Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unsat core #91

Merged
merged 44 commits into from
May 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
d69cde3
added strings
LaorS Apr 23, 2023
7cbc628
changes in printer
LaorS Apr 25, 2023
1a9a634
added more string functions
LaorS May 3, 2023
9881934
added le,lt,ge,gr
LaorS May 3, 2023
c59b7fe
added string printing
LaorS May 4, 2023
8bd8860
added string tests
LaorS May 10, 2023
11542cf
added string tests
LaorS May 17, 2023
036fc13
added regular expressions
LaorS May 31, 2023
06bd219
fixed Plus
LaorS Jun 4, 2023
a66afae
added sequences
LaorS Jun 15, 2023
beebc9f
small fixes
LaorS Jun 15, 2023
1b69d40
fixed Empty
LaorS Jun 18, 2023
755685d
Update test/pgms/example_string_comparison.py
LaorS Jun 18, 2023
46620c7
added tests
LaorS Jun 19, 2023
49c10be
added tests
LaorS Jun 19, 2023
87226c4
removed cvc5-Linux
LaorS Jun 25, 2023
d1a2d89
Update cvc5_pythonic_api/cvc5_pythonic_printer.py
LaorS Jun 25, 2023
c73ba74
added SeqUpdate
LaorS Jun 25, 2023
96b30aa
more documentation
LaorS Jun 26, 2023
532adfd
SubSeq on sequence only
LaorS Jun 26, 2023
d40cc29
added re concat
LaorS Jun 28, 2023
a4271a6
added missing functions
LaorS Jul 4, 2023
f1f7607
added doc-tests
LaorS Jul 6, 2023
c379962
reverting formatting
LaorS Jul 12, 2023
12cf47b
Merge branch 'main' into strings_new
LaorS Jul 12, 2023
dfc5fcc
format
LaorS Jul 12, 2023
ebdf7eb
removed cvc5
LaorS Jul 12, 2023
9ad8db5
fixed tests,cast and string format + comment
LaorS Jul 17, 2023
66fa4d4
fixed as_string
LaorS Aug 3, 2023
968e77a
reformatted
LaorS Aug 3, 2023
983fcc4
unsat
LaorS Oct 24, 2023
2a42a46
merge
LaorS Oct 24, 2023
545a073
fixed tests
LaorS Nov 5, 2023
550785a
Update cvc5_pythonic_api/cvc5_pythonic.py
LaorS Nov 7, 2023
d2364bd
Update cvc5_pythonic_api/cvc5_pythonic.py
LaorS Nov 7, 2023
b92b773
Update cvc5_pythonic_api/cvc5_pythonic.py
LaorS Nov 7, 2023
9ce80b8
Update cvc5_pythonic_api/cvc5_pythonic.py
LaorS Nov 7, 2023
e67c8d1
Update cvc5_pythonic_api/cvc5_pythonic.py
LaorS Nov 7, 2023
5be0b73
Update cvc5_pythonic_api/cvc5_pythonic.py
LaorS Nov 7, 2023
bfda30b
Update test/pgms/unsat_core.py
LaorS Nov 7, 2023
5538a22
PR changes
LaorS Nov 8, 2023
bff21e7
test
yoni206 May 8, 2024
902ee60
revert
yoni206 May 8, 2024
d636a15
fix
yoni206 May 8, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 28 additions & 2 deletions cvc5_pythonic_api/cvc5_pythonic.py
Original file line number Diff line number Diff line change
Expand Up @@ -1819,7 +1819,7 @@ def as_string(self):

>>> s = Unit(IntVal(1)) + Unit(IntVal(2))
>>> s.as_string()
'(str.++ (seq.unit 1) (seq.unit 2))'
'(seq.++ (seq.unit 1) (seq.unit 2))'
>>> x = Unit(RealVal(1.5))
>>> print(x.as_string())
(seq.unit (/ 3 2))
Expand Down Expand Up @@ -6316,14 +6316,40 @@ def statistics(self):
sat
>>> stats = s.statistics()
>>> stats['cvc5::CONSTANT']
{'defaulted': True, 'internal': False, 'value': {}}
{'default': True, 'internal': False, 'value': {}}
>>> len(stats.get()) < 10
True
>>> len(stats.get(True, True)) > 30
True
"""
return self.solver.getStatistics()

def unsat_core(self):
"""Return a subset (as a list of Bool expressions) of the assumptions provided to the last check().

These are the unsat ("failed") assumptions.

To enable this, set the option "produce-unsat-assumptions" to true.

>>> a,b,c = Bools('a b c')
>>> s = Solver()
>>> s.set('produce-unsat-assumptions','true')
>>> s.add(Or(a,b),Or(b,c),Not(c))
>>> s.check(a,b,c)
unsat
>>> core = s.unsat_core()
>>> a in core
False
>>> b in core
False
>>> c in core
True
>>> s.check(a,b)
sat
"""
core = self.solver.getUnsatAssumptions()
return [BoolRef(c) for c in core]


def SolverFor(logic, ctx=None, logFile=None):
"""Create a solver customized for the given logic.
Expand Down
1 change: 1 addition & 0 deletions test/pgm_outputs/unsat_assumptions.py.out
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
success
150 changes: 150 additions & 0 deletions test/pgms/unsat_assumptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
from cvc5_pythonic_api import *


def reset_solver(s):
s.reset()
s.set('produce-unsat-assumptions','true')

def validate_unsat_assumptions(assumptions, core):
# checks that the produced unsat assumptions (core) match the assumptions (assumptions) sent to the check function
return sum([c in assumptions for c in core]) == len(core)


def check_unsat_assumptions(assertions, core):
# This function checks wether, given assertions, the produced unsat assumptions (core) also lead to unsat result
slvr = Solver()
slvr.set('produce-unsat-assumptions','true')
for a in assertions:
slvr.add(a)
return s.check(*core) == unsat


# 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.
nontrivial_counter = 0

p1, p2, p3 = Bools('p1 p2 p3')
x, y = Ints('x y')
s = Solver()
reset_solver(s)
assertions = [Implies(p1, x > 0), Implies(p2, y > x), Implies(p2, y < 1), Implies(p3, y > -3)]

for a in assertions:
s.add(a)

assumptions = [p1,p2,p3]

s.check(*assumptions)

core = s.unsat_core()


assert validate_unsat_assumptions(assumptions,core)
assert check_unsat_assumptions(assertions,core)
if len(core) < len(assumptions):
nontrivial_counter += 1

# example 2 - booleans

reset_solver(s)

a, b, c = Bools('a b c')

# Add constraints

assertions = [Or(a, b), Or(Not(a), c), Not(c) ]
for c in assertions:
s.add(c)


# Check satisfiability
assumptions = [a,b,c]
result = s.check(*assumptions)

unsat_core = s.unsat_core()

assert validate_unsat_assumptions(assumptions,unsat_core)
assert check_unsat_assumptions(assertions,assumptions)
if len(unsat_core) < len(assumptions):
nontrivial_counter += 1

# example 3 - booleans


reset_solver(s)

a, b, c = Bools('a b c')
d = Bool('d')
# Add constraints with boolean operators
assertions = [And(a, b, Not(c)), Or(a, d), Not(And(a, d)) ]
for a in assertions:
s.add(a)

# Check satisfiability
assumptions = [a,b,c,d]
result = s.check(*assumptions)

unsat_core = s.unsat_core()

assert validate_unsat_assumptions(assumptions,unsat_core)
assert check_unsat_assumptions(assertions,assumptions)
if len(unsat_core) < len(assumptions):
nontrivial_counter += 1

# example 4 - reals



reset_solver(s)

x = Real('x')
y = Real('y')
z = Real('z')

assertions = [x + y == 5, y - z > 2, z > 3 ]
for a in assertions:
s.add(a)

# Check satisfiability
assumptions = [x > 0, y > 0, z > 0]
result = s.check(*assumptions)

unsat_core = s.unsat_core()

assert validate_unsat_assumptions(assumptions,unsat_core)
assert check_unsat_assumptions(assertions,assumptions)
if len(unsat_core) < len(assumptions):
nontrivial_counter += 1


# example 5 - strings


reset_solver(s)


# Define string variables
s1 = String('s1')
s2 = String('s2')

# Add string constraints
assertions = [Or(s1 == "hello", s1 == "world"), s1 + s2 == "helloworld"]
for a in assertions:
s.add(a)

# Check satisfiability

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

unsat_core = s.unsat_core()

assert validate_unsat_assumptions([Length(s2) < 2], unsat_core)
assert check_unsat_assumptions(assertions,[ Length(s2) < 2 ])
if len(unsat_core) < len([ Length(s2) < 2 ]):
nontrivial_counter += 1

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

print('success')


Loading