Theory Get_Types_Verification
theory Get_Types_Verification
imports
"../abs-def/Abs_SAIS"
"../def/Get_Types"
begin
section "Suffix Types"
lemma get_suffix_types_step_r0_ret:
"∃xs' i'. get_suffix_types_step_r0 (xs, i) ys = (xs', i') ∧
length xs' = length xs ∧ (i = 0 ⟶ i' = 0) ∧ (∃j. i = Suc j ⟶ i' = j)"
by (cases i; simp)
lemma get_suffix_types_step_r0_0:
"get_suffix_types_step_r0 (xs, 0) ys = (xs, 0)"
by simp
lemma get_suffix_types_step_r0_Suc:
"⟦Suc i < length xs; length xs = length ys; ∀k < length xs. i < k ⟶ xs ! k = suffix_type ys k⟧ ⟹
get_suffix_types_step_r0 (xs, Suc i) ys = (xs[i := suffix_type ys i], i)"
apply clarsimp
apply (intro conjI impI arg_cong[where f = "λx. xs[i := x]"])
apply (simp add: nth_gr_imp_l_type)
apply (simp add: nth_less_imp_s_type)
by (metis suffix_type_neq)
fun get_suffix_types_inv
where
"get_suffix_types_inv ys (xs, i) =
(length xs = length ys ∧ i < length xs ∧ (∀k < length xs. i ≤ k ⟶ xs ! k = suffix_type ys k))"
lemma get_suffix_types_inv_maintained:
assumes "get_suffix_types_inv ys (xs, i)"
shows "get_suffix_types_inv ys (get_suffix_types_step_r0 (xs, i) ys)"
proof (cases i)
case 0
hence "get_suffix_types_step_r0 (xs, i) ys = (xs, 0)"
using get_suffix_types_step_r0_0 by simp
moreover
have "get_suffix_types_inv ys (xs, 0)"
using "0" assms by auto
ultimately show ?thesis
by presburger
next
case (Suc n)
hence "get_suffix_types_step_r0 (xs, i) ys = (xs[n := suffix_type ys n], n)"
by (metis Suc_leI assms get_suffix_types_inv.simps get_suffix_types_step_r0_Suc)
moreover
have "get_suffix_types_inv ys (xs[n := suffix_type ys n], n)"
using Suc assms le_eq_less_or_eq by fastforce
ultimately show ?thesis
by simp
qed
lemma get_suffix_types_inv_established:
"xs ≠ [] ⟹ get_suffix_types_inv xs (replicate (length xs) S_type, length xs - Suc 0)"
by (simp add: suffix_type_last)
lemma get_suffix_types_base_prod':
"∃xs'. repeat n get_suffix_types_step_r0 (xs, m) ys = (xs', m - n)"
proof (induct n arbitrary: xs m)
case 0
then show ?case
by (simp add: repeat_0)
next
case (Suc n)
note IH = this
from repeat_step[of n get_suffix_types_step_r0 "(xs, m)" ys]
have "repeat (Suc n) get_suffix_types_step_r0 (xs, m) ys
= get_suffix_types_step_r0 (repeat n get_suffix_types_step_r0 (xs, m) ys) ys" .
moreover
from IH[of xs m]
obtain xs' where
"repeat n get_suffix_types_step_r0 (xs, m) ys = (xs', m - n)"
by blast
moreover
have "∃xs''. get_suffix_types_step_r0 (xs', m - n) ys = (xs'', m - Suc n)"
proof (cases "m-n")
case 0
hence "get_suffix_types_step_r0 (xs', m - n) ys = (xs', 0)"
by auto
moreover
have "m - Suc n = 0"
using "0" by auto
ultimately show ?thesis
by simp
next
case (Suc k)
have "(m - n < length xs' ∧ m - n < length ys) ∨ ¬(m - n < length xs' ∧ m - n < length ys)"
by blast
moreover
have "m - n < length xs' ∧ m - n < length ys ⟹ ?thesis"
by (clarsimp simp add: Suc diff_Suc)
moreover
have "¬(m - n < length xs' ∧ m - n < length ys) ⟹ ?thesis"
by (clarsimp simp add: Suc diff_Suc)
ultimately show ?thesis
by blast
qed
ultimately show ?case
by presburger
qed
lemma get_suffix_types_inv_holds:
assumes "xs ≠ []"
shows "get_suffix_types_inv xs (get_suffix_types_base xs)"
unfolding get_suffix_types_base_def
apply (rule repeat_maintain_inv)
apply (metis get_suffix_types_inv_maintained prod.collapse)
apply (rule get_suffix_types_inv_established[OF assms])
done
lemma get_suffix_types_base_prod:
"∃xs'. get_suffix_types_base xs = (xs', 0)"
unfolding get_suffix_types_base_def
by (metis cancel_comm_monoid_add_class.diff_cancel get_suffix_types_base_prod')
lemma get_suffix_types_base_ref:
"get_suffix_types_base xs = (abs_get_suffix_types xs, 0)"
proof (cases "xs ≠ []")
assume "¬ xs ≠ []"
then show ?thesis
by (clarsimp simp: get_suffix_types_base_def repeat_0 get_suffix_types_def)
next
assume "xs ≠ []"
with get_suffix_types_inv_holds
have "get_suffix_types_inv xs (get_suffix_types_base xs)"
by blast
moreover
from get_suffix_types_base_prod[of xs]
obtain xs' where
"get_suffix_types_base xs = (xs', 0)"
by blast
ultimately have "get_suffix_types_inv xs (xs', 0)"
by auto
moreover
have "abs_get_suffix_types xs = xs'"
unfolding list_eq_iff_nth_eq
by (metis bot_nat_0.extremum calculation get_suffix_types_correct
get_suffix_types_inv.simps
length_abs_get_suffix_types)
ultimately show ?thesis
by (simp add: ‹get_suffix_types_base xs = (xs', 0)›)
qed
lemma get_suffix_types_eq:
"get_suffix_types xs = abs_get_suffix_types xs"
by (simp add: get_suffix_types_base_ref get_suffix_types_def)
lemmas length_get_suffix_types =
length_abs_get_suffix_types[simplified get_suffix_types_eq]
section "LMS types"
lemma is_lms_refinement:
assumes "length ST = length T" "∀i < length T. ST ! i = suffix_type T i"
shows "is_lms_ref ST = abs_is_lms T"
proof
fix i
show "is_lms_ref ST i = abs_is_lms T i"
proof (cases i)
case 0
then show ?thesis
by (simp add: abs_is_lms_0)
next
case (Suc n)
then show ?thesis
by (metis Suc_lessD assms abs_is_lms_def abs_is_lms_imp_less_length is_lms_ref.simps(2))
qed
qed
section "Extracting LMS types"
lemma :
"⟦length ST = length T; ∀i < length T. ST ! i = suffix_type T i⟧ ⟹
extract_lms ST = abs_extract_lms T"
by (clarsimp simp: fun_eq_iff is_lms_refinement)
section "LMS Substrings"
lemma find_next_lms_refinement:
"⟦length ST = length T; ∀i < length T. ST ! i = suffix_type T i⟧ ⟹
find_next_lms ST= abs_find_next_lms T"
unfolding find_next_lms_def abs_find_next_lms_def
apply (clarsimp simp: is_lms_refinement fun_eq_iff)
by argo
lemma lms_slice_refinement:
"⟦length ST = length T; ∀i < length T. ST ! i = suffix_type T i⟧ ⟹
lms_slice_ref T ST = lms_slice T"
unfolding lms_slice_ref_def lms_slice_def
by (clarsimp simp: find_next_lms_refinement fun_eq_iff)
section ‹Rename Mapping›
lemma rename_mapping'_refinement:
assumes "length ST = length T" "∀i < length T. ST ! i = suffix_type T i"
shows "rename_mapping' T ST = abs_rename_mapping' T"
proof (intro fun_eq_iff[THEN iffD2] allI)
fix xs ns i
show "rename_mapping' T ST xs ns i = abs_rename_mapping' T xs ns i"
using assms
proof (induct rule: rename_mapping'.induct[of _ T ST xs ns i])
case (1 T ST ns i)
then show ?case
by simp
next
case (2 T ST x ns i)
then show ?case
by simp
next
case (3 T ST a b xs ns i)
then show ?case
by (simp add: lms_slice_refinement)
qed
qed
lemma rename_mapping_refinement:
assumes "length ST = length T"
assumes "∀i < length T. ST ! i = suffix_type T i"
shows "rename_mapping T ST = abs_rename_mapping T"
by (clarsimp simp: fun_eq_iff assms rename_mapping'_refinement abs_rename_mapping_def
rename_mapping_def)
end