20.11.2014 Views

Limbaje Formale, Automate şi Compilatoare

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

<strong>Limbaje</strong> <strong>Formale</strong>, <strong>Automate</strong> <strong>şi</strong> <strong>Compilatoare</strong><br />

Curs 3<br />

2014-15<br />

LFAC (2014-15) Curs 3 1 / 30


Structura cursului<br />

1 <strong>Automate</strong> finite cu ǫ-tranziţii<br />

2 Gramatici de tip 3 <strong>şi</strong> automate finite<br />

3 Automatul determinist minimal<br />

LFAC (2014-15) Curs 3 2 / 30


<strong>Automate</strong> finite cu ǫ-tranziţii<br />

Curs 3<br />

1 <strong>Automate</strong> finite cu ǫ-tranziţii<br />

2 Gramatici de tip 3 <strong>şi</strong> automate finite<br />

3 Automatul determinist minimal<br />

LFAC (2014-15) Curs 3 3 / 30


<strong>Automate</strong> finite cu ǫ-tranziţii<br />

<strong>Automate</strong> finite cu ǫ-tranziţii<br />

Definiţie 1<br />

Un automat finit cu ǫ-tranziţii este un 5-uplu A = (Q,Σ,δ, q 0 , F), unde:<br />

Q, Σ, q 0 <strong>şi</strong> F sunt definite ca în cazul automatelor finite<br />

deterministe<br />

δ este o funcţie , δ : Q×(Σ∪{ǫ}) → 2 Q , numită funcţia de tranziţie<br />

Observaţie:<br />

A este automat nedeterminist, dacă δ(q,ǫ) = ∅,∀q ∈ Q<br />

A este automat determinist, dacă, în plus:<br />

|δ(q, a)| = 1,∀q ∈ Q,∀a ∈ Σ<br />

LFAC (2014-15) Curs 3 4 / 30


<strong>Automate</strong> finite cu ǫ-tranziţii<br />

Exemplu<br />

LFAC (2014-15) Curs 3 5 / 30


<strong>Automate</strong> finite cu ǫ-tranziţii<br />

Extensia lui δ la cuvinte<br />

Cl(q)<br />

= {q ′ |q ′ ∈ Q, in graful automatului A exista un drum de la q la q’ de lungime k ≥ 0<br />

ale carui arce sunt etichetate cu ǫ}.<br />

q ∈ Cl(q)<br />

LFAC (2014-15) Curs 3 6 / 30


<strong>Automate</strong> finite cu ǫ-tranziţii<br />

Extensia lui δ la cuvinte<br />

Cl(q)<br />

= {q ′ |q ′ ∈ Q, in graful automatului A exista un drum de la q la q’ de lungime k ≥ 0<br />

ale carui arce sunt etichetate cu ǫ}.<br />

q ∈ Cl(q)<br />

Dacă S ⊆ Q, atunci notăm:<br />

Cl(S) = ⋃ q∈S<br />

Cl(q)<br />

LFAC (2014-15) Curs 3 6 / 30


<strong>Automate</strong> finite cu ǫ-tranziţii<br />

Extensia lui δ la cuvinte<br />

Cl(q)<br />

= {q ′ |q ′ ∈ Q, in graful automatului A exista un drum de la q la q’ de lungime k ≥ 0<br />

ale carui arce sunt etichetate cu ǫ}.<br />

q ∈ Cl(q)<br />

Dacă S ⊆ Q, atunci notăm:<br />

Cl(S) = ⋃ q∈S<br />

Cl(q)<br />

Extensia lui δ la cuvinte: ˆδ : Q ×Σ ∗ → 2 Q<br />

LFAC (2014-15) Curs 3 6 / 30


<strong>Automate</strong> finite cu ǫ-tranziţii<br />

Extensia lui δ la cuvinte<br />

Cl(q)<br />

= {q ′ |q ′ ∈ Q, in graful automatului A exista un drum de la q la q’ de lungime k ≥ 0<br />

ale carui arce sunt etichetate cu ǫ}.<br />

q ∈ Cl(q)<br />

Dacă S ⊆ Q, atunci notăm:<br />

Cl(S) = ⋃ q∈S<br />

Cl(q)<br />

Extensia lui δ la cuvinte: ˆδ : Q ×Σ ∗ → 2 Q<br />

1 ˆδ(q,ǫ) = Cl(q),∀q ∈ Q;<br />

LFAC (2014-15) Curs 3 6 / 30


<strong>Automate</strong> finite cu ǫ-tranziţii<br />

Extensia lui δ la cuvinte<br />

Cl(q)<br />

= {q ′ |q ′ ∈ Q, in graful automatului A exista un drum de la q la q’ de lungime k ≥ 0<br />

ale carui arce sunt etichetate cu ǫ}.<br />

q ∈ Cl(q)<br />

Dacă S ⊆ Q, atunci notăm:<br />

Cl(S) = ⋃ q∈S<br />

Cl(q)<br />

Extensia lui δ la cuvinte: ˆδ : Q ×Σ ∗ → 2 Q<br />

1 ˆδ(q,ǫ) = Cl(q),∀q ∈ Q;<br />

2 ˆδ(q, ua) = Cl(δ(ˆδ(q, u), a))), ∀q ∈ Q,∀u ∈ Σ ∗ ,∀a ∈ Σ.<br />

LFAC (2014-15) Curs 3 6 / 30


<strong>Automate</strong> finite cu ǫ-tranziţii<br />

Extensia lui δ la cuvinte<br />

ˆδ(q, a) = Cl(δ(Cl(q), a)),∀q ∈ Q,∀a ∈ Σ<br />

În cazul automatelor cu ǫ - tranziţii vom păstra notaţia ˆδ pentru<br />

extensie pentru că, în general, ˆδ(q,ǫ) ≠ δ(q,ǫ) <strong>şi</strong><br />

ˆδ(q, a) ≠ δ(q, a), a ∈ Σ.<br />

ˆδ(q, uv) = ˆδ(ˆδ(q, u), v), ∀q ∈ Q,∀u, v ∈ Σ ∗<br />

LFAC (2014-15) Curs 3 7 / 30


<strong>Automate</strong> finite cu ǫ-tranziţii<br />

Limbajul acceptat<br />

Definiţie 2<br />

Limbajul acceptat (recunoscut) de automatul cu ǫ-tranziţii<br />

A = (Q,Σ,δ, q 0 , F) este mulţimea :<br />

L(A) = {w|w ∈ Σ ∗ ,ˆδ(q 0 , w)∩F ≠ ∅}.<br />

Un cuvânt w este recunoscut de un automat A dacă, după citirea<br />

în întregime a cuvântului w, automatul (pornind din starea iniţială<br />

q 0 ) poate să ajungă într-o stare finală.<br />

LFAC (2014-15) Curs 3 8 / 30


<strong>Automate</strong> finite cu ǫ-tranziţii<br />

Automatul determinist echivalent<br />

Teorema 1<br />

Pentru orice automat A cu ǫ - tranziţii există un automat A ′ determinist<br />

echivalent cu A<br />

Dacă A = (Q,Σ,δ, q 0 , F) atunci A ′ = (Q ′ ,Σ,δ ′ , q<br />

0 ′, F′ ) unde:<br />

Q ′ = 2 Q<br />

q<br />

0 ′ = Cl(q 0)<br />

δ ′ (S, a) = Cl(δ(S, a)) S ∈ Q ′ , a ∈ Σ<br />

S ∈ F ′ ⇔ S ∩ F ≠ ∅<br />

LFAC (2014-15) Curs 3 9 / 30


<strong>Automate</strong> finite cu ǫ-tranziţii<br />

Automatul determinist echivalent<br />

Teorema 1<br />

Pentru orice automat A cu ǫ - tranziţii există un automat A ′ determinist<br />

echivalent cu A<br />

Dacă A = (Q,Σ,δ, q 0 , F) atunci A ′ = (Q ′ ,Σ,δ ′ , q<br />

0 ′, F′ ) unde:<br />

Q ′ = 2 Q<br />

q<br />

0 ′ = Cl(q 0)<br />

δ ′ (S, a) = Cl(δ(S, a)) S ∈ Q ′ , a ∈ Σ<br />

S ∈ F ′ ⇔ S ∩ F ≠ ∅<br />

Au loc:<br />

δ ′ (q<br />

0 ′, w) = ˆδ(q 0 , w), ∀w ∈ Σ ∗<br />

L(A ′ ) = L(A)<br />

LFAC (2014-15) Curs 3 9 / 30


<strong>Automate</strong> finite cu ǫ-tranziţii<br />

Automatul determinist echivalent - algoritm<br />

Intrare: Automatul A (cu ǫ - tranziţii) ; Cl(S)<br />

Ie<strong>şi</strong>re: Automatul determinist A ′ = (Q ′ ,Σ,δ ′ , q 0 ′, F′ ), echivalent cu A.<br />

q 0 ′ = Cl({q 0}); Q ′ = {q 0 ′} ;<br />

marcat(q 0 ′) = false; F′ = ∅ ;<br />

if (q 0 ′ ∩ F ≠ ∅) then F′ = F ′ ∪{q 0 ′} ;<br />

while (∃S ∈ Q ′ &&!marcat(S)) { // S este nemarcat<br />

for (a ∈ Σ){<br />

S ′ = Cl(δ(S, a));<br />

δ ′ (S, a) = S ′ ;<br />

if (S ′ ∉ Q ′ ){<br />

Q ′ = Q ′ ∪{S ′ };<br />

marcat(S ′ ) = false;<br />

if (S ′ ∩ F ≠ ∅) then F ′ = F ′ ∪{S ′ } ;<br />

}<br />

}<br />

marcat(S) = true;<br />

}<br />

LFAC (2014-15) Curs 3 10 / 30


<strong>Automate</strong> finite cu ǫ-tranziţii<br />

Exemplu<br />

LFAC (2014-15) Curs 3 11 / 30


<strong>Automate</strong> finite cu ǫ-tranziţii<br />

Exemplu<br />

LFAC (2014-15) Curs 3 11 / 30


Gramatici de tip 3 <strong>şi</strong> automate finite<br />

Curs 3<br />

1 <strong>Automate</strong> finite cu ǫ-tranziţii<br />

2 Gramatici de tip 3 <strong>şi</strong> automate finite<br />

3 Automatul determinist minimal<br />

LFAC (2014-15) Curs 3 12 / 30


Gramatici de tip 3 <strong>şi</strong> automate finite<br />

De la gramatici de tip 3 la automate finite<br />

Pentru orice gramatică G de tip 3 (în formă normală) există un<br />

automat A (nedeterminist) astfel ca L(A) = L(G):<br />

În gramatica G În automatul A<br />

T Σ = T<br />

N Q = N ∪{f}, F = {f}<br />

S<br />

q 0 = S<br />

q → ap p ∈ δ(q, a)<br />

q → a f ∈ δ(q, a)<br />

dacă S → ǫ se adaugă S la F<br />

LFAC (2014-15) Curs 3 13 / 30


Gramatici de tip 3 <strong>şi</strong> automate finite<br />

De la automate finite la gramatici de tip 3<br />

Pentru orice automat finit (determinist) există o gramatică G de tip<br />

3 astfel ca L(A) = L(G):<br />

În automatul A<br />

Σ<br />

Q<br />

În gramatica G<br />

T = Σ<br />

N = Q<br />

q 0 S = q 0<br />

δ(q, a) = p q → ap<br />

δ(q, a) ∈ F q → a<br />

dacă q 0 ∈ F se adaugă q 0 → ǫ<br />

LFAC (2014-15) Curs 3 14 / 30


Automatul determinist minimal<br />

Curs 3<br />

1 <strong>Automate</strong> finite cu ǫ-tranziţii<br />

2 Gramatici de tip 3 <strong>şi</strong> automate finite<br />

3 Automatul determinist minimal<br />

LFAC (2014-15) Curs 3 15 / 30


Automatul determinist minimal<br />

Stări accesibile<br />

Fie A = (Q,Σ,δ, q 0 , F) automat finit determinist<br />

Starea q este accesibilă în A dacă există un cuvânt w ∈ Σ ∗ astfel încât<br />

q = δ(q 0 , w).<br />

LFAC (2014-15) Curs 3 16 / 30


Automatul determinist minimal<br />

Stări inseparabile<br />

Fie A = (Q,Σ,δ, q 0 , F) un automat finit determinist.<br />

Definiţie 3<br />

Stările q 1 <strong>şi</strong> q 2 sunt inseparabile în raport cu F , (notat q 1 ρq 2 ) ddacă<br />

∀w ∈ Σ ∗ : δ(q 1 , w) ∈ F ⇔ δ(q 2 , w) ∈ F<br />

LFAC (2014-15) Curs 3 17 / 30


Automatul determinist minimal<br />

Stări inseparabile<br />

Fie A = (Q,Σ,δ, q 0 , F) un automat finit determinist.<br />

Definiţie 3<br />

Stările q 1 <strong>şi</strong> q 2 sunt inseparabile în raport cu F , (notat q 1 ρq 2 ) ddacă<br />

∀w ∈ Σ ∗ : δ(q 1 , w) ∈ F ⇔ δ(q 2 , w) ∈ F<br />

Dacă există w ∈ Σ ∗ cu δ(q 1 , w) ∈ F <strong>şi</strong> δ(q 2 , w) ∉ F (sau invers),<br />

stările q 1 <strong>şi</strong> q 2 sunt separabile (de către w), <strong>şi</strong> notăm q 1 sep q 2<br />

q 1 sep q2 ⇔ ¬q 1 ρq 2 .<br />

LFAC (2014-15) Curs 3 17 / 30


Automatul determinist minimal<br />

Stări inseparabile<br />

Fie A = (Q,Σ,δ, q 0 , F) un automat finit determinist.<br />

Definiţie 3<br />

Stările q 1 <strong>şi</strong> q 2 sunt inseparabile în raport cu F , (notat q 1 ρq 2 ) ddacă<br />

∀w ∈ Σ ∗ : δ(q 1 , w) ∈ F ⇔ δ(q 2 , w) ∈ F<br />

Dacă există w ∈ Σ ∗ cu δ(q 1 , w) ∈ F <strong>şi</strong> δ(q 2 , w) ∉ F (sau invers),<br />

stările q 1 <strong>şi</strong> q 2 sunt separabile (de către w), <strong>şi</strong> notăm q 1 sep q 2<br />

q 1 sep q2 ⇔ ¬q 1 ρq 2 .<br />

Observaţie: dacă q 1 ∈ F <strong>şi</strong> q 2 ∉ F , atunci q 1 sep q 2<br />

LFAC (2014-15) Curs 3 17 / 30


Automatul determinist minimal<br />

Exemplu<br />

LFAC (2014-15) Curs 3 18 / 30


Automatul determinist minimal<br />

Automat minimal<br />

Observaţii:<br />

Relatia ρ este relaţie de echivalenţă.<br />

∃a ∈ Σ : δ(p, a) sep δ(q, a) =⇒ p sep q.<br />

LFAC (2014-15) Curs 3 19 / 30


Automatul determinist minimal<br />

Automat minimal<br />

Observaţii:<br />

Relatia ρ este relaţie de echivalenţă.<br />

∃a ∈ Σ : δ(p, a) sep δ(q, a) =⇒ p sep q.<br />

Teorema 2<br />

Fie A un automat determinist cu toate stările accesibile. Daca toate<br />

stările din A sunt separabile în raport cu F, atunci nu există un alt<br />

automat A ′ cu număr mai mic de stări <strong>şi</strong> L(A) = L(A ′ ).<br />

LFAC (2014-15) Curs 3 19 / 30


Automatul determinist minimal<br />

Automatul minimal<br />

Fie A = (Q,Σ,δ, q 0 , F) un automat finit determinist si relaţia ρ.<br />

Dacă ∀q 1 , q 2 ∈ Q : q 1 sep q 2 , atunci A este minimal.<br />

Altfel, automatul minimal:<br />

A ρ = (Q/ρ,Σ,δ ρ ,[q 0 ], F/ρ)<br />

Q/ρ - clasele de echivalenţă ale relaţiei ρ:<br />

Q/ρ = {[q]|q ∈ Q}<br />

δ ρ ([q], a) = [δ(q, a)]<br />

[q 0 ] clasa de echivalenţă în care se află starea q 0<br />

F/ρ = {[q]|q ∈ F}<br />

LFAC (2014-15) Curs 3 20 / 30


Automatul determinist minimal<br />

Exemplu<br />

LFAC (2014-15) Curs 3 21 / 30


Automatul determinist minimal<br />

Automatul minimal<br />

Fie automatul minimal: A ρ = (Q/ρ,Σ,δ ρ ,[q 0 ], F/ρ)<br />

Q/ρ - clasele de echivalenţă ale relaţiei ρ:<br />

δ ρ ([q], a) = [δ(q, a)]<br />

[q 0 ] clasa de echivalenţă în care se află starea q 0<br />

F/ρ = {[q]|q ∈ F}<br />

Teorema 3<br />

Fie automatul determinist A, cu toate stările accesibile. Automatul A ρ<br />

construit ca mai sus este automatul cu număr minim de stări care<br />

acceptă limbajul L(A).<br />

LFAC (2014-15) Curs 3 22 / 30


Automatul determinist minimal<br />

Algoritm pentru determinarea relaţiei ρ<br />

Fie A = (Q,Σ,δ, q 0 , F), Q = {q 0 , q 1 ,...,q n }<br />

Tablou separabil[q i , q j ]:<br />

separabil[q i , q j ] = 1 ddacă q i sep q j (separabil[q i , q j ] = 0 ddacă<br />

q i ρq j )<br />

iniţial separabil[q i , q j ] = 1 ddacă q i ∈ F, q j ∉ F (sau invers)<br />

dacă există a ∈ Σ cu δ(q i , a) sep δ(q j , a), atunci q i sep q j , adică :<br />

dacă separabil[q i , q j ] = 0 <strong>şi</strong> există a ∈ Σ cu<br />

separabil[δ(q i , a),δ(q j , a)] = 1, atunci separabil[q i , q j ] = 1<br />

LFAC (2014-15) Curs 3 23 / 30


Automatul determinist minimal<br />

Algoritm pentru determinarea relaţiei ρ<br />

lista[p, r] : (p ≠ r)<br />

o pereche de stări inseparabile (q i , q j ) (separabil[q i , q j ] = 0 ) se<br />

adaugă la lista[p, r] dacă:<br />

⇐⇒<br />

există a ∈ Σ astfel încât p = δ(q i , a), r = δ(q j , a) ((qi, qj) ≠ (p, r))<br />

separabil[p, r] = 0<br />

(qi, qj) → lista[δ(q i , a),δ(qj, a)] dacă separabil[q i , q j ] = 0 <strong>şi</strong><br />

separabil[δ(q i , a),δ(qj, a)] = 0<br />

LFAC (2014-15) Curs 3 24 / 30


Automatul determinist minimal<br />

Algoritm pentru determinarea relaţiei ρ<br />

lista[p, r] : (p ≠ r)<br />

o pereche de stări inseparabile (q i , q j ) (separabil[q i , q j ] = 0 ) se<br />

adaugă la lista[p, r] dacă:<br />

⇐⇒<br />

există a ∈ Σ astfel încât p = δ(q i , a), r = δ(q j , a) ((qi, qj) ≠ (p, r))<br />

separabil[p, r] = 0<br />

(qi, qj) → lista[δ(q i , a),δ(qj, a)] dacă separabil[q i , q j ] = 0 <strong>şi</strong><br />

separabil[δ(q i , a),δ(qj, a)] = 0<br />

dacă p <strong>şi</strong> r devin la un moment dat separabile, atunci perechile de<br />

stări (q i , q j ) din lista[p, r] devin separabile:<br />

Fie (q i , q j ) ∈ lista[p, r] ⇒ ∃a : p = δ(q i , a), r = δ(q j , a)<br />

p sep r ⇔ δ(q i , a) sep δ(q j , a) =⇒ q i sep q j<br />

LFAC (2014-15) Curs 3 24 / 30


Automatul determinist minimal<br />

Algoritm pentru determinarea relaţiei ρ<br />

Se iniţializează tabloul separabil (separabil[q i , q j ] = 1, dacă<br />

q i ∈ F , q j ∉ F sau invers)<br />

Pentru orice q i , q j (0 ≤ i < j ≤ n) cu separabil[q i , q j ] = 0 :<br />

LFAC (2014-15) Curs 3 25 / 30


Automatul determinist minimal<br />

Algoritm pentru determinarea relaţiei ρ<br />

Se iniţializează tabloul separabil (separabil[q i , q j ] = 1, dacă<br />

q i ∈ F , q j ∉ F sau invers)<br />

Pentru orice q i , q j (0 ≤ i < j ≤ n) cu separabil[q i , q j ] = 0 :<br />

Dacă există a ∈ Σ cu separabil[δ(q i , a),δ(q j , a)] = 1, atunci:<br />

separabil[q i , q j ] = 1<br />

trebuie modificat tabloul separabil pentru toate perechile de stări a<br />

căror separabilitate depinde de q i , q j (perechile de stări din<br />

lista[q i , q j ])<br />

LFAC (2014-15) Curs 3 25 / 30


Automatul determinist minimal<br />

Algoritm pentru determinarea relaţiei ρ<br />

Se iniţializează tabloul separabil (separabil[q i , q j ] = 1, dacă<br />

q i ∈ F , q j ∉ F sau invers)<br />

Pentru orice q i , q j (0 ≤ i < j ≤ n) cu separabil[q i , q j ] = 0 :<br />

Dacă există a ∈ Σ cu separabil[δ(q i , a),δ(q j , a)] = 1, atunci:<br />

separabil[q i , q j ] = 1<br />

trebuie modificat tabloul separabil pentru toate perechile de stări a<br />

căror separabilitate depinde de q i , q j (perechile de stări din<br />

lista[q i , q j ])<br />

Altfel (pentru orice a ∈ Σ are loc separabil[δ(q i , a),δ(q j , a)] = 0):<br />

pentru orice a ∈ Σ cu δ(q i , a) ≠ δ(q j , a) adaugă (q i , q j ) la<br />

lista[δ(q i , a),δ(q j , a)]<br />

LFAC (2014-15) Curs 3 25 / 30


Automatul determinist minimal<br />

Algoritm pentru determinarea relaţiei ρ<br />

//initializarea tablourilor,<br />

se marchează perechile F ×(Q − F) si (Q − F)×F<br />

1.for (i=0; i


Automatul determinist minimal<br />

9.for (i=0; i


Automatul determinist minimal<br />

Algoritm pentru determinarea relaţiei ρ<br />

// qi si qj devin separabile si la fel toate<br />

// perechile de stari dependente de qi,qj<br />

update separabil(qi, qj){<br />

separabil[qi, qj] = 1;<br />

for ((q i, ′ q j) ′ ∈ lista[qi, qj]){<br />

if (separabil[q i, ′ q j] ′ == 0)<br />

update separabil(q i, ′ q j);<br />

′<br />

}<br />

}<br />

LFAC (2014-15) Curs 3 28 / 30


Automatul determinist minimal<br />

Exemplu<br />

LFAC (2014-15) Curs 3 29 / 30


Automatul determinist minimal<br />

Exemplu<br />

LFAC (2014-15) Curs 3 29 / 30


Automatul determinist minimal<br />

Exemplu<br />

LFAC (2014-15) Curs 3 29 / 30


Automatul determinist minimal<br />

Exemplu<br />

LFAC (2014-15) Curs 3 29 / 30


Automatul determinist minimal<br />

Exemplu<br />

LFAC (2014-15) Curs 3 29 / 30


Automatul determinist minimal<br />

Exemplu<br />

LFAC (2014-15) Curs 3 29 / 30


Automatul determinist minimal<br />

Corectitudinea algoritmului<br />

Teorema 4<br />

Algoritmul se termină întotdeauna <strong>şi</strong> în final se obţine, pentru orice<br />

două stări q i <strong>şi</strong> q j , 0 ≤ i < j ≤ n: separabil[q i , q j ] = 1 ddacă q i sep q j<br />

LFAC (2014-15) Curs 3 30 / 30


Automatul determinist minimal<br />

Corectitudinea algoritmului<br />

Teorema 4<br />

Algoritmul se termină întotdeauna <strong>şi</strong> în final se obţine, pentru orice<br />

două stări q i <strong>şi</strong> q j , 0 ≤ i < j ≤ n: separabil[q i , q j ] = 1 ddacă q i sep q j<br />

(⇐=) Se arată că:<br />

P(k) : Pentru orice două stări q i <strong>şi</strong> q j (0 ≤ i < j ≤ n) separabile de către un cuvânt w<br />

cu |w| ≤ k (δ(q i , w) ∈ F,δ(q j , w) ∉ F), are loc:<br />

separabil[q i , q j ] = 1.<br />

Inducţie după |w|.<br />

LFAC (2014-15) Curs 3 30 / 30

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!