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)); } }
int TotalIteRules(STb <FuncDecl, Expr, Sort> stb) { int count = 0; foreach (var state in stb.States) { var rule = stb.GetRuleFrom(state); count += IteRules(rule); } return(count); }
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[] { }, }); }