如何测试用户理论插件的不一致性?

时间:2012-08-29 20:08:36

标签: z3

我正在实现一个用户理论插件。我想测试用户理论中的不一致性来修剪一些模型。

更具体地说,在我的理论中,x是用户类集的变量,f是返回集合大小的函数。我有两个断言:x = set1 OR x = set2f x > 2。假设set1的大小为1,set2的大小为3.

在搜索中,Z3首先使用x = set1。所以我可以添加另一个断言f x = 1,它在INT部分中会不一致。我想测试不一致性,以便我可以否定当前的赋值,让Z3回溯并尝试其他选项。

我的问题是如何做到这一点。

我尝试了3种方法:

(1)使用f x = 1直接添加断言Z3_theory_assert_axiom()。然后搜索终止,立即返回UNSAT。

(2)我尝试使用Z3_check_assumptions()f x = 1作为假设来检查当前上下文。但是Z3_check_assumptions()不允许这样的复合公式。所以,它不可能是解决方案。

(3)我首先推送上下文,使用f x = 1添加断言Z3_assert_cnstr(),使用Z3_check_and_get_model()测试一致性,然后弹出刚刚推送的上下文。在测试中,如果它不一致,我将获得Z3_get_context_assignment(ctx)的当前赋值并断言否定赋值以触发回溯。我观察到的是Z3确实发现了不一致性,但是当前的赋值仅包含有关像(= 1 (f x))这样的大小部分的断言。换句话说,缺少关于用户理论的断言,如(= x set1) and not (= x set2)。因此,即使我否定当前的分配,在回溯之后,Z3仍然会尝试x = set1而不是其他选项x = set2

我哪里错了?谢谢!

1 个答案:

答案 0 :(得分:2)

您应该在回调中仅使用来自用户理论插件的第一个选项Z3_theory_assert_axiom()。你也应该只断言重言式,即与当前任务无关的公理。因此,而不是断言

f x = 1

你应该断言

x = set1 => f x = 1

(假设我理解)因为这个公式无论如何都是正确的。 你也可以断言:

f set1 = 1

(假设,我再次理解),这也会关闭y = set1&的分支。 f y> 1用于其他变量保持。更一般地说,你想要断言最强的理论公理来修剪出许多相关的分支。但理论公理必须是真实的,而不仅仅是在搜索的本地分支内。