getting undefined reference to a function in commonLISP - list

I'm trying to compile the following code:
(defun nextStates (st)
"generate all possible states"
(setf N 0)
(setf states-list (make-list 9))
(setf list-actions (possible-actions))
(loop for x in list-actions do
(setf aux (nextState st x))
(when (not(member aux (states-list) :test #'equalp))
(progn
(setf (nth N states-list) aux)
(setf N (+ N 1))
)
)
)
(values states-list)
)
nextState is a function and states-list is a list, both of which are defined. I'm getting "undefined reference to states-list".
I don't know what I'm doing wrong.
Any help will be greatly appreciated

Renaming the badly camel case to lisp case I'm left with this.
(defun next-states (st)
"generate all possible states"
(loop :for action :in (possible-actions)
:for aux := (next-state st action) :then (next-state st action)
:when (not (member aux states-list :test #'equalp))
:collect aux :into states-list
:finally (return states-list)))
As a test here is what I had:
(defun possible-actions ()
"have duplicates to see not member in action"
'(0 1 3 3 4))
(defun next-state (st action)
"Simple version for test"
(+ st action))
(next-states 3) ; ==> (3 4 6 7)

Related

DrRacket Using accumulator as List-ref index

I am trying to write a function that take a list and iterates over each element in the list if the number is even I want that number to be added to the previous number in the list.
I was thinking an accumulator will count up from 0 with each iteration giving a position for each element in the list.
If the number in the list is even I want to add that number to the previous number in the list.
Hence why I am trying to use the accumulator as an index for list-ref. I don't know how to write it to get the accumulator value for the previous iteration (+ i (list-ref a-list(- acc 1)))?
(define loopl (lambda (l)
(for/fold
([acc 0])([i l])
(cond
[(even? i)(+ i (list-ref (- acc 1) l))]
enter image description here
The question is not quite clear about the value to be returned by this function:
this answer assumes that it is a total of even elements together with their previous elements.
The function is developed using the
HtDF (How to Design Functions)
design method with a BSL (Beginning Student language) in DrRacket.
Start with a stub, incorporating signature and purpose, and a minimal "check-expect" example:
(Note: layout differs slightly from HtDF conventions)
(define (sum-evens-with-prev xs) ;; (Listof Integer) -> Integer ; *stub define* ;; *signature*
;; produce total of each even x with its previous element ; *purpose statement*
0) ; *stub body* (a valid result)
(check-expect (sum-evens-with-prev '()) 0) ; *minimal example*
This can be run in DrRacket:
Welcome to DrRacket, version 8.4 [cs].
Language: Beginning Student with List Abbreviations
The test passed!
>
The next steps in HtDF are template and inventory. For a function with one list
argument the "natural recursion" list template is likely to be appropriate;
(define (fn xs) ;; (Listof X) -> Y ; *template*
(cond ;
[(empty? xs) ... ] #|base case|# ;; Y ;
[else (... #|something|# ;; X Y -> Y ;
(first xs) (fn (rest xs))) ])) ;
With this template the function and the next tests become:
(define (sum-evens-with-prev xs) ;; (Listof Number) -> Number
;; produce total of each even x with its previous element (prev of first is 0)
(cond
[(empty? xs) 0 ] #|base case: from minimal example|#
[else (error "with arguments: " #|something: ?|#
(first xs) (sum-evens-with-prev (rest xs))) ]))
(check-expect (sum-evens-with-prev '(1)) 0)
(check-expect (sum-evens-with-prev '(2)) 2)
These tests fail, but the error messages and purpose statement suggest what is required:
the (... #|something|# from the template has to choose whether to add (first xs):
(define (sum-evens-with-prev xs) ;; (Listof Integer) -> Integer
;; produce total of each even x with its previous element (prev of first is 0)
(cond
[(empty? xs) 0 ]
[else
(if (even? (first xs))
(+ (first xs) (sum-evens-with-prev (rest xs)))
(sum-evens-with-prev (rest xs))) ]))
Now all 3 tests pass! Time for more check-expects (note: careful introduction of
check-expects is a way of clarifying ones understanding of the requirements, and
points one to the code to be added):
(check-expect (sum-evens-with-prev '(1 1)) 0)
(check-expect (sum-evens-with-prev '(1 2)) 3)
Ran 5 tests.
1 of the 5 tests failed.
Check failures:
Actual value 2 differs from 3, the expected value.
sum-evens-with-prev needs the prev value to include in the even? case:
make it available by introducing it as an argument (renaming the function), add
the appropriate arguments to the recursive calls, the function now just calls
sum-evens-and-prev:
(define (sum-evens-and-prev xs prev) ;; (Listof Integer) Integer -> Integer
;; produce total of each even x and prev
(cond
[(empty? xs) 0 ]
[else
(if (even? (first xs))
(+ prev (first xs) (sum-evens-and-prev (rest xs) (first xs)))
(sum-evens-and-prev (rest xs) (first xs))) ]))
(define (sum-evens-with-prev xs) ;; (Listof Integer) -> Integer
;; produce total of each even x with its previous element (prev of first is 0)
(sum-evens-and-prev xs 0))
(just add some more tests, and all is well :)
(check-expect (sum-evens-with-prev '(0 2)) 2)
(check-expect (sum-evens-with-prev '(2 1)) 2)
(check-expect (sum-evens-with-prev '(1 3)) 0)
(check-expect (sum-evens-with-prev '(2 2)) 6)
(check-expect (sum-evens-with-prev '(1 2 3 4)) 10)
(check-expect (sum-evens-with-prev '(1 2 3 3 5 6 6)) 26)
Welcome to DrRacket, version 8.4 [cs].
Language: Beginning Student with List Abbreviations.
All 11 tests passed!
>
The (for/fold) form requires a (values) clause, and it is in that which you would put the conditional form.
Assuming you want only the new list as the return value, you would also want a #:result clause following the iteration variables.
(define loopl
(lambda (l)
(for/fold
([index 0]
[acc '()]
#:result acc)
([i l])
(values [+ index 1]
[append acc
(if (and (> index 0)
(even? i))
(list (+ i (list-ref l (- index 1))))
(list i))]))))
This should give the correct answer.
You almost never want to repeatedly call list-ref in a loop: that makes for horrible performance. Remember that (list-ref l i) takes time proportional to i: in your case you're going to be calling list-ref with the index being, potentially 0, 1, ..., and that going to result in quadratic performance, which is bad.
Instead there's a neat trick if you want to iterate over elements of a list offset by a fixed amount (here 1): iterate over two lists: the list itself and its tail.
In addition you need to check that the first element of the list is not even (because there is no previous element in that case, so this is an error).
Finally I'm not entirely sure what you wanted to return from the function: I'm assuming it's the sum.
(define (accum-even-previouses l)
(unless (not (even? (first l)))
;; if the first elt is even this is an error
(error 'accum-even-previouses "even first elt"))
(for/fold ([accum 0])
([this (in-list (rest l))]
[previous (in-list l)])
(+ accum (if (even? this)
(+ this previous)
0))))

how to make a recursive racket list that, from the input list, outputs its decreasing to 1 for every element in the list (e.g. ('3 2) outputs ('32121)

****What I tried****
(define(help num)
(if(= num 1)
num
(cons(num (help( - num 1))))))
;i called this defination in the bottom one
(define (list-expand L)
(cond
[(empty? L)'()]
[(=(car L)1)(cons(car L)(list-expand (cdr L)))]
[(>(car L)1) (cons(help(car L)(list-expand(cdr L))))]))
In the help procedure, the base case is incorrect - if the output is a list then you must return a list. And in the recursive step, num is not a procedure, so it must not be surrounded by brackets:
(define (help num)
(if (<= num 0)
'()
(cons num (help (- num 1)))))
And in list-expand, both recursive steps are incorrect. You just need to test whether the list is empty or not, calling help with the correct number of parameters; use append to combine the results, because we're concatenating sublists together:
(define (list-expand L)
(if (empty? L)
'()
(append (help (car L)) (list-expand (cdr L)))))
That should work as expected, but please spend some time studying Scheme's syntax, you still have trouble with the basics, for instance, when and where to use brackets...
(list-expand '(3 2))
=> '(3 2 1 2 1)
Just for fun - a non-recursive solution in Racket:
(append-map (lambda (n) (stream->list (in-range n 0 -1))) '(3 2))
;; or:
(append-map (lambda (n) (for/list ((x (in-range n 0 -1))) x)) '(3 2))
Returning:
'(3 2 1 2 1)

Shoelace formula in racket

I am having problems in finding a way to recursively calculate the area.
(check-expect(signed-area(list (make-posn 1 2)(make-posn 3 4)(make-posn 5 6)(make-posn 1 6)))8)
(check-expect(signed-area(list (make-posn 1 2)(make-posn 11 3)(make-posn 12 9)(make-posn 2 10)))70)
(define (signed-area lop)
(cond
[(< 3 (length lop)) 0]
[else
(abs (/ (+(-(* (posn-x (first lop)) (posn-y (second lop)))
(* (posn-x(second lop)) (posn-y(first lop))))
(-(* (posn-x (second lop)) (posn-y (third lop)))
(* (posn-x(third lop)) (posn-y(second lop))))
(-(* (posn-x (third lop)) (posn-y (fourth lop)))
(* (posn-x(fourth lop)) (posn-y(third lop))))
(-(* (posn-x (fourth lop)) (posn-y (first lop)))
(* (posn-x(first lop)) (posn-y(fourth lop)))))
2))]))
I am out of ideas on how to recursively go through the list, and remove the first posn after it went through the list. Since the code I have is limited to 4 points and I have to make this to be at least 3 points
Solution I - direct recursion
However, the problem is the absolute function at the end over the entire formula.
For this to be executed at the very final on the entire sum, you have to put your function into the outer function and apply abs on the function-call:
(define (signed-area plist)
(define (.signed-area plist)
(cond ((< (length plist) 3) 0)
(else (+
(/ (- (* (first plist) (fourth plist))
(* (second plist) (third plist)))
2)
(.signed-area (cddr plist))))))
(abs (.signed-area plist))) ;; final absolute
Instead of dividing by to for every summand, you can do it also at the
very end on the entire absolute sum. So, very very minimally more efficient - but in the praxis totally negligible improvement.
(define (signed-area plist)
(define (.signed-area plist)
(cond ((< (length plist) 3) 0)
(else (+
(- (* (first plist) (fourth plist))
(* (second plist) (third plist)))
(.signed-area (cddr plist))))))
(* (/ 1 2) (abs (.signed-area plist))))
Solution II - tail-call recursion
This is a technique which is memory saving and avoids nesting of recursive calls for the interpreter. So generally regarded as best practice.
In addition, you can more clearly see what happens between the steps - because
you have just to concentrate on acc and what is done on it at each recursion step - then you understand the formula/procedure undertaken on the results of each single step. Because of these two reasons, tail-call recursion is the preferred method for lisp-programmers to formulate recursive functions.
(define (signed-area plist)
(define (.signed-area plist acc) ; introduce accumulator
(cond ((< (length plist) 3) (* (/ 1 2) (abs acc)))
(else (.signed-area (cddr plist) ; in next round remove first pair
(+ (- (* (first plist) (fourth plist))
(* (second plist) (third plist)))
acc))))) ; add shoelace product to accumulator
(.signed-area plist 0)) ; call inner recursive function with accumulator start value 0
;
Test
All three function definitions give the correct result 2:
(signed-area (list 1 2 3 4 5 6))
;; => 2
For checking/testing, calculate by hand the example:
;; to check, calculate shoelace by hand:
;; visualize:
;; 1 2
;; 3 4
;; 5 6
;
;; and then calculate:
(* (/ 1 2)
(abs (+ (- (* 1 4)
(* 2 3))
(- (* 3 6)
(* 4 5)))))
;; => 2
For list-of-posn
(define (signed-area list-of-posn)
(define (.signed-area list-of-posn acc) ; introduce accumulator
(cond ((< (length list-of-posn) 2) (* (/ 1 2) (abs acc)))
(else (.signed-area (cdr list-of-posn) ; in next round remove first posn
(+ (- (* (posn-x (first list-of-posn)) (posn-y (second list-of-posn)))
(* (posn-x (second list-of-posn)) (posn-y (first list-of-posn))))
acc))))) ; add shoelace product to accumulator
(.signed-area list-of-posn 0)) ; call inner recursive function with accumulator start value 0

Elisp: how to find list duplicates

I am using this to find list duplicates:
(defun have-dups (x)
(let ((dups (copy-tree x)))
(if (eq (length (delete-dups dups)) (length x))
nil
t)))
(have-dups (list 1 2 3 3)) ;=> t
(have-dups (list 1 2 3)) ;=> nil
Considering the overhead of copy-tree and delete-dups, probably there is a better way.
Use a hash table, as soon as you find an element which already exists in the hash table, you know you have duplicates:
(defun has-dup (list)
(block nil
(let ((hash (make-hash-table :test 'eql)))
(map ()
(lambda (item)
(if (gethash item hash)
(return t)
(setf (gethash item hash) t)))
list))))
Here is a shorter version of your answer, which uses remove-duplicates instead of delete-dups, to avoid the destructive properties of the latter:
(defun has-dups-p (LIST) ""
(let ((unique1 (remove-duplicates LIST :test #'equal)))
(if (eq LIST unique1)
nil
t)))
(has-dups '(1 2 3 2 1)) ; t
(has-dups '("a" "b" "c")) ; nil
I find this reasonably easy to read and eq should be reasonably efficient as it goes straight to C, particularly where a duplicate occurs early in the list. Both remove-duplicates and delete-dups are passed to cl--delete-duplicates which is rather involved...
A longer solution follows, which returns the elements of LIST which have duplicates and the position of each duplicated element in LIST (remembering that seqs are zero-indexed in elisp). Note that this currently only applies where the elements of LIST are strings, although I'm sure it could be extended further to more general cases:
(defun list-duplicates (LIST) "
Returns `nil' when LIST has no duplicates.
Otherise, returns a `list' of `cons's.
In each list element:
- the `car' is the element of LIST which has duplicates.
- the `cdr' is a list of the positions where the duplicates are found."
(interactive)
;; res1 = result
;; unique1 = LIST with duplicates removed
(let ((unique1 (remove-duplicates LIST :test #'string-equal))
(res1 '()))
(if (eq LIST unique1)
nil
(progn
(dolist (x unique1)
;; i = incrementor
;; pos1 = list of postions of duplicates
(let (y (i 0) (pos1 '()))
(while (member x LIST)
(set 'y (seq-position LIST x))
(when (> i 0)
(push y pos1))
(set 'i (+ 1 i))
(set 'LIST
(substitute (concat x "1") x LIST :test #'string-equal :count 1)))
(push (cons x (nreverse pos1)) res1)))
(nreverse res1)))))
e.g.
(list-duplicates '("a" "b" "c")) ; nil
(list-duplicates '("a" "b" "b" "a" "b" "c" "c")) ; (("a" 3) ("b" 2 4) ("c" 6))

How to make a list of pairs in lisp?

I'm trying to do a list of pairs as a part of a homework assignment.
I tried doing (somewhere in the middle of a function)
(setq list1 (append list1 (cons n1 n2)))
And for some reason I don't understand, this works fine with the first pair, but as I try to append the second pair, this error pops up:
*** - APPEND: A proper list must not end with 2
How can I solve this?
So, continuing on this subject, thanks to the answer given, I was able to correct my problem. But a new one came up, and I think it is related with it. So, I have this function:
(defun action(state)
(let ((list_actions '())
(limNumActions (1- (list-length state)))
(limNumSubActions 0)
(numActions 0)
(numSubActions 0))
(loop for numActions from 0 to limNumActions do
(setq limNumSubActions (1- (list-length (nth numActions state))))
(loop for numSubActions from 0 to limNumSubActions do
(setq list_actions (append list_actions
(list (cons numActions numSubActions))))
(print 'list_actions)
(print list_actions)))))
I used the printfunction as a simple "debugger". It returns this:
LIST_ACTIONS
((0 . 0))
LIST_ACTIONS
((0 . 0) (0 . 1))
LIST_ACTIONS
((0 . 0) (0 . 1) (1 . 0))
LIST_ACTIONS
((0 . 0) (0 . 1) (1 . 0) (1 . 1))
NIL
And this is exactly the result I was expecting! Except for the NIL part... Can you understand why the list list_actions is NILat the end?
The code can be expressed more succintly as follows:
(defun action (state)
(let ((list-actions '()))
(loop for i from 0 for state-i in state do
(loop for j from 0 below (length state-i) do
(setf list-actions (append list-actions (list (cons i j))))
(print 'list-actions)
(print list-actions)))
list-actions))
If only the result is needed, it can be shorter (and less costly, because it doesn't use the expensive append function),
(defun action (state)
(loop for i from 0 for state-i in state append
(loop for j below (length state-i) collect (cons i j))))
append takes two lists, not a list and a single element. You need to put a list around the pair before using it in append.
Currently the pair is being taken as part of the list, which makes the list improper and causes the second append to fail since improper lists don't exactly have an end to append to.
I have tried to refine your example a bit + write a version which uses a different, but, IMO more idiomatic approach to the problem:
;; Your original version, but cleaned up a bit
(defun action (state)
(loop with list-actions = nil
with lim-num-actions = (1- (list-length state))
with lim-num-sub-actions = 0
for num-actions from 0 to lim-num-actions
do (setq lim-num-sub-actions (1- (list-length (nth num-actions state))))
(loop for num-sub-actions from 0 to lim-num-sub-actions
do (push (cons num-actions num-sub-actions) list-actions)
(format t "~&~s ~s" 'list-actions list-actions))
finally (return list-actions)))
;; A more traditional approach (if you want to use iteration)
(defun action (state)
(reverse
(loop for i in state
for j from 0
collect (cons j 0))))
;; Using a nice library to do iteration
(ql:quickload "iterate")
;; Note, you could do (in-package :iterate)
;; to lose `iterate:' prefix to make it even shorter
(defun action (state)
(iterate:iter
(iterate:for i #:on state)
(iterate:for j #:from 0)
(iterate:accumulate (cons j 0) #:by #'cons)))
;; Just another way to do this, using `reduce'
(reduce #'(lambda (a b)
(declare (ignore b))
(cons (cons (1+ (caar a)) 0) a))
(cdr (mapcar #'list '(1 2 3 4 5)))
:initial-value '((0 . 0)))
(action (mapcar #'list '(1 2 3 4 5)))