1 (* Title: HOL/ex/Transfer_Int_Nat.thy |
1 (* Title: HOL/ex/Transfer_Int_Nat.thy |
2 Author: Brian Huffman, TU Muenchen |
2 Author: Brian Huffman, TU Muenchen |
3 *) |
3 *) |
4 |
4 |
5 section {* Using the transfer method between nat and int *} |
5 section \<open>Using the transfer method between nat and int\<close> |
6 |
6 |
7 theory Transfer_Int_Nat |
7 theory Transfer_Int_Nat |
8 imports GCD |
8 imports GCD |
9 begin |
9 begin |
10 |
10 |
11 subsection {* Correspondence relation *} |
11 subsection \<open>Correspondence relation\<close> |
12 |
12 |
13 definition ZN :: "int \<Rightarrow> nat \<Rightarrow> bool" |
13 definition ZN :: "int \<Rightarrow> nat \<Rightarrow> bool" |
14 where "ZN = (\<lambda>z n. z = of_nat n)" |
14 where "ZN = (\<lambda>z n. z = of_nat n)" |
15 |
15 |
16 subsection {* Transfer domain rules *} |
16 subsection \<open>Transfer domain rules\<close> |
17 |
17 |
18 lemma Domainp_ZN [transfer_domain_rule]: "Domainp ZN = (\<lambda>x. x \<ge> 0)" |
18 lemma Domainp_ZN [transfer_domain_rule]: "Domainp ZN = (\<lambda>x. x \<ge> 0)" |
19 unfolding ZN_def Domainp_iff[abs_def] by (auto intro: zero_le_imp_eq_int) |
19 unfolding ZN_def Domainp_iff[abs_def] by (auto intro: zero_le_imp_eq_int) |
20 |
20 |
21 subsection {* Transfer rules *} |
21 subsection \<open>Transfer rules\<close> |
22 |
22 |
23 context |
23 context |
24 begin |
24 begin |
25 interpretation lifting_syntax . |
25 interpretation lifting_syntax . |
26 |
26 |
112 apply (simp add: setsum.reindex int_setsum ZN_def rel_fun_def) |
112 apply (simp add: setsum.reindex int_setsum ZN_def rel_fun_def) |
113 apply (rule setsum.cong) |
113 apply (rule setsum.cong) |
114 apply simp_all |
114 apply simp_all |
115 done |
115 done |
116 |
116 |
117 text {* For derived operations, we can use the @{text "transfer_prover"} |
117 text \<open>For derived operations, we can use the @{text "transfer_prover"} |
118 method to help generate transfer rules. *} |
118 method to help generate transfer rules.\<close> |
119 |
119 |
120 lemma ZN_listsum [transfer_rule]: "(list_all2 ZN ===> ZN) listsum listsum" |
120 lemma ZN_listsum [transfer_rule]: "(list_all2 ZN ===> ZN) listsum listsum" |
121 by transfer_prover |
121 by transfer_prover |
122 |
122 |
123 end |
123 end |
124 |
124 |
125 subsection {* Transfer examples *} |
125 subsection \<open>Transfer examples\<close> |
126 |
126 |
127 lemma |
127 lemma |
128 assumes "\<And>i::int. 0 \<le> i \<Longrightarrow> i + 0 = i" |
128 assumes "\<And>i::int. 0 \<le> i \<Longrightarrow> i + 0 = i" |
129 shows "\<And>i::nat. i + 0 = i" |
129 shows "\<And>i::nat. i + 0 = i" |
130 apply transfer |
130 apply transfer |
157 shows "\<forall>x::nat. \<exists>y z. x + 3 * y = 5 * z" |
157 shows "\<forall>x::nat. \<exists>y z. x + 3 * y = 5 * z" |
158 apply transfer |
158 apply transfer |
159 apply fact |
159 apply fact |
160 done |
160 done |
161 |
161 |
162 text {* The @{text "fixing"} option prevents generalization over the free |
162 text \<open>The @{text "fixing"} option prevents generalization over the free |
163 variable @{text "n"}, allowing the local transfer rule to be used. *} |
163 variable @{text "n"}, allowing the local transfer rule to be used.\<close> |
164 |
164 |
165 lemma |
165 lemma |
166 assumes [transfer_rule]: "ZN x n" |
166 assumes [transfer_rule]: "ZN x n" |
167 assumes "\<forall>i\<in>{0..}. i < x \<longrightarrow> 2 * i < 3 * x" |
167 assumes "\<forall>i\<in>{0..}. i < x \<longrightarrow> 2 * i < 3 * x" |
168 shows "\<forall>i. i < n \<longrightarrow> 2 * i < 3 * n" |
168 shows "\<forall>i. i < n \<longrightarrow> 2 * i < 3 * n" |
183 shows "listsum [x, y, z] = (0::nat) \<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 |
184 apply transfer |
185 apply fact |
185 apply fact |
186 done |
186 done |
187 |
187 |
188 text {* Quantifiers over higher types (e.g. @{text "nat list"}) are |
188 text \<open>Quantifiers over higher types (e.g. @{text "nat list"}) are |
189 transferred to a readable formula thanks to the transfer domain rule @{thm Domainp_ZN} *} |
189 transferred to a readable formula thanks to the transfer domain rule @{thm Domainp_ZN}\<close> |
190 |
190 |
191 lemma |
191 lemma |
192 assumes "\<And>xs::int list. list_all (\<lambda>x. x \<ge> 0) xs \<Longrightarrow> |
192 assumes "\<And>xs::int list. list_all (\<lambda>x. x \<ge> 0) xs \<Longrightarrow> |
193 (listsum xs = 0) = list_all (\<lambda>x. x = 0) xs" |
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" |
194 shows "listsum xs = (0::nat) \<longleftrightarrow> list_all (\<lambda>x. x = 0) xs" |
195 apply transfer |
195 apply transfer |
196 apply fact |
196 apply fact |
197 done |
197 done |
198 |
198 |
199 text {* Equality on a higher type can be transferred if the relations |
199 text \<open>Equality on a higher type can be transferred if the relations |
200 involved are bi-unique. *} |
200 involved are bi-unique.\<close> |
201 |
201 |
202 lemma |
202 lemma |
203 assumes "\<And>xs::int list. \<lbrakk>list_all (\<lambda>x. x \<ge> 0) xs; xs \<noteq> []\<rbrakk> \<Longrightarrow> |
203 assumes "\<And>xs::int list. \<lbrakk>list_all (\<lambda>x. x \<ge> 0) xs; xs \<noteq> []\<rbrakk> \<Longrightarrow> |
204 listsum xs < listsum (map (\<lambda>x. x + 1) xs)" |
204 listsum xs < listsum (map (\<lambda>x. x + 1) xs)" |
205 shows "xs \<noteq> [] \<Longrightarrow> listsum xs < listsum (map Suc xs)" |
205 shows "xs \<noteq> [] \<Longrightarrow> listsum xs < listsum (map Suc xs)" |