示例#1
0
        public HoudiniVC(StratifiedInliningInfo siInfo, HashSet <string> procCalls, HashSet <string> currentAssignment)
            : base(siInfo, procCalls)
        {
            var gen = siInfo.vcgen.prover.VCExprGen;
            // Remove CandiateFunc
            var fsp = new FindSummaryPred(gen);

            vcexpr = fsp.Apply(vcexpr);
            this.constantToAssumedExpr  = fsp.constantToAssumedExpr;
            this.constantToAssertedExpr = fsp.constantToAssertedExpr;


            if (!HoudiniInlining.DualHoudini)
            {
                // Assume current summaries of callees
                foreach (var tup in constantToAssumedExpr)
                {
                    if (!currentAssignment.Contains(tup.Item1))
                    {
                        continue;
                    }
                    vcexpr = gen.And(vcexpr, gen.Implies(tup.Item2, tup.Item3));
                }
            }
            else
            {
                // Assert current post
                foreach (var tup in constantToAssertedExpr)
                {
                    if (!currentAssignment.Contains(tup.Key))
                    {
                        continue;
                    }
                    vcexpr = gen.And(vcexpr, gen.Not(tup.Value));
                }
            }
        }
示例#2
0
 public void GetTransformer(StratifiedInliningInfo info)
 {
     Term vcTerm = boogieContext.VCExprToTerm(info.vcexpr, linOptions);
     Term[] paramTerms = info.interfaceExprVars.Select(x => boogieContext.VCExprToTerm(x, linOptions)).ToArray();
     var relParams = new List<FuncDecl>();
     var nodeParams = new List<RPFP.Node>();
     var memo = new TermDict< Term>();
     var done = new Dictionary<Term,Term>(); // note this hashes on equality, not reference!
     vcTerm = CollectParamsRec(memo, vcTerm, relParams, nodeParams,done);
     // var ops = new Util.ContextOps(ctx);
     // var foo = ops.simplify_lhs(vcTerm);
     // vcTerm = foo.Item1;
     info.F = rpfp.CreateTransformer(relParams.ToArray(), paramTerms, vcTerm);
     info.edge = rpfp.CreateEdge(info.node, info.F, nodeParams.ToArray());
     rpfp.edges.Add(info.edge);
     // TODO labels[info.edge.number] = foo.Item2;
 }
示例#3
0
 private bool EvalToFalse(RPFP rpfp, RPFP.Node root, Term expr,StratifiedInliningInfo info)
 {
     Term res = rpfp.Eval(root.Outgoing,expr);
     return res.Equals(ctx.MkTrue());
 }
示例#4
0
        public bool CodeLabelTrue(RPFP rpfp, RPFP.Node root, Absy code, StratifiedInliningInfo info, string prefix)
        {
            string label = CodeLabel(code, info, prefix);

            if (label == null)
                throw new LabelNotFound();
            return root.Outgoing.labels.Contains(label);
        }
示例#5
0
        public void GenerateVCsForStratifiedInlining()
        {
            Contract.Requires(program != null);
            foreach (Declaration decl in program.TopLevelDeclarations)
            {
                Contract.Assert(decl != null);
                Implementation impl = decl as Implementation;
                if (impl == null)
                    continue;
                Contract.Assert(!impl.Name.StartsWith(recordProcName), "Not allowed to have an implementation for this guy");

                Procedure proc = cce.NonNull(impl.Proc);

                {
                    StratifiedInliningInfo info = new StratifiedInliningInfo(impl, program, boogieContext, QuantifierExpr.GetNextSkolemId());
                    implName2StratifiedInliningInfo[impl.Name] = info;
                    // We don't need controlFlowVariable for stratified Inlining
                    //impl.LocVars.Add(info.controlFlowVariable);
                    List<Expr> exprs = new List<Expr>();

                    if (mode != Mode.Boogie && QKeyValue.FindBoolAttribute(impl.Attributes, "entrypoint"))
                    {
                        proc.Ensures.Add(new Ensures(Token.NoToken, true, Microsoft.Boogie.Expr.False, "", null));
                        info.assertExpr = Microsoft.Boogie.Expr.False;
                        // info.isMain = true;
                    }
                    else if (mode == Mode.Corral || proc.FindExprAttribute("inline") != null || proc is LoopProcedure)
                    {
                        foreach (Variable v in program.GlobalVariables())
                        {
                            Contract.Assert(v != null);
                            exprs.Add(new OldExpr(Token.NoToken, new IdentifierExpr(Token.NoToken, v)));
                        }
                        foreach (Variable v in proc.InParams)
                        {
                            Contract.Assert(v != null);
                            exprs.Add(new IdentifierExpr(Token.NoToken, v));
                        }
                        foreach (Variable v in proc.OutParams)
                        {
                            Contract.Assert(v != null);
                            exprs.Add(new IdentifierExpr(Token.NoToken, v));
                        }
                        foreach (IdentifierExpr ie in proc.Modifies)
                        {
                            Contract.Assert(ie != null);
                            if (ie.Decl == null)
                                continue;
                            exprs.Add(ie);
                        }
                        Expr freePostExpr = new NAryExpr(Token.NoToken, new FunctionCall(info.function), exprs);
            #if true
                        if(mode == Mode.Corral || mode == Mode.OldCorral)
                            proc.Ensures.Add(new Ensures(Token.NoToken, true, freePostExpr, "", new QKeyValue(Token.NoToken, "si_fcall", new List<object>(), null)));
            #endif
                    }
                    else // not marked "inline" must be main
                    {
                        Expr freePostExpr = new NAryExpr(Token.NoToken, new FunctionCall(info.function), exprs);
                        info.isMain = true;
                    }
                }
            }

            if (mode == Mode.Boogie) return;

            foreach (var decl in program.TopLevelDeclarations)
            {
                var proc = decl as Procedure;
                if (proc == null) continue;
                if (!proc.Name.StartsWith(recordProcName)) continue;
                Contract.Assert(proc.InParams.Count == 1);

                // Make a new function
                TypedIdent ti = new TypedIdent(Token.NoToken, "", Microsoft.Boogie.Type.Bool);
                Contract.Assert(ti != null);
                Formal returnVar = new Formal(Token.NoToken, ti, false);
                Contract.Assert(returnVar != null);

                // Get record type
                var argtype = proc.InParams[0].TypedIdent.Type;

                var ins = new List<Variable>();
                ins.Add(new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "x", argtype), true));

                var recordFunc = new Function(Token.NoToken, proc.Name, ins, returnVar);
                boogieContext.DeclareFunction(recordFunc, "");

                var exprs = new List<Expr>();
                exprs.Add(new IdentifierExpr(Token.NoToken, proc.InParams[0]));

                Expr freePostExpr = new NAryExpr(Token.NoToken, new FunctionCall(recordFunc), exprs);
                proc.Ensures.Add(new Ensures(true, freePostExpr));
            }
        }
示例#6
0
        public Term CodeLabeledExpr(RPFP rpfp, RPFP.Node root, Absy code, StratifiedInliningInfo info, string prefix)
        {
            string label = CodeLabel(code, info, prefix);

            if (label != null)
            {
                var res = labels[label];
                return res;
            }
            else return null;
        }
示例#7
0
 public bool CodeLabelFalse(RPFP rpfp, RPFP.Node root, Absy code, StratifiedInliningInfo info, string prefix)
 {
     return CodeLabelTrue(rpfp, root, code, info, prefix);
 }
示例#8
0
 public string CodeLabel(Absy code, StratifiedInliningInfo info, string prefix)
 {
     if (info.label2absyInv == null)
     {
         info.label2absyInv = new Dictionary<Absy, string>();
         foreach (int foo in info.label2absy.Keys)
         {
             Absy bar = info.label2absy[foo] as Absy;
             string lbl = foo.ToString();
             info.label2absyInv.Add(bar, lbl);
         }
     }
     if (info.label2absyInv.ContainsKey(code))
     {
         string label = info.label2absyInv[code];
         return prefix+label;
     }
     return null;
 }
示例#9
0
 public StateId(RPFP.Edge e, int c, StratifiedInliningInfo i)
 {
     edge = e;
     capturePoint = c;
     info = i;
 }
示例#10
0
        private void GetModelWithStates(Model m, RPFP.Node cex, StratifiedInliningInfo mainInfo,
            List<StateId> orderedStateIds,
            Dictionary<int,Dictionary<string,string>> varSubst)
        {
            if (m == null) return;
            var mvInfo = mainInfo.mvInfo;

            foreach (Variable v in mvInfo.AllVariables)
            {
                m.InitialState.AddBinding(v.Name, GetModelValue(m, v, varSubst[cex.Outgoing.number]));
            }

            Dictionary<int, RPFP.Edge> edgeNumbering = new Dictionary<int,RPFP.Edge>();
            NumberCexEdges(cex, edgeNumbering);

            int lastCandidate = 0;
            int lastCapturePoint = CALL;
            for (int i = 0; i < orderedStateIds.Count; ++i)
            {
                var s = orderedStateIds[i];
                RPFP.Edge edge = s.edge;
                int candidate = edge.number;
                int capturePoint = s.capturePoint;
                Dictionary<string, string> subst = varSubst[candidate];

                string implName = edge.Parent.Name.GetDeclName();
                var info = s.info.mvInfo;

                if (capturePoint == CALL || capturePoint == RETURN)
                {
                    lastCandidate = candidate;
                    lastCapturePoint = capturePoint;
                    continue;
                }

                Contract.Assume(0 <= capturePoint && capturePoint < info.CapturePoints.Count);
                VC.ModelViewInfo.Mapping map = info.CapturePoints[capturePoint];
                var prevInc = (lastCapturePoint != CALL && lastCapturePoint != RETURN && candidate == lastCandidate)
                  ? info.CapturePoints[lastCapturePoint].IncarnationMap : new Dictionary<Variable, Expr>();
                var cs = m.MkState(map.Description);

                foreach (Variable v in info.AllVariables)
                {
                    var e = (Expr)map.IncarnationMap[v];

                    if (e == null)
                    {
                        if (lastCapturePoint == CALL || lastCapturePoint == RETURN)
                        {
                            cs.AddBinding(v.Name, GetModelValue(m, v, subst));
                        }
                        continue;
                    }

                    if (lastCapturePoint != CALL && lastCapturePoint != RETURN && prevInc[v] == e) continue; // skip unchanged variables

                    Model.Element elt;
                    if (e is IdentifierExpr)
                    {
                        IdentifierExpr ide = (IdentifierExpr)e;
                        elt = GetModelValue(m, ide.Decl, subst);
                    }
                    else if (e is LiteralExpr)
                    {
                        LiteralExpr lit = (LiteralExpr)e;
                        elt = m.MkElement(lit.Val.ToString());
                    }
                    else
                    {
                        Contract.Assume(false);
                        elt = m.MkFunc(e.ToString(), 0).GetConstant();
                    }
                    cs.AddBinding(v.Name, elt);
                }

                lastCandidate = candidate;
                lastCapturePoint = capturePoint;
            }

            return;
        }
示例#11
0
        private void GenerateVCForStratifiedInlining(Program program, StratifiedInliningInfo info, Checker checker)
        {
            Contract.Requires(program != null);
            Contract.Requires(info != null);
            Contract.Requires(checker != null);
            Contract.Requires(info.impl != null);
            Contract.Requires(info.impl.Proc != null);

            Implementation impl = info.impl;
            if (mode == Mode.Boogie && style == AnnotationStyle.Flat && impl.Name != main_proc_name)
                return;
            Contract.Assert(impl != null);
            ConvertCFG2DAG(impl,edgesCut);
            VC.ModelViewInfo mvInfo;
            PassifyImpl(impl, out mvInfo);
            Dictionary<int, Absy> label2absy = null;
            VCExpressionGenerator gen = checker.VCExprGen;
            Contract.Assert(gen != null);
            VCExpr vcexpr;
            if(NoLabels){
                // int assertionCount = 0;
                VCExpr startCorrect = null; /* VC.VCGen.LetVC(cce.NonNull(impl.Blocks[0]), null, null, info.blockVariables, info.bindings,
                    info.ctxt, out assertionCount); */
                vcexpr = gen.Let(info.bindings, startCorrect);
            }
            else vcexpr = GenerateVC(impl, null /* info.controlFlowVariable */, out label2absy, info.ctxt);
            if(mode != Mode.Boogie)
                vcexpr = gen.Not(vcexpr);
            Contract.Assert(vcexpr != null);
            info.label2absy = label2absy;
            info.mvInfo = mvInfo;
            List<VCExpr> interfaceExprs = new List<VCExpr>();

            if (true /* was:  !info.isMain */)
            {
                Boogie2VCExprTranslator translator = checker.TheoremProver.Context.BoogieExprTranslator;
                Contract.Assert(translator != null);
                info.privateVars = new List<VCExprVar>();
                foreach (Variable v in impl.LocVars)
                {
                    Contract.Assert(v != null);
                    info.privateVars.Add(translator.LookupVariable(v));
                }
                foreach (Variable v in impl.OutParams)
                {
                    Contract.Assert(v != null);
                    info.privateVars.Add(translator.LookupVariable(v));
                }

                info.interfaceExprVars = new List<VCExprVar>();

                foreach (Variable v in info.interfaceVars)
                {
                    Contract.Assert(v != null);
                    VCExprVar ev = translator.LookupVariable(v);
                    Contract.Assert(ev != null);
                    info.interfaceExprVars.Add(ev);
                    interfaceExprs.Add(ev);
                }
            }

            Function function = cce.NonNull(info.function);
            Contract.Assert(function != null);
            info.funcExpr = gen.Function(function, interfaceExprs);
            info.vcexpr = vcexpr;

            if (mode == Mode.Boogie)
            {
                Term z3vc = boogieContext.VCExprToTerm(vcexpr, linOptions);
                FactorVCs(z3vc, DualityVCs);
            }
            else
            {
                // Index the procedures by relational variable
                FuncDecl R = boogieContext.VCExprToTerm(info.funcExpr, linOptions).GetAppDecl();
                relationToProc.Add(R, info);
                info.node = rpfp.CreateNode(boogieContext.VCExprToTerm(info.funcExpr, linOptions));
                rpfp.nodes.Add(info.node);
                if (info.isMain || QKeyValue.FindBoolAttribute(impl.Attributes, "entrypoint"))
                    info.node.Bound.Formula = ctx.MkFalse();
            }
        }
示例#12
0
        private Counterexample GenerateTraceRec(
            RPFP rpfp, RPFP.Node root,
            List<StateId> orderedStateIds,
            Block/*!*/ b, List<Block>/*!*/ trace,
            Dictionary<TraceLocation/*!*/, CalleeCounterexampleInfo/*!*/>/*!*/ calleeCounterexamples,
            StratifiedInliningInfo info,
            bool toplevel)
        {
            Contract.Requires(b != null);
            Contract.Requires(trace != null);
            Contract.Requires(cce.NonNullDictionaryAndValues(calleeCounterexamples));

            Stack<RPFP.Node> continuation_stack = new Stack<RPFP.Node>();

            // If our block is not present, try diving into precondition
            // and push a continuation.
            // TODO: is the precondition always the first child?
            while (!CodeLabelFalse(rpfp, root, b, info, "+"))
            {
                if (root.Outgoing != null && root.Outgoing.Children.Length > 0)
                {
                    continuation_stack.Push(root);
                    root = root.Outgoing.Children[0];
                }
                else
                {
                    // can't find our block
                    Contract.Assert(false);
                    return null;
                }
            }

            // After translation, all potential errors come from asserts.
            while (true)
            {

                List<Cmd> cmds = b.Cmds;
                TransferCmd transferCmd = cce.NonNull(b.TransferCmd);
                for (int i = 0; i < cmds.Count; i++)
                {
                    Cmd cmd = cce.NonNull(cmds[i]);

                    // Skip if 'cmd' not contained in the trace or not an assert
                    if (cmd is AssertCmd)
                    {
                        bool is_failed_assertion = false;
                        if (NoLabels)
                            is_failed_assertion = true; // we assume only assertions on
                        else
                            is_failed_assertion = CodeLabelTrue(rpfp, root, cmd, info, "@");

                        if (is_failed_assertion)
                        {
                            if (continuation_stack.Count == 0)
                            {
                                Counterexample newCounterexample =
                                    AssertCmdToCounterexample((AssertCmd)cmd, transferCmd, trace, new Microsoft.Boogie.Model(), info.mvInfo,
                                    boogieContext);
                                newCounterexample.AddCalleeCounterexample(calleeCounterexamples);
                                return newCounterexample;
                            }
                            root = continuation_stack.Pop();
                        }
                        continue;
                    }

                    // Counterexample generation for inlined procedures
                    AssumeCmd assumeCmd = cmd as AssumeCmd;
                    if (assumeCmd == null)
                        continue;
                    NAryExpr naryExpr = assumeCmd.Expr as NAryExpr;
                    if (naryExpr == null)
                        continue;
                    string calleeName = naryExpr.Fun.FunctionName;
                    Contract.Assert(calleeName != null);

                    // what is this crap???
                    BinaryOperator binOp = naryExpr.Fun as BinaryOperator;
                    if (binOp != null && binOp.Op == BinaryOperator.Opcode.And)
                    {
                        Expr expr = naryExpr.Args[0];
                        NAryExpr mvStateExpr = expr as NAryExpr;
                        if (mvStateExpr != null && mvStateExpr.Fun.FunctionName == VC.ModelViewInfo.MVState_FunctionDef.Name)
                        {
                            LiteralExpr x = mvStateExpr.Args[1] as LiteralExpr;
                            // Debug.Assert(x != null);
                            int foo = x.asBigNum.ToInt;
                            orderedStateIds.Add(new StateId(root.Outgoing,foo,info));
                        }
                    }

                    if (calleeName.EndsWith("_summary"))
                        calleeName = calleeName.Substring(0, calleeName.Length - 8);

                    if (!implName2StratifiedInliningInfo.ContainsKey(calleeName) && !calleeName.EndsWith("_summary"))
                        continue;

                    {
                        Term code = CodeLabeledExpr(rpfp, root, cmd, info, "+si_fcall_");
                        int pos = TransformerArgPosition(rpfp, root, code);
                        if (pos >= 0)
                        {
                            RPFP.Node callee = root.Outgoing.Children[pos];
                            orderedStateIds.Add(new StateId(callee.Outgoing, CALL,info));
                            calleeCounterexamples[new TraceLocation(trace.Count - 1, i)] =
                                new CalleeCounterexampleInfo(
                                    cce.NonNull(GenerateTrace(rpfp, callee, orderedStateIds,
                                                implName2StratifiedInliningInfo[calleeName].impl, false)),
                                    new List<object>());
                            orderedStateIds.Add(new StateId(root.Outgoing, RETURN,info));
                        }
                    }
                }

                GotoCmd gotoCmd = transferCmd as GotoCmd;
                List<Block> cuts = null;
                if (edgesCut.ContainsKey(b))
                    cuts = edgesCut[b];
                b = null;

                if (gotoCmd != null)
                {

                    foreach (Block bb in cce.NonNull(gotoCmd.labelTargets))
                    {
                        Contract.Assert(bb != null);
                        if (CodeLabelFalse(rpfp, root, bb, info, "+"))
                        {
                            trace.Add(bb);
                            b = bb;
                            break;
                        }
                    }
                    if (b != null) continue;
                }
                // HACK: we have to try edges that were cut in generating the VC

                if (cuts != null)
                    foreach (var bb in cuts)
                    {
                        if (CodeLabelFalse(rpfp, root, bb, info, "+"))
                        {
                            trace.Add(bb);
                            b = bb;
                            break;
                        }
                    }
                if (b != null) continue;

                return null;
            }
        }
示例#13
0
        private void EmitProcSpec(TokenTextWriter twr, Procedure proc, StratifiedInliningInfo info, RPFP.Transformer annot)
        {
            // last ensures clause will be the symbolic one
            if (!info.isMain)
            {
                var ens = proc.Ensures[proc.Ensures.Count - 1];
                if (ens.Condition != Expr.False) // this is main
                {
                    var postExpr = ens.Condition as NAryExpr;
                    var args = postExpr.Args;

                    var ind = annot.IndParams;
                    var bound = new Dictionary<VCExpr, Expr>();
                    for (int i = 0; i < args.Count; i++)
                    {
                        bound[ind[i]] = args[i];
                    }
                    var new_ens_cond = VCExprToExpr(annot.Formula, bound);
                    if (new_ens_cond != Expr.True)
                    {
                        var new_ens = new Ensures(false, new_ens_cond);
                        var enslist = new List<Ensures>();
                        enslist.Add(new_ens);
                        var new_proc = new Procedure(proc.tok, proc.Name, proc.TypeParameters, proc.InParams,
                                                     proc.OutParams, new List<Requires>(), new List<IdentifierExpr>(), enslist);
                        new_proc.Emit(twr, 0);
                    }
                }
            }
        }
示例#14
0
		private void FixedPointToSpecs(){
			
			if(mode != Mode.Corral || CommandLineOptions.Clo.PrintFixedPoint == null)
				return; // not implemented for other annotation modes yet
			
            var twr = new TokenTextWriter(CommandLineOptions.Clo.PrintFixedPoint, /*pretty=*/ false);
			Dictionary<string, RPFP.Node> pmap = new Dictionary<string,RPFP.Node> ();

			foreach (var node in rpfp.nodes)
				pmap.Add ((node.Name as VCExprBoogieFunctionOp).Func.Name, node);
			
			foreach (var impl in program.Implementations)
            {
                Contract.Assert(!impl.Name.StartsWith(recordProcName), "Not allowed to have an implementation for this guy");

                Procedure proc = cce.NonNull(impl.Proc);

                {
                    StratifiedInliningInfo info = new StratifiedInliningInfo(impl, program, boogieContext, QuantifierExpr.GetNextSkolemId());
                    implName2StratifiedInliningInfo[impl.Name] = info;
                    // We don't need controlFlowVariable for stratified Inlining
                    //impl.LocVars.Add(info.controlFlowVariable);
                    List<Expr> exprs = new List<Expr>();

                    {
                        if (pmap.ContainsKey(impl.Name))
                        {
                            RPFP.Node node = pmap[impl.Name];
                            var annot = node.Annotation;
                            EmitProcSpec(twr, proc, info, annot);
                        }
                    }
                }
            }
			twr.Close ();
		}