What is the problem here? I was trying to increment value but it's giving output as 0 - lisp

Been at this for hours, I'm new to LISP and could not figure out what is wrong with this. I'm trying to solve a matrix problem using backtracking. Can someone help?
(defvar m 3)
(defvar n 4)
(defvar M-DASH (make-array (list m n)
:initial-contents '((1 0 1 0) (0 1 1 0) (1 0 1 1))))
(defvar selected (make-array n))
(defvar set-count 0)
(defun cand-set-count (M-DASH set-count selected curr)
(if (>= curr m)
(progn
(incf set-count)
(return-from cand-set-count 0)
))
(loop for i from 0 to (- n 1)
do (if (and (equal (aref M-DASH curr i) 1) (null (aref selected i)))
(progn
(setf (aref selected i) 1)
(cand-set-count M-DASH set-count selected (+ curr 1))
(setf (aref selected i) nil)
))))
(cand-set-count M-DASH set-count selected 0)
(format t "~A" set-count)

Before answering the actual question, a few notes on style and general remarks:
Special variables (i.e. introduced by defvar or defparameter) are usually named with a name starting and ending with * (for example, (defvar *m* 4)
Unless you did some very weird modifications, the reader won't be case sensitive. This means that M-DASH and m-dash are the same symbol. For this reason, we tend not to use any form of capitalization, as it might induce some mistakes (e.g. believing that two symbols are different while they are in fact identical ...).
If you use a if but only care about the then or the else part, use when/unless instead. It makes intent clearer, and also comes with what is known as an "implicit progn":
(if some-test
(progn
(do-smtg)
(do-smtg-else)))
is identical to
(when some-test
(do-smtg)
(do-smtg-else))
If you are only looping from 0 to some number, and not doing very complex things (or, if you are a beginner, and don't want to deal with the specific syntax rules of the loop macro ...), use dotimes instead. It is more readable, less confusing, and in general less prone to mistake.
With that in mind, your main function can be rewritten as:
(defun cand-set-count (m-dash set-count selected curr)
(when (>= curr m)
(incf set-count)
(return-from cand-set-count 0))
(dotimes (i n)
(when (and (equal (aref m-dash curr i) 1)
(null (aref selected i)))
(setf (aref selected i) 1)
(cand-set-count m-dash set-count selected (+ curr 1))
(setf (aref selected i) nil))))
which is definitely clearer.
And now, the actual problem: the line (incf set-count) does not do what you think it does. It does not increase the value of the special variable named set-count ... and that would be clear, had you followed the convention of naming special variables with * around their name (I am not being sarcastic here: it is (one of ...) the reason conventions exist). What gets incremented is the local binding, not the value of the special variable. You can try it with a simpler code:
* (defvar *foo* 0)
0
* (defun bar (foo)
(incf foo))
BAR
* (bar *foo*)
1
* *foo*
0
Said differently: you have a special (and so, in some sense, global) variable named set-count, but your function also takes an argument, named set-count ! Do you want to go pure functional & side-effect-free, or do you want to mutate state and pass global references around ? Either is fine, but you need to stick to it.
The same is true for the other arguments, m-dash and selected, that are both "shadowed" inside the function body, and never actually modified.
Another mistake that might bite you later on: arrays are not initialized by default. You cannot suppose that (defvar selected (make-array n)) initializes anything to 0 or to nil; your function later tests if (null (aref selected i)), but if you do not explicitly initialize selected with :initial-contents/:initial-element, the result is undefined.

Related

Questions about replacing while and if statements with lisp

I want to change the code below to Lisp code, but I keep getting errors in grammar. How do I fix the if statement?
int promising(int i)
{
int k = 1;
while (k < i)
{
if (col[i] == col[k] || abs(col[i] - col[k]) == abs(i - k))
return 0;
k++;
}
return 1;
}
Below is the one I changed to the Lisp code.
(setq col (list 0 0 0 0))
(DEFUN promising (i)
(let ((k 1)) ; k =1
(loop while (< k i)
do((if (or ( = (nth i col) (nth k col))
(= ( abs((setq a (- (nth i col) (nth k col)))))
( abs((setq b (- i k ))))))
(return-from promising 0)))
do (setq k (1+ k)))
(return-from promising 1))
)
It is difficult for me to flexibly change the complicated condition of the if statement to the lisp code.
You are doing "C-in-Lisp". Trying to directly translate C (or for that matter, C++/Java/C#/Python ...) programs into Lisp will often lead to poor code, and you should be better off trying to understand how those problems are sovled in Lisp.
That being said:
You should not use (setq col <whatever>) at the toplevel. Global variables are introduced using defvar or defparameter and their name is of the form *variable-name* to distinguish them from other variables. This is because they have different scoping rules, and behave differently (i.e. they are not equivalent to other languages' global variables). In particular, using setq with a variable that has not been declared with defvar or defparameter is undefined behaviour, and most implementations will allow it, but they will then create this global variable. You generally don't want that. To sum up: either use (defvar *col* (list 0 0 ...)) if you need this really is a global variable, or simply use (let ((col (list 0 ...))) <more-code>) where you need it.
loop is a complicated construct. This is, in itself, another mini-language that you have to learn on top of Lisp. In particular, if all you ever want to do is "loop with some variable between some bounds and increment it by some value at each step", use
(loop for k from 1 do ...) ;; this introduces a local variable k, incremented by 1 at each step, with no upper bound
(loop for k from 1 to 10 do ...) ;; same, but only loop until k reaches 10
(loop for k from 1 to 10 by 3 do ...) same, but increments k by 3 at each step
Other constructs are available. Read this section of Practical Common Lisp for a good introduction, and the relevant CLHS section for a technical description and documentation.
Please follow conventions for whitespace this makes it much easier to read. For example, never place a parenthesis alone on its line (e.g. your very last parenthesis), and ( abs((setq b (- i k )))) should really be written (abs ((setq b (- i k)))) (ignoring the fact that this is incorrect, see below ...). As far as style is concerned, you also need to fix the indentation, and don't write DEFUN is uppercase, it is unnecessary and looks weird.
You cannot place extra parenthensis just to group things together, parenthesis have semantic meaning. In particular, in most cases, calling a function or using pretty much any special operator is done by (<operator-name> <first-arg> <second-arg> ... ). You almost never have 2 consecutive opening parenthesis.
Why are you using (setq a ...) and (setq b ...) in your loop ? Neither a nor b is ever declared or used anywhere else.
If you want to access specific elements of a list, don't use a list, use a vector. In particular, several calls to the nth function is often the sign that you really should have been using a vector.
A correct version of your code, using a few loop facilities, and still assuming that col is a list (which is should not be) although there would be other loop constructs making this even clearer ...
(defun promising (i)
(loop for k from 1 below i
for col-k = (nth k col)
do (when (or (= (nth i col) (nth k col))
(= (abs (- (nth i col) (nth k col)))
(abs (- i k))))
(return-from promising 0)))
1)
Note that this code is incredibly inefficient and this is why I suggested not to translate directly from C to Lisp. In particular, although you traverse a list (you access the k-th element at the k-th step), your code calls nth at each step instead of traversing the list ! You also compute (nth i col) at each step, which is already useless in C (it is constant so doesn't need to be recomputed at every step), but is catastrophic here. This should really be:
(defun promising (i)
(let ((col-i (nth i col)))
(loop for k from 1 below i
for col-k in (cdr col) ;; you start from the index 1, not 0
do (when (or (= col-i col-k)
(= (abs (- col-i col-k))
(abs (- i k))))
(return-from promising 0))))
1)
There are several mistakes in the code.
Incorrect function calls
(DEFUN promising (i)
(let ((k 1)) ; k =1
(loop while (< k i)
do((if (or ( = (nth i col) (nth k col))
;; ^^
;; Incorrect
)
And also here:
(setq col (list 0 0 0 0))
(DEFUN promising (i)
(let ((k 1)) ; k =1
(loop while (< k i)
do((if (or ( = (nth i col) (nth k col))
(= ( abs((setq a (- (nth i col) (nth k col)))))
;; ^^
;; Incorrect
( abs((setq b (- i k ))))))
;; ^^
;; Incorrect
(return-from promising 0)))
do (setq k (1+ k)))
(return-from promising 1))
)
The loop macro have 2 do keywords
(setq col (list 0 0 0 0))
(DEFUN promising (i)
(let ((k 1)) ; k =1
(loop while (< k i)
do((if (or ( = (nth i col) (nth k col))
;; ^^
;; First do
(= ( abs((setq a (- (nth i col) (nth k col)))))
( abs((setq b (- i k ))))))
(return-from promising 0)))
do (setq k (1+ k)))
;; ^^
;; Second do
(return-from promising 1))
)
return-from is used several times
return-from is usually not present in Common Lisp code, this is pretty much like C goto, something developers try to avoid.
Incoherent setq defining a and b (probably old code)
(setq col (list 0 0 0 0))
(DEFUN promising (i)
(let ((k 1)) ; k =1
(loop while (< k i)
do((if (or ( = (nth i col) (nth k col))
(= ( abs((setq a (- (nth i col) (nth k col)))))\
;; ^^^^^^
;; ??
( abs((setq b (- i k ))))))
;; ^^^^^^
;; ??
Weird incrementation scheme
(setq k (1+ k))
While being correct, Common Lisp programmers will simply use the increment function:
(incf k)
Final code
The code you might looking for should be close to that one:
(defun promising (i)
(let ((k 1))
(loop while (< k i) do
(if (or (= (nth i col) (nth k col))
(= (abs (- (nth i col) (nth k col)))
(abs (- i k ))))
(return-from promising 0))
(incf k))
;; return value
k))
Please note that the code is not equivalent to the C version, because the data structure is completely different. In the C version, the access to the data will be very fast O(1). The Common Lisp version will be slow if you have a large number of elements O(n). You can be fast with Common Lisp if you replace your list by an array/vector.

Implementing an infinite list of consecutive integers in Lisp for lazy evaluation

Prelude
In Raku there's a notion called infinite list AKA lazy list which is defined and used like:
my #inf = (1,2,3 ... Inf);
for #inf { say $_;
exit if $_ == 7 }
# => OUTPUT
1
2
3
4
5
6
7
I'd like to implement this sort of thing in Common Lisp, specifically an infinite list of consecutive integers like:
(defun inf (n)
("the implementation"))
such that
(inf 5)
=> (5 6 7 8 9 10 .... infinity)
;; hypothetical output just for the demo purposes. It won't be used in reality
Then I'll use it for lazy evaluation like this:
(defun try () ;; catch and dolist
(catch 'foo ;; are just for demo purposes
(dolist (n (inf 1) 'done)
(format t "~A~%" n)
(when (= n 7)
(throw 'foo x)))))
CL-USER> (try)
1
2
3
4
5
6
7
; Evaluation aborted.
How can I implement such an infinite list in CL in the most practical way?
A good pedagogical approach to this is to define things which are sometimes called 'streams'. The single best introduction to doing this that I know of is in Structure and Interpretation of Computer Programs. Streams are introduced in section 3.5, but don't just read that: read the book, seriously: it is a book everyone interested in programming should read.
SICP uses Scheme, and this sort of thing is more natural in Scheme. But it can be done in CL reasonably easily. What I've written below is rather 'Schemy' CL: in particular I just assume tail calls are optimised. That's not a safe assumption in CL, but it's good enough to see how you can build these concepts into a language which does not already have them, if your language is competent.
First of all we need a construct which supports lazy evaluation: we need to be able to 'delay' something to create a 'promise' which will be evaluated only when it needs to be. Well, what functions do is evaluate their body only when they are asked to, so we'll use them:
(defmacro delay (form)
(let ((stashn (make-symbol "STASH"))
(forcedn (make-symbol "FORCED")))
`(let ((,stashn nil)
(,forcedn nil))
(lambda ()
(if ,forcedn
,stashn
(setf ,forcedn t
,stashn ,form))))))
(defun force (thing)
(funcall thing))
delay is mildly fiddly, it wants to make sure that a promise is forced only once, and it also wants to make sure that the form being delayed doesn't get infected by the state it uses to do that. You can trace the expansion of delay to see what it makes:
(delay (print 1))
-> (let ((#:stash nil) (#:forced nil))
(lambda ()
(if #:forced #:stash (setf #:forced t #:stash (print 1)))))
This is fine.
So now, we'll invent streams: streams are like conses (they are conses!) but their cdrs are delayed:
(defmacro cons-stream (car cdr)
`(cons ,car (delay ,cdr)))
(defun stream-car (s)
(car s))
(defun stream-cdr (s)
(force (cdr s)))
OK, let's write a function to get the nth element of a stream:
(defun stream-nth (n s)
(cond ((null s)
nil)
((= n 0) (stream-car s))
(t
(stream-nth (1- n) (stream-cdr s)))))
And we can test this:
> (stream-nth 2
(cons-stream 0 (cons-stream 1 (cons-stream 2 nil))))
2
And now we can write a function to enumerate an interval in the naturals, which by default will be an half-infinite interval:
(defun stream-enumerate-interval (low &optional (high nil))
(if (and high (> low high))
nil
(cons-stream
low
(stream-enumerate-interval (1+ low) high))))
And now:
> (stream-nth 1000 (stream-enumerate-interval 0))
1000
And so on.
Well, we'd like some kind of macro which lets us traverse a stream: something like dolist, but for streams. Well we can do this by first writing a function which will call a function for each element in the stream (this is not the way I'd do this in production CL code, but it's fine here):
(defun call/stream-elements (f s)
;; Call f on the elements of s, returning NIL
(if (null s)
nil
(progn
(funcall f (stream-car s))
(call/stream-elements f (stream-cdr s)))))
And now
(defmacro do-stream ((e s &optional (r 'nil)) &body forms)
`(progn
(call/stream-elements (lambda (,e)
,#forms)
,s)
,r))
And now, for instance
(defun look-for (v s)
;; look for an element of S which is EQL to V
(do-stream (e s (values nil nil))
(when (eql e v)
(return-from look-for (values e t)))))
And we can then say
> (look-for 100 (stream-enumerate-interval 0))
100
t
Well, there is a lot more mechanism you need to make streams really useful: you need to be able to combine them, append them and so on. SICP has many of these functions, and they're generally easy to turn into CL, but too long here.
For practical purposes it would be wise to use existing libraries, but since the question is about how to implemented lazy lists, we will do it from scratch.
Closures
Lazy iteration is a matter of producing an object that can generate the new value of a lazy sequence each time it is asked to do so.
A simple approach for this is to return a closure, i.e. a function that closes over variables, which produces values while updating its state by side-effect.
If you evaluate:
(let ((a 0))
(lambda () (incf a)))
You obtain a function object that has a local state, namely here the variable named a.
This is a lexical binding to a location that is exclusive to this function, if you evaluate a second time the same expression, you'll obtain a different anonymous function that has its own local state.
When you call the closure, the value stored in a in incremented and its value is returned.
Let's bind this closure to a variable named counter, call it multiple times and store the successive results in a list:
(let ((counter (let ((a 0))
(lambda () (incf a)))))
(list (funcall counter)
(funcall counter)
(funcall counter)
(funcall counter)))
The resulting list is:
(1 2 3 4)
Simple iterator
In your case, you want to have an iterator that starts counting from 5 when writing:
(inf 5)
This can implemented as follows:
(defun inf (n)
(lambda ()
(shiftf n (1+ n))))
Here is there is no need to add a let, the lexical binding of an argument to n is done when calling the function.
We assign n to a different value within the body over time.
More precisely, SHIFTF assigns n to (1+ n), but returns the previous value of n.
For example:
(let ((it (inf 5)))
(list (funcall it)
(funcall it)
(funcall it)
(funcall it)))
Which gives:
(5 6 7 8)
Generic iterator
The standard dolist expects a proper list as an input, there is no way you can put another kind of data and expect it to work (or maybe in an implementation-specific way).
We need a similar macro to iterate over all the values in an arbitrary iterator.
We also need to specify when iteration stops.
There are multiple possibilities here, let's define a basic iteration protocol as follows:
we can call make-iterator on any object, along with arbitrary arguments, to obtain an iterator
we can call next on an iterator to obtain the next value.
More precisely, if there is a value, next returns the value and T as a secondary value; otherwise, next returns NIL.
Let's define two generic functions:
(defgeneric make-iterator (object &key)
(:documentation "create an iterator for OBJECT and arguments ARGS"))
(defgeneric next (iterator)
(:documentation "returns the next value and T as a secondary value, or NIL"))
Using generic functions allows the user to define custom iterators, as long as they respect the specified behaviour above.
Instead of using dolist, which only works with eager sequences, we define our own macro: for.
It hides calls to make-iterator and next from the user.
In other words, for takes an object and iterates over it.
We can skip iteration with (return v) since for is implemented with loop.
(defmacro for ((value object &rest args) &body body)
(let ((it (gensym)) (exists (gensym)))
`(let ((,it (make-iterator ,object ,#args)))
(loop
(multiple-value-bind (,value ,exists) (next ,it)
(unless ,exists
(return))
,#body)))))
We assume any function object can act as an iterator, so we specialize next for values f of class function, so that the function f gets called:
(defmethod next ((f function))
"A closure is an interator"
(funcall f))
Also, we can also specialize make-iterator to make closures their own iterators (I see no other good default behaviour to provide for closures):
(defmethod make-iterator ((function function) &key)
function)
Vector iterator
For example, we can built an iterator for vectors as follows. We specialize make-iterator for values (here named vec) of class vector.
The returned iterator is a closure, so we will be able to call next on it.
The method accepts a :start argument defaulting to zero:
(defmethod make-iterator ((vec vector) &key (start 0))
"Vector iterator"
(let ((index start))
(lambda ()
(when (array-in-bounds-p vec index)
(values (aref vec (shiftf index (1+ index))) t)))))
You can now write:
(for (v "abcdefg" :start 2)
(print v))
And this prints the following characters:
#\c
#\d
#\e
#\f
#\g
List iterator
Likewise, we can build a list iterator.
Here to demonstrate other kind of iterators, let's have a custom cursor type.
(defstruct list-cursor head)
The cursor is an object which keeps a reference to the current cons-cell in the list being visited, or NIL.
(defmethod make-iterator ((list list) &key)
"List iterator"
(make-list-cursor :head list))
And we define next as follows, specializeing on list-cursor:
(defmethod next ((cursor list-cursor))
(when (list-cursor-head cursor)
(values (pop (list-cursor-head cursor)) t)))
Ranges
Common Lisp also allows methods to be specialized with EQL specializers, which means the object we give to for might be a specific keyword, for example :range.
(defmethod make-iterator ((_ (eql :range)) &key (from 0) (to :infinity) (by 1))
(check-type from number)
(check-type to (or number (eql :infinity)))
(check-type by number)
(let ((counter from))
(case to
(:infinity
(lambda () (values (incf counter by) t)))
(t
(lambda ()
(when (< counter to)
(values (incf counter by) T)))))))
A possible call for make-iterator would be:
(make-iterator :range :from 0 :to 10 :by 2)
This also returns a closure.
Here, for example, you would iterate over a range as follows:
(for (v :range :from 0 :to 10 :by 2)
(print v))
The above expands as:
(let ((#:g1463 (make-iterator :range :from 0 :to 10 :by 2)))
(loop
(multiple-value-bind (v #:g1464)
(next #:g1463)
(unless #:g1464 (return))
(print v))))
Finally, if we add small modification to inf (adding secondary value):
(defun inf (n)
(lambda ()
(values (shiftf n (1+ n)) T)))
We can write:
(for (v (inf 5))
(print v)
(when (= v 7)
(return)))
Which prints:
5
6
7
I'll show it with a library:
How to create and consume an infinite list of integers with the GTWIWTG generators library
This library, called "Generators The Way I Want Them Generated", allows to do three things:
create generators (iterators)
combine them
consume them (once).
It is not unsimilar to the nearly-classic Series.
Install the lib with (ql:quickload "gtwiwtg"). I will work in its package: (in-package :gtwiwtg).
Create a generator for an infinite list of integers, start from 0:
GTWIWTG> (range)
#<RANGE-BACKED-GENERATOR! {10042B4D83}>
We can also specify its :from, :to, :by and :inclusive parameters.
Combine this generator with others: not needed here.
Iterate over it and stop:
GTWIWTG> (for x *
(print x)
(when (= x 7)
(return)))
0
1
2
3
4
5
6
7
T
This solution is very practical :)

`A' is not of the expected type `REAL'

The code below server to show the number of integer in a list.
(defun isNum (N)
(and (<= N 9) (>= N 0)))
(defun count-numbers (list)
(let ((count 0))
(dolist (item list count)
(cond
((null list) nil)
(((and (<= N 9) (>= N 0))) item)(incf count))
(setq(0 + count))))))
I get the error A' is not of the expected typeREAL' when I run the command
(count-numbers '(3 4 5 6 a 7 b) )
I'm surprised it runs at all, given that your cond is improperly constructed, you switch to infix notation in the unnecessarily side-effect-generating bit of your code and you're using unbound variables in count-numbers. Hypothetically, if it did run, that error sounds about right. You're doing numeric comparisons on a parameter (and those error on non-numeric input).
I've got my codereview hat on today, so lets go through this a bit more in-depth.
Lisp (it actually doesn't matter which, afaik this applies to CL, Scheme and all the mongrels) uses lower-case-snake-case-with-dashes, and not lowerCamelCase for variable and function names.
(defun is-num (n)
(and (<= n 9) (>= n 0)))
Common Lisp convention is to end a predicate with p or -p rather than begin them with is-. Scheme has the (IMO better) convention of ending predicates with ? instead
(defun num-p (n)
(and (<= n 9) (>= n 0)))
((and (<= N 9) (>= N 0))) is not how you call a function. You actually need to use its name, not just attempt to call its body. This is the source of one of the many errors you'd get if you tried to run this code.
(defun count-numbers (list)
(let ((count 0))
(dolist (item list count)
(cond
((null list) nil)
((num-p item) item)(incf count))
(setq(0 + count))))))
numberp already exists, and does a type check on its input rather than attempting numeric comparisons. You should probably use that instead.
(defun count-numbers (list)
(let ((count 0))
(dolist (item list count)
(cond
((null list) nil)
((numberp item) item)(incf count))
(setq(0 + count))))))
((numberp item) item) (incf count)) probably doesn't do what you think it does as a cond clause. It actually gets treated as two separate clauses; one checks whether item is a number, and returns it if it is. The second tries to check the variable incf and returns count if it evaluates to t (which it doesn't, and won't). What you seem to want is to increment the counter count when you find a number in your list, which means you should put that incf clause in with the item.
(defun count-numbers (list)
(let ((count 0))
(dolist (item list count)
(cond ((null list) nil)
((numberp item)
(incf count)
item))
(setq (0 + count)))))
(setq (0 + count)) is the wrong thing for three reasons
You seem to have tripped back into infix notation, which means that the second bit there is actually attempting to call the function 0 with the variables + and count as arguments.
You don't have a second part to the setq, which means you're trying to set the above to NIL implicitly.
You don't actually need to set anything in order to return a value
At this point, we finally have a piece of code that will evaluate and run properly (and it doesn't throw the error you mention above).
(defun count-numbers (list)
(let ((count 0))
(dolist (item list count)
(cond ((null list) nil)
((numberp item)
(incf count)
item))
count)))
dolist is an iteration construct that does something for each element in a given list. That means you don't actually need to test for list termination manually with that cond. Also, because dolist doesn't collect results, there's no reason to return item to it. You're also unnecessarily shadowing the local count you declare in the let.
(defun count-numbers (list)
(let ((count 0))
(dolist (item list)
(when (numberp item) (incf count)))
count))
As usual, you can do all this with a simpler loop call.
(defun count-numbers (list)
(loop for item in list
when (numberp item) sum 1))
which makes the counter implicit and saves you from needing to return it manually. In fact, unless this was specifically an exercise to write your own iteration function, Common Lisp has a built in count-if, which takes predicate sequence [some other options] and returns the count of items in sequence that match predicate. If you wanted to name count-numbers specifically, for stylistic reasons, you could just
(defun count-numbers (list) (count-if #'numberp list))
and be done with it.
In conclusion, good try, but please try reading up on the language family for realzies before asking further questions.
Yet another way to do it would be:
(reduce
#'(lambda (a b)
(if (numberp b) (1+ a) a))
'(3 4 5 6 a 7 b) :initial-value 0) ; 5
I.e. process the sequence in a way that you are given at each iteration the result of the previous iteration + the next member of the sequence. Start with zero and increment the result each time the element in the sequence is a number.
EDIT
Sorry, I haven't seen Inaimathi mentioned count-if. That would be probably better.

A lisp function refinement

I've done the Graham Common Lisp Chapter 5 Exercise 5, which requires a function that takes an object X and a vector V, and returns a list of all the objects that immediately precede X in V.
It works like:
> (preceders #\a "abracadabra")
(#\c #\d #r)
I have done the recursive version:
(defun preceders (obj vec &optional (result nil) &key (startt 0))
(let ((l (length vec)))
(cond ((null (position obj vec :start startt :end l)) result)
((= (position obj vec :start startt :end l) 0)
(preceders obj vec result
:startt (1+ (position obj vec :start startt :end l))))
((> (position obj vec :start startt :end l) 0)
(cons (elt vec (1- (position obj vec :start startt :end l)))
(preceders obj vec result
:startt (1+ (position obj vec
:start startt
:end l))))))))
It works correctly, but my teachers gives me the following critique:
"This calls length repeatedly. Not so bad with vectors, but still unnecessary. More efficient and more flexible (for the user) code is to define this like other sequence processing functions. Use :start and :end keyword parameters, the way the other sequence functions do, with the same default initial values. length should need to be called at most once."
I am consulting the Common Lisp textbook and google, but there seem to be of little help on this bit: I don't know what he means by "using :start and :end keyword parameters", and I have no clue of how to "call length just once". I would be grateful if you guys could give me some idea how on to refine my code to meet the requirement that my teacher posted.
UPDATE:
Now I have come up with the following code:
(defun preceders (obj vec
&optional (result nil)
&key (start 0) (end (length vec)) (test #'eql))
(let ((pos (position obj vec :start start :end end :test test)))
(cond ((null pos) result)
((zerop pos) (preceders obj vec result
:start (1+ pos) :end end :test test))
(t (preceders obj vec (cons (elt vec (1- pos)) result)
:start (1+ pos) :end end :test test)))))
I get this critique:
"When you have a complex recursive call that is repeated identically in more than one branch, it's often simpler to do the call first, save it in a local variable, and then use the variable in a much simpler IF or COND."
Also,for my iterative version of the function:
(defun preceders (obj vec)
(do ((i 0 (1+ i))
(r nil (if (and (eql (aref vec i) obj)
(> i 0))
(cons (aref vec (1- i)) r)
r)))
((eql i (length vec)) (reverse r))))
I get the critique
"Start the DO at a better point and remove the repeated > 0 test"
a typical parameter list for such a function would be:
(defun preceders (item vector
&key (start 0) (end (length vector))
(test #'eql))
...
)
As you can see it has START and END parameters.
TEST is the default comparision function. Use (funcall test item (aref vector i)).
Often there is also a KEY parameter...
LENGTH is called repeatedly for every recursive call of PRECEDERS.
I would do the non-recursive version and move two indexes over the vector: one for the first item and one for the next item. Whenever the next item is EQL to the item you are looking for, then push the first item on to a result list (if it is not member there).
For the recursive version, I would write a second function that gets called by PRECEDERS, which takes two index variables starting with 0 and 1, and use that. I would not call POSITION. Usually this function is a local function via LABELS inside PRECEDERS, but to make it a bit easier to write, the helper function can be outside, too.
(defun preceders (item vector
&key (start 0) (end (length vector))
(test #'eql))
(preceders-aux item vector start end test start (1+ start) nil))
(defun preceders-aux (item vector start end test pos0 pos1 result)
(if (>= pos1 end)
result
...
))
Does that help?
Here is the iterative version using LOOP:
(defun preceders (item vector
&key (start 0) (end (length vector))
(test #'eql))
(let ((result nil))
(loop for i from (1+ start) below end
when (funcall test item (aref vector i))
do (pushnew (aref vector (1- i)) result))
(nreverse result)))
Since you already have a solution that's working, I'll amplifiy Rainer Joswig's solution, mainly to make related stylistic comments.
(defun preceders (obj seq &key (start 0) (end (length seq)) (test #'eql))
(%preceders obj seq nil start end test))
The main reason to have separate helper function (which I call %PRECEDERS, a common convention for indicating that a function is "private") is to eliminate the optional argument for the result. Using optional arguments that way in general is fine, but optional and keyword arguments play horribly together, and having both in a single function is a extremely efficient way to create all sorts of hard to debug errors.
It's a matter of taste whether to make the helper function global (using DEFUN) or local (using LABELS). I prefer making it global since it means less indentation and easier interactive debugging. YMMV.
A possible implementation of the helper function is:
(defun %preceders (obj seq result start end test)
(let ((pos (position obj seq :start start :end end :test test)))
;; Use a local binding for POS, to make it clear that you want the
;; same thing every time, and to cache the result of a potentially
;; expensive operation.
(cond ((null pos) (delete-duplicates (nreverse result) :test test))
((zerop pos) (%preceders obj seq result (1+ pos) end test))
;; I like ZEROP better than (= 0 ...). YMMV.
(t (%preceders obj seq
(cons (elt seq (1- pos)) result)
;; The other little bit of work to make things
;; tail-recursive.
(1+ pos) end test)))))
Also, after all that, I think I should point out that I also agree with Rainer's advice to do this with an explicit loop instead of recursion, provided that doing it recursively isn't part of the exercise.
EDIT: I switched to the more common "%" convention for the helper function. Usually whatever convention you use just augments the fact that you only explicitly export the functions that make up your public interface, but some standard functions and macros use a trailing "*" to indicate variant functionality.
I changed things to delete duplicated preceders using the standard DELETE-DUPLICATES function. This has the potential to be much (i.e., exponentially) faster than repeated uses of ADJOIN or PUSHNEW, since it can use a hashed set representation internally, at least for common test functions like EQ, EQL and EQUAL.
A slightly modofied variant of Rainer's loop version:
(defun preceders (item vector
&key (start 0) (end (length vector))
(test #'eql))
(delete-duplicates
(loop
for index from (1+ start) below end
for element = (aref vector index)
and previous-element = (aref vector (1- index)) then element
when (funcall test item element)
collect previous-element)))
This makes more use of the loop directives, and among other things only accesses each element in the vector once (we keep the previous element in the previous-element variable).
Answer for your first UPDATE.
first question:
see this
(if (foo)
(bar (+ 1 baz))
(bar baz))
That's the same as:
(bar (if (foo)
(+ 1 baz)
baz))
or:
(let ((newbaz (if (foo)
(+ 1 baz)
baz)))
(bar newbaz))
Second:
Why not start with I = 1 ?
See also the iterative version in my other answer...
The iterative version proposed by Rainer is very nice, it's compact and more efficient since you traverse the sequence only one time; in contrast to the recursive version which calls position at every iteration and thus traverse the sub-sequence every time. (Edit: I'm sorry, I was completely wrong about this last sentence, see Rainer's comment)
If a recursive version is needed, another approach is to advance the start until it meets the end, collecting the result along its way.
(defun precede (obj vec &key (start 0) (end (length vec)) (test #'eql))
(if (or (null vec) (< end 2)) nil
(%precede-recur obj vec start end test '())))
(defun %precede-recur (obj vec start end test result)
(let ((next (1+ start)))
(if (= next end) (nreverse result)
(let ((newresult (if (funcall test obj (aref vec next))
(adjoin (aref vec start) result)
result)))
(%precede-recur obj vec next end test newresult)))))
Of course this is just another way of expressing the loop version.
test:
[49]> (precede #\a "abracadabra")
(#\r #\c #\d)
[50]> (precede #\a "this is a long sentence that contains more characters")
(#\Space #\h #\t #\r)
[51]> (precede #\s "this is a long sentence that contains more characters")
(#\i #\Space #\n #\r)
Also, I'm interested Robert, did your teacher say why he doesn't like using adjoin or pushnew in a recursive algorithm?

How do I memoize a recursive function in Lisp?

I'm a Lisp beginner. I'm trying to memoize a recursive function for calculating the number of terms in a Collatz sequence (for problem 14 in Project Euler). My code as of yet is:
(defun collatz-steps (n)
(if (= 1 n) 0
(if (evenp n)
(1+ (collatz-steps (/ n 2)))
(1+ (collatz-steps (1+ (* 3 n)))))))
(defun p14 ()
(defvar m-collatz-steps (memoize #'collatz-steps))
(let
((maxsteps (funcall m-collatz-steps 2))
(n 2)
(steps))
(loop for i from 1 to 1000000
do
(setq steps (funcall m-collatz-steps i))
(cond
((> steps maxsteps)
(setq maxsteps steps)
(setq n i))
(t ())))
n))
(defun memoize (fn)
(let ((cache (make-hash-table :test #'equal)))
#'(lambda (&rest args)
(multiple-value-bind
(result exists)
(gethash args cache)
(if exists
result
(setf (gethash args cache)
(apply fn args)))))))
The memoize function is the same as the one given in the On Lisp book.
This code doesn't actually give any speedup compared to the non-memoized version. I believe it's due to the recursive calls calling the non-memoized version of the function, which sort of defeats the purpose. In that case, what is the correct way to do the memoization here? Is there any way to have all calls to the original function call the memoized version itself, removing the need for the special m-collatz-steps symbol?
EDIT: Corrected the code to have
(defvar m-collatz-steps (memoize #'collatz-steps))
which is what I had in my code.
Before the edit I had erroneously put:
(defvar collatz-steps (memoize #'collatz-steps))
Seeing that error gave me another idea, and I tried using this last defvar itself and changing the recursive calls to
(1+ (funcall collatz-steps (/ n 2)))
(1+ (funcall collatz-steps (1+ (* 3 n))))
This does seem to perform the memoization (speedup from about 60 seconds to 1.5 seconds), but requires changing the original function. Is there a cleaner solution which doesn't involve changing the original function?
I assume you're using Common-Lisp, which has separate namespaces for variable and function names. In order to memoize the function named by a symbol, you need to change its function binding, through the accessor `fdefinition':
(setf (fdefinition 'collatz-steps) (memoize #'collatz-steps))
(defun p14 ()
(let ((mx 0) (my 0))
(loop for x from 1 to 1000000
for y = (collatz-steps x)
when (< my y) do (setf my y mx x))
mx))
Here is a memoize function that rebinds the symbol function:
(defun memoize-function (function-name)
(setf (symbol-function function-name)
(let ((cache (make-hash-table :test #'equal)))
#'(lambda (&rest args)
(multiple-value-bind
(result exists)
(gethash args cache)
(if exists
result
(setf (gethash args cache)
(apply fn args)))))))
You would then do something like this:
(defun collatz-steps (n)
(if (= 1 n) 0
(if (evenp n)
(1+ (collatz-steps (/ n 2)))
(1+ (collatz-steps (1+ (* 3 n)))))))
(memoize-function 'collatz-steps)
I'll leave it up to you to make an unmemoize-function.
something like this:
(setf collatz-steps (memoize lambda (n)
(if (= 1 n) 0
(if (evenp n)
(1+ (collatz-steps (/ n 2)))
(1+ (collatz-steps (1+ (* 3 n))))))))
IOW: your original (non-memoized) function is anonymous, and you only give a name to the result of memoizing it.
Note a few things:
(defun foo (bar)
... (foo 3) ...)
Above is a function that has a call to itself.
In Common Lisp the file compiler can assume that FOO does not change. It will NOT call an updated FOO later. If you change the function binding of FOO, then the call of the original function will still go to the old function.
So memoizing a self recursive function will NOT work in the general case. Especially not if you are using a good compiler.
You can work around it to go always through the symbol for example: (funcall 'foo 3)
(DEFVAR ...) is a top-level form. Don't use it inside functions. If you have declared a variable, set it with SETQ or SETF later.
For your problem, I'd just use a hash table to store the intermediate results.
Changing the "original" function is necessary, because, as you say, there's no other way for the recursive call(s) to be updated to call the memoized version.
Fortunately, the way lisp works is to find the function by name each time it needs to be called. This means that it is sufficient to replace the function binding with the memoized version of the function, so that recursive calls will automatically look up and reenter through the memoization.
huaiyuan's code shows the key step:
(setf (fdefinition 'collatz-steps) (memoize #'collatz-steps))
This trick also works in Perl. In a language like C, however, a memoized version of a function must be coded separately.
Some lisp implementations provide a system called "advice", which provides a standardized structure for replacing functions with enhanced versions of themselves. In addition to functional upgrades like memoization, this can be extremely useful in debugging by inserting debug prints (or completely stopping and giving a continuable prompt) without modifying the original code.
This function is exactly the one Peter Norvig gives as an example of a function that seems like a good candidate for memoization, but which is not.
See figure 3 (the function 'Hailstone') of his original paper on memoization ("Using Automatic Memoization as a Software Engineering Tool in Real-World AI Systems").
So I'm guessing, even if you get the mechanics of memoization working, it won't really speed it up in this case.
A while ago I wrote a little memoization routine for Scheme that used a chain of closures to keep track of the memoized state:
(define (memoize op)
(letrec ((get (lambda (key) (list #f)))
(set (lambda (key item)
(let ((old-get get))
(set! get (lambda (new-key)
(if (equal? key new-key) (cons #t item)
(old-get new-key))))))))
(lambda args
(let ((ans (get args)))
(if (car ans) (cdr ans)
(let ((new-ans (apply op args)))
(set args new-ans)
new-ans))))))
This needs to be used like so:
(define fib (memoize (lambda (x)
(if (< x 2) x
(+ (fib (- x 1)) (fib (- x 2)))))))
I'm sure that this can be ported to your favorite lexically scoped Lisp flavor with ease.
I'd probably do something like:
(let ((memo (make-hash-table :test #'equal)))
(defun collatz-steps (n)
(or (gethash n memo)
(setf (gethash n memo)
(cond ((= n 1) 0)
((oddp n) (1+ (collatz-steps (+ 1 n n n))))
(t (1+ (collatz-steps (/ n 2)))))))))
It's not Nice and Functional, but, then, it's not much hassle and it does work. Downside is that you don't get a handy unmemoized version to test with and clearing the cache is bordering on "very difficult".