Theory Vec_Extras
theory Vec_Extras
imports
"HOL-Analysis.Finite_Cartesian_Product"
Fixed_Length_Vector.Fixed_Length_Vector
begin
unbundle no Finite_Cartesian_Product.vec_syntax
unbundle Fixed_Length_Vector.vec_syntax
type_definition_vec
text ‹The most important lemmas to know when working with @{type vec} are
\begin{itemize}
\item @{thm [source] vec_of_list_inject}: @{thm vec_of_list_inject[no_vars]}
\item @{thm [source] vec_of_list_inverse}: @{thm vec_of_list_inverse[no_vars]}
\item @{thm [source] nth_vec.rep_eq}: @{thm nth_vec.rep_eq[no_vars]}
\end{itemize}
Tip:
When using @{const vec_of_list} to create a vector @{term "v :: ('a, 'b) vec"} from
@{term "xs :: 'a list"}, it is essential to separately prove that
@{term "xs ∈ {xs. length xs = CARD('b)}"} for above lemmas to apply›
:: "('a, 'b::{finite, index1}) Finite_Cartesian_Product.vec ⇒
('a, 'b) Fixed_Length_Vector.vec" is
‹λx. map (λi. Finite_Cartesian_Product.vec_nth x i :: 'a) (indexes :: 'b list)› by simp
:: "('a, 'b::{finite, index1}) Fixed_Length_Vector.vec ⇒
('a, 'b) Finite_Cartesian_Product.vec" where
‹fcp_of_vec ≡ λx. Finite_Cartesian_Product.vec_lambda (λi. x $ i)›
:: "nat ⇒ ('a, 'b) Fixed_Length_Vector.vec ⇒
(nat × 'a, 'b) Fixed_Length_Vector.vec" is
‹List.enumerate› by simp
lemma :
assumes "infinite (UNIV :: 'a set)" "finite (UNIV :: 'b set)"
shows "infinite (UNIV :: ('a,'b) Fixed_Length_Vector.vec set)"
proof -
let ?UNIVA = "UNIV :: 'a set"
let ?UNIVB = "UNIV :: 'b set"
let ?UNIVV = "UNIV :: ('a,'b) Fixed_Length_Vector.vec set"
have "CARD('b) > 0" using assms(2) finite_UNIV_card_ge_0 by blast
then have "(λx. nth_vec' x 0) ` ?UNIVV = ?UNIVA"
apply (intro surjI[where ?f = "λx. replicate_vec x"])
by (simp add: nth_vec'.rep_eq)
moreover have "card ((λx. nth_vec' x 0) ` ?UNIVV) ≤ card ?UNIVV"
by (simp add: calculation assms)
ultimately show ?thesis by (metis assms finite_imageI)
qed
lemma :
assumes "infinite (UNIV :: 'b set)"
shows "(UNIV :: ('a,'b) Fixed_Length_Vector.vec set) = {vec_of_list []}"
by (metis (mono_tags, lifting) UNIV_eq_I assms card.infinite insertI1 length_0_conv
list_of_vec_inverse list_of_vec_length)
lemma :
shows "CARD(('a, 'b) Fixed_Length_Vector.vec) = CARD('a) ^ CARD('b)" (is "?lhs = ?rhs")
proof -
let ?UNIVA = "UNIV :: 'a set"
let ?UNIVB = "UNIV :: 'b set"
let ?UNIVV = "UNIV :: ('a,'b) Fixed_Length_Vector.vec set"
consider "finite ?UNIVA" | "infinite ?UNIVA" "finite ?UNIVB" | "infinite ?UNIVA" "infinite ?UNIVB"
by fast
then show ?thesis
proof cases
case 1
have "?lhs = card ({xs. length xs = CARD('b)} :: 'a list set)"
using Fixed_Length_Vector.vec.type_definition_vec type_definition.card by blast
also have "… = ?rhs" using card_lists_length_eq[of ?UNIVA, OF 1] by simp
finally show ?thesis .
next
case 2
have "infinite ?UNIVV" using infinite_UNIV_vec[OF 2] .
then show ?thesis using 2 finite_UNIV_card_ge_0 by (simp add: card_eq_0_iff)
next
case 3
have "card ?UNIVV = Suc 0" unfolding infinite_index_UNIV_vec[OF 3(2)] by simp
then show ?thesis using 3 by (simp add: card_eq_0_iff)
qed
qed
lemma (in index1) [simp]:
assumes "a ≠ b"
shows "from_index a ≠ from_index b"
by (metis assms local.from_to_index)
lemma [simp]:
fixes xs :: "('a, 'b :: index1) Fixed_Length_Vector.vec"
shows "list_of_vec xs ≠ []"
by (metis from_index_bound gr_implies_not0 list.size(3) list_of_vec_length)
lemma :
fixes xs :: "('a, 'b :: index1) Fixed_Length_Vector.vec"
assumes "i < CARD('b)"
shows
"xs = vec_of_list (
take i (list_of_vec xs) @
list_of_vec xs ! i #
drop (Suc i) (list_of_vec xs))"
by (simp add: Cons_nth_drop_Suc assms)
lemma :
fixes xs :: "('a, 'b :: index1) Fixed_Length_Vector.vec"
assumes "i < CARD('b)"
shows
"xs = vec_of_list (
take i (list_of_vec xs) @
xs $ to_index i #
drop (Suc i) (list_of_vec xs))"
by (simp add: Cons_nth_drop_Suc assms nth_vec.rep_eq to_from_index)
lemma :
assumes "y ! i ≠ x ! i"
shows "(i, y ! i) ∉ set (List.enumerate 0 x)"
apply (subst in_set_conv_nth, clarsimp)
using assms nth_enumerate_eq by fastforce
lemma :
assumes "y ! j ≠ x ! j"
shows "(j, y ! j) ∉ set (List.enumerate 0 (take i x))"
apply (subst in_set_conv_nth, clarsimp)
by (metis arith_simps(49) assms length_take min_less_iff_conj nth_enumerate_eq nth_take
prod.sel(1,2))
lemma :
assumes "y ! j ≠ x ! j"
shows "(j, y ! j) ∉ set (List.enumerate (Suc i) (drop (Suc i) x))"
apply (subst in_set_conv_nth, clarsimp)
by (metis assms fst_eqD length_drop linorder_not_le nat_diff_split not_less_zero nth_drop
nth_enumerate_eq snd_eqD)
lemma :
fixes xs :: "('a, 'b :: index1) Fixed_Length_Vector.vec"
assumes "m < CARD('b)"
shows "enumerate_vec n xs $ to_index m = (n + m, xs $ to_index m)"
by (simp add: nth_vec.rep_eq index.to_from_index index_axioms assms enumerate_vec.rep_eq
nth_enumerate_eq)
lemma :
fixes xs :: "('a, 'b :: index1) Fixed_Length_Vector.vec"
shows "p ∈ set_vec (enumerate_vec n xs) ⟷
n ≤ fst p ∧ fst p < CARD('b) + n ∧ xs $ to_index (fst p - n) = snd p"
apply (simp add:
in_set_enumerate_eq nth_vec.rep_eq set_vec.rep_eq index.to_from_index
index_axioms enumerate_vec.rep_eq nth_enumerate_eq)
by (metis less_diff_conv2 to_from_index)
lemma :
shows "inj vec_of_fcp"
apply (clarsimp
intro!: injI
simp: vec_of_fcp_def vec_of_list_inject indexes_def vec_eq_iff Ball_def)
by (metis from_to_index from_index_bound)
lemma :
shows "inj fcp_of_vec"
by (auto intro!: injI vec_cong simp: fcp_of_vec_def)
lemma :
shows "vec_of_fcp (fcp_of_vec x) = x"
apply (simp add: vec_of_fcp_def fcp_of_vec_def)
by (metis UNIV_I vec_explode vec_lambda.abs_eq vec_lambda_inverse)
lemma :
shows "fcp_of_vec (vec_of_fcp x) = x"
apply (simp add: vec_of_fcp_def fcp_of_vec_def)
by (metis vec_lambda.abs_eq vec_lambda_nth vec_lambda_unique)
lemma :
shows "surj vec_of_fcp"
using fcp_of_vec_inverse by (intro surjI)
lemma :
shows "surj fcp_of_vec"
using vec_of_fcp_inverse by (intro surjI)
lemma :
shows "bij vec_of_fcp"
by (intro bijI inj_vec_of_fcp surj_vec_of_fcp)
lemma :
shows "bij fcp_of_vec"
by (intro bijI inj_fcp_of_vec surj_fcp_of_vec)
unbundle no Fixed_Length_Vector.vec_syntax
end