Theory Freiman_3k_4
theory Freiman_3k_4
imports
Freiman_Sumset_Basics
"HOL-Computational_Algebra.Group_Closure"
Kneser_Cauchy_Davenport.Kneser_Cauchy_Davenport_main_proofs
begin
section ‹Freiman's @{text "3k - 4"} theorem for integer sumsets›
text ‹
This theory develops the integer-side infrastructure for Freiman's
@{text "3k - 4"} theorem. The final theorem is most naturally stated after
normalizing a finite integer set by translation and dilation; the lemmas
below record the affine invariance and interval containment facts used by
that reduction.
›
subsection ‹Integer arithmetic progressions›
definition int_ap_segment :: "int ⇒ int ⇒ nat ⇒ int set" where
"int_ap_segment a d n = (λi. a + int i * d) ` {..<n}"
definition int_arithmetic_progression :: "int set ⇒ bool" where
"int_arithmetic_progression A ⟷ (∃a d n. A = int_ap_segment a d n)"
lemma int_arithmetic_progressionI:
"A = int_ap_segment a d n ⟹ int_arithmetic_progression A"
unfolding int_arithmetic_progression_def by blast
lemma int_arithmetic_progressionE:
assumes "int_arithmetic_progression A"
obtains a d n where "A = int_ap_segment a d n"
using assms unfolding int_arithmetic_progression_def by blast
lemma finite_int_ap_segment [simp]:
"finite (int_ap_segment a d n)"
by (simp add: int_ap_segment_def)
lemma int_ap_segment_empty [simp]:
"int_ap_segment a d 0 = {}"
by (simp add: int_ap_segment_def)
lemma inj_on_int_ap_segment_index:
assumes "d ≠ 0"
shows "inj_on (λi. a + int i * d) {..<n}"
proof (rule inj_onI)
fix i j
assume i: "i ∈ {..<n}" and j: "j ∈ {..<n}"
assume eq: "a + int i * d = a + int j * d"
from eq have "int i * d = int j * d"
by simp
with assms have "int i = int j"
by simp
then show "i = j"
by simp
qed
lemma card_int_ap_segment:
assumes "d ≠ 0"
shows "card (int_ap_segment a d n) = n"
using assms
by (simp add: int_ap_segment_def card_image inj_on_int_ap_segment_index)
lemma int_ap_segment_one_eq_atLeastAtMost:
assumes "a ≤ b"
shows "int_ap_segment a 1 (nat (b - a + 1)) = {a..b}"
proof
show "int_ap_segment a 1 (nat (b - a + 1)) ⊆ {a..b}"
proof
fix x
assume "x ∈ int_ap_segment a 1 (nat (b - a + 1))"
then obtain i where i_lt: "i < nat (b - a + 1)" and x: "x = a + int i"
by (auto simp: int_ap_segment_def)
from assms have "0 < b - a + 1"
by linarith
with i_lt have "int i < b - a + 1"
by linarith
with x show "x ∈ {a..b}"
by auto
qed
next
show "{a..b} ⊆ int_ap_segment a 1 (nat (b - a + 1))"
proof
fix x
assume x_in: "x ∈ {a..b}"
then have ax_nonneg: "0 ≤ x - a"
by simp
define i where "i = nat (x - a)"
from ax_nonneg have int_i: "int i = x - a"
by (simp add: i_def)
from x_in have "x - a < b - a + 1"
by simp
with int_i have "i < nat (b - a + 1)"
by linarith
moreover have "x = a + int i"
using int_i by simp
ultimately show "x ∈ int_ap_segment a 1 (nat (b - a + 1))"
by (auto simp: int_ap_segment_def)
qed
qed
lemma finite_int_set_subset_min_max_ap:
assumes fin: "finite A" and nonempty: "A ≠ {}"
shows "A ⊆ int_ap_segment (Min A) 1 (nat (Max A - Min A + 1))"
proof -
have "Min A ≤ Max A"
using assms by simp
then have interval_eq: "int_ap_segment (Min A) 1 (nat (Max A - Min A + 1)) = {Min A..Max A}"
by (rule int_ap_segment_one_eq_atLeastAtMost)
have "A ⊆ {Min A..Max A}"
using assms by auto
then show ?thesis
using interval_eq by simp
qed
subsection ‹Affine images and sumsets›
definition affine_image_int :: "int ⇒ int ⇒ int set ⇒ int set" where
"affine_image_int c d A = (λx. c + d * x) ` A"
lemma affine_image_int_iff:
"x ∈ affine_image_int c d A ⟷ (∃a∈A. x = c + d * a)"
by (auto simp: affine_image_int_def)
lemma finite_affine_image_int [intro]:
assumes "finite A"
shows "finite (affine_image_int c d A)"
using assms by (simp add: affine_image_int_def)
lemma inj_on_affine_image_int:
fixes c d :: int
assumes "d ≠ 0"
shows "inj_on (λx. c + d * x) A"
proof (rule inj_onI)
fix x y
assume "x ∈ A" and "y ∈ A"
assume eq: "c + d * x = c + d * y"
have "(c + d * x) - c = (c + d * y) - c"
using eq by simp
then have "d * x = d * y"
by simp
with assms show "x = y"
by simp
qed
lemma card_affine_image_int:
assumes fin: "finite A" and d_nonzero: "d ≠ 0"
shows "card (affine_image_int c d A) = card A"
using fin inj_on_affine_image_int[OF d_nonzero, of c A]
by (simp add: affine_image_int_def card_image)
lemma affine_image_int_sumset:
"sumset (affine_image_int c d A) (affine_image_int e d B) =
affine_image_int (c + e) d (sumset A B)"
proof
show "sumset (affine_image_int c d A) (affine_image_int e d B) ⊆
affine_image_int (c + e) d (sumset A B)"
proof
fix x
assume "x ∈ sumset (affine_image_int c d A) (affine_image_int e d B)"
then obtain y z where
y: "y ∈ affine_image_int c d A"
and z: "z ∈ affine_image_int e d B"
and x: "x = y + z"
by (rule sumsetE)
from y obtain a where a: "a ∈ A" and y_eq: "y = c + d * a"
by (auto simp: affine_image_int_def)
from z obtain b where b: "b ∈ B" and z_eq: "z = e + d * b"
by (auto simp: affine_image_int_def)
have "a + b ∈ sumset A B"
using a b by (rule sumsetI)
moreover have "x = (c + e) + d * (a + b)"
using x y_eq z_eq by (simp add: algebra_simps)
ultimately show "x ∈ affine_image_int (c + e) d (sumset A B)"
by (auto simp: affine_image_int_def)
qed
next
show "affine_image_int (c + e) d (sumset A B) ⊆
sumset (affine_image_int c d A) (affine_image_int e d B)"
proof
fix x
assume "x ∈ affine_image_int (c + e) d (sumset A B)"
then obtain s where s: "s ∈ sumset A B" and x: "x = (c + e) + d * s"
by (auto simp: affine_image_int_def)
from s obtain a b where a: "a ∈ A" and b: "b ∈ B" and s_eq: "s = a + b"
by (rule sumsetE)
have "c + d * a ∈ affine_image_int c d A"
using a by (auto simp: affine_image_int_def)
moreover have "e + d * b ∈ affine_image_int e d B"
using b by (auto simp: affine_image_int_def)
moreover have "x = (c + d * a) + (e + d * b)"
using x s_eq by (simp add: algebra_simps)
ultimately show "x ∈ sumset (affine_image_int c d A) (affine_image_int e d B)"
by (metis sumsetI)
qed
qed
lemma affine_image_int_sumset_self:
"sumset (affine_image_int c d A) (affine_image_int c d A) =
affine_image_int (2 * c) d (sumset A A)"
proof -
have "sumset (affine_image_int c d A) (affine_image_int c d A) =
affine_image_int (c + c) d (sumset A A)"
by (rule affine_image_int_sumset)
also have "… = affine_image_int (2 * c) d (sumset A A)"
by simp
finally show ?thesis .
qed
lemma card_sumset_affine_image_int:
assumes finA: "finite A" and finB: "finite B" and d_nonzero: "d ≠ 0"
shows "card (sumset (affine_image_int c d A) (affine_image_int e d B)) =
card (sumset A B)"
proof -
have "card (sumset (affine_image_int c d A) (affine_image_int e d B)) =
card (affine_image_int (c + e) d (sumset A B))"
by (simp add: affine_image_int_sumset)
also have "… = card (sumset A B)"
by (rule card_affine_image_int[OF finite_sumset[OF finA finB] d_nonzero])
finally show ?thesis .
qed
lemma card_sumset_affine_image_int_self:
assumes fin: "finite A" and d_nonzero: "d ≠ 0"
shows "card (sumset (affine_image_int c d A) (affine_image_int c d A)) =
card (sumset A A)"
by (rule card_sumset_affine_image_int[OF fin fin d_nonzero])
lemma affine_image_int_zero_one [simp]:
"affine_image_int 0 1 A = A"
by (auto simp: affine_image_int_def)
subsection ‹Endpoint lower bound for two-fold sumsets›
lemma endpoint_affine_images_inter:
fixes A :: "int set"
assumes fin: "finite A" and nonempty: "A ≠ {}"
shows "affine_image_int (Min A) 1 A ∩ affine_image_int (Max A) 1 A =
{Min A + Max A}"
proof
show "affine_image_int (Min A) 1 A ∩ affine_image_int (Max A) 1 A ⊆
{Min A + Max A}"
proof
fix x
assume x_in: "x ∈ affine_image_int (Min A) 1 A ∩ affine_image_int (Max A) 1 A"
then obtain a where a_in: "a ∈ A" and x_left: "x = Min A + a"
by (auto simp: affine_image_int_def)
from x_in obtain b where b_in: "b ∈ A" and x_right: "x = Max A + b"
by (auto simp: affine_image_int_def)
have a_le: "a ≤ Max A"
using fin a_in by simp
have min_le_b: "Min A ≤ b"
using fin b_in by simp
have "x ≤ Min A + Max A"
using x_left a_le by simp
moreover have "Min A + Max A ≤ x"
using x_right min_le_b by simp
ultimately have "x = Min A + Max A"
by simp
then show "x ∈ {Min A + Max A}"
by simp
qed
next
have min_in: "Min A ∈ A"
using fin nonempty by simp
have max_in: "Max A ∈ A"
using fin nonempty by simp
show "{Min A + Max A} ⊆
affine_image_int (Min A) 1 A ∩ affine_image_int (Max A) 1 A"
using min_in max_in by (auto simp: affine_image_int_def add.commute)
qed
lemma endpoint_affine_union_card:
fixes A :: "int set"
assumes fin: "finite A" and nonempty: "A ≠ {}"
shows "card (affine_image_int (Min A) 1 A ∪ affine_image_int (Max A) 1 A) =
2 * card A - 1"
proof -
let ?L = "affine_image_int (Min A) 1 A"
let ?R = "affine_image_int (Max A) 1 A"
have finL: "finite ?L"
by (rule finite_affine_image_int[OF fin])
have finR: "finite ?R"
by (rule finite_affine_image_int[OF fin])
have cardL: "card ?L = card A"
by (rule card_affine_image_int[OF fin]) simp
have cardR: "card ?R = card A"
by (rule card_affine_image_int[OF fin]) simp
have inter: "?L ∩ ?R = {Min A + Max A}"
by (rule endpoint_affine_images_inter[OF fin nonempty])
have "card ?L + card ?R = card (?L ∪ ?R) + card (?L ∩ ?R)"
by (rule card_Un_Int[OF finL finR])
then have "card A + card A = card (?L ∪ ?R) + 1"
using cardL cardR inter by simp
moreover have "0 < card A"
using fin nonempty by (simp add: card_gt_0_iff)
ultimately show ?thesis
by simp
qed
lemma endpoint_affine_images_inter_two_sets:
fixes A B :: "int set"
assumes finA: "finite A" and nonemptyA: "A ≠ {}"
assumes finB: "finite B" and nonemptyB: "B ≠ {}"
shows "affine_image_int (Min A) 1 B ∩ affine_image_int (Max B) 1 A =
{Min A + Max B}"
proof
show "affine_image_int (Min A) 1 B ∩ affine_image_int (Max B) 1 A ⊆
{Min A + Max B}"
proof
fix x
assume x_in: "x ∈ affine_image_int (Min A) 1 B ∩ affine_image_int (Max B) 1 A"
then obtain b where b_in: "b ∈ B" and x_left: "x = Min A + b"
by (auto simp: affine_image_int_def)
from x_in obtain a where a_in: "a ∈ A" and x_right: "x = Max B + a"
by (auto simp: affine_image_int_def)
have b_le: "b ≤ Max B"
using finB b_in by simp
have min_le_a: "Min A ≤ a"
using finA a_in by simp
have "x ≤ Min A + Max B"
using x_left b_le by simp
moreover have "Min A + Max B ≤ x"
using x_right min_le_a by simp
ultimately have "x = Min A + Max B"
by simp
then show "x ∈ {Min A + Max B}"
by simp
qed
next
have min_in: "Min A ∈ A"
using finA nonemptyA by simp
have max_in: "Max B ∈ B"
using finB nonemptyB by simp
show "{Min A + Max B} ⊆
affine_image_int (Min A) 1 B ∩ affine_image_int (Max B) 1 A"
using min_in max_in by (auto simp: affine_image_int_def add.commute)
qed
lemma card_sumset_ge_card_add_card_minus_one:
fixes A B :: "int set"
assumes finA: "finite A" and finB: "finite B"
assumes nonemptyA: "A ≠ {}" and nonemptyB: "B ≠ {}"
shows "card A + card B - 1 ≤ card (sumset A B)"
proof -
let ?L = "affine_image_int (Min A) 1 B"
let ?R = "affine_image_int (Max B) 1 A"
have min_in: "Min A ∈ A"
using finA nonemptyA by simp
have max_in: "Max B ∈ B"
using finB nonemptyB by simp
have finL: "finite ?L"
by (rule finite_affine_image_int[OF finB])
have finR: "finite ?R"
by (rule finite_affine_image_int[OF finA])
have cardL: "card ?L = card B"
by (rule card_affine_image_int[OF finB]) simp
have cardR: "card ?R = card A"
by (rule card_affine_image_int[OF finA]) simp
have inter: "?L ∩ ?R = {Min A + Max B}"
by (rule endpoint_affine_images_inter_two_sets[OF finA nonemptyA finB nonemptyB])
have "card ?L + card ?R = card (?L ∪ ?R) + card (?L ∩ ?R)"
by (rule card_Un_Int[OF finL finR])
then have card_union: "card (?L ∪ ?R) = card A + card B - 1"
using cardL cardR inter finA nonemptyA by simp
have union_subset: "?L ∪ ?R ⊆ sumset A B"
proof
fix x
assume x_in: "x ∈ ?L ∪ ?R"
then show "x ∈ sumset A B"
proof
assume "x ∈ ?L"
then obtain b where b_in: "b ∈ B" and x_eq: "x = Min A + b"
by (auto simp: affine_image_int_def)
then show ?thesis
using min_in by (auto intro: sumsetI)
next
assume "x ∈ ?R"
then obtain a where a_in: "a ∈ A" and x_eq: "x = Max B + a"
by (auto simp: affine_image_int_def)
have "a + Max B ∈ sumset A B"
using a_in max_in by (rule sumsetI)
then show ?thesis
using x_eq by (simp add: add.commute)
qed
qed
have "card (?L ∪ ?R) ≤ card (sumset A B)"
by (rule card_mono[OF finite_sumset[OF finA finB] union_subset])
with card_union show ?thesis
by simp
qed
lemma card_sumset_self_ge_two_card_minus_one:
fixes A :: "int set"
assumes fin: "finite A" and nonempty: "A ≠ {}"
shows "2 * card A - 1 ≤ card (sumset A A)"
proof -
let ?L = "affine_image_int (Min A) 1 A"
let ?R = "affine_image_int (Max A) 1 A"
have min_in: "Min A ∈ A"
using fin nonempty by simp
have max_in: "Max A ∈ A"
using fin nonempty by simp
have finL: "finite ?L"
by (rule finite_affine_image_int[OF fin])
have finR: "finite ?R"
by (rule finite_affine_image_int[OF fin])
have card_union: "card (?L ∪ ?R) = 2 * card A - 1"
by (rule endpoint_affine_union_card[OF fin nonempty])
have union_subset: "?L ∪ ?R ⊆ sumset A A"
proof
fix x
assume x_in: "x ∈ ?L ∪ ?R"
then show "x ∈ sumset A A"
proof
assume "x ∈ ?L"
then obtain a where a_in: "a ∈ A" and x_eq: "x = Min A + a"
by (auto simp: affine_image_int_def)
then show ?thesis
using min_in by (auto intro: sumsetI)
next
assume "x ∈ ?R"
then obtain a where a_in: "a ∈ A" and x_eq: "x = Max A + a"
by (auto simp: affine_image_int_def)
then show ?thesis
using max_in by (auto intro: sumsetI)
qed
qed
have "card (?L ∪ ?R) ≤ card (sumset A A)"
by (rule card_mono[OF finite_sumset[OF fin fin] union_subset])
with card_union show ?thesis
by simp
qed
subsection ‹Holes in the normalized interval›
definition interval_holes :: "int set ⇒ int set" where
"interval_holes A = {x. 0 ≤ x ∧ x ≤ Max A ∧ x ∉ A}"
definition lower_sum_holes :: "int set ⇒ int set" where
"lower_sum_holes A = {x ∈ interval_holes A. x ∈ sumset A A}"
definition upper_sum_holes :: "int set ⇒ int set" where
"upper_sum_holes A = {x ∈ interval_holes A. Max A + x ∈ sumset A A}"
definition stable_sum_holes :: "int set ⇒ int set" where
"stable_sum_holes A =
interval_holes A - (lower_sum_holes A ∪ upper_sum_holes A)"
definition left_stable_sum_holes :: "int set ⇒ int set" where
"left_stable_sum_holes A = interval_holes A - lower_sum_holes A"
definition right_stable_sum_holes :: "int set ⇒ int set" where
"right_stable_sum_holes A = interval_holes A - upper_sum_holes A"
lemma finite_interval_holes [simp]:
"finite (interval_holes A)"
proof -
have "interval_holes A ⊆ {0..Max A}"
by (auto simp: interval_holes_def)
then show ?thesis
by (rule finite_subset) simp
qed
lemma finite_lower_sum_holes [simp]:
"finite (lower_sum_holes A)"
unfolding lower_sum_holes_def by simp
lemma finite_upper_sum_holes [simp]:
"finite (upper_sum_holes A)"
unfolding upper_sum_holes_def by simp
lemma finite_stable_sum_holes [simp]:
"finite (stable_sum_holes A)"
unfolding stable_sum_holes_def by simp
lemma finite_left_stable_sum_holes [simp]:
"finite (left_stable_sum_holes A)"
unfolding left_stable_sum_holes_def by simp
lemma finite_right_stable_sum_holes [simp]:
"finite (right_stable_sum_holes A)"
unfolding right_stable_sum_holes_def by simp
lemma stable_sum_holes_eq_left_right_inter:
"stable_sum_holes A =
left_stable_sum_holes A ∩ right_stable_sum_holes A"
by (auto simp: stable_sum_holes_def left_stable_sum_holes_def right_stable_sum_holes_def)
lemma left_stable_sum_hole_notin_sumset:
assumes x_left: "x ∈ left_stable_sum_holes A"
shows "x ∈ interval_holes A" "x ∉ sumset A A"
proof -
show x_hole: "x ∈ interval_holes A"
using x_left by (simp add: left_stable_sum_holes_def)
show "x ∉ sumset A A"
proof
assume "x ∈ sumset A A"
with x_hole have "x ∈ lower_sum_holes A"
by (simp add: lower_sum_holes_def)
with x_left show False
by (simp add: left_stable_sum_holes_def)
qed
qed
lemma right_stable_sum_hole_notin_sumset:
assumes x_right: "x ∈ right_stable_sum_holes A"
shows "x ∈ interval_holes A" "Max A + x ∉ sumset A A"
proof -
show x_hole: "x ∈ interval_holes A"
using x_right by (simp add: right_stable_sum_holes_def)
show "Max A + x ∉ sumset A A"
proof
assume "Max A + x ∈ sumset A A"
with x_hole have "x ∈ upper_sum_holes A"
by (simp add: upper_sum_holes_def)
with x_right show False
by (simp add: right_stable_sum_holes_def)
qed
qed
lemma left_stable_hole_prefix_card_le_holes:
fixes A :: "int set"
assumes fin: "finite A"
assumes x_left: "x ∈ left_stable_sum_holes A"
shows "card (A ∩ {0..x}) ≤ card ({0..x} - A)"
proof -
let ?P = "A ∩ {0..x}"
let ?Q = "{0..x} - A"
let ?f = "λa. x - a"
have x_not_sum: "x ∉ sumset A A"
by (rule left_stable_sum_hole_notin_sumset(2)[OF x_left])
have image_sub: "?f ` ?P ⊆ ?Q"
proof
fix y
assume "y ∈ ?f ` ?P"
then obtain a where a_in: "a ∈ A" and a_bounds: "0 ≤ a" "a ≤ x" and y_eq: "y = x - a"
by auto
have y_bounds: "0 ≤ y" "y ≤ x"
using a_bounds y_eq by auto
have "y ∉ A"
proof
assume y_in: "y ∈ A"
have "a + y ∈ sumset A A"
using a_in y_in by (rule sumsetI)
moreover have "a + y = x"
using y_eq by simp
ultimately show False
using x_not_sum by simp
qed
with y_bounds show "y ∈ ?Q"
by simp
qed
have inj: "inj_on ?f ?P"
by (rule inj_onI) simp
have finP: "finite ?P"
using fin by simp
have "card ?P = card (?f ` ?P)"
by (simp add: card_image finP inj)
also have "… ≤ card ?Q"
by (rule card_mono[OF _ image_sub]) simp
finally show ?thesis .
qed
lemma left_stable_hole_prefix_twice_card_le:
fixes A :: "int set"
assumes fin: "finite A"
assumes x_left: "x ∈ left_stable_sum_holes A"
shows "2 * card (A ∩ {0..x}) ≤ nat (x + 1)"
proof -
let ?P = "A ∩ {0..x}"
let ?Q = "{0..x} - A"
have x_hole: "x ∈ interval_holes A"
by (rule left_stable_sum_hole_notin_sumset(1)[OF x_left])
then have x_nonneg: "0 ≤ x"
by (simp add: interval_holes_def)
have P_sub: "?P ⊆ {0..x}"
by simp
have Q_eq: "?Q = {0..x} - ?P"
by auto
have cardQ: "card ?Q = card {0..x} - card ?P"
by (simp add: Q_eq card_Diff_subset[OF _ P_sub])
have prefix_le: "card ?P ≤ card ?Q"
by (rule left_stable_hole_prefix_card_le_holes[OF fin x_left])
have P_card_le: "card ?P ≤ card {0..x}"
by (rule card_mono[OF _ P_sub]) simp
have "2 * card ?P ≤ card {0..x}"
using prefix_le cardQ P_card_le by linarith
also have "… = nat (x + 1)"
using x_nonneg by simp
finally show ?thesis .
qed
lemma right_stable_hole_suffix_card_le_holes:
fixes A :: "int set"
assumes fin: "finite A"
assumes x_right: "x ∈ right_stable_sum_holes A"
shows "card (A ∩ {x..Max A}) ≤ card ({x..Max A} - A)"
proof -
let ?n = "Max A"
let ?P = "A ∩ {x..?n}"
let ?Q = "{x..?n} - A"
let ?f = "λa. ?n + x - a"
have nx_not_sum: "?n + x ∉ sumset A A"
by (rule right_stable_sum_hole_notin_sumset(2)[OF x_right])
have image_sub: "?f ` ?P ⊆ ?Q"
proof
fix y
assume "y ∈ ?f ` ?P"
then obtain a where a_in: "a ∈ A" and a_bounds: "x ≤ a" "a ≤ ?n"
and y_eq: "y = ?n + x - a"
by auto
have y_bounds: "x ≤ y" "y ≤ ?n"
using a_bounds y_eq by auto
have "y ∉ A"
proof
assume y_in: "y ∈ A"
have "a + y ∈ sumset A A"
using a_in y_in by (rule sumsetI)
moreover have "a + y = ?n + x"
using y_eq by simp
ultimately show False
using nx_not_sum by simp
qed
with y_bounds show "y ∈ ?Q"
by simp
qed
have inj: "inj_on ?f ?P"
by (rule inj_onI) simp
have finP: "finite ?P"
using fin by simp
have "card ?P = card (?f ` ?P)"
by (simp add: card_image finP inj)
also have "… ≤ card ?Q"
by (rule card_mono[OF _ image_sub]) simp
finally show ?thesis .
qed
lemma right_stable_hole_suffix_twice_card_le:
fixes A :: "int set"
assumes fin: "finite A"
assumes x_right: "x ∈ right_stable_sum_holes A"
shows "2 * card (A ∩ {x..Max A}) ≤ nat (Max A - x + 1)"
proof -
let ?n = "Max A"
let ?P = "A ∩ {x..?n}"
let ?Q = "{x..?n} - A"
have x_hole: "x ∈ interval_holes A"
by (rule right_stable_sum_hole_notin_sumset(1)[OF x_right])
then have x_le: "x ≤ ?n"
by (simp add: interval_holes_def)
have P_sub: "?P ⊆ {x..?n}"
by simp
have Q_eq: "?Q = {x..?n} - ?P"
by auto
have cardQ: "card ?Q = card {x..?n} - card ?P"
by (simp add: Q_eq card_Diff_subset[OF _ P_sub])
have suffix_le: "card ?P ≤ card ?Q"
by (rule right_stable_hole_suffix_card_le_holes[OF fin x_right])
have P_card_le: "card ?P ≤ card {x..?n}"
by (rule card_mono[OF _ P_sub]) simp
have "2 * card ?P ≤ card {x..?n}"
using suffix_le cardQ P_card_le by linarith
also have "… = nat (?n - x + 1)"
using x_le by simp
finally show ?thesis .
qed
lemma hole_cover_of_no_stable_sum_holes:
assumes stable_empty: "stable_sum_holes A = {}"
shows "card (interval_holes A) ≤ card (lower_sum_holes A) + card (upper_sum_holes A)"
proof -
have subset: "interval_holes A ⊆ lower_sum_holes A ∪ upper_sum_holes A"
using stable_empty by (auto simp: stable_sum_holes_def)
have "card (interval_holes A) ≤ card (lower_sum_holes A ∪ upper_sum_holes A)"
by (rule card_mono[OF finite_UnI[OF finite_lower_sum_holes finite_upper_sum_holes] subset])
also have "… ≤ card (lower_sum_holes A) + card (upper_sum_holes A)"
by (rule card_Un_le)
finally show ?thesis .
qed
lemma interval_holes_eq_interval_diff:
assumes subset: "A ⊆ {0..Max A}"
shows "interval_holes A = {0..Max A} - A"
using subset by (auto simp: interval_holes_def)
lemma normalized_subset_interval:
fixes A :: "int set"
assumes fin: "finite A"
assumes zero: "0 ∈ A"
assumes nonneg: "⋀x. x ∈ A ⟹ 0 ≤ x"
shows "A ⊆ {0..Max A}"
proof
fix x
assume x_in: "x ∈ A"
have "0 ≤ x"
by (rule nonneg[OF x_in])
moreover have "x ≤ Max A"
using fin x_in by simp
ultimately show "x ∈ {0..Max A}"
by simp
qed
lemma card_interval_holes:
fixes A :: "int set"
assumes fin: "finite A"
assumes zero: "0 ∈ A"
assumes nonneg: "⋀x. x ∈ A ⟹ 0 ≤ x"
shows "card (interval_holes A) = nat (Max A + 1) - card A"
proof -
have subset: "A ⊆ {0..Max A}"
by (rule normalized_subset_interval[OF fin zero nonneg])
have max_nonneg: "0 ≤ Max A"
using fin zero by simp
have "card (interval_holes A) = card ({0..Max A} - A)"
by (simp add: interval_holes_eq_interval_diff[OF subset])
also have "… = card {0..Max A} - card A"
by (rule card_Diff_subset[OF fin subset])
also have "… = nat (Max A + 1) - card A"
using max_nonneg by simp
finally show ?thesis .
qed
lemma Min_eq_zero_of_zero_mem_nonneg:
assumes fin: "finite A"
assumes zero: "0 ∈ A"
assumes nonneg: "⋀x. x ∈ A ⟹ 0 ≤ x"
shows "Min A = 0"
proof (rule antisym)
show "Min A ≤ 0"
using fin zero by simp
next
have "A ≠ {}"
using zero by auto
then have "Min A ∈ A"
using fin by simp
then show "0 ≤ Min A"
by (rule nonneg)
qed
lemma normalized_endpoint_union_card:
fixes A :: "int set"
assumes fin: "finite A"
assumes zero: "0 ∈ A"
assumes nonneg: "⋀x. x ∈ A ⟹ 0 ≤ x"
shows "card (A ∪ affine_image_int (Max A) 1 A) = 2 * card A - 1"
proof -
have nonempty: "A ≠ {}"
using zero by auto
have min0: "Min A = 0"
by (rule Min_eq_zero_of_zero_mem_nonneg[OF fin zero nonneg])
have "card (affine_image_int (Min A) 1 A ∪ affine_image_int (Max A) 1 A) =
2 * card A - 1"
by (rule endpoint_affine_union_card[OF fin nonempty])
then show ?thesis
by (simp add: min0)
qed
lemma lower_sum_holes_disjoint_endpoint_union:
fixes A :: "int set"
assumes fin: "finite A"
assumes zero: "0 ∈ A"
assumes nonneg: "⋀x. x ∈ A ⟹ 0 ≤ x"
shows "(A ∪ affine_image_int (Max A) 1 A) ∩ lower_sum_holes A = {}"
proof
show "(A ∪ affine_image_int (Max A) 1 A) ∩ lower_sum_holes A ⊆ {}"
proof
fix x
assume x_in: "x ∈ (A ∪ affine_image_int (Max A) 1 A) ∩ lower_sum_holes A"
then have x_hole: "x ∈ interval_holes A"
by (simp add: lower_sum_holes_def)
then have x_notin_A: "x ∉ A" and x_le: "x ≤ Max A"
by (auto simp: interval_holes_def)
from x_in have x_base: "x ∈ A ∪ affine_image_int (Max A) 1 A"
by simp
then show "x ∈ {}"
proof
assume "x ∈ A"
with x_notin_A show ?thesis
by simp
next
assume "x ∈ affine_image_int (Max A) 1 A"
then obtain a where a_in: "a ∈ A" and x_eq: "x = Max A + a"
by (auto simp: affine_image_int_def)
have "0 ≤ a"
by (rule nonneg[OF a_in])
with x_eq x_le have a0: "a = 0"
by simp
have "Max A ∈ A"
using fin zero Max_in by fastforce
with x_notin_A x_eq a0 show ?thesis
by simp
qed
qed
qed simp
lemma upper_sum_holes_image_disjoint_endpoint_union:
fixes A :: "int set"
assumes fin: "finite A"
assumes zero: "0 ∈ A"
assumes nonneg: "⋀x. x ∈ A ⟹ 0 ≤ x"
shows "(A ∪ affine_image_int (Max A) 1 A) ∩
affine_image_int (Max A) 1 (upper_sum_holes A) = {}"
proof
show "(A ∪ affine_image_int (Max A) 1 A) ∩
affine_image_int (Max A) 1 (upper_sum_holes A) ⊆ {}"
proof
fix y
assume y_in: "y ∈ (A ∪ affine_image_int (Max A) 1 A) ∩
affine_image_int (Max A) 1 (upper_sum_holes A)"
then obtain x where x_upper: "x ∈ upper_sum_holes A" and y_eq: "y = Max A + x"
by (auto simp: affine_image_int_def)
then have x_hole: "x ∈ interval_holes A"
by (simp add: upper_sum_holes_def)
then have x_nonneg: "0 ≤ x" and x_notin_A: "x ∉ A"
by (auto simp: interval_holes_def)
from y_in have y_base: "y ∈ A ∪ affine_image_int (Max A) 1 A"
by simp
then show "y ∈ {}"
proof
assume yA: "y ∈ A"
have y_le: "y ≤ Max A"
using fin yA by simp
with y_eq x_nonneg have x0: "x = 0"
by simp
with zero x_notin_A show ?thesis
by simp
next
assume "y ∈ affine_image_int (Max A) 1 A"
then obtain a where a_in: "a ∈ A" and ya: "y = Max A + a"
by (auto simp: affine_image_int_def)
from y_eq ya have "x = a"
by simp
with x_notin_A a_in show ?thesis
by simp
qed
qed
qed simp
lemma lower_sum_holes_disjoint_upper_sum_holes_image:
fixes A :: "int set"
assumes fin: "finite A"
assumes zero: "0 ∈ A"
assumes nonneg: "⋀x. x ∈ A ⟹ 0 ≤ x"
shows "lower_sum_holes A ∩ affine_image_int (Max A) 1 (upper_sum_holes A) = {}"
proof
show "lower_sum_holes A ∩ affine_image_int (Max A) 1 (upper_sum_holes A) ⊆ {}"
proof
fix y
assume y_in: "y ∈ lower_sum_holes A ∩ affine_image_int (Max A) 1 (upper_sum_holes A)"
then have y_hole: "y ∈ interval_holes A"
by (simp add: lower_sum_holes_def)
then have y_le: "y ≤ Max A" and y_notin_A: "y ∉ A"
by (auto simp: interval_holes_def)
from y_in obtain x where x_upper: "x ∈ upper_sum_holes A" and y_eq: "y = Max A + x"
by (auto simp: affine_image_int_def)
then have x_hole: "x ∈ interval_holes A"
by (simp add: upper_sum_holes_def)
then have x_nonneg: "0 ≤ x" and x_notin_A: "x ∉ A"
by (auto simp: interval_holes_def)
with y_eq y_le have x0: "x = 0"
by simp
with zero x_notin_A show "y ∈ {}"
by simp
qed
qed simp
lemma normalized_sumset_lower_bound_with_holes:
fixes A :: "int set"
assumes fin: "finite A"
assumes zero: "0 ∈ A"
assumes nonneg: "⋀x. x ∈ A ⟹ 0 ≤ x"
shows "2 * card A - 1 + card (lower_sum_holes A) + card (upper_sum_holes A)
≤ card (sumset A A)"
proof -
let ?B = "A ∪ affine_image_int (Max A) 1 A"
let ?L = "lower_sum_holes A"
let ?U = "affine_image_int (Max A) 1 (upper_sum_holes A)"
let ?S = "?B ∪ ?L ∪ ?U"
have nonempty: "A ≠ {}"
using zero by auto
have max_in: "Max A ∈ A"
using fin nonempty by simp
have finB: "finite ?B"
by (rule finite_UnI[OF fin finite_affine_image_int[OF fin]])
have finL: "finite ?L"
by simp
have finU: "finite ?U"
by (rule finite_affine_image_int) simp
have cardB: "card ?B = 2 * card A - 1"
by (rule normalized_endpoint_union_card[OF fin zero nonneg])
have cardU: "card ?U = card (upper_sum_holes A)"
by (rule card_affine_image_int) simp_all
have BL_disj: "?B ∩ ?L = {}"
by (rule lower_sum_holes_disjoint_endpoint_union[OF fin zero nonneg])
have BU_disj: "?B ∩ ?U = {}"
by (rule upper_sum_holes_image_disjoint_endpoint_union[OF fin zero nonneg])
have LU_disj: "?L ∩ ?U = {}"
by (rule lower_sum_holes_disjoint_upper_sum_holes_image[OF fin zero nonneg])
have BL_card: "card (?B ∪ ?L) = card ?B + card ?L"
by (rule card_Un_disjoint[OF finB finL BL_disj])
have BL_U_disj: "(?B ∪ ?L) ∩ ?U = {}"
using BU_disj LU_disj by auto
have cardS: "card ?S = 2 * card A - 1 + card ?L + card (upper_sum_holes A)"
proof -
have "card ?S = card (?B ∪ ?L) + card ?U"
by (rule card_Un_disjoint[OF finite_UnI[OF finB finL] finU BL_U_disj])
also have "… = card ?B + card ?L + card ?U"
using BL_card by simp
also have "… = 2 * card A - 1 + card ?L + card (upper_sum_holes A)"
using cardB cardU by simp
finally show ?thesis .
qed
have S_subset: "?S ⊆ sumset A A"
proof
fix y
assume y_in: "y ∈ ?S"
then show "y ∈ sumset A A"
proof
assume yBL: "y ∈ ?B ∪ ?L"
then show ?thesis
proof
assume yB: "y ∈ ?B"
then show ?thesis
proof
assume yA: "y ∈ A"
have "0 + y ∈ sumset A A"
proof (rule sumsetI)
show "0 ∈ A"
by (rule zero)
show "y ∈ A"
by (rule yA)
qed
then show ?thesis
by simp
next
assume "y ∈ affine_image_int (Max A) 1 A"
then obtain a where a_in: "a ∈ A" and y_eq: "y = Max A + a"
by (auto simp: affine_image_int_def)
have "Max A + a ∈ sumset A A"
using max_in a_in by (rule sumsetI)
then show ?thesis
using y_eq by simp
qed
next
assume "y ∈ ?L"
then show ?thesis
by (simp add: lower_sum_holes_def)
qed
next
assume "y ∈ ?U"
then obtain x where x_in: "x ∈ upper_sum_holes A" and y_eq: "y = Max A + x"
by (auto simp: affine_image_int_def)
then have "Max A + x ∈ sumset A A"
by (simp add: upper_sum_holes_def)
then show ?thesis
using y_eq by simp
qed
qed
have "card ?S ≤ card (sumset A A)"
by (rule card_mono[OF finite_sumset[OF fin fin] S_subset])
with cardS show ?thesis
by simp
qed
lemma normalized_sumset_eq_endpoint_union_with_holes:
fixes A :: "int set"
assumes fin: "finite A"
assumes zero: "0 ∈ A"
assumes nonneg: "⋀x. x ∈ A ⟹ 0 ≤ x"
shows "sumset A A =
A ∪ affine_image_int (Max A) 1 A ∪
lower_sum_holes A ∪
affine_image_int (Max A) 1 (upper_sum_holes A)"
proof
let ?n = "Max A"
have nonempty: "A ≠ {}"
using zero by auto
have top: "?n ∈ A"
using fin nonempty by simp
have subset: "A ⊆ {0..?n}"
by (rule normalized_subset_interval[OF fin zero nonneg])
show "sumset A A ⊆
A ∪ affine_image_int ?n 1 A ∪
lower_sum_holes A ∪
affine_image_int ?n 1 (upper_sum_holes A)"
proof
fix y
assume y_in: "y ∈ sumset A A"
then obtain a b where a_in: "a ∈ A" and b_in: "b ∈ A" and y_eq: "y = a + b"
by (rule sumsetE)
have a_bounds: "0 ≤ a" "a ≤ ?n"
using subset a_in by auto
have b_bounds: "0 ≤ b" "b ≤ ?n"
using subset b_in by auto
show "y ∈
A ∪ affine_image_int ?n 1 A ∪
lower_sum_holes A ∪
affine_image_int ?n 1 (upper_sum_holes A)"
proof (cases "y ≤ ?n")
case True
show ?thesis
proof (cases "y ∈ A")
case True
then show ?thesis
by simp
next
case False
have "y ∈ interval_holes A"
using y_eq a_bounds b_bounds True False by (auto simp: interval_holes_def)
then have "y ∈ lower_sum_holes A"
using y_in by (simp add: lower_sum_holes_def)
then show ?thesis
by simp
qed
next
case False
let ?x = "y - ?n"
have y_split: "y = ?n + ?x"
by simp
have x_pos: "0 < ?x"
using False by simp
have x_le: "?x ≤ ?n"
using y_eq a_bounds b_bounds by linarith
show ?thesis
proof (cases "?x ∈ A")
case True
have "y ∈ affine_image_int ?n 1 A"
unfolding affine_image_int_def
proof (rule image_eqI[where x = "?x"])
show "y = ?n + 1 * ?x"
using y_split by simp
show "?x ∈ A"
by (rule True)
qed
then show ?thesis
by simp
next
case False
have x_hole: "?x ∈ interval_holes A"
using x_pos x_le False by (auto simp: interval_holes_def)
have x_upper: "?x ∈ upper_sum_holes A"
using x_hole y_in by (simp add: upper_sum_holes_def)
have "y ∈ affine_image_int ?n 1 (upper_sum_holes A)"
unfolding affine_image_int_def
proof (rule image_eqI[where x = "?x"])
show "y = ?n + 1 * ?x"
using y_split by simp
show "?x ∈ upper_sum_holes A"
by (rule x_upper)
qed
then show ?thesis
by simp
qed
qed
qed
show "A ∪ affine_image_int ?n 1 A ∪
lower_sum_holes A ∪
affine_image_int ?n 1 (upper_sum_holes A) ⊆ sumset A A"
proof
fix y
assume y_in: "y ∈ A ∪ affine_image_int ?n 1 A ∪
lower_sum_holes A ∪
affine_image_int ?n 1 (upper_sum_holes A)"
then show "y ∈ sumset A A"
proof
assume y_base_or_lower:
"y ∈ A ∪ affine_image_int ?n 1 A ∪ lower_sum_holes A"
then show ?thesis
proof
assume y_base: "y ∈ A ∪ affine_image_int ?n 1 A"
then show ?thesis
proof
assume yA: "y ∈ A"
have "0 + y ∈ sumset A A"
using zero yA by (rule sumsetI)
then show ?thesis
by simp
next
assume "y ∈ affine_image_int ?n 1 A"
then obtain a where a_in: "a ∈ A" and y_eq: "y = ?n + a"
by (auto simp: affine_image_int_def)
have "?n + a ∈ sumset A A"
using top a_in by (rule sumsetI)
then show ?thesis
using y_eq by simp
qed
next
assume "y ∈ lower_sum_holes A"
then show ?thesis
by (simp add: lower_sum_holes_def)
qed
next
assume "y ∈ affine_image_int ?n 1 (upper_sum_holes A)"
then obtain x where x_upper: "x ∈ upper_sum_holes A" and y_eq: "y = ?n + x"
by (auto simp: affine_image_int_def)
then have "?n + x ∈ sumset A A"
by (simp add: upper_sum_holes_def)
then show ?thesis
using y_eq by simp
qed
qed
qed
lemma normalized_sumset_card_eq_with_holes:
fixes A :: "int set"
assumes fin: "finite A"
assumes zero: "0 ∈ A"
assumes nonneg: "⋀x. x ∈ A ⟹ 0 ≤ x"
shows "card (sumset A A) =
2 * card A - 1 + card (lower_sum_holes A) + card (upper_sum_holes A)"
proof -
let ?B = "A ∪ affine_image_int (Max A) 1 A"
let ?L = "lower_sum_holes A"
let ?U = "affine_image_int (Max A) 1 (upper_sum_holes A)"
let ?S = "?B ∪ ?L ∪ ?U"
have finB: "finite ?B"
by (rule finite_UnI[OF fin finite_affine_image_int[OF fin]])
have finL: "finite ?L"
by simp
have finU: "finite ?U"
by (rule finite_affine_image_int) simp
have cardB: "card ?B = 2 * card A - 1"
by (rule normalized_endpoint_union_card[OF fin zero nonneg])
have cardU: "card ?U = card (upper_sum_holes A)"
by (rule card_affine_image_int) simp_all
have BL_disj: "?B ∩ ?L = {}"
by (rule lower_sum_holes_disjoint_endpoint_union[OF fin zero nonneg])
have BU_disj: "?B ∩ ?U = {}"
by (rule upper_sum_holes_image_disjoint_endpoint_union[OF fin zero nonneg])
have LU_disj: "?L ∩ ?U = {}"
by (rule lower_sum_holes_disjoint_upper_sum_holes_image[OF fin zero nonneg])
have BL_card: "card (?B ∪ ?L) = card ?B + card ?L"
by (rule card_Un_disjoint[OF finB finL BL_disj])
have BL_U_disj: "(?B ∪ ?L) ∩ ?U = {}"
using BU_disj LU_disj by auto
have "card (sumset A A) = card ?S"
by (simp add: normalized_sumset_eq_endpoint_union_with_holes[OF fin zero nonneg])
also have "… = card (?B ∪ ?L) + card ?U"
by (rule card_Un_disjoint[OF finite_UnI[OF finB finL] finU BL_U_disj])
also have "… = card ?B + card ?L + card ?U"
using BL_card by simp
also have "… =
2 * card A - 1 + card (lower_sum_holes A) + card (upper_sum_holes A)"
using cardB cardU by simp
finally show ?thesis .
qed
lemma normalized_small_doubling_hole_contribution_upper:
fixes A :: "int set"
assumes fin: "finite A"
assumes card_ge: "3 ≤ card A"
assumes zero: "0 ∈ A"
assumes nonneg: "⋀x. x ∈ A ⟹ 0 ≤ x"
assumes small_doubling: "card (sumset A A) ≤ 3 * card A - 4"
shows "card (lower_sum_holes A) + card (upper_sum_holes A) ≤ card A - 3"
proof -
have card_eq:
"card (sumset A A) =
2 * card A - 1 + card (lower_sum_holes A) + card (upper_sum_holes A)"
by (rule normalized_sumset_card_eq_with_holes[OF fin zero nonneg])
show ?thesis
using card_eq small_doubling card_ge by linarith
qed
lemma normalized_max_bound_from_hole_contribution:
fixes A :: "int set"
assumes fin: "finite A"
assumes zero: "0 ∈ A"
assumes nonneg: "⋀x. x ∈ A ⟹ 0 ≤ x"
assumes hole_cover:
"card (interval_holes A) ≤ card (lower_sum_holes A) + card (upper_sum_holes A)"
shows "nat (Max A + 1) ≤ card (sumset A A) - card A + 1"
proof -
let ?k = "card A"
let ?s = "card (sumset A A)"
let ?n = "nat (Max A + 1)"
let ?h = "card (interval_holes A)"
let ?l = "card (lower_sum_holes A)"
let ?u = "card (upper_sum_holes A)"
have lower: "2 * ?k - 1 + ?l + ?u ≤ ?s"
by (rule normalized_sumset_lower_bound_with_holes[OF fin zero nonneg])
have h_bound: "2 * ?k - 1 + ?h ≤ ?s"
using lower hole_cover by linarith
have subset: "A ⊆ {0..Max A}"
by (rule normalized_subset_interval[OF fin zero nonneg])
have max_nonneg: "0 ≤ Max A"
using fin zero by simp
have k_le_n: "?k ≤ ?n"
proof -
have "?k ≤ card {0..Max A}"
by (rule card_mono[OF _ subset]) simp
also have "… = ?n"
using max_nonneg by simp
finally show ?thesis .
qed
have h_eq: "?h = ?n - ?k"
by (rule card_interval_holes[OF fin zero nonneg])
have k_pos: "0 < ?k"
using fin zero by (simp add: card_gt_0_iff, blast)
have n_eq: "?n = ?h + ?k"
using h_eq k_le_n by linarith
have n_plus: "?n + ?k - 1 = 2 * ?k - 1 + ?h"
using n_eq k_pos by linarith
have "?n + ?k - 1 ≤ ?s"
using h_bound n_plus by simp
moreover note k_pos
ultimately show ?thesis
by linarith
qed
subsection ‹Modular shadows of integer sumsets›
definition mod_image_int :: "int ⇒ int set ⇒ int set" where
"mod_image_int n A = (λx. x mod n) ` A"
definition mod_sumset_int :: "int ⇒ int set ⇒ int set ⇒ int set" where
"mod_sumset_int n A B = mod_image_int n (sumset A B)"
definition mod_translate_int :: "int ⇒ int ⇒ int set ⇒ int set" where
"mod_translate_int n a H = (λh. (a + h) mod n) ` H"
definition mod_fiber_int :: "int ⇒ int set ⇒ int ⇒ int set" where
"mod_fiber_int n S r = {s ∈ S. s mod n = r}"
lemma mod_image_int_iff:
"r ∈ mod_image_int n A ⟷ (∃a∈A. r = a mod n)"
by (auto simp: mod_image_int_def)
lemma finite_mod_image_int [intro]:
assumes "finite A"
shows "finite (mod_image_int n A)"
using assms by (simp add: mod_image_int_def)
lemma mod_sumset_int_iff:
"r ∈ mod_sumset_int n A B ⟷ (∃a∈A. ∃b∈B. r = (a + b) mod n)"
by (auto simp: mod_sumset_int_def mod_image_int_def sumset_def)
lemma finite_mod_sumset_int [intro]:
assumes "finite A" "finite B"
shows "finite (mod_sumset_int n A B)"
unfolding mod_sumset_int_def
by (rule finite_mod_image_int) (rule finite_sumset[OF assms])
lemma mod_translate_int_iff:
"r ∈ mod_translate_int n a H ⟷ (∃h∈H. r = (a + h) mod n)"
by (auto simp: mod_translate_int_def)
lemma finite_mod_translate_int [intro]:
assumes "finite H"
shows "finite (mod_translate_int n a H)"
using assms by (simp add: mod_translate_int_def)
lemma mod_translate_int_subset_residues:
assumes n_pos: "0 < n"
shows "mod_translate_int n a H ⊆ {0..n - 1}"
using n_pos by (auto simp: mod_translate_int_def pos_mod_bound)
lemma mod_add_translate_inj_on_residues:
fixes a n :: int
assumes n_pos: "0 < n"
shows "inj_on (λh. (a + h) mod n) {0..n - 1}"
proof (rule inj_onI)
fix x y
assume x_in: "x ∈ {0..n - 1}"
assume y_in: "y ∈ {0..n - 1}"
assume eq: "(a + x) mod n = (a + y) mod n"
have x_bounds: "0 ≤ x" "x < n"
using x_in by auto
have y_bounds: "0 ≤ y" "y < n"
using y_in by auto
have dvd_xy: "n dvd x - y"
using eq by (simp add: mod_eq_dvd_iff algebra_simps)
then obtain q where q_eq: "x - y = n * q"
by (auto elim: dvdE)
have diff_lower: "- n < x - y"
using x_bounds y_bounds by linarith
have diff_upper: "x - y < n"
using x_bounds y_bounds by linarith
have "q = 0"
proof (rule ccontr)
assume "q ≠ 0"
then consider "1 ≤ q" | "q ≤ -1"
by linarith
then show False
proof cases
case 1
then have "n ≤ n * q"
proof -
have "1 * n ≤ q * n"
using 1 n_pos by (intro mult_right_mono) simp_all
then show ?thesis
by (simp add: mult.commute)
qed
then show False
using q_eq diff_upper by linarith
next
case 2
then have "n * q ≤ - n"
proof -
have "q * n ≤ (-1) * n"
using 2 n_pos by (intro mult_right_mono) simp_all
then show ?thesis
by (simp add: mult.commute)
qed
then show False
using q_eq diff_lower by linarith
qed
qed
then show "x = y"
using q_eq by simp
qed
lemma card_mod_translate_int_eq:
fixes H :: "int set"
assumes n_pos: "0 < n"
assumes H_sub: "H ⊆ {0..n - 1}"
shows "card (mod_translate_int n a H) = card H"
proof -
have finH: "finite H"
using H_sub by (rule finite_subset) simp
have inj_res: "inj_on (λh. (a + h) mod n) {0..n - 1}"
by (rule mod_add_translate_inj_on_residues[OF n_pos])
have inj_H: "inj_on (λh. (a + h) mod n) H"
by (rule inj_on_subset[OF inj_res H_sub])
show ?thesis
by (simp add: mod_translate_int_def card_image finH inj_H)
qed
lemma sum_coset_lower_upper_inter_card:
fixes A H :: "int set"
assumes n_pos: "0 < n"
assumes finA: "finite A"
assumes max_eq: "Max A = n"
assumes H_sub: "H ⊆ {0..n - 1}"
assumes zero_H: "0 ∈ H"
assumes add_closed: "⋀x y. x ∈ H ⟹ y ∈ H ⟹ (x + y) mod n ∈ H"
assumes b_in: "b ∈ A" and b_bounds: "0 ≤ b" "b < n"
assumes c_in: "c ∈ A" and c_bounds: "0 ≤ c" "c < n"
defines "R ≡ mod_translate_int n b H"
defines "S ≡ mod_translate_int n c H"
defines "K ≡ mod_translate_int n ((b + c) mod n) H"
assumes K_disj: "K ∩ A = {}"
shows "card H ≤
1 + card ((lower_sum_holes A ∩ upper_sum_holes A) ∩ K) +
card (R - A) + card (S - A)"
proof -
let ?X = "A ∩ R"
let ?Y = "A ∩ S"
let ?T = "sumset ?X ?Y"
let ?Low = "?T ∩ {0..n - 1}"
let ?High = "?T ∩ {n..2 * n - 1}"
let ?Up = "(λt. t - n) ` ?High"
let ?I = "(lower_sum_holes A ∩ upper_sum_holes A) ∩ K"
have finH: "finite H"
using H_sub by (rule finite_subset) simp
have R_sub: "R ⊆ {0..n - 1}"
unfolding R_def by (rule mod_translate_int_subset_residues[OF n_pos])
have S_sub: "S ⊆ {0..n - 1}"
unfolding S_def by (rule mod_translate_int_subset_residues[OF n_pos])
have K_sub: "K ⊆ {0..n - 1}"
unfolding K_def by (rule mod_translate_int_subset_residues[OF n_pos])
have finR: "finite R"
using R_sub by (rule finite_subset) simp
have finS: "finite S"
using S_sub by (rule finite_subset) simp
have finK: "finite K"
using K_sub by (rule finite_subset) simp
have cardR: "card R = card H"
unfolding R_def by (rule card_mod_translate_int_eq[OF n_pos H_sub])
have cardS: "card S = card H"
unfolding S_def by (rule card_mod_translate_int_eq[OF n_pos H_sub])
have cardK: "card K = card H"
unfolding K_def by (rule card_mod_translate_int_eq[OF n_pos H_sub])
have b_R: "b ∈ R"
unfolding R_def mod_translate_int_def
proof (rule image_eqI)
show "b = (b + 0) mod n"
using b_bounds n_pos by simp
show "0 ∈ H"
by (rule zero_H)
qed
have c_S: "c ∈ S"
unfolding S_def mod_translate_int_def
proof (rule image_eqI)
show "c = (c + 0) mod n"
using c_bounds n_pos by simp
show "0 ∈ H"
by (rule zero_H)
qed
have X_nonempty: "?X ≠ {}"
using b_in b_R by auto
have Y_nonempty: "?Y ≠ {}"
using c_in c_S by auto
have finX: "finite ?X"
using finA by simp
have finY: "finite ?Y"
using finA by simp
have sum_residue_in_K: "(x + y) mod n ∈ K"
if x_in: "x ∈ ?X" and y_in: "y ∈ ?Y" for x y
proof -
from x_in obtain h where h_in: "h ∈ H" and x_eq: "x = (b + h) mod n"
by (auto simp: R_def mod_translate_int_def)
from y_in obtain k where k_in: "k ∈ H" and y_eq: "y = (c + k) mod n"
by (auto simp: S_def mod_translate_int_def)
have hk_in: "(h + k) mod n ∈ H"
by (rule add_closed[OF h_in k_in])
have "(x + y) mod n = (b + c + ((h + k) mod n)) mod n"
proof -
have "(x + y) mod n = ((b + h) + (c + k)) mod n"
using x_eq y_eq by (simp add: mod_simps)
also have "… = (b + c + (h + k)) mod n"
by (simp add: algebra_simps)
also have "… = (b + c + ((h + k) mod n)) mod n"
by (simp add: mod_simps)
finally show ?thesis .
qed
then show ?thesis
using hk_in by (auto simp: K_def mod_translate_int_def mod_simps algebra_simps)
qed
have T_bounds: "0 ≤ t ∧ t ≤ 2 * n - 2" if t_in: "t ∈ ?T" for t
proof -
from t_in obtain x y where x_in: "x ∈ ?X" and y_in: "y ∈ ?Y" and t_eq: "t = x + y"
by (rule sumsetE)
have x_bounds: "0 ≤ x" "x ≤ n - 1"
using R_sub x_in by auto
have y_bounds: "0 ≤ y" "y ≤ n - 1"
using S_sub y_in by auto
show ?thesis
using x_bounds y_bounds t_eq by linarith
qed
have T_mod_K: "t mod n ∈ K" if t_in: "t ∈ ?T" for t
proof -
from t_in obtain x y where x_in: "x ∈ ?X" and y_in: "y ∈ ?Y" and t_eq: "t = x + y"
by (rule sumsetE)
show ?thesis
using sum_residue_in_K[OF x_in y_in] t_eq by simp
qed
have low_sub: "?Low ⊆ lower_sum_holes A ∩ K"
proof
fix x
assume x_in: "x ∈ ?Low"
then have x_T: "x ∈ ?T" and x_bounds: "0 ≤ x" "x < n"
by auto
have x_K: "x ∈ K"
using T_mod_K[OF x_T] x_bounds n_pos by simp
have x_not_A: "x ∉ A"
using K_disj x_K by auto
have x_interval: "x ∈ interval_holes A"
using x_bounds x_not_A by (auto simp: interval_holes_def max_eq)
have x_sum: "x ∈ sumset A A"
using x_T by (auto simp: sumset_def)
show "x ∈ lower_sum_holes A ∩ K"
using x_interval x_sum x_K by (auto simp: lower_sum_holes_def)
qed
have up_sub: "?Up ⊆ upper_sum_holes A ∩ K"
proof
fix x
assume x_in: "x ∈ ?Up"
then obtain t where t_high: "t ∈ ?High" and x_eq: "x = t - n"
by auto
then have t_T: "t ∈ ?T" and t_bounds: "n ≤ t" "t < 2 * n"
by auto
have x_bounds: "0 ≤ x" "x < n"
using x_eq t_bounds by linarith+
have t_mod: "t mod n = x"
proof -
have "t = n + x"
using x_eq by simp
then show ?thesis
using x_bounds n_pos by simp
qed
have x_K: "x ∈ K"
using T_mod_K[OF t_T] t_mod by simp
have x_not_A: "x ∉ A"
using K_disj x_K by auto
have x_interval: "x ∈ interval_holes A"
using x_bounds x_not_A by (auto simp: interval_holes_def max_eq)
have "n + x ∈ sumset A A"
using t_T x_eq by (auto simp: sumset_def)
then show "x ∈ upper_sum_holes A ∩ K"
using x_interval x_K by (auto simp: upper_sum_holes_def max_eq)
qed
have finT: "finite ?T"
by (rule finite_sumset[OF finX finY])
have T_split: "?T = ?Low ∪ ?High"
proof
show "?T ⊆ ?Low ∪ ?High"
proof
fix t
assume t_in: "t ∈ ?T"
then have bounds: "0 ≤ t" "t ≤ 2 * n - 2"
using T_bounds by auto
show "t ∈ ?Low ∪ ?High"
proof (cases "t < n")
case True
with t_in bounds show ?thesis
by auto
next
case False
with t_in bounds show ?thesis
by auto
qed
qed
show "?Low ∪ ?High ⊆ ?T"
by auto
qed
have disj_low_high: "?Low ∩ ?High = {}"
using n_pos by auto
have finLow: "finite ?Low"
using finT by simp
have finHigh: "finite ?High"
using finT by simp
have card_T_split: "card ?T = card ?Low + card ?High"
proof -
have "card ?T = card (?Low ∪ ?High)"
using T_split by simp
also have "… = card ?Low + card ?High"
by (rule card_Un_disjoint[OF finLow finHigh disj_low_high])
finally show ?thesis .
qed
have inj_shift: "inj_on (λt. t - n) ?High"
by (rule inj_onI) simp
have card_Up: "card ?Up = card ?High"
by (simp add: card_image finHigh inj_shift)
have card_T_low_up: "card ?T = card ?Low + card ?Up"
using card_T_split card_Up by simp
have low_union_up_sub_K: "?Low ∪ ?Up ⊆ K"
using low_sub up_sub by auto
have low_inter_up_sub_I: "?Low ∩ ?Up ⊆ ?I"
using low_sub up_sub by auto
have finUp: "finite ?Up"
using finHigh by simp
have card_low_up_le: "card ?Low + card ?Up ≤ card K + card ?I"
proof -
have card_union_inter:
"card ?Low + card ?Up = card (?Low ∪ ?Up) + card (?Low ∩ ?Up)"
by (rule card_Un_Int[OF finLow finUp])
have "card (?Low ∪ ?Up) ≤ card K"
by (rule card_mono[OF finK low_union_up_sub_K])
moreover have "card (?Low ∩ ?Up) ≤ card ?I"
by (rule card_mono[OF _ low_inter_up_sub_I]) simp
ultimately show ?thesis
using card_union_inter by linarith
qed
have card_T_le: "card ?T ≤ card H + card ?I"
using card_T_low_up card_low_up_le cardK by simp
have sum_lower: "card ?X + card ?Y - 1 ≤ card ?T"
by (rule card_sumset_ge_card_add_card_minus_one[OF finX finY X_nonempty Y_nonempty])
have R_decomp: "R = ?X ∪ (R - A)"
by auto
have S_decomp: "S = ?Y ∪ (S - A)"
by auto
have R_disj: "?X ∩ (R - A) = {}"
by auto
have S_disj: "?Y ∩ (S - A) = {}"
by auto
have finRdiff: "finite (R - A)"
using finR by simp
have finSdiff: "finite (S - A)"
using finS by simp
have card_R_decomp: "card R = card ?X + card (R - A)"
proof -
have "card R = card (?X ∪ (R - A))"
using R_decomp by simp
also have "… = card ?X + card (R - A)"
by (rule card_Un_disjoint[OF finX finRdiff R_disj])
finally show ?thesis .
qed
have card_S_decomp: "card S = card ?Y + card (S - A)"
proof -
have "card S = card (?Y ∪ (S - A))"
using S_decomp by simp
also have "… = card ?Y + card (S - A)"
by (rule card_Un_disjoint[OF finY finSdiff S_disj])
finally show ?thesis .
qed
show ?thesis
using sum_lower card_T_le cardR cardS card_R_decomp card_S_decomp by linarith
qed
lemma mod_fiber_int_subset:
"mod_fiber_int n S r ⊆ S"
by (auto simp: mod_fiber_int_def)
lemma finite_mod_fiber_int [intro]:
assumes "finite S"
shows "finite (mod_fiber_int n S r)"
using finite_subset[OF mod_fiber_int_subset assms] .