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);
}
}
}