JESS: Find the minimum

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

JESS: Find the minimum

Bob Crothers

I would like find ?word1 and ?word2 such that the absolute value of ?rowNumber1 minus?rowNumber2 is the minimum number and ?word1 is not equal to ?word2

 

rowNumber are integers, 1, 2, 3....

 

I have verified that there is a single minimum.

 

I have tried

 

(defrule find-lines-per-block-ssn

           ?word1 <- (word (page ?page) (rowNumber ?rowNumber1) (type ssn) (text ?text1)  )

            ?word2 <- (word (page ?page) (rowNumber ?rowNumber2&:(<> ?rowNumber1 ?rowNumber2)) (type ssn) (text ?text2) )

            (not

        (word (page ?page) (rowNumber ?rowNumberVar&:(< (abs (- ?rowNumberVar ?rowNumber1) ) (abs (- ?rowNumber2 ?rowNumber1) ) ) ) )

            )

=>

    ; do something

)

 

This rule never fired.

 

 

 

I tried  

(defrule find-lines-per-block-ssn

           ?word1 <- (word (page ?page) (rowNumber ?rowNumber1) (type ssn) (text ?text1)  )

            ?word2 <- (word (page ?page) (rowNumber ?rowNumber2) (type ssn) (text ?text2) )

            (not

        (word (page ?page) (rowNumber ?rowNumberVar&:(< (abs (- ?rowNumberVar ?rowNumber1) ) (abs (- ?rowNumber2 ?rowNumber1) ) ) ) )

            )

=>

    ; do someting

 

This fired but ?word1 equals ?word2.

 

Thanks

 

Bob

 

 

Reply | Threaded
Open this post in threaded view
|

Re: JESS: Find the minimum

Wolfgang Laun-2
What makes one word different from another one? Surely you know (but we don't), and this must be a constraint in that rule.

If it is the rowNumber, than this condition would be logically correct:
   (rowNumber ?rowNumber2 &:(<> ?rowNumber1 ?rowNumber2))
although it were better written as
   (rowNumber ?rowNumber2 & ~?rowNumber1)
If it isn't, omit this constraint.

-W


On 23 August 2011 06:17, Cathy & Bob Crothers <[hidden email]> wrote:

I would like find ?word1 and ?word2 such that the absolute value of ?rowNumber1 minus?rowNumber2 is the minimum number and ?word1 is not equal to ?word2

 

rowNumber are integers, 1, 2, 3....

 

I have verified that there is a single minimum.

 

I have tried

 

(defrule find-lines-per-block-ssn

           ?word1 <- (word (page ?page) (rowNumber ?rowNumber1) (type ssn) (text ?text1)  )

            ?word2 <- (word (page ?page) (rowNumber ?rowNumber2&:(<> ?rowNumber1 ?rowNumber2)) (type ssn) (text ?text2) )

            (not

        (word (page ?page) (rowNumber ?rowNumberVar&:(< (abs (- ?rowNumberVar ?rowNumber1) ) (abs (- ?rowNumber2 ?rowNumber1) ) ) ) )

            )

=>

    ; do something

)

 

This rule never fired.

 

 

 

I tried  

(defrule find-lines-per-block-ssn

           ?word1 <- (word (page ?page) (rowNumber ?rowNumber1) (type ssn) (text ?text1)  )

            ?word2 <- (word (page ?page) (rowNumber ?rowNumber2) (type ssn) (text ?text2) )

            (not

        (word (page ?page) (rowNumber ?rowNumberVar&:(< (abs (- ?rowNumberVar ?rowNumber1) ) (abs (- ?rowNumber2 ?rowNumber1) ) ) ) )

            )

=>

    ; do someting

 

This fired but ?word1 equals ?word2.

 

Thanks

 

Bob

 

 


Reply | Threaded
Open this post in threaded view
|

Re: JESS: Find the minimum

Win Carus
In reply to this post by Bob Crothers

I hope the following provides the functionality you're looking for. Note that the word deftemplate has been modified to incorporate a memory slot that indicates that it has already been selected as a minimal-distance pair; this prevents these facts from participating in spurious future matches.

(deftemplate word
    (slot page)
    (slot rowNumber)
    (slot type)
    (slot text)
    (slot control))

(assert
    (word (page 1) (rowNumber 1) (type ssn) (text "text1") (control FALSE))
    (word (page 1) (rowNumber 2) (type ssn) (text "text2") (control FALSE))
    (word (page 1) (rowNumber 3) (type ssn) (text "text3") (control FALSE))
    (word (page 1) (rowNumber 9) (type ssn) (text "text4") (control FALSE))
    (word (page 1) (rowNumber 10) (type ssn) (text "text5") (control FALSE))
)

(defrule find-lines-per-block-ssn
    ?word1 <- (word (page ?page) (rowNumber ?rowNumber1) (type ssn) (text ?text1) (control FALSE))
    ?word2 <- (word (page ?page) (rowNumber ?rowNumber2&~?rowNumber1&:(< ?rowNumber1 ?rowNumber2)) (type ssn) (text ?text2) (control FALSE))
               (not
                      (word (page ?page)
                         (rowNumber ?rowNumberVar&~rowNumber1&~rowNumber2&:(and (> ?rowNumberVar ?rowNumber1) (< ?rowNumberVar ?rowNumber2) (< (abs (- ?rowNumberVar ?rowNumber1)) (abs (- ?rowNumber2 ?rowNumber1)))))))

    =>
    (modify ?word1 (control TRUE))
    (modify ?word2 (control TRUE))
    (printout t "Cluster: " ?rowNumber1 crlf)
)

(run)

Cluster: 9
Cluster: 2
2

Win Carus

I would like find ?word1 and ?word2 such that the absolute value of ?rowNumber1 minus?rowNumber2 is the minimum number and ?word1 is not equal to ?word2

rowNumber are integers, 1, 2, 3....

I have verified that there is a single minimum.

I have tried

(defrule find-lines-per-block-ssn

?word1

?word2 ?rowNumber1 ?rowNumber2)) (type ssn) (text ?text2) )

(not

(word (page ?page) (rowNumber ?rowNumberVar&:(

)

=>

; do something

)

This rule never fired.

I tried

(defrule find-lines-per-block-ssn

?word1

?word2

(not

(word (page ?page) (rowNumber ?rowNumberVar&:(

)

=>

; do someting

)

This fired but ?word1 equals ?word2.

Thanks

Bob

Reply | Threaded
Open this post in threaded view
|

Re: JESS: Find the minimum

Wolfgang Laun-2
Not sure whether this meets all the possibly undisclosed requirements, not sure about the relation of row numbers and words, but this is firing one, even when there is words from more than one page:

(defrule find-lines-per-block-ssn
  ?w1 <- (word (page ?page)
               (rowNumber ?rowNumber1)
               (type ssn)
               (text ?text1))
  ?w2 <- (word (page ?page)
               (rowNumber ?rowNumber2 &:(< ?rowNumber1 ?rowNumber2))
               (type ssn)
               (text ?text2))
  (not (and (word (page ?px)
                  (rowNumber ?rn1)
                  (type ssn))
            (word (page ?px)
                  (rowNumber ?rn2 &:(< ?rn1 ?rn2))
                  (type ssn))
            (test (< (- ?rn2 ?rn1) (- ?rowNumber2 ?rowNumber1)))))
=>
  (printout t (fact-slot-value ?w1 text) " - " (fact-slot-value ?w2 text) crlf)
)

-W
Reply | Threaded
Open this post in threaded view
|

RE: JESS: Find the minimum

Bob Crothers

 

Yes, this works! This meets my requirements.

 

Thank you Wolfgang.

 

This is similar to my first effort, which never fires. Can you explain the difference between the two rules.

 

My first effort

 

(defrule find-lines-per-block-ssn

           ?word1 <- (word (page ?page) (rowNumber ?rowNumber1) (type ssn) (text ?text1)  )

            ?word2 <- (word (page ?page) (rowNumber ?rowNumber2&:(<> ?rowNumber1 ?rowNumber2)) (type ssn) (text ?text2) )

            (not

        (word (page ?page) (rowNumber ?rowNumberVar&:(< (abs (- ?rowNumberVar ?rowNumber1) ) (abs (- ?rowNumber2 ?rowNumber1) ) ) ) )

            )

=>

    ; do something

)

 

Thanks to everyone who responded. This was my first message to the forum.  Thanks for all the quick and helpful responses.

 

Bob

 

From: [hidden email] [mailto:[hidden email]] On Behalf Of Wolfgang Laun
Sent: Wednesday, August 24, 2011 10:27 AM
To: [hidden email]
Subject: Re: JESS: Find the minimum

 

Not sure whether this meets all the possibly undisclosed requirements, not sure about the relation of row numbers and words, but this is firing one, even when there is words from more than one page:

(defrule find-lines-per-block-ssn
  ?w1 <- (word (page ?page)
               (rowNumber ?rowNumber1)
               (type ssn)
               (text ?text1))
  ?w2 <- (word (page ?page)
               (rowNumber ?rowNumber2 &:(< ?rowNumber1 ?rowNumber2))
               (type ssn)
               (text ?text2))
  (not (and (word (page ?px)
                  (rowNumber ?rn1)
                  (type ssn))
            (word (page ?px)
                  (rowNumber ?rn2 &:(< ?rn1 ?rn2))
                  (type ssn))
            (test (< (- ?rn2 ?rn1) (- ?rowNumber2 ?rowNumber1)))))
=>
  (printout t (fact-slot-value ?w1 text) " - " (fact-slot-value ?w2 text) crlf)
)

-W