(deftemplate item (slot id))
(deftemplate lost (slot id))
(deftemplate counted (slot id))

(set-current-module MAIN)

(defrule lose-an-item
 (declare (auto-focus TRUE)(salience 100))
 (item (id ?c))
 (not (lost (id ?c)))
=>
 (assert (lost (id ?c)))
 (return)
)

(defmodule MOD)

(defrule count-item
 (declare (salience -100))
 (item (id ?id))
 (not (counted (id ?id)))
=>
 (assert (counted (id ?id)))
)

(watch all)

(reset)
(assert (item (id 1)))

(focus MOD)
(run)

I'm expecting the MAIN rule lose-an-item to fire first, because the rule is
declared auto-focus TRUE, but my expectations are off.  Here's what happens:

Jess> (batch main.clp)
 ==> Focus MAIN
 ==> f-0 (MAIN::initial-fact)
 ==> f-1 (MAIN::item (id 1))
==> Activation: MAIN::lose-an-item :  f-1,
==> Activation: MOD::count-item :  f-1,
 <== Focus MAIN
 ==> Focus MOD
FIRE 1 MOD::count-item f-1,
 ==> f-2 (MAIN::counted (id 1))
 <== Focus MOD
 ==> Focus MAIN
FIRE 2 MAIN::lose-an-item f-1,
 ==> f-3 (MAIN::lost (id 1))
 <== Focus MAIN
 ==> Focus MAIN
2

I see that both rules properly activate upon assertion of the matching
(item) fact, but I want the MAIN rule to fire first, so I gave it salience
100 (and gave the MOD rule salience -100 to see if that would make
difference).  Why doesn't MAIN auto-focus when I (run), regardless that I
have explicitly given MOD module focus?

One other experiment I tried was to put an (agenda) call immediately before
and after (focus MOD) to see what's what:

Jess> (batch main.clp)
 ==> Focus MAIN
 ==> f-0 (MAIN::initial-fact)
 ==> f-1 (MAIN::item (id 1))
==> Activation: MAIN::lose-an-item :  f-1,
==> Activation: MOD::count-item :  f-1,
[Activation: MOD::count-item  f-1, ; time=2 ; salience=-100]
For a total of 1 activations in module MOD.
 <== Focus MAIN
 ==> Focus MOD
[Activation: MOD::count-item  f-1, ; time=2 ; salience=-100]
For a total of 1 activations in module MOD.
FIRE 1 MOD::count-item f-1,
 ==> f-2 (MAIN::counted (id 1))
 <== Focus MOD
 ==> Focus MAIN
FIRE 2 MAIN::lose-an-item f-1,
 ==> f-3 (MAIN::lost (id 1))
 <== Focus MAIN
 ==> Focus MAIN
2

So the watch activations shows MAIN::lose-an-item activating upon assertion
of the matching (item) fact, yet (agenda) reports only the MOD rule.  Seems
like something happened to the activation of MAIN::lose-an-item between the
time I asserted the (item) fact and the time that I executed the (agenda)
function.  Is there something subtle here that I am missing?  Please advise
even if it's obvious and not subtle.  ;-\

[Aside:  I recall a discussion about auto-focus rules and the (return)
function on this list a while back, but removing (return) from my
lose-an-item rule gives no difference other than the final ==> Focus MAIN
not occurring.  With (return) in, I tried this:

(reset)
(assert (item (id 1)))

(printout t (get-focus-stack) crlf)
(agenda)
(focus MOD)
(printout t (get-focus-stack) crlf)
(agenda)
(run)
(printout t (get-focus-stack) crlf)

and saw:

Jess> (batch main.clp)
 ==> Focus MAIN
 ==> f-0 (MAIN::initial-fact)
 ==> f-1 (MAIN::item (id 1))
==> Activation: MAIN::lose-an-item :  f-1,
==> Activation: MOD::count-item :  f-1,
(MAIN)
[Activation: MOD::count-item  f-1, ; time=2 ; salience=-100]
For a total of 1 activations in module MOD.
 <== Focus MAIN
 ==> Focus MOD
(MOD MAIN)
[Activation: MOD::count-item  f-1, ; time=2 ; salience=-100]
For a total of 1 activations in module MOD.
FIRE 1 MOD::count-item f-1,
 ==> f-2 (MAIN::counted (id 1))
 <== Focus MOD
 ==> Focus MAIN
FIRE 2 MAIN::lose-an-item f-1,
 ==> f-3 (MAIN::lost (id 1))
 <== Focus MAIN
 ==> Focus MAIN
()

Note how it appears that the MAIN module refocuses after (run), but then my
final call to (get-focus-stack) shows the empty stack.  I don't know why,
don't know if it's related to my above-described problem, but mention this
parenthetically just in case.]

V/R,

Moon

Reply via email to