-
Notifications
You must be signed in to change notification settings - Fork 53
Expand file tree
/
Copy pathFin.v
More file actions
116 lines (103 loc) · 3.12 KB
/
Copy pathFin.v
File metadata and controls
116 lines (103 loc) · 3.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
(** Numbers up to @n@ **)
Require Coq.Lists.List.
Require Import ExtLib.Core.RelDec.
Require Import ExtLib.Tactics.EqDep.
Require Import ExtLib.Tactics.Injection.
Set Implicit Arguments.
Set Strict Implicit.
Set Asymmetric Patterns.
Set Asymmetric Patterns No Implicits.
(** `fin n` corresponds to "naturals less than `n`",
i.e. a finite set of size n
**)
Inductive fin : nat -> Type :=
| F0 : forall {n}, fin (S n)
| FS : forall {n}, fin n -> fin (S n).
Fixpoint fin_all (n : nat) : list (fin n) :=
match n as n return list (fin n) with
| 0 => nil
| S n => @F0 n :: List.map (@FS _) (fin_all n)
end%list.
Theorem fin_all_In : forall {n} (f : fin n),
List.In f (fin_all n).
Proof.
induction n; intros.
inversion f.
remember (S n). destruct f.
simpl; firstorder.
inversion Heqn0. subst.
simpl. right. apply List.in_map. auto.
Qed.
Theorem fin_case : forall n (f : fin (S n)),
f = F0 \/ exists f', f = FS f'.
Proof.
intros. generalize (fin_all_In f). intros.
destruct H; auto.
eapply List.in_map_iff in H. right. destruct H.
exists x. intuition.
Qed.
Definition fin0_elim (f : fin 0) : forall T, T :=
match f in fin n return match n with
| 0 => forall T, T
| _ => unit
end with
| F0 _ => tt
| FS _ _ => tt
end.
Fixpoint pf_lt (n m : nat) : Prop :=
match n , m with
| 0 , S _ => True
| S n , S m => pf_lt n m
| _ , _ => False
end.
Fixpoint make (m n : nat) {struct m} : pf_lt n m -> fin m :=
match n as n , m as m return pf_lt n m -> fin m with
| 0 , 0 => @False_rect _
| 0 , S n => fun _ => F0
| S n , 0 => @False_rect _
| S n , S m => fun pf => FS (make m n pf)
end.
Notation "'##' n" := (@make _ n I) (at level 0).
Global Instance Injective_FS {n : nat} (a b : fin n)
: Injective (FS a = FS b).
refine {| result := a = b |}.
abstract (intro ; inversion H ; eapply inj_pair2 in H1 ; assumption).
Defined.
Fixpoint fin_eq_dec {n} (x : fin n) {struct x} : fin n -> bool :=
match x in fin n' return fin n' -> bool with
| F0 _ => fun y => match y with
| F0 _ => true
| _ => false
end
| FS n' x' => fun y : fin (S n') =>
match y in fin n'' return (match n'' with
| 0 => unit
| S n'' => fin n''
end -> bool) -> bool with
| F0 _ => fun _ => false
| FS _ y' => fun f => f y'
end (fun y => fin_eq_dec x' y)
end.
Global Instance RelDec_fin_eq (n : nat) : RelDec (@eq (fin n)) :=
{ rel_dec := fin_eq_dec }.
Global Instance RelDec_Correct_fin_eq (n : nat)
: RelDec_Correct (RelDec_fin_eq n).
Proof.
constructor.
induction x. simpl.
intro. destruct (fin_case y) ; subst.
intuition.
destruct H ; subst.
intuition; auto with *; try congruence.
(* inversion H.*)
intro ; destruct (fin_case y) ; subst ; simpl.
intuition ; try congruence.
inversion H.
destruct H ; subst.
split ; intro.
f_equal ; eauto.
eapply IHx.
eapply H.
inv_all ; subst.
apply IHx. reflexivity.
Qed.