Synchronous Dataflow Pattern Matching

Werbung
Synchronous Dataflow Pattern Matching
Christian Cikryt und Jakob Pfender
FU Berlin
Institut für Informatik
Seminar über Programmiersprachen
23. Juli 2013
Einleitung
Thema der Arbeit
Einführung von varianten Typen
”
(Datenstruktur) und Pattern
Matching (Kontrollstruktur) in
synchrone Datenflusssprachen“
Begriffsdefinitionen
Reaktive Systeme
▶
Ständige Interaktion mit der Umgebung
▶
Umgebung gibt die Geschwindigkeit vor
▶
Beispiele: Mikrowellen, Roboter, industrielle
Steuerungsanlagen
Synchrone Datenflusssprachen
▶
Sprachen für die Entwicklung reaktiver Systeme
▶
Funktionale Programmiersprachen auf unendlichen
Datenströmen
▶
Beispiele: LUSTRE, SCADE, SIGNAL
Clocks und Clock Calculus
Clock
▶
(De)aktiviert Programmteile in synchronen Datenflusssprachen
▶
Repräsentiert Geschwindigkeit eines Ausdrucks
▶
Erlaubt Modellierung paralleler Prozesse mit unterschiedlichen
Geschwindigkeiten
Clock Calculus
▶
Beweisbar korrekte statische Analysemethode
▶
Für Ausdrücke mit unterschiedlichen Geschwindigkeiten
Variante Typen und Pattern Matching
▶
Bekannt aus der funktionalen Programmierung
▶
Variante Typen speichern Werte, der einen von mehreren
vordefinierten Typen annehmen kann
▶
Erhöhte Typsicherheit durch Pattern Matching
Variante Typen und Pattern Matching – Beispiel
type 'a baum = Blatt
| Knoten of 'a * 'a baum * 'a baum
let rec mitglied x baum =
match baum with
| Blatt -> false
| Knoten(y, links, rechts) ->
if x = y then true else
member x links || member x rechts;;
Motivation und Ziele
Mangel an Datenstrukturen
▶
Synchrone Datenflusssprachen unterstützen nur sehr wenige
Datentypen (Boolean, ganze Zahlen, Fließkommazahlen,
Arrays)
▶
Mit steigender Komplexität reaktiver Systeme steigen auch
Anforderungen an die Sprache
Mangel an Konstrollstrukturen
▶
Sequentielles oder sich entwickelndes Verhalten funktional
auszudrücken ist nicht trivial
▶
Existierende Sprachen haben auf unterschiedlichste Art
versucht, Kontrollstrukturen einzuführen
▶
Hier gelöst durch Clock Calculus, Pattern Matching und
variante Typen
Die Sprache
Beispiel
type event = Left | Middle | Right
let up_down mouse = count where
rec count = 0 ->
match mouse with
| Left on c => (pre count) when c + 1
| Middle => 0
| Right on c => (pre count) when c - 1
Operationelle Semantik von WHEN
[]
▶
WHEN-[]:
[]
R ⊢ e1 −
→e′1
R ⊢ e1
R ⊢ e2 −
→e′2
[]
when
e2 −
→e′1
c
▶
WHEN-T:
R ⊢ e1 →
− e′1
R ⊢ e1
when
c
▶
WHEN-F:
R ⊢ e1 →
− e′1
R ⊢ e1
when
e′2
true
R ⊢ e2 −−→e′2
c
e2 −
→e′1
when
R ⊢ e2 −−→e′2
[]
when
e′2
false
e2 −
→e′1
when
e′2
Erweitertes Beispiel
type event = Left | Right | Middle | Key of int
let up_down event = count where
rec count, step = (0,1) ->
match event with
| Left on c => ((pre count) + step, pre step) when c
| Middle on c => 0, (pre step) when c
| Right on c => ((pre count) - step, pre step) when c
| Key i on c => (pre count) when c, i
Clocks und Pattern Matching
Clocks und Pattern Matching – Beispiel
type number = Int of int | Float of float
let float_of_number n =
match n with
| Int i => float i
| Float f => f
Es gilt:
c1 ∧ c2 = false c1 ∨ c2 = cl
Eigenschaften der Branch Clocks
▶
Subclocks des gematchten Elements
▶
Gegenseitiger Ausschluss
▶
Genau eine Branch Clock muss verfügbar sein
▶
Pattern Matching vollständig definiert
Benennung
Explizit mit
on-Schlüsselwort:
match event with
. . .
| (Key i) on c => (pre count) when c, i
Implizit:
pre (x when c)
(pre x) when c
Zusammenfassen von Ausdrücken:
match event, (pre count) with
. . .
| (Key i), pc => (pc, i)
Formalisierung
Grammatik
e ::= c | x | op(e, e) | c
D ::= D
and
D|D
c ::= i |
fun
x.y
with
D
d ::= x
in
with
fby
when
e
D | x = e | x = e(e)
D
i ::= true | false | 0 | ...
op ::= + | ...
e|e
Operationelle Semantik
v
▶
R⊢e−
→ e′
▶
R ⊢ D −→ D′
▶
R⊢d−
→ d′
R′
v
Formalisierung des Clock Calculus
Grammatik:
σ ::= ∀α1 , ..., αm .∀K1 , ..., Kk .cl
cl ::= cl → cl | s | (k : s)
s ::= base | s
k ::= x | K
Operationelle Semantik:
▶
H ⊢ e : cl
▶
H ⊢ D : H′
▶
H ⊢ d : cl
on
k|α
n, m, k ∈ N
Formalisierung der Erweiterungen
Deklaration varianter Typen
type
(α1 , ..., αm ) t = C1
of τ1
| ... | Cn
Grammatik
e ::=... | C1 (e) | ... | Cn (e)
P ::= c | x | C1 (P) | ... | Cn (P)
D ::= x = match e
| P1
with
on
x 1 ⇒ d1
on
xn ⇒ dn
...
| Pn
of τn
Formalisierung der Erweiterungen
Erweiterung durch Konstruktoren:
sv ::= c | C1 (sv) | ... | Cn (sv)
v ::= sv | []
Reduktionsregeln:
[]
R⊢e−
→ e′
[]
R ⊢ Ci (e) −−−→ Ci (e′ )
R⊢e−
→ e′
R ⊢ Ci (e) −
→ Ci (e′ )
sv
Ci (sv)
Reduktionsregeln für Pattern Matching
MATCH-[]:
[]
R, [[]/x] ⊢ e −
→ e′
[]
∀i ∈ {1, ..., n}R, [[]/x], [[]/xi ], [F/ci ] ⊢ di −
→ d′i
x = match e′ with
| P1 (x1 ) on c1 ⇒ d′1
x = match e with
| P1 (x1 ) on c1 ⇒ d1
R⊢
...
| Pn (xn )
[[]/x]
on cn
⇒ dn
−−−→
...
| Pn (xn )
on cn
⇒ d′n
Reduktionsregeln für Pattern Matching
MATCH:
Pj (vj )
R, [v/x] ⊢ e −−−→ e′
v
R, [v/x], [vj /xj ], [T/cj ], ⊢ dj →
− d′j
[]
∀i ∈ {1, ..., n} such that i ̸= j, R, [v/x], [[]/xi ], [F/ci ] ⊢ di −
→ d′i
x = match e′ with
| P1 (x1 ) on c1 ⇒ d′1
x = match e with
| P1 (x1 ) on c1 ⇒ d1
R⊢
...
| Pn (xn )
[v/x]
on cn
⇒ dn
−−−→
...
| Pn (xn )
on cn
⇒ d′n
Reduktionsregeln für erweiterten Clock Calculus
C-H:
H⊢e:s
H ⊢ C(e) : s
MATCH-H:
H, [x : cl] ⊢ e : cl
∀i ∈ {1, ..., n} : H, Hi ⊢ Pi : cl on ci H, Hi , [x : cl] ⊢ di : cl
ci ∈
/ fvcl (H), Dom(Hi ) = fvPi
H⊢
x = match e with
| P1 (x1 ) on c1 ⇒ d1
...
| Pn (xn ) on cn ⇒ dn
: [x : cl]
on
ci
Kritik
Probleme bei der Übersetzung
Beispielprogramm:
match v with
| true on c => let rec nat = 0 fby (nat + 1) in
(nat when c)
| false => 0
Ist äquivalent zu:
let rec nat = 0 fby (nat + 1) in
match v with
| true on c => nat when c
| false => 0
Probleme bei der Übersetzung
Beispielprogramm:
match v with
| true on c => let rec nat = 0 fby (nat + 1) in
let x = (merge c nat 0) in
(x when c)
| false => 0
Ist äquivalent zu:
let nat, c =
match c with
| true => let rec nat = 0 fby (nat + 1) in
nat, true
| false => 0, false in
let x = merge c (nat when c) 0 in
match v with
| true => x when c
| false => 0
Die Programmstruktur wurde durch die Übersetzung verändert!
Kritik – Zusammenfassung
▶
Übersetzung von Pattern Matching-Ausdrücken ist alles
andere als trivial
▶
Wenn sich nicht alle Ausdrücke nach ihrer Branch Clock
richten kann nicht 1:1 übersetzt werden
▶
Automatisches Umschreiben ist möglich, kann aber u.U. keine
Abhängigkeiten bewahren
▶
Theoretische Überlegungen somit praktisch nicht umsetzbar
Verwandte Arbeiten
Verwandte Arbeiten
▶
ARGOS: Beschreibung reaktiver Systeme als Automaten
mittels graphischer Syntax
▶
SYNCHRONIE: Integration imperativer, deklarativer und
graphischer Programmierparadigmen
▶
Girault et al.: Semantik hierarchische endliche
Zustandsautomaten
▶
Mode-Automata: Erweiterung von LUSTRE um Automaten
als Kontrollstruktur
▶
Pouzet et al.: Clock Calculus als Typsystem angelehnt an ML
Adaptionen
LUCID SYNCHRONE Compiler:
▶
Implizite Filterung von freien Variablen
▶
Unterausdrücke nie schneller als Branch Clock
SCADE Compiler (experimentell):
▶
Beschränkt auf Aufzählungstypen (keine Argumente in
Konstruktoren)
▶
Pattern Matching als mehrere Kontrollstrukturen in
Hostsprache kompiliert
▶
Genutzt zur Modellierung von Automaten
Fazit
Fazit
▶
Ausführliche Ausarbeitung zu varianten Typen und Pattern
Matching als Kontrollstruktur auf theoretischer Ebene
▶
Erfolgreiche Umsetzung des Clock Calculus als
Kontrollstruktur
▶
Übertragung von der Theorie in die Praxis herausfordernd
Diskussion
Fragen?
Herunterladen