(z3py) 使用 all_smt 生成二维列表的所有解决方案

(z3py) Generate all solutions for a 2D list using all_smt

为了找出 SMT 中生成的所有解决方案,我使用了

中建议的 all_smt() 方法

但是,这仅适用于一维列表。如果我们尝试列出二维列表的解决方案怎么办?

我得到的一般错误是:

'list' object has no attribute 'as_ast'

我试图从二维列表中分离出每个一维列表,如下所示:

def all_smt(s, initial_terms):
    def block_term(s, m, t):
        s.add(t != m.eval(t, model_completion=True))
    def fix_term(s, m, t):
        s.add(t == m.eval(t, model_completion=True))
    def all_smt_rec(terms):
        for j in range(len(terms)):
            term = terms[j]
            print("term:", term)
            if sat == s.check():
                m = s.model()
                yield m
                for i in range(len(term)):
                    s.push()
                    block_term(s, m, term[i])
                    for j in range(i):
                        fix_term(s, m, term[j])
                    yield from all_smt_rec(term[i:])
                    s.pop()   
    yield from all_smt_rec(list(initial_terms))

但是在 'terms' 一定次数后,我收到错误 object of type 'ArithRef' has no len()

我们如何将 all_smt 用于 2D ArithRef 列表?更好的是,我们可以将其概括为 nD 列表吗?

initial_terms 应该是一个简单的术语列表,您不希望在模型中“重复”这些术语。如果你有一个 2d(或 n-d 表示任何 n),只需在将它传递给 all_smt.

之前将其展平

展平二维列表的简单方法是:

>>> import itertools
>>> list(itertools.chain(*[[1,2,3],[4,5,6],[7,8,9]]))
[1, 2, 3, 4, 5, 6, 7, 8, 9]

如果你有higher-dimensions,你可以写一个类似的函数来相应地压平它们。