Der KIV-Kalkül Simplifier und Heuristiken 47 KIV-Kalkül: Überblick • Versuch 1: basic rules, ab Versuch 2: KIV-Kalkül • Sequenzenkalkül kennt keine Beweisstrukturierung: ⇒ Lemmas + Regeln zum Anwenden von Lemmas • Beobachtung: Sequenzenkalkül ist sehr elementar: ⇒ viele Regeln automatisch anwendbar • Deshalb: Definition eines Simplifiers, der alle unkritischen Regeln immer automatisch anwendet. • Regeln mit 2 Prämissen (disjunction left, conjunction right etc.) sind der Idee nach alle Fallunterscheidungen ⇒ Zusammenfassen zu einer Regel case distinction • Automatisches Anwenden von Regeln durch Heuristiken, die man jederzeit dazu- oder wegschalten kann 48 Nachtrag zum Basiskalkül: cut und weakening Wozu braucht man: Γ′ ⊢ ∆′ (weakening, Γ′ ⊆ Γ, ∆′ ⊆ ∆) Γ⊢∆ 49 Γ ⊢ ϕ, ∆ ϕ, Γ ⊢ ∆ (cut formula) Γ⊢∆ Nachtrag zum Basiskalkül: cut und weakening Wozu braucht man: Γ′ ⊢ ∆′ (weakening, Γ′ ⊆ Γ, ∆′ ⊆ ∆) Γ⊢∆ Γ ⊢ ϕ, ∆ ϕ, Γ ⊢ ∆ (cut formula) Γ⊢∆ Erinnerung: Wenn Axiome (in KIV auch: Lemmas) gegeben sind, dürfen diese als Prämissen in Beweisbäumen übrigbleiben 49 Nachtrag zum Basiskalkül: cut und weakening Wozu braucht man: Γ′ ⊢ ∆′ (weakening, Γ′ ⊆ Γ, ∆′ ⊆ ∆) Γ⊢∆ Γ ⊢ ϕ, ∆ ϕ, Γ ⊢ ∆ (cut formula) Γ⊢∆ Erinnerung: Wenn Axiome (in KIV auch: Lemmas) gegeben sind, dürfen diese als Prämissen in Beweisbäumen übrigbleiben • Regeln werden nur benötigt, um Axiome als Prämissen hinzubekommen • Im Basiskalkül: insert axiom, erzeugt eine Prämisse • Im KIV-Kalkül: insert lemma & insert rewrite-lemma ⊢ Ax Cl∀ (Ax ), Γ ⊢ ∆ (insert axiom) Γ⊢∆ 49 KIV-Kalkül: Lemmaanwendung Beim Anwenden von Axiomen will man nicht umständlich cut, all left (und evtl. insert equation) machen Γ′ ⊢ ∆′ Γ ⊢ Θ( V Γ′ ), ∆ Θ( ∆′ ), Γ ⊢ ∆ W Γ⊢∆ (insert lemma) • Γ′ ⊢ ∆′ ist das Lemma (Axiom oder anderes Theorem) • Θ ist eine Substitution für die freien Variablen des Lemmas • Die Prämisse mit dem Lemma wird vom System als geschlossen betrachtet 50 KIV-Kalkül: Ersetzungslemmas ′ Γ ⊢ϕ→σ=τ Γ ⊢ Θ( Γ′ ∧ ϕ), ∆ Γ⊢∆ V Γ′′ ⊢ ∆′′ (insert rewrite lemma) • Γ′ ⊢ ϕ → σ = τ ist das Lemma (Γ und Vorbedingung ϕ dürfen fehlen) • Θ ist eine Substitution für die freien Variablen des Lemmas • Γ′′ ⊢ ∆′′ entsteht aus Γ ⊢ ∆ durch Ersetzen von Θ(σ) durch Θ(τ ) • Lemmas der Form Γ′ ⊢ ϕ → (ψ ↔ χ) mit ψ Literal erlaubt: Dann wird Θ(ψ) durch Θ(χ) ersetzt • Wird kontextsensitiv unterstützt: Klicken auf das führende Funktionssymbol von σ in der Sequenz bietet passende Rewrite-Regeln an 51 KIV-Kalkül: Der Simplifier Beobachtung: Viele Vereinfachungen macht man beim mathematischen Beweisen ohne darüber nachzudenken. Alle unkritischen Regeln wendet der Simplifier in einem Schritt immer an. Es gibt 2 Arten von Vereinfachung: Logische Vereinfachung • Beipiel: Ersetzen von A ∧ A durch A (für jede Formel A) • Sind von Axiomen unabhängig, werden immer angewandt Simplifierregeln • Beispiel (nat. Zahlen): n + 0 = n zum Ersetzen von τ + 0 durch τ • Benötigen eine als Simplifierregel markiertes Axiom oder Lemma 52 Simplifier: Logische Vereinfachung • Aussagenlogische Regeln mit einer Prämisse (wie implication right, con. left, dis. right etc.) • All right, Exists left, axiom, reflexivity • Aussagenlogik mit true und false • ∃ x. x = τ ∧ A kann zu Aτx vereinfacht werden, falls x 6∈ Vars(τ ). • Vereinfachung mit Hilfe des Kontexts Beispiele: true ⊢ ∆ A, Γtrue A A A, Γ ⊢ ∆ AfBalse → B, Γ ⊢ ∆ A → B, Γ ⊢ , ∆ ΓfAalse ⊢ A, ∆fAalse Γ ⊢ A, ∆ true ,Γ ⊢ ∆ A ∧ BA A ∧ B, Γ ⊢ ∆ = A ∧ true ⇒ A Bsp.: A ∧ A ⇒ A ∧ Atrue A 53 true ,Γ ⊢ ∆ A → BA A → B, Γ ⊢ , ∆ true ,∆ Γ ⊢ A ∧ BA Γ ⊢ A ∧ B, ∆ Simplifier: Datenstrukturabhängige Regeln • Simplifierregeln sind Axiome oder Theoreme (Sequenzen), die einen entsprechenden Verwendungseintrag haben • Die syntaktische Form bestimmt den Effekt • Es gibt mehrere Klassen: ⋆ Simplifierregeln ⋆ Forward-Regeln • Alle Regeln können lokal oder global sein Zentral für das Verständnis von KIV: Welche Simplifierregel hat welchen Effekt? 54 Simplifier: lokale und globale Regeln 2 Klassen von Simplifierregeln • Lokale Simplifierregeln: Werden in Beweisen über der Spezifikation, in der sie definiert sind, benutzt. • Globale Simplifierregeln: Werden in Beweisen in Spezifikationen, die über der, in der sie definiert sind, benutzt. Pragmatik • Lokal werden Axiome als Simplifierregeln verwendet • Global werden Theoreme verwendet, die “gute” Simplifierregeln sind Analog für Forward-Regeln 55 Simplifier: Eingabe von Simplifierregeln Theoreme werden als Simplifierregeln eingetragen, wahlweise durch • Am Ende der Sequenz in der specification/sequents-Datei: used for: s, ls; used for: f, lf; • Auf Spezifikationsebene im Menü: Add (Local) Simplifierrules Add (Local) Forwardrules • Auf Spezifikationsebene: durch Rechtsklick auf das Theorem und Anklicken der Checkbox 56 Simplifier: Typen von Simplifierregeln Simplifierregeln (mit Eintrag s und/oder ls) gehören zu einer der Klassen • Termersetzungsregel = Rewriteregel: Generelle Form: Γ ⊢ ϕ → (σ = τ ) Effekt: (Instanzen von) σ durch τ ersetzen • Formelersetzungsregel = Äquivalenzregel Generelle Form: Γ ⊢ ϕ → (ψ ↔ χ) Effekt: (Instanzen von) ψ durch χ ersetzen • Assoziativität und Kommutativität: Generelle Form: (a + b) + c = a + (b + c) und a + b = b + a Effekt: Alle anderen Regeln modulo Ass. und Komm. anwenden 57 Simplifier: Pragmatik von Bedingungen Rewrite- und Äquivalenzregeln haben die generelle Form Γ ⊢ ϕ → σ = τ und Γ ⊢ ϕ → (ψ ↔ χ) • Vorbedingungen Γ und ϕ: Als Formel dieselbe Bedeutung, aber unterschiedlich behandelt. • ϕ = ϕ1 ∧ . . . ∧ ϕn muss Konjunktion von Literalen sein • Literal = evtl. negierte atomare Formel • Atomare Formel = Anwendung von Gleicheit oder nicht vordefiniertem Prädikat (ungleich ∧, ∨, . . . ) auf Terme • (Instanzen von) ϕ1 , . . . , ϕn werden in Sequenz gesucht: Nichtnegierte Formeln im Antezedent, negierte im Sukzedent • Γ wird versucht durch rekursiven Simplifieraufruf zu beweisen • Γ darf beliebige Formeln enthalten 58 Simplifier: Pragmatik von Bedingungen Wann sollte man Vorbedingungen in Γ stecken, wann in ϕ1 , . . . ,ϕn ? • Vorbedingungen vor dem Sequenzenhaken in Γ sollten nur dann definiert werden, wenn sie in sinnvollen Sequenzen immer erfüllt sind. • Typische sinnvolle Vorbedingungen sind Definiertheitsbedingungen: ⋆ ⋆ ⋆ ⋆ m −1 (Vorgänger von m) ist nur für m 6= 0 definiert m − n ist nur für n ≤ m definiert .rest und .last sind nur für nichtleere Listen definiert Arrays: i < #ar sollte für Zugriff a[i] immer wahr sein • Wenn man die Pragmatik nicht befolgt: Viele nutzlose Simplifieraufrufe (wird schnell sehr langsam) 59 Simplifier: Beispiele zu Vorbedingungen • n 6= 0 ⊢ (m < n −1 ↔ m +1 < n) Vorbedingung ok im Antezedent, da 0 − 1 nicht sinnvoll ist • ⊢ m < n → (n < m + 2 ↔ m + 1 = n) Nicht im Antezedent, sonst, sobald Instanzen von n < m + 2 vorkommen: viele unnötige Beweisversuche für m < n • m ≤ n ⊢ (n − m) + m = m Beweist z. B. die Sequenz f(x) > 5 ⊢ (f(x) − 3) + 3 = f(x) (da der Simplifier f(x) > 5 ⊢ 3 ≤ f(x) beweisen kann) ⊢ m ≤ n → (n − m) + m = m beweist die Sequenz nicht, da 3 ≤ f(x) nicht in der Sequenz vorkommt 60 Simplifier: Rewrite-Regeln Γ⊢ϕ→σ=τ ersetzt (Instanzen von) σ durch τ , wenn Vorbedingungen ok Einschränkungen: • free (ϕ) ∪ free (σ ) muß alle freien Variablen abdecken • σ und τ müssen Terme sein, σ darf keine Variable sein Beispiele: • (m + n) − n = m • i > 0 → sqrt(i ˆ 2) = i (i integer; warum nicht im Antezedent?) • (s1 ∪ s2) \ s2 = s1 \ s2 (Mengen) • x 6= [] → (x + y ).first = x.first (Listen, + = append, warum nicht Ant.?) 61 Simplifier: Äquivalenzregeln Γ ⊢ ϕ → (ψ ↔ χ) ersetzt (Instanzen von) ψ durch χ, wenn Vorbedingungen ok Einschränkungen: • free (ϕ) ∪ free (ψ ) muß alle freien Variablen abdecken • ψ muss Prädikat sein, χ ist beliebige Formel • Vereinfachung: falls ψ keine Gleichung, statt (ψ ↔ true) nur ψ • Vereinfachung: statt (ψ ↔ f alse) nur ¬ ψ Beispiele: • sorted(a + []), # x = 0 ↔ x = [] (Listen) • m + n < m + n0 ↔ n < n0 • n 6= 0 ⊢ (m < n −1 ↔ m +1 < n) 62 Simplifier: Äquivalenzregeln mit Konjunktion oder Disjunktion Äquivalenzregel: a ∈ s1 ∪ s2 ↔ a ∈ s1 ∨ a ∈ s2 Effekt: Γ ⊢ a ∈ s1, a ∈ s2, ∆ Γ ⊢ a ∈ s1 ∪ s2, ∆ Γ, a ∈ s1 ⊢ ∆, a ∈ s2 Γ, a ∈ s1 ∪ s2 ⊢ ∆, a ∈ s2 Γ, a ∈ s2 ⊢ ∆, a ∈ s1 Γ, a ∈ s1 ∪ s2 ⊢ ∆, a ∈ s1 Kein Effekt auf Γ1 , a ∈ s1 ∪ s2, Γ2 ⊢ ∆ (wenn a ∈ s1 und a ∈ s2 nicht in ∆) ! Idee: Verschachtelte aussagenlogische Ausdrücke sind schwer zu lesen. Selber Effekt, falls ψ Konjunktion (Antezedent und Sukzendent vertauscht). Beispiel: ⊢ a ∈ s1 ∩ s2 ↔ a ∈ s1 ∧ a ∈ s2. 63 Simplifier: weitere Äquivalenzregeln • Wenn in Γ ⊢ ϕ → (ψ ↔ χ) das χ keine Konjunktion/Disjunktion ist, wird immer ersetzt • Somit: Regel a ∈ s1 ∪ s2 ↔ ¬ ¬ (a ∈ s1 ∨ a ∈ s2) umgeht den Effekt der Disjunktion (nur selten verwendet) • Regel, die nur auf ϕ im Antezedent angewandt wird: Γ ⊢ ϕ1 ∧ . . . ∧ ϕn → (¬ ¬ ϕ ↔ ψ) • Regel, die nur auf ϕ im Sukzedent angewandt wird: Γ ⊢ ϕ1 ∧ . . . ∧ ϕn → (¬ ϕ ↔ ψ) 64 Simplifier: Pragmatik für einseitige Regeln • Angenommen es gilt ⊢ ϕ1 → ϕ • ϕ1 sei eine komplexe Formel, ϕ sei eine einfache, schwächere Formel • Beispiel: ⊢ isprefix(attach(list1,a),list2) → a ∈ list2 • Direkte Verwendung als Simplifierregel ergibt: ⋆ Beweisziele ϕ1 , Γ ⊢ ϕ, ∆ werden geschlossen (Prima!) ⋆ Aus Beweiszielen ϕ1 , ϕ, Γ ⊢ ∆ wird ϕ gelöscht • Letzteres ist unerwünscht, da a ∈ list2 häufige Vorbedingung ist • Deshalb: ⊢ isprefix(attach(list1,a),list2) → (¬ a ∈ list2 ↔ false) • Falls ψ eine negierte Formel ist braucht man die Form mit 2 Negationen • Beispiel ⊢ isprefix(attach(list1,a),list2) → (¬ ¬ list2 = [] ↔ false) • Allgemein gilt für Implikationen: Immer überlegen, was für einen Effekt man will! 65 Simplifier: Beispiele für Äquivalenzregeln • m ≤ n → (n < m ↔ false) ⋆ Beweist m ≤ n, n < m, Γ ⊢ ∆ ⋆ Wirft in m ≤ n, Γ ⊢ n < m, ∆ das n < m weg • (s1 \ s2) \ s3 = (s1 \ s3) \ s2 ↔ true ⋆ Beweist Gleichung im Sukzedent, wirft sie im Antezedent weg ⋆ Warum muß das “↔ true” sein? • Es gilt: s ∩ s0 = ∅ ∧ a ∈ s → ¬ a ∈ s0 Was wäre eine sinnvolle Simplifierregel? 66 Simplifier: Beispiele für Äquivalenzregeln • m ≤ n → (n < m ↔ false) ⋆ Beweist m ≤ n, n < m, Γ ⊢ ∆ ⋆ Wirft in m ≤ n, Γ ⊢ n < m, ∆ das n < m weg • (s1 \ s2) \ s3 = (s1 \ s3) \ s2 ↔ true ⋆ Beweist Gleichung im Sukzedent, wirft sie im Antezedent weg ⋆ Warum muß das “↔ true” sein? • Es gilt: s ∩ s0 = ∅ ∧ a ∈ s → ¬ a ∈ s0 Was wäre eine sinnvolle Simplifierregel? ⋆ In Sequenz s ∩ s0 = ∅, a ∈ s ⊢ a ∈ s0 nicht das a ∈ s0 durch false ersetzen (und damit wegwerfen) ⇒ nur im Antezedent auf s ∩ s0 = ∅, a ∈ s, a ∈ s0 ⊢ anwenden und damit Sequenz schliessen ⋆ Lösung: s ∩ s0 = ∅ ∧ a ∈ s → (¬ ¬ a ∈ s0 ↔ false) 66 Simplifier: Kommutativität und Assoziativität • Kommutativität: m + n = n + m • Assoziativität: (m + n) + k = n + (m + k) • Kurz: C(+), A(+), AC(+) für komm., ass., komm. und ass. • Werden nicht direkt verwendet (Warum?) • Ob eine Simplifierregel passt, wird “modulo” dieser Regeln geprüft • ⊢ a + b ∗ c = c ∗ b + a wird mit C(+,*) sofort (per Reflexivität) bewiesen. • ⊢ b ∗ c ≤ (c ∗ a) ∗ b wird für AC(∗) mit der Regel m ≤ m ∗ n bewiesen • Viele Operatoren sind AC: +,∗, min, ggt, ∪ • Nur assoziativ ist z.B. append auf Listen, ∗ auf Matrizen • Nur kommutativ ist sehr selten 67 Simplifier: Regeln für Zahlen • KIV hat Zahlen vordefiniert: ⋆ für die Sort nat: 0,1,2,. . . ⋆ für die Sorte int: . . . , ∼2, ∼1, 0, 1, 2, . . . • Implizite Regeln: Summen, Differenzen, <, ≤ etc. mit Zahlen werden immer gleich ausgewertet. • Manche Simplifierregeln will man nur anwenden, wenn eine bestimmte Variable m durch eine Zahl instanziert ist ⇒ Schreibe Schreibe (∗ m) statt m (mindestens einmal in der Regel) • Bsp: Distributivität: ⊢ a ∗ (∗ m) + a ∗ (∗ n) = a ∗ (n + m) ⋆ Wenn m, n Zahlen ⇒ m + n wird sofort ausgerechnet ⋆ Wenn m, n keine Zahlen sind, Regel umgekehrt anwenden! 68 Simplifier: Forwardregeln • Manchmal will man neue Information zu einer Sequenz dazunehmen • Fast nur für Transitivität von Ordnungs- und Äquivalenzrelationen: m < n ∧ n < n0 → m < n0 isperm(x, y ) ∧ isperm(y, z ) → isperm(x, z ) • Dazu gibt es Forward-Regeln der Form: Γ ⊢ ϕ1 ∧ . . . ∧ ϕn → ϕ • Vorbedingungen werden wie bei Simplifierregeln behandelt • ϕ wird genau einmal zur Sequenz addiert 69 Simplifier: Hinweise zu Forwardregeln • Transitivität ist unkritisch (sollte man machen) • Häufig etliche Varianten notwendig: m < n ∧ n ≤ n0 → m < n0 m < n ∧ ¬ n0 < n → m < n0 m ≤ n + 1 ∧ n < n0 → m ≤ n0 • Ein Lemma sollte nie Forward- und Simplifierregel sein. Warum? • Forward-Regeln geben sehr leicht Endlosschleifen im Simplifier! ⇒ Sehr vorsichtig, nur mit gutem Grund verwenden • Einfaches Bsp. für Endlosschleife: ⊢ m < n → m < n + 1 • Bsp.: 0 < n ⊢ (∗ n) ≤ m → m 6= 0 • Warum nur (∗ n) und nicht einfach n? Warum 0 < n im Antezedent? 70 Weitere KIV-Regeln: Induktion • Theoretisches zu Induktion nächstes Mal • In KIV gibt es pro Datentyp meist eine strukturelle Induktionsregel • Nat. Zahlen: Wenn für eine Formel ϕ(n) ⋆ ϕ(0) gilt ⋆ für jedes n: aus Ind.hyp. ϕ(n) folgt: ϕ(n +1) dann gilt für ∀ n. ϕ(n) • Im Sequenzenkalkül: ϕ ist jetzt die Sequenz Γ ⊢ ∆ für Induktionsformel in Formel umwandeln! ⊢ ϕ(0) ϕ = ∀ y. ϕ(n) ⊢ ϕ(n +1) Γ⊢∆ V Γ→ W ∆, y = free(Γ → ∆) \ {n} 71 Induktion für Listen • Jede Liste ist entweder die leere Liste [] oder durch Addition von a vorne an x a + x gebildet • Achtung: append von zwei Listen wird auch x + y geschrieben • Es gilt ebenfalls strukturelle Induktion: Wenn für eine Formel ϕ(x) ⋆ ϕ([]) gilt ⋆ für jede Liste x: aus Ind.hyp. ϕ(x) folgt für jedes a: ϕ(a + x) dann gilt für ∀ x. ϕ(x) ⊢ ϕ([]) ϕ(x) ⊢ ϕ(a + x) Γ⊢∆ V W ϕ = ∀ y. Γ → ∆, y = free(Γ → ∆) \ {x} Hinweis: Ind.hyp weglassen = Fallunterscheidung, ob Liste = [] oder = a + x 72 Pragmatik zur Listeninduktion • Viele Definitionen sind rekursiv append: [] + y = y , (a + x) + y = a + (x + y) size: #([]) = 0, #(a + x) = 1 + # x isprefix: isprefix([],y ), ¬ isprefix(a + x,[]), isprefix(a + x, b + y ) ↔ a = b ∧ isprefix(x, y ) sorted: sorted([]), sorted(a + []), sorted((a + (b + x)) ↔ a < b ∧ sorted(b + x) • Induktion, wann immer möglich, über Variable am rekursiven Argument. Also: erstes Argument bei append und isprefix • Wenn dort keine Variable, oft Generalisierung des Arguments zu Variable notwendig • Anschliessend rekursive Definition anwenden (oft mit Simplifier!), dann Induktionshypothese • Bei sorted geht Rekursion über 2 Stufen: Induktion für FU! 73 KIV-Kalkül: Elimination für Selektoren • Listen haben (Postfix-)Selektoren ⋆ .first (erstes Element) ⋆ .rest (Rest der Liste) • Trick: Selektoren loswerden mit Hilfe von insert elim lemma • Benötigt wird Lemma ⊢ x 6= [] → (a = x.first ∧ y = x.rest ↔ x = a + y ) • Eliminationsregel sucht ein Term t.first oder t.rest • Wenn t 6= [] gilt, wird t = a + y ersetzt (neue Variablen a, y ) • Damit wird aus t.first bzw. t.rest jetzt a bzw. y t = a + y, Γ(a, y, a + y) ⊢ ∆(a, y, a + y) t 6= [], Γ(t.first, t.rest, t) ⊢ ∆(t.first, t.rest, t) 74 KIV-Kalkül: Elimination für andere Funktionen • Manchmal geht Elimination auch für andere “unbeliebte” Funktionen • Beliebte Beispiele: Minus und Division • Lemma für Minus: n ≤ m ⊢ n0 = m − n ↔ m = n0 + n • Vorteil: Man kann auf Simplifierregeln für − verzichten! • Nachteil: Neue Variable n0 wird eingeführt (manchmal unintuitiv) Γ(n0 + n, n, n0) ⊢ ∆(n0 + n, n, n0) n ≤ m,Γ(m, n, m − n) ⊢ ∆(m, n, m − n) 75 Spezifikation von Listen (1) list-basic = enrich nat with sorts elem; list; constants [] : list; functions .+. : elem × list → list prio 9; prio 9; .+. : list × list → list . .first : list → elem ; . .rest : list → list ; # : list → nat ; predicates . < . : elem × elem; . ∈ . : elem × list; variables c, b, a: elem; z2 , y2 , x2 , z1 , y1 , x1 , z0 , y0 , x0 , z, y, x: list; induction list generated by [], + :: elem × list; 76 Spezifikation von Listen (2) axioms irreflexivity : transitivity : totality : constructors : first : rest : append-base : append-rec : size-base : size-rec : In : end enrich ⊢ ¬ a < a; ⊢ a < b ∧ b < c → a < c; ⊢ a < b ∨ a = b ∨ b < a; ⊢[] 6= a + x; ⊢ (a + x).first = a; ⊢ (a + x).rest = x; ⊢[] + x = x; ⊢ (a + x) + y = a + x + y ; ⊢ #([]) = 0; ⊢ #(a + x) = #(x) + 1; ⊢ a ∈ x ↔ (∃ y, z. x = y + a + z); 77 used for : s,ls; used for : f,lf; used for : s,ls; used for : s,ls; used for : s,ls; used for : s,ls; used for : s,ls; used for : s,ls; used for : s,ls; Beispiel (1) zu zeigen: ⊢ # (x + y) = # x + # y Beweis durch strukturelle Induktion über x: Induktions Anfang x = [] # ( [] + y ) = # y = 0 + # y = # x + # y Induktions Schritt x ⇒ a + x # ( (a + x) + y ) = # (a + x + y) = # (x + y) + 1 = # x + # y + 1 = # x + 1 + # y = # (a + x)+ # y 78 Herleitung (1) 79 Herleitung (2) 80 Noch ein Beispiel z.z.: x + a = y + z ∧ ¬ a ∈ z → z = [] Strukturelle Induktion über x: • x = []: [] + a = a + [] = y + z z = [] ⇒ y = [] ⇒ a + [] = z ⇒ a ∈ z • x = b + x′ : Ind.Hyp: ∀ a, y, z. x′ + a = y + z ∧ ¬ a ∈ z → z = [] z.z.: (b + x′ ) + a = y + z ∧ ¬ a ∈ z → z = [] (b + x′ ) + a = b + (x′ + a) = y + z 1. y 6= [] ⇒ b = y .first ∧ x′ + a = y .rest + z ⇒ (Ind.-Hyp) 2. y = [] ⇒ b + (x′ + a) = z ⇒ a ∈ b + (x′ + a) 81 Automatisierung in KIV: Heuristiken • Flexible Automatisierung ist zentral, um bei grossen Fallstudien nicht immer wieder die gleichen Beweisschritte wiederholen zu müssen • Deshalb in KIV: Automatisierung durch zuschaltbare Heuristiken • Speziell: der Simplifier ist eine Heuristik ⇒ sollte man (fast) immer benutzen • Für jedes Beweisziel werden alle Heuristiken der Reihen nach ausprobiert • Gewählte Heuristiken jederzeit änderbar Sehr wichtig für das Verständnis von KIV: Welche Heuristik hat welchen Effekt? 82 Wichtige Heuristiken für PL in KIV (1) • Simplifier ⋆ Wendet die Simplifier-Regel an • pl case distinction ⋆ Wendet Regel case distinction an ⋆ Für einfache bis mittelschwere Beweise ⋆ Gefahr, unnötige Fallunterscheidungen zu machen • if-then-else-split ⋆ if-then-else-Operator: (ϕ ⊃ σ; τ ) bezeichnet σ , falls ϕ wahr ist, sonst τ ⋆ Wendet cut Regel mit ϕ an ⋆ Häufig einsetzbar, um sinnvolle Fallunterscheidungen zu erzwingen ⋆ Beispiel: Fallunterscheidung nach Anwendung von Rewrite-Regel abs(i) = (i ≥ 0 ⊃ i; − i) 83 Wichtige Heuristiken für PL in KIV (2) • Quantifier closing ⋆ Sucht Instanzen, mit denen eine Prämisse direkt geschlossen werden kann ⋆ Immer verwenden ⋆ Einziges Problem: Bei sehr vielen Quantoren braucht die Heuristik viel unnötige Zeit ⋆ Deshalb Spezifikationsmethodik: Prädikat (+ Simplfierregeln) definieren statt grosse Quantorenformeln zu verwenden • Quantifier: ⋆ Sucht „sinnvolle“ Instanzen für Quantoren ⋆ Kann Endlosschleifen verursachen! ⋆ Nur bei einfachen Quantorenbeweisen einsetzbar 84 Wichtige Heuristiken für PL in KIV (3) • structural induction: ⋆ Macht strukturelle Induktion über “sinnvolle” Terme ⋆ Idee für “sinnvoll”: Variablen an rekursiven Positionen: n ist sinnvoll in m + n, da + rekursiv über das zweite Argument definiert: m + 0 = m, m + (n +1) = (m + n) +1 ⋆ Klappt meistens, aber nicht immer ⋆ Heuristik wendet ausserdem einmal die Induktionshypothese an • module specific: ⋆ Eigentlich eine Meta-Heuristik: Erlaubt heuristische Anwendung von Regeln durch Patterns ⋆ Pattern: Gibt Formeln (oder Schemas für Formeln) an, die in der Sequenz vorkommen müssen bzw. nicht vorkommen dürfen + Regel die angewandt werden soll ⋆ Alle Patterns stehen in der Datei module-specific 85 Wichtige Heuristiken für PL in KIV (4) elimination: • Heuristik gesteuert durch Eliminationsregeln (analog zu: Simplifier durch Simplifierregeln) • KIV-Eingabe analog : used for: e; etc. • Beispiel: n ≤ m ⊢ n0 = m − n ↔ m = n0 + n • Vorbedingung im Antezedent: n ≤ m muss beweisbar sein (analog zu Simplifierregeln) 86 KIV-Kalkül: Heuristiksätze • in KIV: 3 vordefinierte Heuristiksätze: ⋆ PL Heuristics: minimale Menge sinnvoller Heuristiken ⋆ PL Heuristics + Case Splitting: Keine Induktion, FU automatisch ⋆ PL Heuristics + Struct. Ind.: Versucht Ziel induktiv zu beweisen und Fallunterscheidungen (FU) automatisch zu machen • Für grössere Projekte definiert man häufig seinen eigenen Standardsatz ⇒ Datei default-heuristics • Weitere Heuristiken für Programme (DL). Dort noch wichtiger, da Programme mehr Struktur haben (später) 87