Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow exceptions to a group of rules #170

Closed
denismerigoux opened this issue Jan 3, 2022 · 0 comments
Closed

Allow exceptions to a group of rules #170

denismerigoux opened this issue Jan 3, 2022 · 0 comments
Assignees
Labels
🔧 compiler Issue concerns the compiler ✨ enhancement New feature or request 💡 language Language design

Comments

@denismerigoux
Copy link
Contributor

The problem

Suppose you have a piece of legislation that defines a quantity piecewise:

## Article 1

If the person is less than 25 years old, then the benefit is $1000.

```catala
scope Benefit:
  definition benefit under_condition person.age <= 25 consequence equals $1000
```

## Article 2

If the person is more than 25 years old, then the benefit is $500.

```catala
scope Benefit:
  definition benefit under_condition person.age > 25 consequence equals $500
```

Then, another article defines an exceptional case for the benefit:

## Article 3

If the person is disabled, the benefit is equal to $2000.

To formalize that in Catala, you would want the definition in article 3 to be an exception to the group of piecewise definitions in articles 1 and 2. However, you cannot do that currently since you can only declare an exception to a single rule. This situation happens in a real-world example :

champ d'application PrestationsFamiliales :
# TODO: ajouter le cas d'une ou plusieurs exceptions à un ensemble
# de définitions par morceaux regroupées par une même étiquette
# (non encore implémenté)
étiquette cas_base règle droit_ouvert de enfant sous condition
enfant.obligation_scolaire sous forme Avant ou
enfant.obligation_scolaire sous forme Pendant
conséquence rempli
.

Solution

Syntax

I propose to piggyback on the label syntax and allow to have the same label being applied to several definitions. Using the same label effectively "groups" them together :

scope Benefit:
  label benefits_base_case 
  definition benefit under condition person.age > 25 consequence equals $1000
  
  label benefits_base_case 
  definition benefit under condition person.age <= 25 consequence equals $500
  
  exception benefits_base_case
  definition benefit under condition person.is_disabled consequence equals $2000

Semantics

The semantics effect of this proposal will be limited to how the default tree is built from the various definitions and the exceptions relationships between them. The critical function that will be modified is

let def_map_to_tree (def_info : Ast.ScopeDef.t) (def : Ast.rule Ast.RuleMap.t) : rule_tree list =
let exc_graph = Dependency.build_exceptions_graph def def_info in
Dependency.check_for_exception_cycle exc_graph;
(* we start by the base cases: they are the vertices which have no successors *)
let base_cases =
Dependency.ExceptionsDependencies.fold_vertex
(fun v base_cases ->
if Dependency.ExceptionsDependencies.out_degree exc_graph v = 0 then v :: base_cases
else base_cases)
exc_graph []
in
let rec build_tree (base_case : Ast.RuleName.t) : rule_tree =
let exceptions = Dependency.ExceptionsDependencies.pred exc_graph base_case in
match exceptions with
| [] -> Leaf (Ast.RuleMap.find base_case def)
| _ -> Node (List.map build_tree exceptions, Ast.RuleMap.find base_case def)
in
List.map build_tree base_cases

In the current version, the vertices of the exceptions graph are single rules or definitions. With this proposal, the vertices should be sets of rules. Several rules r_1,...,r_n grouped together shall be encoded with the default < r_1 ... r_n | false :- EmptyError > so that they are at the same level exception-wise.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🔧 compiler Issue concerns the compiler ✨ enhancement New feature or request 💡 language Language design
Projects
None yet
Development

No branches or pull requests

1 participant