Informatik 3 WS 2002/3 http://www.cs.inf.ethz.ch/37-003/ Prof. Jürg Gutknecht ETH Zürich 1 Inhaltsübersicht • Imperative Programmierung ¾ Nichtdeterminismus ¾ Guarded Commands, Unity • Funktionale Programmierung ¾ Evaluations Strategien, λ-Calculus ¾ Lisp, Scheme, ML, Haskell • Deklarative Programmierung ¾ Meta Beschreibung (Schemas) ¾ XML • Logische Programmierung ¾ Horn-Klauseln, Inferenzmechanismen ¾ Prolog 2 Imperative Programmierung Rekapitulation • Zustandsraum X • Prädikate P, Q, ... über X • Anweisungen S, T, ... ¾Zustandstransformatoren x → S(x) ¾Prädikatentransformatoren Q → wp(S, Q) • Hoare Triplet { P } S { Q } P ⇒ wp(S, Q) Weakest Precondition 3 1 Imperative Programmierung Dijkstra‘s Sprache • • • • • • • Guarded Command P → S Abort Anweisung abort Skip Anweisung skip Zuweisung x, y, ... := E, F, ... Sequenz S; T Alternative if P → S | Q → T | … fi Repetition do P → S | Q → T | … od 4 Imperative Programmierung Semantik • Semantik der Zuweisung x durch E ¾Zuweisung x := E substituieren ¾wp(x := E, Q) = Q(x := E) • Beispiel: Implementation von x, y := y, x ¾t := x; x := y; y := t ¾x := x + y; y := x - y; x := x – y (x = X) ∧ (y = Y) (x - y = X) ∧ (y = Y) (x – (x – y ) = X) ∧ (x - y = Y) (y = X) ∧ (x + y - y = Y) 5 Imperative Programmierung Nichtdeterminismus • Ordnen H :⇔ (a, b, c) ist Permutation von (A, B, C) a, b, c := A, B, C; { H } Invariante do a > b → swap a, b { H } | b > c → swap b, c { H } od Termination { (a ≤ b ≤ c) ∧ H } ? • Sequentielle Implementation ¾Bubblesort 6 2 Imperative Programmierung 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 } do f(I) < g(J) → I := I + 1 { H } Sentinel | g(J) < h(K) → J := J + 1 { H } garantiert | h(K) < f(I) → K := K + 1 { H } Termination od { (f(I) ≥ g(I) ≥ h(K) ≥ f(I)) ∧ H } 7 Unity Formalismus Chandy & Misra • Nächstmögliche Meetingzeit? • Meetingagenda f ¾(∀t: f(t) ≥ t, f(f(t)) = f(t)) • f, g, h Agendas 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 8 Unity Formalismus Nächstmögliche Meetingzeit • Invariante (∀s: s < t: s ist keine mögliche Meetingtime) • Beweis Mit vollständiger Induktion • Wahr bei Programmstart • Wahr nach jeder Ausführung einer Zuweisung 9 3 Unity Formalismus 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 f ¾Verteiltes System • r := max (f(r), g(r), h(r)) g Zentraler Koordinator f h g h 10 Abstrakte Spezifikation Konzept der Zwischensprache Problemebene Spezifikationsebene Guarded Commands Unity Implementationsebene Von Neumann SMP Verteiltes System11 Kommentar 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. 12 4 Funktionale Programmierung Grundprinzipien • Speicherloses Ablaufsmodell ¾ Wegabstraktion von Speicherzuständen und Zustandsübergängen • y = f(x) ¾ Resultat als Funktion der Argumente ¾ Keine Nebeneffekte • z = g(f(x)) = (gf)(x) ¾ Komposition von Funktionen • g = F(f) ¾ Funktionen als Argumente und Resultate 13 Funktionale Programmierung am Beispiel von ML • Standard ML ¾Core Language für Programming-in-the-Small • Higher-Order Prozedural • Funktionaler Subset – – – – Starke Typisierung mit Inferenzmechanismus Funktionen als „First-Class-Citizens″ Parametrischer Polymorphismus Lazy Evaluation • Interaktive Abarbeitung auf Expressionbasis ¾Modulsystem für Programming-in-the-Large • Structures • Signatures • Functors 14 Funktionen Notation • Deklarationsmuster fn x => E fn x0 => E0 | x1 => E1 | ... | _ => En val f = fn x => E val g = 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 Linksassoziativität! val pi = 3.1416 val color = fn 0 => ″red″ | 1 => ″green″ | 2 => ″blue color (1) 15 5 Scopes Notation • Deklarationsmuster ¾ local val a = ... val f = fn ... in val F = fn ... end • Beispiel ¾ local val pi = 3.14 val sq = fn x => x * x in val ringarea = fn (R, r) => pi * (sq R – sq r) end 16 Zeller‘sche Formel Bestimmung des Wochentages aus y, m, d ● (2.61m – 0.2 + d + y + y ÷ 4 + c ÷ 4 – 2c) mod 7 ● local Monat - 2 val floor = Real.floor 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 17 Rekursion Integer-to-String Uebersetzung val rec radix = fn (n, digits) => subscript let string val b = size digits val digit = fn n => str (String.sub (digits, n)) val radix‘ = fn (true, n) => digit n in | (false, n) => radix (n div b, digits) ^ digit (n mod b) radix‘ (n < b, n) concatenate end radix (13, ″01″) liefert ″1101″ 18 6 The Standard ML Library Typenbezogene Module („Structures“) • Bool Structure ¾ Bool.not ¾ Bool.fromString, Bool.toString • Char Structure T.fromString ¾ Char.chr, Char.ord ¾ Char.toUpper, Char.toLower ¾ Char.contains, Char.notContains • Int Structure ¾ Int.abs, Int.min, Int.max ¾ Int.fromString, Int.toString NONE SOME t option Datentyp • Real Structure ¾ Real.trunc, Real.round, Real.floor, Real.ceil ¾ Real.fromInt • String Structure ¾ String.sub, String.substring ¾ String.concat 19 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)) ... )) 20 Funktionen höherer Ordnung fadd/fmul in SML • val rec fadd = fn (f, n) => let val condfadd = fn in true => 0 │false => f (n) + fadd (f, n-1) condfadd (n < 1) end 21 7 Funktionen höherer Ordnung fgen in SML • val rec fgen = fn (g, f, e, n) => let val condfgen = fn in Neutral Element true => e │false => g (f (n), fgen(g, f, e, n-1)) condfgen (n < 1) end 22 Funktionen höherer Ordnung sum, sq, fac als fgen • op - Notation val op ♣ = fn (x, y) => x ♣ y • Ableitungen 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) 23 Funktionen höherer Ordnung Funktionen als Resultat • F (...) ist selbst eine Funktion 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)) 24 8 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 Curried ¾Z X x Y ≅ (Z Y) 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) 25 Funktionen höherer Ordnung Beispiel Hashing • Hashfunktion mit Kollisionsbehandlung ¾Hash (k, i) := (k + h (k, i)) mod N ¾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)) 26 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 27 9 Abgeleitete 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)) 28 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 } 29 Typvariablen und Datentypen • Polymorphie let val Id = fn x => x in (Id 3, Id true) end type α → α • type α set = α → bool Typvariable • Datentypen Konstruktor datatype color = red │ green │ blue datatype α tree = empty │ node of α * α tree * α tree Konstruktor node (25, NIL, node (17, NIL, NIL)) 30 10 Listen • datatype α list = nil │ :: of α * α list • 2 :: 1 :: nil cons [21] Abgeleitete Form Exception • fun hd [] = raise Empty│ hd (h :: t) = h • fun last [] = raise Empty │ last [x] = x │ last (h :: t) = last t • fun tl [] = raise Empty │ tl (h :: t) = t NONE SOME t 31 Listen • fun length [ ] = 0 │ length (h :: t) = 1 + length t • infixr 5 @ fun [] @ lst2 = lst2 │ (h :: t) @ lst2 = h :: t @ lst2 • fun rev [] = [] │ rev (h :: t) = (rev t) @ [h] • fun revAp ([], lst) = lst │ revAp (h :: t, lst) = revAp (t, h :: lst) 32 Listen • fun member (x, []) = false │member (x, h :: t) = x = h orelse member (x, t) • exception Retrieve fun retrieve (k, []) = raise Retrieve │ retrieve (k, (k1, v1) :: t) = if k = k1 then v1 else retrieve (k, t) • fun nth ([], _) = raise Subscript │ nth (h :: t, 0) = h │ nth (_ :: t, n) = nth (t, n – 1) handle Overflow => raise Subscript 33 11 Listen • 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 hthen h :: takewhile (p, t) else [] 34 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) 35 Listen • 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 end Effizienzsteigerung durch Ausfaktorisieren von f 36 12 Listen • fun mapPartial f [] = [] │mapPartial f (h :: t) = case f h of NONE => mapPartial f t │ SOME v => v :: mapPartial f t • 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 ¾type ((α * β) → β) → (β → ((α list) → β)) ¾f assoziativ & kommutativ ⇒ foldL f = foldR f 37 Listen • fun sort s = foldR insert [] s • fun concat s = foldR (op @) [] s ¾type (α list) list → α list • 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 ] 38 Listen • 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)] 39 13 Beispiel: 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) • datatype variable = Var of string 40 Beispiel: Command Interpreter Sample Command • WHILE X > Y DO X := X – 1; Z := Z * Z 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“))))) 41 Beispiel: Command Interpreter Store • fun assoc [] prevassoc a = prevassoc a │ assoc ((a0, b0) :: t) prevassoc a = if a = a0 then b0 else assoc t prevassoc a • fun emptyassoc a = error • datatype value = Value of int • datatype store = Store of (variable → value) • val nullstore = let fun f v = Value 0 in Store fend • fun get (v, Store f) = f v • fun update (Store f, v, a) = Store (assoc [(v, a)] f) • assoc [(v, a)] f ⇔ fun newf v’ = if v = v’ then a else f v’ 42 14 Beispiel: Command Interpreter Evaluator • eval: expression → store → value • fun eval (Constant n) s = Value n │ eval (Contents v) s = get (v, s) │ eval (Minus (e1, e2)) s = let val Value n1 = eval e1 s and Value n2 = eval e2 s in Value (n1 – n2) end │ eval (Times (e1, e2)) s = let val Value n1 = eval e1 s and Value n2 = eval e2 s in Value (n1 * n2) end │ eval (Greater (e1, e2)) s = let val Value n1 = eval e1 s and Value n2 = eval e2 s in if n1 > n2 then Value (1) else Value (0) end 43 Beispiel: 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 44 Beispiel: 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 45 15 Beispiel: 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 46 Beispiel: 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 • fun literal a (Symbol x :: s) = if a = x then Ok (x, s) else Fail │ literal a other = Fail ¾ Literal: string → string parser 47 Beispiel: 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) in modres (p s) end modify • fun (p1 <&> p2) s = infixr 4 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 48 16 Beispiel: Command Interpreter Expression Parsers • 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 49 Beispiel: Command Interpreter Expression Parsers • 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 50 Beispiel: Command Interpreter Command Parsers • 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 51 17 Beispiel: Command Interpreter Command Parsers • 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) 52 Abstrakte Datentypen • Abstraktionsmechanismen ¾Funktionen ¾Datentypen • Beispiele ¾Store definiert via Funktionen & Konstanten get: variable x store → value update: store x variable x value → store store0: store ¾Set (s. Uebung) 53 Abstrakte Datentypen Typ Funktion Programm Kunden ADT Operationen (Signaturen) Darstellungen Implementationen Darstellungen 54 18 Abstrakte Datentypen Beispiel canvas • datatype color = Red | Orange | Yellow | green | Blue | Indigo | Violet • datatype coordinate = Coord of int x int • type canvas newcanvas: color → int → int → canvas sizecanvas: canvas → (int * int) colorof: canvas → coordinate → color paint: color → coordinate → canvas → canvas 55 Abstrakte Datentypen Beispiel canvas • Spezifikation ¾ Hilfsprädikat is_on: coordinate → canvas → bool ¾ For all coord, coord‘: coordinate For all clr: color For all m, n, m1, n1: int For all canv: canvas colorof (newcanvas clr m n) coord‘ = clr colorof (paint clr coord canv) coord‘ = if coord = coord‘ & is_on (coord, canv) then clr else colorof canvas coord‘ sizecanvas (newcanvas clr m n) = (m, n) sizecanvas (paint clr coord canv) = sizecanvas canv is_on (Coord (m1, n1), newcanvas clr m n) = m1 > 0 & m1 <= m & n1 > 0 & n1 <= n is_on (coord‘, paint clr coord canv) = is_on (coord‘, canvas) 56 Abstrakte Datentypen Beispiel canvas • Implementation ¾ datatype canvas = Cnvs of int x int K clr coord x (coordinate → color) = clr ¾ fun newcanvas clr m n = Cnvs (m, n, K clr) fun sizecanvas (Cnvs (m, n, f)) = (m, n) fun colorof (Cnvs (m, n, f)) coord = f coord fun paint clr (Coord (m1, n1)) (Cnvs (m, n, f)) = if m1 > 0 & m1 <= m & n1 > 0 & n1 <= n then Cnvs (m, n, assoc [(Coord (m1, n1), clr)] f) else Cnvs (m, n, f) ¾ fun is_on (Coord (m1, n1), Cnvs (m, n, f)) = m1 > 0 & m1 <= m & n1 > 0 & n1 <= n 57 19 Abstrakte Datentypen Beispiel canvas • Authentication local fun f (Coord (m1, n1)) = if m1 < n1 then Red else Blue in val mycanvas = Cnvs (10, 10, f) end • Secrecy fun get_paint_fn (Cnvs (m, n, f)) = f 58 Abstrakte Datentypen Beschränkter Gültigkeitsbereich des Konstruktors Cnvs Beispiel canvas abstype canvas = Cnvs of int x int x (coordinate → color with fun newcanvas clr m n = Cnvs (m, n, K clr) fun sizecanvas (Cnvs (m, n, f)) = (m, n) fun colorof (Cnvs (m, n, f)) coord = f coord fun paint clr (Coord (m1, n1)) (Cnvs (m, n, f)) = if m1 > 0 & m1 <= m & n1 > 0 & n1 <= n then Cnvs (m, n, assoc [(Coord (n1, m1), clr)] f) else Cnvs (m, n, f) end 59 Abstrakte Datentypen Beispiel canvas 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 (clr, m, n)) = m1 > 0 & m1 <= m & n1 > 0 & n1 <= n is_on (coord‘, Paint (clr, coord, cnvs)) = is_on (coord‘, cnvs) in fun newcanvas clr m n = Newcanvas (clr, m, n) fun paint clr coord cnvs = Paint (clr, coord, cnvs) fun sizecanvas (Newcanvas (clr, m, n)) = (m, n) | sizecanvas (Paint (clr, coord, cnvs)) = sizecanvas cnvs fun colorof (Newcanvas (clr, m, n)) coord = clr | colorof (Paint (clr, coord, cnvs)) coord‘ = if coord = coord‘ & is_on(coord‘, cnvs) then clr else colorof cnvs coord‘ | end end 60 20 Abstrakte Datentypen Beispiel canvas • Die zweite Implementation von canvas widerspiegelt die Entstehungsgeschichte. Falls coord1 # coord2 sind folgende Konstruktionen verschiedene Darstellungen desselben abstrakten Wertes Paint (clr1, coord1, Paint (clr2, coord2, cnvs)) Paint (clr2, coord2, Paint (clr1, coord1, cnvs)) • Die Gleichheitsrelation für abstrakte Datenypen muss explizit implementiert werden 61 Abstrakte Datentypen Parametrisierung • type α board = Board of int x int x coordinate → α newboard: α → int → int → α board sizeboard: α board → (int x int) contentsboard: α board → coordinate → α updateboard: α board → coordinate → α → α board • 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 62 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 63 21 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 64 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 65 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 66 22 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 67 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 68 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 69 23 Ausführung von Programmen • Abarbeitung von Definitionen ¾Struktur struct ¾Funktor functor ¾Signatur sig ¾Typ type Definiert Umgebung Abstrakt abstype Konkret datatype ¾Wert val Funktion val fn / fun In aktueller Umgebung • Auswertung von Ausdrücken 70 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 71 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 72 24 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)) 73 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) 74 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 ← [... ] 75 25 Auswertungsstrategien Lazy Evaluation • Ablaufsmodellierung Sieve Konsument Master Sift Produzent Slave Coroutine Coroutine 76 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 77 Auswertungsstrategien Lazy Evaluation • Ablaufsmodellierung 1 :: hamming merge3 map times 2 map times 3 hamming map times 5 78 26 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 79 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 80 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 81 27 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 → α 82 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 83 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 84 28 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 ... 85 • 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 86 Logische Programmierung Situierung • Logische Deduktion mit Formeln erster Ordnung (Kowalski (1979) • Beweise werden via Resolution auf der Basis des Unifikationsalgorithmus automatisch erzeugt • Sprache Prolog 87 29 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). 88 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 = [] 89 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, []) 90 Antwort 30 Logische Programmierung Beispiel Stammbaum (1) t ht // p: man (adam). man (peter). Fakten man (paul). woman (marry). woman (eve). Werte parent (adam, peter). parent (eve, peter). parent (adam, paul). parent (marry, paul). kt m s. i.m .c ff i.c un ~ z/ / ak rt ba o ol pr g/ og al ne ge l m ht y. 91 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 92 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). 93 31 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). 94 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 95 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 96 32 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). 97 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 98 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). 99 33 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 */ 100 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 101 Logische Programmierung Deduktionsstrategie (3) • ?- p(X) X = a X = b X = d Depth-First Traversierung Unifikation 102 34 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 103 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) 104 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 105 35 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 106 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? 107 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 108 36 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)). 109 Logische Programmierung Zustandstransformation • Get Food getfood(state(_, _, _, has)). getfood(S1) :- perform(A, S1, S2), getfood(S2). • Query ?- getfood(state(atdoor, atwindow,onfloor, hasnot)). yes. 110 Logische Programmierung Zustandstransformation • Mit Trace Output getfood(S1) :perform(A, S1, S2), nl, write(‚in '), write(S1), nl, write(' try '), write(A), getfood(S2). 111 37 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 112 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) 113 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) 114 38 Beispiel 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('>> '), !. 115 Beispiel 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). 116 Beispiel Eliza Pattern Matching with Input & Output Creation Stimulus Response Dictionary Dictionary Input 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). 117 39 Beispiel Eliza Pattern Matching with Input & Output 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 118 Beispiel 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, _). 119 Beispiel 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 120 40 Deskriptive Programmierung 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> 121 </library> XML Namespaces • Explizite Namespaces Globally <LIBRARY> unique id <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> 122 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> 123 41 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 124 </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> 125 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> 126 42 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"/> 127 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"/> 128 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> 129 43 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> 130 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> 131 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 132 44 • <?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> 133 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> 134 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> 135 45 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 136 <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 137 <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) 138 46 <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] 139 <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'] 140 <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> 141 47 <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')] <AAA> <Q/> <SSSS/> <BB/> <CCC/> <DDDDDDDD/> <EEEE/> </AAA> 142 //*[string-length(name()) = 3] //*[string-length(name()) < 3] //*[string-length(name()) > 3] 143 <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 144 48 <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> 145 / ... :: 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 146 <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> 147 </AAA> <AAA> 49 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 148 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> 149 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> 150 50 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)"/> 151 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> 152 XSLT Output Steuerung ¾ Bedingung <xsl:for-each select="catalog/cd"> <xsl:if test="price&gt;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) &lt; &gt;153 51 XSLT ¾ Auswahl Output Steuerung <xsl:for-each select="catalog/cd"> <tr> <td><xsl:value-of select="title"/></td> <xsl:choose> <xsl:when test="price&gt;'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> 154 XSLT Output Steuerung ¾ Hinzufügen eines Attributes <img> <xsl:attribute name="src"> <xsl:value-of select="@src" /> </xsl:attribute> </img> 155 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> 156 52 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> 157 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> 158 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 159 53 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)"/> 160 </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> 161 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> 162 54 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> 163 XSLT Strukturschema (1) XML Internalize / A DOM B A Skript xxxx yy zzz XSLT ZL Templates Function Calls A API C Impl XSLT Strom Prozessor ZL 164 XSLT Strukturschema (2) Internalize ZL Template ZL Template DOM Impl XML / A B A A C API Impl XSLT Prozessor Strom ZL 165 55 ASP Server Architektur (1) request Internet Server C http Active Server Page .asp .htm ASP engine C 166 ASP Server Architektur (2) Provider A Webservice f My Webservice .asp .htm f g Internet ASP engine .net Provider B Webservice g class 167 ASP Server Code • Inline Server Code <html> <body bgcolor="yellow"> <center> <h2>Hello W3Schools!</h2> <p><%Response.Write(now())%></p> </center> </body> </html> 168 56 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> 169 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> 170 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> 171 57 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> 172 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 173 </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> 174 58 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> 175 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> 176 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 177 </script> 59 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> 178 ASP Fallstudie Picture Market zServicebeschreibung z z Kunde fordert Bild an Server liefert Zufallsbild zServicebestandteile z Aktive Serverseite PictureMart.aspx z „Businesslogic“ Modul z Kollektion von Bildern Auf Serverseite PictureMart.mod pict1.gif, ..., pictN.gif 179 Fallstudie Picture Market PictureMart.aspx (1) <html> <head> <add assembly = "PictureMart.dll"/> <script language = "C#" runat = "server" add assembly = "PictureMart.dll"> 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> 180 60 Fallstudie Picture Market PictureMart.aspx (2) <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> 181 Fallstudie Picture Market PictureMart.mod 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. 182 61