Theory Abs_Induce_Verification
theory Abs_Induce_Verification
imports
Abs_Induce_L_Verification
Abs_Induce_S_Verification
Abs_Bucket_Insert_Verification
begin
section "Bucket Initialisation Properties"
lemma l_bucket_init_map_bucket_start:
"l_bucket_init α T (map (bucket_start α T) [0..<Suc (α (Max (set T)))])"
unfolding l_bucket_init_def
by (metis add.left_neutral diff_zero le_imp_less_Suc length_map length_upt lessI nth_map_upt)
lemma lms_bucket_init_map_bucket_end:
"lms_bucket_init α T (map (bucket_end α T) [0..<Suc (α (Max (set T)))])"
unfolding lms_bucket_init_def
by (metis add.left_neutral diff_zero le_imp_less_Suc length_map length_upt lessI nth_map_upt)
lemma s_bucket_init_map_bucket_end:
"s_bucket_init α T ((map (bucket_end α T) [0..<Suc (α (Max (set T)))])[0 := 0])"
unfolding s_bucket_init_def
by (metis (no_types, lifting) length_greater_0_conv length_list_update list.size(3)
nth_list_update lms_bucket_init_def lms_bucket_init_map_bucket_end)
abbreviation "bucket_starts α T ≡ map (bucket_start α T) [0..<Suc (α (Max (set T)))]"
abbreviation "bucket_ends α T ≡ map (bucket_end α T) [0..<Suc (α (Max (set T)))]"
section "Bucket Insert Precondition"
lemma lms_pre_established:
assumes "set LMS = {i. abs_is_lms T i}"
and "distinct LMS"
and "strict_mono α"
shows "lms_pre α T (bucket_ends α T) (replicate (length T) (length T)) (rev LMS)"
(is "lms_pre α T ?B ?SA (rev LMS)")
proof -
from lms_bucket_init_map_bucket_end[of α T]
have "lms_bucket_init α T ?B" .
then show "lms_pre α T ?B ?SA0 (rev LMS)"
by (clarsimp simp: lms_pre_def `lms_bucket_init α T ?B` assms
simp del: upt_Suc)
qed
section "Induce L Precondition"
lemma l_perm_pre_established:
assumes "valid_list T"
and "strict_mono α"
and "lms_pre α T B SA (rev LMS)"
shows "l_perm_pre α T (bucket_starts α T) (abs_bucket_insert α T B SA (rev LMS))"
(is "l_perm_pre α T ?B ?SA")
unfolding l_perm_pre_def
proof safe
show "lms_init α T ?SA"
by (metis assms(3) abs_bucket_insert_vals lms_init_def lms_vals_postD)
next
show "l_init α T ?SA"
unfolding l_init_def
proof (intro allI impI; elim conjE)
fix b i
assume "b ≤ α (Max (set T))" "i < length ?SA" "bucket_start α T b ≤ i"
"i < l_bucket_end α T b"
hence "i < lms_bucket_start α T b"
using l_bucket_end_le_lms_bucket_start less_le_trans by blast
with lms_unknowns_postD[OF abs_bucket_insert_unknowns[OF assms(3)] `b ≤ _`
`bucket_start _ _ _ ≤ _`]
show "?SA ! i = length T" .
qed
next
show "s_init α T ?SA"
unfolding s_init_def
proof (intro allI impI; elim conjE)
fix b i
assume "b ≤ α (Max (set T))" "i < length ?SA" "l_bucket_end α T b ≤ i"
"i < lms_bucket_start α T b"
hence "bucket_start α T b ≤ i"
by (simp add: l_bucket_end_def)
with lms_unknowns_postD[OF abs_bucket_insert_unknowns[OF assms(3)] `b ≤ _` _
`i < lms_bucket_start _ _ _`]
show "?SA ! i = length T" .
qed
next
from l_bucket_init_map_bucket_start[of α T]
show "l_bucket_init α T ?B" .
next
show "length ?SA = length T"
by (metis assms(3) abs_bucket_insert_length lms_pre_elims(2))
qed (force simp: valid_list_not_nil[OF assms(1)] assms(2))+
section "Induce S Precondition"
lemma s_perm_pre_established:
assumes "valid_list T"
and "strict_mono α"
and "α bot = 0"
and "Suc 0 < length T"
and "lms_pre α T B0 SA0 (rev LMS)"
and "SA1 = abs_bucket_insert α T B0 SA0 (rev LMS)"
and "l_perm_pre α T B1 SA1"
shows "s_perm_pre α T ((bucket_ends α T)[0 := 0]) (abs_induce_l α T B1 SA1) (length T)"
(is "s_perm_pre α T ?B ?SA ?n")
unfolding s_perm_pre_def
proof (intro conjI)
from s_bucket_init_map_bucket_end[of α T]
show "s_bucket_init α T ?B" .
next
from valid_list_length_ex[OF assms(1)]
obtain n where
"length T = Suc n"
by blast
hence "∃m. length T = Suc (Suc m)"
using assms(4) old.nat.exhaust by auto
then obtain m where
"length T = Suc (Suc m)"
by blast
from abs_bucket_insert_bot_first[OF assms(5,1) `length T = Suc (Suc m)` assms(3)]
have "SA1 ! 0 = n"
using ‹length T = Suc (Suc m)› ‹length T = Suc n› assms(6) by auto
have "0 ≤ α (Max (set T))"
by simp
moreover
have "s_bucket_start α T 0 ≤ 0"
by (simp add: assms(1-3) valid_list_s_bucket_start_0)
moreover
have "0 < bucket_end α T 0"
by (simp add: assms(1-3) valid_list_bucket_end_0)
ultimately have "?SA ! 0 = SA1 ! 0"
using abs_induce_l_unchanged[OF `l_perm_pre _ _ _ _`, of 0 0]
by blast
with `SA1 ! 0 = n`
have "?SA ! 0 = n"
by simp
with `length T = Suc n`
show "s_type_init T ?SA"
using s_type_init_def by blast
next
show "length ?SA = length T"
by (metis abs_induce_l_length assms(7) l_perm_pre_elims(7))
next
from abs_induce_l_distinct_l_bucket[OF assms(7)]
abs_induce_l_list_slice_l_bucket[OF assms(7)]
show "l_types_init α T ?SA"
by (simp add: l_types_init_def)
qed(force simp: assms)+
section "Permutation"
lemma abs_sa_induce_permutation:
assumes "set LMS = {i. abs_is_lms T i}"
and "distinct LMS"
and "valid_list T"
and "strict_mono α"
and "α bot = 0"
and "Suc 0 < length T"
shows "abs_sa_induce α T LMS <~~> [0..< length T]"
proof -
let ?B0 = "map (bucket_end α T) [0..<Suc (α (Max (set T)))]" and
?B1 = "map (bucket_start α T) [0..<Suc (α (Max (set T)))]" and
?SA0 = "replicate (length T) (length T)"
let ?B2 = "?B0[0 := 0]"
let ?SA1 = "abs_bucket_insert α T ?B0 ?SA0 (rev LMS)"
let ?SA2 = "abs_induce_l α T ?B1 ?SA1"
let ?SA3 = "abs_induce_s α T (?B0[0 := 0]) ?SA2"
from lms_pre_established[OF assms(1,2,4)]
have "lms_pre α T ?B0 ?SA0 (rev LMS)" .
have "l_perm_pre α T ?B1 ?SA1"
using ‹lms_pre α T ?B0 ?SA0 (rev LMS)› assms(3,4) l_perm_pre_established by blast
have "s_perm_pre α T ?B2 ?SA2 (length T)"
using ‹l_perm_pre α T ?B1 ?SA1› ‹lms_pre α T ?B0 ?SA0 (rev LMS)› assms(3-6)
s_perm_pre_established by blast
with abs_induce_s_perm[of α T "?B0[0 := 0]" ?SA2]
have "?SA3 <~~> [0..< length T]"
by blast
then show ?thesis
by (metis abs_sa_induce_def)
qed
section "Sorting"
lemma abs_sa_induce_suffix_sorted:
assumes "set LMS = {i. abs_is_lms T i}"
and "distinct LMS"
and "valid_list T"
and "strict_mono α"
and "α bot = 0"
and "Suc 0 < length T"
and "ordlistns.sorted (map (suffix T) LMS)"
shows "ordlistns.sorted (map (suffix T) (abs_sa_induce α T LMS))"
proof -
let ?B0 = "map (bucket_end α T) [0..<Suc (α (Max (set T)))]" and
?B1 = "map (bucket_start α T) [0..<Suc (α (Max (set T)))]" and
?SA0 = "replicate (length T) (length T)"
let ?B2 = "?B0[0 := 0]"
let ?SA1 = "abs_bucket_insert α T ?B0 ?SA0 (rev LMS)"
let ?SA2 = "abs_induce_l α T ?B1 ?SA1"
let ?SA3 = "abs_induce_s α T (?B0[0 := 0]) ?SA2"
from lms_pre_established[OF assms(1,2,4)]
have "lms_pre α T ?B0 ?SA0 (rev LMS)" .
have P0:
"∀b ≤ α (Max (set T)).
ordlistns.sorted (map (suffix T)
(list_slice ?SA1 (lms_bucket_start α T b) (bucket_end α T b)))"
proof(intro allI impI)
fix b
assume "b ≤ α (Max (set T))"
from lms_suffix_sorted_bucket[OF `lms_pre _ _ _ _ _` _ `b ≤ _`] assms(7)
show "ordlistns.sorted (map (suffix T)
(list_slice ?SA1 (lms_bucket_start α T b) (bucket_end α T b)))"
by simp
qed
have "l_perm_pre α T ?B1 ?SA1"
using ‹lms_pre α T ?B0 ?SA0 (rev LMS)› assms(3,4) l_perm_pre_established by blast
moreover
have "l_suffix_sorted_pre α T ?SA1"
using P0 l_suffix_sorted_pre_def by blast
ultimately have P1:
"∀b ≤ α (Max (set T)).
ordlistns.sorted (map (suffix T) (list_slice ?SA2 (bucket_start α T b) (l_bucket_end α T b)))"
using abs_induce_l_suffix_sorted_l_bucket by blast
have "s_perm_pre α T ?B2 ?SA2 (length T)"
using ‹l_perm_pre α T ?B1 ?SA1› ‹lms_pre α T ?B0 ?SA0 (rev LMS)› assms(3-6)
s_perm_pre_established by blast
moreover
have "s_sorted_pre α T ?SA2"
using P1 s_sorted_pre_def by blast
ultimately show ?thesis
by (metis abs_induce_s_sorted abs_sa_induce_def)
qed
theorem abs_sa_induce_prefix_sorted:
assumes "set LMS = {i. abs_is_lms T i}"
and "distinct LMS"
and "valid_list T"
and "strict_mono α"
and "α bot = 0"
and "Suc 0 < length T"
shows "ordlistns.sorted (map (lms_slice T) (abs_sa_induce α T LMS))"
proof -
let ?B0 = "map (bucket_end α T) [0..<Suc (α (Max (set T)))]" and
?B1 = "map (bucket_start α T) [0..<Suc (α (Max (set T)))]" and
?SA0 = "replicate (length T) (length T)"
let ?B2 = "?B0[0 := 0]"
let ?SA1 = "abs_bucket_insert α T ?B0 ?SA0 (rev LMS)"
let ?SA2 = "abs_induce_l α T ?B1 ?SA1"
let ?SA3 = "abs_induce_s α T (?B0[0 := 0]) ?SA2"
from lms_pre_established[OF assms(1,2,4)]
have "lms_pre α T ?B0 ?SA0 (rev LMS)" .
have P0:
"∀b ≤ α (Max (set T)).
ordlistns.sorted (map (lms_prefix T)
(list_slice ?SA1 (lms_bucket_start α T b) (bucket_end α T b)))"
proof(intro allI impI)
fix b
assume "b ≤ α (Max (set T))"
from lms_prefix_sorted_bucket[OF `lms_pre _ _ _ _ _` `b ≤ _`]
show "ordlistns.sorted (map (lms_prefix T)
(list_slice ?SA1 (lms_bucket_start α T b) (bucket_end α T b)))"
by simp
qed
have "l_perm_pre α T ?B1 ?SA1"
using ‹lms_pre α T ?B0 ?SA0 (rev LMS)› assms(3,4) l_perm_pre_established by blast
moreover
have "l_prefix_sorted_pre α T ?SA1"
using P0 l_prefix_sorted_pre_def by blast
ultimately have P1:
"∀b ≤ α (Max (set T)).
ordlistns.sorted (map (lms_prefix T)
(list_slice ?SA2 (bucket_start α T b) (l_bucket_end α T b)))"
using abs_induce_l_prefix_sorted_l_bucket by blast
have P2:
"∀b ≤ α (Max (set T)).
ordlistns.sorted (map (lms_slice T)
(list_slice ?SA2 (bucket_start α T b) (l_bucket_end α T b)))"
proof (intro allI impI sorted_wrt_mapI)
fix b i j
let ?xs = "list_slice ?SA2 (bucket_start α T b) (l_bucket_end α T b)" and
?R1 = "(λx y. list_less_eq_ns (lms_prefix T x) (lms_prefix T y))" and
?R2 = "(λx y. list_less_eq_ns (lms_slice T x) (lms_slice T y))"
assume "b ≤ α (Max (set T))" "i < j" "j < length ?xs"
with P1
have "ordlistns.sorted (map (lms_prefix T) ?xs)"
by blast
with sorted_wrt_mapD[OF _ ‹i < j› ‹j < length ?xs›]
have "list_less_eq_ns (lms_prefix T (?xs ! i)) (lms_prefix T (?xs ! j))"
by blast
moreover
from abs_induce_l_list_slice_l_bucket[OF `l_perm_pre _ _ _ _` `b ≤ _`]
have "?xs ! i ∈ l_bucket α T b"
using Suc_lessD ‹i < j› ‹j < length ?xs› less_trans_Suc nth_mem by blast
hence "suffix_type T (?xs ! i) = L_type"
using l_bucket_def bucket_def by blast
hence "lms_prefix T (?xs ! i) = lms_slice T (?xs ! i)"
by (metis SL_types.distinct(1) abs_is_lms_def not_lms_imp_next_eq_lms_prefix)
moreover
from abs_induce_l_list_slice_l_bucket[OF `l_perm_pre _ _ _ _` `b ≤ _`]
have "?xs ! j ∈ l_bucket α T b"
using ‹j < length ?xs› less_trans_Suc nth_mem by blast
hence "suffix_type T (?xs ! j) = L_type"
using l_bucket_def bucket_def by blast
hence "lms_prefix T (?xs ! j) = lms_slice T (?xs ! j)"
by (metis SL_types.distinct(1) abs_is_lms_def not_lms_imp_next_eq_lms_prefix)
ultimately show "list_less_eq_ns (lms_slice T (?xs ! i)) (lms_slice T (?xs ! j))"
by order
qed
have "s_perm_pre α T ?B2 ?SA2 (length T)"
using ‹l_perm_pre α T ?B1 ?SA1› ‹lms_pre α T ?B0 ?SA0 (rev LMS)› assms(3-6)
s_perm_pre_established by blast
moreover
have "s_prefix_sorted_pre α T ?SA2"
using P2 s_prefix_sorted_pre_def by blast
ultimately show ?thesis
by (metis abs_induce_s_prefix_sorted abs_sa_induce_def)
qed
end