I'm trying to define a function which searches my knowledge base. This
is what I have so far:
(defun search-kb (pattern kb)
(cond (kb
(match pattern (car kb))
(search-kb pattern (cdr kb)))))
match is another function which checks if the two patterns match,
pattern is the user inputed pattern such as (likes phred roses), and kb
is the knowledge base of facts, such as (likes phred roses) etc.
Now my problem is this. Once it finds a pattern that matches the
knowledge base, it still keeps searching the kb and ultimately returns
nil (unless it matches the last pattern in the kb). How can I make the
function stop and return true when it matches a pattern?
I tried this:
(defun search-kb (pattern kb)
(cond (kb
(cond (match pattern (car kb))
(search-kb pattern (cdr kb))))))
but that doesn't seem to work, and gives me an error message. I'm not
sure if you can do nested cond's anyway.
Any suggestions will be appreciated.
Thanks.
--
Mel
Please post reply to newsgroup. Reply address isn't valid.
On Thu, Nov 14, 2002 at 12:18:31PM +1030, arien wrote:
> I'm trying to define a function which searches my knowledge base. This
> is what I have so far:
>
> (defun search-kb (pattern kb)
> (cond (kb
> (match pattern (car kb))
> (search-kb pattern (cdr kb)))))
>
>
> match is another function which checks if the two patterns match,
> pattern is the user inputed pattern such as (likes phred roses), and kb
> is the knowledge base of facts, such as (likes phred roses) etc.
>
> Now my problem is this. Once it finds a pattern that matches the
> knowledge base, it still keeps searching the kb and ultimately returns
> nil (unless it matches the last pattern in the kb). How can I make the
> function stop and return true when it matches a pattern?
You have two base cases here:
* When you've reached the limit of your knowledge-base
(presumably, when kb is nil)
* When you've found a match (when MATCH returns non-nil, perhaps?)
And you have one recursive case:
* When you've not found a match.
The COND special form checks each listed condition and executes the
associated code if and only if the condition is true. It will only
execute the first true case it finds. (Basically, IF-THEN-ELSEIF
performs the same in other languages).
So you simply need to decide appropriate behavior for each case, and
write up a single COND form.
--
; 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: Kenny Tilton
Subject: Re: newbie trying to get function to work
Date:
Message-ID: <3DD30BFE.4090304@nyc.rr.com>
arien wrote:
> I'm trying to define a function which searches my knowledge base. This
> is what I have so far:
>
> (defun search-kb (pattern kb)
> (cond (kb
> (match pattern (car kb))
> (search-kb pattern (cdr kb)))))
>
>
<worse effort snipped>
>
> I'm not
> sure if you can do nested cond's anyway.
Aside: anything can be nested.
>
> Any suggestions will be appreciated.
Multiple forms (match..) and (search-kb...) after the test form in a
cond clause become an implicit progn, meaning both forms get evaluated
(unless match throws or dies). ie, match gets called, its result thrown
away, then regardless search-kb gets called recursively.
Clearly what you were hoping for is that the recursive call happen only
if match failed (and i presume match returns nil if it fails).
So what you have coded, effectively, is:
(progn
'red
'blue)
which returns 'blue. your mission is first to work out how to change
this /explicit/ progn to something else which returns 'red:
(??? 'red 'blue)
red
...and in this case 'blue:
(same??? nil 'blue)
blue
Then fix that cond clause so instead of the implicit progn you use ???.
At which point you can worry about why you have a cond with only one
clause, and look for a simpler way if elegance matters.
--
kenny tilton
clinisys, inc
---------------------------------------------------------------
""Well, I've wrestled with reality for thirty-five years, Doctor,
and I'm happy to state I finally won out over it.""
Elwood P. Dowd
"Coby Beck" <·····@mercury.bc.ca> wrote in message ··················@otis.netspace.net.au...
>
> "Brent Harp" <··········@hotmail.com> wrote in message
> ····························@news20.bellglobal.com...
> >
> >
> > How about:
> >
> > (defun search-kb (pattern kb)
> > (or (match pattern (car kb))
> > (search-kb pattern (cdr kb))))
>
> Wouldn't that recurse forever?
>
Lack of sleep?
OR is not a function, it evaluates its arguments from
left to right until it gets non-nil result.
--
Geoff
"Coby Beck" <·····@mercury.bc.ca> wrote in message ··················@otis.netspace.net.au...
>
> "Brent Harp" <··········@hotmail.com> wrote in message
> ····························@news20.bellglobal.com...
> >
> >
> > How about:
> >
> > (defun search-kb (pattern kb)
> > (or (match pattern (car kb))
> > (search-kb pattern (cdr kb))))
>
> Wouldn't that recurse forever?
It would if the pattern is not in the kb, since then presumably the
match would always return NIL, and there isn't any clause that returns
when kb is NIL. And (cdr nil) => nil, so....
(defun search-kb (pattern kb)
(and kb
(or (match pattern (car kb))
(search-kb pattern (cdr kb)))))
--
Thomas A. Russ, USC/Information Sciences Institute ···@isi.edu
"Geoffrey Summerhayes" <·············@hotmail.com> wrote in message
····························@news20.bellglobal.com...
>
> "Coby Beck" <·····@mercury.bc.ca> wrote in message
··················@otis.netspace.net.au...
> >
> > "Brent Harp" <··········@hotmail.com> wrote in message
> > ····························@news20.bellglobal.com...
> > >
> > >
> > > How about:
> > >
> > > (defun search-kb (pattern kb)
> > > (or (match pattern (car kb))
> > > (search-kb pattern (cdr kb))))
> >
> > Wouldn't that recurse forever?
> >
>
> Lack of sleep?
Too much sleep? ;-)
> OR is not a function, it evaluates its arguments from
> left to right until it gets non-nil result.
I meant if there is no match:
= > (defun search-kb (pattern kb)
(or (match pattern (car kb))
(search-kb pattern (cdr kb))))
SEARCH-KB
= > (defun match (pattern fact)
(equal pattern fact))
MATCH
= > (search-kb 'a '(b c d a e))
T
= > (search-kb 'a '(b c d e))
Stack overflow (stack size 16000).
1 (abort) Return to level 0.
2 Return to top loop level 0.
Type :b for backtrace, :c <option number> to proceed, or :? for other
options
--
Coby Beck
(remove #\Space "coby 101 @ bigpond . com")
"Coby Beck" <·····@mercury.bc.ca> wrote in message ·················@otis.netspace.net.au...
>
>
> I meant if there is no match:
>
> = > (defun search-kb (pattern kb)
> (or (match pattern (car kb))
> (search-kb pattern (cdr kb))))
Ah, so desu. My apologies.
---
Geoff