/* This function allows you to replace, for example: * * Bpl.BoundVariable iVar = new Bpl.BoundVariable(e.tok, new Bpl.TypedIdent(e.tok, "$i", Bpl.Type.Int)); * Bpl.IdentifierExpr i = new Bpl.IdentifierExpr(e.tok, iVar); * * with: * * Bpl.Expr i; var iVar = BplBoundVar("$i", Bpl.Type.Int, out i); */ static Bpl.BoundVariable BplBoundVar(string name, Bpl.Type ty, out Bpl.Expr e) { Contract.Requires(ty != null); var v = new Bpl.BoundVariable(ty.tok, new Bpl.TypedIdent(ty.tok, name, ty)); e = new Bpl.IdentifierExpr(ty.tok, name, ty); return(v); }
public void CachedHashCodeIdentifierExpr() { var id = new IdentifierExpr(Token.NoToken, "foo", BasicType.Bool, /*immutable=*/true); Assert.AreEqual(id.ComputeHashCode(), id.GetHashCode()); var variable = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "foo2", BasicType.Int)); var id2 = new IdentifierExpr(Token.NoToken, variable, /*immutable=*/true); Assert.AreEqual(id2.ComputeHashCode(), id2.GetHashCode()); }
public void CachedHashCodeForAllExpr() { 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 forAll = new ForallExpr(Token.NoToken, new List<Variable> () {x, y }, body, /*immutable=*/ true); Assert.AreEqual(forAll.ComputeHashCode(), forAll.GetHashCode()); }
public override Expr VisitIdentifierExpr(IdentifierExpr node) { if (node.Decl == null || !(node.Decl is LocalVariable || node.Decl is Formal || node.Decl is GlobalVariable)) { return node; } else { BoundVariable boundVar; if (!Substitutions.TryGetValue(node.Decl, out boundVar)) { boundVar = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, node.Name, node.Type)); Substitutions[node.Decl] = boundVar; } return new IdentifierExpr(node.tok, boundVar); } }
public override BoundVariable VisitBoundVariable(BoundVariable node) { Contract.Ensures(Contract.Result<BoundVariable>() == node); return (BoundVariable)this.VisitVariable(node); }
public virtual BoundVariable VisitBoundVariable(BoundVariable node) { Contract.Requires(node != null); Contract.Ensures(Contract.Result<BoundVariable>() != null); node = (BoundVariable)this.VisitVariable(node); return node; }
public override Absy Visit(Absy node) { //Contract.Requires(node != null); Contract.Ensures(Contract.Result<Absy>() != null); node = base.Visit(node); LambdaExpr lambda = node as LambdaExpr; if (lambda != null) { IToken/*!*/ tok = lambda.tok; Contract.Assert(tok != null); Set freeVars = new Set(); lambda.ComputeFreeVariables(freeVars); // this is ugly, the output will depend on hashing order Dictionary<Variable, Expr> subst = new Dictionary<Variable, Expr>(); List<Variable> formals = new List<Variable>(); List<Expr> callArgs = new List<Expr>(); List<Expr> axCallArgs = new List<Expr>(); List<Variable> dummies = new List<Variable>(lambda.Dummies); List<TypeVariable> freeTypeVars = new List<TypeVariable>(); List<Type/*!*/> fnTypeVarActuals = new List<Type/*!*/>(); List<TypeVariable> freshTypeVars = new List<TypeVariable>(); // these are only used in the lambda@n function's definition foreach (object o in freeVars) { // 'o' is either a Variable or a TypeVariable. Since the lambda desugaring happens only // at the outermost level of a program (where there are no mutable variables) and, for // procedure bodies, after the statements have been passified (when mutable variables have // been replaced by immutable incarnations), we are interested only in BoundVar's and // TypeVariable's. BoundVariable v = o as BoundVariable; if (v != null) { TypedIdent ti = new TypedIdent(v.TypedIdent.tok, v.TypedIdent.Name, v.TypedIdent.Type); Formal f = new Formal(v.tok, ti, true); formals.Add(f); BoundVariable b = new BoundVariable(v.tok, ti); dummies.Add(b); callArgs.Add(new IdentifierExpr(v.tok, v)); Expr/*!*/ id = new IdentifierExpr(f.tok, b); Contract.Assert(id != null); subst.Add(v, id); axCallArgs.Add(id); } else if (o is TypeVariable) { TypeVariable tv = (TypeVariable)o; freeTypeVars.Add(tv); fnTypeVarActuals.Add(tv); freshTypeVars.Add(new TypeVariable(tv.tok, tv.Name)); } } Formal res = new Formal(tok, new TypedIdent(tok, TypedIdent.NoName, cce.NonNull(lambda.Type)), false); Function fn = new Function(tok, "lambda@" + lambdaid++, freshTypeVars, formals, res, "auto-generated lambda function", lambda.Attributes); lambdaFunctions.Add(fn); FunctionCall fcall = new FunctionCall(new IdentifierExpr(tok, fn.Name)); fcall.Func = fn; // resolve here List<Expr/*!*/> selectArgs = new List<Expr/*!*/>(); foreach (Variable/*!*/ v in lambda.Dummies) { Contract.Assert(v != null); selectArgs.Add(new IdentifierExpr(v.tok, v)); } NAryExpr axcall = new NAryExpr(tok, fcall, axCallArgs); axcall.Type = res.TypedIdent.Type; axcall.TypeParameters = SimpleTypeParamInstantiation.From(freeTypeVars, fnTypeVarActuals); NAryExpr select = Expr.Select(axcall, selectArgs); select.Type = lambda.Body.Type; List<Type/*!*/> selectTypeParamActuals = new List<Type/*!*/>(); List<TypeVariable> forallTypeVariables = new List<TypeVariable>(); foreach (TypeVariable/*!*/ tp in lambda.TypeParameters) { Contract.Assert(tp != null); selectTypeParamActuals.Add(tp); forallTypeVariables.Add(tp); } forallTypeVariables.AddRange(freeTypeVars); select.TypeParameters = SimpleTypeParamInstantiation.From(lambda.TypeParameters, selectTypeParamActuals); Expr bb = Substituter.Apply(Substituter.SubstitutionFromHashtable(subst), lambda.Body); NAryExpr body = Expr.Eq(select, bb); body.Type = Type.Bool; body.TypeParameters = SimpleTypeParamInstantiation.EMPTY; Trigger trig = new Trigger(select.tok, true, new List<Expr> { select }); lambdaAxioms.Add(new ForallExpr(tok, forallTypeVariables, dummies, lambda.Attributes, trig, body)); NAryExpr call = new NAryExpr(tok, fcall, callArgs); call.Type = res.TypedIdent.Type; call.TypeParameters = SimpleTypeParamInstantiation.From(freeTypeVars, fnTypeVarActuals); return call; } return node; }
public void CachedHashCodeLambdaExpr() { 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 lambda = new LambdaExpr(Token.NoToken, new List<TypeVariable>(), new List<Variable>() { x, y}, null, body, /*immutable=*/true); Assert.AreEqual(lambda.ComputeHashCode(), lambda.GetHashCode()); }
public void ProtectedForAllExprBody() { 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 forAll = new ForallExpr(Token.NoToken, new List<Variable> () { x, y }, body, /*immutable=*/true); forAll.Body = Expr.Lt(xId, yId); // Changing the body of an immutable ForAllExpr should fail }
public Expr Compute() { Search(second.thatAction.Blocks[0], false); Dictionary<Variable, Expr> map = new Dictionary<Variable, Expr>(); List<Variable> boundVars = new List<Variable>(); if (first != null) { foreach (Variable v in first.thisAction.LocVars) { BoundVariable bv = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, v.Name, v.TypedIdent.Type)); map[v] = new IdentifierExpr(Token.NoToken, bv); boundVars.Add(bv); } } foreach (Variable v in second.thatAction.LocVars) { BoundVariable bv = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, v.Name, v.TypedIdent.Type)); map[v] = new IdentifierExpr(Token.NoToken, bv); boundVars.Add(bv); } Substitution subst = Substituter.SubstitutionFromHashtable(map); if (boundVars.Count > 0) return new ExistsExpr(Token.NoToken, boundVars, Substituter.Apply(subst, transitionRelation)); else return transitionRelation; }
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); }
public override Expr VisitLambdaExpr(LambdaExpr lambda) { var baseResult = base.VisitLambdaExpr(lambda); lambda = baseResult as LambdaExpr; if (lambda == null) { return baseResult; // apparently, the base visitor already turned the lambda into something else } // We start by getting rid of any use of "old" inside the lambda. This is done as follows. // For each variable "g" occurring inside lambda as "old(... g ...)", create a new name "og". // Replace each old occurrence of "g" with "og", removing the enclosing "old" wrappers. var oldFinder = new OldFinder(); oldFinder.Visit(lambda); var oldSubst = new Dictionary<Variable, Expr>(); // g -> g0 var callOldMapping = new Dictionary<Variable, Expr>(); // g0 -> old(g) foreach (var v in oldFinder.FreeOldVars) { var g = v as GlobalVariable; if (g != null) { var g0 = new GlobalVariable(g.tok, new TypedIdent(g.tok, g.TypedIdent.Name + "@old", g.TypedIdent.Type)); oldSubst.Add(g, new IdentifierExpr(g0.tok, g0)); callOldMapping.Add(g0, new OldExpr(g0.tok, new IdentifierExpr(g.tok, g))); } } var lambdaBody = Substituter.ApplyReplacingOldExprs( Substituter.SubstitutionFromHashtable(new Dictionary<Variable,Expr>()), Substituter.SubstitutionFromHashtable(oldSubst), lambda.Body); var lambdaAttrs = Substituter.ApplyReplacingOldExprs( Substituter.SubstitutionFromHashtable(new Dictionary<Variable, Expr>()), Substituter.SubstitutionFromHashtable(oldSubst), lambda.Attributes); if (0 < CommandLineOptions.Clo.VerifySnapshots && QKeyValue.FindStringAttribute(lambdaAttrs, "checksum") == null) { // Attach a dummy checksum to avoid issues in the dependency analysis. var checksumAttr = new QKeyValue(lambda.tok, "checksum", new List<object> { "lambda expression" }, null); if (lambdaAttrs == null) { lambdaAttrs = checksumAttr; } else { lambdaAttrs.AddLast(checksumAttr); } } // this is ugly, the output will depend on hashing order var subst = new Dictionary<Variable, Expr>(); var substFnAttrs = new Dictionary<Variable, Expr>(); var formals = new List<Variable>(); var callArgs = new List<Expr>(); var axCallArgs = new List<Expr>(); var dummies = new List<Variable>(lambda.Dummies); var freeTypeVars = new List<TypeVariable>(); var fnTypeVarActuals = new List<Type/*!*/>(); var freshTypeVars = new List<TypeVariable>(); // these are only used in the lambda@n function's definition // compute the free variables of the lambda expression, but with lambdaBody instead of lambda.Body Set freeVars = new Set(); BinderExpr.ComputeBinderFreeVariables(lambda.TypeParameters, lambda.Dummies, lambdaBody, lambdaAttrs, freeVars); foreach (object o in freeVars) { // 'o' is either a Variable or a TypeVariable. if (o is Variable) { var v = o as Variable; var ti = new TypedIdent(v.TypedIdent.tok, v.TypedIdent.Name, v.TypedIdent.Type); var f = new Formal(v.tok, ti, true); formals.Add(f); substFnAttrs.Add(v, new IdentifierExpr(f.tok, f)); var b = new BoundVariable(v.tok, ti); dummies.Add(b); if (callOldMapping.ContainsKey(v)) { callArgs.Add(callOldMapping[v]); } else { callArgs.Add(new IdentifierExpr(v.tok, v)); } Expr id = new IdentifierExpr(b.tok, b); subst.Add(v, id); axCallArgs.Add(id); } else { var tv = (TypeVariable)o; freeTypeVars.Add(tv); fnTypeVarActuals.Add(tv); freshTypeVars.Add(new TypeVariable(tv.tok, tv.Name)); } } var sw = new System.IO.StringWriter(); var wr = new TokenTextWriter(sw, true); lambda.Emit(wr); string lam_str = sw.ToString(); FunctionCall fcall; IToken tok = lambda.tok; Formal res = new Formal(tok, new TypedIdent(tok, TypedIdent.NoName, cce.NonNull(lambda.Type)), false); if (liftedLambdas.TryGetValue(lambda, out fcall)) { if (CommandLineOptions.Clo.TraceVerify) { Console.WriteLine("Old lambda: {0}", lam_str); } } else { if (CommandLineOptions.Clo.TraceVerify) { Console.WriteLine("New lambda: {0}", lam_str); } Function fn = new Function(tok, FreshLambdaFunctionName(), freshTypeVars, formals, res, "auto-generated lambda function", Substituter.Apply(Substituter.SubstitutionFromHashtable(substFnAttrs), lambdaAttrs)); fn.OriginalLambdaExprAsString = lam_str; fcall = new FunctionCall(new IdentifierExpr(tok, fn.Name)); fcall.Func = fn; // resolve here liftedLambdas[lambda] = fcall; List<Expr/*!*/> selectArgs = new List<Expr/*!*/>(); foreach (Variable/*!*/ v in lambda.Dummies) { Contract.Assert(v != null); selectArgs.Add(new IdentifierExpr(v.tok, v)); } NAryExpr axcall = new NAryExpr(tok, fcall, axCallArgs); axcall.Type = res.TypedIdent.Type; axcall.TypeParameters = SimpleTypeParamInstantiation.From(freeTypeVars, fnTypeVarActuals); NAryExpr select = Expr.Select(axcall, selectArgs); select.Type = lambdaBody.Type; List<Type/*!*/> selectTypeParamActuals = new List<Type/*!*/>(); List<TypeVariable> forallTypeVariables = new List<TypeVariable>(); foreach (TypeVariable/*!*/ tp in lambda.TypeParameters) { Contract.Assert(tp != null); selectTypeParamActuals.Add(tp); forallTypeVariables.Add(tp); } forallTypeVariables.AddRange(freeTypeVars); select.TypeParameters = SimpleTypeParamInstantiation.From(lambda.TypeParameters, selectTypeParamActuals); Expr bb = Substituter.Apply(Substituter.SubstitutionFromHashtable(subst), lambdaBody); NAryExpr body = Expr.Eq(select, bb); body.Type = Type.Bool; body.TypeParameters = SimpleTypeParamInstantiation.EMPTY; Trigger trig = new Trigger(select.tok, true, new List<Expr> { select }); lambdaFunctions.Add(fn); lambdaAxioms.Add(new ForallExpr(tok, forallTypeVariables, dummies, Substituter.Apply(Substituter.SubstitutionFromHashtable(subst), lambdaAttrs), trig, body)); } NAryExpr call = new NAryExpr(tok, fcall, callArgs); call.Type = res.TypedIdent.Type; call.TypeParameters = SimpleTypeParamInstantiation.From(freeTypeVars, fnTypeVarActuals); return call; }
public void SimpleLambda() { var boundVar = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken,"foo",Microsoft.Boogie.Type.Bool)); var id = new IdentifierExpr(Token.NoToken, boundVar); // This is basically an Identity Map var lambdaExpr = new LambdaExpr(Token.NoToken, new List<TypeVariable>() , new List<Variable>() { boundVar }, null, id); var id2 = new IdentifierExpr(Token.NoToken, boundVar); var lambdaExpr2 = new LambdaExpr(Token.NoToken, new List<TypeVariable>() , new List<Variable>() { boundVar }, null, id2); Assert.AreNotSame(lambdaExpr, lambdaExpr2); // These are different references Assert.IsTrue(lambdaExpr.Equals(lambdaExpr2)); // These are "structurally equal" Assert.AreEqual(lambdaExpr.GetHashCode(), lambdaExpr2.GetHashCode()); // If the .Equals() is true then hash codes must be the same }
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 }
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))); return SubsetExprs(domain, scope, partition, 0, Expr.True); }
public LinearDomain(Program program, string domainName, Dictionary<Type, Function> collectors) { this.axioms = new List<Axiom>(); this.collectors = collectors; MapType setType = (MapType)collectors.First().Value.OutParams[0].TypedIdent.Type; this.elementType = setType.Arguments[0]; MapType mapTypeBool = new MapType(Token.NoToken, new List<TypeVariable>(), new List<Type> { this.elementType }, Type.Bool); MapType mapTypeInt = new MapType(Token.NoToken, new List<TypeVariable>(), new List<Type> { this.elementType }, Type.Int); this.mapOrBool = new Function(Token.NoToken, "linear_" + domainName + "_MapOr", new List<Variable> { new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "a", mapTypeBool), true), new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "b", mapTypeBool), true) }, new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "c", mapTypeBool), false)); if (CommandLineOptions.Clo.UseArrayTheory) { this.mapOrBool.AddAttribute("builtin", "MapOr"); } else { BoundVariable a = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "a", mapTypeBool)); IdentifierExpr aie = Expr.Ident(a); BoundVariable b = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "b", mapTypeBool)); IdentifierExpr bie = Expr.Ident(b); BoundVariable x = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", elementType)); IdentifierExpr xie = Expr.Ident(x); var mapApplTerm = new NAryExpr(Token.NoToken, new FunctionCall(mapOrBool), new List<Expr> { aie, bie } ); var lhsTerm = new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List<Expr> { mapApplTerm, xie } ); var rhsTerm = Expr.Or(new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List<Expr> { aie, xie } ), new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List<Expr> { bie, xie} )); var axiomExpr = new ForallExpr(Token.NoToken, new List<TypeVariable>(), new List<Variable> { a, b }, null, new Trigger(Token.NoToken, true, new List<Expr> { mapApplTerm }), new ForallExpr(Token.NoToken, new List<Variable> { x }, Expr.Binary(BinaryOperator.Opcode.Eq, lhsTerm, rhsTerm))); axiomExpr.Typecheck(new TypecheckingContext(null)); axioms.Add(new Axiom(Token.NoToken, axiomExpr)); } this.mapImpBool = new Function(Token.NoToken, "linear_" + domainName + "_MapImp", new List<Variable> { new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "a", mapTypeBool), true), new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "b", mapTypeBool), true) }, new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "c", mapTypeBool), false)); if (CommandLineOptions.Clo.UseArrayTheory) { this.mapImpBool.AddAttribute("builtin", "MapImp"); } else { BoundVariable a = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "a", mapTypeBool)); IdentifierExpr aie = Expr.Ident(a); BoundVariable b = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "b", mapTypeBool)); IdentifierExpr bie = Expr.Ident(b); BoundVariable x = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", elementType)); IdentifierExpr xie = Expr.Ident(x); var mapApplTerm = new NAryExpr(Token.NoToken, new FunctionCall(mapImpBool), new List<Expr> { aie, bie }); var lhsTerm = new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List<Expr> { mapApplTerm, xie }); var rhsTerm = Expr.Imp(new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List<Expr> { aie, xie }), new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List<Expr> { bie, xie })); var axiomExpr = new ForallExpr(Token.NoToken, new List<TypeVariable>(), new List<Variable> { a, b }, null, new Trigger(Token.NoToken, true, new List<Expr> { mapApplTerm }), new ForallExpr(Token.NoToken, new List<Variable> { x }, Expr.Binary(BinaryOperator.Opcode.Eq, lhsTerm, rhsTerm))); axiomExpr.Typecheck(new TypecheckingContext(null)); axioms.Add(new Axiom(Token.NoToken, axiomExpr)); } this.mapConstBool = new Function(Token.NoToken, "linear_" + domainName + "_MapConstBool", new List<Variable> { new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "b", Type.Bool), true) }, new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "c", mapTypeBool), false)); if (CommandLineOptions.Clo.UseArrayTheory) { this.mapConstBool.AddAttribute("builtin", "MapConst"); } else { BoundVariable x = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", elementType)); IdentifierExpr xie = Expr.Ident(x); var trueTerm = new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List<Expr> { new NAryExpr(Token.NoToken, new FunctionCall(mapConstBool), new List<Expr> { Expr.True }), xie }); var trueAxiomExpr = new ForallExpr(Token.NoToken, new List<Variable> { x }, trueTerm); trueAxiomExpr.Typecheck(new TypecheckingContext(null)); axioms.Add(new Axiom(Token.NoToken, trueAxiomExpr)); var falseTerm = new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List<Expr> { new NAryExpr(Token.NoToken, new FunctionCall(mapConstBool), new List<Expr> { Expr.False }), xie }); var falseAxiomExpr = new ForallExpr(Token.NoToken, new List<Variable> { x }, Expr.Unary(Token.NoToken, UnaryOperator.Opcode.Not, falseTerm)); falseAxiomExpr.Typecheck(new TypecheckingContext(null)); axioms.Add(new Axiom(Token.NoToken, falseAxiomExpr)); } this.mapEqInt = new Function(Token.NoToken, "linear_" + domainName + "_MapEq", new List<Variable> { new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "a", mapTypeInt), true), new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "b", mapTypeInt), true) }, new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "c", mapTypeBool), false)); if (CommandLineOptions.Clo.UseArrayTheory) { this.mapEqInt.AddAttribute("builtin", "MapEq"); } else { BoundVariable a = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "a", mapTypeInt)); IdentifierExpr aie = Expr.Ident(a); BoundVariable b = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "b", mapTypeInt)); IdentifierExpr bie = Expr.Ident(b); BoundVariable x = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", elementType)); IdentifierExpr xie = Expr.Ident(x); var mapApplTerm = new NAryExpr(Token.NoToken, new FunctionCall(mapEqInt), new List<Expr> { aie, bie }); var lhsTerm = new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List<Expr> { mapApplTerm, xie }); var rhsTerm = Expr.Eq(new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List<Expr> { aie, xie }), new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List<Expr> { bie, xie })); var axiomExpr = new ForallExpr(Token.NoToken, new List<TypeVariable>(), new List<Variable> { a, b }, null, new Trigger(Token.NoToken, true, new List<Expr> { mapApplTerm }), new ForallExpr(Token.NoToken, new List<Variable> { x }, Expr.Binary(BinaryOperator.Opcode.Eq, lhsTerm, rhsTerm))); axiomExpr.Typecheck(new TypecheckingContext(null)); axioms.Add(new Axiom(Token.NoToken, axiomExpr)); } this.mapConstInt = new Function(Token.NoToken, "linear_" + domainName + "_MapConstInt", new List<Variable> { new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "b", Type.Int), true) }, new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "c", mapTypeInt), false)); if (CommandLineOptions.Clo.UseArrayTheory) { this.mapConstInt.AddAttribute("builtin", "MapConst"); } else { BoundVariable a = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "a", Type.Int)); IdentifierExpr aie = Expr.Ident(a); BoundVariable x = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "x", elementType)); IdentifierExpr xie = Expr.Ident(x); var lhsTerm = new NAryExpr(Token.NoToken, new MapSelect(Token.NoToken, 1), new List<Expr> { new NAryExpr(Token.NoToken, new FunctionCall(mapConstInt), new List<Expr> { aie }), xie }); var axiomExpr = new ForallExpr(Token.NoToken, new List<Variable> { a, x }, Expr.Binary(BinaryOperator.Opcode.Eq, lhsTerm, aie)); axiomExpr.Typecheck(new TypecheckingContext(null)); axioms.Add(new Axiom(Token.NoToken, axiomExpr)); } foreach (var axiom in axioms) { axiom.Expr.Resolve(new ResolutionContext(null)); axiom.Expr.Typecheck(new TypecheckingContext(null)); } }
// We have to give the type explicitly, because the type of the formal "likeThisOne" can contain type variables protected Variable CreateTemporaryVariable(List<Variable> tempVars, Variable likeThisOne, Type ty, TempVarKind kind) { Contract.Requires(ty != null); Contract.Requires(likeThisOne != null); Contract.Requires(tempVars != null); Contract.Ensures(Contract.Result<Variable>() != null); string/*!*/ tempNamePrefix; switch (kind) { case TempVarKind.Formal: tempNamePrefix = "formal@"; break; case TempVarKind.Old: tempNamePrefix = "old@"; break; case TempVarKind.Bound: tempNamePrefix = "forall@"; break; default: { Contract.Assert(false); throw new cce.UnreachableException(); } // unexpected kind } TypedIdent ti = likeThisOne.TypedIdent; TypedIdent newTi = new TypedIdent(ti.tok, "call" + UniqueId + tempNamePrefix + ti.Name, ty); Variable/*!*/ v; if (kind == TempVarKind.Bound) { v = new BoundVariable(likeThisOne.tok, newTi); } else { v = new LocalVariable(likeThisOne.tok, newTi); tempVars.Add(v); } return v; }
public void ProtectedLambdaExprBody() { 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 lambda = new LambdaExpr(Token.NoToken, new List<TypeVariable>(), new List<Variable>() { x, y}, null, body, /*immutable=*/true); lambda.Body = Expr.Lt(xId, yId); // Changing the body of an immutable ExistsExpr should fail }
private void PopulateExistsVars(Variable v) { if (existsVars.ContainsKey(v)) return; existsVars[v] = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "#tmp_" + existsVars.Count, v.TypedIdent.Type)); }
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 DisjointnessExpr(string domainName, Variable inputVar, HashSet<Variable> scope) { if (scope.Count == 0) { return Expr.True; } 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))); return SubsetExprs(domain, scope, partition, 1, SubsetExpr(domain, Expr.Ident(inputVar), partition, 0)); }
public override BoundVariable VisitBoundVariable(BoundVariable node) { //Contract.Requires(node != null); Contract.Ensures(Contract.Result<BoundVariable>() != null); return base.VisitBoundVariable((BoundVariable)node.Clone()); }
private void AddPath() { HashSet<Variable> existsVars = new HashSet<Variable>(); Dictionary<Variable, Expr> varToExpr = new Dictionary<Variable, Expr>(); foreach (Variable v in frame) { varToExpr[v] = Expr.Ident(v); } if (first != null) { foreach (Variable v in first.thatOutParams) { varToExpr[v] = Expr.Ident(v); } } foreach (Variable v in second.thisOutParams) { varToExpr[v] = Expr.Ident(v); } List<Expr> pathExprs = new List<Expr>(); int boundVariableCount = 0; foreach (Cmd cmd in cmdStack) { if (cmd is AssumeCmd) { AssumeCmd assumeCmd = cmd as AssumeCmd; FlattenAnd(assumeCmd.Expr, pathExprs); } 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]; } Substitute(map, ref pathExprs, ref varToExpr); } else if (cmd is HavocCmd) { HavocCmd havocCmd = cmd as HavocCmd; Dictionary<Variable, Expr> map = new Dictionary<Variable, Expr>(); foreach (IdentifierExpr ie in havocCmd.Vars) { BoundVariable bv = new BoundVariable(Token.NoToken, new TypedIdent(Token.NoToken, "#tmp_" + boundVariableCount++, ie.Decl.TypedIdent.Type)); map[ie.Decl] = Expr.Ident(bv); existsVars.Add(bv); } Substitute(map, ref pathExprs, ref varToExpr); } else { Debug.Assert(false); } } paths.Add(new PathInfo(existsVars, varToExpr, pathExprs)); }