Z3 不断获得;“未知”;结果:SMTLIB v2输入中的模式用法

Z3 不断获得;“未知”;结果:SMTLIB v2输入中的模式用法,z3,smt,Z3,Smt,在Z3中使用SMTLIBv2输入格式和模式时,我遇到了一个问题:我一直使用以下输入获得结果“未知”: (declare-datatypes () ((L L0 L1))) (declare-fun path () (List L)) (declare-fun checkTransition ((List L)) Bool) (define-fun isCons ((p (List L))) Bool (not (= p nil)) ) ; configuration options

在Z3中使用SMTLIBv2输入格式和模式时,我遇到了一个问题:我一直使用以下输入获得结果“未知”:

(declare-datatypes () ((L L0 L1)))
(declare-fun path () (List L))
(declare-fun checkTransition ((List L)) Bool)

(define-fun isCons ((p (List L))) Bool
    (not (= p nil))
)

; configuration options for :pattern, taken from the Z3 tutorial
(set-option :auto-config false) ; disable automatic self configuration
(set-option :smt.mbqi false)    ; disable model-based quantifier instantiation

(assert (isCons path))
(assert (isCons (tail path)))
(assert (= nil (tail (tail path))))
(assert (= L0 (head path)))             ; initial state constraint

(assert
    (forall ((p (List L)))
    (!
        (implies
            (and    (isCons p)
                    (isCons (tail p)))
            (and    (=  L0  (head p))           ; transition from L0
                    (=  L1  (head (tail p)))))  ; to L1
    :pattern ((checkTransition p))
    )
    )
)
(assert (checkTransition path))

(check-sat)
(get-model)
我使用一个列表来表示通过过渡系统的可能路径。在这种情况下,过渡系统仅由通过从L0到L1的过渡连接的状态L0和L1组成。通过assert语句,我将路径限制为以L0开始且长度为2的路径。 我希望得到路径作为模型(L0(cons(L1(cons-nil)))

我已经尝试将其归结为一个仍然显示问题的最小示例,结果是上面的代码。 我想使用该模式实现对“路径”的递归检查,以确保列表中的每两个连续节点都符合某些(转换)约束。连续cons的检查用作此递归检查的停止条件。尽管在上面的示例中,我通过checkTransition删除了递归检查,但它仍然不起作用。整个想法可以追溯到Milicevic和Kugler的一篇文章中,他们使用Z32.0和.NETAPI以这种方式表示模型检查问题

我知道模式实例化可能导致结果“未知”,但我想知道为什么在这样一个简单的(?)示例中已经发生了这种情况。我是否以错误的方式使用该模式来实现量词支持

关于这个问题的任何想法都是非常受欢迎的

问候 卡斯滕

附言: 我在MacOS X(10.8.3)上使用Z3版本4.3.2 上述文章:Milicevic,A.和Kugler,H.,2011年。使用SMT和列表理论进行模型检查。美国宇航局正式方法,第282-297页

根据mhs的评论进行编辑:

不获取模型的问题似乎发生在版本4.3.2(不稳定)中。 我对不同版本进行了一些故障排除:

  • Z3 4.3.0 32位,WinXP 32位,来自安装程序
    • 结果:未知,但给出了一个模型
  • Z3版本4.3.1,git checkout 89c1785b73225a1b363c0e485f854613121b70a7,MacOS X,自编译,这是主分支中的最新版本。。。。
    • 结果:未知,但给出了一个模型

  • 主分支的各种其他签出,所有我刚刚在Win7 x64上的Z3 4.3.0上尝试了您的示例,我得到了结果

    unknown
    
    (model 
      (define-fun path () (List L)
        (insert L0 (insert L1 nil)))
    
      (define-fun checkTransition ((x!1 (List L))) Bool
        (ite (= x!1 (insert L0 (insert L1 nil))) true
          true))
    )
    
    这不是你所期望的
    path
    的模型吗

    我假设您得到了未知的,因为您的问题没有得到充分说明,尽管我不能指出具体的问题。如果你给Z3一些要反驳的东西,比如通过附加

    (assert (not (= L1 (head (tail path)))))
    (check-sat)
    

    到您的代码,然后您将得到预期的
    unsat

    Z3有许多解算器。当结果未知时,并非每个解算器都会生成“候选模型”。 默认解算器是自动选择要使用的解算器的组合。在
    不稳定
    (正在工作)分支中修改了公文包解算器。夜间构建是使用
    unstable
    分支编译的。我将添加一个命令,指定执行
    (check sat)
    时执行的解算器。因此,如果我们对
    未知
    结果的“候选模型”感兴趣,我们可以指定一个生成它们的解算器。同时,您可以使用以下变通方法:

    • (检查sat)
      之前添加
      (推)
      命令。这是一个迫使公文包解算器选择一个生成“候选模型”的解算器的小技巧
    补充说明:

    • Z3 v4.3.2尚未发布。这就是为什么问题中的夜间构建会附加git哈希值
      197b2e8ddb91
      96f460a7f2d
      。这些哈希代码标识用于构建它们的精确git提交

    • 如果我们删除命令
      (设置选项:smt.mbqi false)
      ,Z3将使用
      mbqi
      模块,并将成功地将断言显示为
      unsat


    非常感谢您的回答!我做了更多的挖掘,见下面的答案。