With clisp and sbcl:
(%i1) load("/home/volker/Maxima/git/maxima/src/ifactor.lisp")$
(%i2) :lisp (get-factor-list 15)
((5 1) (3 1))
(%i2) :lisp (let* ((fs (get-factor-list 14)) (f (car fs))) (incf (cadr f) 41))
42
(%i2) :lisp (get-factor-list 15)
((5 42) (3 1))
Each call to get-factor-list should cons a new list, so each return value should be referentially independent.
I tried to find the reason of this error and observed that in ifactor.lisp lines 223-226
\(when \(> \(\* d d\) n\)
\(push \`\(,n 1\) factors\)
\(when $ifactor\_verbose \(format t "small prime cofactor: ~A~%" n\)\)
\(return-from get-small-factors \(values 1 factors\)\)\)
the backquote-comma-macro-line seems to cause this.
Using
(push (list n 1) factors)
or
(setq tmp 1)
(push `(,n ,tmp) factors)
instead the results are as expected.
I don't get the clue what's wrong with (push `(,n 1) factors).
If I create a new list foo with (copy-tree factors) inside of get-small-factors and do
(push `(,n 1) foo)
the results for foo are as expected.
So I guess the variable 'factors' has referential problems. Don't know why.
(setq foo (copy-tree factors))
isn't even necessary.
(setq foo factors)
or
(setf foo factors)
also works:
(setf foo factors)
(print foo)
(push `(,n 1) foo)
(print foo)
(print factors)
(push `(,n 1) factors)
(print factors)
prints
(%i2) :lisp (get-factor-list 15)
((3 1))
((5 1) (3 1))
((3 1))
((5 42) (3 1)) <- print
((5 42) (3 1)) <- return value
I think you should just go ahead and change the code. Looks to me like you have identified a problem and a way to fix it, so I think you should ahead and fix it.
Hi Robert,
I have just checked if this problem is present with gcl on Windows and it's not. But with ccl (Windows agein). So it counts 3 : 1 (first noticed with sbcl and clisp on Linux).
The fact that gcl doesn't show this problem makes me wonder whether it's a Maxima or a Lisp problem.
I will follow your advice, change the code and close this report.
Best
Volker