section"Linear Algebra on Finite Cartesian Products"
theory Cartesian_Space imports "HOL-Combinatorics.Transposition"
Finite_Cartesian_Product
Linear_Algebra begin
subsection✐‹tag unimportant›‹Type @{typ ‹'a ^ 'n›} and fields as vector spaces› (*much of the following is really basic linear algebra, check for overlap? renamesubsection? *)
definition"cart_basis = {axis i 1 | i. i∈UNIV}"
lemma finite_cart_basis: "finite (cart_basis)"unfolding cart_basis_def using finite_Atleast_Atmost_nat by fastforce
interpretation vec: vector_space "(*s) " by unfold_locales (vector algebra_simps)+
lemma independent_cart_basis: "vec.independent (cart_basis)" proof (rule vec.independent_if_scalars_zero) show"finite (cart_basis)"using finite_cart_basis . fix f::"('a, 'b) vec → 'a"and x::"('a, 'b) vec" assume eq_0: "(∑x∈cart_basis. f x *s x) = 0"and x_in: "x ∈ cart_basis" obtain i where x: "x = axis i 1"using x_in unfolding cart_basis_def by auto have sum_eq_0: "(∑x∈(cart_basis) - {x}. f x * (x $ i)) = 0" proof (intro sum.neutral ballI) fix y assume y: "y ∈ cart_basis - {x}" obtain a where a: "y = axis a 1"and a_not_i: "a ≠ i" using y x unfolding cart_basis_def by auto have"y $ i = 0"unfolding a axis_def using a_not_i by auto thus"f y * y $ i = 0"by simp qed have"0 = (∑x∈cart_basis. f x *s x) $ i"using eq_0 by simp alsohave"… = (∑x∈cart_basis. (f x *s x) $ i)"unfolding sum_component .. alsohave"… = (∑x∈cart_basis. f x * (x $ i))"unfolding vector_smult_component .. alsohave"… = f x * (x $ i) + (∑x∈(cart_basis) - {x}. f x * (x $ i))" by (rule sum.remove[OF finite_cart_basis x_in]) alsohave"… = f x * (x $ i)"unfolding sum_eq_0 by simp alsohave"… = f x"unfolding x axis_def by auto finallyshow"f x = 0" .. qed
lemma span_cart_basis [simp]: "vec.span (cart_basis) = UNIV" proof - have"x ∈ vec.span cart_basis"for x :: "('a, 'b) vec" proof - let ?f="λv. x $ (THE i. v = axis i 1)" have"x $ i = (∑v∈cart_basis. x $ (THE i. v = axis i 1) *s v) $ i"for i::'b proof - let ?w = "axis i (1::'a)" have the_eq_i: "(THE a. ?w = axis a 1) = i" by (rule the_equality, auto simp: axis_eq_axis) have sum_eq_0: "(∑v∈(cart_basis) - {?w}. x $ (THE i. v = axis i 1) * v $ i) = 0" proof (intro sum.neutral ballI) fix y:: "('a, 'b) vec" assume y: "y ∈ cart_basis - {?w}" obtain j where j: "y = axis j 1"and i_not_j: "i ≠ j" using y unfolding cart_basis_def by auto have the_eq_j: "(THE i. y = axis i 1) = j" by (simp add: axis_eq_axis j) show"x $ (THE i. y = axis i 1) * y $ i = 0" by (simp add: axis_def i_not_j j) qed have"(∑v∈cart_basis. x $ (THE i. v = axis i 1) *s v) $ i = (∑v∈cart_basis. x $ (THE i. v = axis i 1) * v $ i)" by force alsohave"… = x $ (THE a. ?w = axis a 1) * ?w $ i + (∑v∈(cart_basis) - {?w}. x $ (THE i. v = axis i 1) * v $ i)" by (rule sum.remove[OF finite_cart_basis], auto simp add: cart_basis_def) alsohave"… = x $ (THE a. ?w = axis a 1) * ?w $ i" unfolding sum_eq_0 by simp alsohave"… = x $ i" unfolding the_eq_i unfolding axis_def by auto finallyshow ?thesis by simp qed thenshow"x ∈ vec.span (cart_basis)" by (metis (no_types, lifting) vec.span_base vec.span_scale vec.span_sum vec_eq_iff) qed thenshow ?thesis by auto qed
(*Some interpretations:*) interpretation vec: finite_dimensional_vector_space "(*s)""cart_basis" by (unfold_locales, auto simp add: finite_cart_basis independent_cart_basis span_cart_basis)
lemma span_vec_eq: "vec.span X = span X" and dim_vec_eq: "vec.dim X = dim X" and dependent_vec_eq: "vec.dependent X = dependent X" and subspace_vec_eq: "vec.subspace X = subspace X" for X::"(real^'n) set" unfolding span_raw_def dim_raw_def dependent_raw_def subspace_raw_def by (auto simp: scalar_mult_eq_scaleR)
lemma linear_componentwise: fixes f:: "'a::field ^'m → 'a ^ 'n" assumes lf: "Vector_Spaces.linear (*s) (*s) f" shows"(f x)$j = sum (λi. (x$i) * (f (axis i 1)$j)) (UNIV :: 'm set)" (is"?lhs = ?rhs") proof - interpret lf: Vector_Spaces.linear "(*s)""(*s)" f using lf . let ?M = "(UNIV :: 'm set)" let ?N = "(UNIV :: 'n set)" have fM: "finite ?M"by simp have"?rhs = (sum (λi. (x$i) *s (f (axis i 1))) ?M)$j" unfolding sum_component by simp thenshow ?thesis unfolding lf.sum[symmetric] lf.scale[symmetric] unfolding basis_expansion by auto qed
interpretation vec: Vector_Spaces.linear "(*s)""(*s)""(*v) A" using matrix_vector_mul_linear_gen.
lemma matrix_works: assumes lf: "Vector_Spaces.linear (*s) (*s) f" shows"matrix f *v x = f (x::'a::field ^ 'n)" proof - have"∀i. (∑j∈UNIV. x $ j * f (axis j 1) $ i) = f x $ i" by (simp add: Cartesian_Space.linear_componentwise lf) thenshow ?thesis by (simp add: matrix_def matrix_vector_mult_def vec_eq_iff mult.commute) qed
lemma matrix_of_matrix_vector_mul[simp]: "matrix(λx. A *v (x :: 'a::field ^ 'n)) = A" by (simp add: matrix_eq matrix_works)
lemma matrix_compose_gen: assumes lf: "Vector_Spaces.linear (*s) (*s) (f::'a::{field}^'n → 'a^'m)" and lg: "Vector_Spaces.linear (*s) (*s) (g::'a^'m → 'a^_)" shows"matrix (g o f) = matrix g ** matrix f" using lf lg Vector_Spaces.linear_compose[OF lf lg] matrix_works[OF Vector_Spaces.linear_compose[OF lf lg]] by (simp add: matrix_eq matrix_works matrix_vector_mul_assoc[symmetric] o_def)
lemma matrix_compose: assumes"linear (f::real^'n → real^'m)""linear (g::real^'m → real^_)" shows"matrix (g o f) = matrix g ** matrix f" using matrix_compose_gen[of f g] assms by (simp add: linear_def scalar_mult_eq_scaleR)
lemma left_invertible_transpose: "(∃(B). B ** transpose (A) = mat (1::'a::comm_semiring_1)) ⟷ (∃(B). A ** B = mat 1)" by (metis matrix_transpose_mul transpose_mat transpose_transpose)
lemma right_invertible_transpose: "(∃(B). transpose (A) ** B = mat (1::'a::comm_semiring_1)) ⟷ (∃(B). B ** A = mat 1)" by (metis matrix_transpose_mul transpose_mat transpose_transpose)
lemma linear_matrix_vector_mul_eq: "Vector_Spaces.linear (*s) (*s) f ⟷ linear (f :: real^'n → real ^'m)" by (simp add: scalar_mult_eq_scaleR linear_def)
lemma matrix_vector_mul[simp]: "Vector_Spaces.linear (*s) (*s) g ==> (λy. matrix g *v y) = g" "linear f ==> (λx. matrix f *v x) = f" "bounded_linear f ==> (λx. matrix f *v x) = f" for f :: "real^'n → real ^'m" by (simp_all add: ext matrix_works linear_matrix_vector_mul_eq linear_linear)
lemma matrix_left_invertible_injective: fixes A :: "'a::field^'n^'m" shows"(∃B. B ** A = mat 1) ⟷ inj ((*v) A)" proof safe fix B assume B: "B ** A = mat 1" show"inj ((*v) A)" unfolding inj_on_def by (metis B matrix_vector_mul_assoc matrix_vector_mul_lid) next assume"inj ((*v) A)" from vec.linear_injective_left_inverse[OF matrix_vector_mul_linear_gen this] obtain g where"Vector_Spaces.linear (*s) (*s) g"and"g ∘ (*v) A = id" by blast thenhave"matrix g ** A = mat 1" by (metis matrix_compose_gen matrix_id_mat_1 matrix_of_matrix_vector_mul vec.linear_axioms) thenshow"∃B. B ** A = mat 1" by metis qed
lemma matrix_left_invertible_ker: "(∃B. (B::'a::{field} ^'m^'n) ** (A::'a::{field}^'n^'m) = mat 1) ⟷ (∀x. A *v x = 0 ⟶ x = 0)" by (simp add: matrix_left_invertible_injective vec.inj_iff_eq_0)
lemma matrix_right_invertible_surjective: "(∃B. (A::'a::field^'n^'m) ** (B::'a::field^'m^'n) = mat 1) ⟷ surj (λx. A *v x)" proof - have"∧B x. A ** B = mat 1 ==>∃y. x = A *v y" by (metis matrix_vector_mul_assoc matrix_vector_mul_lid) moreover have"∃B. A ** B = mat 1"if"surj ((*v) A)" by (metis (no_types, opaque_lifting) matrix_compose_gen matrix_id_mat_1
matrix_of_matrix_vector_mul vec.linear_axioms
vec.linear_surjective_right_inverse that) ultimatelyshow ?thesis by (auto simp: image_def set_eq_iff surj_def) qed
lemma matrix_left_invertible_independent_columns: fixes A :: "'a::{field}^'n^'m" shows"(∃(B::'a ^'m^'n). B ** A = mat 1) ⟷ (∀c. sum (λi. c i *s column i A) (UNIV :: 'n set) = 0 ⟶ (∀i. c i = 0))"
(is"?lhs ⟷ ?rhs") proof - let ?U = "UNIV :: 'n set" have"c i = 0" if"∀x. A *v x = 0 ⟶ x = 0""sum (λi. c i *s column i A) ?U = 0"for c i by (metis (no_types) UNIV_I matrix_mult_sum vec_lambda_eta vec_nth_cases zero_vec_def that) moreoverhave"x = 0"if"A *v x = 0" ?rhs for x by (metis (full_types) matrix_mult_sum that vec_eq_iff zero_index) ultimatelyshow ?thesis unfolding matrix_left_invertible_ker by auto qed
lemma matrix_right_invertible_independent_rows: fixes A :: "'a::{field}^'n^'m" shows"(∃(B::'a^'m^'n). A ** B = mat 1) ⟷ (∀c. sum (λi::'m. c i *s row i A) UNIV = 0 ⟶ (∀i. c i = 0))" by (simp add: matrix_left_invertible_independent_columns flip: left_invertible_transpose)
lemma matrix_right_invertible_span_columns: "(∃(B::'a::field ^'n^'m). (A::'a ^'m^'n) ** B = mat 1) ⟷ vec.span (columns A) = UNIV" (is"?lhs = ?rhs") proof - let ?U = "UNIV :: 'm set" have fU: "finite ?U"by simp have lhseq: "?lhs ⟷ (∀y. ∃(x::'a^'m). sum (λi. (x$i) *s column i A) ?U = y)" unfolding matrix_right_invertible_surjective matrix_mult_sum surj_def by (simp add: eq_commute) have rhseq: "?rhs ⟷ (∀x. x ∈ vec.span (columns A))"by blast
{ assume h: ?lhs
{ fix x:: "'a ^'n" obtain y :: "'a ^'m"where y: "sum (λi. (y$i) *s column i A) ?U = x" using h lhseq by blast thenhave"x ∈ vec.span (columns A)" by (metis (mono_tags, lifting) columns_def mem_Collect_eq vec.span_base vec.span_scale vec.span_sum)
} thenhave ?rhs unfolding rhseq by blast } moreover
{ assume h:?rhs let ?P = "λ(y::'a ^'n). ∃(x::'a^'m). sum (λi. (x$i) *s column i A) ?U = y"
{ fix y have"y ∈ vec.span (columns A)" unfolding h by blast thenhave"?P y" proof (induction rule: vec.span_induct_alt) case base thenshow ?case by (metis (full_types) matrix_mult_sum matrix_vector_mult_0_right) next case (step c y1 y2) from step obtain i where i: "i ∈ ?U""y1 = column i A" unfolding columns_def by blast obtain x:: "'a ^'m"where x: "sum (λi. (x$i) *s column i A) ?U = y2" using step by blast let ?x = "(χ j. if j = i then c + (x$i) else (x$j))::'a^'m" show ?case proof (rule exI[where x= "?x"], vector, auto simp add: i x[symmetric] if_distrib distrib_left if_distribR cong del: if_weak_cong) fix j have th: "∀xa ∈ ?U. (if xa = i then (c + (x$i)) * ((column xa A)$j) else (x$xa) * ((column xa A$j))) = (if xa = i then c * ((column i A)$j) else 0) + ((x$xa) * ((column xa A)$j))" using i(1) by (simp add: field_simps) have"sum (λxa. if xa = i then (c + (x$i)) * ((column xa A)$j) else (x$xa) * ((column xa A$j))) ?U = sum (λxa. (if xa = i then c * ((column i A)$j) else 0) + ((x$xa) * ((column xa A)$j))) ?U" using th by force alsohave"… = sum (λxa. if xa = i then c * ((column i A)$j) else 0) ?U + sum (λxa. ((x$xa) * ((column xa A)$j))) ?U" by (simp add: sum.distrib) alsohave"… = c * ((column i A)$j) + sum (λxa. ((x$xa) * ((column xa A)$j))) ?U" unfolding sum.delta[OF fU] using i(1) by simp finallyshow"sum (λxa. if xa = i then (c + (x$i)) * ((column xa A)$j) else (x$xa) * ((column xa A$j))) ?U = c * ((column i A)$j) + sum (λxa. ((x$xa) * ((column xa A)$j))) ?U" . qed qed
} thenhave ?lhs unfolding lhseq ..
} ultimatelyshow ?thesis by blast qed
lemma matrix_left_invertible_span_rows_gen: "(∃(B::'a^'m^'n). B ** (A::'a::field^'n^'m) = mat 1) ⟷ vec.span (rows A) = UNIV" by (metis columns_transpose matrix_right_invertible_span_columns right_invertible_transpose)
lemma matrix_left_invertible_span_rows: "(∃(B::real^'m^'n). B ** (A::real^'n^'m) = mat 1) ⟷ span (rows A) = UNIV" using matrix_left_invertible_span_rows_gen[of A] by (simp add: span_vec_eq)
lemma matrix_left_right_inverse1: fixes A A' :: "'a::{field}^'n^'n" assumes AA': "A ** A' = mat 1" shows"A' ** A = mat 1" proof - have sA: "surj ((*v) A)" using AA' matrix_right_invertible_surjective by auto obtain f' :: "'a ^'n → 'a ^'n" where f': "Vector_Spaces.linear (*s) (*s) f'""∀x. f' (A *v x) = x""∀x. A *v f' x = x" using sA vec.linear_surjective_isomorphism by blast have"matrix f' ** A = mat 1" by (metis f' matrix_eq matrix_vector_mul_assoc matrix_vector_mul_lid matrix_works) thus"A' ** A = mat 1" by (metis AA' matrix_mul_assoc matrix_mul_lid) qed
lemma matrix_left_right_inverse: fixes A A' :: "'a::{field}^'n^'n" shows"A ** A' = mat 1 ⟷ A' ** A = mat 1" using matrix_left_right_inverse1 by blast
lemma invertible_left_inverse: fixes A :: "'a::{field}^'n^'n" shows"invertible A ⟷ (∃(B::'a^'n^'n). B ** A = mat 1)" by (metis invertible_def matrix_left_right_inverse)
lemma invertible_right_inverse: fixes A :: "'a::{field}^'n^'n" shows"invertible A ⟷ (∃(B::'a^'n^'n). A** B = mat 1)" by (metis invertible_def matrix_left_right_inverse)
lemma invertible_mult: assumes inv_A: "invertible A" and inv_B: "invertible B" shows"invertible (A**B)" proof - obtain A' where AA': "A ** A' = mat 1"and A'A: "A' ** A = mat 1" using inv_A unfolding invertible_def by blast obtain B' where BB': "B ** B' = mat 1"and B'B: "B' ** B = mat 1" using inv_B unfolding invertible_def by blast have"A ** B ** (B' ** A') = mat 1" by (metis AA' BB' matrix_mul_assoc matrix_mul_rid) moreoverhave"B' ** A' ** (A ** B) = mat 1" by (metis A'A B'B matrix_mul_assoc matrix_mul_rid) ultimatelyshow ?thesis using invertible_def by blast qed
lemma transpose_invertible: fixes A :: "real^'n^'n" assumes"invertible A" shows"invertible (transpose A)" by (meson assms invertible_def matrix_left_right_inverse right_invertible_transpose)
lemma matrix_scaleR_vector_ac: fixes A :: "real^('m::finite)^'n" shows"A *v (k *R v) = k *R A *v v" by (metis matrix_vector_mult_scaleR transpose_scalar vector_scaleR_matrix_ac vector_transpose_matrix)
lemma scaleR_matrix_vector_assoc: fixes A :: "real^('m::finite)^'n" shows"k *R (A *v v) = k *R A *v v" by (metis matrix_scaleR_vector_ac matrix_vector_mult_scaleR)
subsection‹Some interesting theorems and interpretations›
locale linear_first_finite_dimensional_vector_space =
l?: Vector_Spaces.linear scaleB scaleC f +
B?: finite_dimensional_vector_space scaleB BasisB for scaleB :: "('a::field => 'b::ab_group_add => 'b)" (infixr‹*b›75) and scaleC :: "('a => 'c::ab_group_add => 'c)" (infixr‹*c›75) and BasisB :: "('b set)" and f :: "('b=>'c)"
lemma matrix_vector_mult_in_columnspace: fixes A :: "real^'n^'m" shows"(A *v x) ∈ span(columns A)" using matrix_vector_mult_in_columnspace_gen[of A x] by (simp add: span_vec_eq)
lemma subspace_orthogonal_to_vector: "subspace {y. orthogonal x y}" by (simp add: subspace_def orthogonal_clauses)
lemma orthogonal_nullspace_rowspace: fixes A :: "real^'n^'m" assumes0: "A *v x = 0"and y: "y ∈ span(rows A)" shows"orthogonal x y" using y proof (induction rule: span_induct) case base thenshow ?case by (simp add: subspace_orthogonal_to_vector) next case (step v) thenobtain i where"v = row i A" by (auto simp: rows_def) with0show ?case by (metis inner_commute matrix_vector_mul_component orthogonal_def row_def vec_lambda_eta
zero_index) qed
lemma nullspace_inter_rowspace: fixes A :: "real^'n^'m" shows"A *v x = 0 ∧ x ∈ span(rows A) ⟷ x = 0" using orthogonal_nullspace_rowspace orthogonal_self span_zero matrix_vector_mult_0_right by blast
lemma matrix_vector_mul_injective_on_rowspace: fixes A :: "real^'n^'m" shows"[A *v x = A *v y; x ∈ span(rows A); y ∈ span(rows A)]==> x = y" using nullspace_inter_rowspace [of A "x-y"] by (metis diff_eq_diff_eq diff_self matrix_vector_mult_diff_distrib span_diff)
definition✐‹tag important› rank :: "'a::field^'n^'m=>nat" where row_rank_def_gen: "rank A ≡ vec.dim(rows A)"
lemma row_rank_def: "rank A = dim (rows A)"for A::"real^'n^'m" by (auto simp: row_rank_def_gen dim_vec_eq)
lemma dim_rows_le_dim_columns: fixes A :: "real^'n^'m" shows"dim(rows A) ≤ dim(columns A)" proof - have"dim (span (rows A)) ≤ dim (span (columns A))" proof - obtain B where"independent B""span(rows A) ⊆ span B" and B: "B ⊆ span(rows A)""card B = dim (span(rows A))" using basis_exists [of "span(rows A)"] by metis with span_subspace have eq: "span B = span(rows A)" by auto thenhave inj: "inj_on ((*v) A) (span B)" by (simp add: inj_on_def matrix_vector_mul_injective_on_rowspace) thenhave ind: "independent ((*v) A ` B)" by (rule linear_independent_injective_image [OF Finite_Cartesian_Product.matrix_vector_mul_linear ‹independent B›]) have"dim (span (rows A)) ≤ card ((*v) A ` B)" by (metis B(2) card_image inj inj_on_subset order.refl span_superset) alsohave"…≤ dim (span (columns A))" using _ ind by (rule independent_card_le_dim) (auto intro!: matrix_vector_mult_in_columnspace) finallyshow ?thesis . qed thenshow ?thesis by simp qed
lemma column_rank_def: fixes A :: "real^'n^'m" shows"rank A = dim(columns A)" unfolding row_rank_def by (metis columns_transpose dim_rows_le_dim_columns le_antisym rows_transpose)
lemma rank_transpose: fixes A :: "real^'n^'m" shows"rank(transpose A) = rank A" by (metis column_rank_def row_rank_def rows_transpose)
lemma matrix_vector_mult_basis: fixes A :: "real^'n^'m" shows"A *v (axis k 1) = column k A" by (simp add: cart_eq_inner_axis column_def matrix_mult_dot)
lemma columns_image_basis: fixes A :: "real^'n^'m" shows"columns A = (*v) A ` (range (λi. axis i 1))" by (force simp: columns_def matrix_vector_mult_basis [symmetric])
lemma rank_dim_range: fixes A :: "real^'n^'m" shows"rank A = dim(range (λx. A *v x))" unfolding column_rank_def by (smt (verit, best) columns_image_basis dim_span image_subset_iff iso_tuple_UNIV_I matrix_vector_mult_in_columnspace span_eq)
lemma rank_bound: fixes A :: "real^'n^'m" shows"rank A ≤ min CARD('m) (CARD('n))" by (metis (mono_tags, lifting) dim_subset_UNIV_cart min.bounded_iff
column_rank_def row_rank_def)
lemma full_rank_injective: fixes A :: "real^'n^'m" shows"rank A = CARD('n) ⟷ inj ((*v) A)" by (simp add: matrix_left_invertible_injective [symmetric] matrix_left_invertible_span_rows row_rank_def
dim_eq_full [symmetric] card_cart_basis vec.dimension_def)
lemma full_rank_surjective: fixes A :: "real^'n^'m" shows"rank A = CARD('m) ⟷ surj ((*v) A)" by (metis (no_types, opaque_lifting) dim_eq_full dim_vec_eq rank_dim_range span_vec_eq vec.span_UNIV vec.span_image vec_dim_card)
lemma less_rank_noninjective: fixes A :: "real^'n^'m" shows"rank A < CARD('n) ⟷¬ inj ((*v) A)" using less_le rank_bound by (auto simp: full_rank_injective [symmetric])
lemma matrix_nonfull_linear_equations_eq: fixes A :: "real^'n^'m" shows"(∃x. (x ≠ 0) ∧ A *v x = 0) ⟷ rank A ≠ CARD('n)" by (meson matrix_left_invertible_injective full_rank_injective matrix_left_invertible_ker)
lemma rank_eq_0: "rank A = 0 ⟷ A = 0"and rank_0 [simp]: "rank (0::real^'n^'m) = 0" for A :: "real^'n^'m" by (auto simp: rank_dim_range matrix_eq)
lemma rank_mul_le_right: fixes A :: "real^'n^'m"and B :: "real^'p^'n" shows"rank(A ** B) ≤ rank B" proof - have"rank(A ** B) ≤ dim ((*v) A ` range ((*v) B))" by (auto simp: rank_dim_range image_comp o_def matrix_vector_mul_assoc) alsohave"…≤ rank B" by (simp add: rank_dim_range dim_image_le) finallyshow ?thesis . qed
lemma rank_mul_le_left: fixes A :: "real^'n^'m"and B :: "real^'p^'n" shows"rank(A ** B) ≤ rank A" by (metis matrix_transpose_mul rank_mul_le_right rank_transpose)
subsection✐‹tag unimportant›‹Lemmas for working on ‹real^1/2/3/4››
lemma exhaust_2: fixes x :: 2 shows"x = 1 ∨ x = 2" proof (induct x) case (of_int z) thenhave"z = 0 | z = 1" by fastforce thenshow ?case by auto qed
lemma forall_2: "(∀i::2. P i) ⟷ P 1 ∧ P 2" by (metis exhaust_2)
lemma exhaust_3: fixes x :: 3 shows"x = 1 ∨ x = 2 ∨ x = 3" proof (induct x) case (of_int z) thenhave"z = 0 ∨ z = 1 ∨ z = 2"by fastforce thenshow ?caseby auto qed
lemma forall_3: "(∀i::3. P i) ⟷ P 1 ∧ P 2 ∧ P 3" by (metis exhaust_3)
lemma exhaust_4: fixes x :: 4 shows"x = 1 ∨ x = 2 ∨ x = 3 ∨ x = 4" proof (induct x) case (of_int z) thenhave"z = 0 ∨ z = 1 ∨ z = 2 ∨ z = 3"by fastforce thenshow ?caseby auto qed
lemma forall_4: "(∀i::4. P i) ⟷ P 1 ∧ P 2 ∧ P 3 ∧ P 4" by (metis exhaust_4)
lemma UNIV_1 [simp]: "UNIV = {1::1}" by auto
lemma UNIV_2: "UNIV = {1, 2::2}" using exhaust_2 by auto
lemma UNIV_3: "UNIV = {1, 2, 3::3}" using exhaust_3 by auto
lemma UNIV_4: "UNIV = {1, 2, 3, 4::4}" using exhaust_4 by auto
lemma sum_1: "sum f (UNIV::1 set) = f 1" unfolding UNIV_1 by simp
lemma sum_2: "sum f (UNIV::2 set) = f 1 + f 2" unfolding UNIV_2 by simp
lemma sum_3: "sum f (UNIV::3 set) = f 1 + f 2 + f 3" unfolding UNIV_3 by (simp add: ac_simps)
lemma sum_4: "sum f (UNIV::4 set) = f 1 + f 2 + f 3 + f 4" unfolding UNIV_4 by (simp add: ac_simps)
subsection✐‹tag unimportant›\<open>The collapse of the general concepts to dimension one›
lemma vector_one: "(x::'a ^1) = (χ i. (x$1))" by (simp add: vec_eq_iff)
lemma forall_one: "(∀(x::'a ^1). P x) ⟷ (∀x. P(χ i. x))" by (metis vector_one)
lemma dist_real: "dist(x::real ^ 1) y = ∣(x$1) - (y$1)∣" by (auto simp add: norm_real dist_norm)
subsection✐‹tag unimportant›‹Routine results connecting the types typ‹real^1› and typ‹real›\<close>
lemma vector_one_nth [simp]: fixes x :: "'a^1"shows"vec (x $ 1) = x" by (metis vec_def vector_one)
lemma tendsto_at_within_vector_1: fixes S :: "'a :: metric_space set" assumes"(f ---> fx) (at x within S)" shows"((λy::'a^1. χ i. f (y $ 1)) ---> (vec fx::'a^1)) (at (vec x) within vec ` S)" proof (rule topological_tendstoI) fix T :: "('a^1) set" assume"open T""vec fx ∈ T" have"∀F x in at x within S. f x ∈ (λx. x $ 1) ` T" using‹open T›‹vec fx ∈ T› assms open_image_vec_nth tendsto_def by fastforce thenshow"∀F x::'a^1 in at (vec x) within vec ` S. (χ i. f (x $ 1)) ∈ T" unfolding eventually_at dist_norm [symmetric] by (rule ex_forward)
(use‹open T›in ‹fastforce simp: dist_norm dist_vec_def L2_set_def image_iff vector_one open_vec_def›) qed
lemma forall_vector_1: "(∀v::'a::zero^1. P v) ⟷ (∀x. P(vector[x]))" by (metis vector_1 vector_one)
lemma forall_vector_2: "(∀v::'a::zero^2. P v) ⟷ (∀x y. P(vector[x, y]))" proof - have"P v"if"∧x y. P (vector [x, y])"for v proof - have"vector [v$1, v$2] = v" unfolding vec_eq_iff by (metis (mono_tags) exhaust_2 vector_2) thenshow ?thesis by (metis that) qed thenshow ?thesis by auto qed
lemma forall_vector_3: "(∀v::'a::zero^3. P v) ⟷ (∀x y z. P(vector[x, y, z]))" proof - have"P v"if"∧x y z. P (vector [x, y, z])"for v proof - have"vector [v$1, v$2, v$3] = v" unfolding vec_eq_iff by (metis (mono_tags) exhaust_3 vector_3) thenshow ?thesis by (metis that) qed thenshow ?thesis by auto qed
subsection✐‹tag unimportant›‹lambda skolemization on cartesian products›
lemmainduct_matrix_row_operations: fixesP::"real^'n^'n\<Rightarrow>bool" assumeszero_row:"\<And>Ai.rowiA=0\<Longrightarrow>PA" anddiagonal:"\<And>A.(\<And>ij.i\<noteq>j\<Longrightarrow>A$i$j=0)\<Longrightarrow>PA" andswap_cols:"\<And>Amn.\<lbrakk>PA;m\<noteq>n\<rbrakk>\<Longrightarrow>P(\<chi>ij.A$i$Transposition.transposemnj)" androw_op:"\<And>Amnc.\<lbrakk>PA;m\<noteq>n\<rbrakk> \<Longrightarrow>P(\<chi>i.ifi=mthenrowmA+c*\<^sub>RrownAelserowiA)" shows"PA" proof- have"PA"if"(\<And>ij.\<lbrakk>j\<in>-K;i\<noteq>j\<rbrakk>\<Longrightarrow>A$i$j=0)"forAK proof- have"finiteK" bysimp thenshow?thesisusingthat proof(inductionarbitrary:Arule:finite_induct) caseempty withdiagonalshow?case bysimp next case(insertkK) noteinsertK=insert have"PA"ifkk:"A$k$k\<noteq>0" and0:"\<And>ij.\<lbrakk>j\<in>-insertkK;i\<noteq>j\<rbrakk>\<Longrightarrow>A$i$j=0" "\<And>i.\<lbrakk>i\<in>-L;i\<noteq>k\<rbrakk>\<Longrightarrow>A$i$k=0"forAL proof- have"finiteL" bysimp thenshow?thesisusing0kk proof(inductionarbitrary:Arule:finite_induct) case(emptyB) show?case proof(ruleinsertK) fixij assume"i\<in>-K""j\<noteq>i" show"B$j$i=0" using\<open>j\<noteq>i\<close>\<open>i\<in>-K\<close>empty by(metisComplDComplICompl_eq_Diff_UNIVDiff_emptyUNIV_Iinsert_iff) qed next case(insertlLB) show?case proof(cases"k=l") caseTrue withinsertshow?thesis byauto next caseFalse let?C="\<chi>i.ifi=lthenrowlB-(B$l$k/B$k$k)*\<^sub>RrowkBelserowiB" have1:"\<lbrakk>j\<in>-insertkK;i\<noteq>j\<rbrakk>\<Longrightarrow>?C$i$j=0"forji by(autosimp:insert.prems(1)row_def) have2:"?C$i$k=0" if"i\<in>-L""i\<noteq>k"fori proof(cases"i=l") caseTrue withthatinsert.premsshow?thesis by(simpadd:row_def) next caseFalse withthatshow?thesis by(simpadd:insert.prems(2)row_def) qed have3:"?C$k$k\<noteq>0" by(autosimp:insert.premsrow_def\<open>k\<noteq>l\<close>) havePC:"P?C" usinginsert.IH[OF123]byauto haveeqB:"(\<chi>i.ifi=lthenrowl?C+(B$l$k/B$k$k)*\<^sub>Rrowk?Celserowi?C)=B" using\<open>k\<noteq>l\<close>by(simpadd:vec_eq_iffrow_def) show?thesis usingrow_op[OFPC,oflk,wherec="B$l$k/B$k$k"]eqB\<open>k\<noteq>l\<close> by(simpadd:cong:if_cong) qed qed qed thenhavenonzero_hyp:"PA" ifkk:"A$k$k\<noteq>0"andzeroes:"\<And>ij.j\<in>-insertkK\<and>i\<noteq>j\<Longrightarrow>A$i$j=0"forA by(autosimp:intro!:kkzeroes) show?case proof(cases"rowkA=0") caseTrue withzero_rowshow?thesisbyauto next caseFalse thenobtainlwherel:"A$k$l\<noteq>0" by(autosimp:row_defzero_vec_defvec_eq_iff) show?thesis proof(cases"k=l") caseTrue withlnonzero_hypinsert.premsshow?thesis byblast next caseFalse have*:"A$i$Transposition.transposeklj=0"if"j\<noteq>k""j\<notin>K""i\<noteq>j"forij usingFalselinsert.premsthat by(autosimpadd:Transposition.transpose_def) have"P(\<chi>ij.(\<chi>ij.A$i$Transposition.transposeklj)$i$Transposition.transposeklj)"
by (rule swap_cols [OF nonzero_hyp False]) (auto simp: l *) moreover have"(χ i j. (χ i j. A $ i $ Transposition.transpose k l j) $ i $ Transposition.transpose k l j) = A" by simp ultimatelyshow ?thesis by simp qed qed qed qed thenshow ?thesis by blast qed
lemma induct_matrix_elementary: fixes P :: "real^'n^'n → bool" assumes mult: "∧A B. [P A; P B]==> P(A ** B)" and zero_row: "∧A i. row i A = 0 ==> P A" and diagonal: "∧A. (∧i j. i ≠ j ==> A$i$j = 0) ==> P A" and swap1: "∧m n. m ≠ n ==> P(χ i j. mat 1 $ i $ Transposition.transpose m n j)" and idplus: "∧m n c. m ≠ n ==> P(χ i j. if i = m ∧ j = n then c else of_bool (i = j))" shows"P A" proof - have swap: "P (χ i j. A $ i $ Transposition.transpose m n j)" (is"P ?C") if"P A""m ≠ n"for A m n proof - have"A ** (χ i j. mat 1 $ i $ Transposition.transpose m n j) = ?C" by (simp add: matrix_matrix_mult_def mat_def vec_eq_iff if_distrib sum.delta_remove) thenshow ?thesis using mult swap1 that by metis qed have row: "P (χ i. if i = m then row m A + c *R row n A else row i A)" (is"P ?C") if"P A""m ≠ n"for A m n c proof - let ?B = "χ i j. if i = m ∧ j = n then c else of_bool (i = j)" have"?B ** A = ?C" using‹m ≠ n›unfolding matrix_matrix_mult_def row_def of_bool_def by (auto simp: vec_eq_iff if_distrib [of "λx. x * y"for y] sum.remove cong: if_cong) thenshow ?thesis by (rule subst) (auto simp: that mult idplus) qed show ?thesis by (rule induct_matrix_row_operations [OF zero_row diagonal swap row]) qed
lemma induct_matrix_elementary_alt: fixes P :: "real^'n^'n → bool" assumes mult: "∧A B. [P A; P B]==> P(A ** B)" and zero_row: "∧A i. row i A = 0 ==> P A" and diagonal: "∧A. (∧i j. i ≠ j ==> A$i$j = 0) ==> P A" and swap1: "∧m n. m ≠ n ==> P(χ i j. mat 1 $ i $ Transposition.transpose m n j)" and idplus: "∧m n. m ≠ n ==> P(χ i j. of_bool (i = m ∧ j = n ∨ i = j))" shows"P A" proof - have *: "P (χ i j. if i = m ∧ j = n then c else of_bool (i = j))" if"m ≠ n"for m n c proof (cases "c = 0") case True with diagonal show ?thesis by auto next case False thenhave eq: "(χ i j. if i = m ∧ j = n then c else of_bool (i = j)) = (χ i j. if i = j then (if j = n then inverse c else 1) else 0) ** (χ i j. of_bool (i = m ∧ j = n ∨ i = j)) ** (χ i j. if i = j then if j = n then c else 1 else 0)" using‹m ≠ n› apply (simp add: matrix_matrix_mult_def vec_eq_iff of_bool_def if_distrib [of "λx. y * x"for y] cong: if_cong) apply (simp add: if_if_eq_conj sum.neutral conj_commute cong: conj_cong) done show ?thesis unfolding eq by (intro mult idplus that) (auto intro: diagonal) qed show ?thesis by (rule induct_matrix_elementary) (auto intro: assms *) qed
lemma matrix_vector_mult_matrix_matrix_mult_compose: "(*v) (A ** B) = (*v) A ∘ (*v) B" by (auto simp: matrix_vector_mul_assoc)
lemma induct_linear_elementary: fixes f :: "real^'n → real^'n" assumes"linear f" and comp: "∧f g. [linear f; linear g; P f; P g]==> P(f ∘ g)" and zeroes: "∧f i. [linear f; ∧x. (f x) $ i = 0]==> P f" and const: "∧c. P(λx. χ i. c i * x$i)" and swap: "∧m n::'n. m ≠ n ==> P(λx. χ i. x $ Transposition.transpose m n i)" and idplus: "∧m n::'n. m ≠ n ==> P(λx. χ i. if i = m then x$m + x$n else x$i)" shows"P f" proof - have"P ((*v) A)"for A proof (rule induct_matrix_elementary_alt) fix A B assume"P ((*v) A)"and"P ((*v) B)" thenshow"P ((*v) (A ** B))" by (auto simp add: matrix_vector_mult_matrix_matrix_mult_compose intro!: comp) next fix A :: "real^'n^'n"and i assume"row i A = 0" with matrix_vector_mul_linear show"P ((*v) A)" by (metis matrix_vector_mul_component matrix_vector_mult_0 row_def
vec_lambda_eta zero_index zeroes) next fix A :: "real^'n^'n" assume0: "∧i j. i ≠ j ==> A $ i $ j = 0" have"A $ i $ i * x $ i = (∑j∈UNIV. A $ i $ j * x $ j)"for x and i :: "'n" by (simp add: 0 comm_monoid_add_class.sum.remove [where x=i]) thenhave"(λx. χ i. A $ i $ i * x $ i) = ((*v) A)" by (auto simp: 0 matrix_vector_mult_def) thenshow"P ((*v) A)" using const [of "λi. A $ i $ i"] by simp next fix m n :: "'n" assume"m ≠ n" have eq: "(∑j∈UNIV. if i = Transposition.transpose m n j then x $ j else 0) = (∑j∈UNIV. if j = Transposition.transpose m n i then x $ j else 0)" for i and x :: "real^'n" by (rule sum.cong) (auto simp add: swap_id_eq) have"(λx::real^'n. χ i. x $ Transposition.transpose m n i) = ((*v) (χ i j. if i = Transposition.transpose m n j then 1 else 0))" by (auto simp: mat_def matrix_vector_mult_def eq if_distrib [of "λx. x * y"for y] cong: if_cong) with swap [OF ‹m ≠ n›] show"P ((*v) (χ i j. mat 1 $ i $ Transposition.transpose m n j))" by (simp add: mat_def matrix_vector_mult_def) next fix m n :: "'n" assume"m ≠ n" thenhave"x $ m + x $ n = (∑j∈UNIV. of_bool (j = n ∨ m = j) * x $ j)"for x :: "real^'n" by (auto simp: of_bool_def if_distrib [of "λx. x * y"for y] sum.remove cong: if_cong) thenhave"(λx::real^'n. χ i. if i = m then x $ m + x $ n else x $ i) = ((*v) (χ i j. of_bool (i = m ∧ j = n ∨ i = j)))" unfolding matrix_vector_mult_def of_bool_def by (auto simp: vec_eq_iff if_distrib [of "λx. x * y"for y] cong: if_cong) thenshow"P ((*v) (χ i j. of_bool (i = m ∧ j = n ∨ i = j)))" using idplus [OF ‹m ≠ n›] by simp qed thenshow ?thesis by (metis ‹linear f› matrix_vector_mul(2)) qed
end
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.47 Sekunden
(vorverarbeitet am 2026-06-30)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.