We are using Microsoft Z3 C and C# API (I have 2 programs).
In Microsoft Z3, when we try to solve a formula, Z3 always returns the results in the same sequence, when there are two or more satisfiable solutions.
Is it possible to get random results from Z3 so that for the same input, it will generate different output sequence in different execution.
Please note that, I cannot use smt2 code directly. I this issue, people suggested to use "random_seed" and "smt.arith.random_initial_value" parameters.
(set-option :smt.arith.random_initial_value true)
(declare-const x Int)
(declare-const y Int)
(assert (> (+ x y) 0))
(check-sat-using (using-params qflra :random_seed 1))
(get-model)
(check-sat-using (using-params qflra :random_seed 2))
(get-model)
(check-sat-using (using-params qflra :random_seed 3))
(get-model)
This smt2 solution works and I have managed to verify it using rise4fun. But these parameters are not available in Z3 C or C# API.
In C code, we I try to set these parameters using function "Z3_set_param_value", I get warning like this.
WARNING: unknown parameter 'smt.arith.random_initial_value'
WARNING: unknown parameter 'random_seed'
Can anyone guide me how to use these parameters? Also, is there any other way I can get random results from Z3 c-api or C# api code execution?
Randomized results were never considered, but we can "trick" Z3 into doing a little bit of that by setting options like the random seeds. If you need multiple solutions, but not multiple & random solutions, just assert the negation of the first solution and ask Z3 to solve the problem again, with the added constraint.
Those particular options that are mentioned in the question, can be set via the API as well, but they have to be set on the right objects. As stated in the documentation (header file comments), Z3_set_param_value can only be used for those 10 options mentioned there. Other options have to be set on Z3_params objects which can later be handed over to tactics and solvers, using Z3_params_set_*. If needed, they can also be set by changing the global default value for those options via Z3_global_param_set.
Related
Are functions in z3 realized by inlining? E.g. would this
(define-fun f ((parameter Int)) Int (* parameter parameter))
(assert (= (f x) y))
automatically be replaced by this?:
(assert (= (* x x) y))
I know that in https://smtlib.github.io/jSMTLIB/SMTLIBTutorial.pdf#subsection.3.9.4 (page 38) it is mentioned that they are "equivalent"/"an abbreviation", but I just wanted to make sure whether this means that the function calls themselves are replaced.
Thanks so much!
Yes, the SMT-LIB standard indeed defines define-fun to be a C-style macro that is syntactically expanded to its defining expression.
However, while this defines its semantics, the definition does not necessarily require SMT-LIB tools, most notably SMT solvers, to actually implement define-fun like this. Hence, it could be that an SMT solver behaved differently, e.g. in terms of performance, if you ran it on two versions of a program: one with define-funs, and a second where you manually replaced all define-funs with their corresponding expressions.
The last bit is pure speculation from my side, though; you'd have to look at, e.g. Z3's sources (or maybe just its verbose debug output) to find out what a particular tool actually does.
Are there good mechanisms in Z3 to abstract over assertions? I want to create a “function” that takes in parameters and makes assertions about those parameters, possibly with “local variable” definitions in it.
Imagine that I have a String and I want to assert that it represents a decimal number between 13 and 24. I could write a combination of regular expression assertions about the string and combine it with a str.to.int range assertion. I can do that directly, but if I have dozens of such variables I want to make the assertion about, it gets repetitive. I can use an external language API, or perhaps define a macro/function returning a boolean inside Z3 and assert that it’s true, but that feels a bit indirect. What’s idiomatic here? I want it to be just as easy for Z3 to solve as writing the assertions out by hand
You can use define-fun to define a Boolean function f such that you can (assert (f x y z ...)), where f can of course be a conjunction of multiple conditions. The define-fun will be inlined by Z3's SMT2 frontend, i.e., there should not be any runtime cost to it.
(Z3 also supports macros defined via (forall ((x ...)) (= (f x ...) ...)), but you need to explicitly apply the model-finder tactic to inline them.)
I would like to model the behaviour of generic datatypes in SMT v2.6. I am using Z3 as constraint solver. I modelled, based on the official example, a generic list as parameterised datatype in the following way:
(declare-datatypes (T) ((MyList nelem (cons (hd T) (tl MyList)))))
I would like the list to be generic with respect to the datatype. Later on, I would like to declare constants the following way:
(declare-const x (MyList Int))
(declare-const y (MyList Real))
However, now I would like to define functions on the generic datatype MyList (e.g., a length operation, empty operation, ...) so that they are re-usable for all T's. Do you have an idea how I could achieve this? I did try something like:
(declare-sort K)
(define-fun isEmpty ((in (MyList K))) Bool
(= in nelem)
)
but this gives me an error message; for this example to work Z3 would need to do some type-inference, I suppose.
Would be great if you could could give me a hint.
SMT-Lib does not allow polymorphic user-defined functions. Section 4.1.5 of http://smtlib.cs.uiowa.edu/papers/smt-lib-reference-v2.6-r2017-07-18.pdf states:
Well-sortedness checks, required for commands that use sorts or terms,
are always done with respect to the current signature. It is an error
to declare or define a symbol that is already in the current
signature. This implies in particular that, contrary to theory
function symbols, user-defined function symbols cannot be overloaded.
Which is further expanded in Footnote-29:
The motivation for not overloading user-defined symbols is to simplify
their processing by a solver. This restriction is significant only for
users who want to extend the signature of the theory used by a script
with a new polymorphic function symbol—i.e., one whose rank would
contain parametric sorts if it was a theory symbol. For instance,
users who want to declare a “reverse” function on arbitrary lists,
must define a different reverse function symbol for each (concrete)
list sort used in the script. This restriction might be removed in
future versions.
So, as you suspected, you cannot define "polymorphic" functions at the user level. But as the footnote indicates, this restriction might be removed in the future, something that will most likely happen as SMT-solvers are more widely deployed. Exactly when that might happen, however, is anyone's guess.
I'm just getting started out and I'm curious if there is a way to add hypotheses. Using (assert ...) isn't what I want as for my application sometimes the assumptions are allowed to be false and therefore everything should become satisfiable. I know I can just use implications such as (assert (implies assumption conclusion)) but if there are many assumptions, it seems clumsy convert all of my assertions into implications. Roughly I'd like to have an interaction model like
(assume ...)
...
(assume ...)
(assert ...)
...
(assert ...)
(check-sat)
Using assert with implications is the way to go, there is no assume (see the SMT-LIB manual, section 3.9, http://smtlib.cs.uiowa.edu/papers/smt-lib-reference-v2.0-r10.12.21.pdf ).
If you have many assertions you'd like to use as assumptions, you may want to use one of the programmatic APIs to help automate this conversion for you: http://z3.codeplex.com/documentation
Alternatively, if the assertions are simple enough, you could just write a script operating on string representations of the assertions to print the SMT-LIB formulas with the implications.
You may also be interested in this: Soft/Hard constraints in Z3
I have a certain set of assertions that I give to z3 which are satisfiable. When I call (check-sat), z3 returns sat. I then call (get-model), and look at the definition for a specific variable, %%P2_*_143. It looks like this:
(define-fun %%P2_*_143 () JS (NUM 2.0))
If I take this definition, turn it into the assertion
(assert (= %%P2_*_143 (NUM 2.0)))
and call (check-sat) again, z3 returns unsat. Furthermore, if I then call (get-unsat-core), z3 returns ().
My understanding is that the model produced by z3 gives a satisfying assignment to all variables, so asserting that assignment should also be satisfiable. Is this incorrect, or do I have a bug elsewhere?
The entire set of assertions is in this gist: https://gist.github.com/2966738. The added assertion is at the very bottom.
I am using Z3 version 3.2, on Mac OS X 10.7.4. I was also able to reproduce this behavior using the online interface at http://rise4fun.com/z3.
A similar bug has been reported a couple of days ago. There is a bug in the model construction in the linear real arithmetic package. The bug has been fixed. Z3 uses infinitesimals to handle strict inequalities, the details are described in the following paper: http://research.microsoft.com/en-us/um/people/leonardo/cav06.pdf
Note that the bug does not affect the soundness of the solver. That is, the sat/unsat answers are correct. However, the model is not. The second query in your example is unsat because the model is incorrect. If you need, I can make a new binary available that fixes this issue. In the meantime, you can workaround the bug, by adding the following commands in your script:
(declare-fun delta () Real)
(assert (< 0.0000001 delta))
(assert (< delta 0.0000002))