-
Notifications
You must be signed in to change notification settings - Fork 53
Expand file tree
/
Copy pathMember.v
More file actions
139 lines (125 loc) · 3.86 KB
/
Copy pathMember.v
File metadata and controls
139 lines (125 loc) · 3.86 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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
(** [member] is the proof relevant version of [In] **)
Require Import Coq.Lists.List.
Require Import Relations RelationClasses.
Require Import ExtLib.Core.RelDec.
Require Import ExtLib.Data.SigT.
Require Import ExtLib.Data.ListNth.
Require Import ExtLib.Data.Option.
Require Import ExtLib.Tactics.Injection.
Require Import ExtLib.Tactics.EqDep.
Set Implicit Arguments.
Set Strict Implicit.
Set Asymmetric Patterns.
Set Asymmetric Patterns No Implicits.
Section member.
Context {T : Type}.
Inductive member (a : T) : list T -> Type :=
| MZ : forall ls, member a (a :: ls)
| MN : forall l ls, member a ls -> member a (l :: ls).
Section to_nat.
Variable a : T.
Fixpoint to_nat {ls} (m : member a ls) : nat :=
match m with
| MZ _ => 0
| MN _ _ m => S (to_nat m)
end.
End to_nat.
Lemma member_eta
: forall x ls (m : member x ls),
m = match m in member _ ls
return member x ls
with
| MZ ls => MZ x ls
| MN _ _ n => MN _ n
end.
Proof.
destruct m; auto.
Qed.
Lemma member_case
: forall x ls (m : member x ls),
match ls as ls return member x ls -> Prop with
| nil => fun _ => False
| l :: ls' => fun m =>
(exists (pf : l = x),
m = match pf in _ = z return member z (l :: ls') with
| eq_refl => MZ _ ls'
end)
\/ exists m' : member x ls',
m = MN _ m'
end m.
Proof.
induction m.
{ left. exists eq_refl. reflexivity. }
{ right. eauto. }
Qed.
Lemma to_nat_eq_member_eq
: forall {_ : EqDec T (@eq T)} x ls (a b : member x ls),
to_nat a = to_nat b ->
a = b.
Proof.
induction a; intros.
{ destruct (member_case b).
{ destruct H0. subst.
rewrite (UIP_refl x0). reflexivity. }
{ destruct H0. subst.
simpl in *. congruence. } }
{ destruct (member_case b).
{ exfalso. destruct H0. subst. simpl in *. congruence. }
{ destruct H0. subst. simpl in *.
inversion H; clear H; subst.
eapply IHa in H1. f_equal. assumption. } }
Qed.
Fixpoint nth_member (ls : list T) (n : nat) {struct n}
: option { x : T & member x ls } :=
match ls as ls return option { x : T & member x ls } with
| nil => None
| l :: ls =>
match n with
| 0 => Some (@existT _ (fun x => member x (l :: ls)) l (MZ _ _))
| S n =>
match nth_member ls n with
| Some (existT v m) => Some (@existT _ _ v (MN _ m))
| None => None
end
end
end.
Definition get_next ls y x (m : member x (y :: ls))
: option (member x ls) :=
match m in member _ ls'
return match ls' with
| nil => unit
| l' :: ls' => option (member x ls')
end
with
| MZ _ => None
| MN _ _ m => Some m
end.
Instance Injective_MN x y ls m m' : Injective (@MN x y ls m = @MN x y ls m').
Proof.
refine {| result := m = m' |}.
intro.
assert (get_next (MN y m) = get_next (MN y m')).
{ rewrite H. reflexivity. }
{ simpl in *. inversion H0. reflexivity. }
Defined.
Lemma nth_member_nth_error
: forall ls p,
nth_member ls (to_nat (projT2 p)) = Some p <->
nth_error ls (to_nat (projT2 p)) = Some (projT1 p).
Proof.
destruct p. simpl in *.
induction m.
{ simpl. split; auto. }
{ simpl. split.
{ intros. destruct (nth_member ls (to_nat m)); try congruence.
{ destruct s.
inv_all. subst. inv_all. subst.
apply IHm. reflexivity. } }
{ intros.
eapply IHm in H. rewrite H. reflexivity. } }
Qed.
Lemma member_In : forall ls (t : T), member t ls -> List.In t ls.
Proof.
induction 1; simpl; auto.
Qed.
End member.