src/HOL/Lifting.thy
author wenzelm
Thu May 24 17:25:53 2012 +0200 (2012-05-24)
changeset 47988 e4b69e10b990
parent 47982 7aa35601ff65
child 48891 c0eafbd55de3
permissions -rw-r--r--
tuned proofs;
     1 (*  Title:      HOL/Lifting.thy
     2     Author:     Brian Huffman and Ondrej Kuncar
     3     Author:     Cezary Kaliszyk and Christian Urban
     4 *)
     5 
     6 header {* Lifting package *}
     7 
     8 theory Lifting
     9 imports Plain Equiv_Relations Transfer
    10 keywords
    11   "print_quotmaps" "print_quotients" :: diag and
    12   "lift_definition" :: thy_goal and
    13   "setup_lifting" :: thy_decl
    14 uses
    15   ("Tools/Lifting/lifting_util.ML")
    16   ("Tools/Lifting/lifting_info.ML")
    17   ("Tools/Lifting/lifting_term.ML")
    18   ("Tools/Lifting/lifting_def.ML")
    19   ("Tools/Lifting/lifting_setup.ML")
    20 begin
    21 
    22 subsection {* Function map *}
    23 
    24 notation map_fun (infixr "--->" 55)
    25 
    26 lemma map_fun_id:
    27   "(id ---> id) = id"
    28   by (simp add: fun_eq_iff)
    29 
    30 subsection {* Quotient Predicate *}
    31 
    32 definition
    33   "Quotient R Abs Rep T \<longleftrightarrow>
    34      (\<forall>a. Abs (Rep a) = a) \<and> 
    35      (\<forall>a. R (Rep a) (Rep a)) \<and>
    36      (\<forall>r s. R r s \<longleftrightarrow> R r r \<and> R s s \<and> Abs r = Abs s) \<and>
    37      T = (\<lambda>x y. R x x \<and> Abs x = y)"
    38 
    39 lemma QuotientI:
    40   assumes "\<And>a. Abs (Rep a) = a"
    41     and "\<And>a. R (Rep a) (Rep a)"
    42     and "\<And>r s. R r s \<longleftrightarrow> R r r \<and> R s s \<and> Abs r = Abs s"
    43     and "T = (\<lambda>x y. R x x \<and> Abs x = y)"
    44   shows "Quotient R Abs Rep T"
    45   using assms unfolding Quotient_def by blast
    46 
    47 context
    48   fixes R Abs Rep T
    49   assumes a: "Quotient R Abs Rep T"
    50 begin
    51 
    52 lemma Quotient_abs_rep: "Abs (Rep a) = a"
    53   using a unfolding Quotient_def
    54   by simp
    55 
    56 lemma Quotient_rep_reflp: "R (Rep a) (Rep a)"
    57   using a unfolding Quotient_def
    58   by blast
    59 
    60 lemma Quotient_rel:
    61   "R r r \<and> R s s \<and> Abs r = Abs s \<longleftrightarrow> R r s" -- {* orientation does not loop on rewriting *}
    62   using a unfolding Quotient_def
    63   by blast
    64 
    65 lemma Quotient_cr_rel: "T = (\<lambda>x y. R x x \<and> Abs x = y)"
    66   using a unfolding Quotient_def
    67   by blast
    68 
    69 lemma Quotient_refl1: "R r s \<Longrightarrow> R r r"
    70   using a unfolding Quotient_def
    71   by fast
    72 
    73 lemma Quotient_refl2: "R r s \<Longrightarrow> R s s"
    74   using a unfolding Quotient_def
    75   by fast
    76 
    77 lemma Quotient_rel_rep: "R (Rep a) (Rep b) \<longleftrightarrow> a = b"
    78   using a unfolding Quotient_def
    79   by metis
    80 
    81 lemma Quotient_rep_abs: "R r r \<Longrightarrow> R (Rep (Abs r)) r"
    82   using a unfolding Quotient_def
    83   by blast
    84 
    85 lemma Quotient_rep_abs_fold_unmap: 
    86   assumes "x' \<equiv> Abs x" and "R x x" and "Rep x' \<equiv> Rep' x'" 
    87   shows "R (Rep' x') x"
    88 proof -
    89   have "R (Rep x') x" using assms(1-2) Quotient_rep_abs by auto
    90   then show ?thesis using assms(3) by simp
    91 qed
    92 
    93 lemma Quotient_Rep_eq:
    94   assumes "x' \<equiv> Abs x" 
    95   shows "Rep x' \<equiv> Rep x'"
    96 by simp
    97 
    98 lemma Quotient_rel_abs: "R r s \<Longrightarrow> Abs r = Abs s"
    99   using a unfolding Quotient_def
   100   by blast
   101 
   102 lemma Quotient_rel_abs2:
   103   assumes "R (Rep x) y"
   104   shows "x = Abs y"
   105 proof -
   106   from assms have "Abs (Rep x) = Abs y" by (auto intro: Quotient_rel_abs)
   107   then show ?thesis using assms(1) by (simp add: Quotient_abs_rep)
   108 qed
   109 
   110 lemma Quotient_symp: "symp R"
   111   using a unfolding Quotient_def using sympI by (metis (full_types))
   112 
   113 lemma Quotient_transp: "transp R"
   114   using a unfolding Quotient_def using transpI by (metis (full_types))
   115 
   116 lemma Quotient_part_equivp: "part_equivp R"
   117 by (metis Quotient_rep_reflp Quotient_symp Quotient_transp part_equivpI)
   118 
   119 end
   120 
   121 lemma identity_quotient: "Quotient (op =) id id (op =)"
   122 unfolding Quotient_def by simp 
   123 
   124 text {* TODO: Use one of these alternatives as the real definition. *}
   125 
   126 lemma Quotient_alt_def:
   127   "Quotient R Abs Rep T \<longleftrightarrow>
   128     (\<forall>a b. T a b \<longrightarrow> Abs a = b) \<and>
   129     (\<forall>b. T (Rep b) b) \<and>
   130     (\<forall>x y. R x y \<longleftrightarrow> T x (Abs x) \<and> T y (Abs y) \<and> Abs x = Abs y)"
   131 apply safe
   132 apply (simp (no_asm_use) only: Quotient_def, fast)
   133 apply (simp (no_asm_use) only: Quotient_def, fast)
   134 apply (simp (no_asm_use) only: Quotient_def, fast)
   135 apply (simp (no_asm_use) only: Quotient_def, fast)
   136 apply (simp (no_asm_use) only: Quotient_def, fast)
   137 apply (simp (no_asm_use) only: Quotient_def, fast)
   138 apply (rule QuotientI)
   139 apply simp
   140 apply metis
   141 apply simp
   142 apply (rule ext, rule ext, metis)
   143 done
   144 
   145 lemma Quotient_alt_def2:
   146   "Quotient R Abs Rep T \<longleftrightarrow>
   147     (\<forall>a b. T a b \<longrightarrow> Abs a = b) \<and>
   148     (\<forall>b. T (Rep b) b) \<and>
   149     (\<forall>x y. R x y \<longleftrightarrow> T x (Abs y) \<and> T y (Abs x))"
   150   unfolding Quotient_alt_def by (safe, metis+)
   151 
   152 lemma Quotient_alt_def3:
   153   "Quotient R Abs Rep T \<longleftrightarrow>
   154     (\<forall>a b. T a b \<longrightarrow> Abs a = b) \<and> (\<forall>b. T (Rep b) b) \<and>
   155     (\<forall>x y. R x y \<longleftrightarrow> (\<exists>z. T x z \<and> T y z))"
   156   unfolding Quotient_alt_def2 by (safe, metis+)
   157 
   158 lemma Quotient_alt_def4:
   159   "Quotient R Abs Rep T \<longleftrightarrow>
   160     (\<forall>a b. T a b \<longrightarrow> Abs a = b) \<and> (\<forall>b. T (Rep b) b) \<and> R = T OO conversep T"
   161   unfolding Quotient_alt_def3 fun_eq_iff by auto
   162 
   163 lemma fun_quotient:
   164   assumes 1: "Quotient R1 abs1 rep1 T1"
   165   assumes 2: "Quotient R2 abs2 rep2 T2"
   166   shows "Quotient (R1 ===> R2) (rep1 ---> abs2) (abs1 ---> rep2) (T1 ===> T2)"
   167   using assms unfolding Quotient_alt_def2
   168   unfolding fun_rel_def fun_eq_iff map_fun_apply
   169   by (safe, metis+)
   170 
   171 lemma apply_rsp:
   172   fixes f g::"'a \<Rightarrow> 'c"
   173   assumes q: "Quotient R1 Abs1 Rep1 T1"
   174   and     a: "(R1 ===> R2) f g" "R1 x y"
   175   shows "R2 (f x) (g y)"
   176   using a by (auto elim: fun_relE)
   177 
   178 lemma apply_rsp':
   179   assumes a: "(R1 ===> R2) f g" "R1 x y"
   180   shows "R2 (f x) (g y)"
   181   using a by (auto elim: fun_relE)
   182 
   183 lemma apply_rsp'':
   184   assumes "Quotient R Abs Rep T"
   185   and "(R ===> S) f f"
   186   shows "S (f (Rep x)) (f (Rep x))"
   187 proof -
   188   from assms(1) have "R (Rep x) (Rep x)" by (rule Quotient_rep_reflp)
   189   then show ?thesis using assms(2) by (auto intro: apply_rsp')
   190 qed
   191 
   192 subsection {* Quotient composition *}
   193 
   194 lemma Quotient_compose:
   195   assumes 1: "Quotient R1 Abs1 Rep1 T1"
   196   assumes 2: "Quotient R2 Abs2 Rep2 T2"
   197   shows "Quotient (T1 OO R2 OO conversep T1) (Abs2 \<circ> Abs1) (Rep1 \<circ> Rep2) (T1 OO T2)"
   198   using assms unfolding Quotient_alt_def4 by (auto intro!: ext)
   199 
   200 lemma equivp_reflp2:
   201   "equivp R \<Longrightarrow> reflp R"
   202   by (erule equivpE)
   203 
   204 subsection {* Respects predicate *}
   205 
   206 definition Respects :: "('a \<Rightarrow> 'a \<Rightarrow> bool) \<Rightarrow> 'a set"
   207   where "Respects R = {x. R x x}"
   208 
   209 lemma in_respects: "x \<in> Respects R \<longleftrightarrow> R x x"
   210   unfolding Respects_def by simp
   211 
   212 subsection {* Invariant *}
   213 
   214 definition invariant :: "('a \<Rightarrow> bool) \<Rightarrow> 'a \<Rightarrow> 'a \<Rightarrow> bool" 
   215   where "invariant R = (\<lambda>x y. R x \<and> x = y)"
   216 
   217 lemma invariant_to_eq:
   218   assumes "invariant P x y"
   219   shows "x = y"
   220 using assms by (simp add: invariant_def)
   221 
   222 lemma fun_rel_eq_invariant:
   223   shows "((invariant R) ===> S) = (\<lambda>f g. \<forall>x. R x \<longrightarrow> S (f x) (g x))"
   224 by (auto simp add: invariant_def fun_rel_def)
   225 
   226 lemma invariant_same_args:
   227   shows "invariant P x x \<equiv> P x"
   228 using assms by (auto simp add: invariant_def)
   229 
   230 lemma UNIV_typedef_to_Quotient:
   231   assumes "type_definition Rep Abs UNIV"
   232   and T_def: "T \<equiv> (\<lambda>x y. x = Rep y)"
   233   shows "Quotient (op =) Abs Rep T"
   234 proof -
   235   interpret type_definition Rep Abs UNIV by fact
   236   from Abs_inject Rep_inverse Abs_inverse T_def show ?thesis 
   237     by (fastforce intro!: QuotientI fun_eq_iff)
   238 qed
   239 
   240 lemma UNIV_typedef_to_equivp:
   241   fixes Abs :: "'a \<Rightarrow> 'b"
   242   and Rep :: "'b \<Rightarrow> 'a"
   243   assumes "type_definition Rep Abs (UNIV::'a set)"
   244   shows "equivp (op=::'a\<Rightarrow>'a\<Rightarrow>bool)"
   245 by (rule identity_equivp)
   246 
   247 lemma typedef_to_Quotient:
   248   assumes "type_definition Rep Abs S"
   249   and T_def: "T \<equiv> (\<lambda>x y. x = Rep y)"
   250   shows "Quotient (invariant (\<lambda>x. x \<in> S)) Abs Rep T"
   251 proof -
   252   interpret type_definition Rep Abs S by fact
   253   from Rep Abs_inject Rep_inverse Abs_inverse T_def show ?thesis
   254     by (auto intro!: QuotientI simp: invariant_def fun_eq_iff)
   255 qed
   256 
   257 lemma typedef_to_part_equivp:
   258   assumes "type_definition Rep Abs S"
   259   shows "part_equivp (invariant (\<lambda>x. x \<in> S))"
   260 proof (intro part_equivpI)
   261   interpret type_definition Rep Abs S by fact
   262   show "\<exists>x. invariant (\<lambda>x. x \<in> S) x x" using Rep by (auto simp: invariant_def)
   263 next
   264   show "symp (invariant (\<lambda>x. x \<in> S))" by (auto intro: sympI simp: invariant_def)
   265 next
   266   show "transp (invariant (\<lambda>x. x \<in> S))" by (auto intro: transpI simp: invariant_def)
   267 qed
   268 
   269 lemma open_typedef_to_Quotient:
   270   assumes "type_definition Rep Abs {x. P x}"
   271   and T_def: "T \<equiv> (\<lambda>x y. x = Rep y)"
   272   shows "Quotient (invariant P) Abs Rep T"
   273   using typedef_to_Quotient [OF assms] by simp
   274 
   275 lemma open_typedef_to_part_equivp:
   276   assumes "type_definition Rep Abs {x. P x}"
   277   shows "part_equivp (invariant P)"
   278   using typedef_to_part_equivp [OF assms] by simp
   279 
   280 text {* Generating transfer rules for quotients. *}
   281 
   282 context
   283   fixes R Abs Rep T
   284   assumes 1: "Quotient R Abs Rep T"
   285 begin
   286 
   287 lemma Quotient_right_unique: "right_unique T"
   288   using 1 unfolding Quotient_alt_def right_unique_def by metis
   289 
   290 lemma Quotient_right_total: "right_total T"
   291   using 1 unfolding Quotient_alt_def right_total_def by metis
   292 
   293 lemma Quotient_rel_eq_transfer: "(T ===> T ===> op =) R (op =)"
   294   using 1 unfolding Quotient_alt_def fun_rel_def by simp
   295 
   296 lemma Quotient_abs_induct:
   297   assumes "\<And>y. R y y \<Longrightarrow> P (Abs y)" shows "P x"
   298   using 1 assms unfolding Quotient_def by metis
   299 
   300 lemma Quotient_All_transfer:
   301   "((T ===> op =) ===> op =) (Ball (Respects R)) All"
   302   unfolding fun_rel_def Respects_def Quotient_cr_rel [OF 1]
   303   by (auto, metis Quotient_abs_induct)
   304 
   305 lemma Quotient_Ex_transfer:
   306   "((T ===> op =) ===> op =) (Bex (Respects R)) Ex"
   307   unfolding fun_rel_def Respects_def Quotient_cr_rel [OF 1]
   308   by (auto, metis Quotient_rep_reflp [OF 1] Quotient_abs_rep [OF 1])
   309 
   310 lemma Quotient_forall_transfer:
   311   "((T ===> op =) ===> op =) (transfer_bforall (\<lambda>x. R x x)) transfer_forall"
   312   using Quotient_All_transfer
   313   unfolding transfer_forall_def transfer_bforall_def
   314     Ball_def [abs_def] in_respects .
   315 
   316 end
   317 
   318 text {* Generating transfer rules for total quotients. *}
   319 
   320 context
   321   fixes R Abs Rep T
   322   assumes 1: "Quotient R Abs Rep T" and 2: "reflp R"
   323 begin
   324 
   325 lemma Quotient_bi_total: "bi_total T"
   326   using 1 2 unfolding Quotient_alt_def bi_total_def reflp_def by auto
   327 
   328 lemma Quotient_id_abs_transfer: "(op = ===> T) (\<lambda>x. x) Abs"
   329   using 1 2 unfolding Quotient_alt_def reflp_def fun_rel_def by simp
   330 
   331 lemma Quotient_total_abs_induct: "(\<And>y. P (Abs y)) \<Longrightarrow> P x"
   332   using 1 2 assms unfolding Quotient_alt_def reflp_def by metis
   333 
   334 lemma Quotient_total_abs_eq_iff: "Abs x = Abs y \<longleftrightarrow> R x y"
   335   using Quotient_rel [OF 1] 2 unfolding reflp_def by simp
   336 
   337 end
   338 
   339 text {* Generating transfer rules for a type defined with @{text "typedef"}. *}
   340 
   341 context
   342   fixes Rep Abs A T
   343   assumes type: "type_definition Rep Abs A"
   344   assumes T_def: "T \<equiv> (\<lambda>(x::'a) (y::'b). x = Rep y)"
   345 begin
   346 
   347 lemma typedef_bi_unique: "bi_unique T"
   348   unfolding bi_unique_def T_def
   349   by (simp add: type_definition.Rep_inject [OF type])
   350 
   351 lemma typedef_rep_transfer: "(T ===> op =) (\<lambda>x. x) Rep"
   352   unfolding fun_rel_def T_def by simp
   353 
   354 lemma typedef_All_transfer: "((T ===> op =) ===> op =) (Ball A) All"
   355   unfolding T_def fun_rel_def
   356   by (metis type_definition.Rep [OF type]
   357     type_definition.Abs_inverse [OF type])
   358 
   359 lemma typedef_Ex_transfer: "((T ===> op =) ===> op =) (Bex A) Ex"
   360   unfolding T_def fun_rel_def
   361   by (metis type_definition.Rep [OF type]
   362     type_definition.Abs_inverse [OF type])
   363 
   364 lemma typedef_forall_transfer:
   365   "((T ===> op =) ===> op =)
   366     (transfer_bforall (\<lambda>x. x \<in> A)) transfer_forall"
   367   unfolding transfer_bforall_def transfer_forall_def Ball_def [symmetric]
   368   by (rule typedef_All_transfer)
   369 
   370 end
   371 
   372 text {* Generating the correspondence rule for a constant defined with
   373   @{text "lift_definition"}. *}
   374 
   375 lemma Quotient_to_transfer:
   376   assumes "Quotient R Abs Rep T" and "R c c" and "c' \<equiv> Abs c"
   377   shows "T c c'"
   378   using assms by (auto dest: Quotient_cr_rel)
   379 
   380 text {* Proving reflexivity *}
   381 
   382 definition left_total :: "('a \<Rightarrow> 'b \<Rightarrow> bool) \<Rightarrow> bool"
   383   where "left_total R \<longleftrightarrow> (\<forall>x. \<exists>y. R x y)"
   384 
   385 lemma left_totalI:
   386   "(\<And>x. \<exists>y. R x y) \<Longrightarrow> left_total R"
   387 unfolding left_total_def by blast
   388 
   389 lemma left_totalE:
   390   assumes "left_total R"
   391   obtains "(\<And>x. \<exists>y. R x y)"
   392 using assms unfolding left_total_def by blast
   393 
   394 lemma Quotient_to_left_total:
   395   assumes q: "Quotient R Abs Rep T"
   396   and r_R: "reflp R"
   397   shows "left_total T"
   398 using r_R Quotient_cr_rel[OF q] unfolding left_total_def by (auto elim: reflpE)
   399 
   400 lemma reflp_Quotient_composition:
   401   assumes lt_R1: "left_total R1"
   402   and r_R2: "reflp R2"
   403   shows "reflp (R1 OO R2 OO R1\<inverse>\<inverse>)"
   404 using assms
   405 proof -
   406   {
   407     fix x
   408     from lt_R1 obtain y where "R1 x y" unfolding left_total_def by blast
   409     moreover then have "R1\<inverse>\<inverse> y x" by simp
   410     moreover have "R2 y y" using r_R2 by (auto elim: reflpE)
   411     ultimately have "(R1 OO R2 OO R1\<inverse>\<inverse>) x x" by auto
   412   }
   413   then show ?thesis by (auto intro: reflpI)
   414 qed
   415 
   416 lemma reflp_equality: "reflp (op =)"
   417 by (auto intro: reflpI)
   418 
   419 subsection {* ML setup *}
   420 
   421 use "Tools/Lifting/lifting_util.ML"
   422 
   423 use "Tools/Lifting/lifting_info.ML"
   424 setup Lifting_Info.setup
   425 
   426 declare fun_quotient[quot_map]
   427 lemmas [reflexivity_rule] = reflp_equality reflp_Quotient_composition
   428 
   429 use "Tools/Lifting/lifting_term.ML"
   430 
   431 use "Tools/Lifting/lifting_def.ML"
   432 
   433 use "Tools/Lifting/lifting_setup.ML"
   434 
   435 hide_const (open) invariant
   436 
   437 end