2015-05-17 07:50:32 +00:00
|
|
|
|
/-
|
|
|
|
|
Copyright (c) 2015 Microsoft Corporation. All rights reserved.
|
|
|
|
|
Released under Apache 2.0 license as described in the file LICENSE.
|
2015-06-04 08:51:34 +00:00
|
|
|
|
Author: Jeremy Avigad, Haitao Zhang
|
2015-05-17 07:50:32 +00:00
|
|
|
|
|
|
|
|
|
Finite unions and intersections on finsets.
|
|
|
|
|
|
|
|
|
|
Note: for the moment we only do unions. We need to generalize bigops for intersections.
|
|
|
|
|
-/
|
|
|
|
|
import data.finset.comb algebra.group_bigops
|
|
|
|
|
open list
|
|
|
|
|
|
|
|
|
|
namespace finset
|
|
|
|
|
|
|
|
|
|
variables {A B : Type} [deceqA : decidable_eq A] [deceqB : decidable_eq B]
|
|
|
|
|
|
|
|
|
|
/- Unionl and Union -/
|
|
|
|
|
|
|
|
|
|
section union
|
|
|
|
|
|
2015-12-13 19:15:10 +00:00
|
|
|
|
definition to_comm_monoid_Union (B : Type) [decidable_eq B] :
|
2015-12-06 07:27:46 +00:00
|
|
|
|
comm_monoid (finset B) :=
|
|
|
|
|
⦃ comm_monoid,
|
2015-05-17 07:50:32 +00:00
|
|
|
|
mul := union,
|
|
|
|
|
mul_assoc := union.assoc,
|
|
|
|
|
one := empty,
|
|
|
|
|
mul_one := union_empty,
|
|
|
|
|
one_mul := empty_union,
|
|
|
|
|
mul_comm := union.comm
|
|
|
|
|
⦄
|
|
|
|
|
|
|
|
|
|
local attribute finset.to_comm_monoid_Union [instance]
|
|
|
|
|
|
|
|
|
|
include deceqB
|
|
|
|
|
|
2015-12-06 07:27:46 +00:00
|
|
|
|
definition Unionl (l : list A) (f : A → finset B) : finset B := Prodl l f
|
2015-05-17 07:50:32 +00:00
|
|
|
|
notation `⋃` binders `←` l, r:(scoped f, Unionl l f) := r
|
2015-12-06 07:27:46 +00:00
|
|
|
|
definition Union (s : finset A) (f : A → finset B) : finset B := finset.Prod s f
|
2015-05-17 07:50:32 +00:00
|
|
|
|
notation `⋃` binders `∈` s, r:(scoped f, finset.Union s f) := r
|
|
|
|
|
|
2015-12-06 07:27:46 +00:00
|
|
|
|
theorem Unionl_nil (f : A → finset B) : Unionl [] f = ∅ := Prodl_nil f
|
2015-05-17 07:50:32 +00:00
|
|
|
|
theorem Unionl_cons (f : A → finset B) (a : A) (l : list A) :
|
2015-12-06 07:27:46 +00:00
|
|
|
|
Unionl (a::l) f = f a ∪ Unionl l f := Prodl_cons f a l
|
2015-05-17 07:50:32 +00:00
|
|
|
|
theorem Unionl_append (l₁ l₂ : list A) (f : A → finset B) :
|
2015-12-06 07:27:46 +00:00
|
|
|
|
Unionl (l₁++l₂) f = Unionl l₁ f ∪ Unionl l₂ f := Prodl_append l₁ l₂ f
|
2015-05-17 07:50:32 +00:00
|
|
|
|
theorem Unionl_mul (l : list A) (f g : A → finset B) :
|
2015-12-06 07:27:46 +00:00
|
|
|
|
Unionl l (λx, f x ∪ g x) = Unionl l f ∪ Unionl l g := Prodl_mul l f g
|
2015-05-17 07:50:32 +00:00
|
|
|
|
section deceqA
|
|
|
|
|
include deceqA
|
|
|
|
|
theorem Unionl_insert_of_mem (f : A → finset B) {a : A} {l : list A} (H : a ∈ l) :
|
2015-12-06 07:27:46 +00:00
|
|
|
|
Unionl (list.insert a l) f = Unionl l f := Prodl_insert_of_mem f H
|
2015-05-17 07:50:32 +00:00
|
|
|
|
theorem Unionl_insert_of_not_mem (f : A → finset B) {a : A} {l : list A} (H : a ∉ l) :
|
2015-12-06 07:27:46 +00:00
|
|
|
|
Unionl (list.insert a l) f = f a ∪ Unionl l f := Prodl_insert_of_not_mem f H
|
2015-05-17 07:50:32 +00:00
|
|
|
|
theorem Unionl_union {l₁ l₂ : list A} (f : A → finset B) (d : list.disjoint l₁ l₂) :
|
2015-12-06 07:27:46 +00:00
|
|
|
|
Unionl (list.union l₁ l₂) f = Unionl l₁ f ∪ Unionl l₂ f := Prodl_union f d
|
|
|
|
|
theorem Unionl_empty (l : list A) : Unionl l (λ x, ∅) = (∅ : finset B) := Prodl_one l
|
2015-05-17 07:50:32 +00:00
|
|
|
|
end deceqA
|
|
|
|
|
|
2015-12-06 07:27:46 +00:00
|
|
|
|
theorem Union_empty (f : A → finset B) : Union ∅ f = ∅ := finset.Prod_empty f
|
2015-05-17 07:50:32 +00:00
|
|
|
|
theorem Union_mul (s : finset A) (f g : A → finset B) :
|
2015-12-06 07:27:46 +00:00
|
|
|
|
Union s (λx, f x ∪ g x) = Union s f ∪ Union s g := finset.Prod_mul s f g
|
2015-05-17 07:50:32 +00:00
|
|
|
|
section deceqA
|
|
|
|
|
include deceqA
|
|
|
|
|
theorem Union_insert_of_mem (f : A → finset B) {a : A} {s : finset A} (H : a ∈ s) :
|
2015-12-06 07:27:46 +00:00
|
|
|
|
Union (insert a s) f = Union s f := finset.Prod_insert_of_mem f H
|
2015-06-04 08:51:34 +00:00
|
|
|
|
private theorem Union_insert_of_not_mem (f : A → finset B) {a : A} {s : finset A} (H : a ∉ s) :
|
2015-12-06 07:27:46 +00:00
|
|
|
|
Union (insert a s) f = f a ∪ Union s f := finset.Prod_insert_of_not_mem f H
|
2015-05-17 07:50:32 +00:00
|
|
|
|
theorem Union_union (f : A → finset B) {s₁ s₂ : finset A} (disj : s₁ ∩ s₂ = ∅) :
|
2015-12-06 07:27:46 +00:00
|
|
|
|
Union (s₁ ∪ s₂) f = Union s₁ f ∪ Union s₂ f := finset.Prod_union f disj
|
2015-05-17 07:50:32 +00:00
|
|
|
|
theorem Union_ext {s : finset A} {f g : A → finset B} (H : ∀x, x ∈ s → f x = g x) :
|
2015-12-06 07:27:46 +00:00
|
|
|
|
Union s f = Union s g := finset.Prod_ext H
|
|
|
|
|
theorem Union_empty' (s : finset A) : Union s (λ x, ∅) = (∅ : finset B) := finset.Prod_one s
|
2015-05-17 07:50:32 +00:00
|
|
|
|
|
|
|
|
|
-- this will eventually be an instance of something more general
|
|
|
|
|
theorem inter_Union (s : finset B) (t : finset A) (f : A → finset B) :
|
|
|
|
|
s ∩ (⋃ x ∈ t, f x) = (⋃ x ∈ t, s ∩ f x) :=
|
2015-05-19 21:18:36 +00:00
|
|
|
|
begin
|
|
|
|
|
induction t with s' x H IH,
|
|
|
|
|
rewrite [*Union_empty, inter_empty],
|
|
|
|
|
rewrite [*Union_insert_of_not_mem _ H, inter.distrib_left, IH],
|
|
|
|
|
end
|
2015-05-17 07:50:32 +00:00
|
|
|
|
|
|
|
|
|
theorem mem_Union_iff (s : finset A) (f : A → finset B) (b : B) :
|
|
|
|
|
b ∈ (⋃ x ∈ s, f x) ↔ (∃ x, x ∈ s ∧ b ∈ f x ) :=
|
2015-05-19 21:18:36 +00:00
|
|
|
|
begin
|
|
|
|
|
induction s with s' a H IH,
|
|
|
|
|
rewrite [exists_mem_empty_eq],
|
|
|
|
|
rewrite [Union_insert_of_not_mem _ H, mem_union_eq, IH, exists_mem_insert_eq]
|
|
|
|
|
end
|
2015-05-17 07:50:32 +00:00
|
|
|
|
|
|
|
|
|
theorem mem_Union_eq (s : finset A) (f : A → finset B) (b : B) :
|
|
|
|
|
b ∈ (⋃ x ∈ s, f x) = (∃ x, x ∈ s ∧ b ∈ f x ) :=
|
|
|
|
|
propext !mem_Union_iff
|
2015-06-04 08:51:34 +00:00
|
|
|
|
|
|
|
|
|
theorem Union_insert (f : A → finset B) {a : A} {s : finset A} :
|
|
|
|
|
Union (insert a s) f = f a ∪ Union s f :=
|
|
|
|
|
decidable.by_cases
|
|
|
|
|
(assume Pin : a ∈ s,
|
|
|
|
|
begin
|
|
|
|
|
rewrite [Union_insert_of_mem f Pin],
|
|
|
|
|
apply ext,
|
|
|
|
|
intro x,
|
|
|
|
|
apply iff.intro,
|
|
|
|
|
exact mem_union_r,
|
|
|
|
|
rewrite [mem_union_eq],
|
|
|
|
|
intro Por,
|
|
|
|
|
exact or.elim Por
|
|
|
|
|
(assume Pl, begin
|
|
|
|
|
rewrite mem_Union_eq, exact (exists.intro a (and.intro Pin Pl)) end)
|
|
|
|
|
(assume Pr, Pr)
|
|
|
|
|
end)
|
|
|
|
|
(assume H : a ∉ s, !Union_insert_of_not_mem H)
|
|
|
|
|
|
|
|
|
|
lemma image_eq_Union_index_image (s : finset A) (f : A → finset B) :
|
2015-11-21 00:38:10 +00:00
|
|
|
|
Union s f = Union (image f s) id :=
|
2015-06-04 08:51:34 +00:00
|
|
|
|
finset.induction_on s
|
|
|
|
|
(by rewrite Union_empty)
|
|
|
|
|
(take s1 a Pa IH, by rewrite [image_insert, *Union_insert, IH])
|
2015-07-11 01:58:20 +00:00
|
|
|
|
|
2015-12-13 19:15:10 +00:00
|
|
|
|
lemma Union_const [decidable_eq B] {f : A → finset B} {s : finset A} {t : finset B} :
|
2015-07-11 04:43:18 +00:00
|
|
|
|
s ≠ ∅ → (∀ x, x ∈ s → f x = t) → Union s f = t :=
|
2015-07-11 01:58:20 +00:00
|
|
|
|
begin
|
|
|
|
|
induction s with a' s' H IH,
|
|
|
|
|
{intros [H1, H2], exfalso, apply H1 !rfl},
|
|
|
|
|
intros [H1, H2],
|
|
|
|
|
rewrite [Union_insert, H2 _ !mem_insert],
|
|
|
|
|
cases (decidable.em (s' = ∅)) with [seq, sne],
|
2015-07-11 02:09:36 +00:00
|
|
|
|
{rewrite [seq, Union_empty, union_empty]},
|
2015-07-11 01:58:20 +00:00
|
|
|
|
have H3 : ∀ x, x ∈ s' → f x = t, from (λ x H', H2 x (mem_insert_of_mem _ H')),
|
|
|
|
|
rewrite [IH sne H3, union_self]
|
|
|
|
|
end
|
2015-05-17 07:50:32 +00:00
|
|
|
|
end deceqA
|
|
|
|
|
|
|
|
|
|
end union
|
|
|
|
|
|
|
|
|
|
end finset
|