diff -r 05e6042394b9 -r 12554634e552 src/HOL/Library/EfficientNat.thy --- a/src/HOL/Library/EfficientNat.thy Wed Sep 20 12:24:11 2006 +0200 +++ b/src/HOL/Library/EfficientNat.thy Wed Sep 20 12:24:28 2006 +0200 @@ -51,37 +51,22 @@ *} int ("(_)") -definition - "nat_plus m n = nat (int m + int n)" - "nat_minus m n = nat (int m - int n)" - "nat_mult m n = nat (int m * int n)" - "nat_div m n = nat (fst (divAlg (int m, int n)))" - "nat_mod m n = nat (snd (divAlg (int m, int n)))" - "nat_less m n = (int m < int n)" - "nat_less_equal m n = (int m <= int n)" - "nat_eq m n = (int m = int n)" +ML {* set Toplevel.debug *} +setup {* + CodegenData.del_datatype "nat" +*} code_type nat (SML target_atom "IntInf.int") (Haskell target_atom "Integer") -code_const "0::nat" and Suc (*all constructors of nat must be hidden*) - (SML target_atom "(0 :: IntInf.int)" and "IntInf.+ (_, 1)") - (Haskell target_atom "0" and "(+) 1 _") - -code_const nat and int - (SML target_atom "(fn n : IntInf.int => if n < 0 then 0 else n)" and "_") - (Haskell target_atom "(\\n :: Int -> if n < 0 then 0 else n)" and "_") +code_const int + (SML "_") + (Haskell "_") -text {* - Eliminate @{const "0::nat"} and @{const "1::nat"} - by unfolding in place. -*} - -lemma [code inline]: - "0 = nat 0" - "1 = nat 1" -by (simp_all add: expand_fun_eq) +definition + nat_of_int :: "int \ nat" + "k \ 0 \ nat_of_int k = nat k" text {* Case analysis on natural numbers is rephrased using a conditional @@ -99,38 +84,72 @@ using their counterparts on the integers: *} -lemma [code]: "m + n = nat (int m + int n)" - by arith -lemma [code]: "m - n = nat (int m - int n)" - by arith -lemma [code]: "m * n = nat (int m * int n)" - by (simp add: zmult_int) -lemma [code]: "m div n = nat (int m div int n)" - by (simp add: zdiv_int [symmetric]) -lemma [code]: "m mod n = nat (int m mod int n)" - by (simp add: zmod_int [symmetric]) -lemma [code]: "(m < n) = (int m < int n)" - by simp +code_constname + nat_of_int "IntDef.nat_of_int" + +code_const nat_of_int + (SML "_") + (Haskell "_") -lemma [code func, code inline]: "m + n = nat_plus m n" - unfolding nat_plus_def by arith -lemma [code func, code inline]: "m - n = nat_minus m n" - unfolding nat_minus_def by arith -lemma [code func, code inline]: "m * n = nat_mult m n" - unfolding nat_mult_def by (simp add: zmult_int) -lemma [code func, code inline]: "m div n = nat_div m n" - unfolding nat_div_def div_def [symmetric] zdiv_int [symmetric] by simp -lemma [code func, code inline]: "m mod n = nat_mod m n" - unfolding nat_mod_def mod_def [symmetric] zmod_int [symmetric] by simp -lemma [code func, code inline]: "(m < n) = nat_less m n" - unfolding nat_less_def by simp -lemma [code func, code inline]: "(m <= n) = nat_less_equal m n" - unfolding nat_less_equal_def by simp -lemma [code func, code inline]: "OperationalEquality.eq m n = nat_eq m n" - unfolding nat_eq_def eq_def by simp +lemma [code func]: "0 = nat_of_int 0" + by (simp add: nat_of_int_def) +lemma [code func, code inline]: "1 = nat_of_int 1" + by (simp add: nat_of_int_def) +lemma [code func]: "Suc n = n + 1" + by simp +lemma [code, code inline]: "m + n = nat (int m + int n)" + by arith +lemma [code func, code inline]: "m + n = nat_of_int (int m + int n)" + by (simp add: nat_of_int_def) +lemma [code, code inline]: "m - n = nat (int m - int n)" + by arith +lemma [code, code inline]: "m * n = nat (int m * int n)" + unfolding zmult_int by simp +lemma [code func, code inline]: "m * n = nat_of_int (int m * int n)" +proof - + have "int (m * n) = int m * int n" + by (induct m) (simp_all add: zadd_zmult_distrib) + then have "m * n = nat (int m * int n)" by auto + also have "\ = nat_of_int (int m * int n)" + proof - + have "int m \ 0" and "int n \ 0" by auto + have "int m * int n \ 0" by (rule split_mult_pos_le) auto + with nat_of_int_def show ?thesis by auto + qed + finally show ?thesis . +qed +lemma [code]: "m div n = nat (int m div int n)" + unfolding zdiv_int [symmetric] by simp +lemma [code func]: "m div n = fst (Divides.divmod m n)" + unfolding divmod_def by simp +lemma [code]: "m mod n = nat (int m mod int n)" + unfolding zmod_int [symmetric] by simp +lemma [code func]: "m mod n = snd (Divides.divmod m n)" + unfolding divmod_def by simp +lemma [code, code inline]: "(m < n) \ (int m < int n)" + by simp +lemma [code func, code inline]: "(m \ n) \ (int m \ int n)" + by simp +lemma [code func, code inline]: "OperationalEquality.eq m n \ OperationalEquality.eq (int m) (int n)" + unfolding eq_def by simp +lemma [code func]: "nat k = (if k < 0 then 0 else nat_of_int k)" +proof (cases "k < 0") + case True then show ?thesis by simp +next + case False then show ?thesis by (simp add: nat_of_int_def) +qed lemma [code func]: - "int_aux i n = (if nat_eq n 0 then i else int_aux (i + 1) (nat_minus n 1))" - unfolding nat_eq_def nat_minus_def int_aux_def by simp + "int_aux i n = (if int n = 0 then i else int_aux (i + 1) (nat_of_int (int n - 1)))" +proof - + have "0 < n \ int n = 1 + int (nat_of_int (int n - 1))" + proof - + assume prem: "n > 0" + then have "int n - 1 \ 0" by auto + then have "nat_of_int (int n - 1) = nat (int n - 1)" by (simp add: nat_of_int_def) + with prem show "int n = 1 + int (nat_of_int (int n - 1))" by simp + qed + then show ?thesis unfolding int_aux_def by simp +qed subsection {* Preprocessors *}