Library UniMath.Algebra.Universal.HVectors
Require Import UniMath.Foundations.All.
Require Import UniMath.Combinatorics.StandardFiniteSets.
Require Export UniMath.Combinatorics.Vectors.
Local Open Scope stn.
Basic definitions.
If v is a vector of types U1, U2, ..., Un, then hvec v is the product type U1 × (U2 × ... × Un). We introduce several basic operations on heterogeneous vectors: often they have the same syntax then the corresponding operation on plain vectors, and a name which begins with h.Definition hvec {n: nat} (v: vec UU n): UU.
Proof.
revert n v.
exact (vec_ind (λ _ _, UU) unit (λ x _ _ IHv, x × IHv)).
Defined.
Declare Scope hvec_scope.
Delimit Scope hvec_scope with hvec.
Local Open Scope hvec_scope.
Bind Scope hvec_scope with hvec.
Definition hnil : hvec vnil := tt.
Definition hcons {A: UU} (x: A) {n: nat} {v: vec UU n} (hv: hvec v) : hvec (A ::: v) := x ,, hv.
Notation "[( x ; .. ; y )]" := (hcons x .. (hcons y hnil) ..): hvec_scope.
Notation "[()]" := hnil (at level 0, format "[()]"): hvec_scope.
Infix ":::" := hcons: hvec_scope.
Definition functionToHVec {n: nat} {P: ⟦ n ⟧ → UU} (f: ∏ i: ⟦ n ⟧, P i) : hvec (make_vec P).
Proof.
induction n.
- exact [()].
- exact ((f firstelement) ::: (IHn (P ∘ dni_firstelement) (f ∘ dni_firstelement))).
Defined.
Definition hhd {A: UU} {n: nat} {v: vec UU n} (hv: hvec (A ::: v)): A := pr1 hv.
Definition htl {A: UU} {n: nat} {v: vec UU n} (hv: hvec (A ::: v)): hvec v := pr2 hv.
Definition hel {n: nat} {v: vec UU n} (hv: hvec v): ∏ i: ⟦ n ⟧, el v i.
Proof.
revert n v hv.
refine (vec_ind _ _ _).
- intros.
apply (fromempty (negnatlthn0 (pr1 i) (pr2 i))).
- intros x n xs IHxs.
induction i as [i iproof].
induction i.
+ exact (hhd hv).
+ exact (IHxs (htl hv) (make_stn _ i iproof)).
Defined.
Lemma hcons_paths {A: UU} (x y: A) {n: nat} (v: vec UU n) (xs ys: hvec v) (p: x = y) (ps: xs = ys)
: x ::: xs = y ::: ys.
Proof.
apply (map_on_two_paths (λ x xs, @hcons A x n v xs)) ; assumption.
Defined.
Lemma isofhlevelhvec {m: nat} {n: nat} (v: vec UU n) (levels: hvec (vec_map (isofhlevel m) v))
: isofhlevel m (hvec v).
Proof.
revert n v levels.
refine (vec_ind _ _ _).
- intro.
apply isofhlevelcontr.
apply iscontrunit.
- intros x n xs IHxs levels.
simpl.
apply isofhleveldirprod.
+ apply (pr1 levels).
+ apply (IHxs (pr2 levels)).
Defined.
Lemma hvec_vec_fill {A: UU} {n: nat}
: hvec (vec_fill A n) = vec A n.
Proof.
induction n.
- apply idpath.
- simpl.
apply maponpaths.
assumption.
Defined.
Level-1 heterogeneous vectors.
Miscellanea of operations on level-1 hvecs.
Definition h1const_is_vec {A: UU} {n: nat} (v: vec A n) (B: UU)
: hvec (vec_map (λ _, B) v) = vec B n.
Proof.
induction n.
- apply idpath.
- simpl.
apply maponpaths.
apply IHn.
Defined.
h1lower transforms a hvec (vec_map P v) into a vec when P is a constant map. Although
it would be possibile to define h1lower starting from h1const_is_vec, this would make difficult
to work by induction over v.
Definition h1lower {A: UU} {n: nat} {v: vec A n} {B: UU} (h1v: hvec (vec_map (λ _, B) v))
: vec B n.
Proof.
revert n v h1v.
refine (vec_ind _ _ _).
- apply idfun.
- intros x n xs IHxs h1v.
exact (vcons (hhd h1v) (IHxs (htl h1v))).
Defined.
Definition h1foldr {A: UU} {n: nat} {v: vec A n} {P: A → UU} {B: UU} (comb: ∏ (a: A), P a → B → B)
(s: B) (h1v: hvec (vec_map P v)): B.
Proof.
revert n v h1v.
refine (vec_ind _ _ _).
- intro.
exact s.
- intros x n xs IHxs.
simpl.
intro.
exact (comb _ (pr1 h1v) (IHxs (pr2 h1v))).
Defined.
Map for level-1 hvecs.
Definition h1map {A: UU} {n: nat} {v: vec A n} {P: A → UU}
{Q: A → UU} (f: ∏ (a: A), P a → Q a) (h1v: hvec (vec_map P v))
: hvec (vec_map Q v).
Proof.
revert n v f h1v.
refine (vec_ind _ _ _ ).
- intros.
exact [()].
- intros x n xs IHxs.
simpl.
intros f h1v.
exact (f x (pr1 h1v) ::: IHxs f (pr2 h1v)).
Defined.
Lemma h1map_idfun {A: UU} {n: nat} {v: vec A n} {P: A → UU} (h1v: hvec (vec_map P v))
: h1map (λ a: A, idfun (P a)) h1v = h1v.
Proof.
revert n v h1v.
refine (vec_ind _ _ _).
- induction h1v.
apply idpath.
- simpl.
intros x n xs IHxs h1v.
change h1v with (pr1 h1v ::: pr2 h1v).
apply maponpaths.
apply (IHxs (pr2 h1v)).
Defined.
Lemma h1map_compose {A: UU} {n: nat} {v: vec A n} {P: A → UU} {Q: A → UU} {R: A → UU}
(f: ∏ a: A, P a → Q a) (g: ∏ (a: A), Q a → R a) (h1v: hvec (vec_map P v))
: h1map g (h1map f h1v) = h1map (λ a: A, (g a) ∘ (f a)) h1v.
Proof.
revert n v h1v.
refine (vec_ind _ _ _).
- induction h1v.
apply idpath.
- simpl.
intros x n xs IHxs h1v.
apply maponpaths.
apply (IHxs (pr2 h1v)).
Defined.
{Q: A → UU} (f: ∏ (a: A), P a → Q a) (h1v: hvec (vec_map P v))
: hvec (vec_map Q v).
Proof.
revert n v f h1v.
refine (vec_ind _ _ _ ).
- intros.
exact [()].
- intros x n xs IHxs.
simpl.
intros f h1v.
exact (f x (pr1 h1v) ::: IHxs f (pr2 h1v)).
Defined.
Lemma h1map_idfun {A: UU} {n: nat} {v: vec A n} {P: A → UU} (h1v: hvec (vec_map P v))
: h1map (λ a: A, idfun (P a)) h1v = h1v.
Proof.
revert n v h1v.
refine (vec_ind _ _ _).
- induction h1v.
apply idpath.
- simpl.
intros x n xs IHxs h1v.
change h1v with (pr1 h1v ::: pr2 h1v).
apply maponpaths.
apply (IHxs (pr2 h1v)).
Defined.
Lemma h1map_compose {A: UU} {n: nat} {v: vec A n} {P: A → UU} {Q: A → UU} {R: A → UU}
(f: ∏ a: A, P a → Q a) (g: ∏ (a: A), Q a → R a) (h1v: hvec (vec_map P v))
: h1map g (h1map f h1v) = h1map (λ a: A, (g a) ∘ (f a)) h1v.
Proof.
revert n v h1v.
refine (vec_ind _ _ _).
- induction h1v.
apply idpath.
- simpl.
intros x n xs IHxs h1v.
apply maponpaths.
apply (IHxs (pr2 h1v)).
Defined.
h1map_vec is just the composition of h1map and h1lower, but it deserves a name
since it is used in the definition of level-2 hvecs (see later).
Definition h1map_vec {A: UU} {n: nat} {v: vec A n} {P: A → UU}
{B: UU} (f: ∏ (a: A), P a → B) (h1v: hvec (vec_map P v))
: vec B n := h1lower (h1map f h1v).
Level-2 heterogeneous vectors.
Definition h2map {A: UU} {n: nat} {v: vec A n} {P: A → UU} {h1v: hvec (vec_map P v)}
{Q: ∏ (a: A) (p: P a), UU} {R: ∏ (a: A) (p: P a), UU}
(f: ∏ (a: A) (p: P a), Q a p → R a p) (h2v: hvec (h1map_vec Q h1v))
: hvec (h1map_vec R h1v).
Proof.
revert n v f h1v h2v.
refine (vec_ind _ _ _ ).
- intros.
exact [()].
- intros x n xs IHv f h1v h2v.
exact (f x (pr1 h1v) (pr1 h2v) ::: IHv f (pr2 h1v) (pr2 h2v)).
Defined.
h1lift transforms a level-1 hvec into a level-2 hvec.
Definition h1lift {A: UU} {n: nat} {v: vec A n} {P: A → UU} (h1v: hvec (vec_map P v))
: hvec (h1map_vec (λ a _, P a) h1v).
Proof.
revert n v h1v.
refine (vec_ind _ _ _ ).
- intros.
exact [()].
- intros x n xs IHv h1v.
exact ((pr1 h1v) ::: IHv (pr2 h1v)).
Defined.
h2lower transforms a level-2 hvec h2v: hvec (hmap_vec Q h1v) into a level-1 hvec when
Q: ∏ a: A, P a → UU is constant on the argument of type P a.
Definition h2lower {A: UU} {n: nat} {v: vec A n} {P: A → UU} {h1v: hvec (vec_map P v)}
{Q: A → UU} (h2v: hvec (h1map_vec (λ a _, Q a) h1v))
: hvec (vec_map Q v).
Proof.
revert n v h1v h2v.
refine (vec_ind _ _ _).
- reflexivity.
- simpl.
intros x n xs IHxs h1v h2v.
split.
+ exact (pr1 h2v).
+ exact (IHxs (pr2 h1v) (pr2 h2v)).
Defined.
{Q: A → UU} (h2v: hvec (h1map_vec (λ a _, Q a) h1v))
: hvec (vec_map Q v).
Proof.
revert n v h1v h2v.
refine (vec_ind _ _ _).
- reflexivity.
- simpl.
intros x n xs IHxs h1v h2v.
split.
+ exact (pr1 h2v).
+ exact (IHxs (pr2 h1v) (pr2 h2v)).
Defined.
h2lower_h1map_h1lift and h1map_h1lift_as_h2map are two normalization lemmas relating level-1 and
level-2 hvecs.
Lemma h2lower_h1map_h1lift {A: UU} {n: nat} {v: vec A n} {P: A → UU}
{Q: ∏ (a: A), UU} (f: ∏ (a: A), P a → Q a) (h1v: hvec (vec_map P v))
: h2lower (h2map (λ a p _, f a p) (h1lift h1v)) = h1map f h1v.
Proof.
revert n v h1v.
refine (vec_ind _ _ _).
- reflexivity.
- intros x n xs IHxs h1v.
simpl.
apply maponpaths.
exact (IHxs (pr2 h1v)).
Defined.
Lemma h1map_h1lift_as_h2map {A: UU} {n: nat} {v: vec A n} {P: A → UU} (h1v: hvec (vec_map P v))
{Q: ∏ (a: A) (p: P a), UU} (h2v: hvec (h1map_vec Q h1v))
{R: ∏ (a: A) (p: P a), UU} (f: ∏ (a: A) (p: P a), R a p)
: h2map (λ a p _, f a p) (h1lift h1v) = h2map (λ a p _, f a p) h2v.
Proof.
revert n v h1v h2v.
refine (vec_ind _ _ _).
- reflexivity.
- simpl.
intros x n xs IHxs h1v h2v.
apply maponpaths.
exact (IHxs (pr2 h1v) (pr2 h2v)).
Defined.
Definition h2foldr {A: UU} {n: nat} {v: vec A n} {P: A → UU} {h1v: hvec (vec_map P v)}
{Q: ∏ (a: A) (p: P a), UU} {B: UU}
(comp: ∏ (a: A) (p: P a), Q a p → B → B) (s: B) (h2v: hvec (h1map_vec Q h1v))
: B.
Proof.
revert n v h1v h2v.
refine (vec_ind _ _ _).
- intros.
exact s.
- simpl.
intros x n xs IHxs h1v h2v.
exact (comp _ _ (pr1 h2v) (IHxs (pr2 h1v) (pr2 h2v))).
Defined.
h1map_path returns a proof that hmap f h1v and hmap g h1v are equal, provided that we
have a level-2 hvec h2path of proofs that the images of f and g on corresponding elements
of h1v are equal.
Lemma h1map_path {A: UU} {n: nat} {v: vec A n} {P: A → UU} {Q: A → UU} (f: ∏ a: A, P a → Q a)
(g: ∏ (a: A), P a → Q a) (h1v: hvec (vec_map P v))
(h2path: hvec (h1map_vec (λ a p, f a p = g a p) h1v))
: h1map f h1v = h1map g h1v.
Proof.
revert n v h1v h2path.
refine (vec_ind _ _ _).
- induction h1v.
reflexivity.
- simpl.
intros x n xs IHxs h1v h2path.
use map_on_two_paths.
+ exact (pr1 h2path).
+ exact (IHxs (pr2 h1v) (pr2 h2path)).
Defined.