Documente Academic
Documente Profesional
Documente Cultură
Limbaje Form Autom
Limbaje Form Autom
Facultatea de Matematică-Informatică
Platforma BLACKBOARD
Codul cursului:
Denumirea cursului: Limbaje formale si automate
Tip curs: Obligatoriu
Durata cursului / Nr. Credite: semestrul 1 / 4 credite
Perioada de accesare a cursului: 1 oct 2006 - 1 oct 2007
Manualul recomandat:
G. Albeanu, Limbaje formale si automate, Editura FRM, 2005
Obiectivul principal al cursului: Dobandirea de cunostinte si competenţe privind
generarea şi recunoaşterea limbajelor, operaţiile cu limbaje si analiza sintactica.
Modul de stabilire a notei finale: 6u x 3p + 10m x 5p + 4d x 8p = 100p. In final se
imparte numărul de puncte la 10 şi se rotujeşte la întreg.
ZI - Verificare, se ia în considerare şi activitatea desfăsurată la seminar (50%)
FR,ID - examen la calculator (6 întrebări uşoare, 10 întrebări de nivel mediu şi
4 întrebări dificile) cu ponderile de mai sus.
Consultaţii pentru studenţi: Marţi, 7.30-16
Adrese e-mail responsabil pentru contactul cu studenţii: info@spiruharet.ro
Titularul/titularii cursului / serie: ZI, FR, ID
Prof. Univ. Dr. Albeanu Grigore
galbeanu@fmi.unibuc.ro
Str. Ion Ghica, Facultatea de matematică-informatică
7.30-16
Definiţia 1.1 [Alfabet] Un alfabet este o mulţime finită şi nevidă ale cărei elemente
sunt numite simboluri (litere).
Notaţie Alfabetele se vor nota prin semne precum: V, VN, VT, Σ etc.
Definiţia 1.2 [Cuvânt] Fie Σ = {a1, a2, ..., an} un alfabet, unde n este un număr natural
nenul (n ≥ 1). Orice secvenţă x = ai1ai2...air, aij ∈ Σ, 1 ≤ j ≤ r, se numeşte cuvânt (şir,
frază) peste Σ. Lungimea cuvântului x se notează cu |x| şi este egală cu r. Convenim să
considerăm şi cuvântul “format” cu zero simboluri pe care-l notăm cu λ şi îl numim
cuvântul vid sau şirul nul.
Notaţii Mulţimea tuturor cuvintelor peste Σ se notează cu Σ*, iar mulţimea tuturor
cuvintelor nenule, Σ*-{λ}, se notează cu Σ+.
b) Σ+ = UΣ k
.
k ≥1
Definiţia 1.3 Orice submulţime L de cuvinte peste Σ, L ⊆ Σ*, se numeşte limbaj peste
Σ.
Definiţia 1.4 [Concatenarea, Produsul] Fie L1 (peste Σ1) şi L2 (peste Σ2) limbaje .
Atunci L1L2 = {uv| u ∈L1, v ∈L2 } se numeşte concatenarea sau produsul limbajelor
L1 şi L2.
Observaţia 1.4 Dacă L este un limbaj λ-liber (nu conţine cuvântul vid) atunci L+=L*-{λ}.
Notaţii Pentru un şir y ∈Σ*, notăm prin Sub(y), Pref(y), Suf(y) mulţimea
subcuvintelor, prefixelor şi, respectiv, a sufixelor cuvântului y.
Definiţia 1.7 [Extinderea operaţiilor Sub, Pref şi Suf asupra limbajelor] Fie L ⊆Σ*.
Atunci
Sub(L) = U Sub( x) ; Pref(L) = U Pref ( x) ; Suf(L) = U Suf ( x) .
x∈L x∈L x∈L
Observaţia 1.5 În mod similar, se poate defini răsturnatul (oglinditul) limbajului L.
Definiţia 1.8 [Substituţia] Fie ansamblul (U, V, s), unde U, V sunt alfabete, iar s : V
→ P(U*) este o aplicaţie oarecare. Aplicaţia s extinsă la V* prin s(λ)={λ},
s(xy)=s(x)s(y), x, y ∈ V*, iar apoi la limbaje, se numeşte substituţie.
Propoziţia 1.2 [Σ* este mulţime numărabilă] Dacă Σ este un alfabet, atunci Σ* este
mulţime numărabilă.
Definiţia 1.10 [Mulţimi închise la operaţii] Fie U o mulţime univers şi funcţia f : U →
U. O mulţime A ⊆ U este închisă faţă de f, sau în raport cu f, dacă şi numai dacă
pentru oricare x ∈ A rezultă f(x) ∈ A.
Propoziţia 1.3 [Închiderea unei mulţimi B în raport cu o operaţie f – cea mai mică
mulţime închisă la operaţia f şi care conţine mulţimea B]. Fie mulţimea univers U,
funcţia f : U → U şi B ⊆ U . Construim, în mod inductiv, şirul de mulţimi:
A0 = B; Ak+1 = Ak ∪ {f(x) | x ∈ Ak}, k ∈ N şi A = U Ak . Atunci:
k∈N
a) A este închisă faţă de f;
b) Dacă mulţimea C este astfel încât B ⊂ C ⊆ U şi este închisă faţă de f atunci A⊆C.
Definiţia 1.11 [Mulţimi regulate] Fie Σ un alfabet. Familia mulţimilor regulate peste
Σ este definită recursiv astfel:
(1) (∀L) ((L⊆Σ* şi card L < ∞) ⇒ L este mulţime regulată peste Σ). Se includ
aici mulţimea vidă şi mulţimea formată doar cu şirul nul λ.
(2) Dacă A şi B sunt mulţimi regulate peste Σ atunci A∪B (reuniunea) şi AB
(produsul) sunt mulţimi regulate peste Σ.
(3) Dacă A este mulţime regulată peste Σ atunci A* este mulţime regulată peste
Σ.
(4) Singurele mulţimi regulate peste Σ sunt cele obţinute prin aplicarea regulilor
1)-3).
Definiţia 1.13 [Limbajul unei expresii regulate numit şi limbaj regulat] Fie r o
expresie regulată peste alfabetul Σ. Limbajul L(r), desemnat de expresia r, este obţinut
astfel: L(∅) = ∅; L(λ)={λ}, L(a) = {a}; L(r+s)=L(r)∪L(s); L(rs)=L(r)L(s) şi L(r*)
=(L(r))*.
Observaţia 1.7
a) Dacă presupunem că ordinea operaţiilor (pe baza priorităţii de aplicare) este
*, ., + atunci se poate renunţa la paranteze.
b) Din definţia expresiilor regulate, rezultă că o mulţime este regulată peste Σ
dacă şi numai dacă coincide cu limbajul unei expresii regulate peste Σ.
c) Pentru o mulţime regulată pot exista mai multe expresii regulate echivalente.
Două expresii regulate r1 şi r2 sunt echivalente (scriem r1 ∼ r2) dacă şi numai
dacă L(r1) = L(r2).
Definiţia 2.2 [Generare (derivare) directă, lungimea unei derivări] Fie SR = (V, P),
iar α şi β cuvinte peste V. Atunci:
a) α generează direct β (şi se notează α → β) dacă şi numai dacă există
şirurile u, v, x şi y astfel încât u ∈ Pref(α) ∩ Pref(β), v ∈ Suf(α) ∩ Suf(β), α
= uxv, β = uyv, iar (x, y) ∈ P.
b) α generează1 β (şi se notează α →
*
β) dacă şi numai dacă există cuvintele
peste V, α0 = α, α1, α2, …, αk-1, αk = β, k ≥ 0, iar αi generează direct αi+1, 0
≤ i ≤ k-1.
Se spune că şirul α0, α1, α2, …, αk-1, αk formează o derivare pentru β pornind de
la şirul α. Numărul k este lungimea derivării.
sunt valabile şi pentru cuvintele peste Ω ∪ Σ. Orice cuvânt peste Ω ∪ Σ care poate fi
generat din S, se numeşte formă propoziţională în gramatica G. Fie FP(G) mulţimea
formelor propoziţionale ale lui G. Limbajul generat de gramatica G este L(G) = {w |
w ∈ Σ*, S →
*
w}, adică L(G) = FP(G) ∩ Σ*.
Notaţie Dacă sunt mai multe reguli cu acelaşi cuvânt în partea stângă: (p, q1), (p, q2),
…, (p, qm), atunci convenim să notăm această submulţime de reguli (sau p-reguli) sub
forma: p ::= q1 | q2 | … | qm. De asemenea, notăm prin V mulţimea tuturor
simbolurilor gramaticii G, adică V = Ω ∪ Σ.
Prin
→ s-a notat închiderea reflexivă şi tranzitivă a relaţiei binare →.
1 *
2
O pereche (p, q) se numeşte regulă de rescriere sau producţie; p reprezintă membrul stâng, iar q este
membrul drept al producţiei (p, q).
Observaţia 2.1 Ansambul SR = (Ω ∪ Σ, P) este un sistem de rescriere pentru limbajul
L(G) pornind de la şirul S. Metoda de generare pentru L(G) poate fi specificată prin
structura (SR, {S}, Σ).
Propoziţia 2.2 Pentru orice gramatică de tip 2, G = (Ω, Σ, S, P), există o gramatică
echivalentă G’ = (Ω’, Σ, S, P’), de tip 2, în care toate producţiile lui P’ care conţin
terminale sunt de forma A ::= a, a ∈ Σ.
Propoziţia 2.4 Fie G o gramatică liniară la stânga, există o gramatică liniară la stânga
G’ astfel încât L(G’) = L(G), iar regulile gramaticii G’ sunt numai de forma A ::= Ba
şi A ::= a, unde A, B ∈ Ω, iar a ∈ Σ ∪ {λ}.
Propoziţia 2.5 Fie G o gramatică în care producţiile sunt de forma A ::= Ba şi A ::= a.
Atunci există o gramatică G’ echivalentă cu G pentru care producţiile sunt de forma A
::= aB şi A ::= a.
Observaţia 2.3 Propoziţiile anterioare arată echivalenţa dintre gramaticile liniare la
stânga şi cele liniare la dreapta. Nu trebuie crezut că dacă o gramatică are pe lângă
reguli de tipul A ::= a, atât reguli de forma A ::= aB, cât şi reguli de forma C ::= Db,
ea va fi echivalentă cu o gramatică liniară la stânga (sau la dreapta). De exemplu,
gramatica cu regulile { S ::= aA | aB; A ::= Sb; B ::= b} generează un limbaj de tip 2
şi nu unul de tip 3 aşa cum ar părea la prima vedere.
Atât pentru gramatici independente de context cât şi pentru gramatici liniare (la stânga
sau la dreapta) modul prin care o formă propozitională poate fi obţinută, prin derivare,
poate fi reprezentat grafic cu ajutorul structurilor arborescente.
Fie D = (X, A) un digraf (graf orientat): dacă (x, y) ∈ A atunci x este
predecesorul lui y, iar y este succesorul lui x. Arborii ordonaţi sunt digrafuri conexe
şi fără circuite cu proprietăţile:
a) Există, în D, un unic nod, numit rădăcină care nu are predecesori şi de la
care există un drum la fiecare nod al digrafului;
b) Orice nod, altul decât rădăcina, are exact un predecesor;
c) Mulţimea succesorilor oricărui nod este ordonată.
Arborii orientaţi se desenează cu rădăcina în sus, iar ordinea succesorilor unui nod
este de la stânga la dreapta. Se înţelege că sensul arcelor este de sus în jos; astfel nu
mai este nevoie de săgeţi. Nodurile cu descendenţi din D sunt noduri interioare, iar
celelalte se numesc noduri terminale sau frunze.
Definiţia 2.7 [Arbore de derivare] Fie G = (Ω, Σ, S, P) o gramatică de tip cel puţin 2.
Un arbore de derivare pentru G este un arbore ordonat D = (X, A) împreună cu o
funcţie de etichetare f : X → Ω ∪ Σ ∪ {λ} cu proprietăţile:
1) f(r) = S, dacă r este rădăcina arborelui;
2) Dacă x ∈ X atunci f(x) ∈ Ω;
3) Dacă x are descendenţii x1, x2, …, xn, în această ordine, atunci P conţine
regula de rescriere f(x) ::= f(x1)f(x2)…f(xn).
4) Dacă f(x) = λ, x nu are descendenţi (este frunză).
Observaţia 2.6 Orice gramatică independentă de context care conţine, printre regulile
sale de rescriere, producţii de unul din tipurile (1)-(4), cu neterminalul A util in
generarea de cuvinte peste Σ, este ambiguă: (1) A ::= AA; (2) A ::= AγA; (3) A ::=
αA | Aβ; (4) A ::= αA | αAβA.
Un limbaj, în general, poate fi generat de către foarte multe gramatici distincte. Pentru
aplicaţii practice trebuie utilizate gramatici cât mai simple. În cele ce urmează se
consideră complexitatea statică a gramaticilor (mărimea şi structura gramaticilor.)
3
În unele publicaţii se omite cuvântul “extrem”, folosindu-se noţiunile de derivare stânga (resp.
dreapta) în acepţiunea definiţiei 2.8.
Definiţia 2.11 [Măsurarea complexităţii sintactice] Fie G o clasă de gramatici şi fie
L(G) familia limbajelor generate de gramaticile din clasa G. O măsură a complexităţii
gramaticilor din clasa G este o aplicaţie ψ : G → N. Complexitatea sintactică a
limbajelor din familia L(G) este
ψ(L) = min { ψ(G) | L = L(G), G ∈ G}, L ∈ L(G).
Fie x ∈ L(G) şi D(x) mulţimea derivărilor lui x din S, în gramatica G. Indexul şirului
x în raport cu gramatica G este
Index (x, G) = min Index(D, G).
D∈D ( x )
4
Această gramatică este echivalentă cu o gramatică G’ independentă de context (după eliminare λ-
producţiilor).
3. Mecanisme pentru recunoaşterea automată a
mulţimilor regulate
Definiţia 3.1 [AFD] Un sistem AFD (automat finit determinist) este o structură M =
(Q, Σ, δ, q0, F) unde: Q este o mulţime finită şi nevidă de elemente numite stări; Σ
este un alfabet (numit, de intrare); δ : QxΣ → Q este o funcţie parţială (parţial
definită), numită funcţie de tranziţie; q0 ∈ Q este starea iniţială a automatului M şi F
⊆ Q este o mulţime nevidă, numită mulţimea stărilor finale.
Observaţia 3.1 [Diagrama de tranziţie] Unui sistem AFD i se poate asocia un digraf
(o diagramă de tranziţie) astfel:
• nodurile digrafului sunt stările automatului (corespund elementelor mulţimii
Q);
• dacă δ(q, a) = p atunci, în digraf, există un arc de la nodul q la nodul p,
etichetat cu simbolul a;
• digraful nu conţine alte noduri şi alte arce în afara celor specificate mai sus.
Propoziţia 3.1 Cu notaţiile de mai sus, δ(q, uv) = δ(δ(q,u), v), pentru oricare u, v ∈
Σ*.
Definiţia 3.3 [Limbaj acceptat de sisteme AFD] Fie M =(Q, Σ, δ, q0, F) un AFD.
Limbajul acceptat de M, notat L(M), este: L(M) = {u | u ∈Σ*, δ(q0, u) ∈ F}.
Definiţia 3.4 [AFN] Un sistem AFN (automat finit nedeterminist) este o structură N =
(Q, Σ, δ, q0, F), unde Q, Σ, q0 şi F au semnificaţia din definiţa 3.1, iar δ : QxΣ →
P(Q), unde P(Q) reprezintă mulţimea submulţimilor lui Q (adesea notată prin 2Q).
Definiţia 3.6 [Limbaj acceptat de sisteme AFN] Fie N un sistem AFN ca în definiţia
3.4. Limbajul acceptat de N este: L(N) = {w | w ∈ Σ*, δ(q0, w) ∩ F ≠ ∅}.
Propoziţia 3.3 Fie L un limbaj acceptat de un AFN. Atunci există un AFD, notat cu
M, astfel încât L(M) = L.
Propoziţia 3.4 Fie L un limbaj peste Σ acceptat de un sistem tranziţional, notat cu λN.
Atunci există un AFN, notat cu N, astfel încât L(N) = L (= L(λN)). Reciproca este, în
mod banal, adevărată.
3.5 Sistemele AFN şi expresiile regulate
Propoziţia 3.5 Fie r o expresie regulată. Atunci există un AFN care recunoaşte
limbajul L(r).
Propoziţia 3.6 Dacă L este un limbaj acceptat de un AFD atunci L este o mulţime
regulată.
Teorema 3.2 Un limbaj este regulat dacă şi numai dacă este recunoscut de un AFN
(deci şi de un AFD).
Teorema 3.3 [Kleene] Familia limbajelor regulate este cea mai mică familie de
limbaje care conţine limbajele finite şi este închisă la reuniune, produs (concatenare)
şi la operaţia * (închiderea Kleene).
4. Optimizarea automatelor finite
Definiţia 4.1 [Stări accesibile, stări utile] Fie M = (Q, Σ, δ, q0, F) un AFD. O stare q
∈ Q este accesibilă din q0 dacă există un cuvânt w ∈Σ* astfel încât δ(q0, w) = q. O
stare se numeşte inaccesibilă dacă nu este accesibilă. O stare q este utilă dacă există
un cuvânt w ∈ Σ* astfel încât δ(q, w) ∈ F. O stare este inutilă dacă nu este utilă.
Intrare: Q, Σ, q0, δ, F
Ieşire: Q’ – mulţimea stărilor accesibile
SEQ
1. i := 0; S0 := {q0};
2. do {Si+1 := Si ∪{δ(s, a) | s ∈ Si, a ∈ Σ}; i = i+1; }while(Si – Si-1 ≠ ∅);
3. Q’ = Si.
END.
Propoziţia 4.1
Cu notaţiile de mai sus, următoarele afirmaţii sunt adevărate:
a) q este stare accesibilă dacă şi numai dacă q ∈ Q’;
b) Dacă |Q| = m, iar |Σ| = n, atunci complexitatea algoritmului 4.1 este O(mn).
Algoritmul 4.2 [Determinarea stărilor utile2] Prin aplicarea strategiei greedy, putem
obţine un şir ascendent de mulţimi cu stări utile, majorat în sensul relaţiei de
incluziune de mulţimea stărilor automatului considerat.
Fie U0 = F. Pentru i ≥ 0, formăm Ui+1 = Ui ∪ {q ∈ Q - Ui| există a ∈ Σ astfel
încât δ(q, a) ∈ Ui}.
Este clar că trebuie să existe k0, k0 ≤ |Q| astfel încât Uk0 = Uk0+1, k0 fiind cel mai
mic număr natural cu această proprietate; în aceste condiţii Uk0+j = Uk0, oricare j≥1.
Mulţimea stărilor utile este Uk0.
1
Problema determinării stărilor accesibile este echivalentă cu problema determinării vârfurilor unui
digraf care sunt legate prin cel puţin un drum de vârful care corespunde stării q0. Dacă se determină
matricea existenţei drumurilor sau, echivalent, închiderea tranzitivă a relaţiei binare asociată diagramei
de tranziţie (de exemplu, folosind algoritmul Roy-Warshal) atunci stările accesibile corespund valorii 1
în linia stării q0 din matricea existenţei drumurilor.
2
În unele lucrări, stările utile sunt denumite stări observabile.
Intrare: Q, Σ, q0, δ, F
Ieşire: U’ – mulţimea stărilor utile
SEQ
1. i := 0; U0:= F;
2. do {
for a ∈ Σ do for q ∈ Q - Ui do if δ(q, a) ∈ Ui then Ui+1 = Ui ∪ {q};
i = i +1;
}while(Ui – Ui-1 ≠ ∅);
3. U’ = Ui.
END.
Propoziţia 4.2
Cu notaţiile de mai sus, următoarele afirmaţii sunt adevărate:
a) q este stare utilă dacă şi numai dacă q ∈ U’;
b) Dacă |Q| = m, iar |Σ| = n, atunci complexitatea algoritmului 4.2 este O(mn).
3
Clasa de echivalenţă a unui element x este formată din totalitatea elementelor echivalente cu x.
2 ⇒ 3. Se verifică uşor că ρL este o relaţie de echivalenţă invariantă la dreapta, de
rang finit.
Teorema 4.2 Automatul M’ construit anterior (în demonstraţia teoremei 4.1) este
automatul minimal care acceptă limbajul L şi el este unic până la o redenumire a
stărilor (un izomorfism).
Definiţia 4.3 [Relaţia ≡] Fie M = (Q, Σ, δ, q0, F) un AFD. Definim, pe mulţimea
stărilor, o relaţie de echivalenţă, notată ≡, astfel: Dacă p, q ∈Q atunci p ≡ q dacă şi
numai dacă pentru oricare w ∈ Σ* avem echivalenţa: δ(p, w) ∈ F ⇔ δ(q, w) ∈ F.
Paşii:
1. Se marchează toate perechile (p, q), p ∈ F, q ∈ Q - F; S1 = F, S2 = Q - F.
2. Pentru fiecare pereche (p, q) ∈ SxS, unde S = S1 sau S = S2, p ≠ q, execută
A. Dacă există a ∈ Σ astfel încât (δ(p, a), δ(q, a)) este marcată atunci :
i) se marchează (p, q);
ii) se marchează, recursiv, toate perechile din lista lui (p, q) şi din
listele altor perechi marcate la acest pas.
B. Dacă pentru oricare a ∈ Σ, perechea (δ(p, a), δ(q, a)) nu este marcată
atunci, pentru oricare a ∈ Σ, se adaugă (p, q) în lista perechii (δ(p, a),
δ(q, a)) ori de câte ori δ(p, a) ≠ δ(q, a).
Observaţia 4.3 Odată găsite perechile de stări echivalente se poate construi automatul
minimal care acceptă limbajul supus discuţiei.
Fie M’=(Q’, Σ, δ’, [q0], F’) unde prin [q] notăm clasa de echivalenţă relativ la
relaţia ≡ care are ca reprezentant starea q. Celelalte elemente sunt: Q’ = {[q] | q este
stare accesibilă din q0}, F’ = {[q] | q ∈ F}, δ’([q], a)= [δ(q, a)], oricare [q] ∈ Q’şi
oricare a ∈ Σ.
Teorema 4.3 [Lema de pompare] Fie L un limbaj regulat. Există atunci un număr
natural n astfel încât pentru orice cuvânt w ∈ L, |w| ≥ n, w = xyz cu proprietăţile:
a) |xy| ≤ n;
b) |y| ≥ 1;
c) xyiz ∈ L pentru oricare i ≥ 0.
Propoziţia 4.4 Fie L un limbaj acceptat de un AFD cu n stări. Atunci L este infinit ⇔
există w ∈ L, n ≤ |w| < 2n.
Algoritmul 4.4 Fie L un limbaj acceptat de un AFD cu n stări. Pentru a verifica dacă
L ≠ ∅, se poate aplica următorul algoritm, cu complexitatea mult mai mică decât
metoda furnizată prin propoziţia 4.3.
Intrare: Q, Σ, q0, δ, F
Ieşire: “DA” dacă L este nevid; “NU” în caz contrar.
SEQ
1. i := 0; S0:= {q0};
2. do {Si+1 := Si ∪{δ(s, a) | s ∈ Si, a ∈ Σ}; i = i + 1;} while(Si – Si-1 ≠ ∅);
3. if Si ∩ F = ∅ then write “NU”; else write “DA”.
END.
Se observă că mulţimea Si, de la pasul 3, conţine stările accesibile. Este clar că dacă
nici o stare finală nu este accesibilă atunci limbajul L este vid.
Algoritmul 4.5 Fie L un limbaj acceptat de un AFD cu n stări. Pentru a verifica dacă
L ≠ ∅, se poate aplica următorul algoritm, cu complexitatea mult mai mică decât
metoda furnizată prin propoziţia 4.4.
Intrare: Q, Σ, q0, δ, F
Ieşire: “DA” dacă L este infinit; “NU” în caz contrar.
SEQ
1. i := 0; S0:= {q0};
2. do {Si+1 := Si ∪{δ(s, a) | s ∈ Si, a ∈ Σ}; i = i + 1; }while(i < n);
3. do{
if Si ∩ F ≠ ∅ then write “DA”; stop.
Si+1 := Si ∪{δ(s, a) | s ∈ Si, a ∈ Σ}; i = i + 1;
}while(i < 2n);
4. write “NU”.
END.
5. Transformări asupra gramaticilor formale
Definiţia 5.1 [Limbaj de tip i (i = 1, 2, 3)] Limbajul L este de tip i (i = 1, 2, 3), dacă
limbajul L – {λ} este generat de o gramatică de tipul i (i = 1, 2, 3).
Definiţia 6.2 [FNG] O gramatică G = (Ω, Σ, S, P), fără λ-producţii şi fără redenumiri,
este în forma normală Greibach (FNG) dacă P conţine producţii numai de forma A
::= aW, pentru A ∈ Ω, a ∈ Σ şi W ∈ (Ω∪Σ)*.
Lema 6.1 Fie gramatica proprie G = (Ω, Σ, S, P) şi A ::= α1Bα2 o A-producţie şi B ::=
β1 | β2 | … βk toate B-producţiile din mulţimea P. Considerăm G1 = (Ω, Σ, S, P1) unde
P1 = (P – {A ::= α1Bα2}) ∪ {A ::= α1β1α2 | α1β2α2 |… | α1βkα2 }. Atunci G şi G1 sunt
gramatici echivalente.
Lema 6.2 Fie gramatica fără λ-producţii şi numai cu simboluri utilizabile, G = (Ω, Σ,
S, P) şi A ::= Aα1 | Aα2 … | Aαk toate A-producţiile recursive la stânga şi A ::= β1 |
β2 | … βm restul A-producţiilor din mulţimea P. Fie X un simbol nou, X ∉ Ω ∪ Σ, Ω1
= Ω ∪ {X} şi gramatica G1 = (Ω1, Σ, S, P1), unde P1 se obţine din P prin înlocuirea
tuturor A-producţiilor cu regulile: A ::= β1 | β2 | … βm, A ::= β1X | β2X | … βmX şi X
::= α1 | α2 … | αk, X ::= α1X | α2X … | αkX.
Atunci G şi G1 sunt echivalente.
Teorema 6.3 Fie G = (Ω, Σ, S, P) o gramatică proprie. Atunci există gramatica G*, în
forma normală Greibach, echivalentă cu G.
SEQ
1. P* := P1; i := m;
2. while i > 1 do
SEQ
i := i - 1;
while (există j, i < j ≤ m, Ai ::= Ajα în P*) do
P* := (P* - {Ai ::= Ajα}) ∪ {Ai ::= βα | Aj ::= β ∈ P*}
END
3. for indici i ai simbolurilor Y do
while (există j, 1 ≤ j ≤ m, Yi ::= Ajα ∈ P*) do
P* := (P* - { Yi ::= Ajα }) ∪ {Yi ::= βα | Aj ::= β ∈ P*}
END.
Propoziţia 6.1 Fie G o gramatică independentă de context. Atunci L(G) este infinit
dacă şi numai dacă există w ∈ L(G) astfel încât p < |w| ≤ p + q, unde p şi q sunt
numerele furnizate de teorema 6.4.
7. Gramatici şi automate
Teorema 7.3 Pentru orice limbaj regulat L există o gramatică liniară G astfel încât
L=L(G).
Un automat pushdown (cu memorie locală gestionată prin disciplina LIFO [eng. Last
In First Out] – numită memorie pushdown) citeşte banda de intrare (de la stânga la
dreapta) folosind un număr de stări interne (ca şi un AFD sau AFN), dar tranziţia, în
general nedeterministă, se face nu numai în raport cu starea anterioară şi informaţia
curentă de pe banda de intrare, ci şi în funcţie de cea mai recentă informaţie stocată în
memoria auxiliară (prelucrată ca o stivă de capacitate infinită).
Definiţia 7.1 [APD] Un automat pushdown (APD) este un sistem M = (Q, Σ, Γ, δ, q0,
Z0, F) unde Q, Σ, q0, şi F au semnificaţiile cunoscute, Γ este o mulţime finită şi nevidă
de simboluri care formează alfabetul pushdown, Z0 ∈ Γ este simbolul pushdown
iniţial, iar δ este funcţia de tranziţie δ : Qx(Σ ∪ {λ})xΓ → P(QxΓ*).
Definiţia 7.2 [Configuraţie] Fie M = (Q, Σ, Γ, δ, q0, Z0, F) un APD. Orice triplet (q,
w, α) ∈ QxΣ*xΓ* se numeşte configuraţie a automatului M. Elementele configuraţiei
au următoarea semnificaţie: q este starea curentă a unităţii de comandă a automatului;
w este un cuvânt peste alfabetul de intrare Σ, inclusiv λ, care reprezintă partea necitită
de pe banda de intrare3; α reprezintă conţinutul memoriei stivă. Dacă α = λ atunci
memoria stivă este vidă.
Observaţia 7.1 Mişcarea automatului este posibilă numai dacă memoria stivă este
nevidă.
1
A se vedea şi propoziţia 2.5.
2
Din acest motiv gramaticile liniare se mai numesc şi gramatici regulate. Rezultă, de aici, că familia
limbajelor de tip 3 conţine limbajele finite şi este închisă la operaţiile de reuniune, produs şi stelare (*).
Astfel, limbajele de tip 3 sunt descriptibile cu ajutorul expresiilor regulate, generabile de gramatici
liniare şi recunoscute de sisteme tranziţionale şi deci de automate finite.
3
Capul de citire se găseşte în dreptul primului simbol al cuvântului w. Se presupune că, la dreapta,
după ultimul caracter al cuvânului w se află şirul vid λ.
Definiţia 7.4 [Închiderea reflexivă şi tranzitivă a relaţiei |-] Închiderea reflexivă şi
tranzitivă a relaţiei |-, notată prin
→
*
, se defineşte astfel:
(q1, w1, α1)
→
*
(q2, w2, α2) dacă (q1, w1, α1) = (q2, w2, α2)
sau există k configuraţii (pi, ui, βi), i = 1, 2, …, k, astfel încât (q1, w1, α1) = (p1, u1, β1),
(q2, w2, α2) = (pk, uk, βk) şi (pi, ui, βi) |- (pi+1, ui+1, βi+1), i = 1, 2, …, k-1.
Definiţia 7.5 [Cuvânt acceptat prin stare finală] Fie M = (Q, Σ, Γ, δ, q0, Z0, F) un
APD şi w ∈ Σ* un cuvânt. Atunci w este acceptat (recunoscut) de automatul M dacă
există q ∈ F şi α ∈ Γ* astfel încât (q0, w, Z0)
→
*
(q, λ, α).
Definiţia 7.6 [Limbaj acceptat prin stări finale] Fie M = (Q, Σ, Γ, δ, q0, Z0, F) un
APD. Limbajul acceptat (recunoscut) de automatul M, notat L(M), este mulţimea
tuturor cuvintelor acceptate de M prin atingerea unei stări finale.
Definiţia 7.7 [Cuvânt acceptat cu memoria pushdown vidă] Fie M = (Q, Σ, Γ, δ, q0,
Z0, F) un APD şi w ∈ Σ* un cuvânt. Atunci w este acceptat (recunoscut) de automatul
M cu memoria pushdown vidă4 dacă există q ∈ Q astfel încât (q0, w, Z0) →
*
(q, λ,
λ). Mulţimea tuturor cuvintelor acceptate de M cu memoria pushdown vidă se va nota
cu Lλ(M) şi este limbajul recunoscut de M cu memoria pushdown vidă.
Teorema 7.4 [Un limbaj recunoscut de un APD cu stări finale poate fi recunoscut şi
de un APD cu memoria pushdown vidă] Fie L(M) limbajul recunoscut de automatul
pushdown M = (Q, Σ, Γ, δ, q0, Z0, F). Atunci există un APD, notat M’=(Q’, Σ, Γ’, δ’,
qinit, X, ∅), care recunoaşte L(M) cu memoria pushdown vidă, adică Lλ(M’) = L(M).
Teorema 7.5 [Un limbaj recunoscut de un APD cu memoria pushdown vidă poate fi
recunoscut şi de un APD cu stări finale] Fie Lλ(M) limbajul recunoscut de automatul
pushdown M = (Q, Σ, Γ, δ, q0, Z0, ∅). Atunci există un APD, notat M’ = (Q’, Σ, Γ’, δ’,
qinit, X, {qf}), care recunoaşte Lλ(M) cu starea finală qf, adică Lλ(M) = L(M’).
Teorema 7.7 Pentru orice sistem APD care recunoaşte limbajul L cu memoria
pushdown vidă, există o gramatică independentă de context care generează limbajul
L.
Definiţia 7.8 [MT] O maşină Turing sau sistem MT este o structură M = (Q, Σ, Γ, δ,
q0, B, F) unde Q, Σ, q0 şi F au semnificaţia uzuală (vezi, de exemplu, sistemele AFD,
AFN sau APD), Γ este o mulţime finită şi nevidă care conţine Σ, simbolul B (cu rol
special, numit şi blanc) şi alte simboluri - întreaga mulţime Γ numindu-se alfabetul de
4
Se observă că putem alege F = ∅.
lucru, iar δ este funcţia de tranziţie definită astfel: δ : QxΓ → QxΓx{S, D} unde S, D
înseamnă stânga, respectiv dreapta.
Teorema 7.8 Pentru orice maşină Turing M există o gramatică G, de tip 0, astfel încât
L(M) = L(G).
Definiţia 7.12 [LBA] Un automat liniar mărginit sau sistem LBA (eng. Linear
Bounded Automata) este un sistem MT, nedeterminist care satisface, în plus,
următoarele două condiţii:
a) Mulţimea Σ conţine două simboluri distincte cu semnificaţie specială, notate
prin # şi $.
b) Sistemul MT nu se poate deplasa nici la stânga simbolului #, nici la dreapta
simbolului $. Mai precis: δ(q, #) = (q’, #, D) şi δ(q, $) = (q’, $, S).
Definiţia 7.13 [Limbajul acceptat de un sistem LBA] Fie M = (Q, Σ, Γ, δ, q0, B, F) un
sistem LBA. Limbajul acceptat de M, notat L(M), este definit prin:
L(M) = {w | w ∈ Σ*, există r ∈ F şi α, β ∈ Γ* astfel încât q0#w$ →*
αrβ}.
Definiţia 8.1 Fie L o familie oarecare de limbaje. Spunem că familia L este închisă la
operaţia # dacă ∀L1, ∀L2 ( L1 ∈ L şi L2 ∈ L ⇒ L1 # L2 ∈ L ).
Teorema 8.1 Familia limbajelor dependente de context este închisă faţă de reuniune.
Observaţa 8.1 Enunţul şi demonstraţia de mai sus pot fi refăcute pentru a arăta
închiderea la reuniune a familiilor L2 şi L3.
Conform teoremei 3.3, familia limbajelor regulate este cea mai mică familie de
limbaje care conţine limbajele finite şi este închisă la reuniune, produs (concatenare)
şi la operaţia * (închiderea Kleene). Trebuie remarcat că familia L 3 include strict
familia limbajelor finite.
Observaţia 8.3 Dacă L este un limbaj de tip i (i = 2 sau 3) atunci L+ este de tip i.
Observaţia 8.5 Un sistem gsm este un sistem AFN care, în plus, faţă de banda de
intrare (cuvinte peste Σ) conţine şi o bandă de ieşire (pentru manipularea cuvintelor
peste ∆). Faptul că (q2, u) ∈ δ(q1, a) arată trecerea din starea q1 in starea q2, când capul
de citire a întâlnit simbolul a, dar şi emiterea cuvântului u ∈ ∆* la ieşire. Funcţia δ se
extinde la Σ*, în mod obişnuit.
Definiţia 8.3 Fie M = (Q, Σ, ∆, δ, q0, F) un sistem gsm. Transformarea gsm definită
de M este funcţia gM : Σ* → P(∆*) definită după cum urmează. Fie u ∈ Σ* oarecare.
Atunci gM(u) = {w | w ∈ ∆*, există q ∈ F astfel încât (q, w) ∈ δ(q0, u)}.
Dacă L ⊆ Σ* atunci gM(L) = U g M (u ) . Transformarea gsm inversă este g M−1 : ∆*
u∈L
Teorema 8.10 Orice clasă de limbaje peste alfabetul Σ închisă la substituţii finite şi
intersecţie cu limbaje regulate este închisă la transformări gsm.
Limbajul C++ a fost dezvoltat la începutul anilor ’80 de către Bjarne Stroustrup de la
laboratoarele AT&T Bell. Este un supraset al limbajului C, cel care a fost creat în 1972 de
către Dennis Ritchie. C++ păstrează viteza, eficienţa şi simplitatea limbajului C pe care-l
îmbunătăţeşte şi îl completează cu support pentru abstractizarea datelor şi proiectarea
orientată obiectual. Definiţiile formale, de mai jos, definesc, parţial, sintaxa instrucţiunilor
limbajului C++ (AT&T 1997).
Doi termeni: declarare şi definire (prin definire se înţelege declarare +
iniţializare) joacă un rol important în specificarea programelor C/C++. În cazul
definiţiilor fără iniţializator, variabilele primesc valori implicite, echivalente lui 0 (0
pentru tipuri numerice, cuvântul vid (λ) pentru şiruri de caractere, valoarea NULL
pentru pointeri). Declaraţiile introduc nume în unităţile de program (blocuri/ unităţi de
translatare).
În general declaraţiile nu sunt şi definiţii. Următoarele situaţii nu constituie definiţii:
(1) Se declară o funcţie fără a-i specifica şi corpul;
(2) Declaraţia conţine specificatorul extern şi nu are iniţializare sau corp de
funcţie;
(3) Se declară un membru static într-o declaraţie de clasă;
(4) Se declară un nume de clasă;
(5) Se descrie o declaraţie typedef.
Declaraţiile pentru variabile pot specifica şi tipul legării: intern sau extern
(introdus prin intermediul clasei de memorare). De asemenea, declaraţiile sau
definiţiile pot conţine calificatori cv (const sau volatile) care definesc
modificabilitatea obiectelor precizate. Modul de aplicabilitate al calificatorilor cv
asupra pointerilor prezintă o importantă particularitate: atributul const sau volatile
prefixat cu operatorul * (dereferenţiere) se aplică pointerului şi nu obiectului punctat
de acesta.
Programele C++ sunt organizate în unităţi de translatare ce pot fi compilate
separat, urmând ca procesul editării legăturilor (eng. bind, make, link etc.), prin care
se obţine executabilul, să fie realizat ulterior.
Limbajul Prolog diferă de limbajul C++ foarte mult. Prolog este un limbaj declarativ
pentru programare logică. Face parte din clasa limbajelor de generaţia a cincea şi a
fost dezvoltat în perioada 1974-1979, la Universitatea din Marsilia. Este utilizat cu
predilecţie în inteligenţa artificială şi lingvistica computaţională1. În cele ce urmează
descriem elementele de sintaxă ale dialectului SICStus2. Mai întâi descriem câteva
elemente ale acestui dialect.
Obiectele limbajului se numesc termeni. Un termen este fie o constantă, o
variabilă sau un termen compus. Constantele includ întregii, numerele în virgulă
mobilă (Floating point) şi atomii. Variabilele sunt specificate prin identificatori care
încep cu literă mare sau _ (pentru variabilele anonime). Termenii compuşi se referă la
construcţii definite printr-un functor şi o secvenţă de argumente, între paranteze
rotunde. Un atom este un functor cu aritatea zero (fără argumente).
Listele sunt structuri speciale. O listă nevidă are un prim element (capul listei) şi
lista elementelor rămase şi, se notează prin [ primul-element | Lista-elementelor-
rămase ]. O listă de întregi, care reprezintă coduri ASCII, defineşte un string (şir de
caractere).
Unitatea de bază a unui program logic o reprezintă scopul sau apelul procedural.
Un program Prolog constă dintr-o secvenţă de construcţii numite fraze. O frază
conţine, în general, două părţi: capul şi coada. Capul frazei joacă rolul concluziei, iar
coada frazei pe cel al ipotezei. Dacă capul este nevid avem de-a face cu o clauză:
P :- A, B, C.
Aceasta se poate citi astfel: P este proprietate adevărată dacă sunt adevărate simultan A, B şi
C.
1
Pentru procesarea limbajului natural, folosind limbajul Prolog, se poate parcurge Hristea (2000).
2
SICStus Prolog – The Prolog Language, http://www.sics.se/SICS-reports/SICS-T--93-01--
SE/report_9.html
Dacă corpul clauzei este vid atunci clauza se numeşte atomică (sau clauză
unitate). Clauza atomică este de forma P. şi se citeşte: P este o propoziţie validă
(satisfăcută).
O frază cu capul vid este o directivă. O categorie specială de directive o
reprezintă întrebările. O întrebare este de forma
?- P, Q.
şi se poate citi interogativ: “Sunt P şi Q adevărate?” sau, procedural, “Satisfacerea
scopurilor P şi Q”.
Frazele, în general, conţin variabile. Variabilele aflate în fraze diferite sunt
complet independente. Domeniul lexical al unei variabile se reduce la fraza în care
apare. Variabilele disticte dintr-o frază reprezintă entităţi sau valori arbitrare.
Predicatul unui functor F este dat de secvenţa de clauze care au în partea de
concluzie functorul F. Pentru predicatele în care apar atât clauze de bază cât şi clauze
recursive, se recomandă (chiar trebuie) scrierea clauzelor de bază mai întâi şi apoi
scrierea celor recursive. Mai multe predicate pot avea acelaşi nume, dar arităţi diferite.
Unele predicate sunt furnizate de sistemul Prolog (se spune că sunt predicate built-in).
Cele mai multe predicate traduc cunoaşterea umană în fapte, reguli şi întrebări (sau
scopuri).
O subgramatică formală a limbajului Prolog (dialectul SICStus) cuprinde reguli precum:
Observaţia 9.2 Limbajul Prolog permite atât codificarea algoritmilor recursivi, cât şi
a celor nerecursivi.
Pentru a vedea dacă un cuvânt aparţine sau nu limbajului generat de gramatica dată, formulăm
o întrebare privitoare la simbolul de start. De exemplu
?- s([a,a,a,b,b,b], X).
X = []
?- s([a,a,b,b,x,y],Y).
Y = [x, y]
Metalimbajul XML (eXtensible Markup Language – apărut în anul 1996) a fost definit pentru
a descrie limbaje de marcare. Se bazează pe SGML (Standard Generalized Markup Language
– apărut în anul 1980) şi este un set de reguli, specificaţii şi convenţii pentru structurarea
datelor în fişiere text. Similar cu HTML şi XHTML, metalimbajul XML utilizează tag-uri
(cuprinse între caracterele "<" şi ">") şi atribute (de forma nume = "valoare") care apar în
interiorul tag-urilor.
Spre deosebire de HTML care indică modul de vizualizare a informaţiei de către
navigatoarele Web, limbajul XML foloseşte tag-uri doar pentru a delimita datele, iar
interpretarea este dată de aplicaţia care utilizează descrierea. Astfel, se specifică doar structura
documentului, nu şi semantica acestuia.
Din punct de vedere formal, un document XML constă din următoarele
construcţii:
a) comentarii – ignorate de procesoarele XML;
b) referinţe de entităţi – predefinite (amp, lt, gt, apos, quot – închise între & şi ;)
şi altele;
c) referinţe de caractere;
3
în sensul gramaticilor formale
d) instrucţiuni de procesare (PI -– Processing Instruction – informaţii de
transmis interpretoarelor XML şi altor programe);
e) secţiuni CDATA (o secţiune CDATA este utilă atunci când se stochează text
formatat, dar care nu trebuie interpretat, de exemplu, specificarea unui titlu:
<![CDATA[<TITLE>Acesta este un titlu !</TITLE>]]>
f) STag - tag-uri de început, de forma <numetag>;
g) ETag - tag-uri de sfârşit, de forma </numetag>;
h) TagVid - elemente vide, de exemplu: <IMG SRC="image.jpg" />;
i) declaraţii pentru tipul documentului.
Folosind notaţia EBNF4, gramatica limbajului XML, Versiunea 1.0, este dată prin producţiile:
4
Notaţia Backus-Naur extinsă constă din construcţii de forma simbol ::= expresie (notaţie utilizată, în
acest document, pentru specificarea regulilor de rescriere). Pentru XML sunt utilizate următoarele
notaţii:
• #xNNNN - NNNN este un întreg hexazecimal, iar expresia reprezintă caracterul în formatul ISO
10646 pentru care şirul de biţi (UCS-4), interpretaţi ca un număr întreg fără semn au valoarea
indicată.
• [a-zA-Z], [#xNNNN-#xNNNN] - orice caracter din domeniul specificat.
• [^a-z], [^#xNNNN-#xNNNN] - orice caracter din afara domeniului precizat.
• [^abc], [^#xNNNN#xNNNN#xNNNN] - orice caracter care nu este printre caracterele date.
• "şir" - un literal şir de caractere între ghilimele.
• 'şir' - un literal şir de caractere între apostrofuri.
• a b - a urmat de b.
• a | b - a sau b, dar nu ambele.
• a ñ b - mulţimea de şiruri reprezentate prin a, dar nu reprezentate prin b.
• a? - a sau nimic.
• a+ - una sau mai multe apariţii ale lui a.
• a* - zero sau mai multe apariţii ale lui a.
• %a - un parametru poate apărea în text acolo unde poate apărea a.
• (expresie) - scrierea unei expresii între paranteze impune tratarea expresiei ca o unitate şi aceasta
poate conţine operatorul prefix % sau operatorii sufix: ?, * sau +.
• /* ... */ - un comentariu.
VerNum ::= '1.0'
Diverse ::= Comentariu | PI | S
Decl-tipdoc ::= '<!DOCTYPE' S Nume (S ExternID)? S? ('[' IntSubset ']' S?)? '>'
Element ::= TagVid | STag Conţinut ETag
STag ::= '<' Nume (S Atribut)* S? '>'
Atribut ::= Nume Eq Valoare-atribut
ETag ::= '</' Nume S? '>'
1
În teoria algoritmilor, o gramatică formală G se numeşte recursivă dacă există un algoritm
care acceptă, la intrare, orice cuvânt w peste vocabularul terminal şi produce, la ieşire,
răspunsul la întrebarea: “w ∈ L(G)? “ Nu trebuie să confundăm această noţiune cu cea
referitoare la recursivitatea la stânga (resp. dreapta) a gramaticilor, introdusă prin definiţia
2.10.
Obiectivul final constă în obţinerea muţimii V1,m. Într-adevăr w ∈
L(G) dacă şi numai dacă S
→*
w, dacă şi numai dacă S ∈ V1,m.
2
De obicei se utilizează simbolul # pentru a indica indexul unui obiect. Prin urmare indexul
producţiei A ::= α ∈ P, va fi #(A ::= α).
k = min{s | s = 1, 2, …, j-1, A ::= BC ∈ P, B ∈ Vis , C ∈ Vi+s, j-
s})
then SEQ
h := h+1;
n[h] := #(A ::= BC);
if (k < j-k) then SEQ Analiza(i, k, B); Analiza(i+k, j-k, C);
END
else SEQ Analiza(i+k, j-k, C); Analiza(i, k, B); END;
END
END
END
Procedura este apelată prin Analiza(1, |w|, S) numai dacă algoritmul CYK a
furnizat rezultatul “w ∈L(G)”. Valoarea variabilei h va fi majorată de
valoarea [log2|w|].
Fie G = (Ω, Σ, S, P) o gramatică independentă de context. Definiţia
10.1 poate fi prelungită pentru toate formele propoziţionale (vezi definiţia
2.4) γ ∈ (Ω ∪ Σ)*. Se va defini analiza sintactică parţial stângă.
3
Producţiile se aplică într-o derivare extrem stânga (definiţia 2.8).
4
Producţiile se aplică într-o derivare extrem dreapta (definiţia 2.8).
Propoziţia 10.4 Fie G = (Ω, Σ, S, P) o gramatică independentă de context,
χ
nerecursivă la stânga şi A → wXu (stânga). Atunci există o constantă
reală pozitivă, c, astfel încât
|χ| ≤ c|w|+2.
5
O gramatică este aciclică dacă nu conţine reguli astfel încât să fie posibile derivări de
forma A
*→ A.
• Structura (s, i, α, β) se numeşte configuraţie a algoritmului de
analiză sintactică ascendentă dacă s ∈ {q, r, t, e} şi reprezintă
starea algoritmului (q – starea curentă, r – starea de revenire, t –
starea de terminare şi e – starea de eroare), i este poziţia simbolului
analizat, α este o listă gestionată ca o stivă cu vârful la dreapta,
iniţial conţinând un simbol special, notat $ şi apoi cuvinte peste Ω
∪ Σ ∪ {$}, numită şi lista pushdown, iar β este o listă gestionată ca
o stivă cu vârful la stânga şi care conţine cuvinte peste {D} ∪ { i | i
= 1, 2, ..., |P|}.
• Configuraţia iniţială a algoritmului este (q, 1, $, λ).
9. Se consideră variantele
a) regulat
b) independent de context
c) dependent de context
28[]. Se consideră limbajul format din toate cuvintele peste {a, b} care încep cu b şi
după care urmează 0, 1, 2 sau mai multe simboluri a. Alegeţi expresia regulată
corespunzătoare.
29[]. Se consideră limbajul format din toate cuvintele peste {a, b} care conţin
simbolul b exact de două ori. Alegeţi expresia regulată corespunzătoare.
30 []. Se consideră limbajul format din toate cuvintele peste {a, b}. Alegeţi expresia
regulată corespunzătoare.
31[]. Se consideră limbajul format din toate cuvintele peste {a, b} care conţin
consecutiv două simboluri a sau două simboluri b. Alegeţi expresia regulată
corespunzătoare.
12. Se consideră gramatica G = ({S, A, B}, {a, b}, S, P), unde P = {S ::= bA | aB, A
::= bAA | aS | a, B::= aBB | bS | b}. G este în forma normală
a) Chomsky
b) Greibach
c) Nici una din formele menţionate
15[]. Adevărat sau fals? Există clase de limbaje peste alfabetul Σ închise la substituţii
finite şi intersecţie cu limbaje regulate, dar care nu sunt închise la transformări gsm.
19. Fie gramatica G = ({S, A}, {a, b}, S, {(S, AA), (S, AS), (S, b), (A, SA), (A, AS),
(A, a)}) si w = abaab (|w| = 5). Algorimul CYK (Cocke, Younger, Kasami), la pasul
al treilea produce:
a. V[3][3]={A, S}, V[3][2]={A, S}, V[3][1]={A, S} c. V[3][3]={A, S},
V[3][2]={A, S}, V[3][1]={S}
b. V[3][3]={A, S}, V[3][2]={A, S}, V[3][1]={A} d. V[3][3]={A, S},
V[3][2]={S}, V[3][1]={A}
20. Fie gramatica G = ({S}, {a, b}, S, {S ::= aSB (1) | ab (2)} şi cuvântul w = aaabbb.
Analiza sintactică a cuvântului w este (între paranteze se află numărul producţiei):
a) 112
b) 121
c) 211
23. Gramatica ce contine reguli de forma S ::= if c then S else S | if c then S | a nu este
ambigua
b) Σ +
= UΣ k
.
k ≥1
Exemplul 1.2
Următoarele construcţii descriu limbaje:
1) Σ = {a, b, c}, L1 = {anbncn | n ≥ 1},
L2 = {ap | p ∈ N*, p număr prim},
L3 = {xx | x∈Σ*}.
2) Σ = {0, 1}, L = { x∈Σ* | x este scrierea binară a unui număr natural
divizibil prin 5}.
3) L = {a3, a5}.
Observaţia 1.3
L{λ}={λ}L=L;
L∅ = ∅L = ∅,
pentru oricare limbaj L, unde ∅ este limbajul vid.
Observaţia 1.4
Dacă L este un limbaj λ-liber (nu conţine cuvântul vid) atunci L+ = L* - {λ}.
0, w=λ
f ( w) = k −1
i1 + i2 n + L + ik n , w = xi1 xi2 L xik , k =| w |,1 ≤ i s ≤ n,1 ≤ s ≤ k .
Cerinta 1.2. Fie mulţimea univers U, funcţia f : U → U şi B ⊆ U . Construim, în
mod inductiv, şirul de mulţimi:
A0 = B; Ak+1 = Ak ∪ {f(x) | x ∈ Ak}, k ∈ N şi A = U
Ak . Atunci:
k∈N
a) A este închisă faţă de f;
Exemplul 1.4
Următoarele limbaje sunt mulţimi regulate:
L1={an| n≥1};
L2 = {(ab)nc| n≥0};
L3 = {a,b}*, etc.
Demonstraţie. Folosind unele dintre identităţile a-h, demonstrăm afirmaţia i). Din r
∼ s*t rezultă r ∼ (λ + ss*)t ∼ λt + ss*t ∼ t + sr ∼ sr + t. Presupunem că λ ∉ L(s) şi că
r ∼ sr + t . Obţinem, succesiv, r ∼ sr + t ∼ s(sr + t) +t ∼ s2r + (st + t) ∼ s3r + (s2t + st
+ t) ∼ … ∼ sk+1r + (skt + sk-1t + … + st + t), pentru k ≥ 0. Arătăm că r ∼ s*t prin
dublă incluziune. Fie x ∈ L(r) de lungime k := |x|. Deoarece r∼ sk+1r + (skt + sk-1t +
… + st + t) şi λ ∉ L(s) rezultă că x ∉ sk+1r (este clar că L(sk+1) conţine cuvinte cu
cel puţin k + 1 simboluri). Prin urmare x ∈ L(skt + sk-1t + … + st + t ) ⊂ L(s*t).
Reciproc, fie x ∈ L(s*t), deci există i ≥ 0 astfel încât x ∈ L(sit). Dar, identitatea r∼
si+1r + (sit + si-1t + … + st + t) arată că L(r) ⊃ L(sit). Deci x ∈ L(r). Partea a doua a
afirmaţiei se demonstrează similar.
Observaţia 2.1
Ansambul SR = (Ω ∪ Σ, P) este un sistem de rescriere pentru limbajul L(G)
pornind de la şirul S. Metoda de generare pentru L(G) poate fi specificată prin
structura (SR, {S}, Σ).
=
Exemplul 2.2 [akbk]
O gramatică care generează limbajul {anbn | n≥1}. este G=({S}, {a, b}, S,
{(S, aSb), (S, ab)}. Se demonstrează, prin inducţie, că
FP(G) = {akSbk | k ≥ 1} ∪ {akbk | k ≥ 1}.
Prin urmare L(G) = {akbk | k≥1}.
Cerinta 2.1
Pentru orice gramatică de tip 2, G = (Ω, Σ, S, P) , dacă AB
→*
w, atunci
există w1, w2 ∈ V* astfel încât: 1) w = w1w2 şi 2) A → w1, B
*
→ w2.
*
Cerinta 2.2
Pentru orice gramatică de tip 2, G = (Ω, Σ, S, P), există o gramatică
echivalentă G’ = (Ω’, Σ, S, P’), de tip 2, în care toate producţiile lui P’ care conţin
terminale sunt de forma A ::= a, a ∈ Σ.
Cerinta 2.3
Orice gramatică liniară la dreapta este echivalentă cu o gramatică de acelaşi
tip, dar cu reguli de forma: A ::= aB sau A ::= a, unde A, B ∈ Ω, iar a ∈ Σ ∪ {λ}.
Exemplul 2.4
Fie gramatica G = ({S, A, B, C, D}, {a, b, c}, S, {S ::= A | abcB, A ::= C | D,
B ::= A | ab, C ::= S}). Obţinem succesiv:
R(S) = {A, C, D, S},
R(A) = {C, D, S, A},
R(B) = {A, C, D, S},
R(C) = {S, A, C, D},
R(D) = ∅.
Considerăm regula S ::= abcB şi simbolurile X1, X2. Formăm mulţimea
S1 = {S ::= aX1, X1 ::= bX2, X2 ::= cB}.
Pentru regula B ::= ab, considerăm simbolul X3 şi mulţimea de reguli
P1 = {B::=aX3, X3 ::= b}.
În acest moment, regulile sunt:
1
R(B) reprezintă mulţimea redenumirilor directe sau prin simboluri intermediare ale
neterminalului B.
S ::= A | aX1; X1 ::= bX2;
A ::= C | D; X2 ::= cB;
B ::= A | aX3; X3 ::= b.
C ::= S;
Regula S ::= A se transformă în S ::= aX1 (care există deja), regula A::= C se
transformă în A ::= aX1, regula A ::= D se elimină, regula B::=A se înlocuieşte cu
B ::= aX1, iar regula C ::=S se înlocuieşte cu regula C ::= aX1. Gramatica G’ are
mulţimea neterminalelor Ω’ = {S, B, X1, X2, X3}, aceeaşi mulţime de terminale,
simbolul de start S şi mulţimea de reguli P’ = { S ::= aX1, X1 ::= bX2, X2 ::= cB, B
::= aX1 | aX3, X3 ::= b}. Se observă că simbolurile A, C şi D sunt inutile Regulile A
::= aX1 şi C ::= aX1 pot fi adăugate, dar în procesul de generare nu se vor aplica
niciodată.
Observaţia 2.2
Fie G o gramatică liniară la stânga, există o gramatică liniară la stânga G’
astfel încât L(G’) = L(G), iar regulile gramaticii G’ sunt numai de forma A ::= Ba
şi A ::= a, unde A, B ∈ Ω, iar a ∈ Σ ∪ {λ}.
Cerinta 2.5
Fie G o gramatică în care producţiile sunt de forma A ::= Ba şi A ::= a.
Atunci există o gramatică G’ echivalentă cu G pentru care producţiile sunt de
forma A ::= aB şi A ::= a.
Fie w∈L(G). Dacă |w| = 1, rezultă S ::= w ∈ P, deci (regula 2) S’::=w ∈ P’. Prin
urmare w ∈ L(G’). Dacă w = a1a2…an, n > 1, atunci există derivarea: S → A1an →
A2an-1an → A3an-2an-1an … → An-1 a2a3… an-2an-1an → a1a2…an. Producţiile folosite
au fost: S ::= A1an; A1 ::= A2an-1; …, An-2 ::= An-1a2 şi An-1 ::= a1. Deci, în P’, se vor
utiliza regulile A1 ::= an; A2 ::= an-1A1; …, An-1 ::= a2An-2 şi S’ ::= a1An-1. Rezultă că
w ∈ L(G’). Incluziunea inversă se demonstrează similar.
Observaţia 2.3
Propoziţiile anterioare arată echivalenţa dintre gramaticile liniare la stânga şi
cele liniare la dreapta. Nu trebuie crezut că dacă o gramatică are pe lângă reguli de
tipul A ::= a, atât reguli de forma A ::= aB, cât şi reguli de forma C ::= Db, ea va fi
echivalentă cu o gramatică liniară la stânga (sau la dreapta). De exemplu, gramatica
cu regulile { S ::= aA | aB; A ::= Sb; B ::= b} generează2 un limbaj de tip 2 şi nu
unul de tip 3 aşa cum ar părea la prima vedere.
Exemplul 2.5
Următoarele limbaje sunt de tip 3: L1 = {an | n≥1}, L2 = Σ+, unde Σ este un
alfabet finit (a se face legătura şi cu elementele lexicale ale limbajelor de
programare), L3 = {a(ba)n | n ≥0}. L1 este generat de gramatica G1 având regulile:
P={S ::= aS | a}. Fie Σ = {a1, a2, …, an}, L2 este generat de o gramatică cu regulile:
P = {S ::= aiS | i = 1, 2, …, n} ∪ {S ::= ai | i = 1, 2, …, n}. Limbajul L3 este generat
de gramatica cu regulile P = { S := aA | a, A ::= bB, B ::= aA | a}.
Exemplul 2.6
Fie gramatica G = ({E, T, F}, {(, ), +, *, a}, E, P) unde E este simbolul de
start, iar P are următoarele elemente: E ::= E+T | T; T ::= T*F | F, F ::= (E) | a.
Arborii de derivare pentru şirurile a+(a*a) şi (a+a)*a sunt3:
E E
/ | \ |
E + T T
| | / | \
T F T * F
| / | \ | |
F ( E ) F a
| | / | \
a T ( E )
/ | \ /|\
T * F E + T
| | | |
F a T F
| | |
a F a
|
a
Cerinta 2.6
Fie G = (Ω, Σ, S, P) o gramatică independentă de context. Oricare ar fi A ∈
Ω, α ∈ (Ω ∪ Σ)*, A →
*
α dacă şi numai dacă există un A-arbore cu frontiera α.
X1 X2 … Xk
2
Se demonstrează uşor că limbajul generat de gramatica de la observaţia 2.3 este L = {anbn
| n ≥ 1}.
3
În arbori, au fost trecute direct etichetele vârfurilor şi nu elementele din mulţimea X.
Prin urmare, în G există producţia A ::= X1X2…Xk, Deci A → X1X2…Xk. Să
presupunem că proprietatea are loc pentru arbori cu cel mult n - 1 noduri interioare
şi fie un A-arbore cu n noduri interioare şi frontiera α (n > 1). Descendenţii lui A
nu pot fi toţi frunze. Fie X1, X2, …, Xk etichetele acestor descendenţi şi αi frontiera
Xi – arborelui dacă Xi ∈ Ω şi αi = Xi dacă Xi ∈ Σ. Deoarece orice Xi-arbore are cel
mult n-1 noduri, atunci Xi →
*
αi (evident şi pentru Xi ∈ Σ). Prin urmare, în G
există derivarea A → X1X2…Xk →
*
α1X2…Xk →
*
α1α2X3 … Xk →*
α1α2
…αk-1Xk → α1α2 …αk = α.
*
X1 X2 … Xk
X1 X2 Xk-1 Xk
α1 α2 αk-1 αk
Observaţia 2.4
Fie G = (Ω, Σ, S, P) o gramatică independentă de context. Atunci α ∈ L(G),
adică S → *
α, dacă şi numai dacă există un arbore de derivare (S-arbore) cu
frontiera α.
Observaţia 2.5
Fie G = (Ω, Σ, S, P) o gramatică independentă de context şi w∈ L(G), deci
există un arbore de derivare cu frontiera w.
a) Evident, se poate pune în evidenţă o derivare extrem stânga (resp.
dreapta) pentru w din S. Totuşi, pentru un anumit cuvânt pot exista mai
multe derivări extrem stânga (resp. dreapta), ceea ce denotă o ambiguitate
în procesul de generare.
b) Pentru orice cuvânt w∈ L(G), numărul de derivări extrem stânga pentru
w este egal cu numărul de derivări extrem dreapta.
Exemplul 2.7
Fie G = ({S}, {a, b}, S, {S ::= SbS | a}) şi cuvântul w = (ab)3a. Se observă că:
S → SbS → SbSbS → abSbS → abSbSbS → ababSbS → abababS → abababa
şi
S → SbS → SbSbS → SbSbSbS → abSbSbS → ababSbS → abababS → abababa.
Dacă numerotăm regulile de rescriere:
1. S ::= SbS,
2. S ::= a
atunci derivările cuvântului (ab)3a sunt obţinute prin aplicarea secvenţelor de
reguli: 1,1,2,1,2,2,2 (resp. 1,1,1,2,2,2,2). Totuşi limbajul {(ab)na | n ≥ 1} nu este
ambiguu deoarece este generat şi de gramatica liniară la dreapta G1 = ({S, X, Y},
{a, b}, S, {S ::= Xa, X := aY, Y ::= bX | b}) care nu este ambiguă.
Observaţia 2.6
Orice gramatică independentă de context care conţine, printre regulile sale de
rescriere, producţii de unul din tipurile (1)-(4), cu neterminalul A util in generarea
de cuvinte peste Σ, este ambiguă:
(1) A ::= AA;
(2) A ::= AγA;
(3) A ::= αA | Aβ;
(4) A ::= αA | αAβA.
Cerinta 2.7
Fie G = (Ω, Σ, S, P) o gramatică independentă de context, iar A ∈ Ω cu
proprietatea că există o producţie de forma A ::= Aα. Atunci există o gramatică G’
echivalentă cu G care pentru orice A-regulă A ::= β avem A ∉ Pref(β).
Demonstraţie. Fie A ::= Aαi, i = 1, 2, …, n, toate A-regulile de rescriere ale
gramaticii G care au neterminalul A ca primă literă a membrului drept, iar A ::= βi ,
i = 1, 2, …, m, celelalte A-reguli. Considerăm gramatica G’ = (Ω ∪ {B}, Σ, S, P’)
unde B ∉ (Ω ∪ Σ) este un simbol nou, iar P’ se obţine din P astfel:
P’=(P-{A :: Aαi; 1≤i≤n}) ∪{ A ::= βiB; 1≤i≤m} }) ∪{B ::= αiB | αi; 1 ≤ i ≤ n}.
Observăm că noua gramatică nu mai este recursivă la stânga în A, dar este
recursivă la dreapta în B. Echivalenţa celor două gramatici rezultă imediat.
Exemplul 2.9
Fie gramatica independentă de context G = (Ω, Σ, S, P), unde Ω = {S, A, B},
Σ = {a, b} şi P = {(S, aB); (S, bA); (A, a); (A, aS); (A, bAA); (B, b); (B, bS); (B,
aBB)}. Atunci Var(G) = 3, Prod(G) = 8 şi Simb(G) = 32. Fie derivarea D1: S → aB
→ abS → abbA → abba. Atunci Index(D1, G) = 1. Derivarea D2: S → bA → bbAA
→ bbaSA → bbaaBA → bbaaaBBA → … → bbaaabba, are indexul Index(D2, G)
= 3.
q0 1 q1
0 0 0 0
q2 1 q3
Cerinta 3.1
Cu notaţiile de mai sus, δ(q, uv) = δ(δ(q,u), v), pentru oricare u, v ∈ Σ*.
Exemplul 3.2
Fie automatul din exemplul 3.1. Atunci:
a) δ(q0, 10101100) = δ(δ(q0, 1), 0101100) = δ(δ(q1, 0), 101100) =
δ(δ(q3, 1), 01100) = δ(δ(q2, 0), 1100) = δ(δ(q0, 1), 100)= δ(δ(q1, 1),00) =
δ(δ(q0, 0),0) = δ(δ(q2, 0), λ)= δ(q2, 0) = q0 ∈ F.
b) δ(q0, 11101001) = δ(δ(q0, 1), 1101001) = δ(δ(q1, 1), 101001) =
δ(δ(q0, 1), 01001) = δ(δ(q1, 0), 1001) = δ(δ(q3, 1), 001)= δ(δ(q2, 0), 01)=
δ(δ(q0, 0), 1) = δ(δ(q2, 1), λ) = δ(q2,1) = q3 ∉ F.
Exemplul 3.3
Limbajul acceptat de automatul prezentat în exemplul 3.1 este constituit din
mulţimea şirurilor peste {0, 1} în care apar un număr par de ‘0’ şi un număr par de
‘1’.
Exemplul 3.4
Fie N = (Q, Σ, δN, q0, F) cu Q = {A, B, C}, Σ = {a, b}, q0 = A, F = {B, C} şi
δN dată prin tabelul:
δN a b
A {A, B} {B}
B {A, C} {C}
C {B, C} {A}
şi w = abababb.
Atunci, obţinem succesiv:
δN(A, abababb) = δN(A, bababb) ∪ δN(B, bababb);
δN(A, bababb) = δN(B, ababb) = δN(A, babb) ∪ δN(C, babb);
δN(B, bababb) = δN(C, ababb) = δN(B, babb) ∪ δN(C, babb);
δN(A, babb) = δN(B, abb) = δN(A, bb) ∪ δN(C, bb);
δN(B, babb) = δN(C, abb) = δN(B, bb) ∪ δN(C, bb);
δN(C, babb) = δN(A, abb) = δN(A, bb) ∪ δN(B, bb);
δN(A, bb) = δN(B, b) = {C};
δN(B, bb) = δN(C, b) = {A};
δN(C, bb) = δN(A, b) = {B};
δN(A,abababb) = {A, B, C}.
Observăm că F ∩ δN(A, abababb) ≠ ∅. Deci abababb ∈ L(N).
Cerinta 3.2.
Orice limbaj acceptat de un AFD este acceptat de un AFN.
Demonstraţie. Evident.
Cerinţa 3.3.
Fie L un limbaj acceptat de un AFN. Atunci există un AFD, notat cu M,
astfel încât L(M) = L.
Exemplul 3.5
Fie automatul finit nedeterminist din exemplul 3.4. Automatul finit
determinist asociat are este caracterizat prin tabelul:
QM P(Q) A b
q7’ ∅ q7’ q7’
q0’ {A} q3 ’ q1’
q1’ {B} q4 ’ q2’
q2’ {C} q5 ’ q0’
q3’ {A, B} q6’ q5’
q4’ {A, C} q6’ q3’
q5’ {B, C} q6’ q4’
q6’ {A, B, C} q6 ’ q6’
deoarece:
δM(q0’, a) = δM({A}, a) = δN(A, a) = {A, B} = q3’;
δM(q0’, b) = δM({A}, b) = δN(A, b) = {B} = q1’;
δM(q1’, a) = δM({B}, a) = δN(B, a) = {A, C} = q4’;
δM(q1’, b) = δM({B}, b) = δN(B, b) = {C} = q2’;
δM(q2’, a) = δM({C}, a) = δN(C, a) = {B, C} = q5’;
δM(q2’, b) = δM({C}, b) = δN(C, b) = {A} = q0’;
δM(q3’, a) = δM({A, B}, a) = δN(A, a) ∪ δN(B, a) = {A, B, C} = q6’;
δM(q3’, b) = δM({A, B}, b) = δN(A, b) ∪ δN(B, b) = {B, C} = q5’;
δM(q4’, a) = δM({A, C}, a) = δN(A, a) ∪ δN(C, a) = {A, B, C} = q6’;
δM(q4’, b) = δM({A, C}, b) = δN(A, b) ∪ δN(C, b) = {A, B} = q3’;
δM(q5’, a) = δM({B, C}, a) = δN(B, a) ∪ δN(C, a) = {A, B, C} = q6’;
δM(q5’, b) = δM({B, C}, b) = δN(B, b) ∪ δN(C, b) = {A, C} = q4’;
δM(q6’, a) = δM({A, B, C},a) = δN(A,a) ∪ δN(B,a) ∪ δN(C,a)={A, B, C} = q6’;
δM(q6’, b) = δM({A, B, C},b) =δN(A,b) ∪ δN(B,b) ∪ δN(C,b)={A, B, C} = q6’,
iar F’ = {q1’, q2’, q3’, q4’, q5’, q6’}. Observăm că q7’ este stare inutilă şi se poate
elimina din QM.
4. Optimizarea automatelor finite
Algoritmul 4.1 [Determinarea stărilor accesibile4]
Prin aplicarea strategiei greedy, putem obţine un şir ascendent de mulţimi cu
stări accesibile, majorat în sensul relaţiei de incluziune de mulţimea stărilor
automatului considerat.
Fie S0 = {q0}. Pentru i ≥ 0, formăm Si+1 = Si ∪ {q ∈ Q - Si| există s ∈ Si şi a
∈ Σ astfel încât δ(s, a) = q}. O altă modalitate de construire a şirului ascendent
utilizează relaţia de recurenţă: Si+1 = Si ∪ {δ(s, a) | s ∈ Si, a ∈ Σ}.
Este clar că trebuie să existe k0, k0 ≤ |Q| astfel încât Sk0 = Sk0+1, k0 fiind cel
mai mic număr natural cu această proprietate; în aceste condiţii Sk0+j = Sk0, oricare j
≥ 1. Mulţimea stărilor accesibile este Sk0.
Intrare: Q, Σ, q0, δ, F
Ieşire: Q’ – mulţimea stărilor accesibile
SEQ
1. i := 0; S0 := {q0};
2. do {Si+1 := Si ∪{δ(s, a) | s ∈ Si, a ∈ Σ}; i = i+1; }while(Si – Si-1 ≠ ∅);
3. Q’ = Si.
END.
Intrare: Q, Σ, q0, δ, F
Ieşire: U’ – mulţimea stărilor utile
SEQ
1. i := 0; U0:= F;
2. do {
for a ∈ Σ do for q ∈ Q - Ui do if δ(q, a) ∈ Ui then Ui+1 = Ui ∪ {q};
i = i +1;
}while(Ui – Ui-1 ≠ ∅);
3. U’ = Ui.
END.
4
Problema determinării stărilor accesibile este echivalentă cu problema determinării
vârfurilor unui digraf care sunt legate prin cel puţin un drum de vârful care corespunde
stării q0. Dacă se determină matricea existenţei drumurilor sau, echivalent, închiderea
tranzitivă a relaţiei binare asociată diagramei de tranziţie (de exemplu, folosind algoritmul
Roy-Warshal) atunci stările accesibile corespund valorii 1 în linia stării q0 din matricea
existenţei drumurilor.
5
În unele lucrări, stările utile sunt denumite stări observabile.
Cerinta 4.1 [Lema de pompare]
Fie L un limbaj regulat. Există atunci un număr natural n astfel încât pentru
orice cuvânt w ∈ L, |w| ≥ n, w = xyz cu proprietăţile:
a) |xy| ≤ n;
b) |y| ≥ 1;
c) xyiz ∈ L pentru oricare i ≥ 0.
Cerinta 4.2
Fie L un limbaj acceptat de un AFD cu n stări. Atunci L ≠ ∅ ⇔ există w ∈ L
astfel încât |w| < n;
Algoritmul 4.3
Fie L un limbaj acceptat de un AFD cu n stări. Pentru a verifica dacă L ≠ ∅,
se poate aplica următorul algoritm.
Intrare: Q, Σ, q0, δ, F
Ieşire: “DA” dacă L este nevid; “NU” în caz contrar.
SEQ
1. i := 0; S0:= {q0};
2. do {Si+1 := Si ∪{δ(s, a) | s ∈ Si, a ∈ Σ}; i = i + 1;} while(Si – Si-1 ≠ ∅);
3. if Si ∩ F = ∅ then write “NU”; else write “DA”.
END.
Algoritmul 4.4
Fie L un limbaj acceptat de un AFD cu n stări. Pentru a verifica dacă L ≠ ∅,
se poate aplica următorul algoritm.
Intrare: Q, Σ, q0, δ, F
Ieşire: “DA” dacă L este infinit; “NU” în caz contrar.
SEQ
1. i := 0; S0:= {q0};
2. do {Si+1 := Si ∪{δ(s, a) | s ∈ Si, a ∈ Σ}; i = i + 1; }while(i < n);
3. do{
if Si ∩ F ≠ ∅ then write “DA”; stop.
Si+1 := Si ∪{δ(s, a) | s ∈ Si, a ∈ Σ}; i = i + 1;
}while(i < 2n);
4. write “NU”.
END.
5. Transformări asupra gramaticilor formale
Cerinta 5.1 [Eliminarea redenumirilor]
Fie G = (Ω, Σ, S, P) o gramatică de tipul 2 sau 3. Există o gramatică G1 = (Ω,
Σ, S, P1) de acelaşi tip cu G, echivalentă cu G şi fără redenumiri.
U0 = ∅;
Um+1 = Um ∪ {X | X ∈ Ω, există w, w ∈ Um*, X ::= w ∈ P}
are următoarele proprietăţi:
Dacă derivarea X →
*
λ este de lungime 1 atunci X ::= λ este producţie
din P, deci X ∈ U1 ⊆ Uk*.
Presupunem că pentru orice derivare X →*
λ cu lungimea cel mult m
rezultă X ∈ Uk*. Fie X → λ o derivare de lungime m+1. Punem în evidenţă
*
6
Acestea se mai numesc şi simboluri productive. Prin analogie cu sistemele AFD,
simbolurile productive vor fi numite şi simboluri utile. Simbolurile care sunt în acelaşi timp
accesibile (definiţia 5.3) şi productive le vom numi simboluri utilizabile, precum în
Atanasiu (1987).
k pentru care Uk = Uk+1. Notăm această valoare prin k*. Deci se poate scrie că U0 ⊆
U1 ⊆ … ⊆ Uk*.
De asemenea, pentru oricare i = 1, 2, …, k*, dacă X ∈ Ui atunci există w ∈
Σ* astfel încât X →
*
w. Dacă i = 1, afirmaţia rezultă din construcţia mulţimii
U1. Presupunem proprietatea adevărată pentru un indice i şi considerăm X ∈ Ui+1.
Dacă X ∈ Ui demonstraţia este încheiată. Considerăm cazul X ∈ Ui+1 – Ui, deci
există producţia X ::= X1X2…Xr, cu Xi ∈ Ui ∪ Σ, i = 1, 2, …, r. Dacă Xi ∈ Σ,
considerăm wi = Xi; altfel, prin ipoteza de inducţie există wi astfel încât Xi →*
Cerinţa 5.8
Fie G = (Ω, Σ, S, P) o gramatică independentă de context cu L(G) ≠ ∅. Există
G1 = (Ω1, Σ1, S, P1) echivalentă cu G care este gramatică proprie.
Exemplul 5.1
Simbolurile neutilizabile ale gramaticii cu mulţimea de reguli {(S, A), (S, B),
(A, aB), (A, bS), (A, b), (B, AB), (B, Ba), (C, AS), (C, b)} sunt B, a şi C.
Exemplul 5.2
După eliminarea λ-producţiilor, gramatica cu regulile {(S, aSbS), (S, bSaS),
(S, λ)} devine echivalentă cu gramatica cu regulile {(S’, S), (S’, λ), (S, aSbS), (S,
aSb), (S, abS), (S, ab), (S, bSaS), (S, baS), (S, bSa), (S, ba)}.
Exemplul 5.3
Fie gramatica G cu mulţimea de reguli P = {(S, A), (A, bS), (A, b)}.
Gramatica proprie echivalentă cu G are mulţimea regulilor P’ = {(S, bS), (S, b)},
iar A este un simbol neutilizabil.
Cerinta 6.1
Fie G = (Ω, Σ, S, P) o gramatică proprie. Atunci există G1 gramatică în forma
normală Chomsky echivalentă cu G.
Exemplul 6.1
Fie gramatica cu regulile S ::= bA | aB; A ::= bAA | aS | a; B ::= aBB | bS | b.
Introducem neterminalele noi Xa şi Xb. Formăm regulile Xa ::= a şi Xb ::= b. Apoi
modificăm regulile gramaticii iniţiale cu excepţia regulilor A ::= a şi B ::= b.
Obţinem noua mulţime de reguli:
Cerinta 6.2
Fie G = (Ω, Σ, S, P) o gramatică de tip 2 în forma normală Chomsky. Dacă
derivarea A → w1 → … → wn, n ≥ 1, wn ∈ Σ*, are proprietatea că cel mai lung lanţ
de la rădăcină la vârfurile terminale în arborele de derivare asociat ei în gramatica
GA = (Ω, Σ, A, P) are k noduri, atunci |wn| ≤ 2k-1.
Cerinta 6.3
Fie gramatica proprie G = (Ω, Σ, S, P) şi A ::= α1Bα2 o A-producţie şi B ::=
β1 | β2 | … βk toate B-producţiile din mulţimea P. Considerăm G1 = (Ω, Σ, S, P1)
unde P1 = (P – {A ::= α1Bα2}) ∪ {A ::= α1β1α2 | α1β2α2 |… | α1βkα2 }. Atunci G şi
G1 sunt gramatici echivalente.
Cerinta 6.5
Fie G = (Ω, Σ, S, P) o gramatică proprie. Atunci există gramatica G*, în
forma normală Greibach, echivalentă cu G.
SEQ
1. P* := P1; i := m;
2. while i > 1 do
SEQ
i := i - 1;
while (există j, i < j ≤ m, Ai ::= Ajα în P*) do
P* := (P* - {Ai ::= Ajα}) ∪ {Ai ::= βα | Aj ::= β ∈ P*}
END
3. for indici i ai simbolurilor Y do
while (există j, 1 ≤ j ≤ m, Yi ::= Ajα ∈ P*) do
P* := (P* - { Yi ::= Ajα }) ∪ {Yi ::= βα | Aj ::= β ∈ P*}
END.
Exemplul 6.2
Fie gramatica G, cu simbolurile neterminale numerotate şi regulile: A1 ::=
A2A3; A2 ::= A3A1 | b; A3 ::= A1A2 | a.
Se observă că gramatica G, deşi are reguli de tip FNC, este recursivă în mai
mulţi paşi.
Considerăm regula A3 ::= A1A2 şi o înlocuim cu A3 ::= A2A3A2, prin
aplicarea lemei 6.1. Observăm că în continuare persistă recursivitatea în mai mulţi
paşi. Considerăm regula A3 ::= A2A3A2 şi o înlocuim, folosind lema 6.1, cu regulile
A3 ::= A3A1A3A2 | bA3A2. Observăm că am ajuns la reursivitate într-un singur pas
şi putem aplica lema 6.2. Eliminăm regula A3 ::= A3A1A3A2 şi introducem regulile
A3 ::= bA3A2Y3 | aY3; Y3 ::= A1A3A2Y3 | A1A3A2. Am obţinut următoarea mulţime
de reguli:
A1 ::= A2A3;
A2 := A3A1 | b;
A3 ::= bA3A2Y3 | aY3 | bA3A2 | a
Y3 ::= A1A3A2Y3 | A1A3A2.
În continuare aplicăm algoritmul din demonstraţia teoremei 6.3. Eliminăm
regula A2 ::= A3A1 şi adăugăm regulile: A2 ::= bA3A2Y3A1 | aY3A1 | bA3A2A1 | aA1.
Observăm că A2 ::= b rămâne pe loc. Apoi regula A1 ::= A2A3 se elimină şi se
introduc regulile: A1 ::= bA3A2Y3A1A3 | aY3A1A3 | bA3A2A1A3 | aA1A3 | bA3. Până
acum am aplicat pasul 2 cu indicii i =2 şi 1.
Aplicăm, în continuare, pasul 3 pentru Y3. Astfel regulile
Y3 ::= A1A3A2Y3 | A1A3A2
se înlocuiesc cu
Y3 ::= bA3A2Y3A1A3A3A2Y3 | aY3A1A3A3A2Y3 | bA3A2A1A3A3A2Y3 |
aA1A3A3A2Y3 | bA3A3A2Y3 | bA3A2Y3A1A3A3A2 | aY3A1A3A3A2 |
bA3A2A1A3A3A2 | aA1A3A3A2 | bA3A3A2.
Exemplul 6.3
Un exemplu simplu de limbaj care nu este independent de context este L =
{anbncn | n ≥ 1}. Prin reducere la absurd, putem presupune contrariul, adică L este
un limbaj independent de context. Atunci există constantele p şi q date de lema
Bar-Hillel. Se alege un număr natural k > p / 3 şi cuvântul w = akbkck de lungime
mai mare ca p. Din descompunerea furnizată de teorema 6.4 rezultă că v şi y conţin
cel mult una din literele a, b sau c; altfel prin iterare nu s-ar mai păstra ordinea
alfabetică. Totuşi prin iterare ar trebui să se obţină acelaşi număr de simboluri a, b
şi c, ori nu pentru orice i ≥ 0 se poate obţine acest lucru. Rezultă că L nu este un
limbaj independent de context.
Cerinta 6.7
Fie G o gramatică independentă de context. Atunci L(G) este infinit dacă şi
numai dacă există w ∈ L(G) astfel încât p < |w| ≤ p + q, unde p şi q sunt numerele
furnizate de teorema 6.4.
Demonstraţie. Dacă L(G) este infinit rezultă că există w ∈ L(G) cu |w| > p,
deoarece Σ este o mulţime finită. Dacă |w| ≤ p + q atunci stop, altfel aplicarea
teoremei 6.4 şi alegerea lui i = 0, în procesul iterativ conduce la un cuvânt mai
scurt, dar de lungime mai mare ca p. După un număr finit de paşi se ajunge la un
cuvânt cu lungimea cel mult p + q. Afirmaţia reciprocă rezultă din aplicarea
teoremei 6.4 şi generarea unui şir infinit de cuvinte prin iteraţie.
7. Gramatici şi automate
Cerinta 7.1
Fie G = (Ω, Σ, S, P) o gramatică liniară la dreapta7. Atunci există un automat
finit nedeterminist (deci şi unul determinist) M astfel încât L(M) = L(G).
Cerinta 7.2
Orice limbaj generat de o gramatică liniară8 este regulat.
7
A se vedea şi propoziţia 2.5 (manual).
Demonstraţie. Se aplică teorema 3.1, teorema 3.2 şi teorema 7.1 (din manual)
Exemplul 7.1
Fie gramatica G = (Ω, Σ, S, P), unde Ω = {S, A, B}, Σ = {a, b} şi P = { S ::=
aA | a, A ::= bB, B ::= aA | a}.
Un AFN care recunoaşte limbajul L(G) are stările {S, A, B, X}, mulţimea
stărilor finale este {X}, iar funcţia de tranziţie este:
δ A B
S {A, X} ∅
A ∅ {B}
B {A, X} ∅
X ∅ ∅
Cerinta 7.3
Pentru orice limbaj regulat L există o gramatică liniară G astfel încât L=L(G).
Exemplul 7.2
Fie automatul dat prin tabelul
δ a b C
q0 q1 Q0
q1 q1 q2
q2 q2 Q0
8
Din acest motiv gramaticile liniare se mai numesc şi gramatici regulate. Rezultă, de aici,
că familia limbajelor de tip 3 conţine limbajele finite şi este închisă la operaţiile de
reuniune, produs şi stelare (*). Astfel, limbajele de tip 3 sunt descriptibile cu ajutorul
expresiilor regulate, generabile de gramatici liniare şi recunoscute de sisteme tranziţionale
şi deci de automate finite.
q1 ::= aq1 | bq2;
q2 ::= bq2 | cq0 | c.
Observaţia 7.1
Mişcarea automatului este posibilă numai dacă memoria stivă este nevidă.
Exemplul 7.3
Fie Q = {q0, q1, q2}, Σ = {a, b}, Γ = {a, Z0}, F = {q0} şi funcţia de tranziţie δ
definită astfel: δ(q0, a, Z0) = {(q1, aZ0)}, δ(q1, a, a) = {(q1, aa)}, δ(q1, b, a) = {(q2,
λ)}, δ(q2, b, a) = {(q2, λ)}, δ(q2, λ, Z0) = {(q0, λ)}, δ(q, x, Z0) = ∅ în celelalte
cazuri. Fie M = (Q, Σ, Γ, δ, q0, Z0, F). Se poate arăta că L(M) = {anbn | n ≥ 0}.
Cerinta 7.4 [Un limbaj recunoscut de un APD cu stări finale poate fi recunoscut şi
de un APD cu memoria pushdown vidă]
Fie L(M) limbajul recunoscut de automatul pushdown M = (Q, Σ, Γ, δ, q0, Z0,
F). Atunci există un APD, notat M’=(Q’, Σ, Γ’, δ’, qinit, X, ∅), care recunoaşte
L(M) cu memoria pushdown vidă, adică Lλ(M’) = L(M).
Demonstraţie. Fie Q’ = Q ∪ {qinit, qλ} unde qinit şi qλ sunt două elemente distincte
şi noi în raport cu Q. De asemenea, considerăm X un simbol nou în raport cu Γ şi
formăm Γ’ = Γ∪{X}. Dacă definim δ’ ca mai jos atunci se poate demonstra, prin
dublă incluziune – vezi Popovici şi colectiv(1991), că Lλ(M’) = L(M). Funcţia δ’
acţionează conform următoarelor şapte legi:
Cerinta 7.5 [Un limbaj recunoscut de un APD cu memoria pushdown vidă poate fi
recunoscut şi de un APD cu stări finale]
Fie Lλ(M) limbajul recunoscut de automatul pushdown M = (Q, Σ, Γ, δ, q0,
Z0, ∅). Atunci există un APD, notat M’ = (Q’, Σ, Γ’, δ’, qinit, X, {qf}), care
recunoaşte Lλ(M) cu starea finală qf, adică Lλ(M) = L(M’).
Demonstraţie. Fie Q’ = Q ∪ {qinit, qf} unde qinit şi qf sunt două elemente distincte şi
noi în raport cu Q. De asemenea, considerăm X un simbol nou în raport cu Γ şi
formăm Γ’ = Γ∪{X}. Dacă definim δ’ ca mai jos atunci se poate demonstra, prin
dublă incluziune (conform Popovici şi colectiv(1991)), că Lλ(M) = L(M’). Funcţia
δ’ acţionează conform următoarelor patru legi:
Cerinta 7.6
Pentru orice gramatică independentă de context G = (Ω, Σ, S, P) care
generează limbajul L = L(G) există un sistem APD care recunoaşte L.
Exemplul 7.4
Fie gramatica G = ({S, A}, {0, 1, 2}, S, P) unde P constă din producţiile: S
::= S2 | A2; A ::= 0A1 | 01. Se observă că L(G) = {0n1n2m | n, m ≥ 1}.
Sistemul APD care recunoaşte limbajul L(G) este M = ({q}, {0, 1, 2}, {S, A,
0, 1, 2}, δ, q, S, ∅) unde δ are următoarea definiţie:
Cerinta 7.7
Pentru orice sistem APD care recunoaşte limbajul L cu memoria pushdown
vidă, există o gramatică independentă de context care generează limbajul L.
Exemplul 7.5
Fie Q = {q0, q1, q2}, Σ = {a, b}, Γ = {a, Z0}, şi funcţia de tranziţie δ definită
astfel: δ(q0, a, Z0) = {(q1, aZ0)}, δ(q1, a, a) = {(q1, aa)}, δ(q1, b, a) = {(q2,λ)}, δ(q2,
b, a) = {(q2,λ)}, δ(q2, λ, Z0) = {(q0,λ)}, δ(q, x, Z0) = ∅, în celelalte cazuri. Fie M =
(Q, Σ, Γ, δ, q0, Z0, ∅). Se poate arăta că Lλ(M) = {anbn | n ≥ 0}. A se vedea şi
exemplul 7.3.
Gramatica de tip doi care recunoaşte limbajul Lλ(M), construită pe baza
metodei dată de demonstraţia teoremei 7.7 are 24 de producţii, după cum urmează.
Conform [Start] introducem trei producţii:
S ::= [q0Z0q0] | [q0Z0q1] | [q0Z0q0].
Conform [Compunere] pentru δ(q0, a, Z0) = {(q1, aZ0)} introducem
următoarele nouă producţii:
[q0Z0q0] ::= a [q1aq0] [q0Z0q0]; [q0Z0q0] ::= a [q1aq1] [q1Z0q0];
[q0Z0q0] ::= a [q1aq2] [q2Z0q0]; [q0Z0q1] ::= a [q1aq0] [q0Z0q1];
[q0Z0q1] ::= a [q1aq1] [q1Z0q1]; [q0Z0q1] ::= a [q1aq2] [q2Z0q1];
[q0Z0q2] ::= a [q1aq0] [q0Z0q2]; [q0Z0q2] ::= a [q1aq1] [q1Z0q2];
[q0Z0q2] ::= a [q1aq2] [q2Z0q2];
Folosind [Compunere] pentru δ(q1, a, a) = {(q1, aa)} obţinem încă nouă
producţii:
[q1Z0q0] ::= a [q1aq0] [q0aq0]; [q1Z0q0] ::= a [q1aq1] [q1aq0];
[q1Z0q0] ::= a [q1aq2] [q2aq0]; [q1Z0q1] ::= a [q1aq0] [q0aq1];
[q1Z0q1] ::= a [q1aq1] [q1aq1]; [q1Z0q1] ::= a [q1aq2] [q2aq1];
[q1Z0q2] ::= a [q1aq0] [q0aq2]; [q1Z0q2] ::= a [q1aq1] [q1aq2];
[q1Z0q2] ::= a [q1aq2] [q2aq2];
Aplicăm regula [Ştergere] pentru δ(q1, b, a) = {(q2, λ)} şi δ(q2, b, a) = {(q2, λ)}.
Obţinem producţiile: [q1aq2] ::= b şi [q2aq2] ::= b.
Pentru tranziţia δ(q2, λ, Z0) = {(q0,λ)}, obţinem producţia: [q2Z0q0] ::= λ.
Evident, λ-producţiile pot fi eliminate şi se obţine o gramatică de tip doi, dar
foarte complexă (în sensul că mărimea mulţimilor Ω şi P este considerabilă).
Comparaţi cu gramatica obţinută printr-o simplă modificare a gramaticii din
exemplul 2.2 (manual).
Observaţia 7.2
Fie M = (Q, Σ, Γ, δ, q0, B, ∅) un sistem MT. Atunci L(M) = ∅.
Observaţia 7.3
Fie M = (Q, Σ, Γ, δ, q0, B, Q) un sistem MT. Atunci L(M) = Σ*.
Observaţia 7.4
Introducerea nedeterminismului asupra sistemelor MT nu creşte puterea de
acceptare. Mai precis, are loc:
Cerinta 7.8
Pentru orice maşină Turing M există o gramatică G, de tip 0, astfel încât
L(M) = L(G).
Cerinta 7.9
Următoarele afirmaţii sunt adevărate.
a) Pentru orice gramatică dependentă de context (de tip 1) G = (Ω, Σ, S, P)
există o gramatică monotonă G’ = (Ω, Σ, S, P’) astfel încât L(G’) = L(G)
– {λ}.
b) Pentru orice automat liniar mărginit M există o gramatică monotonă G
astfel încât L(M) = L(G).
Exemplul 7.6
O maşină Turing care acceptă limbajul L = {anbncn | n > 0} este M = (Q, Σ, Γ,
δ, q0, B, F), unde Q = {q0, q1, q2, q3, q4, q5}, Σ = {a, b, c}, Γ = {a, b, c, x, y, z, B}, F
= {q5}, iar δ este dată prin tabelul:
δ A B c x Y z B
q0 (q1,x,D) ∅ ∅ ∅ (q4,y,D) ∅ ∅
q1 (q1, a, D) (q2, y, D) ∅ ∅ (q1,y,D) ∅ ∅
q2 ∅ (q2, b, D) (q3, z, S) ∅ ∅ (q2,z,D) ∅
q3 (q3, a, S) (q3, b, S) ∅ (q0,z,D) (q3,y,S) (q3,z,S) ∅
q4 ∅ ∅ ∅ ∅ (q4,y,D) (q4,z,D) (q5,B,D)
q5 ∅ ∅ ∅ ∅ ∅ ∅ ∅
8. Proprietăţi de închidere
Cerinta 8.1
Familia limbajelor dependente de context este închisă faţă de reuniune.
Observaţa 8.1
Enunţul şi demonstraţia de mai sus pot fi refăcute pentru a arăta închiderea la
reuniune a familiilor L2 şi L3.
Conform teoremei 3.3 (manul), familia limbajelor regulate este cea mai mică
familie de limbaje care conţine limbajele finite şi este închisă la reuniune, produs
(concatenare) şi la operaţia * (închiderea Kleene). Trebuie remarcat că familia L3
include strict familia limbajelor finite.
Cerinta 8.2
Fie Σ un alfabet şi L ⊆ Σ* un limbaj regulat. Atunci Σ* - L este un limbaj
regulat
Cerinta 8.3
Familia limbajelor regulate este închisă la operaţia de intersecţie.
Observaţia 8.2
Familia limbajelor regulate peste un alfabet Σ, fiind închisă la reuniune,
intersecţie şi complementară, formează o algebră booleană în care suma booleană
este reuniunea, produsul boolean este intersecţia, iar complementul unui element
este obţinut prin formarea limbajului complementar (diferenţa până la Σ*.)
Cerinta 8.4
Familia L2 este închisă la reuniune.
Cerinta 8.5
Familia L2 este închisă la concatenare (produs).
Demonstraţie. Fie L1 şi L2 două limbaje independente de context generate de
gramaticile G1 = (Ω1, Σ1, S1, P1 ) şi G2 = (Ω2, Σ2, S2, P2) astfel încât gramaticile G1
= (Ω1, Σ1, S1, P1 – {S1 ::= λ}) şi G2 = (Ω2, Σ2, S2, P2 - {S2 ::= λ}) să fie
independente de context, iar Ω1 ∩ Ω2 = ∅, Ω1 ∩ Σ2 = ∅ şi Ω2 ∩ Σ1 = ∅. Fie S ∉
Ω1 ∪ Ω2 ∪ Σ1 ∪Σ 2. Formăm gramatica G = (Ω1 ∪ Ω2 ∪{S}, Σ1 ∪ Σ 2, S, P) unde
P = P1 ∪ P2 ∪ {S::= S1S2}. Este uşor de arătat că L = L1L2 este generat de
gramatica G.
Cerinta 8.6
Familia L2 este închisă la operaţia * (stelare).
Observaţia 8.3
Dacă L este un limbaj de tip i (i = 2 sau 3) atunci L+ este de tip i.
Cerinta 8.7
Familia L2 nu este închisă la intersecţie şi complementară.
Cerinta 8.8
Fie L ∈ L2 şi R ∈ L3, L1 = L ∩ R şi L2 = L – R. Atunci Li ∈ L2 (i = 1, 2).
(A1, q0, q1) … (An, qn-1, fi) → (a1, q0, q1) … (an, qn-1, fi)
*
→ a1a2…an, prin
*
Cerinta 8.9
Considerăm transformarea de substituire definită asupra limbajelor ca în
definiţia 1.8 - manual. Familia limbajelor independente de context este închisă la
substituţii.
t(α2) →*
… → *
t(αp) = t(α) = t(a1) t(a2) … t(ak) = S a1 S a2 … S ak .
Deoarece s(ai) = L( G a1 ) atunci există în fiecare G a1 , derivarea S a1
→
*
wi, i =
1, 2, …, k. Prin urmare S a1
→
*
wi în G1 şi S
→
*
S a1 S a2 … S ak
→
*
Deci există o derivare S → wt ∈ {Sa | a ∈ Σ}*. Prin urmare există k ≥1 astfel
*
Observaţia 8.4
Familia limbajelor independente de context este închisă la homomorfisme.
Observaţia 8.5
Un sistem gsm este un sistem AFN care, în plus, faţă de banda de intrare
(cuvinte peste Σ) conţine şi o bandă de ieşire (pentru manipularea cuvintelor peste
∆). Faptul că (q2, u) ∈ δ(q1, a) arată trecerea din starea q1 in starea q2, când capul de
citire a întâlnit simbolul a, dar şi emiterea cuvântului u ∈ ∆* la ieşire. Funcţia δ se
extinde la Σ*, în mod obişnuit.
Cerinţa 8.10
Orice clasă de limbaje peste alfabetul Σ închisă la substituţii finite şi
intersecţie cu limbaje regulate este închisă la transformări gsm.
Observaţia 8.6
Deoarece familiile Li ( i = 2, 3) satisfac condiţille teoremei 8.10 rezultă că
acestea sunt închise la transformări gsm.
void main(void){
Sistem_AFD M;
M.Determină_stările_accesibile(); M.Afişare_informaţii();
}
domains
list=integer* /* Se defineste tipul lista de intregi */
predicates
wlist(list) /* afisarea elementelor unei liste */
nlist(list,integer) /* Numarul elementelor unei liste */
slist(list,integer) /* Suma elementelor listei */
addx(integer,list,list) /* Adauga x la fiecare element al listei */
addl(list,list,list) /* aduna element cu element doua liste */
dlist(list,list) /* dublarea elementelor unei liste */
rnlist(list,list) /* eliminarea numerelor negative */
inlist(integer,list) /* este in lista? Yes or No */
catlist(list, list, list) /* concatenare de liste */
clauses
wlist([]) :- !.
wlist([H | T]) :- write(H), nl, wlist(T).
nlist([],0) :-!.
nlist([_|T],N) :- nlist(T,N1), N=N1+1.
slist([],0) :- !.
slist([X|C],S) :- slist(C,S1), S=S1+X.
addx(X,[], []):- !.
addx(X,[A|R], [Y|R1]) :- Y=A+X,addx(X,R,R1).
addl([],L,L) :- !.
addl(L,[],L) :- !.
addl([A|L1],[B|L2],[C|L3]) :- C=A+B,addl(L1,L2,L3).
dlist([], []) :- !.
dlist([A|B], [A,A|C]) :- dlist(B,C).
rnlist([],[]) :- !.
rnlist([X|A],[X|B]) :- X>=0, !, rnlist(A,B).
rnlist([X|A],B) :- X<0,!, rnlist(A,B).
inlist(X, [X|A]) :- !.
inlist(X, [_|A]) :- inlist(X,A).
catlist([],L,L) :- !.
catlist([X|L1], L, [X|L2]):- catlist(L1, L, L2).
Exemplul 9.3
Următoarele clause sunt suficiente pentru a permite testarea apartenenţei unui
cuvânt la mulţimea cuvintelor acceptate de un sistem AFN. Considerăm automatul
prezentat în exemplul 3.4. Stările sunt s1, s2, s3 şi corespund notaţiei cu A, B, C
din exemplul 3.4 - manual. Vocabularul este {a, b}. Declaraţiile Prolog sunt:
delta(s1, a, s1).
delta(s1, a, s2).
delta(s1, b, s2).
delta(s2, a, s1).
delta(s2, a, s3).
delta(s2, b, s3).
delta(s3, a, s2).
delta(s3, a, s3).
delta(s3, b, s1).
stare_iniţială(s1).
stare_finală(s2).
stare_finală(s3).
accepta(X, []) :- stare_finală(X), write("Da").
accepta(X, [Prima_literă | Restul]) :- delta(X, Prima_literă, Y),
accepta(Y, Restul).
aparţine(W) :- stare-iniţială(X), accepta(X, W).
aparţine( _ ) :- write("Nu").
?- aparţine([a, b, a, b, a, b, b]).
Observaţia 9.1
În Prolog se comunică cunoştinţe. Determinarea efectivă a soluţiei este
realizată de către nucleul Prolog prin metode specifice: unificare, backtracking etc.
Observaţia 9.2
Limbajul Prolog permite atât codificarea algoritmilor recursivi, cât şi a celor
nerecursivi. Următoarele declaraţii permit calculul factorialului în ambele variante.
00F] | [#x202A-#x202E] | [#x206A-#x206F] | #xFEFF
Exemplul 9.4
Secvenţa XML următoare ilustrează definirea înregistrărilor tip bază de date:
<?XML version = "1.0" ?>
<!DOCTYPE DOCUMENT [
<!ELEMENT DOCUMENT (CLIENT)*>
<!ELEMENT CLIENT (NUMESIPRENUME, DATA, COMENZI)>
<!ELEMENT NUMESIPRENUME (NUME, PRENUME)>
<!ELEMENT NUME (#PCDATA)>
<!ELEMENT PRENUME (#PCDATA)>
<!ELEMENT DATA (#PCDATA)>
<!ELEMENT COMENZI (POZITIE)*>
<!ELEMENT POZITIE (PRODUS, NUMAR, PRET)>
<!ELEMENT PRODUS (#PCDATA)>
<!ELEMENT NUMAR (#PCDATA)>
<!ELEMENT PRET (#PCDATA)>
]>
<DOCUMENT>
<!—Date despre clienti-->
<CLIENT>
<NUMESIPRENUME>
<NUME>Ionescu</NUME>
<PRENUME>Marian</PRENUME>
</NUMESIPRENUME>
<DATA>Februarie 23, 2005</DATA>
<COMENZI>
<POZITIE>
<PRODUS>CAIET DICTANDO</PRODUS>
<NUMAR>15</NUMAR>
<PRET>25000</PRET>
</POZITIE>
<POZITIE>
<PRODUS>CRETA</PRODUS>
<NUMAR>10</NUMAR>
<PRET>15000</PRET>
</POZITIE>
</COMENZI>
</CLIENT>
<CLIENT>
<NUMESIPRENUME>
<NUME>Popescu</NUME>
<PRENUME>Alexandru</PRENUME>
</NUMESIPRENUME>
<DATA>Februarie 24, 2005</DATA>
<COMENZI>
<POZITIE>
<PRODUS>CARTE</PRODUS>
<NUMAR>1</NUMAR>
<PRET>500000</PRET>
</POZITIE>
<POZITIE>
<PRODUS>CD AUDIO</PRODUS>
<NUMAR>10</NUMAR>
<PRET>150000</PRET>
</POZITIE>
</COMENZI>
</CLIENT>
</DOCUMENT>
Exemplul 9.5
Documentul următor defineşte două tipuri de obiecte (cerc şi elipsă)
împreună cu atributele acestora.
Exemplul 10.1
Fie gramatica G = ({S, A}, {a, b}, S, {(S, AA), (S, AS), (S, b), (A, SA), (A,
AS), (A, a)}) şi w = abaab (|w| = 5). Prin aplicarea propoziţiei 10.1 se obţine
următorul şir de mulţimi:
X0 = {S};
X2 = X1 ∪ {SAA, ASA, aA, AAS, Aa, SAS, ASS, aS, AAA, Ab};
X3 = X2 ∪ {AAAA, ASAA, bAA, SSAA, SASA, SaA, SAAS, SAa, ASSA, aSA,
AASA, AbA, ASAS, ASa, aAS, aa, AaS, AAAS, Aab, bAS, SSAS, SASS, SaS,
SAAA, SAAS, SAb, ASSS, aSS, AASS, AbS, ASb, aAA, ab, AaA, AAa, , ab}
X4 = X3 ∪ {SAAAA, ASAAA, aAAA, AASAA, AaAA, AAASA, AAaA,
AAAAS, AAAa, SASAA, ASSAA, aSAA, AAAAA, AbAA, ASASA, ASaA,
ASAAS, ASAa, bSAA, bASA, baA, bAAS, bAa, SbAA, SSSAA, SSASA, SSaA,
SSAAS, SSAa, SASSA, SaSA, SAASA, SAbA, SASAS, SASa, AAaA, ASaA,
SaAS, Sab, SaAS, SAASS, SAaS, SAAAS, SAAb, Saa, ASSSA, aSSA, AASSA,
AbSA, ASbA, ASSAS, ASSa, aAAA, aASA, abA, AaSA, AAbA, AASAS, AASa,
SAbA, AbAS, Aba, aSAS, AbAS, ASASS, ASaS, ASAb, aSa, aASS, aaS, aAAS,
aAb, AaAA, AaAS, Aab, ASAAS, AAASS, AAbS, AAAb, SAab, ASab, aab,
bSAS, bASS, baS, bAAA, bAAS, bAb, SAAAS, SbAS, SSASS, SSSAS, SSaS,
SSAAA, SSAb, bASS, SSASS, SASSS, SaSS, SAASS, SAbS, SASAA, SASb,
AAaS, baS, SaAA, bAAAA, SaAA, SAaA, SAAa, ASAb, ASAb, bAb, Sab,
ASSSS, aSSS, AASSS, AbSS, ASAAS, ASbS, ASSb, aAAS, abS, aSb, AaSS,
AAbS, AASb, SAbS, AbAA, AbAS, Abb, aaA, SAaA, ASaA, aaA, AaAS, Aaa,
ASAa, aAa, AASa, Aaa},
...
X9 = X8 ∪ {abaab, ...}
Cerinta 10.2
Există un algoritm care să determine, pentru o gramatică independentă de
context G = (Ω, Σ, S, P) şi un cuvânt w ∈ Σ*, dacă w ∈ L(G) sau w ∉ L(G).
algoritm pentru a decide dacă w ∈ L(G) sau nu, ar trebui să genereze toate
derivările de lungime |w|. Acest lucru este posibil deoarece numărul regulilor este
finit şi prin aplicarea metodei backtracking se pot genera toate derivările de o
anumită lungime.
Exemplul 10.2
Considerăm datele de intrare din exemplul 10.1. Rezultatul aplicării
algoritmului CYK este prezentat în următorul tabel:
Cerinta 10.3
Algoritmul CYK (Cocke, Younger şi Kasami) calculează mulţimile Vi,j (j =
1, 2, …, m; i = 1, 2, …, m – j + 1) folosind O(m3) operaţii de reuniune.
Demonstraţie. Complexitatea pasului 1 este O(m). Numărul de operaţii de reuniune
din pasul 2 este dat de numărul tripletelor (j, i, k) - cardinalul mulţimii -
Procedura este apelată prin Analiza(1, |w|, S) numai dacă algoritmul CYK a
furnizat rezultatul “w ∈L(G)”. Valoarea variabilei h va fi majorată de valoarea
[log2|w|].
Cerinta 10.4
Fie G = (Ω, Σ, S, P) o gramatică independentă de context, nerecursivă la
χ
stânga şi A → wXu (stânga). Atunci există o constantă reală pozitivă, c, astfel
încât
|χ| ≤ c|w|+2.
χ
Demonstraţie. Fie n = |Ω| şi arborele corespunzător derivării A → wXu
(stânga). Atunci, în acest arbore nu există nici un drum de lungime mai mare decât
n(|w| + 2). Fie s = max {|α| |A ::= α∈P}. Cum în arborele de derivare nu sunt mai
mult de sn(|w| + 2) noduri interioare, rezultă că lungimea unei analize stângi poate fi
majorată ca în enunţ. Se observă că se poate lua c = sn care depinde numai de
gramatica G, nu şi de forma propoziţională.
Exemplul 10.3
Fie gramatica cu regulile S ::= aSb | b şi cuvântul w = aaabbb. Prin aplicarea
algoritmului de analiză sintactică descendentă rezultă următoarele configuraţii:
(q, 1, λ, S$) |- (q, 1, S1, aSb$) |- (q, 2, S1a, Sb$) |- (q, 2, S1aS1, aSbb$) |-
(q, 3, S1aS1a, Sbb$) |- (q, 3, S1aS1aS1, aSbbb$) |- (q, 4, S1aS1aS1a, Sbbb$) |-
(q, 4, S1aS1aS1aS1, aSbbbb$) |- (r, 4, S1aS1aS1aS1, aSbbbb$) |-
(q, 4, S1aS1aS1aS2, abbbb$) |- (r, 4, S1aS1aS1aS2, abbbb$) |-
(r, 4, S1aS1aS1a, Sbbb$) |- (r, 3, S1aS1aS1, aSbbb$) |-
(q, 3, S1aS1aS2, abbb$) |- (q, 4, S1aS1aS2a, bbb$) |-
(q, 5, S1aS1aS2ab, bb$) |- (q, 6, S1aS1aS2abb, b$) |-
(q, 7, S1aS1aS2abbb, $) |- (t, 7, S1aS1aS2abbb, λ).
Analiza sintactică a cuvântului aaabbb este 112 unde indicii şi asocierile sunt
următoarele: 1 (S1) pentru S ::= aSb, respectiv 2 (S2) pentru S ::= ab.
Cerinta 10.5
Fie G = (Ω, Σ, S, P) o gramatică independentă de context, fără λ-producţii şi
χ
aciclică, w ∈ Σ*, iar A → uXw (dreapta). Atunci există o constantă reală
pozitivă, c, astfel încât
|χ| ≤ c|w|.
Exemplul 10.4
Fie gramatica din exemplul 10.3 şi cuvântul w = a3b3. Conform algoritmului
analizei sintactice ascendente au loc următoarele tranziţii:
(q, 1, $, λ) |- (q, 2, $a, D) |- (q, 3, $aa, DD) |- (q, 4, $aaa, DDD) |-
(q, 5, $aaab, DDDD) |- (q, 5, $aaS, 2DDDD) |- (q, 6, $aaSb, D2DDDD) |-
(q, 6, $aS, 2D2DDDD) |- (q, 6, $aSb, D1D2DDDD) |-
(q, 7, $S, 1D2D2DDDD) |- (t, 7, λ, 1D1D2DDDD).
Analiza sintactică a cuvântului aaabbb este 112 unde indicii producţiilor sunt
următoarele: 1 pentru S ::= aSb, respectiv 2 pentru S ::= ab.
Bibliografie