private Expr GenerateZ3ToExpr(Variable expr, RankedAlphabetSort outputAlph, List<FastToken> children)
 {
     //Find the child number and return the transition
     int childPosition = 1;
     foreach (var child in children)
     {
         if (child.text == ((Variable)expr).token.text)
         {
             break;
         }
         childPosition++;
     }
     return alphabet.alph.ChildVar(childPosition);
 }
 //Generate the tree definition corresponding to a ranked alphabet
 private static bool GenerateTreeClass(Dictionary<string, Def> defs, FastTransducerInstance fti, RankedAlphabetSort ras)
 {
     //Create a new tree definition
     TreeClassDef treeDef = new TreeClassDef(ras, z3p);
     fti.treeDefinitions.Add(ras.alphName, treeDef);
     return true;
 }
 private Expr GenerateZ3ToExpr(Value expr, RankedAlphabetSort outputAlph)
 {
     switch (expr.sort.kind)
     {
         case (FastSortKind.Bool):
             {
                 if (expr.token.Kind == Tokens.TRUE)
                     return z3p.True;
                 if (expr.token.Kind == Tokens.FALSE)
                     return z3p.False;
                 break;
             }
         case (FastSortKind.Int):
             {
                 return z3p.MkInt(Convert.ToInt32(expr.token.text));
             }
         case (FastSortKind.Real):
             {
                 return z3p.Z3.MkReal(expr.token.text);
             }
         case (FastSortKind.String):
             {
                 return z3p.MkListFromString(expr.token.text.Substring(1, expr.token.text.Length - 2), z3p.CharSort);
             }
         case (FastSortKind.Tree):
             {
                 String[] lr = expr.token.text.Split('.');
                 return z3p.GetEnumElement(lr[0], lr[1]);
             }
     }
     throw new Exception("Unexpected Sort");
 }
 private Expr GenerateZ3ToExpr(RecordExp expr, RankedAlphabetSort outputAlph, FastTransducerInstance fti)
 {
     Expr[] terms = new Expr[expr.args.Count];
     for (int i = 0; i < expr.args.Count; i++)
     {
         terms[i] = GenerateZ3ExprFromWhereExpr(expr.args.ElementAt<FExp>(i), fti);
     }
     return z3p.MkApp(outputAlph.tupleFuncDec, terms);
 }
        private Expr GenerateZ3ToExpr(AppExp expr, RankedAlphabetSort outputAlph, List<FastToken> children, int from, List<string> reachedStates, List<Def> queue, Dictionary<string, Def> defs, FastTransducerInstance fti, List<int>[] nextStatesL)
        {
            List<Expr> termList = new List<Expr>();
            switch (expr.func.name.Kind)
            {
                #region predefined functions
                case (Tokens.EQ):
                    {
                        return z3p.MkEq(GenerateZ3ExprFromToExpr(expr.args[0], outputAlph, children, from, reachedStates, queue, defs, fti, nextStatesL), GenerateZ3ExprFromToExpr(expr.args[1], outputAlph, children, from, reachedStates, queue, defs, fti, nextStatesL));
                    }
                case (Tokens.AND):
                    {
                        foreach (var arg in expr.args)
                            termList.Add(GenerateZ3ExprFromToExpr(arg, outputAlph, children, from, reachedStates, queue, defs, fti, nextStatesL));
                        return z3p.MkAnd(termList.ToArray());
                    }
                //case ("xor"):
                //    {
                //        if (expr.args.Count > 2)
                //            throw new Exception("Too many arguments");
                //        return z3p.Z3.MkXor((BoolExpr)GenerateZ3ExprFromToExpr(expr.args[0], outputAlph, children, from, reachedStates, queue, defs, fti, nextStatesL), (BoolExpr)GenerateZ3ExprFromToExpr(expr.args[1], outputAlph, children, from, reachedStates, queue, defs, fti, nextStatesL));
                //    }
                case (Tokens.NOT):
                    {
                        return z3p.MkNot(GenerateZ3ExprFromToExpr(expr.args[0], outputAlph, children, from, reachedStates, queue, defs, fti, nextStatesL));
                    }
                case (Tokens.OR):
                    {
                        foreach (var arg in expr.args)
                            termList.Add(GenerateZ3ExprFromToExpr(arg, outputAlph, children, from, reachedStates, queue, defs, fti, nextStatesL));
                        return z3p.MkOr(termList.ToArray());
                    }
                case (Tokens.IMPLIES):
                    {
                        return z3p.MkOr(z3p.MkNot(GenerateZ3ExprFromToExpr(expr.args[0], outputAlph, children, from, reachedStates, queue, defs, fti, nextStatesL)), GenerateZ3ExprFromToExpr(expr.args[1], outputAlph, children, from, reachedStates, queue, defs, fti, nextStatesL));
                    }
                case (Tokens.PLUS):
                    {
                        foreach (var arg in expr.args)
                            termList.Add(GenerateZ3ExprFromToExpr(arg, outputAlph, children, from, reachedStates, queue, defs, fti, nextStatesL));
                        if (z3p.GetSort(termList[0]).SortKind == Z3_sort_kind.Z3_BV_SORT)
                            return z3p.MkBvAddMany(termList.ToArray());
                        return z3p.MkAdd(termList.ToArray());
                    }
                case (Tokens.DIV):
                    {
                        return z3p.MkCharDiv(GenerateZ3ExprFromToExpr(expr.args[0], outputAlph, children, from, reachedStates, queue, defs, fti, nextStatesL), GenerateZ3ExprFromToExpr(expr.args[1], outputAlph, children, from, reachedStates, queue, defs, fti, nextStatesL));
                    }
                case (Tokens.MINUS):
                    {
                        return z3p.MkCharSub(GenerateZ3ExprFromToExpr(expr.args[0], outputAlph, children, from, reachedStates, queue, defs, fti, nextStatesL), GenerateZ3ExprFromToExpr(expr.args[1], outputAlph, children, from, reachedStates, queue, defs, fti, nextStatesL));
                    }
                case (Tokens.TIMES):
                    {
                        return z3p.MkCharMul(GenerateZ3ExprFromToExpr(expr.args[0], outputAlph, children, from, reachedStates, queue, defs, fti, nextStatesL), GenerateZ3ExprFromToExpr(expr.args[1], outputAlph, children, from, reachedStates, queue, defs, fti, nextStatesL));
                    }
                case (Tokens.LT):
                    {
                        return z3p.MkCharLt(GenerateZ3ExprFromToExpr(expr.args[0], outputAlph, children, from, reachedStates, queue, defs, fti, nextStatesL), GenerateZ3ExprFromToExpr(expr.args[1], outputAlph, children, from, reachedStates, queue, defs, fti, nextStatesL));
                    }
                case (Tokens.LE):
                    {
                        return z3p.MkCharLe(GenerateZ3ExprFromToExpr(expr.args[0], outputAlph, children, from, reachedStates, queue, defs, fti, nextStatesL), GenerateZ3ExprFromToExpr(expr.args[1], outputAlph, children, from, reachedStates, queue, defs, fti, nextStatesL));
                    }
                case (Tokens.GT):
                    {
                        return z3p.MkCharGt(GenerateZ3ExprFromToExpr(expr.args[0], outputAlph, children, from, reachedStates, queue, defs, fti, nextStatesL), GenerateZ3ExprFromToExpr(expr.args[1], outputAlph, children, from, reachedStates, queue, defs, fti, nextStatesL));
                    }
                case (Tokens.GE):
                    {
                        return z3p.MkCharGe(GenerateZ3ExprFromToExpr(expr.args[0], outputAlph, children, from, reachedStates, queue, defs, fti, nextStatesL), GenerateZ3ExprFromToExpr(expr.args[1], outputAlph, children, from, reachedStates, queue, defs, fti, nextStatesL));
                    }
                case (Tokens.MOD):
                    {
                        return z3p.MkMod(GenerateZ3ExprFromToExpr(expr.args[0], outputAlph, children, from, reachedStates, queue, defs, fti, nextStatesL), GenerateZ3ExprFromToExpr(expr.args[1], outputAlph, children, from, reachedStates, queue, defs, fti, nextStatesL));
                    }
                case (Tokens.ITE):
                    {
                        return z3p.MkIte(GenerateZ3ExprFromToExpr(expr.args[0], outputAlph, children, from, reachedStates, queue, defs, fti, nextStatesL), GenerateZ3ExprFromToExpr(expr.args[1], outputAlph, children, from, reachedStates, queue, defs, fti, nextStatesL), GenerateZ3ExprFromToExpr(expr.args[2], outputAlph, children, from, reachedStates, queue, defs, fti, nextStatesL));
                    }
                #endregion
                default:
                    {
                        if (expr.IsTranDef)
                        {
                            //The application is a transduction applied to a subtree
                            //Check if the current trans has been processed, if not add it to the queue
                            String name = ((AppExp)expr).func.name.text;
                            int pos = reachedStates.IndexOf(name);
                            if (pos == -1)
                            {
                                reachedStates.Add(name);
                                var transDef = defs[name];
                                queue.Add((TransDef)transDef);
                                pos = reachedStates.Count-1;
                            }

                            //Find the child number and return the transition
                            int childPosition = 1;
                            foreach (var child in children)
                            {
                                if (child.text == ((AppExp)expr).args[0].token.text)
                                {
                                    break;
                                }
                                childPosition++;
                            }
                            if (!nextStatesL[childPosition - 1].Contains(pos))
                                nextStatesL[childPosition - 1].Add(pos);

                            return alphabet.alph.MkTrans(outputAlph.alph, pos, childPosition);
                        }

                        //It means the app is a constructor
                        Expr[] terms = new Expr[expr.args.Count-1];
                        var terms_0 = GenerateZ3ToExpr((RecordExp)expr.args.ElementAt<FExp>(0), outputAlph, fti);
                        for (int i = 1; i < expr.args.Count; i++)
                        {
                            terms[i-1] = GenerateZ3ExprFromToExpr(expr.args.ElementAt<FExp>(i), outputAlph, children, from, reachedStates, queue, defs, fti, nextStatesL);
                        }
                        return outputAlph.alph.MkTree(expr.func.name.text, terms_0, terms);

                    }
            }
        }
 public Expr GenerateZ3ExprFromToExpr(FExp expr, RankedAlphabetSort outputAlph, List<FastToken> children, int from, List<string> reachedStates, List<Def> queue, Dictionary<string, Def> defs, FastTransducerInstance fti, List<int>[] nextStatesL)
 {
     switch (expr.kind)
     {
         case (FExpKind.App):
             return GenerateZ3ToExpr((AppExp)expr, outputAlph, children, from, reachedStates, queue, defs, fti, nextStatesL);
         case (FExpKind.Value):
             return GenerateZ3ToExpr((Value)expr, outputAlph);
         case (FExpKind.Var):
             return GenerateZ3ToExpr((Variable)expr, outputAlph, children);
     }
     return null;
 }
 public TreeClassDef(RankedAlphabetSort ras, Z3Provider z3p)
 {
     this.alphabet = ras;
     this.z3p = z3p;
     this.trees = new Dictionary<string, IEnumerable<Expr>>();
     this.acceptors = new Dictionary<string, TreeTransducer>();
     this.transducers = new Dictionary<string, TreeTransducer>();
 }