C++ 关于Z3中模型的迭代细化

C++ 关于Z3中模型的迭代细化,c++,z3,C++,Z3,此问题是以下问题的后续问题: 正如Nikolaj所建议的,我实现了一种惰性循环方法,但我有几个问题要问 一,。 我使用model类的get_func_interp函数来获得Z3对自定义谓词的解释。它在大多数情况下工作正常,但有时,解释是根据Z3生成的其他函数定义的(下面的示例) 型号: (define-fun path1() Int 712) (define-fun path2 () Int 38) (define-fun z3contians ((x!1 Int) (x!2 Int))

此问题是以下问题的后续问题:

正如Nikolaj所建议的,我实现了一种惰性循环方法,但我有几个问题要问

一,。 我使用model类的get_func_interp函数来获得Z3对自定义谓词的解释。它在大多数情况下工作正常,但有时,解释是根据Z3生成的其他函数定义的(下面的示例)

型号:

(define-fun path1() Int 712)

(define-fun path2 () Int
  38)
(define-fun z3contians ((x!1 Int) (x!2 Int)) Bool
  true)
(define-fun k!15 ((x!1 Int)) Int
  (ite (= x!1 1) 1
    0))
(define-fun z3connects!16 ((x!1 Int) (x!2 Int) (x!3 Int)) Bool
  (ite (and (= x!1 712) (= x!2 0) (= x!3 1)) true
  (ite (and (= x!1 38) (= x!2 1) (= x!3 5)) true
    false)))
(define-fun k!13 ((x!1 Int)) Int
  (ite (>= x!1 712) (ite (>= x!1 1001) 1001 712) 38))
(define-fun k!14 ((x!1 Int)) Int
  (ite (= x!1 1) 1
    5))
(define-fun z3connects ((x!1 Int) (x!2 Int) (x!3 Int)) Bool
  (z3connects!16 (k!13 x!1) (k!15 x!2) (k!14 x!3)))
在这些情况下,g get_func_interp函数似乎不够。我不能迭代函数的所有可能输入并使用eval,因为我不知道该函数的非默认情况的数量

二,。 在使用惰性循环方法时,我注意到Z3有时会错过正确的模型,因为它试图更改不需要真正更改的值。我写了一个小例子来说明这一情况:

(declare-fun path1 () Int)
(declare-fun path2 () Int)
(declare-fun pred1 (Int) Bool)
(declare-fun pred2 (Int) Bool)
(assert (pred1 path1))
(assert (pred2 path2))
(check-sat)
(get-model)

现在,如果我们考虑PRED1(x)是(x= 12),并且Pord2(x)是(x= 11),我们可以看到Z3从来没有得到模型,因为它总是只报告具有(PATH1=1,PATT2=2)的模型,(PATH1=2,PATH 2= 3)…(PATH1=10,PATH2=11),(PATH1=11,PATH 2= 12)…等等有没有一种策略可以防止这种情况发生?我知道这不是一个特定于工具的问题,但任何见解都会有所帮助。

关于2:您可能对什么是“正确的”模型有一些想法。主要的一点是在调用Z3时不仅要阻塞单个模型,还要阻塞整个模型集。假设你得到一系列模型(1,2)(2,3)(3,4)。。这个序列有什么问题?当然,这取决于你的理论。现在假设您的理论要求path1>path2,然后添加path1>path2,而不是(和(不是(=path1 1))(不是(=path2)))关于1:我不确定我是否理解您“不能迭代输入”。函数的解释是一个组合:第一个k!xx应用于参数,然后应用其他函数。要在域上迭代,这里有一个简单的(非优化的)方法:创建非默认域值的叉积+k的一个额外值!xx函数。将其视为新的非默认值集。