我刚刚开始独自玩Z3,我认为一个有趣的实验是构造一个3元素场。
因此,我将字段S声明为三个元素A,B,C的标量枚举,并开始逐渐添加字段公理,并在每步之后向Z3请求一个模型,以查看发生了什么。一切顺利,直到我断言减法的可能性,∀ab。(∃x.a+ x = b):
(declare-datatypes () ((S A B C)))
; there exist three distinct elements in S
(declare-const someA S)
(declare-const someB S)
(declare-const someC S)
(assert (distinct someA someB someC))
(declare-fun ADD (S S) S)
(declare-fun MUL (S S) S)
; commutative
(assert (forall ((x S) (y S)) (= (ADD x y) (ADD y x))))
(assert (forall ((x S) (y S)) (= (MUL x y) (MUL y x))))
; associative
(assert (forall ((x S) (y S) (z S)) (= (ADD x (ADD y z)) (ADD (ADD x y) z))))
(assert (forall ((x S) (y S) (z S)) (= (MUL x (MUL y z)) (MUL (MUL x y) z))))
; subtractivity
(assert (forall ((a S) (b S)) (exists ((x S)) (= (ADD a x) b))))
(check-sat)
(get-model)
这将导致Z3永远循环。我很惊讶。我的意思是,我理解为什么FOL通常无法确定,但是我认为这将是“简单”的情况之一,因为a,b和ADD的所有可能值的空间都是有限的(在这种情况下,甚至小)?为什么循环?最好以一种不会丧失其预期直觉意义的方式来表达可减性公理的正确方法是什么?
答案 0 :(得分:0)
虽然@alias通常对他的建议是正确的,但如果您愿意削弱公理化,您仍然可以使用Z3。例如:
...
; subtractivity
(declare-fun SUB (S S) S)
(assert (forall ((a S) (b S) (x S)) (iff (= (ADD a x) b) (= (SUB b x) a))))
(check-sat)
(get-model)