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

Commit 1d7f479

Browse files
feat(data/set/basic): Add set.nontrivial predicate and API (#15867)
Analogously to the existing `set.subsingleton`, we add `set.nontrivial` and the corresponding API. This allows for dot notation to be used for `set.nontrivial` (which is equivalent to ¬ `set.subsingleton`). We also make some small changes to `set.subsingleton`, mostly style tweaks, a rename, and a missing lemma. Co-authored-by: Wrenna Robson <34025592+linesthatinterlace@users.noreply.github.com>
1 parent c239c99 commit 1d7f479

File tree

1 file changed

+140
-9
lines changed

1 file changed

+140
-9
lines changed

src/data/set/basic.lean

Lines changed: 140 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ Definitions in the file:
4040
4141
* `subsingleton s : Prop` : the predicate saying that `s` has at most one element.
4242
43+
* `nontrivial s : Prop` : the predicate saying that `s` has at least two distinct elements.
44+
4345
* `range f : set β` : the image of `univ` under `f`.
4446
Also works for `{p : Prop} (f : p → α)` (unlike `image`)
4547
@@ -247,14 +249,6 @@ mt $ mem_of_subset_of_mem h
247249

248250
theorem not_subset : (¬ s ⊆ t) ↔ ∃a ∈ s, a ∉ t := by simp only [subset_def, not_forall]
249251

250-
theorem nontrivial_mono {α : Type*} {s t : set α} (h₁ : s ⊆ t) (h₂ : nontrivial s) :
251-
nontrivial t :=
252-
begin
253-
rw nontrivial_iff at h₂ ⊢,
254-
obtain ⟨⟨x, hx⟩, ⟨y, hy⟩, hxy⟩ := h₂,
255-
exact ⟨⟨x, h₁ hx⟩, ⟨y, h₁ hy⟩, by simpa using hxy⟩,
256-
end
257-
258252
/-! ### Definition of strict subsets `s ⊂ t` and basic properties. -/
259253

260254
protected theorem eq_or_ssubset_of_subset (h : s ⊆ t) : s = t ∨ s ⊂ t :=
@@ -453,7 +447,7 @@ by simp [subset_def]
453447
lemma univ_unique [unique α] : @set.univ α = {default} :=
454448
set.ext $ λ x, iff_of_true trivial $ subsingleton.elim x default
455449

456-
instance [nonempty α] : nontrivial (set α) := ⟨⟨∅, univ, empty_ne_univ⟩⟩
450+
instance nontrivial_of_nonempty [nonempty α] : nontrivial (set α) := ⟨⟨∅, univ, empty_ne_univ⟩⟩
457451

458452
/-! ### Lemmas about union -/
459453

@@ -1778,6 +1772,143 @@ theorem subsingleton_of_image {α β : Type*} {f : α → β} (hf : function.inj
17781772
(s : set α) (hs : (f '' s).subsingleton) : s.subsingleton :=
17791773
(hs.preimage hf).mono $ subset_preimage_image _ _
17801774

1775+
/-! ### Nontrivial -/
1776+
1777+
/-- A set `s` is `nontrivial` if it has at least two distinct elements. -/
1778+
protected def nontrivial (s : set α) : Prop := ∃ x y ∈ s, x ≠ y
1779+
1780+
lemma nontrivial_of_mem_mem_ne {x y} (hx : x ∈ s) (hy : y ∈ s) (hxy : x ≠ y) : s.nontrivial :=
1781+
⟨x, hx, y, hy, hxy⟩
1782+
1783+
/-- Extract witnesses from s.nontrivial. This function might be used instead of case analysis on the
1784+
argument. Note that it makes a proof depend on the classical.choice axiom. -/
1785+
protected noncomputable def nontrivial.some (hs : s.nontrivial) : α × α :=
1786+
(hs.some, hs.some_spec.some_spec.some)
1787+
1788+
protected lemma nontrivial.some_fst_mem (hs : s.nontrivial) : hs.some.fst ∈ s := hs.some_spec.some
1789+
1790+
protected lemma nontrivial.some_snd_mem (hs : s.nontrivial) : hs.some.snd ∈ s :=
1791+
hs.some_spec.some_spec.some_spec.some
1792+
1793+
protected lemma nontrivial.some_fst_ne_some_snd (hs : s.nontrivial) : hs.some.fst ≠ hs.some.snd :=
1794+
hs.some_spec.some_spec.some_spec.some_spec
1795+
1796+
lemma nontrivial.mono (hs : s.nontrivial) (hst : s ⊆ t) : t.nontrivial :=
1797+
let ⟨x, hx, y, hy, hxy⟩ := hs in ⟨x, hst hx, y, hst hy, hxy⟩
1798+
1799+
lemma nontrivial_pair {x y} (hxy : x ≠ y) : ({x, y} : set α).nontrivial :=
1800+
⟨x, mem_insert _ _, y, mem_insert_of_mem _ (mem_singleton _), hxy⟩
1801+
1802+
lemma nontrivial_of_pair_subset {x y} (hxy : x ≠ y) (h : {x, y} ⊆ s) : s.nontrivial :=
1803+
(nontrivial_pair hxy).mono h
1804+
1805+
lemma nontrivial.pair_subset (hs : s.nontrivial) : ∃ x y (hab : x ≠ y), {x, y} ⊆ s :=
1806+
let ⟨x, hx, y, hy, hxy⟩ := hs in ⟨x, y, hxy, insert_subset.2 ⟨hx, (singleton_subset_iff.2 hy)⟩⟩
1807+
1808+
lemma nontrivial_iff_pair_subset : s.nontrivial ↔ ∃ x y (hxy : x ≠ y), {x, y} ⊆ s :=
1809+
⟨nontrivial.pair_subset, λ H, let ⟨x, y, hxy, h⟩ := H in nontrivial_of_pair_subset hxy h⟩
1810+
1811+
lemma nontrivial_of_exists_ne {x} (hx : x ∈ s) (h : ∃ y ∈ s, y ≠ x) : s.nontrivial :=
1812+
let ⟨y, hy, hyx⟩ := h in ⟨y, hy, x, hx, hyx⟩
1813+
1814+
lemma nontrivial.exists_ne {z} (hs : s.nontrivial) : ∃ x ∈ s, x ≠ z :=
1815+
begin
1816+
by_contra H, push_neg at H,
1817+
rcases hs with ⟨x, hx, y, hy, hxy⟩,
1818+
rw [H x hx, H y hy] at hxy,
1819+
exact hxy rfl
1820+
end
1821+
1822+
lemma nontrivial_iff_exists_ne {x} (hx : x ∈ s) : s.nontrivial ↔ ∃ y ∈ s, y ≠ x :=
1823+
⟨λ H, H.exists_ne, nontrivial_of_exists_ne hx⟩
1824+
1825+
lemma nontrivial_of_lt [preorder α] {x y} (hx : x ∈ s) (hy : y ∈ s) (hxy : x < y) : s.nontrivial :=
1826+
⟨x, hx, y, hy, ne_of_lt hxy⟩
1827+
1828+
lemma nontrivial_of_exists_lt [preorder α] (H : ∃ x y ∈ s, x < y) : s.nontrivial :=
1829+
let ⟨x, hx, y, hy, hxy⟩ := H in nontrivial_of_lt hx hy hxy
1830+
1831+
lemma nontrivial.exists_lt [linear_order α] (hs : s.nontrivial) : ∃ x y ∈ s, x < y :=
1832+
let ⟨x, hx, y, hy, hxy⟩ := hs in
1833+
or.elim (lt_or_gt_of_ne hxy) (λ H, ⟨x, hx, y, hy, H⟩) (λ H, ⟨y, hy, x, hx, H⟩)
1834+
1835+
lemma nontrivial.iff_exists_lt [linear_order α] : s.nontrivial ↔ ∃ x y ∈ s, x < y :=
1836+
⟨nontrivial.exists_lt, nontrivial_of_exists_lt⟩
1837+
1838+
lemma nontrivial.nonempty (hs : s.nontrivial) : s.nonempty := let ⟨x, hx, _⟩ := hs in ⟨x, hx⟩
1839+
1840+
lemma nontrivial.ne_empty (hs : s.nontrivial) : s ≠ ∅ := hs.nonempty.ne_empty
1841+
1842+
lemma nontrivial.not_subset_empty (hs : s.nontrivial) : ¬ s ⊆ ∅ := hs.nonempty.not_subset_empty
1843+
1844+
@[simp] lemma not_nontrivial_empty : ¬ (∅ : set α).nontrivial := λ h, h.ne_empty rfl
1845+
1846+
@[simp] lemma not_nontrivial_singleton {x} : ¬ ({x} : set α).nontrivial :=
1847+
λ H, begin
1848+
rw nontrivial_iff_exists_ne (mem_singleton x) at H,
1849+
exact let ⟨y, hy, hya⟩ := H in hya (mem_singleton_iff.1 hy)
1850+
end
1851+
1852+
lemma nontrivial.ne_singleton {x} (hs : s.nontrivial) : s ≠ {x} :=
1853+
λ H, by { rw H at hs, exact not_nontrivial_singleton hs }
1854+
1855+
lemma nontrivial.not_subset_singleton {x} (hs : s.nontrivial) : ¬ s ⊆ {x} :=
1856+
(not_congr subset_singleton_iff_eq).2 (not_or hs.ne_empty hs.ne_singleton)
1857+
1858+
lemma nontrivial_univ [nontrivial α] : (univ : set α).nontrivial :=
1859+
let ⟨x, y, hxy⟩ := exists_pair_ne α in ⟨x, mem_univ _, y, mem_univ _, hxy⟩
1860+
1861+
lemma nontrivial_of_univ_nontrivial (h : (univ : set α).nontrivial) : nontrivial α :=
1862+
let ⟨x, _, y, _, hxy⟩ := h in ⟨⟨x, y, hxy⟩⟩
1863+
1864+
@[simp] lemma nontrivial_univ_iff : (univ : set α).nontrivial ↔ nontrivial α :=
1865+
⟨nontrivial_of_univ_nontrivial, λ h, @nontrivial_univ _ h⟩
1866+
1867+
lemma nontrivial_of_nontrivial (hs : s.nontrivial) : nontrivial α :=
1868+
let ⟨x, _, y, _, hxy⟩ := hs in ⟨⟨x, y, hxy⟩⟩
1869+
1870+
/-- `s`, coerced to a type, is a nontrivial type if and only if `s` is a nontrivial set. -/
1871+
@[simp, norm_cast] lemma nontrivial_coe (s : set α) : nontrivial s ↔ s.nontrivial :=
1872+
by simp_rw [← nontrivial_univ_iff, set.nontrivial, mem_univ,
1873+
exists_true_left, set_coe.exists, subtype.mk_eq_mk]
1874+
1875+
/-- A type with a set `s` whose `coe_sort` is a nontrivial type is nontrivial.
1876+
For the corresponding result for `subtype`, see `subtype.nontrivial_iff_exists_ne`. -/
1877+
lemma nontrivial_of_nontrivial_coe (hs : nontrivial s) : nontrivial α :=
1878+
by { rw [s.nontrivial_coe] at hs, exact nontrivial_of_nontrivial hs }
1879+
1880+
theorem nontrivial_mono {α : Type*} {s t : set α} (hst : s ⊆ t) (hs : nontrivial s) :
1881+
nontrivial t := (nontrivial_coe _).2 $ (s.nontrivial_coe.1 hs).mono hst
1882+
1883+
/-- The preimage of a nontrivial set under a surjective map is nontrivial. -/
1884+
theorem nontrivial.preimage {s : set β} (hs : s.nontrivial) {f : α → β}
1885+
(hf : function.surjective f) : (f ⁻¹' s).nontrivial :=
1886+
begin
1887+
rcases hs with ⟨fx, hx, fy, hy, hxy⟩,
1888+
rcases ⟨hf fx, hf fy⟩ with ⟨⟨x, rfl⟩, ⟨y, rfl⟩⟩,
1889+
exact ⟨x, hx, y, hy, mt (congr_arg f) hxy⟩
1890+
end
1891+
1892+
/-- The image of a nontrivial set under an injective map is nontrivial. -/
1893+
theorem nontrivial.image (hs : s.nontrivial)
1894+
{f : α → β} (hf : function.injective f) : (f '' s).nontrivial :=
1895+
let ⟨x, hx, y, hy, hxy⟩ := hs in ⟨f x, mem_image_of_mem f hx, f y, mem_image_of_mem f hy, hf.ne hxy⟩
1896+
1897+
/-- If the image of a set is nontrivial, the set is nontrivial. -/
1898+
lemma nontrivial_of_image (f : α → β) (s : set α) (hs : (f '' s).nontrivial) : s.nontrivial :=
1899+
let ⟨_, ⟨x, hx, rfl⟩, _, ⟨y, hy, rfl⟩, hxy⟩ := hs in ⟨x, hx, y, hy, mt (congr_arg f) hxy⟩
1900+
1901+
/-- If the preimage of a set under an injective map is nontrivial, the set is nontrivial. -/
1902+
lemma nontrivial_of_preimage {f : α → β} (hf : function.injective f) (s : set β)
1903+
(hs : (f ⁻¹' s).nontrivial) : s.nontrivial :=
1904+
(hs.image hf).mono $ image_preimage_subset _ _
1905+
1906+
@[simp] lemma not_subsingleton_iff : ¬ s.subsingleton ↔ s.nontrivial :=
1907+
by simp_rw [set.subsingleton, set.nontrivial, not_forall]
1908+
1909+
@[simp] lemma not_nontrivial_iff : ¬ s.nontrivial ↔ s.subsingleton :=
1910+
iff.not_left not_subsingleton_iff.symm
1911+
17811912
theorem univ_eq_true_false : univ = ({true, false} : set Prop) :=
17821913
eq.symm $ eq_univ_of_forall $ classical.cases (by simp) (by simp)
17831914

0 commit comments

Comments
 (0)