Bug with recursive functions? - recursion

I'm trying recursive functions in z3, and I'm curious if there's a bug with model construction. Consider:
(define-fun-rec f ((x Int)) Int
(ite (> x 1)
(f (- x 1))
1))
(check-sat)
(get-value ((f 0)))
Here f is actually the constant function 1, just defined in a silly way. For this input, z3 prints:
sat
(((f 0) 0))
This seems incorrect, since f 0 should equal 1.
What's interesting is if I assert what z3 proposes as the result, then I get the correct unsat answer:
(define-fun-rec f ((x Int)) Int
(ite (> x 1)
(f (- x 1))
1))
(assert (= (f 0) 0))
(check-sat)
I get:
unsat
So, it looks like z3 actually does now that f 0 cannot be 0; even though it produced that very model in the previous case.
Taking this one step further, if I issue:
(define-fun-rec f ((x Int)) Int
(ite (> x 1)
(f (- x 1))
1))
(assert (= (f 0) 1))
(check-sat)
(get-model)
Then z3 responds:
sat
(model
(define-fun f ((x!0 Int)) Int
1)
)
which is indeed a reasonable answer.
So, it seems perhaps there's a bug with recursive function models under certain conditions?

The models used not to reflect the graph of recursive function definitions.
So when evaluating recursive functions on values that had not been seen during solving it could produce arbitrary results. This behavior is now changed as the recursive definitions are included in models.

Related

How to convert a sum and product constraint into SMT-lib2 (for Z3)

I'm wondering what the best way to convert a sum a le
or similarly a product
into an SMT-lib2 expression, specifically for solving with Z3 (or even metitarski).
I thought there would be an obvious approach with a quantifier, but I'm having trouble creating it, and in many use cases such a sum is likely to have constants for exprLB and exprUB, which would mean that I would hope some kind of tactic would simply unroll it into a long sequence of addition, where use of a quantifier might make that much more difficult.
For example, a fairly trivial tactic to convert
into
which is both trivially expressed as (and trivially solved by most SMT solvers) as
(+
(/ 2 x1)
(/ 2 x2)
(/ 2 x3)
)
yielding
sat (model (define-fun x1 () Real 1.0) (define-fun x2 () Real 1.0) (define-fun x3 () Real (/ 1.0 4.0)) )
How can I generally express a sum over three expressions (lower-bound, upper-bound, and accumulator) elegantly in smt-lib2?
The obvious choice would be to use arrays for your x values, and recursive-functions to model the sum/product.
Z3 does support recursive functions, but it's not fool-proof. At best you'll get unknown, since most such formulae would require inductive proofs; something SMT-solvers are not good at. At worst, you get an unhelpful answer, or maybe even a bogus one if you hit a bug.
Here's an example that works out ok:
(declare-fun xs () (Array Int Real))
(define-fun-rec sum ((lb Int) (ub Int)) Real
(ite (> lb ub)
0
(+ (select xs lb)
(sum (+ lb 1) ub))))
(declare-fun lb () Int)
(declare-fun ub () Int)
(assert (= (sum lb ub) 12.34))
(check-sat)
(get-value (lb ub xs))
Z3 responds:
sat
((lb 0)
(ub 0)
(xs ((as const (Array Int Real)) (/ 617.0 50.0))))
This is pretty cool actually, though maybe not as impressive as you expected. You can force it to a certain range as well:
(declare-fun xs () (Array Int Real))
(define-fun-rec sum ((lb Int) (ub Int)) Real
(ite (> lb ub)
0
(+ (select xs lb)
(sum (+ lb 1) ub))))
(declare-fun lb () Int)
(declare-fun ub () Int)
(assert (= 1 lb))
(assert (= 3 ub))
(assert (= (sum lb ub) 12.34))
(check-sat)
(get-value (lb ub))
(eval (select xs 1))
(eval (select xs 2))
(eval (select xs 3))
This produces:
sat
((lb 1)
(ub 3))
0.0
(- (/ 121233.0 50.0))
2437.0
Which is a correct model. Unfortunately, slight changes to the formula/assertions cause it to produce unhelpful answers. If I try:
(declare-fun xs () (Array Int Real))
(define-fun-rec sum ((lb Int) (ub Int)) Real
(ite (> lb ub)
0
(+ (/ 2.0 (select xs lb))
(sum (+ lb 1) ub))))
(assert (= (sum 1 3) 12.34))
(check-sat)
Then I get:
unknown
As solvers mature in their support for recursive functions, you can surely expect them to answer more queries successfully. For the short term, you're more likely to see unknown responses quite often.
Personally, I think using an SMT solver when you don't know how many terms you have in your sum/product is just not the best idea. If you know the number of terms, by all means use an SMT solver. If not, you're better off using interactive theorem proving, i.e., systems that allow you to express recursive functions and inductive proofs; such as Isabelle, Coq, and others.

Understanding Let/cc and throw in racket

In class we talked about two functions in racket i-e letcc and throw. The instructor said that let/cc has something to do with calling with the current continuation and throw just applies a to b e.g.
(throw a b)
I haven't been able to find much about these online. I did find a question asked for letcc on stackoverflow but I have not been able to understand the functioning of letcc from it completely. Could someone explain these two in simple words along with a simple example?
Edit1: Also in my practice mid exam we are given two question related to it.
For each of the following expressions that contain uses of let/cc, what is the value of each expression?
(let/cc k (throw (throw k 5) 6))
(let/cc k (throw k ((( lambda (x) x) k) (∗ 5 5))))
The answers to these are 5 and 25 respectively. I just wanna understand the two concepts so that I can work with questions like these in my midterm exam.
Let's look at let/cc first.
The expression (let/cc k e) will 1) capture the current continuation (represented as a function) then 2) bind the variable k to the captured continuation and finally 3) evaluate the expression e.
A few examples are in order.
If during evaluation of the expression e, the captured contination k is not called, then the value of the let/cc expression is simply the value(s) to which the expression e evaluated to.
> (+ 10 (let/cc k 32))
42
If on the other hand k is called with a value v then the value of the entire let\cc expression becomes v.
> (+ 10 (let/cc k (+ 1 (k 2))))
12
Notice that the part (+ _) around the call (k 2) is skipped.
The value is return to the continuation of (let/cc ...) immediately.
The most common use of let/cc is to mimic the control struct return known from many statement based languages. Here is the classical is-it-a-leap-year problem:
(define (divisible-by? y k)
(zero? (remainder y k)))
(define (leap-year? y)
(let/cc return
(when (not (divisible-by? y 4))
(return #f))
(when (not (divisible-by? y 100))
(return #t))
(when (not (divisible-by? y 400))
(return #f))
#t))
(for/list ([y (in-range 1898 1906)])
(list y (leap-year? y)))
Now what about throw ? That depends on which throw we are talking about.
Is it the one from misc1/throw ?
Or perhaps the one from Might's article? http://matt.might.net/articles/programming-with-continuations--exceptions-backtracking-search-threads-generators-coroutines/
Or perhaps you are using the definition
(define (throw k v)
(k v))
If the latter, then you can replace (k v) in my examples with (throw k v).
UPDATE
Note that the continuation bound to k can be used more than once - it can also be used outside the let/cc expression. Consider this example:
(define n 0)
(let ([K (let/cc k k)])
(when (< n 10)
(displayln n)
(set! n (+ n 1))
(K K)))
Can you figure out what it does without running it?
Here is a "step by step" evaluation of the nested let/cc example.
(let/cc k0
((let/cc k1
(k0 (sub1 (let/cc k2
(k1 k2)))))
1))
(let/cc k0
(k2 1))
(let/cc k0
((let/cc k1
(k0 (sub1 1)))
1))
(let/cc k0
((let/cc k1
(k0 0))
1))
0

Lambda Recursion in Dr Racket

Im trying to created the function "apply N times" in Dr Racket but Don't know where I'm going wrong. My code seems to be correct but clearly I'm missing something. Printed below is the code and the error I'm getting.
(define (applyNtimes F n)
(lambda (x)
(if (= n 0) x
(F (applyNtimes F (- n 1))))))
(define cdr3 (applyNtimes cdr 3))
(cdr3 '(1 2 3 4 4 5))
and This is the error I'm getting:
cdr: contract violation
expected: pair?
given: #
the expected output should be
(4 4 5)
Here's the problem, you are trying to apply F to the return of applyNtimes but think for a second, what does that return? a lambda.
This means in your case, we're trying to apply cdr to a lambda, whoops.
In order to get the value of this lambda to actually use it, we have to invoke it. Doing this is pretty easy, just changing
(F (applyNtimes F (- n 1))))))
to
(F ( (applyNtimes F (- n 1)) ;;Get the Lambda
x))))) ;; and apply it to x
To understand this let's break it apart, first we apply F to something. Since in our case F is really cdr we'd better give it some form of pair.
In this code the 'Something' is the result of applying (applyNTimes F (- n 1)) to x.
Well this leads us to some recursion, where what we're really doing is
(F (F (F ... ((applyNTimes F (- n whatever)) x))))
Ok so how does this recursion end? Well when (- n whatever) is 0, we return the lambda
(lambda (x) x)
Which really turns this whole thing into
(F (F (F (F (F (F x))))))
Which is our desired applyNtimes function.

Bad Syntax with let in LISP

I keep getting this error when trying to run the code:
(let ((exp lambda (x y) (if (= y 1) x (* (exp x (- y 1)) x)))))
Error:
let: bad syntax in: (let ((exp lambda (x y) (if (= y 1) x (* (exp x (- y 1)) x)))))
My function is supposed to define recursive exponentiation, but I'm having problems with let.
You're missing an opening parenthesis before the lambda, and the let form is missing a body. Also, you can't use let for defining recursive functions; you need to use letrec (for Scheme) or labels (for Common Lisp). Perhaps you meant this (Scheme):
(letrec ((exp (lambda (x y)
(if (= y 1) x
(* (exp x (- y 1)) x)))))
exp)

How to improve this piece of code?

My solution to exercise 1.11 of SICP is:
(define (f n)
(if (< n 3)
n
(+ (f (- n 1)) (* 2 (f (- n 2))) (* 3 (f (- n 3))))
))
As expected, a evaluation such as (f 100) takes a long time. I was wondering if there was a way to improve this code (without foregoing the recursion), and/or take advantage of multi-core box. I am using 'mit-scheme'.
The exercise tells you to write two functions, one that computes f "by means of a recursive process", and another that computes f "by means of an iterative process". You did the recursive one. Since this function is very similar to the fib function given in the examples of the section you linked to, you should be able to figure this out by looking at the recursive and iterative examples of the fib function:
; Recursive
(define (fib n)
(cond ((= n 0) 0)
((= n 1) 1)
(else (+ (fib (- n 1))
(fib (- n 2))))))
; Iterative
(define (fib n)
(fib-iter 1 0 n))
(define (fib-iter a b count)
(if (= count 0)
b
(fib-iter (+ a b) a (- count 1))))
In this case you would define an f-iter function which would take a, b, and c arguments as well as a count argument.
Here is the f-iter function. Notice the similarity to fib-iter:
(define (f-iter a b c count)
(if (= count 0)
c
(f-iter (+ a (* 2 b) (* 3 c)) a b (- count 1))))
And through a little trial and error, I found that a, b, and c should be initialized to 2, 1, and 0 respectively, which also follows the pattern of the fib function initializing a and b to 1 and 0. So f looks like this:
(define (f n)
(f-iter 2 1 0 n))
Note: f-iter is still a recursive function but because of the way Scheme works, it runs as an iterative process and runs in O(n) time and O(1) space, unlike your code which is not only a recursive function but a recursive process. I believe this is what the author of Exercise 1.1 was looking for.
I'm not sure how best to code it in Scheme, but a common technique to improve speed on something like this would be to use memoization. In a nutshell, the idea is to cache the result of f(p) (possibly for every p seen, or possibly the last n values) so that next time you call f(p), the saved result is returned, rather than being recalculated. In general, the cache would be a map from a tuple (representing the input arguments) to the return type.
Well, if you ask me, think like a mathematician. I can't read scheme, but if you're coding a Fibonacci function, instead of defining it recursively, solve the recurrence and define it with a closed form. For the Fibonacci sequence, the closed form can be found here for example. That'll be MUCH faster.
edit: oops, didn't see that you said forgoing getting rid of the recursion. In that case, your options are much more limited.
See this article for a good tutorial on developing a fast Fibonacci function with functional programming. It uses Common LISP, which is slightly different from Scheme in some aspects, but you should be able to get by with it. Your implementation is equivalent to the bogo-fig function near the top of the file.
To put it another way:
To get tail recursion, the recursive call has to be the very last thing the procedure does.
Your recursive calls are embedded within the * and + expressions, so they are not tail calls (since the * and + are evaluated after the recursive call.)
Jeremy Ruten's version of f-iter is tail-recursive rather than iterative (i.e. it looks like a recursive procedure but is as efficient as the iterative equivalent.)
However you can make the iteration explicit:
(define (f n)
(let iter
((a 2) (b 1) (c 0) (count n))
(if (<= count 0)
c
(iter (+ a (* 2 b) (* 3 c)) a b (- count 1)))))
or
(define (f n)
(do
((a 2 (+ a (* 2 b) (* 3 c)))
(b 1 a)
(c 0 b)
(count n (- count 1)))
((<= count 0) c)))
That particular exercise can be solved by using tail recursion - instead of waiting for each recursive call to return (as is the case in the straightforward solution you present), you can accumulate the answer in a parameter, in such a way that the recursion behaves exactly the same as an iteration in terms of the space it consumes. For instance:
(define (f n)
(define (iter a b c count)
(if (zero? count)
c
(iter (+ a (* 2 b) (* 3 c))
a
b
(- count 1))))
(if (< n 3)
n
(iter 2 1 0 n)))

Resources