From: Joerivdv
Subject: frames + decision tree
Date: 
Message-ID: <3b30e720$0$84432$ba620e4c@news.skynet.be>
Hi, I'm looking for someone who can help me with some short common lisp
assignments. I have succeeded in solving parts of the assignments myself,
but I have to hand them in this friday, so I am really desperate. I have
tried my absolute best, but I can't seem to get any further. The programs
are AI related and involve the induction of a decision tree and the creation
and handling of frames (knowledge representation). I will paste both
assignments here. There are only small parts that need to be written, the
rest is already given.

Decision Tree:

(defvar *examples*)
(defvar *domains*)
(defvar *categories*)
(defvar *features*)

(setf *examples*
      '(((sunny up north) no-rain)
        ((cloudy up south) rain)
        ((cloudy stable north) rain)
        ((sunny down north) no-rain)
        ((cloudy down north) rain)
 ((sunny up south) no-rain)
        ((cloudy down south) no-rain)))

;;; TODO 1: write a function that takes *examples* as input and
;;; computes *categories* *features* and *domains* automatically.
;;; TODO 1:
;;; macro, which automatically computes *domains*, *categories*
;;; and *features*.

(defmacro create-cat (examples)
  (let ((*categories* (gensym))
        (*domains* (gensym))
        (*features* (gensym)))
  `(progn (setf *categories*
                '(rain no-rain))
          (setf *domains*
                '((outlook (cloudy sunny))
                  (air-pressure (up down stable))
                  (wind-direction (north south))))
          (setf *features*
                '(outlook air-pressure wind-direction)))))

;;; macro needs to be invoked
;;;
(create-cat *examples*)

(defun domain (feature)
  (cadr (assoc feature *domains*)))

(defun example-class (example)
  (cadr example))

(defun example-features (example)
  (car example))

(defun feature-value (index features)
  (nth index features))

;;; If a set of examples contains only one class, it is homogeneous.
;;;
(defun homogeneous-p (examples)
  (= 1
     (length
      (let (result)
        (dolist (ex examples result)
          (pushnew (example-class ex) result))))))

;;; TODO-2: make this function return a random class in case of a tie
;;; (equal frequency of classes)

;;; Which class has highest frequency in the example set
;;;
;;; Sort categories according to count (the category which has
;;; the highest value for 'count'needs to be put in front.
;;;
(defun sort-class (examples)
  (sort
   (mapcar #'(lambda (x)
               (list x (count x examples :key #'example-class)))
           *categories*)
   #'>
   :key #' cadr))

;;; If counts are equal, choose a random category.

(defun majority-class (examples)
  (if (equal (cdar (sort-class *examples*))
             (cdadr (sort-class *examples*)))
      (cadr-of-caar (sort-class *examples*))
    (caar (sort-class *examples*))))


;;; The random-function
;;;

(defun cadr-of-caar (list)
                  (if (= 0 (random 2))
                      (caadr list)
                    (caar list)))


(defun build-decision-tree
       (examples features &optional (default (majority-class examples)))
  (cond ((null examples) nil)
        ((homogeneous-p examples)
         (example-class (car examples)))
        ((null features)
         (majority-class examples))
        (t
         (let ((best-feature
                (find-most-informative-feature examples features)))
           (cons best-feature
                 (mapcar  #'(lambda (value)
                              (let ((new-examples
                                     (find-examples-with-value
                                      best-feature
                                      value
                                      examples)))
                                (if new-examples
                                    (list value
                                          (build-decision-tree
                                           new-examples
                                           (remove
                                            best-feature features)))
                                  (list value default))))
                          (domain best-feature)))))))


;;; Select the subset of examples which has value "value" for feature
;;; "feature"
;;;
(defun find-examples-with-value (feature value examples)
  (let ((result nil)
        (feature-pos (position feature *features*)))
    (dolist (ex examples result)
      (when (equal value (feature-value feature-pos (example-features ex)))
        (push ex result)))))


;;; > (entropy '(0.2 0.8))
;;; 0.7219280948873623
;;; By convention 0 log2 0 = 0
;;;
(defun entropy (distribution)
  (- (apply #'+
            (mapcar #'(lambda (x)
                        (if (= x 0)
                            0
                          (* x (log x 2))))
                    distribution))))


;;; TODO 4: entropy is not calculated when only
;;;         1 feature remains.
;;;
(defun find-most-informative-feature (examples features)
  (cond ((= (count features examples) 1)
         value features)
        (t
         (caar
          (sort
           (compute-average-entropy features examples)
           #'<
           :key #'cadr)))))


;;; > (make-distributions-table '(outlook wind-direction ) *examples*)
;;; (((CLOUDY (3 1)) (SUNNY (0 3))) NIL ((SOUTH (1 2)) (NORTH (2 2))))

(defun make-distributions-table (features examples)
  (let ((feature-value-class-data (make-list (length *features*)))
        (feature-indices
         (mapcar #'(lambda (x)
                     (position x *features*))
                 features)))
    (dolist (ex examples feature-value-class-data)
      (let* ((class (example-class ex))
             (class-pos (position class *categories*))
             (values (example-features ex)))
        (dolist (index feature-indices)
          (let* ((val (feature-value index values))
                 (old-distrib
                  (assoc val
                         (nth index feature-value-class-data))))
            (if old-distrib
                (incf (nth class-pos (cadr old-distrib)))
              (let ((new-distrib
                     (make-list (length *categories*)
                                :initial-element 0)))
                (incf (nth class-pos new-distrib))
                (push (list val new-distrib)
                      (nth index feature-value-class-data))))))))))


;;; > (compute-average-entropy  '(outlook  air-pressure wind-direction )
*examples*)
;;;((WIND-DIRECTION 0.96498394) (AIR-PRESSURE 0.7871107) (OUTLOOK
0.46358752))

(defun compute-average-entropy (features examples)
  (let ((table (make-distributions-table features examples))
        (number-of-examples (length examples))
        (result))
    (dolist (feat features result)
      (let* ((index (position feat *features*))
             (subtable (nth index table))
             (feat-result 0))
        (dolist (val-info subtable
                          (push (list feat feat-result) result))
          (let ((sum (apply #'+ (cadr val-info))))
            (setf feat-result
                  (+ feat-result
                     (* (/ sum number-of-examples)
                        (funcall #'entropy
                                 (mapcar #'(lambda (x)
                                             (/ x sum))
                                         (cadr val-info))))))))))))

(setf *tree* (build-decision-tree *examples* *features*))

;;; Todo-3: write a function that clasifies a pattern of values given
;;; an induced decision tree

;;; > (setf *tree* (build-decision-tree *examples* *features*))
;;; > (classify '(cloudy up north) *tree*)
;;; RAIN


Frames

So far I have only come up with some solution for the TODO1, but even that
doesn't work. The TODO's are at the end.

;;; Here we will collect frames
;;;
(defvar *frames* nil)

;;; Contructor
;;;
(defun defframe (name parents &rest slots)
  (push (list name parents slots)
        *frames*))

;;; Accessors
;;;
(defun getframe (name)
  (assoc name *frames*))

(defun frame-parents (frame)
  (cadr frame))

(defun frame-slots (frame)
  (caddr frame))


;;; TODO-1: define function remove-frame
;;; (remove-frame 'erik) removes all instances of erik from *frames*

;;; Message Passing
;;;

(defun remove-frame (name frame)
(cond ((null frame) '())
 ((equal (caar frame) name)) remove-frame name (cdr frame))
 (t (cons ((car frame) (remove-frame name cdr frame))))))

(defun >> (frame message &rest args)
  (let ((method (find-value frame message)))
    (cond ((demonp method)
           (apply (coerce (second method) 'function)
                  (cons frame args)))
          (t method))))

(defun demonp (method)
  (and (listp method) (eql (car method) :demon)))

;;; Simple inheritance (each frame can only have 1 parent to inherit
;;; from)

(defun find-value (name message)
  (let ((frame (getframe name)))
    (if (not frame)
        (error "Undefined frame ~A" name)
      (let ((information (assoc message (frame-slots frame))))
        (if information
            (cadr information)
          (let ((parents (frame-parents frame)))
            (if (null parents)
                (error "Undefined message ~A for frame ~A" message name)
              (find-value (car parents) message))))))))


;;; TODO-2: Define a multiple-inheritance version of find-value
;;; E.g. (defframe 'nixon '(quaker republican))
;;;      (defframe 'quaker '() '(pacifist t))
;;;      (defframe 'republican '() '(pacifist nil))
;;; Use order-dependence to resolve ambiguity
;;;      > (>> 'nixon 'pacifist)
;;;        T

;;; TODO-3: Define a function "set->>" which you can use to change the
;;; value of a slot in a frame
;;; E.g. (set->> 'erik 'favorite-tv-station 'bbc)
;;;      (>> 'erik 'favorite-tv-station)
;;;      bbc


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

#|
Example


(defframe 'person
          '()
          '(number-of-legs 2)
          '(favorite-tv-station vtm)
          '(age
     (:demon (lambda (x) (- 2001 (>> x 'birthyear))))))

(defframe 'erik
          '(person)
          '(favorite-tv-station canvas)
          '(birthyear 1970))

 > *frames*
((ERIK (PERSON) ((FAVORITE-TV-STATION CANVAS) (BIRTHYEAR 1970)))
 (PERSON
  NIL
  ((NUMBER-OF-LEGS 2)
   (FAVORITE-TV-STATION VTM)
   (AGE (:DEMON (LAMBDA (X) (- 2001 (>> X 'BIRTHYEAR))))))))


> (>> 'erik 'number-of-legs)
2

> (>> 'erik 'favorite-tv-station)
CANVAS

> (>> 'erik 'hair-color)

Error: Undefined message HAIR-COLOR for frame PERSON

> (>> 'erik 'age)
31

> (>> 'walter 'age)

Error: Undefined frame WALTER

> (trace find-value)
(FIND-VALUE)

> (>> 'erik 'age)
0 FIND-VALUE > (ERIK AGE)
  1 FIND-VALUE > (PERSON AGE)
  1 FIND-VALUE < ((:DEMON #))
0 FIND-VALUE < ((:DEMON #))
0 FIND-VALUE > (ERIK BIRTHYEAR)
0 FIND-VALUE < (1970)
31

Example for demons with arguments:

(defframe 'person
          '()
          '(number-of-legs 2)
          '(favorite-tv-station vtm)
          '(age
     (:demon (lambda (x &optional y)
        (- (if y y 2001) (>> x 'birthyear))))))

> (>> 'erik 'age 2005)
35
|#

I know this seems like a lot of work, but I am really desperate. Please help
me, I would be very gratefull.

J.

From: ···············@solibri.com
Subject: Re: frames + decision tree
Date: 
Message-ID: <ubsni9g66.fsf@solibri.com>
"Joerivdv" <···········@hotmail.com> writes:

> (defvar *examples*)
> (defvar *domains*)
> (defvar *categories*)
> (defvar *features*)
> 
> (setf *examples*
>       '(((sunny up north) no-rain)
>         ((cloudy up south) rain)
>         ((cloudy stable north) rain)
>         ((sunny down north) no-rain)
>         ((cloudy down north) rain)
>  ((sunny up south) no-rain)
>         ((cloudy down south) no-rain)))
> 
> ;;; TODO 1: write a function that takes *examples* as input and
> ;;; computes *categories* *features* and *domains* automatically.
> ;;; TODO 1:
> ;;; macro, which automatically computes *domains*, *categories*
> ;;; and *features*.
> 
> (defmacro create-cat (examples)
>   (let ((*categories* (gensym))
>         (*domains* (gensym))
>         (*features* (gensym)))
>   `(progn (setf *categories*
>                 '(rain no-rain))
>           (setf *domains*
>                 '((outlook (cloudy sunny))
>                   (air-pressure (up down stable))
>                   (wind-direction (north south))))
>           (setf *features*
>                 '(outlook air-pressure wind-direction)))))
> 

I fail to see why should this be a macro: you are not doing anything
you couldn't do with a function. Further, why does it have examples as
a parameter when it does nothing with it? Also, this gensym usage
doen't seem to do anything useful: if you are trying to assign stuff
to the global variables *categories* etc, that LET is not helping any.


> ;;; TODO-1: define function remove-frame
> ;;; (remove-frame 'erik) removes all instances of erik from *frames*
> 
> ;;; Message Passing
> ;;;
> 
> (defun remove-frame (name frame)
> (cond ((null frame) '())
>  ((equal (caar frame) name)) remove-frame name (cdr frame))
>  (t (cons ((car frame) (remove-frame name cdr frame))))))

Apart from a missing ( and a superfluous ) on the third line, I'm
wondering where this name parameter came from, as the spec only asked
for frame ?


-- 
From: Joerivdv
Subject: Re: frames + decision tree
Date: 
Message-ID: <3b31f9a3$0$84424$ba620e4c@news.skynet.be>
> I fail to see why should this be a macro: you are not >doing anything you
couldn't do with a function. Further, >why does it have examples as a
parameter when it does >nothing with it? Also, this gensym usage doen't seem
to >do anything useful: if you are trying to assign stuff to the >global
variables *categories* etc, that LET is not helping >any.

We were asked to create a function that uses gensym to automatically create
the global variables in the TODO part. The only way I could get gensym into
the code was by putting them into a macro.

> Apart from a missing ( and a superfluous ) on the third > line, I'm
wondering where this name parameter came
> from, as the spec only asked for frame ?

I have a new version, which does work. The only problem is that the second
argument 'frame' still needs to be in there, whereas we are just allowed to
use 'name'. Could I use *frames* inside the function, without using it as an
argument? Here is the new function:

(defun remove-frame (name frame)
    (cond ((null frame) '())
     ((equal (caar frame) name)
      (remove-frame name (cdr frame)))
    (t (cons (car frame) (remove-frame name(cdrframe))))))

J.
<···············@solibri.com> wrote in message
··················@solibri.com...
> "Joerivdv" <···········@hotmail.com> writes:
>
> > (defvar *examples*)
> > (defvar *domains*)
> > (defvar *categories*)
> > (defvar *features*)
> >
> > (setf *examples*
> >       '(((sunny up north) no-rain)
> >         ((cloudy up south) rain)
> >         ((cloudy stable north) rain)
> >         ((sunny down north) no-rain)
> >         ((cloudy down north) rain)
> >  ((sunny up south) no-rain)
> >         ((cloudy down south) no-rain)))
> >
> > ;;; TODO 1: write a function that takes *examples* as input and
> > ;;; computes *categories* *features* and *domains* automatically.
> > ;;; TODO 1:
> > ;;; macro, which automatically computes *domains*, *categories*
> > ;;; and *features*.
> >
> > (defmacro create-cat (examples)
> >   (let ((*categories* (gensym))
> >         (*domains* (gensym))
> >         (*features* (gensym)))
> >   `(progn (setf *categories*
> >                 '(rain no-rain))
> >           (setf *domains*
> >                 '((outlook (cloudy sunny))
> >                   (air-pressure (up down stable))
> >                   (wind-direction (north south))))
> >           (setf *features*
> >                 '(outlook air-pressure wind-direction)))))
> >
>
> I fail to see why should this be a macro: you are not doing anything
> you couldn't do with a function. Further, why does it have examples as
> a parameter when it does nothing with it? Also, this gensym usage
> doen't seem to do anything useful: if you are trying to assign stuff
> to the global variables *categories* etc, that LET is not helping any.
>
>
> > ;;; TODO-1: define function remove-frame
> > ;;; (remove-frame 'erik) removes all instances of erik from *frames*
> >
> > ;;; Message Passing
> > ;;;
> >
> > (defun remove-frame (name frame)
> > (cond ((null frame) '())
> >  ((equal (caar frame) name)) remove-frame name (cdr frame))
> >  (t (cons ((car frame) (remove-frame name cdr frame))))))
>
> Apart from a missing ( and a superfluous ) on the third line, I'm
> wondering where this name parameter came from, as the spec only asked
> for frame ?
>
>
> --
From: Kent M Pitman
Subject: Re: frames + decision tree
Date: 
Message-ID: <sfwsngtg9uo.fsf@world.std.com>
"Joerivdv" <···········@hotmail.com> writes:

> We were asked to create a function that uses gensym to automatically create
> the global variables in the TODO part. The only way I could get gensym into
> the code was by putting them into a macro.

Actually, just for the record, explicit calls to EVAL or COMPILE are
some other ways.  But you're right that you'd have to be operating at the
meta-level in some way to satisfy what it sounds like the assignment
is.  (Whether or not that's the right assignment for you to have is
another question.)
From: Joerivdv
Subject: Re: frames + decision tree
Date: 
Message-ID: <3b3213ca$0$84425$ba620e4c@news.skynet.be>
So what do you suggest I do to get the equivalent of:

(setf *categories*
      '(rain no-rain))

(setf *domains*
      '((outlook (cloudy sunny))
        (air-pressure (up down stable))
        (wind-direction (north south))))

(setf *features*
      '(outlook air-pressure wind-direction))

presuming that this is also given:

(defvar *examples*)
(defvar *domains*)
(defvar *categories*)
(defvar *features*)

(setf *examples*
      '(((sunny up north) no-rain)
        ((cloudy up south) rain)
        ((cloudy stable north) rain)
        ((sunny down north) no-rain)
        ((cloudy down north) rain)
 ((sunny up south) no-rain)
 ((cloudy down south) no-rain)))

And that the assignment was:

;;; TODO 1: write a function that takes *examples* as input and
;;; computes *categories* *features* and *domains* automatically. (using
gensym).

"Kent M Pitman" <······@world.std.com> wrote in message
····················@world.std.com...
> "Joerivdv" <···········@hotmail.com> writes:
>
> > We were asked to create a function that uses gensym to automatically
create
> > the global variables in the TODO part. The only way I could get gensym
into
> > the code was by putting them into a macro.
>
> Actually, just for the record, explicit calls to EVAL or COMPILE are
> some other ways.  But you're right that you'd have to be operating at the
> meta-level in some way to satisfy what it sounds like the assignment
> is.  (Whether or not that's the right assignment for you to have is
> another question.)
From: Janis Dzerins
Subject: Re: frames + decision tree
Date: 
Message-ID: <87pubx23xg.fsf@asaka.latnet.lv>
"Joerivdv" <···········@hotmail.com> writes:

> So what do you suggest I do to get the equivalent of:
> 
> (setf *categories*
>       '(rain no-rain))
> 
> (setf *domains*
>       '((outlook (cloudy sunny))
>         (air-pressure (up down stable))
>         (wind-direction (north south))))
> 
> (setf *features*
>       '(outlook air-pressure wind-direction))
> 
> presuming that this is also given:
> 
> (defvar *examples*)
> (defvar *domains*)
> (defvar *categories*)
> (defvar *features*)
> 
> (setf *examples*
>       '(((sunny up north) no-rain)
>         ((cloudy up south) rain)
>         ((cloudy stable north) rain)
>         ((sunny down north) no-rain)
>         ((cloudy down north) rain)
>  ((sunny up south) no-rain)
>  ((cloudy down south) no-rain)))
> 
> And that the assignment was:
> 
> ;;; TODO 1: write a function that takes *examples* as input and
> ;;; computes *categories* *features* and *domains* automatically. (using
> gensym).

I wrote couple of functions that do the following:

cl-user(11): *examples*
(((sunny up north) no-rain)
 ((cloudy up south) rain)
 ((cloudy stable north) rain)
 ((sunny down north) no-rain)
 ((cloudy down north) rain)
 ((sunny up south) no-rain)
 ((cloudy down south) no-rain))
cl-user(12): (todo-1 *examples*)
(:categories (rain no-rain)
 :domains ((#:g163 (sunny cloudy))
           (#:g164 (up stable down))
           (#:g165 (north south)))
 :features (#:g163 #:g164 #:g165))

Is that what's required?

If so, then the task is almost like deleting duplicates (just have to
first understand where to delete them from).

I really don't want to do the homework for you. What exactly do you
not understand how to do?

-- 
Janis Dzerins

  If million people say a stupid thing it's still a stupid thing.
From: Thomas A. Russ
Subject: Re: frames + decision tree
Date: 
Message-ID: <ymiu219wn38.fsf@sevak.isi.edu>
Janis Dzerins <·····@latnet.lv> writes:
> > ;;; TODO 1: write a function that takes *examples* as input and
> > ;;; computes *categories* *features* and *domains* automatically. (using
> > gensym).
> 
> I wrote couple of functions that do the following:
> 
> cl-user(11): *examples*
> (((sunny up north) no-rain)
>  ((cloudy up south) rain)
>  ((cloudy stable north) rain)
>  ((sunny down north) no-rain)
>  ((cloudy down north) rain)
>  ((sunny up south) no-rain)
>  ((cloudy down south) no-rain))
> cl-user(12): (todo-1 *examples*)
> (:categories (rain no-rain)
>  :domains ((#:g163 (sunny cloudy))
>            (#:g164 (up stable down))
>            (#:g165 (north south)))
>  :features (#:g163 #:g164 #:g165))
> 
> Is that what's required?

Not having any more data than the rest of the Newsgroup, I would guess
that this is on the right track.  It would seem that Joerivdv's initial
function had the programmer performing the the derivation of categories,
etc. rather than having the system itself do it.

I would expect the goal is to produce a function that can be used with a
different set of examples to come up with analogous answers to what
Janis came up with.











-- 
Thomas A. Russ,  USC/Information Sciences Institute          ···@isi.edu    
From: Joerivdv
Subject: Re: frames + decision tree
Date: 
Message-ID: <3b32f480$0$84424$ba620e4c@news.skynet.be>
That is correct, but I don't know how to use gensym in a function
and what it actually does once you have used it. I have worked
my way through Successful Lisp: How to Understand and Use
Common Lisp by D.B. Lamkins, but I cannot figure out how the
gensym works.

J.

"Thomas A. Russ" <···@sevak.isi.edu> wrote in message
····················@sevak.isi.edu...
> Janis Dzerins <·····@latnet.lv> writes:
> > > ;;; TODO 1: write a function that takes *examples* as input and
> > > ;;; computes *categories* *features* and *domains* automatically.
(using
> > > gensym).
> >
> > I wrote couple of functions that do the following:
> >
> > cl-user(11): *examples*
> > (((sunny up north) no-rain)
> >  ((cloudy up south) rain)
> >  ((cloudy stable north) rain)
> >  ((sunny down north) no-rain)
> >  ((cloudy down north) rain)
> >  ((sunny up south) no-rain)
> >  ((cloudy down south) no-rain))
> > cl-user(12): (todo-1 *examples*)
> > (:categories (rain no-rain)
> >  :domains ((#:g163 (sunny cloudy))
> >            (#:g164 (up stable down))
> >            (#:g165 (north south)))
> >  :features (#:g163 #:g164 #:g165))
> >
> > Is that what's required?
>
> Not having any more data than the rest of the Newsgroup, I would guess
> that this is on the right track.  It would seem that Joerivdv's initial
> function had the programmer performing the the derivation of categories,
> etc. rather than having the system itself do it.
>
> I would expect the goal is to produce a function that can be used with a
> different set of examples to come up with analogous answers to what
> Janis came up with.
>
>
>
>
>
>
>
>
>
>
>
> --
> Thomas A. Russ,  USC/Information Sciences Institute          ···@isi.edu
From: Janis Dzerins
Subject: Re: frames + decision tree
Date: 
Message-ID: <87hex90w0n.fsf@asaka.latnet.lv>
"Joerivdv" <···········@hotmail.com> writes:

> That is correct, but I don't know how to use gensym in a function
> and what it actually does once you have used it. I have worked
> my way through Successful Lisp: How to Understand and Use
> Common Lisp by D.B. Lamkins, but I cannot figure out how the
> gensym works.

Gensym just creates a new (uninterned) symbol. From my understanding
of your task it seems that you have to use gensym to create names for
domains (features) since they cannot be named like in the example.

-- 
Janis Dzerins

  If million people say a stupid thing it's still a stupid thing.
From: Joerivdv
Subject: Re: frames + decision tree
Date: 
Message-ID: <3b3302f8$0$84427$ba620e4c@news.skynet.be>
Can you give an example of how gensym is used
in defining a function?

J.

"Janis Dzerins" <·····@latnet.lv> wrote in message
···················@asaka.latnet.lv...
> "Joerivdv" <···········@hotmail.com> writes:
>
> > That is correct, but I don't know how to use gensym in a function
> > and what it actually does once you have used it. I have worked
> > my way through Successful Lisp: How to Understand and Use
> > Common Lisp by D.B. Lamkins, but I cannot figure out how the
> > gensym works.
>
> Gensym just creates a new (uninterned) symbol. From my understanding
> of your task it seems that you have to use gensym to create names for
> domains (features) since they cannot be named like in the example.
>
> --
> Janis Dzerins
>
>   If million people say a stupid thing it's still a stupid thing.
From: Janis Dzerins
Subject: Re: frames + decision tree
Date: 
Message-ID: <874rt8okzp.fsf@asaka.latnet.lv>
"Joerivdv" <···········@hotmail.com> writes:

> Can you give an example of how gensym is used in defining a
> function?

I don't quite get what your're asking for. If you want a function that
returns something with gensyms in it:

(defun f (n)
  (loop repeat n
     collect (gensym)))

If you want a function whose name is gensym, then ther's more to it --
gensyms are not interned so you can't refer to them by name. I really
don't thing you'd need this.

Anyway -- gensym is a symbol and you can use it's slots:

(let ((f (gensym)))
  (setf (symbol-function f) #'+)
  (list f (funcall f 1 2)))


And -- could you please make something, post it here and ask why it
dosn't work like you intended. Like: "I've got this function, but for
some reason it fails to do this and that although this and that thing
should work like...". Or othrewise I've got the impression you don't
understand event what to ask for.

-- 
Janis Dzerins

  If million people say a stupid thing it's still a stupid thing.
From: Joerivdv
Subject: Re: frames + decision tree
Date: 
Message-ID: <3b32292f$0$84433$ba620e4c@news.skynet.be>
The problem is, how to use gensym and what does it do. If I apply your
function and I write e.g.
CL-user13 : *domains*
do I get:
((outlook (cloudy sunny))
(air-pressure (up down stable))
(wind-direction (north south))) ?

I think your function does what's necessary.

J.


"Janis Dzerins" <·····@latnet.lv> wrote in message
···················@asaka.latnet.lv...
> "Joerivdv" <···········@hotmail.com> writes:
>
> > So what do you suggest I do to get the equivalent of:
> >
> > (setf *categories*
> >       '(rain no-rain))
> >
> > (setf *domains*
> >       '((outlook (cloudy sunny))
> >         (air-pressure (up down stable))
> >         (wind-direction (north south))))
> >
> > (setf *features*
> >       '(outlook air-pressure wind-direction))
> >
> > presuming that this is also given:
> >
> > (defvar *examples*)
> > (defvar *domains*)
> > (defvar *categories*)
> > (defvar *features*)
> >
> > (setf *examples*
> >       '(((sunny up north) no-rain)
> >         ((cloudy up south) rain)
> >         ((cloudy stable north) rain)
> >         ((sunny down north) no-rain)
> >         ((cloudy down north) rain)
> >  ((sunny up south) no-rain)
> >  ((cloudy down south) no-rain)))
> >
> > And that the assignment was:
> >
> > ;;; TODO 1: write a function that takes *examples* as input and
> > ;;; computes *categories* *features* and *domains* automatically. (using
> > gensym).
>
> I wrote couple of functions that do the following:
>
> cl-user(11): *examples*
> (((sunny up north) no-rain)
>  ((cloudy up south) rain)
>  ((cloudy stable north) rain)
>  ((sunny down north) no-rain)
>  ((cloudy down north) rain)
>  ((sunny up south) no-rain)
>  ((cloudy down south) no-rain))
> cl-user(12): (todo-1 *examples*)
> (:categories (rain no-rain)
>  :domains ((#:g163 (sunny cloudy))
>            (#:g164 (up stable down))
>            (#:g165 (north south)))
>  :features (#:g163 #:g164 #:g165))
>
> Is that what's required?
>
> If so, then the task is almost like deleting duplicates (just have to
> first understand where to delete them from).
>
> I really don't want to do the homework for you. What exactly do you
> not understand how to do?
>
> --
> Janis Dzerins
>
>   If million people say a stupid thing it's still a stupid thing.
From: Janis Dzerins
Subject: Re: frames + decision tree
Date: 
Message-ID: <87lmml22lj.fsf@asaka.latnet.lv>
Janis Dzerins <·····@latnet.lv> writes:

> I wrote couple of functions that do the following:
> 
> cl-user(11): *examples*
> (((sunny up north) no-rain)
>  ((cloudy up south) rain)
>  ((cloudy stable north) rain)
>  ((sunny down north) no-rain)
>  ((cloudy down north) rain)
>  ((sunny up south) no-rain)
>  ((cloudy down south) no-rain))
> cl-user(12): (todo-1 *examples*)
> (:categories (rain no-rain)
>  :domains ((#:g163 (sunny cloudy))
>            (#:g164 (up stable down))
>            (#:g165 (north south)))
>  :features (#:g163 #:g164 #:g165))
> 
> Is that what's required?
> 
> If so, then the task is almost like deleting duplicates (just have to
> first understand where to delete them from).
> 
> I really don't want to do the homework for you. What exactly do you
> not understand how to do?

I'm going home so I'm following up my own post with some hints.

1. mapcar is your biggest friend in this task.

(mapcar #'first *examples*)
(mapcar #'second *examples*)

2. (transpose (mapcar #'first *examples))

Result looks like this:

((sunny cloudy cloudy sunny cloudy sunny cloudy)
 (up up stable down down up down)
 (north south north north north south south))

You should write 'transpose' yourself, of course.

3. Look what delete-duplicates does if you haven't yet.

-- 
Janis Dzerins

  If million people say a stupid thing it's still a stupid thing.
From: Joerivdv
Subject: Re: frames + decision tree
Date: 
Message-ID: <3b34bc1e$0$93442$ba620e4c@news.skynet.be>
Ok, this is what I have for transpose:

(defun transpose (list)
       (list(mapcar #'first (mapcar #'first list))
            (mapcar #'second (mapcar #'first list))
            (mapcar #'third (mapcar #'first list))))

I get the input you foretold. Then I wrote:

(defun del-transpose (list)
                   (let ((bla (make-array 3 :initial-contents (transpose
list))))
                     (list (delete-duplicates (aref bla 0))
                            (delete-duplicates (aref bla 1))
                            (delete-duplicates (aref bla 2)))))

Which gets me:
((SUNNY CLOUDY) (STABLE UP DOWN) (NORTH SOUTH))

Is this what you had in mind?

Now I just need to write a function, which uses gensym, and assigns the
values.
This is what I wrote:


(defun create-cat (examples)
  (let* ((outlook (gensym))
         (wind-direction (gensym))
         (air-pressure (gensym)))
    (setf categories (delete-duplicates (mapcar #'second *examples*)))
    (setf features (outlook wind-direction air-pressure))
    (setf domains
          (let* ((blab (make-array 3 :initial-contents (del-transpose
*examples*)))
                 (outlook (aref blab 0))
                 (air-pressure (aref blab 1))
                 (wind-direction (aref blab 2)))
            (list (outlook wind-direction air-pressure))))))

This is what i get:

Variable *categories* is unbound.

Yet if I type
CL-user : categories
I get:
(RAIN NO-RAIN)

I don't understand!!!

"Janis Dzerins" <·····@latnet.lv> wrote in message
···················@asaka.latnet.lv...
> Janis Dzerins <·····@latnet.lv> writes:
>
> > I wrote couple of functions that do the following:
> >
> > cl-user(11): *examples*
> > (((sunny up north) no-rain)
> >  ((cloudy up south) rain)
> >  ((cloudy stable north) rain)
> >  ((sunny down north) no-rain)
> >  ((cloudy down north) rain)
> >  ((sunny up south) no-rain)
> >  ((cloudy down south) no-rain))
> > cl-user(12): (todo-1 *examples*)
> > (:categories (rain no-rain)
> >  :domains ((#:g163 (sunny cloudy))
> >            (#:g164 (up stable down))
> >            (#:g165 (north south)))
> >  :features (#:g163 #:g164 #:g165))
> >
> > Is that what's required?
> >
> > If so, then the task is almost like deleting duplicates (just have to
> > first understand where to delete them from).
> >
> > I really don't want to do the homework for you. What exactly do you
> > not understand how to do?
>
> I'm going home so I'm following up my own post with some hints.
>
> 1. mapcar is your biggest friend in this task.
>
> (mapcar #'first *examples*)
> (mapcar #'second *examples*)
>
> 2. (transpose (mapcar #'first *examples))
>
> Result looks like this:
>
> ((sunny cloudy cloudy sunny cloudy sunny cloudy)
>  (up up stable down down up down)
>  (north south north north north south south))
>
> You should write 'transpose' yourself, of course.
>
> 3. Look what delete-duplicates does if you haven't yet.
>
> --
> Janis Dzerins
>
>   If million people say a stupid thing it's still a stupid thing.
From: Janis Dzerins
Subject: Re: frames + decision tree
Date: 
Message-ID: <874rt4bq9w.fsf@asaka.latnet.lv>
"Joerivdv" <···········@hotmail.com> writes:

> Ok, this is what I have for transpose:
> 
> (defun transpose (list)
>        (list(mapcar #'first (mapcar #'first list))
>             (mapcar #'second (mapcar #'first list))
>             (mapcar #'third (mapcar #'first list))))

1. You do (mapcar #'first list) three times. Use LET.
2. Your function does not transpose list, but first element of the
   list.
3. It transposes only 3xN list.

Suggesstions:

Make this function transpose the list it is passed not some
substructure of it.

(defun transpose (list)
  (list (mapcar #'first list)
        (mapcar #'second list)
        (mapcar #'third list)))

Then you could write the call to it like this:

(transpose (mapcar #'first *examples*))

Making the function work for MxN matrices I'll leave up to you.


> I get the input you foretold. Then I wrote:
> 
> (defun del-transpose (list)
>                    (let ((bla (make-array 3 :initial-contents (transpose list))))
>                      (list (delete-duplicates (aref bla 0))
>                             (delete-duplicates (aref bla 1))
>                             (delete-duplicates (aref bla 2)))))
>
> Which gets me:
> ((SUNNY CLOUDY) (STABLE UP DOWN) (NORTH SOUTH))

This would be better:

(defun del-transpose (list)
  (mapcar #'remove-duplicates (transpose list)))

(Sorry, I suggested using DELETE-DUPLICATES, but that should be used
with caution, so you're better off using REMOVE-DUPLICATES).

And you could do without this function using this implementation :)

> Is this what you had in mind?

Almost.

> Now I just need to write a function, which uses gensym, and assigns the
> values.
> This is what I wrote:
> 
> 
> (defun create-cat (examples)
>   (let* ((outlook (gensym))
>          (wind-direction (gensym))
>          (air-pressure (gensym)))
>     (setf categories (delete-duplicates (mapcar #'second *examples*)))
>     (setf features (outlook wind-direction air-pressure))
>     (setf domains
>           (let* ((blab (make-array 3 :initial-contents (del-transpose
> *examples*)))
>                  (outlook (aref blab 0))
>                  (air-pressure (aref blab 1))
>                  (wind-direction (aref blab 2)))
>             (list (outlook wind-direction air-pressure))))))
> 
> This is what i get:
> 
> Variable *categories* is unbound.

Where do you assign anything to *categories*?

> Yet if I type
> CL-user : categories
> I get:
> (RAIN NO-RAIN)
> 
> I don't understand!!!

You should have used DEFPARAMETER or DEFVAR to define a special
variable *categories* (and others you need as well). And then use the
defined variables, not some new ones.

-- 
Janis Dzerins

  If million people say a stupid thing it's still a stupid thing.

P.S. It's already Monday -- did you submit your homewrok already? I
could post my solution (todo-1) if it's so.
From: Joerivdv
Subject: Re: frames + decision tree
Date: 
Message-ID: <3b34e555$0$93443$ba620e4c@news.skynet.be>
I wrote some function that uses gensym
and takes *examples* as its argument.(The transpose and del-transpose
functions are explained in the last mail.)
Here it is:

(defun create-cat (list)
  (let ((outlook (gensym))
        (air-pressure (gensym))
        (wind-direction (gensym)))
    (setf *categories* (delete-duplicates (mapcar #'second *examples*)))
    (setf *domains* (list `(,outlook (car (del-transpose *examples*)))
                                   `(,air-pressure (cadr (del-transpose
*examples*)))
                                   `(,wind-direction (cddr (del-transpose
*examples*)))))
    (setf *features* `(,outlook ,air-pressure ,wind-direction))))

But the big problem is that the car's and cdr's in the *domains* part are
not evaluated.
Instead the programme returns the following for *domains*:

((#:G464 (CAR (DEL-TRANSPOSE *EXAMPLES*))) (#:G465 (CADR (DEL-TRANSPOSE
*EXAMPLES*))) (#:G466 (CDDR (DEL-TRANSPOSE *EXAMPLES*))))

*categories* gives (RAIN NO-RAIN)
*features* gives (#:g464 #:g465 #:g466)
So these are fine.
How can I get the function to eveluate the parts that are just copied
into the *domains* variable?

J.

"Janis Dzerins" <·····@latnet.lv> wrote in message
···················@asaka.latnet.lv...
> Janis Dzerins <·····@latnet.lv> writes:
>
> > I wrote couple of functions that do the following:
> >
> > cl-user(11): *examples*
> > (((sunny up north) no-rain)
> >  ((cloudy up south) rain)
> >  ((cloudy stable north) rain)
> >  ((sunny down north) no-rain)
> >  ((cloudy down north) rain)
> >  ((sunny up south) no-rain)
> >  ((cloudy down south) no-rain))
> > cl-user(12): (todo-1 *examples*)
> > (:categories (rain no-rain)
> >  :domains ((#:g163 (sunny cloudy))
> >            (#:g164 (up stable down))
> >            (#:g165 (north south)))
> >  :features (#:g163 #:g164 #:g165))
> >
> > Is that what's required?
> >
> > If so, then the task is almost like deleting duplicates (just have to
> > first understand where to delete them from).
> >
> > I really don't want to do the homework for you. What exactly do you
> > not understand how to do?
>
> I'm going home so I'm following up my own post with some hints.
>
> 1. mapcar is your biggest friend in this task.
>
> (mapcar #'first *examples*)
> (mapcar #'second *examples*)
>
> 2. (transpose (mapcar #'first *examples))
>
> Result looks like this:
>
> ((sunny cloudy cloudy sunny cloudy sunny cloudy)
>  (up up stable down down up down)
>  (north south north north north south south))
>
> You should write 'transpose' yourself, of course.
>
> 3. Look what delete-duplicates does if you haven't yet.
>
> --
> Janis Dzerins
>
>   If million people say a stupid thing it's still a stupid thing.
From: Tim Moore
Subject: Re: frames + decision tree
Date: 
Message-ID: <9h2uq4$j9u$0@216.39.145.192>
On Sat, 23 Jun 2001, Joerivdv wrote:
> Here it is:
> 
> (defun create-cat (list)
>   (let ((outlook (gensym))
>         (air-pressure (gensym))
>         (wind-direction (gensym)))
>     (setf *categories* (delete-duplicates (mapcar #'second *examples*)))
>     (setf *domains* (list `(,outlook (car (del-transpose *examples*)))
>                                    `(,air-pressure (cadr (del-transpose
> *examples*)))
>                                    `(,wind-direction (cddr (del-transpose
> *examples*)))))
>     (setf *features* `(,outlook ,air-pressure ,wind-direction))))
> 
> But the big problem is that the car's and cdr's in the *domains* part are
> not evaluated.
> Instead the programme returns the following for *domains*:
> 
> ((#:G464 (CAR (DEL-TRANSPOSE *EXAMPLES*))) (#:G465 (CADR (DEL-TRANSPOSE
> *EXAMPLES*))) (#:G466 (CDDR (DEL-TRANSPOSE *EXAMPLES*))))

Try:

(setf *domains* (list `(,outlook ,(car (del-transpose *examples*)))
		      `(,air-pressure ,(cadr (del-transpose *examples*)))
		      `(,wind-direction ,(cddr (del-transpose 
                                                *examples*)))))
Tim
From: Janis Dzerins
Subject: Re: frames + decision tree
Date: 
Message-ID: <87zoawabjb.fsf@asaka.latnet.lv>
Tim Moore <·····@herschel.bricoworks.com> writes:

> On Sat, 23 Jun 2001, Joerivdv wrote:
> > Here it is:
> > 
> > (defun create-cat (list)
> >   (let ((outlook (gensym))
> >         (air-pressure (gensym))
> >         (wind-direction (gensym)))
> >     (setf *categories* (delete-duplicates (mapcar #'second *examples*)))
> >     (setf *domains* (list `(,outlook (car (del-transpose *examples*)))
> >                                    `(,air-pressure (cadr (del-transpose
> > *examples*)))
> >                                    `(,wind-direction (cddr (del-transpose
> > *examples*)))))
> >     (setf *features* `(,outlook ,air-pressure ,wind-direction))))
> > 
> > But the big problem is that the car's and cdr's in the *domains* part are
> > not evaluated.
> > Instead the programme returns the following for *domains*:
> > 
> > ((#:G464 (CAR (DEL-TRANSPOSE *EXAMPLES*))) (#:G465 (CADR (DEL-TRANSPOSE
> > *EXAMPLES*))) (#:G466 (CDDR (DEL-TRANSPOSE *EXAMPLES*))))
> 
> Try:
> 
> (setf *domains* (list `(,outlook ,(car (del-transpose *examples*)))
> 		      `(,air-pressure ,(cadr (del-transpose *examples*)))
> 		      `(,wind-direction ,(cddr (del-transpose 
>                                                 *examples*)))))

Or better yet (until you understand backquote):

(setf *domains* (list (list outlook (car (del-transpose *examples*)))
                      (list air-pressure (cadr (del-transpose *examples*)))
                      (list wind-direction (cddr (del-transpose *examples*)))))

Not to mention calling DEL-TRANSPOSE three times to get the same result.

-- 
Janis Dzerins

  If million people say a stupid thing it's still a stupid thing.
From: Joerivdv
Subject: Re: frames + decision tree
Date: 
Message-ID: <3b35beb8$0$5238$ba620e4c@news.skynet.be>
I found the problem. This is what I have:

(defun transpose (list)
  (list(mapcar #'first (mapcar #'first list))
       (mapcar #'second (mapcar #'first list))
       (mapcar #'third (mapcar #'first list))))


(defun del-transpose (list)
  (let ((bla (make-array 3 :initial-contents (transpose list))))
    (list (delete-duplicates (aref bla 0))
          (delete-duplicates (aref bla 1))
          (delete-duplicates (aref bla 2)))))


(defun create-cat (list)
  (let ((outlook (gensym))
        (air-pressure (gensym))
        (wind-direction (gensym)))
    (setf *categories* (delete-duplicates (mapcar #'second *examples*)))
    (setf *domains* (list `(,outlook ,(car (del-transpose *examples*)))
                          `(,air-pressure ,(cadr (del-transpose
*examples*)))
                          `(,wind-direction ,(cddr (del-transpose
*examples*)))))
    (setf *features* `(,outlook ,air-pressure ,wind-direction))))

This is what I get:

CL-user : *categories*
(RAIN NO-RAIN)

CL-user : *domains*
((#:G477 (SUNNY CLOUDY)) (#:G478 (STABLE UP DOWN)) (#:G479 ((NORTH SOUTH))))

CL-user : *features*
(#:G477 #:G478 #:G479)

I think this is a good solution for
the assignment. Can I do this with a shorter code?
What do you have?
Thanks for the help. Do you have any hints for the
other assignments? (TODO-3 for decision trees = some function named
classify)
(TODO-2 and TODO-3 for frames)??

Thanks again.

greetz,

J.

PS: like the quote.

"Janis Dzerins" <·····@latnet.lv> wrote in message
···················@asaka.latnet.lv...
> Janis Dzerins <·····@latnet.lv> writes:
>
> > I wrote couple of functions that do the following:
> >
> > cl-user(11): *examples*
> > (((sunny up north) no-rain)
> >  ((cloudy up south) rain)
> >  ((cloudy stable north) rain)
> >  ((sunny down north) no-rain)
> >  ((cloudy down north) rain)
> >  ((sunny up south) no-rain)
> >  ((cloudy down south) no-rain))
> > cl-user(12): (todo-1 *examples*)
> > (:categories (rain no-rain)
> >  :domains ((#:g163 (sunny cloudy))
> >            (#:g164 (up stable down))
> >            (#:g165 (north south)))
> >  :features (#:g163 #:g164 #:g165))
> >
> > Is that what's required?
> >
> > If so, then the task is almost like deleting duplicates (just have to
> > first understand where to delete them from).
> >
> > I really don't want to do the homework for you. What exactly do you
> > not understand how to do?
>
> I'm going home so I'm following up my own post with some hints.
>
> 1. mapcar is your biggest friend in this task.
>
> (mapcar #'first *examples*)
> (mapcar #'second *examples*)
>
> 2. (transpose (mapcar #'first *examples))
>
> Result looks like this:
>
> ((sunny cloudy cloudy sunny cloudy sunny cloudy)
>  (up up stable down down up down)
>  (north south north north north south south))
>
> You should write 'transpose' yourself, of course.
>
> 3. Look what delete-duplicates does if you haven't yet.
>
> --
> Janis Dzerins
>
>   If million people say a stupid thing it's still a stupid thing.
From: Janis Dzerins
Subject: Re: frames + decision tree
Date: 
Message-ID: <87vglkab3b.fsf@asaka.latnet.lv>
"Joerivdv" <···········@hotmail.com> writes:

> I found the problem. This is what I have:
> 
> (defun transpose (list)
>   (list(mapcar #'first (mapcar #'first list))
>        (mapcar #'second (mapcar #'first list))
>        (mapcar #'third (mapcar #'first list))))
> 
> 
> (defun del-transpose (list)
>   (let ((bla (make-array 3 :initial-contents (transpose list))))
>     (list (delete-duplicates (aref bla 0))
>           (delete-duplicates (aref bla 1))
>           (delete-duplicates (aref bla 2)))))
> 
> 
> (defun create-cat (list)
>   (let ((outlook (gensym))
>         (air-pressure (gensym))
>         (wind-direction (gensym)))
>     (setf *categories* (delete-duplicates (mapcar #'second *examples*)))
>     (setf *domains* (list `(,outlook ,(car (del-transpose *examples*)))
>                           `(,air-pressure ,(cadr (del-transpose
> *examples*)))
>                           `(,wind-direction ,(cddr (del-transpose
> *examples*)))))
>     (setf *features* `(,outlook ,air-pressure ,wind-direction))))
> 
> This is what I get:
> 
> CL-user : *categories*
> (RAIN NO-RAIN)
> 
> CL-user : *domains*
> ((#:G477 (SUNNY CLOUDY)) (#:G478 (STABLE UP DOWN)) (#:G479 ((NORTH SOUTH))))
> 
> CL-user : *features*
> (#:G477 #:G478 #:G479)
> 
> I think this is a good solution for the assignment. Can I do this
> with a shorter code?
> What do you have?

I hope your teacher is reading this group:

;;; Not the best implementation but will do for this toy task
(defun transpose (list)
  (apply #'mapcar #'list list))

;;; Not the most efficient but will do the task
(defun todo-1 (samples)
  (let ((domain-values (mapcar #'remove-duplicates
                                (transpose (mapcar #'first samples)))))
    (setf *categories* (remove-duplicates (mapcar #'second samples))
          *domains* (mapcar #'(lambda (values)
                                (list (gensym) values))
                            domain-values)
          *features* (mapcar #'first *domains*))))

> Thanks for the help. Do you have any hints for the
> other assignments? (TODO-3 for decision trees = some function named
> classify)
> (TODO-2 and TODO-3 for frames)??

Not yet.

-- 
Janis Dzerins

  If million people say a stupid thing it's still a stupid thing.
From: Joerivdv
Subject: Re: frames + decision tree
Date: 
Message-ID: <3b375c1c$0$5242$ba620e4c@news.skynet.be>
Thanks, your implementation is better,
since it works for *tree* as well, whereas mine
went wrong for that one. I just got a message that I need to
hand the assignments in tomorrow, so you
will probably not be able to help me on such short notice.
However I would like to finish them, even if I can't hand them in.
In the mean time, all help is welcome of course.
Sorry if I bother you with my problems, but I've only been doing
Lisp for two months.

J.

"Janis Dzerins" <·····@latnet.lv> wrote in message
···················@asaka.latnet.lv...
> "Joerivdv" <···········@hotmail.com> writes:
>
> > I found the problem. This is what I have:
> >
> > (defun transpose (list)
> >   (list(mapcar #'first (mapcar #'first list))
> >        (mapcar #'second (mapcar #'first list))
> >        (mapcar #'third (mapcar #'first list))))
> >
> >
> > (defun del-transpose (list)
> >   (let ((bla (make-array 3 :initial-contents (transpose list))))
> >     (list (delete-duplicates (aref bla 0))
> >           (delete-duplicates (aref bla 1))
> >           (delete-duplicates (aref bla 2)))))
> >
> >
> > (defun create-cat (list)
> >   (let ((outlook (gensym))
> >         (air-pressure (gensym))
> >         (wind-direction (gensym)))
> >     (setf *categories* (delete-duplicates (mapcar #'second *examples*)))
> >     (setf *domains* (list `(,outlook ,(car (del-transpose *examples*)))
> >                           `(,air-pressure ,(cadr (del-transpose
> > *examples*)))
> >                           `(,wind-direction ,(cddr (del-transpose
> > *examples*)))))
> >     (setf *features* `(,outlook ,air-pressure ,wind-direction))))
> >
> > This is what I get:
> >
> > CL-user : *categories*
> > (RAIN NO-RAIN)
> >
> > CL-user : *domains*
> > ((#:G477 (SUNNY CLOUDY)) (#:G478 (STABLE UP DOWN)) (#:G479 ((NORTH
SOUTH))))
> >
> > CL-user : *features*
> > (#:G477 #:G478 #:G479)
> >
> > I think this is a good solution for the assignment. Can I do this
> > with a shorter code?
> > What do you have?
>
> I hope your teacher is reading this group:
>
> ;;; Not the best implementation but will do for this toy task
> (defun transpose (list)
>   (apply #'mapcar #'list list))
>
> ;;; Not the most efficient but will do the task
> (defun todo-1 (samples)
>   (let ((domain-values (mapcar #'remove-duplicates
>                                 (transpose (mapcar #'first samples)))))
>     (setf *categories* (remove-duplicates (mapcar #'second samples))
>           *domains* (mapcar #'(lambda (values)
>                                 (list (gensym) values))
>                             domain-values)
>           *features* (mapcar #'first *domains*))))
>
> > Thanks for the help. Do you have any hints for the
> > other assignments? (TODO-3 for decision trees = some function named
> > classify)
> > (TODO-2 and TODO-3 for frames)??
>
> Not yet.
>
> --
> Janis Dzerins
>
>   If million people say a stupid thing it's still a stupid thing.
From: Joerivdv
Subject: Re: frames + decision tree
Date: 
Message-ID: <3b35c706$0$93448$ba620e4c@news.skynet.be>
MAJOR PROBLEM.

This is what I get for *tree* when I use the piece of code
I just wrote:

(#:G464 (CAR NO-RAIN) ((DEL-TRANSPOSE *EXAMPLES*) NO-RAIN))

What I should get is something like:

(OUTLOOK
    (CLOUDY
        (AIR-PRESSURE ((UP NO-RAIN)
                                      (STABLE (WIND-DIRECTION ((NORTH
NO-RAIN)

(SOUTH RAIN))))
                                      (DOWN RAIN)))
    (SUNNY NO-RAIN)))

???

J.
"Janis Dzerins" <·····@latnet.lv> wrote in message
···················@asaka.latnet.lv...
> Janis Dzerins <·····@latnet.lv> writes:
>
> > I wrote couple of functions that do the following:
> >
> > cl-user(11): *examples*
> > (((sunny up north) no-rain)
> >  ((cloudy up south) rain)
> >  ((cloudy stable north) rain)
> >  ((sunny down north) no-rain)
> >  ((cloudy down north) rain)
> >  ((sunny up south) no-rain)
> >  ((cloudy down south) no-rain))
> > cl-user(12): (todo-1 *examples*)
> > (:categories (rain no-rain)
> >  :domains ((#:g163 (sunny cloudy))
> >            (#:g164 (up stable down))
> >            (#:g165 (north south)))
> >  :features (#:g163 #:g164 #:g165))
> >
> > Is that what's required?
> >
> > If so, then the task is almost like deleting duplicates (just have to
> > first understand where to delete them from).
> >
> > I really don't want to do the homework for you. What exactly do you
> > not understand how to do?
>
> I'm going home so I'm following up my own post with some hints.
>
> 1. mapcar is your biggest friend in this task.
>
> (mapcar #'first *examples*)
> (mapcar #'second *examples*)
>
> 2. (transpose (mapcar #'first *examples))
>
> Result looks like this:
>
> ((sunny cloudy cloudy sunny cloudy sunny cloudy)
>  (up up stable down down up down)
>  (north south north north north south south))
>
> You should write 'transpose' yourself, of course.
>
> 3. Look what delete-duplicates does if you haven't yet.
>
> --
> Janis Dzerins
>
>   If million people say a stupid thing it's still a stupid thing.
From: ···············@solibri.com
Subject: Re: frames + decision tree
Date: 
Message-ID: <u66dpaoqz.fsf@solibri.com>
"Joerivdv" <···········@hotmail.com> writes:

> We were asked to create a function that uses gensym to automatically create
> the global variables in the TODO part. The only way I could get gensym into
> the code was by putting them into a macro.

This doesn't make much sense to me, so perhaps that spec was a little
longer than here  mentioned.


> I have a new version, which does work. The only problem is that the second
> argument 'frame' still needs to be in there, whereas we are just allowed to
> use 'name'. Could I use *frames* inside the function, without using it as an
> argument? 

Of course you can, that's what defining them with defvar does.

> Here is the new function:
> 
> (defun remove-frame (name frame)
>     (cond ((null frame) '())
>      ((equal (caar frame) name)
>       (remove-frame name (cdr frame)))
>     (t (cons (car frame) (remove-frame name(cdrframe))))))

Why not use the existing machinery in the language:

(defun remove-frame (name)
  (setq *frames* (delete name *frames* :key #'first)))

Or something like that?

-- 
From: Joerivdv
Subject: Re: frames + decision tree
Date: 
Message-ID: <3b32123c$0$94455$ba620e4c@news.skynet.be>
Thanks, that does the trick.

Instead of  a macro, I could just write a function that does setf for the
different global variables. But how could I use gensym?

About the TODO 3 in the decision tree programme, I need to compare the first
argument in my command line e.g. '(cloudy up north) *tree* with an embedded
list of length 2 in my *tree*. If the arguments are equal, then the cdr of
that list with length 2 is my *category*. How do I match an argument from my
command line with an embedded list of length 2?


<···············@solibri.com> wrote in message
··················@solibri.com...
> "Joerivdv" <···········@hotmail.com> writes:
>
> > We were asked to create a function that uses gensym to automatically
create
> > the global variables in the TODO part. The only way I could get gensym
into
> > the code was by putting them into a macro.
>
> This doesn't make much sense to me, so perhaps that spec was a little
> longer than here  mentioned.
>
>
> > I have a new version, which does work. The only problem is that the
second
> > argument 'frame' still needs to be in there, whereas we are just allowed
to
> > use 'name'. Could I use *frames* inside the function, without using it
as an
> > argument?
>
> Of course you can, that's what defining them with defvar does.
>
> > Here is the new function:
> >
> > (defun remove-frame (name frame)
> >     (cond ((null frame) '())
> >      ((equal (caar frame) name)
> >       (remove-frame name (cdr frame)))
> >     (t (cons (car frame) (remove-frame name(cdrframe))))))
>
> Why not use the existing machinery in the language:
>
> (defun remove-frame (name)
>   (setq *frames* (delete name *frames* :key #'first)))
>
> Or something like that?
>
> --
From: ···············@solibri.com
Subject: Re: frames + decision tree
Date: 
Message-ID: <uu219hirr.fsf@solibri.com>
"Joerivdv" <···········@hotmail.com> writes:

> Instead of  a macro, I could just write a function that does setf for the
> different global variables. But how could I use gensym?

That's the problem with the spec: a straightforward function solution has no
need for a gensym. 


> About the TODO 3 in the decision tree programme, I need to compare the first
> argument in my command line e.g. '(cloudy up north) *tree* with an embedded
> list of length 2 in my *tree*. If the arguments are equal, then the cdr of
> that list with length 2 is my *category*. How do I match an argument from my
> command line with an embedded list of length 2?

This is a little unclear: lists of different lengths are not equal in
the CL EQUAL sense. What does the data structure of your *tree*
actually look like? (I don't have time to try to puzzle it out of the
code.)

-- 
From: Joerivdv
Subject: Re: frames + decision tree
Date: 
Message-ID: <3b322f98$0$84429$ba620e4c@news.skynet.be>
The data structure of the *tree* is a list and looks like:
(OUTLOOK
    (CLOUDY
        (WIND-DIRECTION (NORTH RAIN)
                                            (SOUTH (AIR-PRESSURE (UP RAIN)

(DOWN NO-RAIN)

(STABLE NO-RAIN)))))
    (SUNNY NO-RAIN))

The function classify checks the *tree* to conclude whether it is going to
be RAIN or
NO-RAIN. These are always arguments of an embedded list in *tree* with
length 2.
If I need to classify '(cloudy up north) I figured that I just need to match
the car
of my list I wish to classify with an element of *tree* and see whether it
is the car
of an embedded list in *tree* with length 2 and then return the cdr of that
embedded list.

But actually, this will only work for this particular tree.

In general, I need to match the car of the list I wish to classify with the
car
of some embedded list of *tree*. If that embedded list has length 2, then
return
the cdr of that list. If not, then try to match the next argument of the
list I wish to
classify with the car of an embedded list of the cdr of the list whose car
was matched
by the first element, and so on.

So i need to write some recursive function, but I don't know how. I started
with
sth like this:

(defun classify (list)
    (if (and (equal (car list) (...))
                (= (length ...) 2))
        (cdr ...)
    (classify (cdr list)))



<···············@solibri.com> wrote in message
··················@solibri.com....
> "Joerivdv" <···········@hotmail.com> writes:
>
> > Instead of  a macro, I could just write a function that does setf for
the
> > different global variables. But how could I use gensym?
>
> That's the problem with the spec: a straightforward function solution has
no
> need for a gensym.
>
>
> > About the TODO 3 in the decision tree programme, I need to compare the
first
> > argument in my command line e.g. '(cloudy up north) *tree* with an
embedded
> > list of length 2 in my *tree*. If the arguments are equal, then the cdr
of
> > that list with length 2 is my *category*. How do I match an argument
from my
> > command line with an embedded list of length 2?
>
> This is a little unclear: lists of different lengths are not equal in
> the CL EQUAL sense. What does the data structure of your *tree*
> actually look like? (I don't have time to try to puzzle it out of the
> code.)
>
> --
>
>
>
From: ···············@solibri.com
Subject: Re: frames + decision tree
Date: 
Message-ID: <uofrhhcgg.fsf@solibri.com>
"Joerivdv" <···········@hotmail.com> writes:

> The data structure of the *tree* is a list and looks like:
> (OUTLOOK
>     (CLOUDY
>         (WIND-DIRECTION (NORTH RAIN)
>                                             (SOUTH (AIR-PRESSURE (UP RAIN)
> 
> (DOWN NO-RAIN)
> 
> (STABLE NO-RAIN)))))
>     (SUNNY NO-RAIN))



> In general, I need to match the car of the list I wish to classify with the
> car
> of some embedded list of *tree*. If that embedded list has length 2, then
> return
> the cdr of that list. If not, then try to match the next argument of the
> list I wish to
> classify with the car of an embedded list of the cdr of the list whose car
> was matched
> by the first element, and so on.

Seems too simplistic, you should also check that you are at a leaf
node, i.e. the second element of your embedded list is not another list. 

Further, your arguments are not in the same order in the example as in
your tree, so you have to check all variants; in this case a linear
pass through the argument should be sufficient.

So, you should walk through your tree matching any of the keys in your
current data. Whenever you find a match, restart the walk with the
branch found and your data with the key just found removed.

--