private bool TryComputeNAryExprs(IdentifierExpr id) { var toRemove = new HashSet <Expr>(); foreach (var expr in this.ExpressionMap[id].Keys.ToList()) { if (!(expr is NAryExpr)) { continue; } int ixs = 0; if (((expr as NAryExpr).Args[0] is IdentifierExpr) && ((expr as NAryExpr).Args[0] as IdentifierExpr).Name.StartsWith("$M.")) { toRemove.Add(expr); continue; } if (PointerAnalysis.ShouldSkipFromAnalysis(expr as NAryExpr)) { toRemove.Add(expr); continue; } if (PointerAnalysis.IsArithmeticExpression(expr as NAryExpr)) { toRemove.Add(expr); continue; } Expr p = (expr as NAryExpr).Args[0]; Expr i = (expr as NAryExpr).Args[1]; Expr s = (expr as NAryExpr).Args[2]; if (!(i is LiteralExpr && s is LiteralExpr)) { toRemove.Add(expr); continue; } ixs = (i as LiteralExpr).asBigNum.ToInt * (s as LiteralExpr).asBigNum.ToInt; this.ExpressionMap[id].Add(p, this.ExpressionMap[id][expr] + ixs); toRemove.Add(expr); } foreach (var expr in toRemove) { this.ExpressionMap[id].Remove(expr); } if (this.ExpressionMap[id].Any(val => val.Key is NAryExpr)) { return(false); } return(true); }
internal bool IsAxiom(IdentifierExpr expr) { bool result = false; if (expr == null) { return(result); } foreach (var axiom in this.AC.TopLevelDeclarations.OfType <Axiom>()) { Expr axiomExpr = null; if (axiom.Expr is NAryExpr) { axiomExpr = (axiom.Expr as NAryExpr).Args[0]; } else { axiomExpr = axiom.Expr; } if (axiomExpr.ToString().Equals(expr.Name)) { result = true; break; } } return(result); }
public void SimpleForAllWithTrigger() { var builder = GetSimpleBuilder(); var freeVarX = GetVariable("x", BasicType.Int); var xid = new IdentifierExpr(Token.NoToken, freeVarX); var fb = new FunctionCallBuilder(); var funcCall = fb.CreateUninterpretedFunctionCall("f", BPLType.Int, new List <BPLType>() { BPLType.Int }); var body = builder.Gt(builder.UFC(funcCall, xid), xid); // Single trigger var triggers = new Microsoft.Boogie.Trigger(Token.NoToken, /*positive=*/ true, new List <Expr>() { builder.UFC(funcCall, xid) }, null); var result = builder.ForAll(new List <Variable>() { freeVarX }, body, triggers); Assert.AreEqual("(forall x: int :: { f(x) } f(x) > x)", result.ToString()); CheckIsBoolType(result); }
public VarDefinitionStmt(IdentifierExpr name, IdentifierExpr type, bool isConst, Expression initialValue) { _name = name; _type = type; _isConst = isConst; _initialValue = initialValue; }
public override Expr VisitIdentifierExpr(IdentifierExpr node) { if (node.Decl is GlobalVariable) { if (!canAccessSharedVars) { Error(node, "Shared variable can be accessed only in atomic actions or specifications"); } else if (this.globalVarToSharedVarInfo.ContainsKey(node.Decl)) { if (this.globalVarToSharedVarInfo[node.Decl].hideLayerNum < minLayerNum) { minLayerNum = this.globalVarToSharedVarInfo[node.Decl].hideLayerNum; } if (this.globalVarToSharedVarInfo[node.Decl].introLayerNum > maxLayerNum) { maxLayerNum = this.globalVarToSharedVarInfo[node.Decl].introLayerNum; } } else { Error(node, "Accessed shared variable must have layer annotation"); } } else if (node.Decl is LocalVariable && ghostVars.Contains(node.Decl) && !canAccessGhostVars) { Error(node, "Ghost variable can be accessed only in assertions"); } return(base.VisitIdentifierExpr(node)); }
private Expr ElimPendingAsyncExpr(IdentifierExpr pa) { return(Expr.And( Expr.Or(elim.Keys.Select(a => ExprHelper.FunctionCall(a.pendingAsyncCtor.membership, pa))), Expr.Gt(Expr.Select(PAs, pa), Expr.Literal(0)) )); }
public void FunctionCallCallsVisitOnAllParametersPassedTest() { var target = new EvaluateVisitor(); var functionName = RandomGenerator.String(); var functionNameExpr = new IdentifierExpr(functionName); var parameters = new[] { new VarDefinitionStmt(new IdentifierExpr("A"), new IdentifierExpr("INT"), false, new ConstantExpr(1)), new VarDefinitionStmt(new IdentifierExpr("B"), new IdentifierExpr("STRING"), false, new ConstantExpr("TEST")), new VarDefinitionStmt(new IdentifierExpr("C"), new IdentifierExpr("BOOL"), false, new ConstantExpr(true)) }; var values = new Expression[] { new ConstantExpr(1), new ConstantExpr(RandomGenerator.String()), new ConstantExpr(true) }; var returnValue = values[1]; var functionDefinition = new FunctionDefinitionExpr(functionNameExpr, parameters, new ScopeBlockStmt(new[] { new ReturnStmt(returnValue) }), new IdentifierExpr("String")); var expr = new FunctionCallExpr(functionNameExpr, values); _scope.DefineIdentifier(functionName, Value.FromObject(functionDefinition)); var actual = target.Visit(expr, _scope); Assert.AreEqual(((ConstantExpr)returnValue).Value, actual.ToObject()); }
public void IdentifierExprName() { var id = new IdentifierExpr(Token.NoToken, "foo", BasicType.Bool, /*immutable=*/ true); Assert.IsTrue(id.Immutable); Assert.Throws(typeof(InvalidOperationException), () => id.Name = "foo2"); }
public override ILineObject Generate(GenerationEnvironment env) { List <ILineObject> ret = new List <ILineObject>(); if (CheckInstance != null && CheckInstance.Length != 0) { ret.Add(new ControlBlock(ControlBlockType.If, new BiOpExpr(ActorVariableHelper.GenerateGet(CheckInstance), ThisExpr.Instance.MakeIndex("name"), BiOpExpr.Op.NotEqual), new ILineObject[] { ThisExpr.Instance.MakeIndex("Release").Call().Statement(), }).Statement()); } var ownerActor = new IdentifierExpr("ownerActor"); var x = Position.GenerateX(ownerActor, env); var y = Position.GenerateY(ownerActor, env); var setRotation = ThisExpr.Instance.MakeIndex("rz").Assign(ownerActor.MakeIndex("rz")).Statement(); ret.AddRange(new ILineObject[] { new LocalVarStatement("ownerActor", ActorVariableHelper.GenerateGet("SYS_parent").MakeIndex("wr")), new ControlBlock(ControlBlockType.If, "ownerActor != null", new ILineObject[] { ThisExpr.Instance.MakeIndex("x").Assign(x).Statement(), ThisExpr.Instance.MakeIndex("y").Assign(y).Statement(), IgnoreRotation ? new SimpleLineObject("") : setRotation, }).Statement(), new ControlBlock(ControlBlockType.Else, new ILineObject[] { ThisExpr.Instance.MakeIndex("Release").Call().Statement(), }).Statement(), }); return(new SimpleBlock(ret).Statement()); }
private void FindUseOfFunctionPointers(InstrumentationRegion region, int regionIndex, IdentifierExpr constant, HashSet <InstrumentationRegion> alreadyFound) { if (alreadyFound.Contains(region)) { return; } alreadyFound.Add(region); var id = region.Implementation().InParams[regionIndex]; if (region.FunctionPointers.Contains(id)) { return; } region.FunctionPointers.Add(id); foreach (var block in region.Blocks()) { for (int idx = 0; idx < block.Cmds.Count; idx++) { if (!(block.Cmds[idx] is CallCmd)) { continue; } var call = block.Cmds[idx] as CallCmd; var calleeRegion = this.AC.InstrumentationRegions.Find(val => val.Implementation().Name.Equals(call.callee)); if (calleeRegion == null) { continue; } var indexes = new HashSet <int>(); for (int i = 0; i < call.Ins.Count; i++) { if (!(call.Ins[i] is IdentifierExpr)) { continue; } if (id.Name.Equals((call.Ins[i] as IdentifierExpr).Name)) { indexes.Add(i); } } if (indexes.Count == 0) { continue; } foreach (var index in indexes) { this.FindUseOfFunctionPointers(calleeRegion, index, constant, alreadyFound); } } } }
bool InferSubstitution(Expr x, out Variable var, out Expr expr) { var = null; expr = null; NAryExpr naryExpr = x as NAryExpr; if (naryExpr == null || naryExpr.Fun.FunctionName != "==") { return(false); } IdentifierExpr arg0 = naryExpr.Args[0] as IdentifierExpr; if (arg0 != null && arg0.Decl is BoundVariable) { var = arg0.Decl; expr = naryExpr.Args[1]; return(true); } IdentifierExpr arg1 = naryExpr.Args[1] as IdentifierExpr; if (arg1 != null && arg1.Decl is BoundVariable) { var = arg1.Decl; expr = naryExpr.Args[0]; return(true); } return(false); }
public void IdentifierExprName() { var id = new IdentifierExpr(Token.NoToken, "foo", BasicType.Bool, /*immutable=*/ true); Assert.IsTrue(id.Immutable); id.Name = "foo2"; }
private AssertCmd GenBoundCheck(BOUND_TYPE btype, AccessRecord ar, int arrDim, Variable offsetVar) { Expr boundExpr = null; IdentifierExpr offsetVarExpr = new IdentifierExpr(Token.NoToken, offsetVar); switch (btype) { case BOUND_TYPE.LOWER: boundExpr = verifier.IntRep.MakeSge(offsetVarExpr, verifier.IntRep.GetLiteral(0, verifier.size_t_bits)); break; case BOUND_TYPE.UPPER: boundExpr = verifier.IntRep.MakeSlt(offsetVarExpr, verifier.IntRep.GetLiteral(arrDim, verifier.size_t_bits)); break; } return(new AssertCmd(Token.NoToken, boundExpr, new QKeyValue(Token.NoToken, "array_bounds", new List <object> { }, new QKeyValue(Token.NoToken, "sourceloc_num", new List <object> { new LiteralExpr(Token.NoToken, Microsoft.Basetypes.BigNum.FromInt(CurrSourceLocNum)) }, new QKeyValue(Token.NoToken, "check_id", new List <object> { "bounds_check_state_" + ArraySourceID }, new QKeyValue(Token.NoToken, "array_name", new List <object> { ar.v.Name }, null)))))); }
public InductiveSequentialization(AtomicAction inputAction, AtomicAction outputAction, AtomicAction invariantAction, Dictionary <AtomicAction, AtomicAction> elim) { this.inputAction = inputAction; this.outputAction = outputAction; this.invariantAction = invariantAction; this.elim = elim; // TODO: check frame computation // We could compute a tighter frame per check. For example, base/conclusion checkers // don't have to take the eliminated actions into account. var frameVars = new List <AtomicAction> { invariantAction, outputAction, inputAction } .Union(elim.Select(kv => kv.Value)) .SelectMany(a => a.gateUsedGlobalVars.Union(a.modifiedGlobalVars)).Distinct(); this.frame = new HashSet <Variable>(frameVars); this.modifies = frame.Select(Expr.Ident).ToList(); newPAs = Expr.Ident(VarHelper.LocalVariable("newPAs", PendingAsyncMultisetType)); if (HasChoice) { choice = Expr.Ident(invariantAction.impl.OutParams.Last()); } else { choice = Expr.Ident(VarHelper.LocalVariable("choice", PendingAsyncType)); } }
public override Expr VisitIdentifierExpr(IdentifierExpr node) { IdentifierExpr newNode; if (node.Name != node.Decl.Name || node.Name != node.Decl.TypedIdent.Name) { Console.WriteLine("Inconsistent variable/ident naming on " + node.Name + " " + node.Decl.Name + " " + node.Decl.TypedIdent.Name); } GlobalVariable g = node.Decl as GlobalVariable; if (g == null) { newNode = null; } else { g = GetNewVar(g); if (g == null) { newNode = null; } else { //newNode = Expr.Ident(g); newNode = new IdentifierExpr(Token.NoToken, g); } } return(base.VisitIdentifierExpr(newNode == null ? node : newNode)); }
private void LiteralArgumentAnalyser(Procedure p, int arg) { LiteralExpr literal = null; foreach (CallCmd callCmd in CallSites[p]) { if (callCmd.Ins[arg] == null || !(callCmd.Ins[arg] is LiteralExpr)) { return; } LiteralExpr l = callCmd.Ins[arg] as LiteralExpr; if (literal == null) { literal = l; } else if (!literal.Equals(l)) { return; } } Expr e; e = new IdentifierExpr(Token.NoToken, p.InParams[arg]); e = Expr.Eq(e, literal); p.Requires.Add(new Requires(false, e)); }
private Expr CollectBooleanAssignment(IdentifierExpr glob, Variable assignedVar) { return(new NAryExpr(Token.NoToken, new FunctionCall(collectBoolFunc), new List <Expr>() { glob, IdentifierExpr.Ident(assignedVar) })); }
public void ParallelSymbolicAssignment() { p = LoadProgramFrom(@" procedure main() { var x:int; var y:int; assert {:symbooglix_bp ""before""} true; x, y := y, x; assert {:symbooglix_bp ""after""} true; } ", "file.bpl"); e = GetExecutor(p, new DFSStateScheduler(), GetSolver()); int count = 0; IdentifierExpr symbolicForx = null; IdentifierExpr symbolicFory = null; e.BreakPointReached += delegate(object sender, Executor.BreakPointEventArgs eventArgs) { switch (eventArgs.Name) { case "before": { var vAndExprForx = e.CurrentState.GetInScopeVariableAndExprByName("x"); Assert.IsInstanceOf <IdentifierExpr>(vAndExprForx.Value); Assert.IsInstanceOf <SymbolicVariable>((vAndExprForx.Value as IdentifierExpr).Decl); symbolicForx = vAndExprForx.Value as IdentifierExpr; var vAndExprFory = e.CurrentState.GetInScopeVariableAndExprByName("y"); Assert.IsInstanceOf <IdentifierExpr>(vAndExprFory.Value); Assert.IsInstanceOf <SymbolicVariable>((vAndExprFory.Value as IdentifierExpr).Decl); symbolicFory = vAndExprFory.Value as IdentifierExpr; } break; case "after": { Assert.IsNotNull(symbolicForx); Assert.IsNotNull(symbolicFory); // Check that swapped happened var vAndExprForNewx = e.CurrentState.GetInScopeVariableAndExprByName("x"); Assert.AreSame(symbolicFory, vAndExprForNewx.Value); var vAndExprForNewy = e.CurrentState.GetInScopeVariableAndExprByName("y"); Assert.AreSame(symbolicForx, vAndExprForNewy.Value); } break; default: Assert.Fail("unrecognised breakpoint"); break; } ++count; }; e.Run(GetMain(p)); Assert.AreEqual(2, count); }
public QuantifierExpr RewriteMatchingLoops(QuantifierWithTriggers q) { // rewrite quantifier to avoid mathing loops // before: // assert forall i :: 0 <= i < a.Length-1 ==> a[i] <= a[i+1]; // after: // assert forall i,j :: j == i+1 ==> 0 <= i < a.Length-1 ==> a[i] <= a[i+1]; substMap = new Dictionary <Expression, IdentifierExpr>(); usedMap = new Dictionary <Expression, IdentifierExpr>(); foreach (var m in q.LoopingMatches) { var e = m.OriginalExpr; if (TriggersCollector.IsPotentialTriggerCandidate(e) && triggersCollector.IsTriggerKiller(e)) { foreach (var sub in e.SubExpressions) { if (triggersCollector.IsTriggerKiller(sub) && (!TriggersCollector.IsPotentialTriggerCandidate(sub))) { IdentifierExpr ie; if (!substMap.TryGetValue(sub, out ie)) { var newBv = new BoundVar(sub.tok, "_t#" + substMap.Count, sub.Type); ie = new IdentifierExpr(sub.tok, newBv.Name); ie.Var = newBv; ie.Type = newBv.Type; substMap[sub] = ie; } } } } } var expr = (QuantifierExpr)q.quantifier; if (substMap.Count > 0) { var s = new Translator.ExprSubstituter(substMap); expr = s.Substitute(q.quantifier) as QuantifierExpr; } else { // make a copy of the expr if (expr is ForallExpr) { expr = new ForallExpr(expr.tok, expr.TypeArgs, expr.BoundVars, expr.Range, expr.Term, TriggerUtils.CopyAttributes(expr.Attributes)) { Type = expr.Type }; } else { expr = new ExistsExpr(expr.tok, expr.TypeArgs, expr.BoundVars, expr.Range, expr.Term, TriggerUtils.CopyAttributes(expr.Attributes)) { Type = expr.Type }; } } return(expr); }
public override Expr VisitIdentifierExpr(IdentifierExpr node) { if (!inold) { flag = true; } return(base.VisitIdentifierExpr(node)); }
public override Expr VisitIdentifierExpr(IdentifierExpr node) { if (consts.Keys.Contains(node.ToString())) { return(consts[node.ToString()]); } return(base.VisitIdentifierExpr(node)); }
public override Expr VisitIdentifierExpr(IdentifierExpr node) { var ie = (IdentifierExpr)base.VisitIdentifierExpr(node); // Need to fix up the name, since IdentifierExpr's equality also checks the name ie.Name = ie.Decl.TypedIdent.Name; return(ie); }
public override Expr VisitIdentifierExpr(IdentifierExpr node) { if (!globals.Contains(node.Name)) { usedVars.Add(node.Name); } return(node); }
public override Expr VisitIdentifierExpr(IdentifierExpr node) { //Contract.Requires(node != null); Contract.Ensures(Contract.Result <Expr>() != null); Expr /*?*/ e = subst(cce.NonNull(node.Decl)); return(e == null?base.VisitIdentifierExpr(node) : e); }
public override Expr VisitIdentifierExpr(IdentifierExpr node) { if (node.Decl == _toSearch) { Success = true; } return(base.VisitIdentifierExpr(node)); }
public override Expr VisitIdentifierExpr(IdentifierExpr node) { if (AllMaps.Contains(node.Name)) { return(Expr.Ident(U)); } return(node); }
public override Expr VisitIdentifierExpr(IdentifierExpr node) { if (GetReplacementVariable(node, out var variable)) { return(new IdentifierExpr(variable.tok, variable)); } return(base.VisitIdentifierExpr(node)); }
public ClassDefinitionStmt(IdentifierExpr name, IEnumerable <VarDefinitionStmt> members, IEnumerable <FunctionExpr> functions) { _name = name; _members = members.ToArray(); _functions = functions.ToArray(); }
public override Expr VisitIdentifierExpr(IdentifierExpr node) { if (node.Decl != null) { node.Decl = this.VisitVariable(node.Decl); } return(node); }
protected Tuple <Variable, IdentifierExpr> GetBoundVarAndIdExpr(string name, Microsoft.Boogie.Type type) { var typeIdent = new TypedIdent(Token.NoToken, name, type); var v = new BoundVariable(Token.NoToken, typeIdent); var id = new IdentifierExpr(Token.NoToken, v, /*immutable=*/ true); return(new Tuple <Variable, IdentifierExpr>(v, id)); }
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 FunctionNamePropertyReturnsPassedName() { var name = new IdentifierExpr(RandomGenerator.String()); var arguments = new Expression[] { new ConstantExpr(RandomGenerator.Int()), new ConstantExpr(RandomGenerator.Int()) }; var target = new FunctionCallExpr(name, arguments); Assert.AreSame(name.Name, target.FunctionName.Name); }
public void SimpleIdentifierExprs() { var variable = new GlobalVariable(Token.NoToken, new TypedIdent(Token.NoToken, "foo", Microsoft.Boogie.Type.GetBvType(8))); var idVar = new IdentifierExpr(Token.NoToken, variable); var idVar2 = new IdentifierExpr(Token.NoToken, variable); Assert.AreNotSame(idVar, idVar2); // These are different references Assert.IsTrue(idVar.Equals(idVar2)); // These are "structurally equal" Assert.AreEqual(idVar.GetHashCode(), idVar2.GetHashCode()); // If the .Equals() is true then hash codes must be the same }
public static void Predicate(Program p, Func<Procedure, bool> useProcedurePredicates = null, UniformityAnalyser uni = null) { useProcedurePredicates = useProcedurePredicates ?? (proc => false); if (uni != null) { var oldUPP = useProcedurePredicates; useProcedurePredicates = proc => oldUPP(proc) && !uni.IsUniform(proc.Name); } foreach (var decl in p.TopLevelDeclarations.ToList()) { if (decl is Procedure || decl is Implementation) { var proc = decl as Procedure; Implementation impl = null; if (proc == null) { impl = (Implementation)decl; proc = impl.Proc; } bool upp = useProcedurePredicates(proc); if (upp) { var dwf = (DeclWithFormals)decl; var fpVar = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "_P", Microsoft.Boogie.Type.Bool), /*incoming=*/true); dwf.InParams = new List<Variable>( (new Variable[] {fpVar}.Concat(dwf.InParams.Cast<Variable>())) .ToArray()); if (impl == null) { var fpIdentifierExpr = new IdentifierExpr(Token.NoToken, fpVar); foreach (Requires r in proc.Requires) { new EnabledReplacementVisitor(fpIdentifierExpr).VisitExpr(r.Condition); if (!QKeyValue.FindBoolAttribute(r.Attributes, "do_not_predicate")) { r.Condition = Expr.Imp(fpIdentifierExpr, r.Condition); } } foreach (Ensures e in proc.Ensures) { new EnabledReplacementVisitor(new IdentifierExpr(Token.NoToken, fpVar)).VisitExpr(e.Condition); if (!QKeyValue.FindBoolAttribute(e.Attributes, "do_not_predicate")) { e.Condition = Expr.Imp(fpIdentifierExpr, e.Condition); } } } } if (impl != null) { try { new SmartBlockPredicator(p, impl, useProcedurePredicates, uni).PredicateImplementation(); } catch (Program.IrreducibleLoopException) { } } } } }
public void ReturnTypePropertyReturnsPassedReturnType() { var name = new IdentifierExpr(RandomGenerator.String()); var arguments = new VarDefinitionStmt[0]; var body = new ConstantExpr(RandomGenerator.Int()); var returnType = new IdentifierExpr(RandomGenerator.String()); var target = new LambdaDefinitionExpr(name, arguments, body, returnType); Assert.AreSame(returnType, target.ReturnType); }
public void BodyPropertyReturnsPassedBody2() { var name = new IdentifierExpr(RandomGenerator.String()); var arguments = new VarDefinitionStmt[0]; var body = new ScopeBlockStmt(new [] { new NoOpStatement()}); var returnType = new IdentifierExpr(RandomGenerator.String()); var target = new FunctionDefinitionExpr(name, arguments, body, returnType); Assert.AreSame(body, target.Body); }
public void ArgumentsPropertyReturnsPassedArguments() { var name = new IdentifierExpr(RandomGenerator.String()); var arguments = new VarDefinitionStmt[0]; var body = new NoOpStatement(); var returnType = new IdentifierExpr(RandomGenerator.String()); var target = new FunctionDefinitionExpr(name, arguments, body, returnType); Assert.AreSame(arguments, target.Arguments); }
public void AcceptMethodCallsVisitOnVisitorWithThis() { var name = new IdentifierExpr(RandomGenerator.String()); var arguments = new Expression[] { new ConstantExpr(RandomGenerator.Int()), new ConstantExpr(RandomGenerator.Int()) }; var target = new FunctionCallExpr(name, arguments); var visitor = new Mock<IExpressionVisitor<string, int>>(); target.Accept(visitor.Object, 0); visitor.Verify(x => x.Visit(target, 0), Times.Once); }
public void AcceptMethodCallsOnlyVisitOnVisitorWithThisAndNoOtherVisitMethods() { var name = new IdentifierExpr(RandomGenerator.String()); var arguments = new Expression[] { new ConstantExpr(RandomGenerator.Int()), new ConstantExpr(RandomGenerator.Int()) }; var target = new FunctionCallExpr(name, arguments); // throw exception is any other methods called other than the PlusExpr overload. var visitor = new Mock<IExpressionVisitor<string, int>>(MockBehavior.Strict); visitor.Setup(x => x.Visit(target, 123)).Returns(""); target.Accept(visitor.Object, 123); }
private List<VarDefinitionStmt> ParseParameterList(Parser parser) { var parameters = new List<VarDefinitionStmt>(); if (parser.Peek().Type == "RIGHTPAREN") return parameters; while (true) { var name = parser.ParseExpression(0); if(!(name is IdentifierExpr)) throw new ParseException("Expected parameter name"); Expression type = null; if (parser.ConsumeOptional("COLON")) { type = parser.ParseExpression(0); if (!(type is IdentifierExpr)) throw new ParseException("Expected parameter type"); } else { type = new IdentifierExpr("dynamic"); } parameters.Add(new VarDefinitionStmt((IdentifierExpr)name, (IdentifierExpr)type, false, null)); if (parser.Peek().Type == "RIGHTPAREN") break; parser.Consume("COMMA"); } return parameters; }
public void IdentifierExprDecl() { var id = new IdentifierExpr(Token.NoToken, "foo", BasicType.Bool, /*immutable=*/true); Assert.IsTrue(id.Immutable); var typedIdent = new TypedIdent(Token.NoToken, "foo2", BasicType.Bool); id.Decl = new GlobalVariable(Token.NoToken, typedIdent); }
public void IdentifierExprName() { var id = new IdentifierExpr(Token.NoToken, "foo", BasicType.Bool, /*immutable=*/true); Assert.IsTrue(id.Immutable); id.Name = "foo2"; }
/// <summary> /// Before calling TrExpr(expr), the caller must have spilled the let variables declared in "expr". /// </summary> void TrExpr(Expression expr, TextWriter wr, bool inLetExprBody) { Contract.Requires(expr != null); if (expr is LiteralExpr) { LiteralExpr e = (LiteralExpr)expr; if (e is StaticReceiverExpr) { wr.Write(TypeName(e.Type, wr)); } else if (e.Value == null) { wr.Write("({0})null", TypeName(e.Type, wr)); } else if (e.Value is bool) { wr.Write((bool)e.Value ? "true" : "false"); } else if (e is CharLiteralExpr) { wr.Write("'{0}'", (string)e.Value); } else if (e is StringLiteralExpr) { var str = (StringLiteralExpr)e; wr.Write("{0}<char>.FromString({1}\"{2}\")", DafnySeqClass, str.IsVerbatim ? "@" : "", (string)e.Value); } else if (AsNativeType(e.Type) != null) { wr.Write((BigInteger)e.Value + AsNativeType(e.Type).Suffix); } else if (e.Value is BigInteger) { BigInteger i = (BigInteger)e.Value; if (new BigInteger(int.MinValue) <= i && i <= new BigInteger(int.MaxValue)) { wr.Write("new BigInteger({0})", i); } else { wr.Write("BigInteger.Parse(\"{0}\")", i); } } else if (e.Value is Basetypes.BigDec) { var n = (Basetypes.BigDec)e.Value; if (0 <= n.Exponent) { wr.Write("new Dafny.BigRational(new BigInteger({0}", n.Mantissa); for (int i = 0; i < n.Exponent; i++) { wr.Write("0"); } wr.Write("), BigInteger.One)"); } else { wr.Write("new Dafny.BigRational(new BigInteger({0}), new BigInteger(1", n.Mantissa); for (int i = n.Exponent; i < 0; i++) { wr.Write("0"); } wr.Write("))"); } } else { Contract.Assert(false); throw new cce.UnreachableException(); // unexpected literal } } else if (expr is ThisExpr) { wr.Write(enclosingMethod != null && enclosingMethod.IsTailRecursive ? "_this" : "this"); } else if (expr is IdentifierExpr) { var e = (IdentifierExpr)expr; if (e.Var is Formal && inLetExprBody && !((Formal)e.Var).InParam) { // out param in letExpr body, need to copy it to a temp since // letExpr body is translated to an anonymous function that doesn't // allow out parameters var name = string.Format("_pat_let_tv{0}", GetUniqueAstNumber(e)); wr.Write("@" + name); copyInstrWriter.Append("var @" + name + "= @" + e.Var.CompileName + ";\n"); } else { wr.Write("@" + e.Var.CompileName); } } else if (expr is SetDisplayExpr) { var e = (SetDisplayExpr)expr; var elType = e.Type.AsSetType.Arg; wr.Write("{0}<{1}>.FromElements", DafnySetClass, TypeName(elType, wr)); TrExprList(e.Elements, wr, inLetExprBody); } else if (expr is MultiSetDisplayExpr) { var e = (MultiSetDisplayExpr)expr; var elType = e.Type.AsMultiSetType.Arg; wr.Write("{0}<{1}>.FromElements", DafnyMultiSetClass, TypeName(elType, wr)); TrExprList(e.Elements, wr, inLetExprBody); } else if (expr is SeqDisplayExpr) { var e = (SeqDisplayExpr)expr; var elType = e.Type.AsSeqType.Arg; wr.Write("{0}<{1}>.FromElements", DafnySeqClass, TypeName(elType, wr)); TrExprList(e.Elements, wr, inLetExprBody); } else if (expr is MapDisplayExpr) { MapDisplayExpr e = (MapDisplayExpr)expr; wr.Write("{0}.FromElements", TypeName(e.Type, wr)); TrExprPairList(e.Elements, wr, inLetExprBody); } else if (expr is MemberSelectExpr) { MemberSelectExpr e = (MemberSelectExpr)expr; SpecialField sf = e.Member as SpecialField; if (sf != null) { wr.Write(sf.PreString); TrParenExpr(e.Obj, wr, inLetExprBody); wr.Write(".@{0}", sf.CompiledName); wr.Write(sf.PostString); } else { TrExpr(e.Obj, wr, inLetExprBody); wr.Write(".@{0}", e.Member.CompileName); } } else if (expr is SeqSelectExpr) { SeqSelectExpr e = (SeqSelectExpr)expr; Contract.Assert(e.Seq.Type != null); if (e.Seq.Type.IsArrayType) { if (e.SelectOne) { Contract.Assert(e.E0 != null && e.E1 == null); TrParenExpr(e.Seq, wr, inLetExprBody); wr.Write("[(int)"); TrParenExpr(e.E0, wr, inLetExprBody); wr.Write("]"); } else { TrParenExpr("Dafny.Helpers.SeqFromArray", e.Seq, wr, inLetExprBody); if (e.E1 != null) { TrParenExpr(".Take", e.E1, wr, inLetExprBody); } if (e.E0 != null) { TrParenExpr(".Drop", e.E0, wr, inLetExprBody); } } } else if (e.SelectOne) { Contract.Assert(e.E0 != null && e.E1 == null); TrParenExpr(e.Seq, wr, inLetExprBody); TrParenExpr(".Select", e.E0, wr, inLetExprBody); } else { TrParenExpr(e.Seq, wr, inLetExprBody); if (e.E1 != null) { TrParenExpr(".Take", e.E1, wr, inLetExprBody); } if (e.E0 != null) { TrParenExpr(".Drop", e.E0, wr, inLetExprBody); } } } else if (expr is MultiSetFormingExpr) { var e = (MultiSetFormingExpr)expr; wr.Write("{0}<{1}>", DafnyMultiSetClass, TypeName(e.E.Type.AsCollectionType.Arg, wr)); var eeType = e.E.Type.NormalizeExpand(); if (eeType is SeqType) { TrParenExpr(".FromSeq", e.E, wr, inLetExprBody); } else if (eeType is SetType) { TrParenExpr(".FromSet", e.E, wr, inLetExprBody); } else { Contract.Assert(false); throw new cce.UnreachableException(); } } else if (expr is MultiSelectExpr) { MultiSelectExpr e = (MultiSelectExpr)expr; TrParenExpr(e.Array, wr, inLetExprBody); string prefix = "["; foreach (Expression idx in e.Indices) { wr.Write("{0}(int)", prefix); TrParenExpr(idx, wr, inLetExprBody); prefix = ", "; } wr.Write("]"); } else if (expr is SeqUpdateExpr) { SeqUpdateExpr e = (SeqUpdateExpr)expr; if (e.ResolvedUpdateExpr != null) { TrExpr(e.ResolvedUpdateExpr, wr, inLetExprBody); } else { TrParenExpr(e.Seq, wr, inLetExprBody); wr.Write(".Update("); TrExpr(e.Index, wr, inLetExprBody); wr.Write(", "); TrExpr(e.Value, wr, inLetExprBody); wr.Write(")"); } } else if (expr is FunctionCallExpr) { FunctionCallExpr e = (FunctionCallExpr)expr; CompileFunctionCallExpr(e, wr, wr, inLetExprBody, TrExpr); } else if (expr is ApplyExpr) { var e = expr as ApplyExpr; wr.Write("Dafny.Helpers.Id<"); wr.Write(TypeName(e.Function.Type, wr)); wr.Write(">("); TrExpr(e.Function, wr, inLetExprBody); wr.Write(")"); TrExprList(e.Args, wr, inLetExprBody); } else if (expr is DatatypeValue) { DatatypeValue dtv = (DatatypeValue)expr; Contract.Assert(dtv.Ctor != null); // since dtv has been successfully resolved var typeParams = dtv.InferredTypeArgs.Count == 0 ? "" : string.Format("<{0}>", TypeNames(dtv.InferredTypeArgs, wr)); wr.Write("new @{0}{1}(", DtName(dtv.Ctor.EnclosingDatatype), typeParams); if (!dtv.IsCoCall) { // For an ordinary constructor (that is, one that does not guard any co-recursive calls), generate: // new Dt_Cons<T>( args ) wr.Write("new {0}(", DtCtorName(dtv.Ctor, dtv.InferredTypeArgs, wr)); string sep = ""; for (int i = 0; i < dtv.Arguments.Count; i++) { Formal formal = dtv.Ctor.Formals[i]; if (!formal.IsGhost) { wr.Write(sep); TrExpr(dtv.Arguments[i], wr, inLetExprBody); sep = ", "; } } wr.Write(")"); } else { // In the case of a co-recursive call, generate: // new Dt__Lazy<T>( new Dt__Lazy<T>.ComputerComputer( LAMBDA )() ) // where LAMBDA is: // () => { var someLocals = eagerlyEvaluatedArguments; // return () => { return Dt_Cons<T>( ...args...using someLocals and including function calls to be evaluated lazily... ); }; // } wr.Write("new {0}__Lazy{1}", dtv.DatatypeName, typeParams); wr.Write("(new {0}__Lazy{1}.ComputerComputer(() => {{ ", dtv.DatatypeName, typeParams); // locals string args = ""; string sep = ""; for (int i = 0; i < dtv.Arguments.Count; i++) { Formal formal = dtv.Ctor.Formals[i]; if (!formal.IsGhost) { Expression actual = dtv.Arguments[i].Resolved; string arg; var fce = actual as FunctionCallExpr; if (fce == null || fce.CoCall != FunctionCallExpr.CoCallResolution.Yes) { string varName = idGenerator.FreshId("_ac"); arg = varName; wr.Write("var {0} = ", varName); TrExpr(actual, wr, inLetExprBody); wr.Write("; "); } else { var sw = new StringWriter(); CompileFunctionCallExpr(fce, sw, wr, inLetExprBody, (exp, wrr, inLetExpr) => { string varName = idGenerator.FreshId("_ac"); sw.Write(varName); wrr.Write("var {0} = ", varName); TrExpr(exp, wrr, inLetExpr); wrr.Write("; "); }); arg = sw.ToString(); } args += sep + arg; sep = ", "; } } wr.Write("return () => { return "); wr.Write("new {0}({1}", DtCtorName(dtv.Ctor, dtv.InferredTypeArgs, wr), args); wr.Write("); }; })())"); } wr.Write(")"); } else if (expr is OldExpr) { Contract.Assert(false); throw new cce.UnreachableException(); // 'old' is always a ghost (right?) } else if (expr is UnaryOpExpr) { var e = (UnaryOpExpr)expr; switch (e.Op) { case UnaryOpExpr.Opcode.Not: wr.Write("!"); TrParenExpr(e.E, wr, inLetExprBody); break; case UnaryOpExpr.Opcode.Cardinality: wr.Write("new BigInteger("); TrParenExpr(e.E, wr, inLetExprBody); wr.Write(".Length)"); break; default: Contract.Assert(false); throw new cce.UnreachableException(); // unexpected unary expression } } else if (expr is ConversionExpr) { var e = (ConversionExpr)expr; var fromInt = e.E.Type.IsNumericBased(Type.NumericPersuation.Int); Contract.Assert(fromInt || e.E.Type.IsNumericBased(Type.NumericPersuation.Real)); var toInt = e.ToType.IsNumericBased(Type.NumericPersuation.Int); Contract.Assert(toInt || e.ToType.IsNumericBased(Type.NumericPersuation.Real)); Action fromIntAsBigInteger = () => { Contract.Assert(fromInt); if (AsNativeType(e.E.Type) != null) { wr.Write("new BigInteger"); } TrParenExpr(e.E, wr, inLetExprBody); }; Action toIntCast = () => { Contract.Assert(toInt); if (AsNativeType(e.ToType) != null) { wr.Write("(" + AsNativeType(e.ToType).Name + ")"); } }; if (fromInt && !toInt) { // int -> real wr.Write("new Dafny.BigRational("); fromIntAsBigInteger(); wr.Write(", BigInteger.One)"); } else if (!fromInt && toInt) { // real -> int toIntCast(); TrParenExpr(e.E, wr, inLetExprBody); wr.Write(".ToBigInteger()"); } else if (AsNativeType(e.ToType) != null) { toIntCast(); LiteralExpr lit = e.E.Resolved as LiteralExpr; UnaryOpExpr u = e.E.Resolved as UnaryOpExpr; MemberSelectExpr m = e.E.Resolved as MemberSelectExpr; if (lit != null && lit.Value is BigInteger) { // Optimize constant to avoid intermediate BigInteger wr.Write("(" + (BigInteger)lit.Value + AsNativeType(e.ToType).Suffix + ")"); } else if ((u != null && u.Op == UnaryOpExpr.Opcode.Cardinality) || (m != null && m.MemberName == "Length" && m.Obj.Type.IsArrayType)) { // Optimize .Length to avoid intermediate BigInteger TrParenExpr((u != null) ? u.E : m.Obj, wr, inLetExprBody); if (AsNativeType(e.ToType).UpperBound <= new BigInteger(0x80000000U)) { wr.Write(".Length"); } else { wr.Write(".LongLength"); } } else { TrParenExpr(e.E, wr, inLetExprBody); } } else if (e.ToType.IsIntegerType && AsNativeType(e.E.Type) != null) { fromIntAsBigInteger(); } else { Contract.Assert(fromInt == toInt); Contract.Assert(AsNativeType(e.ToType) == null); Contract.Assert(AsNativeType(e.E.Type) == null); TrParenExpr(e.E, wr, inLetExprBody); } } else if (expr is BinaryExpr) { BinaryExpr e = (BinaryExpr)expr; string opString = null; string preOpString = ""; string callString = null; switch (e.ResolvedOp) { case BinaryExpr.ResolvedOpcode.Iff: opString = "=="; break; case BinaryExpr.ResolvedOpcode.Imp: preOpString = "!"; opString = "||"; break; case BinaryExpr.ResolvedOpcode.Or: opString = "||"; break; case BinaryExpr.ResolvedOpcode.And: opString = "&&"; break; case BinaryExpr.ResolvedOpcode.EqCommon: { if (e.E0.Type.IsRefType) { // Dafny's type rules are slightly different C#, so we may need a cast here. // For example, Dafny allows x==y if x:array<T> and y:array<int> and T is some // type parameter. opString = "== (object)"; } else if (e.E0.Type.IsDatatype || e.E0.Type.IsTypeParameter || e.E0.Type.SupportsEquality) { callString = "Equals"; } else { opString = "=="; } break; } case BinaryExpr.ResolvedOpcode.NeqCommon: { if (e.E0.Type.IsRefType) { // Dafny's type rules are slightly different C#, so we may need a cast here. // For example, Dafny allows x==y if x:array<T> and y:array<int> and T is some // type parameter. opString = "!= (object)"; } else if (e.E0.Type.IsDatatype || e.E0.Type.IsTypeParameter || e.E0.Type.SupportsEquality) { preOpString = "!"; callString = "Equals"; } else { opString = "!="; } break; } case BinaryExpr.ResolvedOpcode.Lt: case BinaryExpr.ResolvedOpcode.LtChar: opString = "<"; break; case BinaryExpr.ResolvedOpcode.Le: case BinaryExpr.ResolvedOpcode.LeChar: opString = "<="; break; case BinaryExpr.ResolvedOpcode.Ge: case BinaryExpr.ResolvedOpcode.GeChar: opString = ">="; break; case BinaryExpr.ResolvedOpcode.Gt: case BinaryExpr.ResolvedOpcode.GtChar: opString = ">"; break; case BinaryExpr.ResolvedOpcode.Add: opString = "+"; break; case BinaryExpr.ResolvedOpcode.Sub: opString = "-"; break; case BinaryExpr.ResolvedOpcode.Mul: opString = "*"; break; case BinaryExpr.ResolvedOpcode.Div: if (expr.Type.IsIntegerType || (AsNativeType(expr.Type) != null && AsNativeType(expr.Type).LowerBound < BigInteger.Zero)) { string suffix = AsNativeType(expr.Type) != null ? ("_" + AsNativeType(expr.Type).Name) : ""; wr.Write("Dafny.Helpers.EuclideanDivision" + suffix + "("); TrParenExpr(e.E0, wr, inLetExprBody); wr.Write(", "); TrExpr(e.E1, wr, inLetExprBody); wr.Write(")"); } else { opString = "/"; // for reals } break; case BinaryExpr.ResolvedOpcode.Mod: if (expr.Type.IsIntegerType || (AsNativeType(expr.Type) != null && AsNativeType(expr.Type).LowerBound < BigInteger.Zero)) { string suffix = AsNativeType(expr.Type) != null ? ("_" + AsNativeType(expr.Type).Name) : ""; wr.Write("Dafny.Helpers.EuclideanModulus" + suffix + "("); TrParenExpr(e.E0, wr, inLetExprBody); wr.Write(", "); TrExpr(e.E1, wr, inLetExprBody); wr.Write(")"); } else { opString = "%"; // for reals } break; case BinaryExpr.ResolvedOpcode.SetEq: case BinaryExpr.ResolvedOpcode.MultiSetEq: case BinaryExpr.ResolvedOpcode.SeqEq: case BinaryExpr.ResolvedOpcode.MapEq: callString = "Equals"; break; case BinaryExpr.ResolvedOpcode.SetNeq: case BinaryExpr.ResolvedOpcode.MultiSetNeq: case BinaryExpr.ResolvedOpcode.SeqNeq: case BinaryExpr.ResolvedOpcode.MapNeq: preOpString = "!"; callString = "Equals"; break; case BinaryExpr.ResolvedOpcode.ProperSubset: case BinaryExpr.ResolvedOpcode.ProperMultiSubset: callString = "IsProperSubsetOf"; break; case BinaryExpr.ResolvedOpcode.Subset: case BinaryExpr.ResolvedOpcode.MultiSubset: callString = "IsSubsetOf"; break; case BinaryExpr.ResolvedOpcode.Superset: case BinaryExpr.ResolvedOpcode.MultiSuperset: callString = "IsSupersetOf"; break; case BinaryExpr.ResolvedOpcode.ProperSuperset: case BinaryExpr.ResolvedOpcode.ProperMultiSuperset: callString = "IsProperSupersetOf"; break; case BinaryExpr.ResolvedOpcode.Disjoint: case BinaryExpr.ResolvedOpcode.MultiSetDisjoint: case BinaryExpr.ResolvedOpcode.MapDisjoint: callString = "IsDisjointFrom"; break; case BinaryExpr.ResolvedOpcode.InSet: case BinaryExpr.ResolvedOpcode.InMultiSet: case BinaryExpr.ResolvedOpcode.InMap: TrParenExpr(e.E1, wr, inLetExprBody); wr.Write(".Contains("); TrExpr(e.E0, wr, inLetExprBody); wr.Write(")"); break; case BinaryExpr.ResolvedOpcode.NotInSet: case BinaryExpr.ResolvedOpcode.NotInMultiSet: case BinaryExpr.ResolvedOpcode.NotInMap: wr.Write("!"); TrParenExpr(e.E1, wr, inLetExprBody); wr.Write(".Contains("); TrExpr(e.E0, wr, inLetExprBody); wr.Write(")"); break; case BinaryExpr.ResolvedOpcode.Union: case BinaryExpr.ResolvedOpcode.MultiSetUnion: callString = "Union"; break; case BinaryExpr.ResolvedOpcode.Intersection: case BinaryExpr.ResolvedOpcode.MultiSetIntersection: callString = "Intersect"; break; case BinaryExpr.ResolvedOpcode.SetDifference: case BinaryExpr.ResolvedOpcode.MultiSetDifference: callString = "Difference"; break; case BinaryExpr.ResolvedOpcode.ProperPrefix: callString = "IsProperPrefixOf"; break; case BinaryExpr.ResolvedOpcode.Prefix: callString = "IsPrefixOf"; break; case BinaryExpr.ResolvedOpcode.Concat: callString = "Concat"; break; case BinaryExpr.ResolvedOpcode.InSeq: TrParenExpr(e.E1, wr, inLetExprBody); wr.Write(".Contains("); TrExpr(e.E0, wr, inLetExprBody); wr.Write(")"); break; case BinaryExpr.ResolvedOpcode.NotInSeq: wr.Write("!"); TrParenExpr(e.E1, wr, inLetExprBody); wr.Write(".Contains("); TrExpr(e.E0, wr, inLetExprBody); wr.Write(")"); break; default: Contract.Assert(false); throw new cce.UnreachableException(); // unexpected binary expression } if (opString != null) { NativeType nativeType = AsNativeType(e.Type); bool needsCast = nativeType != null && nativeType.NeedsCastAfterArithmetic; if (needsCast) { wr.Write("(" + nativeType.Name + ")("); } wr.Write(preOpString); TrParenExpr(e.E0, wr, inLetExprBody); wr.Write(" {0} ", opString); TrParenExpr(e.E1, wr, inLetExprBody); if (needsCast) { wr.Write(")"); } } else if (callString != null) { wr.Write(preOpString); TrParenExpr(e.E0, wr, inLetExprBody); wr.Write(".@{0}(", callString); TrExpr(e.E1, wr, inLetExprBody); wr.Write(")"); } } else if (expr is TernaryExpr) { Contract.Assume(false); // currently, none of the ternary expressions is compilable } else if (expr is LetExpr) { var e = (LetExpr)expr; if (e.Exact) { // The Dafny "let" expression // var Pattern(x,y) := G; E // is translated into C# as: // LamLet(G, tmp => // LamLet(dtorX(tmp), x => // LamLet(dtorY(tmp), y => E))) Contract.Assert(e.LHSs.Count == e.RHSs.Count); // checked by resolution var neededCloseParens = 0; for (int i = 0; i < e.LHSs.Count; i++) { var lhs = e.LHSs[i]; if (Contract.Exists(lhs.Vars, bv => !bv.IsGhost)) { var rhsName = string.Format("_pat_let{0}_{1}", GetUniqueAstNumber(e), i); wr.Write("Dafny.Helpers.Let<"); wr.Write(TypeName(e.RHSs[i].Type, wr) + "," + TypeName(e.Body.Type, wr)); wr.Write(">("); TrExpr(e.RHSs[i], wr, inLetExprBody); wr.Write(", " + rhsName + " => "); neededCloseParens++; var c = TrCasePattern(lhs, rhsName, e.Body.Type, wr); Contract.Assert(c != 0); // we already checked that there's at least one non-ghost neededCloseParens += c; } } TrExpr(e.Body, wr, true); for (int i = 0; i < neededCloseParens; i++) { wr.Write(")"); } } else if (e.BoundVars.All(bv => bv.IsGhost)) { // The Dafny "let" expression // ghost var x,y :| Constraint; E // is compiled just like E is, because the resolver has already checked that x,y (or other ghost variables, for that matter) don't // occur in E (moreover, the verifier has checked that values for x,y satisfying Constraint exist). TrExpr(e.Body, wr, inLetExprBody); } else { // The Dafny "let" expression // var x,y :| Constraint; E // is translated into C# as: // LamLet(0, dummy => { // the only purpose of this construction here is to allow us to add some code inside an expression in C# // var x,y; // // Embark on computation that fills in x,y according to Constraint; the computation stops when the first // // such value is found, but since the verifier checks that x,y follows uniquely from Constraint, this is // // not a source of nondeterminancy. // return E; // }) Contract.Assert(e.RHSs.Count == 1); // checked by resolution if (e.Constraint_MissingBounds != null) { foreach (var bv in e.Constraint_MissingBounds) { Error("this let-such-that expression is too advanced for the current compiler; Dafny's heuristics cannot find any bound for variable '{0}' (line {1})", wr, bv.Name, e.tok.line); } } else { wr.Write("Dafny.Helpers.Let<int," + TypeName(e.Body.Type, wr) + ">(0, _let_dummy_" + GetUniqueAstNumber(e) + " => {"); foreach (var bv in e.BoundVars) { wr.Write("{0} @{1}", TypeName(bv.Type, wr), bv.CompileName); wr.WriteLine(" = {0};", DefaultValue(bv.Type, wr)); } TrAssignSuchThat(0, new List<IVariable>(e.BoundVars).ConvertAll(bv => (IVariable)bv), e.RHSs[0], e.Constraint_Bounds, e.tok.line, wr, inLetExprBody); wr.Write(" return "); TrExpr(e.Body, wr, true); wr.Write("; })"); } } } else if (expr is MatchExpr) { var e = (MatchExpr)expr; // new Dafny.Helpers.Function<SourceType, TargetType>(delegate (SourceType _source) { // if (source.is_Ctor0) { // FormalType f0 = ((Dt_Ctor0)source._D).a0; // ... // return Body0; // } else if (...) { // ... // } else if (true) { // ... // } // }(src) string source = idGenerator.FreshId("_source"); wr.Write("new Dafny.Helpers.Function<{0}, {1}>(delegate ({0} {2}) {{ ", TypeName(e.Source.Type, wr), TypeName(e.Type, wr), source); if (e.Cases.Count == 0) { // the verifier would have proved we never get here; still, we need some code that will compile wr.Write("throw new System.Exception();"); } else { int i = 0; var sourceType = (UserDefinedType)e.Source.Type.NormalizeExpand(); foreach (MatchCaseExpr mc in e.Cases) { MatchCasePrelude(source, sourceType, cce.NonNull(mc.Ctor), mc.Arguments, i, e.Cases.Count, 0, wr); wr.Write("return "); TrExpr(mc.Body, wr, inLetExprBody); wr.Write("; "); i++; } wr.Write("}"); } // We end with applying the source expression to the delegate we just built wr.Write("})("); TrExpr(e.Source, wr, inLetExprBody); wr.Write(")"); } else if (expr is QuantifierExpr) { var e = (QuantifierExpr)expr; // Compilation does not check whether a quantifier was split. Contract.Assert(e.Bounds != null); // for non-ghost quantifiers, the resolver would have insisted on finding bounds var n = e.BoundVars.Count; Contract.Assert(e.Bounds.Count == n); for (int i = 0; i < n; i++) { var bound = e.Bounds[i]; var bv = e.BoundVars[i]; // emit: Dafny.Helpers.QuantX(boundsInformation, isForall, bv => body) if (bound is ComprehensionExpr.BoolBoundedPool) { wr.Write("Dafny.Helpers.QuantBool("); } else if (bound is ComprehensionExpr.CharBoundedPool) { wr.Write("Dafny.Helpers.QuantChar("); } else if (bound is ComprehensionExpr.IntBoundedPool) { var b = (ComprehensionExpr.IntBoundedPool)bound; wr.Write("Dafny.Helpers.QuantInt("); TrExpr(b.LowerBound, wr, inLetExprBody); wr.Write(", "); TrExpr(b.UpperBound, wr, inLetExprBody); wr.Write(", "); } else if (bound is ComprehensionExpr.SetBoundedPool) { var b = (ComprehensionExpr.SetBoundedPool)bound; wr.Write("Dafny.Helpers.QuantSet("); TrExpr(b.Set, wr, inLetExprBody); wr.Write(", "); } else if (bound is ComprehensionExpr.MapBoundedPool) { var b = (ComprehensionExpr.MapBoundedPool)bound; wr.Write("Dafny.Helpers.QuantMap("); TrExpr(b.Map, wr, inLetExprBody); wr.Write(", "); } else if (bound is ComprehensionExpr.SeqBoundedPool) { var b = (ComprehensionExpr.SeqBoundedPool)bound; wr.Write("Dafny.Helpers.QuantSeq("); TrExpr(b.Seq, wr, inLetExprBody); wr.Write(", "); } else if (bound is ComprehensionExpr.DatatypeBoundedPool) { var b = (ComprehensionExpr.DatatypeBoundedPool)bound; wr.Write("Dafny.Helpers.QuantDatatype("); wr.Write("{0}.AllSingletonConstructors, ", DtName(b.Decl)); } else { Contract.Assert(false); throw new cce.UnreachableException(); // unexpected BoundedPool type } wr.Write("{0}, ", expr is ForallExpr ? "true" : "false"); wr.Write("@{0} => ", bv.CompileName); } TrExpr(e.LogicalBody(true), wr, inLetExprBody); for (int i = 0; i < n; i++) { wr.Write(")"); } } else if (expr is SetComprehension) { var e = (SetComprehension)expr; // For "set i,j,k,l | R(i,j,k,l) :: Term(i,j,k,l)" where the term has type "G", emit something like: // ((ComprehensionDelegate<G>)delegate() { // var _coll = new List<G>(); // foreach (L l in sq.Elements) { // foreach (K k in st.Elements) { // for (BigInteger j = Lo; j < Hi; j++) { // for (bool i in Helper.AllBooleans) { // if (R(i,j,k,l)) { // _coll.Add(Term(i,j,k,l)); // } // } // } // } // } // return Dafny.Set<G>.FromCollection(_coll); // })() Contract.Assert(e.Bounds != null); // the resolver would have insisted on finding bounds var typeName = TypeName(e.Type.AsSetType.Arg, wr); var collection_name = idGenerator.FreshId("_coll"); wr.Write("((Dafny.Helpers.ComprehensionDelegate<{0}>)delegate() {{ ", typeName); wr.Write("var {0} = new System.Collections.Generic.List<{1}>(); ", collection_name, typeName); var n = e.BoundVars.Count; Contract.Assert(e.Bounds.Count == n); for (int i = 0; i < n; i++) { var bound = e.Bounds[i]; var bv = e.BoundVars[i]; if (bound is ComprehensionExpr.BoolBoundedPool) { wr.Write("foreach (var @{0} in Dafny.Helpers.AllBooleans) {{ ", bv.CompileName); } else if (bound is ComprehensionExpr.CharBoundedPool) { wr.Write("foreach (var @{0} in Dafny.Helpers.AllChars) {{ ", bv.CompileName); } else if (bound is ComprehensionExpr.IntBoundedPool) { var b = (ComprehensionExpr.IntBoundedPool)bound; if (AsNativeType(bv.Type) != null) { wr.Write("foreach (var @{0} in @{1}.IntegerRange(", bv.CompileName, bv.Type.AsNewtype.FullCompileName); } else { wr.Write("foreach (var @{0} in Dafny.Helpers.IntegerRange(", bv.CompileName); } TrExpr(b.LowerBound, wr, inLetExprBody); wr.Write(", "); TrExpr(b.UpperBound, wr, inLetExprBody); wr.Write(")) { "); } else if (bound is ComprehensionExpr.SetBoundedPool) { var b = (ComprehensionExpr.SetBoundedPool)bound; wr.Write("foreach (var @{0} in (", bv.CompileName); TrExpr(b.Set, wr, inLetExprBody); wr.Write(").Elements) { "); } else if (bound is ComprehensionExpr.MapBoundedPool) { var b = (ComprehensionExpr.MapBoundedPool)bound; wr.Write("foreach (var @{0} in (", bv.CompileName); TrExpr(b.Map, wr, inLetExprBody); wr.Write(").Domain) { "); } else if (bound is ComprehensionExpr.SeqBoundedPool) { var b = (ComprehensionExpr.SeqBoundedPool)bound; wr.Write("foreach (var @{0} in (", bv.CompileName); TrExpr(b.Seq, wr, inLetExprBody); wr.Write(").Elements) { "); } else if (bound is ComprehensionExpr.DatatypeBoundedPool) { var b = (ComprehensionExpr.DatatypeBoundedPool)bound; wr.Write("foreach (var @{0} in {1}.AllSingletonConstructors) {{", bv.CompileName, TypeName(bv.Type, wr)); } else { Contract.Assert(false); throw new cce.UnreachableException(); // unexpected BoundedPool type } } wr.Write("if ("); TrExpr(e.Range, wr, inLetExprBody); wr.Write(") {"); wr.Write("{0}.Add(", collection_name); TrExpr(e.Term, wr, inLetExprBody); wr.Write("); }"); for (int i = 0; i < n; i++) { wr.Write("}"); } wr.Write("return Dafny.Set<{0}>.FromCollection({1}); ", typeName, collection_name); wr.Write("})()"); } else if (expr is MapComprehension) { var e = (MapComprehension)expr; // For "map i | R(i) :: Term(i)" where the term has type "V" and i has type "U", emit something like: // ((MapComprehensionDelegate<U, V>)delegate() { // var _coll = new List<Pair<U,V>>(); // foreach (L l in sq.Elements) { // foreach (K k in st.Elements) { // for (BigInteger j = Lo; j < Hi; j++) { // for (bool i in Helper.AllBooleans) { // if (R(i,j,k,l)) { // _coll.Add(new Pair(i, Term(i)); // } // } // } // } // } // return Dafny.Map<U, V>.FromElements(_coll); // })() Contract.Assert(e.Bounds != null); // the resolver would have insisted on finding bounds var domtypeName = TypeName(e.Type.AsMapType.Domain, wr); var rantypeName = TypeName(e.Type.AsMapType.Range, wr); var collection_name = idGenerator.FreshId("_coll"); wr.Write("((Dafny.Helpers.MapComprehensionDelegate<{0},{1}>)delegate() {{ ", domtypeName, rantypeName); wr.Write("var {0} = new System.Collections.Generic.List<Dafny.Pair<{1},{2}>>(); ", collection_name, domtypeName, rantypeName); var n = e.BoundVars.Count; Contract.Assert(e.Bounds.Count == n && n == 1); var bound = e.Bounds[0]; var bv = e.BoundVars[0]; if (bound is ComprehensionExpr.BoolBoundedPool) { wr.Write("foreach (var @{0} in Dafny.Helpers.AllBooleans) {{ ", bv.CompileName); } else if (bound is ComprehensionExpr.CharBoundedPool) { wr.Write("foreach (var @{0} in Dafny.Helpers.AllChars) {{ ", bv.CompileName); } else if (bound is ComprehensionExpr.IntBoundedPool) { var b = (ComprehensionExpr.IntBoundedPool)bound; if (AsNativeType(bv.Type) != null) { wr.Write("foreach (var @{0} in @{1}.IntegerRange(", bv.CompileName, bv.Type.AsNewtype.FullCompileName); } else { wr.Write("foreach (var @{0} in Dafny.Helpers.IntegerRange(", bv.CompileName); } TrExpr(b.LowerBound, wr, inLetExprBody); wr.Write(", "); TrExpr(b.UpperBound, wr, inLetExprBody); wr.Write(")) { "); } else if (bound is ComprehensionExpr.SetBoundedPool) { var b = (ComprehensionExpr.SetBoundedPool)bound; wr.Write("foreach (var @{0} in (", bv.CompileName); TrExpr(b.Set, wr, inLetExprBody); wr.Write(").Elements) { "); } else if (bound is ComprehensionExpr.MapBoundedPool) { var b = (ComprehensionExpr.MapBoundedPool)bound; wr.Write("foreach (var @{0} in (", bv.CompileName); TrExpr(b.Map, wr, inLetExprBody); wr.Write(").Domain) { "); } else if (bound is ComprehensionExpr.SeqBoundedPool) { var b = (ComprehensionExpr.SeqBoundedPool)bound; wr.Write("foreach (var @{0} in (", bv.CompileName); TrExpr(b.Seq, wr, inLetExprBody); wr.Write(").Elements) { "); } else { // TODO: handle ComprehensionExpr.SubSetBoundedPool Contract.Assert(false); throw new cce.UnreachableException(); // unexpected BoundedPool type } wr.Write("if ("); TrExpr(e.Range, wr, inLetExprBody); wr.Write(") { "); wr.Write("{0}.Add(new Dafny.Pair<{1},{2}>(@{3},", collection_name, domtypeName, rantypeName, bv.CompileName); TrExpr(e.Term, wr, inLetExprBody); wr.Write(")); }"); wr.Write("}"); wr.Write("return Dafny.Map<{0},{1}>.FromCollection({2}); ", domtypeName, rantypeName, collection_name); wr.Write("})()"); } else if (expr is LambdaExpr) { LambdaExpr e = (LambdaExpr)expr; var fvs = Translator.ComputeFreeVariables(expr); var sm = new Dictionary<IVariable, Expression>(); var bvars = new List<BoundVar>(); var fexprs = new List<Expression>(); foreach(var fv in fvs) { fexprs.Add(new IdentifierExpr(fv.Tok, fv.Name) { Var = fv, // resolved here! Type = fv.Type }); var bv = new BoundVar(fv.Tok, fv.Name, fv.Type); bvars.Add(bv); sm[fv] = new IdentifierExpr(bv.Tok, bv.Name) { Var = bv, // resolved here! Type = bv.Type }; } var su = new Translator.Substituter(null, sm, new Dictionary<TypeParameter, Type>(), null); BetaRedex(bvars, fexprs, expr.Type, wr, inLetExprBody, () => { wr.Write("("); wr.Write(Util.Comma(e.BoundVars, bv => "@" + bv.CompileName)); wr.Write(") => "); TrExpr(su.Substitute(e.Body), wr, inLetExprBody); }); } else if (expr is StmtExpr) { var e = (StmtExpr)expr; TrExpr(e.E, wr, inLetExprBody); } else if (expr is ITEExpr) { ITEExpr e = (ITEExpr)expr; wr.Write("("); TrExpr(e.Test, wr, inLetExprBody); wr.Write(") ? ("); TrExpr(e.Thn, wr, inLetExprBody); wr.Write(") : ("); TrExpr(e.Els, wr, inLetExprBody); wr.Write(")"); } else if (expr is ConcreteSyntaxExpression) { var e = (ConcreteSyntaxExpression)expr; TrExpr(e.ResolvedExpression, wr, inLetExprBody); } else if (expr is NamedExpr) { TrExpr(((NamedExpr)expr).Body, wr, inLetExprBody); } else { Contract.Assert(false); throw new cce.UnreachableException(); // unexpected expression } }
public void AcceptMethodCallsVisitOnVisitorWithThis() { var name = new IdentifierExpr(RandomGenerator.String()); var arguments = new VarDefinitionStmt[0]; var body = new NoOpStatement(); var returnType = new IdentifierExpr(RandomGenerator.String()); var target = new FunctionDefinitionExpr(name, arguments, body, returnType); var visitor = new Mock<IExpressionVisitor<string, int>>(); target.Accept(visitor.Object, 0); visitor.Verify(x => x.Visit(target, 0), Times.Once); }
public override Expr VisitIdentifierExpr(IdentifierExpr node) { //Contract.Requires(node != null); Contract.Ensures(Contract.Result<Expr>() != null); return base.VisitIdentifierExpr((IdentifierExpr)node.Clone()); }
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 PredicateBlock(Expr pExpr, Block block, List<Block> newBlocks, ref Block prevBlock) { var firstBlock = block; var oldCmdSeq = block.Cmds; block.Cmds = new List<Cmd>(); newBlocks.Add(block); if (prevBlock != null && !((prevBlock.TransferCmd is ReturnCmd) && uni != null && uni.IsUniform(impl.Name, block))) { prevBlock.TransferCmd = new GotoCmd(Token.NoToken, new List<Block> { block }); } Block currentBlock = block; Expr pCurrentExpr = pExpr; while (parentMap.ContainsKey(currentBlock)) { Block parent = parentMap[currentBlock]; Expr pParentExpr = null; if (predMap.ContainsKey(parent)) { var parentPred = predMap[parent]; if (parentPred != null) { pParentExpr = Expr.Ident(parentPred); block.Cmds.Add(new AssertCmd(Token.NoToken, pCurrentExpr != null ? (Expr)Expr.Imp(pCurrentExpr, pParentExpr) : pParentExpr)); } } currentBlock = parent; pCurrentExpr = pParentExpr; } Block dominator = FindImmediateDominator(block); Expr pDomExpr = Expr.True; if (dominator != null && predMap.ContainsKey(dominator)) pDomExpr = new IdentifierExpr(Token.NoToken, predMap[dominator]); var transferCmd = block.TransferCmd; foreach (Cmd cmd in oldCmdSeq) PredicateCmd(pExpr, pDomExpr, newBlocks, block, cmd, out block); if (ownedMap.ContainsKey(firstBlock)) { var owned = ownedMap[firstBlock]; foreach (var v in owned) block.Cmds.Add(Cmd.SimpleAssign(Token.NoToken, Expr.Ident(v), Expr.False)); } bool hasPredicatedRegion; PredicateTransferCmd(pExpr, block, block.Cmds, transferCmd, out hasPredicatedRegion); if (hasPredicatedRegion) prevBlock = block; else prevBlock = null; doneBlocks.Add(block); }
void PredicateImplementation() { blockGraph = prog.ProcessLoops(impl); sortedBlocks = blockGraph.LoopyTopSort(); AssignPredicates(); partInfo = BuildPartitionInfo(); if (myUseProcedurePredicates) fp = Expr.Ident(impl.InParams[0]); var newBlocks = new List<Block>(); Block prevBlock = null; foreach (var n in sortedBlocks) { if (predMap.ContainsKey(n.Item1)) { var p = predMap[n.Item1]; var pExpr = Expr.Ident(p); if (n.Item2) { var dominator = FindImmediateDominator(n.Item1); if (dominator != null && predMap.ContainsKey(dominator)) { AssumeCmd aCmd = new AssumeCmd(Token.NoToken, Expr.True); aCmd.Attributes = new QKeyValue(Token.NoToken, "dominator_predicate", new List<object>() { predMap[dominator].ToString() }, aCmd.Attributes); aCmd.Attributes = new QKeyValue(Token.NoToken, "predicate", new List<object>() { predMap[n.Item1].ToString() }, aCmd.Attributes); n.Item1.Cmds.Insert(0, aCmd); } var backedgeBlock = new Block(); newBlocks.Add(backedgeBlock); backedgeBlock.Label = n.Item1.Label + ".backedge"; backedgeBlock.Cmds = new List<Cmd> { new AssumeCmd(Token.NoToken, pExpr, new QKeyValue(Token.NoToken, "backedge", new List<object>(), null)) }; backedgeBlock.TransferCmd = new GotoCmd(Token.NoToken, new List<Block> { n.Item1 }); var tailBlock = new Block(); newBlocks.Add(tailBlock); tailBlock.Label = n.Item1.Label + ".tail"; tailBlock.Cmds = new List<Cmd> { new AssumeCmd(Token.NoToken, Expr.Not(pExpr)) }; if (uni != null && !uni.IsUniform(impl.Name, n.Item1)) { uni.AddNonUniform(impl.Name, backedgeBlock); uni.AddNonUniform(impl.Name, tailBlock); } if (prevBlock != null) prevBlock.TransferCmd = new GotoCmd(Token.NoToken, new List<Block> { backedgeBlock, tailBlock }); prevBlock = tailBlock; } else { PredicateBlock(pExpr, n.Item1, newBlocks, ref prevBlock); } } else { if (!n.Item2) { PredicateBlock(null, n.Item1, newBlocks, ref prevBlock); } } } if (prevBlock != null) prevBlock.TransferCmd = new ReturnCmd(Token.NoToken); impl.Blocks = newBlocks; }
void PredicateImplementation() { blockGraph = prog.ProcessLoops(impl); var sortedBlocks = blockGraph.LoopyTopSort(); int blockId = 0; foreach (var block in impl.Blocks) blockIds[block] = Expr.Literal(blockId++); returnBlockId = Expr.Literal(blockId++); curVar = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, "cur", Microsoft.Boogie.Type.Int)); impl.LocVars.Add(curVar); cur = Expr.Ident(curVar); pVar = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, "p", Microsoft.Boogie.Type.Bool)); impl.LocVars.Add(pVar); p = Expr.Ident(pVar); if (useProcedurePredicates) fp = Expr.Ident(impl.InParams[0]); var newBlocks = new List<Block>(); Block entryBlock = new Block(); entryBlock.Label = "entry"; entryBlock.Cmds = new List<Cmd> { Cmd.SimpleAssign(Token.NoToken, cur, CreateIfFPThenElse(blockIds[sortedBlocks[0].Item1], returnBlockId)) }; newBlocks.Add(entryBlock); var prevBlock = entryBlock; foreach (var n in sortedBlocks) { if (n.Item2) { var backedgeBlock = new Block(); newBlocks.Add(backedgeBlock); backedgeBlock.Label = n.Item1.Label + ".backedge"; backedgeBlock.Cmds = new List<Cmd> { new AssumeCmd(Token.NoToken, Expr.Eq(cur, blockIds[n.Item1]), new QKeyValue(Token.NoToken, "backedge", new List<object>(), null)) }; backedgeBlock.TransferCmd = new GotoCmd(Token.NoToken, new List<Block> { n.Item1 }); var tailBlock = new Block(); newBlocks.Add(tailBlock); tailBlock.Label = n.Item1.Label + ".tail"; tailBlock.Cmds = new List<Cmd> { new AssumeCmd(Token.NoToken, Expr.Neq(cur, blockIds[n.Item1])) }; prevBlock.TransferCmd = new GotoCmd(Token.NoToken, new List<Block> { backedgeBlock, tailBlock }); prevBlock = tailBlock; } else { var runBlock = n.Item1; var oldCmdSeq = runBlock.Cmds; runBlock.Cmds = new List<Cmd>(); newBlocks.Add(runBlock); prevBlock.TransferCmd = new GotoCmd(Token.NoToken, new List<Block> { runBlock }); pExpr = Expr.Eq(cur, blockIds[runBlock]); if (createCandidateInvariants && blockGraph.Headers.Contains(runBlock)) { AddUniformCandidateInvariant(runBlock.Cmds, runBlock); AddNonUniformCandidateInvariant(runBlock.Cmds, runBlock); } runBlock.Cmds.Add(Cmd.SimpleAssign(Token.NoToken, p, pExpr)); var transferCmd = runBlock.TransferCmd; foreach (Cmd cmd in oldCmdSeq) PredicateCmd(newBlocks, runBlock, cmd, out runBlock); PredicateTransferCmd(runBlock.Cmds, transferCmd); prevBlock = runBlock; doneBlocks.Add(runBlock); } } prevBlock.TransferCmd = new ReturnCmd(Token.NoToken); impl.Blocks = newBlocks; }
public override Cmd VisitCallCmd(CallCmd node) { var result = base.VisitCallCmd(node); var oldProc = programInCachedSnapshot.FindProcedure(node.Proc.Name); if (oldProc != null && oldProc.DependencyChecksum != node.Proc.DependencyChecksum && node.AssignedAssumptionVariable == null) { var before = new List<Cmd>(); var beforePrecondtionCheck = new List<Cmd>(); var after = new List<Cmd>(); var axioms = new List<Axiom>(); Expr assumedExpr = new LiteralExpr(Token.NoToken, false); // TODO(wuestholz): Try out two alternatives: only do this for low priority implementations or not at all. var canUseSpecs = DependencyCollector.CanExpressOldSpecs(oldProc, Program); if (canUseSpecs && oldProc.SignatureEquals(node.Proc)) { var desugaring = node.Desugaring; Contract.Assert(desugaring != null); var precond = node.CheckedPrecondition(oldProc, Program, e => FunctionExtractor.Extract(e, Program, axioms)); if (precond != null) { var assume = new AssumeCmd(node.tok, precond, new QKeyValue(Token.NoToken, "precondition_previous_snapshot", new List<object>(), null)); assume.IrrelevantForChecksumComputation = true; beforePrecondtionCheck.Add(assume); } var unmods = node.UnmodifiedBefore(oldProc); var eqs = new List<Expr>(); foreach (var unmod in unmods) { var oldUnmod = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, string.Format("{0}##old##{1}", unmod.Name, FreshTemporaryVariableName), unmod.Type)); var lhs = new SimpleAssignLhs(Token.NoToken, new IdentifierExpr(Token.NoToken, oldUnmod)); var rhs = new IdentifierExpr(Token.NoToken, unmod.Decl); var cmd = new AssignCmd(Token.NoToken, new List<AssignLhs> { lhs }, new List<Expr> { rhs }); cmd.IrrelevantForChecksumComputation = true; before.Add(cmd); var eq = LiteralExpr.Eq(new IdentifierExpr(Token.NoToken, oldUnmod), new IdentifierExpr(Token.NoToken, unmod.Decl)); eq.Type = Type.Bool; eq.TypeParameters = SimpleTypeParamInstantiation.EMPTY; eqs.Add(eq); } var mods = node.ModifiedBefore(oldProc); var oldSubst = new Dictionary<Variable, Expr>(); foreach (var mod in mods) { var oldMod = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, string.Format("{0}##old##{1}", mod.Name, FreshTemporaryVariableName), mod.Type)); oldSubst[mod.Decl] = new IdentifierExpr(Token.NoToken, oldMod); var lhs = new SimpleAssignLhs(Token.NoToken, new IdentifierExpr(Token.NoToken, oldMod)); var rhs = new IdentifierExpr(Token.NoToken, mod.Decl); var cmd = new AssignCmd(Token.NoToken, new List<AssignLhs> { lhs }, new List<Expr> { rhs }); cmd.IrrelevantForChecksumComputation = true; before.Add(cmd); } assumedExpr = node.Postcondition(oldProc, eqs, oldSubst, Program, e => FunctionExtractor.Extract(e, Program, axioms)); if (assumedExpr == null) { assumedExpr = new LiteralExpr(Token.NoToken, true); } } if (assumedExpr != null) { var lv = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, string.Format("a##cached##{0}", FreshAssumptionVariableName), Type.Bool), new QKeyValue(Token.NoToken, "assumption", new List<object>(), null)); node.AssignedAssumptionVariable = lv; currentImplementation.InjectAssumptionVariable(lv, !canUseSpecs); var lhs = new SimpleAssignLhs(Token.NoToken, new IdentifierExpr(Token.NoToken, lv)); var rhs = LiteralExpr.And(new IdentifierExpr(Token.NoToken, lv), assumedExpr); var assumed = new AssignCmd(node.tok, new List<AssignLhs> { lhs }, new List<Expr> { rhs }); assumed.IrrelevantForChecksumComputation = true; after.Add(assumed); } node.ExtendDesugaring(before, beforePrecondtionCheck, after); if (CommandLineOptions.Clo.TraceCachingForTesting || CommandLineOptions.Clo.TraceCachingForBenchmarking) { using (var tokTxtWr = new TokenTextWriter("<console>", Console.Out, false, false)) { var loc = node.tok != null && node.tok != Token.NoToken ? string.Format("{0}({1},{2})", node.tok.filename, node.tok.line, node.tok.col) : "<unknown location>"; Console.Out.WriteLine("Processing call to procedure {0} in implementation {1} (at {2}):", node.Proc.Name, currentImplementation.Name, loc); foreach (var a in axioms) { Console.Out.Write(" >>> added axiom: "); a.Expr.Emit(tokTxtWr); Console.Out.WriteLine(); } foreach (var b in before) { Console.Out.Write(" >>> added before: "); b.Emit(tokTxtWr, 0); } foreach (var b in beforePrecondtionCheck) { Console.Out.Write(" >>> added before precondition check: "); b.Emit(tokTxtWr, 0); } foreach (var a in after) { Console.Out.Write(" >>> added after: "); a.Emit(tokTxtWr, 0); } } } } return result; }
public void AcceptMethodCallsOnlyVisitOnVisitorWithThisAndNoOtherVisitMethods() { var name = new IdentifierExpr(RandomGenerator.String()); var arguments = new VarDefinitionStmt[0]; var body = new NoOpStatement(); var returnType = new IdentifierExpr(RandomGenerator.String()); var target = new FunctionDefinitionExpr(name, arguments, body, returnType); // throw exception is any other methods called other than the PlusExpr overload. var visitor = new Mock<IExpressionVisitor<string, int>>(MockBehavior.Strict); visitor.Setup(x => x.Visit(target, 1234)).Returns(""); target.Accept(visitor.Object, 1234); }
private NAryExpr GetUnTypedImmutableNAry() { var id = new IdentifierExpr(Token.NoToken, "foo", BasicType.Bool, /*immutable=*/true); Assert.IsTrue(id.Immutable); Assert.IsTrue(id.Type.IsBool); var e = new NAryExpr(Token.NoToken, new BinaryOperator(Token.NoToken, BinaryOperator.Opcode.And), new List<Expr>() { id, id }, /*immutable=*/true); Assert.IsNull(e.Type); Assert.IsTrue(e.Immutable); return e; }
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 }
void PredicateCmd(Expr p, Expr pDom, List<Cmd> cmdSeq, Cmd cmd) { if (cmd is CallCmd) { var cCmd = (CallCmd)cmd; Debug.Assert(useProcedurePredicates(cCmd.Proc)); cCmd.Ins.Insert(0, p != null ? p : Expr.True); cmdSeq.Add(cCmd); } else if (p == null) { new EnabledReplacementVisitor(Expr.True, pDom).Visit(cmd); cmdSeq.Add(cmd); } else if (cmd is AssignCmd) { var aCmd = (AssignCmd)cmd; cmdSeq.Add(new AssignCmd(Token.NoToken, aCmd.Lhss, new List<Expr>(aCmd.Lhss.Zip(aCmd.Rhss, (lhs, rhs) => new NAryExpr(Token.NoToken, new IfThenElse(Token.NoToken), new List<Expr> { p, rhs, lhs.AsExpr }))))); } else if (cmd is AssertCmd) { var aCmd = (AssertCmd)cmd; Expr newExpr = new EnabledReplacementVisitor(p, pDom).VisitExpr(aCmd.Expr); aCmd.Expr = QKeyValue.FindBoolAttribute(aCmd.Attributes, "do_not_predicate") ? newExpr : Expr.Imp(p, newExpr); cmdSeq.Add(aCmd); } else if (cmd is AssumeCmd) { var aCmd = (AssumeCmd)cmd; Expr newExpr = new EnabledReplacementVisitor(p, pDom).VisitExpr(aCmd.Expr); aCmd.Expr = QKeyValue.FindBoolAttribute(aCmd.Attributes, "do_not_predicate") ? newExpr : Expr.Imp(p, newExpr); cmdSeq.Add(aCmd); } else if (cmd is HavocCmd) { var hCmd = (HavocCmd)cmd; foreach (IdentifierExpr v in hCmd.Vars) { Microsoft.Boogie.Type type = v.Decl.TypedIdent.Type; Contract.Assert(type != null); IdentifierExpr havocTempExpr; if (havocVars.ContainsKey(type)) { havocTempExpr = havocVars[type]; } else { var havocVar = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, "_HAVOC_" + type.ToString(), type)); impl.LocVars.Add(havocVar); havocVars[type] = havocTempExpr = new IdentifierExpr(Token.NoToken, havocVar); } cmdSeq.Add(new HavocCmd(Token.NoToken, new List<IdentifierExpr> { havocTempExpr })); cmdSeq.Add(Cmd.SimpleAssign(Token.NoToken, v, new NAryExpr(Token.NoToken, new IfThenElse(Token.NoToken), new List<Expr> { p, havocTempExpr, v }))); } } else if (cmd is CommentCmd) { // skip } else if (cmd is StateCmd) { var sCmd = (StateCmd)cmd; var newCmdSeq = new List<Cmd>(); foreach (Cmd c in sCmd.Cmds) PredicateCmd(p, pDom, newCmdSeq, c); sCmd.Cmds = newCmdSeq; cmdSeq.Add(sCmd); } else { Console.WriteLine("Unsupported cmd: " + cmd.GetType().ToString()); } }
void PredicateCmd(List<Cmd> cmdSeq, Cmd cmd) { if (cmd is AssignCmd) { var aCmd = (AssignCmd)cmd; cmdSeq.Add(new AssignCmd(Token.NoToken, aCmd.Lhss, new List<Expr>(aCmd.Lhss.Zip(aCmd.Rhss, (lhs, rhs) => new NAryExpr(Token.NoToken, new IfThenElse(Token.NoToken), new List<Expr> { p, rhs, lhs.AsExpr }))))); } else if (cmd is AssertCmd) { var aCmd = (AssertCmd)cmd; if (cmdSeq.Last() is AssignCmd && cmdSeq.Cast<Cmd>().SkipEnd(1).All(c => c is AssertCmd)) { // This may be a loop invariant. Make sure it continues to appear as // the first statement in the block. var assign = cmdSeq.Last(); cmdSeq.RemoveAt(cmdSeq.Count-1); Expr newExpr = new EnabledReplacementVisitor(pExpr).VisitExpr(aCmd.Expr); aCmd.Expr = QKeyValue.FindBoolAttribute(aCmd.Attributes, "do_not_predicate") ? newExpr : Expr.Imp(pExpr, newExpr); cmdSeq.Add(aCmd); // cmdSeq.Add(new AssertCmd(aCmd.tok, Expr.Imp(pExpr, aCmd.Expr))); cmdSeq.Add(assign); } else { aCmd.Expr = Expr.Imp(p, aCmd.Expr); cmdSeq.Add(aCmd); // cmdSeq.Add(new AssertCmd(aCmd.tok, Expr.Imp(p, aCmd.Expr))); } } else if (cmd is AssumeCmd) { var aCmd = (AssumeCmd)cmd; cmdSeq.Add(new AssumeCmd(Token.NoToken, Expr.Imp(p, aCmd.Expr))); } else if (cmd is HavocCmd) { var hCmd = (HavocCmd)cmd; foreach (IdentifierExpr v in hCmd.Vars) { Microsoft.Boogie.Type type = v.Decl.TypedIdent.Type; Contract.Assert(type != null); IdentifierExpr havocTempExpr; if (havocVars.ContainsKey(type)) { havocTempExpr = havocVars[type]; } else { var havocVar = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, "_HAVOC_" + type.ToString(), type)); impl.LocVars.Add(havocVar); havocVars[type] = havocTempExpr = new IdentifierExpr(Token.NoToken, havocVar); } cmdSeq.Add(new HavocCmd(Token.NoToken, new List<IdentifierExpr> { havocTempExpr })); cmdSeq.Add(Cmd.SimpleAssign(Token.NoToken, v, new NAryExpr(Token.NoToken, new IfThenElse(Token.NoToken), new List<Expr> { p, havocTempExpr, v }))); } } else if (cmd is CallCmd) { Debug.Assert(useProcedurePredicates); var cCmd = (CallCmd)cmd; cCmd.Ins.Insert(0, p); cmdSeq.Add(cCmd); } else if (cmd is CommentCmd) { // skip } else if (cmd is StateCmd) { var sCmd = (StateCmd)cmd; var newCmdSeq = new List<Cmd>(); foreach (Cmd c in sCmd.Cmds) PredicateCmd(newCmdSeq, c); sCmd.Cmds = newCmdSeq; cmdSeq.Add(sCmd); } else { Console.WriteLine("Unsupported cmd: " + cmd.GetType().ToString()); } }
public static IdentifierExpr MakeIdentifierExpr(string name, Type type, bool isGhost) { Util.Assert(type != null); IdentifierExpr id = new IdentifierExpr(Bpl.Token.NoToken, name); id.Type = type; id.Var = new LocalVariable(Bpl.Token.NoToken, Bpl.Token.NoToken, name, type, isGhost); return id; }
public override Expr VisitIdentifierExpr(IdentifierExpr node) { //Contract.Requires(node != null); Contract.Ensures(Contract.Result<Expr>() != null); Expr/*?*/ e = null; if (insideOldExpr) { e = forold(cce.NonNull(node.Decl)); } if (e == null) { e = always(cce.NonNull(node.Decl)); } return e == null ? base.VisitIdentifierExpr(node) : e; }
public override void Visit(IdentifierExpr identifierNode) { identifierNode.ExprValue = SymbolTable.GetSymbolValue(identifierNode.IdentifierName); }
public Tuple<Method,TypeApply> GetSeqBuildMethod(Type t, SeqTree tree, List<bool> elemDimensions) { if (elemDimensions.Count == 0) { return GetSeqMethod(t, "seq_Empty"); } if (elemDimensions.Count == 2 && elemDimensions[0] && elemDimensions[1]) { return GetSeqMethod(t, "seq_Append"); } string op = "seq_" + SeqTree.TreeName(tree); DatatypeDecl seqDecl = FindDatatype("Seq"); var tok = new Bpl.Token(0, 0); tok.filename = @"!\Seq.dfy"; TypeApply tApp = Compile_SeqType((SeqType)t); Type dataType = new UserDefinedType(tok, "Seq", seqDecl, new List<Type> { ((SeqType)t).Arg }); Type elemType = ((SeqType)t).Arg; Func<string,Type,Expression> idExpr = (x, typ) => { var e = new IdentifierExpr(tok, x); e.Type = typ; e.Var = new LocalVariable(tok, tok, x, typ, false); return e; }; Func<string,List<Expression>,FunctionCallExpr> seqCall = (x, args) => { var seqOp = GetSeqOperation(t, x); FunctionCallExpr callExpr = new FunctionCallExpr( tok, "Seq_Empty", new ThisExpr(tok), tok, args); callExpr.Function = seqOp.Item1; callExpr.TypeArgumentSubstitutions = seqOp.Item2.typeArgs; return callExpr; }; Expression empty = seqCall("Seq_Empty", new List<Expression> {}); int varCount = 0; Func<SeqTree,Expression> resultRec = null; resultRec = (subtree) => { if (subtree == null) { return idExpr("s" + (varCount++), dataType); } if (subtree.buildCount >= 0) { Expression build = empty; for (int i = 0; i < subtree.buildCount; i++) { build = seqCall("Seq_Build", new List<Expression> { build, idExpr("a" + (varCount++), elemType) }); } return build; } else { return seqCall("Seq_Append", new List<Expression> { resultRec(subtree.left), resultRec(subtree.right) }); } }; Expression result = resultRec(tree); Expression post = seqCall("Seq_Equal", new List<Expression> { idExpr("s", dataType), result }); List<Statement> stmts = new List<Statement>(); for (int i = elemDimensions.Count; i > 0;) { bool isFirst = (i == elemDimensions.Count); i--; if (elemDimensions[i]) { if (isFirst) { stmts.Add(new AssignStmt(tok, tok, idExpr("s", dataType), new ExprRhs(idExpr("s" + i, dataType)))); } else { // s := seq_Append(s9, s); var selectExpr = new MemberSelectExpr(tok, new ThisExpr(tok), "seq_Append"); selectExpr.Member = FindMethod(selectExpr.MemberName); // Manually resolve here selectExpr.TypeApplication = new List<Type>() { elemType }; // Manually resolve here selectExpr.Type = new InferredTypeProxy(); // Manually resolve here CallStmt callStmt = new CallStmt(tok, tok, new List<Expression> {idExpr("s", dataType)}, selectExpr, new List<Expression> { idExpr("s" + i, dataType), idExpr("s", dataType) }); stmts.Add(callStmt); } } else { if (isFirst) { DatatypeValue nil = new DatatypeValue(tok, "Seq", "Nil", new List<Expression>() {}); nil.Type = dataType; nil.InferredTypeArgs = new List<Type> { elemType }; nil.Ctor = seqDecl.Ctors[0]; Util.Assert(nil.Ctor.Name == "Seq_Nil"); stmts.Add(new AssignStmt(tok, tok, idExpr("s", dataType), new ExprRhs(nil))); } // lemma_Seq_Cons(ai, s); var selectExpr = new MemberSelectExpr(tok, new ThisExpr(tok), "lemma_Seq_Cons"); selectExpr.Member = FindMethod(selectExpr.MemberName); // Manually resolve here selectExpr.TypeApplication = new List<Type>() { elemType }; // Manually resolve here selectExpr.Type = new InferredTypeProxy(); // Manually resolve here CallStmt callStmt = new CallStmt(tok, tok, new List<Expression> {}, selectExpr, new List<Expression> { idExpr("a" + i, elemType), idExpr("s", dataType) }); callStmt.IsGhost = true; stmts.Add(callStmt); DatatypeValue cons = new DatatypeValue(tok, "Seq", "Cons", new List<Expression>() { idExpr("a" + i, elemType), idExpr("s", dataType) }); cons.Type = dataType; cons.InferredTypeArgs = new List<Type> { elemType }; cons.Ctor = seqDecl.Ctors[1]; Util.Assert(cons.Ctor.Name == "Seq_Cons"); stmts.Add(new AssignStmt(tok, tok, idExpr("s", dataType), new ExprRhs(cons))); } } BlockStmt body = new BlockStmt(tok, tok, stmts); List<Formal> ins = new List<Formal>(); for (int i = 0; i < elemDimensions.Count; i++) { bool isSeq = elemDimensions[i]; ins.Add(new Formal(tok, (isSeq ? "s" : "a") + i, isSeq ? dataType : elemType, true, false)); } List<Formal> outs = new List<Formal> { new Formal(tok, "s", dataType, false, false) }; List<MaybeFreeExpression> reqs = new List<MaybeFreeExpression>(); List<MaybeFreeExpression> enss = new List<MaybeFreeExpression> { new MaybeFreeExpression(post) }; Specification<FrameExpression> mods = new Specification<FrameExpression>(new List<FrameExpression>(), null); Specification<Expression> decs = new Specification<Expression>(new List<Expression>(), null); Attributes attrs = new Attributes("dafnycc_conservative_seq_triggers", new List<Expression>(), null); Method m = new Method(tok, op, true, false, tApp.typeParams, ins, outs, reqs, mods, enss, decs, body, attrs, tok); m.EnclosingClass = GetSeqMethod(t, "seq_Append").Item1.EnclosingClass; return Tuple.Create(m, Compile_Method(m, tApp.typeArgs)); }
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); } }