Thanks for the help guys. Here is what I ended up with. This works, but
I'm sure it's not the most efficient way to solve the problem.
(defrule setCalculatedCostGCI20k5k
(HrBenefitJoin (hrBenefitConfigId "00001-0000000076")(benefitJoinId
?bjid)(calculatedCost ?cost)(OBJECT ?obj)(coveredPersonId
?cPer)(payingPersonId ?pPer)(relationshipId ?rel))
(Person (personId ?cPer)(dob ?dob)(OBJECT ?objP))
=>
(printout t "age = " (call ?objP calcAgeAsOf(call
com.arahant.utils.DateUtils now )) " for " ?bjid " " crlf)
(if (eq ?rel nil) then
(if (< (call ?objP calcAgeAsOf(call com.arahant.utils.DateUtils now
)) 30) then
(call ?obj overrideAgeCost 11.55)
else (if (< (call ?objP calcAgeAsOf(call
com.arahant.utils.DateUtils now )) 40) then
(call ?obj overrideAgeCost 18.95)
else (if (< (call ?objP calcAgeAsOf(call
com.arahant.utils.DateUtils now )) 50) then
(call ?obj overrideAgeCost 38.35)
else (if (< (call ?objP calcAgeAsOf(call
com.arahant.utils.DateUtils now )) 60) then
(call ?obj overrideAgeCost 65.95)
else (if (< (call ?objP calcAgeAsOf(call
com.arahant.utils.DateUtils now )) 70) then
(call ?obj overrideAgeCost 104.35)
else
(printout t "age greater than 69 ... "
(call ?objP calcAgeAsOf(call com.arahant.utils.DateUtils now )) " for "
?bjid " " crlf))))))
else (if (neq ?rel nil) then
(if (< (call ?objP calcAgeAsOf(call
com.arahant.utils.DateUtils now )) 30) then
(call ?obj overrideAgeCost 4.20)
else (if (< (call ?objP calcAgeAsOf(call
com.arahant.utils.DateUtils now )) 40) then
(call ?obj overrideAgeCost 6.05)
else (if (< (call ?objP calcAgeAsOf(call
com.arahant.utils.DateUtils now )) 50) then
(call ?obj overrideAgeCost 10.90)
else (if (< (call ?objP calcAgeAsOf(call
com.arahant.utils.DateUtils now )) 60) then
(call ?obj overrideAgeCost 17.80)
else (if (< (call ?objP calcAgeAsOf(call
com.arahant.utils.DateUtils now )) 70) then
(call ?obj overrideAgeCost
27.40)
else
(printout t "age greater than 69
... " (call ?objP calcAgeAsOf(call com.arahant.utils.DateUtils now )) " for
" ?bjid " " crlf))))))))
(printout t "setCalculatedCostGCI function fired for " ?bjid ".
overrideAgeCost = " (call ?obj overrideAgeCost) crlf)
; (printout t "setCalculatedCostGCI function fired for " ?bjid " " crlf)
)
On Thu, Jan 6, 2011 at 10:32 AM, Wolfgang Laun <[email protected]>wrote:
> This additional information does not require a fundamentally different
> approach.
>
> Using the same set of facts CostEmployee/CostSpouse, we can now use
> two rules, one calculating the cost for the employee, and the other
> one for the spouse.
>
> (defrule calc-self
> ?hbj <- (HrBenefitJoin (hrBenefitConfigId "00001-0000000073")
> (calculatedCost 0)
> {relationshipId == nil}
> (payingPersonId ?pPer)
> (coveredPersonId ?cPer) )
> (Person (personId ?cPer) (dob ?dob) )
> (CostEmployee (lo ?lo&:(<= ?lo (yrs ?dob)))
> (hi ?hi&:(>= ?hi (yrs ?dob)))(cost ?cost))
> =>
> (printout t "Cost for " ?cPer " paid by himself: " ?cost crlf )
> )
>
> (defrule calc-other
> ?hbj <- (HrBenefitJoin (hrBenefitConfigId "00001-0000000073")
> (calculatedCost 0)
> {relationshipId != nil}
> (payingPersonId ?pPer)
> (coveredPersonId ?cPer) )
> (Person (personId ?cPer) (dob ?dob) )
> (CostSpouse (lo ?lo&:(<= ?lo (yrs ?dob)))
> (hi ?hi&:(>= ?hi (yrs ?dob)))(cost ?cost))
> =>
> (printout t "Cost for " ?cPer " paid by " ?pPer ": " ?cost crlf )
> )
>
> The date calculation is abstracted into a
> (deffunction yrs (?dob) ... (return ?yrs) )
>
> Implementing this in Jess or in Java is a simple programming exercise,
> but it presumably it depends on some technical/legal issues, e.g., it
> may not be possible to use "today" as a basis for calculating the
> difference in years from the person's dob.
>
> Since there's no information what to do with the resulting cost, it's
> just printed to standard output, but updating slot calculatedCost in
> HrBenefitJoin is straightforward.
>
> Cheers
> Wolfgang
>
>
> On 05/01/2011, Derek Adams <[email protected]> wrote:
> > the facts that I am working with are:
> >
> > (HrBenefitJoin (hrBenefitConfigId "00001-0000000073")(benefitJoinId
> > ?bjid)(calculatedCost ?cost)(OBJECT ?obj)(coveredPersonId
> > ?cPer)(payingPersonId ?pPer)(relationshipId ?rel))
> > (Person (personId ?cPer)(dob ?dob)(OBJECT ?objP))
> >
> > ?rel is what identifies the "covered person" as spouse or employee. If
> ?rel
> > is nil, it's employee, else it's spouse.
> >
> > So ?objP is my covered person (either spouse or employee).
> >
> > On Wed, Jan 5, 2011 at 3:36 PM, Wolfgang Laun
> > <[email protected]>wrote:
> >
> >> With this kind of problem, there are (at least) two approaches. Given
> that
> >> Employee and Spouse are represented as facts:
> >> (deftemplate Spouse (slot name)(slot age))
> >> (deftemplate Employee (slot name)(slot age)(slot spouse))
> >>
> >> (deffacts test-facts
> >> (Employee (name "John Smith")(age 35)(spouse "Jane Smith"))
> >> (Spouse (name "Jane Smith")(age 28))
> >> (Employee (name "Honey Rider")(age 39)(spouse "James Rider"))
> >> (Spouse (name "James Rider")(age 45))
> >> )
> >>
> >> (1) You can write one rule for each possible combination of age
> brackets.
> >>
> >> (defrule compute_1_1
> >> (Employee (name ?name){age >= 18 && age <= 29}(spouse ?spouse))
> >> (Spouse {name == ?spouse}{age >= 18 && age <= 29})
> >> =>
> >> (printout t "cost " ?name " " (+ 11.55 6.65) crlf)
> >> )
> >> ... more boring code ...
> >> (defrule compute_3_3
> >> (Employee (name ?name){age >= 40 && age <= 49}(spouse ?spouse))
> >> (Spouse {name == ?spouse}{age >= 40 && age <= 49})
> >> =>
> >> (printout t "cost " ?name " " (+ 38.35 20.05) crlf)
> >> )
> >>
> >> (2) You can represent the tables for the costs as facts:
> >> (deftemplate CostEmployee (slot lo)(slot hi)(slot cost))
> >> (deftemplate CostSpouse (slot lo)(slot hi)(slot cost))
> >>
> >> (deffacts costs
> >> (CostEmployee (lo 18)(hi 29)(cost 11.55))
> >> (CostEmployee (lo 30)(hi 39)(cost 18.95))
> >> (CostEmployee (lo 40)(hi 49)(cost 38.35))
> >> (CostSpouse (lo 18)(hi 29)(cost 6.65))
> >> (CostSpouse (lo 30)(hi 39)(cost 10.35))
> >> (CostSpouse (lo 40)(hi 49)(cost 20.05))
> >> )
> >>
> >> and use a single rule:
> >>
> >> (defrule compute
> >> (Employee (name ?name)(age ?ageE)(spouse ?spouse))
> >> (Spouse {name == ?spouse}(age ?ageS))
> >> (CostEmployee {lo <= ?ageE}{hi >= ?ageE}(cost ?costE))
> >> (CostSpouse {lo <= ?ageS}{hi >= ?ageS}(cost ?costS))
> >> =>
> >> (printout t "cost " ?name " " (+ ?costE ?costS) crlf)
> >> )
> >>
> >> HTH
> >> Wolfgang
> >>
> >>
> >>
> >>
> >>
> >> On 5 January 2011 22:30, Wolfgang Laun <[email protected]> wrote:
> >>
> >>> Sent on behalf of Derek Adams:
> >>>
> >>>
> >>> Hey Jess Users! This is my first post, so I apologize for anything
> >>> "noob"
> >>> that I say/do...
> >>>
> >>> I'm very new to Jess. I understand the basics but applying my
> knowledge
> >>> for the first time is proving more difficult than I anticipated. Here
> is
> >>> the problem:
> >>>
> >>> I need to set up a rule in Jess that calculates the cost of a benefit
> >>> based on age and enrollees.
> >>> *
> >>> Example:
> >>> The Benefit Configuration is "Employee $10k / Spouse $5k"
> >>> The enrollees are the employee (John Smith age 30) and spouse (Jane
> Smith
> >>> and 28).
> >>> The costs are calculated as follows:
> >>>
> >>> Age Employee Spouse
> >>> 18-29 11.55 6.65
> >>> 30-39 18.95 10.35
> >>> 40-49 38.35 20.05*
> >>>
> >>> *So John's cost is 18.95 and Jane's cost is 6.65 for a total of 25.60*.
> >>>
> >>> Any advice would be greatly appreciated!
> >>>
> >>> Thanks,
> >>>
> >>> Derek Adams
> >>>
> >>
> >>
> >
> >
> > --
> > *Derek Adams*
> > Lead Developer
> > Arahant LLC
> > Work: 615-376-5500 ext. 314
> > Cell: 270-543-0920
> >
>
>
> --------------------------------------------------------------------
> 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].
> --------------------------------------------------------------------
>
>
--
*Derek Adams*
Lead Developer
Arahant LLC
Work: 615-376-5500 ext. 314
Cell: 270-543-0920