newbie trying to get function to work 
Author Message
 newbie trying to get function to work

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.



Mon, 02 May 2005 09:48:31 GMT  
 newbie trying to get function to work

Quote:

> 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.

--

; 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."



Mon, 02 May 2005 10:25:48 GMT  
 newbie trying to get function to work

Quote:

> 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>

Quote:

>  I'm not
> sure if you can do nested cond's anyway.

Aside: anything can be nested.

Quote:

> 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



Mon, 02 May 2005 10:32:14 GMT  
 newbie trying to get function to work


Quote:
> 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)))))

How about:

(defun search-kb (pattern kb)
    (or (match pattern (car kb))
        (search-kb pattern (cdr kb))))

-mbh



Mon, 02 May 2005 11:53:00 GMT  
 newbie trying to get function to work


Quote:
> 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)))))

Depending on what match returns it can be as simple as

(defun search-kb (pattern kb)
    (find pattern kb :test 'match))

See http://www.lispworks.com/reference/HyperSpec/Body/f_find_.htm

or maybe an iterative version

(defun search-kb (pattern kb)
    (loop for entry in kb
        for match = (match pattern entry)
        when match return match))

The first is probably best, then you do not even have to write search-kb.

Wade



Mon, 02 May 2005 12:58:55 GMT  
 newbie trying to get function to work


Quote:



> > 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)))))

> How about:

> (defun search-kb (pattern kb)
>     (or (match pattern (car kb))
>         (search-kb pattern (cdr kb))))

Wouldn't that recurse forever?

I was thinking:
(defun search-kb (pattern kb)
    (when kb
        (or (match pattern kb)
            (search-kb pattern (cdr kb)))))

but for a loopy version:
(defun search-kb (pattern kb)
   (loop for fact in kb
         do (when (match pattern fact)
               (return fact))))

--
Coby Beck



Mon, 02 May 2005 13:20:26 GMT  
 newbie trying to get function to work

Quote:



> > 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



Tue, 03 May 2005 01:33:10 GMT  
 newbie trying to get function to work


Quote:




Quote:



> > > 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?  ;-)

Quote:
> 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



Tue, 03 May 2005 08:13:37 GMT  
 newbie trying to get function to work

Quote:

> 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



Tue, 03 May 2005 12:00:50 GMT  
 newbie trying to get function to work

Quote:



> > 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)))))

--



Tue, 03 May 2005 07:38:39 GMT  
 
 [ 10 post ] 

 Relevant Pages 

1. Newbie: trying to get GNU Smalltalk to work on win98

2. newbie question on getting Blt to work with Pmw on Windows

3. Need help getting Windows timeSetEvent() timer function to work

4. try gfdg try kuiou try gsdfas try

5. counter function : How works the Set attribute function

6. CW4 Beta 3 -- Still getting errors ? Try This

7. I am getting timeouts trying to access parallel port with VISA

8. Try this if you are having problems getting action out of your joystick

9. Try This. It Truely Works

10. Trying to create image in working directory

11. Just try this, it will work

12. Just try this, it will work

 

 
Powered by phpBB® Forum Software