diff --git a/examples/python/efsmt.py b/examples/python/efsmt.py index 53c83c02e16..afd9a21ae3e 100644 --- a/examples/python/efsmt.py +++ b/examples/python/efsmt.py @@ -5,43 +5,33 @@ Modified from the example in pysmt https://github.com/pysmt/pysmt/blob/97088bf3b0d64137c3099ef79a4e153b10ccfda7/examples/efsmt.py ''' -def efsmt(y, phi, maxloops=None): - """Solving exists x. forall y. phi(x, y)""" - vars = get_vars(phi) - x = [item for item in vars if item not in y] - esolver = Solver() - fsolver = Solver() - esolver.add(BoolVal(True)) + +def efsmt(ys, phi, maxloops = None): + """Solving exists xs. forall ys. phi(x, y)""" + xs = [x for x in get_vars(phi) if x not in ys] + E = Solver() + F = Solver() + E.add(BoolVal(True)) loops = 0 while maxloops is None or loops <= maxloops: loops += 1 - eres = esolver.check() + eres = E.check() if eres == unsat: return unsat else: - emodel = esolver.model() - tau = [emodel.eval(var, True) for var in x] - sub_phi = phi - for i in range(len(x)): - sub_phi = simplify(substitute(sub_phi, (x[i], tau[i]))) - fsolver.add(Not(sub_phi)) - if fsolver.check() == sat: - fmodel = fsolver.model() - sigma = [fmodel.eval(v, True) for v in y] - sub_phi = phi - for j in range(len(y)): - sub_phi = simplify(substitute(sub_phi, (y[j], sigma[j]))) - esolver.add(sub_phi) + emodel = E.model() + sub_phi = substitute(phi, [(x, emodel.eval(x, True)) for x in xs]) + F.push() + F.add(Not(sub_phi)) + if F.check() == sat: + fmodel = F.model() + sub_phi = substitute(phi, [(y, fmodel.eval(y, True)) for y in ys]) + E.add(sub_phi) else: - return sat + return sat, [(x, emodel.eval(x, True)) for x in xs] + F.pop() return unknown - -def test(): - x, y, z = Reals("x y z") - fmla = Implies(And(y > 0, y < 10), y - 2 * x < 7) - fmlb = And(y > 3, x == 1) - print(efsmt([y], fmla)) - print(efsmt([y], fmlb)) - -test() +x, y, z = Reals("x y z") +print(efsmt([y], Implies(And(y > 0, y < 10), y - 2 * x < 7))) +print(efsmt([y], And(y > 3, x == 1)))