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.
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."
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.
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."
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.
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."
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.
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.
"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")
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
>
> 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
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
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
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
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.
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
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.
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.
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.
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.
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/