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