author | wenzelm |
Tue, 05 Jul 2016 23:39:49 +0200 | |
changeset 63400 | 249fa34faba2 |
parent 61955 | e96292f32c3c |
child 63540 | f8652d0534fa |
permissions | -rw-r--r-- |
7700 | 1 |
(* Title: HOL/Inductive.thy |
10402 | 2 |
Author: Markus Wenzel, TU Muenchen |
11688 | 3 |
*) |
10727 | 4 |
|
60758 | 5 |
section \<open>Knaster-Tarski Fixpoint Theorem and inductive definitions\<close> |
1187 | 6 |
|
54398
100c0eaf63d5
moved 'Ctr_Sugar' further up the theory hierarchy, so that 'Datatype' can use it
blanchet
parents:
52143
diff
changeset
|
7 |
theory Inductive |
100c0eaf63d5
moved 'Ctr_Sugar' further up the theory hierarchy, so that 'Datatype' can use it
blanchet
parents:
52143
diff
changeset
|
8 |
imports Complete_Lattices Ctr_Sugar |
46950
d0181abdbdac
declare command keywords via theory header, including strict checking outside Pure;
wenzelm
parents:
46947
diff
changeset
|
9 |
keywords |
56146
8453d35e4684
discontinued somewhat pointless "thy_script" keyword kind;
wenzelm
parents:
55604
diff
changeset
|
10 |
"inductive" "coinductive" "inductive_cases" "inductive_simps" :: thy_decl and |
8453d35e4684
discontinued somewhat pointless "thy_script" keyword kind;
wenzelm
parents:
55604
diff
changeset
|
11 |
"monos" and |
54398
100c0eaf63d5
moved 'Ctr_Sugar' further up the theory hierarchy, so that 'Datatype' can use it
blanchet
parents:
52143
diff
changeset
|
12 |
"print_inductives" :: diag and |
58306
117ba6cbe414
renamed 'rep_datatype' to 'old_rep_datatype' (HOL)
blanchet
parents:
58187
diff
changeset
|
13 |
"old_rep_datatype" :: thy_goal and |
55575
a5e33e18fb5c
moved 'primrec' up (for real this time) and removed temporary 'old_primrec'
blanchet
parents:
55534
diff
changeset
|
14 |
"primrec" :: thy_decl |
15131 | 15 |
begin |
10727 | 16 |
|
60758 | 17 |
subsection \<open>Least and greatest fixed points\<close> |
24915 | 18 |
|
26013
8764a1f1253b
Theorem Inductive.lfp_ordinal_induct generalized to complete lattices
haftmann
parents:
25557
diff
changeset
|
19 |
context complete_lattice |
8764a1f1253b
Theorem Inductive.lfp_ordinal_induct generalized to complete lattices
haftmann
parents:
25557
diff
changeset
|
20 |
begin |
8764a1f1253b
Theorem Inductive.lfp_ordinal_induct generalized to complete lattices
haftmann
parents:
25557
diff
changeset
|
21 |
|
63400 | 22 |
definition lfp :: "('a \<Rightarrow> 'a) \<Rightarrow> 'a" \<comment> \<open>least fixed point\<close> |
23 |
where "lfp f = Inf {u. f u \<le> u}" |
|
24915 | 24 |
|
63400 | 25 |
definition gfp :: "('a \<Rightarrow> 'a) \<Rightarrow> 'a" \<comment> \<open>greatest fixed point\<close> |
26 |
where "gfp f = Sup {u. u \<le> f u}" |
|
24915 | 27 |
|
28 |
||
63400 | 29 |
subsection \<open>Proof of Knaster-Tarski Theorem using @{term lfp}\<close> |
24915 | 30 |
|
63400 | 31 |
text \<open>@{term "lfp f"} is the least upper bound of the set @{term "{u. f u \<le> u}"}\<close> |
24915 | 32 |
|
63400 | 33 |
lemma lfp_lowerbound: "f A \<le> A \<Longrightarrow> lfp f \<le> A" |
24915 | 34 |
by (auto simp add: lfp_def intro: Inf_lower) |
35 |
||
63400 | 36 |
lemma lfp_greatest: "(\<And>u. f u \<le> u \<Longrightarrow> A \<le> u) \<Longrightarrow> A \<le> lfp f" |
24915 | 37 |
by (auto simp add: lfp_def intro: Inf_greatest) |
38 |
||
26013
8764a1f1253b
Theorem Inductive.lfp_ordinal_induct generalized to complete lattices
haftmann
parents:
25557
diff
changeset
|
39 |
end |
8764a1f1253b
Theorem Inductive.lfp_ordinal_induct generalized to complete lattices
haftmann
parents:
25557
diff
changeset
|
40 |
|
63400 | 41 |
lemma lfp_lemma2: "mono f \<Longrightarrow> f (lfp f) \<le> lfp f" |
24915 | 42 |
by (iprover intro: lfp_greatest order_trans monoD lfp_lowerbound) |
43 |
||
63400 | 44 |
lemma lfp_lemma3: "mono f \<Longrightarrow> lfp f \<le> f (lfp f)" |
24915 | 45 |
by (iprover intro: lfp_lemma2 monoD lfp_lowerbound) |
46 |
||
63400 | 47 |
lemma lfp_unfold: "mono f \<Longrightarrow> lfp f = f (lfp f)" |
24915 | 48 |
by (iprover intro: order_antisym lfp_lemma2 lfp_lemma3) |
49 |
||
50 |
lemma lfp_const: "lfp (\<lambda>x. t) = t" |
|
63400 | 51 |
by (rule lfp_unfold) (simp add: mono_def) |
24915 | 52 |
|
53 |
||
60758 | 54 |
subsection \<open>General induction rules for least fixed points\<close> |
24915 | 55 |
|
63400 | 56 |
lemma lfp_ordinal_induct [case_names mono step union]: |
61076 | 57 |
fixes f :: "'a::complete_lattice \<Rightarrow> 'a" |
26013
8764a1f1253b
Theorem Inductive.lfp_ordinal_induct generalized to complete lattices
haftmann
parents:
25557
diff
changeset
|
58 |
assumes mono: "mono f" |
63400 | 59 |
and P_f: "\<And>S. P S \<Longrightarrow> S \<le> lfp f \<Longrightarrow> P (f S)" |
60 |
and P_Union: "\<And>M. \<forall>S\<in>M. P S \<Longrightarrow> P (Sup M)" |
|
26013
8764a1f1253b
Theorem Inductive.lfp_ordinal_induct generalized to complete lattices
haftmann
parents:
25557
diff
changeset
|
61 |
shows "P (lfp f)" |
8764a1f1253b
Theorem Inductive.lfp_ordinal_induct generalized to complete lattices
haftmann
parents:
25557
diff
changeset
|
62 |
proof - |
8764a1f1253b
Theorem Inductive.lfp_ordinal_induct generalized to complete lattices
haftmann
parents:
25557
diff
changeset
|
63 |
let ?M = "{S. S \<le> lfp f \<and> P S}" |
8764a1f1253b
Theorem Inductive.lfp_ordinal_induct generalized to complete lattices
haftmann
parents:
25557
diff
changeset
|
64 |
have "P (Sup ?M)" using P_Union by simp |
8764a1f1253b
Theorem Inductive.lfp_ordinal_induct generalized to complete lattices
haftmann
parents:
25557
diff
changeset
|
65 |
also have "Sup ?M = lfp f" |
8764a1f1253b
Theorem Inductive.lfp_ordinal_induct generalized to complete lattices
haftmann
parents:
25557
diff
changeset
|
66 |
proof (rule antisym) |
8764a1f1253b
Theorem Inductive.lfp_ordinal_induct generalized to complete lattices
haftmann
parents:
25557
diff
changeset
|
67 |
show "Sup ?M \<le> lfp f" by (blast intro: Sup_least) |
63400 | 68 |
then have "f (Sup ?M) \<le> f (lfp f)" |
69 |
by (rule mono [THEN monoD]) |
|
70 |
then have "f (Sup ?M) \<le> lfp f" |
|
71 |
using mono [THEN lfp_unfold] by simp |
|
72 |
then have "f (Sup ?M) \<in> ?M" |
|
73 |
using P_Union by simp (intro P_f Sup_least, auto) |
|
74 |
then have "f (Sup ?M) \<le> Sup ?M" |
|
75 |
by (rule Sup_upper) |
|
76 |
then show "lfp f \<le> Sup ?M" |
|
77 |
by (rule lfp_lowerbound) |
|
26013
8764a1f1253b
Theorem Inductive.lfp_ordinal_induct generalized to complete lattices
haftmann
parents:
25557
diff
changeset
|
78 |
qed |
8764a1f1253b
Theorem Inductive.lfp_ordinal_induct generalized to complete lattices
haftmann
parents:
25557
diff
changeset
|
79 |
finally show ?thesis . |
63400 | 80 |
qed |
26013
8764a1f1253b
Theorem Inductive.lfp_ordinal_induct generalized to complete lattices
haftmann
parents:
25557
diff
changeset
|
81 |
|
60174
70d8f7abde8f
strengthened lfp_ordinal_induct; added dual gfp variant
hoelzl
parents:
60173
diff
changeset
|
82 |
theorem lfp_induct: |
63400 | 83 |
assumes mono: "mono f" |
84 |
and ind: "f (inf (lfp f) P) \<le> P" |
|
60174
70d8f7abde8f
strengthened lfp_ordinal_induct; added dual gfp variant
hoelzl
parents:
60173
diff
changeset
|
85 |
shows "lfp f \<le> P" |
70d8f7abde8f
strengthened lfp_ordinal_induct; added dual gfp variant
hoelzl
parents:
60173
diff
changeset
|
86 |
proof (induction rule: lfp_ordinal_induct) |
63400 | 87 |
case (step S) |
88 |
then show ?case |
|
60174
70d8f7abde8f
strengthened lfp_ordinal_induct; added dual gfp variant
hoelzl
parents:
60173
diff
changeset
|
89 |
by (intro order_trans[OF _ ind] monoD[OF mono]) auto |
70d8f7abde8f
strengthened lfp_ordinal_induct; added dual gfp variant
hoelzl
parents:
60173
diff
changeset
|
90 |
qed (auto intro: mono Sup_least) |
70d8f7abde8f
strengthened lfp_ordinal_induct; added dual gfp variant
hoelzl
parents:
60173
diff
changeset
|
91 |
|
70d8f7abde8f
strengthened lfp_ordinal_induct; added dual gfp variant
hoelzl
parents:
60173
diff
changeset
|
92 |
lemma lfp_induct_set: |
63400 | 93 |
assumes lfp: "a \<in> lfp f" |
94 |
and mono: "mono f" |
|
95 |
and hyp: "\<And>x. x \<in> f (lfp f \<inter> {x. P x}) \<Longrightarrow> P x" |
|
96 |
shows "P a" |
|
97 |
by (rule lfp_induct [THEN subsetD, THEN CollectD, OF mono _ lfp]) (auto intro: hyp) |
|
60174
70d8f7abde8f
strengthened lfp_ordinal_induct; added dual gfp variant
hoelzl
parents:
60173
diff
changeset
|
98 |
|
63400 | 99 |
lemma lfp_ordinal_induct_set: |
24915 | 100 |
assumes mono: "mono f" |
63400 | 101 |
and P_f: "\<And>S. P S \<Longrightarrow> P (f S)" |
102 |
and P_Union: "\<And>M. \<forall>S\<in>M. P S \<Longrightarrow> P (\<Union>M)" |
|
103 |
shows "P (lfp f)" |
|
46008
c296c75f4cf4
reverted some changes for set->predicate transition, according to "hg log -u berghofe -r Isabelle2007:Isabelle2008";
wenzelm
parents:
45907
diff
changeset
|
104 |
using assms by (rule lfp_ordinal_induct) |
24915 | 105 |
|
106 |
||
63400 | 107 |
text \<open>Definition forms of \<open>lfp_unfold\<close> and \<open>lfp_induct\<close>, to control unfolding.\<close> |
24915 | 108 |
|
63400 | 109 |
lemma def_lfp_unfold: "h \<equiv> lfp f \<Longrightarrow> mono f \<Longrightarrow> h = f h" |
45899 | 110 |
by (auto intro!: lfp_unfold) |
24915 | 111 |
|
63400 | 112 |
lemma def_lfp_induct: "A \<equiv> lfp f \<Longrightarrow> mono f \<Longrightarrow> f (inf A P) \<le> P \<Longrightarrow> A \<le> P" |
24915 | 113 |
by (blast intro: lfp_induct) |
114 |
||
63400 | 115 |
lemma def_lfp_induct_set: |
116 |
"A \<equiv> lfp f \<Longrightarrow> mono f \<Longrightarrow> a \<in> A \<Longrightarrow> (\<And>x. x \<in> f (A \<inter> {x. P x}) \<Longrightarrow> P x) \<Longrightarrow> P a" |
|
24915 | 117 |
by (blast intro: lfp_induct_set) |
118 |
||
63400 | 119 |
text \<open>Monotonicity of \<open>lfp\<close>!\<close> |
120 |
lemma lfp_mono: "(\<And>Z. f Z \<le> g Z) \<Longrightarrow> lfp f \<le> lfp g" |
|
121 |
by (rule lfp_lowerbound [THEN lfp_greatest]) (blast intro: order_trans) |
|
24915 | 122 |
|
123 |
||
63400 | 124 |
subsection \<open>Proof of Knaster-Tarski Theorem using \<open>gfp\<close>\<close> |
24915 | 125 |
|
63400 | 126 |
text \<open>@{term "gfp f"} is the greatest lower bound of the set @{term "{u. u \<le> f u}"}\<close> |
24915 | 127 |
|
63400 | 128 |
lemma gfp_upperbound: "X \<le> f X \<Longrightarrow> X \<le> gfp f" |
24915 | 129 |
by (auto simp add: gfp_def intro: Sup_upper) |
130 |
||
63400 | 131 |
lemma gfp_least: "(\<And>u. u \<le> f u \<Longrightarrow> u \<le> X) \<Longrightarrow> gfp f \<le> X" |
24915 | 132 |
by (auto simp add: gfp_def intro: Sup_least) |
133 |
||
63400 | 134 |
lemma gfp_lemma2: "mono f \<Longrightarrow> gfp f \<le> f (gfp f)" |
24915 | 135 |
by (iprover intro: gfp_least order_trans monoD gfp_upperbound) |
136 |
||
63400 | 137 |
lemma gfp_lemma3: "mono f \<Longrightarrow> f (gfp f) \<le> gfp f" |
24915 | 138 |
by (iprover intro: gfp_lemma2 monoD gfp_upperbound) |
139 |
||
63400 | 140 |
lemma gfp_unfold: "mono f \<Longrightarrow> gfp f = f (gfp f)" |
24915 | 141 |
by (iprover intro: order_antisym gfp_lemma2 gfp_lemma3) |
142 |
||
143 |
||
60758 | 144 |
subsection \<open>Coinduction rules for greatest fixed points\<close> |
24915 | 145 |
|
63400 | 146 |
text \<open>Weak version.\<close> |
147 |
lemma weak_coinduct: "a \<in> X \<Longrightarrow> X \<subseteq> f X \<Longrightarrow> a \<in> gfp f" |
|
45899 | 148 |
by (rule gfp_upperbound [THEN subsetD]) auto |
24915 | 149 |
|
63400 | 150 |
lemma weak_coinduct_image: "a \<in> X \<Longrightarrow> g`X \<subseteq> f (g`X) \<Longrightarrow> g a \<in> gfp f" |
45899 | 151 |
apply (erule gfp_upperbound [THEN subsetD]) |
152 |
apply (erule imageI) |
|
153 |
done |
|
24915 | 154 |
|
63400 | 155 |
lemma coinduct_lemma: "X \<le> f (sup X (gfp f)) \<Longrightarrow> mono f \<Longrightarrow> sup X (gfp f) \<le> f (sup X (gfp f))" |
24915 | 156 |
apply (frule gfp_lemma2) |
157 |
apply (drule mono_sup) |
|
158 |
apply (rule le_supI) |
|
159 |
apply assumption |
|
160 |
apply (rule order_trans) |
|
161 |
apply (rule order_trans) |
|
162 |
apply assumption |
|
163 |
apply (rule sup_ge2) |
|
164 |
apply assumption |
|
165 |
done |
|
166 |
||
63400 | 167 |
text \<open>Strong version, thanks to Coen and Frost.\<close> |
168 |
lemma coinduct_set: "mono f \<Longrightarrow> a \<in> X \<Longrightarrow> X \<subseteq> f (X \<union> gfp f) \<Longrightarrow> a \<in> gfp f" |
|
55604 | 169 |
by (rule weak_coinduct[rotated], rule coinduct_lemma) blast+ |
24915 | 170 |
|
63400 | 171 |
lemma gfp_fun_UnI2: "mono f \<Longrightarrow> a \<in> gfp f \<Longrightarrow> a \<in> f (X \<union> gfp f)" |
45899 | 172 |
by (blast dest: gfp_lemma2 mono_Un) |
24915 | 173 |
|
60174
70d8f7abde8f
strengthened lfp_ordinal_induct; added dual gfp variant
hoelzl
parents:
60173
diff
changeset
|
174 |
lemma gfp_ordinal_induct[case_names mono step union]: |
61076 | 175 |
fixes f :: "'a::complete_lattice \<Rightarrow> 'a" |
60174
70d8f7abde8f
strengthened lfp_ordinal_induct; added dual gfp variant
hoelzl
parents:
60173
diff
changeset
|
176 |
assumes mono: "mono f" |
63400 | 177 |
and P_f: "\<And>S. P S \<Longrightarrow> gfp f \<le> S \<Longrightarrow> P (f S)" |
178 |
and P_Union: "\<And>M. \<forall>S\<in>M. P S \<Longrightarrow> P (Inf M)" |
|
60174
70d8f7abde8f
strengthened lfp_ordinal_induct; added dual gfp variant
hoelzl
parents:
60173
diff
changeset
|
179 |
shows "P (gfp f)" |
70d8f7abde8f
strengthened lfp_ordinal_induct; added dual gfp variant
hoelzl
parents:
60173
diff
changeset
|
180 |
proof - |
70d8f7abde8f
strengthened lfp_ordinal_induct; added dual gfp variant
hoelzl
parents:
60173
diff
changeset
|
181 |
let ?M = "{S. gfp f \<le> S \<and> P S}" |
70d8f7abde8f
strengthened lfp_ordinal_induct; added dual gfp variant
hoelzl
parents:
60173
diff
changeset
|
182 |
have "P (Inf ?M)" using P_Union by simp |
70d8f7abde8f
strengthened lfp_ordinal_induct; added dual gfp variant
hoelzl
parents:
60173
diff
changeset
|
183 |
also have "Inf ?M = gfp f" |
70d8f7abde8f
strengthened lfp_ordinal_induct; added dual gfp variant
hoelzl
parents:
60173
diff
changeset
|
184 |
proof (rule antisym) |
63400 | 185 |
show "gfp f \<le> Inf ?M" |
186 |
by (blast intro: Inf_greatest) |
|
187 |
then have "f (gfp f) \<le> f (Inf ?M)" |
|
188 |
by (rule mono [THEN monoD]) |
|
189 |
then have "gfp f \<le> f (Inf ?M)" |
|
190 |
using mono [THEN gfp_unfold] by simp |
|
191 |
then have "f (Inf ?M) \<in> ?M" |
|
192 |
using P_Union by simp (intro P_f Inf_greatest, auto) |
|
193 |
then have "Inf ?M \<le> f (Inf ?M)" |
|
194 |
by (rule Inf_lower) |
|
195 |
then show "Inf ?M \<le> gfp f" |
|
196 |
by (rule gfp_upperbound) |
|
60174
70d8f7abde8f
strengthened lfp_ordinal_induct; added dual gfp variant
hoelzl
parents:
60173
diff
changeset
|
197 |
qed |
70d8f7abde8f
strengthened lfp_ordinal_induct; added dual gfp variant
hoelzl
parents:
60173
diff
changeset
|
198 |
finally show ?thesis . |
63400 | 199 |
qed |
60174
70d8f7abde8f
strengthened lfp_ordinal_induct; added dual gfp variant
hoelzl
parents:
60173
diff
changeset
|
200 |
|
63400 | 201 |
lemma coinduct: |
202 |
assumes mono: "mono f" |
|
203 |
and ind: "X \<le> f (sup X (gfp f))" |
|
204 |
shows "X \<le> gfp f" |
|
60174
70d8f7abde8f
strengthened lfp_ordinal_induct; added dual gfp variant
hoelzl
parents:
60173
diff
changeset
|
205 |
proof (induction rule: gfp_ordinal_induct) |
70d8f7abde8f
strengthened lfp_ordinal_induct; added dual gfp variant
hoelzl
parents:
60173
diff
changeset
|
206 |
case (step S) then show ?case |
70d8f7abde8f
strengthened lfp_ordinal_induct; added dual gfp variant
hoelzl
parents:
60173
diff
changeset
|
207 |
by (intro order_trans[OF ind _] monoD[OF mono]) auto |
70d8f7abde8f
strengthened lfp_ordinal_induct; added dual gfp variant
hoelzl
parents:
60173
diff
changeset
|
208 |
qed (auto intro: mono Inf_greatest) |
24915 | 209 |
|
63400 | 210 |
|
60758 | 211 |
subsection \<open>Even Stronger Coinduction Rule, by Martin Coen\<close> |
24915 | 212 |
|
63400 | 213 |
text \<open>Weakens the condition @{term "X \<subseteq> f X"} to one expressed using both |
60758 | 214 |
@{term lfp} and @{term gfp}\<close> |
63400 | 215 |
lemma coinduct3_mono_lemma: "mono f \<Longrightarrow> mono (\<lambda>x. f x \<union> X \<union> B)" |
216 |
by (iprover intro: subset_refl monoI Un_mono monoD) |
|
24915 | 217 |
|
218 |
lemma coinduct3_lemma: |
|
63400 | 219 |
"X \<subseteq> f (lfp (\<lambda>x. f x \<union> X \<union> gfp f)) \<Longrightarrow> mono f \<Longrightarrow> |
220 |
lfp (\<lambda>x. f x \<union> X \<union> gfp f) \<subseteq> f (lfp (\<lambda>x. f x \<union> X \<union> gfp f))" |
|
221 |
apply (rule subset_trans) |
|
222 |
apply (erule coinduct3_mono_lemma [THEN lfp_lemma3]) |
|
223 |
apply (rule Un_least [THEN Un_least]) |
|
224 |
apply (rule subset_refl, assumption) |
|
225 |
apply (rule gfp_unfold [THEN equalityD1, THEN subset_trans], assumption) |
|
226 |
apply (rule monoD, assumption) |
|
227 |
apply (subst coinduct3_mono_lemma [THEN lfp_unfold], auto) |
|
228 |
done |
|
24915 | 229 |
|
63400 | 230 |
lemma coinduct3: "mono f \<Longrightarrow> a \<in> X \<Longrightarrow> X \<subseteq> f (lfp (\<lambda>x. f x \<union> X \<union> gfp f)) \<Longrightarrow> a \<in> gfp f" |
231 |
apply (rule coinduct3_lemma [THEN [2] weak_coinduct]) |
|
232 |
apply (rule coinduct3_mono_lemma [THEN lfp_unfold, THEN ssubst]) |
|
233 |
apply simp_all |
|
234 |
done |
|
24915 | 235 |
|
63400 | 236 |
text \<open>Definition forms of \<open>gfp_unfold\<close> and \<open>coinduct\<close>, to control unfolding.\<close> |
24915 | 237 |
|
63400 | 238 |
lemma def_gfp_unfold: "A \<equiv> gfp f \<Longrightarrow> mono f \<Longrightarrow> A = f A" |
45899 | 239 |
by (auto intro!: gfp_unfold) |
24915 | 240 |
|
63400 | 241 |
lemma def_coinduct: "A \<equiv> gfp f \<Longrightarrow> mono f \<Longrightarrow> X \<le> f (sup X A) \<Longrightarrow> X \<le> A" |
45899 | 242 |
by (iprover intro!: coinduct) |
24915 | 243 |
|
63400 | 244 |
lemma def_coinduct_set: "A \<equiv> gfp f \<Longrightarrow> mono f \<Longrightarrow> a \<in> X \<Longrightarrow> X \<subseteq> f (X \<union> A) \<Longrightarrow> a \<in> A" |
45899 | 245 |
by (auto intro!: coinduct_set) |
24915 | 246 |
|
247 |
lemma def_Collect_coinduct: |
|
63400 | 248 |
"A \<equiv> gfp (\<lambda>w. Collect (P w)) \<Longrightarrow> mono (\<lambda>w. Collect (P w)) \<Longrightarrow> a \<in> X \<Longrightarrow> |
249 |
(\<And>z. z \<in> X \<Longrightarrow> P (X \<union> A) z) \<Longrightarrow> a \<in> A" |
|
45899 | 250 |
by (erule def_coinduct_set) auto |
24915 | 251 |
|
63400 | 252 |
lemma def_coinduct3: "A \<equiv> gfp f \<Longrightarrow> mono f \<Longrightarrow> a \<in> X \<Longrightarrow> X \<subseteq> f (lfp (\<lambda>x. f x \<union> X \<union> A)) \<Longrightarrow> a \<in> A" |
45899 | 253 |
by (auto intro!: coinduct3) |
24915 | 254 |
|
63400 | 255 |
text \<open>Monotonicity of @{term gfp}!\<close> |
256 |
lemma gfp_mono: "(\<And>Z. f Z \<le> g Z) \<Longrightarrow> gfp f \<le> gfp g" |
|
257 |
by (rule gfp_upperbound [THEN gfp_least]) (blast intro: order_trans) |
|
258 |
||
24915 | 259 |
|
60758 | 260 |
subsection \<open>Rules for fixed point calculus\<close> |
60173 | 261 |
|
262 |
lemma lfp_rolling: |
|
263 |
assumes "mono g" "mono f" |
|
264 |
shows "g (lfp (\<lambda>x. f (g x))) = lfp (\<lambda>x. g (f x))" |
|
265 |
proof (rule antisym) |
|
266 |
have *: "mono (\<lambda>x. f (g x))" |
|
267 |
using assms by (auto simp: mono_def) |
|
268 |
show "lfp (\<lambda>x. g (f x)) \<le> g (lfp (\<lambda>x. f (g x)))" |
|
269 |
by (rule lfp_lowerbound) (simp add: lfp_unfold[OF *, symmetric]) |
|
270 |
show "g (lfp (\<lambda>x. f (g x))) \<le> lfp (\<lambda>x. g (f x))" |
|
271 |
proof (rule lfp_greatest) |
|
63400 | 272 |
fix u |
273 |
assume "g (f u) \<le> u" |
|
60173 | 274 |
moreover then have "g (lfp (\<lambda>x. f (g x))) \<le> g (f u)" |
275 |
by (intro assms[THEN monoD] lfp_lowerbound) |
|
276 |
ultimately show "g (lfp (\<lambda>x. f (g x))) \<le> u" |
|
277 |
by auto |
|
278 |
qed |
|
279 |
qed |
|
280 |
||
281 |
lemma lfp_lfp: |
|
282 |
assumes f: "\<And>x y w z. x \<le> y \<Longrightarrow> w \<le> z \<Longrightarrow> f x w \<le> f y z" |
|
283 |
shows "lfp (\<lambda>x. lfp (f x)) = lfp (\<lambda>x. f x x)" |
|
284 |
proof (rule antisym) |
|
285 |
have *: "mono (\<lambda>x. f x x)" |
|
286 |
by (blast intro: monoI f) |
|
287 |
show "lfp (\<lambda>x. lfp (f x)) \<le> lfp (\<lambda>x. f x x)" |
|
288 |
by (intro lfp_lowerbound) (simp add: lfp_unfold[OF *, symmetric]) |
|
289 |
show "lfp (\<lambda>x. lfp (f x)) \<ge> lfp (\<lambda>x. f x x)" (is "?F \<ge> _") |
|
290 |
proof (intro lfp_lowerbound) |
|
291 |
have *: "?F = lfp (f ?F)" |
|
292 |
by (rule lfp_unfold) (blast intro: monoI lfp_mono f) |
|
293 |
also have "\<dots> = f ?F (lfp (f ?F))" |
|
294 |
by (rule lfp_unfold) (blast intro: monoI lfp_mono f) |
|
295 |
finally show "f ?F ?F \<le> ?F" |
|
296 |
by (simp add: *[symmetric]) |
|
297 |
qed |
|
298 |
qed |
|
299 |
||
300 |
lemma gfp_rolling: |
|
301 |
assumes "mono g" "mono f" |
|
302 |
shows "g (gfp (\<lambda>x. f (g x))) = gfp (\<lambda>x. g (f x))" |
|
303 |
proof (rule antisym) |
|
304 |
have *: "mono (\<lambda>x. f (g x))" |
|
305 |
using assms by (auto simp: mono_def) |
|
306 |
show "g (gfp (\<lambda>x. f (g x))) \<le> gfp (\<lambda>x. g (f x))" |
|
307 |
by (rule gfp_upperbound) (simp add: gfp_unfold[OF *, symmetric]) |
|
308 |
show "gfp (\<lambda>x. g (f x)) \<le> g (gfp (\<lambda>x. f (g x)))" |
|
309 |
proof (rule gfp_least) |
|
310 |
fix u assume "u \<le> g (f u)" |
|
311 |
moreover then have "g (f u) \<le> g (gfp (\<lambda>x. f (g x)))" |
|
312 |
by (intro assms[THEN monoD] gfp_upperbound) |
|
313 |
ultimately show "u \<le> g (gfp (\<lambda>x. f (g x)))" |
|
314 |
by auto |
|
315 |
qed |
|
316 |
qed |
|
317 |
||
318 |
lemma gfp_gfp: |
|
319 |
assumes f: "\<And>x y w z. x \<le> y \<Longrightarrow> w \<le> z \<Longrightarrow> f x w \<le> f y z" |
|
320 |
shows "gfp (\<lambda>x. gfp (f x)) = gfp (\<lambda>x. f x x)" |
|
321 |
proof (rule antisym) |
|
322 |
have *: "mono (\<lambda>x. f x x)" |
|
323 |
by (blast intro: monoI f) |
|
324 |
show "gfp (\<lambda>x. f x x) \<le> gfp (\<lambda>x. gfp (f x))" |
|
325 |
by (intro gfp_upperbound) (simp add: gfp_unfold[OF *, symmetric]) |
|
326 |
show "gfp (\<lambda>x. gfp (f x)) \<le> gfp (\<lambda>x. f x x)" (is "?F \<le> _") |
|
327 |
proof (intro gfp_upperbound) |
|
328 |
have *: "?F = gfp (f ?F)" |
|
329 |
by (rule gfp_unfold) (blast intro: monoI gfp_mono f) |
|
330 |
also have "\<dots> = f ?F (gfp (f ?F))" |
|
331 |
by (rule gfp_unfold) (blast intro: monoI gfp_mono f) |
|
332 |
finally show "?F \<le> f ?F ?F" |
|
333 |
by (simp add: *[symmetric]) |
|
334 |
qed |
|
335 |
qed |
|
24915 | 336 |
|
63400 | 337 |
|
60758 | 338 |
subsection \<open>Inductive predicates and sets\<close> |
11688 | 339 |
|
60758 | 340 |
text \<open>Package setup.\<close> |
10402 | 341 |
|
61337 | 342 |
lemmas basic_monos = |
22218 | 343 |
subset_refl imp_refl disj_mono conj_mono ex_mono all_mono if_bool_eq_conj |
11688 | 344 |
Collect_mono in_mono vimage_mono |
345 |
||
48891 | 346 |
ML_file "Tools/inductive.ML" |
21018
e6b8d6784792
Added new package for inductive definitions, moved old package
berghofe
parents:
20604
diff
changeset
|
347 |
|
61337 | 348 |
lemmas [mono] = |
22218 | 349 |
imp_refl disj_mono conj_mono ex_mono all_mono if_bool_eq_conj |
33934
25d6a8982e37
Streamlined setup for monotonicity rules (no longer requires classical rules).
berghofe
parents:
32701
diff
changeset
|
350 |
imp_mono not_mono |
21018
e6b8d6784792
Added new package for inductive definitions, moved old package
berghofe
parents:
20604
diff
changeset
|
351 |
Ball_def Bex_def |
e6b8d6784792
Added new package for inductive definitions, moved old package
berghofe
parents:
20604
diff
changeset
|
352 |
induct_rulify_fallback |
e6b8d6784792
Added new package for inductive definitions, moved old package
berghofe
parents:
20604
diff
changeset
|
353 |
|
11688 | 354 |
|
60758 | 355 |
subsection \<open>Inductive datatypes and primitive recursion\<close> |
11688 | 356 |
|
60758 | 357 |
text \<open>Package setup.\<close> |
11825 | 358 |
|
58112
8081087096ad
renamed modules defining old datatypes, as a step towards having 'datatype_new' take 'datatype's place
blanchet
parents:
56146
diff
changeset
|
359 |
ML_file "Tools/Old_Datatype/old_datatype_aux.ML" |
8081087096ad
renamed modules defining old datatypes, as a step towards having 'datatype_new' take 'datatype's place
blanchet
parents:
56146
diff
changeset
|
360 |
ML_file "Tools/Old_Datatype/old_datatype_prop.ML" |
58187
d2ddd401d74d
fixed infinite loops in 'register' functions + more uniform API
blanchet
parents:
58112
diff
changeset
|
361 |
ML_file "Tools/Old_Datatype/old_datatype_data.ML" |
58112
8081087096ad
renamed modules defining old datatypes, as a step towards having 'datatype_new' take 'datatype's place
blanchet
parents:
56146
diff
changeset
|
362 |
ML_file "Tools/Old_Datatype/old_rep_datatype.ML" |
8081087096ad
renamed modules defining old datatypes, as a step towards having 'datatype_new' take 'datatype's place
blanchet
parents:
56146
diff
changeset
|
363 |
ML_file "Tools/Old_Datatype/old_datatype_codegen.ML" |
8081087096ad
renamed modules defining old datatypes, as a step towards having 'datatype_new' take 'datatype's place
blanchet
parents:
56146
diff
changeset
|
364 |
ML_file "Tools/Old_Datatype/old_primrec.ML" |
12437
6d4e02b6dd43
Moved code generator setup from Recdef to Inductive.
berghofe
parents:
12023
diff
changeset
|
365 |
|
55575
a5e33e18fb5c
moved 'primrec' up (for real this time) and removed temporary 'old_primrec'
blanchet
parents:
55534
diff
changeset
|
366 |
ML_file "Tools/BNF/bnf_fp_rec_sugar_util.ML" |
a5e33e18fb5c
moved 'primrec' up (for real this time) and removed temporary 'old_primrec'
blanchet
parents:
55534
diff
changeset
|
367 |
ML_file "Tools/BNF/bnf_lfp_rec_sugar.ML" |
a5e33e18fb5c
moved 'primrec' up (for real this time) and removed temporary 'old_primrec'
blanchet
parents:
55534
diff
changeset
|
368 |
|
61955
e96292f32c3c
former "xsymbols" syntax is used by default, and ASCII replacement syntax with print mode "ASCII";
wenzelm
parents:
61952
diff
changeset
|
369 |
text \<open>Lambda-abstractions with pattern matching:\<close> |
e96292f32c3c
former "xsymbols" syntax is used by default, and ASCII replacement syntax with print mode "ASCII";
wenzelm
parents:
61952
diff
changeset
|
370 |
syntax (ASCII) |
e96292f32c3c
former "xsymbols" syntax is used by default, and ASCII replacement syntax with print mode "ASCII";
wenzelm
parents:
61952
diff
changeset
|
371 |
"_lam_pats_syntax" :: "cases_syn \<Rightarrow> 'a \<Rightarrow> 'b" ("(%_)" 10) |
23526 | 372 |
syntax |
61955
e96292f32c3c
former "xsymbols" syntax is used by default, and ASCII replacement syntax with print mode "ASCII";
wenzelm
parents:
61952
diff
changeset
|
373 |
"_lam_pats_syntax" :: "cases_syn \<Rightarrow> 'a \<Rightarrow> 'b" ("(\<lambda>_)" 10) |
60758 | 374 |
parse_translation \<open> |
52143 | 375 |
let |
376 |
fun fun_tr ctxt [cs] = |
|
377 |
let |
|
378 |
val x = Syntax.free (fst (Name.variant "x" (Term.declare_term_frees cs Name.context))); |
|
379 |
val ft = Case_Translation.case_tr true ctxt [x, cs]; |
|
380 |
in lambda x ft end |
|
381 |
in [(@{syntax_const "_lam_pats_syntax"}, fun_tr)] end |
|
60758 | 382 |
\<close> |
23526 | 383 |
|
384 |
end |