protected override void VisitOneStmt(Statement stmt) { if (stmt is ForallStmt) { ForallStmt s = (ForallStmt)stmt; if (s.ForallExpressions != null) { foreach (Expression expr in s.ForallExpressions) { VisitOneExpr(expr); } } } }
protected override bool VisitOneStmt(Statement stmt, ref OldExpr /*?*/ st) { if (stmt is ForallStmt) { ForallStmt s = (ForallStmt)stmt; if (s.ForallExpressions != null) { foreach (Expression expr in s.ForallExpressions) { VisitOneExpr(expr, ref st); } } } return(true); }
public virtual void Visit(ForallStmt forAllStatement) { VisitNullableAttributes(forAllStatement.Attributes); VisitNullableStatement(forAllStatement.Body); }
void ForallStmt(out Statement/*!*/ s) { Contract.Ensures(Contract.ValueAtReturn(out s) != null); IToken/*!*/ x = Token.NoToken; List<BoundVar> bvars = null; Attributes attrs = null; Expression range = null; var ens = new List<MaybeFreeExpression/*!*/>(); bool isFree; Expression/*!*/ e; BlockStmt block = null; IToken bodyStart, bodyEnd; IToken tok = Token.NoToken; if (la.kind == 103) { Get(); x = t; tok = x; } else if (la.kind == 104) { Get(); x = t; errors.Warning(t, "the 'parallel' keyword has been deprecated; the comprehension statement now uses the keyword 'forall' (and the parentheses around the bound variables are now optional)"); } else SynErr(190); if (la.kind == _openparen) { Expect(50); if (la.kind == 1) { QuantifierDomain(out bvars, out attrs, out range); } Expect(51); } else if (StartOf(24)) { if (la.kind == _ident) { QuantifierDomain(out bvars, out attrs, out range); } } else SynErr(191); if (bvars == null) { bvars = new List<BoundVar>(); } if (range == null) { range = new LiteralExpr(x, true); } while (la.kind == 88 || la.kind == 89) { isFree = false; if (la.kind == 88) { Get(); isFree = true; errors.Warning(t, "the 'free' keyword is soon to be deprecated"); } Expect(89); Expression(out e, false, true); ens.Add(new MaybeFreeExpression(e, isFree)); OldSemi(); tok = t; } if (la.kind == _lbrace) { BlockStmt(out block, out bodyStart, out bodyEnd); } if (DafnyOptions.O.DisallowSoundnessCheating && block == null && 0 < ens.Count) { SemErr(t, "a forall statement with an ensures clause must have a body"); } if (block != null) { tok = block.EndTok; } s = new ForallStmt(x, tok, bvars, attrs, range, ens, block); }
private void FindRemovableTypesInForallStmt(ForallStmt forall, Method method, WildCardDecreases wildCardParent, ClassDecl classDecl) { FindRemovableTypesInStatement(forall.Body, forall, method, wildCardParent, classDecl); }
public virtual Statement CloneStmt(Statement stmt) { if (stmt == null) { return null; } Statement r; if (stmt is AssertStmt) { var s = (AssertStmt)stmt; r = new AssertStmt(Tok(s.Tok), Tok(s.EndTok), CloneExpr(s.Expr), null); } else if (stmt is AssumeStmt) { var s = (AssumeStmt)stmt; r = new AssumeStmt(Tok(s.Tok), Tok(s.EndTok), CloneExpr(s.Expr), null); } else if (stmt is TacticInvariantStmt) { var s = (TacticInvariantStmt)stmt; r = new TacticInvariantStmt(Tok(s.Tok), Tok(s.EndTok), CloneExpr(s.Expr), null, s.IsObjectLevel); } else if (stmt is TacticAssertStmt) { var s = (TacticAssertStmt)stmt; r = new TacticAssertStmt(Tok(s.Tok), Tok(s.EndTok), CloneExpr(s.Expr), null, s.IsObjectLevel); } else if (stmt is PrintStmt) { var s = (PrintStmt)stmt; r = new PrintStmt(Tok(s.Tok), Tok(s.EndTok), s.Args.ConvertAll(CloneExpr)); } else if (stmt is BreakStmt) { var s = (BreakStmt)stmt; if (s.TargetLabel != null) { r = new BreakStmt(Tok(s.Tok), Tok(s.EndTok), s.TargetLabel); } else { r = new BreakStmt(Tok(s.Tok), Tok(s.EndTok), s.BreakCount); } } else if (stmt is ReturnStmt) { var s = (ReturnStmt)stmt; r = new ReturnStmt(Tok(s.Tok), Tok(s.EndTok), s.rhss == null ? null : s.rhss.ConvertAll(CloneRHS)); } else if (stmt is YieldStmt) { var s = (YieldStmt)stmt; r = new YieldStmt(Tok(s.Tok), Tok(s.EndTok), s.rhss == null ? null : s.rhss.ConvertAll(CloneRHS)); } else if (stmt is AssignStmt) { var s = (AssignStmt)stmt; r = new AssignStmt(Tok(s.Tok), Tok(s.EndTok), CloneExpr(s.Lhs), CloneRHS(s.Rhs)); } else if (stmt is BlockStmt) { r = CloneBlockStmt((BlockStmt)stmt); } else if (stmt is IfStmt) { var s = (IfStmt)stmt; r = new IfStmt(Tok(s.Tok), Tok(s.EndTok), s.IsExistentialGuard, CloneExpr(s.Guard), CloneBlockStmt(s.Thn), CloneStmt(s.Els)); } else if (stmt is AlternativeStmt) { var s = (AlternativeStmt)stmt; r = new AlternativeStmt(Tok(s.Tok), Tok(s.EndTok), s.Alternatives.ConvertAll(CloneGuardedAlternative)); } else if (stmt is WhileStmt) { var s = (WhileStmt)stmt; r = new WhileStmt(Tok(s.Tok), Tok(s.EndTok), CloneExpr(s.Guard), s.Invariants.ConvertAll(CloneMayBeFreeExpr), CloneSpecExpr(s.Decreases), CloneSpecFrameExpr(s.Mod), CloneBlockStmt(s.Body)); ((WhileStmt)r).TacAps = s.TacAps; } else if (stmt is AlternativeLoopStmt) { var s = (AlternativeLoopStmt)stmt; r = new AlternativeLoopStmt(Tok(s.Tok), Tok(s.EndTok), s.Invariants.ConvertAll(CloneMayBeFreeExpr), CloneSpecExpr(s.Decreases), CloneSpecFrameExpr(s.Mod), s.Alternatives.ConvertAll(CloneGuardedAlternative)); } else if (stmt is ForallStmt) { var s = (ForallStmt)stmt; r = new ForallStmt(Tok(s.Tok), Tok(s.EndTok), s.BoundVars.ConvertAll(CloneBoundVar), null, CloneExpr(s.Range), s.Ens.ConvertAll(CloneMayBeFreeExpr), CloneStmt(s.Body)); if (s.ForallExpressions != null) { ((ForallStmt)r).ForallExpressions = s.ForallExpressions.ConvertAll(CloneExpr); } } else if (stmt is CalcStmt) { var s = (CalcStmt)stmt; // calc statements have the unusual property that the last line is duplicated. If that is the case (which // we expect it to be here), we share the clone of that line as well. var lineCount = s.Lines.Count; var lines = new List<Expression>(lineCount); for (int i = 0; i < lineCount; i++) { lines.Add(i == lineCount - 1 && 2 <= lineCount && s.Lines[i] == s.Lines[i - 1] ? lines[i - 1] : CloneExpr(s.Lines[i])); } Contract.Assert(lines.Count == lineCount); r = new CalcStmt(Tok(s.Tok), Tok(s.EndTok), CloneCalcOp(s.Op), lines, s.Hints.ConvertAll(CloneBlockStmt), s.StepOps.ConvertAll(CloneCalcOp), CloneCalcOp(s.ResultOp), CloneAttributes(s.Attributes)); } else if (stmt is MatchStmt) { var s = (MatchStmt)stmt; r = new MatchStmt(Tok(s.Tok), Tok(s.EndTok), CloneExpr(s.Source), s.Cases.ConvertAll(CloneMatchCaseStmt), s.UsesOptionalBraces); } else if (stmt is AssignSuchThatStmt) { var s = (AssignSuchThatStmt)stmt; r = new AssignSuchThatStmt(Tok(s.Tok), Tok(s.EndTok), s.Lhss.ConvertAll(CloneExpr), CloneExpr(s.Expr), s.AssumeToken == null ? null : Tok(s.AssumeToken), null); } else if (stmt is UpdateStmt) { var s = (UpdateStmt)stmt; r = new UpdateStmt(Tok(s.Tok), Tok(s.EndTok), s.Lhss.ConvertAll(CloneExpr), s.Rhss.ConvertAll(CloneRHS), s.CanMutateKnownState); } else if (stmt is VarDeclStmt) { var s = (VarDeclStmt)stmt; var lhss = s.Locals.ConvertAll(c => new LocalVariable(Tok(c.Tok), Tok(c.EndTok), c.Name, CloneType(c.OptionalType), c.IsGhost)); r = new VarDeclStmt(Tok(s.Tok), Tok(s.EndTok), lhss, (ConcreteUpdateStatement)CloneStmt(s.Update)); } else if (stmt is LetStmt) { var s = (LetStmt)stmt; r = new LetStmt(Tok(s.Tok), Tok(s.EndTok), s.LHSs.ConvertAll(CloneCasePattern), s.RHSs.ConvertAll(CloneExpr)); } else if (stmt is ModifyStmt) { var s = (ModifyStmt)stmt; var mod = CloneSpecFrameExpr(s.Mod); var body = s.Body == null ? null : CloneBlockStmt(s.Body); r = new ModifyStmt(Tok(s.Tok), Tok(s.EndTok), mod.Expressions, mod.Attributes, body); } else if (stmt is TacnyCasesBlockStmt) { var s = (TacnyCasesBlockStmt)stmt; var guard = CloneExpr(s.Guard); var body = s.Body == null ? null : CloneBlockStmt(s.Body); r = new TacnyCasesBlockStmt(Tok(s.Tok), Tok(s.EndTok), guard, body); } else if (stmt is TacnyChangedBlockStmt) { var s = (TacnyChangedBlockStmt)stmt; var body = s.Body == null ? null : CloneBlockStmt(s.Body); r = new TacnyChangedBlockStmt(Tok(s.Tok), Tok(s.EndTok), body); } else if (stmt is TacnySolvedBlockStmt) { var s = (TacnySolvedBlockStmt)stmt; var body = s.Body == null ? null : CloneBlockStmt(s.Body); r = new TacnySolvedBlockStmt(Tok(s.Tok), Tok(s.EndTok), body); } else if (stmt is TacnyTryCatchBlockStmt) { var s = (TacnyTryCatchBlockStmt)stmt; var body = s.Body == null ? null : CloneBlockStmt(s.Body); var c = s.Ctch == null ? null : CloneBlockStmt(s.Ctch); r = new TacnyTryCatchBlockStmt(Tok(s.Tok), Tok(s.EndTok), body, c); } else if (stmt is TacticVarDeclStmt) { var s = (TacticVarDeclStmt)stmt; var lhss = s.Locals.ConvertAll(c => new LocalVariable(Tok(c.Tok), Tok(c.EndTok), c.Name, CloneType(c.OptionalType), c.IsGhost)); r = new TacticVarDeclStmt(Tok(s.Tok), Tok(s.EndTok), lhss, (ConcreteUpdateStatement)CloneStmt(s.Update)); } else { Contract.Assert(false); throw new cce.UnreachableException(); // unexpected statement } // add labels to the cloned statement AddStmtLabels(r, stmt.Labels); r.Attributes = CloneAttributes(stmt.Attributes); return r; }
public virtual void AddResolvedGhostStatement(Statement stmt) { BlockStmt block = stmt as BlockStmt; IfStmt ifStmt = stmt as IfStmt; AssertStmt assertStmt = stmt as AssertStmt; AssignStmt assignStmt = stmt as AssignStmt; CallStmt callStmt = stmt as CallStmt; VarDecl varDecl = stmt as VarDecl; CalcStmt calcStmt = stmt as CalcStmt; ForallStmt forallStmt = stmt as ForallStmt; AssignSuchThatStmt existsStmt = stmt as AssignSuchThatStmt; if (block != null) { var oldRenamer = PushRename(); block.Body.ForEach(AddGhostStatement); PopRename(oldRenamer); } else if (varDecl != null) { AddGhostVarDecl(varDecl.Name, varDecl.Type, varDecl.IsGhost); } else if (minVerify) { return; } else if (assignStmt != null) { ExprRhs expRhs = assignStmt.Rhs as ExprRhs; if (expRhs != null) { FieldSelectExpr fieldSelect = assignStmt.Lhs as FieldSelectExpr; RtlVar destVar; if (fieldSelect != null) { destVar = new RtlVar(GhostVar(fieldSelect.FieldName), true, fieldSelect.Type); } else { destVar = AsVar(assignStmt.Lhs); Util.Assert(destVar != null); } stmts.Add(new RtlGhostMove(new RtlVar[] { destVar }, new RtlExp[] { GhostExpression(expRhs.Expr) })); } else { throw new Exception("not implemented: " + assignStmt.Rhs); } } else if (callStmt != null) { AddGhostCall(callStmt.Lhs.ConvertAll(AsVar), callStmt.Args, dafnySpec.Compile_Method(callStmt.Method, callStmt.TypeArgumentSubstitutions.ToDictionary(p => p.Key, p => AppType(p.Value))), DafnySpec.IsHeapMethod(callStmt.Method)); SymdiffLinearityPoint(); } else if (ifStmt != null) { stmts.Add(new RtlGhostStmtComputed(s => "if (" + s.args[0] + ") {", new RtlExp[] { GhostExpression(ifStmt.Guard) })); Indent(); AddGhostStatement(ifStmt.Thn); Unindent(); stmts.Add(new RtlGhostStmtComputed(s => "}", new RtlExp[0])); if (ifStmt.Els != null) { stmts.Add(new RtlGhostStmtComputed(s => "if (" + s.args[0] + ") {", new RtlExp[] { GhostExpression(new UnaryExpr(Bpl.Token.NoToken, UnaryExpr.Opcode.Not, ifStmt.Guard)) })); Indent(); AddGhostStatement(ifStmt.Els); Unindent(); stmts.Add(new RtlGhostStmtComputed(s => "}", new RtlExp[0])); } } else if (assertStmt != null) { stmts.Add(new RtlAssert(GhostExpression(assertStmt.Expr))); } else if (forallStmt != null) { var oldRenamer = PushRename(forallStmt.BoundVars.Select(v => v.Name)); RtlExp ens = new RtlLiteral("true"); foreach (var e in forallStmt.Ens) { ens = new RtlBinary("&&", ens, GhostExpression(e.E)); } RtlExp range = (forallStmt.Range == null) ? new RtlLiteral("true") : GhostExpression(forallStmt.Range); List <RtlExp> wellFormed = GetTypeWellFormed(forallStmt.BoundVars. Select(x => Tuple.Create(GhostVar(x.Name), x.IsGhost, x.Type)).ToList()); wellFormed.ForEach(e => range = new RtlBinary("&&", e, range)); ens = new RtlBinary("==>", range, ens); string vars = String.Join(", ", forallStmt.BoundVars.Select(x => GhostVar(x.Name) + ":" + TypeString(AppType(x.Type)))); stmts.Add(new RtlGhostStmtComputed(s => "forall " + vars + "::(" + s.args[0] + ")", new List <RtlExp> { ens })); stmts.Add(new RtlGhostStmtComputed(s => "{", new RtlExp[0])); Indent(); stmts.Add(PushForall()); stmts.Add(new RtlGhostStmtComputed(s => "if (" + s.args[0] + ")", new List <RtlExp> { range })); stmts.Add(new RtlGhostStmtComputed(s => "{", new RtlExp[0])); Indent(); AddGhostStatement(forallStmt.Body); foreach (var e in forallStmt.Ens) { stmts.Add(new RtlAssert(GhostExpression(e.E))); } PopForall(); Unindent(); stmts.Add(new RtlGhostStmtComputed(s => "}", new RtlExp[0])); Unindent(); stmts.Add(new RtlGhostStmtComputed(s => "}", new RtlExp[0])); PopRename(oldRenamer); } else if (existsStmt != null) { List <RtlStmt> assigns = new List <RtlStmt>(); List <RtlVar> tmps = new List <RtlVar>(); List <Tuple <string, bool, Type> > varTuples = new List <Tuple <string, bool, Type> >(); var oldRenamer = PushRename(); foreach (var lhs in existsStmt.Lhss) { IdentifierExpr idExp = lhs.Resolved as IdentifierExpr; RtlVar origVar = AsVar(lhs); AddRename(idExp.Name); RtlVar renameVar = AsVar(lhs); tmps.Add(renameVar); varTuples.Add(Tuple.Create(renameVar.ToString(), true, idExp.Type)); assigns.Add(new RtlGhostMove(new RtlVar[] { origVar }, new RtlExp[] { renameVar })); } string vars = String.Join(", ", tmps.Select(x => x.getName() + ":" + TypeString(AppType(x.type)))); stmts.Add(new RtlGhostStmtComputed(s => "exists " + vars + "::(" + s.args[0] + ");", new List <RtlExp> { GetTypeWellFormedExp(varTuples.ToList(), "&&", GhostExpression(existsStmt.Expr)) })); stmts.AddRange(assigns); PopRename(oldRenamer); } else if (calcStmt != null) { Util.Assert(calcStmt.Steps.Count == calcStmt.Hints.Count); CalcStmt.BinaryCalcOp binOp = calcStmt.Op as CalcStmt.BinaryCalcOp; bool isImply = binOp != null && binOp.Op == BinaryExpr.Opcode.Imp && calcStmt.Steps.Count > 0; if (isImply) { stmts.Add(new RtlGhostStmtComputed(s => "if (" + s.args[0] + ")", new RtlExp[] { GhostExpression(CalcStmt.Lhs(calcStmt.Steps[0])) })); stmts.Add(new RtlGhostStmtComputed(s => "{", new RtlExp[0])); Indent(); } var stepCount = calcStmt.Hints.Last().Body.Count == 0 ? calcStmt.Steps.Count - 1 : calcStmt.Steps.Count; for (int i = 0; i < stepCount; i++) { if (calcStmt.Hints[i] == null) { stmts.Add(new RtlAssert(GhostExpression(calcStmt.Steps[i]))); } else { stmts.Add(new RtlGhostStmtComputed(s => "forall::(" + s.args[0] + ")", new List <RtlExp> { GhostExpression(calcStmt.Steps[i]) })); stmts.Add(new RtlGhostStmtComputed(s => "{", new RtlExp[0])); Indent(); var dict = new Dictionary <string, RtlVar>(); stmts.Add(new RtlGhostStmtComputed(s => String.Concat(dict.Values.Select( x => "var " + x.x + ":" + TypeString(x.type) + ";")), new RtlExp[0])); forallVars.Add(dict); AddGhostStatement(calcStmt.Hints[i]); forallVars.RemoveAt(forallVars.Count - 1); Unindent(); stmts.Add(new RtlGhostStmtComputed(s => "}", new RtlExp[0])); } } if (isImply) { Unindent(); stmts.Add(new RtlGhostStmtComputed(s => "}", new RtlExp[0])); } } else { throw new Exception("not implemented in ghost methods: " + stmt); } }