src/HOL/Lifting.thy
author kuncar
Wed May 16 19:17:20 2012 +0200 (2012-05-16)
changeset 47937 70375fa2679d
parent 47936 756f30eac792
child 47982 7aa35601ff65
permissions -rw-r--r--
generate abs_eq, use it as a code equation for total quotients; no_abs_code renamed to no_code; added no_code for quotient_type command
     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 lemma reflp_equality: "reflp (op =)"
   125 by (auto intro: reflpI)
   126 
   127 text {* TODO: Use one of these alternatives as the real definition. *}
   128 
   129 lemma Quotient_alt_def:
   130   "Quotient R Abs Rep T \<longleftrightarrow>
   131     (\<forall>a b. T a b \<longrightarrow> Abs a = b) \<and>
   132     (\<forall>b. T (Rep b) b) \<and>
   133     (\<forall>x y. R x y \<longleftrightarrow> T x (Abs x) \<and> T y (Abs y) \<and> Abs x = Abs y)"
   134 apply safe
   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 (simp (no_asm_use) only: Quotient_def, fast)
   139 apply (simp (no_asm_use) only: Quotient_def, fast)
   140 apply (simp (no_asm_use) only: Quotient_def, fast)
   141 apply (rule QuotientI)
   142 apply simp
   143 apply metis
   144 apply simp
   145 apply (rule ext, rule ext, metis)
   146 done
   147 
   148 lemma Quotient_alt_def2:
   149   "Quotient R Abs Rep T \<longleftrightarrow>
   150     (\<forall>a b. T a b \<longrightarrow> Abs a = b) \<and>
   151     (\<forall>b. T (Rep b) b) \<and>
   152     (\<forall>x y. R x y \<longleftrightarrow> T x (Abs y) \<and> T y (Abs x))"
   153   unfolding Quotient_alt_def by (safe, metis+)
   154 
   155 lemma Quotient_alt_def3:
   156   "Quotient R Abs Rep T \<longleftrightarrow>
   157     (\<forall>a b. T a b \<longrightarrow> Abs a = b) \<and> (\<forall>b. T (Rep b) b) \<and>
   158     (\<forall>x y. R x y \<longleftrightarrow> (\<exists>z. T x z \<and> T y z))"
   159   unfolding Quotient_alt_def2 by (safe, metis+)
   160 
   161 lemma Quotient_alt_def4:
   162   "Quotient R Abs Rep T \<longleftrightarrow>
   163     (\<forall>a b. T a b \<longrightarrow> Abs a = b) \<and> (\<forall>b. T (Rep b) b) \<and> R = T OO conversep T"
   164   unfolding Quotient_alt_def3 fun_eq_iff by auto
   165 
   166 lemma fun_quotient:
   167   assumes 1: "Quotient R1 abs1 rep1 T1"
   168   assumes 2: "Quotient R2 abs2 rep2 T2"
   169   shows "Quotient (R1 ===> R2) (rep1 ---> abs2) (abs1 ---> rep2) (T1 ===> T2)"
   170   using assms unfolding Quotient_alt_def2
   171   unfolding fun_rel_def fun_eq_iff map_fun_apply
   172   by (safe, metis+)
   173 
   174 lemma apply_rsp:
   175   fixes f g::"'a \<Rightarrow> 'c"
   176   assumes q: "Quotient R1 Abs1 Rep1 T1"
   177   and     a: "(R1 ===> R2) f g" "R1 x y"
   178   shows "R2 (f x) (g y)"
   179   using a by (auto elim: fun_relE)
   180 
   181 lemma apply_rsp':
   182   assumes a: "(R1 ===> R2) f g" "R1 x y"
   183   shows "R2 (f x) (g y)"
   184   using a by (auto elim: fun_relE)
   185 
   186 lemma apply_rsp'':
   187   assumes "Quotient R Abs Rep T"
   188   and "(R ===> S) f f"
   189   shows "S (f (Rep x)) (f (Rep x))"
   190 proof -
   191   from assms(1) have "R (Rep x) (Rep x)" by (rule Quotient_rep_reflp)
   192   then show ?thesis using assms(2) by (auto intro: apply_rsp')
   193 qed
   194 
   195 subsection {* Quotient composition *}
   196 
   197 lemma Quotient_compose:
   198   assumes 1: "Quotient R1 Abs1 Rep1 T1"
   199   assumes 2: "Quotient R2 Abs2 Rep2 T2"
   200   shows "Quotient (T1 OO R2 OO conversep T1) (Abs2 \<circ> Abs1) (Rep1 \<circ> Rep2) (T1 OO T2)"
   201   using assms unfolding Quotient_alt_def4 by (auto intro!: ext)
   202 
   203 lemma equivp_reflp2:
   204   "equivp R \<Longrightarrow> reflp R"
   205   by (erule equivpE)
   206 
   207 subsection {* Respects predicate *}
   208 
   209 definition Respects :: "('a \<Rightarrow> 'a \<Rightarrow> bool) \<Rightarrow> 'a set"
   210   where "Respects R = {x. R x x}"
   211 
   212 lemma in_respects: "x \<in> Respects R \<longleftrightarrow> R x x"
   213   unfolding Respects_def by simp
   214 
   215 subsection {* Invariant *}
   216 
   217 definition invariant :: "('a \<Rightarrow> bool) \<Rightarrow> 'a \<Rightarrow> 'a \<Rightarrow> bool" 
   218   where "invariant R = (\<lambda>x y. R x \<and> x = y)"
   219 
   220 lemma invariant_to_eq:
   221   assumes "invariant P x y"
   222   shows "x = y"
   223 using assms by (simp add: invariant_def)
   224 
   225 lemma fun_rel_eq_invariant:
   226   shows "((invariant R) ===> S) = (\<lambda>f g. \<forall>x. R x \<longrightarrow> S (f x) (g x))"
   227 by (auto simp add: invariant_def fun_rel_def)
   228 
   229 lemma invariant_same_args:
   230   shows "invariant P x x \<equiv> P x"
   231 using assms by (auto simp add: invariant_def)
   232 
   233 lemma UNIV_typedef_to_Quotient:
   234   assumes "type_definition Rep Abs UNIV"
   235   and T_def: "T \<equiv> (\<lambda>x y. x = Rep y)"
   236   shows "Quotient (op =) Abs Rep T"
   237 proof -
   238   interpret type_definition Rep Abs UNIV by fact
   239   from Abs_inject Rep_inverse Abs_inverse T_def show ?thesis 
   240     by (fastforce intro!: QuotientI fun_eq_iff)
   241 qed
   242 
   243 lemma UNIV_typedef_to_equivp:
   244   fixes Abs :: "'a \<Rightarrow> 'b"
   245   and Rep :: "'b \<Rightarrow> 'a"
   246   assumes "type_definition Rep Abs (UNIV::'a set)"
   247   shows "equivp (op=::'a\<Rightarrow>'a\<Rightarrow>bool)"
   248 by (rule identity_equivp)
   249 
   250 lemma typedef_to_Quotient:
   251   assumes "type_definition Rep Abs S"
   252   and T_def: "T \<equiv> (\<lambda>x y. x = Rep y)"
   253   shows "Quotient (invariant (\<lambda>x. x \<in> S)) Abs Rep T"
   254 proof -
   255   interpret type_definition Rep Abs S by fact
   256   from Rep Abs_inject Rep_inverse Abs_inverse T_def show ?thesis
   257     by (auto intro!: QuotientI simp: invariant_def fun_eq_iff)
   258 qed
   259 
   260 lemma typedef_to_part_equivp:
   261   assumes "type_definition Rep Abs S"
   262   shows "part_equivp (invariant (\<lambda>x. x \<in> S))"
   263 proof (intro part_equivpI)
   264   interpret type_definition Rep Abs S by fact
   265   show "\<exists>x. invariant (\<lambda>x. x \<in> S) x x" using Rep by (auto simp: invariant_def)
   266 next
   267   show "symp (invariant (\<lambda>x. x \<in> S))" by (auto intro: sympI simp: invariant_def)
   268 next
   269   show "transp (invariant (\<lambda>x. x \<in> S))" by (auto intro: transpI simp: invariant_def)
   270 qed
   271 
   272 lemma open_typedef_to_Quotient:
   273   assumes "type_definition Rep Abs {x. P x}"
   274   and T_def: "T \<equiv> (\<lambda>x y. x = Rep y)"
   275   shows "Quotient (invariant P) Abs Rep T"
   276   using typedef_to_Quotient [OF assms] by simp
   277 
   278 lemma open_typedef_to_part_equivp:
   279   assumes "type_definition Rep Abs {x. P x}"
   280   shows "part_equivp (invariant P)"
   281   using typedef_to_part_equivp [OF assms] by simp
   282 
   283 text {* Generating transfer rules for quotients. *}
   284 
   285 context
   286   fixes R Abs Rep T
   287   assumes 1: "Quotient R Abs Rep T"
   288 begin
   289 
   290 lemma Quotient_right_unique: "right_unique T"
   291   using 1 unfolding Quotient_alt_def right_unique_def by metis
   292 
   293 lemma Quotient_right_total: "right_total T"
   294   using 1 unfolding Quotient_alt_def right_total_def by metis
   295 
   296 lemma Quotient_rel_eq_transfer: "(T ===> T ===> op =) R (op =)"
   297   using 1 unfolding Quotient_alt_def fun_rel_def by simp
   298 
   299 lemma Quotient_abs_induct:
   300   assumes "\<And>y. R y y \<Longrightarrow> P (Abs y)" shows "P x"
   301   using 1 assms unfolding Quotient_def by metis
   302 
   303 lemma Quotient_All_transfer:
   304   "((T ===> op =) ===> op =) (Ball (Respects R)) All"
   305   unfolding fun_rel_def Respects_def Quotient_cr_rel [OF 1]
   306   by (auto, metis Quotient_abs_induct)
   307 
   308 lemma Quotient_Ex_transfer:
   309   "((T ===> op =) ===> op =) (Bex (Respects R)) Ex"
   310   unfolding fun_rel_def Respects_def Quotient_cr_rel [OF 1]
   311   by (auto, metis Quotient_rep_reflp [OF 1] Quotient_abs_rep [OF 1])
   312 
   313 lemma Quotient_forall_transfer:
   314   "((T ===> op =) ===> op =) (transfer_bforall (\<lambda>x. R x x)) transfer_forall"
   315   using Quotient_All_transfer
   316   unfolding transfer_forall_def transfer_bforall_def
   317     Ball_def [abs_def] in_respects .
   318 
   319 end
   320 
   321 text {* Generating transfer rules for total quotients. *}
   322 
   323 context
   324   fixes R Abs Rep T
   325   assumes 1: "Quotient R Abs Rep T" and 2: "reflp R"
   326 begin
   327 
   328 lemma Quotient_bi_total: "bi_total T"
   329   using 1 2 unfolding Quotient_alt_def bi_total_def reflp_def by auto
   330 
   331 lemma Quotient_id_abs_transfer: "(op = ===> T) (\<lambda>x. x) Abs"
   332   using 1 2 unfolding Quotient_alt_def reflp_def fun_rel_def by simp
   333 
   334 lemma Quotient_total_abs_induct: "(\<And>y. P (Abs y)) \<Longrightarrow> P x"
   335   using 1 2 assms unfolding Quotient_alt_def reflp_def by metis
   336 
   337 lemma Quotient_total_abs_eq_iff: "Abs x = Abs y \<longleftrightarrow> R x y"
   338   using Quotient_rel [OF 1] 2 unfolding reflp_def by simp
   339 
   340 end
   341 
   342 text {* Generating transfer rules for a type defined with @{text "typedef"}. *}
   343 
   344 context
   345   fixes Rep Abs A T
   346   assumes type: "type_definition Rep Abs A"
   347   assumes T_def: "T \<equiv> (\<lambda>(x::'a) (y::'b). x = Rep y)"
   348 begin
   349 
   350 lemma typedef_bi_unique: "bi_unique T"
   351   unfolding bi_unique_def T_def
   352   by (simp add: type_definition.Rep_inject [OF type])
   353 
   354 lemma typedef_rep_transfer: "(T ===> op =) (\<lambda>x. x) Rep"
   355   unfolding fun_rel_def T_def by simp
   356 
   357 lemma typedef_All_transfer: "((T ===> op =) ===> op =) (Ball A) All"
   358   unfolding T_def fun_rel_def
   359   by (metis type_definition.Rep [OF type]
   360     type_definition.Abs_inverse [OF type])
   361 
   362 lemma typedef_Ex_transfer: "((T ===> op =) ===> op =) (Bex A) Ex"
   363   unfolding T_def fun_rel_def
   364   by (metis type_definition.Rep [OF type]
   365     type_definition.Abs_inverse [OF type])
   366 
   367 lemma typedef_forall_transfer:
   368   "((T ===> op =) ===> op =)
   369     (transfer_bforall (\<lambda>x. x \<in> A)) transfer_forall"
   370   unfolding transfer_bforall_def transfer_forall_def Ball_def [symmetric]
   371   by (rule typedef_All_transfer)
   372 
   373 end
   374 
   375 text {* Generating the correspondence rule for a constant defined with
   376   @{text "lift_definition"}. *}
   377 
   378 lemma Quotient_to_transfer:
   379   assumes "Quotient R Abs Rep T" and "R c c" and "c' \<equiv> Abs c"
   380   shows "T c c'"
   381   using assms by (auto dest: Quotient_cr_rel)
   382 
   383 subsection {* ML setup *}
   384 
   385 use "Tools/Lifting/lifting_util.ML"
   386 
   387 use "Tools/Lifting/lifting_info.ML"
   388 setup Lifting_Info.setup
   389 
   390 declare fun_quotient[quot_map]
   391 declare reflp_equality[reflp_preserve]
   392 
   393 use "Tools/Lifting/lifting_term.ML"
   394 
   395 use "Tools/Lifting/lifting_def.ML"
   396 
   397 use "Tools/Lifting/lifting_setup.ML"
   398 
   399 hide_const (open) invariant
   400 
   401 end