private List<Tuple<string, List<Model.Element>>> ExtractState(string impl, Expr expr, Model model) { var funcsUsed = FunctionCollector.Collect(expr); var ret = new List<Tuple<string, List<Model.Element>>>(); foreach (var tup in funcsUsed.Where(t => t.Item2 == null)) { var constant = tup.Item1; if (!constant2FuncCall.ContainsKey(constant.Name)) continue; var func = constant2FuncCall[constant.Name]; var funcName = (func.Fun as FunctionCall).FunctionName; var vals = new List<Model.Element>(); prover.Context.BoogieExprTranslator.Translate(func.Args).Iter(ve => vals.Add(getValue(ve, model))); ret.Add(Tuple.Create(funcName, vals)); } foreach (var tup in funcsUsed.Where(t => t.Item2 != null)) { var constant = tup.Item1; var boundExpr = tup.Item2; if (!constant2FuncCall.ContainsKey(constant.Name)) continue; // There are some bound variables (because the existential function was inside an \exists). // We must find an assignment for bound varibles // First, peice apart the existential functions var cd = new Duplicator(); var tup2 = ExistentialExprModelMassage.Massage(cd.VisitExpr(boundExpr.Body)); var be = tup2.Item1; Expr env = Expr.True; foreach (var ahFunc in tup2.Item2) { var tup3 = impl2FuncCalls[impl].First(t => t.Item2.Name == ahFunc.Name); var varList = new List<Expr>(); tup3.Item3.Args.OfType<Expr>().Iter(v => varList.Add(v)); env = Expr.And(env, function2Value[tup3.Item1].Gamma(varList)); } be = Expr.And(be, Expr.Not(env)); // map formals to constants var formalToConstant = new Dictionary<string, Constant>(); foreach (var f in boundExpr.Dummies.OfType<Variable>()) formalToConstant.Add(f.Name, new Constant(Token.NoToken, new TypedIdent(Token.NoToken, f.Name + "@subst@" + (existentialConstCounter++), f.TypedIdent.Type), false)); be = Substituter.Apply(new Substitution(v => formalToConstant.ContainsKey(v.Name) ? Expr.Ident(formalToConstant[v.Name]) : Expr.Ident(v)), be); formalToConstant.Values.Iter(v => prover.Context.DeclareConstant(v, false, null)); var reporter = new ICEHoudiniErrorReporter(); var ve = prover.Context.BoogieExprTranslator.Translate(be); prover.Assert(ve, true); prover.Check(); var proverOutcome = prover.CheckOutcomeCore(reporter); if (proverOutcome != ProverInterface.Outcome.Invalid) continue; model = reporter.model; var func = constant2FuncCall[constant.Name]; var funcName = (func.Fun as FunctionCall).FunctionName; var vals = new List<Model.Element>(); foreach (var funcArg in func.Args.OfType<Expr>()) { var arg = Substituter.Apply(new Substitution(v => formalToConstant.ContainsKey(v.Name) ? Expr.Ident(formalToConstant[v.Name]) : Expr.Ident(v)), funcArg); vals.Add(getValue(prover.Context.BoogieExprTranslator.Translate(arg), model)); } ret.Add(Tuple.Create(funcName, vals)); } return ret; }
public void Init() { d = new Duplicator(); }