lisp parsing for 'not' - parsing

(defun simplify (x)
(if (and (not (null x)) (listp x))
(if (and (equal '(car x) '(cadr x)) (equal '(car x) 'not))
(simplify (cddr x))
(cons (car x) (simplify (cdr x)))
)
'nil
)
)
This lisp function is meant to take an expression as an argument then remove superfluous 'not's from it and return it. It checks if the argument is a non-empty list and returns nil if it isn't (base case). If it is non-empty, I want to check if the car(x) = car(cdr(x)) = 'not'. If they aren't detected to be a pair of 'not's then it should recurse and build on a list to return. If they are detected to be both 'not' then it should still recurse but also skipping both car(x) and car(cdr(x)). Right now all this code does is return an expression identical to the argument so I assume the problem is that my condition in the nested if statement isn't being set off properly, how can I check if car(x) and cadr(x) are both 'not'?

"when you assume..."
Actually, the test is semi-ok (but you'll end up taking (car nil) if x is (not) ). The problem is the recursion. Try it on paper:
(simplify '(and (not (not y)) (or x (not (not z))))`
(car x) is not not.
so: (cons (car x) (simplify (cdr x))
Now x is '((not (not y)) (or x (not (not z))))So(car x)is(not (not y)), which is not equal tonot`. Recurse again
Now x is ((or x (not (not z)))and(car x)is(or x (not (not z)))`. But you probably get the picture.
Hint: (map simplify x) and fix your termination condition to return x if x is an atom.

(equal '(car x) '(cadr x)) is always false, because the list (car x) is different from the list (cadr x). If you want to get the car and cadr of some particular x, you need to not quote these expressions.

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.

Scheme: problem about display when using `delay` expression

This is a problem related to ex3.51 in SICP, here is the code
(define (cons-stream x y)
(cons x (delay y)))
(define (stream-car stream) (car stream))
(define (stream-cdr stream) (force (cdr stream)))
(define (stream-map proc s)
(if (stream-null? s)
the-empty-stream
(cons-stream
(proc (stream-car s))
(stream-map proc (stream-cdr s)))))
(define (stream-enumerate-interval low high)
(if (> low high)
the-empty-stream
(cons-stream
low
(stream-enumerate-interval (+ low 1) high))))
(define (stream-ref s n)
(if (= n 0)
(stream-car s)
(stream-ref (stream-cdr s) (- n 1))))
(define (show x)
(display x)
x)
;test
(stream-map show (stream-enumerate-interval 0 10))
the output is 012345678910(0 . #<promise>).
but I thought the delay expression in cons-stream delayed the evaluation, if i use a different processing function in stream-map like lambda (x) (+ x 1) the output (1 . #<promise>) is more reasonable, so why does display print all the numbers?
The problem is with this definition:
(define (cons-stream x y)
(cons x (delay y)))
It defines cons-stream as a function, since it uses define.
Scheme's evaluation is eager: the arguments are evaluated before the function body is entered. Thus y is already fully calculated when it is passed to delay.
Instead, cons-stream should be defined as a macro, like
(define-syntax cons-stream
(syntax-rules ()
((_ a b) (cons a (delay b)))))
or we can call delay explicitly, manually, like e.g.
(define (stream-map proc s)
(if (stream-null? s)
the-empty-stream
(cons
(proc (stream-car s))
(delay
(stream-map proc (stream-cdr s))))))
Then there'd be no calls to cons-stream in our code, only the (cons A (delay B)) calls. And delay is a macro (or special form, whatever), it does not evaluate its arguments before working but rather goes straight to manipulating the argument expressions instead.
And we could even drop the calls to delay, and replace (cons A (delay B)) with (cons A (lambda () B)). This would entail also reimplementing force (which is built-in, and goes together with the built-in delay) as simply (define (force x) (x)) or just calling the (x) manually where appropriate to force a stream's tail.
You can see such lambda-based streams code towards the end of this answer, or an ideone entry (for this RosettaCode entry) without any macros using the explicit lambdas instead. This approach can change the performance of the code though, as delay is memoizing but lambda-based streams are not. The difference will be seen if we ever try to access a stream's element more than once.
See also this answer for yet another take on streams implementation, surgically modifying list's last cons cell as a memoizing force.

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.

What is the return statement in Scheme?

I am trying to translate this Python program to Scheme:
def test(x):
if x > 1:
print('foo')
if x > 10:
return
if x == 4:
print('bar')
test(1)
test(2) # prints 'foo'
test(4) # prints 'foo\nbar'
test(11) # prints 'foo'
What is the return statement in Scheme?
In Scheme there isn't an explicit return keyword - it's a lot simpler than that, the value of the last expression in a sequence of expressions is the one that gets returned. For example, your Python code will translate to this, and notice that the (> x 10) case had to be moved to the bottom, so if it's true it can exit the function immediately with a #f value.
(define (test x)
(if (> x 1)
(do-something))
(if (= x 4)
(do-something))
(if (> x 10)
#f))
(test 11)
=> #f
In fact, after reordering the conditions we can remove the last one, but beware: an unspecified value will be returned if x is not 4, according to Guile's documentation - in other words, you should always return a value in each case, and an if expression should have both consequent and alternative parts.
(define (test x)
(if (> x 1)
(do-something))
(if (= x 4)
(do-something)))
(test 11)
=> unspecified
And by the way, I believe the logic in the Python code is a bit off. The first condition will always be evaluated whenever a value of x greater than 1 is passed, but if it is less than or equal to 1 the returned value in Python will be None and in Scheme is unspecified. Also the original function isn't explicitly returning a value - in Python this means that None will be returned, in Scheme the returned value will be either (do-something) if x happens to be 4, or unspecified in any other case.
In Racket the most literal translation is:
#lang racket
(define (test x)
(let/ec return
(when (> x 1)
(do-something))
(when (> x 10)
(return 42))
(when (= x 4)
(do-something))))
(define (do-something)
(display "!"))
(test 11)
The let/ec is short for let/escape-continuation. Look up the equivalent control structure in the manual for your Scheme implementation of choice.
The example displays one ! and then returns 42.
The implicit return of Scheme can be illustrated by comparing how you can implement a simple function, such as square, in Python and scheme.
In Python:
def square(x):
return x*x;
In Scheme:
(define (square x)
(* x x))
As others have said, the last expression's value in a function is its return value, so you just have to arrange for exclusive execution pathways in your code, to achieve this effect.
(if <test> <consequent> <alternative>) is the basic branching operation in Scheme:
(define (test x)
(if (> x 1)
(do_something)
#f)
(if (> x 10)
#f ; return #f
;; else:
(if (= x 4)
(do_something)
;; else:
#f)))
(test 11)
Or we could use cond to avoid the needlessly nested structure in the code:
(define (test x)
(if (> x 1)
(do_something)
#f)
(cond
( (> x 10) #f)
( (= x 4) (do_something))
( else #f)))
You may use call/cc
(define (test x) (call/cc (lambda (k)
(if x
(k x)
(k))
(display "never displayed"))))
> (test 3)
3
> (test #f)
>
You can return no value using (k).
Read about Continuations.
I meet same question as you asked when I tried to implement a "tile" function to duplicate a list for multiple times. The idea is 1) create a variable to store the temporary result; 2) use "append" function in a for-loop; 3) return the temporary result.
The solution seems easy, as follows:
(define (tile ls n)
(define r (list ))
(do ((i 0 (+ i 1)))
((> i (- n 1)))
(begin
(set! r (append r ls))
)
)
r
)
actually a sole variable name itself will let the whole function return the value of this variable. This is because the Scheme always returns the last executed statement as the value of this function.
There is no return statement in Scheme. The body of a procedure is a sequence of expressions and the return value is the value of the last expression. So here is an equivalent Scheme program:
(define (test x)
(if (> x 1)
(display "foo\n"))
(if (not (> x 10))
(if (= x 4)
(display "bar\n"))))
(test 1)
(test 2) ; prints "foo"
(test 4) ; prints "foo\nbar"
(test 11) ; prints "foo"
You can simplify it to this program:
(define (test x)
(if (> x 1)
(display "foo\n"))
(if (= x 4)
(display "bar\n"))))

Comparing two lists of symbols in lisp

Let's say I have two lisp lists that are the same but in different sequence: '(A B C) and '(C B A).
How can I check if they are the same (in the sense that the elements are the same)?
CL-USER> (equal '(a b c) '(c b a))
NIL
Like this:
(not (set-exclusive-or '(a b c) '(c b a)))
which returns T if the two sets are equal, NIL otherwise.
[Edit] If they are not truly sets then you could use this:
(not (set-exclusive-or
(remove-duplicates '(a b c))
(remove-duplicates '(c b a))))
If the lists are not sets and repeated items are important, one could use a function like this:
(defun same-elements-p (a b)
(loop (when (and (null a) (null b))
(return t))
(when (or (null a) (null b))
(return nil))
(setf b (remove (pop a) b :count 1))))
If both lists are empty, they are the same. We remove all items of one list from the other and see what happens. Note the :count 1 argument to REMOVE. It makes sure than only one item is removed.
We can define the functions perm-equal and perm-equalp which are similar to EQUAL and EQUALP except that if the arguments are lists, then their permutation doesn't matter. The list (1 1 2 3) is perm-equal to (2 1 3 1), but not to (2 3 1).
The implementation works by normalizing values into a canonical permutation by sorting. This brings up the ugly spectre of requiring an inequality comparison. However, we can hide that by providing a predefined one which works for numbers, symbols and strings. (Why doesn't the sort function do something like this, the way eql is defaulted as the :key parameter?)
(defun less (a b)
(if (realp a)
(< a b)
(string< a b)))
(defun lessp (a b)
(if (realp a)
(< a b)
(string-lessp a b)))
(defun perm-equal (a b &optional (pred #'less))
(if (or (atom a) (atom b))
(equal a b)
(let ((as (sort (copy-list a) pred))
(bs (sort (copy-list b) pred)))
(equal as bs))))
(defun perm-equalp (a b &optional (pred #'lessp))
(if (or (atom a) (atom b))
(equalp a b)
(let ((as (sort (copy-list a) pred))
(bs (sort (copy-list b) pred)))
(equalp as bs))))
Notes:
Doesn't handle improper lists: it just tries to sort them and it's game over.
Even though equalp compares vectors, perm-equalp doesn't extend its permutation-squashing logic over vectors.
realp is used to test for numbers because complex numbers satisfy numberp, yet cannot be compared with <.
The trivial answer for non-sets is to sort both lists. CL's default sort is destructive, so you'll need copies if you want to keep them afterwards.
(defun sorted (a-list predicate)
(sort (copy-list a-list) predicate))
(defun same-list-p (list-a list-b predicate)
(equalp (sorted list-a predicate) (sorted list-b predicate)))
It doesn't have the best performance, but is simple and functional.
This looks to me like an O(n) variant:
(defun equal-elementwise (a b &key (test #'eq))
(loop with hash = (make-hash-table :test test)
for i on a for j on b do
(let ((i (car i)) (j (car j)))
(unless (funcall test i j)
(setf (gethash i hash) (1+ (gethash i hash 0))
(gethash j hash) (1- (gethash j hash 0)))))
finally (return
(unless (or (cdr i) (cdr j))
(loop for value being the hash-value of hash do
(unless (zerop value) (return))
finally (return t))))))
However, this won't be efficient on short lists.

Resources