feat(library/algebra): add lattice instances for Prop, fun, and set

Adds weak_order, lattice and complete_lattice instances for Prop, fun, and set. Adds supporting
theorems to various other places.
This commit is contained in:
Johannes Hölzl 2016-01-04 22:03:47 +01:00 committed by Leonardo de Moura
parent c0deac6a63
commit 9c28552afb
6 changed files with 276 additions and 0 deletions

View file

@ -270,3 +270,92 @@ have le₂ : ⨅ univ ≤ ⨆ (∅ : set A), from
le.antisymm le₁ le₂ le.antisymm le₁ le₂
end complete_lattice end complete_lattice
/- complete lattice instances -/
section
open eq.ops complete_lattice
definition complete_lattice_fun [instance] {A B : Type} [complete_lattice B] :
complete_lattice (A → B) :=
⦃ complete_lattice, lattice_fun,
Inf := λS x, Inf ((λf, f x) ' S),
le_Inf := take f S H x,
le_Inf (take y Hy, obtain g `g ∈ S` `g x = y`, from Hy, `g x = y` ▸ H g `g ∈ S` x),
Inf_le := take f S `f ∈ S` x,
Inf_le (exists.intro f (and.intro `f ∈ S` rfl)),
Sup := λS x, Sup ((λf, f x) ' S),
le_Sup := take f S `f ∈ S` x,
le_Sup (exists.intro f (and.intro `f ∈ S` rfl)),
Sup_le := take f S H x,
Sup_le (take y Hy, obtain g `g ∈ S` `g x = y`, from Hy, `g x = y` ▸ H g `g ∈ S` x)
section
open classical -- Prop and set are only in the classical setting a complete lattice
definition complete_lattice_Prop [instance] : complete_lattice Prop :=
⦃ complete_lattice, lattice_Prop,
Inf := λS, false ∉ S,
le_Inf := take x S H Hx Hf,
H _ Hf Hx,
Inf_le := take x S Hx Hf,
(classical.cases_on x (take x, true.intro) Hf) Hx,
Sup := λS, true ∈ S,
le_Sup := take x S Hx H,
iff_subst (iff.intro (take H, true.intro) (take H', H)) Hx,
Sup_le := take x S H Ht,
H _ Ht true.intro
lemma sInter_eq_fun_Inf {A : Type} (S : set (set A)) : ⋂₀ S = @Inf (A → Prop) _ S :=
funext (take x,
calc
(⋂₀ S) x = ∀₀ P ∈ S, P x : rfl
... = ¬ (∃₀ P ∈ S, P x = false) :
begin
rewrite not_bounded_exists,
apply bounded_forall_congr,
intros,
rewrite eq_false,
rewrite not_not_iff
end
... = @Inf (A → Prop) _ S x : rfl)
lemma sUnion_eq_fun_Sup {A : Type} (S : set (set A)) : ⋃₀ S = @Sup (A → Prop) _ S :=
funext (take x,
calc
(⋃₀ S) x = ∃₀ P ∈ S, P x : rfl
... = (∃₀ P ∈ S, P x = true) :
begin
apply bounded_exists_congr,
intros,
rewrite eq_true
end
... = @Sup (A → Prop) _ S x : rfl)
definition complete_lattice_set [instance] {A : Type} : complete_lattice (set A) :=
⦃ complete_lattice,
le := subset,
le_refl := @le_refl (A → Prop) _,
le_trans := @le_trans (A → Prop) _,
le_antisymm := @le_antisymm (A → Prop) _,
inf := inter,
sup := union,
inf_le_left := @inf_le_left (A → Prop) _,
inf_le_right := @inf_le_right (A → Prop) _,
le_inf := @le_inf (A → Prop) _,
le_sup_left := @le_sup_left (A → Prop) _,
le_sup_right := @le_sup_right (A → Prop) _,
sup_le := @sup_le (A → Prop) _,
Inf := sInter,
Sup := sUnion,
le_Inf := begin intros X S H, rewrite sInter_eq_fun_Inf, apply (@le_Inf (A → Prop) _), exact H end,
Inf_le := begin intros X S H, rewrite sInter_eq_fun_Inf, apply (@Inf_le (A → Prop) _), exact H end,
le_Sup := begin intros X S H, rewrite sUnion_eq_fun_Sup, apply (@le_Sup (A → Prop) _), exact H end,
Sup_le := begin intros X S H, rewrite sUnion_eq_fun_Sup, apply (@Sup_le (A → Prop) _), exact H end
end
end

View file

@ -106,3 +106,35 @@ section
theorem sup_eq_right {a b : A} (H : a ≤ b) : a ⊔ b = b := theorem sup_eq_right {a b : A} (H : a ≤ b) : a ⊔ b = b :=
eq.subst !sup.comm (sup_eq_left H) eq.subst !sup.comm (sup_eq_left H)
end end
/- lattice instances -/
definition lattice_Prop [instance] : lattice Prop :=
⦃ lattice, weak_order_Prop,
inf := and,
le_inf := take a b c Ha Hb Hc, and.intro (Ha Hc) (Hb Hc),
inf_le_left := @and.elim_left,
inf_le_right := @and.elim_right,
sup := or,
sup_le := @or.rec,
le_sup_left := @or.intro_left,
le_sup_right := @or.intro_right
definition lattice_fun [instance] {A B : Type} [lattice B] : lattice (A → B) :=
⦃ lattice, weak_order_fun,
inf := λf g x, inf (f x) (g x),
le_inf := take f g h Hf Hg x, le_inf (Hf x) (Hg x),
inf_le_left := take f g x, !inf_le_left,
inf_le_right := take f g x, !inf_le_right,
sup := λf g x, sup (f x) (g x),
sup_le := take f g h Hf Hg x, sup_le (Hf x) (Hg x),
le_sup_left := take f g x, !le_sup_left,
le_sup_right := take t g x, !le_sup_right
/-
Should we add a trans-instance from total orders to lattices?
If we added we should add it with lower priority:
Prop is added as a lattice, but in the classical case it is a total order!
-/

View file

@ -434,3 +434,35 @@ section
(assume H : a ≤ b, by rewrite (max_eq_right H); apply H₂) (assume H : a ≤ b, by rewrite (max_eq_right H); apply H₂)
(assume H : a > b, by rewrite (max_eq_left_of_lt H); apply H₁) (assume H : a > b, by rewrite (max_eq_left_of_lt H); apply H₁)
end end
/- order instances -/
definition weak_order_Prop [instance] : weak_order Prop :=
⦃ weak_order,
le := λx y, x → y,
le_refl := λx, id,
le_trans := λa b c H1 H2 x, H2 (H1 x),
le_antisymm := λf g H1 H2, propext (and.intro H1 H2)
definition weak_order_fun [instance] {A B : Type} [weak_order B] : weak_order (A → B) :=
⦃ weak_order,
le := λx y, ∀b, x b ≤ y b,
le_refl := λf b, !le.refl,
le_trans := λf g h H1 H2 b, !le.trans (H1 b) (H2 b),
le_antisymm := λf g H1 H2, funext (λb, !le.antisymm (H1 b) (H2 b))
definition weak_order_dual {A : Type} (wo : weak_order A) : weak_order A :=
⦃ weak_order,
le := λx y, y ≤ x,
le_refl := le.refl,
le_trans := take a b c `b ≤ a` `c ≤ b`, le.trans `c ≤ b` `b ≤ a`,
le_antisymm := take a b `b ≤ a` `a ≤ b`, le.antisymm `a ≤ b` `b ≤ a` ⦄
lemma dual {A : Type} (wo : weak_order A) (a b : A) :
@le _ (@weak_order.to_has_le _ (weak_order_dual wo)) a b =
@le _ (@weak_order.to_has_le _ wo) b a :=
rfl
-- what to do with the strict variants?

View file

@ -64,6 +64,54 @@ theorem bounded_exists.intro {P : X → Prop} {s : set X} {x : X} (xs : x ∈ s)
∃₀ x ∈ s, P x := ∃₀ x ∈ s, P x :=
exists.intro x (and.intro xs Px) exists.intro x (and.intro xs Px)
lemma bounded_forall_congr {A : Type} {S : set A} {P Q : A → Prop} (H : ∀₀ x∈S, P x ↔ Q x) :
(∀₀ x ∈ S, P x) = (∀₀ x ∈ S, Q x) :=
begin
apply propext,
apply forall_congr,
intros x,
apply imp_congr_right,
apply H
end
lemma bounded_exists_congr {A : Type} {S : set A} {P Q : A → Prop} (H : ∀₀ x∈S, P x ↔ Q x) :
(∃₀ x ∈ S, P x) = (∃₀ x ∈ S, Q x) :=
begin
apply propext,
apply exists_congr,
intros x,
apply and_congr_right,
apply H
end
section
open classical
lemma not_bounded_exists {A : Type} {S : set A} {P : A → Prop} :
(¬ (∃₀ x ∈ S, P x)) = (∀₀ x ∈ S, ¬ P x) :=
begin
rewrite forall_iff_not_exists,
apply propext,
apply forall_congr,
intro x,
rewrite not_and_iff_not_or_not,
rewrite imp_iff_not_or
end
lemma not_bounded_forall {A : Type} {S : set A} {P : A → Prop} :
(¬ (∀₀ x ∈ S, P x)) = (∃₀ x ∈ S, ¬ P x) :=
calc (¬ (∀₀ x ∈ S, P x)) = ¬ ¬ (∃₀ x ∈ S, ¬ P x) :
begin
rewrite not_bounded_exists,
apply (congr_arg not),
apply bounded_forall_congr,
intros x H,
rewrite not_not_iff
end
... = (∃₀ x ∈ S, ¬ P x) : by (rewrite not_not_iff)
end
/- empty set -/ /- empty set -/
definition empty : set X := λx, false definition empty : set X := λx, false
@ -95,6 +143,10 @@ subset.antisymm H (empty_subset s)
theorem subset_empty_iff (s : set X) : s ⊆ ∅ ↔ s = ∅ := theorem subset_empty_iff (s : set X) : s ⊆ ∅ ↔ s = ∅ :=
iff.intro eq_empty_of_subset_empty (take xeq, by rewrite xeq; apply subset.refl ∅) iff.intro eq_empty_of_subset_empty (take xeq, by rewrite xeq; apply subset.refl ∅)
lemma bounded_forall_empty_iff {P : X → Prop} :
(∀₀x∈∅, P x) ↔ true :=
iff.intro (take H, true.intro) (take H, by contradiction)
/- universal set -/ /- universal set -/
definition univ : set X := λx, true definition univ : set X := λx, true
@ -287,6 +339,18 @@ theorem forall_of_forall_insert {P : X → Prop} {a : X} {s : set X}
∀ x, x ∈ s → P x := ∀ x, x ∈ s → P x :=
λ x xs, H x (!mem_insert_of_mem xs) λ x xs, H x (!mem_insert_of_mem xs)
lemma forall_insert_iff {P : X → Prop} {a : X} {s : set X} :
(∀₀x ∈ insert a s, P x) ↔ P a ∧ (∀₀x ∈ s, P x) :=
begin
apply iff.intro, all_goals (intro H),
{ apply and.intro,
{ apply H, apply mem_insert },
{ intro x Hx, apply H, apply mem_insert_of_mem, assumption } },
{ intro x Hx, cases Hx with eq Hx,
{ cases eq, apply (and.elim_left H) },
{ apply (and.elim_right H), assumption } }
end
/- singleton -/ /- singleton -/
theorem mem_singleton_iff (a b : X) : a ∈ '{b} ↔ a = b := theorem mem_singleton_iff (a b : X) : a ∈ '{b} ↔ a = b :=
@ -521,8 +585,45 @@ theorem complement_complement_image (S : set (set X)) :
complement ' (complement ' S) = S := complement ' (complement ' S) = S :=
by rewrite [-image_compose, complement_compose_complement, image_id] by rewrite [-image_compose, complement_compose_complement, image_id]
lemma forall_image_implies_forall {f : X → Y} {S : set X} {P : Y → Prop} (H : ∀₀ x ∈ S, P (f x)) :
∀₀ y ∈ f ' S, P y :=
begin
intro x' Hx;
cases Hx with x Hx;
cases Hx with Hx eq;
rewrite (eq⁻¹);
apply H;
assumption
end
lemma forall_image_iff {f : X → Y} {S : set X} {P : Y → Prop} :
(∀₀ y ∈ f ' S, P y) ↔ (∀₀ x ∈ S, P (f x)) :=
iff.intro (take H x Hx, H _ (!mem_image_of_mem `x ∈ S`)) forall_image_implies_forall
lemma image_insert_eq {f : X → Y} {a : X} {S : set X} :
f ' insert a S = insert (f a) (f ' S) :=
begin
apply set.ext,
intro x, apply iff.intro, all_goals (intros H),
{ cases H with y Hy, cases Hy with Hy eq, rewrite (eq⁻¹), cases Hy with y_eq,
{ rewrite y_eq, apply mem_insert },
{ apply mem_insert_of_mem, apply mem_image_of_mem, assumption } },
{ cases H with eq Hx,
{ rewrite eq, apply mem_image_of_mem, apply mem_insert },
{ cases Hx with y Hy, cases Hy with Hy eq,
rewrite (eq⁻¹), apply mem_image_of_mem, apply mem_insert_of_mem, assumption } }
end
end image end image
/- function pre image -/
definition preimage {A B:Type} (f : A → B) (Y : set B) : set A := { x | f x ∈ Y }
lemma image_subset_iff {A B : Type} {f : A → B} {X : set A} {Y : set B} :
f ' X ⊆ Y ↔ X ⊆ preimage f Y :=
@forall_image_iff A B f X Y
/- collections of disjoint sets -/ /- collections of disjoint sets -/
definition disjoint_sets (S : set (set X)) : Prop := ∀ a b, a ∈ S → b ∈ S → a ≠ b → a ∩ b = ∅ definition disjoint_sets (S : set (set X)) : Prop := ∀ a b, a ∈ S → b ∈ S → a ≠ b → a ∩ b = ∅

View file

@ -159,6 +159,18 @@ propext (iff.intro
(assume H, eq.of_iff H) (assume H, eq.of_iff H)
(assume H, iff.of_eq H)) (assume H, iff.of_eq H))
lemma eq_false {a : Prop} : (a = false) = (¬ a) :=
begin
rewrite ((@iff_eq_eq a false)⁻¹),
rewrite iff_false
end
lemma eq_true {a : Prop} : (a = true) = a :=
begin
rewrite ((@iff_eq_eq a true)⁻¹),
rewrite iff_true
end
end aux end aux
/- All propositions are decidable -/ /- All propositions are decidable -/

View file

@ -342,6 +342,11 @@ iff.intro
(λHab Hc, iff.mp H2 (Hab (iff.mpr H1 Hc))) (λHab Hc, iff.mp H2 (Hab (iff.mpr H1 Hc)))
(λHcd Ha, iff.mpr H2 (Hcd (iff.mp H1 Ha))) (λHcd Ha, iff.mpr H2 (Hcd (iff.mp H1 Ha)))
theorem imp_congr_right (H : a → (b ↔ c)) : (a → b) ↔ (a → c) :=
iff.intro
(take Hab Ha, iff.elim_left (H Ha) (Hab Ha))
(take Hab Ha, iff.elim_right (H Ha) (Hab Ha))
theorem not_not_intro (Ha : a) : ¬¬a := theorem not_not_intro (Ha : a) : ¬¬a :=
assume Hna : ¬a, Hna Ha assume Hna : ¬a, Hna Ha
@ -392,6 +397,11 @@ and.rec (λHa Hb, and.intro (H₂ Ha) (H₃ Hb))
theorem and_congr [congr] (H1 : a ↔ c) (H2 : b ↔ d) : (a ∧ b) ↔ (c ∧ d) := theorem and_congr [congr] (H1 : a ↔ c) (H2 : b ↔ d) : (a ∧ b) ↔ (c ∧ d) :=
iff.intro (and.imp (iff.mp H1) (iff.mp H2)) (and.imp (iff.mpr H1) (iff.mpr H2)) iff.intro (and.imp (iff.mp H1) (iff.mp H2)) (and.imp (iff.mpr H1) (iff.mpr H2))
theorem and_congr_right (H : a → (b ↔ c)) : (a ∧ b) ↔ (a ∧ c) :=
iff.intro
(take Hab, obtain `a` `b`, from Hab, and.intro `a` (iff.elim_left (H `a`) `b`))
(take Hac, obtain `a` `c`, from Hac, and.intro `a` (iff.elim_right (H `a`) `c`))
theorem and.comm [simp] : a ∧ b ↔ b ∧ a := theorem and.comm [simp] : a ∧ b ↔ b ∧ a :=
iff.intro and.swap and.swap iff.intro and.swap and.swap