Variables bounds not taken into account by Z3 / OCaml binding - neural-network

Good afternoon,
I am trying to build a formula with some variables that have bounds, using the Z3 OCaml bindings. For the context, I am trying to prove safety properties on a neural network encoded as an SMT formula.
Some of my inputs variables have bounds on their values, bounds that I would like to
add as constraints on my SMT formulaes. I am then iteratively adding new constraints to my solver stack and checking if they are working.
Here is the initial content of the solver stack, obtained with Z3.Solver.get_assertions. It contains the neural network control flow without certain
nodes, the weights and biases values, and the input bound constraints.
(forall ((x Real)) (= (reluR x) (ite (> x 0.0) x 0.0)))
[...]
;bunch of variables definitions and constraints
[...]
;input variables definitions
(> |CELL_actual_input_0_0_0_1| (/ 1.0 2.0))
(< |CELL_actual_input_0_0_0_1| 2.0)
(> |CELL_actual_input_0_0_0_0| (/ 1.0 2.0))
(< |CELL_actual_input_0_0_0_0| 2.0)
;a bunch of contraints defining the control flow of the network, here is an example
(= |CELL_actual_output_0_0_0_0| (+ |CELL_22_0_0_0_0| |CELL_l_4.bias_0|))
(= |CELL_14_0_0_0_1|
(+ (* |CELL_12_0_0_0_0| |CELL_25_0_1|)
(* |CELL_12_0_0_0_1| |CELL_25_1_1|)
(* |CELL_12_0_0_0_2| |CELL_25_2_1|)
(* |CELL_12_0_0_0_3| |CELL_25_3_1|)))
[...]
I then added the following expressions, describing the activation of a ReLU node.
(= |CELL_20_0_0_0_0| |CELL_19_0_0_0_0|)
(> |CELL_19_0_0_0_0| 0.0)
The solver answer positively, and something bugs me on the corresponding model:
[...]
(define-fun |CELL_actual_input_0_0_0_0| () Real
0.0)
(define-fun |CELL_actual_input_0_0_0_1| () Real
0.0)
[...]
It seems that it violates my input bounds constraints.
The content of solver stack after solving is the following, I am not sure I am understanding the lines from the forall
(forall ((x Real)) (= (reluR x) (k!11 x)))
(not (<= |CELL_actual_input_0_0_0_1| (/ 1.0 2.0)))
(not (<= 2.0 |CELL_actual_input_0_0_0_1|))
(not (<= |CELL_actual_input_0_0_0_0| (/ 1.0 2.0)))
(not (<= 2.0 |CELL_actual_input_0_0_0_0|))
(forall ((x!1 Real))
(! (or (not (<= x!1 0.0)) (= (k!11 x!1) 0.0)) :pattern ((k!11 x!1))))
(forall ((x!1 Real))
(! (or (<= x!1 0.0) (= (k!11 x!1) x!1)) :pattern ((k!11 x!1))))
Note that I am declaring my control flow where the inputs variables are already appearing first, then I redeclare my input with the Arithmetic.Real.mk_const_s ctx name, where
name is the same. Could it be that the variable being recorded twice in the stack?
Thank in advance for your answers

Related

Unused Lexical Variable

Just started learning lisp. I have no idea why I am getting these errors or even what they mean. I am simply trying to code an approximation of pi using the Gregory-Leibniz series, here is the code.
(defun gl (n)
(defparameter x 0) ;init variable to hold our runnning sum
(loop for y from 0 to n ;number of iterations, starting from 0 to desired n
(if (= y 0) ;if n is 0 then we just want 4
(defparameter w 4))
(if (> y 0) ;else, 4*(-1^y)/((2 * y)+1)
(defparameter w (* 4 (/ (exp -1 y) (+ (* 2 y) 1)))))
(+ x w)) ;add to our running sum
(write x)) ;once loop is over, print x.
I have tried using setq, defvar, let etc. instead of defparameter but I still get "Undeclared free variable X".
I also get the error "Unused lexical variable N" even though I am using it for my loop, which is weird also.
How can I fix this and why is it happening? Thanks!
Here is the code after Emacs auto-indented it:
(defun gl (n)
(defparameter x 0)
(loop for y from 0 to n
(if (= y 0)
(defparameter w 4))
(if (> y 0)
(defparameter w (* 4 (/ (exp -1 y) (+ (* 2 y) 1)))))
(+ x w))
(write x))
Compiling the following code with SBCL gives one error and two warnings.
One warning says that x is undefined.
You should not call defparameter from inside your function, since defvar and defparameter are used to declare dynamic variables and to set their value in the global scope. Prefer to have let bindings, or, since you already are using a loop, a with clause. When you want to modify a binding, use setf.
The errors comes from the macroexpansion of LOOP, which is malformed. For SBCL, that means that the code is treated as dead-code for the rest of the function compilation; that explains why n appears not to be used, which is what the second warning is about.
There are various fixes remaining to be done:
Use function EXPT, not EXP.
Calling (+ x w) only computes a value but does not modify x, the result is useless.
Prefer using if as expression, like a ternary operator in other languages, in your case the code can be simplified
Adding one can be done with function 1+ (that's the name of the function, not a special syntax for adding constants)
The write operation is rarely needed, especially if you are computing a mathematical formula; just return the value, and the REPL will print it automatically.
Small corrections that make your code works:
(defun gl (n)
(let ((x 0))
(loop
for y from 0 to n
for w = (if (= y 0)
4
(* 4 (/ (expt -1 y) (+ (* 2 y) 1))))
do (setf x (+ x w)))
(write x)))
I would personally get rid of x and w, and use a SUM loop clause.
(defun gl (n)
(loop
for y from 0 to n
sum (if (zerop y)
4
(* 4 (/ (expt -1 y)
(1+ (* 2 y)))))))

Comparing flonum

I want to define a function that would have the following properties:
(almost-equal? (cos (/ pi 2)) 0.0) ; --> #t
For doing that I thought that I should use flulp in the following way:
(define (almost-equal? a b)
(let [[epsilon (max (abs (flulp (* 10.0 a))) (abs (flulp (* 10.0 b))))]]
(<= (absolute-error a b) epsilon)))
But it failed to pass my test. Do we have a canonical way of doing such comparison? Any advise are welcome.
Use relative-error: documentation
I can recommend this article on how to debug numerical functions:
Practically Accurate Floating-Point Math
by Neil Toronto and Jay McCarthy

if: Bad syntax error (Scheme programming)

(define generalized-triangular
(lambda (input n)
(if (= n 1)
1
(+ (input n) (generalized-triangular (- n 1))))))
This program is designed to take a number and a function as inputs and do the following..
f(1) + f(2) + f(3)+ … + f(N).
An example input would be:
(generalized-triangular square 3)
The Error message:
if: bad syntax;
has 4 parts after keyword in: (if (= n 1) 1 (+ (input n) (generalized-triangular (- n 1))) input)
The error is quite explicit - an if form can only have two parts after the condition - the consequent (if the condition is true) and the alternative (if the condition is false). Perhaps you meant this?
(if (= n 1)
1
(+ (input n) (generalized-triangular input (- n 1))))
I moved the input from the original code, it was in the wrong place, as the call to generalized-triangular expects two arguments, in the right order.
For the record: if you need to execute more than one expression in either the consequent or the alternative (which is not the case for your question, but it's useful to know about it), then you must pack them in a begin, for example:
(if <condition> ; condition
(begin ; consequent
<expression1>
<expression2>)
(begin ; alternative
<expression3>
<expression4>))
Alternatively, you could use a cond, which has an implicit begin:
(cond (<condition> ; condition
<expression1> ; consequent
<expression2>)
(else ; alternative
<expression3>
<expression4>))
Literal answer
The code you posted in your question is fine:
(define generalized-triangular
(lambda (input n)
(if (= n 1)
1
(+ (input n) (generalized-triangular (- n 1))))))
The error message in your question would be for something like this code:
(define generalized-triangular
(lambda (input n)
(if (= n 1)
1
(+ (input n) (generalized-triangular (- n 1)))
input)))
The problem is input. if is of the form (if <cond> <then> <else>). Not counting if itself, it has 3 parts. The code above supplies 4.
Real answer
Two tips:
Use DrRacket to write your code, and let it help you with the indenting. I couldn't make any sense of your original code. (Even after someone edited it for you, the indentation was a bit wonky making it still difficult to parse mentally.)
I don't know about your class, but for "real" Racket code I'd recommend using cond instead of if. Racket has an informal style guide that recommends this, too.
here's the tail-recursive
(define (generalized-triangular f n-max)
(let loop ((n 1) (sum 0))
(if (> n n-max)
0
(loop (+ n 1) (+ sum (f n))))))
Since you're using the racket tag, I assume the implementation of generalized-triangular is not required to use only standard Scheme. In that case, a very concise and efficient version (that doesn't use if at all) can be written with the racket language:
(define (generalized-triangular f n)
(for/sum ([i n]) (f (+ i 1))))
There are two things necessary to understand beyond standard Scheme to understand this definition that you can easily look up in the Racket Reference: how for/sum works and how a non-negative integer behaves when used as a sequence.

LISP SICP Video Lecture 2a Average Damp Question

In the following code, I am trying to understand how the variable whatami gets its value. In following the logic, I see that the procedure (lambda (y) (/ x y)) is the parameter that I am passing to the method average-damp, and is represented within that method as the variable f. It seems as though (/ x y) and (average (f whatami) whatami) need to be executed, but I can't figure out the order of execution. Any help is appreciated.
(define (average x y)
(/ (+ x y) 2))
(define (fixed-point f start)
(define tolerance 0.00001)
(define (close-enuf? u v)
(< (abs (- u v)) tolerance))
(define (iter old new)
(if (close-enuf? old new)
new
(iter new (f new))))
(iter start (f start)))
(define average-damp
(lambda (f)
(lambda (whatami) (average (f whatami) whatami))))
; square root with average damping
(define (_sqrt x)
(fixed-point
(average-damp (lambda (y) (/ x y)))
1))
(_sqrt 4.0)
The average-damp procedure takes a procedure as its argument and returns a procedure as its value. When given a procedure that takes one argument, average-damp returns another procedure that computes the average of the values before and after applying the original function f to its argument. It's inside the fixed-point procedure where that returned function is applied (iteratively).
So the average-damp procedure doesn't execute either (/ x y) or (average(f whatami) whatami) at all, it just uses the function passed to it to create a new function that it returns.

Simple LISP function not working

I decided to learn LISP today, and have been playing around with it for a bit. I wrote a simple baby function just to test my understanding, and now understand that my understanding doesn't understand as much as I had understood it to understand. :D
Anyway, here is the function. The idea is that when it is called, e.g. (esexp base x) it should return the value base^x. So (esexp 3 4) = 3^4 = 81.
(I am using the CMU implementation of Common Lisp, if that matters.)
(defun esexp (base x)
(if (= x 0)
1
(if (< x 0)
(/ esexp (base (+ x 1)) base)
(* esexp (base (+ x 1)) base))))
This doesn't work. I get errors that look like (Warning: This variable is undefined: SLBEXP) and (Error in KERNEL::UNBOUND-SYMBOL-ERROR-HANDLER: the variable SLBEXP is unbound.) So. What am I doing wrong? AND would there be a better (or more LISP-ish way) to write this function?
ETA
Corrected code:
(defun esexp (base x)
(if (= x 0)
1
(if (< x 0)
(/ (esexp base (+ x 1)) base)
(* (esexp base (- x 1)) base))))
esexp(base (+ x 1))
should be
(esexp base (+ x 1))
esexp is a function just like +. The syntax for invoking a function is
(function-name arg1 arg2 ...)
The technical explanation of the error: the compiler was parsing the code:
(/ esexp(base (+ x 1)) base)
as this:
(/ esexp (base (+ x 1)) base)
which says:
first, add 1 to the parameter x
then, invoke a function called base with the result above.
divide the value of a variable called esexp by the result above.
then, divide that result by the parameter base. (The divide operator in Common Lisp can take more than two arguments.)
You see the trick? When a word appears as the first item in a s-expression (and that s-expression isn't quoted), it's usually treated as the name of a function you want to invoke. Otherwise, it's treated as the name of a variable whose value you want to retrieve. Further, in Common Lisp a symbol like esexp can be bound to both a function value and a variable value at the same time; context or special expressions like #'esexp (which means the function) are used to figure out which one you mean.
The compiler was telling you that, though esexp was bound to a function with your defun statement, it had not yet been bound to a variable value, and therefore could not be used as such. Hence, the error.
Just a note about the code. I believe it should be
(defun esexp (base x)
(if (= x 0)
1
(if (< x 0)
(/ (esexp(base (+ x 1)) base))
(* (esexp(base (- x 1)) base))))
Otherwise the function will never terminate. (you had (* (esexp(base (+ x 1)) base)))))