Skip to content
This repository was archived by the owner on Jul 24, 2024. It is now read-only.

Commit fc6f57a

Browse files
committed
feat(data/list/basic): list.forall2, list.sections
1 parent 42f5ea0 commit fc6f57a

File tree

1 file changed

+58
-0
lines changed

1 file changed

+58
-0
lines changed

data/list/basic.lean

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1876,6 +1876,64 @@ def transpose : list (list α) → list (list α)
18761876
| [] := []
18771877
| (l::ls) := transpose_aux l (transpose ls)
18781878

1879+
/- forall₂ -/
1880+
1881+
inductive forall₂ (R : α → β → Prop) : list α → list β → Prop
1882+
| nil : forall₂ [] []
1883+
| cons {a b l₁ l₂} : R a b → forall₂ l₁ l₂ → forall₂ (a::l₁) (b::l₂)
1884+
1885+
attribute [simp] forall₂.nil
1886+
1887+
@[simp] theorem forall₂_cons {R : α → β → Prop} {a b l₁ l₂} :
1888+
forall₂ R (a::l₁) (b::l₂) ↔ R a b ∧ forall₂ R l₁ l₂ :=
1889+
⟨λ h, by cases h with h₁ h₂; simp *, λ ⟨h₁, h₂⟩, forall₂.cons h₁ h₂⟩
1890+
1891+
@[simp] theorem forall₂_nil_left {R : α → β → Prop} {a l} : ¬ forall₂ R [] (a::l).
1892+
1893+
@[simp] theorem forall₂_nil_right {R : α → β → Prop} {a l} : ¬ forall₂ R (a::l) [].
1894+
1895+
theorem forall₂_length_eq {R : α → β → Prop} :
1896+
∀ {l₁ l₂}, forall₂ R l₁ l₂ → length l₁ = length l₂
1897+
| _ _ (forall₂.nil _) := rfl
1898+
| _ _ (forall₂.cons h₁ h₂) := congr_arg succ (forall₂_length_eq h₂)
1899+
1900+
theorem forall₂_zip {R : α → β → Prop} :
1901+
∀ {l₁ l₂}, forall₂ R l₁ l₂ → ∀ {a b}, (a, b) ∈ zip l₁ l₂ → R a b
1902+
| _ _ (forall₂.cons h₁ h₂) x y (or.inl rfl) := h₁
1903+
| _ _ (forall₂.cons h₁ h₂) x y (or.inr h₃) := forall₂_zip h₂ h₃
1904+
1905+
theorem forall₂_iff_zip {R : α → β → Prop} {l₁ l₂} : forall₂ R l₁ l₂ ↔
1906+
length l₁ = length l₂ ∧ ∀ {a b}, (a, b) ∈ zip l₁ l₂ → R a b :=
1907+
⟨λ h, ⟨forall₂_length_eq h, @forall₂_zip _ _ _ _ _ h⟩,
1908+
λ h, begin
1909+
cases h with h₁ h₂,
1910+
induction l₁ with a l₁ IH generalizing l₂,
1911+
{ simp [length_eq_zero.1 h₁.symm] },
1912+
{ cases l₂ with b l₂; injection h₁ with h₁,
1913+
exact forall₂.cons (h₂ $ or.inl rfl) (IH h₁ $ λ a b h, h₂ $ or.inr h) }
1914+
end
1915+
1916+
/- sections -/
1917+
1918+
/-- List of all sections through a list of lists. A section
1919+
of `[L₁, L₂, ..., Lₙ]` is a list whose first element comes from
1920+
`L₁`, whose second element comes from `L₂`, and so on. -/
1921+
def sections : list (list α) → list (list α)
1922+
| [] := [[]]
1923+
| (l::L) := bind (sections L) $ λ s, map (λ a, a::s) l
1924+
1925+
theorem mem_sections {L : list (list α)} {f} : f ∈ sections L ↔ forall₂ (∈) f L :=
1926+
begin
1927+
refine ⟨λ h, _, λ h, _⟩,
1928+
{ induction L generalizing f; simp [sections] at h;
1929+
casesm* [Exists _, _ ∧ _, _ = _]; simp * },
1930+
{ induction h with a l f L al fL fs; simp [sections],
1931+
exact ⟨_, fs, _, al, rfl, rfl⟩ }
1932+
end
1933+
1934+
theorem mem_sections_length {L : list (list α)} {f} (h : f ∈ sections L) : length f = length L :=
1935+
forall₂_length_eq (mem_sections.1 h)
1936+
18791937
/- permutations -/
18801938

18811939
section permutations

0 commit comments

Comments
 (0)