Why is this Symbolic Execution with Z3 resulting in an error? - c

I am trying to generate test cases using a symbolic execution logic based on the SMT Solver Z3.
I have the following code.
void foo(int a, int b, int c){
int x = 0, y = 0, z = 0;
if(a){
x = -2;
}
if (b < 5){
if (!a && c) { y = 1; }
z = 2;
}
assert(x + y + z != 3);
}
Now, an error occurs during the SMT Solving process and the resulting error log is like below.
(set-option :produce-unsat-cores true)
(set-option :produce-models true)
(set-option :produce-proofs true)
(define-sort bot () Int)
(declare-const sv_1 Int)
(declare-const sv_5 Int)
(define-fun strcmp ((a String) (b String)) Int (ite (= a b) 0 1))
(assert (! (not (= sv_1 0)) :named __a0))
(assert (! (< sv_5 5) :named __a1))
(assert (! (not (not (= sv_1 0))) :named __a2))
(assert (! (not (not (= (+ (+ (bvneg 2) 0) 2) 3))) :named __a3))
(check-sat)
(get-unsat-core)
(get-model)
I have done some testing with this code.
If I do not use x, y, z in the assert function, there is no error.
If the first 'if statement' is true (i.e. a != 0), then the program will never enter the 'if (!a && c) statement. If I erase one of these 'if statements', the there is no error. But I do not understand why this error is occurring. Could anyone explain to me why Z3 is not being able to solve this? Thank you.

You didn't tell us what exact error you're getting, so I'm assuming it comes from z3 and not from some other part of your toolchain. Let's run the SMTLib program you posted through z3. When I do that, z3
tells me that there's a "sort mismatch:"
(error "line 13 column 38: operator is applied to arguments of the wrong sort")
And this is because you've the line:
(assert (! (not (not (= (+ (+ (bvneg 2) 0) 2) 3))) :named __a3))
and in particular the expression (bvneg 2). The function bvneg is bit-vector negation, but 2 is an Integer, not a bit-vector value. You want to use regular negation instead. So, change that line to:
(assert (! (not (not (= (+ (+ (- 0 2) 0) 2) 3))) :named __a3))
With that change, z3 says:
unsat
(__a3)
(error "line 16 column 10: model is not available")
Great; so now you have unsat, and the unsat-core is __a3. The error in the last line can be ignored, it arises because you called get-model but the problem is unsatisfiable, and thus there is no model to display.
Now, you might wonder why this is unsat, perhaps you expected it to be satisfiable? You haven't told us how you converted your C function to SMTLib, and it appears that you used some unnamed tool to do so, perhaps one of your own creation. The tool clearly has a bug in it, as it created the bvneg expression that we fixed above, maybe it's not to be trusted as much! But let's see why z3 thinks this problem is unsat.
It boils down to these two lines that your tool generated:
(assert (! (not (= sv_1 0)) :named __a0))
(assert (! (not (not (= sv_1 0))) :named __a2))
Let's simplify these by dropping the annotations, and for clarity I'll rename sv_1 to a, since that seems to be the origin of the variable. This gives us:
(assert (not (= a 0)))
(assert (not (not (= a 0))))
Let's simplify a bit:
(assert (distinct a 0))
(assert (not (distinct a 0)))
(In SMTLib, (distinct x y) means (not (= x y)).)
And now we see the problem; you have two assertions the first one says a is not 0, and the second says it's not the case that a is not 0. Clearly, these two assertions conflict each other, and this is why z3 tells you unsat.
There's actually another source of conflict as well. The other assertion simplifies to:
(assert (not (not (= (+ (+ (- 0 2) 0) 2) 3)
which, if you do the arithmetic, says:
(assert (= 0 3))
which is clearly not true. (And this is why z3 tells you your unsat core is __a3; which is the root-cause of why the whole set of assumptions is unsatisfiable. Note that unsat-cores are not unique, and z3 does not guarantee it'll give you a minimal set. So it could've told you (__a0 __a2) as well as the unsat-core; but that's a separate discussion.)
So, z3 is doing the right thing given your generated SMTLib (after the correction mentioned above.)
Why your tool generates this SMTLib for the C-program is something we cannot help you with unless you tell us more about how you generated that output, or what this intermediate tool actually does. My rough guess is that it's actually generating a bunch of test cases, and eventually it comes to a point where it says "I don't have any more test cases to generate" so everything is actually fine; but there seems to be some issue with why it would generate the (get-model) call; or why it would do the bvneg call which is incorrect. But otherwise, you'll have to consult with the developers of the tool that generates this SMTLib for you for further debugging.

Related

Scheme: using open-i/o-file function

I'm using MIT Scheme 10.1.5 and am curious why the following code using open-i/o-file is not working I expected. Does anyone know what the issue is?
(define l "~/tmp0")
(define x ''(a b (c d) e f))
(let ((p (open-i/o-file l)))
(begin (write x p)
(flush-output p)
(let ((r (read p)))
(close-port p)
r)))
;Value: #!eof
when I was expecting:
;Value: (quote (a b (c d) e f))
When using open-input-file or open-output-file the results are expected:
(let ((p (open-output-file l)))
(write x p)
(close-port p))
(let ((p (open-input-file l)))
(let ((r (read p)))
(close-port p)
r))
;Value: (quote (a b (c d) e f))
When you read from or write to a port, the port position is advanced. After writing to an i/o port, you need to reset the position of the port if you want to read what was written.
This does not seem to be very well documented in the MIT/GNU Scheme Reference Manual, but you can use textual-port-operation to perform manipulations on textual ports. Now, this is a bit more convoluted than you might like for a couple of reasons.
First, textual-port-operation takes a port and a symbol as its arguments and returns a procedure that accomplishes the operation, i.e., textual-port-operation does not do the operations itself.
Second, the symbol argument to textual-port-operation indicates the operation, but a complete list of these symbols is not present in the reference manual (as far as I can tell). You will need to call textual-port-operation-names on the port to find out which operations the port supports.
Here is a rewritten version of OP code that behaves as expected:
(define l "./test-file.dat")
(define x ''(a b (c d) e f))
;; (define (display-port-ops p)
;; (newline)
;; (display (textual-port-operation-names p)) (newline)
;; (newline))
(let* ((p (open-i/o-file l))
(start ((textual-port-operation p 'position) p)))
;; (display-port-ops p)
(write x p)
(flush-output p)
((textual-port-operation p 'set-position!) p start)
(let ((r (read p)))
(close-port p) r))
Here, the display-port-ops procedure was used to interrogate the port and discover which operations are supported and what symbols represent those operations. This had to be called with a port argument, so it was placed in the let* form. I called this, uncommented, before adding either of the calls to textual-port-operation so that I could see which operations were available. The position and set-position! operations looked promising, so they were incorporated into the program. Note that let* had to replace let so that the value of p could be used in an expression calculating the start position.
The call to display-port-ops, which just wraps a call to textual-port-operation-names, showed this result:
(length pathname position set-position! truename write-self close-input eof?
input-line input-open? input-channel buffered-output-bytes bytes-written
close-output output-column output-open? output-channel synchronize-output
char-set close coding known-coding? known-codings known-line-ending?
known-line-endings line-ending open? set-coding set-line-ending
supports-coding? char-ready? peek-char read-char read-substring unread-char
flush-output write-char write-substring)
Armed with these procedures, here is what happens:
Immediately after creating the port p, (textual-port-operation p 'position) is called, yielding a procedure that will return a port position; this procedure is called on the port p, and start is bound to the result, saving the initial position of the port.
After writing to the port, (textual-port-operation p 'set-position!) is called, yielding a procedure that will mutate the state of a port, setting a new position; this procedure is called on the port p and the desired position start.
Now, when read is called on p, reading commences from the port's initial position.
When the program is loaded, the test-file.dat is created as expected, and the result of reading the file back is displayed in the REPL:
1 (user) => (load "file-io.scm")
;Loading "file-io.scm"... done
;Value: (quote (a b (c d) e f))

Strange behavior of log4cl and iterate

I am starting to use log4cl and am facing a weird issue when using it inside an iterate loop. While working does show the name of the method it is empty for not-working.
Do I miss something obvious here? Or is there a bug in the combination of iterate and log4cl?
(ql:quickload "iterate")
(ql:quickload "log4cl")
(defpackage :minimal
(:use #:cl #:iterate))
(in-package :minimal)
(defclass test ()
((a :documentation "test-a"
:initform (make-array '(3 3)
:element-type 'integer
:initial-element 0)
:initarg :a)))
(defvar *a* (make-instance 'test))
(defmethod not-working ((test test))
(with-slots (a) test
(iter
(for i below 3)
(iter
(for j below 3)
(unless (= 10 (aref a i j))
(log:info "R: ~D C: ~D" i j))))))
(defmethod working ((test test))
(with-slots (a) test
(loop
for i below 3
do (loop
for j below 3
unless (= 10 (aref a i j))
do (log:info "I: ~D J: ~D" i j)))))
(not-working *a*)
(working *a*)
EDIT
I see the issue only on sbcl. Using cclthe method name is displayed correctly. Furthermore, omitting the (are...) statement inside unless leads to a working version:
(defmethod also-working ((test test))
(with-slots (a) test
(iter
(for i below 3)
(iter
(for j below 3)
(unless (= 10 j)
(log:info "R: ~D C: ~D" i j))))))

Multiplying numbers and outputting result in a file in SCHEME

I am new to the concept of SCHEME and just started learning Scheme (and DrRacket). Started with some online resources including, DrRacket Docs. Following this and some other references online, I am trying to solve a basic problem which involves reading 2 numbers from a file (data.inp), multiplying the numbers and displaying the output in a different file (result.out).
So far, I have been able to come up with following code,
#lang racket
(define (file->char_list path)
(call-with-input-file path
(lambda (input-port)
(let loop ((x (read-char input-port)))
(cond
((eof-object? x) '())
(#t (begin (cons x (loop (read-char input-port))))))))))
(define (yb)
;(call-with-input-file "data.inp"
;(lambda (in) (read-string 14 in)
; ))
;(call-with-output-file "result.out"
;(lambda (output-port)
; (display "(* x x)" output-port)))
; Fill in the blank
;(fprintf (current-output-port) "Done!~n"))
(string->number (apply string (file->char_list "data.inp"))))
(yb)
I am stuck at reading numbers from a file (data.inp) and multiplying them. I have references some previous stackoverflow questions but I am sort of stuck at this point. Any help will be appreciated :)
In Scheme, most of the time you'll probably want to use the default "current" ports for input and output. On most Unix systems, the default current input port is linked to stdin and the default current output port is linked to stdout.
With that in mind, reading in two numbers and writing out their product is basically:
(display (* (read) (read)))
Now, if you want to use actual input and output files, like you mentioned in your question, then you can either wrap with with-input-from-file/with-output-to-file (which temporarily changes the current input and output port):
(with-input-from-file "data.inp"
(lambda ()
(with-output-to-file "result.out"
(lambda ()
(display (* (read) (read)))))))
or you can explicitly specify ports, and leave the current/default input and output ports unchanged:
(call-with-input-file "data.inp"
(lambda (in)
(call-with-output-file "result.out"
(lambda (out)
(display (* (read in) (read in)) out)))))

Writing a While Loop in Scheme

I am trying to implement a while loop using recursion with lambda, but I just don't understand how to do it.
I am supposed to start with this lambda expression:
((lambda (x) (x x)) (lambda (x) (x x))
My first question is why does this cause 'eternal' recursion? I try to understand how it works, but I just can't grasp it.
I also have this code to go after:
((lambda (x) (x x))
(lambda (x)
(if (not (= i 0))
(begin
(display i)
(set! i (- i 1))
(x x))
)))
This code causes a loop that prints from i = n to i = 0, but I don't understand this either. If someone would care to explain the use of lambda here I would be grateful :)
Edit: I have to use this lambda expression as my 'starting point', and I don't want to use macros (it's a voluntary excercise which I try to understand, so I want to follow the guidelines :))
To see what happens when ((lambda (x) (x x)) (lambda (x) (x x)) is evaluated use the stepper in DrRacket. It can show you the steps an evaluation takes.
Write your expression in the definition window of DrRacket.
Then choose the teaching language "Intermediate Student with lambda". Then click the stepper button (the green triangle followed by a bar).
You will see something that looks like the image (which uses a different program):
Update:
Try this program:
(define i 5)
((lambda (x) (x x))
(lambda (x)
(if (not (= i 0))
(x x)
'ignore)))
Update:
(define i 5)
(define f
(lambda (x)
(if (not (= i 0))
(begin
(display i)
(set! i (- i 1))
(x x))
'done)))
(f f)
Or without any defines at all:
((lambda (f) (f f))
(lambda (x)
(if (not (= i 0))
(begin
(display i)
(set! i (- i 1))
(x x))
'done)))
And here without an external variable:
((lambda (f i) (f f i))
(lambda (x i)
(if (not (= i 0))
(begin
(display i)
(x x (- i 1)))
'done))
5)
Using a while function:
(define (while body . args)
(apply body body args))
(while (lambda (loop i)
(if (not (= i 0))
(begin
(display i)
(loop loop (- i 1)))
'done))
5)

for/continue in scheme/lisp

I'm writing a small interpreter for a C-like language in Scheme (R5RS) and trying to convert something like:
for (i = 0; i < 100; i++)
{
if (isprime(i)) continue;
else /* do something with i */
}
to valid Scheme (the isprime function is just an example and not important).
However, after trying for some time, I have not been able to find an efficient/simple way to add the equivalent of a continue statement to a do loop in Scheme. What would be even better would be a "for" macro which allows "continue" and "break" to be used.
I'm considering switching to Common Lisp. Would this sort of thing be any easier in CL?
We can write FOR as a macro. The Common Lisp version:
(defmacro for ((var start end) &body body)
(let ((block-name (gensym "BLOCK")))
`(loop for ,var from ,start below ,end
do (block ,block-name
(flet ((continue ()
(return-from ,block-name)))
,#body)))))
CL-USER 2 > (for (i 10 20)
(if (evenp i) (continue))
(print i))
11
13
15
17
19
CL's tagbody is a convenient target:
(let (i)
(tagbody
(setf i 0)
body
(if (isprime i)
(go increment))
(do-something-with i)
increment
(setf i (1+ i))
(if (< i 100)
(go body))))
I'd go for continuations like in this pseudo-scheme example.
Just store the current point of execution in a continuation and call it when appropriate.
(call/cc (lambda break ; jump outside the for
(for 0 100 (lambda i
(call/cc (lambda continue ; jump to the next iteration
(if (isprime i)
(continue)
(break))))))))
I know this is 8 years late, but I thought it might help someone.
Using the iterate construct in Common Lisp, you could use the next-iteration clause:
(iter (for i from 0 to 100)
(if (isprime i)
(next-iteration)
(do-something-else)))
The straightforward Scheme way to achieve this is just to restructure your code:
for (i = 0; i < 100; i++)
{
if (isprime(i)) continue;
if (is_bad(i)) break;
else /* do something with i */
}
is
(let loop ((i 0))
(cond
((isprime i) ;; continue the loop
(loop (+ i 1)))
((is_bad i)
#f) ;; break from the loop
(else ;; do something with i
....... ;; and then continue the loop
(loop (+ i 1)))))
If your loop body is tangled and you want to (continue) or (break) from deep inside its nested structure, either have your compiler restructure it in the above way, or you could set up exit points with call/cc as e.g.
(call/cc (lambda (break)
(let loop ((i 0))
(call/cc (lambda (continue)
;; your loop logic here,
;; potentially using
;; (continue A) ;; A is ignored
;; or
;; (break B) ;; B is immediately returned as
;; ;; the overall loop's result
))
;; (continue _) continues here:
(loop (+ i 1)))))
Racket has delimited continuations which should be more efficient.
To implement this particular code sample in Scheme, you don't need continue, break or call/cc:
(let loop ((i 0))
(when (< i 100)
(if (prime? i)
(loop (add1 i)))
(do-something-else)))
I think Vijay's answer can be extended in a way that works (sorry for answering my own question, but can't figure out how to format code in a comment):
(let loop ((i 0))
(define (next)
(loop (+ i 1)))
(call/cc
(lambda (break)
(if (< i 100)
(begin
(if (isprime i)
(next)
(begin
(if (isbad i)
(break break))
(do-something)
(next))))))))
It's not a macro, but doubtlessly leads to one that's general enough. I'd be interested to see any improvements. I'm pretty new to Scheme.
You can use throw and catch as well (elisp):
(let ((j 0))
(while (< j 10)
(catch 'continue
(setq j (1+ j))
(if (= j 3) (throw 'continue t))
(prin1 j))))
1245678910nil

Resources