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.
--------------------------------------------------------------------

Reply via email to