Sunteți pe pagina 1din 52

Fundamentele limbajelor de programare

C11

Denisa Diaconescu
Traian S, erbănut, ă

Departamentul de Informatică, FMI, UB

1
Semantica limbajelor de
programare
Principalele paradigme de programare

• Imperativă (cum calculăm)


• Procedurală

• Orientată pe obiecte

• Declarativă (ce calculăm)


• Logică

• Functională

Fundamentele paradigmelor de programare


Imperativă Execut, ia unei Mas, ini Turing
Logică Rezolut, ia în logica clauzelor Horn
Funct, ională Beta-reduct, ie în Lambda Calcul

2
Ce înseamnă semantică formală?

Ce defines, te un limbaj de programare?

• Sintaxa – Simboluri de operat, ie, cuvinte cheie, descriere


(formală) a programelor/expresiilor bine formate

• Practic – Un limbaj e definit de modul cum poate fi folosit


• Manual de utilizare s, i exemple de bune practici
• Implementare (compilator/interpretor)
• Instrumente ajutătoare (analizor de sintaxă, depanator)

• Semantica – Ce înseamnă/care e comportamentul unei


instruct, iuni?
• De cele mai multe ori se dă din umeri s, i se spune că Practica e
suficientă
• Limbajele mai utilizate sunt standardizate

3
La ce foloses, te semantica?

• Să înt, elegem un limbaj în profunzime


• Ca programator: pe ce mă pot baza când programez
• Ca implementator al limbajului: ce garant, ii trebuie să ofer

• Ca instrument în proiectarea unui nou limbaj/a unei extensii


• Înt, elegerea componentelor s, i a relat, iilor dintre ele
• Exprimarea (s, i motivarea) deciziilor de proiectare
• Demonstrarea unor proprietăt, i generice ale limbajului

• Ca bază pentru demonstrarea corectitudinii programelor

4
Problema corectitudinii programelor

• Pentru anumite metode de programare


The Program Correctness Problem
(e.g., imperativă, orientată pe obiecte),
nu este us, or să stabilim dacă un program
este corect sau să înt, elegem ce
înseamnă că este corect (e.g, în raport
cu ce?!).
• Corectitudinea programelor devine o
problemă din ce în ce mai importantă, nu
?
doar pentru aplicat, ii "safety-critical".
• Conventional models of using computers – not easy to deter

• Avem nevoie de metode ce asigură! Has become a very important issue, not just in safety-crit
! Components with assured quality, being able to give a wa
"calitate", capabile să ofere "garant,!ii".
Being able to run untrusted code, certificate carrying cod

5
C

#include <iostream>
using namespace std;
int main()
{
int square;
for(int i = 1; i <= 5; ++i)
{
square = i * i;
cout << square << endl;
}
}

6
C

#include <iostream>
using namespace std;
• Este corect?
int main()
{
int square;
for(int i = 1; i <= 5; ++i)
{
square = i * i;
cout << square << endl;
}
}

6
C

#include <iostream>
using namespace std;
• Este corect? În raport cu ce?
int main()
{
int square;
for(int i = 1; i <= 5; ++i)
{
square = i * i;
cout << square << endl;
}
}

6
C

#include <iostream>
using namespace std;
• Este corect? În raport cu ce?
int main()
{ • Un formalism adecvat trebuie:
int square; • să permită descrierea
for(int i = 1; i <= 5; ++i) problemelor (specificat, ii), s, i
• să rat, ioneze despre
{
implementarea lor
square = i * i;
(corectitudinea programelor).
cout << square << endl;
}
}

6
Care este comportamentul corect?

int main(void) {
int x = 0;
return (x = 1) + (x = 2);
}

7
Care este comportamentul corect?

int main(void) {
int x = 0;
return (x = 1) + (x = 2);
}

• GCC4, MSVC: valoarea întoarsă e 4


• GCC3, ICC, Clang: valoarea întoarsă e 3

Conform standardului limbajului C (ISO/IEC 9899:2018)


Comportamentul programului este nedefinit.

7
Tipuri de semantică

• Limbaj natural – descriere textuală a efectelor


• Statică – un sistem de tipuri care exclude programe eronate
• Operat, ională – asocierea unei demonstrat, ii pentru execut, ie
• ⟨cod , σ⟩ → ⟨cod ′ , σ′ ⟩
• modelează execut, ia unui program pe o mas, ină abstractă
• utilă pentru implementarea de compilatoare s, i interpretoare
• Axiomatică – aproximarea logică a efectelor unei instruct, iuni
• ⊢ {φ}cod {ψ}
• modelează comportamentul un program prin formulele logice pe
care le satisface
• utilă pentru demonstrarea corectitudinii
• Denotat, ională – asocierea unui obiect matematic (denotat, ie)
• ⟦cod ⟧
• modelează un program ca obiecte matematice
• utilă pentru fundamente matematice
8
Limbajul IMP

Vom folosi ca exemplu un mic limbaj imperativ IMP care cont, ine:

• Expresii
• Aritmetice: x + 3
• Booleene: x >= 7
• Instruct, iuni
• De atribuire: x = 5
• Condit, ionale: if(x >= 7, x = 5, x = 0)
• De ciclare: while(x >= 7, x = x - 1)
• Compunerea instruct, iunilor: x=7; while(x>=0, x=x-1)
• Blocuri de instruct, iuni: {x=7; while(x>=0, x=x-1)}

9
Limbajul IMP

Un exemplu de program în limbajul IMP

{ x = 10 ; sum = 0;
while(0 =< x,
{sum = sum + x; x = x-1}
)},
sum

Semantica: după executia programului, se evaluează sum

10
Sintaxa BNF a limbajului IMP

E ::= n | x
| E+E | E-E | E*E

B ::= true | false


| E =< E | E >= E | E == E
| not(B) | and(B , B) | or(B , B)

C ::= skip
| x=E
| if( B , C , C )
| while( B , C )
| {C}| C;C

P ::= { C }, E
11
Semantica operat, ională small-step
Imagine de ansamblu

• Semantica operat, ională descrie cum se execută un program pe o


masină abstractă (ideală).

• Semantica operat, ională small-step


• semantica structurală, a pas, ilor mici
• descrie cum o execut, ie a programului avansează în functie de
reduceri succesive.
⟨cod , σ⟩ → ⟨cod ′ , σ′ ⟩

• Semantica operat, ională big-step


• semantică naturală, într-un pas mare

12
Starea execut, iei

• Starea execut, iei unui program IMP la un moment dat este dată
de valorile det, inute în acel moment de variabilele declarate în
program.
• Formal, starea execut, iei unui program IMP la un moment dat este
o funct, ie part, ială (cu domeniu finit):
σ : Var ⇀ Int
• Notatii:
• Descrierea funct, iei prin enumerare: σ = n 7→ 10, sum 7→ 0
• Funct, ia vidă ⊥, nedefinită pentru nicio variabilă
• Obt, inerea valorii unei variabile: σ(x )
• Suprascrierea valorii unei variabile:

 σ(y ), dacă y , x

σ x ←v ( y ) = 


 v, dacă y = x
13
Semantica small-step

• Introdusă de Gordon Plotkin (1981)


• Denumiri alternative:
• Semantică Operat, ională Structurală
• semantică prin tranzit, ii
• semantică prin reducere
• Defines, te cel mai mic pas de execut, ie ca o relat, ie „de tranzit, ie”
între configurat, ii:
⟨cod , σ⟩ → ⟨cod ′ , σ′ ⟩
• Execut, ia se obt, ine ca o succesiune de astfel de tranzit, ii:
⟨x = 0 ; x = x + 1 , ⊥⟩ → ⟨x = x + 1 , x 7→ 0⟩
→ ⟨x = 0 + 1 , x 7→ 0⟩
→ ⟨x = 1 , x 7→ 0⟩
→ ⟨{} , x 7→ 1⟩
• Cum definim această relat, ie?
14
Prin inductie după elementele din sintaxă.
Redex. Reguli structurale. Axiome

• Expresie reductibilă (redex)


• Fragmentul de sintaxă care va fi procesat la pasul următor
if (0 <= 5 + 7 * x , r = 1 , r = 0)

15
Redex. Reguli structurale. Axiome

• Expresie reductibilă (redex)


• Fragmentul de sintaxă care va fi procesat la pasul următor
if (0 <= 5 + 7 * x , r = 1 , r = 0)

15
Redex. Reguli structurale. Axiome

• Expresie reductibilă (redex)


• Fragmentul de sintaxă care va fi procesat la pasul următor
if (0 <= 5 + 7 * x , r = 1 , r = 0)
• Reguli structurale
• Folosesc la identificarea următorului redex
• Definite recursiv pe structura termenilor

15
Redex. Reguli structurale. Axiome

• Expresie reductibilă (redex)


• Fragmentul de sintaxă care va fi procesat la pasul următor
if (0 <= 5 + 7 * x , r = 1 , r = 0)
• Reguli structurale
• Folosesc la identificarea următorului redex
• Definite recursiv pe structura termenilor

⟨b , σ⟩ → − ⟨b ′ , σ⟩
⟨if (b , bl 1 , bl 2 ) , σ⟩ →
− ⟨if (b ′ , bl 1 , bl 2 ) , σ⟩

15
Redex. Reguli structurale. Axiome

• Expresie reductibilă (redex)


• Fragmentul de sintaxă care va fi procesat la pasul următor
if (0 <= 5 + 7 * x , r = 1 , r = 0)
• Reguli structurale
• Folosesc la identificarea următorului redex
• Definite recursiv pe structura termenilor

⟨b , σ⟩ → − ⟨b ′ , σ⟩
⟨if (b , bl 1 , bl 2 ) , σ⟩ →
− ⟨if (b ′ , bl 1 , bl 2 ) , σ⟩

• Axiome
• Realizează pasul computat, ional

15
Redex. Reguli structurale. Axiome

• Expresie reductibilă (redex)


• Fragmentul de sintaxă care va fi procesat la pasul următor
if (0 <= 5 + 7 * x , r = 1 , r = 0)
• Reguli structurale
• Folosesc la identificarea următorului redex
• Definite recursiv pe structura termenilor

⟨b , σ⟩ → − ⟨b ′ , σ⟩
⟨if (b , bl 1 , bl 2 ) , σ⟩ →
− ⟨if (b ′ , bl 1 , bl 2 ) , σ⟩

• Axiome
• Realizează pasul computat, ional

⟨if (true, bl 1 , bl 2 ) , σ⟩ →
− ⟨bl 1 , σ⟩

15
Semantica expresiilor aritmetice

• Semantica unui întreg este o valoare


• nu poate fi redex, deci nu avem regulă

• Semantica unei variabile


(Id) ⟨x , σ⟩ →
− ⟨i , σ⟩ dacă σ(x ) = i
• Semantica adunării a două expresii aritmetice
(Add) ⟨i1 + i2 , σ⟩ →
− ⟨i , σ⟩ dacă i1 + i2 = i
⟨a1 , σ⟩ →
− ⟨a1′ , σ⟩
⟨a1 + a2 , σ⟩ →
− ⟨a1′ + a2 , σ⟩
⟨a2 , σ⟩ →
− ⟨a2′ , σ⟩
⟨a1 + a2 , σ⟩ →
− ⟨a1 + a2′ , σ⟩
Observatie: ordinea de evaluare a argumentelor este
nespecificată.

16
Semantica expresiilor booleene

• Semantica operatorului de comparat, ie


(Leq-false) ⟨i1 =< i2 , σ⟩ →
− ⟨false , σ⟩ dacă i1 > i2
(Leq-true) ⟨i1 =< i2 , σ⟩ →
− ⟨true , σ⟩ dacă i1 ≤ i2

⟨a1 , σ⟩ →
− ⟨a1′ , σ⟩ ⟨a2 , σ⟩ →
− ⟨a2′ , σ⟩
⟨a1 =< a2 , σ⟩ →
− ⟨a1′ =< a2 , σ⟩ ⟨a1 =< a2 , σ⟩ →
− ⟨a1 =< a2′ , σ⟩

• Semantica negat, iei


(!-false) ⟨not(true) , σ⟩ →
− ⟨false , σ⟩
(!-true) ⟨not(false) , σ⟩ →
− ⟨true , σ⟩

⟨a , σ⟩ →− ⟨a ′ , σ⟩
⟨not (a ) , σ⟩ →
− ⟨not (a ′ ) , σ⟩

17
Semantica expresiilor booleene

• Semantica s, i-ului

(And-false) ⟨and (false, b2 ) , σ⟩ →


− ⟨false , σ⟩
(And-true) ⟨and (true, b2 ) , σ⟩ →
− ⟨b2 , σ⟩

⟨b1 , σ⟩ →− ⟨b1′ , σ⟩
⟨and (b1 , b2 ) , σ⟩ →
− ⟨and (b1′ , b2 ) , σ⟩

18
Semantica compunerii s, i a blocurilor

• Semantica blocurilor
(Block) ⟨{ s } , σ⟩ →
− ⟨s , σ⟩

• Semantica compunerii secvent, iale


(Next-stmt) ⟨skip; s2 , σ⟩ →
− ⟨s2 , σ⟩
⟨s1 , σ⟩ →
− ⟨s1′ , σ′ ⟩
⟨s1 ; s2 , σ⟩ →
− ⟨s1′ ; s2 , σ′ ⟩
• Semantica atribuirii

(Asgn) ⟨x = i , σ⟩ →
− ⟨skip , σ′ ⟩ dacă σ′ = σx ←i
⟨a , σ⟩ →
− ⟨a ′ , σ⟩
⟨x = a , σ⟩ →
− ⟨x = a ′ , σ⟩

19
Semantica lui if

• Semantica lui if
(If-true) ⟨if (true, bl 1 , bl 2 ) , σ⟩ →− ⟨bl 1 , σ⟩
(If-false) ⟨if (false, bl 1 , bl 2 ) , σ⟩ → − ⟨bl 2 , σ⟩
⟨b , σ⟩ → − ⟨b , σ⟩

⟨if (b , bl 1 , bl 2 ) , σ⟩ →
− ⟨if (b ′ , bl 1 , bl 2 ) , σ⟩

• Semantica lui while


(While) ⟨while (b , bl ) , σ⟩ →
− ⟨if (b , bl ;while (b , bl ), skip) , σ⟩

• Semantica programelor
⟨a1 , σ1 ⟩ →− ⟨a2 , σ2 ⟩
(Pgm)
⟨(skip, a1 ) , σ1 ⟩ →
− ⟨(skip, a2 ) , σ2 ⟩
⟨s1 , σ1 ⟩ →− ⟨s2 , σ2 ⟩
⟨(s1 , a ) , σ1 ⟩ →
− ⟨(s2 , a ) , σ2 ⟩
20
Semantica small-step a lui IMP

Execut, ie pas cu pas


Asgn
⟨i = 3 ; while (0 <= i ,{ i = i + −4 }) , ⊥⟩ −−−→

21
Semantica small-step a lui IMP

Execut, ie pas cu pas


Asgn
⟨i = 3 ; while (0 <= i ,{ i = i + −4 }) , ⊥⟩ −−−→
Next-stmt
⟨skip; while (0 <= i ,{ i = i + −4 }) , i 7→ 3⟩ −−−−−−−→

21
Semantica small-step a lui IMP

Execut, ie pas cu pas


Asgn
⟨i = 3 ; while (0 <= i ,{ i = i + −4 }) , ⊥⟩ −−−→
Next-stmt
⟨skip; while (0 <= i ,{ i = i + −4 }) , i 7→ 3⟩ −−−−−−−→
While
⟨while (0 <= i ,{ i = i + −4 }) , i 7→ 3⟩ −−−−→

21
Semantica small-step a lui IMP

Execut, ie pas cu pas


Asgn
⟨i = 3 ; while (0 <= i ,{ i = i + −4 }) , ⊥⟩ −−−→
Next-stmt
⟨skip; while (0 <= i ,{ i = i + −4 }) , i 7→ 3⟩ −−−−−−−→
While
⟨while (0 <= i ,{ i = i + −4 }) , i 7→ 3⟩ −−−−→
Id
⟨if (0 <= i , i = i + −4 ;while (0 <= i , { i = i + −4 }) ,skip) , i 7→ 3⟩ −

21
Semantica small-step a lui IMP

Execut, ie pas cu pas


Asgn
⟨i = 3 ; while (0 <= i ,{ i = i + −4 }) , ⊥⟩ −−−→
Next-stmt
⟨skip; while (0 <= i ,{ i = i + −4 }) , i 7→ 3⟩ −−−−−−−→
While
⟨while (0 <= i ,{ i = i + −4 }) , i 7→ 3⟩ −−−−→
Id
⟨if (0 <= i , i = i + −4 ;while (0 <= i , { i = i + −4 }) ,skip) , i 7→ 3⟩ −

Leq-true
⟨if (0 <= 3 , i = i + −4 ;while (0 <= i , { i = i + −4 }) ,skip) , i 7→ 3⟩ −−−−−−→

21
Semantica small-step a lui IMP

Execut, ie pas cu pas


Asgn
⟨i = 3 ; while (0 <= i ,{ i = i + −4 }) , ⊥⟩ −−−→
Next-stmt
⟨skip; while (0 <= i ,{ i = i + −4 }) , i 7→ 3⟩ −−−−−−−→
While
⟨while (0 <= i ,{ i = i + −4 }) , i 7→ 3⟩ −−−−→
Id
⟨if (0 <= i , i = i + −4 ;while (0 <= i , { i = i + −4 }) ,skip) , i 7→ 3⟩ −

Leq-true
⟨if (0 <= 3 , i = i + −4 ;while (0 <= i , { i = i + −4 }) ,skip) , i 7→ 3⟩ −−−−−−→
If-true
⟨if (true, i = i + −4 ;while (0 <= i , { i = i + −4 }) ,skip) , i 7→ 3⟩ −−−−−→

21
Semantica small-step a lui IMP

Execut, ie pas cu pas


Asgn
⟨i = 3 ; while (0 <= i ,{ i = i + −4 }) , ⊥⟩ −−−→
Next-stmt
⟨skip; while (0 <= i ,{ i = i + −4 }) , i 7→ 3⟩ −−−−−−−→
While
⟨while (0 <= i ,{ i = i + −4 }) , i 7→ 3⟩ −−−−→
Id
⟨if (0 <= i , i = i + −4 ;while (0 <= i , { i = i + −4 }) ,skip) , i 7→ 3⟩ −

Leq-true
⟨if (0 <= 3 , i = i + −4 ;while (0 <= i , { i = i + −4 }) ,skip) , i 7→ 3⟩ −−−−−−→
If-true
⟨if (true, i = i + −4 ;while (0 <= i , { i = i + −4 }) ,skip) , i 7→ 3⟩ −−−−−→
Id
⟨i = i + −4 ;while (0 <= i , { i = i + −4 }) , i 7→ 3⟩ −

···

21
Semantica axiomatică
Semantica Axiomatică

• Dezvoltată de Tony Hoare în 1969


(inspirată de rezultatele lui Robert Floyd).

• Defines, te triplete (triplete Hoare) de forma


{P } C {Q }
unde:
• C este o instruct, iune

• P (precondit, ie), Q (postcondit, ie) sunt asert, iuni logice asupra stării
sistemului înaintea, respectiv după execut, ia lui C

• Limbajul asert, iunilor este un limbaj de ordinul I.

22
Semantica Axiomatică

Interpretarea unui triplet Hoare {P } C {Q }


• dacă programul se execută dintr-o stare init, ială care satisface P
• s, i execut, ia se termină
• atunci se ajunge într-o stare finală care satisface Q.

23
Semantica Axiomatică

Interpretarea unui triplet Hoare {P } C {Q }


• dacă programul se execută dintr-o stare init, ială care satisface P
• s, i execut, ia se termină
• atunci se ajunge într-o stare finală care satisface Q.

Exemple:

• {x = 1} x = x+1 {x = 2} este corect


• {x = 1} x = x+1 {x = 3} nu este corect
• {⊤} if (x <= y) z = x; else z = y; {z = min(x, y)} este
corect

23
Logica Hoare ne ajută să verificăm corectitudinea programelor

• Se asociază fiecărei construct, ii sintactice o regulă de deduct, ie


care defines, te recursiv tripletele corecte pentru un limbaj.

• Se exprimă o asert, iune de corectitudine a programului ca un


tripet Hoare

• Se verifică dacă tripletul dat e corect folosind definit, ia recursivă

24
Sistem de reguli pentru logica Floyd-Hoare

Reguli generale pentru logică propozit, ională


P1 → P2 {P2} C {Q2} Q2 → Q1
(→)
{P1} C {Q1}

{P1} C {Q } {P2} C {Q }
(∨)
{P1 ∨ P2} C {Q }

{P } C {Q1} {P } C {Q2}
(∧)
{P } C {Q1 ∧ Q2}

25
Logica Floyd-Hoare pentru IMP1

(Skip)
{P } {} {P }

{P } C1 {Q } {Q } C2 {R }
(Seq)
{P } C1 ; C2 {R }

(Asign)
{P [x /e ]} x = e {P }

{B ∧ P } C1 {Q } {¬B ∧ P } C2 {Q }
(If)
{P } if (B) C1 else C2 {Q }

{B ∧ P } C {P }
(While)
{P } while (B) C {¬B ∧ P }

26
Regula pentru atribuire

(Asign)
{P [x /e ]} x = e {P }

Exemplu:

{x + y = y + 10} x = x + y {x = y + 10}

27
Regula pentru condit, ii

{B ∧ P } C1 {Q } {¬B ∧ P } C2 {Q }
(If)
{P } if (B) C1 else C2 {Q }

Exemplu:

Pentru a demonstra
{⊤} if (x <= y) z = x; else z = y; {z = min(x, y)}
este suficient să demonstrăm

• {x ≤ y} z = x {z = min(x, y)}
• {¬(x ≤ y)} z = y {z = min(x, y)}

28
Invariant, i pentru while

Cum demonstrăm {P } while(B) C {Q } ?

Se determină un invariant I s, i se foloses, te următoarea regulă:

P→I {B ∧ I} C {I} (I ∧ ¬B) → Q


(Inv)
{P } while (B) C {Q }

Invariantul trebuie să satisfacă următoarele proprietăt, i:

• să fie adevărat init, ial


• să rămână adevărat după execut, ia unui ciclu
• să implice postcondit, ia la ies, irea din buclă

29
Invariant, i pentru while

{x = 0 ∧ 0 ≤ n ∧ y = 1}

while (x < n) { x = x + 1; y = y * x}

{y = n!}

30
Invariant, i pentru while

{x = 0 ∧ 0 ≤ n ∧ y = 1}

while (x < n) { x = x + 1; y = y * x}

{y = n!}

• Invariantul I este y = x !

30
Invariant, i pentru while

{x = 0 ∧ 0 ≤ n ∧ y = 1}

while (x < n) { x = x + 1; y = y * x}

{y = n!}

• Invariantul I este y = x !
• (x = 0 ∧ 0 ≤ n ∧ y = 1) → I
• {I ∧ (x < n)} x = x + 1; y = y * x { I }
• I ∧ ¬(x < n) → (y = n!)

30
Pe data viitoare!

31

S-ar putea să vă placă și