private Expr GenerateZ3Expr(AppExp expr, FastTransducerInstance fti)
{
List<Expr> termList = new List<Expr>();
switch (expr.func.name.Kind)
{
case (Tokens.EQ):
{
return z3p.MkEq(GenerateZ3ExprFromExpr(expr.args[0], fti), GenerateZ3ExprFromExpr(expr.args[1], fti));
}
case (Tokens.AND):
{
foreach (var arg in expr.args)
termList.Add(GenerateZ3ExprFromExpr(arg, fti));
return z3p.MkAnd(termList.ToArray());
}
//case ("xor"):
// {
// return z3p.Z3.MkXor((BoolExpr)GenerateZ3ExprFromExpr(expr.args[0], fti), (BoolExpr)GenerateZ3ExprFromExpr(expr.args[1], fti));
// }
case (Tokens.NOT):
{
return z3p.MkNot(GenerateZ3ExprFromExpr(expr.args[0], fti));
}
case (Tokens.OR):
{
foreach (var arg in expr.args)
termList.Add(GenerateZ3ExprFromExpr(arg, fti));
return z3p.MkOr(termList.ToArray());
}
case (Tokens.IMPLIES):
{
return z3p.MkOr(z3p.MkNot(GenerateZ3ExprFromExpr(expr.args[0], fti)), GenerateZ3ExprFromExpr(expr.args[1], fti));
}
case (Tokens.PLUS):
{
foreach (var arg in expr.args)
termList.Add(GenerateZ3ExprFromExpr(arg, fti));
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(GenerateZ3ExprFromExpr(expr.args[0], fti), GenerateZ3ExprFromExpr(expr.args[1], fti));
}
case (Tokens.MINUS):
{
return z3p.MkCharSub(GenerateZ3ExprFromExpr(expr.args[0], fti), GenerateZ3ExprFromExpr(expr.args[1], fti));
}
case (Tokens.TIMES):
{
return z3p.MkCharMul(GenerateZ3ExprFromExpr(expr.args[0], fti), GenerateZ3ExprFromExpr(expr.args[1], fti));
}
case (Tokens.LT):
{
return z3p.MkCharLt(GenerateZ3ExprFromExpr(expr.args[0], fti), GenerateZ3ExprFromExpr(expr.args[1], fti));
}
case (Tokens.LE):
{
return z3p.MkCharLe(GenerateZ3ExprFromExpr(expr.args[0], fti), GenerateZ3ExprFromExpr(expr.args[1], fti));
}
case (Tokens.GT):
{
return z3p.MkCharGt(GenerateZ3ExprFromExpr(expr.args[0], fti), GenerateZ3ExprFromExpr(expr.args[1], fti));
}
case (Tokens.GE):
{
return z3p.MkCharGe(GenerateZ3ExprFromExpr(expr.args[0], fti), GenerateZ3ExprFromExpr(expr.args[1], fti));
}
case (Tokens.MOD):
{
return z3p.MkMod(GenerateZ3ExprFromExpr(expr.args[0], fti), GenerateZ3ExprFromExpr(expr.args[1], fti));
}
//case ("concat"):
// {
// throw new Exception("concat not defined yet");
// //return z3p.MkL(GenerateZ3ExprFromExpr(expr.args[0], fti), GenerateZ3ExprFromExpr(expr.args[1], fti));
// }
case (Tokens.ITE):
{
return z3p.MkIte(GenerateZ3ExprFromExpr(expr.args[0], fti), GenerateZ3ExprFromExpr(expr.args[1], fti), GenerateZ3ExprFromExpr(expr.args[2], fti));
}
case (Tokens.ID):
{
foreach (var f in fti.functions)
{
if (this.name == f.name)
throw new Exception("cannot define recursive functions");
if (expr.func.name.text == f.name)
{
List<Expr> argsExprs = new List<Expr>();
foreach (var a in expr.args)
{
argsExprs.Add(GenerateZ3ExprFromExpr(a, fti));
}
return z3p.ApplySubstitution(f.functionDef, f.variableExprs.Values.ToArray(), argsExprs.ToArray<Expr>());
//return z3p.MkApp(f.funcDecl, argsExprs.ToArray<Expr>());
}
}
throw new FastException(FastExceptionKind.UnknownFunction);
}
default:
throw new FastException(FastExceptionKind.UnknownFunction);
}
}