Skip to content

Commit

Permalink
feat(order/rel_classes): Unbundled typeclass to state that two relati…
Browse files Browse the repository at this point in the history
…ons are the non strict and strict versions (#11381)

This defines a Prop-valued mixin `is_nonstrict_strict_order α r s` to state `s a b ↔ r a b ∧ ¬ r b a`.

The idea is to allow dot notation for lemmas about the interaction of `⊆` and `⊂` (which currently do not have a `preorder`-like typeclass). Dot notation on each of them is already possible thanks to unbundled relation classes (which allow to state lemmas for both `set` and `finset`).
  • Loading branch information
YaelDillies committed Feb 2, 2022
1 parent d002769 commit cd1d839
Show file tree
Hide file tree
Showing 3 changed files with 243 additions and 91 deletions.
58 changes: 36 additions & 22 deletions src/data/finset/basic.lean
Expand Up @@ -221,25 +221,42 @@ instance finset_coe.can_lift (s : finset α) : can_lift α s :=
@[simp, norm_cast] lemma coe_sort_coe (s : finset α) :
((s : set α) : Sort*) = s := rfl

/-! ### subset -/
/-! ### Subset and strict subset relations -/

instance : has_subset (finset α) := ⟨λ s₁ s₂, ∀ ⦃a⦄, a ∈ s₁ → a ∈ s₂⟩
section subset
variables {s t : finset α}

theorem subset_def {s₁ s₂ : finset α} : s₁ ⊆ s₂ ↔ s₁.1 ⊆ s₂.1 := iff.rfl
instance : has_subset (finset α) := ⟨λ s t, ∀ ⦃a⦄, a ∈ s → a ∈ t⟩
instance : has_ssubset (finset α) := ⟨λ s t, s ⊆ t ∧ ¬ t ⊆ s⟩

instance : partial_order (finset α) :=
{ le := (⊆),
lt := (⊂),
le_refl := λ s a, id,
le_trans := λ s t u hst htu a ha, htu $ hst ha,
le_antisymm := λ s t hst hts, ext $ λ a, ⟨@hst _, @hts _⟩ }

instance : is_refl (finset α) (⊆) := has_le.le.is_refl
instance : is_trans (finset α) (⊆) := has_le.le.is_trans
instance : is_antisymm (finset α) (⊆) := has_le.le.is_antisymm
instance : is_irrefl (finset α) (⊂) := has_lt.lt.is_irrefl
instance : is_trans (finset α) (⊂) := has_lt.lt.is_trans
instance : is_asymm (finset α) (⊂) := has_lt.lt.is_asymm
instance : is_nonstrict_strict_order (finset α) (⊆) (⊂) := ⟨λ _ _, iff.rfl⟩

lemma subset_def : s ⊆ t ↔ s.1 ⊆ t.1 := iff.rfl
lemma ssubset_def : s ⊂ t ↔ s ⊆ t ∧ ¬ t ⊆ s := iff.rfl

@[simp] theorem subset.refl (s : finset α) : s ⊆ s := subset.refl _
protected lemma subset.rfl {s :finset α} : s ⊆ s := subset.refl _

theorem subset_of_eq {s t : finset α} (h : s = t) : s ⊆ t := h ▸ subset.refl _
protected theorem subset_of_eq {s t : finset α} (h : s = t) : s ⊆ t := h ▸ subset.refl _

theorem subset.trans {s₁ s₂ s₃ : finset α} : s₁ ⊆ s₂ → s₂ ⊆ s₃ → s₁ ⊆ s₃ := subset.trans

theorem superset.trans {s₁ s₂ s₃ : finset α} : s₁ ⊇ s₂ → s₂ ⊇ s₃ → s₁ ⊇ s₃ :=
λ h' h, subset.trans h h'

-- TODO: these should be global attributes, but this will require fixing other files
local attribute [trans] subset.trans superset.trans

theorem mem_of_subset {s₁ s₂ : finset α} {a : α} : s₁ ⊆ s₂ → a ∈ s₁ → a ∈ s₂ := mem_of_subset

lemma not_mem_mono {s t : finset α} (h : s ⊆ t) {a : α} : a ∉ t → a ∉ s := mt $ @h _
Expand All @@ -254,21 +271,6 @@ theorem subset_iff {s₁ s₂ : finset α} : s₁ ⊆ s₂ ↔ ∀ ⦃x⦄, x

@[simp] theorem val_le_iff {s₁ s₂ : finset α} : s₁.1 ≤ s₂.1 ↔ s₁ ⊆ s₂ := le_iff_subset s₁.2

instance : has_ssubset (finset α) := ⟨λa b, a ⊆ b ∧ ¬ b ⊆ a⟩

instance : partial_order (finset α) :=
{ le := (⊆),
lt := (⊂),
le_refl := subset.refl,
le_trans := @subset.trans _,
le_antisymm := @subset.antisymm _ }


/-- Coercion to `set α` as an `order_embedding`. -/
def coe_emb : finset α ↪o set α := ⟨⟨coe, coe_injective⟩, λ s t, coe_subset⟩

@[simp] lemma coe_coe_emb : ⇑(coe_emb : finset α ↪o set α) = coe := rfl

theorem subset.antisymm_iff {s₁ s₂ : finset α} : s₁ = s₂ ↔ s₁ ⊆ s₂ ∧ s₂ ⊆ s₁ :=
le_antisymm_iff

Expand Down Expand Up @@ -306,6 +308,18 @@ lemma exists_of_ssubset {s₁ s₂ : finset α} (h : s₁ ⊂ s₂) :
∃ x ∈ s₂, x ∉ s₁ :=
set.exists_of_ssubset h

end subset

-- TODO: these should be global attributes, but this will require fixing other files
local attribute [trans] subset.trans superset.trans

/-! ### Order embedding from `finset α` to `set α` -/

/-- Coercion to `set α` as an `order_embedding`. -/
def coe_emb : finset α ↪o set α := ⟨⟨coe, coe_injective⟩, λ s t, coe_subset⟩

@[simp] lemma coe_coe_emb : ⇑(coe_emb : finset α ↪o set α) = coe := rfl

/-! ### Nonempty -/

/-- The property `s.nonempty` expresses the fact that the finset `s` is not empty. It should be used
Expand Down
43 changes: 20 additions & 23 deletions src/data/set/basic.lean
Expand Up @@ -3,7 +3,6 @@ Copyright (c) 2014 Jeremy Avigad. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Jeremy Avigad, Leonardo de Moura
-/
import logic.unique
import order.boolean_algebra

/-!
Expand Down Expand Up @@ -77,18 +76,6 @@ universes u v w x
run_cmd do e ← tactic.get_env,
tactic.set_env $ e.mk_protected `set.compl

lemma has_subset.subset.trans {α : Type*} [has_subset α] [is_trans α (⊆)]
{a b c : α} (h : a ⊆ b) (h' : b ⊆ c) : a ⊆ c := trans h h'

lemma has_subset.subset.antisymm {α : Type*} [has_subset α] [is_antisymm α (⊆)]
{a b : α} (h : a ⊆ b) (h' : b ⊆ a) : a = b := antisymm h h'

lemma has_ssubset.ssubset.trans {α : Type*} [has_ssubset α] [is_trans α (⊂)]
{a b c : α} (h : a ⊂ b) (h' : b ⊂ c) : a ⊂ c := trans h h'

lemma has_ssubset.ssubset.asymm {α : Type*} [has_ssubset α] [is_asymm α (⊂)]
{a b : α} (h : a ⊂ b) : ¬(b ⊂ a) := asymm h

namespace set

variable {α : Type*}
Expand Down Expand Up @@ -173,6 +160,7 @@ end set_coe
/-- See also `subtype.prop` -/
lemma subtype.mem {α : Type*} {s : set α} (p : s) : (p : α) ∈ s := p.prop

/-- Duplicate of `eq.subset'`, which currently has elaboration problems. -/
lemma eq.subset {α} {s t : set α} : s = t → s ⊆ t :=
by { rintro rfl x hx, exact hx }

Expand Down Expand Up @@ -217,10 +205,21 @@ lemma set_of_and {p q : α → Prop} : {a | p a ∧ q a} = {a | p a} ∩ {a | q

lemma set_of_or {p q : α → Prop} : {a | p a ∨ q a} = {a | p a} ∪ {a | q a} := rfl

/-! ### Lemmas about subsets -/
/-! ### Subset and strict subset relations -/

instance : has_ssubset (set α) := ⟨(<)⟩

instance : is_refl (set α) (⊆) := has_le.le.is_refl
instance : is_trans (set α) (⊆) := has_le.le.is_trans
instance : is_antisymm (set α) (⊆) := has_le.le.is_antisymm
instance : is_irrefl (set α) (⊂) := has_lt.lt.is_irrefl
instance : is_trans (set α) (⊂) := has_lt.lt.is_trans
instance : is_asymm (set α) (⊂) := has_lt.lt.is_asymm
instance : is_nonstrict_strict_order (set α) (⊆) (⊂) := ⟨λ _ _, iff.rfl⟩

-- TODO(Jeremy): write a tactic to unfold specific instances of generic notation?
theorem subset_def {s t : set α} : (s ⊆ t) = ∀ x, x ∈ s → x ∈ t := rfl
lemma subset_def : (s ⊆ t) = ∀ x, x ∈ s → x ∈ t := rfl
lemma ssubset_def : s ⊂ t = (s ⊆ t ∧ ¬ t ⊆ s) := rfl

@[refl] theorem subset.refl (a : set α) : a ⊆ a := assume x, id
theorem subset.rfl {s : set α} : s ⊆ s := subset.refl s
Expand Down Expand Up @@ -257,29 +256,27 @@ end

/-! ### Definition of strict subsets `s ⊂ t` and basic properties. -/

instance : has_ssubset (set α) := ⟨(<)⟩

@[simp] lemma lt_eq_ssubset : ((<) : set α → set α → Prop) = (⊂) := rfl

theorem ssubset_def : (s ⊂ t) = (s ⊆ t ∧ ¬ (t ⊆ s)) := rfl

theorem eq_or_ssubset_of_subset (h : s ⊆ t) : s = t ∨ s ⊂ t :=
protected theorem eq_or_ssubset_of_subset (h : s ⊆ t) : s = t ∨ s ⊂ t :=
eq_or_lt_of_le h

lemma exists_of_ssubset {s t : set α} (h : s ⊂ t) : (∃x∈t, x ∉ s) :=
not_subset.1 h.2

lemma ssubset_iff_subset_ne {s t : set α} : s ⊂ t ↔ s ⊆ t ∧ s ≠ t :=
protected lemma ssubset_iff_subset_ne {s t : set α} : s ⊂ t ↔ s ⊆ t ∧ s ≠ t :=
@lt_iff_le_and_ne (set α) _ s t

lemma ssubset_iff_of_subset {s t : set α} (h : s ⊆ t) : s ⊂ t ↔ ∃ x ∈ t, x ∉ s :=
⟨exists_of_ssubset, λ ⟨x, hxt, hxs⟩, ⟨h, λ h, hxs $ h hxt⟩⟩

lemma ssubset_of_ssubset_of_subset {s₁ s₂ s₃ : set α} (hs₁s₂ : s₁ ⊂ s₂) (hs₂s₃ : s₂ ⊆ s₃) :
protected lemma ssubset_of_ssubset_of_subset {s₁ s₂ s₃ : set α} (hs₁s₂ : s₁ ⊂ s₂)
(hs₂s₃ : s₂ ⊆ s₃) :
s₁ ⊂ s₃ :=
⟨subset.trans hs₁s₂.1 hs₂s₃, λ hs₃s₁, hs₁s₂.2 (subset.trans hs₂s₃ hs₃s₁)⟩

lemma ssubset_of_subset_of_ssubset {s₁ s₂ s₃ : set α} (hs₁s₂ : s₁ ⊆ s₂) (hs₂s₃ : s₂ ⊂ s₃) :
protected lemma ssubset_of_subset_of_ssubset {s₁ s₂ s₃ : set α} (hs₁s₂ : s₁ ⊆ s₂)
(hs₂s₃ : s₂ ⊂ s₃) :
s₁ ⊂ s₃ :=
⟨subset.trans hs₁s₂ hs₂s₃.1, λ hs₃s₁, hs₂s₃.2 (subset.trans hs₃s₁ hs₁s₂)⟩

Expand Down

0 comments on commit cd1d839

Please sign in to comment.