Eine Behauptung . . .
Schon bekannte Funktionen:
filter:: (a→Bool)→[a]→[a]
filterp [ ] = [ ]
filterp (a:as) | p a =a: (filterp as)
| otherwise=filterp as map:: (a→b)→[a]→[b]
maph [ ] = [ ]
maph (a:as) = (h a) : (maph as)
filterp (a:as) | p a =a: (filterp as)
| otherwise=filterp as map:: (a→b)→[a]→[b]
maph [ ] = [ ]
maph (a:as) = (h a) : (maph as) F¨ur jede Wahl vonp,h undl gilt:
filterp (maph l) =
Eine Behauptung . . .
Schon bekannte Funktionen:
filter:: (a→Bool)→[a]→[a]
filterp [ ] = [ ]
filterp (a:as) | p a =a: (filterp as)
| otherwise=filterp as map:: (a→b)→[a]→[b]
maph [ ] = [ ]
maph (a:as) = (h a) : (maph as) F¨ur jede Wahl vonp,h undl gilt:
filterp (maph l) = maph (filter(p◦h) l)
. . . und ihr Beweis
Per Induktion ¨uber die L¨ange der Liste:
1. filterp (maph [ ]) = maph (filter (p◦h) [ ]) ? OK
. . . und ihr Beweis
Per Induktion ¨uber die L¨ange der Liste:
1. filterp (maph [ ]) = maph (filter (p◦h) [ ]) ? OK 2. filterp (maph (a:as)) = maph(filter(p◦h) (a:as))?
filterp (maph (a:as))
filterp (maph (a:as))
= filterp ((h a) : (maph as))
. . . und ihr Beweis
Per Induktion ¨uber die L¨ange der Liste:
1. filterp (maph [ ]) = maph (filter (p◦h) [ ]) ? OK 2. filterp (maph (a:as)) = maph(filter(p◦h) (a:as))?
filterp (maph (a:as))
= filterp ((h a) : (maph as))
= if p (h a)then (h a) : (filterp (maph as)) else filterp (maph as)
filterp (maph (a:as))
= filterp ((h a) : (maph as))
= if p (h a)then (h a) : (filterp (maph as)) else filterp (maph as)
= if (p◦h) athen (h a) : (maph (filter(p◦h) as)) else maph (filter(p◦h) as)
. . . und ihr Beweis
Per Induktion ¨uber die L¨ange der Liste:
1. filterp (maph [ ]) = maph (filter (p◦h) [ ]) ? OK 2. filterp (maph (a:as)) = maph(filter(p◦h) (a:as))?
filterp (maph (a:as))
= filterp ((h a) : (maph as))
= if p (h a)then (h a) : (filterp (maph as)) else filterp (maph as)
= if (p◦h) athen (h a) : (maph (filter(p◦h) as)) else maph (filter(p◦h) as)
= if (p◦h) athen maph (a: (filter(p◦h)as)) else maph (filter(p◦h) as)
filterp (maph (a:as))
= filterp ((h a) : (maph as))
= if p (h a)then (h a) : (filterp (maph as)) else filterp (maph as)
= if (p◦h) athen (h a) : (maph (filter(p◦h) as)) else maph (filter(p◦h) as)
= if (p◦h) athen maph (a: (filter(p◦h)as)) else maph (filter(p◦h) as)
= maph (if (p◦h)a then a: (filter(p◦h)as) else filter(p◦h) as)
. . . und ihr Beweis
Per Induktion ¨uber die L¨ange der Liste:
1. filterp (maph [ ]) = maph (filter (p◦h) [ ]) ? OK 2. filterp (maph (a:as)) = maph(filter(p◦h) (a:as))?
filterp (maph (a:as))
= filterp ((h a) : (maph as))
= if p (h a)then (h a) : (filterp (maph as)) else filterp (maph as)
= if (p◦h) athen (h a) : (maph (filter(p◦h) as)) else maph (filter(p◦h) as)
= if (p◦h) athen maph (a: (filter(p◦h)as)) else maph (filter(p◦h) as)
= maph (if (p◦h)a then a: (filter(p◦h)as) else filter(p◦h) as)
= maph (filter(p◦h) (a:as))
filterp (maph (a:as))
= filterp ((h a) : (maph as))
= if p (h a)then (h a) : (filterp (maph as)) else filterp (maph as)
= if (p◦h) athen (h a) : (maph (filter(p◦h) as)) else maph (filter(p◦h) as)
= if (p◦h) athen maph (a: (filter(p◦h)as)) else maph (filter(p◦h) as)
= maph (if (p◦h)a then a: (filter(p◦h)as) else filter(p◦h) as)
= maph (filter(p◦h) (a:as))
Ein weiteres Beispiel
Angenommen, wir wollen (f¨ur gewisse h,f,k undl) h (foldrf k l)
durch einen einzelnen Aufruf von foldrersetzen.
h (foldrf k ( : x1 :
x2 X : xn [ ]
)) = h f x1 f
x2 X f xn k
Ein weiteres Beispiel
Angenommen, wir wollen (f¨ur gewisse h,f,k undl) h (foldrf k l)
durch einen einzelnen Aufruf von foldrersetzen.
h (foldrf k ( : x1 :
x2 X : xn [ ]
)) = h f x1 f
x2 X f xn k Angenommen, wir w¨ussten ein g, so dass f¨ur allex und y,
. . . , dann:
h (foldrf k l) = foldrg (h k)l Beweis per Induktion ¨uber die L¨ange der Liste:
1. h (foldrf k [ ]) = foldr g (h k) [ ] ?
Beweis per Induktion ¨uber die L¨ange der Liste:
1. h (foldrf k [ ]) = foldr g (h k) [ ] ? OK
. . . , dann:
h (foldrf k l) = foldrg (h k)l Beweis per Induktion ¨uber die L¨ange der Liste:
1. h (foldrf k [ ]) = foldr g (h k) [ ] ? OK 2. h (foldrf k (a:as)) = foldrg (h k) (a:as) ?
Beweis per Induktion ¨uber die L¨ange der Liste:
1. h (foldrf k [ ]) = foldr g (h k) [ ] ? OK 2. h (foldrf k (a:as)) = foldrg (h k) (a:as) ?
h (foldrf k (a:as))
. . . , dann:
h (foldrf k l) = foldrg (h k)l Beweis per Induktion ¨uber die L¨ange der Liste:
1. h (foldrf k [ ]) = foldr g (h k) [ ] ? OK 2. h (foldrf k (a:as)) = foldrg (h k) (a:as) ?
h (foldrf k (a:as))
= h (f a(foldrf k as))
Beweis per Induktion ¨uber die L¨ange der Liste:
1. h (foldrf k [ ]) = foldr g (h k) [ ] ? OK 2. h (foldrf k (a:as)) = foldrg (h k) (a:as) ?
h (foldrf k (a:as))
= h (f a(foldrf k as))
= g a (h (foldr f k as))
. . . , dann:
h (foldrf k l) = foldrg (h k)l Beweis per Induktion ¨uber die L¨ange der Liste:
1. h (foldrf k [ ]) = foldr g (h k) [ ] ? OK 2. h (foldrf k (a:as)) = foldrg (h k) (a:as) ?
h (foldrf k (a:as))
= h (f a(foldrf k as))
= g a (h (foldr f k as))
= g a (foldr g (h k) as)
Beweis per Induktion ¨uber die L¨ange der Liste:
1. h (foldrf k [ ]) = foldr g (h k) [ ] ? OK 2. h (foldrf k (a:as)) = foldrg (h k) (a:as) ?
h (foldrf k (a:as))
= h (f a(foldrf k as))
= g a (h (foldr f k as))
= g a (foldr g (h k) as)
= foldr g (h k) (a:as)
. . . , dann:
h (foldrf k l) = foldrg (h k)l Beweis per Induktion ¨uber die L¨ange der Liste:
1. h (foldrf k [ ]) = foldr g (h k) [ ] ? OK
2. h (foldrf k (a:as)) = foldrg (h k) (a:as) ? OK
Auf anderen Datentypen
Zum Beispiel:
dataTree a = Leaf a|Node (Tree a) (Treea) flat:: Tree a→[a]
flat(Leaf a) = [a]
flat(Nodet1 t2) = (flatt1)++(flatt2)
flat:: Tree a→[a]
flat(Leaf a) = [a]
flat(Nodet1 t2) = (flatt1)++(flatt2) incr:: Tree Int→Tree Int
incr(Leaf a) = Leaf (a+ 1)
incr(Nodet1 t2) = Node (incrt1) (incrt2)
Auf anderen Datentypen
Zum Beispiel:
dataTree a = Leaf a|Node (Tree a) (Treea) flat:: Tree a→[a]
flat(Leaf a) = [a]
flat(Nodet1 t2) = (flatt1)++(flatt2) incr:: Tree Int→Tree Int
incr(Leaf a) = Leaf (a+ 1)
incr(Nodet1 t2) = Node (incrt1) (incrt2) Behauptung:
flat(incrt) =
flat:: Tree a→[a]
flat(Leaf a) = [a]
flat(Nodet1 t2) = (flatt1)++(flatt2) incr:: Tree Int→Tree Int
incr(Leaf a) = Leaf (a+ 1)
incr(Nodet1 t2) = Node (incrt1) (incrt2) Behauptung:
flat(incrt) = map(+1) (flatt)
Auf anderen Datentypen
Beweis per struktureller Induktion:
1. flat(incr(Leaf a)) = map(+1) (flat(Leaf a))?
Auf anderen Datentypen
Beweis per struktureller Induktion:
1. flat(incr(Leaf a)) = map(+1) (flat(Leaf a))? OK
2. flat(incr(Node t1 t2)) = map(+1) (flat(Nodet1 t2))?
2. flat(incr(Node t1 t2)) = map(+1) (flat(Nodet1 t2))?
flat(incr(Node t1 t2))
Auf anderen Datentypen
Beweis per struktureller Induktion:
1. flat(incr(Leaf a)) = map(+1) (flat(Leaf a))? OK
2. flat(incr(Node t1 t2)) = map(+1) (flat(Nodet1 t2))?
flat(incr(Node t1 t2))
= flat(Node (incrt1) (incrt2))
2. flat(incr(Node t1 t2)) = map(+1) (flat(Nodet1 t2))?
flat(incr(Node t1 t2))
= flat(Node (incrt1) (incrt2))
= (flat(incrt1))++(flat(incrt2))
Auf anderen Datentypen
Beweis per struktureller Induktion:
1. flat(incr(Leaf a)) = map(+1) (flat(Leaf a))? OK
2. flat(incr(Node t1 t2)) = map(+1) (flat(Nodet1 t2))?
flat(incr(Node t1 t2))
= flat(Node (incrt1) (incrt2))
= (flat(incrt1))++(flat(incrt2))
= (map(+1) (flatt1))++(map(+1) (flatt2))
2. flat(incr(Node t1 t2)) = map(+1) (flat(Nodet1 t2))?
flat(incr(Node t1 t2))
= flat(Node (incrt1) (incrt2))
= (flat(incrt1))++(flat(incrt2))
= (map(+1) (flatt1))++(map(+1) (flatt2))
= map(+1) ((flatt1)++(flatt2))
Auf anderen Datentypen
Beweis per struktureller Induktion:
1. flat(incr(Leaf a)) = map(+1) (flat(Leaf a))? OK
2. flat(incr(Node t1 t2)) = map(+1) (flat(Nodet1 t2))?
flat(incr(Node t1 t2))
= flat(Node (incrt1) (incrt2))
= (flat(incrt1))++(flat(incrt2))
= (map(+1) (flatt1))++(map(+1) (flatt2))
= map(+1) ((flatt1)++(flatt2))
= map(+1) (flat(Node t1 t2))
2. flat(incr(Node t1 t2)) = map(+1) (flat(Nodet1 t2))? OK (mit Hilfe: (maph l1)++(maph l2) = maph (l1++l2))
Manchmal nicht so einfach
Naives Umdrehen einer Liste:
reverse:: [a]→[a]
reverse[ ] = [ ]
reverse(a:as) = (reverse as)++[a]
reverse(a:as) = (reverse as)++[a]
Zu beweisen:
maph (reverse l) = reverse(map h l)
Manchmal nicht so einfach
Naives Umdrehen einer Liste:
reverse:: [a]→[a]
reverse[ ] = [ ]
reverse(a:as) = (reverse as)++[a]
Zu beweisen:
maph (reverse l) = reverse(map h l) Induktionsschritt:
2. map h (reverse (a:as)) = reverse(map h (a:as))?
reverse(a:as) = (reverse as)++[a]
Zu beweisen:
maph (reverse l) = reverse(map h l) Induktionsschritt:
2. map h (reverse (a:as)) = reverse(map h (a:as))? maph (reverse (a:as))
Manchmal nicht so einfach
Naives Umdrehen einer Liste:
reverse:: [a]→[a]
reverse[ ] = [ ]
reverse(a:as) = (reverse as)++[a]
Zu beweisen:
maph (reverse l) = reverse(map h l) Induktionsschritt:
2. map h (reverse (a:as)) = reverse(map h (a:as))? maph (reverse (a:as))
= maph ((reverseas)++[a])
reverse(a:as) = (reverse as)++[a]
Zu beweisen:
maph (reverse l) = reverse(map h l) Induktionsschritt:
2. map h (reverse (a:as)) = reverse(map h (a:as))? maph (reverse (a:as))
= maph ((reverseas)++[a])
= (maph (reverseas))++(maph [a])
Manchmal nicht so einfach
Naives Umdrehen einer Liste:
reverse:: [a]→[a]
reverse[ ] = [ ]
reverse(a:as) = (reverse as)++[a]
Zu beweisen:
maph (reverse l) = reverse(map h l) Induktionsschritt:
2. map h (reverse (a:as)) = reverse(map h (a:as))? maph (reverse (a:as))
= maph ((reverseas)++[a])
= (maph (reverseas))++(maph [a])
= (reverse (maph as))++[h a]
reverse(a:as) = (reverse as)++[a]
Zu beweisen:
maph (reverse l) = reverse(map h l) Induktionsschritt:
2. map h (reverse (a:as)) = reverse(map h (a:as))? maph (reverse (a:as))
= maph ((reverseas)++[a])
= (maph (reverseas))++(maph [a])
= (reverse (maph as))++[h a]
Manchmal nicht so einfach
Naives Umdrehen einer Liste:
reverse:: [a]→[a]
reverse[ ] = [ ]
reverse(a:as) = (reverse as)++[a]
Zu beweisen:
maph (reverse l) = reverse(map h l) Induktionsschritt:
2. map h (reverse (a:as)) = reverse(map h (a:as))? maph (reverse (a:as))
= maph ((reverseas)++[a])
= (maph (reverseas))++(maph [a])
= (reverse (maph as))++[h a]
reverse(a:as) = (reverse as)++[a]
Zu beweisen:
maph (reverse l) = reverse(map h l) Induktionsschritt:
2. map h (reverse (a:as)) = reverse(map h (a:as))? OK
Manchmal nicht so einfach
Effizientes Umdrehen einer Liste:
reverse′ :: [a]→[a]→[a]
reverse′ [ ] bs=bs
reverse′ (a:as) bs=reverse′ as (a:bs)
reverse (a:as) bs=reverse as (a:bs) Zu beweisen:
maph (reverse′ l [ ]) = reverse′ (map h l) [ ]
Manchmal nicht so einfach
Effizientes Umdrehen einer Liste:
reverse′ :: [a]→[a]→[a]
reverse′ [ ] bs=bs
reverse′ (a:as) bs=reverse′ as (a:bs) Zu beweisen:
maph (reverse′ l [ ]) = reverse′ (map h l) [ ] Induktionsschritt:
2. maph (reverse′(a:as) [ ]) = reverse′ (maph (a:as)) [ ]?
reverse (a:as) bs=reverse as (a:bs) Zu beweisen:
maph (reverse′ l [ ]) = reverse′ (map h l) [ ] Induktionsschritt:
2. maph (reverse′(a:as) [ ]) = reverse′ (maph (a:as)) [ ]? maph (reverse′ (a:as) [ ])
Manchmal nicht so einfach
Effizientes Umdrehen einer Liste:
reverse′ :: [a]→[a]→[a]
reverse′ [ ] bs=bs
reverse′ (a:as) bs=reverse′ as (a:bs) Zu beweisen:
maph (reverse′ l [ ]) = reverse′ (map h l) [ ] Induktionsschritt:
2. maph (reverse′(a:as) [ ]) = reverse′ (maph (a:as)) [ ]? maph (reverse′ (a:as) [ ])
= maph (reverse′ as [a])
reverse (a:as) bs=reverse as (a:bs) Zu beweisen:
maph (reverse′ l [ ]) = reverse′ (map h l) [ ] Induktionsschritt:
2. maph (reverse′(a:as) [ ]) = reverse′ (maph (a:as)) [ ]? maph (reverse′ (a:as) [ ])
= maph (reverse′ as [a])
?
Manchmal nicht so einfach
Effizientes Umdrehen einer Liste:
reverse′ :: [a]→[a]→[a]
reverse′ [ ] bs=bs
reverse′ (a:as) bs=reverse′ as (a:bs) Zu beweisen:
maph (reverse′ l [ ]) = reverse′ (map h l) [ ] Induktionsschritt:
2. maph (reverse′(a:as) [ ]) = reverse′ (maph (a:as)) [ ]? maph (reverse′ (a:as) [ ])
= maph (reverse′ as [a])
?
reverse (a:as) bs=reverse as (a:bs) Zu beweisen:
maph (reverse′ l [ ]) = reverse′ (map h l) [ ] Induktionsschritt:
2. maph (reverse′(a:as) [ ]) = reverse′ (maph (a:as)) [ ]? maph (reverse′ (a:as) [ ])
= maph (reverse′ as [a])
?
Manchmal nicht so einfach
Effizientes Umdrehen einer Liste:
reverse′ :: [a]→[a]→[a]
reverse′ [ ] bs=bs
reverse′ (a:as) bs=reverse′ as (a:bs) Zu beweisen:
maph (reverse′ l [ ]) = reverse′ (map h l) [ ] Induktionsschritt:
2. maph (reverse′(a:as) [ ]) = reverse′ (maph (a:as)) [ ]? maph (reverse′ (a:as) [ ])
= maph (reverse′ as [a])
?
reverse′ (maph as) [h a]
reverse (a:as) bs=reverse as (a:bs) Zu beweisen:
maph (reverse′ l [ ]) = reverse′ (map h l) [ ] Induktionsschritt:
2. maph (reverse′(a:as) [ ]) = reverse′ (maph (a:as)) [ ]? maph (reverse′ (a:as) [ ])
= maph (reverse′ as [a])
?
= reverse′ (maph as) [h a]
Freie Theoreme [Wadler, 1989]
Urspr¨ungliches Beispiel:
filter:: (a→Bool)→[a]→[a]
filterp [ ] = [ ]
filterp (a:as) | p a =a: (filterp as)
| otherwise=filterp as F¨ur jede Wahl vonp,h undl gilt:
filterp (map h l) = map h (filter(p◦h) l) Bewiesen per Induktion.
filterp (a:as) | p a =a: (filterp as)
| otherwise=filterp as F¨ur jede Wahl vonp,h undl gilt:
filterp (map h l) = map h (filter(p◦h) l) Bewiesen per Induktion.
Aber auch m¨oglich ohneInduktion!
Freie Theoreme [Wadler, 1989]
Urspr¨ungliches Beispiel:
filter::(a→Bool)→[a]→[a]
F¨ur jede Wahl vonp,h undl gilt:
filterp (map h l) = map h (filter(p◦h) l) Bewiesen per Induktion.
Aber auch m¨oglich ohneInduktion!
takeWhile::(a→Bool)→[a]→[a]
F¨ur jede Wahl vonp,h undl gilt:
filterp (map h l) = map h (filter(p◦h) l) takeWhilep (map h l) = map h (takeWhile(p◦h)l)
Freie Theoreme [Wadler, 1989]
Urspr¨ungliches Beispiel:
filter::(a→Bool)→[a]→[a]
takeWhile::(a→Bool)→[a]→[a]
g::(a→Bool)→[a]→[a]
F¨ur jede Wahl vonp,h undl gilt:
filterp (map h l) = map h (filter(p◦h) l) takeWhilep (map h l) = map h (takeWhile(p◦h)l)
gp (map h l) = map h (g(p◦h) l)
takeWhile::(a→Bool)→[a]→[a]
g::(a→Bool)→[a]→[a]
F¨ur jede Wahl vonp,h undl gilt:
filterp (map h l) = map h (filter(p◦h) l) takeWhilep (map h l) = map h (takeWhile(p◦h)l)
gp (map h l) = map h (g(p◦h) l) Aber wie soll man so etwas beweisen k¨onnen?
Versuch einer Argumentation
• g:: (a→Bool)→[a]→[a] muss f¨ur jede m¨ogliche Instanziierung von aeinheitlich arbeiten.
Versuch einer Argumentation
• g:: (a→Bool)→[a]→[a] muss f¨ur jede m¨ogliche Instanziierung von aeinheitlich arbeiten.
• Die Ausgabeliste kann nur Elemente der Eingabe l enthalten.
• Welche, und in welcher Reihenfolge/Vielfachheit, kann lediglich von l und dem Eingabepr¨adikatp abh¨angen.
• Welche, und in welcher Reihenfolge/Vielfachheit, kann lediglich von l und dem Eingabepr¨adikatp abh¨angen.
• Die einzig m¨oglichen Grundlagen zur Entscheidung sind die L¨ange von l und dieErgebnisse vonp auf Elementen vonl.
Versuch einer Argumentation
• g:: (a→Bool)→[a]→[a] muss f¨ur jede m¨ogliche Instanziierung von aeinheitlich arbeiten.
• Die Ausgabeliste kann nur Elemente der Eingabe l enthalten.
• Welche, und in welcher Reihenfolge/Vielfachheit, kann lediglich von l und dem Eingabepr¨adikatp abh¨angen.
• Die einzig m¨oglichen Grundlagen zur Entscheidung sind die L¨ange von l und die Ergebnisse vonp auf Elementen vonl.
• Aber, die Listen (map h l) undl haben stetsdie selbe L¨ange.
• Welche, und in welcher Reihenfolge/Vielfachheit, kann lediglich von l und dem Eingabepr¨adikatp abh¨angen.
• Die einzig m¨oglichen Grundlagen zur Entscheidung sind die L¨ange von l und dieErgebnisse vonp auf Elementen vonl.
• Aber, die Listen (map h l) undl haben stets die selbe L¨ange.
• Und Anwendung vonp auf ein Element von (maph l) hat stetsdas selbe Ergebnis wie Anwendung von (p◦h) auf das entsprechende Element vonl.
Versuch einer Argumentation
• g:: (a→Bool)→[a]→[a] muss f¨ur jede m¨ogliche Instanziierung von aeinheitlich arbeiten.
• Die Ausgabeliste kann nur Elemente der Eingabe l enthalten.
• Welche, und in welcher Reihenfolge/Vielfachheit, kann lediglich von l und dem Eingabepr¨adikatp abh¨angen.
• Die einzig m¨oglichen Grundlagen zur Entscheidung sind die L¨ange von l und die Ergebnisse vonp auf Elementen vonl.
• Aber, die Listen (map h l) undl haben stets die selbe L¨ange.
• Und Anwendung vonp auf ein Element von (maph l) hat stets das selbe Ergebnis wie Anwendung von (p◦h) auf das entsprechende Element vonl.
• Also w¨ahlt gmitp stets
”die selben“ Elemente aus (maph l) wie es gmit (p◦h) aus l tut,
• Welche, und in welcher Reihenfolge/Vielfachheit, kann lediglich von l und dem Eingabepr¨adikatp abh¨angen.
• Die einzig m¨oglichen Grundlagen zur Entscheidung sind die L¨ange von l und die Ergebnisse vonp auf Elementen vonl.
• Aber, die Listen (map h l) undl haben stets die selbe L¨ange.
• Und Anwendung vonp auf ein Element von (maph l) hat stets das selbe Ergebnis wie Anwendung von (p◦h) auf das entsprechende Element vonl.
• Also w¨ahlt gmitp stets
”die selben“ Elemente aus (maph l) wie es gmit (p◦h) aus l tut,außer dass im ersten Fall die entsprechenden Abbilder unter h ausgegeben werden.
Versuch einer Argumentation
• g:: (a→Bool)→[a]→[a] muss f¨ur jede m¨ogliche Instanziierung von aeinheitlich arbeiten.
• Die Ausgabeliste kann nur Elemente der Eingabe l enthalten.
• Welche, und in welcher Reihenfolge/Vielfachheit, kann lediglich von l und dem Eingabepr¨adikatp abh¨angen.
• Die einzig m¨oglichen Grundlagen zur Entscheidung sind die L¨ange von l und die Ergebnisse vonp auf Elementen vonl.
• Aber, die Listen (map h l) undl haben stets die selbe L¨ange.
• Und Anwendung vonp auf ein Element von (maph l) hat stets das selbe Ergebnis wie Anwendung von (p◦h) auf das entsprechende Element vonl.
• Also w¨ahlt gmitp stets
”die selben“ Elemente aus (maph l) wie es gmit (p◦h) aus l tut, außer dass im ersten Fall die entsprechenden Abbilder unter h ausgegeben werden.
• Also ist (g (map )) gleich (map (g(p◦h) )).
• Welche, und in welcher Reihenfolge/Vielfachheit, kann lediglich von l und dem Eingabepr¨adikatp abh¨angen.
• Die einzig m¨oglichen Grundlagen zur Entscheidung sind die L¨ange von l und die Ergebnisse vonp auf Elementen vonl.
• Aber, die Listen (map h l) undl haben stets die selbe L¨ange.
• Und Anwendung vonp auf ein Element von (maph l) hat stets das selbe Ergebnis wie Anwendung von (p◦h) auf das entsprechende Element vonl.
• Also w¨ahlt gmitp stets
”die selben“ Elemente aus (maph l) wie es gmit (p◦h) aus l tut, außer dass im ersten Fall die entsprechenden Abbilder unter h ausgegeben werden.
• Also ist (g (map )) gleich (map (g(p◦h) )).
Geht es vielleicht etwas formaler?
Gegeben:
g:: (a→Bool)→[a]→[a]
Behauptung, f¨ur jede Wahl von p,h und l:
gp (maph l) = maph (g(p◦h)l)
gp (maph l) = maph (g(p◦h)l)
Wie w¨are es mit Induktion ¨uber den Syntaxaufbau von g?
Geht es vielleicht etwas formaler?
Gegeben:
g:: (a→Bool)→[a]→[a]
Behauptung, f¨ur jede Wahl von p,h und l:
gp (maph l) = maph (g(p◦h)l)
Wie w¨are es mit Induktion ¨uber den Syntaxaufbau von g?
Problem: l¨asst Typinformation außer Acht
gp (maph l) = maph (g(p◦h)l)
Wie w¨are es mit Induktion ¨uber den Syntaxaufbau von g?
Problem: l¨asst Typinformation außer Acht
Wie w¨are es dann mit Induktion nur ¨uber alle Funktionen des Typs (a→Bool)→[a]→[a]?
Geht es vielleicht etwas formaler?
Gegeben:
g:: (a→Bool)→[a]→[a]
Behauptung, f¨ur jede Wahl von p,h und l:
gp (maph l) = maph (g(p◦h)l)
Wie w¨are es mit Induktion ¨uber den Syntaxaufbau von g?
Problem: l¨asst Typinformation außer Acht
Wie w¨are es dann mit Induktion nur ¨uber alle Funktionen des Typs (a→Bool)→[a]→[a]?
Problem: dieser Bereich nicht kompositionell
gp (maph l) = maph (g(p◦h)l)
Wie w¨are es mit Induktion ¨uber den Syntaxaufbau von g?
Problem: l¨asst Typinformation außer Acht
Wie w¨are es dann mit Induktion nur ¨uber alle Funktionen des Typs (a→Bool)→[a]→[a]?
Problem: dieser Bereich nicht kompositionell
Wir m¨ussen also allgemein Aussagen der obigen Art f¨ur alle Typen gleichzeitig“ beweisen!
Geht es vielleicht etwas formaler?
Strategie:
• zu jedem Typ angeben, welche m¨oglichen Varianten (semantisch, nicht syntaktisch) von Elementen diesen Typs es gibt
(semantisch, nicht syntaktisch) von Elementen diesen Typs es gibt
• das Ganze m¨oglichst kompositionell ¨uber den Aufbau von Typen
Geht es vielleicht etwas formaler?
Strategie:
• zu jedem Typ angeben, welche m¨oglichen Varianten (semantisch, nicht syntaktisch) von Elementen diesen Typs es gibt
• das Ganze m¨oglichst kompositionell ¨uber den Aufbau von Typen
• sp¨ater per Induktion ¨uber die Syntax beweisen, dass jede Funktion die semantischen Einschr¨ankungen ihres Typs erf¨ullt
(semantisch, nicht syntaktisch) von Elementen diesen Typs es gibt
• das Ganze m¨oglichst kompositionell ¨uber den Aufbau von Typen
• sp¨ater per Induktion ¨uber die Syntax beweisen, dass jede Funktion die semantischen Einschr¨ankungen ihres Typs erf¨ullt
Erster Punkt an Beispielen
Frage: Welche Funktionen haben den Typ
”(a,a)→a“ ?
Erster Punkt an Beispielen
Frage: Welche Funktionen haben den Typ
”(a,a)→a“ ? Antwort: nur fstund snd(und semantisch ¨aquivalente)
Frage: Welche Funktionen haben den Typ
”a→a“ ?
Erster Punkt an Beispielen
Frage: Welche Funktionen haben den Typ
”(a,a)→a“ ? Antwort: nur fstund snd(und semantisch ¨aquivalente)
Frage: Welche Funktionen haben den Typ
”a→a“ ? Antwort: nur id
Frage: Welche Funktionen haben den Typ
”a→a“ ? Antwort: nur id
Frage: Welche Funktionen haben den Typ
”a→[a]“ ?
Erster Punkt an Beispielen
Frage: Welche Funktionen haben den Typ
”(a,a)→a“ ? Antwort: nur fstund snd(und semantisch ¨aquivalente)
Frage: Welche Funktionen haben den Typ
”a→a“ ? Antwort: nur id
Frage: Welche Funktionen haben den Typ
”a→[a]“ ? Antwort: f0,f1,f2, . . . , wobei:
f0 = [ ]
Frage: Welche Funktionen haben den Typ
”a→a“ ? Antwort: nur id
Frage: Welche Funktionen haben den Typ
”a→[a]“ ? Antwort: f0,f1,f2, . . . , wobei:
f0 = [ ] f1 a = [a]
Erster Punkt an Beispielen
Frage: Welche Funktionen haben den Typ
”(a,a)→a“ ? Antwort: nur fstund snd(und semantisch ¨aquivalente)
Frage: Welche Funktionen haben den Typ
”a→a“ ? Antwort: nur id
Frage: Welche Funktionen haben den Typ
”a→[a]“ ? Antwort: f0,f1,f2, . . . , wobei:
f0 = [ ] f1 a = [a]
f2 a = [a,a]
. . .
Frage: Welche Funktionen haben den Typ
”a→a“ ? Antwort: nur id
Frage: Welche Funktionen haben den Typ
”a→[a]“ ? Antwort: f0,f1,f2, . . . , wobei:
f0 = [ ] f1 a = [a]
f2 a = [a,a]
. . .
Welche M¨oglichkeiten gibt es f¨ur g :: [ a ] → [ a ] ?
Zun¨achst wieder intuitiv:
Welche M¨oglichkeiten gibt es f¨ur g :: [ a ] → [ a ] ?
Zun¨achst wieder intuitiv:
• Die Ausgabe- kann nurElemente der Eingabelisteenthalten.
• Welche, und in welcher Reihenfolge/Vielfachheit, kann lediglich von dieser Liste abh¨angen
• Welche, und in welcher Reihenfolge/Vielfachheit, kann
lediglich von dieser Liste abh¨angen, und zwar von ihrer L¨ange.
Welche M¨oglichkeiten gibt es f¨ur g :: [ a ] → [ a ] ?
Zun¨achst wieder intuitiv:
• Die Ausgabe- kann nur Elemente der Eingabeliste enthalten.
• Welche, und in welcher Reihenfolge/Vielfachheit, kann
lediglich von dieser Liste abh¨angen, und zwar von ihrer L¨ange.
• Folglich sind f¨ur eine feste Eingabel¨ange die L¨ange der
Ausgabeliste sowie die Anordnung der Elemente darin stets fix.
• Welche, und in welcher Reihenfolge/Vielfachheit, kann
lediglich von dieser Liste abh¨angen, und zwar von ihrer L¨ange.
• Folglich sind f¨ur eine feste Eingabel¨ange die L¨ange der
Ausgabeliste sowie die Anordnung der Elemente darin stets fix.
Formal beschrieben:
F¨ur jedes g:: [a]→[a] gibt es:
Welche M¨oglichkeiten gibt es f¨ur g :: [ a ] → [ a ] ?
Zun¨achst wieder intuitiv:
• Die Ausgabe- kann nur Elemente der Eingabeliste enthalten.
• Welche, und in welcher Reihenfolge/Vielfachheit, kann
lediglich von dieser Liste abh¨angen, und zwar von ihrer L¨ange.
• Folglich sind f¨ur eine feste Eingabel¨ange die L¨ange der
Ausgabelistesowie die Anordnung der Elemente darin stets fix.
Formal beschrieben:
F¨ur jedes g:: [a]→[a] gibt es:
• eine Funktionf :N→N, so dass f¨ur jedesn ∈Naus einer Liste der L¨ange n mitgstets eine Liste der L¨angef(n) wird;
• Welche, und in welcher Reihenfolge/Vielfachheit, kann
lediglich von dieser Liste abh¨angen, und zwar von ihrer L¨ange.
• Folglich sind f¨ur eine feste Eingabel¨ange die L¨ange der
Ausgabeliste sowie dieAnordnung der Elemente darinstets fix.
Formal beschrieben:
F¨ur jedes g:: [a]→[a] gibt es:
• eine Funktionf :N→N, so dass f¨ur jedesn ∈Naus einer Liste der L¨ange n mitgstets eine Liste der L¨angef(n) wird;
• eine Funktionh :N×N→N, so dass f¨ur jede Liste einer L¨angen ∈Nund f¨ur jedes 0≤m<f(n), das m-te Element der Ausgabeliste das h(n,m)-te Element der Eingabeliste ist.
Welche M¨oglichkeiten gibt es f¨ur g :: [ a ] → [ a ] ?
Zun¨achst wieder intuitiv:
• Die Ausgabe- kann nur Elemente der Eingabeliste enthalten.
• Welche, und in welcher Reihenfolge/Vielfachheit, kann
lediglich von dieser Liste abh¨angen, und zwar von ihrer L¨ange.
• Folglich sind f¨ur eine feste Eingabel¨ange die L¨ange der
Ausgabeliste sowie die Anordnung der Elemente darin stets fix.
Formal beschrieben:
F¨ur jedes g:: [a]→[a] gibt es:
• eine Funktionf :N→N, so dass f¨ur jedesn ∈Naus einer Liste der L¨ange n mitgstets eine Liste der L¨angef(n) wird;
• eine Funktionh :N×N→N, so dass f¨ur jede Liste einer L¨angen ∈Nund f¨ur jedes 0≤m<f(n), das m-te Element der Ausgabeliste das h(n,m)-te Element der Eingabeliste ist.
(semantisch, nicht syntaktisch) von Elementen diesen Typs es gibt
• das Ganze m¨oglichst kompositionell ¨uber den Aufbau von Typen
• sp¨ater per Induktion ¨uber die Syntax beweisen, dass jede Funktion die semantischen Einschr¨ankungen ihres Typs erf¨ullt