JESS: Ranking facts

2007-11-27 Thread Jan Willem Lokin
Hi,

Consider the following situation. I have asserted quite a number of
facts, with various values for their slots. Now I want to select a
limited number of facts that are most suitable, according to some
user-defined criterion.

My idea was to set up a defquery and then use Java sorting to order
the QuertResult according to my criterion. However, there seems to be
no way to transform a QueyResult into a Collection.

Note that my problems would be simple if I had fixed limits on my slot
values, but I haven't: if i woudl have slot values of 2, 4 and 6 and I
would like to have the smallest two, a limit of 5 would do it, but
this would not work when the values were 13, 15 and 29.

My suspicion is that I am trying to solve the problem in the wrong
manner, or even trying to solve the wrong problem. Any suggestions are
appreciated.

Regards,

JW Lokin


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: Ranking facts

2007-11-27 Thread Wolfgang Laun

Maybe this is coming close to what you want.

; your fact template
(deftemplate Fact (slot id)(slot a)(slot b)(slot c))

; supposed to contain the rating functions for the slot values
(deftemplate Func (slot fa)(slot fb)(slot fc))

; the computed ranking for a fact
(deftemplate Rank (slot r)(slot f))

; the collected results
(deftemplate Count (slot n)(multislot facts))

; some facts
(deffacts someT
   (Fact (id A)(a 42)(b 23)(c 17))
   (Fact (id B)(a 21)(b 11)(c  7))
   (Fact (id C)(a 15)(b 10)(c 12))
   (Fact (id D)(a 33)(b 12)(c  9))
)

; rating functions for the slots
(deffacts aFunc
   (Func (fa (lambda (?a) (return (- ?a 10
 (fb (lambda (?b) (return (/ ?b  3
 (fc (lambda (?c) (return (* ?c  2)
)

; a rule computing the fact ranking as the sum of the slot rankings
(defrule setRank
 ?fact - (Fact (a ?a) (b ?b) (c ?c))
 (Func (fa ?fa)(fb ?fb)(fc ?fc))
=
 (bind ?rank (+ (call ?fa ?a)(call ?fb ?b)(call ?fc ?c)))
 (assert (Rank (r ?rank)(f ?fact)))
)

(reset)
(run)

; getting  displaying the n best rankings
(defrule getBest
  ?count - (Count (n ?n : ( ?n 0))(facts $?facts))
  ?rank  - (Rank  (r ?r)(f ?fact))
  (not ( Rank (r ?r1 : ( ?r1 ?r
=
  (-- ?n)
  (modify ?count (n ?n)(facts (list $?facts ?fact)))
  (retract ?rank)
)
(defrule showBest
  ?count - (Count (n 0)(facts $?facts))
=
  (retract ?count)
  (foreach ?f $?facts
 (printout t (fact-slot-value ?f id) crlf)
  )
)

; top 3
(assert (Count (n 3)))
(run)

Notice that some Rank facts remain, but these can be easily retracted.

Kind regards
Wolfgang


Jan Willem Lokin wrote:


Hi,

Consider the following situation. I have asserted quite a number of
facts, with various values for their slots. Now I want to select a
limited number of facts that are most suitable, according to some
user-defined criterion.

My idea was to set up a defquery and then use Java sorting to order
the QuertResult according to my criterion. However, there seems to be
no way to transform a QueyResult into a Collection.

Note that my problems would be simple if I had fixed limits on my slot
values, but I haven't: if i woudl have slot values of 2, 4 and 6 and I
would like to have the smallest two, a limit of 5 would do it, but
this would not work when the values were 13, 15 and 29.

My suspicion is that I am trying to solve the problem in the wrong
manner, or even trying to solve the wrong problem. Any suggestions are
appreciated.

Regards,

JW Lokin


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: Ranking facts

2007-11-27 Thread Jason Morris
Hi Jan,

Couldn't you simply write one or more rules that place matching fact
bindings into an arbitrary collection class?
I'm assuming that you are filtering only on one type of fact.  For example:

(clear)
(import java.util.ArrayList)
(watch all)

(deftemplate somefact
(slot x)
(slot y)
(slot z))

(deffacts init
(somefact (x 2) (y 4) (z 6))
(somefact (x 13) (y 15) (z 29))
(somefact (x 5) (y 8) (z 11)))

(deffunction update-fact-list-display (?conditionNumber ?colFacts)
(printout t Facts that match condition  ?conditionNumber : crlf)
(printout t  crlf)
(foreach ?fact ?colFacts
(printout t FactID:  ?fact crlf)))

(defrule find-all-somefacts-condition-1
Finds all somefacts having 1st set of arbitrary conditions
?factId -(somefact (x ?x:(= ?x 5)) (y ?y:(= ?y 5)) (z ?))
=
(bind ?colFacts1 (fetch colFacts1))
(?colFacts1 add ?factId)
(update-fact-list-display 1 ?colFacts1))

(defrule find-all-somefacts-condition-2
Finds all somefacts having 2nd set of arbitrary conditions
?factId -(somefact (x ?x:(= ?x 5)) (y ?y:(= ?y 4)) (z ?))
=
(bind ?colFacts2 (fetch colFacts2))
(?colFacts2 add ?factId)
(update-fact-list-display 2 ?colFacts2))

;; Program
(bind ?colFacts1 (new ArrayList))
(store colFacts1 ?colFacts1)
(bind ?colFacts2 (new ArrayList))
(store colFacts2 ?colFacts2)
(reset)
(run)

// OUTPUT
==
MAIN::find-all-somefacts-condition-1: +1+1+1+1+t
MAIN::find-all-somefacts-condition-2: =1+1+1+1+t
 == Focus MAIN
 == f-0 (MAIN::initial-fact)
 == f-1 (MAIN::somefact (x 2) (y 4) (z 6))
== Activation: MAIN::find-all-somefacts-condition-1 :
 == f-2 (MAIN::somefact (x 13) (y 15) (z 29))
== Activation: MAIN::find-all-somefacts-condition-2 :
 == f-3 (MAIN::somefact (x 5) (y 8) (z 11))
== Activation: MAIN::find-all-somefacts-condition-2 :
FIRE 1 MAIN::find-all-somefacts-condition-2 f-3
Facts that match condtion 2:

FactID: Java-Object:jess.Fact
FIRE 2 MAIN::find-all-somefacts-condition-2 f-2
Facts that match condtion 2:

FactID: Java-Object:jess.Fact
FactID: Java-Object:jess.Fact
FIRE 3 MAIN::find-all-somefacts-condition-1 f-1
Facts that match condtion 1:

FactID: Java-Object:jess.Fact
 == Focus MAIN

//

Cheers,
Jason

-- 
---
Jason Morris
Morris Technical Solutions LLC
http://www.morris-technical-solutions.com

On Nov 27, 2007 7:43 AM, Jan Willem Lokin [EMAIL PROTECTED] wrote:
 Hi,

 Consider the following situation. I have asserted quite a number of
 facts, with various values for their slots. Now I want to select a
 limited number of facts that are most suitable, according to some
 user-defined criterion.

 My idea was to set up a defquery and then use Java sorting to order
 the QuertResult according to my criterion. However, there seems to be
 no way to transform a QueyResult into a Collection.

 Note that my problems would be simple if I had fixed limits on my slot
 values, but I haven't: if i woudl have slot values of 2, 4 and 6 and I
 would like to have the smallest two, a limit of 5 would do it, but
 this would not work when the values were 13, 15 and 29.

 My suspicion is that I am trying to solve the problem in the wrong
 manner, or even trying to solve the wrong problem. Any suggestions are
 appreciated.

 Regards,

 JW Lokin

 
 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: Ranking facts

2007-11-27 Thread Robert Kirby
Facts can be selected in rank order with a defquery and a Java collection.

(deftemplate sample
Sample facts to be ranked
(declare (ordered FALSE))
(slot primary (type INTEGER) (default 0))
(slot secondary (type INTEGER))
(slot stuff)
)

(defquery sample-query
Query for well-formed samples with an exclusion
(declare (variables ?exclude))
?sample - (sample (primary ?primary~nil)
   (secondary ?secondary~nil)
   (stuff ~?exclude)))

(deffunction top-samples (?threshold ?criterion)
Print top N sample facts according to criterion
(bind ?tree-set (new java.util.TreeSet ?criterion))
(bind ?samples (run-query* sample-query nil))
(while (?samples next)
(call ?tree-set add (?samples get sample)))
(close ?samples)
(bind ?iterator (?tree-set iterator))
(while (and (?iterator hasNext) ( ?threshold 0))
(-- ?threshold)
(bind ?sample (?iterator next))
(printout t Sample fact: 
  (fact-slot-value ?sample primary)  
  (fact-slot-value ?sample secondary)  
  (fact-slot-value ?sample stuff) crlf)))

(defglobal ?*compare-samples* =
(implement java.util.Comparator using
   (lambda (?dummy ?first ?second)
   (bind ?name1 (fact-slot-value ?first primary))
   (bind ?name2 (fact-slot-value ?second primary))
   (if ( ?name1 ?name2) then
   (return -1))
   (if ( ?name1 ?name2) then
   (return 1))
   (bind ?name1 (fact-slot-value ?first secondary))
   (bind ?name2 (fact-slot-value ?second secondary))
   (if ( ?name1 ?name2) then
   (return -1))
   (if ( ?name1 ?name2) then
   (return 1))
   0)))

(deffacts sample-facts
Sample fact examples to be ranked
(sample (primary 1) (secondary 10) (stuff A))
(sample (primary 1) (secondary 11) (stuff B))
(sample (primary 2) (secondary 5) (stuff C))
(sample (primary 2) (secondary 6) (stuff D))
(sample (primary 2) (secondary 6) (stuff E))
(sample (primary 2) (secondary 7) (stuff F))
(sample (primary 3) (secondary 9) (stuff G))
(sample (primary 3) (stuff H))
(sample (primary 1) (stuff I))
)

Jess (reset)
TRUE
Jess (top-samples 3 ?*compare-samples*)
Sample fact: 1 10 A
Sample fact: 1 11 B
Sample fact: 2 5 C
FALSE

Many variations are possible.
- To avoid recalculating an expensive comparison function, the criteria could 
be pre-calculated as the key of a TreeMap instead of a TreeSet.
- The java.util.Collections.sort method could sort any java.util.List 
collection instead of a TreeSet.
- A rule could add items to a collection instead of a defquery.

Bob Kirby

At 04:43 AM 11/27/2007, Jan Willem Lokin wrote:
Hi,

Consider the following situation. I have asserted quite a number of
facts, with various values for their slots. Now I want to select a
limited number of facts that are most suitable, according to some
user-defined criterion.

My idea was to set up a defquery and then use Java sorting to order
the QuertResult according to my criterion. However, there seems to be
no way to transform a QueyResult into a Collection.

Note that my problems would be simple if I had fixed limits on my slot
values, but I haven't: if i woudl have slot values of 2, 4 and 6 and I
would like to have the smallest two, a limit of 5 would do it, but
this would not work when the values were 13, 15 and 29.

My suspicion is that I am trying to solve the problem in the wrong
manner, or even trying to solve the wrong problem. Any suggestions are
appreciated.

Regards,

JW Lokin