I'm solving SAT problem with Z3. And I get this assignment form Z3:
(model
(define-fun B ((x!0 Int))
(ite (= x!0 1) false
(ite (= x!0 2) false
true)))
(define-fun D ((x!0 Int))
(or (= x!0 3) (= x!0 1))
(define-fun A ((x!0 Int))
(ite (= x!0 1) false
(ite (= x!0 4) false
true)))
(define-fun C ((x!0 Int))
(ite (= x!0 5) false
true))
I can understand it for B, D, C (B1,B2 are false and others(B3,B4,B5) are true).
But how can you meaningfully interpret this OR formula for D? It should be that D1 and D3 are true and D2,D4,D5 are false and it seems it gives right answer. But why it present it in such strange form?
Model printing is not standardized in SMTLib, and depending on what underlying types you use (functions, arrays, scalar types etc.) Z3 will print in some internal format.
To get individual values, you can always do:
(eval (D 0))
etc. to retrieve individual values.
Related
I have a (get-model) query for Z3 which returns this function:
(define-fun rules ((x!0 Tree)) Bool
(ite (= x!0 (node "mann" (cons (node "adam" nil) nil))) true
(ite (= x!0 (node "mensch" (cons (node "adam" nil) nil))) true
true)))
When using this code:
(declare-datatypes () ((Tree leaf (node (value String) (children TreeList)))
(TreeList nil (cons (car Tree) (cdr TreeList)))))
(declare-const list TreeList)
(declare-const fact1 Tree)
(declare-const fact2 Tree)
(assert (not (is-leaf fact1)))
(assert (not (is-leaf fact2)))
(assert (not (= list nil)))
(assert (= (value fact1) "mann"))
(assert (= (value fact2) "adam"))
(assert (= (children fact1) list))
(assert (= fact2 (car list)))
(declare-const list2 TreeList)
(declare-const fact3 Tree)
(declare-const fact4 Tree)
(assert (not (is-leaf fact3)))
(assert (not (is-leaf fact4)))
(assert (not (= list2 nil)))
(assert (= (value fact3) "mensch"))
(assert (= (value fact4) "adam"))
(assert (= (children fact3) list2))
(assert (= fact4 (car list2)))
(declare-fun rules (Tree) Bool)
(assert (= (rules fact1) true))
(assert (=> (rules fact1) (rules fact3)))
(check-sat)
(get-model)
The problem is I need the function "rules" to return false, whenever the argument is not one of the trees I have asserted rules for it to be true, but I can't find a way to edit the last "else" in the function. (get-model) seems to always use the most common answer of the function as it's answer if none of the rules work and since I only have rules for trees which make the answer true it uses true for the else as well, but I can't use the function that way.
It seems you're trying to model Prolog like "closed-world" assumption here. This is not how SMT solvers work: They will find a model that will satisfy all the requirements, and everything else is fair game. That is, if you want no other value to satisfy your rules, then you have to state that explicitly.
You might want to look at datalog modeling though, which seems closer to what you are trying to express: https://rise4fun.com/z3/tutorialcontent/fixedpoints
In SMT: check uniqueness and totality of function I gave a function axiomatization and asked Z3 for a model. However because solving something with quantifiers in it is undecidable in general, Z3 times out.
Here is a modified version in which the "int" case is modelled as a single value:
(declare-datatypes () ((ABC int error none)))
(declare-fun f (ABC ABC) ABC)
(assert (forall ((x ABC)) (=> (or (= x int) (= x error) (= x none)) (= (f none x) none))))
(assert (forall ((x ABC)) (=> (or (= x int) (= x error) (= x none)) (= (f x none) none))))
(assert (forall ((x ABC)) (=> (or (= x int) (= x error)) (= (f error x) error))))
(assert (forall ((x ABC)) (=> (or (= x int) (= x error)) (= (f x error) error))))
(assert (forall ((x ABC) (y ABC)) (=> (and (= x int) (= y int)) (= (f x y) int))))
(check-sat)
(get-model)
Because there now are finitely many cases, Z3 gives an answer quickly:
sat
(model
(define-fun k!26 ((x!0 ABC)) ABC
(ite (= x!0 error) error
(ite (= x!0 int) int
none)))
(define-fun f!28 ((x!0 ABC) (x!1 ABC)) ABC
(ite (and (= x!0 error) (= x!1 int)) error
(ite (and (= x!0 int) (= x!1 error)) error
(ite (and (= x!0 error) (= x!1 error)) error
(ite (and (= x!0 int) (= x!1 int)) int
none)))))
(define-fun k!27 ((x!0 ABC)) ABC
(ite (= x!0 error) error
(ite (= x!0 int) int
none)))
(define-fun f ((x!0 ABC) (x!1 ABC)) ABC
(f!28 (k!27 x!0) (k!26 x!1)))
)
Both k!26 and k!27 actually just return their input (this is easily seen by checking all three cases). Is it possible to simplify the model by eliminating these two functions automatically?
Optimally I would like to have something like the following, although I see that might not be possible:
(define-fun f ((x!0 ABC) (x!1 ABC)) ABC
(ite (or (= x!0 none) (= x!1 none)) none
(ite (or (= x!0 error) (= x!1 error)) error
int)))
I'm using Z3Py, but both general Z3-specific and Z3Py-specific answers are welcome.
I don't think there's much you can do to guide Z3 to provide a "simpler" answer here; as the model generated depends on how the proof was done and even simple changes to the problem can have unpredictable results. In particular, the model you get can change with the next version of Z3.
Having said that, a common trick is to eval terms in the model. Since your current problem only involves a finite domain, you can enumerate it. If you add the following lines at the end of your script:
(eval (f int int))
(eval (f int error))
(eval (f int none))
(eval (f error int))
(eval (f error error))
(eval (f error none))
(eval (f none int))
(eval (f none error))
(eval (f none none))
Then Z3 will print:
int
error
none
error
error
none
none
none
none
Perhaps you can use that output to construct a "simpler" model yourself. Of course, this only works if the domain is finite; but you can use the same trick to evaluate "interesting" parts of the input domain, depending on your problem.
I originally posted the question as shown below the dotted line, but since then I have an even simpler example:
(declare-fun f (Int) Int)
(assert (= (f 10) 1))
(check-sat)
(get-model)
produces an interpretation for f as expected. However change the constant to anything but 10, and Z3 just spins the arrowhead a couple of times but then prints nothing!
--------------------------------------- original question -----------------------------
I tried Z3 on the following input and the arrowhead turns a few times and stops but Z3 prints or says nothing. Why?
(declare-fun f (Int Int) Int)
(assert (>= (f 1 1) 1))
(assert (>= (f 1 2) 2))
(assert (>= (f 2 1) 2))
(assert (>= (f 2 2) 2))
(assert (= (f 1 1) 1))
(assert (= (f 2 2) 2))
(assert (or (= (f 1 2) 1) (= (f 1 2) 2)))
(assert (or (= (f 2 1) 1) (= (f 2 1) 2)))
(check-sat)
(get-model)
I feel like I'm missing something really obvious..
I am obtaining (using iZ3, Z3 unstable branch)
sat
(model
(define-fun f ((x!1 Int) (x!2 Int)) Int
(ite (and (= x!1 1) (= x!2 1)) 1
(ite (and (= x!1 2) (= x!2 2)) 2
(ite (and (= x!1 1) (= x!2 2)) 2
(ite (and (= x!1 2) (= x!2 1)) 2 2)))))
)
Run this example online here
I presume you're using Z3 on rise4fun? The version running there may be a little out of date. We have to manually update the binary there. If it doesn't reply, it's either because it times out, or because there was some other problem (e.g., segfault). It's quite possible that the version on rise4fun exhibits some bug that's already been fixed in other version of Z3 (e.g., unstable, iZ3, etc).
Some values of uninterpreted functions can be unconstrained during the search. For example, if in smt query only f(1) is called, then f(2), f(3) can be anything. Is there a way (some option may be) to know which values were not used during the solving and therefore can be anything?
For quantifier free problems, you can achieve that by using the option :model-partial to true.
Here is an example (also available here):
(set-option :model-partial true)
(declare-fun f (Int) Int)
(assert (> (f 0) 0))
(assert (< (f 1) 0))
(check-sat)
(get-model)
In this example, we get the output:
sat
(model
(define-fun f ((x!1 Int)) Int
(ite (= x!1 0) 1
(ite (= x!1 1) (- 1)
#unspecified)))
)
BTW, in the next release (Z3 4.3.2), this option is renamed to :model.partial. In the next release, the options are grouped in modules.
get-value call returns an expression instead of concrete value #b01:
sat
(((trans_local true true (_ bv2 2)) (ite #b10 #b01 (ite #b00 (ite #b10 #b11 #b01) (ite #b01 (ite #b10 #b10 #b00) #b01)))))
simplify results in the same way(and it probably should). How should I use get-value to get a correct result?
Here is the query:
(set-logic UFBV)
(set-option :produce-models true)
(define-fun trans_local ((x!1 (_ BitVec 2)) (x!2 Bool) (x!3 Bool)) (_ BitVec 2)
(ite (= x!1 #b10)
(ite x!2 #b01 #b00)
(ite (= x!1 #b00)
(ite (and x!2 x!3)
#b11
(ite (and (not x!2) x!3)
#b10
(ite (and (not x!2) (not x!3)) #b00 #b01)))
(ite (= x!1 #b01) (ite (and x!2 x!3) #b10 (ite (and (not x!2) x!3) #b10 #b00)) #b01)))
)
(check-sat)
(get-value ((trans_local true true (_ bv2 2))))
Your expression is not well sorted. In Z3, define-fun is essentially a macro. Z3 3.2 does not check if macro applications are well sorted. So, you did not get any error message. This has been fixed, and the fix will be available in the next release: Z3 4.0.
That being said, you can get the expected result by fixing the sort error in the get-value statement. I guess, you intended to write:
(get-value ((trans_local (_ bv1 2) true true)))