TERM Subst(TERM e, params TERM[] subst) { var theta = new Dictionary <TERM, TERM>(); for (int i = 0; i < subst.Length; i += 2) { theta[subst[i]] = subst[i + 1]; } var res = solver.ApplySubstitution(e, theta); return(res); }
/// <summary> /// Get the projection pair for A, the control-state projection, and the register-state projection. /// Gets also the function combine that combines the projections back to the original register format /// combine(control_state,register_state). /// </summary> internal void GetProjectionPair(IRegisterInfo <TERM> A, out TERM control_proj, out TERM register_proj, out Func <TERM, TERM, TERM> combine) { var v = MkRegister(solver.GetSort(A.InitialRegister)); var projs = new List <Pair <TERM, bool> >(GetRegisterProjections(v, v, A)).ToArray(); var first = Array.ConvertAll(Array.FindAll(projs, p => p.Second), pair => pair.First); var second = Array.ConvertAll(Array.FindAll(projs, p => !p.Second), pair => pair.First); if (first.Length == 0) //no control projection { control_proj = solver.UnitConst; register_proj = v; combine = ((x1, x2) => x2); } else if (second.Length == 0) //no register projection { control_proj = v; register_proj = solver.UnitConst; combine = ((x1, x2) => x1); } else { control_proj = (first.Length == 1 ? first[0] : solver.MkTuple(first)); register_proj = (second.Length == 1 ? second[0] : solver.MkTuple(second)); var control_sort = solver.GetSort(control_proj); var tmp_control_var = solver.MkVar(2, control_sort); var register_sort = solver.GetSort(register_proj); var tmp_register_var = solver.MkVar(3, register_sort); List <KeyValuePair <TERM, TERM> > subst_list; var skel = MkTupleVarSkeleton(v, out subst_list); var subst = new Dictionary <TERM, TERM>(); int m = 0; int n = 0; for (int i = 0; i < subst_list.Count; i++) //subst_list has the same length as projs { if (projs[i].Second) { subst[subst_list[i].Key] = (first.Length == 1 ? tmp_control_var : solver.MkProj(m++, tmp_control_var)); } else { subst[subst_list[i].Key] = (second.Length == 1 ? tmp_register_var : solver.MkProj(n++, tmp_register_var)); } } var combined_reg = solver.Simplify(solver.ApplySubstitution(skel, subst)); combine = (x1, x2) => solver.ApplySubstitution(combined_reg, tmp_control_var, x1, tmp_register_var, x2); } }
FUNC MkAcc() { var stringSort = solver.MkListSort(inpSort); var StringSort = stringSort; var EmptyString = solver.GetNil(stringSort); var _char = solver.MkVar(0, inpSort); Dictionary <int, FUNC> acceptDecls = new Dictionary <int, FUNC>(); foreach (int state in automaton.States) { acceptDecls[state] = solver.MkFreshFuncDecl(name + state, new SORT[] { stringSort }, solver.BoolSort); } TERM x = solver.MkVar(0, StringSort); TERM xIsEmpty = solver.MkEq(x, EmptyString); foreach (int state in automaton.States) { //create axioms for the transitions //for each state n and transitions // (n,cond1,n1),...,(n,condk,nk),(n,m1),...,(n,ml) //create the axiom // accept_n(x) <=> ((x != nil) & // OR_{1<=i<=k} ( condi[head(x)] & accept_ni(tail(x))) | // OR_{1<=i<=l} accept_mi(x) | // ite(n is final, x=nil, false) //assumes that the FA does not include epsilon-loops //or else terminaton is not guaranteed List <Move <TERM> > trans = new List <Move <TERM> >(automaton.GetMovesFrom(state)); TERM lhs = solver.MkApp(acceptDecls[state], x); List <TERM> rhs_cases = new List <TERM>(); List <TERM> rhs_extra_cases = new List <TERM>(); foreach (Move <TERM> t in trans) { if (t.IsEpsilon) { rhs_extra_cases.Add(solver.MkApp(acceptDecls[t.TargetState], x)); } else { rhs_cases.Add(solver.MkAnd(solver.ApplySubstitution(t.Label, _char, solver.MkFirstOfList(x)), solver.MkApp(acceptDecls[t.TargetState], solver.MkRestOfList(x)))); } } if (automaton.IsFinalState(state)) { rhs_extra_cases.Add(xIsEmpty); } TERM rhs_extra = (rhs_extra_cases.Count == 0 ? solver.False : (rhs_extra_cases.Count == 1 ? rhs_extra_cases[0] : solver.MkOr(rhs_extra_cases.ToArray()))); TERM rhs_nonempty_case = solver.MkAnd(solver.MkNot(xIsEmpty), solver.MkOr(rhs_cases.ToArray())); TERM rhs = (rhs_extra.Equals(solver.False) ? rhs_nonempty_case : solver.MkOr(rhs_extra, rhs_nonempty_case)); solver.MainSolver.Assert(solver.MkAxiom(lhs, rhs, x)); } return(acceptDecls[automaton.InitialState]); }
protected override Expr MkFunctionCall(ident id, params Expr[] args) { if (id.name == "string") //construct a string from fixed characters { return(args.Length > 0 ? solver.MkList(args) : solver.MkListFromString("", solver.CharSort)); } if (id.name == "in") //RHS is a regular expression { if (args.Length != 2) { throw new BekParseException(id.Line, id.Pos, "Wrong number of arguments"); } string regex = "^(" + GetString(args[1]) + ")$"; Automaton <Expr> aut = solver.RegexConverter.Convert(regex).Determinize().Minimize(); if (aut.StateCount != 2 || aut.MoveCount != 1) { throw new BekParseException(id.Line, id.Pos, "The rhs must be a regex character class or regex matching strings of length 1 (anchors are implicit)"); } Expr pred = aut.GetMoveFrom(aut.InitialState).Label; Expr predInst = solver.ApplySubstitution(pred, solver.MkCharVar(0), args[0]); return(predInst); } return(solver.Library.ApplyFunction(id.name, args)); //var func = funcs.Find(fn => fn.id.name.Equals(name.name)); //if (func != null) // return library.LocalFunction(name, args); //try //{ // switch (name.name) // { // case ("ite"): // return MkIte(name, args); // case ("dec"): // case ("FromDecimals"): // return FromDecimals(args); // case ("IsHighSurrogate"): // return library.IsHighSurrogate(args); // case ("IsLowSurrogate"): // return library.IsLowSurrogate(args); // case ("hex"): // case ("HexEnc"): // return library.HexEnc(args); // case ("Bits"): // case ("BitExtract"): // return library.BitExtr(args); // case ("InCssSafeList"): // return library.InCssSafeList(args); // case ("UnicodeCodePoint"): // case ("CssCombinedCodePoint"): // return library.UnicodeCodePoint(args); // case ("long"): // return MkLong(args); // case ("string"): // if (args.Length == 0) // return solver.MkListFromString("", solver.CharSort); // else // return solver.MkList(args); // default: // if (name.name.StartsWith("hex")) // { // string rest = name.name.Substring(3); // int k; // if (!int.TryParse(rest, out k) || args.Length != 1) // throw new BekParseException(name.line, name.pos, string.Format("Unknown function '{0}'", name.name)); // return library.HexEnc(k, args[0]); // } // else // { // throw new BekParseException(name.line, name.pos, string.Format("Unknown function '{0}'", name.name)); // } // } //} //catch (BekParseException e) //{ // throw e; //} //catch (Exception e) //{ // throw new BekParseException(name.line, name.pos, e.Message); //} }