From b083c7546eb6aeccc4f13d4f7354800d4c4ab918 Mon Sep 17 00:00:00 2001 From: Huanyi Chen <huanyi-chen@hotmail.com> Date: Fri, 28 Dec 2018 12:40:44 -0500 Subject: [PATCH] Substitue Vars in queries Replace Vars that are representing primary inputs as "i#" when query solvers. --- examples/python/mini_ic3.py | 41 +++++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/examples/python/mini_ic3.py b/examples/python/mini_ic3.py index 5a8ea566b..a509d6ff8 100644 --- a/examples/python/mini_ic3.py +++ b/examples/python/mini_ic3.py @@ -17,6 +17,7 @@ class Horn2Transitions: def __init__(self): self.trans = True self.init = True + self.inputs = [] self.goal = True self.index = 0 @@ -48,6 +49,9 @@ class Horn2Transitions: if pred is None: return False self.goal = self.subst_vars("x", inv, pred) + self.goal = self.subst_vars("i", self.goal, self.goal) + self.inputs += self.vars + self.inputs = list(set(self.inputs)) return True def is_body(self, body): @@ -77,6 +81,9 @@ class Horn2Transitions: self.xs = self.vars pred = self.subst_vars("xn", inv1, pred) self.xns = self.vars + pred = self.subst_vars("i", pred, pred) + self.inputs += self.vars + self.inputs = list(set(self.inputs)) self.trans = pred return True @@ -97,12 +104,24 @@ class Horn2Transitions: def mk_subst(self, prefix, inv): self.index = 0 - return [(f, self.mk_bool(prefix)) for f in inv.children()] + if self.is_inv(inv) is not None: + return [(f, self.mk_bool(prefix)) for f in inv.children()] + else: + vars = self.get_vars(inv) + return [(f, self.mk_bool(prefix)) for f in vars] def mk_bool(self, prefix): self.index += 1 return Bool("%s%d" % (prefix, self.index)) + def get_vars(self, f, rs=[]): + if is_var(f): + return z3util.vset(rs + [f], str) + else: + for f_ in f.children(): + rs = self.get_vars(f_, rs) + return z3util.vset(rs, str) + # Produce a finite domain solver. # The theory QF_FD covers bit-vector formulas # and pseudo-Boolean constraints. @@ -169,8 +188,9 @@ def prune(R): return R - removed class MiniIC3: - def __init__(self, init, trans, goal, x0, xn): + def __init__(self, init, trans, goal, x0, inputs, xn): self.x0 = x0 + self.inputs = inputs self.xn = xn self.init = init self.bad = goal @@ -229,6 +249,9 @@ class MiniIC3: def project0(self, m): return self.values2literals(m, self.x0) + def projectI(self, m): + return self.values2literals(m, self.inputs) + def projectN(self, m): return self.values2literals(m, self.xn) @@ -242,12 +265,14 @@ class MiniIC3: is_sat = self.s_bad.check() if is_sat == sat: m = self.s_bad.model() - props = self.project0(m) + cube = self.project0(m) + props = cube + self.projectI(m) self.s_good.push() self.s_good.add(R) is_sat2 = self.s_good.check(props) assert is_sat2 == unsat core = self.s_good.unsat_core() + core = [c for c in core if c in set(cube)] self.s_good.pop() self.s_bad.pop() return is_sat, core @@ -263,8 +288,8 @@ class MiniIC3: # minimize cube that is core of Dual solver. # this assumes that props & cube => Trans - def minimize_cube(self, cube, lits): - is_sat = self.min_cube_solver.check(lits + [c for c in cube]) + def minimize_cube(self, cube, inputs, lits): + is_sat = self.min_cube_solver.check(lits + [c for c in cube] + [i for i in inputs]) assert is_sat == unsat core = self.min_cube_solver.unsat_core() assert core @@ -319,7 +344,7 @@ class MiniIC3: m = s.model() s.pop() if is_sat == sat: - cube = self.next(self.minimize_cube(self.project0(m), self.projectN(m))) + cube = self.next(self.minimize_cube(self.project0(m), self.projectI(m), self.projectN(m))) elif is_sat == unsat: cube, f = self.generalize(cube, f) return cube, f, is_sat @@ -348,7 +373,7 @@ class MiniIC3: def test(file): h2t = Horn2Transitions() h2t.parse(file) - mp = MiniIC3(h2t.init, h2t.trans, h2t.goal, h2t.xs, h2t.xns) + mp = MiniIC3(h2t.init, h2t.trans, h2t.goal, h2t.xs, h2t.inputs, h2t.xns) result = mp.run() if isinstance(result, Goal): g = result @@ -435,4 +460,4 @@ class Quip(MiniIC3): else: return is_sat -""" \ No newline at end of file +"""