Use of context in C++ API - z3

I have the following program , which transforms a string into a Boolean formula (string_to_formula), where I am defining expr_vector b(c). This code works, but I am not being able to reason about the context. What is the function of a context? Is there any way we can define the variable b just once? Why do we need to send the context to the function? And can this code be written in a more succinct way?
int main() { try {
context c;
expr form(c);
form = string_to_formula("x1x00xx011",c);
expr form1(c);
form1 = string_to_formula("1100x1x0",c);
solver s(c);
s.add(form && form1);
s.check();
model m = s.get_model();
cout << m << "\n";
}
expr string_to_formula(string str, context& c )
{
expr_vector b(c) ;
for ( unsigned i = 0; i < str.length(); i++)
{ stringstream b_name;
b_name << "b_" << i;
b.push_back(c.bool_const(b_name.str().c_str()));
}
expr formula(c);
formula = c.bool_val(true);
for( unsigned i = 0 ; i < str.length() ; ++i )
{ char element = str.at(i) ;
if ( element == '1' )
formula = formula && ( b[i] == c.bool_val(true) ) ;
else if ( element == '0' )
formula = formula && ( b[i] == c.bool_val(false) ) ;
else if ( element == 'x' )
continue;
}
return formula;
}

The context object is relevant for multi-threaded programs.
Each execution thread can have its own context, and they can be accessed without using any form of synchronization (e.g., mutexes).
Each expression belongs to a single context. We cannot use the same expression in two different contexts, but we can copy them from one context to another.
In Z3, expressions are maximally shared. For example, if we have an expressions such as (f T T) where T is a big term, then internally Z3 has only one copy of T. For implementing this feature, we use a hashtable. The hashtable is stored in the context.
If we use the same context C in two different execution threads, Z3 will probably crash due to race conditions updating C.
If your program has only one execution thread, you can avoid "moving" the context around by having a global variable.
The idea of context/manager is present in many libraries. For example, in CUDD (BDD library), they have a DdManager. In the script language Lua, they have a lua_State. These are all instances of the same idea.

Related

Using a variable as arithmetic operator in Lua

I want to use a variable that references an arithmetic operator within an if statement expression as shown below:
str = { '>60', '>60', '>-60', '=0' }
del = 75
function decode_prog(var1, var2)
op = string.sub(var1, 1, 1)
vb = tonumber(string.sub(var1, 2, 3))
if var2 op vb then
print("condition met")
else
print('condition not meet')
end
end
for i = 1, #str do
decode_prog(str[i], del)
end
When the above code executes, it should either print "condition met" or "condition not met" based on the result of the operation, however I am instead receiving an error.
You cannot substitute a native Lua operator with a variable that references a function, the only way to go about what you are attempted to do is to create a set of functions within an associative array and set the index as a reference to the respective operation you want to conduct.
Looking at your list, you have a greater than (>) and equal to (=). We create a table for these operations that takes two parameters as follows.
local operators = {
[">"] = function(x, y) return x > y end,
["="] = function(x, y) return x == y end,
-- Add more operations as required.
}
You can then invoke the respective function from the decode_prog function by obtaining the operation character from the string, along with the numeric value itself - this is possible because you can obtain the function from the associative array where the index is the string of the operation we want to conduct.
local result = operators[op](var2, number)
This calls upon the operators array, uses the op to determine which index we need to go to for our appropriate operation, and returns the value.
Final Code:
str = { '>60', '>60', '>-60', '=0' }
del = 75
local operators = {
[">"] = function(x, y) return x > y end,
["="] = function(x, y) return x == y end,
}
function decode_prog(var1, var2)
local op = string.sub(var1, 1, 1) -- Fetch the arithmetic operator we intend to use.
local number = tonumber(string.sub(var1, 2)) -- Strip the operator from the number string and convert the result to a numeric value.
local result = operators[op](var2, number) -- Invoke the respective function from the operators table based on what character we see at position one.
if result then
print("condition met")
else
print('condition not meet')
end
end
for i = 1, #str do
decode_prog(str[i], del)
end
I can't make much sense of your code or what you want to achieve doing that but if could simply use load.
You build your expression as a string and run it. Of course you should take care of two character operators like >= which I did not and you should validate your input.
local str={'>60','>60','>-60','=0'}
local del=75
function decode_prog(var1, var2)
local operator = var1:sub(1,1):gsub("=", "==")
local expr = string.format("return %d %s %s", var2,operator, var1:sub(2))
print(string.format("condition %smet", load(expr)() and "" or "not "))
end
for i,v in ipairs(str) do
decode_prog(v, del)
end
A very simple way would be to add a condition for each supported operator:
function decode_prog(var1, var2)
op = string.sub(var1, 1, 1)
vb = tonumber(string.sub(var1, 2)) --remove the last argument and use tonumber()
if vb == nil then return end --if the string does not contain number
if (op == ">" and var2 > vb) or (op == "=" and var2 == vb) --[[add more conditions here]] then
print("condition met")
else
print("condition not met")
end
end
I changed the vb=string.sub(var1,2,3) line too.
This form vb = tonumber(string.sub(var1, 2)) will allow use of numbers that have any number of digits and added tonumber() which will allow us to catch not-a-number errors when comparison would probably fail.
Then I added a logic to determine what the operator is and if the condition is met.
Operator limitations:
This will only work with operators that are one character and operator such as >= will not be possible unless you use a different character for it. ≥ will not play nicely, since it is multiple characters.

For satement in Dafny

I'm confused about Dafny's forall statement if the statement inside the forall is to update a variable such as c.arr[i].d, which is mixed with field and array element access. For instance, the example as follows can't be compiled.
I think, explicitly indicating modifies clause is very tedious, I need indicate: modifies top, modifies top.Cache[i]
datatype CACHE_STATE = I| S| E
datatype MSG_CMD = Empty| ReqS| ReqE| Inv| InvAck| GntS| GntE
type NODE=nat
type DATA=nat
type boolean=bool
class class_0 {
var
Data : DATA,
Cmd : MSG_CMD
}
class class_1 {
var
Data : DATA,
State : CACHE_STATE
}
class TopC{
var
AuxData : DATA,
MemData : DATA,
CurPtr : NODE,
CurCmd : MSG_CMD,
ExGntd : boolean,
ShrSet : array<boolean>,
InvSet : array<boolean>,
Chan3 : array<class_0 > ,
Chan2 : array<class_0 > ,
Chan1 : array<class_0 > ,
Cache : array<class_1 > }
method n_RecvReqS(top:TopC,i:nat, N0:nat )
requires 0<= i<N0
requires top.Chan1.Length ==N0
requires N0>0
requires top.InvSet.Length ==N0
requires N0>0
requires top.ShrSet.Length ==N0
requires N0>0
requires top.Cache.Length ==N0
requires ((top.Chan1[i].Cmd == ReqS) && (top.CurCmd == Empty))
modifies top.Chan1[i]
modifies top.InvSet
modifies top.ShrSet
modifies top
modifies top.Cache
{
top.CurCmd := ReqS;
top.CurPtr := i;
top.Chan1[i].Cmd := Empty;
forall j | 0<= j< N0 {
top.InvSet[j] := top.ShrSet[j];
}
forall j | 0<= j< N0 {
top.Cache[j].State:= I;
}
}
Knowing about a method's effect on the heap is crucial to verification, though writing modifies clauses can be tedious. In your case, you need to account for all of the modifications that method n_RecvReqS performs. As you've noted, this includes every top.Cache[j] objects, for all j's.
One way to include these in your modifies clause is to use a set comprehension:
modifies set j | 0 <= j < top.Cache.Length :: top.Cache[j]
This denotes the set of the objects top.Cache[j], where j ranges among the values satisfying 0 <= j < top.Cache.Length.
Read on for further options.
If you do this often and you consider all of these caches to be part of the representation of a TopC object, then you'll probably want to abstract over the many pieces of your state and put these into a set. If you search the Dafny test suite for declarations like
ghost var Repr: set<object>
you'll find some examples. Then, your entire modifies clause would just be
modifies Repr
If you're not ready to use such a Repr set yet, then there's another simple modifies clause you can write for the cache modifications in your program. If you list a sequence of objects in a modifies clause, Dafny will automatically convert it to the corresponding set of objects. You can convert all of the array elements of top.Cache into a sequence by the expression top.Cache[..]. Thus, to account for the updates in your forall statement, you can write
modifies top.Cache[..]
Unfortunately, Dafny doesn't automatically realize that each top.Cache[j] in the body of your forall statement is indeed an element of the set formed from the sequence top.Cache[..]. It is possible to assist the verifier to help it prove this, but doing so adds some clutter to the forall statement. Here's how I did it:
forall j | 0 <= j < N0 {
(assert top.Cache[j] in top.Cache[..]; top.Cache[j]).State:= I;
}
Rustan

Abstract Syntax Tree for Source Code including Expressions

I am building a new simple programming language (just to learn how compilers work in my free time).
I have already built a lexer which can tokenize my source code into lexemes.
However, I am now stuck on how to form an Abstract Syntax Tree from the tokens, where the source code might contain an expression (with operator precedence).
For simplicity, I shall include only 4 basic operators: +, -, /, and * in addition to brackets (). Operator precedence will follow BODMAS rule.
I realize I might be able to convert the expression from infix to prefix/postfix, form the tree and substitute it.
However, I am not sure if that is possible. Even if it is possible, I am not sure how efficient it might be or how difficult it might be to implement.
Is there some trivial way to form the tree in-place without having to convert to prefix/postfix first?
I came across the Shunting Yard algorithm which seems to do this. However, I found it to be quite a complicated algorithm. Is there something simpler, or should I go ahead with implementing the Shunting Yard algorithm?
Currently, the following program is tokenized by my lexer as follows:
I am demonstrating using a Java program for syntax familiarity.
Source Program:
public class Hello
{
public static void main(String[] args)
{
int a = 5;
int b = 6;
int c = 7;
int r = a + b * c;
System.out.println(r);
}
}
Lexer output:
public
class
Hello
{
public
static
void
main
(
String
[
]
args
)
{
int
a
=
5
;
int
b
=
6
;
int
c
=
7
;
int
r
=
a
+
b
*
c
;
System
.
out
.
println
(
r
)
;
}
}
// I know this might look ugly that I use a global variable ret to return parsed subtrees
// but please bear with it, I got used to this for various performance/usability reasons
var ret, tokens
function get_precedence(op) {
// this is an essential part, cannot parse an expression without the precedence checker
if (op == '*' || op == '/' || op == '%') return 14
if (op == '+' || op == '-') return 13
if (op == '<=' || op == '>=' || op == '<' || op == '>') return 11
if (op == '==' || op == '!=') return 10
if (op == '^') return 8
if (op == '&&') return 6
if (op == '||') return 5
return 0
}
function parse_primary(pos) {
// in the real language primary is almost everything that can be on the sides of +
// but here we only handle numbers detected with the JavaScript 'typeof' keyword
if (typeof tokens[pos] == 'number') {
ret = {
type: 'number',
value: tokens[pos],
}
return pos + 1
}
else {
return undefined
}
}
function parse_operator(pos) {
// let's just reuse the function we already wrote insted of creating another huge 'if'
if (get_precedence(tokens[pos]) != 0) {
ret = {
type: 'operator',
operator: tokens[pos],
}
return pos + 1
}
else {
return undefined
}
}
function parse_expr(pos) {
var stack = [], code = [], n, op, next, precedence
pos = parse_primary(pos)
if (pos == undefined) {
// error, an expression can only start with a primary
return undefined
}
stack.push(ret)
while (true) {
n = pos
pos = parse_operator(pos)
if (pos == undefined) break
op = ret
pos = parse_primary(pos)
if (pos == undefined) break
next = ret
precedence = get_precedence(op.operator)
while (stack.length > 0 && get_precedence(stack[stack.length - 1].operator) >= precedence) {
code.push(stack.pop())
}
stack.push(op)
code.push(next)
}
while(stack.length > 0) {
code.push(stack.pop())
}
if (code.length == 1) ret = code[0]
else ret = {
type: 'expr',
stack: code,
}
return n
}
function main() {
tokens = [1, '+', 2, '*', 3]
var pos = parse_expr(0)
if (pos) {
console.log('parsed expression AST')
console.log(ret)
}
else {
console.log('unable to parse anything')
}
}
main()
Here is your bare-bones implementation of shunting yard expression parsing. This is written in JavaScript. This is as minimalistic and simple as you can get. Tokenizing is left off for brevity, you give the parse the array of tokens (you call them lexemes).
The actual Shunting Yard is the parse_expr function. This is the "classic" implementation that uses the stack, this is my preference, some people prefer functional recursion.
Functions that parse various syntax elements are usually called "parselets". here we have three of them, one for expression, others are for primary and operator. If a parselet detects the corresponding syntax construction at the position pos it will return the next position right after the construct, and the construct itself in AST form is returned via the global variable ret. If the parselet does not find what it expects it returns undefined.
It is now trivially simple to add support for parens grouping (, just extend parse_primary with if (parse_group())... else if (parse_number())... etc. In the meantime your parse_primary will grow real big supporting various things, prefix operators, function calls, etc.

Maintenance of reference counting in Z3

By some reasons I have to use C++ API and C API of Z3 together. In C++ API, reference counting of Z3 objects are well maintained and I needn't to worry about making mistakes. However I have to manually maintain reference counting for Z3 objects when I use C API because C++ API uses Z3_mk_context_rc to create the context. I have several problems on reference counting maintenance in Z3.
(1) If the reference counting of a Z3_ast is reduced to 0, what is responsible to release the memory of this Z3_ast? And when?
(2) The code below
void rctry(context & c)
{
expr x = c.int_const("x");
expr y = c.int_const("y");
Z3_ast res = Z3_mk_eq(c,x,y);
#ifdef FAULT_CLAUSE
expr z = c.int_const("z");
expr u = c.int_const("u");
Z3_ast fe = Z3_mk_eq(c,z,u);
#endif
std::cout << Z3_ast_to_string(c,res) << std::endl;
}
void main()
{
config cfg;
cfg.set("MODEL", true);
cfg.set("PROOF", true);
context c(cfg);
rctry(c);
}
Although I didn't increase reference count for AST referenced by res, the program works well. If FAULT_CLAUSE is defined, program still works, but it will output (= z u) instead of (= x y). How to explain this?
Thank you!
My golden rule for reference counting is: Whenever my program receives a pointer to a Z3 object, I immediately increment the ref count and I save the object somewhere safe (i.e., I now own 1 reference to that object). Only when I'm absolutely sure that I will not need the object any longer, then I will call Z3_dec_ref; from that point on, any access to that object will trigger undefined behavior (not necessarily a segfault), because I don't own any references anymore - Z3 owns all the rerferences and it can do whatever it wants to do with them.
Z3 objects are always deallocated when the ref count goes to zero; it's within the call to dec_ref() that the deallocation happens. If Z3_dec_ref() is never called (like in the example given), then the object may remain in memory so accessing that particular part of the memory might perhaps still give "ok looking" results, but that part of the memory may also be overwritten by other procedures so that they contain garbage.
In the example program given, we would need to add inc/dec_ref calls as follows:
void rctry(context & c)
{
expr x = c.int_const("x");
expr y = c.int_const("y");
Z3_ast res = Z3_mk_eq(c,x,y);
Z3_inc_ref(c, res); // I own 1 ref to res!
#ifdef FAULT_CLAUSE
expr z = c.int_const("z");
expr u = c.int_const("u");
Z3_ast fe = Z3_mk_eq(c,z,u);
Z3_inc_ref(c, fe); I own 1 ref to fe!
#endif
std::cout << Z3_ast_to_string(c, res) << std::endl;
#ifdef FAULT_CLAUSE
Z3_dec_ref(c, fe); // I give up my ref to fe.
#endif
Z3_dec_ref(c, res); // I give up my ref to res.
}
The explanation for the output (= z u) is that the second call to Z3_mk_eq
re-uses the chunk of memory that previously held res, because apparently
only the library itself had a reference to it, so it is free to chose what to
do with the memory. The consequence is that the call to Z3_ast_to_string
reads from the right part of the memory (that used to contain res), but the
contents of that part of the memory have changed in the meanwhile.
That was the long explanation for anybody who needs to manage ref counts in C. In
the case of C++ there is also a much more convenient way: the ast/expr/etc
objects contain a constructor that takes C objects. Therefore, we can construct
managed objects by simply wrapping them in constructor calls; in this
particular example that could be done as follows:
void rctry(context & c)
{
expr x = c.int_const("x");
expr y = c.int_const("y");
expr res = expr(c, Z3_mk_eq(c, x, y)); // res is now a managed expr
#ifdef FAULT_CLAUSE
expr z = c.int_const("z");
expr u = c.int_const("u");
expr fe = expr(c, Z3_mk_eq(c,z,u)); // fe is now a managed expr
#endif
std::cout << Z3_ast_to_string(c, res) << std::endl;
}
Within the destructor of expr there is a call to Z3_dec_ref, so that it
will be called automatically at the end of the function, when res and fe go
out of scope.

Traversing Z3_ast tree in C/C++

In short, I need to be able to traverse Z3_ast tree and access the data associated with its nodes. Cannot seem to find any documentation/examples on how to do that. Any pointers would be helpful.
At length, I need to parse smt2lib type formulae into Z3, make some variable to constant substitutions and then reproduce the formula in a data structure which is compatible with another unrelated SMT sovler (mistral to be specific, I don't think details about mistral are important to this question but funnily enough it does not have a command line interface where I can feed it text formulae. It just has a C API). I have figured that to generate the formula in mistral's format, I would need to traverse the Z3_ast tree and reconstruct the formula in the desired format. I cannot seem to find any documentation/examples that demonstrate how to do this. Any pointers would be helpful.
Consider using the C++ auxiliary classes defined at z3++.h. The Z3 distribution also includes an example using these classes. Here is a small code fragment that traverses a Z3 expression.
If your formulas do not contain quantifiers, then you don't even need to handle the is_quantifier() and is_var() branches.
void visit(expr const & e) {
if (e.is_app()) {
unsigned num = e.num_args();
for (unsigned i = 0; i < num; i++) {
visit(e.arg(i));
}
// do something
// Example: print the visited expression
func_decl f = e.decl();
std::cout << "application of " << f.name() << ": " << e << "\n";
}
else if (e.is_quantifier()) {
visit(e.body());
// do something
}
else {
assert(e.is_var());
// do something
}
}
void tst_visit() {
std::cout << "visit example\n";
context c;
expr x = c.int_const("x");
expr y = c.int_const("y");
expr z = c.int_const("z");
expr f = x*x - y*y >= 0;
visit(f);
}

Resources