@@ -1876,6 +1876,64 @@ def transpose : list (list α) → list (list α)
1876
1876
| [] := []
1877
1877
| (l::ls) := transpose_aux l (transpose ls)
1878
1878
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
+
1879
1937
/- permutations -/
1880
1938
1881
1939
section permutations
0 commit comments