I think [EMAIL PROTECTED] wrote:
> > The difference is that the invisible (not) CE for this rule is
> > different, because it specifies the exact subgoal2's it can generate -
> > i.e., it will only be activated/deactivated with regard to the exact
> > facts (need-subgoal2 bird) or (need-subgoal2 dog) whereas your other rules would
> > also fire for (need-subgoal2 chicken), even though neither of them
> > could cons up a chicken even if they wanted to. The bogus subgoal2
> > thus generated could possibly block a desired one from being
> > asserted. Again, use ppdefrule to see the difference.
> 
> Okay, I see this, but are we agreed that even this reformulation
> doesn't solve my problem?

Yes, we are agreed. It solves only part of it, and not necessarily in
a general way.

> 
> What happenned here was my misunderstanding of something in
> the manual, viz. the placement of 'nil' in certain slots in the
> Jess-generated (need-X) fact. As I realize now, and as is
> the only sensible thing, Jess puts 'nil' in any slot that is not
> yet bound, but it uses any already bound values as they appear in
> the LHS that triggered the backchaining.
> 
> Looking at the ppdefrule, or just thinking clearly about the documentation,
> would have made this obvious. However, for the benefit of those of us 
> who read the manual in a bleary-eyed state at 3am after a long day of 
> hacking, maybe it would be good to state this explicitly <g>.
> (Something like: "Jess places a 'nil' in those slots that are not 
> currently bound..." or something like that). 

Yes, indeed. I think the problem is that most of the manual section on
backward chaining was written in the belief that it would change a lot
before a final release, but the changes never came. I was waiting for
some good feedback (like this!)

> 
> See, my misinterpretation (with reasoning only possible at 3am)
> was along the lines of: "Okay, Jess generates a need-X fact and
> it sticks 'nil' in the fact's slots; so there must not be
> any relationship between the values of those slots in the fact
> that the rule (with need-X on the LHS) asserts, and the need-X
> condition itself. Weird, yes, but maybe it was convenient to
> do it that way." 
> 
> Sigh. My mind is capable of extraordinary flights sometimes.
> 

Well, as the manual doesn't spell things out, this is a perfectly
reasonable conclusion.  

> 
> > More or less, but there is a subtle difference. It's perfectly fine to
> > have 27 rules that all respond to (need-subgoal2 ?). But if one of
> > them sees (need-subgoal2 chicken) it's buggy if it asserts (subgoal2
> > cat); this is what's wrong with boath ground3 and ground4. They need
> > to be sure to assert only the fact that was requested. Alternatively,
> > the 27 cases can only match specific need-subgoal2 facts, and again,
> > can thereby do the right thing as well. Do you understand what I'm
> > saying?
> 
> I do. You're saying that the correct way to express the "ground"
> cases is to enumerate them in the (need-X ...) CE. From a Prolog
> point of view this seems strange, but it is a consequence of
> the mechanism that uses a LHS CE as the backchaining flag. I'm
> okay with that.

That's one way. There's another way, which is to do it on the rule
RHS. That's my first 27 rules case above: you don't enumerate the case
on the LHS - you simply match a variable ?x. But then on the RHS you use
some other criteria to decide how to satisfy (need-X ?x) The important
point is that Jess tries to hand you some information and your rules
have to use it.

> 
> But I'm still confused about the role of the 'nil's, and their
> relation to the automatically generated (not...) CE.
> 
> My revised understanding is that a condition of the form "(need-X nil)" 
> is intended to indicate the need for a fact with head X and some (any)
> value in the next slot.

Yes.

> 
> If that interpretation is correct, then what I meant to say was:
> 
> (do-backward-chaining the-goal)
> (do-backward-chaining subgoal1)
> (do-backward-chaining subgoal2)
>  
> (defrule main 
>         (the-goal ?a) 
> =>
>         (printout t "You won!" crlf) 
> ) 
>  
>  
> (defrule support 
>         (need-the-goal nil)
>         (subgoal1 ?animal) 
>         (subgoal2 ?animal) 
> => 
>         (the-goal ?animal) 
> ) 
>  
> (defrule ground1
>         (need-subgoal1 nil)
> =>
>         (assert (subgoal1 bird))
> )
>  
> (defrule ground2 
>         (need-subgoal1 nil)
> => 
>         (assert (subgoal1 cat ))
> )
>  
> (defrule ground3
>         (need-subgoal2 nil)
> =>
>         (assert (subgoal2 bird))
> )
>  
> (defrule ground4 
>         (need-subgoal2 nil)
> =>
>         (assert (subgoal2 dog))
> )
> 
> But note that in this case, the automatically added 'not' CE
> is of the form (for example)
> 
>       (not (need-subgoal1 nil))
> 
> which doesn't serve the purpose of ensuring only one firing:
> 
> Jess> (reset)
>  ==> f-0 (initial-fact)
>  ==> f-1 (need-the-goal nil)
>  ==> f-2 (need-subgoal1 nil)
> ==> Activation: ground1 :  f-2,
> ==> Activation: ground2 :  f-2,
> TRUE
> Jess> (run)
> FIRE 1 ground2 f-2,
>  ==> f-3 (subgoal1 cat)
>  ==> f-4 (need-subgoal2 cat)
> FIRE 2 ground1 f-2,
>  ==> f-5 (subgoal1 bird)
>  ==> f-6 (need-subgoal2 bird)
> 2
> Jess> 
> 
> Plus, the chaining to rules ground3 and ground4 doesn't occur.
> 
> Similarly, if I use the formulation you suggested, namely:
> 
> (defrule main
>         (the-goal ?a)
> =>
>         (printout t "You won!" crlf)
> )
> 
> (defrule support
>         (need-the-goal ?animal)
>         (subgoal1 ?animal)
>         (subgoal2 ?animal)
> =>
>         (the-goal ?animal)
> )
>  
> (defrule ground1and2
>         (need-subgoal1 ?x&bird|cat)
> =>
>         (assert (subgoal1 ?x))
> )
>  
> (defrule ground3and4
>         (need-subgoal2 ?x&bird|dog)
> =>
>         (assert (subgoal2 ?x))
> )
>  
> the following (nothing) happens:
> 
> Jess> (reset)
>  ==> f-0 (initial-fact)
>  ==> f-1 (need-the-goal nil)
>  ==> f-2 (need-subgoal1 nil)
> TRUE
> Jess> (run)
> 0
> 
> So I remain confused about the nils.
> 
> (None of which has anything to do with a way of providing backtracking,
> but I want to make sure I understand the way backchaining currently
> works.)
> 

But notice what happens if we modify defrule main like this:

(defrule main
  (possible-goal ?a)
  (the-goal ?a)
  =>
  (printout t "You won!" crlf)
  )

and add the following deffacts:

(deffacts possible-goal
  (possible-goal bird)
  (possible-goal cat)
  (possible-goal dog))

Now the-goal is eventually satisfied, and all the possible goals are
explored to some extent. The reason this works and the previous setup
did not is that the old main would generate (need-X nil) facts, while
the "ground rules" would only match (need-X bird), etc. In the present
case, all the facts contain specific animal names, so the ground rules
match them.

But you are right in your original conclusion that Jess doesn't do
general "backtracking" as Prolog does; I guess this is a clearer
formulation (for me) of where it is that people are confused about
Jess' behaviour.
 

> Sidney
> 
> 
> Sidney Bailin
> Knowledge Evolution, Inc.



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