Re: JESS: Using a rule engine for plan recognition

2006-02-14 Thread Jonathan Sewall




Back to a month-old topic, herewith some more information. Back then I
asked 
 1) whether others have suggestions for implementing backtracking in
Jess and 
 2) whether it would be appropriate to make Activation.setInactive()
public.
Thanks again for your replies so far. Anyone who reads all the rest of
this has my sympathies.

Jonathan Sewall
__

Our application is a toolkit for writing intelligent tutoring
systems. Our users are tutor authors who
 1) create a student interface that exposes the individual steps in
the task to be tutored, and then
 2) write rules in Jess to model the individual steps or substeps in
the task and check whether a student entry matches a step.

That is, authors write a cognitive model that will simulate a human
tutor looking over the student's shoulder at runtime. When the student
enters a value on the interface (that is, attempts a step in the task),
our toolkit runs a depth-limited search that fires rules to generate
the proper next steps until it either finds the student's entry or
gives up and calls the entry incorrect. We have a depth-limited search
because a logical chain of several rules is often needed to model a
single step, and typically the student's entry can't be fully checked
until the last rule in the chain. 

We inherit this depth-limited search and style of rule-writing from a
previous production rule system we used for tutors: we are trying to
replace that system with Jess. Each activation is a node in the search
tree; each rule firing deepens the search by one level. The new
activations triggered by a single firing are the activation's child
nodes, each representing an alternative path in the search space--that
is, an alternative possible path toward finding the student's entry.
For reasons that have to do with the capability to generate hints (that
is, to formulate an answer when the student asks "what do I do next?"
instead of attempting a step), our authors check the student input on
the RHS side of their rules, not on the LHS. Hence when a path ends
with failure to match the student input, we backtrack to try an
alternative path. We currently use (bsave) and (bload) for
backtracking, but we ask whether there are faster alternatives. We use
Activation.setInactive() to explore sibling paths upon backtracking.

To make this concrete, here is a trace of what our algorithm does now
for a simple task: the rules are from a tutor for multicolumn addition
for a child. Each step in the task is to write a single digit of the
sum (in the ones, tens, ... place) or to write a carry digit. The
author intends to permit the student to write a sum digit or a carry
digit in either order. This fine-grained cognitive model uses several
substeps for each step: it first fires a rule to choose the next
column (ones, tens, ...) of digits to work on, then a rule to add the
digits in that column, then a rule to determine whether a carry is
needed,.then either a rule to actually write the carry digit or to
write the sum digit. At the substep where the model must determine
whether a carry is needed, we have (bold insertions are comments):

Jess (agenda)
[Activation: MAIN::must-carry : f-39, f-40,,, f-37, f-38, f-32, f-4 ;
time=47 ; salience=0]
Jess (run 1)
1
Jess (agenda) ; must-carry found a carry needed, so activates
both write-carry and write-sum
[Activation: MAIN::write-carry f-39, f-42, f-32, f-28, f-38, f-37,
f-36, f-4 ; time=57 ; salience=0]
[Activation: MAIN::write-sum f-39, f-40,, f-37, f-36, f-4 ; time=57 ;
salience=0]
For a total of 2 activations in module MAIN.
Jess (bsave before-write.rete) ; 2 activations created, so
bsave to permit backtracking
TRUE
Jess (run 1) ; run the write-carry activation
1
Jess (bload before-write.rete) ; found that write-carry fails
to match student's input, so backtrack
TRUE
Jess (agenda) ; now must search alternative path by firing
write-sum, not write-carry
[Activation: MAIN::write-carry f-39, f-42, f-32, f-28, f-38, f-37,
f-36, f-4 ; time=57 ; salience=0]
[Activation: MAIN::write-sum f-39, f-40,, f-37, f-36, f-4 ; time=57 ;
salience=0]
For a total of 2 activations in module MAIN.
Jess (bind ?it (call (engine) listActivations)) ; use
Activation.setInactive() to skip write-carry
Java-Object:jess.HeapPriorityQueue$1 ; (see next several
steps)
Jess (bind ?wc (call ?it next))
Java-Object:jess.Activation
Jess (call jess.JessPrivateAccess setActivationInactive ?wc)
Jess (agenda)
[Activation: MAIN::write-sum f-39, f-40,, f-37, f-36, f-4 ; time=57 ;
salience=0]
For a total of 1 activations in module MAIN.
Jess (run 1) ; now fire write-sum
1
Jess (agenda)
[Activation: MAIN::write-carry f-39, f-42, f-32, f-28, f-38, f-37,
f-36, f-4 ; time=64 ; salience=0]
For a total of 1 activations in module MAIN.
Jess (run 1)
1

[EMAIL PROTECTED] wrote:

  I think Jonathan Sewall wrote:1. I'd be interested in others' experience with this use of Jess, esp. 
strategies for backtracking. 
  
2. I'd ask that 

Re: JESS: Getting Facts in Sorted Order

2006-02-14 Thread Dusan Sormaz


Eric,
here is the rule that will work:
(defrule items-to-buy 
 ?ItemFound - (SomethingIWant (Name
?ItemName) 

(Price ?ItemPrice) 

(Priority ?ItemPriority1) 

(Selected false ) )
(not (SomethingIWant (Selected false) (Priority ?p:( ?p
?ItemPriority1 
 =
 (printout t Found:  ?ItemName
,  ?ItemPrice ,  ?ItemPriority1 crlf)
 (modify ?ItemFound (Selected true) )
)
In addition you should execute (run) at the end of the file, or from JESS
prompt
Dusan Sormaz
PS. If you see smiley in (not ...) clause replace it by : ( .
At 09:30 PM 2/13/2006, you wrote:
OK,
I’m very, very new to JESS and rules engines, so please forgive me for a
very basic question. I have read “JESS in Action” but I’m still stumped
on this one. I get that the rules engine will match all possible facts
against my rule(s). I think of it as kind of an implied iteration, versus
a loop in a procedural language. But, I’d like to have some control over
the order in which those facts are applied to my rule. For example,
imagine I have a database of stuff on my wish list. I keep the name of
each item and the price. And I have a rule that will match on all of the
entries in the database, and do something like make a shopping list and
keep a running total. So far, so good. But, I have a limited budget, and
an infinite wish list. So, I want to make sure my rule matches the things
I want the most, first. And this is where I’m stuck. I can add a
“Priority” slot. But, how do I write the rule to match on the higher
priority facts, first? I played with a (not …) statement I saw in “JESS
in Action”, but it doesn’t quite do what I’m looking for. I may have 3
priority 1 items and I’ll want the rule to match on all of them, and I
might have 2 priority 2 items and I’ll want to rule to match on both of
those. But, I want the rule to match on all of the priority 1 items
before any of the priority 2 items. I pasted my test code below. I’m sure
I just haven’t gotten my mind wrapped around how you do things in this
environment, yet. But, I could use a nudge in the right direction on this
one. Thanks in advance for any suggestions!

Eric

; Test Prioritizing
Facts.

(printout t crlf crlf)

(clear)

(reset)

(deftemplate SomethingIWant Stuff I want
 (slot Name (default Whatever) )
 (slot Price (default 10) )
 (slot Priority (default 0) )
 (slot Selected (default false) )
)

(assert 
 (SomethingIWant 
 (Name TiVo) 
 (Price 200) 
 (Priority 1) 
 )
)

(assert 
 (SomethingIWant 
 (Name DVD Burner)

 (Price 400) 
 (Priority 5) 
 )
)

(assert 
 (SomethingIWant 
 (Name Wheels)

 (Price 1000) 
 (Priority 2) 
 )
)

(defrule items-to-buy 

 ?ItemFound - (SomethingIWant (Name
?ItemName) 

(Price ?ItemPrice) 

(Priority ?ItemPriority1) 

(Selected false ) )

 ?ItemFound2 - (SomethingIWant (Name
?ItemName2) 

(Price ?ItemPrice2) 

(Priority ?ItemPriority2) )
 
; (not (eq ?ItemName ?ItemName2 ) ) 

 (not (SomethingIWant (Priority
?ItemPriority2:( ?ItemPriority1 ?ItemPriority2  
; (test (= ?ItemPriority1 ?ItemPriority2 ) ) 

 =

 (printout t Found:  ?ItemName
,  ?ItemPrice ,  ?ItemPriority1 crlf)

 (modify ?ItemFound (Selected true) )

)




*
* Dušan Šormaz, PhD, Associate
Professor

* Ohio University
* Industrial and Manufacturing Systems Engineering Department
* 277 Stocker Center, Athens, OH 45701-2979
* phone: (740) 593-1545 
* fax: (740) 593-0778 
* e-mail: [EMAIL PROTECTED] 
* url:

http://www.ent.ohiou.edu/~sormaz 
*
 



RE: JESS: Getting Facts in Sorted Order

2006-02-14 Thread Eric W. Bonnett








    Thanks, but that only matches
on the single set of facts with the lowest priority. I want to get all of the
facts, I just want them to be given to the rule in order of priority. For
example, given the following set of facts:



(assert 

    (SomethingIWant 

    (Name TiVo) 

    (Price 200) 

    (Priority 1) 

    )

)



(assert 

    (SomethingIWant 

    (Name Tires) 

    (Price 800) 

    (Priority 1) 

    )

)



(assert 

    (SomethingIWant 

    (Name Carb) 

    (Price 400) 

    (Priority 1) 

    )

)



(assert 

    (SomethingIWant 

    (Name DVD Burner) 

    (Price 400) 

    (Priority 5) 

    )

)



(assert 

    (SomethingIWant 

    (Name Wheels) 

    (Price 1000) 

    (Priority 2) 

    )

)



(assert 

    (SomethingIWant 

    (Name shocks) 

    (Price 900) 

    (Priority 2) 

    )

)



I get the following output: 



TRUE

Jess (run)

Found: Carb, 400, 1

Found: Tires, 800, 1

Found: TiVo, 200, 1

3

Jess





The output I want to see would be
something like:



Found: Carb, 400, 1

Found: Tires, 800, 1

Found: TiVo, 200, 1

Found: Wheels, 1000, 2

Found: shocks, 900, 2

Found: DVD Burner, 400, 5



If I can get that to work, Id have
some additional logic to stop processing at some point. In this example, maybe
Id keep a running total of items and stop when Ive reached my
budget, but I want to make sure I get the higher priority items first. 



Should I maybe be setting another fact to
the current priority, initialize it to 1 and just match facts
that have that priority, then increment the current priority fact and match
against facts that have that new priority and continue through the valid range
of priorities? That just feels like Im trying to impose my procedural
thinking on the rules engine. So, Im looking for a more rules friendly
approach. Or maybe have separate rules that match on each individual priority
and have the then part of each rule call the same function, and
use salience to fire the rules in the desired order? 



Thanks,



Eric











From: owner-jess-users@sandia.gov [mailto:owner-jess-users@sandia.gov] On Behalf Of Dusan Sormaz
Sent: Tuesday, February 14, 2006
7:51 AM
To: jess-users@sandia.gov
Subject: Re: JESS: Getting Facts
in Sorted Order





Eric,

here is the rule that will work:

(defrule items-to-buy 
 ?ItemFound - (SomethingIWant (Name
?ItemName) 

(Price ?ItemPrice) 

(Priority ?ItemPriority1) 

(Selected false ) )
(not (SomethingIWant (Selected false) (Priority ?p:( ?p
?ItemPriority1 
 =
 (printout t Found:  ?ItemName ,
 ?ItemPrice ,  ?ItemPriority1 crlf)
 (modify ?ItemFound (Selected true) )
)

In addition you should execute (run) at the end of the file, or from JESS
prompt

Dusan Sormaz

PS. If you see smiley in (not ...) clause replace it by : ( .

At 09:30 PM 2/13/2006, you wrote:



OK, Im very, very new to JESS and rules engines, so
please forgive me for a very basic question. I have read JESS in
Action but Im still stumped on this one. I get that the rules
engine will match all possible facts against my rule(s). I think of it as kind
of an implied iteration, versus a loop in a procedural language. But, Id
like to have some control over the order in which those facts are applied to my
rule. For example, imagine I have a database of stuff on my wish list. I keep
the name of each item and the price. And I have a rule that will match on all
of the entries in the database, and do something like make a shopping list and
keep a running total. So far, so good. But, I have a limited budget, and an
infinite wish list. So, I want to make sure my rule matches the things I want
the most, first. And this is where Im stuck. I can add a
Priority slot. But, how do I write the rule to match on the
higher priority facts, first? I played with a (not ) statement I saw in
JESS in Action, but it doesnt quite do what Im
looking for. I may have 3 priority 1 items and Ill want the rule to
match on all of them, and I might have 2 priority 2 items and Ill want
to rule to match on both of those. But, I want the rule to match on all of the
priority 1 items before any of the priority 2 items. I pasted my test code
below. Im sure I just havent gotten my mind wrapped around how
you do things in this environment, yet. But, I could use a nudge in the right
direction on this one. Thanks in advance for any suggestions!

Eric

; Test Prioritizing Facts.

(printout t crlf crlf)

(clear)

(reset)

(deftemplate SomethingIWant Stuff I want
 (slot Name (default Whatever) )
 (slot Price (default 10) )
 (slot Priority (default 0) )
 (slot Selected (default false) )
)

(assert 
 (SomethingIWant 
 (Name TiVo) 
 (Price 200) 
 (Priority 1) 
 )
)

(assert 
 (SomethingIWant 
 (Name DVD Burner) 
 (Price 400) 
 (Priority 5) 
 )
)

(assert 
 (SomethingIWant 
 (Name Wheels) 
 (Price 1000) 
 (Priority 2) 
 )
)

(defrule items-to-buy 

 ?ItemFound - (SomethingIWant (Name
?ItemName) 


RE: JESS: Getting Facts in Sorted Order

2006-02-14 Thread Eric W. Bonnett
Hmm, I don't think so. Copy\paste! :) I should have mentioned it
before, I'm using the publicly available version 6.1p4 that I downloaded
based on instructions in the book. Would that matter? I'm still waiting for
my company to fill out the licensing forms to get the latest version.

Thanks,

Eric


-Original Message-
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On
Behalf Of [EMAIL PROTECTED]
Sent: Tuesday, February 14, 2006 10:30 AM
To: jess-users@sandia.gov
Subject: Re: JESS: Getting Facts in Sorted Order

I think Eric W. Bonnett wrote:
[Charset iso-8859-2 unsupported, filtering to ASCII...]
 Thanks, but that only matches on the single set of facts with
 the lowest priority.

No, actually, it'll do just exactly what you want. Maybe you typed it wrong?

-
Ernest Friedman-Hill  
Advanced Software Research  Phone: (925) 294-2154
Sandia National LabsFAX:   (925) 294-2234
PO Box 969, MS 9012 [EMAIL PROTECTED]
Livermore, CA 94550 http://herzberg.ca.sandia.gov


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]



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]




RE: JESS: Getting Facts in Sorted Order

2006-02-14 Thread Eric W. Bonnett
Aha, said the blind man! :) I really did copy\paste Dusan's rule. But, I
pasted just the rule into my program. And in my program I was asserting the
facts before defining the rule and apparently that makes quite a difference.
Now, let me see if I can grok why that is. This was just a simplified
example to pose the question in. In the real application I'm working
towards, I'll be loading the rules from a .clp file and then asserting the
facts from a Java application. So, I think this will be OK. Thank you both
very much!

Eric


-Original Message-
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On
Behalf Of [EMAIL PROTECTED]
Sent: Tuesday, February 14, 2006 12:03 PM
To: jess-users@sandia.gov
Subject: Re: JESS: Getting Facts in Sorted Order

I think Eric W. Bonnett wrote:
   Hmm, I don't think so. Copy\paste! :) I should have mentioned it
 before, I'm using the publicly available version 6.1p4 that I downloaded
 based on instructions in the book.

On the off chance that there was something about this version, I tried
it myself -- but it worked fine. Here's the program I ran:

(deftemplate SomethingIWant Stuff I want
(slot Name (default Whatever) )
(slot Price (default 10) )
(slot Priority (default 0) )
(slot Selected (default false) )
)

(defrule items-to-buy
  ?ItemFound - (SomethingIWant   (Name ?ItemName)
  (Price ?ItemPrice)
  (Priority ?ItemPriority1)
  (Selected false ) )
  (not (SomethingIWant (Selected false) (Priority ?p:( ?p
?ItemPriority1
  =
  (printout t  Found:  ?ItemName ,  ?ItemPrice ,  ?ItemPriority1 crlf)
  (modify ?ItemFound (Selected true) )
  )

(assert
(SomethingIWant
(Name TiVo)
(Price 200)
(Priority 1)
)
)

(assert
(SomethingIWant
(Name Tires)
(Price 800)
(Priority 1)
)
)

(assert
(SomethingIWant
(Name Carb)
(Price 400)
(Priority 1)
)
)

(assert
(SomethingIWant
(Name DVD Burner)
(Price 400)
(Priority 5)
)
)

(assert
(SomethingIWant
(Name Wheels)
(Price 1000)
(Priority 2)
)
)

(assert
(SomethingIWant
(Name shocks)
(Price 900)
(Priority 2)
)
)

(run)

And here's the output:

Found: Carb, 400, 1
Found: Tires, 800, 1
Found: TiVo, 200, 1
Found: shocks, 900, 2
Found: Wheels, 1000, 2
Found: DVD Burner, 400, 5

-
Ernest Friedman-Hill  
Advanced Software Research  Phone: (925) 294-2154
Sandia National LabsFAX:   (925) 294-2234
PO Box 969, MS 9012 [EMAIL PROTECTED]
Livermore, CA 94550 http://herzberg.ca.sandia.gov


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]



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]