Skip to content
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

Penetrating by blocks #5779

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
d6f3951
Add proof by statement
keyboardDrummer Sep 16, 2024
84c7073
Merge remote-tracking branch 'origin/master' into penetratingByBlocks
keyboardDrummer Sep 16, 2024
a2f6b5c
Pass AssertMode to all Assert calls
keyboardDrummer Sep 16, 2024
313ad7e
Use free calls inside by blocks
keyboardDrummer Sep 20, 2024
174abf8
Move code from BoogieGenerator.TrStatement into separate files
keyboardDrummer Sep 20, 2024
5a2f37c
Use namespace directive
keyboardDrummer Sep 20, 2024
ae6f060
Start with removing pre and post call stuff
keyboardDrummer Sep 20, 2024
3cdae72
Finish pre/post call cleanup
keyboardDrummer Sep 20, 2024
9e7a558
Remove the proof field everywhere but in BlockByProof
keyboardDrummer Sep 20, 2024
2b17edc
Update parser
keyboardDrummer Sep 20, 2024
0774dc4
Fix a few bugs
keyboardDrummer Sep 20, 2024
1049866
More use of BodyTranslationContext.AssertMode
keyboardDrummer Sep 20, 2024
a8b2312
Improve printing
keyboardDrummer Sep 20, 2024
0391450
Rename of UpdateStmt
keyboardDrummer Sep 20, 2024
6b985cf
Add comments
keyboardDrummer Sep 20, 2024
fe456d3
Definite assignment tracking issue
keyboardDrummer Sep 21, 2024
5af6b22
Definite assignment tracker changed so it's never cleaned up
keyboardDrummer Sep 21, 2024
6e6d73d
Add substituter implementation
keyboardDrummer Sep 21, 2024
212cfbe
Prepare for using ordered dictionary for locals
keyboardDrummer Sep 23, 2024
da8787e
Introduce Variables class to track Boogie variables using an ordered …
keyboardDrummer Sep 23, 2024
185834a
CallBy.dfy works now
keyboardDrummer Sep 23, 2024
6f2dbf3
CallByHide.dfy passes
keyboardDrummer Sep 23, 2024
16f8ef7
Convert giant if to switch statement
keyboardDrummer Sep 23, 2024
5415a97
Fix
keyboardDrummer Sep 23, 2024
00e11e8
Merge remote-tracking branch 'origin/master' into penetratingByBlocks
keyboardDrummer Sep 23, 2024
10ee669
Ran formatter and def assignment improvement
keyboardDrummer Sep 23, 2024
2eea9e3
Move to symbols for mapping to tracking variables
keyboardDrummer Sep 24, 2024
6560fc2
Fixes
keyboardDrummer Sep 24, 2024
e9db4b9
More fixes
keyboardDrummer Sep 24, 2024
0830162
Fix formatter
keyboardDrummer Sep 24, 2024
35442d9
Merge commit 'ef13a72f3a9d3f' into penetratingByBlocks
keyboardDrummer Sep 24, 2024
d4ca466
Fix
keyboardDrummer Sep 24, 2024
4dfbd8b
Fix expect file
keyboardDrummer Sep 24, 2024
e8c409f
Undo Def as tracking changes
keyboardDrummer Sep 24, 2024
a078831
Fixes
keyboardDrummer Sep 24, 2024
e86fed8
Update expect file
keyboardDrummer Sep 24, 2024
67cdf7b
Update tests
keyboardDrummer Sep 24, 2024
054140b
Update tests
keyboardDrummer Sep 24, 2024
ae8d333
Use an immediately dictionary instead of adding and removing
keyboardDrummer Sep 24, 2024
a4796d2
Fix test generation
keyboardDrummer Sep 24, 2024
8ab5cb7
Refactoring
keyboardDrummer Sep 24, 2024
bdb02ae
Update test
keyboardDrummer Sep 24, 2024
2f189bb
Add test-case for assign such that
keyboardDrummer Sep 24, 2024
880fa30
Add tests
keyboardDrummer Sep 24, 2024
95a09a2
Add another test
keyboardDrummer Sep 24, 2024
13a25b3
Updates
keyboardDrummer Sep 25, 2024
46dc302
Fix SubsetTypes
keyboardDrummer Sep 25, 2024
946bdd6
Merge branch 'master' into penetratingByBlocks
keyboardDrummer Sep 25, 2024
f45a1a3
Remove todos
keyboardDrummer Oct 6, 2024
7cce358
Regenerated makefiles
keyboardDrummer Oct 6, 2024
d132f87
Merge remote-tracking branch 'origin/master' into penetratingByBlocks
keyboardDrummer Oct 6, 2024
f9c2fa3
Update doos
keyboardDrummer Oct 6, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 19 additions & 14 deletions Source/DafnyCore/AST/Expressions/StmtExpr.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,20 +53,25 @@ public override IEnumerable<Expression> TerminalExpressions {
/// S is executed.
/// This method should be called only after successful resolution of the expression.
/// </summary>
public Expression GetSConclusion() {
// this is one place where we actually investigate what kind of statement .S is
if (S is PredicateStmt) {
var s = (PredicateStmt)S;
return s.Expr;
} else if (S is CalcStmt) {
var s = (CalcStmt)S;
return s.Result;
} else if (S is HideRevealStmt) {
return CreateBoolLiteral(tok, true); // one could use the definition axiom or the referenced labeled assertions, but "true" is conservative and much simpler :)
} else if (S is AssignStatement) {
return CreateBoolLiteral(tok, true); // one could use the postcondition of the method, suitably instantiated, but "true" is conservative and much simpler :)
} else {
Contract.Assert(false); throw new cce.UnreachableException(); // unexpected statement
public Expression GetStatementConclusion() {
return GetStatementConclusion(S);
}

private Expression GetStatementConclusion(Statement statement) {
switch (statement) {
// this is one place where we actually investigate what kind of statement .S is
case PredicateStmt stmt:
return stmt.Expr;
case CalcStmt stmt:
return stmt.Result;
case HideRevealStmt:
return CreateBoolLiteral(tok, true); // one could use the definition axiom or the referenced labeled assertions, but "true" is conservative and much simpler :)
case AssignStatement:
return CreateBoolLiteral(tok, true); // one could use the postcondition of the method, suitably instantiated, but "true" is conservative and much simpler :)
case BlockByProofStmt stmt:
return GetStatementConclusion(stmt.Body);
default:
Contract.Assert(false); throw new cce.UnreachableException(); // unexpected statement
}
}

Expand Down
121 changes: 29 additions & 92 deletions Source/DafnyCore/AST/Grammar/Printer/Printer.Statement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,18 @@

namespace Microsoft.Dafny {

interface ICanPrint {
void Render(TextWriter wr, Printer printer, int indent);
}

public partial class Printer {

/// <summary>
/// Prints from the current position of the current line.
/// If the statement requires several lines, subsequent lines are indented at "indent".
/// No newline is printed after the statement.
/// </summary>
public void PrintStatement(Statement stmt, int indent) {
public void PrintStatement(Statement stmt, int indent, bool includeSemicolon = true) {
Contract.Requires(stmt != null);

if (stmt.IsGhost && printMode == PrintModes.NoGhostOrIncludes) {
Expand All @@ -40,38 +44,13 @@ public void PrintStatement(Statement stmt, int indent) {
}
}

if (stmt is PredicateStmt) {
if (printMode == PrintModes.NoGhostOrIncludes) {
return;
}

Expression expr = ((PredicateStmt)stmt).Expr;
var assertStmt = stmt as AssertStmt;
var expectStmt = stmt as ExpectStmt;
wr.Write(assertStmt != null ? "assert" :
expectStmt != null ? "expect" :
"assume");
if (stmt.Attributes != null) {
PrintAttributes(stmt.Attributes);
}

wr.Write(" ");
if (assertStmt != null && assertStmt.Label != null) {
wr.Write("{0}: ", assertStmt.Label.Name);
}

PrintExpression(expr, true);
if (assertStmt != null && assertStmt.Proof != null) {
wr.Write(" by ");
PrintStatement(assertStmt.Proof, indent);
} else if (expectStmt != null && expectStmt.Message != null) {
wr.Write(", ");
PrintExpression(expectStmt.Message, true);
wr.Write(";");
} else {
wr.Write(";");
}
if (stmt is ICanPrint canPrint) {
canPrint.Render(wr, this, indent);
return;
}

if (stmt is PredicateStmt) {
PrintPredicateStmt(stmt, includeSemicolon);
} else if (stmt is PrintStmt) {
PrintStmt s = (PrintStmt)stmt;
wr.Write("print");
Expand All @@ -88,7 +67,6 @@ public void PrintStatement(Statement stmt, int indent) {
for (int i = 0; i < s.BreakAndContinueCount - 1; i++) {
wr.Write("break ");
}

wr.Write($"{s.Kind};");
}

Expand All @@ -103,7 +81,6 @@ public void PrintStatement(Statement stmt, int indent) {
sep = ", ";
}
}

wr.Write(";");

} else if (stmt is SingleAssignStmt) {
Expand All @@ -122,7 +99,6 @@ public void PrintStatement(Statement stmt, int indent) {
PrintStatement(s, ind);
wr.WriteLine();
}

if (sbs.BodyProper.Count != 0 || sbs.SeparatorTok != null) {
Indent(indent + IndentAmount);
wr.WriteLine("new;");
Expand All @@ -132,7 +108,6 @@ public void PrintStatement(Statement stmt, int indent) {
wr.WriteLine();
}
}

Indent(indent);
wr.Write("}");

Expand All @@ -149,7 +124,6 @@ public void PrintStatement(Statement stmt, int indent) {
if (s.UsesOptionalBraces) {
wr.Write(" {");
}

PrintAlternatives(indent + (s.UsesOptionalBraces ? IndentAmount : 0), s.Alternatives);
if (s.UsesOptionalBraces) {
wr.WriteLine();
Expand All @@ -176,10 +150,8 @@ public void PrintStatement(Statement stmt, int indent) {
} else {
wr.Write(" ");
}

wr.Write("{");
}

Contract.Assert(s.Alternatives.Count != 0);
PrintAlternatives(indent + (s.UsesOptionalBraces ? IndentAmount : 0), s.Alternatives);
if (s.UsesOptionalBraces) {
Expand All @@ -198,7 +170,6 @@ public void PrintStatement(Statement stmt, int indent) {
foreach (var expr in s.EffectiveEnsuresClauses) {
PrintExpression(expr, false, new string(' ', indent + IndentAmount) + "ensures ");
}

if (s.Body != null) {
wr.WriteLine();
Indent(indent);
Expand All @@ -209,7 +180,6 @@ public void PrintStatement(Statement stmt, int indent) {
wr.Write(" ");
PrintQuantifierDomain(s.BoundVars, s.Attributes, s.Range);
}

PrintSpec("ensures", s.Ens, indent + IndentAmount);
if (s.Body != null) {
if (s.Ens.Count == 0) {
Expand All @@ -220,7 +190,6 @@ public void PrintStatement(Statement stmt, int indent) {
}
}
}

if (s.Body != null) {
PrintStatement(s.Body, indent);
}
Expand All @@ -231,10 +200,7 @@ public void PrintStatement(Statement stmt, int indent) {

} else if (stmt is CalcStmt) {
CalcStmt s = (CalcStmt)stmt;
if (printMode == PrintModes.NoGhostOrIncludes) {
return;
} // Calcs don't get a "ghost" attribute, but they are.

if (printMode == PrintModes.NoGhostOrIncludes) { return; } // Calcs don't get a "ghost" attribute, but they are.
wr.Write("calc");
PrintAttributes(stmt.Attributes);
wr.Write(" ");
Expand All @@ -245,11 +211,9 @@ public void PrintStatement(Statement stmt, int indent) {
PrintCalcOp(s.Op);
wr.Write(" ");
}

wr.WriteLine("{");
int lineInd = indent + IndentAmount;
int lineCount =
s.Lines.Count == 0 ? 0 : s.Lines.Count - 1; // if nonempty, .Lines always contains a duplicated last line
int lineCount = s.Lines.Count == 0 ? 0 : s.Lines.Count - 1; // if nonempty, .Lines always contains a duplicated last line
// The number of op/hints is commonly one less than the number of lines, but
// it can also equal the number of lines for empty calc's and for calc's with
// a dangling hint.
Expand All @@ -265,22 +229,19 @@ public void PrintStatement(Statement stmt, int indent) {
if (i == hintCount) {
break;
}

// print the operator, if any
if (op != null || (options.DafnyPrintResolvedFile != null && s.Op != null)) {
Indent(indent); // this lines up with the "calc"
PrintCalcOp(op ?? s.Op);
wr.WriteLine();
}

// print the hints
foreach (var st in h.Body) {
Indent(lineInd);
PrintStatement(st, lineInd);
wr.WriteLine();
}
}

Indent(indent);
wr.Write("}");
} else if (stmt is NestedMatchStmt) {
Expand All @@ -290,22 +251,18 @@ public void PrintStatement(Statement stmt, int indent) {
if (s.Flattened != null && options.DafnyPrintResolvedFile != null) {
wr.WriteLine();
if (!printingDesugared) {
Indent(indent);
wr.WriteLine("/*---------- flattened ----------");
Indent(indent); wr.WriteLine("/*---------- flattened ----------");
}

var savedDesugarMode = printingDesugared;
printingDesugared = true;
Indent(indent);
PrintStatement(s.Flattened, indent);
Indent(indent); PrintStatement(s.Flattened, indent);
wr.WriteLine();
printingDesugared = savedDesugarMode;

if (!printingDesugared) {
Indent(indent);
wr.WriteLine("---------- end flattened ----------*/");
Indent(indent); wr.WriteLine("---------- end flattened ----------*/");
}

Indent(indent);
}

Expand All @@ -317,7 +274,6 @@ public void PrintStatement(Statement stmt, int indent) {
if (s.UsesOptionalBraces) {
wr.Write(" {");
}

int caseInd = indent + (s.UsesOptionalBraces ? IndentAmount : 0);
foreach (NestedMatchCaseStmt mc in s.Cases) {
wr.WriteLine();
Expand All @@ -333,7 +289,6 @@ public void PrintStatement(Statement stmt, int indent) {
PrintStatement(bs, caseInd + IndentAmount);
}
}

if (s.UsesOptionalBraces) {
wr.WriteLine();
Indent(indent);
Expand Down Expand Up @@ -375,8 +330,9 @@ public void PrintStatement(Statement stmt, int indent) {
Indent(indent);
wr.Write("}");
}

} else if (stmt is ConcreteAssignStatement concreteAssignStatement) {
PrintConcreteUpdateStatement(concreteAssignStatement, indent);
PrintConcreteUpdateStatement(concreteAssignStatement, indent, includeSemicolon);
} else if (stmt is CallStmt) {
// Most calls are printed from their concrete syntax given in the input. However, recursive calls to
// prefix lemmas end up as CallStmt's by the end of resolution and they may need to be printed here.
Expand All @@ -386,45 +342,39 @@ public void PrintStatement(Statement stmt, int indent) {

} else if (stmt is VarDeclStmt) {
var s = (VarDeclStmt)stmt;
if (s.Locals.Exists(v => v.IsGhost) && printMode == PrintModes.NoGhostOrIncludes) {
return;
}

if (s.Locals.Exists(v => v.IsGhost) && printMode == PrintModes.NoGhostOrIncludes) { return; }
if (s.Locals.TrueForAll((v => v.IsGhost))) {
// Emit the "ghost" modifier if all of the variables are ghost. If some are ghost, but not others,
// then some of these ghosts are auto-converted to ghost, so we should not emit the "ghost" keyword.
wr.Write("ghost ");
}

wr.Write("var");
string sep = "";
foreach (var local in s.Locals) {
wr.Write(sep);
if (local.Attributes != null) {
PrintAttributes(local.Attributes);
}

wr.Write(" {0}", local.DisplayName);
PrintType(": ", local.SyntacticType);
sep = ",";
}

if (s.Assign != null) {
wr.Write(" ");
PrintUpdateRHS(s.Assign, indent);
}

PrintBy(s.Assign, indent);
if (includeSemicolon) {
wr.Write(";");
}
} else if (stmt is VarDeclPattern) {
var s = (VarDeclPattern)stmt;
if (s.tok is AutoGeneratedToken) {
wr.Write("/* ");
}

if (s.HasGhostModifier) {
wr.Write("ghost ");
}

wr.Write("var ");
PrintCasePattern(s.LHS);
wr.Write(" := ");
Expand Down Expand Up @@ -473,26 +423,11 @@ public void PrintStatement(Statement stmt, int indent) {
PrintStatement(haltRecoveryStatement.RecoverBody, ind);
wr.Write("[[ } ]]");
} else {
Contract.Assert(false);
throw new cce.UnreachableException(); // unexpected statement
}
}

void PrintBy(ConcreteAssignStatement statement, int indent) {
var proof = statement switch {
AssignStatement updateStmt => updateStmt.Proof,
AssignOrReturnStmt returnStmt => returnStmt.Proof,
_ => null
};
if (proof != null) {
wr.Write(" by ");
PrintStatement(proof, indent);
} else {
wr.Write(";");
Contract.Assert(false); throw new cce.UnreachableException(); // unexpected statement
}
}

public void PrintConcreteUpdateStatement(ConcreteAssignStatement stmt, int indent) {
public void PrintConcreteUpdateStatement(ConcreteAssignStatement stmt, int indent, bool includeSemicolon = true) {
string sep = "";
foreach (var lhs in stmt.Lhss) {
wr.Write(sep);
Expand All @@ -503,7 +438,9 @@ public void PrintConcreteUpdateStatement(ConcreteAssignStatement stmt, int inden
wr.Write(" ");
}
PrintUpdateRHS(stmt, indent);
PrintBy(stmt, indent);
if (includeSemicolon) {
wr.Write(";");
}
}

public void PrintBlockStmt(BlockStmt stmt, int indent) {
Expand Down Expand Up @@ -773,8 +710,8 @@ void PrintRhs(AssignmentRhs rhs) {
PrintType(t.EType);
}
if (options.DafnyPrintResolvedFile == null &&
t.InitDisplay != null && t.ArrayDimensions.Count == 1 &&
AutoGeneratedToken.Is(t.ArrayDimensions[0].tok)) {
t.InitDisplay != null && t.ArrayDimensions.Count == 1 &&
AutoGeneratedToken.Is(t.ArrayDimensions[0].tok)) {
// elide the size
wr.Write("[]");
} else {
Expand Down
4 changes: 3 additions & 1 deletion Source/DafnyCore/AST/Grammar/Printer/Printer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1112,7 +1112,9 @@ void PrintFormal(Formal f, bool showNewKeyword) {

internal void PrintDecreasesSpec(Specification<Expression> decs, int indent) {
Contract.Requires(decs != null);
if (printMode == PrintModes.NoGhostOrIncludes) { return; }
if (printMode == PrintModes.NoGhostOrIncludes) {
return;
}
if (decs.Expressions != null && decs.Expressions.Count != 0) {
wr.WriteLine();
Indent(indent);
Expand Down
Loading