885 text \<open> |
888 text \<open> |
886 We instantiate divisibility on the natural numbers by |
889 We instantiate divisibility on the natural numbers by |
887 means of @{const divmod_nat_rel}: |
890 means of @{const divmod_nat_rel}: |
888 \<close> |
891 \<close> |
889 |
892 |
890 definition divmod_nat :: "nat \<Rightarrow> nat \<Rightarrow> nat \<times> nat" where |
893 qualified definition divmod_nat :: "nat \<Rightarrow> nat \<Rightarrow> nat \<times> nat" where |
891 "divmod_nat m n = (THE qr. divmod_nat_rel m n qr)" |
894 "divmod_nat m n = (THE qr. divmod_nat_rel m n qr)" |
892 |
895 |
893 lemma divmod_nat_rel_divmod_nat: |
896 qualified lemma divmod_nat_rel_divmod_nat: |
894 "divmod_nat_rel m n (divmod_nat m n)" |
897 "divmod_nat_rel m n (divmod_nat m n)" |
895 proof - |
898 proof - |
896 from divmod_nat_rel_ex |
899 from divmod_nat_rel_ex |
897 obtain qr where rel: "divmod_nat_rel m n qr" . |
900 obtain qr where rel: "divmod_nat_rel m n qr" . |
898 then show ?thesis |
901 then show ?thesis |
899 by (auto simp add: divmod_nat_def intro: theI elim: divmod_nat_rel_unique) |
902 by (auto simp add: divmod_nat_def intro: theI elim: divmod_nat_rel_unique) |
900 qed |
903 qed |
901 |
904 |
902 lemma divmod_nat_unique: |
905 qualified lemma divmod_nat_unique: |
903 assumes "divmod_nat_rel m n qr" |
906 assumes "divmod_nat_rel m n qr" |
904 shows "divmod_nat m n = qr" |
907 shows "divmod_nat m n = qr" |
905 using assms by (auto intro: divmod_nat_rel_unique divmod_nat_rel_divmod_nat) |
908 using assms by (auto intro: divmod_nat_rel_unique divmod_nat_rel_divmod_nat) |
906 |
909 |
|
910 qualified lemma divmod_nat_zero: "divmod_nat m 0 = (0, m)" |
|
911 by (simp add: Divides.divmod_nat_unique divmod_nat_rel_def) |
|
912 |
|
913 qualified lemma divmod_nat_zero_left: "divmod_nat 0 n = (0, 0)" |
|
914 by (simp add: Divides.divmod_nat_unique divmod_nat_rel_def) |
|
915 |
|
916 qualified lemma divmod_nat_base: "m < n \<Longrightarrow> divmod_nat m n = (0, m)" |
|
917 by (simp add: divmod_nat_unique divmod_nat_rel_def) |
|
918 |
|
919 qualified lemma divmod_nat_step: |
|
920 assumes "0 < n" and "n \<le> m" |
|
921 shows "divmod_nat m n = apfst Suc (divmod_nat (m - n) n)" |
|
922 proof (rule divmod_nat_unique) |
|
923 have "divmod_nat_rel (m - n) n (divmod_nat (m - n) n)" |
|
924 by (fact divmod_nat_rel_divmod_nat) |
|
925 then show "divmod_nat_rel m n (apfst Suc (divmod_nat (m - n) n))" |
|
926 unfolding divmod_nat_rel_def using assms by auto |
|
927 qed |
|
928 |
|
929 end |
|
930 |
907 instantiation nat :: semiring_div |
931 instantiation nat :: semiring_div |
908 begin |
932 begin |
909 |
933 |
910 definition divide_nat where |
934 definition divide_nat where |
911 div_nat_def: "m div n = fst (divmod_nat m n)" |
935 div_nat_def: "m div n = fst (Divides.divmod_nat m n)" |
912 |
936 |
913 definition mod_nat where |
937 definition mod_nat where |
914 "m mod n = snd (divmod_nat m n)" |
938 "m mod n = snd (Divides.divmod_nat m n)" |
915 |
939 |
916 lemma fst_divmod_nat [simp]: |
940 lemma fst_divmod_nat [simp]: |
917 "fst (divmod_nat m n) = m div n" |
941 "fst (Divides.divmod_nat m n) = m div n" |
918 by (simp add: div_nat_def) |
942 by (simp add: div_nat_def) |
919 |
943 |
920 lemma snd_divmod_nat [simp]: |
944 lemma snd_divmod_nat [simp]: |
921 "snd (divmod_nat m n) = m mod n" |
945 "snd (Divides.divmod_nat m n) = m mod n" |
922 by (simp add: mod_nat_def) |
946 by (simp add: mod_nat_def) |
923 |
947 |
924 lemma divmod_nat_div_mod: |
948 lemma divmod_nat_div_mod: |
925 "divmod_nat m n = (m div n, m mod n)" |
949 "Divides.divmod_nat m n = (m div n, m mod n)" |
926 by (simp add: prod_eq_iff) |
950 by (simp add: prod_eq_iff) |
927 |
951 |
928 lemma div_nat_unique: |
952 lemma div_nat_unique: |
929 assumes "divmod_nat_rel m n (q, r)" |
953 assumes "divmod_nat_rel m n (q, r)" |
930 shows "m div n = q" |
954 shows "m div n = q" |
931 using assms by (auto dest!: divmod_nat_unique simp add: prod_eq_iff) |
955 using assms by (auto dest!: Divides.divmod_nat_unique simp add: prod_eq_iff) |
932 |
956 |
933 lemma mod_nat_unique: |
957 lemma mod_nat_unique: |
934 assumes "divmod_nat_rel m n (q, r)" |
958 assumes "divmod_nat_rel m n (q, r)" |
935 shows "m mod n = r" |
959 shows "m mod n = r" |
936 using assms by (auto dest!: divmod_nat_unique simp add: prod_eq_iff) |
960 using assms by (auto dest!: Divides.divmod_nat_unique simp add: prod_eq_iff) |
937 |
961 |
938 lemma divmod_nat_rel: "divmod_nat_rel m n (m div n, m mod n)" |
962 lemma divmod_nat_rel: "divmod_nat_rel m n (m div n, m mod n)" |
939 using divmod_nat_rel_divmod_nat by (simp add: divmod_nat_div_mod) |
963 using Divides.divmod_nat_rel_divmod_nat by (simp add: divmod_nat_div_mod) |
940 |
|
941 lemma divmod_nat_zero: "divmod_nat m 0 = (0, m)" |
|
942 by (simp add: divmod_nat_unique divmod_nat_rel_def) |
|
943 |
|
944 lemma divmod_nat_zero_left: "divmod_nat 0 n = (0, 0)" |
|
945 by (simp add: divmod_nat_unique divmod_nat_rel_def) |
|
946 |
|
947 lemma divmod_nat_base: "m < n \<Longrightarrow> divmod_nat m n = (0, m)" |
|
948 by (simp add: divmod_nat_unique divmod_nat_rel_def) |
|
949 |
|
950 lemma divmod_nat_step: |
|
951 assumes "0 < n" and "n \<le> m" |
|
952 shows "divmod_nat m n = (Suc ((m - n) div n), (m - n) mod n)" |
|
953 proof (rule divmod_nat_unique) |
|
954 have "divmod_nat_rel (m - n) n ((m - n) div n, (m - n) mod n)" |
|
955 by (rule divmod_nat_rel) |
|
956 thus "divmod_nat_rel m n (Suc ((m - n) div n), (m - n) mod n)" |
|
957 unfolding divmod_nat_rel_def using assms by auto |
|
958 qed |
|
959 |
964 |
960 text \<open>The ''recursion'' equations for @{const divide} and @{const mod}\<close> |
965 text \<open>The ''recursion'' equations for @{const divide} and @{const mod}\<close> |
961 |
966 |
962 lemma div_less [simp]: |
967 lemma div_less [simp]: |
963 fixes m n :: nat |
968 fixes m n :: nat |
964 assumes "m < n" |
969 assumes "m < n" |
965 shows "m div n = 0" |
970 shows "m div n = 0" |
966 using assms divmod_nat_base by (simp add: prod_eq_iff) |
971 using assms Divides.divmod_nat_base by (simp add: prod_eq_iff) |
967 |
972 |
968 lemma le_div_geq: |
973 lemma le_div_geq: |
969 fixes m n :: nat |
974 fixes m n :: nat |
970 assumes "0 < n" and "n \<le> m" |
975 assumes "0 < n" and "n \<le> m" |
971 shows "m div n = Suc ((m - n) div n)" |
976 shows "m div n = Suc ((m - n) div n)" |
972 using assms divmod_nat_step by (simp add: prod_eq_iff) |
977 using assms Divides.divmod_nat_step by (simp add: prod_eq_iff) |
973 |
978 |
974 lemma mod_less [simp]: |
979 lemma mod_less [simp]: |
975 fixes m n :: nat |
980 fixes m n :: nat |
976 assumes "m < n" |
981 assumes "m < n" |
977 shows "m mod n = m" |
982 shows "m mod n = m" |
978 using assms divmod_nat_base by (simp add: prod_eq_iff) |
983 using assms Divides.divmod_nat_base by (simp add: prod_eq_iff) |
979 |
984 |
980 lemma le_mod_geq: |
985 lemma le_mod_geq: |
981 fixes m n :: nat |
986 fixes m n :: nat |
982 assumes "n \<le> m" |
987 assumes "n \<le> m" |
983 shows "m mod n = (m - n) mod n" |
988 shows "m mod n = (m - n) mod n" |
984 using assms divmod_nat_step by (cases "n = 0") (simp_all add: prod_eq_iff) |
989 using assms Divides.divmod_nat_step by (cases "n = 0") (simp_all add: prod_eq_iff) |
985 |
990 |
986 instance proof |
991 instance proof |
987 fix m n :: nat |
992 fix m n :: nat |
988 show "m div n * n + m mod n = m" |
993 show "m div n * n + m mod n = m" |
989 using divmod_nat_rel [of m n] by (simp add: divmod_nat_rel_def) |
994 using divmod_nat_rel [of m n] by (simp add: divmod_nat_rel_def) |