Пример #1
0
 public ConjunctionDomain(string baseDomain, Template left, Template right, ref Z3Context z3Context, string str, int constantRange)
 {
     this.str = str;
     args = new List<ICEDomain>();
     args.Add(ICEDomainFactory.GetInstance(baseDomain, left, ref z3Context, str + "_1", constantRange));
     args.Add(ICEDomainFactory.GetInstance(baseDomain, right, ref z3Context, str + "_2", constantRange));
 }
Пример #2
0
        string str; // is "b1" for functionname == "b1"

        #endregion Fields

        #region Constructors

        public ConjunctionDomain(string baseDomain, int numConjuncts, ref Z3Context z3Context, string str, int constantRange)
        {
            Debug.Assert(numConjuncts > 0);
            args = new List<ICEDomain>();
            this.str = str;
            for (int i = 0; i < numConjuncts; i++)
            {
                if (baseDomain == "Intervals")
                {
                    this.args.Add(new ICEIntervals(ref z3Context, this.str + "_" + i.ToString(), constantRange) as ICEDomain);
                }
                else if (baseDomain == "Octagons")
                {
                    this.args.Add(new ICEOctagons(ref z3Context, this.str + "_" + i.ToString(), constantRange) as ICEDomain);
                }
                else throw new ICEHoudiniInternalError("Domain not found");
            }
        }
Пример #3
0
 public Term constructSMTConstraint(List<Model.Element> states, ref Z3Context z3Context)
 {
     //Debug.Assert(states.Count == 1);
     List<Term> terms = new List<Term>();
     for (int i = 0; i < this.args.Count; i++)
     {
         terms.Add(this.args.ElementAt(i).constructSMTConstraint(states, ref z3Context));
     }
     return z3Context.context.MkAnd(terms.ToArray());
 }
Пример #4
0
        public static ICEDomain GetInstance(string domainName, ref Z3Context z3Context, string str, int constantRange)
        {
            if (domainName == "Intervals")
            {
                return new ICEIntervals(ref z3Context, str, constantRange) as ICEDomain;
            }
            else if (domainName == "Octagons")
            {
                return new ICEOctagons(ref z3Context, str, constantRange) as ICEDomain;
            }

            int pos = domainName.IndexOf("(");
            if (pos <= 0)
            {
                Console.WriteLine("Domain {0} not found", domainName);
                Console.WriteLine("Supported domains are:");
                Console.WriteLine("  {Intervals}");
                throw new ICEHoudiniInternalError("Domain not found");
            }
            else{
                string baseDomain = domainName.Substring(0, pos);
                string templateString = domainName.Substring(pos);
                TemplateParser.initialize(templateString);
                Template t = TemplateParser.Parse();
                return GetInstance(baseDomain, t, ref z3Context, str, constantRange);
            }
        }
Пример #5
0
        public static ICEDomain GetInstance(string baseDomain, Template t, ref Z3Context z3Context, string str, int constantRange)
        {
            if (t.op == TemplateOperator.None)
            {
                if (t.value == 1)
                {
                    if (baseDomain == "Intervals")
                    {
                        return new ICEIntervals(ref z3Context, str, constantRange);
                    }
                    else if (baseDomain == "Octagons")
                    {
                        return new ICEOctagons(ref z3Context, str, constantRange);
                    }
                    else throw new ICEHoudiniInternalError("Domain not found");
                }
                else
                {
                    return new ConjunctionDomain(baseDomain, t.value, ref z3Context, str, constantRange);
                }
            }

            if (t.op == TemplateOperator.ConjunctionOp)
            {
                return new ConjunctionDomain(baseDomain, t.left, t.right, ref z3Context, str, constantRange);
            }

            Debug.Assert(t.op == TemplateOperator.DisjunctionOp);
            return new DisjunctionDomain(baseDomain, t.left, t.right, ref z3Context, str, constantRange);
        }
Пример #6
0
        public Term constructSMTConstraint(List<Model.Element> states, ref Z3Context z3Context)
        {
            Context context = z3Context.context;
            Term termHasFirst = context.MkConst(this.str + "_hf", z3Context.boolSort);
            Term termHasSecond = context.MkConst(this.str + "_hs", z3Context.boolSort);
            Term termSign1 = context.MkConst(this.str + "_s1", z3Context.boolSort);
            Term termSign2 = context.MkConst(this.str + "_s2", z3Context.boolSort);
            Term termVar1 = context.MkConst(this.str + "_v1", z3Context.intSort);
            Term termVar2 = context.MkConst(this.str + "_v2", z3Context.intSort);
            Term termOp = context.MkConst(this.str + "_op", z3Context.boolSort);
            Term termConstant = context.MkConst(this.str + "_c", z3Context.intSort);

            if(!this.numVarsInitialized)
            {
                this.numVars = states.Count;
                this.numVarsInitialized = true;
                // assert 0 <= var1, var2 <= numVars-1
                context.AssertCnstr(context.MkLe(context.MkNumeral(0, z3Context.intSort), termVar1));
                context.AssertCnstr(context.MkLe(termVar1, context.MkNumeral(this.numVars-1, z3Context.intSort)));
                context.AssertCnstr(context.MkLe(context.MkNumeral(0, z3Context.intSort), termVar2));
                context.AssertCnstr(context.MkLe(termVar2, context.MkNumeral(this.numVars-1, z3Context.intSort)));

                if(this.numVars > 1)
                {
                    context.AssertCnstr(context.MkNot(context.MkEq(termVar1, termVar2)));
                }
                else
                {
                    Debug.Assert(this.numVars == 1);
                    context.AssertCnstr(context.MkNot(termHasSecond));
                }
            }
            else
            {
                Debug.Assert(states.Count == this.numVars);
            }

            Term firstVal = context.MkNumeral(0, z3Context.intSort);
            for(int i = this.numVars-1; i >= 0; i--)
            {
                var state = states[i] as Model.Integer;
                if (state == null)
                    throw new ICEHoudiniInternalError("Incorrect type, expected int");
                var intval = state.AsInt();

                firstVal = context.MkIte(context.MkEq(termVar1, context.MkNumeral(i, z3Context.intSort)), context.MkNumeral(intval, z3Context.intSort), firstVal);
            }
            firstVal = context.MkIte(termSign1, firstVal, context.MkUnaryMinus(firstVal));
            firstVal = context.MkIte(termHasFirst, firstVal, context.MkNumeral(0, z3Context.intSort));

            Term secondVal = context.MkNumeral(0, z3Context.intSort);
            if(this.numVars > 1) {
                for(int i = this.numVars-1; i >= 0; i--)
                {
                    var state = states[i] as Model.Integer;
                    if (state == null)
                        throw new ICEHoudiniInternalError("Incorrect type, expected int");
                    var intval = state.AsInt();

                    secondVal = context.MkIte(context.MkEq(termVar2, context.MkNumeral(i, z3Context.intSort)), context.MkNumeral(intval, z3Context.intSort), secondVal);
                }
                secondVal = context.MkIte(termSign2, secondVal, context.MkUnaryMinus(secondVal));
                secondVal = context.MkIte(termHasSecond, secondVal, context.MkNumeral(0, z3Context.intSort));
            }
            // else hasSecond = false and secondVal = 0 in this case already

            Term lhs = context.MkAdd(firstVal, secondVal);
            return context.MkIte(termOp, context.MkEq(lhs, termConstant), context.MkLe(lhs, termConstant));
        }
Пример #7
0
        public bool initializeFromModel(Z3.Model model, ref Z3Context z3Context)
        {
            Debug.Assert(model != null);
            Context context = z3Context.context;
            Term termHasFirst = context.MkConst(this.str + "_hf", z3Context.boolSort);
            Term termHasSecond = context.MkConst(this.str + "_hs", z3Context.boolSort);
            Term termSign1 = context.MkConst(this.str + "_s1", z3Context.boolSort);
            Term termSign2 = context.MkConst(this.str + "_s2", z3Context.boolSort);
            Term termVar1 = context.MkConst(this.str + "_v1", z3Context.intSort);
            Term termVar2 = context.MkConst(this.str + "_v2", z3Context.intSort);
            Term termOp = context.MkConst(this.str + "_op", z3Context.boolSort);
            Term termConstant = context.MkConst(this.str + "_c", z3Context.intSort);

            bool ret = false;

            bool hf = context.GetBoolValue(model.Eval(termHasFirst)).getBool();
            bool hs = context.GetBoolValue(model.Eval(termHasSecond)).getBool();
            bool s1 = context.GetBoolValue(model.Eval(termSign1)).getBool();
            bool s2 = context.GetBoolValue(model.Eval(termSign2)).getBool();
            int v1 = context.GetNumeralInt(model.Eval(termVar1));
            int v2 = context.GetNumeralInt(model.Eval(termVar2));
            bool op = context.GetBoolValue(model.Eval(termOp)).getBool();
            int c = context.GetNumeralInt(model.Eval(termConstant));

            if (this.hasFirst != hf)
            {
                ret = true;
                goto init;
            }
            if (!this.hasFirst && !hf)
            {
                bool oldVal = this.op ? 0 == this.constant : 0 <= this.constant;
                bool newVal = op ? 0 == c : 0 <= c;
                if (oldVal != newVal)
                {
                    ret = true;
                }
                goto init;
            }
            // hf && this.hasFirst
            if (this.sign1 != s1 || this.var1 != v1)
            {
                ret = true;
                goto init;
            }
            if (this.hasSecond != hs)
            {
                ret = true;
                goto init;
            }
            if (this.hasSecond && hs)
            {
                if (this.sign2 != s2 || this.var2 != v2)
                {
                    ret = true;
                    goto init;
                }
            }
            if (this.op != op || this.constant != c)
            {
                ret = true;
                goto init;
            }

            init:
            this.hasFirst = hf;
            this.hasSecond = hs;
            this.sign1 = s1;
            this.sign2 = s2;
            this.var1 = v1;
            this.var2 = v2;
            this.op = op;
            this.constant = c;

            return ret;
        }
Пример #8
0
        public bool initializeFromModel(Z3.Model model, ref Z3Context z3Context)
        {
            Debug.Assert(model != null);
            Context context = z3Context.context;

            Term termUpperLimit = context.MkConst(this.str + "_ul", z3Context.intSort);
            Term termLowerLimit = context.MkConst(this.str + "_ll", z3Context.intSort);
            Term termHasUpperLimit = context.MkConst(this.str + "_hul", z3Context.boolSort);
            Term termHasLowerLimit = context.MkConst(this.str + "_hll", z3Context.boolSort);

            bool ret = false;

            int ul = context.GetNumeralInt(model.Eval(termUpperLimit));
            int ll = context.GetNumeralInt(model.Eval(termLowerLimit));
            bool hul = context.GetBoolValue(model.Eval(termHasUpperLimit)).getBool();
            bool hll = context.GetBoolValue(model.Eval(termHasLowerLimit)).getBool();

            if((hasUpperLimit != hul) || (hasUpperLimit && hul && (upperLimit != ul)))
                ret = true;

            if ((hasLowerLimit != hll) || (hasLowerLimit && hll && (lowerLimit != ll)))
                ret = true;

            upperLimit = ul;
            lowerLimit = ll;
            hasUpperLimit = hul;
            hasLowerLimit = hll;
            return ret;
        }
Пример #9
0
        public ICEOctagons(ref Z3Context z3Context, string str, int constantRange)
        {
            // Initialize the invariant function with "true".
            this.hasFirst = false;
            this.hasSecond = false;
            this.sign1 = false;
            this.sign2 = false;
            this.var1 = 0;
            this.var2 = 0;
            this.numVars = 0;
            this.numVarsInitialized = false;    // will be initialized after the first counter-example is processed.
            this.op = true;
            this.constant = 0;
            this.str = str;

            // enter the variables in the z3Context
            Context context = z3Context.context;

            Term termHasFirst = context.MkConst(this.str + "_hf", z3Context.boolSort);
            Term termHasSecond = context.MkConst(this.str + "_hs", z3Context.boolSort);
            Term termSign1 = context.MkConst(this.str + "_s1", z3Context.boolSort);
            Term termSign2 = context.MkConst(this.str + "_s2", z3Context.boolSort);
            Term termVar1 = context.MkConst(this.str + "_v1", z3Context.intSort);
            Term termVar2 = context.MkConst(this.str + "_v2", z3Context.intSort);
            Term termOp = context.MkConst(this.str + "_op", z3Context.boolSort);
            Term termConstant = context.MkConst(this.str + "_c", z3Context.intSort);

            // assert -constantRange <= constant <= constantRange
            context.AssertCnstr(context.MkLe(context.MkNumeral(-1*constantRange, z3Context.intSort), termConstant));
            context.AssertCnstr(context.MkLe(termConstant, context.MkNumeral(constantRange, z3Context.intSort)));
            // assert hasSecond => hasFirst
            context.AssertCnstr(context.MkImplies(termHasSecond, termHasFirst));
            // assert 0 <= var1, var2 <= numVars-1 when the first counter-example is processed.
        }
Пример #10
0
        int upperLimit; // \in [-10,10]

        #endregion Fields

        #region Constructors

        public ICEIntervals(ref Z3Context z3Context, string str, int constantRange)
        {
            // Initialize the invariant function with "true".
            this.upperLimit = 0;
            this.lowerLimit = 0;
            this.hasUpperLimit = false;
            this.hasLowerLimit = false;
            //this.sampleID = 0;
            this.str = str;

            // enter the variables in the z3Context
            Context context = z3Context.context;

            Term termUpperLimit = context.MkConst(this.str + "_ul", z3Context.intSort);
            Term termLowerLimit = context.MkConst(this.str + "_ll", z3Context.intSort);
            Term termHasUpperLimit = context.MkConst(this.str + "_hul", z3Context.boolSort);
            Term termHasLowerLimit = context.MkConst(this.str + "_hll", z3Context.boolSort);

            // assert -constantRange <= lowerLimit <= upperLimit <= constantRange
            context.AssertCnstr(context.MkLe(context.MkNumeral(-1*constantRange, z3Context.intSort), termLowerLimit));
            context.AssertCnstr(context.MkLe(termLowerLimit, termUpperLimit));
            context.AssertCnstr(context.MkLe(termUpperLimit, context.MkNumeral(constantRange, z3Context.intSort)));
        }
Пример #11
0
        public Term constructSMTConstraint(List<Model.Element> states, ref Z3Context z3Context)
        {
            Debug.Assert(states.Count == 1);
            var state = states[0] as Model.Integer;
            if (state == null)
                throw new ICEHoudiniInternalError("Incorrect type, expected int");
            var intval = state.AsInt();

            Context context = z3Context.context;

            Term termUpperLimit = context.MkConst(this.str + "_ul", z3Context.intSort);
            Term termLowerLimit = context.MkConst(this.str + "_ll", z3Context.intSort);
            Term termHasUpperLimit = context.MkConst(this.str + "_hul", z3Context.boolSort);
            Term termHasLowerLimit = context.MkConst(this.str + "_hll", z3Context.boolSort);

            Term c1_id = context.MkImplies(termHasLowerLimit, context.MkLe(termLowerLimit, context.MkNumeral(intval, z3Context.intSort)));
            Term c2_id = context.MkImplies(termHasUpperLimit, context.MkLe(context.MkNumeral(intval, z3Context.intSort), termUpperLimit));

            return context.MkAnd(c1_id, c2_id);
        }
Пример #12
0
        public bool initializeFromModel(Z3.Model model, ref Z3Context z3Context)
        {
            Debug.Assert(model != null);
            bool ret = false;
            if (this.arg1.initializeFromModel(model, ref z3Context))
                ret = true;
            if (this.arg2.initializeFromModel(model, ref z3Context))
                ret = true;

            return ret;
        }
Пример #13
0
 public Term constructSMTConstraint(List<Model.Element> states, ref Z3Context z3Context)
 {
     return z3Context.context.MkOr(arg1.constructSMTConstraint(states, ref z3Context), arg2.constructSMTConstraint(states, ref z3Context));
 }
Пример #14
0
 public DisjunctionDomain(string baseDomain, Template left, Template right, ref Z3Context z3Context, string str, int constantRange)
 {
     this.str = str;
     this.arg1 = ICEDomainFactory.GetInstance(baseDomain, left, ref z3Context, str + "_1", constantRange);
     this.arg2 = ICEDomainFactory.GetInstance(baseDomain, right, ref z3Context, str + "_2", constantRange);
 }
Пример #15
0
        private ICEOutcome LearnInvFromTemplate(Dictionary<string, int> impl2Priority, Template t, int range, out VCGenOutcome overallOutcome)
        {
            overallOutcome = null;

            // create a new z3 context
            if (z3Context != null)
            {
                z3Context.context.Dispose();
                z3Context.config.Dispose();
            }
            z3Context = new Z3Context();

            foreach (var func in existentialFunctions.Values)
            {
                // initialize function to an "Octagons" instance with the given template "t".
                function2Value[func.Name] = ICEDomainFactory.GetInstance("Octagons", t, ref z3Context, func.Name, range);
            }

            // add counterexamples into the z3Context. These are obtained from the earlier iterations of the template.
            foreach (var cex in counterExamples)
            {
                AddCounterExampleToZ3Context(cex);
            }

            var worklist = new SortedSet<Tuple<int, string>>();
            name2Impl.Keys.Iter(k => worklist.Add(Tuple.Create(impl2Priority[k], k)));

            while (worklist.Any())
            {
                var impl = worklist.First().Item2;
                worklist.Remove(worklist.First());

                #region vcgen

                var gen = prover.VCExprGen;
                var terms = new List<Expr>();
                foreach (var tup in impl2FuncCalls[impl])
                {
                    var controlVar = tup.Item2;
                    var exprVars = tup.Item3;
                    var varList = new List<Expr>();
                    exprVars.Args.OfType<Expr>().Iter(v => varList.Add(v));

                    var args = new List<Expr>();
                    controlVar.InParams.Iter(v => args.Add(Expr.Ident(v)));
                    Expr term = Expr.Eq(new NAryExpr(Token.NoToken, new FunctionCall(controlVar), args),
                                 function2Value[tup.Item1].Gamma(varList));

                    if (controlVar.InParams.Count != 0)
                    {
                        term = new ForallExpr(Token.NoToken, new List<Variable>(controlVar.InParams.ToArray()),
                            new Trigger(Token.NoToken, true, new List<Expr> { new NAryExpr(Token.NoToken, new FunctionCall(controlVar), args) }),
                            term);
                    }
                    terms.Add(term);
                }
                var env = BinaryTreeAnd(terms, 0, terms.Count - 1);

                env.Typecheck(new TypecheckingContext((IErrorSink)null));
                var envVC = prover.Context.BoogieExprTranslator.Translate(env);

                var vc = gen.Implies(envVC, impl2VC[impl]);

                if (CommandLineOptions.Clo.Trace)
                {
                    Console.WriteLine("Verifying {0}: ", impl);
                    //Console.WriteLine("env: {0}", envVC);
                    var envFuncs = new HashSet<string>();
                    impl2FuncCalls[impl].Iter(tup => envFuncs.Add(tup.Item1));
                    envFuncs.Iter(f => PrintFunction(existentialFunctions[f]));
                }

                #endregion vcgen

                VCExpr finalVC;

                #region bound_value_of_cexs
            #if false
                finalVC = vc;

            #else
                int bound = 1000000;
                terms.Clear();
                foreach (var tup in impl2FuncCalls[impl])
                {
                    var exprVars = tup.Item3;
                    var varList = new List<Expr>();
                    exprVars.Args.OfType<Expr>().Where(v => v.Type.IsInt).Iter(v => varList.Add(v));
                    foreach (var variable in varList)
                    {
                        terms.Add(Expr.Le(variable, Expr.Literal(bound)));
                        terms.Add(Expr.Ge(variable, Expr.Literal(-1 * bound)));
                        //terms.Add(Expr.Ge(variable, Expr.Literal(0)));
                    }
                }
                var boundcex = BinaryTreeAnd(terms, 0, terms.Count - 1);
                boundcex.Typecheck(new TypecheckingContext((IErrorSink)null));
                var boundcexVC = prover.Context.BoogieExprTranslator.Translate(boundcex);

                finalVC = gen.Implies(boundcexVC, vc);
            #endif
                #endregion bound_value_of_cexs

                var handler = impl2ErrorHandler[impl].Item1;
                var collector = impl2ErrorHandler[impl].Item2;
                collector.Reset(impl);
                VCisValid = true;   // set to false if control reaches HandleCounterExample
                realErrorEncountered = false;
                newSamplesAdded = false;

                var start = DateTime.Now;

                prover.Push();
                prover.Assert(gen.Not(finalVC), true);
                prover.FlushAxiomsToTheoremProver();
                prover.Check();
                ProverInterface.Outcome proverOutcome = prover.CheckOutcomeCore(handler);

                //prover.BeginCheck(impl, vc, handler);
                //ProverInterface.Outcome proverOutcome = prover.CheckOutcomeCore(handler);

                var inc = (DateTime.Now - start);
                proverTime += inc;
                numProverQueries++;

                if (CommandLineOptions.Clo.Trace)
                    Console.WriteLine("Prover Time taken = " + inc.TotalSeconds.ToString());

                if (proverOutcome == ProverInterface.Outcome.TimeOut || proverOutcome == ProverInterface.Outcome.OutOfMemory)
                {
                    Console.WriteLine("Z3 Prover for implementation {0} times out or runs out of memory !", impl);
                    z3Context.context.Dispose();
                    z3Context.config.Dispose();

                    overallOutcome = new VCGenOutcome(proverOutcome, new List<Counterexample>());
                    return ICEOutcome.Timeout;
                }

                if (CommandLineOptions.Clo.Trace)
                    Console.WriteLine(!VCisValid ? "SAT" : "UNSAT");

                if (!VCisValid)
                {
                    if (realErrorEncountered)
                    {
                        overallOutcome = new VCGenOutcome(ProverInterface.Outcome.Invalid, collector.real_errors);
                        return ICEOutcome.ErrorFound;
                    }

                    Debug.Assert(newSamplesAdded);
                    HashSet<string> funcsChanged;
                    if (!learn(out funcsChanged))
                    {
                        // learner timed out or there is no valid conjecture in the current given template
                        overallOutcome = new VCGenOutcome(ProverInterface.Outcome.Invalid, collector.conjecture_errors);
                        prover.Pop();
                        return ICEOutcome.InvariantNotFound;
                    }
                    // propagate dependent guys back into the worklist, including self
                    var deps = new HashSet<string>();
                    deps.Add(impl);
                    funcsChanged.Iter(f => deps.UnionWith(function2implAssumed[f]));
                    funcsChanged.Iter(f => deps.UnionWith(function2implAsserted[f]));

                    deps.Iter(s => worklist.Add(Tuple.Create(impl2Priority[s], s)));
                }

                prover.Pop();
            }
            // The program was verified with the current template!
            overallOutcome = new VCGenOutcome(ProverInterface.Outcome.Valid, new List<Counterexample>());
            return ICEOutcome.InvariantFound;
        }
Пример #16
0
 public bool initializeFromModel(Z3.Model model, ref Z3Context z3Context)
 {
     Debug.Assert(model != null);
     bool ret = false;
     for (int i = 0; i < args.Count; i++)
     {
         if (this.args.ElementAt(i).initializeFromModel(model, ref z3Context))
             ret = true;
     }
     return ret;
 }