How can I correctly represent a box structure with dotted pairs in Lisp?

121 Views Asked by At

I have issue with representing box structure via LISP's dotted pairs.

CL-USER 21 > (cons 1 (cons (cons 3 4) (cons (cons 3 4) 2)))

(1 (3 . 4) (3 . 4) . 2)

This is what i have, this is the output, but that's clearly incorrect, because the 3.4 pair is there twice, can someone help me correct this please? It has to be represented with cons(dotted pairs).enter image description here

ive tried to represent it many different ways, but i cant find the solution for this.

4

There are 4 best solutions below

0
Barmar On

You need to use a variable so you can refer to the same pair in multiple places.

(let ((box34 (cons 3 4)))
  (cons 1 (cons box34 (cons box34 2))))
0
Rainer Joswig On

You can create it like this:

CL-USER 1 > (let ((c (cons 3 4)))
              (cons 1
                    (cons c
                          (cons c 2))))
(1 (3 . 4) (3 . 4) . 2)

We don't see it in the printed output, but the sublists are the same object:

CL-USER 2 >  (eq (second *) (third *))
T

We can let Lisp make the structure clear:

CL-USER 3 > setf *print-circle* t
T

CL-USER 4 > ***
(1 #1=(3 . 4) #1# . 2)
0
Jérôme Radix On

You don't need to declare a specific variable to compose your list, you just need to use the Sharpsign Sharpsign :

CL-USER> (setf foo '(1 #1=(3 . 4) #1# . 2))
(1 (3 . 4) (3 . 4) . 2)

CL-USER> (eq (second foo) (third foo))
T
0
ignis volens On

[This is really a comment not an answer, but it's too long for a comment.]

As you are using LispWorks, you might be interested in using its grapher as a visualisation tool to see cons trees. Here is a function which will do that:

(use-package :capi)

(defun show-cons-graph (c)
  (contain
   (make-instance 'graph-pane
                  :roots (list c)
                  :children-function (lambda (c)
                                       (typecase c
                                         (cons (list (car c) (cdr c)))
                                         (t '())))
                  :print-function (lambda (c)
                                    (typecase c
                                      (cons "")
                                      (t (format nil "~S" c)))))))

Here is

(show-cons-graph (cons 1 (cons (cons 3 4) (cons (cons 3 4) 2)))

not sharing

and here is

(let ((c (cons 3 4)))
  (show-cons-graph (cons 1 (cons c (cons c 2)))))

sharing