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.
Related
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 am defining time steps using an Int in SMT-LIB, which forces me to assert things to make sure nothing happens in the negatives:
(declare-sort Pkg) ; A package
(define-sort Time () Int) ; The installation step
; ...
(assert (forall ((t Time) (p Pkg)) (=> (< t 0) (not (installed p t)))))
I saw that in Z3 we can define inductive Nats in the usual style. Would it be good to use the inductive definition of Nat or is there a better way of doing what I am trying to do above?
You should really stick to Int, and put in >= 0 constraints appropriately. Z3 knows a lot about Int, has all sorts of proof rules and tricks to deal with it. While you can indeed define an inductive Nat type, you'll lose all the internal machinery for dealing with integers, and due to the recursive definition Z3's decision procedures will be less effective; especially in combination with other theories.
Having said that, it is impossible to know unless you try: There might be some problem domains where the inductive definition might fit better. But just by purely looking at the kind of you're problem dealing with, good old Int seems to be the right choice for you.
Also see this related question: Representing temporal constraints in SMT-LIB which is definitely relevant in your context.
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.
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))