-
Notifications
You must be signed in to change notification settings - Fork 112
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
Introduce aggressive pruning and the related 'uses' keyword for constants and functions #450
Changes from all commits
d28df0f
62f6e6b
ce74b0a
3b60a4a
89f0ad9
9ec7194
5c81182
6a192fb
e2eb2f2
d77e4e6
4ee7da5
67af2e0
524772c
fc5665f
edcf878
1c9691e
1634080
41b9387
03f5c73
56b011f
b6d5e73
4ece719
09177ee
b0f6604
c9f3d27
4042f5d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -523,10 +523,7 @@ protected CommandLineOptions(string toolName, string descriptiveName) | |
|
||
private static CommandLineOptions clo; | ||
|
||
public static CommandLineOptions /*!*/ Clo | ||
{ | ||
get { return clo; } | ||
} | ||
public static CommandLineOptions /*!*/ Clo => clo; | ||
|
||
public static void Install(CommandLineOptions options) | ||
{ | ||
|
@@ -592,7 +589,80 @@ public bool PrintInstrumented { | |
public bool InstrumentWithAsserts = false; | ||
public string ProverPreamble { get; set; }= null; | ||
public bool WarnNotEliminatedVars = false; | ||
public bool PruneFunctionsAndAxioms = false; | ||
|
||
public enum PruneMode { | ||
None, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The discussion about automatic pruning assumes that the reader already understands the basic algorithm for adding edges among various declarations. Is that description already present in some documentation? If not, please add it here. The description should mention the declarations among which edges are present and for each edge a short intuitive description of what that edge means. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't fully understand the automatic pruning option, so I can't easily provide the detailed description you ask for. I think the summary is that any reference between declarations, except for those in quantifiers with triggers, is considered bidirectional. I would be okay with removing automatic pruning once Dafny uses UsesClauses pruning. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, removing Automatic seems desirable since currently there are multiple overlapping ways of doing the same thing. Would removing Automatic also mean that :exclude_dep will be dropped? @RustanLeino : Any objection to dropping Automatic once Dafny uses UsesClauses pruning. What is the timeline on that move? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yes
I'm working on it. About a month. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have no objection to dropping the Automatic mode and the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @shazqadeer can we merge this? I don't have a strong opinion on the name of the |
||
|
||
/** | ||
* Automatic pruning will remove any declarations that do not reference, | ||
* directly or indirectly, and are not referenced by, the implementation being verified, | ||
* and declarations which cannot be used for verifying the current implementation, | ||
* such as axioms with triggers that can not be satisfied. | ||
* | ||
* Automatic pruning detects incoming edges in axioms, for example: | ||
* | ||
* function A(int): int; | ||
* axiom A(3) == 2; | ||
* | ||
* Will detect edges in both directions between the declaration of A and the axiom declaration. | ||
* So if either declaration is live, both declarations are live. | ||
*/ | ||
Automatic, | ||
|
||
/** | ||
* UsesDecls pruning will not automatically detect incoming edges in axioms. | ||
* Instead it depends on uses clauses in the input program to determine the outgoing edges of functions and constants. | ||
* Outgoing edges in axioms are still detected automatically. | ||
* | ||
* The reason to use UsesDecls over Automatic pruning is that the latter can miss pruning opportunities. | ||
* Consider the following program: | ||
* | ||
* ``` | ||
* function F(int): int; | ||
* function G(int): int; | ||
* | ||
* // declaration axiom for F | ||
* axiom forall x: int :: F(x) == x * 2 | ||
* | ||
* // declaration axiom for G | ||
* axiom forall x: int :: G(x) == F(x) + 1 | ||
* | ||
* procedure FMultipliesByTwo(x: int) | ||
* ensures F(x) - x == x | ||
* { } | ||
* ``` | ||
* | ||
* Automatic pruning will not remove any declarations when verifying the procedure FMultipliesByTwo, | ||
* since it refers to F, which refers to the declaration axiom of G through an incoming edge in the axiom, | ||
* which also has an outgoing edge to G. | ||
* | ||
* If we rewrite the previous program to | ||
* | ||
* ``` | ||
* function F(int) returns (int) uses { | ||
* axiom forall x: int :: F(x) == x * 2 | ||
* } | ||
* function G(int) returns (int) uses { | ||
* axiom forall x: int :: G(x) == F(x) + 1 | ||
* } | ||
* | ||
* procedure FMultipliesByTwo(x: int) | ||
* ensures F(x) - x == x | ||
* { } | ||
* ``` | ||
* | ||
* And apply UsesDecls pruning, then G and its axiom will be removed when verifying FMultipliesByTwo. | ||
* | ||
* An alternative to using UsesDecls pruning, is to add an {:exclude_dep} attribute to a function or constant, | ||
* which prevents axioms from detecting incoming edges from that declaration. | ||
* To add outgoing edges to the function or constant, uses clauses should be used. | ||
* | ||
* Using Automatic pruning in combination with {:exclude_dep} can be useful if this provides good enough pruning, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you mean: If Automatic pruning in combination with {:exclude_dep} does not enable good enough pruning, consider migrating from Automatic to UsesClauses pruning. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not exactly. I've changed the text slightly: Using Automatic pruning in combination with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I still don't understand what this sentence means, specifically the part after the comma. Perhaps you are trying to communicate two separate thoughts in one sentence by reusing words. If you write down those two thoughts separately in two sentences, I might be able to understand better and suggest a coalescing. Can the part before the comma not be written more compactly as: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm trying to say that there's two use-cases for the Automatic pruning option:
|
||
* or to migrate from None to UsesDecls pruning. | ||
*/ | ||
UsesDecls | ||
} | ||
public PruneMode Prune = PruneMode.None; | ||
|
||
public enum InstrumentationPlaces | ||
{ | ||
|
@@ -1681,6 +1751,12 @@ protected override bool ParseOption(string name, CommandLineOptionEngine.Command | |
ps.GetNumericArgument(ref KInductionDepth); | ||
return true; | ||
|
||
case "prune": | ||
int number = 0; | ||
ps.GetNumericArgument(ref number); | ||
Prune = (PruneMode)number; | ||
return true; | ||
|
||
case "emitDebugInformation": | ||
ps.GetNumericArgument(ref emitDebugInformation); | ||
return true; | ||
|
@@ -1738,7 +1814,6 @@ protected override bool ParseOption(string name, CommandLineOptionEngine.Command | |
ps.CheckBooleanFlag("trustInductiveSequentialization", ref trustInductiveSequentialization) || | ||
ps.CheckBooleanFlag("useBaseNameForFileName", ref UseBaseNameForFileName) || | ||
ps.CheckBooleanFlag("freeVarLambdaLifting", ref FreeVarLambdaLifting) || | ||
ps.CheckBooleanFlag("pruneFunctionsAndAxioms", ref PruneFunctionsAndAxioms) || | ||
ps.CheckBooleanFlag("warnNotEliminatedVars", ref WarnNotEliminatedVars) | ||
) | ||
{ | ||
|
@@ -2323,8 +2398,10 @@ Use the SMT theory of arrays (as opposed to axioms). Supported | |
only for monomorphic programs. | ||
/reflectAdd In the VC, generate an auxiliary symbol, elsewhere defined | ||
to be +, instead of +. | ||
/pruneFunctionsAndAxioms | ||
Prune declarations for each implementation | ||
/prune:<n> | ||
0 (default) - none | ||
1 - automatic pruning | ||
2 - aggressive pruning. Requires binding axioms to functions and constants using 'uses' | ||
/relaxFocus Process foci in a bottom-up fashion. This way only generates | ||
a linear number of splits. The default way (top-down) is more | ||
aggressive and it may create an exponential number of splits. | ||
|
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.
This makes
uses
a reserved keyword in Boogie. Any previous program that useduses
as an identifier will no longer parse. I think this is okay, but we should make sure to bump the Boogie version accordingly (to a new minor number, probably).If there's concern about making
uses
a keyword, an alternative would be to add it as a contextual keyword. That's a little tricky here, becausecould mean one thing with
and something different with
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 bumped the minor version number