Regular Expression Types Moritz Fuchs
Agenda Wiederholung Reguläre Ausdrücke Regular Expression Types Beispiele
Reguläre Ausdrücke
Beschreiben die regulären Sprachen Kompakt Ausdrucksstark Eindeutiger minimaler DFA!
Regeln Basiswörter Aneinanderreihung Alternative Kleene-Stern Nützliche Makros
Grundlagen ε ist das leere Wort ∑ ist das Zielalphabet A-Z 0,1 String,Int,Float,...
Basiswörter a ∈ ∑ ∪ {ε} Beispiele: α = t α = ε
Aneinanderreihung α, β seien reguläre Ausdrücke Dann ist γ = αβ ein regulärer Ausdruck Bedeutung: Erst α dann β
Alternative α,β reguläre Ausdrücke Dann ist γ = α ∣ β ein regulärer Ausdruck Bedeutung: Einer der Ausdrücke muss erfüllt sein
Kleene-Stern Sei α ein regulärer Ausdruck Dann ist γ = α* ein regulärer Ausdruck Bedeutung: 0 oder mehr
? - Makro α wieder regulärer Ausdruck γ = α? steht für α ∣ ε Bedeutung: Optionalität
+ - Makro α wieder regulärer Ausdruck γ = α+ steht für αα* Bedeutung: „Einmal oder mehr“
Beispiel - Adressbuch
Regular Expression Types
Reguläre Ausdrücke in Typsystemen Subtyping Rekursive Definitionen Polymorphe Funktionen Vor- und Nachteile
Beispiel RET type Addrbook = addrbook[Person*] type Person = person[Name, *,Tel?] type Name = name[String] type = [String] type Tel = tel[String]
Beispiel ohne RET type Addrbook = addrbook[SomePersons] type SomePersons = Person,SomePersons | () type Person = person[Name,Some s,OptionalTel] type Some s = ,Some s | () type OptionalTel = Tel | () type Name = name[String] type = [String] type Tel = tel[String]
Subtyping Inklusionsbeziehnung zwischen regulären Ausdrücken Inklusionsbeziehung zwischen Tree Automata Potentiell sehr teuer (EXPTIME-vollständig)
Subtyping Beispiel type Addrbook = addrbook[Person*] type Person = person[Name, *,Tel?] person[Name, *,Tel?] <: person[Name, *,Tel*]
Rekursive Definitionen type betterAddrbook = Eintrag* type Eintrag = name[String], betterAddrbook | person[Name, *,Tel?], (important[] | unimportant[])
Rekursive Definitionen Nicht alle Arten erlaubt Sonst wäre Inklusion nicht mehr entscheidbar Ausdrücke müssen,wohlgeformt‘ sein
Wohlgeformtheit type X = a[],Y type Y = b[],X | ()
Subtyping bei Rekursiven Definitionen type importantAddrbook = Eintrag* type Eintrag = name[String], importantAddrbook | person[Name, *,Tel?], important[] importantAddrbook <: betterAddrbook
Polymorphe Funktionen filter (a | b)* -> b* filter (x :: b, xs :: (a | b)* ) = ( x, filter xs ) filter (x :: a, xs :: (a | b)* ) = filter xs filter () = ()
Polymorphe Funktionen Problem: Mehrdeutige Instanzierungen: filter (C | C)* -> C* filter (x :: C, xs :: (C | C)* ) = ( x, filter xs ) filter (x :: C, xs :: (C | C)* ) = filter xs filter () = () Alle akzeptieren? Alle ablehnen?
Polymorphe Funktionen Lösung: Mehrdeutige Instanzierungen werden abgelehnt! Potentiell mehrdeutige Instanzierungen werden trotzdem akzeptiert
Vor- und Nachteile flexibel kompakt Potentiell langsam durch Inklusionsprüfung für Subtyping
Implementierungen XDuce (Beispiel 1) XHaskell (Beispiel 2) CDuce...
XDuce
Optimiert für XML-Verarbeitung Erste Spracherweiterung für Regular Expression Types
Subtagging Zusätzlich zum Subtyping manuelle Subtypen: subtag pizza <: essen subtag nudeln <: essen
~ Für jedes label l gilt: subtag l <: ~ Nützlicher Typ Any: type Any = (~[Any] | String | Int | Float)*
FUN!
Beispiel 1 - XDuce XML-Datenbankerweiterung
Ausgangssituation Moritz Fuchs Max Mustermann il> < n>
Ausgangssituation type Addrbook = addrbook[Person*] type Person = person[Name, *,Tel?] type Addrbook = addrbook[Person*] type Person = person[Name, *,Tel*]
2. Datenbank type Addrbook2 = addrbook[Person2*] type Person2 = person[Name, *,Addr]
Integration Erste Idee: type Addrbook3 = addrbook[Person1*,Person2*] Nachteil: 2 Schleifen nötig für die Verarbeitung Lösung: Umformung des regulären Ausdrucks
Integration person[Name, *,Tel*] | person[Name, *,Addr] Idee: (Person1*, Person2*) ist Subtyp von (Person1 | Person2)* = person[(Name, *,Tel*) | (Name, *,Addr)] = person[(Name, *, (Tel* | Addr)]
Lösung type Addrbook3 = addrbook[Person3*] type Person3 = person[Name, *,(Tel* | Addr)]
Beispiel XHaskell Von einem Adressbuch zu einem Telefonbuch - in 8 Zeilen
Ausgangssituation data Person = Person Name ( *) (Tel*) data Name = Name String data Tel = Tel String data = String data Eintrag = Eintrag (Name,Tel+) data Buch a= Buch a* type AddrBuch = Buch Person type Telefonbuch = Buch Eintrag
Schritt 1- Person zu Eintrag p2E :: Person -> Eintrag? p2E (Person (n:: Name)(es :: *) (t::Tel+)) = Eintrag (n,t) p2E (Person (n:: Name) (es :: *) (t::())) = ()
Schritt 2- mapStar mapStar :: (a -> b) -> a* -> b* mapStar f (x :: ()) = x mapStar f (x::a, xs::a*) = (f x, mapStar f xs)
Schritt 3- Adressbuch zu Telefonbuch ab2tb :: Addrbuch -> Telefonbuch ab2tb (Buch (x :: Person*)) = Buch (mapStar pToE x)
Beispiel XHaskell λ-Funktionen
Ausgangssituation data Female = F data Male = M members :: (Female | Male)* Ziel: (Female*, Male*)
fold :: (a -> b -> a) -> a -> b* -> a fold f x (y :: ()) = x fold f x ((y::b)(ys::b*)) = fold f (f x y) ys Schritt 1- fold
transform :: (a | b)* -> (a*,b*) transform xs = fold (\x->\y -> case y of (z::a) -> (z,x) (z::b) -> (x,z)) () xs Schritt 2- transformation transform members
Fragen?