Scheme Traverse and print a DAG in a depth first way - printing

Let a NODE be a function with a STORE in its closure. All leafs of the graph have a STORE that is a single value (either a constant or a variable) and all internal nodes have a STORE that is a list containing:
A symbol representing a function ('+ '* 'cos 'sin etc)
A list of one or more NODES representing the children of this NODE.
A simplification function (which is irrelevant for my question).
Assume [[(NODE f)]] = [[(f STORE)]] if f is a procedure and STORE is the STORE in NODE'S closure.
I am trying to find a way to traverse this tree and print an expression that can be evaluated with (eval). I have come close but I just cannot get it to work.
Here is my code:
(define repr
(lambda(store)
(if (is_leaf? store)
store
(list (car store)
(repr_helper (cadr store) repr)))))
(define repr_helper
(lambda(f_list arg)
(cond ((null? f_list) '())
(else (cons ((car f_list) arg) (repr_helper (cdr f_list) arg))))))
Simple exemple: Assume a tree with a single addition of 4 arguments (creates a + node with 4 children all of which are leaves).
((Add 10 'x 'y 'z) repr)
Output: '(+ (10 x y z)).
Expected output: '(+ 10 x y z)
As you can see the problem comes from the extra parenthesis inside the expression. You can imagine this is even worse for more complex examples. I understand where I create the list and why the parenthesis is there, but I can't seem to find a way to remove it, print the values correctly.

Try modifying the part that builds the list, like this:
(define repr
(lambda (store)
(if (is_leaf? store)
store
(cons (car store)
(repr_helper (cadr store) repr)))))
We just need to add a new item at the head of the list returned by repr_helper, a call to cons will do the trick.

Related

delete! function for R5RS

I'm trying to write a delete! function that mutates a list and removes from it a specified value. This is the code I have so far.
(define (extend! l . xs)
(if (null? (cdr l))
(set-cdr! l xs)
(apply extend! (cdr l) xs)))
(define (delete! lis y)
(define returnLis '())
(for-each (lambda(x) (if(not(eq? x y))
(extend! returnLis x))) lis)
returnLis)
The problem I am having is that I am trying to add to an empty list which can't be done in Scheme.
Desired outcome:
(delete! '(1 2 3 4 5) 3)
=> (1 2 4 5)
Your extend function use actually would make a copy of each element in a fresh pair, but since the initial value is '() it cannot be set-cdr!. The whole point of mutating something is that old variables will continue point to the changed data and making a copy won't do that.
You need to see the pairs. You want to remove 3
[1,-]->[2,-]->[3,-]->[4,-]->[5,-]->()
So When you have found 3, you need to change the cdr of the pair that holds 2 and pint it the pair that holds 3s cdr like this:
[1,-]->[2,-]->[4,-]->[5,-]->()
Something like this then:
(define (delete lst e)
(if (and (not (null? lst)) (not (null? (cdr lst))))
(if (equal? (cadr lst) e)
(set-cdr! lst (cddr lst))
(delete (cdr lst) e))
'undefined))
(define test (list 1 2 3 4 5))
(delete lst 3)
lst ; ==> (1 2 4 5)
Notice I'm using list since a quoted literal cannot be used here since you are not allowed to change constant data like '(1 2 3 4 5). The result will be undefined or it will signal an error.
It won't work if the element in question is the first. It's because the variable points to the first pair and this only changes the pointers in pairs, not bindings. One could just switch the two first and delete the second, but in the event you have a one element list you are still stuck. Scheme implementations of mutable queues usually have a head consisting of a dummy element not considered part of the list to delete the first element.
All you need is a head-sentinel technique:
(define (delete! lis y)
(define returnLis (list 1))
(for-each (lambda(x) (if(not(eq? x y))
(extend! returnLis x))) lis)
(cdr returnLis))
Well, not all... because as it is, this is a quadratic algorithm. It re-searches the returnLis from top anew while adding each new element with extend!. Better just maintain the last cdr cell and update it:
(define (delete! lis y)
(define returnLis (list 1))
(define last-cell returnLis)
(for-each (lambda(x) (cond ((not(eq? x y))
; (extend! last-cell x)
(set-cdr! last-cell (list x))
(set! last-cell (cdr last-cell)))))
lis)
(cdr returnLis))
But, as #Sylwester points out, with this approach you shouldn't use an exclamation mark in the name, as this will return a freshly built list instead of mutating the argument's structure.

Streams and the substitution model

I am wondering how the substitution model can be used to show certain things about infinite streams. For example, say you have a stream that puts n in the nth spot and so on inductively. I define it below:
(define all-ints
(lambda ((n <integer>))
(stream-cons n (all-ints (+ 1 n)))))
(define integers (all-ints 1))
It is pretty clear that this does what it is supposed to, but how would someone go about proving it? I decided to use induction. Specifically, induction on k where
(last (stream-to-list integers k))
provides the last value of the first k values of the stream provided, in this case integers. I define stream-to-list below:
(define stream-to-list
(lambda ((s <stream>) (n <integer>))
(cond ((or (zero? n) (stream-empty? s)) '())
(else (cons (stream-first s)
(stream-to-list (stream-rest s) (- n 1)))))))
What I'd like to prove, specifically, is the property that k = (last (stream-to-list integers k)) for all k > 1.
Getting the base case is fairly easy and I can do that, but how would I go about showing the "inductive case" as thoroughly as possible? Since computing the item in the k+1th spot requires that the previous k items also be computed, I don't know how this could be shown. Could someone give me some hints?
In particular, if someone could explain how, exactly, streams are interpreted using the substitution model, I'd really appreciate it. I know they have to be different from the other constructs a regular student would have learned before streams, because they delay computation and I feel like that means they can't be evaluated completely. In turn this would man, I think, the substitution model's apply eval apply etc pattern would not be followed.
stream-cons is a special form. It equalent to wrapping both arguments in lambdas, making them thunks. like this:
(stream-cons n (all-ints (+ 1 n))) ; ==>
(cons (lambda () n) (lambda () (all-ints (+ n 1))))
These procedures are made with the lexical scopes so here n is the initial value while when forcing the tail would call all-ints again in a new lexical scope giving a new n that is then captured in the the next stream-cons. The procedures steam-first and stream-rest are something like this:
(define (stream-first s)
(if (null? (car s))
'()
((car s))))
(define (stream-rest s)
(if (null? (cdr s))
'()
((cdr s))))
Now all of this are half truths. The fact is they are not functional since they mutates (memoize) the value so the same value is not computed twice, but this is not a problem for the substitution model since side effects are off limits anyway. To get a feel for how it's really done see the SICP wizards in action. Notice that the original streams only delayed the tail while modern stream libraries delay both head and tail.

Scheme and Shallow Binding

(define make (lambda (x) (lambda (y) (cons x (list y)))))
(let ((x 7)
(p (make 4)))
(cons x (p 0)))
I'm new to Scheme and functional program, so I am a bit clunky with walking through programs, but I get that if I used deep binding this program will return (7 4 0). Makes sense. What would this program do using shallow binding? I get this may sound dumb but is the p in the line with cons a redefinition? So in that case, we would return (7 0)?
Basically, I understand the concept of deep v. shallow binding, but I feel like I'm jumbling it up when looking at Scheme because I'm not crazy familiar with it.
Deep or shallow binding is an implementational technique and can not be observed from inside the program. The difference for the programmer is between lexical and dynamic scoping rules, but both can be implemented with any of the two techniques (i.e. one notion has got nothing to do with the other).
Deep or shallow refers to the choice of stack frame to hold a given outer scoped variable's binding. In deep binding there is a chain of frames to be accessed until the correct frame is entered holding the record for the variable; in shallow binding all bindings are present in one, shallow environment. See also "rerooting" (which only makes sense in the context of shallow binding implementation of lexical scoping).
To your specific question, under lexical scoping rules your code would return (7 4 0) and under dynamic - (7 7 0), because the call ((lambda(y) (list x y)) 0) is done inside the dynamic scope of x=7 binding (as a side note, (cons x (list y)) is the same as (list x y)):
x = 7
p = (lambda (y) (list x y)) ; x=4 is unused, in p=(make 4)
(cons 7 (p 0)) == (list 7 7 0) ; 'x' in this line and in lambda body for p
; both refer to same binding that is
; in effect, i.e. x=7
NB same terms (deep/shallow binding) are used in other language(s) now with completely different meaning (they do have something to do with the scoping rules there), which I don't care to fully understand. This answer is given in the context of Scheme.
Reference: Shallow Binding in LISP 1.5 by Baker, Henry G. Jr., 1977.
See this wikipedia article for a discussion on scoping (it mentions lexical/dynamic scoping and deep/shallow binding) bearing in mind that Scheme is lexically scoped. Will Ness' answer provides additional information.
For now, let's see step-by-step what's happening in this snippet of code:
; a variable called x is defined and assigned the value 7
(let ((x 7)
; make is called and returns a procedure p, inside its x variable has value 4
(p (make 4)))
; 7 is appended at the head of the result of calling p with y = 0
(cons x (p 0)))
=> '(7 4 0)
Notice that in the second line a closure is created in the lambda returned by make, and the variable x inside will be assigned the value 4. This x has nothing to do with the outer x, because Scheme is lexically scoped.
The last line is not a redefinition, as mentioned in the previous paragraph the x inside make is different from the x defined in the let expression.

Scheme console printing

Just started with Scheme. I'm having problem with printing on console.
A simple list printing example:
(define factorial
(lambda (n)
(cond
((= 0 n) 1)
(#t (* n (factorial (- n 1)))))))
I want to print n, every time the function is called. I figured that I can't do that within the same function? Do I need to call another function just so I can print?
Printing in Scheme works by calling display (and possibly, newline).
Since you want to call it sequentially before/after something else (which, in a functional (or in the case of Scheme, functional-ish) language only makes sense for the called functions side-effects), you would normally need to use begin, which evaluates its arguments in turn and then returns the value of the last subexpression. However, lambda implicitly contains such a begin-expression.
So in your case, it would go like this:
(lambda (n)
(display n) (newline)
(cond [...]))
Two remarks:
You can use (define (factorial n) [...]) as a shorthand for (define factorial (lambda (n) [...])).
The way you implement factorial forbids tail call-optimization, therefore the program will use quite a bit of stack space for larger values of n. Rewriting it into a optimizable form using an accumulator is possible, though.
If you only want to print n once, when the user calls the function, you will indeed need to write a wrapper, like this:
(define (factorial n)
(display n) (newline)
(inner-factorial n))
And then rename your function to inner-factorial.

How to make a better mapper in Scheme using Streams

The Scheme implementation of map takes N+1 arguments: a procedure of N arguments, and N lists. Further, it terminates mapping when the end of the shortest list is reached.
An alternative is to provide a default value for each list, which will be treated as the next element(s) of each list if it turns out to be shorter than the others.
That is define a procedure streem-map which takes as its arguments:
a procedure of N arguments
a list of N elements, which is the default value for the Nth stream
N streams
Streem-map produces a stream where the first element is the procedure applied to the (N) first elements of the streams, the second element is the same procedure applied to the second elements of the streams, and so on. If the Nth stream becomes empty, streem-map uses the Nth default element. Therefore, the stream produced by streem-map will always have infinite length; if all of the N input streams are of finite length, eventually it will generate lists consisting of the
procedure applied to the N default values.
For example:
(streem-map (lambda (x y z) (* x y z))
‘(0 1 2)
(list->streem ‘(1 2 3))
(list->streem ‘(9 9))
(list->streem ‘(4))
would generate the infinite stream consisting of: ‘(36 36 6 0 0 0 …)
Let's first define a set of basic stream primitives, so that the rest of the code makes sense:
(define-syntax stream-cons
(syntax-rules ()
((stream-cons obj expr)
(cons obj (delay expr)))))
(define stream-car car)
(define (stream-cdr p) (force (cdr p)))
(define stream-null? null?)
With these we can define operations for "streems", our "better streams".
(define (streem-car stream default)
(if (stream-null? stream) default (stream-car stream)))
(define (streem-cdr stream)
(if (stream-null? stream) stream (stream-cdr stream)))
(define (streem-map proc defaults . streams)
(stream-cons (apply proc (map streem-car streams defaults))
(apply streem-map proc defaults (map streem-cdr streams))))
You should be able to easily adapt this to whatever stream library you are already using.
You don't need a separate list->streem conversion, you can pass streem-map regular streams (presumably created with list->stream).
If you use the streams of SRFI-41, this is just an application of stream-unfold. Note: I am the author of SRFI-41.

Resources