SMT: check uniqueness and totality of function

孤街浪徒 提交于 2019-12-11 12:45:38

问题


Given is a function and a description of its behavior:

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

How can I transform this description to SMT (I'm using Z3) and check whether the description defines a total function?

To give you an idea what I want to achieve: in the end I want to generate Python code implementing this function with the minimum number of branches. For example:

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

This is what I tried so far:

(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)

This timeouts.

EDIT: In Simplify function interpretation in model I described a simpler axiomatization of f where int is a single case, resulting in finitely many cases. Can I somehow tell Z3 that the concrete val in int doesn't matter and there are effectively finitely many cases?


回答1:


To check uniqueness: Your axiomatization is good; you just need to "replicate" it for two functions then ask for two values such that they differ:

(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 quickly returns unsat for this; meaning f and g cannot differ. Now, you can try commenting out some of the asserts for f and/or g and ask for a model. Depending on which asserts you comment out, Z3 might come up with a model for f and g such that they have different behavior; OR it can still time-out, trying to construct a model to do so. In the presence of quantifiers, you can't really expect anything better from an SMT solver.



来源:https://stackoverflow.com/questions/37472357/smt-check-uniqueness-and-totality-of-function

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!