Z3 量化列表长度限制导致unsat

Z3 量化列表长度限制导致unsat,z3,smt,Z3,Smt,在下面的例子中,我试图对所有可能列表的长度设置一个约束 以量化的方式。这将导致一个“unsat”结果,我相信这是正确的 有人能详细说明为什么这是不可满足的,如果有办法绕过这个限制,而不把长度限制放在一个特定的变量/常数上吗 我发现了有趣的线索,但我的问题并没有得到真正的回答。此外,答案是旧的,参考SMT-LIB版本2.0(一个是未量化版本)。也许Z3现在能够以我所不知道的方式做到这一点 (set-logic ALL) (set-option :produce-unsat-cores true)

在下面的例子中,我试图对所有可能列表的长度设置一个约束 以量化的方式。这将导致一个“unsat”结果,我相信这是正确的

有人能详细说明为什么这是不可满足的,如果有办法绕过这个限制,而不把长度限制放在一个特定的变量/常数上吗

我发现了有趣的线索,但我的问题并没有得到真正的回答。此外,答案是旧的,参考SMT-LIB版本2.0(一个是未量化版本)。也许Z3现在能够以我所不知道的方式做到这一点

(set-logic ALL)
(set-option :produce-unsat-cores true)

(declare-datatypes ((List 1)) ((par (T) ((cons (head T) (tail (List T))) (nil)))))

(define-sort IntList() (List Int))

(define-fun-rec IntList.length((l IntList)) Int
    (ite
        (= l (as nil IntList))
        0
        (+ (IntList.length (tail l)) 1)
    )
)

(assert (! (forall ((this IntList)) (<= 2 (IntList.length this))) :named a10))

(check-sat)
(get-unsat-core)
(全部设置逻辑)
(设置选项:生成unsat核心为真)
(声明数据类型((列表1))((第(T)部分)((第(T)部分)(第(T)部分)(第(T)部分)(第(T)部分)(第(T)部分)(无)
(定义排序IntList()(列表Int))
(定义fun rec IntList.length((l IntList))Int
(三)
(=l(作为零整数列表))
0
(+(IntList.length(尾部l))1)
)
)
(assert(!(forall((this IntList))(此断言:

(assert (! (forall ((this IntList)) (<= 2 (IntList.length this))) :named a10))
也就是说,你必须写一个暗示,并在假设你的列表长度至少为2的情况下证明你想要的。当然,这可能会变得非常复杂,而且SMT求解者通常不能很好地进行量化,因此要注意复杂性

一般来说,对于SMT解算器来说,关于递归数据类型的推理不是一个强大的套件。递归函数定义工具相对较新,对它们的支持很少,而且经常出现错误。任何使用递归数据类型的验证尝试都必须对任何感兴趣的属性使用归纳,SMT解算器只是不进行归纳-你最好尝试像Isabelle、ACL2、Lean、HOL等实际的定理证明

(assert (forall ((x IntList)) (=> (>= (length-of x) 2) 
                              ... condition you want to prove ...)))