Shallow vs. Deep binding in scheme - binding

Assuming dynamic scoping, what would be the difference in the display statement if it was shallow or deep binding?
I understand that shallow binding is when it is bound at the call and deep is when it is bound while passed as a parameter but I'm not sure how this works in the context of scheme. I think that the deep binding should print 2 but I'm not sure
(define A
(let* ((x 2)
(C (lambda (P)
(let ((x 4))
(P))))
(D (display x))
(B (let ((x 3))
(C D))))
(B)))

Let's get some definitions into play:
Deep binding binds the environment at the time a procedure is passed as an
argument.
Shallow binding binds the environment at the time a procedure is actually called
So the only difference will be regarding the evaluation of C which happens inside B.
(define A
(let* ((x 2)
(C (lambda (P)
(let ((x 4))
(P))))
(D (display x))
(B (let ((x 3))
(C D))))
(B)))
On the other hand, the code itself seems to be buggy, (display x) will not return a value yet it is passed into C.
Let's assume you meant (D (lambda () (display x)))
(define A
(let* ((x 2)
(C (lambda (P)
(let ((x 4))
(P))))
(D (lambda () (display x)))
(B (let ((x 3))
(C D))))
(B)))
under deep binding the value of x is 3 when D is passed into C, so we should expect 3 to be printed.
under shallow binding the value of x is 4 when the procedure is actually called, so 4 will be printed.

Related

Racket: How can I fix my code so that it will return all the flipped pairs that is missing?

This function should return the symmetric closure of L.
Examples:
(Symmetric-Closure'((a a) (a b) (b a) (b c) (c b))) ---> '((a a) (a b) (b a) (b c) (c b))
(Symmetric-Closure'((a a) (a b) (a c))) ---> '((a a) (a b) (a c) (b a)(c a))
(Symmetric-Closure'((a a) (b b))) ---> '((a a) (b b))
(Symmetric-Closure'())---> '()
Here is what I have in Racket
(define (Symmetric-Closure L)
;Iterate over each pair in L
(andmap (lambda (x)
;If the flipped pair does not exist in L, it will
;return L and the flipped pair that is missing. Otherwise, return L.
(if(not(member (list (cadr x)(car x)) L))
(cons (list (cadr x)(car x)) L)
(append L)))
L))
How can I fix my code so that it will return all the flipped pairs that is missing
For example, my code only return L and the last missing flipped pair (c a) instead of (b a) and (c a)
;this is wrong, it should return '((c a)(b a)(a a)(a b)(a c))
(Symmetric-Closure '((a a)(a b)(a c))-----> '((c a)(a a)(a b)(a c))
;this is correct
(Symmetric-Closure '((a a)(a b)(b a)(b c)(c b)))-----> '((a a)(a b)(b a)(b c)(c b))
andmap means "map the list using this function and then and together the results." In Racket, whenever you and together any values, the result is going to be either the last value provided to it, or false. For example, (and value1 value2) results in value2 if neither value1 nor value2 is false (and if one of them is false, the result is false as well). Since the value produced by your lambda is never false, the result of your andmap is going to be the value of the lambda expression the final time it is called, which in this case, could be the list (cons (list (cadr x)(car x)) L) for the last value of x that it sees in the original list L. This means that all preceding values that were consed don't factor into the result at all.
You could modify this to use a simple map instead. But this produces a list of lists of pairs, not a list of pairs which is what you want. So at the end you need to flatten this to arrive at the result.
(define (symmetric-closure L)
;Iterate over each pair in L
(apply append
(map (lambda (x)
;If the flipped pair does not exist in L, it will
;return L and the flipped pair that is missing. Otherwise, return L.
(if (not (member (list (cadr x) (car x)) L))
(list (list (cadr x) (car x)) x)
(list x)))
L)))
One thing to be aware of, though, is that this algorithm calls member for every element in the original list. Checking for membership in a list is O(N) and you are doing this N times, meaning that the complexity of this algorithm is O(N²). You should be able to do this more efficiently, for instance by using a hash set.

Why is this simple Z3 proof so slow?

The following Z3 code times out on the online repl:
; I want a function
(declare-fun f (Int) Int)
; I want it to be linear
(assert (forall ((a Int) (b Int)) (
= (+ (f a) (f b)) (f (+ a b))
)))
; I want f(2) == 4
(assert (= (f 2) 4))
; TIMEOUT :(
(check-sat)
So does this version, where it is looking for a function on the reals:
(declare-fun f (Real) Real)
(assert (forall ((a Real) (b Real)) (
= (+ (f a) (f b)) (f (+ a b))
)))
(assert (= (f 2) 4))
(check-sat)
It's faster when I give it a contradiction:
(declare-fun f (Real) Real)
(assert (forall ((a Real) (b Real)) (
= (+ (f a) (f b)) (f (+ a b))
)))
(assert (= (f 2) 4))
(assert (= (f 4) 7))
(check-sat)
I'm quite unknowledgeable about theorem provers. What is so slow here? Is the prover just having lots of trouble proving that linear functions with f(2) = 4 exist?
The slowness is most likely due to too many quantifier instantiations, caused by problematic patterns/triggers. If you don't know about these yet, have a look at the corresponding section of the Z3 guide.
Bottom line: patterns are a syntactic heuristic, indicating to the SMT solver when to instantiate the quantifier. Patterns must cover all quantified variables and interpreted functions such as addition (+) are not allowed in patterns. A matching loop is a situation in which every quantifier instantiation gives rise to further quantifier instantiations.
In your case, Z3 probably picks the pattern set :pattern ((f a) (f b)) (since you don't explicitly provide patterns). This suggests Z3 to instantiate the quantifier for every a, b for which the ground terms (f a) and (f b) have already occurred in the current proof search. Initially, the proof search contains (f 2); hence, the quantifier can be instantiated with a, b bound to 2, 2. This yields (f (+ 2 2)), which can be used to instantiate the quantifier once more (and also in combination with (f 2)). Z3 is thus stuck in a matching loop.
Here is a snippet arguing my point:
(set-option :smt.qi.profile true)
(declare-fun f (Int) Int)
(declare-fun T (Int Int) Bool) ; A dummy trigger function
(assert (forall ((a Int) (b Int)) (!
(= (+ (f a) (f b)) (f (+ a b)))
:pattern ((f a) (f b))
; :pattern ((T a b))
)))
(assert (= (f 2) 4))
(set-option :timeout 5000) ; 5s is enough
(check-sat)
(get-info :reason-unknown)
(get-info :all-statistics)
With the explicitly provided pattern you'll get your original behaviour (modulo the specified timeout). Moreover, the statistics report lots of instantiations of the quantifier (and more still if you increase the timeout).
If you comment the first pattern and uncomment the second, i.e. if you "guard" the quantifier with a dummy trigger that won't show up in the proof search, then Z3 terminates immediately. Z3 will still report unknown, though, because it "knowns" that it did not account for the quantified constraint (which would be a requirement for sat; and it also cannot show unsat).
It is sometimes possible to rewrite quantifiers in order to have better triggering behaviour. The Z3 guide, for example, illustrates that in the context of injective functions/inverse functions. Maybe you'll be able to perform a similar transformation here.

Mandelbrot set in Scheme

I was wondering if anyone had any advice on writing the mandelbrot stream. I have wrote the following functions for myself to help:
(define (make-complex a b) (cons a b))
(define (real-coeff c) (car c))
(define (imag-coeff c) (cdr c))
(define (c-add c d)
(make-complex (+ (real-coeff c) (real-coeff d))
(+ (imag-coeff c) (imag-coeff d))))
(define (c-mult c d)
(make-complex (- (* (real-coeff c) (real-coeff d))
(* (imag-coeff c) (imag-coeff d)))
(+ (* (real-coeff c) (imag-coeff d))
(* (imag-coeff c) (real-coeff d)))))
(define (c-length c)
(define (square x) (* x x))
(sqrt (+ (square (real-coeff c))
(square (imag-coeff c)))))
I have that fz(x) = x2 +z. The stream should return: a, fz(a), fz(fz(a)), fz(fz(fz(a))). I am confused on how to use the functions that I wrote to create a stream that has this output. Anyone have some good advice as to where to go with this?
Start with a value for z and make your function fz(x) like:
(define (make-fz z) (lambda (x) (+ z (* 2 x))))
Now, using srfi-41 stream library, define a stream just as you've indicated:
Try it out (with z of 0):
> (stream->list (stream-take 10 (stream-iterate (make-fz 0) 1)))
(1 2 4 8 16 32 64 128 256 512)
Note: that stream-iterate is defined something like:
(define-stream (stream-iterate fz a)
(stream-cons a (stream-iterate fz (fz a))))
As uselpa said, Scheme has built-in complex numbers. The functions you mentioned are provided as follows:
make-rectangular
real-part
imag-part
+
*
magnitude
As for the second part of your question, what is z? It's hard to answer this without knowing what you're wanting.

cross product in z3

Does z3 provide a cross product function for two lists? If not is it possible to define one without using higher order functions or using the provided list functions? I have been having trouble trying to define one. I know how to define one using map but I don't think that is supported in z3.
You can declare the cross product function in SMT 2.0.
However, any non-trivial property will require a proof by induction. Z3 currently does not support proofs by induction. Thus, it will only be able to prove very simple facts.
BTW, by cross-product of lists, I'm assuming you want a function that given the lists [a, b] and [c, d] returns the list or pairs [(a, c), (a, d), (b, c), (b, d)].
Here is a script that defines the product function.
The script also demonstrates some limitations of the SMT 2.0 language. For example, SMT 2.0 does not support the definition of parametric axioms or functions. So, I used uninterpreted sorts to "simulate" that. I also had to define the auxiliary functions append and product-aux. You can try this example online at: http://rise4fun.com/Z3/QahiP
The example also proves the following trivial fact that if l = product([a], [b]), then first(head(l)) must be a.
If you are insterested in proving non-trivial properties. I see two options. We can try to prove the base case and inductive cases using Z3. The main disadvantage in this approach is that we have to manually create these cases, and mistakes can be made. Another option is to use an interactive theorem prover such as Isabelle. BTW, Isabelle has a much richer input language, and provides tactics for invoking Z3.
For more information about algebraic datatypes in Z3, go to the online tutorial http://rise4fun.com/Z3/tutorial/guide (Section Datatypes).
;; List is a builtin datatype in Z3
;; It has the constructors insert and nil
;; Declaring Pair type using algebraic datatypes
(declare-datatypes (T1 T2) ((Pair (mk-pair (first T1) (second T2)))))
;; SMT 2.0 does not support parametric function definitions.
;; So, I'm using two uninterpreted sorts.
(declare-sort T1)
(declare-sort T2)
;; Remark: We can "instantiate" these sorts to interpreted sorts (Int, Real) by replacing the declarations above
;; with the definitions
;; (define-sort T1 () Int)
;; (define-sort T2 () Real)
(declare-fun append ((List (Pair T1 T2)) (List (Pair T1 T2))) (List (Pair T1 T2)))
;; Remark: I'm using (as nil (Pair T1 T2)) because nil is overloaded. So, I must tell which one I want.
(assert (forall ((l (List (Pair T1 T2))))
(= (append (as nil (List (Pair T1 T2))) l) l)))
(assert (forall ((h (Pair T1 T2)) (t (List (Pair T1 T2))) (l (List (Pair T1 T2))))
(= (append (insert h t) l) (insert h (append t l)))))
;; Auxiliary definition
;; Given [a, b, c], d returns [(a, d), (b, d), (c, d)]
(declare-fun product-aux ((List T1) T2) (List (Pair T1 T2)))
(assert (forall ((v T2))
(= (product-aux (as nil (List T1)) v)
(as nil (List (Pair T1 T2))))))
(assert (forall ((h T1) (t (List T1)) (v T2))
(= (product-aux (insert h t) v)
(insert (mk-pair h v) (product-aux t v)))))
(declare-fun product ((List T1) (List T2)) (List (Pair T1 T2)))
(assert (forall ((l (List T1)))
(= (product l (as nil (List T2))) (as nil (List (Pair T1 T2))))))
(assert (forall ((l (List T1)) (h T2) (t (List T2)))
(= (product l (insert h t))
(append (product-aux l h) (product l t)))))
(declare-const a T1)
(declare-const b T2)
(declare-const l (List (Pair T1 T2)))
(assert (= (product (insert a (as nil (List T1))) (insert b (as nil (List T2))))
l))
(assert (not (= (first (head l)) a)))
(check-sat)
There isn't an #include directive for the smt-lib format.
Z3 provides several other ways to provide input.
The Python input format leverages all of Python, so importing files is naturally supported.
There is a tutorial on Z3Py on http://rise4fun.com/z3py

Scheme: pattern matching syntax

This was an edit to an earlier post. I am reposting it because I think the original isn't getting any more views since I accepted a partial answer already.
I have written a function match-rewriter which is just match-lambda except that it returns its argument if no match is found.
Using match rewriter I want to be able to write rules that can be passed to another function rewrite which is this:
#| (rewrite rule s) repeatedly calls unary function 'rule' on every "part"
of s-expr s, in unspecified order, replacing each part with result of rule,
until calling rule makes no more changes to any part.
Parts are s, elements of s, and (recursively) parts of the elements of s. (define (rewrite rule s) |#
(let* ([with-subparts-rewritten
(if (list? s) (map (λ (element) (rewrite rule element)) s) s)]
[with-also-rule-self (rule with-subparts-rewritten)])
(if (equal? with-also-rule-self with-subparts-rewritten)
with-also-rule-self
(rewrite rule with-also-rule-self))))
Here is an example of proper usage:
(define arithmetic
(match-rewriter (`(+ ,a ,b) (+ a b))
(`(* ,a ,b) (* a b))
))
(rewrite arithmetic '(+ (* 2 (+ 3 4)) 5))
==>
19
Now I have written:
(define let→λ&call
(match-rewriter (`(let ((,<var> ,<val>) . (,<vars> ,<vals>)) ,<expr> . ,<exprs>)
`((λ (,<var> . ,<vars>) ,<expr> . ,<exprs>) ,<val> . ,<vals>))))
to implement lets as lambda calls, but this is how it is behaving:
(rewrite let→λ&call '(let((x 1) (y 2) (z 3)) (displayln x) (displayln y) (displayln z)))
'((λ (x y 2)
(displayln x)
(displayln y)
(displayln z))
1
z
3)
which, I have to say, really has me stumped. Strangely this call:
(rewrite let→λ&call '(let((w 0) (x 1) (y 2) (z 3)) (displayln w) (displayln x) (displayln y) (displayln z)))
'(let ((w 0) (x 1) (y 2) (z 3))
(displayln w)
(displayln x)
(displayln y)
(displayln z))
Just returns its argument, meaning that match-rewriter did not find a match for this pattern.
Any advice is appreciated.
Thanks.
This pattern:
((,<var> ,<val>) . (,<vars> ,<vals>))
does not do what you want. In particular, it's equivalent to:
((,<var> ,<val>) ,<vars> ,<vals>)
I recommend that you use regular match patterns, rather than quasi-patterns, until you have a better sense of how they work. The pattern for this would be:
(list (list <var> <val>) (list <vars> <vals>) ...)

Resources