-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathNat.lp
336 lines (304 loc) · 8.22 KB
/
Nat.lp
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
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
require open AL_library.Notation
require open AL_library.Constructive_logic
// Type of natural numbers
constant symbol nat : Set
set declared "ℕ"
definition ℕ ≔ τ nat
constant symbol zero : ℕ
constant symbol succ : ℕ → ℕ
// Enabling builtin natural number literals
set builtin "0" ≔ zero
set builtin "+1" ≔ succ
assert 42 : ℕ // example
// Induction principle
symbol nat_ind p : π (p 0) → (Πx, π (p x) → π (p (succ x))) → Πx, π (p x)
rule nat_ind _ $u _ 0 ↪ $u
with nat_ind $p $u $v (succ $n) ↪ $v $n (nat_ind $p $u $v $n)
//symbol nat_ind_math : π (∀ (λp : ℕ → Prop, p 0))
//Π(P :ℕ → Prop), π(∃P) → π (¬(∀ (λm:ℕ, ¬ (P m))))
// Injective principle
symbol nat_inj : Πn m, π ((succ n) = (succ m)) → π (n = m) // A voir !
///////////////////////////////
// Addition
///////////////////////////////
//Fixpoint plus n m :=
// match n with
// | 0 => m
// | S n' => S (plus n' m)
// end.
symbol plus : ℕ → ℕ → ℕ
set infix left 6 "+" ≔ plus
assert λx y z,x+y+z ≡ λx y z,(x+y)+z // check that x+y=z is parsed correctly
rule 0 + $y ↪ $y
with succ $x + $y ↪ succ ($x + $y)
// Eval compute in (0 + 1).
compute 0+1
// Eval compute in (plus 1 1).
compute plus 1 1
//Lemma plus_0_n : forall n, 0 + n = n.
//Proof.
//intro n. simpl. reflexivity.
//Qed.
theorem plus_0_n : Πn, π ((0 + n) = n)
proof
assume n
reflexivity
qed
// Addition is commutative
//Lemma plus_n_0 : forall n, n + O = n.
//Proof.
//induction n.
//+ simpl. reflexivity.
//+ simpl. rewrite IHn. reflexivity.
//Qed.
theorem plus_n_0 : Πn, π ((n + 0) = n)
proof
assume n
refine nat_ind (λz, (z + 0) = z) _ _ _
// Case n = O
refine eq_refl 0
// Case = S n'
assume n' Hn'
simpl
rewrite Hn'
reflexivity
qed
//rule $x + 0 ↪ $x
//Lemma plus_n_Sm : forall n m,
// n + S m = S (n + m).
//Proof.
//induction n ; intro m ; simpl.
//+ reflexivity.
//+ rewrite IHn. reflexivity.
//Qed.
theorem plus_n_Sm : Πn m, π ((n + (succ m)) = (succ (n + m)))
proof
assume n m
refine nat_ind (λz, ((z + (succ m)) = (succ (z + m)))) _ _ n
reflexivity
simpl
assume n' Hn'
rewrite Hn'
reflexivity
qed
//rule $x + succ $y ↪ succ ($x + $y)
//Lemma plus_comm : forall n m, n+m=m+n.
//Proof.
//induction n ; intros m0.
//+ simpl. rewrite plus_n_0. reflexivity.
//+ simpl. rewrite IHn. rewrite plus_n_Sm. reflexivity.
//Qed.
theorem plus_comm : Πn m, π((n + m) = (m + n))
proof
assume n m
refine nat_ind (λz, ((z + m) = (m + z))) _ _ n
simpl rewrite plus_n_0 reflexivity
simpl assume n' Hn' rewrite Hn' rewrite plus_n_Sm reflexivity
qed
// Addition is associative
//Lemma plus_assoc : forall n m p,
// n+(m+p) = n+m+p.
//Proof.
//induction n ; intros m p.
//+ simpl. reflexivity.
//+ simpl. rewrite IHn. reflexivity.
//Qed.
theorem plus_assoc : Πn m p, π ((n+(m+p)) = (n+m+p))
proof
assume n m p
refine nat_ind (λz, (z+(m+p)) = (z+m+p)) _ _ n
reflexivity
assume n' Hn'
simpl
rewrite Hn'
reflexivity
qed
//rule ($x + $y) + $z ↪ $x + ($y + $z)
/////////////////////////////////////
// Multiplication
/////////////////////////////////////
//Fixpoint mult (n m : nat) : nat :=
// match n with
// | O => 0
// | S n' => m + (mult n' m)
// end.
symbol mult : ℕ → ℕ → ℕ
set infix left 7 "×" ≔ mult
rule 0 × _ ↪ 0
with succ $x × $y ↪ $y + $x × $y
assert λx y z,x+y×z ≡ λx y z,x+(y×z) // check that x+y×z is parsed correctly
//Lemma mult_0_n : forall n : nat, 0*n=0.
//Proof.
//intros. simpl. reflexivity.
//Qed.
theorem mult_0_n : Πn, π ((0 × n) = 0)
proof
assume n
refine eq_refl 0
qed
// Multiplication is commutative
//Lemma mult_n_0 : forall n, n*0= 0.
//Proof.
//induction n.
//+ apply mult_0_n.
//+ simpl. exact IHn.
// (* ou assumption*)
//Qed.
theorem mult_n_0 : Πn, π ((n × 0) = 0)
proof
refine nat_ind (λz, (z × 0) = 0) _ _
// Case n = O
refine eq_refl 0
// Case = S n'
assume n' Hn'
simpl
apply Hn'
qed
// rule _ × 0 ↪ 0
//Lemma mult_n_Sm : forall n m, n*S m=n+n*m.
//Proof.
//induction n ; intros m0 ; simpl.
//+ reflexivity.
//+ rewrite IHn.
// do 2 (rewrite plus_assoc).
// rewrite plus_comm with (n:=n) (m := m0). reflexivity.
//Qed.
theorem mult_n_Sm : Πn m, π ((n × succ m) = (n + n × m))
proof
assume n m
refine nat_ind (λz, (z × succ m) = (z + z × m)) _ _ n
reflexivity
assume n' Hn' simpl rewrite Hn'
rewrite plus_assoc rewrite plus_assoc rewrite plus_comm n' m reflexivity
qed
// rule $x × succ $y ↪ $x + $x × $y
//Lemma mult_comm : forall n m, n *m=m*n.
//Proof.
//induction n ; intros m0 ; simpl.
//+ rewrite mult_n_0. reflexivity.
//+ rewrite IHn. rewrite mult_n_Sm. reflexivity.
//Qed.
theorem mult_comm : Πn m, π ((n×m) = (m×n))
proof
assume n m
refine nat_ind (λz, ((z × m) = (m × z))) _ _ n
rewrite mult_n_0 reflexivity
assume n' Hn' simpl rewrite Hn'
rewrite mult_n_Sm reflexivity
qed
// Multiplication distributes over addition
//Lemma mult_plus_distr_r : forall n m p,
// (n+m)*p = n*p+m*p.
//Proof.
//induction n ; intros m p; simpl.
//+ reflexivity.
//+ rewrite IHn. apply plus_assoc.
//Qed.
theorem mult_plus_distr_r :
Πn m p, π (((n+m)×p) = ((n×p)+(m×p)))
proof
assume n m p
refine nat_ind
(λz, ((z+m)×p) = ((z×p)+(m×p))) _ _ n
reflexivity
assume n' Hn' simpl rewrite Hn'
apply plus_assoc p (n'×p) (m×p) // pas inféré
qed
//rule ($x + $y) × $z ↪ $x × $z + $y × $z
// Prouver directement
//Lemma mult_plus_distr_l : forall n m p,
// n*(m+p)=n*m+n*p.
//Proof.
//induction n; intros m p ; simpl.
//+ reflexivity.
//+ rewrite IHn.
// rewrite plus_comm with (n:=p) (m:=n*p).
// rewrite <- plus_assoc with (n:=m) (m:=n*m) (p:=n*p+p).
// rewrite plus_comm with (n:=m) (m:=n*m + (n*p + p)).
// do 2 (rewrite plus_assoc).
// rewrite plus_comm with (n:=m) (m:=p).
// rewrite <- plus_assoc with (n:=p + m) (m:=n*m) (p:=n*p).
// rewrite plus_comm with (n:=p + m) (m:=n*m + n*p).
// rewrite plus_assoc. reflexivity.
//Qed.
theorem plus_assoc_trash : Πn m p, π ((n+m+p) = (n+(m+p)))
proof
assume n m p
refine nat_ind (λz, (z+m+p) = (z+(m+p))) _ _ n
reflexivity
assume n' Hn'
simpl
rewrite Hn'
reflexivity
qed
theorem mult_plus_distr_l :
Πn m p, π ((n×(m+p)) = ((n×m)+(n×p)))
proof
assume n m p
refine nat_ind (λz, (z×(m+p)) = ((z×m)+(z×p))) _ _ n
// 0. π ((zero × (m + p)) = ((zero × m) + (zero × p)))
reflexivity
//1. Π(x:τ nat), π ((x × (m + p)) = ((x × m) + (x × p))) →
// π ((succ x × (m + p)) = ((succ x × m) + (succ x × p)))
simpl assume n' IHn' rewrite IHn'
rewrite plus_comm p (n'×p)
rewrite plus_assoc_trash m (n'×m) ((n'×p)+p)
rewrite plus_comm m (n'×m + (n'×p + p))
rewrite plus_assoc rewrite plus_assoc
rewrite plus_comm m p
rewrite plus_assoc_trash (p+m) (n'×m) (n'×p)
rewrite plus_comm (p + m) (n'×m + n'×p)
rewrite plus_assoc reflexivity
qed
// Prouver en utilisant les lemmes précédents
// (mais bien sûr pas [mult_plus_distr_l])
//Lemma mult_plus_distr_l_bis : forall n m p,
// n*(m+p)=n*m+n*p.
//Proof.
//intros n m p.
//rewrite mult_comm with (n := n) (m := m).
//rewrite mult_comm with (n := n) (m := p).
//rewrite <- mult_plus_distr_r.
//apply mult_comm.
//Qed.
theorem mult_plus_distr_l_bis :
Πn m p, π ((mult n (plus m p)) = (plus (mult n m) (mult n p)))
proof
assume n m p
rewrite mult_comm n m
rewrite mult_comm n p
rewrite mult_comm n (plus m p)
symmetry
rewrite mult_plus_distr_r
reflexivity
qed
// theorem mul_addr x y z : π (z×(x+y) = z×x+z×y)
// proof
// assume x y z
// rewrite mul_com
// rewrite mul_addl
// rewrite mul_com
// rewrite [y×_]mul_com
// reflexivity
// qed
//rule $z × ($x + $y) ↪ $z × $x + $z × $y
// Multiplication is associative
//Lemma mult_assoc : forall n m p, n*(m*p) = (n*m)*p.
//Proof.
//induction n ; intros m p; simpl.
//+ reflexivity.
//+ rewrite IHn. rewrite mult_plus_distr_r. reflexivity.
//Qed.
theorem mult_assoc : Π n m p, π ((n×(m×p)) = ((n×m)×p))
proof
assume n m p
refine nat_ind (λz, ((z×(m×p)) = ((z×m)×p))) _ _ n
reflexivity
simpl assume n' Hn' // simpl
rewrite Hn'
rewrite mult_plus_distr_r // m (mult n' m) p
reflexivity
qed
//rule ($x × $y) × $z ↪ $x × ($y × $z)
// Doubling function.
definition double n ≔ n×2