Count occurrence of element in list - scheme

I created this method which, given a Scheme s-expression, should return the number of sub-expressions which are equal? to literal – for example (count '((a b c) b) 'b) should return 2.
(define (count list literal)
(define (count-under list literal count)
(cond
[(null? list) count]
[(member literal (car list)) (count-under (cdr list) literal (+ count 1))]))
(count-under list literal 0))
I am not getting any output from what I have written so far.

When I try to evaluate (count '((a b c) b) 'b) with the definition of count you propose, DrRacket shows the error message
member: not a proper list: 'b
So I definitely do get output from what you've written so far. However, as Racket indicates, your code attempts to do a member-check on something that's not a list.
To see why, mentally trace what your program is doing when list is '((a b c) b) and literal is 'b):
Check whether '((a b c) b) is null?. It isn't, so we move to the next branch.
Check whether 'b is a member of (car '((a b c) b), i.e., '(a b c). It is, so we execute this branch's consequent.
Recurse with list bound to (cdr '((a b c) b), i.e., to '(b). You correctly pass along the literal unchanged, and increment the count.
Check whether '(b) is null?. It isn't, so we move to the next branch.
Check whether 'b is a member of (car '(b), i.e., 'b. 'b isn't a list, so member throws an error.

Related

What is the concept of "third" in Primitive function scheme?

I am new at scheme computation.
I have a given problem:
(DEFINE (third C) (CAR(CDR CDR(C))))
(third ‘(A (B C) (D E) F))
I know the concept of CDR and CAR, but I don't understand what will "third" do. I read that it is a way to define "threesome???".
I am inclined to replace the value of C by the value of the second statement next to third which is ‘(A (B C) (D E) F), is this correct?
Can you explain in simple term as possible what "third" do in this given and how can I solve this given problem?
In lisps the list is a fundamental data structure, and it is comprised of pairs. Traditionally, the first member of the pair is called its car, and the second member is called its cdr:
( car . cdr )
Here the dot indicates that the pair is composed of two cells. Given a pair, (a . b), the accessor for the first member is also called car, and the accessor for the second member is called cdr. So:
(car '(a . b)) --> a, and
(cdr '(a . b)) --> b.
To form a list, pairs are combined in the following way: the first member of the first pair is the first element of the list, and the second member of the first pair is either the empty list or a pair representing the rest of the list. So, a list of one element, e.g., (a) is represented by the pair (a . ()).
A list of two elements, e.g., (a b) is represented by the pair (a . (b . ())). Here, the second member of the first pair is the pair (b . ()). You will note that the cdr of the list (a b) is the list (b), or equivalently (b . ()).
A list of three elements, e.g., (a b c) is similarly represented as (a . (b . (c . ()))). A list is a pair which has either the empty list () or a pair in its cdr. There is a distinction to be made here about proper lists (the final pair must have a () in its cdr) and improper lists, but I will ignore that distinction here. And the empty list is also a list (but not a pair). To make things a bit more precise: in Scheme a list is either the empty list or a pair whose cdr is a list.
So, car gets the first member of a list, and cdr gets the rest of the list. Given the list (a b c d) we can see that:
(cdr '(a b c d)) --> (b c d), and
(cdr (cdr '(a b c d))) --> (cdr '(b c d)) --> (c d), and
(car (cdr (cdr '(a b c d)))) --> (car (cdr '(b c d))) --> (car '(c d)) --> c.
So, given the definition:
(define (third xs)
(car (cdr (cdr xs))))
We have:
> (third '(a b c d))
c
I will leave it to the OP to apply this information to the question of:
(third '(a (b c) (d e) f)) --> ?

Retrieve nth cdr of a list in Scheme

I would like to return the nth cdr of a list. For example, I say
(nth-cdr 3 '(a b c d e)) and i would get (c d e) as output. I am not sure where I am going wrong with my code.
My approach is this. I will check if (= num 0) if it is, I will return the list. If not, I will recursively call nth-cdr and subtract 1 from num and cdr list
The code is this
(define arbitrary-cdr (lambda (num list)
(if (= num 0)
'()
(arbitrary-cdr (- num 1) (cdr list))
)))
However, I get this error when i try doing (arbitrary-cdr 3 ‘(a b c d e))
‘: undefined;
cannot reference an identifier before its definition
I am not sure what this means. When I say that, it means I hit the base case and would just like to return the list. I think my logic is correct though.
The first code that you posted was:
(define arbitrary-cdr
(lambda (num list)
(if (= num 0)
(list)
(arbitrary-cdr (- num 1) (cdr list)))))
The error that you received was:
scratch.rkt> (arbitrary-cdr 3 '(a b d c e))
; application: not a procedure;
; expected a procedure that can be applied to arguments
; given: '(c e)
The problem was that you used list as an argument to the arbitrary-cdr procedure; since Racket is a lisp-1, procedures do not have their own namespace, so this redefined list. With (list), and with list redefined the code attempted to call ((c e)), but (c e) is not a procedure.
This is a great example for why you should not use list or other built-in procedure identifiers as parameters in your own procedure definitions in Scheme or Racket. You can get away with this in Common Lisp, because Common Lisp is a lisp-2, i.e., has a separate namespace for functions.
With your updated code:
(define arbitrary-cdr
(lambda (num list)
(if (= num 0)
'()
(arbitrary-cdr (- num 1) (cdr list)))))
I don't get the error you report; maybe your code is not quite what you have posted. But, there is a mistake in the logic of your code. As it is, an empty list will always be returned:
scratch.rkt> (arbitrary-cdr 3 '(a b c d e f))
'()
The problem is that when the base case is reached you should return the input list, not an empty list. That is, given (arbitrary-cdr 0 '(a b c)), you want the result to be (a b c). This also means that your test case is wrong; (arbitrary-cdr 0 '(a b c d e)) --> '(a b c d e), and (arbitrary-cdr 3 '(a b c d e)) --> '(d e).
Here is your code rewritten, using xs instead of list to avoid the redefinition, and returning xs instead of an empty list when the base case is reached:
(define arbitrary-cdr
(lambda (num xs)
(if (= num 0)
xs
(arbitrary-cdr (- num 1) (cdr xs)))))
Sample interactions:
scratch.rkt> (arbitrary-cdr 0 '(a b c d e))
'(a b c d e)
scratch.rkt> (arbitrary-cdr 1 '(a b c d e))
'(b c d e)
scratch.rkt> (arbitrary-cdr 3 '(a b c d e))
'(d e)

Set operation A\B in Common Lisp

I just started learning Common Lisp 2 days ago, so please excuse spaghetti code and non-understanding.
My problem is the following: I want to write a function that performs the set-
operation A\B, where A and B sets that are not empty. They are represented by two lists.
So far I came up with this:
(defun myDifference (a b)
(if (null a)
(return-from myDifference) ;when a hits NIL, get outta the whole function
)
(if (not(member (car a) b)) ; if the first element of A ist not in B, add it to a list (which later should be the return)
(cons (car a) '())
)
(myDifference (cdr a) b) ; proceed with the remaining elements of A, until (null a) hits
)
I tried it with:
(myDifference '( 1 2 3) '(1 5 6))
But the output is NIL, whichever lists I try it on.
I suspect the problem occurs in quitting the function.
You have 3 expressions in your my-difference body. The first returns nil if (null a)
The second computes either (list a) or (list), then discards that value.
The third recurses with a changed to (cdr a).
It's clear that this has to return nil since the last one eventuelly recurses with a becoming nil and the recursion then returns nil since that is the default value when you don't supply a value. A better approach would be to make it one expression like this:
(defun my-difference (a b)
(if (null a)
a
(if (not (member (car a) b))
(cons (car a) (my-difference (cdr a) b))
(my-difference (cdr a) b))))
The third part of if is the else part and as you see we nest to get somthing similar to if-elseif-else of other languages. This can be written flatter with cond:
(defun my-difference (a b)
(cond ((null a) a)
((not (member (car a) b))
(cons (car a) (my-difference (cdr a) b)))
(t (my-difference (cdr a) b))))

Scheme - checking structural equivalences of lists (how to use AND)

I am trying to write a program that will check the structural equivalence of some list input, whether it includes just atoms or nested sub lists.
I am having trouble with using AND, I don't even know if its possible and I cant seem to understand documentation I am looking at.
My code:
(define (structEqual a b)
(cond
(((null? car a) AND (null? car b)) (structEqual (cdr a) (cdr b)))
(((null? car a) OR (null? car b)) #f)
(((pair? car a) AND (pair? car b))
(if (= (length car a) (length car b))
(structEqual (cdr a) (cdr b))
#f))
(((pair? car a) OR (pair? car b)) #f)
(else (structEqual (cdr a) (cdr b)))))
The idea is (i think): (when I say both, i mean the current cdr of a or b)
Check if both a and b are null, then they are structurally equal
Check if only either a or b is null, then they are not structually equal
Check if both of them are pairs
If they are both pairs, then see if the length of the pair is equal, if not they are not structurally equal.
If they are not both pairs, then if one of them is a pair and the other isnt then they are not structurally equivalent.
If neither of them are pairs, then they both must be atoms, so they are structurally equivalent.
So as you can see I am trying to recursively do this by checking the equivalence of the car of a or b, and then either returning #f if they fail or moving on to the cdr of each if they are equivalent at each step.
Any help?
There is no infix operators in Scheme (or any LISP) only prefix. Every time the operator comes first. (or x (and y z q) (and y w e)) where each letter can be a complex expression. Everything that is not #f is a true value. Thus (if 4 'a 'b) evaluates to a because 4 is a true value. car needs its parentheses.
When evaluating another predicate in cond you should make use of the fact that everything up to that has been false. eg.
(define (structure-equal? a b)
(cond
((null? a) (null? b)) ; if a is null the result is if b is null
((not (pair? a)) (not (pair? b))) ; if a is not pair the result is if b is not also
((pair? b) (and (structure-equal? (car a) (car b)) ; if b is pair (both a and b is pair then) both
(structure-equal? (cdr a) (cdr b)))) ; car and cdr needs to be structurally equal
(else #f))) ; one pair the other not makes it #f
(structure-equal '(a (b (c d e) f) g . h) '(h (g (f e d) c) b . a)) ; ==> #t

Meaning of 'quote in Lisp

This question arose when reading SICP. Why (list 'quote '(a b c)) evaluated by the interpreter (R5RS in Dr.Racket) as '(a b c). For me it should be (quote (a b c)). For instance (list 'quot '(a b c)) is evaluated as (quot (a b c)). What is so special in the 'quote?
You'll get different behaviors depending on exactly what Lisp you're using (Scheme, Racket, Common Lisp, etc.) but in general, the system will accept 'x as a shorthand or syntactic sugar for (quote x). The two forms are exactly equivalent and their values are the same: the unevaluated x. When a result is coming out of the system, it might choose to print in the first way to make the result more intuitive to the user. A similar thing happens with cons, too. For instance,
(cons 1 2)
;=> (1 . 2)
because that's the general way that cons cells (pairs) are printed. However, there's a special case defined for when the second part of the pair is another list (either the empty list () or another pair, and that's why we have the following. I've also written a bit more about how lists and cons cells are printed in an answer to Recursive range in Lisp adds a period?.
(cons 1 '())
;=> (1)
(cons 1 '(2 3))
;=> (1 2 3)
Now, I've written the values of the expression above. E.g., the value of the form (cons 1 '(2 3)) is the list (1 2 3). As an additional complication, some systems (I'm thinking of some languages is Dr. Racket, in particular) don't print the value of a form in the interactive prompt, but rather print a form that would produce the same (for certain interpretations of “the same”) values. For instance, you might evaluate '(1 . 2) and see the output (cons 1 2) because that's another form that would produce the same value. This can be helpful if you're doing pure functional programming that has referential transparency, but if you're not expecting it, it can lead to some confusion.
A good way to see that we're getting the results that we should, regardless of how the system prints them, is to inspect them. We expect that (list 'quote '(a b c)) should return a list whose car is the symbol quote and whose cadr is the list (a b c). This is what we get (in Dr. Racket 5.3 with language R5RS):
> (display (list 'quote '(a b c)))
'(a b c)
> (display (car (list 'quote '(a b c))))
quote
> (display (cadr (list 'quote '(a b c))))
(a b c)
We get similar results if we use 'qmmmt instead of 'quote:
> (display (list 'qmmmt '(a b c)))
(qmmmt (a b c))
> (display (car (list 'qmmmt '(a b c))))
qmmmt
> (display (cadr (list 'qmmmt '(a b c))))
(a b c)
The only difference is that in the first case, display displays the list whose car is the symbol quote using the shorthand that is available for such lists. That is, instead of displaying (quote (a b c)) it displayed '(a b c).
'(a b c) and (quote (a b c)) are actually different notations for the same. So don't be surprised if your Lisp prints the shorter version.
In general '<something> is the same as (quote <something>).
QUOTE is used in Lisp to mark expressions which should evaluate to themselves. Usually a list would be a function or macro call and a symbol would be a variable. If you want to treat those as data, you need to quote them.
Since (quote <something>) is used so often in Lisp, the abbreviated version '<something> has been introduced to save a bit of typing or reading...
display emits some behaviors. Eg. '(a . (b . (c . ()))) is displayed (a b c). 'quote is displayed quote and perhaps '(quote x y) is displayed (quote x y) while '(quote x) is displayed 'x or (quote x). Which one is implementation dependent but both mean the same.
As data (ie. quoted, like (quote quote) and it's abbrivation 'quote) the result of the evaluation, the symbol quote is nothing special, for any LISP, just like '+ and 'potato happen to be the symbols + and potato. Any symbol that mean something when not quoted is no special when quoted.
It also took me a while to understand this problem. But it's just your good-hearted lisp interpreter showing (quote (a b c)) in it's equivalent form '(a b c). Since there is no such equivalence/syntactic sugar for (quott (a b c)), it's shown as is.

Resources