Library ASCommon.HVec


From stdpp Require Export fin.

Require Import Options.
Require Import CBase CArith.

Fixpoint hvec (n : nat) : (fin n Type) Type :=
  match n with
  | 0%natfun _unit
  | S mfun T ⇒ ((T 0%fin) × hvec m (T FS))%type
  end.
Arguments hvec {n} T.

Fixpoint hget {n : nat} (i : fin n) : T : fin n Type, hvec T T i :=
  match i with
  | 0%finfun _ vv.1
  | FS pfun _ vhget p _ v.2
  end.
Arguments hget {n} i {T} v.

Fixpoint hvec_func {n : nat} : T : fin n Type, ( i, T i) hvec T :=
  match n with
  | 0%natfun _ f()
  | S mfun _ f(f 0%fin, hvec_func _ (fun xf (FS x)))
  end.
Arguments hvec_func {n T} f.

Fixpoint hset {n : nat} (i : fin n) : T : fin n Type, T i hvec T hvec T :=
  match i with
  | 0%finfun _ nv v(nv, v.2)
  | FS pfun _ nv v(v.1, hset p _ nv v.2)
  end.
Arguments hset {n} i {T} nv v.

Lemma hvec_get_func {n : nat} {T : fin n Type} (i : fin n) (f : i, T i) :
  hget i (hvec_func f) = f i.
Proof. induction i; hauto. Qed.

Lemma hvec_get_set_same {n : nat} {T : fin n Type}
  (v : hvec T) (i : fin n) (nv : T i) :
  hget i (hset i nv v) = nv.
Proof. induction i; hauto. Qed.

Lemma hvec_get_set_diff {n : nat} {T : fin n Type}
  (v : hvec T) (i j : fin n) (nv : T j) :
  i j hget i (hset j nv v) = hget i v.
Proof. induction i; sauto dep:on. Qed.

Definition hmap {n : nat} {T1 T2 : fin n Type} (f : i, T1 i T2 i)
  (v : hvec T1) : hvec T2 := hvec_func (fun if i (hget i v)).

Definition hmap2 {n : nat} {T1 T2 T3 : fin n Type} (f : i, T1 i T2 i T3 i)
  (v1 : hvec T1) (v2 : hvec T2) : hvec T3
  := hvec_func (fun if i (hget i v1) (hget i v2)).

Lemma hget_hmap {n : nat} {T1 T2 : fin n Type} (f : i, T1 i T2 i)
  (v : hvec T1) (i : fin n) :
  hget i (hmap f v) = f i (hget i v).
Proof.
  unfold hmap.
  rewrite hvec_get_func.
  reflexivity.
Qed.

Definition hlast {n : nat} {T : fin (S n) Type} (v : hvec T) : T (fin_last n)
  := hget (fin_last n) v.