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);
        }
        STb <FuncDecl, Expr, Sort> GenerateDecoder()
        {
            var ctx = _automataCtx.Z3;

            Expr inputVar    = _automataCtx.MkVar(0, ctx.BoolSort);
            Expr registerVar = _automataCtx.MkVar(1, _automataCtx.MkTupleSort());
            Sort outputSort  = ctx.MkBitVecSort(8);
            var  stb         = new STb <FuncDecl, Expr, Sort>(_automataCtx, DeclarationType.Name, inputVar.Sort, outputSort, registerVar.Sort, _automataCtx.MkTuple(), 0);

            int nextState = 0;
            var states    = new Dictionary <HuffmanDecision, int>();

            PreOrder(_tree, node =>
            {
                var decision = node as HuffmanDecision;
                if (decision != null)
                {
                    states.Add(decision, nextState++);
                }
            });
            Func <HuffmanNode, BaseRule <Expr> > getBaseRule = node =>
            {
                var decision = node as HuffmanDecision;
                if (decision != null)
                {
                    return(new BaseRule <Expr>(Sequence <Expr> .Empty, registerVar, states[decision]));
                }
                else
                {
                    var leaf = (HuffmanLeaf)node;
                    return(new BaseRule <Expr>(new Sequence <Expr>(ctx.MkBV(leaf.Symbol, 8)), registerVar, 0));
                }
            };

            PreOrder(_tree, node =>
            {
                var decision = node as HuffmanDecision;
                if (decision != null)
                {
                    stb.AssignRule(states[decision], new IteRule <Expr>(inputVar, getBaseRule(decision.Left), getBaseRule(decision.Right)));
                    stb.AssignFinalRule(states[decision], new BaseRule <Expr>(Sequence <Expr> .Empty, registerVar, states[decision]));
                }
            });

            if (ShowGraphStages.Count > 0)
            {
                stb.ToST().ShowGraph();
            }
            return(stb);
        }
示例#3
0
 internal STbMinimizer(STb <FUNC, TERM, SORT> stb)
 {
     this.stb = stb;
     this.st  = stb.ToST();
 }
示例#4
0
        STb <FuncDecl, Expr, Sort> Generate()
        {
            var name = DeclarationType.ContainingNamespace.Name + "." +
                       (DeclarationType.ContainingType == null ? "" : DeclarationType.ContainingType.Name + ".") + DeclarationType.Name;

            Console.WriteLine("XPath " + name);

            var        parser = new XPathParser <IXPathNode>();
            IXPathNode root;

            try
            {
                root = parser.Parse(_xpath, new XPathNodeBuilder());
                Console.WriteLine(root);
            }
            catch (XPathParserException e)
            {
                throw new TransducerCompilationException("XPath parsing failed", e);
            }

            var resultSort       = _ctx.MkBitVecSort(32);
            var levelCounterSort = _ctx.MkBitVecSort(32);
            var regSort          = _ctx.MkTupleSort(resultSort, levelCounterSort);
            var initReg          = _ctx.MkTuple(_ctx.MkNumeral(0, resultSort), _ctx.MkNumeral(0, levelCounterSort));

            var        stb       = new STb <FuncDecl, Expr, Sort>(_ctx, "stb", _ctx.CharSort, _ctx.MkBitVecSort(32), regSort, initReg, 0);
            int        freeState = 1;
            Func <int> nextState = () => freeState++;

            var resultProj       = _ctx.MkProj(0, stb.RegVar);
            var levelCounterProj = _ctx.MkProj(1, stb.RegVar);

            Func <int, IgnorerInfo> CreateIgnorer = (exitState) =>
            {
                IgnorerInfo info = new IgnorerInfo();

                int outsideTagState    = nextState();
                int freshTagState      = nextState();
                int openingTagState    = nextState();
                int standaloneTagState = nextState();
                int closingTagState    = nextState();

                stb.AssignRule(outsideTagState,
                               new IteRule <Expr>(EqualsChar(stb.InputVar, '<'),
                                                  new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, freshTagState),
                                                  new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, outsideTagState)));

                stb.AssignRule(freshTagState,
                               new IteRule <Expr>(EqualsChar(stb.InputVar, '/'),
                                                  new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, closingTagState),
                                                  new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, openingTagState)));

                var counterOne      = _ctx.MkNumeral(1, levelCounterSort);
                var levelCounterInc = _ctx.MkTuple(resultProj, _ctx.MkBvAdd(levelCounterProj, counterOne));
                stb.AssignRule(openingTagState,
                               new IteRule <Expr>(EqualsChar(stb.InputVar, '>'),
                                                  new BaseRule <Expr>(Sequence <Expr> .Empty, levelCounterInc, outsideTagState),
                                                  new IteRule <Expr>(EqualsChar(stb.InputVar, '/'),
                                                                     new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, standaloneTagState),
                                                                     new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, openingTagState))));

                var counterZero        = _ctx.MkNumeral(0, levelCounterSort);
                var levelCounterZeroed = _ctx.MkTuple(resultProj, counterZero);
                stb.AssignRule(standaloneTagState,
                               new IteRule <Expr>(EqualsChar(stb.InputVar, '>'),
                                                  new IteRule <Expr>(_ctx.MkEq(levelCounterProj, counterZero),
                                                                     new BaseRule <Expr>(Sequence <Expr> .Empty, levelCounterZeroed, exitState),
                                                                     new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, outsideTagState)),
                                                  new IteRule <Expr>(EqualsChar(stb.InputVar, '/'),
                                                                     new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, standaloneTagState),
                                                                     new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, openingTagState))));

                var levelCounterDec = _ctx.MkTuple(resultProj, _ctx.MkBvSub(levelCounterProj, counterOne));
                stb.AssignRule(closingTagState,
                               new IteRule <Expr>(EqualsChar(stb.InputVar, '>'),
                                                  new IteRule <Expr>(_ctx.MkEq(levelCounterProj, counterOne),
                                                                     new BaseRule <Expr>(Sequence <Expr> .Empty, levelCounterZeroed, exitState),
                                                                     new BaseRule <Expr>(Sequence <Expr> .Empty, levelCounterDec, outsideTagState)),
                                                  new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, closingTagState)));

                info.MoveToTagOpening             = new BaseRule <Expr>(Sequence <Expr> .Empty, levelCounterZeroed, openingTagState);
                info.MoveToTagOpeningOrStandalone = new IteRule <Expr>(EqualsChar(stb.InputVar, '/'),
                                                                       new BaseRule <Expr>(Sequence <Expr> .Empty, levelCounterZeroed, standaloneTagState),
                                                                       info.MoveToTagOpening);
                var levelCounterSet = _ctx.MkTuple(resultProj, counterOne);
                info.MoveToOutsideTag = new BaseRule <Expr>(Sequence <Expr> .Empty, levelCounterSet, outsideTagState);

                return(info);
            };

            var next        = root;
            int?parentState = null;
            int startState  = stb.InitialState;
            int childState  = nextState();
            var zeroResult  = _ctx.MkTuple(_ctx.MkNumeral(0, resultSort), levelCounterProj);

            while (next != null)
            {
                XPathAxisNode current;
                var           step = next as XPathStepNode;
                if (step != null)
                {
                    current = step.Left as XPathAxisNode;
                    next    = step.Right;
                }
                else
                {
                    current = next as XPathAxisNode;
                    next    = null;
                }

                if (current.Axis == XPathAxis.Root)
                {
                    continue;
                }

                if (current == null)
                {
                    throw new TransducerCompilationException("Unsupported XPath node type: " + next.GetType());
                }
                if (current.Axis != XPathAxis.Child)
                {
                    throw new TransducerCompilationException("Unsupported axis: " + current.Axis);
                }
                if (current.Type != System.Xml.XPath.XPathNodeType.Element)
                {
                    throw new TransducerCompilationException("Unsupported node type: " + current.Type);
                }

                int freshTagState             = nextState();
                int closingTagState           = nextState();
                int standaloneMatchState      = nextState();
                int matchedOpeningTagState    = nextState();
                int matchedStandaloneTagState = nextState();
                var ignorer = CreateIgnorer(startState);

                stb.AssignRule(startState,
                               new IteRule <Expr>(EqualsChar(stb.InputVar, '<'),
                                                  new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, freshTagState),
                                                  new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, startState)));

                int  matchState     = freshTagState;
                int  nextMatchState = nextState();
                bool first          = true;
                foreach (char c in current.Label)
                {
                    STbRule <Expr> matchRule;

                    if (first)
                    {
                        matchRule = new IteRule <Expr>(EqualsChar(stb.InputVar, '/'),
                                                       new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, closingTagState),
                                                       new IteRule <Expr>(EqualsChar(stb.InputVar, c),
                                                                          new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, nextMatchState),
                                                                          new IteRule <Expr>(EqualsChar(stb.InputVar, '>'),
                                                                                             ignorer.MoveToOutsideTag,
                                                                                             ignorer.MoveToTagOpening)));
                        first = false;
                    }
                    else
                    {
                        matchRule = new IteRule <Expr>(EqualsChar(stb.InputVar, c),
                                                       new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, nextMatchState),
                                                       new IteRule <Expr>(EqualsChar(stb.InputVar, '>'),
                                                                          ignorer.MoveToOutsideTag,
                                                                          ignorer.MoveToTagOpeningOrStandalone));
                    }

                    stb.AssignRule(matchState, matchRule);
                    matchState     = nextMatchState;
                    nextMatchState = nextState();
                }

                stb.AssignRule(closingTagState,
                               new IteRule <Expr>(EqualsChar(stb.InputVar, '>'),
                                                  parentState != null ? (STbRule <Expr>) new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, parentState.Value) : new UndefRule <Expr>(),
                                                  new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, closingTagState)));

                stb.AssignRule(matchState,
                               new IteRule <Expr>(EqualsChar(stb.InputVar, '>'),
                                                  new BaseRule <Expr>(Sequence <Expr> .Empty, zeroResult, childState),
                                                  new IteRule <Expr>(EqualsChar(stb.InputVar, ' '),
                                                                     new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, matchedOpeningTagState),
                                                                     new IteRule <Expr>(EqualsChar(stb.InputVar, '/'),
                                                                                        new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, standaloneMatchState),
                                                                                        ignorer.MoveToTagOpening))));

                stb.AssignRule(standaloneMatchState,
                               new IteRule <Expr>(EqualsChar(stb.InputVar, '>'),
                                                  new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, startState),
                                                  new UndefRule <Expr>()));

                stb.AssignRule(matchedOpeningTagState,
                               new IteRule <Expr>(EqualsChar(stb.InputVar, '>'),
                                                  new BaseRule <Expr>(Sequence <Expr> .Empty, zeroResult, childState),
                                                  new IteRule <Expr>(EqualsChar(stb.InputVar, '/'),
                                                                     new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, matchedStandaloneTagState),
                                                                     new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, matchedOpeningTagState))));

                stb.AssignRule(matchedStandaloneTagState,
                               new IteRule <Expr>(EqualsChar(stb.InputVar, '>'),
                                                  new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, startState),
                                                  new IteRule <Expr>(EqualsChar(stb.InputVar, '/'),
                                                                     new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, matchedStandaloneTagState),
                                                                     new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, matchedOpeningTagState))));

                parentState = startState;
                startState  = childState;
                childState  = nextState();
            }

            Func <Expr, Expr> AddZeros = (c) =>
            {
                uint k = (uint)(32 - (int)_ctx.CharSetProvider.Encoding);
                if (k == 0)
                {
                    return(c);
                }
                else
                {
                    return(_ctx.MkZeroExt(k, c));
                }
            };
            var toIntUpdate = _ctx.MkTuple(
                _ctx.MkBvAdd(_ctx.MkBvMul(_ctx.MkNumeral(10, resultSort), resultProj), _ctx.MkBvSub(AddZeros(stb.InputVar), _ctx.MkNumeral((int)'0', resultSort))),
                levelCounterProj);

            var expectSlashState = nextState();
            var scanTagState     = nextState();

            stb.AssignRule(startState,
                           new IteRule <Expr>(EqualsChar(stb.InputVar, '<'),
                                              new BaseRule <Expr>(new Sequence <Expr>(resultProj), zeroResult, expectSlashState),
                                              new BaseRule <Expr>(Sequence <Expr> .Empty, toIntUpdate, startState)));

            stb.AssignRule(expectSlashState,
                           new IteRule <Expr>(EqualsChar(stb.InputVar, '/'),
                                              new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, scanTagState),
                                              new UndefRule <Expr>()));

            stb.AssignRule(scanTagState,
                           new IteRule <Expr>(EqualsChar(stb.InputVar, '>'),
                                              parentState != null ? (STbRule <Expr>) new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, parentState.Value) : new UndefRule <Expr>(),
                                              new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, scanTagState)));

            Console.WriteLine(stb.StateCount);

            foreach (var state in stb.States)
            {
                stb.AssignFinalRule(state, new BaseRule <Expr>(Sequence <Expr> .Empty, stb.RegVar, state));
            }

            if (ShowGraphStages.Count > 0)
            {
                stb.ToST().ShowGraph();
            }
            return(stb);
        }
        STb <FuncDecl, Expr, Sort> GenerateSTb()
        {
            var name = DeclarationType.ContainingNamespace.Name + "." +
                       (DeclarationType.ContainingType == null ? "" : DeclarationType.ContainingType.Name + ".") + DeclarationType.Name;

            Console.WriteLine("Exploring " + name);

            Expr    inputVar    = _info.AutomataCtx.MkVar(0, Mapper.GetSortMapping(_transducerType.TypeArguments[0]).Sort);
            Expr    registerVar = _info.AutomataCtx.MkVar(1, Mapper.GetSortMapping(DeclarationType).Sort);
            Mutator register    = Mapper.GetSortMapping(DeclarationType).MutatorForValue(registerVar);

            var methods = DeclarationType.DeclaringSyntaxReferences.Select(r => r.GetSyntax())
                          .SelectMany(s => s.DescendantNodes(n => !(n is MethodDeclarationSyntax)))
                          .OfType <MethodDeclarationSyntax>().Select(Syntax => new { Syntax, Symbol = Model.GetDeclaredSymbol(Syntax) as IMethodSymbol })
                          .Where(x => x.Symbol != null);

            // Find the Update function
            var updateMethods = methods.Where(x => x.Symbol.MetadataName == "Update" && x.Symbol.IsOverride &&
                                              x.Symbol.Parameters.Length == 1 && x.Symbol.Parameters[0].Type == InputTypeSymbol).ToArray();

            if (updateMethods.Length == 0)
            {
                throw new SyntaxErrorException("No IEnumerable<" + OutputTypeSymbol + "> Update(" + InputTypeSymbol + ") method declared");
            }
            else if (updateMethods.Length > 1)
            {
                throw new SyntaxErrorException("Multiple Update methods declared");
            }
            var updateMethod = updateMethods[0];
            // Explore the Update function
            var updateCfg = new ControlFlowGraph(updateMethod.Syntax.Body, Model);
            Dictionary <ISymbol, Mutator> parameters = updateMethod.Symbol.Parameters
                                                       .ToDictionary(p => (ISymbol)p, p => Mapper.GetSortMapping(_transducerType.TypeArguments[0]).MutatorForValue(inputVar));
            var updateEntryState = new MainExplorationState(_info, updateCfg.EntryPoint, register, parameters, new[] { inputVar, registerVar });
            var updateRule       = updateEntryState.Explore();

            // Find the Finish function
            var finishMethods = methods.Where(x => x.Symbol.MetadataName == "Finish" && x.Symbol.IsOverride &&
                                              x.Symbol.Parameters.Length == 0).ToArray();
            STbRule <Expr> finishRule;

            if (finishMethods.Length == 0)
            {
                finishRule = new BaseRule <Expr>(Sequence <Expr> .Empty, register.CreateUpdate(), 0);
            }
            else
            {
                if (finishMethods.Length > 1)
                {
                    throw new SyntaxErrorException("Multiple Finish methods declared");
                }
                var finishMethod = finishMethods[0];
                // Explore the Finish function
                var finishCfg        = new ControlFlowGraph(finishMethod.Syntax.Body, Model);
                var finishEntryState = new MainExplorationState(_info, finishCfg.EntryPoint, register, new Dictionary <ISymbol, Mutator>(), new[] { registerVar });
                finishRule = finishEntryState.Explore();
            }

            var outputSort = Mapper.GetSortMapping(_transducerType.TypeArguments[1]).Sort;
            var stb        = new STb <FuncDecl, Expr, Sort>(_info.AutomataCtx, DeclarationType.Name, inputVar.Sort, outputSort, registerVar.Sort,
                                                            Mapper.GetSortMapping(DeclarationType).MutatorForDefaultValue().CreateUpdate().SafeSimplify(Ctx), 0);

            stb.AssignRule(0, updateRule);
            stb.AssignFinalRule(0, finishRule);

            if (ShowGraphStages.Contains(ShowGraph.Stage.UnSimplified))
            {
                stb.ShowGraph();
            }
            stb = stb.Flatten();
            if (ShowGraphStages.Contains(ShowGraph.Stage.Simplified))
            {
                stb.ToST().ShowGraph();
            }
            return(stb);
        }