src/HOL/ex/Fundefs.thy
changeset 19568 6fa47aad35e9
child 19583 c5fa77b03442
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/HOL/ex/Fundefs.thy	Fri May 05 18:39:16 2006 +0200
@@ -0,0 +1,125 @@
+(*  Title:      HOL/ex/Fundefs.thy
+    ID:         $Id$
+    Author:     Alexander Krauss, TU Muenchen
+
+Examples of function definitions using the new "function" package.
+*)
+
+theory Fundefs
+imports Main
+begin
+
+
+section {* Very basic *}
+
+consts fib :: "nat \<Rightarrow> nat"
+function 
+  "fib 0 = 1"
+  "fib (Suc 0) = 1"
+  "fib (Suc (Suc n)) = fib n + fib (Suc n)"
+by pat_completeness (* shows that the patterns are complete *)
+  auto (* shows that the patterns are compatible *)
+
+(* we get partial simp and induction rules: *)
+thm fib.psimps
+thm fib.pinduct
+
+(* There is also a cases rule to distinguish cases along the definition *)
+thm fib.cases
+
+(* Now termination: *)
+termination fib
+  by (auto_term "less_than")    
+
+thm fib.simps
+thm fib.induct
+
+
+section {* Currying *}
+
+consts add :: "nat \<Rightarrow> nat \<Rightarrow> nat" 
+function
+  "add 0 y = y"
+  "add (Suc x) y = Suc (add x y)"
+by pat_completeness auto
+termination 
+  by (auto_term "measure fst")
+
+thm add.induct (* Note the curried induction predicate *)
+
+
+section {* Nested recursion *}
+
+
+consts nz :: "nat \<Rightarrow> nat"
+function
+  "nz 0 = 0"
+  "nz (Suc x) = nz (nz x)"
+by pat_completeness auto
+
+lemma nz_is_zero: (* A lemma we need to prove termination *)
+  assumes trm: "x \<in> nz.dom"
+  shows "nz x = 0"
+using trm
+by induct auto
+
+termination nz
+  apply (auto_term "less_than") (* Oops, it left us something to prove *)
+  by (auto simp:nz_is_zero)
+
+thm nz.simps
+thm nz.induct
+
+
+section {* More general patterns *}
+
+(* Currently, patterns must always be compatible with each other, since
+no automatich splitting takes place. But the following definition of
+gcd is ok, although patterns overlap: *)
+
+
+consts gcd2 :: "nat \<Rightarrow> nat \<Rightarrow> nat"
+function 
+  "gcd2 x 0 = x"
+  "gcd2 0 y = y"
+  "gcd2 (Suc x) (Suc y) = (if x < y then gcd2 (Suc x) (y - x)
+                                else gcd2 (x - y) (Suc y))"
+by pat_completeness auto
+termination by (auto_term "measure (\<lambda>(x,y). x + y)")
+
+thm gcd2.simps
+thm gcd2.induct
+
+
+(* General patterns allow even strange definitions: *)
+consts ev :: "nat \<Rightarrow> bool"
+function 
+  "ev (2 * n) = True"
+  "ev (2 * n + 1) = False"
+proof - (* completeness is more difficult here. . . *)
+  assume c1: "\<And>n. x = 2 * n \<Longrightarrow> P"
+    and c2: "\<And>n. x = 2 * n + 1 \<Longrightarrow> P"
+  have divmod: "x = 2 * (x div 2) + (x mod 2)" by auto
+  show "P"
+  proof cases 
+    assume "x mod 2 = 0"
+    with divmod have "x = 2 * (x div 2)" by simp
+    with c1 show "P" .
+  next
+    assume "x mod 2 \<noteq> 0"
+    hence "x mod 2 = 1" by simp
+    with divmod have "x = 2 * (x div 2) + 1" by simp
+    with c2 show "P" .
+  qed
+qed presburger+ (* solve compatibility with presburger *)
+termination by (auto_term "{}")
+
+thm ev.simps
+thm ev.induct
+thm ev.cases
+
+
+
+
+
+end
\ No newline at end of file