Record KleeneStore i j a := kleeneStore
{ dim : nat
; peek : Vector.t j dim -> a
; pos : Vector.t i dim
}.
Definition extract i a (s : KleeneStore i i a) : a :=
peek (pos s).
Definition KSmap i j a b (f : a -> b) (s : KleeneStore i j a) : KleeneStore i j b :=
kleeneStore (fun v => f (peek v)) (pos s).
Definition duplicate i j k a (s : KleeneStore i k a) :
KleeneStore i j (KleeneStore j k a) :=
kleeneStore (fun v => kleeneStore (peek (k:=s)) v) (pos s).
Record KleeneCoalg (i o : Type -> Type) := kleeneCoalg
{ coalg :> forall a b, (o a) -> KleeneStore (i a) (i b) (o b)
; coalg_extract : forall a (x:o a), extract (coalg _ x) = x
; coalg_duplicate : forall a b c (x:o a),
duplicate (i b) (coalg c x) = KSmap (coalg c) (coalg b x)
}.

(* Specifications: *)
Lemma free_b_dim i o (k : KleeneCoalg i o) a b b' (x : o a) : dim (coalg k b x) = dim (coalg k b' x).
Lemma free_b_pos i o (k : KleeneCoalg i o) a b b' (x : o a) :
eq_rect _ _ (pos (coalg k b x)) _ (free_b_dim k _ _ x) = pos (coalg k b' x).