File: Mathlib/Data/List/Chain.lean

full_name: List.Chain.iff
code: theorem Chain.iff {S : α → α → Prop} (H : ∀ a b, R a b ↔ S a b) {a : α} {l : List α} :
    Chain R a l ↔ Chain S a l 
goal: List.Chain R a l ↔ List.Chain S a l

full_name: List.Chain.iff_mem
code: theorem Chain.iff_mem {a : α} {l : List α} :
    Chain R a l ↔ Chain (fun x y => x ∈ a :: l ∧ y ∈ l ∧ R x y) a l 
goal: List.Chain R a l ↔ List.Chain (fun x y => x ∈ a :: l ∧ y ∈ l ∧ R x y) a l

full_name: List.chain_singleton
code: theorem chain_singleton {a b : α} : Chain R a [b] ↔ R a b 
goal: List.Chain R a [b] ↔ R a b

full_name: List.chain_split
code: theorem chain_split {a b : α} {l₁ l₂ : List α} :
    Chain R a (l₁ ++ b :: l₂) ↔ Chain R a (l₁ ++ [b]) ∧ Chain R b l₂ 
goal: List.Chain R a (l₁ ++ b :: l₂) ↔ List.Chain R a (l₁ ++ [b]) ∧ List.Chain R b l₂

full_name: List.chain_append_cons_cons
code: @[simp]
theorem chain_append_cons_cons {a b c : α} {l₁ l₂ : List α} :
    Chain R a (l₁ ++ b :: c :: l₂) ↔ Chain R a (l₁ ++ [b]) ∧ R b c ∧ Chain R c l₂ 
goal: List.Chain R a (l₁ ++ b :: c :: l₂) ↔ List.Chain R a (l₁ ++ [b]) ∧ R b c ∧ List.Chain R c l₂

full_name: List.chain_iff_forall₂
code: theorem chain_iff_forall₂ :
    ∀ {a : α} {l : List α}, Chain R a l ↔ l = [] ∨ Forall₂ R (a :: dropLast l) l
  
goal: List.Chain R a l ↔ l = [] ∨ List.Forall₂ R (a :: l.dropLast) l

full_name: List.chain_append_singleton_iff_forall₂
code: theorem chain_append_singleton_iff_forall₂ :
    Chain R a (l ++ [b]) ↔ Forall₂ R (a :: l) (l ++ [b]) 
goal: List.Chain R a (l ++ [b]) ↔ List.Forall₂ R (a :: l) (l ++ [b])

full_name: List.chain_map
code: theorem chain_map (f : β → α) {b : β} {l : List β} :
    Chain R (f b) (map f l) ↔ Chain (fun a b : β => R (f a) (f b)) b l 
goal: List.Chain R (f b) (List.map f l) ↔ List.Chain (fun a b => R (f a) (f b)) b l

full_name: List.chain_of_chain_map
code: theorem chain_of_chain_map {S : β → β → Prop} (f : α → β) (H : ∀ a b : α, S (f a) (f b) → R a b)
    {a : α} {l : List α} (p : Chain S (f a) (map f l)) : Chain R a l 
goal: List.Chain R a l

full_name: List.chain_map_of_chain
code: theorem chain_map_of_chain {S : β → β → Prop} (f : α → β) (H : ∀ a b : α, R a b → S (f a) (f b))
    {a : α} {l : List α} (p : Chain R a l) : Chain S (f a) (map f l) 
goal: List.Chain S (f a) (List.map f l)

full_name: List.chain_pmap_of_chain
code: theorem chain_pmap_of_chain {S : β → β → Prop} {p : α → Prop} {f : ∀ a, p a → β}
    (H : ∀ a b ha hb, R a b → S (f a ha) (f b hb)) {a : α} {l : List α} (hl₁ : Chain R a l)
    (ha : p a) (hl₂ : ∀ a ∈ l, p a) : Chain S (f a ha) (List.pmap f l hl₂) 
goal: List.Chain S (f a ha) (List.pmap f l hl₂)

full_name: List.chain_of_chain_pmap
code: theorem chain_of_chain_pmap {S : β → β → Prop} {p : α → Prop} (f : ∀ a, p a → β) {l : List α}
    (hl₁ : ∀ a ∈ l, p a) {a : α} (ha : p a) (hl₂ : Chain S (f a ha) (List.pmap f l hl₁))
    (H : ∀ a b ha hb, S (f a ha) (f b hb) → R a b) : Chain R a l 
goal: List.Chain R a l

full_name: List.Chain.pairwise
code: protected theorem Chain.pairwise [IsTrans α R] :
    ∀ {a : α} {l : List α}, Chain R a l → Pairwise R (a :: l)
  
goal: List.Chain R a l → List.Pairwise R (a :: l)

full_name: List.chain_iff_pairwise
code: theorem chain_iff_pairwise [IsTrans α R] {a : α} {l : List α} : Chain R a l ↔ Pairwise R (a :: l) 
goal: List.Chain R a l ↔ List.Pairwise R (a :: l)

full_name: List.Chain.sublist
code: protected theorem Chain.sublist [IsTrans α R] (hl : l₂.Chain R a) (h : l₁ <+ l₂) :
    l₁.Chain R a 
goal: List.Chain R a l₁

full_name: List.Chain.rel
code: protected theorem Chain.rel [IsTrans α R] (hl : l.Chain R a) (hb : b ∈ l) : R a b 
goal: R a b

full_name: List.chain_iff_get
code: theorem chain_iff_get {R} : ∀ {a : α} {l : List α}, Chain R a l ↔
    (∀ h : 0 < length l, R a (get l ⟨0, h⟩)) ∧
      ∀ (i : ℕ) (h : i < l.length - 1),
        R (get l ⟨i, by omega⟩) (get l ⟨i+1, by omega⟩)
  
goal: List.Chain R a l ↔
  (∀ (h : 0 < l.length), R a (l.get ⟨0, h⟩)) ∧ ∀ (i : ℕ) (h : i < l.length - 1), R (l.get ⟨i, ⋯⟩) (l.get ⟨i + 1, ⋯⟩)

full_name: List.Chain'.imp
code: theorem Chain'.imp {S : α → α → Prop} (H : ∀ a b, R a b → S a b) {l : List α} (p : Chain' R l) :
    Chain' S l 
goal: List.Chain' S l

full_name: List.Chain'.iff
code: theorem Chain'.iff {S : α → α → Prop} (H : ∀ a b, R a b ↔ S a b) {l : List α} :
    Chain' R l ↔ Chain' S l 
goal: List.Chain' R l ↔ List.Chain' S l

full_name: List.Chain'.iff_mem
code: theorem Chain'.iff_mem : ∀ {l : List α}, Chain' R l ↔ Chain' (fun x y => x ∈ l ∧ y ∈ l ∧ R x y) l
  
goal: List.Chain' R l ↔ List.Chain' (fun x y => x ∈ l ∧ y ∈ l ∧ R x y) l

full_name: List.chain'_nil
code: @[simp]
theorem chain'_nil : Chain' R [] 
goal: List.Chain' R []

full_name: List.chain'_singleton
code: @[simp]
theorem chain'_singleton (a : α) : Chain' R [a] 
goal: List.Chain' R [a]

full_name: List.chain'_cons
code: @[simp]
theorem chain'_cons {x y l} : Chain' R (x :: y :: l) ↔ R x y ∧ Chain' R (y :: l) 
goal: List.Chain' R (x :: y :: l) ↔ R x y ∧ List.Chain' R (y :: l)

full_name: List.chain'_isInfix
code: theorem chain'_isInfix : ∀ l : List α, Chain' (fun x y => [x, y] <:+: l) l
  
goal: List.Chain' (fun x y => [x, y] <:+: l) l

full_name: List.chain'_split
code: theorem chain'_split {a : α} :
    ∀ {l₁ l₂ : List α}, Chain' R (l₁ ++ a :: l₂) ↔ Chain' R (l₁ ++ [a]) ∧ Chain' R (a :: l₂)
  
goal: List.Chain' R (l₁ ++ a :: l₂) ↔ List.Chain' R (l₁ ++ [a]) ∧ List.Chain' R (a :: l₂)

full_name: List.chain'_append_cons_cons
code: @[simp]
theorem chain'_append_cons_cons {b c : α} {l₁ l₂ : List α} :
    Chain' R (l₁ ++ b :: c :: l₂) ↔ Chain' R (l₁ ++ [b]) ∧ R b c ∧ Chain' R (c :: l₂) 
goal: List.Chain' R (l₁ ++ b :: c :: l₂) ↔ List.Chain' R (l₁ ++ [b]) ∧ R b c ∧ List.Chain' R (c :: l₂)

full_name: List.chain'_map
code: theorem chain'_map (f : β → α) {l : List β} :
    Chain' R (map f l) ↔ Chain' (fun a b : β => R (f a) (f b)) l 
goal: List.Chain' R (List.map f l) ↔ List.Chain' (fun a b => R (f a) (f b)) l

full_name: List.chain'_of_chain'_map
code: theorem chain'_of_chain'_map {S : β → β → Prop} (f : α → β) (H : ∀ a b : α, S (f a) (f b) → R a b)
    {l : List α} (p : Chain' S (map f l)) : Chain' R l 
goal: List.Chain' R l

full_name: List.chain'_map_of_chain'
code: theorem chain'_map_of_chain' {S : β → β → Prop} (f : α → β) (H : ∀ a b : α, R a b → S (f a) (f b))
    {l : List α} (p : Chain' R l) : Chain' S (map f l) 
goal: List.Chain' S (List.map f l)

full_name: List.Pairwise.chain'
code: theorem Pairwise.chain' : ∀ {l : List α}, Pairwise R l → Chain' R l
  
goal: List.Pairwise R l → List.Chain' R l

full_name: List.chain'_iff_pairwise
code: theorem chain'_iff_pairwise [IsTrans α R] : ∀ {l : List α}, Chain' R l ↔ Pairwise R l
  
goal: List.Chain' R l ↔ List.Pairwise R l

full_name: List.Chain'.sublist
code: protected theorem Chain'.sublist [IsTrans α R] (hl : l₂.Chain' R) (h : l₁ <+ l₂) : l₁.Chain' R 
goal: List.Chain' R l₁

full_name: List.Chain'.cons
code: theorem Chain'.cons {x y l} (h₁ : R x y) (h₂ : Chain' R (y :: l)) : Chain' R (x :: y :: l) 
goal: List.Chain' R (x :: y :: l)

full_name: List.Chain'.tail
code: theorem Chain'.tail : ∀ {l}, Chain' R l → Chain' R l.tail
  
goal: List.Chain' R l → List.Chain' R l.tail

full_name: List.Chain'.rel_head
code: theorem Chain'.rel_head {x y l} (h : Chain' R (x :: y :: l)) : R x y 
goal: R x y

full_name: List.Chain'.rel_head?
code: theorem Chain'.rel_head? {x l} (h : Chain' R (x :: l)) ⦃y⦄ (hy : y ∈ head? l) : R x y 
goal: R x y

full_name: List.Chain'.cons'
code: theorem Chain'.cons' {x} : ∀ {l : List α}, Chain' R l → (∀ y ∈ l.head?, R x y) → Chain' R (x :: l)
  
goal: List.Chain' R l → (∀ (y : α), y ∈ l.head? → R x y) → List.Chain' R (x :: l)

full_name: List.chain'_cons'
code: theorem chain'_cons' {x l} : Chain' R (x :: l) ↔ (∀ y ∈ head? l, R x y) ∧ Chain' R l 
goal: List.Chain' R (x :: l) ↔ (∀ (y : α), y ∈ l.head? → R x y) ∧ List.Chain' R l

full_name: List.chain'_append
code: theorem chain'_append :
    ∀ {l₁ l₂ : List α},
      Chain' R (l₁ ++ l₂) ↔ Chain' R l₁ ∧ Chain' R l₂ ∧ ∀ x ∈ l₁.getLast?, ∀ y ∈ l₂.head?, R x y
  
goal: List.Chain' R (l₁ ++ l₂) ↔
  List.Chain' R l₁ ∧ List.Chain' R l₂ ∧ ∀ (x : α), x ∈ l₁.getLast? → ∀ (y : α), y ∈ l₂.head? → R x y

full_name: List.Chain'.append
code: theorem Chain'.append (h₁ : Chain' R l₁) (h₂ : Chain' R l₂)
    (h : ∀ x ∈ l₁.getLast?, ∀ y ∈ l₂.head?, R x y) : Chain' R (l₁ ++ l₂) 
goal: List.Chain' R (l₁ ++ l₂)

full_name: List.Chain'.left_of_append
code: theorem Chain'.left_of_append (h : Chain' R (l₁ ++ l₂)) : Chain' R l₁ 
goal: List.Chain' R l₁

full_name: List.Chain'.right_of_append
code: theorem Chain'.right_of_append (h : Chain' R (l₁ ++ l₂)) : Chain' R l₂ 
goal: List.Chain' R l₂

full_name: List.Chain'.infix
code: theorem Chain'.infix (h : Chain' R l) (h' : l₁ <:+: l) : Chain' R l₁ 
goal: List.Chain' R l₁

full_name: List.Chain'.suffix
code: theorem Chain'.suffix (h : Chain' R l) (h' : l₁ <:+ l) : Chain' R l₁ 
goal: List.Chain' R l₁

full_name: List.Chain'.prefix
code: theorem Chain'.prefix (h : Chain' R l) (h' : l₁ <+: l) : Chain' R l₁ 
goal: List.Chain' R l₁

full_name: List.Chain'.drop
code: theorem Chain'.drop (h : Chain' R l) (n : ℕ) : Chain' R (drop n l) 
goal: List.Chain' R (List.drop n l)

full_name: List.Chain'.init
code: theorem Chain'.init (h : Chain' R l) : Chain' R l.dropLast 
goal: List.Chain' R l.dropLast

full_name: List.Chain'.take
code: theorem Chain'.take (h : Chain' R l) (n : ℕ) : Chain' R (take n l) 
goal: List.Chain' R (List.take n l)

full_name: List.chain'_pair
code: theorem chain'_pair {x y} : Chain' R [x, y] ↔ R x y 
goal: List.Chain' R [x, y] ↔ R x y

full_name: List.Chain'.imp_head
code: theorem Chain'.imp_head {x y} (h : ∀ {z}, R x z → R y z) {l} (hl : Chain' R (x :: l)) :
    Chain' R (y :: l) 
goal: List.Chain' R (y :: l)

full_name: List.chain'_reverse
code: theorem chain'_reverse : ∀ {l}, Chain' R (reverse l) ↔ Chain' (flip R) l
  
goal: List.Chain' R l.reverse ↔ List.Chain' (flip R) l

full_name: List.chain'_iff_get
code: theorem chain'_iff_get {R} : ∀ {l : List α}, Chain' R l ↔
    ∀ (i : ℕ) (h : i < length l - 1),
      R (get l ⟨i, by omega⟩) (get l ⟨i + 1, by omega⟩)
  
goal: List.Chain' R l ↔ ∀ (i : ℕ) (h : i < l.length - 1), R (l.get ⟨i, ⋯⟩) (l.get ⟨i + 1, ⋯⟩)

full_name: List.Chain'.append_overlap
code: /-- If `l₁ l₂` and `l₃` are lists and `l₁ ++ l₂` and `l₂ ++ l₃` both satisfy
  `Chain' R`, then so does `l₁ ++ l₂ ++ l₃` provided `l₂ ≠ []` -/
theorem Chain'.append_overlap {l₁ l₂ l₃ : List α} (h₁ : Chain' R (l₁ ++ l₂))
    (h₂ : Chain' R (l₂ ++ l₃)) (hn : l₂ ≠ []) : Chain' R (l₁ ++ l₂ ++ l₃) 
goal: List.Chain' R (l₁ ++ l₂ ++ l₃)

full_name: List.chain'_join
code: lemma chain'_join : ∀ {L : List (List α)}, [] ∉ L →
    (Chain' R L.join ↔ (∀ l ∈ L, Chain' R l) ∧
    L.Chain' (fun l₁ l₂ => ∀ᵉ (x ∈ l₁.getLast?) (y ∈ l₂.head?), R x y))

goal: ¬[] ∈ L →
  (List.Chain' R L.join ↔
    (∀ (l : List α), l ∈ L → List.Chain' R l) ∧
      List.Chain' (fun l₁ l₂ => ∀ (x : α), x ∈ l₁.getLast? → ∀ (y : α), y ∈ l₂.head? → R x y) L)

full_name: List.exists_chain_of_relationReflTransGen
code: /-- If `a` and `b` are related by the reflexive transitive closure of `r`, then there is an
`r`-chain starting from `a` and ending on `b`.
The converse of `relationReflTransGen_of_exists_chain`.
-/
theorem exists_chain_of_relationReflTransGen (h : Relation.ReflTransGen r a b) :
    ∃ l, Chain r a l ∧ getLast (a :: l) (cons_ne_nil _ _) = b 
goal: ∃ l, List.Chain r a l ∧ (a :: l).getLast ⋯ = b

full_name: List.Chain.induction
code: /-- Given a chain from `a` to `b`, and a predicate true at `b`, if `r x y → p y → p x` then
the predicate is true everywhere in the chain and at `a`.
That is, we can propagate the predicate up the chain.
-/
theorem Chain.induction (p : α → Prop) (l : List α) (h : Chain r a l)
    (hb : getLast (a :: l) (cons_ne_nil _ _) = b) (carries : ∀ ⦃x y : α⦄, r x y → p y → p x)
    (final : p b) : ∀ i ∈ a :: l, p i 
goal: i ∈ a :: l → p i

full_name: List.Chain.induction_head
code: /-- Given a chain from `a` to `b`, and a predicate true at `b`, if `r x y → p y → p x` then
the predicate is true at `a`.
That is, we can propagate the predicate all the way up the chain.
-/
@[elab_as_elim]
theorem Chain.induction_head (p : α → Prop) (l : List α) (h : Chain r a l)
    (hb : getLast (a :: l) (cons_ne_nil _ _) = b) (carries : ∀ ⦃x y : α⦄, r x y → p y → p x)
    (final : p b) : p a 
goal: p a

full_name: List.relationReflTransGen_of_exists_chain
code: /--
If there is an `r`-chain starting from `a` and ending at `b`, then `a` and `b` are related by the
reflexive transitive closure of `r`. The converse of `exists_chain_of_relationReflTransGen`.
-/
theorem relationReflTransGen_of_exists_chain (l : List α) (hl₁ : Chain r a l)
    (hl₂ : getLast (a :: l) (cons_ne_nil _ _) = b) : Relation.ReflTransGen r a b 
goal: Relation.ReflTransGen r a b

full_name: List.Chain'.cons_of_le
code: theorem Chain'.cons_of_le [LinearOrder α] {a : α} {as m : List α}
    (ha : List.Chain' (· > ·) (a :: as)) (hm : List.Chain' (· > ·) m) (hmas : m ≤ as) :
    List.Chain' (· > ·) (a :: m) 
goal: List.Chain' (fun x x_1 => x > x_1) (a :: m)

full_name: List.chains
code: /-- The type of `r`-decreasing chains -/
abbrev List.chains 
goal: Type u_1

full_name: List.lex_chains
code: /-- The lexicographic order on the `r`-decreasing chains -/
abbrev List.lex_chains (l m : List.chains r) : Prop 
goal: Prop

full_name: Acc.list_chain'
code: /-- If an `r`-decreasing chain `l` is empty or its head is accessible by `r`, then
  `l` is accessible by the lexicographic order `List.Lex r`. -/
theorem Acc.list_chain' {l : List.chains r} (acc : ∀ a ∈ l.val.head?, Acc r a) :
    Acc (List.lex_chains r) l 
goal: Acc (List.lex_chains r) l

full_name: WellFounded.list_chain'
code: /-- If `r` is well-founded, the lexicographic order on `r`-decreasing chains is also. -/
theorem WellFounded.list_chain' (hwf : WellFounded r) :
    WellFounded (List.lex_chains r) 
goal: WellFounded (List.lex_chains r)

full_name: instIsWellFoundedChainsLex_chains
code: instance [hwf : IsWellFounded α r] :
    IsWellFounded (List.chains r) (List.lex_chains r) 
goal: IsWellFounded (List.chains r) (List.lex_chains r)