D5: Więcej zabaw z listami [TODO]
From Typonomikon Require Export D5d.
Permutacje (TODO)
Permutacje jako ciągi transpozycji
Module Transpositions.
Inductive Perm {A : Type} : list A -> list A -> Prop :=
| Perm_refl : forall l : list A, Perm l l
| Perm_transp :
forall (x y : A) (l1 l2 l3 l4 : list A),
Perm (l1 ++ x :: l2 ++ y :: l3) l4 ->
Perm (l1 ++ y :: l2 ++ x :: l3) l4.
Lemma Perm_cons :
forall {A : Type} (h : A) (t1 t2 : list A),
Perm t1 t2 -> Perm (h :: t1) (h :: t2).
Lemma Perm_trans :
forall {A : Type} {l1 l2 l3 : list A},
Perm l1 l2 -> Perm l2 l3 -> Perm l1 l3.
Lemma Permutation_Perm :
forall {A : Type} {l1 l2 : list A},
Permutation l1 l2 -> Perm l1 l2.
Lemma Permutation_transpose :
forall {A : Type} {x y : A} {l1 l2 l3 : list A},
Permutation (l1 ++ x :: l2 ++ y :: l3) (l1 ++ y :: l2 ++ x :: l3).
Lemma Perm_Permutation :
forall {A : Type} {l1 l2 : list A},
Perm l1 l2 -> Permutation l1 l2.
End Transpositions.
Permutacje jako ciągi transpozycji v2
Module InductiveTranspositions.
Inductive Transposition {A : Type} : list A -> list A -> Prop :=
| Transposition' :
forall (l1 : list A) (x : A) (l2 : list A) (y : A) (l3 : list A),
Transposition (l1 ++ x :: l2 ++ y :: l3) (l1 ++ y :: l2 ++ x :: l3).
Inductive Transposition2 {A : Type} : list A -> list A -> Prop :=
| Transposition2' :
forall (l1 : list A) (x : A) (l2 : list A) (y : A) (l3 r1 r2: list A),
r1 = l1 ++ x :: l2 ++ y :: l3 ->
r2 = l1 ++ y :: l2 ++ x :: l3 ->
Transposition2 r1 r2.
Inductive Perm {A : Type} : list A -> list A -> Prop :=
| Perm_refl : forall l : list A, Perm l l
| Perm_step_trans :
forall l1 l2 l3 : list A,
Transposition l1 l2 -> Perm l2 l3 -> Perm l1 l3.
Lemma Perm_cons :
forall (A : Type) (x : A) (l1 l2 : list A),
Perm l1 l2 -> Perm (x :: l1) (x :: l2).
Lemma Perm_trans :
forall (A : Type) (l1 l2 l3 : list A),
Perm l1 l2 -> Perm l2 l3 -> Perm l1 l3.
Lemma Permutation_Perm :
forall (A : Type) (l1 l2 : list A),
Permutation l1 l2 -> Perm l1 l2.
Lemma Perm_Permutation :
forall (A : Type) (l1 l2 : list A),
Perm l1 l2 -> Permutation l1 l2.
Lemma Perm_spec :
forall (A : Type) (l1 l2 : list A),
Perm l1 l2 <-> Permutation l1 l2.
Lemma Perm_count :
forall (A : Type) (p : A -> bool) (l1 l2 : list A),
Perm l1 l2 -> count p l1 = count p l2.
End InductiveTranspositions.
Permutacje jako ciągi transpozycji elementów sąsiednich
Module AdjacentTranspositions.
Inductive Perm {A : Type} : list A -> list A -> Prop :=
| Perm_refl : forall l : list A, Perm l l
| Perm_steptrans :
forall (x y : A) (l1 l2 l3 : list A),
Perm (l1 ++ y :: x :: l2) l3 -> Perm (l1 ++ x :: y :: l2) l3.
Lemma Perm_Permutation :
forall (A : Type) (l1 l2 : list A),
Perm l1 l2 -> Permutation l1 l2.
Lemma Perm_cons :
forall {A : Type} (x : A) {l1 l2 : list A},
Perm l1 l2 -> Perm (x :: l1) (x :: l2).
Lemma Perm_trans :
forall {A : Type} {l1 l2 l3 : list A},
Perm l1 l2 -> Perm l2 l3 -> Perm l1 l3.
Lemma Permutation_Perm :
forall {A : Type} {l1 l2 : list A},
Permutation l1 l2 -> Perm l1 l2.
End AdjacentTranspositions.
Permutacje jako ciągi transpozycji elementów sąsiednich v2
Module Exchange.
Definition exchange {A : Type} (l1 l2 : list A) : Prop :=
exists (x y : A) (r1 r2 : list A),
l1 = r1 ++ x :: y :: r2 /\
l2 = r1 ++ y :: x :: r2.
Inductive Perm {A : Type} : list A -> list A -> Prop :=
| Perm_refl : forall l : list A, Perm l l
| Perm_step_trans :
forall l1 l2 l3 : list A,
exchange l1 l2 -> Perm l2 l3 -> Perm l1 l3.
Lemma Perm_cons :
forall (A : Type) (x : A) (l1 l2 : list A),
Perm l1 l2 -> Perm (x :: l1) (x :: l2).
Lemma Perm_trans :
forall (A : Type) (l1 l2 l3 : list A),
Perm l1 l2 -> Perm l2 l3 -> Perm l1 l3.
Lemma Permutation_Perm :
forall (A : Type) (l1 l2 : list A),
Permutation l1 l2 -> Perm l1 l2.
Lemma Perm_Permutation :
forall (A : Type) (l1 l2 : list A),
Perm l1 l2 -> Permutation l1 l2.
Lemma Perm_spec :
forall (A : Type) (l1 l2 : list A),
Perm l1 l2 <-> Permutation l1 l2.
Lemma Perm_count :
forall (A : Type) (p : A -> bool) (l1 l2 : list A),
Perm l1 l2 -> count p l1 = count p l2.
End Exchange.
Permutacje za pomocą liczenia właściwości
Module Exactly.
Ltac inv H := inversion H; subst; clear H.
Definition Perm {A : Type} (l1 l2 : list A) : Prop :=
forall (P : A -> Prop) (n : nat),
Exactly P n l1 <-> Exactly P n l2.
Lemma Permutation_Exactly :
forall {A : Type} {l1 l2 : list A},
Permutation l1 l2 ->
forall (P : A -> Prop) (n : nat),
Exactly P n l1 -> Exactly P n l2.
Lemma Permutation_Perm :
forall {A : Type} {l1 l2 : list A},
Permutation l1 l2 -> Perm l1 l2.
Lemma Perm_front_ex :
forall {A : Type} {h : A} {t l : list A},
Perm (h :: t) l ->
exists l1 l2 : list A,
l = l1 ++ h :: l2 /\ Perm t (l1 ++ l2).
Lemma Perm_Permutation :
forall {A : Type} {l1 l2 : list A},
Perm l1 l2 -> Permutation l1 l2.
End Exactly.
Permutacje za pomocą liczenia właściwości v2
Module AtLeast.
Ltac inv H := inversion H; subst; clear H.
Definition Perm {A : Type} (l1 l2 : list A) : Prop :=
forall (P : A -> Prop) (n : nat),
(AtLeast P n l1 <-> AtLeast P n l2).
#[global] Hint Constructors AtLeast : core.
Lemma Permutation_AtLeast :
forall {A : Type} {l1 l2 : list A},
Permutation l1 l2 ->
forall (P : A -> Prop) (n : nat),
AtLeast P n l1 -> AtLeast P n l2.
Lemma Permutation_Perm :
forall {A : Type} {l1 l2 : list A},
Permutation l1 l2 -> Perm l1 l2.
Lemma AtLeast_1 :
forall {A : Type} {P : A -> Prop} {l : list A},
AtLeast P 1 l ->
exists (x : A) (l1 l2 : list A),
P x /\ l = l1 ++ x :: l2.
Lemma AtLeast_app_comm' :
forall {A : Type} {P : A -> Prop} {n : nat} {l1 l2 : list A},
AtLeast P n (l1 ++ l2) <-> AtLeast P n (l2 ++ l1).
Lemma AtLeast_cons_app :
forall
{A : Type} {P : A -> Prop} {n : nat}
(x : A) (l1 l2 : list A),
AtLeast P n (l1 ++ x :: l2) <->
AtLeast P n (x :: l1 ++ l2).
Lemma Perm_front_ex :
forall {A : Type} {h : A} {t l : list A},
Perm (h :: t) l ->
exists l1 l2 : list A,
l = l1 ++ h :: l2 /\ Perm t (l1 ++ l2).
Lemma Perm_Permutation :
forall {A : Type} {l1 l2 : list A},
Perm l1 l2 -> Permutation l1 l2.
#[global] Hint Constructors Exactly : core.
Lemma AtLeast_Exactly :
forall {A : Type} (l1 l2 : list A),
(forall (P : A -> Prop) (n : nat),
AtLeast P n l1 <-> AtLeast P n l2)
<->
(forall (P : A -> Prop) (n : nat),
Exactly P n l1 <-> Exactly P n l2).
End AtLeast.
Permutacje, jeszcze dziwniej
Require Import Equality.
Module PermWeird.
Inductive Elem {A : Type} (x : A) : list A -> Type :=
| Z : forall l : list A, Elem x (x :: l)
| S : forall {t : list A}, Elem x t -> forall h : A, Elem x (h :: t).
Arguments Z {A x} _.
Arguments S {A x t} _ _.
TODO: iso skopiowane z rozdziału o izomorfizmach typów.
Class iso (A B : Type) : Type :=
{
coel : A -> B;
coer : B -> A;
coel_coer :
forall a : A, coer (coel a) = a;
coer_coel :
forall b : B, coel (coer b) = b;
}.
Arguments coel {A B} _.
Arguments coer {A B} _.
Definition Perm {A : Type} (l1 l2 : list A) : Type :=
forall x : A, iso (Elem x l1) (Elem x l2).
End PermWeird.
Permutacje za pomocą liczenia właściwości rozstrzygalnych
Module Count.
Definition perm {A : Type} (l1 l2 : list A) : Prop :=
forall p : A -> bool, count p l1 = count p l2.
Lemma count_ex :
forall (A : Type) (p : A -> bool) (l : list A),
count p l = 0 \/
exists (x : A) (l1 l2 : list A),
p x = true /\ l = l1 ++ x :: l2.
Import Exchange.
Lemma Perm_perm :
forall (A : Type) (l1 l2 : list A),
Perm l1 l2 -> perm l1 l2.
Lemma perm_Perm :
forall (A : Type) (l1 l2 : list A),
perm l1 l2 -> Perm l1 l2.
End Count.
Permutacje przez wstawianie
Module Insert.
Inductive Insert {A : Type} (x : A) : list A -> list A -> Type :=
| Insert_here :
forall l : list A, Insert x l (x :: l)
| Insert_there :
forall (h : A) (t t' : list A), Insert x t t' -> Insert x (h :: t) (h :: t').
Inductive Perm {A : Type} : list A -> list A -> Prop :=
| Perm_nil : Perm [] []
| Perm_Insert :
forall (x : A) (l1 l1' l2 l2' : list A),
Insert x l1 l1' -> Insert x l2 l2' -> Perm l1 l2 -> Perm l1' l2'.
#[global] Hint Constructors Insert Perm : core.
Lemma Perm_refl :
forall {A : Type} (l : list A),
Perm l l.
Proof.
induction l as [| h t]; econstructor; eauto.
Qed.
Lemma Perm_Insert' :
forall {A : Type} (x : A) (l1 l2 : list A),
Insert x l1 l2 -> Perm (x :: l1) l2.
Proof.
induction 1.
apply Perm_refl.
econstructor; eauto. apply Perm_refl.
Qed.
Lemma Perm_trans :
forall {A : Type} {l1 l2 : list A},
Perm l1 l2 -> forall l3 : list A, Perm l2 l3 -> Perm l1 l3.
Proof.
intros until 2. revert l1 H.
induction H0; intros.
assumption.
{
revert x l1 l2 l2' X X0 H0 IHPerm.
induction H; intros.
inv X.
{
apply Perm_Insert' in X.
apply Perm_Insert' in X0.
apply Perm_Insert' in X1.
apply Perm_Insert' in X2.
Admitted.
Lemma Permutation_Perm :
forall {A : Type} {l1 l2 : list A},
Permutation l1 l2 -> Perm l1 l2.
Proof.
induction 1.
constructor.
econstructor; eauto.
econstructor; eauto. apply Perm_refl.
eapply Perm_trans; eassumption.
Qed.
Lemma Permutation_Insert :
forall {A : Type} (x : A) (l1 l2 : list A),
Insert x l1 l2 -> Permutation (x :: l1) l2.
Proof.
induction 1.
reflexivity.
econstructor; eauto.
Qed.
Lemma Perm_Permutation :
forall {A : Type} {l1 l2 : list A},
Perm l1 l2 -> Permutation l1 l2.
Proof.
induction 1.
reflexivity.
{
apply Permutation_Insert in X.
apply Permutation_Insert in X0.
rewrite <- X, <- X0.
constructor.
assumption.
}
Qed.
End Insert.
Permutacje przez wstawianie v2 (TODO)
Module Insert2.
Inductive Perm {A : Type} : list A -> list A -> Prop :=
| Perm_nil : Perm [] []
| Perm_insert :
forall (x : A) (l1 l2 r1 r2 : list A),
Perm (l1 ++ l2) (r1 ++ r2) -> Perm (l1 ++ x :: l2) (r1 ++ x :: r2).
#[global] Hint Constructors Perm : core.
Lemma Perm_refl :
forall {A : Type} (l : list A),
Perm l l.
Proof.
induction l as [| h t].
constructor.
apply (Perm_insert h [] t [] t). cbn. assumption.
Qed.
Lemma Perm_sym :
forall {A : Type} {l1 l2 : list A},
Perm l1 l2 -> Perm l2 l1.
Proof.
induction 1.
constructor.
constructor. assumption.
Qed.
Lemma Perm_trans :
forall {A : Type} {l1 l2 : list A},
Perm l1 l2 -> forall l3 : list A, Perm l2 l3 -> Perm l1 l3.
Proof.
intros until 2.
revert l1 H.
induction H0; intros.
assumption.
inv H.
apply (f_equal length) in H3. rewrite length_app in H3. cbn in H3. lia.
Restart.
induction 1 as [| x l1 l2 r1 r2 H12 IH].
intros. assumption.
{
intros l3 H23. remember (r1 ++ x :: r2) as MID.
revert l1 l2 H12 IH HeqMID.
induction H23; intros.
apply (f_equal length) in HeqMID. rewrite length_app in HeqMID. cbn in HeqMID. lia.
Admitted.
Lemma Permutation_Perm :
forall {A : Type} {l1 l2 : list A},
Permutation l1 l2 -> Perm l1 l2.
Proof.
induction 1.
constructor.
apply (Perm_insert x [] l [] l'). cbn. assumption.
apply (Perm_insert x [y] l [] (y :: l)). cbn. apply Perm_refl.
eapply Perm_trans; eassumption.
Qed.
Lemma Perm_Permutation :
forall {A : Type} {l1 l2 : list A},
Perm l1 l2 -> Permutation l1 l2.
Proof.
induction 1.
reflexivity.
rewrite !Permutation_middle. constructor. assumption.
Qed.
End Insert2.
Znajdowanie wszystkich permutacji (TODO)
Znajdowanie permutacji przez selekcję
Module perms_select.
Fixpoint select {A : Type} (l : list A) : list (list A * list A) :=
match l with
| [] => [([], [])]
| h :: t => [([], l)] ++ map (fun '(a, b) => (h :: a, b)) (select t)
end.
Lemma select_app :
forall {A : Type} {l1 l2 : list A},
select (l1 ++ l2) =
map (fun '(l, r) => (app l l2, r)) (select l1) ++
map (fun '(l, r) => (app l1 l, r)) (select l2).
Fixpoint perms {A : Type} (l : list A) : list (list A) :=
match l with
| [] => [[]]
| h :: t =>
bind (fun ll =>
map (fun '(l, r) => l ++ h :: r) (select ll)) (perms t)
end.
Lemma Permutation_bind :
forall {A B : Type} (f g : A -> list B),
(forall x : A, Permutation (f x) (g x)) ->
forall l : list A, Permutation (bind f l) (bind g l).
Lemma Permutation_select_app :
forall {A : Type} {l1 l2 : list A},
Permutation (select (l1 ++ l2)) (select (l2 ++ l1)).
Lemma map_select :
forall {A B : Type} (f : A -> B) (l : list A),
select (map f l)
=
map (fun '(L, R) => (map f L, map f R)) (select l).
Lemma Permutation_perms :
forall (A : Type) (l1 l2 : list A),
Permutation l1 l2 -> Permutation (perms l1) (perms l2).
Lemma elem_perms :
forall (A : Type) (l : list A),
elem l (perms l).
Lemma Permutation_perms' :
forall (A : Type) (l1 l2 : list A),
Permutation l1 l2 -> elem l1 (perms l2).
End perms_select.
Module perms_ins.
Znajdowanie permutacji przez wstawianie
Fixpoint ins {A : Type} (x : A) (l : list A) : list (list A) :=
match l with
| [] => [[x]]
| h :: t => [x :: h :: t] ++ map (cons h) (ins x t)
end.
Fixpoint perms {A : Type} (l : list A) : list (list A) :=
match l with
| [] => [[]]
| h :: t => bind (ins h) (perms t)
end.
Lemma len_ins :
forall (A : Type) (x : A) (l : list A),
length (ins x l) = S (length l).
Fixpoint nsum (l : list nat) : nat :=
match l with
| [] => 0
| h :: t => h + nsum t
end.
Lemma len_join :
forall (A : Type) (ll : list (list A)),
length (join ll) = nsum (map length ll).
Lemma len_perms :
forall (A : Type) (l : list A),
length (perms l) = fact (length l).
Lemma map_ins :
forall (A B : Type) (f : A -> B) (x : A) (l : list A),
map (map f) (ins x l) = ins (f x) (map f l).
Lemma ins_app :
forall (A : Type) (x : A) (l1 l2 : list A),
l1 = [] \/
l2 = [] \/
ins x (l1 ++ l2) =
map (fun l => app l l2) (ins x l1) ++
map (app l1) (ins x l2).
Lemma ins_snoc :
forall (A : Type) (x y : A) (l : list A),
ins x (snoc y l) =
snoc (snoc x (snoc y l)) (map (snoc y) (ins x l)).
Lemma map_ext_eq :
forall {A B : Type} {f g : A -> B} {l : list A},
(forall x : A, f x = g x) ->
map f l = map g l.
Lemma ins_rev :
forall (A : Type) (x : A) (l : list A),
ins x (rev l) = rev (map rev (ins x l)).
Lemma elem_ins :
forall (A : Type) (x : A) (l : list A),
elem (x :: l) (ins x l).
Lemma elem_perms :
forall (A : Type) (l : list A),
elem l (perms l).
Lemma Permutation_elem_ins :
forall (A : Type) (x : A) (l1 l2 : list A),
elem l2 (ins x l1) -> Permutation (x :: l1) l2.
Lemma Permutation_bind :
forall (A B : Type) (f g : A -> list B) (l1 l2 : list A),
(forall x : A, Permutation (f x) (g x)) ->
Permutation l1 l2 ->
Permutation (bind f l1) (bind g l2).
Lemma count_join :
forall (A : Type) (p : A -> bool) (l : list (list A)),
count p (join l) = nsum (map (count p) l).
Lemma nsum_app :
forall l1 l2 : list nat,
nsum (l1 ++ l2) = nsum l1 + nsum l2.
Fixpoint deepcount
{A : Type} (p : A -> bool) (l : list (list A)) : nat :=
match l with
| [] => 0
| h :: t => count p h + deepcount p t
end.
Lemma Permutation_bind_ins :
forall {A : Type} (x y : A) (l : list A),
Permutation (bind (ins x) (ins y l)) (bind (ins y) (ins x l)).
Lemma Permutation_perms :
forall (A : Type) (l1 l2 : list A),
Permutation l1 l2 -> Permutation (perms l1) (perms l2).
Lemma Permutation_perms' :
forall (A : Type) (l1 l2 : list A),
Permutation l1 l2 -> elem l1 (perms l2).
Lemma perms_Permutation :
forall {A : Type} {l1 l2 : list A},
elem l1 (perms l2) -> Permutation l1 l2.
End perms_ins.
Znajdowanie permutacji przez cykle
Require Import FunctionalExtensionality.
Module perms_cycles.
Import cycles.
Fixpoint perms {A : Type} (l : list A) : list (list A) :=
match l with
| [] => [[]]
| h :: t => join (map (fun t => cycles (cons h t)) (perms t))
end.
Compute cycles [1; 2].
Compute perms [3].
Compute perms [2; 3].
Compute cycles (map (cons 2) [[3]]).
Compute perms [1; 2; 3].
Compute perms [1; 2; 3; 4].
Fixpoint sum (l : list nat) : nat :=
match l with
| [] => 0
| h :: t => h + sum t
end.
Lemma len_join :
forall {A : Type} (l : list (list A)),
length (join l) = sum (map length l).
Lemma len_cycles_aux :
forall {A : Type} (l : list A) (n : nat),
length (cycles_aux n l) = n.
Lemma len_cycles :
forall {A : Type} (l : list A),
l <> [] -> length (cycles l) = length l.
Lemma sum_map_S :
forall l : list nat,
sum (map S l) = length l + sum l.
Lemma sum_replicate :
forall n m : nat,
sum (replicate n m) = n * m.
Lemma length_perms :
forall {A : Type} (l : list A),
length (perms l) = fact (length l) /\
map length (perms l) =
replicate (length (perms l)) (length l).
Lemma perms_spec :
forall {A : Type} (l1 l2 : list A),
elem l1 (perms l2) -> Permutation l1 l2.
Lemma perms_spec :
forall {A : Type} (l1 l2 : list A),
Permutation l1 l2 -> elem l1 (perms l2).
End perms_cycles.
Module Specs.
Import Count.
Import perms_select.
Lemma perm_perms :
forall {A : Type} {l1 l2 : list A},
perm l1 l2 -> elem l1 (perms l2).
End Specs.
Zbiory
Zbiory jako zdeduplikowane permutacje
Inductive SameSet {A : Type} : list A -> list A -> Prop :=
| SameSet_nil : SameSet [] []
| SameSet_cons :
forall (h : A) (t1 t2 : list A), SameSet t1 t2 -> SameSet (h :: t1) (h :: t2)
| SameSet_swap :
forall (x y : A) (l : list A), SameSet (y :: x :: l) (x :: y :: l)
| SameSet_dedup :
forall (h : A) (t : list A), SameSet (h :: t) (h :: h :: t)
| SameSet_trans :
forall l1 l2 l3 : list A, SameSet l1 l2 -> SameSet l2 l3 -> SameSet l1 l3.
Lemma SameSet_SetEquiv :
forall {A : Type} {l1 l2 : list A},
SameSet l1 l2 -> SetEquiv l1 l2.
Lemma Permutation_SameSet :
forall {A : Type} {l1 l2 : list A},
Permutation l1 l2 -> SameSet l1 l2.
Module SetExists.
Definition SameSetEx {A : Type} (l1 l2 : list A) : Prop :=
forall P : A -> Prop, Exists P l1 <-> Exists P l2.
Lemma SameSetEx_SetEquiv :
forall {A : Type} {l1 l2 : list A},
SameSetEx l1 l2 <-> SetEquiv l1 l2.
End SetExists.
Zbiory za pomocą transpozycji i deduplikacji
Module SetTranspositionDedup.
Inductive Transposition {A : Type} : list A -> list A -> Prop :=
| Transposition' :
forall (x y : A) (l1 l2 l3 : list A),
Transposition (l1 ++ x :: l2 ++ y :: l3) (l1 ++ y :: l2 ++ x :: l3).
Inductive Dedup {A : Type} : list A -> list A -> Prop :=
| Dedup' :
forall (x : A) (l1 l2 l3 : list A),
Dedup (l1 ++ x :: l2 ++ x :: l3) (l1 ++ x :: l2 ++ l3).
Inductive SameSetTD {A : Type} : list A -> list A -> Prop :=
| SameSetTD_refl :
forall l : list A, SameSetTD l l
| SameSetTD_transp :
forall l1 l2 l3 : list A,
Transposition l1 l2 -> SameSetTD l2 l3 -> SameSetTD l1 l3
| SameSetTD_dedup :
forall l1 l2 l3 : list A,
Dedup l1 l2 -> SameSetTD l2 l3 -> SameSetTD l1 l3.
Lemma SameSetTD_SetEquiv :
forall {A : Type} {l1 l2 : list A},
SameSetTD l1 l2 -> SetEquiv l1 l2.
End SetTranspositionDedup.
Zbiory za pomocą sąsiednich transpozycji i deduplikacji
Module SetAdjacentTranspositionDedup.
Inductive AdjacentTransposition {A : Type} : list A -> list A -> Prop :=
| AdjacentTransposition' :
forall (x y : A) (l1 l2 : list A),
AdjacentTransposition (l1 ++ x :: y :: l2) (l1 ++ y :: x :: l2).
Inductive AdjacentDedup {A : Type} : list A -> list A -> Prop :=
| AdjacentDedup' :
forall (x : A) (l1 l2 : list A),
AdjacentDedup (l1 ++ x :: x :: l2) (l1 ++ x :: l2).
Inductive SameSetATD {A : Type} : list A -> list A -> Prop :=
| SameSetATD_refl :
forall l : list A, SameSetATD l l
| SameSetATD_transp :
forall l1 l2 l3 : list A,
AdjacentTransposition l1 l2 -> SameSetATD l2 l3 -> SameSetATD l1 l3
| SameSetATD_dedup :
forall l1 l2 l3 : list A,
AdjacentDedup l1 l2 -> SameSetATD l2 l3 -> SameSetATD l1 l3.
Lemma SameSetATD_trans :
forall {A : Type} {l1 l2 : list A},
SameSetATD l1 l2 ->
forall {l3 : list A}, SameSetATD l2 l3 -> SameSetATD l1 l3.
Lemma SameSetATD_SetEquiv :
forall {A : Type} {l1 l2 : list A},
SameSetATD l1 l2 -> SetEquiv l1 l2.
Lemma AdjacentDedup_cons :
forall {A : Type} {t1 t2 : list A},
AdjacentDedup t1 t2 ->
forall h : A, AdjacentDedup (h :: t1) (h :: t2).
Lemma SameSetATD_cons :
forall {A : Type} {t1 t2 : list A},
SameSetATD t1 t2 ->
forall h : A, SameSetATD (h :: t1) (h :: t2).
Lemma SetEquiv_SameSetATD :
forall {A : Type} {l1 l2 : list A},
SetEquiv l1 l2 -> SameSetATD l1 l2.
Inductive SameSetATD' {A : Type} (l1 : list A) : list A -> Prop :=
| SameSetATD'_refl :
SameSetATD' l1 l1
| SameSetATD'_transp :
forall l2 l3 : list A,
SameSetATD' l1 l2 -> AdjacentTransposition l2 l3 -> SameSetATD' l1 l3
| SameSetATD'_dedup :
forall l2 l3 : list A,
SameSetATD' l1 l2 -> AdjacentDedup l2 l3 -> SameSetATD' l1 l3.
Lemma SameSetATD'_trans :
forall {A : Type} {l1 l2 : list A},
SameSetATD' l1 l2 ->
forall {l3 : list A}, SameSetATD' l2 l3 -> SameSetATD' l1 l3.
Lemma SameSetATD'_spec :
forall {A : Type} {l1 l2 : list A},
SameSetATD' l1 l2 <-> SameSetATD l1 l2.
End SetAdjacentTranspositionDedup.