# Le bloc retraites du modèle Destinie 2: guide de l'utilisateur

Didier Blanchet, Emmanuelle Crenner

<figure><img src="image_1.png" /></figure>

## To cite this version:

Didier Blanchet, Emmanuelle Crenner. Le bloc retraites du modèle Destinie 2: guide de l'utilisateur. 2010. hal-05485677

HAL Id: hal-05485677

https://insee.hal.science/hal-05485677v1

Preprint submitted on 30 Jan 2026

HAL is a multi-disciplinary open access
archive for the deposit and dissemination of sci-
entific research documents, whether they are pub-
lished or not. The documents may come from
teaching and research institutions in France or
abroad, or from public or private research centers.

L'archive ouverte pluridisciplinaire HAL, est
destinée au dépôt et à la diffusion de documents
scientifiques de niveau recherche, publiés ou non,
émanant des établissements d'enseignement et de
recherche français ou étrangers, des laboratoires
publics ou privés.

<figure><img src="image_2.png" /></figure>

Distributed under a Creative Commons CC BY 4.0 - Attribution - International License
Direction des Études et Synthèses Économiques

G 2010 / 14

Le bloc retraites du modèle Destinie 2 :
guide de l'utilisateur

Didier BLANCHET

Emmanuelle CRENNER

Document de travail
INSTITUT NATIONAL DE LA STATISTIQUE ET DES ÉTUDES ÉCONOMIQUES

Série des documents de travail
de la Direction des Études et Synthèses Économiques

G 2010 / 14

Le bloc retraites du modèle Destinie 2 :
guide de l'utilisateur

Didier BLANCHET *
Emmanuelle CRENNER **

JUILLET 2010

Le bloc retraite présenté dans ce document s'appuie sur les autres composantes du modèle Destinie mises au point par Sylvie LE MINEZ et Sophie BUFFETEAU. Sa finalisation a beaucoup bénéficié de premiers travaux d'exploitation conduits avec Magali BEFFY, Marion BACHELET et Claire MARBOT.

<footnote>* Département des Études Économiques d'Ensemble - Timbre G201 - 15, bd Gabriel Péri - BP 100 - 92244 MALAKOFF CEDEX</footnote>

<footnote>** Appartenait, lors de ce travail, à la division « Redistribution et Politiques Sociales » du même département.</footnote>
# Le bloc retraites du modèle Destinie 2 :
guide de l'utilisateur

## Résumé

Le modèle Destinie est un modèle de microsimulation dynamique dont l'objectif principal est la projection des retraites aux niveaux individuel et agrégé. Ce document présente comment la nouvelle version du modèle permet de réaliser de telles projections. Elles ne découlent pas d'un modèle fermé que l'utilisateur se contenterait de reparamétrer pour la simulation de variantes. Le nouveau modèle Destinie 2 a plutôt été conçu sous forme d'une bibliothèque d'outils mobilisables pour la construction de programmes de projection sur mesure. On présente l'ensemble de ces bibliothèques et divers exemples de mise en œuvre. Le document vise aussi bien les utilisations standard du modèle que les utilisations plus avancées, y compris celles qui nécessiteraient la construction de modules additionnels.

**Mots-clés** : Microsimulation, retraites

# The pension projection package of the Destinie 2 model :
user's guide

## Abstract

The Destinie model is a dynamic microsimulation model whose main purpose is the long run projection of pensions both at the macro and micro levels. This document presents how such simulations can be built with the new version of the model. They do not rely on a closed ready-made program where variants would be obtained by just changing values for a predetermined set of parameters. The new Destinie 2 model has been rather designed as a toolbox of modules, allowing the construction of ad hoc projection programs that can be tailored to users' demands. We provide a comprehensive view of this toolbox. This document addresses the needs of both basic users and more advanced ones, including for applications that would eventually require the building of additional modules.

**Keywords:** Microsimulation, pensions.

**Classification JEL** : C63, H55
Sommaire

I - Introduction .................................................................................................................. 7

I.1 Objectifs et principales caractéristiques du modèle .................................................... 7

I.2 Un exemple introductif .................................................................................................... 9

I.3 Plan du document .................................................................................................................. 11

II - L'environnement de programmation ........................................................................ 12

II.1 Introduction au langage Perl .................................................................................... 12

II.1.1 Éléments généraux de syntaxe .................................................................................. 13

II.1.2 Types de données ........................................................................................................ 13

II.1.3 Boucles et instructions conditionnelles .................................................................... 14

II.1.4 Opérateurs et traitement de chaînes de caractères .................................................... 16

II.1.5 L'appel des sous-programmes .................................................................................... 17

II.1.6 La documentation des programmes ............................................................................ 17

II.2 Environnement Perl IDE .................................................................................................... 18

II.3 Organisation physique des fichiers .................................................................................... 20

III - Les variables .................................................................................................................. 22

III.1 Préliminaire technique : les notions de variables locales et globales ................................ 22

III.2 De quelles informations a-t-on besoin pour simuler les retraites ? .................................... 23

III.3 Les variables prédéfinies (bibliothèque DefVarRetr) .................................................... 24

III.3.1 Vue d'ensemble ............................................................................................................ 24

III.3.2 Variables individuelles d'input .................................................................................... 25

III.3.3 Variables individuelles d'output .................................................................................... 27

III.3.4 Variables individuelles temporaires ............................................................................ 27

III.3.5 Paramètres temporels lus dans des fichiers Excel. .................................................... 28

III.3.6 Paramètres scalaires générés par la fonction Useleg. .................................................... 30

III.3.7 Autres paramètres ............................................................................................................ 30

III.4 Déclaration de variables micro ou macro additionnelles .................................................... 31

IV - Utilisations courantes (1) : effectuer une simulation et éditer ses résultats.................................................. 33

IV.1 Le préambule d'un programme de simulation ................................................................. 34

IV.1.1 Initialisations des programmes et des variables locales ............................................ 34

IV.1.2 Sélectionner les fichiers issus du générateur de biographies : la fonction UseBios .................................................... 35

IV.1.3 Déclarer les options générales de la simulation : la fonction UseOpt ............................................ 35

IV.2 Les boucles : version élémentaire .................................................................................... 37

IV.2.1 Vue d'ensemble ............................................................................................................ 37

IV.2.2 Relire les biographies individuelles : la fonction Relec ............................................ 38

IV.2.3 Choisir la législation : UseLeg et UseLegRetroMax .................................................... 39

IV.2.4 Simuler la liquidation : la fonction SimDir .................................................................... 41

IV.3 Les boucles : quelques cas plus complexes ........................................................................ 41

IV.3.1 Lancer plusieurs scénarios dans un seul programme ............................................ 41

IV.3.2 Sauvegarder une variable micro pour d'autres scénarios ............................................ 42

IV.3.3 Enchaîner plusieurs boucles individuelles : le cas des droits dérivés et du minimum vieillesse .................................................... 43

IV.3.4 Modifier des données individuelles en amont de la simulation des retraites ............................................ 44

IV.3.5 Simuler des cas-types ............................................................................................................ 45
<table>
  <tbody>
    <tr>
      <td><b>IV.4 Création de résultats agrégés</b></td>
      <td><b>45</b></td>
    </tr>
    <tr>
      <td>IV.4.1 Fonctions de tabulation génériques</td>
      <td>45</td>
    </tr>
    <tr>
      <td>IV.4.2 Un exemple</td>
      <td>47</td>
    </tr>
    <tr>
      <td>IV.4.3 Fonctions de tabulation directe des salaires et des retraites</td>
      <td>48</td>
    </tr>
    <tr>
      <td><b>IV.5 Sauvegarde des résultats macros dans des fichiers Excel</b></td>
      <td><b>49</b></td>
    </tr>
    <tr>
      <td><b>IV.6 Sauvegarde de résultats macros dans des fichiers texte</b></td>
      <td><b>52</b></td>
    </tr>
    <tr>
      <td><b>V - Utilisations courantes (2) : inspecter les données individuelles</b></td>
      <td><b>54</b></td>
    </tr>
    <tr>
      <td><b>V.1 L'explorateur</b></td>
      <td><b>54</b></td>
    </tr>
    <tr>
      <td><b>V.2 Sauvegarder des résultats individuels dans un fichier texte</b></td>
      <td><b>57</b></td>
    </tr>
    <tr>
      <td><b>VI - Utilisations avancées (1) : présentation détaillée de l'ensemble des bibliothèques</b></td>
      <td><b>59</b></td>
    </tr>
    <tr>
      <td><b>VI.1 La bibliothèque OutilsDroits : les outils de calcul des droits</b></td>
      <td><b>59</b></td>
    </tr>
    <tr>
      <td>VI.1.1 Fonctions de calcul de variables intermédiaires des droits directs</td>
      <td>60</td>
    </tr>
    <tr>
      <td>VI.1.2 Fonctions de calcul de variables intermédiaires pour l'âge de liquidation</td>
      <td>61</td>
    </tr>
    <tr>
      <td>VI.1.3 Fonctions de calcul des montants de pension</td>
      <td>62</td>
    </tr>
    <tr>
      <td>VI.1.4 Calcul d'indicateurs dérivés</td>
      <td>63</td>
    </tr>
    <tr>
      <td><b>VI.2 La bibliothèque OutilsComp : la simulation des comportements de départ à la retraite</b></td>
      <td><b>65</b></td>
    </tr>
    <tr>
      <td>VI.2.1 Les fonctions de premier niveau</td>
      <td>65</td>
    </tr>
    <tr>
      <td>VI.2.2 Fonctions de calcul de l'âge de départ à la retraite : TestLiq et AgeOpt</td>
      <td>66</td>
    </tr>
    <tr>
      <td><b>VI.3 La bibliothèque OutilsMen : l'environnement familial des individus</b></td>
      <td><b>67</b></td>
    </tr>
    <tr>
      <td>VI.3.1 Fonctions de calcul démographique</td>
      <td>67</td>
    </tr>
    <tr>
      <td>VI.3.2 Fonctions relatives au niveau de vie</td>
      <td>69</td>
    </tr>
    <tr>
      <td><b>VI.4 La bibliothèque OutilsBase</b></td>
      <td><b>70</b></td>
    </tr>
    <tr>
      <td>VI.4.1 Initialisations</td>
      <td>71</td>
    </tr>
    <tr>
      <td>VI.4.2 Opérations élémentaires</td>
      <td>72</td>
    </tr>
    <tr>
      <td>VI.4.3 Valeurs de fonctions élémentaires</td>
      <td>73</td>
    </tr>
    <tr>
      <td>VI.4.4 Tirages de variables aléatoires</td>
      <td>75</td>
    </tr>
    <tr>
      <td>VI.4.5 Création et gestion de listes d'identifiants</td>
      <td>76</td>
    </tr>
    <tr>
      <td><b>VI.5 Fonctionnalités supplémentaires de la bibliothèque OutilsRetr</b></td>
      <td><b>78</b></td>
    </tr>
    <tr>
      <td>VI.5.1 Simulation de systèmes en comptes notionnels</td>
      <td>78</td>
    </tr>
    <tr>
      <td>VI.5.2 Compléments sur la fonction SimDir</td>
      <td>79</td>
    </tr>
    <tr>
      <td><b>VI.6 Fonctionnalités supplémentaires de la bibliothèque OutilsTab</b></td>
      <td><b>81</b></td>
    </tr>
    <tr>
      <td>VI.6.1 Initialisation</td>
      <td>82</td>
    </tr>
    <tr>
      <td>VI.6.2 Tabulations simples : la fonction Distrib</td>
      <td>82</td>
    </tr>
    <tr>
      <td>VI.6.3 Construire des séries de résultats macro par âge</td>
      <td>82</td>
    </tr>
    <tr>
      <td>VI.6.4 Construire des séries de résultats macro par génération</td>
      <td>84</td>
    </tr>
    <tr>
      <td>VI.6.5 Autres manipulations de tableaux</td>
      <td>84</td>
    </tr>
    <tr>
      <td><b>VI.7 Fonctionnalités supplémentaires de la bibliothèque OutilsExcel</b></td>
      <td><b>86</b></td>
    </tr>
    <tr>
      <td>VI.7.1 Gestion générale de classeurs Excel</td>
      <td>86</td>
    </tr>
    <tr>
      <td>VI.7.2 Lecture de données</td>
      <td>87</td>
    </tr>
    <tr>
      <td>VI.7.3 Écriture de données</td>
      <td>88</td>
    </tr>
    <tr>
      <td><b>VI.8 Fonctionnalités supplémentaires de la bibliothèque DefVarRetr</b></td>
      <td><b>89</b></td>
    </tr>
    <tr>
      <td><b>VII - Utilisations avancées (2) : création de nouveaux modules</b></td>
      <td><b>91</b></td>
    </tr>
    <tr>
      <td><b>VII.1 Structure générale d'un module</b></td>
      <td><b>91</b></td>
    </tr>
    <tr>
      <td><b>VII.2 Création de fonctions : principes et exemples</b></td>
      <td><b>92</b></td>
    </tr>
    <tr>
      <td>VII.2.1 Principes de la programmation des fonctions en Perl</td>
      <td>92</td>
    </tr>
    <tr>
      <td>VII.2.2 Un cas élémentaire : l'exemple de la fonction Duree</td>
      <td>93</td>
    </tr>
  </tbody>
</table>
<table><tr><td>VII.2.3 Utilisation de paramètres légaux dépendant de la date : l'exemple de la fonction CSGRet</td><td>94</td></tr><tr><td>VII.2.4 Fonction dont un argument est une série temporelle complète : l'exemple de la fonction SalMoy</td><td>95</td></tr><tr><td>VII.2.5 Fonction dont un argument est un intervalle de valeurs : l'exemple de la fonction NbEnf</td><td>96</td></tr><tr><td>VII.2.6 Fonction dont un argument est un bloc d'instructions : l'exemple de la fonction Svar</td><td>97</td></tr><tr><td><strong>Références</strong></td><td><strong>99</strong></td></tr><tr><td><strong>Annexe 1 : Liste des variables globales par ordre alphabétique</strong></td><td><strong>100</strong></td></tr><tr><td><strong>Annexe 2 : Variables globales classées par type et mode de calcul ou d'initialisation</strong></td><td><strong>106</strong></td></tr><tr><td><strong>Annexe 3 :<br>liste des procédures, classées par bibliothèque et fonction</strong></td><td><strong>112</strong></td></tr></table>
# I - Introduction

Le modèle Destinie est un modèle de microsimulation dynamique dont l'objectif principal est la projection à long terme des retraites. Sa première version avait été construite à l'Insee dans les années 1990 (Blanchet et Chanut, 1998 ; Division Redistribution et Politiques Sociales, 1999 ; Bardaji et al., 2006). Elle a été utilisée jusqu'en 2008 mais elle s'est progressivement avérée de plus en plus difficile à maintenir. Une réécriture complète a donc débuté à partir de 2005. Les principes généraux de cette réécriture sont présentés dans un document joint (Blanchet, Buffeteau, Crenner et Le Minez, 2010) auquel sont renvoyés les lecteurs uniquement intéressés par une vue d'ensemble du nouveau modèle. Le présent document est un document plus technique, destiné à ses utilisateurs directs ou aux lecteurs souhaitant avoir une connaissance plus approfondie de ses fonctionnalités.

Pour introduire ce document, on va rappeler brièvement le principe de la microsimulation et indiquer quelle est l'architecture du nouveau modèle. L'une de ses caractéristiques est de ne plus proposer un programme tout fait de simulation des droits à retraite que l'utilisateur se contenterait de reparamétrer ou compléter en fonction des besoins. Le nouveau modèle se présente plutôt comme un outil logiciel permettant la construction de programmes de simulation sur mesure. L'objectif du présent guide est de donner tous les éléments nécessaires à la construction de tels programmes. On présentera d'entrée de jeu un exemple d'un tel programme ce qui permettra de donner un premier aperçu des questions que va couvrir ce document.

## I.1 Objectifs et principales caractéristiques du modèle

Simuler les droits à retraite suppose de connaître l'histoire détaillée des individus tant sur le plan démographique (vie en couple, naissance des enfants, décès du conjoint) que sur le plan professionnel (années en emploi, salaires perçus, années au chômage, périodes d'inactivité...). Pour construire ce type de simulation, le modèle Destinie part d'un échantillon représentatif de la population française et il en projette le devenir au niveau individuel par combinaison de règles d'évolution déterministes ou stochastiques. Les droits à retraite sont calculés sur cette base et le fait d'en disposer au niveau individuel permet de produire une grande variété de résultats : non seulement des agrégats, mais aussi des indicateurs d'inégalité des retraites ou de l'ampleur des effets redistributifs de tel ou tel scénario de réforme.

La première version du modèle Destinie avait été écrite en langage Turbo Pascal. La décision de réécriture s'explique entre autres par la difficulté à continuer de faire évoluer le modèle sous ce langage. Après divers essais, on a opté pour une réécriture dans le langage Perl, et cette réécriture a également été l'occasion de revisiter entièrement l'architecture du modèle. Pour la résumer brièvement, on dira que la nouvelle version a cherché à améliorer les performances de l'ancien modèle dans trois domaines principaux: la légèreté, la souplesse, et la traçabilité des résultats des simulations.

Ceci a notamment conduit à adopter une architecture à deux étages (figure 1).

- Le premier étage est qualifié de générateur de biographies. Il simule des trajectoires démographiques et professionnelles en faisant abstraction des départs en retraite, et donc jusqu'à des âges aussi élevés que nécessaire pour pouvoir simuler des scénarios de remontée éventuellement importante des âges de liquidation. Les biographies qui sont produites par ce générateur sont stockées dans des fichiers intermédiaires.

- Le second étage concerne la simulation des retraites. Les opérations de ce second étage consistent à relire les données biographiques fournies par le générateur, et à y rajouter une simulation des comportements de départ en retraite et le calcul des droits associés.
<figure><img src="image_3.png" /><figcaption>Figure 1 : architecture simplifiée du bloc retraite du modèle Destinie 2</figcaption></figure>
Cette organisation a facilité les travaux de développement en permettant un travail autonome
sur chacun des deux étages. En utilisation courante, son intérêt est qu'elle évite d'avoir à
relancer l'ensemble de la simulation des trajectoires démographiques et professionnelles pour
chaque variante de retraite, ce qui allège les travaux de simulation. Un intérêt additionnel est
que, par construction, les variantes retraites tourneront sur une population d'individus aux
caractéristiques fixes et entièrement contrôlées, ce qui facilite l'analyse des effets des réformes.

La construction de ces variantes se présente par ailleurs d'une manière très différente de ce
qu'elle était dans le modèle Destinie 1. Les projections ne découlent plus d'un programme de
référence unique qu'on modifie d'un scénario à l'autre. Compte tenu de la grande diversité des
exercices de projection qui peuvent être demandés au modèle, on a opté pour un
fonctionnement beaucoup plus ouvert et modulaire. Ce qui est proposé n'est plus un
programme, mais des bibliothèques d'utilitaires servant à construire des programmes de
projection « à la carte ». Ceci rend l'instrument beaucoup plus flexible, et améliore la traçabilité
de ses résultats car le principe est désormais d'avoir autant de programmes différents que
d'exercices de simulation. Avec un tel système, toutes les informations sur les hypothèses qui
ont conduit à une simulation peuvent être automatiquement retrouvées dans le programme qui
l'a généré, sans qu'il y ait besoin d'autre forme d'archivage.

La figure 1 présente l'organisation générale des fichiers et des programmes. Les programmes de simulation des retraites sont des programmes source Perl de type .pl représentés au centre du diagramme qui lisent les fichiers fournis par le générateur de biographies et qui permettent de produire des fichiers de résultats qui sont des fichiers Excel ou des fichiers texte.

I.2 Un exemple introductif

L'objectif de ce guide est de donner tous les éléments nécessaires à la construction de tels
programmes. Pour qu'on ait tout de suite une idée de leur contenu, la figure 2 donne un
exemple simple pour une simulation élémentaire. On y reconnaît deux boucles emboitées sur la
date et l'ensemble des individus simulés, caractéristiques d'un modèle de microsimulation
dynamique. À l'intérieur de ces boucles, on utilise des fonctions prédéfinies telles que Relec
(relecture des données biographiques en input), UseLeg (choix de la législation) ou SimDir
(simulation de la liquidation des droits directs). La boucle temporelle contient également des
appels à des fonctions de calcul de résultats agrégés telles que Mvar, Svar ou Count dont les
résultats sont sauvegardés en fin de programme par appel à d'autres fonctions prédéfinies
(ClassOut, SavSer et CloseOut).

Cet exemple montre que le bloc retraites du nouveau modèle Destinie fonctionne bien comme
un mini-logiciel de calcul des droits à retraite, dont les éléments sont des variables prédéfinies
et des programmes fournis par les bibliothèques indiquées sur la partie droite de la figure 1.
Ces éléments se divisent en deux groupes :

- Le premier regroupe ce qui est indispensable aux utilisations les plus courantes du modèle. Il s'agit de variables ou programmes définis dans quatre bibliothèques : la librairie qui déclare l'ensemble des variables Destinie (DefVarRetr.pm), celle qui fournit les principaux utilitaires de calcul des retraites (OutilsRetr.pm) et des bibliothèques de programmes de tabulation et de sortie sous Excel (OutilsTab.pm et OutilsExcel.pm).

- La connaissance du second groupe n'est utile que pour des utilisations plus avancées. Il s'agit d'une part de certaines des composantes des bibliothèques mentionnées à l'instant qui n'ont pas besoin d'être connues pour les utilisations usuelles. Il s'agit par ailleurs de l'intégralité du contenu de quatre autres bibliothèques qui, en utilisation courante, ne sont mobilisées qu'indirectement, mais dans lesquelles on peut aller puiser pour des calculs plus élaborés. Cet ensemble contient notamment deux bibliothèques sur lesquelles s'appuie OutilsrRetr.pm : la bibliothèque contenant les détails des calculs de droits à retraite (OutilsDroits.pm), et la bibliothèque simulant les différentes options de comportement de départ en retraite (OutilsComp.pm). Il existe aussi une bibliothèque d'outils généraux
partagés par l'ensemble des autres bibliothèques (OutilsBase.pm), et une bibliothèque
permettant divers types de calculs au niveau des ménages (OutilsMen.pm).

<figure><img src="image_4.png" /><figcaption>Figure 2 : un exemple simple de programme de simulation</figcaption></figure>

Pour revenir aux utilisations courantes, la droite de la figure 1 fait état d'un dernier instrument, le programme prédéfini Explore.pl. Ce programme s'appuie sur la même boîte à outils que les programmes .pl sur mesure mais son but n'est pas de construire des simulations complètes. Il sert à explorer interactivement le contenu détaillé des fichiers d'input et de tester différentes hypothèses de départ en retraite, individu par individu. Cet outil est principalement destiné au débogage des programmes ou à l'examen de résultats au niveau fin, par exemple lorsqu'une simulation conduit à des résultats inattendus pour un certain nombre d'individus. Les résultats de cet explorateur peuvent éventuellement être dirigés vers des fichiers .xls ou .txt, mais sont le plus souvent consultés à l'écran, dans une fenêtre d'exécution MS-DOS.
I.3 Plan du document

Ayant présenté cette organisation générale du programme, on peut préciser les objectifs et le
plan du présent document. Il n'abordera pas le fonctionnement du générateur de biographies.
Le lecteur ayant besoin de le connaître est renvoyé à Buffeteau et Le Minez (à paraître). Il
s'adresse à l'utilisateur qui part de fichiers de biographies déjà constitués et qui souhaite
construire des programmes de projection des retraites. Il présente l'ensemble de ce qui doit
être connu pour construire ces projections.

La section II est principalement consacrée à la présentation du langage Perl et de son environnement de programmation. Elle peut-être sautée par l'utilisateur qui connaît déjà ce langage, hormis sa dernière section consacrée aux principes d'organisation physique des fichiers Destinie.

Les sections III à V sont ensuite consacrées aux utilisations courantes. La section III permet de découvrir l'ensemble des variables que Destinie met à disposition de l'utilisateur et indique comment procéder lorsqu'il doit en créer de nouvelles. La section IV présente en détail les fonctions d'usage courant et notamment celles qui figuraient dans l'exemple de la figure 2. La section V présente l'explorateur et les autres possibilités qui existent pour inspecter les résultats d'une simulation au niveau individuel.

La section VI est destinée à l'utilisateur avancé. Elle contient la description complète de l'ensemble des procédures des différents modules, hormis celles qui auront déjà été présentées aux sections IV et V.

La section VII s'adresse pour finir à l'utilisateur qui souhaiterait développer des modules additionnels. Par exemple, la version I du modèle Destinie avait servi à des projections de dépendance aux grands âges (Duée et Rebillard, 2005) et cet exercice devrait être prochainement renouvelé. Un module simulant la consommation de soins de santé est également en cours de développement (Albouy, Davezies et Debrand, 2010). Un module épargne/patrimoine est également à l'étude. On donnera quelques principes simples concernant la façon dont peuvent être développés de tels modules.
## II - L'environnement de programmation

Cette première partie est consacrée à l'environnement général de programmation de Destinie 2. L'essentiel est consacré à présenter les rudiments du langage Perl (section II.1) et un exemple d'outil de développement intégré dans ce langage qui est celui qui a servi à la mise au point de ce modèle Destinie 2 (section II.2). Ces deux sections peuvent être sautées par l'utilisateur qui connaît déjà ce langage. La dernière section présente la structure physique d'organisation des fichiers de travail : sa lecture est donc indispensable (section II.3).

### II.1 Introduction au langage Perl

Plusieurs possibilités de langage ont été explorées pour la réécriture du modèle Destinie. On aurait pu envisager de s'appuyer sur un logiciel statistique tels que SAS. L'intérêt aurait été de bénéficier de procédures de calcul statistique ou de mise en forme des résultats toutes faites. Mais ces logiciels sont surtout conçus pour des traitements de données statistiques en bloc, alors que la microsimulation oblige à alterner traitement en blocs et travail différencié individu par individu. De manière plus générale, le recours à un logiciel évolué crée le risque de se laisser enfermer dans des solutions de programmation restrictives interdisant de faire évoluer le modèle dans des directions non prévues au départ.

Il vaut donc, mieux, en général, s'appuyer sur un langage élémentaire, ce qui avait déjà été le cas pour Destinie 1. Un assez grand nombre de modèles existants recourent au langage C++ et à la programmation orientée objet, par exemple la famille de modèles développés à partir du logiciel ModGen (Statistique Canada, 2010)<fnref n="1" />. Quelques tentatives ont été faites de reprogrammation en C++ d'une partie du programme Destinie 1 mais les pousser à terme aurait nécessité un investissement et des compétences supérieures aux moyens disponibles sur le projet : il s'agissait d'un changement de logique de programmation trop important par rapport à l'expérience acquise sur le modèle Destinie 1.

On a donc préféré se rabattre sur un langage permettant de conserver l'esprit de la programmation de Destinie 1, mais sans les limites auxquelles avait fini par se heurter le langage Turbo Pascal. Le langage Perl est apparu constituer une réponse assez pratique à nos besoins. Ce langage n'est pas sans défaut, mais c'est un langage extrêmement flexible, qui n'impose aucun style de programmation *a priori*. Il présentait un certain nombre d'avantages additionnels pour la microsimulation, tels que l'allocation dynamique des tableaux, une grande souplesse dans la spécification des sous-programmes, l'existence d'une fonction de tri incorporée au langage ou l'existence de bibliothèques d'interface avec Excel. D'autres fonctionnalités se sont avérées utiles *a posteriori* : le fait qu'il s'agisse d'un langage interprété plutôt que compilé a notamment permis la construction de fonctions de tabulation très flexibles et a rendu extrêmement facile l'ajout d'un explorateur interactif à la batterie d'instruments qui avait été prévue au départ.

Les quelques sections qui suivent ne peuvent évidemment se substituer à la lecture de présentations plus complètes du langage, mais elles fournissent le minimum indispensable à la compréhension du reste du manuel et devraient suffire à la programmation d'applications Destinie élémentaires. On notera qu'on n'y aborde pas la question des entrées-sorties, car il existe dans Destinie 2 des fonctions qui permettent d'éviter le recours aux entrées sorties de base de Perl. Celles-ci peuvent néanmoins s'avérer utiles dans certains cas, mais les exemples correspondants seront donnés au fur et à mesure du reste du document, notamment dans les sections IV.6 et V.2.

<footnote n="1">¹ Parmi les autres produits disponibles pour le développement de modèles de microsimulation dynamique figure le logiciel LIAM, mais dont le développement est intervenu après le lancement de la réécriture de Destinie 2 (voir O'Donoghue, 2008).</footnote>
### II.1.1 Éléments généraux de syntaxe

Perl différencie majuscules et minuscules. Les instructions sont séparées par des points virgule. Elles peuvent s'étendre sur plusieurs lignes si nécessaire.

La syntaxe de Perl est assez libre -souvent même jugée trop libre. C'est à l'utilisateur de se créer ses propres règles de présentation et d'essayer de s'y tenir. Toutes les librairies et exemples de programme du modèle Destinie 2 ont essayé de suivre les règles suivantes dont on a commencé à avoir l'illustration dans l'exemple de l'introduction :

- Une indentation systématique pour les boucles et instructions conditionnelles ainsi que pour le contenu des sous-programmes.

- Une notation en minuscules pour les données individuelles et les compteurs de boucle

- Une combinaison majuscules/minuscules pour les noms de sous-programmes et les paramètres législatifs de calcul des retraites

- Une écriture exclusivement en majuscules pour les variables de niveau macro

Un autre élément de sécurisation consiste à activer certaines directives de compilation. Par exemple, comme on le reprécisera plus loin, l'instruction `use strict` rend la prédéclaration des variables obligatoires et son usage est donc fortement recommandé. L'instruction `use diagnostics` conduit par ailleurs à l'affichage de messages d'erreurs plus nombreux et plus complets. Son usage n'est pas nécessairement recommandé en phase d'exploitation, car elle ralentit l'exécution. En revanche, elle peut être utile en phase de mise au point.

### II.1.2 Types de données

Perl est un langage très peu typé. Une variable n'a pas à être prédéfinie comme étant de type caractère, entier ou réel. En fait, une variable peut prendre tour à tour les trois formes selon le contexte et les affectations. De la même manière, un tableau peut mélanger des éléments des trois types.

En revanche, un critère de typage fondamental oppose scalaires, tableaux ordinaires (dits encore listes) et tableaux associatifs dits encore « hachages ».

Le nom d'un objet **scalaire** commence toujours par le symbole `$` (comme **scalar**) qu'il s'agisse d'un nombre ou d'une chaîne de caractère. Par exemple

```
$age = 10;
$sexe = "Hom";
```

Il existe un nom de scalaire réservé, qui est `$_`. Le contenu de ce scalaire dépend du contexte où il est appelé : dans les applications qui nous intéresseront, il s'agira de l'indice de boucle par défaut (cf. infra).

Un tableau est une liste de scalaires donc l'individage commence à la valeur 0. Il faut distinguer l'objet tableau, dont le nom commence toujours par `@` (comme **array**), et les éléments de ce tableau qui sont des scalaires et dont le nom commence par `$`.

Ainsi,

```
@statut
```

sera un tableau contenant les statuts des différents individus d'une base, mais

```
$statut[$i]
```
sera le statut de l'individu $i.

La gestion des tableaux sous Perl est entièrement dynamique, ce qui veut dire qu'il n'y a pas besoin de prédéfinir leur longueur, ce qui est un avantage pour des programmes de simulation travaillant sur des populations dont la taille évolue au cours du temps et est donc indéterminée *a priori*.

Comme pour les scalaires, il existe une notion de tableau par défaut, nommé `@_`. Savoir le manipuler n'est pas indispensable pour les utilisations standard des modules retraite. Il est par contre nécessaire à connaître pour les utilisations avancées, notamment pour l'utilisateur qui veut construire ses propres procédures : à l'intérieur d'un sous programme, le tableau `@_` sert en effet à stocker les valeurs des arguments transmis à ce sous programme lors de son appel. On y reviendra dans la partie VII.

On notera par ailleurs que le même nom peut être utilisé pour un scalaire pur et un tableau : `@tableau`, `$tableau[$i]` et `$tableau` renverront donc à trois entités différentes.

Un **hachage** est enfin un tableau dont les éléments sont indicés par des chaînes de caractère et non pas par des entiers ordonnés : on parle d'ailleurs de clés plutôt que d'indices. Le nom d'un hachage commence par %, mais, comme pour les tableaux, ses éléments sont des scalaires et sont donc nommés avec le préfixe $, avec une clé passée entre accolades plutôt qu'entre crochets. Par exemple, si on définit le hachage

`%effectif`

indicé par les clés `"Hommes"` et `"Femmes"`, l'objet

`$effectif{"Hommes"}`

pourra désigner l'effectif de la population masculine<fnref n="2" />.

On peut construire des tableaux à double indice comme tableaux de tableaux, ou encore des hachages de hachages, des hachages de tableaux... Par exemple

`$qmor{"Hom"}[60]`

pourra désigner la mortalité masculine à 60 ans. Dans ce cas particulier, si on veut accéder au tableau global de ces quotients de mortalité masculins par âge, il faudra noter

`@{$qmor{"Hom"}}`

Cette notation un peu lourde se comprend comme suit : `$qmor{"Hom"}`, qui est un scalaire, est en fait l'adresse en mémoire du tableau qui nous intéresse. C'est pour accéder au tableau entier qu'on rajoute l'appel `@{...}` qui veut dire « retourner l'intégralité du tableau dont l'adresse est passée en argument ».

Un tableau à double entrée n'est pas nécessairement rectangulaire. Ce sera souvent le cas dans Destinie. Par exemple, le modèle gère un tableau à double indice `@statut_` qui donne les séquences par âge des statuts individuels vis-à-vis du marché du travail. Ce tableau a une forme irrégulière puisque les durées de vie des individus sont différentes.

### II.1.3 Boucles et instructions conditionnelles

Les instructions conditionnelles s'écrivent de la manière suivante :

<footnote n="2">² On peut se passer des guillemets si la chaîne est une chaîne simple sans blancs</footnote>
```perl
if ( condition )
{
    instruction
};
```

qui signifie que si la condition est remplie alors on effectue l'instruction.

On peut rajouter des instructions supplémentaires selon d'autres conditions à l'aide de `else` et `elif`:

```perl
if (condition1)
{
    instruction1
}
else
{
    instruction2
};
```

ou

```perl
if (condition1)
{
    instruction1
}
elif (condition2)
{
    instruction2
};
```

Chaque condition peut correspondre à une combinaison de conditions à l'aide des signes `&&` (et) et `||` (ou):

```perl
if ((cond1 && cond2) || (cond3))
{
    instruction
};
```

qui signifie, si la condition1 et la condition2 sont remplies, ou si la condition3 est remplie, alors effectuer l'instruction.

Pour les **boucles** la syntaxe est similaire. La plus courante est:

```perl
for $i (2..20,50,99)
{
    ...
};
```

qui veut dire « effectuer les instructions entre crochets pour les valeurs de la variable `$i` comprises entre 2 et 20, ainsi que les valeurs 50 et 99 ». Il existe une forme encore plus compacte :

```perl
for (2..20,50,99)
{
    ...
};
```

dans laquelle l'indice de boucle sera le scalaire `$_` qui pourra être utilisé sous ce nom à l'intérieur de la boucle.

La liste passée après l'instruction `for` peut aussi être un tableau. Si `@liste` est une liste d'identifiants d'individus présélectionnés selon un critère particulier, l'instruction

```perl
for (@liste)
{
    ...
};
```
exécutera l'ensemble des instructions entre accolades pour l'ensemble des individus de la liste.

Il existe aussi des boucles `foreach`, `while`, `until` dont on ne détaillera pas ici la syntaxe.

Petit conseil pratique :
comment éviter le cauchemar des `{ }`, `[]` et `( )` ?

Les accolades, parenthèses et crochets sont beaucoup utilisés par le langage Perl. Ces signes ont des
utilités bien distinctes :

( ) encadre des conditions et des valeurs d'une boucle ou des paramètres d'une fonction.

{ } est utilisé pour délimiter des blocs d'instructions et des indices de hachages

[] n'est utilisé que pour préciser les indices d'une variable

La mauvaise utilisation de ces signes est source de nombreuses erreurs. Voici deux exemples de
messages d'erreurs que l'on rencontre très souvent lorsqu'on programme en Perl :

```
syntax error at sortie scenarios.pl line 42, near "$i)"
```

Ce message indique à quel endroit la compilation a posé problème et s'est arrêtée. Il donne donc quelques indications sur l'endroit où chercher le problème, mais il ne dit pas que le problème est lié une parenthèse ou un crochet, même si l'expérience sur Destinie montre que le plus souvent il s'agit de ce type d'erreur.

```
Missing right curly or square bracket at sortie scenarios.pl line 218, at end of line
```

Ce message d'erreur quant à lui a l'avantage de préciser le type d'erreur, mais ne donne aucune
indication sur l'endroit où le problème se situe. Il dit juste qu'arrivé à la fin, il lui manque une parenthèse
(ou un crochet ou une accolade). Pour éviter ces problèmes, il faut contrôler le plus en amont possible la
bonne fermeture des parenthèses, crochets et accolades. Il est aussi utile de s'astreindre aux règles
d'indentation proposées et de commenter les fins des blocs les plus importants.

II.1.4 Opérateurs et traitement de chaînes de caractères

On a les opérateurs standards, y compris les opérateurs d'incrémentation de C++, de type
$i++$ pour $i=$i+1.

S'agissant des opérateurs logiques, il faut faire attention au fait que les opérateurs de
comparaison sont en principe différents pour les chaînes et les nombres, par exemple $eq$ dans
le premier cas et $==$ dans le second. Ils fonctionnent de la même manière pour les nombres
entiers, mais pas nécessairement pour des nombres réels. Par ailleurs, $==$ traite de la même
manière les valeurs zéro, `undef` (objet non défini) et la chaîne vide "" alors que $eq$ différencie
ces trois valeurs et s'avère donc préférable lorsqu'il y a risque d'ambiguïté.

Il faut par ailleurs être très attentif à l'erreur classique consistant à mettre un `=` simple à la place d'un `==`. Soit par exemple, l'instruction :

```
for $i (1..IMax) {if ($age[$_] =60) {Liq($_)}};
```

La plupart des langages diagnostiqueraient une erreur de syntaxe. La démarche de Perl est au contraire d'essayer de donner du sens à cette syntaxe. Au lieu de tester si l'âge de l'individu `$i` est égal à 60 ans, il va comprendre cette instruction comme voulant dire « affecter la valeur 60 au scalaire `$age[$i]` » puis « si le résultat de cette affectation est vrai (i.e. différent de zéro, ce qui va être le cas) alors réaliser l'instruction entre crochets ». Avec ce type d'erreur, c'est l'ensemble de la population qui se retrouve en retraite et âgée de 60 ans à la fin de la boucle `for`.
### II.1.5 L'appel des sous-programmes

L'appel d'un sous-programme<fnref n="3" /> se fait à l'aide de son nom suivi de la liste des arguments d'appel, entre parenthèses, séparés les uns des autres par des virgules.

Quelques points sont à connaître pour bien manipuler ces appels :

- Certains arguments peuvent être optionnels. Il s'agit dans ce cas des derniers arguments de la liste d'appel. Lorsque c'est le cas, ce sera précisé dans le descriptif du sous-programme.

- Beaucoup des sous-programmes des bibliothèques Destinie 2 sont appelés à l'intérieur de boucles, soit sur la période, soit sur la date. Dans une grande majorité des cas, le seul argument qui est passé à ces sous-programmes est soit cet indice de date, soit cet indice individuel. Par exemple :

```
SimDir($i);
```

indique de simuler les droits directs de l'individu $i. Il n'y a pas besoin de donner au sous programme les autres caractéristiques de l'individu $i, car elles sont stockées dans des variables globales qui contiennent toutes les informations individuelles nécessaires et qui sont visibles depuis l'ensemble des librairies Destinie 2 (voir infra section III.1). Dit d'une autre manière, il suffit de dire à Destinie sur quel individu il travaille, et les programmes se chargent du reste.

- Une précision est nécessaire sur le mode de passage des tableaux. En général, le passage d'un tableau doit se faire en indiquant son adresse. Or l'adresse du tableau `@tab` s'écrit `\@tab`. Il faudrait donc, en toute rigueur, avoir des appels de type :

```
$PENSION_MOYENNE= MVar(\@pension);
```

Il est cependant plus agréable de se contenter de la notation :

```
$PENSION_MOYENNE= MVar(@pension);
```

Ceci est possible dès lors que la spécification du sous-programme mentionne que l'argument qui lui est passé est une adresse de tableau. Dans ce cas, le sous-programme interprète `@tab` non pas comme l'ensemble du tableau, mais comme son adresse. En général, sauf mention contraire, les procédures Destinie 2 ont été spécifiées de sorte à permettre ce type d'appel.

- Il est possible de passer des instructions Perl comme argument à un sous programme. C'est ce que faisait par exemple l'instruction suivante du programme de la figure 2.

```
$PENSION_MOYENNE[$t] = MVar(@pension, sub{$pension[$_] > 0});
```

On verra plus loin que cette possibilité est systématiquement utilisée dans les programmes de tabulation (section IV.3).

### II.1.6 La documentation des programmes

L'ensemble des bibliothèques qui vont être présentées dans ce document sont fortement documentées. Les commentaires apparaissent en vert dans les programmes car il s'agit du code couleur par défaut de l'environnement PerllDE.

<footnote n="3">³ Dans tout le texte, on parlera indifféremment de sous-programmes, procédures ou fonctions.</footnote>
Il en existe deux sortes :

- Des commentaires simples précédés du symbole #.

- Des commentaires précédés de séquences de contrôle en début de ligne tels que `=head`, `=head1` (début de section) et `=cut` (fin de section). Cette écriture évite d'écrire un `#` en début de chaque ligne quand le commentaire est long. Les commentaires présentés sous cette forme peuvent aussi être extraits du programme par des utilitaires Pod2... qui les convertissent en divers types de fichiers texte (tels que `.txt`, `.man`, `.tex`). Une partie du présent document a été produite de cette manière.

## II.2 Environnement Perl IDE

Comme la plupart des langages de même type, Perl utilise deux types de fichiers source,

- des fichiers correspondant aux programmes principaux. Leur nom d'extension est `.pl`

- des fichiers de librairies. Leur nom d'extension est `.pm`.

La création et la mise en œuvre de ces fichiers nécessitent de disposer d'un environnement **de développement intégré** et d'un **compilateur/exécuteur**. Plusieurs versions de l'un et l'autre sont disponibles sur le Web. Le développement de Destinie 2 s'est fait avec le compilateur ActivePerl accessible sur le site www.activestate.com et l'environnement de développement intégré Perl IDE téléchargeable sur http://www.open-perl-ide.sourceforge.net/.

En principe, mais ceci n'a pas été testé, le code source Perlde Destinie est directement transférable vers des plateformes Mac OS ou Linux (Perl est préinstallé sur tous les systèmes Unix).

La figure 3 donne une image de l'écran de l'environnement Perl IDE. Les parties les plus utilisées pour le modèle Destinie 2 sont la partie droite de l'écran et la partie basse. La partie en haut à droite donne la liste des fichiers source sur lequel travaille l'utilisateur. Chaque onglet correspond au code source d'un programme principal ou d'une bibliothèque. On peut ouvrir autant d'onglets que l'on veut en même temps.

Pour lancer un programme plusieurs solutions existent. La solution la plus simple, une fois positionné sur le bon fichier, est de lancer la commande Run dans le menu déroulant du même nom.

Les résultats de l'exécution apparaissent dans deux fenêtres du bas de l'écran. La fenêtre **Console** est celle dans laquelle apparaissent les affichages écran demandés au fur et à mesure de la simulation, la fenêtre **Error Output** est celle où sont reportés les messages d'erreur.

Dans certains cas, on peut préférer lancer le programme Perl depuis l'extérieur de l'environnement IDE. Il faut dans ce cas que le contenu du fichier `.pl` ait été sauvegardé (par la commande **Save** du menu **File**). L'exécution directe de ce fichier `.pl` se fait en l'ouvrant avec la commande **perl.exe**. Ce mode d'exécution est préférable pour les programmes `.pl` interactifs et notamment l'explorateur. On notera qu'il n'existe pas de version `.exe` de cet explorateur. Perl est un langage interprété qui ne connaît que les fichiers de code source et les recompile automatiquement à chaque exécution.
<figure><img src="image_5.png" /><figcaption>Figure 3 : L'environnement Perl IDE</figcaption></figure>
## II.3 Organisation physique des fichiers

La figure 1 de l'introduction avait permis d'identifier les principaux éléments de la boite à outils Destinie, constituée de modules `.pm`, de l'explorateur, de fichiers de paramètres et des données individuelles récupérées du générateur de biographies. Pour que l'ensemble fonctionne, l'organisation de ces différents fichiers sur le disque de travail doit respecter quelques règles qui ont été choisies pour faciliter le portage du programme d'un ordinateur à un autre.

L'ensemble du travail se fait sur un répertoire ou un sous-répertoire du disque de travail devant comporter le mot Destinie, que ce soit en minuscule ou en minuscule. Ce sous-répertoire contient deux sous-répertoires obligatoires :

- Le sous-répertoire *Outils* contient l'ensemble des utilitaires `.pm` et l'explorateur *Explore.pl*. En usage standard, l'utilisateur n'accède à ce répertoire que pour l'exécution de l'explorateur, sauf s'il a créé un raccourci pointant vers ce fichier. Ce répertoire contient aussi les deux fichiers de paramètres *ParamSociaux.xls* et *ParamMortal.xls*. Il contient enfin trois sous-répertoires contenant les librairies d'interface Perl/Excel récupérées sur le site http://www.cpan.org<fnref n="4" /> et qui sont utilisées par la libraire *OutilsExcel.pm*.

- Le sous-répertoire *Bios* sert à stocker les jeux de fichiers de biographies. Les biographies sont stockées dans des fichiers *BioEmp.txt* qui contiennent l'ensemble des trajectoires professionnelles et des fichiers *BioFam.txt* qui comprennent, année après année, l'ensemble des évolutions de la situation familiale. Typiquement, on pourra avoir au moins deux versions de chacun de ces fichiers : des versions de taille réduite pour les travaux de mise au point et des versions de grande taille pour les applications finales. Chaque version du couple *BioEmp/BioFam* devra être stockée dans un sous-répertoire différent du répertoire *Bios*.

<table><caption>Figure 4 : Arborescence type du répertoire Destinie 2
(en gras, noms ou éléments de noms obligatoires)</caption><thead><tr><th></th><th></th><th></th></tr></thead><tbody><tr><td>..\destinie v2</td><td>Bios</td><td><pre><code>\petit BioEmp.txt
chantillon BioFam.txt</code></pre><pre><code>\gros BioEmp.txt
chantillon BioFam.txt</code></pre><pre><code>...</code></pre></td><td rowspan="2">Fichiers de<br>biographies</td></tr><tr><td></td><td>Outils</td><td><pre><code>\OLE-Storage_Lite-0.14
\Spreadsheet-ParseExcel-0.2603
\Spreadsheet-WriteExcel-2.15
Explore.pl
DefVarRetr.pm
OutilsRetr.pm
OutilsTab.pm
OutilsExcel.pm
OutilsDroits.pm
OutilsComp.pm
OutilsBase.pm
OutilsMen.pm
ParamSociaux.xls
ParamMortal.xls</code></pre></td></tr><tr><td></td><td>Simul</td><td><pre><code>\Appli 1
Simul1.pl
Resultats1.xls
Simul2.pl
Resultats2.xls
...
\Appli 2
Simul.pl
Resultats.xls</code></pre></td><td>Utilitaires</td></tr><tr><td></td><td></td><td></td><td>Programmes<br>de simulation<br>et résultats</td></tr></tbody></table>

<footnote n="4">⁴ Il s'agit du site du Comprehensive Perl Archive Network qui mutualise l'ensemble des instruments produits pour et par la communauté Perl.</footnote>
En dehors de ces deux contraintes, les programmes .pl de simulation et leurs résultats peuvent être stockés dans des emplacements quelconques du répertoire Destinie, mais on suggère de les cantonner dans un sous répertoire Simul, lui-même subdivisé en autant de sous-répertoires que de projets mobilisant le modèle.

La figure 4 donne un tel modèle d'arborescence en identifiant en caractères gras les fichiers fournis par Destinie et/ou noms de répertoires imposés et, en caractères normaux les fichiers et répertoires laissés à l'initiative de l'utilisateur.
## III - Les variables

Les règles de base du langage ayant été posées, nous allons voir dans cette partie et dans les deux suivantes comment utiliser le bloc retraite a minima, sans rentrer dans les détails des calculs effectués par le modèle.

Cette partie est consacrée à la présentation exhaustive de la liste des variables prédéfinies gérées par le modèle Destinie et des règles à suivre pour la création de variables additionnelles. On commencera par expliciter la différence entre les notions de variables globales et locales (section III.1). Les variables prédéfinies par Destinie sont du premier type alors que les variables créées par l'utilisateur sont de deuxième type. On donnera ensuite une vue générale du type d'information que requiert une simulation de retraite (section III.2) ce qui permettra de mieux comprendre le pourquoi des différents types de variables prévus par Destinie dont la liste sera présentée exhaustivement section III.3. Puis on indiquera dans quel cas et de quelle manière on est amené à créer des variables additionnelles propres à chaque simulation (section III.4).

### III.1 Préliminaire technique : les notions de variables locales et globales

Avant de détailler comment initialiser des variables dans Destinie 2, il est essentiel de comprendre les différents types de variables que gère Perl en général et que gère ce modèle en particulier. Le type de variables dépend de l'endroit où elles sont utilisées et de la façon dont elles sont initialisées. Perl permet de déclarer des variables à deux niveaux :

- Les variables locales qui ne sont utilisables que depuis le programme principal ou le sous-programme où elles ont été déclarées<fnref n="5" />.

- Des variables globales partagées entre les différents modules et le programme principal.

Les variables locales sont déclarées par l'instruction `my` suivie de la liste de variables entre parenthèses, par exemple `my ($var1, @var2)`. Le terme `my` fait bien ressortir que ces variables sont propres au bloc de texte dans lequel elles sont déclarées. On a vu dans l'exemple de l'introduction que c'est cette instruction `my` qui sert à déclarer les variables du programme `pl` qui ne sont pas des variables par défaut de Destinie.

Les bibliothèques contiennent également de grands nombres de variables locales qui sont uniquement destinées à des calculs internes à ces bibliothèques, et qui ne seront donc pas visibles depuis le programme principal, parce qu'on a considéré que cette visibilité n'était pas nécessaire. Par exemple, il existe dans la bibliothèque `OutilsDroits` une fonction `SalBase`, qui calcule le salaire de référence du régime général, i.e. la moyenne des salaires des meilleures années de la carrière. Pour ce faire, la fonction `SalBase` gère un tableau intermédiaire de salaires qui seront triés par ordre décroissant avant calcul de leur moyenne sur le nombre d'années choisi. Un tel tableau n'a pas à être conservé de manière permanente et il s'agit donc d'un tableau local à cette fonction `SalBase`, dont le contenu est détruit sitôt que Perl sort de cette fonction.

La déclaration en variables globales a été réservée à l'ensemble des variables dont on peut avoir besoin dans le programme principal. Pour ce faire, elles sont déclarées dans le module `DefVarRetr` par une instruction `our`, telle que `our (@var1, @var2..)` mais elles nécessitent aussi l'appel à une procédure d'exportation pour être visibles depuis d'autres modules. Plus précisément, `DefVarRetr` commence, sous forme très abrégée, par une séquence d'instructions de type :

<footnote n="5">⁵ Le terme Perl exact est variables lexicales, i.e. dont la portée correspond à un certain bloc de texte du code source. Ce terme sert à les différencier d'un autre concept de variable locale qui existait dans les premières versions du langage. On utilisera néanmoins le terme de local car plus suggestif et plus familer.</footnote>
```perl
require Exporter;
our @ISA = qw (Exporter);
our @EXPORT = qw (@anaiss @sexe @findet @pere @mere @matri @conjoint);
```

qui signifie que `DefVarRetr` met les variables `@anaiss`, `@sexe`... à disposition de tous les programmes ou autres modules qui feront appel à lui.

Cette syntaxe est un peu complexe, mais sa maitrise n'est utile qu'à l'utilisateur qui souhaiterait développer ses propres modules et nous n'y reviendrons donc qu'à la partie VII. Pour les utilisations courantes, il suffit de savoir que `DefVarRetr` contient un jeu d'instructions de ce type qui met à disposition de l'utilisateur un certain nombre de variables. Le point important est surtout de savoir quelles sont ces variables, comment elles sont alimentées et comment elles peuvent être utilisées. C'est ce à quoi sont dédiées les sous-sections suivantes. Avant cela, il faut se poser la question de ce dont a besoin, en règle générale, un programme de calcul de droits à retraite. C'est l'objet de la section III.2.

## III.2 De quelles informations a-t-on besoin pour simuler les retraites ?

Le calcul des pensions de retraite relève de règles complexes et variées selon les régimes de retraite. La simulation des pensions et des départs à la retraite nécessite de disposer de nombreuses informations sur les individus et sur la réglementation en vigueur. Nous ne verrons pas dans ce document la réglementation détaillée et les différents modes de calcul des pensions. Pour faciliter la lecture de ce guide, on va néanmoins rappeler les bases générales de ces calculs, afin de bien comprendre de quelles informations il est nécessaire de disposer dans le cadre du modèle Destinie.

### La carrière professionnelle

Les pensions de base au régime général et dans la fonction publique, correspondent à une proportion d'un montant de salaire. Le montant de ce salaire utilisé dans le calcul de la pension dépend de la carrière des individus. Il peut s'agir d'un salaire annuel moyen (SAM) sur les n meilleures années de salaires, du dernier salaire selon le régime. L'importance de la part du salaire versée dépend des périodes pendant lesquelles l'individu peut être considéré comme affilié à ce régime : les durées validées dans ce régime.

Les salaires perçus et les périodes de la carrière (en emploi, au chômage, dans la fonction publique, au régime général...) sont donc les éléments clés pour le calcul de la retraite. Les durées prises en compte pour la retraite ne correspondent pas seulement aux années travaillées, mais aussi aux périodes de chômage et de préretraite. Pour le calcul du salaire à prendre en compte, il est nécessaire de disposer d'informations sur les salaires perçus par chaque individu tout au long de sa carrière, mais aussi des allocations de chômage et de préretraite, puisque ces périodes sont également prises en compte. Un point important est que les règles de calcul des retraites s'appliquent à des salaires nominaux. De manière générale, le séries gérées ou produites par Destinie sont des séries nominales. Les convertir en données réelles imposera de les rediviser par l'indice des prix, mais ceci est facilité par le fait que cet indice des prix fait partie des variables fournies par le modèle.

### Les situations familiales

Le système de retraite accorde également des droits spécifiques aux individus selon leur situation familiale. Si la personne a eu des enfants, elle bénéficie d'une majoration de la durée validée (MDA). Si elle s'est arrêtée de travailler pour élever ses enfants, elle a le droit de valider certaines de ces années par le biais de l'allocation vieillesse aux parents au foyer (AVPF). Il faut donc disposer d'informations sur les enfants de chaque individu. De plus une pension de réversion peut être versée au conjoint survivant lorsqu'un individu décède. Il faut donc connaître la situation de couple des personnes dont on simule les retraites, en particulier connaître leur conjoint éventuel pour pouvoir, le moment venu, lui affecter une pension de réversion.
### La législation

Ces principes généraux du calcul des retraites sont nettement plus complexes lorsqu'on applique la législation propre à chaque régime. De plus, le système de retraite a connu de nombreuses réformes au cours du temps et toutes les générations ne se voient pas appliquer les mêmes règles de calcul. Chaque année, la valeur de certains éléments de calcul de la pension sont également revalorisés : le plafond de la sécurité sociale, les valeurs des points... Pour simuler les retraites dans le temps comme le fait le modèle Destinie, il est nécessaire d'intégrer toutes les composantes de la législation pour tous les régimes, toutes les années et toutes les générations.

### Les modalités de départ à la retraite

Enfin, le modèle Destinie simule le moment où un individu part à la retraite. Dans la réalité, le moment du départ résulte d'un choix individuel complexe (selon des critères financiers mais également des préférences personnelles) et de règles imposées aux individus (âge minimum, âge maximum...). Un des intérêts de Destinie est de permettre de simuler différentes méthodes de détermination du moment du départ à la retraite. Par exemple on peut imposer que tous les individus liquident leur pension lorsque le taux de liquidation est maximum et pas avant ni après, ou bien imposer un âge identique pour tous, ou proposer des modes de choix plus libres et plus complexes. Pour cela le modèle doit disposer de tous les éléments permettant de mettre en œuvre ces différents modes de départ à la retraite.

## III.3 Les variables prédéfinies (bibliothèque DefVarRetr)

### III.3.1 Vue d'ensemble

De très nombreuses variables sont prévues par Destinie pour stocker et gérer l'ensemble de ces informations. Ces variables sont définies par le module `DefVarRetr.pm` et sont essentiellement des variables individuelles et des paramètres de calcul des droits à retraite. L'utilisateur n'a pas à les redéclarer, mais il a besoin de les connaître pour pouvoir les utiliser. Plus précisément, on distinguera six rubriques :

- Les variables individuelles de type tableau qui vont servir d'input aux simulations de retraite. Il va s'agir pour l'essentiel de données récupérées du générateur de biographies, et aussi de quelques paramètres de comportement auxquels ce module attribue des valeurs par défaut, modifiables au besoin. Ces opérations de récupération ou d'initialisation mobiliseront deux programmes fournis dans `OutilsRetr`: les programmes `UseBios` et `Relec`.

- Des variables individuelles d'output, également de type tableau, et destinées à accueillir les résultats de la simulation des droits à retraite. Le calcul de ces droits constitue l'objet principal de la simulation. Il est réalisé à l'aide des autres fonctions de la bibliothèque `OutilsRetr`. `DefVarRetr` se contente de définir ces variables sans leur donner de valeurs par défaut.

- Des variables individuelles de travail de type scalaire. Contrairement aux deux groupes précédents qui sont des variables indicées par `$i$, ces variables sont des scalaires utilisés temporairement pour stocker des intermédiaires de calcul. Leurs valeurs sont écrasées lorsque le programme passe à la simulation de l'individu suivant. Ce système économise la place mémoire. Mais, en fonction des besoins, on peut consulter ces variables en cours de simulation ou créer des variables permanentes dans le programme appelant pour en stocker les résultats.

- Les paramètres de calcul des droits à retraite qui se présentent sous forme de séries temporelles lues dans des fichiers Excel. Les valeurs par défaut de ces paramètres sont lues par `DefVarRetr`, et peuvent être modifiées ensuite au gré des scénarios.
- Des paramètres de calcul des droits à retraite plus complexes, traités comme scalaires. Leurs valeurs sont fixées par appel du programme `UseLeg`, lui aussi fourni dans `OutilsRetr`.

- Il existe enfin divers types de variables auxiliaires, telles que des variables stockant les codes utilisés pour les variables individuelles qualitatives, ce qui dispense de connaître les valeurs numériques de ces codes, ou encore les noms des fichiers ou des répertoires de travail, ainsi que diverses options de simulation.

Ces six groupes de variables vont être examinés dans les sous-sections III.3.2 à III.3.7. Les listes complètes n'en seront pas systématiquement données. Le lecteur est renvoyé aux annexes pour ces listes complètes, données soit sous forme alphabétique soit par catégorie.

Indépendamment de `DefVarRetr`, l'utilisateur peut vouloir rajouter à cette liste d'autres variables qui lui seront utiles. La section III.4 sera consacrée aux exemples de variables micro-additionnelles ou variables macro qu'on est amené à déclarer et utiliser dans le programme principal.

### III.3.2 Variables individuelles d'input

Les variables individuelles d'input sont les variables individuelles sur lesquelles va s'appuyer la simulation des droits à retraite de chaque personne de l'échantillon. Leurs valeurs seront renseignées par la procédure `Relec` de la bibliothèque `OutilsRetr` qui sera présentée plus loin.

Ce groupe de variables comprend lui-même trois sous-groupes.

- les variables lues directement dans les fichiers issus du générateur de biographies,

- quelques variables dérivées des précédentes, calculées ou imputées par `Relec`,

- les variables de préférences utilisées dans certains types de simulation des comportements de départs à la retraite. Elles ne sont pas issues du générateur de biographies. `Relec` se charge de les initialiser à des valeurs par défaut.

Même si une bonne part de ces variables n'ont pas à être utilisées directement en fonctionnement standard, on donne leur liste complète, compte tenu de leur rôle central dans le programme, et aussi parce que c'est l'occasion de donner l'aperçu de ce que produit le générateur de biographies. Il s'agit dans tous les cas de tableaux indicés par l'identifiant individuel, qu'on notera en général `$i$, l'individage commençant à la position 1 (il n'y a pas d'individu 0) et éventuellement par un deuxième indice. On donne directement le format d'appel de leurs éléments scalaires, plutôt que leur nom de tableau commençant par `@`.

Le premier sous-groupe comprend :

<table><tr><td>$anaiss[$i]</td><td>: l'année de naissance</td></tr><tr><td>$sexe[$i]</td><td>: le sexe</td></tr><tr><td>$findet[$i]</td><td>: l'âge de fin d'études</td></tr><tr><td>$pere[$i]</td><td>: l'identifiant du père</td></tr><tr><td>$mere[$i]</td><td>: l'identifiant de la mère</td></tr><tr><td>$matri[$i]</td><td>: le statut matrimonial</td></tr><tr><td>$conjoint[$i]</td><td>: l'identifiant du conjoint</td></tr><tr><td>$enf[$i][$e]</td><td>: les identifiants des enfants</td></tr><tr><td>$statut_[$i][$a]</td><td>: la séquence des statuts passés par rapport à l'emploi</td></tr><tr><td>$salaire_[$i][$a]</td><td>: la séquence des salaires nominaux passés par âge</td></tr><tr><td>$tauxPrim[$i]</td><td>: le taux de prime si l'individu travaille dans la fonction publique</td></tr></table>

Le deuxième sous-groupe comprend :

<table><tr><td>$trim[$i]</td><td>: le trimestre de naissance</td></tr></table>
<table><tr><td>$age[$i]</td><td>: l'âge courant</td></tr><tr><td>$present[$i]</td><td>: une indicatrice de présence dans l'échantillon à la date courante (entre la naissance ou la migration et le décès)</td></tr><tr><td>$statut[$i]</td><td>: le statut courant (i.e. $statut_[$i][$age[$i]])</td></tr><tr><td>$salaire[$i]</td><td>: le salaire nominal courant (i.e. $salaire_[$i][$age[$i]])</td></tr><tr><td>$deces[$i]</td><td>: indique si l'individu est décédé l'année en cours</td></tr><tr><td>$migrant[$i]</td><td>: indique si l'individu est un migrant de l'année</td></tr></table>

Le troisième sous-groupe comprend enfin :

<table><tr><td>$taux[$i]</td><td>: la préférence pour le présent</td></tr><tr><td>$k[$i]</td><td>: la préférence pour le loisir/coefficient de pénibilité du travail</td></tr><tr><td>$gamma[$i]</td><td>: l'aversion pour le risque</td></tr><tr><td>$seuil[$i]</td><td>: seuil de déclenchement du report du départ en retraite</td></tr></table>

La signification exacte des variables @taux, @k, @gamma et @seuil apparaîtra plus loin. Il s'agit de variables commandant le comportement de départ en retraite. Elles sont initialisées à des valeurs par défaut mais modifiables par le programme appelant si ce paramétrage ne convient pas ou si on veut introduire une hétérogénéité individuelle de ces paramètres.

Concernant les autres variables, deux points sont à préciser.

Tout d'abord, les identifiants des personnes apparentées à l'individu $i$ peuvent eux-mêmes être utilisés comme indices. Cela signifie que Destinie accepte des syntaxes de type `$age[$pere[$i]]` qui donne directement l'âge du père de l'individu $i$. Ce type d'appel n'est pas courant en utilisation standard, mais on devine facilement les utilisations qui peuvent en être faites. Par exemple, les procédures de la bibliothèque `OutilsMen` qui sera présentée en partie IV utilisent cette fonctionnalité.

Le second point concerne les variables à double-indice. Il y a deux cas de figure.

- Le premier est celui de la variable `@enf`, dont le premier indice est l'individu, et le deuxième indice est le rang de naissance de l'enfant. Cela veut dire que le tableau `@{$enf[$i]}` donne directement la liste des identifiants des enfants de l'individu $i$. La bibliothèque `OutilsMen` qui sera présentée en partie VI utilise là encore cette fonctionnalité.

- Le second cas est celui des variables rétrospectives. Le principe est de leur donner un nom se terminant par un blanc souligné. Par défaut, Destinie en gère deux, celles qui sont indispensables aux calculs de droits à retraite. Il s'agit des variables `@salaire_` et `@statut_` qui donnent un rétrospectif des carrières. Pour l'individu $i$, le statut et le salaire à l'âge $a$ sont accessibles par `$statut_[$i][$a]` et `$salaire_[$i][$a]$. Les séquences complètes correspondantes sont les tableaux simples `@{$statut_[$i]}` et `@{$salaire_[$i]}`. Les procédures de calcul des retraites font un large appel à ces données rétrospectives.

À ces variables `@statut_` et `@salaire_` sont associées les variables simples `@statut` et `@salaire` qui donnent le salaire et le statut courants. Ces deux variables n'apportent aucune information supplémentaire : on a redondance entre `$statut[$i]` et `$statut_[$i][$age[$i]]`, et entre `$salaire[$i]` et `$salaire_[$i][$age[$i]]`. Mais ces deux variables ont été introduites car elles donnent le statut et le salaire courant dans des formes qui seront utilisables par les procédures de tabulation, alors que les tableaux à double indice `@statut_` et `@salaire_` ne le sont pas.

Destinie n'a pas prévu d'autres variables à double indice pour ne pas saturer d'office la place mémoire. Mais l'utilisateur peut en créer d'autres en fonction de ses besoins. Par exemple, un programme pourrait créer et renseigner une variable `$conjoint_[$i][$a]` qui donnerait l'historique des conjoints successifs de cet individu, si cette information s'avérait nécessaire.
### III.3.3 Variables individuelles d'output

Ces variables sont construites sur le même modèle que les variables présentées à la section précédente, mais à la différence des variables initialisées par Relec, il s'agit de variables qui vont découler de la simulation des retraites. Ici encore on donne leur liste complète, car c'est en général sur ces variables que porteront les demandes de tabulation. Il est donc nécessaire de toutes les connaître. Il s'agit de :

<table><tr><td>$pension rg[$i]</td><td>: pension régime général</td></tr><tr><td>$pension ar[$i]</td><td>: pension arrco</td></tr><tr><td>$pension ag[$i]</td><td>: pension agirc</td></tr><tr><td>$pension fp[$i]</td><td>: pension fonction publique</td></tr><tr><td>$pension in[$i]</td><td>: pension d'indépendant</td></tr><tr><td>$pension cn pri[$i]</td><td>: pension comptes notionnels du secteur privé (si existe)</td></tr><tr><td>$pension cn fp[$i]</td><td>: pension comptes notionnels du secteur public (si existe)</td></tr><tr><td>$pension[$i]</td><td>: pension directe totale (somme des sept précédentes)</td></tr><tr><td>$rev rg[$i]</td><td>: réversion régime général</td></tr><tr><td>$rev ar[$i]</td><td>: réversion arrco</td></tr><tr><td>$rev ag[$i]</td><td>: réversion agirc</td></tr><tr><td>$rev fp[$i]</td><td>: réversion fonction publique</td></tr><tr><td>$rev in[$i]</td><td>: réversion d'indépendant</td></tr><tr><td>$pension cn pri[$i]</td><td>: réversion comptes notionnels du secteur privé (si existe)</td></tr><tr><td>$pension cn fp[$i]</td><td>: réversion comptes notionnels du secteur public (si existe)</td></tr><tr><td>$rev[$i]</td><td>: réversion totale (somme des sept précédentes)</td></tr><tr><td>$min vieil[$i]</td><td>: allocation du minimum vieillesse</td></tr><tr><td>$ageliq[$i]</td><td>: âge de la liquidation</td></tr><tr><td>$pliq[$i]</td><td>: pension à la liquidation</td></tr></table>

Cette liste n'est pas figée. L'utilisateur peut souhaiter rajouter des variables de même type ou bien des variables dérivées à double indice sur le modèle présenté à la section précédente. Par exemple une variable $pension[$i][$a]$ peut servir à stocker la séquence des pensions successives de chaque individu et servir à des calculs de somme de droits actualisés durant la retraite ou à produire des profils d'évolution du niveau de vie par âge.

Un autre exemple de variable additionnelle sont les variables d'archivage. Une variable d'archivage peut par exemple conserver les valeurs de @ageliq obtenues dans une simulation de référence et les utiliser pour des variantes à âge de la retraite exogène, pour simuler l'impact de réformes à comportements inchangés. Les variables d'archivage peuvent aussi permettre la comparaison des résultats de scénarios individus par individus.

On reviendra sur les différents exemples possibles de variables additionnelles en partie III.4.

### III.3.4 Variables individuelles temporaires

Les variables de retraite qu'on vient d'indiquer sont des variables de résultats finaux. Le calcul des retraites inclut aussi la production de beaucoup d'éléments intermédiaires, par exemple le SAM et la durée cotisée pour le régime général, ou encore la durée tous régimes.

Il n'a pas été prévu que ces variables intermédiaires soient systématiquement gardées dans des tableaux indicés par $i$. Elles sont stockées dans des variables scalaires, ce qui veut dire que l'information est perdue lorsque le programme procède à un nouveau calcul de retraite pour un autre individu. Mais il peut-être utile et il est possible d'y accéder avant ce passage à l'individu suivant. À l'intérieur d'une boucle sur $i$, elles sont visibles depuis le programme principal pour cet individu $i$ tant que l'on n'est pas passé à l'individu suivant de la boucle.

Ici encore, on donne leur liste complète :
<table><tr><td>$dureefra</td><td>: durée cotisée au régime général</td></tr><tr><td>$duree_fpa</td><td>: idem, en service actif</td></tr><tr><td>$duree_fps</td><td>: idem, en service sédentaire</td></tr><tr><td>$duree_in</td><td>: durée cotisée en régime d'indépendant</td></tr><tr><td>$duree_tot</td><td>: durée cotisée totale</td></tr><tr><td>$duree_avpf</td><td>: durée de bénéfice de l'AVPF</td></tr><tr><td>$dureefra_maj</td><td>: durée RG incluant AVPF et MDA (selon options)</td></tr><tr><td>$duree_fpa_maj</td><td>: durée FP incluant MDA éventuelle (selon options)</td></tr><tr><td>$duree_in_maj</td><td>: durée indépendant incluant MDA éventuelle (selon options)</td></tr><tr><td>$duree_tot_maj</td><td>: durée totale incluant AVPF et MDA (selon options)</td></tr><tr><td>$duree_cho</td><td>: durée passée au chômage</td></tr><tr><td>$duree_emp</td><td>: durée passée en emploi</td></tr><tr><td>$duree_PR</td><td>: durée passée en préretraite</td></tr><tr><td>$samfra</td><td>: SAM servant au calcul de la pension RG</td></tr><tr><td>$sam_in</td><td>: SAM pour le calcul de la pension d'indépendant</td></tr><tr><td>$sr_fpa</td><td>: salaire de référence pour le calcul de la pension FP</td></tr><tr><td>$points_arrco</td><td>: cumul de points ARRCO</td></tr><tr><td>$points_agirc</td><td>: cumul de points AGIRC</td></tr><tr><td>$points-cn_pri</td><td>: cumul de points comptes notionnels secteur privé</td></tr><tr><td>$points-cn_fpa</td><td>: cumul de points comptes notionnels secteur public</td></tr><tr><td>$min_cont</td><td>: minimum contributif</td></tr><tr><td>$min_garanti</td><td>: minimum garanti</td></tr><tr><td>$id_clone</td><td>: id de l'individu de départ lorsqu'on travaille sur un clone</td></tr></table>

Ces variables peuvent soit être affichées à la volée (par exemple dans une phase de débogage où on a identifié un problème sur un individu particulier) soit être stockées dans un tableau qu'on aura pris soin de prédéclarer, et qui peut d'ailleurs prendre le même nom puisque Perl sait faire la différence entre un tableau @x, son $i-ème élément $x[$i] et le scalaire $x.

Autrement dit, on peut avoir, dans le programme appelant :

my (@points_arrco);

for $t..

{

for $i...

{

Simulation

$points_arrco[$i]=$points_arrco;

}

}

après quoi la distribution des points ARRCO peut être calculée. Ce genre de manipulation suppose évidemment de bien savoir de quelle façon les différents programmes manipulent ces variables tampon.

### III.3.5 Paramètres temporels lus dans des fichiers Excel.

Pour calculer les droits à retraite et procéder aux simulations de comportement qui vont alimenter ces variables d'output, la bibliothèque `OutilsRetr` et les bibliothèques qu'elle appelle vont avoir besoin de nombreux paramètres. Une partie de ces paramètres sont stockées dans deux fichiers Excel, et relus directement par `DefVarRetr`. Il s'agit des fichiers `ParamSociaux.xls` et `ParamMortal.xls`. Ces deux fichiers doivent se trouver sur le même répertoire que celui où figure `DefVarRetr.pm`.
Le fichier ParamSociaux.xls contient des éléments de barèmes qui ont la forme de séries temporelles simples<fnref n="6" />. Pour ces séries temporelles, la convention d'indication est de prendre l'année 1900 comme année de départ. Autrement dit l'indice 0 correspond à l'année 1900. Par exemple $PlafondSS[98] est le plafond de la sécurité sociale de l'année 1998, $PlafondSS[102] est celui de l'année 2002. On représente que, comme toutes les autres données monétaires générées par Destinie, il s'agit de valeurs nominales, à la conversion près en euros des francs et anciens francs. Elles peuvent être reconverties en valeurs réelles en utilisant l'indice des prix également fourni dans le même fichier.

Ce fichier ParamSociaux.xls comprend sept feuilles correspondant à autant de groupes de paramètres :

- Paramètres généraux (ParamGene) : indice des prix, SMIC, plafond de la sécurité sociale et valeur du point dans la fonction publique.

- Paramètres de calcul des retraites de base et des pensions minimales (ParamRetrBase) : coefficients de revalorisation des pensions, taux minima, coefficient pour la MDA. Ces paramètres sont nécessaires au calcul de la pension de droit direct de base.

- Paramètres des régimes complémentaires (ParamComp) : salaires de référence, taux de cotisations, valeurs du point...

- Paramètres de calcul des réversions (ParamRev) : minimum, maximum, taux de réversion.

- Paramètres de calcul des préretraites (ParamPreRet) : taux de préretraite et âge d'accès.

- Paramètres des prestations familiales (ParamFam) : base mensuelle des allocations familiales et plafonds de ressources pour diverses prestations familiales (complément familial, APJE, PAJE...). Ces paramètres ne sont pas directement utilisés pour le calcul des pensions de retraite, mais peuvent être utiles pour un module sur les prestations sociales ou sur les revenus de façon plus générale.

- Autres paramètres (ParamAutres) : il s'agit de divers taux de cotisation sociale, autres que les cotisations retraite, servant aux calculs des salaires et pensions nettes.

La liste détaillée de ces paramètres se trouve en annexe de ce document.

Les valeurs lues dans ce fichier doivent être vues comme des valeurs de référence qui peuvent faire l'objet de modifications dans le programme appelant selon les besoins des scénarios. Par exemple, en projection, il est possible d'avoir une instruction :

$PlafondSS[$t]=1.03*$PlafondSS[$t-1];

qui imposerait une règle d'évolution du plafond différente de celle prévue par défaut dans le fichier ParamSociaux (cette hypothèse est une indexation sur la productivité, à savoir, par défaut, 1,5 % par an).

Le fichier ParamMortal.xls contient les tables de mortalité qui sont nécessaires aux calculs de droits à retraite actualisés et/ou aux fonctions d'utilité intertemporelles. On dispose à la fois des quotients de mortalité et des taux de survie qui sont tous deux stockés sous forme des tableaux indicés par le sexe, la date et l'âge, de termes génériques $quotient[$s][$t] [$a] et $survie[$s][$t] [$a].

La lecture des deux fichiers ParamSociaux.xls et ParamMortal.xls se fait grâce à la bibliothèque OutilExcel. Les procédures correspondantes ne sont pas à connaître pour les utilisations standard. Contrairement aux procédures d'écriture dans des fichiers Excel qui

<footnote n="6">⁶ Une part importante des barèmes retrospectifs est reprise de Bozio (2008).</footnote>
seront vues plus loin, elles ne sont pas détaillées dans cette présentation des utilisations usuelles du modèle et le lecteur intéressé par la description de ces procédures est renvoyé à la partie V.7.

### III.3.6 Paramètres scalaires générés par la fonction UseLeg.

Pour certains paramètres de calcul (surcote, décote, durée cible, nombre d'années prises en compte pour le SAM...), le stockage dans des fichiers Excel s'est avéré peu pratique. Il s'agit pour l'essentiel de paramètres dépendant à la fois de la période et de la génération, pour lesquels il aurait fallu prévoir des tableaux à double indice et des fichiers Excel de taille importante mais comportant beaucoup de cases redondantes pour les périodes de stabilité des barèmes.

On a donc plutôt choisi de traiter ces paramètres comme des scalaires simples, dont Destinie recalcule la valeur pour chaque cas individuel. Il le fait à l'aide d'une fonction fournie par la bibliothèque `OutilsRetr` qui est la fonction `UseLeg`. Cette fonction joue un rôle crucial pour le choix des scénarios et elle sera analysée plus loin (section IV.2.3).

Comme pour les paramètres lus dans les fichiers Excel, la liste détaillée de des paramètres générés par la fonction `UseLeg` se trouve en annexe de ce document.

### III.3.7 Autres paramètres

Parmi les autres variables ou paramètres, on dispose tout d'abord de variables stockant les codes utilisés pour les variables micro-qualitatives. Par exemple, pour le sexe, au lieu d'identifier les hommes par le code 1 et les femmes par le code 2, on pourra les identifier respectivement par `$CodeHom` et `$CodeFem`. Cette codification est particulièrement utile pour les statuts professionnels qui comprennent beaucoup de modalités et sont souvent utilisées par les différents programmes.

<table><caption>Figure 5 : Liste des codes présents dans le modèle Destinie 2</caption><thead><tr><th>Type de code</th><th>Nom</th><th>Signification</th><th>Valeur(s)</th></tr></thead><tbody><tr><td rowspan="2">Codes sexe</td><td>$CodeHom</td><td>Homme</td><td>1</td></tr><tr><td>$CodeFem</td><td>Femme</td><td>2</td></tr><tr><td rowspan="4">Codes statut matrimonial</td><td>$CodeCel</td><td>Célibataire</td><td>1</td></tr><tr><td>$CodeMar</td><td>Marié (en couple)</td><td>2</td></tr><tr><td>$CodeVeu</td><td>Veuf</td><td>3</td></tr><tr><td>$CodeSepar</td><td>Séparé</td><td>4</td></tr><tr><td rowspan="10">Codes statut d'emploi</td><td>$CodeNC</td><td>Non Cadre du privé</td><td>1</td></tr><tr><td>$CodeCad</td><td>Cadre du privé</td><td>2</td></tr><tr><td>$CodeFPS</td><td>Fonction publique</td><td>31</td></tr><tr><td>$CodeFPA</td><td>sédentaire</td><td>32</td></tr><tr><td>$CodInd</td><td>Fonction publique active</td><td>4</td></tr><tr><td>$CodeCho</td><td>Indépendant</td><td>5</td></tr><tr><td>$CodeIna</td><td>Chômeur</td><td>6</td></tr><tr><td>$CodePr</td><td>Inactif</td><td>7</td></tr><tr><td>$CodeAvpf</td><td>Pré retraité</td><td>8</td></tr><tr><td></td><td>Inactif avec AVPF</td><td></td></tr><tr><td rowspan="3">Codes regroupés</td><td>@CodesAct</td><td>Actifs</td><td>1,2,31,32,4,5</td></tr><tr><td>@CodesOcc</td><td>Actifs occupés</td><td>1,2,31,32,4</td></tr><tr><td>@CodesFP</td><td>Fonction publique</td><td>31,32</td></tr></tbody></table>

Ces variables permettent à l'utilisateur de construire des tabulations sans se soucier des conventions de codage numérique internes à Destinie. Par exemple, on verra plus loin qu'on pourra écrire :

$$ SALMOYNC = MVar (@salaire, sub {$statut[$_] == $CodeNC}); $$
pour calculer le salaire moyen des salariés du privé non cadres, ou encore :

$TAUXVEUVAGE[$a] = Taux (sub{$matri[$_]==$CodeVeu}, sub{$age[$_]==$a});

où $CodeNC = non cadre du secteur privé et $CodeVeu = veuf ou veuve.

Les codes regroupés permettent des écritures simplifiées, par exemple :

$PACT = Count(sub{In($statut[$_],@CodesAct)});
$SALMOYFP = MVar (@salaire,sub{In($statut[$_],@CodesFP)});

où @CodesAct et @CodesFP sont des familles de codes regroupant respectivement l'ensemble des cas d'activité et l'ensemble des cas d'emploi public (actifs et sédentaires).

L'utilisateur peut générer d'autres types de codes regroupés dans le programme appelant en fonction de ses besoins.

On notera l'absence de code spécifique pour les enfants d'âge scolaire ou les retraités. Les premiers sont classés comme inactifs ou en emploi s'il y a cumul emploi-études (le générateur de biographies génère des individus qui travaillent avant d'avoir atteint leur âge de fin d'études).

Pour les seconds, pour éviter toute ambiguïté sur la notion de retraité, le fait d'être repéré comme tel tient uniquement au fait de toucher une pension positive plutôt qu'à un code statut spécifique. Éventuellement, le code statut d'un bénéficiaire d'une retraite pourrait être mis à une autre valeur que $CodeIna, dans des versions du modèle qui autoriseraient le cumul emploi et retraite.

Il est également possible d'afficher les codes en clair, grâce au hachage prédéfini %Label. Par exemple, si un individu est dans le statut 31 à l'âge $a, l'instruction

print $Label{"statut"}[$statut_[$i][$a]];

affichera la chaîne FPA. Cette fonctionnalité est utilisée dans les affichages de l'explorateur qui sera examiné plus loin.

On mentionnera pour finir diverses variables de contrôle de la simulation mais, en utilisation standard, il est surtout utile de connaître les fonctions qui les renseignent puisqu'il n'est en général pas nécessaire d'y accéder directement. On renvoie donc aux tableaux de l'annexe pour leur liste détaillée. Parmi ces variables figurent notamment les noms des répertoires et fichiers de travail, directement reconstitués par le programme ou déterminés par la fonction UseBios, ainsi que des informations sur les données de départ également renseignées lors de l'appel de la fonction UseBios (taux de sondage et année de base).

### III.4 Déclaration de variables micro ou macro additionnelles

À côté des variables globales initialisées dans DefVarRetr et directement mobilisables, l'utilisateur est en général amené à créer d'autres variables propres au programme .pl qu'il construit pour sa simulation.

Il faut d'abord qu'il définisse par lui-même les différents indices de boucle dont il aura besoin (a minima un indice $i et un indice $t).

Il faut ensuite qu'il définisse les variables stockant les résultats macro, c'est-à-dire en général des séries temporelles stockant des résultats globaux année après année, qui seront renseignées à l'aide des procédures de tabulation vues plus loin en IV.3, par exemple @PENSION_MOYENNE pour la série temporelle de la retraite moyenne, @RATIO_DEM pour la projection du ratio retraités/actifs. Aucune de ces variables n'a été prédéfinie en standard, car elles sont complètement dépendantes de l'exercice que l'utilisateur souhaite réaliser
On peut aussi être amené à déclarer des variables micro additionnelles. On a déjà vu plusieurs raisons de le faire :

- Pour récupérer des résultats de calculs intermédiaires des retraites et les conserver pour chaque individu de la population.

- Pour constituer des tableaux à double-indice de données rétrospectives sur le modèle de @statut_ ou @salaire_

- Pour conserver le résultat d'un scénario en vue d'une réutilisation dans un autre scénario du même programme : par exemple l'âge de liquidation pour réutilisation dans un scénario où on contraindra les individus à partir au même âge, ou le niveau de pension pour des comparaisons individuelles avec le niveau observé dans les variantes.

On peut encore imaginer beaucoup d'autres cas de figure :

- Pour créer des descripteurs sociodémographiques non prévus au départ par Destinie. Par exemple, si on veut utiliser le nombre d'enfants, il faut initialiser une variable @nenf qu'on pourra renseigner à l'aide des procédures proposées dans la bibliothèque OutilsMen.

- Pour créer des variables de retraite non standard : par exemple des taux de remplacement, des parts des différentes composantes de la pension dans la pension totale, un compteur du nombre de droits différents dont profite un individu, ou de son apport au revenu global du ménage, etc...

Enfin, mais ceci relève plutôt des utilisations très avancées, l'utilisateur peut être amené à ajouter des paramètres additionnels de calcul des retraites, ou des paramètres gouvernant l'évolution d'autres comportements que le départ en retraite.

Dans tous les cas, il faut déclarer ces variables à l'aide d'une instruction my en début de programme (voir III.1). Avec l'option use strict, l'omission de cette déclaration conduit en effet à un message d'erreur dès qu'on cherche à utiliser la variable, du type :

Global symbol "@MSAL " requires explicit package name...

Lorsqu'on crée ces variables additionnelles, il est suggéré de se tenir aux conventions d'écriture adoptées dans l'ensemble des procédures du modèle, à savoir :

- des minuscules pour les variables micro simples (comme @statut)

- des minuscules suivies d'un blanc souligné pour les variables micro à double indice (comme @statut_)

- une combinaison de majuscules et minuscules pour les paramètres législatifs (comme @ValPtARRCO pour la valeur du point ARRCO)

- des majuscules pour les variables macro (@MSAL)

Le respect de ces règles n'est évidemment pas indispensable, mais il est recommandé pour les programmes destinés à être partagés entre plusieurs utilisateurs (notamment en cas de développement de nouveaux modules).
## IV - Utilisations courantes (1) :
effectuer une simulation et éditer ses résultats

Les différentes catégories de variables Destinie ayant été précisées, on va maintenant pouvoir analyser en détail le contenu d'un programme de simulation.

Comme on l'a vu en introduction, la production d'une simulation nécessite l'écriture d'un programme principal (i.e. un fichier .pl) spécifiquement dédié à cette simulation dont la structure type est donnée par la figure 6. Sous sa forme la plus courante, il contiendra quatre éléments principaux :

- Un ensemble d'initialisations (préambule) : appels des bibliothèques, déclarations de variables autres que celles définies par défaut, ouvertures de fichiers ou choix de certaines options générales de simulation.

- La simulation des retraites proprement dite, qui prend la forme d'une boucle temporelle et d'une boucle individuelle emboîtées

- La production de résultats agrégés par appel à des fonctions de tabulation

- La sauvegarde de ces résultats dans des fichiers Excel.

Cette forme de base peut elle-même connaître des variantes ou additions diverses.

- Il est possible d'imbriquer des boucles supplémentaires : par exemple insérer la boucle temporelle au sein d'une boucle balayant plusieurs scénarios successifs, ou enchainer plusieurs boucles individuelles au sein de la même boucle temporelle. Enchainer plusieurs boucles individuelles est notamment nécessaire pour le calcul de droits à retraite sous condition de ressource du ménage. Calculer l'accès d'un couple au minimum vieillesse suppose en effet la connaissance des retraites des deux conjoints. Il faut donc qu'une première boucle ait calculé les droits de l'ensemble de la population avant de pouvoir vérifier si tel ou tel couple d'individus a droit au minimum vieillesse.

<figure><img src="image_6.png" /><figcaption>Figure 6 : organisation d'un programme principal</figcaption></figure>
- Il est possible de créer et renseigner d'autres variables micro que celles que le modèle gère par défaut. Par exemple, dans une simulation qui chaîne plusieurs scénarios, une variable `$taux_rep{$sc}[$i]` peut être créée pour stocker le taux de remplacement de l'individu $i dans le scénario $sc, après quoi il sera possible de calculer et analyser des écarts de taux de remplacement, d'un scénario à l'autre, individu par individu.

- Il est également possible de sauvegarder les résultats sous d'autres formats qu'en Excel.

Cette partie va présenter l'ensemble de ces opérations. La section IV.1 présentera le préambule type d'un programme de simulation. La section IV.2. portera sur le cœur de la simulation et sera donc surtout consacrée au contenu et à l'utilisation de la bibliothèque `OutilsRetr`. La section IV.3 expliquera comment générer et sauvegarder des variables de résultats à l'aide des programmes de tabulation et d'écriture des bibliothèques `OutilsTab` et `OutilsExcel`. La section IV.4 présentera enfin quelques exemples d'utilisation plus élaborés.

# IV.1 Le préambule d'un programme de simulation

## IV.1.1 Initialisations des programmes et des variables locales

Les premières lignes du programme prennent généralement la forme suivante :

```perl
# Ce programme effectue une projection des retraites sous l'hypothèse départ
# au taux plein avec la législation de 2003. Il calcule trois variables
# d'output :
# - le niveau de la retraite moyenne,
# - le ratio retraites/masse salariale
# - Le ratio retraités/actifs occupés
# Ces résultats sont sauvegardés dans le fichier Excel Exemple.xls
```

```perl
use strict;
```

Il est conseillé de commencer les programmes principaux par quelques lignes de commentaires. Les trois premières lignes du programme ci-dessus constituent des commentaires. Ils sont reconnaissables ici par la présence du signe `#` en début de ligne et ils apparaissent par défaut en vert dans l'environnement PerlIDE.

On a également vu qu'il est vivement conseillé d'utiliser la directive de compilation `use strict` située en début de code source, qui force l'utilisateur à prédéfinir toutes ses variables. Par défaut, aucune prédéclaration n'est requise dans Perl : on verra que le programme `Explore.pl` utilise cette faculté qui est particulièrement agréable en mode interactif, mais qui est en général déconseillée dans les programmes de grande taille.

La suite du préambule est constituée d'une séquence d'instructions du type :

```perl
use lib "../../Outils";
use DefVarRetr;
use OutilsRetr;
use OutilsTab;
use OutilsExcel;
my ($i, $t, @PENSION_MOYENNE, @RATIO_DEM, @RATIO_FIN, $resultats);
```

Dans cette séquence, l'instruction `use lib` sert à déclarer le répertoire dans lequel vont être trouvées ces différentes bibliothèques. On voit que le chemin d'accès est indiqué à l'aide de la syntaxe `../../` qui est celle à donner avec l'arborescence qui était proposée en section III.1. Chaque chaîne de caractère `../` signifie qu'il faut remonter d'un niveau dans l'arborescence pour trouver la librairie indiquée.
On fournit ensuite autant d'instructions `use qu'il y aura de librairies directement mobilisées par le programme appelant. Si l'une des ces instructions `use` est oubliée dans le programme principal, des messages d'erreur apparaissent dans la fenêtre `Error Output`. Par exemple, si on oublie `DefVarRetr` qui initialise les variables, dès que le programme rencontre un appel d'une variable déclarée dans `DefvarRetr`, le programme ne la trouve pas et demande qu'elle soit déclarée de façon explicite, avec un message d'erreur du type :

```
Global symbol "@age" requires explicit package name at
../.. /Outils/OutilsDroits.pm line 561.
```

L'instruction `my` qui clôt cet en-tête sert à la fois à déclarer les variables additionnelles du type décrit en III.1.9, mais aussi les variables scalaires de boucle (indices `$i` et `$t`) et une variable `$resultats` qui servira à repérer le fichier Excel dans lequel seront sauvegardés les résultats, et dont la signification sera précisée plus loin en IV.4.

### IV.1.2 Sélectionner les fichiers issus du générateur de biographies : la fonction UseBios

La fonction `UseBios` sert ensuite à définir les fichiers en entrée du bloc retraite comprenant les données issues du générateur de biographies et à donner quelques informations sur ces fichiers.

```
UseBios("Repertoire Bios", 2003, 1/9246);
```

Le premier argument est le nom du sous-répertoire du répertoire Bios sur lequel le programme doit aller lire les fichiers `BioEmp.txt` et `BioFam.txt`. Le deuxième argument indique à quelle année de départ se réfèrent ces fichiers. Dans la version actuelle du modèle, cette année de référence est l'année 2003, date de collecte de l'enquête patrimoine sur laquelle s'appuie le générateur de biographies. Le dernier paramètre est le taux de sondage de cet échantillon. Sur la base de ce taux de sondage, Destinie applique des coefficients de redressement à l'ensemble des programmes de tabulation assurant que les effectifs sortent systématiquement en milliers et les masses financières en milliards d'euros. Il est toujours possible de désactiver ces redressements, par exemple pour avoir des nombres d'individus effectivement présents dans l'échantillon, mais ceci oblige à faire appel à la fonction spécialisée `UseW` du module `OutilsTab` qui ne sera présentée qu'en partie VI.

On notera que ce n'est pas cette procédure `UseBios` qui procède à l'ouverture des fichiers. En effet, en cas de scénarios multiples, il faut procéder à autant de réouvertures initiales qu'il y a de scénarios différents. Ceci est donc plutôt fait lorsque la procédure `Relec` est appelée sur l'année initiale de projection, à l'intérieur de la ou des boucles temporelles. On renvoie à la section suivante pour la présentation de la procédure `Relec` et de son fonctionnement.

### IV.1.3 Déclarer les options générales de la simulation : la fonction UseOpt

La fonction `UseOpt` sert ensuite à définir les options de la simulation.

```
UseOpt("TP");
```

Dans l'exemple ci-dessus, une seule option est présente : le type de comportement de départ à la retraite. `TP` indique que les personnes partent à la retraite lorsqu'elles atteignent le taux plein. Mais `UseOpt` sert aussi à préciser la liste de droits pris en compte dans la simulation et, le cas échéant, à lancer une transition vers un système en comptes notionnels.

L'ensemble des options disponibles sont les suivantes :

- **Pour le comportement de liquidation** (options exclusives les unes des autres)

- `Exo`: départ à un âge exogène

- `Pmin`: départ dès qu'un certain niveau de pension minimal est atteint
TP : départ au taux plein

UInst : départ si l'utilité instantanée à être en retraite dépasse l'utilité sans changement de statut

UAct : départ à l'âge qui maximise l'utilité actualisée sur le restant de l'existence (modèle de comportement de type Stock et Wise)

SSW : départ à l'âge qui maximise la masse des pensions actualisées sur l'ensemble de la durée de la retraite

Accrual : départ dès que le report d'un an de la liquidation fait baisser la masse des pensions actualisées sur l'ensemble de la durée de la retraite

- Pour le calcul des droits (options non exclusives)

NoMC : neutralisation du minimum contributif

NoMDA : neutralisation de la MDA

NoBonif : neutralisation de la bonif pour 3 enfants et plus

NoAVPF : neutralisation de l'AVPF

CarTot : prise en compte de l'ensemble de la carrière pour le calcul du SR fonction publique

NoAssimil : exclusion des années de préretraite et de chômage dans les durées validées

- Pour les comptes notionnels

CN : passage à une simulation en comptes notionnels

Pour cette dernière option, une deuxième instruction `UseOptCN` est utilisée pour préciser les caractéristiques de ce système en comptes notionnels. Cette fonction est décrite plus loin en VI.5.1.

L'ensemble des options demandées sont passées à `UseOpt` dans une chaîne de caractère unique dont la syntaxe est très libre : les options peuvent être indiquées dans un ordre quelconque, en majuscule ou minuscule, éventuellement au milieu d'autres caractères (par exemple au sein d'un nom de scénario en clair). Les appels suivants sont donc équivalents :

UseOpt ("TP NoMDA");
UseOpt ("tp nomda");
UseOpt ("Scenario 1 : TP/NoMda");

La fonction `UseOpt` a par ailleurs un second argument optionnel qu'il faut ajouter lorsqu'on a demandé les options `"Exo"` ou `"pmin"`. Dans ces deux cas, il faut définir le tableau qui fournit l'âge cible de départ pour chaque individu ou le niveau minimum de pension à partir duquel il décide de liquider. En général, ces informations sont des informations sauvegardées d'une simulation précédente du même programme puisque l'idée est soit de simuler une variante à âge de départ inchangé, soit une variante à niveau de retraite inchangé. Si on suppose par exemple que ce sont des tableaux `@ageref` ou `@pens_cible` qui ont servi à garder ces informations, on aura des appels de la forme :

UseOpt ("Exo", @ageref);

ou :

UseOpt ("pmin", @pens_cible);

Ces cas seront examinés plus en détail dans le paragraphe III.4 qui analyse des cas de programmation plus complexes. Mais le tableau `@ageref` pourrait aussi être n'importe quel autre tableau construit directement par l'utilisateur, par exemple un tableau fixant l'âge de 60 ans pour tout le monde.
## IV.2 Les boucles : version élémentaire

### IV.2.1 Vue d'ensemble

La double boucle emboîtée sur la date et la population simulée constitue le cœur de la simulation. L'encadré ci-dessous rappelle comment se présentait cette double boucle dans l'exemple de la figure 2.

```perl
# Boucle temporelle
for $t (103..150)
{
    # Simulation
    Pointage("Simulation année ".$t);
    for $i (1..IMax)
    {
        UseLegRetroMax (2003);
        UseLeg($t, $anaiss[$i]);
        SimDir($i);
    }
}; # Fin boucle temporelle
```

La boucle temporelle est la boucle `for $t (103..150)`. Elle va de 2003 à 2050, mais l'indication tient compte de ce que, pour économiser la place, les tableaux de paramètres prennent l'année 1900 comme année d'origine. Ce principe est adopté dans l'ensemble du modèle, même si on verra plus loin que beaucoup de procédures acceptent qu'on leur passe des millésimes complets.

La fonction `pointage` ne joue pas de rôle dans la simulation. Elle sert seulement à suivre son avancement. Dans l'exemple ci-dessus, elle affichera un message à chaque année de simulation, en précisant l'heure à laquelle le programme a démarré sa simulation.

À l'intérieur de la boucle temporelle, la première opération consiste à récupérer les données nécessaires dans les fichiers issues du générateur de biographie. Ceci se fait par appel de la fonction `Relec` de la bibliothèque `OutilsRetr`, dont le seul argument est la date `$t`. Cette relecture est donc faite en dehors de la boucle individuelle. C'est la procédure `Relec` elle-même qui gère le balayage de l'ensemble de la population.

Une fois effectuée cette relecture, la fonction principale du programme est de simuler les départs en retraite. C'est cette opération qui est effectuée à l'intérieur d'une boucle individuelle `for $i (1..IMax) où IMax est en fait une fonction de la bibliothèque OutilsBase qui indique le nombre total d'individus connus de Destinie. Cette simulation des liquidations fait intervenir trois fonctions :`

- la fonction `UseLegRetroMax` qui indique le choix de la législation pour les reconstitutions initiales,

- la fonction `UseLeg` qui précise le choix de la législation en projection,

- la fonction `SimDir` qui lance la simulation des pensions de droits directs.

La dernière accolade ferme la boucle temporelle.

On va maintenant examiner plus en détail chacune des procédures appelées dans cette double boucle.
IV.2.2 Relire les biographies individuelles : la fonction Relec

La fonction Relec sert à relire les contenus des fichiers BioEmp et BioFam. Elle est lancée
dans le programme principal dans la boucle temporelle, au début de chaque année de la
simulation. Son seul argument est la date, sous forme millésimée ou modulo 1900. On peut
donc avoir des appels de la forme:

Relec($t);
Relec(103);
Relec(2003);

Pour préciser à quoi a accès le programme après appel de cette procédure, il est nécessaire de donner quelques indications sur le contenu des deux fichiers auxquels elle accède.

Ce fichier BioEmp comprend trois lignes par individu. La première ligne comprend des informations qui sont indépendantes de l'âge :

- l'identifiant de l'individu

- le sexe

- l'année de naissance (en 4 chiffres)

- l'âge de fin d'études

- le taux de prime (en l'état, Destinie applique le même taux de prime sur l'ensemble de la carrière)

Les deux lignes suivantes donnent respectivement les séquences de statuts d'emploi et de
salaires nominaux successifs entre l'âge de 15 ans et le décès. Le séparateur utilisé est le
point-virgule.

Ce fichier BioEmp est lu en une seule fois dès la première année de simulation. Cela signifie
que, dès le début de la simulation, on connait l'ensemble des carrières non seulement
rétrospectives mais aussi prospectives de l'ensemble des individus, y compris d'ailleurs pour
des individus qui ne sont pas encore actifs car devant naître (ou migrer) ultérieurement :
autrement dit, à chaque date, il y a une vision d'ensemble des variables $statut_[$i] [$a]
et $salaire_[$i] [$a] pour l'ensemble des individus simulés qu'ils soient déjà présents ou
non dans l'échantillon à la date initiale.

En utilisation normale, ces carrières ne sont modifiées par le programme appelant qu'au
moment du départ en retraite : lorsqu'on simule un départ en retraite, tous les statuts des
années ultérieures sont mis d'office à la valeur $CodeIna et les salaires sont mis à zéro. Ceci
sera fait automatiquement par la fonction SimDir. Mais il est aussi possible d'introduire
d'autres modifications sur ces profils de carrière à d'autres stades du programme. Un exemple
en sera donné plus loin à la section IV.3.4.

La structure du fichier BioFam est un peu plus complexe. Pour chaque année de simulation, il
contient une ligne pour chaque individu connaissant un changement de situation familiale. Les
informations, toujours séparées par un point-virgule sont :

- l'identifiant de l'individu

- celui de son père

- celui de sa mère

- sa situation matrimoniale

- l'identifiant du conjoint

- les identifiants des enfants (au maximum 6)

Pour la première année, aucune de ces informations n'est connue ex ante, il y a donc une ligne
par individu de la base. Pour les années suivantes, seuls les individus qui connaissent un
changement sont renseignés. Le nombre d'enregistrements est donc variable d'une année de
projection à l'autre. Pour marquer la séparation entre les années, le fichier comprend donc des
lignes additionnelles marquant le passage à l'année suivante. À la jonction entre deux années,
on a donc un contenu du type :
7930;517;6299;1;%;%;%;
7931;736;6314;1;%;%;%;
7932;528;7160;1;%;%;%;
*** Fin année 2018
31;28;29;4;%;%;%;
32;28;29;2;3189;%;%;%
78;76;77;2;5266;%;%;%
96;-1338;1339;3;-97;98;99;100;%;

Dans cet exemple, le dernier individu connaissant un changement de situation en 2018 est l'individu 7932. Il s'agit en fait d'une naissance. Cet individu a pour parents les individus 528 et 7160, son statut matrimonial de départ est le statut de célibataire, avec une valeur qui est donc manquante pour l'identifiant du conjoint et une ancienneté de zéro année dans ce statut et il n'a aucun enfant.

Pour l'année 2019, les deux individus 31 et 32 qui ont les mêmes parents 28 et 29 connaissent respectivement une séparation et une mise en couple, dans le deuxième cas avec la personne d'identifiant 3189. La quatrième personne connaissant un événement démographique pour cette année 2019 est l'individu 96. Il n'a plus son conjoint (statut matrimonial à 3 et identifiant du conjoint négatif -97), et perd son père (identifiant -1338) mais a encore sa mère (1339). Conserver les identifiants des personnes liées à un individu donné après leur décès permet de conserver l'information sur les liens familiaux qui passaient par cette personne. Pour ce qui concerne l'individu décédé, il cesse d'être considéré comme présent dans la population : c'est le programme Relec qui se charge de mettre à zéro l'indicatrice $present[$i]. Ceci évite notamment que l'individu soit pris en compte dans les comptages relatifs à l'année courante.

En année courante, Relec se charge aussi de mettre à jour l'âge, les variables de statut et de salaire courant $statut[$i] et $salaire[$i] et les indicatrices permettant de savoir si l'individu est décédé au cours de l'année ou s'il est un migrant de l'année ($deces[$i] et $migrant[$i]). Elle remet par ailleurs à zéro l'indicatrice $liq[$i] de liquidation l'année courante : celle-ci sera recalculée juste après, pour les nouveaux liquidants, par la fonction SimDir.

### IV.2.3 Choisir la législation : UseLeg et UseLegRetroMax

Comme déjà indiqué en III.3.6, la fonction UseLeg sert à initialiser les valeurs des paramètres législatifs que DefVarRetr ne lit pas directement sous forme de séries temporelles dans ParamSociaux.xls. Comme les paramètres de calcul de la retraite dépendront en général de l'individu, à année donnée, elle doit être appelée à l'intérieur de la boucle individuelle de calcul des pensions

La fonction UseLeg fixe les valeurs de ces différents paramètres en fonction de l'année et de la génération. Par exemple :

UseLeg($t, $anaiss[$i]);

signifie que, jusqu'au prochain appel de UseLeg, on va utiliser les paramètres que prévoyait la législation de l'année $t pour les individus nés en $anaiss[$i].

Cette fonction permet de simuler d'autres règles de calcul des droits que celles s'appliquant ou devant effectivement s'appliquer à l'individu $i.

UseLeg(1992, $anaiss[$i]);
UseLeg(1992, 1942);

mettent en œuvre le barème que prévoyait la législation de 1992 pour les individus nés en $anaiss[$i] ou pour la génération 1942. Si ceci ne suffit pas à décrire le scénario souhaité, il est toujours possible de modifier à la main un ou plusieurs paramètres après ces appels de UseLeg, comme on a vu pouvoir le faire pour les paramètres lus dans ParamSociaux.xls.
On notera que, dans ces appels, on utilise le millésime complet. En fait, pour pouvoir utiliser les mêmes compteurs de date que ceux qui indicent les séries temporelles le programme accepte aussi les dates ramenées à l'origine 1900, i.e. on aurait pu écrire :

UseLeg(103, $anaiss[$i]);

C'est ce qui était implicitement fait dans le premier exemple d'appel si $t était une variable de boucle comprise entre 103 et 150.

La fonction UseLegRetroMax est le pendant de UseLeg pour les reconstitutions rétrospectives de droits directs. La raison d'être de cette fonction est que le nouveau modèle Destinie 2 ne se contente pas de projeter les retraites. Il les réimpute également pour les personnes déjà retraitées dans l'échantillon initial. La raison principale de ce choix a été d'assurer une meilleure continuité des trajectoires en début de projection. En effet, chaîner des pensions calculées et des pensions initiales observées crée fatalement une discontinuité initiale, sauf à avoir un module parfait et exhaustif de calcul des droits et des droits courants également parfaitement mesurés. Aucune de ces deux conditions ne peut être parfaitement remplie et Destinie 2 résout le problème en imputant les pensions des retraités actuels à l'aide des mêmes modules de calcul que ceux utilisés en projection. Ceci assure une projection à « biais constant », qu'on a considéré préférable à une projection à biais variable.

Il s'est avéré que cette façon de procéder avait un deuxième avantage : dès lors que les pensions initiales sont réimputées, il est possible de le faire sur d'autres bases que la législation effective pour construire des scénarios « contrefactuels ». Un scénario contrefactuel consiste par exemple à calculer ce que seraient aujourd'hui les retraites et comment elles seraient destinées à évoluer si on en était resté à la législation de 1992.

Pour que ce type de calcul soit possible, il faut évidemment que l'utilisateur puisse choisir la législation à appliquer à ces imputations rétrospectives. C'est ce à quoi sert la fonction UseLegRetroMax. Elle a un argument unique qui fixe la date à laquelle on choisit de bloquer rétrospectivement la législation. Ainsi :

UseLegRetroMax(1992);

simulera les conditions initiales qui auraient résulté d'un maintien de la législation de 1992.

Une imputation des pensions initiales selon les règles effectives sera obtenue en demandant :

UseLegRetroMax(2003);

Comme pour UseLeg, ces appels ne fixent que les paramètres de calcul non lus dans ParamSociaux.xls. Les paramètres que DefVarRetr lit dans ParamSociaux.xls peuvent faire l'objet de modifications rétrospectives directes, dans une boucle temporelle spécifique en amont de la boucle temporelle principale.

Par exemple (cas d'école) :

for $t (70..150)
{
    $plafondSS[$t]=$plafondSS[70] ;
}

conduit à simuler l'évolution rétrospective et prospective du système de retraite dans l'hypothèse où le plafond aurait cessé d'évoluer depuis 1970.
### IV.2.4 Simuler la liquidation : la fonction SimDir

Cette fonction est la fonction principale de Destinie 2. Elle initialise ou actualise les droits directs. Ce programme est appelé à l'intérieur de la boucle sur données individuelles. L'argument unique est l'identifiant de l'individu.

Les autres options de comportement ont été définies par `UseOpt`, s'il y a lieu. La législation mise en œuvre est celle définie par le dernier appel de `UseLeg` ou de `UseLegRetroMax`.

Cette fonction fait appel à d'autres fonctions créées dans d'autres sous-programmes que `OutilsRetr` (`TestLiq`, `Liq` et `Revalo`). Ces fonctions ne seront pas détaillées dans cette partie. Elles n'ont besoin d'être connues que pour une utilisation avancée du modèle et leur articulation exacte sera précisée plus loin en section VI.5.2.

À ce stade, il est surtout important de comprendre comment la fonction `SimDir` procède.

La fonction `SimDir` ne concerne que les individus en vie de plus de 54 ans. Si c'est le cas, la fonction `SimDir` distingue deux situations :

Si on est à l'année initiale de la projection (en général 2003), il s'agit dans ce cas de réimputer l'ensemble des pensions initiales, pour tout le stock d'individus en âge d'être retraité. La fonction `SimDir` calcule l'année de liquidation et le montant des pensions éventuelles. Elle remonte à l'année où l'individu a eu 55 ans et lance la fonction `TestLiq` qui teste si les conditions pour la liquidation sont remplies. Si c'est le cas, elle lance la fonction `Liq` qui calcule le montant des pensions. Si ce n'est pas le cas, elle reteste le fait qu'il y ait eu liquidation ou non pour tous les âges jusqu'au minimum de l'âge courant et de l'âge de 65 ans. Une fois l'année de liquidation déterminée les pensions des années suivantes (jusqu'à l'année de départ de la simulation) sont revalorisées à l'aide de la fonction `Revalo`.

- S'il s'agit d'une année postérieure à l'année de départ, il s'agit soit de revaloriser les pensions en cours, soit de simuler les nouvelles liquidations. Si l'individu n'est pas retraité, `SimDir` teste s'il s'agit de l'année de liquidation (`TestLiq`) et si c'est le cas affecte le montant des pensions (`Liq`). Si l'individu est déjà retraité `SimDir` revalorise les pensions avec `Revalo`.

Exemples d'appel combiné avec `UseLeg`, dans une double boucle sur `$t` et `$i` :

```
UseLegRetroMax(2003);
UseLeg ($t, $anaiss[$i]);
SimDir($i);
```

initialise ou projette les droits en $t avec les conditions réelles

```
UseLegRetroMax(1992);
UseLeg (1992, $anaiss[$i]);
SimDir($i);
```

initialise ou projette les droits en $t avec une législation bloquée à l'année 1992.

## IV.3 Les boucles : quelques cas plus complexes

### IV.3.1 Lancer plusieurs scénarios dans un seul programme

Très souvent, un programme ne sert pas à simuler un scénario unique mais plusieurs scénarios. Les deux boucles temporelle et individuelle sont donc emboitées dans une boucle balayant l'ensemble des scénarios qu'on veut examiner. Soit `$sc` la variable servant à identifier les scénarios. Il peut s'agit d'un simple numéro, mais il sera en général plus parlant d'utiliser une chaîne de caractère puisqu'il est possible d'effectuer des boucles indicées par des chaînes de caractères et on verra plus loin qu'on pourra ensuite en sauvegarder les résultats dans des
hachages eux-aussi indicés par les mêmes chaînes. On peut également choisir ces chaînes de sorte qu'elles puissent être directement passées comme arguments de `UseOpt`.

La démarche consiste donc à écrire, en début de programme (avant les boucles temporelles et avant les ouvertures de fichiers en sortie s'il y en a) une boucle du type :

```perl
for $sc ("TP", "Uact")
{
    UseOpt($sc);
    for $t (103..150)
    {
        Relec($t);
        for $i (1..Imax)
        {
            ...
        }
    }
}
```

La chaîne `$sc` peut se présenter de manière encore plus complexe. Par exemple, on peut labeller des scénarios sous la forme `$sc="TP/NoBonif-1992"` ou `"Uact/NoBonif-1992"` puis utiliser l'opérateur Perl `split` pour éclater `$sc` en deux variables `$option` et `$legislation` qui pourront ensuite être passées séparément à `UseOpt` et `UseLeg`, cette instruction `split` s'utilisant sous la forme :

```perl
($option, $legislation) = split /-/,$sc;
```

après quoi l'utilisateur pourra appeler successivement les deux fonctions `UseOpt ($option)` et `UseLeg ($legislation, $anaiss[$i])`.

### IV.3.2 Sauvegarder une variable micro pour d'autres scénarios

Lorsqu'on simule plusieurs scénarios, on peut vouloir conserver un résultat micro d'un des scénarios pour utilisation dans un autre scénario. Il y a deux cas principaux : le premier est-ce-lui où on veut procéder à des comparaisons des situations individuelles entre scénarios, le second est-ce-lui où on a besoin des résultats d'un scénario de référence pour paramétrer les hypothèses d'un scénario alternatif. On a vu que ce deuxième cas de figure se présente lorsqu'on utilise les options `exo` et `pmin` pour la simulation de l'âge de liquidation.

L'exemple qui suit présente la façon de procéder dans les deux cas. On suppose deux scénarios `"ref"` et `"var"` correspondant à deux législations. On suppose qu'on veut simuler le second avec exactement le même âge de liquidation que le premier et qu'on veut calculer les variations individuelles de niveau de pension à la liquidation entre les deux scénarios. Si on a prédéclaré les variables `@age_ref`, `@p_ref` et `@delta_p`, ceci pourra être assuré par la séquence suivante :

```perl
my ($sc, $i, $t, @age_ref, @p_ref, @delta_p);

for $sc ("ref", "var")
{
    if ($sc eq "ref")
    {
        UseOpt("TP")
    }
    else
    {
        UseOpt ("Exo", @age_ref)
    }
    for $t (103..150)
```
```perl
{
    Relec($t);
    for $i (1..IMax)
    {
        SimDir($i)
    }
    if ($liq[$i==1])
    {
        if ($sc eq "ref")
        {
            $p_ref[$i]=$pension[$i];
        }
        else
        {
            $delta_p[$i]=$pension[$i]-$p_ref[$i];
        }
    }
    if ($sc eq "ref")
    {
        @age_ref=@ageliq;
    }
}
```

Dans cet exemple, les variables micro `@p_ref` et `@delta_p` ne sont calculées que pour les personnes liquidant en cours de projection (sous condition sur la variable `@liq` générée par `SimDir`). En revanche, on note que la variable `@age_ref` est renseignée en fin de boucle, de manière globale, par simple copie de `@ageliq`. Ceci permet de récupérer l'âge de liquidation du scénario de référence non seulement pour les personnes liquidant en cours de projection mais aussi pour les gens dont on simule la liquidation rétrospective avant l'année 2003. On aurait aussi pu le faire à l'intérieur de la boucle sur `$i` et `$t`, mais sans tester sur la valeur de `$liq`.

### IV.3.3 Enchaîner plusieurs boucles individuelles : le cas des droits dérivés et du minimum vieillesse

Il est parfois nécessaire de faire plusieurs boucles sur les individus à l'intérieur d'une boucle temporelle. En effet, certaines fonctions sont dépendantes des calculs effectués sur l'ensemble des individus. En particulier, pour calculer les droits à la retraite dérivés (les pensions de réversion) il faut que la pension du conjoint de l'individu soit déjà connue. La fonction `SimDer` ne peut être mise en œuvre que si la fonction `SimDir` a déjà été appliquée à tous les individus. Le principe est identique pour le calcul du minimum vieillesse dont la perception dépend des revenus de l'individu et de ceux son conjoint. Dans la première boucle on calcule les revenus de tous et dans une deuxième on calcule le minimum vieillesse. On peut donc rajouter alors deux nouvelles boucles, après la boucle principale sur les individus :

```perl
for $i (1..IMax) {SimDer($i)};
for $i (1..IMax) {SimMinVieil($i)};
```

Comme cela a été signalé plus haut, ce mode de programmation permet de faire des simulations plus courtes dans le cas où l'on n'a pas besoin de tous les calculs de droits. Logiquement, le programme simple sans les fonctions `SimDer` et `SimMinVieil` prend moins de temps que si on y rajoute les deux fonctions. Cet avantage n'est pas négligeable surtout dès lors que l'on travaille sur les bases complètes (gros échantillons).

On va préciser le format de ces deux fonctions.
### La fonction SimDer

La fonction `SimDer` simule les pensions de reversions initiales ou projetées.

Pour l'initialisation, la réversion est imputée sur la base de la retraite d'un pseudo-conjoint désigné par le générateur de biographie, après quoi le lien avec ce pseudo-conjoint est effacé. Si le conjoint n'était pas encore retraité au moment de son décès, on calcule la pension qu'il aurait perçu à 60 ans pour évaluer la pension de réversion.

Ce n'est pas cette procédure qui effectue les revalorisations. Elles sont faites en même temps que pour les droits directs dans `SimDir`.

La fonction `Simder` a pour seul argument `$i`.

### La fonction SimMinViel

La fonction `SimMinViel` simule le minimum vieillesse pour les individus qui sont personnes de référence de leur ménage. Elle vérifie les conditions de ressources du ménage grâce à différentes fonctions de la bibliothèque `OutilsMen`.

Cette fonction a un seul argument : `$i`.

### IV.3.4 Modifier des données individuelles en amont de la simulation des retraites

Une manipulation moins fréquente mais qui peut être utile consiste à introduire des modifications dans les données relues dans le fichier `BioEmp` ou le fichier `BioFam`, autres que celles correspondant à la liquidation des retraites. Par exemple, la séquence suivante simule un choc de chômage pour l'année 2010 augmentant de deux points le risque de chômage des salariés du privé.

```perl
for $t (103..150)
{
    Relec($t);
    for $i (1..Imax)
    {
        if (($t==110) && (In($statut[$i], $CodeNC, $CodeCad))
            && (Booleen(0.02)))
        {
            $statut[$i][$age[$i]]=$CodeCho;
            $statut[$i] = $CodeCho;
        }
        SimDir($i);
    }
}
```

Cet exemple montre que l'organisation à deux étages séparant la simulation des retraites et le générateur de biographies n'oblige pas nécessairement à remonter à ce dernier pour des variantes d'activité, tant que celles-ci restent simples.

On notera que, dans cet exemple, il faut penser à modifier de façon cohérente les variables `$statut` et `$statut_`. On relèvera aussi l'utilisation des deux fonctions `In` et `Booleen` qui sont de fonctions de la bibliothèque généraliste `OutilsBase` qui sera présentée plus loin en VI.4

Si on utilisait le même principe pour simuler des chocs sur la situation familiale, il faudrait tenir compte de la façon dont `Relec` lit le fichier `BioFam`. Une modification une année donnée dans une des variables de `BioFam` sera préservée tant que `Relec` ne lira aucun changement dans `BioFam` pour l'individu `$i`, et sera annulée lorsque `Relec` rencontrera une ligne dans `BioFam`
relative à cet individu $i$. Il faut donc prévoir une façon de gérer ce problème, mais les variantes avec chocs sur la situation démographique et familiale sont *a priori* moins fréquentes. Les variantes démographiques, s'il y en a, auront plutôt intérêt à s'appuyer sur différents couples de fichiers `BioEmp` et `BioFam` résultant d'exécutions séparées du générateur de biographies.

### IV.3.5 Simuler des cas-types

L'approche par cas-types est un complément utile de la microsimulation. La nouvelle conception de Destinie permet d'utiliser sa boîte à outils sur d'autres carrières que celles générées par le générateur de biographies et ces carrières peuvent être des carrières de cas types totalement contrôlés par l'utilisateur. Dans ce cas, il n'y a pas d'appel ni à `UseBios` ni à `Relec`. On remplit les tableaux prédéfinis par `DefVarRetr` avec les caractéristiques des cas-types qu'on souhaite étudier. L'exemple ci-dessous montre par exemple comment construire trois cas types de non cadres à carrières complètes et ayant fait ces carrières à 0,5, une fois ou 1,5 fois le plafond de la sécurité sociale. On calcule leurs droits pour un départ à 60 ans en 2010.

```perl
my ($i, $a);

for $i (1..3)
{
    $anaiss[$i]=1950;
    $sexe[$i]=$CodeHom;
    for $a (20..60)
    {
        $statut[$i][$a] = $CodeNC;
        $salaire[$i][$a]=0.5*$i*$PlafondSS[$anaiss[$i]+$a-1900];
    }
    $age[$i]=60;
    $statut[$i] = $statut[$i][$age[$i]];
    $salaire[$i] = $salaire[$i][$age[$i]];
    UseLeg(2010, $anaiss[$i]);
    SimDir($i);
}
```

À partir de là, on peut afficher ce que l'on veut des caractéristiques de ces individus et on voit facilement comment le programme peut être complexifié pour analyser des cas-types plus nombreux et plus élaborés.

## IV.4 Création de résultats agrégés

### IV.4.1 Fonctions de tabulation génériques

Les résultats macro sont le plus souvent des résultats annuels. Ils ne dépendent donc pas de $i, mais de $t. Ils doivent donc être calculés dans la boucle temporelle, mais en dehors des boucles individuelles.

Dans l'exemple de la figure 2, ceci correspondait au bloc d'instructions :

```perl
$PENSION_MOYENNE[$t] = MVar(@pension, sub{$pension[$_] > 0});
$RATIO_FINANCIER[$t] = SVar(@pension)/Svar(@salaire);
$RATIO_DEMOGR[$t]    = Ratio(sub{$pension[$_] > 0}, sub{$salaire[$_] > 0});
```
situé juste avant la fin de la boucle temporelle.

Un tel segment de programme s'appuie sur des fonctions de tabulation instantanées proposées par la bibliothèque *OutilsTab*. En règle générale, ces fonctions ont pour argument la variable qu'il s'agit de tabuler, suivi d'un filtre passé sous forme d'une instruction Perl appliquée à l'individu d'indice générique `$_` et passée entre accolades après le mot clé `sub`. Cette syntaxe est détaillée complètement en VII.2.6. Pour les utilisations courantes il suffit de comprendre que le texte passé après le mot-clé `sub` est un mini-sous-programme que la fonction va évaluer dans une instruction `if` à l'intérieur de sa propre boucle de balayage de la population. Lorsqu'il s'agit de simples comptages, on ne passe que le filtre, ou deux filtres lorsqu'il s'agit de calculer des taux ou des ratios.

On va se limiter ici aux cas les plus usuels, une présentation complète de la bibliothèque étant faite en partie IV

## Fonction SVar

Cette fonction somme des valeurs d'une variable sous condition sur les valeurs d'une ou plusieurs autres variables.

### Exemples d'appel :

Masse salariale des individus du groupe 15-65 ans :

```perl
$MASSE_SAL = SVar(@salaire, sub { ($age[$_] >= 15) && ($age[$_] <= 65) });
```

ou

```perl
$MASSE_SAL = SVar(@salaire, sub { In($age[$_], (15..65)) });
```

Masse salariale de l'ensemble de la population :

```perl
$MASSE_SAL = SVar (@salaire);
```

Effectif de la population âgée de 15 à 64 ans

```perl
$POP15_64 = SVar (@pop, sub {In($_, (15..64))});
```

## Fonction Mvar

Cette procédure fonctionne selon le même principe que `SVar` mais calcule une moyenne. Pour alléger les affichages, le résultat est fourni avec une seule décimale.

### Exemples d'appel

Salaire moyen du groupe 15-65 ans. Comme précédemment, les deux formes d'écriture suivantes sont équivalentes :

```perl
$SAL_MOY = MVar(@salaire, sub { ($salaire[$_] > 0)
    && (($age[$_] >= 15) && ($age[$_] <= 65)) });
$SAL_MOY = MVar(@salaire, sub { ($salaire[$_] > 0)
    && (In($age[$_], (15..65))));
```

On notera que, dans cet exemple, on filtre sur les salaires positifs pour éviter d'inclure dans la moyenne les individus à salaire nul. Le même problème ne se posait pas pour la mise en œuvre de la fonction `SVar`.

## Fonction EVar

Cette fonction suit le même principe que `SVar` et `MVar` mais calcule un écart-type.
## Fonction Count

Cette fonction compte le nombre d'individus remplissant la condition passée en argument. Sans argument, elle retourne le nombre total d'individus présents à la date courante.

### Exemples d'appel

```perl
@POP      = Count;
@SALPOS   = Count (sub { ($age[$_] > 15) && ($salaire[$_] > 0)});
```

## Fonction Taux

Cette fonction calcule un taux, i.e. la proportion d'individus remplissant la première des conditions données en argument parmi les individus remplissant la seconde. S'il n'y a pas de deuxième condition, le taux est calculé par rapport à la population totale. Il est retourné directement en %, avec une seule décimale.

### Exemples d'appel

```perl
@TAUX_ACT{"20-40"} = Taux(sub {In($statut[$_], @CodesAct)},
                          sub {In($age[$_], (20..40))});
```

calculera la part des actifs (premier `sub`: `In($statut[$_], @CodesAct)` parmi la population des individus dont l'âge est compris entre 20 et 40 ans (deuxième `sub`: `In($age[$_], (20..40))`).

```perl
@TAUX_ACT_GLOB = Taux(sub {In($statut[$_], @CodesAct)});
```

calculera la part des actifs sur l'ensemble de la population.

## Fonction Ratio

Cette fonction calcule un ratio, i.e. le rapport entre les effectifs de deux populations. Le principe d'appel est le même que pour la fonction `Taux`, au fait près que la condition définissant la population du dénominateur n'est plus facultative et que les deux conditions sont utilisées de manière disjointe (dans la fonction `Taux`, le numérateur est la sous-population remplissant simultanément les deux conditions qui étaient passées en argument).

### Exemple d'appel :

```perl
@Ratio Dep = Ratio(sub {$age[$_] > 59},
                    sub {($age[$_] >= 20) && ($age[$_] < 60)});
```

calculera le rapport entre le nombre d'individus d'âge supérieur à 59 ans et le nombre d'individus entre 20 et 59 ans.

## IV.4.2 Un exemple

L'extrait ci-dessous présente d'autres exemples de mobilisation de ces fonctions pour des calculs d'agrégats.

```perl
# Comptages année courante
$MSAL[$t]   = SVar(@salaire);
if ($t==103) {$PIB[$t]=1800000}
else        {$PIB[$t]=$PIB[103]*$MSAL[$t]/$MSAL[103]};
$TOTDIR[$t] = SVar (@pension )/$PIB[$t];
$TOTDER[$t] = SVar (@rev     )/$PIB[$t];
$MOYDIR[$t] = MVar (@pension, sub {$pension[$_] > 0})/$Prix[$t];
```
$MOYDER[$t] = MVar (@rev , sub{$rev[$_]>0 })/$Prix[$t];
$NBDIR[$t] = Count (sub{$pension[$_]>0 });
$NBDER[$t] = Count (sub{$rev[$_]>0 });

Cet exemple sert à calculer des sommes de pensions par rapport au PIB, des pensions moyennes et des nombres de retraités, en distinguant les pensions de droit direct et les pensions de réversion.

On calcule d'abord une masse salariale $MSAL[$t] par SVar. C'est sur la base de cette
masse salariale qu'on calcule une évaluation de PIB à chaque date, sous l'hypothèse d'une
constance du rapport salaires/PIB à compter de 2003. Ceci suppose bien sûr que l'agrégat
@PIB ait été déclaré dans le programme.

On notera que aussi bien @MSAL que @PIB sont ici des grandeurs nominales, ce qui ne pose
pas de problème pour le calcul des variables $TOTDIR et $TOTDER qui sont des ratios. En
revanche, les pensions moyennes $MOYDIR et $MOYDER calculées par MVar sont divisées par
l'indice des prix $Prix[$t] pour apparaître en valeurs réelles. Cette correction joue surtout
sur les premières années : le démarrage de la projection se fait en effet avec les valeurs
effectives des paramètres de gestion des retraites enregistrées jusqu'à la date courante, par
exemple les valeurs du point ou les taux de revalorisation effectivement appliqués jusqu'en
2009. Au-delà, Destinie fige la variable $Prix[$t] et cesse de distinguer évolutions réelles et
nominales. Mais la correction par les prix est nécessaire au moins au titre des premières
années.

La fonction Count sert enfin à calculer les effectifs de bénéficiaires de droits directs et de droits dérivés.

Si on voulait différencier ces variables par sexe, on peut avoir la séquence suivante, moyennant
déclaration préalable des deux hachages de tableaux %MOYDIRS et %MOYDERF :

for $s ($CodeHom, $CodeFem)
{
    $buf=$Label{"sexe"}$[$s];
    $MOYDIRS{$buf}$[$t]=MVar(@pension,
        sub{($pension[$_]>0)&& ($sexe[$_] eq $s)});
    $MOYDERS{$buf}$[$t]=MVar(@pension,
        sub{($rev[$_]>0) && ($sexe[$_] eq $s)});
}

Ces deux hachages sont ensuite sauvegardables directement dans des feuilles Excel par une
procédure SavHS qui sera vue dès la section suivante.

De la même façon, si on était à l'intérieur d'une boucle sur plusieurs scénarios indicés par la
variable $sc, on pourrait avoir des tabulations sauvegardant dans des hachages de séries
temporelles indicés par le nom du scénario.

IV.4.3 Fonctions de tabulation directe des salaires et des retraites

Les tabulations de masses ou de moyennes de salaires et de retraites sont celles qui
reviennent le plus souvent. Or la syntaxe de ces tabulations peut être assez lourde lorsqu'on
veut obtenir ces valeurs pour des sous-populations spécifiques et/ou, dans le cas des pensions,
pour des composantes particulières de la pension. Pour simplifier ces calculs, Destinie 2
propose quatre fonctions de raccourcis : les fonctions SSal, Msal, SPens et MPens.

Procédure SSal

Cette fonction retourne une masse salariale. Le premier argument optionnel est une chaîne de
caractères incluant le champ ("pri", "in", "fp") et/ou du sexe ("hom" ou "fem"). Le
second argument, également optionnel, est une condition additionnelle passée sous la même
forme que pour les autres procédures de tabulation.

Exemples

$MSAL[$t]=SSal;
$MSAL[$t]=SSal("pri/fem");
$MSAL[$t]=SSal(sub{$age[$_]>40});
$MSAL[$t]=SSal("fp/hom",sub{$age[$_]>40});

Procédure MSal

Cette fonction retourne un salaire moyen avec les mêmes règles d'appel que pour SSal. La tabulation ne prendra en compte que les individus du champ pour qui le salaire est positif.

Exemples

$MSAL[$t]=MSal;
$MSAL[$t]=MSal("pri/fem");
$MSAL[$t]=MSal(sub{$age[$_]>40});
$MSAL[$t]=MSal("fp/hom",sub{$age[$_]>40});

Procédure SPens

Cette fonction retourne une masse de pensions. Le premier argument optionnel est une chaîne de caractère incluant la définition du régime ("rg", "ar", "ag", "in" ou "fp") et/ou du sexe ("hom" ou "fem"). Par défaut, la pension calculée est la pension totale pour les deux sexes. Le second argument, également optionnel, est une condition additionnelle passée sous la même forme que pour les autres procédures de tabulation.

Exemples d'appel :

$PTOT[$t]=SPens;
$PTOT[$t]=SPens("rg/fem");
$PTOT[$t]=SPens(sub{$liq[$_==1]});
$PTOT[$t]=SPens("rg/hom",sub{$liq[$_==1]});

Procedure MPens

Cette fonction retourne une pension moyenne, avec les mêmes types d'arguments que pour la fonction SPens.

Exemples d'appel :

$PMOY[$t]=MPens;
$PMOY[$t]=MPens("rg/fem");
$PMOY[$t]=MPens(sub{$liq[$_==1]});
$PMOY[$t]=MPens("rg/hom",sub{$liq[$_==1]});

IV.5 Sauvegarde des résultats macros dans des fichiers Excel

Pour exporter les résultats des fonctions de tabulation, l'utilisateur dispose des fonctions de la
la bibliothèque OutilsExcel.pm. Cette bibliothèque lit ou écrit différents formats de tableaux
dans des fichiers Excel. Ses programmes s'appellent en toute fin de programme. Dans
l'exemple introductif, ceci correspondait aux lignes de code :

$resultats = ClassOut("Exemple.xls");
SavSer($resultats, "Resultats", "Principaux agregats",
       "Pension moyenne ", @PENSION_MOYENNE,
```perl
"Ratio financier ",@RATIO_FIN,
"Ratio démographique",@RATIO_DEM);
CloseOut($resultats);
```

L'autre exemple suivant, un peu plus riche, combine sorties de résultats se présentant sous formes de séries temporelles ou sous forme de profils par âge :

```perl
$resultats = ClassOut("TestCentral.xls");

# sauvegarde de séries temporelles
SavSer($resultats,"Totaux","Masses de pensions (en % du PIB)",
       "Ensemble des droits directs ",@TOTDIR,
       "Ensemble des droits dérivés ",@TOTDER);
SavSer($resultats,"Moyennes","Pensions annuelles moyennes (en euros)",
       "Ensemble des droits directs ",@MOYDIR,
       "Ensemble des droits dérivés ",@MOYDER);
SavSer($resultats,"Effectifs","Effectifs de bénéficiaires",
       "Ensemble des droits directs ",@NBDIR,
       "Ensemble des droits dérivés ",@NBDER);

# sauvegarde de séries par génération
SavSer($resultats,"MoyLiq","Pensions moyennes des liquidants",
       "Nbre liquidants ",@NBLIQ_G,
       "Pension de droits directs ",@PENSLIQ_G);

# sauvegarde de séries par âge
SavPro($resultats,"Pension_A","Données par age en 2003 et 2008",
       "Population ",@POP_2003,
       "Taux d'actifs occupés ",@TXOCC_2003,
       "Pension RG en 2003 ",@MOYRG_2003);

CloseOut($resultats);
```

Mais la bibliothèque permet aussi l'écriture de tableaux plus complexes : tableaux par âge et période, hachages de séries temporelles, séries temporelles de hachages, hachages de hachages... On va se borner ici à présenter les plus usuelles des procédures de cette bibliothèque, le reste des procédures disponibles étant présenté en section VI.7.

## Fonction ClassOut

Cette fonction ouvre un nouveau classeur en écriture.

### Exemple d'appel

```perl
$resul= ClassOut("resultats.xls");
```

On crée ici une variable $resul que l'on indiquera lorsque l'on utilisera les fonctions d'écriture des résultats. Ce fichier s'appelle dans cet exemple `resultats.xls`. Il est créé automatiquement dans le répertoire où se trouve le programme principal.

Attention, il y a toujours création d'un nouveau fichier (la bibliothèque ne gère pas la réécriture dans un fichier existant).
## Fonction CloseOut

Cette fonction ferme un classeur ouvert en écriture.

### Exemple d'appel

```pascal
CloseOut($resul);
```

## Fonction SavSer

La fonction SavSer sauvegarde un ensemble de séries par années ou par génération dans une feuille Excel. Les trois premiers arguments sont le nom du classeur (du fichier Excel), le nom de la feuille et le titre de la feuille. Les arguments facultatifs sont répétés autant de fois qu'il y a de variables de calculs à insérer dans la feuille : le titre de la colonne et le nom de la variable contenant le résultat du calcul.

### Exemple d'appel

```pascal
SavSer($resul, "Feuil2", "Titre",
       "Poptot", @poptot,
       "Pib", @pib,
       "Salaires", @sal);
```

Dans cet exemple on sauvegarde, dans le fichier défini par la variable $resul, dans la feuille intitulée Feuil2, un tableau dont le titre est titre :

- une colonne intitulée Poptot comprenant la série correspondant au tableau @poptot,

- une colonne intitulée Pib comprenant la série correspondant au tableau @pib,

- une colonne intitulée Salaires comprenant la série correspondant au tableau @sal.

Le résultat se présentera sous la forme suivante

<table><thead><tr><th></th><th>A</th><th>B</th><th>C</th><th>D</th><th>E</th><th>F</th><th>G</th></tr></thead><tbody><tr><td>1</td><td>Titre</td><td></td><td></td><td></td><td></td><td></td><td></td></tr><tr><td>2</td><td></td><td>Poptot</td><td>Pib</td><td>Salaires</td><td></td><td></td><td></td></tr><tr><td>3</td><td>2003</td><td>..</td><td>..</td><td>..</td><td></td><td></td><td></td></tr><tr><td>4</td><td>2004</td><td>..</td><td>..</td><td>..</td><td></td><td></td><td></td></tr><tr><td>5</td><td>2005</td><td>..</td><td>..</td><td>..</td><td></td><td></td><td></td></tr></tbody></table>

## Fonction SavPro

Cette fonction sauvegarde un ensemble de profils par âge dans une feuille Excel. On obtient un fichier Excel contenant dans chaque colonne un âge et chaque ligne une variable.

### Exemple d'appel

```pascal
SavPro($resul, "Feuil2", "Titre",
       "Nombre", @prod,
       "Salaire", @sal);
```

Le résultat se présentant cette fois sous la forme suivante, avec les séries en ligne plutôt qu'en colonne :

<table><thead><tr><th></th><th>A</th><th>B</th><th>C</th><th>D</th><th>E</th><th>F</th><th>G</th></tr></thead><tbody><tr><td>1</td><td>Titre</td><td></td><td></td><td></td><td></td><td></td><td></td></tr><tr><td>2</td><td></td><td>0</td><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr><tr><td>3</td><td>Nombre</td><td>..</td><td>..</td><td>..</td><td>..</td><td>..</td><td>..</td></tr><tr><td>4</td><td>Salaire</td><td>..</td><td>..</td><td>..</td><td>..</td><td>..</td><td>..</td></tr></tbody></table>
## Fonction SavHS

Cette fonction est celle qui permet de sauvegarder directement les hachages de séries temporelles dont on a vu des exemples en section IV.4.2. Par exemple si, dans une boucle sur `$sc`, on a généré le hachage `%pop` d'élément générique `$pop{$sc}[$t]`, on pourra sauvegarder d'un bloc ce hachage par l'instruction :

```
SavHS($resul, "Popul", "Population, selon scenarios", %pop);
```

Le tableau contient autant de colonnes que de scénarios simulés.

<table><thead><tr><th></th><th>A</th><th>B</th><th>C</th><th>D</th><th>E</th><th>F</th><th>G</th></tr></thead><tbody><tr><td>1</td><td colspan="7">Population, selon scénarios</td></tr><tr><td>2</td><td></td><td>Scénario 1</td><td>Scénario 2</td><td>Scénario 3</td><td></td><td></td><td></td></tr><tr><td>3</td><td>2003</td><td>..</td><td>..</td><td>..</td><td></td><td></td><td></td></tr><tr><td>4</td><td>2004</td><td>..</td><td>..</td><td>..</td><td></td><td></td><td></td></tr><tr><td>5</td><td>2005</td><td>..</td><td>..</td><td>..</td><td></td><td></td><td></td></tr></tbody></table>

On l'utilise de la même façon pour sauvegarder des hachages donnant la même série temporelle pour diverses sous populations, par exemple, avec la variable `%MOYDIRS` proposée en section IV.4.2

```
SavHS($resul, "MOYDIRHF", "Pensions de droits directs ", %MOYDIRS);
```

qui donnera la feuille Excel :

<table><thead><tr><th></th><th>A</th><th>B</th><th>C</th><th>D</th><th>E</th><th>F</th><th>G</th></tr></thead><tbody><tr><td>1</td><td colspan="7">Pensions de droits directs</td></tr><tr><td>2</td><td></td><td>Hommes</td><td>Femmes</td><td></td><td></td><td></td><td></td></tr><tr><td>3</td><td>2003</td><td>..</td><td>..</td><td></td><td></td><td></td><td></td></tr><tr><td>4</td><td>2004</td><td>..</td><td>..</td><td>..</td><td></td><td></td><td></td></tr><tr><td>5</td><td>2005</td><td>..</td><td>..</td><td>..</td><td></td><td></td><td></td></tr></tbody></table>

## IV.6 Sauvegarde de résultats macros dans des fichiers texte

L'utilisateur de Destinie peut souhaiter sauvegarder ses résultats dans un fichier texte plutôt que dans un fichier Excel s'il considère que les fonctions de sauvegarde dans Excel sont trop limitées. Ceci suppose qu'il maîtrise les entrées-sorties sous Perl. On renvoie à des documentations plus complètes du langage pour une vue complète de ces entrées-sorties et on se borne à donner ci-après l'exemple d'un élément de programme donnant un tableau de résultats pour un nombre limité d'années.

```perl
open (SOR, ">compar.txt");
@dates=(106,115,120,130,140,150);
printf SOR "\nNombre de pensionnés\n";
for (@dates) { $ann=1900+$_; printf SOR "\t $ann"; };
printf SOR "\n CNAV"; for (@dates) {printf SOR "\t $NBRG[$_]"};
printf SOR "\n FP"; for (@dates) {printf SOR "\t $NBFP[$_]"};
printf SOR "\n ARRCO"; for (@dates) {printf SOR "\t $NBAR[$_]"};
printf SOR "\n AGIRC"; for (@dates) {printf SOR "\t $NBAG[$_]"};
printf SOR "\nPension moyenne\n";
for (@dates) { $ann=1900+$_; printf SOR "\t $ann"; };
printf SOR "\n CNAV"; for (@dates) {printf SOR "\t $MOYRG[$_]"};
printf SOR "\n FP"; for (@dates) {printf SOR "\t $MOYFP[$_]"};
printf SOR "\n ARRCO"; for (@dates) {printf SOR "\t $MOYAR[$_]"};
printf SOR "\n AGIRC"; for (@dates) {printf SOR "\t $MOYAG[$_]"};
```
Ce segment de programme utilise la fonction Perl `open` qui ouvre un fichier en lui associant ici le nom logique `SOR`. Contrairement aux autres variables, il n'a pas besoin d'être prédéclaré même sous la directive `use strict`. On note aussi le `>` avant le nom du fichier indiquant que celui-ci est ouvert en écriture.

L'autre fonction est la fonction `print` qui utilise par ailleurs les séquences d'échappement `\n` (saut de ligne) et `\t` (tabulation). On notera également la forme

```
print SOR "\t $MOYRG[$_]"
```

qui correspond à ce qu'on appelle une interpolation de variable dans une chaîne : la valeur `$MOYRG[$_]` est traduite en chaîne de caractère au sein de la chaîne entre doubles cotes. Une écriture également correcte aurait été :

```
print SOR "\t", $MOYRG[$_]
```

mais la première est plus légère lorsqu'on enchaine la sortie de plusieurs variables séparées par autant d'éléments de texte.

L'output de ce bloc de programme aura l'apparence suivante :

<table><thead><tr><th colspan="7">Nombre de pensionnés</th></tr><tr><th></th><th>2006</th><th>2015</th><th>2020</th><th>2030</th><th>2040</th><th>2050</th></tr></thead><tbody><tr><td>CNAV</td><td>9127</td><td>10828</td><td>12298</td><td>14693</td><td>16339</td><td>17736</td></tr><tr><td>FP</td><td>1812</td><td>2321</td><td>2608</td><td>3135</td><td>3662</td><td>4050</td></tr><tr><td>ARRCO</td><td>7934</td><td>10116</td><td>11808</td><td>14416</td><td>16099</td><td>17597</td></tr><tr><td>AGIRC</td><td>1794</td><td>2099</td><td>2164</td><td>2469</td><td>2728</td><td>3236</td></tr></tbody><thead><tr><th colspan="7">Pension moyenne</th></tr><tr><th></th><th>2006</th><th>2015</th><th>2020</th><th>2030</th><th>2040</th><th>2050</th></tr></thead><tbody><tr><td>CNAV</td><td>7923</td><td>7993</td><td>8139</td><td>8832</td><td>10137</td><td>11407</td></tr><tr><td>FP</td><td>23702</td><td>22217</td><td>22903</td><td>23203</td><td>27581</td><td>31904</td></tr><tr><td>ARRCO</td><td>3747</td><td>3438</td><td>3233</td><td>3112</td><td>3310</td><td>3590</td></tr><tr><td>AGIRC</td><td>10808</td><td>9928</td><td>9831</td><td>11514</td><td>13354</td><td>13681</td></tr></tbody></table>

Pour des mises en page encore plus travaillées, il existe également en Perl une instruction `printf` permettant des impressions formatées.
# V - Utilisations courantes (2) : inspecter les données individuelles

L'interprétation des résultats d'une simulation est parfois complexe et peut nécessiter l'examen de cas individuels spécifiques. Il arrive en effet que les barèmes produisent des résultats peu intuitifs pour certains types de profils individuels.

Pour examiner des résultats individu par individu, il existe deux possibilités. L'une consiste à prévoir des affichages ou des sauvegardes de résultats individuels en cours de simulation, à l'intérieur donc du programme .pl. L'autre consiste à recourir à un programme interactif, l'explorateur, qui permet de balayer le fichier BioEmp individu par individu et de tester différentes hypothèses de départ en retraite sur les individus qu'on examine. On va commencer par présenter le fonctionnement de cet explorateur (section V.1) puis on donnera quelques indications sur la façon d'afficher ou sauvegarder des résultats individuels depuis un programme .pl.

## V.1 L'explorateur

L'explorateur a été mis au point pour permettre un examen rapide et interactif des données individuelles. Il ne procède pas à une simulation complète, mais il lit et stocke en mémoire l'ensemble des carrières figurant dans un fichier BioEmp et la situation familiale initiale du fichier BioFam. Avec ces informations en mémoire, il est possible d'afficher toutes sortes de données individuelles à la demande, et de procéder à divers essais de simulation du départ en retraite à n'importe quel horizon, puisque BioEmp contient à la fois les carrières rétrospectives et prospectives, avec affichage de l'ensemble des résultats associés.

On peut aussi utiliser l'explorateur pour afficher n'importe quelle statistique relative à l'état initial de la population, en demandant l'impression à l'écran de résultats d'une quelconque des procédures de la bibliothèque OutilsTab. En fait, c'est l'intégralité des procédures des bibliothèques Destinie qui sont accessibles depuis l'explorateur, dès lors que leur application à un sens sur les données que cet explorateur stocke en mémoire et dès lors qu'elles ne mobilisent pas plus d'une ligne de code.

L'explorateur se lance en ouvrant le fichier Explore.pl du sous-répertoire Outils avec le compilateur Perl. Ceci déclenche l'ouverture d'une fenêtre MS-DOS à l'intérieur de laquelle se déroule l'ensemble des opérations qui suivent. La figure 6 l'exemple du début d'une session de l'explorateur.

La première demande de l'explorateur est de lui indiquer dans quel sous-répertoire de biographies se trouvent les fichiers BioEmp et BioFam à charger. Il donne pour ce faire la liste complète des sous-répertoires du répertoire Bios, et la sélection se fait par numéro. Une fois les contenus des deux fichiers chargés, l'explorateur informe du nombre d'individus lus dans chacun d'entre eux, dont le nombre d'individus effectivement présents dans la population à la date de départ. Le premier est supérieur au second puisque le fichier BioEmp.txt comprend également les débuts de trajectoires des individus dont la date de naissance est supérieure à cette date de départ.

Une fois ceci fait, l'explorateur émet des invites de commande auxquelles on répond en soumettant des textes de commandes Perl utilisant les différentes variables Destinie. Par exemple :

```perl
>>> print $age[$pere[27]]
```

qui affichera l'âge du père de l'individu 27, s'il est dans la population. On peut aussi bien écrire :

```perl
>>> $id=27;
```

```perl
>>> print $age[$pere[$id]]
```
<figure><img src="image_7.png" /><figcaption>Figure 7 : Exemple de mise en œuvre de l'explorateur</figcaption></figure>

**Lecture** : Dans cet exemple, l'explorateur affiche la biographie de l'individu n° 100, modifie les données professionnelles relatives à la 59ème année de cet individu, affiche la biographie modifiée et donne la pension qui en découle dans l'hypothèse d'un départ à 60 ans
Dans cet exemple, la variable `$id` n'a pas eu besoin d'être prédéclarée car l'explorateur fonctionne sans la directive `use strict` qui force la déclaration des variables. Pour la même raison, on pourra écrire une séquence :

```perl
>>> $effectif=Count;
>>> print "L'effectif initial est de ",$effectif
```

qui équivaudra à :

```perl
>>> print "L'effectif initial est de ", Count
```

On peut également entrer une suite de séquences générant des résultats, puis ouvrant un classeur Excel et stockant ces résultats dans ce classeur. Dès qu'on ferme ce classeur par `CloseOut`, il est récupérable sous Excel pour une analyse immédiate.

Mais l'usage principal de l'explorateur est l'affichage de profils individuels ou de détails du calcul des droits à retraite, qui se fait à l'aide des deux fonctions `ShowBio` et `ShowRet` qui sont des fonctions de la bibliothèque `OutilsRetr`, et donc également accessibles depuis un programme quelconque, mais qu'on présente dans cette section puisque c'est dans le cadre de l'explorateur que leur usage est le plus naturel.

## Fonction ShowBio

Cette fonction affiche la biographie professionnelle complète d'un individu. Les éléments affichés sont l'identifiant, le sexe et l'année de naissance, l'âge de fin d'études et le taux de prime (indépendant de l'âge) dans le cas où l'individu travaille dans le secteur public. Elle affiche ensuite un tableau complet de ses statuts (en clair) et salaires par âge.

La fonction a deux arguments d'appel. Le premier argument obligatoire est l'identifiant de l'individu. Le second, optionnel, définit le mode d'affichage des salaires. Ceux-ci peuvent être affichés en valeur nominale (option par défaut), en valeur réelle (option `"reel"`) ou en pourcentage de la valeur courante du plafond de la sécurité sociale à chaque âge (option `"%plaf"`).

## Fonction ShowPens

Cette fonction affiche la pension qu'aurait l'individu en liquidant à un âge donné et les différents éléments intermédiaires de son calcul. Les deux arguments obligatoires sont l'identifiant de l'individu et l'âge auquel on veut simuler la liquidation. Un troisième argument optionnel définit la législation à mettre en œuvre pour ce calcul de la pension. Par défaut, il s'agit de la législation en vigueur à l'âge de liquidation. Les deux autres options sont soit une autre date, soit la chaine vide `""` qui désactive tout choix de législation par ce programme `ShowPens` et permet donc de simuler l'incidence d'une législation sur mesure prédéfinie par des instructions précédentes.

Par exemple, supposons que l'individu 20 soit né en 1950. L'instruction

```perl
>>> ShowPens(20, 60)
```

donnera les différents éléments de la liquidation pour l'individu 20 s'il part, en 2010, à l'âge de 60 ans, avec la législation prévue à cette date pour les individus de cette génération.

L'instruction alternative

```perl
>>> ShowPens(20, 60, 1992)
```
donne les éléments de liquidation au même âge avec une législation bloquée aux règles prévues en 1992.

La séquence d'instructions

```
>>> UseLeg(1992,1950)
>>> $DureeCalcSam=15
>>> ShowPens(20,60,")
```

donnera enfin la retraite avec un départ selon la législation de 1992 mais une durée de calcul du SAM portée à 15 ans au lieu de 10.

L'utilisation de la fonction `ShowPens` appelle deux remarques supplémentaires :

- Cette fonction `ShowPens` ne travaille pas directement sur les données de l'individu passé en argument mais sur les données d'une copie de cet individu d'identifiant 0. Les données relatives à l'individu traité sont donc laissées inchangées, ce qui autorise des appels successifs avec différentes hypothèses d'âge ou de législation. Si on voulait simuler un départ effectif en retraite d'un individu sous l'explorateur, il faudrait recourir à la fonction `SimDir`, comme dans les programmes `.pl` vus jusqu'ici.

- Sauf désactivation préalable par `UseOpt`, cette fonction intègre les avantages familiaux, mais sur la base de la situation familiale observée au départ de la simulation, qui n'intègre donc pas les évolutions ultérieures de cette situation familiale. Cela suffit néanmoins à capter une part substantielle de ces droits familiaux. On peut aussi forcer des droits supplémentaires en manipulant les variables de liens familiaux de l'individu considéré même si ceci est à faire avec prudence.

## Autres fonctionnalités de l'explorateur

L'explorateur accepte la commande `help` qui, à ce stade, se borne à retourner la syntaxe des deux fonctions `ShowBio` et `ShowRet`.

À l'intérieur de la fenêtre ouverte par l'explorateur, on dispose des facilités de base d'une fenêtre MS-DOS, par exemple l'ascenseur, le rappel et la modification d'une commande antérieure à l'aide des curseurs `↑` et `←`, la fonction de recherche d'une zone de texte ou le copier-coller vers un autre fichier.

La sortie de l'explorateur se fait soit par fermeture de la fenêtre de travail soit par la commande `exit`.

## V.2 Sauvegarder des résultats individuels dans un fichier texte

L'autre façon d'accéder aux résultats individuels est de demander leur affichage ou leur impression dans un fichier à l'intérieur du programme de simulation. Supposons par exemple qu'on veuille se focaliser sur les individus avec des valeurs du taux de remplacement atypique. On peut insérer, après `SimDir`, un bloc du type :

```
If (($liq[$i==1] && (TauxRemp($i)>100))
{
    print join ("\t", $i, $anaiss[$i], $pension[$i], $sam, $duree_RG), "\n"
}
)
```

Dans cette instruction, on notera l'utilisation de la fonction `join` qui sert à concatenner un ensemble de valeurs dans une chaîne de caractères unique avec comme séparateur le premier argument d'appel.
Si le programme est lancé depuis l'environnement PerlIde, il y aura affichage dans sa fenêtre console d'une ligne pour chaque individu liquidant l'année en cours avec un taux de remplacement supérieur à l'unité. Les éléments affichés seront l'identifiant, l'année de naissance, la pension, le SAM et durée au régime général. On peut alternativement demander dans la même fenêtre l'affichage complet des biographies et éléments de pension de ces individus par un appel à ShowBio ou ShowPens, ou demander l'impression des mêmes éléments dans un fichier .txt ouvert avec l'instruction open décrite plus haut en IV.6.

On peut également procéder à des affichages individuels en fin de boucles, sur des variables individuelles permanentes. Par exemple, une variable micro telle que @pension peut avoir été déclinée en un hachage %pension contenant la valeur de la pension à la liquidation pour plusieurs scénarios, et on peut, en fin de programme, constituer un fichier donnant, sur la même ligne, les niveaux de pension des différents scénarios individu par individu, en même temps que d'autres descripteurs des caractéristiques individuelles, le tout pouvant être ensuite relu par d'autres instruments, tels que SAS, pour des analyses plus détaillées des caractéristiques des perdants ou gagnants aux différents types de réformes.

La séquence pour parvenir à ce type de résultats sera :

```perl
my ($sc, $i, $t, %pension);

for $sc ("ref", "var1", "var2")
{
    ...
    for $t (103..150)
    {
        Relec($t);
        for $i (1..Imax)
        {
            SimDir($i)
        }
        if ($liq[$i] == 1)
        {
            $pension{$sc}[$i] = $pension[$i]
        }
    }
}

open COMP, ">compar.txt";
for $i (1..IMax)
{
    print COMP join("\t", $i, $anaiss[$i], $sexe[$i], $findet[$i],
                 $pension{"ref"}[$i],
                 $pension{"var1"}[$i],
                 $pension{"var2"}[$i]), "\n";
}

close COMP;
```
# VI - Utilisations avancées (1) :
## présentation détaillée de l'ensemble des bibliothèques

Cette partie du document va maintenant détailler l'ensemble des fonctions disponibles dans la boite à outils Destinie 2. On va commencer par le contenu intégral de quatre bibliothèques qui n'ont pas encore été détaillées car non indispensables pour les utilisations les plus courantes, à savoir *OutilsDroits*, *OutilsComp*, *OutilsMen* et *OutilsBase*. Puis on examinera les éléments des bibliothèques *OutilsRetr*, *OutilsTab* et *OutilsExcel* qui n'ont pas été encore présentés dans les sections précédentes.

Cette partie permettra d'avoir une vue d'ensemble des instruments préfabriqués dont dispose l'utilisateur pour construire ses programmes .pl et/ou effectuer des calculs interactifs à l'intérieur de l'explorateur. En revanche, elle ne détaille pas la façon dont ces différents instruments sont eux-mêmes programmés. Pour quelques exemples de cette programmation, on renvoie à la partie VII.

### VI.1 La bibliothèque OutilsDroits : les outils de calcul des droits

Cette bibliothèque est celle qui assure le calcul des droits à retraite, à la fois pour le secteur privé et le secteur public. Il s'agit de calculs de droits à âge de liquidation donné. Les âges de liquidation sont calculés par la bibliothèque *OutilsComp*. *OutilsRetr* (surtout *SimDir*) combine *OutilsComp* et *OutilsDroits* pour simuler la liquidation et l'évolution des pensions.

Cette bibliothèque *OutilsDroits* travaille à la fois sur les variables individuelles indicées et non indicées de *DefVarRetr*.

Un premier sous-ensemble de fonctions sert à calculer les variables intermédiaires non indicées. Il s'agit de :

*Duree* : calcul de la durée passée dans un statut quelconque

*DurBase* : calcul des durées de base (durées cotisées)

*DurMajo* : calcul des durées majorées des droits familiaux

*AllocChom* : calcul des allocations chômage pour le SAM

*SalBase* : calcul du SAM et du salaire de référence FP

*Points* : calcul des décomptes de points ARRCO et AGIRC (et comptes notionnels, le cas échant)

*MinCont* : calcul du minimum contributif

*MinGaranti* : calcul du minimum garanti

Les quatre fonctions suivantes gèrent les âges d'accès à la retraite. Il s'agit de :

*AgeTrim* : retourne un âge trimestrialisé

*AgeMin* : indique si l'individu a atteint l'âge minimum d'ouverture des droits

*AgeMax* : indique si l'individu a dépassé l'âge maximum d'activité

*TauxPlein* : indique si l'individu a atteint les conditions du taux plein

Les deux fonctions suivantes s'appuient sur les précédentes pour calculer les droits à retraite ou les réévaluer. Il s'agit de :

*Liq* : calcul des droits complets à la liquidation

*Revalo* : revalorisation de l'ensemble des droits (y.c. réversion)

Il existe également des fonctions calculant différents indicateurs dérivés pouvant servir à l'analyse des droits :

*CotRet* : calcule les cotisations retraite sur salaires

*CotAut* : calcule la somme des autres cotisations sur salaires
<table><tr><td>CSGSal</td><td>: calcule la CSG/CRDS sur salaires</td></tr><tr><td>CSGRet</td><td>: calcule la CSG/CRDS sur pensions</td></tr><tr><td>SalNet</td><td>: calcule le salaire net</td></tr><tr><td>PNet</td><td>: calcule la pension nette</td></tr><tr><td>SalMoy</td><td>: calcule la moyenne des n derniers salaires</td></tr><tr><td>SalCum</td><td>: calcule la somme des n derniers salaires</td></tr><tr><td>Pente</td><td>: calcule un indice de pente de la carrière</td></tr><tr><td>TauxRemp</td><td>: calcule un taux de remplacement rapporté aux n derniers salaires</td></tr><tr><td>TauxAnn</td><td>: calcule un taux d'annuité effectif, défini comme le ratio entre le niveau de pension et la masse des salaires touchés durant la vie active</td></tr></table>

Toutes ces procédures ont au moins un argument d'appel qui est l'identifiant de l'individu. Le calcul se fait par défaut à l'âge courant de cet individu, soit $age[$i]$. Ainsi, si on se trouve à l'intérieur d'une double boucle sur $t$ et $i$, la fonction `TauxPlein($i$)`, par exemple, nous indique si l'individu $i$ dont l'âge en $t$ est $age[$i]$ a atteint, à cette date, les conditions du taux plein, telles que définies par le dernier appel de la fonction `UseLeg` de `DefVarRetr`. Mais il est aussi possible, dans certain cas, de forcer le calcul pour un âge autre que l'âge courant, qui est alors fourni par le deuxième paramètre d'appel. Il existe enfin d'autres paramètres optionnels qu'on décrit ci-après au cas par cas.

## VI.1.1 Fonctions de calcul de variables intermédiaires des droits directs

### Fonction Duree

La fonction Duree est une fonction utilitaire qui permet de calculer la durée passée par un individu dans un statut donné. Elle permet de calculer combien de temps un individu a été dans un statut donné entre 15 ans et un âge quelconque. Les arguments de cette fonction sont l'identifiant de l'individu, l'âge auquel on arrête le comptage de l'individu (le plus souvent $age[$i]$) et le ou les statut(s) à prendre en compte. Cette fonction Duree est essentiellement appelée dans les fonctions `DurBase` et `DurMajo`, présentées ci-dessous. Mais elle peut également être appelée depuis le programme principal si l'utilisateur a besoin d'une durée que ces fonctions ne calculent pas.

**Exemple d'appel :**

```
$duree_cho=Duree($i,$age[$i],$CodeCho);
```

calculera le temps pendant lequel un individu a été au chômage jusqu'à son âge courant.

```
$duree_act=Duree($i,$age[$i],@CodesAct);
```

calculera de la même manière la durée passée en activité.

### Fonction DurBase

La fonction `DurBase` calcule les durées cotisées dans les différents régimes, les durées en emploi, au chômage, en préretraite et la durée pendant laquelle l'individu a validé des années à l'AVPF. Elle passe en revue toutes les années de la carrière et incrémente les durées à calculer au fur et à mesure.

Elle modifie les valeurs des scalaires `$dureefra`, `$dureeavpf`, `$dureeemp`, `$dureePR` et `$duree_cho`.
## Fonction DurMajo

La fonction DurMajo repart des durées calculées par DurBase, et calcule les durées majorées prenant en compte la Majoration de Durée d'Assurance (MDA) et/ou l'Allocation Vieillesse des Parents au Foyer (AVPF) selon les options qui ont été précisées dans UseOpt. Elle met à jour les différentes durées déjà calculées par DurBase.

## Fonction SalBase

La fonction SalBase calcule les salaires servant de base au calcul des pensions de base, c'est-à-dire le SAM pour le RG et les régimes d'indépendants et le salaire de référence pour la fonction publique. Les résultats sont stockés dans $sam_rg, $sam_in et $sr_fp.

## Fonction Points

La fonction Points calcule le nombre de points accumulés dans les régimes ARRCO et AGIRC et stocke les résultats dans les variables $points_arrco et $points_agirc. Elle calcule aussi, s'il y a lieu, les totaux de points dans les régimes en comptes notionnels, si on simule la mise en place de tels régimes, selon les options présentées plus loin en VI.5.

## Fonction Mincont

La fonction Mincont calcule le montant attribuable au titre du minimum contributif. Elle suppose que les durées de cotisation sont connues, donc des appels préalables de DurBase et DurMajo pour pouvoir utiliser les durées majorées au régime général et les durées validées tous régimes.

Le calcul utilise les paramètres $Mincont1[$t], $Mincont2[$t] de ParamSociaux et $DureeProratRG créé par UseLeg.

## Fonction MinGaranti

La fonction MinGaranti calcule le montant attribuable au titre du minimum garanti. Elle tient compte de la période transitoire entre 2003 et 2013 avec application progressive de la réforme. Elle suppose que $duree_fp ait été renseignée, i.e. un appel préalable de DurBase.

## VI.1.2 Fonctions de calcul de variables intermédiaires pour l'âge de liquidation

### Fonction AgeTrim

Cette fonction retourne l'âge trimestrialisé de l'individu $i sur la base de son âge annuel et de son trimestre de naissance. Destinie travaille en pas annuel, mais l'utilisation d'un âge trimestrialisé est nécessaire lorsqu'on veut éviter des sauts trop importants de comportements moyens lorsque les seuils d'âge franchissent des valeurs entières. Il utilise en input la variable $trim[$i] donnant le trimestre de naissance impute au moment de l'appel de Relec.
### Fonction AgeMin

La fonction `AgeMin` indique si l'individu a atteint l'âge minimum d'ouverture des droits (60 ans dans le privé et 55 ans dans la fonction publique active). Elle relance pour ce faire les procédures `DurBase`. Elle retourne un booléen mais ne modifie aucune variable. Elle est utilisée dans la fonction `TestLiq`.

**Exemple d'appel :**

```perl
if (AgeMin($i)) {...}
```

### Fonction AgeMax

Retourne l'âge maximal de départ en retraite applicable à l'individu $i.

**Exemple d'appel :**

```perl
if ($age[$iAgeMax($i)] {...})
```

### Fonction TauxPlein

Indique si l'individu remplit les conditions du taux plein. Elle relance pour ce faire les procédures `DurBase` et `DurMajo`. Elle retourne un booléen mais ne modifie aucune variable.

**Exemple d'appel :**

```perl
if (TauxPlein($i)) {...}
```

## VI.1.3 Fonctions de calcul des montants de pension

### Fonction Liq

Simule l'effet de la liquidation à l'âge courant. Cette fonction n'a pas de valeur de retour. Elle modifie directement les variables globales `$pension_rg[$i]`, `$pensionFP[$i]` ... ainsi que `$pension[$i]` et `$ageliq[$i]`. Elle modifie aussi les variables `$statut[$i][$age[$i]]` et `$salaire[$i][$age[$i]]` ainsi que leurs équivalents `$statut[$i]` et `$salaire[$i]`.

Après avoir lancé toutes les fonctions intermédiaires (durées validées, salaire de référence et SAM, points, minimum garanti et minimum contributif) cette fonction `Liq` calcule la distance au taux plein.

Elle comprend ensuite plusieurs sous-modules : pour le calcul de la pension au RG, pour les pensions ARRCO et AGIRC, pour les pensions civiles, pour les pensions des indépendants.

Pour finir, elle procède aux mises à jours finales des variables de montant des pensions, du statut et des salaires et de l'âge de liquidation.

**Exemple d'appel :**

```perl
Liq($i);
```
### Fonction Revalo

La fonction `Revalo`, comme son nom l'indique, revalorise les composantes de la pension de l'individu $i$. Par défaut la revalorisation est faite de `$age[$i]-1` à `$age[$i]$. Si on veut une revalorisation cumulée sur plusieurs années, on précise à la fois l'âge d'arrivée et l'âge de départ.

Elle revalorise les pensions de base et les pensions de réversion en appliquant le coefficient de revalorisation du régime général ou de la fonction publique, dont les valeurs sont fournies dans `ParamSociaux`.

Elle revalorise également les pensions des régimes complémentaires en tenant compte de l'évolution de la valeur des points dans chaque régime.

Cette fonction s'applique à la fois aux droits directs et à la réversion.

### Exemples d'appel

```
Revalo($i);
```

calcule les composantes de la pension à `$age[$i]` en supposant que leurs valeurs avant appel sont celles de l'âge `$age[$i]-1`.

```
Revalo($i, 60, 65)
```

calcule les composantes de la pension à 65 ans en supposant que leurs valeurs avant appel sont celles atteintes par $i à 60 ans.

## VI.1.4 Calcul d'indicateurs dérivés

### Fonction CotRet

Cette fonction calcule la somme des cotisations retraite de l'individu $i$ à l'âge courant ou (optionnel) à un âge quelconque (il s'agit des cotisations salariés).

Exemples d'appel :

```
$cotret[$i][$a] = CotRet($i, $a);
$cotret[$i] = CotRet($i);
```

### Fonction CotAut

Cette fonction calcule les cotisations sur salaire autres que retraite. Même principe que `CotRet`.

### Fonction CSGSal

Cette fonction calcule la CSG-CRDS sur le salaire. Même principe que `CotRet` et `CotAut`.

### Fonction CSGRet

Cette fonction calcule la CSG-CRDS sur la pension. Contrairement à `CotRet` et `CotAut`, ne s'applique qu'à la pension courante.

Exemple d'appel :

```
$csg[$i] = $CSGRet($i);
```
### Fonction SalNet

Cette fonction calcule le salaire net de tous prélèvements (cotisations retraites, autres cotisations sociales et CSG/CRDS), à l'âge courant ou à un âge quelconque (optionnel).

### Fonction PNet

Cette fonction calcule la pension nette de prélèvements (CSG et CRDS), uniquement à l'âge courant.

### Fonction SalMoy

Cette fonction calcule la moyenne des salaires des n dernières années de la carrière (par défaut l'ensemble de la carrière). Le premier argument est l'indice de l'individu. Le second indique si on veut des salaires bruts ou nets. Le troisième argument, optionnel, donne le nombre n s'il ne s'agit pas de l'ensemble de la carrière. Un quatrième argument optionnel donne la série temporelle sur la base de laquelle on revalorise ces salaires passés. Par défaut, il s'agit des prix. L'ordre des deux arguments optionnels est indifférent (ce qui permet de ne passer qu'un seul des deux).

Exemples d'appel :

```perl
$sal_moy[$i]=SalMoy($i, "brut", 10);
$sal_moy[$i]=SalMoy($i, "net", @PlafondSS);
```

### Fonction SalCum

Cette fonction calcule la somme des salaires des n dernières années de la carrière (par défaut l'ensemble de la carrière). Le principe de l'appel est le même que pour la fonction SalMoy.

### Fonction Pente

Calcule un indice de pente du profil de salaire brut. Cet indice de pente est le ratio en % des n dernières années de carrière rapporté au salaire moyen de l'ensemble de la carrière. Par défaut, n est égal à 1. Les salaires moyens sont revalorisés par défaut comme les prix, ou selon la variable passée comme second argument optionnel

Exemples d'appel :

```perl
$pente[$i]=Pente($i);
$pente[$i]=Pente($i, 10, @PlafondSS);
```

### Fonction TauxRemp

Calcule le taux de remplacement, à n'utiliser donc que si $liq[$i==1. Les arguments d'appel sont les mêmes que pour SalCum ou SalMoy.

Exemples d'appel :

```perl
if ($liq[$i]) {$taux_r_b[$i]=TauxRemp($i, "brut");};
if ($liq[$i]) {$taux_r_n[$i]=TauxRemp($i, "net", 5, @PlafondSS)};
```

### Fonction TauxAnn

Calcule le taux d'annuité apparent, i.e. le rapport entre la pension à la liquidation et le cumul des salaires passés. Le principe d'appel est le même que pour TauxRemp.

Exemples d'appel :

```perl
if ($liq[$i]) {$taux_ann[$i]=TauxAnn($i, "brut");};
if ($liq[$i]) {$taux_ann[$i]=TauxAnn($i, "net", @PlafondSS)};
```
## VI.2 La bibliothèque OutilsComp : la simulation des comportements de départ à la retraite

Cette bibliothèque propose des outils de simulation des comportements de départ en retraite. Elle utilise les bibliothèques OutilsBase.pm, DefVarRetr.pm et OutilsRetr.pm. Contrairement aux programmes fournis dans OutilsRetr qui sont spécifiques au système français, les outils de cette bibliothèque sont des outils généraux qui pourraient être utilisés pour simuler des comportements dans des régimes entièrement différents.

La liste détaillée des fonctions disponibles est la suivante :

<table><tr><td>Uinst</td><td>: utilité instantanée selon statut courant</td></tr><tr><td>Uact</td><td>: utilité actualisée sur durée de vie restante selon âge de départ anticipé</td></tr><tr><td>SSW</td><td>: somme actualisée des droits en fonction de l'âge de départ anticipé</td></tr><tr><td>Accrual</td><td>: calcule le gain sur SSW lorsqu'on reporte la liquidation d'un an par rapport à l'âge courant</td></tr><tr><td>Peak</td><td>: calcule le SSW max pour tous les âges de départ au-delà de l'âge courant</td></tr><tr><td>TestLiq</td><td>: teste la décision de liquidation à l'âge courant avec cinq règles de comportement possibles</td></tr><tr><td>AgeOpt</td><td>: calcule âge optimal selon critères SSW ou UAct. Retourne également la valeur atteinte pour le critère qui est maximisé</td></tr></table>

### VI.2.1 Les fonctions de premier niveau

#### Fonction UInst

La fonction Uinst retourne l'utilité dérivée du revenu dans l'état courant, du type :

$$U = \text{revenu}^{1-\gamma}/(1-\gamma)$$

où $\gamma$ correspond au paramètre $\$\gamma\$[\$i\$] défini par DefVarRetr et initialisé par défaut à 0,5. La fonction gère le cas particulier $\gamma=1$. Le revenu est soit le revenu d'activité soit la pension. Mais la fonction ne prend pas en compte la préférence pour le loisir. Celle-ci est rajoutée au calcul par TestLiq lorsque l'option Uinst est activée.

**Exemple d'appel :**

UInst($i$);

#### Fonction UAct

La fonction Uact retourne l'utilité actualisée sur la durée de vie restante selon l'âge de liquidation anticipé. Pour un âge anticipé de $a_r$ sa forme est :

$$U_a(a, a_r) = \sum_{u=a}^{a_r} (1+\tau)^{a-u} s(u) \frac{w(u)^{1-\gamma}}{1-\gamma} + \sum_{u=a_r}^{\omega} (1+\tau)^{a-u} s(u) \frac{kp(a_r)^{1-\gamma}}{1-\gamma}$$

Les coefficients $\tau$, $k$ et $\gamma$ correspondent aux variables $\$taux[\$i\$], $\$k[\$i\$] et $\$\gamma\$[\$i\$] déclarées dans DefVarRetr, initialisés par défaut à 0,03, 1.5 et 0,5. Pour l'interprétation du rôle de ces paramètres, le lecteur est renvoyé au document général de présentation du modèle (Blanchet et al., 2010). La fonction de survie $s(a)$ est prise égale à la survie à l'âge courant telle que lue dans ParamMortal.xls, différenciée selon le sexe. Les revenus générateurs d'utilité sont des revenus réels. La pension $p(a_r)$ est telle qu'évaluée avec la législation active au moment du lancement de la fonction.

Les paramètres passés à la fonction sont l'identifiant de l'individu et l'âge de liquidation anticipé.
**Exemple d'appel :**

UAct($i, $ageliq);

## Fonction SSW

La fonction SSW retourne la richesse sécurité sociale sur la durée de vie restante selon l'âge de liquidation anticipé avec le taux $taux[$i]$. Les paramètres sont l'identifiant de l'individu et l'âge de liquidation anticipée. Si l'âge de liquidation anticipé n'est pas précisé, on suppose qu'il s'agit d'un individu déjà retraité et la procédure sert à calculer la valeur actualisée des droits restant à lui servir.

Cette fonction SSW calcule les droits cumulés en valeur à la date d'évaluation, mais corrigés de l'inflation anticipée (pas d'illusion monétaire en projection).

**Exemple d'appel :**

SSW($i, $ageliq);

## Fonction Accrual

La fonction Accrual retourne le gain relatif de SSW à reporter d'un an au-delà de l'âge courant. Elle revient donc à appeler deux fois la fonction SSW, sous les hypothèses de départ à l'âge courant et un an plus tard, et à faire la différence des deux résultats. Un résultat nul correspond à la neutralité actuarielle (pour le taux d'actualisation retenu).

**Exemple d'appel :**

$accrual= Accrual($i, 60);

## VI.2.2 Fonctions de calcul de l'âge de départ à la retraite : TestLiq et AgeOpt

La fonction TestLiq teste si le départ en retraite de l'individu $i$ a lieu à l'âge courant selon l'option de comportement choisie par UseOpt. La mise à la retraite est systématique à $\$AgeMaxFP$ ou $\$AgeMaxRG$, selon le statut courant, et quelle que soit l'option choisie

Selon l'option indiquée dans UseOpt, la fonction TestLiq lance des fonctions liées à ce type de comportement de liquidation (Uact, UInst, SSW) ou la fonction de test du taux plein. La plupart de ces fonctions lancent la fonction Liq car elles nécessitent de connaître le montant des pensions si la personne liquidait. L'articulation entre cette fonction, la fonction Liq et la fonction DroitsDir sera réexpliquée plus en détail plus loin à la section VI.5.2.

La fonction TestLiq retourne une variable qui vaut 1 si la personne liquide l'année courante et 0 sinon.

**Exemple d'appel :**

if TestLiq($i) {...};

## Fonction AgeOpt

La fonction AgeOpt retourne l'âge optimal au départ selon les critères Uact et SSW. Les paramètres sont les mêmes que pour Liq (sauf le paramètre $\$seuil$, qui est ici sans objet).
## VI.3 La bibliothèque OutilsMen : l'environnement familial des individus

Cette bibliothèque propose un certain nombre de programmes permettant de reconstituer les caractéristiques des ménages ou de l'environnement familial des individus. Il s'agit pour l'essentiel de caractéristiques démographiques (taille, nombre d'enfants). Mais elle contient aussi quelques caractéristiques économiques (revenu global, niveau de vie). En l'état, ces calculs de niveaux de vie ne prennent en compte que les salaires, les retraites et une version très sommaire des prestations chômage. La modélisation des autres composantes du revenu a été laissée à des développements ultérieurs.

Pour ces fonctions, le premier argument d'appel est en général l'indice de l'individu du ménage auquel on s'intéresse, suivi éventuellement d'un certain nombre de paramètres optionnels. Par exemple `TailMen($i)` donnera la taille du ménage de l'individu `$i`, `NbEnf($i, 0, 14)` donnera le nombre d'enfants de l'individu `$i$, âgés de 0 à 14 ans.

La liste détaillée des fonctions disponibles est la suivante :

### Fonctions démographiques

*   **Acharg**: indique si l'individu est un enfant à charge

*   **PersRef**: retourne la personne de référence du ménage d'appartenance

*   **EcartAge**: calcule l'écart d'âge entre l'individu et son conjoint

*   **NbEnf**: nombre d'enfants

*   **NbEnfC**: nombre d'enfants à charge

*   **TailMen**: taille du ménage

*   **ListEnf**: liste des identifiants des enfants

*   **ListEnfC**: liste des identifiants des enfants à charge

*   **ListMen**: liste des identifiants des membres du ménage

### Fonctions de calcul du niveau de vie

*   **NbUC**: Nombre d'unités de consommation

*   **RevMen**: Revenu global du ménage

*   **NVMen**: Niveau de vie du ménage

### VI.3.1 Fonctions de calcul démographique

#### Fonction ACharg

Cette fonction indique si l'individu passé en référence est un enfant à charge. Elle retourne un boolean.

#### Exemple d'appel :

```perl
if (ACharg($i)) {...}
```

#### Fonction PersRef

La fonction `PersRef` retourne l'identifiant de la personne de référence du ménage auquel appartient l'individu `$i`.

Nous avons adopté les conventions habituelles des enquêtes auprès des ménages pour déterminer la personne de référence. Si l'individu est un enfant à charge, la personne de référence de son ménage est son père s'il vit avec lui, sinon sa mère. Si la personne est un adulte, si elle ne vit pas en couple, elle est elle-même la personne de référence, si elle a un conjoint et si c'est une femme son conjoint est la personne de référence.

#### Exemples d'appel :

```perl
$pr[$i]=PersRef($i);
```
```perl
if (PersRef($i) eq $i) { } # teste si $i est la personne
# de référence de son ménage
```

## Fonction EcartAge

Cette fonction calcule l'écart d'âge entre deux individus, par exemple l'écart d'âge entre conjoints, ou l'âge d'un individu à la naissance d'un de ses enfants.

**Exemples d'appel :**

```perl
$ecartcj=EcartAge($i, $conjoint[$i]);
$age_premier_enfant=EcartAge($i, $enf[$i][1]);
```

## Fonction NbEnf

La fonction NbEnf calcule le nombre d'enfants. Elle comprend deux arguments. Le premier argument est l'indice de l'individu. Le deuxième permet de sélectionner les enfants pris en compte dans le calcul. Par défaut, il s'agit de l'ensemble des enfants encore en vie. Mais le second argument peut servir à spécifier une tranche d'âge, ou prendre la modalité "tous" qui permet d'inclure aussi les enfants décédés (calcul d'une descendance complète).

**Exemples d'appel :**

```perl
$nenf[$i]=NbEnf($i, [4..19]);
$nenf[$i]=NbEnf($i, "Tous");
```

## Fonction NbEnfC

La fonction NbEnfC fonctionne de la même façon que NbEnf, mais elle se limite aux enfants à charge. De ce fait, l'option "tous" n'est pas prévue.

**Exemple d'appel :**

```perl
$nenf[$i]=NbEnfC($i, [4..19]);
```

## Fonction TailMen

Taille du ménage auquel appartient l'individu $i.

La taille du ménage est égale au nombre d'enfants à charge de la personne de référence auquel on ajoute 1 pour la personne de référence elle-même et encore 1 si la personne de référence a un conjoint (si l'identifiant du conjoint de la personne de référence est positif).

**Exemple d'appel :**

```perl
$taille=TailMen($i);
```

## Fonction ListEnf

La fonction ListEnf suit le même principe que la fonction NbEnf, mais crée une liste contenant les identifiants des enfants. Par défaut, il s'agit de la liste des enfants encore en vie. Le second argument est soit une tranche d'âge, soit l'argument "tous" qui permet d'inclure aussi les enfants décédés.

**Exemples d'appel :**
```perl
@liste=ListEnf($i, [4..19]);
@liste=ListEnf($i, "Tous");
```

### Fonction ListEnfC

La fonction `ListEnfC` est identique à la fonction `ListEnf` mais elle se limite aux enfants à charge. De ce fait, comme pour `NbEnfC`, l'option `"tous"` n'est pas prévue.

Cette fonction sert entre autres à obtenir la liste des individus d'un ménage (fonction `ListMen` qui ne retient que les enfants à charge) qui permet de calculer la somme des revenus des membres du ménage (fonction `RevMen`).

**Exemple d'appel :**

```perl
@liste=ListEnfC($i, [4..19]);
```

### Fonction ListMen

La fonction `ListMen` retourne la liste des membres du ménage de l'individu `$i`.

Elle ajoute à la liste l'individu, son conjoint s'il existe (identifiant positif) et la liste des enfants, grâce à la fonction `ListEnfC`.

**Exemple d'appel :**

```perl
@liste=ListMen($i);
```

## VI.3.2 Fonctions relatives au niveau de vie

### Fonction NbUC

La fonction `NbUC` calcule le nombre d'unités de consommation du ménage de l'individu dont le numéro est passé en argument, d'après l'échelle d'équivalence OCDE modifiée. Elle affecte donc un poids de 1 à la personne de référence, un poids de 0,5 à son conjoint éventuel et à ses enfants de 14 ans et plus et un poids de 0,3 aux enfants de moins de 14 ans.

### Fonction RevMen

La fonction `RevMen` calcule le revenu global du ménage de l'individu `$i`. Elle fait la somme des revenus de tous les membres du ménage retenus dans `ListMen`.

Dans cette fonction les revenus pris en compte sont les salaires, les allocations chômage, les pensions de retraite directes et de réversion et le minimum vieillesse.

**Exemple d'appel :**

```perl
RevMen($i)
```

### Fonction NVMen

La fonction `NVMen` calcule le niveau de vie du ménage, en divisant le revenu du ménage (`RevMen ($i)`) par le nombre d'unités de consommation (`NbUC ($i)`).
## VI.4 La bibliothèque OutilsBase

La bibliothèque `OutilsBase` propose un ensemble de programmes très généraux destinés à la microsimulation et à la manipulation de données individuelles des types présentés aux sections précédentes. Elle contient également quelques fonctions arithmétiques de base. La liste résumée de ces fonctions est donnée ci-dessous, et les détails de chaque fonction sont donnés dans les sous-sections suivantes.

### Initialisations

`UseVRef` : Définition d'une variable de référence

### Opérations élémentaires

`In` : test d'appartenance à un ensemble de taille quelconque

`Out` : test de non-appartenance

`Min` : minimum d'un ensemble quelconque de valeurs

`Max` : maximum d'un ensemble quelconque de valeurs

`IMin` : indice du premier élément non vide d'un tableau

`IMax` : indice du dernier élément d'un tableau

`Arr` : arrondi d'un scalaire à un nombre donné de décimales

`ArrAlea` : arrondi aléatoire

`Pointage` : affichage de l'heure

### Valeurs de fonctions-type

`Esc` : valeur en x d'une fonction en escalier

`Affn` : valeur en x d'une fonction affine par morceaux

`Sigm` : valeur en x d'une fonction sigmoïde

`Part` : part de x comprise entre deux seuils

`MinMax` : plancher si x<plancher, plafond si x>plafond, x entre les deux

`Redr` : transformation monotone d'une variable x sur support [0,1]

### Tirages de variables aléatoires

`Alea` : tirage pseudo-aléatoire dans loi [0,1]

`Boolean` : tirage boolean

`MultiNom` : tirage selon une loi multinomiale

`Logist` : tirage selon loi logistique

`Pareto` : tirage selon une loi de Pareto

`LogLogist` : tirage selon une loi log-logistique (définie par deux quelconques de ses quantiles)

### Création et manipulation de variables individuelles et de listes d'identifiants

`Sel` : création liste d'identifiants selon critère déterministe

`Tirage` : création liste d'identifiants à partir d'une proba d'inclusion

`Trunc` : troncation d'une liste à ses n premiers éléments

`Excl` : exclusion d'éléments d'une liste

`EltAlea` : tirage d'un élément au hasard dans une liste

`TriAsc` : tri ascendant d'une liste selon valeurs d'une variable

`TriDesc` : tri descendant d'une liste selon valeurs d'une variable

`TriAlea` : permutation aléatoire d'une liste

`TriSect` : permutation d'une liste par section
## VI.4.1 Initialisations

### Fonction UseVRef

On commence par une fonction que l'utilisateur n'a, en général, pas besoin de manipuler, mais qu'il est utile de connaître pour bien comprendre le fonctionnement d'un certain nombre de fonctions, notamment les fonctions de tabulation. Cette procédure sert à définir une variable de référence parmi l'ensemble des variables micro de Destinie. La variable de référence a deux utilisés :

- Elle sert à connaître l'intervalle d'indices individuels pertinents. À un instant donné, l'indice maximal pour lequel des données micro sont renseignées correspond au dernier indice actif de cette variable de référence et les variables de tabulation se serviront par défaut de cette borne. C'est aussi sur cette base qu'est construite la fonction IMax dont on a vu l'utilisation dans la boucle individuelle du programme principal.

- Par ailleurs, elle sert à filtrer les identifiants effectivement pertinents. Le besoin d'un tel filtrage vient de ce que Destinie ne détruit pas les données de l'individu $i$ une fois qu'il est décédé car ces données peuvent servir à différents niveaux : pour des calculs de réversion, pour des reconstitutions de réseaux de parenté etc... Or il serait évidemment problématique que les procédures de tabulation mélangent des données sur des individus vivants et décédés. D'où la nécessité du filtrage.

Pour ce faire, la procédure UseVRef a deux arguments, l'adresse de la variable de référence et la valeur seuil de cette variable en dessous de laquelle les individus sont considérés comme non pertinents.

Par défaut, c'est le programme DefVarRetr qui se charge de cette initialisation. Il comprend une instruction :

UseVRef(@present,0);

qui signifie que les comptages s'effectueront en balayant les positions occupées par la variable @present en ignorant tous les individus $i$ pour qui $\$present[i]$ sera inférieur ou égal à zéro.

Par exemple :

$\$POP60etplus=Count(sub{$\$age[$_] > 60});$

calculera la population en vie et d'âge supérieur ou égal à 60.

Très exceptionnellement, l'utilisateur peut vouloir changer ces valeurs par défaut. Par exemple, la séquence :

UseVRef(@present,-1);
$TOTAL_NES_APRES_1920 = Count(sub{$\$anaiss[$_] >= 1920});$

calculera le nombre d'individus qui sont ou ont été traités par le modèle et qui sont nés depuis 1920, qu'ils soient encore en vie ou non à la date du comptage.

Il existe d'ailleurs un cas où cette désactivation du filtrage par la variable $\$present$ est prévue d'office par Destinie qui est le cas de tabulations par génération. Celles-ci interviennent nécessairement en toute fin de simulation et doivent incorporer l'ensemble des individus, qu'ils soient encore en vie ou non. Les fonctions qui effectuent ces tabulations sont présentées plus loin en section IV.6.4.
## VI.4.2 Opérations élémentaires

### Fonction In

La fonction In teste l'appartenance d'un scalaire à un ensemble. Ce scalaire est le premier argument. L'ensemble auquel on teste l'appartenance est fourni à la suite.

**Exemple d'appel :**

```perl
if (In("toto", ("titi", "tata", "toto", 1))) {...};
```

```perl
if (In($statut[$i], @CodesAct) {...});
```

(NB : dans le premier cas, la deuxième paire de parenthèses n'est mise que pour la lisibilité, elle est facultative).

### Fonction Out

La fonction Out teste si le premier argument est absent de la liste des arguments suivants.

**Exemple d'appel :**

```perl
if (Out("toto", ("titi", "tata", "toto", 1))) {...};
```

### Fonction Min

La fonction Min calcule le minimum d'un nombre quelconque de scalaires (et/ou d'un tableau passé par valeurs).

**Exemple d'appel :**

```perl
$x = Min (2, $y, $z);
```

### Fonction Max

La fonction Max calcule le max d'un nombre quelconque de scalaires (et/ou d'un tableau passé par valeurs).

**Exemple d'appel :**

```perl
$x = Max (2, $y, $z, @w);
```

### Fonction IMin

La fonction Imin retourne l'indice du premier élément non vide d'un tableau monodimensionnel quelconque

**Exemple d'appel :**

```perl
$debutSeriePIB = IMin(@seriePib);
```

### Fonction IMax

La fonction Imax retourne l'indice max d'une variable. S'il n'y a pas d'argument, on utilise la variable de référence définie par `UseVRef` (cf. *supra*).

**Exemple d'appel :**
$n=IMax(@var);

### Fonction Arr

La fonction `Arr` arrondi un scalaire à `$ndec$` décimales (0 par défaut). Le premier argument correspond au scalaire et le deuxième au nombre de décimales.

**Exemple d'appel :**

```
print Arr(2.3456,2);
```

imprimera 2.35

### Fonction ArrAlea

Arrondit un scalaire à ses valeurs entières encadrantes de manière aléatoire.

**Exemple d'appel :**

```
$x=ArrAlea(2.2);
```

retournera la valeur 2 avec une probabilité 0.8 et la valeur 3 avec une probabilité de 0.2.

### Fonction Pointage

La fonction Pointage affiche l'heure courante avec le texte de légende passé en premier argument, soit à l'écran (par défaut) soit dans le fichier dont le nom logique est passé en deuxième argument (optionnel).

**Exemples d'appels :**

```
Pointage("Debut de la simulation année ".$t);
```

```
Pointage("Debut de la simulation année ".$t,LOG);
```

## VI.4.3 Valeurs de fonctions élémentaires

### Fonction Esc

La fonction `Esc` calcule la valeur en un point donné d'une fonction en escalier. On donne le point où on souhaite l'évaluer et la séquence valeurs/points de discontinuité (avec une valeur de plus que de points de discontinuité).

**Exemple d'appel :**

```
$x= Esc($g,0,1933,3,1945,2,1970,1.5);
```

donne 0 si `$g<1933`, 3 s'il est compris entre 1933 et 1944 inclus...

### Fonction Affn

La fonction `Affn` calcule la valeur en un point donné d'une fonction affine par morceaux. On donne le point où on souhaite l'évaluer et un nombre arbitraire de paires `$x[$_]`, `$y[$_]` (avec `$x` croissant) correspondant aux points anguleux. La fonction est supposée constante avant et après le dernier point fourni.

**Exemple d'appel :**
$dureecib = Affn($g,1933,150,1943,160);

donne 150 si $g<1933, 160 si $g>1943 et interpole linéairement dans l'intervalle.

$dureecib = Affn($g,1933,150,1943,160,1948,160,1952,164);

idem avec trois segments.

## Fonction Sigm

La fonction Sigm retourne la valeur en $x d'une fonction sigmoïde variant de $y0 à $y1 entre $x0 et $x1 et constante de part et d'autre de ces bornes.

**Exemple d'appel :**

Sigm($x,2,0,3,1);

## Fonction Part

La fonction Part calcule la part d'une grandeur scalaire $x comprise entre deux seuils $s1 et $s2, c'est-à-dire 0 si $x<$s1, $x-$s1 si $x$ entre $s1 et $s2 et $s2-$s1 si $x>$s2.

**Exemple d'appel :**

$SalTR2 = Part($salaire,$PlafondSS,3*$PlafondSS);

## Fonction MinMax

La fonction MinMax retourne $x, si $x est compris entre $s1 et $s2, $s1 si $x<$s1 et $s2 si $x>$s2. Cette fonction est utile pour calculer des grandeurs ayant à la fois une valeur plancher et une valeur plafond

**Exemple d'appel :**

$prestation = MinMax($prestation,$plancher,$plafond);

## Fonction Redr

La fonction Redr redresse une proba scalaire $p$ d'un facteur $k$ selon la formule :

$$t(p)=kp/(1+(k-1)p).$$

Cette formule laisse à 1 ou 0 les probas égales à ces valeurs. Pour 0<p<1 elle préserve les rapports des odds-ratio, autrement dit, si on a les probas $p$ et $p'$ pour deux individus, alors on a :

$$[t(p)/(1-t(p))]/[t(p')/(1-t(p'))] = [p/(1-p)]/[p'/(1-p')]$$

Cette fonction sert à la fonction Tirage (voir plus bas).

**Exemple d'appel :**

$proba[$_] = Redr($proba[$_], $coeff);
### VI.4.4 Tirages de variables aléatoires

#### Fonction Alea

La fonction Alea effectue un tirage selon une loi uniforme [0,1]. Elle utilise une racine $seed$ qui est une variable de la bibliothèque visible depuis le programme appelant dont on peut éventuellement modifier l'initialisation en début de programme.

**Exemple d'appel :**

```perl
$seed = 12345689; # Reinitialisation de $seed
for $i (1..IMax)
{
    $x[$i]=Alea;
}
```

#### Fonction Boolean

La fonction Boolean effectue un tirage d'un évènement selon une probabilité donnée.

**Exemple d'appel :**

```perl
if (&Boolean ($qmor{$sexe[$i]}[$age[$i]}) {$statut[$i]=0};
```

NB : elle fonctionne aussi avec des valeurs hors de l'intervalle [0,1] : le retour est vrai si l'argument est supérieur à un, faux si l'argument est inférieur à zéro.

#### Fonction Multinom

Cette fonction retourne une variable valant 1, 2, .. ou n, avec les n probabilités passées en argument. Si la somme des probabilités est inférieure à un, les cas restants sont mis à 99.

#### Fonction Logist

Cette fonction effectue un tirage centré et réduit selon une loi logistique de moyenne et écart-type donnés.

#### Fonction Pareto

La fonction Pareto effectue un tirage selon loi de Pareto en fonction de son seuil et de son paramètre de forme.

**Exemple d'appel :**

```perl
$x=Pareto(1000,2);
```

#### Fonction LogLogist

Cette fonction effectue le tirage d'une variable aléatoire selon une loi LogLogistique, i.e. de fonction de répartition $z^a/(b+z^a)$ paramétrée par deux quelconques de ses quantiles. Par exemple

```perl
$x=LogLogist(.25,2,.5,3)
```

tirera une VA dont le premier quartile est à 2 et la médiane est à 3.
### VI.4.5 Création et gestion de listes d'identifiants

Les listes d'indices sont des listes d'entiers servant à repérer des sous-populations. Pour ces listes, l'ensemble des indices sont supposés actifs, y compris l'indice zéro, ce qui permet d'utiliser ces listes dans des instructions shift, par exemple.

Exemple : si on a une population de 10 individus telle que

`@statut[1..10] = (1,3,4,2,5,2,3,4,5,4);`

La liste `@liste=(3,8,10)` correspondra à la liste des numéros des individus tels que `$statut[$i==4]`.

Les opérations disponibles pour les listes sont la création, de manière déterministe ou aléatoire, la troncation, ou des opérations de tri.

#### Fonction Sel

Cette fonction construit une sous liste de l'ensemble d'indices d'une variable selon un critère déterministe sur cette variable et/ou d'autres variables. Comme pour les fonctions de comptage la condition est fournie sous forme d'une instruction Perl passée entre accolades après le mot clé `sub`.

Exemples d'appels :

`@liste = Sel (sub { ($age[$_] > 15) && ($statut[$_] == 1)});`

`@liste = Sel (sub { ($age[$_] > 15) && ($_<100)});`

#### Fonction Tirage

Cette fonction effectue le tirage d'une liste d'individus selon une variable `@proba` donnant la probabilité de sélection. Le second paramètre, optionnel, donne le nombre d'individus que l'on veut tirer (en espérance). Si ces deux paramètres sont incohérents, on applique à `@proba` une déformation conservant les risques relatifs et permettant d'atteindre, en moyenne, la cible d'effectifs recherchée. Si aucune cible n'est donnée, les probas sont utilisées telles quelles, sans redressement.

Exemple d'appel :

`@liste=Tirage(@proba,200,*LOG);`

Cas particuliers :

- S'il y a des individus avec `$proba[$i]=1` en nombre supérieur à la cible, la liste sera celle de ces individus, et la cible sera donc dépassée (mais on peut ensuite réduire la liste par la procédure `Trunc`)

- Si la cible est supérieure au nombre total d'individus pour qui `$proba[$i]>0`, l'ensemble de ces probabilités positives sont portées à 1, mais la contrainte reste non saturée.

Le dernier paramètre, optionnel, est l'adresse d'un fichier servant à garder trace du déroulement des itérations, lorsque ajustement il y a.

#### Fonction Trunc

Cette fonction effectue une troncation d'une liste à un effectif total donné (si l'effectif initial est supérieur à cette cible). Si on veut que les individus éliminés le soient au hasard, il faut prévoir un appel préalable de `TriAlea`.

Exemple d'appel :

`Trunc(@liste,100);`
### Fonction Excl

Cette fonction exclut d'une liste, avec une probabilité donnée, les individus remplissant une condition. Si la probabilité n'est pas déclarée, elle est supposée égale à un et l'exclusion est donc déterministe.

**Exemple d'appel :**

```
Excl(@liste, sub {Out($statut[$_*], @CodesAct)}, 0.8);
```

exclura de `@liste_ind` les individus actifs avec une probabilité de 0.8.

### Fonction EltAlea

Cette fonction renvoie un élément au hasard dans une liste.

**Exemple d'appel :**

```
$numero=EltAlea(@liste);
```

### Fonction TriAsc

Cette fonction trie une liste d'identifiants selon les valeurs croissantes d'une variable associée à ces identifiants.

**Exemples d'appels :**

```
@salaire[1..5] = (4,5,2,7,9);
@liste = (1,3,4);
TriAsc(@liste, @salaire);
```

change la liste d'identifiants en (3, 1, 4) (pour qui les salaires respectifs sont de 2, 4 et 7)

### Fonction TriDesc

Cette fonction trie une liste d'identifiants selon les valeurs décroissantes d'une variable associée à ces identifiants, selon le même principe que `TriAsc`.

**Exemple d'appel :**

```
TriDesc(@liste, @salaire);
```

### Fonction TriAlea

La fonction `TriAlea` trie une liste selon un ordre aléatoire.

**Exemple d'appel :**

```
TriAlea(@liste);
```

### Fonction TriSect

Cette fonction effectue une permutation d'une liste par section : on tire un élément au hasard, et on replace en début de liste cet élément et tous les suivants. Cette fonction permet de parcourir une liste à partir d'une position aléatoire d'une manière plus rapide que par `TriAlea`.

**Exemple d'appel :**

```
TriSect(@liste);
```