From: arien
Subject: Struggling with assignment
Date: 
Message-ID: <MPG.189a38f6dae1ad39897e8@news.adl.ihug.com.au>
I'm desperately trying to understand, and complete this assignment. I'm 
just wondering if anyone can give me a few pointers that'll put me in 
the right direction?

At the moment, I'm getting this error message:
Error: Undefined function PATTERN called with arguments

I don't understand cuz 'pattern' shouldn't be a function.
Also, the purpose is to implement subsumption on a type hierarchy so 
that is their isn't a match, then the program will look to see if there 
is a more general match (for example, "likes mary dog" would return 
true).

I've pasted the majority of the code below, and "match" is a function 
which checks the if the two patterns are matching (this function was 
working from an earlier assignment). I will post that code too if it 
helps. But mainly I'm wondering if someone can help me understand how 
the rules are supposed to work, and where it is that I'm going totally 
wrong!

Thanks!

--------------------------------------------
(defun infer (pattern)
  (setq temp-list nil)
  (infer1 (pattern assertions)))


(defun infer1 (pattern kb)                       
  (cond ((rulep (car kb))
         (match (conclusion (car kb)) pattern))
   
        ((listp (car kb))
         (match (car kb) pattern))

        (t 
         (infer1 (pattern (cdr kb))))))
  
        
;knowledge base
(setq assertions
      '((likes phred roses)
        (likes alphonse roses)
        (likes mary dog)
        (likes phred penelope)
        (is-a penelope elephant)
        (is-a penelope gray)
        (is-a dog animal)
        (is-a elephant animal)
       
        (rule if (and (likes (? x) (? z))
                      (likes (? y) (? z)))
              then (friend (? x) (? y)))))


(defun conclusion (rule) (nth 4 rule))

(defun rulep (pattern)
  (and  (listp pattern)
        (equal (nth 0 pattern) 'rule)))
---------------------------------------------


-- 
Mel

Please post reply to newsgroup. Reply address isn't valid.

From: Matthew Danish
Subject: Re: Struggling with assignment
Date: 
Message-ID: <20030123024019.E27240@lain.cheme.cmu.edu>
On Thu, Jan 23, 2003 at 05:38:37PM +1030, arien wrote:
> (defun infer (pattern)
>   (setq temp-list nil)
    ^^^^^^^^^^^^^^^^^^^^
    Presumably you have already defined a variable somewhere named
    TEMP-LIST?  I do not know for sure, but if this is a special
    variable then you should name it using the *'s convention:
    *TEMP-LIST*.

    The same goes for ASSERTIONS, btw, which you should
    (a) define before using it
    (b) define using DEFVAR or DEFPARAMETER; you are not supposed to
        use SETQ to create new variables.
    (c) rename to *ASSERTIONS* because it is a special variable
    

>   (infer1 (pattern assertions)))
            ^^^^^^^^^^^^^^^^^^^^
    This is attempting to call a function named PATTERN (or use a
    macro named PATTERN, etc)

    I suspect the parentheses are superfluous, judging from the
    lambda-list of INFER1.

>         (infer1 (pattern (cdr kb))))))

    Similarly here.


> (defun rulep (pattern)
>   (and  (listp pattern)
>         (equal (nth 0 pattern) 'rule)))

    LISTP will also return T for an argument of NIL, which may or may
    not be desired.  Consider CONSP instead.  You need not use EQUAL
    when comparing a symbol to a symbol, EQL is sufficient.  Generally I
    prefer to use the functions such as FIRST and FIFTH instead of (NTH
    0 ...) and (NTH 4 ...), but it's just a matter of style.

-- 
; Matthew Danish <·······@andrew.cmu.edu>
; OpenPGP public key: C24B6010 on keyring.debian.org
; Signed or encrypted mail welcome.
; "There is no dark side of the moon really; matter of fact, it's all dark."
From: arien
Subject: Re: Struggling with assignment
Date: 
Message-ID: <MPG.189a4935422b886b9897ea@news.adl.ihug.com.au>
In article <·····················@lain.cheme.cmu.edu>, 
·······@andrew.cmu.edu says...
> On Thu, Jan 23, 2003 at 05:38:37PM +1030, arien wrote:
> > (defun infer (pattern)
> >   (setq temp-list nil)
>     ^^^^^^^^^^^^^^^^^^^^
>     Presumably you have already defined a variable somewhere named
>     TEMP-LIST?  I do not know for sure, but if this is a special
>     variable then you should name it using the *'s convention:
>     *TEMP-LIST*.


no I haven't defined a temp-list as a global variable. I only intend 
temp-list to be a temporary variable. Is setq the wrong thing to use in 
this case?

 
>     The same goes for ASSERTIONS, btw, which you should
>     (a) define before using it
>     (b) define using DEFVAR or DEFPARAMETER; you are not supposed to
>         use SETQ to create new variables.
>     (c) rename to *ASSERTIONS* because it is a special variable


I don't quite understand where I should use defvar, since this part was 
given to us, it was straight out of the book???



> >   (infer1 (pattern assertions)))
>             ^^^^^^^^^^^^^^^^^^^^
>     This is attempting to call a function named PATTERN (or use a
>     macro named PATTERN, etc)
> 
>     I suspect the parentheses are superfluous, judging from the
>     lambda-list of INFER1.
> 
> >         (infer1 (pattern (cdr kb))))))
> 
>     Similarly here.

Ah I see my problem here now, thanks! Obviously I'm still falling into 
old habits of putting the brackets around parameters (such as in Java).
Thankyou, I'm getting tired and I didn't find it myself!

 
> > (defun rulep (pattern)
> >   (and  (listp pattern)
> >         (equal (nth 0 pattern) 'rule)))
> 
>     LISTP will also return T for an argument of NIL, which may or may
>     not be desired.  Consider CONSP instead.  You need not use EQUAL
>     when comparing a symbol to a symbol, EQL is sufficient.  Generally I
>     prefer to use the functions such as FIRST and FIFTH instead of (NTH
>     0 ...) and (NTH 4 ...), but it's just a matter of style.

The rulep function was also straight out of the text! I'm confused!
I've only been taught EQ and EQUAL. What is EQL?

-- 
Mel

Please post reply to newsgroup. Reply address isn't valid.
From: Matthew Danish
Subject: Re: Struggling with assignment
Date: 
Message-ID: <20030123054227.F27240@lain.cheme.cmu.edu>
On Thu, Jan 23, 2003 at 06:47:57PM +1030, arien wrote:
> In article <·····················@lain.cheme.cmu.edu>, 
> ·······@andrew.cmu.edu says...
> > On Thu, Jan 23, 2003 at 05:38:37PM +1030, arien wrote:
> > > (defun infer (pattern)
> > >   (setq temp-list nil)
> >     ^^^^^^^^^^^^^^^^^^^^
> >     Presumably you have already defined a variable somewhere named
> >     TEMP-LIST?  I do not know for sure, but if this is a special
> >     variable then you should name it using the *'s convention:
> >     *TEMP-LIST*.
> no I haven't defined a temp-list as a global variable. I only intend 
> temp-list to be a temporary variable. Is setq the wrong thing to use in 
> this case?

Well, SETQ in CL never creates a new variable, it only modifies the
binding of an existing one.

If you want to create a new special variable, use DEFVAR or
DEFPARAMETER.  If you want to introduce a new lexical variable, use LET
or LET*.  Function parameters are also considered to introduce lexical
variables in the scope of the function.

(You can also introduce special variables with LET, but that is a more
advanced matter)

> >     The same goes for ASSERTIONS, btw, which you should
> >     (a) define before using it
> >     (b) define using DEFVAR or DEFPARAMETER; you are not supposed to
> >         use SETQ to create new variables.
> >     (c) rename to *ASSERTIONS* because it is a special variable
> I don't quite understand where I should use defvar, since this part was 
> given to us, it was straight out of the book???

Using SETQ to create variables is an older usage which certain modern
implementations may, or may not, support.  Better to translate it into
the appropriate DEF* form instead.

> > > (defun rulep (pattern)
> > >   (and  (listp pattern)
> > >         (equal (nth 0 pattern) 'rule)))
> >     LISTP will also return T for an argument of NIL, which may or may
> >     not be desired.  Consider CONSP instead.  You need not use EQUAL
> >     when comparing a symbol to a symbol, EQL is sufficient.  Generally I
> >     prefer to use the functions such as FIRST and FIFTH instead of (NTH
> >     0 ...) and (NTH 4 ...), but it's just a matter of style.
> The rulep function was also straight out of the text! I'm confused!
> I've only been taught EQ and EQUAL. What is EQL?

;; crude definition
(defun eql (a b)
  (cond ((and (characterp a)
              (characterp b))
	 (char= a b))
	((and (numberp a)
	      (numberp b))
	 (= a b))
	(t
	 (eq a b))))

The implication being that EQ itself is not sufficient to test equality
of numbers and characters.  For symbols, it does suffice, but in general
you should stick to EQL anyhow, with its stronger notion of object
identity.

(Of course, you should know what EQUAL and EQUALP do as well)

-- 
; Matthew Danish <·······@andrew.cmu.edu>
; OpenPGP public key: C24B6010 on keyring.debian.org
; Signed or encrypted mail welcome.
; "There is no dark side of the moon really; matter of fact, it's all dark."
From: arien
Subject: Re: Struggling with assignment
Date: 
Message-ID: <MPG.189a7c4a88fdea3b9897ee@news.adl.ihug.com.au>
In article <·····················@lain.cheme.cmu.edu>, 
·······@andrew.cmu.edu says...
> On Thu, Jan 23, 2003 at 06:47:57PM +1030, arien wrote:
> > In article <·····················@lain.cheme.cmu.edu>, 
> > ·······@andrew.cmu.edu says...
> > > On Thu, Jan 23, 2003 at 05:38:37PM +1030, arien wrote:
> > > > (defun infer (pattern)
> > > >   (setq temp-list nil)
> > >     ^^^^^^^^^^^^^^^^^^^^
> > >     Presumably you have already defined a variable somewhere named
> > >     TEMP-LIST?  I do not know for sure, but if this is a special
> > >     variable then you should name it using the *'s convention:
> > >     *TEMP-LIST*.
> > no I haven't defined a temp-list as a global variable. I only intend 
> > temp-list to be a temporary variable. Is setq the wrong thing to use in 
> > this case?
> 
> Well, SETQ in CL never creates a new variable, it only modifies the
> binding of an existing one.
> 
> If you want to create a new special variable, use DEFVAR or
> DEFPARAMETER.  If you want to introduce a new lexical variable, use LET
> or LET*.  Function parameters are also considered to introduce lexical
> variables in the scope of the function.
> 
> (You can also introduce special variables with LET, but that is a more
> advanced matter)
> 
> Using SETQ to create variables is an older usage which certain modern
> implementations may, or may not, support.  Better to translate it into
> the appropriate DEF* form instead.

Thankyou for this information. Helps make this a little clearer for me. 
However, I think I will leave it the same as the text book for the 
purposes of this assignment (unless I find it is causing the problems in 
the code), but I just wanted to let you know, I have taken it in.

> 

> 
> ;; crude definition
> (defun eql (a b)
>   (cond ((and (characterp a)
>               (characterp b))
> 	 (char= a b))
> 	((and (numberp a)
> 	      (numberp b))
> 	 (= a b))
> 	(t
> 	 (eq a b))))
> 
> The implication being that EQ itself is not sufficient to test equality
> of numbers and characters.  For symbols, it does suffice, but in general
> you should stick to EQL anyhow, with its stronger notion of object
> identity.
> 
> (Of course, you should know what EQUAL and EQUALP do as well)

oh dear, no I've never heard of EQUALP. *sigh*

Anyway, now I've figured out a bit more of what I'm doing I think. My 
Infer1 code now looks like this:

(defun infer1 (pattern kb)                       
  (cond (kb
         (if (rulep (car kb))
             (if (premise (car kb))
                 (match (conclusion (car kb)) pattern)
               (infer1 pattern (cdr kb)))  
           (if (listp (car kb))
               (or (match (car kb) pattern)
                    (infer1 pattern (cdr kb))))))))

But now I've discovered that these functions don't just check the 
knowledge base automatically:

(defun premise (rule) (nth 2 rule))
(defun conclusion (rule) (nth 4 rule)) 

Would anyone perhaps be able to give me a wee little hint on where I 
start? I don't understand how I make the premise rule, compare with the 
knowledge base, and then bind the variables for use in the conclusion 
rule.
Knowledge base:

(setq *assertions*
      '((likes phred roses)
        (likes alphonse roses)
        (likes mary dog)
        (likes phred penelope)
        (is-a penelope elephant)
        (is-a penelope gray)
        (is-a dog animal)
        (is-a elephant animal)
        (rule if (and (likes (? x) (? z))
                      (likes (? y) (? z)))
              then (friend (? x) (? y)))))


Thanks. I really appreciate these ideas you are giving me!

-- 
Mel

Please post reply to newsgroup. Reply address isn't valid.
From: Matthew Danish
Subject: Re: Struggling with assignment
Date: 
Message-ID: <20030123082941.G27240@lain.cheme.cmu.edu>
On Thu, Jan 23, 2003 at 10:25:49PM +1030, arien wrote:
> oh dear, no I've never heard of EQUALP. *sigh*

http://www-2.cs.cmu.edu/Groups/AI/html/hyperspec/HyperSpec/Body/fun_equalp.html

> Anyway, now I've figured out a bit more of what I'm doing I think. My 
> Infer1 code now looks like this:
> [changed]

 (defun infer1 (pattern kb)                       
   (when kb
     (if (rulep (car kb))
       (if (premise (car kb))
         (match (conclusion (car kb)) pattern)
         (infer1 pattern (cdr kb)))  
       (when (listp (car kb))
         (or (match (car kb) pattern)
             (infer1 pattern (cdr kb))))))))
 
Note the use of WHEN instead of (COND (KB ...)) and IF with a single
case.

Anyhow, I don't know much about the MATCH function you have, but I would
presume that you should use it in combination with the premise and
obtain some bindings from it, which would be substituted by some other
related utility function.

ie.
(let ((bindings (match premise pattern)))
  (sub bindings conclusion))


Let me know if I'm completely off.

-- 
; Matthew Danish <·······@andrew.cmu.edu>
; OpenPGP public key: C24B6010 on keyring.debian.org
; Signed or encrypted mail welcome.
; "There is no dark side of the moon really; matter of fact, it's all dark."
From: arien
Subject: Re: Struggling with assignment
Date: 
Message-ID: <MPG.189aff8b6818cd89897f1@news.adl.ihug.com.au>
In article <·····················@lain.cheme.cmu.edu>, 
·······@andrew.cmu.edu says...
> On Thu, Jan 23, 2003 at 10:25:49PM +1030, arien wrote:
> > oh dear, no I've never heard of EQUALP. *sigh*
> 
> http://www-2.cs.cmu.edu/Groups/AI/html/hyperspec/HyperSpec/Body/fun_equalp.html
> 
> > Anyway, now I've figured out a bit more of what I'm doing I think. My 
> > Infer1 code now looks like this:
> > [changed]
> 
>  (defun infer1 (pattern kb)                       
>    (when kb
>      (if (rulep (car kb))
>        (if (premise (car kb))
>          (match (conclusion (car kb)) pattern)
>          (infer1 pattern (cdr kb)))  
>        (when (listp (car kb))
>          (or (match (car kb) pattern)
>              (infer1 pattern (cdr kb))))))))
>  
> Note the use of WHEN instead of (COND (KB ...)) and IF with a single
> case.

I haven't heard of WHEN? How does it work?

> 
> Anyhow, I don't know much about the MATCH function you have, but I would
> presume that you should use it in combination with the premise and
> obtain some bindings from it, which would be substituted by some other
> related utility function.
> 
> ie.
> (let ((bindings (match premise pattern)))
>   (sub bindings conclusion))


this looks like it might be helpful. I haven't heard of BINDINGS though, 
how is it used?

Match function:

(defun match (template data)
    (cond  ((and (null template) (null data)))
           ((let ((t-item (car template))
                  (d-item (car data)))
            (cond  ((vara t-item)
                      (match (cdr template) (cdr data))
                      (set (cadr t-item) (car data))
                       t)
                   ((equal t-item d-item)
                      (match (cdr template) (cdr data))))
                                                       )))) 


;checks if list contains ?
(defun vara (item)
    (cond
         ((atom item) nil)
         ((eq (car item) '?) t)
         (t nil)))

-- 
Mel

Please post reply to newsgroup. Reply address isn't valid.
From: Barry Margolin
Subject: Re: Struggling with assignment
Date: 
Message-ID: <SkZX9.28$Wh3.2068@paloalto-snr1.gtei.net>
In article <·························@news.adl.ihug.com.au>,
arien  <·············@getlost.invalid> wrote:
>In article <·····················@lain.cheme.cmu.edu>, 
>·······@andrew.cmu.edu says...
>> Note the use of WHEN instead of (COND (KB ...)) and IF with a single
>> case.
>
>I haven't heard of WHEN? How does it work?

It executes the body when the condition is true, just as the name implies.

It's described in CLTL on the same page as IF.

-- 
Barry Margolin, ······@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Coby Beck
Subject: Re: Struggling with assignment
Date: 
Message-ID: <b0q5h4$2u4s$1@otis.netspace.net.au>
"arien" <·············@getlost.invalid> wrote
> > (let ((bindings (match premise pattern)))
> >   (sub bindings conclusion))
>
> this looks like it might be helpful. I haven't heard of BINDINGS though,
> how is it used?

Where your textbooks are doint things like:

(defun foo (a b)
    (setq x (frob b))
    (* (do-things x a) b))

which may really do the equivalent of this (not guaranteed):

(defvar *x*)
(defun foo (a b)
    (setq *x* (frob b))
    (* (do-things *x* a) b))

The proper way (ie create local bindings) if you don't mean x to be global
is:

(defun foo (a b)
    (let ((x (frob b))
        (* (do-things x a) b)))


It is the counterpart of C's:

...
int x;
 (now use x)

But setq is *not* supposed to be the first time you hear of a variable.

--
Coby Beck
(remove #\Space "coby 101 @ bigpond . com")
From: arien
Subject: Re: Struggling with assignment
Date: 
Message-ID: <MPG.189b5014c7f9c0739897f4@news.adl.ihug.com.au>
In article <·························@news.adl.ihug.com.au>, 
·············@getlost.invalid says...
> In article <·····················@lain.cheme.cmu.edu>, 
> ·······@andrew.cmu.edu says...
> > On Thu, Jan 23, 2003 at 10:25:49PM +1030, arien wrote:
> > > oh dear, no I've never heard of EQUALP. *sigh*
> > 
> > http://www-2.cs.cmu.edu/Groups/AI/html/hyperspec/HyperSpec/Body/fun_equalp.html
> > 
> > > Anyway, now I've figured out a bit more of what I'm doing I think. My 
> > > Infer1 code now looks like this:
> > > [changed]
> > 
> >  (defun infer1 (pattern kb)                       
> >    (when kb
> >      (if (rulep (car kb))
> >        (if (premise (car kb))
> >          (match (conclusion (car kb)) pattern)
> >          (infer1 pattern (cdr kb)))  
> >        (when (listp (car kb))
> >          (or (match (car kb) pattern)
> >              (infer1 pattern (cdr kb))))))))
> >  
> > Note the use of WHEN instead of (COND (KB ...)) and IF with a single
> > case.
> 
> I haven't heard of WHEN? How does it work?
> 
> > 
> > Anyhow, I don't know much about the MATCH function you have, but I would
> > presume that you should use it in combination with the premise and
> > obtain some bindings from it, which would be substituted by some other
> > related utility function.
> > 
> > ie.
> > (let ((bindings (match premise pattern)))
> >   (sub bindings conclusion))
> 

Sorry, that was a stupid question! Bindings is a variable, I understand 
that now. I was tired last night, and now I've had some sleep it's a 
little more clear.

I've got another stupid question though, why is there two parentheses 
before 'binding'? I am trying to use this idea (although in a totally 
different way, since the above example cannot work with my code), but 
I'm having problems with the interpreter saying "Warning - Bindings 
assumed special"

I do not want this. I thought using LET is supposed to allow you to use 
temporary variables on the fly?

-- 
Mel

Please post reply to newsgroup. Reply address isn't valid.
From: Larry Clapp
Subject: Re: Struggling with assignment
Date: 
Message-ID: <5pdq0b.m5c.ln@127.0.0.1>
In article <··························@news.adl.ihug.com.au>, arien wrote:
> In article <·························@news.adl.ihug.com.au>, 
> ·············@getlost.invalid says...
>> In article <·····················@lain.cheme.cmu.edu>, 
>> ·······@andrew.cmu.edu says...
>> > Anyhow, I don't know much about the MATCH function you have,
>> > but I would presume that you should use it in combination
>> > with the premise and obtain some bindings from it, which
>> > would be substituted by some other related utility function.
>> > 
>> > ie.
>> > (let ((bindings (match premise pattern)))
>> >   (sub bindings conclusion))
>> 
> 
> Sorry, that was a stupid question! Bindings is a variable, I
> understand that now. I was tired last night, and now I've had
> some sleep it's a little more clear.
> 
> I've got another stupid question though, 

Indeed.  Well, elementary, anyway.

>                                          why is there two
> parentheses before 'binding'? I am trying to use this idea
> (although in a totally different way, since the above example
> cannot work with my code), but I'm having problems with the
> interpreter saying "Warning - Bindings assumed special"
> 
> I do not want this. I thought using LET is supposed to allow
> you to use temporary variables on the fly?

Yes.  Look up LET here:
http://www.lispworks.com/reference/HyperSpec/Body/s_let_l.htm#let:

| let  ({var | (var [init-form])}*) declaration* form* => result*
| let* ({var | (var [init-form])}*) declaration* form* => result*
| [...]
| Description:
| 
| let and let* create new variable bindings and execute a series
| of forms that use these bindings. let performs the bindings in
| parallel and let* does them sequentially.
| 
| The form
| 
|  (let ((var1 init-form-1)
|        (var2 init-form-2)
|        ...
|        (varm init-form-m))
|    declaration1
|    declaration2
|    ...
|    declarationp
|    form1
|    form2
|    ...
|    formn)
| 
| first evaluates the expressions init-form-1, init-form-2, and
| so on, in that order, saving the resulting values. Then all of
| the variables varj are bound to the corresponding values; each
| binding is lexical unless there is a special declaration to the
| contrary. The expressions formk are then evaluated in order;
| the values of all but the last are discarded (that is, the body
| of a let is an implicit progn).
| 
| For both let and let*, if there is not an init-form associated
| with a var, var is initialized to nil."

As you can see, LET accepts a list of variables and initforms as
its first argument.  If you just want to bind the variables to
NIL, you can say

    (let (var1 var2 var3)
        ; code
        )

If you want to bind the variables to some specific value, you have
to say

    (let ((var1 initform1)
          (var2 initform2)
          (var3 initform3))
        ; code
        )

initform can be a constant (e.g. 5), or a function call (e.g.
(random 10)), etc.

Learning to use the HyperSpec would save you a great many of
these elementary questions.

-- Larry
From: arien
Subject: Re: Struggling with assignment
Date: 
Message-ID: <MPG.189b691b96d115029897f5@news.adl.ihug.com.au>
> 
> Learning to use the HyperSpec would save you a great many of
> these elementary questions.
> 

Just one more silly question that the Hyperspec doesn't answer for me 
(as least, not in simple English that I can understand).

Does that mean, that after the last parentheses of the LET block, does 
that mean the variables are no longer bound after this?

ie.

    (let ((var1 initform1)
          (var2 initform2)
          (var3 initform3))
        ; code
        ) ; so after here - var1, var2 and var3 no longer exist?

Thankyou for being patient with these simple questions. No documentation 
on the web seems to spell out some of this stuff clearly when you need 
it to!

Cheers

-- 
Mel

Please post reply to newsgroup. Reply address isn't valid.
From: Larry Clapp
Subject: Re: Struggling with assignment
Date: 
Message-ID: <tvjq0b.e5f.ln@127.0.0.1>
In article <··························@news.adl.ihug.com.au>, arien wrote:
>> Learning to use the HyperSpec would save you a great many of
>> these elementary questions.
> 
> Just one more silly question that the Hyperspec doesn't answer
> for me (as least, not in simple English that I can understand).
> 
> Does that mean, that after the last parentheses of the LET
> block, does that mean the variables are no longer bound after
> this?
> 
> ie.
> 
>     (let ((var1 initform1)
>           (var2 initform2)
>           (var3 initform3))
>         ; code
>         ) ; so after here - var1, var2 and var3 no longer exist?

Correct ... unless var1 (etc) already existed /outside/ the let,
in which case the ending of the LET restores their previous
values.

For example:

    (let ((x 1))
      (print x)
      (let ((x 2))
	(print x))
      (print x))

prints 1, then 2, then 1 again.

In the description for LET, the HyperSpec says "each binding is
lexical unless there is a special declaration to the contrary".

Looking under L in the Glossary (and ignoring the part about
special variables for now) we find:

| lexical binding n. a binding in a lexical environment.

which leads us to

| lexical environment n. that part of the environment that
| contains bindings whose names have lexical scope

which leads us to

| lexical scope n. scope that is limited to a spatial or textual
| region within the establishing form.

which leads us to

| scope n. the structural or textual region of code in which
| references to an object, a binding, an exit point, a tag, or an
| environment (usually by name) can occur.

So, we read that a couple of times  :)  , especially the part
about "within the establishing form", and see that if a LET binds
a variable, that variable exists until the closing right-paren of
the LET.

Let's try looking at the code like the compiler looks at it
(well, sort of like).  That is, as data:

* (defparameter *exp* '(let ((x 1))
			 (print x)
			 (let ((x 2))
			   (print x))
			 (print x)))
*EXP*

* *exp*
(LET ((X 1))
  (PRINT X)
  (LET ((X 2))
    (PRINT X))
  (PRINT X))

* (first *exp*)
LET

* (second *exp*)
((X 1))

* (third *exp*)
(PRINT X)

* (fourth *exp*)
(LET ((X 2))
  (PRINT X))

Similarly:

* (setq *exp* '(let ((x 1) 
		     (y 2))
		 (print x)
		 (let ((x 2))
		   (print x))
		 (print x)))
(LET ((X 1) (Y 2))
  (PRINT X)
  (LET ((X 2))
    (PRINT X))
  (PRINT X))

* (second *exp*)
((X 1) (Y 2))

* (fourth *exp*)
(LET ((X 2))
  (PRINT X))

In both of these examples, the inner LET is just the fourth form
of the outer LET.  The X variable defined in that inner LET lasts
until the end of that same LET.

Going back to your question about "two parentheses before
'bindings'" (which you hopefully understand by now, but just to
drive the point home), in the second example, we see that the
outer LET has /two/ variable bindings: X and Y.  /Both/ bindings
/still/ happen in (second *exp*).  You have to give LET exactly
one /list/ of bindings (no more, no less); that /list/ always
comes right after the LET, and can contain many bindings ... or
none:

    (let ()
      ; code
      )

Observe:

* (setq *exp* '(let () 
		 (print '(hi arien))))
(LET ()
  (PRINT '(HI ARIEN)))

* (second *exp*)
NIL

* (third *exp*)
(PRINT '(HI ARIEN))

* (eval *exp*)
(HI ARIEN) 
(HI ARIEN)

Hope this helps.

-- Larry
From: Marc Spitzer
Subject: Re: Struggling with assignment
Date: 
Message-ID: <868yxbxeul.fsf@bogomips.optonline.net>
arien <·············@getlost.invalid> writes:

> > 
> > Learning to use the HyperSpec would save you a great many of
> > these elementary questions.
> > 
> 
> Just one more silly question that the Hyperspec doesn't answer for me 
> (as least, not in simple English that I can understand).
> 
> Does that mean, that after the last parentheses of the LET block, does 
> that mean the variables are no longer bound after this?
> 
> ie.
> 
>     (let ((var1 initform1)
>           (var2 initform2)
>           (var3 initform3))
>         ; code
>         ) ; so after here - var1, var2 and var3 no longer exist?

yes

> 
> Thankyou for being patient with these simple questions. No documentation 
> on the web seems to spell out some of this stuff clearly when you need 
> it to!

below is a test run from cmucl 18d that shows the behavior you are asking
about:
* (let ((a 'cat)(b 'dog))    
(print a)
(print b))

CAT 
DOG 
DOG
* a

Error in KERNEL::UNBOUND-SYMBOL-ERROR-HANDLER:  the variable A is unbound.

if you were to do this and then reread the definition of let in the hyperspec
you would get several benefits:

1: you would start solving problems that you do not get immediately, real
problems.

2: you would start to learn your tools and thus they make more sense so
you have less stupid questions.  

3: You would build a better reputation in this group, ie has a brain
and is willing to use it.

4: you could ask better questions

5: you would probably get things done faster.

6: you would learn the scientific method, some what

7: later you would be able to do even harder things

marc
From: Henrik Motakef
Subject: Re: Struggling with assignment
Date: 
Message-ID: <87y95bf490.fsf@interim.henrik-motakef.de>
arien <·············@getlost.invalid> writes:

> Does that mean, that after the last parentheses of the LET block, does 
> that mean the variables are no longer bound after this?
> 
> ie.
> 
>     (let ((var1 initform1)
>           (var2 initform2)
>           (var3 initform3))
>         ; code
>         ) ; so after here - var1, var2 and var3 no longer exist?

Sort of. Unless there is another binding "around" this, of course:

| * (progn
|     (let ((var1 :foo))
|       (print var1)) ; LET ends here
|     (princ var1))
| :FOO
| 
| Error in KERNEL::UNBOUND-SYMBOL-ERROR-HANDLER:  the variable VAR1 is unbound.
| 
| Restarts:
|   0: [ABORT] Return to Top-Level.
| 
| Debug  (type H for help)
| ...
| * (progn
|     (let ((var1 :foo))
|       (print var1)
|       (let ((var1 :bar))
| 	  (print var1)) ; inner LET ends,
|       (print var1)))  ; VAR1 has its old value again
| :FOO 
| :BAR 
| :FOO 
| :FOO

hth
Henrik
From: Daniel Barlow
Subject: Re: Struggling with assignment
Date: 
Message-ID: <87r8b48a73.fsf@noetbook.telent.net>
arien <·············@getlost.invalid> writes:

> no I haven't defined a temp-list as a global variable. I only intend 
> temp-list to be a temporary variable. Is setq the wrong thing to use in 
> this case?

Yes.  It seems that you're struggling with assignment when you should
instead be struggling with binding.


-dan

-- 

   http://www.cliki.net/ - Link farm for free CL-on-Unix resources 
From: arien
Subject: Re: Struggling with assignment
Date: 
Message-ID: <MPG.189a65649fbd94999897ec@news.adl.ihug.com.au>
In article <··············@noetbook.telent.net>, ···@telent.net says...
> arien <·············@getlost.invalid> writes:
> 
> > no I haven't defined a temp-list as a global variable. I only intend 
> > temp-list to be a temporary variable. Is setq the wrong thing to use in 
> > this case?
> 
> Yes.  It seems that you're struggling with assignment when you should
> instead be struggling with binding.
> 
> 
> -dan
> 
> 

Actually, I don't really need temp-list anymore. I've taken it out, 
since my change of plans doesn't use it (at the moment at least).

But this doesn't solve my problem at all. I don't really understand a 
lot of the finer details of lisp, and since I have had an extension on 
the assignment (I had a food poisoning incident), there is no one to 
really help me at the moment.

It's so frustrating too when I don't have a proper book on Lisp (we are 
using George F Luger - Artificial Intelligence).

-- 
Mel

Please post reply to newsgroup. Reply address isn't valid.
From: Paolo Amoroso
Subject: Re: Struggling with assignment
Date: 
Message-ID: <VEgwPlbGCjC5Xt4KYyscNCTKBOhT@4ax.com>
On Thu, 23 Jan 2003 20:48:34 +1030, arien <·············@getlost.invalid>
wrote:

> It's so frustrating too when I don't have a proper book on Lisp (we are 

Have a look at this:

  Successful Lisp (by David Lamkins)
  http://psg.com/~dlamkins/sl/contents.html


Paolo
-- 
EncyCMUCLopedia * Extensive collection of CMU Common Lisp documentation
http://www.paoloamoroso.it/ency/README
From: arien
Subject: Re: Struggling with assignment
Date: 
Message-ID: <MPG.189affb355133f179897f2@news.adl.ihug.com.au>
In article <····························@4ax.com>, ·······@mclink.it 
says...
> On Thu, 23 Jan 2003 20:48:34 +1030, arien <·············@getlost.invalid>
> wrote:
> 
> > It's so frustrating too when I don't have a proper book on Lisp (we are 
> 
> Have a look at this:
> 
>   Successful Lisp (by David Lamkins)
>   http://psg.com/~dlamkins/sl/contents.html
> 
> 
> Paolo
> 

Thanks!

-- 
Mel

Please post reply to newsgroup. Reply address isn't valid.
From: arien
Subject: Re: Struggling with assignment
Date: 
Message-ID: <MPG.189a4f5e169385a9897eb@news.adl.ihug.com.au>
In article <·····················@lain.cheme.cmu.edu>, 
·······@andrew.cmu.edu says...
> On Thu, Jan 23, 2003 at 05:38:37PM +1030, arien wrote:
> > (defun infer (pattern)
> >   (setq temp-list nil)
>     ^^^^^^^^^^^^^^^^^^^^
>     Presumably you have already defined a variable somewhere named
>     TEMP-LIST?  I do not know for sure, but if this is a special
>     variable then you should name it using the *'s convention:
>     *TEMP-LIST*.
> 
>     The same goes for ASSERTIONS, btw, which you should
>     (a) define before using it
>     (b) define using DEFVAR or DEFPARAMETER; you are not supposed to
>         use SETQ to create new variables.
>     (c) rename to *ASSERTIONS* because it is a special variable
>     
> 
> >   (infer1 (pattern assertions)))
>             ^^^^^^^^^^^^^^^^^^^^
>     This is attempting to call a function named PATTERN (or use a
>     macro named PATTERN, etc)
> 
>     I suspect the parentheses are superfluous, judging from the
>     lambda-list of INFER1.
> 
> >         (infer1 (pattern (cdr kb))))))
> 
>     Similarly here.
> 
> 
> > (defun rulep (pattern)
> >   (and  (listp pattern)
> >         (equal (nth 0 pattern) 'rule)))
> 
>     LISTP will also return T for an argument of NIL, which may or may
>     not be desired.  Consider CONSP instead.  You need not use EQUAL
>     when comparing a symbol to a symbol, EQL is sufficient.  Generally I
>     prefer to use the functions such as FIRST and FIFTH instead of (NTH
>     0 ...) and (NTH 4 ...), but it's just a matter of style.
> 
> 


Ok, I've edited the infer1 function quite a bit, but I'm still not quite 
getting the desired result. For some reason it's only looking at the 
first list in the knowledge base (likes phred roses) and the rest are 
returning nil.

Oh where am I going wrong now?

(defun infer1 (pattern kb)                       
  (cond (kb
         (if (rulep (car kb))
             (and (match (conclusion (car kb)) pattern)
                  (infer1 pattern (cdr kb)))  
           (if (listp (car kb))
               (and (match (car kb) pattern)
                    (infer1 pattern (cdr kb))))))))

-- 
Mel

Please post reply to newsgroup. Reply address isn't valid.
From: Barry Margolin
Subject: Re: Struggling with assignment
Date: 
Message-ID: <_QTX9.5$Wh3.1492@paloalto-snr1.gtei.net>
In article <·························@news.adl.ihug.com.au>,
arien  <·············@getlost.invalid> wrote:
>Ok, I've edited the infer1 function quite a bit, but I'm still not quite 
>getting the desired result. For some reason it's only looking at the 
>first list in the knowledge base (likes phred roses) and the rest are 
>returning nil.
>
>Oh where am I going wrong now?

Since you use AND, you only recurse on the rest of the KB if MATCH returns
truth.  Is that what you want?

>(defun infer1 (pattern kb)                       
>  (cond (kb
>         (if (rulep (car kb))
>             (and (match (conclusion (car kb)) pattern)
>                  (infer1 pattern (cdr kb)))  
>           (if (listp (car kb))
>               (and (match (car kb) pattern)
>                    (infer1 pattern (cdr kb))))))))

-- 
Barry Margolin, ······@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: arien
Subject: Re: Struggling with assignment
Date: 
Message-ID: <MPG.189afed5a6e314a19897f0@news.adl.ihug.com.au>
In article <················@paloalto-snr1.gtei.net>, ······@genuity.net 
says...
> In article <·························@news.adl.ihug.com.au>,
> arien  <·············@getlost.invalid> wrote:
> >Ok, I've edited the infer1 function quite a bit, but I'm still not quite 
> >getting the desired result. For some reason it's only looking at the 
> >first list in the knowledge base (likes phred roses) and the rest are 
> >returning nil.
> >
> >Oh where am I going wrong now?
> 
> Since you use AND, you only recurse on the rest of the KB if MATCH returns
> truth.  Is that what you want?

No it wasn't :-)
But I've fixed that now!


> 
> >(defun infer1 (pattern kb)                       
> >  (cond (kb
> >         (if (rulep (car kb))
> >             (and (match (conclusion (car kb)) pattern)
> >                  (infer1 pattern (cdr kb)))  
> >           (if (listp (car kb))
> >               (and (match (car kb) pattern)
> >                    (infer1 pattern (cdr kb))))))))
> 
> 



-- 
Mel

Please post reply to newsgroup. Reply address isn't valid.
From: Raymond Wiker
Subject: Re: Struggling with assignment
Date: 
Message-ID: <86lm1cdyc9.fsf@raw.grenland.fast.no>
arien <·············@getlost.invalid> writes:

> I'm desperately trying to understand, and complete this assignment. I'm 
> just wondering if anyone can give me a few pointers that'll put me in 
> the right direction?
> 
> At the moment, I'm getting this error message:
> Error: Undefined function PATTERN called with arguments
> 
> I don't understand cuz 'pattern' shouldn't be a function.

        It isn't, but you are trying to call it as a function. This
happens in the functions infer and infer1, on the last line in both
cases. 

-- 
Raymond Wiker                        Mail:  ·············@fast.no
Senior Software Engineer             Web:   http://www.fast.no/
Fast Search & Transfer ASA           Phone: +47 23 01 11 60
P.O. Box 1677 Vika                   Fax:   +47 35 54 87 99
NO-0120 Oslo, NORWAY                 Mob:   +47 48 01 11 60

Try FAST Search: http://alltheweb.com/