Coq¶
Contents
2 Coqdoc (documentation)¶
to generate documents of all Coq files in and under the current directory, run
$ find . -name "*.v" > allfiles
$ coqdoc --html --directory index -Q . Coq --files-from allfiles --table-of-contents
$ rm allfiles
find . -name *.v > allfiles
puts names of all.v
files in this directory and its subdirectories (recursively) on the fileallfiles
--html
indicates that outputs are html files.index.html
will be generated along the way.--directory index~
indicates that the output files are put in./index
directory--Q . Coq
means that files in./A/B
directories, i.e., files./A/B/C.v
, are named asCoq.A.B.C
(What is difference between-Q
and-R
?)--files-from allfiles
indicates thatcoqdoc
works on every files listed onallfiles
--table-of-contents
makes the table of contents,toc.html
, according to the order of files inallfiles
4 Terms¶
*qualified identifier* Example. “A.B.C” means an identifier C is qualified by B that is qualified by A.
5 Gallina¶
match
twith
c1\(\Rightarrow\) e1|
c2\(\Rightarrow\) e2|...|
c1\(\Rightarrow\) elend
if
tthen
e1else
e2is equivalent tomatch
twith true
\(\Rightarrow\) e1| false
\(\Rightarrow\) e2end
fun n:nat => (n*n*n)%nat
is a function of typenat -> nat
and has the same meaning asλ n:nat. n*n*n
in typed λ-calculusfun (n:nat) -> n*n*n
in ocaml
the followings are all equivalent
fun n:nat => fun p:nat => fun z:Z => (Z_of_nat(n+p)+z)%Z
fun n p:nat => fun z:Z => (Z_of_nat(n+p)+z)%Z
fun (n p:nat) (z:Z) => (Z_of_nat(n+p)+z)%Z
let v:= t1 in t2
wherev
is an identifier andt1
andt2
are expression is the local binding(λv.t2)
that will evaluated as((λv.t2) t1)
thent2[v/t1]
after the β-reduction.
6 Vernacular Command¶
Require Import
``Coq.Unicode.Utf8.``Require Import
``Arith.``Require Import
``ZArith.``Require Import
``Bool.``Print Libraries
Open Scope
``Z_scope.``Close Scope
``Z_scope.``Open Scope
``nat_scope.``Set
``Printing Notations.``Unset
``Printing Notations.``Reset Initial
Reset
``id``The followings all have the same meaning
Definition cube := fun z:Z => z*z*z
Definition cube (z:Z):Z := z*z*z
Definition cube z := z*z*z
Eval compute in (h 56 78)
whenh:nat->nat->nat
evaluateh(56,78)
.Eval compute
is synomym forEval cbv iota beta zeta delta
.Locate "_ * _"
Hypothesis
``h:P``Variables
``h:P``Axiom
``h:P``Parameter
``x:P``Theorem
Lemma
Proof
Qed
build the proof term corresponding to the sequence of tactics, check the term’s type is the initial statement, save this new theorem as a definition liking to the theorem name, its statement (i.e., type), and the proof term.Print
``something``Reset
``something``Section
``proof_of_something``End
``proof_of_something``SearchPattern
``(_ + _ <= _)%Z.``Show 7
show 7th subgoal.Restart
restart the proof.Abort
abort the proof.Identity Coercion id : C >-> D
Fixpoint f (a:T) := expr
defines a function on a variablea
recursively.Fixpoint mult2 (n:nat):nat := match n with | 0 => 0 | S p => S (S (mult2 p)) end.
Fixpoint f (a1:T1) ... (ap:Tp) {struct ai}: T := expr
defines a function with variablesa1
,…,ap
that is recursively defined on the variableai
Fixpoint plus (n m:nat) {struct n}:nat := match n with | 0 => m | S p => S (plus p m) end.
Fixpoint iterate (A:Set)(f:A -> A)(n:nat)(x:A){struct n}:A := match n with | 0 => x | S p => f (iterate A f p x) end.
7 Tactic¶
tac1; tac2; ...; tacn
combination of tacticstac; [tac1|tac2|...|tacn]
exactlyn
goals are generated so apply tactictaci
to the ~i~th subgoaltac || tac'
applytac
and if it fails, applytac'
idtac
leaves the goal as it is and always succeedsfail
alwas fail.tac; fail
fails only whentac
generates new goalstry tac
behaves liketac || idtac
intros
add hypothesesapply H
apply hypothesisH
to the current goalassumption
the statement to prove is exactly the statement of the hypothesisexact
similar toassumption
but globalauto
cut
suppose we have hypotheses(H:P->Q) (H0:Q->R) (H1:(P->R)->T->Q) (H2:(P->R)->T)
To proveQ
, we can see thatP->R
is easy to prove byH
andH0
, and fromP->R
it is easy to finish the proof byH1
andH2
. So once the goalQ
is generated, we first make an assumption thatP->R
that is to be proved later bycut P->R
that generates(P->Q)->R
so that we canintro
the term forP->Q
assert
opposite ofcut
. In the example forcut
, we can firstassert P->R
and prove it, then use it to proveQ
later.unfold lt
reflexivity
when a goal isa=a
. this is synonym toapply refl_equal
left
when a goal isa \/ (b)
, prove it by provinga
right
when a goal isa \/ (b)
, prove it by privingb
elim t
whent:T
whereT
is inductive type, thenelim t
as the same aspattern t; apply T_ind
orT_rec
, or etc depending the goal sort. Ift= b|c
and if the goal ist -> d
this eliminatea
to produce subgoalsb->d
andc->d
elim t using T_ind2
same aselim t
butt
does need to be an inductive type as long asT_ind
is of the form of an induction principle which has the form∀P:T→S, P t1→P t2→...→(∀t:T, P t)
.pattern m
when we want to provem:month ⊢ m=Jan ∨ ... ∨ m=Dec
, we can usepattern m
to convert the goal into(λm0:month, m0=Jan ∨ ... ∨ m0=Dec) m
to usemonth_ind
that is of the form∀P:month→Prop, P Jan → ... → P Dec → ∀m:month, P m
.induction
``v`` is similar tointros until
``v``; elim
``v`` follwed by a collection ofintros
in each branchcase t
wheret:T
andT
is an inductive type. This replaces all instances oft
in the goal statement with all possible cases, as defined by the inductive type.discriminate H
whereH:t1 = t2 ⊢ e
whilet1 ≠ t2
.discriminate
when the goal ist1 ≠ t2
whilet1 ≠ t2
. First,t1 ≠ t2
is equivalent tot1 = t2 → False
. Then the goal is to proveH:t1 = t2 ⊢ False
. Sincet1 ≠ t2
, we can define a functionF:=(λ t:T. if t=t1 True and if t=t2 False)
so that the goal becomesH:t1=t2 ⊢ (F t2)
. Rewriting by the assumptionH
we obtainH:t1=t2 ⊢ (F t1)
that isH:t1=t2 ⊢ True
. Thentrivial
finishes the proof. This is the situation whereFalse ⊢ True
andFalse ⊢ False
.rewrite H
if there is a hypothesisH:x=y
thene ↦ e[x/y]
rewrite ← H
if there is a hypothesisH:x=y
thene ↦ e[y/x]
8 Module¶
Load
my_module.v
can be loaded in the current context with commandLoad my_module
.
compiling the module
my_module.v
bycoqc
creates a filemy_module.vo
that can be reloaded withRequire Import my_module
when a new module
N
requires an old moduleM
we useRequire Export M
in moduleN
so thatM
is automatically visible whenN
is required.
9 Inductive definitions¶
Inductive month : Set :=
January : month | February : month | March : month
| April : month | May : month | June : month
| July : month | August : month | September : month
| October : month | November : month | December : month.
Theorem month_equal :
forall m:month,
m=January \/ m=February \/ m=March \/ m=April \/
m=May \/ m=June \/ m=July \/ m=August \/
m=September \/ m=October \/ m=November \/ m=December.
Proof.
induction m; auto 12.
Qed.
Check (fun b:bool => match b with true => 33 | false => 45 end).
Definition month_length (leap:bool) (m:month) : nat :=
match m with
| January => 31 | February => if leap then 29 else 28
| March => 31 | April => 30 | May => 31 | June => 30
| July => 31 | August => 31 | September => 30
| October => 31 | November => 30 | December => 31
end.
Fail Definition month_length : bool->month->nat :=
fun (leap:bool) (m:month) => match m with January => 31 end.
Definition month_length' (leap:bool) :=
month_rec (fun m:month => nat)
31 (if leap then 29 else 28) 31 30 31 30 31 31 30 31 30 31.
Definition month_length'' (leap:bool) (m:month) :=
match m with
| February => if leap then 29 else 28
| April => 30 | June => 30 | September => 30 | November => 30
| other => 31
end.
Eval compute in (fun leap => month_length leap November).
Theorem length_february : month_length false February = 28.
Proof.
simpl.
trivial.
Qed.
Inductive plane : Set := point : Z->Z->plane.
Definition abscissa (p:plane) : Z :=
match p with point x y => x end.
Reset plane.
Record plane : Set := point {abscissa : Z; ordinate : Z}.
Inductive vehicle : Set :=
| bicycle : nat->vehicle
| motorized : nat->nat->vehicle.
Definition nb_wheels (v:vehicle) : nat :=
match v with
| bicycle x => 2
| motorized x n => n
end.
Definition nb_seats (v:vehicle) : nat :=
match v with
| bicycle x => x
| motorized x _ => x
end.
Theorem at_least_28 :
forall (leap:bool) (m:month), 28 <= month_length leap m.
Proof.
intros leap m; case m; simpl; auto with arith.
case leap; auto with arith.
Qed.
Definition next_month (m:month) :=
match m with
January => February | February => March | March => April
| April => May | May => June | June => July
| July => August | August => September
| September => October | October => November
| November => December | December => January
end.
Theorem next_august_then_july:
forall m:month, next_month m = August -> m=July.
Proof.
intro m; case m; simpl; intro Hnext_eq.
Show 7.
trivial.
Show 1.
discriminate Hnext_eq.
Abort.
Theorem bicycle_eq_seats :
forall x1 y1:nat, bicycle x1 = bicycle y1 -> x1 = y1.
Proof.
intros x1 y1 H.
injection H.
trivial.
Qed.
Theorem next_march_shorter :
forall (leap:bool) (m1 m2:month), next_month m1 = March ->
month_length leap m1 <= month_length leap m2.
Proof.
intros leap m1 m2 H.
case m1.
Show 4.
simpl.
Abort.
Theorem next_march_shorter :
forall (leap:bool) (m1 m2:month), next_month m1 = March ->
month_length leap m1 <= month_length leap m2.
Proof.
intros leap m1 m2.
case m1.
Show 4.
Abort.
Theorem next_march_shorter :
forall (leap:bool) (m1 m2:month), next_month m1 = March ->
month_length leap m1 <= month_length leap m2.
Proof.
intros leap m1 m2 H.
generalize H.
Abort.
Theorem test : forall (x y:nat), 0 <= x + y + y.
Proof.
intros.
generalize (x+y+y).
Abort.
Theorem next_march_shorter :
forall (leap:bool) (m1 m2:month), next_month m1 = March ->
month_length leap m1 <= month_length leap m2.
Proof.
intros leap m1 m2 H.
generalize (refl_equal m1).
Abort.
Theorem plus_assoc :
forall x y z:nat, (x+y)+z = x+(y+z).
Proof.
intros x y z.
elim x.
rewrite plus_O_n.
rewrite plus_O_n.
reflexivity.
intros x' Hrec.
Check plus_Sn_m.
rewrite (plus_Sn_m x' y).
rewrite (plus_Sn_m (x'+y) z).
rewrite (plus_Sn_m x' (y+z)).
rewrite Hrec.
reflexivity.
Qed.
Fixpoint mult2 (n:nat) : nat :=
match n with 0 => 0 | S p => S (S (mult2 p)) end.
Fixpoint plus (n m:nat) {struct n} : nat :=
match n with 0 => m | S p => S (plus p m) end.
Fixpoint iterate (A:Set) (f:A->A) (n:nat) (x:A) {struct n} : A :=
match n with 0 => x | S p => f (iterate A f p x) end.
Inductive Z_btree : Set :=
| Z_leaf : Z_btree
| Z_bnode : Z -> Z_btree -> Z_btree -> Z_btree.
Fixpoint sum_all_values (t:Z_btree) : Z :=
(match t with
| Z_leaf => 0
| Z_bnode v t1 t2 => v + sum_all_values t1 + sum_all_values t2
end)%Z.
Fixpoint zero_present (t:Z_btree) : bool :=
match t with
| Z_leaf => false
| Z_bnode (0%Z) t1 t2 => true
| Z_bnode _ t1 t2 => if (zero_present t1) then true else zero_present t2
end.
Fixpoint Psucc (x:positive) : positive :=
match x with
| xI x' => xO (Psucc x')
| xO x' => xI x'
| xH => 2%positive
end.
Inductive Z_fbtree : Set :=
| Z_fleaf : Z_fbtree
| Z_fnode : Z -> (bool -> Z_fbtree) -> Z_fbtree.
Definition right_son (t:Z_btree) : Z_btree :=
match t with
| Z_leaf => Z_leaf
| Z_bnode a t1 t2 => t2
end.
Definition fright_son (t:Z_fbtree) : Z_fbtree :=
match t with
| Z_fleaf => Z_fleaf
| Z_fnode a f => f false
end.
Fixpoint fsum_all_values (t:Z_fbtree) : Z :=
(match t with
| Z_fleaf => 0
| Z_fnode v f => v + fsum_all_values (f true) + fsum_all_values (f false)
end )%Z.
Inductive Z_inf_branch_tree : Set :=
Z_inf_leaf : Z_inf_branch_tree
| Z_inf_node : Z -> (nat -> Z_inf_branch_tree) -> Z_inf_branch_tree.
Fail Fixpoint n_sum_all_values (n:nat) (t:Z_inf_branch_tree) {struct t} : Z :=
(match t with
Z_inf_leaf => 0
| Z_inf_node v f => v + sum_f n (fun x:nat => n_sum_all_values n (f x))
end )%Z.
Theorem plus_assoc' : forall (x y z:nat), x+y+z=x+(y+z).
Proof.
intros x y z.
elim x.
simpl.
reflexivity.
intros n H.
(** %(** ``\verb|rewrite H|'' would not work yet so we need *) *)
simpl.
rewrite H.
reflexivity.
Qed.
Definition mult2' : nat -> nat :=
fix f (n:nat) : nat :=
match n with
0 => 0
| S p => S (S (f p))
end.
Require Import List.
Print list.
Check cons.
Fixpoint app (A:Set) (l m:list A) {struct l} : list A :=
match l with
| nil => m (** %(** not ``\verb|nil A => m|'' *) *)
| cons a l1 => cons a (app A l1 m) (** %(** not ``\verb|cons A a l1|'' nor ``\verb|(app l1 m)|'' *) *)
end.
Print option.
Definition pred_option (n:nat) : option nat :=
match n with
0 => None (** %(** ``\verb|pred_option|'' is not defined for 0 *) *)
| S p => Some p
end.
Definition pred2_option (n:nat) : option nat :=
match pred_option n with
None => None
| Some p => pred_option p
end.
Fixpoint nth_option (A:Set) (n:nat) (l:list A) {struct l} : option A :=
match n, l with
0, cons a t1 => Some a
| S p, cons a t1 => nth_option A p t1
| n, nil => None
end.
Print prod.
Print fst.
Print sum.
Check (sum nat bool).
Check (inl bool 4).
Inductive ltree (n:nat) : Set :=
lleaf : ltree n
| lnode : forall p:nat, p <= n -> ltree n -> ltree n -> ltree n.
Inductive sqrt_data (n:nat) : Set :=
sqrt_intro : forall x:nat, x*x <= n -> n < (S x)*(S x) -> sqrt_data n.
Inductive htree (A:Set) : nat -> Set :=
hleaf : A -> htree A 0
| hnode : forall n:nat, A -> htree A n -> htree A n -> htree A (S n).
Fixpoint htree_to_btree (n:nat) (t:htree Z n) {struct t} : Z_btree :=
match t with
hleaf _ x => Z_bnode x Z_leaf Z_leaf
| hnode _ p v t1 t2 => Z_bnode v (htree_to_btree p t1) (htree_to_btree p t2)
end.
Fixpoint invert (A:Set) (n:nat) (t:htree A n) {struct t} : htree A n :=
match t in htree _ x return htree A x with
hleaf _ v => hleaf A v
| hnode _ p v t1 t2 => hnode A p v (invert A p t2) (invert A p t1)
end.
Print Empty_set.
Check Empty_set_ind.
Inductive strange : Set :=
cs : strange -> strange.
Theorem strange_empty : forall (x:strange), False.
intro x.
elim x.
trivial.
Qed.
Inductive even_line : nat -> Set :=
even_empty_line : even_line 0
| even_step_line : forall (n:nat), even_line n -> even_line (S (S n)).
Check even_empty_line.
Check even_step_line _ even_empty_line.
Check even_step_line _ (even_step_line _ even_empty_line).
Check even_line 3.