Logiques de programmes, troisi`eme cours
Pointeurs et structures de donn ´ees : la logique de s ´eparation
Xavier Leroy 2021-03-18
Coll`ege de France, chaire de sciences du logiciel [email protected]
Prologue :
les tableaux en logique de Hoare
Les tableaux
Ajout des tableaux dans IMP
Expressions : a::=. . .|T[a] lecture dans le tableauT Commandes : c::=. . .|T[a] :=a0 ´ecriture dans le tableauT
Convention : les variables en majusculesT,U, sont des tableaux.
2
Une logique de Hoare pour les tableaux
Quel triplet de Hoare pour l’´ecriture dans un tableau ?
Incorrect : {Q[T[a]←a0]}T[a] :=a0{Q} 8
Il n’y a pas queT[a]qui est modifi´e, mais aussiT[a1]pour toute expressiona1qui a la mˆeme valeur quea. Exemple :
{0=0∧T[i] =1}T[0] :=0{T[0] =0∧T[i] =1} est faux sii=0.
Correct : {Q[T ←(T+a7→a0)]}T[a] :=a0 {Q} 4 L’expressionT+a7→a0d´enote un tableau ´egal `aTsauf que l’indiceaa pour valeura0. (functional update)
3
Raisonner sur les tableaux
On raisonne sur ces tableauxfonctionnelsavec l’´equation
(T+a7→a0) [i] =
a0 si i=a T[i] si i6=a Exemple (v ´erification d’une ´ecriture dansT[0])
{i6=0∧T[i] =1}⇐⇒
{0=0∧(i=0?0:T[i]) =1}⇐⇒
{(T+07→0)[0] =0∧(T+07→0)[i] =1} T[0] :=0
{T[0] =0∧T[i] =1}
4
Exemple : l’initialisation d’un tableau
i:=0;
{i=0} whilei<Ndo
{ ∀j, 0≤j<i⇒T[j] =j×2}⇒
{ ∀j, 0≤j<i+1⇒(T+i7→i×2)[j] =j×2} T[i] :=i×2;
{ ∀j, 0≤j<i+1⇒T[j] =j×2} i:=i+1
{ ∀j, 0≤j<i⇒T[j] =j×2} done
5
Exemple : le tri par insertion
i
j i i:=1;
whilei<Ndo
{0<i<N ∧ ∀p,q, 0≤p≤q<i⇒T[p]≤T[q]} j:=i;
whilej>0∧T[j−1]>T[j]
{0≤j≤i ∧ ∀p,q, 0≤p≤q≤i∧q6=j⇒T[p]≤T[q]} swap(T,j,j−1);
j:=j−1 done i:=i+1 done
Plus un invariant :Test une permutation du tableau initialT0
6
Les pointeurs
et l’approche de Burstall-Bornat
Les pointeurs
Pointeurs : explicites (Algol-W, Pascal, C, C++) ou implicites via des objets manipul´es par r´ef´erence (Java, Lisp, Python, OCaml, . . . ).
Tr`es utilis´es pour repr´esenter et manipuler desgrapheset des structures de donn´ees chaˆın´ees(listes, arbres, . . . ).
7
Exemple : les listes simplement chaˆın ´ees
class List { typedef struct cell * list;
int head; struct cell { int head; list tail; };
List tail;
}
Les listes[1;2;3]et[4;5] :
1 2 3× 4 5 ×
Concat´enation en place des listesl1etl2: p = l1;
while (p->tail != NULL) p = p->tail;
p->tail = l2;
8
Exemple : les listes simplement chaˆın ´ees
class List { typedef struct cell * list;
int head; struct cell { int head; list tail; };
List tail;
}
Les listes[1;2;3]et[4;5] :
1 2 3 4 5 ×
Concat´enation en place des listesl1etl2: p = l1;
while (p->tail != NULL) p = p->tail;
p->tail = l2;
8
Le probl `eme du partage (aliasing)
Le partage est essentiel pour repr´esenter les graphes,
mais souvent probl´ematique pour des structures plus simples.
1 2 3
1 2 3
4 5
8 9
× l1
l2
l3
`A gauche :l1est une liste cyclique (infinie) 1,2,3,1,2,3, . . .
`A droite :l2partage avecl3le suffixe4,5.
9
Le probl `eme du partage (aliasing)
p = l1;while (p->tail != NULL) p = p->tail;
p->tail = l2;
Sil1est cyclique, la concat´enation ne termine pas.
Sil1partage avecl2, une liste cyclique est cr´e´ee.
Toute listel3qui partage avecl1est modifi´ee par effet de bord.
1 2 3 1 2 3 4 5
6
l1 l2 l1
l3
l2
×
10
Mod ´eliser les pointeurs et le tas m ´emoire (memory heap)
Le mod `ele na¨ıf :
• Le tas m´emoire = un grand tableau globalM.
• Un pointeurp= un indice dansM.
• Un acc`esp→f= un acc`esM[p+offset(f)]. Le mod `ele de Burstall-Bornat :
• Le tas m´emoire = un tableau global par champF1,F2, . . .
• Un pointeurp= un indice dans les tableauxFi.
• Un acc`esp→f= un acc`esF[p].
• Une affectationp→f:=amodifieF[p]mais les autres tableauxF0 6=Fsont inchang´es.
11
Les graphes dans le mod `ele Burstall-Bornat
struct node { bool mark;
int arity;
struct node * child[arity];
}
Trois tableaux globauxMARK[p],ARITY[p],CHILD[p][i]. Larelation d’accessibilit´epath(p,q),
le nœudqest accessible depuis le nœudp.
path(p,p)
p6=0 0≤i<ARITY[p] path(CHILD[p][i],q) path(p,q)
12
Un algorithme g ´en ´erique de parcours de graphe
Marquer tous les nœuds atteignables depuis une raciner. { ∀x, MARK[x] =0}
W:={r} whileW6=∅do
{ ∀x, path(r,x)⇐⇒MARK[x] =1∨ ∃p∈W,path(p,x)} pickp∈W; W:=W\ {p};
if MARK[p] =0then begin MARK[p] =1;
W:=W∪ {CHILD[p][i]|0≤i<ARITY[p]}
end done
{ ∀x, path(r,x)⇐⇒MARK[x] =1}
(Note : l’affectationMARK[p] =1 ne change pas les tableauxCHILDet
ARITY, et donc pr´eserve la relationpath.) 13
Les listes simplement chaˆın ´ees dans le mod `ele Burstall-Bornat
Deux tableaux globauxHEADetTAIL.Unpr´edicat de repr´esentation:lseg(w,p,q),
entre les pointeurspetqse trouve la repr´esentation de la liste (math´ematique)w.
lseg(ε,p,p)
p6=0 HEAD[p] =n lseg(w,TAIL[p],q) lseg(n·w,p,q)
ppointe sur une liste bien form´ee (sans cycles)=
∃w, lseg(w,p,NULL).
petqpointent sur des listes disjointes (sans partage) =
∀r,w,w0, lseg(w,p,r)∧lseg(w0,q,r)⇒r=NULL
14
Sp ´ecifier la concat ´enation de listes
On d´efinitlist(w,p)def= lseg(w,p,NULL),le pointeurprepr´esente la listew.
{w6=ε∧list(w,l1)∧list(w0,l2)∧disjoint(l1,l2)} concat(l1,l2)
{list(w·w0,l1)∧list(w0,l2)}
Une sp´ecification raisonnable mais encore incompl`ete :
il manque le fait que toute listel3initialement disjointe del1 n’est pas modifi´ee.
The verification proofs are quite long for such a simple mat- ter and very boring. We will not weary the reader with them ; instead we will try to do better.
(R. M. Burstall, 1972)
15
Raisonnement local
et empreintes m ´emoire
Le raisonnement local
Un principe de bon sens :Tout ce qui n’est pas explicitement mentionn ´e dans {P}c{Q}est pr ´eserv ´e par l’ex ´ecution de c.
En logique de Hoare, ce principe se pr´esente comme la r`egle d’encadrement (frame rule) suivante :
{P}c{Q}
aucune variable modifi´ee parcn’apparaˆıt dansR {P∧R}c{Q∧R}
Exemple :{x=0}x:=x+1{x=1}, et donc {x=0∧y=8}x:=x+1{x=1∧y=8}.
16
Pointeur + partage = plus de raisonnement local ?
1 2 3 4 5
6 l1
l3
l2
×
Prenons
P=list(1.2.3.ε,l1)∧list(4.5.ε,l2)∧disjoint(l1,l2) Q=list(1.2.3.4.5.ε,l1)
R=list(6.3.ε,l3)
On a bien{P}concat(l1,l2){Q}
mais pas {P∧R}concat(l1,l2){Q∧R}
(Rest fauxapr`es).
17
Vers une meilleure r `egle d’encadrement
{P}c{Q}
aucune variable modifi´ee parcn’apparaˆıt dansR aucune case m´emoire modifi´ee parcn’est mentionn´ee dansR
{P∧R}c{Q∧R}
Cette r`egle est plausible, mais la conditionaucune case m´emoire modifi´ee parcn’est mentionn´ee dansRn’est pas syntaxique.
Ce serait bien si la logique de programmes nous permettait de la v´erifier !
18
Empreintes m ´emoire
`A une assertion logiqueP,Qon associe uneempreinte m´emoire: l’ensemble des adresses (pointeurs) dont elle d´ecrit le contenu.
Exemple
L’assertionp7→0,`a l’adressepil y a la valeur 0, a pour empreinte{p}.
L’assertion(b∧p7→0)∨(¬b∧q7→1)
a pour empreinte{p}sibest vrai,{q}sibest faux.
19
Vers une meilleure r `egle d’encadrement
Intuition (presque vraie) : si{P}c{Q}, les cases m´emoire modifi´ees pendant l’ex´ecution decsont mentionn´ees dansPou dansQ, et donc appartiennent `a leur empreinte.
{P}c{Q}
aucune variable modifi´ee parcn’apparaˆıt dansR empreinte(P)∩empreinte(R) =∅
empreinte(Q)∩empreinte(R) =∅ {P∧R}c{Q∧R}
20
Conjonction s ´eparante
L’´enonc´ePetRsont vraies et leurs empreintes sont disjointesrevient si souvent qu’on lui donne un nom : la conjonction s´eparante, not´eePVR.
Formellement : (assertions = pr´edicats sur l’´etat m´emoireh) (PVR)h def= ∃h1,h2, P h1∧R h2∧h=h1]h2(union disjointe)
Exemple
p7→0Vp7→0 est toujours fausse.
p7→0Vq7→0 impliquep6=q.
21
Conjonction s ´eparante et encadrement
Laframe rulede la logique de s´eparation : {P}c{Q}
aucune variable modifi´ee parcn’apparaˆıt dansR {PVR}c{QVR}
Capture ´el´egamment l’id´ee de raisonnement local : P,Qd´ecrivent les parties de la m´emoire pertinentes pour l’ex´ecution dec;Rd´ecrit d’autres parties.
22
La logique de s ´eparation
L’ ´emergence de la logique de s ´eparation
Burstall (1972) : lesDistinct Nonrepeating List Systems (≈structures simplement chaˆın´ees sans aucun partage) + r`egles de raisonnement ad-hoc.
Reynolds (1999),Intuitionistic Reasoning about Shared Mutable Data Structures. Introduit la notion de conjonction s´eparante.
O’Hearn et Pym (1999),The Logic of Bunched Implications.
Pour raisonner sur des ressources utilis´ees de mani`ere lin´eaire.
O’Hearn, Reynolds, Yang (2001),Local Reasoning about Programs that Alter Data Structures. La pr´esentation moderne de la logique de s´eparation.
Reynolds (2002),Separation Logic : A Logic for Shared Mutable Data Structures. L’article qui lui a donn´e son nom.
23
Quel langage avec des pointeurs ?
Approche classique :IMP + op´erationsalloc,get,set,free. Deux degr´es de mutabilit´e : variables et cases m´emoire.
Assertions = pr´edicats de l’´etat des variables (s, lestore) et de l’´etat des cases m´emoire (h, leheap) Dans ce cours :mini-ML + r´ef´erences
ou encore : lambda-calcul + monade d’´etat.
Variables immuables contenant des r´ef´erences (adresses) de cases m´emoires mutables.
Assertions = pr´edicats de l’´etat des cases m´emoire (h, leheap).
24
Le langage PTR
Commandes (expressions avec effets) :
c::=a expression pure
|letx=cinc0 s´equence et liaison
|ifbthenc1elsec2 conditionnelle
|choose(N) choix non d´eterministe
|alloc(N) alloueNcases m´emoire
|get(a) lecture `a l’adressea
|set(a,a0) ´ecriture `a l’adressea
|free(a) d´esallocation de l’adressea
Dans les exemples on utilisera aussi des fonctions r´ecursives deff x1 · · · xn=c.
25
Exemples de programmes PTR
Allocation et initialisation d’une cellule de liste : def cons hd tl =
let a = alloc(2) in let _ = set(a, hd) in let _ = set(a + 1, tl) in a
N.B. adresses = entiers, avec arithm´etique de pointeurs.
Concat´enation en place de deux listes : def concat_rec l1 l2 =
let tl = get(l1 + 1) in
if tl = 0 then set(l1 + 1, l2) else concat_rec tl l2 def concat l1 l2 =
if l1 = 0 then l2 else let _ = concat_rec l1 l2 in l1
26
Les assertions
Les assertions sont des pr´edicats sur l’´etat m´emoireh. Assertions pures (Pest une proposition) :
hPi def= λh.P∧Dom(h) =∅
La m´emoire est vide
emp def= h>i = λh.Dom(h) =∅
L’adresse`contient la valeurv
`7→v def= λh.Dom(h) ={`} ∧h(`) =v
L’adresse`est valide
`7→ def= ∃v, `7→v = λh.Dom(h) ={`}
27
La conjonction s ´eparante
La conjonction s´eparantePVQdit qu’on peut partitionner l’´etat en deux parties, l’une satisfaisantPet l’autre satisfaisantQ.
PVQ def= λh.∃h1,h2, P h1∧Q h2∧h=h1]h2
Quelques propri´et´es :
PVQ=QVP (PVQ)VR=PV(QVR) empVP=PVemp=P hAiVhBi=hA∧Bi
28
Les r `egles de la logique de s ´eparation
D´efinissent des triplets{P}c{Q}.Les commandes renvoyant une valeurv, la postconditionQest une fonctionλv. . .des valeurs dans les assertions.
P⇒Q[[a]]
{P}a{Q}
∀n∈[0,N[, P⇒Q n {P}choose(N){Q} {P}c{R} ∀v, {R v}c0[x ←v]{Q}
{P}letx =cinc0{Q}
{ hbiVP}c1{Q} { h¬biVP}c2{Q} {P}ifbthenc1elsec2{Q}
29
Les r `egles structurelles
{P}c{Q}
(encadrement)
{PVR}c{λv.Q v VR}
P⇒P0 {P0}c{Q0} ∀v, Q0v⇒Q v
(cons´equence)
{P}c{Q}
A⇒ {P}c{Q}
(pure-elim)
{ hAiVP}c{Q}
∀x,{P}c{Q}
(∃-elim)
{ ∃x, P}c{Q}
30
Les
petites
r `egles pour les op ´erations sur la m ´emoire
Petitessignifieavec la plus petite empreinte m´emoire. {emp} alloc(N) {λ`. `7→ V· · ·V`+N−17→ } {[[a]]7→x} get(a) {λv.hv=xiV[[a]]7→x}
{[[a]]7→ } set(a,a0) {λv.[[a]]7→[[a0]]} {[[a]]7→ } free(a) {λv.emp}
Des r`eglesplus grossess’obtiennent par encadrement, p.ex.
{P} alloc(2) {λ`.PV`7→ V`+17→ }
31
Structures de donn ´ees et
pr ´edicats de repr ´esentation
Listes simplement chaˆın ´ees
Pr´edicats de repr´esentation : lseg(ε,p,q) = hp=qi
lseg(x·w,p,q) = ∃p0,p7→xVp+17→p0 Vlseg(w,p0,q) list(w,p) = lseg(w,p,NULL)
Exemple
1 2 3 q 4 5
p: q: ×
On alseg(1.2.3.ε,p,q)Vlist(4.5.ε,q)ce qui ´equivaut `a list(1.2.3.4.5.ε,p).
32
Sp ´ecifier des fonctions sur les listes simplement chaˆın ´ees
{list(w,p)} length(p) {λr.hr=|w|iVlist(w,p)} {list(w,p)} copy(p) {λr.list(w,r)Vlist(w,p)} {list(w,p)} dispose(p) {λr.emp}
{list(w,p)Vlist(w0,q)}concat(p,q) {λr.list(w·w0,r)} {list(w,p)} reverse(p) {λr.list(rev(w),r)}
33
Sp ´ecifier des fonctions sur les listes simplement chaˆın ´ees
{list(w,p)} length(p) {λr.hr=|w|iVlist(w,p)} {list(w,p)} copy(p) {λr.list(w,r)Vlist(w,p)} {list(w,p)} dispose(p) {λr.emp}
{list(w,p)Vlist(w0,q)}concat(p,q) {λr.list(w·w0,r)} {list(w,p)} reverse(p) {λr.list(rev(w),r)} Contrˆole du partage :
• Pourcopy(p), la postconditionlist(w,r)Vlist(w,p)garantit que le r´esultat ne partage aucune cellule avec l’argument.
• Pourconcat(p,q), la pr´econditionlist(w,p)Vlist(w0,q)exige que les deux arguments ne partagent aucune cellule.
33
Sp ´ecifier des fonctions sur les listes simplement chaˆın ´ees
{list(w,p)} length(p) {λr.hr=|w|iVlist(w,p)} {list(w,p)} copy(p) {λr.list(w,r)Vlist(w,p)} {list(w,p)} dispose(p) {λr.emp}
{list(w,p)Vlist(w0,q)}concat(p,q) {λr.list(w·w0,r)} {list(w,p)} reverse(p) {λr.list(rev(w),r)} Gestion des ressources :
• Certaines listes sont pr´eserv´ees (length,copy)
• D’autres sont allou´ees (copy) ou d´etruites (dispose)
• D’autres sont recompos´ees en de nouvelles listes (concat)
33
Sp ´ecifier des fonctions sur les listes simplement chaˆın ´ees
{list(w,p)} length(p) {λr.hr=|w|iVlist(w,p)} {list(w,p)} copy(p) {λr.list(w,r)Vlist(w,p)} {list(w,p)} dispose(p) {λr.emp}
{list(w,p)Vlist(w0,q)}concat(p,q) {λr.list(w·w0,r)} {list(w,p)} reverse(p) {λr.list(rev(w),r)} Permissions :
• Apr`esdispose(p)ouconcat(p,q), on perd le droit d’acc´eder `ap etqcomme listes bien form´ees.
• Apr`esconcat(p,q), on gagne le droit d’acc´eder `a la valeur r´esultat comme une liste bien form´ee.
33
Un exemple de v ´erification
{list(w,p)Vlist(w0,q)} def rev appendp q=
ifp=NULL then //w=ε q
else //west de la formex·w1 lett=get(p+1)in
let =set(p+1,q)in rev appendt p
{λr.list(rev(w)·w0,r)}
34
Un exemple de v ´erification
{list(w,p)Vlist(w0,q)} def rev appendp q=
ifp=NULL then //w=ε { hp=NULLiVlist(w0,q)} q
else //west de la formex·w1
{ ∃p0,p7→xVp+17→p0 Vlist(w1,p0)Vlist(w0,q)} lett=get(p+1)in
{p7→x Vp+17→tVlist(w1,t)Vlist(w0,q)} let =set(p+1,q)in
{list(w1,t)Vp7→xVp+17→qVlist(w0,q)} rev appendt p
{λr.list(rev(w1).x·w0,r)} {λr.list(rev(w)·w0,r)}
34
Listes circulaires
1
2 3
4
5
8 7
6
Pr´edicat de repr´esentation :
circlist(w,p) =hw6=εiVlseg(w,p,p) Concat´enation de deux listes circulaires :
{circlist(w,p)Vcirclist(w0,q)} swap(p,q);swap(p+1,q+1)
{circlist(w·w0,q)}
35
Listes circulaires
5
2 3
4
1
8 7
6
Pr´edicat de repr´esentation :
circlist(w,p) =hw6=εiVlseg(w,p,p) Concat´enation de deux listes circulaires :
{circlist(w,p)Vcirclist(w0,q)} swap(p,q);swap(p+1,q+1)
{circlist(w·w0,q)}
35
Listes doublement chaˆın ´ees
1 b 2 3 4 a
p: :q
Chaˆınage en avant depjusqu’`aa, en arri`ere deqjusqu’`ab. dlseg(ε,p,a,q,b) = hp=a∧q=bi
dlseg(x·w,p,a,q,b) = ∃p0,p7→x Vp+17→p0 Vp+27→b Vdlseg(w,p0,a,q,p0) dlist(w,p,q) = dlseg(w,p,NULL,q,NULL)
36
L’astuce du
ou exclusif
1 2 3
p: b⊕q q: p⊕r r: q⊕a
Dans chaque cellule on stocke leou exclusifdu pointeur vers l’avant et du pointeur vers l’arri`ere.
Parcours en avant : on apetqet on retrouver= (p⊕r)⊕p.
Parcours en arri`ere : on aretqet on retrouvep= (p⊕r)⊕r. dlseg(ε,p,a,q,b) = hp=a∧q=bi
dlseg(x·w,p,a,q,b) = ∃p0,p7→xVp+17→b⊕p0 V Vdlseg(w,p0,a,q,p0) dlist(w,p,q) = dlseg(w,p,NULL,q,NULL)
37
Arbres binaires
4 2
× 1 × × 3×
5
×6 ×
×
Pr´edicat de repr´esentation :
tree(Leaf,p) =hp=NULLi
tree(Node(t1,x,t2),p) =∃p1,p2, p7→p1Vp+17→x Vp+27→p2 Vtree(t1,p1)Vtree(t2,p2) Note : pas de partage interne possible, les sous-arbres doivent ˆetre disjoints.
38
Arbres binaires avec partage interne (≈ dags)
4 2
× 1 × ×3 ×
Possible avec uneoverlapping conjunction: (Hobor et Villard, 2013)
(P∪VQ)h=∃h1,h2,h3,h=h1]h2]h3∧P(h1]h2)∧Q(h1]h3)
tree(Leaf,p) =hp=NULLi
tree(Node(t1,x,t2),p) =∃p1,p2, p7→p1Vp+17→x Vp+27→p2 V(tree(t1,p1)∪Vtree(t2,p2))
39
Correction s ´emantique
de la logique de s ´eparation
Correction s ´emantique de la logique de s ´eparation
Nous avons donn´e des r`egles d´efinissant un triplet{P}c{Q}. Si{P}c{Q}est d´erivable par ces r`egles, toutes les ex´ecutions possibles decvalident-elles le contrat ´enonc´e par ce triplet ?
40
La s ´emantique par r ´eductions de PTR
On r´eduit des configurationsc/ho `uh:adresses→fin valeurs est l’´etat m´emoire courant (memory heap).
Les r`egles pour les constructions pures : (letx=ainc)/h→c[x←[[a]]]/h
(letx =c1inc2)/h→(letx =c01inc2)/h0 sic1/h→c01/h0 (letx =c1inc2)/h→err sic1/h→err
(ifbthenc1elsec2)/h→c1/h si[[b]]est vrai (ifbthenc1elsec2)/h→c2/h si[[b]]est faux
choose(N)/h→n/h pour toutn∈[0,N[
41
La s ´emantique par r ´eductions de PTR
Les r`egles pour les constructions imp´eratives :
alloc(N)/h→`/h[`←0, `+1←0, . . . , `+N−1←0]
pour tout`tel que{`, . . . , `+N−1} ∩Dom(h) =∅ get(a)/h→h([[a]])/h si[[a]]∈Dom(h)
set(a,a0)/h→0/h[ [[a]]←[[a0]] ] si[[a]]∈Dom(h) free(a)/h→0/(h\[[a]]) si[[a]]∈Dom(h) R`egles d’erreur :
get(a)/h→err si[[a]]∈/ Dom(h) set(a,a0)/h→err si[[a]]∈/ Dom(h) free(a)/h→err si[[a]]∈/ Dom(h)
42
´Enoncer la correction s´emantique
Mˆeme approche que pour la logique de Hoare forte.
On d´efinit le pr´edicat inductifTermc h Q,la commandec d´emarr´ee dans l’´etathtermine toujours sans erreurs et dans un
´etat satisfaisantQ.
Q[[a]]h
Terma h Q
(∀a, c6=a) c/h6→err (∀c0,h0, c/h→c0/h0 ⇒Termc0h0Q) Termc h Q
43
Correction s ´emantique
Le triplet s´emantique :si l’´etat initial satisfaitP, la commandec termine dans un ´etat satisfaisantQ
{{P}}c{{Q}} def= ∀h, P h⇒Termc h Q
On montre que cette d´efinition satisfait les axiomes et les r`egles d’inf´erences de la logique de s´eparation :
• SiP⇒Q[[a]]alors{{P}}a{{Q}}
• {{[[a]]7→ }}set(a,a0){{λv.[[a]]7→[[a0]]}}
• etc.
Th ´eor `eme (Correction s ´emantique de la logique de s ´eparation) Si{P}c{Q}est d ´erivable, alors{{P}}c{{Q}}est vrai.
44
Validit ´e s ´emantique de la r `egle d’encadrement
La principale difficult´e est de montrer que la r`egle d’encadrement est s´emantiquement valide :
Si{{P}}c{{Q}}alors{{PVR}}c{{λv.Q vVR}}.
Pour cela, il faut un lemme d’encadrement sur le pr´edicatTerm: SiTermc h1QetR h2alorsTermc(h1]h2) (λv.Q v VR).
C’est vrai en raison d’une jolie propri´et´e de la s´emantique op´erationnelle : si une commande ne fait pas d’erreurs dans un
petit ´etat, toute r´eduction dans ungrand ´etat est simul´ee par une r´eduction dans lepetit ´etat.
45
Encadrer les r ´eductions
c/h1
c/h c0/h0
encadrement h=h1]h2
r´eduction err
\
err
\
c0/h01
encadrement h0 =h01]h2 r´eduction
Sic/h16→err, alorsc/h1]h26→err. Si de plus
c/h1]h2→c0/h0, il existeh01tel queh0=h01]h2etc/h1 →c0/h01.
46
Encadrer les r ´eductions
c/h1
c/h c0/h0
encadrement h=h1]h2
r´eduction err
\
err
\
c0/h01
encadrement h0 =h01]h2 r´eduction
Sic/h16→err, alorsc/h1]h26→err. Si de plus
c/h1]h2→c0/h0, il existeh01tel queh0=h01]h2etc/h1 →c0/h01.
46
Encadrer les r ´eductions
c/h1
c/h c0/h0
encadrement h=h1]h2
r´eduction err
\
err
\
c0/h01
encadrement h0 =h01]h2 r´eduction
Sic/h16→err, alorsc/h1]h26→err. Si de plus
c/h1]h2→c0/h0, il existeh01tel queh0=h01]h2etc/h1 →c0/h01.
46
Encadrer les r ´eductions
Cette propri´et´e est vraie dans notre langage PTR parce que la r`egle de r´eduction des allocations estnon-d´eterministe: l’adresse`allou´ee peut ˆetre choisie parmi les adresses libres.
alloc(N)/h→`/h[`←0, `+1←0, . . . , `+N−1←0]
pour tout`tel que{`, . . . , `+N−1} ∩Dom(h) =∅ Ce ne serait plus vrai si`´etait une fonction de l’´etat m´emoire : alloc(N)/h→`/h[`←0, `+1←0, . . . , `+N−1←0]
avec`=firstfree(h,N)
car, en g´en´eral,firstfree(h1]h2,N)6=firstfree(h1,N).
47
Plan B : valider la r `egle d’encadrement par construction
Si l’allocation est d´eterministe, ou si on n’a pas envie de montrer la propri´et´e d’encadrement des r´eductions, voici une alternative.
1. D´efinir le triplet s´emantique de Hoare usuel :
{{P}}c{{Q}}Hoare def= ∀h, P h⇒Termc h Q
2. D´efinir le triplet s´emantique de s´eparationen quantifiant sur tous les encadrements possibles:
{{P}}c{{Q}}Sep def= ∀R, {{PVR}}c{{λv.Q vVR}}Hoare
48
Propri ´et ´es du triplet s ´emantique de Hoare
3. Montrer que le triplet s´emantique{{P}}c{{Q}}Hoaresatisfait
• lesgrandesr`egles pour les constructions imp´eratives {{P}}alloc(N) {{λ`. `7→ V· · ·V`+N−17→ VP}}Hoare {{[[a]]7→xVP}} get(a) {{λv.hv=xiV[[a]]7→xVP}}Hoare
{{[[a]]7→ VP}}set(a,a0) {{λv.[[a]]7→[[a0]]VP}}Hoare {{[[a]]7→ VP}} free(a) {{λv.P}}Hoare
• les r`egles usuelles pour les structures de contrˆole :
• siP⇒Q[[a]]alors{{P}}a{{Q}}Hoare
• si{{P}}c{{R}}Hoareet∀v,{{Rv}}c0[x←v]{{Q}}Hoare alors{{P}}letx=cinc0{{Q}}Hoare
• etc.
• mais pas la r`egle d’encadrement.
49
Propri ´et ´es du triplet s ´emantique de s ´eparation
{{P}}c{{Q}}Sep def= ∀R, {{PVR}}c{{λv.Q vVR}}Hoare
4. Observer que le triplet s´emantique de s´eparation satisfait
• lespetitesr`egles pour les constructions imp´eratives ;
• les r`egles pour les structures de contrˆole ;
• la r`egle d’encadrement.
5. Conclure que{P}c{Q}implique{{P}}c{{Q}}Sepet donc aussi{{P}}c{{Q}}Hoare.
50
Point d’ ´etape
Point d’ ´etape
L’apparition des logiques de s´eparation au d´ebut des ann´ees 2000 a enti`erement renouvel´e le domaine des logiques de programmes et de la v´erification d´eductive.
De tr`es nombreuses extensions, (→cours du 01/04)
notamment vers le parall´elisme `a m´emoire partag´ee.
(→cours du 25/03 et du 08/04)
De nombreuses mises en application :
• v´erification d´eductive + d´emonstration automatique
(Smallfoot, Infer, VeriFast) (→s´eminaire du 25/03)
• plongements dans des assistants `a la d´emonstration
(CFML, VST, Bedrock, IRIS) (→s´eminaires du 01/04 et du 08/04)
• syst`emes de types comme celui du langage Rust.
51
Bibliographie
Bibliographie
Une introduction `a la logique de s´eparation :
• Peter O’Hearn,Separation Logic, Comm. ACM 62(2), 2019.
Un des articles fondateurs, toujours de r´ef´erence 19 ans apr`es :
• John C. Reynolds,Separation Logic : A Logic for Shared Mutable Data Structures, LICS 2002.
M´ecanisations de la logique de s´eparation :
• Le d´eveloppement Coq correspondant `a ce cours :
https://github.com/xavierleroy/cdf-program-logics
• A. Chargu´eraud,Foundations of Separation Logic, 2021, https://www.chargueraud.org/teach/verif/
52