This commit is contained in:
William Ball 2024-03-30 22:45:43 -07:00
parent 3889121d8e
commit 1646475f96
6 changed files with 667 additions and 3 deletions

2
.gitignore vendored
View file

@ -4,3 +4,5 @@
*.vos *.vos
.Makefile.d .Makefile.d
*.aux *.aux
Makefile
Makefile.conf

View file

@ -45,7 +45,7 @@ HASNATDYNLINK := $(COQMF_HASNATDYNLINK)
OCAMLWARN := $(COQMF_WARN) OCAMLWARN := $(COQMF_WARN)
Makefile.conf: _CoqProject Makefile.conf: _CoqProject
coq_makefile -f _CoqProject Basics.v Induction.v Structured.v -o Makefile coq_makefile -f _CoqProject Basics.v Induction.v Lists.v Polymorphism.v Tactics.v -o Makefile
# This file can be created by the user to hook into double colon rules or # This file can be created by the user to hook into double colon rules or
# add any other Makefile code he may need # add any other Makefile code he may need

View file

@ -1,5 +1,5 @@
# This configuration file was generated by running: # This configuration file was generated by running:
# coq_makefile -f _CoqProject Basics.v Induction.v Structured.v -o Makefile # coq_makefile -f _CoqProject Basics.v Induction.v Lists.v Polymorphism.v Tactics.v -o Makefile
COQBIN?= COQBIN?=
ifneq (,$(COQBIN)) ifneq (,$(COQBIN))
@ -14,7 +14,7 @@ COQMKFILE ?= "$(COQBIN)coq_makefile"
# # # #
############################################################################### ###############################################################################
COQMF_CMDLINE_VFILES := Basics.v Induction.v Structured.v COQMF_CMDLINE_VFILES := Basics.v Induction.v Lists.v Polymorphism.v Tactics.v
COQMF_SOURCES := $(shell $(COQMKFILE) -sources-of -f _CoqProject $(COQMF_CMDLINE_VFILES)) COQMF_SOURCES := $(shell $(COQMKFILE) -sources-of -f _CoqProject $(COQMF_CMDLINE_VFILES))
COQMF_VFILES := $(filter %.v, $(COQMF_SOURCES)) COQMF_VFILES := $(filter %.v, $(COQMF_SOURCES))
COQMF_MLIFILES := $(filter %.mli, $(COQMF_SOURCES)) COQMF_MLIFILES := $(filter %.mli, $(COQMF_SOURCES))

291
Polymorphism.v Normal file
View file

@ -0,0 +1,291 @@
From LF Require Export Lists.
Inductive list (X : Type) : Type :=
| nil
| cons (x : X) (l : list X).
Fixpoint repeat X x count : list X :=
match count with
| 0 => nil X
| S count' => cons X x (repeat X x count')
end.
Arguments nil {X}.
Arguments cons {X}.
Arguments repeat {X}.
Fixpoint app {X : Type} (l1 l2 : list X) : list X :=
match l1 with
| nil => l2
| cons h t => cons h (app t l2)
end.
Fixpoint rev {X : Type} (l: list X) : list X :=
match l with
| nil => nil
| cons h t => app (rev t) (cons h nil)
end.
Fixpoint length {X : Type} (l : list X) : nat :=
match l with
| nil => 0
| cons _ l' => S (length l')
end.
Notation "x :: y" := (cons x y)
(at level 60, right associativity).
Notation "[ ]" := nil.
Notation "[ x ; .. ; y ]" := (cons x .. (cons y []) ..).
Notation "x ++ y" := (app x y)
(at level 60, right associativity).
Theorem app_nil_r : forall (X: Type), forall l:list X,
l ++ [] = l.
Proof.
intros X.
induction l as [ | h t IHt].
- reflexivity.
- simpl.
rewrite IHt.
reflexivity.
Qed.
Theorem app_assoc : forall A (l m n: list A),
l ++ m ++ n = (l ++ m) ++ n.
Proof.
intros A l m n.
induction l as [ | h t IHt].
- reflexivity.
- simpl.
rewrite IHt.
reflexivity.
Qed.
Lemma app_length : forall X (l1 l2 : list X),
length (l1 ++ l2) = length l1 + length l2.
Proof.
intros X l1 l2.
induction l1 as [ | h t IHt].
- reflexivity.
- simpl. rewrite IHt. reflexivity.
Qed.
Theorem rev_app_distr: forall X (l1 l2 : list X),
rev (l1 ++ l2) = rev l2 ++ rev l1.
Proof.
intros X l1 l2.
induction l1 as [ | h t IHt].
- simpl.
rewrite app_nil_r.
reflexivity.
- simpl.
rewrite IHt.
rewrite app_assoc.
reflexivity.
Qed.
Inductive prod (X Y : Type) : Type :=
| pair (x : X) (y : Y).
Arguments pair {X Y}.
Notation "( x , y )" := (pair x y).
Notation "X * Y" := (prod X Y) : type_scope.
Definition fst {X Y : Type} (p : X * Y) : X :=
match p with
| (x, y) => x
end.
Definition snd {X Y : Type} (p : X * Y) : Y :=
match p with
| (x, y) => y
end.
Fixpoint combine {X Y : Type} (lx : list X) (ly : list Y) : list (X * Y) :=
match lx, ly with
| [], _ => []
| _, [] => []
| x :: tx, y :: ty => (x, y) :: (combine tx ty)
end.
Fixpoint split {X Y : Type} (l : list (X * Y)) : (list X) * (list Y) :=
match l with
| [] => ([], [])
| (x, y) :: rest => match split rest with
| (xs, ys) => (x :: xs, y :: ys)
end
end.
Fixpoint nth_error {X : Type} (l : list X) (n : nat) : option X :=
match l with
| nil => None
| a :: l' => match n with
| O => Some a
| S n' => nth_error l' n'
end
end.
Definition hd_error {X : Type} (l : list X) : option X :=
match l with
| [] => None
| h :: _ => Some h
end.
Definition doit3times {X : Type} (f : X -> X) (n : X) : X :=
f (f (f n)).
Fixpoint filter {X : Type} (test : X -> bool) (l : list X) : list X :=
match l with
| [] => []
| h :: t => if test h
then h :: (filter test t)
else filter test t
end.
Definition filter_even_gt_7 : list nat -> list nat :=
filter (fun n => even n && (7 <? n)).
Definition partition {X : Type}
(test : X -> bool)
(l : list X)
: list X * list X :=
match l with
| [] => ([], [])
| h :: t => if test h
then (h :: filter test t, filter (fun y => negb (test y)) t)
else (filter test t, h :: filter (fun y => negb (test y)) t)
end.
Fixpoint map {X Y : Type} (f : X -> Y) (l : list X) : list Y :=
match l with
| [] => []
| h :: t => f h :: map f t
end.
Theorem map_app : forall (X Y : Type) (f : X -> Y) (l1 l2 : list X),
map f (l1 ++ l2) = map f l1 ++ map f l2.
Proof.
intros X Y f l1 l2.
induction l1 as [ | h t IHt].
- reflexivity.
- simpl.
rewrite IHt.
reflexivity.
Qed.
Theorem map_rev : forall (X Y : Type) (f : X -> Y) (l : list X),
map f (rev l) = rev (map f l).
Proof.
intros X Y f.
induction l as [ | h t IHt].
- reflexivity.
- simpl.
rewrite map_app.
simpl.
rewrite IHt.
reflexivity.
Qed.
Fixpoint flat_map {X Y : Type} (f : X -> list Y) (l : list X) : list Y :=
match l with
| [] => []
| h :: t => f h ++ flat_map f t
end.
Definition option_map {X Y : Type} (f : X -> Y) (xo : option X) : option Y :=
match xo with
| None => None
| Some x => Some (f x)
end.
Fixpoint fold {X Y : Type} (f : X -> Y -> Y) (l : list X) (b : Y) : Y :=
match l with
| nil => b
| h :: t => f h (fold f t b)
end.
Definition constfun {X : Type} (x : X) : nat -> X :=
fun (k : nat) => x.
Module Exercises.
Definition fold_length {X : Type} (l : list X) : nat :=
fold (fun _ n => S n) l 0.
Theorem fold_length_correct : forall X (l : list X),
fold_length l = length l.
Proof.
intros X.
induction l as [ | h t IHt].
- reflexivity.
- simpl.
rewrite <- IHt.
reflexivity.
Qed.
Definition fold_map {X Y : Type} (f : X -> Y) (l : list X) : list Y :=
fold (fun x acc => f x :: acc) l [].
Theorem fold_map_correct : forall X Y (f : X -> Y) (l : list X),
fold_map f l = map f l.
Proof.
intros X Y f.
induction l as [ | h t IHt].
- reflexivity.
- simpl.
rewrite <- IHt.
reflexivity.
Qed.
Definition prod_curry {X Y Z : Type}
(f : X * Y -> Z) (x : X) (y : Y) : Z := f (x, y).
Definition prod_uncurry {X Y Z : Type}
(f : X -> Y -> Z) (p : X * Y) : Z :=
match p with
| (x, y) => f x y
end.
Theorem uncurry_curry : forall (X Y Z : Type)
(f : X -> Y -> Z)
x y,
prod_curry (prod_uncurry f) x y = f x y.
Proof.
intros X Y Z f x y.
unfold prod_uncurry.
unfold prod_curry.
reflexivity.
Qed.
Theorem curry_uncurry : forall (X Y Z : Type)
(f : X * Y -> Z)
x y,
prod_uncurry (prod_curry f) (x, y) = f (x, y).
Proof.
intros X Y Z f x y.
unfold prod_uncurry, prod_curry.
reflexivity.
Qed.
Module Church.
Definition cnat := forall X : Type, (X -> X) -> X -> X.
Definition zero : cnat :=
fun (X : Type) (f : X -> X) (x : X) => x.
Definition scc (n : cnat) : cnat :=
fun (X : Type) (f : X -> X) (x : X) => f ((n X f) x).
Definition one := scc zero.
Definition two := scc one.
Definition plus (n m : cnat) : cnat :=
fun (X : Type) (f : X -> X) (x : X) => (n X f) ((m X f) x).
Definition mult (n m : cnat) : cnat :=
fun (X : Type) (f : X -> X) (x : X) =>
(m X (n X f)) x.
End Church.
End Exercises.

371
Tactics.v Normal file
View file

@ -0,0 +1,371 @@
From LF Require Export Polymorphism.
From LF Require Export Lists.
Theorem silly : forall (n m o p : nat),
n = m ->
(n = m -> [n ; o] = [m ; p]) ->
[n;o] = [m;p].
Proof.
intros n m o p eq1 eq2.
apply eq2.
apply eq1.
Qed.
Theorem rev_involutive : forall (X : Type) (l : list X),
rev (rev l) = l.
Proof.
intros X.
induction l as [ | h t IHt].
- reflexivity.
- simpl.
rewrite rev_app_distr.
rewrite IHt.
reflexivity.
Qed.
Theorem rev_exercise1 : forall (X : Type ) (l l' : list X),
l = rev l' -> l' = rev l.
Proof.
intros X l l' H.
rewrite H.
symmetry.
apply rev_involutive.
Qed.
Theorem trans_eq : forall (X : Type) (n m o : X),
n = m -> m = o -> n = o.
Proof.
intros X n m o eq1 eq2.
rewrite eq1.
rewrite eq2.
reflexivity.
Qed.
Example trans_eq_exercise : forall (n m o p : nat),
m = S o ->
(n + p) = m ->
(n + p) = S o.
Proof.
intros n m o p eq1 eq2.
transitivity m.
- apply eq2.
- apply eq1.
Qed.
Example injection_ex_1 : forall (n m o : nat),
[n ; m] = [o ; o] ->
n = m.
Proof.
intros n m o H.
injection H as H1 H2.
rewrite H1.
rewrite H2.
reflexivity.
Qed.
Example injection_ex_2 : forall (X : Type) (x y z : X) (l j : list X),
x :: y :: l = z :: j ->
j = z :: l ->
x = y.
Proof.
intros X x y z l j H1 H2.
injection H1 as H1'.
rewrite H1'.
rewrite H2 in H.
injection H as H'.
symmetry.
apply H'.
Qed.
Theorem eqb_0_l : forall n,
0 =? n = true -> n = 0.
Proof.
intros [ | n'].
- reflexivity.
- intros H.
discriminate H.
Qed.
Theorem f_equal : forall (A B : Type) (f : A -> B) (x y : A),
x = y -> f x = f y.
Proof.
intros A B f x y eq.
rewrite eq.
reflexivity.
Qed.
Theorem eq_implies_succ_eq : forall (n m : nat),
n = m -> S n = S m.
Proof.
intros n m H.
apply f_equal.
apply H.
Qed.
Theorem S_inj : forall (n m : nat) (b : bool),
((S n) =? (S m)) = b ->
(n =? m) = b.
Proof.
intros n m b H.
simpl in H.
apply H.
Qed.
Example specialize_example : forall n,
(forall m, m * n = 0)
-> n = 0.
Proof.
intros n H.
specialize H with (m := 1).
simpl in H.
rewrite add_0_r in H.
apply H.
Qed.
Theorem double_injective : forall n m,
double n = double m ->
n = m.
Proof.
induction n as [ | n' IHn'].
- simpl.
intros m H.
destruct m as [ | m'].
+ reflexivity.
+ discriminate.
- simpl.
intros m H.
destruct m as [ | m'].
+ discriminate.
+ f_equal.
apply IHn'.
simpl in H.
injection H as H.
apply H.
Qed.
Theorem eqb_true : forall n m,
n =? m = true -> n = m.
Proof.
induction n as [ | n' IHn'].
- simpl.
intros m H.
destruct m as [ | m'] eqn:Eqm.
+ reflexivity.
+ discriminate.
- simpl.
intros m H.
destruct m as [ | m'] eqn:Eqm.
+ discriminate.
+ f_equal.
apply IHn' in H.
apply H.
Qed.
Theorem plus_n_n_injective : forall n m,
n + n = m + m ->
n = m.
Proof.
induction n as [ | n' IHn'].
- simpl.
intros m H.
destruct m as [ | m' ].
+ trivial.
+ discriminate.
- simpl.
intros m H.
destruct m as [ | m' ].
+ discriminate.
+ simpl in H.
injection H as H.
rewrite <- plus_n_Sm in H.
rewrite <- plus_n_Sm in H.
injection H as H.
apply IHn' in H.
rewrite H.
reflexivity.
Qed.
Theorem nth_error_after_last : forall (n : nat) (X : Type) (l : list X),
length l = n ->
nth_error l n = None.
Proof.
intros n X l.
generalize dependent n.
induction l as [ | h t IHt].
- intros n H.
reflexivity.
- intros n H.
destruct n as [ | n'].
+ simpl.
discriminate.
+ simpl.
simpl in H.
injection H as H.
apply IHt in H.
apply H.
Qed.
Definition square n := n * n.
Lemma square_mult : forall n m, square (n * m) = square n * square m.
Proof.
intros n m.
unfold square.
rewrite mult_assoc.
assert (H : n * m * n = n * n * m).
{ rewrite mul_comm. apply mult_assoc. }
rewrite H. rewrite mult_assoc. reflexivity.
Qed.
Theorem combine_split : forall X Y (l : list (X * Y)) l1 l2,
split l = (l1, l2) ->
combine l1 l2 = l.
Proof.
intros X Y l l1 l2.
generalize dependent l2.
generalize dependent l1.
induction l as [ | (h1, h2) t IHt].
- intros l1 l2.
simpl.
intros H.
injection H as H1 H2.
rewrite <- H1.
rewrite <- H2.
reflexivity.
- intros l1 l2 H.
simpl in H.
destruct (split t) as [t1 t2] eqn:Eqnt in H.
apply IHt in Eqnt.
injection H as H1 H2.
rewrite <- H1.
rewrite <- H2.
simpl.
rewrite Eqnt.
reflexivity.
Qed.
Theorem bool_fn_applied_thrice :
forall (f : bool -> bool) (b : bool),
f (f (f b)) = f b.
Proof.
intros f b.
destruct b as [ | ] eqn:Eqb
; destruct (f true) as [ | ] eqn:Eqft
; destruct (f false) as [ | ] eqn:Eqff.
- repeat rewrite Eqft. reflexivity.
- repeat rewrite Eqft. reflexivity.
- rewrite Eqft. reflexivity.
- rewrite Eqff. reflexivity.
- repeat rewrite Eqft. reflexivity.
- repeat rewrite Eqff. reflexivity.
- rewrite Eqft. rewrite Eqff. reflexivity.
- repeat rewrite Eqff. reflexivity.
Qed.
Theorem eqb_sym : forall (n m : nat),
(n =? m) = (m =? n).
Proof.
induction n as [ | n' IHn'].
- intros m.
destruct (0 =? m) as [ | ] eqn:Eqmz.
+ apply eqb_true in Eqmz.
rewrite <- Eqmz.
reflexivity.
+ simpl in Eqmz.
destruct m as [ | m' ] eqn:Eqm.
* discriminate.
* reflexivity.
- intros m.
destruct (S n' =? m) as [ | ] eqn:EqmSn.
+ simpl in EqmSn.
destruct m as [ | m' ] eqn:Eqm.
* discriminate.
* apply eqb_true in EqmSn.
rewrite EqmSn.
rewrite eqb_refl.
reflexivity.
+ destruct m as [ | m' ] eqn:Eqm.
* reflexivity.
* simpl.
simpl in EqmSn.
rewrite IHn' with (m := m') in EqmSn.
symmetry.
apply EqmSn.
Qed.
Theorem eqb_trans : forall n m p,
n =? m = true ->
m =? p = true ->
n =? p = true.
Proof.
intros n m p H1 H2.
apply eqb_true in H1.
apply eqb_true in H2.
rewrite <- H1 in H2.
rewrite H2.
rewrite eqb_refl.
reflexivity.
Qed.
Theorem filter_exercise : forall (X : Type) (test : X -> bool)
(x : X) (l lf : list X),
filter test l = x :: lf ->
test x = true.
Proof.
intros X test x l lf.
generalize dependent lf.
induction l as [ | h t IHt].
- intros lf H.
simpl in H.
discriminate H.
- intros lf H.
destruct (test h) as [ | ] eqn:Eqtesth.
+ simpl in H.
rewrite Eqtesth in H.
injection H as H1 H2.
rewrite H1 in Eqtesth.
apply Eqtesth.
+ simpl in H.
rewrite Eqtesth in H.
apply IHt in H.
apply H.
Qed.
Fixpoint forallb {X : Type} (test : X -> bool) (l : list X) :=
match l with
| [] => true
| h :: t => if test h
then forallb test t
else false
end.
Fixpoint existsb {X : Type} (test : X -> bool) (l : list X) :=
match l with
| [] => false
| h :: t => if test h
then true
else existsb test t
end.
Definition existsb' {X : Type} (test : X -> bool) (l : list X) :=
negb (forallb (fun x => negb (test x)) l).
Theorem existsb_existsb' : forall (X : Type) (test : X -> bool) (l : list X),
existsb test l = existsb' test l.
Proof.
intros X test.
induction l as [ | h t IHt].
- reflexivity.
- simpl.
destruct (test h) as [ | ] eqn:Eqtesth.
+ unfold existsb'.
simpl.
rewrite Eqtesth.
reflexivity.
+ unfold existsb'.
simpl.
rewrite Eqtesth.
simpl.
unfold existsb' in IHt.
apply IHt.
Qed.