src/HOL/Inductive.thy
changeset 45899 df887263a379
parent 45897 65cef0298158
child 45907 4b41967bd77e
equal deleted inserted replaced
45898:b619242b0439 45899:df887263a379
   114 
   114 
   115 text{*Definition forms of @{text lfp_unfold} and @{text lfp_induct}, 
   115 text{*Definition forms of @{text lfp_unfold} and @{text lfp_induct}, 
   116     to control unfolding*}
   116     to control unfolding*}
   117 
   117 
   118 lemma def_lfp_unfold: "[| h==lfp(f);  mono(f) |] ==> h = f(h)"
   118 lemma def_lfp_unfold: "[| h==lfp(f);  mono(f) |] ==> h = f(h)"
   119 by (auto intro!: lfp_unfold)
   119   by (auto intro!: lfp_unfold)
   120 
   120 
   121 lemma def_lfp_induct: 
   121 lemma def_lfp_induct: 
   122     "[| A == lfp(f); mono(f);
   122     "[| A == lfp(f); mono(f);
   123         f (inf A P) \<le> P
   123         f (inf A P) \<le> P
   124      |] ==> A \<le> P"
   124      |] ==> A \<le> P"
   158 
   158 
   159 subsection {* Coinduction rules for greatest fixed points *}
   159 subsection {* Coinduction rules for greatest fixed points *}
   160 
   160 
   161 text{*weak version*}
   161 text{*weak version*}
   162 lemma weak_coinduct: "[| a: X;  X \<subseteq> f(X) |] ==> a : gfp(f)"
   162 lemma weak_coinduct: "[| a: X;  X \<subseteq> f(X) |] ==> a : gfp(f)"
   163 by (rule gfp_upperbound [THEN subsetD], auto)
   163   by (rule gfp_upperbound [THEN subsetD]) auto
   164 
   164 
   165 lemma weak_coinduct_image: "!!X. [| a : X; g`X \<subseteq> f (g`X) |] ==> g a : gfp f"
   165 lemma weak_coinduct_image: "!!X. [| a : X; g`X \<subseteq> f (g`X) |] ==> g a : gfp f"
   166 apply (erule gfp_upperbound [THEN subsetD])
   166   apply (erule gfp_upperbound [THEN subsetD])
   167 apply (erule imageI)
   167   apply (erule imageI)
   168 done
   168   done
   169 
   169 
   170 lemma coinduct_lemma:
   170 lemma coinduct_lemma:
   171      "[| X \<le> f (sup X (gfp f));  mono f |] ==> sup X (gfp f) \<le> f (sup X (gfp f))"
   171      "[| X \<le> f (sup X (gfp f));  mono f |] ==> sup X (gfp f) \<le> f (sup X (gfp f))"
   172   apply (frule gfp_lemma2)
   172   apply (frule gfp_lemma2)
   173   apply (drule mono_sup)
   173   apply (drule mono_sup)
   180   apply assumption
   180   apply assumption
   181   done
   181   done
   182 
   182 
   183 text{*strong version, thanks to Coen and Frost*}
   183 text{*strong version, thanks to Coen and Frost*}
   184 lemma coinduct_set: "[| mono(f);  a: X;  X \<subseteq> f(X Un gfp(f)) |] ==> a : gfp(f)"
   184 lemma coinduct_set: "[| mono(f);  a: X;  X \<subseteq> f(X Un gfp(f)) |] ==> a : gfp(f)"
   185 by (blast intro: weak_coinduct [OF _ coinduct_lemma])
   185   by (blast intro: weak_coinduct [OF _ coinduct_lemma])
   186 
   186 
   187 lemma coinduct: "[| mono(f); X \<le> f (sup X (gfp f)) |] ==> X \<le> gfp(f)"
   187 lemma coinduct: "[| mono(f); X \<le> f (sup X (gfp f)) |] ==> X \<le> gfp(f)"
   188   apply (rule order_trans)
   188   apply (rule order_trans)
   189   apply (rule sup_ge1)
   189   apply (rule sup_ge1)
   190   apply (erule gfp_upperbound [OF coinduct_lemma])
   190   apply (erule gfp_upperbound [OF coinduct_lemma])
   191   apply assumption
   191   apply assumption
   192   done
   192   done
   193 
   193 
   194 lemma gfp_fun_UnI2: "[| mono(f);  a: gfp(f) |] ==> a: f(X Un gfp(f))"
   194 lemma gfp_fun_UnI2: "[| mono(f);  a: gfp(f) |] ==> a: f(X Un gfp(f))"
   195 by (blast dest: gfp_lemma2 mono_Un)
   195   by (blast dest: gfp_lemma2 mono_Un)
   196 
   196 
   197 
   197 
   198 subsection {* Even Stronger Coinduction Rule, by Martin Coen *}
   198 subsection {* Even Stronger Coinduction Rule, by Martin Coen *}
   199 
   199 
   200 text{* Weakens the condition @{term "X \<subseteq> f(X)"} to one expressed using both
   200 text{* Weakens the condition @{term "X \<subseteq> f(X)"} to one expressed using both
   225 
   225 
   226 text{*Definition forms of @{text gfp_unfold} and @{text coinduct}, 
   226 text{*Definition forms of @{text gfp_unfold} and @{text coinduct}, 
   227     to control unfolding*}
   227     to control unfolding*}
   228 
   228 
   229 lemma def_gfp_unfold: "[| A==gfp(f);  mono(f) |] ==> A = f(A)"
   229 lemma def_gfp_unfold: "[| A==gfp(f);  mono(f) |] ==> A = f(A)"
   230 by (auto intro!: gfp_unfold)
   230   by (auto intro!: gfp_unfold)
   231 
   231 
   232 lemma def_coinduct:
   232 lemma def_coinduct:
   233      "[| A==gfp(f);  mono(f);  X \<le> f(sup X A) |] ==> X \<le> A"
   233      "[| A==gfp(f);  mono(f);  X \<le> f(sup X A) |] ==> X \<le> A"
   234 by (iprover intro!: coinduct)
   234   by (iprover intro!: coinduct)
   235 
   235 
   236 lemma def_coinduct_set:
   236 lemma def_coinduct_set:
   237      "[| A==gfp(f);  mono(f);  a:X;  X \<subseteq> f(X Un A) |] ==> a: A"
   237      "[| A==gfp(f);  mono(f);  a:X;  X \<subseteq> f(X Un A) |] ==> a: A"
   238 by (auto intro!: coinduct_set)
   238   by (auto intro!: coinduct_set)
   239 
   239 
   240 (*The version used in the induction/coinduction package*)
   240 (*The version used in the induction/coinduction package*)
   241 lemma def_Collect_coinduct:
   241 lemma def_Collect_coinduct:
   242     "[| A == gfp(%w. Collect(P(w)));  mono(%w. Collect(P(w)));   
   242     "[| A == gfp(%w. Collect(P(w)));  mono(%w. Collect(P(w)));   
   243         a: X;  !!z. z: X ==> P (X Un A) z |] ==>  
   243         a: X;  !!z. z: X ==> P (X Un A) z |] ==>  
   244      a : A"
   244      a : A"
   245 apply (erule def_coinduct_set, auto) 
   245   by (erule def_coinduct_set) auto
   246 done
       
   247 
   246 
   248 lemma def_coinduct3:
   247 lemma def_coinduct3:
   249     "[| A==gfp(f); mono(f);  a:X;  X \<subseteq> f(lfp(%x. f(x) Un X Un A)) |] ==> a: A"
   248     "[| A==gfp(f); mono(f);  a:X;  X \<subseteq> f(lfp(%x. f(x) Un X Un A)) |] ==> a: A"
   250 by (auto intro!: coinduct3)
   249   by (auto intro!: coinduct3)
   251 
   250 
   252 text{*Monotonicity of @{term gfp}!*}
   251 text{*Monotonicity of @{term gfp}!*}
   253 lemma gfp_mono: "(!!Z. f Z \<le> g Z) ==> gfp f \<le> gfp g"
   252 lemma gfp_mono: "(!!Z. f Z \<le> g Z) ==> gfp f \<le> gfp g"
   254   by (rule gfp_upperbound [THEN gfp_least], blast intro: order_trans)
   253   by (rule gfp_upperbound [THEN gfp_least], blast intro: order_trans)
   255 
   254 
   294 
   293 
   295 parse_translation (advanced) {*
   294 parse_translation (advanced) {*
   296 let
   295 let
   297   fun fun_tr ctxt [cs] =
   296   fun fun_tr ctxt [cs] =
   298     let
   297     let
   299       (* FIXME proper name context!? *)
   298       val x = Syntax.free (fst (Name.variant "x" (Term.declare_term_frees cs Name.context)));
   300       val x = Free (singleton (Name.variant_list (Term.add_free_names cs [])) "x", dummyT);
       
   301       val ft = Datatype_Case.case_tr true ctxt [x, cs];
   299       val ft = Datatype_Case.case_tr true ctxt [x, cs];
   302     in lambda x ft end
   300     in lambda x ft end
   303 in [(@{syntax_const "_lam_pats_syntax"}, fun_tr)] end
   301 in [(@{syntax_const "_lam_pats_syntax"}, fun_tr)] end
   304 *}
   302 *}
   305 
   303