1 (* Title: HOL/Transfer.thy |
1 (* Title: HOL/Transfer.thy |
2 Author: Brian Huffman, TU Muenchen |
2 Author: Brian Huffman, TU Muenchen |
3 Author: Ondrej Kuncar, TU Muenchen |
3 Author: Ondrej Kuncar, TU Muenchen |
4 *) |
4 *) |
5 |
5 |
6 section {* Generic theorem transfer using relations *} |
6 section \<open>Generic theorem transfer using relations\<close> |
7 |
7 |
8 theory Transfer |
8 theory Transfer |
9 imports Basic_BNF_LFPs Hilbert_Choice Metis |
9 imports Basic_BNF_LFPs Hilbert_Choice Metis |
10 begin |
10 begin |
11 |
11 |
12 subsection {* Relator for function space *} |
12 subsection \<open>Relator for function space\<close> |
13 |
13 |
14 locale lifting_syntax |
14 locale lifting_syntax |
15 begin |
15 begin |
16 notation rel_fun (infixr "===>" 55) |
16 notation rel_fun (infixr "===>" 55) |
17 notation map_fun (infixr "--->" 55) |
17 notation map_fun (infixr "--->" 55) |
36 lemma rel_fun_eq_rel: |
36 lemma rel_fun_eq_rel: |
37 shows "rel_fun (op =) R = (\<lambda>f g. \<forall>x. R (f x) (g x))" |
37 shows "rel_fun (op =) R = (\<lambda>f g. \<forall>x. R (f x) (g x))" |
38 by (simp add: rel_fun_def) |
38 by (simp add: rel_fun_def) |
39 |
39 |
40 |
40 |
41 subsection {* Transfer method *} |
41 subsection \<open>Transfer method\<close> |
42 |
42 |
43 text {* Explicit tag for relation membership allows for |
43 text \<open>Explicit tag for relation membership allows for |
44 backward proof methods. *} |
44 backward proof methods.\<close> |
45 |
45 |
46 definition Rel :: "('a \<Rightarrow> 'b \<Rightarrow> bool) \<Rightarrow> 'a \<Rightarrow> 'b \<Rightarrow> bool" |
46 definition Rel :: "('a \<Rightarrow> 'b \<Rightarrow> bool) \<Rightarrow> 'a \<Rightarrow> 'b \<Rightarrow> bool" |
47 where "Rel r \<equiv> r" |
47 where "Rel r \<equiv> r" |
48 |
48 |
49 text {* Handling of equality relations *} |
49 text \<open>Handling of equality relations\<close> |
50 |
50 |
51 definition is_equality :: "('a \<Rightarrow> 'a \<Rightarrow> bool) \<Rightarrow> bool" |
51 definition is_equality :: "('a \<Rightarrow> 'a \<Rightarrow> bool) \<Rightarrow> bool" |
52 where "is_equality R \<longleftrightarrow> R = (op =)" |
52 where "is_equality R \<longleftrightarrow> R = (op =)" |
53 |
53 |
54 lemma is_equality_eq: "is_equality (op =)" |
54 lemma is_equality_eq: "is_equality (op =)" |
55 unfolding is_equality_def by simp |
55 unfolding is_equality_def by simp |
56 |
56 |
57 text {* Reverse implication for monotonicity rules *} |
57 text \<open>Reverse implication for monotonicity rules\<close> |
58 |
58 |
59 definition rev_implies where |
59 definition rev_implies where |
60 "rev_implies x y \<longleftrightarrow> (y \<longrightarrow> x)" |
60 "rev_implies x y \<longleftrightarrow> (y \<longrightarrow> x)" |
61 |
61 |
62 text {* Handling of meta-logic connectives *} |
62 text \<open>Handling of meta-logic connectives\<close> |
63 |
63 |
64 definition transfer_forall where |
64 definition transfer_forall where |
65 "transfer_forall \<equiv> All" |
65 "transfer_forall \<equiv> All" |
66 |
66 |
67 definition transfer_implies where |
67 definition transfer_implies where |
103 lemma Rel_abs: |
103 lemma Rel_abs: |
104 assumes "\<And>x y. Rel A x y \<Longrightarrow> Rel B (f x) (g y)" |
104 assumes "\<And>x y. Rel A x y \<Longrightarrow> Rel B (f x) (g y)" |
105 shows "Rel (A ===> B) (\<lambda>x. f x) (\<lambda>y. g y)" |
105 shows "Rel (A ===> B) (\<lambda>x. f x) (\<lambda>y. g y)" |
106 using assms unfolding Rel_def rel_fun_def by fast |
106 using assms unfolding Rel_def rel_fun_def by fast |
107 |
107 |
108 subsection {* Predicates on relations, i.e. ``class constraints'' *} |
108 subsection \<open>Predicates on relations, i.e. ``class constraints''\<close> |
109 |
109 |
110 definition left_total :: "('a \<Rightarrow> 'b \<Rightarrow> bool) \<Rightarrow> bool" |
110 definition left_total :: "('a \<Rightarrow> 'b \<Rightarrow> bool) \<Rightarrow> bool" |
111 where "left_total R \<longleftrightarrow> (\<forall>x. \<exists>y. R x y)" |
111 where "left_total R \<longleftrightarrow> (\<forall>x. \<exists>y. R x y)" |
112 |
112 |
113 definition left_unique :: "('a \<Rightarrow> 'b \<Rightarrow> bool) \<Rightarrow> bool" |
113 definition left_unique :: "('a \<Rightarrow> 'b \<Rightarrow> bool) \<Rightarrow> bool" |
227 lemma bi_uniqueI: "left_unique R \<Longrightarrow> right_unique R \<Longrightarrow> bi_unique R" |
227 lemma bi_uniqueI: "left_unique R \<Longrightarrow> right_unique R \<Longrightarrow> bi_unique R" |
228 unfolding bi_unique_alt_def .. |
228 unfolding bi_unique_alt_def .. |
229 |
229 |
230 end |
230 end |
231 |
231 |
232 subsection {* Equality restricted by a predicate *} |
232 subsection \<open>Equality restricted by a predicate\<close> |
233 |
233 |
234 definition eq_onp :: "('a \<Rightarrow> bool) \<Rightarrow> 'a \<Rightarrow> 'a \<Rightarrow> bool" |
234 definition eq_onp :: "('a \<Rightarrow> bool) \<Rightarrow> 'a \<Rightarrow> 'a \<Rightarrow> bool" |
235 where "eq_onp R = (\<lambda>x y. R x \<and> x = y)" |
235 where "eq_onp R = (\<lambda>x y. R x \<and> x = y)" |
236 |
236 |
237 lemma eq_onp_Grp: "eq_onp P = BNF_Def.Grp (Collect P) id" |
237 lemma eq_onp_Grp: "eq_onp P = BNF_Def.Grp (Collect P) id" |
273 |
273 |
274 lemma Domainp_prod_fun_eq[relator_domain]: |
274 lemma Domainp_prod_fun_eq[relator_domain]: |
275 "Domainp (op= ===> T) = (\<lambda>f. \<forall>x. (Domainp T) (f x))" |
275 "Domainp (op= ===> T) = (\<lambda>f. \<forall>x. (Domainp T) (f x))" |
276 by (auto intro: choice simp: Domainp_iff rel_fun_def fun_eq_iff) |
276 by (auto intro: choice simp: Domainp_iff rel_fun_def fun_eq_iff) |
277 |
277 |
278 text {* Properties are preserved by relation composition. *} |
278 text \<open>Properties are preserved by relation composition.\<close> |
279 |
279 |
280 lemma OO_def: "R OO S = (\<lambda>x z. \<exists>y. R x y \<and> S y z)" |
280 lemma OO_def: "R OO S = (\<lambda>x z. \<exists>y. R x y \<and> S y z)" |
281 by auto |
281 by auto |
282 |
282 |
283 lemma bi_total_OO: "\<lbrakk>bi_total A; bi_total B\<rbrakk> \<Longrightarrow> bi_total (A OO B)" |
283 lemma bi_total_OO: "\<lbrakk>bi_total A; bi_total B\<rbrakk> \<Longrightarrow> bi_total (A OO B)" |
299 |
299 |
300 lemma left_unique_OO: "left_unique R \<Longrightarrow> left_unique S \<Longrightarrow> left_unique (R OO S)" |
300 lemma left_unique_OO: "left_unique R \<Longrightarrow> left_unique S \<Longrightarrow> left_unique (R OO S)" |
301 unfolding left_unique_def OO_def by blast |
301 unfolding left_unique_def OO_def by blast |
302 |
302 |
303 |
303 |
304 subsection {* Properties of relators *} |
304 subsection \<open>Properties of relators\<close> |
305 |
305 |
306 lemma left_total_eq[transfer_rule]: "left_total op=" |
306 lemma left_total_eq[transfer_rule]: "left_total op=" |
307 unfolding left_total_def by blast |
307 unfolding left_total_def by blast |
308 |
308 |
309 lemma left_unique_eq[transfer_rule]: "left_unique op=" |
309 lemma left_unique_eq[transfer_rule]: "left_unique op=" |
382 ML_file "Tools/BNF/bnf_fp_rec_sugar_transfer.ML" |
382 ML_file "Tools/BNF/bnf_fp_rec_sugar_transfer.ML" |
383 |
383 |
384 declare pred_fun_def [simp] |
384 declare pred_fun_def [simp] |
385 declare rel_fun_eq [relator_eq] |
385 declare rel_fun_eq [relator_eq] |
386 |
386 |
387 subsection {* Transfer rules *} |
387 subsection \<open>Transfer rules\<close> |
388 |
388 |
389 context |
389 context |
390 begin |
390 begin |
391 interpretation lifting_syntax . |
391 interpretation lifting_syntax . |
392 |
392 |
396 (transfer_bforall (Domainp A)) transfer_forall" |
396 (transfer_bforall (Domainp A)) transfer_forall" |
397 using assms unfolding right_total_def |
397 using assms unfolding right_total_def |
398 unfolding transfer_forall_def transfer_bforall_def rel_fun_def Domainp_iff |
398 unfolding transfer_forall_def transfer_bforall_def rel_fun_def Domainp_iff |
399 by fast |
399 by fast |
400 |
400 |
401 text {* Transfer rules using implication instead of equality on booleans. *} |
401 text \<open>Transfer rules using implication instead of equality on booleans.\<close> |
402 |
402 |
403 lemma transfer_forall_transfer [transfer_rule]: |
403 lemma transfer_forall_transfer [transfer_rule]: |
404 "bi_total A \<Longrightarrow> ((A ===> op =) ===> op =) transfer_forall transfer_forall" |
404 "bi_total A \<Longrightarrow> ((A ===> op =) ===> op =) transfer_forall transfer_forall" |
405 "right_total A \<Longrightarrow> ((A ===> op =) ===> implies) transfer_forall transfer_forall" |
405 "right_total A \<Longrightarrow> ((A ===> op =) ===> implies) transfer_forall transfer_forall" |
406 "right_total A \<Longrightarrow> ((A ===> implies) ===> implies) transfer_forall transfer_forall" |
406 "right_total A \<Longrightarrow> ((A ===> implies) ===> implies) transfer_forall transfer_forall" |
423 |
423 |
424 lemma eq_imp_transfer [transfer_rule]: |
424 lemma eq_imp_transfer [transfer_rule]: |
425 "right_unique A \<Longrightarrow> (A ===> A ===> op \<longrightarrow>) (op =) (op =)" |
425 "right_unique A \<Longrightarrow> (A ===> A ===> op \<longrightarrow>) (op =) (op =)" |
426 unfolding right_unique_alt_def2 . |
426 unfolding right_unique_alt_def2 . |
427 |
427 |
428 text {* Transfer rules using equality. *} |
428 text \<open>Transfer rules using equality.\<close> |
429 |
429 |
430 lemma left_unique_transfer [transfer_rule]: |
430 lemma left_unique_transfer [transfer_rule]: |
431 assumes "right_total A" |
431 assumes "right_total A" |
432 assumes "right_total B" |
432 assumes "right_total B" |
433 assumes "bi_unique A" |
433 assumes "bi_unique A" |
585 { |
585 { |
586 assume "R\<^sup>*\<^sup>* x y" "A y y'" |
586 assume "R\<^sup>*\<^sup>* x y" "A y y'" |
587 thus "R'\<^sup>*\<^sup>* x' y'" |
587 thus "R'\<^sup>*\<^sup>* x' y'" |
588 proof(induction arbitrary: y') |
588 proof(induction arbitrary: y') |
589 case base |
589 case base |
590 with `bi_unique A` `A x x'` have "x' = y'" by(rule bi_uniqueDr) |
590 with \<open>bi_unique A\<close> \<open>A x x'\<close> have "x' = y'" by(rule bi_uniqueDr) |
591 thus ?case by simp |
591 thus ?case by simp |
592 next |
592 next |
593 case (step y z z') |
593 case (step y z z') |
594 from `bi_total A` obtain y' where "A y y'" unfolding bi_total_def by blast |
594 from \<open>bi_total A\<close> obtain y' where "A y y'" unfolding bi_total_def by blast |
595 hence "R'\<^sup>*\<^sup>* x' y'" by(rule step.IH) |
595 hence "R'\<^sup>*\<^sup>* x' y'" by(rule step.IH) |
596 moreover from R `A y y'` `A z z'` `R y z` |
596 moreover from R \<open>A y y'\<close> \<open>A z z'\<close> \<open>R y z\<close> |
597 have "R' y' z'" by(auto dest: rel_funD) |
597 have "R' y' z'" by(auto dest: rel_funD) |
598 ultimately show ?case .. |
598 ultimately show ?case .. |
599 qed |
599 qed |
600 next |
600 next |
601 assume "R'\<^sup>*\<^sup>* x' y'" "A y y'" |
601 assume "R'\<^sup>*\<^sup>* x' y'" "A y y'" |
602 thus "R\<^sup>*\<^sup>* x y" |
602 thus "R\<^sup>*\<^sup>* x y" |
603 proof(induction arbitrary: y) |
603 proof(induction arbitrary: y) |
604 case base |
604 case base |
605 with `bi_unique A` `A x x'` have "x = y" by(rule bi_uniqueDl) |
605 with \<open>bi_unique A\<close> \<open>A x x'\<close> have "x = y" by(rule bi_uniqueDl) |
606 thus ?case by simp |
606 thus ?case by simp |
607 next |
607 next |
608 case (step y' z' z) |
608 case (step y' z' z) |
609 from `bi_total A` obtain y where "A y y'" unfolding bi_total_def by blast |
609 from \<open>bi_total A\<close> obtain y where "A y y'" unfolding bi_total_def by blast |
610 hence "R\<^sup>*\<^sup>* x y" by(rule step.IH) |
610 hence "R\<^sup>*\<^sup>* x y" by(rule step.IH) |
611 moreover from R `A y y'` `A z z'` `R' y' z'` |
611 moreover from R \<open>A y y'\<close> \<open>A z z'\<close> \<open>R' y' z'\<close> |
612 have "R y z" by(auto dest: rel_funD) |
612 have "R y z" by(auto dest: rel_funD) |
613 ultimately show ?case .. |
613 ultimately show ?case .. |
614 qed |
614 qed |
615 } |
615 } |
616 qed |
616 qed |