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) *)
(************************************************************************)
(*********************************************************************)
(*********************************************************************) (* Adapted in May 2006 by Jean-Marc Notin from initial contents by Laurent Théry (Huffmann contribution, October 2003) *) Require Import List Setoid Compare_dec Morphisms FinFun. Import ListNotations. (* For notations [] and [a;b;c] *) Set Implicit Arguments. (* Set Universe Polymorphism. *) Section Permutation. Variable A:Type. Inductive Permutation : list A -> list A -> Prop := | perm_nil: Permutation [] [] | perm_skip x l l' : Permutation l l' -> Permutation (x::l) (x::l') | perm_swap x y l : Permutation (y::x::l) (x::y::l) | perm_trans l l' l'' : Permutation l l' -> Permutation l' l'' -> Permutation l l''. Local Hint Constructors Permutation : core.
Some facts about Permutation
A:Typeforall l : list A, Permutation [] l -> l = []A:Typeforall l : list A, Permutation [] l -> l = []A:Typel:list AHF:Permutation [] ll = []induction HF; discriminate || auto. Qed.A:Typel, m:list AHeqm:m = []HF:Permutation m ll = []A:Typeforall (l : list A) (x : A), ~ Permutation [] (x :: l)A:Typeforall (l : list A) (x : A), ~ Permutation [] (x :: l)apply Permutation_nil in HF; discriminate. Qed.A:Typel:list Ax:AHF:Permutation [] (x :: l)False
Permutation over lists is a equivalence relation
A:Typeforall l : list A, Permutation l lA:Typeforall l : list A, Permutation l lexact IHl. Qed.A:Typea:Al:list AIHl:Permutation l lPermutation l lA:Typeforall l l' : list A, Permutation l l' -> Permutation l' lA:Typeforall l l' : list A, Permutation l l' -> Permutation l' lapply perm_trans with (l':=l'); assumption. Qed.A:Typel, l', l'':list AHperm1:Permutation l l'Hperm2:Permutation l' l''IHHperm1:Permutation l' lIHHperm2:Permutation l'' l'Permutation l'' lA:Typeforall l l' l'' : list A, Permutation l l' -> Permutation l' l'' -> Permutation l l''exact perm_trans. Qed. End Permutation. Hint Resolve Permutation_refl perm_nil perm_skip : core. (* These hints do not reduce the size of the problem to solve and they must be used with care to avoid combinatoric explosions *) Local Hint Resolve perm_swap perm_trans : core. Local Hint Resolve Permutation_sym Permutation_trans : core. (* This provides reflexivity, symmetry and transitivity and rewriting on morphims to come *) Instance Permutation_Equivalence A : Equivalence (@Permutation A) | 10 := { Equivalence_Reflexive := @Permutation_refl A ; Equivalence_Symmetric := @Permutation_sym A ; Equivalence_Transitive := @Permutation_trans A }.A:Typeforall l l' l'' : list A, Permutation l l' -> Permutation l' l'' -> Permutation l l''A:TypeProper (eq ==> Permutation (A:=A) ==> Permutation (A:=A)) consrepeat intro; subst; auto using perm_skip. Qed. Section Permutation_properties. Variable A:Type. Implicit Types a b : A. Implicit Types l m : list A.A:TypeProper (eq ==> Permutation (A:=A) ==> Permutation (A:=A)) cons
Compatibility with others operations on lists
A:Typeforall (l l' : list A) (x : A), Permutation l l' -> In x l -> In x l'intros l l' x Hperm; induction Hperm; simpl; tauto. Qed.A:Typeforall (l l' : list A) (x : A), Permutation l l' -> In x l -> In x l'A:TypeProper (eq ==> Permutation (A:=A) ==> iff) (In (A:=A))repeat red; intros; subst; eauto using Permutation_in. Qed.A:TypeProper (eq ==> Permutation (A:=A) ==> iff) (In (A:=A))A:Typeforall l l' tl : list A, Permutation l l' -> Permutation (l ++ tl) (l' ++ tl)A:Typeforall l l' tl : list A, Permutation l l' -> Permutation (l ++ tl) (l' ++ tl)eapply Permutation_trans with (l':=l'++tl); trivial. Qed.A:Typetl, l, l', l'':list AHperm1:Permutation l l'Hperm2:Permutation l' l''IHHperm1:Permutation (l ++ tl) (l' ++ tl)IHHperm2:Permutation (l' ++ tl) (l'' ++ tl)Permutation (l ++ tl) (l'' ++ tl)A:Typeforall l tl tl' : list A, Permutation tl tl' -> Permutation (l ++ tl) (l ++ tl')intros l tl tl' Hperm; induction l; [trivial | repeat rewrite <- app_comm_cons; constructor; assumption]. Qed.A:Typeforall l tl tl' : list A, Permutation tl tl' -> Permutation (l ++ tl) (l ++ tl')A:Typeforall l m l' m' : list A, Permutation l l' -> Permutation m m' -> Permutation (l ++ m) (l' ++ m')A:Typeforall l m l' m' : list A, Permutation l l' -> Permutation m m' -> Permutation (l ++ m) (l' ++ m')A:Typem, m':list Ax, y:Al:list AHpermmm':Permutation m m'Permutation (y :: x :: l ++ m) (x :: y :: l ++ m')A:Typem, m', l, l', l'':list AHpermll'1:Permutation l l'Hpermll'2:Permutation l' l''Hpermmm':Permutation m m'IHHpermll'1:Permutation (l ++ m) (l' ++ m')IHHpermll'2:Permutation (l' ++ m) (l'' ++ m')Permutation (l ++ m) (l'' ++ m')A:Typem, m', l, l', l'':list AHpermll'1:Permutation l l'Hpermll'2:Permutation l' l''Hpermmm':Permutation m m'IHHpermll'1:Permutation (l ++ m) (l' ++ m')IHHpermll'2:Permutation (l' ++ m) (l'' ++ m')Permutation (l ++ m) (l'' ++ m')apply Permutation_app_tail; assumption. Qed.A:Typem, m', l, l', l'':list AHpermll'1:Permutation l l'Hpermll'2:Permutation l' l''Hpermmm':Permutation m m'IHHpermll'1:Permutation (l ++ m) (l' ++ m')IHHpermll'2:Permutation (l' ++ m) (l'' ++ m')Permutation (l' ++ m') (l'' ++ m')A:TypeProper (Permutation (A:=A) ==> Permutation (A:=A) ==> Permutation (A:=A)) (app (A:=A))repeat intro; now apply Permutation_app. Qed.A:TypeProper (Permutation (A:=A) ==> Permutation (A:=A) ==> Permutation (A:=A)) (app (A:=A))A:Typeforall (a : A) (l l' tl tl' : list A), Permutation l l' -> Permutation tl tl' -> Permutation (l ++ a :: tl) (l' ++ a :: tl')intros; apply Permutation_app; auto. Qed.A:Typeforall (a : A) (l l' tl tl' : list A), Permutation l l' -> Permutation tl tl' -> Permutation (l ++ a :: tl) (l' ++ a :: tl')A:Typeforall (l : list A) (x : A), Permutation (x :: l) (l ++ [x])A:Typeforall (l : list A) (x : A), Permutation (x :: l) (l ++ [x])A:Typea:Al:list AIHl:forall x0 : A, Permutation (x0 :: l) (l ++ [x0])x:APermutation (x :: a :: l) ((a :: l) ++ [x])rewrite <- IHl; auto. Qed. Local Hint Resolve Permutation_cons_append : core.A:Typea:Al:list AIHl:forall x0 : A, Permutation (x0 :: l) (l ++ [x0])x:APermutation (x :: a :: l) (a :: l ++ [x])A:Typeforall l l' : list A, Permutation (l ++ l') (l' ++ l)A:Typeforall l l' : list A, Permutation (l ++ l') (l' ++ l)A:Typel':list APermutation l' (l' ++ [])A:Typex:Al:list AIHl:forall l'0 : list A, Permutation (l ++ l'0) (l'0 ++ l)l':list APermutation (x :: l ++ l') (l' ++ x :: l)A:Typex:Al:list AIHl:forall l'0 : list A, Permutation (l ++ l'0) (l'0 ++ l)l':list APermutation (x :: l ++ l') (l' ++ x :: l)A:Typex:Al:list AIHl:forall l'0 : list A, Permutation (l ++ l'0) (l'0 ++ l)l':list APermutation (x :: l' ++ l) (l' ++ x :: l)now rewrite <- app_assoc. Qed. Local Hint Resolve Permutation_app_comm : core.A:Typex:Al:list AIHl:forall l'0 : list A, Permutation (l ++ l'0) (l'0 ++ l)l':list APermutation ((l' ++ [x]) ++ l) (l' ++ x :: l)A:Typeforall (l l1 l2 : list A) (a : A), Permutation l (l1 ++ l2) -> Permutation (a :: l) (l1 ++ a :: l2)A:Typeforall (l l1 l2 : list A) (a : A), Permutation l (l1 ++ l2) -> Permutation (a :: l) (l1 ++ a :: l2)A:Typel, l1, l2:list Aa:AH:Permutation l (l1 ++ l2)Permutation (a :: l) (l1 ++ a :: l2)A:Typel, l1, l2:list Aa:AH:Permutation l (l1 ++ l2)Permutation (a :: l1 ++ l2) (l1 ++ a :: l2)now rewrite <- app_assoc. Qed. Local Hint Resolve Permutation_cons_app : core.A:Typel, l1, l2:list Aa:AH:Permutation l (l1 ++ l2)Permutation ((l1 ++ [a]) ++ l2) (l1 ++ a :: l2)A:Typea:Al, l':list AAdd a l l' -> Permutation (a :: l) l'A:Typea:Al, l':list AAdd a l l' -> Permutation (a :: l) l'A:Typea, x:Al, l':list AH:Add a l l'IHAdd:Permutation (a :: l) l'Permutation (a :: x :: l) (x :: l')now apply perm_skip. Qed.A:Typea, x:Al, l':list AH:Add a l l'IHAdd:Permutation (a :: l) l'Permutation (x :: a :: l) (x :: l')A:Typeforall (l1 l2 : list A) (a : A), Permutation (a :: l1 ++ l2) (l1 ++ a :: l2)auto. Qed. Local Hint Resolve Permutation_middle : core.A:Typeforall (l1 l2 : list A) (a : A), Permutation (a :: l1 ++ l2) (l1 ++ a :: l2)A:Typeforall l : list A, Permutation l (rev l)A:Typeforall l : list A, Permutation l (rev l)now rewrite IHl at 1. Qed.A:Typex:Al:list AIHl:Permutation l (rev l)Permutation (x :: l) (rev l ++ [x])A:TypeProper (Permutation (A:=A) ==> Permutation (A:=A)) (rev (A:=A))repeat intro; now rewrite <- 2 Permutation_rev. Qed.A:TypeProper (Permutation (A:=A) ==> Permutation (A:=A)) (rev (A:=A))A:Typeforall l l' : list A, Permutation l l' -> length l = length l'A:Typeforall l l' : list A, Permutation l l' -> length l = length l'now transitivity (length l'). Qed.A:Typel, l', l'':list AHperm1:Permutation l l'Hperm2:Permutation l' l''IHHperm1:length l = length l'IHHperm2:length l' = length l''length l = length l''A:TypeProper (Permutation (A:=A) ==> eq) (length (A:=A))exact Permutation_length. Qed.A:TypeProper (Permutation (A:=A) ==> eq) (length (A:=A))A:Typeforall P : list A -> list A -> Prop, P [] [] -> (forall (x : A) (l l' : list A), Permutation l l' -> P l l' -> P (x :: l) (x :: l')) -> (forall (x y : A) (l l' : list A), Permutation l l' -> P l l' -> P (y :: x :: l) (x :: y :: l')) -> (forall l l' l'' : list A, Permutation l l' -> P l l' -> Permutation l' l'' -> P l' l'' -> P l l'') -> forall l l' : list A, Permutation l l' -> P l l'A:Typeforall P : list A -> list A -> Prop, P [] [] -> (forall (x : A) (l l' : list A), Permutation l l' -> P l l' -> P (x :: l) (x :: l')) -> (forall (x y : A) (l l' : list A), Permutation l l' -> P l l' -> P (y :: x :: l) (x :: y :: l')) -> (forall l l' l'' : list A, Permutation l l' -> P l l' -> Permutation l' l'' -> P l' l'' -> P l l'') -> forall l l' : list A, Permutation l l' -> P l l'A:TypeP:list A -> list A -> PropHnil:P [] []Hskip:forall (x : A) (l l' : list A), Permutation l l' -> P l l' -> P (x :: l) (x :: l')Hswap:forall (x y : A) (l l' : list A), Permutation l l' -> P l l' -> P (y :: x :: l) (x :: y :: l')Htrans:forall l l' l'' : list A, Permutation l l' -> P l l' -> Permutation l' l'' -> P l' l'' -> P l l''forall l l' : list A, Permutation l l' -> P l l'A:TypeP:list A -> list A -> PropHnil:P [] []Hskip:forall (x0 : A) (l0 l' : list A), Permutation l0 l' -> P l0 l' -> P (x0 :: l0) (x0 :: l')Hswap:forall (x0 y0 : A) (l0 l' : list A), Permutation l0 l' -> P l0 l' -> P (y0 :: x0 :: l0) (x0 :: y0 :: l')Htrans:forall l0 l' l'' : list A, Permutation l0 l' -> P l0 l' -> Permutation l' l'' -> P l' l'' -> P l0 l''x, y:Al:list AP (y :: x :: l) (x :: y :: l)A:TypeP:list A -> list A -> PropHnil:P [] []Hskip:forall (x : A) (l0 l'0 : list A), Permutation l0 l'0 -> P l0 l'0 -> P (x :: l0) (x :: l'0)Hswap:forall (x y : A) (l0 l'0 : list A), Permutation l0 l'0 -> P l0 l'0 -> P (y :: x :: l0) (x :: y :: l'0)Htrans:forall l0 l'0 l''0 : list A, Permutation l0 l'0 -> P l0 l'0 -> Permutation l'0 l''0 -> P l'0 l''0 -> P l0 l''0l, l', l'':list AH:Permutation l l'H0:Permutation l' l''IHPermutation1:P l l'IHPermutation2:P l' l''P l l''A:TypeP:list A -> list A -> PropHnil:P [] []Hskip:forall (x0 : A) (l0 l' : list A), Permutation l0 l' -> P l0 l' -> P (x0 :: l0) (x0 :: l')Hswap:forall (x0 y0 : A) (l0 l' : list A), Permutation l0 l' -> P l0 l' -> P (y0 :: x0 :: l0) (x0 :: y0 :: l')Htrans:forall l0 l' l'' : list A, Permutation l0 l' -> P l0 l' -> Permutation l' l'' -> P l' l'' -> P l0 l''x, y:Al:list AP (y :: x :: l) (x :: y :: l)A:TypeP:list A -> list A -> PropHnil:P [] []Hskip:forall (x0 : A) (l0 l' : list A), Permutation l0 l' -> P l0 l' -> P (x0 :: l0) (x0 :: l')Hswap:forall (x0 y0 : A) (l0 l' : list A), Permutation l0 l' -> P l0 l' -> P (y0 :: x0 :: l0) (x0 :: y0 :: l')Htrans:forall l0 l' l'' : list A, Permutation l0 l' -> P l0 l' -> Permutation l' l'' -> P l' l'' -> P l0 l''x, y:Al:list AP (x :: y :: l) (x :: y :: l)A:TypeP:list A -> list A -> PropHnil:P [] []Hskip:forall (x : A) (l0 l'0 : list A), Permutation l0 l'0 -> P l0 l'0 -> P (x :: l0) (x :: l'0)Hswap:forall (x y : A) (l0 l'0 : list A), Permutation l0 l'0 -> P l0 l'0 -> P (y :: x :: l0) (x :: y :: l'0)Htrans:forall l0 l'0 l''0 : list A, Permutation l0 l'0 -> P l0 l'0 -> Permutation l'0 l''0 -> P l'0 l''0 -> P l0 l''0l, l', l'':list AH:Permutation l l'H0:Permutation l' l''IHPermutation1:P l l'IHPermutation2:P l' l''P l l''A:TypeP:list A -> list A -> PropHnil:P [] []Hskip:forall (x0 : A) (l0 l' : list A), Permutation l0 l' -> P l0 l' -> P (x0 :: l0) (x0 :: l')Hswap:forall (x0 y0 : A) (l0 l' : list A), Permutation l0 l' -> P l0 l' -> P (y0 :: x0 :: l0) (x0 :: y0 :: l')Htrans:forall l0 l' l'' : list A, Permutation l0 l' -> P l0 l' -> Permutation l' l'' -> P l' l'' -> P l0 l''x, y:Al:list AP l lA:TypeP:list A -> list A -> PropHnil:P [] []Hskip:forall (x0 : A) (l0 l' : list A), Permutation l0 l' -> P l0 l' -> P (x0 :: l0) (x0 :: l')Hswap:forall (x0 y0 : A) (l0 l' : list A), Permutation l0 l' -> P l0 l' -> P (y0 :: x0 :: l0) (x0 :: y0 :: l')Htrans:forall l0 l' l'' : list A, Permutation l0 l' -> P l0 l' -> Permutation l' l'' -> P l' l'' -> P l0 l''x, y:Al:list AP (x :: y :: l) (x :: y :: l)A:TypeP:list A -> list A -> PropHnil:P [] []Hskip:forall (x : A) (l0 l'0 : list A), Permutation l0 l'0 -> P l0 l'0 -> P (x :: l0) (x :: l'0)Hswap:forall (x y : A) (l0 l'0 : list A), Permutation l0 l'0 -> P l0 l'0 -> P (y :: x :: l0) (x :: y :: l'0)Htrans:forall l0 l'0 l''0 : list A, Permutation l0 l'0 -> P l0 l'0 -> Permutation l'0 l''0 -> P l'0 l''0 -> P l0 l''0l, l', l'':list AH:Permutation l l'H0:Permutation l' l''IHPermutation1:P l l'IHPermutation2:P l' l''P l l''A:TypeP:list A -> list A -> PropHnil:P [] []Hskip:forall (x0 : A) (l0 l' : list A), Permutation l0 l' -> P l0 l' -> P (x0 :: l0) (x0 :: l')Hswap:forall (x0 y0 : A) (l0 l' : list A), Permutation l0 l' -> P l0 l' -> P (y0 :: x0 :: l0) (x0 :: y0 :: l')Htrans:forall l0 l' l'' : list A, Permutation l0 l' -> P l0 l' -> Permutation l' l'' -> P l' l'' -> P l0 l''x, y:Al:list AP (x :: y :: l) (x :: y :: l)A:TypeP:list A -> list A -> PropHnil:P [] []Hskip:forall (x : A) (l0 l'0 : list A), Permutation l0 l'0 -> P l0 l'0 -> P (x :: l0) (x :: l'0)Hswap:forall (x y : A) (l0 l'0 : list A), Permutation l0 l'0 -> P l0 l'0 -> P (y :: x :: l0) (x :: y :: l'0)Htrans:forall l0 l'0 l''0 : list A, Permutation l0 l'0 -> P l0 l'0 -> Permutation l'0 l''0 -> P l'0 l''0 -> P l0 l''0l, l', l'':list AH:Permutation l l'H0:Permutation l' l''IHPermutation1:P l l'IHPermutation2:P l' l''P l l''A:TypeP:list A -> list A -> PropHnil:P [] []Hskip:forall (x0 : A) (l0 l' : list A), Permutation l0 l' -> P l0 l' -> P (x0 :: l0) (x0 :: l')Hswap:forall (x0 y0 : A) (l0 l' : list A), Permutation l0 l' -> P l0 l' -> P (y0 :: x0 :: l0) (x0 :: y0 :: l')Htrans:forall l0 l' l'' : list A, Permutation l0 l' -> P l0 l' -> Permutation l' l'' -> P l' l'' -> P l0 l''x, y:Al:list AP (y :: l) (y :: l)A:TypeP:list A -> list A -> PropHnil:P [] []Hskip:forall (x : A) (l0 l'0 : list A), Permutation l0 l'0 -> P l0 l'0 -> P (x :: l0) (x :: l'0)Hswap:forall (x y : A) (l0 l'0 : list A), Permutation l0 l'0 -> P l0 l'0 -> P (y :: x :: l0) (x :: y :: l'0)Htrans:forall l0 l'0 l''0 : list A, Permutation l0 l'0 -> P l0 l'0 -> Permutation l'0 l''0 -> P l'0 l''0 -> P l0 l''0l, l', l'':list AH:Permutation l l'H0:Permutation l' l''IHPermutation1:P l l'IHPermutation2:P l' l''P l l''A:TypeP:list A -> list A -> PropHnil:P [] []Hskip:forall (x0 : A) (l0 l' : list A), Permutation l0 l' -> P l0 l' -> P (x0 :: l0) (x0 :: l')Hswap:forall (x0 y0 : A) (l0 l' : list A), Permutation l0 l' -> P l0 l' -> P (y0 :: x0 :: l0) (x0 :: y0 :: l')Htrans:forall l0 l' l'' : list A, Permutation l0 l' -> P l0 l' -> Permutation l' l'' -> P l' l'' -> P l0 l''x, y:Al:list AP l lA:TypeP:list A -> list A -> PropHnil:P [] []Hskip:forall (x : A) (l0 l'0 : list A), Permutation l0 l'0 -> P l0 l'0 -> P (x :: l0) (x :: l'0)Hswap:forall (x y : A) (l0 l'0 : list A), Permutation l0 l'0 -> P l0 l'0 -> P (y :: x :: l0) (x :: y :: l'0)Htrans:forall l0 l'0 l''0 : list A, Permutation l0 l'0 -> P l0 l'0 -> Permutation l'0 l''0 -> P l'0 l''0 -> P l0 l''0l, l', l'':list AH:Permutation l l'H0:Permutation l' l''IHPermutation1:P l l'IHPermutation2:P l' l''P l l''eauto. Qed.A:TypeP:list A -> list A -> PropHnil:P [] []Hskip:forall (x : A) (l0 l'0 : list A), Permutation l0 l'0 -> P l0 l'0 -> P (x :: l0) (x :: l'0)Hswap:forall (x y : A) (l0 l'0 : list A), Permutation l0 l'0 -> P l0 l'0 -> P (y :: x :: l0) (x :: y :: l'0)Htrans:forall l0 l'0 l''0 : list A, Permutation l0 l'0 -> P l0 l'0 -> Permutation l'0 l''0 -> P l'0 l''0 -> P l0 l''0l, l', l'':list AH:Permutation l l'H0:Permutation l' l''IHPermutation1:P l l'IHPermutation2:P l' l''P l l''A:Typeforall (l l' : list A) (x : A), ~ Permutation [] (l ++ x :: l')A:Typeforall (l l' : list A) (x : A), ~ Permutation [] (l ++ x :: l')A:Typel, l':list Ax:AHF:Permutation [] (l ++ x :: l')Falsedestruct l; discriminate. Qed. Ltac InvAdd := repeat (match goal with | H: Add ?x _ (_ :: _) |- _ => inversion H; clear H; subst end). Ltac finish_basic_perms H := try constructor; try rewrite perm_swap; try constructor; trivial; (rewrite <- H; now apply Permutation_Add) || (rewrite H; symmetry; now apply Permutation_Add).A:Typel, l':list Ax:AHF:l ++ x :: l' = []FalseA:Typea:Al1, l2:list APermutation l1 l2 -> forall l1' l2' : list A, Add a l1' l1 -> Add a l2' l2 -> Permutation l1' l2'A:Typea:Al1, l2:list APermutation l1 l2 -> forall l1' l2' : list A, Add a l1' l1 -> Add a l2' l2 -> Permutation l1' l2'A:Typea:Aforall l1 l2 : list A, Permutation l1 l2 -> forall l1' l2' : list A, Add a l1' l1 -> Add a l2' l2 -> Permutation l1' l2'A:Typea:Aforall l1' l2' : list A, Add a l1' [] -> Add a l2' [] -> Permutation l1' l2'A:Typea:Aforall (x : A) (l l' : list A), Permutation l l' -> (forall l1' l2' : list A, Add a l1' l -> Add a l2' l' -> Permutation l1' l2') -> forall l1' l2' : list A, Add a l1' (x :: l) -> Add a l2' (x :: l') -> Permutation l1' l2'A:Typea:Aforall (x y : A) (l l' : list A), Permutation l l' -> (forall l1' l2' : list A, Add a l1' l -> Add a l2' l' -> Permutation l1' l2') -> forall l1' l2' : list A, Add a l1' (y :: x :: l) -> Add a l2' (x :: y :: l') -> Permutation l1' l2'A:Typea:Aforall l l' l'' : list A, Permutation l l' -> (forall l1' l2' : list A, Add a l1' l -> Add a l2' l' -> Permutation l1' l2') -> Permutation l' l'' -> (forall l1' l2' : list A, Add a l1' l' -> Add a l2' l'' -> Permutation l1' l2') -> forall l1' l2' : list A, Add a l1' l -> Add a l2' l'' -> Permutation l1' l2'inversion_clear 1.A:Typea:Aforall l1' l2' : list A, Add a l1' [] -> Add a l2' [] -> Permutation l1' l2'A:Typea:Aforall (x : A) (l l' : list A), Permutation l l' -> (forall l1' l2' : list A, Add a l1' l -> Add a l2' l' -> Permutation l1' l2') -> forall l1' l2' : list A, Add a l1' (x :: l) -> Add a l2' (x :: l') -> Permutation l1' l2'A:Typea, x:Al1, l2:list APE:Permutation l1 l2IH:forall l1' l2' : list A, Add a l1' l1 -> Add a l2' l2 -> Permutation l1' l2'forall l1' l2' : list A, Add a l1' (x :: l1) -> Add a l2' (x :: l2) -> Permutation l1' l2'A:Typea, x:Al1, l2:list APE:Permutation l1 l2IH:forall l1'0 l2'0 : list A, Add a l1'0 l1 -> Add a l2'0 l2 -> Permutation l1'0 l2'0l1', l2':list AH:Add a l1' (x :: l1)H0:Add a l2' (x :: l2)Permutation l1' l2'A:Typea, x:Al1, l2:list APE:Permutation l1 l2IH:forall l1' l2' : list A, Add a l1' l1 -> Add a l2' l2 -> Permutation l1' l2'l:list AH3:Add a l l2l0:list AH2:Add a l0 l1Permutation (x :: l0) (x :: l)now apply IH.A:Typea, x:Al1, l2:list APE:Permutation l1 l2IH:forall l1' l2' : list A, Add a l1' l1 -> Add a l2' l2 -> Permutation l1' l2'l:list AH3:Add a l l2l0:list AH2:Add a l0 l1Permutation l0 lA:Typea:Aforall (x y : A) (l l' : list A), Permutation l l' -> (forall l1' l2' : list A, Add a l1' l -> Add a l2' l' -> Permutation l1' l2') -> forall l1' l2' : list A, Add a l1' (y :: x :: l) -> Add a l2' (x :: y :: l') -> Permutation l1' l2'A:Typea, x, y:Al1, l2:list APE:Permutation l1 l2IH:forall l1' l2' : list A, Add a l1' l1 -> Add a l2' l2 -> Permutation l1' l2'forall l1' l2' : list A, Add a l1' (y :: x :: l1) -> Add a l2' (x :: y :: l2) -> Permutation l1' l2'A:Typea, x, y:Al1, l2:list APE:Permutation l1 l2IH:forall l1'0 l2'0 : list A, Add a l1'0 l1 -> Add a l2'0 l2 -> Permutation l1'0 l2'0l1', l2':list AH:Add a l1' (y :: x :: l1)H0:Add a l2' (x :: y :: l2)Permutation l1' l2'A:Typea, x, y:Al1, l2:list APE:Permutation l1 l2IH:forall l1' l2' : list A, Add a l1' l1 -> Add a l2' l2 -> Permutation l1' l2'l0:list AH2:Add a l0 l2l3:list AH1:Add a l3 l1Permutation (y :: x :: l3) (x :: y :: l0)now apply IH.A:Typea, x, y:Al1, l2:list APE:Permutation l1 l2IH:forall l1' l2' : list A, Add a l1' l1 -> Add a l2' l2 -> Permutation l1' l2'l0:list AH2:Add a l0 l2l3:list AH1:Add a l3 l1Permutation l3 l0A:Typea:Aforall l l' l'' : list A, Permutation l l' -> (forall l1' l2' : list A, Add a l1' l -> Add a l2' l' -> Permutation l1' l2') -> Permutation l' l'' -> (forall l1' l2' : list A, Add a l1' l' -> Add a l2' l'' -> Permutation l1' l2') -> forall l1' l2' : list A, Add a l1' l -> Add a l2' l'' -> Permutation l1' l2'A:Typea:Al1, l, l2:list APE:Permutation l1 lIH:forall l1'0 l2'0 : list A, Add a l1'0 l1 -> Add a l2'0 l -> Permutation l1'0 l2'0PE':Permutation l l2IH':forall l1'0 l2'0 : list A, Add a l1'0 l -> Add a l2'0 l2 -> Permutation l1'0 l2'0l1', l2':list AAD1:Add a l1' l1AD2:Add a l2' l2Permutation l1' l2'A:Typea:Al1, l, l2:list APE:Permutation l1 lIH:forall l1'0 l2'0 : list A, Add a l1'0 l1 -> Add a l2'0 l -> Permutation l1'0 l2'0PE':Permutation l l2IH':forall l1'0 l2'0 : list A, Add a l1'0 l -> Add a l2'0 l2 -> Permutation l1'0 l2'0l1', l2':list AAD1:Add a l1' l1AD2:Add a l2' l2In a lA:Typea:Al1, l, l2:list APE:Permutation l1 lIH:forall l1'0 l2'0 : list A, Add a l1'0 l1 -> Add a l2'0 l -> Permutation l1'0 l2'0PE':Permutation l l2IH':forall l1'0 l2'0 : list A, Add a l1'0 l -> Add a l2'0 l2 -> Permutation l1'0 l2'0l1', l2':list AAD1:Add a l1' l1AD2:Add a l2' l2Ha:In a lPermutation l1' l2'A:Typea:Al1, l, l2:list APE:Permutation l1 lIH:forall l1'0 l2'0 : list A, Add a l1'0 l1 -> Add a l2'0 l -> Permutation l1'0 l2'0PE':Permutation l l2IH':forall l1'0 l2'0 : list A, Add a l1'0 l -> Add a l2'0 l2 -> Permutation l1'0 l2'0l1', l2':list AAD1:Add a l1' l1AD2:Add a l2' l2In a lA:Typea:Al1, l, l2:list APE:Permutation l1 lIH:forall l1'0 l2'0 : list A, Add a l1'0 l1 -> Add a l2'0 l -> Permutation l1'0 l2'0PE':Permutation l l2IH':forall l1'0 l2'0 : list A, Add a l1'0 l -> Add a l2'0 l2 -> Permutation l1'0 l2'0l1', l2':list AAD1:Add a l1' l1AD2:Add a l2' l2In a l1simpl; auto.A:Typea:Al1, l, l2:list APE:Permutation l1 lIH:forall l1'0 l2'0 : list A, Add a l1'0 l1 -> Add a l2'0 l -> Permutation l1'0 l2'0PE':Permutation l l2IH':forall l1'0 l2'0 : list A, Add a l1'0 l -> Add a l2'0 l2 -> Permutation l1'0 l2'0l1', l2':list AAD1:Add a l1' l1AD2:Add a l2' l2In a (a :: l1')A:Typea:Al1, l, l2:list APE:Permutation l1 lIH:forall l1'0 l2'0 : list A, Add a l1'0 l1 -> Add a l2'0 l -> Permutation l1'0 l2'0PE':Permutation l l2IH':forall l1'0 l2'0 : list A, Add a l1'0 l -> Add a l2'0 l2 -> Permutation l1'0 l2'0l1', l2':list AAD1:Add a l1' l1AD2:Add a l2' l2Ha:In a lPermutation l1' l2'transitivity l'; auto. Qed.A:Typea:Al1, l, l2:list APE:Permutation l1 lIH:forall l1'0 l2'0 : list A, Add a l1'0 l1 -> Add a l2'0 l -> Permutation l1'0 l2'0PE':Permutation l l2IH':forall l1'0 l2'0 : list A, Add a l1'0 l -> Add a l2'0 l2 -> Permutation l1'0 l2'0l1', l2':list AAD1:Add a l1' l1AD2:Add a l2' l2Ha:In a ll':list AAD:Add a l' lPermutation l1' l2'A:Typel1, l2, l3, l4:list Aa:APermutation (l1 ++ a :: l2) (l3 ++ a :: l4) -> Permutation (l1 ++ l2) (l3 ++ l4)A:Typel1, l2, l3, l4:list Aa:APermutation (l1 ++ a :: l2) (l3 ++ a :: l4) -> Permutation (l1 ++ l2) (l3 ++ l4)eapply Permutation_Add_inv; eauto using Add_app. Qed.A:Typel1, l2, l3, l4:list Aa:AH:Permutation (l1 ++ a :: l2) (l3 ++ a :: l4)Permutation (l1 ++ l2) (l3 ++ l4)A:Typel, l':list Aa:APermutation (a :: l) (a :: l') -> Permutation l l'A:Typel, l':list Aa:APermutation (a :: l) (a :: l') -> Permutation l l'eapply Permutation_Add_inv; eauto using Add_head. Qed.A:Typel, l':list Aa:AH:Permutation (a :: l) (a :: l')Permutation l l'A:Typel, l1, l2:list Aa:APermutation (a :: l) (l1 ++ a :: l2) -> Permutation l (l1 ++ l2)A:Typel, l1, l2:list Aa:APermutation (a :: l) (l1 ++ a :: l2) -> Permutation l (l1 ++ l2)eapply Permutation_Add_inv; eauto using Add_head, Add_app. Qed.A:Typel, l1, l2:list Aa:AH:Permutation (a :: l) (l1 ++ a :: l2)Permutation l (l1 ++ l2)A:Typeforall l l1 l2 : list A, Permutation (l ++ l1) (l ++ l2) -> Permutation l1 l2A:Typeforall l l1 l2 : list A, Permutation (l ++ l1) (l ++ l2) -> Permutation l1 l2A:Typea:Al:list AIHl:forall l1 l2 : list A, Permutation (l ++ l1) (l ++ l2) -> Permutation l1 l2forall l1 l2 : list A, Permutation (a :: l ++ l1) (a :: l ++ l2) -> Permutation l1 l2A:Typea:Al:list AIHl:forall l0 l3 : list A, Permutation (l ++ l0) (l ++ l3) -> Permutation l0 l3l1, l2:list AH:Permutation (a :: l ++ l1) (a :: l ++ l2)Permutation l1 l2apply Permutation_cons_inv with a; auto. Qed.A:Typea:Al:list AIHl:forall l0 l3 : list A, Permutation (l ++ l0) (l ++ l3) -> Permutation l0 l3l1, l2:list AH:Permutation (a :: l ++ l1) (a :: l ++ l2)Permutation (l ++ l1) (l ++ l2)A:Typel, l1, l2:list APermutation (l1 ++ l) (l2 ++ l) -> Permutation l1 l2A:Typel, l1, l2:list APermutation (l1 ++ l) (l2 ++ l) -> Permutation l1 l2apply Permutation_app_inv_l. Qed.A:Typel, l1, l2:list APermutation (l ++ l1) (l ++ l2) -> Permutation l1 l2A:Typeforall (a : A) (l : list A), Permutation [a] l -> l = [a]A:Typeforall (a : A) (l : list A), Permutation [a] l -> l = [a]A:Typea:Al, m:list AHeqm:m = [a]H:Permutation m ll = [a]apply Permutation_nil in H as ->; trivial. Qed.A:Typea:Al':list AIHPermutation:[] = [a] -> l' = [a]H:Permutation [] l'a :: l' = [a]A:Typeforall a b : A, Permutation [a] [b] -> a = bA:Typeforall a b : A, Permutation [a] [b] -> a = bapply Permutation_length_1_inv in H; injection H as ->; trivial. Qed.A:Typea, b:AH:Permutation [a] [b]a = bA:Typeforall (a1 a2 : A) (l : list A), Permutation [a1; a2] l -> l = [a1; a2] \/ l = [a2; a1]A:Typeforall (a1 a2 : A) (l : list A), Permutation [a1; a2] l -> l = [a1; a2] \/ l = [a2; a1]A:Typea1, a2:Al, m:list AHeqm:m = [a1; a2]H:Permutation m ll = [a1; a2] \/ l = [a2; a1]A:Typel, m:list AH:Permutation m lforall a1 a2 : A, m = [a1; a2] -> l = [a1; a2] \/ l = [a2; a1]A:Typel':list Aa2:AIHPermutation:forall a0 a3 : A, [a2] = [a0; a3] -> l' = [a0; a3] \/ l' = [a3; a0]H:Permutation [a2] l'a1:Aa1 :: l' = [a1; a2] \/ a1 :: l' = [a2; a1]A:Typel, l', l'':list AH:Permutation l l'H0:Permutation l' l''IHPermutation1:forall a0 a3 : A, l = [a0; a3] -> l' = [a0; a3] \/ l' = [a3; a0]IHPermutation2:forall a0 a3 : A, l' = [a0; a3] -> l'' = [a0; a3] \/ l'' = [a3; a0]a1, a2:AHeqm:l = [a1; a2]l'' = [a1; a2] \/ l'' = [a2; a1]apply IHPermutation1 in Heqm as [H1|H1]; apply IHPermutation2 in H1 as []; auto. Qed.A:Typel, l', l'':list AH:Permutation l l'H0:Permutation l' l''IHPermutation1:forall a0 a3 : A, l = [a0; a3] -> l' = [a0; a3] \/ l' = [a3; a0]IHPermutation2:forall a0 a3 : A, l' = [a0; a3] -> l'' = [a0; a3] \/ l'' = [a3; a0]a1, a2:AHeqm:l = [a1; a2]l'' = [a1; a2] \/ l'' = [a2; a1]A:Typeforall a1 a2 b1 b2 : A, Permutation [a1; a2] [b1; b2] -> a1 = b1 /\ a2 = b2 \/ a1 = b2 /\ a2 = b1A:Typeforall a1 a2 b1 b2 : A, Permutation [a1; a2] [b1; b2] -> a1 = b1 /\ a2 = b2 \/ a1 = b2 /\ a2 = b1apply Permutation_length_2_inv in H as [H|H]; injection H as -> ->; auto. Qed.A:Typea1, b1, a2, b2:AH:Permutation [a1; b1] [a2; b2]a1 = a2 /\ b1 = b2 \/ a1 = b2 /\ b1 = a2A:Typel, l':list ANoDup l -> NoDup l' -> (forall x : A, In x l <-> In x l') -> Permutation l l'A:Typel, l':list ANoDup l -> NoDup l' -> (forall x : A, In x l <-> In x l') -> Permutation l l'A:Typel, l':list AN:NoDup lNoDup l' -> (forall x : A, In x l <-> In x l') -> Permutation l l'A:Typel:list AN:NoDup lforall l' : list A, NoDup l' -> (forall x : A, In x l <-> In x l') -> Permutation l l'A:Typeforall l' : list A, NoDup l' -> (forall x : A, In x [] <-> In x l') -> Permutation [] l'A:Typea:Al:list AHal:~ In a lHl:NoDup lIH:forall l' : list A, NoDup l' -> (forall x : A, In x l <-> In x l') -> Permutation l l'forall l' : list A, NoDup l' -> (forall x : A, In x (a :: l) <-> In x l') -> Permutation (a :: l) l'A:Typeforall l' : list A, NoDup l' -> (forall x : A, In x [] <-> In x l') -> Permutation [] l'A:Typea:Al':list ANoDup (a :: l') -> (forall x : A, False <-> a = x \/ In x l') -> Permutation [] (a :: l')A:Typea:Al':list AHl':NoDup (a :: l')H:forall x : A, False <-> a = x \/ In x l'Permutation [] (a :: l')rewrite (H a); auto.A:Typea:Al':list AHl':NoDup (a :: l')H:forall x : A, False <-> a = x \/ In x l'FalseA:Typea:Al:list AHal:~ In a lHl:NoDup lIH:forall l' : list A, NoDup l' -> (forall x : A, In x l <-> In x l') -> Permutation l l'forall l' : list A, NoDup l' -> (forall x : A, In x (a :: l) <-> In x l') -> Permutation (a :: l) l'A:Typea:Al:list AHal:~ In a lHl:NoDup lIH:forall l'0 : list A, NoDup l'0 -> (forall x : A, In x l <-> In x l'0) -> Permutation l l'0l':list AHl':NoDup l'H:forall x : A, In x (a :: l) <-> In x l'Permutation (a :: l) l'A:Typea:Al:list AHal:~ In a lHl:NoDup lIH:forall l'0 : list A, NoDup l'0 -> (forall x : A, In x l <-> In x l'0) -> Permutation l l'0l':list AHl':NoDup l'H:forall x : A, In x (a :: l) <-> In x l'Ha:In a l'Permutation (a :: l) l'A:Typea:Al:list AHal:~ In a lHl:NoDup lIH:forall l'0 : list A, NoDup l'0 -> (forall x : A, In x l <-> In x l'0) -> Permutation l l'0l':list AHl':NoDup l'H:forall x : A, In x (a :: l) <-> In x l'Ha:In a l'l'':list AAD:Add a l'' l'Permutation (a :: l) l'A:Typea:Al:list AHal:~ In a lHl:NoDup lIH:forall l'0 : list A, NoDup l'0 -> (forall x : A, In x l <-> In x l'0) -> Permutation l l'0l':list AHl':NoDup l'H:forall x : A, In x (a :: l) <-> In x l'Ha:In a l'l'':list AAD:Add a l'' l'Permutation (a :: l) (a :: l'')A:Typea:Al:list AHal:~ In a lHl:NoDup lIH:forall l'0 : list A, NoDup l'0 -> (forall x : A, In x l <-> In x l'0) -> Permutation l l'0l':list AHl':NoDup l'H:forall x : A, In x (a :: l) <-> In x l'Ha:In a l'l'':list AAD:Add a l'' l'Permutation l l''A:Typea:Al:list AHal:~ In a lHl:NoDup ll':list AHl':NoDup l'H:forall x : A, In x (a :: l) <-> In x l'Ha:In a l'l'':list AAD:Add a l'' l'NoDup l''A:Typea:Al:list AHal:~ In a lHl:NoDup ll':list AHl':NoDup l'H:forall x : A, In x (a :: l) <-> In x l'Ha:In a l'l'':list AAD:Add a l'' l'forall x : A, In x l <-> In x l''now apply (NoDup_Add AD).A:Typea:Al:list AHal:~ In a lHl:NoDup ll':list AHl':NoDup l'H:forall x : A, In x (a :: l) <-> In x l'Ha:In a l'l'':list AAD:Add a l'' l'NoDup l''A:Typea:Al:list AHal:~ In a lHl:NoDup ll':list AHl':NoDup l'H:forall x : A, In x (a :: l) <-> In x l'Ha:In a l'l'':list AAD:Add a l'' l'forall x : A, In x l <-> In x l''A:Typea:Al:list AHal:~ In a lHl:NoDup ll':list AHl':NoDup l'H:forall x0 : A, In x0 (a :: l) <-> In x0 l'Ha:In a l'l'':list AAD:Add a l'' l'x:AIn x l -> In x l''A:Typea:Al:list AHal:~ In a lHl:NoDup ll':list AHl':NoDup l'H:forall x0 : A, In x0 (a :: l) <-> In x0 l'Ha:In a l'l'':list AAD:Add a l'' l'x:AIn x l'' -> In x lA:Typea:Al:list AHal:~ In a lHl:NoDup ll':list AHl':NoDup l'H:forall x0 : A, In x0 (a :: l) <-> In x0 l'Ha:In a l'l'':list AAD:Add a l'' l'x:AIn x l -> In x l''A:Typea:Al:list AHal:~ In a lHl:NoDup ll':list AHl':NoDup l'H:forall x0 : A, In x0 (a :: l) <-> In x0 l'Ha:In a l'l'':list AAD:Add a l'' l'x:Aincl (a :: l) l'apply H.A:Typea:Al:list AHal:~ In a lHl:NoDup ll':list AHl':NoDup l'H:forall x0 : A, In x0 (a :: l) <-> In x0 l'Ha:In a l'l'':list AAD:Add a l'' l'x, a0:AIn a0 (a :: l) -> In a0 l'A:Typea:Al:list AHal:~ In a lHl:NoDup ll':list AHl':NoDup l'H:forall x0 : A, In x0 (a :: l) <-> In x0 l'Ha:In a l'l'':list AAD:Add a l'' l'x:AIn x l'' -> In x lA:Typea:Al:list AHal:~ In a lHl:NoDup ll':list AHl':NoDup l'H:forall x0 : A, In x0 (a :: l) <-> In x0 l'Ha:In a l'l'':list AAD:Add a l'' l'x:AHx:In x l''In x lA:Typea:Al:list AHal:~ In a lHl:NoDup ll':list AHl':NoDup l'H:forall x0 : A, In x0 (a :: l) <-> In x0 l'Ha:In a l'l'':list AAD:Add a l'' l'x:AHx:In x l''In x (a :: l)A:Typea:Al:list AHal:~ In a lHl:NoDup ll':list AHl':NoDup l'H:forall x0 : A, In x0 (a :: l) <-> In x0 l'Ha:In a l'l'':list AAD:Add a l'' l'x:AHx:In x l''Hx':In x (a :: l)In x lA:Typea:Al:list AHal:~ In a lHl:NoDup ll':list AHl':NoDup l'H:forall x0 : A, In x0 (a :: l) <-> In x0 l'Ha:In a l'l'':list AAD:Add a l'' l'x:AHx:In x l''In x (a :: l)A:Typea:Al:list AHal:~ In a lHl:NoDup ll':list AHl':NoDup l'H:forall x0 : A, In x0 (a :: l) <-> In x0 l'Ha:In a l'l'':list AAD:Add a l'' l'x:AHx:In x l''In x l'now right.A:Typea:Al:list AHal:~ In a lHl:NoDup ll':list AHl':NoDup l'H:forall x0 : A, In x0 (a :: l) <-> In x0 l'Ha:In a l'l'':list AAD:Add a l'' l'x:AHx:In x l''In x (a :: l'')A:Typea:Al:list AHal:~ In a lHl:NoDup ll':list AHl':NoDup l'H:forall x0 : A, In x0 (a :: l) <-> In x0 l'Ha:In a l'l'':list AAD:Add a l'' l'x:AHx:In x l''Hx':In x (a :: l)In x lA:Typea:Al:list AHal:~ In a lHl:NoDup ll':list AHl':NoDup l'H:forall x0 : A, In x0 (a :: l) <-> In x0 l'Ha:In a l'l'':list AAD:Add a l'' l'x:AHx:In x l''H0:a = xIn x lA:Typel:list Ax:AHal:~ In x lHl:NoDup ll':list AHl':NoDup l'Ha:In x l'H:forall x0 : A, In x0 (x :: l) <-> In x0 l'l'':list AAD:Add x l'' l'Hx:In x l''In x ltauto. Qed.A:Typel:list Ax:AHal:~ In x lHl:NoDup ll':list AHa:In x l'H:forall x0 : A, In x0 (x :: l) <-> In x0 l'l'':list AHl':NoDup l'' /\ ~ In x l''AD:Add x l'' l'Hx:In x l''In x lA:Typel, l':list ANoDup l -> NoDup l' -> length l' <= length l -> incl l l' -> Permutation l l'A:Typel, l':list ANoDup l -> NoDup l' -> length l' <= length l -> incl l l' -> Permutation l l'A:Typel, l':list AH:NoDup lH0:NoDup l'H1:length l' <= length lH2:incl l l'Permutation l l'A:Typel, l':list AH:NoDup lH0:NoDup l'H1:length l' <= length lH2:incl l l'forall x : A, In x l <-> In x l'apply NoDup_length_incl; trivial. Qed.A:Typel, l':list AH:NoDup lH0:NoDup l'H1:length l' <= length lH2:incl l l'x:AIn x l' -> In x lA:Typel, l':list APermutation l l' -> NoDup l -> NoDup l'A:Typel, l':list APermutation l l' -> NoDup l -> NoDup l'A:Typex:Al, l':list AH:Permutation l l'IHPermutation:NoDup l -> NoDup l'NoDup (x :: l) -> NoDup (x :: l')A:Typex, y:Al:list ANoDup (y :: x :: l) -> NoDup (x :: y :: l)inversion_clear 1; constructor; eauto using Permutation_in.A:Typex:Al, l':list AH:Permutation l l'IHPermutation:NoDup l -> NoDup l'NoDup (x :: l) -> NoDup (x :: l')A:Typex, y:Al:list ANoDup (y :: x :: l) -> NoDup (x :: y :: l)A:Typex, y:Al:list AH1:~ In y (x :: l)H2:NoDup (x :: l)NoDup (x :: y :: l)A:Typex, y:Al:list AH1:~ (x = y \/ In y l)H:~ In x lH0:NoDup lNoDup (x :: y :: l)A:Typex, y:Al:list AH1:~ (x = y \/ In y l)H:~ In x lH0:NoDup l~ In x (y :: l)A:Typex, y:Al:list AH1:~ (x = y \/ In y l)H:~ In x lH0:NoDup lNoDup (y :: l)constructor; intuition. Qed.A:Typex, y:Al:list AH1:~ (x = y \/ In y l)H:~ In x lH0:NoDup lNoDup (y :: l)A:TypeProper (Permutation (A:=A) ==> iff) (NoDup (A:=A))repeat red; eauto using Permutation_NoDup. Qed. End Permutation_properties. Section Permutation_map. Variable A B : Type. Variable f : A -> B.A:TypeProper (Permutation (A:=A) ==> iff) (NoDup (A:=A))A, B:Typef:A -> Bl, l':list APermutation l l' -> Permutation (map f l) (map f l')induction 1; simpl; eauto. Qed.A, B:Typef:A -> Bl, l':list APermutation l l' -> Permutation (map f l) (map f l')A, B:Typef:A -> BProper (Permutation (A:=A) ==> Permutation (A:=B)) (map f)exact Permutation_map. Qed. End Permutation_map.A, B:Typef:A -> BProper (Permutation (A:=A) ==> Permutation (A:=B)) (map f)n:natf:nat -> natbFun n f -> Injective f -> let l := seq 0 n in Permutation (map f l) ln:natf:nat -> natbFun n f -> Injective f -> let l := seq 0 n in Permutation (map f l) ln:natf:nat -> natHf:bFun n fBD:Injective flet l := seq 0 n in Permutation (map f l) ln:natf:nat -> natHf:bFun n fBD:Injective flength (seq 0 n) <= length (map f (seq 0 n))n:natf:nat -> natHf:bFun n fBD:Injective fincl (map f (seq 0 n)) (seq 0 n)now rewrite map_length.n:natf:nat -> natHf:bFun n fBD:Injective flength (seq 0 n) <= length (map f (seq 0 n))n:natf:nat -> natHf:bFun n fBD:Injective fincl (map f (seq 0 n)) (seq 0 n)n:natf:nat -> natHf:bFun n fBD:Injective fx:natIn x (map f (seq 0 n)) -> In x (seq 0 n)n:natf:nat -> natHf:bFun n fBD:Injective fx:nat(exists x0 : nat, f x0 = x /\ In x0 (seq 0 n)) -> In x (seq 0 n)n:natf:nat -> natHf:bFun n fBD:Injective fy:natHy':In y (seq 0 n)In (f y) (seq 0 n)n:natf:nat -> natHf:bFun n fBD:Injective fy:natHy':0 <= y < 0 + n0 <= f y < 0 + nn:natf:nat -> natHf:bFun n fBD:Injective fy:natHy':0 <= y < n0 <= f y < nauto with arith. Qed. Section Permutation_alt. Variable A:Type. Implicit Type a : A. Implicit Type l : list A.n:natf:nat -> natHf:bFun n fBD:Injective fy:natHy':y < n0 <= f y < n
Alternative characterization of permutation
via nth_error and nth
Let adapt f n := let m := f (S n) in if le_lt_dec m (f 0) then m else pred m.A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natf:nat -> natInjective f -> Injective (adapt f)A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natf:nat -> natInjective f -> Injective (adapt f)A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natf:nat -> natInjective f -> Injective (fun n : nat => if le_lt_dec (f (S n)) (f 0) then f (S n) else Nat.pred (f (S n)))A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natf:nat -> natHf:Injective fx, y:natEQ:(if le_lt_dec (f (S x)) (f 0) then f (S x) else Nat.pred (f (S x))) = (if le_lt_dec (f (S y)) (f 0) then f (S y) else Nat.pred (f (S y)))x = yA:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natf:nat -> natHf:Injective fx, y:natLE:f (S x) <= f 0LE':f (S y) <= f 0EQ:f (S x) = f (S y)x = yA:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natf:nat -> natHf:Injective fx, y:natLE:f (S x) <= f 0LT':f 0 < f (S y)EQ:f (S x) = Nat.pred (f (S y))x = yA:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natf:nat -> natHf:Injective fx, y:natLT:f 0 < f (S x)LE':f (S y) <= f 0EQ:Nat.pred (f (S x)) = f (S y)x = yA:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natf:nat -> natHf:Injective fx, y:natLT:f 0 < f (S x)LT':f 0 < f (S y)EQ:Nat.pred (f (S x)) = Nat.pred (f (S y))x = ynow apply eq_add_S, Hf.A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natf:nat -> natHf:Injective fx, y:natLE:f (S x) <= f 0LE':f (S y) <= f 0EQ:f (S x) = f (S y)x = yA:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natf:nat -> natHf:Injective fx, y:natLE:f (S x) <= f 0LT':f 0 < f (S y)EQ:f (S x) = Nat.pred (f (S y))x = yA:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natf:nat -> natHf:Injective fx, y:natLE:f (S x) < f 0 \/ f (S x) = f 0LT':f 0 < f (S y)EQ:f (S x) = Nat.pred (f (S y))x = yA:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natf:nat -> natHf:Injective fx, y:natLT:f (S x) < f 0LT':f 0 < f (S y)EQ:f (S x) = Nat.pred (f (S y))x = yA:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natf:nat -> natHf:Injective fx, y:natLT:S (f (S x)) <= f 0LT':f 0 < f (S y)EQ:f (S x) = Nat.pred (f (S y))x = yA:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natf:nat -> natHf:Injective fx, y:natLT:S (Nat.pred (f (S y))) <= f 0LT':f 0 < f (S y)EQ:f (S x) = Nat.pred (f (S y))x = yelim (Lt.lt_not_le _ _ LT' LT).A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natf:nat -> natHf:Injective fx, y:natLT:f (S y) <= f 0LT':f 0 < f (S y)EQ:f (S x) = Nat.pred (f (S y))x = yA:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natf:nat -> natHf:Injective fx, y:natLT:f 0 < f (S x)LE':f (S y) <= f 0EQ:Nat.pred (f (S x)) = f (S y)x = yA:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natf:nat -> natHf:Injective fx, y:natLT:f 0 < f (S x)LE':f (S y) < f 0 \/ f (S y) = f 0EQ:Nat.pred (f (S x)) = f (S y)x = yA:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natf:nat -> natHf:Injective fx, y:natLT:f 0 < f (S x)LT':f (S y) < f 0EQ:Nat.pred (f (S x)) = f (S y)x = yA:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natf:nat -> natHf:Injective fx, y:natLT:f 0 < f (S x)LT':S (f (S y)) <= f 0EQ:Nat.pred (f (S x)) = f (S y)x = yA:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natf:nat -> natHf:Injective fx, y:natLT:f 0 < f (S x)LT':S (Nat.pred (f (S x))) <= f 0EQ:Nat.pred (f (S x)) = f (S y)x = yelim (Lt.lt_not_le _ _ LT LT').A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natf:nat -> natHf:Injective fx, y:natLT:f 0 < f (S x)LT':f (S x) <= f 0EQ:Nat.pred (f (S x)) = f (S y)x = yA:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natf:nat -> natHf:Injective fx, y:natLT:f 0 < f (S x)LT':f 0 < f (S y)EQ:Nat.pred (f (S x)) = Nat.pred (f (S y))x = ynow rewrite (Lt.S_pred _ _ LT), (Lt.S_pred _ _ LT'), EQ. Qed.A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natf:nat -> natHf:Injective fx, y:natLT:f 0 < f (S x)LT':f 0 < f (S y)EQ:Nat.pred (f (S x)) = Nat.pred (f (S y))f (S x) = f (S y)A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)a:Al1, l2:list Af:nat -> natInjective f -> length l1 = f 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (adapt f n)A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)a:Al1, l2:list Af:nat -> natInjective f -> length l1 = f 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (adapt f n)A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)a:Al1, l2:list Af:nat -> natInjective f -> length l1 = f 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (if le_lt_dec (f (S n)) (f 0) then f (S n) else Nat.pred (f (S n)))A:Typeadapt:=fun (f0 : nat -> nat) (n0 : nat) => let m := f0 (S n0) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)a:Al1, l2:list Af:nat -> natHf:Injective fE:length l1 = f 0n:natnth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (if le_lt_dec (f (S n)) (f 0) then f (S n) else Nat.pred (f (S n)))A:Typeadapt:=fun (f0 : nat -> nat) (n0 : nat) => let m := f0 (S n0) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)a:Al1, l2:list Af:nat -> natHf:Injective fE:length l1 = f 0n:natLE:f (S n) <= f 0nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (f (S n))A:Typeadapt:=fun (f0 : nat -> nat) (n0 : nat) => let m := f0 (S n0) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)a:Al1, l2:list Af:nat -> natHf:Injective fE:length l1 = f 0n:natLT:f 0 < f (S n)nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (Nat.pred (f (S n)))A:Typeadapt:=fun (f0 : nat -> nat) (n0 : nat) => let m := f0 (S n0) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)a:Al1, l2:list Af:nat -> natHf:Injective fE:length l1 = f 0n:natLE:f (S n) <= f 0nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (f (S n))A:Typeadapt:=fun (f0 : nat -> nat) (n0 : nat) => let m := f0 (S n0) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)a:Al1, l2:list Af:nat -> natHf:Injective fE:length l1 = f 0n:natLE:f (S n) < f 0 \/ f (S n) = f 0nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (f (S n))A:Typeadapt:=fun (f0 : nat -> nat) (n0 : nat) => let m := f0 (S n0) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)a:Al1, l2:list Af:nat -> natHf:Injective fE:length l1 = f 0n:natLT:f (S n) < f 0nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (f (S n))rewrite 2 nth_error_app1; auto.A:Typeadapt:=fun (f0 : nat -> nat) (n0 : nat) => let m := f0 (S n0) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)a:Al1, l2:list Af:nat -> natHf:Injective fE:length l1 = f 0n:natLT:f (S n) < length l1nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (f (S n))A:Typeadapt:=fun (f0 : nat -> nat) (n0 : nat) => let m := f0 (S n0) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)a:Al1, l2:list Af:nat -> natHf:Injective fE:length l1 = f 0n:natLT:f 0 < f (S n)nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (Nat.pred (f (S n)))A:Typeadapt:=fun (f0 : nat -> nat) (n0 : nat) => let m := f0 (S n0) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)a:Al1, l2:list Af:nat -> natHf:Injective fE:length l1 = f 0n:natLT:f 0 < f (S n)nth_error (l1 ++ a :: l2) (S (Nat.pred (f (S n)))) = nth_error (l1 ++ l2) (Nat.pred (f (S n)))A:Typeadapt:=fun (f0 : nat -> nat) (n0 : nat) => let m := f0 (S n0) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)a:Al1, l2:list Af:nat -> natHf:Injective fE:length l1 = f 0n:natLT:length l1 < S (Nat.pred (f (S n)))nth_error (l1 ++ a :: l2) (S (Nat.pred (f (S n)))) = nth_error (l1 ++ l2) (Nat.pred (f (S n)))rewrite <- Minus.minus_Sn_m; auto with arith. Qed.A:Typeadapt:=fun (f0 : nat -> nat) (n0 : nat) => let m := f0 (S n0) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)a:Al1, l2:list Af:nat -> natHf:Injective fE:length l1 = f 0n:natLT:length l1 < S (Nat.pred (f (S n)))nth_error (a :: l2) (S (Nat.pred (f (S n))) - length l1) = nth_error l2 (Nat.pred (f (S n)) - length l1)A:Typeadapt:=fun (f : nat -> nat) (n : nat) => let m := f (S n) in if le_lt_dec m (f 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f : nat -> nat, Injective f -> Injective (adapt f)adapt_ok:forall (a : A) (l1 l2 : list A) (f : nat -> nat), Injective f -> length l1 = f 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (adapt f n)l, l':list APermutation l l' <-> length l = length l' /\ (exists f : nat -> nat, Injective f /\ (forall n : nat, nth_error l' n = nth_error l (f n)))A:Typeadapt:=fun (f : nat -> nat) (n : nat) => let m := f (S n) in if le_lt_dec m (f 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f : nat -> nat, Injective f -> Injective (adapt f)adapt_ok:forall (a : A) (l1 l2 : list A) (f : nat -> nat), Injective f -> length l1 = f 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (adapt f n)l, l':list APermutation l l' <-> length l = length l' /\ (exists f : nat -> nat, Injective f /\ (forall n : nat, nth_error l' n = nth_error l (f n)))A:Typeadapt:=fun (f : nat -> nat) (n : nat) => let m := f (S n) in if le_lt_dec m (f 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f : nat -> nat, Injective f -> Injective (adapt f)adapt_ok:forall (a : A) (l1 l2 : list A) (f : nat -> nat), Injective f -> length l1 = f 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (adapt f n)l, l':list APermutation l l' -> length l = length l' /\ (exists f : nat -> nat, Injective f /\ (forall n : nat, nth_error l' n = nth_error l (f n)))A:Typeadapt:=fun (f : nat -> nat) (n : nat) => let m := f (S n) in if le_lt_dec m (f 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f : nat -> nat, Injective f -> Injective (adapt f)adapt_ok:forall (a : A) (l1 l2 : list A) (f : nat -> nat), Injective f -> length l1 = f 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (adapt f n)l, l':list Alength l = length l' /\ (exists f : nat -> nat, Injective f /\ (forall n : nat, nth_error l' n = nth_error l (f n))) -> Permutation l l'A:Typeadapt:=fun (f : nat -> nat) (n : nat) => let m := f (S n) in if le_lt_dec m (f 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f : nat -> nat, Injective f -> Injective (adapt f)adapt_ok:forall (a : A) (l1 l2 : list A) (f : nat -> nat), Injective f -> length l1 = f 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (adapt f n)l, l':list APermutation l l' -> length l = length l' /\ (exists f : nat -> nat, Injective f /\ (forall n : nat, nth_error l' n = nth_error l (f n)))A:Typeadapt:=fun (f : nat -> nat) (n : nat) => let m := f (S n) in if le_lt_dec m (f 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f : nat -> nat, Injective f -> Injective (adapt f)adapt_ok:forall (a : A) (l1 l2 : list A) (f : nat -> nat), Injective f -> length l1 = f 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (adapt f n)l, l':list AP:Permutation l l'length l = length l' /\ (exists f : nat -> nat, Injective f /\ (forall n : nat, nth_error l' n = nth_error l (f n)))A:Typeadapt:=fun (f : nat -> nat) (n : nat) => let m := f (S n) in if le_lt_dec m (f 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f : nat -> nat, Injective f -> Injective (adapt f)adapt_ok:forall (a : A) (l1 l2 : list A) (f : nat -> nat), Injective f -> length l1 = f 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (adapt f n)l, l':list AP:Permutation l l'exists f : nat -> nat, Injective f /\ (forall n : nat, nth_error l' n = nth_error l (f n))A:Typeadapt:=fun (f : nat -> nat) (n : nat) => let m := f (S n) in if le_lt_dec m (f 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f : nat -> nat, Injective f -> Injective (adapt f)adapt_ok:forall (a : A) (l1 l2 : list A) (f : nat -> nat), Injective f -> length l1 = f 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (adapt f n)exists f : nat -> nat, Injective f /\ (forall n : nat, nth_error [] n = nth_error [] (f n))A:Typeadapt:=fun (f : nat -> nat) (n : nat) => let m := f (S n) in if le_lt_dec m (f 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f : nat -> nat, Injective f -> Injective (adapt f)adapt_ok:forall (a : A) (l1 l2 : list A) (f : nat -> nat), Injective f -> length l1 = f 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (adapt f n)x:Al, l':list AP:Permutation l l'IHP:exists f : nat -> nat, Injective f /\ (forall n : nat, nth_error l' n = nth_error l (f n))exists f : nat -> nat, Injective f /\ (forall n : nat, nth_error (x :: l') n = nth_error (x :: l) (f n))A:Typeadapt:=fun (f : nat -> nat) (n : nat) => let m := f (S n) in if le_lt_dec m (f 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f : nat -> nat, Injective f -> Injective (adapt f)adapt_ok:forall (a : A) (l1 l2 : list A) (f : nat -> nat), Injective f -> length l1 = f 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (adapt f n)x, y:Al:list Aexists f : nat -> nat, Injective f /\ (forall n : nat, nth_error (x :: y :: l) n = nth_error (y :: x :: l) (f n))A:Typeadapt:=fun (f : nat -> nat) (n : nat) => let m := f (S n) in if le_lt_dec m (f 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f : nat -> nat, Injective f -> Injective (adapt f)adapt_ok:forall (a : A) (l1 l2 : list A) (f : nat -> nat), Injective f -> length l1 = f 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (adapt f n)l, l', l'':list AP1:Permutation l l'P2:Permutation l' l''IHP1:exists f : nat -> nat, Injective f /\ (forall n : nat, nth_error l' n = nth_error l (f n))IHP2:exists f : nat -> nat, Injective f /\ (forall n : nat, nth_error l'' n = nth_error l' (f n))exists f : nat -> nat, Injective f /\ (forall n : nat, nth_error l'' n = nth_error l (f n))A:Typeadapt:=fun (f : nat -> nat) (n : nat) => let m := f (S n) in if le_lt_dec m (f 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f : nat -> nat, Injective f -> Injective (adapt f)adapt_ok:forall (a : A) (l1 l2 : list A) (f : nat -> nat), Injective f -> length l1 = f 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (adapt f n)exists f : nat -> nat, Injective f /\ (forall n : nat, nth_error [] n = nth_error [] (f n))split; try red; auto.A:Typeadapt:=fun (f : nat -> nat) (n : nat) => let m := f (S n) in if le_lt_dec m (f 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f : nat -> nat, Injective f -> Injective (adapt f)adapt_ok:forall (a : A) (l1 l2 : list A) (f : nat -> nat), Injective f -> length l1 = f 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (adapt f n)Injective (fun n : nat => n) /\ (forall n : nat, nth_error [] n = nth_error [] n)A:Typeadapt:=fun (f : nat -> nat) (n : nat) => let m := f (S n) in if le_lt_dec m (f 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f : nat -> nat, Injective f -> Injective (adapt f)adapt_ok:forall (a : A) (l1 l2 : list A) (f : nat -> nat), Injective f -> length l1 = f 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (adapt f n)x:Al, l':list AP:Permutation l l'IHP:exists f : nat -> nat, Injective f /\ (forall n : nat, nth_error l' n = nth_error l (f n))exists f : nat -> nat, Injective f /\ (forall n : nat, nth_error (x :: l') n = nth_error (x :: l) (f n))A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)x:Al, l':list AP:Permutation l l'f:nat -> natHf:Injective fHf':forall n : nat, nth_error l' n = nth_error l (f n)exists f0 : nat -> nat, Injective f0 /\ (forall n : nat, nth_error (x :: l') n = nth_error (x :: l) (f0 n))A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)x:Al, l':list AP:Permutation l l'f:nat -> natHf:Injective fHf':forall n : nat, nth_error l' n = nth_error l (f n)Injective (fun n : nat => match n with | 0 => 0 | S n0 => S (f n0) end) /\ (forall n : nat, nth_error (x :: l') n = nth_error (x :: l) match n with | 0 => 0 | S n0 => S (f n0) end)A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)x:Al, l':list AP:Permutation l l'f:nat -> natHf:Injective fHf':forall n : nat, nth_error l' n = nth_error l (f n)forall x0 y : nat, match x0 with | 0 => 0 | S n => S (f n) end = match y with | 0 => 0 | S n => S (f n) end -> x0 = yA:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)x:Al, l':list AP:Permutation l l'f:nat -> natHf:Injective fHf':forall n : nat, nth_error l' n = nth_error l (f n)forall n : nat, nth_error (x :: l') n = nth_error (x :: l) match n with | 0 => 0 | S n0 => S (f n0) endintros [|y] [|z]; simpl; now auto.A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)x:Al, l':list AP:Permutation l l'f:nat -> natHf:Injective fHf':forall n : nat, nth_error l' n = nth_error l (f n)forall x0 y : nat, match x0 with | 0 => 0 | S n => S (f n) end = match y with | 0 => 0 | S n => S (f n) end -> x0 = yintros [|n]; simpl; auto.A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)x:Al, l':list AP:Permutation l l'f:nat -> natHf:Injective fHf':forall n : nat, nth_error l' n = nth_error l (f n)forall n : nat, nth_error (x :: l') n = nth_error (x :: l) match n with | 0 => 0 | S n0 => S (f n0) endA:Typeadapt:=fun (f : nat -> nat) (n : nat) => let m := f (S n) in if le_lt_dec m (f 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f : nat -> nat, Injective f -> Injective (adapt f)adapt_ok:forall (a : A) (l1 l2 : list A) (f : nat -> nat), Injective f -> length l1 = f 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (adapt f n)x, y:Al:list Aexists f : nat -> nat, Injective f /\ (forall n : nat, nth_error (x :: y :: l) n = nth_error (y :: x :: l) (f n))A:Typeadapt:=fun (f : nat -> nat) (n : nat) => let m := f (S n) in if le_lt_dec m (f 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f : nat -> nat, Injective f -> Injective (adapt f)adapt_ok:forall (a : A) (l1 l2 : list A) (f : nat -> nat), Injective f -> length l1 = f 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (adapt f n)x, y:Al:list AInjective (fun n : nat => match n with | 0 => 1 | 1 => 0 | S (S _) => n end) /\ (forall n : nat, nth_error (x :: y :: l) n = nth_error (y :: x :: l) match n with | 0 => 1 | 1 => 0 | S (S _) => n end)A:Typeadapt:=fun (f : nat -> nat) (n : nat) => let m := f (S n) in if le_lt_dec m (f 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f : nat -> nat, Injective f -> Injective (adapt f)adapt_ok:forall (a : A) (l1 l2 : list A) (f : nat -> nat), Injective f -> length l1 = f 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (adapt f n)x, y:Al:list Aforall x0 y0 : nat, match x0 with | 0 => 1 | 1 => 0 | S (S _) => x0 end = match y0 with | 0 => 1 | 1 => 0 | S (S _) => y0 end -> x0 = y0A:Typeadapt:=fun (f : nat -> nat) (n : nat) => let m := f (S n) in if le_lt_dec m (f 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f : nat -> nat, Injective f -> Injective (adapt f)adapt_ok:forall (a : A) (l1 l2 : list A) (f : nat -> nat), Injective f -> length l1 = f 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (adapt f n)x, y:Al:list Aforall n : nat, nth_error (x :: y :: l) n = nth_error (y :: x :: l) match n with | 0 => 1 | 1 => 0 | S (S _) => n endintros [|[|z]] [|[|t]]; simpl; now auto.A:Typeadapt:=fun (f : nat -> nat) (n : nat) => let m := f (S n) in if le_lt_dec m (f 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f : nat -> nat, Injective f -> Injective (adapt f)adapt_ok:forall (a : A) (l1 l2 : list A) (f : nat -> nat), Injective f -> length l1 = f 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (adapt f n)x, y:Al:list Aforall x0 y0 : nat, match x0 with | 0 => 1 | 1 => 0 | S (S _) => x0 end = match y0 with | 0 => 1 | 1 => 0 | S (S _) => y0 end -> x0 = y0intros [|[|n]]; simpl; auto.A:Typeadapt:=fun (f : nat -> nat) (n : nat) => let m := f (S n) in if le_lt_dec m (f 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f : nat -> nat, Injective f -> Injective (adapt f)adapt_ok:forall (a : A) (l1 l2 : list A) (f : nat -> nat), Injective f -> length l1 = f 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (adapt f n)x, y:Al:list Aforall n : nat, nth_error (x :: y :: l) n = nth_error (y :: x :: l) match n with | 0 => 1 | 1 => 0 | S (S _) => n endA:Typeadapt:=fun (f : nat -> nat) (n : nat) => let m := f (S n) in if le_lt_dec m (f 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f : nat -> nat, Injective f -> Injective (adapt f)adapt_ok:forall (a : A) (l1 l2 : list A) (f : nat -> nat), Injective f -> length l1 = f 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (adapt f n)l, l', l'':list AP1:Permutation l l'P2:Permutation l' l''IHP1:exists f : nat -> nat, Injective f /\ (forall n : nat, nth_error l' n = nth_error l (f n))IHP2:exists f : nat -> nat, Injective f /\ (forall n : nat, nth_error l'' n = nth_error l' (f n))exists f : nat -> nat, Injective f /\ (forall n : nat, nth_error l'' n = nth_error l (f n))A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l', l'':list AP1:Permutation l l'P2:Permutation l' l''f:nat -> natHf:Injective fHf':forall n : nat, nth_error l' n = nth_error l (f n)IHP2:exists f0 : nat -> nat, Injective f0 /\ (forall n : nat, nth_error l'' n = nth_error l' (f0 n))exists f0 : nat -> nat, Injective f0 /\ (forall n : nat, nth_error l'' n = nth_error l (f0 n))A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l', l'':list AP1:Permutation l l'P2:Permutation l' l''f:nat -> natHf:Injective fHf':forall n : nat, nth_error l' n = nth_error l (f n)g:nat -> natHg:Injective gHg':forall n : nat, nth_error l'' n = nth_error l' (g n)exists f0 : nat -> nat, Injective f0 /\ (forall n : nat, nth_error l'' n = nth_error l (f0 n))A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l', l'':list AP1:Permutation l l'P2:Permutation l' l''f:nat -> natHf:Injective fHf':forall n : nat, nth_error l' n = nth_error l (f n)g:nat -> natHg:Injective gHg':forall n : nat, nth_error l'' n = nth_error l' (g n)Injective (fun n : nat => f (g n)) /\ (forall n : nat, nth_error l'' n = nth_error l (f (g n)))A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l', l'':list AP1:Permutation l l'P2:Permutation l' l''f:nat -> natHf:Injective fHf':forall n : nat, nth_error l' n = nth_error l (f n)g:nat -> natHg:Injective gHg':forall n : nat, nth_error l'' n = nth_error l' (g n)forall x y : nat, f (g x) = f (g y) -> x = yA:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l', l'':list AP1:Permutation l l'P2:Permutation l' l''f:nat -> natHf:Injective fHf':forall n : nat, nth_error l' n = nth_error l (f n)g:nat -> natHg:Injective gHg':forall n : nat, nth_error l'' n = nth_error l' (g n)forall n : nat, nth_error l'' n = nth_error l (f (g n))auto.A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l', l'':list AP1:Permutation l l'P2:Permutation l' l''f:nat -> natHf:Injective fHf':forall n : nat, nth_error l' n = nth_error l (f n)g:nat -> natHg:Injective gHg':forall n : nat, nth_error l'' n = nth_error l' (g n)forall x y : nat, f (g x) = f (g y) -> x = yA:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l', l'':list AP1:Permutation l l'P2:Permutation l' l''f:nat -> natHf:Injective fHf':forall n : nat, nth_error l' n = nth_error l (f n)g:nat -> natHg:Injective gHg':forall n : nat, nth_error l'' n = nth_error l' (g n)forall n : nat, nth_error l'' n = nth_error l (f (g n))rewrite <- Hf'; auto.A:Typeadapt:=fun (f0 : nat -> nat) (n0 : nat) => let m := f0 (S n0) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n0 : nat, nth_error (l1 ++ a :: l2) (f0 (S n0)) = nth_error (l1 ++ l2) (adapt f0 n0)l, l', l'':list AP1:Permutation l l'P2:Permutation l' l''f:nat -> natHf:Injective fHf':forall n0 : nat, nth_error l' n0 = nth_error l (f n0)g:nat -> natHg:Injective gHg':forall n0 : nat, nth_error l'' n0 = nth_error l' (g n0)n:natnth_error l'' n = nth_error l (f (g n))A:Typeadapt:=fun (f : nat -> nat) (n : nat) => let m := f (S n) in if le_lt_dec m (f 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f : nat -> nat, Injective f -> Injective (adapt f)adapt_ok:forall (a : A) (l1 l2 : list A) (f : nat -> nat), Injective f -> length l1 = f 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (adapt f n)l, l':list Alength l = length l' /\ (exists f : nat -> nat, Injective f /\ (forall n : nat, nth_error l' n = nth_error l (f n))) -> Permutation l l'A:Typeadapt:=fun (f : nat -> nat) (n : nat) => let m := f (S n) in if le_lt_dec m (f 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f : nat -> nat, Injective f -> Injective (adapt f)adapt_ok:forall (a : A) (l1 l2 : list A) (f : nat -> nat), Injective f -> length l1 = f 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (adapt f n)l, l':list Alength l = length l' /\ (exists f : nat -> nat, Injective f /\ (forall n : nat, nth_error l' n = nth_error l (f n))) -> Permutation l l'A:Typeadapt:=fun (f : nat -> nat) (n : nat) => let m := f (S n) in if le_lt_dec m (f 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f : nat -> nat, Injective f -> Injective (adapt f)adapt_ok:forall (a : A) (l1 l2 : list A) (f : nat -> nat), Injective f -> length l1 = f 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (adapt f n)l':list Aforall l : list A, length l = length l' /\ (exists f : nat -> nat, Injective f /\ (forall n : nat, nth_error l' n = nth_error l (f n))) -> Permutation l l'A:Typeadapt:=fun (f : nat -> nat) (n : nat) => let m := f (S n) in if le_lt_dec m (f 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f : nat -> nat, Injective f -> Injective (adapt f)adapt_ok:forall (a : A) (l1 l2 : list A) (f : nat -> nat), Injective f -> length l1 = f 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (adapt f n)forall l : list A, length l = length [] /\ (exists f : nat -> nat, Injective f /\ (forall n : nat, nth_error [] n = nth_error l (f n))) -> Permutation l []A:Typeadapt:=fun (f : nat -> nat) (n : nat) => let m := f (S n) in if le_lt_dec m (f 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f : nat -> nat, Injective f -> Injective (adapt f)adapt_ok:forall (a0 : A) (l1 l2 : list A) (f : nat -> nat), Injective f -> length l1 = f 0 -> forall n : nat, nth_error (l1 ++ a0 :: l2) (f (S n)) = nth_error (l1 ++ l2) (adapt f n)a:Al':list AIHl':forall l : list A, length l = length l' /\ (exists f : nat -> nat, Injective f /\ (forall n : nat, nth_error l' n = nth_error l (f n))) -> Permutation l l'forall l : list A, length l = length (a :: l') /\ (exists f : nat -> nat, Injective f /\ (forall n : nat, nth_error (a :: l') n = nth_error l (f n))) -> Permutation l (a :: l')intros [|l] (E & _); now auto.A:Typeadapt:=fun (f : nat -> nat) (n : nat) => let m := f (S n) in if le_lt_dec m (f 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f : nat -> nat, Injective f -> Injective (adapt f)adapt_ok:forall (a : A) (l1 l2 : list A) (f : nat -> nat), Injective f -> length l1 = f 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (adapt f n)forall l : list A, length l = length [] /\ (exists f : nat -> nat, Injective f /\ (forall n : nat, nth_error [] n = nth_error l (f n))) -> Permutation l []A:Typeadapt:=fun (f : nat -> nat) (n : nat) => let m := f (S n) in if le_lt_dec m (f 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f : nat -> nat, Injective f -> Injective (adapt f)adapt_ok:forall (a0 : A) (l1 l2 : list A) (f : nat -> nat), Injective f -> length l1 = f 0 -> forall n : nat, nth_error (l1 ++ a0 :: l2) (f (S n)) = nth_error (l1 ++ l2) (adapt f n)a:Al':list AIHl':forall l : list A, length l = length l' /\ (exists f : nat -> nat, Injective f /\ (forall n : nat, nth_error l' n = nth_error l (f n))) -> Permutation l l'forall l : list A, length l = length (a :: l') /\ (exists f : nat -> nat, Injective f /\ (forall n : nat, nth_error (a :: l') n = nth_error l (f n))) -> Permutation l (a :: l')A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a0 : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a0 :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)a:Al':list AIHl':forall l0 : list A, length l0 = length l' /\ (exists f0 : nat -> nat, Injective f0 /\ (forall n : nat, nth_error l' n = nth_error l0 (f0 n))) -> Permutation l0 l'l:list AE:length l = length (a :: l')f:nat -> natHf:Injective fHf':forall n : nat, nth_error (a :: l') n = nth_error l (f n)Permutation l (a :: l')A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a0 : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a0 :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)a:Al':list AIHl':forall l0 : list A, length l0 = length l' /\ (exists f0 : nat -> nat, Injective f0 /\ (forall n : nat, nth_error l' n = nth_error l0 (f0 n))) -> Permutation l0 l'l:list AE:length l = S (length l')f:nat -> natHf:Injective fHf':forall n : nat, nth_error (a :: l') n = nth_error l (f n)Permutation l (a :: l')A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a0 : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a0 :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)a:Al':list AIHl':forall l0 : list A, length l0 = length l' /\ (exists f0 : nat -> nat, Injective f0 /\ (forall n : nat, nth_error l' n = nth_error l0 (f0 n))) -> Permutation l0 l'l:list AE:length l = S (length l')f:nat -> natHf:Injective fHf':forall n : nat, nth_error (a :: l') n = nth_error l (f n)Ha:nth_error l (f 0) = Some aPermutation l (a :: l')A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a0 : A) (l0 l3 : list A) (f0 : nat -> nat), Injective f0 -> length l0 = f0 0 -> forall n : nat, nth_error (l0 ++ a0 :: l3) (f0 (S n)) = nth_error (l0 ++ l3) (adapt f0 n)a:Al':list AIHl':forall l0 : list A, length l0 = length l' /\ (exists f0 : nat -> nat, Injective f0 /\ (forall n : nat, nth_error l' n = nth_error l0 (f0 n))) -> Permutation l0 l'l:list AE:length l = S (length l')f:nat -> natHf:Injective fHf':forall n : nat, nth_error (a :: l') n = nth_error l (f n)Ha:nth_error l (f 0) = Some al1, l2:list AL12:l = l1 ++ a :: l2L1:length l1 = f 0Permutation l (a :: l')A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a0 : A) (l0 l3 : list A) (f0 : nat -> nat), Injective f0 -> length l0 = f0 0 -> forall n : nat, nth_error (l0 ++ a0 :: l3) (f0 (S n)) = nth_error (l0 ++ l3) (adapt f0 n)a:Al':list AIHl':forall l0 : list A, length l0 = length l' /\ (exists f0 : nat -> nat, Injective f0 /\ (forall n : nat, nth_error l' n = nth_error l0 (f0 n))) -> Permutation l0 l'l:list AE:length l = S (length l')f:nat -> natHf:Injective fHf':forall n : nat, nth_error (a :: l') n = nth_error l (f n)Ha:nth_error l (f 0) = Some al1, l2:list AL12:l = l1 ++ a :: l2L1:length l1 = f 0Permutation (l1 ++ a :: l2) (a :: l')A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a0 : A) (l0 l3 : list A) (f0 : nat -> nat), Injective f0 -> length l0 = f0 0 -> forall n : nat, nth_error (l0 ++ a0 :: l3) (f0 (S n)) = nth_error (l0 ++ l3) (adapt f0 n)a:Al':list AIHl':forall l0 : list A, length l0 = length l' /\ (exists f0 : nat -> nat, Injective f0 /\ (forall n : nat, nth_error l' n = nth_error l0 (f0 n))) -> Permutation l0 l'l:list AE:length l = S (length l')f:nat -> natHf:Injective fHf':forall n : nat, nth_error (a :: l') n = nth_error l (f n)Ha:nth_error l (f 0) = Some al1, l2:list AL12:l = l1 ++ a :: l2L1:length l1 = f 0Permutation (a :: l1 ++ l2) (a :: l')A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a0 : A) (l0 l3 : list A) (f0 : nat -> nat), Injective f0 -> length l0 = f0 0 -> forall n : nat, nth_error (l0 ++ a0 :: l3) (f0 (S n)) = nth_error (l0 ++ l3) (adapt f0 n)a:Al':list AIHl':forall l0 : list A, length l0 = length l' /\ (exists f0 : nat -> nat, Injective f0 /\ (forall n : nat, nth_error l' n = nth_error l0 (f0 n))) -> Permutation l0 l'l:list AE:length l = S (length l')f:nat -> natHf:Injective fHf':forall n : nat, nth_error (a :: l') n = nth_error l (f n)Ha:nth_error l (f 0) = Some al1, l2:list AL12:l = l1 ++ a :: l2L1:length l1 = f 0Permutation (l1 ++ l2) l'A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a0 : A) (l0 l3 : list A) (f0 : nat -> nat), Injective f0 -> length l0 = f0 0 -> forall n : nat, nth_error (l0 ++ a0 :: l3) (f0 (S n)) = nth_error (l0 ++ l3) (adapt f0 n)a:Al':list AIHl':forall l0 : list A, length l0 = length l' /\ (exists f0 : nat -> nat, Injective f0 /\ (forall n : nat, nth_error l' n = nth_error l0 (f0 n))) -> Permutation l0 l'l:list AE:length l = S (length l')f:nat -> natHf:Injective fHf':forall n : nat, nth_error (a :: l') n = nth_error l (f n)Ha:nth_error l (f 0) = Some al1, l2:list AL12:l = l1 ++ a :: l2L1:length l1 = f 0length (l1 ++ l2) = length l'A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a0 : A) (l0 l3 : list A) (f0 : nat -> nat), Injective f0 -> length l0 = f0 0 -> forall n : nat, nth_error (l0 ++ a0 :: l3) (f0 (S n)) = nth_error (l0 ++ l3) (adapt f0 n)a:Al':list AIHl':forall l0 : list A, length l0 = length l' /\ (exists f0 : nat -> nat, Injective f0 /\ (forall n : nat, nth_error l' n = nth_error l0 (f0 n))) -> Permutation l0 l'l:list AE:length l = S (length l')f:nat -> natHf:Injective fHf':forall n : nat, nth_error (a :: l') n = nth_error l (f n)Ha:nth_error l (f 0) = Some al1, l2:list AL12:l = l1 ++ a :: l2L1:length l1 = f 0Injective (adapt f)A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a0 : A) (l0 l3 : list A) (f0 : nat -> nat), Injective f0 -> length l0 = f0 0 -> forall n : nat, nth_error (l0 ++ a0 :: l3) (f0 (S n)) = nth_error (l0 ++ l3) (adapt f0 n)a:Al':list AIHl':forall l0 : list A, length l0 = length l' /\ (exists f0 : nat -> nat, Injective f0 /\ (forall n : nat, nth_error l' n = nth_error l0 (f0 n))) -> Permutation l0 l'l:list AE:length l = S (length l')f:nat -> natHf:Injective fHf':forall n : nat, nth_error (a :: l') n = nth_error l (f n)Ha:nth_error l (f 0) = Some al1, l2:list AL12:l = l1 ++ a :: l2L1:length l1 = f 0forall n : nat, nth_error l' n = nth_error (l1 ++ l2) (adapt f n)A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a0 : A) (l0 l3 : list A) (f0 : nat -> nat), Injective f0 -> length l0 = f0 0 -> forall n : nat, nth_error (l0 ++ a0 :: l3) (f0 (S n)) = nth_error (l0 ++ l3) (adapt f0 n)a:Al':list AIHl':forall l0 : list A, length l0 = length l' /\ (exists f0 : nat -> nat, Injective f0 /\ (forall n : nat, nth_error l' n = nth_error l0 (f0 n))) -> Permutation l0 l'l:list AE:length l = S (length l')f:nat -> natHf:Injective fHf':forall n : nat, nth_error (a :: l') n = nth_error l (f n)Ha:nth_error l (f 0) = Some al1, l2:list AL12:l = l1 ++ a :: l2L1:length l1 = f 0length (l1 ++ l2) = length l'A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a0 : A) (l0 l3 : list A) (f0 : nat -> nat), Injective f0 -> length l0 = f0 0 -> forall n : nat, nth_error (l0 ++ a0 :: l3) (f0 (S n)) = nth_error (l0 ++ l3) (adapt f0 n)a:Al':list AIHl':forall l0 : list A, length l0 = length l' /\ (exists f0 : nat -> nat, Injective f0 /\ (forall n : nat, nth_error l' n = nth_error l0 (f0 n))) -> Permutation l0 l'l:list Af:nat -> natHf:Injective fHf':forall n : nat, nth_error (a :: l') n = nth_error l (f n)Ha:nth_error l (f 0) = Some al1, l2:list AL12:l = l1 ++ a :: l2L1:length l1 = f 0length l = S (length l') -> length (l1 ++ l2) = length l'A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a0 : A) (l0 l3 : list A) (f0 : nat -> nat), Injective f0 -> length l0 = f0 0 -> forall n : nat, nth_error (l0 ++ a0 :: l3) (f0 (S n)) = nth_error (l0 ++ l3) (adapt f0 n)a:Al':list AIHl':forall l0 : list A, length l0 = length l' /\ (exists f0 : nat -> nat, Injective f0 /\ (forall n : nat, nth_error l' n = nth_error l0 (f0 n))) -> Permutation l0 l'l:list Af:nat -> natHf:Injective fHf':forall n : nat, nth_error (a :: l') n = nth_error l (f n)Ha:nth_error l (f 0) = Some al1, l2:list AL12:l = l1 ++ a :: l2L1:length l1 = f 0length l1 + length (a :: l2) = S (length l') -> length l1 + length l2 = length l'A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a0 : A) (l0 l3 : list A) (f0 : nat -> nat), Injective f0 -> length l0 = f0 0 -> forall n : nat, nth_error (l0 ++ a0 :: l3) (f0 (S n)) = nth_error (l0 ++ l3) (adapt f0 n)a:Al':list AIHl':forall l0 : list A, length l0 = length l' /\ (exists f0 : nat -> nat, Injective f0 /\ (forall n : nat, nth_error l' n = nth_error l0 (f0 n))) -> Permutation l0 l'l:list Af:nat -> natHf:Injective fHf':forall n : nat, nth_error (a :: l') n = nth_error l (f n)Ha:nth_error l (f 0) = Some al1, l2:list AL12:l = l1 ++ a :: l2L1:length l1 = f 0length l1 + S (length l2) = S (length l') -> length l1 + length l2 = length l'now injection 1.A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a0 : A) (l0 l3 : list A) (f0 : nat -> nat), Injective f0 -> length l0 = f0 0 -> forall n : nat, nth_error (l0 ++ a0 :: l3) (f0 (S n)) = nth_error (l0 ++ l3) (adapt f0 n)a:Al':list AIHl':forall l0 : list A, length l0 = length l' /\ (exists f0 : nat -> nat, Injective f0 /\ (forall n : nat, nth_error l' n = nth_error l0 (f0 n))) -> Permutation l0 l'l:list Af:nat -> natHf:Injective fHf':forall n : nat, nth_error (a :: l') n = nth_error l (f n)Ha:nth_error l (f 0) = Some al1, l2:list AL12:l = l1 ++ a :: l2L1:length l1 = f 0S (length l1 + length l2) = S (length l') -> length l1 + length l2 = length l'now apply adapt_injective.A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a0 : A) (l0 l3 : list A) (f0 : nat -> nat), Injective f0 -> length l0 = f0 0 -> forall n : nat, nth_error (l0 ++ a0 :: l3) (f0 (S n)) = nth_error (l0 ++ l3) (adapt f0 n)a:Al':list AIHl':forall l0 : list A, length l0 = length l' /\ (exists f0 : nat -> nat, Injective f0 /\ (forall n : nat, nth_error l' n = nth_error l0 (f0 n))) -> Permutation l0 l'l:list AE:length l = S (length l')f:nat -> natHf:Injective fHf':forall n : nat, nth_error (a :: l') n = nth_error l (f n)Ha:nth_error l (f 0) = Some al1, l2:list AL12:l = l1 ++ a :: l2L1:length l1 = f 0Injective (adapt f)A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a0 : A) (l0 l3 : list A) (f0 : nat -> nat), Injective f0 -> length l0 = f0 0 -> forall n : nat, nth_error (l0 ++ a0 :: l3) (f0 (S n)) = nth_error (l0 ++ l3) (adapt f0 n)a:Al':list AIHl':forall l0 : list A, length l0 = length l' /\ (exists f0 : nat -> nat, Injective f0 /\ (forall n : nat, nth_error l' n = nth_error l0 (f0 n))) -> Permutation l0 l'l:list AE:length l = S (length l')f:nat -> natHf:Injective fHf':forall n : nat, nth_error (a :: l') n = nth_error l (f n)Ha:nth_error l (f 0) = Some al1, l2:list AL12:l = l1 ++ a :: l2L1:length l1 = f 0forall n : nat, nth_error l' n = nth_error (l1 ++ l2) (adapt f n)A:Typeadapt:=fun (f0 : nat -> nat) (n0 : nat) => let m := f0 (S n0) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a0 : A) (l0 l3 : list A) (f0 : nat -> nat), Injective f0 -> length l0 = f0 0 -> forall n0 : nat, nth_error (l0 ++ a0 :: l3) (f0 (S n0)) = nth_error (l0 ++ l3) (adapt f0 n0)a:Al':list AIHl':forall l0 : list A, length l0 = length l' /\ (exists f0 : nat -> nat, Injective f0 /\ (forall n0 : nat, nth_error l' n0 = nth_error l0 (f0 n0))) -> Permutation l0 l'l:list AE:length l = S (length l')f:nat -> natHf:Injective fHf':forall n0 : nat, nth_error (a :: l') n0 = nth_error l (f n0)Ha:nth_error l (f 0) = Some al1, l2:list AL12:l = l1 ++ a :: l2L1:length l1 = f 0n:natnth_error l' n = nth_error (l1 ++ l2) (adapt f n)apply (Hf' (S n)). } Qed.A:Typeadapt:=fun (f0 : nat -> nat) (n0 : nat) => let m := f0 (S n0) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a0 : A) (l0 l3 : list A) (f0 : nat -> nat), Injective f0 -> length l0 = f0 0 -> forall n0 : nat, nth_error (l0 ++ a0 :: l3) (f0 (S n0)) = nth_error (l0 ++ l3) (adapt f0 n0)a:Al':list AIHl':forall l0 : list A, length l0 = length l' /\ (exists f0 : nat -> nat, Injective f0 /\ (forall n0 : nat, nth_error l' n0 = nth_error l0 (f0 n0))) -> Permutation l0 l'l:list AE:length l = S (length l')f:nat -> natHf:Injective fHf':forall n0 : nat, nth_error (a :: l') n0 = nth_error l (f n0)Ha:nth_error l (f 0) = Some al1, l2:list AL12:l = l1 ++ a :: l2L1:length l1 = f 0n:natnth_error l' n = nth_error l (f (S n))A:Typeadapt:=fun (f : nat -> nat) (n : nat) => let m := f (S n) in if le_lt_dec m (f 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f : nat -> nat, Injective f -> Injective (adapt f)adapt_ok:forall (a : A) (l1 l2 : list A) (f : nat -> nat), Injective f -> length l1 = f 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (adapt f n)l, l':list APermutation l l' <-> (exists f : nat -> nat, Injective f /\ bFun (length l) f /\ (forall n : nat, nth_error l' n = nth_error l (f n)))A:Typeadapt:=fun (f : nat -> nat) (n : nat) => let m := f (S n) in if le_lt_dec m (f 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f : nat -> nat, Injective f -> Injective (adapt f)adapt_ok:forall (a : A) (l1 l2 : list A) (f : nat -> nat), Injective f -> length l1 = f 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (adapt f n)l, l':list APermutation l l' <-> (exists f : nat -> nat, Injective f /\ bFun (length l) f /\ (forall n : nat, nth_error l' n = nth_error l (f n)))A:Typeadapt:=fun (f : nat -> nat) (n : nat) => let m := f (S n) in if le_lt_dec m (f 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f : nat -> nat, Injective f -> Injective (adapt f)adapt_ok:forall (a : A) (l1 l2 : list A) (f : nat -> nat), Injective f -> length l1 = f 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (adapt f n)l, l':list Alength l = length l' /\ (exists f : nat -> nat, Injective f /\ (forall n : nat, nth_error l' n = nth_error l (f n))) -> exists f : nat -> nat, Injective f /\ bFun (length l) f /\ (forall n : nat, nth_error l' n = nth_error l (f n))A:Typeadapt:=fun (f : nat -> nat) (n : nat) => let m := f (S n) in if le_lt_dec m (f 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f : nat -> nat, Injective f -> Injective (adapt f)adapt_ok:forall (a : A) (l1 l2 : list A) (f : nat -> nat), Injective f -> length l1 = f 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (adapt f n)l, l':list A(exists f : nat -> nat, Injective f /\ bFun (length l) f /\ (forall n : nat, nth_error l' n = nth_error l (f n))) -> length l = length l' /\ (exists f : nat -> nat, Injective f /\ (forall n : nat, nth_error l' n = nth_error l (f n)))A:Typeadapt:=fun (f : nat -> nat) (n : nat) => let m := f (S n) in if le_lt_dec m (f 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f : nat -> nat, Injective f -> Injective (adapt f)adapt_ok:forall (a : A) (l1 l2 : list A) (f : nat -> nat), Injective f -> length l1 = f 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (adapt f n)l, l':list Alength l = length l' /\ (exists f : nat -> nat, Injective f /\ (forall n : nat, nth_error l' n = nth_error l (f n))) -> exists f : nat -> nat, Injective f /\ bFun (length l) f /\ (forall n : nat, nth_error l' n = nth_error l (f n))A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l':list AE:length l = length l'f:nat -> natHf:Injective fHf':forall n : nat, nth_error l' n = nth_error l (f n)exists f0 : nat -> nat, Injective f0 /\ bFun (length l) f0 /\ (forall n : nat, nth_error l' n = nth_error l (f0 n))A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l':list AE:length l = length l'f:nat -> natHf:Injective fHf':forall n : nat, nth_error l' n = nth_error l (f n)Injective f /\ bFun (length l) f /\ (forall n : nat, nth_error l' n = nth_error l (f n))A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l':list AE:length l = length l'f:nat -> natHf:Injective fHf':forall n : nat, nth_error l' n = nth_error l (f n)bFun (length l) fA:Typeadapt:=fun (f0 : nat -> nat) (n0 : nat) => let m := f0 (S n0) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n0 : nat, nth_error (l1 ++ a :: l2) (f0 (S n0)) = nth_error (l1 ++ l2) (adapt f0 n0)l, l':list AE:length l = length l'f:nat -> natHf:Injective fHf':forall n0 : nat, nth_error l' n0 = nth_error l (f n0)n:natHn:n < length lf n < length lA:Typeadapt:=fun (f0 : nat -> nat) (n0 : nat) => let m := f0 (S n0) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n0 : nat, nth_error (l1 ++ a :: l2) (f0 (S n0)) = nth_error (l1 ++ l2) (adapt f0 n0)l, l':list AE:length l = length l'f:nat -> natHf:Injective fHf':forall n0 : nat, nth_error l' n0 = nth_error l (f n0)n:natHn:n < length lLE:length l <= f nf n < length lelim (Lt.lt_not_le _ _ Hn LE).A:Typeadapt:=fun (f0 : nat -> nat) (n0 : nat) => let m := f0 (S n0) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n0 : nat, nth_error (l1 ++ a :: l2) (f0 (S n0)) = nth_error (l1 ++ l2) (adapt f0 n0)l, l':list AE:length l = length l'f:nat -> natHf:Injective fHf':forall n0 : nat, nth_error l' n0 = nth_error l (f n0)n:natHn:n < length lLE:length l <= nf n < length lA:Typeadapt:=fun (f : nat -> nat) (n : nat) => let m := f (S n) in if le_lt_dec m (f 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f : nat -> nat, Injective f -> Injective (adapt f)adapt_ok:forall (a : A) (l1 l2 : list A) (f : nat -> nat), Injective f -> length l1 = f 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (adapt f n)l, l':list A(exists f : nat -> nat, Injective f /\ bFun (length l) f /\ (forall n : nat, nth_error l' n = nth_error l (f n))) -> length l = length l' /\ (exists f : nat -> nat, Injective f /\ (forall n : nat, nth_error l' n = nth_error l (f n)))A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l':list Af:nat -> natHf:Injective fHf2:bFun (length l) fHf3:forall n : nat, nth_error l' n = nth_error l (f n)length l = length l'A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l':list Af:nat -> natHf:Injective fHf2:bFun (length l) fHf3:forall n : nat, nth_error l' n = nth_error l (f n)H:length l' <= length l'length l = length l'A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l':list Af:nat -> natHf:Injective fHf2:bFun (length l) fHf3:forall n : nat, nth_error l' n = nth_error l (f n)H:length l <= f (length l')length l = length l'A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l':list Af:nat -> natHf:Injective fHf2:bFun (length l) fHf3:forall n : nat, nth_error l' n = nth_error l (f n)H:length l <= f (length l')LE:length l <= length l'length l = length l'A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l':list Af:nat -> natHf:Injective fHf2:bFun (length l) fHf3:forall n : nat, nth_error l' n = nth_error l (f n)H:length l <= f (length l')LE:length l < length l' \/ length l = length l'length l = length l'A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l':list Af:nat -> natHf:Injective fHf2:bFun (length l) fHf3:forall n : nat, nth_error l' n = nth_error l (f n)H:length l <= f (length l')LT:length l < length l'length l = length l'A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l':list Af:nat -> natHf:Injective fHf2:bFun (length l) fHf3:forall n : nat, nth_error l' n = nth_error l (f n)H:length l <= f (length l')LT:f (length l) < length llength l = length l'A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l':list Af:nat -> natHf:Injective fHf2:bFun (length l) fHf3:forall n : nat, nth_error l' n = nth_error l (f n)H:length l <= f (length l')LT:f (length l) < length lbInjective (length l) fA:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l':list Af:nat -> natHf:Injective fHf2:bFun (length l) fHf3:forall n : nat, nth_error l' n = nth_error l (f n)H:length l <= f (length l')LT:f (length l) < length lHf':bInjective (length l) flength l = length l'A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l':list Af:nat -> natHf:Injective fHf2:bFun (length l) fHf3:forall n : nat, nth_error l' n = nth_error l (f n)H:length l <= f (length l')LT:f (length l) < length lbInjective (length l) fnow apply Hf.A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l':list Af:nat -> natHf:Injective fHf2:bFun (length l) fHf3:forall n : nat, nth_error l' n = nth_error l (f n)H:length l <= f (length l')LT:f (length l) < length lx, y:natE:f x = f yx = yA:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l':list Af:nat -> natHf:Injective fHf2:bFun (length l) fHf3:forall n : nat, nth_error l' n = nth_error l (f n)H:length l <= f (length l')LT:f (length l) < length lHf':bInjective (length l) flength l = length l'A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l':list Af:nat -> natHf:Injective fHf2:bFun (length l) fHf3:forall n : nat, nth_error l' n = nth_error l (f n)H:length l <= f (length l')LT:f (length l) < length lHf':bSurjective (length l) flength l = length l'A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l':list Af:nat -> natHf:Injective fHf2:bFun (length l) fHf3:forall n : nat, nth_error l' n = nth_error l (f n)H:length l <= f (length l')LT:f (length l) < length lHf':bSurjective (length l) fy:natHy:y < length lHy':f y = f (length l)length l = length l'A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l':list Af:nat -> natHf:Injective fHf2:bFun (length l) fHf3:forall n : nat, nth_error l' n = nth_error l (f n)H:length l <= f (length l')LT:f (length l) < length lHf':bSurjective (length l) fy:natHy:y < length lHy':y = length llength l = length l'elim (Lt.lt_irrefl _ Hy). Qed.A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l':list Af:nat -> natHf:Injective fHf2:bFun (length l) fHf3:forall n : nat, nth_error l' n = nth_error l (f n)H:length l <= f (length l')LT:f (length l) < length lHf':bSurjective (length l) fHy:length l < length llength l = length l'A:Typeadapt:=fun (f : nat -> nat) (n : nat) => let m := f (S n) in if le_lt_dec m (f 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f : nat -> nat, Injective f -> Injective (adapt f)adapt_ok:forall (a : A) (l1 l2 : list A) (f : nat -> nat), Injective f -> length l1 = f 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (adapt f n)l, l':list Ad:APermutation l l' <-> (let n := length l in length l' = n /\ (exists f : nat -> nat, bFun n f /\ bInjective n f /\ (forall x : nat, x < n -> nth x l' d = nth (f x) l d)))A:Typeadapt:=fun (f : nat -> nat) (n : nat) => let m := f (S n) in if le_lt_dec m (f 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f : nat -> nat, Injective f -> Injective (adapt f)adapt_ok:forall (a : A) (l1 l2 : list A) (f : nat -> nat), Injective f -> length l1 = f 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (adapt f n)l, l':list Ad:APermutation l l' <-> (let n := length l in length l' = n /\ (exists f : nat -> nat, bFun n f /\ bInjective n f /\ (forall x : nat, x < n -> nth x l' d = nth (f x) l d)))A:Typeadapt:=fun (f : nat -> nat) (n : nat) => let m := f (S n) in if le_lt_dec m (f 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f : nat -> nat, Injective f -> Injective (adapt f)adapt_ok:forall (a : A) (l1 l2 : list A) (f : nat -> nat), Injective f -> length l1 = f 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (adapt f n)l, l':list Ad:APermutation l l' -> let n := length l in length l' = n /\ (exists f : nat -> nat, bFun n f /\ bInjective n f /\ (forall x : nat, x < n -> nth x l' d = nth (f x) l d))A:Typeadapt:=fun (f : nat -> nat) (n : nat) => let m := f (S n) in if le_lt_dec m (f 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f : nat -> nat, Injective f -> Injective (adapt f)adapt_ok:forall (a : A) (l1 l2 : list A) (f : nat -> nat), Injective f -> length l1 = f 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (adapt f n)l, l':list Ad:A(let n := length l in length l' = n /\ (exists f : nat -> nat, bFun n f /\ bInjective n f /\ (forall x : nat, x < n -> nth x l' d = nth (f x) l d))) -> Permutation l l'A:Typeadapt:=fun (f : nat -> nat) (n : nat) => let m := f (S n) in if le_lt_dec m (f 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f : nat -> nat, Injective f -> Injective (adapt f)adapt_ok:forall (a : A) (l1 l2 : list A) (f : nat -> nat), Injective f -> length l1 = f 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (adapt f n)l, l':list Ad:APermutation l l' -> let n := length l in length l' = n /\ (exists f : nat -> nat, bFun n f /\ bInjective n f /\ (forall x : nat, x < n -> nth x l' d = nth (f x) l d))A:Typeadapt:=fun (f : nat -> nat) (n : nat) => let m := f (S n) in if le_lt_dec m (f 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f : nat -> nat, Injective f -> Injective (adapt f)adapt_ok:forall (a : A) (l1 l2 : list A) (f : nat -> nat), Injective f -> length l1 = f 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (adapt f n)l, l':list Ad:AH:Permutation l l'let n := length l in length l' = n /\ (exists f : nat -> nat, bFun n f /\ bInjective n f /\ (forall x : nat, x < n -> nth x l' d = nth (f x) l d))A:Typeadapt:=fun (f : nat -> nat) (n : nat) => let m := f (S n) in if le_lt_dec m (f 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f : nat -> nat, Injective f -> Injective (adapt f)adapt_ok:forall (a : A) (l1 l2 : list A) (f : nat -> nat), Injective f -> length l1 = f 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (adapt f n)l, l':list Ad:AH:Permutation l l'E:length l = length l'let n := length l in length l' = n /\ (exists f : nat -> nat, bFun n f /\ bInjective n f /\ (forall x : nat, x < n -> nth x l' d = nth (f x) l d))A:Typeadapt:=fun (f : nat -> nat) (n : nat) => let m := f (S n) in if le_lt_dec m (f 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f : nat -> nat, Injective f -> Injective (adapt f)adapt_ok:forall (a : A) (l1 l2 : list A) (f : nat -> nat), Injective f -> length l1 = f 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (adapt f n)l, l':list Ad:AH:Permutation l l'E:length l = length l'exists f : nat -> nat, bFun (length l) f /\ bInjective (length l) f /\ (forall x : nat, x < length l -> nth x l' d = nth (f x) l d)A:Typeadapt:=fun (f : nat -> nat) (n : nat) => let m := f (S n) in if le_lt_dec m (f 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f : nat -> nat, Injective f -> Injective (adapt f)adapt_ok:forall (a : A) (l1 l2 : list A) (f : nat -> nat), Injective f -> length l1 = f 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (adapt f n)l, l':list Ad:AH:exists f : nat -> nat, Injective f /\ bFun (length l) f /\ (forall n : nat, nth_error l' n = nth_error l (f n))E:length l = length l'exists f : nat -> nat, bFun (length l) f /\ bInjective (length l) f /\ (forall x : nat, x < length l -> nth x l' d = nth (f x) l d)A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l':list Ad:Af:nat -> natHf:Injective fHf2:bFun (length l) fHf3:forall n : nat, nth_error l' n = nth_error l (f n)E:length l = length l'exists f0 : nat -> nat, bFun (length l) f0 /\ bInjective (length l) f0 /\ (forall x : nat, x < length l -> nth x l' d = nth (f0 x) l d)A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l':list Ad:Af:nat -> natHf:Injective fHf2:bFun (length l) fHf3:forall n : nat, nth_error l' n = nth_error l (f n)E:length l = length l'bFun (length l) f /\ bInjective (length l) f /\ (forall x : nat, x < length l -> nth x l' d = nth (f x) l d)A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l':list Ad:Af:nat -> natHf:Injective fHf2:bFun (length l) fHf3:forall n : nat, nth_error l' n = nth_error l (f n)E:length l = length l'bInjective (length l) fA:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l':list Ad:Af:nat -> natHf:Injective fHf2:bFun (length l) fHf3:forall n : nat, nth_error l' n = nth_error l (f n)E:length l = length l'forall x : nat, x < length l -> nth x l' d = nth (f x) l dA:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l':list Ad:Af:nat -> natHf:Injective fHf2:bFun (length l) fHf3:forall n : nat, nth_error l' n = nth_error l (f n)E:length l = length l'x, y:natHxy:f x = f yx = yA:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l':list Ad:Af:nat -> natHf:Injective fHf2:bFun (length l) fHf3:forall n : nat, nth_error l' n = nth_error l (f n)E:length l = length l'forall x : nat, x < length l -> nth x l' d = nth (f x) l dA:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l':list Ad:Af:nat -> natHf:Injective fHf2:bFun (length l) fHf3:forall n : nat, nth_error l' n = nth_error l (f n)E:length l = length l'forall x : nat, x < length l -> nth x l' d = nth (f x) l dA:Typeadapt:=fun (f0 : nat -> nat) (n0 : nat) => let m := f0 (S n0) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n0 : nat, nth_error (l1 ++ a :: l2) (f0 (S n0)) = nth_error (l1 ++ l2) (adapt f0 n0)l, l':list Ad:Af:nat -> natHf:Injective fHf2:bFun (length l) fHf3:forall n0 : nat, nth_error l' n0 = nth_error l (f n0)E:length l = length l'n:natHn:n < length lnth n l' d = nth (f n) l dA:Typeadapt:=fun (f0 : nat -> nat) (n0 : nat) => let m := f0 (S n0) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n0 : nat, nth_error (l1 ++ a :: l2) (f0 (S n0)) = nth_error (l1 ++ l2) (adapt f0 n0)l, l':list Ad:Af:nat -> natHf:Injective fHf2:bFun (length l) fHf3:forall n0 : nat, nth_error l' n0 = nth_error l (f n0)E:length l = length l'n:natHn:n < length lnth_default d l' n = nth_default d l (f n)now rewrite Hf3.A:Typeadapt:=fun (f0 : nat -> nat) (n0 : nat) => let m := f0 (S n0) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n0 : nat, nth_error (l1 ++ a :: l2) (f0 (S n0)) = nth_error (l1 ++ l2) (adapt f0 n0)l, l':list Ad:Af:nat -> natHf:Injective fHf2:bFun (length l) fHf3:forall n0 : nat, nth_error l' n0 = nth_error l (f n0)E:length l = length l'n:natHn:n < length lmatch nth_error l' n with | Some x => x | None => d end = match nth_error l (f n) with | Some x => x | None => d endA:Typeadapt:=fun (f : nat -> nat) (n : nat) => let m := f (S n) in if le_lt_dec m (f 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f : nat -> nat, Injective f -> Injective (adapt f)adapt_ok:forall (a : A) (l1 l2 : list A) (f : nat -> nat), Injective f -> length l1 = f 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f (S n)) = nth_error (l1 ++ l2) (adapt f n)l, l':list Ad:A(let n := length l in length l' = n /\ (exists f : nat -> nat, bFun n f /\ bInjective n f /\ (forall x : nat, x < n -> nth x l' d = nth (f x) l d))) -> Permutation l l'A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l':list Ad:AE:length l' = length lf:nat -> natHf1:bFun (length l) fHf2:bInjective (length l) fHf3:forall x : nat, x < length l -> nth x l' d = nth (f x) l dPermutation l l'A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l':list Ad:AE:length l' = length lf:nat -> natHf1:bFun (length l) fHf2:bInjective (length l) fHf3:forall x : nat, x < length l -> nth x l' d = nth (f x) l dlength l = length l' /\ (exists f0 : nat -> nat, Injective f0 /\ (forall n : nat, nth_error l' n = nth_error l (f0 n)))A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l':list Ad:AE:length l' = length lf:nat -> natHf1:bFun (length l) fHf2:bInjective (length l) fHf3:forall x : nat, x < length l -> nth x l' d = nth (f x) l dexists f0 : nat -> nat, Injective f0 /\ (forall n : nat, nth_error l' n = nth_error l (f0 n))A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l':list Ad:AE:length l' = length lf:nat -> natHf1:bFun (length l) fHf2:bInjective (length l) fHf3:forall x : nat, x < length l -> nth x l' d = nth (f x) l dInjective (fun n : nat => if le_lt_dec (length l) n then n else f n) /\ (forall n : nat, nth_error l' n = nth_error l (if le_lt_dec (length l) n then n else f n))A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l':list Ad:AE:length l' = length lf:nat -> natHf1:bFun (length l) fHf2:bInjective (length l) fHf3:forall x : nat, x < length l -> nth x l' d = nth (f x) l dInjective (fun n : nat => if le_lt_dec (length l) n then n else f n)A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l':list Ad:AE:length l' = length lf:nat -> natHf1:bFun (length l) fHf2:bInjective (length l) fHf3:forall x : nat, x < length l -> nth x l' d = nth (f x) l dforall n : nat, nth_error l' n = nth_error l (if le_lt_dec (length l) n then n else f n)A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l':list Ad:AE:length l' = length lf:nat -> natHf1:bFun (length l) fHf2:bInjective (length l) fHf3:forall x : nat, x < length l -> nth x l' d = nth (f x) l dInjective (fun n : nat => if le_lt_dec (length l) n then n else f n)A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l':list Ad:AE:length l' = length lf:nat -> natHf1:bFun (length l) fHf2:bInjective (length l) fHf3:forall x0 : nat, x0 < length l -> nth x0 l' d = nth (f x0) l dx, y:nat(if le_lt_dec (length l) x then x else f x) = (if le_lt_dec (length l) y then y else f y) -> x = yA:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l':list Ad:AE:length l' = length lf:nat -> natHf1:bFun (length l) fHf2:bInjective (length l) fHf3:forall x0 : nat, x0 < length l -> nth x0 l' d = nth (f x0) l dx, y:natLE:length l <= xLT':y < length lx = f y -> x = yA:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l':list Ad:AE:length l' = length lf:nat -> natHf1:bFun (length l) fHf2:bInjective (length l) fHf3:forall x0 : nat, x0 < length l -> nth x0 l' d = nth (f x0) l dx, y:natLT:x < length lLE':length l <= yf x = y -> x = yA:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l':list Ad:AE:length l' = length lf:nat -> natHf1:bFun (length l) fHf2:bInjective (length l) fHf3:forall x0 : nat, x0 < length l -> nth x0 l' d = nth (f x0) l dx, y:natLE:length l <= xLT':y < length lx = f y -> x = yA:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l':list Ad:AE:length l' = length lf:nat -> natHf1:bFun (length l) fHf2:bInjective (length l) fHf3:forall x0 : nat, x0 < length l -> nth x0 l' d = nth (f x0) l dx, y:natLE:length l <= xLT':f y < length lx = f y -> x = yA:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l':list Ad:AE:length l' = length lf:nat -> natHf1:bFun (length l) fHf2:bInjective (length l) fHf3:forall x : nat, x < length l -> nth x l' d = nth (f x) l dy:natLE:length l <= f yLT':f y < length lf y = yeapply Lt.lt_le_trans; eauto.A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l':list Ad:AE:length l' = length lf:nat -> natHf1:bFun (length l) fHf2:bInjective (length l) fHf3:forall x : nat, x < length l -> nth x l' d = nth (f x) l dy:natLE:length l <= f yLT':f y < length lf y < f yA:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l':list Ad:AE:length l' = length lf:nat -> natHf1:bFun (length l) fHf2:bInjective (length l) fHf3:forall x0 : nat, x0 < length l -> nth x0 l' d = nth (f x0) l dx, y:natLT:x < length lLE':length l <= yf x = y -> x = yA:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l':list Ad:AE:length l' = length lf:nat -> natHf1:bFun (length l) fHf2:bInjective (length l) fHf3:forall x0 : nat, x0 < length l -> nth x0 l' d = nth (f x0) l dx, y:natLT:f x < length lLE':length l <= yf x = y -> x = yA:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l':list Ad:AE:length l' = length lf:nat -> natHf1:bFun (length l) fHf2:bInjective (length l) fHf3:forall x0 : nat, x0 < length l -> nth x0 l' d = nth (f x0) l dx:natLT:f x < length lLE':length l <= f xx = f xeapply Lt.lt_le_trans; eauto.A:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l':list Ad:AE:length l' = length lf:nat -> natHf1:bFun (length l) fHf2:bInjective (length l) fHf3:forall x0 : nat, x0 < length l -> nth x0 l' d = nth (f x0) l dx:natLT:f x < length lLE':length l <= f xf x < f xA:Typeadapt:=fun (f0 : nat -> nat) (n : nat) => let m := f0 (S n) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n : nat, nth_error (l1 ++ a :: l2) (f0 (S n)) = nth_error (l1 ++ l2) (adapt f0 n)l, l':list Ad:AE:length l' = length lf:nat -> natHf1:bFun (length l) fHf2:bInjective (length l) fHf3:forall x : nat, x < length l -> nth x l' d = nth (f x) l dforall n : nat, nth_error l' n = nth_error l (if le_lt_dec (length l) n then n else f n)A:Typeadapt:=fun (f0 : nat -> nat) (n0 : nat) => let m := f0 (S n0) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n0 : nat, nth_error (l1 ++ a :: l2) (f0 (S n0)) = nth_error (l1 ++ l2) (adapt f0 n0)l, l':list Ad:AE:length l' = length lf:nat -> natHf1:bFun (length l) fHf2:bInjective (length l) fHf3:forall x : nat, x < length l -> nth x l' d = nth (f x) l dn:natnth_error l' n = nth_error l (if le_lt_dec (length l) n then n else f n)A:Typeadapt:=fun (f0 : nat -> nat) (n0 : nat) => let m := f0 (S n0) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n0 : nat, nth_error (l1 ++ a :: l2) (f0 (S n0)) = nth_error (l1 ++ l2) (adapt f0 n0)l, l':list Ad:AE:length l' = length lf:nat -> natHf1:bFun (length l) fHf2:bInjective (length l) fHf3:forall x : nat, x < length l -> nth x l' d = nth (f x) l dn:natLE:length l <= nnth_error l' n = nth_error l nA:Typeadapt:=fun (f0 : nat -> nat) (n0 : nat) => let m := f0 (S n0) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n0 : nat, nth_error (l1 ++ a :: l2) (f0 (S n0)) = nth_error (l1 ++ l2) (adapt f0 n0)l, l':list Ad:AE:length l' = length lf:nat -> natHf1:bFun (length l) fHf2:bInjective (length l) fHf3:forall x : nat, x < length l -> nth x l' d = nth (f x) l dn:natLT:n < length lnth_error l' n = nth_error l (f n)A:Typeadapt:=fun (f0 : nat -> nat) (n0 : nat) => let m := f0 (S n0) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n0 : nat, nth_error (l1 ++ a :: l2) (f0 (S n0)) = nth_error (l1 ++ l2) (adapt f0 n0)l, l':list Ad:AE:length l' = length lf:nat -> natHf1:bFun (length l) fHf2:bInjective (length l) fHf3:forall x : nat, x < length l -> nth x l' d = nth (f x) l dn:natLE:length l <= nnth_error l' n = nth_error l nA:Typeadapt:=fun (f0 : nat -> nat) (n0 : nat) => let m := f0 (S n0) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n0 : nat, nth_error (l1 ++ a :: l2) (f0 (S n0)) = nth_error (l1 ++ l2) (adapt f0 n0)l, l':list Ad:AE:length l' = length lf:nat -> natHf1:bFun (length l) fHf2:bInjective (length l) fHf3:forall x : nat, x < length l -> nth x l' d = nth (f x) l dn:natLE:length l <= nLE':length l' <= nnth_error l' n = nth_error l ncongruence.A:Typeadapt:=fun (f0 : nat -> nat) (n0 : nat) => let m := f0 (S n0) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n0 : nat, nth_error (l1 ++ a :: l2) (f0 (S n0)) = nth_error (l1 ++ l2) (adapt f0 n0)l, l':list Ad:AE:length l' = length lf:nat -> natHf1:bFun (length l) fHf2:bInjective (length l) fHf3:forall x : nat, x < length l -> nth x l' d = nth (f x) l dn:natLE:nth_error l n = NoneLE':nth_error l' n = Nonenth_error l' n = nth_error l nA:Typeadapt:=fun (f0 : nat -> nat) (n0 : nat) => let m := f0 (S n0) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n0 : nat, nth_error (l1 ++ a :: l2) (f0 (S n0)) = nth_error (l1 ++ l2) (adapt f0 n0)l, l':list Ad:AE:length l' = length lf:nat -> natHf1:bFun (length l) fHf2:bInjective (length l) fHf3:forall x : nat, x < length l -> nth x l' d = nth (f x) l dn:natLT:n < length lnth_error l' n = nth_error l (f n)A:Typeadapt:=fun (f0 : nat -> nat) (n0 : nat) => let m := f0 (S n0) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n0 : nat, nth_error (l1 ++ a :: l2) (f0 (S n0)) = nth_error (l1 ++ l2) (adapt f0 n0)l, l':list Ad:AE:length l' = length lf:nat -> natHf1:bFun (length l) fHf2:bInjective (length l) fHf3:forall x : nat, x < length l -> nth x l' d = nth (f x) l dn:natLT:n < length lLT':n < length l'nth_error l' n = nth_error l (f n)A:Typeadapt:=fun (f0 : nat -> nat) (n0 : nat) => let m := f0 (S n0) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n0 : nat, nth_error (l1 ++ a :: l2) (f0 (S n0)) = nth_error (l1 ++ l2) (adapt f0 n0)l, l':list Ad:AE:length l' = length lf:nat -> natHf1:bFun (length l) fHf2:bInjective (length l) fn:natHf3:nth n l' d = nth (f n) l dLT:n < length lLT':n < length l'nth_error l' n = nth_error l (f n)A:Typeadapt:=fun (f0 : nat -> nat) (n0 : nat) => let m := f0 (S n0) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n0 : nat, nth_error (l1 ++ a :: l2) (f0 (S n0)) = nth_error (l1 ++ l2) (adapt f0 n0)l, l':list Ad:AE:length l' = length lf:nat -> natHf1:bFun (length l) fHf2:bInjective (length l) fn:natHf3:nth_default d l' n = nth_default d l (f n)LT:n < length lLT':n < length l'nth_error l' n = nth_error l (f n)A:Typeadapt:=fun (f0 : nat -> nat) (n0 : nat) => let m := f0 (S n0) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n0 : nat, nth_error (l1 ++ a :: l2) (f0 (S n0)) = nth_error (l1 ++ l2) (adapt f0 n0)l, l':list Ad:AE:length l' = length lf:nat -> natHf1:bFun (length l) fHf2:bInjective (length l) fn:natHf3:match nth_error l' n with | Some x => x | None => d end = match nth_error l (f n) with | Some x => x | None => d endLT:n < length lLT':n < length l'nth_error l' n = nth_error l (f n)A:Typeadapt:=fun (f0 : nat -> nat) (n0 : nat) => let m := f0 (S n0) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n0 : nat, nth_error (l1 ++ a :: l2) (f0 (S n0)) = nth_error (l1 ++ l2) (adapt f0 n0)l, l':list Ad:AE:length l' = length lf:nat -> natHf1:bFun (length l) fHf2:bInjective (length l) fn:natHf3:match nth_error l' n with | Some x => x | None => d end = match nth_error l (f n) with | Some x => x | None => d endLT:f n < length lLT':n < length l'nth_error l' n = nth_error l (f n)do 2 destruct nth_error; congruence. Qed. End Permutation_alt. (* begin hide *) Notation Permutation_app_swap := Permutation_app_comm (only parsing). (* end hide *)A:Typeadapt:=fun (f0 : nat -> nat) (n0 : nat) => let m := f0 (S n0) in if le_lt_dec m (f0 0) then m else Nat.pred m:(nat -> nat) -> nat -> natadapt_injective:forall f0 : nat -> nat, Injective f0 -> Injective (adapt f0)adapt_ok:forall (a : A) (l1 l2 : list A) (f0 : nat -> nat), Injective f0 -> length l1 = f0 0 -> forall n0 : nat, nth_error (l1 ++ a :: l2) (f0 (S n0)) = nth_error (l1 ++ l2) (adapt f0 n0)l, l':list Ad:AE:length l' = length lf:nat -> natHf1:bFun (length l) fHf2:bInjective (length l) fn:natHf3:match nth_error l' n with | Some x => x | None => d end = match nth_error l (f n) with | Some x => x | None => d endLT:nth_error l (f n) <> NoneLT':nth_error l' n <> Nonenth_error l' n = nth_error l (f n)