Informatik 3 WS 2002/3

Werbung
Informatik 3
WS 2002/3
http://www.cs.inf.ethz.ch/37-003/
Prof. Jürg Gutknecht
ETH Zürich
29. März, 2003
1
Themenübersicht
Programmierparadigmen (1)
• Imperative Programmierung
¾Nichtdeterminismus
¾Guarded Commands
¾Unity
2
Themenübersicht
Programmierparadigmen (2)
• Funktionale Programmierung
¾ Einführung in die Sprache SML
¾ Funktionen, Höhere Funktionen
¾ Datentypen, Konstruktoren
¾ Typeninferenzmechanismus
¾ Parametrische Polymorphie
¾ Listen- und Baumstrukturen
¾ Fallstudie Interpreter
¾ Module und Funktoren, Abstrakte Datentypen
¾ Evaluations Strategien, Lazy Evaluation
3
Themenübersicht
Programmierparadigmen (3)
• Logische Programmierung
¾Einführung in Prolog
¾Horn Klauseln
¾Deduktionsmaschine
• Deskriptive Programmierung
¾Einführung in XML
¾Tags und Attribute
¾Meta Beschreibung (Schemas)
4
Nichtdeterministische
Imperative Programmierung
5
Imperative Programmierung
Formale Grundbegriffe
• Zustandsraum X
• Prädikate P, Q, ... über X
• Anweisungen S, T, ...
¾Zustandstransformator x → S(x)
¾Prädikatentransformator Q → wp(S, Q)
• Hoare Triplet { P } S { Q }
P ⇒ wp(S, Q)
weakest
precondition
6
Imperative Programmierung
Guarded Commands (Dijkstra)
•
•
•
•
•
•
•
Fehlerhalt Anweisung abort
Neutrale Anweisung skip
Mehrfachzuweisung x, y, ... := E, F, ...
Sequenz S; T
Guarded Command P → S
Alternative if P → S | Q → T | … fi
Repetition do P → S | Q → T | … od
nichtdeterministische
Auswahl
7
Guarded Commands
Semantik
• Semantik der Zuweisung
¾Zuweisung x := E
¾wp(x := E, Q) = Qx := E
in Q x durch E
substituieren
• Zwei Implementationen von x, y := y, x
¾t := x; x := y; y := t
(x – (x – y ) = X) ∧ (x - y = Y)
¾
x := x + y; (y = X) ∧ (x + y - y = Y)
y := x – y; (x - y = X) ∧ (y = Y)
x := x – y (x = X) ∧ (y = Y)
Q
8
Guarded Commands
Sortieralgorithmus
• Nichtdeterministische Formulierung
H :⇔ (a, b, c) ist Permutation von (A, B, C)
a, b, c := A, B, C; { H }
Invariante
do
a > b → a, b := b, a { H }
| b > c → b, c := c, b { H }
od
Termination ?
{ (a ≤ b ≤ c) ∧ H }
• Sequentielle Implementation
¾Bubblesort
Ueberspezifikation
9
Guarded Commands
Problem des Stipendienbetrügers
• f, g, h lexikografisch geordnete Namen von
Studierenden, Stipendiaten, Angestellten
Crook(x) :⇔ (∃ i, j, k: x = f(i), g(j), h(k))
H :⇔ (∀x: x < min(f(I), g(J), h(K)): ¬Crook(x))
I, J, K := 0, 0, 0; { H }
Sentinel
do
garantiert
f(I) < g(J) → I := I + 1 { H }
Termination
| g(J) < h(K) → J := J + 1 { H }
| h(K) < f(I) → K := K + 1 { H }
od
{ (f(I) ≥ g(I) ≥ h(K) ≥ f(I)) ∧ H }
10
Unity Formalismus
Problem: Nächstmögliche Meetingzeit
• Terminkalender f
Chandy & Misra
¾(∀t: f(t) ≥ t, f(f(t)) = f(t))
• f, g, h Terminkalender
Unity Programm
t := 0;
t := f(t) || t := g(t) || t := h(t)
¾ Termination: Sobald Fixpunkt erreicht ist
¾ Faire Auswahl: Jede Zuweisung kommt
nach endlich vielen Schritten an die Reihe
11
Unity Formalismus
Problem: Nächstmögliche Meetingzeit
• Invariante
(∀s: s < t: s ist keine mögliche Meetingzeit)
• Beweis mit vollständiger Induktion
¾Wahr bei Programmstart
¾Wahr nach jeder Ausführung
einer Zuweisung
12
Unity Formalismus
Problem: Nächstmögliche Meetingzeit
• Implementationen
¾Von Neumann Rechner oder Ring
• LOOP r := f(r); r := g(r); r := h(r) END;
• LOOP
r := f(r); r := g(r); r := f(r); r := h(r)
END
Zentraler
¾Verteiltes System
Koordinator
• r := max (f(r), g(r), h(r))
f
f
Token Ring
g
h
g
h
13
Programmspezifikation
Ebenenmodell
Problem
•Guarded Commands
Spezifikation •Unity
•...
Implementation
Systemarchitektur
Von
Neumann
SMP Verteiltes
System14
Funktionale Programmierung
15
Programmierparadigmen
Kommentar von John Backus
• The assignment statement splits programming in two worlds. The
first world is the world of the right-hand sides. This is an
orderly world of expressions with useful algebraic properties. It
is the world in which useful computation takes place.
• The second world is the world of statements. The primary
statement is the assignment statement itself. All the other
statements exist in order to make it possible to perform a
computation that is based on this primitive construct: the
assignment statement itself.
• The world of statments is a disorderly one, with few useful
mathematical properties. Structured programming can be seen
as a modest effort to introduce some order to this chaotic
world, but it accomplishes little in attacking the fundamental
problems created by word-at-a-time von Neumann-style of
programming.
16
Funktionale Programmierung
Grundprinzipien
• Speicherloses Ablaufsmodell
¾ Wegabstrahierung von Speicherzuständen
und Zustandsübergängen
• Funktion als Programmelement
¾ Resultat als Funktion der Argumente y = f(x)
¾ Keine Nebeneffekte
• Komposition von Funktionen/ Programmen
¾ (g°f) (x) = g (f (x))
• Höhere Funktionen
¾ Funktionen als Argumente und Resultate g = F(f)
17
Standard ML
als Referenzsprache
• Core Language für Programming-in-the-Small
¾ Starke Typisierung mit Inferenzmaschine
¾ Pattern Matching Mechanismus für Argumente
¾ Funktionen als „First-Class-Citizens″
¾ Konkrete und abstrakte Datentypen
¾ Polymorphie
¾ Interaktive Abarbeitung
• Modulsystem für Programming-in-the-Large
¾ Structures
¾ Signatures
¾ Functors
18
Funktionen
λ-Ausdrücke
• fn
Expression
fn x => E
else any
fn x0 => E0 | x1 => E1 | ... | _ => En
fn (x0, y) => E0 | (x1, y) => E1 ... | _ => En
• Beispiele
fn x => x + 1
(fn x => x + 1) 2002
(fn x => x + 1)((fn x => x + 1) 7)
(fn x => x + 1)(fn x => x + 1) 7 linksassoziativ!
fn 0 => ″red″ | 1 => ″green″ | 2 => ″blue“ 19
Werte und Bereiche
Definitionsschemata
• val und let ... in ... end
val euler = 0.5772
val succ = fn x => x + 1
val color = fn 0 => ″white″ | _ => ″black″
val f = fn x =>
let val d = 2.72 val g = fn t => t * t * t in g (x – e) end
• local ... in ... end
local
val pi = 3.14
val sq = fn x => x * x
in val ringarea = fn (R, r) => pi * (sq R – sq r)
end
20
Beispiel Wochentagsbestimmung
Wochentag
Zeller‘sche Formel
• (2.61m – 0.2 + d + y + y ÷ 4 + c ÷ 4 – 2c) mod 7
c = Jahrhundert, y = Jahr im Jahrhundert,
m = Monat – 2 im Jahr, d = Tag im Monat$
• local
Qualifiziert mit
val floor = Real.floor
Modulnamen
val real = Real.fromInt
val zc = fn (d, m, y, c) => (floor (2.61 * real m – 0.2)
+ d + y + y div 4 + c div 4 – 2 * c) mod 7
in
val zeller = fn
(d, 1, y) => zc (d, 11, (y-1) mod 100, (y–1) div 100 + 1)
| (d, 2, y) => zc (d, 12, (y-1) mod 100, (y–1) div 100 + 1)
| (d, m, y) => zc (d, m-2, y mod 100, y div 100 + 1)
end
Pattern
21
Beispiel Integer-to-String
Hinweis
Rekursive Formulierung
val rec radix = fn (n, digits) =>
let
Teilstring
val b = size digits
val digit = fn n => str (String.sub (digits, n))
val radix′ =
fn (true, n) => digit n
concatenate
| (false, n) =>
radix (n div b, digits) ^ digit (n mod b)
in
radix′ (n < b, n)
end
radix (13, ″01″) liefert ″1101″
22
Standard ML Library
Typbezogene Module (Structures)
• Bool Structure
Bool.not, Bool.fromString, Bool.toString
NONE
T.fromString
• Char Structure
SOME t
Char.chr, Char.ord, Char.toUpper, Char.toLower
Char.contains, Char.notContains
option
Datentyp
• Int Structure
Int.abs, Int.min, Int.max, Int.fromString, Int.toString
• Real Structure
Real.trunc, Real.round, Real.floor, Real.ceil, Real.fromInt
• String Structure
String.sub, String.substring, String.concat
23
Funktionen höherer Ordnung
Funktionen als Argumente
•
•
•
•
•
•
sum (n) = n + n-1 + ... + 1
sq (n) = (2*n – 1) + (2*(n-1) – 1) + ... + (2*1 – 1)
fadd (f, n) = f(n) + f(n-1) + ... + f(1)
fac (n) = n * n-1 * ... * 1
fmul (f, n) = f(n) * f(n-1) * ... * f(1)
fgen (g, f, n) = g(f(n), g(f(n-1), ..., f(1)) ... ))
24
Funktionen höherer Ordnung
fadd/fmul in SML
• val rec fadd = fn (f, n) =>
let
val condfadd = fn
true => 0
│false => f (n) + fadd (f, n-1)
in
condfadd (n < 1)
end
25
Funktionen höherer Ordnung
fgen in SML
• val rec fgen = fn (g, f, e, n) =>
let
Neutral
val condfgen = fn
Element
true => e
│false => g (f (n), fgen(g, f, e, n-1))
in
condfgen (n < 1)
end
26
Funktionen höherer Ordnung
sum, sq, fac als fgen
• op - Notation
val op ♣ = fn (x, y) => x ♣ y
• Spezialisierungen von fgen
val sum = fn n => fgen (op +, fn x => x, 0, n)
val sq = fn n => fgen (op +, fn x => 2* x – 1, 0, n)
val fac = fn n => fgen (op *, fn x => x, 1, n)
27
Funktionen höherer Ordnung
Funktionen als Resultat
• Funktion als Funktionswert
val F = fn (...) => fn (...) => ...
• Komposition
val comp = fn (f, g) => fn x => g(f(x))
• Iteration
val rec iter = fn
0 => (fn f => fn x => x)
│ n => (fn f => fn x => f(iter (n-1) f x))
28
Funktionen höherer Ordnung
Curry‘sche Isomorphie (Haskell B. Curry)
• Funktionenräume
Abbildungen
¾A, B Mengen
¾BA Menge aller Funktionen von A nach B
• Curried Functions
¾X, Y, Z Mengen
X
X
x
Y
Y
≅ (Z )
¾Z
Curried
X
f ∈ Z X x Y ↔ f′ ∈ (Z Y) via f′ (x) (y) = f (x, y)
¾val curry = fn f => fn x => fn y => f (x, y)
¾val uncurry = fn f′ => fn (x, y) => f′ (x) (y)
29
Funktionen höherer Ordnung
Beispiel Hashing
• Hashfunktion mit Kollisionsbehandlung
Hash (k, i) := (k + h (k, i)) mod N
• Kollisionsbehandlung als Parameter
¾val H = fn h => fn (k, i) => (k + h (k, i)) mod N
¾val HashL = H (fn (k, i) => i)
Konstante
val HashQ = H (fn (k, i) => i * i)
val HashD = H (fn (k, i) =>
i * ((N–2) - k mod (N–2))
30
Funktionen höherer Ordnung
Beispiel Hashing
• Sondierung
val rec H = fn key =>
let HH = fn (h, i, key) =>
let check = fn
true => h (i, key)
│false => HH (h, i + 1, key)
in check (NoCollision (h (i, key))
end
in HH (HashD, 0, key)
end
31
Abgeleitete SML Formen
fun, case, if
• fun succ x = x + 1
• fun sum 1 = 1
│ sum n = sum (n – 1) + n
• fun fgen (g, f, e, n) =
case n < 1 of
true => e
│ false => g (f (n), fgen(g, f, e, n-1))
• fun fgen (g, f, e, n) =
if n < 1 then e else g (f (n), fgen(g, f, e, n-1))
32
Records und Tupel
• Records
{ name: string, age: int }
val president = { name = „bush“, age = 57 }
#name(president)
• Tupel
int * bool * real
{ 1: int, 2: bool, 3: real }
val n: int * bool * real = (7, true, 0.9)
val n = { 1 = 7, 2 = true, 3 = 0.9 }
33
Datentypen und Polymorphie
"Konstruktor"
• Datentypen
datatype color = red │ green │ blue
• Parametrische Polymorphie
¾type α set = α → bool
¾type α → α
¾let val Id = fn x => x in (Id 3, Id true) end
¾datatype α tree = empty
))
L
I
,N
│ node of α * α tree * α tree
L
I
,N
"Konstruktor"
nod
5,
2
(
e
N
(1
e
d
o
n
,
L
I
7
34
Listen
Head, Tail
• datatype α list = nil │ :: of α * α list
• 2 :: 1 :: nil Abgeleitete
cons
[21]
Form
Exception
• fun head [] = raise Empty│ head (h :: t) = h
• fun tail [] = raise Empty │ tail (h :: t) = t
SOME t
NONE
• fun last [] = raise Empty │ last [x] = x
│ last (h :: t) = last t
35
Listen
Appending
• fun length [ ] = 0
│ length (h :: t) = 1 + length t
• infixr 5 @ Signatur
fun [] @ list = list
│ (h :: t) @ list = h :: t @ list
• fun rev [] = [] │ rev (h :: t) = (rev t) @ [h]
• fun revApd ([], list) = list
│ revApd (h :: t, list) = revApd (t, h :: list)
36
Listen
Retrieval
• fun member (x, []) = false
│member (x, h :: t) = x = h orelse
member (x, t)
• exception Retrieve
fun retrieve (kev, []) = raise Retrieve
│ retrieve (key, (k, v) :: t) =
if key = k then v else retrieve (key, t)
• fun nth ([], _) = raise Subscript
│ nth (h :: t, 0) = h
│ nth (_ :: t, n) = nth (t, n – 1)
any handle Overflow => raise Subscript
37
Listen
Sections
• fun take (_, 0) = []
│ take ([], _) = raise Subscript
│ take (h :: t, n) = h :: take (t, n-1)
handle Overflow => raise Subscript
• fun takewhile (p, []) = []
│ takewhile (p, h :: t) =
if p h then h :: takewhile (p, t)
else []
38
Listen
Sorting
• fun insert (x, []) = [x]
│insert (x, h :: t) =
if x <= h then x :: h :: t
else h :: insert (x, t)
• fun sort [] = []
│ sort (h :: t) = insert (h, sort t)
39
Listen
Mapping
• fun map f [] = []
│ map f (h :: t) = f h :: map f t
• fun map f =
let
fun map_f [] = []
│ map_f (h :: t) = f h :: map_f t
in map_f
Effizienzsteigerung
end
durch Binden von f
40
Listen
Folding als generische Operation
• fun mapPartial f [] = []
│mapPartial f (h :: t) =
case f h of
NONE => mapPartial f t
│ SOME v => v :: mapPartial f t
• type ((α * β) → β) → (β → ((α list) → β))
fun foldR f e [] = e
│ foldR f e (h :: t) = f (h, foldR f e t)
• type ((α * β) → β) → (β → ((α list) → β))
fun foldL f e [] = e
│ foldL f e (h :: t) = foldL f (f(h, e)) t
• f assoziativ & kommutativ ⇒ foldL f = foldR f41
Listen
•
•
•
•
Folding Spezialisierungen
fun sort s = foldR insert [] s
type (α list) list → α list
fun concat s = foldR (op @) [] s
fun length s = foldR (fn (x, y) => 1 + y) 0 s
fun listrev s = foldL (op ::) [] s
listrev [ 1, 2, 3 ]
foldL (op ::) [] (1 :: [2, 3])
foldL (op ::) (1 :: []) [2, 3]
foldL (op ::) (2 :: [1]) [3]
foldL (op ::) (3 :: [2, 1]) []
[ 3, 2, 1 ]
42
Listen
Paarlisten und Zipping
• fun zip f [] [] = []
│ zip f (h::t) (k::u) = f h k :: zip f t u
│ zip f x y = error
• val addlists = zip plus
val mullists = zip times
val pairlists = zip pair
• pairlists [1, 2, 3, 4] [5, 6, 7, 8]
= [(1, 5), (2, 6), (3, 7), (4, 8)]
43
Fallstudie 1: Tautologieerkennung
Strategie (Lösung nach C. Ignat)
• Definiere allgemeine logische Ausdrücke E
unter Verwendung der Operatoren ¬, ∧, ∨, ⇒
• Definiere Regeln zur Transformation eines
allgemeinen Ausdrucks E in konjunktive
Normalform cnf(E), d. h. in eine Form A ∧ B ∧
C ∧ ..., wobei A, B, C Disjunktionen von Termen
der Form Atom oder ¬Atom sind
• E Tautologie ⇔ alle Faktoren in cnf(E) sind
Tautologien
• Faktor A in cnf(E) ist Tautologie ⇔ ein Term
in A ist Tautologie oder es existiert ein Paar
a, ¬a in A
44
Fallstudie 1: Tautologieerkennung
Datentyp Ausdruck mit Konstruktoren
• datatype expr = Atom of string
| Neg of expr
| Disj of expr * expr
| Conj of expr * expr
• fun implic (p, q) = Disj (Neg p, q)
45
Fallstudie 1: Tautologieerkennung
Negative Normal Form nnf
• fun nnf (Atom a) = Atom a
| nnf (Neg (Atom a)) = Neg (Atom a)
| nnf (Neg (Neg p)) = nnf p
| nnf (Neg (Conj(p, q))) =
Negation nur
nnf (Disj (Neg p, Neg q))
auf Atome
| nnf (Neg (Disj(p, q))) =
angewandt
nnf (Conj (Neg p, Neg q))
| nnf (Conj (p,q)) = Conj (nnf p, nnf q)
| nnf (Disj (p,q)) = Disj (nnf p, nnf q)
46
Fallstudie 1: Tautologieerkennung
Konjunktive Normal Form cnf
• fun distrib (p, Conj (q, r)) =
Conj (distrib (p, q), distrib (p, r))
| distrib (Conj (q, r), p)
Conj (distrib (q, p), distrib (r, p))
| distrib (p, q) = Disj (p, q)
• fun cnf (Conj (p, q)) = Conj (cnf p, cnf q)
| cnf (Disj (p, q)) = distrib (cnf p, cnf q)
| cnf p = p
47
Fallstudie 1: Tautologieerkennung
Kriterium und Implementation
• fun isTaut (p) = taut (cnf (nnf (p)))
• fun taut (Conj (p, q)) = taut p andalso taut q
| taut (p) = inter (pos p, neg p) <> []
• fun inter ([], ys) = []
| inter (x::xs, ys) =
if List.exists (fn t => (t = x)) ys
then x::inter (xs, ys)
else inter (xs, ys)
48
Fallstudie 1: Tautologieerkennung
Gruppierung in pos und neg Atome
• exception Cnf
• fun pos (Atom a) =[a]
| pos (Neg (Atom _)) = []
| pos (Disj (p, q)) = pos p @ pos q
| pos _ = raise Cnf
• fun neg (Atom _) = []
| neg (Neg (Atom a)) = [a]
| neg (Disj (p, q)) = neg p @ neg q
| neg _ = raise Cnf
49
Fallstudie 2: Huffmancode
Huffmann Trees (Lösung nach C. Ignat)
Liste von
Trees nach
Häufigkeit
geordnet
• datatype HTree = Leaf of char
| Node of HTree * HTree
• fun insertT a [] =[a]
| insertT (p1:real, h1) ((p2, h2) :: xs) =
if p1 < p2 then (p1, h1) :: (p2, h2) :: xs
else (p2, h2) :: insertT (p1, h1) xs
bottom up
• fun consH [(p, h)] = h
Konstruktion
| consH (a :: b :: xs) =
let fun consT (p1, h1)(p2, h2) = des HTrees
(p1 + p2, Node (h1, h2))
in consH (insertT (consT a b) xs)
end
50
Fallstudie 2: Huffmancode
Programm
Expandiere
die Pfadcodes
• fun expandP a =
let fun expand (Leaf sym) path = [(sym, path)]
| expand (Node(left, right)) path =
(expand left (path ^ "0")) @
(expand right (path ^ "1"))
in expand a "" end
Sortiere
Symbole nach
• fun huffman x =
Häufigkeit
let fun sortS [] = []
| sortS ((p:real, sym) :: xs) =
insertT (p, (Leaf sym)) (sortS xs)
in expandP (consH (sortS x)) end
• val l = [ (0.5, #"A"), (0.2, #"B"), (0.1, #"C"),
(0.1, #"D"), (0.05, #"E"), (0.05, #"F") ];
run huffman l
51
Fallstudie 3: Command Interpreter
Abstract Syntax
• datatype command = Assign of
(variable x expression)
│ Sequence of (command x command)
│ Conditional of
(expression x command x command)
│ Repetition of (expression x command)
• datatype expression = Constant of int
│ Contents of variable
│ Minus of (expression x expression)
│ Greater of (expression x expression)
│ Times of (expression x expression)
52
• datatype variable = Var of string
Fallstudie 3: Command Interpreter
Sample Command
• WHILE X > Y DO
X := X – 1; Z := Z * Z
Konstruktoren
END
• Repetition (Greater (Contents (Var „X“),
Contents (Var („Y“)),
Sequence (Assign (Var „X“,
Minus (Contents (Var „X“),
Constant 1)),
Assign (Var „Z“,
Times (Contents (Var „Z“),
Contents (Var „Z“)))))
53
Fallstudie 3: Command Interpreter
•
•
•
•
•
Store
datatype value = Value of int
datatype store = Store of (name → value)
fun get (a, Store f) = f a
fun update (Store f, a, v) =
Store (assoc [(a, v)] f)
fun assoc [] f = f
│ assoc ((a0, v0) :: t) f =
if a = a0 then v0 else assoc t f
54
Fallstudie 3: Command Interpreter
Evaluator
• eval: expression → store → value
• fun eval (Constant n) s = Value n
│ eval (Variable a) s = get (a, s)
│ eval (Minus (e1, e2)) s =
let val Value v1 = eval e1 s and Value v2 = eval e2 s
in Value (v1 – v2) end
│ eval (Times (e1, e2)) s =
let val Value v1 = eval e1 s and Value v2 = eval e2 s
in Value (v1 * v2) end
│ eval (Greater (e1, e2)) s =
let val Value v1 = eval e1 s and Value v2 = eval e2 s
in if v1 > v2 then Value (1) else Value (0) end
55
Fallstudie 3: Command Interpreter
Interpreter
• fun switch (Value 1) f g s = f s
│ switch (Value 0) f g s = g s
│ switch (Value n) f g s = error
• fun interpret (Assign (v, e)) s =
let val a = eval e s in update (s, v, a) end
│ interpret (Sequence (c1, c2)) s =
interpret c2 (interpret c1 s)
│ interpret (Conditional (e, c1, c2)) s =
switch (eval e s) (interpret c1) (interpret c2) s
│ intepret (Repetition (e, c)) s =
switch (eval e s)
(interpret (Repetition (e, c)) ° interpret c) Id s
56
Fallstudie 3: Command Interpreter
Concrete Syntax
• exp ::= aexp [ ”>” aexp ]
aexp ::= bexp [”-” aexp ]
bexp ::= cexp [”*” bexp ]
cexp ::= ”(” exp ”)” │ number │ variable
command ::= unitcom [ ”;” command ]
unitcom ::= whilecom │ ifcom │ assign
whilecom ::=
”WHILE” exp ”DO” command ”END”
ifcom ::= ”IF” exp ”THEN” command
”ELSE” command ”END”
assign ::= variable ”:=” exp
57
Fallstudie 3: Command Interpreter
Parsers
• datatype token = Ident of string
│ Symbol of string
│ Number of int
• datatype α possible = Ok of α
│ Fail
• type α parser =
token list → (α x token list) possible
58
Fallstudie 3: Command Interpreter
Basic Parsers
• fun number (Number n :: s) = Ok (n, s)
│ number other = Fail
• fun variable (Ident x :: s) = Ok (Var x, s)
│ variable other = Fail
• literal: string → string parser
fun literal a (Symbol x :: s) =
if a = x then Ok (x, s) else Fail
│ literal a other = Fail
59
Fallstudie 3: Command Interpreter
Parser Builders
• fun (p1 <│> p2) s =
let fun p2_if_fail Fail = p2 s │ p2_if_fail x = x
in p2_if_fail (p1 s) end
infixr 3
• fun (p modify f) s =
<│>
let fun modres Fail = Fail
infixr 0
│ modres (Ok (x, y)) = Ok (f x, y)
modify
in modres (p s) end
infixr 4
• fun (p1 <&> p2) s =
<&>
let fun p2_after Fail = Fail
│ p2_after (Ok (x1, s1)) = (p2 modify (pair x1)) s1
in p2_after (p1 s) end
• fun emptyseq s = Ok ([], s)
• fun optional p = (p modify (consonto [])) <│> emptyseq
60
Fallstudie 3: Command Interpreter
Expression Parsers (1)
• fun exp s = (aexp <&> optional (literal „>“ <&> aexp)
modify opt_compare) s
and aexp s = (bexp <&> optional (literal „-“ <&> aexp)
modify opt_sub) s
and bexp s = (cexp <&> optional (literal „*“ <&> cexp)
modify opt_mul) s
and cexp s = ((literal „(“ <&> exp <&> literal „)“
modify unparenth)
<│> (number modify Constant)
<│> (variable modify Contents)) s
and ...
61
Fallstudie 3: Command Interpreter
Expression Parsers (2)
...
and unparenth (brac, (e, ket)) = e
and opt_compare (e1, [ ]) = e1
| opt_compare (e1, [ (oper, e2) ]) = Greater (e1, e2)
| opt_compare other = error
and opt_sub (e1, [ ]) = e1
| opt_sub (e1, [ (oper, e2) ]) = Minus (e1, e2)
| opt_sub other = error
and opt_mul (e1, [ ]) = e1
| opt_mul (e1, [ (oper, e2) ]) = Times (e1, e2)
| opt_mul other = error
62
Fallstudie 3: Command Interpreter
Command Parsers (1)
• fun command s = (unitcom <&> optional
(literal „;“ <&> command) modify opt_seq) s
and unitcom s = (whilecom <|> ifcom <|> assign) s
and whilecom s = (literal „WHILE“ <&> exp <&>
literal „DO“ <&> command <&> literal „END“
modify mk_while_node) s
and ifcom s = (literal „IF“ <&> exp <&>
literal „THEN“ <&> command <&>
literal „ELSE“ <&> command <&> literal „END“
modify mk_if_node) s
and assign s = (variable <&> literal „:=„ <&> exp
modify mk_assign_node) s
and ...
63
Fallstudie 3: Command Interpreter
Command Parsers (2)
...
and opt_seq (c1, [ ]) = c1
| opt_seq (c1, [(semicol, c2)]) = Sequence(c1, c2)
| opt_seq other = error
and mk_while_node (w, (ex, (d, (com, e)))) =
While (ex, com)
and mk_if_node (i, (ex, (t, (c1, (e, (c2, f)))))) =
Conditional (ex, c1, c2)
and mk_assign_node (v, (coleq, e)) = Assign (v, e)
64
Abstrakte Datentypen
Kunden
Funktion
Typ
Programm
ADT
Operationen
(Signaturen)
Implementationen
Darstellungen
Darstellungen
65
Abstrakte Datentypen
Beispiele
• Store definiert via Funktionen & Konstanten
type store
get: variable x store → value
update: store x variable x value → store
nullstore: store
• Set (s. Uebung)
Alle Werte
gleich 0
66
Abstrakte Datentypen
konkret
Beispiel canvas: Definition
• datatype color = Red | Orange | Yellow
| green | Blue | Indigo | Violet
• datatype coordinate = Coord of int x int
abstrakt
• type canvas
newcanvas: color → int → int → canvas
sizecanvas: canvas → (int * int)
colorof: canvas → coordinate → color
paint: color → coordinate → canvas → canvas
67
Abstrakte Datentypen
Beispiel canvas: Spezifikation
• is_on: coordinate → canvas → bool
• For all P, P': coordinate
Hilfsprädikat
For all col: color
For all m, n, m1, n1: int
For all cnv: canvas
colorof (newcanvas col m n) P‘ = col
colorof (paint col P cnv) P‘ =
if P = P‘ & is_on (P, cnv) then col
else colorof canvas P‘
sizecanvas (newcanvas col m n) = (m, n)
sizecanvas (paint col P cnv) = sizecanvas cnv
is_on (Coord (m1, n1), newcanvas col m n)
= m1 > 0 & m1 <= m & n1 > 0 & n1 <= n
is_on (P‘, paint col P cnv) = is_on (P‘, cnv)
68
Abstrakte Datentypen
Beschränkter Gültigkeitsbereich
des Konstruktors Cnv
Beispiel canvas: 1. Implementation
abstype canvas =
Cnv of int x int x (coordinate → color)
K col P = col
with
fun newcanvas col m n = Cnv (m, n, K col)
fun sizecanvas (Cnv (m, n, f)) = (m, n)
fun colorof (Cnv (m, n, f)) P = f P
fun paint col (Coord (m1, n1)) (Cnv (m, n, f))
= if m1 > 0 & m1 <= m & n1 > 0 & n1 <= n
then
Cnv (m, n, assoc [(Coord (m1, n1), col)] f)
else Cnv (m, n, f)
end
69
Abstrakte Datentypen
Beispiel canvas
• Authentication
local
fun f (Coord (m1, n1)) =
if m1 < n1 then Red else Blue
in val mycanvas = Cnv (10, 10, f)
end
• Secrecy
fun get_paint_fn (Cnv (m, n, f)) = f
70
Abstrakte Datentypen
Beispiel canvas: 2. Implementation
abstype canvas = Paint of color x coordinate x canvas
| Newcanvas of color x int x int
with
local fun is_on (Coord (m1, n1), Newcanvas (col, m, n))
= m1 > 0 & m1 <= m & n1 > 0 & n1 <= n
| is_on (P‘, Paint (col, P, cnv)) = is_on (P‘, cnv)
in fun newcanvas col m n = Newcanvas (col, m, n)
fun paint col P cnv = Paint (col, P, cnv)
fun sizecanvas (Newcanvas (col, m, n)) = (m, n)
| sizecanvas (Paint (col, P, cnv)) = sizecanvas cnv
fun colorof (Newcanvas (col, m, n)) P = col
| colorof (Paint (col, P, cnv)) P‘
= if P = P‘ & is_on(P‘, cnv) then col else colorof cnv P‘
end
71
end
Abstrakte Datentypen
Beispiel canvas
• Die zweite Implementation von canvas
widerspiegelt die Entstehungsgeschichte.
Falls P1 # P2 sind folgende Konstruktionen
verschiedene Darstellungen desselben
abstrakten Wertes
Paint (col1, P1, Paint (col2, P2, cnv))
Paint (col2, P2, Paint (col1, P1, cnv))
• Die Gleichheitsrelation für abstrakte
Datenypen muss explizit implementiert werden
72
Abstrakte Datentypen
Parametrisierte Typen
• abstype α board = Board of int x int x coordinate → α
with
fun newboard b m n =
if m > 0 & n > 0 then Board (m, n, K b) else error
fun sizeboard (Board (m, n, f)) = (m, n)
fun contentsboard (Board (m, n, f)) =
if m1 > 0 & m1 <= m & n1 > 0 & n1 <= n
then f (Coord (m1, n1)) else error
fun updateboard (Board (m, n, f)) (Coord (m1, n1)) b
if m1 > 0 & m1 <= m & n1 > 0 & n1 <= n
then Board (m, n, assoc[(Coord (m1, n1), b)] f)
else error
end
73
Abstrakte Datentypen
Subtypen
• type ordintlist
null_ord: ordintlist → bool
nil_ord: ordintlist
hd_ord: ordintlist → int
tl_ord: ordintlist → ordintlist
insert_ord: int → ordintlist → ordintlist
order: int list → ordintlist
74
Abstrakte Datentypen
Subtypen
• abstype ordintlist = Ordered of int list
with
local
fun insert n [] = [n] │insert n (a :: x) =
if (lessthan a) n then n :: a :: x else a :: insert n x
fun sort [] = [] | sort (a :: x) = let val low = filter (lessthan a) x
and high = filter (non (lessthan a)) x
in sort low @ [a] @ sort high
Quicksort
in
fun null_ord (Ordered []) = true
│ null_ord (Ordered (a :: x)) = true
val nil_ord = Ordered []
fun hd_ord (Ordered (a :: x)) = a
hd_ord (Ordered [] ) = error
fun tl_ord (Ordered (a :: x)) = Ordered x
tl_ord (Ordered []) = error
fun insert_ord n (Ordered x) = Ordered (insert n x)
fun order x = Ordered (sort x)
end
end
75
Strukturen und Funktoren
Module
• Struktur
¾ Namespace
¾ Menge von Definitionen
¾ Environment Komponente
• Beispiel ListOps
¾ structure ListOps = struct
fun foldR ... fun reduce ... fun member ...
end
¾ let val accumulate = ListOps.foldR
in accumulate times 2
end
¾ local open ListOps in ... end
76
Strukturen und Funktoren
Signaturen
z
z
structure B = struct
datatype counter = C of int
val bottom = C(0)
val top = C(99)
fun next (C x) =
if C x = top then bottom else C (x + 1)
fun above (C x) (C y) = y > x
end
signature SIGB = sig
datatype counter = C of int
val bottom: counter val top: counter
val next: counter → counter
val above: counter → counter → bool
end
77
Strukturen und Funktoren
Beispiel: Dictionary
z
z
signature KEY = sig
type key
val before: key → key → bool
val matches: key → key → bool
end
signature DICTIONARY = sig
structure K: KEY
type α dict
val newdict: α dict
val lookup: α dict → K.key → α
val enter: α dict → K.key → α → α dict
end
78
Strukturen und Funktoren
Beispiel: Dictionary Definition
• functor MkDict (Keystruct: KEY): DICTIONARY
= struct
structure K = Keystruct
abstype α dict = Emp
| Item of K.key x α x α dict x α dict
with val newdict = Emp
fun lookup Emp k‘ = error
| lookup (Item (k, a, d1, d2)) k‘
= if K.matches k k‘ then a
else if K.before k k‘ then lookup d1 k‘
else lookup d2 k‘
fun enter Emp k‘ b = Item (k‘ b, Emp, Emp)
| enter (Item (k, a, d1, d2)) k‘ b
= if K.matches k k‘ then Item (k‘, b, d1, d2)
else if K.before k k‘ then Item (k, a, enter d1 k‘ b, d2)
else Item (k, a, d1, enter d2 k‘ b)
end
end
79
Strukturen und Funktoren
Beispiel: Dictionary Verwendung
• structure IntKey =
struct
type key = int
fun before (x: key) (y: key) = y < x
fun matches (x: key) (y: key) = x = y
end
• structure IntDict = MkDict (IntKey)
• open IntDict
im aktuellen Environment
¾ structure K: KEY zur Verfügung gestellt
type α dict
val newdict: α dict
val lookup: α dict → K.key → α → α dict
¾ wobei K = IntKey and K.key = int
80
Ausführung von Programmen
• Abarbeitung von Definitionen
¾Struktur struct
¾Funktor functor
¾Signatur sig
¾Typ type
™Abstrakt abstype
™Konkret datatype
¾Wert val
™Funktion val fn / fun
Definiert
Umgebung
In aktueller
Umgebung
• Auswertung von Ausdrücken
81
Auswertungsstrategien
Lazy Evaluation
• Strategien
SML
¾Eager: „Vollständige Auswertung aller
Argumente vor Funktionsanwendung“
¾Lazy: „Verzögerte Auswertung der
Haskell
Argumente, so spät wie möglich“
• Beeinflussung des Programmierstils
¾Undefinierte Werte
¾Wiederverwenung von Komposition
¾Unendliche Datenstrukturen
¾Implizite Coroutinen
82
Auswertungsstrategien
Lazy Evaluation
• Bedingte Ausdrücke
fun cond true x y = x | cond false x y = y
Bei Lazy Evaluation
cond A B false ⇔ A & B
cond A true B ⇔ A | B
ev. B = Ω „undefiniert“
• Rekursion
fun ([] = []) = true
| ((a :: x) = (b :: y)) = cond (a = b) (x = y) false
| ((a :: x) = []) = false
| ([] = (b :: y)) = false
83
Auswertungsstrategien
Lazy Evaluation
• Exists
¾Ohne Wiederverwendung
fun exists p [] = false
| exists p (a :: x) =
if p a then true else exists p x
¾Bei Lazy Evaluation mit Wiederverwendung
fun exists p x = not (null (filter p x))
84
Auswertungsstrategien
Lazy Evaluation
• Sieb des Erasthotenes
int list
2 3 4 ...
val primes = sieve (from 2)
fun sieve (a :: x) = a :: sieve (sift a x)
fun sift a x = filter (non (multipleof a)) x
fun multipleof a b = (b mod a = 0)
85
Auswertungsstrategien
Lazy Evaluation
• Ablaufsszenarium
[] ← sieve ← [2, 3, 4, 5, 6, 7, 8, 9, ...]
[2] ← sieve ← (sift 2) [3, 4, 5, 6, 7, 8, 9, ...]
[2] ← sieve ← [3, 5, 7, 9, ...]
[2, 3] ← sieve ← (sift 3) [5, 7, 9, ...]
[2, 3] ← sieve ← [5, 7, ... ]
[2, 3, 5] ← sieve ← (sift 5) [7, ... ]
[2, 3, 5] ← sieve ← [7, ... ]
[2, 3, 5, 7] ← sieve ← [... ]
86
Auswertungsstrategien
Lazy Evaluation
• Ablaufsmodellierung
Sieve
Konsument
Master
Sift
Produzent
Slave
Coroutine
Coroutine
87
Auswertungsstrategien
Lazy Evaluation
• Hamming Zahlen
• 2p * 3q * 5r
• val rec hamming =
1 :: merge3 (map (times 2) hamming)
(map (times 3) hamming)
(map (times 5) hamming)
fun merge3 x y z = merge x (merge y z)
fun merge (a :: x) (b :: y) =
if a < b then a :: merge x (b :: y)
else if a > b then b :: merge (a :: x) y
else a :: merge x y
88
Auswertungsstrategien
Lazy Evaluation
• Ablaufsmodellierung
1 :: hamming
merge3
map
times 2
map
times 3
hamming
map
times 5
89
Auswertungsstrategien
Lazy Evaluation
• Ablaufsszenarium
[ 1, .. ]
[ 1, 2, .. ] ← [ 2, .. ] [ 3, .. ] [ 5, .. ]
[ 1, 2, 3, .. ] ← [ 2, 4, .. ] [ 3, .. ] [ 5, .. ]
[ 1, 2, 3, 4, .. ] ← [ 2, 4, .. ] [ 3, 6, .. ] [ 5, .. ]
[ 1, 2, 3, 4, 5, .. ] ← [ 2, 4, 6, .. ] [ 3, 6, .. ] [ 5, .. ]
[ 1, 2, 3, 4, 5, 6, .. ] ← [ 2, 4, 6, .. ] [ 3, 6, .. ] [ 5, 10, .. ]
[ 1, 2, 3, 4, 5, 6, 8, .. ] ← [ 2, 4, 6, 8, .. ] [ 3, 6, 9, .. ] [ 5, 10, .. ]
[ 1, 2, 3, 4, 5, 6, 8, 9, .. ] ← [ 2, 4, 6, 8, 10, .. ] [ 3, 6, 9, .. ] [ 5, 10, .. ]
• Prinzip
[ .., 2a*3b*5c, .., 2p*3q* 5r, .., 2s*3t*5r ] bereits erzeugt
Wähle nächstes Element aus 2a+1*3b*5c, 2p*3q+1* 5r, 2s*3t*5r+1
90
Auswertungsstrategien
Funktionen als Coroutinen
g
a
f
b
f (g a, a, b)
c
p
g
a
f
b
let fun h x = f (g x, x, b) in h a end
c
g
p
b
f
let val rec a = p (a, c) in a end
91
let val rec a = p (a, c) in f (g a, a, b) end
Auswertungsstrategien
Lazy Dictionary
• Aufgabe: Durchkämmen eines Textes
und Annotieren aller Verwendungen von
Begriffen durch deren Erklärung
• Vorgehen: Laufende Erstellung bzw.
Abfrage einer Tabelle bestehend aus
Einträgen der Form (Begriff, Erklärung)
• Problem: Begriffe, die (textuell) vor
ihrer Erklärung verwendet werden
92
Auswertungsstrategien
Lazy Dictionary Definition
• Dictionary
¾ α dictop Operationen Entry und Lookup
α dict Registratur von Paaren key x α
dictop Strom
• Prozess
¾ fun dictproc opstream =
let val finaldict = builddict (getentries opstream)
in map (lookup finaldict) (getlookups opstream) end
• Signaturen
¾ dictproc: (α dictop) list → α list
getentries: (α dictop) list → (key x α) list
getlookups: (α dictop) list → key list
builddict: (key x α) list → α dict
lookup: α dict → key → α
93
Auswertungsstrategien
α dictop Implementation
• type key = int
• datatype α dictop = Entry of (key, α)
| Lookup of key
• fun getentries (Lookup k :: r) = getentries r
| getentries (Entry (k, a) :: r) =
(k, a) :: getentries r
• fun getlookups (Lookup k :: r) = k :: getlookups r
| getlookups (Entry (k, a) :: r) = getlookups r
94
Auswertungsstrategien
α dict Implementation
• datatype α dict = Emp
| Item of (key x α x α dict x α dict)
• fun lookup Emp k‘ = error
| lookup Item (k, a, d1, d2) k‘ =
if k = k‘ then a
else if k > k‘ then lookup d1 k‘
else lookup d2 k‘
• fun builddict [] = Emp
| builddict ((k1, a1) :: r)
let fun smaller (k, a) = k < k1
fun larger (k, a) = k > k1
in Item (k1, a1,
builddict (filter smaller r),
builddict (filter larger r)) end
95
Auswertungsstrategien
Lazy Dictionary Illustration
• opstream = [ L3, E(1, „x“), E(3, „z“), L1, L2, E(2, „y“) ]
• dictproc opstream =
= map (lookup finaldict) (getlookups opstream) =
= map (lookup finaldict) (3 :: getlookups (E(1, “x“) :: ...))
= (lookup finaldict 3) ::
(map (lookup finaldict) (getlookups (E(1, „x“) :: ...)))
• finaldict = builddict ((1,“x“)::(3,“z“)::...))
= Item(1, “x“, builddict..., builddict (3,“z“)::...)
= Item(1, „x“, builddict..., Item(3, „z“, ..., ...))
• lookup finaldict 3
= lookup (Item(1, „x“, builddict..., Item(3, „z“, ..., ...))) 3
= „z“
• dictproc opstream = „z“ :: map ...
96
• dictproc opstream = [ „z“, „x“, „y“ ]
Auswertungsstrategien
Interaktive Programme
• type input = char list list
Ungelesene
• type output = char list list
Inputdaten
• type (α, β) interaction =
(input x α) → (input x β x output)
• <@>: (α, β) interaction x (β, γ) interaction →
(α, γ) interaction
infix <@>
fun (i1 <@> i2) (input, a) =
let val (in1, b, out1) = i1 (input, a)
val (in2, c, out2) = i2 (in1, b)
in (in2, c, out1 @ out2)
end
97
Logische Programmierung
98
Logische Programmierung
Situierung
• Logische Deduktion mit Formeln erster
Ordnung (Kowalski (1979)
• Beweise werden via Resolution auf der
Basis des Unifikationsalgorithmus
automatisch erzeugt
• Sprache Prolog
99
Logische Programmierung
Ziel
IF
Horn Klauseln
• A :- A1, A2, ... , An. Regel
A. :- TRUE, Fakt
• isappendof (X, Y, Z) ⇔ X @ Y = Z
isappendof ([], X, X).
Relation
isappendof (A :: X, Y, A :: Z) :- isappendof (X, Y, Z).
• isflattenof
isflattenof (Empty, []).
AND
isflattenof (Tr (T1, A, T2), Z) :- isflattenof (T1, X1),
isflattenof (T2, X2), isappendof (X1, A :: X2, Z).
OR
isflattenof (Tr (T1, A, T2), Z) :- isflattenof (T1, X1),
isflattenof (T2, X2), isappendof (A :: X1, X2, Z).
100
Logische Programmierung
Programme
• isappendof ([1, 2], [3], [])?
Logische
no
Variable
• isappendof ([1, 2], [3], ?Z)?
z = [1, 2, 3]
• isappendof (?X, ?Y, [1, 2, 3])?
(1) X = [], Y = [1, 2, 3]
(2) X = [1], Y = [2, 3]
(3) X = [1, 2], Y = [3]
(4) X = [1, 2, 3], Y = []
101
Logische Programmierung
Illustration einer Deduktion
• Notation
Cons(1, Cons(2, Cons(3, []))) für [1, 2, 3]
Ziel
• Deduktion
? isappendof (Cons (?X, []), ?Y, Cons (1, Cons (2, [])))
isappendof (Cons (?1, ?2), ?3, Cons (?1, ?4)) :isappendof (?2, ?3, ?4)
Unifikation
?X zu 1, ?2 zu [], ?3 zu ?Y, ?1 zu 1, ?4 zu Cons (2, [])
? isappendof ([], ?Y, Cons (2, []))
Neues Ziel
isappendof ([], ?5, ?5)
?Y zu Cons (2, []), ?5 zu Cons (2, [])
?X = 1, ?Y = Cons (2, [])
102
Antwort
Logische Programmierung
Beispiel Stammbaum (1)
ht
tp
man (adam).
man (peter).
Fakten
man (paul).
woman (marry).
woman (eve). Werte
parent (adam, peter).
parent (eve, peter).
parent (adam, paul).
parent (marry, paul).
:/
/k
ti
.m
s.
m
.
ff
cu
ni
~
z/
.c
ba
a
rt
k/
ol
pr
og
/g
l
ea
en
og
y.
ht
l
m
103
Logische Programmierung
Beispiel Stammbaum (2)
Variablen
father (F, C) :- man (F), parent (F,C).
mother (M, C) :- woman (M), parent (M,C).
is_father (F) :- father (F, _).
Regeln
is_mother (M) :- mother (M, _).
?- father (X, paul).
Anonyme
X = adam
Variable
Abfrage,
Query
104
Logische Programmierung
Beispiel Stammbaum (3)
son (S,P) :- man (S), parent (P, S).
daughter (D, P) :- woman (D), parent (P, D).
siblings (A, B) :- parent (P, A), parent (P, B), A\=B.
full_siblings (A, B) :- parent (F, A), parent (F, B),
parent (M, A), parent (M, B), A\=B, F\=M.
full_siblings2 (A,B) :- father (F, A), father (F, B),
mother (M, A), mother (M, B), A\=B.
uncle (U, N) :- man (U), siblings (U, P), parent (P, N).
aunt (A, N) :- woman (A), siblings (A, P), parent (P, N).
grand_parent (G,N) :- parent (G, X), parent (X, N).
105
Logische Programmierung
Beispiel Stammbaum (4)
human(H) :- man(H). OR
human(H) :- woman(H).
descendent(D, A) :- parent(A, D).
descendent(D, A) :- parent(P, D),
descendent(P, A).
ancestor(A, D) :- descendent(D, A).
106
Logische Programmierung
Beispiel Fakultät (1)
• factorial(0,1).
factorial(N,F) :- N>0, N1 is N-1,
factorial(N1,F1), F is N * F1.
?- factorial(3,W). W=6
factorial(3, 6)
Klausel
baum
3>0
2 is 3-1
factorial(2, 2)
6 is 3*2
2>0
1 is 2-1
factorial(1, 1)
2 is 2*1
1>0
0 is 1-1
factorial(0, 1)
1 is 1*1
true
107
Logische Programmierung
Beispiel Fakultät (2)
• Ableitungsbaum
Trace
?- factorial(3,X).
(1) 0 Call: factorial(3,_8140) ?
(1) 1 Head [2]: factorial(3,_8140) ?
(2) 1 Call (built-in): 3>0 ?
(2) 1 Done (built-in): 3>0 ?
(3) 1 Call (built-in): _8256 is 3-1 ?
(3) 1 Done (built-in): 2 is 3-1 ?
(4) 1 Call: factorial(2, _8270) ?
...
(1) 0 Exit: factorial(3,6) ? X=6
108
Logische Programmierung
Beispiel Türme von Hanoi (1)
• move(1, X, Y, _) :write('Move top disk from '),
write(X),
write(' to '),
write(Y).
move(N, X, Y, Z) :N>1,
M is N-1,
move(M, X, Z, Y),
move(1, X, Y,_),
move(M, Z, Y, X).
109
Logische Programmierung
Beispiel Türme von Hanoi (2)
• ?- move(3,left,right,center).
Move top disk from left to right
Move top disk from left to center
Move top disk from right to center
Move top disk from left to right
Move top disk from center to left
Move top disk from center to right
Move top disk from left to right
yes
110
Logische Programmierung
Beispiel Türme von Hanoi (3)
• zum Erreichen des Ziels
?- move(3, left, right, center)
• erreiche Ziel
?-move(2, left, center, right)
danach erreiche Ziel
?-move(1, left, right, center)
danach erreiche Ziel
?-move(2, center, right, left).
111
Logische Programmierung
Deduktionsstrategie (1)
• /* program P
p(a).
p(X) :- q(X), r(X).
p(X) :- u(X).
q(X) :- s(X).
r(a).
r(b).
s(a).
s(b).
s(c).
u(d).
clause # */
/* #1 */
/* #2 */
/* #3 */
/* #4 */
/* #5 */
/* #6 */
/* #7 */
/* #8 */
/* #9 */
/* #10 */
112
Logische Programmierung
Deduktionsstrategie (2)
• Klauselbäume
p(a)
p(b)
p(c)
p(d)
true
q(b) r(b)
q(c) r(c)
u(d)
s(b) true
s(c)
true
true
true
113
Logische Programmierung
Deduktionsstrategie (3)
• ?- p(X)
X = a
X = b
X = d
Depth-First
Traversierung
Unifikation
114
Logische Programmierung
„!“ (cut) als Steuerbefehl
• havevisitor(friday).
weather(friday, fair).
Falltüre,
weather(saturday, fair).
blockiert das
weather(sunday, fair).
Backtracking
weekend(saturday).
weekend(sunday).
picnic(Day) :- weather(Day, fair), !, weekend(Day)., !
picnic(Day) :- havevisitor(Day).
• ?- picnic(When)
?- picnic(When)
When = saturday
no
When = sunday
?- picnic(When)
When = friday
When = saturday
„red cuts“
yes
yes
115
Logische Programmierung
Negation als Failure
Negation „Q wenn nicht P“
¾ Q :- P, !, fail.
Notation für Q
Q.
\+ P
¾ different(X, Y) :- X=Y, !, fail.
different(X, Y).
¾ home(X) :- out(X), !, fail.
home(X).
out(sue).
?- home(sue)
closed world
no
assumption
?- home(joe)
?- home(Anyone)
116
Logische Programmierung
Negation als Failure
student(bill).
student(joe).
married(joe).
single_student(X) :- (\+ married(X)), student(X).
?- single_student(bill)
yes
?- single_student(joe)
no
?- single_student(X)
no
single_student(X) :- student(X), (\+ married(X))
?- single_student(X)
X = bill
117
Logische Programmierung
Alternative
• Bedingung „Wenn P dann Q sonst R“
¾S :- P, !, Q.
S :- R.
¾add(X, L1, L2) :- member(X, L1), !, L2 = L1.
add(X, L1, L2) :- L2 = [X| L1].
Durch Hinzufügen
von X zu L1
entsteht L2
118
Logische Programmierung
Zustandsübergänge
• The Hungry Monkey
There is a monkey at the door into a room. In the
middle of the room a banana is hanging from the
ceiling. The monkey is hungry and wants to get the
banana, but he cannot stretch high enough from the
floor. At the window of the room there is a box that
the monkey can use. The monkey can perform the
following actions: walk on the floor, climb the box,
push the box around (if he is already at it), and grasp
the banana if he is standing on the box and directly
underneath the banana. Can the monkey grasp the
banana?
119
Logische Programmierung
Zustandsübergänge
• Zustand des Systems
allgm
state(M, B, O, G).
Anfang state(door, window, onfloor, hasnot).
Ende
state(_, _, _, has)
• Aktionen
walk(P1, P2)
push(P1, P2)
climb
grab
120
Logische Programmierung
Zustandsübergänge
• Perform Action
¾perform(A, S1, S2)
¾perform(grasp, state(middle, middle, onbox,
hasnot), state(middle, middle, onbox, has)).
perform(climb, state(MP, BP, onfloor, H),
state(BP, BP, onbox, H)).
perform(push(P1, P2), state(P1, P1, onfloor, H),
state(P2, P2, onfloor, H)).
perform(walk(P1, P2), state(P1, BP, onfloor, H),
state(P2, BP, onfloor, H)).
121
Logische Programmierung
Zustandstransformation
• Get Food
getfood(state(_, _, _, has)).
getfood(S1) :- perform(A, S1, S2),
getfood(S2).
• Query
?- getfood(state(atdoor, atwindow,onfloor,
hasnot)).
yes.
122
Logische Programmierung
Zustandstransformation
• Mit Trace Output
getfood(S1) :perform(A, S1, S2),
nl, write(‚in '), write(S1),
nl, write(' try '), write(A),
getfood(S2).
123
Logische Programmierung
Zustandstransformation
• in state(atdoor, atwindow, onfloor, hasnot)
try climb
in state(atdoor, atwindow, onfloor, hasnot)
try walk(atdoor, _224)
in state(_224, atwindow, onfloor, hasnot)
try climb
in state(atwindow, atwindow, onfloor, hasnot)
try push(atwindow, _283)
in state(_283, _283, onfloor, hasnot)
try climb
in state(middle, middle, onbox, hasnot)
try grasp
yes
124
Logische Programmierung
Digitale Schaltkreise
• Logischer Operator → Prolog Prädikat
¾ INVERTER
inv(0, 1), inv(1, 0)
¾ AND Gate
and(0, 0, 0), and(0, 1, 0), and(1, 0, 0), and(1, 1, 1)
• Schaltkreis → Prolog Regel
Circuit (Input, Output) :Gate1 (InputA, InputB, OutputC),
...
GateN (InputA, InputB, OutputC).
• Schaltkreissimulation → Prolog Query
?- Circuit (Input, Output)
125
Logische Programmierung
Digitale Schaltkreise
A
B
T1
E
C
D
T2
Circuit (A, B, C, D, E) :NAND (A, B, T1),
NORE (C, D, T2),
NAND (T1, T2, E).
?- Circuit (A, B, C, D, E)
126
Fallstudie 1: Eliza
Weizenbaum 1966, nach Sterling & Shapiro
run :nl, write('What is your problem?'),
nl, write('>> '),
read_word_list(Input), eliza(Input), !.
eliza([bye]) :nl, write('Goodbye. I hope I have helped you.'), nl.
eliza(Input) :Create
pattern(Stimulus, Response),
Dictionary
match(Stimulus, Dictionary, Input),
match(Response, Dictionary, Output),
Create
reply(Output),
Output
read_word_list(Input1), !, eliza(Input1).
reply([Head|Tail]) :- write(Head), write(' '), reply(Tail).
reply([]) :- nl, write('>> '), !.
127
Fallstudie 1: Eliza
Korrespondierende Musterpaare
pattern([i, am, 1], [how, long, have, you, been, 1, ?]).
pattern([1, you, 2, me, 3],
[what, makes, you, think, i, 2, you, ?]).
pattern([i, like, 1],
[does, anyone, else, in, your, family, like, 1, ?]).
pattern([i, feel, 1], [do, you, often, feel, that, way, ?]).
pattern([1, love, 2], [do, you, feel, unloved, ?]).
pattern([1, X, 2],
[can, you, tell, me, more, about, your, X, ?]) :important(X).
pattern([1, me], [what, makes, you, think, that, ?]).
pattern([1], [please, tell, me, more]).
important(father). important(mother).
important(problem). important(fear).
128
Fallstudie 1: Eliza
Pattern Matching with I/O Creation
Stimulus Dictionary Input
Response Dictionary Output
match([N| Pattern], Dictionary, Target) :integer(N), lookup(N, Dictionary, LeftTarget),
append(LeftTarget, RightTarget, Target),
match(Pattern, Dictionary, RightTarget).
match([Word| Pattern], Dictionary, [Word| Target]) :atom(Word), match(Pattern, Dictionary, Target).
match([], _, []).
lookup(Key, [(Key, Value)| Tail], Value).
lookup(Key, [(Key1, _)| Tail], Value) :\+ (Key = Key1), lookup(Key, Tail, Value).
129
Fallstudie 1: Eliza
Pattern Matching with I/O Creation
• match ([i, am, 1],
beim
Dictionary,
Aufruf
[i, am, sick])
• match ([i, am, 1],
beim
[(1, [sick])| Tail],
Austritt
[i, am, sick])
• match ([how, long, have, you, been, 1, ?],
[(1, [sick])| Tail],
Output)
• match ([how, long, have, you, been, 1, ?],
[(1, [sick])| Tail],
[how, long, have, you, been, sick, ?])
Stimulus
Dictionary
Input
Stimulus
Dictionary
Input
Response
Dictionary
Output
Response
Dictionary
Output
130
Fallstudie 1: Eliza
Input Scanning Support
read_word_list(Ws) :- get0(C), read_word_list(C, Ws).
read_word_list(C, [W|Ws]) :word_char(C, C1),
read_word(C1, W, C2),
read_word_list(C2, Ws).
read_word_list(C, []) :- end_of_words_char(C).
read_word_list(C, Ws) :fill_char(C), get0(C1), read_word_list(C1, Ws).
read_word(C, W, C1) :word_chars(C, Cs, C1), name(W, Cs).
word_chars(C, [C1| Cs], C0) :word_char(C, C1), !, get0(C2), word_chars(C2, Cs, C0).
word_chars(C, [], C) :- \+ word_char(C, _).
131
Fallstudie 1: Eliza
Input Scanning Support
word_char(C, C) :- 97 =< C, C =< 122.
word_char(C, C1) :- 65 =< C, C =< 90, C1 is C + 32.
word_char(C, C) :- 48 =< C, C =< 57.
word_char(95, 95). % _
word_char(39, 39). % '
fill_char(32). % space
fill_char(40). % (
fill_char(41). % )
fill_char(33). % !
fill_char(63). % ?
fill_char(_). % treat any other "bad" char as fill char
end_of_words_char(46). % .
end_of_words_char(10). % newline
132
Fallstudie 2: Flucht über Brücke
Hilfsprädikate (Lösung nach Ch. Portmann)
• append1 ([], L, L).
append1 ([X|L1], L, [X|L2]) :append1 (L1, L, L2).
• select1 (X, [X|L], L).
select1 (X, [Y|L1], [Y|L2]) :select1 (X, L1, L2).
• group ([X], L1, L2, X) :- select1 (X, L1, L2).
X Maximum Y
group ([X, Y], L1, L2, Y) :select1 (X, L1, L), select1 (Y, L, L2),
X <= Y.
133
Fallstudie 2: Flucht über Brücke
Zyklus left → right → left
Protokoll
• left (L, R, P0, P2, T0, T2, TMax) :group (X, L, L1, TGroup), T0
append1 (X, R, R1),
L
append1 (P0, [X], P1),
T2
T1 is T0 + TGroup,
T1 =< TMax,
right (L1, R1, P1, P2, T1, T2, TMax).
T1
R
134
Fallstudie 2: Flucht über Brücke
Zyklus right → left → right
• right (L, R, P0, P2, T0, T2, TMax) :group (X, R, R1, TGroup),
append1 (X, L, L1),
append1 (P0, [X], P1),
T1 is T + TGroup,
T1 =< TMax,
left (L1, R1, P1, P2, T1, T2, TMax).
• right([], _, P, P, T, T, _).
Ziel
135
Fallstudie 2: Flucht über Brücke
Programm
• go (People, TMax, P, T) :left (People, [], [], P, 0, T, TMax).
• go ([5, 10, 20, 25], 60, P, T).
start
(people coded
by transition
time)
136
Deskriptive Programmierung
137
XML
(Extended Markup Language)
• XML Elemente Taginhalt
Sematisches
<director>John Doe</director>
Tag
<actor>John Doe</actor>
<CITY zip="4000">Basel</CITY>
Mit Attribut
<marker kind= "separator" />
Leeres Tag
• XML Dokumente
<?xml version="1.0" encoding="ISO-8859-1"?>
<library>
<book isbn="0345374827">
<title>Zen and the Art of Motorcycle Maintenance
</title>
<author>Robert M. Pirsig</author>
</book>
138
</library>
XML
Namespaces
• Explizite Namespaces
Globally
unique id
<LIBRARY>
<books:BOOK
xmlns:books="urn:BookLovers.org:BookInfo"
xmlns:money="urn:Finance:Money">
<books:TITLE>Creepy Crawlies</books:TITLE>
<books:PRICE money:currency="US Dollar">
22.95
</books:PRICE>
</books:BOOK>
</LIBRARY>
• Default Namespace
<BOOK xmlns="urn:BookLovers.org:BookInfo">
<TITLE>Creepy Crawlies</TITLE>
<PRICE currency="US Dollar">22.95</PRICE>
</BOOK>
139
XML
Schemata (1)
• <?xml version="1.0"?>
<note
xmlns="http://www.w3schools.com"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchemainstance"
xsi:schemaLocation=
"http://www.w3schools.com/schema/note.xsd">
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body lang="EN">Don't forget me!</body>
</note>
140
XML
Schemata (2)
• <?xml version="1.0"?>
<xs:schema
xmlns="http://www.w3schools.com"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.w3schools.com"
elementFormDefault="qualified">
<xs:element name="note">
complex
<xs:complexType><xs:sequence>
simple
<xs:element name="to" type="xs:string"/>
<xs:element name="from" type="xs:string"/>
<xs:element name="heading" type="xs:string"/>
<xs:element name="body" mixed="true">
<xs:attribute name="lang" type="xs:string"/>
</xs:element>
El./Attr.
</xs:sequence></xs:complexType>
</xs:element>
und Text
141
</xs:schema>
Schemata
Modifiers
• Defaultwert-Modifiers
<xs:element name="color" type="xs:string"
default="red"/>
<xs:element name="color" type="xs:string"
fixed="red"/>
• Bereich-Modifiers
<xs:element name="age">
<xs:simpleType> <xs:restriction base="xs:integer">
<xs:minInclusive value="0"/>
<xs:maxInclusive value="100"/>
</xs:restriction> </xs:simpleType>
</xs:element>
142
Schemata
Modifiers
• Bereich-Modifiers
¾ <xs:element name="car">
<xs:simpleType> <xs:restriction base="xs:string">
<xs:enumeration value="Audi"/>
<xs:enumeration value="Golf"/>
<xs:enumeration value="BMW"/>
</xs:restriction> </xs:simpleType>
</xs:element>
¾ <xs:element name="letter">
<xs:simpleType> <xs:restriction base="xs:string">
<xs:pattern value="([a-z])*"/>
</xs:restriction> </xs:simpleType>
</xs:element>
143
Schemata
Typdefinition
• <xs:complexType name="personinfo">
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence>
</xs:complexType>
• <xs:element name="employee" type="personinfo"/>
<xs:element name="student" type="personinfo"/>
<xs:element name="member" type="personinfo"/>
144
Schemata
Typableitung durch Erweiterung
• <xs:complexType name="personinfo">
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence>
</xs:complexType>
• <xs:complexType name="fullpersoninfo">
<xs:complexContent>
<xs:extension base="personinfo"> <xs:sequence>
<xs:element name="address" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="country" type="xs:string"/>
</xs:sequence></xs:extension>
</xs:complexContent>
</xs:complexType>
• <xs:element name="employee" type="fullpersoninfo"/>
145
Schemata
Typableitung durch Einschränkung
• <xs:complexType name="vehicle">
<xs:complexContent>
<xs:sequence>
<xs:element name="license" type="xs:string"/>
<xs:element name="category" type="xs:string"/>
<xs:element name="fabdate" type="xs:date"/>
<xs:element name="weight" type="xs:int"/>
</xs:sequence>
</xs:complexContent>
</xs:complexType>
• <xs:complexType name="bicycle">
<xs:restriction base="personinfo"> <xs:sequence>
<xs:element name="license" type="xs:string"/>
<xs:element name="fabdate" type="xs:date"/>
</xs:sequence> </xs:restriction>
</xs:complexType>
146
Schemata
Kompositoren
Alle in
beliebiger
Reihenfolge
• <xs:element name="person">
<xs:complexType> <xs:all>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:all> </xs:complexType>
Genau
</xs:element>
eines
• <xs:element name="person">
<xs:complexType> <xs:choice>
<xs:element name="employee" type="employee"/>
<xs:element name="member" type="member"/>
</xs:choice> </xs:complexType>
</xs:element>
147
Schemata
Kompositoren
Genau in
dieser
Reihenfolge
• <xs:element name="person">
<xs:complexType> <xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence> </xs:complexType>
</xs:element>
• <xs:element name="person">
<xs:complexType> <xs:sequence>
<xs:element name="full_name" type="xs:string"/>
<xs:element name="child_name" type="xs:string"
maxOccurs="10" minOccurs="0"/>
</xs:sequence> </xs:complexType> Spezifikation
der Anzahl
</xs:element>
148
Schemata
Any Element
Auszug aus
familiy.xsd
• <xs:element name="person">
<xs:complexType> <xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
<xs:any minOccurs="0"/>
</xs:sequence> </xs:complexType>
</xs:element>
• <xs:element name="children">
<xs:complexType> <xs:sequence>
<xs:element name="childname" type="xs:string"
maxOccurs="unbounded"/>
</xs:sequence> </xs:complexType>
</xs:element>
Auszug aus
children.xsd
149
• <?xml version="1.0" encoding="ISO-8859-1"?>
<persons xmlns="http://www.microsoft.com"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema instance"
xsi:SchemaLocation=
"http://www.microsoft.com family.xsd
http://www.w3schools.com children.xsd">
<person>
<firstname>Hege</firstname>
<lastname>Refsnes</lastname>
<children>
<childname>Cecilie</childname>
</children>
</person>
<person>
<firstname>Stale</firstname>
<lastname>Refsnes</lastname>
</person>
</persons>
150
Schemata
Elementgruppen
• <xs:group name="persongroup">
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
<xs:element name="birthday" type="xs:date"/>
</xs:sequence>
</xs:group>
• <xs:element name="person" type="personinfo">
• <xs:complexType name="personinfo">
<xs:sequence>
<xs:group ref="persongroup"/>
<xs:element name="country" type="xs:string"/>
</xs:sequence> </xs:complexType>
151
Schemata
Attributgruppen
• <xs:attributeGroup name="personattrgroup">
<xs:attribute name="firstname" type="xs:string"/>
<xs:attribute name="lastname" type="xs:string"/>
<xs:attribute name="birthday" type="xs:date"/>
</xs:attributeGroup>
• <xs:element name="person">
<xs:complexType>
<xs:attributeGroup ref="personattrgroup"/>
</xs:complexType>
</xs:element>
152
XML
Baumsicht & Pfadmodell
• XPath Notation für XML Knotenzugriffe
XML Baum
<AAA>
<BBB/>
<CCC/>
<BBB/>
<BBB/>
<DDD>
<BBB/>
</DDD>
<CCC/>
</AAA>
Knotenidentifikation durch Pfade
/AAA
/AAA/CCC
/AAA/DDD/BBB
153
<AAA>
<BBB/>
<CCC/>
<BBB/>
<DDD>
<BBB/>
</DDD>
<CCC>
<DDD>
<BBB/>
<BBB/>
</DDD>
</CCC>
</AAA>
<AAA>
<BBB/>
<CCC/>
<BBB/>
<DDD>
<BBB/>
</DDD>
<CCC>
<DDD>
<BBB/>
<BBB/>
</DDD>
</CCC>
</AAA>
//BBB
//DDD/BBB
154
<AAA>
<AAA>
<XXX>
<XXX>
<DDD>
<DDD>
<BBB/>
<BBB/>
<BBB/>
<BBB/>
<EEE/>
<EEE/>
<FFF/>
<FFF/>
</DDD>
</DDD>
</XXX>
</XXX>
<CCC>
<CCC>
<DDD>
<DDD>
<BBB/>
<BBB/>
<BBB/>
<BBB/>
<EEE/>
<EEE/>
<FFF/>
<FFF/>
</DDD>
</DDD>
</CCC>
</CCC>
<CCC>
<CCC>
<BBB>
<BBB>
<BBB>
<BBB>
<BBB/>
<BBB/>
</BBB>
</BBB>
</BBB>
</BBB>
</CCC>
</CCC>
</AAA>
</AAA>
/AAA/CCC/DDD/*
/*/*/*/BBB
//* (alle)
155
<AAA>
<BBB/>
<BBB/>
<BBB/>
<BBB/>
</AAA>
<AAA>
<BBB id = "b1"/>
//BBB[@*] <BBB id = "b2"/>
<BBB name = "bbb"/>
//BBB[not(@*)] <BBB/>
</AAA>
/AAA/BBB[1]
/AAA/BBB[last]
//@id
//BBB[@id]
//BBB[@name]
156
<AAA>
<AAA>
<BBB id = "b1"/>
<BBB id = "b1"/>
<BBB name = " bbb "/>
<BBB name = " bbb "/>
<BBB name = "bbb"/>
<BBB name = "bbb"/>
</AAA>
</AAA>
//BBB[@id='b1']
//BBB[@name='bbb']
//BBB[normalize-space(@name)='bbb']
157
<AAA>
<CCC>
<BBB/>
<BBB/>
<BBB/>
</CCC>
<DDD>
<BBB/>
<BBB/>
</DDD>
<EEE>
<CCC/>
<DDD/>
</EEE>
</AAA>
<AAA>
<CCC>
<BBB/>
<BBB/>
<BBB/>
</CCC>
<DDD>
<BBB/>
<BBB/>
</DDD>
<EEE>
<CCC/>
<DDD/>
</EEE>
</AAA>
//*[count(BBB)=2]
//*[count(*)=2]
//*[count(*)=3]
<AAA>
<CCC>
<BBB/>
<BBB/>
<BBB/>
</CCC>
<DDD>
<BBB/>
<BBB/>
</DDD>
<EEE>
<CCC/>
<DDD/>
</EEE>
</AAA>
158
<AAA>
<BCC>
<BBB/>
<BBB/>
<BBB/>
</BCC>
<DDB>
<BBB/>
<BBB/>
</DDB>
<BEC>
<CCC/>
<DBD/>
</BEC>
</AAA>
<AAA>
<BCC>
<BBB/>
<BBB/>
<BBB/>
</BCC>
<DDB>
<BBB/>
<BBB/>
</DDB>
<BEC>
<CCC/>
<DBD/>
</BEC>
</AAA>
<AAA>
<BCC>
<BBB/>
<BBB/>
<BBB/>
</BCC>
<DDB>
<BBB/>
<BBB/>
</DDB>
<BEC>
<CCC/>
<DBD/>
</BEC>
</AAA>
//*[name()='BBB']
//*[starts-with(name(),'B')]
//*[contains(name(),'C')]
159
<AAA>
<Q/>
<SSSS/>
<BB/>
<CCC/>
<DDDDDDDD/>
<EEEE/>
</AAA>
//*[string-length(name()) = 3]
//*[string-length(name()) < 3]
//*[string-length(name()) > 3]
160
<AAA>
<AAA>
<AAA>
<BBB/>
<BBB/>
<BBB/>
<CCC/>
<CCC/>
<CCC/>
<DDD>
<DDD>
<DDD>
<CCC/>
<CCC/>
<CCC/>
</DDD>
</DDD>
</DDD>
<EEE/>
<EEE/>
<EEE/>
</AAA>
</AAA>
</AAA>
//CCC | //BBB
/AAA/EEE | //BBB
/AAA/EEE | //DDD/CCC | /AAA | //BBB
161
<AAA>
<BBB/>
<BBB/>
<BBB/>
<BBB/>
<BBB/>
<BBB/>
<BBB/>
<BBB/>
<CCC/>
<CCC/>
<CCC/>
</AAA>
<AAA>
<BBB/>
<BBB/>
<BBB/>
<BBB/> //BBB[position() mod 2 = 0]
<BBB/> //BBB[ position() =
floor(last() div 2 + 0.5) or
<BBB/>
position() = ceiling(last() div 2 + 0.5)]
<BBB/>
<BBB/> //CCC[
position() = floor(last() div 2 + 0.5) or
<CCC/>
position() = ceiling(last() div 2 + 0.5)]
<CCC/>
<CCC/>
</AAA>
162
/ ... ::
Achse
Achsen
self
child (Default)
descendant
parent
ancestor
following-sibling
preceding-sibling
following
preceding
descendant-or-self
ancestor-or-self
Partitionierung
children, children of children, ...
parents, parents of parents, ...
following siblings
preceding siblings
Bezüglich
aktuellem
context
163
<AAA>
<BBB>
<AAA>
<CCC/>
<BBB>
<BBB/>
<ZZZ>
<CCC/>
<CCC/>
<DDD/>
<DDD/>
</AAA>
</ZZZ>
</BBB>
</BBB>
<XXX>
/AAA
<XXX>
<DDD>
/child::AAA
<DDD>
<EEE/>
/AAA/BBB
<EEE/>
<DDD/>
/child::AAA/child::BBB
<DDD/>
<CCC/>
/child::AAA/BBB
<CCC/>
<FFF/>
<FFF/>
<FFF>
<FFF>
<GGG/>
<GGG/>
</FFF>
</FFF>
</DDD>
</DDD>
</XXX>
//CCC/following-sibling::*
</XXX>
<CCC>
//GGG/preceding::*
<CCC>
<DDD/>
<DDD/>
</CCC>
</CCC>
</AAA>
164
</AAA>
<AAA>
XSLT
Grundprinzipien
• Transformiert XML Quellbaum in XML
Resultatbaum
™Typische Anwendung ist die Darstellung
eines XML Quelldokumentes in Form eines
XHTML Resultatdokumentes
• Ist regelbasiert. Erkennt spezifizierte
Templates im Quellbaum und transformiert sie
gemäss angegebenen Regeln
• Transformiert den Restbaum identisch
• Verwendet XPath zur Navigation im XML Baum
165
XSLT
Beispiel CD Katalog
• <?xml version="1.0" encoding="ISO-8859-1"?>
<catalog>
<cd>
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
...
</catalog>
166
Schablone
• <?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
XPath (root)
<html> <body>
<h2>My CD Collection</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th align="left">Title</th>
<th align="left">Artist</th>
XPath
</tr>
<xsl:for-each select="catalog/cd">
<tr>
<td><xsl:value-of select="title"/></td>
<td><xsl:value-of select="artist"/></td>
</tr>
</xsl:for-each>
Schreibe
</table>
operation
</body> </html>
</xsl:template>
</xsl:stylesheet>
167
XSLT
Output Steuerung
• XPath Funktionen
o Anzahl Knoten
Review of 3.5 = <xsl:value-of
select="count(books/book[review=3.5])"/>
o Wert als Zahl
The number is: <xsl:value-of
select="number(books/book/price)"/>
o Substring
<xsl:value-of select="substring(name, 1, 3)"/>
o Position im Kontext
<xsl:number value="position()"/>.
<xsl:value-of select="name"/>
o Summe
Total Price = <xsl:value-of select="sum(//price)"/>
168
XSLT
Output Steuerung
• Sortieren
o <xsl:sort
select = string-expression
data-type = { "text" | "number" | Qname }
order = { "ascending" | "descending" }
case-order = { "upper-first" | "lower-first" }
lang = { language-code }
/>
o <xsl:for-each select="catalog/cd">
<xsl:sort select="artist"/>
<tr>
<td><xsl:value-of select="title"/></td>
<td><xsl:value-of select="artist"/></td>
</tr>
</xsl:for-each>
169
XSLT
Output Steuerung
• Bedingung
<xsl:for-each select="catalog/cd">
<xsl:if test="price>10">
<tr>
<td><xsl:value-of select="title"/></td>
<td><xsl:value-of select="artist"/></td>
</tr>
</xsl:if>
</xsl:for-each>
• Filter
<xsl:for-each select="catalog/cd[artist='...']">
Filteroperatoren = (equal) != (not equal) < >170
XSLT
• Auswahl
Output Steuerung
<xsl:for-each select="catalog/cd">
<tr>
<td><xsl:value-of select="title"/></td>
<xsl:choose>
<xsl:when test="price>'10'">
<td bgcolor="#ff00ff">
<xsl:value-of select="artist"/>
</td>
</xsl:when>
<xsl:otherwise>
<td><xsl:value-of select="artist"/></td>
</xsl:otherwise>
</xsl:choose>
</tr>
</xsl:for-each>
171
XSLT
Output Steuerung
• Hinzufügen eines Attributes
<img>
<xsl:attribute name="src">
<xsl:value-of select="@src" />
</xsl:attribute>
</img>
172
XSLT
Output Steuerung
• Anwendung von Templates
Regelbasierte
Architektur
<xsl:template match="/">
<html> <body> <h2>My CD Collection</h2>
<xsl:apply-templates/>
</body> </html>
</xsl:template>
<xsl:template match="cd">
<p>
<xsl:apply-templates select="title"/>
<xsl:apply-templates select="artist"/>
</p>
</xsl:template>
173
XSLT
Output Steuerung
• Anwendung von Templates
<xsl:template match="title"> Title:
<span style="color:#ff0000">
<xsl:value-of select="."/>
</span> <br />
</xsl:template>
<xsl:template match="artist"> Artist:
<span style="color:#00ff00">
<xsl:value-of select="."/>
</span> <br />
</xsl:template>
174
Simple Vector Graphics (SVG)
Beispiel 1
• Blaues Rechteck in rotem Rechteck
<?xml version="1.0" encoding="ISO-8859-1"
standalone="no" ?>
<!DOCTYPE svg PUBLIC "//W3C//DTD SVG
20010904//EN" "http://www.w3.org/TR/2001/
REC-SVG 20010904/DTD/svg10.dtd">
<svg width="200" height="200"
xmlns="http://www.w3.org/2000/svg">
<rect x="0" y="0" width="200" height="200"
style="fill:red;" />
<svg x="10" y="10" width="100" height="100">
<rect x="0" y="0" width="100" height="100"
style="fill:blue;" />
</svg>
</svg>
175
Simple Vector Graphics (SVG)
• Spirale als Pfad
Beispiel 2
• <path
d="M156 334 C153.239 334 151 334 151 334 C151
339.523 153.239 344 156 344 C164.284 344 171 339.523
171 334 C171 322.954 164.284 314 156 314 C142.193
314 131 322.954 131 334 C131 350.568 142.193 364 156
364 C175.33 364 191 350.568 191 334 C191 311.909
175.33 294 156 294 C131.147 294 111 311.909 111 334
C111 361.614 131.147 384 156 384 C186.375 384 211
361.614 211 334 C211 300.863 186.375 274 156 274"
style="fill:none;stroke:url(#red-darkgreen);
stroke-width:2"/>
• M = moveto, L = lineto, H = horizontal lineto,
V = vertical lineto, C = curveto, S = smooth curveto,
Q = quadratic bezier curve, A = elliptical arc
T = smooth quadratic bezier curveto. Z = closepath 176
Simple Vector Graphics (SVG)
Beispiel 3
• Beleuchtete Kugel
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
"http://www.w3.org/TR/2001/REC-SVG
20010904/DTD/svg10.dtd">
<svg width="100%" height="100%">
<defs>
<radialGradient id="fade-to-black" cx="50%"
cy="50%" r="50%" fx="50%" fy="50%" spreadMethod="pad"
gradientUnits="objectBoundingBox">
<stop offset="0%"
style="stop-color:rgb(255,255,255);stop-opacity:0"/>
<stop offset="100%"
style="stop-color:rgb(0,0,0);stop-opacity:1"/>
</radialGradient>
</defs>
<ellipse cx="229.5" cy="200.5" rx="112.5" ry="100.5"
style="fill:url(#fade-to-black)"/>
177
</svg>
XSLT
Auf SVG angewandt
• XML Quelldokument
<?xml version="1.0"?>
<cubicles>
<cubicle north="10" east="15"
width="10" length="10"/>
<cubicle north="0" east="0"
width="10" length="10"/>
</cubicles>
178
XSLT
Auf SVG angewandt
• XSL Transformation
<?xml version='1.0'?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<svg xmlns="http://www.w3.org/2000/svg">
<title>Our Cubicles</title>
<xsl:apply-templates select="cubicle"/>
</svg>
</xsl:template>
<xsl:template match="cubicle">
<rect x="{north}" y="{east}"
width="{width}" height="{length}"/>
</xsl:template>
</xsl:stylesheet>
179
XSLT
Auf SVG angewandt
• SVG Resultatdokument
<?xml version="1.0" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg">
<title>Our Cubicles</title>
<rect x="10" y="15" width="10" height="10"/>
<rect x="0" y="0" width="10" height="10"/>
</svg>
180
XSLT
Strukturschema (1)
XML
Internalize
/
A
DOM
B
A
Skript
xxxx
yy zzz XSLT
ZL
Templates
Function Calls
A
C
API
Impl
XSLT
Prozessor
Strom
ZL
181
XSLT
Strukturschema (2)
Internalize
ZL
Template
ZL
Template
DOM
Impl
XML
/
A
B
A
A
C
API
Impl
XSLT
Prozessor
Strom
ZL
182
ASP
Server Architektur (1)
request
Internet Server
C
C
http
.htm
Active
Server
Page
.asp
ASP
engine
183
ASP
Server Architektur (2) Provider A
Webservice
f
My
Webservice .asp
.htm
f
g
Internet
incl.
state
post
back .net
ASP
engine
class
Provider B
Webservice
g
184
ASP
Server Code
•
Inline Server Code
<html>
<body bgcolor="yellow">
<center>
<h2>Hello W3Schools!</h2>
<p><%Response.Write(now())%></p>
</center>
</body>
</html>
185
ASP
HTML Server Controls
• <script runat="server">
Sub Page_Load
link1.HRef="http://www.w3schools.com"
End Sub
</script>
<html>
Web Form
<body>
<form runat="server">
<a id="link1" runat="server">Visit W3Schools!</a>
</form>
HTML Server
</body>
Control
</html>
186
ASP
Web Server Controls
• <asp:control_name id="some_id" runat="server">
• <html>
<body>
Calendar Control
<form runat="server">
<asp:Calendar DayNameFormat="Full"
runat="server">
<WeekendDayStyle
BackColor="#fafad2" ForeColor="#ff0000" />
<DayHeaderStyle ForeColor="#0000ff" />
<TodayDayStyle BackColor="#00ff00" />
</asp:Calendar>
</form>
</body>
</html>
187
ASP
Web Server Controls
• <html>
XML Control
<body>
<form runat="server">
<asp:Xml DocumentSource="cdcatalog.xml"
TransformSource="cdcatalog.xsl" runat="server"
/>
</form>
<p><a href="cdcatalog.xml" target="_blank">
View XML file
</a></p>
<p><a href="cdcatalog.xsl" target="_blank">
View XSL file
</a></p>
</body>
</html>
188
ASP
Web Server Controls
• <script runat="server">
Sub submit(Source As Object, e As EventArgs)
button1.Text="You clicked me!"
End Sub
</script>
<html>
Web Server
<body>
Control
<form runat="server">
<asp:Button id="button1" Text="Click me!"
runat="server" OnClick="submit"/>
</form>
</body>
</html>
189
ASP
Validation Server Controls
• <html>
<body>
<form runat="server">
Enter a number from 1 to 100:
<asp:TextBox id="tbox1" runat="server" />
<br /><br />
<asp:Button Text="Submit" runat="server" /> <br />
<asp:RangeValidator ControlToValidate="tbox1"
MinimumValue="1" MaximumValue="100"
Type="Integer" EnableClientScript="false"
Text="The value must be from 1 to 100!"
runat="server" />
</form>
Validation
</body>
Server Control
190
</html>
ASP
Event Handlers
• <script runat="server">Sub Page_Load
if Not Page.IsPostBack then
lbl1.Text="The date and time is " & now() end if
End Sub
Sub submit(s As Object, e As EventArgs)
lbl2.Text="Hello World!"
End Sub
</script>
<html>
<body>
<form runat="server">
<h3><asp:label id="lbl1" runat="server" /></h3>
<h3><asp:label id="lbl2" runat="server" /></h3>
<asp:button text="Submit" onclick="submit"
runat="server" />
</form>
</body>
</html>
191
ASP
Volatile Content
• <html>
<body>
<form action="demo_classicasp.aspx"
method="post"> Your name:
<input type="text" name="fname" size="20">
<input type="submit" value="Submit">
</form>
<% dim fname
fname=Request.Form("fname")
If fname<>"" Then
Response.Write("Hello " & fname & "!") End If
%>
</body>
</html>
192
ASP
Persistent Content
• <script runat="server">
Sub submit(sender As Object, e As EventArgs)
lbl1.Text="Hello " & txt1.Text & "!"
End Sub
</script>
<html>
<body>
<form runat="server"> Your name:
<asp:TextBox id="txt1" runat="server" />
<asp:Button OnClick="submit" Text="Submit"
runat="server" /> <p>
<asp:Label id="lbl1" runat="server" /></p>
</form>
</body>
</html>
193
ASP
Persistent Content
• <form name="_ctl0" method="post"
action="page.aspx" id="_ctl0">
<input type="hidden" name="__VIEWSTATE"
value="dDwtNTI0ODU5MDE1Ozs+
ZBCF2ryjMpeVgUrY2eTj79HNl4Q=" />
.....some code
</form>
194
ASP
Data Binding via XML (1)
• <%@ Import Namespace="System.Data" %>
<script runat="server"> sub Page_Load
if Not Page.IsPostBack then
dim mycountries=New DataSet
mycountries.ReadXml(MapPath("countries.xml"))
rb.DataSource=mycountries
rb.DataValueField="value"
rb.DataTextField="text"
rb.DataBind()
end if
end sub
sub displayMessage(s as Object,e As EventArgs)
lbl1.text="Your favorite country is: "
& rb.SelectedItem.Text
end sub
195
</script>
ASP
Data Binding via XML (2)
• <html>
<body>
<form runat="server">
<asp:RadioButtonList id="rb" runat="server"
AutoPostBack="True"
onSelectedIndexChanged="displayMessage" />
<p>
<asp:label id="lbl1" runat="server" />
</p>
</form>
</body>
</html>
196
ASP
Fallstudie Picture Market
• Servicebeschreibung
o
o
Kunde fordert Bild an
Server liefert Zufallsbild
• Servicebestandteile
o
Aktive Serverseite
o
„Businesslogic“ Modul
o
Kollektion von Bildern
PictureMart.aspx
Auf
Serverseite
PictureMart.mod
pict1.gif, ..., pictN.gif
197
Fallstudie Picture Market
PictureMart.aspx (1)
suche in \bin Directory
und Assemblycache
<html>
<head>
<add assembly = "PictureMart.dll, Version=1.0"/>
<script language="C#" runat="server">
public void Page_Load(Object sender, EventArgs E) {
if (!(Page.IsPostBack) ) {
Image1.ImageUrl = "pic/empty.gif"; } }
void SubmitBtn_Click(Object sender, EventArgs e) {
Image1.ImageUrl = PictureMart.PictureMart.Select(); }
</script>
</head>
<body>
198
...
Fallstudie Picture Market
PictureMart.aspx (2)
...
</head>
<body>
<h3>Fun Picture Market</h3>
Business Logic powered by Oberon for .net
<form runat=server>
<asp:Image ID = "Image1" ImageUrl = "pic/empty.gif"
AlternateText = "empty" runat = "server"/>
<p>
<asp:button text = „Apply“
OnClick = "SubmitBtn_Click" runat = server/>
</form>
</body>
</html>
199
Fallstudie Picture Market
PictureMart.mod
Oberon
for .NET
MODULE PictureMart;
IMPORT System;
VAR rand: System.Random;
PROCEDURE Select* (): System.String;
BEGIN
RETURN System.String.Concat
{ (System.String, System.String, System.String):
System.String } ("pic/pict",
System.Convert.ToString(rand.Next(1, 14)), ".gif");
END Select;
BEGIN NEW(rand)
END PictureMart.
200
Herunterladen