Represents a definition of a datatype over a given set of ranked symbols and a given node sort.
示例#1
0
        /// <summary>
        /// Make a tree rule from the input alphabet to the output alphabet.
        /// </summary>
        /// <param name="inputAlphabet">input alphabet</param>
        /// <param name="outputAlphabet">output alphabet</param>
        /// <param name="state">source state</param>
        /// <param name="symbol">a ranked symbol of the input alphabet</param>
        /// <param name="guard">attribute guard</param>
        /// <param name="output">output tree</param>
        /// <param name="lookahead">domain restriction states</param>
        public TreeRule MkTreeRule(RankedAlphabet inputAlphabet, RankedAlphabet outputAlphabet, int state, string symbol, Expr guard, Expr output, params int[][] lookahead)
        {
            var A      = inputAlphabet;
            var B      = outputAlphabet;
            var constr = A.GetConstructor(symbol);

            CheckAttribute(guard, A);

            if (A.GetRank(symbol) != lookahead.Length)
            {
                throw new AutomataException(AutomataExceptionKind.TreeTheory_RankMismatch);
            }

            ExprSet[] la = new ExprSet[lookahead.Length];
            int       j  = 0;

            for (int i = 0; i < lookahead.Length; i++)
            {
                la[i] = new ExprSet();
                for (j = 0; j < lookahead[i].Length; j++)
                {
                    la[i].Add(Z.MkNumeral(lookahead[i][j], Z.IntSort));
                }
            }

            var outp = (output == null ? null : NormalizeOutput(output, A, B, A.GetRank(symbol)));

            return(new TreeRule(Z.MkInt(state), constr, guard, outp, la));
        }
示例#2
0
 public TreeRule MkTreeAcceptorRule(RankedAlphabet A, int top, string symbol, Expr guard, params int[] bottom)
 {
     int[][] lookahead = new int[bottom.Length][];
     for (int i = 0; i < bottom.Length; i++)
     {
         lookahead[i] = new int[] { bottom[i] }
     }
     ;
     return(MkTreeRule(A, A, top, symbol, guard, null, lookahead));
 }
示例#3
0
 private void CheckAttribute(Expr term, RankedAlphabet A)
 {
     //check that the term does not use any free varibales other than the attribute variable
     foreach (var v in Z.GetVars(term))
     {
         if (!v.Equals(A.AttrVar))
         {
             throw new AutomataException(AutomataExceptionKind.TreeTheory_UnexpectedVariable);
         }
     }
 }
示例#4
0
        /// <summary>
        /// Make a tree rule from the input alphabet to the output alphabet.
        /// </summary>
        /// <param name="inputAlphabet">input alphabet</param>
        /// <param name="outputAlphabet">output alphabet</param>
        /// <param name="state">source state</param>
        /// <param name="symbol">a ranked symbol of the input alphabet</param>
        /// <param name="guard">attribute guard</param>
        /// <param name="output">output tree</param>
        public TreeRule MkTreeRule(RankedAlphabet inputAlphabet, RankedAlphabet outputAlphabet, int state, string symbol, Expr guard, Expr output)
        {
            var A      = inputAlphabet;
            var B      = outputAlphabet;
            var constr = A.GetConstructor(symbol);

            CheckAttribute(guard, A);

            var outp = (output == null ? null : NormalizeOutput(output, A, B, A.GetRank(symbol)));

            return(new TreeRule(Z.MkInt(state), constr, guard, outp, A.GetRank(symbol)));
        }
示例#5
0
        /// <summary>
        /// Make an output term of applying the given state to the given child subtree.
        /// </summary>
        /// <param name="outputAlphabet">the output alphabet sort</param>
        /// <param name="state">the state from which the child is transduced</param>
        /// <param name="child">the accessor of the child, must be a positive integer between 1 and MaxRank</param>
        public Expr MkTrans(RankedAlphabet outputAlphabet, int state, int child)
        {
            var f = tt.GetTrans(AlphabetSort, outputAlphabet.AlphabetSort);
            var s = tt.Z.MkInt(state);

            if (child < 1 || child > MaxRank)
            {
                throw new AutomataException(AutomataExceptionKind.RankedAlphabet_ChildAccessorIsOutOufBounds);
            }
            var x   = ChildVar(child);
            var res = tt.Z.MkApp(f, s, x);

            return(res);
        }
示例#6
0
 //adds identity states when A=B and a child is ouput without transformation
 internal Expr NormalizeOutput(Expr t, RankedAlphabet A, RankedAlphabet B, int rank)
 {
     if (Z.IsVar(t))
     {
         if (Z.GetVarIndex(t) > rank || !t.Sort.Equals(A.AlphabetSort))
         {
             throw new AutomataException(AutomataExceptionKind.TreeTheory_UnexpectedVariable);
         }
         else
         {
             return(Z.MkApp(GetTrans(A.AlphabetSort, B.AlphabetSort), identityState, t));
         }
     }
     else if (t.ASTKind == Z3_ast_kind.Z3_APP_AST)
     {
         var f    = t.FuncDecl;
         var args = t.Args;
         if (B.ContainsConstructor(f))
         {
             CheckAttribute(args[0], A);
             var args1 = new Expr[args.Length];
             args1[0] = args[0];
             for (int j = 1; j < args.Length; j++)
             {
                 args1[j] = NormalizeOutput(args[j], A, B, rank);
             }
             return(Z.MkApp(f, args1));
         }
         else if (IsTrans(f))
         {
             if (args[0].ASTKind != Z3_ast_kind.Z3_NUMERAL_AST || !Z.IsVar(args[1]) || Z.GetVarIndex(args[1]) > rank || Z.GetVarIndex(args[1]) < 1)
             {
                 throw new AutomataException(AutomataExceptionKind.TreeTheory_UnexpectedVariable);
             }
             else
             {
                 return(t);
             }
         }
         else
         {
             throw new AutomataException(AutomataExceptionKind.TreeTheory_UnexpectedOutput);
         }
     }
     else
     {
         throw new AutomataException(AutomataExceptionKind.TreeTheory_UnexpectedOutput);
     }
 }
示例#7
0
        /// <summary>
        /// Make a new tree automaton or tree transducer.
        /// </summary>
        /// <param name="initStates">initial states</param>
        /// <param name="inputAlphabet">input alphabet</param>
        /// <param name="outputAlphabet">output alphabet</param>
        /// <param name="rules">rules of the automaton or transducer</param>
        /// <returns></returns>
        public TreeTransducer MkTreeAutomaton(IEnumerable <int> initStates, RankedAlphabet inputAlphabet, RankedAlphabet outputAlphabet, IEnumerable <TreeRule> rules)
        {
            foreach (var st in initStates)
            {
                if (st < 0)
                {
                    throw new AutomataException(AutomataExceptionKind.TreeTransducer_InvalidStateId);
                }
            }

            var stateList = new List <Expr>();
            var stateSet  = new HashSet <Expr>();
            var rulesList = new List <TreeRule>(rules);
            var q0_list   = new List <Expr>();

            foreach (var st in initStates)
            {
                q0_list.Add(Z.MkInt(st));
            }

            #region perform basic sanity checks
            foreach (var rule in rulesList)
            {
                if (rule.State.Equals(identityState))
                {
                    throw new AutomataException(AutomataExceptionKind.TreeTransducer_InvalidUseOfIdentityState);
                }
                if (stateSet.Add(rule.state))
                {
                    stateList.Add(rule.state);
                }
            }
            foreach (var rule in rulesList)
            {
                if (!rule.IsTrueForAllStates(st => (stateSet.Contains(st) || st.Equals(identityState))))
                {
                    throw new AutomataException(AutomataExceptionKind.TreeTransducer_InvalidStateId);
                }
            }
            #endregion

            var ta  = new TreeTransducer(q0_list, inputAlphabet, outputAlphabet, stateList, rulesList);
            var ta1 = ta.Clean();
            return(ta1);
        }
示例#8
0
        internal TreeRule MkIdRule(RankedAlphabet A)
        {
            if (!IsAcceptorRule)
            {
                throw new AutomataException(AutomataExceptionKind.MkIdRule_RuleIsNotAcceptorRule);
            }

            Expr[] args = new Expr[this.lookahead.Length + 1];
            args[0] = A.AttrVar;
            for (int i = 1; i <= this.lookahead.Length; i++)
            {
                if (!(this.lookahead[i - 1].IsEmptyOrSingleton))
                {
                    throw new AutomataException(AutomataExceptionKind.MkIdRule_RuleIsNotFlat);
                }
                args[i] = (this.lookahead[i - 1].IsEmpty ? A.tt.Z.MkApp(A.Trans, A.tt.identityState, A.ChildVar(i))
                                                       : A.tt.Z.MkApp(A.Trans, this.lookahead[i - 1].SomeElement, A.ChildVar(i)));
            }
            var new_output = A.tt.Z.MkApp(symbol, args);
            var new_rule   = new TreeRule(this.state, this.symbol, this.guard, new_output, this.lookahead);

            return(new_rule);
        }
示例#9
0
        internal TreeRule MkIdRule(RankedAlphabet A)
        {
            if (!IsAcceptorRule)
                throw new AutomataException(AutomataExceptionKind.MkIdRule_RuleIsNotAcceptorRule);

            Expr[] args = new Expr[this.lookahead.Length + 1];
            args[0] = A.AttrVar;
            for (int i = 1; i <= this.lookahead.Length; i++)
            {
                if (!(this.lookahead[i-1].IsEmptyOrSingleton))
                    throw new AutomataException(AutomataExceptionKind.MkIdRule_RuleIsNotFlat);
                args[i] = (this.lookahead[i-1].IsEmpty ? A.tt.Z.MkApp(A.Trans, A.tt.identityState, A.ChildVar(i))
                                                       : A.tt.Z.MkApp(A.Trans, this.lookahead[i-1].SomeElement, A.ChildVar(i)));
            }
            var new_output = A.tt.Z.MkApp(symbol, args);
            var new_rule = new TreeRule(this.state, this.symbol, this.guard, new_output, this.lookahead);
            return new_rule;
        }
        public RankedAlphabetSort(AlphabetDef def, Z3Provider z3p, FastTransducerInstance fti)
        {
            this.z3p = z3p;

            List<string> alphSymbols = new List<string>();
            List<int> alphArities = new List<int>();

            // Create list of symbols with corresponding arities
            foreach (var sym in def.symbols)
            {
                alphSymbols.Add(sym.name.text);
                alphArities.Add(sym.arity - 1);
            }

            alphFieldsSorts = new List<Sort>();
            tupleKeys = new List<String>();

            foreach (var field in def.attrSort.fieldSorts)
            {
                tupleKeys.Add(field.Key);
                switch (field.Value.kind)
                {
                    case (FastSortKind.Char):
                        {
                            alphFieldsSorts.Add(z3p.CharSort);
                            break;
                        }
                    case (FastSortKind.Real):
                        {
                            alphFieldsSorts.Add(z3p.RealSort);
                            break;
                        }
                    case (FastSortKind.Bool):
                        {
                            alphFieldsSorts.Add(z3p.BoolSort);
                            break;
                        }
                    case (FastSortKind.Int):
                        {
                            alphFieldsSorts.Add(z3p.IntSort);
                            break;
                        }
                    case (FastSortKind.String):
                        {
                            alphFieldsSorts.Add(z3p.MkListSort(z3p.CharSort));
                            break;
                        }
                    case (FastSortKind.Tree):
                        {
                            foreach (var enumSort in fti.enums)
                            {
                                if (enumSort.name == field.Value.name.text)
                                {
                                    alphFieldsSorts.Add(enumSort.sort);
                                    break;
                                }
                            }
                            break;
                        }
                }
            }

            this.tupleName = "$" + def.id.text;
            this.tupleTests = new FuncDecl[alphFieldsSorts.Count];
            var tupsymbs = new Symbol[tupleKeys.Count];
            int j = 0;
            foreach(var v in tupleKeys){
                tupsymbs[j]= z3p.Z3.MkSymbol(v);
                j++;
            }
            var tup = z3p.Z3.MkTupleSort(z3p.Z3.MkSymbol(tupleName), tupsymbs, alphFieldsSorts.ToArray());
            this.tupleSort = tup;
            this.tupleFuncDec = tup.MkDecl;
            this.tupleTests = tup.FieldDecls;

            this.alph = z3p.TT.MkRankedAlphabet(def.id.text, this.tupleSort, alphSymbols.ToArray(), alphArities.ToArray());
            this.alphName = def.id.text;
            this.alphSort = this.alph.AlphabetSort;
        }
示例#11
0
        /// <summary>
        /// Creates a ranked alphabet, a rank of a function symbol is the number of its children (subtrees).
        /// The rank excludes the node label. Thus, all function symbols have rank + 1 number of arguments.
        /// The first argument is always the attribute.
        /// </summary>
        /// <param name="name">alphabet name</param>
        /// <param name="attributeSort">attribute sort</param>
        /// <param name="symbols">function symbols of the alphabet</param>
        /// <param name="ranks">ranks of the function symbols</param>
        public RankedAlphabet MkRankedAlphabet(string name, Sort attributeSort, string[] symbols, int[] ranks)
        {
            #region validity checks
            if (string.IsNullOrWhiteSpace(name) || attributeSort == null || symbols == null || ranks == null || symbols.Length == 0 || ranks.Length == 0)
            {
                throw new AutomataException(AutomataExceptionKind.InvalidArguments);
            }

            var name_nodeSort = new Tuple <string, Sort>(name, attributeSort);
            if (rankedAlphabetSortMap.ContainsKey(name_nodeSort))
            {
                throw new AutomataException(AutomataExceptionKind.RankedAlphabet_IsAlreadyDefined);
            }

            if (symbols.Length != ranks.Length)
            {
                throw new AutomataException(AutomataExceptionKind.RankedAlphabet_IsInvalid);
            }

            Dictionary <string, int> idMap = new Dictionary <string, int>(symbols.Length);
            bool containsOneleaf           = false;
            int  maxrank = 0;
            for (int i = 0; i < symbols.Length; i++)
            {
                if (string.IsNullOrWhiteSpace(symbols[i]) || idMap.ContainsKey(symbols[i]) || ranks[i] < 0)
                {
                    throw new AutomataException(AutomataExceptionKind.RankedAlphabet_IsInvalid);
                }
                else
                {
                    idMap.Add(symbols[i], i);
                    containsOneleaf = (containsOneleaf || ranks[i] == 0);
                    maxrank         = (maxrank > ranks[i] ? maxrank : ranks[i]);
                }
            }
            if (!containsOneleaf)
            {
                throw new AutomataException(AutomataExceptionKind.RankedAlphabet_ContainsNoLeaf);
            }
            #endregion

            int K = symbols.Length;

            var fieldNames   = new string[K][];
            var fieldSorts   = new Sort[K][];
            var testerNames  = new string[K];
            var constructors = new Constructor[K];

            for (int i = 0; i < K; i++)
            {
                string symb  = symbols[i];
                int    arity = ranks[i] + 1;
                fieldNames[i] = new string[arity];
                fieldSorts[i] = new Sort[arity];
                var field_refs = new uint[arity];
                fieldSorts[i][0] = attributeSort;
                for (int j = 0; j < arity; j++)
                {
                    fieldNames[i][j] = symb + "@" + j;
                }
                constructors[i] = Z.z3.MkConstructor(symb, "$is" + symb, fieldNames[i], fieldSorts[i], field_refs);
            }

            Sort datatype = Z.z3.MkDatatypeSort(name, constructors);

            var constrs   = new FuncDecl[K];
            var accessors = new FuncDecl[K][];
            var testers   = new FuncDecl[K];

            for (int i = 0; i < K; i++)
            {
                constrs[i]   = constructors[i].ConstructorDecl;
                accessors[i] = constructors[i].AccessorDecls;
                testers[i]   = constructors[i].TesterDecl;
            }

            rankedAlphabetSortMap[name_nodeSort] = datatype;
            FuncDecl acceptor = Z.MkFuncDecl(string.Format("$lang_{0}", name), new Sort[] { Z.IntSort, datatype }, Z.BoolSort);
            Expr[]   vars     = new Expr[maxrank + 1];
            vars[0] = Z.MkVar(0, attributeSort);
            for (int i = 1; i <= maxrank; i++)
            {
                vars[i] = Z.MkVar((uint)i, datatype);
            }
            var ra = new RankedAlphabet(this, symbols, idMap, datatype, attributeSort, ranks, constrs, accessors, testers, acceptor, vars);
            rankedAlphabetInfoMap[datatype] = ra;
            return(ra);
        }
示例#12
0
 /// <summary>
 /// Make a new tree automaton or tree transducer.
 /// </summary>
 /// <param name="q0">initial state</param>
 /// <param name="inputAlphabet">input alphabet</param>
 /// <param name="outputAlphabet">output alphabet</param>
 /// <param name="rules">rules of the automaton or transducer</param>
 /// <returns></returns>
 public TreeTransducer MkTreeAutomaton(int q0, RankedAlphabet inputAlphabet, RankedAlphabet outputAlphabet, IEnumerable <TreeRule> rules)
 {
     return(MkTreeAutomaton(new List <int>(new int[] { q0 }), inputAlphabet, outputAlphabet, rules));
 }
示例#13
0
 /// <summary>
 /// Make an output term of applying the given state to the given child subtree.
 /// </summary>
 /// <param name="outputAlphabet">the output alphabet sort</param>
 /// <param name="state">the state from which the child is transduced</param>
 /// <param name="child">the accessor of the child, must be a positive integer between 1 and MaxRank</param>
 public Expr MkTrans(RankedAlphabet outputAlphabet, int state, int child)
 {
     var f = tt.GetTrans(AlphabetSort, outputAlphabet.AlphabetSort);
     var s = tt.Z.MkInt(state);
     if (child < 1 || child > MaxRank)
         throw new AutomataException(AutomataExceptionKind.RankedAlphabet_ChildAccessorIsOutOufBounds);
     var x = ChildVar(child);
     var res = tt.Z.MkApp(f, s, x);
     return res;
 }