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)); }
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"); } }
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()); }
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); } }
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); }
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)); }
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; }
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; }
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. }
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))); }
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); }
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; }
public Term constructSMTConstraint(List<Model.Element> states, ref Z3Context z3Context) { return z3Context.context.MkOr(arg1.constructSMTConstraint(states, ref z3Context), arg2.constructSMTConstraint(states, ref z3Context)); }
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); }
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; }
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; }