如何让z3返回多个unsat核心、多个令人满意的任务
我正在研究一种研究工具的一个组成部分; 我对检索(QF_LRA)感兴趣 -多个(最小或其他)未安装的内核和如何让z3返回多个unsat核心、多个令人满意的任务,z3,smt,sat,Z3,Smt,Sat,我正在研究一种研究工具的一个组成部分; 我对检索(QF_LRA)感兴趣 -多个(最小或其他)未安装的内核和 -多次SAT作业 我已在论坛上查看有关此主题的早期讨论,例如。, 他们参考了z3 Python教程 e、 g, 现在它似乎处于离线状态。我尝试了github等的其他建议来查找提到的教程,但没有成功 我使用的是Z3JavaAPI;但是很高兴切换到其他选项。这是教程。你可以找到更多关于马可的信息 来自马克·利菲顿的网页 最小不可满足核和最大满足子集的计数 本教程演示了如何使用Z3提取所有最小
-多次SAT作业 我已在论坛上查看有关此主题的早期讨论,例如。, 他们参考了z3 Python教程 e、 g, 现在它似乎处于离线状态。我尝试了github等的其他建议来查找提到的教程,但没有成功
我使用的是Z3JavaAPI;但是很高兴切换到其他选项。这是教程。你可以找到更多关于马可的信息 来自马克·利菲顿的网页 最小不可满足核和最大满足子集的计数 本教程演示了如何使用Z3提取所有最小不可满足的核心 以及所有最大满意子集 起源 我们接下来描述的算法 代表Liffiton和Malik独立进行的岩芯提取过程的实质 Previti和Marques Silva的作品: 枚举不可行性:快速查找多个缪斯
马克·H·利菲顿和阿马尔·马利克
在过程中。第十届人工智能集成国际会议 约束编程中的智能(AI)和运筹学(OR)技术(CPAIOR-2013),160-1752013年5月。 部分MUS计数
亚历山德罗·普雷维蒂,若昂·马尔克斯·席尔瓦 在过程中。AAAI-2013 2013年7月 Z3py特性 此实现不包含任何调优。 它是由马克·利菲顿(MarkLiffiton)提供的,它是从 他的马可波罗网站。 EMU的代码也可用。 该示例演示了Z3基于Python的API的以下特性:
class MapSolver:
def __init__(self, n):
"""Initialization.
Args:
n: The number of constraints to map.
"""
self.solver = Solver()
self.n = n
self.all_n = set(range(n)) # used in complement fairly frequently
def next_seed(self):
"""Get the seed from the current model, if there is one.
Returns:
A seed as an array of 0-based constraint indexes.
"""
if self.solver.check() == unsat:
return None
seed = self.all_n.copy() # default to all True for "high bias"
model = self.solver.model()
for x in model:
if is_false(model[x]):
seed.remove(int(x.name()))
return list(seed)
def complement(self, aset):
"""Return the complement of a given set w.r.t. the set of mapped constraints."""
return self.all_n.difference(aset)
def block_down(self, frompoint):
"""Block down from a given set."""
comp = self.complement(frompoint)
self.solver.add( MkOr( [Bool(str(i)) for i in comp] ) )
def block_up(self, frompoint):
"""Block up from a given set."""
self.solver.add( MkOr( [Not(Bool(str(i))) for i in frompoint] ) )
def enumerate_sets(csolver, map):
"""Basic MUS/MCS enumeration, as a simple example."""
while True:
seed = map.next_seed()
if seed is None:
return
if csolver.check_subset(seed):
MSS = csolver.grow(seed)
yield ("MSS", csolver.to_c_lits(MSS))
map.block_down(MSS)
else:
MUS = csolver.shrink(seed)
yield ("MUS", csolver.to_c_lits(MUS))
map.block_up(MUS)
main()
非常感谢您的详细回复和指向Mark Liffiton网页的指针。对不起,上面代码片段的第3、4行中是否缺少某些内容?
class SubsetSolver:
constraints = []
n = 0
s = Solver()
varcache = {}
idcache = {}
def __init__(self, constraints):
self.constraints = constraints
self.n = len(constraints)
for i in range(self.n):
self.s.add(Implies(self.c_var(i), constraints[i]))
def c_var(self, i):
if i not in self.varcache:
v = Bool(str(self.constraints[abs(i)]))
self.idcache[get_id(v)] = abs(i)
if i >= 0:
self.varcache[i] = v
else:
self.varcache[i] = Not(v)
return self.varcache[i]
def check_subset(self, seed):
assumptions = self.to_c_lits(seed)
return (self.s.check(assumptions) == sat)
def to_c_lits(self, seed):
return [self.c_var(i) for i in seed]
def complement(self, aset):
return set(range(self.n)).difference(aset)
def seed_from_core(self):
core = self.s.unsat_core()
return [self.idcache[get_id(x)] for x in core]
def shrink(self, seed):
current = set(seed)
for i in seed:
if i not in current:
continue
current.remove(i)
if not self.check_subset(current):
current = set(self.seed_from_core())
else:
current.add(i)
return current
def grow(self, seed):
current = seed
for i in self.complement(current):
current.append(i)
if not self.check_subset(current):
current.pop()
return current
class MapSolver:
def __init__(self, n):
"""Initialization.
Args:
n: The number of constraints to map.
"""
self.solver = Solver()
self.n = n
self.all_n = set(range(n)) # used in complement fairly frequently
def next_seed(self):
"""Get the seed from the current model, if there is one.
Returns:
A seed as an array of 0-based constraint indexes.
"""
if self.solver.check() == unsat:
return None
seed = self.all_n.copy() # default to all True for "high bias"
model = self.solver.model()
for x in model:
if is_false(model[x]):
seed.remove(int(x.name()))
return list(seed)
def complement(self, aset):
"""Return the complement of a given set w.r.t. the set of mapped constraints."""
return self.all_n.difference(aset)
def block_down(self, frompoint):
"""Block down from a given set."""
comp = self.complement(frompoint)
self.solver.add( MkOr( [Bool(str(i)) for i in comp] ) )
def block_up(self, frompoint):
"""Block up from a given set."""
self.solver.add( MkOr( [Not(Bool(str(i))) for i in frompoint] ) )
def enumerate_sets(csolver, map):
"""Basic MUS/MCS enumeration, as a simple example."""
while True:
seed = map.next_seed()
if seed is None:
return
if csolver.check_subset(seed):
MSS = csolver.grow(seed)
yield ("MSS", csolver.to_c_lits(MSS))
map.block_down(MSS)
else:
MUS = csolver.shrink(seed)
yield ("MUS", csolver.to_c_lits(MUS))
map.block_up(MUS)
main()