Copy of a 2d array instead of reference in CLISP - arrays

I am trying to create a copy of the first element in the array and add the copy to the end of the array. I then want to do work (move_NE) on the copy I just created, changing it but not the original. The intended result is to have an array of two elements, one which points to the original and the other which points to a modified original.
(vector-push-extend (initialize_board 5) *all_states*)
(vector-push-extend (elt *all_states* 0) *all_states*)
(move_NE (elt *all_states* 1) 0 2)
From what I can figure, (elt *all_states* 0) is producing a reference to the original element which results in an array with two elements, both which point to the same thing.
The context of this program is from my attempts to write a program to generate all possible moves for a triangular peg solitaire (cracker barrel) game. *all_states* is an array of boardstates, each of which are a 2d array.
Any help is appreciated.
EDIT: My background is in C/C++ programming.

There's no copying-on-assignment in Common Lisp. (And, as far as I'm aware, There's not in most Object Oriented Programming languages, either. E.g., in Java, if you have Object x = ...; Object y = x; there's just one object. If you modify that object through either the variable x or y, the change will be visible if you access the object through the other variable.) If you need a copy of an object, you'll need to make that copy yourself. That's just the same for other built in datatypes, too.
First, note that if you store a value in an element of an array, it doesn't modify the previous value that was stored in that array:
CL-USER> (let ((a (make-array 10 :adjustable t :fill-pointer 1)))
(setf (aref a 0) "one")
(print a)
(vector-push-extend (aref a 0) a)
(print a)
(setf (aref a 1) "five")
(print a))
; #("one")
; #("one" "one")
; #("one" "five")
But, when the array looked like #("one" "one"), the value of (aref a 0) and (aref a 1) is the same string. You can see this if we modify that string:
CL-USER> (let ((a (make-array 10 :adjustable t :fill-pointer 1)))
(setf (aref a 0) "one")
(print a)
(vector-push-extend (aref a 0) a)
(setf (char (aref a 1) 2) #\3)
(print a))
; #("one")
; #("on3" "on3") ; we changed the **single** string
When you extend the array you can, of course, make a copy of the object, and then there will be two distinct objects:
CL-USER> (let ((a (make-array 10 :adjustable t :fill-pointer 1)))
(setf (aref a 0) "one")
(print a)
(vector-push-extend (copy-seq (aref a 0)) a)
(print a)
(setf (char (aref a 1) 2) #\3)
(print a))
; #("one")
; #("one" "one")
; #("one" "on3")
You mentioned
From what I can figure, (elt *all_states* 0) is producing a reference
to the original element which results in an array with two elements,
both which point to the same thing.
That's really the behavior that you want. If (elt *all_states* 0) didn't return the object at index 0 of the array, but returned a copy of the object, there'd be no way to modify the actual thing that's stored in the array (if the array was the only way to get ahold of the object). You mentioned coming from a C/C++ background; I highly recommend that rather than try to adapt that mental model to become a mental model for Common Lisp, that you spend some time building a mental model of Common Lisp from (almost) scratch. I don't mean that in a dismissive sense; in my opinion, it's good advice for any programmer learning a new language. If you try to "get by" with assumptions based on other languages, you can end up with some pretty subtle and hard-to-find bugs. I'd make a similar suggestion to someone with a Lisp background learning C/C++. If, for some reason, you don't have the time to do that, the quickest and safest advice I can give you is this:
If you you need to think of Common Lisp with a C/C++ model, choose C, not C++. Primitive datatypes (ints, chars, etc.) are roughly the same, and everything is is handled by pointers.
With that model, then your initial problem is very clear. You've got an array of pointers to objects, and you extended an array with another pointer to the same object. It's no surprise, then, that when you modified the object pointed at by that pointer, it was visible through all pointers to that object. You need to allocate a new object that's a copy of the first, and put a pointer to that in the array.
This is really the behavior that you want

Related

Two cons point to same memory when mapping over array in Common Lisp

I have the following function:
(defun transform-matrix (matrix)
(let ((res (map 'vector
(lambda (x)
(map 'vector
(lambda (ix)
(if ix
'(t 0) ; --> Problem happens here
0))
x))
matrix)))
res))
This function will accept a 2d matrix, in which each element can either be t or nil. Then it will transform t -> '(t 0) and nil -> 0.
The result array has one problem is every (t 0) cons now point to the same memory location. For example if i save the result array in res variable and do this:
(eq (aref (aref res 0) 0)
(aref (aref res 1) 1))
*Assume that res[0][0] and res[1][1] is the '(t, 0) nodes.
This will result in T. But do like this is result in nil:
(eq '(t 0) '(t 0))
Can i ask what happen with the transform-matrix that make created cons to point to the same memory location.
I test these codes on SBCL 2.0.0 Windows 64 Bit.
Thank you.
One way to see the problem here is to change your function to this:
(defun transform-matrix (matrix)
(let ((non-nil-value '(t 0))
(nil-value 0))
(map 'vector
(lambda (x)
(map 'vector
(lambda (ix)
(if ix non-nil-value nil-value))
x))
matrix)))
It should be clear that this code is functionally identical: both functions have a single occurrence of '(t 0): this one just gives it a name.
But now let's gut this function and consider this:
(defun ts ()
(let ((non-nil-value '(t 0)))
(eq non-nil-value non-nil-value)))
Well, certainly I would expect the result of calling this function to be t.
And that's why every element in your resulting nested vectors which isn't 0 is the same: because you only ever constructed one object.
If you want all of the objects in the returned value to be different objects (ie not to be identical), you need to construct a new object each time, for instance by:
(defun transform-matrix (matrix)
(let ((non-nil-template '(t 0)))
(map 'vector
(lambda (x)
(map 'vector
(lambda (ix)
(if ix (copy-list non-nil-template) 0))
x))
matrix)))
This will ensure that each non-zero element of the resulting object
is distinct;
can safely be mutated.
Neither of these were previously true.
For the case of (eq '(t 0) '(t 0)) you might expect that this must return nil. That is (I think definitely) the case in interpreted code. But for compiled code the answer is not so clear. At least for the file compiler, it's fairly clear that in fact this may return t. Section 3.2.4.4 of the spec says, in part
If two literal objects appearing in the source code for a single file processed with the file compiler are the identical, the corresponding objects in the compiled code must also be the identical. With the exception of symbols and packages, any two literal objects in code being processed by the file compiler may be coalesced if and only if they are similar; if they are either both symbols or both packages, they may only be coalesced if and only if they are identical.
And in (eq '(t 0) '(t 0)), there are two literal lists, which are similar, and which therefore may be coalesced by the file compiler.
As a general rule, if you want a mutable object, or an object which you need to be certain is not identical to any other object, you should construct it explicitly: it is never safe (or even legal) to mutate literal objects, and the rules on which objects can be coalesced are complex enough that it is generally just safer to construct the objects so you know what is happening.
As an aside is there a reason you are using nested vectors rather than a two-dimensional matrix?
Just to add to TFB:
Lisp does not copy its arguments in a function call. It passes references to it:
(let ((a '(1 2))) ; A is a reference to (1 2)
(foo a) ; calls FOO and the same (1 2) will be
; accessible via a new reference inside FOO
(setf (aref array 0) a)
(setf (aref array 1) a) ; this will make the array at 0 and 1
; reference the same list
)
If i use the quote version '(t 0) twice in the REPL i still can get two different cons.
That's because in the REPL you would need to enter '(t 0) twice and make sure that the Reader (the R in REPL) constructs new lists, which it usually does:
CL-USER > (eq (read) (read))
(0 1) (0 1)
NIL
Now the REPL reader:
CL-USER 6 > '(1 2)
(1 2) ; result
CL-USER 7 > '(1 2)
(1 2)
CL-USER 8 > (eq * **) ; comparing previous results
NIL
Each call to READ conses a fresh new lists.
Side note: There are actually also more advanced REPL readers, where one can reference already existing lists, like in the REPL of the McCLIM listener.
Firstly, note that your transform-matrix function contains exactly one instance of the '(t 0) syntax, whereas the expression you're testing at the REPL contains two instances: (eq '(t 0) '(t 0)).
Because that expression has two instances, it is is possible that those will be different objects. In fact, the Lisp implementation would have to go out of its way to turn them into one object, and it is something that is allowed.
The (t 0) syntax is a piece of the program's source code. A program can apply the quote operator (for which the ' character is a shorthand) to a piece of its syntax to use that syntax as a literal. A given literal is one object; multiple evaluations of the same quote yield the same object.
When Lisp is naively interpreted, the interpreter recursively walks the original list-based source code. The implementation of the quote operator simply returns the piece of code that is being walked as a value.
When Lisp is compiled, the list-based source code is transformed to something else, such as native machine language for the CPU to execute directly. In the transformed image, the source code is gone. Yet, the compiler has to recognize the quote special form and translate it somehow. To do that, it has to take the piece of source code structure enclosed by quote and embed that object in the compiled image, so that it's somehow available to the compiled code: i.e. that quoted part of the source is not gone, but is propagated into the translation. For instance, the compiled image may be accompanied by a static vector dedicated for storing literals. Whenever the compiler process a quote expression like '(t 0), it allocates the next available slot in that vector, like position 47 or whatever, and stick the object (t 0) into that slot. The compiled version of '(t 0) code will then access that slot 47 in the literal data vector, and it will do that every time it is executed, retrieving the same object each time, just like the interpreted version of the program retrieveds the same piece of its own source code each time.
When compiling literals, the compiler may also search through the vector and de-duplicate it. Instead of allocating the next available index, like 47, it might scan through the literals and discover that index 13 already has a (t 0). Then it generates code to access index 13. Therefore, the compiled version of (eq '(t 0) '(t 0)) may well yield true.
Now, the way your question is framed, there is no evidence that there is an actual problem from all of the slots sharing a single instance of (t 0).
You need these objects to be different if you ever change the 0 value to something else by mutation. However, even that issue can be solved without actually making the objects different up-front. So that is to say, we can keep all the (t 0) entries objects pointing to the same object, and if we want to change some of them to, say, (t 3), we can allocate a whole new object at that time, rather that doing (set (cadr entry) 3). Moreover, maybe we can make all the (t 3) entries point to a single (t 3), like we did with (t 0).
It is impossible to say that changing '(t 0) to (list t 0) is the best approach to fix the problem, assuming there even is a problem.

How to swap two rows in a twodimensional array in common lisp nondestructively

I'm trying to swap two rows in a twodimensional array in Common Lisp. I have found a way to this with aref. This a destructive way of doing it and I like to keep it more functional. Has anyone a better idea?
(defun swap-rows (matrix r1 r2)
"Returns a modified matrix with two swapped rows"
(loop for i upto (1- (array-dimension matrix 1))
do (rotatef (aref copy r1 i) (aref copy r2 i))))
I have been looking at making a copy of the original array, but it still changes the original array. This is my second try:
(defun swap-rows (matrix r1 r2)
"Returns a modified matrix with two swapped rows"
(let ((copy matrix))
(loop for i upto (1- (array-dimension matrix 1))
do (rotatef (aref copy r1 i) (aref copy r2 i))
finally (return copy))))
There are some other things I've looked at but some ways to copy the array seem somewhat overly complicated. Thanks in advance for any advice.
P.S. I prefer not to use any outside libraries (very sorry to the person who recommended Alexandria).
Here below you are not doing a copy, just binding a variable (copy) to an existing value (the one bound to matrix):
(let ((copy matrix))
...)
As seen in the other answer, you can use the Alexandria library to copy array without much complexity; for example:
(alexandria:copy-array #2A((1 0 0)
(0 1 0)
(0 0 1)))
In your case, if you import the symbol, it is sufficent to write:
(let ((copy (copy-array matrix)))
...)
If you only ever swap rows without modifying their content, maybe you can define matrices as sequences of vectors. You would share the same rows, but in a different orders (and if you need to change values, then you can copy vectors).
To copy an array in Common Lisp is not particularly simple, and I think this is due to the fact that arrays in this language are data structures particularly suitable for side-effect programming instead of side-effect free (or functional) programming. As #coredump pointed out, if you prefer to use side-effect free programming you should probably use other data structures, like list of lists, or sequences of vectors.
If you want to stick with arrays, here is an alternative way of doing your copy (not very simple or efficient!):
(defun swap-rows (matrix r1 r2)
"returns a copy of matrix with rows r1 ≤ r2 swapped"
(let* ((rows (array-dimension matrix 0))
(cols (array-dimension matrix 1)))
(flet ((get-rows (from-r to-r)
"get block of matrix from row from-r to row to-r excluded"
(loop for i from from-r below to-r
collect (loop for j from 0 below cols
collect (aref matrix i j)))))
(make-array
(list rows cols)
:initial-contents
(append (get-rows 0 r1)
(get-rows r2 (1+ r2))
(get-rows (1+ r1) r2)
(get-rows r1 (1+ r1))
(get-rows (1+ r2) rows))))))
In practice this convert the original array in blocks of lists, and rebuild a new array starting from those lists.

How to have two equal arrays but with a different internal state

I want to create a copy of an array that already exists, but i want to be able to change values on one of them not altering the other one.
(setf arayONE (make-array(list 2 2)))
(setf arayTWO arayONE)
(setf (aref arayONE 1 1) 2) ; this will change both arayONE and arayTWO values
I also tryed passing the value with the (let ....) statement but gave the same answer..
Thanks sorry for the newbie question.
When you do (setf arayTWO arayONE) you are actually giving to the same array two different names, since setf does not perform any copy, but simply assign to the variable arayTWO the value of arayONE, which is a reference to an array.
So you have to explicitly copy the array, but since there is no primitive function in Common Lisp to copy arrays, you have to write it by yourself or use the function provided by some library, like Alexandria.
For a simple copy like that of this case, you could for instance write something like this:
(setf arayTWO (make-array (array-dimensions arayONE)))
(dotimes (i (array-total-size arayONE))
(setf (row-major-aref arayTWO i)
(row-major-aref arayONE i)))
For a more general function that works for every kind of array, with fill pointer, adjustability, etc., you could look at this answer: How do you copy an array in common lisp?

Access array with list of indices

I want to access arrays with the indices being in a list. Let's call this utility arefl, and it's defined as follows:
(arefl array '(x y z ...)) equals (aref array x y z ...)
My goal is to create some generic functions that operate on matrices of any size.
I have failed to implement such a thing with macros and just aref. The closest thing that I have is:
(defmacro arefl (array is)
"Access array by a list of indices"
`(apply #'aref (cons ,array ,is)))
which works, and actually it also works with (setf (arefl array is) value) but the compiler, at least sbcl, throws a warning telling me that I'm redefining setf for (I guess) apply. The warning is:
; in: DEFUN (SETF AREFL**)
; (SETF (APPLY #'AREF ARRAY (REDUCE 'CONS ARGS :FROM-END T)) NEW-VALUE)
; --> LET* MULTIPLE-VALUE-BIND LET APPLY MULTIPLE-VALUE-CALL
; ==>
; #'(SETF AREF)
;
; caught STYLE-WARNING:
; defining as a SETF function a name that already has a SETF macro:
; (SETF AREF)
;
; compilation unit finished
; caught 1 STYLE-WARNING condition
--
Is there a better way? I'm looking for an implementation that works well with setf and does not need a call to another function like apply nor does do any cons
Ok, define-setf-expander is overkill for this.
(defun arefl (array list)
(apply #'aref array list))
(defun (setf arefl) (x array list)
(setf (apply #'aref array list) x))
See "APPLY Forms as Places": http://clhs.lisp.se/Body/05_abe.htm
First, though I recognize that you said
I'm looking for an implementation that works well with setf and does not need a call to another function like apply nor does do any cons
however, you can simply use apply 'aref here, and you don't need to do any consing, since only apply's final argument needs to be a list. That means that all the following are equivalent:
(aref array 0 1)
(apply 'aref (list array 0 1))
(apply 'aref array (list 0 1))
(apply 'aref array 0 (list 1))
(apply 'aref array 0 1 '())
Most importantly, if you want to avoid calling cons, it means that you can do
(apply 'aref array indices)
You can use setf with this too (although you will have to use #'array, and not 'array):
(setf (apply #'aref array indices) new-value)
Since apply works here, you just need to make your aref* and (setf aref*) functions (to be analogous with list*):
(defun aref* (array &rest args)
  (apply 'aref array (reduce 'cons args :from-end t)))
             
(defun (setf aref*) (new-value array &rest args)
  (setf (apply #'aref array (reduce 'cons args :from-end t)) new-value))
The (reduce 'cons args :from-end t) in those is used to support spreadable argument list designators, which are what apply uses. Using this idiom, you can pass exactly the same kinds of arguments to (aref* ...) that you could use in (apply #'aref ...). That might be a bit more complex than the use cases that you've described, but it means that rather than having to specifically describe what sorts of arguments aref* takes, you can simply say (like the documentation for apply does), that aref*'s args are a spreadable argument list designator, and that aref* applies aref to the args.

How to compare two lists in lisp that are not exactly the same in length or structure?

I have these two lists:
'(and 1 (or a b))
'( (a 0)(b 1) )
I am new to lisp, and I am finding it very hard to figure out how to compare these two lists. I am thinking of creating a comparison function, but I don't know how to compare them one by one as in lisp values aren't returned until the expression is evaluated. Since they aren't the same structure either, I can't assume they will be the same, structurally at least. Any explanation how this works?
Edit: Sorry, I forgot to say why I am comparing. The second list is to suppose to bind the number to everywhere where those variables exists in the first list. So the resulting first list should be:
'(and 1(or 0 1))
Built in:
$ clisp -q
[1]> (sublis '((a . 0) (b . 1)) '(and 1 (or a b)))
(AND 1 (OR 0 1))
[2]>
So the homework reduces to making a wrapper for SUBLIS which accepts the bindings in the form ((a 0) (b 1)) rather than ((a . 0) (b . 1)).
Clue:
(loop for (x y) in vars collecting (cons x y))
;;; Look up a var like A a list like ((A 0) (B 1))
;;; and retrieve the (A 0). Or nil if not found.
(defun lookup-var (var bindings)
(find var bindings :key #'first))
;;; The homework
(defun subst-vars (tree bindings)
(cond
;; if the tree is a cons cell, then substitute in the
;; car, substitute in the cdr, and combine the results by consing
;; a new cons! Easy!
((consp tree) (cons (subst-vars (car tree) bindings)
(subst-vars (cdr tree) bindings)))
;; Otherwise the tree must be an atom. See if the atom is
;; a var that we can substitute. If not, return the atom.
(t (let ((binding (lookup-var tree bindings)))
(if binding
(second binding) ;; got a binding entry; return its value!
tree))))) ;; no deal, just return the original
Typed this right in the stackoverflow window and it ran with no edits. :)
This is quite inefficient though. Suppose that the variables do not occur in the tree at all. It makes a wasteful copy of the tree instead of just returning the tree. So that you do some work on this yourself, can you figure out a way to optimize it so that it avoids calling the cons function unnecessarily? Hint: check if the recursive calls to subst-vars just return the same object.

Resources