1 (* Title: HOL/Accessible_Part.thy
3 Author: Lawrence C Paulson, Cambridge University Computer Laboratory
4 Copyright 1994 University of Cambridge
7 header {* The accessible part of a relation *}
10 imports Wellfounded_Recursion
13 subsection {* Inductive definition *}
16 Inductive definition of the accessible part @{term "acc r"} of a
17 relation; see also \cite{paulin-tlca}.
21 acc :: "('a * 'a) set => 'a set"
22 for r :: "('a * 'a) set"
24 accI: "(!!y. (y, x) : r ==> y : acc r) ==> x : acc r"
27 termip :: "('a => 'a => bool) => 'a => bool" where
28 "termip r == accp (r\<inverse>\<inverse>)"
31 termi :: "('a * 'a) set => 'a set" where
32 "termi r == acc (r\<inverse>)"
34 lemmas accpI = accp.accI
36 subsection {* Induction rules *}
39 assumes major: "accp r a"
40 assumes hyp: "!!x. accp r x ==> \<forall>y. r y x --> P y ==> P x"
42 apply (rule major [THEN accp.induct])
44 apply (rule accp.accI)
49 theorems accp_induct_rule = accp_induct [rule_format, induct set: accp]
51 theorem accp_downward: "accp r b ==> r a b ==> accp r a"
52 apply (erule accp.cases)
57 assumes na: "\<not> accp R x"
58 obtains z where "R z x" and "\<not> accp R z"
60 assume a: "\<And>z. \<lbrakk>R z x; \<not> accp R z\<rbrakk> \<Longrightarrow> thesis"
63 proof (cases "\<forall>z. R z x \<longrightarrow> accp R z")
65 hence "\<And>z. R z x \<Longrightarrow> accp R z" by auto
68 with na show thesis ..
70 case False then obtain z where "R z x" and "\<not> accp R z"
76 lemma accp_downwards_aux: "r\<^sup>*\<^sup>* b a ==> accp r a --> accp r b"
77 apply (erule rtranclp_induct)
79 apply (blast dest: accp_downward)
82 theorem accp_downwards: "accp r a ==> r\<^sup>*\<^sup>* b a ==> accp r b"
83 apply (blast dest: accp_downwards_aux)
86 theorem accp_wfPI: "\<forall>x. accp r x ==> wfP r"
88 apply (induct_tac P x rule: accp_induct)
93 theorem accp_wfPD: "wfP r ==> accp r x"
94 apply (erule wfP_induct_rule)
95 apply (rule accp.accI)
99 theorem wfP_accp_iff: "wfP r = (\<forall>x. accp r x)"
100 apply (blast intro: accp_wfPI dest: accp_wfPD)
104 text {* Smaller relations have bigger accessible parts: *}
107 assumes sub: "R1 \<le> R2"
108 shows "accp R2 \<le> accp R1"
110 fix x assume "accp R2 x"
111 then show "accp R1 x"
114 assume ih: "\<And>y. R2 y x \<Longrightarrow> accp R1 y"
115 with sub show "accp R1 x"
116 by (blast intro: accp.accI)
121 text {* This is a generalized induction theorem that works on
122 subsets of the accessible part. *}
124 lemma accp_subset_induct:
125 assumes subset: "D \<le> accp R"
126 and dcl: "\<And>x z. \<lbrakk>D x; R z x\<rbrakk> \<Longrightarrow> D z"
128 and istep: "\<And>x. \<lbrakk>D x; (\<And>z. R z x \<Longrightarrow> P z)\<rbrakk> \<Longrightarrow> P x"
131 from subset and `D x`
133 then show "P x" using `D x`
137 and "\<And>y. R y x \<Longrightarrow> D y \<Longrightarrow> P y"
138 with dcl and istep show "P x" by blast
143 text {* Set versions of the above theorems *}
145 lemmas acc_induct = accp_induct [to_set]
147 lemmas acc_induct_rule = acc_induct [rule_format, induct set: acc]
149 lemmas acc_downward = accp_downward [to_set]
151 lemmas not_acc_down = not_accp_down [to_set]
153 lemmas acc_downwards_aux = accp_downwards_aux [to_set]
155 lemmas acc_downwards = accp_downwards [to_set]
157 lemmas acc_wfI = accp_wfPI [to_set]
159 lemmas acc_wfD = accp_wfPD [to_set]
161 lemmas wf_acc_iff = wfP_accp_iff [to_set]
163 lemmas acc_subset = accp_subset [to_set]
165 lemmas acc_subset_induct = accp_subset_induct [to_set]