# Theory Linear_Bound_Argument

```(* Title: Linear_Bound_Argument.thy
Author: Chelsea Edmonds
*)
section ‹Linear Bound Argument - General ›
text ‹Lemmas to enable general reasoning using the linear bound argument for combinatorial proofs.
Jukna \<^cite>‹"juknaExtremalCombinatorics2011"› presents a good overview of the mathematical background
this theory is based on and applications ›
theory Linear_Bound_Argument imports Incidence_Matrices Jordan_Normal_Form.DL_Rank
Jordan_Normal_Form.Ring_Hom_Matrix
begin

subsection ‹Vec Space Extensions›
text ‹Simple extensions to the existing vector space locale on linear independence ›
context vec_space
begin
lemma lin_indpt_set_card_lt_dim:
fixes A :: "'a vec set"
assumes "A ⊆ carrier_vec n"
assumes "lin_indpt A"
shows "card A ≤ dim"
using assms(1) assms(2) fin_dim li_le_dim(2) by blast

lemma lin_indpt_dim_col_lt_dim:
fixes A :: "'a mat"
assumes "A ∈ carrier_mat n nc"
assumes "distinct (cols A)"
assumes "lin_indpt (set (cols A))"
shows "nc ≤ dim"
proof -
have b: "card (set (cols A)) = dim_col A" using cols_length assms(2)
have "set (cols A) ⊆ carrier_vec n" using assms(1) cols_dim by blast
thus ?thesis using lin_indpt_set_card_lt_dim assms b by auto
qed

lemma lin_comb_imp_lin_dep_fin:
fixes A :: "'a vec set"
assumes "finite A"
assumes "A ⊆ carrier_vec n"
assumes "lincomb c A = 0⇩v n"
assumes "∃ a. a ∈ A ∧ c a ≠ 0"
shows "lin_dep A"
unfolding lin_dep_def using assms lincomb_as_lincomb_list_distinct sumlist_nth by auto

text ‹While a trivial definition, this enables us to directly reference the definition outside
of a locale context, as @{term "lin_indpt"} is an inherited definition ›
definition lin_indpt_vs:: "'a vec set ⇒ bool" where
"lin_indpt_vs A ⟷ lin_indpt A"

lemma lin_comb_sum_lin_indpt:
fixes A :: "'a vec list"
assumes "set (A) ⊆ carrier_vec n"
assumes "distinct A"
assumes "⋀ f. lincomb_list (λi. f (A ! i)) A = 0⇩v n ⟹ ∀v∈ (set A). f v = 0"
shows "lin_indpt (set A)"
by (rule finite_lin_indpt2, auto simp add: assms lincomb_as_lincomb_list_distinct)

lemma lin_comb_mat_lin_indpt:
fixes A :: "'a vec list"
assumes "set (A) ⊆ carrier_vec n"
assumes "distinct A"
assumes "⋀ f. mat_of_cols n A *⇩v vec (length A) (λi. f (A ! i))  = 0⇩v n ⟹ ∀v∈ (set A). f v = 0"
shows "lin_indpt (set A)"
proof (rule lin_comb_sum_lin_indpt, auto simp add: assms)
fix f v
have "⋀ v. v ∈ set A ⟹ dim_vec v = n"
using assms by auto
then show "lincomb_list (λi. f (A ! i)) A = 0⇩v n ⟹ v ∈ set A ⟹ f v = 0"
using  lincomb_list_as_mat_mult[of A "(λi. f (A ! i))"] assms(3)[of f] by auto
qed

lemma lin_comb_mat_lin_indpt_vs:
fixes A :: "'a vec list"
assumes "set (A) ⊆ carrier_vec n"
assumes "distinct A"
assumes "⋀ f. mat_of_cols n A *⇩v vec (length A) (λi. f (A ! i))  = 0⇩v n ⟹ ∀v∈ (set A). f v = 0"
shows "lin_indpt_vs (set A)"
using lin_comb_mat_lin_indpt lin_indpt_vs_def assms by auto

end

subsection ‹Linear Bound Argument Lemmas›

text ‹Three general representations of the linear bound argument, requiring a direct fact of
linear independence onthe rows of the vector space over either a set A of vectors, list xs of vectors
or a Matrix' columns ›
lemma lin_bound_arg_general_set:
fixes A ::"('a :: {field})vec set"
assumes "A ⊆ carrier_vec nr"
assumes "vec_space.lin_indpt_vs nr A"
shows "card A ≤ nr"
using vec_space.lin_indpt_set_card_lt_dim[of "A" "nr"] vec_space.lin_indpt_vs_def[of nr A]
vec_space.dim_is_n assms by metis

lemma lin_bound_arg_general_list:
fixes xs ::"('a :: {field})vec list"
assumes "distinct xs"
assumes "(set xs) ⊆ carrier_vec nr"
assumes "vec_space.lin_indpt_vs nr (set xs)"
shows "length (xs) ≤ nr"
using lin_bound_arg_general_set[of "set xs" nr] distinct_card assms
by force

lemma lin_bound_arg_general:
fixes A ::"('a :: {field}) mat"
assumes "distinct (cols A)"
assumes "A ∈ carrier_mat nr nc"
assumes "vec_space.lin_indpt_vs nr (set (cols A))"
shows "nc ≤ nr"
proof -
have ss: "set (cols A) ⊆ carrier_vec nr" using assms cols_dim by blast
have "length (cols A) = nc"
using assms(2) cols_length by blast
thus ?thesis using lin_bound_arg_general_list[of "cols A" "nr"] ss assms by simp
qed

text‹The linear bound argument lemma on a matrix requiring the lower level assumption on a linear
combination. This removes the need to directly refer to any aspect of the linear algebra libraries ›
lemma lin_bound_argument:
fixes A :: "('a :: {field}) mat"
assumes "distinct (cols A)"
assumes "A ∈ carrier_mat nr nc"
assumes "⋀ f. A *⇩v vec nc (λi. f (col A i)) = 0⇩v nr ⟹ ∀v∈ (set (cols A)). f v = 0"
shows "nc ≤ nr"
proof (intro lin_bound_arg_general[of "A" nr nc] vec_space.lin_comb_mat_lin_indpt_vs, simp_all add: assms)
show "set (cols A) ⊆ carrier_vec nr" using assms cols_dim by blast
next
have mA: "mat_of_cols nr (cols A) = A" using mat_of_cols_def assms by auto
have "⋀ f. vec (dim_col A) (λi. f (cols A ! i)) = vec nc (λi. f (col A i))"
proof (intro eq_vecI, simp_all add: assms)
show "⋀f i. i < nc ⟹ vec (dim_col A) (λi. f (cols A ! i)) \$ i = f (col A i)"
using assms(2) by force
show "dim_col A = nc " using assms by simp
qed
then show "⋀f. mat_of_cols nr (cols A) *⇩v vec (dim_col A) (λi. f (cols A ! i)) = 0⇩v nr ⟹
∀v∈set (cols A). f v = 0"
using mA assms(3) by metis
qed

text ‹A further extension to present the linear combination directly as a sum. This manipulation from
vector product to a summation was found to commonly be repeated in proofs applying this rule ›
lemma lin_bound_argument2:
fixes A :: "('a :: {field}) mat"
assumes "distinct (cols A)"
assumes "A ∈ carrier_mat nr nc"
assumes "⋀ f. vec nr (λi. ∑ j ∈ {0..<nc} . f (col A j) * (col A j) \$ i) = 0⇩v nr ⟹
∀v∈ (set (cols A)). f v = 0"
shows "nc ≤ nr"
proof (intro lin_bound_argument[of A nr nc], simp add: assms, simp add: assms)
fix f
have "A *⇩v vec nc (λi. f (col A i)) =
vec (dim_row A) (λi. ∑ j ∈ {0..<nc} . (row A i \$ j) * f (col A j))"
by (auto simp add: mult_mat_vec_def scalar_prod_def assms(2))
also have "... = vec (dim_row A) (λi. ∑ j ∈ {0..<nc} . f (col A j) * (col A j \$ i))"
using assms(2) by (intro eq_vecI, simp_all) (meson mult.commute)
finally show "A *⇩v vec nc (λi. f (col A i)) = 0⇩v nr ⟹ ∀v∈set (cols A). f v = 0"
using assms(3)[of f] assms(2) by fastforce
qed

end```