我如何检查一个 Const 是否包含在 Z3Py 的列表中?
How I can to check if a Const is containing in a List in Z3Py?
在 Z3Py 中,我需要检查 Const 类型是否包含在 List 中,我定义了数据类型 List 和 Const,我尝试使用方法 Contain (https://z3prover.github.io/api/html/namespacez3py.html#ada058544efbae7608acaef3233aa4422) 但它仅可用对于字符串数据类型,我需要全部。
def funList(sort):
List = Datatype('List')
#insert: (Int, List) -> List
List.declare('insert', ('head', sort), ('tail', List))
List.declare('nil')
return List.create()
IntList = funList(IntSort())
l1 = Const('l1', IntList)
我试图在 Z3 中做一个循环,但它不起作用:S
你的问题不是很清楚。您是否正在尝试编写某种列表成员资格? (就像在列表中查找元素一样。)
如果这是您的目标,我建议不要使用基于 Datatype
的编码。因为您将在其上编写的任何函数(如 elem
、length
等)都必须是递归的。而且 SMT 求解器不能很好地处理该形式的递归定义;因为它将逻辑放入不可判定的片段中。此外,当存在像这样的递归类型时,调试和编码相当困难,因为工具支持不是很好。
如果您的目标是使用类似列表的结构,我建议您改用内置的 sequence
逻辑。这是一个例子:
from z3 import *
s = Solver()
# declare a sequence of integers
iseq = Const('iseq', SeqSort(IntSort()))
# assert 3 is somewhere in this sequence
s.add(Contains(iseq, Unit(IntVal(3))))
# assert the sequence has at least 5 elements
s.add(Length(iseq) >= 5)
# get a model and print it:
if s.check() == sat:
print s.model()
当我 运行 这个时,我得到:
$ python a.py
[iseq = Concat(Unit(9),
Concat(Unit(10),
Concat(Unit(3),
Concat(Unit(16), Unit(17)))))]
这可能有点难读,但它本质上是在说 iseq
是一个由一堆单例 (Unit
) 串联而成的序列 (Concat
)。在更方便的表示法中,这将是:
iseq = [9, 10, 3, 16, 17]
如您所见,它有 5 个元素,3
确实是我们的约束所要求的序列。
Z3的时序逻辑非常丰富,包含了很多你想实现的功能。看这里:https://z3prover.github.io/api/html/z3py_8py_source.html#l09944
在 Z3Py 中,我需要检查 Const 类型是否包含在 List 中,我定义了数据类型 List 和 Const,我尝试使用方法 Contain (https://z3prover.github.io/api/html/namespacez3py.html#ada058544efbae7608acaef3233aa4422) 但它仅可用对于字符串数据类型,我需要全部。
def funList(sort):
List = Datatype('List')
#insert: (Int, List) -> List
List.declare('insert', ('head', sort), ('tail', List))
List.declare('nil')
return List.create()
IntList = funList(IntSort())
l1 = Const('l1', IntList)
我试图在 Z3 中做一个循环,但它不起作用:S
你的问题不是很清楚。您是否正在尝试编写某种列表成员资格? (就像在列表中查找元素一样。)
如果这是您的目标,我建议不要使用基于 Datatype
的编码。因为您将在其上编写的任何函数(如 elem
、length
等)都必须是递归的。而且 SMT 求解器不能很好地处理该形式的递归定义;因为它将逻辑放入不可判定的片段中。此外,当存在像这样的递归类型时,调试和编码相当困难,因为工具支持不是很好。
如果您的目标是使用类似列表的结构,我建议您改用内置的 sequence
逻辑。这是一个例子:
from z3 import *
s = Solver()
# declare a sequence of integers
iseq = Const('iseq', SeqSort(IntSort()))
# assert 3 is somewhere in this sequence
s.add(Contains(iseq, Unit(IntVal(3))))
# assert the sequence has at least 5 elements
s.add(Length(iseq) >= 5)
# get a model and print it:
if s.check() == sat:
print s.model()
当我 运行 这个时,我得到:
$ python a.py
[iseq = Concat(Unit(9),
Concat(Unit(10),
Concat(Unit(3),
Concat(Unit(16), Unit(17)))))]
这可能有点难读,但它本质上是在说 iseq
是一个由一堆单例 (Unit
) 串联而成的序列 (Concat
)。在更方便的表示法中,这将是:
iseq = [9, 10, 3, 16, 17]
如您所见,它有 5 个元素,3
确实是我们的约束所要求的序列。
Z3的时序逻辑非常丰富,包含了很多你想实现的功能。看这里:https://z3prover.github.io/api/html/z3py_8py_source.html#l09944