private IEnumerable <Solution> SuchThat(Statement st, Solution solution) { TacticVarDeclStmt tvds = st as TacticVarDeclStmt; // statement must be object level, thus include as is if (tvds == null) { yield return(AddNewStatement(st, st)); yield break; } AssignSuchThatStmt suchThat = tvds.Update as AssignSuchThatStmt; Contract.Assert(suchThat != null, Error.MkErr(st, 5, typeof(AssignSuchThatStmt), tvds.Update.GetType())); BinaryExpr bexp = suchThat.Expr as BinaryExpr; Contract.Assert(bexp != null, Error.MkErr(st, 5, typeof(BinaryExpr), suchThat.Expr.GetType())); // this will cause issues when multiple variables are used // as the variables are updated one at a time foreach (var local in tvds.Locals) { foreach (var item in ResolveExpression(bexp, local)) { yield return(AddNewLocal(local, item)); } } }
public override IEnumerable <ProofState> Generate(Statement statement, ProofState state) { var tvds = statement as TacticVarDeclStmt; AssignSuchThatStmt suchThat = null; if (tvds != null) { suchThat = tvds.Update as AssignSuchThatStmt; } else if (statement is AssignSuchThatStmt) { suchThat = (AssignSuchThatStmt)statement; } else { Contract.Assert(false, "Unexpected statement type"); } Contract.Assert(suchThat != null, "Unexpected statement type"); BinaryExpr bexp = suchThat.Expr as BinaryExpr; var locals = new List <string>(); if (tvds == null) { foreach (var item in suchThat.Lhss) { if (item is IdentifierExpr) { var id = (IdentifierExpr)item; if (state.ContainTacnyVal(id.Name)) { locals.Add(id.Name); } else { //TODO: error } } } } else { locals = new List <string>(tvds.Locals.Select(x => x.Name).ToList()); } // this will cause issues when multiple variables are used // as the variables are updated one at a time foreach (var local in locals) { foreach (var item in ResolveExpression(state, bexp, local)) { var copy = state.Copy(); copy.UpdateTacnyVar(local, item); yield return(copy); } } }
public string GenerateString(AssignSuchThatStmt statement, int tabs) { StringBuilder bob = new StringBuilder(); ApplyIndentation(bob, tabs); foreach (Expression lhs in statement.Lhss) { bob.Append(GenerateString(lhs)); bob.Append(", "); } bob.Remove(bob.Length - 2, 2); bob.Append(" " + statement.Tok.val + " "); bob.Append(GenerateString(statement.Expr) + statement.EndTok.val); return(bob.ToString()); }
public static Atomic GetAtomicType(Statement st) { UpdateStmt us = null; TacnyBlockStmt tbs; TacticVarDeclStmt tvds; VarDeclStmt vds; OrStmt os; IToken tok = null; if ((tbs = st as TacnyBlockStmt) != null) { TacnyCasesBlockStmt tcbs; TacnySolvedBlockStmt tsbs; TacnyChangedBlockStmt tchbs; TacnyTryCatchBlockStmt ttcbs; if ((tcbs = tbs as TacnyCasesBlockStmt) != null) { return(AtomicSignature[tcbs.WhatKind]); } if ((tsbs = tbs as TacnySolvedBlockStmt) != null) { return(AtomicSignature[tsbs.WhatKind]); } if ((tchbs = tbs as TacnyChangedBlockStmt) != null) { return(AtomicSignature[tchbs.WhatKind]); } if ((ttcbs = tbs as TacnyTryCatchBlockStmt) != null) { return(AtomicSignature[ttcbs.WhatKind]); } } else if (((os = st as OrStmt) != null)) { tok = os.Tok; } else if (st is IfStmt) { return(Atomic.If); } else if (st is WhileStmt) { return(Atomic.While); } else if ((us = st as UpdateStmt) != null) { } else if ((vds = st as VarDeclStmt) != null) { AssignSuchThatStmt suchThat = vds.Update as AssignSuchThatStmt; // check if declaration is such that if (suchThat != null) { tok = suchThat.Tok; } else { us = vds.Update as UpdateStmt; } } else if ((tvds = st as TacticVarDeclStmt) != null) { var suchThat = tvds.Update as AssignSuchThatStmt; // check if declaration is such that if (suchThat != null) { tok = suchThat.Tok; } else { us = tvds.Update as UpdateStmt; } } else if (st is TacticInvariantStmt) { return(Atomic.Invar); } if (tok != null) { return(GetAtomicType(tok)); } if (us == null) { return(Atomic.Undefined); } var er = (ExprRhs)us.Rhss[0]; return(GetAtomicType(er.Expr as ApplySuffix)); }
void VarDeclStatement(out Statement/*!*/ s) { IToken x = null, assignTok = null; bool isGhost = false; LocalVariable d; AssignmentRhs r; List<LocalVariable> lhss = new List<LocalVariable>(); List<AssignmentRhs> rhss = new List<AssignmentRhs>(); IToken suchThatAssume = null; Expression suchThat = null; Attributes attrs = null; IToken endTok; if (la.kind == 73) { Get(); isGhost = true; x = t; } Expect(78); if (!isGhost) { x = t; } while (la.kind == 46) { Attribute(ref attrs); } LocalIdentTypeOptional(out d, isGhost); lhss.Add(d); d.Attributes = attrs; attrs = null; while (la.kind == 22) { Get(); while (la.kind == 46) { Attribute(ref attrs); } LocalIdentTypeOptional(out d, isGhost); lhss.Add(d); d.Attributes = attrs; attrs = null; } if (la.kind == 25 || la.kind == 46 || la.kind == 95) { if (la.kind == 95) { Get(); assignTok = t; Rhs(out r); rhss.Add(r); while (la.kind == 22) { Get(); Rhs(out r); rhss.Add(r); } } else { while (la.kind == 46) { Attribute(ref attrs); } Expect(25); assignTok = t; if (la.kind == _assume) { Expect(31); suchThatAssume = t; } Expression(out suchThat, false, true); } } while (!(la.kind == 0 || la.kind == 28)) {SynErr(184); Get();} Expect(28); endTok = t; ConcreteUpdateStatement update; if (suchThat != null) { var ies = new List<Expression>(); foreach (var lhs in lhss) { ies.Add(new IdentifierExpr(lhs.Tok, lhs.Name)); } update = new AssignSuchThatStmt(assignTok, endTok, ies, suchThat, suchThatAssume, attrs); } else if (rhss.Count == 0) { update = null; } else { var ies = new List<Expression>(); foreach (var lhs in lhss) { ies.Add(new AutoGhostIdentifierExpr(lhs.Tok, lhs.Name)); } update = new UpdateStmt(assignTok, endTok, ies, rhss); } s = new VarDeclStmt(x, endTok, lhss, update); }
void UpdateStmt(out Statement/*!*/ s) { List<Expression> lhss = new List<Expression>(); List<AssignmentRhs> rhss = new List<AssignmentRhs>(); Expression e; AssignmentRhs r; IToken x, endTok = Token.NoToken; Attributes attrs = null; IToken suchThatAssume = null; Expression suchThat = null; Lhs(out e); x = e.tok; if (la.kind == 28 || la.kind == 46) { while (la.kind == 46) { Attribute(ref attrs); } Expect(28); endTok = t; rhss.Add(new ExprRhs(e, attrs)); } else if (la.kind == 22 || la.kind == 25 || la.kind == 95) { lhss.Add(e); while (la.kind == 22) { Get(); Lhs(out e); lhss.Add(e); } if (la.kind == 95) { Get(); x = t; Rhs(out r); rhss.Add(r); while (la.kind == 22) { Get(); Rhs(out r); rhss.Add(r); } } else if (la.kind == 25) { Get(); x = t; if (la.kind == _assume) { Expect(31); suchThatAssume = t; } Expression(out suchThat, false, true); } else SynErr(182); Expect(28); endTok = t; } else if (la.kind == 21) { Get(); SemErr(t, "invalid statement (did you forget the 'label' keyword?)"); } else SynErr(183); if (suchThat != null) { s = new AssignSuchThatStmt(x, endTok, lhss, suchThat, suchThatAssume, null); } else { if (lhss.Count == 0 && rhss.Count == 0) { s = new BlockStmt(x, endTok, new List<Statement>()); // error, give empty statement } else { s = new UpdateStmt(x, endTok, lhss, rhss); } } }
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 static IEnumerable<ProofState> EvaluateSuchThatStmt(AssignSuchThatStmt stmt, ProofState state) { var evaluator = new Atomic.SuchThatAtomic(); return evaluator.Generate(stmt, state); }
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); } }
void VarDeclStatement(out Statement/*!*/ s) { IToken x = null, assignTok = null; bool isGhost = false; LocalVariable d; AssignmentRhs r; List<LocalVariable> lhss = new List<LocalVariable>(); List<AssignmentRhs> rhss = new List<AssignmentRhs>(); IToken suchThatAssume = null; Expression suchThat = null; Attributes attrs = null; IToken endTok; s = dummyStmt; if (la.kind == 65) { Get(); isGhost = true; x = t; } Expect(61); if (!isGhost) { x = t; } if (la.kind == 1 || la.kind == 46) { while (la.kind == 46) { Attribute(ref attrs); } LocalIdentTypeOptional(out d, isGhost); lhss.Add(d); d.Attributes = attrs; attrs = null; while (la.kind == 22) { Get(); while (la.kind == 46) { Attribute(ref attrs); } LocalIdentTypeOptional(out d, isGhost); lhss.Add(d); d.Attributes = attrs; attrs = null; } if (la.kind == 25 || la.kind == 46 || la.kind == 104) { if (la.kind == 104) { Get(); assignTok = t; Rhs(out r); rhss.Add(r); while (la.kind == 22) { Get(); Rhs(out r); rhss.Add(r); } } else { while (la.kind == 46) { Attribute(ref attrs); } Expect(25); assignTok = t; if (la.kind == _assume) { Expect(31); suchThatAssume = t; } Expression(out suchThat, false, true); } } while (!(la.kind == 0 || la.kind == 28)) {SynErr(198); Get();} Expect(28); endTok = t; ConcreteUpdateStatement update; if (suchThat != null) { var ies = new List<Expression>(); foreach (var lhs in lhss) { ies.Add(new IdentifierExpr(lhs.Tok, lhs.Name)); } update = new AssignSuchThatStmt(assignTok, endTok, ies, suchThat, suchThatAssume, attrs); } else if (rhss.Count == 0) { update = null; } else { var ies = new List<Expression>(); foreach (var lhs in lhss) { ies.Add(new AutoGhostIdentifierExpr(lhs.Tok, lhs.Name)); } update = new UpdateStmt(assignTok, endTok, ies, rhss); } s = new VarDeclStmt(x, endTok, lhss, update); } else if (la.kind == 50) { Get(); var letLHSs = new List<CasePattern>(); var letRHSs = new List<Expression>(); List<CasePattern> arguments = new List<CasePattern>(); CasePattern pat; Expression e = dummyExpr; IToken id = t; if (la.kind == 1 || la.kind == 50) { CasePattern(out pat); arguments.Add(pat); while (la.kind == 22) { Get(); CasePattern(out pat); arguments.Add(pat); } } Expect(51); theBuiltIns.TupleType(id, arguments.Count, true); // make sure the tuple type exists string ctor = BuiltIns.TupleTypeCtorName; //use the TupleTypeCtors pat = new CasePattern(id, ctor, arguments); if (isGhost) { pat.Vars.Iter(bv => bv.IsGhost = true); } letLHSs.Add(pat); if (la.kind == 104) { Get(); } else if (la.kind == 25 || la.kind == 46) { while (la.kind == 46) { Attribute(ref attrs); } Expect(25); SemErr(pat.tok, "LHS of assign-such-that expression must be variables, not general patterns"); } else SynErr(199); Expression(out e, false, true); letRHSs.Add(e); Expect(28); s = new LetStmt(e.tok, e.tok, letLHSs, letRHSs); } else SynErr(200); }
public static IEnumerable <ProofState> EvaluateSuchThatStmt(AssignSuchThatStmt stmt, ProofState state) { var evaluator = new Atomic.SuchThatAtomic(); return(evaluator.Generate(stmt, state)); }
public override IEnumerable <ProofState> Generate(Statement statement, ProofState state) { AssignSuchThatStmt suchThat = null; if (statement is AssignSuchThatStmt) { suchThat = (AssignSuchThatStmt)statement; } else { state.ReportTacticError(statement.Tok, "Unexpected statement for suchthat(:|)"); yield break; } var nameExpr = suchThat.Lhss[0]; if (nameExpr is IdentifierExpr) { var id = nameExpr as IdentifierExpr; name = id.Name; } else if (nameExpr is NameSegment) { var id = nameExpr as NameSegment; if (!state.ContainTVal(id.Name)) { state.ReportTacticError(statement.Tok, "Fail to register variable " + id.Name); yield break; } else { name = id.Name; } } else { state.ReportTacticError(statement.Tok, "Fail to register variable."); yield break; } string errInfo; // var expr = Expr.SimpExpr.SimpTacticExpr(state, suchThat.Expr); var expr = suchThat.Expr; /* * if (!CheckExpr(expr, out errInfo)) { * state.ReportTacticError(statement.Tok, "Unexpceted expression in suchthat statement: " + errInfo); * yield break; * }*/ Expression pos, neg, pred; if (!RewriteExpr(expr as BinaryExpr, out pos, out neg, out pred)) { state.ReportTacticError(expr.tok, "Syntax error in Suchthat expression."); yield break; } if (pos != null) { pos = EvalExpr.EvalTacticExpression(state, pos); if (pos == null) { yield break; } } if (neg != null) { neg = EvalExpr.EvalTacticExpression(state, neg); if (neg == null) { yield break; } } if (pos == null) { state.ReportTacticError(statement.Tok, "Suchthat expression is evaluated as an empty sequence."); yield break; } if (pos is SeqDisplayExpr) { if (neg != null && !(neg is SeqDisplayExpr)) { state.ReportTacticError(statement.Tok, "Unexpceted expression in suchthat statement."); yield break; } var eles = EvalExpr.RemoveDup((pos as SeqDisplayExpr).Elements); if (eles.Count == 0) { state.ReportTacticError(statement.Tok, "The expression is evaluated as an empty set."); yield break; } foreach (var item in eles) { var copy = state.Copy(); copy.UpdateTacticVar(name, item); if (neg != null) { var inNeg = EvalExpr.EvalTacticExpression(state, new BinaryExpr(new Token(TacnyDriver.TacticCodeTokLine, 0), BinaryExpr.Opcode.In, item, neg)); if (inNeg is LiteralExpr && (inNeg as LiteralExpr).Value is bool) { if ((bool)(inNeg as LiteralExpr).Value) { continue; } } else { throw new Exception("A unhandled error orrurs when evaluating a suchtaht statement"); } } if (pred != null) { var value = new BinaryExpr(new Token(TacnyDriver.TacticCodeTokLine, 0), BinaryExpr.Opcode.Eq, suchThat.Lhss[0].Copy(), item); var candidate = new BinaryExpr(new Token(TacnyDriver.TacticCodeTokLine, 0), BinaryExpr.Opcode.Add, value, pred); var res = EvalExpr.EvalTacticExpression(copy, pred); Console.WriteLine(Printer.ExprToString(res)); if (res is LiteralExpr && (res as LiteralExpr).Value is bool) { if (!(bool)(res as LiteralExpr).Value) { continue; } } else { throw new Exception("A unhandled error orrurs when evaluating a suchtaht statement"); } } yield return(copy); } } else { state.ReportTacticError(statement.Tok, "Unexpceted expression in suchthat statement."); yield break; } }