private BranchingRule <TERM> EvalB(ConsList <TERM> inputs, int qA, TERM regA, TERM pathCond, int qB, TERM regB, Func <int, int, int> stateComposer, Sequence <TERM> outputFromB, bool isFinal) { if (inputs == null) { int qAB = stateComposer(qA, qB); if (isFinal) { var fr = B.GetFinalRuleFrom(qB); if (fr.IsNotUndef) { return(this.CreateFinalComposedRule(pathCond, qAB, outputFromB, fr, regB)); } else { return(UndefRule <TERM> .Default); } } else { TERM regAB = (regA.Equals(regVar_1) && regB.Equals(regVar_2) ? regVar : JoinRegs(regA, regB)); var res = new BaseRule <TERM>(outputFromB, regAB, qAB); return(res); } } else { return(EvalB_Rule(B.GetRuleFrom(qB), qA, regA, pathCond, inputs, regB, stateComposer, outputFromB, isFinal)); } }
public STb <F, T, S> Mk(string regex, params Tuple <string, STb <F, T, S> >[] args) { var K = args.Length; bool isLoop; var patternAutomataPairs = solver.CharSetProvider.ConvertCaptures(regex, out isLoop); var captureAutomata = new Dictionary <string, Automaton <BDD> >(); var stbs = new Dictionary <string, STb <F, T, S> >(); foreach (var arg in args) { if (stbs.ContainsKey(arg.Item1) || string.IsNullOrEmpty(arg.Item1)) { throw new AutomataException(AutomataExceptionKind.InvalidArguments); } stbs[arg.Item1] = arg.Item2; } foreach (var pair in patternAutomataPairs) { if (pair.Item1 != "") { captureAutomata[pair.Item1] = pair.Item2; } } var captureSortPos = new Dictionary <string, int>(); var captureSortName = new Dictionary <string, string>(); for (int i = 0; i < args.Length; i += 1) { captureSortName[args[i].Item1] = args[i].Item2.OutputSort.ToString(); captureSortPos[args[i].Item1] = i; } if (Array.Exists(patternAutomataPairs, pair => (pair.Item1 != "" && !captureSortName.ContainsKey(pair.Item1)))) { throw new AutomataException(AutomataExceptionKind.InvalidArguments); } S[] argSorts = new S[K]; for (int i = 0; i < K; i++) { if (!captureAutomata.ContainsKey(args[i].Item1)) { throw new AutomataException(AutomataExceptionKind.InvalidArguments); } if (!args[i].Item2.OutputSort.Equals(args[i].Item2.RegisterSort)) { throw new AutomataException(AutomataExceptionKind.InvalidArguments); } argSorts[i] = args[i].Item2.OutputSort; } var regSort = solver.MkTupleSort(argSorts); var regVar = solver.MkVar(1, regSort); var initReg = solver.MainSolver.FindOneMember(solver.MkEq(regVar, regVar)).Value; var inpVar = solver.MkVar(0, solver.CharSort); var stb = new STb <F, T, S>(solver, "stb", solver.CharSort, regSort, regSort, initReg, 0); var nextStateId = 0; var stateIdMap = new Dictionary <Tuple <int, int, int>, int>(); Func <int, int, int, int> MkState = (n, q1, q2) => { int p; var nq = new Tuple <int, int, int>(n, q1, q2); if (stateIdMap.TryGetValue(nq, out p)) { return(p); } else { p = nextStateId; nextStateId += 1; stateIdMap[nq] = p; return(p); } }; var resSTB = new STb <F, T, S>(solver, "STB", solver.CharSort, solver.CharSort, solver.UnitSort, solver.UnitConst, 0); resSTB.AssignRule(0, new BaseRule <T>(new Sequence <T>(solver.MkCharVar(0)), solver.UnitConst, 0)); resSTB.AssignFinalRule(0, new BaseRule <T>(Sequence <T> .Empty, solver.UnitConst, 0)); for (int i = 0; i < patternAutomataPairs.Length; i++) { var aut = patternAutomataPairs[i].Item2; if (patternAutomataPairs[i].Item1 == "") { var autSTMoves = new List <Move <Rule <T> > >(); foreach (var move in aut.GetMoves()) { //move cannot be epsilon here var cond = solver.ConvertFromCharSet(move.Label); autSTMoves.Add(Move <Rule <T> > .Create(move.SourceState, move.TargetState, Rule <T> .Mk(cond, solver.UnitConst))); } foreach (var f in aut.GetFinalStates()) { //collect guards of all moves exitingfrom f var allGuardsFromF = solver.CharSetProvider.False; foreach (var fmove in aut.GetMovesFrom(f)) { allGuardsFromF = solver.CharSetProvider.MkOr(allGuardsFromF, fmove.Label); } var elseFromF = solver.ConvertFromCharSet(solver.CharSetProvider.MkNot(allGuardsFromF)); autSTMoves.Add(Move <Rule <T> > .Create(f, f, Rule <T> .Mk(elseFromF, solver.UnitConst, solver.MkCharVar(0)))); autSTMoves.Add(Move <Rule <T> > .Create(f, f, Rule <T> .MkFinal(solver.True))); } var autST = ST <F, T, S> .Create(solver, patternAutomataPairs[i].Item1, solver.UnitConst, solver.CharSort, solver.CharSort, solver.UnitSort, aut.InitialState, autSTMoves); var autSTb = autST.ToSTb(); resSTB = resSTB.Compose(autSTb); } else { var stb1 = stbs[patternAutomataPairs[i].Item1]; if (!stb1.InputSort.Equals(solver.CharSort)) { throw new AutomataException(AutomataExceptionKind.InvalidArguments); } var autSTMoves = new List <Move <Rule <T> > >(); foreach (var move in aut.GetMoves()) { //move cannot be epsilon here var cond = solver.ConvertFromCharSet(move.Label); autSTMoves.Add(Move <Rule <T> > .Create(move.SourceState, move.TargetState, Rule <T> .Mk(cond, solver.UnitConst, inpVar))); } foreach (var f in aut.GetFinalStates()) { autSTMoves.Add(Move <Rule <T> > .Create(f, f, Rule <T> .MkFinal(solver.True))); } var autST = ST <F, T, S> .Create(solver, patternAutomataPairs[i].Item1, solver.UnitConst, solver.CharSort, solver.CharSort, solver.UnitSort, aut.InitialState, autSTMoves); var autSTb = autST.ToSTb(); var stb2 = autSTb.Compose(stb1); foreach (var f in stb.States) { var frule = stb.GetFinalRuleFrom(f); if (frule.IsNotUndef) { //var frule1 = } } } } throw new NotImplementedException(); }
public STb <FUNC, TERM, SORT> Minimize() { var s = stb.Solver; var alphaSort = s.MkOptionSort(stb.InputSort); var autoSort = s.MkTupleSort(alphaSort, stb.OutputListSort, stb.RegisterSort, stb.RegisterSort); var autoVar = s.MkVar(3, autoSort); var autoInput = s.MkProj(0, autoVar); var autoSomeInput = s.MkGetSomeValue(autoInput); var autoOutputList = s.MkProj(1, autoVar); var autoOldReg = s.MkProj(2, autoVar); var autoNewReg = s.MkProj(3, autoVar); Func <TERM, TERM> finalSubstitute = (t) => s.ApplySubstitution(t, stb.RegVar, autoOldReg); Func <TERM, TERM> nonFinalSubstitute = (t) => finalSubstitute(s.ApplySubstitution(t, stb.InputVar, autoSomeInput)); int acceptingState = stb.States.Max() + 1; int errorState = stb.States.Max() + 2; var moves = new List <Move <TERM> >(); foreach (var state in stb.States) { var nonFinalConds = new List <TERM>(); foreach (var nonFinal in st.GetNonFinalMovesFrom(state)) { var rule = nonFinal.Label; var conds = new List <TERM>(); conds.Add(s.MkIsSome(autoInput)); conds.Add(nonFinalSubstitute(rule.Guard)); var outputList = autoOutputList; foreach (var yield in rule.Output) { conds.Add(s.MkIsCons(outputList)); conds.Add(s.MkEq(s.MkFirstOfList(outputList), nonFinalSubstitute(yield))); outputList = s.MkRestOfList(outputList); } conds.Add(s.MkIsNil(outputList)); conds.Add(s.MkEq(autoNewReg, nonFinalSubstitute(rule.Update))); var cond = s.MkAnd(conds); moves.Add(Move <TERM> .Create(state, nonFinal.TargetState, cond)); nonFinalConds.Add(cond); } var finalConds = new List <TERM>(); foreach (var rule in st.GetFinalRules(state)) { var conds = new List <TERM>(); conds.Add(s.MkIsNone(autoInput)); conds.Add(finalSubstitute(rule.Guard)); var outputList = autoOutputList; foreach (var yield in rule.Output) { conds.Add(s.MkIsCons(outputList)); conds.Add(s.MkEq(s.MkFirstOfList(outputList), finalSubstitute(yield))); outputList = s.MkRestOfList(outputList); } conds.Add(s.MkIsNil(outputList)); var cond = s.MkAnd(conds); moves.Add(Move <TERM> .Create(state, acceptingState, cond)); finalConds.Add(cond); } } //moves.Add(Move<TERM>.Create(errorState, errorState, s.True)); var auto = Automaton <TERM> .Create(stb.Solver, stb.InitialState, new int[] { acceptingState }, moves); auto.CheckDeterminism(stb.Solver); var blocks = auto.BookkeepingMinimize(stb.Solver); Func <STbRule <TERM>, STbRule <TERM> > redirect = null; redirect = r => { switch (r.RuleKind) { case STbRuleKind.Undef: return(r); case STbRuleKind.Base: return(new BaseRule <TERM>(r.Yields, r.Register, blocks[r.State].GetRepresentative())); case STbRuleKind.Ite: var t = redirect(r.TrueCase); var f = redirect(r.FalseCase); return(new IteRule <TERM>(r.Condition, t, f)); default: throw new NotImplementedException(); } }; var minimized = new STb <FUNC, TERM, SORT>(stb.Solver, stb.Name + "_min", stb.InputSort, stb.OutputSort, stb.RegisterSort, stb.InitialRegister, blocks[stb.InitialState].GetRepresentative()); var representatives = new HashSet <int>(); foreach (var state in stb.States) { representatives.Add(blocks[state].GetRepresentative()); } foreach (var state in representatives) { minimized.AssignRule(state, redirect(stb.GetRuleFrom(state)).CollapseRedundantITEs(s)); minimized.AssignFinalRule(state, redirect(stb.GetFinalRuleFrom(state)).CollapseRedundantITEs(s)); } return(minimized); }
public STb <FUNC, TERM, SORT> Compose() { var stack = new SimpleStack <Tuple <int, int> >(); int stateId = 1; var stateIdMap = new Dictionary <Tuple <int, int>, int>(); var revStateIdMap = new Dictionary <int, Tuple <int, int> >(); var q0A_x_q0B = new Tuple <int, int>(A.InitialState, B.InitialState); stack.Push(q0A_x_q0B); stateIdMap[q0A_x_q0B] = 0; revStateIdMap[0] = q0A_x_q0B; Func <int, int, int> ComposeStates = (x, y) => { var xy = new Tuple <int, int>(x, y); int q; if (stateIdMap.TryGetValue(xy, out q)) { return(q); } else { q = stateId; stateId += 1; stateIdMap[xy] = q; revStateIdMap[q] = xy; stack.Push(xy); return(q); } }; var A2B = new STb <FUNC, TERM, SORT>(solver, A.Name + "2" + B.Name, A.InputSort, B.OutputSort, regSort, JoinRegs(A.InitialRegister, B.InitialRegister), 0); //create normal composed rules while (stack.IsNonempty) { var qA_x_qB = stack.Pop(); var qA = qA_x_qB.Item1; var qB = qA_x_qB.Item2; var ruleA = A.GetRuleFrom(qA); if (ruleA.IsNotUndef) { var qAB_rule = Comp(solver.True, ruleA, qB, ComposeStates, false); A2B.AssignRule(stateIdMap[qA_x_qB], qAB_rule); } else { A2B.AssignRule(stateIdMap[qA_x_qB], UndefRule <TERM> .Default); } } foreach (var qAB in A2B.States) { var qA_x_qB = revStateIdMap[qAB]; var qA = qA_x_qB.Item1; var qB = qA_x_qB.Item2; var ruleA = A.GetFinalRuleFrom(qA); if (ruleA.IsNotUndef) { var qAB_Frule = Comp(solver.True, ruleA, qB, (p, q) => qAB, true); A2B.AssignFinalRule(qAB, qAB_Frule); } } A2B.EliminateDeadends(); //Func<Rule<TERM>, Rule<TERM>> ReplaceWithEpsilon = (r) => // { // }; //var aut = A2B.ToST(true).automaton.RelpaceAllGuards(ReplaceWithEpsilon); return(A2B); }
static public ComputationTree ToComputationTrees(STb <FuncDecl, Expr, Sort> stb, bool includeOutput) { var ctx = ((Z3Provider)stb.Solver).Z3; var states = stb.States.Select((State, Index) => new { State, Index, Name = "S" + State }); var csEnumSort = ctx.IntSort; var outputListSort = stb.OutputListSort as ListSort; var resultSort = ctx.MkTupleSort(ctx.MkSymbol(stb.Name + "#STATE"), new[] { ctx.MkSymbol("#CS"), ctx.MkSymbol("#OUT"), ctx.MkSymbol("#VARS") }, new[] { csEnumSort, outputListSort, stb.RegisterSort }); var csField = resultSort.FieldDecls[0]; var outputField = resultSort.FieldDecls[1]; var registerField = resultSort.FieldDecls[2]; var inputVar = stb.Solver.MkVar(0, stb.InputSort); var registerVar = stb.Solver.MkVar(1, stb.RegisterSort); var computationVar = stb.Solver.MkVar(2, resultSort); var csProjection = csField.Apply(computationVar); var outputProjection = outputField.Apply(computationVar); var registerProjection = registerField.Apply(computationVar); Func <int, Expr[], Expr, Expr> createResult = (state, yields, register) => { Expr output; if (includeOutput) { output = yields.Length == 0 ? outputProjection : ctx.MkFuncDecl("Append", new Sort[] { outputListSort, outputListSort }, outputListSort).Apply( outputProjection, ctx.MkFuncDecl("List", yields.Select(x => x.Sort).ToArray(), outputListSort).Apply(yields)); } else { output = outputProjection; } var result = resultSort.MkDecl.Apply( ctx.MkInt(state), output, register != null ? register : registerProjection); return(result.Substitute(registerVar, registerProjection)); }; ComputationNode ruleNode; var stateComps = stb.States.Select(State => new { State, Computation = ToComputationTree(ctx, stb.GetRuleFrom(State), registerVar, registerProjection, createResult) }).ToList(); if (stateComps.Count == 0) { ruleNode = new UndefinedNode(); } else { ruleNode = new SwitchNode(stateComps.Select(x => ctx.MkEq(csProjection, ctx.MkInt(x.State))).ToArray(), stateComps.Select(x => x.Computation).ToArray()); } ComputationNode finalNode; var finalComps = stb.States.Where(s => stb.IsFinalState(s)) .Select(State => new { State, Computation = ToComputationTree(ctx, stb.GetFinalRuleFrom(State), registerVar, registerProjection, createResult) }).ToList(); if (finalComps.Count == 0) { finalNode = new UndefinedNode(); } else { finalNode = new SwitchNode(finalComps.Select(x => ctx.MkEq(csProjection, ctx.MkInt(x.State))).ToArray(), finalComps.Select(x => x.Computation).ToArray()); } var initialState = resultSort.MkDecl.Apply( ctx.MkInt(stb.InitialState), outputListSort.Nil, stb.InitialRegister); return(new ComputationTree { Move = ruleNode, Finish = finalNode, InitialState = initialState, EnumSorts = new EnumSort[] { }, }); }