关于Z3中未解释函数的表示

发布于 2024-12-24 16:00:22 字数 813 浏览 2 评论 0原文

我有一个简单的问题。我编写了一个简单的程序(使用 Z3 NET API)并得到如下输出。

程序(部分):

        Sort[] domain = new Sort[3];
        domain[0] = intT;  
        domain[1] = intT;          
        domain[2] = intT;  
        FPolicy = z3.MkFuncDecl("FPolicy", domain, boolT);      

        Term[] args = new Term[3];
        args[0] = z3.MkNumeral(0, intT);
        args[1] = z3.MkNumeral(1, intT);
        args[2] = z3.MkNumeral(30, intT);
        z3.AssertCnstr(z3.MkApp(FPolicy, args));

        args[1] = z3.MkNumeral(2, intT);
        args[2] = z3.MkNumeral(20, intT);
        z3.AssertCnstr(z3.MkApp(FPolicy, args));

输出:

FPolicy -> {
  0 1 30 -> true
  0 2 20 -> true     
  else -> true
}

我想知道我能否将“else -> true”设置为 false(即“else -> false”)。

I have a quick question. I wrote a simple program (using Z3 NET API) and got the output as follows.

Program (Partial):

        Sort[] domain = new Sort[3];
        domain[0] = intT;  
        domain[1] = intT;          
        domain[2] = intT;  
        FPolicy = z3.MkFuncDecl("FPolicy", domain, boolT);      

        Term[] args = new Term[3];
        args[0] = z3.MkNumeral(0, intT);
        args[1] = z3.MkNumeral(1, intT);
        args[2] = z3.MkNumeral(30, intT);
        z3.AssertCnstr(z3.MkApp(FPolicy, args));

        args[1] = z3.MkNumeral(2, intT);
        args[2] = z3.MkNumeral(20, intT);
        z3.AssertCnstr(z3.MkApp(FPolicy, args));

Output:

FPolicy -> {
  0 1 30 -> true
  0 2 20 -> true     
  else -> true
}

I am wondering could I make the "else -> true" as false (i.e., "else -> false").

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

倒数 2024-12-31 16:00:22

对于无量词问题,Z3 (3.2) 将为 else 选择在范围中更频繁出现的值。这里的范围是指 Z3 分配给特定有限输入值集的有限值集。在我们的示例中,range 中仅出现 true。因此,选择 true 作为 else 值。

对于无量词(和无数组)问题,如果不使用选项 :model-compact true ,则 else 的值并不重要。
也就是说,如果公式F可满足,Z3将产生模型M。然后,如果我们更改 M 中任何 else 的值,生成的模型 M' 仍然是 F 的模型代码>.
因此,您可以忽略 else,或者假设它是您想要的任何内容,如果输入公式 F 是无量词的,则 F 不使用数组理论,并且不使用 :model-compact true
此属性基于 Z3 当前实现的算法,将来可能会发生变化。
相比之下,mhs提供的解决方案不受Z3实现变化的影响。在他的编码中,任何 SMT 求解器(成功生成模型)都必须使用 false 作为量词前件中未指定的每个点的函数值。

另一种选择是使用 default 运算符,并使用数组对问题进行编码。
当使用 default 运算符时,我们应该将数组视为对:(实际数组,默认值)。
此默认值用于在模型构建期间提供 else 值。
Z3 还有几个内置公理来传播默认值:storemap 运算符。
这是使用这种方法编码的问题:

(set-option :produce-models true)
(declare-const FPolicy (Array Int Int Int Bool))

(assert (select FPolicy 0 1 30))
(assert (select FPolicy 0 2 20))
(assert (not (default FPolicy)))

(check-sat)
(get-model)

For quantifier free problems, Z3 (3.2) will select for the else the value that occurs more often in the range. By range here, I mean the finite set of values that Z3 assigned to a particular finite set of input values. In our example, only true occurs in the range. Thus, true is selected as the else value.

For quantifier free (and array free) problems, if the option :model-compact true is not used, then the value of the else doesn’t matter.
That is, if the formula F is satisfiable, Z3 will produce a model M. Then, if we change the value of any else in M, the resultant model M’ is still a model for F.
Thus, you can ignore the else, or assume it is whatever you want, IF the input formula F is quantifier free, F does not use array theory, and :model-compact true is not used.
This property is based on the algorithms currently implemented in Z3, and this may change in the future.
In contrast, the solution provided by mhs is not affected by changes in the implementation of Z3. In his encoding, any SMT solver (that succeeds in producing a model) will have to use false as the value of the function in every point not specified in the antecedent of the quantifier.

Another option is to use the default operator, and encode your problem using arrays.
When, the default operator is used, we should view arrays as pairs: (Actual Array, Default value).
This Default Value is used to provide the else value during model construction.
Z3 also has several builtin axioms to propagate default values over: store and map operators.
Here is your problem encoded using this approach:

(set-option :produce-models true)
(declare-const FPolicy (Array Int Int Int Bool))

(assert (select FPolicy 0 1 30))
(assert (select FPolicy 0 2 20))
(assert (not (default FPolicy)))

(check-sat)
(get-model)
孤单情人 2024-12-31 16:00:22

以下内容怎么样(RiSE4fun 链接)?

(set-option :MBQI true)

(declare-fun FPolicy (Int Int Int) Bool)

(assert (forall ((x1 Int) (x2 Int) (x3 Int)) (!
  (implies
    (not
      (or
        (and (= x1 0) (= x2 1) (= x3 30))
        (and (= x1 0) (= x2 2) (= x3 20))))
      (= (FPolicy x1 x2 x3) false))
  :pattern (FPolicy x1 x2 x3))))

(assert (FPolicy 0 1 30))
(assert (FPolicy 0 2 20))

(check-sat)
(get-model)

我看到的优点是您可以更改它,使 FPolicy(0 1 30) == false 无需触及 forall-constraint。
明显的缺点是您基本上必须两次提及所有参数元组,并且创建的模型相当复杂。

我期待看到更好的解决方案:-)

How about the following (RiSE4fun link)?

(set-option :MBQI true)

(declare-fun FPolicy (Int Int Int) Bool)

(assert (forall ((x1 Int) (x2 Int) (x3 Int)) (!
  (implies
    (not
      (or
        (and (= x1 0) (= x2 1) (= x3 30))
        (and (= x1 0) (= x2 2) (= x3 20))))
      (= (FPolicy x1 x2 x3) false))
  :pattern (FPolicy x1 x2 x3))))

(assert (FPolicy 0 1 30))
(assert (FPolicy 0 2 20))

(check-sat)
(get-model)

The advantage I can see is that you can change it such that FPolicy(0 1 30) == false without touching the forall-constraint.
The obvious disadvantage is that you basically have to mention all argument tuples twice, and that the created model is rather convoluted.

I am looking forward to seeing better solutions :-)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文