I need to reason about vectors' permutations in Coq. The standard library only includes permutation definitions for lists. As my first attempt, I tried to mimic it for vectors as:
Inductive VPermutation: forall n, vector A n -> vector A n -> Prop :=
| vperm_nil: VPermutation 0 [] []
| vperm_skip {n} x l l' : VPermutation n l l' -> VPermutation (S n) (x::l) (x::l')
| vperm_swap {n} x y l : VPermutation (S (S n)) (y::x::l) (x::y::l)
| vperm_trans {n} l l' l'' :
VPermutation n l l' -> VPermutation n l' l'' -> VPermutation n l l''.
I quickly realized that there are many permutation lemmas, already proven on lists which needs to be also proven for vectors. It is a lot of work, and I thought that perhaps I can take a shortcut by proving the following lemma:
Lemma ListVecPermutation {n} {l1 l2} {v1 v2}:
l1 = list_of_vec v1 ->
l2 = list_of_vec v2 ->
Permutation l1 l2 ->
VPermutation A n v1 v2.
Proof.
It would allow me to re-use list permutation lemmas for vectors as long as I can show that vectors could be converted to corresponding lists.
Aside: I am using list_of_vec
definition from coq-color
library as it seems to be easier to reason about than VectorDef.to_list
.
Fixpoint list_of_vec n (v : vector A n) : list A :=
match v with
| Vnil => nil
| Vcons x v => x :: list_of_vec v
end.
Proving this lemma ended being tricky. I tried to do this by induction:
Proof.
intros H1 H2 P.
revert H1 H2.
dependent induction P.
-
intros H1 H2.
dep_destruct v1; auto.
dep_destruct v2; auto.
inversion H1.
-
But it leaves me with inductive hypotehsis which is not sufficiently generalized and depends on v1
and v2
:
IHP : l = list_of_vec v1 -> l' = list_of_vec v2 -> VPermutation A n v1 v2
I will be glad to hear suggestions on the approach in general and my formulation of it.
P.S. The full self-contained example: https://gist.github.com/vzaliva/c31300aa484ff6ad2089cb0c45c3828a
seq
andtuple
library available in math-comp. - ejgallego