Skip to content

Commit ed25955

Browse files
authored
Fixes for unsat core production (#98)
1 parent 0bb7f09 commit ed25955

File tree

3 files changed

+33
-40
lines changed

3 files changed

+33
-40
lines changed

cvc5_pythonic_api/cvc5_pythonic.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6325,15 +6325,14 @@ def statistics(self):
63256325
return self.solver.getStatistics()
63266326

63276327
def unsat_core(self):
6328-
"""Return a subset (as a list of Bool expressions) of the assumptions provided to the last check().
6328+
"""Return a subset (as a list of Bool expressions) of the
6329+
assertions and assumptions provided to the last check().
63296330
6330-
These are the unsat ("failed") assumptions.
6331-
6332-
To enable this, set the option "produce-unsat-assumptions" to true.
6331+
To enable this, set the option "produce-unsat-cores" to true.
63336332
63346333
>>> a,b,c = Bools('a b c')
63356334
>>> s = Solver()
6336-
>>> s.set('produce-unsat-assumptions','true')
6335+
>>> s.set('produce-unsat-cores','true')
63376336
>>> s.add(Or(a,b),Or(b,c),Not(c))
63386337
>>> s.check(a,b,c)
63396338
unsat
@@ -6347,8 +6346,8 @@ def unsat_core(self):
63476346
>>> s.check(a,b)
63486347
sat
63496348
"""
6350-
core = self.solver.getUnsatAssumptions()
6351-
return [BoolRef(c) for c in core]
6349+
core = self.solver.getUnsatCore()
6350+
return [_to_expr_ref(c, Context(self)) for c in core]
63526351

63536352

63546353
def SolverFor(logic, ctx=None, logFile=None):

test/pgms/unsat_assumptions.py renamed to test/pgms/unsat_cores.py

Lines changed: 27 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,21 @@
33

44
def reset_solver(s):
55
s.reset()
6-
s.set('produce-unsat-assumptions','true')
6+
s.set('produce-unsat-cores','true')
77

8-
def validate_unsat_assumptions(assumptions, core):
9-
# checks that the produced unsat assumptions (core) match the assumptions (assumptions) sent to the check function
10-
return sum([c in assumptions for c in core]) == len(core)
8+
def validate_unsat_core(input_formulas, core):
9+
# checks that the produced unsat core match the input formulas sent to the check function
10+
return sum([c in input_formulas for c in core]) == len(core)
1111

1212

13-
def check_unsat_assumptions(assertions, core):
14-
# This function checks wether, given assertions, the produced unsat assumptions (core) also lead to unsat result
13+
def check_unsat_core(core):
14+
# This function checks whether the unsat core is unsatisfiable
1515
slvr = Solver()
16-
slvr.set('produce-unsat-assumptions','true')
17-
for a in assertions:
18-
slvr.add(a)
1916
return s.check(*core) == unsat
2017

2118

2219
# To make make sure the unsat_core function works there should be at least one nontrivial solution - a solution that doesn't contain all the assumptions sent in the check function.
23-
nontrivial_counter = 0
20+
nontrivial_counter = 0
2421

2522
p1, p2, p3 = Bools('p1 p2 p3')
2623
x, y = Ints('x y')
@@ -37,10 +34,9 @@ def check_unsat_assumptions(assertions, core):
3734

3835
core = s.unsat_core()
3936

40-
41-
assert validate_unsat_assumptions(assumptions,core)
42-
assert check_unsat_assumptions(assertions,core)
43-
if len(core) < len(assumptions):
37+
assert validate_unsat_core(assertions + assumptions,core)
38+
assert check_unsat_core(core)
39+
if len(core) < len(assumptions) + len(assertions):
4440
nontrivial_counter += 1
4541

4642
# example 2 - booleans
@@ -60,11 +56,11 @@ def check_unsat_assumptions(assertions, core):
6056
assumptions = [a,b,c]
6157
result = s.check(*assumptions)
6258

63-
unsat_core = s.unsat_core()
59+
core = s.unsat_core()
6460

65-
assert validate_unsat_assumptions(assumptions,unsat_core)
66-
assert check_unsat_assumptions(assertions,assumptions)
67-
if len(unsat_core) < len(assumptions):
61+
assert validate_unsat_core(assertions + assumptions, core)
62+
assert check_unsat_core(core)
63+
if len(core) < len(assumptions) + len(assertions):
6864
nontrivial_counter += 1
6965

7066
# example 3 - booleans
@@ -83,11 +79,11 @@ def check_unsat_assumptions(assertions, core):
8379
assumptions = [a,b,c,d]
8480
result = s.check(*assumptions)
8581

86-
unsat_core = s.unsat_core()
82+
core = s.unsat_core()
8783

88-
assert validate_unsat_assumptions(assumptions,unsat_core)
89-
assert check_unsat_assumptions(assertions,assumptions)
90-
if len(unsat_core) < len(assumptions):
84+
assert validate_unsat_core(assumptions + assertions, core)
85+
assert check_unsat_core(core)
86+
if len(core) < len(assumptions) + len(assertions):
9187
nontrivial_counter += 1
9288

9389
# example 4 - reals
@@ -108,13 +104,13 @@ def check_unsat_assumptions(assertions, core):
108104
assumptions = [x > 0, y > 0, z > 0]
109105
result = s.check(*assumptions)
110106

111-
unsat_core = s.unsat_core()
107+
core = s.unsat_core()
112108

113-
assert validate_unsat_assumptions(assumptions,unsat_core)
114-
assert check_unsat_assumptions(assertions,assumptions)
115-
if len(unsat_core) < len(assumptions):
109+
assert validate_unsat_core(assumptions + assertions, core)
110+
assert check_unsat_core(core)
111+
if len(core) < len(assumptions) + len(assertions):
116112
nontrivial_counter += 1
117-
113+
118114

119115
# example 5 - strings
120116

@@ -135,16 +131,14 @@ def check_unsat_assumptions(assertions, core):
135131

136132
result = s.check( Length(s2) < 2)
137133

138-
unsat_core = s.unsat_core()
134+
core = s.unsat_core()
139135

140-
assert validate_unsat_assumptions([Length(s2) < 2], unsat_core)
141-
assert check_unsat_assumptions(assertions,[ Length(s2) < 2 ])
142-
if len(unsat_core) < len([ Length(s2) < 2 ]):
136+
assert validate_unsat_core([Length(s2) < 2] + assertions, core)
137+
assert check_unsat_core(core)
138+
if len(core) < len([ Length(s2) < 2 ]) + len(assertions):
143139
nontrivial_counter += 1
144140

145141
# check that there is at least one nontrivial unsat core
146142
assert nontrivial_counter >= 1
147143

148144
print('success')
149-
150-

0 commit comments

Comments
 (0)