lean4-htt/library/init/algebra/classes.lean

290 lines
12 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/-
Copyright (c) 2017 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Leonardo de Moura
-/
prelude
import init.logic init.data.ordering.basic
universes u v
@[algebra] class is_symm_op (α : Type u) (β : out_param (Type v)) (op : αα → β) : Prop :=
(symm_op : ∀ a b, op a b = op b a)
@[algebra] class is_commutative (α : Type u) (op : ααα) : Prop :=
(comm : ∀ a b, op a b = op b a)
instance is_symm_op_of_is_commutative (α : Type u) (op : ααα) [is_commutative α op] : is_symm_op α α op :=
{symm_op := is_commutative.comm op}
@[algebra] class is_associative (α : Type u) (op : ααα) : Prop :=
(assoc : ∀ a b c, op (op a b) c = op a (op b c))
@[algebra] class is_left_id (α : Type u) (op : ααα) (o : out_param α) : Prop :=
(left_id : ∀ a, op o a = a)
@[algebra] class is_right_id (α : Type u) (op : ααα) (o : out_param α) : Prop :=
(right_id : ∀ a, op a o = a)
@[algebra] class is_left_null (α : Type u) (op : ααα) (o : out_param α) : Prop :=
(left_null : ∀ a, op o a = o)
@[algebra] class is_right_null (α : Type u) (op : ααα) (o : out_param α) : Prop :=
(right_null : ∀ a, op a o = o)
@[algebra] class is_left_cancel (α : Type u) (op : ααα) : Prop :=
(left_cancel : ∀ a b c, op a b = op a c → b = c)
@[algebra] class is_right_cancel (α : Type u) (op : ααα) : Prop :=
(right_cancel : ∀ a b c, op a b = op c b → a = c)
@[algebra] class is_idempotent (α : Type u) (op : ααα) : Prop :=
(idempotent : ∀ a, op a a = a)
@[algebra] class is_left_distrib (α : Type u) (op₁ : ααα) (op₂ : out_param $ ααα) : Prop :=
(left_distrib : ∀ a b c, op₁ a (op₂ b c) = op₂ (op₁ a b) (op₁ a c))
@[algebra] class is_right_distrib (α : Type u) (op₁ : ααα) (op₂ : out_param $ ααα) : Prop :=
(right_distrib : ∀ a b c, op₁ (op₂ a b) c = op₂ (op₁ a c) (op₁ b c))
@[algebra] class is_left_inv (α : Type u) (op : ααα) (inv : out_param $ αα) (o : out_param α) : Prop :=
(left_inv : ∀ a, op (inv a) a = o)
@[algebra] class is_right_inv (α : Type u) (op : ααα) (inv : out_param $ αα) (o : out_param α) : Prop :=
(right_inv : ∀ a, op a (inv a) = o)
@[algebra] class is_cond_left_inv (α : Type u) (op : ααα) (inv : out_param $ αα) (o : out_param α) (p : out_param $ α → Prop) : Prop :=
(left_inv : ∀ a, p a → op (inv a) a = o)
@[algebra] class is_cond_right_inv (α : Type u) (op : ααα) (inv : out_param $ αα) (o : out_param α) (p : out_param $ α → Prop) : Prop :=
(right_inv : ∀ a, p a → op a (inv a) = o)
@[algebra] class is_distinct (α : Type u) (a : α) (b : α) : Prop :=
(distinct : a ≠ b)
/-
-- The following type class doesn't seem very useful, a regular simp lemma should work for this.
class is_inv (α : Type u) (β : Type v) (f : α → β) (g : out β → α) : Prop :=
(inv : ∀ a, g (f a) = a)
-- The following one can also be handled using a regular simp lemma
class is_idempotent (α : Type u) (f : αα) : Prop :=
(idempotent : ∀ a, f (f a) = f a)
-/
@[algebra] class is_irrefl (α : Type u) (r : αα → Prop) : Prop :=
(irrefl : ∀ a, ¬ r a a)
@[algebra] class is_refl (α : Type u) (r : αα → Prop) : Prop :=
(refl : ∀ a, r a a)
@[algebra] class is_symm (α : Type u) (r : αα → Prop) : Prop :=
(symm : ∀ a b, r a b → r b a)
instance is_symm_op_of_is_symm (α : Type u) (r : αα → Prop) [is_symm α r] : is_symm_op α Prop r :=
{symm_op := λ a b, propext $ iff.intro (is_symm.symm a b) (is_symm.symm b a)}
@[algebra] class is_asymm (α : Type u) (r : αα → Prop) : Prop :=
(asymm : ∀ a b, r a b → ¬ r b a)
@[algebra] class is_antisymm (α : Type u) (r : αα → Prop) : Prop :=
(antisymm : ∀ a b, r a b → r b a → a = b)
@[algebra] class is_trans (α : Type u) (r : αα → Prop) : Prop :=
(trans : ∀ a b c, r a b → r b c → r a c)
@[algebra] class is_total (α : Type u) (r : αα → Prop) : Prop :=
(total : ∀ a b, r a b r b a)
@[algebra] class is_preorder (α : Type u) (r : αα → Prop) extends is_refl α r, is_trans α r : Prop.
@[algebra] class is_total_preorder (α : Type u) (r : αα → Prop) extends is_trans α r, is_total α r : Prop.
instance is_total_preorder_is_preorder (α : Type u) (r : αα → Prop) [s : is_total_preorder α r] : is_preorder α r :=
{trans := s.trans,
refl := λ a, or.elim (is_total.total r a a) id id}
@[algebra] class is_partial_order (α : Type u) (r : αα → Prop) extends is_preorder α r, is_antisymm α r : Prop.
@[algebra] class is_linear_order (α : Type u) (r : αα → Prop) extends is_partial_order α r, is_total α r : Prop.
@[algebra] class is_equiv (α : Type u) (r : αα → Prop) extends is_preorder α r, is_symm α r : Prop.
@[algebra] class is_per (α : Type u) (r : αα → Prop) extends is_symm α r, is_trans α r : Prop.
@[algebra] class is_strict_order (α : Type u) (r : αα → Prop) extends is_irrefl α r, is_trans α r : Prop.
@[algebra] class is_incomp_trans (α : Type u) (lt : αα → Prop) : Prop :=
(incomp_trans : ∀ a b c, (¬ lt a b ∧ ¬ lt b a) → (¬ lt b c ∧ ¬ lt c b) → (¬ lt a c ∧ ¬ lt c a))
@[algebra] class is_strict_weak_order (α : Type u) (lt : αα → Prop) extends is_strict_order α lt, is_incomp_trans α lt : Prop.
@[algebra] class is_trichotomous (α : Type u) (lt : αα → Prop) : Prop :=
(trichotomous : ∀ a b, lt a b a = b lt b a)
@[algebra] class is_strict_total_order (α : Type u) (lt : αα → Prop) extends is_trichotomous α lt, is_strict_weak_order α lt.
instance eq_is_equiv (α : Type u) : is_equiv α (=) :=
{symm := @eq.symm _, trans := @eq.trans _, refl := eq.refl}
section
variables {α : Type u} {r : αα → Prop}
local infix `≺`:50 := r
lemma irrefl [is_irrefl α r] (a : α) : ¬ a ≺ a :=
is_irrefl.irrefl _ a
lemma refl [is_refl α r] (a : α) : a ≺ a :=
is_refl.refl _ a
lemma trans [is_trans α r] {a b c : α} : a ≺ b → b ≺ c → a ≺ c :=
is_trans.trans _ _ _
lemma symm [is_symm α r] {a b : α} : a ≺ b → b ≺ a :=
is_symm.symm _ _
lemma antisymm [is_antisymm α r] {a b : α} : a ≺ b → b ≺ a → a = b :=
is_antisymm.antisymm _ _
lemma asymm [is_asymm α r] {a b : α} : a ≺ b → ¬ b ≺ a :=
is_asymm.asymm _ _
lemma trichotomous [is_trichotomous α r] : ∀ (a b : α), a ≺ b a = b b ≺ a :=
is_trichotomous.trichotomous r
lemma incomp_trans [is_incomp_trans α r] {a b c : α} : (¬ a ≺ b ∧ ¬ b ≺ a) → (¬ b ≺ c ∧ ¬ c ≺ b) → (¬ a ≺ c ∧ ¬ c ≺ a) :=
is_incomp_trans.incomp_trans _ _ _
instance is_asymm_of_is_trans_of_is_irrefl [is_trans α r] [is_irrefl α r] : is_asymm α r :=
⟨λ a b h₁ h₂, absurd (trans h₁ h₂) (irrefl a)⟩
section explicit_relation_variants
variable (r)
@[elab_simple]
lemma irrefl_of [is_irrefl α r] (a : α) : ¬ a ≺ a := irrefl a
@[elab_simple]
lemma refl_of [is_refl α r] (a : α) : a ≺ a := refl a
@[elab_simple]
lemma trans_of [is_trans α r] {a b c : α} : a ≺ b → b ≺ c → a ≺ c := trans
@[elab_simple]
lemma symm_of [is_symm α r] {a b : α} : a ≺ b → b ≺ a := symm
@[elab_simple]
lemma asymm_of [is_asymm α r] {a b : α} : a ≺ b → ¬ b ≺ a := asymm
@[elab_simple]
lemma total_of [is_total α r] (a b : α) : a ≺ b b ≺ a :=
is_total.total _ _ _
@[elab_simple]
lemma trichotomous_of [is_trichotomous α r] : ∀ (a b : α), a ≺ b a = b b ≺ a := trichotomous
@[elab_simple]
lemma incomp_trans_of [is_incomp_trans α r] {a b c : α} : (¬ a ≺ b ∧ ¬ b ≺ a) → (¬ b ≺ c ∧ ¬ c ≺ b) → (¬ a ≺ c ∧ ¬ c ≺ a) := incomp_trans
end explicit_relation_variants
end
namespace strict_weak_order
section
parameters {α : Type u} {r : αα → Prop}
local infix `≺`:50 := r
def equiv (a b : α) : Prop :=
¬ a ≺ b ∧ ¬ b ≺ a
parameter [is_strict_weak_order α r]
local infix ` ≈ `:50 := equiv
lemma erefl (a : α) : a ≈ a :=
⟨irrefl a, irrefl a⟩
lemma esymm {a b : α} : a ≈ b → b ≈ a :=
λ ⟨h₁, h₂⟩, ⟨h₂, h₁⟩
lemma etrans {a b c : α} : a ≈ b → b ≈ c → a ≈ c :=
incomp_trans
lemma not_lt_of_equiv {a b : α} : a ≈ b → ¬ a ≺ b :=
λ h, h.1
lemma not_lt_of_equiv' {a b : α} : a ≈ b → ¬ b ≺ a :=
λ h, h.2
instance : is_equiv α equiv :=
{refl := erefl, trans := @etrans, symm := @esymm}
end
/- Notation for the equivalence relation induced by lt -/
notation a ` ≈[`:50 lt `]` b:50 := @equiv _ lt a b
end strict_weak_order
lemma is_strict_weak_order_of_is_total_preorder {α : Type u} {le : αα → Prop} {lt : αα → Prop} [decidable_rel le] [s : is_total_preorder α le]
(h : ∀ a b, lt a b ↔ ¬ le b a) : is_strict_weak_order α lt :=
{
trans :=
λ a b c hab hbc,
have nba : ¬ le b a, from iff.mp (h _ _) hab,
have ncb : ¬ le c b, from iff.mp (h _ _) hbc,
have hab : le a b, from or.resolve_left (total_of le b a) nba,
have nca : ¬ le c a, from λ hca : le c a,
have hcb : le c b, from trans_of le hca hab,
absurd hcb ncb,
iff.mpr (h _ _) nca,
irrefl := λ a hlt, absurd (refl_of le a) (iff.mp (h _ _) hlt),
incomp_trans := λ a b c ⟨nab, nba⟩ ⟨nbc, ncb⟩,
have hba : le b a, from decidable.of_not_not (iff.mp (not_iff_not_of_iff (h _ _)) nab),
have hab : le a b, from decidable.of_not_not (iff.mp (not_iff_not_of_iff (h _ _)) nba),
have hcb : le c b, from decidable.of_not_not (iff.mp (not_iff_not_of_iff (h _ _)) nbc),
have hbc : le b c, from decidable.of_not_not (iff.mp (not_iff_not_of_iff (h _ _)) ncb),
have hac : le a c, from trans_of le hab hbc,
have hca : le c a, from trans_of le hcb hba,
and.intro
(λ n, absurd hca (iff.mp (h _ _) n))
(λ n, absurd hac (iff.mp (h _ _) n))
}
lemma lt_of_lt_of_incomp {α : Type u} {lt : αα → Prop} [is_strict_weak_order α lt] [decidable_rel lt]
: ∀ {a b c}, lt a b → (¬ lt b c ∧ ¬ lt c b) → lt a c :=
λ a b c hab ⟨nbc, ncb⟩,
have nca : ¬ lt c a, from λ hca, absurd (trans_of lt hca hab) ncb,
decidable.by_contradiction $
λ nac : ¬ lt a c,
have ¬ lt a b ∧ ¬ lt b a, from incomp_trans_of lt ⟨nac, nca⟩ ⟨ncb, nbc⟩,
absurd hab this.1
lemma lt_of_incomp_of_lt {α : Type u} {lt : αα → Prop} [is_strict_weak_order α lt] [decidable_rel lt]
: ∀ {a b c}, (¬ lt a b ∧ ¬ lt b a) → lt b c → lt a c :=
λ a b c ⟨nab, nba⟩ hbc,
have nca : ¬ lt c a, from λ hca, absurd (trans_of lt hbc hca) nba,
decidable.by_contradiction $
λ nac : ¬ lt a c,
have ¬ lt b c ∧ ¬ lt c b, from incomp_trans_of lt ⟨nba, nab⟩ ⟨nac, nca⟩,
absurd hbc this.1
lemma eq_of_incomp {α : Type u} {lt : αα → Prop} [is_trichotomous α lt] {a b} : (¬ lt a b ∧ ¬ lt b a) → a = b :=
λ ⟨nab, nba⟩,
match trichotomous_of lt a b with
| or.inl hab := absurd hab nab
| or.inr (or.inl hab) := hab
| or.inr (or.inr hba) := absurd hba nba
end
lemma eq_of_eqv_lt {α : Type u} {lt : αα → Prop} [is_trichotomous α lt] {a b} : a ≈[lt] b → a = b :=
eq_of_incomp
lemma incomp_iff_eq {α : Type u} {lt : αα → Prop} [is_trichotomous α lt] [is_irrefl α lt] (a b) : (¬ lt a b ∧ ¬ lt b a) ↔ a = b :=
iff.intro eq_of_incomp (λ hab, eq.subst hab (and.intro (irrefl_of lt a) (irrefl_of lt a)))
lemma eqv_lt_iff_eq {α : Type u} {lt : αα → Prop} [is_trichotomous α lt] [is_irrefl α lt] (a b) : a ≈[lt] b ↔ a = b :=
incomp_iff_eq a b
lemma not_lt_of_lt {α : Type u} {lt : αα → Prop} [is_strict_order α lt] {a b} : lt a b → ¬ lt b a :=
λ h₁ h₂, absurd (trans_of lt h₁ h₂) (irrefl_of lt _)