Inheritance: Ast
        /// <summary>
        /// Generate a transducer rooted in def from a transducer definition
        /// </summary>
        public bool AddTransducer(Def def, FastTransducerInstance fti, Dictionary<string, Def> defs)
        {
            #region Accessory variables
            int ruleNumb;
            int[][] givenExpr;
            Expr whereExpr;
            Expr toExpr;
            int currentState = 0;
            Def untdef;
            TransDef currentDef;
            LangDef currentLangDef;
            bool isTrans = true;

            //The alphabet of the transducer
            List<GuardedExp> cases = new List<GuardedExp>();
            RankedAlphabet currentAlphabet = alphabet.alph;
            List<TreeRule> transducerRules = new List<TreeRule>();
            List<string> exploredStates = new List<string>();
            List<string> reachedStates = new List<string>();

            RankedAlphabetSort outputAlphabet = null;

            int childPosition;
            String name = "";
            String defName = "";
            List<FastToken> children;

            int[][] nextStates;
            List<int>[] nextStatesL;
            #endregion

            List<Def> definitionQueue = new List<Def>();

            //Find the output alphabet

            #region pick proper outputAlph
            if (def.kind == DefKind.Trans)
            {
                TransDef tdef = def as TransDef;
                defName = tdef.func.name.text;
                outputAlphabet = fti.alphabets[tdef.range.name.text];
            }
            if (def.kind == DefKind.Lang)
            {
                LangDef ldef = def as LangDef;
                defName = ldef.func.name.text;
                outputAlphabet = fti.alphabets[ldef.domain.name.text];
            }
            #endregion

            reachedStates.Add(defName);
            definitionQueue.Add(def);

            while (definitionQueue.Count > 0)
            {
                //remove state from the queue and mark it as explored
                untdef = definitionQueue.ElementAt<Def>(0);
                definitionQueue.RemoveAt(0);
                #region pick proper type for def
                if (untdef.kind == DefKind.Trans)
                {
                    isTrans = true;
                    currentDef = (TransDef)untdef;
                    exploredStates.Add(currentDef.func.name.text);
                    cases = currentDef.cases;
                }
                if (untdef.kind == DefKind.Lang)
                {
                    isTrans = false;
                    currentLangDef = (LangDef)untdef;
                    exploredStates.Add(currentLangDef.func.name.text);
                    cases = currentLangDef.cases;
                }
                #endregion

                ruleNumb = 0;
                List<int> unsatRules = new List<int>();
                foreach (var defCase in cases)
                {
                    ruleNumb++;
                    children = defCase.pat.children;

                    //Compute the Z3 term for the where condition
                    whereExpr = GenerateZ3ExprFromWhereExpr(defCase.where, fti).Simplify();

                    if (z3p.IsSatisfiable(whereExpr))
                    {
                        //Compute the termSet array corresponding to the given
                        givenExpr = new int[children.Count][];

                        #region Find next states and add them to the queue and add the corresponding number to next states
                        nextStates = new int[children.Count][];
                        nextStatesL = new List<int>[children.Count];
                        for (int i = 0; i < children.Count; i++)
                            nextStatesL[i] = new List<int>();
                        foreach (var expr in defCase.given)
                        {
                            if (expr.kind == FExpKind.App)
                            {
                                name = ((AppExp)expr).func.name.text;
                                //Add the state to the queue if it has not been reached yet
                                if (!reachedStates.Contains(name))
                                {
                                    reachedStates.Add(name);
                                    var langDef = defs[name] as LangDef;
                                    definitionQueue.Add(langDef);

                                }
                                childPosition = 0;
                                foreach (var child in children)
                                {
                                    if (child.text == ((AppExp)expr).args[0].token.text)
                                    {
                                        break;
                                    }
                                    childPosition++;
                                }
                                nextStatesL[childPosition].Add(reachedStates.IndexOf(name));
                            }
                        }

                        #endregion

                        //Compute the Z3 term for the to condition
                        if (isTrans)
                            toExpr = GenerateZ3ExprFromToExpr(defCase.to, outputAlphabet, children, currentState, reachedStates, definitionQueue, defs, fti, nextStatesL).Simplify();
                        else
                            toExpr = null;

                        //Next states will contain the outgoing states of the automata
                        for (int i = 0; i < children.Count; i++)
                            nextStates[i] = nextStatesL[i].ToArray();
                        transducerRules.Add(z3p.TT.MkTreeRule(currentAlphabet, outputAlphabet.alph, currentState, defCase.pat.symbol.text, whereExpr, toExpr, nextStates));
                    }
                    else
                    {
                        unsatRules.Add(ruleNumb - 1);
                        //Console.WriteLine("Rule " + ruleNumb + " is unsat in " + untdef.id.text);
                        fti.fastLog.WriteLog(LogLevel.Normal, string.Format("Rule {0} in '{1}' is not satisfiable", +ruleNumb, untdef.id.text));
                    }

                }
                int removed = 0;
                foreach (int ind in unsatRules)
                {
                    cases.RemoveAt(ind-removed);
                    removed++;
                }
                currentState++;
            }

            //Generate transducer
            try
            {
                var automaton = z3p.TT.MkTreeAutomaton(0, currentAlphabet, outputAlphabet.alph, transducerRules);
                automaton = automaton.RemoveMultipleInitialStates();
                if (def.kind == DefKind.Trans)
                {
                    transducers.Add(defName, automaton);
                    if (automaton.IsEmpty)
                        fti.fastLog.WriteLog(LogLevel.Normal, string.Format("the transducer '{0}' is empty", defName));
                }
                else
                {
                    acceptors.Add(defName, automaton);
                    if (automaton.IsEmpty)
                        fti.fastLog.WriteLog(LogLevel.Normal, string.Format("the language '{0}' is empty", defName));
                }
            }
            catch (AutomataException e)
            {
                Console.WriteLine(e);
                throw e;
            }
            return true;
        }
Ejemplo n.º 2
0
 public void Add(Def def)
 {
     if (def is QueryDef)
     {
         //queries.Add((QueryDef)def);
         defs.Add(def);
     }
     else
     {
         if (defsMap.ContainsKey(def.id.text))
             throw new FastParseException(def.id.Location, string.Format("ID '{0}' is defined twice", def.id.text));
         defsMap[def.id.text] = def;
         defs.Add(def);
     }
 }