Built with Alectryon, running Coq+SerAPI v8.16.0+0.16.3. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑ Ctrl+↓ to navigate, Ctrl+🖱️ to focus. On Mac, use ⌘ instead of Ctrl.
From Tealeaves Require Export
  Classes.Monoid
  Classes.Categorical.Applicative
  Classes.Categorical.Monad
  Classes.Categorical.ShapelyFunctor
  Classes.Kleisli.TraversableFunctor
  Functors.Early.Batch.

From Tealeaves.Functors Require Import
  Early.List
  Constant
  VectorRefinement.

Import Early.Batch.Notations.
Import Monoid.Notations.
Import Applicative.Notations.
Import Kleisli.TraversableFunctor.Notations.
Import VectorRefinement.Notations.

#[local] Generalizable Variables ψ ϕ W F G M A B C D X Y O.
#[local] Arguments map F%function_scope {Map} {A B}%type_scope f%function_scope _.
#[local] Arguments ret T%function_scope {Return} (A)%type_scope _.
#[local] Arguments pure F%function_scope {Pure} {A}%type_scope _.
#[local] Arguments mult F%function_scope {Mult} {A B}%type_scope _.

(** * <<mapReduce>> Rewriting Lemmas *)
(******************************************************************************)
Section Batch_mapReduce_rewriting.

  Context {A B C: Type}.

  
A, B, C: Type

forall (M : Type) (op : Monoid_op M) (unit0 : Monoid_unit M), Monoid M -> forall (f : A -> M) (a : A) (rest : Batch A B (B -> C)), mapReduce f (rest ⧆ a) = mapReduce f rest ● f a
A, B, C: Type

forall (M : Type) (op : Monoid_op M) (unit0 : Monoid_unit M), Monoid M -> forall (f : A -> M) (a : A) (rest : Batch A B (B -> C)), mapReduce f (rest ⧆ a) = mapReduce f rest ● f a
A, B, C, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
a: A
rest: Batch A B (B -> C)

mapReduce f (rest ⧆ a) = mapReduce f rest ● f a
A, B, C, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
a: A
rest: Batch A B (B -> C)

traverse f (rest ⧆ a) = traverse f rest ● f a
A, B, C, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
a: A
rest: Batch A B (B -> C)

map (const M) Step (traverse f rest) <⋆> f a = traverse f rest ● f a
reflexivity. Qed. End Batch_mapReduce_rewriting. (** ** <<mapReduce>> Rewriting for << <⋆> >> *) (******************************************************************************)
A, B, C, C': Type

forall (M : Type) (op : Monoid_op M) (unit0 : Monoid_unit M), Monoid M -> forall (f : A -> M) (g : C -> C') (b : Batch A B C), mapReduce f b = mapReduce f (map (Batch A B) g b)
A, B, C, C': Type

forall (M : Type) (op : Monoid_op M) (unit0 : Monoid_unit M), Monoid M -> forall (f : A -> M) (g : C -> C') (b : Batch A B C), mapReduce f b = mapReduce f (map (Batch A B) g b)
A, B, C, C', M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
g: C -> C'
b: Batch A B C

mapReduce f b = mapReduce f (map (Batch A B) g b)
A, B, C, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
b: Batch A B C

forall (C' : Type) (g : C -> C'), mapReduce f b = mapReduce f (map (Batch A B) g b)
A, B, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
C: Type
c: C
C': Type
g: C -> C'

mapReduce f (Done c) = mapReduce f (map (Batch A B) g (Done c))
A, B, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
C: Type
b: Batch A B (B -> C)
a: A
IHb: forall (C' : Type) (g : (B -> C) -> C'), mapReduce f b = mapReduce f (map (Batch A B) g b)
C': Type
g: C -> C'
mapReduce f (b ⧆ a) = mapReduce f (map (Batch A B) g (b ⧆ a))
A, B, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
C: Type
c: C
C': Type
g: C -> C'

mapReduce f (Done c) = mapReduce f (map (Batch A B) g (Done c))
reflexivity.
A, B, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
C: Type
b: Batch A B (B -> C)
a: A
IHb: forall (C' : Type) (g : (B -> C) -> C'), mapReduce f b = mapReduce f (map (Batch A B) g b)
C': Type
g: C -> C'

mapReduce f (b ⧆ a) = mapReduce f (map (Batch A B) g (b ⧆ a))
A, B, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
C: Type
b: Batch A B (B -> C)
a: A
IHb: forall (C' : Type) (g : (B -> C) -> C'), mapReduce f b = mapReduce f (map (Batch A B) g b)
C': Type
g: C -> C'

mapReduce f b ● f a = mapReduce f (map (Batch A B) g (b ⧆ a))
A, B, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
C: Type
b: Batch A B (B -> C)
a: A
IHb: forall (C' : Type) (g : (B -> C) -> C'), mapReduce f b = mapReduce f (map (Batch A B) g b)
C': Type
g: C -> C'

mapReduce f b ● f a = mapReduce f (map (Batch A B) (compose g) b ⧆ a)
A, B, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
C: Type
b: Batch A B (B -> C)
a: A
IHb: forall (C' : Type) (g : (B -> C) -> C'), mapReduce f b = mapReduce f (map (Batch A B) g b)
C': Type
g: C -> C'

mapReduce f b ● f a = mapReduce f (map (Batch A B) (compose g) b) ● f a
A, B, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
C: Type
b: Batch A B (B -> C)
a: A
C': Type
g: C -> C'
IHb: mapReduce f b = mapReduce f (map (Batch A B) (compose g) b)

mapReduce f b ● f a = mapReduce f (map (Batch A B) (compose g) b) ● f a
A, B, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
C: Type
b: Batch A B (B -> C)
a: A
C': Type
g: C -> C'
IHb: mapReduce f b = mapReduce f (map (Batch A B) (compose g) b)

mapReduce f (map (Batch A B) (compose g) b) ● f a = mapReduce f (map (Batch A B) (compose g) b) ● f a
reflexivity. Qed.
A, B, C, D, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M

forall (c : C) (b2 : Batch A B D), mapReduce f (Done c ⊗ b2) = mapReduce f b2
A, B, C, D, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M

forall (c : C) (b2 : Batch A B D), mapReduce f (Done c ⊗ b2) = mapReduce f b2
A, B, C, D, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
c: C
b2: Batch A B D

mapReduce f (Done c ⊗ b2) = mapReduce f b2
A, B, C, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
c: C
C0: Type
c0: C0

mapReduce f (Done c ⊗ Done c0) = mapReduce f (Done c0)
A, B, C, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
c: C
C0: Type
b2: Batch A B (B -> C0)
a: A
IHb2: mapReduce f (Done c ⊗ b2) = mapReduce f b2
mapReduce f (Done c ⊗ (b2 ⧆ a)) = mapReduce f (b2 ⧆ a)
A, B, C, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
c: C
C0: Type
c0: C0

mapReduce f (Done c ⊗ Done c0) = mapReduce f (Done c0)
reflexivity.
A, B, C, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
c: C
C0: Type
b2: Batch A B (B -> C0)
a: A
IHb2: mapReduce f (Done c ⊗ b2) = mapReduce f b2

mapReduce f (Done c ⊗ (b2 ⧆ a)) = mapReduce f (b2 ⧆ a)
A, B, C, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
c: C
C0: Type
b2: Batch A B (B -> C0)
a: A
IHb2: mapReduce f (Done c ⊗ b2) = mapReduce f b2

mapReduce f (Done c ⊗ (b2 ⧆ a)) = mapReduce f b2 ● f a
A, B, C, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
c: C
C0: Type
b2: Batch A B (B -> C0)
a: A
IHb2: mapReduce f (Done c ⊗ b2) = mapReduce f b2

mapReduce f (Done c ⊗ (b2 ⧆ a)) = mapReduce f (Done c ⊗ b2) ● f a
A, B, C, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
c: C
C0: Type
b2: Batch A B (B -> C0)
a: A
IHb2: mapReduce f (Done c ⊗ b2) = mapReduce f b2

(pure (const M) Step ● Traverse_Batch1 B (B -> C * C0) (const M) Map_const Pure_const Mult_const A False f (map (Batch A B) strength_arrow (mult_Batch (Done c) b2))) ● f a = mapReduce f (mult_Batch (Done c) b2) ● f a
A, B, C, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
c: C
C0: Type
b2: Batch A B (B -> C0)
a: A
IHb2: mapReduce f (Done c ⊗ b2) = mapReduce f b2

(Ƶ ● Traverse_Batch1 B (B -> C * C0) (const M) Map_const (fun (X : Type) (_ : X) => Ƶ) Mult_const A False f (map (Batch A B) strength_arrow (mult_Batch (Done c) b2))) ● f a = mapReduce f (mult_Batch (Done c) b2) ● f a
A, B, C, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
c: C
C0: Type
b2: Batch A B (B -> C0)
a: A
IHb2: mapReduce f (Done c ⊗ b2) = mapReduce f b2

Traverse_Batch1 B (B -> C * C0) (const M) Map_const (fun (X : Type) (_ : X) => Ƶ) Mult_const A False f (map (Batch A B) strength_arrow (mult_Batch (Done c) b2)) ● f a = mapReduce f (mult_Batch (Done c) b2) ● f a
A, B, C, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
c: C
C0: Type
b2: Batch A B (B -> C0)
a: A
IHb2: mapReduce f (Done c ⊗ b2) = mapReduce f b2

mapReduce f (map (Batch A B) strength_arrow (mult_Batch (Done c) b2)) ● f a = mapReduce f (mult_Batch (Done c) b2) ● f a
A, B, C, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
c: C
C0: Type
b2: Batch A B (B -> C0)
a: A
IHb2: mapReduce f (Done c ⊗ b2) = mapReduce f b2

mapReduce f (mult_Batch (Done c) b2) ● f a = mapReduce f (mult_Batch (Done c) b2) ● f a
reflexivity. Qed.
A, B, C, D, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M

forall (b1 : Batch A B C) (b2 : Batch A B D), mapReduce f (b1 ⊗ b2) = mapReduce f b1 ● mapReduce f b2
A, B, C, D, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M

forall (b1 : Batch A B C) (b2 : Batch A B D), mapReduce f (b1 ⊗ b2) = mapReduce f b1 ● mapReduce f b2
A, B, C, D, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
b1: Batch A B C
b2: Batch A B D

mapReduce f (b1 ⊗ b2) = mapReduce f b1 ● mapReduce f b2
A, B, C, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
b1: Batch A B C
C0: Type
c: C0

mapReduce f (b1 ⊗ Done c) = mapReduce f b1 ● mapReduce f (Done c)
A, B, C, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
b1: Batch A B C
C0: Type
b2: Batch A B (B -> C0)
a: A
IHb2: mapReduce f (b1 ⊗ b2) = mapReduce f b1 ● mapReduce f b2
mapReduce f (b1 ⊗ (b2 ⧆ a)) = mapReduce f b1 ● mapReduce f (b2 ⧆ a)
A, B, C, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
b1: Batch A B C
C0: Type
c: C0

mapReduce f (b1 ⊗ Done c) = mapReduce f b1 ● mapReduce f (Done c)
A, B, C, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
b1: Batch A B C
C0: Type
c: C0

mapReduce f (map (Batch A B) (fun c0 : C => (c0, c)) b1) = mapReduce f b1 ● pure (const M) (Done c)
A, B, C, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
b1: Batch A B C
C0: Type
c: C0

mapReduce f b1 = mapReduce f b1 ● pure (const M) (Done c)
A, B, C, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
b1: Batch A B C
C0: Type
c: C0

mapReduce f b1 = mapReduce f b1 ● Ƶ
A, B, C, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
b1: Batch A B C
C0: Type
c: C0

mapReduce f b1 = mapReduce f b1
reflexivity.
A, B, C, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
b1: Batch A B C
C0: Type
b2: Batch A B (B -> C0)
a: A
IHb2: mapReduce f (b1 ⊗ b2) = mapReduce f b1 ● mapReduce f b2

mapReduce f (b1 ⊗ (b2 ⧆ a)) = mapReduce f b1 ● mapReduce f (b2 ⧆ a)
A, B, C, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
b1: Batch A B C
C0: Type
b2: Batch A B (B -> C0)
a: A
IHb2: mapReduce f (b1 ⊗ b2) = mapReduce f b1 ● mapReduce f b2

mapReduce f (b1 ⊗ (b2 ⧆ a)) = mapReduce f b1 ● (mapReduce f b2 ● f a)
A, B, C, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
b1: Batch A B C
C0: Type
b2: Batch A B (B -> C0)
a: A
IHb2: mapReduce f (b1 ⊗ b2) = mapReduce f b1 ● mapReduce f b2

mapReduce f (b1 ⊗ (b2 ⧆ a)) = (mapReduce f b1 ● mapReduce f b2) ● f a
A, B, C, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
b1: Batch A B C
C0: Type
b2: Batch A B (B -> C0)
a: A

mapReduce f (b1 ⊗ (b2 ⧆ a)) = mapReduce f (b1 ⊗ b2) ● f a
A, B, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
C: Type
c: C
C0: Type
b2: Batch A B (B -> C0)
a: A

mapReduce f (Done c ⊗ (b2 ⧆ a)) = mapReduce f (Done c ⊗ b2) ● f a
A, B, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
C: Type
b1: Batch A B (B -> C)
a0: A
C0: Type
b2: Batch A B (B -> C0)
a: A
IHb1: mapReduce f (b1 ⊗ (b2 ⧆ a)) = mapReduce f (b1 ⊗ b2) ● f a
mapReduce f ((b1 ⧆ a0) ⊗ (b2 ⧆ a)) = mapReduce f ((b1 ⧆ a0) ⊗ b2) ● f a
A, B, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
C: Type
c: C
C0: Type
b2: Batch A B (B -> C0)
a: A

mapReduce f (Done c ⊗ (b2 ⧆ a)) = mapReduce f (Done c ⊗ b2) ● f a
A, B, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
C: Type
c: C
C0: Type
b2: Batch A B (B -> C0)
a: A

mapReduce f (b2 ⧆ a) = mapReduce f (Done c ⊗ b2) ● f a
A, B, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
C: Type
c: C
C0: Type
b2: Batch A B (B -> C0)
a: A

mapReduce f (b2 ⧆ a) = mapReduce f b2 ● f a
A, B, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
C: Type
c: C
C0: Type
b2: Batch A B (B -> C0)
a: A

mapReduce f b2 ● f a = mapReduce f b2 ● f a
reflexivity.
A, B, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
C: Type
b1: Batch A B (B -> C)
a0: A
C0: Type
b2: Batch A B (B -> C0)
a: A
IHb1: mapReduce f (b1 ⊗ (b2 ⧆ a)) = mapReduce f (b1 ⊗ b2) ● f a

mapReduce f ((b1 ⧆ a0) ⊗ (b2 ⧆ a)) = mapReduce f ((b1 ⧆ a0) ⊗ b2) ● f a
A, B, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
C: Type
b1: Batch A B (B -> C)
a0: A
C0: Type
b2: Batch A B (B -> C0)
a: A
IHb1: mapReduce f (b1 ⊗ (b2 ⧆ a)) = mapReduce f (b1 ⊗ b2) ● f a

(pure (const M) Step ● Traverse_Batch1 B (B -> C * C0) (const M) Map_const Pure_const Mult_const A False f (map (Batch A B) strength_arrow (mult_Batch (b1 ⧆ a0) b2))) ● f a = mapReduce f (mult_Batch (b1 ⧆ a0) b2) ● f a
A, B, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
C: Type
b1: Batch A B (B -> C)
a0: A
C0: Type
b2: Batch A B (B -> C0)
a: A
IHb1: mapReduce f (b1 ⊗ (b2 ⧆ a)) = mapReduce f (b1 ⊗ b2) ● f a

(Ƶ ● Traverse_Batch1 B (B -> C * C0) (const M) Map_const (fun (X : Type) (_ : X) => Ƶ) Mult_const A False f (map (Batch A B) strength_arrow (mult_Batch (b1 ⧆ a0) b2))) ● f a = mapReduce f (mult_Batch (b1 ⧆ a0) b2) ● f a
A, B, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
C: Type
b1: Batch A B (B -> C)
a0: A
C0: Type
b2: Batch A B (B -> C0)
a: A
IHb1: mapReduce f (b1 ⊗ (b2 ⧆ a)) = mapReduce f (b1 ⊗ b2) ● f a

Traverse_Batch1 B (B -> C * C0) (const M) Map_const (fun (X : Type) (_ : X) => Ƶ) Mult_const A False f (map (Batch A B) strength_arrow (mult_Batch (b1 ⧆ a0) b2)) ● f a = mapReduce f (mult_Batch (b1 ⧆ a0) b2) ● f a
A, B, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
C: Type
b1: Batch A B (B -> C)
a0: A
C0: Type
b2: Batch A B (B -> C0)
a: A
IHb1: mapReduce f (b1 ⊗ (b2 ⧆ a)) = mapReduce f (b1 ⊗ b2) ● f a

mapReduce f (map (Batch A B) strength_arrow (mult_Batch (b1 ⧆ a0) b2)) ● f a = mapReduce f (mult_Batch (b1 ⧆ a0) b2) ● f a
A, B, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
C: Type
b1: Batch A B (B -> C)
a0: A
C0: Type
b2: Batch A B (B -> C0)
a: A
IHb1: mapReduce f (b1 ⊗ (b2 ⧆ a)) = mapReduce f (b1 ⊗ b2) ● f a

mapReduce f (mult_Batch (b1 ⧆ a0) b2) ● f a = mapReduce f (mult_Batch (b1 ⧆ a0) b2) ● f a
reflexivity. Qed.
A, B: Type

forall (M : Type) (op : Monoid_op M) (unit0 : Monoid_unit M), Monoid M -> forall (f : A -> M) (X Y : Type) (lhs : Batch A B (X -> Y)) (rhs : Batch A B X), mapReduce f (lhs <⋆> rhs) = mapReduce f lhs ● mapReduce f rhs
A, B: Type

forall (M : Type) (op : Monoid_op M) (unit0 : Monoid_unit M), Monoid M -> forall (f : A -> M) (X Y : Type) (lhs : Batch A B (X -> Y)) (rhs : Batch A B X), mapReduce f (lhs <⋆> rhs) = mapReduce f lhs ● mapReduce f rhs
A, B, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
X, Y: Type
lhs: Batch A B (X -> Y)
rhs: Batch A B X

mapReduce f (lhs <⋆> rhs) = mapReduce f lhs ● mapReduce f rhs
A, B, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
X, Y: Type
lhs: Batch A B (X -> Y)
rhs: Batch A B X

mapReduce f (map (Batch A B) (fun '(f, a) => f a) (lhs ⊗ rhs)) = mapReduce f lhs ● mapReduce f rhs
A, B, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
X, Y: Type
lhs: Batch A B (X -> Y)
rhs: Batch A B X

mapReduce f (lhs ⊗ rhs) = mapReduce f lhs ● mapReduce f rhs
A, B, M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
f: A -> M
X, Y: Type
lhs: Batch A B (X -> Y)
rhs: Batch A B X

mapReduce f lhs ● mapReduce f rhs = mapReduce f lhs ● mapReduce f rhs
reflexivity. Qed. Section Batch_mapReduce_rewriting_derived. Context {A B C: Type}. (** ** <<tolist>> *) (******************************************************************************) Import List.ListNotations.
A, B, C: Type

forall (b : Batch A B (B -> C)) (a : A), tolist (b ⧆ a) = tolist b ++ [a]
A, B, C: Type

forall (b : Batch A B (B -> C)) (a : A), tolist (b ⧆ a) = tolist b ++ [a]
A, B, C: Type
b: Batch A B (B -> C)
a: A

tolist (b ⧆ a) = tolist b ++ [a]
reflexivity. Qed. (** ** <<tosubset>> *) (******************************************************************************) Import Subset.Notations. #[export] Instance ToSubset_Batch1 {B C}: ToSubset (BATCH1 B C) := ToSubset_Traverse.
A, B, C: Type

forall (b : Batch A B (B -> C)) (a : A), tosubset (b ⧆ a) = tosubset b ∪ {{a}}
A, B, C: Type

forall (b : Batch A B (B -> C)) (a : A), tosubset (b ⧆ a) = tosubset b ∪ {{a}}
A, B, C: Type
b: Batch A B (B -> C)
a: A

tosubset (b ⧆ a) = tosubset b ∪ {{a}}
A, B, C: Type
b: Batch A B (B -> C)
a: A

mapReduce (ret subset A) (b ⧆ a) = tosubset b ∪ {{a}}
A, B, C: Type
b: Batch A B (B -> C)
a: A

mapReduce (ret subset A) b ● ret subset A a = tosubset b ∪ {{a}}
reflexivity. Qed. (** ** <<a ∈ _>> *) (******************************************************************************) Import ContainerFunctor.Notations.
A, B, C: Type

forall (b : Batch A B (B -> C)) (a a' : A), a' ∈ (b ⧆ a) = (a' ∈ b \/ a' = a)
A, B, C: Type

forall (b : Batch A B (B -> C)) (a a' : A), a' ∈ (b ⧆ a) = (a' ∈ b \/ a' = a)
A, B, C: Type
b: Batch A B (B -> C)
a, a': A

a' ∈ (b ⧆ a) = (a' ∈ b \/ a' = a)
A, B, C: Type
b: Batch A B (B -> C)
a, a': A

mapReduce {{a'}} (b ⧆ a) = (a' ∈ b \/ a' = a)
A, B, C: Type
b: Batch A B (B -> C)
a, a': A

mapReduce {{a'}} (b ⧆ a) = (mapReduce {{a'}} b \/ a' = a)
A, B, C: Type
b: Batch A B (B -> C)
a, a': A

mapReduce {{a'}} b ● {{a'}} a = (mapReduce {{a'}} b \/ a' = a)
reflexivity. Qed. End Batch_mapReduce_rewriting_derived. (** * Simultaneous Induction on Two <<Batch>>es of the Same Shape *) (******************************************************************************) Section shape_induction. Context {A1 A2 B C : Type} {b1: Batch A1 B C} {b2: Batch A2 B C} (Hshape: shape (F := BATCH1 B C) b1 = shape (F := BATCH1 B C) b2) (P : forall C : Type, Batch A1 B C -> Batch A2 B C -> Prop) (IHdone: forall (C : Type) (c : C), P C (Done c) (Done c)) (IHstep: forall (C : Type) (b1 : Batch A1 B (B -> C)) (b2 : Batch A2 B (B -> C)), P (B -> C) b1 b2 -> forall (a1 : A1) (a2: A2) (Hshape: shape (F := BATCH1 B C) (Step b1 a1) = shape (F := BATCH1 B C) (Step b2 a2)), P C (Step b1 a1) (Step b2 a2)).
A1, A2, B, C: Type
b1: Batch A1 B C
b2: Batch A2 B C
Hshape: shape b1 = shape b2
P: forall C : Type, Batch A1 B C -> Batch A2 B C -> Prop
IHdone: forall (C : Type) (c : C), P C (Done c) (Done c)
IHstep: forall (C : Type) (b1 : Batch A1 B (B -> C)) (b2 : Batch A2 B (B -> C)), P (B -> C) b1 b2 -> forall (a1 : A1) (a2 : A2), shape (b1 ⧆ a1) = shape (b2 ⧆ a2) -> P C (b1 ⧆ a1) (b2 ⧆ a2)

P C b1 b2
A1, A2, B, C: Type
b1: Batch A1 B C
b2: Batch A2 B C
Hshape: shape b1 = shape b2
P: forall C : Type, Batch A1 B C -> Batch A2 B C -> Prop
IHdone: forall (C : Type) (c : C), P C (Done c) (Done c)
IHstep: forall (C : Type) (b1 : Batch A1 B (B -> C)) (b2 : Batch A2 B (B -> C)), P (B -> C) b1 b2 -> forall (a1 : A1) (a2 : A2), shape (b1 ⧆ a1) = shape (b2 ⧆ a2) -> P C (b1 ⧆ a1) (b2 ⧆ a2)

P C b1 b2
A1, A2, B, C: Type
b1: Batch A1 B C
b2: Batch A2 B C
c: C
Hshape: shape (Done c) = shape b2
P: forall C : Type, Batch A1 B C -> Batch A2 B C -> Prop
IHdone: forall (C : Type) (c : C), P C (Done c) (Done c)
IHstep: forall (C : Type) (b1 : Batch A1 B (B -> C)) (b2 : Batch A2 B (B -> C)), P (B -> C) b1 b2 -> forall (a1 : A1) (a2 : A2), shape (b1 ⧆ a1) = shape (b2 ⧆ a2) -> P C (b1 ⧆ a1) (b2 ⧆ a2)

P C (Done c) b2
A1, A2, B, C: Type
b1: Batch A1 B C
b2: Batch A2 B C
rest: Batch A1 B (B -> C)
a: A1
Hshape: shape (rest ⧆ a) = shape b2
P: forall C : Type, Batch A1 B C -> Batch A2 B C -> Prop
IHdone: forall (C : Type) (c : C), P C (Done c) (Done c)
IHstep: forall (C : Type) (b1 : Batch A1 B (B -> C)) (b2 : Batch A2 B (B -> C)), P (B -> C) b1 b2 -> forall (a1 : A1) (a2 : A2), shape (b1 ⧆ a1) = shape (b2 ⧆ a2) -> P C (b1 ⧆ a1) (b2 ⧆ a2)
IHrest: Batch A1 B (B -> C) -> forall b2 : Batch A2 B (B -> C), shape rest = shape b2 -> P (B -> C) rest b2
P C (rest ⧆ a) b2
A1, A2, B, C: Type
b1: Batch A1 B C
b2: Batch A2 B C
c: C
Hshape: shape (Done c) = shape b2
P: forall C : Type, Batch A1 B C -> Batch A2 B C -> Prop
IHdone: forall (C : Type) (c : C), P C (Done c) (Done c)
IHstep: forall (C : Type) (b1 : Batch A1 B (B -> C)) (b2 : Batch A2 B (B -> C)), P (B -> C) b1 b2 -> forall (a1 : A1) (a2 : A2), shape (b1 ⧆ a1) = shape (b2 ⧆ a2) -> P C (b1 ⧆ a1) (b2 ⧆ a2)

P C (Done c) b2
A1, A2, B, C: Type
b1: Batch A1 B C
b2: Batch A2 B C
c, c0: C
Hshape: shape (Done c) = shape (Done c0)
P: forall C : Type, Batch A1 B C -> Batch A2 B C -> Prop
IHdone: forall (C : Type) (c : C), P C (Done c) (Done c)
IHstep: forall (C : Type) (b1 : Batch A1 B (B -> C)) (b2 : Batch A2 B (B -> C)), P (B -> C) b1 b2 -> forall (a1 : A1) (a2 : A2), shape (b1 ⧆ a1) = shape (b2 ⧆ a2) -> P C (b1 ⧆ a1) (b2 ⧆ a2)

P C (Done c) (Done c0)
A1, A2, B, C: Type
b1: Batch A1 B C
b2: Batch A2 B C
c: C
b: Batch A2 B (B -> C)
a: A2
Hshape: shape (Done c) = shape (b ⧆ a)
P: forall C : Type, Batch A1 B C -> Batch A2 B C -> Prop
IHdone: forall (C : Type) (c : C), P C (Done c) (Done c)
IHstep: forall (C : Type) (b1 : Batch A1 B (B -> C)) (b2 : Batch A2 B (B -> C)), P (B -> C) b1 b2 -> forall (a1 : A1) (a2 : A2), shape (b1 ⧆ a1) = shape (b2 ⧆ a2) -> P C (b1 ⧆ a1) (b2 ⧆ a2)
P C (Done c) (b ⧆ a)
A1, A2, B, C: Type
b1: Batch A1 B C
b2: Batch A2 B C
c, c0: C
Hshape: shape (Done c) = shape (Done c0)
P: forall C : Type, Batch A1 B C -> Batch A2 B C -> Prop
IHdone: forall (C : Type) (c : C), P C (Done c) (Done c)
IHstep: forall (C : Type) (b1 : Batch A1 B (B -> C)) (b2 : Batch A2 B (B -> C)), P (B -> C) b1 b2 -> forall (a1 : A1) (a2 : A2), shape (b1 ⧆ a1) = shape (b2 ⧆ a2) -> P C (b1 ⧆ a1) (b2 ⧆ a2)

P C (Done c) (Done c0)
now inversion Hshape.
A1, A2, B, C: Type
b1: Batch A1 B C
b2: Batch A2 B C
c: C
b: Batch A2 B (B -> C)
a: A2
Hshape: shape (Done c) = shape (b ⧆ a)
P: forall C : Type, Batch A1 B C -> Batch A2 B C -> Prop
IHdone: forall (C : Type) (c : C), P C (Done c) (Done c)
IHstep: forall (C : Type) (b1 : Batch A1 B (B -> C)) (b2 : Batch A2 B (B -> C)), P (B -> C) b1 b2 -> forall (a1 : A1) (a2 : A2), shape (b1 ⧆ a1) = shape (b2 ⧆ a2) -> P C (b1 ⧆ a1) (b2 ⧆ a2)

P C (Done c) (b ⧆ a)
false.
A1, A2, B, C: Type
b1: Batch A1 B C
b2: Batch A2 B C
rest: Batch A1 B (B -> C)
a: A1
Hshape: shape (rest ⧆ a) = shape b2
P: forall C : Type, Batch A1 B C -> Batch A2 B C -> Prop
IHdone: forall (C : Type) (c : C), P C (Done c) (Done c)
IHstep: forall (C : Type) (b1 : Batch A1 B (B -> C)) (b2 : Batch A2 B (B -> C)), P (B -> C) b1 b2 -> forall (a1 : A1) (a2 : A2), shape (b1 ⧆ a1) = shape (b2 ⧆ a2) -> P C (b1 ⧆ a1) (b2 ⧆ a2)
IHrest: Batch A1 B (B -> C) -> forall b2 : Batch A2 B (B -> C), shape rest = shape b2 -> P (B -> C) rest b2

P C (rest ⧆ a) b2
A1, A2, B, C: Type
b1: Batch A1 B C
b2: Batch A2 B C
rest: Batch A1 B (B -> C)
a: A1
c': C
Hshape: shape (rest ⧆ a) = shape (Done c')
P: forall C : Type, Batch A1 B C -> Batch A2 B C -> Prop
IHdone: forall (C : Type) (c : C), P C (Done c) (Done c)
IHstep: forall (C : Type) (b1 : Batch A1 B (B -> C)) (b2 : Batch A2 B (B -> C)), P (B -> C) b1 b2 -> forall (a1 : A1) (a2 : A2), shape (b1 ⧆ a1) = shape (b2 ⧆ a2) -> P C (b1 ⧆ a1) (b2 ⧆ a2)
IHrest: Batch A1 B (B -> C) -> forall b2 : Batch A2 B (B -> C), shape rest = shape b2 -> P (B -> C) rest b2

P C (rest ⧆ a) (Done c')
A1, A2, B, C: Type
b1: Batch A1 B C
b2: Batch A2 B C
rest: Batch A1 B (B -> C)
a: A1
rest': Batch A2 B (B -> C)
a': A2
Hshape: shape (rest ⧆ a) = shape (rest' ⧆ a')
P: forall C : Type, Batch A1 B C -> Batch A2 B C -> Prop
IHdone: forall (C : Type) (c : C), P C (Done c) (Done c)
IHstep: forall (C : Type) (b1 : Batch A1 B (B -> C)) (b2 : Batch A2 B (B -> C)), P (B -> C) b1 b2 -> forall (a1 : A1) (a2 : A2), shape (b1 ⧆ a1) = shape (b2 ⧆ a2) -> P C (b1 ⧆ a1) (b2 ⧆ a2)
IHrest: Batch A1 B (B -> C) -> forall b2 : Batch A2 B (B -> C), shape rest = shape b2 -> P (B -> C) rest b2
P C (rest ⧆ a) (rest' ⧆ a')
A1, A2, B, C: Type
b1: Batch A1 B C
b2: Batch A2 B C
rest: Batch A1 B (B -> C)
a: A1
c': C
Hshape: shape (rest ⧆ a) = shape (Done c')
P: forall C : Type, Batch A1 B C -> Batch A2 B C -> Prop
IHdone: forall (C : Type) (c : C), P C (Done c) (Done c)
IHstep: forall (C : Type) (b1 : Batch A1 B (B -> C)) (b2 : Batch A2 B (B -> C)), P (B -> C) b1 b2 -> forall (a1 : A1) (a2 : A2), shape (b1 ⧆ a1) = shape (b2 ⧆ a2) -> P C (b1 ⧆ a1) (b2 ⧆ a2)
IHrest: Batch A1 B (B -> C) -> forall b2 : Batch A2 B (B -> C), shape rest = shape b2 -> P (B -> C) rest b2

P C (rest ⧆ a) (Done c')
false.
A1, A2, B, C: Type
b1: Batch A1 B C
b2: Batch A2 B C
rest: Batch A1 B (B -> C)
a: A1
rest': Batch A2 B (B -> C)
a': A2
Hshape: shape (rest ⧆ a) = shape (rest' ⧆ a')
P: forall C : Type, Batch A1 B C -> Batch A2 B C -> Prop
IHdone: forall (C : Type) (c : C), P C (Done c) (Done c)
IHstep: forall (C : Type) (b1 : Batch A1 B (B -> C)) (b2 : Batch A2 B (B -> C)), P (B -> C) b1 b2 -> forall (a1 : A1) (a2 : A2), shape (b1 ⧆ a1) = shape (b2 ⧆ a2) -> P C (b1 ⧆ a1) (b2 ⧆ a2)
IHrest: Batch A1 B (B -> C) -> forall b2 : Batch A2 B (B -> C), shape rest = shape b2 -> P (B -> C) rest b2

P C (rest ⧆ a) (rest' ⧆ a')
A1, A2, B, C: Type
b1: Batch A1 B C
b2: Batch A2 B C
rest: Batch A1 B (B -> C)
a: A1
rest': Batch A2 B (B -> C)
a': A2
Hshape: shape (rest ⧆ a) = shape (rest' ⧆ a')
P: forall C : Type, Batch A1 B C -> Batch A2 B C -> Prop
IHdone: forall (C : Type) (c : C), P C (Done c) (Done c)
IHstep: forall (C : Type) (b1 : Batch A1 B (B -> C)) (b2 : Batch A2 B (B -> C)), P (B -> C) b1 b2 -> forall (a1 : A1) (a2 : A2), shape (b1 ⧆ a1) = shape (b2 ⧆ a2) -> P C (b1 ⧆ a1) (b2 ⧆ a2)
IHrest: Batch A1 B (B -> C) -> forall b2 : Batch A2 B (B -> C), shape rest = shape b2 -> P (B -> C) rest b2

P (B -> C) rest rest'
A1, A2, B, C: Type
b1: Batch A1 B C
b2: Batch A2 B C
rest: Batch A1 B (B -> C)
a: A1
rest': Batch A2 B (B -> C)
a': A2
Hshape: shape (rest ⧆ a) = shape (rest' ⧆ a')
P: forall C : Type, Batch A1 B C -> Batch A2 B C -> Prop
IHdone: forall (C : Type) (c : C), P C (Done c) (Done c)
IHstep: forall (C : Type) (b1 : Batch A1 B (B -> C)) (b2 : Batch A2 B (B -> C)), P (B -> C) b1 b2 -> forall (a1 : A1) (a2 : A2), shape (b1 ⧆ a1) = shape (b2 ⧆ a2) -> P C (b1 ⧆ a1) (b2 ⧆ a2)
IHrest: Batch A1 B (B -> C) -> forall b2 : Batch A2 B (B -> C), shape rest = shape b2 -> P (B -> C) rest b2
shape (rest ⧆ a) = shape (rest' ⧆ a')
A1, A2, B, C: Type
b1: Batch A1 B C
b2: Batch A2 B C
rest: Batch A1 B (B -> C)
a: A1
rest': Batch A2 B (B -> C)
a': A2
Hshape: shape (rest ⧆ a) = shape (rest' ⧆ a')
P: forall C : Type, Batch A1 B C -> Batch A2 B C -> Prop
IHdone: forall (C : Type) (c : C), P C (Done c) (Done c)
IHstep: forall (C : Type) (b1 : Batch A1 B (B -> C)) (b2 : Batch A2 B (B -> C)), P (B -> C) b1 b2 -> forall (a1 : A1) (a2 : A2), shape (b1 ⧆ a1) = shape (b2 ⧆ a2) -> P C (b1 ⧆ a1) (b2 ⧆ a2)
IHrest: Batch A1 B (B -> C) -> forall b2 : Batch A2 B (B -> C), shape rest = shape b2 -> P (B -> C) rest b2

P (B -> C) rest rest'
A1, A2, B, C: Type
b1: Batch A1 B C
b2: Batch A2 B C
rest: Batch A1 B (B -> C)
a: A1
rest': Batch A2 B (B -> C)
a': A2
Hshape: shape (rest ⧆ a) = shape (rest' ⧆ a')
P: forall C : Type, Batch A1 B C -> Batch A2 B C -> Prop
IHdone: forall (C : Type) (c : C), P C (Done c) (Done c)
IHstep: forall (C : Type) (b1 : Batch A1 B (B -> C)) (b2 : Batch A2 B (B -> C)), P (B -> C) b1 b2 -> forall (a1 : A1) (a2 : A2), shape (b1 ⧆ a1) = shape (b2 ⧆ a2) -> P C (b1 ⧆ a1) (b2 ⧆ a2)
IHrest: Batch A1 B (B -> C) -> forall b2 : Batch A2 B (B -> C), shape rest = shape b2 -> P (B -> C) rest b2

Batch A1 B (B -> C)
A1, A2, B, C: Type
b1: Batch A1 B C
b2: Batch A2 B C
rest: Batch A1 B (B -> C)
a: A1
rest': Batch A2 B (B -> C)
a': A2
Hshape: shape (rest ⧆ a) = shape (rest' ⧆ a')
P: forall C : Type, Batch A1 B C -> Batch A2 B C -> Prop
IHdone: forall (C : Type) (c : C), P C (Done c) (Done c)
IHstep: forall (C : Type) (b1 : Batch A1 B (B -> C)) (b2 : Batch A2 B (B -> C)), P (B -> C) b1 b2 -> forall (a1 : A1) (a2 : A2), shape (b1 ⧆ a1) = shape (b2 ⧆ a2) -> P C (b1 ⧆ a1) (b2 ⧆ a2)
IHrest: Batch A1 B (B -> C) -> forall b2 : Batch A2 B (B -> C), shape rest = shape b2 -> P (B -> C) rest b2
shape rest = shape rest'
A1, A2, B, C: Type
b1: Batch A1 B C
b2: Batch A2 B C
rest: Batch A1 B (B -> C)
a: A1
rest': Batch A2 B (B -> C)
a': A2
Hshape: shape (rest ⧆ a) = shape (rest' ⧆ a')
P: forall C : Type, Batch A1 B C -> Batch A2 B C -> Prop
IHdone: forall (C : Type) (c : C), P C (Done c) (Done c)
IHstep: forall (C : Type) (b1 : Batch A1 B (B -> C)) (b2 : Batch A2 B (B -> C)), P (B -> C) b1 b2 -> forall (a1 : A1) (a2 : A2), shape (b1 ⧆ a1) = shape (b2 ⧆ a2) -> P C (b1 ⧆ a1) (b2 ⧆ a2)
IHrest: Batch A1 B (B -> C) -> forall b2 : Batch A2 B (B -> C), shape rest = shape b2 -> P (B -> C) rest b2

shape rest = shape rest'
now inversion Hshape.
A1, A2, B, C: Type
b1: Batch A1 B C
b2: Batch A2 B C
rest: Batch A1 B (B -> C)
a: A1
rest': Batch A2 B (B -> C)
a': A2
Hshape: shape (rest ⧆ a) = shape (rest' ⧆ a')
P: forall C : Type, Batch A1 B C -> Batch A2 B C -> Prop
IHdone: forall (C : Type) (c : C), P C (Done c) (Done c)
IHstep: forall (C : Type) (b1 : Batch A1 B (B -> C)) (b2 : Batch A2 B (B -> C)), P (B -> C) b1 b2 -> forall (a1 : A1) (a2 : A2), shape (b1 ⧆ a1) = shape (b2 ⧆ a2) -> P C (b1 ⧆ a1) (b2 ⧆ a2)
IHrest: Batch A1 B (B -> C) -> forall b2 : Batch A2 B (B -> C), shape rest = shape b2 -> P (B -> C) rest b2

shape (rest ⧆ a) = shape (rest' ⧆ a')
apply Hshape. Qed. End shape_induction. (* (** * Miscellaneous *) (******************************************************************************) Instance: forall B, Pure (BATCH1 B B). Proof. unfold Pure. intros B A. apply batch. Defined. Instance: forall B, Mult (BATCH1 B B). Proof. unfold Mult. intros B A A'. apply batch. Defined. *) (** * <<runBatch>> specialized to monoids *) (******************************************************************************) Section runBatch_monoid. Context `{Monoid M}. Fixpoint runBatch_monoid {A B: Type} `(ϕ: A -> M) `(b: Batch A B C): M := match b with | Done c => monoid_unit M | Step rest a => runBatch_monoid (ϕ: A -> M) rest ● ϕ a end.
M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
A, B: Type

forall (ϕ : A -> M) (C : Type) (b : Batch A B C), runBatch_monoid ϕ b = unconst (runBatch (mkConst ∘ ϕ) b)
M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
A, B: Type

forall (ϕ : A -> M) (C : Type) (b : Batch A B C), runBatch_monoid ϕ b = unconst (runBatch (mkConst ∘ ϕ) b)
M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
A, B: Type
ϕ: A -> M
C: Type
b: Batch A B C

runBatch_monoid ϕ b = unconst (runBatch (mkConst ∘ ϕ) b)
M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
A, B: Type
ϕ: A -> M
C: Type
c: C

runBatch_monoid ϕ (Done c) = unconst (runBatch (mkConst ∘ ϕ) (Done c))
M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
A, B: Type
ϕ: A -> M
C: Type
b: Batch A B (B -> C)
a: A
IHb: runBatch_monoid ϕ b = unconst (runBatch (mkConst ∘ ϕ) b)
runBatch_monoid ϕ (b ⧆ a) = unconst (runBatch (mkConst ∘ ϕ) (b ⧆ a))
M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
A, B: Type
ϕ: A -> M
C: Type
c: C

runBatch_monoid ϕ (Done c) = unconst (runBatch (mkConst ∘ ϕ) (Done c))
easy.
M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
A, B: Type
ϕ: A -> M
C: Type
b: Batch A B (B -> C)
a: A
IHb: runBatch_monoid ϕ b = unconst (runBatch (mkConst ∘ ϕ) b)

runBatch_monoid ϕ (b ⧆ a) = unconst (runBatch (mkConst ∘ ϕ) (b ⧆ a))
M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
A, B: Type
ϕ: A -> M
C: Type
b: Batch A B (B -> C)
a: A
IHb: runBatch_monoid ϕ b = unconst (runBatch (mkConst ∘ ϕ) b)

runBatch_monoid ϕ b ● ϕ a = unconst (runBatch (mkConst ∘ ϕ) b) ● ϕ a
now rewrite IHb. Qed.
M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
A, B: Type

forall (ϕ : A -> M) (C : Type) (b : Batch A B C), runBatch_monoid ϕ b = runBatch (ϕ : A -> const M B) b
M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
A, B: Type

forall (ϕ : A -> M) (C : Type) (b : Batch A B C), runBatch_monoid ϕ b = runBatch (ϕ : A -> const M B) b
M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
A, B: Type
ϕ: A -> M
C: Type
b: Batch A B C

runBatch_monoid ϕ b = runBatch (ϕ : A -> const M B) b
M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
A, B: Type
ϕ: A -> M
C: Type
c: C

runBatch_monoid ϕ (Done c) = runBatch ϕ (Done c)
M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
A, B: Type
ϕ: A -> M
C: Type
b: Batch A B (B -> C)
a: A
IHb: runBatch_monoid ϕ b = runBatch ϕ b
runBatch_monoid ϕ (b ⧆ a) = runBatch ϕ (b ⧆ a)
M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
A, B: Type
ϕ: A -> M
C: Type
c: C

runBatch_monoid ϕ (Done c) = runBatch ϕ (Done c)
easy.
M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
A, B: Type
ϕ: A -> M
C: Type
b: Batch A B (B -> C)
a: A
IHb: runBatch_monoid ϕ b = runBatch ϕ b

runBatch_monoid ϕ (b ⧆ a) = runBatch ϕ (b ⧆ a)
M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
A, B: Type
ϕ: A -> M
C: Type
b: Batch A B (B -> C)
a: A
IHb: runBatch_monoid ϕ b = runBatch ϕ b

runBatch_monoid ϕ b ● ϕ a = runBatch ϕ b ● ϕ a
now rewrite IHb. Qed.
M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
A, B, C, C': Type

forall (ϕ : A -> M) (f : C -> C') (b : Batch A B C), runBatch_monoid ϕ b = runBatch_monoid ϕ (map (Batch A B) f b)
M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
A, B, C, C': Type

forall (ϕ : A -> M) (f : C -> C') (b : Batch A B C), runBatch_monoid ϕ b = runBatch_monoid ϕ (map (Batch A B) f b)
M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
A, B, C, C': Type
ϕ: A -> M
f: C -> C'
b: Batch A B C

runBatch_monoid ϕ b = runBatch_monoid ϕ (map (Batch A B) f b)
M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
A, B, C: Type
ϕ: A -> M
b: Batch A B C

forall (C' : Type) (f : C -> C'), runBatch_monoid ϕ b = runBatch_monoid ϕ (map (Batch A B) f b)
M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
A, B: Type
ϕ: A -> M
C: Type
c: C
C': Type
f: C -> C'

runBatch_monoid ϕ (Done c) = runBatch_monoid ϕ (map (Batch A B) f (Done c))
M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
A, B: Type
ϕ: A -> M
C: Type
b: Batch A B (B -> C)
a: A
IHb: forall (C' : Type) (f : (B -> C) -> C'), runBatch_monoid ϕ b = runBatch_monoid ϕ (map (Batch A B) f b)
C': Type
f: C -> C'
runBatch_monoid ϕ (b ⧆ a) = runBatch_monoid ϕ (map (Batch A B) f (b ⧆ a))
M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
A, B: Type
ϕ: A -> M
C: Type
c: C
C': Type
f: C -> C'

runBatch_monoid ϕ (Done c) = runBatch_monoid ϕ (map (Batch A B) f (Done c))
reflexivity.
M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
A, B: Type
ϕ: A -> M
C: Type
b: Batch A B (B -> C)
a: A
IHb: forall (C' : Type) (f : (B -> C) -> C'), runBatch_monoid ϕ b = runBatch_monoid ϕ (map (Batch A B) f b)
C': Type
f: C -> C'

runBatch_monoid ϕ (b ⧆ a) = runBatch_monoid ϕ (map (Batch A B) f (b ⧆ a))
M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
A, B: Type
ϕ: A -> M
C: Type
b: Batch A B (B -> C)
a: A
IHb: forall (C' : Type) (f : (B -> C) -> C'), runBatch_monoid ϕ b = runBatch_monoid ϕ (map (Batch A B) f b)
C': Type
f: C -> C'

runBatch_monoid ϕ b ● ϕ a = runBatch_monoid ϕ (map (Batch A B) (compose f) b) ● ϕ a
M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
A, B: Type
ϕ: A -> M
C: Type
b: Batch A B (B -> C)
a: A
IHb: forall (C' : Type) (f : (B -> C) -> C'), runBatch_monoid ϕ b = runBatch_monoid ϕ (map (Batch A B) f b)
C': Type
f: C -> C'

runBatch_monoid ϕ b ● ϕ a = runBatch_monoid ϕ b ● ϕ a
reflexivity. Qed.
M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
A, B, B': Type

forall (ϕ : A -> M) (f : B' -> B) (C : Type) (b : Batch A B C), runBatch_monoid ϕ b = runBatch_monoid ϕ (mapsnd_Batch f b)
M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
A, B, B': Type

forall (ϕ : A -> M) (f : B' -> B) (C : Type) (b : Batch A B C), runBatch_monoid ϕ b = runBatch_monoid ϕ (mapsnd_Batch f b)
M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
A, B, B': Type
ϕ: A -> M
f: B' -> B
C: Type
b: Batch A B C

runBatch_monoid ϕ b = runBatch_monoid ϕ (mapsnd_Batch f b)
M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
A, B, B': Type
ϕ: A -> M
f: B' -> B
C: Type
b: Batch A B C

runBatch ϕ b = runBatch_monoid ϕ (mapsnd_Batch f b)
M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
A, B, B': Type
ϕ: A -> M
f: B' -> B
C: Type
b: Batch A B C

runBatch ϕ b = runBatch ϕ (mapsnd_Batch f b)
M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
A, B, B': Type
ϕ: A -> M
f: B' -> B
C: Type
b: Batch A B C

runBatch ϕ b = runBatch (map (const M) f ∘ ϕ) b
M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
A, B, B': Type
ϕ: A -> M
f: B' -> B
C: Type
b: Batch A B C

runBatch ϕ b = runBatch (map (const M) f ∘ ϕ) b
M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
A, B, B': Type
ϕ: A -> M
f: B' -> B
C: Type
c: C

runBatch ϕ (Done c) = runBatch (map (const M) f ∘ ϕ) (Done c)
M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
A, B, B': Type
ϕ: A -> M
f: B' -> B
C: Type
b: Batch A B (B -> C)
a: A
IHb: runBatch ϕ b = runBatch (map (const M) f ∘ ϕ) b
runBatch ϕ (b ⧆ a) = runBatch (map (const M) f ∘ ϕ) (b ⧆ a)
M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
A, B, B': Type
ϕ: A -> M
f: B' -> B
C: Type
c: C

runBatch ϕ (Done c) = runBatch (map (const M) f ∘ ϕ) (Done c)
easy.
M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
A, B, B': Type
ϕ: A -> M
f: B' -> B
C: Type
b: Batch A B (B -> C)
a: A
IHb: runBatch ϕ b = runBatch (map (const M) f ∘ ϕ) b

runBatch ϕ (b ⧆ a) = runBatch (map (const M) f ∘ ϕ) (b ⧆ a)
M: Type
op: Monoid_op M
unit0: Monoid_unit M
H: Monoid M
A, B, B': Type
ϕ: A -> M
f: B' -> B
C: Type
b: Batch A B (B -> C)
a: A
IHb: runBatch ϕ b = runBatch (map (const M) f ∘ ϕ) b

runBatch ϕ b ● ϕ a = runBatch (map (const M) f ∘ ϕ) b ● (map (const M) f ∘ ϕ) a
now rewrite IHb. Qed. End runBatch_monoid. (** * The <<length_Batch>> Operation *) (** This function is introduced because using <<plength>> has less desirable simplification behavior, which makes programming functions like <<Batch_make>> difficult *) (******************************************************************************) From Tealeaves Require Import Misc.NaturalNumbers. Section length. Fixpoint length_Batch {A B C: Type} (b: Batch A B C): nat := match b with | Done _ => 0 | Step rest a => S (length_Batch (C := B -> C) rest) end.
A, B, C: Type
b: Batch A B C

length_Batch b = plength b
A, B, C: Type
b: Batch A B C

length_Batch b = plength b
A, B, C: Type
c: C

length_Batch (Done c) = plength (Done c)
A, B, C: Type
b: Batch A B (B -> C)
a: A
IHb: length_Batch b = plength b
length_Batch (b ⧆ a) = plength (b ⧆ a)
A, B, C: Type
c: C

length_Batch (Done c) = plength (Done c)
reflexivity.
A, B, C: Type
b: Batch A B (B -> C)
a: A
IHb: length_Batch b = plength b

length_Batch (b ⧆ a) = plength (b ⧆ a)
A, B, C: Type
b: Batch A B (B -> C)
a: A
IHb: length_Batch b = plength b

S (length_Batch b) = Traverse_Batch1 B (B -> C) (const nat) Map_const Pure_const Mult_const A False (fun _ : A => 1) b ● 1
A, B, C: Type
b: Batch A B (B -> C)
a: A
IHb: length_Batch b = plength b

S (plength b) = Traverse_Batch1 B (B -> C) (const nat) Map_const Pure_const Mult_const A False (fun _ : A => 1) b ● 1
A, B, C: Type
b: Batch A B (B -> C)
a: A
IHb: length_Batch b = plength b

S (plength b) = (Traverse_Batch1 B (B -> C) (const nat) Map_const Pure_const Mult_const A False (fun _ : A => 1) b + 1)%nat
A, B, C: Type
b: Batch A B (B -> C)
a: A
IHb: length_Batch b = plength b

S (plength b) = S (Traverse_Batch1 B (B -> C) (const nat) Map_const Pure_const Mult_const A False (fun _ : A => 1) b)
reflexivity. Qed.
A, B, C: Type
b: Batch A B C

length_Batch b = runBatch (fun _ : A => 1) b
A, B, C: Type
b: Batch A B C

length_Batch b = runBatch (fun _ : A => 1) b
A, B, C: Type
b: Batch A B C

plength b = runBatch (fun _ : A => 1) b
A, B, C: Type
c: C

plength (Done c) = runBatch (fun _ : A => 1) (Done c)
A, B, C: Type
b: Batch A B (B -> C)
a: A
IHb: plength b = runBatch (fun _ : A => 1) b
plength (b ⧆ a) = runBatch (fun _ : A => 1) (b ⧆ a)
A, B, C: Type
c: C

plength (Done c) = runBatch (fun _ : A => 1) (Done c)
reflexivity.
A, B, C: Type
b: Batch A B (B -> C)
a: A
IHb: plength b = runBatch (fun _ : A => 1) b

plength (b ⧆ a) = runBatch (fun _ : A => 1) (b ⧆ a)
A, B, C: Type
b: Batch A B (B -> C)
a: A
IHb: plength b = runBatch (fun _ : A => 1) b

Traverse_Batch1 B (B -> C) (const nat) Map_const Pure_const Mult_const A False (fun _ : A => 1) b ● 1 = runBatch (fun _ : A => 1) b ● 1
A, B, C: Type
b: Batch A B (B -> C)
a: A
IHb: plength b = runBatch (fun _ : A => 1) b

Traverse_Batch1 B (B -> C) (const nat) Map_const Pure_const Mult_const A False (fun _ : A => 1) b ● 1 = plength b ● 1
reflexivity. Qed. (** ** Rewriting Rules *) (** TODO *) (******************************************************************************)
A, B, C: Type

forall (b : Batch A B (B -> C)) (a : A), length_Batch (b ⧆ a) = S (length_Batch b)
A, B, C: Type

forall (b : Batch A B (B -> C)) (a : A), length_Batch (b ⧆ a) = S (length_Batch b)
reflexivity. Qed. (** ** Length is the Same as the Underlying <<list>> *) (* The length of a <<Batch>> is the same as the length of the list we can extract from it *) (******************************************************************************)

forall (A B C : Type) (b : Batch A B C), length_Batch b = length (runBatch (ret list A) b)

forall (A B C : Type) (b : Batch A B C), length_Batch b = length (runBatch (ret list A) b)
A, B, C: Type
b: Batch A B C

length_Batch b = length (runBatch (ret list A) b)
A, B, C: Type
c: C

length_Batch (Done c) = length (runBatch (ret list A) (Done c))
A, B, C: Type
b: Batch A B (B -> C)
a: A
IHb: length_Batch b = length (runBatch (ret list A) b)
length_Batch (b ⧆ a) = length (runBatch (ret list A) (b ⧆ a))
A, B, C: Type
c: C

length_Batch (Done c) = length (runBatch (ret list A) (Done c))
reflexivity.
A, B, C: Type
b: Batch A B (B -> C)
a: A
IHb: length_Batch b = length (runBatch (ret list A) b)

length_Batch (b ⧆ a) = length (runBatch (ret list A) (b ⧆ a))
A, B, C: Type
b: Batch A B (B -> C)
a: A
IHb: length_Batch b = length (runBatch (ret list A) b)

S (length_Batch b) = length (runBatch (ret list A) b ● ret list A a)
A, B, C: Type
b: Batch A B (B -> C)
a: A
IHb: length_Batch b = length (runBatch (ret list A) b)

S (length (runBatch (ret list A) b)) = length (runBatch (ret list A) b ● ret list A a)
A, B, C: Type
b: Batch A B (B -> C)
a: A
IHb: length_Batch b = length (runBatch (ret list A) b)

S (length (runBatch (ret list A) b)) = length (runBatch (ret list A) b ++ ret list A a)
A, B, C: Type
b: Batch A B (B -> C)
a: A
IHb: length_Batch b = length (runBatch (ret list A) b)

S (length (runBatch (ret list A) b)) = (length (runBatch (ret list A) b) + length (ret list A a))%nat
A, B, C: Type
b: Batch A B (B -> C)
a: A
IHb: length_Batch b = length (runBatch (ret list A) b)

S (length (runBatch (ret list A) b)) = (length (runBatch (ret list A) b) + 1)%nat
lia. Qed. (** ** Length is Preserved By <<map>> *) (******************************************************************************)

forall (A B C C' : Type) (f : C -> C') (b : Batch A B C), length_Batch b = length_Batch (map (Batch A B) f b)

forall (A B C C' : Type) (f : C -> C') (b : Batch A B C), length_Batch b = length_Batch (map (Batch A B) f b)
A, B, C, C': Type
f: C -> C'
b: Batch A B C

length_Batch b = length_Batch (map (Batch A B) f b)
A, B, C: Type
b: Batch A B C

forall (C' : Type) (f : C -> C'), length_Batch b = length_Batch (map (Batch A B) f b)
A, B, C: Type
c: C
C': Type
f: C -> C'

length_Batch (Done c) = length_Batch (map (Batch A B) f (Done c))
A, B, C: Type
b: Batch A B (B -> C)
a: A
IHb: forall (C' : Type) (f : (B -> C) -> C'), length_Batch b = length_Batch (map (Batch A B) f b)
C': Type
f: C -> C'
length_Batch (b ⧆ a) = length_Batch (map (Batch A B) f (b ⧆ a))
A, B, C: Type
c: C
C': Type
f: C -> C'

length_Batch (Done c) = length_Batch (map (Batch A B) f (Done c))
reflexivity.
A, B, C: Type
b: Batch A B (B -> C)
a: A
IHb: forall (C' : Type) (f : (B -> C) -> C'), length_Batch b = length_Batch (map (Batch A B) f b)
C': Type
f: C -> C'

length_Batch (b ⧆ a) = length_Batch (map (Batch A B) f (b ⧆ a))
A, B, C: Type
b: Batch A B (B -> C)
a: A
IHb: forall (C' : Type) (f : (B -> C) -> C'), length_Batch b = length_Batch (map (Batch A B) f b)
C': Type
f: C -> C'

S (length_Batch b) = S (length_Batch (map (Batch A B) (compose f) b))
A, B, C: Type
b: Batch A B (B -> C)
a: A
IHb: forall (C' : Type) (f : (B -> C) -> C'), length_Batch b = length_Batch (map (Batch A B) f b)
C': Type
f: C -> C'

length_Batch b = length_Batch (map (Batch A B) (compose f) b)
A, B, C: Type
b: Batch A B (B -> C)
a: A
C': Type
f: C -> C'
IHb: length_Batch b = length_Batch (map (Batch A B) (compose f) b)

length_Batch b = length_Batch (map (Batch A B) (compose f) b)
auto. Qed.

forall (A A' B C : Type) (f : A -> A') (b : Batch A B C), length_Batch b = length_Batch (mapfst_Batch f b)

forall (A A' B C : Type) (f : A -> A') (b : Batch A B C), length_Batch b = length_Batch (mapfst_Batch f b)
A, A', B, C: Type
f: A -> A'
b: Batch A B C

length_Batch b = length_Batch (mapfst_Batch f b)
A, A', B: Type
f: A -> A'
C: Type
c: C

length_Batch (Done c) = length_Batch (mapfst_Batch f (Done c))
A, A', B: Type
f: A -> A'
C: Type
b: Batch A B (B -> C)
a: A
IHb: length_Batch b = length_Batch (mapfst_Batch f b)
length_Batch (b ⧆ a) = length_Batch (mapfst_Batch f (b ⧆ a))
A, A', B: Type
f: A -> A'
C: Type
c: C

length_Batch (Done c) = length_Batch (mapfst_Batch f (Done c))
reflexivity.
A, A', B: Type
f: A -> A'
C: Type
b: Batch A B (B -> C)
a: A
IHb: length_Batch b = length_Batch (mapfst_Batch f b)

length_Batch (b ⧆ a) = length_Batch (mapfst_Batch f (b ⧆ a))
A, A', B: Type
f: A -> A'
C: Type
b: Batch A B (B -> C)
a: A
IHb: length_Batch b = length_Batch (mapfst_Batch f b)

S (length_Batch b) = S (length_Batch (mapfst_Batch f b))
A, A', B: Type
f: A -> A'
C: Type
b: Batch A B (B -> C)
a: A
IHb: length_Batch b = length_Batch (mapfst_Batch f b)

S (length_Batch (mapfst_Batch f b)) = S (length_Batch (mapfst_Batch f b))
reflexivity. Qed.

forall (A B B' C : Type) (f : B' -> B) (b : Batch A B C), length_Batch b = length_Batch (mapsnd_Batch f b)

forall (A B B' C : Type) (f : B' -> B) (b : Batch A B C), length_Batch b = length_Batch (mapsnd_Batch f b)
A, B, B', C: Type
f: B' -> B
b: Batch A B C

length_Batch b = length_Batch (mapsnd_Batch f b)
A, B, B': Type
f: B' -> B
C: Type
c: C

length_Batch (Done c) = length_Batch (mapsnd_Batch f (Done c))
A, B, B': Type
f: B' -> B
C: Type
b: Batch A B (B -> C)
a: A
IHb: length_Batch b = length_Batch (mapsnd_Batch f b)
length_Batch (b ⧆ a) = length_Batch (mapsnd_Batch f (b ⧆ a))
A, B, B': Type
f: B' -> B
C: Type
c: C

length_Batch (Done c) = length_Batch (mapsnd_Batch f (Done c))
reflexivity.
A, B, B': Type
f: B' -> B
C: Type
b: Batch A B (B -> C)
a: A
IHb: length_Batch b = length_Batch (mapsnd_Batch f b)

length_Batch (b ⧆ a) = length_Batch (mapsnd_Batch f (b ⧆ a))
A, B, B': Type
f: B' -> B
C: Type
b: Batch A B (B -> C)
a: A
IHb: length_Batch b = length_Batch (mapsnd_Batch f b)

S (length_Batch b) = S (length_Batch (map (Batch A B') (precompose f) (mapsnd_Batch f b)))
A, B, B': Type
f: B' -> B
C: Type
b: Batch A B (B -> C)
a: A
IHb: length_Batch b = length_Batch (mapsnd_Batch f b)

length_Batch b = length_Batch (map (Batch A B') (precompose f) (mapsnd_Batch f b))
A, B, B': Type
f: B' -> B
C: Type
b: Batch A B (B -> C)
a: A
IHb: length_Batch b = length_Batch (mapsnd_Batch f b)

length_Batch (mapsnd_Batch f b) = length_Batch (map (Batch A B') (precompose f) (mapsnd_Batch f b))
A, B, B': Type
f: B' -> B
C: Type
b: Batch A B (B -> C)
a: A
IHb: length_Batch b = length_Batch (mapsnd_Batch f b)

length_Batch (map (Batch A B') (precompose f) (mapsnd_Batch f b)) = length_Batch (map (Batch A B') (precompose f) (mapsnd_Batch f b))
reflexivity. Qed. (** ** Length is Preserved by <<cojoin_Batch>> *) (******************************************************************************)

forall (A A' B C : Type) (b : Batch A B C), length_Batch b = length_Batch (cojoin_Batch b)

forall (A A' B C : Type) (b : Batch A B C), length_Batch b = length_Batch (cojoin_Batch b)
A, A', B, C: Type
c: C

length_Batch (Done c) = length_Batch (cojoin_Batch (Done c))
A, A', B, C: Type
b: Batch A B (B -> C)
a: A
IHb: length_Batch b = length_Batch (cojoin_Batch b)
length_Batch (b ⧆ a) = length_Batch (cojoin_Batch (b ⧆ a))
A, A', B, C: Type
c: C

length_Batch (Done c) = length_Batch (cojoin_Batch (Done c))
reflexivity.
A, A', B, C: Type
b: Batch A B (B -> C)
a: A
IHb: length_Batch b = length_Batch (cojoin_Batch b)

length_Batch (b ⧆ a) = length_Batch (cojoin_Batch (b ⧆ a))
A, A', B, C: Type
b: Batch A B (B -> C)
a: A
IHb: length_Batch b = length_Batch (cojoin_Batch b)

S (length_Batch b) = S (length_Batch (map (Batch A A') Step (cojoin_Batch b)))
A, A', B, C: Type
b: Batch A B (B -> C)
a: A
IHb: length_Batch b = length_Batch (cojoin_Batch b)

length_Batch b = length_Batch (map (Batch A A') Step (cojoin_Batch b))
A, A', B, C: Type
b: Batch A B (B -> C)
a: A
IHb: length_Batch b = length_Batch (cojoin_Batch b)

length_Batch (cojoin_Batch b) = length_Batch (map (Batch A A') Step (cojoin_Batch b))
A, A', B, C: Type
b: Batch A B (B -> C)
a: A
IHb: length_Batch b = length_Batch (cojoin_Batch b)

length_Batch (cojoin_Batch b) = length_Batch (cojoin_Batch b)
reflexivity. Qed. (** ** Two Same-Shaped <<Batch>>es Have the Same Length*) (******************************************************************************)

forall (A1 B C : Type) (b1 : Batch A1 B C) (A2 : Type) (b2 : Batch A2 B C), shape b1 = shape b2 -> length_Batch b1 = length_Batch b2

forall (A1 B C : Type) (b1 : Batch A1 B C) (A2 : Type) (b2 : Batch A2 B C), shape b1 = shape b2 -> length_Batch b1 = length_Batch b2
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C
Hshape: shape b1 = shape b2

length_Batch b1 = length_Batch b2
A1, B, C: Type
c: C
A2: Type
b2: Batch A2 B C
Hshape: shape (Done c) = shape b2

length_Batch (Done c) = length_Batch b2
A1, B, C: Type
b1: Batch A1 B (B -> C)
a: A1
A2: Type
b2: Batch A2 B C
Hshape: shape (b1 ⧆ a) = shape b2
IHb1: forall b2 : Batch A2 B (B -> C), shape b1 = shape b2 -> length_Batch b1 = length_Batch b2
length_Batch (b1 ⧆ a) = length_Batch b2
A1, B, C: Type
c: C
A2: Type
b2: Batch A2 B C
Hshape: shape (Done c) = shape b2

length_Batch (Done c) = length_Batch b2
A1, B, C: Type
c: C
A2: Type
c0: C
Hshape: shape (Done c) = shape (Done c0)

length_Batch (Done c) = length_Batch (Done c0)
A1, B, C: Type
c: C
A2: Type
b2: Batch A2 B (B -> C)
a: A2
Hshape: shape (Done c) = shape (b2 ⧆ a)
length_Batch (Done c) = length_Batch (b2 ⧆ a)
A1, B, C: Type
c: C
A2: Type
c0: C
Hshape: shape (Done c) = shape (Done c0)

length_Batch (Done c) = length_Batch (Done c0)
now inversion Hshape.
A1, B, C: Type
c: C
A2: Type
b2: Batch A2 B (B -> C)
a: A2
Hshape: shape (Done c) = shape (b2 ⧆ a)

length_Batch (Done c) = length_Batch (b2 ⧆ a)
false.
A1, B, C: Type
b1: Batch A1 B (B -> C)
a: A1
A2: Type
b2: Batch A2 B C
Hshape: shape (b1 ⧆ a) = shape b2
IHb1: forall b2 : Batch A2 B (B -> C), shape b1 = shape b2 -> length_Batch b1 = length_Batch b2

length_Batch (b1 ⧆ a) = length_Batch b2
A1, B, C: Type
b1: Batch A1 B (B -> C)
a: A1
A2: Type
c: C
Hshape: shape (b1 ⧆ a) = shape (Done c)
IHb1: forall b2 : Batch A2 B (B -> C), shape b1 = shape b2 -> length_Batch b1 = length_Batch b2

length_Batch (b1 ⧆ a) = length_Batch (Done c)
A1, B, C: Type
b1: Batch A1 B (B -> C)
a: A1
A2: Type
b2: Batch A2 B (B -> C)
a0: A2
Hshape: shape (b1 ⧆ a) = shape (b2 ⧆ a0)
IHb1: forall b2 : Batch A2 B (B -> C), shape b1 = shape b2 -> length_Batch b1 = length_Batch b2
length_Batch (b1 ⧆ a) = length_Batch (b2 ⧆ a0)
A1, B, C: Type
b1: Batch A1 B (B -> C)
a: A1
A2: Type
c: C
Hshape: shape (b1 ⧆ a) = shape (Done c)
IHb1: forall b2 : Batch A2 B (B -> C), shape b1 = shape b2 -> length_Batch b1 = length_Batch b2

length_Batch (b1 ⧆ a) = length_Batch (Done c)
false.
A1, B, C: Type
b1: Batch A1 B (B -> C)
a: A1
A2: Type
b2: Batch A2 B (B -> C)
a0: A2
Hshape: shape (b1 ⧆ a) = shape (b2 ⧆ a0)
IHb1: forall b2 : Batch A2 B (B -> C), shape b1 = shape b2 -> length_Batch b1 = length_Batch b2

length_Batch (b1 ⧆ a) = length_Batch (b2 ⧆ a0)
A1, B, C: Type
b1: Batch A1 B (B -> C)
a: A1
A2: Type
b2: Batch A2 B (B -> C)
a0: A2
Hshape: shape (b1 ⧆ a) = shape (b2 ⧆ a0)
IHb1: forall b2 : Batch A2 B (B -> C), shape b1 = shape b2 -> length_Batch b1 = length_Batch b2

S (length_Batch b1) = S (length_Batch b2)
A1, B, C: Type
b1: Batch A1 B (B -> C)
a: A1
A2: Type
b2: Batch A2 B (B -> C)
a0: A2
Hshape: shape (b1 ⧆ a) = shape (b2 ⧆ a0)
IHb1: forall b2 : Batch A2 B (B -> C), shape b1 = shape b2 -> length_Batch b1 = length_Batch b2

length_Batch b1 = length_Batch b2
A1, B, C: Type
b1: Batch A1 B (B -> C)
a: A1
A2: Type
b2: Batch A2 B (B -> C)
a0: A2
Hshape: shape (b1 ⧆ a) = shape (b2 ⧆ a0)
IHb1: forall b2 : Batch A2 B (B -> C), shape b1 = shape b2 -> length_Batch b1 = length_Batch b2

shape b1 = shape b2
now inversion Hshape. Qed. End length. (** * Specification for <<traverse>> via <<runBatch>> *) (******************************************************************************)
G: Type -> Type
H: Map G
H0: Mult G
H1: Pure G
Applicative0: Applicative G
A, A': Type
ϕ: A -> G A'
B, C: Type

traverse ϕ = runBatch (map G (batch A' B) ∘ ϕ)
G: Type -> Type
H: Map G
H0: Mult G
H1: Pure G
Applicative0: Applicative G
A, A': Type
ϕ: A -> G A'
B, C: Type

traverse ϕ = runBatch (map G (batch A' B) ∘ ϕ)
G: Type -> Type
H: Map G
H0: Mult G
H1: Pure G
Applicative0: Applicative G
A, A': Type
ϕ: A -> G A'
B, C: Type

traverse ϕ = runBatch (map G (batch A' B) ∘ ϕ)
G: Type -> Type
H: Map G
H0: Mult G
H1: Pure G
Applicative0: Applicative G
A, A': Type
ϕ: A -> G A'
B, C: Type
b: Batch A B C

traverse ϕ b = runBatch (map G (batch A' B) ∘ ϕ) b
G: Type -> Type
H: Map G
H0: Mult G
H1: Pure G
Applicative0: Applicative G
A, A': Type
ϕ: A -> G A'
B, C: Type
c: C

traverse ϕ (Done c) = runBatch (map G (batch A' B) ∘ ϕ) (Done c)
G: Type -> Type
H: Map G
H0: Mult G
H1: Pure G
Applicative0: Applicative G
A, A': Type
ϕ: A -> G A'
B, C: Type
rest: Batch A B (B -> C)
a: A
IHrest: traverse ϕ rest = runBatch (map G (batch A' B) ∘ ϕ) rest
traverse ϕ (rest ⧆ a) = runBatch (map G (batch A' B) ∘ ϕ) (rest ⧆ a)
G: Type -> Type
H: Map G
H0: Mult G
H1: Pure G
Applicative0: Applicative G
A, A': Type
ϕ: A -> G A'
B, C: Type
c: C

traverse ϕ (Done c) = runBatch (map G (batch A' B) ∘ ϕ) (Done c)
G: Type -> Type
H: Map G
H0: Mult G
H1: Pure G
Applicative0: Applicative G
A, A': Type
ϕ: A -> G A'
B, C: Type
c: C

traverse ϕ (Done c) = pure (G ∘ Batch A' B) c
G: Type -> Type
H: Map G
H0: Mult G
H1: Pure G
Applicative0: Applicative G
A, A': Type
ϕ: A -> G A'
B, C: Type
c: C

pure G (Done c) = pure (G ∘ Batch A' B) c
reflexivity.
G: Type -> Type
H: Map G
H0: Mult G
H1: Pure G
Applicative0: Applicative G
A, A': Type
ϕ: A -> G A'
B, C: Type
rest: Batch A B (B -> C)
a: A
IHrest: traverse ϕ rest = runBatch (map G (batch A' B) ∘ ϕ) rest

traverse ϕ (rest ⧆ a) = runBatch (map G (batch A' B) ∘ ϕ) (rest ⧆ a)
G: Type -> Type
H: Map G
H0: Mult G
H1: Pure G
Applicative0: Applicative G
A, A': Type
ϕ: A -> G A'
B, C: Type
rest: Batch A B (B -> C)
a: A
IHrest: traverse ϕ rest = runBatch (map G (batch A' B) ∘ ϕ) rest

traverse ϕ (rest ⧆ a) = runBatch (map G (batch A' B) ∘ ϕ) rest <⋆> (map G (batch A' B) ∘ ϕ) a
G: Type -> Type
H: Map G
H0: Mult G
H1: Pure G
Applicative0: Applicative G
A, A': Type
ϕ: A -> G A'
B, C: Type
rest: Batch A B (B -> C)
a: A
IHrest: traverse ϕ rest = runBatch (map G (batch A' B) ∘ ϕ) rest

map G Step (traverse ϕ rest) <⋆> ϕ a = runBatch (map G (batch A' B) ∘ ϕ) rest <⋆> (map G (batch A' B) ∘ ϕ) a
G: Type -> Type
H: Map G
H0: Mult G
H1: Pure G
Applicative0: Applicative G
A, A': Type
ϕ: A -> G A'
B, C: Type
rest: Batch A B (B -> C)
a: A
IHrest: traverse ϕ rest = runBatch (map G (batch A' B) ∘ ϕ) rest

map G Step (runBatch (map G (batch A' B) ∘ ϕ) rest) <⋆> ϕ a = runBatch (map G (batch A' B) ∘ ϕ) rest <⋆> (map G (batch A' B) ∘ ϕ) a
G: Type -> Type
H: Map G
H0: Mult G
H1: Pure G
Applicative0: Applicative G
A, A': Type
ϕ: A -> G A'
B, C: Type
rest: Batch A B (B -> C)
a: A
IHrest: traverse ϕ rest = runBatch (map G (batch A' B) ∘ ϕ) rest

map G Step (runBatch (map G (batch A' B) ∘ ϕ) rest) <⋆> ϕ a = runBatch (map G (batch A' B) ∘ ϕ) rest <⋆> map G (batch A' B) (ϕ a)
G: Type -> Type
H: Map G
H0: Mult G
H1: Pure G
Applicative0: Applicative G
A, A': Type
ϕ: A -> G A'
B, C: Type
rest: Batch A B (B -> C)
a: A
IHrest: traverse ϕ rest = runBatch (map G (batch A' B) ∘ ϕ) rest

map G Step (runBatch (map G (batch A' B) ∘ ϕ) rest) <⋆> ϕ a = map G (ap (Batch A' B)) (runBatch (map G (batch A' B) ∘ ϕ) rest) <⋆> map G (batch A' B) (ϕ a)
G: Type -> Type
H: Map G
H0: Mult G
H1: Pure G
Applicative0: Applicative G
A, A': Type
ϕ: A -> G A'
B, C: Type
rest: Batch A B (B -> C)
a: A
IHrest: traverse ϕ rest = runBatch (map G (batch A' B) ∘ ϕ) rest

map G Step (runBatch (map G (batch A' B) ∘ ϕ) rest) <⋆> ϕ a = map G (precompose (batch A' B)) (map G (ap (Batch A' B)) (runBatch (map G (batch A' B) ∘ ϕ) rest)) <⋆> ϕ a
G: Type -> Type
H: Map G
H0: Mult G
H1: Pure G
Applicative0: Applicative G
A, A': Type
ϕ: A -> G A'
B, C: Type
rest: Batch A B (B -> C)
a: A
IHrest: traverse ϕ rest = runBatch (map G (batch A' B) ∘ ϕ) rest

map G Step (runBatch (map G (batch A' B) ∘ ϕ) rest) <⋆> ϕ a = (map G (precompose (batch A' B)) ∘ map G (ap (Batch A' B))) (runBatch (map G (batch A' B) ∘ ϕ) rest) <⋆> ϕ a
G: Type -> Type
H: Map G
H0: Mult G
H1: Pure G
Applicative0: Applicative G
A, A': Type
ϕ: A -> G A'
B, C: Type
rest: Batch A B (B -> C)
a: A
IHrest: traverse ϕ rest = runBatch (map G (batch A' B) ∘ ϕ) rest

map G Step (runBatch (map G (batch A' B) ∘ ϕ) rest) <⋆> ϕ a = map G (precompose (batch A' B) ∘ ap (Batch A' B)) (runBatch (map G (batch A' B) ∘ ϕ) rest) <⋆> ϕ a
G: Type -> Type
H: Map G
H0: Mult G
H1: Pure G
Applicative0: Applicative G
A, A': Type
ϕ: A -> G A'
B, C: Type
rest: Batch A B (B -> C)
a: A
IHrest: traverse ϕ rest = runBatch (map G (batch A' B) ∘ ϕ) rest

Step = precompose (batch A' B) ∘ ap (Batch A' B)
G: Type -> Type
H: Map G
H0: Mult G
H1: Pure G
Applicative0: Applicative G
A, A': Type
ϕ: A -> G A'
B, C: Type
rest: Batch A B (B -> C)
a: A
IHrest: traverse ϕ rest = runBatch (map G (batch A' B) ∘ ϕ) rest
b: Batch A' B (B -> C)

Step b = (precompose (batch A' B) ∘ ap (Batch A' B)) b
G: Type -> Type
H: Map G
H0: Mult G
H1: Pure G
Applicative0: Applicative G
A, A': Type
ϕ: A -> G A'
B, C: Type
rest: Batch A B (B -> C)
a: A
IHrest: traverse ϕ rest = runBatch (map G (batch A' B) ∘ ϕ) rest
b: Batch A' B (B -> C)

Step b = (fun X : A' => map (Batch A' B) (fun '(f, a) => f a) (b ⊗ batch A' B X))
G: Type -> Type
H: Map G
H0: Mult G
H1: Pure G
Applicative0: Applicative G
A, A': Type
ϕ: A -> G A'
B, C: Type
rest: Batch A B (B -> C)
a: A
IHrest: traverse ϕ rest = runBatch (map G (batch A' B) ∘ ϕ) rest
b: Batch A' B (B -> C)

Step b = (fun X : A' => map (Batch A' B) (compose (fun '(f, a) => f a)) (map (Batch A' B) strength_arrow (map (Batch A' B) (fun c : B -> C => (c, id)) b)) ⧆ X)
G: Type -> Type
H: Map G
H0: Mult G
H1: Pure G
Applicative0: Applicative G
A, A': Type
ϕ: A -> G A'
B, C: Type
rest: Batch A B (B -> C)
a: A
IHrest: traverse ϕ rest = runBatch (map G (batch A' B) ∘ ϕ) rest
b: Batch A' B (B -> C)

Step b = (fun X : A' => map (Batch A' B) (compose (fun '(f, a) => f a)) ((map (Batch A' B) strength_arrow ∘ map (Batch A' B) (fun c : B -> C => (c, id))) b) ⧆ X)
G: Type -> Type
H: Map G
H0: Mult G
H1: Pure G
Applicative0: Applicative G
A, A': Type
ϕ: A -> G A'
B, C: Type
rest: Batch A B (B -> C)
a: A
IHrest: traverse ϕ rest = runBatch (map G (batch A' B) ∘ ϕ) rest
b: Batch A' B (B -> C)

Step b = (fun X : A' => map (Batch A' B) (compose (fun '(f, a) => f a)) (map (Batch A' B) (strength_arrow ∘ (fun c : B -> C => (c, id))) b) ⧆ X)
G: Type -> Type
H: Map G
H0: Mult G
H1: Pure G
Applicative0: Applicative G
A, A': Type
ϕ: A -> G A'
B, C: Type
rest: Batch A B (B -> C)
a: A
IHrest: traverse ϕ rest = runBatch (map G (batch A' B) ∘ ϕ) rest
b: Batch A' B (B -> C)

Step b = (fun X : A' => (map (Batch A' B) (compose (fun '(f, a) => f a)) ∘ map (Batch A' B) (strength_arrow ∘ (fun c : B -> C => (c, id)))) b ⧆ X)
G: Type -> Type
H: Map G
H0: Mult G
H1: Pure G
Applicative0: Applicative G
A, A': Type
ϕ: A -> G A'
B, C: Type
rest: Batch A B (B -> C)
a: A
IHrest: traverse ϕ rest = runBatch (map G (batch A' B) ∘ ϕ) rest
b: Batch A' B (B -> C)

Step b = (fun X : A' => map (Batch A' B) (compose (fun '(f, a) => f a) ∘ (strength_arrow ∘ (fun c : B -> C => (c, id)))) b ⧆ X)
G: Type -> Type
H: Map G
H0: Mult G
H1: Pure G
Applicative0: Applicative G
A, A': Type
ϕ: A -> G A'
B, C: Type
rest: Batch A B (B -> C)
a: A
IHrest: traverse ϕ rest = runBatch (map G (batch A' B) ∘ ϕ) rest
b: Batch A' B (B -> C)

Step b = (fun X : A' => map (Batch A' B) (fun (a : B -> C) (a0 : B) => let '(f, a1) := strength_arrow (a, id) a0 in f a1) b ⧆ X)
G: Type -> Type
H: Map G
H0: Mult G
H1: Pure G
Applicative0: Applicative G
A, A': Type
ϕ: A -> G A'
B, C: Type
rest: Batch A B (B -> C)
a: A
IHrest: traverse ϕ rest = runBatch (map G (batch A' B) ∘ ϕ) rest
b: Batch A' B (B -> C)

Step b = (fun X : A' => map (Batch A' B) (fun a : B -> C => a ○ id) b ⧆ X)
G: Type -> Type
H: Map G
H0: Mult G
H1: Pure G
Applicative0: Applicative G
A, A': Type
ϕ: A -> G A'
B, C: Type
rest: Batch A B (B -> C)
a: A
IHrest: traverse ϕ rest = runBatch (map G (batch A' B) ∘ ϕ) rest
b: Batch A' B (B -> C)

b = map (Batch A' B) (fun a : B -> C => a ○ id) b
G: Type -> Type
H: Map G
H0: Mult G
H1: Pure G
Applicative0: Applicative G
A, A': Type
ϕ: A -> G A'
B, C: Type
rest: Batch A B (B -> C)
a: A
IHrest: traverse ϕ rest = runBatch (map G (batch A' B) ∘ ϕ) rest
b: Batch A' B (B -> C)

b = map (Batch A' B) (fun a : B -> C => a) b
G: Type -> Type
H: Map G
H0: Mult G
H1: Pure G
Applicative0: Applicative G
A, A': Type
ϕ: A -> G A'
B, C: Type
rest: Batch A B (B -> C)
a: A
IHrest: traverse ϕ rest = runBatch (map G (batch A' B) ∘ ϕ) rest
b: Batch A' B (B -> C)

b = id b
reflexivity. Qed. (** * <<Batch _ B C>> is a traversable monad *) (******************************************************************************) (** ** Operation *) (******************************************************************************) Definition bindt_Batch (B C: Type) (G: Type -> Type) `{Map G} `{Pure G} `{Mult G} (A A': Type) (f: A -> G (Batch A' B B)) (b: Batch A B B): G (Batch A' B B) := map G join_Batch (traverse (T := BATCH1 B B) f b). (** ** Traversable Monad Laws *) (** TODO *) (** * Deconstructing <<Batch A B C>> into Shape and Contents *) (******************************************************************************) Section deconstruction. #[local] Generalizable Variables n v a. (** ** <<Batch_make>> and <<Batch_contents>> *) (******************************************************************************) (** Extract the contents of <<Batch>> as a vector *) Fixpoint Batch_contents `(b: Batch A B C): Vector (length_Batch b) A := match b with | Done c => vnil | Step b a => vcons (length_Batch b) a (Batch_contents b) end. (** Obtain the build function of <<Batch>>. Note that <<Batch_make b v>> in general has type <<C>>, not another <<Batch>>. That is, this is not <<make>> in the sense of <<put>> *) Fixpoint Batch_make `(b: Batch A B C): Vector (length_Batch b) B -> C := match b return Vector (length_Batch b) B -> C with | Done c => fun v => c | Step b a => fun v => Batch_make b (Vector_tl v) (Vector_hd v) end. (** ** <<Batch_replace_contents>> *) (** This is <<make>> in the sense of <<put>>. *) (******************************************************************************) Fixpoint Batch_replace_contents `(b: Batch A B C) `(v: Vector (length_Batch b) A') : Batch A' B C := match b return (Vector (length_Batch b) A' -> Batch A' B C) with | Done c => fun v => Done c | Step rest a => fun v => Step (Batch_replace_contents rest (Vector_tl v)) (Vector_hd v) end v. (** ** Rewriting rules *) (******************************************************************************) Section rw. Context {A B C: Type}. Implicit Types (a: A) (b: Batch A B (B -> C)) (c: C).
A, B, C: Type
c: C

Batch_contents (Done c) = vnil
A, B, C: Type
c: C

Batch_contents (Done c) = vnil
reflexivity. Qed.
A, B, C: Type
b: Batch A B (B -> C)
a: A

Batch_contents (b ⧆ a) = vcons (length_Batch b) a (Batch_contents b)
A, B, C: Type
b: Batch A B (B -> C)
a: A

Batch_contents (b ⧆ a) = vcons (length_Batch b) a (Batch_contents b)
reflexivity. Qed.
A, B, C: Type
c: C

Batch_make (Done c) = const c
A, B, C: Type
c: C

Batch_make (Done c) = const c
reflexivity. Qed.
A, B, C: Type
b: Batch A B (B -> C)
a: A

Batch_make (b ⧆ a) = (fun v : Vector (length_Batch (b ⧆ a)) B => Batch_make b (Vector_tl v) (Vector_hd v))
A, B, C: Type
b: Batch A B (B -> C)
a: A

Batch_make (b ⧆ a) = (fun v : Vector (length_Batch (b ⧆ a)) B => Batch_make b (Vector_tl v) (Vector_hd v))
reflexivity. Qed.
A, B, C: Type
c: C
A': Type
v: Vector (length_Batch (Done c)) A'

Batch_replace_contents (Done c) v = Done c
A, B, C: Type
c: C
A': Type
v: Vector (length_Batch (Done c)) A'

Batch_replace_contents (Done c) v = Done c
reflexivity. Qed.
A, B, C: Type
b: Batch A B (B -> C)
a: A
A': Type
v: Vector (length_Batch (b ⧆ a)) A'

Batch_replace_contents (b ⧆ a) v = Batch_replace_contents b (Vector_tl v) ⧆ Vector_hd v
A, B, C: Type
b: Batch A B (B -> C)
a: A
A': Type
v: Vector (length_Batch (b ⧆ a)) A'

Batch_replace_contents (b ⧆ a) v = Batch_replace_contents b (Vector_tl v) ⧆ Vector_hd v
reflexivity. Qed. End rw. (** ** Relating <<tolist>> and <<Batch_contents>> *) (******************************************************************************) Ltac hide_rhs := match goal with | |- ?lhs = ?rhs => let name := fresh "rhs" in remember rhs as name end.
A, B, C: Type

forall b : Batch A B C, proj1_sig (Batch_contents b) = List.rev (tolist b)
A, B, C: Type

forall b : Batch A B C, proj1_sig (Batch_contents b) = List.rev (tolist b)
A, B, C: Type
b: Batch A B C

proj1_sig (Batch_contents b) = List.rev (tolist b)
A, B, C: Type
c: C

proj1_sig (Batch_contents (Done c)) = List.rev (tolist (Done c))
A, B, C: Type
b: Batch A B (B -> C)
a: A
IHb: proj1_sig (Batch_contents b) = List.rev (tolist b)
proj1_sig (Batch_contents (b ⧆ a)) = List.rev (tolist (b ⧆ a))
A, B, C: Type
c: C

proj1_sig (Batch_contents (Done c)) = List.rev (tolist (Done c))
reflexivity.
A, B, C: Type
b: Batch A B (B -> C)
a: A
IHb: proj1_sig (Batch_contents b) = List.rev (tolist b)

proj1_sig (Batch_contents (b ⧆ a)) = List.rev (tolist (b ⧆ a))
A, B, C: Type
b: Batch A B (B -> C)
a: A
IHb: proj1_sig (Batch_contents b) = List.rev (tolist b)

proj1_sig (vcons (length_Batch b) a (Batch_contents b)) = List.rev (tolist (b ⧆ a))
A, B, C: Type
b: Batch A B (B -> C)
a: A
IHb: proj1_sig (Batch_contents b) = List.rev (tolist b)
rhs: list A

proj1_sig (vcons (length_Batch b) a (Batch_contents b)) = List.rev (tolist (b ⧆ a))
(* ^^ Simplify a hidden (length_Batch (b ⧆ a) without affecting RHS. *) (* ^^ rewrite Batch_contents_rw2 fails due to binders *)
A, B, C: Type
b: Batch A B (B -> C)
a: A
IHb: proj1_sig (Batch_contents b) = List.rev (tolist b)
rhs: list A

a :: proj1_sig (Batch_contents b) = List.rev (tolist (b ⧆ a))
A, B, C: Type
b: Batch A B (B -> C)
a: A
IHb: proj1_sig (Batch_contents b) = List.rev (tolist b)
rhs: list A

a :: proj1_sig (Batch_contents b) = List.rev (tolist b ++ a :: nil)
A, B, C: Type
b: Batch A B (B -> C)
a: A
IHb: proj1_sig (Batch_contents b) = List.rev (tolist b)
rhs: list A

a :: proj1_sig (Batch_contents b) = a :: List.rev (tolist b)
A, B, C: Type
b: Batch A B (B -> C)
a: A
IHb: proj1_sig (Batch_contents b) = List.rev (tolist b)
rhs: list A

a :: proj1_sig (Batch_contents b) = a :: proj1_sig (Batch_contents b)
reflexivity. Qed. (** ** Rewriting Rules for << <⋆> >> *) (******************************************************************************) Section rewrite_Batch_contents. Context {A B: Type}.
A, B: Type

forall (X : Type) (x : X), Batch_contents (pure (Batch A B) x) = vnil
A, B: Type

forall (X : Type) (x : X), Batch_contents (pure (Batch A B) x) = vnil
A, B, X: Type
x: X

Batch_contents (pure (Batch A B) x) = vnil
reflexivity. Qed.
A, B: Type

forall (C D : Type) (x : Batch A B C) (y : Batch A B D), Batch_contents (x ⊗ y) ~~ Vector_append (Batch_contents y) (Batch_contents x)
A, B: Type

forall (C D : Type) (x : Batch A B C) (y : Batch A B D), Batch_contents (x ⊗ y) ~~ Vector_append (Batch_contents y) (Batch_contents x)
A, B, C, D: Type
x: Batch A B C
y: Batch A B D

Batch_contents (x ⊗ y) ~~ Vector_append (Batch_contents y) (Batch_contents x)
A, B, C, D: Type
x: Batch A B C
y: Batch A B D

proj1_sig (Batch_contents (x ⊗ y)) = proj1_sig (Vector_append (Batch_contents y) (Batch_contents x))
A, B, C, D: Type
x: Batch A B C
y: Batch A B D

List.rev (tolist (x ⊗ y)) = proj1_sig (Vector_append (Batch_contents y) (Batch_contents x))
A, B, C, D: Type
x: Batch A B C
y: Batch A B D

List.rev (mapReduce (ret list A) (x ⊗ y)) = proj1_sig (Vector_append (Batch_contents y) (Batch_contents x))
A, B, C, D: Type
x: Batch A B C
y: Batch A B D

List.rev (mapReduce (ret list A) x ● mapReduce (ret list A) y) = proj1_sig (Vector_append (Batch_contents y) (Batch_contents x))
A, B, C, D: Type
x: Batch A B C
y: Batch A B D

List.rev (mapReduce (ret list A) x ++ mapReduce (ret list A) y) = proj1_sig (Vector_append (Batch_contents y) (Batch_contents x))
A, B, C, D: Type
x: Batch A B C
y: Batch A B D

List.rev (mapReduce (ret list A) y) ++ List.rev (mapReduce (ret list A) x) = proj1_sig (Vector_append (Batch_contents y) (Batch_contents x))
A, B, C, D: Type
x: Batch A B C
y: Batch A B D

List.rev (mapReduce (ret list A) y) ++ List.rev (mapReduce (ret list A) x) = proj1_sig (Batch_contents y) ++ proj1_sig (Batch_contents x)
A, B, C, D: Type
x: Batch A B C
y: Batch A B D

List.rev (mapReduce (ret list A) y) ++ List.rev (mapReduce (ret list A) x) = List.rev (tolist y) ++ proj1_sig (Batch_contents x)
A, B, C, D: Type
x: Batch A B C
y: Batch A B D

List.rev (mapReduce (ret list A) y) ++ List.rev (mapReduce (ret list A) x) = List.rev (tolist y) ++ List.rev (tolist x)
reflexivity. Qed.
A, B: Type

forall (X Y : Type) (f : Batch A B (X -> Y)) (x : Batch A B X), Batch_contents (f <⋆> x) ~~ Vector_append (Batch_contents x) (Batch_contents f)
A, B: Type

forall (X Y : Type) (f : Batch A B (X -> Y)) (x : Batch A B X), Batch_contents (f <⋆> x) ~~ Vector_append (Batch_contents x) (Batch_contents f)
A, B, X, Y: Type
f: Batch A B (X -> Y)
x: Batch A B X

Batch_contents (f <⋆> x) ~~ Vector_append (Batch_contents x) (Batch_contents f)
A, B, X, Y: Type
f: Batch A B (X -> Y)
x: Batch A B X

proj1_sig (Batch_contents (f <⋆> x)) = proj1_sig (Vector_append (Batch_contents x) (Batch_contents f))
A, B, X, Y: Type
f: Batch A B (X -> Y)
x: Batch A B X

List.rev (tolist (f <⋆> x)) = proj1_sig (Vector_append (Batch_contents x) (Batch_contents f))
A, B, X, Y: Type
f: Batch A B (X -> Y)
x: Batch A B X

List.rev (mapReduce (ret list A) (f <⋆> x)) = proj1_sig (Vector_append (Batch_contents x) (Batch_contents f))
A, B, X, Y: Type
f: Batch A B (X -> Y)
x: Batch A B X

List.rev (mapReduce (ret list A) (f <⋆> x)) = proj1_sig (Batch_contents x) ++ proj1_sig (Batch_contents f)
A, B, X, Y: Type
f: Batch A B (X -> Y)
x: Batch A B X

List.rev (mapReduce (ret list A) f ● mapReduce (ret list A) x) = proj1_sig (Batch_contents x) ++ proj1_sig (Batch_contents f)
A, B, X, Y: Type
f: Batch A B (X -> Y)
x: Batch A B X

List.rev (mapReduce (ret list A) f ++ mapReduce (ret list A) x) = proj1_sig (Batch_contents x) ++ proj1_sig (Batch_contents f)
A, B, X, Y: Type
f: Batch A B (X -> Y)
x: Batch A B X

List.rev (mapReduce (ret list A) x) ++ List.rev (mapReduce (ret list A) f) = proj1_sig (Batch_contents x) ++ proj1_sig (Batch_contents f)
A, B, X, Y: Type
f: Batch A B (X -> Y)
x: Batch A B X

List.rev (mapReduce (ret list A) x) ++ List.rev (mapReduce (ret list A) f) = List.rev (tolist x) ++ proj1_sig (Batch_contents f)
A, B, X, Y: Type
f: Batch A B (X -> Y)
x: Batch A B X

List.rev (mapReduce (ret list A) x) ++ List.rev (mapReduce (ret list A) f) = List.rev (tolist x) ++ List.rev (tolist f)
reflexivity. Qed. End rewrite_Batch_contents. (** ** Same Shape Iff Same <<Batch_make>> *) (******************************************************************************)

forall (A1 B C : Type) (b1 : Batch A1 B C) (A2 : Type) (b2 : Batch A2 B C), shape b1 = shape b2 -> Batch_make b1 ~!~ Batch_make b2

forall (A1 B C : Type) (b1 : Batch A1 B C) (A2 : Type) (b2 : Batch A2 B C), shape b1 = shape b2 -> Batch_make b1 ~!~ Batch_make b2
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C
Hshape: shape b1 = shape b2

Batch_make b1 ~!~ Batch_make b2
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C
Hshape: shape b1 = shape b2

forall (C : Type) (c : C), Batch_make (Done c) ~!~ Batch_make (Done c)
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C
Hshape: shape b1 = shape b2
forall (C : Type) (b1 : Batch A1 B (B -> C)) (b2 : Batch A2 B (B -> C)), Batch_make b1 ~!~ Batch_make b2 -> forall (a1 : A1) (a2 : A2), shape (b1 ⧆ a1) = shape (b2 ⧆ a2) -> Batch_make (b1 ⧆ a1) ~!~ Batch_make (b2 ⧆ a2)
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C
Hshape: shape b1 = shape b2

forall (C : Type) (c : C), Batch_make (Done c) ~!~ Batch_make (Done c)
split; auto.
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C
Hshape: shape b1 = shape b2

forall (C : Type) (b1 : Batch A1 B (B -> C)) (b2 : Batch A2 B (B -> C)), Batch_make b1 ~!~ Batch_make b2 -> forall (a1 : A1) (a2 : A2), shape (b1 ⧆ a1) = shape (b2 ⧆ a2) -> Batch_make (b1 ⧆ a1) ~!~ Batch_make (b2 ⧆ a2)
A1, B, A2: Type

forall (C : Type) (b1 : Batch A1 B (B -> C)) (b2 : Batch A2 B (B -> C)), Batch_make b1 ~!~ Batch_make b2 -> forall (a1 : A1) (a2 : A2), shape (b1 ⧆ a1) = shape (b2 ⧆ a2) -> Batch_make (b1 ⧆ a1) ~!~ Batch_make (b2 ⧆ a2)
A1, B, A2, C: Type
b1: Batch A1 B (B -> C)
b2: Batch A2 B (B -> C)
Hsim: Batch_make b1 ~!~ Batch_make b2
a1: A1
a2: A2
Hshape: shape (b1 ⧆ a1) = shape (b2 ⧆ a2)

Batch_make (b1 ⧆ a1) ~!~ Batch_make (b2 ⧆ a2)
A1, B, A2, C: Type
b1: Batch A1 B (B -> C)
b2: Batch A2 B (B -> C)
Hsim: Batch_make b1 ~!~ Batch_make b2
a1: A1
a2: A2
Hshape: shape (b1 ⧆ a1) = shape (b2 ⧆ a2)

length_Batch (b1 ⧆ a1) = length_Batch (b2 ⧆ a2)
A1, B, A2, C: Type
b1: Batch A1 B (B -> C)
b2: Batch A2 B (B -> C)
Hsim: Batch_make b1 ~!~ Batch_make b2
a1: A1
a2: A2
Hshape: shape (b1 ⧆ a1) = shape (b2 ⧆ a2)
forall (v1 : Vector (length_Batch (b1 ⧆ a1)) B) (v2 : Vector (length_Batch (b2 ⧆ a2)) B), v1 ~~ v2 -> Batch_make (b1 ⧆ a1) v1 = Batch_make (b2 ⧆ a2) v2
A1, B, A2, C: Type
b1: Batch A1 B (B -> C)
b2: Batch A2 B (B -> C)
Hsim: Batch_make b1 ~!~ Batch_make b2
a1: A1
a2: A2
Hshape: shape (b1 ⧆ a1) = shape (b2 ⧆ a2)

length_Batch (b1 ⧆ a1) = length_Batch (b2 ⧆ a2)
auto using length_Batch_shape.
A1, B, A2, C: Type
b1: Batch A1 B (B -> C)
b2: Batch A2 B (B -> C)
Hsim: Batch_make b1 ~!~ Batch_make b2
a1: A1
a2: A2
Hshape: shape (b1 ⧆ a1) = shape (b2 ⧆ a2)

forall (v1 : Vector (length_Batch (b1 ⧆ a1)) B) (v2 : Vector (length_Batch (b2 ⧆ a2)) B), v1 ~~ v2 -> Batch_make (b1 ⧆ a1) v1 = Batch_make (b2 ⧆ a2) v2
A1, B, A2, C: Type
b1: Batch A1 B (B -> C)
b2: Batch A2 B (B -> C)
Hsim: Batch_make b1 ~!~ Batch_make b2
a1: A1
a2: A2
Hshape: shape (b1 ⧆ a1) = shape (b2 ⧆ a2)
v1: Vector (length_Batch (b1 ⧆ a1)) B
v2: Vector (length_Batch (b2 ⧆ a2)) B
Hsim': v1 ~~ v2

Batch_make (b1 ⧆ a1) v1 = Batch_make (b2 ⧆ a2) v2
A1, B, A2, C: Type
b1: Batch A1 B (B -> C)
b2: Batch A2 B (B -> C)
Hsim: Batch_make b1 ~!~ Batch_make b2
a1: A1
a2: A2
Hshape: shape (b1 ⧆ a1) = shape (b2 ⧆ a2)
v1: Vector (length_Batch (b1 ⧆ a1)) B
v2: Vector (length_Batch (b2 ⧆ a2)) B
Hsim': v1 ~~ v2

Batch_make b1 (Vector_tl v1) (Vector_hd v1) = Batch_make b2 (Vector_tl v2) (Vector_hd v2)
A1, B, A2, C: Type
b1: Batch A1 B (B -> C)
b2: Batch A2 B (B -> C)
Hsim: Batch_make b1 ~!~ Batch_make b2
a1: A1
a2: A2
Hshape: shape (b1 ⧆ a1) = shape (b2 ⧆ a2)
v1: Vector (length_Batch (b1 ⧆ a1)) B
v2: Vector (length_Batch (b2 ⧆ a2)) B
Hsim': v1 ~~ v2

Batch_make b1 (Vector_tl v1) (Vector_hd v2) = Batch_make b2 (Vector_tl v2) (Vector_hd v2)
A1, B, A2, C: Type
b1: Batch A1 B (B -> C)
b2: Batch A2 B (B -> C)
Hsim: Batch_make b1 ~!~ Batch_make b2
a1: A1
a2: A2
Hshape: shape (b1 ⧆ a1) = shape (b2 ⧆ a2)
v1: Vector (length_Batch (b1 ⧆ a1)) B
v2: Vector (length_Batch (b2 ⧆ a2)) B
Hsim': v1 ~~ v2

Batch_make b1 (Vector_tl v1) = Batch_make b2 (Vector_tl v2)
auto using Vector_fun_sim_eq, Vector_tl_sim. Qed.

forall (A1 B C : Type) (b1 : Batch A1 B C) (A2 : Type) (b2 : Batch A2 B C), Batch_make b1 ~!~ Batch_make b2 -> shape b1 = shape b2

forall (A1 B C : Type) (b1 : Batch A1 B C) (A2 : Type) (b2 : Batch A2 B C), Batch_make b1 ~!~ Batch_make b2 -> shape b1 = shape b2
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C
H: Batch_make b1 ~!~ Batch_make b2

shape b1 = shape b2
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C
H: length_Batch b1 = length_Batch b2 /\ (forall (v1 : Vector (length_Batch b1) B) (v2 : Vector (length_Batch b2) B), v1 ~~ v2 -> Batch_make b1 v1 = Batch_make b2 v2)

shape b1 = shape b2
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C
Hlen: length_Batch b1 = length_Batch b2
Hsim: forall (v1 : Vector (length_Batch b1) B) (v2 : Vector (length_Batch b2) B), v1 ~~ v2 -> Batch_make b1 v1 = Batch_make b2 v2

shape b1 = shape b2
A1, B, C: Type
c: C
A2: Type
b2: Batch A2 B C
Hlen: length_Batch (Done c) = length_Batch b2
Hsim: forall (v1 : Vector (length_Batch (Done c)) B) (v2 : Vector (length_Batch b2) B), v1 ~~ v2 -> Batch_make (Done c) v1 = Batch_make b2 v2

shape (Done c) = shape b2
A1, B, C: Type
b1: Batch A1 B (B -> C)
a: A1
A2: Type
b2: Batch A2 B C
Hlen: length_Batch (b1 ⧆ a) = length_Batch b2
Hsim: forall (v1 : Vector (length_Batch (b1 ⧆ a)) B) (v2 : Vector (length_Batch b2) B), v1 ~~ v2 -> Batch_make (b1 ⧆ a) v1 = Batch_make b2 v2
IHb1: forall b2 : Batch A2 B (B -> C), length_Batch b1 = length_Batch b2 -> (forall (v1 : Vector (length_Batch b1) B) (v2 : Vector (length_Batch b2) B), v1 ~~ v2 -> Batch_make b1 v1 = Batch_make b2 v2) -> shape b1 = shape b2
shape (b1 ⧆ a) = shape b2
A1, B, C: Type
c: C
A2: Type
b2: Batch A2 B C
Hlen: length_Batch (Done c) = length_Batch b2
Hsim: forall (v1 : Vector (length_Batch (Done c)) B) (v2 : Vector (length_Batch b2) B), v1 ~~ v2 -> Batch_make (Done c) v1 = Batch_make b2 v2

shape (Done c) = shape b2
A1, B, C: Type
c: C
A2: Type
c0: C
Hlen: length_Batch (Done c) = length_Batch (Done c0)
Hsim: forall (v1 : Vector (length_Batch (Done c)) B) (v2 : Vector (length_Batch (Done c0)) B), v1 ~~ v2 -> Batch_make (Done c) v1 = Batch_make (Done c0) v2

shape (Done c) = shape (Done c0)
A1, B, C: Type
c: C
A2: Type
b2: Batch A2 B (B -> C)
a: A2
Hlen: length_Batch (Done c) = length_Batch (b2 ⧆ a)
Hsim: forall (v1 : Vector (length_Batch (Done c)) B) (v2 : Vector (length_Batch (b2 ⧆ a)) B), v1 ~~ v2 -> Batch_make (Done c) v1 = Batch_make (b2 ⧆ a) v2
shape (Done c) = shape (b2 ⧆ a)
A1, B, C: Type
c: C
A2: Type
c0: C
Hlen: length_Batch (Done c) = length_Batch (Done c0)
Hsim: forall (v1 : Vector (length_Batch (Done c)) B) (v2 : Vector (length_Batch (Done c0)) B), v1 ~~ v2 -> Batch_make (Done c) v1 = Batch_make (Done c0) v2

shape (Done c) = shape (Done c0)
A1, B, C: Type
c: C
A2: Type
c0: C
Hlen: 0 = 0
Hsim: forall v1 v2 : Vector 0 B, v1 ~~ v2 -> c = c0

Done c = Done c0
A1, B, C: Type
c: C
A2: Type
c0: C
Hlen: 0 = 0
Hsim: c = c0

Done c = Done c0
now inversion Hsim.
A1, B, C: Type
c: C
A2: Type
b2: Batch A2 B (B -> C)
a: A2
Hlen: length_Batch (Done c) = length_Batch (b2 ⧆ a)
Hsim: forall (v1 : Vector (length_Batch (Done c)) B) (v2 : Vector (length_Batch (b2 ⧆ a)) B), v1 ~~ v2 -> Batch_make (Done c) v1 = Batch_make (b2 ⧆ a) v2

shape (Done c) = shape (b2 ⧆ a)
false.
A1, B, C: Type
b1: Batch A1 B (B -> C)
a: A1
A2: Type
b2: Batch A2 B C
Hlen: length_Batch (b1 ⧆ a) = length_Batch b2
Hsim: forall (v1 : Vector (length_Batch (b1 ⧆ a)) B) (v2 : Vector (length_Batch b2) B), v1 ~~ v2 -> Batch_make (b1 ⧆ a) v1 = Batch_make b2 v2
IHb1: forall b2 : Batch A2 B (B -> C), length_Batch b1 = length_Batch b2 -> (forall (v1 : Vector (length_Batch b1) B) (v2 : Vector (length_Batch b2) B), v1 ~~ v2 -> Batch_make b1 v1 = Batch_make b2 v2) -> shape b1 = shape b2

shape (b1 ⧆ a) = shape b2
A1, B, C: Type
b1: Batch A1 B (B -> C)
a: A1
A2: Type
c: C
Hlen: length_Batch (b1 ⧆ a) = length_Batch (Done c)
Hsim: forall (v1 : Vector (length_Batch (b1 ⧆ a)) B) (v2 : Vector (length_Batch (Done c)) B), v1 ~~ v2 -> Batch_make (b1 ⧆ a) v1 = Batch_make (Done c) v2
IHb1: forall b2 : Batch A2 B (B -> C), length_Batch b1 = length_Batch b2 -> (forall (v1 : Vector (length_Batch b1) B) (v2 : Vector (length_Batch b2) B), v1 ~~ v2 -> Batch_make b1 v1 = Batch_make b2 v2) -> shape b1 = shape b2

shape (b1 ⧆ a) = shape (Done c)
A1, B, C: Type
b1: Batch A1 B (B -> C)
a: A1
A2: Type
b2: Batch A2 B (B -> C)
a0: A2
Hlen: length_Batch (b1 ⧆ a) = length_Batch (b2 ⧆ a0)
Hsim: forall (v1 : Vector (length_Batch (b1 ⧆ a)) B) (v2 : Vector (length_Batch (b2 ⧆ a0)) B), v1 ~~ v2 -> Batch_make (b1 ⧆ a) v1 = Batch_make (b2 ⧆ a0) v2
IHb1: forall b2 : Batch A2 B (B -> C), length_Batch b1 = length_Batch b2 -> (forall (v1 : Vector (length_Batch b1) B) (v2 : Vector (length_Batch b2) B), v1 ~~ v2 -> Batch_make b1 v1 = Batch_make b2 v2) -> shape b1 = shape b2
shape (b1 ⧆ a) = shape (b2 ⧆ a0)
A1, B, C: Type
b1: Batch A1 B (B -> C)
a: A1
A2: Type
c: C
Hlen: length_Batch (b1 ⧆ a) = length_Batch (Done c)
Hsim: forall (v1 : Vector (length_Batch (b1 ⧆ a)) B) (v2 : Vector (length_Batch (Done c)) B), v1 ~~ v2 -> Batch_make (b1 ⧆ a) v1 = Batch_make (Done c) v2
IHb1: forall b2 : Batch A2 B (B -> C), length_Batch b1 = length_Batch b2 -> (forall (v1 : Vector (length_Batch b1) B) (v2 : Vector (length_Batch b2) B), v1 ~~ v2 -> Batch_make b1 v1 = Batch_make b2 v2) -> shape b1 = shape b2

shape (b1 ⧆ a) = shape (Done c)
false.
A1, B, C: Type
b1: Batch A1 B (B -> C)
a: A1
A2: Type
b2: Batch A2 B (B -> C)
a0: A2
Hlen: length_Batch (b1 ⧆ a) = length_Batch (b2 ⧆ a0)
Hsim: forall (v1 : Vector (length_Batch (b1 ⧆ a)) B) (v2 : Vector (length_Batch (b2 ⧆ a0)) B), v1 ~~ v2 -> Batch_make (b1 ⧆ a) v1 = Batch_make (b2 ⧆ a0) v2
IHb1: forall b2 : Batch A2 B (B -> C), length_Batch b1 = length_Batch b2 -> (forall (v1 : Vector (length_Batch b1) B) (v2 : Vector (length_Batch b2) B), v1 ~~ v2 -> Batch_make b1 v1 = Batch_make b2 v2) -> shape b1 = shape b2

shape (b1 ⧆ a) = shape (b2 ⧆ a0)
A1, B, C: Type
b1: Batch A1 B (B -> C)
a: A1
A2: Type
b2: Batch A2 B (B -> C)
a0: A2
Hlen: length_Batch (b1 ⧆ a) = length_Batch (b2 ⧆ a0)
Hsim: forall (v1 : Vector (length_Batch (b1 ⧆ a)) B) (v2 : Vector (length_Batch (b2 ⧆ a0)) B), v1 ~~ v2 -> Batch_make (b1 ⧆ a) v1 = Batch_make (b2 ⧆ a0) v2
IHb1: forall b2 : Batch A2 B (B -> C), length_Batch b1 = length_Batch b2 -> (forall (v1 : Vector (length_Batch b1) B) (v2 : Vector (length_Batch b2) B), v1 ~~ v2 -> Batch_make b1 v1 = Batch_make b2 v2) -> shape b1 = shape b2

mapfst_Batch (const tt) b1 ⧆ const tt a = mapfst_Batch (const tt) b2 ⧆ const tt a0
A1, B, C: Type
b1: Batch A1 B (B -> C)
a: A1
A2: Type
b2: Batch A2 B (B -> C)
a0: A2
Hlen: length_Batch (b1 ⧆ a) = length_Batch (b2 ⧆ a0)
Hsim: forall (v1 : Vector (length_Batch (b1 ⧆ a)) B) (v2 : Vector (length_Batch (b2 ⧆ a0)) B), v1 ~~ v2 -> Batch_make (b1 ⧆ a) v1 = Batch_make (b2 ⧆ a0) v2
IHb1: forall b2 : Batch A2 B (B -> C), length_Batch b1 = length_Batch b2 -> (forall (v1 : Vector (length_Batch b1) B) (v2 : Vector (length_Batch b2) B), v1 ~~ v2 -> Batch_make b1 v1 = Batch_make b2 v2) -> shape b1 = shape b2

mapfst_Batch (const tt) b1 = mapfst_Batch (const tt) b2
A1, B, C: Type
b1: Batch A1 B (B -> C)
a: A1
A2: Type
b2: Batch A2 B (B -> C)
a0: A2
Hlen: length_Batch (b1 ⧆ a) = length_Batch (b2 ⧆ a0)
Hsim: forall (v1 : Vector (length_Batch (b1 ⧆ a)) B) (v2 : Vector (length_Batch (b2 ⧆ a0)) B), v1 ~~ v2 -> Batch_make (b1 ⧆ a) v1 = Batch_make (b2 ⧆ a0) v2
IHb1: forall b2 : Batch A2 B (B -> C), length_Batch b1 = length_Batch b2 -> (forall (v1 : Vector (length_Batch b1) B) (v2 : Vector (length_Batch b2) B), v1 ~~ v2 -> Batch_make b1 v1 = Batch_make b2 v2) -> shape b1 = shape b2

length_Batch b1 = length_Batch b2
A1, B, C: Type
b1: Batch A1 B (B -> C)
a: A1
A2: Type
b2: Batch A2 B (B -> C)
a0: A2
Hlen: length_Batch (b1 ⧆ a) = length_Batch (b2 ⧆ a0)
Hsim: forall (v1 : Vector (length_Batch (b1 ⧆ a)) B) (v2 : Vector (length_Batch (b2 ⧆ a0)) B), v1 ~~ v2 -> Batch_make (b1 ⧆ a) v1 = Batch_make (b2 ⧆ a0) v2
IHb1: forall b2 : Batch A2 B (B -> C), length_Batch b1 = length_Batch b2 -> (forall (v1 : Vector (length_Batch b1) B) (v2 : Vector (length_Batch b2) B), v1 ~~ v2 -> Batch_make b1 v1 = Batch_make b2 v2) -> shape b1 = shape b2
forall (v1 : Vector (length_Batch b1) B) (v2 : Vector (length_Batch b2) B), v1 ~~ v2 -> Batch_make b1 v1 = Batch_make b2 v2
A1, B, C: Type
b1: Batch A1 B (B -> C)
a: A1
A2: Type
b2: Batch A2 B (B -> C)
a0: A2
Hlen: length_Batch (b1 ⧆ a) = length_Batch (b2 ⧆ a0)
Hsim: forall (v1 : Vector (length_Batch (b1 ⧆ a)) B) (v2 : Vector (length_Batch (b2 ⧆ a0)) B), v1 ~~ v2 -> Batch_make (b1 ⧆ a) v1 = Batch_make (b2 ⧆ a0) v2
IHb1: forall b2 : Batch A2 B (B -> C), length_Batch b1 = length_Batch b2 -> (forall (v1 : Vector (length_Batch b1) B) (v2 : Vector (length_Batch b2) B), v1 ~~ v2 -> Batch_make b1 v1 = Batch_make b2 v2) -> shape b1 = shape b2

length_Batch b1 = length_Batch b2
now inversion Hlen.
A1, B, C: Type
b1: Batch A1 B (B -> C)
a: A1
A2: Type
b2: Batch A2 B (B -> C)
a0: A2
Hlen: length_Batch (b1 ⧆ a) = length_Batch (b2 ⧆ a0)
Hsim: forall (v1 : Vector (length_Batch (b1 ⧆ a)) B) (v2 : Vector (length_Batch (b2 ⧆ a0)) B), v1 ~~ v2 -> Batch_make (b1 ⧆ a) v1 = Batch_make (b2 ⧆ a0) v2
IHb1: forall b2 : Batch A2 B (B -> C), length_Batch b1 = length_Batch b2 -> (forall (v1 : Vector (length_Batch b1) B) (v2 : Vector (length_Batch b2) B), v1 ~~ v2 -> Batch_make b1 v1 = Batch_make b2 v2) -> shape b1 = shape b2

forall (v1 : Vector (length_Batch b1) B) (v2 : Vector (length_Batch b2) B), v1 ~~ v2 -> Batch_make b1 v1 = Batch_make b2 v2
A1, B, C: Type
b1: Batch A1 B (B -> C)
a: A1
A2: Type
b2: Batch A2 B (B -> C)
a0: A2
Hlen: length_Batch (b1 ⧆ a) = length_Batch (b2 ⧆ a0)
Hsim: forall (v1 : Vector (length_Batch (b1 ⧆ a)) B) (v2 : Vector (length_Batch (b2 ⧆ a0)) B), v1 ~~ v2 -> Batch_make (b1 ⧆ a) v1 = Batch_make (b2 ⧆ a0) v2
IHb1: forall b2 : Batch A2 B (B -> C), length_Batch b1 = length_Batch b2 -> (forall (v1 : Vector (length_Batch b1) B) (v2 : Vector (length_Batch b2) B), v1 ~~ v2 -> Batch_make b1 v1 = Batch_make b2 v2) -> shape b1 = shape b2
v1: Vector (length_Batch b1) B
v2: Vector (length_Batch b2) B
Vsim: v1 ~~ v2

Batch_make b1 v1 = Batch_make b2 v2
A1, B, C: Type
b1: Batch A1 B (B -> C)
a: A1
A2: Type
b2: Batch A2 B (B -> C)
a0: A2
Hlen: length_Batch (b1 ⧆ a) = length_Batch (b2 ⧆ a0)
Hsim: forall (v1 : Vector (length_Batch (b1 ⧆ a)) B) (v2 : Vector (length_Batch (b2 ⧆ a0)) B), v1 ~~ v2 -> Batch_make (b1 ⧆ a) v1 = Batch_make (b2 ⧆ a0) v2
IHb1: forall b2 : Batch A2 B (B -> C), length_Batch b1 = length_Batch b2 -> (forall (v1 : Vector (length_Batch b1) B) (v2 : Vector (length_Batch b2) B), v1 ~~ v2 -> Batch_make b1 v1 = Batch_make b2 v2) -> shape b1 = shape b2
v1: Vector (length_Batch b1) B
v2: Vector (length_Batch b2) B
Vsim: v1 ~~ v2
b: B

Batch_make b1 v1 b = Batch_make b2 v2 b
A1, B, C: Type
b1: Batch A1 B (B -> C)
a: A1
A2: Type
b2: Batch A2 B (B -> C)
a0: A2
Hlen: length_Batch (b1 ⧆ a) = length_Batch (b2 ⧆ a0)
Hsim: forall (v1 : Vector (length_Batch (b1 ⧆ a)) B) (v2 : Vector (length_Batch (b2 ⧆ a0)) B), v1 ~~ v2 -> Batch_make (b1 ⧆ a) v1 = Batch_make (b2 ⧆ a0) v2
IHb1: forall b2 : Batch A2 B (B -> C), length_Batch b1 = length_Batch b2 -> (forall (v1 : Vector (length_Batch b1) B) (v2 : Vector (length_Batch b2) B), v1 ~~ v2 -> Batch_make b1 v1 = Batch_make b2 v2) -> shape b1 = shape b2
v1: Vector (length_Batch b1) B
v2: Vector (length_Batch b2) B
Vsim: v1 ~~ v2
b: B

vcons (length_Batch b1) b v1 ~~ vcons (length_Batch b2) b v2
A1, B, C: Type
b1: Batch A1 B (B -> C)
a: A1
A2: Type
b2: Batch A2 B (B -> C)
a0: A2
Hlen: length_Batch (b1 ⧆ a) = length_Batch (b2 ⧆ a0)
Hsim: forall (v1 : Vector (length_Batch (b1 ⧆ a)) B) (v2 : Vector (length_Batch (b2 ⧆ a0)) B), v1 ~~ v2 -> Batch_make (b1 ⧆ a) v1 = Batch_make (b2 ⧆ a0) v2
IHb1: forall b2 : Batch A2 B (B -> C), length_Batch b1 = length_Batch b2 -> (forall (v1 : Vector (length_Batch b1) B) (v2 : Vector (length_Batch b2) B), v1 ~~ v2 -> Batch_make b1 v1 = Batch_make b2 v2) -> shape b1 = shape b2
v1: Vector (length_Batch b1) B
v2: Vector (length_Batch b2) B
Vsim: v1 ~~ v2
b: B
Vsim': vcons (length_Batch b1) b v1 ~~ vcons (length_Batch b2) b v2
Batch_make b1 v1 b = Batch_make b2 v2 b
A1, B, C: Type
b1: Batch A1 B (B -> C)
a: A1
A2: Type
b2: Batch A2 B (B -> C)
a0: A2
Hlen: length_Batch (b1 ⧆ a) = length_Batch (b2 ⧆ a0)
Hsim: forall (v1 : Vector (length_Batch (b1 ⧆ a)) B) (v2 : Vector (length_Batch (b2 ⧆ a0)) B), v1 ~~ v2 -> Batch_make (b1 ⧆ a) v1 = Batch_make (b2 ⧆ a0) v2
IHb1: forall b2 : Batch A2 B (B -> C), length_Batch b1 = length_Batch b2 -> (forall (v1 : Vector (length_Batch b1) B) (v2 : Vector (length_Batch b2) B), v1 ~~ v2 -> Batch_make b1 v1 = Batch_make b2 v2) -> shape b1 = shape b2
v1: Vector (length_Batch b1) B
v2: Vector (length_Batch b2) B
Vsim: v1 ~~ v2
b: B
Vsim': vcons (length_Batch b1) b v1 ~~ vcons (length_Batch b2) b v2

Batch_make b1 v1 b = Batch_make b2 v2 b
A1, B, C: Type
b1: Batch A1 B (B -> C)
a: A1
A2: Type
b2: Batch A2 B (B -> C)
a0: A2
Hlen: length_Batch (b1 ⧆ a) = length_Batch (b2 ⧆ a0)
v1: Vector (length_Batch b1) B
v2: Vector (length_Batch b2) B
b: B
Hsim: Batch_make (b1 ⧆ a) (vcons (length_Batch b1) b v1) = Batch_make (b2 ⧆ a0) (vcons (length_Batch b2) b v2)
IHb1: forall b2 : Batch A2 B (B -> C), length_Batch b1 = length_Batch b2 -> (forall (v1 : Vector (length_Batch b1) B) (v2 : Vector (length_Batch b2) B), v1 ~~ v2 -> Batch_make b1 v1 = Batch_make b2 v2) -> shape b1 = shape b2
Vsim: v1 ~~ v2
Vsim': vcons (length_Batch b1) b v1 ~~ vcons (length_Batch b2) b v2

Batch_make b1 v1 b = Batch_make b2 v2 b
A1, B, C: Type
b1: Batch A1 B (B -> C)
a: A1
A2: Type
b2: Batch A2 B (B -> C)
a0: A2
Hlen: length_Batch (b1 ⧆ a) = length_Batch (b2 ⧆ a0)
v1: Vector (length_Batch b1) B
v2: Vector (length_Batch b2) B
b: B
Hsim: Batch_make b1 (Vector_tl (vcons (length_Batch b1) b v1)) (Vector_hd (vcons (length_Batch b1) b v1)) = Batch_make b2 (Vector_tl (vcons (length_Batch b2) b v2)) (Vector_hd (vcons (length_Batch b2) b v2))
IHb1: forall b2 : Batch A2 B (B -> C), length_Batch b1 = length_Batch b2 -> (forall (v1 : Vector (length_Batch b1) B) (v2 : Vector (length_Batch b2) B), v1 ~~ v2 -> Batch_make b1 v1 = Batch_make b2 v2) -> shape b1 = shape b2
Vsim: v1 ~~ v2
Vsim': vcons (length_Batch b1) b v1 ~~ vcons (length_Batch b2) b v2

Batch_make b1 v1 b = Batch_make b2 v2 b
A1, B, C: Type
b1: Batch A1 B (B -> C)
a: A1
A2: Type
b2: Batch A2 B (B -> C)
a0: A2
Hlen: length_Batch (b1 ⧆ a) = length_Batch (b2 ⧆ a0)
v1: Vector (length_Batch b1) B
v2: Vector (length_Batch b2) B
b: B
Hsim: Batch_make b1 v1 (Vector_hd (vcons (length_Batch b1) b v1)) = Batch_make b2 v2 (Vector_hd (vcons (length_Batch b2) b v2))
IHb1: forall b2 : Batch A2 B (B -> C), length_Batch b1 = length_Batch b2 -> (forall (v1 : Vector (length_Batch b1) B) (v2 : Vector (length_Batch b2) B), v1 ~~ v2 -> Batch_make b1 v1 = Batch_make b2 v2) -> shape b1 = shape b2
Vsim: v1 ~~ v2
Vsim': vcons (length_Batch b1) b v1 ~~ vcons (length_Batch b2) b v2

Batch_make b1 v1 b = Batch_make b2 v2 b
A1, B, C: Type
b1: Batch A1 B (B -> C)
a: A1
A2: Type
b2: Batch A2 B (B -> C)
a0: A2
Hlen: length_Batch (b1 ⧆ a) = length_Batch (b2 ⧆ a0)
v1: Vector (length_Batch b1) B
v2: Vector (length_Batch b2) B
b: B
Hsim: Batch_make b1 v1 b = Batch_make b2 v2 b
IHb1: forall b2 : Batch A2 B (B -> C), length_Batch b1 = length_Batch b2 -> (forall (v1 : Vector (length_Batch b1) B) (v2 : Vector (length_Batch b2) B), v1 ~~ v2 -> Batch_make b1 v1 = Batch_make b2 v2) -> shape b1 = shape b2
Vsim: v1 ~~ v2
Vsim': vcons (length_Batch b1) b v1 ~~ vcons (length_Batch b2) b v2

Batch_make b1 v1 b = Batch_make b2 v2 b
assumption. Qed.

forall (A1 B C : Type) (b1 : Batch A1 B C) (A2 : Type) (b2 : Batch A2 B C), shape b1 = shape b2 <-> Batch_make b1 ~!~ Batch_make b2

forall (A1 B C : Type) (b1 : Batch A1 B C) (A2 : Type) (b2 : Batch A2 B C), shape b1 = shape b2 <-> Batch_make b1 ~!~ Batch_make b2
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C

shape b1 = shape b2 <-> Batch_make b1 ~!~ Batch_make b2
split; auto using Batch_make_shape, Batch_make_shape_rev. Qed. (** ** Two Lemmas for <<shape>> and <<length_Batch>> *) (******************************************************************************)

forall (A B C : Type) (b : Batch A B C), shape b = Batch_replace_contents b (Vector_tt (length_Batch b))

forall (A B C : Type) (b : Batch A B C), shape b = Batch_replace_contents b (Vector_tt (length_Batch b))
A, B, C: Type
b: Batch A B C

shape b = Batch_replace_contents b (Vector_tt (length_Batch b))
A, B, C: Type
c: C

shape (Done c) = Batch_replace_contents (Done c) (Vector_tt (length_Batch (Done c)))
A, B, C: Type
b: Batch A B (B -> C)
a: A
IHb: shape b = Batch_replace_contents b (Vector_tt (length_Batch b))
shape (b ⧆ a) = Batch_replace_contents (b ⧆ a) (Vector_tt (length_Batch (b ⧆ a)))
A, B, C: Type
c: C

shape (Done c) = Batch_replace_contents (Done c) (Vector_tt (length_Batch (Done c)))
reflexivity.
A, B, C: Type
b: Batch A B (B -> C)
a: A
IHb: shape b = Batch_replace_contents b (Vector_tt (length_Batch b))

shape (b ⧆ a) = Batch_replace_contents (b ⧆ a) (Vector_tt (length_Batch (b ⧆ a)))
A, B, C: Type
b: Batch A B (B -> C)
a: A
IHb: shape b = Batch_replace_contents b (Vector_tt (length_Batch b))

mapfst_Batch (const tt) b ⧆ const tt a = Batch_replace_contents b (Vector_tl (vcons (length_Batch b) tt (Vector_repeat (length_Batch b) tt))) ⧆ Vector_hd (vcons (length_Batch b) tt (Vector_repeat (length_Batch b) tt))
A, B, C: Type
b: Batch A B (B -> C)
a: A
IHb: shape b = Batch_replace_contents b (Vector_tt (length_Batch b))

mapfst_Batch (const tt) b ⧆ const tt a = Batch_replace_contents b (Vector_repeat (length_Batch b) tt) ⧆ Vector_hd (vcons (length_Batch b) tt (Vector_repeat (length_Batch b) tt))
A, B, C: Type
b: Batch A B (B -> C)
a: A
IHb: shape b = Batch_replace_contents b (Vector_tt (length_Batch b))

mapfst_Batch (const tt) b ⧆ const tt a = Batch_replace_contents b (Vector_repeat (length_Batch b) tt) ⧆ tt
A, B, C: Type
b: Batch A B (B -> C)
a: A
IHb: shape b = Batch_replace_contents b (Vector_tt (length_Batch b))

mapfst_Batch (const tt) b = Batch_replace_contents b (Vector_repeat (length_Batch b) tt)
apply IHb. Qed.

forall (A1 B C : Type) (b1 : Batch A1 B C) (A2 : Type) (b2 : Batch A2 B C), (Type -> Batch_make b1 ~!~ Batch_make b2) -> length_Batch b1 = length_Batch b2

forall (A1 B C : Type) (b1 : Batch A1 B C) (A2 : Type) (b2 : Batch A2 B C), (Type -> Batch_make b1 ~!~ Batch_make b2) -> length_Batch b1 = length_Batch b2
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C
H: Type -> Batch_make b1 ~!~ Batch_make b2

length_Batch b1 = length_Batch b2
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C
H: Type -> Batch_make b1 ~!~ Batch_make b2

?f ~!~ ?g
apply (H False). Qed.

forall (A1 B C : Type) (b1 : Batch A1 B C) (A2 : Type) (b2 : Batch A2 B C), (forall A' : Type, Batch_replace_contents b1 ~!~ Batch_replace_contents b2) -> length_Batch b1 = length_Batch b2

forall (A1 B C : Type) (b1 : Batch A1 B C) (A2 : Type) (b2 : Batch A2 B C), (forall A' : Type, Batch_replace_contents b1 ~!~ Batch_replace_contents b2) -> length_Batch b1 = length_Batch b2
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C
H: forall A' : Type, Batch_replace_contents b1 ~!~ Batch_replace_contents b2

length_Batch b1 = length_Batch b2
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C
H: forall A' : Type, Batch_replace_contents b1 ~!~ Batch_replace_contents b2

?f ~!~ ?g
apply (H False). Qed. (** ** Same Shape Implies Same <<Batch_replace_contents>> *) (******************************************************************************)

forall (A1 B C : Type) (b1 : Batch A1 B C) (A2 : Type) (b2 : Batch A2 B C), shape b1 = shape b2 -> forall A' : Type, Batch_replace_contents b1 ~!~ Batch_replace_contents b2

forall (A1 B C : Type) (b1 : Batch A1 B C) (A2 : Type) (b2 : Batch A2 B C), shape b1 = shape b2 -> forall A' : Type, Batch_replace_contents b1 ~!~ Batch_replace_contents b2
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C
Hshape: shape b1 = shape b2

forall A' : Type, Batch_replace_contents b1 ~!~ Batch_replace_contents b2
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C
Hshape: shape b1 = shape b2

forall (C : Type) (c : C) (A' : Type), Batch_replace_contents (Done c) ~!~ Batch_replace_contents (Done c)
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C
Hshape: shape b1 = shape b2
forall (C : Type) (b1 : Batch A1 B (B -> C)) (b2 : Batch A2 B (B -> C)), (forall A' : Type, Batch_replace_contents b1 ~!~ Batch_replace_contents b2) -> forall (a1 : A1) (a2 : A2), shape (b1 ⧆ a1) = shape (b2 ⧆ a2) -> forall A' : Type, Batch_replace_contents (b1 ⧆ a1) ~!~ Batch_replace_contents (b2 ⧆ a2)
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C
Hshape: shape b1 = shape b2

forall (C : Type) (c : C) (A' : Type), Batch_replace_contents (Done c) ~!~ Batch_replace_contents (Done c)
A1, B, A2: Type

forall (C : Type) (c : C) (A' : Type), Batch_replace_contents (Done c) ~!~ Batch_replace_contents (Done c)
A1, B, A2, C: Type
c: C
A': Type

Batch_replace_contents (Done c) ~!~ Batch_replace_contents (Done c)
now split.
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C
Hshape: shape b1 = shape b2

forall (C : Type) (b1 : Batch A1 B (B -> C)) (b2 : Batch A2 B (B -> C)), (forall A' : Type, Batch_replace_contents b1 ~!~ Batch_replace_contents b2) -> forall (a1 : A1) (a2 : A2), shape (b1 ⧆ a1) = shape (b2 ⧆ a2) -> forall A' : Type, Batch_replace_contents (b1 ⧆ a1) ~!~ Batch_replace_contents (b2 ⧆ a2)
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C
Hshape: shape b1 = shape b2
C0: Type
b0: Batch A1 B (B -> C0)
b3: Batch A2 B (B -> C0)
H: forall A' : Type, Batch_replace_contents b0 ~!~ Batch_replace_contents b3
a1: A1
a2: A2
Hshape0: shape (b0 ⧆ a1) = shape (b3 ⧆ a2)
A': Type

Batch_replace_contents (b0 ⧆ a1) ~!~ Batch_replace_contents (b3 ⧆ a2)
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C
Hshape: shape b1 = shape b2
C0: Type
b0: Batch A1 B (B -> C0)
b3: Batch A2 B (B -> C0)
H: forall A' : Type, Batch_replace_contents b0 ~!~ Batch_replace_contents b3
a1: A1
a2: A2
Hshape0: shape (b0 ⧆ a1) = shape (b3 ⧆ a2)
A': Type

length_Batch (b0 ⧆ a1) = length_Batch (b3 ⧆ a2)
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C
Hshape: shape b1 = shape b2
C0: Type
b0: Batch A1 B (B -> C0)
b3: Batch A2 B (B -> C0)
H: forall A' : Type, Batch_replace_contents b0 ~!~ Batch_replace_contents b3
a1: A1
a2: A2
Hshape0: shape (b0 ⧆ a1) = shape (b3 ⧆ a2)
A': Type
forall (v1 : Vector (length_Batch (b0 ⧆ a1)) A') (v2 : Vector (length_Batch (b3 ⧆ a2)) A'), v1 ~~ v2 -> Batch_replace_contents (b0 ⧆ a1) v1 = Batch_replace_contents (b3 ⧆ a2) v2
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C
Hshape: shape b1 = shape b2
C0: Type
b0: Batch A1 B (B -> C0)
b3: Batch A2 B (B -> C0)
H: forall A' : Type, Batch_replace_contents b0 ~!~ Batch_replace_contents b3
a1: A1
a2: A2
Hshape0: shape (b0 ⧆ a1) = shape (b3 ⧆ a2)
A': Type

length_Batch (b0 ⧆ a1) = length_Batch (b3 ⧆ a2)
auto using length_Batch_shape.
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C
Hshape: shape b1 = shape b2
C0: Type
b0: Batch A1 B (B -> C0)
b3: Batch A2 B (B -> C0)
H: forall A' : Type, Batch_replace_contents b0 ~!~ Batch_replace_contents b3
a1: A1
a2: A2
Hshape0: shape (b0 ⧆ a1) = shape (b3 ⧆ a2)
A': Type

forall (v1 : Vector (length_Batch (b0 ⧆ a1)) A') (v2 : Vector (length_Batch (b3 ⧆ a2)) A'), v1 ~~ v2 -> Batch_replace_contents (b0 ⧆ a1) v1 = Batch_replace_contents (b3 ⧆ a2) v2
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C
Hshape: shape b1 = shape b2
C0: Type
b0: Batch A1 B (B -> C0)
b3: Batch A2 B (B -> C0)
H: forall A' : Type, Batch_replace_contents b0 ~!~ Batch_replace_contents b3
a1: A1
a2: A2
Hshape0: shape (b0 ⧆ a1) = shape (b3 ⧆ a2)
A': Type
v1: Vector (length_Batch (b0 ⧆ a1)) A'
v2: Vector (length_Batch (b3 ⧆ a2)) A'
Hsim: v1 ~~ v2

Batch_replace_contents (b0 ⧆ a1) v1 = Batch_replace_contents (b3 ⧆ a2) v2
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C
Hshape: shape b1 = shape b2
C0: Type
b0: Batch A1 B (B -> C0)
b3: Batch A2 B (B -> C0)
H: forall A' : Type, Batch_replace_contents b0 ~!~ Batch_replace_contents b3
a1: A1
a2: A2
Hshape0: shape (b0 ⧆ a1) = shape (b3 ⧆ a2)
A': Type
v1: Vector (length_Batch (b0 ⧆ a1)) A'
v2: Vector (length_Batch (b3 ⧆ a2)) A'
Hsim: v1 ~~ v2

Batch_replace_contents b0 (Vector_tl v1) ⧆ Vector_hd v1 = Batch_replace_contents b3 (Vector_tl v2) ⧆ Vector_hd v2
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C
Hshape: shape b1 = shape b2
C0: Type
b0: Batch A1 B (B -> C0)
b3: Batch A2 B (B -> C0)
H: forall A' : Type, Batch_replace_contents b0 ~!~ Batch_replace_contents b3
a1: A1
a2: A2
Hshape0: shape (b0 ⧆ a1) = shape (b3 ⧆ a2)
A': Type
v1: Vector (length_Batch (b0 ⧆ a1)) A'
v2: Vector (length_Batch (b3 ⧆ a2)) A'
Hsim: v1 ~~ v2

Batch_replace_contents b0 (Vector_tl v1) ⧆ Vector_hd v2 = Batch_replace_contents b3 (Vector_tl v2) ⧆ Vector_hd v2
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C
Hshape: shape b1 = shape b2
C0: Type
b0: Batch A1 B (B -> C0)
b3: Batch A2 B (B -> C0)
H: forall A' : Type, Batch_replace_contents b0 ~!~ Batch_replace_contents b3
a1: A1
a2: A2
Hshape0: shape (b0 ⧆ a1) = shape (b3 ⧆ a2)
A': Type
v1: Vector (length_Batch (b0 ⧆ a1)) A'
v2: Vector (length_Batch (b3 ⧆ a2)) A'
Hsim: v1 ~~ v2

Batch_replace_contents b0 (Vector_tl v1) = Batch_replace_contents b3 (Vector_tl v2)
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C
Hshape: shape b1 = shape b2
C0: Type
b0: Batch A1 B (B -> C0)
b3: Batch A2 B (B -> C0)
H: forall A' : Type, Batch_replace_contents b0 ~!~ Batch_replace_contents b3
a1: A1
a2: A2
Hshape0: shape (b0 ⧆ a1) = shape (b3 ⧆ a2)
A': Type
v1: Vector (length_Batch (b0 ⧆ a1)) A'
v2: Vector (length_Batch (b3 ⧆ a2)) A'
Hsim: v1 ~~ v2

Vector_tl v1 ~~ Vector_tl v2
auto using Vector_tl_sim. Qed.

forall (A1 B C : Type) (b1 : Batch A1 B C) (A2 : Type) (b2 : Batch A2 B C), (forall A' : Type, Batch_replace_contents b1 ~!~ Batch_replace_contents b2) -> shape b1 = shape b2

forall (A1 B C : Type) (b1 : Batch A1 B C) (A2 : Type) (b2 : Batch A2 B C), (forall A' : Type, Batch_replace_contents b1 ~!~ Batch_replace_contents b2) -> shape b1 = shape b2
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C
Hsim: forall A' : Type, Batch_replace_contents b1 ~!~ Batch_replace_contents b2

shape b1 = shape b2
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C
Hsim: forall A' : Type, Batch_replace_contents b1 ~!~ Batch_replace_contents b2

Batch_replace_contents b1 (Vector_tt (length_Batch b1)) = shape b2
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C
Hsim: forall A' : Type, Batch_replace_contents b1 ~!~ Batch_replace_contents b2

Batch_replace_contents b1 (Vector_tt (length_Batch b1)) = Batch_replace_contents b2 (Vector_tt (length_Batch b2))
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C
Hsim: forall A' : Type, Batch_replace_contents b1 ~!~ Batch_replace_contents b2

Vector_tt (length_Batch b1) ~~ Vector_tt (length_Batch b2)
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C
Hsim: forall A' : Type, Batch_replace_contents b1 ~!~ Batch_replace_contents b2
H: length_Batch b1 = length_Batch b2

Vector_tt (length_Batch b1) ~~ Vector_tt (length_Batch b2)
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C
Hsim: forall A' : Type, Batch_replace_contents b1 ~!~ Batch_replace_contents b2
length_Batch b1 = length_Batch b2
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C
Hsim: forall A' : Type, Batch_replace_contents b1 ~!~ Batch_replace_contents b2
H: length_Batch b1 = length_Batch b2

Vector_tt (length_Batch b1) ~~ Vector_tt (length_Batch b2)
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C
Hsim: forall A' : Type, Batch_replace_contents b1 ~!~ Batch_replace_contents b2
H: length_Batch b1 = length_Batch b2

Vector_tt (length_Batch b2) ~~ Vector_tt (length_Batch b2)
reflexivity.
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C
Hsim: forall A' : Type, Batch_replace_contents b1 ~!~ Batch_replace_contents b2

length_Batch b1 = length_Batch b2
now apply Batch_replace_contents_sim_length. Qed.

forall (A1 B C : Type) (b1 : Batch A1 B C) (A2 : Type) (b2 : Batch A2 B C), (forall A' : Type, Batch_replace_contents b1 ~!~ Batch_replace_contents b2) <-> shape b1 = shape b2

forall (A1 B C : Type) (b1 : Batch A1 B C) (A2 : Type) (b2 : Batch A2 B C), (forall A' : Type, Batch_replace_contents b1 ~!~ Batch_replace_contents b2) <-> shape b1 = shape b2
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C

(forall A' : Type, Batch_replace_contents b1 ~!~ Batch_replace_contents b2) <-> shape b1 = shape b2
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C

(forall A' : Type, Batch_replace_contents b1 ~!~ Batch_replace_contents b2) -> shape b1 = shape b2
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C
shape b1 = shape b2 -> forall A' : Type, Batch_replace_contents b1 ~!~ Batch_replace_contents b2
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C

(forall A' : Type, Batch_replace_contents b1 ~!~ Batch_replace_contents b2) -> shape b1 = shape b2
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C
H: forall A' : Type, Batch_replace_contents b1 ~!~ Batch_replace_contents b2

shape b1 = shape b2
now apply Batch_replace_contents_shape_rev.
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C

shape b1 = shape b2 -> forall A' : Type, Batch_replace_contents b1 ~!~ Batch_replace_contents b2
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C
H: shape b1 = shape b2
A': Type

Batch_replace_contents b1 ~!~ Batch_replace_contents b2
now apply Batch_replace_contents_shape. Qed. (** ** <<Batch_make>> Equal Iff <<Batch_replace_contents>> Equal *) (******************************************************************************)

forall (A1 B C : Type) (b1 : Batch A1 B C) (A2 : Type) (b2 : Batch A2 B C), Batch_make b1 ~!~ Batch_make b2 <-> (forall A' : Type, Batch_replace_contents b1 ~!~ Batch_replace_contents b2)

forall (A1 B C : Type) (b1 : Batch A1 B C) (A2 : Type) (b2 : Batch A2 B C), Batch_make b1 ~!~ Batch_make b2 <-> (forall A' : Type, Batch_replace_contents b1 ~!~ Batch_replace_contents b2)
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C

Batch_make b1 ~!~ Batch_make b2 <-> (forall A' : Type, Batch_replace_contents b1 ~!~ Batch_replace_contents b2)
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C

shape b1 = shape b2 <-> (forall A' : Type, Batch_replace_contents b1 ~!~ Batch_replace_contents b2)
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C

(forall A' : Type, Batch_replace_contents b1 ~!~ Batch_replace_contents b2) <-> (forall A' : Type, Batch_replace_contents b1 ~!~ Batch_replace_contents b2)
reflexivity. Qed. (** ** Similarity Lemmas for <<Batch_make>> *) (******************************************************************************)
A, B, C: Type
b: Batch A B C
v1, v2: Vector (length_Batch b) B
Hsim: v1 ~~ v2

Batch_make b v1 = Batch_make b v2
A, B, C: Type
b: Batch A B C
v1, v2: Vector (length_Batch b) B
Hsim: v1 ~~ v2

Batch_make b v1 = Batch_make b v2
A, B, C: Type
b: Batch A B C
v1, v2: Vector (length_Batch b) B
Hsim: v1 = v2

Batch_make b v1 = Batch_make b v2
now subst. Qed. (* This sort of lemma is very useful when the complexity of expression <<v1>> and <<v2>> obstructs tactics like <<rewrite>> *)
A, B, C: Type
b1, b2: Batch A B C
v1: Vector (length_Batch b1) B
v2: Vector (length_Batch b2) B
Heq: b1 = b2
Hsim: v1 ~~ v2

Batch_make b1 v1 = Batch_make b2 v2
A, B, C: Type
b1, b2: Batch A B C
v1: Vector (length_Batch b1) B
v2: Vector (length_Batch b2) B
Heq: b1 = b2
Hsim: v1 ~~ v2

Batch_make b1 v1 = Batch_make b2 v2
A, B, C: Type
b2: Batch A B C
v1, v2: Vector (length_Batch b2) B
Hsim: v1 ~~ v2

Batch_make b2 v1 = Batch_make b2 v2
now (subst; apply Batch_make_sim1). Qed.
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C
v1: Vector (length_Batch b1) B
v2: Vector (length_Batch b2) B
Heq: shape b1 = shape b2
Hsim: v1 ~~ v2

Batch_make b1 v1 = Batch_make b2 v2
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C
v1: Vector (length_Batch b1) B
v2: Vector (length_Batch b2) B
Heq: shape b1 = shape b2
Hsim: v1 ~~ v2

Batch_make b1 v1 = Batch_make b2 v2
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C
v1: Vector (length_Batch b1) B
v2: Vector (length_Batch b2) B
Heq: shape b1 = shape b2
Hsim: v1 ~~ v2

Batch_make b1 ~!~ Batch_make b2
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C
v1: Vector (length_Batch b1) B
v2: Vector (length_Batch b2) B
Heq: shape b1 = shape b2
Hsim: v1 ~~ v2
v1 ~~ v2
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C
v1: Vector (length_Batch b1) B
v2: Vector (length_Batch b2) B
Heq: shape b1 = shape b2
Hsim: v1 ~~ v2

shape b1 = shape b2
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C
v1: Vector (length_Batch b1) B
v2: Vector (length_Batch b2) B
Heq: shape b1 = shape b2
Hsim: v1 ~~ v2
v1 ~~ v2
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C
v1: Vector (length_Batch b1) B
v2: Vector (length_Batch b2) B
Heq: shape b1 = shape b2
Hsim: v1 ~~ v2

v1 ~~ v2
assumption. Qed.
A, B, C: Type
b: Batch A B C
v1: Vector (length_Batch b) B
n: nat
v2: Vector n B
Heq: n = length_Batch b

v1 ~~ v2 -> Batch_make b v1 = Batch_make b (coerce Heq in v2)
A, B, C: Type
b: Batch A B C
v1: Vector (length_Batch b) B
n: nat
v2: Vector n B
Heq: n = length_Batch b

v1 ~~ v2 -> Batch_make b v1 = Batch_make b (coerce Heq in v2)
A, B, C: Type
b: Batch A B C
v1, v2: Vector (length_Batch b) B

v1 ~~ v2 -> Batch_make b v1 = Batch_make b (coerce eq_refl in v2)
A, B, C: Type
b: Batch A B C
v1, v2: Vector (length_Batch b) B
H: v1 ~~ v2

Batch_make b v1 = Batch_make b (coerce eq_refl in v2)
A, B, C: Type
b: Batch A B C
v1, v2: Vector (length_Batch b) B
H: v1 ~~ v2

Batch_make b v1 = Batch_make b v2
A, B, C: Type
b: Batch A B C
v1, v2: Vector (length_Batch b) B
H: v1 ~~ v2

v1 ~~ v2
assumption. Qed. (** Rewrite the <<Batch>> argument to an equal one by coercing the length proof in the vector. *)
A, B, C: Type
b1, b2: Batch A B C
v: Vector (length_Batch b1) B
Heq: b1 = b2

Batch_make b1 v = Batch_make b2 (rew [fun b : Batch A B C => Vector (length_Batch b) B] Heq in v)
A, B, C: Type
b1, b2: Batch A B C
v: Vector (length_Batch b1) B
Heq: b1 = b2

Batch_make b1 v = Batch_make b2 (rew [fun b : Batch A B C => Vector (length_Batch b) B] Heq in v)
now (subst; apply Batch_make_sim1). Qed.
A, B, C: Type
b1, b2: Batch A B C
v: Vector (length_Batch b1) B
Heq: b1 = b2

Batch_make b1 v = Batch_make b2 (coerce eq_ind_r (fun z : Batch A B C => length_Batch z = length_Batch b2) eq_refl Heq in v)
A, B, C: Type
b1, b2: Batch A B C
v: Vector (length_Batch b1) B
Heq: b1 = b2

Batch_make b1 v = Batch_make b2 (coerce eq_ind_r (fun z : Batch A B C => length_Batch z = length_Batch b2) eq_refl Heq in v)
A, B, C: Type
b2: Batch A B C
v: Vector (length_Batch b2) B

Batch_make b2 v = Batch_make b2 (coerce eq_ind_r (fun z : Batch A B C => length_Batch z = length_Batch b2) eq_refl eq_refl in v)
A, B, C: Type
b2: Batch A B C
v: Vector (length_Batch b2) B

Batch_make b2 v = Batch_make b2 (coerce eq_refl in v)
now rewrite coerce_Vector_eq_refl. Qed. (** ** Similarity Laws for <<Batch_replace_contents>> *) (******************************************************************************)
A, B, C: Type
b: Batch A B C
A': Type
v1, v2: Vector (length_Batch b) A'
Hsim: v1 ~~ v2

Batch_replace_contents b v1 = Batch_replace_contents b v2
A, B, C: Type
b: Batch A B C
A': Type
v1, v2: Vector (length_Batch b) A'
Hsim: v1 ~~ v2

Batch_replace_contents b v1 = Batch_replace_contents b v2
A, B, C: Type
c: C
A': Type
v1, v2: Vector (length_Batch (Done c)) A'
Hsim: v1 ~~ v2

Batch_replace_contents (Done c) v1 = Batch_replace_contents (Done c) v2
A, B, C: Type
b: Batch A B (B -> C)
a: A
A': Type
v1, v2: Vector (length_Batch (b ⧆ a)) A'
Hsim: v1 ~~ v2
IHb: forall v1 v2 : Vector (length_Batch b) A', v1 ~~ v2 -> Batch_replace_contents b v1 = Batch_replace_contents b v2
Batch_replace_contents (b ⧆ a) v1 = Batch_replace_contents (b ⧆ a) v2
A, B, C: Type
c: C
A': Type
v1, v2: Vector (length_Batch (Done c)) A'
Hsim: v1 ~~ v2

Batch_replace_contents (Done c) v1 = Batch_replace_contents (Done c) v2
reflexivity.
A, B, C: Type
b: Batch A B (B -> C)
a: A
A': Type
v1, v2: Vector (length_Batch (b ⧆ a)) A'
Hsim: v1 ~~ v2
IHb: forall v1 v2 : Vector (length_Batch b) A', v1 ~~ v2 -> Batch_replace_contents b v1 = Batch_replace_contents b v2

Batch_replace_contents (b ⧆ a) v1 = Batch_replace_contents (b ⧆ a) v2
A, B, C: Type
b: Batch A B (B -> C)
a: A
A': Type
v1, v2: Vector (length_Batch (b ⧆ a)) A'
Hsim: v1 ~~ v2
IHb: forall v1 v2 : Vector (length_Batch b) A', v1 ~~ v2 -> Batch_replace_contents b v1 = Batch_replace_contents b v2

Batch_replace_contents b (Vector_tl v1) ⧆ Vector_hd v1 = Batch_replace_contents b (Vector_tl v2) ⧆ Vector_hd v2
A, B, C: Type
b: Batch A B (B -> C)
a: A
A': Type
v1, v2: Vector (length_Batch (b ⧆ a)) A'
Hsim: v1 ~~ v2
IHb: forall v1 v2 : Vector (length_Batch b) A', v1 ~~ v2 -> Batch_replace_contents b v1 = Batch_replace_contents b v2

Batch_replace_contents b (Vector_tl v2) ⧆ Vector_hd v1 = Batch_replace_contents b (Vector_tl v2) ⧆ Vector_hd v2
A, B, C: Type
b: Batch A B (B -> C)
a: A
A': Type
v1, v2: Vector (length_Batch (b ⧆ a)) A'
Hsim: v1 ~~ v2
IHb: forall v1 v2 : Vector (length_Batch b) A', v1 ~~ v2 -> Batch_replace_contents b v1 = Batch_replace_contents b v2

Batch_replace_contents b (Vector_tl v2) ⧆ Vector_hd v2 = Batch_replace_contents b (Vector_tl v2) ⧆ Vector_hd v2
reflexivity. Qed.
A, B, C: Type
b1, b2: Batch A B C
A': Type
v1: Vector (length_Batch b1) A'
v2: Vector (length_Batch b2) A'
Heq: b1 = b2
Hsim: v1 ~~ v2

Batch_replace_contents b1 v1 = Batch_replace_contents b2 v2
A, B, C: Type
b1, b2: Batch A B C
A': Type
v1: Vector (length_Batch b1) A'
v2: Vector (length_Batch b2) A'
Heq: b1 = b2
Hsim: v1 ~~ v2

Batch_replace_contents b1 v1 = Batch_replace_contents b2 v2
now (subst; apply Batch_replace_sim1). Qed.
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C
A': Type
v1: Vector (length_Batch b1) A'
v2: Vector (length_Batch b2) A'
Heq: shape b1 = shape b2
Hsim: v1 ~~ v2

Batch_replace_contents b1 v1 = Batch_replace_contents b2 v2
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C
A': Type
v1: Vector (length_Batch b1) A'
v2: Vector (length_Batch b2) A'
Heq: shape b1 = shape b2
Hsim: v1 ~~ v2

Batch_replace_contents b1 v1 = Batch_replace_contents b2 v2
A1, B, C: Type
b1: Batch A1 B C
A2: Type
b2: Batch A2 B C
A': Type
v1: Vector (length_Batch b1) A'
v2: Vector (length_Batch b2) A'
Heq: shape b1 = shape b2
Hsim: v1 ~~ v2

Batch_replace_contents b1 ~!~ Batch_replace_contents b2
now apply Batch_replace_contents_shape_iff. Qed. (** ** Naturality of <<Batch_make>> *) (******************************************************************************)
A, B, C: Type
b: Batch A B C
D: Type
f: C -> D
v1: Vector (length_Batch b) B
v2: Vector (length_Batch (map (Batch A B) f b)) B
Hsim: v1 ~~ v2

f (Batch_make b v1) = Batch_make (map (Batch A B) f b) v2
A, B, C: Type
b: Batch A B C
D: Type
f: C -> D
v1: Vector (length_Batch b) B
v2: Vector (length_Batch (map (Batch A B) f b)) B
Hsim: v1 ~~ v2

f (Batch_make b v1) = Batch_make (map (Batch A B) f b) v2
A, B, C: Type
b: Batch A B C
D: Type
f: C -> D
v1: Vector (length_Batch b) B

forall v2 : Vector (length_Batch (map (Batch A B) f b)) B, v1 ~~ v2 -> f (Batch_make b v1) = Batch_make (map (Batch A B) f b) v2
A, B, C: Type
b: Batch A B C
D: Type
f: C -> D

forall (v1 : Vector (length_Batch b) B) (v2 : Vector (length_Batch (map (Batch A B) f b)) B), v1 ~~ v2 -> f (Batch_make b v1) = Batch_make (map (Batch A B) f b) v2
A, B, C: Type
b: Batch A B C

forall (D : Type) (f : C -> D) (v1 : Vector (length_Batch b) B) (v2 : Vector (length_Batch (map (Batch A B) f b)) B), v1 ~~ v2 -> f (Batch_make b v1) = Batch_make (map (Batch A B) f b) v2
A, B, C: Type
c: C

forall (D : Type) (f : C -> D) (v1 : Vector (length_Batch (Done c)) B) (v2 : Vector (length_Batch (map (Batch A B) f (Done c))) B), v1 ~~ v2 -> f (Batch_make (Done c) v1) = Batch_make (map (Batch A B) f (Done c)) v2
A, B, C: Type
rest: Batch A B (B -> C)
a: A
IHrest: forall (D : Type) (f : (B -> C) -> D) (v1 : Vector (length_Batch rest) B) (v2 : Vector (length_Batch (map (Batch A B) f rest)) B), v1 ~~ v2 -> f (Batch_make rest v1) = Batch_make (map (Batch A B) f rest) v2
forall (D : Type) (f : C -> D) (v1 : Vector (length_Batch (rest ⧆ a)) B) (v2 : Vector (length_Batch (map (Batch A B) f (rest ⧆ a))) B), v1 ~~ v2 -> f (Batch_make (rest ⧆ a) v1) = Batch_make (map (Batch A B) f (rest ⧆ a)) v2
A, B, C: Type
c: C

forall (D : Type) (f : C -> D) (v1 : Vector (length_Batch (Done c)) B) (v2 : Vector (length_Batch (map (Batch A B) f (Done c))) B), v1 ~~ v2 -> f (Batch_make (Done c) v1) = Batch_make (map (Batch A B) f (Done c)) v2
reflexivity.
A, B, C: Type
rest: Batch A B (B -> C)
a: A
IHrest: forall (D : Type) (f : (B -> C) -> D) (v1 : Vector (length_Batch rest) B) (v2 : Vector (length_Batch (map (Batch A B) f rest)) B), v1 ~~ v2 -> f (Batch_make rest v1) = Batch_make (map (Batch A B) f rest) v2

forall (D : Type) (f : C -> D) (v1 : Vector (length_Batch (rest ⧆ a)) B) (v2 : Vector (length_Batch (map (Batch A B) f (rest ⧆ a))) B), v1 ~~ v2 -> f (Batch_make (rest ⧆ a) v1) = Batch_make (map (Batch A B) f (rest ⧆ a)) v2
A, B, C: Type
rest: Batch A B (B -> C)
a: A
IHrest: forall (D : Type) (f : (B -> C) -> D) (v1 : Vector (length_Batch rest) B) (v2 : Vector (length_Batch (map (Batch A B) f rest)) B), v1 ~~ v2 -> f (Batch_make rest v1) = Batch_make (map (Batch A B) f rest) v2
D: Type
f: C -> D
v1: Vector (length_Batch (rest ⧆ a)) B
v2: Vector (length_Batch (map (Batch A B) f (rest ⧆ a))) B
Hsim: v1 ~~ v2

f (Batch_make (rest ⧆ a) v1) = Batch_make (map (Batch A B) f (rest ⧆ a)) v2
A, B, C: Type
rest: Batch A B (B -> C)
a: A
IHrest: forall (D : Type) (f : (B -> C) -> D) (v1 : Vector (length_Batch rest) B) (v2 : Vector (length_Batch (map (Batch A B) f rest)) B), v1 ~~ v2 -> f (Batch_make rest v1) = Batch_make (map (Batch A B) f rest) v2
D: Type
f: C -> D
v1: Vector (length_Batch (rest ⧆ a)) B
v2: Vector (length_Batch (map (Batch A B) (compose f) rest ⧆ a)) B
Hsim: v1 ~~ v2

f (Batch_make (rest ⧆ a) v1) = Batch_make (map (Batch A B) (compose f) rest ⧆ a) v2
A, B, C: Type
rest: Batch A B (B -> C)
a: A
IHrest: forall (D : Type) (f : (B -> C) -> D) (v1 : Vector (length_Batch rest) B) (v2 : Vector (length_Batch (map (Batch A B) f rest)) B), v1 ~~ v2 -> f (Batch_make rest v1) = Batch_make (map (Batch A B) f rest) v2
D: Type
f: C -> D
v1: Vector (S (length_Batch rest)) B
v2: Vector (S (length_Batch (map (Batch A B) (compose f) rest))) B
Hsim: v1 ~~ v2

f (Batch_make (rest ⧆ a) v1) = Batch_make (map (Batch A B) (compose f) rest ⧆ a) v2
A, B, C: Type
rest: Batch A B (B -> C)
a: A
IHrest: forall (D : Type) (f : (B -> C) -> D) (v1 : Vector (length_Batch rest) B) (v2 : Vector (length_Batch (map (Batch A B) f rest)) B), v1 ~~ v2 -> f (Batch_make rest v1) = Batch_make (map (Batch A B) f rest) v2
D: Type
f: C -> D
v1: Vector (S (length_Batch rest)) B
v2: Vector (S (length_Batch (map (Batch A B) (compose f) rest))) B
Hsim: v1 ~~ v2

f (Batch_make rest (Vector_tl v1) (Vector_hd v1)) = Batch_make (map (Batch A B) (compose f) rest) (Vector_tl v2) (Vector_hd v2)
A, B, C: Type
rest: Batch A B (B -> C)
a: A
IHrest: forall (D : Type) (f : (B -> C) -> D) (v1 : Vector (length_Batch rest) B) (v2 : Vector (length_Batch (map (Batch A B) f rest)) B), v1 ~~ v2 -> f (Batch_make rest v1) = Batch_make (map (Batch A B) f rest) v2
D: Type
f: C -> D
v1: Vector (S (length_Batch rest)) B
v2: Vector (S (length_Batch (map (Batch A B) (compose f) rest))) B
Hsim: v1 ~~ v2

f (Batch_make rest (Vector_tl v1) (Vector_hd v1)) = Batch_make (map (Batch A B) (compose f) rest) (Vector_tl v2) (Vector_hd v1)
A, B, C: Type
rest: Batch A B (B -> C)
a: A
IHrest: forall (D : Type) (f : (B -> C) -> D) (v1 : Vector (length_Batch rest) B) (v2 : Vector (length_Batch (map (Batch A B) f rest)) B), v1 ~~ v2 -> f (Batch_make rest v1) = Batch_make (map (Batch A B) f rest) v2
D: Type
f: C -> D
v1: Vector (S (length_Batch rest)) B
v2: Vector (S (length_Batch (map (Batch A B) (compose f) rest))) B
Hsim: v1 ~~ v2

(f ∘ Batch_make rest (Vector_tl v1)) (Vector_hd v1) = Batch_make (map (Batch A B) (compose f) rest) (Vector_tl v2) (Vector_hd v1)
A, B, C: Type
rest: Batch A B (B -> C)
a: A
D: Type
f: C -> D
IHrest: forall (v1 : Vector (length_Batch rest) B) (v2 : Vector (length_Batch (map (Batch A B) (compose f) rest)) B), v1 ~~ v2 -> f ∘ Batch_make rest v1 = Batch_make (map (Batch A B) (compose f) rest) v2
v1: Vector (S (length_Batch rest)) B
v2: Vector (S (length_Batch (map (Batch A B) (compose f) rest))) B
Hsim: v1 ~~ v2

(f ∘ Batch_make rest (Vector_tl v1)) (Vector_hd v1) = Batch_make (map (Batch A B) (compose f) rest) (Vector_tl v2) (Vector_hd v1)
A, B, C: Type
rest: Batch A B (B -> C)
a: A
D: Type
f: C -> D
IHrest: forall (v1 : Vector (length_Batch rest) B) (v2 : Vector (length_Batch (map (Batch A B) (compose f) rest)) B), v1 ~~ v2 -> f ∘ Batch_make rest v1 = Batch_make (map (Batch A B) (compose f) rest) v2
v1: Vector (S (length_Batch rest)) B
v2: Vector (S (length_Batch (map (Batch A B) (compose f) rest))) B
Hsim: v1 ~~ v2

Batch_make (map (Batch A B) (compose f) rest) (Vector_tl v2) (Vector_hd v1) = Batch_make (map (Batch A B) (compose f) rest) (Vector_tl v2) (Vector_hd v1)
reflexivity. Qed.
A, B, C: Type
b: Batch A B C
D: Type
f: C -> D
v: Vector (length_Batch b) B

f (Batch_make b v) = Batch_make (map (Batch A B) f b) (coerce batch_length_map f b in v)
A, B, C: Type
b: Batch A B C
D: Type
f: C -> D
v: Vector (length_Batch b) B

f (Batch_make b v) = Batch_make (map (Batch A B) f b) (coerce batch_length_map f b in v)
now rewrite ( Batch_make_natural b f (v1 := v) (v2 :=coerce_Vector_length (batch_length_map _ _) v) ) by vector_sim. Qed.
A, B, C: Type
b: Batch A B C
D: Type
f: C -> D
v: Vector (length_Batch (map (Batch A B) f b)) B

Batch_make (map (Batch A B) f b) v = f (Batch_make b (coerce eq_sym (batch_length_map f b) in v))
A, B, C: Type
b: Batch A B C
D: Type
f: C -> D
v: Vector (length_Batch (map (Batch A B) f b)) B

Batch_make (map (Batch A B) f b) v = f (Batch_make b (coerce eq_sym (batch_length_map f b) in v))
A, B, C: Type
b: Batch A B C
D: Type
f: C -> D
v: Vector (length_Batch (map (Batch A B) f b)) B

Batch_make (map (Batch A B) f b) v = Batch_make (map (Batch A B) f b) (coerce batch_length_map f b in coerce eq_sym (batch_length_map f b) in v)
A, B, C: Type
b: Batch A B C
D: Type
f: C -> D
v: Vector (length_Batch (map (Batch A B) f b)) B

v ~~ coerce batch_length_map f b in coerce eq_sym (batch_length_map f b) in v
vector_sim. Qed. (** ** Naturality of <<Batch_contents>> *) (******************************************************************************)

forall (A B C : Type) (b : Batch A B C) (A' : Type) (f : A -> A'), map (Vector (length_Batch b)) f (Batch_contents b) ~~ Batch_contents (mapfst_Batch f b)

forall (A B C : Type) (b : Batch A B C) (A' : Type) (f : A -> A'), map (Vector (length_Batch b)) f (Batch_contents b) ~~ Batch_contents (mapfst_Batch f b)
A, B, C: Type
b: Batch A B C
A': Type
f: A -> A'

map (Vector (length_Batch b)) f (Batch_contents b) ~~ Batch_contents (mapfst_Batch f b)
A, B, C: Type
c: C
A': Type
f: A -> A'

map (Vector (length_Batch (Done c))) f (Batch_contents (Done c)) ~~ Batch_contents (mapfst_Batch f (Done c))
A, B, C: Type
b: Batch A B (B -> C)
a: A
A': Type
f: A -> A'
IHb: map (Vector (length_Batch b)) f (Batch_contents b) ~~ Batch_contents (mapfst_Batch f b)
map (Vector (length_Batch (b ⧆ a))) f (Batch_contents (b ⧆ a)) ~~ Batch_contents (mapfst_Batch f (b ⧆ a))
A, B, C: Type
c: C
A': Type
f: A -> A'

map (Vector (length_Batch (Done c))) f (Batch_contents (Done c)) ~~ Batch_contents (mapfst_Batch f (Done c))
reflexivity.
A, B, C: Type
b: Batch A B (B -> C)
a: A
A': Type
f: A -> A'
IHb: map (Vector (length_Batch b)) f (Batch_contents b) ~~ Batch_contents (mapfst_Batch f b)

map (Vector (length_Batch (b ⧆ a))) f (Batch_contents (b ⧆ a)) ~~ Batch_contents (mapfst_Batch f (b ⧆ a))
A, B, C: Type
b: Batch A B (B -> C)
a: A
A': Type
f: A -> A'
IHb: map (Vector (length_Batch b)) f (Batch_contents b) ~~ Batch_contents (mapfst_Batch f b)

map (Vector (S (length_Batch b))) f (vcons (length_Batch b) a (Batch_contents b)) ~~ vcons (length_Batch (mapfst_Batch f b)) (f a) (Batch_contents (mapfst_Batch f b))
A, B, C: Type
b: Batch A B (B -> C)
a: A
A': Type
f: A -> A'
IHb: map (Vector (length_Batch b)) f (Batch_contents b) ~~ Batch_contents (mapfst_Batch f b)

vcons (length_Batch b) (f a) (map (Vector (length_Batch b)) f (Batch_contents b)) ~~ vcons (length_Batch (mapfst_Batch f b)) (f a) (Batch_contents (mapfst_Batch f b))
A, B, C: Type
b: Batch A B (B -> C)
a: A
A': Type
f: A -> A'
IHb: map (Vector (length_Batch b)) f (Batch_contents b) ~~ Batch_contents (mapfst_Batch f b)

map (Vector (length_Batch b)) f (Batch_contents b) ~~ Batch_contents (mapfst_Batch f b)
assumption. Qed. (** ** Specification for <<Batch_replace_contents>> *) (*******************************************************************************)
A, A', B, C: Type

forall b : Batch A B C, Batch_replace_contents b = Batch_make (cojoin_Batch b) ○ coerce_Vector_length (length_cojoin_Batch b)
A, A', B, C: Type

forall b : Batch A B C, Batch_replace_contents b = Batch_make (cojoin_Batch b) ○ coerce_Vector_length (length_cojoin_Batch b)
A, A', B, C: Type
b: Batch A B C

Batch_replace_contents b = Batch_make (cojoin_Batch b) ○ coerce_Vector_length (length_cojoin_Batch b)
A, A', B, C: Type
b: Batch A B C
v: Vector (length_Batch b) A'

Batch_replace_contents b v = Batch_make (cojoin_Batch b) (coerce length_cojoin_Batch b in v)
A, A', B, C: Type
b: Batch A B C
v: Vector (length_Batch b) A'

forall e : length_Batch b = length_Batch (cojoin_Batch b), Batch_replace_contents b v = Batch_make (cojoin_Batch b) (coerce e in v)
A, A', B, C: Type
b: Batch A B C
v: Vector (length_Batch b) A'
Heq: length_Batch b = length_Batch (cojoin_Batch b)

Batch_replace_contents b v = Batch_make (cojoin_Batch b) (coerce Heq in v)
A, A', B, C: Type
c: C
v: Vector (length_Batch (Done c)) A'
Heq: length_Batch (Done c) = length_Batch (cojoin_Batch (Done c))

Batch_replace_contents (Done c) v = Batch_make (cojoin_Batch (Done c)) (coerce Heq in v)
A, A', B, C: Type
b: Batch A B (B -> C)
a: A
v: Vector (length_Batch (b ⧆ a)) A'
Heq: length_Batch (b ⧆ a) = length_Batch (cojoin_Batch (b ⧆ a))
IHb: forall (v : Vector (length_Batch b) A') (Heq : length_Batch b = length_Batch (cojoin_Batch b)), Batch_replace_contents b v = Batch_make (cojoin_Batch b) (coerce Heq in v)
Batch_replace_contents (b ⧆ a) v = Batch_make (cojoin_Batch (b ⧆ a)) (coerce Heq in v)
A, A', B, C: Type
c: C
v: Vector (length_Batch (Done c)) A'
Heq: length_Batch (Done c) = length_Batch (cojoin_Batch (Done c))

Batch_replace_contents (Done c) v = Batch_make (cojoin_Batch (Done c)) (coerce Heq in v)
reflexivity.
A, A', B, C: Type
b: Batch A B (B -> C)
a: A
v: Vector (length_Batch (b ⧆ a)) A'
Heq: length_Batch (b ⧆ a) = length_Batch (cojoin_Batch (b ⧆ a))
IHb: forall (v : Vector (length_Batch b) A') (Heq : length_Batch b = length_Batch (cojoin_Batch b)), Batch_replace_contents b v = Batch_make (cojoin_Batch b) (coerce Heq in v)

Batch_replace_contents (b ⧆ a) v = Batch_make (cojoin_Batch (b ⧆ a)) (coerce Heq in v)
A, A', B, C: Type
b: Batch A B (B -> C)
a: A
v: Vector (length_Batch (b ⧆ a)) A'
Heq: length_Batch (b ⧆ a) = length_Batch (cojoin_Batch (b ⧆ a))
IHb: forall (v : Vector (length_Batch b) A') (Heq : length_Batch b = length_Batch (cojoin_Batch b)), Batch_replace_contents b v = Batch_make (cojoin_Batch b) (coerce Heq in v)

Batch_replace_contents b (Vector_tl v) ⧆ Vector_hd v = Batch_make (cojoin_Batch (b ⧆ a)) (coerce Heq in v)
A, A', B, C: Type
b: Batch A B (B -> C)
a: A
v: Vector (length_Batch (b ⧆ a)) A'
Heq: length_Batch (b ⧆ a) = length_Batch (cojoin_Batch (b ⧆ a))
IHb: forall (v : Vector (length_Batch b) A') (Heq : length_Batch b = length_Batch (cojoin_Batch b)), Batch_replace_contents b v = Batch_make (cojoin_Batch b) (coerce Heq in v)

Batch_replace_contents b (Vector_tl v) ⧆ Vector_hd v = Batch_make (map (Batch A A') Step (cojoin_Batch b)) (Vector_tl (coerce Heq in v)) (Vector_hd (coerce Heq in v))
A, A', B, C: Type
b: Batch A B (B -> C)
a: A
v: Vector (length_Batch (b ⧆ a)) A'
Heq: length_Batch (b ⧆ a) = length_Batch (cojoin_Batch (b ⧆ a))
IHb: forall (v : Vector (length_Batch b) A') (Heq : length_Batch b = length_Batch (cojoin_Batch b)), Batch_replace_contents b v = Batch_make (cojoin_Batch b) (coerce Heq in v)

Batch_replace_contents b (Vector_tl v) ⧆ Vector_hd v = Batch_make (cojoin_Batch b) (coerce eq_sym (batch_length_map Step (cojoin_Batch b)) in Vector_tl (coerce Heq in v)) ⧆ Vector_hd (coerce Heq in v)
A, A', B, C: Type
b: Batch A B (B -> C)
a: A
v: Vector (length_Batch (b ⧆ a)) A'
Heq: length_Batch (b ⧆ a) = length_Batch (cojoin_Batch (b ⧆ a))
IHb: forall (v : Vector (length_Batch b) A') (Heq : length_Batch b = length_Batch (cojoin_Batch b)), Batch_replace_contents b v = Batch_make (cojoin_Batch b) (coerce Heq in v)

Batch_replace_contents b (Vector_tl v) ⧆ Vector_hd v = Batch_make (cojoin_Batch b) (coerce eq_sym (batch_length_map Step (cojoin_Batch b)) in Vector_tl (coerce Heq in v)) ⧆ Vector_hd v
A, A', B, C: Type
b: Batch A B (B -> C)
a: A
v: Vector (length_Batch (b ⧆ a)) A'
Heq: length_Batch (b ⧆ a) = length_Batch (cojoin_Batch (b ⧆ a))
IHb: forall (v : Vector (length_Batch b) A') (Heq : length_Batch b = length_Batch (cojoin_Batch b)), Batch_replace_contents b v = Batch_make (cojoin_Batch b) (coerce Heq in v)

Batch_replace_contents b (Vector_tl v) = Batch_make (cojoin_Batch b) (coerce eq_sym (batch_length_map Step (cojoin_Batch b)) in Vector_tl (coerce Heq in v))
A, A', B, C: Type
b: Batch A B (B -> C)
a: A
v: Vector (length_Batch (b ⧆ a)) A'
Heq: length_Batch (b ⧆ a) = length_Batch (cojoin_Batch (b ⧆ a))
IHb: Batch_replace_contents b (Vector_tl v) = Batch_make (cojoin_Batch b) (coerce length_cojoin_Batch b in Vector_tl v)

Batch_replace_contents b (Vector_tl v) = Batch_make (cojoin_Batch b) (coerce eq_sym (batch_length_map Step (cojoin_Batch b)) in Vector_tl (coerce Heq in v))
A, A', B, C: Type
b: Batch A B (B -> C)
a: A
v: Vector (length_Batch (b ⧆ a)) A'
Heq: length_Batch (b ⧆ a) = length_Batch (cojoin_Batch (b ⧆ a))
IHb: Batch_replace_contents b (Vector_tl v) = Batch_make (cojoin_Batch b) (coerce length_cojoin_Batch b in Vector_tl v)

Batch_make (cojoin_Batch b) (coerce length_cojoin_Batch b in Vector_tl v) = Batch_make (cojoin_Batch b) (coerce eq_sym (batch_length_map Step (cojoin_Batch b)) in Vector_tl (coerce Heq in v))
A, A', B, C: Type
b: Batch A B (B -> C)
a: A
v: Vector (length_Batch (b ⧆ a)) A'
Heq: length_Batch (b ⧆ a) = length_Batch (cojoin_Batch (b ⧆ a))
IHb: Batch_replace_contents b (Vector_tl v) = Batch_make (cojoin_Batch b) (coerce length_cojoin_Batch b in Vector_tl v)

coerce length_cojoin_Batch b in Vector_tl v ~~ coerce eq_sym (batch_length_map Step (cojoin_Batch b)) in Vector_tl (coerce Heq in v)
vector_sim. Qed. (** ** Replacing Contents Does Not Change <<length_Batch>>, <<shape>>, or <<Batch_make>> *) (*******************************************************************************)

forall (A B C : Type) (b : Batch A B C) (A' : Type) (v : Vector (length_Batch b) A'), length_Batch b = length_Batch (Batch_replace_contents b v)

forall (A B C : Type) (b : Batch A B C) (A' : Type) (v : Vector (length_Batch b) A'), length_Batch b = length_Batch (Batch_replace_contents b v)
A, B, C: Type
b: Batch A B C
A': Type
v: Vector (length_Batch b) A'

length_Batch b = length_Batch (Batch_replace_contents b v)
A, B, C: Type
c: C
A': Type
v: Vector (length_Batch (Done c)) A'

length_Batch (Done c) = length_Batch (Batch_replace_contents (Done c) v)
A, B, C: Type
b: Batch A B (B -> C)
a: A
A': Type
v: Vector (length_Batch (b ⧆ a)) A'
IHb: forall v : Vector (length_Batch b) A', length_Batch b = length_Batch (Batch_replace_contents b v)
length_Batch (b ⧆ a) = length_Batch (Batch_replace_contents (b ⧆ a) v)
A, B, C: Type
c: C
A': Type
v: Vector (length_Batch (Done c)) A'

length_Batch (Done c) = length_Batch (Batch_replace_contents (Done c) v)
reflexivity.
A, B, C: Type
b: Batch A B (B -> C)
a: A
A': Type
v: Vector (length_Batch (b ⧆ a)) A'
IHb: forall v : Vector (length_Batch b) A', length_Batch b = length_Batch (Batch_replace_contents b v)

length_Batch (b ⧆ a) = length_Batch (Batch_replace_contents (b ⧆ a) v)
A, B, C: Type
b: Batch A B (B -> C)
a: A
A': Type
v: Vector (length_Batch (b ⧆ a)) A'
IHb: forall v : Vector (length_Batch b) A', length_Batch b = length_Batch (Batch_replace_contents b v)

S (length_Batch b) = S (length_Batch (Batch_replace_contents b (Vector_tl v)))
A, B, C: Type
b: Batch A B (B -> C)
a: A
A': Type
v: Vector (length_Batch (b ⧆ a)) A'
IHb: forall v : Vector (length_Batch b) A', length_Batch b = length_Batch (Batch_replace_contents b v)

length_Batch b = length_Batch (Batch_replace_contents b (Vector_tl v))
apply (IHb (Vector_tl v)). Qed.
A, A', B, C: Type

forall (b : Batch A B C) (v : Vector (length_Batch b) A'), Batch_make (Batch_replace_contents b v) = Batch_make b ○ coerce_Vector_length (eq_sym (length_replace_contents b v))
A, A', B, C: Type

forall (b : Batch A B C) (v : Vector (length_Batch b) A'), Batch_make (Batch_replace_contents b v) = Batch_make b ○ coerce_Vector_length (eq_sym (length_replace_contents b v))
A, A', B, C: Type
b: Batch A B C
v: Vector (length_Batch b) A'

Batch_make (Batch_replace_contents b v) = Batch_make b ○ coerce_Vector_length (eq_sym (length_replace_contents b v))
A, A', B, C: Type
b: Batch A B C
v: Vector (length_Batch b) A'
v': Vector (length_Batch (Batch_replace_contents b v)) B

Batch_make (Batch_replace_contents b v) v' = Batch_make b (coerce eq_sym (length_replace_contents b v) in v')
A, A', B, C: Type
b: Batch A B C
v: Vector (length_Batch b) A'
v': Vector (length_Batch (Batch_replace_contents b v)) B

forall e : length_Batch (Batch_replace_contents b v) = length_Batch b, Batch_make (Batch_replace_contents b v) v' = Batch_make b (coerce e in v')
A, A', B, C: Type
b: Batch A B C
v: Vector (length_Batch b) A'
v': Vector (length_Batch (Batch_replace_contents b v)) B
e: length_Batch (Batch_replace_contents b v) = length_Batch b

Batch_make (Batch_replace_contents b v) v' = Batch_make b (coerce e in v')
A, A', B, C: Type
c: C
v: Vector (length_Batch (Done c)) A'
v': Vector (length_Batch (Batch_replace_contents (Done c) v)) B
e: length_Batch (Batch_replace_contents (Done c) v) = length_Batch (Done c)

Batch_make (Batch_replace_contents (Done c) v) v' = Batch_make (Done c) (coerce e in v')
A, A', B, C: Type
b: Batch A B (B -> C)
a: A
v: Vector (length_Batch (b ⧆ a)) A'
v': Vector (length_Batch (Batch_replace_contents (b ⧆ a) v)) B
e: length_Batch (Batch_replace_contents (b ⧆ a) v) = length_Batch (b ⧆ a)
IHb: forall (v : Vector (length_Batch b) A') (v' : Vector (length_Batch (Batch_replace_contents b v)) B) (e : length_Batch (Batch_replace_contents b v) = length_Batch b), Batch_make (Batch_replace_contents b v) v' = Batch_make b (coerce e in v')
Batch_make (Batch_replace_contents (b ⧆ a) v) v' = Batch_make (b ⧆ a) (coerce e in v')
A, A', B, C: Type
c: C
v: Vector (length_Batch (Done c)) A'
v': Vector (length_Batch (Batch_replace_contents (Done c) v)) B
e: length_Batch (Batch_replace_contents (Done c) v) = length_Batch (Done c)

Batch_make (Batch_replace_contents (Done c) v) v' = Batch_make (Done c) (coerce e in v')
reflexivity.
A, A', B, C: Type
b: Batch A B (B -> C)
a: A
v: Vector (length_Batch (b ⧆ a)) A'
v': Vector (length_Batch (Batch_replace_contents (b ⧆ a) v)) B
e: length_Batch (Batch_replace_contents (b ⧆ a) v) = length_Batch (b ⧆ a)
IHb: forall (v : Vector (length_Batch b) A') (v' : Vector (length_Batch (Batch_replace_contents b v)) B) (e : length_Batch (Batch_replace_contents b v) = length_Batch b), Batch_make (Batch_replace_contents b v) v' = Batch_make b (coerce e in v')

Batch_make (Batch_replace_contents (b ⧆ a) v) v' = Batch_make (b ⧆ a) (coerce e in v')
A, A', B, C: Type
b: Batch A B (B -> C)
a: A
v: Vector (length_Batch (b ⧆ a)) A'
v': Vector (length_Batch (Batch_replace_contents (b ⧆ a) v)) B
e: length_Batch (Batch_replace_contents (b ⧆ a) v) = length_Batch (b ⧆ a)
IHb: forall (v : Vector (length_Batch b) A') (v' : Vector (length_Batch (Batch_replace_contents b v)) B) (e : length_Batch (Batch_replace_contents b v) = length_Batch b), Batch_make (Batch_replace_contents b v) v' = Batch_make b (coerce e in v')

Batch_make (Batch_replace_contents b (Vector_tl v)) (Vector_tl v') (Vector_hd v') = Batch_make b (Vector_tl (coerce e in v')) (Vector_hd (coerce e in v'))
A, A', B, C: Type
b: Batch A B (B -> C)
a: A
v: Vector (length_Batch (b ⧆ a)) A'
v': Vector (length_Batch (Batch_replace_contents (b ⧆ a) v)) B
e: length_Batch (Batch_replace_contents (b ⧆ a) v) = length_Batch (b ⧆ a)
IHb: forall e : length_Batch (Batch_replace_contents b (Vector_tl v)) = length_Batch b, Batch_make (Batch_replace_contents b (Vector_tl v)) (Vector_tl v') = Batch_make b (coerce e in Vector_tl v')

Batch_make (Batch_replace_contents b (Vector_tl v)) (Vector_tl v') (Vector_hd v') = Batch_make b (Vector_tl (coerce e in v')) (Vector_hd (coerce e in v'))
A, A', B, C: Type
b: Batch A B (B -> C)
a: A
v: Vector (length_Batch (b ⧆ a)) A'
v': Vector (length_Batch (Batch_replace_contents (b ⧆ a) v)) B
e: length_Batch (Batch_replace_contents (b ⧆ a) v) = length_Batch (b ⧆ a)
IHb: Batch_make (Batch_replace_contents b (Vector_tl v)) (Vector_tl v') = Batch_make b (coerce eq_sym (length_replace_contents b (Vector_tl v)) in Vector_tl v')

Batch_make (Batch_replace_contents b (Vector_tl v)) (Vector_tl v') (Vector_hd v') = Batch_make b (Vector_tl (coerce e in v')) (Vector_hd (coerce e in v'))
A, A', B, C: Type
b: Batch A B (B -> C)
a: A
v: Vector (length_Batch (b ⧆ a)) A'
v': Vector (length_Batch (Batch_replace_contents (b ⧆ a) v)) B
e: length_Batch (Batch_replace_contents (b ⧆ a) v) = length_Batch (b ⧆ a)
IHb: Batch_make (Batch_replace_contents b (Vector_tl v)) (Vector_tl v') = Batch_make b (coerce eq_sym (length_replace_contents b (Vector_tl v)) in Vector_tl v')

Batch_make (Batch_replace_contents b (Vector_tl v)) (Vector_tl v') (Vector_hd v') = Batch_make b (Vector_tl (coerce e in v')) (Vector_hd v')
A, A', B, C: Type
b: Batch A B (B -> C)
a: A
v: Vector (length_Batch (b ⧆ a)) A'
v': Vector (length_Batch (Batch_replace_contents (b ⧆ a) v)) B
e: length_Batch (Batch_replace_contents (b ⧆ a) v) = length_Batch (b ⧆ a)
IHb: Batch_make (Batch_replace_contents b (Vector_tl v)) (Vector_tl v') = Batch_make b (coerce eq_sym (length_replace_contents b (Vector_tl v)) in Vector_tl v')
Vector_hd v' = Vector_hd (coerce e in v')
A, A', B, C: Type
b: Batch A B (B -> C)
a: A
v: Vector (length_Batch (b ⧆ a)) A'
v': Vector (length_Batch (Batch_replace_contents (b ⧆ a) v)) B
e: length_Batch (Batch_replace_contents (b ⧆ a) v) = length_Batch (b ⧆ a)
IHb: Batch_make (Batch_replace_contents b (Vector_tl v)) (Vector_tl v') = Batch_make b (coerce eq_sym (length_replace_contents b (Vector_tl v)) in Vector_tl v')

Batch_make (Batch_replace_contents b (Vector_tl v)) (Vector_tl v') (Vector_hd v') = Batch_make b (Vector_tl (coerce e in v')) (Vector_hd v')
A, A', B, C: Type
b: Batch A B (B -> C)
a: A
v: Vector (length_Batch (b ⧆ a)) A'
v': Vector (length_Batch (Batch_replace_contents (b ⧆ a) v)) B
e: length_Batch (Batch_replace_contents (b ⧆ a) v) = length_Batch (b ⧆ a)
IHb: Batch_make (Batch_replace_contents b (Vector_tl v)) (Vector_tl v') = Batch_make b (coerce eq_sym (length_replace_contents b (Vector_tl v)) in Vector_tl v')
Vector_hd v' = Vector_hd (coerce e in v')
A, A', B, C: Type
b: Batch A B (B -> C)
a: A
v: Vector (length_Batch (b ⧆ a)) A'
v': Vector (length_Batch (Batch_replace_contents (b ⧆ a) v)) B
e: length_Batch (Batch_replace_contents (b ⧆ a) v) = length_Batch (b ⧆ a)
IHb: Batch_make (Batch_replace_contents b (Vector_tl v)) (Vector_tl v') = Batch_make b (coerce eq_sym (length_replace_contents b (Vector_tl v)) in Vector_tl v')

Batch_make b (coerce eq_sym (length_replace_contents b (Vector_tl v)) in Vector_tl v') (Vector_hd v') = Batch_make b (Vector_tl (coerce e in v')) (Vector_hd v')
A, A', B, C: Type
b: Batch A B (B -> C)
a: A
v: Vector (length_Batch (b ⧆ a)) A'
v': Vector (length_Batch (Batch_replace_contents (b ⧆ a) v)) B
e: length_Batch (Batch_replace_contents (b ⧆ a) v) = length_Batch (b ⧆ a)
IHb: Batch_make (Batch_replace_contents b (Vector_tl v)) (Vector_tl v') = Batch_make b (coerce eq_sym (length_replace_contents b (Vector_tl v)) in Vector_tl v')
Vector_hd v' = Vector_hd (coerce e in v')
A, A', B, C: Type
b: Batch A B (B -> C)
a: A
v: Vector (length_Batch (b ⧆ a)) A'
v': Vector (length_Batch (Batch_replace_contents (b ⧆ a) v)) B
e: length_Batch (Batch_replace_contents (b ⧆ a) v) = length_Batch (b ⧆ a)
IHb: Batch_make (Batch_replace_contents b (Vector_tl v)) (Vector_tl v') = Batch_make b (coerce eq_sym (length_replace_contents b (Vector_tl v)) in Vector_tl v')

Batch_make b (coerce eq_sym (length_replace_contents b (Vector_tl v)) in Vector_tl v') (Vector_hd v') = Batch_make b (Vector_tl (coerce e in v')) (Vector_hd v')
A, A', B, C: Type
b: Batch A B (B -> C)
a: A
v: Vector (length_Batch (b ⧆ a)) A'
v': Vector (length_Batch (Batch_replace_contents (b ⧆ a) v)) B
e: length_Batch (Batch_replace_contents (b ⧆ a) v) = length_Batch (b ⧆ a)
IHb: Batch_make (Batch_replace_contents b (Vector_tl v)) (Vector_tl v') = Batch_make b (coerce eq_sym (length_replace_contents b (Vector_tl v)) in Vector_tl v')
Vector_hd v' = Vector_hd (coerce e in v')
A, A', B, C: Type
b: Batch A B (B -> C)
a: A
v: Vector (length_Batch (b ⧆ a)) A'
v': Vector (length_Batch (Batch_replace_contents (b ⧆ a) v)) B
e: length_Batch (Batch_replace_contents (b ⧆ a) v) = length_Batch (b ⧆ a)
IHb: Batch_make (Batch_replace_contents b (Vector_tl v)) (Vector_tl v') = Batch_make b (coerce eq_sym (length_replace_contents b (Vector_tl v)) in Vector_tl v')

coerce eq_sym (length_replace_contents b (Vector_tl v)) in Vector_tl v' = Vector_tl (coerce e in v')
A, A', B, C: Type
b: Batch A B (B -> C)
a: A
v: Vector (length_Batch (b ⧆ a)) A'
v': Vector (length_Batch (Batch_replace_contents (b ⧆ a) v)) B
e: length_Batch (Batch_replace_contents (b ⧆ a) v) = length_Batch (b ⧆ a)
IHb: Batch_make (Batch_replace_contents b (Vector_tl v)) (Vector_tl v') = Batch_make b (coerce eq_sym (length_replace_contents b (Vector_tl v)) in Vector_tl v')
Vector_hd v' = Vector_hd (coerce e in v')
A, A', B, C: Type
b: Batch A B (B -> C)
a: A
v: Vector (length_Batch (b ⧆ a)) A'
v': Vector (length_Batch (Batch_replace_contents (b ⧆ a) v)) B
e: length_Batch (Batch_replace_contents (b ⧆ a) v) = length_Batch (b ⧆ a)
IHb: Batch_make (Batch_replace_contents b (Vector_tl v)) (Vector_tl v') = Batch_make b (coerce eq_sym (length_replace_contents b (Vector_tl v)) in Vector_tl v')

coerce eq_sym (length_replace_contents b (Vector_tl v)) in Vector_tl v' = Vector_tl (coerce e in v')
A, A', B, C: Type
b: Batch A B (B -> C)
a: A
v: Vector (length_Batch (b ⧆ a)) A'
v': Vector (length_Batch (Batch_replace_contents (b ⧆ a) v)) B
e: length_Batch (Batch_replace_contents (b ⧆ a) v) = length_Batch (b ⧆ a)
IHb: Batch_make (Batch_replace_contents b (Vector_tl v)) (Vector_tl v') = Batch_make b (coerce eq_sym (length_replace_contents b (Vector_tl v)) in Vector_tl v')

proj1_sig (coerce eq_sym (length_replace_contents b (Vector_tl v)) in Vector_tl v') = proj1_sig (Vector_tl (coerce e in v'))
A, A', B, C: Type
b: Batch A B (B -> C)
a: A
v: Vector (length_Batch (b ⧆ a)) A'
v': Vector (length_Batch (Batch_replace_contents (b ⧆ a) v)) B
e: length_Batch (Batch_replace_contents (b ⧆ a) v) = length_Batch (b ⧆ a)
IHb: Batch_make (Batch_replace_contents b (Vector_tl v)) (Vector_tl v') = Batch_make b (coerce eq_sym (length_replace_contents b (Vector_tl v)) in Vector_tl v')

proj1_sig (Vector_tl v') = proj1_sig (Vector_tl (coerce e in v'))
apply Vector_tl_coerce_sim.
A, A', B, C: Type
b: Batch A B (B -> C)
a: A
v: Vector (length_Batch (b ⧆ a)) A'
v': Vector (length_Batch (Batch_replace_contents (b ⧆ a) v)) B
e: length_Batch (Batch_replace_contents (b ⧆ a) v) = length_Batch (b ⧆ a)
IHb: Batch_make (Batch_replace_contents b (Vector_tl v)) (Vector_tl v') = Batch_make b (coerce eq_sym (length_replace_contents b (Vector_tl v)) in Vector_tl v')

Vector_hd v' = Vector_hd (coerce e in v')
apply Vector_hd_coerce_eq. Qed.

forall (A A' B C : Type) (b : Batch A B C) (v : Vector (length_Batch b) A'), shape b = shape (Batch_replace_contents b v)

forall (A A' B C : Type) (b : Batch A B C) (v : Vector (length_Batch b) A'), shape b = shape (Batch_replace_contents b v)
A, A', B, C: Type
b: Batch A B C
v: Vector (length_Batch b) A'

shape b = shape (Batch_replace_contents b v)
A, A', B, C: Type
c: C
v: Vector (length_Batch (Done c)) A'

shape (Done c) = shape (Batch_replace_contents (Done c) v)
A, A', B, C: Type
b: Batch A B (B -> C)
a: A
v: Vector (length_Batch (b ⧆ a)) A'
IHb: forall v : Vector (length_Batch b) A', shape b = shape (Batch_replace_contents b v)
shape (b ⧆ a) = shape (Batch_replace_contents (b ⧆ a) v)
A, A', B, C: Type
c: C
v: Vector (length_Batch (Done c)) A'

shape (Done c) = shape (Batch_replace_contents (Done c) v)
reflexivity.
A, A', B, C: Type
b: Batch A B (B -> C)
a: A
v: Vector (length_Batch (b ⧆ a)) A'
IHb: forall v : Vector (length_Batch b) A', shape b = shape (Batch_replace_contents b v)

shape (b ⧆ a) = shape (Batch_replace_contents (b ⧆ a) v)
A, A', B, C: Type
b: Batch A B (B -> C)
a: A
v: Vector (length_Batch (b ⧆ a)) A'
IHb: forall v : Vector (length_Batch b) A', shape b = shape (Batch_replace_contents b v)

mapfst_Batch (const tt) b ⧆ const tt a = mapfst_Batch (const tt) (Batch_replace_contents b (Vector_tl v)) ⧆ const tt (Vector_hd v)
A, A', B, C: Type
b: Batch A B (B -> C)
a: A
v: Vector (length_Batch (b ⧆ a)) A'
IHb: forall v : Vector (length_Batch b) A', shape b = shape (Batch_replace_contents b v)

mapfst_Batch (const tt) b = mapfst_Batch (const tt) (Batch_replace_contents b (Vector_tl v))
apply (IHb (Vector_tl v)). Qed. (** * Lens-like laws *) (******************************************************************************) Section lens_laws. Context {A A' A'' B C: Type}.
A, A', A'', B, C: Type

forall b : Batch A A C, Batch_make b (Batch_contents b) = extract_Batch b
A, A', A'', B, C: Type

forall b : Batch A A C, Batch_make b (Batch_contents b) = extract_Batch b
A, A', A'', B, C: Type
b: Batch A A C

Batch_make b (Batch_contents b) = extract_Batch b
A, A', A'', B, C: Type
c: C

Batch_make (Done c) (Batch_contents (Done c)) = extract_Batch (Done c)
A, A', A'', B, C: Type
b: Batch A A (A -> C)
a: A
IHb: Batch_make b (Batch_contents b) = extract_Batch b
Batch_make (b ⧆ a) (Batch_contents (b ⧆ a)) = extract_Batch (b ⧆ a)
A, A', A'', B, C: Type
c: C

Batch_make (Done c) (Batch_contents (Done c)) = extract_Batch (Done c)
reflexivity.
A, A', A'', B, C: Type
b: Batch A A (A -> C)
a: A
IHb: Batch_make b (Batch_contents b) = extract_Batch b

Batch_make (b ⧆ a) (Batch_contents (b ⧆ a)) = extract_Batch (b ⧆ a)
A, A', A'', B, C: Type
b: Batch A A (A -> C)
a: A
IHb: Batch_make b (Batch_contents b) = extract_Batch b

Batch_make b (Vector_tl (Batch_contents (b ⧆ a))) (Vector_hd (Batch_contents (b ⧆ a))) = extract_Batch (b ⧆ a)
A, A', A'', B, C: Type
b: Batch A A (A -> C)
a: A
IHb: Batch_make b (Batch_contents b) = extract_Batch b

Batch_make b (Vector_tl (vcons (length_Batch b) a (Batch_contents b))) (Vector_hd (vcons (length_Batch b) a (Batch_contents b))) = extract_Batch (b ⧆ a)
A, A', A'', B, C: Type
b: Batch A A (A -> C)
a: A
IHb: Batch_make b (Batch_contents b) = extract_Batch b

Batch_make b (Batch_contents b) (Vector_hd (vcons (length_Batch b) a (Batch_contents b))) = extract_Batch (b ⧆ a)
A, A', A'', B, C: Type
b: Batch A A (A -> C)
a: A
IHb: Batch_make b (Batch_contents b) = extract_Batch b

Batch_make b (Batch_contents b) a = extract_Batch (b ⧆ a)
A, A', A'', B, C: Type
b: Batch A A (A -> C)
a: A
IHb: Batch_make b (Batch_contents b) = extract_Batch b

extract_Batch b a = extract_Batch (b ⧆ a)
reflexivity. Qed.
A, A', A'', B, C: Type

forall b : Batch A B C, Batch_replace_contents b (Batch_contents b) = b
A, A', A'', B, C: Type

forall b : Batch A B C, Batch_replace_contents b (Batch_contents b) = b
A, A', A'', B, C: Type
b: Batch A B C

Batch_replace_contents b (Batch_contents b) = b
A, A', A'', B, C: Type
c: C

Batch_replace_contents (Done c) (Batch_contents (Done c)) = Done c
A, A', A'', B, C: Type
b: Batch A B (B -> C)
a: A
IHb: Batch_replace_contents b (Batch_contents b) = b
Batch_replace_contents (b ⧆ a) (Batch_contents (b ⧆ a)) = b ⧆ a
A, A', A'', B, C: Type
c: C

Batch_replace_contents (Done c) (Batch_contents (Done c)) = Done c
reflexivity.
A, A', A'', B, C: Type
b: Batch A B (B -> C)
a: A
IHb: Batch_replace_contents b (Batch_contents b) = b

Batch_replace_contents (b ⧆ a) (Batch_contents (b ⧆ a)) = b ⧆ a
A, A', A'', B, C: Type
b: Batch A B (B -> C)
a: A
IHb: Batch_replace_contents b (Batch_contents b) = b

Batch_replace_contents b (Vector_tl (vcons (length_Batch b) a (Batch_contents b))) ⧆ Vector_hd (vcons (length_Batch b) a (Batch_contents b)) = b ⧆ a
A, A', A'', B, C: Type
b: Batch A B (B -> C)
a: A
IHb: Batch_replace_contents b (Batch_contents b) = b

Batch_replace_contents b (Batch_contents b) ⧆ Vector_hd (vcons (length_Batch b) a (Batch_contents b)) = b ⧆ a
A, A', A'', B, C: Type
b: Batch A B (B -> C)
a: A
IHb: Batch_replace_contents b (Batch_contents b) = b

Batch_replace_contents b (Batch_contents b) ⧆ a = b ⧆ a
A, A', A'', B, C: Type
b: Batch A B (B -> C)
a: A
IHb: Batch_replace_contents b (Batch_contents b) = b

b ⧆ a = b ⧆ a
reflexivity. Qed.
A, A', A'', B, C: Type

forall (b : Batch A B C) (v : Vector (length_Batch b) A'), Batch_contents (Batch_replace_contents b v) = coerce length_replace_contents b v in v
A, A', A'', B, C: Type

forall (b : Batch A B C) (v : Vector (length_Batch b) A'), Batch_contents (Batch_replace_contents b v) = coerce length_replace_contents b v in v
A, A', A'', B, C: Type
b: Batch A B C
v: Vector (length_Batch b) A'

Batch_contents (Batch_replace_contents b v) = coerce length_replace_contents b v in v
A, A', A'', B, C: Type
b: Batch A B C
v: Vector (length_Batch b) A'

forall e : length_Batch b = length_Batch (Batch_replace_contents b v), Batch_contents (Batch_replace_contents b v) = coerce e in v
A, A', A'', B, C: Type
b: Batch A B C
v: Vector (length_Batch b) A'
Heq: length_Batch b = length_Batch (Batch_replace_contents b v)

Batch_contents (Batch_replace_contents b v) = coerce Heq in v
A, A', A'', B, C: Type
c: C
v: Vector (length_Batch (Done c)) A'
Heq: length_Batch (Done c) = length_Batch (Batch_replace_contents (Done c) v)

Batch_contents (Batch_replace_contents (Done c) v) = coerce Heq in v
A, A', A'', B, C: Type
b: Batch A B (B -> C)
a: A
v: Vector (length_Batch (b ⧆ a)) A'
Heq: length_Batch (b ⧆ a) = length_Batch (Batch_replace_contents (b ⧆ a) v)
IHb: forall (v : Vector (length_Batch b) A') (Heq : length_Batch b = length_Batch (Batch_replace_contents b v)), Batch_contents (Batch_replace_contents b v) = coerce Heq in v
Batch_contents (Batch_replace_contents (b ⧆ a) v) = coerce Heq in v
A, A', A'', B, C: Type
c: C
v: Vector (length_Batch (Done c)) A'
Heq: length_Batch (Done c) = length_Batch (Batch_replace_contents (Done c) v)

Batch_contents (Batch_replace_contents (Done c) v) = coerce Heq in v
A, A', A'', B, C: Type
c: C
v: Vector (length_Batch (Done c)) A'
Heq: length_Batch (Done c) = length_Batch (Batch_replace_contents (Done c) v)

vnil = coerce Heq in v
A, A', A'', B, C: Type
c: C
v: Vector (length_Batch (Done c)) A'
Heq: length_Batch (Done c) = length_Batch (Batch_replace_contents (Done c) v)

coerce Heq in v = vnil
apply Vector_nil_eq.
A, A', A'', B, C: Type
b: Batch A B (B -> C)
a: A
v: Vector (length_Batch (b ⧆ a)) A'
Heq: length_Batch (b ⧆ a) = length_Batch (Batch_replace_contents (b ⧆ a) v)
IHb: forall (v : Vector (length_Batch b) A') (Heq : length_Batch b = length_Batch (Batch_replace_contents b v)), Batch_contents (Batch_replace_contents b v) = coerce Heq in v

Batch_contents (Batch_replace_contents (b ⧆ a) v) = coerce Heq in v
A, A', A'', B, C: Type
b: Batch A B (B -> C)
a: A
v: Vector (S (length_Batch b)) A'
Heq: S (length_Batch b) = S (length_Batch (Batch_replace_contents b (Vector_tl v)))
IHb: forall (v : Vector (length_Batch b) A') (Heq : length_Batch b = length_Batch (Batch_replace_contents b v)), Batch_contents (Batch_replace_contents b v) = coerce Heq in v

vcons (length_Batch (Batch_replace_contents b (Vector_tl v))) (Vector_hd v) (Batch_contents (Batch_replace_contents b (Vector_tl v))) = coerce Heq in v
A, A', A'', B, C: Type
b: Batch A B (B -> C)
a: A
v: Vector (S (length_Batch b)) A'
Heq: S (length_Batch b) = S (length_Batch (Batch_replace_contents b (Vector_tl v)))
IHb: forall (v : Vector (length_Batch b) A') (Heq : length_Batch b = length_Batch (Batch_replace_contents b v)), Batch_contents (Batch_replace_contents b v) = coerce Heq in v

vcons (length_Batch (Batch_replace_contents b (Vector_tl v))) (Vector_hd v) (Batch_contents (Batch_replace_contents b (Vector_tl v))) = vcons (length_Batch (Batch_replace_contents b (Vector_tl v))) (Vector_hd (coerce Heq in v)) (Vector_tl (coerce Heq in v))
A, A', A'', B, C: Type
b: Batch A B (B -> C)
a: A
v: Vector (S (length_Batch b)) A'
Heq: S (length_Batch b) = S (length_Batch (Batch_replace_contents b (Vector_tl v)))
IHb: forall (v : Vector (length_Batch b) A') (Heq : length_Batch b = length_Batch (Batch_replace_contents b v)), Batch_contents (Batch_replace_contents b v) = coerce Heq in v

vcons (length_Batch (Batch_replace_contents b (Vector_tl v))) (Vector_hd v) (Batch_contents (Batch_replace_contents b (Vector_tl v))) = vcons (length_Batch (Batch_replace_contents b (Vector_tl v))) (Vector_hd v) (Vector_tl (coerce Heq in v))
A, A', A'', B, C: Type
b: Batch A B (B -> C)
a: A
v: Vector (S (length_Batch b)) A'
Heq: S (length_Batch b) = S (length_Batch (Batch_replace_contents b (Vector_tl v)))
IHb: Batch_contents (Batch_replace_contents b (Vector_tl v)) = coerce S_uncons Heq in Vector_tl v

vcons (length_Batch (Batch_replace_contents b (Vector_tl v))) (Vector_hd v) (Batch_contents (Batch_replace_contents b (Vector_tl v))) = vcons (length_Batch (Batch_replace_contents b (Vector_tl v))) (Vector_hd v) (Vector_tl (coerce Heq in v))
A, A', A'', B, C: Type
b: Batch A B (B -> C)
a: A
v: Vector (S (length_Batch b)) A'
Heq: S (length_Batch b) = S (length_Batch (Batch_replace_contents b (Vector_tl v)))
IHb: Batch_contents (Batch_replace_contents b (Vector_tl v)) = coerce S_uncons Heq in Vector_tl v

vcons (length_Batch (Batch_replace_contents b (Vector_tl v))) (Vector_hd v) (Batch_contents (Batch_replace_contents b (Vector_tl v))) = vcons (length_Batch (Batch_replace_contents b (Vector_tl v))) (Vector_hd v) (Vector_tl (coerce Heq in v))
(* ^^ I have no idea why this got expanded but it blocks rewriting *)
A, A', A'', B, C: Type
b: Batch A B (B -> C)
a: A
v: Vector (S (length_Batch b)) A'
Heq: S (length_Batch b) = S (length_Batch (Batch_replace_contents b (Vector_tl v)))
IHb: Batch_contents (Batch_replace_contents b (Vector_tl v)) = coerce S_uncons Heq in Vector_tl v

vcons (length_Batch (Batch_replace_contents b (Vector_tl v))) (Vector_hd v) (coerce S_uncons Heq in Vector_tl v) = vcons (length_Batch (Batch_replace_contents b (Vector_tl v))) (Vector_hd v) (Vector_tl (coerce Heq in v))
A, A', A'', B, C: Type
b: Batch A B (B -> C)
a: A
v: Vector (S (length_Batch b)) A'
Heq: S (length_Batch b) = S (length_Batch (Batch_replace_contents b (Vector_tl v)))
IHb: Batch_contents (Batch_replace_contents b (Vector_tl v)) = coerce S_uncons Heq in Vector_tl v

coerce S_uncons Heq in Vector_tl v = Vector_tl (coerce Heq in v)
A, A', A'', B, C: Type
b: Batch A B (B -> C)
a: A
v: Vector (S (length_Batch b)) A'
Heq: S (length_Batch b) = S (length_Batch (Batch_replace_contents b (Vector_tl v)))
IHb: Batch_contents (Batch_replace_contents b (Vector_tl v)) = coerce S_uncons Heq in Vector_tl v

coerce S_uncons Heq in Vector_tl v ~~ Vector_tl (coerce Heq in v)
vector_sim. Qed.
A, A', A'', B, C: Type

forall (b : Batch A B C) (v1 : Vector (length_Batch b) A') (v2 : Vector (length_Batch b) A''), Batch_replace_contents (Batch_replace_contents b v1) (coerce length_replace_contents b v1 in v2) = Batch_replace_contents b v2
A, A', A'', B, C: Type

forall (b : Batch A B C) (v1 : Vector (length_Batch b) A') (v2 : Vector (length_Batch b) A''), Batch_replace_contents (Batch_replace_contents b v1) (coerce length_replace_contents b v1 in v2) = Batch_replace_contents b v2
A, A', A'', B, C: Type
b: Batch A B C
v1: Vector (length_Batch b) A'
v2: Vector (length_Batch b) A''

Batch_replace_contents (Batch_replace_contents b v1) (coerce length_replace_contents b v1 in v2) = Batch_replace_contents b v2
A, A', A'', B, C: Type
b: Batch A B C
v1: Vector (length_Batch b) A'
v2: Vector (length_Batch b) A''

shape (Batch_replace_contents b v1) = shape b
A, A', A'', B, C: Type
b: Batch A B C
v1: Vector (length_Batch b) A'
v2: Vector (length_Batch b) A''
coerce length_replace_contents b v1 in v2 ~~ v2
A, A', A'', B, C: Type
b: Batch A B C
v1: Vector (length_Batch b) A'
v2: Vector (length_Batch b) A''

shape b = shape (Batch_replace_contents b v1)
A, A', A'', B, C: Type
b: Batch A B C
v1: Vector (length_Batch b) A'
v2: Vector (length_Batch b) A''
coerce length_replace_contents b v1 in v2 ~~ v2
A, A', A'', B, C: Type
b: Batch A B C
v1: Vector (length_Batch b) A'
v2: Vector (length_Batch b) A''

coerce length_replace_contents b v1 in v2 ~~ v2
vector_sim. Qed. End lens_laws. (** ** Batch is Shapely *) (******************************************************************************) Section Batch_shapely. Context {A B C: Type}.
A, B, C: Type

forall b1 b2 : Batch A B C, shape b1 = shape b2 -> tolist b1 = tolist b2 -> b1 = b2
A, B, C: Type

forall b1 b2 : Batch A B C, shape b1 = shape b2 -> tolist b1 = tolist b2 -> b1 = b2
A, B, C: Type
b1, b2: Batch A B C
Hshape: shape b1 = shape b2

tolist b1 = tolist b2 -> b1 = b2
A, B, C: Type
b1, b2: Batch A B C
Hshape: shape b1 = shape b2

forall (C : Type) (c : C), tolist (Done c) = tolist (Done c) -> Done c = Done c
A, B, C: Type
b1, b2: Batch A B C
Hshape: shape b1 = shape b2
forall (C : Type) (b1 b2 : Batch A B (B -> C)), (tolist b1 = tolist b2 -> b1 = b2) -> forall a1 a2 : A, shape (b1 ⧆ a1) = shape (b2 ⧆ a2) -> tolist (b1 ⧆ a1) = tolist (b2 ⧆ a2) -> b1 ⧆ a1 = b2 ⧆ a2
A, B, C: Type
b1, b2: Batch A B C
Hshape: shape b1 = shape b2

forall (C : Type) (c : C), tolist (Done c) = tolist (Done c) -> Done c = Done c
intros; reflexivity.
A, B, C: Type
b1, b2: Batch A B C
Hshape: shape b1 = shape b2

forall (C : Type) (b1 b2 : Batch A B (B -> C)), (tolist b1 = tolist b2 -> b1 = b2) -> forall a1 a2 : A, shape (b1 ⧆ a1) = shape (b2 ⧆ a2) -> tolist (b1 ⧆ a1) = tolist (b2 ⧆ a2) -> b1 ⧆ a1 = b2 ⧆ a2
A, B, C: Type
b1, b2: Batch A B C
Hshape: shape b1 = shape b2
X: Type
b1', b2': Batch A B (B -> X)
Heq: tolist b1' = tolist b2' -> b1' = b2'
a1, a2: A
Hshape': shape (b1' ⧆ a1) = shape (b2' ⧆ a2)
Hlist: tolist (b1' ⧆ a1) = tolist (b2' ⧆ a2)

b1' ⧆ a1 = b2' ⧆ a2
A, B, C: Type
b1, b2: Batch A B C
Hshape: shape b1 = shape b2
X: Type
b1', b2': Batch A B (B -> X)
Heq: tolist b1' = tolist b2' -> b1' = b2'
a1, a2: A
Hshape': shape (b1' ⧆ a1) = shape (b2' ⧆ a2)
Hlist: tolist b1' ++ a1 :: nil = tolist (b2' ⧆ a2)

b1' ⧆ a1 = b2' ⧆ a2
A, B, C: Type
b1, b2: Batch A B C
Hshape: shape b1 = shape b2
X: Type
b1', b2': Batch A B (B -> X)
Heq: tolist b1' = tolist b2' -> b1' = b2'
a1, a2: A
Hshape': shape (b1' ⧆ a1) = shape (b2' ⧆ a2)
Hlist: tolist b1' ++ a1 :: nil = tolist b2' ++ a2 :: nil

b1' ⧆ a1 = b2' ⧆ a2
A, B, C: Type
b1, b2: Batch A B C
Hshape: shape b1 = shape b2
X: Type
b1', b2': Batch A B (B -> X)
Heq: tolist b1' = tolist b2' -> b1' = b2'
a1, a2: A
Hshape': shape (b1' ⧆ a1) = shape (b2' ⧆ a2)
Hlist: tolist b1' ++ ret list A a1 = tolist b2' ++ ret list A a2

b1' ⧆ a1 = b2' ⧆ a2
A, B, C: Type
b1, b2: Batch A B C
Hshape: shape b1 = shape b2
X: Type
b1', b2': Batch A B (B -> X)
Heq: tolist b1' = tolist b2' -> b1' = b2'
a1, a2: A
Hshape': shape (b1' ⧆ a1) = shape (b2' ⧆ a2)
Hlist: tolist b1' ++ ret list A a1 = tolist b2' ++ ret list A a2

a1 = a2
A, B, C: Type
b1, b2: Batch A B C
Hshape: shape b1 = shape b2
X: Type
b1', b2': Batch A B (B -> X)
Heq: tolist b1' = tolist b2' -> b1' = b2'
a1, a2: A
Hshape': shape (b1' ⧆ a1) = shape (b2' ⧆ a2)
Hlist: tolist b1' ++ ret list A a1 = tolist b2' ++ ret list A a2
H: a1 = a2
b1' ⧆ a1 = b2' ⧆ a2
A, B, C: Type
b1, b2: Batch A B C
Hshape: shape b1 = shape b2
X: Type
b1', b2': Batch A B (B -> X)
Heq: tolist b1' = tolist b2' -> b1' = b2'
a1, a2: A
Hshape': shape (b1' ⧆ a1) = shape (b2' ⧆ a2)
Hlist: tolist b1' ++ ret list A a1 = tolist b2' ++ ret list A a2

a1 = a2
eapply list_app_inv_r2; eauto.
A, B, C: Type
b1, b2: Batch A B C
Hshape: shape b1 = shape b2
X: Type
b1', b2': Batch A B (B -> X)
Heq: tolist b1' = tolist b2' -> b1' = b2'
a1, a2: A
Hshape': shape (b1' ⧆ a1) = shape (b2' ⧆ a2)
Hlist: tolist b1' ++ ret list A a1 = tolist b2' ++ ret list A a2
H: a1 = a2

b1' ⧆ a1 = b2' ⧆ a2
A, B, C: Type
b1, b2: Batch A B C
Hshape: shape b1 = shape b2
X: Type
b1', b2': Batch A B (B -> X)
Heq: tolist b1' = tolist b2' -> b1' = b2'
a1, a2: A
Hshape': shape (b1' ⧆ a1) = shape (b2' ⧆ a2)
Hlist: tolist b1' ++ ret list A a1 = tolist b2' ++ ret list A a2
H: a1 = a2

b1' = b2'
A, B, C: Type
b1, b2: Batch A B C
Hshape: shape b1 = shape b2
X: Type
b1', b2': Batch A B (B -> X)
Heq: tolist b1' = tolist b2' -> b1' = b2'
a1, a2: A
Hshape': shape (b1' ⧆ a1) = shape (b2' ⧆ a2)
Hlist: tolist b1' ++ ret list A a1 = tolist b2' ++ ret list A a2
H: a1 = a2
H0: b1' = b2'
b1' ⧆ a1 = b2' ⧆ a2
A, B, C: Type
b1, b2: Batch A B C
Hshape: shape b1 = shape b2
X: Type
b1', b2': Batch A B (B -> X)
Heq: tolist b1' = tolist b2' -> b1' = b2'
a1, a2: A
Hshape': shape (b1' ⧆ a1) = shape (b2' ⧆ a2)
Hlist: tolist b1' ++ ret list A a1 = tolist b2' ++ ret list A a2
H: a1 = a2

b1' = b2'
A, B, C: Type
b1, b2: Batch A B C
Hshape: shape b1 = shape b2
X: Type
b1', b2': Batch A B (B -> X)
Heq: tolist b1' = tolist b2' -> b1' = b2'
a1, a2: A
Hshape': shape (b1' ⧆ a1) = shape (b2' ⧆ a2)
Hlist: tolist b1' ++ ret list A a1 = tolist b2' ++ ret list A a2
H: a1 = a2

tolist b1' = tolist b2'
A, B, C: Type
b1, b2: Batch A B C
Hshape: shape b1 = shape b2
X: Type
b1', b2': Batch A B (B -> X)
Heq: tolist b1' = tolist b2' -> b1' = b2'
a1, a2: A
Hshape': shape (b1' ⧆ a1) = shape (b2' ⧆ a2)
Hlist: tolist b1' ++ ret list A a1 = tolist b2' ++ ret list A a2
H: a1 = a2

tolist b1' ++ ret list A ?a1 = tolist b2' ++ ret list A ?a2
eauto.
A, B, C: Type
b1, b2: Batch A B C
Hshape: shape b1 = shape b2
X: Type
b1', b2': Batch A B (B -> X)
Heq: tolist b1' = tolist b2' -> b1' = b2'
a1, a2: A
Hshape': shape (b1' ⧆ a1) = shape (b2' ⧆ a2)
Hlist: tolist b1' ++ ret list A a1 = tolist b2' ++ ret list A a2
H: a1 = a2
H0: b1' = b2'

b1' ⧆ a1 = b2' ⧆ a2
A, B, C: Type
b1, b2: Batch A B C
Hshape: shape b1 = shape b2
X: Type
b2': Batch A B (B -> X)
Heq: tolist b2' = tolist b2' -> b2' = b2'
a2: A
Hshape': shape (b2' ⧆ a2) = shape (b2' ⧆ a2)
Hlist: tolist b2' ++ ret list A a2 = tolist b2' ++ ret list A a2

b2' ⧆ a2 = b2' ⧆ a2
reflexivity. Qed. End Batch_shapely. End deconstruction. (** * Theory About Batch *) (******************************************************************************) Section Batch_theory.

forall (A B C' C D : Type) (b : Batch A B (C -> D)) (f : C' -> C) (v : Vector (length_Batch b) B) (v' : Vector (length_Batch (map (Batch A B) (precompose f) b)) B), v ~~ v' -> forall c : C', Batch_make (map (Batch A B) (precompose f) b) v' c = Batch_make b v (f c)

forall (A B C' C D : Type) (b : Batch A B (C -> D)) (f : C' -> C) (v : Vector (length_Batch b) B) (v' : Vector (length_Batch (map (Batch A B) (precompose f) b)) B), v ~~ v' -> forall c : C', Batch_make (map (Batch A B) (precompose f) b) v' c = Batch_make b v (f c)
A, B, C', C, D: Type
b: Batch A B (C -> D)
f: C' -> C
v: Vector (length_Batch b) B
v': Vector (length_Batch (map (Batch A B) (precompose f) b)) B
Hsim: v ~~ v'
c: C'

Batch_make (map (Batch A B) (precompose f) b) v' c = Batch_make b v (f c)
A, B, C', C, D: Type
b: Batch A B (C -> D)
f: C' -> C
v: Vector (length_Batch b) B
v': Vector (length_Batch (map (Batch A B) (precompose f) b)) B
Hsim: v ~~ v'
c: C'

precompose f (Batch_make b (coerce eq_sym (batch_length_map (precompose f) b) in v')) c = Batch_make b v (f c)
A, B, C', C, D: Type
b: Batch A B (C -> D)
f: C' -> C
v: Vector (length_Batch b) B
v': Vector (length_Batch (map (Batch A B) (precompose f) b)) B
Hsim: v ~~ v'
c: C'

Batch_make b (coerce eq_sym (batch_length_map (fun g : C -> D => g ○ f) b) in v') (f c) = Batch_make b v (f c)
A, B, C', C, D: Type
b: Batch A B (C -> D)
f: C' -> C
v: Vector (length_Batch b) B
v': Vector (length_Batch (map (Batch A B) (precompose f) b)) B
Hsim: v ~~ v'
c: C'

coerce eq_sym (batch_length_map (fun g : C -> D => g ○ f) b) in v' = v
A, B, C', C, D: Type
b: Batch A B (C -> D)
f: C' -> C
v: Vector (length_Batch b) B
v': Vector (length_Batch (map (Batch A B) (precompose f) b)) B
Hsim: v ~~ v'
c: C'

coerce eq_sym (batch_length_map (fun g : C -> D => g ○ f) b) in v' ~~ v
A, B, C', C, D: Type
b: Batch A B (C -> D)
f: C' -> C
v: Vector (length_Batch b) B
v': Vector (length_Batch (map (Batch A B) (precompose f) b)) B
Hsim: v ~~ v'
c: C'

v' ~~ v
A, B, C', C, D: Type
b: Batch A B (C -> D)
f: C' -> C
v: Vector (length_Batch b) B
v': Vector (length_Batch (map (Batch A B) (precompose f) b)) B
Hsim: v ~~ v'
c: C'

proj1_sig v = proj1_sig v'
assumption. Qed.

forall (A B C' C D : Type) (b : Batch A B (C -> D)) (f : C' -> C) (v : Vector (length_Batch (map (Batch A B) (precompose f) b)) B) (c : C'), Batch_make (map (Batch A B) (precompose f) b) v c = Batch_make b (coerce eq_sym (batch_length_map (precompose f) b) in v) (f c)

forall (A B C' C D : Type) (b : Batch A B (C -> D)) (f : C' -> C) (v : Vector (length_Batch (map (Batch A B) (precompose f) b)) B) (c : C'), Batch_make (map (Batch A B) (precompose f) b) v c = Batch_make b (coerce eq_sym (batch_length_map (precompose f) b) in v) (f c)
A, B, C', C, D: Type
b: Batch A B (C -> D)
f: C' -> C
v: Vector (length_Batch (map (Batch A B) (precompose f) b)) B
c: C'

Batch_make (map (Batch A B) (precompose f) b) v c = Batch_make b (coerce eq_sym (batch_length_map (precompose f) b) in v) (f c)
A, B, C', C, D: Type
b: Batch A B (C -> D)
f: C' -> C
v: Vector (length_Batch (map (Batch A B) (precompose f) b)) B
c: C'

coerce eq_sym (batch_length_map (precompose f) b) in v ~~ v
apply Vector_coerce_sim_l. Qed.

forall (A B B' C : Type) (b : Batch A B' C) (f : B -> B') (v : Vector (length_Batch b) B) (v' : Vector (length_Batch (mapsnd_Batch f b)) B), v ~~ v' -> Batch_make b (map (Vector (length_Batch b)) f v) = Batch_make (mapsnd_Batch f b) v'

forall (A B B' C : Type) (b : Batch A B' C) (f : B -> B') (v : Vector (length_Batch b) B) (v' : Vector (length_Batch (mapsnd_Batch f b)) B), v ~~ v' -> Batch_make b (map (Vector (length_Batch b)) f v) = Batch_make (mapsnd_Batch f b) v'
A, B, B', C: Type
b: Batch A B' C
f: B -> B'
v: Vector (length_Batch b) B
v': Vector (length_Batch (mapsnd_Batch f b)) B
Hsim: v ~~ v'

Batch_make b (map (Vector (length_Batch b)) f v) = Batch_make (mapsnd_Batch f b) v'
A, B, B', C: Type
c: C
f: B -> B'
v: Vector (length_Batch (Done c)) B
v': Vector (length_Batch (mapsnd_Batch f (Done c))) B
Hsim: v ~~ v'

Batch_make (Done c) (map (Vector (length_Batch (Done c))) f v) = Batch_make (mapsnd_Batch f (Done c)) v'
A, B, B', C: Type
b: Batch A B' (B' -> C)
a: A
f: B -> B'
v: Vector (length_Batch (b ⧆ a)) B
v': Vector (length_Batch (mapsnd_Batch f (b ⧆ a))) B
Hsim: v ~~ v'
IHb: forall (v : Vector (length_Batch b) B) (v' : Vector (length_Batch (mapsnd_Batch f b)) B), v ~~ v' -> Batch_make b (map (Vector (length_Batch b)) f v) = Batch_make (mapsnd_Batch f b) v'
Batch_make (b ⧆ a) (map (Vector (length_Batch (b ⧆ a))) f v) = Batch_make (mapsnd_Batch f (b ⧆ a)) v'
A, B, B', C: Type
c: C
f: B -> B'
v: Vector (length_Batch (Done c)) B
v': Vector (length_Batch (mapsnd_Batch f (Done c))) B
Hsim: v ~~ v'

Batch_make (Done c) (map (Vector (length_Batch (Done c))) f v) = Batch_make (mapsnd_Batch f (Done c)) v'
A, B, B', C: Type
c: C
f: B -> B'
v, v': Vector 0 B
Hsim: v ~~ v'

Batch_make (Done c) (map (Vector (length_Batch (Done c))) f v) = Batch_make (mapsnd_Batch f (Done c)) v'
A, B, B', C: Type
c: C
f: B -> B'
v, v': Vector 0 B
Hsim: v ~~ v'

Batch_make (Done c) (map (Vector (length_Batch (Done c))) f vnil) = Batch_make (mapsnd_Batch f (Done c)) v'
A, B, B', C: Type
c: C
f: B -> B'
v, v': Vector 0 B
Hsim: v ~~ v'

Batch_make (Done c) (map (Vector (length_Batch (Done c))) f vnil) = Batch_make (mapsnd_Batch f (Done c)) vnil
reflexivity.
A, B, B', C: Type
b: Batch A B' (B' -> C)
a: A
f: B -> B'
v: Vector (length_Batch (b ⧆ a)) B
v': Vector (length_Batch (mapsnd_Batch f (b ⧆ a))) B
Hsim: v ~~ v'
IHb: forall (v : Vector (length_Batch b) B) (v' : Vector (length_Batch (mapsnd_Batch f b)) B), v ~~ v' -> Batch_make b (map (Vector (length_Batch b)) f v) = Batch_make (mapsnd_Batch f b) v'

Batch_make (b ⧆ a) (map (Vector (length_Batch (b ⧆ a))) f v) = Batch_make (mapsnd_Batch f (b ⧆ a)) v'
A, B, B', C: Type
b: Batch A B' (B' -> C)
a: A
f: B -> B'
v: Vector (S (length_Batch b)) B
v': Vector (S (length_Batch (map (Batch A B) (precompose f) (mapsnd_Batch f b)))) B
Hsim: v ~~ v'
IHb: forall (v : Vector (length_Batch b) B) (v' : Vector (length_Batch (mapsnd_Batch f b)) B), v ~~ v' -> Batch_make b (map (Vector (length_Batch b)) f v) = Batch_make (mapsnd_Batch f b) v'

Batch_make (b ⧆ a) (map (Vector (length_Batch (b ⧆ a))) f v) = Batch_make (mapsnd_Batch f (b ⧆ a)) v'
(* LHS *)
A, B, B', C: Type
b: Batch A B' (B' -> C)
a: A
f: B -> B'
v: Vector (S (length_Batch b)) B
v': Vector (S (length_Batch (map (Batch A B) (precompose f) (mapsnd_Batch f b)))) B
Hsim: v ~~ v'
IHb: forall (v : Vector (length_Batch b) B) (v' : Vector (length_Batch (mapsnd_Batch f b)) B), v ~~ v' -> Batch_make b (map (Vector (length_Batch b)) f v) = Batch_make (mapsnd_Batch f b) v'

Batch_make b (Vector_tl (map (Vector (length_Batch (b ⧆ a))) f v)) (Vector_hd (map (Vector (length_Batch (b ⧆ a))) f v)) = Batch_make (mapsnd_Batch f (b ⧆ a)) v'
A, B, B', C: Type
b: Batch A B' (B' -> C)
a: A
f: B -> B'
v: Vector (S (length_Batch b)) B
v': Vector (S (length_Batch (map (Batch A B) (precompose f) (mapsnd_Batch f b)))) B
Hsim: v ~~ v'
IHb: forall (v : Vector (length_Batch b) B) (v' : Vector (length_Batch (mapsnd_Batch f b)) B), v ~~ v' -> Batch_make b (map (Vector (length_Batch b)) f v) = Batch_make (mapsnd_Batch f b) v'

Batch_make b (Vector_tl (map (Vector (length_Batch (b ⧆ a))) f (vcons (length_Batch b) (Vector_hd v) (Vector_tl v)))) (Vector_hd (map (Vector (length_Batch (b ⧆ a))) f (vcons (length_Batch b) (Vector_hd v) (Vector_tl v)))) = Batch_make (mapsnd_Batch f (b ⧆ a)) v'
A, B, B', C: Type
b: Batch A B' (B' -> C)
a: A
f: B -> B'
v: Vector (S (length_Batch b)) B
v': Vector (S (length_Batch (map (Batch A B) (precompose f) (mapsnd_Batch f b)))) B
Hsim: v ~~ v'
IHb: forall (v : Vector (length_Batch b) B) (v' : Vector (length_Batch (mapsnd_Batch f b)) B), v ~~ v' -> Batch_make b (map (Vector (length_Batch b)) f v) = Batch_make (mapsnd_Batch f b) v'

Batch_make b (Vector_tl (vcons (length_Batch b) (f (Vector_hd v)) (map (Vector (length_Batch b)) f (Vector_tl v)))) (Vector_hd (vcons (length_Batch b) (f (Vector_hd v)) (map (Vector (length_Batch b)) f (Vector_tl v)))) = Batch_make (mapsnd_Batch f (b ⧆ a)) v'
A, B, B', C: Type
b: Batch A B' (B' -> C)
a: A
f: B -> B'
v: Vector (S (length_Batch b)) B
v': Vector (S (length_Batch (map (Batch A B) (precompose f) (mapsnd_Batch f b)))) B
Hsim: v ~~ v'
IHb: forall (v : Vector (length_Batch b) B) (v' : Vector (length_Batch (mapsnd_Batch f b)) B), v ~~ v' -> Batch_make b (map (Vector (length_Batch b)) f v) = Batch_make (mapsnd_Batch f b) v'

Batch_make b (map (Vector (length_Batch b)) f (Vector_tl v)) (Vector_hd (vcons (length_Batch b) (f (Vector_hd v)) (map (Vector (length_Batch b)) f (Vector_tl v)))) = Batch_make (mapsnd_Batch f (b ⧆ a)) v'
A, B, B', C: Type
b: Batch A B' (B' -> C)
a: A
f: B -> B'
v: Vector (S (length_Batch b)) B
v': Vector (S (length_Batch (map (Batch A B) (precompose f) (mapsnd_Batch f b)))) B
Hsim: v ~~ v'
IHb: forall (v : Vector (length_Batch b) B) (v' : Vector (length_Batch (mapsnd_Batch f b)) B), v ~~ v' -> Batch_make b (map (Vector (length_Batch b)) f v) = Batch_make (mapsnd_Batch f b) v'

Batch_make b (map (Vector (length_Batch b)) f (Vector_tl v)) (f (Vector_hd v)) = Batch_make (mapsnd_Batch f (b ⧆ a)) v'
(* RHS *)
A, B, B', C: Type
b: Batch A B' (B' -> C)
a: A
f: B -> B'
v: Vector (S (length_Batch b)) B
v': Vector (S (length_Batch (map (Batch A B) (precompose f) (mapsnd_Batch f b)))) B
Hsim: v ~~ v'
IHb: forall (v : Vector (length_Batch b) B) (v' : Vector (length_Batch (mapsnd_Batch f b)) B), v ~~ v' -> Batch_make b (map (Vector (length_Batch b)) f v) = Batch_make (mapsnd_Batch f b) v'

Batch_make b (map (Vector (length_Batch b)) f (Vector_tl v)) (f (Vector_hd v)) = Batch_make (mapsnd_Batch f (b ⧆ a)) v'
(* ^^^ fails for some reason *)
A, B, B', C: Type
b: Batch A B' (B' -> C)
a: A
f: B -> B'
v: Vector (S (length_Batch b)) B
v': Vector (S (length_Batch (map (Batch A B) (precompose f) (mapsnd_Batch f b)))) B
Hsim: v ~~ v'
IHb: forall (v : Vector (length_Batch b) B) (v' : Vector (length_Batch (mapsnd_Batch f b)) B), v ~~ v' -> Batch_make b (map (Vector (length_Batch b)) f v) = Batch_make (mapsnd_Batch f b) v'

Batch_make b (map (Vector (length_Batch b)) f (Vector_tl v)) (f (Vector_hd v)) = Batch_make (map (Batch A B) (precompose f) (mapsnd_Batch f b)) (Vector_tl v') (Vector_hd v')
A, B, B', C: Type
b: Batch A B' (B' -> C)
a: A
f: B -> B'
v: Vector (S (length_Batch b)) B
v': Vector (S (length_Batch (map (Batch A B) (precompose f) (mapsnd_Batch f b)))) B
Hsim: v ~~ v'
IHb: forall (v : Vector (length_Batch b) B) (v' : Vector (length_Batch (mapsnd_Batch f b)) B), v ~~ v' -> Batch_make b (map (Vector (length_Batch b)) f v) = Batch_make (mapsnd_Batch f b) v'

Batch_make b (map (Vector (length_Batch b)) f (Vector_tl v)) (f (Vector_hd v)) = Batch_make (mapsnd_Batch f b) (coerce eq_sym (batch_length_map (precompose f) (mapsnd_Batch f b)) in Vector_tl v') (f (Vector_hd v'))
A, B, B', C: Type
b: Batch A B' (B' -> C)
a: A
f: B -> B'
v: Vector (S (length_Batch b)) B
v': Vector (S (length_Batch (map (Batch A B) (precompose f) (mapsnd_Batch f b)))) B
Hsim: v ~~ v'
IHb: forall (v : Vector (length_Batch b) B) (v' : Vector (length_Batch (mapsnd_Batch f b)) B), v ~~ v' -> Batch_make b (map (Vector (length_Batch b)) f v) = Batch_make (mapsnd_Batch f b) v'

f (Vector_hd v) = f (Vector_hd v')
A, B, B', C: Type
b: Batch A B' (B' -> C)
a: A
f: B -> B'
v: Vector (S (length_Batch b)) B
v': Vector (S (length_Batch (map (Batch A B) (precompose f) (mapsnd_Batch f b)))) B
Hsim: v ~~ v'
IHb: forall (v : Vector (length_Batch b) B) (v' : Vector (length_Batch (mapsnd_Batch f b)) B), v ~~ v' -> Batch_make b (map (Vector (length_Batch b)) f v) = Batch_make (mapsnd_Batch f b) v'
cut: f (Vector_hd v) = f (Vector_hd v')
Batch_make b (map (Vector (length_Batch b)) f (Vector_tl v)) (f (Vector_hd v)) = Batch_make (mapsnd_Batch f b) (coerce eq_sym (batch_length_map (precompose f) (mapsnd_Batch f b)) in Vector_tl v') (f (Vector_hd v'))
A, B, B', C: Type
b: Batch A B' (B' -> C)
a: A
f: B -> B'
v: Vector (S (length_Batch b)) B
v': Vector (S (length_Batch (map (Batch A B) (precompose f) (mapsnd_Batch f b)))) B
Hsim: v ~~ v'
IHb: forall (v : Vector (length_Batch b) B) (v' : Vector (length_Batch (mapsnd_Batch f b)) B), v ~~ v' -> Batch_make b (map (Vector (length_Batch b)) f v) = Batch_make (mapsnd_Batch f b) v'

f (Vector_hd v) = f (Vector_hd v')
A, B, B', C: Type
b: Batch A B' (B' -> C)
a: A
f: B -> B'
v: Vector (S (length_Batch b)) B
v': Vector (S (length_Batch (map (Batch A B) (precompose f) (mapsnd_Batch f b)))) B
Hsim: v ~~ v'
IHb: forall (v : Vector (length_Batch b) B) (v' : Vector (length_Batch (mapsnd_Batch f b)) B), v ~~ v' -> Batch_make b (map (Vector (length_Batch b)) f v) = Batch_make (mapsnd_Batch f b) v'
H0: proj1_sig v = proj1_sig v'

f (Vector_hd v) = f (Vector_hd v')
A, B, B', C: Type
b: Batch A B' (B' -> C)
a: A
f: B -> B'
v: Vector (S (length_Batch b)) B
v': Vector (S (length_Batch (map (Batch A B) (precompose f) (mapsnd_Batch f b)))) B
Hsim: v ~~ v'
IHb: forall (v : Vector (length_Batch b) B) (v' : Vector (length_Batch (mapsnd_Batch f b)) B), v ~~ v' -> Batch_make b (map (Vector (length_Batch b)) f v) = Batch_make (mapsnd_Batch f b) v'
H0: proj1_sig v = proj1_sig v'

Vector_hd v = Vector_hd v'
apply (Vector_hd_sim Hsim).
A, B, B', C: Type
b: Batch A B' (B' -> C)
a: A
f: B -> B'
v: Vector (S (length_Batch b)) B
v': Vector (S (length_Batch (map (Batch A B) (precompose f) (mapsnd_Batch f b)))) B
Hsim: v ~~ v'
IHb: forall (v : Vector (length_Batch b) B) (v' : Vector (length_Batch (mapsnd_Batch f b)) B), v ~~ v' -> Batch_make b (map (Vector (length_Batch b)) f v) = Batch_make (mapsnd_Batch f b) v'
cut: f (Vector_hd v) = f (Vector_hd v')

Batch_make b (map (Vector (length_Batch b)) f (Vector_tl v)) (f (Vector_hd v)) = Batch_make (mapsnd_Batch f b) (coerce eq_sym (batch_length_map (precompose f) (mapsnd_Batch f b)) in Vector_tl v') (f (Vector_hd v'))
A, B, B', C: Type
b: Batch A B' (B' -> C)
a: A
f: B -> B'
v: Vector (S (length_Batch b)) B
v': Vector (S (length_Batch (map (Batch A B) (precompose f) (mapsnd_Batch f b)))) B
Hsim: v ~~ v'
IHb: forall (v : Vector (length_Batch b) B) (v' : Vector (length_Batch (mapsnd_Batch f b)) B), v ~~ v' -> Batch_make b (map (Vector (length_Batch b)) f v) = Batch_make (mapsnd_Batch f b) v'
cut: f (Vector_hd v) = f (Vector_hd v')

Batch_make b (map (Vector (length_Batch b)) f (Vector_tl v)) (f (Vector_hd v')) = Batch_make (mapsnd_Batch f b) (coerce eq_sym (batch_length_map (precompose f) (mapsnd_Batch f b)) in Vector_tl v') (f (Vector_hd v'))
A, B, B', C: Type
b: Batch A B' (B' -> C)
a: A
f: B -> B'
v: Vector (S (length_Batch b)) B
v': Vector (S (length_Batch (map (Batch A B) (precompose f) (mapsnd_Batch f b)))) B
Hsim: v ~~ v'
IHb: forall v' : Vector (length_Batch (mapsnd_Batch f b)) B, Vector_tl v ~~ v' -> Batch_make b (map (Vector (length_Batch b)) f (Vector_tl v)) = Batch_make (mapsnd_Batch f b) v'
cut: f (Vector_hd v) = f (Vector_hd v')

Batch_make b (map (Vector (length_Batch b)) f (Vector_tl v)) (f (Vector_hd v')) = Batch_make (mapsnd_Batch f b) (coerce eq_sym (batch_length_map (precompose f) (mapsnd_Batch f b)) in Vector_tl v') (f (Vector_hd v'))
A, B, B', C: Type
b: Batch A B' (B' -> C)
a: A
f: B -> B'
v: Vector (S (length_Batch b)) B
v': Vector (S (length_Batch (map (Batch A B) (precompose f) (mapsnd_Batch f b)))) B
Hsim: v ~~ v'
IHb: Vector_tl v ~~ coerce eq_sym (batch_length_map (precompose f) (mapsnd_Batch f b)) in Vector_tl v' -> Batch_make b (map (Vector (length_Batch b)) f (Vector_tl v)) = Batch_make (mapsnd_Batch f b) (coerce eq_sym (batch_length_map (precompose f) (mapsnd_Batch f b)) in Vector_tl v')
cut: f (Vector_hd v) = f (Vector_hd v')

Batch_make b (map (Vector (length_Batch b)) f (Vector_tl v)) (f (Vector_hd v')) = Batch_make (mapsnd_Batch f b) (coerce eq_sym (batch_length_map (precompose f) (mapsnd_Batch f b)) in Vector_tl v') (f (Vector_hd v'))
A, B, B', C: Type
b: Batch A B' (B' -> C)
a: A
f: B -> B'
v: Vector (S (length_Batch b)) B
v': Vector (S (length_Batch (map (Batch A B) (precompose f) (mapsnd_Batch f b)))) B
Hsim: v ~~ v'
IHb: Vector_tl v ~~ coerce eq_sym (batch_length_map (precompose f) (mapsnd_Batch f b)) in Vector_tl v' -> Batch_make b (map (Vector (length_Batch b)) f (Vector_tl v)) = Batch_make (mapsnd_Batch f b) (coerce eq_sym (batch_length_map (precompose f) (mapsnd_Batch f b)) in Vector_tl v')
cut: f (Vector_hd v) = f (Vector_hd v')

Batch_make (mapsnd_Batch f b) (coerce eq_sym (batch_length_map (precompose f) (mapsnd_Batch f b)) in Vector_tl v') (f (Vector_hd v')) = Batch_make (mapsnd_Batch f b) (coerce eq_sym (batch_length_map (precompose f) (mapsnd_Batch f b)) in Vector_tl v') (f (Vector_hd v'))
A, B, B', C: Type
b: Batch A B' (B' -> C)
a: A
f: B -> B'
v: Vector (S (length_Batch b)) B
v': Vector (S (length_Batch (map (Batch A B) (precompose f) (mapsnd_Batch f b)))) B
Hsim: v ~~ v'
IHb: Vector_tl v ~~ coerce eq_sym (batch_length_map (precompose f) (mapsnd_Batch f b)) in Vector_tl v' -> Batch_make b (map (Vector (length_Batch b)) f (Vector_tl v)) = Batch_make (mapsnd_Batch f b) (coerce eq_sym (batch_length_map (precompose f) (mapsnd_Batch f b)) in Vector_tl v')
cut: f (Vector_hd v) = f (Vector_hd v')
Vector_tl v ~~ coerce eq_sym (batch_length_map (precompose f) (mapsnd_Batch f b)) in Vector_tl v'
A, B, B', C: Type
b: Batch A B' (B' -> C)
a: A
f: B -> B'
v: Vector (S (length_Batch b)) B
v': Vector (S (length_Batch (map (Batch A B) (precompose f) (mapsnd_Batch f b)))) B
Hsim: v ~~ v'
IHb: Vector_tl v ~~ coerce eq_sym (batch_length_map (precompose f) (mapsnd_Batch f b)) in Vector_tl v' -> Batch_make b (map (Vector (length_Batch b)) f (Vector_tl v)) = Batch_make (mapsnd_Batch f b) (coerce eq_sym (batch_length_map (precompose f) (mapsnd_Batch f b)) in Vector_tl v')
cut: f (Vector_hd v) = f (Vector_hd v')

Batch_make (mapsnd_Batch f b) (coerce eq_sym (batch_length_map (precompose f) (mapsnd_Batch f b)) in Vector_tl v') (f (Vector_hd v')) = Batch_make (mapsnd_Batch f b) (coerce eq_sym (batch_length_map (precompose f) (mapsnd_Batch f b)) in Vector_tl v') (f (Vector_hd v'))
reflexivity.
A, B, B', C: Type
b: Batch A B' (B' -> C)
a: A
f: B -> B'
v: Vector (S (length_Batch b)) B
v': Vector (S (length_Batch (map (Batch A B) (precompose f) (mapsnd_Batch f b)))) B
Hsim: v ~~ v'
IHb: Vector_tl v ~~ coerce eq_sym (batch_length_map (precompose f) (mapsnd_Batch f b)) in Vector_tl v' -> Batch_make b (map (Vector (length_Batch b)) f (Vector_tl v)) = Batch_make (mapsnd_Batch f b) (coerce eq_sym (batch_length_map (precompose f) (mapsnd_Batch f b)) in Vector_tl v')
cut: f (Vector_hd v) = f (Vector_hd v')

Vector_tl v ~~ coerce eq_sym (batch_length_map (precompose f) (mapsnd_Batch f b)) in Vector_tl v'
A, B, B', C: Type
b: Batch A B' (B' -> C)
a: A
f: B -> B'
v: Vector (S (length_Batch b)) B
v': Vector (S (length_Batch (map (Batch A B) (precompose f) (mapsnd_Batch f b)))) B
Hsim: v ~~ v'
IHb: Vector_tl v ~~ coerce eq_sym (batch_length_map (precompose f) (mapsnd_Batch f b)) in Vector_tl v' -> Batch_make b (map (Vector (length_Batch b)) f (Vector_tl v)) = Batch_make (mapsnd_Batch f b) (coerce eq_sym (batch_length_map (precompose f) (mapsnd_Batch f b)) in Vector_tl v')
cut: f (Vector_hd v) = f (Vector_hd v')

Vector_tl v ~~ Vector_tl v'
A, B, B', C: Type
b: Batch A B' (B' -> C)
a: A
f: B -> B'
v: Vector (S (length_Batch b)) B
v': Vector (S (length_Batch (map (Batch A B) (precompose f) (mapsnd_Batch f b)))) B
Hsim: v ~~ v'
IHb: Vector_tl v ~~ coerce eq_sym (batch_length_map (precompose f) (mapsnd_Batch f b)) in Vector_tl v' -> Batch_make b (map (Vector (length_Batch b)) f (Vector_tl v)) = Batch_make (mapsnd_Batch f b) (coerce eq_sym (batch_length_map (precompose f) (mapsnd_Batch f b)) in Vector_tl v')
cut: f (Vector_hd v) = f (Vector_hd v')

v ~~ v'
assumption. Qed.

forall (n m : nat) (Heq : n = m) (A B : Type) (f : A -> B) (v : Vector n A), coerce Heq in map (Vector n) f v = map (Vector m) f (coerce Heq in v)

forall (n m : nat) (Heq : n = m) (A B : Type) (f : A -> B) (v : Vector n A), coerce Heq in map (Vector n) f v = map (Vector m) f (coerce Heq in v)
n, m: nat
Heq: n = m
A, B: Type
f: A -> B
v: Vector n A

coerce Heq in map (Vector n) f v = map (Vector m) f (coerce Heq in v)
n, m: nat
Heq: n = m
A, B: Type
f: A -> B
v: Vector n A

coerce Heq in map (Vector n) f v ~~ map (Vector m) f (coerce Heq in v)
n, m: nat
Heq: n = m
A, B: Type
f: A -> B
v: Vector n A

coerce Heq in map (Vector n) f v ~~ map (Vector n) f v
n, m: nat
Heq: n = m
A, B: Type
f: A -> B
v: Vector n A
map (Vector n) f v ~~ map (Vector m) f (coerce Heq in v)
n, m: nat
Heq: n = m
A, B: Type
f: A -> B
v: Vector n A

coerce Heq in map (Vector n) f v ~~ map (Vector n) f v
n, m: nat
Heq: n = m
A, B: Type
f: A -> B
v: Vector n A

map (Vector n) f v ~~ coerce Heq in map (Vector n) f v
apply Vector_coerce_sim_r.
n, m: nat
Heq: n = m
A, B: Type
f: A -> B
v: Vector n A

map (Vector n) f v ~~ map (Vector m) f (coerce Heq in v)
apply map_coerce_Vector. Qed.

forall (A B B' C : Type) (b : Batch A B' C) (f : B -> B') (v : Vector (length_Batch (mapsnd_Batch f b)) B), Batch_make (mapsnd_Batch f b) v = Batch_make b (coerce eq_sym (batch_length_mapsnd f b) in map (Vector (length_Batch (mapsnd_Batch f b))) f v)

forall (A B B' C : Type) (b : Batch A B' C) (f : B -> B') (v : Vector (length_Batch (mapsnd_Batch f b)) B), Batch_make (mapsnd_Batch f b) v = Batch_make b (coerce eq_sym (batch_length_mapsnd f b) in map (Vector (length_Batch (mapsnd_Batch f b))) f v)
A, B, B', C: Type
b: Batch A B' C
f: B -> B'
v: Vector (length_Batch (mapsnd_Batch f b)) B

Batch_make (mapsnd_Batch f b) v = Batch_make b (coerce eq_sym (batch_length_mapsnd f b) in map (Vector (length_Batch (mapsnd_Batch f b))) f v)
A, B, B', C: Type
b: Batch A B' C
f: B -> B'
v: Vector (length_Batch (mapsnd_Batch f b)) B

Batch_make b (coerce eq_sym (batch_length_mapsnd f b) in map (Vector (length_Batch (mapsnd_Batch f b))) f v) = Batch_make (mapsnd_Batch f b) v
A, B, B', C: Type
b: Batch A B' C
f: B -> B'
v: Vector (length_Batch (mapsnd_Batch f b)) B

Batch_make b (map (Vector (length_Batch b)) f (coerce eq_sym (batch_length_mapsnd f b) in v)) = Batch_make (mapsnd_Batch f b) v
A, B, B', C: Type
b: Batch A B' C
f: B -> B'
v: Vector (length_Batch (mapsnd_Batch f b)) B

coerce eq_sym (batch_length_mapsnd f b) in v ~~ v
apply Vector_coerce_sim_l. Qed. End Batch_theory. (** ** Misc *) (******************************************************************************) Section spec.

forall (G : Type -> Type) (Map_G : Map G) (Pure_G : Pure G) (Mult_G : Mult G), Applicative G -> forall (A B C : Type) (b : Batch A B C) (x : G B) (A' : Type) (v : Vector (length_Batch b) A'), runBatch (const x) b = runBatch (const x) (Batch_replace_contents b v)

forall (G : Type -> Type) (Map_G : Map G) (Pure_G : Pure G) (Mult_G : Mult G), Applicative G -> forall (A B C : Type) (b : Batch A B C) (x : G B) (A' : Type) (v : Vector (length_Batch b) A'), runBatch (const x) b = runBatch (const x) (Batch_replace_contents b v)
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B, C: Type
b: Batch A B C
x: G B
A': Type
v: Vector (length_Batch b) A'

runBatch (const x) b = runBatch (const x) (Batch_replace_contents b v)
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B, C: Type
c: C
x: G B
A': Type
v: Vector (length_Batch (Done c)) A'

runBatch (const x) (Done c) = runBatch (const x) (Batch_replace_contents (Done c) v)
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B, C: Type
b: Batch A B (B -> C)
a: A
x: G B
A': Type
v: Vector (length_Batch (b ⧆ a)) A'
IHb: forall v : Vector (length_Batch b) A', runBatch (const x) b = runBatch (const x) (Batch_replace_contents b v)
runBatch (const x) (b ⧆ a) = runBatch (const x) (Batch_replace_contents (b ⧆ a) v)
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B, C: Type
c: C
x: G B
A': Type
v: Vector (length_Batch (Done c)) A'

runBatch (const x) (Done c) = runBatch (const x) (Batch_replace_contents (Done c) v)
reflexivity.
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B, C: Type
b: Batch A B (B -> C)
a: A
x: G B
A': Type
v: Vector (length_Batch (b ⧆ a)) A'
IHb: forall v : Vector (length_Batch b) A', runBatch (const x) b = runBatch (const x) (Batch_replace_contents b v)

runBatch (const x) (b ⧆ a) = runBatch (const x) (Batch_replace_contents (b ⧆ a) v)
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B, C: Type
b: Batch A B (B -> C)
a: A
x: G B
A': Type
v: Vector (length_Batch (b ⧆ a)) A'
IHb: forall v : Vector (length_Batch b) A', runBatch (const x) b = runBatch (const x) (Batch_replace_contents b v)

runBatch (const x) b <⋆> const x a = runBatch (const x) (Batch_replace_contents b (Vector_tl v)) <⋆> const x (Vector_hd v)
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B, C: Type
b: Batch A B (B -> C)
a: A
x: G B
A': Type
v: Vector (length_Batch (b ⧆ a)) A'
IHb: forall v : Vector (length_Batch b) A', runBatch (const x) b = runBatch (const x) (Batch_replace_contents b v)

runBatch (const x) b = runBatch (const x) (Batch_replace_contents b (Vector_tl v))
apply IHb. Qed.

forall (A B C : Type) (b1 b2 : Batch A B C), b1 = b2 <-> Batch_make b1 ~!~ Batch_make b2 /\ Batch_contents b1 ~~ Batch_contents b2

forall (A B C : Type) (b1 b2 : Batch A B C), b1 = b2 <-> Batch_make b1 ~!~ Batch_make b2 /\ Batch_contents b1 ~~ Batch_contents b2
A, B, C: Type
b1, b2: Batch A B C

b1 = b2 <-> Batch_make b1 ~!~ Batch_make b2 /\ Batch_contents b1 ~~ Batch_contents b2
A, B, C: Type
b1, b2: Batch A B C

b1 = b2 -> Batch_make b1 ~!~ Batch_make b2 /\ Batch_contents b1 ~~ Batch_contents b2
A, B, C: Type
b1, b2: Batch A B C
Batch_make b1 ~!~ Batch_make b2 /\ Batch_contents b1 ~~ Batch_contents b2 -> b1 = b2
A, B, C: Type
b1, b2: Batch A B C

b1 = b2 -> Batch_make b1 ~!~ Batch_make b2 /\ Batch_contents b1 ~~ Batch_contents b2
A, B, C: Type
b2: Batch A B C

Batch_make b2 ~!~ Batch_make b2 /\ Batch_contents b2 ~~ Batch_contents b2
A, B, C: Type
b2: Batch A B C

Batch_make b2 ~!~ Batch_make b2
A, B, C: Type
b2: Batch A B C
Batch_contents b2 ~~ Batch_contents b2
A, B, C: Type
b2: Batch A B C

Batch_make b2 ~!~ Batch_make b2
A, B, C: Type
b2: Batch A B C

length_Batch b2 = length_Batch b2 /\ (forall v1 v2 : Vector (length_Batch b2) B, v1 ~~ v2 -> Batch_make b2 v1 = Batch_make b2 v2)
A, B, C: Type
b2: Batch A B C

forall v1 v2 : Vector (length_Batch b2) B, v1 ~~ v2 -> Batch_make b2 v1 = Batch_make b2 v2
A, B, C: Type
b2: Batch A B C
v1, v2: Vector (length_Batch b2) B
Hsim: v1 ~~ v2

Batch_make b2 v1 = Batch_make b2 v2
auto using Batch_make_sim1.
A, B, C: Type
b1, b2: Batch A B C

Batch_make b1 ~!~ Batch_make b2 /\ Batch_contents b1 ~~ Batch_contents b2 -> b1 = b2
A, B, C: Type
b1, b2: Batch A B C
Hmake: Batch_make b1 ~!~ Batch_make b2
Hcontents: Batch_contents b1 ~~ Batch_contents b2

b1 = b2
A, B, C: Type
b1, b2: Batch A B C
Hmake: Batch_make b1 ~!~ Batch_make b2
Hcontents: Batch_contents b1 ~~ Batch_contents b2

Batch_replace_contents b1 (Batch_contents b1) = b2
A, B, C: Type
b1, b2: Batch A B C
Hmake: Batch_make b1 ~!~ Batch_make b2
Hcontents: Batch_contents b1 ~~ Batch_contents b2

Batch_replace_contents b1 (Batch_contents b1) = Batch_replace_contents b2 (Batch_contents b2)
A, B, C: Type
b1, b2: Batch A B C
Hmake: Batch_make b1 ~!~ Batch_make b2
Hcontents: Batch_contents b1 ~~ Batch_contents b2

shape b1 = shape b2
A, B, C: Type
b1, b2: Batch A B C
Hmake: Batch_make b1 ~!~ Batch_make b2
Hcontents: Batch_contents b1 ~~ Batch_contents b2
Batch_contents b1 ~~ Batch_contents b2
A, B, C: Type
b1, b2: Batch A B C
Hmake: Batch_make b1 ~!~ Batch_make b2
Hcontents: Batch_contents b1 ~~ Batch_contents b2

Batch_contents b1 ~~ Batch_contents b2
assumption. Qed. End spec. (** * Representation theorems *) (******************************************************************************)
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G

forall (A B C : Type) (b : Batch A B C) (f : A -> G B), map G (Batch_make b) (traverse f (Batch_contents b)) = forwards (runBatch (mkBackwards ∘ f) b)
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G

forall (A B C : Type) (b : Batch A B C) (f : A -> G B), map G (Batch_make b) (traverse f (Batch_contents b)) = forwards (runBatch (mkBackwards ∘ f) b)
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B, C: Type
b: Batch A B C
f: A -> G B

map G (Batch_make b) (traverse f (Batch_contents b)) = forwards (runBatch (mkBackwards ∘ f) b)
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B, C: Type
c: C
f: A -> G B

map G (Batch_make (Done c)) (traverse f (Batch_contents (Done c))) = forwards (runBatch (mkBackwards ∘ f) (Done c))
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B, C: Type
b: Batch A B (B -> C)
a: A
f: A -> G B
IHb: map G (Batch_make b) (traverse f (Batch_contents b)) = forwards (runBatch (mkBackwards ∘ f) b)
map G (Batch_make (b ⧆ a)) (traverse f (Batch_contents (b ⧆ a))) = forwards (runBatch (mkBackwards ∘ f) (b ⧆ a))
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B, C: Type
c: C
f: A -> G B

map G (Batch_make (Done c)) (traverse f (Batch_contents (Done c))) = forwards (runBatch (mkBackwards ∘ f) (Done c))
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B, C: Type
c: C
f: A -> G B

map G (fun _ : Vector 0 B => c) (pure G (exist (fun l : list B => length l = 0) nil eq_refl)) = pure G c
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B, C: Type
c: C
f: A -> G B

pure G c = pure G c
reflexivity.
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B, C: Type
b: Batch A B (B -> C)
a: A
f: A -> G B
IHb: map G (Batch_make b) (traverse f (Batch_contents b)) = forwards (runBatch (mkBackwards ∘ f) b)

map G (Batch_make (b ⧆ a)) (traverse f (Batch_contents (b ⧆ a))) = forwards (runBatch (mkBackwards ∘ f) (b ⧆ a))
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B, C: Type
b: Batch A B (B -> C)
a: A
f: A -> G B
IHb: map G (Batch_make b) (traverse f (Batch_contents b)) = forwards (runBatch (mkBackwards ∘ f) b)

map G (Batch_make (b ⧆ a)) (traverse f (vcons (length_Batch b) a (Batch_contents b))) = forwards (runBatch (mkBackwards ∘ f) (b ⧆ a))
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B, C: Type
b: Batch A B (B -> C)
a: A
f: A -> G B
IHb: map G (Batch_make b) (traverse f (Batch_contents b)) = forwards (runBatch (mkBackwards ∘ f) b)

map G (Batch_make (b ⧆ a)) (traverse f (vcons (length_Batch b) a (Batch_contents b))) = forwards (runBatch (mkBackwards ∘ f) (b ⧆ a))
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B, C: Type
b: Batch A B (B -> C)
a: A
f: A -> G B
IHb: map G (Batch_make b) (traverse f (Batch_contents b)) = forwards (runBatch (mkBackwards ∘ f) b)

map G (Batch_make (b ⧆ a)) (pure G (vcons (length_Batch b)) <⋆> f a <⋆> traverse f (Batch_contents b)) = forwards (runBatch (mkBackwards ∘ f) (b ⧆ a))
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B, C: Type
b: Batch A B (B -> C)
a: A
f: A -> G B
IHb: map G (Batch_make b) (traverse f (Batch_contents b)) = forwards (runBatch (mkBackwards ∘ f) b)

map G (Batch_make (b ⧆ a)) (pure G (vcons (length_Batch b)) <⋆> f a <⋆> traverse f (Batch_contents b)) = forwards (runBatch (mkBackwards ∘ f) b <⋆> (mkBackwards ∘ f) a)
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B, C: Type
b: Batch A B (B -> C)
a: A
f: A -> G B
IHb: map G (Batch_make b) (traverse f (Batch_contents b)) = forwards (runBatch (mkBackwards ∘ f) b)

map G (Batch_make (b ⧆ a)) (pure G (vcons (length_Batch b)) <⋆> f a <⋆> traverse f (Batch_contents b)) = map G evalAt (forwards ((mkBackwards ∘ f) a)) <⋆> forwards (runBatch (mkBackwards ∘ f) b)
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B, C: Type
b: Batch A B (B -> C)
a: A
f: A -> G B
IHb: map G (Batch_make b) (traverse f (Batch_contents b)) = forwards (runBatch (mkBackwards ∘ f) b)

map G (compose (Batch_make (b ⧆ a))) (pure G (vcons (length_Batch b)) <⋆> f a) <⋆> traverse f (Batch_contents b) = map G evalAt (forwards ((mkBackwards ∘ f) a)) <⋆> forwards (runBatch (mkBackwards ∘ f) b)
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B, C: Type
b: Batch A B (B -> C)
a: A
f: A -> G B
IHb: map G (Batch_make b) (traverse f (Batch_contents b)) = forwards (runBatch (mkBackwards ∘ f) b)

map G (compose (compose (Batch_make (b ⧆ a)))) (pure G (vcons (length_Batch b))) <⋆> f a <⋆> traverse f (Batch_contents b) = map G evalAt (forwards ((mkBackwards ∘ f) a)) <⋆> forwards (runBatch (mkBackwards ∘ f) b)
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B, C: Type
b: Batch A B (B -> C)
a: A
f: A -> G B
IHb: map G (Batch_make b) (traverse f (Batch_contents b)) = forwards (runBatch (mkBackwards ∘ f) b)

pure G (compose (Batch_make (b ⧆ a)) ∘ vcons (length_Batch b)) <⋆> f a <⋆> traverse f (Batch_contents b) = map G evalAt (forwards ((mkBackwards ∘ f) a)) <⋆> forwards (runBatch (mkBackwards ∘ f) b)
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B, C: Type
b: Batch A B (B -> C)
a: A
f: A -> G B
IHb: map G (Batch_make b) (traverse f (Batch_contents b)) = forwards (runBatch (mkBackwards ∘ f) b)

pure G (compose (Batch_make (b ⧆ a)) ∘ vcons (length_Batch b)) <⋆> f a <⋆> traverse f (Batch_contents b) = map G evalAt (forwards ((mkBackwards ∘ f) a)) <⋆> map G (Batch_make b) (traverse f (Batch_contents b))
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B, C: Type
b: Batch A B (B -> C)
a: A
f: A -> G B
IHb: map G (Batch_make b) (traverse f (Batch_contents b)) = forwards (runBatch (mkBackwards ∘ f) b)

pure G (compose (Batch_make (b ⧆ a)) ∘ vcons (length_Batch b)) <⋆> f a <⋆> traverse f (Batch_contents b) = pure G evalAt <⋆> forwards ((mkBackwards ∘ f) a) <⋆> map G (Batch_make b) (traverse f (Batch_contents b))
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B, C: Type
b: Batch A B (B -> C)
a: A
f: A -> G B
IHb: map G (Batch_make b) (traverse f (Batch_contents b)) = forwards (runBatch (mkBackwards ∘ f) b)

pure G (compose (Batch_make (b ⧆ a)) ∘ vcons (length_Batch b)) <⋆> f a <⋆> traverse f (Batch_contents b) = map G (precompose (Batch_make b)) (pure G evalAt <⋆> forwards ((mkBackwards ∘ f) a)) <⋆> traverse f (Batch_contents b)
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B, C: Type
b: Batch A B (B -> C)
a: A
f: A -> G B
IHb: map G (Batch_make b) (traverse f (Batch_contents b)) = forwards (runBatch (mkBackwards ∘ f) b)

pure G (compose (Batch_make (b ⧆ a)) ∘ vcons (length_Batch b)) <⋆> f a <⋆> traverse f (Batch_contents b) = map G (compose (precompose (Batch_make b))) (pure G evalAt) <⋆> forwards ((mkBackwards ∘ f) a) <⋆> traverse f (Batch_contents b)
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B, C: Type
b: Batch A B (B -> C)
a: A
f: A -> G B
IHb: map G (Batch_make b) (traverse f (Batch_contents b)) = forwards (runBatch (mkBackwards ∘ f) b)

pure G (compose (Batch_make (b ⧆ a)) ∘ vcons (length_Batch b)) <⋆> f a <⋆> traverse f (Batch_contents b) = pure G (precompose (Batch_make b) ∘ evalAt) <⋆> forwards ((mkBackwards ∘ f) a) <⋆> traverse f (Batch_contents b)
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B, C: Type
b: Batch A B (B -> C)
a: A
f: A -> G B
IHb: map G (Batch_make b) (traverse f (Batch_contents b)) = forwards (runBatch (mkBackwards ∘ f) b)

pure G (compose (Batch_make (b ⧆ a)) ∘ vcons (length_Batch b)) <⋆> f a = pure G (precompose (Batch_make b) ∘ evalAt) <⋆> forwards ((mkBackwards ∘ f) a)
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B, C: Type
b: Batch A B (B -> C)
a: A
f: A -> G B
IHb: map G (Batch_make b) (traverse f (Batch_contents b)) = forwards (runBatch (mkBackwards ∘ f) b)

pure G (compose (Batch_make (b ⧆ a)) ∘ vcons (length_Batch b)) = pure G (precompose (Batch_make b) ∘ evalAt)
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B, C: Type
b: Batch A B (B -> C)
a: A
f: A -> G B
IHb: map G (Batch_make b) (traverse f (Batch_contents b)) = forwards (runBatch (mkBackwards ∘ f) b)

compose (Batch_make (b ⧆ a)) ∘ vcons (length_Batch b) = precompose (Batch_make b) ∘ evalAt
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B, C: Type
b: Batch A B (B -> C)
a: A
f: A -> G B
IHb: map G (Batch_make b) (traverse f (Batch_contents b)) = forwards (runBatch (mkBackwards ∘ f) b)
b': B
v': Vector (length_Batch b) B

(compose (Batch_make (b ⧆ a)) ∘ vcons (length_Batch b)) b' v' = (precompose (Batch_make b) ∘ evalAt) b' v'
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B, C: Type
b: Batch A B (B -> C)
a: A
f: A -> G B
IHb: map G (Batch_make b) (traverse f (Batch_contents b)) = forwards (runBatch (mkBackwards ∘ f) b)
b': B
v': Vector (length_Batch b) B

Batch_make (b ⧆ a) (vcons (length_Batch b) b' v') = Batch_make b v' b'
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B, C: Type
b: Batch A B (B -> C)
a: A
f: A -> G B
IHb: map G (Batch_make b) (traverse f (Batch_contents b)) = forwards (runBatch (mkBackwards ∘ f) b)
b': B
v': Vector (length_Batch b) B

Batch_make b (Vector_tl (vcons (length_Batch b) b' v')) (Vector_hd (vcons (length_Batch b) b' v')) = Batch_make b v' b'
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B, C: Type
b: Batch A B (B -> C)
a: A
f: A -> G B
IHb: map G (Batch_make b) (traverse f (Batch_contents b)) = forwards (runBatch (mkBackwards ∘ f) b)
b': B
v': Vector (length_Batch b) B

Batch_make b v' (Vector_hd (vcons (length_Batch b) b' v')) = Batch_make b v' b'
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B, C: Type
b: Batch A B (B -> C)
a: A
f: A -> G B
IHb: map G (Batch_make b) (traverse f (Batch_contents b)) = forwards (runBatch (mkBackwards ∘ f) b)
b': B
v': Vector (length_Batch b) B

Batch_make b v' b' = Batch_make b v' b'
reflexivity. Qed.
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G

forall (A B C : Type) (b : Batch A B C) (f : A -> G B), runBatch f b = map G (Batch_make b) (forwards (traverse (mkBackwards ∘ f) (Batch_contents b)))
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G

forall (A B C : Type) (b : Batch A B C) (f : A -> G B), runBatch f b = map G (Batch_make b) (forwards (traverse (mkBackwards ∘ f) (Batch_contents b)))
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B, C: Type
b: Batch A B C
f: A -> G B

runBatch f b = map G (Batch_make b) (forwards (traverse (mkBackwards ∘ f) (Batch_contents b)))
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B, C: Type
b: Batch A B C
f: A -> G B

map G (Batch_make b) (forwards (traverse (mkBackwards ∘ f) (Batch_contents b))) = runBatch f b
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B, C: Type
b: Batch A B C
f: A -> G B

forwards (map (Backwards G) (Batch_make b) (traverse (mkBackwards ∘ f) (Batch_contents b))) = runBatch f b
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B, C: Type
b: Batch A B C
f: A -> G B

forwards (forwards (runBatch (mkBackwards ∘ (mkBackwards ∘ f)) b)) = runBatch f b
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B, C: Type
b: Batch A B C
f: A -> G B

forwards (forwards ((map (Backwards (Backwards G)) extract_Batch ∘ traverse (mkBackwards ∘ (mkBackwards ∘ f))) b)) = runBatch f b
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B, C: Type
b: Batch A B C
f: A -> G B

forwards (forwards ((map (Backwards (Backwards G)) extract_Batch ∘ traverse (mkBackwards ∘ (mkBackwards ∘ f))) b)) = (map G extract_Batch ∘ traverse f) b
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B, C: Type
b: Batch A B C
f: A -> G B

map G extract_Batch (forwards (forwards (traverse (mkBackwards ∘ (mkBackwards ∘ f)) b))) = (map G extract_Batch ∘ traverse f) b
G: Type -> Type
Map_G: Map G
Pure_G: Pure G
Mult_G: Mult G
H: Applicative G
A, B, C: Type
b: Batch A B C
f: A -> G B

map G extract_Batch (traverse f b) = (map G extract_Batch ∘ traverse f) b
reflexivity. Qed. (** * Annotating <<Batch>> with Proofs of Occurrence *) (******************************************************************************) Require Import ContainerFunctor. Import ContainerFunctor.Notations. Import Applicative.Notations. Import Functors.Early.Subset. Import Subset.Notations. Section annotate_Batch_elements. (** ** Lemmas regarding <<tosubset>> *) (******************************************************************************)
A, B, C: Type

forall (a' : A) (rest : Batch A B (B -> C)) (a : A), tosubset rest a -> tosubset (rest ⧆ a') a
A, B, C: Type

forall (a' : A) (rest : Batch A B (B -> C)) (a : A), tosubset rest a -> tosubset (rest ⧆ a') a
A, B, C: Type
a': A
rest: Batch A B (B -> C)
a: A

tosubset rest a -> tosubset (rest ⧆ a') a
A, B, C: Type
a': A
rest: Batch A B (B -> C)
a: A

tosubset rest a -> (tosubset rest ∪ {{a'}}) a
A, B, C: Type
a': A
rest: Batch A B (B -> C)
a: A

tosubset rest a -> tosubset rest a \/ a' = a
tauto. Defined.
A, B, C: Type

forall (rest : Batch A B (B -> C)) (a : A), tosubset (rest ⧆ a) a
A, B, C: Type

forall (rest : Batch A B (B -> C)) (a : A), tosubset (rest ⧆ a) a
A, B, C: Type
rest: Batch A B (B -> C)
a: A

tosubset (rest ⧆ a) a
A, B, C: Type
rest: Batch A B (B -> C)
a: A

(tosubset rest ∪ {{a}}) a
A, B, C: Type
rest: Batch A B (B -> C)
a: A

tosubset rest a \/ a = a
tauto. Qed.
A, B, C: Type

forall (a' : A) (rest : Batch A B (B -> C)) (a : A), a ∈ rest -> a ∈ (rest ⧆ a')
A, B, C: Type

forall (a' : A) (rest : Batch A B (B -> C)) (a : A), a ∈ rest -> a ∈ (rest ⧆ a')
A, B, C: Type
a': A
rest: Batch A B (B -> C)
a: A

a ∈ rest -> a ∈ (rest ⧆ a')
A, B, C: Type
a': A
rest: Batch A B (B -> C)
a: A

a ∈ rest -> a ∈ rest \/ a = a'
tauto. Defined.
A, B, C: Type

forall (rest : Batch A B (B -> C)) (a : A), a ∈ (rest ⧆ a)
A, B, C: Type

forall (rest : Batch A B (B -> C)) (a : A), a ∈ (rest ⧆ a)
A, B, C: Type
rest: Batch A B (B -> C)
a: A

a ∈ (rest ⧆ a)
A, B, C: Type
rest: Batch A B (B -> C)
a: A

a ∈ rest \/ a = a
tauto. Qed. (** ** Annotation Operation *) (******************************************************************************) Definition sigMap {A: Type} (P Q: A -> Prop) (Himpl: forall a, P a -> Q a): sig P -> sig Q := fun σ => match σ with | exist _ a h => exist Q a (Himpl a h) end.
A, B, C: Type

forall (a : A) (b_orig : Batch A B (B -> C)), Batch {a' : A | a' ∈ b_orig} B (B -> C) -> Batch {a' : A | a' ∈ (b_orig ⧆ a)} B (B -> C)
A, B, C: Type

forall (a : A) (b_orig : Batch A B (B -> C)), Batch {a' : A | a' ∈ b_orig} B (B -> C) -> Batch {a' : A | a' ∈ (b_orig ⧆ a)} B (B -> C)
A, B, C: Type
a: A
b_orig: Batch A B (B -> C)
b_recc: Batch {a' : A | a' ∈ b_orig} B (B -> C)

Batch {a' : A | a' ∈ (b_orig ⧆ a)} B (B -> C)
apply (map (BATCH1 B (B -> C)) (sigMap (fun a0 : A => a0 ∈ b_orig) (fun a0 : A => a0 ∈ (b_orig ⧆ a)) (element_of_Step1 a b_orig)) b_recc). Defined. Fixpoint annotate_occurrence {A B C: Type} (b: Batch A B C): Batch {a| element_of (F := BATCH1 B C) a b} B C := match b with | Done c => Done c | Step rest a => Step (annotate_occurrence_helper a rest (annotate_occurrence rest)) (exist (tosubset (rest ⧆ a)) a (element_of_Step2 rest a)) end. (** * <<runBatch>> Assuming Proofs of Occurrence *) (******************************************************************************) Definition runBatch_with_occurrence {A B C} (G: Type -> Type) `{Applicative G}: forall (b: Batch A B C) `(f: {a | element_of (F := BATCH1 B C) a b} -> G B), G C := fun b f => runBatch f (annotate_occurrence b). End annotate_Batch_elements.