public static IEnumerable <iterassgn> Initializers(iterexpr e, Symtab stab) { foreach (iterassgn ia in assign_filter.Apply(e.initializer)) { yield return(ia); } }
public static IEnumerable <iterassgn> InitialChars(iterexpr e, Symtab stab) { foreach (iterassgn ia in assign_filter.Apply(e.initializer)) { if (stab.Get(ia.lhs).type == BekTypes.CHAR) { yield return(ia); } } }
//internal RaiseRule<Expr> haltRule; public VarInfo(STBuilderZ3 stb, Symtab stab, iterexpr ie, Sort charsort) { this.stab = stab; this.charsort = charsort; this.stb = stb; this.binder = ie.binder; binderid = stab.Get(ie.binder).id; bekVarIds = new List <int>(); bekVarVals = new List <Expr>(); bekVarSorts = new List <Sort>(); proj = new Dictionary <int, int>(); int regPosNr = 0; foreach (iterassgn ia in IterInfo.Initializers(ie, stab)) { proj[stab.Get(ia.lhs).id] = regPosNr; bekVarIds.Add(stab.Get(ia.lhs).id); bekVarVals.Add(MkExpr(stab.Get(ia.lhs).type, ia.rhs)); bekVarSorts.Add(BekTypeToSort(stab.Get(ia.lhs).type)); regPosNr += 1; } K = bekVarSorts.Count; //register sort regSort = (K == 0 ? stb.Solver.UnitSort : (K == 1 ? bekVarSorts[0] : stb.Solver.MkTupleSort(bekVarSorts.ToArray()))); //initial register value initReg = (K == 0 ? stb.Solver.UnitConst : (K == 1 ? bekVarVals[0] : stb.Solver.MkTuple(bekVarVals.ToArray()))); //input character variable c = this.stb.MkInputVariable(charsort); //register variable r = this.stb.MkRegister(regSort); //maps variable identifiers used in the bek program to corresponding term variables varMap = new Dictionary <int, Expr>(); varMap[binderid] = c; //input character variable for (int i = 0; i < K; i++) //bek pgm variables { varMap[bekVarIds[i]] = (K == 1 ? r : stb.Solver.MkProj(i, r)); } //haltRule = new RaiseRule<Expr>(); }
internal BekTypes HandleIter(iterexpr cur) { topexpr_visitor.Visit(this, cur.source); PushIter(cur.binder, cur.initializer); var identfilter = new Filter <ident>(); foreach (var id in identfilter.Apply(cur.body)) { AddElt(id, GetElt(id)); } PopBlock(); return(BekTypes.STR); }
public override STModel Convert(iterexpr ie, Symtab stab) { VarInfo I = new VarInfo(stb, stab, ie, charsort); var iterCases = ConsList <itercase> .Create(ie.GetNormalCases()); var endCases = ConsList <itercase> .Create(ie.GetEndCases()); BranchingRule <Expr> rule = CreateBranchingRule(iterCases, stb.Solver.True, I); BranchingRule <Expr> frule = CreateBranchingRule(endCases, stb.Solver.True, I); STModel st = new STModel(stb.Solver, "iterSTb", charsort, charsort, I.regSort, I.initReg, 0); st.AssignRule(0, rule); st.AssignFinalRule(0, frule); return(st); }
protected STModel HandleIter(iterexpr e) { return(this.iter_handler.Convert(e, this.stab)); }
public override STModel Convert(iterexpr ie, Symtab stab) { var solver = stb.Solver; int binderid = stab.Get(ie.binder).id; List <int> bekVarIds = new List <int>(); List <Expr> bekVarVals = new List <Expr>(); List <Sort> bekVarSorts = new List <Sort>(); Dictionary <int, int> proj = new Dictionary <int, int>(); foreach (iterassgn ia in IterInfo.Initializers(ie, stab)) { proj[stab.Get(ia.lhs).id] = bekVarIds.Count; bekVarIds.Add(stab.Get(ia.lhs).id); bekVarVals.Add(MkExpr(stab.Get(ia.lhs).type, ia.rhs)); bekVarSorts.Add(BekTypeToSort(stab.Get(ia.lhs).type)); } int K = bekVarSorts.Count; //register sort Sort regSort = (K == 0 ? solver.UnitSort : (K == 1 ? bekVarSorts[0] : solver.MkTupleSort(bekVarSorts.ToArray()))); //initial register value Expr initReg = (K == 0 ? solver.UnitConst : (K == 1 ? bekVarVals[0] : solver.MkTuple(bekVarVals.ToArray()))); //input character variable Expr c = this.stb.MkInputVariable(charsort); //register variable Expr r = this.stb.MkRegister(regSort); //maps variable identifiers used in the bek program to corresponding term variables Dictionary <int, Expr> varMap = new Dictionary <int, Expr>(); varMap[binderid] = c; for (int i = 0; i < K; i++) { varMap[bekVarIds[i]] = (K == 1 ? r : solver.MkProj(i, r)); } List <Move <Rulez3> > moves = new List <Move <Rulez3> >(); Expr previousCaseNegated = solver.True; foreach (itercase curcase in ie.GetNormalCases()) { if (!solver.IsSatisfiable(previousCaseNegated)) { break; } //initial symbolic values are the previous register values Expr[] regs0 = new Expr[K]; for (int i = 0; i < K; i++) { regs0[i] = varMap[bekVarIds[i]]; } Expr[] regs = new Expr[K]; for (int i = 0; i < K; i++) { regs[i] = regs0[i]; } //gets the current symbolic value of ident Func <ident, Expr> idents = x => { SymtabElt se = stab.Get(x); if (se.id == binderid) { return(c); //the input character } return(regs0[proj[se.id]]); //the current sybolic value of x }; //current condition is the case condition and not the previous case conditions Expr casecond = this.expr_handler.Convert(curcase.cond, idents); Expr guard = stb.And(previousCaseNegated, casecond); Expr not_casecond = stb.Not(casecond); previousCaseNegated = stb.And(previousCaseNegated, solver.MkNot(casecond)); List <Expr> yields = new List <Expr>(); if (solver.IsSatisfiable(guard)) { #region iterate over the iter statements in the body foreach (iterstmt ist in curcase.body) { //gets the current symbolic value of ident //note that the symbolic value may have been updated by a previous assignment Func <ident, Expr> idents1 = x => { SymtabElt se = stab.Get(x); if (se.id == binderid) { return(c); //the input character } return(regs0[proj[se.id]]); //the current sybolic value of x }; iterassgn a = ist as iterassgn; if (a != null) { var v = expr_handler.Convert(a.rhs, idents1); regs[proj[stab.Get(a.lhs).id]] = v; } else { yieldstmt y = ist as yieldstmt; if (y != null) { foreach (var e in y.args) { strconst s = e as strconst; if (s == null) { yields.Add(expr_handler.Convert(e, idents1)); } else { foreach (int sc in s.content) { yields.Add(solver.MkNumeral(sc, charsort)); } } } } else { throw new BekException(); //TBD: undefined case } } } #endregion Expr upd = (K == 0 ? solver.UnitConst : (K == 1 ? regs[0] : solver.MkTuple(regs))); moves.Add(stb.MkRule(0, 0, guard, upd, yields.ToArray())); } } previousCaseNegated = solver.True; bool noEndCases = true; foreach (itercase curcase in ie.GetEndCases()) { noEndCases = false; if (!solver.IsSatisfiable(previousCaseNegated)) { break; } //initial symbolic values are the previous register values Expr[] regs = new Expr[K]; for (int i = 0; i < K; i++) { regs[i] = varMap[bekVarIds[i]]; } //gets the current symbolic value of ident Func <ident, Expr> idents = x => { SymtabElt se = stab.Get(x); if (se.id == binderid) { throw new BekException("Input var must not occur in an end case"); } return(regs[proj[se.id]]); //the current sybolic value of x }; //current condition is the case condition and not the previous case conditions Expr casecond = this.expr_handler.Convert(curcase.cond, idents); Expr guard = stb.And(previousCaseNegated, casecond); Expr not_casecond = stb.Not(casecond); previousCaseNegated = stb.And(previousCaseNegated, solver.MkNot(casecond)); List <Expr> yields = new List <Expr>(); if (solver.IsSatisfiable(guard)) { #region iterate over the iter statements in the body foreach (iterstmt ist in curcase.body) { //gets the current symbolic value of ident //note that the symbolic value may have been updated by a previous assignment Func <ident, Expr> idents1 = x => { SymtabElt se = stab.Get(x); if (se.id == binderid) { throw new BekException("Input var must not occur in an end case"); } return(regs[proj[se.id]]); //the current sybolic value of x }; iterassgn a = ist as iterassgn; if (a != null) { var v = expr_handler.Convert(a.rhs, idents1); regs[proj[stab.Get(a.lhs).id]] = v; } else { yieldstmt y = ist as yieldstmt; if (y != null) { foreach (var e in y.args) { strconst s = e as strconst; if (s == null) { yields.Add(expr_handler.Convert(e, idents1)); } else { foreach (int sc in s.content) { yields.Add(solver.MkNumeral(sc, charsort)); } } } } else { throw new BekException(); //TBD: undefined case } } } #endregion moves.Add(stb.MkFinalOutput(0, guard, yields.ToArray())); } } //if no end cases were given, assume default true end case with empty yield if (noEndCases) { moves.Add(stb.MkFinalOutput(0, solver.True)); } STModel iterST = STModel.Create(solver, "iter", initReg, charsort, charsort, regSort, 0, moves); iterST.Simplify(); return(iterST); }
public abstract S Convert(iterexpr ie, Symtab stab);