private BoogieExpr dupAndReplaceExpr(BoogieExpr expr, bool isFail, bool inHarness) { List <BoogieExpr> dupAndReplaceExprList(List <BoogieExpr> exprs) { return(exprs.Select(e => dupAndReplaceExpr(e, isFail, inHarness)).ToList()); } if (expr is BoogieIdentifierExpr) { string idName = ((BoogieIdentifierExpr)expr).Name; if (isFail && shadowGlobals.ContainsKey(idName)) { return(new BoogieIdentifierExpr(shadowGlobals[idName].Name)); } return(expr); } if (expr is BoogieMapSelect) { BoogieMapSelect selectExpr = (BoogieMapSelect)expr; return(new BoogieMapSelect(dupAndReplaceExpr(selectExpr.BaseExpr, isFail, inHarness), dupAndReplaceExprList(selectExpr.Arguments))); } if (expr is BoogieMapUpdate) { BoogieMapUpdate updateExpr = (BoogieMapUpdate)expr; return(new BoogieMapUpdate(dupAndReplaceExpr(updateExpr.BaseExpr, isFail, inHarness), dupAndReplaceExprList(updateExpr.Arguments), dupAndReplaceExpr(updateExpr.Value, isFail, inHarness))); } if (expr is BoogieUnaryOperation) { BoogieUnaryOperation unaryOperation = (BoogieUnaryOperation)expr; return(new BoogieUnaryOperation(unaryOperation.Op, dupAndReplaceExpr(unaryOperation.Expr, isFail, inHarness))); } if (expr is BoogieBinaryOperation) { BoogieBinaryOperation binOperation = (BoogieBinaryOperation)expr; return(new BoogieBinaryOperation(binOperation.Op, dupAndReplaceExpr(binOperation.Lhs, isFail, inHarness), dupAndReplaceExpr(binOperation.Rhs, isFail, inHarness))); } if (expr is BoogieITE) { BoogieITE iteExpr = (BoogieITE)expr; return(new BoogieITE(dupAndReplaceExpr(iteExpr.Guard, isFail, inHarness), dupAndReplaceExpr(iteExpr.ThenExpr, isFail, inHarness), dupAndReplaceExpr(iteExpr.ElseExpr, isFail, inHarness))); } if (expr is BoogieQuantifiedExpr) { BoogieQuantifiedExpr quantifiedExpr = (BoogieQuantifiedExpr)expr; return(new BoogieQuantifiedExpr(quantifiedExpr.IsForall, quantifiedExpr.QVars, quantifiedExpr.QVarTypes, dupAndReplaceExpr(quantifiedExpr.BodyExpr, isFail, inHarness), quantifiedExpr.Trigger)); } if (expr is BoogieFuncCallExpr) { BoogieFuncCallExpr callExpr = (BoogieFuncCallExpr)expr; string calledFun = callExpr.Function; // TODO: handle this properly. // if (!isHarnessProcudure(calledFun) && procsWiltImplNames.Contains(calledFun)) // { // if (!inHarness || (!isConstructor(calledFun) && !isPublic(proceduresInProgram[calledFun]))) // calledFun = calledFun + (isFail ? "__fail" : "__success"); // } return(new BoogieFuncCallExpr(calledFun, dupAndReplaceExprList(callExpr.Arguments))); } if (expr is BoogieTupleExpr) { BoogieTupleExpr tupleExpr = (BoogieTupleExpr)expr; return(new BoogieTupleExpr(dupAndReplaceExprList(tupleExpr.Arguments))); } return(expr); }
private List <BoogieAxiom> GenerateVeriSolSumAxioms() { // axiom(forall m:[Ref]int :: (exists _a: Ref::m[_a] != 0) || _SumMapping_VeriSol(m) == 0); var qVar1 = QVarGenerator.NewQVar(0, 0); var qVar2 = QVarGenerator.NewQVar(0, 1); var ma = new BoogieMapSelect(qVar1, qVar2); var maEq0 = new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.NEQ, ma, new BoogieLiteralExpr(System.Numerics.BigInteger.Zero)); var existsMaNeq0 = new BoogieQuantifiedExpr(false, new List <BoogieIdentifierExpr>() { qVar2 }, new List <BoogieType>() { BoogieType.Ref }, maEq0, null); var sumM = new BoogieFuncCallExpr("_SumMapping_VeriSol", new List <BoogieExpr>() { qVar1 }); var sumMEq0 = new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.EQ, sumM, new BoogieLiteralExpr(System.Numerics.BigInteger.Zero)); var maEq0SumEq0 = new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.OR, existsMaNeq0, sumMEq0); var axiom1 = new BoogieQuantifiedExpr(true, new List <BoogieIdentifierExpr>() { qVar1 }, new List <BoogieType>() { new BoogieMapType(BoogieType.Ref, BoogieType.Int) }, maEq0SumEq0, null); // axiom(forall m:[Ref]int, _a: Ref, _b: int :: _SumMapping_VeriSol(m[_a:= _b]) == _SumMapping_VeriSol(m) - m[_a] + _b); var qVar3 = QVarGenerator.NewQVar(0, 2); var subExpr = new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.SUB, sumM, ma); var addExpr = new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.ADD, subExpr, qVar3); var updExpr = new BoogieMapUpdate(qVar1, qVar2, qVar3); var sumUpdExpr = new BoogieFuncCallExpr("_SumMapping_VeriSol", new List <BoogieExpr>() { updExpr }); var sumUpdEqExpr = new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.EQ, sumUpdExpr, addExpr); var axiom2 = new BoogieQuantifiedExpr(true, new List <BoogieIdentifierExpr>() { qVar1, qVar2, qVar3 }, new List <BoogieType>() { new BoogieMapType(BoogieType.Ref, BoogieType.Int), BoogieType.Ref, BoogieType.Int }, sumUpdEqExpr, null); return(new List <BoogieAxiom>() { new BoogieAxiom(axiom1), new BoogieAxiom(axiom2) }); }