STb <FuncDecl, Expr, Sort> GenerateEncoder() { var ctx = _automataCtx.Z3; Expr inputVar = _automataCtx.MkVar(0, ctx.MkBitVecSort(8)); Expr registerVar = _automataCtx.MkVar(1, _automataCtx.MkTupleSort()); Sort outputSort = ctx.BoolSort; var stb = new STb <FuncDecl, Expr, Sort>(_automataCtx, DeclarationType.Name, inputVar.Sort, outputSort, registerVar.Sort, _automataCtx.MkTuple(), 0); var leafPatterns = new Dictionary <byte, bool[]>(); FindLeafPatterns(leafPatterns, _tree, new Stack <bool>()); var patterns = new bool[256][]; foreach (var entry in leafPatterns) { patterns[entry.Key] = entry.Value; } Debug.Assert(patterns.Select((x, i) => patterns.Select((y, j) => i == j || x.Length != y.Length || x.Zip(y, (a, b) => Tuple.Create(a, b)).Any(z => z.Item1 != z.Item2)).All(z => z)).All(z => z)); Debug.Assert(patterns.All(x => x != null), "Internal Huffman tree is missing leaves"); stb.AssignRule(0, GetBinarySearchRule(ctx, (BitVecExpr)inputVar, registerVar, patterns, 0, patterns.Length)); stb.AssignFinalRule(0, new BaseRule <Expr>(Sequence <Expr> .Empty, registerVar, 0)); stb = stb.Compose(GenerateToBytes()); stb = stb.ExploreBools(); if (ShowGraphStages.Count > 0) { stb.ToST().ShowGraph(); } return(stb); }
// Flatten the register structure public static STb <FuncDecl, Expr, Sort> Flatten(this STb <FuncDecl, Expr, Sort> stb) { var boolDummy = new STb <FuncDecl, Expr, Sort>(stb.Solver, "BoolDummy", stb.OutputSort, stb.OutputSort, stb.Solver.BoolSort, stb.Solver.True, 0); boolDummy.AssignRule(0, new BaseRule <Expr>(new Sequence <Expr>(boolDummy.InputVar), boolDummy.RegVar, 0)); boolDummy.AssignFinalRule(0, new BaseRule <Expr>(Sequence <Expr> .Empty, boolDummy.RegVar, 0)); var composed = stb.Compose(boolDummy); // Compose with the "dummy" to ensure there is something to eliminate composed.Name = stb.Name; var explored = composed.ExploreBools(); // Explore bools will flatten when there is something to eliminate return(explored); // TODO: implement in a less round about way }
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(); }