You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Let's show the existence of a fixpoint, as in the Knaster-Tarski theorem.
63
+
The proof is by well-founded induction.
64
+
-/
41
65
theoremfixpoint_exists_1 [Monotone α F] : ∃ x : α, eq x (F x) := by
42
66
have REC : ∀ x : α, le x (F x) -> ∃ y : α , eq y (F y) := by
43
67
intro x
@@ -59,6 +83,32 @@ theorem fixpoint_exists_1 [Monotone α F] : ∃ x : α, eq x (F x) := by
59
83
apply REC
60
84
apply bot_smallest
61
85
86
+
/-
87
+
Unfortunately, we cannot extract the value of the fixpoint.
88
+
-/
89
+
/--
90
+
error: Tactic `cases` failed with a nested error:
91
+
Tactic `induction` failed: recursor `Exists.casesOn` can only eliminate into `Prop`
92
+
93
+
α : Sort u
94
+
F : α → α
95
+
inst✝ : OrderWithBot α
96
+
motive : (∃ x, eq x (F x)) → Sort ?u.1192
97
+
h_1 : (x : α) → (P : eq x (F x)) → motive ⋯
98
+
fixpoint✝ : ∃ x, eq x (F x)
99
+
⊢ motive fixpoint✝ after processing
100
+
_
101
+
the dependent pattern matcher can solve the following kinds of equations
102
+
- <var> = <term> and <term> = <var>
103
+
- <term> = <term> where the terms are definitionally equal
104
+
- <constructor> = <constructor>, examples: List.cons x xs = List.cons y ys, and List.cons x xs = List.nil
105
+
-/
106
+
#guard_msgsin
107
+
defcannotExtractFixpoint [Monotone α F] : α :=
108
+
let fixpoint := fixpoint_exists_1 α F
109
+
match fixpoint with
110
+
| ⟨x, P⟩ => x
111
+
62
112
end FixpointExistence
63
113
64
114
section Iterate
@@ -71,12 +121,29 @@ instance : WellFoundedRelation α where
71
121
rel := gt
72
122
wf := gt_wf
73
123
124
+
/-
125
+
We can alternatively write the iteration algorithm explicitly,
126
+
proving later that it is correct.
127
+
128
+
The algorithm is simple: we iterate `F` starting from a pre-fixpoint `x`
129
+
130
+
The `iterate` function takes as argument not just `x`, but also two proofs:
131
+
- that `x` is a pre-fixpoint, i.e. `le x (F x)`
132
+
- that `x` is below any post-fixpoint `z`.
133
+
134
+
Likewise, it returns as result not just the fixpoint `y`, but also two proofs:
135
+
- that `y` is a fixpoint, i.e. `eq y (F y)`
136
+
- that `y` is below any post-fixpoint `z`.
137
+
-/
74
138
@[grind]defiterate (x : α) (PRE : le x (F x)) (SMALL : ∀ z, le (F z) z -> le x z) : α :=
75
139
if beq x (F x) then x else iterate (F x) (by apply F_mon; exact PRE) (by intro z hyp; specialize SMALL z hyp; apply le_trans; apply F_mon; exact SMALL; exact hyp)
76
140
termination_by x
77
141
decreasing_by
78
142
grind [beq_false']
79
143
144
+
/-
145
+
We then prove that the algorithm implemented above indeed calculates the least fixpoint of `F`.
146
+
-/
80
147
@[grind]theoremiterate_correct (x : α) (PRE : le x (F x)) (SMALL : ∀ z, le (F z) z -> le x z) (heq : y = iterate _ F x PRE SMALL ) : eq y (F y) ∧ ∀ z, le (F z) z → le y z := by
0 commit comments