private BoogieAxiom GenerateAbiEncodePackedAxiomOneArgRef() { var qVar1 = QVarGenerator.NewQVar(0, 0); var qVar2 = QVarGenerator.NewQVar(0, 1); var eqVar12 = new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.EQ, qVar1, qVar2); var qVar1Func = new BoogieFuncCallExpr("abiEncodePacked1R", new List <BoogieExpr>() { qVar1 }); var qVar2Func = new BoogieFuncCallExpr("abiEncodePacked1R", new List <BoogieExpr>() { qVar2 }); var eqFunc12 = new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.NEQ, qVar1Func, qVar2Func); var bodyExpr = new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.OR, eqVar12, eqFunc12); var triggers = new List <BoogieExpr>() { qVar1Func, qVar2Func }; // forall q1:int, q2:int :: q1 == q2 || abiEncodePacked(q1) != abiEncodePacked(q2) var qExpr = new BoogieQuantifiedExpr(true, new List <BoogieIdentifierExpr>() { qVar1, qVar2 }, new List <BoogieType>() { BoogieType.Ref, BoogieType.Ref }, bodyExpr, triggers); return(new BoogieAxiom(qExpr)); }
private BoogieAxiom GenerateKeccakAxiom() { var qVar1 = QVarGenerator.NewQVar(0, 0); var qVar2 = QVarGenerator.NewQVar(0, 1); var eqVar12 = new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.EQ, qVar1, qVar2); var qVar1Func = new BoogieFuncCallExpr("keccak256", new List <BoogieExpr>() { qVar1 }); var qVar2Func = new BoogieFuncCallExpr("keccak256", new List <BoogieExpr>() { qVar2 }); var eqFunc12 = new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.NEQ, qVar1Func, qVar2Func); var bodyExpr = new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.OR, eqVar12, eqFunc12); var triggers = new List <BoogieExpr>() { qVar1Func, qVar2Func }; // forall q1:int, q2:int :: q1 == q2 || keccak256(q1) != keccak256(q2) var qExpr = new BoogieQuantifiedExpr(true, new List <BoogieIdentifierExpr>() { qVar1, qVar2 }, new List <BoogieType>() { BoogieType.Int, BoogieType.Int }, bodyExpr, triggers); return(new BoogieAxiom(qExpr)); }
private BoogieAxiom GenerateAbiEncodePackedAxiomTwoArgsOneRef() { var qVar11 = QVarGenerator.NewQVar(0, 0); var qVar12 = QVarGenerator.NewQVar(0, 1); var qVar21 = QVarGenerator.NewQVar(1, 0); var qVar22 = QVarGenerator.NewQVar(1, 1); var eqVar1 = new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.EQ, qVar11, qVar12); var eqVar2 = new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.EQ, qVar21, qVar22); var qVar1Func = new BoogieFuncCallExpr("abiEncodePacked2R", new List <BoogieExpr>() { qVar11, qVar21 }); var qVar2Func = new BoogieFuncCallExpr("abiEncodePacked2R", new List <BoogieExpr>() { qVar12, qVar22 }); var triggers = new List <BoogieExpr>() { qVar1Func, qVar2Func }; var eqFunc12 = new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.NEQ, qVar1Func, qVar2Func); var eqArgs = new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.AND, eqVar1, eqVar2); var bodyExpr = new BoogieBinaryOperation(BoogieBinaryOperation.Opcode.OR, eqArgs, eqFunc12); // forall q1:int, q2:int, q1', q2' :: (q1 == q1' && q2 == q2') || abiEncodePacked(q1, q2) != abiEncodePacked(q1', q2') var qExpr = new BoogieQuantifiedExpr(true, new List <BoogieIdentifierExpr>() { qVar11, qVar12, qVar21, qVar22 }, new List <BoogieType>() { BoogieType.Ref, BoogieType.Ref, BoogieType.Int, BoogieType.Int }, bodyExpr, triggers); return(new BoogieAxiom(qExpr)); }
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) }); }