Built with Alectryon, running Coq+SerAPI v8.10.0+0.7.0. Coq sources are in this panel; goals and messages will appear in the other. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑ Ctrl+↓ to navigate, Ctrl+🖱️ to focus.
(************************************************************************)
(*         *   The Coq Proof Assistant / The Coq Development Team       *)
(*  v      *   INRIA, CNRS and contributors - Copyright 1999-2018       *)
(* <O___,, *       (see CREDITS file for the list of authors)           *)
(*   \VV/  **************************************************************)
(*    //   *    This file is distributed under the terms of the         *)
(*         *     GNU Lesser General Public License Version 2.1          *)
(*         *     (see LICENSE file for the text of the license)         *)
(************************************************************************)

Require Export List.
Require Export Sorted.
Require Export Setoid Basics Morphisms.
Set Implicit Arguments.
Unset Strict Implicit.
(* Set Universe Polymorphism. *)

Logical relations over lists with respect to a setoid equality

or ordering.
This can be seen as a complement of predicate lelistA and sort found in Sorting.
Section Type_with_equality.
Variable A : Type.
Variable eqA : A -> A -> Prop.
Being in a list modulo an equality relation over type A.
Inductive InA (x : A) : list A -> Prop :=
  | InA_cons_hd : forall y l, eqA x y -> InA x (y :: l)
  | InA_cons_tl : forall y l, InA x l -> InA x (y :: l).

Hint Constructors InA : core.
TODO: it would be nice to have a generic definition instead of the previous one. Having InA = Exists eqA raises too many compatibility issues. For now, we only state the equivalence:
A:Type
eqA:A -> A -> Prop

forall (x : A) (l : list A), InA x l <-> Exists (eqA x) l
A:Type
eqA:A -> A -> Prop

forall (x : A) (l : list A), InA x l <-> Exists (eqA x) l
split; induction 1; auto. Qed.
A:Type
eqA:A -> A -> Prop

forall (x y : A) (l : list A), InA x (y :: l) <-> eqA x y \/ InA x l
A:Type
eqA:A -> A -> Prop

forall (x y : A) (l : list A), InA x (y :: l) <-> eqA x y \/ InA x l
A:Type
eqA:A -> A -> Prop
x, y:A
l:list A
H:InA x (y :: l)

eqA x y \/ InA x l
invlist InA; auto. Qed.
A:Type
eqA:A -> A -> Prop

forall x : A, InA x nil <-> False
A:Type
eqA:A -> A -> Prop

forall x : A, InA x nil <-> False
A:Type
eqA:A -> A -> Prop
x:A
H:InA x nil

False
invlist InA. Qed.
An alternative definition of InA.
A:Type
eqA:A -> A -> Prop

forall (x : A) (l : list A), InA x l <-> (exists y : A, eqA x y /\ In y l)
A:Type
eqA:A -> A -> Prop

forall (x : A) (l : list A), InA x l <-> (exists y : A, eqA x y /\ In y l)
intros; rewrite InA_altdef, Exists_exists; firstorder. Qed.
A list without redundancy modulo the equality over A.
Inductive NoDupA : list A -> Prop :=
  | NoDupA_nil : NoDupA nil
  | NoDupA_cons : forall x l, ~ InA x l -> NoDupA l -> NoDupA (x::l).

Hint Constructors NoDupA : core.
An alternative definition of NoDupA based on ForallOrdPairs
A:Type
eqA:A -> A -> Prop

forall l : list A, NoDupA l <-> ForallOrdPairs (complement eqA) l
A:Type
eqA:A -> A -> Prop

forall l : list A, NoDupA l <-> ForallOrdPairs (complement eqA) l
A:Type
eqA:A -> A -> Prop
x:A
l:list A
H:~ InA x l
H0:NoDupA l
IHNoDupA:ForallOrdPairs (complement eqA) l

Forall (complement eqA x) l
A:Type
eqA:A -> A -> Prop
a:A
l:list A
H:Forall (complement eqA a) l
H0:ForallOrdPairs (complement eqA) l
IHForallOrdPairs:NoDupA l
~ InA a l
A:Type
eqA:A -> A -> Prop
x:A
l:list A
H:~ InA x l
H0:NoDupA l
IHNoDupA:ForallOrdPairs (complement eqA) l

forall x0 : A, In x0 l -> complement eqA x x0
A:Type
eqA:A -> A -> Prop
a:A
l:list A
H:Forall (complement eqA a) l
H0:ForallOrdPairs (complement eqA) l
IHForallOrdPairs:NoDupA l
~ InA a l
A:Type
eqA:A -> A -> Prop
x:A
l:list A
H:~ InA x l
H0:NoDupA l
IHNoDupA:ForallOrdPairs (complement eqA) l
b:A
Hb:In b l

complement eqA x b
A:Type
eqA:A -> A -> Prop
a:A
l:list A
H:Forall (complement eqA a) l
H0:ForallOrdPairs (complement eqA) l
IHForallOrdPairs:NoDupA l
~ InA a l
A:Type
eqA:A -> A -> Prop
x:A
l:list A
H:~ InA x l
H0:NoDupA l
IHNoDupA:ForallOrdPairs (complement eqA) l
b:A
Hb:In b l
Eq:eqA x b

InA x l
A:Type
eqA:A -> A -> Prop
a:A
l:list A
H:Forall (complement eqA a) l
H0:ForallOrdPairs (complement eqA) l
IHForallOrdPairs:NoDupA l
~ InA a l
A:Type
eqA:A -> A -> Prop
x:A
l:list A
H:~ InA x l
H0:NoDupA l
IHNoDupA:ForallOrdPairs (complement eqA) l
b:A
Hb:In b l
Eq:eqA x b

exists y : A, eqA x y /\ In y l
A:Type
eqA:A -> A -> Prop
a:A
l:list A
H:Forall (complement eqA a) l
H0:ForallOrdPairs (complement eqA) l
IHForallOrdPairs:NoDupA l
~ InA a l
A:Type
eqA:A -> A -> Prop
a:A
l:list A
H:Forall (complement eqA a) l
H0:ForallOrdPairs (complement eqA) l
IHForallOrdPairs:NoDupA l

~ InA a l
A:Type
eqA:A -> A -> Prop
a:A
l:list A
H:Forall (complement eqA a) l
H0:ForallOrdPairs (complement eqA) l
IHForallOrdPairs:NoDupA l
a':A
Haa':eqA a a'
Ha':In a' l

False
A:Type
eqA:A -> A -> Prop
a:A
l:list A
H:forall x : A, In x l -> complement eqA a x
H0:ForallOrdPairs (complement eqA) l
IHForallOrdPairs:NoDupA l
a':A
Haa':eqA a a'
Ha':In a' l

False
exact (H a' Ha' Haa'). Qed.
lists with same elements modulo eqA
Definition inclA l l' := forall x, InA x l -> InA x l'.
Definition equivlistA l l' := forall x, InA x l <-> InA x l'.

A:Type
eqA:A -> A -> Prop
l:list A

inclA nil l
A:Type
eqA:A -> A -> Prop
l:list A

inclA nil l
A:Type
eqA:A -> A -> Prop
l:list A
x:A

InA x nil -> InA x l
A:Type
eqA:A -> A -> Prop
l:list A
x:A
H:InA x nil

InA x l
inversion H. Qed. Hint Resolve incl_nil : list.
lists with same elements modulo eqA at the same place
Inductive eqlistA : list A -> list A -> Prop :=
  | eqlistA_nil : eqlistA nil nil
  | eqlistA_cons : forall x x' l l',
      eqA x x' -> eqlistA l l' -> eqlistA (x::l) (x'::l').

Hint Constructors eqlistA : core.
We could also have written eqlistA = Forall2 eqA.
A:Type
eqA:A -> A -> Prop

forall l l' : list A, eqlistA l l' <-> Forall2 eqA l l'
A:Type
eqA:A -> A -> Prop

forall l l' : list A, eqlistA l l' <-> Forall2 eqA l l'
split; induction 1; auto. Qed.
Results concerning lists modulo eqA
Hypothesis eqA_equiv : Equivalence eqA.
Definition eqarefl := (@Equivalence_Reflexive _ _ eqA_equiv).
Definition eqatrans := (@Equivalence_Transitive _ _ eqA_equiv).
Definition eqasym := (@Equivalence_Symmetric _ _ eqA_equiv).
 
Hint Resolve eqarefl eqatrans : core.
Hint Immediate eqasym : core.

Ltac inv := invlist InA; invlist sort; invlist lelistA; invlist NoDupA.
First, the two notions equivlistA and eqlistA are indeed equivlances
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA

Equivalence equivlistA
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA

Equivalence equivlistA
firstorder. Qed.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA

Equivalence eqlistA
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA

Equivalence eqlistA
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA

forall x : list A, eqlistA x x
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
forall x y : list A, eqlistA x y -> eqlistA y x
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
forall x y z : list A, eqlistA x y -> eqlistA y z -> eqlistA x z
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA

forall x y : list A, eqlistA x y -> eqlistA y x
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
forall x y z : list A, eqlistA x y -> eqlistA y z -> eqlistA x z
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA

forall x y z : list A, eqlistA x y -> eqlistA y z -> eqlistA x z
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
x, x':A
l, l':list A
H:eqA x x'
H0:eqlistA l l'
IHeqlistA:forall z : list A, eqlistA l' z -> eqlistA l z

forall z : list A, eqlistA (x' :: l') z -> eqlistA (x :: l) z
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
x, x':A
l, l':list A
H:eqA x x'
H0:eqlistA l l'
IHeqlistA:forall z : list A, eqlistA l' z -> eqlistA l z
x'0:A
l'0:list A
H1:eqlistA (x' :: l') (x'0 :: l'0)
H4:eqA x' x'0
H6:eqlistA l' l'0

eqlistA (x :: l) (x'0 :: l'0)
invlist eqlistA; eauto with *. Qed.
Moreover, eqlistA implies equivlistA. A reverse result will be proved later for sorted list without duplicates.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA

subrelation eqlistA equivlistA
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA

subrelation eqlistA equivlistA
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
x, x':list A
H:eqlistA x x'

equivlistA x x'
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA

equivlistA nil nil
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
x, x':A
l, l':list A
H:eqA x x'
H0:eqlistA l l'
IHeqlistA:equivlistA l l'
equivlistA (x :: l) (x' :: l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
x, x':A
l, l':list A
H:eqA x x'
H0:eqlistA l l'
IHeqlistA:equivlistA l l'

equivlistA (x :: l) (x' :: l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
x, x':A
l, l':list A
H:eqA x x'
H0:eqlistA l l'
IHeqlistA:equivlistA l l'
x0:A

InA x0 (x :: l) <-> InA x0 (x' :: l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
x, x':A
l, l':list A
H:eqA x x'
H0:eqlistA l l'
IHeqlistA:equivlistA l l'
x0:A

eqA x0 x \/ InA x0 l <-> eqA x0 x' \/ InA x0 l'
rewrite (IHeqlistA x0), H; intuition. Qed.
InA is compatible with eqA (for its first arg) and with equivlistA (and hence eqlistA) for its second arg
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA

Proper (eqA ==> equivlistA ==> iff) InA
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA

Proper (eqA ==> equivlistA ==> iff) InA
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
x, x':A
Hxx':eqA x x'
l, l':list A
Hll':equivlistA l l'

InA x l <-> InA x' l'
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
x, x':A
Hxx':eqA x x'
l, l':list A
Hll':equivlistA l l'

InA x l' <-> InA x' l'
rewrite 2 InA_alt; firstorder. Qed.
For compatibility, an immediate consequence of InA_compat
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA

forall (l : list A) (x y : A), eqA x y -> InA x l -> InA y l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA

forall (l : list A) (x y : A), eqA x y -> InA x l -> InA y l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
l:list A
x, y:A
H:eqA x y
H':InA x l

InA y l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
l:list A
x, y:A
H:eqA x y
H':InA x l

InA x l
auto. Qed. Hint Immediate InA_eqA : core.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA

forall (l : list A) (x : A), In x l -> InA x l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA

forall (l : list A) (x : A), In x l -> InA x l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
l:list A
a:A
l0:list A
H:forall x0 : A, In x0 l0 -> InA x0 l0
x:A
H1:a = x

InA x (a :: l0)
subst; auto. Qed. Hint Resolve In_InA : core.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA

forall (l : list A) (x : A), InA x l -> exists (l1 : list A) (y : A) (l2 : list A), eqA x y /\ l = l1 ++ y :: l2
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA

forall (l : list A) (x : A), InA x l -> exists (l1 : list A) (y : A) (l2 : list A), eqA x y /\ l = l1 ++ y :: l2
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall x0 : A, InA x0 l -> exists (l1 : list A) (y : A) (l2 : list A), eqA x0 y /\ l = l1 ++ y :: l2
x:A
H0:eqA x a

exists (l1 : list A) (y : A) (l2 : list A), eqA x y /\ a :: l = l1 ++ y :: l2
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall x0 : A, InA x0 l -> exists (l1 : list A) (y : A) (l2 : list A), eqA x0 y /\ l = l1 ++ y :: l2
x:A
H0:InA x l
exists (l1 : list A) (y : A) (l2 : list A), eqA x y /\ a :: l = l1 ++ y :: l2
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall x0 : A, InA x0 l -> exists (l1 : list A) (y : A) (l2 : list A), eqA x0 y /\ l = l1 ++ y :: l2
x:A
H0:InA x l

exists (l1 : list A) (y : A) (l2 : list A), eqA x y /\ a :: l = l1 ++ y :: l2
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall x0 : A, InA x0 l -> exists (l0 : list A) (y0 : A) (l3 : list A), eqA x0 y0 /\ l = l0 ++ y0 :: l3
x:A
H0:InA x l
l1:list A
y:A
l2:list A
H1:eqA x y
H2:l = l1 ++ y :: l2

exists (l0 : list A) (y0 : A) (l3 : list A), eqA x y0 /\ a :: l = l0 ++ y0 :: l3
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall x0 : A, InA x0 l -> exists (l0 : list A) (y0 : A) (l3 : list A), eqA x0 y0 /\ l = l0 ++ y0 :: l3
x:A
H0:InA x l
l1:list A
y:A
l2:list A
H1:eqA x y
H2:l = l1 ++ y :: l2

eqA x y /\ a :: l = (a :: l1) ++ y :: l2
split; simpl; f_equal; auto. Qed.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA

forall (l1 l2 : list A) (x : A), InA x (l1 ++ l2) -> InA x l1 \/ InA x l2
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA

forall (l1 l2 : list A) (x : A), InA x (l1 ++ l2) -> InA x l1 \/ InA x l2
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l1:list A
IHl1:forall (l0 : list A) (x0 : A), InA x0 (l1 ++ l0) -> InA x0 l1 \/ InA x0 l0
l2:list A
x:A
H:InA x (a :: l1 ++ l2)

InA x (a :: l1) \/ InA x l2
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l1:list A
IHl1:forall (l0 : list A) (x0 : A), InA x0 (l1 ++ l0) -> InA x0 l1 \/ InA x0 l0
l2:list A
x:A
H0:InA x (l1 ++ l2)

InA x (a :: l1) \/ InA x l2
elim (IHl1 l2 x H0); auto. Qed.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA

forall (l1 l2 : list A) (x : A), InA x (l1 ++ l2) <-> InA x l1 \/ InA x l2
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA

forall (l1 l2 : list A) (x : A), InA x (l1 ++ l2) <-> InA x l1 \/ InA x l2
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
l1, l2:list A
x:A

InA x (l1 ++ l2) -> InA x l1 \/ InA x l2
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
l1, l2:list A
x:A
InA x l1 \/ InA x l2 -> InA x (l1 ++ l2)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
l1, l2:list A
x:A

InA x l1 \/ InA x l2 -> InA x (l1 ++ l2)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
l1, l2:list A
x:A
H:InA x l1

(exists y : A, eqA x y /\ In y l1) -> exists y : A, eqA x y /\ In y (l1 ++ l2)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
l1, l2:list A
x:A
H:InA x l2
(exists y : A, eqA x y /\ In y l2) -> exists y : A, eqA x y /\ In y (l1 ++ l2)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
l1, l2:list A
x:A
H:InA x l1
y:A
H1:eqA x y
H2:In y l1

In y (l1 ++ l2)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
l1, l2:list A
x:A
H:InA x l2
(exists y : A, eqA x y /\ In y l2) -> exists y : A, eqA x y /\ In y (l1 ++ l2)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
l1, l2:list A
x:A
H:InA x l2

(exists y : A, eqA x y /\ In y l2) -> exists y : A, eqA x y /\ In y (l1 ++ l2)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
l1, l2:list A
x:A
H:InA x l2
y:A
H1:eqA x y
H2:In y l2

In y (l1 ++ l2)
apply in_or_app; auto. Qed.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA

forall (p : A) (m : list A), InA p (rev m) <-> InA p m
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA

forall (p : A) (m : list A), InA p (rev m) <-> InA p m
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
p:A
m:list A

(exists y : A, eqA p y /\ In y (rev m)) <-> (exists y : A, eqA p y /\ In y m)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
p:A
m:list A
y:A
H0:eqA p y
H1:In y (rev m)

In y m
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
p:A
m:list A
y:A
H0:eqA p y
H1:In y m
In y (rev m)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
p:A
m:list A
y:A
H0:eqA p y
H1:In y m

In y (rev m)
rewrite <- In_rev; auto. Qed.
Some more facts about InA
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
x, y:A

InA x (y :: nil) <-> eqA x y
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
x, y:A

InA x (y :: nil) <-> eqA x y
rewrite InA_cons, InA_nil; tauto. Qed.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
x, y:A
l:list A

InA x (y :: y :: l) <-> InA x (y :: l)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
x, y:A
l:list A

InA x (y :: y :: l) <-> InA x (y :: l)
rewrite !InA_cons; tauto. Qed.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
x, y, z:A
l:list A

InA x (y :: z :: l) <-> InA x (z :: y :: l)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
x, y, z:A
l:list A

InA x (y :: z :: l) <-> InA x (z :: y :: l)
rewrite !InA_cons; tauto. Qed.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
x:A
l:list A

InA x (l ++ l) <-> InA x l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
x:A
l:list A

InA x (l ++ l) <-> InA x l
rewrite InA_app_iff; tauto. Qed. Section NoDupA.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA

forall l l' : list A, NoDupA l -> NoDupA l' -> (forall x : A, InA x l -> InA x l' -> False) -> NoDupA (l ++ l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA

forall l l' : list A, NoDupA l -> NoDupA l' -> (forall x : A, InA x l -> InA x l' -> False) -> NoDupA (l ++ l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall l'0 : list A, NoDupA l -> NoDupA l'0 -> (forall x : A, InA x l -> InA x l'0 -> False) -> NoDupA (l ++ l'0)
l':list A
H:NoDupA (a :: l)
H0:NoDupA l'
H1:forall x : A, InA x (a :: l) -> InA x l' -> False

NoDupA (a :: l ++ l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall l'0 : list A, NoDupA l -> NoDupA l'0 -> (forall x : A, InA x l -> InA x l'0 -> False) -> NoDupA (l ++ l'0)
l':list A
H0:NoDupA l'
H1:forall x : A, InA x (a :: l) -> InA x l' -> False
H2:~ InA a l
H3:NoDupA l

NoDupA (a :: l ++ l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall l'0 : list A, NoDupA l -> NoDupA l'0 -> (forall x : A, InA x l -> InA x l'0 -> False) -> NoDupA (l ++ l'0)
l':list A
H0:NoDupA l'
H1:forall x : A, InA x (a :: l) -> InA x l' -> False
H2:~ InA a l
H3:NoDupA l

~ InA a (l ++ l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall l'0 : list A, NoDupA l -> NoDupA l'0 -> (forall x : A, InA x l -> InA x l'0 -> False) -> NoDupA (l ++ l'0)
l':list A
H0:NoDupA l'
H1:forall x : A, InA x (a :: l) -> InA x l' -> False
H2:~ InA a l
H3:NoDupA l
NoDupA (l ++ l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall l'0 : list A, NoDupA l -> NoDupA l'0 -> (forall x : A, InA x l -> InA x l'0 -> False) -> NoDupA (l ++ l'0)
l':list A
H0:NoDupA l'
H1:forall x : A, InA x (a :: l) -> InA x l' -> False
H2:~ InA a l
H3:NoDupA l
y:A
H4:eqA a y
H5:In y (l ++ l')

False
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall l'0 : list A, NoDupA l -> NoDupA l'0 -> (forall x : A, InA x l -> InA x l'0 -> False) -> NoDupA (l ++ l'0)
l':list A
H0:NoDupA l'
H1:forall x : A, InA x (a :: l) -> InA x l' -> False
H2:~ InA a l
H3:NoDupA l
NoDupA (l ++ l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall l'0 : list A, NoDupA l -> NoDupA l'0 -> (forall x : A, InA x l -> InA x l'0 -> False) -> NoDupA (l ++ l'0)
l':list A
H0:NoDupA l'
H1:forall x : A, InA x (a :: l) -> InA x l' -> False
H2:~ InA a l
H3:NoDupA l
y:A
H4:eqA a y
H5:In y (l ++ l')
H:In y l

False
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall l'0 : list A, NoDupA l -> NoDupA l'0 -> (forall x : A, InA x l -> InA x l'0 -> False) -> NoDupA (l ++ l'0)
l':list A
H0:NoDupA l'
H1:forall x : A, InA x (a :: l) -> InA x l' -> False
H2:~ InA a l
H3:NoDupA l
y:A
H4:eqA a y
H5:In y (l ++ l')
H:In y l'
False
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall l'0 : list A, NoDupA l -> NoDupA l'0 -> (forall x : A, InA x l -> InA x l'0 -> False) -> NoDupA (l ++ l'0)
l':list A
H0:NoDupA l'
H1:forall x : A, InA x (a :: l) -> InA x l' -> False
H2:~ InA a l
H3:NoDupA l
NoDupA (l ++ l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall l'0 : list A, NoDupA l -> NoDupA l'0 -> (forall x : A, InA x l -> InA x l'0 -> False) -> NoDupA (l ++ l'0)
l':list A
H0:NoDupA l'
H1:forall x : A, InA x (a :: l) -> InA x l' -> False
H2:~ InA a l
H3:NoDupA l
y:A
H4:eqA a y
H5:In y (l ++ l')
H:In y l

InA a l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall l'0 : list A, NoDupA l -> NoDupA l'0 -> (forall x : A, InA x l -> InA x l'0 -> False) -> NoDupA (l ++ l'0)
l':list A
H0:NoDupA l'
H1:forall x : A, InA x (a :: l) -> InA x l' -> False
H2:~ InA a l
H3:NoDupA l
y:A
H4:eqA a y
H5:In y (l ++ l')
H:In y l'
False
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall l'0 : list A, NoDupA l -> NoDupA l'0 -> (forall x : A, InA x l -> InA x l'0 -> False) -> NoDupA (l ++ l'0)
l':list A
H0:NoDupA l'
H1:forall x : A, InA x (a :: l) -> InA x l' -> False
H2:~ InA a l
H3:NoDupA l
NoDupA (l ++ l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall l'0 : list A, NoDupA l -> NoDupA l'0 -> (forall x : A, InA x l -> InA x l'0 -> False) -> NoDupA (l ++ l'0)
l':list A
H0:NoDupA l'
H1:forall x : A, InA x (a :: l) -> InA x l' -> False
H2:~ InA a l
H3:NoDupA l
y:A
H4:eqA a y
H5:In y (l ++ l')
H:In y l

exists y0 : A, eqA a y0 /\ In y0 l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall l'0 : list A, NoDupA l -> NoDupA l'0 -> (forall x : A, InA x l -> InA x l'0 -> False) -> NoDupA (l ++ l'0)
l':list A
H0:NoDupA l'
H1:forall x : A, InA x (a :: l) -> InA x l' -> False
H2:~ InA a l
H3:NoDupA l
y:A
H4:eqA a y
H5:In y (l ++ l')
H:In y l'
False
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall l'0 : list A, NoDupA l -> NoDupA l'0 -> (forall x : A, InA x l -> InA x l'0 -> False) -> NoDupA (l ++ l'0)
l':list A
H0:NoDupA l'
H1:forall x : A, InA x (a :: l) -> InA x l' -> False
H2:~ InA a l
H3:NoDupA l
NoDupA (l ++ l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall l'0 : list A, NoDupA l -> NoDupA l'0 -> (forall x : A, InA x l -> InA x l'0 -> False) -> NoDupA (l ++ l'0)
l':list A
H0:NoDupA l'
H1:forall x : A, InA x (a :: l) -> InA x l' -> False
H2:~ InA a l
H3:NoDupA l
y:A
H4:eqA a y
H5:In y (l ++ l')
H:In y l'

False
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall l'0 : list A, NoDupA l -> NoDupA l'0 -> (forall x : A, InA x l -> InA x l'0 -> False) -> NoDupA (l ++ l'0)
l':list A
H0:NoDupA l'
H1:forall x : A, InA x (a :: l) -> InA x l' -> False
H2:~ InA a l
H3:NoDupA l
NoDupA (l ++ l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall l'0 : list A, NoDupA l -> NoDupA l'0 -> (forall x : A, InA x l -> InA x l'0 -> False) -> NoDupA (l ++ l'0)
l':list A
H0:NoDupA l'
H1:forall x : A, InA x (a :: l) -> InA x l' -> False
H2:~ InA a l
H3:NoDupA l
y:A
H4:eqA a y
H5:In y (l ++ l')
H:In y l'

InA a (a :: l)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall l'0 : list A, NoDupA l -> NoDupA l'0 -> (forall x : A, InA x l -> InA x l'0 -> False) -> NoDupA (l ++ l'0)
l':list A
H0:NoDupA l'
H1:forall x : A, InA x (a :: l) -> InA x l' -> False
H2:~ InA a l
H3:NoDupA l
y:A
H4:eqA a y
H5:In y (l ++ l')
H:In y l'
InA a l'
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall l'0 : list A, NoDupA l -> NoDupA l'0 -> (forall x : A, InA x l -> InA x l'0 -> False) -> NoDupA (l ++ l'0)
l':list A
H0:NoDupA l'
H1:forall x : A, InA x (a :: l) -> InA x l' -> False
H2:~ InA a l
H3:NoDupA l
NoDupA (l ++ l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall l'0 : list A, NoDupA l -> NoDupA l'0 -> (forall x : A, InA x l -> InA x l'0 -> False) -> NoDupA (l ++ l'0)
l':list A
H0:NoDupA l'
H1:forall x : A, InA x (a :: l) -> InA x l' -> False
H2:~ InA a l
H3:NoDupA l
y:A
H4:eqA a y
H5:In y (l ++ l')
H:In y l'

InA a l'
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall l'0 : list A, NoDupA l -> NoDupA l'0 -> (forall x : A, InA x l -> InA x l'0 -> False) -> NoDupA (l ++ l'0)
l':list A
H0:NoDupA l'
H1:forall x : A, InA x (a :: l) -> InA x l' -> False
H2:~ InA a l
H3:NoDupA l
NoDupA (l ++ l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall l'0 : list A, NoDupA l -> NoDupA l'0 -> (forall x : A, InA x l -> InA x l'0 -> False) -> NoDupA (l ++ l'0)
l':list A
H0:NoDupA l'
H1:forall x : A, InA x (a :: l) -> InA x l' -> False
H2:~ InA a l
H3:NoDupA l
y:A
H4:eqA a y
H5:In y (l ++ l')
H:In y l'

exists y0 : A, eqA a y0 /\ In y0 l'
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall l'0 : list A, NoDupA l -> NoDupA l'0 -> (forall x : A, InA x l -> InA x l'0 -> False) -> NoDupA (l ++ l'0)
l':list A
H0:NoDupA l'
H1:forall x : A, InA x (a :: l) -> InA x l' -> False
H2:~ InA a l
H3:NoDupA l
NoDupA (l ++ l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall l'0 : list A, NoDupA l -> NoDupA l'0 -> (forall x : A, InA x l -> InA x l'0 -> False) -> NoDupA (l ++ l'0)
l':list A
H0:NoDupA l'
H1:forall x : A, InA x (a :: l) -> InA x l' -> False
H2:~ InA a l
H3:NoDupA l

NoDupA (l ++ l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall l'0 : list A, NoDupA l -> NoDupA l'0 -> (forall x : A, InA x l -> InA x l'0 -> False) -> NoDupA (l ++ l'0)
l':list A
H0:NoDupA l'
H1:forall x : A, InA x (a :: l) -> InA x l' -> False
H2:~ InA a l
H3:NoDupA l

forall x : A, InA x l -> InA x l' -> False
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall l'0 : list A, NoDupA l -> NoDupA l'0 -> (forall x0 : A, InA x0 l -> InA x0 l'0 -> False) -> NoDupA (l ++ l'0)
l':list A
H0:NoDupA l'
H1:forall x0 : A, InA x0 (a :: l) -> InA x0 l' -> False
H2:~ InA a l
H3:NoDupA l
x:A
H:InA x l
H4:InA x l'

False
apply (H1 x); auto. Qed.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA

forall l : list A, NoDupA l -> NoDupA (rev l)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA

forall l : list A, NoDupA l -> NoDupA (rev l)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA

NoDupA nil -> NoDupA (rev nil)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:NoDupA l -> NoDupA (rev l)
NoDupA (a :: l) -> NoDupA (rev (a :: l))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:NoDupA l -> NoDupA (rev l)

NoDupA (a :: l) -> NoDupA (rev (a :: l))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:NoDupA l -> NoDupA (rev l)
H:NoDupA (a :: l)

NoDupA (rev l ++ a :: nil)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:NoDupA l -> NoDupA (rev l)
H0:~ InA a l
H1:NoDupA l

NoDupA (rev l ++ a :: nil)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:NoDupA l -> NoDupA (rev l)
H0:~ InA a l
H1:NoDupA l

NoDupA (a :: nil)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:NoDupA l -> NoDupA (rev l)
H0:~ InA a l
H1:NoDupA l
forall x : A, InA x (rev l) -> InA x (a :: nil) -> False
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:NoDupA l -> NoDupA (rev l)
H0:~ InA a l
H1:NoDupA l

~ InA a nil
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:NoDupA l -> NoDupA (rev l)
H0:~ InA a l
H1:NoDupA l
forall x : A, InA x (rev l) -> InA x (a :: nil) -> False
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:NoDupA l -> NoDupA (rev l)
H0:~ InA a l
H1:NoDupA l

forall x : A, InA x (rev l) -> InA x (a :: nil) -> False
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:NoDupA l -> NoDupA (rev l)
H0:~ InA a l
H1:NoDupA l
x:A

InA x (rev l) -> InA x (a :: nil) -> False
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:NoDupA l -> NoDupA (rev l)
H0:~ InA a l
H1:NoDupA l
x:A

(exists y : A, eqA x y /\ In y (rev l)) -> InA x (a :: nil) -> False
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:NoDupA l -> NoDupA (rev l)
H0:~ InA a l
H1:NoDupA l
x, x1:A
H2:eqA x x1
H3:In x1 (rev l)

InA x (a :: nil) -> False
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:NoDupA l -> NoDupA (rev l)
H0:~ InA a l
H1:NoDupA l
x, x1:A
H2:eqA x x1
H3:In x1 (rev l)
H4:eqA x a

False
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:NoDupA l -> NoDupA (rev l)
H1:NoDupA l
x, x1:A
H2:eqA x x1
H3:In x1 (rev l)
H4:eqA x a

InA a l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:NoDupA l -> NoDupA (rev l)
H1:NoDupA l
x, x1:A
H2:eqA x x1
H3:In x1 (rev l)
H4:eqA x a

InA x1 l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:NoDupA l -> NoDupA (rev l)
H1:NoDupA l
x, x1:A
H2:eqA x x1
H3:In x1 (rev l)
H4:eqA x a

In x1 l
rewrite In_rev; auto. Qed.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA

forall (l l' : list A) (x : A), NoDupA (l ++ x :: l') -> NoDupA (l ++ l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA

forall (l l' : list A) (x : A), NoDupA (l ++ x :: l') -> NoDupA (l ++ l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall (l'0 : list A) (x0 : A), NoDupA (l ++ x0 :: l'0) -> NoDupA (l ++ l'0)
l':list A
x:A
H0:~ InA a (l ++ x :: l')
H1:NoDupA (l ++ x :: l')

NoDupA (a :: l ++ l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall (l'0 : list A) (x0 : A), NoDupA (l ++ x0 :: l'0) -> NoDupA (l ++ l'0)
l':list A
x:A
H0:~ InA a (l ++ x :: l')
H1:NoDupA (l ++ x :: l')

~ InA a (l ++ l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall (l'0 : list A) (x0 : A), NoDupA (l ++ x0 :: l'0) -> NoDupA (l ++ l'0)
l':list A
x:A
H1:NoDupA (l ++ x :: l')
H0:InA a (l ++ l')

InA a (l ++ x :: l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall (l'0 : list A) (x0 : A), NoDupA (l ++ x0 :: l'0) -> NoDupA (l ++ l'0)
l':list A
x:A
H1:NoDupA (l ++ x :: l')
H0:InA a l \/ InA a l'

InA a l \/ InA a (x :: l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall (l'0 : list A) (x0 : A), NoDupA (l ++ x0 :: l'0) -> NoDupA (l ++ l'0)
l':list A
x:A
H1:NoDupA (l ++ x :: l')
H0:InA a l \/ InA a l'

InA a l \/ eqA a x \/ InA a l'
intuition. Qed.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA

forall (l l' : list A) (x : A), NoDupA (l ++ x :: l') -> NoDupA (x :: l ++ l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA

forall (l l' : list A) (x : A), NoDupA (l ++ x :: l') -> NoDupA (x :: l ++ l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall (l'0 : list A) (x0 : A), NoDupA (l ++ x0 :: l'0) -> NoDupA (x0 :: l ++ l'0)
l':list A
x:A
H0:~ InA a (l ++ x :: l')
H1:NoDupA (l ++ x :: l')

NoDupA (x :: a :: l ++ l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall (l'0 : list A) (x0 : A), NoDupA (l ++ x0 :: l'0) -> NoDupA (x0 :: l ++ l'0)
l':list A
x:A
H0:~ InA a (l ++ x :: l')
H1:NoDupA (l ++ x :: l')

~ InA x (a :: l ++ l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall (l'0 : list A) (x0 : A), NoDupA (l ++ x0 :: l'0) -> NoDupA (x0 :: l ++ l'0)
l':list A
x:A
H0:~ InA a (l ++ x :: l')
H1:NoDupA (l ++ x :: l')
NoDupA (a :: l ++ l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall (l'0 : list A) (x0 : A), NoDupA (l ++ x0 :: l'0) -> NoDupA (x0 :: l ++ l'0)
l':list A
x:A
H0:~ InA a (l ++ x :: l')
H1:NoDupA (l ++ x :: l')
H2:NoDupA (x :: l ++ l')

~ InA x (a :: l ++ l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall (l'0 : list A) (x0 : A), NoDupA (l ++ x0 :: l'0) -> NoDupA (x0 :: l ++ l'0)
l':list A
x:A
H0:~ InA a (l ++ x :: l')
H1:NoDupA (l ++ x :: l')
NoDupA (a :: l ++ l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall (l'0 : list A) (x0 : A), NoDupA (l ++ x0 :: l'0) -> NoDupA (x0 :: l ++ l'0)
l':list A
x:A
H0:~ InA a (l ++ x :: l')
H1:NoDupA (l ++ x :: l')
H:~ InA x (l ++ l')
H3:NoDupA (l ++ l')

~ InA x (a :: l ++ l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall (l'0 : list A) (x0 : A), NoDupA (l ++ x0 :: l'0) -> NoDupA (x0 :: l ++ l'0)
l':list A
x:A
H0:~ InA a (l ++ x :: l')
H1:NoDupA (l ++ x :: l')
NoDupA (a :: l ++ l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall (l'0 : list A) (x0 : A), NoDupA (l ++ x0 :: l'0) -> NoDupA (x0 :: l ++ l'0)
l':list A
x:A
H0:~ InA a (l ++ x :: l')
H1:NoDupA (l ++ x :: l')
H:~ InA x (l ++ l')
H3:NoDupA (l ++ l')

~ (eqA x a \/ InA x (l ++ l'))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall (l'0 : list A) (x0 : A), NoDupA (l ++ x0 :: l'0) -> NoDupA (x0 :: l ++ l'0)
l':list A
x:A
H0:~ InA a (l ++ x :: l')
H1:NoDupA (l ++ x :: l')
NoDupA (a :: l ++ l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall (l'0 : list A) (x0 : A), NoDupA (l ++ x0 :: l'0) -> NoDupA (x0 :: l ++ l'0)
l':list A
x:A
H0:~ InA a (l ++ x :: l')
H1:NoDupA (l ++ x :: l')
H:~ InA x (l ++ l')
H3:NoDupA (l ++ l')
H2:eqA x a

False
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall (l'0 : list A) (x0 : A), NoDupA (l ++ x0 :: l'0) -> NoDupA (x0 :: l ++ l'0)
l':list A
x:A
H0:~ InA a (l ++ x :: l')
H1:NoDupA (l ++ x :: l')
H:~ InA x (l ++ l')
H3:NoDupA (l ++ l')
H2:InA x (l ++ l')
False
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall (l'0 : list A) (x0 : A), NoDupA (l ++ x0 :: l'0) -> NoDupA (x0 :: l ++ l'0)
l':list A
x:A
H0:~ InA a (l ++ x :: l')
H1:NoDupA (l ++ x :: l')
NoDupA (a :: l ++ l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall (l'0 : list A) (x0 : A), NoDupA (l ++ x0 :: l'0) -> NoDupA (x0 :: l ++ l'0)
l':list A
x:A
H0:~ InA a (l ++ x :: l')
H1:NoDupA (l ++ x :: l')
H:~ InA x (l ++ l')
H3:NoDupA (l ++ l')
H2:eqA x a

InA a (l ++ x :: l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall (l'0 : list A) (x0 : A), NoDupA (l ++ x0 :: l'0) -> NoDupA (x0 :: l ++ l'0)
l':list A
x:A
H0:~ InA a (l ++ x :: l')
H1:NoDupA (l ++ x :: l')
H:~ InA x (l ++ l')
H3:NoDupA (l ++ l')
H2:InA x (l ++ l')
False
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall (l'0 : list A) (x0 : A), NoDupA (l ++ x0 :: l'0) -> NoDupA (x0 :: l ++ l'0)
l':list A
x:A
H0:~ InA a (l ++ x :: l')
H1:NoDupA (l ++ x :: l')
NoDupA (a :: l ++ l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall (l'0 : list A) (x0 : A), NoDupA (l ++ x0 :: l'0) -> NoDupA (x0 :: l ++ l'0)
l':list A
x:A
H0:~ InA a (l ++ x :: l')
H1:NoDupA (l ++ x :: l')
H:~ InA x (l ++ l')
H3:NoDupA (l ++ l')
H2:InA x (l ++ l')

False
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall (l'0 : list A) (x0 : A), NoDupA (l ++ x0 :: l'0) -> NoDupA (x0 :: l ++ l'0)
l':list A
x:A
H0:~ InA a (l ++ x :: l')
H1:NoDupA (l ++ x :: l')
NoDupA (a :: l ++ l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall (l'0 : list A) (x0 : A), NoDupA (l ++ x0 :: l'0) -> NoDupA (x0 :: l ++ l'0)
l':list A
x:A
H0:~ InA a (l ++ x :: l')
H1:NoDupA (l ++ x :: l')

NoDupA (a :: l ++ l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall (l'0 : list A) (x0 : A), NoDupA (l ++ x0 :: l'0) -> NoDupA (x0 :: l ++ l'0)
l':list A
x:A
H0:~ InA a (l ++ x :: l')
H1:NoDupA (l ++ x :: l')

~ InA a (l ++ l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall (l'0 : list A) (x0 : A), NoDupA (l ++ x0 :: l'0) -> NoDupA (x0 :: l ++ l'0)
l':list A
x:A
H0:~ InA a (l ++ x :: l')
H1:NoDupA (l ++ x :: l')
NoDupA (l ++ l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall (l'0 : list A) (x0 : A), NoDupA (l ++ x0 :: l'0) -> NoDupA (x0 :: l ++ l'0)
l':list A
x:A
H1:NoDupA (l ++ x :: l')
H0:InA a (l ++ l')

InA a (l ++ x :: l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall (l'0 : list A) (x0 : A), NoDupA (l ++ x0 :: l'0) -> NoDupA (x0 :: l ++ l'0)
l':list A
x:A
H0:~ InA a (l ++ x :: l')
H1:NoDupA (l ++ x :: l')
NoDupA (l ++ l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
IHl:forall (l'0 : list A) (x0 : A), NoDupA (l ++ x0 :: l'0) -> NoDupA (x0 :: l ++ l'0)
l':list A
x:A
H0:~ InA a (l ++ x :: l')
H1:NoDupA (l ++ x :: l')

NoDupA (l ++ l')
eapply NoDupA_split; eauto. Qed.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
x:A

NoDupA (x :: nil)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
x:A

NoDupA (x :: nil)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
x:A

~ InA x nil
inversion 1. Qed. End NoDupA. Section EquivlistA.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA

Proper (eqA ==> equivlistA ==> equivlistA) cons
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA

Proper (eqA ==> equivlistA ==> equivlistA) cons
intros ? ? E1 ? ? E2 ?; now rewrite !InA_cons, E1, E2. Qed.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA

Proper (equivlistA ==> equivlistA ==> equivlistA) (app (A:=A))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA

Proper (equivlistA ==> equivlistA ==> equivlistA) (app (A:=A))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
x, y:list A
E1:equivlistA x y
x0, y0:list A
E2:equivlistA x0 y0
x1:A

InA x1 (x ++ x0) <-> InA x1 (y ++ y0)
now rewrite !InA_app_iff, E1, E2. Qed.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
x:A
l:list A

~ equivlistA (x :: l) nil
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
x:A
l:list A

~ equivlistA (x :: l) nil
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
x:A
l:list A
E:equivlistA (x :: l) nil

False
now eapply InA_nil, E, InA_cons_hd. Qed.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
l:list A

equivlistA l nil -> l = nil
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
l:list A

equivlistA l nil -> l = nil
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA

equivlistA nil nil -> nil = nil
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
equivlistA (a :: l) nil -> a :: l = nil
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA

equivlistA nil nil -> nil = nil
trivial.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A

equivlistA (a :: l) nil -> a :: l = nil
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
a:A
l:list A
H:equivlistA (a :: l) nil

a :: l = nil
now apply equivlistA_cons_nil in H. Qed.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
x:A
l:list A

equivlistA (x :: x :: l) (x :: l)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
x:A
l:list A

equivlistA (x :: x :: l) (x :: l)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
x:A
l:list A
x0:A

InA x0 (x :: x :: l) <-> InA x0 (x :: l)
apply InA_double_head. Qed.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
x, y:A
l:list A

equivlistA (x :: y :: l) (y :: x :: l)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
x, y:A
l:list A

equivlistA (x :: y :: l) (y :: x :: l)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
x, y:A
l:list A
x0:A

InA x0 (x :: y :: l) <-> InA x0 (y :: x :: l)
apply InA_permute_heads. Qed.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
l:list A

equivlistA (l ++ l) l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
l:list A

equivlistA (l ++ l) l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
l:list A
x:A

InA x (l ++ l) <-> InA x l
apply InA_app_idem. Qed.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
l, l1, l2:list A
x, y:A

eqA x y -> NoDupA (x :: l) -> NoDupA (l1 ++ y :: l2) -> equivlistA (x :: l) (l1 ++ y :: l2) -> equivlistA l (l1 ++ l2)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
l, l1, l2:list A
x, y:A

eqA x y -> NoDupA (x :: l) -> NoDupA (l1 ++ y :: l2) -> equivlistA (x :: l) (l1 ++ y :: l2) -> equivlistA l (l1 ++ l2)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
l, l1, l2:list A
x, y:A
H:eqA x y
H0:NoDupA (x :: l)
H1:NoDupA (l1 ++ y :: l2)
H2:equivlistA (x :: l) (l1 ++ y :: l2)
a:A

InA a l <-> InA a (l1 ++ l2)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
l, l1, l2:list A
x, y:A
H:eqA x y
H0:NoDupA (x :: l)
H1:NoDupA (l1 ++ y :: l2)
H2:equivlistA (x :: l) (l1 ++ y :: l2)
a:A

InA a (x :: l) <-> InA a (l1 ++ y :: l2) -> InA a l <-> InA a (l1 ++ l2)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
l, l1, l2:list A
x, y:A
H:eqA x y
H0:NoDupA (x :: l)
H1:NoDupA (l1 ++ y :: l2)
H2:equivlistA (x :: l) (l1 ++ y :: l2)
a:A

eqA a x \/ InA a l <-> InA a l1 \/ eqA a y \/ InA a l2 -> InA a l <-> InA a l1 \/ InA a l2
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
l, l1, l2:list A
x, y:A
H:eqA x y
H1:NoDupA (l1 ++ y :: l2)
H2:equivlistA (x :: l) (l1 ++ y :: l2)
a:A
H3:~ InA x l
H4:NoDupA l

eqA a x \/ InA a l <-> InA a l1 \/ eqA a y \/ InA a l2 -> InA a l <-> InA a l1 \/ InA a l2
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
l, l1, l2:list A
x, y:A
H:eqA x y
H1:NoDupA (l1 ++ y :: l2)
H2:equivlistA (x :: l) (l1 ++ y :: l2)
a:A
H3:~ InA x l
H4:NoDupA l
SW:NoDupA (y :: l1 ++ l2)

eqA a x \/ InA a l <-> InA a l1 \/ eqA a y \/ InA a l2 -> InA a l <-> InA a l1 \/ InA a l2
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
l, l1, l2:list A
x, y:A
H:eqA x y
H1:NoDupA (l1 ++ y :: l2)
H2:equivlistA (x :: l) (l1 ++ y :: l2)
a:A
H3:~ InA x l
H4:NoDupA l
H0:~ InA y (l1 ++ l2)
H5:NoDupA (l1 ++ l2)

eqA a x \/ InA a l <-> InA a l1 \/ eqA a y \/ InA a l2 -> InA a l <-> InA a l1 \/ InA a l2
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
l, l1, l2:list A
x, y:A
H:eqA x y
H1:NoDupA (l1 ++ y :: l2)
H2:equivlistA (x :: l) (l1 ++ y :: l2)
a:A
H3:~ InA x l
H4:NoDupA l
H0:~ (InA y l1 \/ InA y l2)
H5:NoDupA (l1 ++ l2)

eqA a x \/ InA a l <-> InA a l1 \/ eqA a y \/ InA a l2 -> InA a l <-> InA a l1 \/ InA a l2
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
l, l1, l2:list A
x, y:A
H:eqA x y
H1:NoDupA (l1 ++ y :: l2)
H2:equivlistA (x :: l) (l1 ++ y :: l2)
a:A
H3:~ InA x l
H4:NoDupA l
H0:~ (InA y l1 \/ InA y l2)
H5:NoDupA (l1 ++ l2)
H6:eqA a x \/ InA a l <-> InA a l1 \/ eqA a y \/ InA a l2
H7:InA a l

InA a l1 \/ InA a l2
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
l, l1, l2:list A
x, y:A
H:eqA x y
H1:NoDupA (l1 ++ y :: l2)
H2:equivlistA (x :: l) (l1 ++ y :: l2)
a:A
H3:~ InA x l
H4:NoDupA l
H0:~ (InA y l1 \/ InA y l2)
H5:NoDupA (l1 ++ l2)
H6:eqA a x \/ InA a l <-> InA a l1 \/ eqA a y \/ InA a l2
H7:InA a l1 \/ InA a l2
InA a l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
l, l1, l2:list A
x, y:A
H:eqA x y
H1:NoDupA (l1 ++ y :: l2)
H2:equivlistA (x :: l) (l1 ++ y :: l2)
a:A
H3:~ InA x l
H4:NoDupA l
H0:~ (InA y l1 \/ InA y l2)
H5:NoDupA (l1 ++ l2)
H6:eqA a x \/ InA a l <-> InA a l1 \/ eqA a y \/ InA a l2
H7:InA a l
H8:~ eqA a x

InA a l1 \/ InA a l2
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
l, l1, l2:list A
x, y:A
H:eqA x y
H1:NoDupA (l1 ++ y :: l2)
H2:equivlistA (x :: l) (l1 ++ y :: l2)
a:A
H3:~ InA x l
H4:NoDupA l
H0:~ (InA y l1 \/ InA y l2)
H5:NoDupA (l1 ++ l2)
H6:eqA a x \/ InA a l <-> InA a l1 \/ eqA a y \/ InA a l2
H7:InA a l1 \/ InA a l2
InA a l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
l, l1, l2:list A
x, y:A
H:eqA x y
H1:NoDupA (l1 ++ y :: l2)
H2:equivlistA (x :: l) (l1 ++ y :: l2)
a:A
H3:~ InA x l
H4:NoDupA l
H0:~ (InA y l1 \/ InA y l2)
H5:NoDupA (l1 ++ l2)
H6:eqA a x \/ InA a l <-> InA a l1 \/ eqA a y \/ InA a l2
H7:InA a l
H8:~ eqA a x
H9:~ eqA a y

InA a l1 \/ InA a l2
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
l, l1, l2:list A
x, y:A
H:eqA x y
H1:NoDupA (l1 ++ y :: l2)
H2:equivlistA (x :: l) (l1 ++ y :: l2)
a:A
H3:~ InA x l
H4:NoDupA l
H0:~ (InA y l1 \/ InA y l2)
H5:NoDupA (l1 ++ l2)
H6:eqA a x \/ InA a l <-> InA a l1 \/ eqA a y \/ InA a l2
H7:InA a l1 \/ InA a l2
InA a l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
l, l1, l2:list A
x, y:A
H:eqA x y
H1:NoDupA (l1 ++ y :: l2)
H2:equivlistA (x :: l) (l1 ++ y :: l2)
a:A
H3:~ InA x l
H4:NoDupA l
H0:~ (InA y l1 \/ InA y l2)
H5:NoDupA (l1 ++ l2)
H6:eqA a x \/ InA a l <-> InA a l1 \/ eqA a y \/ InA a l2
H7:InA a l1 \/ InA a l2

InA a l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
l, l1, l2:list A
x, y:A
H:eqA x y
H1:NoDupA (l1 ++ y :: l2)
H2:equivlistA (x :: l) (l1 ++ y :: l2)
a:A
H3:~ InA x l
H4:NoDupA l
H0:~ (InA y l1 \/ InA y l2)
H5:NoDupA (l1 ++ l2)
H6:eqA a x \/ InA a l <-> InA a l1 \/ eqA a y \/ InA a l2
H7:InA a l1 \/ InA a l2
OR:eqA a x \/ InA a l

InA a l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
l, l1, l2:list A
x, y:A
H:eqA x y
H1:NoDupA (l1 ++ y :: l2)
H2:equivlistA (x :: l) (l1 ++ y :: l2)
a:A
H3:~ InA x l
H4:NoDupA l
H0:~ (InA y l1 \/ InA y l2)
H5:NoDupA (l1 ++ l2)
H7:InA a l1 \/ InA a l2
OR:eqA a x \/ InA a l

InA a l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
l, l1, l2:list A
x, y:A
H:eqA x y
H1:NoDupA (l1 ++ y :: l2)
H2:equivlistA (x :: l) (l1 ++ y :: l2)
a:A
H3:~ InA x l
H4:NoDupA l
H0:~ (InA y l1 \/ InA y l2)
H5:NoDupA (l1 ++ l2)
H7:InA a l1 \/ InA a l2
EQN:eqA a x

InA a l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
l, l1, l2:list A
x, y:A
H:eqA x y
H1:NoDupA (l1 ++ y :: l2)
H2:equivlistA (x :: l) (l1 ++ y :: l2)
a:A
H3:~ InA x l
H4:NoDupA l
H0:~ (InA y l1 \/ InA y l2)
H5:NoDupA (l1 ++ l2)
H7:InA a l1 \/ InA a l2
EQN:eqA a x

InA y l1 \/ InA y l2
rewrite <-H,<-EQN; auto. Qed. End EquivlistA. Section Fold. Variable B:Type. Variable eqB:B->B->Prop. Variable st:Equivalence eqB. Variable f:A->B->B. Variable i:B. Variable Comp:Proper (eqA==>eqB==>eqB) f.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f

forall s s' : list A, eqlistA s s' -> eqB (fold_right f i s) (fold_right f i s')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f

forall s s' : list A, eqlistA s s' -> eqB (fold_right f i s) (fold_right f i s')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
x, x':A
l, l':list A
H:eqA x x'
H0:eqlistA l l'
IHeqlistA:eqB (fold_right f i l) (fold_right f i l')

eqB (f x (fold_right f i l)) (f x' (fold_right f i l'))
apply Comp; auto. Qed.
Fold with restricted transpose hypothesis.
Section Fold_With_Restriction.
Variable R : A -> A -> Prop.
Hypothesis R_sym : Symmetric R.
Hypothesis R_compat : Proper (eqA==>eqA==>iff) R.


(*

(** [ForallOrdPairs R] is compatible with [equivlistA] over the
    lists without duplicates, as long as the relation [R]
    is symmetric and compatible with [eqA]. To prove this fact,
    we use an auxiliary notion: "forall distinct pairs, ...".
*)

Definition ForallNeqPairs :=
 ForallPairs (fun a b => ~eqA a b -> R a b).

(** [ForallOrdPairs] and [ForallNeqPairs] are related, but not completely
    equivalent. For proving one implication, we need to know that the
    list has no duplicated elements... *)

Lemma ForallNeqPairs_ForallOrdPairs : forall l, NoDupA l ->
 ForallNeqPairs l -> ForallOrdPairs R l.
Proof.
 induction l; auto.
 constructor. inv.
 rewrite Forall_forall; intros b Hb.
 apply H0; simpl; auto.
 contradict H1; rewrite H1; auto.
 apply IHl.
 inv; auto.
 intros b c Hb Hc Hneq.
 apply H0; simpl; auto.
Qed.

(** ... and for proving the other implication, we need to be able
   to reverse relation [R]. *)

Lemma ForallOrdPairs_ForallNeqPairs : forall l,
 ForallOrdPairs R l -> ForallNeqPairs l.
Proof.
 intros l Hl x y Hx Hy N.
 destruct (ForallOrdPairs_In Hl x y Hx Hy) as [H|[H|H]].
 subst; elim N; auto.
 assumption.
 apply R_sym; assumption.
Qed.

*)
Compatibility of ForallOrdPairs with respect to inclA.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R

forall l l' : list A, NoDupA l' -> inclA l' l -> ForallOrdPairs R l -> ForallOrdPairs R l'
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R

forall l l' : list A, NoDupA l' -> inclA l' l -> ForallOrdPairs R l -> ForallOrdPairs R l'
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
l:list A

NoDupA nil -> inclA nil l -> ForallOrdPairs R l -> ForallOrdPairs R nil
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
l:list A
x:A
l':list A
IH:NoDupA l' -> inclA l' l -> ForallOrdPairs R l -> ForallOrdPairs R l'
NoDupA (x :: l') -> inclA (x :: l') l -> ForallOrdPairs R l -> ForallOrdPairs R (x :: l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
l:list A
x:A
l':list A
IH:NoDupA l' -> inclA l' l -> ForallOrdPairs R l -> ForallOrdPairs R l'

NoDupA (x :: l') -> inclA (x :: l') l -> ForallOrdPairs R l -> ForallOrdPairs R (x :: l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
l:list A
x:A
l':list A
IH:NoDupA l' -> inclA l' l -> ForallOrdPairs R l -> ForallOrdPairs R l'
ND:NoDupA (x :: l')
Incl:inclA (x :: l') l
FOP:ForallOrdPairs R l

ForallOrdPairs R (x :: l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
l:list A
x:A
l':list A
IH:NoDupA l' -> (forall x0 : A, InA x0 l' -> InA x0 l) -> ForallOrdPairs R l -> ForallOrdPairs R l'
Incl:forall x0 : A, InA x0 (x :: l') -> InA x0 l
FOP:ForallOrdPairs R l
H:~ InA x l'
H0:NoDupA l'

Forall (R x) l'
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
l:list A
x:A
l':list A
IH:NoDupA l' -> (forall x0 : A, InA x0 l' -> InA x0 l) -> ForallOrdPairs R l -> ForallOrdPairs R l'
Incl:forall x0 : A, InA x0 (x :: l') -> InA x0 l
FOP:ForallOrdPairs R l
H:~ InA x l'
H0:NoDupA l'
y:A
Hy:In y l'

R x y
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
l:list A
x:A
l':list A
IH:NoDupA l' -> (forall x0 : A, InA x0 l' -> InA x0 l) -> ForallOrdPairs R l -> ForallOrdPairs R l'
Incl:forall x0 : A, InA x0 (x :: l') -> InA x0 l
FOP:ForallOrdPairs R l
H:~ InA x l'
H0:NoDupA l'
y:A
Hy:In y l'
Ix:InA x (x :: l')

R x y
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
l:list A
x:A
l':list A
IH:NoDupA l' -> (forall x0 : A, InA x0 l' -> InA x0 l) -> ForallOrdPairs R l -> ForallOrdPairs R l'
Incl:forall x0 : A, InA x0 (x :: l') -> InA x0 l
FOP:ForallOrdPairs R l
H:~ InA x l'
H0:NoDupA l'
y:A
Hy:In y l'
Ix:InA x l

R x y
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
l:list A
x:A
l':list A
IH:NoDupA l' -> (forall x0 : A, InA x0 l' -> InA x0 l) -> ForallOrdPairs R l -> ForallOrdPairs R l'
Incl:forall x0 : A, InA x0 (x :: l') -> InA x0 l
FOP:ForallOrdPairs R l
H:~ InA x l'
H0:NoDupA l'
y:A
Hy:In y l'
Ix:exists y0 : A, eqA x y0 /\ In y0 l

R x y
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
l:list A
x:A
l':list A
IH:NoDupA l' -> (forall x0 : A, InA x0 l' -> InA x0 l) -> ForallOrdPairs R l -> ForallOrdPairs R l'
Incl:forall x0 : A, InA x0 (x :: l') -> InA x0 l
FOP:ForallOrdPairs R l
H:~ InA x l'
H0:NoDupA l'
y:A
Hy:In y l'
x':A
Hxx':eqA x x'
Hx':In x' l

R x y
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
l:list A
x:A
l':list A
IH:NoDupA l' -> (forall x0 : A, InA x0 l' -> InA x0 l) -> ForallOrdPairs R l -> ForallOrdPairs R l'
Incl:forall x0 : A, InA x0 (x :: l') -> InA x0 l
FOP:ForallOrdPairs R l
H:~ InA x l'
H0:NoDupA l'
y:A
Hy:In y l'
x':A
Hxx':eqA x x'
Hx':In x' l
Iy:InA y (x :: l')

R x y
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
l:list A
x:A
l':list A
IH:NoDupA l' -> (forall x0 : A, InA x0 l' -> InA x0 l) -> ForallOrdPairs R l -> ForallOrdPairs R l'
Incl:forall x0 : A, InA x0 (x :: l') -> InA x0 l
FOP:ForallOrdPairs R l
H:~ InA x l'
H0:NoDupA l'
y:A
Hy:In y l'
x':A
Hxx':eqA x x'
Hx':In x' l
Iy:InA y l

R x y
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
l:list A
x:A
l':list A
IH:NoDupA l' -> (forall x0 : A, InA x0 l' -> InA x0 l) -> ForallOrdPairs R l -> ForallOrdPairs R l'
Incl:forall x0 : A, InA x0 (x :: l') -> InA x0 l
FOP:ForallOrdPairs R l
H:~ InA x l'
H0:NoDupA l'
y:A
Hy:In y l'
x':A
Hxx':eqA x x'
Hx':In x' l
Iy:exists y0 : A, eqA y y0 /\ In y0 l

R x y
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
l:list A
x:A
l':list A
IH:NoDupA l' -> (forall x0 : A, InA x0 l' -> InA x0 l) -> ForallOrdPairs R l -> ForallOrdPairs R l'
Incl:forall x0 : A, InA x0 (x :: l') -> InA x0 l
FOP:ForallOrdPairs R l
H:~ InA x l'
H0:NoDupA l'
y:A
Hy:In y l'
x':A
Hxx':eqA x x'
Hx':In x' l
y':A
Hyy':eqA y y'
Hy':In y' l

R x y
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
l:list A
x:A
l':list A
IH:NoDupA l' -> (forall x0 : A, InA x0 l' -> InA x0 l) -> ForallOrdPairs R l -> ForallOrdPairs R l'
Incl:forall x0 : A, InA x0 (x :: l') -> InA x0 l
FOP:ForallOrdPairs R l
H:~ InA x l'
H0:NoDupA l'
y:A
Hy:In y l'
x':A
Hxx':eqA x x'
Hx':In x' l
y':A
Hyy':eqA y y'
Hy':In y' l

R x' y'
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
l:list A
x:A
l':list A
IH:NoDupA l' -> (forall x0 : A, InA x0 l' -> InA x0 l) -> ForallOrdPairs R l -> ForallOrdPairs R l'
Incl:forall x0 : A, InA x0 (x :: l') -> InA x0 l
FOP:ForallOrdPairs R l
H:~ InA x l'
H0:NoDupA l'
y:A
Hy:In y l'
x':A
Hxx':eqA x x'
Hx':In x' l
y':A
Hyy':eqA y y'
Hy':In y' l
E:x' = y'

R x' y'
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
l:list A
x:A
l':list A
IH:NoDupA l' -> (forall x0 : A, InA x0 l' -> InA x0 l) -> ForallOrdPairs R l -> ForallOrdPairs R l'
Incl:forall x0 : A, InA x0 (x :: l') -> InA x0 l
FOP:ForallOrdPairs R l
H:~ InA x l'
H0:NoDupA l'
y:A
Hy:In y l'
x':A
Hxx':eqA x x'
Hx':In x' l
y':A
Hyy':eqA y y'
Hy':In y' l
E:x' = y'

InA x l'
rewrite Hxx', E, <- Hyy'; auto. Qed.
Two-argument functions that allow to reorder their arguments.
Definition transpose (f : A -> B -> B) :=
  forall (x y : A) (z : B), eqB (f x (f y z)) (f y (f x z)).
A version of transpose with restriction on where it should hold
Definition transpose_restr (R : A -> A -> Prop)(f : A -> B -> B) :=
  forall (x y : A) (z : B), R x y -> eqB (f x (f y z)) (f y (f x z)).

Variable TraR :transpose_restr R f.

A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f

forall (s1 s2 : list A) (x : A), ForallOrdPairs R (s1 ++ x :: s2) -> eqB (fold_right f i (s1 ++ x :: s2)) (f x (fold_right f i (s1 ++ s2)))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f

forall (s1 s2 : list A) (x : A), ForallOrdPairs R (s1 ++ x :: s2) -> eqB (fold_right f i (s1 ++ x :: s2)) (f x (fold_right f i (s1 ++ s2)))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
s2:list A
x:A
H:ForallOrdPairs R (x :: s2)

eqB (f x (fold_right f i s2)) (f x (fold_right f i s2))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
a:A
s1:list A
IHs1:forall (s0 : list A) (x0 : A), ForallOrdPairs R (s1 ++ x0 :: s0) -> eqB (fold_right f i (s1 ++ x0 :: s0)) (f x0 (fold_right f i (s1 ++ s0)))
s2:list A
x:A
H:ForallOrdPairs R (a :: s1 ++ x :: s2)
eqB (f a (fold_right f i (s1 ++ x :: s2))) (f x (f a (fold_right f i (s1 ++ s2))))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
a:A
s1:list A
IHs1:forall (s0 : list A) (x0 : A), ForallOrdPairs R (s1 ++ x0 :: s0) -> eqB (fold_right f i (s1 ++ x0 :: s0)) (f x0 (fold_right f i (s1 ++ s0)))
s2:list A
x:A
H:ForallOrdPairs R (a :: s1 ++ x :: s2)

eqB (f a (fold_right f i (s1 ++ x :: s2))) (f x (f a (fold_right f i (s1 ++ s2))))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
a:A
s1:list A
IHs1:forall (s0 : list A) (x0 : A), ForallOrdPairs R (s1 ++ x0 :: s0) -> eqB (fold_right f i (s1 ++ x0 :: s0)) (f x0 (fold_right f i (s1 ++ s0)))
s2:list A
x:A
H:ForallOrdPairs R (a :: s1 ++ x :: s2)

eqB (f a (fold_right f i (s1 ++ x :: s2))) (f a (f x (fold_right f i (s1 ++ s2))))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
a:A
s1:list A
IHs1:forall (s0 : list A) (x0 : A), ForallOrdPairs R (s1 ++ x0 :: s0) -> eqB (fold_right f i (s1 ++ x0 :: s0)) (f x0 (fold_right f i (s1 ++ s0)))
s2:list A
x:A
H:ForallOrdPairs R (a :: s1 ++ x :: s2)
eqB (f a (f x (fold_right f i (s1 ++ s2)))) (f x (f a (fold_right f i (s1 ++ s2))))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
a:A
s1:list A
IHs1:forall (s0 : list A) (x0 : A), ForallOrdPairs R (s1 ++ x0 :: s0) -> eqB (fold_right f i (s1 ++ x0 :: s0)) (f x0 (fold_right f i (s1 ++ s0)))
s2:list A
x:A
H:ForallOrdPairs R (a :: s1 ++ x :: s2)

eqB (fold_right f i (s1 ++ x :: s2)) (f x (fold_right f i (s1 ++ s2)))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
a:A
s1:list A
IHs1:forall (s0 : list A) (x0 : A), ForallOrdPairs R (s1 ++ x0 :: s0) -> eqB (fold_right f i (s1 ++ x0 :: s0)) (f x0 (fold_right f i (s1 ++ s0)))
s2:list A
x:A
H:ForallOrdPairs R (a :: s1 ++ x :: s2)
eqB (f a (f x (fold_right f i (s1 ++ s2)))) (f x (f a (fold_right f i (s1 ++ s2))))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
a:A
s1:list A
IHs1:forall (s0 : list A) (x0 : A), ForallOrdPairs R (s1 ++ x0 :: s0) -> eqB (fold_right f i (s1 ++ x0 :: s0)) (f x0 (fold_right f i (s1 ++ s0)))
s2:list A
x:A
H:ForallOrdPairs R (a :: s1 ++ x :: s2)

ForallOrdPairs R (s1 ++ x :: s2)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
a:A
s1:list A
IHs1:forall (s0 : list A) (x0 : A), ForallOrdPairs R (s1 ++ x0 :: s0) -> eqB (fold_right f i (s1 ++ x0 :: s0)) (f x0 (fold_right f i (s1 ++ s0)))
s2:list A
x:A
H:ForallOrdPairs R (a :: s1 ++ x :: s2)
eqB (f a (f x (fold_right f i (s1 ++ s2)))) (f x (f a (fold_right f i (s1 ++ s2))))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
a:A
s1:list A
IHs1:forall (s0 : list A) (x0 : A), ForallOrdPairs R (s1 ++ x0 :: s0) -> eqB (fold_right f i (s1 ++ x0 :: s0)) (f x0 (fold_right f i (s1 ++ s0)))
s2:list A
x:A
H:ForallOrdPairs R (a :: s1 ++ x :: s2)

eqB (f a (f x (fold_right f i (s1 ++ s2)))) (f x (f a (fold_right f i (s1 ++ s2))))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
a:A
s1:list A
IHs1:forall (s0 : list A) (x0 : A), ForallOrdPairs R (s1 ++ x0 :: s0) -> eqB (fold_right f i (s1 ++ x0 :: s0)) (f x0 (fold_right f i (s1 ++ s0)))
s2:list A
x:A
H:ForallOrdPairs R (a :: s1 ++ x :: s2)

R a x
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
a:A
s1:list A
IHs1:forall (s0 : list A) (x0 : A), ForallOrdPairs R (s1 ++ x0 :: s0) -> eqB (fold_right f i (s1 ++ x0 :: s0)) (f x0 (fold_right f i (s1 ++ s0)))
s2:list A
x:A
H0:Forall (R a) (s1 ++ x :: s2)
H1:ForallOrdPairs R (s1 ++ x :: s2)

R a x
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
a:A
s1:list A
IHs1:forall (s0 : list A) (x0 : A), ForallOrdPairs R (s1 ++ x0 :: s0) -> eqB (fold_right f i (s1 ++ x0 :: s0)) (f x0 (fold_right f i (s1 ++ s0)))
s2:list A
x:A
H0:forall x0 : A, In x0 (s1 ++ x :: s2) -> R a x0
H1:ForallOrdPairs R (s1 ++ x :: s2)

In x (s1 ++ x :: s2)
apply in_or_app; simpl; auto. Qed.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f

forall s s' : list A, NoDupA s -> NoDupA s' -> ForallOrdPairs R s -> equivlistA s s' -> eqB (fold_right f i s) (fold_right f i s')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f

forall s s' : list A, NoDupA s -> NoDupA s' -> ForallOrdPairs R s -> equivlistA s s' -> eqB (fold_right f i s) (fold_right f i s')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
s:list A

forall s' : list A, NoDupA nil -> NoDupA s' -> ForallOrdPairs R nil -> equivlistA nil s' -> eqB (fold_right f i nil) (fold_right f i s')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
s:list A
forall (a : A) (l : list A), (forall s' : list A, NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB (fold_right f i l) (fold_right f i s')) -> forall s' : list A, NoDupA (a :: l) -> NoDupA s' -> ForallOrdPairs R (a :: l) -> equivlistA (a :: l) s' -> eqB (fold_right f i (a :: l)) (fold_right f i s')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
s:list A

NoDupA nil -> NoDupA nil -> ForallOrdPairs R nil -> equivlistA nil nil -> eqB i i
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
s:list A
a:A
s':list A
NoDupA nil -> NoDupA (a :: s') -> ForallOrdPairs R nil -> equivlistA nil (a :: s') -> eqB i (f a (fold_right f i s'))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
s:list A
forall (a : A) (l : list A), (forall s' : list A, NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB (fold_right f i l) (fold_right f i s')) -> forall s' : list A, NoDupA (a :: l) -> NoDupA s' -> ForallOrdPairs R (a :: l) -> equivlistA (a :: l) s' -> eqB (fold_right f i (a :: l)) (fold_right f i s')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
s:list A
a:A
s':list A

NoDupA nil -> NoDupA (a :: s') -> ForallOrdPairs R nil -> equivlistA nil (a :: s') -> eqB i (f a (fold_right f i s'))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
s:list A
forall (a : A) (l : list A), (forall s' : list A, NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB (fold_right f i l) (fold_right f i s')) -> forall s' : list A, NoDupA (a :: l) -> NoDupA s' -> ForallOrdPairs R (a :: l) -> equivlistA (a :: l) s' -> eqB (fold_right f i (a :: l)) (fold_right f i s')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
s:list A
a:A
s':list A
H:NoDupA nil
H0:NoDupA (a :: s')
H1:ForallOrdPairs R nil
H2:forall x : A, InA x nil <-> InA x (a :: s')

eqB i (f a (fold_right f i s'))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
s:list A
forall (a : A) (l : list A), (forall s' : list A, NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB (fold_right f i l) (fold_right f i s')) -> forall s' : list A, NoDupA (a :: l) -> NoDupA s' -> ForallOrdPairs R (a :: l) -> equivlistA (a :: l) s' -> eqB (fold_right f i (a :: l)) (fold_right f i s')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
s:list A
a:A
s':list A
H:NoDupA nil
H0:NoDupA (a :: s')
H1:ForallOrdPairs R nil
H2:forall x : A, InA x nil <-> InA x (a :: s')
H3:InA a nil -> InA a (a :: s')
H4:InA a (a :: s') -> InA a nil

eqB i (f a (fold_right f i s'))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
s:list A
forall (a : A) (l : list A), (forall s' : list A, NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB (fold_right f i l) (fold_right f i s')) -> forall s' : list A, NoDupA (a :: l) -> NoDupA s' -> ForallOrdPairs R (a :: l) -> equivlistA (a :: l) s' -> eqB (fold_right f i (a :: l)) (fold_right f i s')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
s:list A

forall (a : A) (l : list A), (forall s' : list A, NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB (fold_right f i l) (fold_right f i s')) -> forall s' : list A, NoDupA (a :: l) -> NoDupA s' -> ForallOrdPairs R (a :: l) -> equivlistA (a :: l) s' -> eqB (fold_right f i (a :: l)) (fold_right f i s')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
s:list A
x:A
l:list A
Hrec:forall s'0 : list A, NoDupA l -> NoDupA s'0 -> ForallOrdPairs R l -> equivlistA l s'0 -> eqB (fold_right f i l) (fold_right f i s'0)
s':list A
N:NoDupA (x :: l)
N':NoDupA s'
F:ForallOrdPairs R (x :: l)
E:equivlistA (x :: l) s'

eqB (f x (fold_right f i l)) (fold_right f i s')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
s:list A
x:A
l:list A
Hrec:forall s'0 : list A, NoDupA l -> NoDupA s'0 -> ForallOrdPairs R l -> equivlistA l s'0 -> eqB (fold_right f i l) (fold_right f i s'0)
s':list A
N:NoDupA (x :: l)
N':NoDupA s'
F:ForallOrdPairs R (x :: l)
E:equivlistA (x :: l) s'
H:InA x s'

eqB (f x (fold_right f i l)) (fold_right f i s')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
s:list A
x:A
l:list A
Hrec:forall s'0 : list A, NoDupA l -> NoDupA s'0 -> ForallOrdPairs R l -> equivlistA l s'0 -> eqB (fold_right f i l) (fold_right f i s'0)
s':list A
N:NoDupA (x :: l)
N':NoDupA s'
F:ForallOrdPairs R (x :: l)
E:equivlistA (x :: l) s'
H:InA x s'
s1:list A
y:A
s2:list A
H1:eqA x y
H2:s' = s1 ++ y :: s2

eqB (f x (fold_right f i l)) (fold_right f i s')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
s:list A
x:A
l:list A
Hrec:forall s' : list A, NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB (fold_right f i l) (fold_right f i s')
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
H:InA x (s1 ++ y :: s2)
E:equivlistA (x :: l) (s1 ++ y :: s2)
H1:eqA x y

eqB (f x (fold_right f i l)) (fold_right f i (s1 ++ y :: s2))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
s:list A
x:A
l:list A
Hrec:forall s' : list A, NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB (fold_right f i l) (fold_right f i s')
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
H:InA x (s1 ++ y :: s2)
E:equivlistA (x :: l) (s1 ++ y :: s2)
H1:eqA x y

eqB (f x (fold_right f i l)) (f x (fold_right f i (s1 ++ s2)))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
s:list A
x:A
l:list A
Hrec:forall s' : list A, NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB (fold_right f i l) (fold_right f i s')
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
H:InA x (s1 ++ y :: s2)
E:equivlistA (x :: l) (s1 ++ y :: s2)
H1:eqA x y
eqB (f x (fold_right f i (s1 ++ s2))) (fold_right f i (s1 ++ y :: s2))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
s:list A
x:A
l:list A
Hrec:forall s' : list A, NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB (fold_right f i l) (fold_right f i s')
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
H:InA x (s1 ++ y :: s2)
E:equivlistA (x :: l) (s1 ++ y :: s2)
H1:eqA x y

eqB (fold_right f i l) (fold_right f i (s1 ++ s2))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
s:list A
x:A
l:list A
Hrec:forall s' : list A, NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB (fold_right f i l) (fold_right f i s')
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
H:InA x (s1 ++ y :: s2)
E:equivlistA (x :: l) (s1 ++ y :: s2)
H1:eqA x y
eqB (f x (fold_right f i (s1 ++ s2))) (fold_right f i (s1 ++ y :: s2))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
s:list A
x:A
l:list A
Hrec:forall s' : list A, NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB (fold_right f i l) (fold_right f i s')
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
H:InA x (s1 ++ y :: s2)
E:equivlistA (x :: l) (s1 ++ y :: s2)
H1:eqA x y

NoDupA l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
s:list A
x:A
l:list A
Hrec:forall s' : list A, NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB (fold_right f i l) (fold_right f i s')
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
H:InA x (s1 ++ y :: s2)
E:equivlistA (x :: l) (s1 ++ y :: s2)
H1:eqA x y
NoDupA (s1 ++ s2)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
s:list A
x:A
l:list A
Hrec:forall s' : list A, NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB (fold_right f i l) (fold_right f i s')
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
H:InA x (s1 ++ y :: s2)
E:equivlistA (x :: l) (s1 ++ y :: s2)
H1:eqA x y
ForallOrdPairs R l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
s:list A
x:A
l:list A
Hrec:forall s' : list A, NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB (fold_right f i l) (fold_right f i s')
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
H:InA x (s1 ++ y :: s2)
E:equivlistA (x :: l) (s1 ++ y :: s2)
H1:eqA x y
equivlistA l (s1 ++ s2)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
s:list A
x:A
l:list A
Hrec:forall s' : list A, NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB (fold_right f i l) (fold_right f i s')
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
H:InA x (s1 ++ y :: s2)
E:equivlistA (x :: l) (s1 ++ y :: s2)
H1:eqA x y
eqB (f x (fold_right f i (s1 ++ s2))) (fold_right f i (s1 ++ y :: s2))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
s:list A
x:A
l:list A
Hrec:forall s' : list A, NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB (fold_right f i l) (fold_right f i s')
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
H:InA x (s1 ++ y :: s2)
E:equivlistA (x :: l) (s1 ++ y :: s2)
H1:eqA x y

NoDupA (s1 ++ s2)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
s:list A
x:A
l:list A
Hrec:forall s' : list A, NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB (fold_right f i l) (fold_right f i s')
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
H:InA x (s1 ++ y :: s2)
E:equivlistA (x :: l) (s1 ++ y :: s2)
H1:eqA x y
ForallOrdPairs R l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
s:list A
x:A
l:list A
Hrec:forall s' : list A, NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB (fold_right f i l) (fold_right f i s')
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
H:InA x (s1 ++ y :: s2)
E:equivlistA (x :: l) (s1 ++ y :: s2)
H1:eqA x y
equivlistA l (s1 ++ s2)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
s:list A
x:A
l:list A
Hrec:forall s' : list A, NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB (fold_right f i l) (fold_right f i s')
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
H:InA x (s1 ++ y :: s2)
E:equivlistA (x :: l) (s1 ++ y :: s2)
H1:eqA x y
eqB (f x (fold_right f i (s1 ++ s2))) (fold_right f i (s1 ++ y :: s2))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
s:list A
x:A
l:list A
Hrec:forall s' : list A, NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB (fold_right f i l) (fold_right f i s')
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
H:InA x (s1 ++ y :: s2)
E:equivlistA (x :: l) (s1 ++ y :: s2)
H1:eqA x y

ForallOrdPairs R l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
s:list A
x:A
l:list A
Hrec:forall s' : list A, NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB (fold_right f i l) (fold_right f i s')
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
H:InA x (s1 ++ y :: s2)
E:equivlistA (x :: l) (s1 ++ y :: s2)
H1:eqA x y
equivlistA l (s1 ++ s2)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
s:list A
x:A
l:list A
Hrec:forall s' : list A, NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB (fold_right f i l) (fold_right f i s')
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
H:InA x (s1 ++ y :: s2)
E:equivlistA (x :: l) (s1 ++ y :: s2)
H1:eqA x y
eqB (f x (fold_right f i (s1 ++ s2))) (fold_right f i (s1 ++ y :: s2))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
s:list A
x:A
l:list A
Hrec:forall s' : list A, NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB (fold_right f i l) (fold_right f i s')
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
H:InA x (s1 ++ y :: s2)
E:equivlistA (x :: l) (s1 ++ y :: s2)
H1:eqA x y

equivlistA l (s1 ++ s2)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
s:list A
x:A
l:list A
Hrec:forall s' : list A, NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB (fold_right f i l) (fold_right f i s')
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
H:InA x (s1 ++ y :: s2)
E:equivlistA (x :: l) (s1 ++ y :: s2)
H1:eqA x y
eqB (f x (fold_right f i (s1 ++ s2))) (fold_right f i (s1 ++ y :: s2))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
s:list A
x:A
l:list A
Hrec:forall s' : list A, NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB (fold_right f i l) (fold_right f i s')
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
H:InA x (s1 ++ y :: s2)
E:equivlistA (x :: l) (s1 ++ y :: s2)
H1:eqA x y

eqB (f x (fold_right f i (s1 ++ s2))) (fold_right f i (s1 ++ y :: s2))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
s:list A
x:A
l:list A
Hrec:forall s' : list A, NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB (fold_right f i l) (fold_right f i s')
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
H:InA x (s1 ++ y :: s2)
E:equivlistA (x :: l) (s1 ++ y :: s2)
H1:eqA x y

eqB (f x (fold_right f i (s1 ++ s2))) (f y (fold_right f i (s1 ++ s2)))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
s:list A
x:A
l:list A
Hrec:forall s' : list A, NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB (fold_right f i l) (fold_right f i s')
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
H:InA x (s1 ++ y :: s2)
E:equivlistA (x :: l) (s1 ++ y :: s2)
H1:eqA x y
eqB (f y (fold_right f i (s1 ++ s2))) (fold_right f i (s1 ++ y :: s2))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
s:list A
x:A
l:list A
Hrec:forall s' : list A, NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB (fold_right f i l) (fold_right f i s')
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
H:InA x (s1 ++ y :: s2)
E:equivlistA (x :: l) (s1 ++ y :: s2)
H1:eqA x y

eqB (fold_right f i (s1 ++ s2)) (fold_right f i (s1 ++ s2))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
s:list A
x:A
l:list A
Hrec:forall s' : list A, NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB (fold_right f i l) (fold_right f i s')
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
H:InA x (s1 ++ y :: s2)
E:equivlistA (x :: l) (s1 ++ y :: s2)
H1:eqA x y
eqB (f y (fold_right f i (s1 ++ s2))) (fold_right f i (s1 ++ y :: s2))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
s:list A
x:A
l:list A
Hrec:forall s' : list A, NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB (fold_right f i l) (fold_right f i s')
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
H:InA x (s1 ++ y :: s2)
E:equivlistA (x :: l) (s1 ++ y :: s2)
H1:eqA x y

eqB (f y (fold_right f i (s1 ++ s2))) (fold_right f i (s1 ++ y :: s2))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
s:list A
x:A
l:list A
Hrec:forall s' : list A, NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB (fold_right f i l) (fold_right f i s')
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
H:InA x (s1 ++ y :: s2)
E:equivlistA (x :: l) (s1 ++ y :: s2)
H1:eqA x y

ForallOrdPairs R (s1 ++ y :: s2)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f
s:list A
x:A
l:list A
Hrec:forall s' : list A, NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB (fold_right f i l) (fold_right f i s')
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
H:InA x (s1 ++ y :: s2)
E:equivlistA (x :: l) (s1 ++ y :: s2)
H1:eqA x y

inclA (s1 ++ y :: s2) (x :: l)
red; intros; rewrite E; auto. Qed.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f

forall (s' s : list A) (x : A), NoDupA s -> NoDupA s' -> ForallOrdPairs R s' -> ~ InA x s -> equivlistA s' (x :: s) -> eqB (fold_right f i s') (f x (fold_right f i s))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr R f

forall (s' s : list A) (x : A), NoDupA s -> NoDupA s' -> ForallOrdPairs R s' -> ~ InA x s -> equivlistA s' (x :: s) -> eqB (fold_right f i s') (f x (fold_right f i s))
intros; apply (@fold_right_equivlistA_restr s' (x::s)); auto. Qed. End Fold_With_Restriction.
we now state similar results, but without restriction on transpose.
Variable Tra :transpose f.

A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
Tra:transpose f

forall (s1 s2 : list A) (x : A), eqB (fold_right f i (s1 ++ x :: s2)) (f x (fold_right f i (s1 ++ s2)))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
Tra:transpose f

forall (s1 s2 : list A) (x : A), eqB (fold_right f i (s1 ++ x :: s2)) (f x (fold_right f i (s1 ++ s2)))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
Tra:transpose f
s2:list A
x:A

eqB (f x (fold_right f i s2)) (f x (fold_right f i s2))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
Tra:transpose f
a:A
s1:list A
IHs1:forall (s0 : list A) (x0 : A), eqB (fold_right f i (s1 ++ x0 :: s0)) (f x0 (fold_right f i (s1 ++ s0)))
s2:list A
x:A
eqB (f a (fold_right f i (s1 ++ x :: s2))) (f x (f a (fold_right f i (s1 ++ s2))))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
Tra:transpose f
a:A
s1:list A
IHs1:forall (s0 : list A) (x0 : A), eqB (fold_right f i (s1 ++ x0 :: s0)) (f x0 (fold_right f i (s1 ++ s0)))
s2:list A
x:A

eqB (f a (fold_right f i (s1 ++ x :: s2))) (f x (f a (fold_right f i (s1 ++ s2))))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
Tra:transpose f
a:A
s1:list A
IHs1:forall (s0 : list A) (x0 : A), eqB (fold_right f i (s1 ++ x0 :: s0)) (f x0 (fold_right f i (s1 ++ s0)))
s2:list A
x:A

eqB (f a (fold_right f i (s1 ++ x :: s2))) (f a (f x (fold_right f i (s1 ++ s2))))
apply Comp; auto. Qed.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
Tra:transpose f

forall s s' : list A, NoDupA s -> NoDupA s' -> equivlistA s s' -> eqB (fold_right f i s) (fold_right f i s')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
Tra:transpose f

forall s s' : list A, NoDupA s -> NoDupA s' -> equivlistA s s' -> eqB (fold_right f i s) (fold_right f i s')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
Tra:transpose f
s, s':list A
H:NoDupA s
H0:NoDupA s'
H1:equivlistA s s'

ForallOrdPairs (fun _ _ : A => True) s
apply ForallPairs_ForallOrdPairs; try red; auto. Qed.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
Tra:transpose f

forall (s' s : list A) (x : A), NoDupA s -> NoDupA s' -> ~ InA x s -> equivlistA s' (x :: s) -> eqB (fold_right f i s') (f x (fold_right f i s))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
i:B
Comp:Proper (eqA ==> eqB ==> eqB) f
Tra:transpose f

forall (s' s : list A) (x : A), NoDupA s -> NoDupA s' -> ~ InA x s -> equivlistA s' (x :: s) -> eqB (fold_right f i s') (f x (fold_right f i s))
intros; apply (@fold_right_equivlistA s' (x::s)); auto. Qed. End Fold. Section Fold2. Variable B:Type. Variable eqB:B->B->Prop. Variable st:Equivalence eqB. Variable f:A->B->B. Variable Comp:Proper (eqA==>eqB==>eqB) f.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f

forall (s s' : list A) (i j : B), eqB i j -> eqlistA s s' -> eqB (fold_right f i s) (fold_right f j s')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f

forall (s s' : list A) (i j : B), eqB i j -> eqlistA s s' -> eqB (fold_right f i s) (fold_right f j s')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
s:list A

forall (s' : list A) (i j : B), eqB i j -> eqlistA s s' -> eqB (fold_right f i s) (fold_right f j s')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
s':list A
i, j:B
heqij:eqB i j
heqss':eqlistA nil s'

eqB (fold_right f i nil) (fold_right f j s')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
a:A
s:list A
IHs:forall (s'0 : list A) (i0 j0 : B), eqB i0 j0 -> eqlistA s s'0 -> eqB (fold_right f i0 s) (fold_right f j0 s'0)
s':list A
i, j:B
heqij:eqB i j
heqss':eqlistA (a :: s) s'
eqB (fold_right f i (a :: s)) (fold_right f j s')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
s':list A
i, j:B
heqij:eqB i j
heqss':eqlistA nil s'

eqB (fold_right f i nil) (fold_right f j s')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
s':list A
i, j:B
heqij:eqB i j
heqss':eqlistA nil s'
H0:nil = s'

eqB (fold_right f i nil) (fold_right f j nil)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
i, j:B
heqij:eqB i j
heqss':eqlistA nil nil

eqB (fold_right f i nil) (fold_right f j nil)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
i, j:B
heqij:eqB i j
heqss':eqlistA nil nil

eqB i j
assumption.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
a:A
s:list A
IHs:forall (s'0 : list A) (i0 j0 : B), eqB i0 j0 -> eqlistA s s'0 -> eqB (fold_right f i0 s) (fold_right f j0 s'0)
s':list A
i, j:B
heqij:eqB i j
heqss':eqlistA (a :: s) s'

eqB (fold_right f i (a :: s)) (fold_right f j s')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
a:A
s:list A
IHs:forall (s'0 : list A) (i0 j0 : B), eqB i0 j0 -> eqlistA s s'0 -> eqB (fold_right f i0 s) (fold_right f j0 s'0)
s':list A
i, j:B
heqij:eqB i j
heqss':eqlistA (a :: s) s'
x, x':A
l, l':list A
H1:eqA a x'
H3:eqlistA s l'
H:x = a
H0:l = s
H2:x' :: l' = s'

eqB (fold_right f i (a :: s)) (fold_right f j (x' :: l'))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
a:A
s:list A
IHs:forall (s' : list A) (i0 j0 : B), eqB i0 j0 -> eqlistA s s' -> eqB (fold_right f i0 s) (fold_right f j0 s')
i, j:B
heqij:eqB i j
x':A
l':list A
heqss':eqlistA (a :: s) (x' :: l')
H1:eqA a x'
H3:eqlistA s l'

eqB (fold_right f i (a :: s)) (fold_right f j (x' :: l'))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
a:A
s:list A
IHs:forall (s' : list A) (i0 j0 : B), eqB i0 j0 -> eqlistA s s' -> eqB (fold_right f i0 s) (fold_right f j0 s')
i, j:B
heqij:eqB i j
x':A
l':list A
heqss':eqlistA (a :: s) (x' :: l')
H1:eqA a x'
H3:eqlistA s l'

eqB (f a (fold_right f i s)) (f x' (fold_right f j l'))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
a:A
s:list A
IHs:forall (s' : list A) (i0 j0 : B), eqB i0 j0 -> eqlistA s s' -> eqB (fold_right f i0 s) (fold_right f j0 s')
i, j:B
heqij:eqB i j
x':A
l':list A
heqss':eqlistA (a :: s) (x' :: l')
H1:eqA a x'
H3:eqlistA s l'

eqA a x'
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
a:A
s:list A
IHs:forall (s' : list A) (i0 j0 : B), eqB i0 j0 -> eqlistA s s' -> eqB (fold_right f i0 s) (fold_right f j0 s')
i, j:B
heqij:eqB i j
x':A
l':list A
heqss':eqlistA (a :: s) (x' :: l')
H1:eqA a x'
H3:eqlistA s l'
eqB (fold_right f i s) (fold_right f j l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
a:A
s:list A
IHs:forall (s' : list A) (i0 j0 : B), eqB i0 j0 -> eqlistA s s' -> eqB (fold_right f i0 s) (fold_right f j0 s')
i, j:B
heqij:eqB i j
x':A
l':list A
heqss':eqlistA (a :: s) (x' :: l')
H1:eqA a x'
H3:eqlistA s l'

eqA a x'
assumption.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
a:A
s:list A
IHs:forall (s' : list A) (i0 j0 : B), eqB i0 j0 -> eqlistA s s' -> eqB (fold_right f i0 s) (fold_right f j0 s')
i, j:B
heqij:eqB i j
x':A
l':list A
heqss':eqlistA (a :: s) (x' :: l')
H1:eqA a x'
H3:eqlistA s l'

eqB (fold_right f i s) (fold_right f j l')
apply IHs;assumption. Qed. Section Fold2_With_Restriction. Variable R : A -> A -> Prop. Hypothesis R_sym : Symmetric R. Hypothesis R_compat : Proper (eqA==>eqA==>iff) R.
Two-argument functions that allow to reorder their arguments.
Definition transpose2 (f : A -> B -> B) :=
  forall (x y : A) (z z': B), eqB z z' -> eqB (f x (f y z)) (f y (f x z')).
A version of transpose with restriction on where it should hold
Definition transpose_restr2 (R : A -> A -> Prop)(f : A -> B -> B) :=
  forall (x y : A) (z z': B), R x y -> eqB z z' -> eqB (f x (f y z)) (f y (f x z')).

Variable TraR :transpose_restr2 R f.

A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f

forall (s1 s2 : list A) (x : A) (i j : B), eqB i j -> ForallOrdPairs R (s1 ++ x :: s2) -> eqB (fold_right f i (s1 ++ x :: s2)) (f x (fold_right f j (s1 ++ s2)))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f

forall (s1 s2 : list A) (x : A) (i j : B), eqB i j -> ForallOrdPairs R (s1 ++ x :: s2) -> eqB (fold_right f i (s1 ++ x :: s2)) (f x (fold_right f j (s1 ++ s2)))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s2:list A
x:A
i, j:B
heqij:eqB i j
H:ForallOrdPairs R (x :: s2)

eqB (f x (fold_right f i s2)) (f x (fold_right f j s2))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
a:A
s1:list A
IHs1:forall (s0 : list A) (x0 : A) (i0 j0 : B), eqB i0 j0 -> ForallOrdPairs R (s1 ++ x0 :: s0) -> eqB (fold_right f i0 (s1 ++ x0 :: s0)) (f x0 (fold_right f j0 (s1 ++ s0)))
s2:list A
x:A
i, j:B
heqij:eqB i j
H:ForallOrdPairs R (a :: s1 ++ x :: s2)
eqB (f a (fold_right f i (s1 ++ x :: s2))) (f x (f a (fold_right f j (s1 ++ s2))))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s2:list A
x:A
i, j:B
heqij:eqB i j
H:ForallOrdPairs R (x :: s2)

eqB (f x (fold_right f i s2)) (f x (fold_right f j s2))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s2:list A
x:A
i, j:B
heqij:eqB i j
H:ForallOrdPairs R (x :: s2)

eqA x x
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s2:list A
x:A
i, j:B
heqij:eqB i j
H:ForallOrdPairs R (x :: s2)
eqB (fold_right f i s2) (fold_right f j s2)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s2:list A
x:A
i, j:B
heqij:eqB i j
H:ForallOrdPairs R (x :: s2)

eqA x x
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s2:list A
x:A
i, j:B
heqij:eqB i j
H:ForallOrdPairs R (x :: s2)
Equivalence_Reflexive:Reflexive eqA
Equivalence_Symmetric:Symmetric eqA
Equivalence_Transitive:Transitive eqA

eqA x x
apply Equivalence_Reflexive.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s2:list A
x:A
i, j:B
heqij:eqB i j
H:ForallOrdPairs R (x :: s2)

eqB (fold_right f i s2) (fold_right f j s2)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s2:list A
x:A
i, j:B
heqij:eqB i j
H:ForallOrdPairs R (x :: s2)

eqB i j
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s2:list A
x:A
i, j:B
heqij:eqB i j
H:ForallOrdPairs R (x :: s2)
eqlistA s2 s2
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s2:list A
x:A
i, j:B
heqij:eqB i j
H:ForallOrdPairs R (x :: s2)

eqB i j
assumption.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s2:list A
x:A
i, j:B
heqij:eqB i j
H:ForallOrdPairs R (x :: s2)

eqlistA s2 s2
reflexivity.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
a:A
s1:list A
IHs1:forall (s0 : list A) (x0 : A) (i0 j0 : B), eqB i0 j0 -> ForallOrdPairs R (s1 ++ x0 :: s0) -> eqB (fold_right f i0 (s1 ++ x0 :: s0)) (f x0 (fold_right f j0 (s1 ++ s0)))
s2:list A
x:A
i, j:B
heqij:eqB i j
H:ForallOrdPairs R (a :: s1 ++ x :: s2)

eqB (f a (fold_right f i (s1 ++ x :: s2))) (f x (f a (fold_right f j (s1 ++ s2))))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
a:A
s1:list A
IHs1:forall (s0 : list A) (x0 : A) (i0 j0 : B), eqB i0 j0 -> ForallOrdPairs R (s1 ++ x0 :: s0) -> eqB (fold_right f i0 (s1 ++ x0 :: s0)) (f x0 (fold_right f j0 (s1 ++ s0)))
s2:list A
x:A
i, j:B
heqij:eqB i j
H:ForallOrdPairs R (a :: s1 ++ x :: s2)

eqB (f a (fold_right f i (s1 ++ x :: s2))) (f a (f x (fold_right f j (s1 ++ s2))))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
a:A
s1:list A
IHs1:forall (s0 : list A) (x0 : A) (i0 j0 : B), eqB i0 j0 -> ForallOrdPairs R (s1 ++ x0 :: s0) -> eqB (fold_right f i0 (s1 ++ x0 :: s0)) (f x0 (fold_right f j0 (s1 ++ s0)))
s2:list A
x:A
i, j:B
heqij:eqB i j
H:ForallOrdPairs R (a :: s1 ++ x :: s2)
eqB (f a (f x (fold_right f j (s1 ++ s2)))) (f x (f a (fold_right f j (s1 ++ s2))))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
a:A
s1:list A
IHs1:forall (s0 : list A) (x0 : A) (i0 j0 : B), eqB i0 j0 -> ForallOrdPairs R (s1 ++ x0 :: s0) -> eqB (fold_right f i0 (s1 ++ x0 :: s0)) (f x0 (fold_right f j0 (s1 ++ s0)))
s2:list A
x:A
i, j:B
heqij:eqB i j
H:ForallOrdPairs R (a :: s1 ++ x :: s2)

eqB (fold_right f i (s1 ++ x :: s2)) (f x (fold_right f j (s1 ++ s2)))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
a:A
s1:list A
IHs1:forall (s0 : list A) (x0 : A) (i0 j0 : B), eqB i0 j0 -> ForallOrdPairs R (s1 ++ x0 :: s0) -> eqB (fold_right f i0 (s1 ++ x0 :: s0)) (f x0 (fold_right f j0 (s1 ++ s0)))
s2:list A
x:A
i, j:B
heqij:eqB i j
H:ForallOrdPairs R (a :: s1 ++ x :: s2)
eqB (f a (f x (fold_right f j (s1 ++ s2)))) (f x (f a (fold_right f j (s1 ++ s2))))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
a:A
s1:list A
IHs1:forall (s0 : list A) (x0 : A) (i0 j0 : B), eqB i0 j0 -> ForallOrdPairs R (s1 ++ x0 :: s0) -> eqB (fold_right f i0 (s1 ++ x0 :: s0)) (f x0 (fold_right f j0 (s1 ++ s0)))
s2:list A
x:A
i, j:B
heqij:eqB i j
H:ForallOrdPairs R (a :: s1 ++ x :: s2)

eqB i j
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
a:A
s1:list A
IHs1:forall (s0 : list A) (x0 : A) (i0 j0 : B), eqB i0 j0 -> ForallOrdPairs R (s1 ++ x0 :: s0) -> eqB (fold_right f i0 (s1 ++ x0 :: s0)) (f x0 (fold_right f j0 (s1 ++ s0)))
s2:list A
x:A
i, j:B
heqij:eqB i j
H:ForallOrdPairs R (a :: s1 ++ x :: s2)
ForallOrdPairs R (s1 ++ x :: s2)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
a:A
s1:list A
IHs1:forall (s0 : list A) (x0 : A) (i0 j0 : B), eqB i0 j0 -> ForallOrdPairs R (s1 ++ x0 :: s0) -> eqB (fold_right f i0 (s1 ++ x0 :: s0)) (f x0 (fold_right f j0 (s1 ++ s0)))
s2:list A
x:A
i, j:B
heqij:eqB i j
H:ForallOrdPairs R (a :: s1 ++ x :: s2)
eqB (f a (f x (fold_right f j (s1 ++ s2)))) (f x (f a (fold_right f j (s1 ++ s2))))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
a:A
s1:list A
IHs1:forall (s0 : list A) (x0 : A) (i0 j0 : B), eqB i0 j0 -> ForallOrdPairs R (s1 ++ x0 :: s0) -> eqB (fold_right f i0 (s1 ++ x0 :: s0)) (f x0 (fold_right f j0 (s1 ++ s0)))
s2:list A
x:A
i, j:B
heqij:eqB i j
H:ForallOrdPairs R (a :: s1 ++ x :: s2)

ForallOrdPairs R (s1 ++ x :: s2)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
a:A
s1:list A
IHs1:forall (s0 : list A) (x0 : A) (i0 j0 : B), eqB i0 j0 -> ForallOrdPairs R (s1 ++ x0 :: s0) -> eqB (fold_right f i0 (s1 ++ x0 :: s0)) (f x0 (fold_right f j0 (s1 ++ s0)))
s2:list A
x:A
i, j:B
heqij:eqB i j
H:ForallOrdPairs R (a :: s1 ++ x :: s2)
eqB (f a (f x (fold_right f j (s1 ++ s2)))) (f x (f a (fold_right f j (s1 ++ s2))))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
a:A
s1:list A
IHs1:forall (s0 : list A) (x0 : A) (i0 j0 : B), eqB i0 j0 -> ForallOrdPairs R (s1 ++ x0 :: s0) -> eqB (fold_right f i0 (s1 ++ x0 :: s0)) (f x0 (fold_right f j0 (s1 ++ s0)))
s2:list A
x:A
i, j:B
heqij:eqB i j
H:ForallOrdPairs R (a :: s1 ++ x :: s2)

eqB (f a (f x (fold_right f j (s1 ++ s2)))) (f x (f a (fold_right f j (s1 ++ s2))))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
a:A
s1:list A
IHs1:forall (s0 : list A) (x0 : A) (i0 j0 : B), eqB i0 j0 -> ForallOrdPairs R (s1 ++ x0 :: s0) -> eqB (fold_right f i0 (s1 ++ x0 :: s0)) (f x0 (fold_right f j0 (s1 ++ s0)))
s2:list A
x:A
i, j:B
heqij:eqB i j
H:ForallOrdPairs R (a :: s1 ++ x :: s2)

R a x
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
a:A
s1:list A
IHs1:forall (s0 : list A) (x0 : A) (i0 j0 : B), eqB i0 j0 -> ForallOrdPairs R (s1 ++ x0 :: s0) -> eqB (fold_right f i0 (s1 ++ x0 :: s0)) (f x0 (fold_right f j0 (s1 ++ s0)))
s2:list A
x:A
i, j:B
heqij:eqB i j
H:ForallOrdPairs R (a :: s1 ++ x :: s2)
eqB (fold_right f j (s1 ++ s2)) (fold_right f j (s1 ++ s2))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
a:A
s1:list A
IHs1:forall (s0 : list A) (x0 : A) (i0 j0 : B), eqB i0 j0 -> ForallOrdPairs R (s1 ++ x0 :: s0) -> eqB (fold_right f i0 (s1 ++ x0 :: s0)) (f x0 (fold_right f j0 (s1 ++ s0)))
s2:list A
x:A
i, j:B
heqij:eqB i j
H0:Forall (R a) (s1 ++ x :: s2)
H1:ForallOrdPairs R (s1 ++ x :: s2)

R a x
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
a:A
s1:list A
IHs1:forall (s0 : list A) (x0 : A) (i0 j0 : B), eqB i0 j0 -> ForallOrdPairs R (s1 ++ x0 :: s0) -> eqB (fold_right f i0 (s1 ++ x0 :: s0)) (f x0 (fold_right f j0 (s1 ++ s0)))
s2:list A
x:A
i, j:B
heqij:eqB i j
H:ForallOrdPairs R (a :: s1 ++ x :: s2)
eqB (fold_right f j (s1 ++ s2)) (fold_right f j (s1 ++ s2))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
a:A
s1:list A
IHs1:forall (s0 : list A) (x0 : A) (i0 j0 : B), eqB i0 j0 -> ForallOrdPairs R (s1 ++ x0 :: s0) -> eqB (fold_right f i0 (s1 ++ x0 :: s0)) (f x0 (fold_right f j0 (s1 ++ s0)))
s2:list A
x:A
i, j:B
heqij:eqB i j
H0:forall x0 : A, In x0 (s1 ++ x :: s2) -> R a x0
H1:ForallOrdPairs R (s1 ++ x :: s2)

In x (s1 ++ x :: s2)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
a:A
s1:list A
IHs1:forall (s0 : list A) (x0 : A) (i0 j0 : B), eqB i0 j0 -> ForallOrdPairs R (s1 ++ x0 :: s0) -> eqB (fold_right f i0 (s1 ++ x0 :: s0)) (f x0 (fold_right f j0 (s1 ++ s0)))
s2:list A
x:A
i, j:B
heqij:eqB i j
H:ForallOrdPairs R (a :: s1 ++ x :: s2)
eqB (fold_right f j (s1 ++ s2)) (fold_right f j (s1 ++ s2))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
a:A
s1:list A
IHs1:forall (s0 : list A) (x0 : A) (i0 j0 : B), eqB i0 j0 -> ForallOrdPairs R (s1 ++ x0 :: s0) -> eqB (fold_right f i0 (s1 ++ x0 :: s0)) (f x0 (fold_right f j0 (s1 ++ s0)))
s2:list A
x:A
i, j:B
heqij:eqB i j
H:ForallOrdPairs R (a :: s1 ++ x :: s2)

eqB (fold_right f j (s1 ++ s2)) (fold_right f j (s1 ++ s2))
reflexivity. Qed.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f

forall (s s' : list A) (i j : B), NoDupA s -> NoDupA s' -> ForallOrdPairs R s -> equivlistA s s' -> eqB i j -> eqB (fold_right f i s) (fold_right f j s')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f

forall (s s' : list A) (i j : B), NoDupA s -> NoDupA s' -> ForallOrdPairs R s -> equivlistA s s' -> eqB i j -> eqB (fold_right f i s) (fold_right f j s')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A

forall (s' : list A) (i j : B), NoDupA nil -> NoDupA s' -> ForallOrdPairs R nil -> equivlistA nil s' -> eqB i j -> eqB (fold_right f i nil) (fold_right f j s')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A
forall (a : A) (l : list A), (forall (s' : list A) (i j : B), NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB i j -> eqB (fold_right f i l) (fold_right f j s')) -> forall (s' : list A) (i j : B), NoDupA (a :: l) -> NoDupA s' -> ForallOrdPairs R (a :: l) -> equivlistA (a :: l) s' -> eqB i j -> eqB (fold_right f i (a :: l)) (fold_right f j s')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A

forall i j : B, NoDupA nil -> NoDupA nil -> ForallOrdPairs R nil -> equivlistA nil nil -> eqB i j -> eqB i j
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A
a:A
s':list A
forall i j : B, NoDupA nil -> NoDupA (a :: s') -> ForallOrdPairs R nil -> equivlistA nil (a :: s') -> eqB i j -> eqB i (f a (fold_right f j s'))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A
forall (a : A) (l : list A), (forall (s' : list A) (i j : B), NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB i j -> eqB (fold_right f i l) (fold_right f j s')) -> forall (s' : list A) (i j : B), NoDupA (a :: l) -> NoDupA s' -> ForallOrdPairs R (a :: l) -> equivlistA (a :: l) s' -> eqB i j -> eqB (fold_right f i (a :: l)) (fold_right f j s')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A
i, j:B
H, H0:NoDupA nil
H1:ForallOrdPairs R nil
H2:equivlistA nil nil
H3:eqB i j

eqB i j
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A
a:A
s':list A
forall i j : B, NoDupA nil -> NoDupA (a :: s') -> ForallOrdPairs R nil -> equivlistA nil (a :: s') -> eqB i j -> eqB i (f a (fold_right f j s'))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A
forall (a : A) (l : list A), (forall (s' : list A) (i j : B), NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB i j -> eqB (fold_right f i l) (fold_right f j s')) -> forall (s' : list A) (i j : B), NoDupA (a :: l) -> NoDupA s' -> ForallOrdPairs R (a :: l) -> equivlistA (a :: l) s' -> eqB i j -> eqB (fold_right f i (a :: l)) (fold_right f j s')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A
a:A
s':list A

forall i j : B, NoDupA nil -> NoDupA (a :: s') -> ForallOrdPairs R nil -> equivlistA nil (a :: s') -> eqB i j -> eqB i (f a (fold_right f j s'))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A
forall (a : A) (l : list A), (forall (s' : list A) (i j : B), NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB i j -> eqB (fold_right f i l) (fold_right f j s')) -> forall (s' : list A) (i j : B), NoDupA (a :: l) -> NoDupA s' -> ForallOrdPairs R (a :: l) -> equivlistA (a :: l) s' -> eqB i j -> eqB (fold_right f i (a :: l)) (fold_right f j s')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A
a:A
s':list A
i, j:B
H:NoDupA nil
H0:NoDupA (a :: s')
H1:ForallOrdPairs R nil
H2:forall x : A, InA x nil <-> InA x (a :: s')
H3:eqB i j

eqB i (f a (fold_right f j s'))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A
forall (a : A) (l : list A), (forall (s' : list A) (i j : B), NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB i j -> eqB (fold_right f i l) (fold_right f j s')) -> forall (s' : list A) (i j : B), NoDupA (a :: l) -> NoDupA s' -> ForallOrdPairs R (a :: l) -> equivlistA (a :: l) s' -> eqB i j -> eqB (fold_right f i (a :: l)) (fold_right f j s')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A
a:A
s':list A
i, j:B
H:NoDupA nil
H0:NoDupA (a :: s')
H1:ForallOrdPairs R nil
H2:forall x : A, InA x nil <-> InA x (a :: s')
H3:eqB i j
H4:InA a nil -> InA a (a :: s')
H5:InA a (a :: s') -> InA a nil

eqB i (f a (fold_right f j s'))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A
forall (a : A) (l : list A), (forall (s' : list A) (i j : B), NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB i j -> eqB (fold_right f i l) (fold_right f j s')) -> forall (s' : list A) (i j : B), NoDupA (a :: l) -> NoDupA s' -> ForallOrdPairs R (a :: l) -> equivlistA (a :: l) s' -> eqB i j -> eqB (fold_right f i (a :: l)) (fold_right f j s')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A

forall (a : A) (l : list A), (forall (s' : list A) (i j : B), NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB i j -> eqB (fold_right f i l) (fold_right f j s')) -> forall (s' : list A) (i j : B), NoDupA (a :: l) -> NoDupA s' -> ForallOrdPairs R (a :: l) -> equivlistA (a :: l) s' -> eqB i j -> eqB (fold_right f i (a :: l)) (fold_right f j s')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A
x:A
l:list A
Hrec:forall (s'0 : list A) (i0 j0 : B), NoDupA l -> NoDupA s'0 -> ForallOrdPairs R l -> equivlistA l s'0 -> eqB i0 j0 -> eqB (fold_right f i0 l) (fold_right f j0 s'0)
s':list A
i, j:B
N:NoDupA (x :: l)
N':NoDupA s'
F:ForallOrdPairs R (x :: l)
E:equivlistA (x :: l) s'
eqij:eqB i j

eqB (f x (fold_right f i l)) (fold_right f j s')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A
x:A
l:list A
Hrec:forall (s'0 : list A) (i0 j0 : B), NoDupA l -> NoDupA s'0 -> ForallOrdPairs R l -> equivlistA l s'0 -> eqB i0 j0 -> eqB (fold_right f i0 l) (fold_right f j0 s'0)
s':list A
i, j:B
N:NoDupA (x :: l)
N':NoDupA s'
F:ForallOrdPairs R (x :: l)
E:equivlistA (x :: l) s'
eqij:eqB i j
H:InA x s'

eqB (f x (fold_right f i l)) (fold_right f j s')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A
x:A
l:list A
Hrec:forall (s'0 : list A) (i0 j0 : B), NoDupA l -> NoDupA s'0 -> ForallOrdPairs R l -> equivlistA l s'0 -> eqB i0 j0 -> eqB (fold_right f i0 l) (fold_right f j0 s'0)
s':list A
i, j:B
N:NoDupA (x :: l)
N':NoDupA s'
F:ForallOrdPairs R (x :: l)
E:equivlistA (x :: l) s'
eqij:eqB i j
H:InA x s'
s1:list A
y:A
s2:list A
H1:eqA x y
H2:s' = s1 ++ y :: s2

eqB (f x (fold_right f i l)) (fold_right f j s')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A
x:A
l:list A
Hrec:forall (s' : list A) (i0 j0 : B), NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB i0 j0 -> eqB (fold_right f i0 l) (fold_right f j0 s')
i, j:B
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
E:equivlistA (x :: l) (s1 ++ y :: s2)
eqij:eqB i j
H:InA x (s1 ++ y :: s2)
H1:eqA x y

eqB (f x (fold_right f i l)) (fold_right f j (s1 ++ y :: s2))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A
x:A
l:list A
Hrec:forall (s' : list A) (i0 j0 : B), NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB i0 j0 -> eqB (fold_right f i0 l) (fold_right f j0 s')
i, j:B
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
E:equivlistA (x :: l) (s1 ++ y :: s2)
eqij:eqB i j
H:InA x (s1 ++ y :: s2)
H1:eqA x y

eqB (f x (fold_right f i l)) (f x (fold_right f j (s1 ++ s2)))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A
x:A
l:list A
Hrec:forall (s' : list A) (i0 j0 : B), NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB i0 j0 -> eqB (fold_right f i0 l) (fold_right f j0 s')
i, j:B
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
E:equivlistA (x :: l) (s1 ++ y :: s2)
eqij:eqB i j
H:InA x (s1 ++ y :: s2)
H1:eqA x y
eqB (f x (fold_right f j (s1 ++ s2))) (fold_right f j (s1 ++ y :: s2))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A
x:A
l:list A
Hrec:forall (s' : list A) (i0 j0 : B), NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB i0 j0 -> eqB (fold_right f i0 l) (fold_right f j0 s')
i, j:B
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
E:equivlistA (x :: l) (s1 ++ y :: s2)
eqij:eqB i j
H:InA x (s1 ++ y :: s2)
H1:eqA x y

eqB (f x (fold_right f i l)) (f x (fold_right f j (s1 ++ s2)))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A
x:A
l:list A
Hrec:forall (s' : list A) (i0 j0 : B), NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB i0 j0 -> eqB (fold_right f i0 l) (fold_right f j0 s')
i, j:B
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
E:equivlistA (x :: l) (s1 ++ y :: s2)
eqij:eqB i j
H:InA x (s1 ++ y :: s2)
H1:eqA x y

eqB (fold_right f i l) (fold_right f j (s1 ++ s2))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A
x:A
l:list A
Hrec:forall (s' : list A) (i0 j0 : B), NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB i0 j0 -> eqB (fold_right f i0 l) (fold_right f j0 s')
i, j:B
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
E:equivlistA (x :: l) (s1 ++ y :: s2)
eqij:eqB i j
H:InA x (s1 ++ y :: s2)
H1:eqA x y

NoDupA l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A
x:A
l:list A
Hrec:forall (s' : list A) (i0 j0 : B), NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB i0 j0 -> eqB (fold_right f i0 l) (fold_right f j0 s')
i, j:B
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
E:equivlistA (x :: l) (s1 ++ y :: s2)
eqij:eqB i j
H:InA x (s1 ++ y :: s2)
H1:eqA x y
NoDupA (s1 ++ s2)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A
x:A
l:list A
Hrec:forall (s' : list A) (i0 j0 : B), NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB i0 j0 -> eqB (fold_right f i0 l) (fold_right f j0 s')
i, j:B
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
E:equivlistA (x :: l) (s1 ++ y :: s2)
eqij:eqB i j
H:InA x (s1 ++ y :: s2)
H1:eqA x y
ForallOrdPairs R l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A
x:A
l:list A
Hrec:forall (s' : list A) (i0 j0 : B), NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB i0 j0 -> eqB (fold_right f i0 l) (fold_right f j0 s')
i, j:B
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
E:equivlistA (x :: l) (s1 ++ y :: s2)
eqij:eqB i j
H:InA x (s1 ++ y :: s2)
H1:eqA x y
equivlistA l (s1 ++ s2)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A
x:A
l:list A
Hrec:forall (s' : list A) (i0 j0 : B), NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB i0 j0 -> eqB (fold_right f i0 l) (fold_right f j0 s')
i, j:B
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
E:equivlistA (x :: l) (s1 ++ y :: s2)
eqij:eqB i j
H:InA x (s1 ++ y :: s2)
H1:eqA x y

NoDupA (s1 ++ s2)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A
x:A
l:list A
Hrec:forall (s' : list A) (i0 j0 : B), NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB i0 j0 -> eqB (fold_right f i0 l) (fold_right f j0 s')
i, j:B
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
E:equivlistA (x :: l) (s1 ++ y :: s2)
eqij:eqB i j
H:InA x (s1 ++ y :: s2)
H1:eqA x y
ForallOrdPairs R l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A
x:A
l:list A
Hrec:forall (s' : list A) (i0 j0 : B), NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB i0 j0 -> eqB (fold_right f i0 l) (fold_right f j0 s')
i, j:B
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
E:equivlistA (x :: l) (s1 ++ y :: s2)
eqij:eqB i j
H:InA x (s1 ++ y :: s2)
H1:eqA x y
equivlistA l (s1 ++ s2)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A
x:A
l:list A
Hrec:forall (s' : list A) (i0 j0 : B), NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB i0 j0 -> eqB (fold_right f i0 l) (fold_right f j0 s')
i, j:B
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
E:equivlistA (x :: l) (s1 ++ y :: s2)
eqij:eqB i j
H:InA x (s1 ++ y :: s2)
H1:eqA x y

ForallOrdPairs R l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A
x:A
l:list A
Hrec:forall (s' : list A) (i0 j0 : B), NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB i0 j0 -> eqB (fold_right f i0 l) (fold_right f j0 s')
i, j:B
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
E:equivlistA (x :: l) (s1 ++ y :: s2)
eqij:eqB i j
H:InA x (s1 ++ y :: s2)
H1:eqA x y
equivlistA l (s1 ++ s2)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A
x:A
l:list A
Hrec:forall (s' : list A) (i0 j0 : B), NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB i0 j0 -> eqB (fold_right f i0 l) (fold_right f j0 s')
i, j:B
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
E:equivlistA (x :: l) (s1 ++ y :: s2)
eqij:eqB i j
H:InA x (s1 ++ y :: s2)
H1:eqA x y

equivlistA l (s1 ++ s2)
eapply equivlistA_NoDupA_split; eauto.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A
x:A
l:list A
Hrec:forall (s' : list A) (i0 j0 : B), NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB i0 j0 -> eqB (fold_right f i0 l) (fold_right f j0 s')
i, j:B
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
E:equivlistA (x :: l) (s1 ++ y :: s2)
eqij:eqB i j
H:InA x (s1 ++ y :: s2)
H1:eqA x y

eqB (f x (fold_right f j (s1 ++ s2))) (fold_right f j (s1 ++ y :: s2))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A
x:A
l:list A
Hrec:forall (s' : list A) (i0 j0 : B), NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB i0 j0 -> eqB (fold_right f i0 l) (fold_right f j0 s')
i, j:B
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
E:equivlistA (x :: l) (s1 ++ y :: s2)
eqij:eqB i j
H:InA x (s1 ++ y :: s2)
H1:eqA x y

eqB (f x (fold_right f j (s1 ++ s2))) (f y (fold_right f i (s1 ++ s2)))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A
x:A
l:list A
Hrec:forall (s' : list A) (i0 j0 : B), NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB i0 j0 -> eqB (fold_right f i0 l) (fold_right f j0 s')
i, j:B
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
E:equivlistA (x :: l) (s1 ++ y :: s2)
eqij:eqB i j
H:InA x (s1 ++ y :: s2)
H1:eqA x y
eqB (f y (fold_right f i (s1 ++ s2))) (fold_right f j (s1 ++ y :: s2))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A
x:A
l:list A
Hrec:forall (s' : list A) (i0 j0 : B), NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB i0 j0 -> eqB (fold_right f i0 l) (fold_right f j0 s')
i, j:B
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
E:equivlistA (x :: l) (s1 ++ y :: s2)
eqij:eqB i j
H:InA x (s1 ++ y :: s2)
H1:eqA x y

eqB (f x (fold_right f j (s1 ++ s2))) (f y (fold_right f i (s1 ++ s2)))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A
x:A
l:list A
Hrec:forall (s' : list A) (i0 j0 : B), NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB i0 j0 -> eqB (fold_right f i0 l) (fold_right f j0 s')
i, j:B
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
E:equivlistA (x :: l) (s1 ++ y :: s2)
eqij:eqB i j
H:InA x (s1 ++ y :: s2)
H1:eqA x y

eqB (fold_right f j (s1 ++ s2)) (fold_right f i (s1 ++ s2))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A
x:A
l:list A
Hrec:forall (s' : list A) (i0 j0 : B), NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB i0 j0 -> eqB (fold_right f i0 l) (fold_right f j0 s')
i, j:B
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
E:equivlistA (x :: l) (s1 ++ y :: s2)
eqij:eqB i j
H:InA x (s1 ++ y :: s2)
H1:eqA x y

eqB (fold_right f i (s1 ++ s2)) (fold_right f j (s1 ++ s2))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A
x:A
l:list A
Hrec:forall (s' : list A) (i0 j0 : B), NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB i0 j0 -> eqB (fold_right f i0 l) (fold_right f j0 s')
i, j:B
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
E:equivlistA (x :: l) (s1 ++ y :: s2)
eqij:eqB i j
H:InA x (s1 ++ y :: s2)
H1:eqA x y

eqB i j
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A
x:A
l:list A
Hrec:forall (s' : list A) (i0 j0 : B), NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB i0 j0 -> eqB (fold_right f i0 l) (fold_right f j0 s')
i, j:B
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
E:equivlistA (x :: l) (s1 ++ y :: s2)
eqij:eqB i j
H:InA x (s1 ++ y :: s2)
H1:eqA x y
eqlistA (s1 ++ s2) (s1 ++ s2)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A
x:A
l:list A
Hrec:forall (s' : list A) (i0 j0 : B), NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB i0 j0 -> eqB (fold_right f i0 l) (fold_right f j0 s')
i, j:B
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
E:equivlistA (x :: l) (s1 ++ y :: s2)
eqij:eqB i j
H:InA x (s1 ++ y :: s2)
H1:eqA x y

eqB i j
assumption.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A
x:A
l:list A
Hrec:forall (s' : list A) (i0 j0 : B), NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB i0 j0 -> eqB (fold_right f i0 l) (fold_right f j0 s')
i, j:B
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
E:equivlistA (x :: l) (s1 ++ y :: s2)
eqij:eqB i j
H:InA x (s1 ++ y :: s2)
H1:eqA x y

eqlistA (s1 ++ s2) (s1 ++ s2)
reflexivity.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A
x:A
l:list A
Hrec:forall (s' : list A) (i0 j0 : B), NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB i0 j0 -> eqB (fold_right f i0 l) (fold_right f j0 s')
i, j:B
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
E:equivlistA (x :: l) (s1 ++ y :: s2)
eqij:eqB i j
H:InA x (s1 ++ y :: s2)
H1:eqA x y

eqB (f y (fold_right f i (s1 ++ s2))) (fold_right f j (s1 ++ y :: s2))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A
x:A
l:list A
Hrec:forall (s' : list A) (i0 j0 : B), NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB i0 j0 -> eqB (fold_right f i0 l) (fold_right f j0 s')
i, j:B
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
E:equivlistA (x :: l) (s1 ++ y :: s2)
eqij:eqB i j
H:InA x (s1 ++ y :: s2)
H1:eqA x y

eqB (fold_right f j (s1 ++ y :: s2)) (f y (fold_right f i (s1 ++ s2)))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A
x:A
l:list A
Hrec:forall (s' : list A) (i0 j0 : B), NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB i0 j0 -> eqB (fold_right f i0 l) (fold_right f j0 s')
i, j:B
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
E:equivlistA (x :: l) (s1 ++ y :: s2)
eqij:eqB i j
H:InA x (s1 ++ y :: s2)
H1:eqA x y

eqB j i
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A
x:A
l:list A
Hrec:forall (s' : list A) (i0 j0 : B), NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB i0 j0 -> eqB (fold_right f i0 l) (fold_right f j0 s')
i, j:B
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
E:equivlistA (x :: l) (s1 ++ y :: s2)
eqij:eqB i j
H:InA x (s1 ++ y :: s2)
H1:eqA x y
ForallOrdPairs R (s1 ++ y :: s2)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A
x:A
l:list A
Hrec:forall (s' : list A) (i0 j0 : B), NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB i0 j0 -> eqB (fold_right f i0 l) (fold_right f j0 s')
i, j:B
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
E:equivlistA (x :: l) (s1 ++ y :: s2)
eqij:eqB i j
H:InA x (s1 ++ y :: s2)
H1:eqA x y

eqB i j
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A
x:A
l:list A
Hrec:forall (s' : list A) (i0 j0 : B), NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB i0 j0 -> eqB (fold_right f i0 l) (fold_right f j0 s')
i, j:B
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
E:equivlistA (x :: l) (s1 ++ y :: s2)
eqij:eqB i j
H:InA x (s1 ++ y :: s2)
H1:eqA x y
ForallOrdPairs R (s1 ++ y :: s2)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A
x:A
l:list A
Hrec:forall (s' : list A) (i0 j0 : B), NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB i0 j0 -> eqB (fold_right f i0 l) (fold_right f j0 s')
i, j:B
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
E:equivlistA (x :: l) (s1 ++ y :: s2)
eqij:eqB i j
H:InA x (s1 ++ y :: s2)
H1:eqA x y

ForallOrdPairs R (s1 ++ y :: s2)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f
s:list A
x:A
l:list A
Hrec:forall (s' : list A) (i0 j0 : B), NoDupA l -> NoDupA s' -> ForallOrdPairs R l -> equivlistA l s' -> eqB i0 j0 -> eqB (fold_right f i0 l) (fold_right f j0 s')
i, j:B
N:NoDupA (x :: l)
s1:list A
y:A
s2:list A
N':NoDupA (s1 ++ y :: s2)
F:ForallOrdPairs R (x :: l)
E:equivlistA (x :: l) (s1 ++ y :: s2)
eqij:eqB i j
H:InA x (s1 ++ y :: s2)
H1:eqA x y

inclA (s1 ++ y :: s2) (x :: l)
red; intros; rewrite E; auto. Qed.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f

forall (s' s : list A) (i j : B) (x : A), NoDupA s -> NoDupA s' -> eqB i j -> ForallOrdPairs R s' -> ~ InA x s -> equivlistA s' (x :: s) -> eqB (fold_right f i s') (f x (fold_right f j s))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
R:A -> A -> Prop
R_sym:Symmetric R
R_compat:Proper (eqA ==> eqA ==> iff) R
TraR:transpose_restr2 R f

forall (s' s : list A) (i j : B) (x : A), NoDupA s -> NoDupA s' -> eqB i j -> ForallOrdPairs R s' -> ~ InA x s -> equivlistA s' (x :: s) -> eqB (fold_right f i s') (f x (fold_right f j s))
intros; apply (@fold_right_equivlistA_restr2 s' (x::s) i j); auto. Qed. End Fold2_With_Restriction. Variable Tra :transpose2 f.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
Tra:transpose2 f

forall (s1 s2 : list A) (i : B) (x x' : A), eqA x x' -> eqB (fold_right f i (s1 ++ x :: s2)) (f x' (fold_right f i (s1 ++ s2)))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
Tra:transpose2 f

forall (s1 s2 : list A) (i : B) (x x' : A), eqA x x' -> eqB (fold_right f i (s1 ++ x :: s2)) (f x' (fold_right f i (s1 ++ s2)))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
Tra:transpose2 f
s2:list A
i:B
x, x':A
H:eqA x x'

eqB (f x (fold_right f i s2)) (f x' (fold_right f i s2))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
Tra:transpose2 f
a:A
s1:list A
IHs1:forall (s0 : list A) (i0 : B) (x0 x'0 : A), eqA x0 x'0 -> eqB (fold_right f i0 (s1 ++ x0 :: s0)) (f x'0 (fold_right f i0 (s1 ++ s0)))
s2:list A
i:B
x, x':A
H:eqA x x'
eqB (f a (fold_right f i (s1 ++ x :: s2))) (f x' (f a (fold_right f i (s1 ++ s2))))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
Tra:transpose2 f
s2:list A
i:B
x, x':A
H:eqA x x'

eqB (f x (fold_right f i s2)) (f x' (fold_right f i s2))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
Tra:transpose2 f
s2:list A
i:B
x, x':A
H:eqA x x'

eqB (fold_right f i s2) (fold_right f i s2)
reflexivity.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
Tra:transpose2 f
a:A
s1:list A
IHs1:forall (s0 : list A) (i0 : B) (x0 x'0 : A), eqA x0 x'0 -> eqB (fold_right f i0 (s1 ++ x0 :: s0)) (f x'0 (fold_right f i0 (s1 ++ s0)))
s2:list A
i:B
x, x':A
H:eqA x x'

eqB (f a (fold_right f i (s1 ++ x :: s2))) (f x' (f a (fold_right f i (s1 ++ s2))))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
Tra:transpose2 f
a:A
s1:list A
IHs1:forall (s0 : list A) (i0 : B) (x0 x'0 : A), eqA x0 x'0 -> eqB (fold_right f i0 (s1 ++ x0 :: s0)) (f x'0 (fold_right f i0 (s1 ++ s0)))
s2:list A
i:B
x, x':A
H:eqA x x'

eqB (f a (fold_right f i (s1 ++ x :: s2))) (f a (f x' (fold_right f i (s1 ++ s2))))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
Tra:transpose2 f
a:A
s1:list A
IHs1:forall (s0 : list A) (i0 : B) (x0 x'0 : A), eqA x0 x'0 -> eqB (fold_right f i0 (s1 ++ x0 :: s0)) (f x'0 (fold_right f i0 (s1 ++ s0)))
s2:list A
i:B
x, x':A
H:eqA x x'
eqB (f a (f x' (fold_right f i (s1 ++ s2)))) (f x' (f a (fold_right f i (s1 ++ s2))))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
Tra:transpose2 f
a:A
s1:list A
IHs1:forall (s0 : list A) (i0 : B) (x0 x'0 : A), eqA x0 x'0 -> eqB (fold_right f i0 (s1 ++ x0 :: s0)) (f x'0 (fold_right f i0 (s1 ++ s0)))
s2:list A
i:B
x, x':A
H:eqA x x'

eqB (f a (fold_right f i (s1 ++ x :: s2))) (f a (f x' (fold_right f i (s1 ++ s2))))
apply Comp;auto.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
Tra:transpose2 f
a:A
s1:list A
IHs1:forall (s0 : list A) (i0 : B) (x0 x'0 : A), eqA x0 x'0 -> eqB (fold_right f i0 (s1 ++ x0 :: s0)) (f x'0 (fold_right f i0 (s1 ++ s0)))
s2:list A
i:B
x, x':A
H:eqA x x'

eqB (f a (f x' (fold_right f i (s1 ++ s2)))) (f x' (f a (fold_right f i (s1 ++ s2))))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
Tra:transpose2 f
a:A
s1:list A
IHs1:forall (s0 : list A) (i0 : B) (x0 x'0 : A), eqA x0 x'0 -> eqB (fold_right f i0 (s1 ++ x0 :: s0)) (f x'0 (fold_right f i0 (s1 ++ s0)))
s2:list A
i:B
x, x':A
H:eqA x x'

eqB (fold_right f i (s1 ++ s2)) (fold_right f i (s1 ++ s2))
reflexivity. Qed.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
Tra:transpose2 f

forall (s s' : list A) (i j : B), NoDupA s -> NoDupA s' -> eqB i j -> equivlistA s s' -> eqB (fold_right f i s) (fold_right f j s')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
Tra:transpose2 f

forall (s s' : list A) (i j : B), NoDupA s -> NoDupA s' -> eqB i j -> equivlistA s s' -> eqB (fold_right f i s) (fold_right f j s')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
Tra:forall (x y : A) (z z' : B), eqB z z' -> eqB (f x (f y z)) (f y (f x z'))

forall (s s' : list A) (i j : B), NoDupA s -> NoDupA s' -> eqB i j -> equivlistA s s' -> eqB (fold_right f i s) (fold_right f j s')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
Tra:forall (x y : A) (z z' : B), eqB z z' -> eqB (f x (f y z)) (f y (f x z'))
s, s':list A
i, j:B
H:NoDupA s
H0:NoDupA s'
H1:eqB i j
H2:equivlistA s s'

ForallOrdPairs (fun _ _ : A => True) s
apply ForallPairs_ForallOrdPairs; try red; auto. Qed.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
Tra:transpose2 f

forall (s' s : list A) (i j : B) (x : A), NoDupA s -> NoDupA s' -> eqB i j -> ~ InA x s -> equivlistA s' (x :: s) -> eqB (fold_right f i s') (f x (fold_right f j s))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
Tra:transpose2 f

forall (s' s : list A) (i j : B) (x : A), NoDupA s -> NoDupA s' -> eqB i j -> ~ InA x s -> equivlistA s' (x :: s) -> eqB (fold_right f i s') (f x (fold_right f j s))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
Tra:transpose2 f
s', s:list A
i, j:B
x:A
H:NoDupA s
H0:NoDupA s'
H1:eqB i j
H2:~ InA x s
H3:equivlistA s' (x :: s)

eqB (fold_right f i s') (f x (fold_right f j s))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
B:Type
eqB:B -> B -> Prop
st:Equivalence eqB
f:A -> B -> B
Comp:Proper (eqA ==> eqB ==> eqB) f
Tra:transpose2 f
s', s:list A
i, j:B
x:A
H:NoDupA s
H0:NoDupA s'
H1:eqB i j
H2:~ InA x s
H3:equivlistA s' (x :: s)

eqB (fold_right f i s') (fold_right f j (x :: s))
eapply fold_right_equivlistA2;auto. Qed. End Fold2. Section Remove. Hypothesis eqA_dec : forall x y : A, {eqA x y}+{~(eqA x y)}.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}

forall (x : A) (l : list A), {InA x l} + {~ InA x l}
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}

forall (x : A) (l : list A), {InA x l} + {~ InA x l}
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x0 y : A, {eqA x0 y} + {~ eqA x0 y}
x:A

{InA x nil} + {~ InA x nil}
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x0 y : A, {eqA x0 y} + {~ eqA x0 y}
x, a:A
l:list A
IHl:{InA x l} + {~ InA x l}
{InA x (a :: l)} + {~ InA x (a :: l)}
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x0 y : A, {eqA x0 y} + {~ eqA x0 y}
x:A

~ InA x nil
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x0 y : A, {eqA x0 y} + {~ eqA x0 y}
x, a:A
l:list A
IHl:{InA x l} + {~ InA x l}
{InA x (a :: l)} + {~ InA x (a :: l)}
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x0 y : A, {eqA x0 y} + {~ eqA x0 y}
x, a:A
l:list A
IHl:{InA x l} + {~ InA x l}

{InA x (a :: l)} + {~ InA x (a :: l)}
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x0 y : A, {eqA x0 y} + {~ eqA x0 y}
x, a:A
l:list A
IHl:{InA x l} + {~ InA x l}
e:eqA x a

{InA x (a :: l)} + {~ InA x (a :: l)}
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x0 y : A, {eqA x0 y} + {~ eqA x0 y}
x, a:A
l:list A
IHl:{InA x l} + {~ InA x l}
n:~ eqA x a
{InA x (a :: l)} + {~ InA x (a :: l)}
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x0 y : A, {eqA x0 y} + {~ eqA x0 y}
x, a:A
l:list A
IHl:{InA x l} + {~ InA x l}
n:~ eqA x a

{InA x (a :: l)} + {~ InA x (a :: l)}
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x0 y : A, {eqA x0 y} + {~ eqA x0 y}
x, a:A
l:list A
i:InA x l
n:~ eqA x a

{InA x (a :: l)} + {~ InA x (a :: l)}
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x0 y : A, {eqA x0 y} + {~ eqA x0 y}
x, a:A
l:list A
n0:~ InA x l
n:~ eqA x a
{InA x (a :: l)} + {~ InA x (a :: l)}
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x0 y : A, {eqA x0 y} + {~ eqA x0 y}
x, a:A
l:list A
n0:~ InA x l
n:~ eqA x a

{InA x (a :: l)} + {~ InA x (a :: l)}
right; intro; inv; contradiction. Defined. Fixpoint removeA (x : A) (l : list A) : list A := match l with | nil => nil | y::tl => if (eqA_dec x y) then removeA x tl else y::(removeA x tl) end.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}

forall (x : A) (l : list A), removeA x l = filter (fun y : A => if eqA_dec x y then false else true) l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}

forall (x : A) (l : list A), removeA x l = filter (fun y : A => if eqA_dec x y then false else true) l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x0 y : A, {eqA x0 y} + {~ eqA x0 y}
x, a:A
l:list A
IHl:removeA x l = filter (fun y : A => if eqA_dec x y then false else true) l

(if eqA_dec x a then removeA x l else a :: removeA x l) = (if if eqA_dec x a then false else true then a :: filter (fun y : A => if eqA_dec x y then false else true) l else filter (fun y : A => if eqA_dec x y then false else true) l)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x0 y : A, {eqA x0 y} + {~ eqA x0 y}
x, a:A
l:list A
IHl:removeA x l = filter (fun y : A => if eqA_dec x y then false else true) l
n:~ eqA x a

a :: removeA x l = a :: filter (fun y : A => if eqA_dec x y then false else true) l
rewrite IHl; auto. Qed.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}

forall (l : list A) (x y : A), InA y (removeA x l) <-> InA y l /\ ~ eqA x y
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}

forall (l : list A) (x y : A), InA y (removeA x l) <-> InA y l /\ ~ eqA x y
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}

forall x y : A, InA y nil <-> InA y nil /\ ~ eqA x y
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
a:A
l:list A
IHl:forall x y : A, InA y (removeA x l) <-> InA y l /\ ~ eqA x y
forall x y : A, InA y (if eqA_dec x a then removeA x l else a :: removeA x l) <-> InA y (a :: l) /\ ~ eqA x y
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x0 y0 : A, {eqA x0 y0} + {~ eqA x0 y0}
x, y:A

InA y nil -> InA y nil /\ ~ eqA x y
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x0 y0 : A, {eqA x0 y0} + {~ eqA x0 y0}
x, y:A
InA y nil /\ ~ eqA x y -> InA y nil
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
a:A
l:list A
IHl:forall x y : A, InA y (removeA x l) <-> InA y l /\ ~ eqA x y
forall x y : A, InA y (if eqA_dec x a then removeA x l else a :: removeA x l) <-> InA y (a :: l) /\ ~ eqA x y
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x0 y0 : A, {eqA x0 y0} + {~ eqA x0 y0}
x, y:A

InA y nil /\ ~ eqA x y -> InA y nil
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
a:A
l:list A
IHl:forall x y : A, InA y (removeA x l) <-> InA y l /\ ~ eqA x y
forall x y : A, InA y (if eqA_dec x a then removeA x l else a :: removeA x l) <-> InA y (a :: l) /\ ~ eqA x y
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
a:A
l:list A
IHl:forall x y : A, InA y (removeA x l) <-> InA y l /\ ~ eqA x y

forall x y : A, InA y (if eqA_dec x a then removeA x l else a :: removeA x l) <-> InA y (a :: l) /\ ~ eqA x y
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x0 y0 : A, {eqA x0 y0} + {~ eqA x0 y0}
a:A
l:list A
IHl:forall x0 y0 : A, InA y0 (removeA x0 l) <-> InA y0 l /\ ~ eqA x0 y0
x, y:A

InA y (if eqA_dec x a then removeA x l else a :: removeA x l) <-> InA y (a :: l) /\ ~ eqA x y
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x0 y0 : A, {eqA x0 y0} + {~ eqA x0 y0}
a:A
l:list A
IHl:forall x0 y0 : A, InA y0 (removeA x0 l) <-> InA y0 l /\ ~ eqA x0 y0
x, y:A
Heq:eqA x a

InA y (removeA x l) <-> InA y (a :: l) /\ ~ eqA x y
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x0 y0 : A, {eqA x0 y0} + {~ eqA x0 y0}
a:A
l:list A
IHl:forall x0 y0 : A, InA y0 (removeA x0 l) <-> InA y0 l /\ ~ eqA x0 y0
x, y:A
Hnot:~ eqA x a
InA y (a :: removeA x l) <-> InA y (a :: l) /\ ~ eqA x y
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x0 y0 : A, {eqA x0 y0} + {~ eqA x0 y0}
a:A
l:list A
IHl:forall x0 y0 : A, InA y0 (removeA x0 l) <-> InA y0 l /\ ~ eqA x0 y0
x, y:A
Heq:eqA x a
H:InA y (a :: l)
H0:~ eqA x y

InA y l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x0 y0 : A, {eqA x0 y0} + {~ eqA x0 y0}
a:A
l:list A
IHl:forall x0 y0 : A, InA y0 (removeA x0 l) <-> InA y0 l /\ ~ eqA x0 y0
x, y:A
Hnot:~ eqA x a
InA y (a :: removeA x l) <-> InA y (a :: l) /\ ~ eqA x y
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x0 y0 : A, {eqA x0 y0} + {~ eqA x0 y0}
a:A
l:list A
IHl:forall x0 y0 : A, InA y0 (removeA x0 l) <-> InA y0 l /\ ~ eqA x0 y0
x, y:A
Heq:eqA x a
H0:~ eqA x y
H1:eqA y a

InA y l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x0 y0 : A, {eqA x0 y0} + {~ eqA x0 y0}
a:A
l:list A
IHl:forall x0 y0 : A, InA y0 (removeA x0 l) <-> InA y0 l /\ ~ eqA x0 y0
x, y:A
Hnot:~ eqA x a
InA y (a :: removeA x l) <-> InA y (a :: l) /\ ~ eqA x y
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x0 y0 : A, {eqA x0 y0} + {~ eqA x0 y0}
a:A
l:list A
IHl:forall x0 y0 : A, InA y0 (removeA x0 l) <-> InA y0 l /\ ~ eqA x0 y0
x, y:A
Hnot:~ eqA x a

InA y (a :: removeA x l) <-> InA y (a :: l) /\ ~ eqA x y
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x0 y0 : A, {eqA x0 y0} + {~ eqA x0 y0}
a:A
l:list A
IHl:forall x0 y0 : A, InA y0 (removeA x0 l) <-> InA y0 l /\ ~ eqA x0 y0
x, y:A
Hnot:~ eqA x a

InA y (a :: removeA x l) -> InA y (a :: l) /\ ~ eqA x y
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x0 y0 : A, {eqA x0 y0} + {~ eqA x0 y0}
a:A
l:list A
IHl:forall x0 y0 : A, InA y0 (removeA x0 l) <-> InA y0 l /\ ~ eqA x0 y0
x, y:A
Hnot:~ eqA x a
InA y (a :: l) /\ ~ eqA x y -> InA y (a :: removeA x l)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x0 y0 : A, {eqA x0 y0} + {~ eqA x0 y0}
a:A
l:list A
IHl:forall x0 y0 : A, InA y0 (removeA x0 l) <-> InA y0 l /\ ~ eqA x0 y0
x, y:A
Hnot:~ eqA x a
H0:eqA y a

InA y (a :: l) /\ ~ eqA x y
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x0 y0 : A, {eqA x0 y0} + {~ eqA x0 y0}
a:A
l:list A
IHl:forall x0 y0 : A, InA y0 (removeA x0 l) <-> InA y0 l /\ ~ eqA x0 y0
x, y:A
Hnot:~ eqA x a
H0:InA y (removeA x l)
InA y (a :: l) /\ ~ eqA x y
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x0 y0 : A, {eqA x0 y0} + {~ eqA x0 y0}
a:A
l:list A
IHl:forall x0 y0 : A, InA y0 (removeA x0 l) <-> InA y0 l /\ ~ eqA x0 y0
x, y:A
Hnot:~ eqA x a
InA y (a :: l) /\ ~ eqA x y -> InA y (a :: removeA x l)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x0 y0 : A, {eqA x0 y0} + {~ eqA x0 y0}
a:A
l:list A
IHl:forall x0 y0 : A, InA y0 (removeA x0 l) <-> InA y0 l /\ ~ eqA x0 y0
x, y:A
Hnot:~ eqA x a
H0:eqA y a

~ eqA x y
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x0 y0 : A, {eqA x0 y0} + {~ eqA x0 y0}
a:A
l:list A
IHl:forall x0 y0 : A, InA y0 (removeA x0 l) <-> InA y0 l /\ ~ eqA x0 y0
x, y:A
Hnot:~ eqA x a
H0:InA y (removeA x l)
InA y (a :: l) /\ ~ eqA x y
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x0 y0 : A, {eqA x0 y0} + {~ eqA x0 y0}
a:A
l:list A
IHl:forall x0 y0 : A, InA y0 (removeA x0 l) <-> InA y0 l /\ ~ eqA x0 y0
x, y:A
Hnot:~ eqA x a
InA y (a :: l) /\ ~ eqA x y -> InA y (a :: removeA x l)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x0 y0 : A, {eqA x0 y0} + {~ eqA x0 y0}
a:A
l:list A
IHl:forall x0 y0 : A, InA y0 (removeA x0 l) <-> InA y0 l /\ ~ eqA x0 y0
x, y:A
H0:eqA y a
Hnot:eqA x y

eqA x a
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x0 y0 : A, {eqA x0 y0} + {~ eqA x0 y0}
a:A
l:list A
IHl:forall x0 y0 : A, InA y0 (removeA x0 l) <-> InA y0 l /\ ~ eqA x0 y0
x, y:A
Hnot:~ eqA x a
H0:InA y (removeA x l)
InA y (a :: l) /\ ~ eqA x y
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x0 y0 : A, {eqA x0 y0} + {~ eqA x0 y0}
a:A
l:list A
IHl:forall x0 y0 : A, InA y0 (removeA x0 l) <-> InA y0 l /\ ~ eqA x0 y0
x, y:A
Hnot:~ eqA x a
InA y (a :: l) /\ ~ eqA x y -> InA y (a :: removeA x l)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x0 y0 : A, {eqA x0 y0} + {~ eqA x0 y0}
a:A
l:list A
IHl:forall x0 y0 : A, InA y0 (removeA x0 l) <-> InA y0 l /\ ~ eqA x0 y0
x, y:A
Hnot:~ eqA x a
H0:InA y (removeA x l)

InA y (a :: l) /\ ~ eqA x y
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x0 y0 : A, {eqA x0 y0} + {~ eqA x0 y0}
a:A
l:list A
IHl:forall x0 y0 : A, InA y0 (removeA x0 l) <-> InA y0 l /\ ~ eqA x0 y0
x, y:A
Hnot:~ eqA x a
InA y (a :: l) /\ ~ eqA x y -> InA y (a :: removeA x l)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x0 y0 : A, {eqA x0 y0} + {~ eqA x0 y0}
a:A
l:list A
IHl:forall x0 y0 : A, InA y0 (removeA x0 l) <-> InA y0 l /\ ~ eqA x0 y0
x, y:A
Hnot:~ eqA x a

InA y (a :: l) /\ ~ eqA x y -> InA y (a :: removeA x l)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x0 y0 : A, {eqA x0 y0} + {~ eqA x0 y0}
a:A
l:list A
IHl:forall x0 y0 : A, InA y0 (removeA x0 l) <-> InA y0 l /\ ~ eqA x0 y0
x, y:A
Hnot:~ eqA x a
H0:~ eqA x y
H1:InA y l

InA y (a :: removeA x l)
right; rewrite IHl; auto. Qed.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}

forall (s : list A) (x : A), NoDupA s -> NoDupA (removeA x s)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}

forall (s : list A) (x : A), NoDupA s -> NoDupA (removeA x s)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x0 y : A, {eqA x0 y} + {~ eqA x0 y}
s:list A
x:A
H:NoDupA nil

NoDupA nil
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x0 y : A, {eqA x0 y} + {~ eqA x0 y}
s:list A
a:A
l:list A
H:forall x0 : A, NoDupA l -> NoDupA (removeA x0 l)
x:A
H0:NoDupA (a :: l)
NoDupA (if eqA_dec x a then removeA x l else a :: removeA x l)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x0 y : A, {eqA x0 y} + {~ eqA x0 y}
s:list A
a:A
l:list A
H:forall x0 : A, NoDupA l -> NoDupA (removeA x0 l)
x:A
H0:NoDupA (a :: l)

NoDupA (if eqA_dec x a then removeA x l else a :: removeA x l)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x0 y : A, {eqA x0 y} + {~ eqA x0 y}
s:list A
a:A
l:list A
H:forall x0 : A, NoDupA l -> NoDupA (removeA x0 l)
x:A
H1:~ InA a l
H2:NoDupA l

NoDupA (if eqA_dec x a then removeA x l else a :: removeA x l)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x0 y : A, {eqA x0 y} + {~ eqA x0 y}
s:list A
a:A
l:list A
H:forall x0 : A, NoDupA l -> NoDupA (removeA x0 l)
x:A
H1:~ InA a l
H2:NoDupA l
n:~ eqA x a

NoDupA (a :: removeA x l)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x0 y : A, {eqA x0 y} + {~ eqA x0 y}
s:list A
a:A
l:list A
H:forall x0 : A, NoDupA l -> NoDupA (removeA x0 l)
x:A
H1:~ InA a l
H2:NoDupA l
n:~ eqA x a

~ InA a (removeA x l)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x0 y : A, {eqA x0 y} + {~ eqA x0 y}
s:list A
a:A
l:list A
H:forall x0 : A, NoDupA l -> NoDupA (removeA x0 l)
x:A
H1:~ InA a l
H2:NoDupA l
n:~ eqA x a

~ (InA a l /\ ~ eqA x a)
intuition. Qed.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}

forall (l l' : list A) (x : A), ~ InA x l -> equivlistA (x :: l) l' -> equivlistA l (removeA x l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}

forall (l l' : list A) (x : A), ~ InA x l -> equivlistA (x :: l) l' -> equivlistA l (removeA x l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x1 y : A, {eqA x1 y} + {~ eqA x1 y}
l, l':list A
x:A
H:~ InA x l
H0:forall x1 : A, InA x1 (x :: l) <-> InA x1 l'
x0:A

InA x0 l <-> InA x0 (removeA x l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x1 y : A, {eqA x1 y} + {~ eqA x1 y}
l, l':list A
x:A
H:~ InA x l
H0:forall x1 : A, InA x1 (x :: l) <-> InA x1 l'
x0:A

InA x0 l <-> InA x0 l' /\ ~ eqA x x0
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x1 y : A, {eqA x1 y} + {~ eqA x1 y}
l, l':list A
x:A
H:~ InA x l
H0:forall x1 : A, InA x1 (x :: l) <-> InA x1 l'
x0:A
H1:InA x0 l

InA x0 l' /\ ~ eqA x x0
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x1 y : A, {eqA x1 y} + {~ eqA x1 y}
l, l':list A
x:A
H:~ InA x l
H0:forall x1 : A, InA x1 (x :: l) <-> InA x1 l'
x0:A
H1:InA x0 l' /\ ~ eqA x x0
InA x0 l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x1 y : A, {eqA x1 y} + {~ eqA x1 y}
l, l':list A
x:A
H:~ InA x l
H0:forall x1 : A, InA x1 (x :: l) <-> InA x1 l'
x0:A
H1:InA x0 l

~ eqA x x0
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x1 y : A, {eqA x1 y} + {~ eqA x1 y}
l, l':list A
x:A
H:~ InA x l
H0:forall x1 : A, InA x1 (x :: l) <-> InA x1 l'
x0:A
H1:InA x0 l' /\ ~ eqA x x0
InA x0 l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x1 y : A, {eqA x1 y} + {~ eqA x1 y}
l, l':list A
x:A
H0:forall x1 : A, InA x1 (x :: l) <-> InA x1 l'
x0:A
H1:InA x0 l
H:eqA x x0

InA x l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x1 y : A, {eqA x1 y} + {~ eqA x1 y}
l, l':list A
x:A
H:~ InA x l
H0:forall x1 : A, InA x1 (x :: l) <-> InA x1 l'
x0:A
H1:InA x0 l' /\ ~ eqA x x0
InA x0 l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x1 y : A, {eqA x1 y} + {~ eqA x1 y}
l, l':list A
x:A
H:~ InA x l
H0:forall x1 : A, InA x1 (x :: l) <-> InA x1 l'
x0:A
H1:InA x0 l' /\ ~ eqA x x0

InA x0 l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x1 y : A, {eqA x1 y} + {~ eqA x1 y}
l, l':list A
x:A
H:~ InA x l
H0:forall x1 : A, InA x1 (x :: l) <-> InA x1 l'
x0:A
H1:InA x0 (x :: l) /\ ~ eqA x x0

InA x0 l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x1 y : A, {eqA x1 y} + {~ eqA x1 y}
l, l':list A
x:A
H:~ InA x l
H0:forall x1 : A, InA x1 (x :: l) <-> InA x1 l'
x0:A
H1:InA x0 (x :: l)
H2:~ eqA x x0

InA x0 l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x1 y : A, {eqA x1 y} + {~ eqA x1 y}
l, l':list A
x:A
H:~ InA x l
H0:forall x1 : A, InA x1 (x :: l) <-> InA x1 l'
x0:A
H2:~ eqA x x0
H3:eqA x0 x

InA x0 l
elim H2; auto. Qed. End Remove.
Results concerning lists modulo eqA and ltA
Variable ltA : A -> A -> Prop.
Hypothesis ltA_strorder : StrictOrder ltA.
Hypothesis ltA_compat : Proper (eqA==>eqA==>iff) ltA.

Let sotrans := (@StrictOrder_Transitive _ _ ltA_strorder).

Hint Resolve sotrans : core.

Notation InfA:=(lelistA ltA).
Notation SortA:=(sort ltA).

Hint Constructors lelistA sort : core.

A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA

forall (l : list A) (x y : A), ltA x y -> InfA y l -> InfA x l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA

forall (l : list A) (x y : A), ltA x y -> InfA y l -> InfA x l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l:list A
x, y:A
H:ltA x y
H0:InfA y (a :: l)

ltA x a
inv; eauto. Qed.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA

Proper (eqA ==> eqlistA ==> iff) InfA
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA

Proper (eqA ==> eqlistA ==> iff) InfA
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
x, x':A
Hxx':eqA x x'
l, l':list A
Hll':eqlistA l l'

InfA x l <-> InfA x' l'
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
x, x':A
Hxx':eqA x x'
l, l':list A

InfA x nil <-> InfA x' nil
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
x, x':A
Hxx':eqA x x'
l, l':list A
x0, x'0:A
l0, l'0:list A
H:eqA x0 x'0
H0:eqlistA l0 l'0
InfA x (x0 :: l0) <-> InfA x' (x'0 :: l'0)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
x, x':A
Hxx':eqA x x'
l, l':list A
x0, x'0:A
l0, l'0:list A
H:eqA x0 x'0
H0:eqlistA l0 l'0

InfA x (x0 :: l0) <-> InfA x' (x'0 :: l'0)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
x, x':A
Hxx':eqA x x'
l, l':list A
x0, x'0:A
l0, l'0:list A
H:eqA x0 x'0
H0:eqlistA l0 l'0
H2:ltA x x0

ltA x' x'0
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
x, x':A
Hxx':eqA x x'
l, l':list A
x0, x'0:A
l0, l'0:list A
H:eqA x0 x'0
H0:eqlistA l0 l'0
H2:ltA x' x'0
ltA x x0
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
x, x':A
Hxx':eqA x x'
l, l':list A
x0, x'0:A
l0, l'0:list A
H:eqA x0 x'0
H0:eqlistA l0 l'0
H2:ltA x' x'0

ltA x x0
rewrite Hxx', H; auto. Qed.
For compatibility, can be deduced from InfA_compat
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
l:list A
x, y:A

eqA x y -> InfA y l -> InfA x l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
l:list A
x, y:A

eqA x y -> InfA y l -> InfA x l
intros H; now rewrite H. Qed. Hint Immediate InfA_ltA InfA_eqA : core.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA

forall (l : list A) (x a : A), SortA l -> InfA a l -> InA x l -> ltA a x
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA

forall (l : list A) (x a : A), SortA l -> InfA a l -> InA x l -> ltA a x
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
l:list A

forall x a : A, SortA nil -> InfA a nil -> InA x nil -> ltA a x
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
l:list A
forall (a : A) (l0 : list A), (forall x a0 : A, SortA l0 -> InfA a0 l0 -> InA x l0 -> ltA a0 x) -> forall x a0 : A, SortA (a :: l0) -> InfA a0 (a :: l0) -> InA x (a :: l0) -> ltA a0 x
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
l:list A
x, a:A
H:SortA nil
H0:InfA a nil
H1:InA x nil

ltA a x
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
l:list A
forall (a : A) (l0 : list A), (forall x a0 : A, SortA l0 -> InfA a0 l0 -> InA x l0 -> ltA a0 x) -> forall x a0 : A, SortA (a :: l0) -> InfA a0 (a :: l0) -> InA x (a :: l0) -> ltA a0 x
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
l:list A

forall (a : A) (l0 : list A), (forall x a0 : A, SortA l0 -> InfA a0 l0 -> InA x l0 -> ltA a0 x) -> forall x a0 : A, SortA (a :: l0) -> InfA a0 (a :: l0) -> InA x (a :: l0) -> ltA a0 x
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
l:list A
a:A
l0:list A
H:forall x0 a1 : A, SortA l0 -> InfA a1 l0 -> InA x0 l0 -> ltA a1 x0
x, a0:A
H0:SortA (a :: l0)
H1:InfA a0 (a :: l0)
H2:InA x (a :: l0)

ltA a0 x
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
l:list A
a:A
l0:list A
H:forall x0 a1 : A, SortA l0 -> InfA a1 l0 -> InA x0 l0 -> ltA a1 x0
x, a0:A
H3:eqA x a
H2:SortA l0
H4:InfA a l0
H0:ltA a0 a

ltA a0 x
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
l:list A
a:A
l0:list A
H:forall x0 a1 : A, SortA l0 -> InfA a1 l0 -> InA x0 l0 -> ltA a1 x0
x, a0:A
H3:InA x l0
H2:SortA l0
H4:InfA a l0
H0:ltA a0 a
ltA a0 x
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
l:list A
a:A
l0:list A
H:forall x0 a1 : A, SortA l0 -> InfA a1 l0 -> InA x0 l0 -> ltA a1 x0
x, a0:A
H3:InA x l0
H2:SortA l0
H4:InfA a l0
H0:ltA a0 a

ltA a0 x
eauto. Qed.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA

forall (l : list A) (x : A), (forall y : A, In y l -> ltA x y) -> InfA x l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA

forall (l : list A) (x : A), (forall y : A, In y l -> ltA x y) -> InfA x l
simple induction l; simpl; intros; constructor; auto. Qed.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA

forall (l : list A) (x : A), (forall y : A, InA y l -> ltA x y) -> InfA x l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA

forall (l : list A) (x : A), (forall y : A, InA y l -> ltA x y) -> InfA x l
simple induction l; simpl; intros; constructor; auto. Qed. (* In fact, this may be used as an alternative definition for InfA: *)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA

forall (l : list A) (x : A), SortA l -> InfA x l <-> (forall y : A, InA y l -> ltA x y)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA

forall (l : list A) (x : A), SortA l -> InfA x l <-> (forall y : A, InA y l -> ltA x y)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
l:list A
x:A
H:SortA l

InfA x l -> forall y : A, InA y l -> ltA x y
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
l:list A
x:A
H:SortA l
(forall y : A, InA y l -> ltA x y) -> InfA x l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
l:list A
x:A
H:SortA l

(forall y : A, InA y l -> ltA x y) -> InfA x l
apply InA_InfA. Qed.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA

forall (l1 l2 : list A) (a : A), InfA a l1 -> InfA a l2 -> InfA a (l1 ++ l2)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA

forall (l1 l2 : list A) (a : A), InfA a l1 -> InfA a l2 -> InfA a (l1 ++ l2)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l1:list A
IHl1:forall (l2 : list A) (a0 : A), InfA a0 l1 -> InfA a0 l2 -> InfA a0 (l1 ++ l2)

forall (l2 : list A) (a0 : A), InfA a0 (a :: l1) -> InfA a0 l2 -> InfA a0 (a :: l1 ++ l2)
intros; inv; auto. Qed.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA

forall l1 l2 : list A, SortA l1 -> SortA l2 -> (forall x y : A, InA x l1 -> InA y l2 -> ltA x y) -> SortA (l1 ++ l2)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA

forall l1 l2 : list A, SortA l1 -> SortA l2 -> (forall x y : A, InA x l1 -> InA y l2 -> ltA x y) -> SortA (l1 ++ l2)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l1:list A
IHl1:forall l0 : list A, SortA l1 -> SortA l0 -> (forall x y : A, InA x l1 -> InA y l0 -> ltA x y) -> SortA (l1 ++ l0)
l2:list A
H:SortA (a :: l1)
H0:SortA l2
H1:forall x y : A, InA x (a :: l1) -> InA y l2 -> ltA x y

SortA (a :: l1 ++ l2)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l1:list A
IHl1:forall l0 : list A, SortA l1 -> SortA l0 -> (forall x y : A, InA x l1 -> InA y l0 -> ltA x y) -> SortA (l1 ++ l0)
l2:list A
H0:SortA l2
H1:forall x y : A, InA x (a :: l1) -> InA y l2 -> ltA x y
H2:SortA l1
H3:InfA a l1

SortA (a :: l1 ++ l2)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l1:list A
IHl1:forall l0 : list A, SortA l1 -> SortA l0 -> (forall x y : A, InA x l1 -> InA y l0 -> ltA x y) -> SortA (l1 ++ l0)
l2:list A
H0:SortA l2
H1:forall x y : A, InA x (a :: l1) -> InA y l2 -> ltA x y
H2:SortA l1
H3:InfA a l1

InfA a (l1 ++ l2)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l1:list A
IHl1:forall l0 : list A, SortA l1 -> SortA l0 -> (forall x y : A, InA x l1 -> InA y l0 -> ltA x y) -> SortA (l1 ++ l0)
l2:list A
H0:SortA l2
H1:forall x y : A, InA x (a :: l1) -> InA y l2 -> ltA x y
H2:SortA l1
H3:InfA a l1

InfA a l2
destruct l2; auto. Qed.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA

forall l : list A, SortA l -> NoDupA l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA

forall l : list A, SortA l -> NoDupA l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
l:list A

forall (a : A) (l0 : list A), (SortA l0 -> NoDupA l0) -> SortA (a :: l0) -> NoDupA (a :: l0)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
l:list A
x:A
l':list A
H:SortA l' -> NoDupA l'
H0:SortA (x :: l')

NoDupA (x :: l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
l:list A
x:A
l':list A
H:SortA l' -> NoDupA l'
H1:SortA l'
H2:InfA x l'

NoDupA (x :: l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
l:list A
x:A
l':list A
H:SortA l' -> NoDupA l'
H1:SortA l'
H2:InfA x l'

~ InA x l'
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
l:list A
x:A
l':list A
H:SortA l' -> NoDupA l'
H1:SortA l'
H2:InfA x l'
H0:InA x l'

False
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
l:list A
x:A
l':list A
H:SortA l' -> NoDupA l'
H1:SortA l'
H2:InfA x l'
H0:InA x l'

ltA x x
eapply SortA_InfA_InA; eauto. Qed.
Some results about eqlistA
Section EqlistA.

A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA

forall l l' : list A, eqlistA l l' -> length l = length l'
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA

forall l l' : list A, eqlistA l l' -> length l = length l'
induction 1; auto; simpl; congruence. Qed.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA

Proper (eqlistA ==> eqlistA ==> eqlistA) (app (A:=A))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA

Proper (eqlistA ==> eqlistA ==> eqlistA) (app (A:=A))
repeat red; induction 1; simpl; auto. Qed.
For compatibility, can be deduced from app_eqlistA_compat
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA

forall l1 l1' l2 l2' : list A, eqlistA l1 l1' -> eqlistA l2 l2' -> eqlistA (l1 ++ l2) (l1' ++ l2')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA

forall l1 l1' l2 l2' : list A, eqlistA l1 l1' -> eqlistA l2 l2' -> eqlistA (l1 ++ l2) (l1' ++ l2')
intros l1 l1' l2 l2' H H'; rewrite H, H'; reflexivity. Qed.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA

forall l1 l1' : list A, eqlistA l1 l1' -> forall l2 l2' : list A, eqlistA l2 l2' -> eqlistA (rev l1 ++ l2) (rev l1' ++ l2')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA

forall l1 l1' : list A, eqlistA l1 l1' -> forall l2 l2' : list A, eqlistA l2 l2' -> eqlistA (rev l1 ++ l2) (rev l1' ++ l2')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
x, x':A
l, l':list A
H:eqA x x'
H0:eqlistA l l'
IHeqlistA:forall l2 l2' : list A, eqlistA l2 l2' -> eqlistA (rev l ++ l2) (rev l' ++ l2')

forall l2 l2' : list A, eqlistA l2 l2' -> eqlistA (rev (x :: l) ++ l2) (rev (x' :: l') ++ l2')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
x, x':A
l, l':list A
H:eqA x x'
H0:eqlistA l l'
IHeqlistA:forall l0 l2'0 : list A, eqlistA l0 l2'0 -> eqlistA (rev l ++ l0) (rev l' ++ l2'0)
l2, l2':list A
H1:eqlistA l2 l2'

eqlistA ((rev l ++ x :: nil) ++ l2) ((rev l' ++ x' :: nil) ++ l2')
do 2 rewrite app_ass; simpl; auto. Qed.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA

Proper (eqlistA ==> eqlistA) (rev (A:=A))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA

Proper (eqlistA ==> eqlistA) (rev (A:=A))
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA

forall x y : list A, eqlistA x y -> eqlistA (rev x) (rev y)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
x, y:list A
H:eqlistA x y

eqlistA (rev x) (rev y)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
x, y:list A
H:eqlistA x y

eqlistA (rev x ++ nil) (rev y ++ nil)
apply eqlistA_rev_app; auto. Qed.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA

forall l1 l1' : list A, eqlistA l1 l1' -> eqlistA (rev l1) (rev l1')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA

forall l1 l1' : list A, eqlistA l1 l1' -> eqlistA (rev l1) (rev l1')
apply rev_eqlistA_compat. Qed.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA

forall l l' : list A, SortA l -> SortA l' -> equivlistA l l' -> eqlistA l l'
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA

forall l l' : list A, SortA l -> SortA l' -> equivlistA l l' -> eqlistA l l'
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l':list A
H:SortA nil
H0:SortA (a :: l')
H1:equivlistA nil (a :: l')

eqlistA nil (a :: l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l:list A
IHl:forall l' : list A, SortA l -> SortA l' -> equivlistA l l' -> eqlistA l l'
H:SortA (a :: l)
H0:SortA nil
H1:equivlistA (a :: l) nil
eqlistA (a :: l) nil
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l:list A
IHl:forall l'0 : list A, SortA l -> SortA l'0 -> equivlistA l l'0 -> eqlistA l l'0
a0:A
l':list A
H:SortA (a :: l)
H0:SortA (a0 :: l')
H1:equivlistA (a :: l) (a0 :: l')
eqlistA (a :: l) (a0 :: l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l:list A
IHl:forall l' : list A, SortA l -> SortA l' -> equivlistA l l' -> eqlistA l l'
H:SortA (a :: l)
H0:SortA nil
H1:equivlistA (a :: l) nil

eqlistA (a :: l) nil
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l:list A
IHl:forall l'0 : list A, SortA l -> SortA l'0 -> equivlistA l l'0 -> eqlistA l l'0
a0:A
l':list A
H:SortA (a :: l)
H0:SortA (a0 :: l')
H1:equivlistA (a :: l) (a0 :: l')
eqlistA (a :: l) (a0 :: l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l:list A
IHl:forall l'0 : list A, SortA l -> SortA l'0 -> equivlistA l l'0 -> eqlistA l l'0
a0:A
l':list A
H:SortA (a :: l)
H0:SortA (a0 :: l')
H1:equivlistA (a :: l) (a0 :: l')

eqlistA (a :: l) (a0 :: l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l:list A
IHl:forall l'0 : list A, SortA l -> SortA l'0 -> equivlistA l l'0 -> eqlistA l l'0
a0:A
l':list A
H1:equivlistA (a :: l) (a0 :: l')
H2:SortA l'
H3:InfA a0 l'
H0:SortA l
H4:InfA a l

eqlistA (a :: l) (a0 :: l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l:list A
IHl:forall l'0 : list A, SortA l -> SortA l'0 -> equivlistA l l'0 -> eqlistA l l'0
a0:A
l':list A
H1:equivlistA (a :: l) (a0 :: l')
H2:SortA l'
H3:InfA a0 l'
H0:SortA l
H4:InfA a l

forall y : A, InA y l -> ltA a y
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l:list A
IHl:forall l'0 : list A, SortA l -> SortA l'0 -> equivlistA l l'0 -> eqlistA l l'0
a0:A
l':list A
H1:equivlistA (a :: l) (a0 :: l')
H2:SortA l'
H3:InfA a0 l'
H0:SortA l
H4:InfA a l
H:forall y : A, InA y l -> ltA a y
eqlistA (a :: l) (a0 :: l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l:list A
IHl:forall l'0 : list A, SortA l -> SortA l'0 -> equivlistA l l'0 -> eqlistA l l'0
a0:A
l':list A
H1:equivlistA (a :: l) (a0 :: l')
H2:SortA l'
H3:InfA a0 l'
H0:SortA l
H4:InfA a l
H:forall y : A, InA y l -> ltA a y

eqlistA (a :: l) (a0 :: l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l:list A
IHl:forall l'0 : list A, SortA l -> SortA l'0 -> equivlistA l l'0 -> eqlistA l l'0
a0:A
l':list A
H1:equivlistA (a :: l) (a0 :: l')
H2:SortA l'
H3:InfA a0 l'
H0:SortA l
H4:InfA a l
H:forall y : A, InA y l -> ltA a y

forall y : A, InA y l' -> ltA a0 y
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l:list A
IHl:forall l'0 : list A, SortA l -> SortA l'0 -> equivlistA l l'0 -> eqlistA l l'0
a0:A
l':list A
H1:equivlistA (a :: l) (a0 :: l')
H2:SortA l'
H3:InfA a0 l'
H0:SortA l
H4:InfA a l
H:forall y : A, InA y l -> ltA a y
H5:forall y : A, InA y l' -> ltA a0 y
eqlistA (a :: l) (a0 :: l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l:list A
IHl:forall l'0 : list A, SortA l -> SortA l'0 -> equivlistA l l'0 -> eqlistA l l'0
a0:A
l':list A
H1:equivlistA (a :: l) (a0 :: l')
H2:SortA l'
H3:InfA a0 l'
H0:SortA l
H4:InfA a l
H:forall y : A, InA y l -> ltA a y
H5:forall y : A, InA y l' -> ltA a0 y

eqlistA (a :: l) (a0 :: l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l:list A
IHl:forall l'0 : list A, SortA l -> SortA l'0 -> equivlistA l l'0 -> eqlistA l l'0
a0:A
l':list A
H1:equivlistA (a :: l) (a0 :: l')
H2:SortA l'
H0:SortA l
H:forall y : A, InA y l -> ltA a y
H5:forall y : A, InA y l' -> ltA a0 y

eqlistA (a :: l) (a0 :: l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l:list A
IHl:forall l'0 : list A, SortA l -> SortA l'0 -> equivlistA l l'0 -> eqlistA l l'0
a0:A
l':list A
H1:equivlistA (a :: l) (a0 :: l')
H2:SortA l'
H0:SortA l
H:forall y : A, InA y l -> ltA a y
H5:forall y : A, InA y l' -> ltA a0 y

eqA a a0
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l:list A
IHl:forall l'0 : list A, SortA l -> SortA l'0 -> equivlistA l l'0 -> eqlistA l l'0
a0:A
l':list A
H1:equivlistA (a :: l) (a0 :: l')
H2:SortA l'
H0:SortA l
H:forall y : A, InA y l -> ltA a y
H5:forall y : A, InA y l' -> ltA a0 y
H3:eqA a a0
eqlistA (a :: l) (a0 :: l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l:list A
IHl:forall l'0 : list A, SortA l -> SortA l'0 -> equivlistA l l'0 -> eqlistA l l'0
a0:A
l':list A
H1:equivlistA (a :: l) (a0 :: l')
H2:SortA l'
H0:SortA l
H:forall y : A, InA y l -> ltA a y
H5:forall y : A, InA y l' -> ltA a0 y
H3:InA a (a :: l) -> InA a (a0 :: l')
H4:InA a (a0 :: l') -> InA a (a :: l)

eqA a a0
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l:list A
IHl:forall l'0 : list A, SortA l -> SortA l'0 -> equivlistA l l'0 -> eqlistA l l'0
a0:A
l':list A
H1:equivlistA (a :: l) (a0 :: l')
H2:SortA l'
H0:SortA l
H:forall y : A, InA y l -> ltA a y
H5:forall y : A, InA y l' -> ltA a0 y
H3:eqA a a0
eqlistA (a :: l) (a0 :: l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l:list A
IHl:forall l'0 : list A, SortA l -> SortA l'0 -> equivlistA l l'0 -> eqlistA l l'0
a0:A
l':list A
H1:equivlistA (a :: l) (a0 :: l')
H2:SortA l'
H0:SortA l
H:forall y : A, InA y l -> ltA a y
H5:forall y : A, InA y l' -> ltA a0 y
H3:InA a (a :: l) -> InA a (a0 :: l')
H4:InA a (a0 :: l') -> InA a (a :: l)
H6:InA a0 (a :: l) -> InA a0 (a0 :: l')
H7:InA a0 (a0 :: l') -> InA a0 (a :: l)

eqA a a0
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l:list A
IHl:forall l'0 : list A, SortA l -> SortA l'0 -> equivlistA l l'0 -> eqlistA l l'0
a0:A
l':list A
H1:equivlistA (a :: l) (a0 :: l')
H2:SortA l'
H0:SortA l
H:forall y : A, InA y l -> ltA a y
H5:forall y : A, InA y l' -> ltA a0 y
H3:eqA a a0
eqlistA (a :: l) (a0 :: l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l:list A
IHl:forall l'0 : list A, SortA l -> SortA l'0 -> equivlistA l l'0 -> eqlistA l l'0
a0:A
l':list A
H1:equivlistA (a :: l) (a0 :: l')
H2:SortA l'
H0:SortA l
H:forall y : A, InA y l -> ltA a y
H5:forall y : A, InA y l' -> ltA a0 y
H3:InA a (a :: l) -> InA a (a0 :: l')
H4:InA a (a0 :: l') -> InA a (a :: l)
H6:InA a0 (a :: l) -> InA a0 (a0 :: l')
H7:InA a0 (a0 :: l') -> InA a0 (a :: l)
H8:InA a (a0 :: l')

eqA a a0
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l:list A
IHl:forall l'0 : list A, SortA l -> SortA l'0 -> equivlistA l l'0 -> eqlistA l l'0
a0:A
l':list A
H1:equivlistA (a :: l) (a0 :: l')
H2:SortA l'
H0:SortA l
H:forall y : A, InA y l -> ltA a y
H5:forall y : A, InA y l' -> ltA a0 y
H3:eqA a a0
eqlistA (a :: l) (a0 :: l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l:list A
IHl:forall l'0 : list A, SortA l -> SortA l'0 -> equivlistA l l'0 -> eqlistA l l'0
a0:A
l':list A
H1:equivlistA (a :: l) (a0 :: l')
H2:SortA l'
H0:SortA l
H:forall y : A, InA y l -> ltA a y
H5:forall y : A, InA y l' -> ltA a0 y
H3:InA a (a :: l) -> InA a (a0 :: l')
H4:InA a (a0 :: l') -> InA a (a :: l)
H6:InA a0 (a :: l) -> InA a0 (a0 :: l')
H7:InA a0 (a0 :: l') -> InA a0 (a :: l)
H9:InA a l'

eqA a a0
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l:list A
IHl:forall l'0 : list A, SortA l -> SortA l'0 -> equivlistA l l'0 -> eqlistA l l'0
a0:A
l':list A
H1:equivlistA (a :: l) (a0 :: l')
H2:SortA l'
H0:SortA l
H:forall y : A, InA y l -> ltA a y
H5:forall y : A, InA y l' -> ltA a0 y
H3:eqA a a0
eqlistA (a :: l) (a0 :: l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l:list A
IHl:forall l'0 : list A, SortA l -> SortA l'0 -> equivlistA l l'0 -> eqlistA l l'0
a0:A
l':list A
H1:equivlistA (a :: l) (a0 :: l')
H2:SortA l'
H0:SortA l
H:forall y : A, InA y l -> ltA a y
H5:forall y : A, InA y l' -> ltA a0 y
H3:InA a (a :: l) -> InA a (a0 :: l')
H4:InA a (a0 :: l') -> InA a (a :: l)
H6:InA a0 (a :: l) -> InA a0 (a0 :: l')
H7:InA a0 (a0 :: l') -> InA a0 (a :: l)
H9:InA a l'
H8:InA a0 (a :: l)

eqA a a0
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l:list A
IHl:forall l'0 : list A, SortA l -> SortA l'0 -> equivlistA l l'0 -> eqlistA l l'0
a0:A
l':list A
H1:equivlistA (a :: l) (a0 :: l')
H2:SortA l'
H0:SortA l
H:forall y : A, InA y l -> ltA a y
H5:forall y : A, InA y l' -> ltA a0 y
H3:eqA a a0
eqlistA (a :: l) (a0 :: l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l:list A
IHl:forall l'0 : list A, SortA l -> SortA l'0 -> equivlistA l l'0 -> eqlistA l l'0
a0:A
l':list A
H1:equivlistA (a :: l) (a0 :: l')
H2:SortA l'
H0:SortA l
H:forall y : A, InA y l -> ltA a y
H5:forall y : A, InA y l' -> ltA a0 y
H3:InA a (a :: l) -> InA a (a0 :: l')
H4:InA a (a0 :: l') -> InA a (a :: l)
H6:InA a0 (a :: l) -> InA a0 (a0 :: l')
H7:InA a0 (a0 :: l') -> InA a0 (a :: l)
H9:InA a l'
H10:InA a0 l

eqA a a0
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l:list A
IHl:forall l'0 : list A, SortA l -> SortA l'0 -> equivlistA l l'0 -> eqlistA l l'0
a0:A
l':list A
H1:equivlistA (a :: l) (a0 :: l')
H2:SortA l'
H0:SortA l
H:forall y : A, InA y l -> ltA a y
H5:forall y : A, InA y l' -> ltA a0 y
H3:eqA a a0
eqlistA (a :: l) (a0 :: l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l:list A
IHl:forall l'0 : list A, SortA l -> SortA l'0 -> equivlistA l l'0 -> eqlistA l l'0
a0:A
l':list A
H1:equivlistA (a :: l) (a0 :: l')
H2:SortA l'
H0:SortA l
H:forall y : A, InA y l -> ltA a y
H5:forall y : A, InA y l' -> ltA a0 y
H3:eqA a a0

eqlistA (a :: l) (a0 :: l')
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l:list A
IHl:forall l'0 : list A, SortA l -> SortA l'0 -> equivlistA l l'0 -> eqlistA l l'0
a0:A
l':list A
H1:equivlistA (a :: l) (a0 :: l')
H2:SortA l'
H0:SortA l
H:forall y : A, InA y l -> ltA a y
H5:forall y : A, InA y l' -> ltA a0 y
H3:eqA a a0

eqlistA l l'
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l:list A
IHl:forall l'0 : list A, SortA l -> SortA l'0 -> equivlistA l l'0 -> eqlistA l l'0
a0:A
l':list A
H1:equivlistA (a :: l) (a0 :: l')
H2:SortA l'
H0:SortA l
H:forall y : A, InA y l -> ltA a y
H5:forall y : A, InA y l' -> ltA a0 y
H3:eqA a a0

equivlistA l l'
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l:list A
IHl:forall l'0 : list A, SortA l -> SortA l'0 -> equivlistA l l'0 -> eqlistA l l'0
a0:A
l':list A
H1:equivlistA (a :: l) (a0 :: l')
H2:SortA l'
H0:SortA l
H:forall y : A, InA y l -> ltA a y
H5:forall y : A, InA y l' -> ltA a0 y
H3:eqA a a0
x:A
H4:InA x l

InA x l'
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l:list A
IHl:forall l'0 : list A, SortA l -> SortA l'0 -> equivlistA l l'0 -> eqlistA l l'0
a0:A
l':list A
H1:equivlistA (a :: l) (a0 :: l')
H2:SortA l'
H0:SortA l
H:forall y : A, InA y l -> ltA a y
H5:forall y : A, InA y l' -> ltA a0 y
H3:eqA a a0
x:A
H4:InA x l'
InA x l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l:list A
IHl:forall l'0 : list A, SortA l -> SortA l'0 -> equivlistA l l'0 -> eqlistA l l'0
a0:A
l':list A
H1:equivlistA (a :: l) (a0 :: l')
H2:SortA l'
H0:SortA l
H:forall y : A, InA y l -> ltA a y
H5:forall y : A, InA y l' -> ltA a0 y
H3:eqA a a0
x:A
H4:InA x l
H6:InA x (a :: l) -> InA x (a0 :: l')
H7:InA x (a0 :: l') -> InA x (a :: l)

InA x l'
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l:list A
IHl:forall l'0 : list A, SortA l -> SortA l'0 -> equivlistA l l'0 -> eqlistA l l'0
a0:A
l':list A
H1:equivlistA (a :: l) (a0 :: l')
H2:SortA l'
H0:SortA l
H:forall y : A, InA y l -> ltA a y
H5:forall y : A, InA y l' -> ltA a0 y
H3:eqA a a0
x:A
H4:InA x l'
InA x l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l:list A
IHl:forall l'0 : list A, SortA l -> SortA l'0 -> equivlistA l l'0 -> eqlistA l l'0
a0:A
l':list A
H1:equivlistA (a :: l) (a0 :: l')
H2:SortA l'
H0:SortA l
H:forall y : A, InA y l -> ltA a y
H5:forall y : A, InA y l' -> ltA a0 y
H3:eqA a a0
x:A
H4:InA x l
H6:InA x (a :: l) -> InA x (a0 :: l')
H7:InA x (a0 :: l') -> InA x (a :: l)
H8:InA x (a0 :: l')

InA x l'
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l:list A
IHl:forall l'0 : list A, SortA l -> SortA l'0 -> equivlistA l l'0 -> eqlistA l l'0
a0:A
l':list A
H1:equivlistA (a :: l) (a0 :: l')
H2:SortA l'
H0:SortA l
H:forall y : A, InA y l -> ltA a y
H5:forall y : A, InA y l' -> ltA a0 y
H3:eqA a a0
x:A
H4:InA x l'
InA x l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l:list A
IHl:forall l'0 : list A, SortA l -> SortA l'0 -> equivlistA l l'0 -> eqlistA l l'0
a0:A
l':list A
H1:equivlistA (a :: l) (a0 :: l')
H2:SortA l'
H0:SortA l
H:forall y : A, InA y l -> ltA a y
H5:forall y : A, InA y l' -> ltA a0 y
H3:eqA a a0
x:A
H4:InA x l
H6:InA x (a :: l) -> InA x (a0 :: l')
H7:InA x (a0 :: l') -> InA x (a :: l)
H9:eqA x a0

InA x l'
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l:list A
IHl:forall l'0 : list A, SortA l -> SortA l'0 -> equivlistA l l'0 -> eqlistA l l'0
a0:A
l':list A
H1:equivlistA (a :: l) (a0 :: l')
H2:SortA l'
H0:SortA l
H:forall y : A, InA y l -> ltA a y
H5:forall y : A, InA y l' -> ltA a0 y
H3:eqA a a0
x:A
H4:InA x l'
InA x l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l:list A
IHl:forall l'0 : list A, SortA l -> SortA l'0 -> equivlistA l l'0 -> eqlistA l l'0
a0:A
l':list A
H1:equivlistA (a :: l) (a0 :: l')
H2:SortA l'
H0:SortA l
H:forall y : A, InA y l -> ltA a y
H5:forall y : A, InA y l' -> ltA a0 y
H3:eqA a a0
x:A
H4:InA a l
H6:InA x (a :: l) -> InA x (a0 :: l')
H7:InA x (a0 :: l') -> InA x (a :: l)
H9:eqA x a0

InA x l'
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l:list A
IHl:forall l'0 : list A, SortA l -> SortA l'0 -> equivlistA l l'0 -> eqlistA l l'0
a0:A
l':list A
H1:equivlistA (a :: l) (a0 :: l')
H2:SortA l'
H0:SortA l
H:forall y : A, InA y l -> ltA a y
H5:forall y : A, InA y l' -> ltA a0 y
H3:eqA a a0
x:A
H4:InA x l'
InA x l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l:list A
IHl:forall l'0 : list A, SortA l -> SortA l'0 -> equivlistA l l'0 -> eqlistA l l'0
a0:A
l':list A
H1:equivlistA (a :: l) (a0 :: l')
H2:SortA l'
H0:SortA l
H:forall y : A, InA y l -> ltA a y
H5:forall y : A, InA y l' -> ltA a0 y
H3:eqA a a0
x:A
H4:InA x l'

InA x l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l:list A
IHl:forall l'0 : list A, SortA l -> SortA l'0 -> equivlistA l l'0 -> eqlistA l l'0
a0:A
l':list A
H1:equivlistA (a :: l) (a0 :: l')
H2:SortA l'
H0:SortA l
H:forall y : A, InA y l -> ltA a y
H5:forall y : A, InA y l' -> ltA a0 y
H3:eqA a a0
x:A
H4:InA x l'
H6:InA x (a :: l) -> InA x (a0 :: l')
H7:InA x (a0 :: l') -> InA x (a :: l)

InA x l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l:list A
IHl:forall l'0 : list A, SortA l -> SortA l'0 -> equivlistA l l'0 -> eqlistA l l'0
a0:A
l':list A
H1:equivlistA (a :: l) (a0 :: l')
H2:SortA l'
H0:SortA l
H:forall y : A, InA y l -> ltA a y
H5:forall y : A, InA y l' -> ltA a0 y
H3:eqA a a0
x:A
H4:InA x l'
H6:InA x (a :: l) -> InA x (a0 :: l')
H7:InA x (a0 :: l') -> InA x (a :: l)
H8:InA x (a :: l)

InA x l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l:list A
IHl:forall l'0 : list A, SortA l -> SortA l'0 -> equivlistA l l'0 -> eqlistA l l'0
a0:A
l':list A
H1:equivlistA (a :: l) (a0 :: l')
H2:SortA l'
H0:SortA l
H:forall y : A, InA y l -> ltA a y
H5:forall y : A, InA y l' -> ltA a0 y
H3:eqA a a0
x:A
H4:InA x l'
H6:InA x (a :: l) -> InA x (a0 :: l')
H7:InA x (a0 :: l') -> InA x (a :: l)
H9:eqA x a

InA x l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
a:A
l:list A
IHl:forall l'0 : list A, SortA l -> SortA l'0 -> equivlistA l l'0 -> eqlistA l l'0
a0:A
l':list A
H1:equivlistA (a :: l) (a0 :: l')
H2:SortA l'
H0:SortA l
H:forall y : A, InA y l -> ltA a y
H5:forall y : A, InA y l' -> ltA a0 y
H3:eqA a a0
x:A
H4:InA a0 l'
H6:InA x (a :: l) -> InA x (a0 :: l')
H7:InA x (a0 :: l') -> InA x (a :: l)
H9:eqA x a

InA x l
elim (StrictOrder_Irreflexive a0); eauto. Qed. End EqlistA.
A few things about filter
Section Filter.

A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA

forall (f : A -> bool) (l : list A), SortA l -> SortA (filter f l)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA

forall (f : A -> bool) (l : list A), SortA l -> SortA (filter f l)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
f:A -> bool
a:A
l:list A
IHl:SortA l -> SortA (filter f l)

SortA (a :: l) -> SortA (if f a then a :: filter f l else filter f l)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
f:A -> bool
a:A
l:list A
IHl:SortA l -> SortA (filter f l)
H0:SortA l
H1:InfA a l

SortA (if f a then a :: filter f l else filter f l)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
f:A -> bool
a:A
l:list A
IHl:SortA l -> SortA (filter f l)
H0:SortA l
H1:InfA a l

SortA (a :: filter f l)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
f:A -> bool
a:A
l:list A
IHl:SortA l -> SortA (filter f l)
H0:SortA l
H1:InfA a l

InfA a (filter f l)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
f:A -> bool
a:A
l:list A
IHl:SortA l -> SortA (filter f l)
H0:SortA l
H1:InfA a l

forall y : A, In y (filter f l) -> ltA a y
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
f:A -> bool
a:A
l:list A
IHl:SortA l -> SortA (filter f l)
H0:SortA l
H1:InfA a l
y:A
H:In y (filter f l)

ltA a y
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
f:A -> bool
a:A
l:list A
IHl:SortA l -> SortA (filter f l)
H0:SortA l
H1:InfA a l
y:A
H:In y l
H2:f y = true

ltA a y
eapply SortA_InfA_InA; eauto. Qed. Arguments eq {A} x _.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA

forall f : A -> bool, Proper (eqA ==> eq) f -> forall (l : list A) (x : A), InA x (filter f l) <-> InA x l /\ f x = true
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA

forall f : A -> bool, Proper (eqA ==> eq) f -> forall (l : list A) (x : A), InA x (filter f l) <-> InA x l /\ f x = true
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA

forall f : A -> bool, Proper (eqA ==> eq) f -> forall (l : list A) (x : A), InA x (filter f l) <-> InA x l /\ f x = true
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
f:A -> bool
H:Proper (eqA ==> eq) f
l:list A
x:A
H0:exists y : A, eqA x y /\ In y (filter f l)

exists y : A, eqA x y /\ In y l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
f:A -> bool
H:Proper (eqA ==> eq) f
l:list A
x:A
H0:exists y : A, eqA x y /\ In y (filter f l)
f x = true
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
f:A -> bool
H:Proper (eqA ==> eq) f
l:list A
x:A
H1:exists y : A, eqA x y /\ In y l
H2:f x = true
exists y : A, eqA x y /\ In y (filter f l)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
f:A -> bool
H:Proper (eqA ==> eq) f
l:list A
x:A
H0:exists y : A, eqA x y /\ In y (filter f l)

f x = true
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
f:A -> bool
H:Proper (eqA ==> eq) f
l:list A
x:A
H1:exists y : A, eqA x y /\ In y l
H2:f x = true
exists y : A, eqA x y /\ In y (filter f l)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
f:A -> bool
H:Proper (eqA ==> eq) f
l:list A
x, y:A
H0:eqA x y
H2:In y l
H3:f y = true

f x = true
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
f:A -> bool
H:Proper (eqA ==> eq) f
l:list A
x:A
H1:exists y : A, eqA x y /\ In y l
H2:f x = true
exists y : A, eqA x y /\ In y (filter f l)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
f:A -> bool
H:Proper (eqA ==> eq) f
l:list A
x:A
H1:exists y : A, eqA x y /\ In y l
H2:f x = true

exists y : A, eqA x y /\ In y (filter f l)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
f:A -> bool
H:Proper (eqA ==> eq) f
l:list A
x, y:A
H0:eqA x y
H1:In y l
H2:f x = true

f y = true
rewrite <- (H _ _ H0); auto. Qed.
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA

forall f : A -> bool, (forall x y : A, f x = true -> f y = false -> ltA x y) -> forall l : list A, SortA l -> l = filter f l ++ filter (fun x : A => negb (f x)) l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA

forall f : A -> bool, (forall x y : A, f x = true -> f y = false -> ltA x y) -> forall l : list A, SortA l -> l = filter f l ++ filter (fun x : A => negb (f x)) l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
f:A -> bool
H:forall x y : A, f x = true -> f y = false -> ltA x y
a:A
l:list A
IHl:SortA l -> l = filter f l ++ filter (fun x : A => negb (f x)) l
H0:SortA (a :: l)

a :: l = (if f a then a :: filter f l else filter f l) ++ (if negb (f a) then a :: filter (fun x : A => negb (f x)) l else filter (fun x : A => negb (f x)) l)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
f:A -> bool
H:forall x y : A, f x = true -> f y = false -> ltA x y
a:A
l:list A
IHl:SortA l -> l = filter f l ++ filter (fun x : A => negb (f x)) l
H1:SortA l
H2:InfA a l

a :: l = (if f a then a :: filter f l else filter f l) ++ (if negb (f a) then a :: filter (fun x : A => negb (f x)) l else filter (fun x : A => negb (f x)) l)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
f:A -> bool
H:forall x y : A, f x = true -> f y = false -> ltA x y
a:A
l:list A
IHl:SortA l -> l = filter f l ++ filter (fun x : A => negb (f x)) l
H1:SortA l
H2:InfA a l

a :: filter f l ++ filter (fun x : A => negb (f x)) l = (if f a then a :: filter f l else filter f l) ++ (if negb (f a) then a :: filter (fun x : A => negb (f x)) l else filter (fun x : A => negb (f x)) l)
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
f:A -> bool
H:forall x y : A, f x = true -> f y = false -> ltA x y
a:A
l:list A
IHl:SortA l -> l = filter f l ++ filter (fun x : A => negb (f x)) l
H1:SortA l
H2:InfA a l
H0:f a = false

a :: filter f l ++ filter (fun x : A => negb (f x)) l = filter f l ++ a :: filter (fun x : A => negb (f x)) l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
f:A -> bool
H:forall x y : A, f x = true -> f y = false -> ltA x y
a:A
l:list A
IHl:SortA l -> l = filter f l ++ filter (fun x : A => negb (f x)) l
H1:SortA l
H2:InfA a l
H0:f a = false

forall e : A, In e l -> f e = false
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
f:A -> bool
H:forall x y : A, f x = true -> f y = false -> ltA x y
a:A
l:list A
IHl:SortA l -> l = filter f l ++ filter (fun x : A => negb (f x)) l
H1:SortA l
H2:InfA a l
H0:f a = false
H3:forall e : A, In e l -> f e = false
a :: filter f l ++ filter (fun x : A => negb (f x)) l = filter f l ++ a :: filter (fun x : A => negb (f x)) l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
f:A -> bool
H:forall x y : A, f x = true -> f y = false -> ltA x y
a:A
l:list A
IHl:SortA l -> l = filter f l ++ filter (fun x : A => negb (f x)) l
H1:SortA l
H2:InfA a l
H0:f a = false
e:A
H3:In e l

f e = false
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
f:A -> bool
H:forall x y : A, f x = true -> f y = false -> ltA x y
a:A
l:list A
IHl:SortA l -> l = filter f l ++ filter (fun x : A => negb (f x)) l
H1:SortA l
H2:InfA a l
H0:f a = false
H3:forall e : A, In e l -> f e = false
a :: filter f l ++ filter (fun x : A => negb (f x)) l = filter f l ++ a :: filter (fun x : A => negb (f x)) l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
f:A -> bool
H:forall x y : A, f x = true -> f y = false -> ltA x y
a:A
l:list A
IHl:SortA l -> l = filter f l ++ filter (fun x : A => negb (f x)) l
H1:SortA l
H2:InfA a l
H0:f a = false
e:A
H3:In e l
H4:ltA a e

f e = false
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
f:A -> bool
H:forall x y : A, f x = true -> f y = false -> ltA x y
a:A
l:list A
IHl:SortA l -> l = filter f l ++ filter (fun x : A => negb (f x)) l
H1:SortA l
H2:InfA a l
H0:f a = false
H3:forall e : A, In e l -> f e = false
a :: filter f l ++ filter (fun x : A => negb (f x)) l = filter f l ++ a :: filter (fun x : A => negb (f x)) l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
f:A -> bool
H:forall x y : A, f x = true -> f y = false -> ltA x y
a:A
l:list A
IHl:SortA l -> l = filter f l ++ filter (fun x : A => negb (f x)) l
H1:SortA l
H2:InfA a l
H0:f a = false
e:A
H3:In e l
H4:ltA a e
H5:f e = true

true = false
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
f:A -> bool
H:forall x y : A, f x = true -> f y = false -> ltA x y
a:A
l:list A
IHl:SortA l -> l = filter f l ++ filter (fun x : A => negb (f x)) l
H1:SortA l
H2:InfA a l
H0:f a = false
H3:forall e : A, In e l -> f e = false
a :: filter f l ++ filter (fun x : A => negb (f x)) l = filter f l ++ a :: filter (fun x : A => negb (f x)) l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
f:A -> bool
H:forall x y : A, f x = true -> f y = false -> ltA x y
a:A
l:list A
IHl:SortA l -> l = filter f l ++ filter (fun x : A => negb (f x)) l
H1:SortA l
H2:InfA a l
H0:f a = false
e:A
H3:In e l
H4:ltA a e
H5:f e = true

ltA e e
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
f:A -> bool
H:forall x y : A, f x = true -> f y = false -> ltA x y
a:A
l:list A
IHl:SortA l -> l = filter f l ++ filter (fun x : A => negb (f x)) l
H1:SortA l
H2:InfA a l
H0:f a = false
H3:forall e : A, In e l -> f e = false
a :: filter f l ++ filter (fun x : A => negb (f x)) l = filter f l ++ a :: filter (fun x : A => negb (f x)) l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
f:A -> bool
H:forall x y : A, f x = true -> f y = false -> ltA x y
a:A
l:list A
IHl:SortA l -> l = filter f l ++ filter (fun x : A => negb (f x)) l
H1:SortA l
H2:InfA a l
H0:f a = false
H3:forall e : A, In e l -> f e = false

a :: filter f l ++ filter (fun x : A => negb (f x)) l = filter f l ++ a :: filter (fun x : A => negb (f x)) l
A:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
ltA:A -> A -> Prop
ltA_strorder:StrictOrder ltA
ltA_compat:Proper (eqA ==> eqA ==> iff) ltA
sotrans:=StrictOrder_Transitive:Transitive ltA
f:A -> bool
H:forall x y : A, f x = true -> f y = false -> ltA x y
a:A
l:list A
IHl:SortA l -> l = filter f l ++ filter (fun x : A => negb (f x)) l
H1:SortA l
H2:InfA a l
H0:f a = false
H3:forall e : A, In e l -> f e = false

nil = filter f l
A:Type
f:A -> bool
a:A
l:list A
IHl:(forall e : A, In e l -> f e = false) -> nil = filter f l

(forall e : A, a = e \/ In e l -> f e = false) -> nil = (if f a then a :: filter f l else filter f l)
A:Type
f:A -> bool
a:A
l:list A
IHl:(forall e : A, In e l -> f e = false) -> nil = filter f l
H:f a = true
H3:forall e : A, a = e \/ In e l -> f e = false

nil = a :: filter f l
rewrite H3 in H; auto; try discriminate. Qed. End Filter. End Type_with_equality. Hint Constructors InA eqlistA NoDupA sort lelistA : core. Arguments equivlistA_cons_nil {A} eqA {eqA_equiv} x l _. Arguments equivlistA_nil_eq {A} eqA {eqA_equiv} l _. Section Find. Variable A B : Type. Variable eqA : A -> A -> Prop. Hypothesis eqA_equiv : Equivalence eqA. Hypothesis eqA_dec : forall x y : A, {eqA x y}+{~(eqA x y)}. Fixpoint findA (f : A -> bool) (l:list (A*B)) : option B := match l with | nil => None | (a,b)::l => if f a then Some b else findA f l end.
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}

forall (l : list (A * B)) (a : A) (b : B), NoDupA (fun p p' : A * B => eqA (fst p) (fst p')) l -> InA (fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p') (a, b) l <-> findA (fun a' : A => if eqA_dec a a' then true else false) l = Some b
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}

forall (l : list (A * B)) (a : A) (b : B), NoDupA (fun p p' : A * B => eqA (fst p) (fst p')) l -> InA (fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p') (a, b) l <-> findA (fun a' : A => if eqA_dec a a' then true else false) l = Some b
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop

forall (l : list (A * B)) (a : A) (b : B), NoDupA eqk l -> InA (fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p') (a, b) l <-> findA (fun a' : A => if eqA_dec a a' then true else false) l = Some b
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop

forall (l : list (A * B)) (a : A) (b : B), NoDupA eqk l -> InA eqke (a, b) l <-> findA (fun a' : A => if eqA_dec a a' then true else false) l = Some b
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a:A
b:B
H:NoDupA eqk nil

InA eqke (a, b) nil <-> None = Some b
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a:(A * B)%type
l:list (A * B)
IHl:forall (a1 : A) (b0 : B), NoDupA eqk l -> InA eqke (a1, b0) l <-> findA (fun a' : A => if eqA_dec a1 a' then true else false) l = Some b0
a0:A
b:B
H:NoDupA eqk (a :: l)
InA eqke (a0, b) (a :: l) <-> (let (a1, b0) := a in if if eqA_dec a0 a1 then true else false then Some b0 else findA (fun a' : A => if eqA_dec a0 a' then true else false) l) = Some b
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a:A
b:B
H:NoDupA eqk nil
H0:InA eqke (a, b) nil

None = Some b
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a:(A * B)%type
l:list (A * B)
IHl:forall (a1 : A) (b0 : B), NoDupA eqk l -> InA eqke (a1, b0) l <-> findA (fun a' : A => if eqA_dec a1 a' then true else false) l = Some b0
a0:A
b:B
H:NoDupA eqk (a :: l)
InA eqke (a0, b) (a :: l) <-> (let (a1, b0) := a in if if eqA_dec a0 a1 then true else false then Some b0 else findA (fun a' : A => if eqA_dec a0 a' then true else false) l) = Some b
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a:(A * B)%type
l:list (A * B)
IHl:forall (a1 : A) (b0 : B), NoDupA eqk l -> InA eqke (a1, b0) l <-> findA (fun a' : A => if eqA_dec a1 a' then true else false) l = Some b0
a0:A
b:B
H:NoDupA eqk (a :: l)

InA eqke (a0, b) (a :: l) <-> (let (a1, b0) := a in if if eqA_dec a0 a1 then true else false then Some b0 else findA (fun a' : A => if eqA_dec a0 a' then true else false) l) = Some b
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
l:list (A * B)
IHl:forall (a0 : A) (b0 : B), NoDupA eqk l -> InA eqke (a0, b0) l <-> findA (fun a'0 : A => if eqA_dec a0 a'0 then true else false) l = Some b0
a:A
b:B
H:NoDupA eqk ((a', b') :: l)

InA eqke (a, b) ((a', b') :: l) <-> (if if eqA_dec a a' then true else false then Some b' else findA (fun a'0 : A => if eqA_dec a a'0 then true else false) l) = Some b
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
l:list (A * B)
IHl:forall (a0 : A) (b0 : B), NoDupA eqk l -> InA eqke (a0, b0) l <-> findA (fun a'0 : A => if eqA_dec a0 a'0 then true else false) l = Some b0
a:A
b:B
H0:~ InA eqk (a', b') l
H1:NoDupA eqk l

InA eqke (a, b) ((a', b') :: l) <-> (if if eqA_dec a a' then true else false then Some b' else findA (fun a'0 : A => if eqA_dec a a'0 then true else false) l) = Some b
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
l:list (A * B)
IHl:forall (a0 : A) (b0 : B), NoDupA eqk l -> InA eqke (a0, b0) l <-> findA (fun a'0 : A => if eqA_dec a0 a'0 then true else false) l = Some b0
a:A
b:B
H0:~ InA eqk (a', b') l
H1:NoDupA eqk l
H:InA eqke (a, b) ((a', b') :: l)

(if if eqA_dec a a' then true else false then Some b' else findA (fun a'0 : A => if eqA_dec a a'0 then true else false) l) = Some b
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
l:list (A * B)
IHl:forall (a0 : A) (b0 : B), NoDupA eqk l -> InA eqke (a0, b0) l <-> findA (fun a'0 : A => if eqA_dec a0 a'0 then true else false) l = Some b0
a:A
b:B
H0:~ InA eqk (a', b') l
H1:NoDupA eqk l
H:(if if eqA_dec a a' then true else false then Some b' else findA (fun a'0 : A => if eqA_dec a a'0 then true else false) l) = Some b
InA eqke (a, b) ((a', b') :: l)
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
l:list (A * B)
IHl:forall (a0 : A) (b0 : B), NoDupA eqk l -> InA eqke (a0, b0) l <-> findA (fun a'0 : A => if eqA_dec a0 a'0 then true else false) l = Some b0
a:A
b:B
H0:~ InA eqk (a', b') l
H1:NoDupA eqk l
H2:eqke (a, b) (a', b')

(if if eqA_dec a a' then true else false then Some b' else findA (fun a'0 : A => if eqA_dec a a'0 then true else false) l) = Some b
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
l:list (A * B)
IHl:forall (a0 : A) (b0 : B), NoDupA eqk l -> InA eqke (a0, b0) l <-> findA (fun a'0 : A => if eqA_dec a0 a'0 then true else false) l = Some b0
a:A
b:B
H0:~ InA eqk (a', b') l
H1:NoDupA eqk l
H2:InA eqke (a, b) l
(if if eqA_dec a a' then true else false then Some b' else findA (fun a'0 : A => if eqA_dec a a'0 then true else false) l) = Some b
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
l:list (A * B)
IHl:forall (a0 : A) (b0 : B), NoDupA eqk l -> InA eqke (a0, b0) l <-> findA (fun a'0 : A => if eqA_dec a0 a'0 then true else false) l = Some b0
a:A
b:B
H0:~ InA eqk (a', b') l
H1:NoDupA eqk l
H:(if if eqA_dec a a' then true else false then Some b' else findA (fun a'0 : A => if eqA_dec a a'0 then true else false) l) = Some b
InA eqke (a, b) ((a', b') :: l)
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
l:list (A * B)
IHl:forall (a0 : A) (b0 : B), NoDupA eqk l -> InA eqke (a0, b0) l <-> findA (fun a'0 : A => if eqA_dec a0 a'0 then true else false) l = Some b0
a:A
b:B
H0:~ InA eqk (a', b') l
H1:NoDupA eqk l
H:eqA a a'
H2:b = b'

(if if eqA_dec a a' then true else false then Some b' else findA (fun a'0 : A => if eqA_dec a a'0 then true else false) l) = Some b
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
l:list (A * B)
IHl:forall (a0 : A) (b0 : B), NoDupA eqk l -> InA eqke (a0, b0) l <-> findA (fun a'0 : A => if eqA_dec a0 a'0 then true else false) l = Some b0
a:A
b:B
H0:~ InA eqk (a', b') l
H1:NoDupA eqk l
H2:InA eqke (a, b) l
(if if eqA_dec a a' then true else false then Some b' else findA (fun a'0 : A => if eqA_dec a a'0 then true else false) l) = Some b
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
l:list (A * B)
IHl:forall (a0 : A) (b0 : B), NoDupA eqk l -> InA eqke (a0, b0) l <-> findA (fun a'0 : A => if eqA_dec a0 a'0 then true else false) l = Some b0
a:A
b:B
H0:~ InA eqk (a', b') l
H1:NoDupA eqk l
H:(if if eqA_dec a a' then true else false then Some b' else findA (fun a'0 : A => if eqA_dec a a'0 then true else false) l) = Some b
InA eqke (a, b) ((a', b') :: l)
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
l:list (A * B)
IHl:forall (a0 : A) (b0 : B), NoDupA eqk l -> InA eqke (a0, b0) l <-> findA (fun a'0 : A => if eqA_dec a0 a'0 then true else false) l = Some b0
a:A
b:B
H0:~ InA eqk (a', b) l
H1:NoDupA eqk l
H:eqA a a'

(if if eqA_dec a a' then true else false then Some b else findA (fun a'0 : A => if eqA_dec a a'0 then true else false) l) = Some b
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
l:list (A * B)
IHl:forall (a0 : A) (b0 : B), NoDupA eqk l -> InA eqke (a0, b0) l <-> findA (fun a'0 : A => if eqA_dec a0 a'0 then true else false) l = Some b0
a:A
b:B
H0:~ InA eqk (a', b') l
H1:NoDupA eqk l
H2:InA eqke (a, b) l
(if if eqA_dec a a' then true else false then Some b' else findA (fun a'0 : A => if eqA_dec a a'0 then true else false) l) = Some b
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
l:list (A * B)
IHl:forall (a0 : A) (b0 : B), NoDupA eqk l -> InA eqke (a0, b0) l <-> findA (fun a'0 : A => if eqA_dec a0 a'0 then true else false) l = Some b0
a:A
b:B
H0:~ InA eqk (a', b') l
H1:NoDupA eqk l
H:(if if eqA_dec a a' then true else false then Some b' else findA (fun a'0 : A => if eqA_dec a a'0 then true else false) l) = Some b
InA eqke (a, b) ((a', b') :: l)
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
l:list (A * B)
IHl:forall (a0 : A) (b0 : B), NoDupA eqk l -> InA eqke (a0, b0) l <-> findA (fun a'0 : A => if eqA_dec a0 a'0 then true else false) l = Some b0
a:A
b:B
H0:~ InA eqk (a', b') l
H1:NoDupA eqk l
H2:InA eqke (a, b) l

(if if eqA_dec a a' then true else false then Some b' else findA (fun a'0 : A => if eqA_dec a a'0 then true else false) l) = Some b
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
l:list (A * B)
IHl:forall (a0 : A) (b0 : B), NoDupA eqk l -> InA eqke (a0, b0) l <-> findA (fun a'0 : A => if eqA_dec a0 a'0 then true else false) l = Some b0
a:A
b:B
H0:~ InA eqk (a', b') l
H1:NoDupA eqk l
H:(if if eqA_dec a a' then true else false then Some b' else findA (fun a'0 : A => if eqA_dec a a'0 then true else false) l) = Some b
InA eqke (a, b) ((a', b') :: l)
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
l:list (A * B)
IHl:forall (a0 : A) (b0 : B), NoDupA eqk l -> InA eqke (a0, b0) l <-> findA (fun a'0 : A => if eqA_dec a0 a'0 then true else false) l = Some b0
a:A
b:B
H0:~ InA eqk (a', b') l
H1:NoDupA eqk l
H2:InA eqke (a, b) l
HeqA:eqA a a'

Some b' = Some b
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
l:list (A * B)
IHl:forall (a0 : A) (b0 : B), NoDupA eqk l -> InA eqke (a0, b0) l <-> findA (fun a'0 : A => if eqA_dec a0 a'0 then true else false) l = Some b0
a:A
b:B
H0:~ InA eqk (a', b') l
H1:NoDupA eqk l
H2:InA eqke (a, b) l
n:~ eqA a a'
findA (fun a'0 : A => if eqA_dec a a'0 then true else false) l = Some b
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
l:list (A * B)
IHl:forall (a0 : A) (b0 : B), NoDupA eqk l -> InA eqke (a0, b0) l <-> findA (fun a'0 : A => if eqA_dec a0 a'0 then true else false) l = Some b0
a:A
b:B
H0:~ InA eqk (a', b') l
H1:NoDupA eqk l
H:(if if eqA_dec a a' then true else false then Some b' else findA (fun a'0 : A => if eqA_dec a a'0 then true else false) l) = Some b
InA eqke (a, b) ((a', b') :: l)
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
l:list (A * B)
IHl:forall (a0 : A) (b0 : B), NoDupA eqk l -> InA eqke (a0, b0) l <-> findA (fun a'0 : A => if eqA_dec a0 a'0 then true else false) l = Some b0
a:A
b:B
H1:NoDupA eqk l
H2:InA eqke (a, b) l
HeqA:eqA a a'

InA eqk (a', b') l
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
l:list (A * B)
IHl:forall (a0 : A) (b0 : B), NoDupA eqk l -> InA eqke (a0, b0) l <-> findA (fun a'0 : A => if eqA_dec a0 a'0 then true else false) l = Some b0
a:A
b:B
H0:~ InA eqk (a', b') l
H1:NoDupA eqk l
H2:InA eqke (a, b) l
n:~ eqA a a'
findA (fun a'0 : A => if eqA_dec a a'0 then true else false) l = Some b
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
l:list (A * B)
IHl:forall (a0 : A) (b0 : B), NoDupA eqk l -> InA eqke (a0, b0) l <-> findA (fun a'0 : A => if eqA_dec a0 a'0 then true else false) l = Some b0
a:A
b:B
H0:~ InA eqk (a', b') l
H1:NoDupA eqk l
H:(if if eqA_dec a a' then true else false then Some b' else findA (fun a'0 : A => if eqA_dec a a'0 then true else false) l) = Some b
InA eqke (a, b) ((a', b') :: l)
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
l:list (A * B)
a:A
b:B

eqA a a' -> InA eqke (a, b) l -> InA eqk (a', b') l
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
l:list (A * B)
IHl:forall (a0 : A) (b0 : B), NoDupA eqk l -> InA eqke (a0, b0) l <-> findA (fun a'0 : A => if eqA_dec a0 a'0 then true else false) l = Some b0
a:A
b:B
H0:~ InA eqk (a', b') l
H1:NoDupA eqk l
H2:InA eqke (a, b) l
n:~ eqA a a'
findA (fun a'0 : A => if eqA_dec a a'0 then true else false) l = Some b
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
l:list (A * B)
IHl:forall (a0 : A) (b0 : B), NoDupA eqk l -> InA eqke (a0, b0) l <-> findA (fun a'0 : A => if eqA_dec a0 a'0 then true else false) l = Some b0
a:A
b:B
H0:~ InA eqk (a', b') l
H1:NoDupA eqk l
H:(if if eqA_dec a a' then true else false then Some b' else findA (fun a'0 : A => if eqA_dec a a'0 then true else false) l) = Some b
InA eqke (a, b) ((a', b') :: l)
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
a:A
b:B

eqA a a' -> InA eqke (a, b) nil -> InA eqk (a', b') nil
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
a0:(A * B)%type
l:list (A * B)
a:A
b:B
IHl:eqA a a' -> InA eqke (a, b) l -> InA eqk (a', b') l
eqA a a' -> InA eqke (a, b) (a0 :: l) -> InA eqk (a', b') (a0 :: l)
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
l:list (A * B)
IHl:forall (a0 : A) (b0 : B), NoDupA eqk l -> InA eqke (a0, b0) l <-> findA (fun a'0 : A => if eqA_dec a0 a'0 then true else false) l = Some b0
a:A
b:B
H0:~ InA eqk (a', b') l
H1:NoDupA eqk l
H2:InA eqke (a, b) l
n:~ eqA a a'
findA (fun a'0 : A => if eqA_dec a a'0 then true else false) l = Some b
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
l:list (A * B)
IHl:forall (a0 : A) (b0 : B), NoDupA eqk l -> InA eqke (a0, b0) l <-> findA (fun a'0 : A => if eqA_dec a0 a'0 then true else false) l = Some b0
a:A
b:B
H0:~ InA eqk (a', b') l
H1:NoDupA eqk l
H:(if if eqA_dec a a' then true else false then Some b' else findA (fun a'0 : A => if eqA_dec a a'0 then true else false) l) = Some b
InA eqke (a, b) ((a', b') :: l)
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
a0:(A * B)%type
l:list (A * B)
a:A
b:B
IHl:eqA a a' -> InA eqke (a, b) l -> InA eqk (a', b') l

eqA a a' -> InA eqke (a, b) (a0 :: l) -> InA eqk (a', b') (a0 :: l)
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
l:list (A * B)
IHl:forall (a0 : A) (b0 : B), NoDupA eqk l -> InA eqke (a0, b0) l <-> findA (fun a'0 : A => if eqA_dec a0 a'0 then true else false) l = Some b0
a:A
b:B
H0:~ InA eqk (a', b') l
H1:NoDupA eqk l
H2:InA eqke (a, b) l
n:~ eqA a a'
findA (fun a'0 : A => if eqA_dec a a'0 then true else false) l = Some b
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
l:list (A * B)
IHl:forall (a0 : A) (b0 : B), NoDupA eqk l -> InA eqke (a0, b0) l <-> findA (fun a'0 : A => if eqA_dec a0 a'0 then true else false) l = Some b0
a:A
b:B
H0:~ InA eqk (a', b') l
H1:NoDupA eqk l
H:(if if eqA_dec a a' then true else false then Some b' else findA (fun a'0 : A => if eqA_dec a a'0 then true else false) l) = Some b
InA eqke (a, b) ((a', b') :: l)
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
a0:(A * B)%type
l:list (A * B)
a:A
b:B
IHl:eqA a a' -> InA eqke (a, b) l -> InA eqk (a', b') l
HeqA:eqA a a'
H:eqke (a, b) a0

InA eqk (a', b') (a0 :: l)
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
l:list (A * B)
IHl:forall (a0 : A) (b0 : B), NoDupA eqk l -> InA eqke (a0, b0) l <-> findA (fun a'0 : A => if eqA_dec a0 a'0 then true else false) l = Some b0
a:A
b:B
H0:~ InA eqk (a', b') l
H1:NoDupA eqk l
H2:InA eqke (a, b) l
n:~ eqA a a'
findA (fun a'0 : A => if eqA_dec a a'0 then true else false) l = Some b
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
l:list (A * B)
IHl:forall (a0 : A) (b0 : B), NoDupA eqk l -> InA eqke (a0, b0) l <-> findA (fun a'0 : A => if eqA_dec a0 a'0 then true else false) l = Some b0
a:A
b:B
H0:~ InA eqk (a', b') l
H1:NoDupA eqk l
H:(if if eqA_dec a a' then true else false then Some b' else findA (fun a'0 : A => if eqA_dec a a'0 then true else false) l) = Some b
InA eqke (a, b) ((a', b') :: l)
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
a0:A
b0:B
l:list (A * B)
a:A
b:B
IHl:eqA a a' -> InA eqke (a, b) l -> InA eqk (a', b') l
HeqA:eqA a a'
H:eqke (a, b) (a0, b0)

InA eqk (a', b') ((a0, b0) :: l)
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
l:list (A * B)
IHl:forall (a0 : A) (b0 : B), NoDupA eqk l -> InA eqke (a0, b0) l <-> findA (fun a'0 : A => if eqA_dec a0 a'0 then true else false) l = Some b0
a:A
b:B
H0:~ InA eqk (a', b') l
H1:NoDupA eqk l
H2:InA eqke (a, b) l
n:~ eqA a a'
findA (fun a'0 : A => if eqA_dec a a'0 then true else false) l = Some b
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
l:list (A * B)
IHl:forall (a0 : A) (b0 : B), NoDupA eqk l -> InA eqke (a0, b0) l <-> findA (fun a'0 : A => if eqA_dec a0 a'0 then true else false) l = Some b0
a:A
b:B
H0:~ InA eqk (a', b') l
H1:NoDupA eqk l
H:(if if eqA_dec a a' then true else false then Some b' else findA (fun a'0 : A => if eqA_dec a a'0 then true else false) l) = Some b
InA eqke (a, b) ((a', b') :: l)
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
a0:A
b0:B
l:list (A * B)
a:A
b:B
IHl:eqA a a' -> InA eqke (a, b) l -> InA eqk (a', b') l
HeqA:eqA a a'
H:eqA a a0
H0:b = b0

InA eqk (a', b') ((a0, b0) :: l)
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
l:list (A * B)
IHl:forall (a0 : A) (b0 : B), NoDupA eqk l -> InA eqke (a0, b0) l <-> findA (fun a'0 : A => if eqA_dec a0 a'0 then true else false) l = Some b0
a:A
b:B
H0:~ InA eqk (a', b') l
H1:NoDupA eqk l
H2:InA eqke (a, b) l
n:~ eqA a a'
findA (fun a'0 : A => if eqA_dec a a'0 then true else false) l = Some b
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
l:list (A * B)
IHl:forall (a0 : A) (b0 : B), NoDupA eqk l -> InA eqke (a0, b0) l <-> findA (fun a'0 : A => if eqA_dec a0 a'0 then true else false) l = Some b0
a:A
b:B
H0:~ InA eqk (a', b') l
H1:NoDupA eqk l
H:(if if eqA_dec a a' then true else false then Some b' else findA (fun a'0 : A => if eqA_dec a a'0 then true else false) l) = Some b
InA eqke (a, b) ((a', b') :: l)
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
a0:A
b0:B
l:list (A * B)
a:A
IHl:eqA a a' -> InA eqke (a, b0) l -> InA eqk (a', b') l
HeqA:eqA a a'
H:eqA a a0

InA eqk (a', b') ((a0, b0) :: l)
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
l:list (A * B)
IHl:forall (a0 : A) (b0 : B), NoDupA eqk l -> InA eqke (a0, b0) l <-> findA (fun a'0 : A => if eqA_dec a0 a'0 then true else false) l = Some b0
a:A
b:B
H0:~ InA eqk (a', b') l
H1:NoDupA eqk l
H2:InA eqke (a, b) l
n:~ eqA a a'
findA (fun a'0 : A => if eqA_dec a a'0 then true else false) l = Some b
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
l:list (A * B)
IHl:forall (a0 : A) (b0 : B), NoDupA eqk l -> InA eqke (a0, b0) l <-> findA (fun a'0 : A => if eqA_dec a0 a'0 then true else false) l = Some b0
a:A
b:B
H0:~ InA eqk (a', b') l
H1:NoDupA eqk l
H:(if if eqA_dec a a' then true else false then Some b' else findA (fun a'0 : A => if eqA_dec a a'0 then true else false) l) = Some b
InA eqke (a, b) ((a', b') :: l)
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
a0:A
b0:B
l:list (A * B)
a:A
IHl:eqA a a' -> InA eqke (a, b0) l -> InA eqk (a', b') l
HeqA:eqA a a'
H:eqA a a0

eqk (a', b') (a0, b0)
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
l:list (A * B)
IHl:forall (a0 : A) (b0 : B), NoDupA eqk l -> InA eqke (a0, b0) l <-> findA (fun a'0 : A => if eqA_dec a0 a'0 then true else false) l = Some b0
a:A
b:B
H0:~ InA eqk (a', b') l
H1:NoDupA eqk l
H2:InA eqke (a, b) l
n:~ eqA a a'
findA (fun a'0 : A => if eqA_dec a a'0 then true else false) l = Some b
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
l:list (A * B)
IHl:forall (a0 : A) (b0 : B), NoDupA eqk l -> InA eqke (a0, b0) l <-> findA (fun a'0 : A => if eqA_dec a0 a'0 then true else false) l = Some b0
a:A
b:B
H0:~ InA eqk (a', b') l
H1:NoDupA eqk l
H:(if if eqA_dec a a' then true else false then Some b' else findA (fun a'0 : A => if eqA_dec a a'0 then true else false) l) = Some b
InA eqke (a, b) ((a', b') :: l)
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
a0:A
b0:B
l:list (A * B)
a:A
IHl:eqA a a' -> InA eqke (a, b0) l -> InA eqk (a', b') l
HeqA:eqA a a'
H:eqA a a0

eqA a' a0
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
l:list (A * B)
IHl:forall (a0 : A) (b0 : B), NoDupA eqk l -> InA eqke (a0, b0) l <-> findA (fun a'0 : A => if eqA_dec a0 a'0 then true else false) l = Some b0
a:A
b:B
H0:~ InA eqk (a', b') l
H1:NoDupA eqk l
H2:InA eqke (a, b) l
n:~ eqA a a'
findA (fun a'0 : A => if eqA_dec a a'0 then true else false) l = Some b
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
l:list (A * B)
IHl:forall (a0 : A) (b0 : B), NoDupA eqk l -> InA eqke (a0, b0) l <-> findA (fun a'0 : A => if eqA_dec a0 a'0 then true else false) l = Some b0
a:A
b:B
H0:~ InA eqk (a', b') l
H1:NoDupA eqk l
H:(if if eqA_dec a a' then true else false then Some b' else findA (fun a'0 : A => if eqA_dec a a'0 then true else false) l) = Some b
InA eqke (a, b) ((a', b') :: l)
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
a0:A
b0:B
l:list (A * B)
a:A
IHl:eqA a a' -> InA eqke (a, b0) l -> InA eqk (a', b') l
HeqA:eqA a a'
H:eqA a a0

eqA a' a
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
l:list (A * B)
IHl:forall (a0 : A) (b0 : B), NoDupA eqk l -> InA eqke (a0, b0) l <-> findA (fun a'0 : A => if eqA_dec a0 a'0 then true else false) l = Some b0
a:A
b:B
H0:~ InA eqk (a', b') l
H1:NoDupA eqk l
H2:InA eqke (a, b) l
n:~ eqA a a'
findA (fun a'0 : A => if eqA_dec a a'0 then true else false) l = Some b
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
l:list (A * B)
IHl:forall (a0 : A) (b0 : B), NoDupA eqk l -> InA eqke (a0, b0) l <-> findA (fun a'0 : A => if eqA_dec a0 a'0 then true else false) l = Some b0
a:A
b:B
H0:~ InA eqk (a', b') l
H1:NoDupA eqk l
H:(if if eqA_dec a a' then true else false then Some b' else findA (fun a'0 : A => if eqA_dec a a'0 then true else false) l) = Some b
InA eqke (a, b) ((a', b') :: l)
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
l:list (A * B)
IHl:forall (a0 : A) (b0 : B), NoDupA eqk l -> InA eqke (a0, b0) l <-> findA (fun a'0 : A => if eqA_dec a0 a'0 then true else false) l = Some b0
a:A
b:B
H0:~ InA eqk (a', b') l
H1:NoDupA eqk l
H2:InA eqke (a, b) l
n:~ eqA a a'

findA (fun a'0 : A => if eqA_dec a a'0 then true else false) l = Some b
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
l:list (A * B)
IHl:forall (a0 : A) (b0 : B), NoDupA eqk l -> InA eqke (a0, b0) l <-> findA (fun a'0 : A => if eqA_dec a0 a'0 then true else false) l = Some b0
a:A
b:B
H0:~ InA eqk (a', b') l
H1:NoDupA eqk l
H:(if if eqA_dec a a' then true else false then Some b' else findA (fun a'0 : A => if eqA_dec a a'0 then true else false) l) = Some b
InA eqke (a, b) ((a', b') :: l)
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
l:list (A * B)
IHl:forall (a0 : A) (b0 : B), NoDupA eqk l -> InA eqke (a0, b0) l <-> findA (fun a'0 : A => if eqA_dec a0 a'0 then true else false) l = Some b0
a:A
b:B
H0:~ InA eqk (a', b') l
H1:NoDupA eqk l
H:(if if eqA_dec a a' then true else false then Some b' else findA (fun a'0 : A => if eqA_dec a a'0 then true else false) l) = Some b

InA eqke (a, b) ((a', b') :: l)
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
l:list (A * B)
IHl:forall (a0 : A) (b0 : B), NoDupA eqk l -> InA eqke (a0, b0) l <-> findA (fun a'0 : A => if eqA_dec a0 a'0 then true else false) l = Some b0
a:A
b:B
H0:~ InA eqk (a', b') l
H1:NoDupA eqk l
e:eqA a a'
H:Some b' = Some b

InA eqke (a, b) ((a', b') :: l)
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
l:list (A * B)
IHl:forall (a0 : A) (b0 : B), NoDupA eqk l -> InA eqke (a0, b0) l <-> findA (fun a'0 : A => if eqA_dec a0 a'0 then true else false) l = Some b0
a:A
b:B
H0:~ InA eqk (a', b') l
H1:NoDupA eqk l
n:~ eqA a a'
H:findA (fun a'0 : A => if eqA_dec a a'0 then true else false) l = Some b
InA eqke (a, b) ((a', b') :: l)
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
l:list (A * B)
IHl:forall (a0 : A) (b0 : B), NoDupA eqk l -> InA eqke (a0, b0) l <-> findA (fun a'0 : A => if eqA_dec a0 a'0 then true else false) l = Some b0
a:A
b:B
H0:~ InA eqk (a', b') l
H1:NoDupA eqk l
n:~ eqA a a'
H:findA (fun a'0 : A => if eqA_dec a a'0 then true else false) l = Some b

InA eqke (a, b) ((a', b') :: l)
A, B:Type
eqA:A -> A -> Prop
eqA_equiv:Equivalence eqA
eqA_dec:forall x y : A, {eqA x y} + {~ eqA x y}
eqk:=fun p p' : A * B => eqA (fst p) (fst p'):A * B -> A * B -> Prop
eqke:=fun p p' : A * B => eqA (fst p) (fst p') /\ snd p = snd p':A * B -> A * B -> Prop
a':A
b':B
l:list (A * B)
IHl:forall (a0 : A) (b0 : B), NoDupA eqk l -> InA eqke (a0, b0) l <-> findA (fun a'0 : A => if eqA_dec a0 a'0 then true else false) l = Some b0
a:A
b:B
H0:~ InA eqk (a', b') l
H1:NoDupA eqk l
n:~ eqA a a'
H:findA (fun a'0 : A => if eqA_dec a a'0 then true else false) l = Some b

InA eqke (a, b) l
rewrite IHl; auto. Qed. End Find.
Compatibility aliases. Proper is rather to be used directly now.
Definition compat_bool {A} (eqA:A->A->Prop)(f:A->bool) :=
 Proper (eqA==>Logic.eq) f.

Definition compat_nat {A} (eqA:A->A->Prop)(f:A->nat) :=
 Proper (eqA==>Logic.eq) f.

Definition compat_P {A} (eqA:A->A->Prop)(P:A->Prop) :=
 Proper (eqA==>impl) P.

Definition compat_op {A B} (eqA:A->A->Prop)(eqB:B->B->Prop)(f:A->B->B) :=
 Proper (eqA==>eqB==>eqB) f.