Theory Polygon_Splitting
theory Polygon_Splitting
imports
"HOL-Analysis.Complete_Measure"
Polygon_Jordan_Curve
Polygon_Convex_Lemmas
begin
section "Polygon Splitting"
lemma split_up_a_list_into_3_parts:
fixes i j:: "nat"
assumes "i < length vts ∧ j < length vts ∧ i < j"
shows
"vts = (take i vts) @ ((vts ! i) # ((take (j - i - 1) (drop (Suc i) vts)) @ (vts ! j) # drop (j - i) (drop (Suc i) vts)))"
proof -
let ?x = "vts ! i"
let ?y = "vts ! j"
let ?vts1 = "(take i vts)"
let ?drop_list = "drop (Suc i) vts"
have vts_is: "vts = ?vts1 @ vts!i # drop (Suc i) vts"
using split_list assms
by (meson id_take_nth_drop)
then have len_vts1: "length ?vts1 = i"
using length_take[of i vts] assms
by auto
have gt_eq: "j - i - 1 ≥ 0"
using assms by auto
let ?ind = "j - i - 1"
have drop_is: "drop (Suc i) vts ! (j - i - 1) = ?y"
using assms by auto
then have drop_list_is: "?drop_list = take ?ind ?drop_list @ ?y # (drop (j - i) ?drop_list)"
by (metis Suc_diff_Suc Suc_leI assms diff_Suc_1 diff_less_mono id_take_nth_drop length_drop)
have "length (drop (Suc ?ind) ?drop_list) = length vts - j - 1"
using length_drop[of "Suc (j - i - 1)" "(drop (Suc i) vts)"] length_take assms
by auto
then show ?thesis
using vts_is drop_list_is len_vts1
by presburger
qed
definition is_polygon_cut :: "(real^2) list ⇒ real^2 ⇒ real^2 ⇒ bool" where
"is_polygon_cut vts x y =
(x ≠ y ∧
polygon (make_polygonal_path vts) ∧
{x, y} ⊆ set vts ∧
path_image (linepath x y) ∩ path_image (make_polygonal_path vts) = {x, y} ∧
path_image (linepath x y) ∩ path_inside (make_polygonal_path vts) ≠ {})"
definition is_polygon_cut_path :: "(real^2) list ⇒ R_to_R2 ⇒ bool" where
"is_polygon_cut_path vts cutpath =
(let x = pathstart cutpath ; y = pathfinish cutpath in
(x ≠ y ∧
polygon (make_polygonal_path vts) ∧
{x, y} ⊆ set vts ∧
simple_path cutpath ∧
path_image cutpath ∩ path_image (make_polygonal_path vts) = {x, y} ∧
path_image cutpath ∩ path_inside (make_polygonal_path vts) ≠ {}))"
definition is_polygon_split ::
"(real^2) list ⇒ nat ⇒ nat ⇒ bool" where
"is_polygon_split vts i j =
(i < length vts ∧ j < length vts ∧ i < j ∧
(let vts1 = (take i vts) in
let vts2 = (take (j - i - 1) (drop (Suc i) vts)) in
let vts3 = drop (j - i) (drop (Suc i) vts) in
let x = vts ! i in
let y = vts ! j in
let p = make_polygonal_path (vts@[vts!0]) in
let p1 = make_polygonal_path (x#(vts2@[y, x])) in
let p2 = make_polygonal_path (vts1 @ [x, y] @ vts3 @ [vts ! 0]) in
let c1 = make_polygonal_path (x#(vts2@[y])) in
let c2 = make_polygonal_path (vts1 @ [x, y] @ vts3) in
(is_polygon_cut (vts@[vts!0]) x y ∧
polygon p ∧ polygon p1 ∧ polygon p2 ∧
path_inside p1 ∩ path_inside p2 = {} ∧
path_inside p1 ∪ path_inside p2 ∪ (path_image (linepath x y) - {x, y}) = path_inside p
∧ ((path_image p1) - (path_image (linepath x y))) ∩ ((path_image p2) - (path_image (linepath x y)))
= {}
∧ path_image p
= ((path_image p1) - (path_image (linepath x y))) ∪ ((path_image p2) - (path_image (linepath x y))) ∪ {x, y}
)))"
definition is_polygon_split_path :: "(real^2) list ⇒ nat ⇒ nat ⇒ (real^2) list ⇒ bool" where
"is_polygon_split_path vts i j cutvts =
(i < length vts ∧ j < length vts ∧ i < j ∧
(let vts1 = (take i vts) in
let vts2 = (take (j - i - 1) (drop (Suc i) vts)) in
let vts3 = drop (j - i) (drop (Suc i) vts) in
let x = vts!i in
let y = vts!j in
let cutpath = make_polygonal_path (x # cutvts @ [y]) in
let p = make_polygonal_path (vts@[vts!0]) in
let p1 = make_polygonal_path (x#(vts2 @ [y] @ (rev cutvts) @ [x])) in
let p2 = make_polygonal_path (vts1 @ ([x] @ cutvts @ [y]) @ vts3 @ [vts ! 0]) in
let c1 = make_polygonal_path (x#(vts2@[y])) in
let c2 = make_polygonal_path (vts1 @ ([x] @ cutvts @ [y]) @ vts3) in
(is_polygon_cut_path (vts@[vts!0]) cutpath ∧
polygon p ∧ polygon p1 ∧ polygon p2 ∧
path_inside p1 ∩ path_inside p2 = {} ∧
path_inside p1 ∪ path_inside p2 ∪ (path_image cutpath - {x, y}) = path_inside p
∧ ((path_image p1) - (path_image cutpath)) ∩ ((path_image p2) - (path_image cutpath)) = {}
∧ path_image p
= ((path_image p1) - (path_image cutpath)) ∪ ((path_image p2) - (path_image cutpath)) ∪ {x, y}
)))"
lemma polygon_split_add_measure:
fixes p p1 p2 :: "R_to_R2"
assumes "is_polygon_split vts i j"
assumes "vts1 = (take i vts)"
"vts2 = (take (j - i - 1) (drop (Suc i) vts)) "
"vts3 = drop (j - i) (drop (Suc i) vts) "
"x = vts ! i "
"y = vts ! j "
"p = make_polygonal_path (vts@[vts!0]) "
"p1 = make_polygonal_path (x#(vts2@[y, x])) "
"p2 = make_polygonal_path (vts1 @ [x, y] @ vts3 @ [vts ! 0])"
defines "M1 ≡ measure lebesgue (path_inside p1)" and
"M2 ≡ measure lebesgue (path_inside p2)" and
"M ≡ measure lebesgue (path_inside p)"
shows "M1 + M2 = M"
proof-
let ?cut = "linepath x y"
let ?cut_open_image = "(path_image ?cut) - {x, y}"
let ?P = "path_inside p"
let ?P1 = "path_inside p1"
let ?P2 = "path_inside p2"
let ?M = "space lebesgue"
let ?A = "sets lebesgue"
let ?μ = "emeasure lebesgue"
have "open ?P1"
by (metis assms(1) assms(3) assms(5) assms(6) assms(8) closed_path_image is_polygon_split_def open_inside path_inside_def polygon_def simple_path_def)
then have P1_measurable: "?P1 ∈ ?A" by simp
have "open ?P2"
by (metis assms(1) assms(2) assms(4) assms(5) assms(6) assms(9) closed_path_image is_polygon_split_def open_inside path_inside_def polygon_def simple_path_def)
then have P2_measurable: "?P2 ∈ ?A" by simp
have "?P1 ∩ ?P2 = {}"
by (metis assms(1) assms(2) assms(3) assms(4) assms(5) assms(6) assms(8) assms(9) is_polygon_split_def)
then have sum_union_finite: "?μ ?P1 + ?μ ?P2 = ?μ (?P1 ∪ ?P2)"
using plus_emeasure P1_measurable P2_measurable by blast
have "measure lebesgue ?P1 = ?μ ?P1"
by (metis assms(1) assms(3) assms(5) assms(6) assms(8) bounded_inside bounded_set_imp_lmeasurable bounded_simple_path_image emeasure_eq_ennreal_measure emeasure_notin_sets ennreal_0 fmeasurableD2 is_polygon_split_def measure_zero_top path_inside_def polygon_def)
moreover have "measure lebesgue ?P2 = ?μ ?P2"
by (metis Sigma_Algebra.measure_def assms(1) assms(2) assms(4) assms(5) assms(6) assms(9) bounded_inside bounded_path_image bounded_set_imp_lmeasurable emeasure_eq_ennreal_measure emeasure_notin_sets enn2real_top ennreal_0 fmeasurableD2 is_polygon_split_def path_inside_def polygon_def simple_path_def)
ultimately have "?μ (?P1 ∪ ?P2) = M1 + M2"
using assms(10) assms(11) sum_union_finite by auto
moreover have "?μ (?P1 ∪ ?P2) = ?μ ?P"
proof-
have "?μ (path_image ?cut) = 0" using linepath_has_emeasure_0 by blast
then have "(path_image ?cut) ∈ null_sets lebesgue" by auto
moreover have "{x, y} ∈ null_sets lebesgue" by simp
ultimately have "?cut_open_image ∈ null_sets lebesgue" using measure_Diff_null_set by auto
moreover have "?P = ?P1 ∪ ?P2 ∪ ?cut_open_image"
by (metis assms(1) assms(2) assms(3) assms(4) assms(5) assms(6) assms(7) assms(8) assms(9) is_polygon_split_def)
ultimately show ?thesis
by (simp add: P1_measurable P2_measurable emeasure_Un_null_set sets.Un)
qed
ultimately show ?thesis
by (smt (verit, best) M1_def M2_def M_def emeasure_eq_ennreal_measure enn2real_ennreal ennreal_neq_top measure_nonneg)
qed
lemma polygonal_paths_measurable:
shows "path_image (make_polygonal_path vts) ∈ sets lebesgue"
proof (induct vts rule: make_polygonal_path_induct)
case (Empty ell)
then show ?case by auto
next
case (Single ell)
then obtain a where "ell = [a]"
by (metis Cons_nth_drop_Suc One_nat_def drop0 drop_eq_Nil le_numeral_extra(4) zero_less_one)
then show ?case using make_polygonal_path.simps(2)[of a] by simp
next
case (Two ell)
then obtain a b where "ell = [a, b]"
by (metis Cons_nth_drop_Suc One_nat_def Suc_1 append_Nil drop_eq_Nil2 dual_order.refl id_take_nth_drop lessI pos2 take0)
then show ?case using make_polygonal_path.simps(3)[of a b] by simp
next
case (Multiple ell)
then have "ell = (ell ! 0) # (ell ! 1) # (ell ! 2) # (drop 3 ell)"
by (metis Cons_nth_drop_Suc One_nat_def Suc_1 drop0 le_Suc_eq linorder_not_less numeral_3_eq_3)
then have "make_polygonal_path ell =
linepath (ell ! 0) (ell ! 1) +++ make_polygonal_path (ell ! 1 # ell ! 2 # (drop 3 ell))"
by (metis make_polygonal_path.simps(4))
then have "path_image (make_polygonal_path ell) = path_image (linepath (ell ! 0) (ell ! 1)) ∪ path_image (make_polygonal_path (ell ! 1 # ell ! 2 # (drop 2 ell)))"
using Cons_nth_drop_Suc Multiple.hyps(1) One_nat_def Suc_1 Un_assoc ‹ell = ell ! 0 # ell ! 1 # ell ! 2 # drop 3 ell› list.discI make_polygonal_path.simps(2) make_polygonal_path.simps(3) nth_Cons_0 numeral_3_eq_3 path_image_cons_union
proof-
have f1: "ell = ell ! 0 # ell ! 1 # ell ! Suc 1 # drop 3 ell"
using Suc_1 ‹ell = ell ! 0 # ell ! 1 # ell ! 2 # drop 3 ell› by presburger
have "Suc 1 < length ell"
by (smt (z3) Suc_1 ‹2 < length ell›)
then have f2: "drop (Suc 1) ell = ell ! Suc 1 # drop (Suc (Suc 1)) ell"
by (smt (z3) Cons_nth_drop_Suc)
have f3: "∀v va vs. path_image (make_polygonal_path (v # va # vs)) = path_image (linepath v va) ∪ path_image (make_polygonal_path (va # vs))"
by (metis (no_types) list.discI nth_Cons_0 path_image_cons_union)
have f4: "∀V v va. path_image (linepath (v::(real, 2) vec) va) ∪ (path_image (linepath va va) ∪ V) = path_image (linepath v va) ∪ V"
by auto
have "path_image (make_polygonal_path ell) = path_image (make_polygonal_path (ell ! 0 # ell ! 1 # drop (Suc 1) ell))"
using f2 f1 by (simp add: numeral_3_eq_3)
then have "path_image (make_polygonal_path ell) = path_image (linepath (ell ! 0) (ell ! 1)) ∪ path_image (make_polygonal_path (ell ! 1 # ell ! Suc 1 # drop (Suc 1) ell))"
using f4 f3 f2 by presburger
then show ?thesis
using Suc_1 by presburger
qed
then show ?case using Multiple(3)
by (metis (no_types, lifting) Cons_nth_drop_Suc Multiple.hyps(1) Multiple.hyps(2) One_nat_def Suc_1 ‹ell = ell ! 0 # ell ! 1 # ell ! 2 # drop 3 ell› list.discI make_polygonal_path.simps(3) nth_Cons_0 numeral_3_eq_3 path_image_cons_union sets.Un)
qed
lemma polygonal_path_has_emeasure_0:
shows "emeasure lebesgue (path_image (make_polygonal_path vts)) = 0"
proof (induct vts)
case Nil
then show ?case by auto
next
case (Cons a vts)
then show ?case
by (metis linepath_is_negligible make_polygonal_path.simps(2) negligible_Un negligible_iff_emeasure0 path_image_cons_union polygonal_paths_measurable)
qed
lemma polygon_split_path_add_measure:
fixes p p1 p2 :: "R_to_R2"
assumes "is_polygon_split_path vts i j cutvts"
assumes "vts1 = (take i vts)"
"vts2 = (take (j - i - 1) (drop (Suc i) vts)) "
"vts3 = drop (j - i) (drop (Suc i) vts) "
"x = vts ! i "
"y = vts ! j "
"p = make_polygonal_path (vts@[vts!0])"
"p1 = make_polygonal_path (x#(vts2 @ [y] @ (rev cutvts) @ [x]))"
"p2 = make_polygonal_path (vts1 @ ([x] @ cutvts @ [y]) @ vts3 @ [vts ! 0])"
defines "M1 ≡ measure lebesgue (path_inside p1)" and
"M2 ≡ measure lebesgue (path_inside p2)" and
"M ≡ measure lebesgue (path_inside p)"
shows "M1 + M2 = M"
proof-
let ?cut = "make_polygonal_path (x # cutvts @ [y])"
let ?cut_open_image = "(path_image ?cut) - {x, y}"
let ?P = "path_inside p"
let ?P1 = "path_inside p1"
let ?P2 = "path_inside p2"
let ?M = "space lebesgue"
let ?A = "sets lebesgue"
let ?μ = "emeasure lebesgue"
have "open ?P1"
by (metis assms(1) assms(3) assms(5) assms(6) assms(8) closed_path_image is_polygon_split_path_def open_inside path_inside_def polygon_def simple_path_def)
then have P1_measurable: "?P1 ∈ ?A" by simp
have "open ?P2"
by (metis assms(1) assms(2) assms(4) assms(5) assms(6) assms(9) closed_path_image is_polygon_split_path_def open_inside path_inside_def polygon_def simple_path_def)
then have P2_measurable: "?P2 ∈ ?A" by simp
have "?P1 ∩ ?P2 = {}"
by (metis assms(1) assms(2) assms(3) assms(4) assms(5) assms(6) assms(8) assms(9) is_polygon_split_path_def)
then have sum_union_finite: "?μ ?P1 + ?μ ?P2 = ?μ (?P1 ∪ ?P2)"
using plus_emeasure P1_measurable P2_measurable by blast
have "?μ (path_image q) = 0 ⟹ (path_image q) ∈ null_sets lebesgue" if *: "path_image q ∈ sets lebesgue" for q::"real ⇒ (real, 2) vec"
using null_sets_def * by blast
have "measure lebesgue ?P1 = ?μ ?P1"
by (metis assms(1) assms(3) assms(5) assms(6) assms(8) bounded_inside bounded_set_imp_lmeasurable bounded_simple_path_image emeasure_eq_ennreal_measure emeasure_notin_sets ennreal_0 fmeasurableD2 is_polygon_split_path_def measure_zero_top path_inside_def polygon_def)
moreover have "measure lebesgue ?P2 = ?μ ?P2"
by (metis Sigma_Algebra.measure_def assms(1) assms(2) assms(4) assms(5) assms(6) assms(9) bounded_inside bounded_path_image bounded_set_imp_lmeasurable emeasure_eq_ennreal_measure emeasure_notin_sets enn2real_top ennreal_0 fmeasurableD2 is_polygon_split_path_def path_inside_def polygon_def simple_path_def)
ultimately have "?μ (?P1 ∪ ?P2) = M1 + M2"
using assms(10) assms(11) sum_union_finite by auto
moreover have "?μ (?P1 ∪ ?P2) = ?μ ?P"
proof-
have "?μ (path_image ?cut) = 0" using polygonal_path_has_emeasure_0
by presburger
then have "(path_image ?cut) ∈ null_sets lebesgue" using polygonal_paths_measurable
by blast
moreover have "{x, y} ∈ null_sets lebesgue" by simp
ultimately have "?cut_open_image ∈ null_sets lebesgue" using measure_Diff_null_set by auto
moreover have "?P = ?P1 ∪ ?P2 ∪ ?cut_open_image"
by (metis assms(1) assms(2) assms(3) assms(4) assms(5) assms(6) assms(7) assms(8) assms(9) is_polygon_split_path_def)
ultimately show ?thesis
by (simp add: P1_measurable P2_measurable emeasure_Un_null_set sets.Un)
qed
ultimately show ?thesis
by (smt (verit, best) M1_def M2_def M_def emeasure_eq_ennreal_measure enn2real_ennreal ennreal_neq_top measure_nonneg)
qed
lemma polygon_cut_path_to_split_path_vtx0:
fixes p :: "R_to_R2"
assumes polygon_p: "polygon p" and
i_gt: "i > 0" and
i_lt: "i < length vts" and
p_is: "p = make_polygonal_path (vts @ [vts ! 0])" and
cutpath: "cutpath = make_polygonal_path ([vts!0] @ cutvts @ [vts!i])" and
have_cut: "is_polygon_cut_path (vts @ [vts!0]) cutpath"
shows "is_polygon_split_path vts 0 i cutvts"
proof -
let ?vts2 = "take (i - 1) (drop 1 vts)"
let ?vts3 = "drop i (drop 1 vts)"
let ?x = "vts ! 0"
let ?y = "vts ! i"
let ?c3_vts = "[?x] @ cutvts @ [?y]"
let ?c3 = "cutpath"
let ?c3_rev_vts = "rev ?c3_vts"
let ?c3_rev = "make_polygonal_path ?c3_rev_vts"
let ?c3' = "reversepath ?c3"
let ?p = "make_polygonal_path (vts @ [vts ! 0])"
let ?p1_vts = "?x # ?vts2 @ ?c3_rev_vts"
let ?p1 = "make_polygonal_path ?p1_vts"
let ?p1_rot_vts = "?c3_rev_vts @ ?vts2 @ [?y]"
let ?p1_rot = "make_polygonal_path ?p1_rot_vts"
let ?p2_vts = "?c3_vts @ ?vts3 @ [?x]"
let ?p2 = "make_polygonal_path ?p2_vts"
let ?c1_vts = "?x # ?vts2 @ [?y]"
let ?c1 = "make_polygonal_path ?c1_vts"
let ?c2_vts = "[?y] @ ?vts3 @ [?x]"
let ?c2 = "reversepath (make_polygonal_path ?c2_vts)"
let ?c2'_vts = "[?y] @ ?vts3 @ [?x]"
let ?c2' = "(make_polygonal_path (?c2'_vts))"
have distinct_vts: "distinct vts"
using polygon_p p_is
using polygon_def simple_polygonal_path_vts_distinct by force
have len_vts_gteq3: "length vts ≥ 3"
using polygon_p p_is polygon_vertices_length_at_least_4 by fastforce
then have "?x # ?vts2 @ [?y] = take (i+1) (vts@ [vts ! 0])"
by (smt (verit, ccfv_threshold) i_gt Cons_nth_drop_Suc Suc_eq_plus1 Suc_pred' add_less_cancel_left butlast_snoc drop0 drop_drop hd_drop_conv_nth i_lt length_append_singleton length_greater_0_conv less_imp_le_nat linorder_not_less list.size(3) plus_1_eq_Suc take_Suc_Cons take_all_iff take_butlast take_hd_drop)
have "[?y] @ ?vts3 @ [?x] = drop (i) (vts @ [vts ! 0])"
using i_gt
by (metis (no_types, lifting) Cons_eq_appendI Cons_nth_drop_Suc Suc_eq_plus1 append_Nil diff_is_0_eq' drop_0 drop_append drop_drop i_lt less_imp_le_nat)
have card_gteq: "card (set vts) ≥ 3"
using polygon_at_least_3_vertices_wraparound polygon_p p_is
by (metis butlast_conv_take butlast_snoc)
then have "vts ≠ []"
by auto
then have vts_is: "vts = ?x # ?vts2 @ ?y # ?vts3"
using split_up_a_list_into_3_parts[of 0 vts i] i_gt i_lt
by auto
have elem_prop1: "last ?c1_vts = ?y"
by (metis (no_types, lifting) last.simps snoc_eq_iff_butlast)
have elem_prop2: "(vts ! 0 # (rev ?vts3) @ [vts ! i]) !
(length (vts ! 0 # drop i (drop 1 vts) @ [vts ! i]) - 1) = vts ! i"
by (metis diff_Suc_1 length_Cons length_append_singleton length_rev nth_Cons_Suc nth_append_length)
have "path_image cutpath = path_image ?c3'" by simp
then have "path_image ?p1 = path_image (?c1 +++ ?c3_rev)"
using elem_prop1 assms make_polygonal_path_image_append_alt[of ?p1 ?p1_vts ?c1 ?c1_vts ?c3_rev ?c3_rev_vts]
by simp
also have "... = path_image ?c1 ∪ path_image ?c3_rev"
by (metis (no_types, opaque_lifting) append_Cons append_Nil elem_prop1 hd_conv_nth last_conv_nth list.discI list.sel(1) path_image_join polygon_pathfinish polygon_pathstart rev.simps(2) rev_rev_ident)
finally have image_prop: "path_image ?p1 = path_image ?c1 ∪ path_image cutpath"
using rev_vts_path_image cutpath by presburger
have "path_image ?c3' = path_image ?c3"
using cutpath rev_vts_path_image by force
then have path_image_p1: "path_image ?c1 ∪ path_image ?c3 = path_image ?p1"
using image_prop by presburger
have "?p2_vts = ?c3_vts @ (tl ?c2_vts)" by simp
then have "path_image ?p2 = path_image (?c3 +++ ?c2')"
using make_polygonal_path_image_append_alt[of ?p2 ?p2_vts ?c3 ?c3_vts ?c2' ?c2_vts]
unfolding assms by auto
then have path_image_p2: "path_image ?c2 ∪ path_image ?c3 = path_image ?p2"
by (metis (no_types, opaque_lifting) Un_commute append_Cons append_Nil cutpath last_conv_nth nth_Cons_0 path_image_join path_image_reversepath polygon_pathfinish polygon_pathstart snoc_eq_iff_butlast)
have "drop 1 vts = take (i - 1) (drop 1 vts) @ [vts ! i] @ drop i (drop 1 vts)"
by (metis (no_types, lifting) Cons_eq_appendI Cons_nth_drop_Suc Suc_eq_plus1 Suc_pred' append.simps(1) append_take_drop_id drop_drop i_gt i_lt)
then have vts_is: "vts @ [vts ! 0] = vts ! 0 # take (i - 1) (drop 1 vts) @ [vts ! i] @ drop i (drop 1 vts) @ [vts ! 0]"
by (metis (no_types, opaque_lifting) Cons_nth_drop_Suc One_nat_def append.assoc append_Cons drop0 i_lt length_pos_if_in_set nth_mem)
let ?vts1' = "take (i - 1) (drop 1 vts)"
let ?vts2' = "drop i (drop 1 vts)"
have path_im_p: "path_image
(make_polygonal_path
((vts ! 0 # ?vts1') @ [vts ! i] @ [vts ! i] @ ?vts2' @ [vts ! 0])) =
path_image
(make_polygonal_path
((vts ! 0 # ?vts1') @ [vts ! i] @ ?vts2' @ [vts ! 0]))"
using make_polygonal_path_image_append_helper[of " vts ! 0 # ?vts1'" "?vts2' @ [vts ! 0]"] by auto
have "path_image
(make_polygonal_path
((vts ! 0 # ?vts1') @ [vts ! i] @ [vts ! i] @ ?vts2' @ [vts ! 0])) = path_image (make_polygonal_path ((vts ! 0 # ?vts1') @ [vts ! i]) +++ (linepath (vts ! i) (vts ! i)) +++ make_polygonal_path ([vts ! i] @ ?vts2' @ [vts ! 0]))"
using make_polygonal_path_image_append[of "(vts ! 0 # ?vts1') @ [vts ! i]" "[vts ! i] @ ?vts2' @ [vts ! 0]"]
by (smt (verit) add_2_eq_Suc' append.assoc append_Cons diff_Suc_1 le_add2 length_Cons length_append_singleton nth_Cons_0 nth_append_length)
then have "path_image p = path_image (make_polygonal_path ((vts ! 0 # ?vts1') @ [vts ! i]) +++ (linepath (vts ! i) (vts ! i)) +++ make_polygonal_path ([vts ! i] @ ?vts2' @ [vts ! 0]))"
using path_im_p p_is vts_is
by simp
then have "path_image p = path_image ?c1 ∪ path_image (linepath (vts ! i) (vts ! i)) ∪ path_image (make_polygonal_path ([vts ! i] @ ?vts2' @ [vts ! 0]))"
by (metis (no_types, lifting) Un_assoc append_Cons elem_prop1 list.discI nth_Cons_0 path_image_join pathfinish_linepath pathstart_join pathstart_linepath polygon_pathfinish polygon_pathstart last_conv_nth)
moreover have "... = path_image ?c1 ∪ {vts ! i} ∪ path_image (make_polygonal_path ([vts ! i] @ ?vts2' @ [vts ! 0]))"
by auto
moreover have "... = path_image ?c1 ∪ path_image (make_polygonal_path ([vts ! i] @ ?vts2' @ [vts ! 0]))"
using vertices_on_path_image by fastforce
ultimately have path_image_p: "path_image p = path_image ?c1 ∪ path_image ?c2"
using path_image_reversepath by blast
have simple_path_polygon: "simple_path (make_polygonal_path (?x # ?vts2 @ ?y # ?vts3 @ [?x]))"
using polygon_p p_is vts_is
using Cons_eq_appendI append_self_conv2 polygon_def by auto
then have loop_free_polygon: "loop_free (make_polygonal_path (?x # ?vts2 @ ?y # ?vts3 @ [?x]))"
unfolding simple_path_def by auto
have loop_free_p: "loop_free p"
using polygon_p p_is unfolding polygon_def simple_path_def by auto
have sublist_c1: "sublist (?x # ?vts2 @ [?y]) vts"
using ‹vts ! 0 # take (i - 1) (drop 1 vts) @ [vts ! i] = take (i + 1) (vts @ [vts ! 0])› i_lt by auto
then have sublist_c1: "sublist (?x # ?vts2 @ [?y]) (vts@[vts !0])"
by (metis ‹vts ! 0 # take (i - 1) (drop 1 vts) @ [vts ! i] = take (i + 1) (vts @ [vts ! 0])› sublist_take)
then have "loop_free ?c1"
using sublist_is_loop_free p_is loop_free_p sublist_c1
by (metis One_nat_def Suc_1 Suc_eq_plus1 Suc_leI Suc_le_mono ‹vts ! 0 # take (i - 1) (drop 1 vts) @ [vts ! i] = take (i + 1) (vts @ [vts ! 0])› i_gt i_lt length_append_singleton less_imp_le_nat take_i_is_loop_free)
then have simple_c1: "simple_path ?c1"
unfolding simple_path_def
using make_polygonal_path_gives_path by blast
have start_c1: "pathstart ?c1 = ?x"
using polygon_pathstart
by (metis Cons_eq_appendI list.discI nth_Cons_0 )
have finish_c1: "pathfinish ?c1 = ?y"
using polygon_pathfinish
by (metis Cons_eq_appendI diff_Suc_1 length_append_singleton list.discI nth_append_length)
have sublist_c2: "sublist ([?y] @ ?vts3 @ [?x]) (vts@[vts !0])"
by (metis ‹[vts ! i] @ drop i (drop 1 vts) @ [vts ! 0] = drop i (vts @ [vts ! 0])› sublist_drop)
have "i ≤ length (tl vts)" using i_lt by fastforce
then have "loop_free ?c2"
by (metis (no_types) Suc_1 ‹[vts ! i] @ drop i (drop 1 vts) @ [vts ! 0] = drop i (vts @ [vts ! 0])› ‹vts ≠ []› butlast_snoc drop_Suc drop_i_is_loop_free length_butlast length_drop loop_free_p loop_free_reversepath p_is tl_append2)
then have simple_c2: "simple_path ?c2"
unfolding simple_path_def
using make_polygonal_path_gives_path
using path_imp_reversepath by blast
have start_c2: "pathstart ?c2 = ?x"
using polygon_pathfinish
by (metis (no_types, lifting) Nil_is_append_conv last_appendR last_conv_nth pathstart_reversepath polygon_pathfinish snoc_eq_iff_butlast)
have finish_c2: "pathfinish ?c2 = ?y"
using polygon_pathstart by auto
have path_image_int: "path_image ?c1 ⊆ path_image ?p"
unfolding path_image_def
by (metis Un_upper1 p_is path_image_def path_image_p)
moreover have "path_image ?p ∩ path_image ?c3 ⊆ {vts ! 0, vts ! i}"
using have_cut unfolding is_polygon_cut_path_def
by (metis (no_types, lifting) Int_commute append_Cons append_is_Nil_conv cutpath last_appendR last_conv_nth last_snoc not_Cons_self2 nth_Cons_0 polygon_pathfinish polygon_pathstart set_eq_subset)
ultimately have vts_subset_c1c3: "path_image ?c1 ∩ path_image ?c3 ⊆ {?x, ?y}"
by blast
have other_subset1: "{vts ! 0, vts ! i} ⊆ path_image ?c1"
using vertices_on_path_image by fastforce
have other_subset2: "{vts ! 0, vts ! i} ⊆ path_image ?c3"
unfolding assms using vertices_on_path_image by force
then have c1_inter_c3: "path_image ?c1 ∩ path_image ?c3 = {vts ! 0, vts ! i}"
using vts_subset_c1c3 other_subset1 other_subset2 by blast
then have "path_image ?c1 ∩ path_image ?c3_rev = {pathstart ?c1, pathstart ?c3_rev}"
by (metis rev_vts_path_image append_Cons append_Nil cutpath hd_conv_nth list.discI list.sel(1) polygon_pathstart rev.simps(2) rev_rev_ident)
then have c1_inter_c3': "path_image (make_polygonal_path (vts ! 0 # take (i - 1) (drop 1 vts) @ [vts ! i])) ∩
path_image (make_polygonal_path (rev ([vts ! 0] @ cutvts @ [vts ! i])))
⊆ {pathstart (make_polygonal_path (vts ! 0 # take (i - 1) (drop 1 vts) @ [vts ! i])),
pathstart (make_polygonal_path (rev ([vts ! 0] @ cutvts @ [vts ! i])))}"
by blast
have last_is_head: "last ?c3_rev_vts = hd ?c1_vts" by auto
have vts_append: "vts ! 0 # take (i - 1) (drop 1 vts) @ rev ([vts ! 0] @ cutvts @ [vts ! i]) =
(vts ! 0 # take (i - 1) (drop 1 vts) @ [vts ! i]) @
tl (rev ([vts ! 0] @ cutvts @ [vts ! i]))"
by simp
have loop_free: "loop_free (make_polygonal_path (vts ! 0 # take (i - 1) (drop 1 vts) @ [vts ! i])) ∧
loop_free (make_polygonal_path (rev ([vts ! 0] @ cutvts @ [vts ! i])))"
by (metis Suc_eq_plus1 Suc_le_mono Zero_neq_Suc ‹vts ! 0 # take (i - 1) (drop 1 vts) @ [vts ! i] = take (i + 1) (vts @ [vts ! 0])› cutpath diff_Suc_1 have_cut i_gt i_lt is_polygon_cut_path_def length_append_singleton less_2_cases less_imp_le_nat less_nat_zero_code linorder_le_less_linear loop_free_p p_is rev_vts_is_loop_free simple_path_def take_i_is_loop_free)
have last_is_head2:
"last (vts ! 0 # take (i - 1) (drop 1 vts) @ [vts ! i]) =
hd (rev ([vts ! 0] @ cutvts @ [vts ! i]))" by simp
have arcs: "arc (make_polygonal_path (vts ! 0 # take (i - 1) (drop 1 vts) @ [vts ! i])) ∧
arc (make_polygonal_path (rev ([vts ! 0] @ cutvts @ [vts ! i])))"
using Nil_is_append_conv append_Cons constant_linepath_is_not_loop_free cutpath finish_c1 have_cut hd_conv_nth is_polygon_cut_path_def last_appendR last_conv_nth last_is_head last_is_head2 last_snoc list.sel(1) loop_free make_polygonal_path.simps(1) make_polygonal_path_gives_path polygon_pathfinish polygon_pathstart simple_path_def simple_path_imp_arc loop_free
by (smt (verit, ccfv_SIG))
then have "loop_free ?p1"
using loop_free_append[of ?p1 ?p1_vts ?c1 ?c1_vts ?c3_rev ?c3_rev_vts,
OF _ _ _ vts_append loop_free c1_inter_c3' _ last_is_head2 arcs] using last_is_head by blast
then have "simple_path ?p1"
unfolding simple_path_def
using make_polygonal_path_gives_path by blast
moreover have "closed_path ?p1"
using polygon_pathstart polygon_pathfinish
unfolding closed_path_def
using elem_prop1 make_polygonal_path_gives_path
by (smt (verit, best) append_is_Nil_conv last_ConsR last_appendR last_conv_nth last_snoc list.discI nth_Cons_0 rev_append singleton_rev_conv)
ultimately have polygon_p1: "polygon ?p1" unfolding polygon_def polygonal_path_def by fastforce
have path_image_int: "path_image ?c2 ⊆ path_image (make_polygonal_path (vts @ [vts ! 0]))"
unfolding path_image_def using path_image_p
by (simp add: p_is path_image_def)
then have vts_subset_c2c3: "path_image ?c2 ∩ path_image ?c3 ⊆ {?x, ?y}"
using have_cut unfolding is_polygon_cut_path_def using ‹path_image (make_polygonal_path (vts @ [vts ! 0])) ∩ path_image cutpath ⊆ {vts ! 0, vts ! i}› by auto
have other_subset3: "{vts ! 0, vts ! i} ⊆ path_image ?c2"
using vertices_on_path_image by fastforce
have other_subset4: "{vts ! 0, vts ! i} ⊆ path_image ?c3"
unfolding assms using vertices_on_path_image by fastforce
have c2_inter_c3: "path_image ?c2 ∩ path_image ?c3 = {vts ! 0, vts ! i}"
using vts_subset_c2c3 other_subset3 other_subset4 by blast
have path_p2: "path ?p2"
using make_polygonal_path_gives_path by blast
have "pathfinish ?p2 = vts ! 0"
using polygon_pathfinish
by (metis Nil_is_append_conv last_appendR last_conv_nth last_snoc list.discI)
then have closed_p2: "closed_path ?p2"
unfolding closed_path_def using polygon_pathstart
using path_p2 by auto
have "([vts ! 0] @ cutvts @ [vts ! i]) @ drop i (drop 1 vts) @ [vts ! 0] =
([vts ! 0] @ cutvts @ [vts ! i]) @ tl ([vts ! i] @ drop i (drop 1 vts) @ [vts ! 0])" by force
moreover have "loop_free cutpath ∧
loop_free (make_polygonal_path ([vts ! i] @ drop i (drop 1 vts) @ [vts ! 0]))"
by (metis ‹loop_free (reversepath (make_polygonal_path ([vts ! i] @ drop i (drop 1 vts) @ [vts ! 0])))› cutpath loop_free loop_free_reversepath rev_rev_ident rev_vts_is_loop_free reversepath_reversepath)
moreover have "path_image cutpath ∩ path_image (make_polygonal_path ([vts ! i] @ drop i (drop 1 vts) @ [vts ! 0]))
⊆ {pathstart cutpath,
pathstart (make_polygonal_path ([vts ! i] @ drop i (drop 1 vts) @ [vts ! 0]))}"
using c2_inter_c3 cutpath polygon_pathstart by auto
moreover have "last ([vts ! i] @ drop i (drop 1 vts) @ [vts ! 0]) ≠ hd ([vts ! 0] @ cutvts @ [vts ! i]) ⟶
path_image cutpath ∩ path_image (make_polygonal_path ([vts ! i] @ drop i (drop 1 vts) @ [vts ! 0]))
⊆ {pathstart (make_polygonal_path ([vts ! i] @ drop i (drop 1 vts) @ [vts ! 0]))}"
by simp
moreover have "last ([vts ! 0] @ cutvts @ [vts ! i]) = hd ([vts ! i] @ drop i (drop 1 vts) @ [vts ! 0])"
by simp
moreover have "arc cutpath ∧ arc (make_polygonal_path ([vts ! i] @ drop i (drop 1 vts) @ [vts ! 0]))"
by (metis (no_types, lifting) arc_simple_path arcs calculation(2) finish_c1 finish_c2 have_cut is_polygon_cut_path_def make_polygonal_path_gives_path pathfinish_reversepath pathstart_reversepath simple_path_def start_c1 start_c2)
ultimately have "loop_free ?p2"
using loop_free_append[of ?p2 ?p2_vts ?c3 ?c3_vts ?c2' ?c2'_vts,
OF _ _ _] using cutpath by blast
then have polygon_p2: "polygon ?p2"
using path_p2 closed_p2 unfolding polygon_def simple_path_def polygonal_path_def
by blast
have simple_c3: "simple_path ?c3"
using have_cut unfolding is_polygon_cut_path_def by meson
have start_c3: "pathstart ?c3 = ?x" unfolding assms using polygon_pathstart by simp
have finish_c3: "pathfinish ?c3 = ?y" unfolding assms using polygon_pathfinish by simp
have "pathstart cutpath = ?x" using assms polygon_pathstart by force
moreover have "pathfinish cutpath = ?y" using assms polygon_pathfinish by simp
ultimately have vts_neq: "vts ! 0 ≠ vts ! i"
using have_cut unfolding is_polygon_cut_path_def by force
have c1_inter_c2: "path_image ?c1 ∩ path_image ?c2 = {vts ! 0, vts ! i}"
proof-
obtain i where i1: "(?x # ?vts2 @ [?y] = take i (vts @ [vts!0]))" and
i2: "([?y] @ ?vts3 @ [?x] = drop (i-1) (vts @ [vts!0]))"
by (metis ‹[vts ! i] @ drop i (drop 1 vts) @ [vts ! 0] = drop i (vts @ [vts ! 0])› ‹vts ! 0 # take (i - 1) (drop 1 vts) @ [vts ! i] = take (i + 1) (vts @ [vts ! 0])› add.commute add_diff_cancel_left')
moreover have 1: "i ≥ 1 ∧ i < length (vts @ [vts!0])"
by (metis (no_types, lifting) bot_nat_0.extremum less_one Nil_is_append_conv append_Cons calculation diff_is_0_eq drop_Cons' linorder_not_less list.inject not_Cons_self2 same_append_eq take_all vts_is vts_neq)
moreover have 2: "?p = make_polygonal_path (vts @ [vts!0]) ∧ loop_free ?p"
unfolding polygon_of_def using p_is polygon_p unfolding polygon_def simple_path_def by blast
ultimately have "path_image ?c1 ∩ path_image (make_polygonal_path ([?y] @ ?vts3 @ [?x])) ⊆ {pathstart ?c1, pathstart (make_polygonal_path ([?y] @ ?vts3 @ [?x]))}"
using loop_free_split_int[of ?p "vts @ [vts!0]" "?x # ?vts2 @ [?y]" i "[?y] @ ?vts3 @ [?x]" ?c1 "make_polygonal_path ([?y] @ ?vts3 @ [?x])" "length (vts @ [vts!0])",
OF 2 i1 i2 _ _ _ 1]
by presburger
moreover have "path_image ?c2 = path_image (make_polygonal_path ([?y] @ ?vts3 @ [?x]))" using path_image_reversepath by fast
moreover have "pathstart (make_polygonal_path ([?y] @ ?vts3 @ [?x])) = ?y" using polygon_pathstart by auto
moreover have "pathstart ?c1 = ?x" using polygon_pathstart by auto
ultimately show ?thesis
using other_subset1 other_subset3 subset_antisym by force
qed
have non_empty_inter: "path_image ?c3 ∩ inside(path_image ?c1 ∪ path_image ?c2) ≠ {}"
using have_cut path_image_p p_is
unfolding is_polygon_cut_path_def path_inside_def
by fastforce
have p1_minus: "((path_image ?p1) - (path_image ?c3)) = path_image ?c1 - {?x, ?y}"
using c1_inter_c3 path_image_p1 by blast
have p2_minus: "((path_image ?p2) - (path_image ?c3)) = path_image ?c2 - {?x, ?y}"
using c2_inter_c3 path_image_p2 by auto
then have path_im_intersect_minus: "((path_image ?p1) - (path_image ?c3)) ∩ ((path_image ?p2) - (path_image (linepath ?x ?y))) = {}"
using c1_inter_c2 p1_minus p2_minus
by blast
have "((path_image ?p1) - (path_image ?c3)) ∪ ((path_image ?p2) - (path_image ?c3)) ∪ {?x, ?y} = ((path_image ?p1) - (path_image ?c3) ∪ {?x, ?y}) ∪ ((path_image ?p2) - (path_image ?c3) ∪ {?x, ?y})"
by auto
then have "((path_image ?p1) - (path_image (?c3))) ∪ ((path_image ?p2) - (path_image (?c3))) ∪ {?x, ?y} = ((path_image ?c1) - {?x, ?y} ∪ {?x, ?y}) ∪ ((path_image ?c2) - {?x, ?y} ∪ {?x, ?y})"
using p1_minus p2_minus by simp
then have "((path_image ?p1) - (path_image (?c3))) ∪ ((path_image ?p2) - (path_image (?c3))) ∪ {?x, ?y} = path_image ?c1 ∪ path_image ?c2"
using other_subset1 other_subset3 by auto
then have path_im_intersect_union: "path_image ?p = ((path_image ?p1) - (path_image (?c3))) ∪ ((path_image ?p2) - (path_image (?c3))) ∪ {?x, ?y}"
using path_image_p p_is by auto
have "inside(path_image ?c1 ∪ path_image ?c3) ∩ inside(path_image ?c2 ∪ path_image ?c3) = {}"
using split_inside_simple_closed_curve_real2[OF simple_c1 start_c1 finish_c1 simple_c2 start_c2 finish_c2
simple_c3 start_c3 finish_c3 vts_neq c1_inter_c2 c1_inter_c3 c2_inter_c3 non_empty_inter]
by fast
then have empty_inter: "path_inside ?p1 ∩ path_inside ?p2 = {}"
using path_image_p1 path_image_p2 unfolding path_inside_def
by force
have "inside(path_image ?c1 ∪ path_image ?c3) ∪ inside(path_image ?c2 ∪ path_image ?c3) ∪
(path_image ?c3 - {vts ! 0, vts ! i}) = inside(path_image ?c1 ∪ path_image ?c2)"
using split_inside_simple_closed_curve_real2[OF simple_c1 start_c1 finish_c1 simple_c2 start_c2 finish_c2
simple_c3 start_c3 finish_c3 vts_neq c1_inter_c2 c1_inter_c3 c2_inter_c3 non_empty_inter]
by fast
then have inside: "path_inside ?p1 ∪ path_inside ?p2 ∪ (path_image ?c3 - {?x, ?y}) = path_inside p"
using path_image_p1 path_image_p1 path_image_p unfolding path_inside_def
by (smt (z3) Diff_cancel Int_Un_distrib2 c1_inter_c2 c1_inter_c3 finish_c1 inf_commute inf_sup_absorb nonempty_simple_path_endless path_image_p2 simple_c1 start_c1)
have first_part: "0 < length vts ∧
i < length vts ∧
0 < i"
using assms
by auto
have second_part_helper: "is_polygon_cut_path (vts @ [vts ! 0]) cutpath ∧
polygon ?p ∧
polygon ?p1 ∧
polygon ?p2 ∧
path_inside ?p1 ∩ path_inside ?p2 = {} ∧
path_inside ?p1 ∪ path_inside ?p2 ∪ (path_image (?c3) - {?x, ?y}) = path_inside p
∧ ((path_image ?p1) - (path_image (?c3))) ∩ ((path_image ?p2) - (path_image (?c3))) = {}
∧ path_image ?p = ((path_image ?p1) - (path_image (?c3))) ∪ ((path_image ?p2) - (path_image (?c3))) ∪ {?x, ?y}"
using polygon_p p_is polygon_p1 polygon_p2 empty_inter inside have_cut path_im_intersect_minus path_im_intersect_union
proof-
have "{} = path_image cutpath ∪ path_image (make_polygonal_path (vts ! 0 # take (i - 1) (drop 1 vts) @ [vts ! i])) ∩ path_image (reversepath (make_polygonal_path ([vts ! i] @ drop i (drop 1 vts) @ [vts ! 0]))) - path_image cutpath"
using c1_inter_c2 c2_inter_c3 by fastforce
then have "{} = (path_image cutpath ∪ path_image (make_polygonal_path (vts ! 0 # take (i - 1) (drop 1 vts) @ [vts ! i]))) ∩ (path_image cutpath ∪ path_image (reversepath (make_polygonal_path ([vts ! i] @ drop i (drop 1 vts) @ [vts ! 0])))) - path_image cutpath"
by blast
then show ?thesis
using empty_inter have_cut inside polygon_p1 polygon_p2 Int_Diff image_prop p_is path_im_intersect_union path_image_p2 polygon_p
by auto
qed
have vts_relation: "(let vts1 = take 0 vts; vts2 = take (i - 0 - 1) (drop (Suc 0) vts);
vts3 = drop (i - 0) (drop (Suc 0) vts); x = vts ! 0; y = vts ! i;
p = make_polygonal_path (vts @ [vts ! 0]); p1 = make_polygonal_path (x # vts2 @ ?c3_rev_vts);
p2 = make_polygonal_path (?c3_vts @ vts3 @ [x]) in
vts1 = [] ∧ vts2 = ?vts2 ∧ vts3 = ?vts3 ∧ p = ?p ∧ p1 = ?p1 ∧ p2 = ?p2)"
by simp
have second_part: "(let vts1 = take 0 vts; vts2 = take (i - 0 - 1) (drop (Suc 0) vts);
vts3 = drop (i - 0) (drop (Suc 0) vts); x = vts ! 0; y = vts ! i;
p = make_polygonal_path (vts @ [vts ! 0]); p1 = make_polygonal_path (x # vts2 @ ?c3_rev_vts);
p2 = make_polygonal_path (vts1 @ ?c3_vts @ vts3 @ [vts ! 0])
in is_polygon_cut_path (vts @ [vts ! 0]) cutpath ∧
polygon p ∧
polygon p1 ∧
polygon p2 ∧
path_inside p1 ∩ path_inside p2 = {} ∧
path_inside p1 ∪ path_inside p2 ∪ (path_image cutpath - {x, y}) = path_inside p
∧ ((path_image p1) - (path_image (cutpath))) ∩ ((path_image p2) - (path_image (cutpath))) = {} ∧
path_image p = ((path_image p1) - (path_image (cutpath))) ∪ ((path_image p2) - (path_image (cutpath))) ∪ {x, y})"
using second_part_helper vts_relation p_is
by (metis self_append_conv2)
show ?thesis
unfolding is_polygon_split_path_def[of vts 0 i cutvts]
using first_part second_part
by (smt (verit, ccfv_threshold) append_Cons append_Nil cutpath rev.simps(2) rev_append rev_is_Nil_conv)
qed
lemma polygon_cut_path_to_split_path:
fixes p :: "R_to_R2"
assumes "polygon p"
"p = make_polygonal_path (vts @ [vts ! 0])"
"is_polygon_cut_path (vts @ [vts!0]) cutpath"
"vts1 ≡ (take i vts)"
"vts2 ≡ (take (j - i - 1) (drop (Suc i) vts))"
"vts3 ≡ drop (j - i) (drop (Suc i) vts)"
"x ≡ vts ! i"
"y ≡ vts ! j"
"cutpath = make_polygonal_path ([x] @ cutvts @ [y])"
"i < length vts ∧ j < length vts ∧ i < j"
"p1 ≡ make_polygonal_path (x#(vts2@([y] @ (rev cutvts) @ [x])))" and
"p2 ≡ make_polygonal_path (vts1 @ ([x] @ cutvts @ [y]) @ vts3 @ [(vts1 @ [x]) ! 0])"
shows "is_polygon_split_path vts i j cutvts"
proof-
let ?poly_vts_rot = "rotate_polygon_vertices (vts @ [vts ! 0]) i"
let ?vts_rot = "butlast ?poly_vts_rot"
let ?p_rot = "make_polygonal_path ?poly_vts_rot"
let ?i_rot = "j - i"
have rot_poly: "polygon ?p_rot" using assms(1) assms(2) rotation_is_polygon by blast
have i_rot: "?i_rot > 0 ∧ ?i_rot < length ?poly_vts_rot - 1"
using assms(10) rotate_polygon_vertices_same_length by fastforce
have vtsi: "vts ! i = ?poly_vts_rot ! 0"
using rotated_polygon_vertices[of ?poly_vts_rot "vts @ [vts!0]" i i]
by (metis (no_types, lifting) One_nat_def Suc_1 assms(10) diff_self_eq_0 hd_conv_nth last_snoc length_append_singleton less_imp_le_nat linorder_not_le not_less_eq_eq nth_append take_all_iff take_eq_Nil)
have vtsj: "vts ! j = ?poly_vts_rot ! ?i_rot"
using rotated_polygon_vertices[of ?poly_vts_rot "vts @ [vts!0]" i j]
by (smt (verit, ccfv_SIG) One_nat_def Suc_1 assms(10) butlast_snoc hd_append2 hd_conv_nth last_snoc leD length_append_singleton less_Suc_eq_le less_imp_le_nat not_less_eq_eq nth_butlast take_all_iff take_eq_Nil)
have "is_polygon_cut_path ?poly_vts_rot cutpath"
proof-
have "?poly_vts_rot ! 0 ≠ ?poly_vts_rot ! ?i_rot"
using assms(3) unfolding is_polygon_cut_path_def using vtsi vtsj
using append_Cons append_is_Nil_conv assms(7) assms(8) assms(9) last_appendR last_conv_nth polygon_pathfinish polygon_pathstart
by force
moreover have "{?poly_vts_rot ! 0, ?poly_vts_rot ! ?i_rot} ⊆ set (?poly_vts_rot @ [?poly_vts_rot ! 0])"
using assms(3) unfolding is_polygon_cut_path_def using i_rot vtsi vtsj by fastforce
moreover have "path_image cutpath ∩ path_image ?p_rot = {?poly_vts_rot ! 0, ?poly_vts_rot ! ?i_rot}"
using polygon_vts_arb_rotation vtsi vtsj assms(3) is_polygon_cut_path_def
by (metis (no_types, lifting) append.assoc append_Cons assms(7) assms(8) assms(9) last_conv_nth nth_Cons_0 polygon_pathfinish polygon_pathstart snoc_eq_iff_butlast)
moreover have "path_image cutpath ∩ path_inside (?p_rot) ≠ {}"
using vtsi vtsj assms(3) polygon_vts_arb_rotation
unfolding is_polygon_cut_path_def path_inside_def by metis
ultimately show ?thesis
unfolding is_polygon_cut_path_def
using rot_poly assms(3) is_polygon_cut_path_def rotate_polygon_vertices_same_set vtsi vtsj
by (metis polygon_vts_arb_rotation)
qed
then have rot_cut: "is_polygon_cut_path (?vts_rot @ [?vts_rot!0]) cutpath"
by (metis butlast_snoc rotate_polygon_vertices_def)
have rot_cut_butlast: "make_polygonal_path ?poly_vts_rot = make_polygonal_path (?vts_rot @ [?vts_rot!0])"
by (metis butlast_snoc rotate_polygon_vertices_def)
have split_rot: "is_polygon_split_path ?vts_rot 0 ?i_rot cutvts"
using rot_cut rot_cut_butlast
by (smt (verit, ccfv_SIG) assms(7) assms(8) assms(9) dual_order.strict_trans i_rot is_polygon_cut_path_def length_butlast nth_butlast polygon_cut_path_to_split_path_vtx0 vtsi vtsj)
let ?vts1_rot = "take 0 ?vts_rot"
let ?vts2_rot = "take (j - i - 0 - 1) (drop (Suc 0) ?vts_rot)"
let ?vts3_rot = "drop (j - i - 0) (drop (Suc 0) ?vts_rot)"
let ?x_rot = "?vts_rot ! 0"
let ?y_rot = "?vts_rot ! (j - i)"
let ?p1_rot_vts = "?x_rot # ?vts2_rot @ [?y_rot] @ (rev cutvts) @ [?x_rot]"
let ?p1_rot = "make_polygonal_path ?p1_rot_vts"
let ?p2_rot_vts = "?vts1_rot @ [?x_rot] @ cutvts @ [?y_rot] @ ?vts3_rot @ [?vts_rot ! 0]"
let ?p2_rot = "make_polygonal_path ?p2_rot_vts"
let ?p1_vts = "x # vts2 @ [y] @ (rev cutvts) @ [x]"
let ?p2_vts = "vts1 @ [x] @ cutvts @ [y] @ vts3 @ [(vts1 @ [x]) ! 0]"
have p2_firstlast: "hd ?p2_vts = last ?p2_vts"
by (metis (no_types, lifting) append_is_Nil_conv append_self_conv2 hd_append2 hd_conv_nth last_appendR last_snoc list.discI list.sel(1))
have "length (drop (Suc i) vts) = length vts - i - 1"
by simp
then have len_prop: "length (drop (Suc i) vts) ≥ j - i - 1"
using assms(9) assms(10) diff_le_mono less_or_eq_imp_le by presburger
have drop_take: "rotate i vts = drop i vts @ take i vts"
using rotate_drop_take[of i vts] assms(10) mod_less by presburger
then have drop_take_suc: "drop (Suc 0) (rotate i vts) = drop (Suc i) vts @ take i vts"
using assms(10) by simp
then have "take (j - Suc i) (drop (Suc 0) (rotate i vts)) = take (j - Suc i) (drop (Suc i) vts)"
using len_prop by force
then have vts2: "take (j - i - 0 - 1) (drop (Suc 0) (butlast (rotate_polygon_vertices (vts @ [vts ! 0]) i))) = vts2"
using assms(5) unfolding rotate_polygon_vertices_def
by (metis Suc_eq_plus1 butlast_snoc diff_diff_left diff_zero)
have xy: "?x_rot = x ∧ ?y_rot = y"
using vtsi vtsj assms by (metis is_polygon_split_path_def nth_butlast split_rot)
moreover have "path_image p = path_image ?p_rot"
using assms(1) assms(2) polygon_vts_arb_rotation by auto
moreover then have "path_inside p = path_inside ?p_rot" unfolding path_inside_def by simp
moreover have "?p1_rot_vts = ?p1_vts" using xy vts2 by presburger
moreover then have "path_image p1 = path_image ?p1_rot" using assms by argo
moreover then have "path_inside p1 = path_inside ?p1_rot" unfolding path_inside_def by argo
moreover have "polygon p1"
using calculation split_rot assms(11) unfolding is_polygon_split_path_def
by (smt (verit, ccfv_SIG) vts2)
moreover have "?p2_rot_vts = rotate_polygon_vertices ?p2_vts i"
proof-
have "butlast (vts1 @ [x] @ cutvts @ [y] @ vts3 @ [(vts1 @ [x]) ! 0])
= vts1 @ [x] @ cutvts @ [y] @ vts3"
by (simp add: butlast_append)
also have "rotate i ... = [x] @ cutvts @ [y] @ vts3 @ vts1"
using assms(4)
by (metis (no_types, lifting) drop_take add_diff_cancel_right' append.assoc assms(10) diff_diff_cancel length_append length_drop length_rotate less_imp_le_nat rotate_append)
finally have "rotate_polygon_vertices ?p2_vts i = [x] @ cutvts @ [y] @ vts3 @ vts1 @ [x]"
unfolding rotate_polygon_vertices_def by simp
moreover have "?vts3_rot = vts3 @ vts1"
using assms(4,6) unfolding rotate_polygon_vertices_def
by (smt (verit, del_insts) One_nat_def Suc_diff_Suc Suc_leI drop_take_suc assms(10) butlast_snoc diff_is_0_eq diff_zero drop0 drop_append i_rot le_add_diff_inverse len_prop length_drop nat_less_le)
ultimately show ?thesis by (simp add: xy)
qed
moreover then have "polygon p2"
using unrotation_is_polygon[of ?p2_vts i p2] split_rot assms(12) p2_firstlast
unfolding is_polygon_split_path_def
by (smt (verit) append.assoc)
moreover then have "path_image p2 = path_image (?p2_rot)"
using assms(12) polygon_vts_arb_rotation calculation by auto
moreover then have "path_inside p2 = path_inside ?p2_rot" unfolding path_inside_def by presburger
ultimately show "is_polygon_split_path vts i j cutvts"
using split_rot unfolding is_polygon_split_path_def
using One_nat_def assms bot_nat_0.not_eq_extremum butlast_snoc hd_append2 hd_conv_nth hd_take le_add2 length_0_conv length_Cons length_append length_butlast nth_append_length rot_cut_butlast rotate_polygon_vertices_same_length take_eq_Nil
by (smt (verit) append.assoc butlast_conv_take have_wraparound_vertex is_polygon_cut_path_def rotate_polygon_vertices_same_set)
qed
lemma good_polygonal_path_implies_polygon_split_path:
assumes "polygon p"
assumes "p = make_polygonal_path (vts @ [vts!0])"
assumes "good_polygonal_path v1 cutvts v2 (vts @ [vts!0])"
assumes "i < length vts ∧ j < length vts"
assumes "vts ! i = v1"
assumes "vts ! j = v2"
assumes "i < j"
shows "is_polygon_split_path vts i j cutvts"
proof-
let ?cutpath = "make_polygonal_path ([v1] @ cutvts @ [v2])"
let ?p_path = "make_polygonal_path (vts @ [vts!0])"
have linepath_subset: "path_image ?cutpath ⊆ path_inside ?p_path ∪ {v1, v2}"
using assms(3) unfolding good_polygonal_path_def by meson
have linepath_ends: "pathstart ?cutpath = v1 ∧ pathfinish ?cutpath = v2"
using polygon_pathfinish polygon_pathstart by force
then have vs_subset1: "{v1, v2} ⊆ path_image ?cutpath"
using vertices_on_path_image by fastforce
have vs_subset2: "{v1, v2} ⊆ path_image (make_polygonal_path (vts @ [vts ! 0]))"
using assms(4-6) vertices_on_path_image[of vts]
using vertices_on_path_image by fastforce
have "path_inside ?p_path ∩ path_image ?p_path = {}"
using inside_outside_polygon[OF assms(1)] assms(2) unfolding inside_outside_def
by blast
then have linepath_path: "path_image ?cutpath ∩ path_image (make_polygonal_path (vts @ [vts ! 0])) = {v1, v2}"
using linepath_subset vs_subset1 vs_subset2
by blast
have "?cutpath (5 / 10) ∈ path_image ?cutpath"
unfolding path_image_def by auto
have v1_neq_v2: "v1 ≠ v2"
using assms(3) unfolding good_polygonal_path_def
by fastforce
have not_v1: "?cutpath (0.5::real) = v1 ⟹ False"
proof -
assume *: "?cutpath (0.5::real) = v1"
then have "?cutpath (0.5::real) = ?cutpath 0"
using linepath_ends unfolding pathstart_def by simp
moreover have "loop_free ?cutpath" using assms unfolding good_polygonal_path_def by metis
ultimately show "False" unfolding loop_free_def by fastforce
qed
have not_v2: "?cutpath (0.5::real) = v2 ⟹ False"
proof-
assume *: "?cutpath (0.5::real) = v2"
then have "?cutpath (0.5::real) = ?cutpath 1"
using linepath_ends unfolding pathfinish_def by simp
moreover have "loop_free ?cutpath" using assms unfolding good_polygonal_path_def by metis
ultimately show "False" unfolding loop_free_def by fastforce
qed
then have "?cutpath (0.5::real) ≠ v1 ∧ ?cutpath (0.5::real) ≠ v2"
using not_v1 not_v2 by auto
then have linepath_inside: "path_image ?cutpath ∩ path_inside (make_polygonal_path (vts @ [vts ! 0])) ≠ {}"
using linepath_subset
using ‹?cutpath (5 / 10) ∈ path_image ?cutpath› by blast
have "is_polygon_cut_path (vts @ [vts!0]) ?cutpath"
using assms(3) assms(1-2) unfolding good_polygonal_path_def is_polygon_cut_path_def
using linepath_path linepath_inside
by (metis linepath_ends make_polygonal_path_gives_path simple_path_def)
then show ?thesis using polygon_cut_path_to_split_path assms by blast
qed
lemma good_path_iff:
"good_linepath a b vts ⟷ good_polygonal_path a [] b vts"
unfolding good_linepath_def good_polygonal_path_def
using linepath_loop_free by auto
lemma polygon_cut_iff: "is_polygon_cut (vts @ [vts!0]) (vts!i) (vts!j)
⟷ is_polygon_cut_path (vts @ [vts!0]) (linepath (vts!i) (vts!j))"
unfolding is_polygon_cut_def is_polygon_cut_path_def
by (metis pathfinish_linepath pathstart_linepath simple_path_linepath)
lemma polygon_split_iff: "is_polygon_split vts i j ⟷ is_polygon_split_path vts i j []"
unfolding is_polygon_split_def is_polygon_split_path_def
by (smt (verit, ccfv_threshold) append_Cons append_Nil make_polygonal_path.simps(3) polygon_cut_iff rev.simps(1))
lemma polygon_cut_to_split_vtx0:
fixes p :: "R_to_R2"
assumes polygon_p: "polygon p" and
i_gt: "i > 0" and
i_lt: "i < length vts" and
p_is: "p = make_polygonal_path (vts @ [vts ! 0])" and
have_cut: "is_polygon_cut (vts @ [vts!0]) (vts!0) (vts!i)"
shows "is_polygon_split vts 0 i"
using have_cut i_gt i_lt p_is polygon_cut_path_to_split_path_vtx0 polygon_cut_iff polygon_p polygon_split_iff
by force
lemma polygon_cut_to_split:
fixes p :: "R_to_R2"
assumes "is_polygon_cut (vts @ [vts!0]) (vts!i) (vts!j)"
"i < length vts ∧ j < length vts ∧ i < j"
shows "is_polygon_split vts i j"
by (metis append_Cons append_Nil assms is_polygon_cut_def make_polygonal_path.simps(3) polygon_cut_path_to_split_path polygon_cut_iff polygon_split_iff)
lemma good_linepath_implies_polygon_split:
assumes "polygon p"
assumes "p = make_polygonal_path (vts @ [vts!0])"
assumes "good_linepath v1 v2 (vts @ [vts!0])"
assumes "i < length vts ∧ j < length vts"
assumes "vts ! i = v1"
assumes "vts ! j = v2"
assumes "i < j"
shows "is_polygon_split vts i j"
using assms good_path_iff good_polygonal_path_implies_polygon_split_path polygon_split_iff
by auto
end