Library UniMath.Algebra.Universal.HVectors
Heterogeneous vectors.
Gianluca Amato, Matteo Calosci, Marco Maggesi, Cosimo Perini Brogi 2019-2024.Require Import UniMath.Foundations.All.
Require Import UniMath.MoreFoundations.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 hvec_ind (P : ∏ n (v: vec UU n), hvec v → UU) :
P 0 [()] [()]
→ (∏ X x n (v: vec UU n) (hv : hvec v), P n v hv → P (S n) (vcons X v) (x ::: hv))
→ (∏ n (v: vec UU n) (hv : hvec v), P n v hv).
Proof.
intros H0 HI n v hv.
induction n as [|n IHn].
- induction v, hv.
exact H0.
- change v with (pr1 v ::: pr2 v)%vec.
change hv with (pr1 hv ::: pr2 hv).
apply HI, IHn.
Defined.
Definition hvec_ind_fixedv {v:∏ n:nat, vec UU n} (P : ∏ n , hvec (v n) → UU) :
(∏ hv0 , P 0 hv0)
→ (∏ n , (∏ hv , P n hv) → (∏ hv, P (S n) hv) )
→ (∏ n (hv : hvec (v n)), P n hv).
Proof.
intros H0 HI n hv.
induction n as [|n IHn].
- use H0.
- change hv with (pr1 hv ::: pr2 hv).
apply HI, IHn.
Defined.
Definition hvec_ind' {n:nat} {v: vec UU n} (P : ∏ n' (v': vec UU n'), hvec v' → UU)
: P 0 [()] [()]
→ (∏ X x m (w: vec UU m) (hw : hvec w), m<n → P m w hw → P (S m) (vcons X w) (x ::: hw))
→ ∏ hv : hvec v, P n v hv.
Proof.
intros H0 HI hv.
induction n as [| n IHn].
- induction v, hv.
exact H0.
- change v with (pr1 v ::: pr2 v)%vec.
change hv with (pr1 hv ::: pr2 hv).
apply HI.
* apply natlthnsn.
* apply IHn.
intros X x m w hw Hm HIm.
apply HI.
+ apply (istransnatlth _ n).
++ exact Hm.
++ apply natlthnsn.
+ exact HIm.
Defined.
Definition hdrop {n:nat} {P: ⟦ S n ⟧ → UU} (f: ∏ i: ⟦ S n ⟧, P i) : (∏ i: ⟦ n ⟧, P (dni_firstelement i)) := f ∘ dni_firstelement.
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 make_hvec {n: nat} {v: vec UU n} (f: ∏ i: ⟦ n ⟧, el v i) : hvec v.
Proof.
revert n v f.
use vec_ind.
+ intro. exact tt.
+ intros X n v IH f.
exists (f firstelement).
exact (IH (hdrop f)).
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.
Some identities for computing hel.
Lemma hel_make_hvec {n} {v: vec UU n} (f : ∏ i: ⟦ n ⟧, el v i) : hel (make_hvec f) ~ f .
Proof.
intro i.
induction n as [|m meq].
- exact (fromstn0 i).
- induction i as (j,jlt).
induction j as [|k _].
+
use (stn_predicate (λ z , hel (make_hvec f) z = f z) 0 _ jlt).
{ reflexivity. }
apply idpath.
+ use meq.
Defined.
Lemma hel_make_hvec_fun {n} {v: vec UU n} (f : ∏ i: ⟦ n ⟧, el v i) : hel (make_hvec f) = f.
Proof.
apply funextsec.
apply hel_make_hvec.
Defined.
Lemma hel_hcons_htl {n} {v: vec UU n} (hv : hvec v) {X:UU} (x : X) (i : ⟦ n ⟧) :
hel (x ::: hv) (dni_firstelement i) = hel hv i.
Proof.
apply idpath.
Defined.
Lemma hel_hcons_hhd {n} {v: vec UU n} (hv : hvec v) {X:UU} (x : X) :
hel (x ::: hv) (firstelement) = x.
Proof.
reflexivity.
Defined.
Lemma drop_hel {n} {v: vec UU (S n)} (hv : hvec v) (i: ⟦ n ⟧ ) : hdrop (hel hv) i = hel (htl hv) i.
Proof.
apply idpath.
Defined.
Lemma hel_htl {n} {v: vec UU (S n)} (hv : hvec v) (i : ⟦ n ⟧)
: hel (htl hv) i = hdrop (hel hv) i.
Proof.
apply idpath.
Defined.
Lemma hvec_extens {n} {v: vec UU n} {hu hv: hvec v} :
(∏ i : ⟦ n ⟧, hel hu i = hel hv i) → hu = hv.
Proof.
intros H.
revert n v hu hv H.
use vec_ind.
- cbn beta.
intros.
use proofirrelevance.
use isapropunit.
- cbn beta.
intros X n v IH hv hu H.
induction hv as (xv,htv).
induction hu as (xu,htu).
use dirprod_paths.
* use (H firstelement).
* use IH.
intro i.
use (H (dni_firstelement i)).
Defined.
Lemma make_hvec_hel {n} {v: vec UU n} (hv : hvec v) : (make_hvec (hel hv)) = hv .
Proof.
apply hvec_extens.
intros i.
rewrite hel_make_hvec.
reflexivity.
Defined.
Definition helf_weq {n: nat} {v: vec UU n} : (hvec v) ≃ ∏ i: ⟦ n ⟧, el v i.
Proof.
use weq_iso.
+ use hel.
+ use make_hvec.
+ use make_hvec_hel.
+ use hel_make_hvec_fun.
Defined.
Lemma inv_helf_weq {n:nat} {v:vec UU n} : invmap (helf_weq (n:=n) (v:=v)) = make_hvec.
Proof.
use funextsec.
intro.
use (invmaponpathsweq helf_weq).
rewrite homotweqinvweq.
simpl.
rewrite hel_make_hvec_fun.
apply idpath.
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.
Lemma transportf_hvec' {n: nat} {v v': vec UU (S n)}
(p : v = v')
(hv : hvec v)
: transportf hvec p hv
= transportf (idfun UU) (maponpaths hd p) (hhd hv) ::: transportf hvec (maponpaths tl p) (htl hv).
Proof.
induction p.
reflexivity.
Qed.
Lemma transportf_hvec {n: nat} {v v': vec UU (S n)}
(p : v = v')
(hv : hvec v)
: transportf hvec p hv
= (transportf hd p (hhd hv)) ::: (transportf (hvec ∘ tl) p (htl hv)).
Proof.
induction p.
reflexivity.
Defined.
Lemma transportf_hvec_vecS_eq {n: nat} {v v': vec UU (S n)}
(p : hd v = hd v')
(q : tl v = tl v')
(hv : hvec v)
: transportf hvec (vecS_eq p q) hv
= (transportf (idfun UU) p (hhd hv)) ::: (transportf hvec q (htl hv)).
Proof.
destruct v as [v_hd v_tl].
destruct v' as [v'_hd v'_tl].
induction (p: v_hd = v'_hd).
induction (q: v_tl = v'_tl).
apply idpath.
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 h1lower_vec_map_comp {I : UU} {n: nat} {v: vec I n}
(A : ∏ (i: I), UU)
(hv : hvec (vec_map (λ (_:I),UU) v))
: h1lower hv
= h1lower (transportf hvec (vec_map_comp A (λ _ : UU, UU) v) hv).
Proof.
revert n v hv.
use vec_ind.
- use idpath.
- intros x n v IH hv.
eapply pathscomp0.
2:{
apply pathsinv0.
eapply (maponpaths h1lower).
use transportf_hvec_vecS_eq.
}
use dirprod_paths.
+ apply idpath.
+ use IH.
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 involving 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 (hhd h1v) ::: IHxs f (htl h1v)).
Defined.
Definition h01map {A: UU} {n: nat} {P: A → UU}
(f: ∏ (a: A), P a) (v : vec A n)
: hvec (vec_map P v).
Proof.
use (vec_ind (λ n v, hvec (vec_map P v))).
- exact tt.
- intros x n' v' hv.
exact (f x ::: hv).
Defined.
Lemma h01maph1lower {I : UU} {n: nat} {v: vec I n}
(A : ∏ (i: I), UU)
(R : UU → UU)
(r : ∏ (i: I), R (A i))
(s : ∏ (X:UU), R X → UU)
: vec_map (λ (i:I), s (A i) (r i)) v
= h1lower (h01map (λ (i:I), s (A i) (r i)) v).
Proof.
revert n v.
use vec_ind.
- apply idpath.
- intros x n v IH.
use dirprod_paths.
+ apply idpath.
+ use IH.
Defined.
Lemma vec_map_conspath {A: UU} {n: nat} {a:A} {v: vec A n} {P: A → UU}
: vcons (P a) (vec_map P v) = vec_map P (vcons a v).
Proof.
apply idpath.
Defined.
Lemma h1map_conspath {A: UU} {n: nat} {a:A} {v: vec A n} {P: A → UU}
{Q: A → UU} (f: ∏ (a: A), P a → Q a)
(h1hd : P a) (h1v: hvec (vec_map P v))
: h1map f (h1hd ::: h1v : hvec (vec_map P (vcons a v)))
= (f a h1hd) ::: h1map f h1v.
Proof.
apply idpath.
Defined.
Lemma h1h01map_comp
{A: UU} {n: nat} {v: vec A n} {P: A → UU}
{Q: A → UU} (f: ∏ (a: A), P a) (g: ∏ (a: A), P a → Q a)
: h1map g (h01map f v) = h01map (λ a, g a (f a)) v.
Proof.
use (vec_ind
(λ n v, h1map g (h01map f v) = h01map (λ a : A, g a (f a)) v)).
- apply idpath.
- intros x n' v' IH.
simpl.
use dirprod_paths.
+ apply idpath.
+ use IH.
Defined.
Lemma h1map_transport_vec_map_comp
{I : UU} {n: nat} {v: vec I n}
(A : ∏ (i: I), UU)
(R : UU → UU)
(s : ∏ (X:UU), R X → UU)
(hv : hvec (vec_map (λ i : I, R (A i)) v))
: h1map s (transportf hvec (vec_map_comp A R v) hv)
= transportf hvec (vec_map_comp A (λ _ : UU, UU) v) (h1map (Q:=λ(_:I), UU) (λ (i:I) (rel : R (A i)), s (A i) rel) hv).
Proof.
revert hv.
use (vec_ind (λ n v, ∏ hv : hvec (vec_map (λ i : I, R (A i)) v),
h1map s (transportf hvec (vec_map_comp A R v) hv) =
transportf hvec (vec_map_comp A (λ _ : UU, UU) v)
(h1map (λ (i : I) (rel : R (A i)), s (A i) rel) hv))).
{ intro. apply idpath. }
intros x n' v' IH hv.
eapply pathscomp0.
{
eapply maponpaths.
use transportf_hvec_vecS_eq.
}
eapply pathscomp0.
2:{
use pathsinv0.
use transportf_hvec_vecS_eq.
}
use dirprod_paths.
- reflexivity.
- use IH.
Defined.
Lemma h1h01map_transport_vec_map_comp
{I : UU} {n: nat} {v: vec I n}
(A : ∏ (i: I), UU)
(R : UU → UU)
(r : ∏ (i: I), R (A i))
(s : ∏ (X:UU), R X → UU)
: h1map s (transportf hvec (vec_map_comp A R v) (h01map r v)) = transportf hvec (vec_map_comp A (λ _, UU) v) (h01map (λ i, s (A i) (r i)) v).
Proof.
eapply pathscomp0.
- use h1map_transport_vec_map_comp.
- use maponpaths.
use h1h01map_comp.
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).
Definition hel_h1map_vec {A: UU} {n: nat} {v: vec A n} {P: A → UU} {B: UU}
(f: ∏ (a: A), P a → B)
(hv: hvec (vec_map P v)) (i:⟦ n ⟧)
: el (h1map_vec f hv) i = f (el v i) (eqweqmap (el_vec_map P v i) (hel hv i)).
Proof.
induction n as [|m IHn0].
+ use fromstn0.
exact i.
+ induction v as [vhead vtail].
induction hv as [hvhead hvtail].
induction i as [j jlt].
induction j as [| k].
- apply idpath.
- use IHn0.
Defined.
Section hel_h1map_vec_vec_fill.
Context {A: UU} {n: nat} {a:A} {P: A → UU} {B: UU} (f: ∏ (x: A), P x → B)
(hv: hvec (vec_map P (vec_fill a n))) (i:⟦ n ⟧).
Definition hel_h1map_vec_vec_fill_lemma : f (el (vec_fill a n) i) (eqweqmap (el_vec_map P (vec_fill a n) i) (hel hv i)) = f a (eqweqmap (el_vec_map_vec_fill P a i) (hel hv i)).
Proof.
induction n as [|m IHn0].
+ use fromstn0.
exact i.
+ induction hv as [hvhead hvtail].
induction i as [j jlt].
induction j as [| k].
- apply idpath.
- use IHn0.
Defined.
Definition hel_h1map_vec_vec_fill : el (h1map_vec f hv) i = f a (eqweqmap (el_vec_map_vec_fill P a i) (hel hv i)).
Proof.
etrans.
{ apply hel_h1map_vec. }
use hel_h1map_vec_vec_fill_lemma.
Defined.
End hel_h1map_vec_vec_fill.
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.
Definition h12map {A: UU} {n: nat} {v: vec A n}
{P: A → UU} {R: ∏ (a: A) (p: P a), UU}
(f: ∏ (a: A) (p: P a), R a p)
(h1v: hvec (vec_map P v))
: hvec (h1map_vec R h1v).
Proof.
revert n v f h1v.
refine (vec_ind _ _ _ ).
- intros.
exact [()].
- intros x n xs IHv f h1v.
exact (f x (pr1 h1v) ::: IHv f (pr2 h1v)).
Defined.
Definition helh2map {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))
(i:⟦ n ⟧)
: hel (h2map f h2v) i = (invweq (eqweqmap (hel_h1map_vec R h1v i)) (f _ _ (eqweqmap (hel_h1map_vec Q h1v i) (hel h2v i)))).
Proof.
revert n v f h1v h2v i.
refine (vec_ind _ _ _ ).
- intros f h1v h2v i.
use fromstn0.
exact i.
- intros x n v X f h1v h2v i.
induction i as [j jlt].
induction j as [| k].
* apply idpath.
* use X.
Defined.
Definition h2map_makehvec {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))
: h2map f h2v = make_hvec (λ i, (invweq (eqweqmap (hel_h1map_vec R h1v i)) (f _ _ (eqweqmap (hel_h1map_vec Q h1v i) (hel h2v i))))).
Proof.
use (invmaponpathsweq helf_weq).
simpl.
use funextsec.
intro i.
etrans.
{ apply helh2map. }
use pathsinv0.
use hel_make_hvec.
Defined.
Definition helh2map_basevecfill {A: UU} {n: nat} {a: A} {P: A → UU} {h1v: hvec (vec_map P (vec_fill a n))}
{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))
(i:⟦ n ⟧)
: hel (h2map f h2v) i = invweq (eqweqmap (hel_h1map_vec_vec_fill R h1v i)) (f _ _ (eqweqmap (hel_h1map_vec_vec_fill Q h1v i) (hel h2v i))).
Proof.
revert n h1v h2v i.
use hvec_ind_fixedv.
- intros h1v h2v i.
use fromstn0.
exact i.
- intros n IH h1v h2v i.
induction i as [j jlt].
induction j as [| k].
* apply idpath.
* use IH.
Defined.
Definition h2map_makehvec_basevecfill {A: UU} {n: nat} {a: A} {P: A → UU} {h1v: hvec (vec_map P (vec_fill a n))}
{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))
: h2map f h2v = make_hvec (λ i, invweq (eqweqmap (hel_h1map_vec_vec_fill R h1v i)) (f _ _ (eqweqmap (hel_h1map_vec_vec_fill Q h1v i) (hel h2v i)))).
Proof.
use (invmaponpathsweq helf_weq).
simpl.
use funextsec.
intro i.
etrans.
{ apply helh2map_basevecfill. }
use pathsinv0.
use hel_make_hvec.
Defined.
{P: A → UU} {R: ∏ (a: A) (p: P a), UU}
(f: ∏ (a: A) (p: P a), R a p)
(h1v: hvec (vec_map P v))
: hvec (h1map_vec R h1v).
Proof.
revert n v f h1v.
refine (vec_ind _ _ _ ).
- intros.
exact [()].
- intros x n xs IHv f h1v.
exact (f x (pr1 h1v) ::: IHv f (pr2 h1v)).
Defined.
Definition helh2map {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))
(i:⟦ n ⟧)
: hel (h2map f h2v) i = (invweq (eqweqmap (hel_h1map_vec R h1v i)) (f _ _ (eqweqmap (hel_h1map_vec Q h1v i) (hel h2v i)))).
Proof.
revert n v f h1v h2v i.
refine (vec_ind _ _ _ ).
- intros f h1v h2v i.
use fromstn0.
exact i.
- intros x n v X f h1v h2v i.
induction i as [j jlt].
induction j as [| k].
* apply idpath.
* use X.
Defined.
Definition h2map_makehvec {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))
: h2map f h2v = make_hvec (λ i, (invweq (eqweqmap (hel_h1map_vec R h1v i)) (f _ _ (eqweqmap (hel_h1map_vec Q h1v i) (hel h2v i))))).
Proof.
use (invmaponpathsweq helf_weq).
simpl.
use funextsec.
intro i.
etrans.
{ apply helh2map. }
use pathsinv0.
use hel_make_hvec.
Defined.
Definition helh2map_basevecfill {A: UU} {n: nat} {a: A} {P: A → UU} {h1v: hvec (vec_map P (vec_fill a n))}
{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))
(i:⟦ n ⟧)
: hel (h2map f h2v) i = invweq (eqweqmap (hel_h1map_vec_vec_fill R h1v i)) (f _ _ (eqweqmap (hel_h1map_vec_vec_fill Q h1v i) (hel h2v i))).
Proof.
revert n h1v h2v i.
use hvec_ind_fixedv.
- intros h1v h2v i.
use fromstn0.
exact i.
- intros n IH h1v h2v i.
induction i as [j jlt].
induction j as [| k].
* apply idpath.
* use IH.
Defined.
Definition h2map_makehvec_basevecfill {A: UU} {n: nat} {a: A} {P: A → UU} {h1v: hvec (vec_map P (vec_fill a n))}
{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))
: h2map f h2v = make_hvec (λ i, invweq (eqweqmap (hel_h1map_vec_vec_fill R h1v i)) (f _ _ (eqweqmap (hel_h1map_vec_vec_fill Q h1v i) (hel h2v i)))).
Proof.
use (invmaponpathsweq helf_weq).
simpl.
use funextsec.
intro i.
etrans.
{ apply helh2map_basevecfill. }
use pathsinv0.
use hel_make_hvec.
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 h2lower_h2map {A: UU} {n: nat} {v: vec A n} {P: A → UU}
{Q: ∏ (a: A) (p: P a), UU }
{R : ∏ (a: A) , UU }
(f: ∏ (a: A), P a → R a) {h1v: hvec (vec_map P v)}
(h2v: hvec (h1map_vec Q h1v))
:
h2lower (h2map (λ a p _, f a p) (h2v)) = h1map f h1v.
Proof.
revert n v h1v h2v.
refine (vec_ind _ _ _).
- reflexivity.
- intros x n xs IHxs h1v h2v.
simpl.
apply maponpaths.
apply (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.
Lemma transportb_h1map_compose_beta {S : UU} {n: nat} {v: vec S n}
(B : S → UU)
(C : S → UU)
(D : ∏ (s: S), (B s) → UU)
(E : ∏ (s: S), UU)
(p : ∏ (s: S), C s → B s)
(f : ∏ (s: S) (c : C s), D s (p s c))
(g : ∏ (s: S) (b : B s), D s b → E s)
(cs : hvec (vec_map (λ s : S, C s) v))
(vhd : S)
(cshd : C vhd)
: transportb
(λ arg, hvec (h1lower arg))
(h1map_compose (λ s, p s) D
(cshd:::cs : hvec (vec_map C (vhd ::: v))))
(h12map (λ s, f s) (cshd:::cs : hvec (vec_map C (vhd ::: v))))
=
(f vhd cshd) :::
transportb
(λ arg, hvec (h1lower arg))
(h1map_compose (λ s, p s) D
(cs))
(h12map (λ s, f s) (cs)).
Proof.
use dirprod_paths.
- simpl.
eapply pathscomp0.
{ use pr1_transportb. }
simpl.
induction (h1map_compose (λ s : S, p s) D cs).
apply idpath.
- simpl.
eapply pathscomp0.
{ use pr2_transportb. }
simpl.
use pathsinv0.
use (functtransportb
(hcons (D vhd (p vhd cshd)))
(λ a0 : UU × hvec (vec_map (λ _ : S, UU) v), hvec (h1lower (htl a0)))
(h1map_compose (λ s : S, p s) D cs)
(h12map (λ s : S, f s) cs)).
Defined.
Lemma h2map_transport_h1mapcompose
{S : UU} {n: nat} {v: vec S n}
(B : S → UU)
(C : S → UU)
(D : ∏ (s: S), (B s) → UU)
(E : ∏ (s: S), UU)
(p : ∏ (s: S), C s → B s)
(f : ∏ (s: S) (c : C s), D s (p s c))
(g : ∏ (s: S) (b : B s), D s b → E s)
(cs : hvec (vec_map (λ s : S, C s) v))
: h2lower (h2map (λ (s:S) (b:B s), g s b)
(transportb
(λ arg, hvec (h1lower arg))
(h1map_compose (λ s, p s) D cs)
(h12map (λ s, f s) cs)))
= h1map (Q:= E) (λ s c, g s (p s c) (f s c) ) cs.
Proof.
generalize dependent n.
refine (vec_ind _ _ _).
- intro cs. apply idpath.
- intros s n v IH cs.
destruct cs as [hhd_cs htl_cs].
eapply pathscomp0.
{ eapply (maponpaths h2lower).
eapply (maponpaths (h2map (λ (s0 : S) (b : B s0), g s0 b))).
use transportb_h1map_compose_beta.
+ exact E.
+ exact g.
}
simpl.
use maponpaths.
use IH.
Defined.
Functions from hvecs and their curried variants.
Definition iterfun {n: nat} (v: vec UU n) (B: UU): UU.
Proof.
revert n v.
refine (vec_ind _ _ _).
- exact B.
- intros x n xs IHxs.
exact (x → IHxs).
Defined.
Definition currify {n: nat} {v: vec UU n} {B: UU} (f: hvec v → B): iterfun v B.
Proof.
revert n v f.
refine (vec_ind _ _ _).
- intros.
exact (f tt).
- intros x n xs IHxs f.
simpl in f.
simpl.
intro a.
exact (IHxs (λ l, f (a,, l))).
Defined.
Definition uncurrify {n: nat} {v: vec UU n} {B: UU} (f: iterfun v B): hvec v → B.
Proof.
revert n v f.
refine (vec_ind _ _ _).
- intros.
exact f.
- intros x n xs IHxs f.
simpl in *.
intro a.
exact (IHxs (f (pr1 a)) (pr2 a)).
Defined.
Definition pr1vechSet {n: nat} : vec hSet n → vec UU n.
Proof.
induction n.
- apply tounit.
- intros Xv.
destruct Xv as [X v].
exact ((X:UU) ,, IHn v).
Defined.
Lemma isasethvec {n: nat} (v: vec UU n)
(iss : hvec (vec_map (isaset) v))
: isaset (hvec v).
Proof.
revert iss.
apply (vec_ind (λ n v, hvec (vec_map isaset v) → isaset (hvec v))).
- intro.
apply isasetunit.
- intros X n' tl IH_tl H.
apply isasetdirprod.
+
apply H.
+
apply IH_tl.
apply H.
Qed.
Section Hvec_ofpaths.
Context {S: UU} {n: nat} {v: vec S n}
{B A: S → UU}
{L: ∏ (s:S), B s → A s}
{hv : hvec (vec_map A v)}
(fib : hvec (h1lower (h1map (λ s a, ∑ (b: B s), L s b = a) hv))).
Let E := h2map
(R:= (λ (s : S) (a : A s), ∏ t : ∑ b : B s, L s b = a, L s (pr1 t) = a))
(λ (s:S) (a : A s) _ , pr2)
fib.
Theorem hvec_ofpaths : h1map L (h2lower (h2map (λ s (p:A s), pr1 ) fib)) = hv.
Proof.
revert n v hv fib E.
use (vec_ind _ _).
- intros hv fib E.
cbn.
induction hv.
apply idpath.
- intros s n v IH hv fib E.
use pathsdirprod.
+ use (hhd E).
+ use IH.
Defined.
End Hvec_ofpaths.
Lemma maponpaths_hhd_hcons
{S: UU} {n: nat} {v v': vec S n}
{A: S → UU} {hv hv': hvec (vec_map A v)}
(e : hv = hv')
(s:S) (a:A s)
: maponpaths hhd (maponpaths (hcons a) e ) = idpath a.
Proof.
induction e.
apply idpath.
Qed.
Lemma maponpaths_htl_hcons
{S: UU} {n: nat} {v v': vec S n}
{A: S → UU} {hv hv': hvec (vec_map A v)}
(e : hv = hv')
(s:S) (a:A s)
: maponpaths htl (maponpaths (hcons a) e ) = e.
Proof.
induction e.
apply idpath.
Qed.
Section transport_hvec_ofpaths.
Context {S: UU} {n: nat} {v: vec S n}
{A: S → UU}
{P: ∏ (s:S), A s → UU}
{hv : hvec (vec_map A v)}
(fib : hvec (h1lower (h1map
(λ s a, ∑ (b: ∑ (a' : A s), P s a'), pr1 b = a) hv))).
Let B := λ s, ∑ (a : A s), P s a.
Let h2v : hvec (h1lower
(h1map P (h1map (λ s : S, pr1)
(h2lower (h2map (λ (s : S) (p : A s), pr1)
fib))))).
Proof.
refine (transportb (λ arg, hvec (h1lower arg)) _ _).
{ use h1map_compose. }
use h12map.
simpl.
intros s ap.
use pr2.
Defined.
Let h2v' : hvec (h1lower (h1map P hv)).
Proof.
refine (h2map _ fib).
intros s a ape.
use (transportf (P s) (pr2 ape)).
use (pr21 ape).
Defined.
Lemma transport_hvec_ofpaths
: transportf
(λ arg, hvec (h1lower (h1map P arg)))
(hvec_ofpaths
(L := λ s, pr1)
fib)
h2v
= h2v'.
Proof.
unfold h2v, h2v'.
clear h2v h2v'.
revert n v hv fib.
refine (vec_ind _ _ _).
- induction hv.
induction fib.
apply idpath.
- intros s n v IH hv fib.
simpl.
use dirprod_paths.
+ simpl.
eapply pathscomp0.
{ use (pr1_transportf
(A := A s × hvec (vec_map A v))
(B := λ x, P s (hhd x))
(P := λ x _, hvec (h1lower (h1map P (htl x))))). }
simpl.
eapply pathscomp0.
{ use (functtransportf hhd). }
simpl.
eapply pathscomp0.
{ eapply (maponpaths (λ p, transportf (P s) p _)).
use maponpaths_pr1_pathsdirprod. }
use maponpaths.
eapply pathscomp0.
{ use (pr1_transportb
(A := UU × hvec (vec_map (λ _ : S, UU) v))). }
eapply pathscomp0.
{ change (UU × hvec (vec_map (λ _ : S, UU) v)) with (hvec(UU:::vec_map (λ _ : S, UU) v)).
refine (functtransportb hhd (idfun UU)
(maponpaths (hcons (P s (pr111 fib)))
(h1map_compose (λ s : S, pr1) P (h2lower (h2map (λ (s : S) (p : A s), pr1) (pr2 fib))))) _). }
simpl.
destruct fib as [hhd_fib htl_fib].
simpl.
eapply pathscomp0.
{ eapply (maponpaths (λ arg, transportb (idfun UU) arg (pr21 hhd_fib))).
use maponpaths_hhd_hcons.
- exact v.
- exact s. }
apply idpath.
+ simpl.
specialize (IH (htl hv) (htl fib)).
use (pathscomp0 _ IH).
eapply pathscomp0.
{ use (pr2_transportf (A:=A s × hvec (vec_map A v))). }
simpl.
eapply pathscomp0.
{ eapply (maponpaths (transportf (λ a : A s × hvec (vec_map A v), hvec (h1lower (h1map P (htl a)))) (pathsdirprod (pr21 fib) (hvec_ofpaths (pr2 fib))) )).
eapply pathscomp0.
{ use (pr2_transportb (A := UU × hvec (vec_map (λ _ : S, UU) v))). }
simpl.
eapply pathscomp0.
{ use (functtransportb htl (λ arg, hvec (h1lower arg))
(maponpaths (hcons (P s (pr111 fib)))
(h1map_compose (λ s0 : S, pr1) P (h2lower (h2map (λ (s0 : S) (p : A s0), pr1) (pr2 fib)))))). }
eapply pathscomp0.
{ eapply (maponpaths (λ arg, transportb
(λ arg, hvec (h1lower arg)) arg _)).
use maponpaths_htl_hcons.
-exact v.
-exact s. }
apply idpath. }
eapply pathscomp0.
{ use (functtransportf htl
(λ arg, hvec (h1lower (h1map P arg)))
(pathsdirprod (pr21 fib) (hvec_ofpaths (pr2 fib)))). }
simpl.
use (maponpaths (λ arg, transportf (λ arg : hvec (vec_map A v), hvec (h1lower (h1map P arg))) arg _)).
use maponpaths_pr2_pathsdirprod.
Qed.
End transport_hvec_ofpaths.
Lemma h2map_idfun {A: UU} {n: nat} {v: vec A n} {P: A → UU} {h1v: hvec (vec_map P v)}
{Q: ∏ (a:A), P a → UU} (h2v: hvec (h1map_vec (λ a p, Q a p) h1v))
: h2map (λ a p, idfun (Q a p)) h2v = h2v.
Proof.
revert n v h1v h2v.
refine (vec_ind _ _ _).
- induction h1v.
induction h2v.
apply idpath.
- simpl.
intros x n xs IHxs h1v h2v.
change h2v with (hhd h2v ::: htl h2v).
apply maponpaths.
apply (IHxs (pr2 h1v)).
Defined.
Lemma h2map_compose {A: UU} {n: nat} {v: vec A n}
{P: A → UU} {h1v: hvec (vec_map P v)}
{Q: ∏ (a:A), P a → UU} (h2v: hvec (h1map_vec Q h1v))
{R: ∏ (a:A) (p: P a), UU}
{S: ∏ (a:A) (p: P a), UU}
(f : ∏ (a : A) (p : P a), Q a p → R a p)
(g : ∏ (a : A) (p : P a), R a p → S a p)
: h2map g (h2map f h2v) = h2map (λ a p, g a p ∘ (f a p)) h2v.
Proof.
revert n v h1v h2v.
refine (vec_ind _ _ _).
- induction h1v.
induction h2v.
apply idpath.
- simpl.
intros x n xs IHxs h1v h2v.
apply maponpaths.
apply (IHxs (pr2 h1v)).
Defined.
Lemma transportb_h2vec {S : UU} {n : nat} {v : vec S n}
(B: S → UU)
(D D' : ∏ s:S, B s→ UU)
(p : D = D')
(bs : hvec (vec_map B v))
(Dbs : hvec (h1lower (h1map D' bs)))
: transportb
(λ D0 : ∏ s : S, B s → UU, hvec (h1map_vec D0 bs))
p
Dbs
= h2map (λ s b d'b, transportb (λ D0, D0 s b) p d'b) Dbs.
Proof.
induction p.
unfold transportb.
use pathsinv0.
use h2map_idfun.
Defined.