private void SExprToSoln (SExpr resp, Dictionary<int,Dictionary<string,string>> varSubst) { 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); var lines = resp.Arguments; // get all the predicate definitions for (int i = 0; i < lines.Length; i++) { var line = lines [i]; string pname; RPFP.Transformer annot; GetDefun(line, out pname, out annot); if(pmap.ContainsKey(pname)){ var node = pmap[pname]; node.Annotation = annot; } else if(pname[0] != '@'){ // if not an internal symbol HandleProverError ("Prover error: got unknown predicate:" + pname); throw new BadExprFromProver (); } } }
private void GetDefun(SExpr line, out string pname, out RPFP.Transformer annot) { if (line.Name != "define-fun") { HandleProverError("Prover error: expected define-fun but got:" + line.Name); throw new BadExprFromProver(); } if (line.ArgCount != 4) { HandleProverError("Prover error: define-fun has wrong number of arguments"); throw new BadExprFromProver(); } pname = StripCruft(line.Arguments[0].Name); var pvars = line.Arguments[1]; var pbody = line.Arguments[3]; // range has to be Bool var binding = new Dictionary<string, VCExpr>(); var pvs = new List<VCExpr>(); foreach (var b in pvars.Arguments) { var e = SExprToVar(b); pvs.Add(e); binding.Add(StripCruft(b.Name), e); } VCExpr bexpr = SExprToVCExpr(pbody, binding); annot = rpfp.CreateRelation(pvs.ToArray(), bexpr); }
private VCExprVar SExprToVar (SExpr e) { if(e.Arguments.Count() != 1){ HandleProverError ("Prover error: bad quantifier syntax"); throw new BadExprFromProver (); } string vname = StripCruft(e.Name); SExpr vtype = e[0]; switch(vtype.Name){ case "Int": return gen.Variable(vname,Type.Int); case "Bool": return gen.Variable (vname,Type.Bool); case "Array":{ // TODO: handle more general array types var idxType = Type.Int; // well, could be something else var valueType = (vtype.Arguments[1].Name == "Int") ? Type.Int : Type.Bool; var types = new List<Type>(); types.Add(idxType); return gen.Variable (vname, new MapType(Token.NoToken,new List<TypeVariable>(),types,valueType)); } default: { HandleProverError ("Prover error: bad type: " + vtype.Name); throw new BadExprFromProver (); } } }
protected VCExpr SExprToVCExpr (SExpr e, Dictionary<string,VCExpr> bound) { if (e.Arguments.Count() == 0) { var name = StripCruft(e.Name); if (name [0] >= '0' && name [0] <= '9') { Microsoft.Basetypes.BigNum x = Microsoft.Basetypes.BigNum.FromString(name); return gen.Integer (x); } if (bound.ContainsKey (name)) { return bound [name]; } if(name == "true") return VCExpressionGenerator.True; if(name == "false") return VCExpressionGenerator.False; if(declHandler.var_map.ContainsKey(name)) return declHandler.var_map[name]; HandleProverError ("Prover error: unknown symbol:" + name); //throw new BadExprFromProver (); var v = gen.Variable(name, Type.Int); bound.Add(name, v); return v; } ArgGetter g = i => SExprToVCExpr (e [i], bound); ArgsGetter ga = () => e.Arguments.Select (x => SExprToVCExpr (x, bound)).ToArray (); VarsGetter gb = () => e [0].Arguments.Select (x => SExprToVar (x)).ToArray (); switch (e.Name) { case "select" : return gen.Select (ga ()); case "store" : return gen.Store (ga ()); case "forall": case "exists": { var binds = e.Arguments[0]; var vcbinds = new List<VCExprVar>(); var bound_copy = new Dictionary<string, VCExpr>(bound); for (int i = 0; i < binds.Arguments.Count(); i++) { var bind = binds.Arguments[i]; var symb = StripCruft(bind.Name); var vcv = SExprToVar(bind); vcbinds.Add(vcv); bound[symb] = vcv; } var body = g(1); if (e.Name == "forall") body = gen.Forall(vcbinds, new List<VCTrigger>(), body); else body = gen.Exists(vcbinds, new List<VCTrigger>(), body); bound = bound_copy; return body; } case "-" : // have to deal with unary case { if(e.ArgCount == 1){ var args = new VCExpr[2]; args[0] = gen.Integer (Microsoft.Basetypes.BigNum.ZERO); args[1] = g(0); return gen.Function(VCStringToVCOp("-"),args); } return gen.Function(VCStringToVCOp("-"),ga()); } case "!" : // this is commentary return g(0); case "let" : { // we expand lets exponentially since there is no let binding in Boogie surface syntax bool expand_lets = true; var binds = e.Arguments[0]; var vcbinds = new List<VCExprLetBinding>(); var bound_copy = new Dictionary<string, VCExpr>(bound); for(int i = 0; i < binds.Arguments.Count(); i++){ var bind = binds.Arguments[i]; var symb = bind.Name; var def = bind.Arguments[0]; var vce = SExprToVCExpr(def, bound); var vcv = gen.Variable(symb,vce.Type); var vcb = gen.LetBinding(vcv,vce); vcbinds.Add (vcb); bound[symb] = expand_lets ? vce : vcv; } var body = g(1); if(!expand_lets) body = gen.Let(vcbinds,body); bound = bound_copy; return body; } default: { var op = VCStringToVCOp (e.Name); if (op == null) { var name = StripCruft(e.Name); if(declHandler.func_map.ContainsKey(name)){ Function f = declHandler.func_map[name]; return gen.Function (f, ga()); } HandleProverError ("Prover error: unknown operator:" + e.Name); throw new BadExprFromProver (); } if(op.Arity == 2) return MakeBinary (op, ga ()); return gen.Function(op, ga()); } } }
void ExtractDataType(SExpr datatypes) { Debug.Assert(datatypes.Name == "declare-datatypes"); if (datatypes[0].Name != "" || datatypes[1].Name != "" || datatypes[1].ArgCount != 1) { Parent.HandleProverError("Unexpected datatype: " + datatypes); throw new BadExprFromProver (); } SMTDataType dt = new SMTDataType(); SExpr typeDef = datatypes[1][0]; if (typeDef.ArgCount != 1) { Parent.HandleProverError("Unexpected datatype: " + datatypes); throw new BadExprFromProver (); } dt.Constructor = typeDef[0].Name; dt.Types = new List<SExpr>(); for (int i = 0; i < typeDef[0].ArgCount; ++i) { if (typeDef[0][i].ArgCount != 1) { Parent.HandleProverError("Unexpected datatype constructor: " + typeDef[0]); throw new BadExprFromProver (); } dt.Types.Add(typeDef[0][i][0]); } DataTypes[typeDef.Name] = dt; }
private Outcome GetInterpolantResponse(out SExpr interpolant) { var result = Outcome.Undetermined; var wasUnknown = false; interpolant = null; Process.Ping(); bool onlyOnce = false; while (true) { var resp = Process.GetProverResponse(); if (resp == null || Process.IsPong(resp)) break; switch (resp.Name) { case "unsat": result = Outcome.Valid; break; case "sat": result = Outcome.Invalid; break; case "unknown": result = Outcome.Invalid; wasUnknown = true; break; default: if (result == Outcome.Valid) { interpolant = resp as SExpr; Contract.Assert(onlyOnce == false); onlyOnce = true; continue; } HandleProverError("Unexpected prover response: " + resp.ToString()); break; } } if (wasUnknown) { SendThisVC("(get-info :reason-unknown)"); Process.Ping(); while (true) { var resp = Process.GetProverResponse(); if (resp == null || Process.IsPong(resp)) break; if (resp.ArgCount == 1 && resp.Name == ":reason-unknown") { switch (resp[0].Name) { case "memout": currentErrorHandler.OnResourceExceeded("memory"); result = Outcome.OutOfMemory; Process.NeedsRestart = true; break; case "timeout": case "canceled": currentErrorHandler.OnResourceExceeded("timeout"); result = Outcome.TimeOut; break; default: break; } } else { HandleProverError("Unexpected prover response (getting info about 'unknown' response): " + resp.ToString()); } } } return result; }
void ConstructFunction(SExpr element, SExpr inType, SExpr outType, StringBuilder m) { List<SExpr> argTypes = new List<SExpr>(); for (int i = 0; i < inType.ArgCount; ++i) { if (inType[i].Name != "_ufmt_" + (i + 1) && inType[i].Name != "x!" + (i + 1) && !inType[i].Name.StartsWith("BOUND_VARIABLE_")) { Parent.HandleProverError("Unexpected function argument: " + inType[i].Name); throw new BadExprFromProver (); } argTypes.Add(inType[i][0]); } ConstructFunctionElements(element, argTypes, outType, m); }
bool isConstArray(SExpr element, SExpr type) { if (type.Name != "Array") return false; if (element.Name == "__array_store_all__") // CVC4 1.4 return true; else if (element.Name == "" && element[0].Name == "as" && element[0][0].Name == "const") // CVC4 > 1.4 return true; return false; }
void ConstructFunctionArguments(SExpr arguments, List<SExpr> argTypes, StringBuilder[] argValues) { if (arguments.Name == "and") { ConstructFunctionArguments(arguments[0], argTypes, argValues); ConstructFunctionArguments(arguments[1], argTypes, argValues); } else if (arguments.Name == "=" && (arguments[0].Name.StartsWith("_ufmt_") || arguments[0].Name.StartsWith("x!"))) { int argNum; if (arguments[0].Name.StartsWith("_ufmt_")) argNum = System.Convert.ToInt32(arguments[0].Name.Substring("_uftm_".Length)) - 1; else /* if (arguments[0].Name.StartsWith("x!")) */ argNum = System.Convert.ToInt32(arguments[0].Name.Substring("x!".Length)) - 1; if (argNum < 0 || argNum >= argTypes.Count) { Parent.HandleProverError("Unexpected function argument: " + arguments[0]); throw new BadExprFromProver (); } if (argValues[argNum] != null) { Parent.HandleProverError("Function argument defined multiple times: " + arguments[0]); throw new BadExprFromProver (); } argValues[argNum] = new StringBuilder(); ConstructComplexValue(arguments[1], argTypes[argNum], argValues[argNum]); } else { Parent.HandleProverError("Unexpected function argument: " + arguments); throw new BadExprFromProver (); } }
void ConstructFunctionElements(SExpr element, List<SExpr> argTypes, SExpr outType, StringBuilder m) { while (element.Name == "ite") { StringBuilder[] argValues = new StringBuilder[argTypes.Count]; ConstructFunctionArguments(element[0], argTypes, argValues); foreach (var s in argValues) m.Append(s + " "); m.Append("-> "); ConstructComplexValue(element[1], outType, m); m.Append("\n "); if (element[2].Name != "ite") m.Append("else -> "); element = element[2]; } ConstructComplexValue(element, outType, m); }
void ConstructSimpleValue(SExpr element, SExpr type, StringBuilder m) { if (type.Name == "Bool" && element.ArgCount == 0) { m.Append(element.ToString()); return; } if (type.Name == "Int") { if (element.ArgCount == 0) { m.Append(element.ToString()); return; } else if (element.Name == "-" && element.ArgCount == 1) { m.Append(element.ToString()); return; } } if (type.Name == "_" && type.ArgCount == 2 && type[0].Name == "BitVec") { if (element.Name == "_" && element.ArgCount == 2 && element[0].Name.StartsWith("bv") && element[0].ArgCount == 0 && element[1].Name == type.Arguments[1].Name && element[1].ArgCount == 0) { m.Append(element[0].Name + '[' + element[1].Name + ']'); return; } } if (type.Name == "Array") { while (element.Name == "store") { ConstructComplexValue(element[1], type[0], m); m.Append(" -> "); ConstructComplexValue(element[2], type[1], m); m.Append("\n "); if (element[0].Name != "store") { m.Append("else -> "); } element = element[0]; } if (isConstArray(element, type)) { ConstructComplexValue(getConstArrayElement(element), type[1], m); return; } else if (element.Name == "_" && element.ArgCount == 2 && element[0].Name == "as-array") { m.Append("as-array[" + element[1].Name + ']'); return; } } if (SortSet.ContainsKey(type.Name) && SortSet[type.Name] == 0) { var prefix = "@uc_T_" + type.Name.Substring(2) + "_"; if (element.Name.StartsWith(prefix)) { m.Append(type.Name + "!val!" + element.Name.Substring(prefix.Length)); return; } } if (Functions.ContainsKey(element.Name) && type.Name == Functions[element.Name].Name) { m.Append(element.Name); return; } if (DataTypes.ContainsKey(type.Name) && DataTypes[type.Name].Constructor == element.Name && element.ArgCount == DataTypes[type.Name].Types.Count) { m.Append("(" + element.Name); for (int i = 0; i < element.ArgCount; ++i) { m.Append(" "); ConstructComplexValue(element[i], DataTypes[type.Name].Types[i], m); } m.Append(")"); return; } Parent.HandleProverError("Unexpected value: " + element); throw new BadExprFromProver (); }
void ConstructComplexValue(SExpr element, SExpr type, StringBuilder m) { if (type.Name == "Array") { if (element.Name == "store" || isConstArray(element, type)) { NumNewArrays++; m.Append("as-array[k!" + NumNewArrays + ']'); SExpr[] args = {new SExpr("k!" + NumNewArrays), new SExpr(""), type, element}; var newElement = new SExpr("define-fun", args); TopLevelProcessed.Add(newElement); ErrorModelTodo.Add(newElement); return; } } ConstructSimpleValue(element, type, m); }
SExpr getConstArrayElement(SExpr element) { if (element.Name == "__array_store_all__") // CVC4 1.4 return element[1]; else if (element.Name == "" && element[0].Name == "as" && element[0][0].Name == "const") // CVC4 > 1.4 return element[1]; Parent.HandleProverError("Unexpected value: " + element); throw new BadExprFromProver (); }
private RPFP.Node SExprToCex(SExpr resp, ErrorHandler handler, Dictionary<int,Dictionary<string,string>> varSubst) { Dictionary<string, RPFP.Node> nmap = new Dictionary<string,RPFP.Node>(); 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); RPFP.Node topnode = null; var lines = resp.Arguments; // last line of derivation is from query, skip it for (int i = 0; i < lines.Length-1; i++) { var line = lines[i]; if (line.ArgCount != 6) { HandleProverError("bad derivation line from prover: " + line.ToString()); return null; } var name = line[0]; var conseq = line[1]; var rule = line[2]; var subst = line[3]; var labs = line[4]; var refs = line[5]; var predName = conseq.Name; { string spacer = "@@"; // Hack! UniqueNamer is adding these and I can't stop it! int pos = predName.LastIndexOf(spacer); if (pos >= 0) predName = predName.Substring(0, pos); } RPFP.Node node = null; if (!pmap.TryGetValue(predName, out node)) { HandleProverError("unknown predicate from prover: " + predName.ToString()); return null; } RPFP.Node cexnode = rpfp.CloneNode(node); cexnode.map = node; nmap.Add(name.Name, cexnode); List<RPFP.Node> Chs = new List<RPFP.Node>(); if (refs.Name != "ref") { HandleProverError("bad references from prover: " + refs.ToString()); return null; } foreach (var c in refs.Arguments) { if (c.Name == "true") Chs.Add(null); else { RPFP.Node ch = null; if (!nmap.TryGetValue(c.Name, out ch)) { HandleProverError("unknown reference from prover: " + c.ToString()); return null; } Chs.Add(ch); } } if (!rule.Name.StartsWith("rule!")) { HandleProverError("bad rule name from prover: " + refs.ToString()); return null; } int ruleNum = Convert.ToInt32(rule.Name.Substring(5)) - 1; if (ruleNum < 0 || ruleNum > rpfp.edges.Count) { HandleProverError("bad rule name from prover: " + refs.ToString()); return null; } RPFP.Edge orig_edge = rpfp.edges[ruleNum]; RPFP.Edge e = rpfp.CreateEdge(cexnode, orig_edge.F, Chs.ToArray()); e.map = orig_edge; topnode = cexnode; if (labs.Name != "labels") { HandleProverError("bad labels from prover: " + labs.ToString()); return null; } e.labels = new HashSet<string>(); foreach (var l in labs.Arguments) e.labels.Add(l.Name); if (subst.Name != "subst") { HandleProverError("bad subst from prover: " + subst.ToString()); return null; } Dictionary<string, string> dict = new Dictionary<string, string>(); varSubst[e.number] = dict; foreach (var s in subst.Arguments) { if (s.Name != "=" || s.Arguments.Length != 2) { HandleProverError("bad equation from prover: " + s.ToString()); return null; } string uniqueName = s.Arguments[0].Name; string spacer = "@@"; // Hack! UniqueNamer is adding these and I can't stop it! int pos = uniqueName.LastIndexOf(spacer); if (pos >= 0) uniqueName = uniqueName.Substring(0, pos); dict.Add(uniqueName, s.Arguments[1].ToString()); } } if (topnode == null) { HandleProverError("empty derivation from prover: " + resp.ToString()); } return topnode; }
void ConstructDefine(SExpr element, StringBuilder m) { Debug.Assert(element.Name == "define-fun"); if (element[1].ArgCount != 0) TopLevelProcessed.Add(element); m.Append(element[0] + " -> "); if (TopLevelProcessed.Contains(element)) m.Append("{\n "); if (element[1].ArgCount == 0 && element[2].Name == "Array" && !TopLevelProcessed.Contains(element)) { ConstructComplexValue(element[3], element[2], m); } else if (element[1].ArgCount == 0) { ConstructSimpleValue(element[3], element[2], m); } else { ConstructFunction(element[3], element[1], element[2], m); } if (TopLevelProcessed.Contains(element)) m.Append("\n}"); m.Append("\n"); }
private Model SExprToModel(SExpr resp, ErrorHandler handler) { // Concatenate all the arguments string modelString = resp[0].Name; // modelString = modelString.Substring(7, modelString.Length - 8); // remove "(model " and final ")" var models = Model.ParseModels(new StringReader("Error model: \n" + modelString)); if (models == null || models.Count == 0) { HandleProverError("no model from prover: " + resp.ToString()); } return models[0]; }
public SMTErrorModelConverter(SExpr _ErrorModel, SMTLibProcessTheoremProver _Parent) { ErrorModelTodo = _ErrorModel.Arguments.ToList();; Parent = _Parent; }