Record KleeneStore i j a := kleeneStore
 { dim : nat
 ; peek : Vector.t j dim -> a
 ; pos : Vector.t i dim
 }.Record KleeneStore i j a := kleeneStore
 { dim : nat
 ; peek : Vector.t j dim -> a
 ; pos : Vector.t i dim
 }.Record KleeneStore i j a := kleeneStore
 { dim : nat
 ; peek : Vector.t j dim -> a
 ; pos : Vector.t i dim
 }.Record KleeneStore i j a := kleeneStore
 { dim : nat
 ; peek : Vector.t j dim -> a
 ; pos : Vector.t i dim
 }.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)
  }.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)
  }.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)
  }.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)
  }.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)
  }.

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).