Z3: Extracting existential model-values

核能气质少年 提交于 2019-11-29 15:42:22

In Z3, get-value only allows the user to reference “global” declarations. The existential variable x is a local declaration. Thus, it can’t be accessed using get-value. By default, Z3 eliminates existential variables using a process called “skolemization”. The idea is to replace existential variables with fresh constants and function symbols. For example, the formula

exists x. forall y. exists z. P(x, y, z)

is converted into

forall y. P(x!1, y, z!1(y))

Note that z becomes a function because the choice of z may depend on y. Wikipedia has an entry on skolem normal form

That being said, I never found a satisfactory solution for the problem you described. For example, a formula may have many different existential variables with the same name. So, it is not clear how to reference each instance in the get-value command in a non-ambiguous way.

A possible workaround for this limitation is to apply the skolemization step “by hand”, or at least for the variables you want to know the value. For example,

(assert (exists ((x (_ BitVec 16))) (forall ((y (_ BitVec 16))) (bvuge y x))))

is written as:

(declare-const x (_ BitVec 16))
(assert (forall ((y (_ BitVec 16))) (bvuge y x)))
(check-sat)
(get-value x)

If the existential variable is nested in a universal quantifier such as:

(assert (forall ((y (_ BitVec 16))) (exists ((x (_ BitVec 16))) (bvuge y x))))
(check-sat)
(get-model)

A fresh skolem function can be used to obtain the value of x for each y. The example above becomes:

(declare-fun sx ((_ BitVec 16)) (_ BitVec 16))
(assert (forall ((y (_ BitVec 16))) (bvuge y (sx y))))
(check-sat)
(get-model)

In this example, sx is the fresh function. The model, produced by Z3, will assign an interpretation for sx. In version 3.0, the interpretation is the identity function. This function can be used to obtain the value of x for each y.

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