public VCExpr get(Term arg) { if (memo.ContainsKey(arg)) { return(memo[arg]); } VCExpr res = null; switch (arg.GetKind()) { case TermKind.Numeral: var numstr = arg.GetNumeralString(); if (arg.GetSort().GetSortKind() == SortKind.Int) { res = gen.Integer(Basetypes.BigNum.FromString(numstr)); } else { res = gen.Real(Basetypes.BigDec.FromString(numstr)); } break; case TermKind.App: var args = arg.GetAppArgs(); var vcargs = new VCExpr[args.Length]; for (int i = 0; i < args.Length; i++) { vcargs[i] = get(args[i]); } switch (arg.GetAppDecl().GetKind()) { case DeclKind.Add: if (vcargs.Length == 0) { if (arg.GetSort().GetSortKind() == SortKind.Int) { res = gen.Integer(Basetypes.BigNum.ZERO); } else { res = gen.Real(Basetypes.BigDec.ZERO); } } else { res = vcargs[0]; for (int k = 1; k < vcargs.Length; k++) { res = gen.Add(res, vcargs[k]); } } break; case DeclKind.And: res = VCExpressionGenerator.True; for (int i = 0; i < vcargs.Length; i++) { res = gen.AndSimp(res, vcargs[i]); } break; case DeclKind.Div: Debug.Assert(vcargs.Length == 2); res = gen.Function(VCExpressionGenerator.RealDivOp, vcargs[0], vcargs[1]); break; case DeclKind.Eq: Debug.Assert(vcargs.Length == 2); res = gen.Eq(vcargs[0], vcargs[1]); break; case DeclKind.False: res = VCExpressionGenerator.False; break; case DeclKind.Ge: Debug.Assert(vcargs.Length == 2); res = gen.Function(VCExpressionGenerator.GeOp, vcargs[0], vcargs[1]); break; case DeclKind.Gt: Debug.Assert(vcargs.Length == 2); res = gen.Gt(vcargs[0], vcargs[1]); break; case DeclKind.IDiv: Debug.Assert(vcargs.Length == 2); res = gen.Function(VCExpressionGenerator.DivOp, vcargs[0], vcargs[1]); break; case DeclKind.Iff: Debug.Assert(vcargs.Length == 2); var l = create_let(args[0], vcargs[0]); var r = create_let(args[1], vcargs[1]); return(gen.And(gen.Implies(l, r), gen.Implies(r, l))); case DeclKind.Implies: Debug.Assert(vcargs.Length == 2); res = gen.Implies(vcargs[0], vcargs[1]); break; case DeclKind.Ite: Debug.Assert(vcargs.Length == 3); res = gen.Function(VCExpressionGenerator.IfThenElseOp, vcargs[0], vcargs[1], vcargs[2]); break; case DeclKind.Le: Debug.Assert(vcargs.Length == 2); res = gen.Function(VCExpressionGenerator.LeOp, vcargs[0], vcargs[1]); break; case DeclKind.Lt: Debug.Assert(vcargs.Length == 2); res = gen.Function(VCExpressionGenerator.LtOp, vcargs[0], vcargs[1]); break; case DeclKind.Mod: Debug.Assert(vcargs.Length == 2); res = gen.Function(VCExpressionGenerator.ModOp, vcargs[0], vcargs[1]); break; case DeclKind.Mul: Debug.Assert(vcargs.Length == 2); res = gen.Function(VCExpressionGenerator.MulOp, vcargs[0], vcargs[1]); break; case DeclKind.Not: Debug.Assert(vcargs.Length == 1); res = gen.Not(vcargs[0]); break; case DeclKind.Or: res = VCExpressionGenerator.False; for (int i = 0; i < vcargs.Length; i++) { res = gen.OrSimp(res, vcargs[i]); } break; case DeclKind.Select: Debug.Assert(vcargs.Length == 2); res = gen.Select(vcargs[0], vcargs[1]); break; case DeclKind.Store: Debug.Assert(vcargs.Length == 3); res = gen.Store(vcargs[0], vcargs[1], vcargs[2]); break; case DeclKind.Sub: Debug.Assert(vcargs.Length == 2); res = gen.Function(VCExpressionGenerator.SubOp, vcargs[0], vcargs[1]); break; case DeclKind.True: res = VCExpressionGenerator.True; break; case DeclKind.Uminus: Debug.Assert(vcargs.Length == 1); var argzero = null; if (vcargs[0].Type.IsInt) { argzero = gen.Integer(Basetypes.BigNum.ZERO); } else { argzero = gen.Real(Basetypes.BigDec.ZERO); } res = gen.Function(VCExpressionGenerator.SubOp, argzero, vcargs[0]); break; case DeclKind.ToInt: Debug.Assert(vcargs.Length == 1); res = gen.Function(VCExpressionGenerator.ToIntOp, vcargs[0]); break; case DeclKind.ToReal: Debug.Assert(vcargs.Length == 1); res = gen.Function(VCExpressionGenerator.ToRealOp, vcargs[0]); break; case DeclKind.Uninterpreted: var name = arg.GetAppDecl().GetDeclName(); if (args.Length == 0) { // a 0-ary constant is a VCExprVar if (!constants_inv.TryGetValue(arg, out res)) { throw new Exception("Z3 returned unknown constant: " + name); } } else { Function f; if (!functions_inv.TryGetValue(arg.GetAppDecl(), out f)) { throw new Exception("Z3 returned unknown function: " + name); } List <VCExpr> vcargsList = new List <VCExpr>(vcargs); res = gen.Function(f, vcargsList); } break; default: throw new Exception("Unknown Z3 operator"); } break; default: Debug.Assert(false); throw new Exception("Unknown Z3 AST kind"); } memo.Add(arg, res); return(res); }