2015-05-08 03:38:55 +00:00
|
|
|
|
/-
|
|
|
|
|
Copyright (c) 2015 Microsoft Corporation. All rights reserved.
|
|
|
|
|
Released under Apache 2.0 license as described in the file LICENSE.
|
|
|
|
|
Author: Jeremy Avigad
|
|
|
|
|
|
|
|
|
|
Cardinality calculations for finite sets.
|
|
|
|
|
-/
|
2015-12-06 07:27:46 +00:00
|
|
|
|
import .to_set .bigops data.set.function data.nat.power
|
|
|
|
|
open nat eq.ops
|
2015-05-08 03:38:55 +00:00
|
|
|
|
|
|
|
|
|
namespace finset
|
|
|
|
|
|
2015-05-10 10:07:03 +00:00
|
|
|
|
variables {A B : Type}
|
|
|
|
|
variables [deceqA : decidable_eq A] [deceqB : decidable_eq B]
|
|
|
|
|
include deceqA
|
2015-05-08 03:38:55 +00:00
|
|
|
|
|
|
|
|
|
theorem card_add_card (s₁ s₂ : finset A) : card s₁ + card s₂ = card (s₁ ∪ s₂) + card (s₁ ∩ s₂) :=
|
2015-05-19 22:56:51 +00:00
|
|
|
|
begin
|
2015-05-25 08:37:07 +00:00
|
|
|
|
induction s₂ with a s₂ ans2 IH,
|
|
|
|
|
show card s₁ + card (∅:finset A) = card (s₁ ∪ ∅) + card (s₁ ∩ ∅),
|
|
|
|
|
by rewrite [union_empty, card_empty, inter_empty],
|
|
|
|
|
show card s₁ + card (insert a s₂) = card (s₁ ∪ (insert a s₂)) + card (s₁ ∩ (insert a s₂)),
|
|
|
|
|
from decidable.by_cases
|
|
|
|
|
(assume as1 : a ∈ s₁,
|
|
|
|
|
assert H : a ∉ s₁ ∩ s₂, from assume H', ans2 (mem_of_mem_inter_right H'),
|
|
|
|
|
begin
|
|
|
|
|
rewrite [card_insert_of_not_mem ans2, union.comm, -insert_union, union.comm],
|
|
|
|
|
rewrite [insert_union, insert_eq_of_mem as1, insert_eq, inter.distrib_left, inter.comm],
|
|
|
|
|
rewrite [singleton_inter_of_mem as1, -insert_eq, card_insert_of_not_mem H, -*add.assoc],
|
|
|
|
|
rewrite IH
|
|
|
|
|
end)
|
|
|
|
|
(assume ans1 : a ∉ s₁,
|
|
|
|
|
assert H : a ∉ s₁ ∪ s₂, from assume H',
|
|
|
|
|
or.elim (mem_or_mem_of_mem_union H') (assume as1, ans1 as1) (assume as2, ans2 as2),
|
|
|
|
|
begin
|
|
|
|
|
rewrite [card_insert_of_not_mem ans2, union.comm, -insert_union, union.comm],
|
|
|
|
|
rewrite [card_insert_of_not_mem H, insert_eq, inter.distrib_left, inter.comm],
|
|
|
|
|
rewrite [singleton_inter_of_not_mem ans1, empty_union, add.right_comm],
|
|
|
|
|
rewrite [-add.assoc, IH]
|
|
|
|
|
end)
|
2015-05-19 22:56:51 +00:00
|
|
|
|
end
|
2015-05-08 03:38:55 +00:00
|
|
|
|
|
|
|
|
|
theorem card_union (s₁ s₂ : finset A) : card (s₁ ∪ s₂) = card s₁ + card s₂ - card (s₁ ∩ s₂) :=
|
|
|
|
|
calc
|
2015-10-09 01:35:37 +00:00
|
|
|
|
card (s₁ ∪ s₂) = card (s₁ ∪ s₂) + card (s₁ ∩ s₂) - card (s₁ ∩ s₂) : nat.add_sub_cancel
|
2015-05-08 03:38:55 +00:00
|
|
|
|
... = card s₁ + card s₂ - card (s₁ ∩ s₂) : card_add_card
|
|
|
|
|
|
2015-05-17 09:06:10 +00:00
|
|
|
|
theorem card_union_of_disjoint {s₁ s₂ : finset A} (H : s₁ ∩ s₂ = ∅) :
|
2015-05-08 03:38:55 +00:00
|
|
|
|
card (s₁ ∪ s₂) = card s₁ + card s₂ :=
|
2015-05-17 09:06:10 +00:00
|
|
|
|
by rewrite [card_union, H]
|
2015-05-08 03:38:55 +00:00
|
|
|
|
|
2015-06-20 11:37:37 +00:00
|
|
|
|
theorem card_eq_card_add_card_diff {s₁ s₂ : finset A} (H : s₁ ⊆ s₂) :
|
|
|
|
|
card s₂ = card s₁ + card (s₂ \ s₁) :=
|
2015-05-17 09:06:10 +00:00
|
|
|
|
have H1 : s₁ ∩ (s₂ \ s₁) = ∅,
|
|
|
|
|
from inter_eq_empty (take x, assume H1 H2, not_mem_of_mem_diff H2 H1),
|
2015-05-08 03:38:55 +00:00
|
|
|
|
calc
|
|
|
|
|
card s₂ = card (s₁ ∪ (s₂ \ s₁)) : union_diff_cancel H
|
|
|
|
|
... = card s₁ + card (s₂ \ s₁) : card_union_of_disjoint H1
|
2015-06-20 11:37:37 +00:00
|
|
|
|
|
|
|
|
|
theorem card_le_card_of_subset {s₁ s₂ : finset A} (H : s₁ ⊆ s₂) : card s₁ ≤ card s₂ :=
|
|
|
|
|
calc
|
|
|
|
|
card s₂ = card s₁ + card (s₂ \ s₁) : card_eq_card_add_card_diff H
|
2015-05-08 03:38:55 +00:00
|
|
|
|
... ≥ card s₁ : le_add_right
|
|
|
|
|
|
2015-05-10 10:07:03 +00:00
|
|
|
|
section card_image
|
|
|
|
|
open set
|
|
|
|
|
include deceqB
|
|
|
|
|
|
2015-06-05 09:32:42 +00:00
|
|
|
|
theorem card_image_eq_of_inj_on {f : A → B} {s : finset A} (H1 : inj_on f (ts s)) :
|
|
|
|
|
card (image f s) = card s :=
|
2015-05-19 22:56:51 +00:00
|
|
|
|
begin
|
2015-05-25 08:37:07 +00:00
|
|
|
|
induction s with a t H IH,
|
2015-05-19 22:56:51 +00:00
|
|
|
|
{ rewrite [card_empty] },
|
|
|
|
|
{ have H2 : ts t ⊆ ts (insert a t), by rewrite [-subset_eq_to_set_subset]; apply subset_insert,
|
|
|
|
|
have H3 : card (image f t) = card t, from IH (inj_on_of_inj_on_of_subset H1 H2),
|
|
|
|
|
have H4 : f a ∉ image f t,
|
2015-05-10 10:07:03 +00:00
|
|
|
|
proof
|
|
|
|
|
assume H5 : f a ∈ image f t,
|
2015-05-11 16:14:48 +00:00
|
|
|
|
obtain x (H6l : x ∈ t) (H6r : f x = f a), from exists_of_mem_image H5,
|
|
|
|
|
have H7 : x = a, from H1 (mem_insert_of_mem _ H6l) !mem_insert H6r,
|
|
|
|
|
show false, from H (H7 ▸ H6l)
|
2015-05-10 10:07:03 +00:00
|
|
|
|
qed,
|
2015-05-19 22:56:51 +00:00
|
|
|
|
calc
|
|
|
|
|
card (image f (insert a t)) = card (insert (f a) (image f t)) : image_insert
|
|
|
|
|
... = card (image f t) + 1 : card_insert_of_not_mem H4
|
|
|
|
|
... = card t + 1 : H3
|
|
|
|
|
... = card (insert a t) : card_insert_of_not_mem H
|
|
|
|
|
}
|
|
|
|
|
end
|
2015-06-05 09:32:42 +00:00
|
|
|
|
|
|
|
|
|
lemma card_le_of_inj_on (a : finset A) (b : finset B)
|
|
|
|
|
(Pex : ∃ f : A → B, set.inj_on f (ts a) ∧ (image f a ⊆ b)):
|
|
|
|
|
card a ≤ card b :=
|
|
|
|
|
obtain f Pinj, from Pex,
|
|
|
|
|
assert Psub : _, from and.right Pinj,
|
|
|
|
|
assert Ple : card (image f a) ≤ card b, from card_le_card_of_subset Psub,
|
|
|
|
|
by rewrite [(card_image_eq_of_inj_on (and.left Pinj))⁻¹]; exact Ple
|
|
|
|
|
|
2015-06-10 07:39:50 +00:00
|
|
|
|
theorem card_image_le (f : A → B) (s : finset A) : card (image f s) ≤ card s :=
|
|
|
|
|
finset.induction_on s
|
|
|
|
|
(by rewrite finset.image_empty)
|
|
|
|
|
(take a s',
|
|
|
|
|
assume Ha : a ∉ s',
|
|
|
|
|
assume IH : card (image f s') ≤ card s',
|
|
|
|
|
begin
|
|
|
|
|
rewrite [image_insert, card_insert_of_not_mem Ha],
|
|
|
|
|
apply le.trans !card_insert_le,
|
|
|
|
|
apply add_le_add_right IH
|
|
|
|
|
end)
|
|
|
|
|
|
|
|
|
|
theorem inj_on_of_card_image_eq {f : A → B} {s : finset A} :
|
|
|
|
|
card (image f s) = card s → inj_on f (ts s) :=
|
|
|
|
|
finset.induction_on s
|
2015-06-11 01:46:16 +00:00
|
|
|
|
(by intro H; rewrite to_set_empty; apply inj_on_empty)
|
2015-06-10 07:39:50 +00:00
|
|
|
|
(begin
|
|
|
|
|
intro a s' Ha IH,
|
2015-06-11 01:46:16 +00:00
|
|
|
|
rewrite [image_insert, card_insert_of_not_mem Ha, to_set_insert],
|
2015-06-10 07:39:50 +00:00
|
|
|
|
assume H1 : card (insert (f a) (image f s')) = card s' + 1,
|
|
|
|
|
show inj_on f (set.insert a (ts s')), from
|
|
|
|
|
decidable.by_cases
|
|
|
|
|
(assume Hfa : f a ∈ image f s',
|
|
|
|
|
have H2 : card (image f s') = card s' + 1,
|
|
|
|
|
by rewrite [card_insert_of_mem Hfa at H1]; assumption,
|
|
|
|
|
absurd
|
|
|
|
|
(calc
|
|
|
|
|
card (image f s') ≤ card s' : !card_image_le
|
|
|
|
|
... < card s' + 1 : lt_succ_self
|
|
|
|
|
... = card (image f s') : H2)
|
|
|
|
|
!lt.irrefl)
|
|
|
|
|
(assume Hnfa : f a ∉ image f s',
|
|
|
|
|
have H2 : card (image f s') + 1 = card s' + 1,
|
|
|
|
|
by rewrite [card_insert_of_not_mem Hnfa at H1]; assumption,
|
2015-10-22 20:09:26 +00:00
|
|
|
|
have H3 : card (image f s') = card s', from add.right_cancel H2,
|
2015-06-10 07:39:50 +00:00
|
|
|
|
have injf : inj_on f (ts s'), from IH H3,
|
|
|
|
|
show inj_on f (set.insert a (ts s')), from
|
|
|
|
|
take x1 x2,
|
|
|
|
|
assume Hx1 : x1 ∈ set.insert a (ts s'),
|
|
|
|
|
assume Hx2 : x2 ∈ set.insert a (ts s'),
|
|
|
|
|
assume feq : f x1 = f x2,
|
|
|
|
|
or.elim Hx1
|
|
|
|
|
(assume Hx1' : x1 = a,
|
|
|
|
|
or.elim Hx2
|
|
|
|
|
(assume Hx2' : x2 = a, by rewrite [Hx1', Hx2'])
|
|
|
|
|
(assume Hx2' : x2 ∈ ts s',
|
|
|
|
|
have Hfa : f a ∈ image f s',
|
|
|
|
|
by rewrite [-Hx1', feq]; apply mem_image_of_mem f Hx2',
|
|
|
|
|
absurd Hfa Hnfa))
|
|
|
|
|
(assume Hx1' : x1 ∈ ts s',
|
|
|
|
|
or.elim Hx2
|
|
|
|
|
(assume Hx2' : x2 = a,
|
|
|
|
|
have Hfa : f a ∈ image f s',
|
|
|
|
|
by rewrite [-Hx2', -feq]; apply mem_image_of_mem f Hx1',
|
|
|
|
|
absurd Hfa Hnfa)
|
|
|
|
|
(assume Hx2' : x2 ∈ ts s', injf Hx1' Hx2' feq)))
|
|
|
|
|
end)
|
|
|
|
|
|
2015-05-10 10:07:03 +00:00
|
|
|
|
end card_image
|
|
|
|
|
|
2015-06-20 11:37:37 +00:00
|
|
|
|
theorem card_pos_of_mem {a : A} {s : finset A} (H : a ∈ s) : card s > 0 :=
|
|
|
|
|
begin
|
|
|
|
|
induction s with a s' H1 IH,
|
|
|
|
|
{ contradiction },
|
|
|
|
|
{ rewrite (card_insert_of_not_mem H1), apply succ_pos }
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
theorem eq_of_card_eq_of_subset {s₁ s₂ : finset A} (Hcard : card s₁ = card s₂) (Hsub : s₁ ⊆ s₂) :
|
|
|
|
|
s₁ = s₂ :=
|
|
|
|
|
have H : card s₁ + 0 = card s₁ + card (s₂ \ s₁),
|
|
|
|
|
by rewrite [Hcard at {1}, card_eq_card_add_card_diff Hsub],
|
|
|
|
|
assert H1 : s₂ \ s₁ = ∅, from eq_empty_of_card_eq_zero (add.left_cancel H)⁻¹,
|
|
|
|
|
by rewrite [-union_diff_cancel Hsub, H1, union_empty]
|
|
|
|
|
|
2015-08-08 00:13:39 +00:00
|
|
|
|
lemma exists_two_of_card_gt_one {s : finset A} : 1 < card s → ∃ a b, a ∈ s ∧ b ∈ s ∧ a ≠ b :=
|
|
|
|
|
begin
|
|
|
|
|
intro h,
|
|
|
|
|
induction s with a s nain ih₁,
|
|
|
|
|
{exact absurd h dec_trivial},
|
|
|
|
|
{induction s with b s nbin ih₂,
|
|
|
|
|
{exact absurd h dec_trivial},
|
|
|
|
|
clear ih₁ ih₂,
|
|
|
|
|
existsi a, existsi b, split,
|
|
|
|
|
{apply mem_insert},
|
|
|
|
|
split,
|
|
|
|
|
{apply mem_insert_of_mem _ !mem_insert},
|
|
|
|
|
{intro aeqb, subst a, exact absurd !mem_insert nain}}
|
|
|
|
|
end
|
|
|
|
|
|
2015-05-17 09:06:10 +00:00
|
|
|
|
theorem Sum_const_eq_card_mul (s : finset A) (n : nat) : (∑ x ∈ s, n) = card s * n :=
|
2015-05-19 22:56:51 +00:00
|
|
|
|
begin
|
2015-05-25 08:37:07 +00:00
|
|
|
|
induction s with a s' H IH,
|
2015-05-19 22:56:51 +00:00
|
|
|
|
rewrite [Sum_empty, card_empty, zero_mul],
|
|
|
|
|
rewrite [Sum_insert_of_not_mem _ H, IH, card_insert_of_not_mem H, add.comm,
|
2015-10-14 19:27:09 +00:00
|
|
|
|
right_distrib, one_mul]
|
2015-05-19 22:56:51 +00:00
|
|
|
|
end
|
2015-05-17 09:06:10 +00:00
|
|
|
|
|
|
|
|
|
theorem Sum_one_eq_card (s : finset A) : (∑ x ∈ s, (1 : nat)) = card s :=
|
|
|
|
|
eq.trans !Sum_const_eq_card_mul !mul_one
|
|
|
|
|
|
|
|
|
|
section deceqB
|
|
|
|
|
include deceqB
|
|
|
|
|
|
|
|
|
|
theorem card_Union_of_disjoint (s : finset A) (f : A → finset B) :
|
|
|
|
|
(∀{a₁ a₂}, a₁ ∈ s → a₂ ∈ s → a₁ ≠ a₂ → f a₁ ∩ f a₂ = ∅) →
|
|
|
|
|
card (⋃ x ∈ s, f x) = ∑ x ∈ s, card (f x) :=
|
|
|
|
|
finset.induction_on s
|
|
|
|
|
(assume H, by rewrite [Union_empty, Sum_empty, card_empty])
|
2015-05-25 08:37:07 +00:00
|
|
|
|
(take a s', assume H : a ∉ s',
|
2015-05-17 09:06:10 +00:00
|
|
|
|
assume IH,
|
|
|
|
|
assume H1 : ∀ {a₁ a₂ : A}, a₁ ∈ insert a s' → a₂ ∈ insert a s' → a₁ ≠ a₂ → f a₁ ∩ f a₂ = ∅,
|
|
|
|
|
have H2 : ∀ a₁ a₂ : A, a₁ ∈ s' → a₂ ∈ s' → a₁ ≠ a₂ → f a₁ ∩ f a₂ = ∅, from
|
|
|
|
|
take a₁ a₂, assume H3 H4 H5,
|
|
|
|
|
H1 (!mem_insert_of_mem H3) (!mem_insert_of_mem H4) H5,
|
|
|
|
|
assert H6 : card (⋃ (x : A) ∈ s', f x) = ∑ (x : A) ∈ s', card (f x), from IH H2,
|
2015-06-18 22:41:00 +00:00
|
|
|
|
assert H7 : ∀ x, x ∈ s' → f a ∩ f x = ∅, from
|
2015-05-17 09:06:10 +00:00
|
|
|
|
take x, assume xs',
|
|
|
|
|
have anex : a ≠ x, from assume aex, (eq.subst aex H) xs',
|
|
|
|
|
H1 !mem_insert (!mem_insert_of_mem xs') anex,
|
|
|
|
|
assert H8 : f a ∩ (⋃ (x : A) ∈ s', f x) = ∅, from
|
|
|
|
|
calc
|
2015-06-18 22:41:00 +00:00
|
|
|
|
f a ∩ (⋃ (x : A) ∈ s', f x) = (⋃ (x : A) ∈ s', f a ∩ f x) : by rewrite inter_Union
|
|
|
|
|
... = (⋃ (x : A) ∈ s', ∅) : by rewrite [Union_ext H7]
|
|
|
|
|
... = ∅ : by rewrite Union_empty',
|
2015-06-04 08:51:34 +00:00
|
|
|
|
by rewrite [Union_insert, Sum_insert_of_not_mem _ H,
|
2015-05-17 09:06:10 +00:00
|
|
|
|
card_union_of_disjoint H8, H6])
|
|
|
|
|
end deceqB
|
|
|
|
|
|
2015-07-03 20:59:37 +00:00
|
|
|
|
lemma dvd_Sum_of_dvd (f : A → nat) (n : nat) (s : finset A) : (∀ a, a ∈ s → n ∣ f a) → n ∣ Sum s f :=
|
|
|
|
|
begin
|
|
|
|
|
induction s with a s nain ih,
|
|
|
|
|
{intros, rewrite [Sum_empty], apply dvd_zero},
|
|
|
|
|
{intro h,
|
|
|
|
|
have h₁ : ∀ a, a ∈ s → n ∣ f a, from
|
|
|
|
|
take a, assume ains, h a (mem_insert_of_mem _ ains),
|
|
|
|
|
have h₂ : n ∣ Sum s f, from ih h₁,
|
|
|
|
|
have h₃ : n ∣ f a, from h a !mem_insert,
|
|
|
|
|
rewrite [Sum_insert_of_not_mem f nain],
|
|
|
|
|
apply dvd_add h₃ h₂}
|
|
|
|
|
end
|
2015-05-08 03:38:55 +00:00
|
|
|
|
end finset
|