| author | paulson <lp15@cam.ac.uk> | 
| Thu, 05 Mar 2015 17:39:04 +0000 | |
| changeset 59614 | 452458cf8506 | 
| parent 58889 | 5b7a9633cfa8 | 
| child 61076 | bdc1e2f0a86a | 
| permissions | -rw-r--r-- | 
| 47654 | 1 | (* Title: HOL/ex/Transfer_Int_Nat.thy | 
| 2 | Author: Brian Huffman, TU Muenchen | |
| 3 | *) | |
| 4 | ||
| 58889 | 5 | section {* Using the transfer method between nat and int *}
 | 
| 47654 | 6 | |
| 7 | theory Transfer_Int_Nat | |
| 53013 
3fbcfa911863
remove unnecessary dependencies on Library/Quotient_*
 kuncar parents: 
52360diff
changeset | 8 | imports GCD | 
| 47654 | 9 | begin | 
| 10 | ||
| 11 | subsection {* Correspondence relation *}
 | |
| 12 | ||
| 13 | definition ZN :: "int \<Rightarrow> nat \<Rightarrow> bool" | |
| 14 | where "ZN = (\<lambda>z n. z = of_nat n)" | |
| 15 | ||
| 51956 
a4d81cdebf8b
better support for domains in Lifting/Transfer = replace Domainp T by the actual invariant in a transferred goal
 kuncar parents: 
47654diff
changeset | 16 | subsection {* Transfer domain rules *}
 | 
| 
a4d81cdebf8b
better support for domains in Lifting/Transfer = replace Domainp T by the actual invariant in a transferred goal
 kuncar parents: 
47654diff
changeset | 17 | |
| 
a4d81cdebf8b
better support for domains in Lifting/Transfer = replace Domainp T by the actual invariant in a transferred goal
 kuncar parents: 
47654diff
changeset | 18 | lemma Domainp_ZN [transfer_domain_rule]: "Domainp ZN = (\<lambda>x. x \<ge> 0)" | 
| 
a4d81cdebf8b
better support for domains in Lifting/Transfer = replace Domainp T by the actual invariant in a transferred goal
 kuncar parents: 
47654diff
changeset | 19 | unfolding ZN_def Domainp_iff[abs_def] by (auto intro: zero_le_imp_eq_int) | 
| 
a4d81cdebf8b
better support for domains in Lifting/Transfer = replace Domainp T by the actual invariant in a transferred goal
 kuncar parents: 
47654diff
changeset | 20 | |
| 47654 | 21 | subsection {* Transfer rules *}
 | 
| 22 | ||
| 53013 
3fbcfa911863
remove unnecessary dependencies on Library/Quotient_*
 kuncar parents: 
52360diff
changeset | 23 | context | 
| 
3fbcfa911863
remove unnecessary dependencies on Library/Quotient_*
 kuncar parents: 
52360diff
changeset | 24 | begin | 
| 
3fbcfa911863
remove unnecessary dependencies on Library/Quotient_*
 kuncar parents: 
52360diff
changeset | 25 | interpretation lifting_syntax . | 
| 
3fbcfa911863
remove unnecessary dependencies on Library/Quotient_*
 kuncar parents: 
52360diff
changeset | 26 | |
| 47654 | 27 | lemma bi_unique_ZN [transfer_rule]: "bi_unique ZN" | 
| 28 | unfolding ZN_def bi_unique_def by simp | |
| 29 | ||
| 30 | lemma right_total_ZN [transfer_rule]: "right_total ZN" | |
| 31 | unfolding ZN_def right_total_def by simp | |
| 32 | ||
| 33 | lemma ZN_0 [transfer_rule]: "ZN 0 0" | |
| 34 | unfolding ZN_def by simp | |
| 35 | ||
| 36 | lemma ZN_1 [transfer_rule]: "ZN 1 1" | |
| 37 | unfolding ZN_def by simp | |
| 38 | ||
| 39 | lemma ZN_add [transfer_rule]: "(ZN ===> ZN ===> ZN) (op +) (op +)" | |
| 55945 | 40 | unfolding rel_fun_def ZN_def by simp | 
| 47654 | 41 | |
| 42 | lemma ZN_mult [transfer_rule]: "(ZN ===> ZN ===> ZN) (op *) (op *)" | |
| 55945 | 43 | unfolding rel_fun_def ZN_def by (simp add: int_mult) | 
| 47654 | 44 | |
| 45 | lemma ZN_diff [transfer_rule]: "(ZN ===> ZN ===> ZN) tsub (op -)" | |
| 55945 | 46 | unfolding rel_fun_def ZN_def tsub_def by (simp add: zdiff_int) | 
| 47654 | 47 | |
| 48 | lemma ZN_power [transfer_rule]: "(ZN ===> op = ===> ZN) (op ^) (op ^)" | |
| 55945 | 49 | unfolding rel_fun_def ZN_def by (simp add: int_power) | 
| 47654 | 50 | |
| 51 | lemma ZN_nat_id [transfer_rule]: "(ZN ===> op =) nat id" | |
| 55945 | 52 | unfolding rel_fun_def ZN_def by simp | 
| 47654 | 53 | |
| 54 | lemma ZN_id_int [transfer_rule]: "(ZN ===> op =) id int" | |
| 55945 | 55 | unfolding rel_fun_def ZN_def by simp | 
| 47654 | 56 | |
| 57 | lemma ZN_All [transfer_rule]: | |
| 58 |   "((ZN ===> op =) ===> op =) (Ball {0..}) All"
 | |
| 55945 | 59 | unfolding rel_fun_def ZN_def by (auto dest: zero_le_imp_eq_int) | 
| 47654 | 60 | |
| 61 | lemma ZN_transfer_forall [transfer_rule]: | |
| 62 | "((ZN ===> op =) ===> op =) (transfer_bforall (\<lambda>x. 0 \<le> x)) transfer_forall" | |
| 63 | unfolding transfer_forall_def transfer_bforall_def | |
| 55945 | 64 | unfolding rel_fun_def ZN_def by (auto dest: zero_le_imp_eq_int) | 
| 47654 | 65 | |
| 66 | lemma ZN_Ex [transfer_rule]: "((ZN ===> op =) ===> op =) (Bex {0..}) Ex"
 | |
| 55945 | 67 | unfolding rel_fun_def ZN_def Bex_def atLeast_iff | 
| 47654 | 68 | by (metis zero_le_imp_eq_int zero_zle_int) | 
| 69 | ||
| 70 | lemma ZN_le [transfer_rule]: "(ZN ===> ZN ===> op =) (op \<le>) (op \<le>)" | |
| 55945 | 71 | unfolding rel_fun_def ZN_def by simp | 
| 47654 | 72 | |
| 73 | lemma ZN_less [transfer_rule]: "(ZN ===> ZN ===> op =) (op <) (op <)" | |
| 55945 | 74 | unfolding rel_fun_def ZN_def by simp | 
| 47654 | 75 | |
| 76 | lemma ZN_eq [transfer_rule]: "(ZN ===> ZN ===> op =) (op =) (op =)" | |
| 55945 | 77 | unfolding rel_fun_def ZN_def by simp | 
| 47654 | 78 | |
| 79 | lemma ZN_Suc [transfer_rule]: "(ZN ===> ZN) (\<lambda>x. x + 1) Suc" | |
| 55945 | 80 | unfolding rel_fun_def ZN_def by simp | 
| 47654 | 81 | |
| 82 | lemma ZN_numeral [transfer_rule]: | |
| 83 | "(op = ===> ZN) numeral numeral" | |
| 55945 | 84 | unfolding rel_fun_def ZN_def by simp | 
| 47654 | 85 | |
| 86 | lemma ZN_dvd [transfer_rule]: "(ZN ===> ZN ===> op =) (op dvd) (op dvd)" | |
| 55945 | 87 | unfolding rel_fun_def ZN_def by (simp add: zdvd_int) | 
| 47654 | 88 | |
| 89 | lemma ZN_div [transfer_rule]: "(ZN ===> ZN ===> ZN) (op div) (op div)" | |
| 55945 | 90 | unfolding rel_fun_def ZN_def by (simp add: zdiv_int) | 
| 47654 | 91 | |
| 92 | lemma ZN_mod [transfer_rule]: "(ZN ===> ZN ===> ZN) (op mod) (op mod)" | |
| 55945 | 93 | unfolding rel_fun_def ZN_def by (simp add: zmod_int) | 
| 47654 | 94 | |
| 95 | lemma ZN_gcd [transfer_rule]: "(ZN ===> ZN ===> ZN) gcd gcd" | |
| 55945 | 96 | unfolding rel_fun_def ZN_def by (simp add: transfer_int_nat_gcd) | 
| 47654 | 97 | |
| 52360 
ac7ac2b242a2
more int/nat transfer rules; examples of new untransferred attribute
 huffman parents: 
51956diff
changeset | 98 | lemma ZN_atMost [transfer_rule]: | 
| 55938 | 99 | "(ZN ===> rel_set ZN) (atLeastAtMost 0) atMost" | 
| 55945 | 100 | unfolding rel_fun_def ZN_def rel_set_def | 
| 52360 
ac7ac2b242a2
more int/nat transfer rules; examples of new untransferred attribute
 huffman parents: 
51956diff
changeset | 101 | by (clarsimp simp add: Bex_def, arith) | 
| 
ac7ac2b242a2
more int/nat transfer rules; examples of new untransferred attribute
 huffman parents: 
51956diff
changeset | 102 | |
| 
ac7ac2b242a2
more int/nat transfer rules; examples of new untransferred attribute
 huffman parents: 
51956diff
changeset | 103 | lemma ZN_atLeastAtMost [transfer_rule]: | 
| 55938 | 104 | "(ZN ===> ZN ===> rel_set ZN) atLeastAtMost atLeastAtMost" | 
| 55945 | 105 | unfolding rel_fun_def ZN_def rel_set_def | 
| 52360 
ac7ac2b242a2
more int/nat transfer rules; examples of new untransferred attribute
 huffman parents: 
51956diff
changeset | 106 | by (clarsimp simp add: Bex_def, arith) | 
| 
ac7ac2b242a2
more int/nat transfer rules; examples of new untransferred attribute
 huffman parents: 
51956diff
changeset | 107 | |
| 
ac7ac2b242a2
more int/nat transfer rules; examples of new untransferred attribute
 huffman parents: 
51956diff
changeset | 108 | lemma ZN_setsum [transfer_rule]: | 
| 55938 | 109 | "bi_unique A \<Longrightarrow> ((A ===> ZN) ===> rel_set A ===> ZN) setsum setsum" | 
| 55945 | 110 | apply (intro rel_funI) | 
| 55938 | 111 | apply (erule (1) bi_unique_rel_set_lemma) | 
| 55945 | 112 | apply (simp add: setsum.reindex int_setsum ZN_def rel_fun_def) | 
| 57418 | 113 | apply (rule setsum.cong) | 
| 114 | apply simp_all | |
| 52360 
ac7ac2b242a2
more int/nat transfer rules; examples of new untransferred attribute
 huffman parents: 
51956diff
changeset | 115 | done | 
| 
ac7ac2b242a2
more int/nat transfer rules; examples of new untransferred attribute
 huffman parents: 
51956diff
changeset | 116 | |
| 47654 | 117 | text {* For derived operations, we can use the @{text "transfer_prover"}
 | 
| 118 | method to help generate transfer rules. *} | |
| 119 | ||
| 120 | lemma ZN_listsum [transfer_rule]: "(list_all2 ZN ===> ZN) listsum listsum" | |
| 58320 | 121 | by transfer_prover | 
| 47654 | 122 | |
| 53013 
3fbcfa911863
remove unnecessary dependencies on Library/Quotient_*
 kuncar parents: 
52360diff
changeset | 123 | end | 
| 
3fbcfa911863
remove unnecessary dependencies on Library/Quotient_*
 kuncar parents: 
52360diff
changeset | 124 | |
| 47654 | 125 | subsection {* Transfer examples *}
 | 
| 126 | ||
| 127 | lemma | |
| 128 | assumes "\<And>i::int. 0 \<le> i \<Longrightarrow> i + 0 = i" | |
| 129 | shows "\<And>i::nat. i + 0 = i" | |
| 130 | apply transfer | |
| 131 | apply fact | |
| 132 | done | |
| 133 | ||
| 134 | lemma | |
| 135 |   assumes "\<And>i k::int. \<lbrakk>0 \<le> i; 0 \<le> k; i < k\<rbrakk> \<Longrightarrow> \<exists>j\<in>{0..}. i + j = k"
 | |
| 136 | shows "\<And>i k::nat. i < k \<Longrightarrow> \<exists>j. i + j = k" | |
| 137 | apply transfer | |
| 138 | apply fact | |
| 139 | done | |
| 140 | ||
| 141 | lemma | |
| 142 |   assumes "\<forall>x\<in>{0::int..}. \<forall>y\<in>{0..}. x * y div y = x"
 | |
| 143 | shows "\<forall>x y :: nat. x * y div y = x" | |
| 144 | apply transfer | |
| 145 | apply fact | |
| 146 | done | |
| 147 | ||
| 148 | lemma | |
| 149 | assumes "\<And>m n::int. \<lbrakk>0 \<le> m; 0 \<le> n; m * n = 0\<rbrakk> \<Longrightarrow> m = 0 \<or> n = 0" | |
| 150 | shows "m * n = (0::nat) \<Longrightarrow> m = 0 \<or> n = 0" | |
| 151 | apply transfer | |
| 152 | apply fact | |
| 153 | done | |
| 154 | ||
| 155 | lemma | |
| 156 |   assumes "\<forall>x\<in>{0::int..}. \<exists>y\<in>{0..}. \<exists>z\<in>{0..}. x + 3 * y = 5 * z"
 | |
| 157 | shows "\<forall>x::nat. \<exists>y z. x + 3 * y = 5 * z" | |
| 158 | apply transfer | |
| 159 | apply fact | |
| 160 | done | |
| 161 | ||
| 162 | text {* The @{text "fixing"} option prevents generalization over the free
 | |
| 163 |   variable @{text "n"}, allowing the local transfer rule to be used. *}
 | |
| 164 | ||
| 165 | lemma | |
| 166 | assumes [transfer_rule]: "ZN x n" | |
| 167 |   assumes "\<forall>i\<in>{0..}. i < x \<longrightarrow> 2 * i < 3 * x"
 | |
| 168 | shows "\<forall>i. i < n \<longrightarrow> 2 * i < 3 * n" | |
| 169 | apply (transfer fixing: n) | |
| 170 | apply fact | |
| 171 | done | |
| 172 | ||
| 173 | lemma | |
| 174 | assumes "gcd (2^i) (3^j) = (1::int)" | |
| 175 | shows "gcd (2^i) (3^j) = (1::nat)" | |
| 176 | apply (transfer fixing: i j) | |
| 177 | apply fact | |
| 178 | done | |
| 179 | ||
| 180 | lemma | |
| 181 | assumes "\<And>x y z::int. \<lbrakk>0 \<le> x; 0 \<le> y; 0 \<le> z\<rbrakk> \<Longrightarrow> | |
| 182 | listsum [x, y, z] = 0 \<longleftrightarrow> list_all (\<lambda>x. x = 0) [x, y, z]" | |
| 183 | shows "listsum [x, y, z] = (0::nat) \<longleftrightarrow> list_all (\<lambda>x. x = 0) [x, y, z]" | |
| 184 | apply transfer | |
| 185 | apply fact | |
| 186 | done | |
| 187 | ||
| 51956 
a4d81cdebf8b
better support for domains in Lifting/Transfer = replace Domainp T by the actual invariant in a transferred goal
 kuncar parents: 
47654diff
changeset | 188 | text {* Quantifiers over higher types (e.g. @{text "nat list"}) are
 | 
| 
a4d81cdebf8b
better support for domains in Lifting/Transfer = replace Domainp T by the actual invariant in a transferred goal
 kuncar parents: 
47654diff
changeset | 189 |   transferred to a readable formula thanks to the transfer domain rule @{thm Domainp_ZN} *}
 | 
| 47654 | 190 | |
| 191 | lemma | |
| 51956 
a4d81cdebf8b
better support for domains in Lifting/Transfer = replace Domainp T by the actual invariant in a transferred goal
 kuncar parents: 
47654diff
changeset | 192 | assumes "\<And>xs::int list. list_all (\<lambda>x. x \<ge> 0) xs \<Longrightarrow> | 
| 47654 | 193 | (listsum xs = 0) = list_all (\<lambda>x. x = 0) xs" | 
| 194 | shows "listsum xs = (0::nat) \<longleftrightarrow> list_all (\<lambda>x. x = 0) xs" | |
| 195 | apply transfer | |
| 196 | apply fact | |
| 197 | done | |
| 198 | ||
| 199 | text {* Equality on a higher type can be transferred if the relations
 | |
| 200 | involved are bi-unique. *} | |
| 201 | ||
| 202 | lemma | |
| 51956 
a4d81cdebf8b
better support for domains in Lifting/Transfer = replace Domainp T by the actual invariant in a transferred goal
 kuncar parents: 
47654diff
changeset | 203 | assumes "\<And>xs\<Colon>int list. \<lbrakk>list_all (\<lambda>x. x \<ge> 0) xs; xs \<noteq> []\<rbrakk> \<Longrightarrow> | 
| 47654 | 204 | listsum xs < listsum (map (\<lambda>x. x + 1) xs)" | 
| 205 | shows "xs \<noteq> [] \<Longrightarrow> listsum xs < listsum (map Suc xs)" | |
| 206 | apply transfer | |
| 207 | apply fact | |
| 208 | done | |
| 209 | ||
| 210 | end |