mirror of
https://github.com/KevinMidboe/linguist.git
synced 2025-10-29 17:50:22 +00:00
New Verilog and Coq sample files added
New Verilog examples and Coq examples for additional training have been added since linguist is currently failing Coq/Verilog recognition tasks (see #201). In case it wasn't obvious, linguist will not currently pass these new, added test cases.
This commit is contained in:
707
samples/coq/Basics.v
Executable file
707
samples/coq/Basics.v
Executable file
@@ -0,0 +1,707 @@
|
||||
Inductive day : Type :=
|
||||
| monday : day
|
||||
| tuesday : day
|
||||
| wednesday : day
|
||||
| thursday : day
|
||||
| friday : day
|
||||
| saturday : day
|
||||
| sunday : day.
|
||||
|
||||
Definition next_weekday (d:day) : day :=
|
||||
match d with
|
||||
| monday => tuesday
|
||||
| tuesday => wednesday
|
||||
| wednesday => thursday
|
||||
| thursday => friday
|
||||
| friday => monday
|
||||
| saturday => monday
|
||||
| sunday => monday
|
||||
end.
|
||||
|
||||
Example test_next_weekday:
|
||||
(next_weekday (next_weekday saturday)) = tuesday.
|
||||
|
||||
Proof. simpl. reflexivity. Qed.
|
||||
|
||||
Inductive bool : Type :=
|
||||
| true : bool
|
||||
| false : bool.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Definition nandb (b1: bool) (b2:bool) : bool :=
|
||||
match b1 with
|
||||
| true => match b2 with
|
||||
| false => true
|
||||
| true => false
|
||||
end
|
||||
| false => true
|
||||
end.
|
||||
|
||||
Example test_nandb1: (nandb true false) = true.
|
||||
Proof. simpl. reflexivity. Qed.
|
||||
Example test_nandb2: (nandb false false) = true.
|
||||
Proof. simpl. reflexivity. Qed.
|
||||
Example test_nandb3: (nandb false true) = true.
|
||||
Proof. simpl. reflexivity. Qed.
|
||||
Example test_nandb4: (nandb true true) = false.
|
||||
Proof. simpl. reflexivity. Qed.
|
||||
|
||||
Definition andb3 (b1: bool) (b2:bool) (b3:bool) : bool :=
|
||||
match b1 with
|
||||
| false => false
|
||||
| true => match b2 with
|
||||
| false => false
|
||||
| true => b3
|
||||
end
|
||||
end.
|
||||
|
||||
Example test_andb31: (andb3 true true true) = true.
|
||||
Proof. simpl. reflexivity. Qed.
|
||||
Example test_andb32: (andb3 false true true) = false.
|
||||
Proof. simpl. reflexivity. Qed.
|
||||
Example test_andb33: (andb3 true false true) = false.
|
||||
Proof. simpl. reflexivity. Qed.
|
||||
Example test_andb34: (andb3 true true false) = false.
|
||||
Proof. simpl. reflexivity. Qed.
|
||||
|
||||
Module Playground1.
|
||||
|
||||
Inductive nat : Type :=
|
||||
| O : nat
|
||||
| S : nat -> nat.
|
||||
|
||||
Definition pred (n : nat) : nat :=
|
||||
match n with
|
||||
| O => O
|
||||
| S n' => n'
|
||||
end.
|
||||
|
||||
Definition minustwo (n : nat) : nat :=
|
||||
match n with
|
||||
| O => O
|
||||
| S O => O
|
||||
| S (S n') => n'
|
||||
end.
|
||||
|
||||
Fixpoint evenb (n : nat) : bool :=
|
||||
match n with
|
||||
| O => true
|
||||
| S O => false
|
||||
| S (S n') => evenb n'
|
||||
end.
|
||||
|
||||
Definition oddb (n : nat) : bool := negb (evenb n).
|
||||
|
||||
Example test_oddb1: (oddb (S O)) = true.
|
||||
Proof. reflexivity. Qed.
|
||||
Example test_oddb2: (oddb (S (S (S (S O))))) = false.
|
||||
Proof. reflexivity. Qed.
|
||||
|
||||
Fixpoint plus (n : nat) (m : nat) : nat :=
|
||||
match n with
|
||||
| O => m
|
||||
| S n' => S (plus n' m)
|
||||
end.
|
||||
|
||||
Fixpoint mult (n m : nat) : nat :=
|
||||
match n with
|
||||
| O => O
|
||||
| S n' => plus m (mult n' m)
|
||||
end.
|
||||
|
||||
Fixpoint minus (n m : nat) : nat :=
|
||||
match n, m with
|
||||
| O, _ => n
|
||||
| S n', O => S n'
|
||||
| S n', S m' => minus n' m'
|
||||
end.
|
||||
|
||||
Fixpoint exp (base power : nat) : nat :=
|
||||
match power with
|
||||
| O => S O
|
||||
| S p => mult base (exp base p)
|
||||
end.
|
||||
|
||||
Fixpoint factorial (n : nat) : nat :=
|
||||
match n with
|
||||
| O => S O
|
||||
| S n' => mult n (factorial n')
|
||||
end.
|
||||
|
||||
Example test_factorial1: (factorial (S (S (S O)))) = (S (S (S (S (S (S O)))))).
|
||||
Proof. simpl. reflexivity. Qed.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Fixpoint ble_nat (n m : nat) : bool :=
|
||||
match n with
|
||||
| O => true
|
||||
| S n' =>
|
||||
match m with
|
||||
| O => false
|
||||
| S m' => ble_nat n' m'
|
||||
end
|
||||
end.
|
||||
|
||||
Example test_ble_nat1: (ble_nat (S (S O)) (S (S O))) = true.
|
||||
Proof. simpl. reflexivity. Qed.
|
||||
Example test_ble_nat2: (ble_nat (S (S O)) (S (S (S (S O))))) = true.
|
||||
Proof. simpl. reflexivity. Qed.
|
||||
Example test_ble_nat3: (ble_nat (S (S (S (S O)))) (S (S O))) = false.
|
||||
Proof. simpl. reflexivity. Qed.
|
||||
|
||||
Definition blt_nat (n m : nat) : bool :=
|
||||
(andb (negb (beq_nat n m)) (ble_nat n m)).
|
||||
|
||||
Example test_blt_nat1: (blt_nat (S (S O)) (S (S O))) = false.
|
||||
Proof. simpl. reflexivity. Qed.
|
||||
Example test_blt_nat3: (blt_nat (S (S (S (S O)))) (S (S O))) = false.
|
||||
Proof. simpl. reflexivity. Qed.
|
||||
Example test_blt_nat2 : (blt_nat (S (S O)) (S (S (S (S O))))) = true.
|
||||
Proof. simpl. reflexivity. Qed.
|
||||
|
||||
Theorem plus_O_n : forall n : nat, O + n = n.
|
||||
Proof.
|
||||
simpl. reflexivity. Qed.
|
||||
|
||||
Theorem plus_O_n' : forall n : nat, O + n = n.
|
||||
Proof.
|
||||
reflexivity. Qed.
|
||||
|
||||
Theorem plus_O_n'' : forall n : nat, O + n = n.
|
||||
Proof.
|
||||
intros n. reflexivity. Qed.
|
||||
|
||||
Theorem plus_1_1 : forall n : nat, (S O) + n = S n.
|
||||
Proof.
|
||||
intros n. reflexivity. Qed.
|
||||
|
||||
Theorem mult_0_1: forall n : nat, O * n = O.
|
||||
Proof.
|
||||
intros n. reflexivity. Qed.
|
||||
|
||||
Theorem plus_id_example : forall n m:nat,
|
||||
n = m -> n + n = m + m.
|
||||
Proof.
|
||||
intros n m.
|
||||
intros H.
|
||||
rewrite -> H.
|
||||
reflexivity. Qed.
|
||||
|
||||
Theorem plus_id_exercise : forall n m o: nat,
|
||||
n = m -> m = o -> n + m = m + o.
|
||||
Proof.
|
||||
intros n m o.
|
||||
intros H.
|
||||
intros H'.
|
||||
rewrite -> H.
|
||||
rewrite <- H'.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem mult_0_plus : forall n m : nat,
|
||||
(O + n) * m = n * m.
|
||||
Proof.
|
||||
intros n m.
|
||||
rewrite -> plus_O_n.
|
||||
reflexivity. Qed.
|
||||
|
||||
Theorem mult_1_plus : forall n m: nat,
|
||||
((S O) + n) * m = m + (n * m).
|
||||
Proof.
|
||||
intros n m.
|
||||
rewrite -> plus_1_1.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem mult_1 : forall n : nat,
|
||||
n * (S O) = n.
|
||||
Proof.
|
||||
intros n.
|
||||
induction n as [| n'].
|
||||
reflexivity.
|
||||
simpl.
|
||||
rewrite -> IHn'.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem plus_1_neq_0 : forall n : nat,
|
||||
beq_nat (n + (S O)) O = false.
|
||||
Proof.
|
||||
intros n.
|
||||
destruct n as [| n'].
|
||||
reflexivity.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem zero_nbeq_plus_1 : forall n : nat,
|
||||
beq_nat O (n + (S O)) = false.
|
||||
Proof.
|
||||
intros n.
|
||||
destruct n.
|
||||
reflexivity.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Require String. Open Scope string_scope.
|
||||
|
||||
Ltac move_to_top x :=
|
||||
match reverse goal with
|
||||
| H : _ |- _ => try move x after H
|
||||
end.
|
||||
|
||||
Tactic Notation "assert_eq" ident(x) constr(v) :=
|
||||
let H := fresh in
|
||||
assert (x = v) as H by reflexivity;
|
||||
clear H.
|
||||
|
||||
Tactic Notation "Case_aux" ident(x) constr(name) :=
|
||||
first [
|
||||
set (x := name); move_to_top x
|
||||
| assert_eq x name; move_to_top x
|
||||
| fail 1 "because we are working on a different case" ].
|
||||
|
||||
Ltac Case name := Case_aux Case name.
|
||||
Ltac SCase name := Case_aux SCase name.
|
||||
Ltac SSCase name := Case_aux SSCase name.
|
||||
Ltac SSSCase name := Case_aux SSSCase name.
|
||||
Ltac SSSSCase name := Case_aux SSSSCase name.
|
||||
Ltac SSSSSCase name := Case_aux SSSSSCase name.
|
||||
Ltac SSSSSSCase name := Case_aux SSSSSSCase name.
|
||||
Ltac SSSSSSSCase name := Case_aux SSSSSSSCase name.
|
||||
|
||||
Theorem andb_true_elim1 : forall b c : bool,
|
||||
andb b c = true -> b = true.
|
||||
Proof.
|
||||
intros b c H.
|
||||
destruct b.
|
||||
Case "b = true".
|
||||
reflexivity.
|
||||
Case "b = false".
|
||||
rewrite <- H. reflexivity. Qed.
|
||||
|
||||
Theorem plus_0_r : forall n : nat, n + O = n.
|
||||
Proof.
|
||||
intros n. induction n as [| n'].
|
||||
Case "n = 0". reflexivity.
|
||||
Case "n = S n'". simpl. rewrite -> IHn'. reflexivity. Qed.
|
||||
|
||||
Theorem minus_diag : forall n,
|
||||
minus n n = O.
|
||||
Proof.
|
||||
intros n. induction n as [| n'].
|
||||
Case "n = 0".
|
||||
simpl. reflexivity.
|
||||
Case "n = S n'".
|
||||
simpl. rewrite -> IHn'. reflexivity. Qed.
|
||||
|
||||
|
||||
Theorem mult_0_r : forall n:nat,
|
||||
n * O = O.
|
||||
Proof.
|
||||
intros n. induction n as [| n'].
|
||||
Case "n = 0".
|
||||
reflexivity.
|
||||
Case "n = S n'".
|
||||
simpl. rewrite -> IHn'. reflexivity. Qed.
|
||||
|
||||
Theorem plus_n_Sm : forall n m : nat,
|
||||
S (n + m) = n + (S m).
|
||||
Proof.
|
||||
intros n m. induction n as [| n'].
|
||||
Case "n = 0".
|
||||
reflexivity.
|
||||
Case "n = S n'".
|
||||
simpl. rewrite -> IHn'. reflexivity. Qed.
|
||||
|
||||
Theorem plus_assoc : forall n m p : nat,
|
||||
n + (m + p) = (n + m) + p.
|
||||
Proof.
|
||||
intros n m p.
|
||||
induction n as [| n'].
|
||||
reflexivity.
|
||||
simpl.
|
||||
rewrite -> IHn'.
|
||||
reflexivity. Qed.
|
||||
|
||||
Theorem plus_distr : forall n m: nat, S (n + m) = n + (S m).
|
||||
Proof.
|
||||
intros n m. induction n as [| n'].
|
||||
Case "n = 0".
|
||||
reflexivity.
|
||||
Case "n = S n'".
|
||||
simpl. rewrite -> IHn'. reflexivity. Qed.
|
||||
|
||||
Theorem mult_distr : forall n m: nat, n * ((S O) + m) = n * (S m).
|
||||
Proof.
|
||||
intros n m.
|
||||
induction n as [| n'].
|
||||
reflexivity.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem plus_comm : forall n m : nat,
|
||||
n + m = m + n.
|
||||
Proof.
|
||||
intros n m.
|
||||
induction n as [| n'].
|
||||
Case "n = 0".
|
||||
simpl.
|
||||
rewrite -> plus_0_r.
|
||||
reflexivity.
|
||||
Case "n = S n'".
|
||||
simpl.
|
||||
rewrite -> IHn'.
|
||||
rewrite -> plus_distr.
|
||||
reflexivity. Qed.
|
||||
|
||||
Fixpoint double (n:nat) :=
|
||||
match n with
|
||||
| O => O
|
||||
| S n' => S (S (double n'))
|
||||
end.
|
||||
|
||||
Lemma double_plus : forall n, double n = n + n.
|
||||
Proof.
|
||||
intros n. induction n as [| n'].
|
||||
Case "n = 0".
|
||||
reflexivity.
|
||||
Case "n = S n'".
|
||||
simpl. rewrite -> IHn'.
|
||||
rewrite -> plus_distr. reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem beq_nat_refl : forall n : nat,
|
||||
true = beq_nat n n.
|
||||
Proof.
|
||||
intros n. induction n as [| n'].
|
||||
Case "n = 0".
|
||||
reflexivity.
|
||||
Case "n = S n".
|
||||
simpl. rewrite <- IHn'.
|
||||
reflexivity. Qed.
|
||||
|
||||
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).
|
||||
Case "Proof by assertion".
|
||||
rewrite -> plus_comm. reflexivity.
|
||||
rewrite -> H. reflexivity. Qed.
|
||||
|
||||
Theorem plus_swap : forall n m p: nat,
|
||||
n + (m + p) = m + (n + p).
|
||||
Proof.
|
||||
intros n m p.
|
||||
rewrite -> plus_assoc.
|
||||
assert(H: m + (n + p) = (m + n) + p).
|
||||
rewrite -> plus_assoc.
|
||||
reflexivity.
|
||||
rewrite -> H.
|
||||
assert(H2: m + n = n + m).
|
||||
rewrite -> plus_comm.
|
||||
reflexivity.
|
||||
rewrite -> H2.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem plus_swap' : forall n m p: nat,
|
||||
n + (m + p) = m + (n + p).
|
||||
Proof.
|
||||
intros n m p.
|
||||
rewrite -> plus_assoc.
|
||||
assert(H: m + (n + p) = (m + n) + p).
|
||||
rewrite -> plus_assoc.
|
||||
reflexivity.
|
||||
rewrite -> H.
|
||||
replace (m + n) with (n + m).
|
||||
rewrite -> plus_comm.
|
||||
reflexivity.
|
||||
rewrite -> plus_comm.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem mult_1_distr: forall m n: nat,
|
||||
n * ((S O) + m) = n * (S O) + n * m.
|
||||
Proof.
|
||||
intros n m.
|
||||
rewrite -> mult_1.
|
||||
rewrite -> plus_1_1.
|
||||
simpl.
|
||||
induction m as [|m'].
|
||||
simpl.
|
||||
reflexivity.
|
||||
simpl.
|
||||
rewrite -> plus_swap.
|
||||
rewrite <- IHm'.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem mult_comm: forall m n : nat,
|
||||
m * n = n * m.
|
||||
Proof.
|
||||
intros m n.
|
||||
induction n as [| n'].
|
||||
Case "n = 0".
|
||||
simpl.
|
||||
rewrite -> mult_0_r.
|
||||
reflexivity.
|
||||
Case "n = S n'".
|
||||
simpl.
|
||||
rewrite <- mult_distr.
|
||||
rewrite -> mult_1_distr.
|
||||
rewrite -> mult_1.
|
||||
rewrite -> IHn'.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem evenb_next : forall n : nat,
|
||||
evenb n = evenb (S (S n)).
|
||||
Proof.
|
||||
intros n.
|
||||
Admitted.
|
||||
|
||||
Theorem negb_negb : forall n : bool,
|
||||
n = negb (negb n).
|
||||
Proof.
|
||||
intros n.
|
||||
destruct n.
|
||||
reflexivity.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem evenb_n_oddb_Sn : forall n : nat,
|
||||
evenb n = negb (evenb (S n)).
|
||||
Proof.
|
||||
intros n.
|
||||
induction n as [|n'].
|
||||
reflexivity.
|
||||
assert(H: evenb n' = evenb (S (S n'))).
|
||||
reflexivity.
|
||||
rewrite <- H.
|
||||
rewrite -> IHn'.
|
||||
rewrite <- negb_negb.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
(*Fixpoint bad (n : nat) : bool :=
|
||||
match n with
|
||||
| O => true
|
||||
| S O => bad (S n)
|
||||
| S (S n') => bad n'
|
||||
end.*)
|
||||
|
||||
Theorem ble_nat_refl : forall n:nat,
|
||||
true = ble_nat n n.
|
||||
Proof.
|
||||
intros n.
|
||||
induction n as [|n'].
|
||||
Case "n = 0".
|
||||
reflexivity.
|
||||
Case "n = S n".
|
||||
simpl.
|
||||
rewrite <- IHn'.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem zero_nbeq_S : forall n: nat,
|
||||
beq_nat O (S n) = false.
|
||||
Proof.
|
||||
intros n.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem andb_false_r : forall b : bool,
|
||||
andb b false = false.
|
||||
Proof.
|
||||
intros b.
|
||||
destruct b.
|
||||
reflexivity.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem plus_ble_compat_1 : forall n m p : nat,
|
||||
ble_nat n m = true -> ble_nat (p + n) (p + m) = true.
|
||||
Proof.
|
||||
intros n m p.
|
||||
intros H.
|
||||
induction p.
|
||||
Case "p = 0".
|
||||
simpl.
|
||||
rewrite -> H.
|
||||
reflexivity.
|
||||
Case "p = S p'".
|
||||
simpl.
|
||||
rewrite -> IHp.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem S_nbeq_0 : forall n:nat,
|
||||
beq_nat (S n) O = false.
|
||||
Proof.
|
||||
intros n.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem mult_1_1 : forall n:nat, (S O) * n = n.
|
||||
Proof.
|
||||
intros n.
|
||||
simpl.
|
||||
rewrite -> plus_0_r.
|
||||
reflexivity. Qed.
|
||||
|
||||
Theorem all3_spec : forall b c : bool,
|
||||
orb (andb b c)
|
||||
(orb (negb b)
|
||||
(negb c))
|
||||
= true.
|
||||
Proof.
|
||||
intros b c.
|
||||
destruct b.
|
||||
destruct c.
|
||||
reflexivity.
|
||||
reflexivity.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Lemma mult_plus_1 : forall n m : nat,
|
||||
S(m + n) = m + (S n).
|
||||
Proof.
|
||||
intros n m.
|
||||
induction m.
|
||||
reflexivity.
|
||||
simpl.
|
||||
rewrite -> IHm.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem mult_mult : forall n m : nat,
|
||||
n * (S m) = n * m + n.
|
||||
Proof.
|
||||
intros n m.
|
||||
induction n.
|
||||
reflexivity.
|
||||
simpl.
|
||||
rewrite -> IHn.
|
||||
rewrite -> plus_assoc.
|
||||
rewrite -> mult_plus_1.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem mult_plus_distr_r : forall n m p:nat,
|
||||
(n + m) * p = (n * p) + (m * p).
|
||||
Proof.
|
||||
intros n m p.
|
||||
induction p.
|
||||
rewrite -> mult_0_r.
|
||||
rewrite -> mult_0_r.
|
||||
rewrite -> mult_0_r.
|
||||
reflexivity.
|
||||
rewrite -> mult_mult.
|
||||
rewrite -> mult_mult.
|
||||
rewrite -> mult_mult.
|
||||
rewrite -> IHp.
|
||||
assert(H1: ((n * p) + n) + (m * p + m) = (n * p) + (n + (m * p + m))).
|
||||
rewrite <- plus_assoc.
|
||||
reflexivity.
|
||||
rewrite -> H1.
|
||||
assert(H2: (n + (m * p + m)) = (m * p + (n + m))).
|
||||
rewrite -> plus_swap.
|
||||
reflexivity.
|
||||
rewrite -> H2.
|
||||
assert(H3: (n * p) + (m * p + (n + m)) = ((n * p ) + (m * p)) + (n + m)).
|
||||
rewrite -> plus_assoc.
|
||||
reflexivity.
|
||||
rewrite -> H3.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem mult_assoc : forall n m p : nat,
|
||||
n * (m * p) = (n * m) * p.
|
||||
Proof.
|
||||
intros n m p.
|
||||
induction n.
|
||||
simpl.
|
||||
reflexivity.
|
||||
simpl.
|
||||
rewrite -> mult_plus_distr_r.
|
||||
rewrite -> IHn.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Inductive bin : Type :=
|
||||
| BO : bin
|
||||
| D : bin -> bin
|
||||
| M : bin -> bin.
|
||||
|
||||
Fixpoint incbin (n : bin) : bin :=
|
||||
match n with
|
||||
| BO => M (BO)
|
||||
| D n' => M n'
|
||||
| M n' => D (incbin n')
|
||||
end.
|
||||
|
||||
Fixpoint bin2un (n : bin) : nat :=
|
||||
match n with
|
||||
| BO => O
|
||||
| D n' => double (bin2un n')
|
||||
| M n' => S (double (bin2un n'))
|
||||
end.
|
||||
|
||||
Theorem bin_comm : forall n : bin,
|
||||
bin2un(incbin n) = S (bin2un n).
|
||||
Proof.
|
||||
intros n.
|
||||
induction n.
|
||||
reflexivity.
|
||||
reflexivity.
|
||||
simpl.
|
||||
rewrite -> IHn.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
End Playground1.
|
||||
300
samples/coq/Heap.v
Executable file
300
samples/coq/Heap.v
Executable file
@@ -0,0 +1,300 @@
|
||||
(************************************************************************)
|
||||
(* v * The Coq Proof Assistant / The Coq Development Team *)
|
||||
(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2010 *)
|
||||
(* \VV/ **************************************************************)
|
||||
(* // * This file is distributed under the terms of the *)
|
||||
(* * GNU Lesser General Public License Version 2.1 *)
|
||||
(************************************************************************)
|
||||
|
||||
(** This file is deprecated, for a tree on list, use [Mergesort.v]. *)
|
||||
|
||||
(** A development of Treesort on Heap trees. It has an average
|
||||
complexity of O(n.log n) but of O(n²) in the worst case (e.g. if
|
||||
the list is already sorted) *)
|
||||
|
||||
(* G. Huet 1-9-95 uses Multiset *)
|
||||
|
||||
Require Import List Multiset PermutSetoid Relations Sorting.
|
||||
|
||||
Section defs.
|
||||
|
||||
(** * Trees and heap trees *)
|
||||
|
||||
(** ** Definition of trees over an ordered set *)
|
||||
|
||||
Variable A : Type.
|
||||
Variable leA : relation A.
|
||||
Variable eqA : relation A.
|
||||
|
||||
Let gtA (x y:A) := ~ leA x y.
|
||||
|
||||
Hypothesis leA_dec : forall x y:A, {leA x y} + {leA y x}.
|
||||
Hypothesis eqA_dec : forall x y:A, {eqA x y} + {~ eqA x y}.
|
||||
Hypothesis leA_refl : forall x y:A, eqA x y -> leA x y.
|
||||
Hypothesis leA_trans : forall x y z:A, leA x y -> leA y z -> leA x z.
|
||||
Hypothesis leA_antisym : forall x y:A, leA x y -> leA y x -> eqA x y.
|
||||
|
||||
Hint Resolve leA_refl.
|
||||
Hint Immediate eqA_dec leA_dec leA_antisym.
|
||||
|
||||
Let emptyBag := EmptyBag A.
|
||||
Let singletonBag := SingletonBag _ eqA_dec.
|
||||
|
||||
Inductive Tree :=
|
||||
| Tree_Leaf : Tree
|
||||
| Tree_Node : A -> Tree -> Tree -> Tree.
|
||||
|
||||
(** [a] is lower than a Tree [T] if [T] is a Leaf
|
||||
or [T] is a Node holding [b>a] *)
|
||||
|
||||
Definition leA_Tree (a:A) (t:Tree) :=
|
||||
match t with
|
||||
| Tree_Leaf => True
|
||||
| Tree_Node b T1 T2 => leA a b
|
||||
end.
|
||||
|
||||
Lemma leA_Tree_Leaf : forall a:A, leA_Tree a Tree_Leaf.
|
||||
Proof.
|
||||
simpl; auto with datatypes.
|
||||
Qed.
|
||||
|
||||
Lemma leA_Tree_Node :
|
||||
forall (a b:A) (G D:Tree), leA a b -> leA_Tree a (Tree_Node b G D).
|
||||
Proof.
|
||||
simpl; auto with datatypes.
|
||||
Qed.
|
||||
|
||||
|
||||
(** ** The heap property *)
|
||||
|
||||
Inductive is_heap : Tree -> Prop :=
|
||||
| nil_is_heap : is_heap Tree_Leaf
|
||||
| node_is_heap :
|
||||
forall (a:A) (T1 T2:Tree),
|
||||
leA_Tree a T1 ->
|
||||
leA_Tree a T2 ->
|
||||
is_heap T1 -> is_heap T2 -> is_heap (Tree_Node a T1 T2).
|
||||
|
||||
Lemma invert_heap :
|
||||
forall (a:A) (T1 T2:Tree),
|
||||
is_heap (Tree_Node a T1 T2) ->
|
||||
leA_Tree a T1 /\ leA_Tree a T2 /\ is_heap T1 /\ is_heap T2.
|
||||
Proof.
|
||||
intros; inversion H; auto with datatypes.
|
||||
Qed.
|
||||
|
||||
(* This lemma ought to be generated automatically by the Inversion tools *)
|
||||
Lemma is_heap_rect :
|
||||
forall P:Tree -> Type,
|
||||
P Tree_Leaf ->
|
||||
(forall (a:A) (T1 T2:Tree),
|
||||
leA_Tree a T1 ->
|
||||
leA_Tree a T2 ->
|
||||
is_heap T1 -> P T1 -> is_heap T2 -> P T2 -> P (Tree_Node a T1 T2)) ->
|
||||
forall T:Tree, is_heap T -> P T.
|
||||
Proof.
|
||||
simple induction T; auto with datatypes.
|
||||
intros a G PG D PD PN.
|
||||
elim (invert_heap a G D); auto with datatypes.
|
||||
intros H1 H2; elim H2; intros H3 H4; elim H4; intros.
|
||||
apply X0; auto with datatypes.
|
||||
Qed.
|
||||
|
||||
(* This lemma ought to be generated automatically by the Inversion tools *)
|
||||
Lemma is_heap_rec :
|
||||
forall P:Tree -> Set,
|
||||
P Tree_Leaf ->
|
||||
(forall (a:A) (T1 T2:Tree),
|
||||
leA_Tree a T1 ->
|
||||
leA_Tree a T2 ->
|
||||
is_heap T1 -> P T1 -> is_heap T2 -> P T2 -> P (Tree_Node a T1 T2)) ->
|
||||
forall T:Tree, is_heap T -> P T.
|
||||
Proof.
|
||||
simple induction T; auto with datatypes.
|
||||
intros a G PG D PD PN.
|
||||
elim (invert_heap a G D); auto with datatypes.
|
||||
intros H1 H2; elim H2; intros H3 H4; elim H4; intros.
|
||||
apply X; auto with datatypes.
|
||||
Qed.
|
||||
|
||||
Lemma low_trans :
|
||||
forall (T:Tree) (a b:A), leA a b -> leA_Tree b T -> leA_Tree a T.
|
||||
Proof.
|
||||
simple induction T; auto with datatypes.
|
||||
intros; simpl; apply leA_trans with b; auto with datatypes.
|
||||
Qed.
|
||||
|
||||
(** ** Merging two sorted lists *)
|
||||
|
||||
Inductive merge_lem (l1 l2:list A) : Type :=
|
||||
merge_exist :
|
||||
forall l:list A,
|
||||
Sorted leA l ->
|
||||
meq (list_contents _ eqA_dec l)
|
||||
(munion (list_contents _ eqA_dec l1) (list_contents _ eqA_dec l2)) ->
|
||||
(forall a, HdRel leA a l1 -> HdRel leA a l2 -> HdRel leA a l) ->
|
||||
merge_lem l1 l2.
|
||||
Require Import Morphisms.
|
||||
|
||||
Instance: Equivalence (@meq A).
|
||||
Proof. constructor; auto with datatypes. red. apply meq_trans. Defined.
|
||||
|
||||
Instance: Proper (@meq A ++> @meq _ ++> @meq _) (@munion A).
|
||||
Proof. intros x y H x' y' H'. now apply meq_congr. Qed.
|
||||
|
||||
Lemma merge :
|
||||
forall l1:list A, Sorted leA l1 ->
|
||||
forall l2:list A, Sorted leA l2 -> merge_lem l1 l2.
|
||||
Proof.
|
||||
fix 1; intros; destruct l1.
|
||||
apply merge_exist with l2; auto with datatypes.
|
||||
rename l1 into l.
|
||||
revert l2 H0. fix 1. intros.
|
||||
destruct l2 as [|a0 l0].
|
||||
apply merge_exist with (a :: l); simpl; auto with datatypes.
|
||||
elim (leA_dec a a0); intros.
|
||||
|
||||
(* 1 (leA a a0) *)
|
||||
apply Sorted_inv in H. destruct H.
|
||||
destruct (merge l H (a0 :: l0) H0).
|
||||
apply merge_exist with (a :: l1). clear merge merge0.
|
||||
auto using cons_sort, cons_leA with datatypes.
|
||||
simpl. rewrite m. now rewrite munion_ass.
|
||||
intros. apply cons_leA.
|
||||
apply (@HdRel_inv _ leA) with l; trivial with datatypes.
|
||||
|
||||
(* 2 (leA a0 a) *)
|
||||
apply Sorted_inv in H0. destruct H0.
|
||||
destruct (merge0 l0 H0). clear merge merge0.
|
||||
apply merge_exist with (a0 :: l1);
|
||||
auto using cons_sort, cons_leA with datatypes.
|
||||
simpl; rewrite m. simpl. setoid_rewrite munion_ass at 1. rewrite munion_comm.
|
||||
repeat rewrite munion_ass. setoid_rewrite munion_comm at 3. reflexivity.
|
||||
intros. apply cons_leA.
|
||||
apply (@HdRel_inv _ leA) with l0; trivial with datatypes.
|
||||
Qed.
|
||||
|
||||
(** ** From trees to multisets *)
|
||||
|
||||
(** contents of a tree as a multiset *)
|
||||
|
||||
(** Nota Bene : In what follows the definition of SingletonBag
|
||||
in not used. Actually, we could just take as postulate:
|
||||
[Parameter SingletonBag : A->multiset]. *)
|
||||
|
||||
Fixpoint contents (t:Tree) : multiset A :=
|
||||
match t with
|
||||
| Tree_Leaf => emptyBag
|
||||
| Tree_Node a t1 t2 =>
|
||||
munion (contents t1) (munion (contents t2) (singletonBag a))
|
||||
end.
|
||||
|
||||
|
||||
(** equivalence of two trees is equality of corresponding multisets *)
|
||||
Definition equiv_Tree (t1 t2:Tree) := meq (contents t1) (contents t2).
|
||||
|
||||
|
||||
|
||||
(** * From lists to sorted lists *)
|
||||
|
||||
(** ** Specification of heap insertion *)
|
||||
|
||||
Inductive insert_spec (a:A) (T:Tree) : Type :=
|
||||
insert_exist :
|
||||
forall T1:Tree,
|
||||
is_heap T1 ->
|
||||
meq (contents T1) (munion (contents T) (singletonBag a)) ->
|
||||
(forall b:A, leA b a -> leA_Tree b T -> leA_Tree b T1) ->
|
||||
insert_spec a T.
|
||||
|
||||
|
||||
Lemma insert : forall T:Tree, is_heap T -> forall a:A, insert_spec a T.
|
||||
Proof.
|
||||
simple induction 1; intros.
|
||||
apply insert_exist with (Tree_Node a Tree_Leaf Tree_Leaf);
|
||||
auto using node_is_heap, nil_is_heap, leA_Tree_Leaf with datatypes.
|
||||
simpl; unfold meq, munion; auto using node_is_heap with datatypes.
|
||||
elim (leA_dec a a0); intros.
|
||||
elim (X a0); intros.
|
||||
apply insert_exist with (Tree_Node a T2 T0);
|
||||
auto using node_is_heap, nil_is_heap, leA_Tree_Leaf with datatypes.
|
||||
simpl; apply treesort_twist1; trivial with datatypes.
|
||||
elim (X a); intros T3 HeapT3 ConT3 LeA.
|
||||
apply insert_exist with (Tree_Node a0 T2 T3);
|
||||
auto using node_is_heap, nil_is_heap, leA_Tree_Leaf with datatypes.
|
||||
apply node_is_heap; auto using node_is_heap, nil_is_heap, leA_Tree_Leaf with datatypes.
|
||||
apply low_trans with a; auto with datatypes.
|
||||
apply LeA; auto with datatypes.
|
||||
apply low_trans with a; auto with datatypes.
|
||||
simpl; apply treesort_twist2; trivial with datatypes.
|
||||
Qed.
|
||||
|
||||
|
||||
(** ** Building a heap from a list *)
|
||||
|
||||
Inductive build_heap (l:list A) : Type :=
|
||||
heap_exist :
|
||||
forall T:Tree,
|
||||
is_heap T ->
|
||||
meq (list_contents _ eqA_dec l) (contents T) -> build_heap l.
|
||||
|
||||
Lemma list_to_heap : forall l:list A, build_heap l.
|
||||
Proof.
|
||||
simple induction l.
|
||||
apply (heap_exist nil Tree_Leaf); auto with datatypes.
|
||||
simpl; unfold meq; exact nil_is_heap.
|
||||
simple induction 1.
|
||||
intros T i m; elim (insert T i a).
|
||||
intros; apply heap_exist with T1; simpl; auto with datatypes.
|
||||
apply meq_trans with (munion (contents T) (singletonBag a)).
|
||||
apply meq_trans with (munion (singletonBag a) (contents T)).
|
||||
apply meq_right; trivial with datatypes.
|
||||
apply munion_comm.
|
||||
apply meq_sym; trivial with datatypes.
|
||||
Qed.
|
||||
|
||||
|
||||
(** ** Building the sorted list *)
|
||||
|
||||
Inductive flat_spec (T:Tree) : Type :=
|
||||
flat_exist :
|
||||
forall l:list A,
|
||||
Sorted leA l ->
|
||||
(forall a:A, leA_Tree a T -> HdRel leA a l) ->
|
||||
meq (contents T) (list_contents _ eqA_dec l) -> flat_spec T.
|
||||
|
||||
Lemma heap_to_list : forall T:Tree, is_heap T -> flat_spec T.
|
||||
Proof.
|
||||
intros T h; elim h; intros.
|
||||
apply flat_exist with (nil (A:=A)); auto with datatypes.
|
||||
elim X; intros l1 s1 i1 m1; elim X0; intros l2 s2 i2 m2.
|
||||
elim (merge _ s1 _ s2); intros.
|
||||
apply flat_exist with (a :: l); simpl; auto with datatypes.
|
||||
apply meq_trans with
|
||||
(munion (list_contents _ eqA_dec l1)
|
||||
(munion (list_contents _ eqA_dec l2) (singletonBag a))).
|
||||
apply meq_congr; auto with datatypes.
|
||||
apply meq_trans with
|
||||
(munion (singletonBag a)
|
||||
(munion (list_contents _ eqA_dec l1) (list_contents _ eqA_dec l2))).
|
||||
apply munion_rotate.
|
||||
apply meq_right; apply meq_sym; trivial with datatypes.
|
||||
Qed.
|
||||
|
||||
|
||||
(** * Specification of treesort *)
|
||||
|
||||
Theorem treesort :
|
||||
forall l:list A,
|
||||
{m : list A | Sorted leA m & permutation _ eqA_dec l m}.
|
||||
Proof.
|
||||
intro l; unfold permutation.
|
||||
elim (list_to_heap l).
|
||||
intros.
|
||||
elim (heap_to_list T); auto with datatypes.
|
||||
intros.
|
||||
exists l0; auto with datatypes.
|
||||
apply meq_trans with (contents T); trivial with datatypes.
|
||||
Qed.
|
||||
|
||||
End defs.
|
||||
1558
samples/coq/Imp.v
Executable file
1558
samples/coq/Imp.v
Executable file
File diff suppressed because it is too large
Load Diff
591
samples/coq/Lists.v
Executable file
591
samples/coq/Lists.v
Executable file
@@ -0,0 +1,591 @@
|
||||
Require Export Basics.
|
||||
Module NatList.
|
||||
Import Playground1.
|
||||
|
||||
Inductive natprod : Type :=
|
||||
pair : nat -> nat -> natprod.
|
||||
|
||||
Definition fst (p : natprod) : nat :=
|
||||
match p with
|
||||
| pair x y => x
|
||||
end.
|
||||
|
||||
Definition snd (p : natprod) : nat :=
|
||||
match p with
|
||||
| pair x y => y
|
||||
end.
|
||||
|
||||
Notation "( x , y )" := (pair x y).
|
||||
|
||||
Definition swap_pair (p : natprod) : natprod :=
|
||||
match p with
|
||||
| (x, y) => (y, x)
|
||||
end.
|
||||
|
||||
Theorem surjective_pairing' : forall (n m : nat),
|
||||
(n, m) = (fst (n, m), snd (n, m)).
|
||||
Proof.
|
||||
reflexivity. Qed.
|
||||
|
||||
Theorem surjective_pairing : forall (p : natprod),
|
||||
p = (fst p, snd p).
|
||||
Proof.
|
||||
intros p.
|
||||
destruct p as (n, m).
|
||||
simpl.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem snd_fst_is_swap : forall (p : natprod),
|
||||
(snd p, fst p) = swap_pair p.
|
||||
Proof.
|
||||
intros p.
|
||||
destruct p.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem fst_swap_is_snd : forall (p : natprod),
|
||||
fst (swap_pair p) = snd p.
|
||||
Proof.
|
||||
intros p.
|
||||
destruct p.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Inductive natlist : Type :=
|
||||
| nil : natlist
|
||||
| cons : nat -> natlist -> natlist.
|
||||
|
||||
Definition l_123 := cons (S O) (cons (S (S O)) (cons (S (S (S O))) nil)).
|
||||
|
||||
Notation "x :: l" := (cons x l) (at level 60, right associativity).
|
||||
Notation "[ ]" := nil.
|
||||
Notation "[]" := nil.
|
||||
Notation "[ x , .. , y ]" := (cons x .. (cons y nil) ..).
|
||||
|
||||
Fixpoint repeat (n count : nat) : natlist :=
|
||||
match count with
|
||||
| O => nil
|
||||
| S count' => n :: (repeat n count')
|
||||
end.
|
||||
|
||||
Fixpoint length (l:natlist) : nat :=
|
||||
match l with
|
||||
| nil => O
|
||||
| h :: t => S (length t)
|
||||
end.
|
||||
|
||||
Fixpoint app (l1 l2 : natlist) : natlist :=
|
||||
match l1 with
|
||||
| nil => l2
|
||||
| h :: t => h :: (app t l2)
|
||||
end.
|
||||
|
||||
Notation "x ++ y" := (app x y) (right associativity, at level 60).
|
||||
|
||||
(*
|
||||
Example test_app1: [1,2,3] ++ [4,5] = [1,2,3,4,5].
|
||||
Proof. reflexivity. Qed.
|
||||
Example test_app2: nil ++ [4,5] = [4,5].
|
||||
Proof. reflexivity. Qed.
|
||||
Example test_app3: [1,2,3] ++ [] = [1,2,3].
|
||||
Proof. reflexivity. Qed.
|
||||
*)
|
||||
|
||||
Definition head (l : natlist) : nat :=
|
||||
match l with
|
||||
| nil => O
|
||||
| h :: t => h
|
||||
end.
|
||||
|
||||
Definition tl (l : natlist) : natlist :=
|
||||
match l with
|
||||
| nil => nil
|
||||
| h :: t => t
|
||||
end.
|
||||
|
||||
(*
|
||||
Example test_tl: tl [1,2,3] = [2,3].
|
||||
Proof. reflexivity. Qed.
|
||||
*)
|
||||
|
||||
Fixpoint nonzeros (l:natlist) : natlist :=
|
||||
match l with
|
||||
| nil => nil
|
||||
| O :: r => nonzeros r
|
||||
| n :: r => n :: (nonzeros r)
|
||||
end.
|
||||
|
||||
Example test_nonzeros: nonzeros [O,S O,O,S (S O), S (S (S O)),O,O] = [S O,S (S O), S (S (S O))].
|
||||
Proof. reflexivity. Qed.
|
||||
|
||||
Fixpoint oddmembers (l:natlist) : natlist :=
|
||||
match l with
|
||||
| nil => nil
|
||||
| n :: r => match (oddb n) with
|
||||
| true => n :: (oddmembers r)
|
||||
| false => oddmembers r
|
||||
end
|
||||
end.
|
||||
|
||||
Example test_oddmembers: oddmembers [O, S O, O, S (S O), S (S (S O)), O, O] = [S O, S (S (S O))].
|
||||
Proof. reflexivity. Qed.
|
||||
|
||||
Fixpoint countoddmembers (l:natlist) : nat :=
|
||||
length (oddmembers l).
|
||||
|
||||
Example test_countoddmembers2: countoddmembers [O, S (S O), S (S (S (S O)))] = O.
|
||||
Proof. reflexivity. Qed.
|
||||
|
||||
Example test_countoddmembers3: countoddmembers [] = O.
|
||||
Proof. reflexivity. Qed.
|
||||
|
||||
Fixpoint alternate (l1 l2 : natlist) : natlist :=
|
||||
match l1 with
|
||||
| nil => l2
|
||||
| a :: r1 => match l2 with
|
||||
| nil => l1
|
||||
| b :: r2 => a :: b :: (alternate r1 r2)
|
||||
end
|
||||
end.
|
||||
|
||||
Example test_alternative1: alternate [S O, S (S O), S (S (S O))] [S (S (S (S O))), S (S (S (S (S O)))), S (S (S (S (S (S O)))))] =
|
||||
[S O, S (S (S (S O))), S (S O), S (S (S (S (S O)))), S (S (S O)), S (S (S (S (S (S O)))))].
|
||||
Proof. reflexivity. Qed.
|
||||
|
||||
Definition bag := natlist.
|
||||
|
||||
Fixpoint count (v : nat) (s: bag) : nat :=
|
||||
match s with
|
||||
| nil => O
|
||||
| v' :: r => match (beq_nat v' v) with
|
||||
| true => S (count v r)
|
||||
| false => count v r
|
||||
end
|
||||
end.
|
||||
|
||||
Example test_count1: count (S O) [S O, S (S O), S (S (S O)), S O, S (S (S (S O))), S O] = S (S (S O)).
|
||||
Proof. reflexivity. Qed.
|
||||
|
||||
Definition sum : bag -> bag -> bag := app.
|
||||
|
||||
Example test_sum1: count (S O) (sum [S O, S (S O), S (S (S O))] [S O, S (S (S (S O))), S O]) = S (S (S O)).
|
||||
Proof. reflexivity. Qed.
|
||||
|
||||
Definition add (v:nat) (s:bag) : bag := v :: s.
|
||||
|
||||
Example test_add1: count (S O) (add (S O) [S O, S (S (S (S O))), S O]) = S (S (S O)).
|
||||
Proof. reflexivity. Qed.
|
||||
|
||||
Definition member (v:nat) (s:bag) : bool :=
|
||||
ble_nat (S O) (count v s).
|
||||
|
||||
Example test_member1: member (S O) [S O, S (S (S (S O))), S O] = true.
|
||||
Proof. reflexivity. Qed.
|
||||
|
||||
Example test_member2: member (S (S O)) [S O, S (S (S (S O))), S O] = false.
|
||||
Proof. reflexivity. Qed.
|
||||
|
||||
Fixpoint remove_one (v:nat) (s:bag) : bag :=
|
||||
match s with
|
||||
| nil => nil
|
||||
| v' :: r => match (beq_nat v v') with
|
||||
| true => r
|
||||
| false => v' :: (remove_one v r)
|
||||
end
|
||||
end.
|
||||
|
||||
Example test_remove_one1: count (S (S (S (S (S O)))))
|
||||
(remove_one (S (S (S (S (S O)))))
|
||||
[S (S O), S O, S (S (S (S (S O)))), S (S (S (S O))), S O]) = O.
|
||||
Proof. reflexivity. Qed.
|
||||
|
||||
Fixpoint remove_all (v:nat) (s:bag) : bag :=
|
||||
match s with
|
||||
| nil => nil
|
||||
| v' :: r => match (beq_nat v v') with
|
||||
| true => remove_all v r
|
||||
| false => v' :: (remove_all v r)
|
||||
end
|
||||
end.
|
||||
|
||||
Example test_remove_all1: count (S (S (S (S (S O)))))
|
||||
(remove_all (S (S (S (S (S O)))))
|
||||
[S (S O), S O, S (S (S (S (S O)))), S (S (S (S O))), S O]) = O.
|
||||
Proof. reflexivity. Qed.
|
||||
|
||||
Fixpoint subset (s1:bag) (s2:bag) : bool :=
|
||||
match s1 with
|
||||
| nil => true
|
||||
| v :: r => andb (member v s2)
|
||||
(subset r (remove_one v s2))
|
||||
end.
|
||||
|
||||
Definition test_subset1: subset [S O, S (S O)] [S (S O), S O, S (S (S (S O))), S O] = true.
|
||||
Proof. reflexivity. Qed.
|
||||
Definition test_subset2: subset [S O, S (S O), S (S O)] [S (S O), S O, S (S (S (S O))), S O] = false.
|
||||
Proof. reflexivity. Qed.
|
||||
|
||||
Theorem bag_count_add : forall n t: nat, forall s : bag,
|
||||
count n s = t -> count n (add n s) = S t.
|
||||
Proof.
|
||||
intros n t s.
|
||||
intros H.
|
||||
induction s.
|
||||
simpl.
|
||||
rewrite <- beq_nat_refl.
|
||||
rewrite <- H.
|
||||
reflexivity.
|
||||
rewrite <- H.
|
||||
simpl.
|
||||
rewrite <- beq_nat_refl.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem nil_app : forall l:natlist,
|
||||
[] ++ l = l.
|
||||
Proof.
|
||||
reflexivity. Qed.
|
||||
|
||||
Theorem tl_length_pred : forall l:natlist,
|
||||
pred (length l) = length (tl l).
|
||||
Proof.
|
||||
intros l. destruct l as [| n l'].
|
||||
Case "l = nil".
|
||||
reflexivity.
|
||||
Case "l = cons n l'".
|
||||
reflexivity. Qed.
|
||||
|
||||
Theorem app_ass:forall l1 l2 l3 : natlist,
|
||||
(l1 ++ l2) ++ l3 = l1 ++ (l2 ++ l3).
|
||||
Proof.
|
||||
intros l1 l2 l3. induction l1 as [| n l1'].
|
||||
Case "l1 = nil".
|
||||
reflexivity.
|
||||
Case "l1 = cons n l1'".
|
||||
simpl. rewrite -> IHl1'. reflexivity. Qed.
|
||||
|
||||
Theorem app_length: forall l1 l2 : natlist,
|
||||
length (l1 ++ l2) = (length l1) + (length l2).
|
||||
Proof.
|
||||
intros l1 l2. induction l1 as [| n l1'].
|
||||
Case "l1 = nil".
|
||||
reflexivity.
|
||||
Case "l1 = cons".
|
||||
simpl. rewrite -> IHl1'. reflexivity. Qed.
|
||||
|
||||
Fixpoint snoc (l:natlist) (v:nat) : natlist :=
|
||||
match l with
|
||||
| nil => [v]
|
||||
| h :: t => h :: (snoc t v)
|
||||
end.
|
||||
|
||||
Fixpoint rev (l:natlist) : natlist :=
|
||||
match l with
|
||||
| nil => nil
|
||||
| h :: t => snoc (rev t) h
|
||||
end.
|
||||
|
||||
Example test_rev1: rev [S O, S (S O), S (S (S O))] = [S (S (S O)), S (S O), S O].
|
||||
Proof. reflexivity. Qed.
|
||||
|
||||
Theorem length_snoc : forall n : nat, forall l : natlist,
|
||||
length (snoc l n) = S (length l).
|
||||
Proof.
|
||||
intros n l. induction l as [| n' l'].
|
||||
Case "l = nil".
|
||||
reflexivity.
|
||||
Case "l = cons n' l'".
|
||||
simpl. rewrite -> IHl'. reflexivity. Qed.
|
||||
|
||||
Theorem rev_length : forall l : natlist,
|
||||
length (rev l) = length l.
|
||||
Proof.
|
||||
intros l. induction l as [| n l'].
|
||||
Case "l = nil".
|
||||
reflexivity.
|
||||
Case "l = cons".
|
||||
simpl. rewrite -> length_snoc.
|
||||
rewrite -> IHl'. reflexivity. Qed.
|
||||
|
||||
Theorem app_nil_end : forall l :natlist,
|
||||
l ++ [] = l.
|
||||
Proof.
|
||||
intros l.
|
||||
induction l.
|
||||
Case "l = nil".
|
||||
reflexivity.
|
||||
Case "l = cons".
|
||||
simpl. rewrite -> IHl. reflexivity. Qed.
|
||||
|
||||
|
||||
|
||||
Theorem rev_snoc : forall l: natlist, forall n : nat,
|
||||
rev (snoc l n) = n :: (rev l).
|
||||
Proof.
|
||||
intros l n.
|
||||
induction l.
|
||||
Case "l = nil".
|
||||
reflexivity.
|
||||
Case "l = cons".
|
||||
simpl.
|
||||
rewrite -> IHl.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem rev_involutive : forall l : natlist,
|
||||
rev (rev l) = l.
|
||||
Proof.
|
||||
intros l.
|
||||
induction l.
|
||||
Case "l = nil".
|
||||
reflexivity.
|
||||
Case "l = cons".
|
||||
simpl.
|
||||
rewrite -> rev_snoc.
|
||||
rewrite -> IHl.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem app_ass4 : forall l1 l2 l3 l4 : natlist,
|
||||
l1 ++ (l2 ++ (l3 ++ l4)) = ((l1 ++ l2) ++ l3) ++ l4.
|
||||
Proof.
|
||||
intros l1 l2 l3 l4.
|
||||
rewrite -> app_ass.
|
||||
rewrite -> app_ass.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem snoc_append : forall (l : natlist) (n : nat),
|
||||
snoc l n = l ++ [n].
|
||||
Proof.
|
||||
intros l n.
|
||||
induction l.
|
||||
Case "l = nil".
|
||||
reflexivity.
|
||||
Case "l = cons".
|
||||
simpl.
|
||||
rewrite -> IHl.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem nonzeros_length : forall l1 l2 : natlist,
|
||||
nonzeros (l1 ++ l2) = (nonzeros l1) ++ (nonzeros l2).
|
||||
Proof.
|
||||
intros l1 l2.
|
||||
induction l1.
|
||||
Case "l1 = nil".
|
||||
reflexivity.
|
||||
Case "l1 = cons".
|
||||
simpl.
|
||||
rewrite -> IHl1.
|
||||
destruct n.
|
||||
reflexivity.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem distr_rev : forall l1 l2 : natlist,
|
||||
rev (l1 ++ l2) = (rev l2) ++ (rev l1).
|
||||
Proof.
|
||||
intros l1 l2.
|
||||
induction l1.
|
||||
Case "l1 = nil".
|
||||
simpl.
|
||||
rewrite -> app_nil_end.
|
||||
reflexivity.
|
||||
Case "l1 = cons".
|
||||
simpl.
|
||||
rewrite -> IHl1.
|
||||
simpl.
|
||||
rewrite -> snoc_append.
|
||||
rewrite -> snoc_append.
|
||||
rewrite -> app_ass.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem count_number_nonzero : forall (s : bag),
|
||||
ble_nat O (count (S O) (S O :: s)) = true.
|
||||
Proof.
|
||||
intros s.
|
||||
induction s.
|
||||
reflexivity.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem ble_n_Sn : forall n,
|
||||
ble_nat n (S n) = true.
|
||||
Proof.
|
||||
intros n. induction n as [| n'].
|
||||
Case "0".
|
||||
simpl. reflexivity.
|
||||
Case "S n'".
|
||||
simpl. rewrite -> IHn'. reflexivity. Qed.
|
||||
|
||||
Theorem remove_decreases_count: forall (s : bag),
|
||||
ble_nat (count O (remove_one O s)) (count O s) = true.
|
||||
Proof.
|
||||
intros s.
|
||||
induction s.
|
||||
Case "s = nil".
|
||||
reflexivity.
|
||||
Case "s = cons".
|
||||
simpl.
|
||||
induction n.
|
||||
SCase "n = O".
|
||||
simpl. rewrite -> ble_n_Sn.
|
||||
reflexivity.
|
||||
SCase "n = S n'".
|
||||
simpl.
|
||||
rewrite -> IHs.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Inductive natoption : Type :=
|
||||
| Some : nat -> natoption
|
||||
| None : natoption.
|
||||
|
||||
Fixpoint index (n:nat) (l:natlist) : natoption :=
|
||||
match l with
|
||||
| nil => None
|
||||
| a :: l' => if beq_nat n O then Some a else index (pred n) l'
|
||||
end.
|
||||
|
||||
Definition option_elim (o : natoption) (d : nat) : nat :=
|
||||
match o with
|
||||
| Some n' => n'
|
||||
| None => d
|
||||
end.
|
||||
|
||||
Definition hd_opt (l : natlist) : natoption :=
|
||||
match l with
|
||||
| nil => None
|
||||
| v :: r => Some v
|
||||
end.
|
||||
|
||||
Example test_hd_opt1 : hd_opt [] = None.
|
||||
Proof. reflexivity. Qed.
|
||||
Example test_hd_opt2 : hd_opt [S O] = Some (S O).
|
||||
Proof. reflexivity. Qed.
|
||||
|
||||
Theorem option_elim_hd : forall l:natlist,
|
||||
head l = option_elim (hd_opt l) O.
|
||||
Proof.
|
||||
intros l.
|
||||
destruct l.
|
||||
reflexivity.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Fixpoint beq_natlist (l1 l2 : natlist) : bool :=
|
||||
match l1 with
|
||||
| nil => match l2 with
|
||||
| nil => true
|
||||
| _ => false
|
||||
end
|
||||
| v1 :: r1 => match l2 with
|
||||
| nil => false
|
||||
| v2 :: r2 => if beq_nat v1 v2 then beq_natlist r1 r2
|
||||
else false
|
||||
end
|
||||
end.
|
||||
|
||||
Example test_beq_natlist1 : (beq_natlist nil nil = true).
|
||||
Proof. reflexivity. Qed.
|
||||
Example test_beq_natlist2 : (beq_natlist [S O, S (S O), S (S (S O))]
|
||||
[S O, S (S O), S (S (S O))] = true).
|
||||
Proof. reflexivity. Qed.
|
||||
|
||||
Theorem beq_natlist_refl : forall l:natlist,
|
||||
beq_natlist l l = true.
|
||||
Proof.
|
||||
intros l.
|
||||
induction l.
|
||||
Case "l = nil".
|
||||
reflexivity.
|
||||
Case "l = cons".
|
||||
simpl.
|
||||
rewrite <- beq_nat_refl.
|
||||
rewrite -> IHl.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem silly1 : forall (n m o p : nat),
|
||||
n = m -> [n, o] = [n, p] -> [n, o] = [m, p].
|
||||
Proof.
|
||||
intros n m o p eq1 eq2.
|
||||
rewrite <- eq1.
|
||||
apply eq2. Qed.
|
||||
|
||||
Theorem silly2a : forall (n m : nat),
|
||||
(n,n) = (m,m) ->
|
||||
(forall (q r : nat), (q, q) = (r, r) -> [q] = [r]) ->
|
||||
[n] = [m].
|
||||
Proof.
|
||||
intros n m eq1 eq2.
|
||||
apply eq2.
|
||||
apply eq1.
|
||||
Qed.
|
||||
|
||||
Theorem silly_ex :
|
||||
(forall n, evenb n = true -> oddb (S n) = true) ->
|
||||
evenb (S (S (S O))) = true ->
|
||||
oddb (S (S (S (S O)))) = true.
|
||||
Proof.
|
||||
intros eq1 eq2.
|
||||
apply eq1.
|
||||
apply eq2.
|
||||
Qed.
|
||||
|
||||
Theorem silly3 : forall (n : nat),
|
||||
true = beq_nat n (S (S (S (S (S O))))) ->
|
||||
beq_nat (S (S n)) (S (S (S (S (S (S (S O))))))) = true.
|
||||
Proof.
|
||||
intros n H.
|
||||
symmetry.
|
||||
apply H.
|
||||
Qed.
|
||||
|
||||
Theorem rev_exercise : forall (l l' : natlist),
|
||||
l = rev l' -> l' = rev l.
|
||||
Proof.
|
||||
intros l l' H.
|
||||
rewrite -> H.
|
||||
rewrite -> rev_involutive.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem beq_nat_sym : forall (n m:nat), forall (b: bool),
|
||||
beq_nat n m = b -> beq_nat m n = b.
|
||||
Proof.
|
||||
intros n.
|
||||
induction n as [| n'].
|
||||
Case "n = O".
|
||||
intros m b eq1.
|
||||
induction m.
|
||||
SCase "m = 0".
|
||||
apply eq1.
|
||||
SCase "m = S m'".
|
||||
apply eq1.
|
||||
Case "n = S n'".
|
||||
induction m.
|
||||
SCase "m = 0".
|
||||
intros b eq1.
|
||||
apply eq1.
|
||||
SCase "m = S m'".
|
||||
intros b eq1.
|
||||
apply IHn'.
|
||||
apply eq1.
|
||||
Qed.
|
||||
|
||||
Theorem app_ass' : forall l1 l2 l3 : natlist,
|
||||
(l1 ++ l2) ++ l3 = l1 ++ (l2 ++ l3).
|
||||
Proof.
|
||||
intros l1. induction l1 as [ | n l1'].
|
||||
reflexivity.
|
||||
simpl.
|
||||
intros l2 l3.
|
||||
rewrite -> IHl1'.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
End NatList.
|
||||
547
samples/coq/PermutSetoid.v
Executable file
547
samples/coq/PermutSetoid.v
Executable file
@@ -0,0 +1,547 @@
|
||||
(************************************************************************)
|
||||
(* v * The Coq Proof Assistant / The Coq Development Team *)
|
||||
(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2010 *)
|
||||
(* \VV/ **************************************************************)
|
||||
(* // * This file is distributed under the terms of the *)
|
||||
(* * GNU Lesser General Public License Version 2.1 *)
|
||||
(************************************************************************)
|
||||
|
||||
Require Import Omega Relations Multiset SetoidList.
|
||||
|
||||
(** This file is deprecated, use [Permutation.v] instead.
|
||||
|
||||
Indeed, this file defines a notion of permutation based on
|
||||
multisets (there exists a permutation between two lists iff every
|
||||
elements have the same multiplicity in the two lists) which
|
||||
requires a more complex apparatus (the equipment of the domain
|
||||
with a decidable equality) than [Permutation] in [Permutation.v].
|
||||
|
||||
The relation between the two relations are in lemma
|
||||
[permutation_Permutation].
|
||||
|
||||
File [Permutation] concerns Leibniz equality : it shows in particular
|
||||
that [List.Permutation] and [permutation] are equivalent in this context.
|
||||
*)
|
||||
|
||||
Set Implicit Arguments.
|
||||
|
||||
Local Notation "[ ]" := nil.
|
||||
Local Notation "[ a ; .. ; b ]" := (a :: .. (b :: []) ..).
|
||||
|
||||
Section Permut.
|
||||
|
||||
(** * From lists to multisets *)
|
||||
|
||||
Variable A : Type.
|
||||
Variable eqA : relation A.
|
||||
Hypothesis eqA_equiv : Equivalence eqA.
|
||||
Hypothesis eqA_dec : forall x y:A, {eqA x y} + {~ eqA x y}.
|
||||
|
||||
Let emptyBag := EmptyBag A.
|
||||
Let singletonBag := SingletonBag _ eqA_dec.
|
||||
|
||||
(** contents of a list *)
|
||||
|
||||
Fixpoint list_contents (l:list A) : multiset A :=
|
||||
match l with
|
||||
| [] => emptyBag
|
||||
| a :: l => munion (singletonBag a) (list_contents l)
|
||||
end.
|
||||
|
||||
Lemma list_contents_app :
|
||||
forall l m:list A,
|
||||
meq (list_contents (l ++ m)) (munion (list_contents l) (list_contents m)).
|
||||
Proof.
|
||||
simple induction l; simpl; auto with datatypes.
|
||||
intros.
|
||||
apply meq_trans with
|
||||
(munion (singletonBag a) (munion (list_contents l0) (list_contents m)));
|
||||
auto with datatypes.
|
||||
Qed.
|
||||
|
||||
(** * [permutation]: definition and basic properties *)
|
||||
|
||||
Definition permutation (l m:list A) := meq (list_contents l) (list_contents m).
|
||||
|
||||
Lemma permut_refl : forall l:list A, permutation l l.
|
||||
Proof.
|
||||
unfold permutation; auto with datatypes.
|
||||
Qed.
|
||||
|
||||
Lemma permut_sym :
|
||||
forall l1 l2 : list A, permutation l1 l2 -> permutation l2 l1.
|
||||
Proof.
|
||||
unfold permutation, meq; intros; symmetry; trivial.
|
||||
Qed.
|
||||
|
||||
Lemma permut_trans :
|
||||
forall l m n:list A, permutation l m -> permutation m n -> permutation l n.
|
||||
Proof.
|
||||
unfold permutation; intros.
|
||||
apply meq_trans with (list_contents m); auto with datatypes.
|
||||
Qed.
|
||||
|
||||
Lemma permut_cons_eq :
|
||||
forall l m:list A,
|
||||
permutation l m -> forall a a', eqA a a' -> permutation (a :: l) (a' :: m).
|
||||
Proof.
|
||||
unfold permutation; simpl; intros.
|
||||
apply meq_trans with (munion (singletonBag a') (list_contents l)).
|
||||
apply meq_left, meq_singleton; auto.
|
||||
auto with datatypes.
|
||||
Qed.
|
||||
|
||||
Lemma permut_cons :
|
||||
forall l m:list A,
|
||||
permutation l m -> forall a:A, permutation (a :: l) (a :: m).
|
||||
Proof.
|
||||
unfold permutation; simpl; auto with datatypes.
|
||||
Qed.
|
||||
|
||||
Lemma permut_app :
|
||||
forall l l' m m':list A,
|
||||
permutation l l' -> permutation m m' -> permutation (l ++ m) (l' ++ m').
|
||||
Proof.
|
||||
unfold permutation; intros.
|
||||
apply meq_trans with (munion (list_contents l) (list_contents m));
|
||||
auto using permut_cons, list_contents_app with datatypes.
|
||||
apply meq_trans with (munion (list_contents l') (list_contents m'));
|
||||
auto using permut_cons, list_contents_app with datatypes.
|
||||
apply meq_trans with (munion (list_contents l') (list_contents m));
|
||||
auto using permut_cons, list_contents_app with datatypes.
|
||||
Qed.
|
||||
|
||||
Lemma permut_add_inside_eq :
|
||||
forall a a' l1 l2 l3 l4, eqA a a' ->
|
||||
permutation (l1 ++ l2) (l3 ++ l4) ->
|
||||
permutation (l1 ++ a :: l2) (l3 ++ a' :: l4).
|
||||
Proof.
|
||||
unfold permutation, meq in *; intros.
|
||||
specialize H0 with a0.
|
||||
repeat rewrite list_contents_app in *; simpl in *.
|
||||
destruct (eqA_dec a a0) as [Ha|Ha]; rewrite H in Ha;
|
||||
decide (eqA_dec a' a0) with Ha; simpl; auto with arith.
|
||||
do 2 rewrite <- plus_n_Sm; f_equal; auto.
|
||||
Qed.
|
||||
|
||||
Lemma permut_add_inside :
|
||||
forall a l1 l2 l3 l4,
|
||||
permutation (l1 ++ l2) (l3 ++ l4) ->
|
||||
permutation (l1 ++ a :: l2) (l3 ++ a :: l4).
|
||||
Proof.
|
||||
unfold permutation, meq in *; intros.
|
||||
generalize (H a0); clear H.
|
||||
do 4 rewrite list_contents_app.
|
||||
simpl.
|
||||
destruct (eqA_dec a a0); simpl; auto with arith.
|
||||
do 2 rewrite <- plus_n_Sm; f_equal; auto.
|
||||
Qed.
|
||||
|
||||
Lemma permut_add_cons_inside_eq :
|
||||
forall a a' l l1 l2, eqA a a' ->
|
||||
permutation l (l1 ++ l2) ->
|
||||
permutation (a :: l) (l1 ++ a' :: l2).
|
||||
Proof.
|
||||
intros;
|
||||
replace (a :: l) with ([] ++ a :: l); trivial;
|
||||
apply permut_add_inside_eq; trivial.
|
||||
Qed.
|
||||
|
||||
Lemma permut_add_cons_inside :
|
||||
forall a l l1 l2,
|
||||
permutation l (l1 ++ l2) ->
|
||||
permutation (a :: l) (l1 ++ a :: l2).
|
||||
Proof.
|
||||
intros;
|
||||
replace (a :: l) with ([] ++ a :: l); trivial;
|
||||
apply permut_add_inside; trivial.
|
||||
Qed.
|
||||
|
||||
Lemma permut_middle :
|
||||
forall (l m:list A) (a:A), permutation (a :: l ++ m) (l ++ a :: m).
|
||||
Proof.
|
||||
intros; apply permut_add_cons_inside; auto using permut_sym, permut_refl.
|
||||
Qed.
|
||||
|
||||
Lemma permut_sym_app :
|
||||
forall l1 l2, permutation (l1 ++ l2) (l2 ++ l1).
|
||||
Proof.
|
||||
intros l1 l2;
|
||||
unfold permutation, meq;
|
||||
intro a; do 2 rewrite list_contents_app; simpl;
|
||||
auto with arith.
|
||||
Qed.
|
||||
|
||||
Lemma permut_rev :
|
||||
forall l, permutation l (rev l).
|
||||
Proof.
|
||||
induction l.
|
||||
simpl; trivial using permut_refl.
|
||||
simpl.
|
||||
apply permut_add_cons_inside.
|
||||
rewrite <- app_nil_end. trivial.
|
||||
Qed.
|
||||
|
||||
(** * Some inversion results. *)
|
||||
Lemma permut_conv_inv :
|
||||
forall e l1 l2, permutation (e :: l1) (e :: l2) -> permutation l1 l2.
|
||||
Proof.
|
||||
intros e l1 l2; unfold permutation, meq; simpl; intros H a;
|
||||
generalize (H a); apply plus_reg_l.
|
||||
Qed.
|
||||
|
||||
Lemma permut_app_inv1 :
|
||||
forall l l1 l2, permutation (l1 ++ l) (l2 ++ l) -> permutation l1 l2.
|
||||
Proof.
|
||||
intros l l1 l2; unfold permutation, meq; simpl;
|
||||
intros H a; generalize (H a); clear H.
|
||||
do 2 rewrite list_contents_app.
|
||||
simpl.
|
||||
intros; apply plus_reg_l with (multiplicity (list_contents l) a).
|
||||
rewrite plus_comm; rewrite H; rewrite plus_comm.
|
||||
trivial.
|
||||
Qed.
|
||||
|
||||
(** we can use [multiplicity] to define [InA] and [NoDupA]. *)
|
||||
|
||||
Fact if_eqA_then : forall a a' (B:Type)(b b':B),
|
||||
eqA a a' -> (if eqA_dec a a' then b else b') = b.
|
||||
Proof.
|
||||
intros. destruct eqA_dec as [_|NEQ]; auto.
|
||||
contradict NEQ; auto.
|
||||
Qed.
|
||||
|
||||
Lemma permut_app_inv2 :
|
||||
forall l l1 l2, permutation (l ++ l1) (l ++ l2) -> permutation l1 l2.
|
||||
Proof.
|
||||
intros l l1 l2; unfold permutation, meq; simpl;
|
||||
intros H a; generalize (H a); clear H.
|
||||
do 2 rewrite list_contents_app.
|
||||
simpl.
|
||||
intros; apply plus_reg_l with (multiplicity (list_contents l) a).
|
||||
trivial.
|
||||
Qed.
|
||||
|
||||
Lemma permut_remove_hd_eq :
|
||||
forall l l1 l2 a b, eqA a b ->
|
||||
permutation (a :: l) (l1 ++ b :: l2) -> permutation l (l1 ++ l2).
|
||||
Proof.
|
||||
unfold permutation, meq; simpl; intros l l1 l2 a b Heq H a0.
|
||||
specialize H with a0.
|
||||
rewrite list_contents_app in *; simpl in *.
|
||||
apply plus_reg_l with (if eqA_dec a a0 then 1 else 0).
|
||||
rewrite H; clear H.
|
||||
symmetry; rewrite plus_comm, <- ! plus_assoc; f_equal.
|
||||
rewrite plus_comm.
|
||||
destruct (eqA_dec a a0) as [Ha|Ha]; rewrite Heq in Ha;
|
||||
decide (eqA_dec b a0) with Ha; reflexivity.
|
||||
Qed.
|
||||
|
||||
Lemma permut_remove_hd :
|
||||
forall l l1 l2 a,
|
||||
permutation (a :: l) (l1 ++ a :: l2) -> permutation l (l1 ++ l2).
|
||||
Proof.
|
||||
eauto using permut_remove_hd_eq, Equivalence_Reflexive.
|
||||
Qed.
|
||||
|
||||
Fact if_eqA_else : forall a a' (B:Type)(b b':B),
|
||||
~eqA a a' -> (if eqA_dec a a' then b else b') = b'.
|
||||
Proof.
|
||||
intros. decide (eqA_dec a a') with H; auto.
|
||||
Qed.
|
||||
|
||||
Fact if_eqA_refl : forall a (B:Type)(b b':B),
|
||||
(if eqA_dec a a then b else b') = b.
|
||||
Proof.
|
||||
intros; apply (decide_left (eqA_dec a a)); auto with *.
|
||||
Qed.
|
||||
|
||||
(** PL: Inutilisable dans un rewrite sans un change prealable. *)
|
||||
|
||||
Global Instance if_eqA (B:Type)(b b':B) :
|
||||
Proper (eqA==>eqA==>@eq _) (fun x y => if eqA_dec x y then b else b').
|
||||
Proof.
|
||||
intros x x' Hxx' y y' Hyy'.
|
||||
intros; destruct (eqA_dec x y) as [H|H];
|
||||
destruct (eqA_dec x' y') as [H'|H']; auto.
|
||||
contradict H'; transitivity x; auto with *; transitivity y; auto with *.
|
||||
contradict H; transitivity x'; auto with *; transitivity y'; auto with *.
|
||||
Qed.
|
||||
|
||||
Fact if_eqA_rewrite_l : forall a1 a1' a2 (B:Type)(b b':B),
|
||||
eqA a1 a1' -> (if eqA_dec a1 a2 then b else b') =
|
||||
(if eqA_dec a1' a2 then b else b').
|
||||
Proof.
|
||||
intros; destruct (eqA_dec a1 a2) as [A1|A1];
|
||||
destruct (eqA_dec a1' a2) as [A1'|A1']; auto.
|
||||
contradict A1'; transitivity a1; eauto with *.
|
||||
contradict A1; transitivity a1'; eauto with *.
|
||||
Qed.
|
||||
|
||||
Fact if_eqA_rewrite_r : forall a1 a2 a2' (B:Type)(b b':B),
|
||||
eqA a2 a2' -> (if eqA_dec a1 a2 then b else b') =
|
||||
(if eqA_dec a1 a2' then b else b').
|
||||
Proof.
|
||||
intros; destruct (eqA_dec a1 a2) as [A2|A2];
|
||||
destruct (eqA_dec a1 a2') as [A2'|A2']; auto.
|
||||
contradict A2'; transitivity a2; eauto with *.
|
||||
contradict A2; transitivity a2'; eauto with *.
|
||||
Qed.
|
||||
|
||||
|
||||
Global Instance multiplicity_eqA (l:list A) :
|
||||
Proper (eqA==>@eq _) (multiplicity (list_contents l)).
|
||||
Proof.
|
||||
intros x x' Hxx'.
|
||||
induction l as [|y l Hl]; simpl; auto.
|
||||
rewrite (@if_eqA_rewrite_r y x x'); auto.
|
||||
Qed.
|
||||
|
||||
Lemma multiplicity_InA :
|
||||
forall l a, InA eqA a l <-> 0 < multiplicity (list_contents l) a.
|
||||
Proof.
|
||||
induction l.
|
||||
simpl.
|
||||
split; inversion 1.
|
||||
simpl.
|
||||
intros a'; split; intros H. inversion_clear H.
|
||||
apply (decide_left (eqA_dec a a')); auto with *.
|
||||
destruct (eqA_dec a a'); auto with *. simpl; rewrite <- IHl; auto.
|
||||
destruct (eqA_dec a a'); auto with *. right. rewrite IHl; auto.
|
||||
Qed.
|
||||
|
||||
Lemma multiplicity_InA_O :
|
||||
forall l a, ~ InA eqA a l -> multiplicity (list_contents l) a = 0.
|
||||
Proof.
|
||||
intros l a; rewrite multiplicity_InA;
|
||||
destruct (multiplicity (list_contents l) a); auto with arith.
|
||||
destruct 1; auto with arith.
|
||||
Qed.
|
||||
|
||||
Lemma multiplicity_InA_S :
|
||||
forall l a, InA eqA a l -> multiplicity (list_contents l) a >= 1.
|
||||
Proof.
|
||||
intros l a; rewrite multiplicity_InA; auto with arith.
|
||||
Qed.
|
||||
|
||||
Lemma multiplicity_NoDupA : forall l,
|
||||
NoDupA eqA l <-> (forall a, multiplicity (list_contents l) a <= 1).
|
||||
Proof.
|
||||
induction l.
|
||||
simpl.
|
||||
split; auto with arith.
|
||||
split; simpl.
|
||||
inversion_clear 1.
|
||||
rewrite IHl in H1.
|
||||
intros; destruct (eqA_dec a a0) as [EQ|NEQ]; simpl; auto with *.
|
||||
rewrite <- EQ.
|
||||
rewrite multiplicity_InA_O; auto.
|
||||
intros; constructor.
|
||||
rewrite multiplicity_InA.
|
||||
specialize (H a).
|
||||
rewrite if_eqA_refl in H.
|
||||
clear IHl; omega.
|
||||
rewrite IHl; intros.
|
||||
specialize (H a0). omega.
|
||||
Qed.
|
||||
|
||||
(** Permutation is compatible with InA. *)
|
||||
Lemma permut_InA_InA :
|
||||
forall l1 l2 e, permutation l1 l2 -> InA eqA e l1 -> InA eqA e l2.
|
||||
Proof.
|
||||
intros l1 l2 e.
|
||||
do 2 rewrite multiplicity_InA.
|
||||
unfold permutation, meq.
|
||||
intros H;rewrite H; auto.
|
||||
Qed.
|
||||
|
||||
Lemma permut_cons_InA :
|
||||
forall l1 l2 e, permutation (e :: l1) l2 -> InA eqA e l2.
|
||||
Proof.
|
||||
intros; apply (permut_InA_InA (e:=e) H); auto with *.
|
||||
Qed.
|
||||
|
||||
(** Permutation of an empty list. *)
|
||||
Lemma permut_nil :
|
||||
forall l, permutation l [] -> l = [].
|
||||
Proof.
|
||||
intro l; destruct l as [ | e l ]; trivial.
|
||||
assert (InA eqA e (e::l)) by (auto with *).
|
||||
intro Abs; generalize (permut_InA_InA Abs H).
|
||||
inversion 1.
|
||||
Qed.
|
||||
|
||||
(** Permutation for short lists. *)
|
||||
|
||||
Lemma permut_length_1:
|
||||
forall a b, permutation [a] [b] -> eqA a b.
|
||||
Proof.
|
||||
intros a b; unfold permutation, meq.
|
||||
intro P; specialize (P b); simpl in *.
|
||||
rewrite if_eqA_refl in *.
|
||||
destruct (eqA_dec a b); simpl; auto; discriminate.
|
||||
Qed.
|
||||
|
||||
Lemma permut_length_2 :
|
||||
forall a1 b1 a2 b2, permutation [a1; b1] [a2; b2] ->
|
||||
(eqA a1 a2) /\ (eqA b1 b2) \/ (eqA a1 b2) /\ (eqA a2 b1).
|
||||
Proof.
|
||||
intros a1 b1 a2 b2 P.
|
||||
assert (H:=permut_cons_InA P).
|
||||
inversion_clear H.
|
||||
left; split; auto.
|
||||
apply permut_length_1.
|
||||
red; red; intros.
|
||||
specialize (P a). simpl in *.
|
||||
rewrite (@if_eqA_rewrite_l a1 a2 a) in P by auto. omega.
|
||||
right.
|
||||
inversion_clear H0; [|inversion H].
|
||||
split; auto.
|
||||
apply permut_length_1.
|
||||
red; red; intros.
|
||||
specialize (P a); simpl in *.
|
||||
rewrite (@if_eqA_rewrite_l a1 b2 a) in P by auto. omega.
|
||||
Qed.
|
||||
|
||||
(** Permutation is compatible with length. *)
|
||||
Lemma permut_length :
|
||||
forall l1 l2, permutation l1 l2 -> length l1 = length l2.
|
||||
Proof.
|
||||
induction l1; intros l2 H.
|
||||
rewrite (permut_nil (permut_sym H)); auto.
|
||||
assert (H0:=permut_cons_InA H).
|
||||
destruct (InA_split H0) as (h2,(b,(t2,(H1,H2)))).
|
||||
subst l2.
|
||||
rewrite app_length.
|
||||
simpl; rewrite <- plus_n_Sm; f_equal.
|
||||
rewrite <- app_length.
|
||||
apply IHl1.
|
||||
apply permut_remove_hd with b.
|
||||
apply permut_trans with (a::l1); auto.
|
||||
revert H1; unfold permutation, meq; simpl.
|
||||
intros; f_equal; auto.
|
||||
rewrite (@if_eqA_rewrite_l a b a0); auto.
|
||||
Qed.
|
||||
|
||||
Lemma NoDupA_equivlistA_permut :
|
||||
forall l l', NoDupA eqA l -> NoDupA eqA l' ->
|
||||
equivlistA eqA l l' -> permutation l l'.
|
||||
Proof.
|
||||
intros.
|
||||
red; unfold meq; intros.
|
||||
rewrite multiplicity_NoDupA in H, H0.
|
||||
generalize (H a) (H0 a) (H1 a); clear H H0 H1.
|
||||
do 2 rewrite multiplicity_InA.
|
||||
destruct 3; omega.
|
||||
Qed.
|
||||
|
||||
End Permut.
|
||||
|
||||
Section Permut_map.
|
||||
|
||||
Variables A B : Type.
|
||||
|
||||
Variable eqA : relation A.
|
||||
Hypothesis eqA_dec : forall x y:A, {eqA x y} + {~ eqA x y}.
|
||||
Hypothesis eqA_equiv : Equivalence eqA.
|
||||
|
||||
Variable eqB : B->B->Prop.
|
||||
Hypothesis eqB_dec : forall x y:B, { eqB x y }+{ ~eqB x y }.
|
||||
Hypothesis eqB_trans : Transitive eqB.
|
||||
|
||||
(** Permutation is compatible with map. *)
|
||||
|
||||
Lemma permut_map :
|
||||
forall f,
|
||||
(Proper (eqA==>eqB) f) ->
|
||||
forall l1 l2, permutation _ eqA_dec l1 l2 ->
|
||||
permutation _ eqB_dec (map f l1) (map f l2).
|
||||
Proof.
|
||||
intros f; induction l1.
|
||||
intros l2 P; rewrite (permut_nil eqA_equiv (permut_sym P)); apply permut_refl.
|
||||
intros l2 P.
|
||||
simpl.
|
||||
assert (H0:=permut_cons_InA eqA_equiv P).
|
||||
destruct (InA_split H0) as (h2,(b,(t2,(H1,H2)))).
|
||||
subst l2.
|
||||
rewrite map_app.
|
||||
simpl.
|
||||
apply permut_trans with (f b :: map f l1).
|
||||
revert H1; unfold permutation, meq; simpl.
|
||||
intros; f_equal; auto.
|
||||
destruct (eqB_dec (f b) a0) as [H2|H2];
|
||||
destruct (eqB_dec (f a) a0) as [H3|H3]; auto.
|
||||
destruct H3; transitivity (f b); auto with *.
|
||||
destruct H2; transitivity (f a); auto with *.
|
||||
apply permut_add_cons_inside.
|
||||
rewrite <- map_app.
|
||||
apply IHl1; auto.
|
||||
apply permut_remove_hd with b; trivial.
|
||||
apply permut_trans with (a::l1); auto.
|
||||
revert H1; unfold permutation, meq; simpl.
|
||||
intros; f_equal; auto.
|
||||
rewrite (@if_eqA_rewrite_l _ _ eqA_equiv eqA_dec a b a0); auto.
|
||||
Qed.
|
||||
|
||||
End Permut_map.
|
||||
|
||||
Require Import Permutation.
|
||||
|
||||
Section Permut_permut.
|
||||
|
||||
Variable A : Type.
|
||||
|
||||
Variable eqA : relation A.
|
||||
Hypothesis eqA_dec : forall x y:A, {eqA x y} + {~ eqA x y}.
|
||||
Hypothesis eqA_equiv : Equivalence eqA.
|
||||
|
||||
Lemma Permutation_impl_permutation : forall l l',
|
||||
Permutation l l' -> permutation _ eqA_dec l l'.
|
||||
Proof.
|
||||
induction 1.
|
||||
apply permut_refl.
|
||||
apply permut_cons; auto using Equivalence_Reflexive.
|
||||
change (x :: y :: l) with ([x] ++ y :: l);
|
||||
apply permut_add_cons_inside; simpl;
|
||||
apply permut_cons_eq; auto using Equivalence_Reflexive, permut_refl.
|
||||
apply permut_trans with l'; trivial.
|
||||
Qed.
|
||||
|
||||
Lemma permut_eqA : forall l l', Forall2 eqA l l' -> permutation _ eqA_dec l l'.
|
||||
Proof.
|
||||
induction 1.
|
||||
apply permut_refl.
|
||||
apply permut_cons_eq; trivial.
|
||||
Qed.
|
||||
|
||||
Lemma permutation_Permutation : forall l l',
|
||||
permutation _ eqA_dec l l' <->
|
||||
exists l'', Permutation l l'' /\ Forall2 eqA l'' l'.
|
||||
Proof.
|
||||
split; intro H.
|
||||
(* -> *)
|
||||
induction l in l', H |- *.
|
||||
exists []; apply permut_sym, permut_nil in H as ->; auto using Forall2.
|
||||
pose proof H as H'.
|
||||
apply permut_cons_InA, InA_split in H
|
||||
as (l1 & y & l2 & Heq & ->); trivial.
|
||||
apply permut_remove_hd_eq, IHl in H'
|
||||
as (l'' & IHP & IHA); clear IHl; trivial.
|
||||
apply Forall2_app_inv_r in IHA as (l1'' & l2'' & Hl1 & Hl2 & ->).
|
||||
exists (l1'' ++ a :: l2''); split.
|
||||
apply Permutation_cons_app; trivial.
|
||||
apply Forall2_app, Forall2_cons; trivial.
|
||||
(* <- *)
|
||||
destruct H as (l'' & H & Heq).
|
||||
apply permut_trans with l''.
|
||||
apply Permutation_impl_permutation; trivial.
|
||||
apply permut_eqA; trivial.
|
||||
Qed.
|
||||
|
||||
End Permut_permut.
|
||||
|
||||
(* begin hide *)
|
||||
(** For compatibilty *)
|
||||
Notation permut_right := permut_cons (only parsing).
|
||||
Notation permut_tran := permut_trans (only parsing).
|
||||
(* end hide *)
|
||||
644
samples/coq/Permutation.v
Executable file
644
samples/coq/Permutation.v
Executable file
@@ -0,0 +1,644 @@
|
||||
(************************************************************************)
|
||||
(* v * The Coq Proof Assistant / The Coq Development Team *)
|
||||
(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2010 *)
|
||||
(* \VV/ **************************************************************)
|
||||
(* // * This file is distributed under the terms of the *)
|
||||
(* * GNU Lesser General Public License Version 2.1 *)
|
||||
(************************************************************************)
|
||||
|
||||
(*********************************************************************)
|
||||
(** * List permutations as a composition of adjacent transpositions *)
|
||||
(*********************************************************************)
|
||||
|
||||
(* Adapted in May 2006 by Jean-Marc Notin from initial contents by
|
||||
Laurent Théry (Huffmann contribution, October 2003) *)
|
||||
|
||||
Require Import List Setoid Compare_dec Morphisms.
|
||||
Import ListNotations. (* For notations [] and [a;b;c] *)
|
||||
Set Implicit Arguments.
|
||||
|
||||
Section Permutation.
|
||||
|
||||
Variable A:Type.
|
||||
|
||||
Inductive Permutation : list A -> list A -> Prop :=
|
||||
| perm_nil: Permutation [] []
|
||||
| perm_skip x l l' : Permutation l l' -> Permutation (x::l) (x::l')
|
||||
| perm_swap x y l : Permutation (y::x::l) (x::y::l)
|
||||
| perm_trans l l' l'' :
|
||||
Permutation l l' -> Permutation l' l'' -> Permutation l l''.
|
||||
|
||||
Local Hint Constructors Permutation.
|
||||
|
||||
(** Some facts about [Permutation] *)
|
||||
|
||||
Theorem Permutation_nil : forall (l : list A), Permutation [] l -> l = [].
|
||||
Proof.
|
||||
intros l HF.
|
||||
remember (@nil A) as m in HF.
|
||||
induction HF; discriminate || auto.
|
||||
Qed.
|
||||
|
||||
Theorem Permutation_nil_cons : forall (l : list A) (x : A),
|
||||
~ Permutation nil (x::l).
|
||||
Proof.
|
||||
intros l x HF.
|
||||
apply Permutation_nil in HF; discriminate.
|
||||
Qed.
|
||||
|
||||
(** Permutation over lists is a equivalence relation *)
|
||||
|
||||
Theorem Permutation_refl : forall l : list A, Permutation l l.
|
||||
Proof.
|
||||
induction l; constructor. exact IHl.
|
||||
Qed.
|
||||
|
||||
Theorem Permutation_sym : forall l l' : list A,
|
||||
Permutation l l' -> Permutation l' l.
|
||||
Proof.
|
||||
intros l l' Hperm; induction Hperm; auto.
|
||||
apply perm_trans with (l':=l'); assumption.
|
||||
Qed.
|
||||
|
||||
Theorem Permutation_trans : forall l l' l'' : list A,
|
||||
Permutation l l' -> Permutation l' l'' -> Permutation l l''.
|
||||
Proof.
|
||||
exact perm_trans.
|
||||
Qed.
|
||||
|
||||
End Permutation.
|
||||
|
||||
Hint Resolve Permutation_refl perm_nil perm_skip.
|
||||
|
||||
(* These hints do not reduce the size of the problem to solve and they
|
||||
must be used with care to avoid combinatoric explosions *)
|
||||
|
||||
Local Hint Resolve perm_swap perm_trans.
|
||||
Local Hint Resolve Permutation_sym Permutation_trans.
|
||||
|
||||
(* This provides reflexivity, symmetry and transitivity and rewriting
|
||||
on morphims to come *)
|
||||
|
||||
Instance Permutation_Equivalence A : Equivalence (@Permutation A) | 10 := {
|
||||
Equivalence_Reflexive := @Permutation_refl A ;
|
||||
Equivalence_Symmetric := @Permutation_sym A ;
|
||||
Equivalence_Transitive := @Permutation_trans A }.
|
||||
|
||||
Instance Permutation_cons A :
|
||||
Proper (Logic.eq ==> @Permutation A ==> @Permutation A) (@cons A) | 10.
|
||||
Proof.
|
||||
repeat intro; subst; auto using perm_skip.
|
||||
Qed.
|
||||
|
||||
Section Permutation_properties.
|
||||
|
||||
Variable A:Type.
|
||||
|
||||
Implicit Types a b : A.
|
||||
Implicit Types l m : list A.
|
||||
|
||||
(** Compatibility with others operations on lists *)
|
||||
|
||||
Theorem Permutation_in : forall (l l' : list A) (x : A),
|
||||
Permutation l l' -> In x l -> In x l'.
|
||||
Proof.
|
||||
intros l l' x Hperm; induction Hperm; simpl; tauto.
|
||||
Qed.
|
||||
|
||||
Global Instance Permutation_in' :
|
||||
Proper (Logic.eq ==> @Permutation A ==> iff) (@In A) | 10.
|
||||
Proof.
|
||||
repeat red; intros; subst; eauto using Permutation_in.
|
||||
Qed.
|
||||
|
||||
Lemma Permutation_app_tail : forall (l l' tl : list A),
|
||||
Permutation l l' -> Permutation (l++tl) (l'++tl).
|
||||
Proof.
|
||||
intros l l' tl Hperm; induction Hperm as [|x l l'|x y l|l l' l'']; simpl; auto.
|
||||
eapply Permutation_trans with (l':=l'++tl); trivial.
|
||||
Qed.
|
||||
|
||||
Lemma Permutation_app_head : forall (l tl tl' : list A),
|
||||
Permutation tl tl' -> Permutation (l++tl) (l++tl').
|
||||
Proof.
|
||||
intros l tl tl' Hperm; induction l;
|
||||
[trivial | repeat rewrite <- app_comm_cons; constructor; assumption].
|
||||
Qed.
|
||||
|
||||
Theorem Permutation_app : forall (l m l' m' : list A),
|
||||
Permutation l l' -> Permutation m m' -> Permutation (l++m) (l'++m').
|
||||
Proof.
|
||||
intros l m l' m' Hpermll' Hpermmm';
|
||||
induction Hpermll' as [|x l l'|x y l|l l' l''];
|
||||
repeat rewrite <- app_comm_cons; auto.
|
||||
apply Permutation_trans with (l' := (x :: y :: l ++ m));
|
||||
[idtac | repeat rewrite app_comm_cons; apply Permutation_app_head]; trivial.
|
||||
apply Permutation_trans with (l' := (l' ++ m')); try assumption.
|
||||
apply Permutation_app_tail; assumption.
|
||||
Qed.
|
||||
|
||||
Global Instance Permutation_app' :
|
||||
Proper (@Permutation A ==> @Permutation A ==> @Permutation A) (@app A) | 10.
|
||||
Proof.
|
||||
repeat intro; now apply Permutation_app.
|
||||
Qed.
|
||||
|
||||
Lemma Permutation_add_inside : forall a (l l' tl tl' : list A),
|
||||
Permutation l l' -> Permutation tl tl' ->
|
||||
Permutation (l ++ a :: tl) (l' ++ a :: tl').
|
||||
Proof.
|
||||
intros; apply Permutation_app; auto.
|
||||
Qed.
|
||||
|
||||
Lemma Permutation_cons_append : forall (l : list A) x,
|
||||
Permutation (x :: l) (l ++ x :: nil).
|
||||
Proof. induction l; intros; auto. simpl. rewrite <- IHl; auto. Qed.
|
||||
Local Hint Resolve Permutation_cons_append.
|
||||
|
||||
Theorem Permutation_app_comm : forall (l l' : list A),
|
||||
Permutation (l ++ l') (l' ++ l).
|
||||
Proof.
|
||||
induction l as [|x l]; simpl; intro l'.
|
||||
rewrite app_nil_r; trivial. rewrite IHl.
|
||||
rewrite app_comm_cons, Permutation_cons_append.
|
||||
now rewrite <- app_assoc.
|
||||
Qed.
|
||||
Local Hint Resolve Permutation_app_comm.
|
||||
|
||||
Theorem Permutation_cons_app : forall (l l1 l2:list A) a,
|
||||
Permutation l (l1 ++ l2) -> Permutation (a :: l) (l1 ++ a :: l2).
|
||||
Proof.
|
||||
intros l l1 l2 a H. rewrite H.
|
||||
rewrite app_comm_cons, Permutation_cons_append.
|
||||
now rewrite <- app_assoc.
|
||||
Qed.
|
||||
Local Hint Resolve Permutation_cons_app.
|
||||
|
||||
Theorem Permutation_middle : forall (l1 l2:list A) a,
|
||||
Permutation (a :: l1 ++ l2) (l1 ++ a :: l2).
|
||||
Proof.
|
||||
auto.
|
||||
Qed.
|
||||
Local Hint Resolve Permutation_middle.
|
||||
|
||||
Theorem Permutation_rev : forall (l : list A), Permutation l (rev l).
|
||||
Proof.
|
||||
induction l as [| x l]; simpl; trivial. now rewrite IHl at 1.
|
||||
Qed.
|
||||
|
||||
Global Instance Permutation_rev' :
|
||||
Proper (@Permutation A ==> @Permutation A) (@rev A) | 10.
|
||||
Proof.
|
||||
repeat intro; now rewrite <- 2 Permutation_rev.
|
||||
Qed.
|
||||
|
||||
Theorem Permutation_length : forall (l l' : list A),
|
||||
Permutation l l' -> length l = length l'.
|
||||
Proof.
|
||||
intros l l' Hperm; induction Hperm; simpl; auto. now transitivity (length l').
|
||||
Qed.
|
||||
|
||||
Global Instance Permutation_length' :
|
||||
Proper (@Permutation A ==> Logic.eq) (@length A) | 10.
|
||||
Proof.
|
||||
exact Permutation_length.
|
||||
Qed.
|
||||
|
||||
Theorem Permutation_ind_bis :
|
||||
forall P : list A -> list A -> Prop,
|
||||
P [] [] ->
|
||||
(forall x l l', Permutation l l' -> P l l' -> P (x :: l) (x :: l')) ->
|
||||
(forall x y l l', Permutation l l' -> P l l' -> P (y :: x :: l) (x :: y :: l')) ->
|
||||
(forall l l' l'', Permutation l l' -> P l l' -> Permutation l' l'' -> P l' l'' -> P l l'') ->
|
||||
forall l l', Permutation l l' -> P l l'.
|
||||
Proof.
|
||||
intros P Hnil Hskip Hswap Htrans.
|
||||
induction 1; auto.
|
||||
apply Htrans with (x::y::l); auto.
|
||||
apply Hswap; auto.
|
||||
induction l; auto.
|
||||
apply Hskip; auto.
|
||||
apply Hskip; auto.
|
||||
induction l; auto.
|
||||
eauto.
|
||||
Qed.
|
||||
|
||||
Ltac break_list l x l' H :=
|
||||
destruct l as [|x l']; simpl in *;
|
||||
injection H; intros; subst; clear H.
|
||||
|
||||
Theorem Permutation_nil_app_cons : forall (l l' : list A) (x : A),
|
||||
~ Permutation nil (l++x::l').
|
||||
Proof.
|
||||
intros l l' x HF.
|
||||
apply Permutation_nil in HF. destruct l; discriminate.
|
||||
Qed.
|
||||
|
||||
Theorem Permutation_app_inv : forall (l1 l2 l3 l4:list A) a,
|
||||
Permutation (l1++a::l2) (l3++a::l4) -> Permutation (l1++l2) (l3 ++ l4).
|
||||
Proof.
|
||||
intros l1 l2 l3 l4 a; revert l1 l2 l3 l4.
|
||||
set (P l l' :=
|
||||
forall l1 l2 l3 l4, l=l1++a::l2 -> l'=l3++a::l4 ->
|
||||
Permutation (l1++l2) (l3++l4)).
|
||||
cut (forall l l', Permutation l l' -> P l l').
|
||||
intros H; intros; eapply H; eauto.
|
||||
apply (Permutation_ind_bis P); unfold P; clear P.
|
||||
- (* nil *)
|
||||
intros; now destruct l1.
|
||||
- (* skip *)
|
||||
intros x l l' H IH; intros.
|
||||
break_list l1 b l1' H0; break_list l3 c l3' H1.
|
||||
auto.
|
||||
now rewrite H.
|
||||
now rewrite <- H.
|
||||
now rewrite (IH _ _ _ _ eq_refl eq_refl).
|
||||
- (* swap *)
|
||||
intros x y l l' Hp IH; intros.
|
||||
break_list l1 b l1' H; break_list l3 c l3' H0.
|
||||
auto.
|
||||
break_list l3' b l3'' H.
|
||||
auto.
|
||||
constructor. now rewrite Permutation_middle.
|
||||
break_list l1' c l1'' H1.
|
||||
auto.
|
||||
constructor. now rewrite Permutation_middle.
|
||||
break_list l3' d l3'' H; break_list l1' e l1'' H1.
|
||||
auto.
|
||||
rewrite perm_swap. constructor. now rewrite Permutation_middle.
|
||||
rewrite perm_swap. constructor. now rewrite Permutation_middle.
|
||||
now rewrite perm_swap, (IH _ _ _ _ eq_refl eq_refl).
|
||||
- (*trans*)
|
||||
intros.
|
||||
destruct (In_split a l') as (l'1,(l'2,H6)).
|
||||
rewrite <- H.
|
||||
subst l.
|
||||
apply in_or_app; right; red; auto.
|
||||
apply perm_trans with (l'1++l'2).
|
||||
apply (H0 _ _ _ _ H3 H6).
|
||||
apply (H2 _ _ _ _ H6 H4).
|
||||
Qed.
|
||||
|
||||
Theorem Permutation_cons_inv l l' a :
|
||||
Permutation (a::l) (a::l') -> Permutation l l'.
|
||||
Proof.
|
||||
intro H; exact (Permutation_app_inv [] l [] l' a H).
|
||||
Qed.
|
||||
|
||||
Theorem Permutation_cons_app_inv l l1 l2 a :
|
||||
Permutation (a :: l) (l1 ++ a :: l2) -> Permutation l (l1 ++ l2).
|
||||
Proof.
|
||||
intro H; exact (Permutation_app_inv [] l l1 l2 a H).
|
||||
Qed.
|
||||
|
||||
Theorem Permutation_app_inv_l : forall l l1 l2,
|
||||
Permutation (l ++ l1) (l ++ l2) -> Permutation l1 l2.
|
||||
Proof.
|
||||
induction l; simpl; auto.
|
||||
intros.
|
||||
apply IHl.
|
||||
apply Permutation_cons_inv with a; auto.
|
||||
Qed.
|
||||
|
||||
Theorem Permutation_app_inv_r : forall l l1 l2,
|
||||
Permutation (l1 ++ l) (l2 ++ l) -> Permutation l1 l2.
|
||||
Proof.
|
||||
induction l.
|
||||
intros l1 l2; do 2 rewrite app_nil_r; auto.
|
||||
intros.
|
||||
apply IHl.
|
||||
apply Permutation_app_inv with a; auto.
|
||||
Qed.
|
||||
|
||||
Lemma Permutation_length_1_inv: forall a l, Permutation [a] l -> l = [a].
|
||||
Proof.
|
||||
intros a l H; remember [a] as m in H.
|
||||
induction H; try (injection Heqm as -> ->; clear Heqm);
|
||||
discriminate || auto.
|
||||
apply Permutation_nil in H as ->; trivial.
|
||||
Qed.
|
||||
|
||||
Lemma Permutation_length_1: forall a b, Permutation [a] [b] -> a = b.
|
||||
Proof.
|
||||
intros a b H.
|
||||
apply Permutation_length_1_inv in H; injection H as ->; trivial.
|
||||
Qed.
|
||||
|
||||
Lemma Permutation_length_2_inv :
|
||||
forall a1 a2 l, Permutation [a1;a2] l -> l = [a1;a2] \/ l = [a2;a1].
|
||||
Proof.
|
||||
intros a1 a2 l H; remember [a1;a2] as m in H.
|
||||
revert a1 a2 Heqm.
|
||||
induction H; intros; try (injection Heqm; intros; subst; clear Heqm);
|
||||
discriminate || (try tauto).
|
||||
apply Permutation_length_1_inv in H as ->; left; auto.
|
||||
apply IHPermutation1 in Heqm as [H1|H1]; apply IHPermutation2 in H1 as ();
|
||||
auto.
|
||||
Qed.
|
||||
|
||||
Lemma Permutation_length_2 :
|
||||
forall a1 a2 b1 b2, Permutation [a1;a2] [b1;b2] ->
|
||||
a1 = b1 /\ a2 = b2 \/ a1 = b2 /\ a2 = b1.
|
||||
Proof.
|
||||
intros a1 b1 a2 b2 H.
|
||||
apply Permutation_length_2_inv in H as [H|H]; injection H as -> ->; auto.
|
||||
Qed.
|
||||
|
||||
Let in_middle l l1 l2 (a:A) : l = l1 ++ a :: l2 ->
|
||||
forall x, In x l <-> a = x \/ In x (l1++l2).
|
||||
Proof.
|
||||
intros; subst; rewrite !in_app_iff; simpl. tauto.
|
||||
Qed.
|
||||
|
||||
Lemma NoDup_cardinal_incl (l l' : list A) : NoDup l -> NoDup l' ->
|
||||
length l = length l' -> incl l l' -> incl l' l.
|
||||
Proof.
|
||||
intros N. revert l'. induction N as [|a l Hal Hl IH].
|
||||
- destruct l'; now auto.
|
||||
- intros l' Hl' E H x Hx.
|
||||
assert (Ha : In a l') by (apply H; simpl; auto).
|
||||
destruct (in_split _ _ Ha) as (l1 & l2 & H12). clear Ha.
|
||||
rewrite in_middle in Hx; eauto.
|
||||
destruct Hx as [Hx|Hx]; [left|right]; auto.
|
||||
apply (IH (l1++l2)); auto.
|
||||
* apply NoDup_remove_1 with a; rewrite <- H12; auto.
|
||||
* apply eq_add_S.
|
||||
simpl in E; rewrite E, H12, !app_length; simpl; auto with arith.
|
||||
* intros y Hy. assert (Hy' : In y l') by (apply H; simpl; auto).
|
||||
rewrite in_middle in Hy'; eauto.
|
||||
destruct Hy'; auto. subst y; intuition.
|
||||
Qed.
|
||||
|
||||
Lemma NoDup_Permutation l l' : NoDup l -> NoDup l' ->
|
||||
(forall x:A, In x l <-> In x l') -> Permutation l l'.
|
||||
Proof.
|
||||
intros N. revert l'. induction N as [|a l Hal Hl IH].
|
||||
- destruct l'; simpl; auto.
|
||||
intros Hl' H. exfalso. rewrite (H a); auto.
|
||||
- intros l' Hl' H.
|
||||
assert (Ha : In a l') by (apply H; simpl; auto).
|
||||
destruct (In_split _ _ Ha) as (l1 & l2 & H12).
|
||||
rewrite H12.
|
||||
apply Permutation_cons_app.
|
||||
apply IH; auto.
|
||||
* apply NoDup_remove_1 with a; rewrite <- H12; auto.
|
||||
* intro x. split; intros Hx.
|
||||
+ assert (Hx' : In x l') by (apply H; simpl; auto).
|
||||
rewrite in_middle in Hx'; eauto.
|
||||
destruct Hx'; auto. subst; intuition.
|
||||
+ assert (Hx' : In x l') by (rewrite (in_middle l1 l2 a); eauto).
|
||||
rewrite <- H in Hx'. destruct Hx'; auto.
|
||||
subst. destruct (NoDup_remove_2 _ _ _ Hl' Hx).
|
||||
Qed.
|
||||
|
||||
Lemma NoDup_Permutation_bis l l' : NoDup l -> NoDup l' ->
|
||||
length l = length l' -> incl l l' -> Permutation l l'.
|
||||
Proof.
|
||||
intros. apply NoDup_Permutation; auto.
|
||||
split; auto. apply NoDup_cardinal_incl; auto.
|
||||
Qed.
|
||||
|
||||
Lemma Permutation_NoDup l l' : Permutation l l' -> NoDup l -> NoDup l'.
|
||||
Proof.
|
||||
induction 1; auto.
|
||||
* inversion_clear 1; constructor; eauto using Permutation_in.
|
||||
* inversion_clear 1 as [|? ? H1 H2]. inversion_clear H2; simpl in *.
|
||||
constructor. simpl; intuition. constructor; intuition.
|
||||
Qed.
|
||||
|
||||
Global Instance Permutation_NoDup' :
|
||||
Proper (@Permutation A ==> iff) (@NoDup A) | 10.
|
||||
Proof.
|
||||
repeat red; eauto using Permutation_NoDup.
|
||||
Qed.
|
||||
|
||||
End Permutation_properties.
|
||||
|
||||
Section Permutation_map.
|
||||
|
||||
Variable A B : Type.
|
||||
Variable f : A -> B.
|
||||
|
||||
Lemma Permutation_map l l' :
|
||||
Permutation l l' -> Permutation (map f l) (map f l').
|
||||
Proof.
|
||||
induction 1; simpl; eauto.
|
||||
Qed.
|
||||
|
||||
Global Instance Permutation_map' :
|
||||
Proper (@Permutation A ==> @Permutation B) (map f) | 10.
|
||||
Proof.
|
||||
exact Permutation_map.
|
||||
Qed.
|
||||
|
||||
End Permutation_map.
|
||||
|
||||
Section Injection.
|
||||
|
||||
Definition injective {A B} (f : A->B) :=
|
||||
forall x y, f x = f y -> x = y.
|
||||
|
||||
Lemma injective_map_NoDup {A B} (f:A->B) (l:list A) :
|
||||
injective f -> NoDup l -> NoDup (map f l).
|
||||
Proof.
|
||||
intros Hf. induction 1 as [|x l Hx Hl IH]; simpl; constructor; trivial.
|
||||
rewrite in_map_iff. intros (y & Hy & Hy'). apply Hf in Hy. now subst.
|
||||
Qed.
|
||||
|
||||
Lemma injective_bounded_surjective n f :
|
||||
injective f ->
|
||||
(forall x, x < n -> f x < n) ->
|
||||
(forall y, y < n -> exists x, x < n /\ f x = y).
|
||||
Proof.
|
||||
intros Hf H.
|
||||
set (l := seq 0 n).
|
||||
assert (P : incl (map f l) l).
|
||||
{ intros x. rewrite in_map_iff. intros (y & <- & Hy').
|
||||
unfold l in *. rewrite in_seq in *. simpl in *.
|
||||
destruct Hy' as (_,Hy'). auto with arith. }
|
||||
assert (P' : incl l (map f l)).
|
||||
{ unfold l.
|
||||
apply NoDup_cardinal_incl; auto using injective_map_NoDup, seq_NoDup.
|
||||
now rewrite map_length. }
|
||||
intros x Hx.
|
||||
assert (Hx' : In x l) by (unfold l; rewrite in_seq; auto with arith).
|
||||
apply P' in Hx'.
|
||||
rewrite in_map_iff in Hx'. destruct Hx' as (y & Hy & Hy').
|
||||
exists y; split; auto. unfold l in *; rewrite in_seq in Hy'.
|
||||
destruct Hy'; auto with arith.
|
||||
Qed.
|
||||
|
||||
Lemma nat_bijection_Permutation n f :
|
||||
injective f -> (forall x, x < n -> f x < n) ->
|
||||
let l := seq 0 n in Permutation (map f l) l.
|
||||
Proof.
|
||||
intros Hf BD.
|
||||
apply NoDup_Permutation_bis; auto using injective_map_NoDup, seq_NoDup.
|
||||
* now rewrite map_length.
|
||||
* intros x. rewrite in_map_iff. intros (y & <- & Hy').
|
||||
rewrite in_seq in *. simpl in *.
|
||||
destruct Hy' as (_,Hy'). auto with arith.
|
||||
Qed.
|
||||
|
||||
End Injection.
|
||||
|
||||
Section Permutation_alt.
|
||||
Variable A:Type.
|
||||
Implicit Type a : A.
|
||||
Implicit Type l : list A.
|
||||
|
||||
(** Alternative characterization of permutation
|
||||
via [nth_error] and [nth] *)
|
||||
|
||||
Let adapt f n :=
|
||||
let m := f (S n) in if le_lt_dec m (f 0) then m else pred m.
|
||||
|
||||
Let adapt_injective f : injective f -> injective (adapt f).
|
||||
Proof.
|
||||
unfold adapt. intros Hf x y EQ.
|
||||
destruct le_lt_dec as [LE|LT]; destruct le_lt_dec as [LE'|LT'].
|
||||
- now apply eq_add_S, Hf.
|
||||
- apply Lt.le_lt_or_eq in LE.
|
||||
destruct LE as [LT|EQ']; [|now apply Hf in EQ'].
|
||||
unfold lt in LT. rewrite EQ in LT.
|
||||
rewrite <- (Lt.S_pred _ _ LT') in LT.
|
||||
elim (Lt.lt_not_le _ _ LT' LT).
|
||||
- apply Lt.le_lt_or_eq in LE'.
|
||||
destruct LE' as [LT'|EQ']; [|now apply Hf in EQ'].
|
||||
unfold lt in LT'. rewrite <- EQ in LT'.
|
||||
rewrite <- (Lt.S_pred _ _ LT) in LT'.
|
||||
elim (Lt.lt_not_le _ _ LT LT').
|
||||
- apply eq_add_S, Hf.
|
||||
now rewrite (Lt.S_pred _ _ LT), (Lt.S_pred _ _ LT'), EQ.
|
||||
Qed.
|
||||
|
||||
Let adapt_ok a l1 l2 f : injective f -> length l1 = f 0 ->
|
||||
forall n, nth_error (l1++a::l2) (f (S n)) = nth_error (l1++l2) (adapt f n).
|
||||
Proof.
|
||||
unfold adapt. intros Hf E n.
|
||||
destruct le_lt_dec as [LE|LT].
|
||||
- apply Lt.le_lt_or_eq in LE.
|
||||
destruct LE as [LT|EQ]; [|now apply Hf in EQ].
|
||||
rewrite <- E in LT.
|
||||
rewrite 2 nth_error_app1; auto.
|
||||
- rewrite (Lt.S_pred _ _ LT) at 1.
|
||||
rewrite <- E, (Lt.S_pred _ _ LT) in LT.
|
||||
rewrite 2 nth_error_app2; auto with arith.
|
||||
rewrite <- Minus.minus_Sn_m; auto with arith.
|
||||
Qed.
|
||||
|
||||
Lemma Permutation_nth_error l l' :
|
||||
Permutation l l' <->
|
||||
(length l = length l' /\
|
||||
exists f:nat->nat,
|
||||
injective f /\ forall n, nth_error l' n = nth_error l (f n)).
|
||||
Proof.
|
||||
split.
|
||||
{ intros P.
|
||||
split; [now apply Permutation_length|].
|
||||
induction P.
|
||||
- exists (fun n => n).
|
||||
split; try red; auto.
|
||||
- destruct IHP as (f & Hf & Hf').
|
||||
exists (fun n => match n with O => O | S n => S (f n) end).
|
||||
split; try red.
|
||||
* intros [|y] [|z]; simpl; now auto.
|
||||
* intros [|n]; simpl; auto.
|
||||
- exists (fun n => match n with 0 => 1 | 1 => 0 | n => n end).
|
||||
split; try red.
|
||||
* intros [|[|z]] [|[|t]]; simpl; now auto.
|
||||
* intros [|[|n]]; simpl; auto.
|
||||
- destruct IHP1 as (f & Hf & Hf').
|
||||
destruct IHP2 as (g & Hg & Hg').
|
||||
exists (fun n => f (g n)).
|
||||
split; try red.
|
||||
* auto.
|
||||
* intros n. rewrite <- Hf'; auto. }
|
||||
{ revert l. induction l'.
|
||||
- intros [|l] (E & _); now auto.
|
||||
- intros l (E & f & Hf & Hf').
|
||||
simpl in E.
|
||||
assert (Ha : nth_error l (f 0) = Some a)
|
||||
by (symmetry; apply (Hf' 0)).
|
||||
destruct (nth_error_split l (f 0) Ha) as (l1 & l2 & L12 & L1).
|
||||
rewrite L12. rewrite <- Permutation_middle. constructor.
|
||||
apply IHl'; split; [|exists (adapt f); split].
|
||||
* revert E. rewrite L12, !app_length. simpl.
|
||||
rewrite <- plus_n_Sm. now injection 1.
|
||||
* now apply adapt_injective.
|
||||
* intro n. rewrite <- (adapt_ok a), <- L12; auto.
|
||||
apply (Hf' (S n)). }
|
||||
Qed.
|
||||
|
||||
Lemma Permutation_nth_error_bis l l' :
|
||||
Permutation l l' <->
|
||||
exists f:nat->nat,
|
||||
injective f /\
|
||||
(forall n, n < length l -> f n < length l) /\
|
||||
(forall n, nth_error l' n = nth_error l (f n)).
|
||||
Proof.
|
||||
rewrite Permutation_nth_error; split.
|
||||
- intros (E & f & Hf & Hf').
|
||||
exists f. do 2 (split; trivial).
|
||||
intros n Hn.
|
||||
destruct (Lt.le_or_lt (length l) (f n)) as [LE|LT]; trivial.
|
||||
rewrite <- nth_error_None, <- Hf', nth_error_None, <- E in LE.
|
||||
elim (Lt.lt_not_le _ _ Hn LE).
|
||||
- intros (f & Hf & Hf2 & Hf3); split; [|exists f; auto].
|
||||
assert (H : length l' <= length l') by auto with arith.
|
||||
rewrite <- nth_error_None, Hf3, nth_error_None in H.
|
||||
destruct (Lt.le_or_lt (length l) (length l')) as [LE|LT];
|
||||
[|apply Hf2 in LT; elim (Lt.lt_not_le _ _ LT H)].
|
||||
apply Lt.le_lt_or_eq in LE. destruct LE as [LT|EQ]; trivial.
|
||||
rewrite <- nth_error_Some, Hf3, nth_error_Some in LT.
|
||||
destruct (injective_bounded_surjective Hf Hf2 LT) as (y & Hy & Hy').
|
||||
apply Hf in Hy'. subst y. elim (Lt.lt_irrefl _ Hy).
|
||||
Qed.
|
||||
|
||||
Lemma Permutation_nth l l' d :
|
||||
Permutation l l' <->
|
||||
(let n := length l in
|
||||
length l' = n /\
|
||||
exists f:nat->nat,
|
||||
(forall x, x < n -> f x < n) /\
|
||||
(forall x y, x < n -> y < n -> f x = f y -> x = y) /\
|
||||
(forall x, x < n -> nth x l' d = nth (f x) l d)).
|
||||
Proof.
|
||||
split.
|
||||
- intros H.
|
||||
assert (E := Permutation_length H).
|
||||
split; auto.
|
||||
apply Permutation_nth_error_bis in H.
|
||||
destruct H as (f & Hf & Hf2 & Hf3).
|
||||
exists f. split; [|split]; auto.
|
||||
intros n Hn. rewrite <- 2 nth_default_eq. unfold nth_default.
|
||||
now rewrite Hf3.
|
||||
- intros (E & f & Hf1 & Hf2 & Hf3).
|
||||
rewrite Permutation_nth_error.
|
||||
split; auto.
|
||||
exists (fun n => if le_lt_dec (length l) n then n else f n).
|
||||
split.
|
||||
* intros x y.
|
||||
destruct le_lt_dec as [LE|LT];
|
||||
destruct le_lt_dec as [LE'|LT']; auto.
|
||||
+ apply Hf1 in LT'. intros ->.
|
||||
elim (Lt.lt_irrefl (f y)). eapply Lt.lt_le_trans; eauto.
|
||||
+ apply Hf1 in LT. intros <-.
|
||||
elim (Lt.lt_irrefl (f x)). eapply Lt.lt_le_trans; eauto.
|
||||
* intros n.
|
||||
destruct le_lt_dec as [LE|LT].
|
||||
+ assert (LE' : length l' <= n) by (now rewrite E).
|
||||
rewrite <- nth_error_None in LE, LE'. congruence.
|
||||
+ assert (LT' : n < length l') by (now rewrite E).
|
||||
specialize (Hf3 n LT). rewrite <- 2 nth_default_eq in Hf3.
|
||||
unfold nth_default in Hf3.
|
||||
apply Hf1 in LT.
|
||||
rewrite <- nth_error_Some in LT, LT'.
|
||||
do 2 destruct nth_error; congruence.
|
||||
Qed.
|
||||
|
||||
End Permutation_alt.
|
||||
|
||||
(* begin hide *)
|
||||
Notation Permutation_app_swap := Permutation_app_comm (only parsing).
|
||||
(* end hide *)
|
||||
875
samples/coq/Poly.v
Executable file
875
samples/coq/Poly.v
Executable file
@@ -0,0 +1,875 @@
|
||||
Require Export Lists.
|
||||
Require Export Basics.
|
||||
|
||||
Import Playground1.
|
||||
|
||||
Inductive list (X : Type) : Type :=
|
||||
| nil : list X
|
||||
| cons : X -> list X -> list X.
|
||||
|
||||
Fixpoint length (X:Type) (l:list X) : nat :=
|
||||
match l with
|
||||
| nil => O
|
||||
| cons h t => S (length X t)
|
||||
end.
|
||||
|
||||
Fixpoint app (X : Type) (l1 l2 : list X)
|
||||
: (list X) :=
|
||||
match l1 with
|
||||
| nil => l2
|
||||
| cons h t => cons X h (app X t l2)
|
||||
end.
|
||||
|
||||
Fixpoint snoc (X:Type) (l:list X) (v:X) : (list X) :=
|
||||
match l with
|
||||
| nil => cons X v (nil X)
|
||||
| cons h t => cons X h (snoc X t v)
|
||||
end.
|
||||
|
||||
Fixpoint rev (X:Type) (l:list X) : list X :=
|
||||
match l with
|
||||
| nil => nil X
|
||||
| cons h t => snoc X (rev X t) h
|
||||
end.
|
||||
|
||||
|
||||
Implicit Arguments nil [[X]].
|
||||
Implicit Arguments cons [[X]].
|
||||
Implicit Arguments length [[X]].
|
||||
Implicit Arguments app [[X]].
|
||||
Implicit Arguments rev [[X]].
|
||||
Implicit Arguments snoc [[X]].
|
||||
|
||||
Definition list123 := cons 1 (cons 2 (cons 3 (nil))).
|
||||
|
||||
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).
|
||||
|
||||
Fixpoint repeat (X : Type) (n : X) (count : nat) : list X :=
|
||||
match count with
|
||||
| O => nil
|
||||
| S count' => n :: (repeat _ n count')
|
||||
end.
|
||||
|
||||
Example test_repeat1:
|
||||
repeat bool true (S (S O)) = [true, true].
|
||||
Proof. reflexivity. Qed.
|
||||
|
||||
Theorem nil_app : forall X:Type, forall l:list X,
|
||||
app [] l = l.
|
||||
Proof.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem rev_snoc : forall X : Type,
|
||||
forall v : X,
|
||||
forall s : list X,
|
||||
rev (snoc s v) = v :: (rev s).
|
||||
Proof.
|
||||
intros X v s.
|
||||
induction s.
|
||||
reflexivity.
|
||||
simpl.
|
||||
rewrite -> IHs.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem snoc_with_append : forall X : Type,
|
||||
forall l1 l2 : list X,
|
||||
forall v : X,
|
||||
snoc (l1 ++ l2) v = l1 ++ (snoc l2 v).
|
||||
Proof.
|
||||
intros X l1 l2 v.
|
||||
induction l1.
|
||||
reflexivity.
|
||||
simpl.
|
||||
rewrite -> IHl1.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Inductive prod (X Y : Type) : Type :=
|
||||
pair : X -> Y -> prod X Y.
|
||||
|
||||
Implicit 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.
|
||||
|
||||
Implicit Arguments combine [X Y].
|
||||
|
||||
Fixpoint split {X Y: Type} (s : list (X * Y)) : (list X)*(list Y) :=
|
||||
match s with
|
||||
| nil => (nil, nil)
|
||||
| (x,y) :: tp => match split tp with
|
||||
| (lx, ly) => (x :: lx, y :: ly)
|
||||
end
|
||||
end.
|
||||
|
||||
Inductive option (X : Type) : Type :=
|
||||
| Some : X -> option X
|
||||
| None : option X.
|
||||
|
||||
Implicit Arguments Some [X].
|
||||
Implicit Arguments None [X].
|
||||
|
||||
Fixpoint index (X : Type) (n : nat)
|
||||
(l : list X) : option X :=
|
||||
match n with
|
||||
| O => match l with
|
||||
| nil => None
|
||||
| x :: xs => Some x
|
||||
end
|
||||
| S n' => match l with
|
||||
| nil => None
|
||||
| x :: xs => index X n' xs
|
||||
end
|
||||
end.
|
||||
|
||||
Definition hd_opt (X : Type) (l : list X) : option X :=
|
||||
match l with
|
||||
| nil => None
|
||||
| x :: xs => Some x
|
||||
end.
|
||||
|
||||
Implicit Arguments hd_opt [X].
|
||||
|
||||
Example test_hd_opt1 : hd_opt [S O, S (S O)] = Some (S O).
|
||||
Proof. reflexivity. Qed.
|
||||
Example test_hd_opt2 : hd_opt [[S O], [S (S O)]] = Some [S O].
|
||||
Proof. reflexivity. Qed.
|
||||
|
||||
Definition plus3 := plus (S (S (S O))).
|
||||
|
||||
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 :=
|
||||
f (fst X Y p) (snd X Y p).
|
||||
|
||||
Theorem uncurry_uncurry : forall (X Y Z : Type) (f : X -> Y -> Z) x y,
|
||||
prod_curry (prod_uncurry f) x y = f x y.
|
||||
Proof.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem curry_uncurry : forall (X Y Z : Type) (f : (X * Y) -> Z)
|
||||
(p : X * Y),
|
||||
prod_uncurry (prod_curry f) p = f p.
|
||||
Proof.
|
||||
destruct p.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
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 countoddmembers' (l:list nat) : nat :=
|
||||
length (filter _ oddb l).
|
||||
|
||||
Definition partition (X : Type) (test : X -> bool) (l : list X)
|
||||
: list X * list X :=
|
||||
(filter _ test l, filter _ (fun el => negb (test el)) l).
|
||||
|
||||
Example test_partition1: partition _ oddb [S O, S (S O), S (S (S O)), S (S (S (S O))), S (S (S (S (S O))))] = ([S O, S (S (S O)), S (S (S (S (S O))))], [S (S O), S (S (S (S O)))]).
|
||||
Proof. reflexivity. Qed.
|
||||
|
||||
Fixpoint map {X Y : Type} (f : X -> Y) (l : list X) : (list Y ) :=
|
||||
match l with
|
||||
| [] => []
|
||||
| h :: t => (f h) :: (map f t)
|
||||
end.
|
||||
|
||||
Example test_map1: map (plus (S (S (S O)))) [S (S O), O, S (S O)] = [S (S (S (S (S O)))), S (S (S O)), S (S (S (S (S O))))].
|
||||
Proof. reflexivity. Qed.
|
||||
|
||||
Theorem map_rev_1 : forall (X Y: Type) (f: X -> Y) (l : list X) (x : X),
|
||||
map f (snoc l x) = snoc (map f l) (f x).
|
||||
Proof.
|
||||
intros X Y f l x.
|
||||
induction l.
|
||||
reflexivity.
|
||||
simpl.
|
||||
rewrite -> IHl.
|
||||
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 l.
|
||||
induction l.
|
||||
reflexivity.
|
||||
simpl.
|
||||
rewrite <- IHl.
|
||||
rewrite -> map_rev_1.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Fixpoint flat_map {X Y : Type} (f : X -> list Y) (l : list X)
|
||||
: (list Y) :=
|
||||
match l with
|
||||
| [] => []
|
||||
| x :: xs => (f x) ++ (flat_map f xs)
|
||||
end.
|
||||
|
||||
Definition map_option {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.
|
||||
|
||||
Example fold_example : fold andb [true, true, false, true] true = false.
|
||||
Proof. reflexivity. Qed.
|
||||
|
||||
Definition constfun {X : Type} (x: X) : nat -> X :=
|
||||
fun (k:nat) => x.
|
||||
|
||||
Definition ftrue := constfun true.
|
||||
Example constfun_example : ftrue O = true.
|
||||
Proof. reflexivity. Qed.
|
||||
|
||||
Definition override {X : Type} (f: nat -> X) (k:nat) (x:X) : nat->X :=
|
||||
fun (k':nat) => if beq_nat k k' then x else f k'.
|
||||
|
||||
Definition fmostlytrue := override (override ftrue (S O) false) (S (S (S O))) false.
|
||||
|
||||
Example override_example1 : fmostlytrue O = true.
|
||||
Proof. reflexivity. Qed.
|
||||
Example override_example2 : fmostlytrue (S O) = false.
|
||||
Proof. reflexivity. Qed.
|
||||
Example override_example3 : fmostlytrue (S (S O)) = true.
|
||||
Proof. reflexivity. Qed.
|
||||
Example override_example4 : fmostlytrue (S (S (S O))) = false.
|
||||
Proof. reflexivity. Qed.
|
||||
|
||||
Theorem override_example : forall (b: bool),
|
||||
(override (constfun b) (S (S (S O))) true) (S (S O)) = b.
|
||||
Proof.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem unfold_example_bad : forall m n,
|
||||
(S (S (S O))) + n = m ->
|
||||
plus3 n = m.
|
||||
Proof.
|
||||
intros m n H.
|
||||
unfold plus3.
|
||||
rewrite -> H.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem override_eq : forall {X : Type} x k (f : nat -> X),
|
||||
(override f k x) k = x.
|
||||
Proof.
|
||||
intros X x k f.
|
||||
unfold override.
|
||||
rewrite <- beq_nat_refl.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem override_neq : forall {X : Type} x1 x2 k1 k2 (f : nat->X),
|
||||
f k1 = x1 ->
|
||||
beq_nat k2 k1 = false ->
|
||||
(override f k2 x2) k1 = x1.
|
||||
Proof.
|
||||
intros X x1 x2 k1 k2 f eq1 eq2.
|
||||
unfold override.
|
||||
rewrite -> eq2.
|
||||
rewrite -> eq1.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem eq_add_S : forall (n m : nat),
|
||||
S n = S m ->
|
||||
n = m.
|
||||
Proof.
|
||||
intros n m eq.
|
||||
inversion eq.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem silly4 : forall (n m : nat),
|
||||
[n] = [m] ->
|
||||
n = m.
|
||||
Proof.
|
||||
intros n o eq.
|
||||
inversion eq.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem silly5 : forall (n m o : nat),
|
||||
[n,m] = [o,o] ->
|
||||
[n] = [m].
|
||||
Proof.
|
||||
intros n m o eq.
|
||||
inversion eq.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem sillyex1 : forall (X : Type) (x y z : X) (l j : list X),
|
||||
x :: y :: l = z :: j ->
|
||||
y :: l = x :: j ->
|
||||
x = y.
|
||||
Proof.
|
||||
intros X x y z l j.
|
||||
intros eq1 eq2.
|
||||
inversion eq1.
|
||||
inversion eq2.
|
||||
symmetry.
|
||||
rewrite -> H0.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem silly6 : forall (n : nat),
|
||||
S n = O ->
|
||||
(S (S O)) + (S (S O)) = (S (S (S (S (S O))))).
|
||||
Proof.
|
||||
intros n contra.
|
||||
inversion contra.
|
||||
Qed.
|
||||
|
||||
Theorem silly7 : forall (n m : nat),
|
||||
false = true ->
|
||||
[n] = [m].
|
||||
Proof.
|
||||
intros n m contra.
|
||||
inversion contra.
|
||||
Qed.
|
||||
|
||||
Theorem sillyex2 : forall (X : Type) (x y z : X) (l j : list X),
|
||||
x :: y :: l = [] ->
|
||||
y :: l = z :: j ->
|
||||
x = z.
|
||||
Proof.
|
||||
intros X x y z l j contra.
|
||||
inversion contra.
|
||||
Qed.
|
||||
|
||||
Theorem beq_nat_eq : forall n m,
|
||||
true = beq_nat n m -> n = m.
|
||||
Proof.
|
||||
intros n. induction n as [| n'].
|
||||
Case "n = O".
|
||||
intros m. destruct m as [| m'].
|
||||
SCase "m = 0". reflexivity.
|
||||
SCase "m = S m'". simpl. intros contra. inversion contra.
|
||||
Case "n = S n'".
|
||||
intros m. destruct m as [| m'].
|
||||
SCase "m = 0". simpl. intros contra. inversion contra.
|
||||
SCase "m = S m'". simpl. intros H.
|
||||
assert(n' = m') as Hl.
|
||||
SSCase "Proof of assertion". apply IHn'. apply H.
|
||||
rewrite -> Hl. reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem beq_nat_eq' : forall m n,
|
||||
beq_nat n m = true -> n = m.
|
||||
Proof.
|
||||
intros m. induction m as [| m'].
|
||||
Case "m = O".
|
||||
destruct n.
|
||||
SCase "n = O".
|
||||
reflexivity.
|
||||
SCase "n = S n'".
|
||||
simpl. intros contra. inversion contra.
|
||||
Case "m = S m'".
|
||||
simpl.
|
||||
destruct n.
|
||||
SCase "n = O".
|
||||
simpl. intros contra. inversion contra.
|
||||
SCase "n = S n'".
|
||||
simpl. intros H.
|
||||
assert (n = m') as Hl.
|
||||
apply IHm'.
|
||||
apply H.
|
||||
rewrite -> Hl.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem length_snoc' : forall (X : Type) (v : X)
|
||||
(l : list X) (n : nat),
|
||||
length l = n ->
|
||||
length (snoc l v) = S n.
|
||||
Proof.
|
||||
intros X v l. induction l as [| v' l'].
|
||||
Case "l = []". intros n eq. rewrite <- eq. reflexivity.
|
||||
Case "l = v' :: l'". intros n eq. simpl. destruct n as [| n'].
|
||||
SCase "n = 0". inversion eq.
|
||||
SCase "n = S n'".
|
||||
assert (length (snoc l' v) = S n').
|
||||
SSCase "Proof of assertion". apply IHl'.
|
||||
inversion eq. reflexivity.
|
||||
rewrite -> H. reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem beq_nat_O_l : forall n,
|
||||
true = beq_nat O n -> O = n.
|
||||
Proof.
|
||||
intros n. destruct n.
|
||||
reflexivity.
|
||||
simpl.
|
||||
intros contra.
|
||||
inversion contra.
|
||||
Qed.
|
||||
|
||||
Theorem beq_nat_O_r : forall n,
|
||||
true = beq_nat n O -> O = n.
|
||||
Proof.
|
||||
intros n.
|
||||
induction n.
|
||||
Case "n = O".
|
||||
reflexivity.
|
||||
Case "n = S n'".
|
||||
simpl.
|
||||
intros contra.
|
||||
inversion contra.
|
||||
Qed.
|
||||
|
||||
Theorem double_injective : forall n m,
|
||||
double n = double m ->
|
||||
n = m.
|
||||
Proof.
|
||||
intros n. induction n as [| n'].
|
||||
Case "n = O".
|
||||
simpl. intros m eq.
|
||||
destruct m as [|m'].
|
||||
SCase "m = O". reflexivity.
|
||||
SCase "m = S m'". inversion eq.
|
||||
Case "n = S n'". intros m eq. destruct m as [| m'].
|
||||
SCase "m = O". inversion eq.
|
||||
SCase "m = S m'".
|
||||
assert(n' = m') as H.
|
||||
SSCase "Proof of assertion". apply IHn'. inversion eq. reflexivity.
|
||||
rewrite -> H. reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem silly3' : forall (n : nat),
|
||||
(beq_nat n (S (S (S (S (S O))))) = true ->
|
||||
beq_nat (S (S n)) (S (S (S (S (S (S (S O))))))) = true) ->
|
||||
true = beq_nat n (S (S (S (S (S O))))) ->
|
||||
true = beq_nat (S (S n)) (S (S (S (S (S (S (S O))))))).
|
||||
Proof.
|
||||
intros n eq H.
|
||||
symmetry in H.
|
||||
apply eq in H.
|
||||
symmetry in H.
|
||||
apply H.
|
||||
Qed.
|
||||
|
||||
Theorem plus_n_n_injective : forall n m,
|
||||
n + n = m + m ->
|
||||
n = m.
|
||||
Proof.
|
||||
intros n. induction n as [| n'].
|
||||
Case "n = O".
|
||||
simpl. intros m.
|
||||
destruct m.
|
||||
SCase "m = O".
|
||||
reflexivity.
|
||||
SCase "m = S m'".
|
||||
simpl.
|
||||
intros contra.
|
||||
inversion contra.
|
||||
Case "n = S n".
|
||||
intros m.
|
||||
destruct m.
|
||||
SCase "m = O".
|
||||
intros contra.
|
||||
inversion contra.
|
||||
SCase "m = S m'".
|
||||
intros eq.
|
||||
inversion eq.
|
||||
rewrite <- plus_n_Sm in H0.
|
||||
rewrite <- plus_n_Sm in H0.
|
||||
inversion H0.
|
||||
apply IHn' in H1.
|
||||
rewrite -> H1.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem override_shadow : forall {X : Type} x1 x2 k1 k2 (f : nat -> X),
|
||||
(override (override f k1 x2) k1 x1) k2 = (override f k1 x1) k2.
|
||||
Proof.
|
||||
intros X x1 x2 k1 k2 f.
|
||||
unfold override.
|
||||
destruct (beq_nat k1 k2).
|
||||
reflexivity.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem combine_split : forall (X : Type) (Y : Type) (l : list (X * Y)) (l1: list X) (l2: list Y),
|
||||
split l = (l1, l2) -> combine l1 l2 = l.
|
||||
Proof.
|
||||
intros X Y l.
|
||||
induction l as [| x y].
|
||||
Case "l = nil".
|
||||
intros l1 l2.
|
||||
intros eq.
|
||||
simpl.
|
||||
simpl in eq.
|
||||
inversion eq.
|
||||
reflexivity.
|
||||
Case "l = ::".
|
||||
intros l1 l2.
|
||||
simpl.
|
||||
destruct x.
|
||||
destruct (split y).
|
||||
simpl.
|
||||
destruct l1.
|
||||
SCase "l1 = []".
|
||||
simpl.
|
||||
induction l2.
|
||||
SSCase "l2 = []".
|
||||
intros contra.
|
||||
inversion contra.
|
||||
SSCase "l2 = ::".
|
||||
intros contra.
|
||||
inversion contra.
|
||||
SCase "l1 = ::".
|
||||
induction l2.
|
||||
SSCase "l2 = []".
|
||||
simpl.
|
||||
intros contra.
|
||||
inversion contra.
|
||||
SSCase "l2 = ::".
|
||||
simpl.
|
||||
intros eq.
|
||||
inversion eq.
|
||||
simpl.
|
||||
rewrite IHy.
|
||||
reflexivity.
|
||||
simpl.
|
||||
rewrite H1.
|
||||
rewrite H3.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem split_combine : forall (X : Type) (Y : Type) (l1: list X) (l2: list Y),
|
||||
length l1 = length l2 -> split (combine l1 l2) = (l1, l2).
|
||||
Proof.
|
||||
intros X Y.
|
||||
intros l1.
|
||||
induction l1.
|
||||
simpl.
|
||||
intros l2.
|
||||
induction l2.
|
||||
reflexivity.
|
||||
|
||||
intros contra.
|
||||
inversion contra.
|
||||
|
||||
destruct l2.
|
||||
simpl.
|
||||
intros contra.
|
||||
inversion contra.
|
||||
|
||||
simpl.
|
||||
intros eq.
|
||||
inversion eq.
|
||||
apply IHl1 in H0.
|
||||
rewrite H0.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Definition sillyfun1 (n : nat) : bool :=
|
||||
if beq_nat n (S (S (S O))) then true
|
||||
else if beq_nat n (S (S (S (S (S O))))) then true
|
||||
else false.
|
||||
|
||||
Theorem beq_equal : forall (a b : nat),
|
||||
beq_nat a b = true ->
|
||||
a = b.
|
||||
Proof.
|
||||
intros a.
|
||||
induction a.
|
||||
destruct b.
|
||||
reflexivity.
|
||||
|
||||
intros contra.
|
||||
inversion contra.
|
||||
|
||||
destruct b.
|
||||
intros contra.
|
||||
inversion contra.
|
||||
|
||||
simpl.
|
||||
intros eq.
|
||||
apply IHa in eq.
|
||||
rewrite eq.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem override_same : forall {X : Type} x1 k1 k2 (f : nat->X),
|
||||
f k1 = x1 ->
|
||||
(override f k1 x1) k2 = f k2.
|
||||
Proof.
|
||||
intros X x1 k1 k2 f eq.
|
||||
unfold override.
|
||||
remember (beq_nat k1 k2) as a.
|
||||
destruct a.
|
||||
rewrite <- eq.
|
||||
symmetry in Heqa.
|
||||
apply beq_equal in Heqa.
|
||||
rewrite -> Heqa.
|
||||
reflexivity.
|
||||
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.
|
||||
intros test.
|
||||
intros x.
|
||||
induction l.
|
||||
simpl.
|
||||
intros lf.
|
||||
intros contra.
|
||||
inversion contra.
|
||||
|
||||
simpl.
|
||||
remember (test x0) as a.
|
||||
destruct a.
|
||||
simpl.
|
||||
intros lf.
|
||||
intros eq.
|
||||
rewrite Heqa.
|
||||
inversion eq.
|
||||
reflexivity.
|
||||
|
||||
intros lf.
|
||||
intros eq.
|
||||
apply IHl in eq.
|
||||
rewrite eq.
|
||||
reflexivity.
|
||||
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_example' : forall (a b c d e f : nat),
|
||||
[a,b] = [c,d] ->
|
||||
[c,d] = [e,f] ->
|
||||
[a,b] = [e,f].
|
||||
Proof.
|
||||
intros a b c d e f eq1 eq2.
|
||||
apply trans_eq with (m := [c,d]). apply eq1. apply eq2.
|
||||
Qed.
|
||||
|
||||
Theorem trans_eq_exercise : forall (n m o p : nat),
|
||||
m = (minustwo o) ->
|
||||
(n + p) = m ->
|
||||
(n + p) = (minustwo o).
|
||||
Proof.
|
||||
intros n m o p.
|
||||
intros eq1 eq2.
|
||||
rewrite eq2.
|
||||
rewrite <- eq1.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem beq_nat_trans : forall n m p,
|
||||
true = beq_nat n m ->
|
||||
true = beq_nat m p ->
|
||||
true = beq_nat n p.
|
||||
Proof.
|
||||
intros n m p.
|
||||
intros eq1 eq2.
|
||||
symmetry in eq1.
|
||||
symmetry in eq2.
|
||||
apply beq_equal in eq1.
|
||||
apply beq_equal in eq2.
|
||||
rewrite eq1.
|
||||
rewrite <- eq2.
|
||||
apply beq_nat_refl.
|
||||
Qed.
|
||||
|
||||
Theorem override_permute : forall {X:Type} x1 x2 k1 k2 k3 (f : nat->X),
|
||||
false = beq_nat k2 k1 ->
|
||||
(override (override f k2 x2) k1 x1) k3 = (override (override f k1 x1) k2 x2) k3.
|
||||
Proof.
|
||||
intros X x1 x2 k1 k2 k3 f.
|
||||
simpl.
|
||||
unfold override.
|
||||
remember (beq_nat k1 k3).
|
||||
remember (beq_nat k2 k3).
|
||||
destruct b.
|
||||
destruct b0.
|
||||
symmetry in Heqb.
|
||||
symmetry in Heqb0.
|
||||
apply beq_equal in Heqb.
|
||||
apply beq_equal in Heqb0.
|
||||
rewrite <- Heqb in Heqb0.
|
||||
assert (k2 = k1 -> true = beq_nat k2 k1).
|
||||
destruct k2.
|
||||
destruct k1.
|
||||
reflexivity.
|
||||
|
||||
intros contra.
|
||||
inversion contra.
|
||||
|
||||
destruct k1.
|
||||
intros contra.
|
||||
inversion contra.
|
||||
|
||||
simpl.
|
||||
intros eq.
|
||||
inversion eq.
|
||||
symmetry .
|
||||
symmetry .
|
||||
apply beq_nat_refl.
|
||||
|
||||
apply H in Heqb0.
|
||||
rewrite <- Heqb0.
|
||||
intros contra.
|
||||
inversion contra.
|
||||
|
||||
intros eq.
|
||||
reflexivity.
|
||||
|
||||
destruct b0.
|
||||
intros eq.
|
||||
reflexivity.
|
||||
|
||||
intros eq.
|
||||
reflexivity.
|
||||
|
||||
Qed.
|
||||
|
||||
Definition fold_length {X : Type} (l : list X) : nat :=
|
||||
fold (fun _ n => S n) l O.
|
||||
|
||||
Example test_fold_length1 : fold_length [S (S (S (S O))), S (S (S (S (S (S (S O)))))), O] = S (S (S O)).
|
||||
Proof. reflexivity. Qed.
|
||||
|
||||
Theorem fold_length_correct : forall X (l :list X),
|
||||
fold_length l = length l.
|
||||
Proof.
|
||||
intros X l.
|
||||
unfold fold_length.
|
||||
induction l.
|
||||
Case "l = O".
|
||||
reflexivity.
|
||||
Case "l = ::".
|
||||
simpl.
|
||||
rewrite IHl.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Definition fold_map {X Y: Type} (f : X -> Y) (l : list X) : list Y :=
|
||||
fold (fun x total => (f x) :: total) l [].
|
||||
|
||||
Theorem fold_map_correct : forall (X Y: Type) (f : X -> Y) (l : list X),
|
||||
fold_map f l = map f l.
|
||||
Proof.
|
||||
intros X Y f l.
|
||||
unfold fold_map.
|
||||
induction l.
|
||||
reflexivity.
|
||||
|
||||
simpl.
|
||||
rewrite IHl.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Fixpoint forallb {X : Type} (f : X -> bool) (l : list X) :=
|
||||
match l with
|
||||
| nil => true
|
||||
| x :: xs => andb (f x) (forallb f xs)
|
||||
end.
|
||||
|
||||
Fixpoint existsb {X : Type} (f : X -> bool) (l : list X) :=
|
||||
match l with
|
||||
| nil => false
|
||||
| x :: xs => orb (f x) (existsb f xs)
|
||||
end.
|
||||
|
||||
Definition existsb2 {X : Type} (f: X -> bool) (l : list X) :=
|
||||
negb (forallb (fun x => negb (f x)) l).
|
||||
|
||||
Theorem existsb_correct : forall (X : Type) (f : X -> bool) (l : list X),
|
||||
existsb f l = existsb2 f l.
|
||||
Proof.
|
||||
intros X f l.
|
||||
induction l.
|
||||
reflexivity.
|
||||
|
||||
simpl.
|
||||
rewrite IHl.
|
||||
unfold existsb2.
|
||||
simpl.
|
||||
destruct (forallb (fun x0 : X => negb (f x0)) l).
|
||||
simpl.
|
||||
destruct (f x).
|
||||
reflexivity.
|
||||
|
||||
reflexivity.
|
||||
|
||||
destruct (f x).
|
||||
reflexivity.
|
||||
|
||||
reflexivity.
|
||||
|
||||
Qed.
|
||||
|
||||
Theorem index_okx : forall (X:Type) (l : list X) (n : nat),
|
||||
length l = n -> index X (S n) l = None.
|
||||
Proof.
|
||||
intros X l.
|
||||
induction l.
|
||||
reflexivity.
|
||||
|
||||
intros n.
|
||||
destruct n.
|
||||
intros contra.
|
||||
inversion contra.
|
||||
|
||||
intros eq.
|
||||
inversion eq.
|
||||
apply IHl.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Inductive mumble : Type :=
|
||||
| a : mumble
|
||||
| b : mumble -> nat -> mumble
|
||||
| c : mumble.
|
||||
Inductive grumble (X:Type) : Type :=
|
||||
| d : mumble -> grumble X
|
||||
| e : X -> grumble X.
|
||||
|
||||
312
samples/coq/Rel.v
Executable file
312
samples/coq/Rel.v
Executable file
@@ -0,0 +1,312 @@
|
||||
Require Export Logic.
|
||||
Import Playground1.
|
||||
|
||||
Definition relation (X:Type) := X -> X -> Prop.
|
||||
|
||||
Definition partial_function {X:Type} (R: relation X) :=
|
||||
forall x y1 y2 : X, R x y1 -> R x y2 -> y1 = y2.
|
||||
|
||||
Theorem next_nat_partial_function :
|
||||
partial_function next_nat.
|
||||
Proof.
|
||||
unfold partial_function.
|
||||
intros x y1 y2 P Q.
|
||||
inversion P.
|
||||
inversion Q.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Theorem le_not_a_partial_function :
|
||||
~ (partial_function le).
|
||||
Proof.
|
||||
unfold not.
|
||||
unfold partial_function.
|
||||
intros H.
|
||||
assert (O = S O) as Nonsense.
|
||||
Case "Proof of assertion.".
|
||||
apply H with O.
|
||||
apply le_n.
|
||||
|
||||
apply le_S.
|
||||
apply le_n.
|
||||
|
||||
inversion Nonsense.
|
||||
Qed.
|
||||
|
||||
Theorem total_relation_not_partial_function :
|
||||
~ (partial_function total_relation).
|
||||
Proof.
|
||||
unfold not.
|
||||
unfold partial_function.
|
||||
intros H.
|
||||
assert (O = S O) as Nonsense.
|
||||
apply H with O.
|
||||
apply total_relation1.
|
||||
|
||||
apply total_relation1.
|
||||
|
||||
inversion Nonsense.
|
||||
Qed.
|
||||
|
||||
Theorem empty_relation_not_partial_funcion :
|
||||
partial_function empty_relation.
|
||||
Proof.
|
||||
unfold partial_function.
|
||||
intros x y1 y2.
|
||||
intros H.
|
||||
inversion H.
|
||||
Qed.
|
||||
|
||||
Definition reflexive {X:Type} (R: relation X) :=
|
||||
forall a : X, R a a.
|
||||
|
||||
Theorem le_reflexive :
|
||||
reflexive le.
|
||||
Proof.
|
||||
unfold reflexive.
|
||||
intros n. apply le_n.
|
||||
Qed.
|
||||
|
||||
Definition transitive {X:Type} (R: relation X) :=
|
||||
forall a b c : X, (R a b) -> (R b c) -> (R a c).
|
||||
|
||||
Theorem le_trans:
|
||||
transitive le.
|
||||
Proof.
|
||||
intros n m o Hnm Hmo.
|
||||
induction Hmo.
|
||||
Case "le_n". apply Hnm.
|
||||
Case "le_S". apply le_S. apply IHHmo.
|
||||
Qed.
|
||||
|
||||
Theorem lt_trans:
|
||||
transitive lt.
|
||||
Proof.
|
||||
unfold lt. unfold transitive.
|
||||
intros n m o Hnm Hmo.
|
||||
apply le_S in Hnm.
|
||||
apply le_trans with (a := (S n)) (b := (S m)) (c := o).
|
||||
apply Hnm.
|
||||
apply Hmo.
|
||||
Qed.
|
||||
|
||||
Theorem lt_trans' :
|
||||
transitive lt.
|
||||
Proof.
|
||||
unfold lt. unfold transitive.
|
||||
intros n m o Hnm Hmo.
|
||||
induction Hmo as [| m' Hm'o].
|
||||
apply le_S.
|
||||
apply Hnm.
|
||||
|
||||
apply le_S.
|
||||
apply IHHm'o.
|
||||
Qed.
|
||||
|
||||
Theorem le_Sn_le: forall n m, S n <= m -> n <= m.
|
||||
Proof.
|
||||
intros n m H. apply le_trans with (S n).
|
||||
apply le_S. apply le_n.
|
||||
apply H. Qed.
|
||||
|
||||
Theorem le_S_n : forall n m,
|
||||
(S n <= S m) -> (n <= m).
|
||||
Proof.
|
||||
intros n m H.
|
||||
apply Sn_le_Sm__n_le_m.
|
||||
apply H.
|
||||
Qed.
|
||||
|
||||
Theorem le_Sn_n : forall n,
|
||||
~ (S n <= n).
|
||||
Proof.
|
||||
induction n.
|
||||
intros H.
|
||||
inversion H.
|
||||
|
||||
unfold not in IHn.
|
||||
intros H.
|
||||
apply le_S_n in H.
|
||||
apply IHn.
|
||||
apply H.
|
||||
Qed.
|
||||
|
||||
(*
|
||||
TODO
|
||||
Theorem lt_trans'' :
|
||||
transitive lt.
|
||||
Proof.
|
||||
unfold lt. unfold transitive.
|
||||
intros n m o Hnm Hmo.
|
||||
induction o as [| o'].
|
||||
*)
|
||||
|
||||
Definition symmetric {X: Type} (R: relation X) :=
|
||||
forall a b : X, (R a b) -> (R b a).
|
||||
|
||||
Definition antisymmetric {X : Type} (R: relation X) :=
|
||||
forall a b : X, (R a b) -> (R b a) -> a = b.
|
||||
|
||||
Theorem le_antisymmetric :
|
||||
antisymmetric le.
|
||||
Proof.
|
||||
intros a b.
|
||||
generalize dependent a.
|
||||
induction b.
|
||||
intros a.
|
||||
intros H.
|
||||
intros H1.
|
||||
inversion H.
|
||||
reflexivity.
|
||||
|
||||
intros a H1 H2.
|
||||
destruct a.
|
||||
inversion H2.
|
||||
|
||||
apply Sn_le_Sm__n_le_m in H1.
|
||||
apply Sn_le_Sm__n_le_m in H2.
|
||||
apply IHb in H1.
|
||||
rewrite H1 in |- *.
|
||||
reflexivity.
|
||||
|
||||
apply H2.
|
||||
Qed.
|
||||
|
||||
(*
|
||||
TODO
|
||||
Theorem le_step : forall n m p,
|
||||
n < m ->
|
||||
n <= S p ->
|
||||
n <= p.
|
||||
Proof.
|
||||
*)
|
||||
|
||||
Definition equivalence {X:Type} (R: relation X) :=
|
||||
(reflexive R) /\ (symmetric R) /\ (transitive R).
|
||||
|
||||
Definition order {X:Type} (R: relation X) :=
|
||||
(reflexive R) /\ (antisymmetric R) /\ (transitive R).
|
||||
|
||||
Definition preorder {X:Type} (R: relation X) :=
|
||||
(reflexive R) /\ (transitive R).
|
||||
|
||||
Theorem le_order :
|
||||
order le.
|
||||
Proof.
|
||||
unfold order. split.
|
||||
Case "refl". apply le_reflexive.
|
||||
split.
|
||||
Case "antisym". apply le_antisymmetric.
|
||||
Case "transitive". apply le_trans. Qed.
|
||||
|
||||
Inductive clos_refl_trans {A:Type} (R: relation A) : relation A :=
|
||||
| rt_step : forall x y, R x y -> clos_refl_trans R x y
|
||||
| rt_refl : forall x, clos_refl_trans R x x
|
||||
| rt_trans : forall x y z,
|
||||
clos_refl_trans R x y -> clos_refl_trans R y z -> clos_refl_trans R x z.
|
||||
|
||||
Theorem next_nat_closure_is_le : forall n m,
|
||||
(n <= m) <-> ((clos_refl_trans next_nat) n m).
|
||||
Proof.
|
||||
intros n m.
|
||||
split.
|
||||
intro H.
|
||||
induction H.
|
||||
apply rt_refl.
|
||||
|
||||
apply rt_trans with m.
|
||||
apply IHle.
|
||||
|
||||
apply rt_step.
|
||||
apply nn.
|
||||
|
||||
intro H.
|
||||
induction H.
|
||||
inversion H.
|
||||
apply le_S.
|
||||
apply le_n.
|
||||
|
||||
apply le_n.
|
||||
|
||||
apply le_trans with y.
|
||||
apply IHclos_refl_trans1.
|
||||
|
||||
apply IHclos_refl_trans2.
|
||||
Qed.
|
||||
|
||||
Inductive refl_step_closure {X : Type} (R: relation X)
|
||||
: X -> X -> Prop :=
|
||||
| rsc_refl : forall (x : X), refl_step_closure R x x
|
||||
| rsc_step : forall (x y z : X), R x y ->
|
||||
refl_step_closure R y z ->
|
||||
refl_step_closure R x z.
|
||||
|
||||
Tactic Notation "rt_cases" tactic(first) ident(c) :=
|
||||
first;
|
||||
[ Case_aux c "rt_step" | Case_aux c "rt_refl" | Case_aux c "rt_trans" ].
|
||||
|
||||
Tactic Notation "rsc_cases" tactic(first) ident(c) :=
|
||||
first;
|
||||
[ Case_aux c "rsc_refl" | Case_aux c "rsc_step" ].
|
||||
|
||||
Theorem rsc_R : forall (X:Type) (R:relation X) (x y:X),
|
||||
R x y -> refl_step_closure R x y.
|
||||
Proof.
|
||||
intros X R x y r.
|
||||
apply rsc_step with y.
|
||||
apply r.
|
||||
|
||||
apply rsc_refl.
|
||||
Qed.
|
||||
|
||||
Theorem rsc_trans :
|
||||
forall (X : Type) (R : relation X) (x y z : X),
|
||||
refl_step_closure R x y ->
|
||||
refl_step_closure R y z ->
|
||||
refl_step_closure R x z.
|
||||
Proof.
|
||||
intros X.
|
||||
intros R x y z.
|
||||
intros H.
|
||||
induction H.
|
||||
intros H1.
|
||||
apply H1.
|
||||
|
||||
intros H1.
|
||||
apply IHrefl_step_closure in H1.
|
||||
apply rsc_step with y.
|
||||
apply H.
|
||||
|
||||
apply H1.
|
||||
Qed.
|
||||
|
||||
Theorem rtc_rsc_coincide:
|
||||
forall (X:Type) (R: relation X) (x y : X),
|
||||
clos_refl_trans R x y <-> refl_step_closure R x y.
|
||||
Proof.
|
||||
intros X R x y.
|
||||
split.
|
||||
intros H.
|
||||
induction H.
|
||||
apply rsc_step with y.
|
||||
apply H.
|
||||
|
||||
apply rsc_refl.
|
||||
|
||||
apply rsc_refl.
|
||||
|
||||
apply rsc_trans with y.
|
||||
apply IHclos_refl_trans1.
|
||||
|
||||
apply IHclos_refl_trans2.
|
||||
|
||||
intros H1.
|
||||
induction H1.
|
||||
apply rt_refl.
|
||||
|
||||
apply rt_trans with y.
|
||||
apply rt_step.
|
||||
apply H.
|
||||
|
||||
apply IHrefl_step_closure.
|
||||
Qed.
|
||||
701
samples/coq/Smallstep.v
Executable file
701
samples/coq/Smallstep.v
Executable file
@@ -0,0 +1,701 @@
|
||||
Require Export Imp.
|
||||
Require Export Relations.
|
||||
|
||||
Inductive tm : Type :=
|
||||
| tm_const : nat -> tm
|
||||
| tm_plus : tm -> tm -> tm.
|
||||
|
||||
Tactic Notation "tm_cases" tactic(first) ident(c) :=
|
||||
first;
|
||||
[ Case_aux c "tm_const" | Case_aux c "tm_plus" ].
|
||||
|
||||
Module SimpleArith0.
|
||||
|
||||
Fixpoint eval (t : tm) : nat :=
|
||||
match t with
|
||||
| tm_const n => n
|
||||
| tm_plus a1 a2 => eval a1 + eval a2
|
||||
end.
|
||||
|
||||
End SimpleArith0.
|
||||
|
||||
Module SimpleArith1.
|
||||
|
||||
Reserved Notation " t '===>' n " (at level 50, left associativity).
|
||||
|
||||
Inductive eval : tm -> nat -> Prop :=
|
||||
| E_Const : forall n,
|
||||
tm_const n ===> n
|
||||
| E_Plus : forall t1 t2 n1 n2,
|
||||
t1 ===> n1 ->
|
||||
t2 ===> n2 ->
|
||||
tm_plus t1 t2 ===> plus n1 n2
|
||||
|
||||
where " t '===>' n " := (eval t n).
|
||||
|
||||
End SimpleArith1.
|
||||
|
||||
Reserved Notation " t '===>' t' " (at level 50, left associativity).
|
||||
|
||||
Inductive eval : tm -> tm -> Prop :=
|
||||
| E_Const : forall n1,
|
||||
tm_const n1 ===> tm_const n1
|
||||
| E_Plus : forall t1 n1 t2 n2,
|
||||
t1 ===> tm_const n1 ->
|
||||
t2 ===> tm_const n2 ->
|
||||
tm_plus t1 t2 ===> tm_const (plus n1 n2)
|
||||
where " t '===>' t' " := (eval t t').
|
||||
|
||||
Tactic Notation "eval_cases" tactic(first) ident(c) :=
|
||||
first;
|
||||
[ Case_aux c "E_Const" | Case_aux c "E_Plus" ].
|
||||
|
||||
Module SimpleArith2.
|
||||
|
||||
Reserved Notation " t '=>' t' " (at level 40).
|
||||
|
||||
Inductive step : tm -> tm -> Prop :=
|
||||
| ST_PlusConstConst : forall n1 n2,
|
||||
tm_plus (tm_const n1) (tm_const n2) => tm_const (plus n1 n2)
|
||||
| ST_Plus1 : forall t1 t1' t2,
|
||||
t1 => t1' ->
|
||||
tm_plus t1 t2 => tm_plus t1' t2
|
||||
| ST_Plus2 : forall n1 t2 t2',
|
||||
t2 => t2' ->
|
||||
tm_plus (tm_const n1) t2 => tm_plus (tm_const n1) t2'
|
||||
|
||||
where " t '=>' t' " := (step t t').
|
||||
|
||||
Tactic Notation "step_cases" tactic(first) ident(c) :=
|
||||
first;
|
||||
[ Case_aux c "ST_PlusConstConst"
|
||||
| Case_aux c "ST_Plus1" | Case_aux c "ST_Plus2" ].
|
||||
|
||||
Example test_step_1 :
|
||||
tm_plus
|
||||
(tm_plus (tm_const 0) (tm_const 3))
|
||||
(tm_plus (tm_const 2) (tm_const 4))
|
||||
=>
|
||||
tm_plus
|
||||
(tm_const (plus 0 3))
|
||||
(tm_plus (tm_const 2) (tm_const 4)).
|
||||
Proof.
|
||||
apply ST_Plus1. apply ST_PlusConstConst. Qed.
|
||||
|
||||
Example test_step_2 :
|
||||
tm_plus
|
||||
(tm_const 0)
|
||||
(tm_plus
|
||||
(tm_const 2)
|
||||
(tm_plus (tm_const 0) (tm_const 3)))
|
||||
=>
|
||||
tm_plus
|
||||
(tm_const 0)
|
||||
(tm_plus
|
||||
(tm_const 2)
|
||||
(tm_const (plus 0 3))).
|
||||
Proof.
|
||||
apply ST_Plus2.
|
||||
simpl.
|
||||
apply ST_Plus2.
|
||||
apply ST_PlusConstConst.
|
||||
Qed.
|
||||
|
||||
Theorem step_deterministic:
|
||||
partial_function step.
|
||||
Proof.
|
||||
unfold partial_function. intros x y1 y2 Hy1 Hy2.
|
||||
generalize dependent y2.
|
||||
step_cases (induction Hy1) Case; intros y2 Hy2.
|
||||
Case "ST_PlusConstConst". step_cases (inversion Hy2) SCase.
|
||||
SCase "ST_PlusConstConst". reflexivity.
|
||||
SCase "ST_Plus1". inversion H2.
|
||||
SCase "ST_Plus2". inversion H2.
|
||||
Case "ST_Plus1". step_cases (inversion Hy2) SCase.
|
||||
SCase "ST_PlusConstConst". rewrite <- H0 in Hy1. inversion Hy1.
|
||||
SCase "ST_Plus1".
|
||||
rewrite <- (IHHy1 t1'0).
|
||||
reflexivity. assumption.
|
||||
SCase "ST_Plus2". rewrite <- H in Hy1. inversion Hy1.
|
||||
Case "ST_Plus2". step_cases (inversion Hy2) SCase.
|
||||
SCase "ST_PlusConstConst". rewrite <- H1 in Hy1. inversion Hy1.
|
||||
SCase "ST_Plus1". inversion H2.
|
||||
SCase "ST_Plus2".
|
||||
rewrite <- (IHHy1 t2'0).
|
||||
reflexivity. assumption. Qed.
|
||||
|
||||
End SimpleArith2.
|
||||
|
||||
Inductive value : tm -> Prop :=
|
||||
v_const: forall n, value (tm_const n).
|
||||
|
||||
Reserved Notation " t '=>' t' " (at level 40).
|
||||
|
||||
Inductive step : tm -> tm -> Prop :=
|
||||
| ST_PlusConstConst : forall n1 n2,
|
||||
tm_plus (tm_const n1) (tm_const n2)
|
||||
=> tm_const (plus n1 n2)
|
||||
| ST_Plus1 : forall t1 t1' t2,
|
||||
t1 => t1' ->
|
||||
tm_plus t1 t2 => tm_plus t1' t2
|
||||
| ST_Plus2 : forall v1 t2 t2',
|
||||
value v1 ->
|
||||
t2 => t2' ->
|
||||
tm_plus v1 t2 => tm_plus v1 t2'
|
||||
|
||||
where " t '=>' t' " := (step t t').
|
||||
|
||||
Tactic Notation "step_cases" tactic(first) ident(c) :=
|
||||
first;
|
||||
[ Case_aux c "ST_PlusConstConst"
|
||||
| Case_aux c "ST_Plus1" | Case_aux c "ST_Plus2" ].
|
||||
|
||||
Theorem step_deterministic :
|
||||
partial_function step.
|
||||
Proof.
|
||||
unfold partial_function.
|
||||
intros x y1 y2 Hy1 Hy2.
|
||||
generalize dependent y2.
|
||||
step_cases (induction Hy1) Case; intros y2 Hy2.
|
||||
step_cases (inversion Hy2) SCase.
|
||||
reflexivity.
|
||||
|
||||
inversion H2.
|
||||
|
||||
inversion Hy2.
|
||||
subst.
|
||||
assumption.
|
||||
|
||||
subst.
|
||||
inversion H3.
|
||||
|
||||
subst.
|
||||
inversion H3.
|
||||
|
||||
step_cases (inversion Hy2) SCase.
|
||||
rewrite <- H0 in Hy1.
|
||||
inversion Hy1.
|
||||
|
||||
rewrite <- (IHHy1 t1'0).
|
||||
reflexivity.
|
||||
|
||||
assumption.
|
||||
|
||||
rewrite <- H in Hy1.
|
||||
rewrite <- H in H1.
|
||||
subst.
|
||||
inversion H1.
|
||||
subst.
|
||||
inversion Hy1.
|
||||
|
||||
step_cases (inversion Hy2) SCase.
|
||||
subst.
|
||||
inversion Hy1.
|
||||
|
||||
subst.
|
||||
inversion H.
|
||||
subst.
|
||||
inversion H3.
|
||||
|
||||
subst.
|
||||
inversion H2.
|
||||
subst.
|
||||
rewrite <- (IHHy1 t2'0).
|
||||
reflexivity.
|
||||
|
||||
assumption.
|
||||
Qed.
|
||||
|
||||
Theorem strong_progress : forall t,
|
||||
value t \/ (exists t', t => t').
|
||||
Proof.
|
||||
tm_cases (induction t) Case.
|
||||
Case "tm_const". left. apply v_const.
|
||||
Case "tm_plus". right. inversion IHt1.
|
||||
SCase "l". inversion IHt2.
|
||||
SSCase "l". inversion H. inversion H0.
|
||||
exists (tm_const (plus n n0)).
|
||||
apply ST_PlusConstConst.
|
||||
SSCase "r". inversion H0 as [t' H1].
|
||||
exists (tm_plus t1 t').
|
||||
apply ST_Plus2. apply H. apply H1.
|
||||
SCase "r". inversion H as [t' H0].
|
||||
exists (tm_plus t' t2).
|
||||
apply ST_Plus1. apply H0. Qed.
|
||||
|
||||
Definition normal_form {X:Type} (R: relation X) (t: X) : Prop :=
|
||||
~ (exists t', R t t').
|
||||
|
||||
Lemma value_is_nf: forall t,
|
||||
value t -> normal_form step t.
|
||||
Proof.
|
||||
unfold normal_form. intros t H. inversion H.
|
||||
intros contra. inversion contra. inversion H1.
|
||||
Qed.
|
||||
|
||||
Lemma nf_is_value: forall t,
|
||||
normal_form step t -> value t.
|
||||
Proof.
|
||||
unfold normal_form. intros t H.
|
||||
assert (G: value t \/ (exists t', t => t')).
|
||||
SCase "Proof of assertion". apply strong_progress.
|
||||
inversion G.
|
||||
SCase "l". assumption.
|
||||
SCase "r". apply ex_falso_quodlibet. apply H. assumption. Qed.
|
||||
|
||||
Corollary nf_same_as_value : forall t,
|
||||
normal_form step t <-> value t.
|
||||
Proof.
|
||||
split. apply nf_is_value. apply value_is_nf.
|
||||
Qed.
|
||||
|
||||
Module Temp1.
|
||||
|
||||
Inductive value : tm -> Prop :=
|
||||
| v_const : forall n, value (tm_const n)
|
||||
| v_funny : forall t1 n2, (* <---- *)
|
||||
value (tm_plus t1 (tm_const n2)).
|
||||
|
||||
Reserved Notation " t '=>' t' " (at level 40).
|
||||
|
||||
Inductive step : tm -> tm -> Prop :=
|
||||
| ST_PlusConstConst : forall n1 n2,
|
||||
tm_plus (tm_const n1) (tm_const n2) => tm_const (plus n1 n2)
|
||||
| ST_Plus1 : forall t1 t1' t2,
|
||||
t1 => t1' ->
|
||||
tm_plus t1 t2 => tm_plus t1' t2
|
||||
| ST_Plus2 : forall v1 t2 t2',
|
||||
value v1 ->
|
||||
t2 => t2' ->
|
||||
tm_plus v1 t2 => tm_plus v1 t2'
|
||||
|
||||
where " t '=>' t' " := (step t t').
|
||||
|
||||
Lemma value_not_same_as_normal_form:
|
||||
exists t, value t /\ ~ normal_form step t.
|
||||
Proof.
|
||||
intros.
|
||||
unfold normal_form.
|
||||
exists (tm_plus (tm_plus (tm_const 1) (tm_const 2)) (tm_const 2)).
|
||||
split.
|
||||
apply v_funny.
|
||||
|
||||
unfold not.
|
||||
intros.
|
||||
apply H.
|
||||
exists (tm_plus (tm_const (1 + 2)) (tm_const 2)).
|
||||
apply ST_Plus1.
|
||||
apply ST_PlusConstConst.
|
||||
Qed.
|
||||
|
||||
End Temp1.
|
||||
|
||||
Module Temp2.
|
||||
|
||||
Inductive value : tm -> Prop :=
|
||||
| v_const : forall n, value (tm_const n).
|
||||
|
||||
(*Reserved Notation " t '===>' t' " (at level 40).*)
|
||||
|
||||
Inductive step : tm -> tm -> Prop :=
|
||||
| ST_Funny : forall n, (* <---- *)
|
||||
tm_const n ===> tm_plus (tm_const n) (tm_const 0)
|
||||
| ST_PlusConstConst : forall n1 n2,
|
||||
tm_plus (tm_const n1) (tm_const n2) ===> tm_const (plus n1 n2)
|
||||
| ST_Plus1 : forall t1 t1' t2,
|
||||
t1 ===> t1' ->
|
||||
tm_plus t1 t2 ===> tm_plus t1' t2
|
||||
| ST_Plus2 : forall v1 t2 t2',
|
||||
value v1 ->
|
||||
t2 ===> t2' ->
|
||||
tm_plus v1 t2 ===> tm_plus v1 t2'
|
||||
|
||||
where " t '===>' t' " := (step t t').
|
||||
|
||||
Lemma value_not_same_as_normal_form :
|
||||
exists t, value t /\ ~ normal_form step t.
|
||||
Proof.
|
||||
exists (tm_const 0).
|
||||
split.
|
||||
apply v_const.
|
||||
|
||||
unfold normal_form.
|
||||
unfold not.
|
||||
intro H.
|
||||
apply H.
|
||||
exists (tm_plus (tm_const 0) (tm_const 0)).
|
||||
apply ST_Funny.
|
||||
Qed.
|
||||
|
||||
End Temp2.
|
||||
|
||||
Module Temp3.
|
||||
|
||||
Inductive value : tm -> Prop :=
|
||||
| v_const : forall n, value (tm_const n).
|
||||
|
||||
(*Reserved Notation " t '===>' t' " (at level 40).*)
|
||||
|
||||
Inductive step : tm -> tm -> Prop :=
|
||||
| ST_PlusConstConst : forall n1 n2,
|
||||
tm_plus (tm_const n1) (tm_const n2) ===> tm_const (plus n1 n2)
|
||||
| ST_Plus1 : forall t1 t1' t2,
|
||||
t1 ===> t1' ->
|
||||
tm_plus t1 t2 ===> tm_plus t1' t2
|
||||
|
||||
where " t '===>' t' " := (step t t').
|
||||
|
||||
Lemma value_not_same_as_normal_form:
|
||||
exists t, ~ value t /\ normal_form step t.
|
||||
Proof.
|
||||
exists (tm_plus (tm_const 1) (tm_plus (tm_const 0) (tm_const 0))).
|
||||
split.
|
||||
intros H.
|
||||
inversion H.
|
||||
|
||||
unfold normal_form.
|
||||
intros H.
|
||||
inversion H.
|
||||
inversion H0.
|
||||
inversion H4.
|
||||
Qed.
|
||||
|
||||
End Temp3.
|
||||
|
||||
Module Temp4.
|
||||
Inductive tm : Type :=
|
||||
| tm_true : tm
|
||||
| tm_false : tm
|
||||
| tm_if : tm -> tm -> tm -> tm.
|
||||
|
||||
Inductive value : tm -> Prop :=
|
||||
| v_true : value tm_true
|
||||
| v_false : value tm_false.
|
||||
|
||||
Inductive step : tm -> tm -> Prop :=
|
||||
| ST_IfTrue : forall t1 t2,
|
||||
tm_if tm_true t1 t2 ===> t1
|
||||
| ST_IfFalse : forall t1 t2,
|
||||
tm_if tm_false t1 t2 ===> t2
|
||||
| ST_If : forall t1 t1' t2 t3,
|
||||
t1 ===> t1' ->
|
||||
tm_if t1 t2 t3 ===> tm_if t1' t2 t3
|
||||
|
||||
where " t '===>' t' " := (step t t').
|
||||
|
||||
Example bool_step_prop3 :
|
||||
tm_if
|
||||
(tm_if tm_true tm_true tm_true)
|
||||
(tm_if tm_true tm_true tm_true)
|
||||
tm_false
|
||||
===>
|
||||
tm_if
|
||||
tm_true
|
||||
(tm_if tm_true tm_true tm_true)
|
||||
tm_false.
|
||||
Proof.
|
||||
apply ST_If.
|
||||
apply ST_IfTrue.
|
||||
Qed.
|
||||
|
||||
Theorem strong_progress: forall t,
|
||||
value t \/ (exists t', t ===> t').
|
||||
Proof.
|
||||
induction t.
|
||||
left.
|
||||
constructor.
|
||||
|
||||
left.
|
||||
constructor.
|
||||
|
||||
right.
|
||||
inversion IHt1.
|
||||
inversion H.
|
||||
exists t2.
|
||||
apply ST_IfTrue.
|
||||
|
||||
exists t3.
|
||||
apply ST_IfFalse.
|
||||
|
||||
inversion H.
|
||||
exists (tm_if x t2 t3).
|
||||
apply ST_If.
|
||||
assumption.
|
||||
Qed.
|
||||
|
||||
Theorem step_deterministic :
|
||||
partial_function step.
|
||||
Proof.
|
||||
unfold partial_function.
|
||||
intros x y1 y2 Hy1 Hy2.
|
||||
generalize dependent y2.
|
||||
induction Hy1.
|
||||
intros.
|
||||
inversion Hy2.
|
||||
reflexivity.
|
||||
|
||||
subst.
|
||||
inversion H3.
|
||||
|
||||
intros.
|
||||
inversion Hy2.
|
||||
reflexivity.
|
||||
|
||||
inversion H3.
|
||||
|
||||
intros.
|
||||
inversion Hy2.
|
||||
subst.
|
||||
inversion Hy1.
|
||||
|
||||
subst.
|
||||
inversion Hy1.
|
||||
|
||||
subst.
|
||||
apply IHHy1 in H3.
|
||||
subst.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Module Temp5.
|
||||
|
||||
|
||||
Inductive step : tm -> tm -> Prop :=
|
||||
| ST_IfTrue : forall t1 t2,
|
||||
tm_if tm_true t1 t2 ===> t1
|
||||
| ST_IfFalse : forall t1 t2,
|
||||
tm_if tm_false t1 t2 ===> t2
|
||||
| ST_If : forall t1 t1' t2 t3,
|
||||
t1 ===> t1' ->
|
||||
tm_if t1 t2 t3 ===> tm_if t1' t2 t3
|
||||
| ST_ShortCut : forall v t,
|
||||
value v ->
|
||||
tm_if t v v ===> v
|
||||
|
||||
where " t '===>' t' " := (step t t').
|
||||
|
||||
Definition bool_step_prop4 :=
|
||||
tm_if
|
||||
(tm_if tm_true tm_true tm_true)
|
||||
tm_false
|
||||
tm_false
|
||||
===>
|
||||
tm_false.
|
||||
|
||||
Example bool_step_prop4_holds :
|
||||
bool_step_prop4.
|
||||
Proof.
|
||||
unfold bool_step_prop4.
|
||||
apply ST_ShortCut.
|
||||
constructor.
|
||||
Qed.
|
||||
|
||||
Theorem strong_progress: forall t,
|
||||
value t \/ (exists t', t ===> t').
|
||||
Proof.
|
||||
induction t.
|
||||
left.
|
||||
constructor.
|
||||
|
||||
left.
|
||||
constructor.
|
||||
|
||||
inversion IHt1.
|
||||
right.
|
||||
inversion H.
|
||||
exists t2.
|
||||
constructor.
|
||||
|
||||
exists t3.
|
||||
constructor.
|
||||
|
||||
right.
|
||||
inversion H.
|
||||
exists (tm_if x t2 t3).
|
||||
apply ST_If.
|
||||
assumption.
|
||||
Qed.
|
||||
|
||||
End Temp5.
|
||||
End Temp4.
|
||||
|
||||
Definition stepmany := refl_step_closure step.
|
||||
|
||||
Notation " t '===>*' t' " := (stepmany t t') (at level 40).
|
||||
|
||||
Lemma test_stepmany_1:
|
||||
tm_plus
|
||||
(tm_plus (tm_const 0) (tm_const 3))
|
||||
(tm_plus (tm_const 2) (tm_const 4))
|
||||
===>*
|
||||
tm_const (plus (plus 0 3) (plus 2 4)).
|
||||
Proof.
|
||||
eapply rsc_step. apply ST_Plus1. apply ST_PlusConstConst.
|
||||
eapply rsc_step. apply ST_Plus2. apply v_const.
|
||||
apply ST_PlusConstConst.
|
||||
eapply rsc_step. apply ST_PlusConstConst.
|
||||
apply rsc_refl. Qed.
|
||||
|
||||
Lemma test_stepmany_2:
|
||||
tm_const 3 ===>* tm_const 3.
|
||||
Proof.
|
||||
eapply rsc_refl.
|
||||
Qed.
|
||||
|
||||
Lemma test_stepmany_3:
|
||||
tm_plus (tm_const 0) (tm_const 3)
|
||||
===>*
|
||||
tm_plus (tm_const 0) (tm_const 3).
|
||||
Proof.
|
||||
eapply rsc_refl.
|
||||
Qed.
|
||||
|
||||
Lemma test_stepmany_4:
|
||||
tm_plus
|
||||
(tm_const 0)
|
||||
(tm_plus
|
||||
(tm_const 2)
|
||||
(tm_plus (tm_const 0) (tm_const 3)))
|
||||
===>*
|
||||
tm_plus
|
||||
(tm_const 0)
|
||||
(tm_const (plus 2 (plus 0 3))).
|
||||
Proof.
|
||||
eapply rsc_step.
|
||||
apply ST_Plus2.
|
||||
apply v_const.
|
||||
|
||||
apply ST_Plus2.
|
||||
apply v_const.
|
||||
|
||||
apply ST_PlusConstConst.
|
||||
|
||||
eapply rsc_step.
|
||||
apply ST_Plus2.
|
||||
apply v_const.
|
||||
|
||||
apply ST_PlusConstConst.
|
||||
|
||||
eapply rsc_refl.
|
||||
Qed.
|
||||
|
||||
Definition step_normal_form := normal_form step.
|
||||
|
||||
Definition normal_form_of (t t' : tm) :=
|
||||
(t ===>* t' /\ step_normal_form t').
|
||||
|
||||
(*
|
||||
Theorem normal_forms_unique:
|
||||
partial_function normal_form_of.
|
||||
Proof.
|
||||
unfold partial_function. unfold normal_form_of. intros x y1 y2 P1 P2.
|
||||
destruct P1 as [P11 P12]. destruct P2 as [P21 P22].
|
||||
generalize dependent y2.
|
||||
|
||||
unfold step_normal_form in P12.
|
||||
unfold step_normal_form.
|
||||
unfold normal_form.
|
||||
unfold normal_form in P12.
|
||||
induction x.
|
||||
intros.
|
||||
unfold stepmany.
|
||||
inversion P11.
|
||||
subst.
|
||||
inversion P21.
|
||||
subst.
|
||||
reflexivity.
|
||||
|
||||
subst.
|
||||
inversion P21.
|
||||
reflexivity.
|
||||
|
||||
subst.
|
||||
inversion H1.
|
||||
|
||||
inversion H.
|
||||
*)
|
||||
|
||||
Definition normalizing {X:Type} (R:relation X) :=
|
||||
forall t, exists t',
|
||||
(refl_step_closure R) t t' /\ normal_form R t'.
|
||||
|
||||
Lemma stepmany_congr_1 : forall t1 t1' t2,
|
||||
t1 ===>* t1' ->
|
||||
tm_plus t1 t2 ===>* tm_plus t1' t2.
|
||||
Proof.
|
||||
intros t1 t1' t2 H.
|
||||
rsc_cases (induction H) Case.
|
||||
apply rsc_refl.
|
||||
|
||||
apply rsc_step with (tm_plus y t2).
|
||||
apply ST_Plus1.
|
||||
apply H.
|
||||
|
||||
apply IHrefl_step_closure.
|
||||
Qed.
|
||||
|
||||
Lemma stepmany_congr2 : forall t1 t2 t2',
|
||||
value t1 ->
|
||||
t2 ===>* t2' ->
|
||||
tm_plus t1 t2 ===>* tm_plus t1 t2'.
|
||||
Proof.
|
||||
intros t1 t2 t2'.
|
||||
intros H1.
|
||||
intros H2.
|
||||
induction H2.
|
||||
apply rsc_refl.
|
||||
|
||||
apply rsc_step with (tm_plus t1 y).
|
||||
apply ST_Plus2.
|
||||
assumption.
|
||||
|
||||
assumption.
|
||||
|
||||
assumption.
|
||||
Qed.
|
||||
|
||||
Theorem step_normalizing :
|
||||
normalizing step.
|
||||
Proof.
|
||||
unfold normalizing.
|
||||
tm_cases (induction t) Case.
|
||||
Case "tm_const".
|
||||
exists (tm_const n).
|
||||
split.
|
||||
SCase "l". apply rsc_refl.
|
||||
SCase "r".
|
||||
(* We can use rewrite with "iff" statements, not
|
||||
just equalities: *)
|
||||
rewrite nf_same_as_value. apply v_const.
|
||||
Case "tm_plus".
|
||||
destruct IHt1 as [t1' H1]. destruct IHt2 as [t2' H2].
|
||||
destruct H1 as [H11 H12]. destruct H2 as [H21 H22].
|
||||
rewrite nf_same_as_value in H12. rewrite nf_same_as_value in H22.
|
||||
inversion H12 as [n1]. inversion H22 as [n2].
|
||||
rewrite <- H in H11.
|
||||
rewrite <- H0 in H21.
|
||||
exists (tm_const (plus n1 n2)).
|
||||
split.
|
||||
SCase "l".
|
||||
apply rsc_trans with (tm_plus (tm_const n1) t2).
|
||||
apply stepmany_congr_1. apply H11.
|
||||
apply rsc_trans with
|
||||
(tm_plus (tm_const n1) (tm_const n2)).
|
||||
apply stepmany_congr2. apply v_const. apply H21.
|
||||
apply rsc_R. apply ST_PlusConstConst.
|
||||
SCase "r".
|
||||
rewrite nf_same_as_value. apply v_const. Qed.
|
||||
|
||||
Lemma eval__value : forall t1 t2,
|
||||
eval t1 t2 ->
|
||||
value t2.
|
||||
Proof.
|
||||
intros t1 t2 HE.
|
||||
eval_cases (inversion HE) Case; apply v_const. Qed.
|
||||
|
||||
|
||||
(*
|
||||
Theorem eval__stepmany: forall t v,
|
||||
eval t v -> t ===>* v.
|
||||
Proof.
|
||||
*)
|
||||
10
samples/coq/Sorting.v
Executable file
10
samples/coq/Sorting.v
Executable file
@@ -0,0 +1,10 @@
|
||||
(************************************************************************)
|
||||
(* v * The Coq Proof Assistant / The Coq Development Team *)
|
||||
(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2010 *)
|
||||
(* \VV/ **************************************************************)
|
||||
(* // * This file is distributed under the terms of the *)
|
||||
(* * GNU Lesser General Public License Version 2.1 *)
|
||||
(************************************************************************)
|
||||
|
||||
Require Export Sorted.
|
||||
Require Export Mergesort.
|
||||
733
samples/coq/Stlc.v
Executable file
733
samples/coq/Stlc.v
Executable file
@@ -0,0 +1,733 @@
|
||||
|
||||
Require Export SfLib.
|
||||
|
||||
Module STLC.
|
||||
|
||||
Inductive ty : Type :=
|
||||
| ty_Bool : ty
|
||||
| ty_arrow : ty -> ty -> ty.
|
||||
|
||||
Inductive tm : Type :=
|
||||
| tm_var : id -> tm
|
||||
| tm_app : tm -> tm -> tm
|
||||
| tm_abs : id -> ty -> tm -> tm
|
||||
| tm_true : tm
|
||||
| tm_false : tm
|
||||
| tm_if : tm -> tm -> tm -> tm.
|
||||
|
||||
Tactic Notation "tm_cases" tactic(first) ident(c) :=
|
||||
first;
|
||||
[ Case_aux c "tm_var" | Case_aux c "tm_app"
|
||||
| Case_aux c "tm_abs" | Case_aux c "tm_true"
|
||||
| Case_aux c "tm_false" | Case_aux c "tm_if" ].
|
||||
|
||||
Notation a := (Id 0).
|
||||
Notation b := (Id 1).
|
||||
Notation c := (Id 2).
|
||||
|
||||
Notation idB :=
|
||||
(tm_abs a ty_Bool (tm_var a)).
|
||||
|
||||
Notation idBB :=
|
||||
(tm_abs a (ty_arrow ty_Bool ty_Bool) (tm_var a)).
|
||||
|
||||
Notation idBBBB :=
|
||||
(tm_abs a (ty_arrow (ty_arrow ty_Bool ty_Bool)
|
||||
(ty_arrow ty_Bool ty_Bool))
|
||||
(tm_var a)).
|
||||
|
||||
Notation k := (tm_abs a ty_Bool (tm_abs b ty_Bool (tm_var a))).
|
||||
|
||||
Inductive value : tm -> Prop :=
|
||||
| v_abs : forall x T t,
|
||||
value (tm_abs x T t)
|
||||
| t_true :
|
||||
value tm_true
|
||||
| t_false :
|
||||
value tm_false.
|
||||
|
||||
Hint Constructors value.
|
||||
|
||||
Fixpoint subst (s:tm) (x:id) (t:tm) : tm :=
|
||||
match t with
|
||||
| tm_var x' => if beq_id x x' then s else t
|
||||
| tm_abs x' T t1 => tm_abs x' T (if beq_id x x' then t1 else (subst s x t1))
|
||||
| tm_app t1 t2 => tm_app (subst s x t1) (subst s x t2)
|
||||
| tm_true => tm_true
|
||||
| tm_false => tm_false
|
||||
| tm_if t1 t2 t3 => tm_if (subst s x t1) (subst s x t2) (subst s x t3)
|
||||
end.
|
||||
|
||||
Reserved Notation "t1 '==>' t2" (at level 40).
|
||||
|
||||
Inductive step : tm -> tm -> Prop :=
|
||||
| ST_AppAbs : forall x T t12 v2,
|
||||
value v2 ->
|
||||
(tm_app (tm_abs x T t12) v2) ==> (subst v2 x t12)
|
||||
| ST_App1 : forall t1 t1' t2,
|
||||
t1 ==> t1' ->
|
||||
tm_app t1 t2 ==> tm_app t1' t2
|
||||
| ST_App2 : forall v1 t2 t2',
|
||||
value v1 ->
|
||||
t2 ==> t2' ->
|
||||
tm_app v1 t2 ==> tm_app v1 t2'
|
||||
| ST_IfTrue : forall t1 t2,
|
||||
(tm_if tm_true t1 t2) ==> t1
|
||||
| ST_IfFalse : forall t1 t2,
|
||||
(tm_if tm_false t1 t2) ==> t2
|
||||
| ST_If : forall t1 t1' t2 t3,
|
||||
t1 ==> t1' ->
|
||||
(tm_if t1 t2 t3) ==> (tm_if t1' t2 t3)
|
||||
|
||||
where "t1 '==>' t2" := (step t1 t2).
|
||||
|
||||
Tactic Notation "step_cases" tactic(first) ident(c) :=
|
||||
first;
|
||||
[ Case_aux c "ST_AppAbs" | Case_aux c "ST_App1"
|
||||
| Case_aux c "ST_App2" | Case_aux c "ST_IfTrue"
|
||||
| Case_aux c "ST_IfFalse" | Case_aux c "ST_If" ].
|
||||
|
||||
Notation stepmany := (refl_step_closure step).
|
||||
Notation "t1 '==>*' t2" := (stepmany t1 t2) (at level 40).
|
||||
|
||||
Hint Constructors step.
|
||||
|
||||
Lemma step_example3 :
|
||||
(tm_app (tm_app idBBBB idBB) idB)
|
||||
==>* idB.
|
||||
Proof.
|
||||
eapply rsc_step.
|
||||
apply ST_App1.
|
||||
apply ST_AppAbs.
|
||||
apply v_abs.
|
||||
|
||||
simpl.
|
||||
eapply rsc_step.
|
||||
apply ST_AppAbs.
|
||||
apply v_abs.
|
||||
|
||||
simpl.
|
||||
apply rsc_refl.
|
||||
Qed.
|
||||
|
||||
Definition context := partial_map ty.
|
||||
Module Context.
|
||||
|
||||
Definition partial_map (A:Type) := id -> option A.
|
||||
Definition empty {A:Type} : partial_map A := (fun _ => None).
|
||||
Definition extend {A:Type} (Gamma : partial_map A) (x:id) (T : A) :=
|
||||
fun x' => if beq_id x x' then Some T else Gamma x'.
|
||||
|
||||
Lemma extend_eq : forall A (ctxt: partial_map A) x T,
|
||||
(extend ctxt x T) x = Some T.
|
||||
Proof.
|
||||
intros. unfold extend. rewrite <- beq_id_refl. auto.
|
||||
Qed.
|
||||
|
||||
Lemma extend_neq : forall A (ctxt: partial_map A) x1 T x2,
|
||||
beq_id x2 x1 = false ->
|
||||
(extend ctxt x2 T) x1 = ctxt x1.
|
||||
Proof.
|
||||
intros. unfold extend. rewrite H. auto.
|
||||
Qed.
|
||||
|
||||
End Context.
|
||||
|
||||
Inductive has_type : context -> tm -> ty -> Prop :=
|
||||
| T_Var : forall Gamma x T,
|
||||
Gamma x = Some T ->
|
||||
has_type Gamma (tm_var x) T
|
||||
| T_Abs : forall Gamma x T11 T12 t12,
|
||||
has_type (extend Gamma x T11) t12 T12 ->
|
||||
has_type Gamma (tm_abs x T11 t12) (ty_arrow T11 T12)
|
||||
| T_App : forall T11 T12 Gamma t1 t2,
|
||||
has_type Gamma t1 (ty_arrow T11 T12) ->
|
||||
has_type Gamma t2 T11 ->
|
||||
has_type Gamma (tm_app t1 t2) T12
|
||||
| T_True : forall Gamma,
|
||||
has_type Gamma tm_true ty_Bool
|
||||
| T_False : forall Gamma,
|
||||
has_type Gamma tm_false ty_Bool
|
||||
| T_If : forall t1 t2 t3 T Gamma,
|
||||
has_type Gamma t1 ty_Bool ->
|
||||
has_type Gamma t2 T ->
|
||||
has_type Gamma t3 T ->
|
||||
has_type Gamma (tm_if t1 t2 t3) T.
|
||||
|
||||
Tactic Notation "has_type_cases" tactic(first) ident(c) :=
|
||||
first;
|
||||
[ Case_aux c "T_Var" | Case_aux c "T_Abs"
|
||||
| Case_aux c "T_App" | Case_aux c "T_True"
|
||||
| Case_aux c "T_False" | Case_aux c "T_If" ].
|
||||
|
||||
Hint Constructors has_type.
|
||||
|
||||
Hint Unfold beq_id beq_nat extend.
|
||||
|
||||
Example typing_example_2_full :
|
||||
has_type empty
|
||||
(tm_abs a ty_Bool
|
||||
(tm_abs b (ty_arrow ty_Bool ty_Bool)
|
||||
(tm_app (tm_var b) (tm_app (tm_var b) (tm_var a)))))
|
||||
(ty_arrow ty_Bool (ty_arrow (ty_arrow ty_Bool ty_Bool) ty_Bool)).
|
||||
Proof.
|
||||
apply T_Abs.
|
||||
apply T_Abs.
|
||||
apply T_App with (T11 := ty_Bool).
|
||||
apply T_Var.
|
||||
unfold extend.
|
||||
simpl.
|
||||
reflexivity.
|
||||
|
||||
apply T_App with (T11 := ty_Bool).
|
||||
apply T_Var.
|
||||
unfold extend.
|
||||
simpl.
|
||||
reflexivity.
|
||||
|
||||
apply T_Var.
|
||||
unfold extend.
|
||||
simpl.
|
||||
reflexivity.
|
||||
Qed.
|
||||
|
||||
Example typing_example_3 :
|
||||
exists T,
|
||||
has_type empty
|
||||
(tm_abs a (ty_arrow ty_Bool ty_Bool)
|
||||
(tm_abs b (ty_arrow ty_Bool ty_Bool)
|
||||
(tm_abs c ty_Bool
|
||||
(tm_app (tm_var b) (tm_app (tm_var a) (tm_var c))))))
|
||||
T.
|
||||
|
||||
Proof with auto.
|
||||
exists
|
||||
(ty_arrow (ty_arrow ty_Bool ty_Bool)
|
||||
(ty_arrow (ty_arrow ty_Bool ty_Bool) (ty_arrow ty_Bool ty_Bool))).
|
||||
apply T_Abs.
|
||||
apply T_Abs.
|
||||
apply T_Abs.
|
||||
apply T_App with (T11 := ty_Bool).
|
||||
apply T_Var.
|
||||
unfold extend.
|
||||
simpl.
|
||||
reflexivity.
|
||||
|
||||
apply T_App with (T11 := ty_Bool).
|
||||
auto.
|
||||
|
||||
auto.
|
||||
Qed.
|
||||
|
||||
|
||||
Theorem coiso : forall a b e,
|
||||
a ==>* b ->
|
||||
tm_app a e ==>* tm_app b e.
|
||||
Proof.
|
||||
intros.
|
||||
induction H.
|
||||
apply rsc_refl.
|
||||
|
||||
apply rsc_step with (tm_app y e).
|
||||
apply ST_App1.
|
||||
assumption.
|
||||
|
||||
assumption.
|
||||
Qed.
|
||||
|
||||
Theorem reptrans : forall a b c,
|
||||
a ==>* b ->
|
||||
b ==>* c ->
|
||||
a ==>* c.
|
||||
Proof.
|
||||
|
||||
intros a b c H.
|
||||
induction H.
|
||||
intros.
|
||||
assumption.
|
||||
|
||||
intros H1.
|
||||
apply IHrefl_step_closure in H1.
|
||||
apply rsc_step with y.
|
||||
assumption.
|
||||
|
||||
assumption.
|
||||
Qed.
|
||||
|
||||
(* TODO
|
||||
Example typing_nonexample_3 :
|
||||
~ (exists S, exists T,
|
||||
has_type empty
|
||||
(tm_abs a S
|
||||
(tm_app (tm_var a) (tm_var a)))
|
||||
T).
|
||||
Proof.
|
||||
*)
|
||||
|
||||
Inductive appears_free_in : id -> tm -> Prop :=
|
||||
| afi_var : forall x,
|
||||
appears_free_in x (tm_var x)
|
||||
| afi_app1 : forall x t1 t2,
|
||||
appears_free_in x t1 -> appears_free_in x (tm_app t1 t2)
|
||||
| afi_app2 : forall x t1 t2,
|
||||
appears_free_in x t2 -> appears_free_in x (tm_app t1 t2)
|
||||
| afi_abs : forall x y T11 t12,
|
||||
y <> x ->
|
||||
appears_free_in x t12 ->
|
||||
appears_free_in x (tm_abs y T11 t12)
|
||||
| afi_if1 : forall x t1 t2 t3,
|
||||
appears_free_in x t1 ->
|
||||
appears_free_in x (tm_if t1 t2 t3)
|
||||
| afi_if2 : forall x t1 t2 t3,
|
||||
appears_free_in x t2 ->
|
||||
appears_free_in x (tm_if t1 t2 t3)
|
||||
| afi_if3 : forall x t1 t2 t3,
|
||||
appears_free_in x t3 ->
|
||||
appears_free_in x (tm_if t1 t2 t3).
|
||||
|
||||
Tactic Notation "afi_cases" tactic(first) ident(c) :=
|
||||
first;
|
||||
[ Case_aux c "afi_var"
|
||||
| Case_aux c "afi_app1" | Case_aux c "afi_app2"
|
||||
| Case_aux c "afi_abs"
|
||||
| Case_aux c "afi_if1" | Case_aux c "afi_if2"
|
||||
| Case_aux c "afi_if3" ].
|
||||
|
||||
Hint Constructors appears_free_in.
|
||||
|
||||
Definition closed (t:tm) :=
|
||||
forall x, ~ appears_free_in x t.
|
||||
|
||||
Lemma free_in_context : forall x t T Gamma,
|
||||
appears_free_in x t ->
|
||||
has_type Gamma t T ->
|
||||
exists T', Gamma x = Some T'.
|
||||
Proof.
|
||||
intros. generalize dependent Gamma. generalize dependent T.
|
||||
afi_cases (induction H) Case;
|
||||
intros; try solve [inversion H0; eauto].
|
||||
Case "afi_abs".
|
||||
inversion H1; subst.
|
||||
apply IHappears_free_in in H7.
|
||||
apply not_eq_beq_id_false in H.
|
||||
rewrite extend_neq in H7; assumption.
|
||||
Qed.
|
||||
|
||||
Corollary typable_empty__closed : forall t T,
|
||||
has_type empty t T ->
|
||||
closed t.
|
||||
Proof.
|
||||
intros t T H x H1.
|
||||
remember (@empty ty) as Gamma.
|
||||
assert (exists t' : _, Gamma x = Some t').
|
||||
apply free_in_context with (t := t) (T := T).
|
||||
assumption.
|
||||
|
||||
assumption.
|
||||
|
||||
inversion H0.
|
||||
rewrite HeqGamma in H2.
|
||||
inversion H2.
|
||||
Qed.
|
||||
|
||||
Lemma context_invariance : forall Gamma Gamma' t S,
|
||||
has_type Gamma t S ->
|
||||
(forall x, appears_free_in x t -> Gamma x = Gamma' x) ->
|
||||
has_type Gamma' t S.
|
||||
Proof with auto.
|
||||
intros.
|
||||
generalize dependent Gamma'.
|
||||
has_type_cases (induction H) Case; intros; auto.
|
||||
apply T_Var.
|
||||
rewrite <- H0...
|
||||
|
||||
apply T_Abs.
|
||||
apply IHhas_type.
|
||||
intros x0 Hafi.
|
||||
unfold extend.
|
||||
remember (beq_id x x0) as e.
|
||||
destruct e.
|
||||
reflexivity.
|
||||
|
||||
auto.
|
||||
apply H0.
|
||||
apply afi_abs.
|
||||
auto.
|
||||
eauto .
|
||||
apply beq_id_false_not_eq.
|
||||
rewrite Heqe.
|
||||
reflexivity.
|
||||
|
||||
assumption.
|
||||
|
||||
apply T_App with T11.
|
||||
auto.
|
||||
|
||||
auto.
|
||||
Qed.
|
||||
|
||||
Lemma substitution_preserves_typing : forall Gamma x U v t T,
|
||||
has_type (extend Gamma x U) t T ->
|
||||
has_type empty v U ->
|
||||
has_type Gamma (subst v x t) T.
|
||||
Proof with eauto.
|
||||
intros Gamma x U v t T Ht Hv.
|
||||
generalize dependent Gamma.
|
||||
generalize dependent T.
|
||||
tm_cases (induction t) Case; intros T Gamma H; inversion H; subst; simpl...
|
||||
Case "tm_var".
|
||||
rename i into y. remember (beq_id x y) as e. destruct e.
|
||||
SCase "x=y".
|
||||
apply beq_id_eq in Heqe. subst.
|
||||
rewrite extend_eq in H2.
|
||||
inversion H2; subst.
|
||||
clear H2.
|
||||
eapply context_invariance...
|
||||
intros x Hcontra.
|
||||
destruct (free_in_context _ _ T empty Hcontra) as (T', HT')...
|
||||
inversion HT'.
|
||||
|
||||
apply T_Var.
|
||||
rewrite extend_neq in H2.
|
||||
assumption.
|
||||
|
||||
rewrite Heqe.
|
||||
reflexivity.
|
||||
|
||||
rename i into y.
|
||||
apply T_Abs.
|
||||
remember (beq_id x y) as e.
|
||||
destruct e.
|
||||
eapply context_invariance...
|
||||
apply beq_id_eq in Heqe.
|
||||
subst.
|
||||
intros x Hafi.
|
||||
unfold extend.
|
||||
destruct (beq_id y x).
|
||||
reflexivity.
|
||||
|
||||
reflexivity.
|
||||
|
||||
apply IHt.
|
||||
eapply context_invariance...
|
||||
intros x0 Hafi.
|
||||
unfold extend.
|
||||
remember (beq_id y x0) as Coiso1.
|
||||
remember (beq_id x x0) as Coiso2.
|
||||
destruct Coiso1.
|
||||
auto.
|
||||
eauto .
|
||||
destruct Coiso2.
|
||||
eauto .
|
||||
auto.
|
||||
apply beq_id_eq in HeqCoiso1.
|
||||
apply beq_id_eq in HeqCoiso2.
|
||||
subst.
|
||||
assert (x0 <> x0).
|
||||
apply beq_id_false_not_eq.
|
||||
rewrite Heqe.
|
||||
auto.
|
||||
|
||||
apply ex_falso_quodlibet.
|
||||
apply H0.
|
||||
reflexivity.
|
||||
|
||||
reflexivity.
|
||||
|
||||
destruct Coiso2.
|
||||
auto.
|
||||
|
||||
auto.
|
||||
Qed.
|
||||
|
||||
Theorem preservation : forall t t' T,
|
||||
has_type empty t T ->
|
||||
t ==> t' ->
|
||||
has_type empty t' T.
|
||||
Proof.
|
||||
remember (@empty ty) as Gamma.
|
||||
intros t t' T HT.
|
||||
generalize dependent t'.
|
||||
induction HT.
|
||||
intros t' H1.
|
||||
inversion H1.
|
||||
|
||||
intros t' H1.
|
||||
inversion H1.
|
||||
|
||||
intros t' H1.
|
||||
inversion H1.
|
||||
apply substitution_preserves_typing with T11.
|
||||
subst.
|
||||
inversion HT1.
|
||||
subst.
|
||||
apply H2.
|
||||
|
||||
subst.
|
||||
assumption.
|
||||
|
||||
subst.
|
||||
apply T_App with T11.
|
||||
apply IHHT1.
|
||||
reflexivity.
|
||||
|
||||
assumption.
|
||||
|
||||
assumption.
|
||||
|
||||
subst.
|
||||
apply T_App with T11.
|
||||
assumption.
|
||||
|
||||
apply IHHT2.
|
||||
reflexivity.
|
||||
|
||||
assumption.
|
||||
|
||||
intros t' H.
|
||||
inversion H.
|
||||
|
||||
intros t' H.
|
||||
inversion H.
|
||||
|
||||
intros t' H.
|
||||
inversion H.
|
||||
subst.
|
||||
assumption.
|
||||
|
||||
subst.
|
||||
assumption.
|
||||
|
||||
subst.
|
||||
apply T_If.
|
||||
apply IHHT1.
|
||||
reflexivity.
|
||||
|
||||
assumption.
|
||||
|
||||
assumption.
|
||||
|
||||
assumption.
|
||||
Qed.
|
||||
|
||||
Theorem progress : forall t T,
|
||||
has_type empty t T ->
|
||||
value t \/ exists t', t ==> t'.
|
||||
Proof.
|
||||
intros t T.
|
||||
intros H.
|
||||
remember (@empty ty) as Gamma.
|
||||
induction H.
|
||||
rewrite HeqGamma in H.
|
||||
unfold empty in H.
|
||||
inversion H.
|
||||
|
||||
left.
|
||||
apply v_abs.
|
||||
|
||||
right.
|
||||
assert (value t1 \/ (exists t' : tm, t1 ==> t')).
|
||||
apply IHhas_type1.
|
||||
assumption.
|
||||
|
||||
assert (value t2 \/ (exists t' : tm, t2 ==> t')).
|
||||
apply IHhas_type2.
|
||||
assumption.
|
||||
|
||||
inversion H1.
|
||||
inversion H2.
|
||||
inversion H3.
|
||||
subst.
|
||||
exists (subst t2 x t).
|
||||
apply ST_AppAbs.
|
||||
assumption.
|
||||
|
||||
subst.
|
||||
inversion H.
|
||||
|
||||
subst.
|
||||
inversion H.
|
||||
|
||||
inversion H4.
|
||||
exists (tm_app t1 x).
|
||||
apply ST_App2.
|
||||
assumption.
|
||||
|
||||
assumption.
|
||||
|
||||
inversion H3.
|
||||
exists (tm_app x t2).
|
||||
apply ST_App1.
|
||||
assumption.
|
||||
|
||||
left.
|
||||
auto.
|
||||
|
||||
left.
|
||||
auto.
|
||||
|
||||
right.
|
||||
assert (value t1 \/ (exists t' : tm, t1 ==> t')).
|
||||
apply IHhas_type1.
|
||||
assumption.
|
||||
|
||||
inversion H2.
|
||||
inversion H3.
|
||||
subst.
|
||||
inversion H.
|
||||
|
||||
subst.
|
||||
exists t2.
|
||||
apply ST_IfTrue.
|
||||
|
||||
subst.
|
||||
exists t3.
|
||||
apply ST_IfFalse.
|
||||
|
||||
inversion H3.
|
||||
exists (tm_if x t2 t3).
|
||||
apply ST_If.
|
||||
assumption.
|
||||
Qed.
|
||||
|
||||
Theorem progress' : forall t T,
|
||||
has_type empty t T ->
|
||||
value t \/ exists t', t ==> t'.
|
||||
Proof.
|
||||
intros t.
|
||||
tm_cases (induction t) Case; intros T Ht; auto.
|
||||
inversion Ht.
|
||||
inversion H1.
|
||||
|
||||
right.
|
||||
inversion Ht.
|
||||
subst.
|
||||
assert (value t1 \/ (exists t' : tm, t1 ==> t')).
|
||||
apply IHt1 with (T := ty_arrow T11 T).
|
||||
assumption.
|
||||
|
||||
assert (value t2 \/ (exists t' : tm, t2 ==> t')).
|
||||
apply IHt2 with T11.
|
||||
assumption.
|
||||
|
||||
inversion H.
|
||||
inversion H1.
|
||||
subst.
|
||||
inversion H0.
|
||||
exists (subst t2 x t).
|
||||
apply ST_AppAbs.
|
||||
assumption.
|
||||
|
||||
inversion H3.
|
||||
exists (tm_app (tm_abs x T0 t) x0).
|
||||
apply ST_App2.
|
||||
assumption.
|
||||
|
||||
assumption.
|
||||
|
||||
subst.
|
||||
inversion H2.
|
||||
|
||||
subst.
|
||||
inversion H2.
|
||||
|
||||
inversion H1.
|
||||
exists (tm_app x t2).
|
||||
apply ST_App1.
|
||||
assumption.
|
||||
|
||||
right.
|
||||
inversion Ht.
|
||||
subst.
|
||||
assert (value t1 \/ (exists t' : tm, t1 ==> t')).
|
||||
apply IHt1 with ty_Bool.
|
||||
assumption.
|
||||
|
||||
assert (value t2 \/ (exists t' : tm, t2 ==> t')).
|
||||
apply IHt2 with T.
|
||||
assumption.
|
||||
|
||||
assert (value t3 \/ (exists t' : tm, t3 ==> t')).
|
||||
apply IHt3 with T.
|
||||
assumption.
|
||||
|
||||
inversion H.
|
||||
inversion H2.
|
||||
subst.
|
||||
inversion H3.
|
||||
|
||||
subst.
|
||||
subst.
|
||||
exists t2.
|
||||
apply ST_IfTrue.
|
||||
|
||||
exists t3.
|
||||
apply ST_IfFalse.
|
||||
|
||||
inversion H2.
|
||||
exists (tm_if x t2 t3).
|
||||
apply ST_If.
|
||||
assumption.
|
||||
Qed.
|
||||
|
||||
Theorem types_unique : forall t T Gamma,
|
||||
has_type Gamma t T ->
|
||||
(forall T', has_type Gamma t T' -> T' = T).
|
||||
Proof.
|
||||
intros t T Gamma H.
|
||||
induction H.
|
||||
intros T'.
|
||||
intros H1.
|
||||
inversion H1.
|
||||
subst.
|
||||
subst.
|
||||
auto.
|
||||
eauto .
|
||||
inversion H1.
|
||||
subst.
|
||||
assert (Some T = Some T').
|
||||
rewrite <- H3.
|
||||
rewrite <- H.
|
||||
reflexivity.
|
||||
|
||||
inversion H0.
|
||||
reflexivity.
|
||||
|
||||
intros T'.
|
||||
intros H1.
|
||||
inversion H1.
|
||||
subst.
|
||||
assert (T1 = T12).
|
||||
apply IHhas_type.
|
||||
assumption.
|
||||
|
||||
rewrite H0.
|
||||
reflexivity.
|
||||
|
||||
intros T' H1.
|
||||
subst.
|
||||
inversion H1.
|
||||
subst.
|
||||
assert (ty_arrow T0 T' = ty_arrow T11 T12).
|
||||
apply IHhas_type1.
|
||||
assumption.
|
||||
|
||||
inversion H2.
|
||||
reflexivity.
|
||||
|
||||
intros T'.
|
||||
intros H.
|
||||
inversion H.
|
||||
reflexivity.
|
||||
|
||||
intros.
|
||||
inversion H.
|
||||
reflexivity.
|
||||
|
||||
intros T'.
|
||||
intros H2.
|
||||
inversion H2.
|
||||
subst.
|
||||
apply IHhas_type2.
|
||||
assumption.
|
||||
Qed.
|
||||
94
samples/verilog/button_debounce.v
Executable file
94
samples/verilog/button_debounce.v
Executable file
@@ -0,0 +1,94 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Original Author: Schuyler Eldridge
|
||||
// Contact Point: Schuyler Eldridge (schuyler.eldridge@gmail.com)
|
||||
// button_debounce.v
|
||||
// Created: 10/10/2009
|
||||
// Modified: 3/20/2012
|
||||
//
|
||||
// Counter based debounce circuit originally written for EC551 (back
|
||||
// in the day) and then modified (i.e. chagned entirely) into 3 always
|
||||
// block format. This debouncer generates a signal that goes high for
|
||||
// 1 clock cycle after the clock sees an asserted value on the button
|
||||
// line. This action is then disabled until the counter hits a
|
||||
// specified count value that is determined by the clock frequency and
|
||||
// desired debounce frequency. An alternative implementation would not
|
||||
// use a counter, but would use the shift register approach, looking
|
||||
// for repeated matches (say 5) on the button line.
|
||||
//
|
||||
// Copyright (C) 2012 Schuyler Eldridge, Boston University
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
`timescale 1ns / 1ps
|
||||
module button_debounce
|
||||
(
|
||||
input clk, // clock
|
||||
input reset_n, // asynchronous reset
|
||||
input button, // bouncy button
|
||||
output reg debounce // debounced 1-cycle signal
|
||||
);
|
||||
|
||||
parameter
|
||||
CLK_FREQUENCY = 66000000,
|
||||
DEBOUNCE_HZ = 2;
|
||||
// These parameters are specified such that you can choose any power
|
||||
// of 2 frequency for a debouncer between 1 Hz and
|
||||
// CLK_FREQUENCY. Note, that this will throw errors if you choose a
|
||||
// non power of 2 frequency (i.e. count_value evaluates to some
|
||||
// number / 3 which isn't interpreted as a logical right shift). I'm
|
||||
// assuming this will not work for DEBOUNCE_HZ values less than 1,
|
||||
// however, I'm uncertain of the value of a debouncer for fractional
|
||||
// hertz button presses.
|
||||
localparam
|
||||
COUNT_VALUE = CLK_FREQUENCY / DEBOUNCE_HZ,
|
||||
WAIT = 0,
|
||||
FIRE = 1,
|
||||
COUNT = 2;
|
||||
|
||||
reg [1:0] state, next_state;
|
||||
reg [25:0] count;
|
||||
|
||||
always @ (posedge clk or negedge reset_n)
|
||||
state <= (!reset_n) ? WAIT : next_state;
|
||||
|
||||
always @ (posedge clk or negedge reset_n) begin
|
||||
if (!reset_n) begin
|
||||
debounce <= 0;
|
||||
count <= 0;
|
||||
end
|
||||
else begin
|
||||
debounce <= 0;
|
||||
count <= 0;
|
||||
case (state)
|
||||
WAIT: begin
|
||||
end
|
||||
FIRE: begin
|
||||
debounce <= 1;
|
||||
end
|
||||
COUNT: begin
|
||||
count <= count + 1;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
always @ * begin
|
||||
case (state)
|
||||
WAIT: next_state = (button) ? FIRE : state;
|
||||
FIRE: next_state = COUNT;
|
||||
COUNT: next_state = (count > COUNT_VALUE - 1) ? WAIT : state;
|
||||
default: next_state = WAIT;
|
||||
endcase
|
||||
end
|
||||
|
||||
endmodule
|
||||
155
samples/verilog/control.v
Executable file
155
samples/verilog/control.v
Executable file
@@ -0,0 +1,155 @@
|
||||
`timescale 1ns / 1ps
|
||||
// Copyright (C) 2008 Schuyler Eldridge, Boston University
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
module control(clk,en,dsp_sel,an);
|
||||
input clk, en;
|
||||
output [1:0]dsp_sel;
|
||||
output [3:0]an;
|
||||
wire a,b,c,d,e,f,g,h,i,j,k,l;
|
||||
|
||||
assign an[3] = a;
|
||||
assign an[2] = b;
|
||||
assign an[1] = c;
|
||||
assign an[0] = d;
|
||||
|
||||
assign dsp_sel[1] = e;
|
||||
|
||||
assign dsp_sel[0] = i;
|
||||
|
||||
|
||||
FDRSE #(
|
||||
.INIT(1'b0) // Initial value of register (1'b0 or 1'b1)
|
||||
) DFF3(
|
||||
.Q(a), // Data output
|
||||
.C(clk), // Clock input
|
||||
.CE(en), // Clock enable input
|
||||
.D(d), // Data input
|
||||
.R(1'b0), // Synchronous reset input
|
||||
.S(1'b0) // Synchronous set input
|
||||
);
|
||||
FDRSE #(
|
||||
.INIT(1'b1) // Initial value of register (1'b0 or 1'b1)
|
||||
) DFF2(
|
||||
.Q(b), // Data output
|
||||
.C(clk), // Clock input
|
||||
.CE(en), // Clock enable input
|
||||
.D(a), // Data input
|
||||
.R(1'b0), // Synchronous reset input
|
||||
.S(1'b0) // Synchronous set input
|
||||
);
|
||||
FDRSE #(
|
||||
.INIT(1'b1) // Initial value of register (1'b0 or 1'b1)
|
||||
) DFF1(
|
||||
.Q(c), // Data output
|
||||
.C(clk), // Clock input
|
||||
.CE(en), // Clock enable input
|
||||
.D(b), // Data input
|
||||
.R(1'b0), // Synchronous reset input
|
||||
.S(1'b0) // Synchronous set input
|
||||
);
|
||||
FDRSE #(
|
||||
.INIT(1'b1) // Initial value of register (1'b0 or 1'b1)
|
||||
) DFF0(
|
||||
.Q(d), // Data output
|
||||
.C(clk), // Clock input
|
||||
.CE(en), // Clock enable input
|
||||
.D(c), // Data input
|
||||
.R(1'b0), // Synchronous reset input
|
||||
.S(1'b0) // Synchronous set input
|
||||
);
|
||||
|
||||
|
||||
FDRSE #(
|
||||
.INIT(1'b1) // Initial value of register (1'b0 or 1'b1)
|
||||
) DFF7(
|
||||
.Q(e), // Data output
|
||||
.C(clk), // Clock input
|
||||
.CE(en), // Clock enable input
|
||||
.D(h), // Data input
|
||||
.R(1'b0), // Synchronous reset input
|
||||
.S(1'b0) // Synchronous set input
|
||||
);
|
||||
FDRSE #(
|
||||
.INIT(1'b1) // Initial value of register (1'b0 or 1'b1)
|
||||
) DFF6(
|
||||
.Q(f), // Data output
|
||||
.C(clk), // Clock input
|
||||
.CE(en), // Clock enable input
|
||||
.D(e), // Data input
|
||||
.R(1'b0), // Synchronous reset input
|
||||
.S(1'b0) // Synchronous set input
|
||||
);
|
||||
FDRSE #(
|
||||
.INIT(1'b0) // Initial value of register (1'b0 or 1'b1)
|
||||
) DFF5(
|
||||
.Q(g), // Data output
|
||||
.C(clk), // Clock input
|
||||
.CE(en), // Clock enable input
|
||||
.D(f), // Data input
|
||||
.R(1'b0), // Synchronous reset input
|
||||
.S(1'b0) // Synchronous set input
|
||||
);
|
||||
FDRSE #(
|
||||
.INIT(1'b0) // Initial value of register (1'b0 or 1'b1)
|
||||
) DFF4(
|
||||
.Q(h), // Data output
|
||||
.C(clk), // Clock input
|
||||
.CE(en), // Clock enable input
|
||||
.D(g), // Data input
|
||||
.R(1'b0), // Synchronous reset input
|
||||
.S(1'b0) // Synchronous set input
|
||||
);
|
||||
|
||||
|
||||
FDRSE #(
|
||||
.INIT(1'b1) // Initial value of register (1'b0 or 1'b1)
|
||||
) DFF11(
|
||||
.Q(i), // Data output
|
||||
.C(clk), // Clock input
|
||||
.CE(en), // Clock enable input
|
||||
.D(l), // Data input
|
||||
.R(1'b0), // Synchronous reset input
|
||||
.S(1'b0) // Synchronous set input
|
||||
);
|
||||
FDRSE #(
|
||||
.INIT(1'b0) // Initial value of register (1'b0 or 1'b1)
|
||||
) DFF10(
|
||||
.Q(j), // Data output
|
||||
.C(clk), // Clock input
|
||||
.CE(en), // Clock enable input
|
||||
.D(i), // Data input
|
||||
.R(1'b0), // Synchronous reset input
|
||||
.S(1'b0) // Synchronous set input
|
||||
);
|
||||
FDRSE #(
|
||||
.INIT(1'b1) // Initial value of register (1'b0 or 1'b1)
|
||||
) DFF9(
|
||||
.Q(k), // Data output
|
||||
.C(clk), // Clock input
|
||||
.CE(en), // Clock enable input
|
||||
.D(j), // Data input
|
||||
.R(1'b0), // Synchronous reset input
|
||||
.S(1'b0) // Synchronous set input
|
||||
);
|
||||
FDRSE #(
|
||||
.INIT(1'b0) // Initial value of register (1'b0 or 1'b1)
|
||||
) DFF8(
|
||||
.Q(l), // Data output
|
||||
.C(clk), // Clock input
|
||||
.CE(en), // Clock enable input
|
||||
.D(k), // Data input
|
||||
.R(1'b0), // Synchronous reset input
|
||||
.S(1'b0) // Synchronous set input
|
||||
);
|
||||
endmodule
|
||||
54
samples/verilog/hex_display.v
Executable file
54
samples/verilog/hex_display.v
Executable file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Zeus Gomez Marmolejo <zeus@opencores.org>
|
||||
*
|
||||
* This file is part of the Zet processor. This processor is free
|
||||
* hardware; you can redistribute it and/or modify it under the terms of
|
||||
* the GNU General Public License as published by the Free Software
|
||||
* Foundation; either version 3, or (at your option) any later version.
|
||||
*
|
||||
* Zet is distrubuted in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Zet; see the file COPYING. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
module hex_display (
|
||||
input [15:0] num,
|
||||
input en,
|
||||
|
||||
output [6:0] hex0,
|
||||
output [6:0] hex1,
|
||||
output [6:0] hex2,
|
||||
output [6:0] hex3
|
||||
);
|
||||
|
||||
// Module instantiations
|
||||
seg_7 hex_group0 (
|
||||
.num (num[3:0]),
|
||||
.en (en),
|
||||
.seg (hex0)
|
||||
);
|
||||
|
||||
seg_7 hex_group1 (
|
||||
.num (num[7:4]),
|
||||
.en (en),
|
||||
.seg (hex1)
|
||||
);
|
||||
|
||||
seg_7 hex_group2 (
|
||||
.num (num[11:8]),
|
||||
.en (en),
|
||||
.seg (hex2)
|
||||
);
|
||||
|
||||
seg_7 hex_group3 (
|
||||
.num (num[15:12]),
|
||||
.en (en),
|
||||
.seg (hex3)
|
||||
);
|
||||
|
||||
endmodule
|
||||
45
samples/verilog/mux.v
Executable file
45
samples/verilog/mux.v
Executable file
@@ -0,0 +1,45 @@
|
||||
`timescale 1ns / 1ps
|
||||
// Copyright (C) 2008 Schuyler Eldridge, Boston University
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
module mux(opA,opB,sum,dsp_sel,out);
|
||||
input [3:0] opA,opB;
|
||||
input [4:0] sum;
|
||||
input [1:0] dsp_sel;
|
||||
output [3:0] out;
|
||||
|
||||
reg cout;
|
||||
|
||||
always @ (sum)
|
||||
begin
|
||||
if (sum[4] == 1)
|
||||
cout <= 4'b0001;
|
||||
else
|
||||
cout <= 4'b0000;
|
||||
end
|
||||
|
||||
reg out;
|
||||
|
||||
always @(dsp_sel,sum,cout,opB,opA)
|
||||
begin
|
||||
if (dsp_sel == 2'b00)
|
||||
out <= sum[3:0];
|
||||
else if (dsp_sel == 2'b01)
|
||||
out <= cout;
|
||||
else if (dsp_sel == 2'b10)
|
||||
out <= opB;
|
||||
else if (dsp_sel == 2'b11)
|
||||
out <= opA;
|
||||
end
|
||||
|
||||
endmodule
|
||||
82
samples/verilog/pipeline_registers.v
Executable file
82
samples/verilog/pipeline_registers.v
Executable file
@@ -0,0 +1,82 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Original Author: Schuyler Eldridge
|
||||
// Contact Point: Schuyler Eldridge (schuyler.eldridge@gmail.com)
|
||||
// pipeline_registers.v
|
||||
// Created: 4.4.2012
|
||||
// Modified: 4.4.2012
|
||||
//
|
||||
// Implements a series of pipeline registers specified by the input
|
||||
// parameters BIT_WIDTH and NUMBER_OF_STAGES. BIT_WIDTH determines the
|
||||
// size of the signal passed through each of the pipeline
|
||||
// registers. NUMBER_OF_STAGES is the number of pipeline registers
|
||||
// generated. This accepts values of 0 (yes, it just passes data from
|
||||
// input to output...) up to however many stages specified.
|
||||
// Copyright (C) 2012 Schuyler Eldridge, Boston University
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
`timescale 1ns / 1ps
|
||||
module pipeline_registers
|
||||
(
|
||||
input clk,
|
||||
input reset_n,
|
||||
input [BIT_WIDTH-1:0] pipe_in,
|
||||
output reg [BIT_WIDTH-1:0] pipe_out
|
||||
);
|
||||
|
||||
// WARNING!!! THESE PARAMETERS ARE INTENDED TO BE MODIFIED IN A TOP
|
||||
// LEVEL MODULE. LOCAL CHANGES HERE WILL, MOST LIKELY, BE
|
||||
// OVERWRITTEN!
|
||||
parameter
|
||||
BIT_WIDTH = 10,
|
||||
NUMBER_OF_STAGES = 5;
|
||||
|
||||
// Main generate function for conditional hardware instantiation
|
||||
generate
|
||||
genvar i;
|
||||
// Pass-through case for the odd event that no pipeline stages are
|
||||
// specified.
|
||||
if (NUMBER_OF_STAGES == 0) begin
|
||||
always @ *
|
||||
pipe_out = pipe_in;
|
||||
end
|
||||
// Single flop case for a single stage pipeline
|
||||
else if (NUMBER_OF_STAGES == 1) begin
|
||||
always @ (posedge clk or negedge reset_n)
|
||||
pipe_out <= (!reset_n) ? 0 : pipe_in;
|
||||
end
|
||||
// Case for 2 or more pipeline stages
|
||||
else begin
|
||||
// Create the necessary regs
|
||||
reg [BIT_WIDTH*(NUMBER_OF_STAGES-1)-1:0] pipe_gen;
|
||||
// Create logic for the initial and final pipeline registers
|
||||
always @ (posedge clk or negedge reset_n) begin
|
||||
if (!reset_n) begin
|
||||
pipe_gen[BIT_WIDTH-1:0] <= 0;
|
||||
pipe_out <= 0;
|
||||
end
|
||||
else begin
|
||||
pipe_gen[BIT_WIDTH-1:0] <= pipe_in;
|
||||
pipe_out <= pipe_gen[BIT_WIDTH*(NUMBER_OF_STAGES-1)-1:BIT_WIDTH*(NUMBER_OF_STAGES-2)];
|
||||
end
|
||||
end
|
||||
// Create the intermediate pipeline registers if there are 3 or
|
||||
// more pipeline stages
|
||||
for (i = 1; i < NUMBER_OF_STAGES-1; i = i + 1) begin : pipeline
|
||||
always @ (posedge clk or negedge reset_n)
|
||||
pipe_gen[BIT_WIDTH*(i+1)-1:BIT_WIDTH*i] <= (!reset_n) ? 0 : pipe_gen[BIT_WIDTH*i-1:BIT_WIDTH*(i-1)];
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
175
samples/verilog/ps2_mouse.v
Executable file
175
samples/verilog/ps2_mouse.v
Executable file
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* PS2 Mouse Interface
|
||||
* Copyright (C) 2010 Donna Polehn <dpolehn@verizon.net>
|
||||
*
|
||||
* This file is part of the Zet processor. This processor is free
|
||||
* hardware; you can redistribute it and/or modify it under the terms of
|
||||
* the GNU General Public License as published by the Free Software
|
||||
* Foundation; either version 3, or (at your option) any later version.
|
||||
*
|
||||
* Zet is distrubuted in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Zet; see the file COPYING. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
module ps2_mouse (
|
||||
input clk, // Clock Input
|
||||
input reset, // Reset Input
|
||||
inout ps2_clk, // PS2 Clock, Bidirectional
|
||||
inout ps2_dat, // PS2 Data, Bidirectional
|
||||
|
||||
input [7:0] the_command, // Command to send to mouse
|
||||
input send_command, // Signal to send
|
||||
output command_was_sent, // Signal command finished sending
|
||||
output error_communication_timed_out,
|
||||
|
||||
output [7:0] received_data, // Received data
|
||||
output received_data_en, // If 1 - new data has been received
|
||||
output start_receiving_data,
|
||||
output wait_for_incoming_data
|
||||
);
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// Internal wires and registers Declarations
|
||||
// --------------------------------------------------------------------
|
||||
wire ps2_clk_posedge; // Internal Wires
|
||||
wire ps2_clk_negedge;
|
||||
|
||||
reg [7:0] idle_counter; // Internal Registers
|
||||
reg ps2_clk_reg;
|
||||
reg ps2_data_reg;
|
||||
reg last_ps2_clk;
|
||||
|
||||
reg [2:0] ns_ps2_transceiver; // State Machine Registers
|
||||
reg [2:0] s_ps2_transceiver;
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// Constant Declarations
|
||||
// --------------------------------------------------------------------
|
||||
localparam PS2_STATE_0_IDLE = 3'h0, // states
|
||||
PS2_STATE_1_DATA_IN = 3'h1,
|
||||
PS2_STATE_2_COMMAND_OUT = 3'h2,
|
||||
PS2_STATE_3_END_TRANSFER = 3'h3,
|
||||
PS2_STATE_4_END_DELAYED = 3'h4;
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// Finite State Machine(s)
|
||||
// --------------------------------------------------------------------
|
||||
always @(posedge clk) begin
|
||||
if(reset == 1'b1) s_ps2_transceiver <= PS2_STATE_0_IDLE;
|
||||
else s_ps2_transceiver <= ns_ps2_transceiver;
|
||||
end
|
||||
|
||||
always @(*) begin
|
||||
ns_ps2_transceiver = PS2_STATE_0_IDLE; // Defaults
|
||||
|
||||
case (s_ps2_transceiver)
|
||||
PS2_STATE_0_IDLE:
|
||||
begin
|
||||
if((idle_counter == 8'hFF) && (send_command == 1'b1))
|
||||
ns_ps2_transceiver = PS2_STATE_2_COMMAND_OUT;
|
||||
else if ((ps2_data_reg == 1'b0) && (ps2_clk_posedge == 1'b1))
|
||||
ns_ps2_transceiver = PS2_STATE_1_DATA_IN;
|
||||
else ns_ps2_transceiver = PS2_STATE_0_IDLE;
|
||||
end
|
||||
PS2_STATE_1_DATA_IN:
|
||||
begin
|
||||
// if((received_data_en == 1'b1) && (ps2_clk_posedge == 1'b1))
|
||||
if((received_data_en == 1'b1)) ns_ps2_transceiver = PS2_STATE_0_IDLE;
|
||||
else ns_ps2_transceiver = PS2_STATE_1_DATA_IN;
|
||||
end
|
||||
PS2_STATE_2_COMMAND_OUT:
|
||||
begin
|
||||
if((command_was_sent == 1'b1) || (error_communication_timed_out == 1'b1))
|
||||
ns_ps2_transceiver = PS2_STATE_3_END_TRANSFER;
|
||||
else ns_ps2_transceiver = PS2_STATE_2_COMMAND_OUT;
|
||||
end
|
||||
PS2_STATE_3_END_TRANSFER:
|
||||
begin
|
||||
if(send_command == 1'b0) ns_ps2_transceiver = PS2_STATE_0_IDLE;
|
||||
else if((ps2_data_reg == 1'b0) && (ps2_clk_posedge == 1'b1))
|
||||
ns_ps2_transceiver = PS2_STATE_4_END_DELAYED;
|
||||
else ns_ps2_transceiver = PS2_STATE_3_END_TRANSFER;
|
||||
end
|
||||
PS2_STATE_4_END_DELAYED:
|
||||
begin
|
||||
if(received_data_en == 1'b1) begin
|
||||
if(send_command == 1'b0) ns_ps2_transceiver = PS2_STATE_0_IDLE;
|
||||
else ns_ps2_transceiver = PS2_STATE_3_END_TRANSFER;
|
||||
end
|
||||
else ns_ps2_transceiver = PS2_STATE_4_END_DELAYED;
|
||||
end
|
||||
|
||||
default:
|
||||
ns_ps2_transceiver = PS2_STATE_0_IDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// Sequential logic
|
||||
// --------------------------------------------------------------------
|
||||
always @(posedge clk) begin
|
||||
if(reset == 1'b1) begin
|
||||
last_ps2_clk <= 1'b1;
|
||||
ps2_clk_reg <= 1'b1;
|
||||
ps2_data_reg <= 1'b1;
|
||||
end
|
||||
else begin
|
||||
last_ps2_clk <= ps2_clk_reg;
|
||||
ps2_clk_reg <= ps2_clk;
|
||||
ps2_data_reg <= ps2_dat;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if(reset == 1'b1) idle_counter <= 6'h00;
|
||||
else if((s_ps2_transceiver == PS2_STATE_0_IDLE) && (idle_counter != 8'hFF))
|
||||
idle_counter <= idle_counter + 6'h01;
|
||||
else if (s_ps2_transceiver != PS2_STATE_0_IDLE)
|
||||
idle_counter <= 6'h00;
|
||||
end
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// Combinational logic
|
||||
// --------------------------------------------------------------------
|
||||
assign ps2_clk_posedge = ((ps2_clk_reg == 1'b1) && (last_ps2_clk == 1'b0)) ? 1'b1 : 1'b0;
|
||||
assign ps2_clk_negedge = ((ps2_clk_reg == 1'b0) && (last_ps2_clk == 1'b1)) ? 1'b1 : 1'b0;
|
||||
|
||||
assign start_receiving_data = (s_ps2_transceiver == PS2_STATE_1_DATA_IN);
|
||||
assign wait_for_incoming_data = (s_ps2_transceiver == PS2_STATE_3_END_TRANSFER);
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// Internal Modules
|
||||
// --------------------------------------------------------------------
|
||||
ps2_mouse_cmdout mouse_cmdout (
|
||||
.clk (clk), // Inputs
|
||||
.reset (reset),
|
||||
.the_command (the_command),
|
||||
.send_command (send_command),
|
||||
.ps2_clk_posedge (ps2_clk_posedge),
|
||||
.ps2_clk_negedge (ps2_clk_negedge),
|
||||
.ps2_clk (ps2_clk), // Bidirectionals
|
||||
.ps2_dat (ps2_dat),
|
||||
.command_was_sent (command_was_sent), // Outputs
|
||||
.error_communication_timed_out (error_communication_timed_out)
|
||||
);
|
||||
|
||||
ps2_mouse_datain mouse_datain (
|
||||
.clk (clk), // Inputs
|
||||
.reset (reset),
|
||||
.wait_for_incoming_data (wait_for_incoming_data),
|
||||
.start_receiving_data (start_receiving_data),
|
||||
.ps2_clk_posedge (ps2_clk_posedge),
|
||||
.ps2_clk_negedge (ps2_clk_negedge),
|
||||
.ps2_data (ps2_data_reg),
|
||||
.received_data (received_data), // Outputs
|
||||
.received_data_en (received_data_en)
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
||||
49
samples/verilog/sign_extender.v
Executable file
49
samples/verilog/sign_extender.v
Executable file
@@ -0,0 +1,49 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Original Author: Schuyler Eldridge
|
||||
// Contact Point: Schuyler Eldridge (schuyler.eldridge@gmail.com)
|
||||
// sign_extender.v
|
||||
// Created: 5.16.2012
|
||||
// Modified: 5.16.2012
|
||||
//
|
||||
// Generic sign extension module
|
||||
//
|
||||
// Copyright (C) 2012 Schuyler Eldridge, Boston University
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
`timescale 1ns/1ps
|
||||
module sign_extender
|
||||
#(
|
||||
parameter
|
||||
INPUT_WIDTH = 8,
|
||||
OUTPUT_WIDTH = 16
|
||||
)
|
||||
(
|
||||
input [INPUT_WIDTH-1:0] original,
|
||||
output reg [OUTPUT_WIDTH-1:0] sign_extended_original
|
||||
);
|
||||
|
||||
wire [OUTPUT_WIDTH-INPUT_WIDTH-1:0] sign_extend;
|
||||
|
||||
generate
|
||||
genvar i;
|
||||
for (i = 0; i < OUTPUT_WIDTH-INPUT_WIDTH; i = i + 1) begin : gen_sign_extend
|
||||
assign sign_extend[i] = (original[INPUT_WIDTH-1]) ? 1'b1 : 1'b0;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
always @ * begin
|
||||
sign_extended_original = {sign_extend,original};
|
||||
end
|
||||
|
||||
endmodule
|
||||
154
samples/verilog/sqrt_pipelined.v
Executable file
154
samples/verilog/sqrt_pipelined.v
Executable file
@@ -0,0 +1,154 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Original Author: Schuyler Eldridge
|
||||
// Contact Point: Schuyler Eldridge (schuyler.eldridge@gmail.com)
|
||||
// sqrt_pipelined.v
|
||||
// Created: 4.2.2012
|
||||
// Modified: 4.5.2012
|
||||
//
|
||||
// Implements a fixed-point parameterized pipelined square root
|
||||
// operation on an unsigned input of any bit length. The number of
|
||||
// stages in the pipeline is equal to the number of output bits in the
|
||||
// computation. This pipelien sustains a throughput of one computation
|
||||
// per clock cycle.
|
||||
//
|
||||
// Copyright (C) 2012 Schuyler Eldridge, Boston University
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
`timescale 1ns / 1ps
|
||||
module sqrt_pipelined
|
||||
(
|
||||
input clk, // clock
|
||||
input reset_n, // asynchronous reset
|
||||
input start, // optional start signal
|
||||
input [INPUT_BITS-1:0] radicand, // unsigned radicand
|
||||
output reg data_valid, // optional data valid signal
|
||||
output reg [OUTPUT_BITS-1:0] root // unsigned root
|
||||
);
|
||||
|
||||
// WARNING!!! THESE PARAMETERS ARE INTENDED TO BE MODIFIED IN A TOP
|
||||
// LEVEL MODULE. LOCAL CHANGES HERE WILL, MOST LIKELY, BE
|
||||
// OVERWRITTEN!
|
||||
parameter
|
||||
INPUT_BITS = 16; // number of input bits (any integer)
|
||||
localparam
|
||||
OUTPUT_BITS = INPUT_BITS / 2 + INPUT_BITS % 2; // number of output bits
|
||||
|
||||
reg [OUTPUT_BITS-1:0] start_gen; // valid data propagation
|
||||
reg [OUTPUT_BITS*INPUT_BITS-1:0] root_gen; // root values
|
||||
reg [OUTPUT_BITS*INPUT_BITS-1:0] radicand_gen; // radicand values
|
||||
wire [OUTPUT_BITS*INPUT_BITS-1:0] mask_gen; // mask values
|
||||
|
||||
// This is the first stage of the pipeline.
|
||||
always @ (posedge clk or negedge reset_n) begin
|
||||
if (!reset_n) begin
|
||||
start_gen[0] <= 0;
|
||||
radicand_gen[INPUT_BITS-1:0] <= 0;
|
||||
root_gen[INPUT_BITS-1:0] <= 0;
|
||||
end
|
||||
else begin
|
||||
start_gen[0] <= start;
|
||||
if ( mask_gen[INPUT_BITS-1:0] <= radicand ) begin
|
||||
radicand_gen[INPUT_BITS-1:0] <= radicand - mask_gen[INPUT_BITS-1:0];
|
||||
root_gen[INPUT_BITS-1:0] <= mask_gen[INPUT_BITS-1:0];
|
||||
end
|
||||
else begin
|
||||
radicand_gen[INPUT_BITS-1:0] <= radicand;
|
||||
root_gen[INPUT_BITS-1:0] <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// Main generate loop to create the masks and pipeline stages.
|
||||
generate
|
||||
genvar i;
|
||||
// Generate all the mask values. These are built up in the
|
||||
// following fashion:
|
||||
// LAST MASK: 0x00...001
|
||||
// 0x00...004 Increasing # OUTPUT_BITS
|
||||
// 0x00...010 |
|
||||
// 0x00...040 v
|
||||
// ...
|
||||
// FIRST MASK: 0x10...000 # masks == # OUTPUT_BITS
|
||||
//
|
||||
// Note that the first mask used can either be of the 0x1... or
|
||||
// 0x4... variety. This is purely determined by the number of
|
||||
// computation stages. However, the last mask used will always be
|
||||
// 0x1 and the second to last mask used will always be 0x4.
|
||||
for (i = 0; i < OUTPUT_BITS; i = i + 1) begin: mask_4
|
||||
if (i % 2) // i is odd, this is a 4 mask
|
||||
assign mask_gen[INPUT_BITS*(OUTPUT_BITS-i)-1:INPUT_BITS*(OUTPUT_BITS-i-1)] = 4 << 4 * (i/2);
|
||||
else // i is even, this is a 1 mask
|
||||
assign mask_gen[INPUT_BITS*(OUTPUT_BITS-i)-1:INPUT_BITS*(OUTPUT_BITS-i-1)] = 1 << 4 * (i/2);
|
||||
end
|
||||
// Generate all the pipeline stages to compute the square root of
|
||||
// the input radicand stream. The general approach is to compare
|
||||
// the current values of the root plus the mask to the
|
||||
// radicand. If root/mask sum is greater than the radicand,
|
||||
// subtract the mask and the root from the radicand and store the
|
||||
// radicand for the next stage. Additionally, the root is
|
||||
// increased by the value of the mask and stored for the next
|
||||
// stage. If this test fails, then the radicand and the root
|
||||
// retain their value through to the next stage. The one weird
|
||||
// thing is that the mask indices appear to be incremented by one
|
||||
// additional position. This is not the case, however, because the
|
||||
// first mask is used in the first stage (always block after the
|
||||
// generate statement).
|
||||
for (i = 0; i < OUTPUT_BITS - 1; i = i + 1) begin: pipeline
|
||||
always @ (posedge clk or negedge reset_n) begin : pipeline_stage
|
||||
if (!reset_n) begin
|
||||
start_gen[i+1] <= 0;
|
||||
radicand_gen[INPUT_BITS*(i+2)-1:INPUT_BITS*(i+1)] <= 0;
|
||||
root_gen[INPUT_BITS*(i+2)-1:INPUT_BITS*(i+1)] <= 0;
|
||||
end
|
||||
else begin
|
||||
start_gen[i+1] <= start_gen[i];
|
||||
if ((root_gen[INPUT_BITS*(i+1)-1:INPUT_BITS*i] +
|
||||
mask_gen[INPUT_BITS*(i+2)-1:INPUT_BITS*(i+1)]) <= radicand_gen[INPUT_BITS*(i+1)-1:INPUT_BITS*i]) begin
|
||||
radicand_gen[INPUT_BITS*(i+2)-1:INPUT_BITS*(i+1)] <= radicand_gen[INPUT_BITS*(i+1)-1:INPUT_BITS*i] -
|
||||
mask_gen[INPUT_BITS*(i+2)-1:INPUT_BITS*(i+1)] -
|
||||
root_gen[INPUT_BITS*(i+1)-1:INPUT_BITS*i];
|
||||
root_gen[INPUT_BITS*(i+2)-1:INPUT_BITS*(i+1)] <= (root_gen[INPUT_BITS*(i+1)-1:INPUT_BITS*i] >> 1) +
|
||||
mask_gen[INPUT_BITS*(i+2)-1:INPUT_BITS*(i+1)];
|
||||
end
|
||||
else begin
|
||||
radicand_gen[INPUT_BITS*(i+2)-1:INPUT_BITS*(i+1)] <= radicand_gen[INPUT_BITS*(i+1)-1:INPUT_BITS*i];
|
||||
root_gen[INPUT_BITS*(i+2)-1:INPUT_BITS*(i+1)] <= root_gen[INPUT_BITS*(i+1)-1:INPUT_BITS*i] >> 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// This is the final stage which just implements a rounding
|
||||
// operation. This stage could be tacked on as a combinational logic
|
||||
// stage, but who cares about latency, anyway? This is NOT a true
|
||||
// rounding stage. In order to add convergent rounding, you need to
|
||||
// increase the input bit width by 2 (increase the number of
|
||||
// pipeline stages by 1) and implement rounding in the module that
|
||||
// instantiates this one.
|
||||
always @ (posedge clk or negedge reset_n) begin
|
||||
if (!reset_n) begin
|
||||
data_valid <= 0;
|
||||
root <= 0;
|
||||
end
|
||||
else begin
|
||||
data_valid <= start_gen[OUTPUT_BITS-1];
|
||||
if (root_gen[OUTPUT_BITS*INPUT_BITS-1:OUTPUT_BITS*INPUT_BITS-INPUT_BITS] > root_gen[OUTPUT_BITS*INPUT_BITS-1:OUTPUT_BITS*INPUT_BITS-INPUT_BITS])
|
||||
root <= root_gen[OUTPUT_BITS*INPUT_BITS-1:OUTPUT_BITS*INPUT_BITS-INPUT_BITS] + 1;
|
||||
else
|
||||
root <= root_gen[OUTPUT_BITS*INPUT_BITS-1:OUTPUT_BITS*INPUT_BITS-INPUT_BITS];
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
70
samples/verilog/t_button_debounce.v
Executable file
70
samples/verilog/t_button_debounce.v
Executable file
@@ -0,0 +1,70 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Original Author: Schuyler Eldridge
|
||||
// Contact Point: Schuyler Eldridge (schuyler.eldridge@gmail.com)
|
||||
// button_debounce.v
|
||||
// Created: 4.5.2012
|
||||
// Modified: 4.5.2012
|
||||
//
|
||||
// Testbench for button_debounce.v.
|
||||
//
|
||||
// Copyright (C) 2012 Schuyler Eldridge, Boston University
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
`timescale 1ns / 1ps
|
||||
module t_button_debounce();
|
||||
|
||||
parameter
|
||||
CLK_FREQUENCY = 66000000,
|
||||
DEBOUNCE_HZ = 2;
|
||||
|
||||
reg clk, reset_n, button;
|
||||
wire debounce;
|
||||
|
||||
button_debounce
|
||||
#(
|
||||
.CLK_FREQUENCY(CLK_FREQUENCY),
|
||||
.DEBOUNCE_HZ(DEBOUNCE_HZ)
|
||||
)
|
||||
button_debounce
|
||||
(
|
||||
.clk(clk),
|
||||
.reset_n(reset_n),
|
||||
.button(button),
|
||||
.debounce(debounce)
|
||||
);
|
||||
|
||||
initial begin
|
||||
clk = 1'bx; reset_n = 1'bx; button = 1'bx;
|
||||
#10 reset_n = 1;
|
||||
#10 reset_n = 0; clk = 0;
|
||||
#10 reset_n = 1;
|
||||
#10 button = 0;
|
||||
end
|
||||
|
||||
always
|
||||
#5 clk = ~clk;
|
||||
|
||||
always begin
|
||||
#100 button = ~button;
|
||||
#0.1 button = ~button;
|
||||
#0.1 button = ~button;
|
||||
#0.1 button = ~button;
|
||||
#0.1 button = ~button;
|
||||
#0.1 button = ~button;
|
||||
#0.1 button = ~button;
|
||||
#0.1 button = ~button;
|
||||
#0.1 button = ~button;
|
||||
end
|
||||
|
||||
endmodule
|
||||
75
samples/verilog/t_div_pipelined.v
Executable file
75
samples/verilog/t_div_pipelined.v
Executable file
@@ -0,0 +1,75 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Original Author: Schuyler Eldridge
|
||||
// Contact Point: Schuyler Eldridge (schuyler.eldridge@gmail.com)
|
||||
// div_pipelined.v
|
||||
// Created: 4.3.2012
|
||||
// Modified: 4.5.2012
|
||||
//
|
||||
// Testbench for div_pipelined.v
|
||||
//
|
||||
// Copyright (C) 2012 Schuyler Eldridge, Boston University
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
`timescale 1ns / 1ps
|
||||
module t_div_pipelined();
|
||||
|
||||
reg clk, start, reset_n;
|
||||
reg [7:0] dividend, divisor;
|
||||
wire data_valid, div_by_zero;
|
||||
wire [7:0] quotient, quotient_correct;
|
||||
|
||||
parameter
|
||||
BITS = 8;
|
||||
|
||||
div_pipelined
|
||||
#(
|
||||
.BITS(BITS)
|
||||
)
|
||||
div_pipelined
|
||||
(
|
||||
.clk(clk),
|
||||
.reset_n(reset_n),
|
||||
.dividend(dividend),
|
||||
.divisor(divisor),
|
||||
.quotient(quotient),
|
||||
.div_by_zero(div_by_zero),
|
||||
// .quotient_correct(quotient_correct),
|
||||
.start(start),
|
||||
.data_valid(data_valid)
|
||||
);
|
||||
|
||||
initial begin
|
||||
#10 reset_n = 0;
|
||||
#50 reset_n = 1;
|
||||
#1
|
||||
clk = 0;
|
||||
dividend = -1;
|
||||
divisor = 127;
|
||||
#1000 $finish;
|
||||
end
|
||||
|
||||
// always
|
||||
// #20 dividend = dividend + 1;
|
||||
|
||||
always begin
|
||||
#10 divisor = divisor - 1; start = 1;
|
||||
#10 start = 0;
|
||||
end
|
||||
|
||||
always
|
||||
#5 clk = ~clk;
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
77
samples/verilog/t_sqrt_pipelined.v
Executable file
77
samples/verilog/t_sqrt_pipelined.v
Executable file
@@ -0,0 +1,77 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Original Author: Schuyler Eldridge
|
||||
// Contact Point: Schuyler Eldridge (schuyler.eldridge@gmail.com)
|
||||
// t_sqrt_pipelined.v
|
||||
// Created: 4.2.2012
|
||||
// Modified: 4.5.2012
|
||||
//
|
||||
// Testbench for generic sqrt operation
|
||||
//
|
||||
// Copyright (C) 2012 Schuyler Eldridge, Boston University
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
`timescale 1ns / 1ps
|
||||
module t_sqrt_pipelined();
|
||||
|
||||
parameter
|
||||
INPUT_BITS = 4;
|
||||
localparam
|
||||
OUTPUT_BITS = INPUT_BITS / 2 + INPUT_BITS % 2;
|
||||
|
||||
reg [INPUT_BITS-1:0] radicand;
|
||||
reg clk, start, reset_n;
|
||||
|
||||
wire [OUTPUT_BITS-1:0] root;
|
||||
wire data_valid;
|
||||
// wire [7:0] root_good;
|
||||
|
||||
sqrt_pipelined
|
||||
#(
|
||||
.INPUT_BITS(INPUT_BITS)
|
||||
)
|
||||
sqrt_pipelined
|
||||
(
|
||||
.clk(clk),
|
||||
.reset_n(reset_n),
|
||||
.start(start),
|
||||
.radicand(radicand),
|
||||
.data_valid(data_valid),
|
||||
.root(root)
|
||||
);
|
||||
|
||||
initial begin
|
||||
radicand = 16'bx; clk = 1'bx; start = 1'bx; reset_n = 1'bx;;
|
||||
#10 reset_n = 0; clk = 0;
|
||||
#50 reset_n = 1; radicand = 0;
|
||||
// #40 radicand = 81; start = 1;
|
||||
// #10 radicand = 16'bx; start = 0;
|
||||
#10000 $finish;
|
||||
end
|
||||
|
||||
always
|
||||
#5 clk = ~clk;
|
||||
|
||||
always begin
|
||||
#10 radicand = radicand + 1; start = 1;
|
||||
#10 start = 0;
|
||||
end
|
||||
|
||||
|
||||
// always begin
|
||||
// #80 start = 1;
|
||||
// #10 start = 0;
|
||||
// end
|
||||
|
||||
endmodule
|
||||
|
||||
313
samples/verilog/vga.v
Executable file
313
samples/verilog/vga.v
Executable file
@@ -0,0 +1,313 @@
|
||||
/*
|
||||
* VGA top level file
|
||||
* Copyright (C) 2010 Zeus Gomez Marmolejo <zeus@aluzina.org>
|
||||
*
|
||||
* This file is part of the Zet processor. This processor is free
|
||||
* hardware; you can redistribute it and/or modify it under the terms of
|
||||
* the GNU General Public License as published by the Free Software
|
||||
* Foundation; either version 3, or (at your option) any later version.
|
||||
*
|
||||
* Zet is distrubuted in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Zet; see the file COPYING. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
module vga (
|
||||
// Wishbone signals
|
||||
input wb_clk_i, // 25 Mhz VDU clock
|
||||
input wb_rst_i,
|
||||
input [15:0] wb_dat_i,
|
||||
output [15:0] wb_dat_o,
|
||||
input [16:1] wb_adr_i,
|
||||
input wb_we_i,
|
||||
input wb_tga_i,
|
||||
input [ 1:0] wb_sel_i,
|
||||
input wb_stb_i,
|
||||
input wb_cyc_i,
|
||||
output wb_ack_o,
|
||||
|
||||
// VGA pad signals
|
||||
output [ 3:0] vga_red_o,
|
||||
output [ 3:0] vga_green_o,
|
||||
output [ 3:0] vga_blue_o,
|
||||
output horiz_sync,
|
||||
output vert_sync,
|
||||
|
||||
// CSR SRAM master interface
|
||||
output [17:1] csrm_adr_o,
|
||||
output [ 1:0] csrm_sel_o,
|
||||
output csrm_we_o,
|
||||
output [15:0] csrm_dat_o,
|
||||
input [15:0] csrm_dat_i
|
||||
);
|
||||
|
||||
|
||||
// Registers and nets
|
||||
//
|
||||
// csr address
|
||||
reg [17:1] csr_adr_i;
|
||||
reg csr_stb_i;
|
||||
|
||||
// Config wires
|
||||
wire [15:0] conf_wb_dat_o;
|
||||
wire conf_wb_ack_o;
|
||||
|
||||
// Mem wires
|
||||
wire [15:0] mem_wb_dat_o;
|
||||
wire mem_wb_ack_o;
|
||||
|
||||
// LCD wires
|
||||
wire [17:1] csr_adr_o;
|
||||
wire [15:0] csr_dat_i;
|
||||
wire csr_stb_o;
|
||||
wire v_retrace;
|
||||
wire vh_retrace;
|
||||
wire w_vert_sync;
|
||||
|
||||
// VGA configuration registers
|
||||
wire shift_reg1;
|
||||
wire graphics_alpha;
|
||||
wire memory_mapping1;
|
||||
wire [ 1:0] write_mode;
|
||||
wire [ 1:0] raster_op;
|
||||
wire read_mode;
|
||||
wire [ 7:0] bitmask;
|
||||
wire [ 3:0] set_reset;
|
||||
wire [ 3:0] enable_set_reset;
|
||||
wire [ 3:0] map_mask;
|
||||
wire x_dotclockdiv2;
|
||||
wire chain_four;
|
||||
wire [ 1:0] read_map_select;
|
||||
wire [ 3:0] color_compare;
|
||||
wire [ 3:0] color_dont_care;
|
||||
|
||||
// Wishbone master to SRAM
|
||||
wire [17:1] wbm_adr_o;
|
||||
wire [ 1:0] wbm_sel_o;
|
||||
wire wbm_we_o;
|
||||
wire [15:0] wbm_dat_o;
|
||||
wire [15:0] wbm_dat_i;
|
||||
wire wbm_stb_o;
|
||||
wire wbm_ack_i;
|
||||
|
||||
wire stb;
|
||||
|
||||
// CRT wires
|
||||
wire [ 5:0] cur_start;
|
||||
wire [ 5:0] cur_end;
|
||||
wire [15:0] start_addr;
|
||||
wire [ 4:0] vcursor;
|
||||
wire [ 6:0] hcursor;
|
||||
wire [ 6:0] horiz_total;
|
||||
wire [ 6:0] end_horiz;
|
||||
wire [ 6:0] st_hor_retr;
|
||||
wire [ 4:0] end_hor_retr;
|
||||
wire [ 9:0] vert_total;
|
||||
wire [ 9:0] end_vert;
|
||||
wire [ 9:0] st_ver_retr;
|
||||
wire [ 3:0] end_ver_retr;
|
||||
|
||||
// attribute_ctrl wires
|
||||
wire [3:0] pal_addr;
|
||||
wire pal_we;
|
||||
wire [7:0] pal_read;
|
||||
wire [7:0] pal_write;
|
||||
|
||||
// dac_regs wires
|
||||
wire dac_we;
|
||||
wire [1:0] dac_read_data_cycle;
|
||||
wire [7:0] dac_read_data_register;
|
||||
wire [3:0] dac_read_data;
|
||||
wire [1:0] dac_write_data_cycle;
|
||||
wire [7:0] dac_write_data_register;
|
||||
wire [3:0] dac_write_data;
|
||||
|
||||
// Module instances
|
||||
//
|
||||
vga_config_iface config_iface (
|
||||
.wb_clk_i (wb_clk_i),
|
||||
.wb_rst_i (wb_rst_i),
|
||||
.wb_dat_i (wb_dat_i),
|
||||
.wb_dat_o (conf_wb_dat_o),
|
||||
.wb_adr_i (wb_adr_i[4:1]),
|
||||
.wb_we_i (wb_we_i),
|
||||
.wb_sel_i (wb_sel_i),
|
||||
.wb_stb_i (stb & wb_tga_i),
|
||||
.wb_ack_o (conf_wb_ack_o),
|
||||
|
||||
.shift_reg1 (shift_reg1),
|
||||
.graphics_alpha (graphics_alpha),
|
||||
.memory_mapping1 (memory_mapping1),
|
||||
.write_mode (write_mode),
|
||||
.raster_op (raster_op),
|
||||
.read_mode (read_mode),
|
||||
.bitmask (bitmask),
|
||||
.set_reset (set_reset),
|
||||
.enable_set_reset (enable_set_reset),
|
||||
.map_mask (map_mask),
|
||||
.x_dotclockdiv2 (x_dotclockdiv2),
|
||||
.chain_four (chain_four),
|
||||
.read_map_select (read_map_select),
|
||||
.color_compare (color_compare),
|
||||
.color_dont_care (color_dont_care),
|
||||
|
||||
.pal_addr (pal_addr),
|
||||
.pal_we (pal_we),
|
||||
.pal_read (pal_read),
|
||||
.pal_write (pal_write),
|
||||
|
||||
.dac_we (dac_we),
|
||||
.dac_read_data_cycle (dac_read_data_cycle),
|
||||
.dac_read_data_register (dac_read_data_register),
|
||||
.dac_read_data (dac_read_data),
|
||||
.dac_write_data_cycle (dac_write_data_cycle),
|
||||
.dac_write_data_register (dac_write_data_register),
|
||||
.dac_write_data (dac_write_data),
|
||||
|
||||
.cur_start (cur_start),
|
||||
.cur_end (cur_end),
|
||||
.start_addr (start_addr),
|
||||
.vcursor (vcursor),
|
||||
.hcursor (hcursor),
|
||||
|
||||
.horiz_total (horiz_total),
|
||||
.end_horiz (end_horiz),
|
||||
.st_hor_retr (st_hor_retr),
|
||||
.end_hor_retr (end_hor_retr),
|
||||
.vert_total (vert_total),
|
||||
.end_vert (end_vert),
|
||||
.st_ver_retr (st_ver_retr),
|
||||
.end_ver_retr (end_ver_retr),
|
||||
|
||||
.v_retrace (v_retrace),
|
||||
.vh_retrace (vh_retrace)
|
||||
);
|
||||
|
||||
vga_lcd lcd (
|
||||
.clk (wb_clk_i),
|
||||
.rst (wb_rst_i),
|
||||
|
||||
.shift_reg1 (shift_reg1),
|
||||
.graphics_alpha (graphics_alpha),
|
||||
|
||||
.pal_addr (pal_addr),
|
||||
.pal_we (pal_we),
|
||||
.pal_read (pal_read),
|
||||
.pal_write (pal_write),
|
||||
|
||||
.dac_we (dac_we),
|
||||
.dac_read_data_cycle (dac_read_data_cycle),
|
||||
.dac_read_data_register (dac_read_data_register),
|
||||
.dac_read_data (dac_read_data),
|
||||
.dac_write_data_cycle (dac_write_data_cycle),
|
||||
.dac_write_data_register (dac_write_data_register),
|
||||
.dac_write_data (dac_write_data),
|
||||
|
||||
.csr_adr_o (csr_adr_o),
|
||||
.csr_dat_i (csr_dat_i),
|
||||
.csr_stb_o (csr_stb_o),
|
||||
|
||||
.vga_red_o (vga_red_o),
|
||||
.vga_green_o (vga_green_o),
|
||||
.vga_blue_o (vga_blue_o),
|
||||
.horiz_sync (horiz_sync),
|
||||
.vert_sync (w_vert_sync),
|
||||
|
||||
.cur_start (cur_start),
|
||||
.cur_end (cur_end),
|
||||
.vcursor (vcursor),
|
||||
.hcursor (hcursor),
|
||||
|
||||
.horiz_total (horiz_total),
|
||||
.end_horiz (end_horiz),
|
||||
.st_hor_retr (st_hor_retr),
|
||||
.end_hor_retr (end_hor_retr),
|
||||
.vert_total (vert_total),
|
||||
.end_vert (end_vert),
|
||||
.st_ver_retr (st_ver_retr),
|
||||
.end_ver_retr (end_ver_retr),
|
||||
|
||||
.x_dotclockdiv2 (x_dotclockdiv2),
|
||||
|
||||
.v_retrace (v_retrace),
|
||||
.vh_retrace (vh_retrace)
|
||||
);
|
||||
|
||||
vga_cpu_mem_iface cpu_mem_iface (
|
||||
.wb_clk_i (wb_clk_i),
|
||||
.wb_rst_i (wb_rst_i),
|
||||
|
||||
.wbs_adr_i (wb_adr_i),
|
||||
.wbs_sel_i (wb_sel_i),
|
||||
.wbs_we_i (wb_we_i),
|
||||
.wbs_dat_i (wb_dat_i),
|
||||
.wbs_dat_o (mem_wb_dat_o),
|
||||
.wbs_stb_i (stb & !wb_tga_i),
|
||||
.wbs_ack_o (mem_wb_ack_o),
|
||||
|
||||
.wbm_adr_o (wbm_adr_o),
|
||||
.wbm_sel_o (wbm_sel_o),
|
||||
.wbm_we_o (wbm_we_o),
|
||||
.wbm_dat_o (wbm_dat_o),
|
||||
.wbm_dat_i (wbm_dat_i),
|
||||
.wbm_stb_o (wbm_stb_o),
|
||||
.wbm_ack_i (wbm_ack_i),
|
||||
|
||||
.chain_four (chain_four),
|
||||
.memory_mapping1 (memory_mapping1),
|
||||
.write_mode (write_mode),
|
||||
.raster_op (raster_op),
|
||||
.read_mode (read_mode),
|
||||
.bitmask (bitmask),
|
||||
.set_reset (set_reset),
|
||||
.enable_set_reset (enable_set_reset),
|
||||
.map_mask (map_mask),
|
||||
.read_map_select (read_map_select),
|
||||
.color_compare (color_compare),
|
||||
.color_dont_care (color_dont_care)
|
||||
);
|
||||
|
||||
vga_mem_arbitrer mem_arbitrer (
|
||||
.clk_i (wb_clk_i),
|
||||
.rst_i (wb_rst_i),
|
||||
|
||||
.wb_adr_i (wbm_adr_o),
|
||||
.wb_sel_i (wbm_sel_o),
|
||||
.wb_we_i (wbm_we_o),
|
||||
.wb_dat_i (wbm_dat_o),
|
||||
.wb_dat_o (wbm_dat_i),
|
||||
.wb_stb_i (wbm_stb_o),
|
||||
.wb_ack_o (wbm_ack_i),
|
||||
|
||||
.csr_adr_i (csr_adr_i),
|
||||
.csr_dat_o (csr_dat_i),
|
||||
.csr_stb_i (csr_stb_i),
|
||||
|
||||
.csrm_adr_o (csrm_adr_o),
|
||||
.csrm_sel_o (csrm_sel_o),
|
||||
.csrm_we_o (csrm_we_o),
|
||||
.csrm_dat_o (csrm_dat_o),
|
||||
.csrm_dat_i (csrm_dat_i)
|
||||
);
|
||||
|
||||
// Continous assignments
|
||||
assign wb_dat_o = wb_tga_i ? conf_wb_dat_o : mem_wb_dat_o;
|
||||
assign wb_ack_o = wb_tga_i ? conf_wb_ack_o : mem_wb_ack_o;
|
||||
assign stb = wb_stb_i & wb_cyc_i;
|
||||
assign vert_sync = ~graphics_alpha ^ w_vert_sync;
|
||||
|
||||
// Behaviour
|
||||
// csr_adr_i
|
||||
always @(posedge wb_clk_i)
|
||||
csr_adr_i <= wb_rst_i ? 17'h0 : csr_adr_o + start_addr[15:1];
|
||||
|
||||
// csr_stb_i
|
||||
always @(posedge wb_clk_i)
|
||||
csr_stb_i <= wb_rst_i ? 1'b0 : csr_stb_o;
|
||||
|
||||
endmodule
|
||||
Reference in New Issue
Block a user