src/HOL/Nat.thy
changeset 57512 cc97b347b301
parent 57492 74bf65a1910a
child 57514 bdc2c6b40bf2
equal deleted inserted replaced
57511:de51a86fc903 57512:cc97b347b301
   242 
   242 
   243 lemma mult_0_right [simp]: "(m::nat) * 0 = 0"
   243 lemma mult_0_right [simp]: "(m::nat) * 0 = 0"
   244   by (induct m) simp_all
   244   by (induct m) simp_all
   245 
   245 
   246 lemma mult_Suc_right [simp]: "m * Suc n = m + (m * n)"
   246 lemma mult_Suc_right [simp]: "m * Suc n = m + (m * n)"
   247   by (induct m) (simp_all add: add_left_commute)
   247   by (induct m) (simp_all add: add.left_commute)
   248 
   248 
   249 lemma add_mult_distrib: "(m + n) * k = (m * k) + ((n * k)::nat)"
   249 lemma add_mult_distrib: "(m + n) * k = (m * k) + ((n * k)::nat)"
   250   by (induct m) (simp_all add: add_assoc)
   250   by (induct m) (simp_all add: add.assoc)
   251 
   251 
   252 instance proof
   252 instance proof
   253   fix n m q :: nat
   253   fix n m q :: nat
   254   show "0 \<noteq> (1::nat)" unfolding One_nat_def by simp
   254   show "0 \<noteq> (1::nat)" unfolding One_nat_def by simp
   255   show "1 * n = n" unfolding One_nat_def by simp
   255   show "1 * n = n" unfolding One_nat_def by simp
   261 
   261 
   262 end
   262 end
   263 
   263 
   264 subsubsection {* Addition *}
   264 subsubsection {* Addition *}
   265 
   265 
   266 lemma nat_add_assoc: "(m + n) + k = m + ((n + k)::nat)"
   266 lemma nat_add_left_cancel:
   267   by (rule add_assoc)
   267   fixes k m n :: nat
   268 
   268   shows "k + m = k + n \<longleftrightarrow> m = n"
   269 lemma nat_add_commute: "m + n = n + (m::nat)"
   269   by (fact add_left_cancel)
   270   by (rule add_commute)
   270 
   271 
   271 lemma nat_add_right_cancel:
   272 lemma nat_add_left_commute: "x + (y + z) = y + ((x + z)::nat)"
   272   fixes k m n :: nat
   273   by (rule add_left_commute)
   273   shows "m + k = n + k \<longleftrightarrow> m = n"
   274 
   274   by (fact add_right_cancel)
   275 lemma nat_add_left_cancel [simp]: "(k + m = k + n) = (m = (n::nat))"
       
   276   by (rule add_left_cancel)
       
   277 
       
   278 lemma nat_add_right_cancel [simp]: "(m + k = n + k) = (m=(n::nat))"
       
   279   by (rule add_right_cancel)
       
   280 
   275 
   281 text {* Reasoning about @{text "m + 0 = 0"}, etc. *}
   276 text {* Reasoning about @{text "m + 0 = 0"}, etc. *}
   282 
   277 
   283 lemma add_is_0 [iff]:
   278 lemma add_is_0 [iff]:
   284   fixes m n :: nat
   279   fixes m n :: nat
   313 
   308 
   314 
   309 
   315 subsubsection {* Difference *}
   310 subsubsection {* Difference *}
   316 
   311 
   317 lemma diff_self_eq_0 [simp]: "(m\<Colon>nat) - m = 0"
   312 lemma diff_self_eq_0 [simp]: "(m\<Colon>nat) - m = 0"
   318   by (induct m) simp_all
   313   by (fact diff_cancel)
   319 
   314 
   320 lemma diff_diff_left: "(i::nat) - j - k = i - (j + k)"
   315 lemma diff_diff_left: "(i::nat) - j - k = i - (j + k)"
   321   by (induct i j rule: diff_induct) simp_all
   316   by (fact diff_diff_add)
   322 
   317 
   323 lemma Suc_diff_diff [simp]: "(Suc m - n) - Suc k = m - n - k"
   318 lemma Suc_diff_diff [simp]: "(Suc m - n) - Suc k = m - n - k"
   324   by (simp add: diff_diff_left)
   319   by (simp add: diff_diff_left)
   325 
   320 
   326 lemma diff_commute: "(i::nat) - j - k = i - k - j"
   321 lemma diff_commute: "(i::nat) - j - k = i - k - j"
   327   by (simp add: diff_diff_left add_commute)
   322   by (fact diff_right_commute)
   328 
   323 
   329 lemma diff_add_inverse: "(n + m) - n = (m::nat)"
   324 lemma diff_add_inverse: "(n + m) - n = (m::nat)"
   330   by (induct n) simp_all
   325   by (fact add_diff_cancel_left')
   331 
   326 
   332 lemma diff_add_inverse2: "(m + n) - n = (m::nat)"
   327 lemma diff_add_inverse2: "(m + n) - n = (m::nat)"
   333   by (simp add: diff_add_inverse add_commute [of m n])
   328   by (fact add_diff_cancel_right')
   334 
   329 
   335 lemma diff_cancel: "(k + m) - (k + n) = m - (n::nat)"
   330 lemma diff_cancel: "(k + m) - (k + n) = m - (n::nat)"
   336   by (induct k) simp_all
   331   by (fact comm_monoid_diff_class.add_diff_cancel_left)
   337 
   332 
   338 lemma diff_cancel2: "(m + k) - (n + k) = m - (n::nat)"
   333 lemma diff_cancel2: "(m + k) - (n + k) = m - (n::nat)"
   339   by (simp add: diff_cancel add_commute)
   334   by (fact add_diff_cancel_right)
   340 
   335 
   341 lemma diff_add_0: "n - (n + m) = (0::nat)"
   336 lemma diff_add_0: "n - (n + m) = (0::nat)"
   342   by (induct n) simp_all
   337   by (fact diff_add_zero)
   343 
   338 
   344 lemma diff_Suc_1 [simp]: "Suc n - 1 = n"
   339 lemma diff_Suc_1 [simp]: "Suc n - 1 = n"
   345   unfolding One_nat_def by simp
   340   unfolding One_nat_def by simp
   346 
   341 
   347 text {* Difference distributes over multiplication *}
   342 text {* Difference distributes over multiplication *}
   348 
   343 
   349 lemma diff_mult_distrib: "((m::nat) - n) * k = (m * k) - (n * k)"
   344 lemma diff_mult_distrib: "((m::nat) - n) * k = (m * k) - (n * k)"
   350 by (induct m n rule: diff_induct) (simp_all add: diff_cancel)
   345 by (induct m n rule: diff_induct) (simp_all add: diff_cancel)
   351 
   346 
   352 lemma diff_mult_distrib2: "k * ((m::nat) - n) = (k * m) - (k * n)"
   347 lemma diff_mult_distrib2: "k * ((m::nat) - n) = (k * m) - (k * n)"
   353 by (simp add: diff_mult_distrib mult_commute [of k])
   348 by (simp add: diff_mult_distrib mult.commute [of k])
   354   -- {* NOT added as rewrites, since sometimes they are used from right-to-left *}
   349   -- {* NOT added as rewrites, since sometimes they are used from right-to-left *}
   355 
   350 
   356 
   351 
   357 subsubsection {* Multiplication *}
   352 subsubsection {* Multiplication *}
   358 
   353 
   359 lemma nat_mult_assoc: "(m * n) * k = m * ((n * k)::nat)"
       
   360   by (rule mult_assoc)
       
   361 
       
   362 lemma nat_mult_commute: "m * n = n * (m::nat)"
       
   363   by (rule mult_commute)
       
   364 
       
   365 lemma add_mult_distrib2: "k * (m + n) = (k * m) + ((k * n)::nat)"
   354 lemma add_mult_distrib2: "k * (m + n) = (k * m) + ((k * n)::nat)"
   366   by (rule distrib_left)
   355   by (fact distrib_left)
   367 
   356 
   368 lemma mult_is_0 [simp]: "((m::nat) * n = 0) = (m=0 | n=0)"
   357 lemma mult_is_0 [simp]: "((m::nat) * n = 0) = (m=0 | n=0)"
   369   by (induct m) auto
   358   by (induct m) auto
   370 
   359 
   371 lemmas nat_distrib =
   360 lemmas nat_distrib =
   400   qed
   389   qed
   401   then show ?thesis by auto
   390   then show ?thesis by auto
   402 qed
   391 qed
   403 
   392 
   404 lemma mult_cancel2 [simp]: "(m * k = n * k) = (m = n | (k = (0::nat)))"
   393 lemma mult_cancel2 [simp]: "(m * k = n * k) = (m = n | (k = (0::nat)))"
   405   by (simp add: mult_commute)
   394   by (simp add: mult.commute)
   406 
   395 
   407 lemma Suc_mult_cancel1: "(Suc k * m = Suc k * n) = (m = n)"
   396 lemma Suc_mult_cancel1: "(Suc k * m = Suc k * n) = (m = n)"
   408   by (subst mult_cancel1) simp
   397   by (subst mult_cancel1) simp
   409 
   398 
   410 
   399 
   948     case 0
   937     case 0
   949     show ?case by (simp add: step)
   938     show ?case by (simp add: step)
   950   next
   939   next
   951     case (Suc k)
   940     case (Suc k)
   952     have "0 + i < Suc k + i" by (rule add_less_mono1) simp
   941     have "0 + i < Suc k + i" by (rule add_less_mono1) simp
   953     hence "i < Suc (i + k)" by (simp add: add_commute)
   942     hence "i < Suc (i + k)" by (simp add: add.commute)
   954     from trans[OF this lessI Suc step]
   943     from trans[OF this lessI Suc step]
   955     show ?case by simp
   944     show ?case by simp
   956   qed
   945   qed
   957   thus "P i j" by (simp add: j)
   946   thus "P i j" by (simp add: j)
   958 qed
   947 qed
  1034 
  1023 
  1035 lemma le_add2: "n \<le> ((m + n)::nat)"
  1024 lemma le_add2: "n \<le> ((m + n)::nat)"
  1036 by (insert add_right_mono [of 0 m n], simp)
  1025 by (insert add_right_mono [of 0 m n], simp)
  1037 
  1026 
  1038 lemma le_add1: "n \<le> ((n + m)::nat)"
  1027 lemma le_add1: "n \<le> ((n + m)::nat)"
  1039 by (simp add: add_commute, rule le_add2)
  1028 by (simp add: add.commute, rule le_add2)
  1040 
  1029 
  1041 lemma less_add_Suc1: "i < Suc (i + m)"
  1030 lemma less_add_Suc1: "i < Suc (i + m)"
  1042 by (rule le_less_trans, rule le_add1, rule lessI)
  1031 by (rule le_less_trans, rule le_add1, rule lessI)
  1043 
  1032 
  1044 lemma less_add_Suc2: "i < Suc (m + i)"
  1033 lemma less_add_Suc2: "i < Suc (m + i)"
  1069 apply (drule add_lessD1)
  1058 apply (drule add_lessD1)
  1070 apply (erule less_irrefl [THEN notE])
  1059 apply (erule less_irrefl [THEN notE])
  1071 done
  1060 done
  1072 
  1061 
  1073 lemma not_add_less2 [iff]: "~ (j + i < (i::nat))"
  1062 lemma not_add_less2 [iff]: "~ (j + i < (i::nat))"
  1074 by (simp add: add_commute)
  1063 by (simp add: add.commute)
  1075 
  1064 
  1076 lemma add_leD1: "m + k \<le> n ==> m \<le> (n::nat)"
  1065 lemma add_leD1: "m + k \<le> n ==> m \<le> (n::nat)"
  1077 apply (rule order_trans [of _ "m+k"])
  1066 apply (rule order_trans [of _ "m+k"])
  1078 apply (simp_all add: le_add1)
  1067 apply (simp_all add: le_add1)
  1079 done
  1068 done
  1080 
  1069 
  1081 lemma add_leD2: "m + k \<le> n ==> k \<le> (n::nat)"
  1070 lemma add_leD2: "m + k \<le> n ==> k \<le> (n::nat)"
  1082 apply (simp add: add_commute)
  1071 apply (simp add: add.commute)
  1083 apply (erule add_leD1)
  1072 apply (erule add_leD1)
  1084 done
  1073 done
  1085 
  1074 
  1086 lemma add_leE: "(m::nat) + k \<le> n ==> (m \<le> n ==> k \<le> n ==> R) ==> R"
  1075 lemma add_leE: "(m::nat) + k \<le> n ==> (m \<le> n ==> k \<le> n ==> R) ==> R"
  1087 by (blast dest: add_leD1 add_leD2)
  1076 by (blast dest: add_leD1 add_leD2)
  1101 
  1090 
  1102 lemma le_add_diff_inverse [simp]: "n \<le> m ==> n + (m - n) = (m::nat)"
  1091 lemma le_add_diff_inverse [simp]: "n \<le> m ==> n + (m - n) = (m::nat)"
  1103 by (simp add: add_diff_inverse linorder_not_less)
  1092 by (simp add: add_diff_inverse linorder_not_less)
  1104 
  1093 
  1105 lemma le_add_diff_inverse2 [simp]: "n \<le> m ==> (m - n) + n = (m::nat)"
  1094 lemma le_add_diff_inverse2 [simp]: "n \<le> m ==> (m - n) + n = (m::nat)"
  1106 by (simp add: add_commute)
  1095 by (simp add: add.commute)
  1107 
  1096 
  1108 lemma Suc_diff_le: "n \<le> m ==> Suc m - n = Suc (m - n)"
  1097 lemma Suc_diff_le: "n \<le> m ==> Suc m - n = Suc (m - n)"
  1109 by (induct m n rule: diff_induct) simp_all
  1098 by (induct m n rule: diff_induct) simp_all
  1110 
  1099 
  1111 lemma diff_less_Suc: "m - n < Suc m"
  1100 lemma diff_less_Suc: "m - n < Suc m"
  1133 
  1122 
  1134 lemma diff_add_assoc: "k \<le> (j::nat) ==> (i + j) - k = i + (j - k)"
  1123 lemma diff_add_assoc: "k \<le> (j::nat) ==> (i + j) - k = i + (j - k)"
  1135 by (induct j k rule: diff_induct) simp_all
  1124 by (induct j k rule: diff_induct) simp_all
  1136 
  1125 
  1137 lemma diff_add_assoc2: "k \<le> (j::nat) ==> (j + i) - k = (j - k) + i"
  1126 lemma diff_add_assoc2: "k \<le> (j::nat) ==> (j + i) - k = (j - k) + i"
  1138 by (simp add: add_commute diff_add_assoc)
  1127 by (simp add: add.commute diff_add_assoc)
  1139 
  1128 
  1140 lemma le_imp_diff_is_add: "i \<le> (j::nat) ==> (j - i = k) = (j = k + i)"
  1129 lemma le_imp_diff_is_add: "i \<le> (j::nat) ==> (j - i = k) = (j = k + i)"
  1141 by (auto simp add: diff_add_inverse2)
  1130 by (auto simp add: diff_add_inverse2)
  1142 
  1131 
  1143 lemma diff_is_0_eq [simp]: "((m::nat) - n = 0) = (m \<le> n)"
  1132 lemma diff_is_0_eq [simp]: "((m::nat) - n = 0) = (m \<le> n)"
  1231   apply (simp del: le_0_eq add: linorder_not_le [symmetric])
  1220   apply (simp del: le_0_eq add: linorder_not_le [symmetric])
  1232   apply (blast intro: mult_le_mono1)
  1221   apply (blast intro: mult_le_mono1)
  1233   done
  1222   done
  1234 
  1223 
  1235 lemma mult_less_cancel1 [simp]: "(k * (m::nat) < k * n) = (0 < k & m < n)"
  1224 lemma mult_less_cancel1 [simp]: "(k * (m::nat) < k * n) = (0 < k & m < n)"
  1236 by (simp add: mult_commute [of k])
  1225 by (simp add: mult.commute [of k])
  1237 
  1226 
  1238 lemma mult_le_cancel1 [simp]: "(k * (m::nat) \<le> k * n) = (0 < k --> m \<le> n)"
  1227 lemma mult_le_cancel1 [simp]: "(k * (m::nat) \<le> k * n) = (0 < k --> m \<le> n)"
  1239 by (simp add: linorder_not_less [symmetric], auto)
  1228 by (simp add: linorder_not_less [symmetric], auto)
  1240 
  1229 
  1241 lemma mult_le_cancel2 [simp]: "((m::nat) * k \<le> n * k) = (0 < k --> m \<le> n)"
  1230 lemma mult_le_cancel2 [simp]: "((m::nat) * k \<le> n * k) = (0 < k --> m \<le> n)"
  1433   case (Suc n)
  1422   case (Suc n)
  1434   have "\<And>i. of_nat_aux (\<lambda>i. i + 1) n (i + 1) = of_nat_aux (\<lambda>i. i + 1) n i + 1"
  1423   have "\<And>i. of_nat_aux (\<lambda>i. i + 1) n (i + 1) = of_nat_aux (\<lambda>i. i + 1) n i + 1"
  1435     by (induct n) simp_all
  1424     by (induct n) simp_all
  1436   from this [of 0] have "of_nat_aux (\<lambda>i. i + 1) n 1 = of_nat_aux (\<lambda>i. i + 1) n 0 + 1"
  1425   from this [of 0] have "of_nat_aux (\<lambda>i. i + 1) n 1 = of_nat_aux (\<lambda>i. i + 1) n 0 + 1"
  1437     by simp
  1426     by simp
  1438   with Suc show ?case by (simp add: add_commute)
  1427   with Suc show ?case by (simp add: add.commute)
  1439 qed
  1428 qed
  1440 
  1429 
  1441 end
  1430 end
  1442 
  1431 
  1443 declare of_nat_code [code]
  1432 declare of_nat_code [code]
  1691 
  1680 
  1692 lemma le_diff_conv: "(j-k \<le> (i::nat)) = (j \<le> i+k)"
  1681 lemma le_diff_conv: "(j-k \<le> (i::nat)) = (j \<le> i+k)"
  1693 by arith
  1682 by arith
  1694 
  1683 
  1695 lemma le_diff_conv2: "k \<le> j ==> (i \<le> j-k) = (i+k \<le> (j::nat))"
  1684 lemma le_diff_conv2: "k \<le> j ==> (i \<le> j-k) = (i+k \<le> (j::nat))"
  1696 by arith
  1685   by (fact le_diff_conv2) -- {* FIXME delete *}
  1697 
  1686 
  1698 lemma diff_diff_cancel [simp]: "i \<le> (n::nat) ==> n - (n - i) = i"
  1687 lemma diff_diff_cancel [simp]: "i \<le> (n::nat) ==> n - (n - i) = i"
  1699 by arith
  1688 by arith
  1700 
  1689 
  1701 lemma le_add_diff: "k \<le> (n::nat) ==> m \<le> n + m - k"
  1690 lemma le_add_diff: "k \<le> (n::nat) ==> m \<le> n + m - k"
  1702 by arith
  1691   by (fact le_add_diff) -- {* FIXME delete *}
  1703 
  1692 
  1704 (*Replaces the previous diff_less and le_diff_less, which had the stronger
  1693 (*Replaces the previous diff_less and le_diff_less, which had the stronger
  1705   second premise n\<le>m*)
  1694   second premise n\<le>m*)
  1706 lemma diff_less[simp]: "!!m::nat. [| 0<n; 0<m |] ==> m - n < m"
  1695 lemma diff_less[simp]: "!!m::nat. [| 0<n; 0<m |] ==> m - n < m"
  1707 by arith
  1696 by arith
  1845 lemma nat_dvd_1_iff_1 [simp]: "m dvd (1::nat) \<longleftrightarrow> m = 1"
  1834 lemma nat_dvd_1_iff_1 [simp]: "m dvd (1::nat) \<longleftrightarrow> m = 1"
  1846 by (simp add: dvd_def)
  1835 by (simp add: dvd_def)
  1847 
  1836 
  1848 lemma dvd_antisym: "[| m dvd n; n dvd m |] ==> m = (n::nat)"
  1837 lemma dvd_antisym: "[| m dvd n; n dvd m |] ==> m = (n::nat)"
  1849   unfolding dvd_def
  1838   unfolding dvd_def
  1850   by (force dest: mult_eq_self_implies_10 simp add: mult_assoc)
  1839   by (force dest: mult_eq_self_implies_10 simp add: mult.assoc)
  1851 
  1840 
  1852 text {* @{term "op dvd"} is a partial order *}
  1841 text {* @{term "op dvd"} is a partial order *}
  1853 
  1842 
  1854 interpretation dvd: order "op dvd" "\<lambda>n m \<Colon> nat. n dvd m \<and> \<not> m dvd n"
  1843 interpretation dvd: order "op dvd" "\<lambda>n m \<Colon> nat. n dvd m \<and> \<not> m dvd n"
  1855   proof qed (auto intro: dvd_refl dvd_trans dvd_antisym)
  1844   proof qed (auto intro: dvd_refl dvd_trans dvd_antisym)
  1888    apply (subgoal_tac "m*n dvd m*1")
  1877    apply (subgoal_tac "m*n dvd m*1")
  1889    apply (drule dvd_mult_cancel, auto)
  1878    apply (drule dvd_mult_cancel, auto)
  1890   done
  1879   done
  1891 
  1880 
  1892 lemma dvd_mult_cancel2: "0<m ==> (n*m dvd m) = (n = (1::nat))"
  1881 lemma dvd_mult_cancel2: "0<m ==> (n*m dvd m) = (n = (1::nat))"
  1893   apply (subst mult_commute)
  1882   apply (subst mult.commute)
  1894   apply (erule dvd_mult_cancel1)
  1883   apply (erule dvd_mult_cancel1)
  1895   done
  1884   done
  1896 
  1885 
  1897 lemma dvd_imp_le: "[| k dvd n; 0 < n |] ==> k \<le> (n::nat)"
  1886 lemma dvd_imp_le: "[| k dvd n; 0 < n |] ==> k \<le> (n::nat)"
  1898 by (auto elim!: dvdE) (auto simp add: gr0_conv_Suc)
  1887 by (auto elim!: dvdE) (auto simp add: gr0_conv_Suc)
  1938 
  1927 
  1939 lemma dvd_plus_eq_left:
  1928 lemma dvd_plus_eq_left:
  1940   fixes m n q :: nat
  1929   fixes m n q :: nat
  1941   assumes "m dvd q"
  1930   assumes "m dvd q"
  1942   shows "m dvd n + q \<longleftrightarrow> m dvd n"
  1931   shows "m dvd n + q \<longleftrightarrow> m dvd n"
  1943   using assms by (simp add: dvd_plus_eq_right add_commute [of n])
  1932   using assms by (simp add: dvd_plus_eq_right add.commute [of n])
  1944 
  1933 
  1945 lemma less_eq_dvd_minus:
  1934 lemma less_eq_dvd_minus:
  1946   fixes m n :: nat
  1935   fixes m n :: nat
  1947   assumes "m \<le> n"
  1936   assumes "m \<le> n"
  1948   shows "m dvd n \<longleftrightarrow> m dvd n - m"
  1937   shows "m dvd n \<longleftrightarrow> m dvd n - m"
  1949 proof -
  1938 proof -
  1950   from assms have "n = m + (n - m)" by simp
  1939   from assms have "n = m + (n - m)" by simp
  1951   then obtain q where "n = m + q" ..
  1940   then obtain q where "n = m + q" ..
  1952   then show ?thesis by (simp add: dvd_reduce add_commute [of m])
  1941   then show ?thesis by (simp add: dvd_reduce add.commute [of m])
  1953 qed
  1942 qed
  1954 
  1943 
  1955 lemma dvd_minus_self:
  1944 lemma dvd_minus_self:
  1956   fixes m n :: nat
  1945   fixes m n :: nat
  1957   shows "m dvd n - m \<longleftrightarrow> n < m \<or> m dvd n"
  1946   shows "m dvd n - m \<longleftrightarrow> n < m \<or> m dvd n"
  1964 proof -
  1953 proof -
  1965   have "m dvd n - q \<longleftrightarrow> m dvd r * m + (n - q)"
  1954   have "m dvd n - q \<longleftrightarrow> m dvd r * m + (n - q)"
  1966     by (auto elim: dvd_plusE)
  1955     by (auto elim: dvd_plusE)
  1967   also from assms have "\<dots> \<longleftrightarrow> m dvd r * m + n - q" by simp
  1956   also from assms have "\<dots> \<longleftrightarrow> m dvd r * m + n - q" by simp
  1968   also from assms have "\<dots> \<longleftrightarrow> m dvd (r * m - q) + n" by simp
  1957   also from assms have "\<dots> \<longleftrightarrow> m dvd (r * m - q) + n" by simp
  1969   also have "\<dots> \<longleftrightarrow> m dvd n + (r * m - q)" by (simp add: add_commute)
  1958   also have "\<dots> \<longleftrightarrow> m dvd n + (r * m - q)" by (simp add: add.commute)
  1970   finally show ?thesis .
  1959   finally show ?thesis .
  1971 qed
  1960 qed
  1972 
  1961 
  1973 
  1962 
  1974 subsection {* aliases *}
  1963 subsection {* aliases *}