Theory Triangle_Lemmas
theory Triangle_Lemmas
imports
Polygon_Convex_Lemmas
Integral_Matrix
"Affine_Arithmetic.Floatarith_Expression"
"HOL-Analysis.Topology_Euclidean_Space"
"HOL-Analysis.Equivalence_Lebesgue_Henstock_Integration"
"HOL-Analysis.Inner_Product"
"HOL-Analysis.Line_Segment"
"HOL-Analysis.Convex_Euclidean_Space"
"HOL-Analysis.Change_Of_Vars"
begin
section "Triangles"
definition elem_triangle :: "real^2 ⇒ real^2 ⇒ real^2 ⇒ bool" where
"elem_triangle a b c ⟷
¬ collinear {a, b, c}
∧ integral_vec a ∧ integral_vec b ∧ integral_vec c
∧ {x. x ∈ convex hull {a, b, c} ∧ integral_vec x} = {a, b, c}"
definition triangle_mat :: "real^2 ⇒ real^2 ⇒ real^2 ⇒ real^2^2" where
"triangle_mat a b c = transpose (vector [b - a, c - a])"
definition triangle_linear :: "real^2 ⇒ real^2 ⇒ real^2 ⇒ (real^2 ⇒ real^2)" where
"triangle_linear a b c = (λx. (triangle_mat a b c) *v x)"
definition triangle_affine :: "real^2 ⇒ real^2 ⇒ real^2 ⇒ (real^2 ⇒ real^2)" where
"triangle_affine a b c = (λx. a + (triangle_mat a b c) *v x)"
abbreviation "unit_square ≡
(convex hull {vector [0, 0], vector [0, 1], vector [1, 1], vector [1, 0]})::((real^2) set)"
abbreviation "unit_triangle ≡
(convex hull {vector [0, 0], vector [1, 0], vector [0, 1]})::((real^2) set)"
abbreviation "unit_triangle' ≡
(convex hull {vector [1, 1], vector [1, 0], vector [0, 1]})::((real^2) set)"
lemma triangle_inside_is_convex_hull_interior:
assumes "polygon_of p [a, b, c, a]"
shows "path_inside p = interior (convex hull {a, b, c})"
proof-
have "path_image p = closed_segment a b ∪ closed_segment b c ∪ closed_segment c a"
proof-
have "path_image (linepath a b) = closed_segment a b" by simp
moreover have "path_image (linepath b c) = closed_segment b c" by simp
moreover have "path_image (linepath c a) = closed_segment c a" by simp
moreover have "path_image p = path_image (linepath a b) ∪ path_image (linepath b c) ∪ path_image (linepath c a)"
using calculation assms(1) unfolding polygon_of_def make_polygonal_path.simps
by (simp add: path_image_join sup_assoc)
ultimately show ?thesis by simp
qed
moreover have "DIM((real, 2) vec) = 2" by simp
ultimately show ?thesis using inside_of_triangle[of a b c] unfolding path_inside_def by presburger
qed
lemma triangle_is_convex:
assumes "p = make_triangle a b c" and "¬ collinear {a, b, c}"
shows "convex (path_inside p)" (is "convex ?s")
using triangle_inside_is_convex_hull_interior assms(1) assms(2)
using make_triangle_def polygon_of_def triangle_is_polygon
by auto
lemma affine_comp_linear_trans: "triangle_affine a b c = (λx. x + a) ∘ (triangle_linear a b c)"
apply (simp add: triangle_affine_def triangle_linear_def)
by auto
lemma triangle_linear_der:
fixes a b c :: "real^2"
defines "T ≡ triangle_linear a b c"
shows "(T has_derivative T) (at x)"
proof-
have "linear T" using T_def by (simp add: triangle_linear_def)
then have "bounded_linear T" by (simp add: linear_linear)
thus ?thesis using bounded_linear_imp_has_derivative by blast
qed
lemma triangle_affine_der:
fixes a b c :: "real^2"
assumes "S ∈ sets lebesgue" and "x ∈ S"
defines "A ≡ triangle_affine a b c" and "T ≡ triangle_linear a b c"
shows "x ∈ S ⟹ (A has_derivative T) (at x within S)"
proof-
assume xin: "x ∈ S"
let ?trans = "λx::real^2. x + a"
have comp: "(?trans ∘ T) = (λx. (T x) + a)"
by auto
have "∀x. A x = (?trans ∘ T) x" unfolding A_def T_def using affine_comp_linear_trans by auto
moreover then have Ax_is: "(⋀x. x ∈ S ⟹ A x = ((λx. x + a) ∘ T) x)"
by auto
moreover have trans_der: "(?trans has_derivative id) (at x within S)"
by (metis (full_types) add.commute assms(2) eq_id_iff has_derivative_transform shift_has_derivative_id)
moreover have Tder: "(T has_derivative T) (at x within S)" using triangle_linear_der
by (simp add: T_def bounded_linear_imp_has_derivative triangle_linear_def)
moreover have comp_der: "((?trans ∘ T) has_derivative T) (at x within S)"
using has_derivative_add_const[OF Tder] comp
by simp
ultimately show "(A has_derivative T) (at x within S)"
using triangle_affine_def triangle_linear_def affine_comp_linear_trans o_apply add.commute vector_derivative_chain_within assms(2) has_derivative_add_const has_derivative_transform A_def T_def
by force
qed
lemma triangle_linear_inj:
fixes a b c :: "real^2"
assumes "¬ collinear {a, b, c}"
defines "L ≡ triangle_linear a b c"
shows "inj L"
proof-
let ?M = "triangle_mat a b c"
let ?m_11 = "(b - a)$1"
let ?m_12 = "(c - a)$1"
let ?m_21 = "(b - a)$2"
let ?m_22 = "(c - a)$2"
have "det ?M = ?m_11*?m_22 - ?m_12*?m_21"
unfolding triangle_mat_def
by (metis det_2 det_transpose mult.commute vector_2(1) vector_2(2))
moreover have "?m_11*?m_22 ≠ ?m_12*?m_21"
proof(rule ccontr)
assume "¬ ?m_11*?m_22 ≠ ?m_12*?m_21"
then have eq: "?m_11*?m_22 = ?m_12*?m_21" by simp
{ assume *: "?m_21 = 0 ∧ ?m_22 ≠ 0"
then have "?m_11 = 0" using eq by simp
then have "?m_11 = 0 ∧ ?m_21 = 0" using * by auto
then have "b - a = 0" by (metis (no_types, opaque_lifting) exhaust_2 vec_eq_iff zero_index)
then have "collinear {a, b, c}" by simp
then have False using assms by fastforce
} moreover
{ assume *: "?m_21 ≠ 0 ∧ ?m_22 = 0"
then have "?m_12 = 0" using eq by simp
then have "?m_12 = 0 ∧ ?m_22 = 0" using * by auto
then have "c - a = 0" by (metis (no_types, opaque_lifting) exhaust_2 vec_eq_iff zero_index)
then have "collinear {a, b, c}" by (simp add: collinear_3_eq_affine_dependent)
then have False using assms by fastforce
} moreover
{ assume *: "?m_21 = 0 ∧ ?m_22 = 0"
{ assume "?m_11 = 0"
then have "b - a = 0" using *
by (metis (no_types, opaque_lifting) exhaust_2 vec_eq_iff zero_index)
then have False using assms(1) by auto
} moreover
{ assume "?m_11 ≠ 0"
then obtain k where "?m_12 = k * ?m_11" using nonzero_divide_eq_eq by blast
moreover have "?m_22 = k * ?m_21" using * by auto
ultimately have "c - a = k *⇩R (b - a)"
by (smt (verit, del_insts) exhaust_2 real_scaleR_def vec_eq_iff vector_scaleR_component)
then have "collinear {a, b, c}"
using vec_diff_scale_collinear[of c a k b] by (simp add: insert_commute)
then have False using assms(1) by fastforce
}
ultimately have False using assms by fastforce
} moreover
{ assume *: "?m_21 ≠ 0 ∧ ?m_22 ≠ 0"
then have "?m_11/?m_21 = ?m_12/?m_22" using eq frac_eq_eq by blast
then obtain m where "?m_11 = m*?m_12 ∧ ?m_21 = m*?m_22"
using nonzero_divide_eq_eq *
by (metis (no_types, lifting) mult.commute times_divide_eq_left)
then have "b - a = m *s (c - a)"
by (smt (verit, del_insts) exhaust_2 vec_eq_iff vector_smult_component)
then have "b - a = m *⇩R (c - a)" by (simp add: scalar_mult_eq_scaleR)
then have "collinear {a, b, c}" using vec_diff_scale_collinear by auto
then have False using assms by auto
}
ultimately show False by fastforce
qed
ultimately have "det ?M ≠ 0" by linarith
thus ?thesis by (simp add: L_def inj_matrix_vector_mult invertible_det_nz triangle_linear_def)
qed
lemma triangle_affine_inj:
fixes a b c :: "real^2"
assumes "¬ collinear {a, b, c}"
defines "A ≡ triangle_affine a b c"
shows "inj A"
proof-
have "inj (triangle_linear a b c)" using triangle_linear_inj[of a b c] assms by auto
moreover have "inj (λx. x + a)" by simp
moreover have "A = (λx. x + a) ∘ (triangle_linear a b c)"
by (simp add: A_def affine_comp_linear_trans)
ultimately show ?thesis using inj_compose by blast
qed
lemma triangle_linear_integrable:
fixes a b c :: "real^2"
assumes "S ∈ lmeasurable"
defines "T ≡ triangle_linear a b c"
shows "(λx. abs (det (matrix (T)))) integrable_on S" (is "(λx. ?c) integrable_on S")
using integrable_on_const[of S ?c] assms(1) by blast
lemma measure_differentiable_image_eq_affine:
fixes a b c :: "real^2"
defines "A ≡ triangle_affine a b c" and "T ≡ triangle_linear a b c"
assumes "S ∈ lmeasurable" and "¬ collinear {a, b, c}"
shows "measure lebesgue (A ` S) = integral S (λx. abs (det (matrix T)))"
proof-
have "⋀x. x ∈ S ⟹ (A has_derivative T) (at x within S)"
using triangle_affine_der A_def T_def assms(3) by blast
moreover have "inj_on A S"
using A_def assms(3) assms(4) triangle_affine_inj inj_on_subset by blast
moreover have "(λx. abs (det (matrix (T)))) integrable_on S"
by (simp add: T_def assms(3) triangle_linear_integrable)
ultimately show ?thesis
using measure_differentiable_image_eq[of _ _ "λx. T"] assms(3) by blast
qed
lemma triangle_affine_img:
fixes a b c :: "real^2"
defines "A ≡ triangle_affine a b c"
shows "convex hull {a, b, c} = A ` unit_triangle"
proof-
let ?O = "(vector [0, 0])::real^2"
let ?e1 = "(vector [1, 0])::real^2"
let ?e2 = "(vector [0, 1])::real^2"
let ?translate_a = "λx. x + a"
let ?T = "triangle_linear a b c"
define al where "al = ?T ?O"
define bl where "bl = ?T ?e1"
define cl where "cl = ?T ?e2"
have a: "a = ?translate_a al"
proof-
have "al = ?O"
by (simp add: al_def mat_vec_mult_2 triangle_linear_def)
then show ?thesis
by (metis (no_types, opaque_lifting) add_0 mat_vec_mult_2 matrix_vector_mult_0 mult_zero_right zero_index)
qed
have b: "b = ?translate_a bl"
proof-
have col1: "column 1 (triangle_mat a b c) = b - a"
by (metis column_transpose row_def triangle_mat_def vec_lambda_eta vector_2(1))
then have "bl = b - a"
using bl_def unfolding triangle_linear_def triangle_mat_def matrix_vector_mult_def
using matrix_vector_mult_basis[of "triangle_mat a b c" 1]
by (simp add: col1 axis_def bl_def mat_vec_mult_2 triangle_linear_def)
then show ?thesis by simp
qed
have c: "c = ?translate_a cl"
proof-
have col2: "column 2 (triangle_mat a b c) = c - a"
by (metis column_transpose row_def triangle_mat_def vec_lambda_eta vector_2(2))
then have "cl = c - a"
using cl_def unfolding triangle_linear_def triangle_mat_def matrix_vector_mult_def
using matrix_vector_mult_basis[of "triangle_mat a b c" 2]
by (simp add: col2 axis_def cl_def mat_vec_mult_2 triangle_linear_def)
then show ?thesis by simp
qed
have "linear ?T" using triangle_linear_def by force
then have "?T ` unit_triangle = convex hull {al, bl, cl}"
using convex_hull_linear_image al_def bl_def cl_def by force
also have "?translate_a ` ... = convex hull {a, b, c}"
using a b c convex_hull_translation[of a "{al, bl, cl}"]
by (metis (no_types, lifting) add.commute image_cong image_empty image_insert)
finally have "?translate_a ` (?T ` unit_triangle) = convex hull {a, b, c}" .
moreover have "?translate_a ∘ ?T = A" unfolding A_def using affine_comp_linear_trans by auto
ultimately show ?thesis by fastforce
qed
lemma triangle_affine_e1_e2:
fixes a b c :: "real^2"
defines "A ≡ triangle_affine a b c"
shows "(triangle_affine a b c) (vector [0, 0]) = a"
"(triangle_affine a b c) (vector [1, 0]) = b"
"(triangle_affine a b c) (vector [0, 1]) = c"
proof-
let ?M = "triangle_mat a b c"
let ?L = "triangle_linear a b c"
let ?A = "triangle_affine a b c"
let ?O = "(vector [0, 0])::(real^2)"
let ?e1 = "(vector [1, 0])::(real^2)"
let ?e2 = "(vector [0, 1])::(real^2)"
show "?A ?O = a"
unfolding triangle_affine_def triangle_mat_def
by (metis (no_types, opaque_lifting) add.right_neutral diff_self mult_zero_right scaleR_left_diff_distrib transpose_matrix_vector vec_scaleR_2 vector_matrix_mult_0)
show "?A ?e1 = b"
proof-
have "?L ?e1 = ?M *v ?e1" unfolding triangle_linear_def by blast
also have "... = vector [1*(?M$1$1) + 0*(?M$1$2), 1*(?M$2$1) + 0*(?M$2$2)]"
unfolding triangle_linear_def triangle_mat_def
using mat_vec_mult_2 by force
also have "... = vector [1*(b - a)$1 + 0*(?M$1$2), 1*(b - a)$2 + 0*(?M$2$2)]"
unfolding triangle_mat_def transpose_def by simp
also have "... = vector [(b - a)$1, (b - a)$2]" by argo
also have "... = b - a"
by (smt (verit) exhaust_2 vec_eq_iff vector_2(1) vector_2(2))
finally show ?thesis unfolding triangle_affine_def triangle_linear_def by simp
qed
show "?A ?e2 = c"
proof-
have "?L ?e2 = ?M *v ?e2" unfolding triangle_linear_def by blast
also have "... = vector [0*(?M$1$1) + 1*(?M$1$2), 0*(?M$2$1) + 1*(?M$2$2)]"
unfolding triangle_linear_def triangle_mat_def
using mat_vec_mult_2 by force
also have "... = vector [0*(?M$1$1) + 1*(c - a)$1, 0*(?M$2$1) + 1*(c - a)$2]"
unfolding triangle_mat_def transpose_def by simp
also have "... = vector [(c - a)$1, (c - a)$2]" by argo
also have "... = c - a"
by (smt (verit) exhaust_2 vec_eq_iff vector_2(1) vector_2(2))
finally show ?thesis unfolding triangle_affine_def triangle_linear_def by simp
qed
qed
lemma triangle_measure_integral_of_det:
fixes a b c :: "real^2"
defines "S ≡ convex hull {a, b, c}"
assumes "¬ collinear {a, b, c}"
shows "measure lebesgue S =
integral unit_triangle (λ(x::real^2). abs (det (matrix (triangle_linear a b c))))"
proof-
let ?A = "triangle_affine a b c"
let ?T = "triangle_linear a b c"
have "bounded unit_triangle" by (simp add: finite_imp_bounded_convex_hull)
then have lmeasurable_S: "unit_triangle ∈ lmeasurable"
using bounded_set_imp_lmeasurable measurable_convex by blast
have "S = ?A ` unit_triangle" using S_def triangle_affine_img by blast
then have "measure lebesgue S = measure lebesgue (?A ` unit_triangle)" by blast
moreover have
"measure lebesgue (?A ` unit_triangle)
= integral unit_triangle (λ(x::real^2). abs (det (matrix ?T)))"
using measure_differentiable_image_eq_affine[OF lmeasurable_S assms(2)] by auto
ultimately show ?thesis by auto
qed
lemma triangle_affine_preserves_interior:
assumes "A = triangle_affine a b c" and "L = triangle_linear a b c"
assumes "¬ collinear {a, b, c}"
shows "A ` (interior S) = interior (A ` S)"
proof-
let ?trans = "λx::real^2. x + a"
have "linear L" by (simp add: assms(2) triangle_linear_def)
moreover have "surj L"
using triangle_linear_inj[of a b c] linear_injective_imp_surjective[of L] assms calculation
by blast
ultimately have L: "interior(L ` S) = L ` (interior S)"
using interior_surjective_linear_image by blast
moreover have "interior(?trans ` S) = ?trans ` (interior S)"
using interior_translation
by (metis (no_types, lifting) add.commute image_cong)
moreover have "A = ?trans ∘ L" using assms triangle_affine_def triangle_linear_def by fastforce
ultimately show ?thesis
by (smt (verit, del_insts) add.commute image_comp image_cong interior_translation)
qed
lemma triangle_affine_preserves_affine_hull:
assumes "A = triangle_affine a b c"
assumes "¬ collinear {a, b, c}"
shows "A ` (affine hull S) = affine hull (A ` S)"
proof-
let ?L = "triangle_linear a b c"
have "linear ?L" by (simp add: triangle_linear_def)
then have "?L ` (affine hull S) = affine hull (?L ` S)"
by (simp add: affine_hull_linear_image linear_linear)
then show ?thesis
unfolding assms(1) triangle_affine_def
by (metis affine_hull_translation image_image triangle_linear_def)
qed
lemma triangle_measure_convex_hull_measure_path_inside_same:
assumes p_triangle: "p = make_triangle a b c"
assumes elem_triangle: "elem_triangle a b c"
shows "measure lebesgue (convex hull {a, b, c}) = measure lebesgue (path_inside p)"
(is "measure lebesgue ?S = measure lebesgue ?I")
proof-
have "bounded ?S" by (simp add: finite_imp_bounded_convex_hull)
then have "measure lebesgue (frontier ?S) = measure lebesgue ?S - measure lebesgue (interior ?S)"
using measure_frontier[of ?S] by auto
then have "... = 0"
by (metis convex_convex_hull negligible_convex_frontier negligible_imp_measure0)
moreover have "?I = interior ?S"
using assms triangle_is_convex
by (metis (no_types, lifting) make_triangle_def convex_polygon_inside_is_convex_hull_interior empty_set insert_absorb2 insert_commute list.simps(15) elem_triangle_def triangle_is_polygon)
ultimately show ?thesis by auto
qed
lemma on_triangle_path_image_cases:
assumes "p = make_triangle a b c"
assumes "d ∈ path_image p"
shows "d ∈ path_image (linepath a b) ∨ d ∈ path_image (linepath b c) ∨ d ∈ path_image (linepath c a)"
using assms unfolding make_triangle_def
by (metis make_polygonal_path.simps(3) make_polygonal_path.simps(4) not_in_path_image_join)
lemma on_triangle_frontier_cases:
fixes a b c :: "real^2"
assumes "¬ collinear {a, b, c}"
assumes "d ∈ frontier (convex hull {a, b, c})"
shows "d ∈ path_image (linepath a b) ∨ d ∈ path_image (linepath b c) ∨ d ∈ path_image (linepath c a)"
proof-
let ?p = "make_triangle a b c"
have "polygon ?p" by (simp add: assms(1) triangle_is_polygon)
then have "path_image ?p = frontier (convex hull {a, b, c})"
unfolding make_triangle_def
by (smt (verit, ccfv_threshold) assms(1) convex_polygon_frontier_is_path_image2 convex_polygon_is_convex_hull empty_set insert_absorb2 insert_commute list.simps(15) make_triangle_def polygon_convex_iff sup_commute triangle_is_convex)
thus ?thesis using on_triangle_path_image_cases assms(2) by blast
qed
lemma triangle_path_image_subset_convex:
assumes "p = make_triangle a b c"
shows "path_image p ⊆ convex hull {a, b, c}"
using polygon_path_image_subset_convex polygon_at_least_3_vertices make_triangle_def
by (metis (no_types, lifting) assms empty_set insert_absorb2 insert_commute insert_iff length_pos_if_in_set list.simps(15))
lemma triangle_convex_hull:
assumes "p = make_triangle a b c" and "¬ collinear {a, b, c}"
shows "convex hull {a, b, c} = (path_image p) ∪ (path_inside p)"
using triangle_is_convex[OF assms(1) assms(2)]
by (smt (z3) Un_commute assms(1) assms(2) closure_Un_frontier convex_closure convex_polygon_is_convex_hull insert_absorb2 insert_commute inside_outside_def inside_outside_polygon list.set(1) list.set(2) make_triangle_def triangle_is_polygon)
end