Theory Projective
section "Projective geometry"
theory Projective
imports Linear_Algebra2
Euclid_Tarski
Action
begin
subsection "Proportionality on non-zero vectors"
context vector_space
begin
definition proportionality :: "('b × 'b) set" where
"proportionality ≡ {(x, y). x ≠ 0 ∧ y ≠ 0 ∧ (∃k. x = scale k y)}"
definition non_zero_vectors :: "'b set" where
"non_zero_vectors ≡ {x. x ≠ 0}"
lemma proportionality_refl_on: "refl_on local.non_zero_vectors local.proportionality"
proof -
have "local.proportionality ⊆ local.non_zero_vectors × local.non_zero_vectors"
unfolding proportionality_def non_zero_vectors_def
by auto
moreover have "∀x∈local.non_zero_vectors. (x, x) ∈ local.proportionality"
proof
fix x
assume "x ∈ local.non_zero_vectors"
hence "x ≠ 0" unfolding non_zero_vectors_def ..
moreover have "x = scale 1 x" by simp
ultimately show "(x, x) ∈ local.proportionality"
unfolding proportionality_def
by blast
qed
ultimately show "refl_on local.non_zero_vectors local.proportionality"
unfolding refl_on_def ..
qed
lemma proportionality_sym: "sym local.proportionality"
proof -
{ fix x y
assume "(x, y) ∈ local.proportionality"
hence "x ≠ 0" and "y ≠ 0" and "∃k. x = scale k y"
unfolding proportionality_def
by simp+
from ‹∃k. x = scale k y› obtain k where "x = scale k y" by auto
with ‹x ≠ 0› have "k ≠ 0" by simp
with ‹x = scale k y› have "y = scale (1/k) x" by simp
with ‹x ≠ 0› and ‹y ≠ 0› have "(y, x) ∈ local.proportionality"
unfolding proportionality_def
by auto
}
thus "sym local.proportionality"
unfolding sym_def
by blast
qed
lemma proportionality_trans: "trans local.proportionality"
proof -
{ fix x y z
assume "(x, y) ∈ local.proportionality" and "(y, z) ∈ local.proportionality"
hence "x ≠ 0" and "z ≠ 0" and "∃j. x = scale j y" and "∃k. y = scale k z"
unfolding proportionality_def
by simp+
from ‹∃j. x = scale j y› and ‹∃k. y = scale k z›
obtain j and k where "x = scale j y" and "y = scale k z" by auto+
hence "x = scale (j * k) z" by simp
with ‹x ≠ 0› and ‹z ≠ 0› have "(x, z) ∈ local.proportionality"
unfolding proportionality_def
by auto
}
thus "trans local.proportionality"
unfolding trans_def
by blast
qed
theorem proportionality_equiv: "equiv local.non_zero_vectors local.proportionality"
unfolding equiv_def
by (simp add:
proportionality_refl_on
proportionality_sym
proportionality_trans)
end
definition invertible_proportionality ::
"((real^('n::finite)^'n) × (real^'n^'n)) set" where
"invertible_proportionality ≡
real_vector.proportionality ∩ (Collect invertible × Collect invertible)"
lemma invertible_proportionality_equiv:
"equiv (Collect invertible :: (real^('n::finite)^'n) set)
invertible_proportionality"
(is "equiv ?invs _")
proof -
from zero_not_invertible
have "real_vector.non_zero_vectors ∩ ?invs = ?invs"
unfolding real_vector.non_zero_vectors_def
by auto
from equiv_restrict and real_vector.proportionality_equiv
have "equiv (real_vector.non_zero_vectors ∩ ?invs) invertible_proportionality"
unfolding invertible_proportionality_def
by auto
with ‹real_vector.non_zero_vectors ∩ ?invs = ?invs›
show "equiv ?invs invertible_proportionality"
by simp
qed
subsection "Points of the real projective plane"
typedef proj2 = "(real_vector.non_zero_vectors :: (real^3) set)//real_vector.proportionality"
proof
have "(axis 1 1 :: real^3) ∈ real_vector.non_zero_vectors"
unfolding real_vector.non_zero_vectors_def
by (simp add: axis_def vec_eq_iff[where 'a="real"])
thus "real_vector.proportionality `` {axis 1 1} ∈ (real_vector.non_zero_vectors :: (real^3) set)//real_vector.proportionality"
unfolding quotient_def
by auto
qed
definition proj2_rep :: "proj2 ⇒ real^3" where
"proj2_rep x ≡ ϵ v. v ∈ Rep_proj2 x"
definition proj2_abs :: "real^3 ⇒ proj2" where
"proj2_abs v ≡ Abs_proj2 (real_vector.proportionality `` {v})"
lemma proj2_rep_in: "proj2_rep x ∈ Rep_proj2 x"
proof -
let ?v = "proj2_rep x"
from quotient_element_nonempty and
real_vector.proportionality_equiv and
Rep_proj2 [of x]
have "∃ w. w ∈ Rep_proj2 x"
by auto
with someI_ex [of "λ z. z ∈ Rep_proj2 x"]
show "?v ∈ Rep_proj2 x"
unfolding proj2_rep_def
by simp
qed
lemma proj2_rep_non_zero: "proj2_rep x ≠ 0"
proof -
from
Union_quotient [of real_vector.non_zero_vectors real_vector.proportionality]
and real_vector.proportionality_equiv
and Rep_proj2 [of x] and proj2_rep_in [of x]
have "proj2_rep x ∈ real_vector.non_zero_vectors"
unfolding quotient_def
by auto
thus "proj2_rep x ≠ 0"
unfolding real_vector.non_zero_vectors_def
by simp
qed
lemma proj2_rep_abs:
fixes v :: "real^3"
assumes "v ∈ real_vector.non_zero_vectors"
shows "(v, proj2_rep (proj2_abs v)) ∈ real_vector.proportionality"
proof -
from ‹v ∈ real_vector.non_zero_vectors›
have "real_vector.proportionality `` {v} ∈ (real_vector.non_zero_vectors :: (real^3) set)//real_vector.proportionality"
unfolding quotient_def
by auto
with Abs_proj2_inverse
have "Rep_proj2 (proj2_abs v) = real_vector.proportionality `` {v}"
unfolding proj2_abs_def
by simp
with proj2_rep_in
have "proj2_rep (proj2_abs v) ∈ real_vector.proportionality `` {v}" by auto
thus "(v, proj2_rep (proj2_abs v)) ∈ real_vector.proportionality" by simp
qed
lemma proj2_abs_rep: "proj2_abs (proj2_rep x) = x"
proof -
from partition_Image_element
[of real_vector.non_zero_vectors
real_vector.proportionality
"Rep_proj2 x"
"proj2_rep x"]
and real_vector.proportionality_equiv
and Rep_proj2 [of x] and proj2_rep_in [of x]
have "real_vector.proportionality `` {proj2_rep x} = Rep_proj2 x"
by simp
with Rep_proj2_inverse show "proj2_abs (proj2_rep x) = x"
unfolding proj2_abs_def
by simp
qed
lemma proj2_abs_mult:
assumes "c ≠ 0"
shows "proj2_abs (c *⇩R v) = proj2_abs v"
proof cases
assume "v = 0"
thus "proj2_abs (c *⇩R v) = proj2_abs v" by simp
next
assume "v ≠ 0"
with ‹c ≠ 0›
have "(c *⇩R v, v) ∈ real_vector.proportionality"
and "c *⇩R v ∈ real_vector.non_zero_vectors"
and "v ∈ real_vector.non_zero_vectors"
unfolding real_vector.proportionality_def
and real_vector.non_zero_vectors_def
by simp_all
with eq_equiv_class_iff
[of real_vector.non_zero_vectors
real_vector.proportionality
"c *⇩R v"
v]
and real_vector.proportionality_equiv
have "real_vector.proportionality `` {c *⇩R v} =
real_vector.proportionality `` {v}"
by simp
thus "proj2_abs (c *⇩R v) = proj2_abs v"
unfolding proj2_abs_def
by simp
qed
lemma proj2_abs_mult_rep:
assumes "c ≠ 0"
shows "proj2_abs (c *⇩R proj2_rep x) = x"
using proj2_abs_mult and proj2_abs_rep and assms
by simp
lemma proj2_rep_inj: "inj proj2_rep"
by (simp add: inj_on_inverseI [of UNIV proj2_abs proj2_rep] proj2_abs_rep)
lemma proj2_rep_abs2:
assumes "v ≠ 0"
shows "∃ k. k ≠ 0 ∧ proj2_rep (proj2_abs v) = k *⇩R v"
proof -
from proj2_rep_abs [of v] and ‹v ≠ 0›
have "(v, proj2_rep (proj2_abs v)) ∈ real_vector.proportionality"
unfolding real_vector.non_zero_vectors_def
by simp
then obtain c where "v = c *⇩R proj2_rep (proj2_abs v)"
unfolding real_vector.proportionality_def
by auto
with ‹v ≠ 0› have "c ≠ 0" by auto
hence "1/c ≠ 0" by simp
from ‹v = c *⇩R proj2_rep (proj2_abs v)›
have "(1/c) *⇩R v = (1/c) *⇩R c *⇩R proj2_rep (proj2_abs v)"
by simp
with ‹c ≠ 0› have "proj2_rep (proj2_abs v) = (1/c) *⇩R v" by simp
with ‹1/c ≠ 0› show "∃ k. k ≠ 0 ∧ proj2_rep (proj2_abs v) = k *⇩R v"
by blast
qed
lemma proj2_abs_abs_mult:
assumes "proj2_abs v = proj2_abs w" and "w ≠ 0"
shows "∃ c. v = c *⇩R w"
proof cases
assume "v = 0"
hence "v = 0 *⇩R w" by simp
thus "∃ c. v = c *⇩R w" ..
next
assume "v ≠ 0"
from ‹proj2_abs v = proj2_abs w›
have "proj2_rep (proj2_abs v) = proj2_rep (proj2_abs w)" by simp
with proj2_rep_abs2 and ‹w ≠ 0›
obtain k where "proj2_rep (proj2_abs v) = k *⇩R w" by auto
with proj2_rep_abs2 [of v] and ‹v ≠ 0›
obtain j where "j ≠ 0" and "j *⇩R v = k *⇩R w" by auto
hence "(1/j) *⇩R j *⇩R v = (1/j) *⇩R k *⇩R w" by simp
with ‹j ≠ 0› have "v = (k/j) *⇩R w" by simp
thus "∃ c. v = c *⇩R w" ..
qed
lemma dependent_proj2_abs:
assumes "p ≠ 0" and "q ≠ 0" and "i ≠ 0 ∨ j ≠ 0" and "i *⇩R p + j *⇩R q = 0"
shows "proj2_abs p = proj2_abs q"
proof -
have "i ≠ 0"
proof
assume "i = 0"
with ‹i ≠ 0 ∨ j ≠ 0› have "j ≠ 0" by simp
with ‹i *⇩R p + j *⇩R q = 0› and ‹q ≠ 0› have "i *⇩R p ≠ 0" by auto
with ‹i = 0› show False by simp
qed
with ‹p ≠ 0› and ‹i *⇩R p + j *⇩R q = 0› have "j ≠ 0" by auto
from ‹i ≠ 0›
have "proj2_abs p = proj2_abs (i *⇩R p)" by (rule proj2_abs_mult [symmetric])
also from ‹i *⇩R p + j *⇩R q = 0› and proj2_abs_mult [of "-1" "j *⇩R q"]
have "… = proj2_abs (j *⇩R q)" by (simp add: algebra_simps [symmetric])
also from ‹j ≠ 0› have "… = proj2_abs q" by (rule proj2_abs_mult)
finally show "proj2_abs p = proj2_abs q" .
qed
lemma proj2_rep_dependent:
assumes "i *⇩R proj2_rep v + j *⇩R proj2_rep w = 0"
(is "i *⇩R ?p + j *⇩R ?q = 0")
and "i ≠ 0 ∨ j ≠ 0"
shows "v = w"
proof -
have "?p ≠ 0" and "?q ≠ 0" by (rule proj2_rep_non_zero)+
with ‹i ≠ 0 ∨ j ≠ 0› and ‹i *⇩R ?p + j *⇩R ?q = 0›
have "proj2_abs ?p = proj2_abs ?q" by (simp add: dependent_proj2_abs)
thus "v = w" by (simp add: proj2_abs_rep)
qed
lemma proj2_rep_independent:
assumes "p ≠ q"
shows "independent {proj2_rep p, proj2_rep q}"
proof
let ?p' = "proj2_rep p"
let ?q' = "proj2_rep q"
let ?S = "{?p', ?q'}"
assume "dependent ?S"
from proj2_rep_inj and ‹p ≠ q› have "?p' ≠ ?q'"
unfolding inj_on_def
by auto
with dependent_explicit_2 [of ?p' ?q'] and ‹dependent ?S›
obtain i and j where "i *⇩R ?p' + j *⇩R ?q' = 0" and "i ≠ 0 ∨ j ≠ 0"
by (simp add: scalar_equiv) auto
with proj2_rep_dependent have "p = q" by simp
with ‹p ≠ q› show False ..
qed
subsection "Lines of the real projective plane"
definition proj2_Col :: "[proj2, proj2, proj2] ⇒ bool" where
"proj2_Col p q r ≡
(∃ i j k. i *⇩R proj2_rep p + j *⇩R proj2_rep q + k *⇩R proj2_rep r = 0
∧ (i≠0 ∨ j≠0 ∨ k≠0))"
lemma proj2_Col_abs:
assumes "p ≠ 0" and "q ≠ 0" and "r ≠ 0" and "i ≠ 0 ∨ j ≠ 0 ∨ k ≠ 0"
and "i *⇩R p + j *⇩R q + k *⇩R r = 0"
shows "proj2_Col (proj2_abs p) (proj2_abs q) (proj2_abs r)"
(is "proj2_Col ?pp ?pq ?pr")
proof -
from ‹p ≠ 0› and proj2_rep_abs2
obtain i' where "i' ≠ 0" and "proj2_rep ?pp = i' *⇩R p" (is "?rp = _") by auto
from ‹q ≠ 0› and proj2_rep_abs2
obtain j' where "j' ≠ 0" and "proj2_rep ?pq = j' *⇩R q" (is "?rq = _") by auto
from ‹r ≠ 0› and proj2_rep_abs2
obtain k' where "k' ≠ 0" and "proj2_rep ?pr = k' *⇩R r" (is "?rr = _") by auto
with ‹i *⇩R p + j *⇩R q + k *⇩R r = 0›
and ‹i' ≠ 0› and ‹proj2_rep ?pp = i' *⇩R p›
and ‹j' ≠ 0› and ‹proj2_rep ?pq = j' *⇩R q›
have "(i/i') *⇩R ?rp + (j/j') *⇩R ?rq + (k/k') *⇩R ?rr = 0" by simp
from ‹i' ≠ 0› and ‹j' ≠ 0› and ‹k' ≠ 0› and ‹i ≠ 0 ∨ j ≠ 0 ∨ k ≠ 0›
have "i/i' ≠ 0 ∨ j/j' ≠ 0 ∨ k/k' ≠ 0" by simp
with ‹(i/i') *⇩R ?rp + (j/j') *⇩R ?rq + (k/k') *⇩R ?rr = 0›
show "proj2_Col ?pp ?pq ?pr" by (unfold proj2_Col_def, best)
qed
lemma proj2_Col_permute:
assumes "proj2_Col a b c"
shows "proj2_Col a c b"
and "proj2_Col b a c"
proof -
let ?a' = "proj2_rep a"
let ?b' = "proj2_rep b"
let ?c' = "proj2_rep c"
from ‹proj2_Col a b c›
obtain i and j and k where
"i *⇩R ?a' + j *⇩R ?b' + k *⇩R ?c' = 0"
and "i ≠ 0 ∨ j ≠ 0 ∨ k ≠ 0"
unfolding proj2_Col_def
by auto
from ‹i *⇩R ?a' + j *⇩R ?b' + k *⇩R ?c' = 0›
have "i *⇩R ?a' + k *⇩R ?c' + j *⇩R ?b' = 0"
and "j *⇩R ?b' + i *⇩R ?a' + k *⇩R ?c' = 0"
by (simp_all add: ac_simps)
moreover from ‹i ≠ 0 ∨ j ≠ 0 ∨ k ≠ 0›
have "i ≠ 0 ∨ k ≠ 0 ∨ j ≠ 0" and "j ≠ 0 ∨ i ≠ 0 ∨ k ≠ 0" by auto
ultimately show "proj2_Col a c b" and "proj2_Col b a c"
unfolding proj2_Col_def
by auto
qed
lemma proj2_Col_coincide: "proj2_Col a a c"
proof -
have "1 *⇩R proj2_rep a + (-1) *⇩R proj2_rep a + 0 *⇩R proj2_rep c = 0"
by simp
moreover have "(1::real) ≠ 0" by simp
ultimately show "proj2_Col a a c"
unfolding proj2_Col_def
by blast
qed
lemma proj2_Col_iff:
assumes "a ≠ r"
shows "proj2_Col a r t ⟷
t = a ∨ (∃ i. t = proj2_abs (i *⇩R (proj2_rep a) + (proj2_rep r)))"
proof
let ?a' = "proj2_rep a"
let ?r' = "proj2_rep r"
let ?t' = "proj2_rep t"
{ assume "proj2_Col a r t"
then obtain h and j and k where
"h *⇩R ?a' + j *⇩R ?r' + k *⇩R ?t' = 0"
and "h ≠ 0 ∨ j ≠ 0 ∨ k ≠ 0"
unfolding proj2_Col_def
by auto
show "t = a ∨ (∃ i. t = proj2_abs (i *⇩R ?a' + ?r'))"
proof cases
assume "j = 0"
with ‹h ≠ 0 ∨ j ≠ 0 ∨ k ≠ 0› have "h ≠ 0 ∨ k ≠ 0" by simp
with proj2_rep_dependent
and ‹h *⇩R ?a' + j *⇩R ?r' + k *⇩R ?t' = 0›
and ‹j = 0›
have "t = a" by auto
thus "t = a ∨ (∃ i. t = proj2_abs (i *⇩R ?a' + ?r'))" ..
next
assume "j ≠ 0"
have "k ≠ 0"
proof (rule ccontr)
assume "¬ k ≠ 0"
with proj2_rep_dependent
and ‹h *⇩R ?a' + j *⇩R ?r' + k *⇩R ?t' = 0›
and ‹j ≠ 0›
have "a = r" by simp
with ‹a ≠ r› show False ..
qed
from ‹h *⇩R ?a' + j *⇩R ?r' + k *⇩R ?t' = 0›
have "h *⇩R ?a' + j *⇩R ?r' + k *⇩R ?t' - k *⇩R ?t' = -k *⇩R ?t'" by simp
hence "h *⇩R ?a' + j *⇩R ?r' = -k *⇩R ?t'" by simp
with proj2_abs_mult_rep [of "-k"] and ‹k ≠ 0›
have "proj2_abs (h *⇩R ?a' + j *⇩R ?r') = t" by simp
with proj2_abs_mult [of "1/j" "h *⇩R ?a' + j *⇩R ?r'"] and ‹j ≠ 0›
have "proj2_abs ((h/j) *⇩R ?a' + ?r') = t"
by (simp add: scaleR_right_distrib)
hence "∃ i. t = proj2_abs (i *⇩R ?a' + ?r')" by auto
thus "t = a ∨ (∃ i. t = proj2_abs (i *⇩R ?a' + ?r'))" ..
qed
}
{ assume "t = a ∨ (∃ i. t = proj2_abs (i *⇩R ?a' + ?r'))"
show "proj2_Col a r t"
proof cases
assume "t = a"
with proj2_Col_coincide and proj2_Col_permute
show "proj2_Col a r t" by blast
next
assume "t ≠ a"
with ‹t = a ∨ (∃ i. t = proj2_abs (i *⇩R ?a' + ?r'))›
obtain i where "t = proj2_abs (i *⇩R ?a' + ?r')" by auto
from proj2_rep_dependent [of i a 1 r] and ‹a ≠ r›
have "i *⇩R ?a' + ?r' ≠ 0" by auto
with proj2_rep_abs2 and ‹t = proj2_abs (i *⇩R ?a' + ?r')›
obtain j where "?t' = j *⇩R (i *⇩R ?a' + ?r')" by auto
hence "?t' - ?t' = (j * i) *⇩R ?a' + j *⇩R ?r' + (-1) *⇩R ?t'"
by (simp add: scaleR_right_distrib)
hence "(j * i) *⇩R ?a' + j *⇩R ?r' + (-1) *⇩R ?t' = 0" by simp
have "∃ h j k. h *⇩R ?a' + j *⇩R ?r' + k *⇩R ?t' = 0
∧ (h ≠ 0 ∨ j ≠ 0 ∨ k ≠ 0)"
proof standard+
from ‹(j * i) *⇩R ?a' + j *⇩R ?r' + (-1) *⇩R ?t' = 0›
show "(j * i) *⇩R ?a' + j *⇩R ?r' + (-1) *⇩R ?t' = 0" .
show "j * i ≠ 0 ∨ j ≠ 0 ∨ (-1::real) ≠ 0" by simp
qed
thus "proj2_Col a r t"
unfolding proj2_Col_def .
qed
}
qed
definition proj2_Col_coeff :: "proj2 ⇒ proj2 ⇒ proj2 ⇒ real" where
"proj2_Col_coeff a r t ≡ ϵ i. t = proj2_abs (i *⇩R proj2_rep a + proj2_rep r)"
lemma proj2_Col_coeff:
assumes "proj2_Col a r t" and "a ≠ r" and "t ≠ a"
shows "t = proj2_abs ((proj2_Col_coeff a r t) *⇩R proj2_rep a + proj2_rep r)"
proof -
from ‹a ≠ r› and ‹proj2_Col a r t› and ‹t ≠ a› and proj2_Col_iff
have "∃ i. t = proj2_abs (i *⇩R proj2_rep a + proj2_rep r)" by simp
thus "t = proj2_abs ((proj2_Col_coeff a r t) *⇩R proj2_rep a + proj2_rep r)"
by (unfold proj2_Col_coeff_def) (rule someI_ex)
qed
lemma proj2_Col_coeff_unique':
assumes "a ≠ 0" and "r ≠ 0" and "proj2_abs a ≠ proj2_abs r"
and "proj2_abs (i *⇩R a + r) = proj2_abs (j *⇩R a + r)"
shows "i = j"
proof -
from ‹a ≠ 0› and ‹r ≠ 0› and ‹proj2_abs a ≠ proj2_abs r›
and dependent_proj2_abs [of a r _ 1]
have "i *⇩R a + r ≠ 0" and "j *⇩R a + r ≠ 0" by auto
with proj2_rep_abs2 [of "i *⇩R a + r"]
and proj2_rep_abs2 [of "j *⇩R a + r"]
obtain k and l where "k ≠ 0"
and "proj2_rep (proj2_abs (i *⇩R a + r)) = k *⇩R (i *⇩R a + r)"
and "proj2_rep (proj2_abs (j *⇩R a + r)) = l *⇩R (j *⇩R a + r)"
by auto
with ‹proj2_abs (i *⇩R a + r) = proj2_abs (j *⇩R a + r)›
have "(k * i) *⇩R a + k *⇩R r = (l * j) *⇩R a + l *⇩R r"
by (simp add: scaleR_right_distrib)
hence "(k * i - l * j) *⇩R a + (k - l) *⇩R r = 0"
by (simp add: algebra_simps vec_eq_iff)
with ‹a ≠ 0› and ‹r ≠ 0› and ‹proj2_abs a ≠ proj2_abs r›
and dependent_proj2_abs [of a r "k * i - l * j" "k - l"]
have "k * i - l * j = 0" and "k - l = 0" by auto
from ‹k - l = 0› have "k = l" by simp
with ‹k * i - l * j = 0› have "k * i = k * j" by simp
with ‹k ≠ 0› show "i = j" by simp
qed
lemma proj2_Col_coeff_unique:
assumes "a ≠ r"
and "proj2_abs (i *⇩R proj2_rep a + proj2_rep r)
= proj2_abs (j *⇩R proj2_rep a + proj2_rep r)"
shows "i = j"
proof -
let ?a' = "proj2_rep a"
let ?r' = "proj2_rep r"
have "?a' ≠ 0" and "?r' ≠ 0" by (rule proj2_rep_non_zero)+
from ‹a ≠ r› have "proj2_abs ?a' ≠ proj2_abs ?r'" by (simp add: proj2_abs_rep)
with ‹?a' ≠ 0› and ‹?r' ≠ 0›
and ‹proj2_abs (i *⇩R ?a' + ?r') = proj2_abs (j *⇩R ?a' + ?r')›
and proj2_Col_coeff_unique'
show "i = j" by simp
qed
datatype proj2_line = P2L proj2
definition L2P :: "proj2_line ⇒ proj2" where
"L2P l ≡ case l of P2L p ⇒ p"
lemma L2P_P2L [simp]: "L2P (P2L p) = p"
unfolding L2P_def
by simp
lemma P2L_L2P [simp]: "P2L (L2P l) = l"
by (induct l) simp
lemma L2P_inj [simp]:
assumes "L2P l = L2P m"
shows "l = m"
using P2L_L2P [of l] and assms
by simp
lemma P2L_to_L2P: "P2L p = l ⟷ p = L2P l"
proof
assume "P2L p = l"
hence "L2P (P2L p) = L2P l" by simp
thus "p = L2P l" by simp
next
assume "p = L2P l"
thus "P2L p = l" by simp
qed
definition proj2_line_abs :: "real^3 ⇒ proj2_line" where
"proj2_line_abs v ≡ P2L (proj2_abs v)"
definition proj2_line_rep :: "proj2_line ⇒ real^3" where
"proj2_line_rep l ≡ proj2_rep (L2P l)"
lemma proj2_line_rep_abs:
assumes "v ≠ 0"
shows "∃ k. k ≠ 0 ∧ proj2_line_rep (proj2_line_abs v) = k *⇩R v"
unfolding proj2_line_rep_def and proj2_line_abs_def
using proj2_rep_abs2 and ‹v ≠ 0›
by simp
lemma proj2_line_abs_rep [simp]: "proj2_line_abs (proj2_line_rep l) = l"
unfolding proj2_line_abs_def and proj2_line_rep_def
by (simp add: proj2_abs_rep)
lemma proj2_line_rep_non_zero: "proj2_line_rep l ≠ 0"
unfolding proj2_line_rep_def
using proj2_rep_non_zero
by simp
lemma proj2_line_rep_dependent:
assumes "i *⇩R proj2_line_rep l + j *⇩R proj2_line_rep m = 0"
and "i ≠ 0 ∨ j ≠ 0"
shows "l = m"
using proj2_rep_dependent [of i "L2P l" j "L2P m"] and assms
unfolding proj2_line_rep_def
by simp
lemma proj2_line_abs_mult:
assumes "k ≠ 0"
shows "proj2_line_abs (k *⇩R v) = proj2_line_abs v"
unfolding proj2_line_abs_def
using ‹k ≠ 0›
by (subst proj2_abs_mult) simp_all
lemma proj2_line_abs_abs_mult:
assumes "proj2_line_abs v = proj2_line_abs w" and "w ≠ 0"
shows "∃ k. v = k *⇩R w"
using assms
by (unfold proj2_line_abs_def) (simp add: proj2_abs_abs_mult)
definition proj2_incident :: "proj2 ⇒ proj2_line ⇒ bool" where
"proj2_incident p l ≡ (proj2_rep p) ∙ (proj2_line_rep l) = 0"
lemma proj2_points_define_line:
shows "∃ l. proj2_incident p l ∧ proj2_incident q l"
proof -
let ?p' = "proj2_rep p"
let ?q' = "proj2_rep q"
let ?B = "{?p', ?q'}"
from card_suc_ge_insert [of ?p' "{?q'}"] have "card ?B ≤ 2" by simp
with dim_le_card' [of ?B] have "dim ?B < 3" by simp
with lowdim_subset_hyperplane [of ?B]
obtain l' where "l' ≠ 0" and "span ?B ⊆ {x. l' ∙ x = 0}" by auto
let ?l = "proj2_line_abs l'"
let ?l'' = "proj2_line_rep ?l"
from proj2_line_rep_abs and ‹l' ≠ 0›
obtain k where "?l'' = k *⇩R l'" by auto
have "?p' ∈ ?B" and "?q' ∈ ?B" by simp_all
with span_superset [of ?B] and ‹span ?B ⊆ {x. l' ∙ x = 0}›
have "l' ∙ ?p' = 0" and "l' ∙ ?q' = 0" by auto
hence "?p' ∙ l' = 0" and "?q' ∙ l' = 0" by (simp_all add: inner_commute)
with dot_scaleR_mult(2) [of _ k l'] and ‹?l'' = k *⇩R l'›
have "proj2_incident p ?l ∧ proj2_incident q ?l"
unfolding proj2_incident_def
by simp
thus "∃ l. proj2_incident p l ∧ proj2_incident q l" by auto
qed
definition proj2_line_through :: "proj2 ⇒ proj2 ⇒ proj2_line" where
"proj2_line_through p q ≡ ϵ l. proj2_incident p l ∧ proj2_incident q l"
lemma proj2_line_through_incident:
shows "proj2_incident p (proj2_line_through p q)"
and "proj2_incident q (proj2_line_through p q)"
unfolding proj2_line_through_def
using proj2_points_define_line
and someI_ex [of "λ l. proj2_incident p l ∧ proj2_incident q l"]
by simp_all
lemma proj2_line_through_unique:
assumes "p ≠ q" and "proj2_incident p l" and "proj2_incident q l"
shows "l = proj2_line_through p q"
proof -
let ?l' = "proj2_line_rep l"
let ?m = "proj2_line_through p q"
let ?m' = "proj2_line_rep ?m"
let ?p' = "proj2_rep p"
let ?q' = "proj2_rep q"
let ?A = "{?p', ?q'}"
let ?B = "insert ?m' ?A"
from proj2_line_through_incident
have "proj2_incident p ?m" and "proj2_incident q ?m" by simp_all
with ‹proj2_incident p l› and ‹proj2_incident q l›
have ortho: "⋀w. w∈?A ⟹ orthogonal ?m' w" "⋀w. w∈?A ⟹ orthogonal ?l' w"
unfolding proj2_incident_def and orthogonal_def
by (metis empty_iff inner_commute insert_iff)+
from proj2_rep_independent and ‹p ≠ q› have "independent ?A" by simp
from proj2_line_rep_non_zero have "?m' ≠ 0" by simp
with orthogonal_independent ‹independent ?A› ortho
have "independent ?B" by auto
from proj2_rep_inj and ‹p ≠ q› have "?p' ≠ ?q'"
unfolding inj_on_def
by auto
hence "card ?A = 2" by simp
moreover have "?m' ∉ ?A"
using ortho(1) orthogonal_self proj2_line_rep_non_zero by auto
ultimately have "card ?B = 3" by simp
with independent_is_basis [of ?B] and ‹independent ?B›
have "is_basis ?B" by simp
with basis_expand obtain c where "?l' = (∑ v∈?B. c v *⇩R v)" by auto
let ?l'' = "?l' - c ?m' *⇩R ?m'"
from ‹?l' = (∑ v∈?B. c v *⇩R v)› and ‹?m' ∉ ?A›
have "?l'' = (∑ v∈?A. c v *⇩R v)" by simp
with orthogonal_sum [of ?A] ortho
have "orthogonal ?l' ?l''" and "orthogonal ?m' ?l''"
by (simp_all add: scalar_equiv)
from ‹orthogonal ?m' ?l''›
have "orthogonal (c ?m' *⇩R ?m') ?l''" by (simp add: orthogonal_clauses)
with ‹orthogonal ?l' ?l''›
have "orthogonal ?l'' ?l''" by (simp add: orthogonal_clauses)
with orthogonal_self_eq_0 [of ?l''] have "?l'' = 0" by simp
with proj2_line_rep_dependent [of 1 l "- c ?m'" ?m] show "l = ?m" by simp
qed
lemma proj2_incident_unique:
assumes "proj2_incident p l"
and "proj2_incident q l"
and "proj2_incident p m"
and "proj2_incident q m"
shows "p = q ∨ l = m"
proof cases
assume "p = q"
thus "p = q ∨ l = m" ..
next
assume "p ≠ q"
with ‹proj2_incident p l› and ‹proj2_incident q l›
and proj2_line_through_unique
have "l = proj2_line_through p q" by simp
moreover from ‹p ≠ q› and ‹proj2_incident p m› and ‹proj2_incident q m›
have "m = proj2_line_through p q" by (rule proj2_line_through_unique)
ultimately show "p = q ∨ l = m" by simp
qed
lemma proj2_lines_define_point: "∃ p. proj2_incident p l ∧ proj2_incident p m"
proof -
let ?l' = "L2P l"
let ?m' = "L2P m"
from proj2_points_define_line [of ?l' ?m']
obtain p' where "proj2_incident ?l' p' ∧ proj2_incident ?m' p'" by auto
hence "proj2_incident (L2P p') l ∧ proj2_incident (L2P p') m"
unfolding proj2_incident_def and proj2_line_rep_def
by (simp add: inner_commute)
thus "∃ p. proj2_incident p l ∧ proj2_incident p m" by auto
qed
definition proj2_intersection :: "proj2_line ⇒ proj2_line ⇒ proj2" where
"proj2_intersection l m ≡ L2P (proj2_line_through (L2P l) (L2P m))"
lemma proj2_incident_switch:
assumes "proj2_incident p l"
shows "proj2_incident (L2P l) (P2L p)"
using assms
unfolding proj2_incident_def and proj2_line_rep_def
by (simp add: inner_commute)
lemma proj2_intersection_incident:
shows "proj2_incident (proj2_intersection l m) l"
and "proj2_incident (proj2_intersection l m) m"
using proj2_line_through_incident(1) [of "L2P l" "L2P m"]
and proj2_line_through_incident(2) [of "L2P m" "L2P l"]
and proj2_incident_switch [of "L2P l"]
and proj2_incident_switch [of "L2P m"]
unfolding proj2_intersection_def
by simp_all
lemma proj2_intersection_unique:
assumes "l ≠ m" and "proj2_incident p l" and "proj2_incident p m"
shows "p = proj2_intersection l m"
proof -
from ‹l ≠ m› have "L2P l ≠ L2P m" by auto
from ‹proj2_incident p l› and ‹proj2_incident p m›
and proj2_incident_switch
have "proj2_incident (L2P l) (P2L p)" and "proj2_incident (L2P m) (P2L p)"
by simp_all
with ‹L2P l ≠ L2P m› and proj2_line_through_unique
have "P2L p = proj2_line_through (L2P l) (L2P m)" by simp
thus "p = proj2_intersection l m"
unfolding proj2_intersection_def
by (simp add: P2L_to_L2P)
qed
lemma proj2_not_self_incident:
"¬ (proj2_incident p (P2L p))"
unfolding proj2_incident_def and proj2_line_rep_def
using proj2_rep_non_zero and inner_eq_zero_iff [of "proj2_rep p"]
by simp
lemma proj2_another_point_on_line:
"∃ q. q ≠ p ∧ proj2_incident q l"
proof -
let ?m = "P2L p"
let ?q = "proj2_intersection l ?m"
from proj2_intersection_incident
have "proj2_incident ?q l" and "proj2_incident ?q ?m" by simp_all
from ‹proj2_incident ?q ?m› and proj2_not_self_incident have "?q ≠ p" by auto
with ‹proj2_incident ?q l› show "∃ q. q ≠ p ∧ proj2_incident q l" by auto
qed
lemma proj2_another_line_through_point:
"∃ m. m ≠ l ∧ proj2_incident p m"
proof -
from proj2_another_point_on_line
obtain q where "q ≠ L2P l ∧ proj2_incident q (P2L p)" by auto
with proj2_incident_switch [of q "P2L p"]
have "P2L q ≠ l ∧ proj2_incident p (P2L q)" by auto
thus "∃ m. m ≠ l ∧ proj2_incident p m" ..
qed
lemma proj2_incident_abs:
assumes "v ≠ 0" and "w ≠ 0"
shows "proj2_incident (proj2_abs v) (proj2_line_abs w) ⟷ v ∙ w = 0"
proof -
from ‹v ≠ 0› and proj2_rep_abs2
obtain j where "j ≠ 0" and "proj2_rep (proj2_abs v) = j *⇩R v" by auto
from ‹w ≠ 0› and proj2_line_rep_abs
obtain k where "k ≠ 0"
and "proj2_line_rep (proj2_line_abs w) = k *⇩R w"
by auto
with ‹j ≠ 0› and ‹proj2_rep (proj2_abs v) = j *⇩R v›
show "proj2_incident (proj2_abs v) (proj2_line_abs w) ⟷ v ∙ w = 0"
unfolding proj2_incident_def
by (simp add: dot_scaleR_mult)
qed
lemma proj2_incident_left_abs:
assumes "v ≠ 0"
shows "proj2_incident (proj2_abs v) l ⟷ v ∙ (proj2_line_rep l) = 0"
proof -
have "proj2_line_rep l ≠ 0" by (rule proj2_line_rep_non_zero)
with ‹v ≠ 0› and proj2_incident_abs [of v "proj2_line_rep l"]
show "proj2_incident (proj2_abs v) l ⟷ v ∙ (proj2_line_rep l) = 0" by simp
qed
lemma proj2_incident_right_abs:
assumes "v ≠ 0"
shows "proj2_incident p (proj2_line_abs v) ⟷ (proj2_rep p) ∙ v = 0"
proof -
have "proj2_rep p ≠ 0" by (rule proj2_rep_non_zero)
with ‹v ≠ 0› and proj2_incident_abs [of "proj2_rep p" v]
show "proj2_incident p (proj2_line_abs v) ⟷ (proj2_rep p) ∙ v = 0"
by (simp add: proj2_abs_rep)
qed
definition proj2_set_Col :: "proj2 set ⇒ bool" where
"proj2_set_Col S ≡ ∃ l. ∀ p∈S. proj2_incident p l"
lemma proj2_subset_Col:
assumes "T ⊆ S" and "proj2_set_Col S"
shows "proj2_set_Col T"
using ‹T ⊆ S› and ‹proj2_set_Col S›
by (unfold proj2_set_Col_def) auto
definition proj2_no_3_Col :: "proj2 set ⇒ bool" where
"proj2_no_3_Col S ≡ card S = 4 ∧ (∀ p∈S. ¬ proj2_set_Col (S - {p}))"
lemma proj2_Col_iff_not_invertible:
"proj2_Col p q r
⟷ ¬ invertible (vector [proj2_rep p, proj2_rep q, proj2_rep r] :: real^3^3)"
(is "_ ⟷ ¬ invertible (vector [?u, ?v, ?w])")
proof -
let ?M = "vector [?u,?v,?w] :: real^3^3"
have "proj2_Col p q r ⟷ (∃ x. x ≠ 0 ∧ x v* ?M = 0)"
proof
assume "proj2_Col p q r"
then obtain i and j and k
where "i ≠ 0 ∨ j ≠ 0 ∨ k ≠ 0" and "i *⇩R ?u + j *⇩R ?v + k *⇩R ?w = 0"
unfolding proj2_Col_def
by auto
let ?x = "vector [i,j,k] :: real^3"
from ‹i ≠ 0 ∨ j ≠ 0 ∨ k ≠ 0›
have "?x ≠ 0"
unfolding vector_def
by (simp add: vec_eq_iff forall_3)
moreover {
from ‹i *⇩R ?u + j *⇩R ?v + k *⇩R ?w = 0›
have "?x v* ?M = 0"
unfolding vector_def and vector_matrix_mult_def
by (simp add: sum_3 vec_eq_iff algebra_simps) }
ultimately show "∃ x. x ≠ 0 ∧ x v* ?M = 0" by auto
next
assume "∃ x. x ≠ 0 ∧ x v* ?M = 0"
then obtain x where "x ≠ 0" and "x v* ?M = 0" by auto
let ?i = "x$1"
let ?j = "x$2"
let ?k = "x$3"
from ‹x ≠ 0› have "?i ≠ 0 ∨ ?j ≠ 0 ∨ ?k ≠ 0" by (simp add: vec_eq_iff forall_3)
moreover {
from ‹x v* ?M = 0›
have "?i *⇩R ?u + ?j *⇩R ?v + ?k *⇩R ?w = 0"
unfolding vector_matrix_mult_def and sum_3 and vector_def
by (simp add: vec_eq_iff algebra_simps) }
ultimately show "proj2_Col p q r"
unfolding proj2_Col_def
by auto
qed
also from matrix_right_invertible_ker [of ?M]
have "… ⟷ ¬ (∃ M'. ?M ** M' = mat 1)" by auto
also from matrix_left_right_inverse
have "… ⟷ ¬ invertible ?M"
unfolding invertible_def
by auto
finally show "proj2_Col p q r ⟷ ¬ invertible ?M" .
qed
lemma not_invertible_iff_proj2_set_Col:
"¬ invertible (vector [proj2_rep p, proj2_rep q, proj2_rep r] :: real^3^3)
⟷ proj2_set_Col {p,q,r}"
(is "¬ invertible ?M ⟷ _")
proof -
from left_invertible_iff_invertible
have "¬ invertible ?M ⟷ ¬ (∃ M'. M' ** ?M = mat 1)" by auto
also from matrix_left_invertible_ker [of ?M]
have "… ⟷ (∃ y. y ≠ 0 ∧ ?M *v y = 0)" by auto
also have "… ⟷ (∃ l. ∀ s∈{p,q,r}. proj2_incident s l)"
proof
assume "∃ y. y ≠ 0 ∧ ?M *v y = 0"
then obtain y where "y ≠ 0" and "?M *v y = 0" by auto
let ?l = "proj2_line_abs y"
from ‹?M *v y = 0›
have "∀ s∈{p,q,r}. proj2_rep s ∙ y = 0"
unfolding vector_def
and matrix_vector_mult_def
and inner_vec_def
and sum_3
by (simp add: vec_eq_iff forall_3)
with ‹y ≠ 0› and proj2_incident_right_abs
have "∀ s∈{p,q,r}. proj2_incident s ?l" by simp
thus "∃ l. ∀ s∈{p,q,r}. proj2_incident s l" ..
next
assume "∃ l. ∀ s∈{p,q,r}. proj2_incident s l"
then obtain l where "∀ s∈{p,q,r}. proj2_incident s l" ..
let ?y = "proj2_line_rep l"
have "?y ≠ 0" by (rule proj2_line_rep_non_zero)
moreover {
from ‹∀ s∈{p,q,r}. proj2_incident s l›
have "?M *v ?y = 0"
unfolding vector_def
and matrix_vector_mult_def
and inner_vec_def
and sum_3
and proj2_incident_def
by (simp add: vec_eq_iff) }
ultimately show "∃ y. y ≠ 0 ∧ ?M *v y = 0" by auto
qed
finally show "¬ invertible ?M ⟷ proj2_set_Col {p,q,r}"
unfolding proj2_set_Col_def .
qed
lemma proj2_Col_iff_set_Col:
"proj2_Col p q r ⟷ proj2_set_Col {p,q,r}"
by (simp add: proj2_Col_iff_not_invertible
not_invertible_iff_proj2_set_Col)
lemma proj2_incident_Col:
assumes "proj2_incident p l" and "proj2_incident q l" and "proj2_incident r l"
shows "proj2_Col p q r"
proof -
from ‹proj2_incident p l› and ‹proj2_incident q l› and ‹proj2_incident r l›
have "proj2_set_Col {p,q,r}" by (unfold proj2_set_Col_def) auto
thus "proj2_Col p q r" by (subst proj2_Col_iff_set_Col)
qed
lemma proj2_incident_iff_Col:
assumes "p ≠ q" and "proj2_incident p l" and "proj2_incident q l"
shows "proj2_incident r l ⟷ proj2_Col p q r"
proof
assume "proj2_incident r l"
with ‹proj2_incident p l› and ‹proj2_incident q l›
show "proj2_Col p q r" by (rule proj2_incident_Col)
next
assume "proj2_Col p q r"
hence "proj2_set_Col {p,q,r}" by (simp add: proj2_Col_iff_set_Col)
then obtain m where "∀ s∈{p,q,r}. proj2_incident s m"
unfolding proj2_set_Col_def ..
hence "proj2_incident p m" and "proj2_incident q m" and "proj2_incident r m"
by simp_all
from ‹p ≠ q› and ‹proj2_incident p l› and ‹proj2_incident q l›
and ‹proj2_incident p m› and ‹proj2_incident q m›
and proj2_incident_unique
have "m = l" by auto
with ‹proj2_incident r m› show "proj2_incident r l" by simp
qed
lemma proj2_incident_iff:
assumes "p ≠ q" and "proj2_incident p l" and "proj2_incident q l"
shows "proj2_incident r l
⟷ r = p ∨ (∃ k. r = proj2_abs (k *⇩R proj2_rep p + proj2_rep q))"
proof -
from ‹p ≠ q› and ‹proj2_incident p l› and ‹proj2_incident q l›
have "proj2_incident r l ⟷ proj2_Col p q r" by (rule proj2_incident_iff_Col)
with ‹p ≠ q› and proj2_Col_iff
show "proj2_incident r l
⟷ r = p ∨ (∃ k. r = proj2_abs (k *⇩R proj2_rep p + proj2_rep q))"
by simp
qed
lemma not_proj2_set_Col_iff_span:
assumes "card S = 3"
shows "¬ proj2_set_Col S ⟷ span (proj2_rep ` S) = UNIV"
proof -
from ‹card S = 3› and choose_3 [of S]
obtain p and q and r where "S = {p,q,r}" by auto
let ?u = "proj2_rep p"
let ?v = "proj2_rep q"
let ?w = "proj2_rep r"
let ?M = "vector [?u, ?v, ?w] :: real^3^3"
from ‹S = {p,q,r}› and not_invertible_iff_proj2_set_Col [of p q r]
have "¬ proj2_set_Col S ⟷ invertible ?M" by auto
also from left_invertible_iff_invertible
have "… ⟷ (∃ N. N ** ?M = mat 1)" ..
also from matrix_left_invertible_span_rows
have "… ⟷ span (rows ?M) = UNIV" by auto
finally have "¬ proj2_set_Col S ⟷ span (rows ?M) = UNIV" .
have "rows ?M = {?u, ?v, ?w}"
proof
{ fix x
assume "x ∈ rows ?M"
then obtain i :: 3 where "x = ?M $ i"
unfolding rows_def and row_def
by (auto simp add: vec_lambda_beta vec_lambda_eta)
with exhaust_3 have "x = ?u ∨ x = ?v ∨ x = ?w"
unfolding vector_def
by auto
hence "x ∈ {?u, ?v, ?w}" by simp }
thus "rows ?M ⊆ {?u, ?v, ?w}" ..
{ fix x
assume "x ∈ {?u, ?v, ?w}"
hence "x = ?u ∨ x = ?v ∨ x = ?w" by simp
hence "x = ?M $ 1 ∨ x = ?M $ 2 ∨ x = ?M $ 3"
unfolding vector_def
by simp
hence "x ∈ rows ?M"
unfolding rows_def row_def vec_lambda_eta
by blast }
thus "{?u, ?v, ?w} ⊆ rows ?M" ..
qed
with ‹S = {p,q,r}›
have "rows ?M = proj2_rep ` S"
unfolding image_def
by auto
with ‹¬ proj2_set_Col S ⟷ span (rows ?M) = UNIV›
show "¬ proj2_set_Col S ⟷ span (proj2_rep ` S) = UNIV" by simp
qed
lemma proj2_no_3_Col_span:
assumes "proj2_no_3_Col S" and "p ∈ S"
shows "span (proj2_rep ` (S - {p})) = UNIV"
proof -
from ‹proj2_no_3_Col S› have "card S = 4" unfolding proj2_no_3_Col_def ..
with ‹p ∈ S› and ‹card S = 4› and card_gt_0_diff_singleton [of S p]
have "card (S - {p}) = 3" by simp
from ‹proj2_no_3_Col S› and ‹p ∈ S›
have "¬ proj2_set_Col (S - {p})"
unfolding proj2_no_3_Col_def
by simp
with ‹card (S - {p}) = 3› and not_proj2_set_Col_iff_span
show "span (proj2_rep ` (S - {p})) = UNIV" by simp
qed
lemma fourth_proj2_no_3_Col:
assumes "¬ proj2_Col p q r"
shows "∃ s. proj2_no_3_Col {s,r,p,q}"
proof -
from ‹¬ proj2_Col p q r› and proj2_Col_coincide have "p ≠ q" by auto
hence "card {p,q} = 2" by simp
from ‹¬ proj2_Col p q r› and proj2_Col_coincide and proj2_Col_permute
have "r ∉ {p,q}" by fast
with ‹card {p,q} = 2› have "card {r,p,q} = 3" by simp
have "finite {r,p,q}" by simp
let ?s = "proj2_abs (∑ t∈{r,p,q}. proj2_rep t)"
have "∃ j. (∑ t∈{r,p,q}. proj2_rep t) = j *⇩R proj2_rep ?s"
proof cases
assume "(∑ t∈{r,p,q}. proj2_rep t) = 0"
hence "(∑ t∈{r,p,q}. proj2_rep t) = 0 *⇩R proj2_rep ?s" by simp
thus "∃ j. (∑ t∈{r,p,q}. proj2_rep t) = j *⇩R proj2_rep ?s" ..
next
assume "(∑ t∈{r,p,q}. proj2_rep t) ≠ 0"
with proj2_rep_abs2
obtain k where "k ≠ 0"
and "proj2_rep ?s = k *⇩R (∑ t∈{r,p,q}. proj2_rep t)"
by auto
hence "(1/k) *⇩R proj2_rep ?s = (∑ t∈{r,p,q}. proj2_rep t)" by simp
from this [symmetric]
show "∃ j. (∑ t∈{r,p,q}. proj2_rep t) = j *⇩R proj2_rep ?s" ..
qed
then obtain j where "(∑ t∈{r,p,q}. proj2_rep t) = j *⇩R proj2_rep ?s" ..
let ?c = "λ t. if t = ?s then 1 - j else 1"
from ‹p ≠ q› have "?c p ≠ 0 ∨ ?c q ≠ 0" by simp
let ?d = "λ t. if t = ?s then j else -1"
let ?S = "{?s,r,p,q}"
have "?s ∉ {r,p,q}"
proof
assume "?s ∈ {r,p,q}"
from ‹r ∉ {p,q}› and ‹p ≠ q›
have "?c r *⇩R proj2_rep r + ?c p *⇩R proj2_rep p + ?c q *⇩R proj2_rep q
= (∑ t∈{r,p,q}. ?c t *⇩R proj2_rep t)"
by (simp add: sum.insert [of _ _ "λ t. ?c t *⇩R proj2_rep t"])
also from ‹finite {r,p,q}› and ‹?s ∈ {r,p,q}›
have "… = ?c ?s *⇩R proj2_rep ?s + (∑ t∈{r,p,q}-{?s}. ?c t *⇩R proj2_rep t)"
by (simp only:
sum.remove [of "{r,p,q}" ?s "λ t. ?c t *⇩R proj2_rep t"])
also have "…
= -j *⇩R proj2_rep ?s + (proj2_rep ?s + (∑ t∈{r,p,q}-{?s}. proj2_rep t))"
by (simp add: algebra_simps)
also from ‹finite {r,p,q}› and ‹?s ∈ {r,p,q}›
have "… = -j *⇩R proj2_rep ?s + (∑ t∈{r,p,q}. proj2_rep t)"
by (simp only:
sum.remove [of "{r,p,q}" ?s "λ t. proj2_rep t",symmetric])
also from ‹(∑ t∈{r,p,q}. proj2_rep t) = j *⇩R proj2_rep ?s›
have "… = 0" by simp
finally
have "?c r *⇩R proj2_rep r + ?c p *⇩R proj2_rep p + ?c q *⇩R proj2_rep q = 0"
.
with ‹?c p ≠ 0 ∨ ?c q ≠ 0›
have "proj2_Col p q r"
by (unfold proj2_Col_def) (auto simp add: algebra_simps)
with ‹¬ proj2_Col p q r› show False ..
qed
with ‹card {r,p,q} = 3› have "card ?S = 4" by simp
from ‹¬ proj2_Col p q r› and proj2_Col_permute
have "¬ proj2_Col r p q" by fast
hence "¬ proj2_set_Col {r,p,q}" by (subst proj2_Col_iff_set_Col [symmetric])
have "∀ u∈?S. ¬ proj2_set_Col (?S - {u})"
proof
fix u
assume "u ∈ ?S"
with ‹card ?S = 4› have "card (?S - {u}) = 3" by simp
show "¬ proj2_set_Col (?S - {u})"
proof cases
assume "u = ?s"
with ‹?s ∉ {r,p,q}› have "?S - {u} = {r,p,q}" by simp
with ‹¬ proj2_set_Col {r,p,q}› show "¬ proj2_set_Col (?S - {u})" by simp
next
assume "u ≠ ?s"
hence "insert ?s ({r,p,q} - {u}) = ?S - {u}" by auto
from ‹finite {r,p,q}› have "finite ({r,p,q} - {u})" by simp
from ‹?s ∉ {r,p,q}› have "?s ∉ {r,p,q} - {u}" by simp
hence "∀ t∈{r,p,q}-{u}. ?d t = -1" by auto
from ‹u ≠ ?s› and ‹u ∈ ?S› have "u ∈ {r,p,q}" by simp
hence "(∑ t∈{r,p,q}. proj2_rep t)
= proj2_rep u + (∑ t∈{r,p,q}-{u}. proj2_rep t)"
by (simp add: sum.remove)
with ‹(∑ t∈{r,p,q}. proj2_rep t) = j *⇩R proj2_rep ?s›
have "proj2_rep u
= j *⇩R proj2_rep ?s - (∑ t∈{r,p,q}-{u}. proj2_rep t)"
by simp
also from ‹∀ t∈{r,p,q}-{u}. ?d t = -1›
have "… = j *⇩R proj2_rep ?s + (∑ t∈{r,p,q}-{u}. ?d t *⇩R proj2_rep t)"
by (simp add: sum_negf)
also from ‹finite ({r,p,q} - {u})› and ‹?s ∉ {r,p,q} - {u}›
have "… = (∑ t∈insert ?s ({r,p,q}-{u}). ?d t *⇩R proj2_rep t)"
by (simp add: sum.insert)
also from ‹insert ?s ({r,p,q} - {u}) = ?S - {u}›
have "… = (∑ t∈?S-{u}. ?d t *⇩R proj2_rep t)" by simp
finally have "proj2_rep u = (∑ t∈?S-{u}. ?d t *⇩R proj2_rep t)" .
moreover
have "∀ t∈?S-{u}. ?d t *⇩R proj2_rep t ∈ span (proj2_rep ` (?S - {u}))"
by (simp add: span_clauses)
ultimately have "proj2_rep u ∈ span (proj2_rep ` (?S - {u}))"
by (metis (no_types, lifting) span_sum)
have "∀ t∈{r,p,q}. proj2_rep t ∈ span (proj2_rep ` (?S - {u}))"
proof
fix t
assume "t ∈ {r,p,q}"
show "proj2_rep t ∈ span (proj2_rep ` (?S - {u}))"
proof cases
assume "t = u"
from ‹proj2_rep u ∈ span (image proj2_rep (?S - {u}))›
show "proj2_rep t ∈ span (proj2_rep ` (?S - {u}))"
by (subst ‹t = u›)
next
assume "t ≠ u"
with ‹t ∈ {r,p,q}›
have "proj2_rep t ∈ proj2_rep ` (?S - {u})" by simp
with span_superset [of "proj2_rep ` (?S - {u})"]
show "proj2_rep t ∈ span (proj2_rep ` (?S - {u}))" by fast
qed
qed
hence "proj2_rep ` {r,p,q} ⊆ span (proj2_rep ` (?S - {u}))"
by (simp only: image_subset_iff)
hence
"span (proj2_rep ` {r,p,q}) ⊆ span (span (proj2_rep ` (?S - {u})))"
by (simp only: span_mono)
hence "span (proj2_rep ` {r,p,q}) ⊆ span (proj2_rep ` (?S - {u}))"
by (simp only: span_span)
moreover
from ‹¬ proj2_set_Col {r,p,q}›
and ‹card {r,p,q} = 3›
and not_proj2_set_Col_iff_span
have "span (proj2_rep ` {r,p,q}) = UNIV" by simp
ultimately have "span (proj2_rep ` (?S - {u})) = UNIV" by auto
with ‹card (?S - {u}) = 3› and not_proj2_set_Col_iff_span
show "¬ proj2_set_Col (?S - {u})" by simp
qed
qed
with ‹card ?S = 4›
have "proj2_no_3_Col ?S" by (unfold proj2_no_3_Col_def) fast
thus "∃ s. proj2_no_3_Col {s,r,p,q}" ..
qed
lemma proj2_set_Col_expand:
assumes "proj2_set_Col S" and "{p,q,r} ⊆ S" and "p ≠ q" and "r ≠ p"
shows "∃ k. r = proj2_abs (k *⇩R proj2_rep p + proj2_rep q)"
proof -
from ‹proj2_set_Col S›
obtain l where "∀ t∈S. proj2_incident t l" unfolding proj2_set_Col_def ..
with ‹{p,q,r} ⊆ S› and ‹p ≠ q› and ‹r ≠ p› and proj2_incident_iff [of p q l r]
show "∃ k. r = proj2_abs (k *⇩R proj2_rep p + proj2_rep q)" by simp
qed
subsection "Collineations of the real projective plane"
typedef cltn2 =
"(Collect invertible :: (real^3^3) set)//invertible_proportionality"
proof
from matrix_id_invertible have "(mat 1 :: real^3^3) ∈ Collect invertible"
by simp
thus "invertible_proportionality `` {mat 1} ∈
(Collect invertible :: (real^3^3) set)//invertible_proportionality"
unfolding quotient_def
by auto
qed
definition cltn2_rep :: "cltn2 ⇒ real^3^3" where
"cltn2_rep A ≡ ϵ B. B ∈ Rep_cltn2 A"
definition cltn2_abs :: "real^3^3 ⇒ cltn2" where
"cltn2_abs B ≡ Abs_cltn2 (invertible_proportionality `` {B})"
definition cltn2_independent :: "cltn2 set ⇒ bool" where
"cltn2_independent X ≡ independent {cltn2_rep A | A. A ∈ X}"
definition apply_cltn2 :: "proj2 ⇒ cltn2 ⇒ proj2" where
"apply_cltn2 x A ≡ proj2_abs (proj2_rep x v* cltn2_rep A)"
lemma cltn2_rep_in: "cltn2_rep B ∈ Rep_cltn2 B"
proof -
let ?A = "cltn2_rep B"
from quotient_element_nonempty and
invertible_proportionality_equiv and
Rep_cltn2 [of B]
have "∃ C. C ∈ Rep_cltn2 B"
by auto
with someI_ex [of "λ C. C ∈ Rep_cltn2 B"]
show "?A ∈ Rep_cltn2 B"
unfolding cltn2_rep_def
by simp
qed
lemma cltn2_rep_invertible: "invertible (cltn2_rep A)"
proof -
from
Union_quotient [of "Collect invertible" invertible_proportionality]
and invertible_proportionality_equiv
and Rep_cltn2 [of A] and cltn2_rep_in [of A]
have "cltn2_rep A ∈ Collect invertible"
unfolding quotient_def
by auto
thus "invertible (cltn2_rep A)"
unfolding invertible_proportionality_def
by simp
qed
lemma cltn2_rep_abs:
fixes A :: "real^3^3"
assumes "invertible A"
shows "(A, cltn2_rep (cltn2_abs A)) ∈ invertible_proportionality"
proof -
from ‹invertible A›
have "invertible_proportionality `` {A} ∈ (Collect invertible :: (real^3^3) set)//invertible_proportionality"
unfolding quotient_def
by auto
with Abs_cltn2_inverse
have "Rep_cltn2 (cltn2_abs A) = invertible_proportionality `` {A}"
unfolding cltn2_abs_def
by simp
with cltn2_rep_in
have "cltn2_rep (cltn2_abs A) ∈ invertible_proportionality `` {A}" by auto
thus "(A, cltn2_rep (cltn2_abs A)) ∈ invertible_proportionality" by simp
qed
lemma cltn2_rep_abs2:
assumes "invertible A"
shows "∃ k. k ≠ 0 ∧ cltn2_rep (cltn2_abs A) = k *⇩R A"
proof -
from ‹invertible A› and cltn2_rep_abs
have "(A, cltn2_rep (cltn2_abs A)) ∈ invertible_proportionality" by simp
then obtain c where "A = c *⇩R cltn2_rep (cltn2_abs A)"
unfolding invertible_proportionality_def and real_vector.proportionality_def
by auto
with ‹invertible A› and zero_not_invertible have "c ≠ 0" by auto
hence "1/c ≠ 0" by simp
let ?k = "1/c"
from ‹A = c *⇩R cltn2_rep (cltn2_abs A)›
have "?k *⇩R A = ?k *⇩R c *⇩R cltn2_rep (cltn2_abs A)" by simp
with ‹c ≠ 0› have "cltn2_rep (cltn2_abs A) = ?k *⇩R A" by simp
with ‹?k ≠ 0›
show "∃ k. k ≠ 0 ∧ cltn2_rep (cltn2_abs A) = k *⇩R A" by blast
qed
lemma cltn2_abs_rep: "cltn2_abs (cltn2_rep A) = A"
proof -
from partition_Image_element
[of "Collect invertible"
invertible_proportionality
"Rep_cltn2 A"
"cltn2_rep A"]
and invertible_proportionality_equiv
and Rep_cltn2 [of A] and cltn2_rep_in [of A]
have "invertible_proportionality `` {cltn2_rep A} = Rep_cltn2 A"
by simp
with Rep_cltn2_inverse
show "cltn2_abs (cltn2_rep A) = A"
unfolding cltn2_abs_def
by simp
qed
lemma cltn2_abs_mult:
assumes "k ≠ 0" and "invertible A"
shows "cltn2_abs (k *⇩R A) = cltn2_abs A"
proof -
from ‹k ≠ 0› and ‹invertible A› and scalar_invertible
have "invertible (k *⇩R A)" by auto
with ‹invertible A›
have "(k *⇩R A, A) ∈ invertible_proportionality"
unfolding invertible_proportionality_def
and real_vector.proportionality_def
by (auto simp add: zero_not_invertible)
with eq_equiv_class_iff
[of "Collect invertible" invertible_proportionality "k *⇩R A" A]
and invertible_proportionality_equiv
and ‹invertible A› and ‹invertible (k *⇩R A)›
have "invertible_proportionality `` {k *⇩R A}
= invertible_proportionality `` {A}"
by simp
thus "cltn2_abs (k *⇩R A) = cltn2_abs A"
unfolding cltn2_abs_def
by simp
qed
lemma cltn2_abs_mult_rep:
assumes "k ≠ 0"
shows "cltn2_abs (k *⇩R cltn2_rep A) = A"
using cltn2_rep_invertible and cltn2_abs_mult and cltn2_abs_rep and assms
by simp
lemma apply_cltn2_abs:
assumes "x ≠ 0" and "invertible A"
shows "apply_cltn2 (proj2_abs x) (cltn2_abs A) = proj2_abs (x v* A)"
proof -
from proj2_rep_abs2 and ‹x ≠ 0›
obtain k where "k ≠ 0" and "proj2_rep (proj2_abs x) = k *⇩R x" by auto
from cltn2_rep_abs2 and ‹invertible A›
obtain c where "c ≠ 0" and "cltn2_rep (cltn2_abs A) = c *⇩R A" by auto
from ‹k ≠ 0› and ‹c ≠ 0› have "k * c ≠ 0" by simp
from ‹proj2_rep (proj2_abs x) = k *⇩R x› and ‹cltn2_rep (cltn2_abs A) = c *⇩R A›
have "proj2_rep (proj2_abs x) v* cltn2_rep (cltn2_abs A) = (k*c) *⇩R (x v* A)"
by (simp add: scaleR_vector_matrix_assoc vector_scaleR_matrix_ac)
with ‹k * c ≠ 0›
show "apply_cltn2 (proj2_abs x) (cltn2_abs A) = proj2_abs (x v* A)"
unfolding apply_cltn2_def
by (simp add: proj2_abs_mult)
qed
lemma apply_cltn2_left_abs:
assumes "v ≠ 0"
shows "apply_cltn2 (proj2_abs v) C = proj2_abs (v v* cltn2_rep C)"
proof -
have "cltn2_abs (cltn2_rep C) = C" by (rule cltn2_abs_rep)
with ‹v ≠ 0› and cltn2_rep_invertible and apply_cltn2_abs [of v "cltn2_rep C"]
show "apply_cltn2 (proj2_abs v) C = proj2_abs (v v* cltn2_rep C)"
by simp
qed
lemma apply_cltn2_right_abs:
assumes "invertible M"
shows "apply_cltn2 p (cltn2_abs M) = proj2_abs (proj2_rep p v* M)"
proof -
from proj2_rep_non_zero and ‹invertible M› and apply_cltn2_abs
have "apply_cltn2 (proj2_abs (proj2_rep p)) (cltn2_abs M)
= proj2_abs (proj2_rep p v* M)"
by simp
thus "apply_cltn2 p (cltn2_abs M) = proj2_abs (proj2_rep p v* M)"
by (simp add: proj2_abs_rep)
qed
lemma non_zero_mult_rep_non_zero:
assumes "v ≠ 0"
shows "v v* cltn2_rep C ≠ 0"
using ‹v ≠ 0› and cltn2_rep_invertible and times_invertible_eq_zero
by auto
lemma rep_mult_rep_non_zero: "proj2_rep p v* cltn2_rep A ≠ 0"
using proj2_rep_non_zero
by (rule non_zero_mult_rep_non_zero)
definition cltn2_image :: "proj2 set ⇒ cltn2 ⇒ proj2 set" where
"cltn2_image P A ≡ {apply_cltn2 p A | p. p ∈ P}"
subsubsection "As a group"
definition cltn2_id :: cltn2 where
"cltn2_id ≡ cltn2_abs (mat 1)"
definition cltn2_compose :: "cltn2 ⇒ cltn2 ⇒ cltn2" where
"cltn2_compose A B ≡ cltn2_abs (cltn2_rep A ** cltn2_rep B)"
definition cltn2_inverse :: "cltn2 ⇒ cltn2" where
"cltn2_inverse A ≡ cltn2_abs (matrix_inv (cltn2_rep A))"
lemma cltn2_compose_abs:
assumes "invertible M" and "invertible N"
shows "cltn2_compose (cltn2_abs M) (cltn2_abs N) = cltn2_abs (M ** N)"
proof -
from ‹invertible M› and ‹invertible N› and invertible_mult
have "invertible (M ** N)" by auto
from ‹invertible M› and ‹invertible N› and cltn2_rep_abs2
obtain j and k where "j ≠ 0" and "k ≠ 0"
and "cltn2_rep (cltn2_abs M) = j *⇩R M"
and "cltn2_rep (cltn2_abs N) = k *⇩R N"
by blast
from ‹j ≠ 0› and ‹k ≠ 0› have "j * k ≠ 0" by simp
from ‹cltn2_rep (cltn2_abs M) = j *⇩R M› and ‹cltn2_rep (cltn2_abs N) = k *⇩R N›
have "cltn2_rep (cltn2_abs M) ** cltn2_rep (cltn2_abs N)
= (j * k) *⇩R (M ** N)"
by (simp add: matrix_scalar_ac scalar_matrix_assoc [symmetric])
with ‹j * k ≠ 0› and ‹invertible (M ** N)›
show "cltn2_compose (cltn2_abs M) (cltn2_abs N) = cltn2_abs (M ** N)"
unfolding cltn2_compose_def
by (simp add: cltn2_abs_mult)
qed
lemma cltn2_compose_left_abs:
assumes "invertible M"
shows "cltn2_compose (cltn2_abs M) A = cltn2_abs (M ** cltn2_rep A)"
proof -
from ‹invertible M› and cltn2_rep_invertible and cltn2_compose_abs
have "cltn2_compose (cltn2_abs M) (cltn2_abs (cltn2_rep A))
= cltn2_abs (M ** cltn2_rep A)"
by simp
thus "cltn2_compose (cltn2_abs M) A = cltn2_abs (M ** cltn2_rep A)"
by (simp add: cltn2_abs_rep)
qed
lemma cltn2_compose_right_abs:
assumes "invertible M"
shows "cltn2_compose A (cltn2_abs M) = cltn2_abs (cltn2_rep A ** M)"
proof -
from ‹invertible M› and cltn2_rep_invertible and cltn2_compose_abs
have "cltn2_compose (cltn2_abs (cltn2_rep A)) (cltn2_abs M)
= cltn2_abs (cltn2_rep A ** M)"
by simp
thus "cltn2_compose A (cltn2_abs M) = cltn2_abs (cltn2_rep A ** M)"
by (simp add: cltn2_abs_rep)
qed
lemma cltn2_abs_rep_abs_mult:
assumes "invertible M" and "invertible N"
shows "cltn2_abs (cltn2_rep (cltn2_abs M) ** N) = cltn2_abs (M ** N)"
proof -
from ‹invertible M› and ‹invertible N›
have "invertible (M ** N)" by (simp add: invertible_mult)
from ‹invertible M› and cltn2_rep_abs2
obtain k where "k ≠ 0" and "cltn2_rep (cltn2_abs M) = k *⇩R M" by auto
from ‹cltn2_rep (cltn2_abs M) = k *⇩R M›
have "cltn2_rep (cltn2_abs M) ** N = k *⇩R M ** N" by simp
with ‹k ≠ 0› and ‹invertible (M ** N)› and cltn2_abs_mult
show "cltn2_abs (cltn2_rep (cltn2_abs M) ** N) = cltn2_abs (M ** N)"
by (simp add: scalar_matrix_assoc [symmetric])
qed
lemma cltn2_assoc:
"cltn2_compose (cltn2_compose A B) C = cltn2_compose A (cltn2_compose B C)"
proof -
let ?A' = "cltn2_rep A"
let ?B' = "cltn2_rep B"
let ?C' = "cltn2_rep C"
from cltn2_rep_invertible
have "invertible ?A'" and "invertible ?B'" and "invertible ?C'" by simp_all
with invertible_mult
have "invertible (?A' ** ?B')" and "invertible (?B' ** ?C')"
and "invertible (?A' ** ?B' ** ?C')"
by auto
from ‹invertible (?A' ** ?B')› and ‹invertible ?C'› and cltn2_abs_rep_abs_mult
have "cltn2_abs (cltn2_rep (cltn2_abs (?A' ** ?B')) ** ?C')
= cltn2_abs (?A' ** ?B' ** ?C')"
by simp
from ‹invertible (?B' ** ?C')› and cltn2_rep_abs2 [of "?B' ** ?C'"]
obtain k where "k ≠ 0"
and "cltn2_rep (cltn2_abs (?B' ** ?C')) = k *⇩R (?B' ** ?C')"
by auto
from ‹cltn2_rep (cltn2_abs (?B' ** ?C')) = k *⇩R (?B' ** ?C')›
have "?A' ** cltn2_rep (cltn2_abs (?B' ** ?C')) = k *⇩R (?A' ** ?B' ** ?C')"
by (simp add: matrix_scalar_ac matrix_mul_assoc scalar_matrix_assoc)
with ‹k ≠ 0› and ‹invertible (?A' ** ?B' ** ?C')›
and cltn2_abs_mult [of k "?A' ** ?B' ** ?C'"]
have "cltn2_abs (?A' ** cltn2_rep (cltn2_abs (?B' ** ?C')))
= cltn2_abs (?A' ** ?B' ** ?C')"
by simp
with ‹cltn2_abs (cltn2_rep (cltn2_abs (?A' ** ?B')) ** ?C')
= cltn2_abs (?A' ** ?B' ** ?C')›
show
"cltn2_compose (cltn2_compose A B) C = cltn2_compose A (cltn2_compose B C)"
unfolding cltn2_compose_def
by simp
qed
lemma cltn2_left_id: "cltn2_compose cltn2_id A = A"
proof -
let ?A' = "cltn2_rep A"
from cltn2_rep_invertible have "invertible ?A'" by simp
with matrix_id_invertible and cltn2_abs_rep_abs_mult [of "mat 1" ?A']
have "cltn2_compose cltn2_id A = cltn2_abs (cltn2_rep A)"
unfolding cltn2_compose_def and cltn2_id_def
by (auto simp add: matrix_mul_lid)
with cltn2_abs_rep show "cltn2_compose cltn2_id A = A" by simp
qed
lemma cltn2_left_inverse: "cltn2_compose (cltn2_inverse A) A = cltn2_id"
proof -
let ?M = "cltn2_rep A"
let ?M' = "matrix_inv ?M"
from cltn2_rep_invertible have "invertible ?M" by simp
with matrix_inv_invertible have "invertible ?M'" by auto
with ‹invertible ?M› and cltn2_abs_rep_abs_mult
have "cltn2_compose (cltn2_inverse A) A = cltn2_abs (?M' ** ?M)"
unfolding cltn2_compose_def and cltn2_inverse_def
by simp
with ‹invertible ?M›
show "cltn2_compose (cltn2_inverse A) A = cltn2_id"
unfolding cltn2_id_def
by (simp add: matrix_inv)
qed
lemma cltn2_left_inverse_ex:
"∃ B. cltn2_compose B A = cltn2_id"
using cltn2_left_inverse ..
interpretation cltn2:
group "(|carrier = UNIV, mult = cltn2_compose, one = cltn2_id|)"
using cltn2_assoc and cltn2_left_id and cltn2_left_inverse_ex
and groupI [of "(|carrier = UNIV, mult = cltn2_compose, one = cltn2_id|)"]
by simp_all
lemma cltn2_inverse_inv [simp]:
"inv⇘(|carrier = UNIV, mult = cltn2_compose, one = cltn2_id|)⇙ A
= cltn2_inverse A"
using cltn2_left_inverse [of A] and cltn2.inv_equality
by simp
lemmas cltn2_inverse_id [simp] = cltn2.inv_one [simplified]
and cltn2_inverse_compose = cltn2.inv_mult_group [simplified]
subsubsection "As a group action"
lemma apply_cltn2_id [simp]: "apply_cltn2 p cltn2_id = p"
proof -
from matrix_id_invertible and apply_cltn2_right_abs
have "apply_cltn2 p cltn2_id = proj2_abs (proj2_rep p v* mat 1)"
unfolding cltn2_id_def by blast
thus "apply_cltn2 p cltn2_id = p"
by (simp add: proj2_abs_rep)
qed
lemma apply_cltn2_compose:
"apply_cltn2 (apply_cltn2 p A) B = apply_cltn2 p (cltn2_compose A B)"
proof -
from rep_mult_rep_non_zero and cltn2_rep_invertible and apply_cltn2_abs
have "apply_cltn2 (apply_cltn2 p A) (cltn2_abs (cltn2_rep B))
= proj2_abs ((proj2_rep p v* cltn2_rep A) v* cltn2_rep B)"
unfolding apply_cltn2_def [of p A]
by simp
hence "apply_cltn2 (apply_cltn2 p A) B
= proj2_abs (proj2_rep p v* (cltn2_rep A ** cltn2_rep B))"
by (simp add: cltn2_abs_rep vector_matrix_mul_assoc)
from cltn2_rep_invertible and invertible_mult
have "invertible (cltn2_rep A ** cltn2_rep B)" by auto
with apply_cltn2_right_abs
have "apply_cltn2 p (cltn2_compose A B)
= proj2_abs (proj2_rep p v* (cltn2_rep A ** cltn2_rep B))"
unfolding cltn2_compose_def
by simp
with ‹apply_cltn2 (apply_cltn2 p A) B
= proj2_abs (proj2_rep p v* (cltn2_rep A ** cltn2_rep B))›
show "apply_cltn2 (apply_cltn2 p A) B = apply_cltn2 p (cltn2_compose A B)"
by simp
qed
interpretation cltn2:
action "(|carrier = UNIV, mult = cltn2_compose, one = cltn2_id|)" apply_cltn2
proof
let ?G = "(|carrier = UNIV, mult = cltn2_compose, one = cltn2_id|)"
fix p
show "apply_cltn2 p 𝟭⇘?G⇙ = p" by simp
fix A B
have "apply_cltn2 (apply_cltn2 p A) B = apply_cltn2 p (A ⊗⇘?G⇙ B)"
by simp (rule apply_cltn2_compose)
thus "A ∈ carrier ?G ∧ B ∈ carrier ?G
⟶ apply_cltn2 (apply_cltn2 p A) B = apply_cltn2 p (A ⊗⇘?G⇙ B)"
..
qed
definition cltn2_transpose :: "cltn2 ⇒ cltn2" where
"cltn2_transpose A ≡ cltn2_abs (transpose (cltn2_rep A))"
definition apply_cltn2_line :: "proj2_line ⇒ cltn2 ⇒ proj2_line" where
"apply_cltn2_line l A
≡ P2L (apply_cltn2 (L2P l) (cltn2_transpose (cltn2_inverse A)))"
lemma cltn2_transpose_abs:
assumes "invertible M"
shows "cltn2_transpose (cltn2_abs M) = cltn2_abs (transpose M)"
proof -
from ‹invertible M› and transpose_invertible have "invertible (transpose M)" by auto
from ‹invertible M› and cltn2_rep_abs2
obtain k where "k ≠ 0" and "cltn2_rep (cltn2_abs M) = k *⇩R M" by auto
from ‹cltn2_rep (cltn2_abs M) = k *⇩R M›
have "transpose (cltn2_rep (cltn2_abs M)) = k *⇩R transpose M"
by (simp add: transpose_scalar)
with ‹k ≠ 0› and ‹invertible (transpose M)›
show "cltn2_transpose (cltn2_abs M) = cltn2_abs (transpose M)"
unfolding cltn2_transpose_def
by (simp add: cltn2_abs_mult)
qed
lemma cltn2_transpose_compose:
"cltn2_transpose (cltn2_compose A B)
= cltn2_compose (cltn2_transpose B) (cltn2_transpose A)"
proof -
from cltn2_rep_invertible
have "invertible (cltn2_rep A)" and "invertible (cltn2_rep B)"
by simp_all
with transpose_invertible
have "invertible (transpose (cltn2_rep A))"
and "invertible (transpose (cltn2_rep B))"
by auto
from ‹invertible (cltn2_rep A)› and ‹invertible (cltn2_rep B)›
and invertible_mult
have "invertible (cltn2_rep A ** cltn2_rep B)" by auto
with ‹invertible (cltn2_rep A ** cltn2_rep B)› and cltn2_transpose_abs
have "cltn2_transpose (cltn2_compose A B)
= cltn2_abs (transpose (cltn2_rep A ** cltn2_rep B))"
unfolding cltn2_compose_def
by simp
also have "… = cltn2_abs (transpose (cltn2_rep B) ** transpose (cltn2_rep A))"
by (simp add: matrix_transpose_mul)
also from ‹invertible (transpose (cltn2_rep B))›
and ‹invertible (transpose (cltn2_rep A))›
and cltn2_compose_abs
have "… = cltn2_compose (cltn2_transpose B) (cltn2_transpose A)"
unfolding cltn2_transpose_def
by simp
finally show "cltn2_transpose (cltn2_compose A B)
= cltn2_compose (cltn2_transpose B) (cltn2_transpose A)" .
qed
lemma cltn2_transpose_transpose: "cltn2_transpose (cltn2_transpose A) = A"
proof -
from cltn2_rep_invertible have "invertible (cltn2_rep A)" by simp
with transpose_invertible have "invertible (transpose (cltn2_rep A))" by auto
with cltn2_transpose_abs [of "transpose (cltn2_rep A)"]
have
"cltn2_transpose (cltn2_transpose A) = cltn2_abs (transpose (transpose (cltn2_rep A)))"
unfolding cltn2_transpose_def [of A]
by simp
with cltn2_abs_rep and transpose_transpose [of "cltn2_rep A"]
show "cltn2_transpose (cltn2_transpose A) = A" by simp
qed
lemma cltn2_transpose_id [simp]: "cltn2_transpose cltn2_id = cltn2_id"
using cltn2_transpose_abs
unfolding cltn2_id_def
by (simp add: transpose_mat matrix_id_invertible)
lemma apply_cltn2_line_id [simp]: "apply_cltn2_line l cltn2_id = l"
unfolding apply_cltn2_line_def
by simp
lemma apply_cltn2_line_compose:
"apply_cltn2_line (apply_cltn2_line l A) B
= apply_cltn2_line l (cltn2_compose A B)"
proof -
have "cltn2_compose
(cltn2_transpose (cltn2_inverse A)) (cltn2_transpose (cltn2_inverse B))
= cltn2_transpose (cltn2_inverse (cltn2_compose A B))"
by (simp add: cltn2_transpose_compose cltn2_inverse_compose)
thus "apply_cltn2_line (apply_cltn2_line l A) B
= apply_cltn2_line l (cltn2_compose A B)"
unfolding apply_cltn2_line_def
by (simp add: apply_cltn2_compose)
qed
interpretation cltn2_line:
action
"(|carrier = UNIV, mult = cltn2_compose, one = cltn2_id|)"
apply_cltn2_line
proof
let ?G = "(|carrier = UNIV, mult = cltn2_compose, one = cltn2_id|)"
fix l
show "apply_cltn2_line l 𝟭⇘?G⇙ = l" by simp
fix A B
have "apply_cltn2_line (apply_cltn2_line l A) B
= apply_cltn2_line l (A ⊗⇘?G⇙ B)"
by simp (rule apply_cltn2_line_compose)
thus "A ∈ carrier ?G ∧ B ∈ carrier ?G
⟶ apply_cltn2_line (apply_cltn2_line l A) B
= apply_cltn2_line l (A ⊗⇘?G⇙ B)"
..
qed
lemmas apply_cltn2_inv [simp] = cltn2.act_act_inv [simplified]
lemmas apply_cltn2_line_inv [simp] = cltn2_line.act_act_inv [simplified]
lemma apply_cltn2_line_alt_def:
"apply_cltn2_line l A
= proj2_line_abs (cltn2_rep (cltn2_inverse A) *v proj2_line_rep l)"
proof -
have "invertible (cltn2_rep (cltn2_inverse A))" by (rule cltn2_rep_invertible)
hence "invertible (transpose (cltn2_rep (cltn2_inverse A)))"
by (rule transpose_invertible)
hence
"apply_cltn2 (L2P l) (cltn2_transpose (cltn2_inverse A))
= proj2_abs (proj2_rep (L2P l) v* transpose (cltn2_rep (cltn2_inverse A)))"
unfolding cltn2_transpose_def
by (rule apply_cltn2_right_abs)
hence "apply_cltn2 (L2P l) (cltn2_transpose (cltn2_inverse A))
= proj2_abs (cltn2_rep (cltn2_inverse A) *v proj2_line_rep l)"
unfolding proj2_line_rep_def
by simp
thus "apply_cltn2_line l A
= proj2_line_abs (cltn2_rep (cltn2_inverse A) *v proj2_line_rep l)"
unfolding apply_cltn2_line_def and proj2_line_abs_def ..
qed
lemma rep_mult_line_rep_non_zero: "cltn2_rep A *v proj2_line_rep l ≠ 0"
using proj2_line_rep_non_zero and cltn2_rep_invertible
and invertible_times_eq_zero
by auto
lemma apply_cltn2_incident:
"proj2_incident p (apply_cltn2_line l A)
⟷ proj2_incident (apply_cltn2 p (cltn2_inverse A)) l"
proof -
have "proj2_rep p v* cltn2_rep (cltn2_inverse A) ≠ 0"
by (rule rep_mult_rep_non_zero)
with proj2_rep_abs2
obtain j where "j ≠ 0"
and "proj2_rep (proj2_abs (proj2_rep p v* cltn2_rep (cltn2_inverse A)))
= j *⇩R (proj2_rep p v* cltn2_rep (cltn2_inverse A))"
by auto
let ?v = "cltn2_rep (cltn2_inverse A) *v proj2_line_rep l"
have "?v ≠ 0" by (rule rep_mult_line_rep_non_zero)
with proj2_line_rep_abs [of ?v]
obtain k where "k ≠ 0"
and "proj2_line_rep (proj2_line_abs ?v) = k *⇩R ?v"
by auto
hence "proj2_incident p (apply_cltn2_line l A)
⟷ proj2_rep p ∙ (cltn2_rep (cltn2_inverse A) *v proj2_line_rep l) = 0"
unfolding proj2_incident_def and apply_cltn2_line_alt_def
by (simp add: dot_scaleR_mult)
also from dot_lmul_matrix [of "proj2_rep p" "cltn2_rep (cltn2_inverse A)"]
have
"… ⟷ (proj2_rep p v* cltn2_rep (cltn2_inverse A)) ∙ proj2_line_rep l = 0"
by simp
also from ‹j ≠ 0›
and ‹proj2_rep (proj2_abs (proj2_rep p v* cltn2_rep (cltn2_inverse A)))
= j *⇩R (proj2_rep p v* cltn2_rep (cltn2_inverse A))›
have "… ⟷ proj2_incident (apply_cltn2 p (cltn2_inverse A)) l"
unfolding proj2_incident_def and apply_cltn2_def
by (simp add: dot_scaleR_mult)
finally show ?thesis .
qed
lemma apply_cltn2_preserve_incident [iff]:
"proj2_incident (apply_cltn2 p A) (apply_cltn2_line l A)
⟷ proj2_incident p l"
by (simp add: apply_cltn2_incident)
lemma apply_cltn2_preserve_set_Col:
assumes "proj2_set_Col S"
shows "proj2_set_Col {apply_cltn2 p C | p. p ∈ S}"
proof -
from ‹proj2_set_Col S›
obtain l where "∀ p∈S. proj2_incident p l" unfolding proj2_set_Col_def ..
hence "∀ q ∈ {apply_cltn2 p C | p. p ∈ S}.
proj2_incident q (apply_cltn2_line l C)"
by auto
thus "proj2_set_Col {apply_cltn2 p C | p. p ∈ S}"
unfolding proj2_set_Col_def ..
qed
lemma apply_cltn2_injective:
assumes "apply_cltn2 p C = apply_cltn2 q C"
shows "p = q"
proof -
from ‹apply_cltn2 p C = apply_cltn2 q C›
have "apply_cltn2 (apply_cltn2 p C) (cltn2_inverse C)
= apply_cltn2 (apply_cltn2 q C) (cltn2_inverse C)"
by simp
thus "p = q" by simp
qed
lemma apply_cltn2_line_injective:
assumes "apply_cltn2_line l C = apply_cltn2_line m C"
shows "l = m"
proof -
from ‹apply_cltn2_line l C = apply_cltn2_line m C›
have "apply_cltn2_line (apply_cltn2_line l C) (cltn2_inverse C)
= apply_cltn2_line (apply_cltn2_line m C) (cltn2_inverse C)"
by simp
thus "l = m" by simp
qed
lemma apply_cltn2_line_unique:
assumes "p ≠ q" and "proj2_incident p l" and "proj2_incident q l"
and "proj2_incident (apply_cltn2 p C) m"
and "proj2_incident (apply_cltn2 q C) m"
shows "apply_cltn2_line l C = m"
proof -
from ‹proj2_incident p l›
have "proj2_incident (apply_cltn2 p C) (apply_cltn2_line l C)" by simp
from ‹proj2_incident q l›
have "proj2_incident (apply_cltn2 q C) (apply_cltn2_line l C)" by simp
from ‹p ≠ q› and apply_cltn2_injective [of p C q]
have "apply_cltn2 p C ≠ apply_cltn2 q C" by auto
with ‹proj2_incident (apply_cltn2 p C) (apply_cltn2_line l C)›
and ‹proj2_incident (apply_cltn2 q C) (apply_cltn2_line l C)›
and ‹proj2_incident (apply_cltn2 p C) m›
and ‹proj2_incident (apply_cltn2 q C) m›
and proj2_incident_unique
show "apply_cltn2_line l C = m" by fast
qed
lemma apply_cltn2_unique:
assumes "l ≠ m" and "proj2_incident p l" and "proj2_incident p m"
and "proj2_incident q (apply_cltn2_line l C)"
and "proj2_incident q (apply_cltn2_line m C)"
shows "apply_cltn2 p C = q"
proof -
from ‹proj2_incident p l›
have "proj2_incident (apply_cltn2 p C) (apply_cltn2_line l C)" by simp
from ‹proj2_incident p m›
have "proj2_incident (apply_cltn2 p C) (apply_cltn2_line m C)" by simp
from ‹l ≠ m› and apply_cltn2_line_injective [of l C m]
have "apply_cltn2_line l C ≠ apply_cltn2_line m C" by auto
with ‹proj2_incident (apply_cltn2 p C) (apply_cltn2_line l C)›
and ‹proj2_incident (apply_cltn2 p C) (apply_cltn2_line m C)›
and ‹proj2_incident q (apply_cltn2_line l C)›
and ‹proj2_incident q (apply_cltn2_line m C)›
and proj2_incident_unique
show "apply_cltn2 p C = q" by fast
qed
subsubsection ‹Parts of some Statements from \<^cite>‹"borsuk"››
text ‹All theorems with names beginning with \emph{statement} are based
on corresponding theorems in \<^cite>‹"borsuk"›.›
lemma statement52_existence:
fixes a :: "proj2^3" and a3 :: "proj2"
assumes "proj2_no_3_Col (insert a3 (range (($) a)))"
shows "∃ A. apply_cltn2 (proj2_abs (vector [1,1,1])) A = a3 ∧
(∀ j. apply_cltn2 (proj2_abs (axis j 1)) A = a$j)"
proof -
let ?v = "proj2_rep a3"
let ?B = "proj2_rep ` range (($) a)"
from ‹proj2_no_3_Col (insert a3 (range (($) a)))›
have "card (insert a3 (range (($) a))) = 4" unfolding proj2_no_3_Col_def ..
from card_image_le [of UNIV "($) a"]
have "card (range (($) a)) ≤ 3" by simp
with card_insert_if [of "range (($) a)" a3]
and ‹card (insert a3 (range (($) a))) = 4›
have "a3 ∉ range (($) a)" by auto
hence "(insert a3 (range (($) a))) - {a3} = range (($) a)" by simp
with ‹proj2_no_3_Col (insert a3 (range (($) a)))›
and proj2_no_3_Col_span [of "insert a3 (range (($) a))" a3]
have "span ?B = UNIV" by simp
from card_suc_ge_insert [of a3 "range (($) a)"]
and ‹card (insert a3 (range (($) a))) = 4›
and ‹card (range (($) a)) ≤ 3›
have "card (range (($) a)) = 3" by simp
with card_image [of proj2_rep "range (($) a)"]
and proj2_rep_inj
and subset_inj_on
have "card ?B = 3" by auto
hence "finite ?B" by simp
with ‹span ?B = UNIV› and span_finite [of ?B]
obtain c where "(∑ w ∈ ?B. (c w) *⇩R w) = ?v"
by (auto simp add: scalar_equiv) (metis (no_types, lifting) UNIV_I rangeE)
let ?C = "χ i. c (proj2_rep (a$i)) *⇩R (proj2_rep (a$i))"
let ?A = "cltn2_abs ?C"
from proj2_rep_inj and ‹a3 ∉ range (($) a)› have "?v ∉ ?B"
unfolding inj_on_def
by auto
have "∀ i. c (proj2_rep (a$i)) ≠ 0"
proof
fix i
let ?Bi = "proj2_rep ` (range (($) a) - {a$i})"
have "a$i ∈ insert a3 (range (($) a))" by simp
have "proj2_rep (a$i) ∈ ?B" by auto
from image_set_diff [of proj2_rep] and proj2_rep_inj
have "?Bi = ?B - {proj2_rep (a$i)}" by simp
with sum_diff1 [of ?B "λ w. (c w) *⇩R w"]
and ‹finite ?B›
and ‹proj2_rep (a$i) ∈ ?B›
have "(∑ w ∈ ?Bi. (c w) *⇩R w) =
(∑ w ∈ ?B. (c w) *⇩R w) - c (proj2_rep (a$i)) *⇩R proj2_rep (a$i)"
by simp
from ‹a3 ∉ range (($) a)› have "a3 ≠ a$i" by auto
hence "insert a3 (range (($) a)) - {a$i} =
insert a3 (range (($) a) - {a$i})" by auto
hence "proj2_rep ` (insert a3 (range (($) a)) - {a$i}) = insert ?v ?Bi"
by simp
moreover from ‹proj2_no_3_Col (insert a3 (range (($) a)))›
and ‹a$i ∈ insert a3 (range (($) a))›
have "span (proj2_rep ` (insert a3 (range (($) a)) - {a$i})) = UNIV"
by (rule proj2_no_3_Col_span)
ultimately have "span (insert ?v ?Bi) = UNIV" by simp
from ‹?Bi = ?B - {proj2_rep (a$i)}›
and ‹proj2_rep (a$i) ∈ ?B›
and ‹card ?B = 3›
have "card ?Bi = 2" by (simp add: card_gt_0_diff_singleton)
hence "finite ?Bi" by simp
with ‹card ?Bi = 2› and dim_le_card' [of ?Bi] have "dim ?Bi ≤ 2" by simp
hence "dim (span ?Bi) ≤ 2" by (subst dim_span)
then have "span ?Bi ≠ UNIV"
by clarify (auto simp: dim_UNIV)
with ‹span (insert ?v ?Bi) = UNIV› and span_redundant
have "?v ∉ span ?Bi" by auto
{ assume "c (proj2_rep (a$i)) = 0"
with ‹(∑ w ∈ ?Bi. (c w) *⇩R w) =
(∑ w ∈ ?B. (c w) *⇩R w) - c (proj2_rep (a$i)) *⇩R proj2_rep (a$i)›
and ‹(∑ w ∈ ?B. (c w) *⇩R w) = ?v›
have "?v = (∑ w ∈ ?Bi. (c w) *⇩R w)"
by simp
with span_finite [of ?Bi] and ‹finite ?Bi›
have "?v ∈ span ?Bi" by (simp add: scalar_equiv)
with ‹?v ∉ span ?Bi› have False .. }
thus "c (proj2_rep (a$i)) ≠ 0" ..
qed
hence "∀ w∈?B. c w ≠ 0"
unfolding image_def
by auto
have "rows ?C = (λ w. (c w) *⇩R w) ` ?B"
unfolding rows_def
and row_def
and image_def
by (auto simp: vec_lambda_eta)
have "∀ x. x ∈ span (rows ?C)"
proof
fix x :: "real^3"
from ‹finite ?B› and span_finite [of ?B] and ‹span ?B = UNIV›
obtain ub where "(∑ w∈?B. (ub w) *⇩R w) = x"
by (auto simp add: scalar_equiv) (metis (no_types, lifting) UNIV_I rangeE)
have "∀ w∈?B. (ub w) *⇩R w ∈ span (rows ?C)"
proof
fix w
assume "w ∈ ?B"
with span_superset [of "rows ?C"] and ‹rows ?C = image (λ w. (c w) *⇩R w) ?B›
have "(c w) *⇩R w ∈ span (rows ?C)" by auto
with span_mul [of "(c w) *⇩R w" "rows ?C" "(ub w)/(c w)"]
have "((ub w)/(c w)) *⇩R ((c w) *⇩R w) ∈ span (rows ?C)"
by (simp add: scalar_equiv)
with ‹∀ w∈?B. c w ≠ 0› and ‹w ∈ ?B›
show "(ub w) *⇩R w ∈ span (rows ?C)" by auto
qed
with span_sum [of ?B "λ w. (ub w) *⇩R w"] and ‹finite ?B›
have "(∑ w∈?B. (ub w) *⇩R w) ∈ span (rows ?C)" by blast
with ‹(∑ w∈?B. (ub w) *⇩R w) = x› show "x ∈ span (rows ?C)" by simp
qed
hence "span (rows ?C) = UNIV" by auto
with matrix_left_invertible_span_rows [of ?C]
have "∃ C'. C' ** ?C = mat 1" ..
with left_invertible_iff_invertible
have "invertible ?C" ..
have "(vector [1,1,1] :: real^3) ≠ 0"
unfolding vector_def
by (simp add: vec_eq_iff forall_3)
with apply_cltn2_abs and ‹invertible ?C›
have "apply_cltn2 (proj2_abs (vector [1,1,1])) ?A =
proj2_abs (vector [1,1,1] v* ?C)"
by simp
from inj_on_iff_eq_card [of UNIV "($) a"] and ‹card (range (($) a)) = 3›
have "inj (($) a)" by simp
from exhaust_3 have "∀ i::3. (vector [1::real,1,1])$i = 1"
unfolding vector_def
by auto
with vector_matrix_row [of "vector [1,1,1]" ?C]
have "(vector [1,1,1]) v* ?C =
(∑ i∈UNIV. (c (proj2_rep (a$i))) *⇩R (proj2_rep (a$i)))"
by simp
also from sum.reindex
[of "($) a" UNIV "λ x. (c (proj2_rep x)) *⇩R (proj2_rep x)"]
and ‹inj (($) a)›
have "… = (∑ x∈(range (($) a)). (c (proj2_rep x)) *⇩R (proj2_rep x))"
by simp
also from sum.reindex
[of proj2_rep "range (($) a)" "λ w. (c w) *⇩R w"]
and proj2_rep_inj and subset_inj_on [of proj2_rep UNIV "range (($) a)"]
have "… = (∑ w∈?B. (c w) *⇩R w)" by simp
also from ‹(∑ w ∈ ?B. (c w) *⇩R w) = ?v› have "… = ?v" by simp
finally have "(vector [1,1,1]) v* ?C = ?v" .
with ‹apply_cltn2 (proj2_abs (vector [1,1,1])) ?A =
proj2_abs (vector [1,1,1] v* ?C)›
have "apply_cltn2 (proj2_abs (vector [1,1,1])) ?A = proj2_abs ?v" by simp
with proj2_abs_rep have "apply_cltn2 (proj2_abs (vector [1,1,1])) ?A = a3"
by simp
have "∀ j. apply_cltn2 (proj2_abs (axis j 1)) ?A = a$j"
proof
fix j :: "3"
have "((axis j 1)::real^3) ≠ 0" by (simp add: vec_eq_iff axis_def)
with apply_cltn2_abs and ‹invertible ?C›
have "apply_cltn2 (proj2_abs (axis j 1)) ?A = proj2_abs (axis j 1 v* ?C)"
by simp
have "∀ i∈(UNIV-{j}).
((axis j 1)$i * c (proj2_rep (a$i))) *⇩R (proj2_rep (a$i)) = 0"
by (simp add: axis_def)
with sum.mono_neutral_left [of UNIV "{j}"
"λ i. ((axis j 1)$i * c (proj2_rep (a$i))) *⇩R (proj2_rep (a$i))"]
and vector_matrix_row [of "axis j 1" ?C]
have "(axis j 1) v* ?C = ?C$j" by (simp add: scalar_equiv)
hence "(axis j 1) v* ?C = c (proj2_rep (a$j)) *⇩R (proj2_rep (a$j))" by simp
with proj2_abs_mult_rep and ‹∀ i. c (proj2_rep (a$i)) ≠ 0›
and ‹apply_cltn2 (proj2_abs (axis j 1)) ?A = proj2_abs (axis j 1 v* ?C)›
show "apply_cltn2 (proj2_abs (axis j 1)) ?A = a$j"
by simp
qed
with ‹apply_cltn2 (proj2_abs (vector [1,1,1])) ?A = a3›
show "∃ A. apply_cltn2 (proj2_abs (vector [1,1,1])) A = a3 ∧
(∀ j. apply_cltn2 (proj2_abs (axis j 1)) A = a$j)"
by auto
qed
lemma statement53_existence:
fixes p :: "proj2^4^2"
assumes "∀ i. proj2_no_3_Col (range (($) (p$i)))"
shows "∃ C. ∀ j. apply_cltn2 (p$0$j) C = p$1$j"
proof -
let ?q = "χ i. χ j::3. p$i $ (of_int (Rep_bit1 j))"
let ?D = "χ i. ϵ D. apply_cltn2 (proj2_abs (vector [1,1,1])) D = p$i$3
∧ (∀ j'. apply_cltn2 (proj2_abs (axis j' 1)) D = ?q$i$j')"
have "∀ i. apply_cltn2 (proj2_abs (vector [1,1,1])) (?D$i) = p$i$3
∧ (∀ j'. apply_cltn2 (proj2_abs (axis j' 1)) (?D$i) = ?q$i$j')"
proof
fix i
have "range (($) (p$i)) = insert (p$i$3) (range (($) (?q$i)))"
proof
show "range (($) (p$i)) ⊇ insert (p$i$3) (range (($) (?q$i)))" by auto
show "range (($) (p$i)) ⊆ insert (p$i$3) (range (($) (?q$i)))"
proof
fix r
assume "r ∈ range (($) (p$i))"
then obtain j where "r = p$i$j" by auto
with eq_3_or_of_3 [of j]
show "r ∈ insert (p$i$3) (range (($) (?q$i)))" by auto
qed
qed
moreover from ‹∀ i. proj2_no_3_Col (range (($) (p$i)))›
have "proj2_no_3_Col (range (($) (p$i)))" ..
ultimately have "proj2_no_3_Col (insert (p$i$3) (range (($) (?q$i))))"
by simp
hence "∃ D. apply_cltn2 (proj2_abs (vector [1,1,1])) D = p$i$3
∧ (∀ j'. apply_cltn2 (proj2_abs (axis j' 1)) D = ?q$i$j')"
by (rule statement52_existence)
with someI_ex [of "λ D. apply_cltn2 (proj2_abs (vector [1,1,1])) D = p$i$3
∧ (∀ j'. apply_cltn2 (proj2_abs (axis j' 1)) D = ?q$i$j')"]
show "apply_cltn2 (proj2_abs (vector [1,1,1])) (?D$i) = p$i$3
∧ (∀ j'. apply_cltn2 (proj2_abs (axis j' 1)) (?D$i) = ?q$i$j')"
by simp
qed
hence "apply_cltn2 (proj2_abs (vector [1,1,1])) (?D$0) = p$0$3"
and "apply_cltn2 (proj2_abs (vector [1,1,1])) (?D$1) = p$1$3"
and "∀ j'. apply_cltn2 (proj2_abs (axis j' 1)) (?D$0) = ?q$0$j'"
and "∀ j'. apply_cltn2 (proj2_abs (axis j' 1)) (?D$1) = ?q$1$j'"
by simp_all
let ?C = "cltn2_compose (cltn2_inverse (?D$0)) (?D$1)"
have "∀ j. apply_cltn2 (p$0$j) ?C = p$1$j"
proof
fix j
show "apply_cltn2 (p$0$j) ?C = p$1$j"
proof cases
assume "j = 3"
with ‹apply_cltn2 (proj2_abs (vector [1,1,1])) (?D$0) = p$0$3›
and cltn2.act_inv_iff
have
"apply_cltn2 (p$0$j) (cltn2_inverse (?D$0)) = proj2_abs (vector [1,1,1])"
by simp
with ‹apply_cltn2 (proj2_abs (vector [1,1,1])) (?D$1) = p$1$3›
and ‹j = 3›
and cltn2.act_act [of "cltn2_inverse (?D$0)" "?D$1" "p$0$j"]
show "apply_cltn2 (p$0$j) ?C = p$1$j" by simp
next
assume "j ≠ 3"
with eq_3_or_of_3 obtain j' :: 3 where "j = of_int (Rep_bit1 j')"
by metis
with ‹∀ j'. apply_cltn2 (proj2_abs (axis j' 1)) (?D$0) = ?q$0$j'›
and ‹∀ j'. apply_cltn2 (proj2_abs (axis j' 1)) (?D$1) = ?q$1$j'›
have "p$0$j = apply_cltn2 (proj2_abs (axis j' 1)) (?D$0)"
and "p$1$j = apply_cltn2 (proj2_abs (axis j' 1)) (?D$1)"
by simp_all
from ‹p$0$j = apply_cltn2 (proj2_abs (axis j' 1)) (?D$0)›
and cltn2.act_inv_iff
have "apply_cltn2 (p$0$j) (cltn2_inverse (?D$0)) = proj2_abs (axis j' 1)"
by simp
with ‹p$1$j = apply_cltn2 (proj2_abs (axis j' 1)) (?D$1)›
and cltn2.act_act [of "cltn2_inverse (?D$0)" "?D$1" "p$0$j"]
show "apply_cltn2 (p$0$j) ?C = p$1$j" by simp
qed
qed
thus "∃ C. ∀ j. apply_cltn2 (p$0$j) C = p$1$j" by (rule exI [of _ ?C])
qed
lemma apply_cltn2_linear:
assumes "j *⇩R v + k *⇩R w ≠ 0"
shows "j *⇩R (v v* cltn2_rep C) + k *⇩R (w v* cltn2_rep C) ≠ 0"
(is "?u ≠ 0")
and "apply_cltn2 (proj2_abs (j *⇩R v + k *⇩R w)) C
= proj2_abs (j *⇩R (v v* cltn2_rep C) + k *⇩R (w v* cltn2_rep C))"
proof -
have "?u = (j *⇩R v + k *⇩R w) v* cltn2_rep C"
by (simp only: vector_matrix_left_distrib scaleR_vector_matrix_assoc)
with ‹j *⇩R v + k *⇩R w ≠ 0› and non_zero_mult_rep_non_zero
show "?u ≠ 0" by simp
from ‹?u = (j *⇩R v + k *⇩R w) v* cltn2_rep C›
and ‹j *⇩R v + k *⇩R w ≠ 0›
and apply_cltn2_left_abs
show "apply_cltn2 (proj2_abs (j *⇩R v + k *⇩R w)) C = proj2_abs ?u"
by simp
qed
lemma apply_cltn2_imp_mult:
assumes "apply_cltn2 p C = q"
shows "∃ k. k ≠ 0 ∧ proj2_rep p v* cltn2_rep C = k *⇩R proj2_rep q"
proof -
have "proj2_rep p v* cltn2_rep C ≠ 0" by (rule rep_mult_rep_non_zero)
from ‹apply_cltn2 p C = q›
have "proj2_abs (proj2_rep p v* cltn2_rep C) = q" by (unfold apply_cltn2_def)
hence "proj2_rep (proj2_abs (proj2_rep p v* cltn2_rep C)) = proj2_rep q"
by simp
with ‹proj2_rep p v* cltn2_rep C ≠ 0› and proj2_rep_abs2 [of "proj2_rep p v* cltn2_rep C"]
have "∃ j. j ≠ 0 ∧ proj2_rep q = j *⇩R (proj2_rep p v* cltn2_rep C)" by simp
then obtain j where "j ≠ 0"
and "proj2_rep q = j *⇩R (proj2_rep p v* cltn2_rep C)" by auto
hence "proj2_rep p v* cltn2_rep C = (1/j) *⇩R proj2_rep q"
by (simp add: field_simps)
with ‹j ≠ 0›
show "∃ k. k ≠ 0 ∧ proj2_rep p v* cltn2_rep C = k *⇩R proj2_rep q"
by (simp add: exI [of _ "1/j"])
qed
lemma statement55:
assumes "p ≠ q"
and "apply_cltn2 p C = q"
and "apply_cltn2 q C = p"
and "proj2_incident p l"
and "proj2_incident q l"
and "proj2_incident r l"
shows "apply_cltn2 (apply_cltn2 r C) C = r"
proof cases
assume "r = p"
with ‹apply_cltn2 p C = q› and ‹apply_cltn2 q C = p›
show "apply_cltn2 (apply_cltn2 r C) C = r" by simp
next
assume "r ≠ p"
from ‹apply_cltn2 p C = q› and apply_cltn2_imp_mult [of p C q]
obtain i where "i ≠ 0" and "proj2_rep p v* cltn2_rep C = i *⇩R proj2_rep q"
by auto
from ‹apply_cltn2 q C = p› and apply_cltn2_imp_mult [of q C p]
obtain j where "j ≠ 0" and "proj2_rep q v* cltn2_rep C = j *⇩R proj2_rep p"
by auto
from ‹p ≠ q›
and ‹proj2_incident p l›
and ‹proj2_incident q l›
and ‹proj2_incident r l›
and proj2_incident_iff
have "r = p ∨ (∃ k. r = proj2_abs (k *⇩R proj2_rep p + proj2_rep q))"
by fast
with ‹r ≠ p›
obtain k where "r = proj2_abs (k *⇩R proj2_rep p + proj2_rep q)" by auto
from ‹p ≠ q› and proj2_rep_dependent [of k p 1 q]
have "k *⇩R proj2_rep p + proj2_rep q ≠ 0" by auto
with ‹r = proj2_abs (k *⇩R proj2_rep p + proj2_rep q)›
and apply_cltn2_linear [of k "proj2_rep p" 1 "proj2_rep q"]
have "k *⇩R (proj2_rep p v* cltn2_rep C) + proj2_rep q v* cltn2_rep C ≠ 0"
and "apply_cltn2 r C
= proj2_abs
(k *⇩R (proj2_rep p v* cltn2_rep C) + proj2_rep q v* cltn2_rep C)"
by simp_all
with ‹proj2_rep p v* cltn2_rep C = i *⇩R proj2_rep q›
and ‹proj2_rep q v* cltn2_rep C = j *⇩R proj2_rep p›
have "(k * i) *⇩R proj2_rep q + j *⇩R proj2_rep p ≠ 0"
and "apply_cltn2 r C
= proj2_abs ((k * i) *⇩R proj2_rep q + j *⇩R proj2_rep p)"
by simp_all
with apply_cltn2_linear
have "apply_cltn2 (apply_cltn2 r C) C
= proj2_abs
((k * i) *⇩R (proj2_rep q v* cltn2_rep C)
+ j *⇩R (proj2_rep p v* cltn2_rep C))"
by simp
with ‹proj2_rep p v* cltn2_rep C = i *⇩R proj2_rep q›
and ‹proj2_rep q v* cltn2_rep C = j *⇩R proj2_rep p›
have "apply_cltn2 (apply_cltn2 r C) C
= proj2_abs ((k * i * j) *⇩R proj2_rep p + (j * i) *⇩R proj2_rep q)"
by simp
also have "… = proj2_abs ((i * j) *⇩R (k *⇩R proj2_rep p + proj2_rep q))"
by (simp add: algebra_simps)
also from ‹i ≠ 0› and ‹j ≠ 0› and proj2_abs_mult
have "… = proj2_abs (k *⇩R proj2_rep p + proj2_rep q)" by simp
also from ‹r = proj2_abs (k *⇩R proj2_rep p + proj2_rep q)›
have "… = r" by simp
finally show "apply_cltn2 (apply_cltn2 r C) C = r" .
qed
subsection "Cross ratios"
definition cross_ratio :: "proj2 ⇒ proj2 ⇒ proj2 ⇒ proj2 ⇒ real" where
"cross_ratio p q r s ≡ proj2_Col_coeff p q s / proj2_Col_coeff p q r"
definition cross_ratio_correct :: "proj2 ⇒ proj2 ⇒ proj2 ⇒ proj2 ⇒ bool" where
"cross_ratio_correct p q r s ≡
proj2_set_Col {p,q,r,s} ∧ p ≠ q ∧ r ≠ p ∧ s ≠ p ∧ r ≠ q"
lemma proj2_Col_coeff_abs:
assumes "p ≠ q" and "j ≠ 0"
shows "proj2_Col_coeff p q (proj2_abs (i *⇩R proj2_rep p + j *⇩R proj2_rep q))
= i/j"
(is "proj2_Col_coeff p q ?r = i/j")
proof -
from ‹j ≠ 0›
and proj2_abs_mult [of "1/j" "i *⇩R proj2_rep p + j *⇩R proj2_rep q"]
have "?r = proj2_abs ((i/j) *⇩R proj2_rep p + proj2_rep q)"
by (simp add: scaleR_right_distrib)
from ‹p ≠ q› and proj2_rep_dependent [of _ p 1 q]
have "(i/j) *⇩R proj2_rep p + proj2_rep q ≠ 0" by auto
with ‹?r = proj2_abs ((i/j) *⇩R proj2_rep p + proj2_rep q)›
and proj2_rep_abs2
obtain k where "k ≠ 0"
and "proj2_rep ?r = k *⇩R ((i/j) *⇩R proj2_rep p + proj2_rep q)"
by auto
hence "(k*i/j) *⇩R proj2_rep p + k *⇩R proj2_rep q - proj2_rep ?r = 0"
by (simp add: scaleR_right_distrib)
hence "∃ l. (k*i/j) *⇩R proj2_rep p + k *⇩R proj2_rep q + l *⇩R proj2_rep ?r = 0
∧ (k*i/j ≠ 0 ∨ k ≠ 0 ∨ l ≠ 0)"
by (simp add: exI [of _ "-1"])
hence "proj2_Col p q ?r" by (unfold proj2_Col_def) auto
have "?r ≠ p"
proof
assume "?r = p"
with ‹(k*i/j) *⇩R proj2_rep p + k *⇩R proj2_rep q - proj2_rep ?r = 0›
have "(k*i/j - 1) *⇩R proj2_rep p + k *⇩R proj2_rep q = 0"
by (simp add: algebra_simps)
with ‹k ≠ 0› and proj2_rep_dependent have "p = q" by simp
with ‹p ≠ q› show False ..
qed
with ‹proj2_Col p q ?r› and ‹p ≠ q›
have "?r = proj2_abs (proj2_Col_coeff p q ?r *⇩R proj2_rep p + proj2_rep q)"
by (rule proj2_Col_coeff)
with ‹p ≠ q› and ‹?r = proj2_abs ((i/j) *⇩R proj2_rep p + proj2_rep q)›
and proj2_Col_coeff_unique
show "proj2_Col_coeff p q ?r = i/j" by simp
qed
lemma proj2_set_Col_coeff:
assumes "proj2_set_Col S" and "{p,q,r} ⊆ S" and "p ≠ q" and "r ≠ p"
shows "r = proj2_abs (proj2_Col_coeff p q r *⇩R proj2_rep p + proj2_rep q)"
(is "r = proj2_abs (?i *⇩R ?u + ?v)")
proof -
from ‹{p,q,r} ⊆ S› and ‹proj2_set_Col S›
have "proj2_set_Col {p,q,r}" by (rule proj2_subset_Col)
hence "proj2_Col p q r" by (subst proj2_Col_iff_set_Col)
with ‹p ≠ q› and ‹r ≠ p› and proj2_Col_coeff
show "r = proj2_abs (?i *⇩R ?u + ?v)" by simp
qed
lemma cross_ratio_abs:
fixes u v :: "real^3" and i j k l :: real
assumes "u ≠ 0" and "v ≠ 0" and "proj2_abs u ≠ proj2_abs v"
and "j ≠ 0" and "l ≠ 0"
shows "cross_ratio (proj2_abs u) (proj2_abs v)
(proj2_abs (i *⇩R u + j *⇩R v))
(proj2_abs (k *⇩R u + l *⇩R v))
= j * k / (i * l)"
(is "cross_ratio ?p ?q ?r ?s = _")
proof -
from ‹u ≠ 0› and proj2_rep_abs2
obtain g where "g ≠ 0" and "proj2_rep ?p = g *⇩R u" by auto
from ‹v ≠ 0› and proj2_rep_abs2
obtain h where "h ≠ 0" and "proj2_rep ?q = h *⇩R v" by auto
with ‹g ≠ 0› and ‹proj2_rep ?p = g *⇩R u›
have "?r = proj2_abs ((i/g) *⇩R proj2_rep ?p + (j/h) *⇩R proj2_rep ?q)"
and "?s = proj2_abs ((k/g) *⇩R proj2_rep ?p + (l/h) *⇩R proj2_rep ?q)"
by (simp_all add: field_simps)
with ‹?p ≠ ?q› and ‹h ≠ 0› and ‹j ≠ 0› and ‹l ≠ 0› and proj2_Col_coeff_abs
have "proj2_Col_coeff ?p ?q ?r = h*i/(g*j)"
and "proj2_Col_coeff ?p ?q ?s = h*k/(g*l)"
by simp_all
with ‹g ≠ 0› and ‹h ≠ 0›
show "cross_ratio ?p ?q ?r ?s = j*k/(i*l)"
by (unfold cross_ratio_def) (simp add: field_simps)
qed
lemma cross_ratio_abs2:
assumes "p ≠ q"
shows "cross_ratio p q
(proj2_abs (i *⇩R proj2_rep p + proj2_rep q))
(proj2_abs (j *⇩R proj2_rep p + proj2_rep q))
= j/i"
(is "cross_ratio p q ?r ?s = _")
proof -
let ?u = "proj2_rep p"
let ?v = "proj2_rep q"
have "?u ≠ 0" and "?v ≠ 0" by (rule proj2_rep_non_zero)+
have "proj2_abs ?u = p" and "proj2_abs ?v = q" by (rule proj2_abs_rep)+
with ‹?u ≠ 0› and ‹?v ≠ 0› and ‹p ≠ q› and cross_ratio_abs [of ?u ?v 1 1 i j]
show "cross_ratio p q ?r ?s = j/i" by simp
qed
lemma cross_ratio_correct_cltn2:
assumes "cross_ratio_correct p q r s"
shows "cross_ratio_correct (apply_cltn2 p C) (apply_cltn2 q C)
(apply_cltn2 r C) (apply_cltn2 s C)"
(is "cross_ratio_correct ?pC ?qC ?rC ?sC")
proof -
from ‹cross_ratio_correct p q r s›
have "proj2_set_Col {p,q,r,s}"
and "p ≠ q" and "r ≠ p" and "s ≠ p" and "r ≠ q"
by (unfold cross_ratio_correct_def) simp_all
have "{apply_cltn2 t C | t. t ∈ {p,q,r,s}} = {?pC,?qC,?rC,?sC}" by auto
with ‹proj2_set_Col {p,q,r,s}›
and apply_cltn2_preserve_set_Col [of "{p,q,r,s}" C]
have "proj2_set_Col {?pC,?qC,?rC,?sC}" by simp
from ‹p ≠ q› and ‹r ≠ p› and ‹s ≠ p› and ‹r ≠ q› and apply_cltn2_injective
have "?pC ≠ ?qC" and "?rC ≠ ?pC" and "?sC ≠ ?pC" and "?rC ≠ ?qC" by fast+
with ‹proj2_set_Col {?pC,?qC,?rC,?sC}›
show "cross_ratio_correct ?pC ?qC ?rC ?sC"
by (unfold cross_ratio_correct_def) simp
qed
lemma cross_ratio_cltn2:
assumes "proj2_set_Col {p,q,r,s}" and "p ≠ q" and "r ≠ p" and "s ≠ p"
shows "cross_ratio (apply_cltn2 p C) (apply_cltn2 q C)
(apply_cltn2 r C) (apply_cltn2 s C)
= cross_ratio p q r s"
(is "cross_ratio ?pC ?qC ?rC ?sC = _")
proof -
let ?u = "proj2_rep p"
let ?v = "proj2_rep q"
let ?i = "proj2_Col_coeff p q r"
let ?j = "proj2_Col_coeff p q s"
from ‹proj2_set_Col {p,q,r,s}› and ‹p ≠ q› and ‹r ≠ p› and ‹s ≠ p›
and proj2_set_Col_coeff
have "r = proj2_abs (?i *⇩R ?u + ?v)" and "s = proj2_abs (?j *⇩R ?u + ?v)"
by simp_all
let ?uC = "?u v* cltn2_rep C"
let ?vC = "?v v* cltn2_rep C"
have "?uC ≠ 0" and "?vC ≠ 0" by (rule rep_mult_rep_non_zero)+
have "proj2_abs ?uC = ?pC" and "proj2_abs ?vC = ?qC"
by (unfold apply_cltn2_def) simp_all
from ‹p ≠ q› and apply_cltn2_injective have "?pC ≠ ?qC" by fast
from ‹p ≠ q› and proj2_rep_dependent [of _ p 1 q]
have "?i *⇩R ?u + ?v ≠ 0" and "?j *⇩R ?u + ?v ≠ 0" by auto
with ‹r = proj2_abs (?i *⇩R ?u + ?v)› and ‹s = proj2_abs (?j *⇩R ?u + ?v)›
and apply_cltn2_linear [of ?i ?u 1 ?v]
and apply_cltn2_linear [of ?j ?u 1 ?v]
have "?rC = proj2_abs (?i *⇩R ?uC + ?vC)"
and "?sC = proj2_abs (?j *⇩R ?uC + ?vC)"
by simp_all
with ‹?uC ≠ 0› and ‹?vC ≠ 0› and ‹proj2_abs ?uC = ?pC›
and ‹proj2_abs ?vC = ?qC› and ‹?pC ≠ ?qC›
and cross_ratio_abs [of ?uC ?vC 1 1 ?i ?j]
have "cross_ratio ?pC ?qC ?rC ?sC = ?j/?i" by simp
thus "cross_ratio ?pC ?qC ?rC ?sC = cross_ratio p q r s"
unfolding cross_ratio_def [of p q r s] .
qed
lemma cross_ratio_unique:
assumes "cross_ratio_correct p q r s" and "cross_ratio_correct p q r t"
and "cross_ratio p q r s = cross_ratio p q r t"
shows "s = t"
proof -
from ‹cross_ratio_correct p q r s› and ‹cross_ratio_correct p q r t›
have "proj2_set_Col {p,q,r,s}" and "proj2_set_Col {p,q,r,t}"
and "p ≠ q" and "r ≠ p" and "r ≠ q" and "s ≠ p" and "t ≠ p"
by (unfold cross_ratio_correct_def) simp_all
let ?u = "proj2_rep p"
let ?v = "proj2_rep q"
let ?i = "proj2_Col_coeff p q r"
let ?j = "proj2_Col_coeff p q s"
let ?k = "proj2_Col_coeff p q t"
from ‹proj2_set_Col {p,q,r,s}› and ‹proj2_set_Col {p,q,r,t}›
and ‹p ≠ q› and ‹r ≠ p› and ‹s ≠ p› and ‹t ≠ p› and proj2_set_Col_coeff
have "r = proj2_abs (?i *⇩R ?u + ?v)"
and "s = proj2_abs (?j *⇩R ?u + ?v)"
and "t = proj2_abs (?k *⇩R ?u + ?v)"
by simp_all
from ‹r ≠ q› and ‹r = proj2_abs (?i *⇩R ?u + ?v)›
have "?i ≠ 0" by (auto simp add: proj2_abs_rep)
with ‹cross_ratio p q r s = cross_ratio p q r t›
have "?j = ?k" by (unfold cross_ratio_def) simp
with ‹s = proj2_abs (?j *⇩R ?u + ?v)› and ‹t = proj2_abs (?k *⇩R ?u + ?v)›
show "s = t" by simp
qed
lemma cltn2_three_point_line:
assumes "p ≠ q" and "r ≠ p" and "r ≠ q"
and "proj2_incident p l" and "proj2_incident q l" and "proj2_incident r l"
and "apply_cltn2 p C = p" and "apply_cltn2 q C = q" and "apply_cltn2 r C = r"
and "proj2_incident s l"
shows "apply_cltn2 s C = s" (is "?sC = s")
proof cases
assume "s = p"
with ‹apply_cltn2 p C = p› show "?sC = s" by simp
next
assume "s ≠ p"
let ?pC = "apply_cltn2 p C"
let ?qC = "apply_cltn2 q C"
let ?rC = "apply_cltn2 r C"
from ‹proj2_incident p l› and ‹proj2_incident q l› and ‹proj2_incident r l›
and ‹proj2_incident s l›
have "proj2_set_Col {p,q,r,s}" by (unfold proj2_set_Col_def) auto
with ‹p ≠ q› and ‹r ≠ p› and ‹s ≠ p› and ‹r ≠ q›
have "cross_ratio_correct p q r s" by (unfold cross_ratio_correct_def) simp
hence "cross_ratio_correct ?pC ?qC ?rC ?sC"
by (rule cross_ratio_correct_cltn2)
with ‹?pC = p› and ‹?qC = q› and ‹?rC = r›
have "cross_ratio_correct p q r ?sC" by simp
from ‹proj2_set_Col {p,q,r,s}› and ‹p ≠ q› and ‹r ≠ p› and ‹s ≠ p›
have "cross_ratio ?pC ?qC ?rC ?sC = cross_ratio p q r s"
by (rule cross_ratio_cltn2)
with ‹?pC = p› and ‹?qC = q› and ‹?rC = r›
have "cross_ratio p q r ?sC = cross_ratio p q r s" by simp
with ‹cross_ratio_correct p q r ?sC› and ‹cross_ratio_correct p q r s›
show "?sC = s" by (rule cross_ratio_unique)
qed
lemma cross_ratio_equal_cltn2:
assumes "cross_ratio_correct p q r s"
and "cross_ratio_correct (apply_cltn2 p C) (apply_cltn2 q C)
(apply_cltn2 r C) t"
(is "cross_ratio_correct ?pC ?qC ?rC t")
and "cross_ratio (apply_cltn2 p C) (apply_cltn2 q C) (apply_cltn2 r C) t
= cross_ratio p q r s"
shows "t = apply_cltn2 s C" (is "t = ?sC")
proof -
from ‹cross_ratio_correct p q r s›
have "cross_ratio_correct ?pC ?qC ?rC ?sC" by (rule cross_ratio_correct_cltn2)
from ‹cross_ratio_correct p q r s›
have "proj2_set_Col {p,q,r,s}" and "p ≠ q" and "r ≠ p" and "s ≠ p"
by (unfold cross_ratio_correct_def) simp_all
hence "cross_ratio ?pC ?qC ?rC ?sC = cross_ratio p q r s"
by (rule cross_ratio_cltn2)
with ‹cross_ratio ?pC ?qC ?rC t = cross_ratio p q r s›
have "cross_ratio ?pC ?qC ?rC t = cross_ratio ?pC ?qC ?rC ?sC" by simp
with ‹cross_ratio_correct ?pC ?qC ?rC t›
and ‹cross_ratio_correct ?pC ?qC ?rC ?sC›
show "t = ?sC" by (rule cross_ratio_unique)
qed
lemma proj2_Col_distinct_coeff_non_zero:
assumes "proj2_Col p q r" and "p ≠ q" and "r ≠ p" and "r ≠ q"
shows "proj2_Col_coeff p q r ≠ 0"
proof
assume "proj2_Col_coeff p q r = 0"
from ‹proj2_Col p q r› and ‹p ≠ q› and ‹r ≠ p›
have "r = proj2_abs ((proj2_Col_coeff p q r) *⇩R proj2_rep p + proj2_rep q)"
by (rule proj2_Col_coeff)
with ‹proj2_Col_coeff p q r = 0› have "r = q" by (simp add: proj2_abs_rep)
with ‹r ≠ q› show False ..
qed
lemma cross_ratio_product:
assumes "proj2_Col p q s" and "p ≠ q" and "s ≠ p" and "s ≠ q"
shows "cross_ratio p q r s * cross_ratio p q s t = cross_ratio p q r t"
proof -
from ‹proj2_Col p q s› and ‹p ≠ q› and ‹s ≠ p› and ‹s ≠ q›
have "proj2_Col_coeff p q s ≠ 0" by (rule proj2_Col_distinct_coeff_non_zero)
thus "cross_ratio p q r s * cross_ratio p q s t = cross_ratio p q r t"
by (unfold cross_ratio_def) simp
qed
lemma cross_ratio_equal_1:
assumes "proj2_Col p q r" and "p ≠ q" and "r ≠ p" and "r ≠ q"
shows "cross_ratio p q r r = 1"
proof -
from ‹proj2_Col p q r› and ‹p ≠ q› and ‹r ≠ p› and ‹r ≠ q›
have "proj2_Col_coeff p q r ≠ 0" by (rule proj2_Col_distinct_coeff_non_zero)
thus "cross_ratio p q r r = 1" by (unfold cross_ratio_def) simp
qed
lemma cross_ratio_1_equal:
assumes "cross_ratio_correct p q r s" and "cross_ratio p q r s = 1"
shows "r = s"
proof -
from ‹cross_ratio_correct p q r s›
have "proj2_set_Col {p,q,r,s}" and "p ≠ q" and "r ≠ p" and "r ≠ q"
by (unfold cross_ratio_correct_def) simp_all
from ‹proj2_set_Col {p,q,r,s}›
have "proj2_set_Col {p,q,r}"
by (simp add: proj2_subset_Col [of "{p,q,r}" "{p,q,r,s}"])
with ‹p ≠ q› and ‹r ≠ p› and ‹r ≠ q›
have "cross_ratio_correct p q r r" by (unfold cross_ratio_correct_def) simp
from ‹proj2_set_Col {p,q,r}›
have "proj2_Col p q r" by (subst proj2_Col_iff_set_Col)
with ‹p ≠ q› and ‹r ≠ p› and ‹r ≠ q›
have "cross_ratio p q r r = 1" by (simp add: cross_ratio_equal_1)
with ‹cross_ratio p q r s = 1›
have "cross_ratio p q r r = cross_ratio p q r s" by simp
with ‹cross_ratio_correct p q r r› and ‹cross_ratio_correct p q r s›
show "r = s" by (rule cross_ratio_unique)
qed
lemma cross_ratio_swap_34:
shows "cross_ratio p q s r = 1 / (cross_ratio p q r s)"
by (unfold cross_ratio_def) simp
lemma cross_ratio_swap_13_24:
assumes "cross_ratio_correct p q r s" and "r ≠ s"
shows "cross_ratio r s p q = cross_ratio p q r s"
proof -
from ‹cross_ratio_correct p q r s›
have "proj2_set_Col {p,q,r,s}" and "p ≠ q" and "r ≠ p" and "s ≠ p" and "r ≠ q"
by (unfold cross_ratio_correct_def, simp_all)
have "proj2_rep p ≠ 0" (is "?u ≠ 0") and "proj2_rep q ≠ 0" (is "?v ≠ 0")
by (rule proj2_rep_non_zero)+
have "p = proj2_abs ?u" and "q = proj2_abs ?v"
by (simp_all add: proj2_abs_rep)
with ‹p ≠ q› have "proj2_abs ?u ≠ proj2_abs ?v" by simp
let ?i = "proj2_Col_coeff p q r"
let ?j = "proj2_Col_coeff p q s"
from ‹proj2_set_Col {p,q,r,s}› and ‹p ≠ q› and ‹r ≠ p› and ‹s ≠ p›
have "r = proj2_abs (?i *⇩R ?u + ?v)" (is "r = proj2_abs ?w")
and "s = proj2_abs (?j *⇩R ?u + ?v)" (is "s = proj2_abs ?x")
by (simp_all add: proj2_set_Col_coeff)
with ‹r ≠ s› have "?i ≠ ?j" by auto
from ‹?u ≠ 0› and ‹?v ≠ 0› and ‹proj2_abs ?u ≠ proj2_abs ?v›
and dependent_proj2_abs [of ?u ?v _ 1]
have "?w ≠ 0" and "?x ≠ 0" by auto
from ‹r = proj2_abs (?i *⇩R ?u + ?v)› and ‹r ≠ q›
have "?i ≠ 0" by (auto simp add: proj2_abs_rep)
have "?w - ?x = (?i - ?j) *⇩R ?u" by (simp add: algebra_simps)
with ‹?i ≠ ?j›
have "p = proj2_abs (?w - ?x)" by (simp add: proj2_abs_mult_rep)
have "?j *⇩R ?w - ?i *⇩R ?x = (?j - ?i) *⇩R ?v" by (simp add: algebra_simps)
with ‹?i ≠ ?j›
have "q = proj2_abs (?j *⇩R ?w - ?i *⇩R ?x)" by (simp add: proj2_abs_mult_rep)
with ‹?w ≠ 0› and ‹?x ≠ 0› and ‹r ≠ s› and ‹?i ≠ 0› and ‹r = proj2_abs ?w›
and ‹s = proj2_abs ?x› and ‹p = proj2_abs (?w - ?x)›
and cross_ratio_abs [of ?w ?x "-1" "-?i" 1 ?j]
have "cross_ratio r s p q = ?j / ?i" by (simp add: algebra_simps)
thus "cross_ratio r s p q = cross_ratio p q r s"
by (unfold cross_ratio_def [of p q r s], simp)
qed
lemma cross_ratio_swap_12:
assumes "cross_ratio_correct p q r s" and "cross_ratio_correct q p r s"
shows "cross_ratio q p r s = 1 / (cross_ratio p q r s)"
proof cases
assume "r = s"
from ‹cross_ratio_correct p q r s›
have "proj2_set_Col {p,q,r,s}" and "p ≠ q" and "r ≠ p" and "r ≠ q"
by (unfold cross_ratio_correct_def) simp_all
from ‹proj2_set_Col {p,q,r,s}› and ‹r = s›
have "proj2_Col p q r" by (simp_all add: proj2_Col_iff_set_Col)
hence "proj2_Col q p r" by (rule proj2_Col_permute)
with ‹proj2_Col p q r› and ‹p ≠ q› and ‹r ≠ p› and ‹r ≠ q› and ‹r = s›
have "cross_ratio p q r s = 1" and "cross_ratio q p r s = 1"
by (simp_all add: cross_ratio_equal_1)
thus "cross_ratio q p r s = 1 / (cross_ratio p q r s)" by simp
next
assume "r ≠ s"
with ‹cross_ratio_correct q p r s›
have "cross_ratio q p r s = cross_ratio r s q p"
by (simp add: cross_ratio_swap_13_24)
also have "… = 1 / (cross_ratio r s p q)" by (rule cross_ratio_swap_34)
also from ‹cross_ratio_correct p q r s› and ‹r ≠ s›
have "… = 1 / (cross_ratio p q r s)" by (simp add: cross_ratio_swap_13_24)
finally show "cross_ratio q p r s = 1 / (cross_ratio p q r s)" .
qed
subsection "Cartesian subspace of the real projective plane"
definition vector2_append1 :: "real^2 ⇒ real^3" where
"vector2_append1 v = vector [v$1, v$2, 1]"
lemma vector2_append1_non_zero: "vector2_append1 v ≠ 0"
proof -
have "(vector2_append1 v)$3 ≠ 0$3"
unfolding vector2_append1_def and vector_def
by simp
thus "vector2_append1 v ≠ 0" by auto
qed
definition proj2_pt :: "real^2 ⇒ proj2" where
"proj2_pt v ≡ proj2_abs (vector2_append1 v)"
lemma proj2_pt_scalar:
"∃ c. c ≠ 0 ∧ proj2_rep (proj2_pt v) = c *⇩R vector2_append1 v"
unfolding proj2_pt_def
by (simp add: proj2_rep_abs2 vector2_append1_non_zero)
abbreviation z_non_zero :: "proj2 ⇒ bool" where
"z_non_zero p ≡ (proj2_rep p)$3 ≠ 0"
definition cart2_pt :: "proj2 ⇒ real^2" where
"cart2_pt p ≡
vector [(proj2_rep p)$1 / (proj2_rep p)$3, (proj2_rep p)$2 / (proj2_rep p)$3]"
definition cart2_append1 :: "proj2 ⇒ real^3" where
"cart2_append1 p ≡ (1 / ((proj2_rep p)$3)) *⇩R proj2_rep p"
lemma cart2_append1_z:
assumes "z_non_zero p"
shows "(cart2_append1 p)$3 = 1"
using ‹z_non_zero p›
by (unfold cart2_append1_def) simp
lemma cart2_append1_non_zero:
assumes "z_non_zero p"
shows "cart2_append1 p ≠ 0"
proof -
from ‹z_non_zero p› have "(cart2_append1 p)$3 = 1" by (rule cart2_append1_z)
thus "cart2_append1 p ≠ 0" by (simp add: vec_eq_iff exI [of _ 3])
qed
lemma proj2_rep_cart2_append1:
assumes "z_non_zero p"
shows "proj2_rep p = ((proj2_rep p)$3) *⇩R cart2_append1 p"
using ‹z_non_zero p›
by (unfold cart2_append1_def) simp
lemma proj2_abs_cart2_append1:
assumes "z_non_zero p"
shows "proj2_abs (cart2_append1 p) = p"
proof -
from ‹z_non_zero p›
have "proj2_abs (cart2_append1 p) = proj2_abs (proj2_rep p)"
by (unfold cart2_append1_def) (simp add: proj2_abs_mult)
thus "proj2_abs (cart2_append1 p) = p" by (simp add: proj2_abs_rep)
qed
lemma cart2_append1_inj:
assumes "z_non_zero p" and "cart2_append1 p = cart2_append1 q"
shows "p = q"
proof -
from ‹z_non_zero p› have "(cart2_append1 p)$3 = 1" by (rule cart2_append1_z)
with ‹cart2_append1 p = cart2_append1 q›
have "(cart2_append1 q)$3 = 1" by simp
hence "z_non_zero q" by (unfold cart2_append1_def) auto
from ‹cart2_append1 p = cart2_append1 q›
have "proj2_abs (cart2_append1 p) = proj2_abs (cart2_append1 q)" by simp
with ‹z_non_zero p› and ‹z_non_zero q›
show "p = q" by (simp add: proj2_abs_cart2_append1)
qed
lemma cart2_append1:
assumes "z_non_zero p"
shows "vector2_append1 (cart2_pt p) = cart2_append1 p"
using ‹z_non_zero p›
unfolding vector2_append1_def
and cart2_append1_def
and cart2_pt_def
and vector_def
by (simp add: vec_eq_iff forall_3)
lemma cart2_proj2: "cart2_pt (proj2_pt v) = v"
proof -
let ?v' = "vector2_append1 v"
let ?p = "proj2_pt v"
from proj2_pt_scalar
obtain c where "c ≠ 0" and "proj2_rep ?p = c *⇩R ?v'" by auto
hence "(cart2_pt ?p)$1 = v$1" and "(cart2_pt ?p)$2 = v$2"
unfolding cart2_pt_def and vector2_append1_def and vector_def
by simp+
thus "cart2_pt ?p = v" by (simp add: vec_eq_iff forall_2)
qed
lemma z_non_zero_proj2_pt: "z_non_zero (proj2_pt v)"
proof -
from proj2_pt_scalar
obtain c where "c ≠ 0" and "proj2_rep (proj2_pt v) = c *⇩R (vector2_append1 v)"
by auto
from ‹proj2_rep (proj2_pt v) = c *⇩R (vector2_append1 v)›
have "(proj2_rep (proj2_pt v))$3 = c"
unfolding vector2_append1_def and vector_def
by simp
with ‹c ≠ 0› show "z_non_zero (proj2_pt v)" by simp
qed
lemma cart2_append1_proj2: "cart2_append1 (proj2_pt v) = vector2_append1 v"
proof -
from z_non_zero_proj2_pt
have "cart2_append1 (proj2_pt v) = vector2_append1 (cart2_pt (proj2_pt v))"
by (simp add: cart2_append1)
thus "cart2_append1 (proj2_pt v) = vector2_append1 v"
by (simp add: cart2_proj2)
qed
lemma proj2_pt_inj: "inj proj2_pt"
by (simp add: inj_on_inverseI [of UNIV cart2_pt proj2_pt] cart2_proj2)
lemma proj2_cart2:
assumes "z_non_zero p"
shows "proj2_pt (cart2_pt p) = p"
proof -
from ‹z_non_zero p›
have "(proj2_rep p)$3 *⇩R vector2_append1 (cart2_pt p) = proj2_rep p"
unfolding vector2_append1_def and cart2_pt_def and vector_def
by (simp add: vec_eq_iff forall_3)
with ‹z_non_zero p›
and proj2_abs_mult [of "(proj2_rep p)$3" "vector2_append1 (cart2_pt p)"]
have "proj2_abs (vector2_append1 (cart2_pt p)) = proj2_abs (proj2_rep p)"
by simp
thus "proj2_pt (cart2_pt p) = p"
by (unfold proj2_pt_def) (simp add: proj2_abs_rep)
qed
lemma cart2_injective:
assumes "z_non_zero p" and "z_non_zero q" and "cart2_pt p = cart2_pt q"
shows "p = q"
proof -
from ‹z_non_zero p› and ‹z_non_zero q›
have "proj2_pt (cart2_pt p) = p" and "proj2_pt (cart2_pt q) = q"
by (simp_all add: proj2_cart2)
from ‹proj2_pt (cart2_pt p) = p› and ‹cart2_pt p = cart2_pt q›
have "proj2_pt (cart2_pt q) = p" by simp
with ‹proj2_pt (cart2_pt q) = q› show "p = q" by simp
qed
lemma proj2_Col_iff_euclid:
"proj2_Col (proj2_pt a) (proj2_pt b) (proj2_pt c) ⟷ real_euclid.Col a b c"
(is "proj2_Col ?p ?q ?r ⟷ _")
proof
let ?a' = "vector2_append1 a"
let ?b' = "vector2_append1 b"
let ?c' = "vector2_append1 c"
let ?a'' = "proj2_rep ?p"
let ?b'' = "proj2_rep ?q"
let ?c'' = "proj2_rep ?r"
from proj2_pt_scalar obtain i and j and k where
"i ≠ 0" and "?a'' = i *⇩R ?a'"
and "j ≠ 0" and "?b'' = j *⇩R ?b'"
and "k ≠ 0" and "?c'' = k *⇩R ?c'"
by metis
hence "?a' = (1/i) *⇩R ?a''"
and "?b' = (1/j) *⇩R ?b''"
and "?c' = (1/k) *⇩R ?c''"
by simp_all
{ assume "proj2_Col ?p ?q ?r"
then obtain i' and j' and k' where
"i' *⇩R ?a'' + j' *⇩R ?b'' + k' *⇩R ?c'' = 0" and "i'≠0 ∨ j'≠0 ∨ k'≠0"
unfolding proj2_Col_def
by auto
let ?i'' = "i * i'"
let ?j'' = "j * j'"
let ?k'' = "k * k'"
from ‹i≠0› and ‹j≠0› and ‹k≠0› and ‹i'≠0 ∨ j'≠0 ∨ k'≠0›
have "?i''≠0 ∨ ?j''≠0 ∨ ?k''≠0" by simp
from ‹i' *⇩R ?a'' + j' *⇩R ?b'' + k' *⇩R ?c'' = 0›
and ‹?a'' = i *⇩R ?a'›
and ‹?b'' = j *⇩R ?b'›
and ‹?c'' = k *⇩R ?c'›
have "?i'' *⇩R ?a' + ?j'' *⇩R ?b' + ?k'' *⇩R ?c' = 0"
by (simp add: ac_simps)
hence "(?i'' *⇩R ?a' + ?j'' *⇩R ?b' + ?k'' *⇩R ?c')$3 = 0"
by simp
hence "?i'' + ?j'' + ?k'' = 0"
unfolding vector2_append1_def and vector_def
by simp
have "(?i'' *⇩R ?a' + ?j'' *⇩R ?b' + ?k'' *⇩R ?c')$1 =
(?i'' *⇩R a + ?j'' *⇩R b + ?k'' *⇩R c)$1"
and "(?i'' *⇩R ?a' + ?j'' *⇩R ?b' + ?k'' *⇩R ?c')$2 =
(?i'' *⇩R a + ?j'' *⇩R b + ?k'' *⇩R c)$2"
unfolding vector2_append1_def and vector_def
by simp+
with ‹?i'' *⇩R ?a' + ?j'' *⇩R ?b' + ?k'' *⇩R ?c' = 0›
have "?i'' *⇩R a + ?j'' *⇩R b + ?k'' *⇩R c = 0"
by (simp add: vec_eq_iff forall_2)
have "dep2 (b - a) (c - a)"
proof cases
assume "?k'' = 0"
with ‹?i'' + ?j'' + ?k'' = 0› have "?j'' = -?i''" by simp
with ‹?i''≠0 ∨ ?j''≠0 ∨ ?k''≠0› and ‹?k'' = 0› have "?i'' ≠ 0" by simp
from ‹?i'' *⇩R a + ?j'' *⇩R b + ?k'' *⇩R c = 0›
and ‹?k'' = 0› and ‹?j'' = -?i''›
have "?i'' *⇩R a + (-?i'' *⇩R b) = 0" by simp
with ‹?i'' ≠ 0› have "a = b" by (simp add: algebra_simps)
hence "b - a = 0 *⇩R (c - a)" by simp
moreover have "c - a = 1 *⇩R (c - a)" by simp
ultimately have "∃ x t s. b - a = t *⇩R x ∧ c - a = s *⇩R x"
by blast
thus "dep2 (b - a) (c - a)" unfolding dep2_def .
next
assume "?k'' ≠ 0"
from ‹?i'' + ?j'' + ?k'' = 0› have "?i'' = -(?j'' + ?k'')" by simp
with ‹?i'' *⇩R a + ?j'' *⇩R b + ?k'' *⇩R c = 0›
have "-(?j'' + ?k'') *⇩R a + ?j'' *⇩R b + ?k'' *⇩R c = 0" by simp
hence "?k'' *⇩R (c - a) = - ?j'' *⇩R (b - a)"
by (simp add: scaleR_left_distrib
scaleR_right_diff_distrib
scaleR_left_diff_distrib
algebra_simps)
hence "(1/?k'') *⇩R ?k'' *⇩R (c - a) = (-?j'' / ?k'') *⇩R (b - a)"
by simp
with ‹?k'' ≠ 0› have "c - a = (-?j'' / ?k'') *⇩R (b - a)" by simp
moreover have "b - a = 1 *⇩R (b - a)" by simp
ultimately have "∃ x t s. b - a = t *⇩R x ∧ c - a = s *⇩R x" by blast
thus "dep2 (b - a) (c - a)" unfolding dep2_def .
qed
with Col_dep2 show "real_euclid.Col a b c" by auto
}
{ assume "real_euclid.Col a b c"
with Col_dep2 have "dep2 (b - a) (c - a)" by auto
then obtain x and t and s where "b - a = t *⇩R x" and "c - a = s *⇩R x"
unfolding dep2_def
by auto
show "proj2_Col ?p ?q ?r"
proof cases
assume "t = 0"
with ‹b - a = t *⇩R x› have "a = b" by simp
with proj2_Col_coincide show "proj2_Col ?p ?q ?r" by simp
next
assume "t ≠ 0"
from ‹b - a = t *⇩R x› and ‹c - a = s *⇩R x›
have "s *⇩R (b - a) = t *⇩R (c - a)" by simp
hence "(s - t) *⇩R a + (-s) *⇩R b + t *⇩R c = 0"
by (simp add: scaleR_right_diff_distrib
scaleR_left_diff_distrib
algebra_simps)
hence "((s - t) *⇩R ?a' + (-s) *⇩R ?b' + t *⇩R ?c')$1 = 0"
and "((s - t) *⇩R ?a' + (-s) *⇩R ?b' + t *⇩R ?c')$2 = 0"
unfolding vector2_append1_def and vector_def
by (simp_all add: vec_eq_iff)
moreover have "((s - t) *⇩R ?a' + (-s) *⇩R ?b' + t *⇩R ?c')$3 = 0"
unfolding vector2_append1_def and vector_def
by simp
ultimately have "(s - t) *⇩R ?a' + (-s) *⇩R ?b' + t *⇩R ?c' = 0"
by (simp add: vec_eq_iff forall_3)
with ‹?a' = (1/i) *⇩R ?a''›
and ‹?b' = (1/j) *⇩R ?b''›
and ‹?c' = (1/k) *⇩R ?c''›
have "((s - t)/i) *⇩R ?a'' + (-s/j) *⇩R ?b'' + (t/k) *⇩R ?c'' = 0"
by simp
moreover from ‹t ≠ 0› and ‹k ≠ 0› have "t/k ≠ 0" by simp
ultimately show "proj2_Col ?p ?q ?r"
unfolding proj2_Col_def
by blast
qed
}
qed
lemma proj2_Col_iff_euclid_cart2:
assumes "z_non_zero p" and "z_non_zero q" and "z_non_zero r"
shows
"proj2_Col p q r ⟷ real_euclid.Col (cart2_pt p) (cart2_pt q) (cart2_pt r)"
(is "_ ⟷ real_euclid.Col ?a ?b ?c")
proof -
from ‹z_non_zero p› and ‹z_non_zero q› and ‹z_non_zero r›
have "proj2_pt ?a = p" and "proj2_pt ?b = q" and "proj2_pt ?c = r"
by (simp_all add: proj2_cart2)
with proj2_Col_iff_euclid [of ?a ?b ?c]
show "proj2_Col p q r ⟷ real_euclid.Col ?a ?b ?c" by simp
qed
lemma euclid_Col_cart2_incident:
assumes "z_non_zero p" and "z_non_zero q" and "z_non_zero r" and "p ≠ q"
and "proj2_incident p l" and "proj2_incident q l"
and "real_euclid.Col (cart2_pt p) (cart2_pt q) (cart2_pt r)"
(is "real_euclid.Col ?cp ?cq ?cr")
shows "proj2_incident r l"
proof -
from ‹z_non_zero p› and ‹z_non_zero q› and ‹z_non_zero r›
and ‹real_euclid.Col ?cp ?cq ?cr›
have "proj2_Col p q r" by (subst proj2_Col_iff_euclid_cart2, simp_all)
hence "proj2_set_Col {p,q,r}" by (simp add: proj2_Col_iff_set_Col)
then obtain m where
"proj2_incident p m" and "proj2_incident q m" and "proj2_incident r m"
by (unfold proj2_set_Col_def, auto)
from ‹p ≠ q› and ‹proj2_incident p l› and ‹proj2_incident q l›
and ‹proj2_incident p m› and ‹proj2_incident q m› and proj2_incident_unique
have "l = m" by auto
with ‹proj2_incident r m› show "proj2_incident r l" by simp
qed
lemma euclid_B_cart2_common_line:
assumes "z_non_zero p" and "z_non_zero q" and "z_non_zero r"
and "B⇩ℝ (cart2_pt p) (cart2_pt q) (cart2_pt r)"
(is "B⇩ℝ ?cp ?cq ?cr")
shows "∃ l. proj2_incident p l ∧ proj2_incident q l ∧ proj2_incident r l"
proof -
from ‹z_non_zero p› and ‹z_non_zero q› and ‹z_non_zero r›
and ‹B⇩ℝ ?cp ?cq ?cr› and proj2_Col_iff_euclid_cart2
have "proj2_Col p q r" by (unfold real_euclid.Col_def) simp
hence "proj2_set_Col {p,q,r}" by (simp add: proj2_Col_iff_set_Col)
thus "∃ l. proj2_incident p l ∧ proj2_incident q l ∧ proj2_incident r l"
by (unfold proj2_set_Col_def) simp
qed
lemma cart2_append1_between:
assumes "z_non_zero p" and "z_non_zero q" and "z_non_zero r"
shows "B⇩ℝ (cart2_pt p) (cart2_pt q) (cart2_pt r)
⟷ (∃ k≥0. k ≤ 1
∧ cart2_append1 q = k *⇩R cart2_append1 r + (1 - k) *⇩R cart2_append1 p)"
proof -
let ?cp = "cart2_pt p"
let ?cq = "cart2_pt q"
let ?cr = "cart2_pt r"
let ?cp1 = "vector2_append1 ?cp"
let ?cq1 = "vector2_append1 ?cq"
let ?cr1 = "vector2_append1 ?cr"
from ‹z_non_zero p› and ‹z_non_zero q› and ‹z_non_zero r›
have "?cp1 = cart2_append1 p"
and "?cq1 = cart2_append1 q"
and "?cr1 = cart2_append1 r"
by (simp_all add: cart2_append1)
have "∀ k. ?cq - ?cp = k *⇩R (?cr - ?cp) ⟷ ?cq = k *⇩R ?cr + (1 - k) *⇩R ?cp"
by (simp add: algebra_simps)
hence "∀ k. ?cq - ?cp = k *⇩R (?cr - ?cp)
⟷ ?cq1 = k *⇩R ?cr1 + (1 - k) *⇩R ?cp1"
unfolding vector2_append1_def and vector_def
by (simp add: vec_eq_iff forall_2 forall_3)
with ‹?cp1 = cart2_append1 p›
and ‹?cq1 = cart2_append1 q›
and ‹?cr1 = cart2_append1 r›
have "∀ k. ?cq - ?cp = k *⇩R (?cr - ?cp)
⟷ cart2_append1 q = k *⇩R cart2_append1 r + (1 - k) *⇩R cart2_append1 p"
by simp
thus "B⇩ℝ (cart2_pt p) (cart2_pt q) (cart2_pt r)
⟷ (∃ k≥0. k ≤ 1
∧ cart2_append1 q = k *⇩R cart2_append1 r + (1 - k) *⇩R cart2_append1 p)"
by (unfold real_euclid_B_def) simp
qed
lemma cart2_append1_between_right_strict:
assumes "z_non_zero p" and "z_non_zero q" and "z_non_zero r"
and "B⇩ℝ (cart2_pt p) (cart2_pt q) (cart2_pt r)" and "q ≠ r"
shows "∃ k≥0. k < 1
∧ cart2_append1 q = k *⇩R cart2_append1 r + (1 - k) *⇩R cart2_append1 p"
proof -
from ‹z_non_zero p› and ‹z_non_zero q› and ‹z_non_zero r›
and ‹B⇩ℝ (cart2_pt p) (cart2_pt q) (cart2_pt r)› and cart2_append1_between
obtain k where "k ≥ 0" and "k ≤ 1"
and "cart2_append1 q = k *⇩R cart2_append1 r + (1 - k) *⇩R cart2_append1 p"
by auto
have "k ≠ 1"
proof
assume "k = 1"
with ‹cart2_append1 q = k *⇩R cart2_append1 r + (1 - k) *⇩R cart2_append1 p›
have "cart2_append1 q = cart2_append1 r" by simp
with ‹z_non_zero q› have "q = r" by (rule cart2_append1_inj)
with ‹q ≠ r› show False ..
qed
with ‹k ≤ 1› have "k < 1" by simp
with ‹k ≥ 0›
and ‹cart2_append1 q = k *⇩R cart2_append1 r + (1 - k) *⇩R cart2_append1 p›
show "∃ k≥0. k < 1
∧ cart2_append1 q = k *⇩R cart2_append1 r + (1 - k) *⇩R cart2_append1 p"
by (simp add: exI [of _ k])
qed
lemma cart2_append1_between_strict:
assumes "z_non_zero p" and "z_non_zero q" and "z_non_zero r"
and "B⇩ℝ (cart2_pt p) (cart2_pt q) (cart2_pt r)" and "q ≠ p" and "q ≠ r"
shows "∃ k>0. k < 1
∧ cart2_append1 q = k *⇩R cart2_append1 r + (1 - k) *⇩R cart2_append1 p"
proof -
from ‹z_non_zero p› and ‹z_non_zero q› and ‹z_non_zero r›
and ‹B⇩ℝ (cart2_pt p) (cart2_pt q) (cart2_pt r)› and ‹q ≠ r›
and cart2_append1_between_right_strict [of p q r]
obtain k where "k ≥ 0" and "k < 1"
and "cart2_append1 q = k *⇩R cart2_append1 r + (1 - k) *⇩R cart2_append1 p"
by auto
have "k ≠ 0"
proof
assume "k = 0"
with ‹cart2_append1 q = k *⇩R cart2_append1 r + (1 - k) *⇩R cart2_append1 p›
have "cart2_append1 q = cart2_append1 p" by simp
with ‹z_non_zero q› have "q = p" by (rule cart2_append1_inj)
with ‹q ≠ p› show False ..
qed
with ‹k ≥ 0› have "k > 0" by simp
with ‹k < 1›
and ‹cart2_append1 q = k *⇩R cart2_append1 r + (1 - k) *⇩R cart2_append1 p›
show "∃ k>0. k < 1
∧ cart2_append1 q = k *⇩R cart2_append1 r + (1 - k) *⇩R cart2_append1 p"
by (simp add: exI [of _ k])
qed
end