给定是一个函数及其行为的描述:
add: (ℤ ∪ {Error, None})² → (ℤ ∪ {Error, None})
For x ∈ (ℤ ∪ {Error, None}):
add(x, None) = add(None, x) = None
For x ∈ (ℤ ∪ {Error}):
add(x, Error) = add(Error, x) = Error
For x, y ∈ ℤ:
add(x, y) = x + y
如何将此描述转换为SMT(我正在使用Z3)并检查描述是否定义了一个总函数?
为了让您了解我想要实现的目标:最后,我希望生成具有最少分支数量的Python代码。例如:
def add(x, y):
if x is None or y is None:
return None
if x is Error or y is Error:
return Error
return x + y
这是我到目前为止所尝试的:
(declare-datatypes () ((ABC (int (val Int)) error none)))
(declare-fun f (ABC ABC) ABC)
(assert (forall ((x ABC)) (=> (or (is-int x) (= x error) (= x none)) (= (f none x) none))))
(assert (forall ((x ABC)) (=> (or (is-int x) (= x error) (= x none)) (= (f x none) none))))
(assert (forall ((x ABC)) (=> (or (is-int x) (= x error)) (= (f error x) error))))
(assert (forall ((x ABC)) (=> (or (is-int x) (= x error)) (= (f x error) error))))
(assert (forall ((x ABC) (y ABC)) (=> (and (is-int x) (is-int y)) (= (f x y) (int (+ (val x) (val y)))))))
(check-sat)
(get-model)
超时。
编辑:在Simplify function interpretation in model中,我描述了f的更简单的公理化,其中int
是一个案例,导致有限的案例。我能以某种方式告诉Z3 val
中的具体int
无关紧要,并且实际上有多少案例?
答案 0 :(得分:1)
检查唯一性:你的公理化是好的;你只需要复制"它为两个函数然后要求两个值,使它们不同:
(declare-datatypes () ((ABC (int (val Int)) error none)))
(declare-fun f (ABC ABC) ABC)
(assert (forall ((x ABC)) (=> (or (is-int x) (= x error) (= x none)) (= (f none x) none))))
(assert (forall ((x ABC)) (=> (or (is-int x) (= x error) (= x none)) (= (f x none) none))))
(assert (forall ((x ABC)) (=> (or (is-int x) (= x error)) (= (f error x) error))))
(assert (forall ((x ABC)) (=> (or (is-int x) (= x error)) (= (f x error) error))))
(assert (forall ((x ABC) (y ABC)) (=> (and (is-int x) (is-int y)) (= (f x y) (int (+ (val x) (val y)))))))
(declare-fun g (ABC ABC) ABC)
(assert (forall ((x ABC)) (=> (or (is-int x) (= x error) (= x none)) (= (g none x) none))))
(assert (forall ((x ABC)) (=> (or (is-int x) (= x error) (= x none)) (= (g x none) none))))
(assert (forall ((x ABC)) (=> (or (is-int x) (= x error)) (= (g error x) error))))
(assert (forall ((x ABC)) (=> (or (is-int x) (= x error)) (= (g x error) error))))
(assert (forall ((x ABC) (y ABC)) (=> (and (is-int x) (is-int y)) (= (g x y) (int (+ (val x) (val y)))))))
; check that there is no {x,y} such that f and g differ on:
(declare-const x ABC)
(declare-const y ABC)
(assert (not (= (f x y) (g x y))))
(check-sat)
(get-model)
Z3迅速回归不满;含义f
和g
无法区分。现在,您可以尝试为f
和/或g
注释掉一些断言并询问模型。根据您注释掉的断言,Z3可能会为f
和g
提供一个模型,使其具有不同的行为; OR 它仍然可能超时,试图构建一个模型来执行此操作。在量词的存在下,您无法从SMT求解器中获得更好的结果。