catala/examples/tutoriel_fr/tutoriel_fr.catala_fr

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

1050 lines
46 KiB
Plaintext
Raw Normal View History

# Tutoriel dutilisation du langage Catala
Bienvenue dans ce tutoriel, son objectif est de vous accompagner dans les
fonctionnalités du langage Catala et de vous apprendre dannoter des textes
législatifs avec ce langage. Ce document sadresse principalement à des
développeurs ou des personnes ayant déjà programmé, même si des juristes avec
des compétences en informatique devraient pouvoir sen sortir.
2022-02-14 01:40:23 +03:00
```catala
# Attention, ce tutoriel en français nest peut-être pas à jour avec
2022-02-14 01:40:23 +03:00
# les dernières fonctionnalités du langage. En effet, le tutoriel en anglais
# disponible sur https://catala-lang.org/en/examples/tutorial constitue
# la référence pour le langage.
# Bienvenue dans le code de Catala. Ceci est un commentaire, parce que la ligne
# est prefixée par #.
# Ce tutoriel ne couvre pas linstallation de Catala. Pour plus
# dinformations sur ce sujet, veuillez-vous référer à :
# https://github.com/CatalaLang/catala#building-and-installation
# Si vous souhaitez commencez votre propre programme Catala pour suivre ce
# tutoriel, créez simplement un fichier vide avec lextension .catala_fr
# et commencez à taper votre programme.
# Pour une référence complète de la syntaxe Catala, voyez sur:
# https://github.com/CatalaLang/catala/raw/master/doc/syntax/syntax.pdf
# Ce tutoriel est lui-même écrit comme un programme Catala et est accessible à :
# https://github.com/CatalaLang/catala/blob/master/examples/tutoriel_fr
2022-02-14 01:40:23 +03:00
```
## Programmation littéraire
Pour commencer à écrire un programme Catala, vous devez partir du texte
dune source législative qui va justifier le code que vous écrirez.
Concrètement, cela signifie de faire un copier-coller du texte de la loi dans un
fichier source Catala, et de le formater afin que Catala puisse le comprendre.
Les fichiers sources Catala ont lextension « .catala_en» en version anglaise.
Si vous écriviez un programme Catala pour une loi française, vous devrez
utiliser lextension « .catala_fr»; pour une loi polonaise, «catala_pl», etc.
Vous pouvez écrire nimporte quel texte simple en Catala, cela sera affiché
sans modification dans une sortie PDF ou HTML. Vous pouvez découper votre texte
en de courtes lignes de moins de 80 caractères, donnant un style «terminal»,
et cela apparaîtra comme un seul paragraphe en sortie. Si vous voulez créer un
nouveau paragraphe, laisser une ligne vierge dans le fichier source.
Dans un programme Catala, la syntaxe du texte, autre que du code, reprend un
sous-ensemble du langage Markdown qui supporte des titres et des blocs de code
Catala.
Catala vous permet de déclarer des en-têtes de section ou de sous-section,
comme cest le cas ici, avec le symbole «#». Vous pouvez diminuer limportance
du titre en augmentant le nombre de «#» après le titre de len-tête.
Généralement, la syntaxe de la programmation littéraire de Catala suit la
syntaxe de Markdown (bien quil nait pas toutes ses fonctionnalités).
Dans le reste de ce tutoriel, nous allons étudier un exemple fictif qui définit
un impôt sur le revenu. Cet impôt sur le revenu est définit à travers différents
articles de loi, chacun deux étant introduit par un en-tête. Le premier
commence ici:
### Article 1
Limpôt sur le revenu dun individu est calculé en tant quun pourcentage fixe
sur les revenus dune personne pour une année.
```catala
# Nous allons bientôt apprendre ce que lon doit écrire, ici, pour traduire
# le sens dun article de loi en code Catala.
# Pour créer un bloc de code Catala dans votre fichier, encadrez le avec
# les délimiteurs Markdown « ```catala» et « ``` ».
```
Afin de traduire cette définition fictive de limpôt sur le revenu en un
programme Catala, nous allons entremêler des bouts de code entre les phrases
2020-12-24 18:09:40 +03:00
du texte législatif. Chaque bout de code devra être aussi court que possible
et aussi proche que possible de la phrase qui justifie le code. Ce style
sappelle la programmation littéraire, un paradigme de programmation inventé
par le célèbre informaticien Donald Knuth dans les années 70.
## Définir un impôt fictif sur le revenu
Le contenu de larticle 1 utilise beaucoup déléments contextuels implicites:
2020-12-22 13:41:29 +03:00
il existe une personne avec un revenu et en même temps un impôt sur le revenu,
quune personne doit acquitter chaque année. Même si ce contexte implicite nest
pas inscrit en tant que tel dans la loi, nous devons lexpliciter pour le
traduire en code. Concrètement, nous avons besoin dune section «métadonnées»
qui définit la forme et les types de données contenues dans la loi.
Commençons notre section métadonnée en déclarant linformation sur le type
«personne», cest à dire le contribuable qui sera le sujet du calcul de
limpôt. Cette personne a un revenu et un nombre denfants, qui sont des
pièces dinformation qui seront nécessaires pour les objectifs fiscaux:
```catala-metadata
2020-12-22 13:41:29 +03:00
déclaration structure Personne:
# Le nom de la structure « Personne », doit commencer
# par une lettre majuscule: c'est la convention «CamelCase».
2020-12-22 13:41:29 +03:00
donnée revenu contenu argent
# A cette ligne, «revenu» est le nom du champ de la structure et
# «argent» est le type de données de ce champ.
# On peut utiliser dautres types comme : entier, décimal,
# argent, date, durée ou tout autre structure ou énumération
2020-12-24 18:09:40 +03:00
# que vous aurez déclaré
2020-12-22 13:41:29 +03:00
donnée nombre_enfants contenu entier
# «revenu» et «nombre_enfants» commencent par une lettre minuscule,
# ils adhèrent à la convention «snake_case».
```
Cette structure contient deux champs de données, «revenu» et
«nombre_enfants». Les structures sont utiles pour regrouper des données qui
vont ensemble. Typiquement, vous aurez une structure pour une entité concrète
sur laquelle sapplique la loi (comme une personne). Cest à vous de décider
comment regrouper les données, mais vous devrez viser à optimiser la lisibilité
du code.
2020-12-22 13:41:29 +03:00
Parfois, la loi donne une énumération de différentes situations. Ces énumérations
sont modélisées en Catala par le type énumération, comme suit :
```catala-metadata
2020-12-24 18:09:40 +03:00
déclaration énumération CréditImpôt:
# Le nom "CréditImpôt" sécrit aussi en «CamelCase»
2020-12-24 18:09:40 +03:00
-- AucunCréditImpôt
# Cette ligne indique que «CréditImpôt» peut être
# en situation « AucunCréditImpôt»
-- CréditImpôtEnfants contenu entier
# Cette ligne indique, de manière alternative, que «CréditImpôt» peut aussi
# être une situation «CréditImpôtEnfants». Cette situation porte un contenu
# de type entier qui correspond au nombre denfants concernés par le crédit
# dimpôt. Cela signifie que si vous êtes dans la situation
# «CréditImpôtEnfants», vous aurez aussi accès à ce nombre denfants.
```
En informatique, une telle énumération est appelée «type somme» ou simplement
énumération. La combinaison de structures et dénumération permet au programmeur
Catala de déclarer toutes les formes possibles de données, car cette combinaison
est équivalente à la puissante notion de «types de données algébriques».
2020-12-22 13:41:29 +03:00
Nous avons défini et typé les données que le programme va manipuler. Maintenant,
nous devons définir un contexte logique dans lequel ces données vont évoluer.
On effectue cela par la notion de «champ dapplication» en Catala.
Les champs dapplication sont proches des fonctions en termes de programmation
traditionnelle. Les champs dapplication doivent avoir été déclarés
2020-12-24 18:09:40 +03:00
préalablement dans les métadonnées, de la manière suivante:
```catala-metadata
2020-12-24 18:09:40 +03:00
déclaration champ d'application CalculImpôtRevenu:
# Les champs dapplication utilisent le CamelCase
entrée personne contenu Personne
2020-12-22 13:41:29 +03:00
# Cette ligne déclare un élémént de contexte du champ d'application,
# cela ressemble à un paramètre de fonction en informatique. C'est la
# donnée sur laquelle le champ d'application va intervenir
interne pourcentage_fixe contenu décimal
résultat impôt_revenu contenu argent
```
Le champ d'application est lunité dabstraction de base dans des programmes
Catala, et la déclaration du champ dapplication est semblable à une signature
de fonction: elle contient une liste de tous les paramètres ainsi que leurs
types. Mais dans Catala, les variables dun champ dapplication représentent
trois choses: paramètres dentrées, paramètres locaux et paramètres de
résultats. La différence entre les trois catégories peuvent être spécifiées par
les différents attributs dentrée/résultat qui précèdent les noms de variables.
«entrée» signifie que la variable doit être définie seulement quand le champ
dapplication «CalculImpôtRevenu» est appelé.
«interne» signifie que la variable ne peut pas être vue en dehors du champ
dapplication: elle nest ni une entrée, ni un résultat du champ dapplication.
«résultat» signifie quun appel au champdapplication peut récupérer la
valeur calculée de la variable. Notez quune variable peut aussi être
simultanément une entrée et un résultat du champ dapplication, dans ce cas
elle devrait être annotée avec "entrée résultat".
2020-12-22 13:41:29 +03:00
Nous avons maintenant tout ce dont nous avons besoin pour annoter le contenu
de larticle 1 qui a été copié ci-dessous.
### Article 1
Limpôt sur le revenu pour une personne est défini comme un pourcentage fixe
2020-12-22 15:44:40 +03:00
des revenus de la personne pour une année.
```catala
2020-12-24 18:09:40 +03:00
champ d'application CalculImpôtRevenu:
définition impôt_revenu égal à
2022-12-07 16:55:58 +03:00
personne.revenu * pourcentage_fixe
```
Dans le code, nous définissons à lintérieur de notre champ dapplication
le montant dimpôt sur le revenu selon la formule décrit dans larticle.
2021-10-11 15:40:44 +03:00
Quand nous définissons des formules, vous avez accès à tous les opérateurs
arithmétiques habituels: addition "+", soustraction "-", multiplication "*"
2020-12-24 18:09:40 +03:00
et division (barre oblique).
2020-12-22 15:44:40 +03:00
2022-12-07 16:55:58 +03:00
Toutefois, dans le code Catala, ces opérateurs peuvent avoir un sens légèrement
différent suivant les unités concernées. En effet, largent par exemple est
arrondi au centime. Le compilateur Catala sélectionne automatiquement
lopération appropriée: ici, de largent est multiplié par un pourcentage (soit
un nombre décimal), ce qui est une opération connue dont le résultat est une
quantité dargent, arrondie au centime. Dautres opérations sont rejetées, comme
la multiplication de deux quantités dargent entre elles, ou laddition de deux
dates.
Revenons à larticle 1, dont une question reste sans réponse: quelle est la
valeur du pourcentage fixe? Souvent, des valeurs précises sont définies
ailleurs dans les sources législatives. Ici, supposons que nous avons:
### Article 2
Le pourcentage fixe mentionné à larticle 1 est égal à 20%.
```catala
2020-12-24 18:09:40 +03:00
champ d'application CalculImpôtRevenu:
définition pourcentage_fixe égal à 20%
# Ecrire 20% est juste une abbréviation pour «0.20 »
```
2020-12-22 15:44:40 +03:00
Vous pouvez voir ici que Catala permet des définitions réparties dans toute
lannotation du texte législatif, afin que chaque définition soit le plus
2020-12-22 15:44:40 +03:00
proche possible de sa localisation dans le texte.
## Définitions conditionnelles
Jusqu'à là tout va bien mais maintenant le texte législatif présente quelques
difficultés. Supposons que le troisième article sécrit:
### Article 3
2020-12-22 15:44:40 +03:00
Si lindividu a à sa charge deux ou plus enfants, alors
le pourcentage fixe mentionné à larticle 1 vaut 15 %.
```catala
# Comment redéfinir «pourcentage_fixe»?
```
Cet article donne en réalité une autre définition pour le pourcentage fixe,
préalablement défini à larticle 2. De plus, larticle 3 définit le pourcentage
de manière conditionnelle pour la personne ayant plus de deux enfants.
Catala permet de redéfinir précisément une variable sous une condition:
```catala
2020-12-24 18:09:40 +03:00
champ d'application CalculImpôtRevenu:
2020-12-22 15:44:40 +03:00
définition pourcentage_fixe sous condition
personne.nombre_enfants >= 2
2020-12-24 18:09:40 +03:00
conséquence égal à 15%
# Ecrire 15% est juste une abbréviation pour «0.15 »
```
Quand le programme Catala va sexécuter, la juste définition sera choisie
dynamiquement en déterminant quelle condition est vraie, selon le contexte.
Une source législative rédigée correctement doit toujours garantir quune seule
condition, au maximum, soit vraie à tout moment. Toutefois, si ce nest pas
le cas, Catala vous permettra de définir un ordre des priorités sur les
conditions, qui devra être justifié par un raisonnement juridique. Mais nous
verrons comment faire cela plus tard.
## Règles
Jusquà présent, vous avez appris comment déclarer un champ dapplication avec
quelques variables, et donner des définitions à ces variables dispersées à
travers le texte de la loi, à des endroits pertinents. Mais il y a un modèle
très fréquent dans des textes législatifs: quen est-il des conditions? Une
condition est une valeur qui peut être soit vraie ou fausse, comme un booléen
en programmation. Cependant, la loi suppose implicitement quune condition est
fausse, sauf indication contraire. Ce modèle est si commun en droit que Catala
lui donne une syntaxe spéciale. Plus précisément, il nomme la définition
de conditions des «règles», ce qui coïncide avec le sens habituel que les gens
lui donneraient.
Voici un exemple de condition qui pourrait survenir dans la loi:
### Article 3 bis
Les enfants éligiblent à lapplication de larticle 3.
```catala
# Pour traiter légibilité des enfants,
# nous créons un nouveau champ dapplication.
déclaration champ d'application Enfant:
entrée âge contenu entier
# Lâge de lenfant peut être déclarée comme ci-dessus.
résultat éligible_à_article_3 condition
# Nous déclarons léligibilité en utilisant le mot-clé spécial «condition»
# qui représente le contenu de la variable.
champ d'application Enfant:
règle éligible_à_article_3 sous condition âge < 18 conséquence rempli
# Au moment de définir la valeur dune condition à vraie, nous utilisons
# la syntaxe spéciale «règle» au lieu de «définition». Les règles fixent
# les conditions à «rempli» ou à «non rempli» par des tests conditionnels.
```
Lors de linteraction avec dautres éléments du code, les valeurs
des conditions se comportent comme des valeurs booléennes.
## Fonctions
Catala vous permet de définir des fonctions partout dans vos données. En effet,
Catala est un langage de programmation fonctionnel et encourage, en utilisant
des fonctions, à décrire les relations entre les données. Voici à quoi
cela ressemble, dans la définition des métadonnées, lorsque nous voulons
définir un calcul de limpôt sur le revenu à deux tranches :
2020-12-22 16:10:09 +03:00
```catala-metadata
2020-12-22 16:10:09 +03:00
déclaration structure DeuxTranches:
donnée seuil contenu argent
donnée taux1 contenu décimal
donnée taux2 contenu décimal
# Cette structure décrit les paramètres dun calcul de la formule de limpôt qui
# possède deux tranches dimpôts, chacune avec leur propre taux dimposition.
2020-12-22 16:10:09 +03:00
2020-12-24 18:09:40 +03:00
déclaration champ d'application CalculImpôtDeuxTranches :
entrée tranches contenu DeuxTranches
# Cette variable dentrée contient la description des paramètres
# de la formule dimposition.
résultat formule_imposition contenu argent
dépend de revenu contenu argent
# Mais en déclarant la variable «formule_imposition», nous la déclarons
# comme une fonction : «contenu argent dépend de »signifie quune fonction
# retourne de «largent» en résultat (limpôt) et prend de «largent» en
# entrée (le revenu).
```
2020-12-22 16:10:09 +03:00
Et dans le code :
### Article 4
Le montant de limpôt pour le calcul à deux tranches est égal au montant
de limpôt de chaque tranche, multiplié par le taux de chaque tranche.
```catala
2020-12-24 18:09:40 +03:00
champ d'application CalculImpôtDeuxTranches :
2020-12-22 16:10:09 +03:00
définition formule_imposition de revenu égal à
# Le paramètre de type «argent», de la fonction «formule_imposition»,
# est «revenu». Le nom du paramètre peut-être ce que vous voulez, et cela
# nimpactera pas les autres parties du code en dehors de la définition.
# Vous pouvez choisir un autre nom pour le paramètre, lors de sa définition,
# de la fonction «formule_imposition».
2022-12-07 16:55:58 +03:00
si revenu <= tranches.seuil alors
revenu * tranches.taux1
2020-12-22 16:10:09 +03:00
sinon (
2022-12-07 16:55:58 +03:00
tranches.seuil * tranches.taux1 +
(revenu - tranches.seuil) * tranches.taux2
)
# Cest cette formule pour implémenter un système à deux tranches.
```
## Inclusion dun champ d'application
2020-12-22 16:27:49 +03:00
Maintenant que nous avons défini notre champ d'application utilitaire pour
calculer un impôt à deux tranches, nous voulons lutiliser dans notre champ
dapplication principal du calcul de limpôt. Comme mentionné précédement, le
champ d'application de Catala peut être aussi pensé comme de grandes fonctions.
Et ces grandes fonctions peuvent sappeler entre elles, cest ce que nous allons
voir dans larticle ci-dessous.
2020-12-22 16:27:49 +03:00
### Article 5
Pour les individus dont le revenu est supérieur à 100 000€, limpôt sur
le revenu de larticle 1 est de 40% du revenu au-delà de 100 000€.
En dessous de 100 000€, limpôt sur le revenu est de 20% du revenu.
```catala
2020-12-24 18:09:40 +03:00
déclaration champ d'application NouveauCalculImpôtRevenu:
deux_tranches champ d'application CalculImpôtDeuxTranches
# Cette ligne indique que nous ajoutons lélément «deux_tranches»
# au contexte. Toutefois, le mot-clé «champ d'application» indique
# que lélément nest pas une donnée mais plutôt un sous-champ d'application,
# qui peut être utilisé pour calculer des choses.
entrée personne contenu Personne
résultat impôt_revenu contenu argent
2020-12-22 16:27:49 +03:00
2020-12-24 18:09:40 +03:00
champ d'application NouveauCalculImpôtRevenu :
# Puisque le sous-champ dapplication «deux_tranches» est une grande
# fonction que nous pouvons appelé, nous avons besoin de définir ses
# paramètres. Ceci est fait ci-dessous:
2020-12-22 16:27:49 +03:00
définition deux_tranches.tranches égal à DeuxTranches {
-- seuil: 100 000€
2020-12-22 16:27:49 +03:00
-- taux1: 20%
-- taux2: 40%
}
# En définissant la variable dentrée «tranches», du sous-champ
# dapplication «deux_tranches», nous avons changé la manière dont
# le sous-champ dapplication séxécutera. Le sous-champ d'application
# séxécutera avec toutes les valeurs définies par lappelant, puis calculera
# la valeur de ses autres variables.
définition impôt_revenu égal à
deux_tranches.formule_imposition de personne.revenu
# Après que le sous-champ d'application ait été éxécuté, vous pouvez en
# récupérer les résultats. Ci-dessus, vous récupérez les résultats de la
# variable «formule_imposition» calculée par le sous-champ dapplication
# «deux_tranches». Cest à vous de choisir ce qui est une entrée et un
# résultat de votre sous-champ d'application; si vous faites un choix
# incohérent, le compilateur Catala vous en avertira.
```
Maintenant que vous avez réussi de définir le calcul dimpôt sur le revenu,
le législateur vient inévitablement pérturber nos belles et irréprochables
formules pour rajouter un cas particulier ! Larticle ci-dessous est un
modèle très fréquent dans les lois, et allez voir comment Catala le gère.
### Article 6
Les personnes ayant moins de 10 000€ de revenus sont exemptés de limpôt
sur le revenu prévu à larticle 1.
```catala
2020-12-24 18:09:40 +03:00
champ d'application NouveauCalculImpôtRevenu:
# Ici, nous définissons simplement une nouvelle définition conditionnelle
# pour «limpôt sur le revenu», qui manipule le cas particulier.
définition impôt_revenu sous condition
2022-12-07 16:55:58 +03:00
personne.revenu <= 10 000€
conséquence égal à 0€
# Quoi? Pensez-vous que quelque chose peut-être faux avec ceci?
# Hmmm… Nous verrons cela plus tard!
```
Et voilà! Nous avons défini un calcul dimpôt à deux tranches en annotant
tout simplement un texte législatif par des bouts de code Catala.
Cependant, les lecteurs attentifs ont vu quelque chose de curieux dans les
articles 5 et 6. Que se passe-t-il si le revenu dune personne est inférieur
à 10 000€? Tout de suite, les deux définitions de larticle 5 et 6
pour limpôt sur le revenu sappliquent, et ils sont en conflit.
2020-12-22 16:49:56 +03:00
La loi ne le précise pas; nos articles sont clairement mal rédigés.
Mais Catala vous aide à trouver ce genre derreur par de simples tests ou
2020-12-22 16:49:56 +03:00
même la vérification formelle. Commençons par les tests.
## Tester les programmes Catala
2020-12-22 17:48:28 +03:00
Tester les programmes Catala peut se faire directement en Catala. En effet,
écrire des cas de tests pour chaque champ dapplication Catala que vous
définissez est une bonne pratique, qui est appelée «tests unitaires» dans
la communauté du génie logicielle.
Les cas de test sont définis dans des champs dapplication :
### Tester NouveauCalculImpotRevenu
```catala
2020-12-22 17:48:28 +03:00
déclaration champ d'application Test1:
# Incluons le champ dapplication du calcul de limpôt comme un sous-champ
calcul_impôt champ d'application NouveauCalculImpôtRevenu
résultat impôt_revenu contenu argent
2020-12-22 17:48:28 +03:00
# Pour éxécuter ce test, en supposant que le compilateur Catala peut être
# appelé avec «catala», entrez la commande suivante:
# catala Interpret --scope=Test1 tutoriel_fr.catala_fr
2020-12-22 17:48:28 +03:00
champ d'application Test1:
définition calcul_impôt.personne égal à
# On définit le paramètre au sous-champ dapplication, puis les
# quatre lignes ci-dessous définissent une structure entière,
# dans laquelle nous y mettons des valeurs.
2020-12-22 17:48:28 +03:00
Personne {
-- revenu: 230 000€
2020-12-22 17:48:28 +03:00
-- nombre_enfants: 0
}
définition impôt_revenu égal à calcul_impôt.impôt_revenu
# Ensuite nous récupérons le montant de limpôt, calculé par
# le sous-champ dapplication, et nous écrivons lassertion de
# la valeur attendue: (230 000€ - 100 000€) * 40% + 100 000€ * 20% = 72 000€
assertion impôt_revenu = 72 000€
```
2020-12-22 17:48:28 +03:00
Ce test devrait être bon. Maintenant étudions un test en échec :
```catala
2020-12-22 17:48:28 +03:00
déclaration champ d'application Test2:
calcul_impôt champ d'application NouveauCalculImpôtRevenu
résultat impôt_revenu contenu argent
2020-12-22 17:48:28 +03:00
champ d'application Test2:
2020-12-24 18:09:40 +03:00
définition calcul_impôt.personne égal à Personne {
-- revenu: 4 000€
2020-12-22 17:48:28 +03:00
-- nombre_enfants: 0
}
définition impôt_revenu égal à calcul_impôt.impôt_revenu
assertion impôt_revenu = 0€
```
Ce cas de test devrait calculer un impôt sur le revenu de 0€,
en raison de larticle 6. Mais au lieu de cela, lexécution produira
2020-12-22 17:48:28 +03:00
une erreur car il y a un conflit entre les règles.
## Définir des exceptions à des règles
En effet, la définition dun impôt sur le revenu à larticle 6 entre en
conflit avec la définition de larticle 5. Mais en réalité, larticle 6
est une simple exception à larticle 5. Dans la loi, il est implicite que
si larticle 6 est applicable, alors son application est prioritaire
sur larticle 5.
### Régler correctement le calcul
Cette priorité implicite doit être explicitement déclarée en Catala.
Voici une version correcte du champ d'application NouveauCalculImpotRevenu:
```catala
2020-12-24 18:09:40 +03:00
déclaration champ d'application NouveauCalculImpôtRevenuCorrect:
deux_tranches champ d'application CalculImpôtDeuxTranches
entrée personne contenu Personne
résultat formule_imposition contenu argent dépend de revenu contenu argent
contexte résultat impôt_revenu contenu argent
# Cette variable est marquée avec un «contexte», un nouveau concept que
# nous navons pas encore introduit. Pour le moment, ignorons le jusquà
# ce que nous revenions dessus dans la section «Variables de contexte».
2020-12-22 17:48:28 +03:00
2020-12-24 18:09:40 +03:00
champ d'application NouveauCalculImpôtRevenuCorrect :
2020-12-22 17:48:28 +03:00
définition deux_tranches.tranches égal à DeuxTranches {
-- seuil: 100 000€
2020-12-22 17:48:28 +03:00
-- taux1: 20%
-- taux2: 40%
}
définition formule_imposition de revenu égal à
deux_tranches.formule_imposition de revenu
```
Pour définir une exception à une règle, vous devez dabord étiquetter
la règle à laquelle vous voulez attacher lexception. Vous pouvez mettre
nimporte quel identifiant en «snake_case» pour létiquette:
```catala
champ d'application NouveauCalculImpôtRevenuCorrect:
étiquette article_5
2023-04-05 20:05:23 +03:00
définition impôt_revenu égal à
deux_tranches.formule_imposition de personne.revenu
2020-12-22 17:48:28 +03:00
# Puis, vous pouvez déclarez lexception qui se réfère à létiquette
exception article_5
définition impôt_revenu sous condition
2022-12-07 16:55:58 +03:00
personne.revenu <= 10 000€
conséquence égal à 0€
```
Et le test devrait désormais fonctionner :
```catala
2020-12-22 17:48:28 +03:00
déclaration champ d'application Test3:
calcul_impôt champ d'application NouveauCalculImpôtRevenuCorrect
résultat impôt_revenu contenu argent
2020-12-22 17:48:28 +03:00
champ d'application Test3:
2020-12-24 18:09:40 +03:00
définition calcul_impôt.personne égal à Personne {
-- revenu: 4 000€
2020-12-22 17:48:28 +03:00
-- nombre_enfants: 0
}
définition impôt_revenu égal à calcul_impôt.impôt_revenu
assertion impôt_revenu = 0€
```
### Définir des exceptions aux groupes de règles
Notez que le système détiquettes vous permet de définir des modèles
dexception plus compliqués. Parfois, vous voulez déclarer une exception
à un groupe de définitions par morceau. Pour cela, utilisez simplement la
même étiquette à tout un morceau de définitions.
### Les exceptions cumulatives
Comme nous lavons vu… Deux exceptions sappliquant pour une même règle, au même
moment, sont en conflits et déclenchent une erreur. Cela arrive, cependant,
que ces exceptions produisent le même résultat à la fin: par convenance, Catala
tolère ce cas et retourne le résultat commun, aussi longtemps quil y a une
stricte égalité syntaxique.
#### Article 6 bis
Des personnes avec 7 enfants ou plus sont exonérées de limpôt sur le revenu
mentionné à larticle 1.
```catala
champ d'application NouveauCalculImpôtRevenuCorrect:
exception article_5
définition impôt_revenu sous condition
personne.nombre_enfants >= 7
conséquence égal à 0€
```
Le même problème devrait être déclenché ci-dessus, pour des familles avec un
revenu en dessous de 10 000€ et avec 7 enfants ou plus. Mais Catala peut
détecter quil ny aura pas de problèmes puisque le résultat est une éxonération
dans les 2 cas.
### Les appels directs au champ d'application
Dans certains cas, il est utile dappliquer le calcul dun champ dapplication
seulement sous des circonstances spécifiques. Par exemple, certaines allocations
sociales peuvent avoir différents modes de calcul, qui dépendent de la situation
des allocataires. Dans ce cas définir chacun de ces modes de calcul, comme un
sous-champ dapplication, est ennuyeux pour deux raisons: premièrement,
certaines valeurs en entrée peuvent ne pas être pertinantes dans des cas où
un allocataire nest pas concerné, et le langage continuera déxiger à ce que
vous ne laissez rien dindéfini; deuxièmement, un calcul inutile aura lieu.
Pour ces cas, il est possible dappeler un champ d'application directement, en
spécifiant en même temps toutes ses variables dentrées, et de récupérer ses
variables de résultat de la même manière quavec des sous-champs dapplication.
```catala
déclaration champ d'application Test5:
2023-04-05 20:05:23 +03:00
interne personne contenu Personne
interne est_applicable_au_calcul_normal_impôt_revenu contenu booléen
résultat impôt_revenu contenu argent
champ d'application Test5:
définition personne égal à Personne {
-- revenu: 7 000€
-- nombre_enfants: 7
}
définition impôt_revenu égal à
si est_applicable_au_calcul_normal_impôt_revenu alors
(résultat de NouveauCalculImpôtRevenuCorrect avec
{ -- personne: personne }).impôt_revenu
sinon 0€ # Insérez dautres modes de calcul ici
```
Ici le syntaxe «NouveauCalculImpôtRevenuCorrect avec» déclenche un appel
au champ dapplication, qui valorise sa variable dentrée «personne».
Ensuite, la syntaxe du point « . » est utilisée pour récupérer le résultat
«impôt_revenu» du champ dapplication.
## Les variables contextuelles dun champ d'application
Avec ses variables «entrée», «interne» et «résultat», les champs
dapplication de Catala sont proches des fonctions avec des paramètres,
des variables locales et des variables retournant un résultat. Cependant,
la loi peut parfois être contradictoire aux bonnes pratiques de programmation,
et ainsi définir des dispositions qui cassent la barrière dabstraction
normalement associée à une fonction.
Ceci peut être le cas quand un corps extérieur du texte législatif «réutilise»
un concept légal, mais en y ajoutant un changement. Considérez lexemple fictif
suivant (mais pas tout à fait pathologique dun point de vue informatique).
### Article 7
Le système de justice inflige des amendes aux individus quand ils commettent une
infraction. Les amendes sont déterminées en fonction du montant des impôts payés
par le particulier. Plus lindividu paie dimpôts, plus lamende est élevée.
Toutefois la détermination du montant de limpôt à payer par un particulier,
dans ce contexte, comprend des frais dimposition fixes de 500€ pour les
particuliers gagnant moins de 10 000€.
```catala
# Pour calculer la base qui détermine limposition de lamende, nous créons
# un nouveau champ dapplication.
déclaration champ d'application DétermineBaseAmende:
calcul_impôt champ d'application NouveauCalculImpôtRevenuCorrect
entrée personne contenu Personne
résultat base_amende contenu argent
champ d'application DétermineBaseAmende:
# Tout dabord, nous relions lentrée et le résultat des
# deux champs dapplications.
définition calcul_impôt.personne égal à personne
définition base_amende égal à calcul_impôt.impôt_revenu
# Mais ensuite, comment prend-on en compte lapplication de la loi qui
# rétablit le mécanisme dannulation de limpôt, pour les particuliers
# gagnant moins de 10 000€?
# C'est là que le concept de «contexte» entre en jeu. En effet, nous avions
# annoté la variable «impôt_revenu», de «NouveauCalculImpôtRevenuCorrect»,
# avec lattribut «contexte».
# «contexte» est une variante de «entrée» qui expose la variable en tant
# quentrée du champ d'application. Cependant, elle est plus permissive que
# «entrée» car elle vous permet de redéfinir la variable «contexte» dans
# son propre champ d'application. Vous êtes alors confronté à un choix pour
# la valeur de «impôt_revenu»: prenez-vous la valeur venant de sa
# définition, à lintérieur de «NouveauCalculImpôtRevenuCorrect», ou
# prenez-vous la valeur venant de lentrée du champ d'application?
# Ce dilemme est résolu de deux manières.
2023-04-05 20:05:23 +03:00
# Premièrement, en examinant les conditions des définitions : seules les
# définitions, dont la condition est évaluée à «vrai> au moment de
# lexécution, seront prises en compte. Sil ny en a qu'une, le choix est
# facile. Mais que se passe-t-il si deux définitions se déclenchent en même
# temps, lune provenant de lentrée et lautre du champ d'application
#«NouveauCalculImpôtRevenuCorrect» ?
# Deuxièmement, dans ce cas, nous donnons toujours la priorité à la définition
# de lentrée. Dans Catala, pour la variable «contexte», le champ
# d'application de lappelant a la priorité sur le champ d'application de
# lappelé. C'est comme si lappelant fournissait une exception supplémentaire
# pour la définition de la variable du champ d'application.
# Pour en revenir à notre petit problème, la solution est ici de fournir,
# depuis lextérieur, une définition exceptionnelle de limpôt sur le revenu
# pour les personnes gagnant moins de 10000€.
définition calcul_impôt.impôt_revenu sous condition
personne.revenu <= 10 000€
conséquence égal à 500€
```
## Une variable, plusieurs états
Lorsqu'une quantité est mentionnée dans la loi, elle ne correspond pas toujours
exactement à une variable unique de Catala. Plus précisément, il arrive souvent
que la loi définisse une quantité unique avec plusieurs étapes de calcul,
chacune sappuyant sur la précédente. Voici un exemple dune telle
configuration et la manière de la traiter grâce à une fonction dédiée de Catala.
Sous le capot, les différents états dune variable de Catala sont mis en
œuvre par des variables distinctes, à lintérieur des représentations
intermédiaires-inférieures du langage.
### Article 8
Fiscalement parlant, la valeur du bâtiment exploité à des fins caritatives peut
être déduite du patrimoine dune personne, qui est alors plafonné à 2 500 000€.
```catala
déclaration champ d'application ImpôtSurLaFortune:
entrée valeur_du_bâtiment_pour_exploitation_caritative contenu argent
entrée total_du_patrimoine contenu argent
interne patrimoine contenu argent
# Après le type de la variable, nous pouvons définir la liste ordonnée
# des états que la variable doit prendre avant de calculer sa valeur finale.
# À chaque état, nous pourrons nous référer à la valeur de létat précédent.
état total
état après_déduction_caritative
état après_plafonnement
champ d'application ImpôtSurLaFortune:
définition patrimoine état total égal à total_du_patrimoine
définition patrimoine état après_déduction_caritative égal à
2023-04-05 20:05:23 +03:00
patrimoine - valeur_du_bâtiment_pour_exploitation_caritative
# Ci-dessus, «patrimoine» se réfère à létat «total»
définition patrimoine état après_plafonnement égal à
si patrimoine >= 2 500 000€ alors 2 500 000€ sinon patrimoine
# Ci-dessus, «patrimoine» réfère à létat «après_déduction_caritative»
assertion patrimoine > 0€
# En dehors de la définition de «patrimoine», «patrimoine» réfère toujours
# à létat final de la variable, ici «après_plafonnement».
```
## Les types de données de Catala
Jusqu'à présent, ce tutoriel vous a présenté la structure de base des programmes
Catala avec le champ d'application, les définitions et les exceptions. Mais pour
être en mesure de gérer la plupart des lois, Catala vient en soutien avec les
types de données habituels sur lesquels les calculs legislatifs opèrent.
### Booléens
Le booléen est le type de donnée le plus élémentaire dans Catala: sa valeur
peut être soit à «vrai», soit à «faux». La condition est un simple booléen
avec une valeur par défaut à «faux». Rendez-vous à la section qui
concerne les conditions, décrite plus haut.
```catala
déclaration champ d'application ValeursBooléennes:
interne valeur1 condition
interne valeur2 contenu booléen
champ d'application ValeursBooléennes:
règle valeur1 sous condition faux et vrai conséquence rempli
# Mets le booléen de la condition «valeur1» à «vrai»,
# si la condition «fauxet vrai» est respectée.
définition valeur2 égal à valeur1 ou bien (valeur1 et vrai) = faux
# Les opérateurs booléens incluent «et», «ou», «ou bien»
```
### Entiers
Les entiers dans Catala sont en précision infinie: ils se comportent comme
des vrais entiers en mathématique, et non comme des entiers dordinateur qui
sont limités par une valeur maximale, en raison de leur stockage sur 32 ou
64 bits. Les entiers peuvent être négatifs.
```catala
déclaration champ d'application ValeursEntières:
interne valeur1 contenu entier
interne valeur2 contenu entier
champ d'application ValeursEntières:
définition valeur1 sous condition 12 - (5 * 3) < 65 conséquence égal à 45 * 9
# Lopérateur « / » correspond à une division entière qui tronque vers 0.
définition valeur2 égal à valeur1 * valeur1 * 65 * 100
```
### Décimales
Les décimales dans Catala sont aussi en précision infinie, qui se comportent
comme de vrais nombres rationnels en mathématique, et non comme des nombres
à virgule flottante dans un ordinateur qui effectuent des calculs approxmatifs.
Les opérateurs sont suffixés avec « , ».
```catala
déclaration champ d'application ValeursDécimales:
interne valeur1 contenu décimal
interne valeur2 contenu décimal
champ d'application ValeursDécimales:
définition valeur1 sous condition
12,655465446655426 - 0,45265426541654 < 12,3554654652
conséquence égal à 45 / 9
# Lopérateur « / » correspond à une division éxacte.
# La division dentiers produit une décimale.
définition valeur2 égal à valeur1 * valeur1 * 65%
# Les pourcentages sont des nombres décimaux (ici 0,65)
```
### Argent
En Catala, largent est simplement représenté par un nombre entier de centimes.
Il nest pas possible en Catala davoir une quantité dargent plus précise
qu'un centime. Cependant, vous pouvez multiplier une quantité dargent
avec une décimale, et le résultat est arrondi au centime le plus proche.
Ce comportement vous permet de repérer lendroit où vous avez besoin
de précision dans vos calculs et de sélectionner les décimales en guise de
précision, au lieu de vous fier sur des chiffres monétaires, où la précision
est de lordre du centime deuro. Deux sommes dargent peuvent être divisées,
produisant une décimale.
```catala
déclaration champ d'application ValeursMonétaires:
interne valeur1 contenu décimal
2023-04-05 20:05:23 +03:00
interne valeur2 contenu argent
champ d'application ValeursMonétaires:
définition valeur1 sous condition
12,655465446655426 - 0,45265426541654 < 12,3554654652 conséquence
égal à (décimal de 45) / (décimal de 9)
définition valeur2 égal à
1,00€ * (((6 520,23€ - 320,45€) * valeur1) / 45€)
```
### Dates et durées
Catala prend en charge les dates du calendrier grégorien, ainsi que les calculs
de durée en termes de jours, de mois et dannées. La soustraction entre une date
et une durée est mesurée en jours, et laddition entre une date et une durée
donne une nouvelle date. Les durées sont mesurées en jours, en mois ou en années
et ne peuvent pas être mélangées, car les mois et les années nont pas toujours
le même nombre de jours. Cette non-mixité nest pas prise en compte par le
système de typage de Catala, mais des erreurs seront générées à lexécution.
Les dates sont spécifiées selon la norme ISO 8601 afin déviter toute confusion
entre les notations américaines et européennes. Les opérateurs de date sont
préfixés par « @ », tandis que les opérateurs de durée sont préfixés par « ^ ».
```catala
déclaration champ d'application ValeursDate:
interne valeur1 contenu date
2023-04-05 20:05:23 +03:00
interne valeur2 contenu durée
champ d'application ValeursDate:
définition valeur1 égal à |2000-01-01| + 1 an # produit |2001-01-01|
2023-04-05 20:05:23 +03:00
définition valeur2 égal à
(valeur1 - |1999-12-31|) + 45 jour # 367 + 45 jours (2000 est bissextile)
```
### Collections
Souvent, les programmes Catala ont besoin de parler de collection de données
parce que la loi parle du nombre denfants, du maximum dune liste, etc.
Catala propose un support de première classe pour les collections, qui ne sont
finalement que des listes de taille fixe. Vous pouvez créer une liste, filtrer
ses éléments, mais aussi agréger son contenu pour calculer toutes sortes de
valeurs.
```catala
déclaration champ d'application ValeursDeCollection:
interne valeur1 contenu collection entier
interne valeur2 contenu entier
champ d'application ValeursDeCollection:
définition valeur1 égal à [45;-6;3;4;0;2155]
définition valeur2 égal à somme entier de (i * i) pour i parmi valeur1
# somme de carré
```
## Conclusion
2020-12-22 17:48:28 +03:00
Ce tutoriel présente les concepts de base et la syntaxe des fonctionnalités
2023-04-05 20:05:23 +03:00
du langage Catala. Cest à vous de les utiliser pour annoter du texte
2020-12-22 17:48:28 +03:00
législatif avec leur traduction algorithmique.
Il ny a pas une seule bonne façon décrire des programmes Catala, car le style
de programmation doit être adapté au texte de loi qui sera annoté. Cependant,
le coeur de Catala est un langage de programmation fonctionnelle.
Par conséquent, suivre les modèles de conception habituels de la programmation
fonctionnelle devrait aider à obtenir du code concis et lisible.
# Annexe A : Les définitions de valeurs de premier niveau
Les définitions de premier niveau permettent de définir des valeurs ou
des fonctions directement dans le programme, sans les placer dans un champ
dapplication. Cela est utile pour les constantes ou les fonctions daide,
comme le montrent les exemples ci-dessous.
Les définitions de premier niveau sont disponibles, en les appelant par leur nom,
dans tout le programme; elles peuvent dépendre les unes des autres (tant qu'il
ny a pas de cycles), mais elles ne sont pas autorisées à être dépendantes des
évaluations faites dans des champs dapplication.
## Example 1: Les constantes de premier niveau
### A. En utilisant les définitions du champ d'application
a. Dans ce corpus, le nombre de jours de travail par semaine est supposé
être de 5.
```catala
déclaration champ d'application NombreDeJoursTravaillésParSemaine:
résultat valeur contenu entier
champ d'application NombreDeJoursTravaillésParSemaine:
définition valeur égal à 5
# Lobligation de déclarer le champ d'application avec une simple variable
# de résultat est assez lourde et nuit à la lisibilité.
```
b. Les frais de repas sont de 2€ par jour de travail, sur le nombre de
semaines travaillées.
```catala
déclaration champ d'application FraisDeRepas_A:
entrée nombre_de_semaines_travaillées contenu entier
nombre_de_jours_travaillés_par_semaine champ d'application
NombreDeJoursTravaillésParSemaine
# Le sous-champ d'application doit être déclaré pour accéder à sa valeur.
# Dans certains cas, il peut être bon davoir une dépendance explicite.
résultat valeur contenu argent
champ d'application FraisDeRepas_A:
définition valeur égal à
2€ * (nombre_de_semaines_travaillées *
2023-04-05 20:05:23 +03:00
nombre_de_jours_travaillés_par_semaine.valeur / 7)
# La syntaxe est <nom_du_champ_dapplication>.<nom_de_variable>
# afin daccéder à la valeur
```
2023-04-05 20:05:23 +03:00
### B. En utilisant les définitions de premier niveau
a. À travers ce corpus, le nombre de jours de travail par semaine est supposé
être 5.
```catala
déclaration nombre_de_jours_travaillés_par_semaine contenu entier égal à 5
# Cest plus simple: une déclaration et une valeur sont données en une fois,
# il nest pas nécessaire dun nom de sous-variable.
```
b. Les frais de repas sont de 2€ par jour de travail, sur le nombre de
semaines travaillées.
```catala
déclaration champ d'application FraisDeRepas_B:
2023-04-05 20:05:23 +03:00
entrée nombre_de_semaines_travaillées contenu entier
résultat valeur contenu argent
champ d'application FraisDeRepas_B:
définition valeur égal à
2023-04-05 20:05:23 +03:00
2€ * (nombre_de_semaines_travaillées *
nombre_de_jours_travaillés_par_semaine / 7)
# Il nest pas nécessaire dun sous-champ d'application, la valeur
# de «nombre_de_jours_travaillés_par semaine» est accessible
# directement par son nom
```
## Exemple 2: Les fonctions de premier niveau
a. Lallocation de base est égale à 30% du loyer
```catala
déclaration champ d'application Allocation:
entrée loyer contenu argent
résultat valeur contenu argent
état de_base
état final
champ d'application Allocation:
définition valeur état de_base égal à loyer * 30%
```
### A. Avec la syntaxe actuelle
b. Lallocation finale est arrondie au multiple supérieur de 100€.
```catala
champ d'application Allocation:
définition valeur état final égal à
arrondi de (valeur / 100,0 + 0,49€) * 100,0
# Ici vous devriez expliquer pourquoi cette formule fait ce que
# le texte exprime, puisque cest loin dêtre évident.
# Ça nest pas grave sil est utilisé quune seule fois, mais cest loin
# dêtre lidéal si cet arrondi spécifique est utilisé partout dans la loi.
```
### B. Nouvelle syntaxe proposée pour les «fonctions de niveau supérieur»
b. Lallocation finale est arrondie au multiple supérieur de 100€
```catala
déclaration arrondi_supérieur_à_100
contenu argent
dépend de montant contenu argent
égal à
arrondi de (montant / 100,0 + 0,49€) * 100,0
# Lexplication est encore nécessaire, bien que
# ça nencombre pas le champ d'application actuel.
# Cette définition pourrait même être mise dans le prologue.
champ d'application Allocation:
définition valeur état final égal à arrondi_supérieur_à_100 de valeur
```
## Exemple 3: Des fonctions avec plusieurs paramètres
Le montant à inclure dans le revenu brut est lexcédent de la juste valeur
marchande du bien sur le montant payé.
```catala-metadata
déclaration champ d'application InclureDansRevenuBrut:
entrée juste_valeur_marchande contenu argent
entrée montant_payé contenu argent
résultat montant_à_inclure contenu argent
```
### A. Avec la syntaxe actuelle
```catala
champ d'application InclureDansRevenuBrut:
définition montant_à_inclure égal à
si juste_valeur_marchande > montant_payé alors
juste_valeur_marchande - montant_payé
sinon
0€
# Cest essentiellement la définition de «lexcédent de»
```
### B. Avec une fonction à deux paramètres
```catala
déclaration excédent
contenu argent
dépend de x contenu argent,
y contenu argent
égal à
si x > y alors x - y
sinon 0€
champ d'application InclureDansRevenuBrut:
définition montant_à_inclure égal à
excédent de juste_valeur_marchande, montant_payé
2023-04-05 20:05:23 +03:00
```