• Aucun résultat trouvé

Th´ eorie de la d´ emonstration et typage

Les r`egles de typage sont tr`es proches de la d´eduction naturelle, dans un fragment de la logique du chapitre 8. En fait, c’est une pr´esentation d’un frag-mentintuitionistepar uncalcul de s´equents. Pour s’en convaincre, oublions les termes PCF dans certaines r`egles de typages, un instant.

Reprenons la cr´eation de fonctions – (⇒Ig) : Γ, A`B Γ`A→B Rappel (chapitre 8) :

(⇒Ig) Γ`A,∆ Γ`B,∆ Γ, A⇒B`∆ Donc oui, c’est la mˆeme r`egle, avec ∆ =∅.

Maitenant l’affectation – (cut) :

Γ`A Γ, x:A`B Γ`B Rappel (chapitre 8) :

(cut) Γ`A,∆ Γ0, A`∆0 Γ,Γ0 `∆,∆0

9.7. TH ´EORIE DE LA D ´EMONSTRATION ET TYPAGE 145 Donc oui, c’est la mˆeme r`egle, avec ∆ =∅, Γ0= Γ et ∆0=B.

Revenons `a la r`egle de typage de la paire – (∧Id) : Γ`A Γ`v:B Γ`(u, v) :A∧B Rappel (chapitre 8) :

(∧Id) Γ`A,∆ Γ`B,∆ Γ`A∧B,∆

Prenons un exemple typique de cette correspondance type/formules, et preuves.

Revenons aux produits un instant.

Une fonction def :X×Y versZ peut-ˆetre consid´er´ee comme :

(i) bien sˆur une fonction qui `a un couple de valeurs (x, y), avec x∈ X et y∈Y, renvoief(x, y)∈Z;

(ii) une fonction de X versY →Z, qui `a unxdans X associe la fonction partiellefx:Y →Z telle quefx(y) =f(x, y) ;

(iii) un ´el´ement deX×Y →Z(soit une fonction de () (unit) versX×Y → Z).

Passer de (i) `a (ii) est«naturel»et on le fait constamment en OCaml. On a une fonction (d’ordre sup´erieur)

curry: ((X×Y)→Z)→(X →(Y →Z)) qui s’appelle la«curryfication».

En Caml, cela se programme de la fa¸con suivante : l e t c u r r y f x y = f ( x , y ) ; ;

v a l c u r r y : ( ’ a ∗ ’ b −> ’ c ) −> ’ a −> ’ b −> ’ c =<fun>

On a ´egalement la d´e-curryfication : l e t u n c u r r y f ( x , y ) = f x y ; ;

v a l u n c u r r y : ( ’ a −> ’ b −> ’ c ) −> ’ a ∗ ’ b −> ’ c = <fun>

Que l’on peut utiliser par exemple comme suit : l e t f ( x , y ) = x+y and g = c u r r y f ; ; v a l f : i n t ∗ i n t −> i n t =<fun>

v a l g : i n t −> i n t −> i n t =<fun>

l e t f 5 = g 5 ; ;

v a l f 5 : i n t −> i n t =<fun>

l e t h x = function y −> f ( x , y ) and

i = function x −> function y −> f ( x , y ) ; ; v a l h : i n t −> i n t −> i n t =<fun>

v a l i : i n t −> i n t −> i n t =<fun>

146 CHAPITRE 9. TYPAGE, ET PROGRAMMATION FONCTIONNELLE Une autre fonction«naturelle»est l’´evaluation :

eval: (X→Z)×X→Z

qui a toutxdeX, et toute fonction deX →Z associeeval(f, x) =f(x) dans Z. En Caml, cela se programme de fa¸con ´evidente :

l e t e v a l f x = f x ; ;

v a l e v a l : ( ’ a −> ’ b ) −> ’ a −> ’ b = <fun>

Vous remarquerez la similarit´e avec la logique propositionnelle. Le paradigme est celui des«proofs as programs», dans une logique«constructive»au moins :

«Programme=preuve de son type»

Illustrons cela par un exemple simple. On rappelle les fonctions Caml sui-vantes :

l e t c u r r y f x y = f ( x , y ) ; ;

v a l c u r r y : ( ’ a ∗ ’ b −> ’ c ) −> ’ a −> ’ b −> ’ c = <fun>

La fonctioncurry est en fait une«preuve» de :

((a∧b) =⇒ c) =⇒ (a =⇒ (b =⇒ c)) De mˆeme pour l’«application»qui s’´ecrit en Caml : l e t a p p l y = u n c u r r y e v a l ; ;

v a l a p p l y : ( ’ a −> ’ b ) ∗ ’ a −> ’ b =<fun>

La fonctionapply est une preuve du«modus ponens»: ((a =⇒ b)∧a) =⇒ b

Reprenons maintenant encoreapply. Supposons qu’on ait les axiomes (=« com-binateurs»)eval et uncurry: on peut en d´eduire une preuve constructive du modus ponens:

(uncurry) ((u =⇒ v) =⇒ w) =⇒ ((u∧v) =⇒ w) en faisantu= (a =⇒ b),v=a,w=bd’o`u :

(((a =⇒ b) =⇒ a) =⇒ b) =⇒ (((a =⇒ b)∧a) =⇒ b) Mais on sait par (eval) :

(eval) ((a =⇒ b) =⇒ a) =⇒ b Donc :

(uncurry eval) ((a =⇒ b)∧a) =⇒ b

Cette preuve correspond `a l’ex´ecution de la composition des fonctionsuncurry eteval :

9.8. POUR ALLER PLUS LOIN 147 u n c u r r y e v a l ; ;

− : ( ’ a −> ’ b ) ∗ ’ a −> ’ b =<fun>

De fa¸con g´en´erale, on a la correspondance de Curry-Howard. Un programme de typetest une preuve det comme suit : (en logiqueintuitioniste)

Terme logique Type informatique Implication type fonctionnel conjonction type produit

disjonction type somme

vrai typeunit

faux ⊥(exception/boucle infinie) Les quantificateurs correspondent aux typesd´ependants.

9.8 Pour aller plus loin

La plupart des cours permettant d’approfondir ce th`eme se trouvent au MPRI (en M2). Parmi les th`emes tr`es avanc´es, on retrouve :

– la g´en´eralisation de la correspondance de Curry-Howard `a la logique clas-sique (call-with-current-continuation, transformationcontinuation passing style) ;

– certains«grands»th´eor`emes ont ´et´e interpr´et´es comme des programmes (ex. th´eor`emes de compl´etude et d’incompl´etude de G¨odel, forcing de Co-hen etc. - par Jean-Louis Krivine) ;

– des liens entre la topologie alg´ebrique et certains syst`emes de types : cf.«Homotopical Foundations»de Vladimir Voevodsky (m´edaille Fields 2002),http://homotopytypetheory.orget les travaux de Steve Awodey (CMU, Pittsburgh).

Exercices

1. Calculer la s´emantique op´erationnelle du terme PCF : (fix f fun x -> ifz x then x+f(x−1)) 3 en appel par valeur.

2. Soitf et gdeux termes PCF de types : f : Np+1→N

g: Np→N

Prouver queh d´efini `a partir def et g par r´ecursion primitive (chapitre 5) peut se d´efinir en PCF. En d´eduire que PCF permet au moins de coder toutes les fonctions r´ecursives primitives.

3. D´efinir un codage des bool´eens comme on avait fait pour recoder les en-tiers au d´ebut de ce chapitre. Donner alors des termes PCF permettant d’interpr´eter les tests sur les bool´eens (sans faire appel `a ifz ).

148 CHAPITRE 9. TYPAGE, ET PROGRAMMATION FONCTIONNELLE 4. Typer le programme PCF (sch´emas monomorphe et polymorphe) :

fix f fun x -> ifz x then x+f(x−1)

Chapitre 10

Programmation r´ eactive synchrone

Ce chapitre introduit `a un paradigme de programmation original, la pro-grammation r´eactive synchrone (en particulier Lustre), ´egalement tr`es utile en pratique, par exemple pour le codage du contrˆole commande d’avions, de cen-trales nucl´eaires, etc. Le code du calculateur primaire de vol de l’A380 par exemple, est ´ecrit en Scade (Esterel Technologies), qui est une version indus-trielle de Lustre. C’est aussi un langage de programmation `a la s´emantique tr`es propre, qui permet d’illustrer encore les outils de la s´emantique du chapitre 6.

Ce langage a une belle s´emantique et a ainsi de nombreux outils associ´es, de preuve, test, etc.

Ce paradigme vient en quelque sorte d’un mariage du contrˆole et de l’informa-tique. En g´en´eral, on peut d´ecrire les programmes dans ce paradigme, graphi-quement, par sch´ema-bloc (comme Matlab/Simulink le fait par exemple) mais

´

egalement `a travers un langage textuel. Ce langage est d´eclaratif, un programme est un ensemble d’´equations, comme nous allons l’expliciter plus bas.

10.1 Lustre

Lustre est un langage de programmation d´eclaratif, donn´e par un ensemble

«d’´equations» mutuellement r´ecursives en g´en´eral, calculant des suites de si-gnaux de sortie, `a partir de signaux d’entr´ee. On peut voir la machine d’ex´ ecu-tion sous-jacente comme une machine parall`ele, dans laquelle chaque ´equation (ou «noeud») est un processus traitant des signaux cadenc´es `a un certain rythme temporel, et en renvoyant d’autres aux autres noeuds. La machine sous-jacente est donc un graphe de processus, avec un mod`ele d’ex´ecution tr`es simple : tous les processus ont la mˆeme horloge globale, c’est-`a-dire qu’ils lisent leur en-tr´ees, calculent, et produisent leurs sorties tous en mˆeme temps, `a chaque«tic» d’horloge. Lustre impl´emente en fait les r´eseaux de Kahn (on les introduit `a la section 10.4) synchrones. Par synchrone, on entend le fait qu’un message par arc

149

150 CHAPITRE 10. PROGRAMMATION R ´EACTIVE SYNCHRONE du r´eseau est envoy´e et re¸cu `a chaque «tic»de l’horloge globale. Cela permet d’´eviter l’utilisation detampons de communicationspotentiellement non born´es, avec une puissance de calcul similaire aux r´eseaux de Kahn g´en´eraux.

Un programme Lustre op`ere sur un flot, c’est-`a-dire unesuite de valeurs: une variablexen Lustre repr´esente une suite infinie de valeurs (x0, x1, . . . , xn, . . .) ; xiest la valeur dexau tempsi. Un programme Lustre prend un flot et renvoie un flot et toutes les op´erations sont globales sur un flot :

– L’´equation de flotx=eest un raccourci pour∀n, xn=en;

– L’expression arithm´etique sur les flotsx+y renvoie le flot (x0+y0, x1+ y1, . . . , xn+yn, . . .).

Lustre introduit ´egalement des op´erateurs temporels. Ceux-ci sont :

– pre (pr´ec´edent) qui donne la valeur au temps pr´ec´edent, d’un flot argu-ment :pre(x)est le flot (⊥, x0, . . . , xn−1, . . .) ;

– ->(suivi de) est utilis´e pour donner des valeurs initiales d’un flot :x->y est le flot (x0, y1, . . . , yn, . . .).

Remarquez que les flots sont typ´es.boolpar exemple est le type des flots de bool´eens.

Les expressions arithm´etiques et bool´eennes, syntaxiquement, sont les mˆemes que d’habitude, mais ´etendues point `a point aux flots. On a ´egalement une forme syntaxique pour l’affectation :let ... = ... tel, les conditionnelles :if ...

then ... else, et la s´equence.

L’organisation d’un programme Lustre est faite ainsi. Un programme Lustre est un ensemble d’´equations a priori potentiellement mutuellement r´ecursives.

Chaque ´equation est d´efini par un noeud identifi´e par le mot cl´e node. Une

´

equation ou noeud est une fonction prenant des flots en argument, renvoyant un flot en r´esultat.

Donnons pour premier exemple un programme simple, compteur d’´ev´ ene-ments :

Dans ce programme,true->resetest un flot bool´een, ´egal `a vrai `a l’instant initial et quandresetest vrai. Quand il est vrai, la valeur decountest renvoy´ee

´

egale `a z´ero. Sinon, quandevtest vrai, on renvoie la valeur `a l’instant pr´ec´edent decountplus 1 ; sinon on conserve l’ancienne valeur.

La repr´esentation graphique associ´e `a cette version textuelle du programme est la suivante :

10.1. LUSTRE 151

Voici un exemple d’utilisation de ce compteur d’´ev´enements.

mod60 = Count ( s e c o n d , minute ) ; minute = s e c o n d and p r e ( mod60 ) = 5 9 ;

Dans ce programme, mod60 est la sortie du noeud Count, qui compte les secondes, et se remet `a z´ero chaque minute.minuteest vrai quandsecondeest cadenc´e et que sa valeur pr´ec´edente est de 59.

Prenons maintenant un exemple du monde du traitement du signal : les filtres lin´eaires `a r´eponse finie. Ce sont des calculs r´ecurrents qui prennent une entr´ee `a l’instantn,xn et renvoient en sortie, `a l’instantn,yn donn´ee par :

yn=

L−1

X

m=0

h(m)xn−m

Graphiquement :

Prenons maintenant l’exemple des filtres lin´eaires `a r´eponse infinie (filtres r´ e-cursifs). Ils prennent en entr´ee `a l’instantn,xn, et renvoient en sortie `a l’instant n,yn donn´ee par :

yn =

L−1

X

m=0

b(m)xn−m+

M−1

X

m=1

a(m)yn−m

Graphiquement :

152 CHAPITRE 10. PROGRAMMATION R ´EACTIVE SYNCHRONE

Un code Lustre typique, correspondant, par exemple dans le cas o`u la sortie est donn´ee par :yn=xn+ 0.9yn−1 :

node f i l t e r ( x : r e a l ) r e t u r n s ( y : r e a l ) ; l e t

y = x +0.0 −> 0 . 9∗p r e ( y ) ; t e l ;

Prenons maintenant un autre exemple : celui du chien de garde (watchdog).

Il permet de g´erer des ´ech´eances : il ´emetalarmquandwatchdogest en attente et quedeadlineest vrai :

node WATCHDOG1( s e t , r e s e t , d e a d l i n e : b o o l ) return ( alarm : b o o l ) ; v a r w a t c h d o g i s o n : b o o l ;

l e t

alarm = d e a d l i n e and w a t c h d o g i s o n ; w a t c h d o g i s o n = f a l s e −> i f s e t t h e n t r u e

e l s e i f r e s e t t h e n f a l s e e l s e p r e ( w a t c h d o g i s o n ) ; a s s e r t n o t ( s e t and r e s e t ) :

t e l ;

(les flots bool´eenssetetresetne doivent pas ˆetre vrais en mˆeme temps).

Un des soucis principaux de la s´emantique de tels langages est d’assurer la

«causalit´e». On veut ainsi que les ´equations d´efinissant un programme aient une signification en termes de propagation d’information, et qu’en quelque sorte, celles-ci ne se mordent pas la queue. Pour assurer la causalit´e, comme tout r´eseau de Kahn se doit, on doit op´erer des restrictions syntaxiques sur les programmes Lustre. Par exemple, let x=x+1; n’est pas un programme Lustre correct : le flotx d´epend instantan´ement de lui-mˆeme, ce qui n’est pas possible (ou alors

10.2. CADENCEMENT ET«CALCUL D’HORLOGES» 153