Lisp function: count the number of atoms in an expression - lisp

I am writing a function in lisp and I am not getting a result.
The function is to count the number of atoms in a expression.
(defun count-atoms(exp)
'Return the total number of non-nil atoms in the expression'
(cond((null exp) 0)
((atom exp) 1)
( t (+ (count-atoms (first exp))
(count-atoms (rest exp))))))
When I run in clisp, all I get is the following without the result.
[3]> (count-atoms '(a b c))
(COND ((NULL EXP) 0) ((ATOM EXP) 1)
(T (+ (COUNT-ATOMS (FIRST EXP)) (COUNT-ATOMS (REST EXP)))))
Can anyone help?

I'm surprised that you get a result at all. I get an error:
*** - PROGN: variable THE has no value
The following restarts are available:
USE-VALUE :R1 Input a value to be used instead of THE.
STORE-VALUE :R2 Input a new value for THE.
ABORT :R3 Abort main loop
The reason is that strings in Common Lisp must be in double quotes: "Return ...". Single quotes are only used to prevent evaluation.

Related

Lisp function count recurring a's in list

I am trying to write a function that takes only a list as a parameter and counts the number of times the symbol a appears in the list, without counting any a's in a sublist within the list.
I am very new to Lisp so please use as basic code as possible so I could understand what it is doing, even if it is inefficient.
(defun times (l)
(setf x 'a)
(cond
((null l) nil)
((equal x (car l)) (+ 1 (times x (cdr L))))
(t (times x(cdr l)))))
So (times '(a b (a) c)) should return 1. However I am getting the error that with this line times is getting two arguments when it should be getting one.
There are multiple ways to implement this in Common Lisp. The example should be small enough for you to follow (test them).
Recursive implementation
Your approach is fine, except you have small errors (in addition to the other ones reported in comments):
Do not use SETF for undeclarded variables.
Do not return NIL in the base case: your function should return a number.
Also, your code coud be better formatted, and you should use longer names (lowercase l in particular is hard to read)
Here is a modified version:
(defun times (list element)
(cond
((null list) 0)
((equal (car list) element) (1+ (times (cdr list) element)))
(t (times (cdr list) element))))
Example
Let's TRACE the function:
CL-USER> (trace times)
Here is the execution trace:
CL-USER> (times '(a b c d a f a) 'a)
0: (TIMES (A B C D A F A) A)
1: (TIMES (B C D A F A) A)
2: (TIMES (C D A F A) A)
3: (TIMES (D A F A) A)
4: (TIMES (A F A) A)
5: (TIMES (F A) A)
6: (TIMES (A) A)
7: (TIMES NIL A)
7: TIMES returned 0
6: TIMES returned 1
5: TIMES returned 1
4: TIMES returned 2
3: TIMES returned 2
2: TIMES returned 2
1: TIMES returned 2
0: TIMES returned 3
3
You can see that the call stack grows for each and every element visited in the list. It is usually a bad practice, especially when the recursive function is basically implementing a loop.
Loops
Use a simple LOOP:
(defun times (list element)
(loop for value in list count (equal value element)))
Alternatively, use DOLIST:
(defun times (list element)
(let ((counter 0))
(dolist (value list counter)
(when (equal element value)
(incf counter)))))
Here above, counter is a local variable introduced by LET. It is incremented with INCF inside the loop, only WHEN the comparison holds. Finally, counter is returned from the dolist (the third parameter indicates which form to evaluate to have the result value). The return value of dolist is also the return value of the let and the whole function.
This can be rewritten also with DO:
(defun times (list element)
(do ((counter 0)) ((null list) counter)
(when (equal element (pop list))
(incf counter))))
The first list in do introduces bindings, the second list is a termination test (here we stop when the list is empty) followed by a result form (here, the counter). Inside the body of the loop, we POP elements from the input list and do the comparison, as before.
Tail-recursive implementation
If you want to keep a recursive implementation, add an accumulator and compute all the intermediate results before entering a recursive evaluation. If all results are passed as function arguments, there is no need to keep track of intermediate results at each step of the recursion, which eliminates the need to even allocate stack frames. The ability to perform tail-call elimination is not expressly required by the specification of the language, but it is typically available in most implementations.
(defun times (list element)
(labels ((recurse (list counter)
(cond
((null list) counter)
((equal (first list) element)
(recurse (rest list) (1+ counter)))
(t (recurse (rest list) counter)))))
(recurse list 0)))
Here above, recurse is a local recursive function introduced by LABELS, which accepts a counter parameter. The difference with the original recursive function is that when the list is empty, it returns the current value of counter instead of zero. Here, the result of recurse is always the same as the value returned by recursive invocations: the compiler can just rebind inputs and perform a jump instead of allocating intermediate frames.
Higher-order functions
Here are yet two other ways, based on higher-order functions.
First, the usual way to define functions with accumulators is with REDUCE (known as fold in other languages). There is no explicit mutation:
(defun times (list element)
(reduce (lambda (counter value)
(if (equal value element)
(1+ counter)
counter))
list
:initial-value 0))
The anonymous function accepts the current state of the accumulator, the current value being visited in the list, and shall compute the next state of the accumulator (the counter).
Alternatively, call MAP with a nil first argument, so that the iteration is only done for effects. The anonymous function established by the LAMBDA form closes over the local counter variable, and can increment it when comparison holds. It is similar to the previous dolist example w.r.t. incrementing the counter through side-effects, but the iteration is done implicitly with map.
(defun times (list element)
(let ((counter 0))
(map ()
(lambda (value)
(when (equal value element)
(incf counter)))
list)
counter))
Built-in
For your information, there is a built-in COUNT function:
(defun times (list element)
(count element list :test #'equal))
Here is some code which might help. It uses tail recursion and defines a helper function which is called recursively and keeps track of the number of times the symbol 'a appears with the argument count. The helper function takes two arguments, but the functino count-a takes one. Count-a calls the helper with the list l and the total number of times it has counted the symbol 'a at the beginning, which is zero to kick off the recursive calls.
(defun count-a (l)
(labels ((helper (x count)
(if (equalp 'a (car x)) (incf count))
(cond ((null x) count)
(t (helper (cdr x) count)))))
(helper l 0)))
You can also use the loop macro:
(defun count-a-with-a-loop (l)
(loop for i in l count (equalp 'a i))\
Or as Coredump points out:
(defun count-a-with-count (l)
(count 'a l :test #'equal))
Note the '# character before equal lets the Lisp interpreter know that equal is a function, known as a reader macro.
If you use a Lisp compiler (like SBCL) you might see this:
* (defun times (l)
(setf x 'a)
(cond
((null l) nil)
((equal x (car l)) (+ 1 (times x (cdr L))))
(t (times x(cdr l)))))
; in: DEFUN TIMES
; (TIMES X (CDR L))
;
; caught WARNING:
; The function was called with two arguments, but wants exactly one.
;
; caught WARNING:
; The function was called with two arguments, but wants exactly one.
;
; caught WARNING:
; undefined variable: X
;
; compilation unit finished
; Undefined variable:
; X
; caught 3 WARNING conditions
The Lisp compiler tells you that there are three errors in your code.
Let's fix the undefined variable problem first, by introducing a local variable x:
(defun times (l)
(let ((x 'a))
(cond
((null l) nil)
((equal x (car l)) (+ 1 (times x (cdr L))))
(t (times x (cdr l))))))
Now, we look at the other two: you call TIMES with two arguments.
We can just remove the x argument, since it is not needed:
(defun times (l)
(let ((x 'a))
(cond
((null l) nil)
((equal x (car l)) (+ 1 (times (cdr L))))
(t (times (cdr l))))))
It may be more useful to be able to search for more things, so we add x to the argument list and add it to the call arguments.
(defun times (x l)
(cond
((null l) nil)
((equal x (car l)) (+ 1 (times x (cdr L))))
(t (times x (cdr l)))))
Now the function should always return a number, not NIL for an empty list:
(defun times (x l)
(cond
((null l) 0)
((equal x (car l)) (+ 1 (times x (cdr L))))
(t (times x (cdr l)))))
Since Lisp has functions like first and rest, we can replace car and cdr:
(defun times (x l)
(cond
((null l) 0)
((equal x (first l)) (+ 1 (times x (rest l))))
(t (times x (rest l)))))

Lisp Arithmetic simplification

I'm a newbie when it comes to programming in lisp and ill be honest recursion is not my forte, I was tasked with writing a function that would simplify arithmetic equations but not solve them. Here is the guidelines this is a school project by the way.
*Write function simplify that takes any arithmetic expression as described above (not just the examples shown) and returns a new function in which the following improvements are made, if they are possible:
Multiplication sub-expression
a. With a 0 as an argument, sub-expression is replaced by 0: (* 3 5 0) -> 0
b. With a 1 as an argument, the 1 is removed: (* 1 2 6) -> (* 2 6). If only one argument remains then the sub-expression is replaced by that argument: (* 1 6) -> 6
Addition sub-expression
a. Any occurrence of 0 is eliminated: (+ 0 2 7 7) -> (+ 2 7 7). If only one argument remains, the sub-expression is eliminated: (+ 0 7) -> 7
My group mates and I have written this so far :
(defun simplify (lis)
(cond
((null lis) '())
((eq (car lis) '*)
(cond
((not(null (member '0 lis))) 0)
((not(null (member '1 lis))) (simplify (remove '1 lis)))
(t (simplify (cdr lis)))
)
)
((eq (car lis) '+)
(cond
(t 0)
)
)
((listp (car lis)) (cons (simplify (car lis))(simplify (cdr lis))))
(t (cons (simplify (car lis)) (simplify (cdr lis))))
)
)
We cant get it to work Correctly if you have any suggestions! Thank you also you can ignore our + function that isn't finished.
It's always good to try to keep functions as simple and short as possible. So let's break up this task into multiple steps:
For both + and * there is an identity element, that you are supposed to remove from the operation (as it doesn't affect the result).
(defun remove-identity-elements (operands identity)
(flet ((is-identity (element)
(equal element identity)))
(let ((filtered-operands (remove-if #'is-identity operands)))
(or filtered-operands (list identity)))))
This function returns a list of operands with identity elements removed. Note that I added a check to avoid returning an empty list, so if the filtered-operands are an empty list (()) the or will evaluate its second argument, returning a list with the identity element as single member.
For an operation, if it's called with only a single operand, you're supposed to simplify that to only the single operand. That task is a good candidate for another function:
(defun compact-single-operand-operation (expression)
(let ((operands (rest expression)))
(if (rest operands)
expression
(first operands))))
Handling an operation can then be done by first removing any identity elements from the operands and then eventually removing the operation all together:
(defun simplify-operation (operator operands identity)
(compact-single-operand-operation
(cons operator (remove-identity-elements operands identity))))
With these functions ready at hand we can approach the simplify function. First of all, we need to cover its recursive nature:
In order to simplify an operation, you need to first simplify each of its operands, as they could be complex (simplify-able) operations, too.
(defun simplify (expression)
(if (listp expression)
(let ((operator (first expression))
(operands (mapcar #'simplify (rest expression))))
;; handle operations
)
expression))
I'm using mapcar with the currently being defined function simplify to get already simplified operands. To stop this recursion we need a base case: If the expression to simplify isn't a list, then we consider it as "self evaluating" and just return it unchanged (this is the "else" part of the if).
Handling the operations is done using the above function simplify-operation, though we need to add a special check to cope with a possible 0 in the operands of a multiplication:
(cond ((eq operator '+) (simplify-operation '+ operands 0))
((eq operator '*)
(if (find 0 operands)
0
(simplify-operation '* operands 1)))
(t (error "Unsupported operation")))
I also put together a live example to play with.

Compiler doesn't complain when cond doesn't have a else branch and the condition isn't satisfied

I have the following Racket code:
#lang racket
(define (for-each proc items)
(cond ((not (null? items))
(proc (car items))
(for-each proc (cdr items)))))
(for-each (lambda (x) (newline) (display x))
(list 57 321 88))
Because the condition isn't satisfied after 88 is printed, and the Racket's documentation says:
If none of the question-expressions evaluates to true, cond’s value is the answer-expression of the else clause. If there is no else, cond reports an error.
So the expected result is an error, however I get the correct output:
57
321
88
Can somebody tell me why? (ps: I'm using DrRacket 6.2)
Changing the indentation a little:
(define (for-each proc items)
(cond
[(not (null? items)) (proc (car items))
(for-each proc (cdr items))]))
A call (for-each f (list 1 2 3))
will call the function and bind proc to f and items to '(1 2 3).
The test (not (null? items)) is true, since '(1 2 3) is non-empty.
The right hand side is therefore evaluated. The right hand side does two things:
1.) (proc (car items)) calls f with the first element in the list (here 1) and then 2). calls (for-each proc (cdr items)). Here (cdr items) becomes '(2 3).
Eventually for-each will be called with (for-each f '()).
At that point (not (null? items)) will evaluate to #f and the cond will try the next clause. Since there are no more clauses cond will return void.
The documentation says:
If no cond-clauses are present, the result is #<void>.
Note: The cond in the teaching languages will return an error. The constructs in the teaching language generally reports errors, where there is a chance of shooting ones own foot.
I don't know where you got that information. To quote the spec:
The last test-expr in a cond can be replaced by else. In terms of evaluation, else serves as a synonym for #t, but it clarifies that the last clause is meant to catch all remaining cases. If else is not used, then it is possible that no test-exprs produce a true value; in that case, the result of the cond expression is #void.

how to overwrite (defun eval (expr)) function in LISP

I am new to LISP programming and it is the end of semester and our teacher asked us to do this project and I have been trying to make it but I am stuck so any help would be appreciated. the Project is to write an eval (expr) function in Lisp to overwrite the already existing function. here is the details:
Project Description: Items in an arithmetic expression separated by spaces;
; Input:
; 1. The form of arithmetic expression given in prefix notation like LISP
; Assumptions:
; 1. binary operations for +, -, *, and /
; 2. integer division, no reals
; 3. an arithmetic expression occupies only one line
; 4. nested arithmetic expressions permitted
; 5. all given inputs are syntax correct
; 6. no need for error handling
I wrote a code that can do eval of the simple arithmetic expressions and it works!! but I COULD NOT get it to work on nested arithmetic operations. I think I have an issue with the recursion part i am doing something wrong but what is it exactly idk :(
here is my code :
; Assign a character string to a global variable input-prompt
; treat input-prompt as a constant global variable
(setf input-prompt "Please input an arithmetic expression: ")
(setf output-prompt "The value is: ")
(defun prompt-for-input (msg)
(format t msg)
(format t "~%")) ; ~% new line
(defun prompt-for-output (msg)
(format t msg))
(defun output-msg (result)
(format t "~S" result) ; ~S takes the result into the print message
(format t "~%"))
(defun eval (expr)
(print "My EVAL Function is Working *_*")
(if (numberp expr) expr)
(cond
((eq (car expr) '+)
(if (and (numberp (cadr expr))
(numberp (caddr expr))) ;to check if we have simple expression
(+ (cadr expr) (caddr expr)) ;in case both are numbers we add normally
(if (not (numberp (cadr expr)))
;in case the second argument is not number
;we need to call eval again to check the expression
((eval (cadr exp)))
(if (not (numberp (caddr expr)))
;in case the third argument is not a number
;we need to call eval again to check the expression
((eval (caddr exp)))
(0)))))
((eq (car expr) '-)
(if (and (numberp (cadr expr))
(numberp (caddr expr))) ;to check if we have simple expression
(- (cadr expr) (caddr expr)) ;in case both are numbers we add normally
(if (not (numberp (cadr expr)))
;in case the second argument is not number
;we need to call eval again to check the expression
((eval (cadr exp)))
(if (not (numberp (caddr expr)))
;in case the third argument is not a number
;we need to call eval again to check the expression
((eval (caddr exp)))
(0)))))
((eq (car expr) '*)
(if (and (numberp (cadr expr))
(numberp (caddr expr))) ;to check if we have simple expression
(* (cadr expr) (caddr expr)) ;in case both are numbers we add normally
(if (not (numberp (cadr expr)))
;in case the second argument is not number
;we need to call eval again to check the expression
((eval (cadr exp)))
(if (not (numberp (caddr expr)))
;in case the third argument is not a number
;we need to call eval again to check the expression
((eval (caddr exp)))
(0)))))
((eq (car expr) '/)
(if (and (numberp (cadr expr))
(numberp (caddr expr))) ;to check if we have simple expression
(/ (cadr expr) (caddr expr)) ;in case both are numbers we add normally
(if (not (numberp (cadr expr)))
;in case the second argument is not number
;we need to call eval again to check the expression
((eval (cadr exp)))
(if (not (numberp (caddr expr)))
;in case the third argument is not a number
;we need to call eval again to check the expression
((eval (caddr exp)))
(0)))))))
; it should have eval(expr) function which returns the value of the
; arithmetic expression
; for instance,
; (+ 2 3) outputs 5
; (+ (* 3 2) (/ 4 2))) outputs 8
; (* (- 2 3) 5) outputs -5
; driver accepts the input arithmetic expression
; evaluate the arithmetic expression
; output the reulst of the evaluation of the arithmetic expression
; execution is in the loop; to exit the loop; type cntrl-c
(defun driver ()
(prompt-for-input input-prompt)
;to print "Please input an arithmetic expression
(let ((expression (read)))
(output-msg expression)
(let ((result (eval expression)))
(prompt-for-output output-prompt)
(output-msg result)))
(driver))
First of all, the basic call that does the trick is ... drum roll ... -
(apply (symbol-function (car expr)) (cdr expr))
this assuming - for a moment - that all the arguments in the expression are already numbers.
This one line replaces all four cases in your code which are all exact copies of one another, up to the operation to be performed.
Now, to make sure we have numbers, we just need to call same eval on each of them. If they were numbers, they will stay as is, and if not - they'll get evaluated.
Let's just call our new function calc, for "calculate", instead:
(defun calc (expr) ; our "eval"
(cond
((numberp expr) expr)
(T (call (car expr)
(mapcar #'calc (cdr expr))))))
(defun call (op args) ; our "apply"
(apply (symbol-function op)
args))
That's all. If you consider this cheating, you can call the operation by hand, but still you don't need to copy the same block of code four times for that. :)
If you indeed write the call yourself to call the operation by hand, do note that the default value for (*) is 1, not 0; and that there's no default value for (-) and (/) in Common Lisp (as tested in CLisp). Also, (/ 2) should return 1/2.
a few hints:
Expressions like (0) are not meaningful. 0 is not a function. Similar ((foo)) also makes no sense.
you should properly format and indent Lisp code. The editor helps.
Avoid functions like CAR, CDR, CADR, ... - use FIRST, REST, SECOND, ...
don't call the function EVAL. That's a built-in function in Common Lisp.

Lisp - Remove instances from a list of pairs

I want to create a function in lisp that receives a number and a list of pairs and iterates through the list of pairs and removes the ones in which the result of the division between the first element of the pair, and the second element of the same pair is different from the number passed as an argument. In the end it returns a list with only the ones in which the result of the division is the same.
I have the following code so far:
(defun retira-terco(num l1)
(cond ((null l1) ())
((not (equal num (/ (car(first l1)) (cdr(first l1)))))
(retira-terco num (rest l1)))
(t (cons (first l1) (retira-terco num (rest l1))))))
When I try to run this example with a real example I get the following error:
Error: `(1)' is not of the expected type `NUMBER'
What am I doing wrong?
The problem with your code is in this line:
(/ (car(first l1)) (cdr(first l1)))
(car (first l1)) evaluates to a number, but (cdr (first l1)) evaluates to a list. You probably meant (cadr (first l1)).
That said, this code isn't that great from a lispiness point of view. You have a condition you want to filter on. Use higher order programming to express that more like this:
(defun foo (num lst)
(remove-if (lambda (item)
(equal num
(/ (car item)
(cadr item))))
lst)))