Weird common lisp error (sbcl) - lisp

I am having a really wierd lisp error. I am using sbcl and have written the following code. I am just hoping someone could explain.
(setq x '((1 (x y) (1 2)) (3 (x z) (2 3)) (3 (x y) (1 2)) (4 (x y) (1 2))))
(caddadr x)
gives the following error message
; Evaluation aborted on #.
however writing it in the for gives me what I was expecting which is
(car (cddadr x))
(2 3)
just wondering why this is to be honest.

There is no such function as caddadr, that's why.
* (fboundp 'caddadr)
NIL
* (fboundp 'cddadr)
T
You have just CAR, CDR, CAAR, CADR, CDAR, CDDR, CAAAR, CAADR, CADAR, CADDR, CDAAR, CDADR, CDDAR, CDDDR, CAAAAR, CAAADR, CAADAR, CAADDR, CADAAR, CADADR, CADDAR, CADDDR, CDAAAR, CDAADR, CDADAR, CDADDR, CDDAAR, CDDADR, CDDDAR and CDDDDR. See: http://clhs.lisp.se/Body/f_car_c.htm

Related

Sort Polynomial based on Symbol and Exponent

I'm writing writing polynomial arithmetic in lisp, and currently working on addition. I need help sorting a polynomial by the exponent and symbol. My polynomials are represented as follows:
((3 ((1 x)(1 y))) (1 ((3 y)))) ; == 3xy + 1y^3
The function I need guidance with is given a term like
((5 ((3 x))) (3 ((3 y))) (4 ((2 z)))) ((6 ((3 x))) (1 ((3 y))) (9 ((2 z)))))
I would want:
((4 ((2 Z))) (9 ((2 Z))) (5 ((3 X))) (6 ((3 X))) (3 ((3 Y))) (1 ((3 Y))))
returned, so that all So all z^2 and z^2 are together.
Your initial example shows terms with two variables (e.g., 3xy), but your example later on doesn't. This solution won't handle the multiple variable term case (and you haven't said how you'd want grouping in that case anyhow), but it will handle your example.
First, define some abstractions for working with your polynomial terms, because they're rather inconvenient at the moment. Here are three functions that make it much easier to extract the coefficient, degree, and variable from each term:
(defun polynomial-term-coefficient (term)
(destructuring-bind (coefficient ((degree variable))) term
(declare (ignore degree variable))
coefficient))
(defun polynomial-term-degree (term)
(destructuring-bind (coefficient ((degree variable))) term
(declare (ignore coefficient variable))
degree))
(defun polynomial-term-variable (term)
(destructuring-bind (coefficient ((degree variable))) term
(declare (ignore coefficient degree))
variable))
Then, as I understand your question, you're actually starting with two polynomials 5x3 + 3y3 + 4z2 and 6x3 + y3 + 9z2. You'd add those together first, just by appending the list of their terms. Then you can sort that on the predicate string> (which takes string designators, so symbols are OK), with a key function of polynomial-term-variable. That is, you use the key function to extract the value that you actually want to sort by.
(let ((p1 '((5 ((3 x))) (3 ((3 y))) (4 ((2 z)))))
(p2 '((6 ((3 x))) (1 ((3 y))) (9 ((2 z))))))
(let ((unsimplified-sum (append p1 p2)))
(sort (copy-list unsimplified-sum) 'string> :key 'polynomial-term-variable)))
;=> ((4 ((2 Z))) (9 ((2 Z))) (3 ((3 Y))) (1 ((3 Y))) (5 ((3 X))) (6 ((3 X))))
You might want to have a search for "Horner's method", which is an old numerical method for computing the value of a polynomial in O(n) time, n being the number of terms. It looks from the outset that's close to what you want to do, or at least similar in representation.

What is the difference between let and let*, I dont understand this (Racket) [duplicate]

This question already has answers here:
Confused by the difference between let and let* in Scheme
(2 answers)
Closed 8 years ago.
(define x 2)
(let ((x 1) (y (+ x 1))) (+ x y))
you get 4;
(let* ((x 1) (y (+ x 1))) (+ x y))
you get 3.
I do not understand how the let thing works. Could someone please explain, i'm new to computer science thanks
(let ((x 0) (z x))
...)
Is equivalent to:
((lambda (x z) ...) 0 x)
Perhaps in the anonymous procedure call you can see that when the arguments are evaluated the variable inside the body does not exist yet, but inside the body x is 0 and the previous x is shadowed in the whole body but accesible as z.
(let* ((x 0) (z x))
...)
Which is equivalent to:
(let ((x 0))
(let ((z x))
...))
Looking at this you see right away that x gets set to 0 and shadows any other x at the time z gets bound.
Imagine you want to calculate the hypothenus og a triangle:
(let ((hypotenuse (sqrt (+ (square a) (square b)))))
...)
You want to split it up a little so you change it to a let* like this:
(let* ((sqa (square a))
(sqb (square b))
(hypotenuse (sqrt sqa sqb)))
...)
If you woudl have used let then sqa and sqb wuldn't be available!
The rule of thumb is to use let and change it to a let* when you need to reference something bound in the same let. Be careful to not shadow variables you are using later.

debugging macro - unbound variable when calling

Essentially I am trying to code up a macro which will print out exactly some statement I am trying to evaluate, and the value it evaluates to.
What I have so far is the following:
(defmacro dbg (statement)
(format t "~a: ~a" statement (eval statement)))
and by typing the following into the slime repl: (dbg (* 2 2)) I get the desired result which is:
"(* 2 2): 4"
However when I try to use it in the following function **:
(defun get-start-position (curr-prime)
(dbg (/ (- (* curr-prime curr-prime) 3) 2))
(/ (- (* curr-prime curr-prime) 3) 2))
slime reports that curr-prime is unbound (and just sticking everything in a let doesn't help). To be more specific the act of trying to compile the function get-start-position results in:
2 compiler notes:
primes.lisp:27:3:
error:
during macroexpansion of (DBG (- # 3)). Use *BREAK-ON-SIGNALS* to intercept:
The variable CURR-PRIME is unbound.
primes.lisp: 29:9:
note:
deleting unreachable code
==>
CURR-PRIME
Compilation failed.
Presumably (and the second warning baffles me), the error comes about because the macro is expanded before the function which calls it gets a chance to bind curr-prime to some value (am I correct here?). That said I have no clue how to get round this issue
What am I doing wrong?
** for what its worth I am coding up a prime sieve where the indicator array has the following elements:
(3,5,7,9, ...)
This particular function will get me the index of the square of a given prime
Not a pro on Lisp macros, but this will do:
(defmacro dbg (statement)
(let ((result (gensym)))
`(let ((,result ,statement))
(format t "~a: ~a" ',statement ,result)
,result)))
then
(dbg (* 2 2))
=> (* 2 2): 4
4
and
(defun get-start-position (curr-prime)
(dbg (/ (- (* curr-prime curr-prime) 3) 2)))
(get-start-position 1)
=> (/ (- (* CURR-PRIME CURR-PRIME) 3) 2): -1
-1

Why does this expression not work as expected in Common Lisp?

A newcomer to Lisp. I know that
(mapcar #'list '(1 2) '(3 4))
will give
'((1 3) (2 4))
and based on my understanding of how apply works, I expect
(apply #'(lambda (&rest x) (mapcar #'list x)) '((1 2) (3 4)))
to return the same result. Instead, I am getting
'(((1 2)) ((3 4)))
I am confused because
(apply #'append '((1 2) (3 4)))
gives me
'(1 2 3 4)
as expected. What is going on?
Simplify it. Suppose you used A instead of (1 2), and B instead of (3 4):
(apply #'(lambda (&rest x) (mapcar #'list x)) '(A B))
Because &rest x takes all the arguments and packs them up as a list, so x has the value
(A B).
Then mapcar iterates twice, passing A to list, producing (A), then it does the same with B. Then mapcar makes a list of those, producing ( (A) (B) )
It's useful to put print statements in there to see what's going on.

More generic lisp code to generate combinations of pairs

Given this sad thing below, which generates all pairs of only two ranges -
[53]> (setq thingie '())
NIL
[54]> (loop for i in (generate-range 0 3) do
(loop for j in (generate-range 4 6) do
(push (list i j) thingie)))
NIL
[55]> thingie
((3 6) (3 5) (3 4) (2 6) (2 5) (2 4) (1 6) (1 5) (1 4) (0 6) (0 5) (0 4))
[56]>
Or, put another way, this generates sort of a two-dimensional discrete layout.
How would I go about building some sort of pairs-generating code that took arbitrary numbers of ranges? (Or generating an n-dimensional discrete layout).
Obviously one solution would be to have a defmacro that took a list-of-lists and built n loops for execution, but that doesn't feel a straightforward way to go.
(defun map-cartesian (fn bags)
(labels ((gn (x y)
(if y (mapc (lambda (i) (gn (cons i x) (cdr y))) (car y))
(funcall fn x))))
(gn nil (reverse bags))))
CL-USER> (map-cartesian #'print '((1 2) (a b c) (x y)))
(1 A X)
(2 A X)
(1 B X)
(2 B X)
(1 C X)
(2 C X)
(1 A Y)
(2 A Y)
(1 B Y)
(2 B Y)
(1 C Y)
(2 C Y)
If you prefer syntax sugar,
(defmacro do-cartesian ((item bags) &body body)
`(map-cartesian (lambda (,item) ,#body) ,bags))
CL-USER> (do-cartesian (x '((1 2) (a b c) (x y)))
(print x))
Edit: (brief explanation)
The first parameter of gn, x, is the partial tuple constructed so far; y is the remaining bags of elements. The function gn extends the partial tuple by iterating over each element i of one of the remaining bags, (car y), to form (cons i x). When there's no remaining bags (the else branch of the if statement), the tuple is completed, so we invoke the supplied function fn on the tuple.
The obvious thing for me would be a recursive function.
If you're thinking of this as a control structure, the macro route is the way to go. If you're thinking of this as a way of generating data, a recursive function is the way to go.
You don't need explicit recursion (or even a macro), this can also be done with a higher-order function:
(defun tuples-from-ranges (range &rest ranges)
(reduce (lambda (acc range)
(mapcan (lambda (sublist)
(mapcar (lambda (elt)
(append sublist (list elt)))
(apply #'generate-range range)))
acc))
ranges
:initial-value (mapcar #'list (apply #'generate-range range))))
The two nested inner higher-order functions (mapcan and mapcar) perform the same function that the two nested loops in your example did. The outer higher-order function reduce will then first combine the values of the first two ranges to pairs, and after that in each invocation of its argument function apply the some process again to the intermediate results from the preceding invocation and the next range.