Exemplo n.º 1
0
        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);
        }
Exemplo n.º 2
0
        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)
            });
        }