Hi,
First of all, thanks for you rapid and good answer.
However, I would like to give you some precision, which leads, in my
opinion, to a problem.
To avoid confusion between the notion of ancestor and descendant, I would
like to take another (very similar) example :
in my knowledge base, I'm going to define a sequence of numbers, saying that
1 is just before 2, 2 is just before 3..., and 5 just before 6.
My (first) goal is to define a rule set to calculate what is smaller than 4.
I'm of course, interested in using backward chaining (I know, this is
probably not the simplest way, but I want to make sure that I understand
correctly this behaviour)
Here is my code, directly adapted from yours :
; -----------------------------------------------
; ----- SmallerThan.txt -------------
; -----------------------------------------------
(do-backward-chaining SmallerThan)
(defrule print-smallerthan-4
(SmallerThan ?x 4)
=>
(printout t ?x " is smaller than " 4 crlf))
(defrule create-smallerthan1
(need-SmallerThan ? ?y)
?p <- (IsJustBefore ?x ?y)
=>
(assert (SmallerThan ?x ?y)))
(defrule create-smallerthan2
(SmallerThan ?x ?y)
(IsJustBefore ?z ?x)
=>
(assert(SmallerThan ?z ?y)))
(reset)
(assert (IsJustBefore 1 2))
(assert (IsJustBefore 2 3))
(assert (IsJustBefore 3 4))
(assert (IsJustBefore 4 5))
(assert (IsJustBefore 5 6))
(run)
; -----------------------------------------------
The execution will be :
Jess> (batch smallerthan.txt)
1 is smaller than 4
2 is smaller than 4
3 is smaller than 4
6 Jess> (facts)
f-0 (initial-fact)
f-1 (need-SmallerThan nil 4)
f-2 (need-SmallerThan nil nil)
f-3 (IsJustBefore 1 2)
f-4 (IsJustBefore 2 3)
f-5 (IsJustBefore 3 4)
f-6 (IsJustBefore 4 5)
f-7 (IsJustBefore 5 6)
f-8 (SmallerThan 3 4)
f-9 (SmallerThan 2 4)
f-10 (SmallerThan 1 4)
For a total of 11 facts.
Jess>
At this point, no problem, everything works perfectly well.
The next test I would like to do is to calculate what is greater than 4,
using (if possible) the same rule set except of course the rule
print-smallerthan-4 that I replace by the following one :
; --------------------------------------------
(defrule print-greaterthan-4
(SmallerThan 4 ?x)
=>
(printout t ?x " is greater than " 4 crlf))
; --------------------------------------------
Unfortunatly, it doesn't do what I originally was expected. It is absolutely
normal because
* smaller than is equivalent to
x<y and z+1<x => z<y (which is exactly my code)
* greater than is equivalent to
z<x and x+1=y => z<y (which is not my code)
This point is important to me, because it shows that Jess doesn't behave
like Prolog in this respect.
isJustBefore(1,2).
isJustBefore(2,3).
isJustBefore(3,4).
isJustBefore(4,5).
isJustBefore(5,6).
smallerThan(X,Y):-
isJustBefore(X,Y).
smallerThan(X,Z):-
isJustBefore(X,Y),
smallerThan(Y,Z).
In this case, a question like smallerThan(X,4) returns 1 2 3 and
smallerThan(4,X) returns 5 6.
I thought that this precision was important and would be happy to get any
comment on that.
Claude.
-----Message d'origine-----
De : friedman_hill ernest j [mailto:[EMAIL PROTECTED]]
Envoye : lundi 29 janvier 2001 16:58
A : Claude CAUVET
Cc : [EMAIL PROTECTED]
Objet : Re: JESS: Pb with backward chaining
Hi,
I imagine that no-one answered this the first time you posted it
because it isn't perfectly clear what you're trying to accomplish or
what problem you're having; you've confused the english words
"ancestor" (an older relation -- a parent, grandparent, etc) with
"descendant" ( a younger relative -- a child, grandchild, etc.) I'll
try to guess what your emaning is and answer your question anyway.
First of all, your program is written to compute all ancestors, then
(perhaps?) only print out the ones of interest; if that's all you
want, it would be much easier to write this as a forward-chaining
program:
----------------------------------------------------------------------
(deffacts relations
(Parent P P1)
(Parent P1 P11)
(Parent P11 P111))
(defrule parent-is-ancestor
(Parent ?individual ?parent)
=>
(assert (Ancestor ?individual ?parent)))
(defrule ancestor-of-ancestor-is-ancestor
(Ancestor ?individual ?ancestor)
(Ancestor ?ancestor ?distant-ancestor)
=>
(assert (Ancestor ?individual ?distant-ancestor)))
(defrule display-descendants-of-P11
(Ancestor ?P P11)
=>
(printout t ?P " is a descendant of P11."))
----------------------------------------------------------------------
But if you really want to do it as backward chaining, then here's a
corrected version of your program
(do-backward-chaining Ancestor)
(defrule print-ancestor-P11
(Ancestor ?x P11)
=>
(printout t ?x " is a descendant of " P11 crlf))
(defrule create-ancestor1
(need-Ancestor ? ?y)
?p <- (Parent ?x ?y)
=>
(printout t "1-Calculating descendant of " ?y crlf)
(assert (Ancestor ?x ?y)))
(defrule create-ancestor2
(Ancestor ?x ?y)
(Parent ?z ?x)
=>
(printout t "2-Calculating descendant of " ?z crlf)
(assert(Ancestor ?z ?y)))
(reset)
(assert (Parent P P1))
(assert (Parent P1 P11))
(assert (Parent P11 P111))
(run)
----------------------------------------------------------------------
The important things are first, to be specific about the patterns you
want to backchain on (hence the change to create-ancestor1 -- you only
want it to fire for one certain ancestor) and to not indicate
something is a goal satisfying rule unless it really needs to be
(hence the change to create-ancestor2 -- you always want it to fire.)
I think Claude CAUVET wrote:
[Charset iso-8859-1 unsupported, filtering to ASCII...]
> Hi,
>
> I'm actually evaluating Jess and have a problem with backward chaining.
>
> Here is what I want to solve: I want to "calculate" in a backward chaining
> manner the ancestors of an individual.
>
> My facts are something like
>
> (Parent P P1)
> (Parent P1 P11)
> (Parent P11 P111)
>
> and so, I would like to get the ancestors of P11. Thus, after executing my
> rules, I would like to get those new facts :
>
> (Ancestor P P11)
> (Ancestor P1 P11)
>
> Thanks for your help.
> Claude.
>
> Here is my complete code :
>
> ; =====================================
> ; file name : testbw.txt
> ; =====================================
> (do-backward-chaining Ancestor)
>
> (defrule print-ancestor-P11
> (Ancestor ?x P11)
> =>
> (printout t "Done." crlf)
> )
>
> (defrule create-ancestor1
> (need-Ancestor $?)
> (Parent ?x ?y)
> =>
> (printout t "1-Calculating ancestor of " ?y crlf)
> (assert(Ancestor ?x ?y))
> )
>
> (defrule create-ancestor2
> (need-Ancestor $?)
> (Ancestor ?x ?y)
> (Parent ?y ?z)
> =>
> (printout t "2-Calculating ancestor of " ?z crlf)
> (assert(Ancestor ?x ?z))
> )
>
> (reset)
> (assert (Parent P P1))
> (assert (Parent P1 P11))
> (assert (Parent P11 P111))
> (run)
>
> ; =====================================
>
>
> Here is the trace of the execution :
>
> Jess> (batch mydata/testbw.txt)
> 1-Calculating ancestor of P111
> 1 Jess> (facts)
> f-0 (initial-fact)
> f-1 (need-Ancestor nil P11)
> f-2 (need-Ancestor nil nil)
> f-3 (Parent P P1)
> f-4 (Parent P1 P11)
> f-5 (Parent P11 P111)
> f-6 (Ancestor P11 P111)
> For a total of 7 facts.
> Jess>
>
>
> ---------------------------------------------------------------------
> 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]
---------------------------------------------------------------------