Duetto
Duetto

Reputation: 19

is it possible to use the result of a defquery by a defrule?

i'm moving along in jess. the problem that i'm using jess for is to allocate docks to members based on a set of rules. the process starts when a dock is put in the pool of available docks. the list of available docks is then compared to the dock request list. i did this part using a defquery. for simplicity i have just one available dock with 2 members requesting it. at this point i would like to start to apply the rules to the result of the query.

i have successfully tested the defquery and the defrule - separately, but don't understand how to have the rule act on the defquery result.

is it possible? i have included the defrule and defquery below

duetto

(defglobal ?*curSlip* = nil ?*cand* = nil)
(deftemplate bid
  (slot person)
  (slot slipRequestedID)
  (slot boatID))
(deftemplate slip
  (slot slipID)
  (slot slength)
  (slot swidth)
  (slot sdepth))
(deftemplate person
  (slot name)
  (slot bycseniority)
  (slot boatID)
  (slot currentSlip))
(deffacts members
  (person (name John)(bycseniority 34)(boatID GEM)(currentSlip A8))
  (person (name Joe)(bycseniority  50)(boatID MS#$)(currentSlip B9))
  (person (name Frank)(bycseniority  120)(boatID DoryO)(currentSlip B8)))
(deffacts bids
  (bid (person John) (slipRequestedID A13) (boatID GEM))
  (bid (person Joe) (slipRequestedID A13) (boatID FarNiente))
  (bid (person Frank) (slipRequestedID B9) (boatID DoryO)))
(deffacts freeSlips
  (slip (slipID A13)))
(defrule mostSenior
   (person (name ?name) (bycseniority ?senior))
   (not (person (name ~?name) (bycseniority ?bycmem&:(< ?bycmem ?senior))))
   =>
   (bind ?*cand* ?name)
   (printout t ?*cand* " is the most senior." crlf))
(defquery bidLookup
    (declare (variables ?slipID))
        (bid (person ?pers) (slipRequestedID ?slipID)))
(reset)
(bind ?collOfBids (run-query* bidLookup A13))
    (while (?collOfBids next)
        (printout t (?collOfBids getString pers) crlf)    
    )

Upvotes: 0

Views: 35

Answers (1)

laune
laune

Reputation: 31290

You are leaving the rule-based approach after locating the most senior person. The fact(s) you need for assigning (or denying) a slot request to the most senior person are already in working-memory. Therefore, running a query doesn't yield any new information.

You could add conditions to the mostSenior rule, first establishing that the most senior person has made a bid (any bids) and, second, that the requested slip has a matching slip. If this rule fires, you have the first allocation (and may remove a bid and a slip).

You'll need to consider what happens when the most senior member isn't requesting anything: perhaps write another rule to remove him from WM. Also, a bid of the most senior member may not have a match, and you may have to remove that to make the "senior-has-no-bids" rule to fire.

Don't worry about duplicating conditions in different rules. The engine is built to deal efficiently with this.

Upvotes: 0

Related Questions