I couldn't agree more with james and donald. Having a ton of if/then/else statements in the RHS really should be avoided. One of the benefits of using a rule-centric approach is it helps you see the logic. I find that having deeply nested if/then/else often hides logical flaws that are hard to fix and debug. Think of it like having small simple methods in your java code versus having a gigantic java method with thousands of lines.
On Fri, Jan 7, 2011 at 10:35 AM, Donald Paul Winston <satchwins...@yahoo.com> wrote: > So many if else statements on the RHS is "unruly". > On Jan 7, 2011, at 9:15 AM, Derek Adams wrote: > > 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 <wolfgang.l...@gmail.com> > 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 <dad...@arahant.com> 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 >> > <wolfgang.l...@gmail.com>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 <wolfgang.l...@gmail.com> 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 y...@address.com' >> in the BODY of a message to majord...@sandia.gov, NOT to the list >> (use your own address!) List problems? Notify owner-jess-us...@sandia.gov. >> -------------------------------------------------------------------- >> > > > > -- > Derek Adams > Lead Developer > Arahant LLC > Work: 615-376-5500 ext. 314 > Cell: 270-543-0920 > > -------------------------------------------------------------------- To unsubscribe, send the words 'unsubscribe jess-users y...@address.com' in the BODY of a message to majord...@sandia.gov, NOT to the list (use your own address!) List problems? Notify owner-jess-us...@sandia.gov. --------------------------------------------------------------------