-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathaula02_gallina.v
599 lines (468 loc) · 15.2 KB
/
aula02_gallina.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
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
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
(** * Programação funcional em Coq *)
(* ############################################### *)
(** * Instalação *)
(** Passo-a-passo:
1. Instalar OPAM: gerenciador de pacotes OCaml
[passo já realizado pelo helpdesk no G3]
Link: http://opam.ocaml.org/doc/Install.html
a) wget https://raw.github.com/ocaml/opam/master/shell/opam_installer.sh -O - | sh -s /usr/local/bin
2. Instalar Coq 8.8.1
Link: https://coq.inria.fr/opam/www/using.html
a) abrir o terminal (ctrl + alt + t)
b) export OPAMROOT=~/opam-coq.8.8.1
# diretório de instalação no home do usuário
c) opam init -n --comp=4.02.3 -j 4
# 4 é o número de núcleos de processamento
d) opam repo add coq-released http://coq.inria.fr/opam/released
e) opam install coq.8.8.1 && opam pin add coq 8.8.1
3. Instalar CoqIDE
Link: https://coq.inria.fr/opam/www/using.html
a) opam install coqide
4. Para rodar a IDE, é preciso reexecutar os
seguintes comandos sempre que abrir um novo
terminal:
a) abrir o terminal (ctrl + alt + t)
b) export OPAMROOT=~/opam-coq.8.8.1
# diretório em que instalou Coq
c) eval `opam config env`
# configurar ambiente
d) coqide &
5. Para testar a instalação, abrir o arquivo
01-exemplo.v e processá-lo até o final
(ctrl + end). O texto deve ficar todo verde.
Outra opção de IDE: Emacs + ProofGeneral
Link: https://proofgeneral.github.io/
Links úteis:
- https://github.com/coq/coq
- https://github.com/coq/coq/wiki
- https://github.com/coq/coq/wiki/The-Coq-FAQ
*)
(* ############################################### *)
(** * Prefácio *)
(** Material baseado na série Software Foundations
https://softwarefoundations.cis.upenn.edu/. *)
(** Aspectos centrais deste material:
- uso de lógica para definir e provar
afirmações precisas sobre programas
- uso de um assistente de prova (Coq)
para construir argumentos lógicos rigorosos
- programação funcional como ligação
entre programação e lógica *)
(** Coq: aspectos históricos
- Em desenvolvimento deste 1984
- Possíveis origens do nome:
- Tradição francesa: Caml, Elan, PhoX, etc.
- Calculus of Constructions
- Símbolo nacional da França
- Primeiras três letras de Thierry Coquand *)
(** Coq: aplicações em CS e matemática:
- Plataforma para modelar PLs
[instruções x86, C, etc.]
- Ambiente para desenvolver HW/SW certificado
[CompCert, CertiKos, RISC-V, etc.]
- Ambiente para programação funcional
[Gallina]
- Assistente de prova para lógica de alta ordem
[Primeira prova verificada formalmente
do Teorema das 4 cores] *)
(* ############################################### *)
(** * Gallina: introdução *)
(** Definindo novo tipo: conjunto de valores possíveis.
- [day] é o nome do tipo
- a definição [day] é um elemento de [Type]
- [:=] usado para preceder a definição
- [|] é usado para separar elementos de [day]
*)
Inductive day : Type :=
| monday : day
| tuesday : day
| wednesday : day
| thursday : day
| friday : day
| saturday : day
| sunday : day.
(** Definindo uma função que opera sobre dias.
- [Definition] funções não-recursivas
- Tipos dnão precisam ser explícitos
- [:=] precede a definição da função
- A definição pode ser feita por casamento
de padrão, como também chamada a outras funções
- [=>] representa o retorno quando [d]
casa com uma das opções
*)
Definition next_weekday (d:day) : day :=
match d with
| monday => tuesday
| tuesday => wednesday
| wednesday => thursday
| thursday => friday
| friday => monday
| saturday => monday
| sunday => monday
end.
(** Validando a função definida:
- [Compute]: avalia expressão
- [Example]: define afirmação a ser verificada
a) dá um nome à afirmação
b) permite usar o modo de prova de Coq
para verificar que a afirmação
é verdadeira (como um teste unitário)
- Extrair programa funcional em OCaml ou Haskell
*)
Compute (next_weekday friday).
(* ==> monday : day *)
Compute (next_weekday (next_weekday saturday)).
(* ==> tuesday : day *)
Example test_next_weekday:
(next_weekday (next_weekday saturday)) = tuesday.
Proof. simpl. reflexivity. Qed.
(** **** Exercise: (sinal) *)
(** Defina o tipo [sinal] que pode ser verde,
amarelo ou vermelho. *)
(** **** Exercise: (next_sinal) *)
(** Defina a função [next_sinal] que muda a cor
de um sinal para a próxima cor esperada *)
(** **** Exercise: (compute_sinal) *)
(** Use [Compute] para testar a definição
de [next_sinal]. *)
(** **** Exercise: (test_sinal) *)
(** Use [Example] para testar a definição
de [next_sinal]. Prove que sua
afirmação é verdadeira usando *)
(* =============================================== *)
(** ** Booleans *)
(** De forma similar, podemos definir o tipo booleano.
- Não confundir: booleano vs. True e False da lógica *)
Inductive bool : Type :=
| true : bool
| false : bool.
(** Definindo funções sobre booleanos
- Observe a sintaxe para vários parâmetros *)
Definition negb (b:bool) : bool :=
match b with
| true => false
| false => true
end.
Definition andb (b1:bool) (b2:bool) : bool :=
match b1 with
| true => b2
| false => false
end.
Definition orb (b1:bool) (b2:bool) : bool :=
match b1 with
| true => true
| false => b2
end.
(** Teste unitários *)
Example test_orb1: (orb true false) = true.
Proof. simpl. reflexivity. Qed.
Example test_orb2: (orb false false) = false.
Proof. simpl. reflexivity. Qed.
Example test_orb3: (orb false true) = true.
Proof. simpl. reflexivity. Qed.
Example test_orb4: (orb true true) = true.
Proof. simpl. reflexivity. Qed.
(** É possível definir uma sintaxe mais familiar
usando [Notation] *)
Notation "x && y" := (andb x y).
Notation "x || y" := (orb x y).
Example test_orb5: false || false || true = true.
Proof. simpl. reflexivity. Qed.
(** **** Exercise: (nandb) *)
(** Defina nandb (usando casamento de padrão e,
em seguida, complete os testes unitários. *)
Definition nandb (b1:bool) (b2:bool) : bool
(* SUBSTITUA COM ":= _sua_definição_ ." *). Admitted.
Example test_nandb1:
(nandb true false) = true.
(* COMPLETE AQUI *) Admitted.
Example test_nandb2:
(nandb false false) = true.
(* COMPLETE AQUI *) Admitted.
Example test_nandb3:
(nandb false true) = true.
(* COMPLETE AQUI *) Admitted.
Example test_nandb4:
(nandb true true) = false.
(* COMPLETE AQUI *) Admitted.
(** **** Exercise: (nandb') *)
(** Defina nandb' usando as definições [andb] e [negb] *)
Definition nandb' (b1:bool) (b2:bool) : bool
(* SUBSTITUA COM ":= _sua_definição_ ." *). Admitted.
(** Nas próximas provas, observe o resultado do
simpl. Tente antes desta tática, usar
unfold nandb' (que obriga a expansão da definição
de nandb'). *)
Example test_nandb'1:
(nandb' true false) = true.
(* COMPLETE AQUI *) Admitted.
Example test_nandb'2:
(nandb' false false) = true.
(* COMPLETE AQUI *) Admitted.
Example test_nandb'3:
(nandb' false true) = true.
(* COMPLETE AQUI *) Admitted.
Example test_nandb'4:
(nandb' true true) = false.
(* COMPLETE AQUI *) Admitted.
(** **** Exercise: (andb3) *)
(** Defina a função [andb3]. Esta função deve
retornar [true] quando todas suas entradas
são [true], e [false] caso contrário *)
Definition andb3 (b1:bool) (b2:bool) (b3:bool) : bool
(* SUBSTITUA COM ":= _sua_definição_ ." *). Admitted.
Example test_andb31:
(andb3 true true true) = true.
(* COMPLETE AQUI *) Admitted.
Example test_andb32:
(andb3 false true true) = false.
(* COMPLETE AQUI *) Admitted.
Example test_andb33:
(andb3 true false true) = false.
(* COMPLETE AQUI *) Admitted.
Example test_andb34:
(andb3 true true false) = false.
(* COMPLETE AQUI *) Admitted.
(* =============================================== *)
(** ** Function Types *)
(** Toda expressão em Coq tem um tipo. O comando
[Check] imprime o tipo de uma expressão. *)
Check true.
(* ===> true : bool *)
Check (negb true).
(* ===> negb true : bool *)
(** A função [negb] é também o valor de um dado, assim
como [true] e [false]. Seu tipo é chamado
_function types_, e escrito usando setas *)
Check negb.
(* ===> negb : bool -> bool *)
(** [negb] é uma função que dado um [bool],
produz um [bool]. *)
Check andb.
(* ===> andb : bool -> bool -> bool *)
(** [andb] é uma função que a partir de dois [bool],
produz um [bool]. *)
(* =============================================== *)
(** ** Tipos compostos *)
(** Tipos definidos até então: enumerações. Cada opção
criada a partir de um certo _construtor_. *)
Inductive rgb : Type :=
| red : rgb
| green : rgb
| blue : rgb.
(** A definição a seguir possui o construtor [primary]
que recebe um [rgb] e produz um [color]. *)
Inductive color : Type :=
| black : color
| white : color
| primary : rgb -> color.
(** Definindo funções sobre tipos compostos *)
Definition monochrome (c : color) : bool :=
match c with
| black => true
| white => true
| primary p => false
end.
Definition isred (c : color) : bool :=
match c with
| black => false
| white => false
| primary red => true
| primary _ => false
end.
(** No exemplo acima, [primary _] tem o mesmo
efeito de [primary p]. *)
(* =============================================== *)
(** ** Módulos *)
(** Uma das maneiras de estruturar uma especificação
em Coq é usar módulos. *)
Module NatPlayground.
(* =============================================== *)
(** ** Números *)
(** Definindo um tipo usando construtores que recebem
argumentos do tipo sendo definido. *)
(** Números naturais
- O: uma representação do número zero
- S _: o sucessor de um número natural *)
Inductive nat : Type :=
| O : nat
| S : nat -> nat.
(** Por isso que tipos são (potencialmente) indutivos:
- [O] é um número natural
- [S O] é um número natural
- [S (S O)] é um número natural
- [S (S false)] não é um número natural *)
(** Esta definição é uma representação estrutural
sem significado. O significado vem do seu uso *)
Inductive nat' : Type :=
| stop : nat'
| tick : nat' -> nat'.
(** Exemplo: função [pred] *)
Definition pred (n : nat) : nat :=
match n with
| O => O
| S n' => n'
end.
End NatPlayground.
(** Coq possui definições para representar
números de forma decimal *)
Check (S (S (S (S O)))).
(* ===> 4 : nat *)
(** Definindo a função [minustwo]. Observe
os dois primeiros casos *)
Definition minustwo (n : nat) : nat :=
match n with
| O => O
| S O => O
| S (S n') => n'
end.
Compute (minustwo 4).
(* ===> 2 : nat *)
(** Tipos dos construtores e das funções
para [nat] *)
Check S.
Check pred.
Check minustwo.
(** Apesar de todos serem valores, as duas
últimas definições possuem uma noção
de computabilidade associada *)
(** Definindo funções recursivas: [Fixpoint]. *)
Fixpoint evenb (n:nat) : bool :=
match n with
| O => true
| S O => false
| S (S n') => evenb n'
end.
(** Definindo [oddb] em função de [evenb] e [negb]. *)
Definition oddb (n:nat) : bool := negb (evenb n).
Example test_oddb1: oddb 1 = true.
Proof. simpl. reflexivity. Qed.
Example test_oddb2: oddb 4 = false.
Proof. simpl. reflexivity. Qed.
(** Definindo funções recursivas com
vários parâmetros *)
Module NatPlayground2.
Fixpoint plus (n : nat) (m : nat) : nat :=
match n with
| O => m
| S n' => S (plus n' m)
end.
(** Testando a definição *)
Compute (plus 3 2).
(* ===> 5 : nat *)
(** O passo-a-passo da computação seria: *)
(* [plus (S (S (S O))) (S (S O))]
==> [S (plus (S (S O)) (S (S O)))]
pela segunda clásula do [match]
==> [S (S (plus (S O) (S (S O))))]
pela segunda clásula do [match]
==> [S (S (S (plus O (S (S O)))))]
pela segunda clásula do [match]
==> [S (S (S (S (S O))))]
pela primeira clásula do [match]
*)
(** Outra notação para vários parâmetros
do mesmo tipo *)
Fixpoint mult (n m : nat) : nat :=
match n with
| O => O
| S n' => plus m (mult n' m)
end.
Example test_mult1: (mult 3 3) = 9.
Proof. simpl. reflexivity. Qed.
(** Casamento de padrão múltiplo *)
Fixpoint minus (n m:nat) : nat :=
match n, m with
| O , _ => O
| S _ , O => n
| S n', S m' => minus n' m'
end.
End NatPlayground2.
(** Definindo exponenciação: [exp] *)
Fixpoint exp (base power : nat) : nat :=
match power with
| O => S O
| S p => mult base (exp base p)
end.
(** **** Exercise: 1(factorial) *)
(** Defina a função fatorial em Coq
factorial(0) = 1
factorial(n) = n * factorial(n-1)
(if n>0) *)
Fixpoint factorial (n:nat) : nat
(* SUBSTITUA COM ":= _sua_definição_ ." *). Admitted.
Example test_factorial1:
(factorial 3) = 6.
(* COMPLETE AQUI *) Admitted.
Example test_factorial2:
(factorial 5) = (mult 10 12).
(* COMPLETE AQUI *) Admitted.
(** As próximas definições definem uma sintaxe
para adição, subtração e multiplicação
- precedência: [at level n], onde n 0..100
menor valor indica maior precedência
- associatividade: [left], [right] ou
[no] [associativity]
*)
Notation "x + y" := (plus x y)
(at level 50, left associativity)
: nat_scope.
Notation "x - y" := (minus x y)
(at level 50, left associativity)
: nat_scope.
Notation "x * y" := (mult x y)
(at level 40, left associativity)
: nat_scope.
Check ((0 + 1) + 1).
(** Definindo se dois números são iguais: [beq_nat] *)
Fixpoint beq_nat (n m : nat) : bool :=
match n with
| O => match m with
| O => true
| S m' => false
end
| S n' => match m with
| O => false
| S m' => beq_nat n' m'
end
end.
(** Definindo menor ou igual: [leb] *)
Fixpoint leb (n m : nat) : bool :=
match n with
| O => true
| S n' =>
match m with
| O => false
| S m' => leb n' m'
end
end.
Example test_leb1: (leb 2 2) = true.
Proof. simpl. reflexivity. Qed.
Example test_leb2: (leb 2 4) = true.
Proof. simpl. reflexivity. Qed.
Example test_leb3: (leb 4 2) = false.
Proof. simpl. reflexivity. Qed.
(** **** Exercise: (blt_nat) *)
(** A função [blt_nat] testa se um número é
menor do que outro. Observe que a próxima
definição não é recursiva. É preciso definir
[blt_nat] a partir de definições passadas *)
Definition blt_nat (n m : nat) : bool
(* SUBSTITUA COM ":= _sua_definição_ ." *). Admitted.
Example test_blt_nat1:
(blt_nat 2 2) = false.
(* COMPLETE AQUI *) Admitted.
Example test_blt_nat2:
(blt_nat 2 4) = true.
(* COMPLETE AQUI *) Admitted.
Example test_blt_nat3:
(blt_nat 4 2) = false.
(* COMPLETE AQUI *) Admitted.
(* ############################################### *)
(** * Leitura sugerida *)
(** Software Foundations: volume 1
- Prefácio
https://softwarefoundations.cis.upenn.edu/lf-current/Preface.html
- Aspectos básicos (até o final de "Data and Functions")
https://softwarefoundations.cis.upenn.edu/lf-current/Basics.html
*)