Hmmm! This is pretty interesting. It looks as though a lot of this
could be supported by automatic transformations; i.e., a lot of the
typical goal-seeking rule is "boilerplate," so for instance, this rule
as written below 

 (defrule backch-A-1
        ;
        ; one way to realize goal A
        ;
        ?n <- (need A ?tag ?x ?y ?z)
        (not (failed-attempt A 1 ?tag ?x ?y ?z))
        (not (trying-for A ? ?tag ?x ?y ?z))
 =>
        ;(retract ?n)
        (assert (trying-for A 1 ?tag ?x ?y ?z))
        (assert (need D ?tag ?y))
        (assert (need E ?tag ?x ?y ?z))
 )

could conceivably be generated from the much simpler


 (defrule backch-A-1
        ;
        ; one way to realize goal A
        ;
        (need A ?x ?y ?z)
 =>
        (assert (need D ?y))
        (assert (need E ?x ?y ?z))
 )


The other stuff might be inferred and automatically inserted; maybe we
need a (declare) statement to give some hints, or maybe a
(set-backchain-reactive A) command might be enough.

Thanks for working this out! This will be filed in my "interesting
things to work on" pile.


I think [EMAIL PROTECTED] wrote:
> I've just come back from vacation to find that my past two attempts
> to send this (first to Ernest only, then to the list) have failed.
> So I'm trying again. Perhaps the internet gremlins are so offended
> by what I've done here that they don't want to transmit it.
> 
> It's a bit of jess code that illustrates how backtracking can be
> implemented to support a richer form of backchaining.
> 
> What I've done here is independent of Jess's current backchaining,
> although it follows the basic idea. It is an implementation for a
> specific case, which I devised to cause a couple of backtracks. 
> But the pattern of rules should make it clear how it would be 
> generalized.
> 
> There are three key points:
> 
> 1. Each backward chaining rule - i.e., each Horn clause that you want to
> 
> do backward chaining over - actually needs two Jess rules: one to
> decompose the goal into subgoals (NeedA -> Need B & NeedC), and one 
> to establish (compose) the goal once the subgoals have been established 
> (B & C -> A). My theorem-proving colleague Dave Barker-Plummer pointed 
> out that this corresponds in theorem-proving terms to a) tactics, and 
> b) inference rules.
> 
> 2. There are two fact types, (trying-for ...) and (failed-attempt ...)
> that keep track of the rule and variable binding used  in any particular
> step through the (implicit) search tree. These are negated as CEs in the
> decomposition rules to prevent re-trying something that was already tried, 
> as well as to enable other decomposition rules that haven't yet
> failed.
> 
> The ubiquitous ?tag variable is there in order to keep separate any unrelated 
> backchaining operations that might happen to have some subgoals in common.
> 
> Curiously, if I understand what I have done here, the backtracking over
> choice of rule is effected by the decomposition rules, while backtracking over
> variable bindings is implicitly effected by the composition rules
> (taking advantage of the Rete algorithm).
> 
> 3. The saliences of the cleanup rules and the particular guard (negated)
> CEs were a bear to arrive at, and the whole thing will break if they are
> so much as breathed on. I've noted some of the rationale in comments, but
> probably not enough.
> 
> If you run the file (there's a run command at the bottom of the file),
> you'll see the backtracking occurring. I don't have a mathematical proof that it is
> correct in the general case, but I tentatively believe it is.
> 
> Cheers,
> Sidney C. Bailin
> Knowledge Evolution, Inc.
> 
> ;;;;;;;;;;;;;;;;;;;;;;;;;
> 
> (clear)
> (watch all)
> ;(unwatch facts)
> 
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> ; Rules for realizing goal A ;
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> 
> (defrule backch-A-1
>       ;
>       ; one way to realize goal A
>       ;
>       ?n <- (need A ?tag ?x ?y ?z)
>       (not (failed-attempt A 1 ?tag ?x ?y ?z))
>       (not (trying-for A ? ?tag ?x ?y ?z))
> =>
>       ;(retract ?n)
>       (assert (trying-for A 1 ?tag ?x ?y ?z))
>       (assert (need D ?tag ?y))
>       (assert (need E ?tag ?x ?y ?z))
> )
> 
> (defrule backch-A-2
>       ;
>       ; another way to realize goal A
>       ;
>       ?n <- (need A ?tag ?x ?y ?z)
>       (not (failed-attempt A 2 ?tag ?x ?y ?z))
>       (not (trying-for A ? ?tag ?x ?y ?z))
> =>
>       ;(retract ?n)
>       (assert (trying-for A 2 ?tag ?x ?y ?z))
>       (assert (need B ?tag ?x ?y))
>       (assert (need C ?tag ?y ?z))
> )
> 
> (defrule fwdch-A-1
>       (B ?tag ?u ?v)
>       (C ?tag ?v ?w)
>       ;
>       ;either any val will do, or it must match the other conditions
>       ;
>       ?t <- (trying-for A ?rule ?tag ?x&nil|?u ?y&nil|?v ?z&nil|?w) 
>       (not (failed-attempt A ?rule ?tag ?u ?v ?w))
> =>
>       (retract ?t)
>       (assert (A ?u ?v ?w))
> )
> 
> (defrule fwdch-A-2
>       (D ?v)
>       (E ?u ?v ?w)
>       ?t <- (trying-for A ?rule ?tag ?x&nil|?u ?y&nil|?v ?z&nil|?w) 
>       (not (failed-attempt A ?rule ?tag ?u ?v ?w))
> =>
>       (retract ?t)
>       (assert (A ?u ?v ?w))
> )
> 
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> ; Rules to cleanup an attempt ;
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> 
> (defrule failed-attempt
>       (declare (salience -995))
>       ?t <- (trying-for ?goal ?rule ?tag $?x)
> =>
>       (retract ?t)
>       (assert (failed-attempt ?goal ?rule ?tag $?x))
>       ;(assert (need ?goal ?tag $?x)) ;backtrack
> )
> (defrule failed-after-trying
>       (declare (salience -996))
>       ?n <- (need ?goal ?tag $?x)
>       ?f <- (failed-attempt ?goal ?rule ?tag $?x)
> =>
>       (retract ?n)
>       (retract ?f)
> )
> (defrule failed-without-even-trying
>       (declare (salience -997))
>       ?n <- (need ?goal ?tag $?x)
> =>
>       (retract ?n) ; give up
> )
> (defrule also-failed-after-trying-this ;residuals
>       (declare (salience -998))
>       ?f <- (failed-attempt ?goal ?rule ?tag $?x)
> =>
>       (retract ?f)
> )
> (defrule succeeded-so-dont-need-anymore
>       (declare (salience 999)) ;do right away to prevent restarting the process
>       ?n <- (need A ?tag ?x ?y ?z)
>       (A ?x ?y ?z)
> =>
>       (retract ?n) 
> )
> 
>       
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> ; Rules for realizing goal B ;
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> 
> (defrule backch-B-1
>       ;
>       ; one binding that realizes goal B
>       ;
>       ?n <- (need B ?tag ?x&cat|nil ?y&dog|nil)
> =>
>       (retract ?n)
>       (assert (B cat dog))
> )
> (defrule backch-B-2
>       ;
>       ; another binding that realizes goal B
>       ;
>       ?n <- (need B ?tag ?x&bird|nil ?y&mouse|nil)
> =>
>       (retract ?n)
>       (assert (B bird mouse))
> )
> (defrule backch-B-2
>       ;
>       ; another binding that realizes goal B
>       ;
>       ?n <- (need B ?tag ?x ?y)
>       (test (< (str-length (str-cat ?x ?y)) 328))
> =>
>       (retract ?n)
>       (assert (B ?x ?y))
> )
> 
> 
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> ; Rules for realizing goal C ;
> ; (similar to A)             ;
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> 
> (defrule backch-C-1
>       ;
>       ; another way to realize goal C
>       ;
>       ?n <- (need C ?tag ?y ?z)
>       (not (failed-attempt C 1 ?tag ?y ?z))
>       (not (trying-for C ? ?tag ?y ?z))
> =>
>       ;(retract ?n)
>       (assert (trying-for C 1 ?tag ?y ?z))
>       (assert (need J ?tag ?y))
>       (assert (need K ?tag ?y ?z))
> )
> (defrule backch-C-2
>       ;
>       ; one way to realize goal C
>       ;
>       ?n <- (need C ?tag ?y ?z)
>       (not (failed-attempt C 2 ?tag ?y ?z))
>       (not (trying-for C ? ?tag ?y ?z))
> =>
>       ;(retract ?n)
>       (assert (trying-for C 2 ?tag ?y ?z))
>       (assert (need H ?tag ?y ?z))
>       (assert (need I ?tag ?z))
> )
> 
> 
> (defrule fwdch-C-1
>       ;
>       ;either any val will do, or it must match the other conditions
>       ;
>       (H ?tag ?v ?w)
>       (I ?tag ?w)
>       ?t <- (trying-for ? ?rule ?tag ?y&nil|?v ?z&nil|?w) 
>       (not (failed-attempt C ?rule ?tag ?v ?w))
> =>
>       (retract ?t)
>       (assert (C ?v ?w))
> )
> 
> (defrule fwdch-C-2
>       (J ?tag ?v)
>       (K ?tag ?v ?w)
>       ?t <- (trying-for C ?rule ?tag ?y&nil|v ?z&nil|?w) 
>       (not (failed-attempt C ?rule ?tag ?v ?w))
> =>
>       (retract ?t)
>       (assert (C ?v ?w))
> )
> 
> 
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> ; Rules for realizing goal D ;
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> 
> (defrule backch-D
>       ?n <- (need D ?tag ?x)
> =>
>       (retract ?n)
>       (assert (D ?x))
> )
> 
> 
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> ; Rules for realizing goal E ;
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> 
> (defrule backch-E
>       ?n <- (need E ?tag ?x ?y ?z)
> =>
>       (retract ?n)
>       (assert (E ?x ?y ?z))
> )
> 
> 
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> ; Rules for realizing goal H ;
> ; (similar to B)             ;
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> 
> (defrule backch-H-1
>       ;
>       ; one binding that realizes goal H
>       ;
>       ?n <- (need H ?tag ?x&kitten|nil ?y&rat|nil)
> =>
>       (retract ?n)
>       (assert (H kitten rat))
> )
> (defrule backch-H-2
>       ;
>       ; another binding that realizes goal H
>       ;
>       ?n <- (need H ?tag ?x&puppy|nil ?y&aardvark|nil)
> =>
>       (retract ?n)
>       (assert (H puppy aardvark))
> )
> 
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> ; Rules for realizing goal I ;
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> 
> (defrule backch-I
>       ?n <- (need I ?tag ?x&cat|dog|puppy|bird|mouse|rat|aardvak)
> =>
>       (retract ?n)
>       (assert (I ?x))
> )
> 
> 
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> (assert (need A 111 cat dog nil))
> 
> (run)
> 
> 
> --------------60C956FF483FAA4AF4481428--
> 
> 
> 
> 
> ----- End Included Message -----
> 
> ---------------------------------------------------------------------
> 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