Converting z3 C++ API ast (or solver) objects to SMTLIB string - c++

I am playing around with z3 and other SMT solvers and want to examine the cases where other solvers like boolector triumph over z3 and vice-versa. For this purpose, I need a way to convert declarations and assertions to the SMT-LIB2 format that other SMT solvers can recognize.
For example, for this example
void print_as_smtlib2_string() {
context c;
expr x = c.int_const("x");
expr y = c.int_const("y");
solver s(c);
s.add(x >= 1);
s.add(y < x + 3);
std::cout << s.check() << "\n";
Z3_set_ast_print_mode(c, Z3_PRINT_SMTLIB_COMPLIANT);
std::cout << "\nSolver is:\n";
std::cout << s << "\n";
}
I get something like:
sat
Solver is:
(solver
(>= x 1)
(< y (+ x 3)))
What I want instead is something like this (rise4fun link: http://rise4fun.com/Z3/aznC8):
(declare-const x Int)
(declare-const y Int)
(assert (>= x 1))
(assert (< y (+ x 3)))
(check-sat)
I have tried C API functions such as Z3_set_ast_print_mode, Z3_ast_to_string but haven't been successful. I looked at Z3_benchmark_to_smtlib_string but this post Input arguments of Z3_benchmark_to_smtlib_string() suggests that it only supports SMTLIB 1.0.

Z3_benchmark_to_smtlib_string is the only function Z3 has for this purpose. Like the post you refer to mentions, it has been extended to SMTLIB2. As Leo says in his reply to that post, it is an old function that is rarely used, and it may not support dumping all the features (e.g., parameters on solvers). Recently, there was also another post relating to this function and problems/bugs in older versions of Z3 (see here).

Related

Get result of tactics application as an expression in Z3

Is there anything similar in C++ like Z3py interface's as_expr(). I'm trying to get the result of applying the tactics as a z3 expression, exp, not as type apply_result.
For example, in the below code
context c;
expr x = c.bool_const("x");
expr y = c.bool_const("y");
expr f = ( (x || y) && (x && y) );
solver s(c);
goal g(c);
g.add( f );
tactic t1(c, "simplify");
apply_result r = t1(g);
std::cout << r << "\n";
Also, is there any way to convert the apply_result into z3 expr?
In general, the result of a tactic application is a set of goals. Most tactics produce only one goal, but some produce more than one. For each of those subgoals, you can use as_expr() and then logical-or them together. We can add an as_expr(...) to class apply_result if that helps. (I'm busy with other stuff at the moment; if you add it yourself, submit a pull request, contributions very welcome!)

Z3 C++ API: set parameter for tactic

I'm using the Z3 C++ API of the SMT Solver and I'd like to change parameters of the "ctx-solver-simplify". I don't know how to input them to the tactic. I tried:
z3::context c;
c.set("arith_lhs",false);
c.set("eq2ineq",true);
And
z3::params params(c);
params.set("arith_lhs",true);
params.set("eq2ineq",true);
Example code:
z3::expr x = c.int_const("x");
z3::expr cond1 = !(x==4);
z3::goal g(c);
g.add(cond1);
z3::tactic t(c, "ctx-solver-simplify");
z3::apply_result r = t(g);
The result is
(goal (not (= x 4)))
And not
(goal and (< x 4) (> x 4)
Same applies for arith_lhs. Any help?
Thanks!
Change:
z3::tactic t(c, "ctx-solver-simplify");
to
z3::tactic t = with(z3::tactic(c, "simplify"), params);
This will instruct Z3 to apply the simplify tactic with the selected parameters. In the SMT-LIB API this is accomplished with the "using-params" combinator. I got the above C++ equivalent from example.cpp shipped with the Z3 source.
So there were two problems: (1) You need to tell Z3 to apply the given tactic with the selected parameters. (2) the ctx-solver-simplify tactic does not have an eq2ineq option. Other tactics do, though, including simplify.

Why does my hash function fail with "ArithmeticException integer overflow" even when using unchecked math

I am using the following function to try to create a 64-bit hash of a string, but it is failing with an ArithmeticException even though I am using the "unchecked" version of the arithmetic operators.
user> (reduce (fn [h c]
(unchecked-add (unchecked-multiply h 31) (long c)))
1125899906842597
"hello")
ArithmeticException integer overflow clojure.lang.Numbers.throwIntOverflow (Numbers.java:1388)
What am I doing wrong here?
have a hint here:
for whatever reason the first param in a function here is treated as integer. Adding type hint helps to solve this problem:
user> (reduce (fn [^long h c]
(unchecked-add (unchecked-multiply h 31) (long c)))
1125899906842597
"hello")
7096547112155234317
update:
moreover: it looks that it comes from the unchecked-multiply
user> (reduce (fn [h c]
(unchecked-add (unchecked-multiply ^long h 31) (long c)))
1125899906842597
"hello")
7096547112155234317
i will make some additional research, and update here, in case of any new information
update 2:
ok, that's what i've found out:
looking at the clojure's documentation at https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Numbers.java
we can see the following:
our case
static public Number unchecked_multiply(Object x, long y){return multiply(x,y);}
leads to:
static public Number multiply(Object x, long y){
return multiply(x,(Object)y);
}
then:
static public Number multiply(Object x, Object y){
return ops(x).combine(ops(y)).multiply((Number)x, (Number)y);
}
so at the end it calls multiply method from LongOps inner class.
final public Number multiply(Number x, Number y){
return num(Numbers.multiply(x.longValue(), y.longValue()));
}
so finally it leads us to a simple (checked?) multiply:
static public long multiply(long x, long y){
if (x == Long.MIN_VALUE && y < 0)
return throwIntOverflow();
long ret = x * y;
if (y != 0 && ret/y != x)
return throwIntOverflow();
return ret;
}
kaboom!
so i don't know whether it is a bug or the desired behavior, but it looks really weird to me.
so the only thing i could advice, is to always remember to typehint your values when using unchecked math in clojure.
You can get the behaviour you want by avoiding the function calls:
(loop [h 1125899906842597
cs "hello"]
(let [c (first cs)]
(if c
(recur (unchecked-add (unchecked-multiply h 31) (long c))
(rest cs))
h)))
;7096547112155234317
Why this is so, I don't know.

Tuppled function versus curried function performance in SML/NJ

I'm learning functional programming using the SML language. While reading my study notes, I came across a question, that asks which kind of a function (tuppled or curried) performs faster.
I've looked at the video here, where the instructor says that this is a matter of language implementation and states (at 5:25) that SML/NJ performs faster with tuppled functions, but doesn't state why that is.
I think my instructor once said, that it's because the curried function creates more closures, but I think I didn't hear right.
Can someone, please, elaborate on this?
There's some more intermediate evaluation for curried functions. Let's say we wanted a function so sum three numbers. We consider the following two definitions:
fun sum (x,y,z) = x + y + z
Alternatively,
fun sum x y z = x + y + z
Consider the following rough evaluation trace on the first version:
:> sum(1,2,3)
1 + 2 + 3 (substitution using pattern matching on the contents of the tuple)
(1 + 2) + 3
3 + 3
6
On the other hand, with the curried version SML will construct some anonymous functions on the fly as it is evaluating the expression. This is because curried functions take advantage of the fact that anonymous functions can be returned as the results of other functions in order to capture the behavior of applying multiple arguments to a single function. Constructing the functions takes some constant amount of time.
:> sum 1 2 3
((sum 1) 2) 3
(((fn x => (fn y => (fn z => x + y + z))) 1) 2) 3
((fn y => (fn z => 1 + y + z)) 2) 3
(fn z => 1 + 2 + z) 3
1 + 2 + 3
(1 + 2) + 3
3 + 3
6
So there are some extra steps involved. It certainly should not cause performance issues in your program, however.

Struggling with BFGS minimization algorithm for Logistic regression in Clojure with Incanter

I'm trying to implement a simple logistic regression example in Clojure using the Incanter data analysis library. I've successfully coded the Sigmoid and Cost functions, but Incanter's BFGS minimization function seems to be causing me quite some trouble.
(ns ml-clj.logistic
(:require [incanter.core :refer :all]
[incanter.optimize :refer :all]))
(defn sigmoid
"compute the inverse logit function, large positive numbers should be
close to 1, large negative numbers near 0,
z can be a scalar, vector or matrix.
sanity check: (sigmoid 0) should always evaluate to 0.5"
[z]
(div 1 (plus 1 (exp (minus z)))))
(defn cost-func
"computes the cost function (J) that will be minimized
inputs:params theta X matrix and Y vector"
[X y]
(let
[m (nrow X)
init-vals (matrix (take (ncol X) (repeat 0)))
z (mmult X init-vals)
h (sigmoid z)
f-half (mult (matrix (map - y)) (log (sigmoid (mmult X init-vals))))
s-half (mult (minus 1 y) (log (minus 1 (sigmoid (mmult X init-vals)))))
sub-tmp (minus f-half s-half)
J (mmult (/ 1 m) (reduce + sub-tmp))]
J))
When I try (minimize (cost-func X y) (matrix [0 0])) giving minimize a function and starting params the REPL throws an error.
ArityException Wrong number of args (2) passed to: optimize$minimize clojure.lang.AFn.throwArity (AFn.java:437)
I'm very confused as to what exactly the minimize function is expecting.
For reference, I rewrote it all in python, and all of the code runs as expected, using the same minimization algorithm.
import numpy as np
import scipy as sp
data = np.loadtxt('testSet.txt', delimiter='\t')
X = data[:,0:2]
y = data[:, 2]
def sigmoid(X):
return 1.0 / (1.0 + np.e**(-1.0 * X))
def compute_cost(theta, X, y):
m = y.shape[0]
h = sigmoid(X.dot(theta.T))
J = y.T.dot(np.log(h)) + (1.0 - y.T).dot(np.log(1.0 - h))
cost = (-1.0 / m) * J.sum()
return cost
def fit_logistic(X,y):
initial_thetas = np.zeros((len(X[0]), 1))
myargs = (X, y)
theta = sp.optimize.fmin_bfgs(compute_cost, x0=initial_thetas,
args=myargs)
return theta
outputting
Current function value: 0.594902
Iterations: 6
Function evaluations: 36
Gradient evaluations: 9
array([ 0.08108673, -0.12334958])
I don't understand why the Python code can run successfully, but my Clojure implementation fails. Any suggestions?
Update
rereading the docstring for minimize i've been trying to calculate the derivative of cost-func which throws a new error.
(def grad (gradient cost-func (matrix [0 0])))
(minimize cost-func (matrix [0 0]) (grad (matrix [0 0]) X))
ExceptionInfo throw+: {:exception "Matrices of different sizes cannot be differenced.", :asize [2 1], :bsize [1 2]} clatrix.core/- (core.clj:950)
using trans to convert the 1xn col matrix to a nx1 row matrix just yields the same error with opposite errors.
:asize [1 2], :bsize [2 1]}
I'm pretty lost here.
I can't say anything about your implementation, but incanter.optimize/minimize expects (at least) three parameters and you're giving it only two:
Arguments:
f -- Objective function. Takes a collection of values and returns a scalar
of the value of the function.
start -- Collection of initial guesses for the minimum
f-prime -- partial derivative of the objective function. Takes
a collection of values and returns a collection of partial
derivatives with respect to each variable. If this is not
provided it will be estimated using gradient-fn.
Unfortunately, I'm not able to tell you directly what to supply (for f-prime?) here but maybe someone else is. Btw, I think the ArityException Wrong number of args (2) passed to [...] is actually quite helpful here.
Edit: Actually, I think the docstring above is not correct, since the source code does not use gradient-fn to estimate f-prime. Maybe, you can use incanter.optimize/gradient to generate your own?
First, Your cost function should have a parameter for theta like your python implementation however your implementation has fixed as initial-value.
Second, if your cost-func is correct, then you can call optimize like this
(optimize (fn [theta] (cost-func theta X y)) [0 0 0])
Hope this can help you.