I try to write a custom print for a Z3_ast of Z3 in C, but I do not know how to manage the Z3_ast_kind of Z3_VAR_AST and Z3_FUNC_DECL_AST, I only know how to print the Z3_sort of Z3_VAR_AST (Z3_get_sort), about this variable value I have no ideas ???. And about the Z3_FUNC_DECL_AST, I couldn't find any accessors can get the function name, number of parameters and the parameters. Could you guys please help me? Cheers
I suggest you take a look at the file 'python/z3printer.py' in the Z3 distribution. It defines a custom pretty printer in Python. The Z3 python API is just a layer on top of the C API. So, it should be straightforward to convert this printer in C.
Regarding Z3_VAR_AST, the function
unsigned Z3_API Z3_get_index_value(__in Z3_context c, __in Z3_ast a);
returns the de-Brujin index for the variable. The meaning of the index is explained here: http://en.wikipedia.org/wiki/De_Bruijn_index
The variable names are stored in the quantifier AST. Note that, the names are irrelevant for Z3. They are stored just to make the output nice. The code in z3printer.py will keeps a stack with the variable names.
Regarding Z3_FUNC_DECL_AST, it is easier to handle than Z3_VAR_AST. ASTs of this kind are actually Z3_func_decl. Then the following APIs can be used to extract the information you want:
Z3_symbol Z3_API Z3_get_decl_name(__in Z3_context c, __in Z3_func_decl d);
Z3_decl_kind Z3_API Z3_get_decl_kind(__in Z3_context c, __in Z3_func_decl d);
unsigned Z3_API Z3_get_domain_size(__in Z3_context c, __in Z3_func_decl d);
unsigned Z3_API Z3_get_arity(__in Z3_context c, __in Z3_func_decl d);
Z3_sort Z3_API Z3_get_domain(__in Z3_context c, __in Z3_func_decl d, __in unsigned i);
Again, the file z3printer.py uses all these functions.
Related
I am working with Boogie and I have come across some behaviors I do not understand.
I have been using assert(false) as a way to check if the previous assume statements are absurd.
For instance in the following case, the program is verified without errors...
type T;
const t1, t2: T;
procedure test()
{
assume (t1 == t2);
assume (t1 != t2);
assert(false);
}
...as t1 == t2 && t1 != t2 is an absurd statement.
On the other hand if I have something like
type T;
var map: [T]bool;
const t1, t2: T;
procedure test()
{
assume(forall a1: T, a2: T :: !map[a1] && map[a2]);
//assert(!map[t1]);
assert(false);
}
The assert(false) only fails when the commented line is uncommented. Why is the commented assert changing the result of the assert(false)?
Gist: the SMT solver underlying Boogie will not instantiate the quantifier if you don't mention a ground instance of map[...] in your program.
Here is why: SMT solvers (that use e-matching) typically use syntactic heuristics to decide when to instantiate a quantifier. Consider the following quantifier:
forall i: Int :: f(i)
This quantifier admits infinitely many instantiations (since i ranges over an unbounded domain), trying all would thus result in non-termination. Instead, SMT solvers expect syntactic hints instructing it for which i the quantifier should be instantiated. These hints are called a patterns or triggers. In Boogie, they can be written as follows:
forall i: Int :: {f(i)} f(i)
This trigger instructs the SMT solver to instantiate the quantifier for each i for which f(i) is mentioned in the program (or rather, current proof search). E.g., if you assume f(5), then the quantifier will be instantiated with 5 substituted for i.
In your example, you don't provide a pattern explicitly, so the SMT solver might pick one for you, by inspecting the quantifier body. It will most likely pick {map[a1], map[a2]} (multiple function applications are allowed, patterns must cover all quantified variables). If you uncomment the assume, the ground term map[t1] becomes available, and the SMT solver can instantiate the quantifier with a1, a2 mapped to t1, t1. Hence, the contradiction is obtained.
See the Z3 guide for more details on patterns. More involved texts about patterns can be found, e.g. in
this paper, in
this paper or in
this paper.
I have a 32bit bit vector expression. Somehow I want to do a signed or unsigned extension on this expression to a 64bit bit vector. Is there any API I can use?
For sign extension:
Z3_ast Z3_API Z3_mk_sign_ext(__in Z3_context c, __in unsigned i, __in Z3_ast t1);
https://github.com/Z3Prover/z3/blob/master/src/api/z3_api.h#L2826
For unsigned extension:
Z3_ast Z3_API Z3_mk_zero_ext(__in Z3_context c, __in unsigned i, __in Z3_ast t1);
https://github.com/Z3Prover/z3/blob/master/src/api/z3_api.h#L2838
These functions are also available in bindings for Python, C#, Java
To simplify the question, if there is a method that has no overloading, and its signiture is: Func<int, int, int, int>, does F# have any helper function to get (fun (a, b, c) -> myFun(a, b, c)) which is of signiture Func<int * int * int, int>
In other functional languages, this is usually called "un-currying", but F# does not include this in the core library. You can define the function quite easily yourself:
let uncurry3 f = (fun (a,b,c) -> f a b c)
Unfortunately, this won't work for any number of arguments - you need to define uncurryX for each number of arguments that you would like to use.
In practice, I would probably not do this though. It can lead to point-free code that is hard to read and debug. Sometimes, a bit more verbosity is useful :-) and if you end up applying this to a certain function too often, it is a good sign that perhaps it should have been defined in the other style.
BTW: The answer is assuming that you use Func to refer to ordinary F# functions. If you were referring to the .NET Func delegate (rather than functions), then you could write:
let uncurry3 (f:Func<_, _, _, _>) =
System.Func<_, _>(fun (a,b,c) -> f.Invoke(a, b, c))
When using a model object, I call func_decl get_func_decl (unsigned i) to get the value assigned to a certain function (variable). The problem I am having is taking the output of that (which is a func_decl) and converting it to int.
For example, if the model is {x |-> 4, y |-> 12, z |-> 6}, I would like to get the actual int values of those 3 variables (4, 12 and 6).
Z3 provides the function Z3_get_numeral_int for this purpose:
Z3_bool Z3_API Z3_get_numeral_int(__in Z3_context c, __in Z3_ast v, __out int* i);
Note that the last parameter is a point to an integer that will be filled with the right value if the call succeeds (it will fail for non-numerals or numerals which are not representable as an int).
There are also other functions called Z3_get_numeral_* to obtain values of different types, e.g., uint64 etc.
This method works for constants (i.e., func_decls of arity 0). To get the entries of a (non-zero arity) function definition, the following function should be used:
Z3_func_entry Z3_API Z3_func_interp_get_entry(__in Z3_context c, __in Z3_func_interp f, unsigned i);
I want to create an expr object from a given SMTLIB2 file. I can see a Z3_parse_smtlib_string function in the C examples. Is there a wrapper for that in the expr class?
The Z3 C++ API does not explicitly provide this functionality as part of the expr class. However, the C++ API can be used alongside the C API, i.e., the function Z3_parse_smtlib_string (or ..._file) can be used to achieve this. Note that this function returns a Z3_ast, which must be converted to an expr object to get back to the C++ "world".
A simple example:
#include <z3++.h>
...
context ctx;
Z3_ast a = Z3_parse_smtlib2_file(ctx, "test.smt2", 0, 0, 0, 0, 0, 0);
expr e(ctx, a);
std::cout << "Result = " << e << std::endl;
Since the Z3_parse_smtlib2_* functions do not perform error checking, no exception will be thrown upon errors. This can be achieved by calls to context::check_error().