Anreicherung: Vorgehen

Werbung
Anreicherung: Vorgehen
• Neue Axiome hinzuzunehmen macht eine Spezifikation sehr schnell
inkonsistent (siehe Versuch 3!)
⇒ Gewünscht: Nur „konsistenzerhaltende“ Anreicherungen
• Formaler Begriff: Konsistenzerhaltend = Hierarchiepersistent
• Neue Operationen sollten „monomorphieerhaltend“ sein: Wenn genau
ein Datentyp spezifiziert, sollte die Operation ebenfalls eindeutig
festgelegt sein
• Formaler Begriff: Monomorphieerhaltend = Eindeutig
Vorgehen: Anreicherung nur durch rekursive und nichtrekursive
Definitionen für neue Operationen. Diese sind hierarchiepersistent und
eindeutig.
138
Nichtrekursive Definitionen (Motivation)
• Grundidee: Definition als Abkürzung einer grossen Formel
• Prädikat: p(x) ↔ ϕ (p kommt in Formel ϕ nicht vor)
• Funktion: f (x) = t (f kommt im Term t nicht vor)
139
Beispiel: Anreicherung um nichtrek. Prädikat
NatDiv =
enrich Nat with
predicates | : nat × nat;
axioms
m | n ↔ ∃ k. k * m = n;
end enrich
Die Anreicherung NatDiv ist hierarchiepersistent und eindeutig.
140
Beispiel: Anr. um nichtrek. Prädikat (mit FU)
NatPrime =
enrich NatDiv with
predicates prime : nat;
axioms
¬ prime(0);
¬ prime(1);
n ≥ 2 → (prime(n) ↔ ∀ m. m | n → m = 1 ∨ m = n);
end enrich
Die Anreicherung NatPrime ist hierarchiepersistent und eindeutig
(FU nach n = 0, n = 1, n ≥ 2 ist vollständig).
141
Beispiel: Anreicherung um nichtrek. Konstante
Nat12 =
enrich Nat with
constants 1 : nat; 2 : nat;
axioms
1 = 0 +1;
2 = 0 +1 +1;
end enrich
Die Anreicherung Nat12 ist hierarchiepersistent und eindeutig
(beachte: In KIV sind die Zahlen schon vordefiniert).
142
Weitere Beispiele
für nichtrekursive Definitionen
m ≤ n ↔ ∃ k. m + k = n
m < n ↔ m ≤ n ∧ m 6= n
m>n↔n<m
even(n) ↔ ∃ m. n = m + m
odd(n) ↔ ¬ even(n)
m < n → min(m, n) = m, ¬ m < n → min(m, n) = n
x ≥ 0 → abs(x) = x, x < 0 → abs(x) = −x
last(l + (a + [])) = a (: unvollst. Def :)
a ∈ l ↔ ∃ l′ , l′′ . l′ + a + l′′ = l
isprefix(l, l′ ) ↔ ∃ l′′ . l + l′′ = l′
nodups(l) ↔ ¬ ∃ l1 , l2 , l3 , a. l = l1 + a + l2 + a + l3
143
Nichtrekursive Definitionen allgemein
• Prädikat: p(x) ↔ ϕ (p kommt in Formel ϕ nicht vor)
• Funktion: f (x) = t (f kommt im Term t nicht vor)
• Prädikat mit 2 vollständigen Fällen:
ε → (q(x, y) ↔ ϕ1 ),
¬ ε → (q(x, y) ↔ ϕ2 )
• Funktionen mit 3 unvollständigen Fällen:
ε ∧ δ → f (x, y) = t1 ,
ε ∧ ¬ δ → f (x, y) = t2 ,
¬ ε ∧ δ → f (x, y) = t3
Satz: Die Hinzunahme einer neuen Operation (Funktion oder Prädikat)
mit nichtrekursiver Definition ist immer hierarchiepersistent. Wenn die Fälle
vollständig sind, ist die Erweiterung sogar eindeutig.
144
Rekursive Definitionen (Motivation)
• Datentypen bestehen aus (der Semantik von) Konstruktortermen
• Rekursive Definitionen geben Definition durch Reduktion auf kleinere
Konstruktorterme
• Entsprechen einem rekursiven Programm, das den Term abläuft
Length =
enrich List with
functions length : list → nat;
axioms
length([]) = 0;
length(a + l) = length(l) +1;
end enrich
Satz: Die Hinzunahme einer neuen Operation mit rekursiver Definition zu
einem freien Datentyp ist immer hierarchiepersistent. Wenn die Fälle
vollständig sind, ist die Erweiterung immer eindeutig.
145
Beispiel: Anreicherung um rek. Definition
Append =
enrich List with
functions . + . : list × list → list;
axioms
[] + l = l;
(a + l) + l’ = a + (l + l’);
end enrich
Append ist hierarchiepersistent und eindeutig
(+ ist überladen: Sowohl Element vor Liste hängen (rot und schwarz),
als auch 2 Listen zusammenhängen (blau)).
146
Beispiel: Anreicherung um rek. Prädikat (FU)
Sorted =
enrich List with
predicates sorted : list
axioms
ordered([]),
ordered(a + []),
ordered(a + b + l) ↔ a < b ∧ ordered(b + l)
end enrich
Ordered ist hierarchiepersistent und eindeutig, da die FU vollständig ist
(jede Liste ist entweder = [], a + [], a + b + l).
147
Strukturierte Spezifikationen:
Umbenennung und Parameter
148
Strukturierte Spezifikationen:
Umbenennung
Umbenennung:
• Benennt die Operationen einer Spezifikation um
• Nützlich um 2 Kopien zu erhalten
• Syntax: rename <SPEC> by morphism
<renaming1>;
...
<renamingn>;
end rename
• renaming = <sort/op/var> → <sort/op/var>;
• Identische Umbenennungen weglassen
(werden beim Ansehen der Spezifikation aber angezeigt)
• Nicht 2 Symbole auf dasselbe abbilden: Injektiv umbenennen
• Entweder alle Variablen oder keine umbenennen
149
Beispiel Umbenennung:
Listen zu Stacks
List by morphism
list → stack;
[] → empty;
(: Typangabe für überladenes Symbol :)
+ :: (elem × list → list) → push;
(: pop nicht mehr postfix, Schreibweise stattdessen pop(x),
default ist in/prae/postfix uebernehmen :)
.rest → pop prio 0;
(: top soll nun praefix sein :)
.first → top .;
(: eigentlich keine Stack-Operation,
nur um Overloading zu zeigen :)
+ :: (list × list → list) → concat prio 0;
x → st;
y → st0;
z → st1;
rename
end rename
150
Strukturierte Spezifikationen:
Generische Spezifikation
Generische Spezifikation:
• Syntax: generic specification
parameter <SPEC>
using <SPEC1>, ..., <SPECn>
target
<signature>
<induction>
<axioms>
end generic specification
• Wie Anreicherung (von <SPEC>, <SPEC1>, ..., <SPECn>), nur
wird von <SPEC> explizit gesagt, dass es sich um einen Parameter
handelt
• Vereinigung und Anreicherung übernimmt den (oder die) Parameter der
Unterspezifikationen
• Variante: generic data specification: Wie data specification nur mit
151
Parameter
Strukturierte Spezifikationen:
Aktualisierung (1)
Aktualisierung:
• Instanziert Parameter (oder einen Parameter) einer Spezifikation
• Beispiel: Listen beliebiger Elemente → Listen von Zahlen
• Syntax: actualize <SPEC> with <ASPEC1>,...,<ASPECn> by morphism
<renaming1>;
...
<renamingn>;
end actualize
• renaming = <sort/op/var> → <sort/op/var>;
• Die Vereinigung von <ASPEC1>,...,<ASPECn> heisst aktuelle
Spezifikation
• Identische Umbenennungen weglassen
• Entweder alle Variablen oder keine umbenennen
152
Strukturierte Spezifikationen:
Aktualisierung (2)
Aktualisierung:
• Der Parameter muss in die aktuelle Spez. abgebildet werden
• Abbildung darf nicht-injektiv sein: pair(elem1 , elem2 ) → pair(nat , nat )
• Der Nicht-Parameter-Teil darf nur injektiv und disjunkt zur aktuellen
Spezifikation umbenannt werden, z. B. list → natlist
• Die instanzierten Axiome des Parameters müssen Axiome in der
aktuellen Spezifikation sein
• Verallgemeinerung instantiated specification:
⋆ Axiome werden bewiesen
⋆ mapping statt morphism erlaubt es, eine Sorte auf ein Tupel von
Sorten abzubilden
153
Aktualisierung: Beispiel (1)
Order =
specification
sorts elem;
constants d : elem;
predicates ≪ : elem × elem;
variables a, b, c : elem;
axioms
¬ a ≪ a; a ≪ b ∧ b ≪ c → a ≪ c;
¬ a ≪ d; (: d ist minimal :)
end specification
List-Ord =
generic data specification
parameter Order
using Nat
list = [] | . + . (. .first : elem; . .rest : list);
size functions length : list → nat;
end generic data specification
154
Aktualisierung: Beispiel (2)
NatList =
List-Ord with Nat by morphism
list → natlist;
elem → nat;
≪ → <;
d → 0;
a → n; b → n0; c → n1;
actualize
end actualize
Die instanzierten Axiome (u. a. ¬ n < 0) sind (modulo Umbenennung) in Nat
vorhanden.
Die Listenoperationen (+, .rest etc.) werden nicht umbenannt (sie
bekommen nur die neuen Sorten als Argumente).
155
Strukturierte Spezifikation:
Nichtfreie Datentypen
156
Nichtfreie Datentypen: Der typische Fehler
Orderedlist =
enrich List3 with
predicates
.<.
: elem × elem ;
ordered : list
;
axioms
¬ a < a; a < b ∨ a = b ∨ b < a;
a < b ∧ b < c → a < c;
ordered([]); ordered(a + []);
ordered(a + b + l) ↔ a < b ∧ ordered (b + l);
end enrich
NICHT
∀ l. ordered(l) addieren!!! Das wäre INKONSISTENT!!!
Allgemein: Ein generierter Datentyp enthält immer alle Konstruktorterme.
Man kann nicht nachträglich welche ausschliessen. Man kann nur einen
nichtfreien Datentyp bilden, der Terme identifiziert
157
Spezifikation nichtfreier Datentypen
• Spezifikationen nichtfreier Datentypen werden sehr leicht inkonsistent
oder uneindeutig
• Konstruiere nichtfreien Datentyp dadurch, daß alle Terme, die die
gleichen Elemente repräsentieren sollen, in einer Klasse
zusammengefaßt werden
• Deshalb als erstes nach der Bestimmung der Konstruktoren:
Definiere Gleichheit durch Extensionalitätsaxiom: x = y ↔ ϕ(x, y)
• Dann: Die in ϕ benutzten Operationen werden rekursiv definiert
• Damit: Monomorph: Höchstens ein Datentyp spezifiziert
• Vorsicht: Rek. Def. kann inkonsistent sein!
• Jetzt: Arrays, im Praktikum: Mengen (einfacher)
158
Beispiel: Arrayspezifikation, Teil 1
Array=
specification
using Nat; Elem;
sorts array;
functions
mkar
.[.]
.[.]
#.
:
:
:
:
nat × elem
array × nat × elem
array × nat
array
→
→
→
→
array;
array;
elem;
nat;
induction
array generated by mkar, [];
variables d : elem; a, a’ : array;
159
Beispiel: Arrayspezifikation, Teil 2
Festlegungen:
• Konstruktor mkar(n, d) bekommt Initialelement d
(Alternative: Unspezifizierte Initialisierung)
• Für m ≥ # a ist Selektion a[m] unspezifiziert
• Für m ≥ # a ist Modifikation Identität: a[m, d] = a
axioms
a = a’ ↔ # a = # a’ ∧ ∀ n. n < # a → a[n] = a’[n];
# mkar(n,d) = n; # a[m , d] = # a;
m < n → mkar(n,d)[m] = d;
m < # a → a[m , d][m] = d; n 6= m → a[m , d][n] = a[n];
end specification
160
Inkonsistente rekursive Definition
• Annahmen:
⋆ Mengen von nat. Zahlen definiert
⋆ Die Mengen sind von ∅ und insert generiert
⋆ Für Mengen gilt: insert(a,insert(a,∅)) = insert(a,∅)
• Rekursive Definition:
sum(∅) = 0,
sum(insert(a, s)) = a + sum(s)
• Inkonsistent, da aus insert(1,insert(1,∅))) = insert(1,∅) folgt:
2 = sum(insert(1,insert(1,∅))) = sum(insert(1,∅)) = 1
• Korrekte Definition:
sum(∅) = 0,
¬ a ∈ s → sum(insert(a, s)) = a + sum(s)
(im Fall a ∈ s ist insert(a, s) = s)
• Operation sum muss mit der Definition der Gleichheit auf Mengen,
i. e. dem Extensionalitätsaxiom verträglich sein!
161
Anforderungen an nichtfreie Datentypen
• Semantische Überlegungen zur Spezifikation nichtfreier Datentypen:
⋆ Es gibt den Datentyp ⇒ Konsistenz (wenn Axiome für den
intendierten Datentyp gelten)
⋆ Die im Extensionalitätsaxiom durch ϕ beschriebene Relation muss
wenigstens Äquivalenzrelation sein:
− Reflexivität: ϕ(a, a)
− Kommutativität: ϕ(a, b) → ϕ(b, a)
− Transitivität: ϕ(a, b) ∧ ϕ(b, c) → ϕ(a, c)
• Für gleiche Konstruktorterme t1 , t2 muss Operation f dasselbe liefern:
ϕ(t1 , t2 ) → f (t1 ) = f (t2 )
⇒ Beweisverpflichtungen
• Äquivalenzrel. + Verträglichkeit = Kongruenz
162
Korrekte Spez. der geordneten Listen (1)
Orderedlist = specification
sorts elem; ordlist;
constants [] : ordlist;
functions
.+.
: elem × ordlist → ordlist ;
min
: ordlist
→ elem ;
butmin : ordlist
→ ordlist ;
predicates
. < . : elem × elem ;
variables
a, b, c : elem;
l, l ′ : ordlist;
induction
ordlist generated by [], +;
163
Korrekte Spez. der geordneten Listen (2)
axioms
¬ a < a; a < b ∨ a = b ∨ b < a;
a < b ∧ b < c → a < c;
l = l′ ↔
l = [] ∧ l’ = []
∨
l 6= [] ∧ l’ 6= []
∧ min(l) = min(l′ )
∧ butmin(l) = butmin(l′ );
min(a + []) = a;
a < b → min(a + b + l) = min(a + l);
¬ a < b → min(a + b + l) = min(b + l);
butmin(a + []) = [];
a < b → butmin(a + b + l) = b + butmin(a + l);
¬ a < b → butmin(a + b + l) = a + butmin(b + l);
end specification
164
Noethersche Induktion
165
Noethersche Induktion (1)
Definition (Noethersche Relationen)
Sei ≪ ⊆ A × A. Die Relation ≪ heißt noethersch (oder wohlfundiert, engl.
well-founded) wenn es keine unendlichen ≪-Ketten gibt:
. . . ≪ a3 ≪ a2 ≪ a1 ≪ a0
Satz (Ordnungsprädikate)
Ordnungsprädikate von Datendefinitionen sind noethersch in jedem Modell
der Spezifikation.
166
Noethersche Induktion (2)
Satz (Noethersche Induktion)
Für noethersche Relationen ≪ gilt:
Wenn für jedes a aus E(a′ ) für alle Elemente a′ ≪ a die Aussage E(a)
gefolgert werden kann, so gilt E für alle Elemente:
(∀ a. (∀ a′ . a′ ≪ a ⇒ E(a′ )) ⇒ E(a)) ⇒ ∀ b. E(b)
Definition (Noethersche Induktionsregel)
Sei y := free(Γ ⊢ ∆) \ {x} und ≪ noethersch. Induktion über x:
IND(≪)
∀ y.∀
x′ .
x′
≪x→( Γ→
Γ⊢∆
V
167
W
′
x
∆)x , Γ
⊢∆
Noethersche Induktion (Beispiele)
Beispiel: Natürliche Zahlen
∀ n0 . n0 < n → ϕ(n0 ) ⊢ ϕ(n)
⊢ ∀ n. ϕ(n)
Beispiel: Listen
∀ l0 . (l0 ≪ l) → ϕ(l0 ) ⊢ ϕ(l)
⊢ ∀ l. ϕ(l)
168
Noethersche Induktion (Beispielprädikate)
Größenordnung:
Sei size : s → nat . Dann ist ≪ noethersch mit
x ≪ y :↔ size(x) < size(y).
Lexikalische Ordnung:
Betrachte Spezifikation Pair2 von vorher. Seien <1 : elem1 × elem1 und <2 :
elem2 × elem2 noethersch. Dann auch ≪ mit
mkpair(a, b) ≪ mkpair(a′ , b′ ) :⇔ a <1 a′ ∨ (a = a′ ∧ b <2 b′ ).
Untermengenordnung:
Seien s, s′ zwei endliche Mengen (Spezifikation später). Dann ist
s ⊂ s′ ↔ s ⊆ s ∧ s 6= s′
noethersch, da s ⊂ s′ → card(s) < card(s′ ).
169
Herunterladen