src/HOL/Euclidean_Division.thy
changeset 66808 1907167b6038
parent 66807 c3631f32dfeb
child 66810 cc2b490f9dc4
equal deleted inserted replaced
66807:c3631f32dfeb 66808:1907167b6038
     4 *)
     4 *)
     5 
     5 
     6 section \<open>Uniquely determined division in euclidean (semi)rings\<close>
     6 section \<open>Uniquely determined division in euclidean (semi)rings\<close>
     7 
     7 
     8 theory Euclidean_Division
     8 theory Euclidean_Division
     9   imports Nat_Transfer
     9   imports Nat_Transfer Lattices_Big
    10 begin
    10 begin
       
    11 
       
    12 subsection \<open>Prelude: simproc for cancelling @{const divide} and @{const modulo}\<close>
       
    13 
       
    14 lemma (in semiring_modulo) cancel_div_mod_rules:
       
    15   "((a div b) * b + a mod b) + c = a + c"
       
    16   "(b * (a div b) + a mod b) + c = a + c"
       
    17   by (simp_all add: div_mult_mod_eq mult_div_mod_eq)
       
    18 
       
    19 ML_file "~~/src/Provers/Arith/cancel_div_mod.ML"
       
    20 
    11 
    21 
    12 subsection \<open>Euclidean (semi)rings with explicit division and remainder\<close>
    22 subsection \<open>Euclidean (semi)rings with explicit division and remainder\<close>
    13   
    23   
    14 class euclidean_semiring = semidom_modulo + normalization_semidom + 
    24 class euclidean_semiring = semidom_modulo + normalization_semidom + 
    15   fixes euclidean_size :: "'a \<Rightarrow> nat"
    25   fixes euclidean_size :: "'a \<Rightarrow> nat"
   637   
   647   
   638 subclass euclidean_ring_cancel ..
   648 subclass euclidean_ring_cancel ..
   639 
   649 
   640 end
   650 end
   641 
   651 
       
   652 
       
   653 subsection \<open>Euclidean division on @{typ nat}\<close>
       
   654 
       
   655 instantiation nat :: unique_euclidean_semiring
       
   656 begin
       
   657 
       
   658 definition normalize_nat :: "nat \<Rightarrow> nat"
       
   659   where [simp]: "normalize = (id :: nat \<Rightarrow> nat)"
       
   660 
       
   661 definition unit_factor_nat :: "nat \<Rightarrow> nat"
       
   662   where "unit_factor n = (if n = 0 then 0 else 1 :: nat)"
       
   663 
       
   664 lemma unit_factor_simps [simp]:
       
   665   "unit_factor 0 = (0::nat)"
       
   666   "unit_factor (Suc n) = 1"
       
   667   by (simp_all add: unit_factor_nat_def)
       
   668 
       
   669 definition euclidean_size_nat :: "nat \<Rightarrow> nat"
       
   670   where [simp]: "euclidean_size_nat = id"
       
   671 
       
   672 definition uniqueness_constraint_nat :: "nat \<Rightarrow> nat \<Rightarrow> bool"
       
   673   where [simp]: "uniqueness_constraint_nat = \<top>"
       
   674 
       
   675 definition divide_nat :: "nat \<Rightarrow> nat \<Rightarrow> nat"
       
   676   where "m div n = (if n = 0 then 0 else Max {k::nat. k * n \<le> m})"
       
   677 
       
   678 definition modulo_nat :: "nat \<Rightarrow> nat \<Rightarrow> nat"
       
   679   where "m mod n = m - (m div n * (n::nat))"
       
   680 
       
   681 instance proof
       
   682   fix m n :: nat
       
   683   have ex: "\<exists>k. k * n \<le> l" for l :: nat
       
   684     by (rule exI [of _ 0]) simp
       
   685   have fin: "finite {k. k * n \<le> l}" if "n > 0" for l
       
   686   proof -
       
   687     from that have "{k. k * n \<le> l} \<subseteq> {k. k \<le> l}"
       
   688       by (cases n) auto
       
   689     then show ?thesis
       
   690       by (rule finite_subset) simp
       
   691   qed
       
   692   have mult_div_unfold: "n * (m div n) = Max {l. l \<le> m \<and> n dvd l}"
       
   693   proof (cases "n = 0")
       
   694     case True
       
   695     moreover have "{l. l = 0 \<and> l \<le> m} = {0::nat}"
       
   696       by auto
       
   697     ultimately show ?thesis
       
   698       by simp
       
   699   next
       
   700     case False
       
   701     with ex [of m] fin have "n * Max {k. k * n \<le> m} = Max (times n ` {k. k * n \<le> m})"
       
   702       by (auto simp add: nat_mult_max_right intro: hom_Max_commute)
       
   703     also have "times n ` {k. k * n \<le> m} = {l. l \<le> m \<and> n dvd l}"
       
   704       by (auto simp add: ac_simps elim!: dvdE)
       
   705     finally show ?thesis
       
   706       using False by (simp add: divide_nat_def ac_simps)
       
   707   qed
       
   708   show "n div 0 = 0"
       
   709     by (simp add: divide_nat_def)
       
   710   have less_eq: "m div n * n \<le> m"
       
   711     by (auto simp add: mult_div_unfold ac_simps intro: Max.boundedI)
       
   712   then show "m div n * n + m mod n = m"
       
   713     by (simp add: modulo_nat_def)
       
   714   assume "n \<noteq> 0" 
       
   715   show "m * n div n = m"
       
   716     using \<open>n \<noteq> 0\<close> by (auto simp add: divide_nat_def ac_simps intro: Max_eqI)
       
   717   show "euclidean_size (m mod n) < euclidean_size n"
       
   718   proof -
       
   719     have "m < Suc (m div n) * n"
       
   720     proof (rule ccontr)
       
   721       assume "\<not> m < Suc (m div n) * n"
       
   722       then have "Suc (m div n) * n \<le> m"
       
   723         by (simp add: not_less)
       
   724       moreover from \<open>n \<noteq> 0\<close> have "Max {k. k * n \<le> m} < Suc (m div n)"
       
   725         by (simp add: divide_nat_def)
       
   726       with \<open>n \<noteq> 0\<close> ex fin have "\<And>k. k * n \<le> m \<Longrightarrow> k < Suc (m div n)"
       
   727         by auto
       
   728       ultimately have "Suc (m div n) < Suc (m div n)"
       
   729         by blast
       
   730       then show False
       
   731         by simp
       
   732     qed
       
   733     with \<open>n \<noteq> 0\<close> show ?thesis
       
   734       by (simp add: modulo_nat_def)
       
   735   qed
       
   736   show "euclidean_size m \<le> euclidean_size (m * n)"
       
   737     using \<open>n \<noteq> 0\<close> by (cases n) simp_all
       
   738   fix q r :: nat
       
   739   show "(q * n + r) div n = q" if "euclidean_size r < euclidean_size n"
       
   740   proof -
       
   741     from that have "r < n"
       
   742       by simp
       
   743     have "k \<le> q" if "k * n \<le> q * n + r" for k
       
   744     proof (rule ccontr)
       
   745       assume "\<not> k \<le> q"
       
   746       then have "q < k"
       
   747         by simp
       
   748       then obtain l where "k = Suc (q + l)"
       
   749         by (auto simp add: less_iff_Suc_add)
       
   750       with \<open>r < n\<close> that show False
       
   751         by (simp add: algebra_simps)
       
   752     qed
       
   753     with \<open>n \<noteq> 0\<close> ex fin show ?thesis
       
   754       by (auto simp add: divide_nat_def Max_eq_iff)
       
   755   qed
       
   756 qed (simp_all add: unit_factor_nat_def)
       
   757 
   642 end
   758 end
       
   759 
       
   760 text \<open>Tool support\<close>
       
   761 
       
   762 ML \<open>
       
   763 structure Cancel_Div_Mod_Nat = Cancel_Div_Mod
       
   764 (
       
   765   val div_name = @{const_name divide};
       
   766   val mod_name = @{const_name modulo};
       
   767   val mk_binop = HOLogic.mk_binop;
       
   768   val mk_plus = HOLogic.mk_binop @{const_name Groups.plus};
       
   769   val dest_plus = HOLogic.dest_bin @{const_name Groups.plus} HOLogic.natT;
       
   770   fun mk_sum [] = HOLogic.zero
       
   771     | mk_sum [t] = t
       
   772     | mk_sum (t :: ts) = mk_plus (t, mk_sum ts);
       
   773   fun dest_sum tm =
       
   774     if HOLogic.is_zero tm then []
       
   775     else
       
   776       (case try HOLogic.dest_Suc tm of
       
   777         SOME t => HOLogic.Suc_zero :: dest_sum t
       
   778       | NONE =>
       
   779           (case try dest_plus tm of
       
   780             SOME (t, u) => dest_sum t @ dest_sum u
       
   781           | NONE => [tm]));
       
   782 
       
   783   val div_mod_eqs = map mk_meta_eq @{thms cancel_div_mod_rules};
       
   784 
       
   785   val prove_eq_sums = Arith_Data.prove_conv2 all_tac
       
   786     (Arith_Data.simp_all_tac @{thms add_0_left add_0_right ac_simps})
       
   787 )
       
   788 \<close>
       
   789 
       
   790 simproc_setup cancel_div_mod_nat ("(m::nat) + n") =
       
   791   \<open>K Cancel_Div_Mod_Nat.proc\<close>
       
   792 
       
   793 lemma div_nat_eqI:
       
   794   "m div n = q" if "n * q \<le> m" and "m < n * Suc q" for m n q :: nat
       
   795   by (rule div_eqI [of _ "m - n * q"]) (use that in \<open>simp_all add: algebra_simps\<close>)
       
   796 
       
   797 lemma mod_nat_eqI:
       
   798   "m mod n = r" if "r < n" and "r \<le> m" and "n dvd m - r" for m n r :: nat
       
   799   by (rule mod_eqI [of _ _ "(m - r) div n"]) (use that in \<open>simp_all add: algebra_simps\<close>)
       
   800 
       
   801 lemma div_mult_self_is_m [simp]:
       
   802   "m * n div n = m" if "n > 0" for m n :: nat
       
   803   using that by simp
       
   804 
       
   805 lemma div_mult_self1_is_m [simp]:
       
   806   "n * m div n = m" if "n > 0" for m n :: nat
       
   807   using that by simp
       
   808 
       
   809 lemma mod_less_divisor [simp]:
       
   810   "m mod n < n" if "n > 0" for m n :: nat
       
   811   using mod_size_less [of n m] that by simp
       
   812 
       
   813 lemma mod_le_divisor [simp]:
       
   814   "m mod n \<le> n" if "n > 0" for m n :: nat
       
   815   using that by (auto simp add: le_less)
       
   816 
       
   817 lemma div_times_less_eq_dividend [simp]:
       
   818   "m div n * n \<le> m" for m n :: nat
       
   819   by (simp add: minus_mod_eq_div_mult [symmetric])
       
   820 
       
   821 lemma times_div_less_eq_dividend [simp]:
       
   822   "n * (m div n) \<le> m" for m n :: nat
       
   823   using div_times_less_eq_dividend [of m n]
       
   824   by (simp add: ac_simps)
       
   825 
       
   826 lemma dividend_less_div_times:
       
   827   "m < n + (m div n) * n" if "0 < n" for m n :: nat
       
   828 proof -
       
   829   from that have "m mod n < n"
       
   830     by simp
       
   831   then show ?thesis
       
   832     by (simp add: minus_mod_eq_div_mult [symmetric])
       
   833 qed
       
   834 
       
   835 lemma dividend_less_times_div:
       
   836   "m < n + n * (m div n)" if "0 < n" for m n :: nat
       
   837   using dividend_less_div_times [of n m] that
       
   838   by (simp add: ac_simps)
       
   839 
       
   840 lemma mod_Suc_le_divisor [simp]:
       
   841   "m mod Suc n \<le> n"
       
   842   using mod_less_divisor [of "Suc n" m] by arith
       
   843 
       
   844 lemma mod_less_eq_dividend [simp]:
       
   845   "m mod n \<le> m" for m n :: nat
       
   846 proof (rule add_leD2)
       
   847   from div_mult_mod_eq have "m div n * n + m mod n = m" .
       
   848   then show "m div n * n + m mod n \<le> m" by auto
       
   849 qed
       
   850 
       
   851 lemma
       
   852   div_less [simp]: "m div n = 0"
       
   853   and mod_less [simp]: "m mod n = m"
       
   854   if "m < n" for m n :: nat
       
   855   using that by (auto intro: div_eqI mod_eqI) 
       
   856 
       
   857 lemma le_div_geq:
       
   858   "m div n = Suc ((m - n) div n)" if "0 < n" and "n \<le> m" for m n :: nat
       
   859 proof -
       
   860   from \<open>n \<le> m\<close> obtain q where "m = n + q"
       
   861     by (auto simp add: le_iff_add)
       
   862   with \<open>0 < n\<close> show ?thesis
       
   863     by (simp add: div_add_self1)
       
   864 qed
       
   865 
       
   866 lemma le_mod_geq:
       
   867   "m mod n = (m - n) mod n" if "n \<le> m" for m n :: nat
       
   868 proof -
       
   869   from \<open>n \<le> m\<close> obtain q where "m = n + q"
       
   870     by (auto simp add: le_iff_add)
       
   871   then show ?thesis
       
   872     by simp
       
   873 qed
       
   874 
       
   875 lemma div_if:
       
   876   "m div n = (if m < n \<or> n = 0 then 0 else Suc ((m - n) div n))"
       
   877   by (simp add: le_div_geq)
       
   878 
       
   879 lemma mod_if:
       
   880   "m mod n = (if m < n then m else (m - n) mod n)" for m n :: nat
       
   881   by (simp add: le_mod_geq)
       
   882 
       
   883 lemma div_eq_0_iff:
       
   884   "m div n = 0 \<longleftrightarrow> m < n \<or> n = 0" for m n :: nat
       
   885   by (simp add: div_if)
       
   886 
       
   887 lemma div_greater_zero_iff:
       
   888   "m div n > 0 \<longleftrightarrow> n \<le> m \<and> n > 0" for m n :: nat
       
   889   using div_eq_0_iff [of m n] by auto
       
   890 
       
   891 lemma mod_greater_zero_iff_not_dvd:
       
   892   "m mod n > 0 \<longleftrightarrow> \<not> n dvd m" for m n :: nat
       
   893   by (simp add: dvd_eq_mod_eq_0)
       
   894 
       
   895 lemma div_by_Suc_0 [simp]:
       
   896   "m div Suc 0 = m"
       
   897   using div_by_1 [of m] by simp
       
   898 
       
   899 lemma mod_by_Suc_0 [simp]:
       
   900   "m mod Suc 0 = 0"
       
   901   using mod_by_1 [of m] by simp
       
   902 
       
   903 lemma div2_Suc_Suc [simp]:
       
   904   "Suc (Suc m) div 2 = Suc (m div 2)"
       
   905   by (simp add: numeral_2_eq_2 le_div_geq)
       
   906 
       
   907 lemma Suc_n_div_2_gt_zero [simp]:
       
   908   "0 < Suc n div 2" if "n > 0" for n :: nat
       
   909   using that by (cases n) simp_all
       
   910 
       
   911 lemma div_2_gt_zero [simp]:
       
   912   "0 < n div 2" if "Suc 0 < n" for n :: nat
       
   913   using that Suc_n_div_2_gt_zero [of "n - 1"] by simp
       
   914 
       
   915 lemma mod2_Suc_Suc [simp]:
       
   916   "Suc (Suc m) mod 2 = m mod 2"
       
   917   by (simp add: numeral_2_eq_2 le_mod_geq)
       
   918 
       
   919 lemma add_self_div_2 [simp]:
       
   920   "(m + m) div 2 = m" for m :: nat
       
   921   by (simp add: mult_2 [symmetric])
       
   922 
       
   923 lemma add_self_mod_2 [simp]:
       
   924   "(m + m) mod 2 = 0" for m :: nat
       
   925   by (simp add: mult_2 [symmetric])
       
   926 
       
   927 lemma mod2_gr_0 [simp]:
       
   928   "0 < m mod 2 \<longleftrightarrow> m mod 2 = 1" for m :: nat
       
   929 proof -
       
   930   have "m mod 2 < 2"
       
   931     by (rule mod_less_divisor) simp
       
   932   then have "m mod 2 = 0 \<or> m mod 2 = 1"
       
   933     by arith
       
   934   then show ?thesis
       
   935     by auto     
       
   936 qed
       
   937 
       
   938 lemma mod_Suc_eq [mod_simps]:
       
   939   "Suc (m mod n) mod n = Suc m mod n"
       
   940 proof -
       
   941   have "(m mod n + 1) mod n = (m + 1) mod n"
       
   942     by (simp only: mod_simps)
       
   943   then show ?thesis
       
   944     by simp
       
   945 qed
       
   946 
       
   947 lemma mod_Suc_Suc_eq [mod_simps]:
       
   948   "Suc (Suc (m mod n)) mod n = Suc (Suc m) mod n"
       
   949 proof -
       
   950   have "(m mod n + 2) mod n = (m + 2) mod n"
       
   951     by (simp only: mod_simps)
       
   952   then show ?thesis
       
   953     by simp
       
   954 qed
       
   955 
       
   956 lemma
       
   957   Suc_mod_mult_self1 [simp]: "Suc (m + k * n) mod n = Suc m mod n"
       
   958   and Suc_mod_mult_self2 [simp]: "Suc (m + n * k) mod n = Suc m mod n"
       
   959   and Suc_mod_mult_self3 [simp]: "Suc (k * n + m) mod n = Suc m mod n"
       
   960   and Suc_mod_mult_self4 [simp]: "Suc (n * k + m) mod n = Suc m mod n"
       
   961   by (subst mod_Suc_eq [symmetric], simp add: mod_simps)+
       
   962 
       
   963 lemma div_mult1_eq: -- \<open>TODO: Generalization candidate\<close>
       
   964   "(a * b) div c = a * (b div c) + a * (b mod c) div c" for a b c :: nat
       
   965   apply (cases "c = 0")
       
   966    apply simp
       
   967   apply (rule div_eqI [of _ "(a * (b mod c)) mod c"])
       
   968      apply (auto simp add: algebra_simps distrib_left [symmetric])
       
   969   done
       
   970 
       
   971 lemma div_add1_eq: -- \<open>NOT suitable for rewriting: the RHS has an instance of the LHS\<close>
       
   972    -- \<open>TODO: Generalization candidate\<close>
       
   973   "(a + b) div c = a div c + b div c + ((a mod c + b mod c) div c)" for a b c :: nat
       
   974   apply (cases "c = 0")
       
   975    apply simp
       
   976   apply (rule div_eqI [of _ "(a mod c + b mod c) mod c"])
       
   977   apply (auto simp add: algebra_simps)
       
   978   done
       
   979 
       
   980 context
       
   981   fixes m n q :: nat
       
   982 begin
       
   983 
       
   984 private lemma eucl_rel_mult2:
       
   985   "m mod n + n * (m div n mod q) < n * q"
       
   986   if "n > 0" and "q > 0"
       
   987 proof -
       
   988   from \<open>n > 0\<close> have "m mod n < n"
       
   989     by (rule mod_less_divisor)
       
   990   from \<open>q > 0\<close> have "m div n mod q < q"
       
   991     by (rule mod_less_divisor)
       
   992   then obtain s where "q = Suc (m div n mod q + s)"
       
   993     by (blast dest: less_imp_Suc_add)
       
   994   moreover have "m mod n + n * (m div n mod q) < n * Suc (m div n mod q + s)"
       
   995     using \<open>m mod n < n\<close> by (simp add: add_mult_distrib2)
       
   996   ultimately show ?thesis
       
   997     by simp
       
   998 qed
       
   999 
       
  1000 lemma div_mult2_eq:
       
  1001   "m div (n * q) = (m div n) div q"
       
  1002 proof (cases "n = 0 \<or> q = 0")
       
  1003   case True
       
  1004   then show ?thesis
       
  1005     by auto
       
  1006 next
       
  1007   case False
       
  1008   with eucl_rel_mult2 show ?thesis
       
  1009     by (auto intro: div_eqI [of _ "n * (m div n mod q) + m mod n"]
       
  1010       simp add: algebra_simps add_mult_distrib2 [symmetric])
       
  1011 qed
       
  1012 
       
  1013 lemma mod_mult2_eq:
       
  1014   "m mod (n * q) = n * (m div n mod q) + m mod n"
       
  1015 proof (cases "n = 0 \<or> q = 0")
       
  1016   case True
       
  1017   then show ?thesis
       
  1018     by auto
       
  1019 next
       
  1020   case False
       
  1021   with eucl_rel_mult2 show ?thesis
       
  1022     by (auto intro: mod_eqI [of _ _ "(m div n) div q"]
       
  1023       simp add: algebra_simps add_mult_distrib2 [symmetric])
       
  1024 qed
       
  1025 
       
  1026 end
       
  1027 
       
  1028 lemma div_le_mono:
       
  1029   "m div k \<le> n div k" if "m \<le> n" for m n k :: nat
       
  1030 proof -
       
  1031   from that obtain q where "n = m + q"
       
  1032     by (auto simp add: le_iff_add)
       
  1033   then show ?thesis
       
  1034     by (simp add: div_add1_eq [of m q k])
       
  1035 qed
       
  1036 
       
  1037 text \<open>Antimonotonicity of @{const divide} in second argument\<close>
       
  1038 
       
  1039 lemma div_le_mono2:
       
  1040   "k div n \<le> k div m" if "0 < m" and "m \<le> n" for m n k :: nat
       
  1041 using that proof (induct k arbitrary: m rule: less_induct)
       
  1042   case (less k)
       
  1043   show ?case
       
  1044   proof (cases "n \<le> k")
       
  1045     case False
       
  1046     then show ?thesis
       
  1047       by simp
       
  1048   next
       
  1049     case True
       
  1050     have "(k - n) div n \<le> (k - m) div n"
       
  1051       using less.prems
       
  1052       by (blast intro: div_le_mono diff_le_mono2)
       
  1053     also have "\<dots> \<le> (k - m) div m"
       
  1054       using \<open>n \<le> k\<close> less.prems less.hyps [of "k - m" m]
       
  1055       by simp
       
  1056     finally show ?thesis
       
  1057       using \<open>n \<le> k\<close> less.prems
       
  1058       by (simp add: le_div_geq)
       
  1059   qed
       
  1060 qed
       
  1061 
       
  1062 lemma div_le_dividend [simp]:
       
  1063   "m div n \<le> m" for m n :: nat
       
  1064   using div_le_mono2 [of 1 n m] by (cases "n = 0") simp_all
       
  1065 
       
  1066 lemma div_less_dividend [simp]:
       
  1067   "m div n < m" if "1 < n" and "0 < m" for m n :: nat
       
  1068 using that proof (induct m rule: less_induct)
       
  1069   case (less m)
       
  1070   show ?case
       
  1071   proof (cases "n < m")
       
  1072     case False
       
  1073     with less show ?thesis
       
  1074       by (cases "n = m") simp_all
       
  1075   next
       
  1076     case True
       
  1077     then show ?thesis
       
  1078       using less.hyps [of "m - n"] less.prems
       
  1079       by (simp add: le_div_geq)
       
  1080   qed
       
  1081 qed
       
  1082 
       
  1083 lemma div_eq_dividend_iff:
       
  1084   "m div n = m \<longleftrightarrow> n = 1" if "m > 0" for m n :: nat
       
  1085 proof
       
  1086   assume "n = 1"
       
  1087   then show "m div n = m"
       
  1088     by simp
       
  1089 next
       
  1090   assume P: "m div n = m"
       
  1091   show "n = 1"
       
  1092   proof (rule ccontr)
       
  1093     have "n \<noteq> 0"
       
  1094       by (rule ccontr) (use that P in auto)
       
  1095     moreover assume "n \<noteq> 1"
       
  1096     ultimately have "n > 1"
       
  1097       by simp
       
  1098     with that have "m div n < m"
       
  1099       by simp
       
  1100     with P show False
       
  1101       by simp
       
  1102   qed
       
  1103 qed
       
  1104 
       
  1105 lemma less_mult_imp_div_less:
       
  1106   "m div n < i" if "m < i * n" for m n i :: nat
       
  1107 proof -
       
  1108   from that have "i * n > 0"
       
  1109     by (cases "i * n = 0") simp_all
       
  1110   then have "i > 0" and "n > 0"
       
  1111     by simp_all
       
  1112   have "m div n * n \<le> m"
       
  1113     by simp
       
  1114   then have "m div n * n < i * n"
       
  1115     using that by (rule le_less_trans)
       
  1116   with \<open>n > 0\<close> show ?thesis
       
  1117     by simp
       
  1118 qed
       
  1119 
       
  1120 text \<open>A fact for the mutilated chess board\<close>
       
  1121 
       
  1122 lemma mod_Suc:
       
  1123   "Suc m mod n = (if Suc (m mod n) = n then 0 else Suc (m mod n))" (is "_ = ?rhs")
       
  1124 proof (cases "n = 0")
       
  1125   case True
       
  1126   then show ?thesis
       
  1127     by simp
       
  1128 next
       
  1129   case False
       
  1130   have "Suc m mod n = Suc (m mod n) mod n"
       
  1131     by (simp add: mod_simps)
       
  1132   also have "\<dots> = ?rhs"
       
  1133     using False by (auto intro!: mod_nat_eqI intro: neq_le_trans simp add: Suc_le_eq)
       
  1134   finally show ?thesis .
       
  1135 qed
       
  1136 
       
  1137 lemma Suc_times_mod_eq:
       
  1138   "Suc (m * n) mod m = 1" if "Suc 0 < m"
       
  1139   using that by (simp add: mod_Suc)
       
  1140 
       
  1141 lemma Suc_times_numeral_mod_eq [simp]:
       
  1142   "Suc (numeral k * n) mod numeral k = 1" if "numeral k \<noteq> (1::nat)"
       
  1143   by (rule Suc_times_mod_eq) (use that in simp)
       
  1144 
       
  1145 lemma Suc_div_le_mono [simp]:
       
  1146   "m div n \<le> Suc m div n"
       
  1147   by (simp add: div_le_mono)
       
  1148 
       
  1149 text \<open>These lemmas collapse some needless occurrences of Suc:
       
  1150   at least three Sucs, since two and fewer are rewritten back to Suc again!
       
  1151   We already have some rules to simplify operands smaller than 3.\<close>
       
  1152 
       
  1153 lemma div_Suc_eq_div_add3 [simp]:
       
  1154   "m div Suc (Suc (Suc n)) = m div (3 + n)"
       
  1155   by (simp add: Suc3_eq_add_3)
       
  1156 
       
  1157 lemma mod_Suc_eq_mod_add3 [simp]:
       
  1158   "m mod Suc (Suc (Suc n)) = m mod (3 + n)"
       
  1159   by (simp add: Suc3_eq_add_3)
       
  1160 
       
  1161 lemma Suc_div_eq_add3_div:
       
  1162   "Suc (Suc (Suc m)) div n = (3 + m) div n"
       
  1163   by (simp add: Suc3_eq_add_3)
       
  1164 
       
  1165 lemma Suc_mod_eq_add3_mod:
       
  1166   "Suc (Suc (Suc m)) mod n = (3 + m) mod n"
       
  1167   by (simp add: Suc3_eq_add_3)
       
  1168 
       
  1169 lemmas Suc_div_eq_add3_div_numeral [simp] =
       
  1170   Suc_div_eq_add3_div [of _ "numeral v"] for v
       
  1171 
       
  1172 lemmas Suc_mod_eq_add3_mod_numeral [simp] =
       
  1173   Suc_mod_eq_add3_mod [of _ "numeral v"] for v
       
  1174 
       
  1175 lemma (in field_char_0) of_nat_div:
       
  1176   "of_nat (m div n) = ((of_nat m - of_nat (m mod n)) / of_nat n)"
       
  1177 proof -
       
  1178   have "of_nat (m div n) = ((of_nat (m div n * n + m mod n) - of_nat (m mod n)) / of_nat n :: 'a)"
       
  1179     unfolding of_nat_add by (cases "n = 0") simp_all
       
  1180   then show ?thesis
       
  1181     by simp
       
  1182 qed
       
  1183 
       
  1184 text \<open>An ``induction'' law for modulus arithmetic.\<close>
       
  1185 
       
  1186 lemma mod_induct [consumes 3, case_names step]:
       
  1187   "P m" if "P n" and "n < p" and "m < p"
       
  1188     and step: "\<And>n. n < p \<Longrightarrow> P n \<Longrightarrow> P (Suc n mod p)"
       
  1189 using \<open>m < p\<close> proof (induct m)
       
  1190   case 0
       
  1191   show ?case
       
  1192   proof (rule ccontr)
       
  1193     assume "\<not> P 0"
       
  1194     from \<open>n < p\<close> have "0 < p"
       
  1195       by simp
       
  1196     from \<open>n < p\<close> obtain m where "0 < m" and "p = n + m"
       
  1197       by (blast dest: less_imp_add_positive)
       
  1198     with \<open>P n\<close> have "P (p - m)"
       
  1199       by simp
       
  1200     moreover have "\<not> P (p - m)"
       
  1201     using \<open>0 < m\<close> proof (induct m)
       
  1202       case 0
       
  1203       then show ?case
       
  1204         by simp
       
  1205     next
       
  1206       case (Suc m)
       
  1207       show ?case
       
  1208       proof
       
  1209         assume P: "P (p - Suc m)"
       
  1210         with \<open>\<not> P 0\<close> have "Suc m < p"
       
  1211           by (auto intro: ccontr) 
       
  1212         then have "Suc (p - Suc m) = p - m"
       
  1213           by arith
       
  1214         moreover from \<open>0 < p\<close> have "p - Suc m < p"
       
  1215           by arith
       
  1216         with P step have "P ((Suc (p - Suc m)) mod p)"
       
  1217           by blast
       
  1218         ultimately show False
       
  1219           using \<open>\<not> P 0\<close> Suc.hyps by (cases "m = 0") simp_all
       
  1220       qed
       
  1221     qed
       
  1222     ultimately show False
       
  1223       by blast
       
  1224   qed
       
  1225 next
       
  1226   case (Suc m)
       
  1227   then have "m < p" and mod: "Suc m mod p = Suc m"
       
  1228     by simp_all
       
  1229   from \<open>m < p\<close> have "P m"
       
  1230     by (rule Suc.hyps)
       
  1231   with \<open>m < p\<close> have "P (Suc m mod p)"
       
  1232     by (rule step)
       
  1233   with mod show ?case
       
  1234     by simp
       
  1235 qed
       
  1236 
       
  1237 lemma split_div:
       
  1238   "P (m div n) \<longleftrightarrow> (n = 0 \<longrightarrow> P 0) \<and> (n \<noteq> 0 \<longrightarrow>
       
  1239      (\<forall>i j. j < n \<longrightarrow> m = n * i + j \<longrightarrow> P i))"
       
  1240      (is "?P = ?Q") for m n :: nat
       
  1241 proof (cases "n = 0")
       
  1242   case True
       
  1243   then show ?thesis
       
  1244     by simp
       
  1245 next
       
  1246   case False
       
  1247   show ?thesis
       
  1248   proof
       
  1249     assume ?P
       
  1250     with False show ?Q
       
  1251       by auto
       
  1252   next
       
  1253     assume ?Q
       
  1254     with False have *: "\<And>i j. j < n \<Longrightarrow> m = n * i + j \<Longrightarrow> P i"
       
  1255       by simp
       
  1256     with False show ?P
       
  1257       by (auto intro: * [of "m mod n"])
       
  1258   qed
       
  1259 qed
       
  1260 
       
  1261 lemma split_div':
       
  1262   "P (m div n) \<longleftrightarrow> n = 0 \<and> P 0 \<or> (\<exists>q. (n * q \<le> m \<and> m < n * Suc q) \<and> P q)"
       
  1263 proof (cases "n = 0")
       
  1264   case True
       
  1265   then show ?thesis
       
  1266     by simp
       
  1267 next
       
  1268   case False
       
  1269   then have "n * q \<le> m \<and> m < n * Suc q \<longleftrightarrow> m div n = q" for q
       
  1270     by (auto intro: div_nat_eqI dividend_less_times_div)
       
  1271   then show ?thesis
       
  1272     by auto
       
  1273 qed
       
  1274 
       
  1275 lemma split_mod:
       
  1276   "P (m mod n) \<longleftrightarrow> (n = 0 \<longrightarrow> P m) \<and> (n \<noteq> 0 \<longrightarrow>
       
  1277      (\<forall>i j. j < n \<longrightarrow> m = n * i + j \<longrightarrow> P j))"
       
  1278      (is "?P \<longleftrightarrow> ?Q") for m n :: nat
       
  1279 proof (cases "n = 0")
       
  1280   case True
       
  1281   then show ?thesis
       
  1282     by simp
       
  1283 next
       
  1284   case False
       
  1285   show ?thesis
       
  1286   proof
       
  1287     assume ?P
       
  1288     with False show ?Q
       
  1289       by auto
       
  1290   next
       
  1291     assume ?Q
       
  1292     with False have *: "\<And>i j. j < n \<Longrightarrow> m = n * i + j \<Longrightarrow> P j"
       
  1293       by simp
       
  1294     with False show ?P
       
  1295       by (auto intro: * [of _ "m div n"])
       
  1296   qed
       
  1297 qed
       
  1298 
       
  1299 
       
  1300 subsection \<open>Code generation\<close>
       
  1301 
       
  1302 code_identifier
       
  1303   code_module Euclidean_Division \<rightharpoonup> (SML) Arith and (OCaml) Arith and (Haskell) Arith
       
  1304 
       
  1305 end