public virtual ExistsExpr VisitExistsExpr(ExistsExpr node) { Contract.Requires(node != null); Contract.Ensures(Contract.Result <ExistsExpr>() != null); node = (ExistsExpr)this.VisitQuantifierExpr(node); return(node); }
public Expr DisjointnessExpr(string domainName, HashSet <Variable> scope) { LinearDomain domain = linearDomains[domainName]; BoundVariable partition = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, string.Format("partition_{0}", domainName), new MapType(Token.NoToken, new List <TypeVariable>(), new List <Type> { domain.elementType }, Microsoft.Boogie.Type.Int))); Expr disjointExpr = Expr.True; int count = 0; foreach (Variable v in scope) { IdentifierExpr ie = new IdentifierExpr(Token.NoToken, v); Expr e = new NAryExpr(Token.NoToken, new FunctionCall(domain.mapConstInt), new List <Expr> { new LiteralExpr(Token.NoToken, Microsoft.Basetypes.BigNum.FromInt(count++)) }); e = new NAryExpr(Token.NoToken, new FunctionCall(domain.mapEqInt), new List <Expr> { new IdentifierExpr(Token.NoToken, partition), e }); e = new NAryExpr(Token.NoToken, new FunctionCall(domain.mapImpBool), new List <Expr> { v.TypedIdent.Type is MapType ? ie : Singleton(ie, domainName), e }); e = Expr.Binary(BinaryOperator.Opcode.Eq, e, new NAryExpr(Token.NoToken, new FunctionCall(domain.mapConstBool), new List <Expr> { Expr.True })); disjointExpr = Expr.Binary(BinaryOperator.Opcode.And, e, disjointExpr); } var expr = new ExistsExpr(Token.NoToken, new List <Variable> { partition }, disjointExpr); expr.Resolve(new ResolutionContext(null)); expr.Typecheck(new TypecheckingContext(null)); return(expr); }
private Expr CalculatePathCondition(PathInfo path) { Expr returnExpr = Expr.True; HashSet <Variable> existsVars = path.existsVars; Dictionary <Variable, Expr> existsMap = new Dictionary <Variable, Expr>(); Dictionary <Variable, Expr> varToExpr = path.varToExpr; foreach (Variable v in varToExpr.Keys) { if (postExistVars.Contains(v)) { continue; } IdentifierExpr ie = varToExpr[v] as IdentifierExpr; if (ie != null && !existsMap.ContainsKey(ie.Decl) && existsVars.Contains(ie.Decl)) { existsMap[ie.Decl] = Expr.Ident(v); existsVars.Remove(ie.Decl); } else { returnExpr = Expr.And(returnExpr, Expr.Eq(Expr.Ident(v), (new MyDuplicator()).VisitExpr(varToExpr[v]))); returnExpr.Type = Type.Bool; } } List <Expr> pathExprs = new List <Expr>(); path.pathExprs.ForEach(x => pathExprs.Add((new MyDuplicator()).VisitExpr(x))); foreach (Expr x in pathExprs) { Variable boundVar; Expr boundVarExpr; if (InferSubstitution(x, out boundVar, out boundVarExpr) && existsVars.Contains(boundVar)) { existsMap[boundVar] = boundVarExpr; existsVars.Remove(boundVar); } else { returnExpr = Expr.And(returnExpr, x); returnExpr.Type = Type.Bool; } } returnExpr = Substituter.Apply(Substituter.SubstitutionFromHashtable(existsMap), returnExpr); if (existsVars.Count > 0) { returnExpr = new ExistsExpr(Token.NoToken, new List <Variable>(existsVars), returnExpr); } return(returnExpr); }
public Expr DisjointnessExprForPermissions(string domainName, IEnumerable<Expr> permissionsExprs) { Expr expr = Expr.True; if (permissionsExprs.Count() > 1) { int count = 0; List<Expr> subsetExprs = new List<Expr>(); LinearDomain domain = linearDomains[domainName]; BoundVariable partition = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, $"partition_{domainName}", domain.mapTypeInt)); foreach (Expr e in permissionsExprs) { subsetExprs.Add(SubsetExpr(domain, e, partition, count)); count++; } expr = new ExistsExpr(Token.NoToken, new List<Variable> {partition}, Expr.And(subsetExprs)); } expr.Resolve(new ResolutionContext(null)); expr.Typecheck(new TypecheckingContext(null)); return expr; }
void PrintExistentialGuard(ExistsExpr guard) { Contract.Requires(guard != null); Contract.Requires(guard.Range == null); PrintQuantifierDomain(guard.BoundVars, guard.Attributes, null); wr.Write(" :| "); PrintExpression(guard.Term, false); }
public override QuantifierExpr VisitQuantifierExpr(QuantifierExpr node) { var oldE = existentialExpr; if (node is ExistsExpr) existentialExpr = (node as ExistsExpr); node = base.VisitQuantifierExpr(node); existentialExpr = oldE; return node; }
public FunctionCollector() { functionsUsed = new List<Tuple<Function, ExistsExpr>>(); existentialExpr = null; }
public override ExistsExpr VisitExistsExpr(ExistsExpr node) { //Contract.Requires(node != null); Contract.Ensures(Contract.Result <ExistsExpr>() != null); return(base.VisitExistsExpr((ExistsExpr)node.Clone())); }
public void SimpleExists() { var boundVar = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken,"foo",Microsoft.Boogie.Type.Bool)); var id = new IdentifierExpr(Token.NoToken, boundVar); var exists = new ExistsExpr(Token.NoToken, new List<Variable>() { boundVar }, id); var id2 = new IdentifierExpr(Token.NoToken, boundVar); var exists2 = new ExistsExpr(Token.NoToken, new List<Variable>() { boundVar }, id2); Assert.AreNotSame(exists, exists2); // These are different references Assert.IsTrue(exists.Equals(exists2)); // These are "structurally equal" Assert.AreEqual(exists.GetHashCode(), exists2.GetHashCode()); // If the .Equals() is true then hash codes must be the same }
protected override Cmd ComputeDesugaring() { Contract.Ensures(Contract.Result<Cmd>() != null); List<Cmd> newBlockBody = new List<Cmd>(); Dictionary<Variable, Expr> substMap = new Dictionary<Variable, Expr>(); Dictionary<Variable, Expr> substMapOld = new Dictionary<Variable, Expr>(); Dictionary<Variable, Expr> substMapBound = new Dictionary<Variable, Expr>(); List<Variable>/*!*/ tempVars = new List<Variable>(); // proc P(ins) returns (outs) // requires Pre // //modifies frame // ensures Post // // call aouts := P(ains) // ins : formal in parameters of procedure // frame : a list of global variables from the modifies clause // outs : formal out parameters of procedure // ains : actual in arguments passed to call // aouts : actual variables assigned to from call // cins : new variables created just for this call, one per ains // cframe : new variables created just for this call, to keep track of OLD values // couts : new variables created just for this call, one per aouts // WildcardVars : new variables created just for this call, one per null in ains #region Create cins; each one is an incarnation of the corresponding in parameter List<Variable>/*!*/ cins = new List<Variable>(); List<Variable> wildcardVars = new List<Variable>(); Contract.Assume(this.Proc != null); for (int i = 0; i < this.Proc.InParams.Count; ++i) { Variable/*!*/ param = cce.NonNull(this.Proc.InParams[i]); bool isWildcard = this.Ins[i] == null; Type/*!*/ actualType; if (isWildcard) actualType = param.TypedIdent.Type.Substitute(TypeParamSubstitution()); else // during type checking, we have ensured that the type of the actual // parameter Ins[i] is correct, so we can use it here actualType = cce.NonNull(cce.NonNull(Ins[i]).Type); Variable cin = CreateTemporaryVariable(tempVars, param, actualType, TempVarKind.Formal); cins.Add(cin); IdentifierExpr ie = new IdentifierExpr(cin.tok, cin); substMap.Add(param, ie); if (isWildcard) { cin = CreateTemporaryVariable(tempVars, param, actualType, TempVarKind.Bound); wildcardVars.Add(cin); ie = new IdentifierExpr(cin.tok, cin); } substMapBound.Add(param, ie); } #endregion #region call aouts := P(ains) becomes: (open outlining one level to see) #region cins := ains (or havoc cin when ain is null) for (int i = 0, n = this.Ins.Count; i < n; i++) { IdentifierExpr/*!*/ cin_exp = new IdentifierExpr(cce.NonNull(cins[i]).tok, cce.NonNull(cins[i])); Contract.Assert(cin_exp != null); if (this.Ins[i] != null) { AssignCmd assign = Cmd.SimpleAssign(Token.NoToken, cin_exp, cce.NonNull(this.Ins[i])); newBlockBody.Add(assign); } else { List<IdentifierExpr>/*!*/ ies = new List<IdentifierExpr>(); ies.Add(cin_exp); HavocCmd havoc = new HavocCmd(Token.NoToken, ies); newBlockBody.Add(havoc); } } #endregion #region assert (exists wildcardVars :: Pre[ins := cins]) Substitution s = Substituter.SubstitutionFromHashtable(substMapBound); bool hasWildcard = (wildcardVars.Count != 0); Expr preConjunction = null; for (int i = 0; i < this.Proc.Requires.Count; i++) { Requires/*!*/ req = cce.NonNull(this.Proc.Requires[i]); if (!req.Free && !IsFree) { if (hasWildcard) { Expr pre = Substituter.Apply(s, req.Condition); if (preConjunction == null) { preConjunction = pre; } else { preConjunction = Expr.And(preConjunction, pre); } } else { Requires/*!*/ reqCopy = (Requires/*!*/)cce.NonNull(req.Clone()); reqCopy.Condition = Substituter.Apply(s, req.Condition); AssertCmd/*!*/ a = new AssertRequiresCmd(this, reqCopy); Contract.Assert(a != null); a.ErrorDataEnhanced = reqCopy.ErrorDataEnhanced; newBlockBody.Add(a); } } else if (CommandLineOptions.Clo.StratifiedInlining > 0) { // inject free requires as assume statements at the call site AssumeCmd/*!*/ a = new AssumeCmd(req.tok, Substituter.Apply(s, req.Condition)); Contract.Assert(a != null); newBlockBody.Add(a); } } if (hasWildcard) { if (preConjunction == null) { preConjunction = Expr.True; } Expr/*!*/ expr = new ExistsExpr(tok, wildcardVars, preConjunction); Contract.Assert(expr != null); AssertCmd/*!*/ a = new AssertCmd(tok, expr); Contract.Assert(a != null); a.ErrorDataEnhanced = AssertCmd.GenerateBoundVarMiningStrategy(expr); newBlockBody.Add(a); } #endregion #region assume Pre[ins := cins] with formal paramters if (hasWildcard) { s = Substituter.SubstitutionFromHashtable(substMap); for (int i = 0; i < this.Proc.Requires.Count; i++) { Requires/*!*/ req = cce.NonNull(this.Proc.Requires[i]); if (!req.Free) { Requires/*!*/ reqCopy = (Requires/*!*/)cce.NonNull(req.Clone()); reqCopy.Condition = Substituter.Apply(s, req.Condition); AssumeCmd/*!*/ a = new AssumeCmd(tok, reqCopy.Condition); Contract.Assert(a != null); newBlockBody.Add(a); } } } #endregion #region cframe := frame (to hold onto frame values in case they are referred to in the postcondition) List<IdentifierExpr> havocVarExprs = new List<IdentifierExpr>(); foreach (IdentifierExpr/*!*/ f in this.Proc.Modifies) { Contract.Assert(f != null); Contract.Assume(f.Decl != null); Contract.Assert(f.Type != null); Variable v = CreateTemporaryVariable(tempVars, f.Decl, f.Type, TempVarKind.Old); IdentifierExpr v_exp = new IdentifierExpr(v.tok, v); substMapOld.Add(f.Decl, v_exp); // this assumes no duplicates in this.Proc.Modifies AssignCmd assign = Cmd.SimpleAssign(f.tok, v_exp, f); newBlockBody.Add(assign); // fra if (!havocVarExprs.Contains(f)) havocVarExprs.Add(f); } #endregion #region Create couts List<Variable>/*!*/ couts = new List<Variable>(); for (int i = 0; i < this.Proc.OutParams.Count; ++i) { Variable/*!*/ param = cce.NonNull(this.Proc.OutParams[i]); bool isWildcard = this.Outs[i] == null; Type/*!*/ actualType; if (isWildcard) actualType = param.TypedIdent.Type.Substitute(TypeParamSubstitution()); else // during type checking, we have ensured that the type of the actual // out parameter Outs[i] is correct, so we can use it here actualType = cce.NonNull(cce.NonNull(Outs[i]).Type); Variable cout = CreateTemporaryVariable(tempVars, param, actualType, TempVarKind.Formal); couts.Add(cout); IdentifierExpr ie = new IdentifierExpr(cout.tok, cout); substMap.Add(param, ie); if (!havocVarExprs.Contains(ie)) havocVarExprs.Add(ie); } // add the where clauses, now that we have the entire substitution map foreach (Variable/*!*/ param in this.Proc.OutParams) { Contract.Assert(param != null); Expr w = param.TypedIdent.WhereExpr; if (w != null) { IdentifierExpr ie = (IdentifierExpr/*!*/)cce.NonNull(substMap[param]); Contract.Assert(ie.Decl != null); ie.Decl.TypedIdent.WhereExpr = Substituter.Apply(Substituter.SubstitutionFromHashtable(substMap), w); } } #endregion #region havoc frame, couts // pass on this's token HavocCmd hc = new HavocCmd(this.tok, havocVarExprs); newBlockBody.Add(hc); #endregion #region assume Post[ins, outs, old(frame) := cins, couts, cframe] Substitution s2 = Substituter.SubstitutionFromHashtable(substMap); Substitution s2old = Substituter.SubstitutionFromHashtable(substMapOld); foreach (Ensures/*!*/ e in this.Proc.Ensures) { Contract.Assert(e != null); Expr copy = Substituter.ApplyReplacingOldExprs(s2, s2old, e.Condition); AssumeCmd assume = new AssumeCmd(this.tok, copy); #region stratified inlining support if (QKeyValue.FindBoolAttribute(e.Attributes, "si_fcall")) { assume.Attributes = Attributes; } if (QKeyValue.FindBoolAttribute(e.Attributes, "candidate")) { assume.Attributes = new QKeyValue(Token.NoToken, "candidate", new List<object>(), assume.Attributes); assume.Attributes.Params.Add(this.callee); } #endregion newBlockBody.Add(assume); } #endregion #region aouts := couts for (int i = 0, n = this.Outs.Count; i < n; i++) { if (this.Outs[i] != null) { Variable/*!*/ param_i = cce.NonNull(this.Proc.OutParams[i]); Expr/*!*/ cout_exp = new IdentifierExpr(cce.NonNull(couts[i]).tok, cce.NonNull(couts[i])); Contract.Assert(cout_exp != null); AssignCmd assign = Cmd.SimpleAssign(param_i.tok, cce.NonNull(this.Outs[i]), cout_exp); newBlockBody.Add(assign); } } #endregion #endregion return new StateCmd(this.tok, tempVars, newBlockBody); }
void QuantifierGuts(out Expression q, bool allowSemi, bool allowLambda) { Contract.Ensures(Contract.ValueAtReturn(out q) != null); IToken/*!*/ x = Token.NoToken; bool univ = false; List<BoundVar/*!*/> bvars; Attributes attrs; Expression range; Expression/*!*/ body; if (la.kind == 103 || la.kind == 123) { Forall(); x = t; univ = true; } else if (la.kind == 124 || la.kind == 125) { Exists(); x = t; } else SynErr(238); QuantifierDomain(out bvars, out attrs, out range); QSep(); Expression(out body, allowSemi, allowLambda); if (univ) { q = new ForallExpr(x, bvars, range, body, attrs); } else { q = new ExistsExpr(x, bvars, range, body, attrs); } }
public override Expr VisitExistsExpr(ExistsExpr node) { Contract.Ensures(Contract.Result<Expr>() == node); return (ExistsExpr)this.VisitQuantifierExpr(node); }
private Expr CalculatePathCondition() { Expr returnExpr = Expr.True; foreach (Variable v in program.GlobalVariables()) { var eqExpr = Expr.Eq(new IdentifierExpr(Token.NoToken, v), new OldExpr(Token.NoToken, new IdentifierExpr(Token.NoToken, v))); returnExpr = Expr.And(eqExpr, returnExpr); } if (first != null) { foreach (Variable v in first.thisOutParams) { var eqExpr = Expr.Eq(new IdentifierExpr(Token.NoToken, v), new OldExpr(Token.NoToken, new IdentifierExpr(Token.NoToken, v))); returnExpr = Expr.And(eqExpr, returnExpr); } } foreach (Variable v in second.thatOutParams) { var eqExpr = Expr.Eq(new IdentifierExpr(Token.NoToken, v), new OldExpr(Token.NoToken, new IdentifierExpr(Token.NoToken, v))); returnExpr = Expr.And(eqExpr, returnExpr); } Block[] dfsStackAsArray = dfsStack.Reverse().ToArray(); for (int i = dfsStackAsArray.Length - 1; i >= 0; i--) { Block b = dfsStackAsArray[i]; for (int j = b.Cmds.Count - 1; j >= 0; j--) { Cmd cmd = b.Cmds[j]; if (cmd is AssumeCmd) { AssumeCmd assumeCmd = cmd as AssumeCmd; returnExpr = Expr.And(new OldExpr(Token.NoToken, assumeCmd.Expr), returnExpr); } else if (cmd is AssignCmd) { AssignCmd assignCmd = (cmd as AssignCmd).AsSimpleAssignCmd; Dictionary <Variable, Expr> map = new Dictionary <Variable, Expr>(); for (int k = 0; k < assignCmd.Lhss.Count; k++) { map[assignCmd.Lhss[k].DeepAssignedVariable] = assignCmd.Rhss[k]; } Substitution subst = Substituter.SubstitutionFromHashtable(new Dictionary <Variable, Expr>()); Substitution oldSubst = Substituter.SubstitutionFromHashtable(map); returnExpr = (Expr) new MySubstituter(subst, oldSubst).Visit(returnExpr); } else if (cmd is HavocCmd) { HavocCmd havocCmd = cmd as HavocCmd; List <Variable> existVars = new List <Variable>(); Dictionary <Variable, Expr> map = new Dictionary <Variable, Expr>(); foreach (IdentifierExpr ie in havocCmd.Vars) { BoundVariable bv = GetBoundVariable(ie.Decl.TypedIdent.Type); map[ie.Decl] = new IdentifierExpr(Token.NoToken, bv); existVars.Add(bv); } Substitution subst = Substituter.SubstitutionFromHashtable(new Dictionary <Variable, Expr>()); Substitution oldSubst = Substituter.SubstitutionFromHashtable(map); returnExpr = new ExistsExpr(Token.NoToken, existVars, (Expr) new MySubstituter(subst, oldSubst).Visit(returnExpr)); } else { Debug.Assert(false); } } } return(returnExpr); }
private void CreateFailurePreservationChecker(Program program, ActionInfo first, ActionInfo second) { Tuple <ActionInfo, ActionInfo> actionPair = new Tuple <ActionInfo, ActionInfo>(first, second); if (failurePreservationCheckerCache.Contains(actionPair)) { return; } failurePreservationCheckerCache.Add(actionPair); List <Variable> inputs = new List <Variable>(); inputs.AddRange(first.thisInParams); inputs.AddRange(second.thatInParams); Expr transitionRelation = (new TransitionRelationComputation(program, second)).Compute(); Expr expr = Expr.True; foreach (AssertCmd assertCmd in first.thisGate) { expr = Expr.And(assertCmd.Expr, expr); } List <Requires> requires = DisjointnessRequires(program, first, second); requires.Add(new Requires(false, Expr.Not(expr))); foreach (AssertCmd assertCmd in second.thatGate) { requires.Add(new Requires(false, assertCmd.Expr)); } Dictionary <Variable, Expr> map = new Dictionary <Variable, Expr>(); Dictionary <Variable, Expr> oldMap = new Dictionary <Variable, Expr>(); List <Variable> boundVars = new List <Variable>(); foreach (Variable v in program.GlobalVariables()) { BoundVariable bv = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "post_" + v.Name, v.TypedIdent.Type)); boundVars.Add(bv); map[v] = new IdentifierExpr(Token.NoToken, bv); } foreach (Variable v in second.thatOutParams) { { BoundVariable bv = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "post_" + v.Name, v.TypedIdent.Type)); boundVars.Add(bv); map[v] = new IdentifierExpr(Token.NoToken, bv); } { BoundVariable bv = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "pre_" + v.Name, v.TypedIdent.Type)); boundVars.Add(bv); oldMap[v] = new IdentifierExpr(Token.NoToken, bv); } } foreach (Variable v in second.thatAction.LocVars) { BoundVariable bv = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "pre_" + v.Name, v.TypedIdent.Type)); boundVars.Add(bv); oldMap[v] = new IdentifierExpr(Token.NoToken, bv); } Expr ensuresExpr = Expr.And(transitionRelation, Expr.Not(expr)); if (boundVars.Count > 0) { Substitution subst = Substituter.SubstitutionFromHashtable(map); Substitution oldSubst = Substituter.SubstitutionFromHashtable(oldMap); ensuresExpr = new ExistsExpr(Token.NoToken, boundVars, (Expr) new MySubstituter(subst, oldSubst).Visit(ensuresExpr)); } List <Ensures> ensures = new List <Ensures>(); ensures.Add(new Ensures(false, ensuresExpr)); List <Block> blocks = new List <Block>(); blocks.Add(new Block(Token.NoToken, "L", new List <Cmd>(), new ReturnCmd(Token.NoToken))); string checkerName = string.Format("FailurePreservationChecker_{0}_{1}", first.proc.Name, second.proc.Name); List <IdentifierExpr> globalVars = new List <IdentifierExpr>(); program.GlobalVariables().Iter(x => globalVars.Add(new IdentifierExpr(Token.NoToken, x))); Procedure proc = new Procedure(Token.NoToken, checkerName, new List <TypeVariable>(), inputs, new List <Variable>(), requires, globalVars, ensures); Implementation impl = new Implementation(Token.NoToken, checkerName, new List <TypeVariable>(), inputs, new List <Variable>(), new List <Variable>(), blocks); impl.Proc = proc; this.decls.Add(impl); this.decls.Add(proc); }
private Expr CalculatePathCondition(PathInfo path) { HashSet <Variable> allExistsVars = new HashSet <Variable>(firstExistsVars.Union(secondExistsVars)); HashSet <Variable> usedExistsVars = new HashSet <Variable>(); Dictionary <Variable, Expr> existsSubstitutionMap = new Dictionary <Variable, Expr>(); List <Expr> inferredSelectEqualities = new List <Expr>(); foreach (Variable v in path.varToExpr.Keys.Except(postExistVars)) { var expr = path.varToExpr[v]; usedExistsVars.UnionWith(VariableCollector.Collect(expr).Intersect(allExistsVars)); IdentifierExpr ie = expr as IdentifierExpr; if (ie != null && IsExistsVar(ie.Decl) && !existsSubstitutionMap.ContainsKey(ie.Decl)) { existsSubstitutionMap[ie.Decl] = Expr.Ident(v); } else if (IsMapStoreExpr(expr)) { inferredSelectEqualities.Add(GenerateEqualityWithSelect(expr as NAryExpr, Expr.Ident(v))); } } foreach (Expr expr in path.pathExprs) { usedExistsVars.UnionWith(VariableCollector.Collect(expr).Intersect(allExistsVars)); } InferSubstitution(allExistsVars, existsSubstitutionMap, path.pathExprs, inferredSelectEqualities); List <Expr> triggerExprs = new List <Expr>(); List <Variable> quantifiedVars = new List <Variable>(); foreach (var v in usedExistsVars.Except(existsSubstitutionMap.Keys)) { var triggerFun = TriggerFunction(v); // this call populates existsVars[v] var quantifiedVar = existsVars[v]; triggerExprs.Add( new NAryExpr(Token.NoToken, new FunctionCall(triggerFun), new Expr[] { Expr.Ident(quantifiedVar) })); quantifiedVars.Add(quantifiedVar); existsSubstitutionMap[v] = Expr.Ident(quantifiedVar); } Substitution subst = Substituter.SubstitutionFromHashtable(existsSubstitutionMap); List <Expr> returnExprs = new List <Expr>(); foreach (Variable v in path.varToExpr.Keys.Except(postExistVars)) { Expr withOldExpr = MyDuplicator.Duplicate(path.varToExpr[v]); var substExpr = Expr.Eq(Expr.Ident(v), Substituter.Apply(subst, withOldExpr)); substExpr.Type = Type.Bool; returnExprs.Add(substExpr); } foreach (Expr x in path.pathExprs) { var withOldExpr = MyDuplicator.Duplicate(x); returnExprs.Add(Substituter.Apply(subst, withOldExpr)); } var returnExpr = Expr.And(returnExprs); if (quantifiedVars.Count > 0) { if (first == null) { returnExpr = new ExistsExpr(Token.NoToken, quantifiedVars, returnExpr); } else { returnExpr = new ExistsExpr(Token.NoToken, quantifiedVars, new Trigger(Token.NoToken, true, triggerExprs), returnExpr); } } return(returnExpr); }
private void CreateFailurePreservationChecker(Program program, ActionInfo first, ActionInfo second) { Tuple<ActionInfo, ActionInfo> actionPair = new Tuple<ActionInfo, ActionInfo>(first, second); if (failurePreservationCheckerCache.Contains(actionPair)) return; failurePreservationCheckerCache.Add(actionPair); List<Variable> inputs = new List<Variable>(); inputs.AddRange(first.thisInParams); inputs.AddRange(second.thatInParams); Expr transitionRelation = (new TransitionRelationComputation(program, second)).Compute(); Expr expr = Expr.True; foreach (AssertCmd assertCmd in first.thisGate) { expr = Expr.And(assertCmd.Expr, expr); } List<Requires> requires = DisjointnessRequires(program, first, second); requires.Add(new Requires(false, Expr.Not(expr))); foreach (AssertCmd assertCmd in second.thatGate) { requires.Add(new Requires(false, assertCmd.Expr)); } Dictionary<Variable, Expr> map = new Dictionary<Variable, Expr>(); Dictionary<Variable, Expr> oldMap = new Dictionary<Variable, Expr>(); List<Variable> boundVars = new List<Variable>(); foreach (Variable v in program.GlobalVariables()) { BoundVariable bv = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "post_" + v.Name, v.TypedIdent.Type)); boundVars.Add(bv); map[v] = new IdentifierExpr(Token.NoToken, bv); } foreach (Variable v in second.thatOutParams) { { BoundVariable bv = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "post_" + v.Name, v.TypedIdent.Type)); boundVars.Add(bv); map[v] = new IdentifierExpr(Token.NoToken, bv); } { BoundVariable bv = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "pre_" + v.Name, v.TypedIdent.Type)); boundVars.Add(bv); oldMap[v] = new IdentifierExpr(Token.NoToken, bv); } } foreach (Variable v in second.thatAction.LocVars) { BoundVariable bv = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "pre_" + v.Name, v.TypedIdent.Type)); boundVars.Add(bv); oldMap[v] = new IdentifierExpr(Token.NoToken, bv); } Expr ensuresExpr = Expr.And(transitionRelation, Expr.Not(expr)); if (boundVars.Count > 0) { Substitution subst = Substituter.SubstitutionFromHashtable(map); Substitution oldSubst = Substituter.SubstitutionFromHashtable(oldMap); ensuresExpr = new ExistsExpr(Token.NoToken, boundVars, (Expr)new MySubstituter(subst, oldSubst).Visit(ensuresExpr)); } List<Ensures> ensures = new List<Ensures>(); ensures.Add(new Ensures(false, ensuresExpr)); List<Block> blocks = new List<Block>(); blocks.Add(new Block(Token.NoToken, "L", new List<Cmd>(), new ReturnCmd(Token.NoToken))); string checkerName = string.Format("FailurePreservationChecker_{0}_{1}", first.proc.Name, second.proc.Name); List<IdentifierExpr> globalVars = new List<IdentifierExpr>(); program.GlobalVariables().Iter(x => globalVars.Add(new IdentifierExpr(Token.NoToken, x))); Procedure proc = new Procedure(Token.NoToken, checkerName, new List<TypeVariable>(), inputs, new List<Variable>(), requires, globalVars, ensures); Implementation impl = new Implementation(Token.NoToken, checkerName, new List<TypeVariable>(), inputs, new List<Variable>(), new List<Variable>(), blocks); impl.Proc = proc; this.decls.Add(impl); this.decls.Add(proc); }
private Expr CalculatePathCondition(PathInfo path) { HashSet<Variable> allExistsVars = new HashSet<Variable>(firstExistsVars.Union(secondExistsVars)); HashSet<Variable> usedExistsVars = new HashSet<Variable>(); Dictionary<Variable, Expr> existsSubstitutionMap = new Dictionary<Variable, Expr>(); List<Expr> inferredSelectEqualities = new List<Expr>(); foreach (Variable v in path.varToExpr.Keys.Except(postExistVars)) { var expr = path.varToExpr[v]; usedExistsVars.UnionWith(VariableCollector.Collect(expr).Intersect(allExistsVars)); IdentifierExpr ie = expr as IdentifierExpr; if (ie != null && IsExistsVar(ie.Decl) && !existsSubstitutionMap.ContainsKey(ie.Decl)) { existsSubstitutionMap[ie.Decl] = Expr.Ident(v); } else if (IsMapStoreExpr(expr)) { inferredSelectEqualities.Add(GenerateEqualityWithSelect(expr as NAryExpr, Expr.Ident(v))); } } foreach (Expr expr in path.pathExprs) { usedExistsVars.UnionWith(VariableCollector.Collect(expr).Intersect(allExistsVars)); } InferSubstitution(allExistsVars, existsSubstitutionMap, path.pathExprs, inferredSelectEqualities); List<Expr> triggerExprs = new List<Expr>(); List<Variable> quantifiedVars = new List<Variable>(); foreach (var v in usedExistsVars.Except(existsSubstitutionMap.Keys)) { var triggerFun = TriggerFunction(v); // this call populates existsVars[v] var quantifiedVar = existsVars[v]; triggerExprs.Add( new NAryExpr(Token.NoToken, new FunctionCall(triggerFun), new Expr[] { Expr.Ident(quantifiedVar) })); quantifiedVars.Add(quantifiedVar); existsSubstitutionMap[v] = Expr.Ident(quantifiedVar); } Substitution subst = Substituter.SubstitutionFromHashtable(existsSubstitutionMap); List<Expr> returnExprs = new List<Expr>(); foreach (Variable v in path.varToExpr.Keys.Except(postExistVars)) { Expr withOldExpr = MyDuplicator.Duplicate(path.varToExpr[v]); var substExpr = Expr.Eq(Expr.Ident(v), Substituter.Apply(subst, withOldExpr)); substExpr.Type = Type.Bool; returnExprs.Add(substExpr); } foreach (Expr x in path.pathExprs) { var withOldExpr = MyDuplicator.Duplicate(x); returnExprs.Add(Substituter.Apply(subst, withOldExpr)); } var returnExpr = Expr.And(returnExprs); if (quantifiedVars.Count > 0) { if (first == null) { returnExpr = new ExistsExpr(Token.NoToken, quantifiedVars, returnExpr); } else { returnExpr = new ExistsExpr(Token.NoToken, quantifiedVars, new Trigger(Token.NoToken, true, triggerExprs), returnExpr); } } return returnExpr; }
void AtomExpression(out Expr/*!*/ e) { Contract.Ensures(Contract.ValueAtReturn(out e) != null); IToken/*!*/ x; int n; BigNum bn; BigDec bd; BigFloat bf; List<Expr>/*!*/ es; List<Variable>/*!*/ ds; Trigger trig; List<TypeVariable>/*!*/ typeParams; IdentifierExpr/*!*/ id; QKeyValue kv; e = dummyExpr; List<Variable>/*!*/ locals; List<Block/*!*/>/*!*/ blocks; switch (la.kind) { case 83: { Get(); e = new LiteralExpr(t, false); break; } case 84: { Get(); e = new LiteralExpr(t, true); break; } case 3: { Nat(out bn); e = new LiteralExpr(t, bn); break; } case 5: case 6: { Dec(out bd); e = new LiteralExpr(t, bd); break; } case 7: { Float(out bf); e = new LiteralExpr(t, bf); break; } case 2: { BvLit(out bn, out n); e = new LiteralExpr(t, bn, n); break; } case 1: { Ident(out x); id = new IdentifierExpr(x, x.val); e = id; if (la.kind == 10) { Get(); if (StartOf(9)) { Expressions(out es); e = new NAryExpr(x, new FunctionCall(id), es); } else if (la.kind == 11) { e = new NAryExpr(x, new FunctionCall(id), new List<Expr>()); } else SynErr(124); Expect(11); } break; } case 85: { Get(); x = t; Expect(10); Expression(out e); Expect(11); e = new OldExpr(x, e); break; } case 15: { Get(); x = t; Expect(10); Expression(out e); Expect(11); e = new NAryExpr(x, new ArithmeticCoercion(x, ArithmeticCoercion.CoercionType.ToInt), new List<Expr>{ e }); break; } case 16: { Get(); x = t; Expect(10); Expression(out e); Expect(11); e = new NAryExpr(x, new ArithmeticCoercion(x, ArithmeticCoercion.CoercionType.ToReal), new List<Expr>{ e }); break; } case 10: { Get(); if (StartOf(9)) { Expression(out e); if (e is BvBounds) this.SemErr("parentheses around bitvector bounds " + "are not allowed"); } else if (la.kind == 89 || la.kind == 90) { Forall(); x = t; QuantifierBody(x, out typeParams, out ds, out kv, out trig, out e); if (typeParams.Count + ds.Count > 0) e = new ForallExpr(x, typeParams, ds, kv, trig, e); } else if (la.kind == 91 || la.kind == 92) { Exists(); x = t; QuantifierBody(x, out typeParams, out ds, out kv, out trig, out e); if (typeParams.Count + ds.Count > 0) e = new ExistsExpr(x, typeParams, ds, kv, trig, e); } else if (la.kind == 93 || la.kind == 94) { Lambda(); x = t; QuantifierBody(x, out typeParams, out ds, out kv, out trig, out e); if (trig != null) SemErr("triggers not allowed in lambda expressions"); if (typeParams.Count + ds.Count > 0) e = new LambdaExpr(x, typeParams, ds, kv, e); } else SynErr(125); Expect(11); break; } case 41: { IfThenElseExpression(out e); break; } case 86: { CodeExpression(out locals, out blocks); e = new CodeExpr(locals, blocks); break; } default: SynErr(126); break; } }
private void IntroduceAndAssignBoundVars(int indent, ExistsExpr exists, TextWriter wr) { Contract.Requires(0 <= indent); Contract.Requires(exists != null); Contract.Assume(exists.Bounds != null); // follows from successful resolution Contract.Assert(exists.Range == null); // follows from invariant of class IfStmt foreach (var bv in exists.BoundVars) { TrLocalVar(bv, false, indent, wr); } var ivars = exists.BoundVars.ConvertAll(bv => (IVariable)bv); TrAssignSuchThat(indent, ivars, exists.Term, exists.Bounds, exists.tok.line, wr, false); }
void ExistentialGuard(out Expression e, bool allowLambda) { var bvars = new List<BoundVar>(); BoundVar bv; IToken x; Attributes attrs = null; Expression body; IdentTypeOptional(out bv); bvars.Add(bv); x = bv.tok; while (la.kind == 22) { Get(); IdentTypeOptional(out bv); bvars.Add(bv); } while (la.kind == 46) { Attribute(ref attrs); } Expect(25); Expression(out body, true, allowLambda); e = new ExistsExpr(x, bvars, null, body, attrs); }
public void CachedHashCodeExistsExpr() { var x = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", BasicType.Int)); var y = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", BasicType.Int)); var body = Expr.Gt (new IdentifierExpr (Token.NoToken, x, /*immutable=*/true), new IdentifierExpr(Token.NoToken, y, /*immutable=*/true)); var exists = new ExistsExpr(Token.NoToken, new List<Variable> () {x, y }, body, /*immutable=*/ true); Assert.AreEqual(exists.ComputeHashCode(), exists.GetHashCode()); }
public virtual Expr VisitExistsExpr(ExistsExpr node) { Contract.Requires(node != null); Contract.Ensures(Contract.Result<Expr>() != null); node = (ExistsExpr)this.VisitQuantifierExpr(node); return node; }
private Expr CalculatePathCondition() { Expr returnExpr = Expr.True; foreach (Variable v in program.GlobalVariables()) { var eqExpr = Expr.Eq(new IdentifierExpr(Token.NoToken, v), new OldExpr(Token.NoToken, new IdentifierExpr(Token.NoToken, v))); returnExpr = Expr.And(eqExpr, returnExpr); } if (first != null) { foreach (Variable v in first.thisOutParams) { var eqExpr = Expr.Eq(new IdentifierExpr(Token.NoToken, v), new OldExpr(Token.NoToken, new IdentifierExpr(Token.NoToken, v))); returnExpr = Expr.And(eqExpr, returnExpr); } } foreach (Variable v in second.thatOutParams) { var eqExpr = Expr.Eq(new IdentifierExpr(Token.NoToken, v), new OldExpr(Token.NoToken, new IdentifierExpr(Token.NoToken, v))); returnExpr = Expr.And(eqExpr, returnExpr); } Block[] dfsStackAsArray = dfsStack.Reverse().ToArray(); for (int i = dfsStackAsArray.Length - 1; i >= 0; i--) { Block b = dfsStackAsArray[i]; for (int j = b.Cmds.Count - 1; j >= 0; j--) { Cmd cmd = b.Cmds[j]; if (cmd is AssumeCmd) { AssumeCmd assumeCmd = cmd as AssumeCmd; returnExpr = Expr.And(new OldExpr(Token.NoToken, assumeCmd.Expr), returnExpr); } else if (cmd is AssignCmd) { AssignCmd assignCmd = (cmd as AssignCmd).AsSimpleAssignCmd; Dictionary<Variable, Expr> map = new Dictionary<Variable, Expr>(); for (int k = 0; k < assignCmd.Lhss.Count; k++) { map[assignCmd.Lhss[k].DeepAssignedVariable] = assignCmd.Rhss[k]; } Substitution subst = Substituter.SubstitutionFromHashtable(new Dictionary<Variable, Expr>()); Substitution oldSubst = Substituter.SubstitutionFromHashtable(map); returnExpr = (Expr) new MySubstituter(subst, oldSubst).Visit(returnExpr); } else if (cmd is HavocCmd) { HavocCmd havocCmd = cmd as HavocCmd; List<Variable> existVars = new List<Variable>(); Dictionary<Variable, Expr> map = new Dictionary<Variable, Expr>(); foreach (IdentifierExpr ie in havocCmd.Vars) { BoundVariable bv = GetBoundVariable(ie.Decl.TypedIdent.Type); map[ie.Decl] = new IdentifierExpr(Token.NoToken, bv); existVars.Add(bv); } Substitution subst = Substituter.SubstitutionFromHashtable(new Dictionary<Variable, Expr>()); Substitution oldSubst = Substituter.SubstitutionFromHashtable(map); returnExpr = new ExistsExpr(Token.NoToken, existVars, (Expr) new MySubstituter(subst, oldSubst).Visit(returnExpr)); } else { Debug.Assert(false); } } } return returnExpr; }
private Expr SubsetExprs(LinearDomain domain, HashSet<Variable> scope, Variable partition, int count, Expr expr) { foreach (Variable v in scope) { if (!domain.collectors.ContainsKey(v.TypedIdent.Type)) continue; Expr ie = new NAryExpr(Token.NoToken, new FunctionCall(domain.collectors[v.TypedIdent.Type]), new List<Expr> { Expr.Ident(v) }); expr = Expr.And(SubsetExpr(domain, ie, partition, count), expr); count++; } expr = new ExistsExpr(Token.NoToken, new List<Variable> { partition }, expr); expr.Resolve(new ResolutionContext(null)); expr.Typecheck(new TypecheckingContext(null)); return expr; }
public Expr DisjointnessExpr(string domainName, HashSet<Variable> scope) { LinearDomain domain = linearDomains[domainName]; BoundVariable partition = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, string.Format("partition_{0}", domainName), new MapType(Token.NoToken, new List<TypeVariable>(), new List<Type> { domain.elementType }, Microsoft.Boogie.Type.Int))); Expr disjointExpr = Expr.True; int count = 0; foreach (Variable v in scope) { IdentifierExpr ie = new IdentifierExpr(Token.NoToken, v); Expr e = new NAryExpr(Token.NoToken, new FunctionCall(domain.mapConstInt), new List<Expr>{ new LiteralExpr(Token.NoToken, Microsoft.Basetypes.BigNum.FromInt(count++)) } ); e = new NAryExpr(Token.NoToken, new FunctionCall(domain.mapEqInt), new List<Expr> { new IdentifierExpr(Token.NoToken, partition), e } ); e = new NAryExpr(Token.NoToken, new FunctionCall(domain.mapImpBool), new List<Expr> { v.TypedIdent.Type is MapType ? ie : Singleton(ie, domainName), e } ); e = Expr.Binary(BinaryOperator.Opcode.Eq, e, new NAryExpr(Token.NoToken, new FunctionCall(domain.mapConstBool), new List<Expr> { Expr.True })); disjointExpr = Expr.Binary(BinaryOperator.Opcode.And, e, disjointExpr); } var expr = new ExistsExpr(Token.NoToken, new List<Variable> { partition }, disjointExpr); expr.Resolve(new ResolutionContext(null)); expr.Typecheck(new TypecheckingContext(null)); return expr; }
public void ProtectedExistsExprBody() { var x = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", BasicType.Int)); var y = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", BasicType.Int)); var xId = new IdentifierExpr(Token.NoToken, x, /*immutable=*/true); var yId = new IdentifierExpr(Token.NoToken, y, /*immutable=*/true); var body = Expr.Gt(xId, yId); var exists = new ExistsExpr(Token.NoToken, new List<Variable> () { x, y }, body, /*immutable=*/true); exists.Body = Expr.Lt(xId, yId); // Changing the body of an immutable ExistsExpr should fail }
/// <summary> /// /// </summary> /// <param name="methodCall"></param> /// <remarks>Stub, This one really needs comments!</remarks> public override void TraverseChildren(IMethodCall methodCall) { var resolvedMethod = ResolveUnspecializedMethodOrThrow(methodCall.MethodToCall); Bpl.IToken methodCallToken = methodCall.Token(); if (this.sink.Options.getMeHere) { // TODO: Get a method reference so this isn't a string comparison? var methodName = MemberHelper.GetMethodSignature(methodCall.MethodToCall, NameFormattingOptions.None); if (methodName.Equals("GetMeHere.GetMeHere.Assert")) { // for now, just translate it as "assert e" this.Traverse(methodCall.Arguments.First()); Bpl.Expr e = this.TranslatedExpressions.Pop(); this.StmtTraverser.StmtBuilder.Add(new Bpl.AssertCmd(methodCallToken, e)); return; } } // Handle type equality specially when it is testing against a constant, i.e., o.GetType() == typeof(T) if (IsOperator(resolvedMethod) && !IsConversionOperator(resolvedMethod) && TypeHelper.TypesAreEquivalent(resolvedMethod.ContainingType, this.sink.host.PlatformType.SystemType)) { // REVIEW: Assume the only operators on System.Type are == and != var typeToTest = methodCall.Arguments.ElementAtOrDefault(0) as ITypeOf; IMethodCall callToGetType; if (typeToTest == null) { typeToTest = methodCall.Arguments.ElementAtOrDefault(1) as ITypeOf; callToGetType = methodCall.Arguments.ElementAtOrDefault(0) as IMethodCall; } else { callToGetType = methodCall.Arguments.ElementAtOrDefault(1) as IMethodCall; } if (typeToTest != null && callToGetType != null && TypeHelper.TypesAreEquivalent(callToGetType.MethodToCall.ContainingType, this.sink.host.PlatformType.SystemObject) && MemberHelper.GetMethodSignature(callToGetType.MethodToCall).Equals("System.Object.GetType")) { IExpression objectToTest = callToGetType.ThisArgument; // generate: $TypeConstructor($DynamicType(o)) == TypeConstructorId var typeConstructorId = this.sink.FindOrDefineType(typeToTest.TypeToGet.ResolvedType).ConstructorId; Contract.Assume(typeConstructorId != null); this.Traverse(objectToTest); var e = this.TranslatedExpressions.Pop(); var exprs = new List<Bpl.Expr>(new Bpl.Expr[] {this.sink.Heap.DynamicType(e)}); Bpl.Expr typeTestExpression = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, new Bpl.NAryExpr(methodCallToken, new Bpl.FunctionCall(sink.Heap.TypeConstructorFunction), exprs), Bpl.Expr.Ident(typeConstructorId)); if (MemberHelper.GetMethodSignature(resolvedMethod).Equals("System.Type.op_Inequality")) typeTestExpression = Bpl.Expr.Unary( methodCallToken, Bpl.UnaryOperator.Opcode.Not, typeTestExpression); this.TranslatedExpressions.Push(typeTestExpression); return; } } // Handle calls to Contract.ForAll and Contract.Exists specially (if they are to the overloads that take two ints and a predicate on ints) if (resolvedMethod.ContainingTypeDefinition.InternedKey == this.sink.host.PlatformType.SystemDiagnosticsContractsContract.InternedKey) { var methodName = resolvedMethod.Name.Value; if (methodCall.Arguments.Count() == 3 && (methodName == "ForAll" || methodName == "Exists")) { var noToken = Bpl.Token.NoToken; this.Traverse(methodCall.Arguments.ElementAt(0)); var lb = this.TranslatedExpressions.Pop(); this.Traverse(methodCall.Arguments.ElementAt(1)); var ub = this.TranslatedExpressions.Pop(); var delegateArgument = methodCall.Arguments.ElementAt(2); this.Traverse(delegateArgument); var del = this.TranslatedExpressions.Pop(); var boundVar = new Bpl.LocalVariable(noToken, new Bpl.TypedIdent(noToken, TranslationHelper.GenerateTempVarName(), Bpl.Type.Int)); var resultVar = new Bpl.LocalVariable(noToken, new Bpl.TypedIdent(noToken, TranslationHelper.GenerateTempVarName(), Bpl.Type.Bool)); var delegateType = delegateArgument.Type; var invokeMethod = delegateType.ResolvedType.GetMembersNamed(this.sink.host.NameTable.GetNameFor("Invoke"), false).First() as IMethodReference; var unspecializedInvokeMethod = Sink.Unspecialize(invokeMethod).ResolvedMethod; var invokeProcedureInfo = sink.FindOrCreateProcedure(unspecializedInvokeMethod); var ins = new List<Bpl.Expr>(); ins.Add(del); var localStmtTraverser = this.StmtTraverser.factory.MakeStatementTraverser(this.sink, this.StmtTraverser.PdbReader, this.contractContext); var secondArg = new Bpl.NAryExpr(noToken, new Bpl.FunctionCall(this.sink.Heap.Int2Union), new List<Bpl.Expr>(new Bpl.Expr[] {Bpl.Expr.Ident(boundVar)})); ins.Add(secondArg); var outs = new List<Bpl.IdentifierExpr>(); outs.Add(Bpl.Expr.Ident(resultVar)); var callCmd = new Bpl.CallCmd(noToken, invokeProcedureInfo.Decl.Name, ins, outs); var blockCmds = new List<Bpl.Cmd>(); blockCmds.Add( new Bpl.AssumeCmd(noToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, new Bpl.NAryExpr(noToken, new Bpl.FunctionCall(this.sink.Heap.Union2Int), new List<Bpl.Expr>(new Bpl.Expr[] {secondArg})), Bpl.Expr.Ident(boundVar)))); blockCmds.Add(callCmd); Bpl.Block block = new Bpl.Block(noToken, "A", blockCmds, new Bpl.ReturnExprCmd(noToken, Bpl.Expr.Ident(resultVar))); Bpl.Expr body = new Bpl.CodeExpr(new List<Bpl.Variable>(new Bpl.Variable[] {resultVar}), new List<Bpl.Block>{block}); Bpl.Expr antecedent = Bpl.Expr.And(Bpl.Expr.Le(lb, Bpl.Expr.Ident(boundVar)), Bpl.Expr.Lt(Bpl.Expr.Ident(boundVar), ub)); Bpl.Expr quantifier; if (methodName == "ForAll") { body = Bpl.Expr.Imp(antecedent, body); quantifier = new Bpl.ForallExpr(methodCallToken, new List<Bpl.Variable>(new Bpl.Variable[] {boundVar}), body); } else { body = Bpl.Expr.And(antecedent, body); quantifier = new Bpl.ExistsExpr(methodCallToken, new List<Bpl.Variable>(new Bpl.Variable[] {boundVar}), body); } this.TranslatedExpressions.Push(quantifier); return; } } List<Bpl.Expr> inexpr; List<Bpl.IdentifierExpr> outvars; Bpl.IdentifierExpr thisExpr; Dictionary<Bpl.IdentifierExpr, Tuple<Bpl.IdentifierExpr,bool>> toBoxed; var proc = TranslateArgumentsAndReturnProcedure(methodCallToken, methodCall.MethodToCall, resolvedMethod, methodCall.IsStaticCall ? null : methodCall.ThisArgument, methodCall.Arguments, out inexpr, out outvars, out thisExpr, out toBoxed); string methodname = proc.Name; var translateAsFunctionCall = proc is Bpl.Function; bool isAsync = false; // this code structure is quite chaotic, and some code needs to be evaluated regardless, hence the try-finally try { if (!translateAsFunctionCall) { foreach (var a in resolvedMethod.Attributes) { if (TypeHelper.GetTypeName(a.Type).EndsWith("AsyncAttribute")) { isAsync = true; } } } var deferringCtorCall = resolvedMethod.IsConstructor && methodCall.ThisArgument is IThisReference; // REVIEW!! Ask Herman: is the above test enough? The following test is used in FindCtorCall.IsDeferringCtor, // but it doesn't work when the type is a struct S because then "this" has a type of "&S". //&& TypeHelper.TypesAreEquivalent(resolvedMethod.ContainingType, methodCall.ThisArgument.Type); if (resolvedMethod.IsConstructor && resolvedMethod.ContainingTypeDefinition.IsStruct && !deferringCtorCall) { handleStructConstructorCall(methodCall, methodCallToken, inexpr, outvars, thisExpr, proc); return; } Bpl.CallCmd call; bool isEventAdd = resolvedMethod.IsSpecialName && resolvedMethod.Name.Value.StartsWith("add_"); bool isEventRemove = resolvedMethod.IsSpecialName && resolvedMethod.Name.Value.StartsWith("remove_"); if (isEventAdd || isEventRemove) { call = translateAddRemoveCall(methodCall, resolvedMethod, methodCallToken, inexpr, outvars, thisExpr, isEventAdd); } else { if (translateAsFunctionCall) { var func = proc as Bpl.Function; var exprSeq = new List<Bpl.Expr>(); foreach (var e in inexpr) { exprSeq.Add(e); } var callFunction = new Bpl.NAryExpr(methodCallToken, new Bpl.FunctionCall(func), exprSeq); this.TranslatedExpressions.Push(callFunction); return; } else { EmitLineDirective(methodCallToken); call = new Bpl.CallCmd(methodCallToken, methodname, inexpr, outvars); call.IsAsync = isAsync; this.StmtTraverser.StmtBuilder.Add(call); } } foreach (KeyValuePair<Bpl.IdentifierExpr, Tuple<Bpl.IdentifierExpr,bool>> kv in toBoxed) { var lhs = kv.Key; var tuple = kv.Value; var rhs = tuple.Item1; Bpl.Expr fromUnion = this.sink.Heap.FromUnion(Bpl.Token.NoToken, lhs.Type, rhs, tuple.Item2); this.StmtTraverser.StmtBuilder.Add(TranslationHelper.BuildAssignCmd(lhs, fromUnion)); } if (this.sink.Options.modelExceptions == 2 || (this.sink.Options.modelExceptions == 1 && this.sink.MethodThrowsExceptions(resolvedMethod))) { Bpl.Expr expr = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, Bpl.Expr.Ident(this.sink.Heap.ExceptionVariable), Bpl.Expr.Ident(this.sink.Heap.NullRef)); this.StmtTraverser.RaiseException(expr); } } finally { // TODO move away phone related code from the translation, it would be better to have 2 or more translation phases if (PhoneCodeHelper.instance().PhonePlugin != null) { if (PhoneCodeHelper.instance().PhoneNavigationToggled) { if (PhoneCodeHelper.instance().isNavigationCall(methodCall)) { Bpl.AssignCmd assignCmd = PhoneCodeHelper.instance().createBoogieNavigationUpdateCmd(sink); this.StmtTraverser.StmtBuilder.Add(assignCmd); } } if (PhoneCodeHelper.instance().PhoneFeedbackToggled) { if (PhoneCodeHelper.instance().isMethodKnownUIChanger(methodCall)) { Bpl.AssumeCmd assumeFalse = new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.LiteralExpr.False); this.StmtTraverser.StmtBuilder.Add(assumeFalse); } } } } }
public override Expr VisitExistsExpr(ExistsExpr node) { //Contract.Requires(node != null); Contract.Ensures(Contract.Result<Expr>() != null); return base.VisitExistsExpr((ExistsExpr)node.Clone()); }
private Expr CalculatePathCondition(PathInfo path) { Expr returnExpr = Expr.True; HashSet<Variable> existsVars = path.existsVars; Dictionary<Variable, Expr> existsMap = new Dictionary<Variable, Expr>(); Dictionary<Variable, Expr> varToExpr = path.varToExpr; foreach (Variable v in varToExpr.Keys) { if (postExistVars.Contains(v)) continue; IdentifierExpr ie = varToExpr[v] as IdentifierExpr; if (ie != null && !existsMap.ContainsKey(ie.Decl) && existsVars.Contains(ie.Decl)) { existsMap[ie.Decl] = Expr.Ident(v); existsVars.Remove(ie.Decl); } else { returnExpr = Expr.And(returnExpr, Expr.Eq(Expr.Ident(v), (new MyDuplicator()).VisitExpr(varToExpr[v]))); returnExpr.Type = Type.Bool; } } List<Expr> pathExprs = new List<Expr>(); path.pathExprs.ForEach(x => pathExprs.Add((new MyDuplicator()).VisitExpr(x))); foreach (Expr x in pathExprs) { Variable boundVar; Expr boundVarExpr; if (InferSubstitution(x, out boundVar, out boundVarExpr) && existsVars.Contains(boundVar)) { existsMap[boundVar] = boundVarExpr; existsVars.Remove(boundVar); } else { returnExpr = Expr.And(returnExpr, x); returnExpr.Type = Type.Bool; } } returnExpr = Substituter.Apply(Substituter.SubstitutionFromHashtable(existsMap), returnExpr); if (existsVars.Count > 0) { returnExpr = new ExistsExpr(Token.NoToken, new List<Variable>(existsVars), returnExpr); } return returnExpr; }