From: arien
Subject: newbie trying to get function to work
Date: 
Message-ID: <MPG.183da4ed7a50ba8f9897c7@news.adl.ihug.com.au>
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.

From: Matthew Danish
Subject: Re: newbie trying to get function to work
Date: 
Message-ID: <20021113212548.S28154@lain.cheme.cmu.edu>
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
From: Geoffrey Summerhayes
Subject: Re: newbie trying to get function to work
Date: 
Message-ID: <s7RA9.12214$QD6.1259782@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?

OR is not a function, it evaluates its arguments from
left to right until it gets non-nil result.

--
Geoff
From: Thomas A. Russ
Subject: Re: newbie trying to get function to work
Date: 
Message-ID: <ymir8dnafi8.fsf@sevak.isi.edu>
"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    
From: Coby Beck
Subject: Re: newbie trying to get function to work
Date: 
Message-ID: <ar1e44$5sk$1@otis.netspace.net.au>
"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")
From: Geoffrey Summerhayes
Subject: Re: newbie trying to get function to work
Date: 
Message-ID: <Vj_A9.14553$QD6.1412798@news20.bellglobal.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