-
Notifications
You must be signed in to change notification settings - Fork 0
/
Matrix.v
203 lines (191 loc) · 5.26 KB
/
Matrix.v
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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
Module MineSweeper.
Require Import Arith Omega.
Set Implicit Arguments.
Section vector.
Variable A: Type.
Inductive vector : nat -> Type :=
| vnil : vector 0
| vcons : forall (a:A) (n:nat), vector n -> vector (S n)
.
End vector.
Implicit Arguments vnil [A].
Delimit Scope vector_scope with vec.
Open Scope vector_scope.
Infix "::" := vcons
(at level 60, right associativity)
: vector_scope.
Notation "[]" := vnil: vector_scope.
Notation "[ x , .. , z ]" :=
(x :: .. (z :: []) ..)
(at level 0)
: vector_scope.
Section vmap.
Variables X Y: Type.
Variable f: X -> Y.
Fixpoint vmap {n} (v: vector X n): vector Y n :=
match v with
| vnil => vnil
| vcons a _ v' => vcons (f a) (vmap v')
end.
End vmap.
Section vzip.
Variables X Y Z: Type.
Variable f: X -> Y -> Z.
Fixpoint vzip {n} (v1: vector X n) (v2: vector Y n): vector Z n.
destruct v1.
constructor.
inversion v2.
constructor.
apply f. exact a. exact a0.
apply vzip. exact v1. exact X0.
Defined.
End vzip.
Definition vi0 {m}: 0 < S m := lt_0_Sn m.
Definition viS {n m}: n < m -> S n < S m := lt_n_S n m.
Notation "!0" := vi0.
Notation "!+ i" := (viS i)
(at level 5, right associativity).
Section viget.
Variable A: Type.
Lemma lt_0_False: forall n, n < 0 -> False. intros. omega. Qed.
Fixpoint viget {n} (v: vector A n) m (H: m < n): A.
destruct v.
(* vnil *)
apply lt_0_False in H. destruct H.
destruct m.
(* 0 *)
exact a.
(* (S _) *)
apply viget with (n:=n) (m:=m).
exact v. apply lt_S_n. exact H.
Defined.
End viget.
Notation "v '_[' i ]" := (viget v i)
(at level 7, left associativity)
: vector_scope.
Section viset.
Variable A: Type.
Fixpoint viset {n} (v: vector A n) m (H: m < n) (b:A) {struct v}: vector A n.
destruct v as [|a n' v'].
(* vnil => False *)
apply lt_0_False in H. destruct H.
destruct m.
(* 0 *)
exact (b::v').
(* S _ *)
apply (fun v''=> a::v'').
apply viset with m; try assumption.
apply lt_S_n. assumption.
Defined.
End viset.
Notation "v '_[' i ] / b" := (viset v i b)
(at level 7, b at level 50, left associativity)
: vector_scope.
Delimit Scope matrix_scope with mat.
Open Scope matrix_scope.
Notation "'mlengths'" := (vector nat)
(at level 0)
: matrix_scope.
Section matrix.
Variable A: Type.
Inductive matrix: forall n, mlengths n -> Type :=
| mscalar: A -> matrix []
| mvector: forall n m v,
vector (@matrix n v) m ->
@matrix (S n) (m::v)
.
End matrix.
Notation "''{}'" := (mvector []%vec): matrix_scope.
Notation "'#{' x , .. , z }" :=
(mvector (x :: .. (z :: []) ..)%vec)
(at level 0)
: matrix_scope.
Notation "''{' x , .. , z }" :=
(mvector (mscalar x :: .. (mscalar z :: []) ..)%vec)
(at level 0)
: matrix_scope.
Section fillvec.
Variable A: Type.
Variable a: A.
Fixpoint fillvec n: vector A n :=
match n with
| O => vnil
| S n' => a :: fillvec n'
end.
End fillvec.
Section fillmat.
Variable A: Type.
Variable a: A.
Fixpoint fillmat n (v: mlengths n): matrix A v.
destruct n as [|n'].
(* n = O *)
dependent inversion v. constructor. assumption.
(* n = S n' *)
dependent inversion v; subst.
constructor.
apply fillvec.
apply fillmat.
Defined.
End fillmat.
Section mmap.
Variables A B: Type.
Variable f: A -> B.
Fixpoint mmap n (v: mlengths n) (m: matrix A v): matrix B v.
destruct n as [|n'].
(* n = O *)
dependent inversion v; subst.
inversion m; subst.
apply mscalar. apply f. assumption.
(* n = S n' *)
inversion m as [|l'' m'' v'']; subst. clear H.
constructor.
specialize (mmap n' v'').
apply (vmap mmap).
exact X.
Defined.
End mmap.
Require Import Eqdep_dec.
Section mzip.
Variables A B C: Type.
Variable f: A -> B -> C.
Fixpoint mzip n (v: mlengths n)
(m1: matrix A v) (m2: matrix B v): matrix C v.
destruct n as [|n'].
(* n = 0 *)
inversion m1. inversion m2.
apply mscalar; apply f; assumption.
(* n = S n' *)
inversion m1 as [|? m1' l1 v1 H1 Heq1]; subst.
inversion m2 as [|? m2' l2 v2 H2 Heq2]; subst.
apply (inj_pair2_eq_dec _ eq_nat_dec _ _ _) in Heq1.
apply (inj_pair2_eq_dec _ eq_nat_dec _ _ _) in Heq2.
assert (Heq: m1' :: l1 = m2' :: l2).
eapply eq_trans. apply Heq1. symmetry. exact Heq2.
clear Heq1. clear Heq2.
assert (Heqm: m1' = m2') by (inversion Heq; reflexivity).
assert (Heql: l1 = l2).
inversion Heq.
apply (Eqdep_dec.inj_pair2_eq_dec _ eq_nat_dec _ _ _) in H1.
exact H1.
clear Heq. rename l2 into l. rename m2' into m'. subst.
apply mvector.
specialize (mzip n' l).
apply (vzip mzip); assumption.
Defined.
End mzip.
Example mzip_ex1: mzip plus '{1,2} '{3,4} = '{4,6}.
Proof.
simpl.
(*
1 subgoal
______________________________________(1/1)
eq_rect_r
(fun l1 : mlengths 0 => vector (matrix nat l1) 2 -> matrix nat (2 :: l1))
(fun v1 : vector (matrix nat []) 2 =>
eq_rect_r
(fun m1' : nat => vector (matrix nat []) m1' -> matrix nat [m1'])
(fun v0 : vector (matrix nat []) 2 =>
mvector
......
*)
Abort.