private static void BuildAssignment(Sink sink, Bpl.StmtListBuilder stmtBuilder, List <Bpl.Variable> lvars, List <Bpl.Variable> rvars) { for (int i = 0; i < lvars.Count; i++) { Bpl.Variable lvar = lvars[i]; Bpl.Type ltype = lvar.TypedIdent.Type; Bpl.Variable rvar = rvars[i]; Bpl.Type rtype = rvar.TypedIdent.Type; Bpl.IdentifierExpr lexpr = Bpl.Expr.Ident(lvar); Bpl.Expr rexpr = Bpl.Expr.Ident(rvar); if (rtype == ltype) { // do nothing } else if (ltype == sink.Heap.UnionType) { rexpr = sink.Heap.ToUnion(Bpl.Token.NoToken, rtype, rexpr, false, stmtBuilder); } else if (rtype == sink.Heap.UnionType) { rexpr = sink.Heap.FromUnion(Bpl.Token.NoToken, ltype, rexpr, false); } else { System.Diagnostics.Debug.Assert(false); } stmtBuilder.Add(TranslationHelper.BuildAssignCmd(lexpr, rexpr)); } }
/// <summary> /// lhs should be a Bpl.IdentifierExpr. /// Creates lhs := rhs; /// </summary> static Bpl.Cmd BplSimplestAssign(Bpl.Expr lhs, Bpl.Expr rhs) { Contract.Requires(lhs is Bpl.IdentifierExpr); return(new Bpl.AssignCmd(rhs.tok, Singleton((Bpl.AssignLhs) new Bpl.SimpleAssignLhs(rhs.tok, (Bpl.IdentifierExpr)lhs)), Singleton(rhs))); }
public bpl.Expr guardWithExistConst(bpl.Expr expr) { var existsConst = new bpl.Constant(bpl.Token.NoToken, new bpl.TypedIdent(bpl.Token.NoToken, existsConstName + (numExistsConst++), bpl.Type.Bool)); existsConsts.Add(existsConst); return(bpl.NAryExpr.Imp(new bpl.IdentifierExpr(bpl.Token.NoToken, existsConst), expr)); }
public Bpl.Expr FromUnion(Bpl.IToken tok, Bpl.Type boogieType, Bpl.Expr expr, bool isStruct) { if (boogieType == UnionType || boogieType == RefType) { return(expr); } Bpl.Function conversion = null; if (boogieType == Bpl.Type.Bool) { conversion = this.Union2Bool; } else if (boogieType == Bpl.Type.Int) { conversion = this.Union2Int; } else if (boogieType == RealType) { conversion = this.Union2Real; } else { throw new InvalidOperationException(String.Format("Unknown Boogie type: '{0}'", boogieType.ToString())); } var callExpr = new Bpl.NAryExpr( tok, new Bpl.FunctionCall(conversion), new List <Bpl.Expr>(new Bpl.Expr[] { expr }) ); callExpr.Type = boogieType; return(callExpr); }
public override void TraverseChildren(IAssertStatement assertStatement) { Bpl.Expr conditionExpr = ExpressionFor(assertStatement.Condition); Bpl.Type conditionType = this.sink.CciTypeToBoogie(assertStatement.Condition.Type); if (conditionType == this.sink.Heap.RefType) { conditionExpr = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, conditionExpr, Bpl.Expr.Ident(this.sink.Heap.NullRef)); } else if (conditionType == Bpl.Type.Int) { conditionExpr = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, conditionExpr, Bpl.Expr.Literal(0)); } else { System.Diagnostics.Debug.Assert(conditionType == Bpl.Type.Bool); } if (this.sink.Options.getMeHere) { StmtBuilder.Add(new Bpl.AssumeCmd(assertStatement.Token(), conditionExpr)); } else { StmtBuilder.Add(new Bpl.AssertCmd(assertStatement.Token(), conditionExpr)); } }
public void RaiseException(Bpl.Expr e) { Bpl.StmtListBuilder builder = new Bpl.StmtListBuilder(); RaiseExceptionHelper(builder); Bpl.IfCmd ifCmd = new Bpl.IfCmd(Bpl.Token.NoToken, e, builder.Collect(Bpl.Token.NoToken), null, null); StmtBuilder.Add(ifCmd); }
bool IsLit(Bpl.Expr expr) { if (expr is Bpl.IdentifierExpr ie) { return(letBoundVariablesWithLitRHS.Contains(ie.Name)); } return(GetLit(expr) != null); }
/* 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 AddRecordCall(string label, IExpression value, Bpl.Expr valueBpl) { // valueBpl.Type only gets set in a few simple cases, while // sink.CciTypeToBoogie(value.Type.ResolvedType) should always be correct // if BCT is working properly. *cross fingers* // ~ REDACTED 2016-06-21 AddRecordCall(label, sink.CciTypeToBoogie(value.Type.ResolvedType), valueBpl); }
public Bpl.Expr ProperMultiset(Bpl.IToken tok, Bpl.Expr e0, Bpl.Expr e1) { Contract.Requires(tok != null); Contract.Requires(e0 != null); Contract.Requires(e1 != null); return(Bpl.Expr.Binary(tok, Bpl.BinaryOperator.Opcode.And, FunctionCall(tok, BuiltinFunction.MultiSetSubset, null, e0, e1), Bpl.Expr.Not(FunctionCall(tok, BuiltinFunction.MultiSetEqual, null, e0, e1)))); }
public static Bpl.AssignCmd BuildAssignCmd(Bpl.IdentifierExpr lhs, Bpl.Expr rhs) { List <Bpl.AssignLhs> lhss = new List <Bpl.AssignLhs>(); lhss.Add(new Bpl.SimpleAssignLhs(lhs.tok, lhs)); List <Bpl.Expr> rhss = new List <Bpl.Expr>(); rhss.Add(rhs); return(new Bpl.AssignCmd(lhs.tok, lhss, rhss)); }
static Bpl.Expr BplOr(IEnumerable <Bpl.Expr> disjuncts) { Contract.Requires(disjuncts != null); Bpl.Expr eq = Bpl.Expr.False; foreach (var d in disjuncts) { eq = BplOr(eq, d); } return(eq); }
static Bpl.Expr BplAnd(IEnumerable <Bpl.Expr> conjuncts) { Contract.Requires(conjuncts != null); Bpl.Expr eq = Bpl.Expr.True; foreach (var c in conjuncts) { eq = BplAnd(eq, c); } return(eq); }
public Bpl.Expr ProperSubset(Bpl.IToken tok, Bpl.Expr e0, Bpl.Expr e1) { Contract.Requires(tok != null); Contract.Requires(e0 != null); Contract.Requires(e1 != null); Contract.Ensures(Contract.Result <Bpl.Expr>() != null); return(Bpl.Expr.Binary(tok, Bpl.BinaryOperator.Opcode.And, FunctionCall(tok, BuiltinFunction.SetSubset, null, e0, e1), Bpl.Expr.Not(FunctionCall(tok, BuiltinFunction.SetSubset, null, e1, e0)))); }
/// <summary> /// Returns the BPL expression that corresponds to the value of the dynamic type /// of the object represented by the expression <paramref name="o"/>. /// </summary> public Bpl.Expr DynamicType(Bpl.Expr o) { // $DymamicType(o) var callDynamicType = new Bpl.NAryExpr( o.tok, new Bpl.FunctionCall(this.DynamicTypeFunction), new List <Bpl.Expr>(new Bpl.Expr[] { o }) ); return(callDynamicType); }
public Bpl.Expr ProperPrefix(Bpl.IToken tok, Bpl.Expr e0, Bpl.Expr e1) { Contract.Requires(tok != null); Contract.Requires(e0 != null); Contract.Requires(e1 != null); Contract.Ensures(Contract.Result <Bpl.Expr>() != null); Bpl.Expr len0 = FunctionCall(tok, BuiltinFunction.SeqLength, null, e0); Bpl.Expr len1 = FunctionCall(tok, BuiltinFunction.SeqLength, null, e1); return(Bpl.Expr.And( Bpl.Expr.Lt(len0, len1), FunctionCall(tok, BuiltinFunction.SeqSameUntil, null, e0, e1, len0))); }
/// <summary> /// If the local declaration has an initial value, then generate the /// statement "loc := e" from it. /// Special case: if "loc" is a struct, then treat it as a call to /// the default ctor. /// Otherwise ignore it. /// </summary> public override void TraverseChildren(ILocalDeclarationStatement localDeclarationStatement) { var initVal = localDeclarationStatement.InitialValue; var typ = localDeclarationStatement.LocalVariable.Type; var isStruct = TranslationHelper.IsStruct(typ); if (initVal == null && !isStruct) { return; } var boogieLocal = this.sink.FindOrCreateLocalVariable(localDeclarationStatement.LocalVariable); var boogieLocalExpr = Bpl.Expr.Ident(boogieLocal); var tok = localDeclarationStatement.Token(); Bpl.Expr e = null; var structCopy = isStruct && initVal != null && !(initVal is IDefaultValue); // then a struct value of type S is being assigned: "lhs := s" // model this as the statement "call lhs := S..#copy_ctor(s)" that does the bit-wise copying if (isStruct) { if (!structCopy) { var defaultValue = new DefaultValue() { DefaultValueType = typ, Locations = new List <ILocation>(localDeclarationStatement.Locations), Type = typ, }; var e2 = ExpressionFor(defaultValue); StmtBuilder.Add(Bpl.Cmd.SimpleAssign(tok, boogieLocalExpr, e2)); } else /*if (structCopy) */ { var proc = this.sink.FindOrCreateProcedureForStructCopy(typ); e = ExpressionFor(initVal); StmtBuilder.Add(new Bpl.CallCmd(tok, proc.Name, new List <Bpl.Expr> { e, }, new List <Bpl.IdentifierExpr> { boogieLocalExpr, })); } } else { e = ExpressionFor(initVal); AddRecordCall(localDeclarationStatement.LocalVariable.Name.Value, initVal, e); StmtBuilder.Add(Bpl.Cmd.SimpleAssign(tok, boogieLocalExpr, e)); } return; }
private static void BplIfIf(Bpl.IToken tk, bool yes, Bpl.Expr guard, BoogieStmtListBuilder builder, Action <BoogieStmtListBuilder> k) { if (yes) { var newBuilder = new BoogieStmtListBuilder(builder.tran); k(newBuilder); builder.Add(new Bpl.IfCmd(tk, guard, newBuilder.Collect(tk), null, null)); } else { k(builder); } }
/// <summary> /// Returns the (typed) BPL expression that corresponds to the value of the field /// <paramref name="f"/> belonging to the object <paramref name="o"/> (which must be non-null). /// </summary> /// <param name="o">The expression that represents the object to be dereferenced. /// </param> /// <param name="f">The field that is used to dereference the object <paramref name="o"/>. /// </param> public override Bpl.Expr ReadHeap(Bpl.Expr /*?*/ o, Bpl.Expr f, AccessType accessType, Bpl.Type unboxType) { if (accessType == AccessType.Struct || accessType == AccessType.Heap) { Bpl.IdentifierExpr field = f as Bpl.IdentifierExpr; Debug.Assert(field != null); return(Bpl.Expr.Select(field, o)); } else { return(FromUnion(f.tok, unboxType, Bpl.Expr.Select(Bpl.Expr.Select(Bpl.Expr.Ident(ArrayContentsVariable), o), f), false)); } }
public static Bpl.AssumeCmd TrAssumeCmd(Bpl.IToken tok, Bpl.Expr expr, Bpl.QKeyValue attributes = null) { var litArgument = GetLit(expr); if (litArgument is Bpl.LiteralExpr literalExpr && literalExpr.asBool) { // In most cases, we leave any Lit brackets that "expr" may have. In the past, these brackets // had always been removed here. Alas, some brittle test cases stopped verifying if we // keep "assume Lit(true)" instead of simplifying it to "assume true". Therefore, as a // special case, we remove the Lit brackets from the literal "true". expr = litArgument; } return(attributes == null ? new Bpl.AssumeCmd(tok, expr) : new Bpl.AssumeCmd(tok, expr, attributes)); }
/// <summary> /// /// </summary> /// <remarks>(mschaef) Works, but still a stub</remarks> /// <param name="conditionalStatement"></param> public override void TraverseChildren(IConditionalStatement conditionalStatement) { StatementTraverser thenTraverser = this.factory.MakeStatementTraverser(this.sink, this.PdbReader, this.contractContext); StatementTraverser elseTraverser = this.factory.MakeStatementTraverser(this.sink, this.PdbReader, this.contractContext); ExpressionTraverser condTraverser = this.factory.MakeExpressionTraverser(this.sink, this, this.contractContext); if (this.sink.Options.instrumentBranches) { var tok = conditionalStatement.Token(); thenTraverser.StmtBuilder.Add( new Bpl.AssumeCmd(tok, Bpl.Expr.True, new Bpl.QKeyValue(Bpl.Token.NoToken, "breadcrumb", new List <object> { Bpl.Expr.Literal(this.sink.UniqueNumberAcrossAllAssemblies) }, null)) ); elseTraverser.StmtBuilder.Add( new Bpl.AssumeCmd(tok, Bpl.Expr.True, new Bpl.QKeyValue(Bpl.Token.NoToken, "breadcrumb", new List <object> { Bpl.Expr.Literal(this.sink.UniqueNumberAcrossAllAssemblies) }, null)) ); } condTraverser.Traverse(conditionalStatement.Condition); thenTraverser.Traverse(conditionalStatement.TrueBranch); elseTraverser.Traverse(conditionalStatement.FalseBranch); Bpl.Expr conditionExpr = condTraverser.TranslatedExpressions.Pop(); Bpl.Type conditionType = this.sink.CciTypeToBoogie(conditionalStatement.Condition.Type); if (conditionType == this.sink.Heap.RefType) { conditionExpr = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, conditionExpr, Bpl.Expr.Ident(this.sink.Heap.NullRef)); } else if (conditionType == Bpl.Type.Int) { conditionExpr = Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Neq, conditionExpr, Bpl.Expr.Literal(0)); } else { System.Diagnostics.Debug.Assert(conditionType == Bpl.Type.Bool); } Bpl.IfCmd ifcmd = new Bpl.IfCmd(conditionalStatement.Token(), conditionExpr, thenTraverser.StmtBuilder.Collect(conditionalStatement.TrueBranch.Token()), null, elseTraverser.StmtBuilder.Collect(conditionalStatement.FalseBranch.Token()) ); StmtBuilder.Add(ifcmd); }
private static void GenerateInAndOutExprs(Bpl.Expr e, List <Bpl.Variable> invars, List <Bpl.Variable> outvars, out List <Bpl.Expr> inExprs, out List <Bpl.IdentifierExpr> outExprs) { inExprs = new List <Bpl.Expr>(); inExprs.Add(e); for (int i = 1; i < invars.Count; i++) { Bpl.Variable f = invars[i]; inExprs.Add(Bpl.Expr.Ident(f)); } outExprs = new List <Bpl.IdentifierExpr>(); foreach (Bpl.Formal f in outvars) { outExprs.Add(Bpl.Expr.Ident(f)); } }
static Bpl.Expr BplForall(IEnumerable <Bpl.Variable> args_in, Bpl.Expr body) { Contract.Requires(args_in != null); Contract.Requires(body != null); Contract.Ensures(Contract.Result <Bpl.Expr>() != null); var args = new List <Bpl.Variable>(args_in); if (args.Count == 0) { return(body); } else { return(new Bpl.ForallExpr(body.tok, args, body)); // NO_TRIGGER } }
/// <summary> /// Returns the BPL command that corresponds to assigning the value <paramref name="value"/> /// to the field <paramref name="f"/> of the object <paramref name="o"/> (which should be non-null). /// </summary> public override void WriteHeap(Bpl.IToken tok, Bpl.Expr /*?*/ o, Bpl.Expr f, Bpl.Expr value, AccessType accessType, Bpl.Type boxType, Bpl.StmtListBuilder builder) { Debug.Assert(o != null); Bpl.Cmd cmd; if (accessType == AccessType.Struct || accessType == AccessType.Heap) { Bpl.IdentifierExpr field = f as Bpl.IdentifierExpr; Debug.Assert(field != null); cmd = Bpl.Cmd.MapAssign(tok, field, o, value); } else { cmd = TranslationHelper.BuildAssignCmd(Bpl.Expr.Ident(ArrayContentsVariable), Bpl.Expr.Store(Bpl.Expr.Ident(ArrayContentsVariable), o, Bpl.Expr.Store(Bpl.Expr.Select(Bpl.Expr.Ident(ArrayContentsVariable), o), f, ToUnion(f.tok, boxType, value, false, builder)))); } builder.Add(cmd); }
Bpl.Expr ArrayLength(Bpl.IToken tok, Bpl.Expr arr, int totalDims, int dim) { Contract.Requires(tok != null); Contract.Requires(arr != null); Contract.Requires(1 <= totalDims); Contract.Requires(0 <= dim && dim < totalDims); string name = "_System." + BuiltIns.ArrayClassName(totalDims) + ".Length"; if (totalDims != 1) { name += dim; } return(new Bpl.NAryExpr(tok, new Bpl.FunctionCall(new Bpl.IdentifierExpr(tok, name, Bpl.Type.Int)), new List <Bpl.Expr> { arr })); }
public bool isTidFunc(bpl.Expr expr) { if (!(expr is bpl.NAryExpr)) { return(false); } var naryExpr = expr as bpl.NAryExpr; if (naryExpr.Fun is bpl.FunctionCall && (naryExpr.Fun as bpl.FunctionCall).Func.Name == tidFunc) { return(true); } else { return(false); } }
private static Bpl.Expr GetLit(Bpl.Expr expr) { if (expr is Bpl.NAryExpr) { Bpl.NAryExpr app = (Bpl.NAryExpr)expr; switch (app.Fun.FunctionName) { case "LitInt": case "LitReal": case "Lit": return(app.Args[0]); default: break; } } return(null); }
public void GenerateDispatchContinuation(ITryCatchFinallyStatement tryCatchFinallyStatement) { string continuationLabel = this.sink.FindOrCreateContinuationLabel(tryCatchFinallyStatement); Bpl.IfCmd elseIfCmd = new Bpl.IfCmd(Bpl.Token.NoToken, Bpl.Expr.Literal(true), TranslationHelper.BuildStmtList(new Bpl.GotoCmd(Bpl.Token.NoToken, new List <string>(new string[] { continuationLabel }))), null, null); List <string> edges = sink.EscapingEdges(tryCatchFinallyStatement); Bpl.IdentifierExpr labelExpr = Bpl.Expr.Ident(this.sink.LabelVariable); for (int i = 0; i < edges.Count; i++) { string label = edges[i]; Bpl.GotoCmd gotoCmd = new Bpl.GotoCmd(Bpl.Token.NoToken, new List <string>(new string[] { label })); Bpl.Expr targetExpr = Bpl.Expr.Literal(i); elseIfCmd = new Bpl.IfCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, labelExpr, targetExpr), TranslationHelper.BuildStmtList(gotoCmd), elseIfCmd, null); } this.StmtBuilder.Add(elseIfCmd); }
Bpl.Expr BplIff(Bpl.Expr a, Bpl.Expr b) { Contract.Requires(a != null); Contract.Requires(b != null); Contract.Ensures(Contract.Result <Bpl.Expr>() != null); if (a == Bpl.Expr.True) { return(b); } else if (b == Bpl.Expr.True) { return(a); } else { return(Bpl.Expr.Iff(a, b)); } }
static Bpl.Expr BplImp(Bpl.Expr a, Bpl.Expr b) { Contract.Requires(a != null); Contract.Requires(b != null); Contract.Ensures(Contract.Result <Bpl.Expr>() != null); if (a == Bpl.Expr.True || b == Bpl.Expr.True) { return(b); } else if (a == Bpl.Expr.False) { return(Bpl.Expr.True); } else { return(Bpl.Expr.Imp(a, b)); } }
public override void TraverseChildren(IArrayIndexer arrayIndexer) { //if (!IsAtomicInstance(arrayIndexer.IndexedObject)) { // // Simplify the BE so that all nested dereferences and method calls are broken up into separate assignments to locals. // var se = ExpressionSimplifier.Simplify(this.sink, arrayIndexer); // this.Traverse(se); // return; //} this.Traverse(arrayIndexer.IndexedObject); Bpl.Expr arrayExpr = TranslatedExpressions.Pop(); var be = arrayIndexer.IndexedObject as IBoundExpression; if (be != null && be.Instance != null) { var l = this.sink.CreateFreshLocal(be.Type); var lhs = Bpl.Expr.Ident(l); var cmd = Bpl.Cmd.SimpleAssign(arrayIndexer.Token(), lhs, arrayExpr); this.StmtTraverser.StmtBuilder.Add(cmd); arrayExpr = lhs; } this.Traverse(arrayIndexer.Indices); int count = arrayIndexer.Indices.Count(); Bpl.Expr[] indexExprs = new Bpl.Expr[count]; for (int i = count; i > 0; i--) { indexExprs[i - 1] = TranslatedExpressions.Pop(); } Bpl.Expr indexExpr; if (indexExprs.Length == 1) { indexExpr = indexExprs[0]; } else { Bpl.Function f = this.sink.FindOrCreateNaryIntFunction(indexExprs.Length); indexExpr = new Bpl.NAryExpr(arrayIndexer.Token(), new Bpl.FunctionCall(f), new List<Bpl.Expr>(indexExprs)); } AssertOrAssumeNonNull(arrayIndexer.Token(), arrayExpr); this.TranslatedExpressions.Push(this.sink.Heap.ReadHeap(arrayExpr, indexExpr, AccessType.Array, this.sink.CciTypeToBoogie(arrayIndexer.Type))); }