-
Notifications
You must be signed in to change notification settings - Fork 1
/
aula04_inducao.v
189 lines (156 loc) · 4.48 KB
/
aula04_inducao.v
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
(** * Indução em Coq *)
Require Export aula03_provas.
(* ############################################### *)
(** * Prova por indução *)
(** Nem sempre é possível provar somente por:
- simplificação
- reescrita
- análise de casos *)
(** Na aula passada, vimos o seguinte teorema *)
Print plus_O_n.
(** E se quisermos provar n + 0 = n? *)
Theorem plus_n_O_firsttry : forall n:nat,
n = n + 0.
Proof.
intros n.
simpl. (* não simplifica nada *)
try reflexivity.
(** [reflexivity] não funciona, pois [n]
em [n + 0] é um número arbitrário e
não caso padrão com o [+] *)
Print NatPlayground2.plus.
Abort.
(** Análise de casos também não ajuda. *)
Theorem plus_n_O_secondtry : forall n:nat,
n = n + 0.
Proof.
intros n. destruct n as [| n'].
- (* n = 0 *)
reflexivity. (* quando [n] é 0, funciona *)
- (* n = S n' *)
simpl. (* aqui [n] é [S n'],
outro número arbitrário *)
Abort.
(** Chamadas sucessivas a [destruct n']
também não ajudaria. Precisamos de indução. *)
Theorem plus_n_O : forall n:nat, n = n + 0.
Proof.
intros n. induction n as [| n' IHn'].
- (* n = 0 *) reflexivity.
- (* n = S n' *) simpl. rewrite <- IHn'.
reflexivity.
Qed.
(** Outro exemplo. *)
Theorem minus_diag : forall n,
minus n n = 0.
Proof.
intros n. induction n as [| n' IHn'].
- (* n = 0 *)
simpl. reflexivity.
- (* n = S n' *)
simpl. rewrite -> IHn'. reflexivity.
Qed.
(** Nota: [induction] move automaticamente
variáveis quantificadas para o contexto. *)
(** **** Exercise: (basic_induction) *)
(** Prove os seguintes teoremas. Será necessário
buscar por resultados previamente provados. *)
Theorem mult_0_r : forall n:nat,
n * 0 = 0.
Proof.
induction n as [|n' IH].
- reflexivity.
- Print Nat.mul. simpl. rewrite -> IH. reflexivity.
Qed.
Theorem plus_n_Sm : forall n m : nat,
S (n + m) = n + (S m).
Proof.
intros n m. induction n as [|n' IH].
- simpl. reflexivity.
- simpl. rewrite <- IH. reflexivity.
Qed.
Theorem plus_comm : forall n m : nat,
n + m = m + n.
Proof.
intros n m. induction n as [| n' IH].
- simpl. rewrite <- plus_n_O. reflexivity.
- simpl. rewrite -> IH. rewrite plus_n_Sm. reflexivity.
Qed.
Theorem plus_assoc : forall n m p : nat,
n + (m + p) = (n + m) + p.
Proof.
intros. induction n as [|n' IH].
- simpl. reflexivity.
- simpl. rewrite <- IH. reflexivity.
Qed.
(* ############################################### *)
(** * Provas aninhadas *)
(** É possivel/aconselhável quebrar provas maiores
em subprovas. Isto pode ser feito a partir de
[Lemma], como também a partir de "sub-teoremas". *)
Theorem mult_0_plus' : forall n m : nat,
(0 + n) * m = n * m.
Proof.
intros n m.
assert (H: 0 + n = n).
{
reflexivity.
}
rewrite -> H.
reflexivity.
Qed.
(** Outro exemplo: veja que a tática [rewrite]
não é muito "inteligente" sobre onde aplicar
a reescrita no objetivo. *)
Theorem plus_rearrange_firsttry :
forall n m p q : nat,
(n + m) + (p + q) = (m + n) + (p + q).
Proof.
intros n m p q.
(* Só queremos trocar (n + m) por (m + n). *)
rewrite -> plus_comm.
(* Mas reescrita não faz o que queremos. *)
Abort.
(** Veja a próxima prova. *)
Theorem plus_rearrange : forall n m p q : nat,
(n + m) + (p + q) = (m + n) + (p + q).
Proof.
intros n m p q.
assert (H: n + m = m + n).
{ rewrite -> plus_comm. reflexivity. }
rewrite -> H. reflexivity.
Qed.
(* ############################################### *)
(** * Mais exercícios *)
(** **** Exercise: (mult_comm) *)
(** Use [assert] para ajudar na prova. Não é
necessário usar indução. *)
Theorem plus_swap : forall n m p : nat,
n + (m + p) = m + (n + p).
Proof.
intros. rewrite plus_assoc.
assert (H: n + m = m + n).
{
rewrite plus_comm. reflexivity.
}
rewrite -> H. rewrite plus_assoc.
reflexivity.
Qed.
(** Agora, prove comutatividade da multiplicação.
Talvez seja necessário provar um teorema auxiliar.
O teorema [plus_swap] será útil. *)
Theorem mult_comm : forall m n : nat,
m * n = n * m.
Proof.
intros. induction m as [|m' IH].
- simpl. Search (_ * 0). rewrite <- mult_n_O.
reflexivity.
- simpl. Print Nat.mul. Search (_ * _). rewrite <- mult_n_Sm.
rewrite plus_comm. rewrite -> IH. reflexivity.
Qed.
(* ############################################### *)
(** * Leitura sugerida *)
(** Software Foundations: volume 1
- Induction
https://softwarefoundations.cis.upenn.edu/lf-current/Induction.html
*)