English 中文(简体)
Z3: Extracting existential model-values
原标题:

I m playing around with Z3 s QBVF solver, and wondering if it s possible to extract values from an existential assertion. To wit, let s say I have the following:

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

This basically says that there is a "least" 16-bit unsigned value. Then, I can say:

(check-sat)
(get-model)

And Z3-3.0 happily responds:

sat
(model  (define-fun x!0 () (_ BitVec 16)
#x0000)
)

Which is really cool. But what I want to do is to be able to extract pieces of that model via get-value. Unsurprisingly, none of the following seem to work

(get-value (x))
(get-value (x!0))

In each case Z3 rightly complains there s no such constant. Clearly Z3 has that information as evidenced by the response to the (check-sat) call. Is there any way to access the existential value automatically via get-value, or some other mechanism?

Thanks..

问题回答

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.





相关问题
How do I reason about conditionals in Coq?

I m working through the ListSet module from the Coq standard library. I m unsure how to reason about conditionals in a proof. For instance, I am having trouble with the following proof. Definitions ...

Z3: Extracting existential model-values

I m playing around with Z3 s QBVF solver, and wondering if it s possible to extract values from an existential assertion. To wit, let s say I have the following: (assert (exists ((x (_ BitVec 16))) (...

Tautology Checker for GNU Prolog [closed]

I am looking for open-source implementations of tautology checkers written in GNU Prolog (implementation for SWI-Prolog is acceptable as well, but GNU Prolog is preferred). I d like to feed program ...

Has anyone tried proving Z3 with Z3 itself?

Has anyone tried proving Z3 with Z3 itself? Is it even possible, to prove that Z3 is correct, using Z3? More theoretical, is it possible to prove that tool X is correct, using X itself?

How to proceed with this Coq Proof?

I m having a problem with my Coq proof and was hoping for some help and guidance. I have part of my definition below: Inductive Architecture : Set := | Create_Architecture (Arch_Name: string)(...

Searching through a list recursively in Coq

Im trying to search for an object in a list, and then perhaps return true if it is found; false otherwise. However, what I have tried to come up with is incorrect. I would really appreciate some ...

Pattern matching not specialising types

I m playing around in Coq, trying to create a sorted list. I just wanted a function that takes a list [1,2,3,2,4] and would return something like Sorted [1,2,3,4] - i.e. taking out the bad parts, but ...

Showing (head . init ) = head in Agda

I m trying to prove a simple lemma in Agda, which I think is true. If a vector has more than two elements, taking its head following taking the init is the same as taking its head immediately. I ...

热门标签