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 Import
Classes.Categorical.Monad
Classes.Coalgebraic.TraversableFunctor
Adapters.KleisliToCoalgebraic.TraversableFunctor
Classes.Kleisli.Theory.TraversableFunctor
Classes.Kleisli.Theory.TraversableMonad
Classes.Categorical.ContainerFunctor
Classes.Categorical.ShapelyFunctor.From Tealeaves Require Export
Functors.Early.List
Functors.Early.Subset.Import ContainerFunctor.Notations.Import TraversableMonad.Notations.Import List.ListNotations.Import Monoid.Notations.Import Subset.Notations.Import Applicative.Notations.Export EqNotations.#[local] Generalizable VariablesM A B G ϕ.(** *** List <<traverse>> is compatible with its <<tosubset_list>> *)(**********************************************************************)
Compat_ToSubset_Traverse list
Compat_ToSubset_Traverse list
ToSubset_list = ToSubset_Traverse
(fun (A : Type) (l : list A) (a : A) => List.In a l) =
ToSubset_Traverse
(fun (A : Type) (l : list A) (a : A) => List.In a l) =
(funA : Type => mapReduce ret)
A: Type l: list A
(funa : A => List.In a l) = mapReduce ret l
A: Type l: list A
(funa : A => List.In a l) = mapReduce_list ret l
A: Type
(funa : A => List.In a []) = mapReduce_list ret []
A: Type a: A l: list A IHl: (funa : A => List.In a l) = mapReduce_list ret l
(funa0 : A => List.In a0 (a :: l)) =
mapReduce_list ret (a :: l)
A: Type
(funa : A => List.In a []) = mapReduce_list ret []
A: Type
(funa : A => List.In a []) = Ƶ
reflexivity.
A: Type a: A l: list A IHl: (funa : A => List.In a l) = mapReduce_list ret l
(funa0 : A => List.In a0 (a :: l)) =
mapReduce_list ret (a :: l)
A: Type a: A l: list A IHl: (funa : A => List.In a l) = mapReduce_list ret l
(funa0 : A => List.In a0 (a :: l)) =
ret a ● mapReduce_list ret l
A: Type a: A l: list A IHl: (funa : A => List.In a l) = mapReduce_list ret l
(funa0 : A => a = a0 \/ List.In a0 l) =
ret a ● mapReduce_list ret l
A: Type a: A l: list A IHl: (funa : A => List.In a l) = mapReduce_list ret l
(funa0 : A => a = a0 \/ List.In a0 l) =
ret a ● (funa : A => List.In a l)
reflexivity.Qed.(** * <<toBatch>> Instance *)(**********************************************************************)#[export] InstanceToBatch_list: ToBatch list :=
DerivedOperations.ToBatch_Traverse.(** * <<map>> equality inversion lemmas *)(** Some lemmas for reasoning backwards from equality between two similarly-concatenated lists. *)(**********************************************************************)
forall (AB : Type) (fg : A -> B) (l1l2 : list A),
map f (l1 ++ l2) = map g (l1 ++ l2) ->
map f l1 = map g l1
forall (AB : Type) (fg : A -> B) (l1l2 : list A),
map f (l1 ++ l2) = map g (l1 ++ l2) ->
map f l1 = map g l1
A, B: Type f, g: A -> B l1, l2: list A H: map f (l1 ++ l2) = map g (l1 ++ l2)
map f l1 = map g l1
A, B: Type f, g: A -> B l2: list A H: map f ([] ++ l2) = map g ([] ++ l2)
map f [] = map g []
A, B: Type f, g: A -> B a: A l1, l2: list A H: map f ((a :: l1) ++ l2) = map g ((a :: l1) ++ l2) IHl1: map f (l1 ++ l2) = map g (l1 ++ l2) ->
map f l1 = map g l1
map f (a :: l1) = map g (a :: l1)
A, B: Type f, g: A -> B l2: list A H: map f ([] ++ l2) = map g ([] ++ l2)
map f [] = map g []
reflexivity.
A, B: Type f, g: A -> B a: A l1, l2: list A H: map f ((a :: l1) ++ l2) = map g ((a :: l1) ++ l2) IHl1: map f (l1 ++ l2) = map g (l1 ++ l2) ->
map f l1 = map g l1
map f (a :: l1) = map g (a :: l1)
A, B: Type f, g: A -> B a: A l1, l2: list A H: (f a :: map f l1) ++ map f l2 =
(g a :: map g l1) ++ map g l2 IHl1: map f l1 ++ map f l2 = map g l1 ++ map g l2 ->
map f l1 = map g l1
f a :: map f l1 = g a :: map g l1
A, B: Type f, g: A -> B a: A l1, l2: list A H: (f a :: map f l1) ++ map f l2 =
(g a :: map g l1) ++ map g l2 IHl1: map f l1 ++ map f l2 = map g l1 ++ map g l2 ->
map f l1 = map g l1
f a :: map g l1 = g a :: map g l1
A, B: Type f, g: A -> B a: A l1, l2: list A H: (f a :: map f l1) ++ map f l2 =
(g a :: map g l1) ++ map g l2 IHl1: map f l1 ++ map f l2 = map g l1 ++ map g l2 ->
map f l1 = map g l1
map f l1 ++ map f l2 = map g l1 ++ map g l2
A, B: Type f, g: A -> B a: A l1, l2: list A H: (f a :: map f l1) ++ map f l2 =
(g a :: map g l1) ++ map g l2 IHl1: map f l1 ++ map f l2 = map g l1 ++ map g l2 ->
map f l1 = map g l1
f a :: map g l1 = g a :: map g l1
A, B: Type f, g: A -> B a: A l1, l2: list A H: (f a :: map f l1) ++ map f l2 =
(g a :: map g l1) ++ map g l2 IHl1: map f l1 ++ map f l2 = map g l1 ++ map g l2 ->
map f l1 = map g l1
f a = g a
A, B: Type f, g: A -> B a: A l1, l2: list A H: f a :: map f l1 ++ map f l2 =
g a :: map g l1 ++ map g l2 IHl1: map f l1 ++ map f l2 = map g l1 ++ map g l2 ->
map f l1 = map g l1
f a = g a
inversion H; auto.
A, B: Type f, g: A -> B a: A l1, l2: list A H: (f a :: map f l1) ++ map f l2 =
(g a :: map g l1) ++ map g l2 IHl1: map f l1 ++ map f l2 = map g l1 ++ map g l2 ->
map f l1 = map g l1
map f l1 ++ map f l2 = map g l1 ++ map g l2
A, B: Type f, g: A -> B a: A l1, l2: list A H: f a :: map f l1 ++ map f l2 =
g a :: map g l1 ++ map g l2 IHl1: map f l1 ++ map f l2 = map g l1 ++ map g l2 ->
map f l1 = map g l1
map f l1 ++ map f l2 = map g l1 ++ map g l2
A, B: Type f, g: A -> B a: A l1, l2: list A H: f a :: map f l1 ++ map f l2 =
g a :: map g l1 ++ map g l2 IHl1: map f l1 ++ map f l2 = map g l1 ++ map g l2 ->
map f l1 = map g l1 H1: f a = g a H2: map f l1 ++ map f l2 = map g l1 ++ map g l2
map f l1 ++ map f l2 = map f l1 ++ map f l2
auto.Qed.
forall (AB : Type) (fg : A -> B) (l1l2 : list A),
map f (l1 ++ l2) = map g (l1 ++ l2) ->
map f l2 = map g l2
forall (AB : Type) (fg : A -> B) (l1l2 : list A),
map f (l1 ++ l2) = map g (l1 ++ l2) ->
map f l2 = map g l2
A, B: Type f, g: A -> B l1, l2: list A H: map f (l1 ++ l2) = map g (l1 ++ l2)
map f l2 = map g l2
A, B: Type f, g: A -> B l1, l2: list A H: map f (l1 ++ l2) = map g (l1 ++ l2)
map f l1 = map g l1
A, B: Type f, g: A -> B l1, l2: list A H: map f (l1 ++ l2) = map g (l1 ++ l2) heads_equal: map f l1 = map g l1
map f l2 = map g l2
A, B: Type f, g: A -> B l1, l2: list A H: map f (l1 ++ l2) = map g (l1 ++ l2)
map f l1 = map g l1
eauto using map_app_inv_l.
A, B: Type f, g: A -> B l1, l2: list A H: map f (l1 ++ l2) = map g (l1 ++ l2) heads_equal: map f l1 = map g l1
map f l2 = map g l2
A, B: Type f, g: A -> B l1, l2: list A H: map f l1 ++ map f l2 = map g l1 ++ map g l2 heads_equal: map f l1 = map g l1
map f l2 = map g l2
A, B: Type f, g: A -> B l1, l2: list A H: map g l1 ++ map f l2 = map g l1 ++ map g l2 heads_equal: map f l1 = map g l1
map f l2 = map g l2
eauto using List.app_inv_head.Qed.
forall (AB : Type) (fg : A -> B) (l1l2 : list A),
map f (l1 ++ l2) = map g (l1 ++ l2) ->
map f l1 = map g l1 /\ map f l2 = map g l2
forall (AB : Type) (fg : A -> B) (l1l2 : list A),
map f (l1 ++ l2) = map g (l1 ++ l2) ->
map f l1 = map g l1 /\ map f l2 = map g l2
intros; split; eauto using map_app_inv_l, map_app_inv_r.Qed.#[local] Generalizable VariableF.(** * Shapely Functor Instance for [list] *)(** As a reasonability check, we prove that [list] is a listable functor. *)(**********************************************************************)SectionShapelyFunctor_list.InstanceTolist_list: Tolist list := funAl => l.
Natural (@tolist list Tolist_list)
Natural (@tolist list Tolist_list)
forall (AB : Type) (f : A -> B),
map f ∘ tolist = tolist ∘ map f
forall (A : Type) (l : list A),
shape l = [] <-> l = []
forall (A : Type) (l : list A),
shape l = [] <-> l = []
A: Type
shape [] = [] <-> [] = []
A: Type a: A l: list A IHl: shape l = [] <-> l = []
shape (a :: l) = [] <-> a :: l = []
A: Type a: A l: list A IHl: shape l = [] <-> l = []
shape (a :: l) = [] <-> a :: l = []
split; intro contra; now inverts contra.Qed.Endlist_shape_rewrite.#[export] Hint Rewrite
@shape_nil @shape_cons @shape_one @shape_app: tea_list.(** ** Reasoning Princples for <<shape>> on Lists *)(**********************************************************************)Sectionlist_shape_lemmas.
forall (A : Type) (l1l2 : list A),
shape l1 = shape l2 <-> length l1 = length l2
forall (A : Type) (l1l2 : list A),
shape l1 = shape l2 <-> length l1 = length l2
A: Type l1, l2: list A
shape l1 = shape l2 <-> length l1 = length l2
A: Type l1: list A
foralll2 : list A,
shape l1 = shape l2 <-> length l1 = length l2
A: Type
foralll2 : list A,
shape [] = shape l2 <-> length [] = length l2
A: Type a: A l1: list A IHl1: foralll2 : list A,
shape l1 = shape l2 <-> length l1 = length l2
foralll2 : list A,
shape (a :: l1) = shape l2 <->
length (a :: l1) = length l2
A: Type
foralll2 : list A,
shape [] = shape l2 <-> length [] = length l2
A: Type
shape [] = shape [] <-> length [] = length []
A: Type a: A l2: list A
shape [] = shape (a :: l2) <->
length [] = length (a :: l2)
A: Type
shape [] = shape [] <-> length [] = length []
split; reflexivity.
A: Type a: A l2: list A
shape [] = shape (a :: l2) <->
length [] = length (a :: l2)
split; inversion1.
A: Type a: A l1: list A IHl1: foralll2 : list A,
shape l1 = shape l2 <-> length l1 = length l2
foralll2 : list A,
shape (a :: l1) = shape l2 <->
length (a :: l1) = length l2
A: Type a: A l1: list A IHl1: foralll2 : list A,
shape l1 = shape l2 <-> length l1 = length l2
foralll2 : list A,
const tt a :: shape l1 = shape l2 <->
S (length l1) = length l2
A: Type a: A l1: list A IHl1: foralll2 : list A,
shape l1 = shape l2 <-> length l1 = length l2
const tt a :: shape l1 = shape [] <->
S (length l1) = length []
A: Type a: A l1: list A IHl1: foralll2 : list A,
shape l1 = shape l2 <-> length l1 = length l2 a0: A l2: list A
const tt a :: shape l1 = shape (a0 :: l2) <->
S (length l1) = length (a0 :: l2)
A: Type a: A l1: list A IHl1: foralll2 : list A,
shape l1 = shape l2 <-> length l1 = length l2
const tt a :: shape l1 = shape [] <->
S (length l1) = length []
A: Type a: A l1: list A IHl1: foralll2 : list A,
shape l1 = shape l2 <-> length l1 = length l2
const tt a :: shape l1 = [] <-> S (length l1) = 0
split; inversion1.
A: Type a: A l1: list A IHl1: foralll2 : list A,
shape l1 = shape l2 <-> length l1 = length l2 a0: A l2: list A
const tt a :: shape l1 = shape (a0 :: l2) <->
S (length l1) = length (a0 :: l2)
A: Type a: A l1: list A IHl1: foralll2 : list A,
shape l1 = shape l2 <-> length l1 = length l2 a0: A l2: list A
const tt a :: shape l1 = const tt a0 :: shape l2 <->
S (length l1) = S (length l2)
A: Type a: A l1: list A IHl1: foralll2 : list A,
shape l1 = shape l2 <-> length l1 = length l2 a0: A l2: list A H: const tt a :: shape l1 = const tt a0 :: shape l2 H1: shape l1 = shape l2
S (length l1) = S (length l2)
A: Type a: A l1: list A IHl1: foralll2 : list A,
shape l1 = shape l2 <-> length l1 = length l2 a0: A l2: list A H: S (length l1) = S (length l2) H1: length l1 = length l2
const tt a :: shape l1 = const tt a0 :: shape l2
A: Type a: A l1: list A IHl1: foralll2 : list A,
shape l1 = shape l2 <-> length l1 = length l2 a0: A l2: list A H: const tt a :: shape l1 = const tt a0 :: shape l2 H1: shape l1 = shape l2
S (length l1) = S (length l2)
A: Type a: A l1: list A IHl1: foralll2 : list A,
shape l1 = shape l2 <-> length l1 = length l2 a0: A l2: list A H: const tt a :: shape l1 = const tt a0 :: shape l2 H1: shape l1 = shape l2
length l1 = length l2
A: Type a: A l1: list A IHl1: foralll2 : list A,
shape l1 = shape l2 <-> length l1 = length l2 a0: A l2: list A H: const tt a :: shape l1 = const tt a0 :: shape l2 H1: shape l1 = shape l2
shape l1 = shape l2
auto.
A: Type a: A l1: list A IHl1: foralll2 : list A,
shape l1 = shape l2 <-> length l1 = length l2 a0: A l2: list A H: S (length l1) = S (length l2) H1: length l1 = length l2
const tt a :: shape l1 = const tt a0 :: shape l2
A: Type a: A l1: list A IHl1: foralll2 : list A,
shape l1 = shape l2 <-> length l1 = length l2 a0: A l2: list A H: S (length l1) = S (length l2) H1: length l1 = length l2
shape l1 = shape l2
A: Type a: A l1: list A IHl1: foralll2 : list A,
shape l1 = shape l2 <-> length l1 = length l2 a0: A l2: list A H: S (length l1) = S (length l2) H1: length l1 = length l2
A: Type a: A l2: list A IHl2: forallr1r2 : list A,
shape [] = shape l2 ->
[] ++ r1 = l2 ++ r2 -> [] = l2
forallr1r2 : list A,
shape [] = shape (a :: l2) ->
[] ++ r1 = (a :: l2) ++ r2 -> [] = a :: l2
A: Type a: A l1: list A IHl1: foralll2r1r2 : list A,
shape l1 = shape l2 ->
l1 ++ r1 = l2 ++ r2 -> l1 = l2
forallr1r2 : list A,
shape (a :: l1) = shape [] ->
(a :: l1) ++ r1 = [] ++ r2 -> a :: l1 = []
A: Type a: A l1: list A IHl1: foralll2r1r2 : list A,
shape l1 = shape l2 ->
l1 ++ r1 = l2 ++ r2 -> l1 = l2 a0: A l2: list A IHl2: forallr1r2 : list A,
shape (a :: l1) = shape l2 ->
(a :: l1) ++ r1 = l2 ++ r2 -> a :: l1 = l2
forallr1r2 : list A,
shape (a :: l1) = shape (a0 :: l2) ->
(a :: l1) ++ r1 = (a0 :: l2) ++ r2 ->
a :: l1 = a0 :: l2
A: Type a: A l2: list A IHl2: forallr1r2 : list A,
shape [] = shape l2 ->
[] ++ r1 = l2 ++ r2 -> [] = l2
forallr1r2 : list A,
shape [] = shape (a :: l2) ->
[] ++ r1 = (a :: l2) ++ r2 -> [] = a :: l2
A: Type a: A l2: list A IHl2: forallr1r2 : list A,
shape [] = shape l2 ->
[] ++ r1 = l2 ++ r2 -> [] = l2 r1, r2: list A shape_eq: shape [] = shape (a :: l2)
[] ++ r1 = (a :: l2) ++ r2 -> [] = a :: l2
now inverts shape_eq.
A: Type a: A l1: list A IHl1: foralll2r1r2 : list A,
shape l1 = shape l2 ->
l1 ++ r1 = l2 ++ r2 -> l1 = l2
forallr1r2 : list A,
shape (a :: l1) = shape [] ->
(a :: l1) ++ r1 = [] ++ r2 -> a :: l1 = []
A: Type a: A l1: list A IHl1: foralll2r1r2 : list A,
shape l1 = shape l2 ->
l1 ++ r1 = l2 ++ r2 -> l1 = l2 r1, r2: list A shape_eq: shape (a :: l1) = shape []
(a :: l1) ++ r1 = [] ++ r2 -> a :: l1 = []
now inverts shape_eq.
A: Type a: A l1: list A IHl1: foralll2r1r2 : list A,
shape l1 = shape l2 ->
l1 ++ r1 = l2 ++ r2 -> l1 = l2 a0: A l2: list A IHl2: forallr1r2 : list A,
shape (a :: l1) = shape l2 ->
(a :: l1) ++ r1 = l2 ++ r2 -> a :: l1 = l2
forallr1r2 : list A,
shape (a :: l1) = shape (a0 :: l2) ->
(a :: l1) ++ r1 = (a0 :: l2) ++ r2 ->
a :: l1 = a0 :: l2
A: Type a: A l1: list A IHl1: foralll2r1r2 : list A,
shape l1 = shape l2 ->
l1 ++ r1 = l2 ++ r2 -> l1 = l2 a0: A l2: list A IHl2: forallr1r2 : list A,
shape (a :: l1) = shape l2 ->
(a :: l1) ++ r1 = l2 ++ r2 -> a :: l1 = l2 r1, r2: list A shape_eq: shape (a :: l1) = shape (a0 :: l2) heq: (a :: l1) ++ r1 = (a0 :: l2) ++ r2
a :: l1 = a0 :: l2
A: Type a: A l1: list A IHl1: foralll2r1r2 : list A,
shape l1 = shape l2 ->
l1 ++ r1 = l2 ++ r2 -> l1 = l2 a0: A l2: list A IHl2: forallr1r2 : list A,
shape (a :: l1) = shape l2 ->
(a :: l1) ++ r1 = l2 ++ r2 -> a :: l1 = l2 r1, r2: list A shape_eq: shape l1 = shape l2 heq: (a :: l1) ++ r1 = (a0 :: l2) ++ r2
a :: l1 = a0 :: l2
A: Type a: A l1: list A IHl1: foralll2r1r2 : list A,
shape l1 = shape l2 ->
l1 ++ r1 = l2 ++ r2 -> l1 = l2 a0: A l2: list A IHl2: forallr1r2 : list A,
shape (a :: l1) = shape l2 ->
(a :: l1) ++ r1 = l2 ++ r2 -> a :: l1 = l2 r1, r2: list A shape_eq: shape l1 = shape l2 heq: a :: l1 ++ r1 = a0 :: l2 ++ r2
a :: l1 = a0 :: l2
A: Type l1: list A IHl1: foralll2r1r2 : list A,
shape l1 = shape l2 ->
l1 ++ r1 = l2 ++ r2 -> l1 = l2 a0: A l2: list A IHl2: forallr1r2 : list A,
shape (a0 :: l1) = shape l2 ->
(a0 :: l1) ++ r1 = l2 ++ r2 -> a0 :: l1 = l2 r1, r2: list A shape_eq: shape l1 = shape l2 H1: l1 ++ r1 = l2 ++ r2
a0 :: l1 = a0 :: l2
A: Type l1: list A IHl1: foralll2r1r2 : list A,
shape l1 = shape l2 ->
l1 ++ r1 = l2 ++ r2 -> l1 = l2 a0: A l2: list A IHl2: forallr1r2 : list A,
shape (a0 :: l1) = shape l2 ->
(a0 :: l1) ++ r1 = l2 ++ r2 -> a0 :: l1 = l2 r1, r2: list A shape_eq: shape l1 = shape l2 H1: l1 ++ r1 = l2 ++ r2
A: Type a: A l2: list A IHl2: forallr1r2 : list A,
shape r1 = shape r2 ->
[] ++ r1 = l2 ++ r2 -> [] = l2
forallr1r2 : list A,
shape r1 = shape r2 ->
[] ++ r1 = (a :: l2) ++ r2 -> [] = a :: l2
A: Type a: A l1: list A IHl1: foralll2r1r2 : list A,
shape r1 = shape r2 ->
l1 ++ r1 = l2 ++ r2 -> l1 = l2
forallr1r2 : list A,
shape r1 = shape r2 ->
(a :: l1) ++ r1 = [] ++ r2 -> a :: l1 = []
A: Type a: A l1: list A IHl1: foralll2r1r2 : list A,
shape r1 = shape r2 ->
l1 ++ r1 = l2 ++ r2 -> l1 = l2 a0: A l2: list A IHl2: forallr1r2 : list A,
shape r1 = shape r2 ->
(a :: l1) ++ r1 = l2 ++ r2 -> a :: l1 = l2
forallr1r2 : list A,
shape r1 = shape r2 ->
(a :: l1) ++ r1 = (a0 :: l2) ++ r2 ->
a :: l1 = a0 :: l2
A: Type a: A l1: list A IHl1: foralll2r1r2 : list A,
shape r1 = shape r2 ->
l1 ++ r1 = l2 ++ r2 -> l1 = l2 r1, r2: list A shape_eq: shape r1 = shape r2 heq: (a :: l1) ++ r1 = [] ++ r2
shape ?Goal2 = shape ?Goal3
A: Type a: A l1: list A IHl1: foralll2r1r2 : list A,
shape r1 = shape r2 ->
l1 ++ r1 = l2 ++ r2 -> l1 = l2 r1, r2: list A shape_eq: shape r1 = shape r2 heq: (a :: l1) ++ r1 = [] ++ r2
shape r1 = shape r2
auto.
A: Type a: A l1: list A IHl1: foralll2r1r2 : list A,
shape r1 = shape r2 ->
l1 ++ r1 = l2 ++ r2 -> l1 = l2 r1, r2: list A shape_eq: shape r1 = shape r2 heq: (a :: l1) ++ r1 = [] ++ r2
(a :: l1) ++ r1 = [] ++ r2
assumption.
A: Type a: A l1: list A IHl1: foralll2r1r2 : list A,
shape r1 = shape r2 ->
l1 ++ r1 = l2 ++ r2 -> l1 = l2 a0: A l2: list A IHl2: forallr1r2 : list A,
shape r1 = shape r2 ->
(a :: l1) ++ r1 = l2 ++ r2 -> a :: l1 = l2
forallr1r2 : list A,
shape r1 = shape r2 ->
(a :: l1) ++ r1 = (a0 :: l2) ++ r2 ->
a :: l1 = a0 :: l2
A: Type a: A l1: list A IHl1: foralll2r1r2 : list A,
shape r1 = shape r2 ->
l1 ++ r1 = l2 ++ r2 -> l1 = l2 a0: A l2: list A IHl2: forallr1r2 : list A,
shape r1 = shape r2 ->
(a :: l1) ++ r1 = l2 ++ r2 -> a :: l1 = l2 r1, r2: list A shape_eq: shape r1 = shape r2 heq: (a :: l1) ++ r1 = (a0 :: l2) ++ r2
a :: l1 = a0 :: l2
A: Type a: A l1: list A IHl1: foralll2r1r2 : list A,
shape r1 = shape r2 ->
l1 ++ r1 = l2 ++ r2 -> l1 = l2 a0: A l2: list A IHl2: forallr1r2 : list A,
shape r1 = shape r2 ->
(a :: l1) ++ r1 = l2 ++ r2 -> a :: l1 = l2 r1, r2: list A shape_eq: shape r1 = shape r2 heq: a :: l1 ++ r1 = a0 :: l2 ++ r2
a :: l1 = a0 :: l2
A: Type l1: list A IHl1: foralll2r1r2 : list A,
shape r1 = shape r2 ->
l1 ++ r1 = l2 ++ r2 -> l1 = l2 a0: A l2: list A IHl2: forallr1r2 : list A,
shape r1 = shape r2 ->
(a0 :: l1) ++ r1 = l2 ++ r2 -> a0 :: l1 = l2 r1, r2: list A shape_eq: shape r1 = shape r2 H1: l1 ++ r1 = l2 ++ r2
a0 :: l1 = a0 :: l2
A: Type l1: list A IHl1: foralll2r1r2 : list A,
shape r1 = shape r2 ->
l1 ++ r1 = l2 ++ r2 -> l1 = l2 a0: A l2: list A IHl2: forallr1r2 : list A,
shape r1 = shape r2 ->
(a0 :: l1) ++ r1 = l2 ++ r2 -> a0 :: l1 = l2 r1, r2: list A shape_eq: shape r1 = shape r2 H1: l1 ++ r1 = l2 ++ r2
A: Type l1, l2, r1, r2: list A hyp: shape l1 = shape l2
l1 ++ r1 = l2 ++ r2 -> l1 = l2 /\ r1 = r2
A: Type l1, l2, r1, r2: list A hyp: shape l1 = shape l2
l1 = l2 /\ r1 = r2 -> l1 ++ r1 = l2 ++ r2
A: Type l1, l2, r1, r2: list A hyp: shape r1 = shape r2
l1 ++ r1 = l2 ++ r2 -> l1 = l2 /\ r1 = r2
A: Type l1, l2, r1, r2: list A hyp: shape r1 = shape r2
l1 = l2 /\ r1 = r2 -> l1 ++ r1 = l2 ++ r2
A: Type l1, l2, r1, r2: list A hyp: shape l1 = shape l2
l1 ++ r1 = l2 ++ r2 -> l1 = l2 /\ r1 = r2
A: Type l1, l2, r1, r2: list A hyp: shape l1 = shape l2 heq: l1 ++ r1 = l2 ++ r2
l1 = l2 /\ r1 = r2
A: Type l1, l2, r1, r2: list A hyp: shape l1 = shape l2 heq: l1 ++ r1 = l2 ++ r2
l1 = l2
A: Type l1, l2, r1, r2: list A hyp: shape l1 = shape l2 heq: l1 ++ r1 = l2 ++ r2
r1 = r2
A: Type l1, l2, r1, r2: list A hyp: shape l1 = shape l2 heq: l1 ++ r1 = l2 ++ r2
r1 = r2
eapply inv_app_eq_lr; eauto.
A: Type l1, l2, r1, r2: list A hyp: shape l1 = shape l2
l1 = l2 /\ r1 = r2 -> l1 ++ r1 = l2 ++ r2
A: Type l1, l2, r1, r2: list A hyp: shape l1 = shape l2 H: l1 = l2 H0: r1 = r2
l1 ++ r1 = l2 ++ r2
nowsubst.
A: Type l1, l2, r1, r2: list A hyp: shape r1 = shape r2
l1 ++ r1 = l2 ++ r2 -> l1 = l2 /\ r1 = r2
A: Type l1, l2, r1, r2: list A hyp: shape r1 = shape r2 heq: l1 ++ r1 = l2 ++ r2
l1 = l2 /\ r1 = r2
A: Type l1, l2, r1, r2: list A hyp: shape r1 = shape r2 heq: l1 ++ r1 = l2 ++ r2
l1 = l2
A: Type l1, l2, r1, r2: list A hyp: shape r1 = shape r2 heq: l1 ++ r1 = l2 ++ r2
r1 = r2
A: Type l1, l2, r1, r2: list A hyp: shape r1 = shape r2 heq: l1 ++ r1 = l2 ++ r2
r1 = r2
eapply inv_app_eq_rr; eauto.
A: Type l1, l2, r1, r2: list A hyp: shape r1 = shape r2
l1 = l2 /\ r1 = r2 -> l1 ++ r1 = l2 ++ r2
A: Type l1, l2, r1, r2: list A hyp: shape r1 = shape r2 H: l1 = l2 H0: r1 = r2
l1 ++ r1 = l2 ++ r2
nowsubst.Qed.
forall (A : Type) (ll1l2 : list A),
l ++ l1 = l ++ l2 -> l1 = l2
forall (A : Type) (ll1l2 : list A),
l ++ l1 = l ++ l2 -> l1 = l2
A: Type l, l1, l2: list A hyp: l ++ l1 = l ++ l2
l1 = l2
A: Type l1, l2: list A hyp: [] ++ l1 = [] ++ l2
l1 = l2
A: Type a: A l, l1, l2: list A hyp: (a :: l) ++ l1 = (a :: l) ++ l2 IHl: l ++ l1 = l ++ l2 -> l1 = l2
l1 = l2
A: Type l1, l2: list A hyp: [] ++ l1 = [] ++ l2
l1 = l2
A: Type l1, l2: list A hyp: l1 = l2
l1 = l2
auto.
A: Type a: A l, l1, l2: list A hyp: (a :: l) ++ l1 = (a :: l) ++ l2 IHl: l ++ l1 = l ++ l2 -> l1 = l2
l1 = l2
A: Type a: A l, l1, l2: list A hyp: (a :: l) ++ l1 = (a :: l) ++ l2 IHl: l ++ l1 = l ++ l2 -> l1 = l2 H0: l ++ l1 = l ++ l2
l1 = l2
auto.Qed.
forall (A : Type) (ll1l2 : list A),
l1 ++ l = l2 ++ l -> l1 = l2
forall (A : Type) (ll1l2 : list A),
l1 ++ l = l2 ++ l -> l1 = l2
A: Type l, l1, l2: list A hyp: l1 ++ l = l2 ++ l
l1 = l2
A: Type l, l1, l2: list A hyp: l1 ++ l = l2 ++ l
shape ?r1 = shape ?r2
A: Type l, l1, l2: list A hyp: l1 ++ l = l2 ++ l
l1 ++ ?r1 = l2 ++ ?r2
A: Type l, l1, l2: list A hyp: l1 ++ l = l2 ++ l
shape l = shape l
reflexivity.Qed.
forall (A : Type) (l1l2 : list A) (a1a2 : A),
l1 ++ ret a1 = l2 ++ ret a2 -> l1 = l2
forall (A : Type) (l1l2 : list A) (a1a2 : A),
l1 ++ ret a1 = l2 ++ ret a2 -> l1 = l2
A: Type l1, l2: list A a1, a2: A H: l1 ++ ret a1 = l2 ++ ret a2
l1 = l2
eapply inv_app_eq_rl; [|eauto]; auto.Qed.
forall (A : Type) (l1l2 : list A) (a1a2 : A),
l1 ++ [a1] = l2 ++ [a2] -> a1 = a2
forall (A : Type) (l1l2 : list A) (a1a2 : A),
l1 ++ [a1] = l2 ++ [a2] -> a1 = a2
A: Type l1, l2: list A a1, a2: A
l1 ++ [a1] = l2 ++ [a2] -> a1 = a2
A: Type l1, l2: list A a1, a2: A hyp: l1 ++ [a1] = l2 ++ [a2]
a1 = a2
A: Type l1, l2: list A a1, a2: A hyp: [a1] = [a2]
a1 = a2
A: Type l1, l2: list A a1, a2: A hyp: l1 ++ [a1] = l2 ++ [a2]
shape [a1] = shape [a2]
A: Type l1, l2: list A a1, a2: A hyp: l1 ++ [a1] = l2 ++ [a2]
shape [a1] = shape [a2]
easy.Qed.Endlist_shape_lemmas.(** * Reasoning principles for <<shape>> on listable functors *)(**********************************************************************)Sectionlistable_shape_lemmas.Context
`{Functor F}
`{Tolist F}
`{! Natural (@tolist F _)}.(* Values with the same shape have equal-length contents *)
F: Type -> Type Map_F: Map F H: Functor F H0: Tolist F Natural0: Natural (@tolist F H0)
forall (A : Type) (t : F A) (B : Type) (u : F B),
shape t = shape u ->
shape (tolist t) = shape (tolist u)
F: Type -> Type Map_F: Map F H: Functor F H0: Tolist F Natural0: Natural (@tolist F H0)
forall (A : Type) (t : F A) (B : Type) (u : F B),
shape t = shape u ->
shape (tolist t) = shape (tolist u)
F: Type -> Type Map_F: Map F H: Functor F H0: Tolist F Natural0: Natural (@tolist F H0) A: Type t: F A B: Type u: F B heq: shape t = shape u
shape (tolist t) = shape (tolist u)
F: Type -> Type Map_F: Map F H: Functor F H0: Tolist F Natural0: Natural (@tolist F H0) A: Type t: F A B: Type u: F B heq: shape t = shape u
(shape ∘ tolist) t = shape (tolist u)
F: Type -> Type Map_F: Map F H: Functor F H0: Tolist F Natural0: Natural (@tolist F H0) A: Type t: F A B: Type u: F B heq: shape t = shape u
(shape ∘ tolist) t = (shape ∘ tolist) u
F: Type -> Type Map_F: Map F H: Functor F H0: Tolist F Natural0: Natural (@tolist F H0) A: Type t: F A B: Type u: F B heq: map (const tt) t = map (const tt) u
(map (const tt) ∘ tolist) t =
(map (const tt) ∘ tolist) u
F: Type -> Type Map_F: Map F H: Functor F H0: Tolist F Natural0: Natural (@tolist F H0) A: Type t: F A B: Type u: F B heq: map (const tt) t = map (const tt) u
(tolist ∘ map (const tt)) t =
(tolist ∘ map (const tt)) u
F: Type -> Type Map_F: Map F H: Functor F H0: Tolist F Natural0: Natural (@tolist F H0) A: Type t: F A B: Type u: F B heq: map (const tt) t = map (const tt) u
F: Type -> Type Map_F: Map F H: Functor F H0: Tolist F Natural0: Natural (@tolist F H0) A: Type t: F A B: Type u: F B heq: map (const tt) t = map (const tt) u
map (const tt) t = map (const tt) u
apply heq.Qed.
F: Type -> Type Map_F: Map F H: Functor F H0: Tolist F Natural0: Natural (@tolist F H0)
forall (A : Type) (l1l2 : F A) (xy : list A),
shape l1 = shape l2 ->
tolist l1 ++ x = tolist l2 ++ y ->
tolist l1 = tolist l2
F: Type -> Type Map_F: Map F H: Functor F H0: Tolist F Natural0: Natural (@tolist F H0)
forall (A : Type) (l1l2 : F A) (xy : list A),
shape l1 = shape l2 ->
tolist l1 ++ x = tolist l2 ++ y ->
tolist l1 = tolist l2
F: Type -> Type Map_F: Map F H: Functor F H0: Tolist F Natural0: Natural (@tolist F H0) A: Type l1, l2: F A x, y: list A shape_eq: shape l1 = shape l2 heq: tolist l1 ++ x = tolist l2 ++ y
tolist l1 = tolist l2
eauto using inv_app_eq_ll, shape_tolist.Qed.
F: Type -> Type Map_F: Map F H: Functor F H0: Tolist F Natural0: Natural (@tolist F H0)
forall (A : Type) (l1l2 : F A) (xy : list A),
shape l1 = shape l2 ->
x ++ tolist l1 = y ++ tolist l2 ->
tolist l1 = tolist l2
F: Type -> Type Map_F: Map F H: Functor F H0: Tolist F Natural0: Natural (@tolist F H0)
forall (A : Type) (l1l2 : F A) (xy : list A),
shape l1 = shape l2 ->
x ++ tolist l1 = y ++ tolist l2 ->
tolist l1 = tolist l2
F: Type -> Type Map_F: Map F H: Functor F H0: Tolist F Natural0: Natural (@tolist F H0) A: Type l1, l2: F A x, y: list A shape_eq: shape l1 = shape l2 heq: x ++ tolist l1 = y ++ tolist l2
tolist l1 = tolist l2
eauto using inv_app_eq_rr, shape_tolist.Qed.Endlistable_shape_lemmas.(** * Quantification Over Elements *)(* TODO: There is no real purpose for this at this point is there? *)(**********************************************************************)Sectionquantification.DefinitionForall_List `(P: A -> Prop): list A -> Prop :=
mapReduce_list (op := Monoid_op_and) (unit := Monoid_unit_true) P.DefinitionForany_List `(P: A -> Prop): list A -> Prop :=
mapReduce_list (op := Monoid_op_or) (unit := Monoid_unit_false) P.
A: Type P: A -> Prop l: list A
Forall_List P l <-> (foralla : A, a ∈ l -> P a)
A: Type P: A -> Prop l: list A
Forall_List P l <-> (foralla : A, a ∈ l -> P a)
A: Type P: A -> Prop l: list A
mapReduce_list P l <-> (foralla : A, a ∈ l -> P a)
A: Type P: A -> Prop
Ƶ <-> (foralla : A, a ∈ [] -> P a)
A: Type P: A -> Prop a: A l: list A IHl: mapReduce_list P l <-> (foralla : A, a ∈ l -> P a)
P a ● mapReduce_list P l <->
(foralla0 : A, a0 ∈ (a :: l) -> P a0)
A: Type P: A -> Prop
Ƶ <-> (foralla : A, a ∈ [] -> P a)
A: Type P: A -> Prop
Ƶ -> foralla : A, a ∈ [] -> P a
A: Type P: A -> Prop
(foralla : A, a ∈ [] -> P a) -> Ƶ
A: Type P: A -> Prop
Ƶ -> foralla : A, a ∈ [] -> P a
A: Type P: A -> Prop tt: Ƶ a: A contra: a ∈ []
P a
inversion contra.
A: Type P: A -> Prop
(foralla : A, a ∈ [] -> P a) -> Ƶ
A: Type P: A -> Prop H: foralla : A, a ∈ [] -> P a
Ƶ
exact I.
A: Type P: A -> Prop a: A l: list A IHl: mapReduce_list P l <-> (foralla : A, a ∈ l -> P a)
P a ● mapReduce_list P l <->
(foralla0 : A, a0 ∈ (a :: l) -> P a0)
A: Type P: A -> Prop a: A l: list A IHl: mapReduce_list P l <-> (foralla : A, a ∈ l -> P a)
P a ● mapReduce_list P l <->
(foralla0 : A, a0 = a \/ a0 ∈ l -> P a0)
A: Type P: A -> Prop a: A l: list A IHl: mapReduce_list P l <-> (foralla : A, a ∈ l -> P a)
P a ● (foralla : A, a ∈ l -> P a) <->
(foralla0 : A, a0 = a \/ a0 ∈ l -> P a0)
A: Type P: A -> Prop a: A l: list A IHl: mapReduce_list P l <-> (foralla : A, a ∈ l -> P a)
P a ● (foralla : A, a ∈ l -> P a) ->
foralla0 : A, a0 = a \/ a0 ∈ l -> P a0
A: Type P: A -> Prop a: A l: list A IHl: mapReduce_list P l <-> (foralla : A, a ∈ l -> P a)
(foralla0 : A, a0 = a \/ a0 ∈ l -> P a0) ->
P a ● (foralla : A, a ∈ l -> P a)
A: Type P: A -> Prop a: A l: list A IHl: mapReduce_list P l <-> (foralla : A, a ∈ l -> P a)
P a ● (foralla : A, a ∈ l -> P a) ->
foralla0 : A, a0 = a \/ a0 ∈ l -> P a0
A: Type P: A -> Prop a: A l: list A IHl: mapReduce_list P l <-> (foralla : A, a ∈ l -> P a) Hpa: P a Hrest: foralla : A, a ∈ l -> P a
foralla0 : A, a0 = a \/ a0 ∈ l -> P a0
A: Type P: A -> Prop a: A l: list A IHl: mapReduce_list P l <-> (foralla : A, a ∈ l -> P a) Hpa: P a Hrest: foralla : A, a ∈ l -> P a x: A Heq: x = a
P x
A: Type P: A -> Prop a: A l: list A IHl: mapReduce_list P l <->
(foralla : A, a ∈ l -> P a) Hpa: P a Hrest: foralla : A, a ∈ l -> P a x: A Hin: x ∈ l
P x
A: Type P: A -> Prop a: A l: list A IHl: mapReduce_list P l <-> (foralla : A, a ∈ l -> P a) Hpa: P a Hrest: foralla : A, a ∈ l -> P a x: A Hin: x ∈ l
P x
auto.
A: Type P: A -> Prop a: A l: list A IHl: mapReduce_list P l <-> (foralla : A, a ∈ l -> P a)
(foralla0 : A, a0 = a \/ a0 ∈ l -> P a0) ->
P a ● (foralla : A, a ∈ l -> P a)
A: Type P: A -> Prop a: A l: list A IHl: mapReduce_list P l <-> (foralla : A, a ∈ l -> P a) H: foralla0 : A, a0 = a \/ a0 ∈ l -> P a0
P a ● (foralla : A, a ∈ l -> P a)
split; auto.Qed.
A: Type P: A -> Prop l: list A
Forany_List P l <-> (existsa : A, a ∈ l /\ P a)
A: Type P: A -> Prop l: list A
Forany_List P l <-> (existsa : A, a ∈ l /\ P a)
A: Type P: A -> Prop l: list A
mapReduce_list P l <-> (existsa : A, a ∈ l /\ P a)
A: Type P: A -> Prop
mapReduce_list P [] <-> (existsa : A, a ∈ [] /\ P a)
A: Type P: A -> Prop a: A l: list A IHl: mapReduce_list P l <-> (existsa : A, a ∈ l /\ P a)
mapReduce_list P (a :: l) <->
(existsa0 : A, a0 ∈ (a :: l) /\ P a0)
A: Type P: A -> Prop
mapReduce_list P [] <-> (existsa : A, a ∈ [] /\ P a)
A: Type P: A -> Prop
mapReduce_list P [] -> existsa : A, a ∈ [] /\ P a
A: Type P: A -> Prop
(existsa : A, a ∈ [] /\ P a) -> mapReduce_list P []
A: Type P: A -> Prop
mapReduce_list P [] -> existsa : A, a ∈ [] /\ P a
intros [].
A: Type P: A -> Prop
(existsa : A, a ∈ [] /\ P a) -> mapReduce_list P []
A: Type P: A -> Prop x: A contra: x ∈ [] Hrest: P x
mapReduce_list P []
inversion contra.
A: Type P: A -> Prop a: A l: list A IHl: mapReduce_list P l <-> (existsa : A, a ∈ l /\ P a)
mapReduce_list P (a :: l) <->
(existsa0 : A, a0 ∈ (a :: l) /\ P a0)
A: Type P: A -> Prop a: A l: list A IHl: mapReduce_list P l <-> (existsa : A, a ∈ l /\ P a)
P a ● mapReduce_list P l <->
(existsa0 : A, a0 ∈ (a :: l) /\ P a0)
A: Type P: A -> Prop a: A l: list A IHl: mapReduce_list P l <-> (existsa : A, a ∈ l /\ P a)
P a ● mapReduce_list P l <->
(existsa0 : A, (a0 = a \/ a0 ∈ l) /\ P a0)
A: Type P: A -> Prop a: A l: list A IHl: mapReduce_list P l <-> (existsa : A, a ∈ l /\ P a)
P a ● mapReduce_list P l <->
(existsa0 : A, (a0 = a \/ a0 ∈ l) /\ P a0)
A: Type P: A -> Prop a: A l: list A IHl: mapReduce_list P l <-> (existsa : A, a ∈ l /\ P a)
P a ● (existsa : A, a ∈ l /\ P a) <->
(existsa0 : A, (a0 = a \/ a0 ∈ l) /\ P a0)
A: Type P: A -> Prop a: A l: list A IHl: mapReduce_list P l <-> (existsa : A, a ∈ l /\ P a)
P a ● (existsa : A, a ∈ l /\ P a) ->
existsa0 : A, (a0 = a \/ a0 ∈ l) /\ P a0
A: Type P: A -> Prop a: A l: list A IHl: mapReduce_list P l <-> (existsa : A, a ∈ l /\ P a)
(existsa0 : A, (a0 = a \/ a0 ∈ l) /\ P a0) ->
P a ● (existsa : A, a ∈ l /\ P a)
A: Type P: A -> Prop a: A l: list A IHl: mapReduce_list P l <-> (existsa : A, a ∈ l /\ P a)
P a ● (existsa : A, a ∈ l /\ P a) ->
existsa0 : A, (a0 = a \/ a0 ∈ l) /\ P a0
A: Type P: A -> Prop a: A l: list A IHl: mapReduce_list P l <-> (existsa : A, a ∈ l /\ P a) Hpa: P a
existsa0 : A, (a0 = a \/ a0 ∈ l) /\ P a0
A: Type P: A -> Prop a: A l: list A IHl: mapReduce_list P l <-> (existsa : A, a ∈ l /\ P a) Hrest: existsa : A, a ∈ l /\ P a
existsa0 : A, (a0 = a \/ a0 ∈ l) /\ P a0
A: Type P: A -> Prop a: A l: list A IHl: mapReduce_list P l <-> (existsa : A, a ∈ l /\ P a) Hpa: P a
(a = a \/ a ∈ l) /\ P a
A: Type P: A -> Prop a: A l: list A IHl: mapReduce_list P l <-> (existsa : A, a ∈ l /\ P a) Hrest: existsa : A, a ∈ l /\ P a
existsa0 : A, (a0 = a \/ a0 ∈ l) /\ P a0
A: Type P: A -> Prop a: A l: list A IHl: mapReduce_list P l <-> (existsa : A, a ∈ l /\ P a) Hrest: existsa : A, a ∈ l /\ P a
existsa0 : A, (a0 = a \/ a0 ∈ l) /\ P a0
A: Type P: A -> Prop a: A l: list A IHl: mapReduce_list P l <-> (existsa : A, a ∈ l /\ P a) x: A H1: x ∈ l H2: P x
existsa0 : A, (a0 = a \/ a0 ∈ l) /\ P a0
A: Type P: A -> Prop a: A l: list A IHl: mapReduce_list P l <-> (existsa : A, a ∈ l /\ P a) x: A H1: x ∈ l H2: P x
(x = a \/ x ∈ l) /\ P x
auto.
A: Type P: A -> Prop a: A l: list A IHl: mapReduce_list P l <-> (existsa : A, a ∈ l /\ P a)
(existsa0 : A, (a0 = a \/ a0 ∈ l) /\ P a0) ->
P a ● (existsa : A, a ∈ l /\ P a)
A: Type P: A -> Prop a: A l: list A IHl: mapReduce_list P l <-> (existsa : A, a ∈ l /\ P a) x: A H1: x = a H3: P x
P a ● (existsa : A, a ∈ l /\ P a)
A: Type P: A -> Prop a: A l: list A IHl: mapReduce_list P l <-> (existsa : A, a ∈ l /\ P a) x: A H2: x ∈ l H3: P x
P a ● (existsa : A, a ∈ l /\ P a)
A: Type P: A -> Prop a: A l: list A IHl: mapReduce_list P l <-> (existsa : A, a ∈ l /\ P a) H3: P a
P a ● (existsa : A, a ∈ l /\ P a)
A: Type P: A -> Prop a: A l: list A IHl: mapReduce_list P l <-> (existsa : A, a ∈ l /\ P a) x: A H2: x ∈ l H3: P x
P a ● (existsa : A, a ∈ l /\ P a)
A: Type P: A -> Prop a: A l: list A IHl: mapReduce_list P l <-> (existsa : A, a ∈ l /\ P a) x: A H2: x ∈ l H3: P x
P a ● (existsa : A, a ∈ l /\ P a)
A: Type P: A -> Prop a: A l: list A IHl: mapReduce_list P l <-> (existsa : A, a ∈ l /\ P a) x: A H2: x ∈ l H3: P x
existsa : A, a ∈ l /\ P a
eexists; eauto.Qed.Endquantification.(** ** <<a ∈ ->> in terms of <<mapReduce_list>> *)(**********************************************************************)
forallA : Type, tosubset = mapReduce_list ret
forallA : Type, tosubset = mapReduce_list ret
A: Type
tosubset = mapReduce_list ret
A: Type l: list A
tosubset l = mapReduce_list ret l
A: Type
tosubset [] = mapReduce_list ret []
A: Type a: A l: list A IHl: tosubset l = mapReduce_list ret l
tosubset (a :: l) = mapReduce_list ret (a :: l)
A: Type
tosubset [] = mapReduce_list ret []
reflexivity.
A: Type a: A l: list A IHl: tosubset l = mapReduce_list ret l
tosubset (a :: l) = mapReduce_list ret (a :: l)
A: Type a: A l: list A IHl: tosubset l = mapReduce_list ret l
tosubset (a :: l) = ret a ● crush_list (map ret l)
A: Type a: A l: list A IHl: tosubset l = mapReduce_list ret l
{{a}} ∪ tosubset l = ret a ● crush_list (map ret l)
A: Type a: A l: list A IHl: tosubset l = mapReduce_list ret l
{{a}} ∪ mapReduce_list ret l =
ret a ● crush_list (map ret l)
reflexivity.Qed.
forall (A : Type) (l : list A) (a : A),
tosubset l a = mapReduce_list (eq a) l
forall (A : Type) (l : list A) (a : A),
tosubset l a = mapReduce_list (eq a) l
mapReduce_list ret [] a = mapReduce_list (eq a) []
A: Type a0: A l: list A a: A IHl: mapReduce_list ret l a = mapReduce_list (eq a) l
mapReduce_list ret (a0 :: l) a =
mapReduce_list (eq a) (a0 :: l)
A: Type a: A
mapReduce_list ret [] a = mapReduce_list (eq a) []
reflexivity.
A: Type a0: A l: list A a: A IHl: mapReduce_list ret l a = mapReduce_list (eq a) l
mapReduce_list ret (a0 :: l) a =
mapReduce_list (eq a) (a0 :: l)
A: Type a0: A l: list A a: A IHl: mapReduce_list ret l a = mapReduce_list (eq a) l
(ret a0 ● mapReduce_list ret l) a =
mapReduce_list (eq a) (a0 :: l)
A: Type a0: A l: list A a: A IHl: mapReduce_list ret l a = mapReduce_list (eq a) l
(ret a0 ● mapReduce_list ret l) a =
(a = a0) ● mapReduce_list (eq a) l
A: Type a0: A l: list A a: A IHl: mapReduce_list ret l a = mapReduce_list (eq a) l
(ret a0 ● mapReduce_list ret l) a =
(a = a0) ● mapReduce_list ret l a
A: Type a0: A l: list A a: A IHl: mapReduce_list ret l a = mapReduce_list (eq a) l
(ret a0 ● mapReduce_list ret l) a =
(a0 = a) ● mapReduce_list ret l a
reflexivity.Qed.(** ** Rewriting Laws for <<mapReduce>> *)(**********************************************************************)SectionmapReduce_rw.Context
{AM: Type}
`{Monoid M}
(f: A -> M).
A, M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M f: A -> M
mapReduce f [] = Ƶ
A, M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M f: A -> M
mapReduce f [] = Ƶ
reflexivity.Qed.
A, M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M f: A -> M
forall (x : A) (xs : list A),
mapReduce f (x :: xs) = f x ● mapReduce f xs
A, M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M f: A -> M
forall (x : A) (xs : list A),
mapReduce f (x :: xs) = f x ● mapReduce f xs
A, M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M f: A -> M x: A xs: list A
mapReduce f (x :: xs) = f x ● mapReduce f xs
A, M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M f: A -> M x: A xs: list A
mapReduce_list f (x :: xs) = f x ● mapReduce_list f xs
A, M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M f: A -> M x: A xs: list A
f x ● mapReduce_list f xs = f x ● mapReduce_list f xs
reflexivity.Qed.
A, M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M f: A -> M a: A
mapReduce f [a] = f a
A, M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M f: A -> M a: A
mapReduce f [a] = f a
A, M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M f: A -> M a: A
mapReduce_list f [a] = f a
simpl_list; auto.Qed.
A, M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M f: A -> M
mapReduce f ∘ ret = f
A, M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M f: A -> M
mapReduce f ∘ ret = f
A, M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M f: A -> M
mapReduce_list f ∘ ret = f
A, M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M f: A -> M
f = f
reflexivity.Qed.
A, M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M f: A -> M
foralll1l2 : list A,
mapReduce f (l1 ++ l2) =
mapReduce f l1 ● mapReduce f l2
A, M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M f: A -> M
foralll1l2 : list A,
mapReduce f (l1 ++ l2) =
mapReduce f l1 ● mapReduce f l2
A, M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M f: A -> M l1, l2: list A
mapReduce f (l1 ++ l2) =
mapReduce f l1 ● mapReduce f l2
A, M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M f: A -> M l1, l2: list A
mapReduce_list f (l1 ++ l2) =
mapReduce_list f l1 ● mapReduce_list f l2
A, M: Type op: Monoid_op M unit0: Monoid_unit M H: Monoid M f: A -> M l1, l2: list A
mapReduce_list f l1 ● mapReduce_list f l2 =
mapReduce_list f l1 ● mapReduce_list f l2
reflexivity.Qed.EndmapReduce_rw.#[export] Hint Rewrite @mapReduce_nil @mapReduce_cons
@mapReduce_one @mapReduce_app: tea_list.
nowinversion1.Defined.Definitionzero_not_S {n} {anything}:
0 = S n -> anything :=
funpf => match pf with
| eq_refl =>
letfalse: False :=
eq_ind 0
(fune: nat => match e with
| 0 => True
| S _ => Falseend) I (S n) pf
in (False_rect anything false)
end.
forall (A : Type) (n : nat) (v : list A),
length v = S n ->
exists (a : A) (v' : list A), v = a :: v'
forall (A : Type) (n : nat) (v : list A),
length v = S n ->
exists (a : A) (v' : list A), v = a :: v'
A: Type n: nat v: list A vlen: length v = S n
exists (a : A) (v' : list A), v = a :: v'
A: Type n: nat vlen: length [] = S n
exists (a : A) (v' : list A), [] = a :: v'
A: Type n: nat a: A v: list A vlen: length (a :: v) = S n
exists (a0 : A) (v' : list A), a :: v = a0 :: v'
A: Type n: nat vlen: length [] = S n
exists (a : A) (v' : list A), [] = a :: v'
inversion vlen.
A: Type n: nat a: A v: list A vlen: length (a :: v) = S n
exists (a0 : A) (v' : list A), a :: v = a0 :: v'
A: Type n: nat a: A v: list A vlen: length (a :: v) = S n
a :: v = a :: v
reflexivity.Qed.Definitionlist_uncons {nA} (l: list A) (vlen: length l = S n):
A * list A :=
match l return (length l = S n -> A * list A) with
| nil => zero_not_S
| cons a rest => funvlen => (a, rest)
end vlen.Definitionlist_uncons_sigma {nA} (l: list A) (vlen: length l = S n):
A * {l: list A | length l = n} :=
match l return
(length l = S n -> A * {l: list A | length l = n})
with
| nil => zero_not_S
| cons hd tl => funvlen => (hd, exist _ tl (S_uncons vlen))
end vlen.Definitionlist_uncons_sigma2 {nA} (l: list A) (vlen: length l = S n):
{p: A * list A | l = uncurry cons p} :=
match l return
(length l = S n -> {p: A * list A | l = uncurry cons p})
with
| nil => zero_not_S
| cons hd tl => funvlen => exist _ (hd, tl) eq_refl
end vlen.(** ** Total Head and Tail Functions for Nonempty Lists *)(**********************************************************************)Definitionlist_hd {nA} :=
fun (l: list A) (vlen: length l = S n) =>
fst (list_uncons l vlen).Definitionlist_tl {nA} :=
fun (l: list A) (vlen: length l = S n) =>
snd (list_uncons l vlen).(** *** Proof irrelevance and rewriting laws *)(**********************************************************************)
n, m: nat A: Type l: list A vlen1: length l = S n vlen2: length l = S m
list_hd l vlen1 = list_hd l vlen2
n, m: nat A: Type l: list A vlen1: length l = S n vlen2: length l = S m
list_hd l vlen1 = list_hd l vlen2
n, m: nat A: Type vlen1: length [] = S n vlen2: length [] = S m
list_hd [] vlen1 = list_hd [] vlen2
n, m: nat A: Type a: A l: list A vlen1: length (a :: l) = S n vlen2: length (a :: l) = S m IHl: forall (vlen1 : length l = S n)
(vlen2 : length l = S m),
list_hd l vlen1 = list_hd l vlen2
list_hd (a :: l) vlen1 = list_hd (a :: l) vlen2
n, m: nat A: Type vlen1: length [] = S n vlen2: length [] = S m
list_hd [] vlen1 = list_hd [] vlen2
inversion vlen1.
n, m: nat A: Type a: A l: list A vlen1: length (a :: l) = S n vlen2: length (a :: l) = S m IHl: forall (vlen1 : length l = S n)
(vlen2 : length l = S m),
list_hd l vlen1 = list_hd l vlen2
list_hd (a :: l) vlen1 = list_hd (a :: l) vlen2
reflexivity.Qed.
n, m: nat A: Type l: list A vlen1: length l = S n vlen2: length l = S m
list_tl l vlen1 = list_tl l vlen2
n, m: nat A: Type l: list A vlen1: length l = S n vlen2: length l = S m
list_tl l vlen1 = list_tl l vlen2
n, m: nat A: Type vlen1: length [] = S n vlen2: length [] = S m
list_tl [] vlen1 = list_tl [] vlen2
n, m: nat A: Type a: A l: list A vlen1: length (a :: l) = S n vlen2: length (a :: l) = S m IHl: forall (vlen1 : length l = S n)
(vlen2 : length l = S m),
list_tl l vlen1 = list_tl l vlen2
list_tl (a :: l) vlen1 = list_tl (a :: l) vlen2
n, m: nat A: Type vlen1: length [] = S n vlen2: length [] = S m
list_tl [] vlen1 = list_tl [] vlen2
inversion vlen1.
n, m: nat A: Type a: A l: list A vlen1: length (a :: l) = S n vlen2: length (a :: l) = S m IHl: forall (vlen1 : length l = S n)
(vlen2 : length l = S m),
list_tl l vlen1 = list_tl l vlen2
list_tl (a :: l) vlen1 = list_tl (a :: l) vlen2
reflexivity.Qed.(** Rewrite a [list_hd] subterm by pushing a type coercion into the length proof *)
n: nat A: Type l1, l2: list A Heq: l1 = l2 vlen: length l1 = S n
list_hd l1 vlen =
list_hd l2
(rew [funl1 : list A => length l1 = S n] Heq in
vlen)
n: nat A: Type l1, l2: list A Heq: l1 = l2 vlen: length l1 = S n
list_hd l1 vlen =
list_hd l2
(rew [funl1 : list A => length l1 = S n] Heq in
vlen)
n: nat A: Type l2: list A vlen: length l2 = S n
list_hd l2 vlen =
list_hd l2
(rew [funl1 : list A => length l1 = S n] eq_refl in
vlen)
apply list_hd_proof_irrelevance.Qed.(** Rewrite a [list_tl] subterm by pushing a type coercion into the length proof *)
n: nat A: Type l1, l2: list A Heq: l1 = l2 vlen: length l1 = S n
list_tl l1 vlen =
list_tl l2
(rew [funl1 : list A => length l1 = S n] Heq in
vlen)
n: nat A: Type l1, l2: list A Heq: l1 = l2 vlen: length l1 = S n
list_tl l1 vlen =
list_tl l2
(rew [funl1 : list A => length l1 = S n] Heq in
vlen)
n: nat A: Type l2: list A vlen: length l2 = S n
list_tl l2 vlen =
list_tl l2
(rew [funl1 : list A => length l1 = S n] eq_refl in
vlen)
apply list_tl_proof_irrelevance.Qed.
n: nat A: Type l: list A vlen: length l = S n
length (list_tl l vlen) = n
n: nat A: Type l: list A vlen: length l = S n
length (list_tl l vlen) = n
n: nat A: Type vlen: length [] = S n
length (list_tl [] vlen) = n
n: nat A: Type a: A l: list A vlen: length (a :: l) = S n
length (list_tl (a :: l) vlen) = n
n: nat A: Type vlen: length [] = S n
length (list_tl [] vlen) = n
inversion vlen.
n: nat A: Type a: A l: list A vlen: length (a :: l) = S n
length (list_tl (a :: l) vlen) = n
n: nat A: Type a: A l: list A vlen: length (a :: l) = S n
n: nat A: Type a: A l: list A vlen: length (a :: l) = S n
list_uncons (a :: l) vlen =
(list_hd (a :: l) vlen, list_tl (a :: l) vlen)
reflexivity.Qed.
n: nat A: Type l: list A vlen: length l = S n
l = list_hd l vlen :: list_tl l vlen
n: nat A: Type l: list A vlen: length l = S n
l = list_hd l vlen :: list_tl l vlen
n: nat A: Type vlen: length [] = S n
[] = list_hd [] vlen :: list_tl [] vlen
n: nat A: Type a: A l: list A vlen: length (a :: l) = S n
a :: l =
list_hd (a :: l) vlen :: list_tl (a :: l) vlen
n: nat A: Type vlen: length [] = S n
[] = list_hd [] vlen :: list_tl [] vlen
inversion vlen.
n: nat A: Type a: A l: list A vlen: length (a :: l) = S n
a :: l =
list_hd (a :: l) vlen :: list_tl (a :: l) vlen
reflexivity.Qed.(** * Filtering Lists *)(**********************************************************************)Fixpointfilter `(P: A -> bool) (l: list A): list A :=
match l with
| nil => nil
| cons a rest =>
if P a then a :: filter P rest else filter P rest
end.(** ** Rewriting Laws for [filter] *)(**********************************************************************)Sectionfilter_lemmas.Context
`(P: A -> bool).
A: Type P: A -> bool
filter P [] = []
A: Type P: A -> bool
filter P [] = []
reflexivity.Qed.
A: Type P: A -> bool
forall (a : A) (l : list A),
filter P (a :: l) =
(if P a then a :: filter P l else filter P l)
A: Type P: A -> bool
forall (a : A) (l : list A),
filter P (a :: l) =
(if P a then a :: filter P l else filter P l)
reflexivity.Qed.
A: Type P: A -> bool
foralla : A, filter P [a] = (if P a then [a] else [])
A: Type P: A -> bool
foralla : A, filter P [a] = (if P a then [a] else [])
reflexivity.Qed.
A: Type P: A -> bool
foralll1l2 : list A,
filter P (l1 ++ l2) = filter P l1 ++ filter P l2
A: Type P: A -> bool
foralll1l2 : list A,
filter P (l1 ++ l2) = filter P l1 ++ filter P l2
A: Type P: A -> bool l1, l2: list A
filter P (l1 ++ l2) = filter P l1 ++ filter P l2
A: Type P: A -> bool l2: list A
filter P ([] ++ l2) = filter P [] ++ filter P l2
A: Type P: A -> bool a: A l1, l2: list A IHl1: filter P (l1 ++ l2) =
filter P l1 ++ filter P l2
filter P ((a :: l1) ++ l2) =
filter P (a :: l1) ++ filter P l2
A: Type P: A -> bool l2: list A
filter P ([] ++ l2) = filter P [] ++ filter P l2
reflexivity.
A: Type P: A -> bool a: A l1, l2: list A IHl1: filter P (l1 ++ l2) =
filter P l1 ++ filter P l2
filter P ((a :: l1) ++ l2) =
filter P (a :: l1) ++ filter P l2
A: Type P: A -> bool a: A l1, l2: list A IHl1: filter P (l1 ++ l2) =
filter P l1 ++ filter P l2
(if P a
then a :: filter P (l1 ++ l2)
else filter P (l1 ++ l2)) =
(if P a then a :: filter P l1 else filter P l1) ++
filter P l2
A: Type P: A -> bool a: A l1, l2: list A IHl1: filter P (l1 ++ l2) =
filter P l1 ++ filter P l2
(if P a
then a :: filter P l1 ++ filter P l2
else filter P l1 ++ filter P l2) =
(if P a then a :: filter P l1 else filter P l1) ++
filter P l2
nowdestruct (P a).Qed.Endfilter_lemmas.#[export] Hint Rewrite
@filter_nil @filter_cons @filter_app @filter_one: tea_list.