Hi Chuck,

As in all pursuits, you should choose the right tool for the
right job. Prolog and a Rete-based system like Jess are very
different.  The central concept in Prolog is backwards chaining: given
the rules human(Socrates) and mortal(X) :- human(X), you might be
interested in knowing mortal(Socrates). Prolog uses the rules to find
it by looking for human(Socrates). Note that if you "forget" this and
ask for it again, Prolog has to compute it again.

The central concept in Jess, though, is forwards chaining. Here, you
have (human Socrates) and (defrule mortal (human ?X) => (assert
(mortal ?X))). You don't want to know (mortal Socrates), but rather
you want to know what happens given that (human Socrates) is
known. (mortal Socrates) is a result. After the rule has fired,
(mortal Socrates) is known, and the rule "mortal" never has to assert
this fact again.

One more difference is that Prolog is really meant to be used from the
console; i.e., you're actually supposed to sit down and type
"mortal(Socrates)." In Jess, only developers do this; the command line
is not intended for end-users. Prolog is really about answering queries,
while Jess is about acting in response to inputs.

Jess is different than some Rete-based systems in that it includes
both a kind of backwards chaining (see manual section 2.8.1.9) and a
construct called a "defquery" which you've already discovered. Both of
these help Jess a better fit for Prolog applications, but they don't
make Jess into a Prolog-like system. Prolog is optimized, in a sense,
for space, at the cost of speed. Jess (and its Rete algorithm) is
optimized for speed at the cost of space. The Rete algorithm is all
about computing things -once- so they never need to be
recomputed. Prolog approach is more interested in exploring large
numbers of possibilities once, while Rete is aimed at exploring
medium-sized number of possibilities repeatedly.

Regarding ways to express relationships: Jess offers a rich set of
possiblities. Here's one in which the mortality is encoded directly
into the facts, so it never needs to be computed at all:

(deftemplate being (slot name))
(deftemplate mortal extends being)
(deftemplate immmortal extends being)
(deftemplate monster extends mortal)
(deftemplate human extends mortal)
(deftemplate god extends immortal)

(defrule list-all-humanoids
  ;; fire for all beings, gods, monsters, and humans
  (being (name ?n))
  =>
  (printout  ?n " is a being " crlf))

(defrule list-all-mortals
  ;; fires only for mortal things      
  (mortal (name ?n))
  =>
  (printout  ?n " is mortal " crlf))

Here's another that's closer in spirit to the Prolog example.

(deftemplate thing (slot type) (slot name))

(deffacts things
  (thing (type human) (name Socrates))
  (thing (type mineral) (name Slate))
  (thing (type vegetable) (name Carrot))
  (thing (type dog) (name Rover))
  (thing (type human) (name Bob)))

(deffacts mortality
  (mortal human)
  (mortal dog))

(defrule list-all-mortals
  ;; fires for dogs and humans
  (mortal ?type)
  (thing (type ?type) (name ?n))       
  =>
  (printout t ?n " is mortal." crlf))      

So there's one fact that expresses that humans are mortal, and one for
each human known. No "extra" facts are generated. Nevertheless, the
mortality of Socrates is remembered and may be used to optimize some
later computation.

Hope this helps.

I think [EMAIL PROTECTED] wrote:
> 
> 
> Please forgive me if this is a misguided missive.  I am trying to understand how
> to use a rule based system, and as such I am sure I am operating under many
> misunderstandings and misconceptions.  I am trying to clear them up, and I would
> appreciate any corrections to my thoughts below.
> 
> I have played around a bit with Prolog.  As a basic example, I understand if I
> have these facts and rules:
> 
>      human(Socrates)
>      mortal(X) :- human(X)
> 
> Then, I can ask the Prolog engine is Socrates mortal by stating
> "mortal(Socrates)" at the engine prompt, and it will respond with "yes".  I can
> also ask it for all the known mortals with the statement "mortal(X)", and it
> will respond with "Socrates".
> 
> I was then thinking how I would do this using Jess.  I believe I would use the
> deffact of
> 
>      (deffact myfacts (human Socrates))
> 
> and the defrule of
> 
>      (defrule universal-truth  ((human ?x) => (assert (mortal ?x))))
> 
> To find all the mortals, I can define a defquery
> 
>       (defquery all-mortals  (mortals ?x))
> 
> (Sorry, the syntax may be a bit off.  I'm not too worried about that.  I don't
> necessarily need responses correcting that.  That's easy to fix and understand.
> It's the concepts that I'm trying to address.)
> 
> Then, do a (reset) and a (run).
> 
> Then execute the defquery with the statement
> 
>      (bind ?e (run-query all-mortal))
> 
> and use an iteration of ?e to get all the results.  (The Jess Language manual
> has an example.)
> 
> I believe this is the only way to get a similiar functionality to the Prolog
> query "mortal(X)".
> 
> If that is true, what troubles me about it is the defrule.  It basically adds
> new facts to the set of facts.  What this means to me is if I have a set of 100
> "human" facts, after I do the (reset), I now have an additional 100 "mortal"
> facts, doubling the number of facts.  And if I have some other rule about
> humans, it would also add another 100 facts.
> 
> This may be considered a feature (because when the new facts are asserted, it
> may cause other rules to fire), or it may be just a result of the
> implementation.  But, also, In some ways (from one particular angle of view),
> these asserted facts can be considered "pollution"
> 1.  They take up space.
> 2.  They take up time to generate.
> 3.  If I remove a human fact, the corresponding mortal fact remains.  I have to
> specifically perform extra steps to get rid of it.
> 
> In the Prolog implementation, issues 3 is not an issue.  There can be a minor
> argument about whether Prolog has issues 1 and 2, but definitely, Prolog will
> not multiply the number of facts by the number of rules like Jess does.
> 
> So is there a way to express relationships between facts (ie if X is human, then
> X is also mortal) without having the relationship specifically stated as a fact
> for each candidate of the relationship (ie "(human Socrates)", "(mortal
> Socrates)", "(human Chuck)", "(mortal Chuck)", etc.)?
> 
> Chuck Sterbis
> Senior Programmer/Analyst
>  Denniston & Denniston, Inc.
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, send the words 'unsubscribe jess-users [EMAIL PROTECTED]'
> in the BODY of a message to [EMAIL PROTECTED], NOT to the
> list (use your own address!) List problems? Notify [EMAIL PROTECTED]
> ---------------------------------------------------------------------
> 



---------------------------------------------------------
Ernest Friedman-Hill  
Distributed Systems Research        Phone: (925) 294-2154
Sandia National Labs                FAX:   (925) 294-2234
Org. 8920, MS 9012                  [EMAIL PROTECTED]
PO Box 969                  http://herzberg.ca.sandia.gov
Livermore, CA 94550
---------------------------------------------------------------------
To unsubscribe, send the words 'unsubscribe jess-users [EMAIL PROTECTED]'
in the BODY of a message to [EMAIL PROTECTED], NOT to the
list (use your own address!) List problems? Notify [EMAIL PROTECTED]
---------------------------------------------------------------------

Reply via email to