Read func interp of a z3 array from the z3 model
The representation for array models is indeed a bit confusing. The meaning of
(define-fun some_array_1 () (Array Int Int)
(_ as-array k!0))
is that the model for array some_array_1
is the function k!0
which is to be interpreted as an array (signified by the call to as-array
. The latter is a parametric function, which has no arguments, therefore, to get at the actual definition of the model function for some_array_1, we have to look up which function as-array
calls. In the given example, we can do that as follows, first making sure that we actually have an array model in the expected format by checking a few of assertions:
assert(Z3_get_decl_kind(c, some_array_1_eval_func_decl) == Z3_OP_AS_ARRAY);
assert(Z3_is_app(c, some_array_1_eval));
assert(Z3_get_decl_num_parameters(c, some_array_1_eval_func_decl) == 1);
assert(Z3_get_decl_parameter_kind(c, some_array_1_eval_func_decl, 0) ==
Z3_PARAMETER_FUNC_DECL);
func_decl model_fd = func_decl(c,
Z3_get_decl_func_decl_parameter(c, some_array_1_eval_func_decl, 0));
The function declaration model_fd
then holds the actual function assigned by the model (k!0
) and we can get the function interpretation via
func_interp fun_interp = m.get_func_interp(model_fd);
Retrieving array from model in Z3Py
You can ask the model to evaluate (eval(...)
) the array at a particular point by constructing a call to the associated array model function. Here's an example:
b = Array('b', IntSort(), BitVecSort(8))
s = Solver()
s.add(b[0] == 21)
s.add(b[1] == 47)
s.check()
m = s.model()
print(m[b])
print(m.eval(b[0]))
print(m.eval(b[1]))
which produces
[1 -> 47, 0 -> 21, else -> 47]
21
47
Z3: Extract array interpretation
Yes, this is possible. A very similar question has been asked recently and the answer with examples can be found here: Read func interp of a z3 array from the z3 model
Extract value from const array in Z3
Thanks to Christoph's hint. I solve this problem by the following code:
suppose
mval = model.eval(...);
mfd = mval.decl();
Then,
while(Z3_get_decl_kind(c.ctx(), mfd) == Z3_OP_STORE) {
expr addr = mval.arg(1);
expr data = mval.arg(2);
// put them into the stack, say __stack__ for later use
// I omit the code for using them
mval = mval.arg(0);
mfd = mval.decl();
// recursively handle the OP_STORE case, because the first
// argument can still be an Z3_OP_STORE
}
// now that we peel the Z3_OP_STORE
if(Z3_get_decl_kind(c.ctx(), mfd) == Z3_OP_CONST_ARRAY) {
expr arg0 = mval.arg(0);
// we can just use it directly since it is a constant
std::string sdef(Z3_get_numeral_string(context, arg0));
// I omit the code for using that value
}
else if( Z3_get_decl_kind(c.ctx(), mfd) == Z3_OP_AS_ARRAY ) {
// HERE is the original code for handling original case.
// in the question from the link:
// http://stackoverflow.com/questions/22885457/read-func-interp-of-a-z3-array-from-the-z3-model/22918197#22918197?newreg=1439fbc25b8d471981bc56ebab6a8bec
//
}
Hope it can be helpful to others.
Understanding the index of all constants of a model
Thanks Tushar for answering the post. You are right that the additional variables come from the existential quantifier. Z3 will skolemize these variables and as it currently stands, the model returned by Z3 includes constants from skolemized existential quantifiers.
This is evidently confusing and we may in the future filter
such variables (and functions) away from the model construction. On the other hand, the naming conventions used for the existential variables retain the names from the quantifiers so that it may be possible, at least manually, to track back the origin of those extra variables.
If I mark it after (get-model)?
As Patrick commented, it's really hard to decipher what you're asking. Please provide some code snippets to show what you get and what you hope to achieve.
Having said that, I'll take a wild guess that you are in a situation where the solver is unsat
, i.e., (check-sat)
returns an unsat
response. Yet, your script has (get-model)
in the next line, which of course errors out since there's no model. And you'd like a way to avoid the error message.
This is a known limitation of SMTLib command language: You cannot programmatically inspect the output of commands, unfortunately. The usual way to solve this sort of problem is to have a "live" connection to the solver (typically in the form of a text pipe), and read a line after issuing (check-sat)
, and programmatically continue depending on the response. This is how most systems built on top of SMT-solvers work.
Alternatively, you can use higher-level APIs in other languages (C/C++/Java/Python/Haskell..) and program z3 that way; and use the facilities of the host language to direct that interaction. This requires you to learn another interface on top of SMTLib, but for serious uses of this technology, you probably don't want to limit yourself to a pure SMTLib interface anyhow.
Also see this answer for a related discussion: Executing get-model or unsat-core depending on solver's decision
Hope this addresses your issue, though it's hard from your question whether this is what you were getting at.
Problem with function from_file() at z3py
Separately reading the files and loading to solver is your best bet, as you found out.
Unless efficiency is of paramount importance, I would not worry about trying to optimize this any further. For any reasonable problem, your solver time will dominate any time spent in loading the assertions from a few (or a few thousand!) files. Do you have a use case that really requires this part to be significantly faster?
Related Topics
Receiving Only Necessary Data with C++ Socket
C++ Template/Ostream Operator Question
C++ Get Handle of Open Sockets of a Program
How to Print the Value of Nullptr on Screen
Convert Hexadecimal String with Leading "0X" to Signed Short in C++
What Is the Meaning of This Star (*) Symbol in C++? - Pointer to Member
Error: 'Null' Was Not Declared in This Scope
What Are Some Tricks I Can Use with MACros
Update Console Without Flickering - C++
Crtp -- Accessing Incomplete Type Members
Workaround for Error C2536: Cannot Specify Explicit Initializer for Arrays in Visual Studio 2013
Remove Duplicates from a List<Int>
How Does the Stl's Multimap Insert Respect Orderings
Reasonably Portable Way to Get Top 64-Bits from 64X64 Bit Multiply
Using an Union (Encapsulated in a Struct) to Bypass Conversions for Neon Data Types
The Difference Between C and C++ Regarding the ++ Operator