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);
        }
示例#2
0
        // 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
        }
示例#3
0
        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();
        }