# Examples

### A simple decision tree involving facts

#### Decision matrix

<table data-view="cards"><thead><tr><th>Bureau Score</th><th>Marital Status</th><th>Business Ownership</th><th>Decision</th></tr></thead><tbody><tr><td>between 650 and 800</td><td>in [Married, Unspecified]</td><td>in [Owned by Self, Owned by Family]</td><td><strong>GO</strong></td></tr></tbody></table>

#### Rule specification

```
from simpleruleengine.conditional.when_all import WhenAll
from simpleruleengine.expression.expression import Expression
from simpleruleengine.operator.between import Between
from simpleruleengine.operator.string_in import In
from simpleruleengine.rulerow.rule_row_decision import RuleRowDecision
from simpleruleengine.ruleset.rule_set_decision import RuleSetDecision
from simpleruleengine.token.numeric_token import NumericToken
from simpleruleengine.token.string_token import StringToken

if __name__ == "__main__":
    cibil_score_between_650_800 = Expression(
        NumericToken("cibil_score"),
        Between(floor=650, ceiling=800)
    )
    marital_status_in_married_unspecified = Expression(
        StringToken("marital_status"),
        In("Married", "Unspecified")
    )
    business_owned_by_self_family = Expression(
        StringToken("business_ownership"),
        In("Owned by Self", "Owned by Family")
    )

    rule_row_decision_go = RuleRowDecision(
        WhenAll(
            cibil_score_between_650_800,
            marital_status_in_married_unspecified,
            business_owned_by_self_family
        ),
        "GO"
    )
    rule_set_decision = RuleSetDecision(rule_row_decision_go)

    # Evaluate a fact set against this rule and assert the results.
    fact = dict(
        cibil_score=700,
        marital_status="Married",
        business_ownership="Owned by Self"
    )
    assert rule_set_decision.evaluate(fact) == "GO"
```

### A complex decision tree involving multiple AND and OR conditions

#### Decision matrix

<table data-view="cards"><thead><tr><th>Applicant Age</th><th>Applicant Ownership</th><th>Business Ownership</th><th>Decision</th></tr></thead><tbody><tr><td>>=35</td><td>in [Owned by Self, Owned by Family]</td><td>in [Owned by Self, Owned by Family]</td><td>GO</td></tr><tr><td>>=35</td><td>in [Owned by Self, Owned by Family]</td><td>in [Rented]</td><td>GO</td></tr><tr><td>>=35</td><td>in [Rented]</td><td>in [Owned by Self, Owned by Family]</td><td>GO</td></tr><tr><td>>=35</td><td>in [Rented]</td><td>in [Rented]</td><td>NO GO</td></tr><tr><td>&#x3C;35</td><td>in [Rented]</td><td>in [Rented]</td><td>NO GO</td></tr><tr><td>&#x3C;35</td><td>in [Owned by Self, Owned by Family]</td><td>in [Rented]</td><td>NO GO</td></tr><tr><td>&#x3C;35</td><td>in [Rented]</td><td>in [Owned by Self, Owned by Family]</td><td>NO GO</td></tr><tr><td>&#x3C;35</td><td>in [Owned by Self, Owned by Family]</td><td>in [Owned by Self, Owned by Family]</td><td>GO</td></tr></tbody></table>

* when the applicant age is >=35, either of applicant ownership or business ownership must be Owned.
* When the applicant age is <35, both the applicant ownership and business ownership must be Owned.

#### Rule specification

```
from simpleruleengine.conditional.when_all import WhenAll
from simpleruleengine.conditional.when_any import WhenAny
from simpleruleengine.expression.expression import Expression
from simpleruleengine.operator.greater_than_equal import Gte
from simpleruleengine.operator.string_in import In
from simpleruleengine.rulerow.rule_row_decision import RuleRowDecision
from simpleruleengine.ruleset.rule_set_decision import RuleSetDecision
from simpleruleengine.token.numeric_token import NumericToken
from simpleruleengine.token.string_token import StringToken

if __name__ == "__main__":
    applicant_age_gte_35 = Expression(
        NumericToken("applicant_age"),
        Gte(35)
    )
    business_owned_by_self_family = Expression(
        StringToken("business_ownership"),
        In("Owned by Self", "Owned by Family")
    )
    applicant_owned_by_self_family = Expression(
        StringToken("applicant_ownership"),
        In("Owned by Self", "Owned by Family")
    )

    rule_row_decision_go = RuleRowDecision(
        WhenAll(
            applicant_age_gte_35,
            WhenAny(
                business_owned_by_self_family,
                applicant_owned_by_self_family
            )
        ),
        "GO"
    )
    rule_set_decision = RuleSetDecision(rule_row_decision_go)

    fact_go = dict(
        applicant_age=42,
        applicant_ownership="Not Owned",
        business_ownership="Owned by Self"
    )
    assert rule_set_decision.evaluate(fact_go) == "GO"

    fact_no_go_1 = dict(
        applicant_age=42,
        applicant_ownership="Not Owned",
        business_ownership="Not Owned"
    )
    assert rule_set_decision.evaluate(fact_no_go_1) != "GO"

    fact_no_go_2 = dict(
        applicant_age=25,
        applicant_ownership="Owned by Self",
        business_ownership="Owned by Self"
    )
    assert rule_set_decision.evaluate(fact_no_go_2) != "GO"
```

### A scoring rule involving multiple parameters

|         Rule set Name         | Weightage |
| :---------------------------: | :-------: |
|    no\_of\_running\_bl\_pl    |    0.5    |
| last\_loan\_drawn\_in\_months |    0.5    |

#### no\_of\_running\_bl\_pl

|            Condition            | Score |
| :-----------------------------: | :---: |
|   no\_of\_running\_bl\_pl >= 7  |  -100 |
|   no\_of\_running\_bl\_pl >= 4  |  -40  |
|   no\_of\_running\_bl\_pl >= 2  |   30  |
|   no\_of\_running\_bl\_pl >= 0  |  100  |
| no\_of\_running\_bl\_pl is none |  100  |

#### last\_loan\_drawn\_in\_months

|               Condition               | Score |
| :-----------------------------------: | :---: |
|   last\_loan\_drawn\_in\_months == 0  |   30  |
|    last\_loan\_drawn\_in\_months <3   |  -30  |
|  last\_loan\_drawn\_in\_months <= 12  |   40  |
|   last\_loan\_drawn\_in\_months >12   |  100  |
| last\_loan\_drawn\_in\_months is none |  100  |

#### Rule Specification

```
from simpleruleengine.conditional.when_all import WhenAll
from simpleruleengine.operator.greater_than_equal import Gte
from simpleruleengine.operator.greater_than import Gt
from simpleruleengine.operator.equal import Eq
from simpleruleengine.operator.less_than import Lt
from simpleruleengine.operator.less_than_equal import Lte
from simpleruleengine.rulerow.rule_row_score import RuleRowScore
from simpleruleengine.ruleset.rule_set_score import RuleSetScore
from simpleruleengine.rule.rule_score import RuleScore
from simpleruleengine.token.numeric_token import NumericToken
from simpleruleengine.expression.expression import Expression

if __name__ == "__main__":
    no_run_bl_pl_gte_7_score_minus_100 = RuleRowScore(
        WhenAll(Expression(NumericToken("no_of_running_bl_pl"), Gte(7))),
        -100
    )
    no_run_bl_pl_gte_4_score_minus_40 = RuleRowScore(
        WhenAll(Expression(NumericToken("no_of_running_bl_pl"), Gte(4))),
        -40
    )
    no_run_bl_pl_gte_2_score_30 = RuleRowScore(
        WhenAll(Expression(NumericToken("no_of_running_bl_pl"), Gte(2))),
        30
    )
    no_run_bl_pl_gte_0_score_100 = RuleRowScore(
        WhenAll(Expression(NumericToken("no_of_running_bl_pl"), Gte(0))),
        100
    )

    no_of_run_bl_pl_rule_set = RuleSetScore(
        no_run_bl_pl_gte_7_score_minus_100,
        no_run_bl_pl_gte_4_score_minus_40,
        no_run_bl_pl_gte_2_score_30,
        no_run_bl_pl_gte_0_score_100,
        weight=0.5
    )

    fact_no_run_bl_pl_2 = dict(no_of_running_bl_pl=2)
    assert no_of_run_bl_pl_rule_set.evaluate(fact_no_run_bl_pl_2) == 15.0

    last_loan_drawn_in_months_eq_0_score_30 = RuleRowScore(
        WhenAll(Expression(NumericToken("last_loan_drawn_in_months"), Eq(0))),
        30
    )
    last_loan_drawn_in_months_lt_3_score_minus_30 = RuleRowScore(
        WhenAll(Expression(NumericToken("last_loan_drawn_in_months"), Lt(3))),
        -30
    )
    last_loan_drawn_in_months_lte_12_score_40 = RuleRowScore(
        WhenAll(Expression(NumericToken("last_loan_drawn_in_months"), Lte(12))),
        40
    )
    last_loan_drawn_in_months_gt_12_score_100 = RuleRowScore(
        WhenAll(Expression(NumericToken("last_loan_drawn_in_months"), Gt(12))),
        100
    )

    last_loan_drawn_in_months_rule_set = RuleSetScore(
        last_loan_drawn_in_months_eq_0_score_30,
        last_loan_drawn_in_months_lt_3_score_minus_30,
        last_loan_drawn_in_months_lte_12_score_40,
        last_loan_drawn_in_months_gt_12_score_100,
        weight=0.5
    )

    fact_last_loan_drawn_in_months_lte_12 = dict(last_loan_drawn_in_months=6)
    assert last_loan_drawn_in_months_rule_set.evaluate(
        fact_last_loan_drawn_in_months_lte_12) == 20.0

    fact_rule_score = dict(last_loan_drawn_in_months=6, no_of_running_bl_pl=2)
    rule_score = RuleScore(
        no_of_run_bl_pl_rule_set,
        last_loan_drawn_in_months_rule_set
    )
    assert rule_score.execute(fact_rule_score) == 35.0

    no_run_bl_pl_gte_7_score_minus_100 = RuleRowScore(
        WhenAll(Expression(NumericToken("no_of_running_bl_pl"), Gte(7))), -100)
    no_run_bl_pl_gte_4_score_minus_40 = RuleRowScore(
        WhenAll(Expression(NumericToken("no_of_running_bl_pl"), Gte(4))), -40)
    no_run_bl_pl_gte_2_score_30 = RuleRowScore(
        WhenAll(Expression(NumericToken("no_of_running_bl_pl"), Gte(2))), 30)
    no_run_bl_pl_gte_0_score_100 = RuleRowScore(
        WhenAll(Expression(NumericToken("no_of_running_bl_pl"), Gte(0))), 100)

    no_of_run_bl_pl_rule_set = RuleSetScore(
        no_run_bl_pl_gte_7_score_minus_100,
        no_run_bl_pl_gte_4_score_minus_40,
        no_run_bl_pl_gte_2_score_30,
        no_run_bl_pl_gte_0_score_100,
        weight=0.5
    )

    fact_no_run_bl_pl_2 = dict(no_of_running_bl_pl=2)
    assert no_of_run_bl_pl_rule_set.evaluate(fact_no_run_bl_pl_2) == 15.0

    last_loan_drawn_in_months_eq_0_score_30 = RuleRowScore(
        WhenAll(Expression(NumericToken("last_loan_drawn_in_months"), Eq(0))),
        30
    )
    last_loan_drawn_in_months_lt_3_score_minus_30 = RuleRowScore(
        WhenAll(Expression(NumericToken("last_loan_drawn_in_months"), Lt(3))),
        -30
    )
    last_loan_drawn_in_months_lte_12_score_40 = RuleRowScore(
        WhenAll(Expression(NumericToken("last_loan_drawn_in_months"), Lte(12))),
        40
    )
    last_loan_drawn_in_months_gt_12_score_100 = RuleRowScore(
        WhenAll(Expression(NumericToken("last_loan_drawn_in_months"), Gt(12))),
        100
    )

    last_loan_drawn_in_months_rule_set = RuleSetScore(
        last_loan_drawn_in_months_eq_0_score_30,
        last_loan_drawn_in_months_lt_3_score_minus_30,
        last_loan_drawn_in_months_lte_12_score_40,
        last_loan_drawn_in_months_gt_12_score_100,
        weight=0.5
    )

    fact_last_loan_drawn_in_months_lte_12 = dict(last_loan_drawn_in_months=6)
    assert last_loan_drawn_in_months_rule_set.evaluate(
        fact_last_loan_drawn_in_months_lte_12) == 20.0

    fact_rule_score = dict(last_loan_drawn_in_months=6, no_of_running_bl_pl=2)
    rule_score = RuleScore(
        no_of_run_bl_pl_rule_set,
        last_loan_drawn_in_months_rule_set
    )
    assert rule_score.execute(fact_rule_score) == 35.0
```

### A nested rule that involves another rule for evaulation

#### Rule

* If cibil score is between 650 and 800, score is 100
* If cibil score is less than 650, score is 0
* Decide GO if pet in \[dog, cat] and cibil score is greater than 0

#### Rule Specification

```
from simpleruleengine.conditional.when_all import WhenAll
from simpleruleengine.expression.expression import Expression
from simpleruleengine.operator.between import Between
from simpleruleengine.operator.greater_than import Gt
from simpleruleengine.operator.greater_than_equal import Gte
from simpleruleengine.operator.string_in import In
from simpleruleengine.operator.less_than_equal import Lte
from simpleruleengine.operator.less_than import Lt
from simpleruleengine.operator.string_not_in import NotIn
from simpleruleengine.rulerow.rule_row_decision import RuleRowDecision
from simpleruleengine.ruleset.rule_set_decision import RuleSetDecision
from simpleruleengine.rulerow.rule_row_score import RuleRowScore
from simpleruleengine.ruleset.rule_set_score import RuleSetScore
from simpleruleengine.token.numeric_token import NumericToken
from simpleruleengine.token.string_token import StringToken
from simpleruleengine.token.rule_token import RuleToken
from simpleruleengine.rule.rule_score import RuleScore

if __name__ == "__main__":
    cibil_score_between_650_800 = Expression(
        NumericToken("cibil_score"),
        Between(floor=650, ceiling=800)
    )

    cibil_score_lt_650 = Expression(
        NumericToken("cibil_score"),
        Lt(650)
    )

    rule_row_between_650_800 = RuleRowScore(
        antecedent=WhenAll(cibil_score_between_650_800),
        consequent=100
    )

    rule_row_between_lt_650 = RuleRowScore(
        antecedent=WhenAll(cibil_score_lt_650),
        consequent=0
    )

    rule_set_cibil_score = RuleSetScore(
        rule_row_between_lt_650,
        rule_row_between_650_800,
        weight=1
    )

    rule_cibil_score = RuleScore(rule_set_cibil_score)

    fact = dict(cibil_score=350)
    assert rule_cibil_score.execute(fact) == 0

    expression_pet_in_dog_cat = Expression(
        StringToken(name="pet"),
        In("dog", "cat")
    )

    expression_cibil_score_gt_0 = Expression(
        RuleToken(name="cibil_rule", rule=rule_cibil_score),
        Gt(0)
    )

    when_all_cibil_and_pet = WhenAll(
        expression_cibil_score_gt_0,
        expression_pet_in_dog_cat
    )

    rule_row_go_cibil_and_pet = RuleRowDecision(
        antecedent=when_all_cibil_and_pet,
        consequent="GO"
    )

    rule_set_decision_cibil_score_and_pet = RuleSetDecision(
        rule_row_go_cibil_and_pet)

    fact = dict(cibil_score=350, pet="dog")
    assert rule_set_decision_cibil_score_and_pet.evaluate(fact) != "GO"

    fact = dict(cibil_score=725, pet="dog")
    assert rule_set_decision_cibil_score_and_pet.evaluate(fact) == "GO"
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://jeyabalajis.gitbook.io/simple-rule-engine/examples.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
