-
Notifications
You must be signed in to change notification settings - Fork 268
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proof dependency warnings #4542
Proof dependency warnings #4542
Conversation
When enabled with -trackVerificationCoverage (an internal Boogie flag that we don't expect most people to use), this calculates proof dependencies and includes them in the output of the "text" format verification logger. Some caveats: * Some important statements aren't labeled yet. * Some descriptions are different in different contexts.
Previously it was sorted by name
This helps ensure deterministic testing.
This occurs due to a Boogie change that now dereferences a property that previously was supposed to never be null but wasn't blindly dereferenced.
Temporary until we fix a Boogie concurrency bug
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Partial review, still have to have a look at the main file changes
@@ -248,6 +252,12 @@ public enum DefaultFunctionOpacityOptions { | |||
DafnyOptions.RegisterLegacyBinding(WarningAsErrors, (options, value) => { options.WarningsAsErrors = value; }); | |||
DafnyOptions.RegisterLegacyBinding(VerifyIncludedFiles, | |||
(options, value) => { options.VerifyAllModules = value; }); | |||
DafnyOptions.RegisterLegacyBinding(WarnVacuity, (options, value) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bit off topic, but do we actually need the legacy bindings on new options? I've been avoiding this given the "legacy" label and just using Options.Get(CommonOptionBag.MyNewOption)
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1, please never add RegisterLegacyBinding
The underlying option it's setting, TrackVerificationCoverage
, is a Boogie option. The RegisterLegacyBinding
call is a way to sync the Dafny option into the Boogie one. This is not the right long term approach, but right now it's what the other Boogie-coupled options are doing.
Ideally, the Boogie options would be separate from the Dafny ones, and you'd have to create them when instantiating "Boogie" (in the code that would be the Boogie ExecutionEngine
, instantiated here: https://github.com/dafny-lang/dafny/blob/master/Source/DafnyDriver/DafnyDriver.cs#L41).
To do that nicely we'd need another registry that's similar to RegisterLegacyBinding
, but then RegisterBoogieBinding
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, it's a bit of a tricky case where we have new, modern options but also need to set a Boogie option. I'd entirely be in favor of some new registry, but I think it's out of scope for this PR.
@@ -466,6 +468,10 @@ public enum CommandLineArgumentsResult { | |||
string baseName = cce.NonNull(Path.GetFileName(dafnyFileNames[^1])); | |||
var (verified, outcome, moduleStats) = await BoogieAsync(options, baseName, boogiePrograms, programId); | |||
|
|||
if (options.TrackVerificationCoverage && verified) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Out of scope for this review, but for the next opportunity: seems like this option name is a holdover from the previous terminology. Is this backed by a CLI option with a better name?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, it's turned on by --warn-vacuity
or --warn-redundant-assumptions
. Dafny users will never need to see the terminology in this option.
// CHECK: ProofDependencyLogging.dfy\(244,24\)-\(244,24\): value always satisfies the subset constraints of 'nat' | ||
// CHECK: ProofDependencyLogging.dfy\(244,47\)-\(244,47\): value always satisfies the subset constraints of 'nat' | ||
// CHECK: ProofDependencyLogging.dfy\(244,25\)-\(244,25\): value always satisfies the subset constraints of 'nat' | ||
// CHECK: ProofDependencyLogging.dfy\(244,48\)-\(244,48\): value always satisfies the subset constraints of 'nat' | ||
// | ||
// CHECK: Results for ObviouslyUnconstrainedCodeFunc \(well-formedness\) | ||
// CHECK: Proof dependencies: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also out of scope for this review, but can't help ask if we should label this more precisely to account for the fact that some proof dependencies may be "spurious", just as counter examples are really something like "potential counter examples"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice that you got adequate testing coverage by reusing the existing test file!
@@ -0,0 +1,20 @@ | |||
ProofDependencyLogging.dfy(176,11): Warning: unnecessary assumption | |||
ProofDependencyLogging.dfy(186,13): Warning: vacuous proof: assertion always holds |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah NOW I get my previous confusion - in this specific (and common) case, the vacuous proof: <proof description>
template leads to a string that's too easy to misinterpret as vacuous proof, or, as another way of saying 'vacuous proof', assertion always holds
. :)
Perhaps we could use a template like vacuous proof of (<proof description>)
instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could also consider not using "vacuous" since many users won't be familiar with that concept. Perhaps "Warning: proved from impossible assumptions: ..." ("contradictory assumptions" is appealing too, but then false
by itself is impossible).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah but you even used "contradictory assumptions" in the option help text so perhaps I shouldn't worry :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, so how about "proved using contradictory assumptions: "? I could change the name of --warn-vacuity
, too. Maybe --warn-contradictory-assumptions
? That's nicely symmetric with --warn-redundant-assumptions
.
currentDefinition = defName; | ||
} | ||
|
||
public IEnumerable<ProofDependency> GetPotentialDependenciesForDefinition(string defName) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah there's the "potential" word I was looking for :)
Source/DafnyCore/DafnyMain.cs
Outdated
@@ -203,5 +205,95 @@ public class DafnyMain { | |||
} | |||
} | |||
|
|||
public static void WarnAboutSuspiciousDependencies(DafnyOptions dafnyOptions, ErrorReporter reporter, ProofDependencyManager depManager) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would put this code in a separate file. I think ideally this could would live in a plugin that could live in a separate assembly that hooks into some PostSymbolVerification
event. Not needed for now but if we can make it look more like that I'd appreciate it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome feature, looking forward to having it on by default in the future :)
Source/DafnyCore/DafnyMain.cs
Outdated
@@ -203,5 +205,95 @@ public class DafnyMain { | |||
} | |||
} | |||
|
|||
public static void WarnAboutSuspiciousDependencies(DafnyOptions dafnyOptions, ErrorReporter reporter, ProofDependencyManager depManager) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1
@@ -0,0 +1,20 @@ | |||
ProofDependencyLogging.dfy(176,11): Warning: unnecessary assumption | |||
ProofDependencyLogging.dfy(186,13): Warning: vacuous proof: assertion always holds |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could also consider not using "vacuous" since many users won't be familiar with that concept. Perhaps "Warning: proved from impossible assumptions: ..." ("contradictory assumptions" is appealing too, but then false
by itself is impossible).
Source/DafnyCore/DafnyMain.cs
Outdated
var unusedAssumeStatements = | ||
unusedDependencies | ||
.OfType<AssumptionDependency>() | ||
.Where(d => d.Description.Contains("assume statement")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Matching against the description feels brittle, especially with just Contains
rather than ==
. Consider adding a fixed identifier of some kind for this use case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I'll see whether there's a better way to do this.
Source/DafnyCore/DafnyMain.cs
Outdated
} | ||
|
||
// Ensures clauses are often proven vacuously during well-formedness checks. | ||
if (verboseName.Contains("well-formedness") && dep is EnsuresDependency) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another test that feels brittle, any way we can be more structured here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately, I don't know of a good way to change this, much as I don't like it. At this point, we only have access to the Boogie Implementation
and it doesn't tell us where it came from.
@@ -0,0 +1,20 @@ | |||
ProofDependencyLogging.dfy(176,11): Warning: unnecessary assumption | |||
ProofDependencyLogging.dfy(186,13): Warning: vacuous proof: assertion always holds |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah but you even used "contradictory assumptions" in the option help text so perhaps I shouldn't worry :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Love the terminology change this led to. Thanks!
Co-authored-by: Robin Salkeld <salkeldr@amazon.com>
I've noticed some odd behavior in this that I'd like to debug before merging it. |
The one thing that's clearly amiss is that it doesn't work well with Boogie's |
There are also some cases where |
…iment-trsplitexpr * commit '86840e6b14386c1e88480854dd8ce64ad17cb2ff': Map eq range (#4567) Fix: Declarations with {:only} ensure that other declarations aren't displayed as verified in the gutter icons (#4433) Fix caching of export declarations (#4556) Do not return exceptions when doing hover in a program with parse errors (#4557) Proof dependency warnings (#4542) [Test Generation] Reduce memory footprint by reusing the same Boogie program for multiple test generation queries (#4530) Fix a variety of bugs in Rust backend based on ESDK testing (#4538) Checker for .Values and .Items on maps (#4551) feat: Allow more assumptions in library backend (#4545) feat: Attributes on reads clauses (#4554) Fix gutter icons fields (#4549) Report errors that occur in the project file, in the IDE as well (#4539) Switch to ubuntu-20.04 for the refman build (#4555)
Adds warnings for two cases of suspicious proof dependencies:
A few cases of vacuity are artifacts of how Dafny programs are encoded in Boogie. Several of these cases are automatically filtered out.
By submitting this pull request, I confirm that my contribution is made under the terms of the MIT license.