-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathrecursion.lean
220 lines (202 loc) · 5.67 KB
/
recursion.lean
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
/-
f = ( nat n ↦ ( n<3 ? n : ( even(n) ? f(n−2)+f(n−3) : f(n−1)+f(n+1) ) ) )
where even = ( nat n ↦ exists m in nat ( m*2=n ) )
-/
def even : nat → Prop :=
λ n, ∃ m, m * 2 = n
def odd : nat → Prop :=
λ n, ∃ m, nat.succ (m * 2) = n
theorem even_xor_odd (n : nat) : xor (even n) (odd n) :=
begin
induction n with n ih,
{ left,
split,
{ existsi 0,
refl },
{ intro h,
cases h with n h,
exact nat.no_confusion h, } },
{ cases ih; cases ih with ih1 ih2,
{ right,
split,
{ cases ih1 with m hm,
existsi m,
rw hm },
{ intro h,
cases h with m hm,
cases m with m,
{ exact nat.no_confusion hm },
{ rw [nat.mul_succ, nat.add_succ, nat.add_comm, nat.mul_one, nat.add_succ] at hm,
apply ih2,
existsi m,
rw [nat.mul_succ, nat.mul_one],
exact nat.succ_inj hm } } },
{ left,
split,
{ cases ih1 with m hm,
cases m with m,
{ existsi 1,
rw ← hm,
refl },
{ existsi m + 2,
rw [← hm],
simp [add_mul, nat.succ_mul, nat.succ_eq_add_one],
rw [← add_assoc, ← add_assoc, ← add_assoc] } },
{ intro ih,
cases ih with m ih,
apply ih2,
existsi m,
exact nat.succ_inj ih } } }
end
theorem odd_of_not_even (n : nat) : ¬ even n → odd n :=
λ h, or.cases_on (even_xor_odd n) (λ h1, false.elim $ h h1.1) and.left
theorem not_even_of_odd (n : nat) : odd n → ¬ even n :=
λ h1 h2, or.cases_on (even_xor_odd n) (λ h3, h3.2 h1) (λ h3, h3.2 h2)
theorem even_of_even_add_two : ∀ n, even (n+2) → even n
| 0 _ := ⟨0, rfl⟩
| n ⟨0, hm⟩ := false.elim $ nat.no_confusion hm
| n ⟨nat.succ m, hm⟩ := ⟨m, by simp [nat.succ_eq_add_one, add_mul] at hm;
rw add_comm at hm;
exact nat.add_right_cancel hm⟩
theorem not_even_of_even_succ : ∀ n, even (n+1) → ¬even n
| n ⟨0, hm⟩ := nat.no_confusion hm
| n ⟨nat.succ m, hm⟩ := not_even_of_odd _ ⟨m, by rw [← nat.succ_inj hm, add_comm, nat.mul_succ, add_comm]; refl⟩
theorem even_of_not_even_succ : ∀ n, ¬ even (n+1) → even n
| 0 _ := ⟨0, rfl⟩
| (nat.succ n) hm := let ⟨m, hm⟩ := odd_of_not_even _ hm in ⟨m, nat.succ_inj hm⟩
theorem even_succ_of_not_even : ∀ n, ¬ even n → even (n+1) :=
λ n h, let ⟨m, hm⟩ := odd_of_not_even _ h in ⟨m+1, hm ▸ by rw [add_mul]; refl⟩
instance : decidable_pred even :=
begin
intro n,
induction n with n ih,
{ right,
existsi 0,
refl },
{ cases ih,
{ right,
cases even_xor_odd n with h h,
{ exfalso,
exact ih h.1 },
{ cases h.1 with m hm,
cases m with m,
{ existsi 1,
rw ← hm,
refl },
{ existsi m + 2,
rw [← hm],
simp [add_mul, nat.succ_mul, nat.succ_eq_add_one],
rw [← add_assoc, ← add_assoc, ← add_assoc] } } },
{ left,
intro h1,
cases even_xor_odd (nat.succ n) with h h,
{ apply h.2,
cases ih with p hp,
existsi p,
rw hp },
{ exact h.2 h1 } } }
end
def aux : nat → nat
| n := if n < 3 then n else
if even n then n - 1 else n + 1
instance aux2 : has_well_founded ℕ :=
{ r := inv_image (<) aux,
wf := inv_image.wf aux nat.lt_wf }
theorem nat.le_of_not_gt {n m : nat} : ¬ m > n → m ≤ n :=
begin
intro h,
cases nat.lt_trichotomy m n with h1 h1,
{ exact nat.le_of_lt h1 },
cases h1 with h1 h1,
{ rw h1 },
{ exfalso,
exact h h1 }
end
theorem aux3 (n : nat) (H1 : ¬n < 3) (H2 : even n) : aux (n - 2) < aux n :=
begin
have H3 := nat.le_of_not_gt H1,
rw [aux, aux, if_neg H1, if_pos H2],
let m := n - 3,
have H4 : n = m + 3,
{ dsimp [m], rw [nat.sub_add_cancel H3] },
rw H4 at *,
simp,
by_cases m + 1 < 3,
{ simp [h],
apply add_lt_add_left,
constructor },
{ simp [h, even_of_even_add_two _ H2],
apply nat.lt_add_of_pos_right,
constructor,
constructor }
end
theorem aux4 (n : nat) (H1 : ¬n < 3) (H2 : even n) : aux (n - 3) < aux n :=
begin
have H3 := nat.le_of_not_gt H1,
simp [aux, H1, H2],
let m := n - 3,
have H4 : n = m + 3,
{ dsimp [m], rw [nat.sub_add_cancel H3] },
rw H4 at *,
simp,
by_cases m < 3,
{ simp [h],
apply nat.lt_add_of_pos_right,
constructor,
constructor },
{ simp [h],
simp [not_even_of_even_succ _ (even_of_even_add_two _ H2)],
apply nat.add_lt_add_left,
constructor }
end
theorem aux5 (n : nat) (H1 : ¬n < 3) (H2 : ¬even n) : aux (n - 1) < aux n :=
begin
have H3 := nat.le_of_not_gt H1,
simp [aux, H1, H2],
let m := n - 3,
have H4 : n = m + 3,
{ dsimp [m], rw [nat.sub_add_cancel H3] },
rw H4 at *,
simp,
by_cases m + 2 < 3,
{ simp [h],
apply nat.add_lt_add_left,
constructor,
constructor },
{ simp [h],
simp [even_of_not_even_succ _ H2],
apply nat.add_lt_add_left,
constructor,
constructor,
constructor }
end
theorem aux6 (n : nat) (H1 : ¬n < 3) (H2 : ¬even n) : aux (n + 1) < aux n :=
begin
have H3 := nat.le_of_not_gt H1,
simp [aux, H1, H2],
let m := n - 3,
have H4 : n = m + 3,
{ dsimp [m], rw [nat.sub_add_cancel H3] },
rw H4 at *,
simp,
by_cases m + 4 < 3,
{ exfalso,
cases h with h h,
cases h with h h,
cases h with h h,
cases h with h h },
{ simp [h],
simp [even_succ_of_not_even _ H2],
apply add_lt_add_left,
constructor }
end
def f : nat → nat
| n := if H1 : n < 3 then n else
if H2 : even n then
f (n - 2) + f (n - 3)
else
f (n - 1) + f (n + 1)
using_well_founded
{ dec_tac := `[exact aux3 n H1 H2 <|> exact aux4 n H1 H2 <|>
exact aux5 n H1 H2 <|> exact aux6 n H1 H2],
rel_tac := λ _ _, `[exact aux2] }