Theory Abs_SAIS
theory Abs_SAIS
imports "../prop/Buckets"
"../prop/LMS_List_Slice_Util"
"../../util/Repeat"
begin
section ‹Induce Sorting›
subsection ‹Bucket Insert›
fun abs_bucket_insert ::
"(('a :: {linorder, order_bot}) ⇒ nat) ⇒
'a list ⇒
nat list ⇒
nat list ⇒
nat list ⇒
nat list"
where
"abs_bucket_insert α T _ SA [] = SA" |
"abs_bucket_insert α T B SA (x # xs) =
(let b = α (T ! x);
k = B ! b - Suc 0;
SA' = SA[k := x];
B' = B[b := k]
in abs_bucket_insert α T B' SA' xs)"
subsection ‹Induce L-types›
fun abs_induce_l_step ::
"nat list × nat list × nat ⇒
(('a :: {linorder, order_bot}) ⇒ nat) × 'a list ⇒
nat list × nat list × nat"
where
"abs_induce_l_step (B, SA, i) (α, T) =
(if i < length SA ∧ SA ! i < length T
then
(case SA ! i of
Suc j ⇒
(case suffix_type T j of
L_type ⇒
(let k = α (T ! j);
l = B ! k
in (B[k := Suc l], SA[l := j], Suc i))
| _ ⇒ (B, SA, Suc i))
| _ ⇒ (B, SA, Suc i))
else (B, SA, Suc i))"
definition abs_induce_l_base ::
"(('a :: {linorder, order_bot}) ⇒ nat) ⇒
'a list ⇒
nat list ⇒
nat list ⇒
nat list × nat list × nat"
where
"abs_induce_l_base α T B SA = repeat (length T) abs_induce_l_step (B, SA, 0) (α, T)"
definition abs_induce_l ::
"(('a :: {linorder, order_bot}) ⇒ nat) ⇒
'a list ⇒
nat list ⇒
nat list ⇒
nat list"
where
"abs_induce_l α T B SA =
(let (B', SA', i) = abs_induce_l_base α T B SA
in SA')"
subsection ‹Induce S-types›
fun abs_induce_s_step ::
"nat list × nat list × nat ⇒
(('a :: {linorder, order_bot}) ⇒ nat) × 'a list ⇒
nat list × nat list × nat"
where
"abs_induce_s_step (B, SA, i) (α, T) =
(case i of
Suc n ⇒
(if Suc n < length SA ∧ SA ! Suc n < length T then
(case SA ! Suc n of
Suc j ⇒
(case suffix_type T j of
S_type ⇒
(let b = α (T ! j);
k = B ! b - Suc 0
in (B[b := k], SA[k := j], n)
)
| _ ⇒ (B, SA, n)
)
| _ ⇒ (B, SA, n)
)
else
(B, SA, n)
)
| _ ⇒ (B, SA, 0)
)"
definition abs_induce_s_base ::
"(('a :: {linorder, order_bot}) ⇒ nat) ⇒
'a list ⇒
nat list ⇒
nat list ⇒
nat list × nat list × nat"
where
"abs_induce_s_base α T B SA = repeat (length T) abs_induce_s_step (B, SA, length T) (α, T)"
definition abs_induce_s ::
"(('a :: {linorder, order_bot}) ⇒ nat) ⇒
'a list ⇒
nat list ⇒
nat list ⇒
nat list"
where
"abs_induce_s α T B SA =
(let (B', SA', i) = abs_induce_s_base α T B SA
in SA')"
subsection ‹Induce Sorting›
definition abs_sa_induce ::
"(('a :: {linorder, order_bot}) ⇒ nat) ⇒
'a list ⇒
nat list ⇒
nat list"
where
"abs_sa_induce α T LMS =
(let
B0 = map (bucket_end α T) [0..<Suc (α (Max (set T)))];
B1 = map (bucket_start α T) [0..<Suc (α (Max (set T)))];
SA = replicate (length T) (length T);
SA = abs_bucket_insert α T B0 SA (rev LMS);
SA = abs_induce_l α T B1 SA
in abs_induce_s α T (B0[0 := 0]) SA)"
section ‹Rename Mapping›
fun abs_rename_mapping' ::
"('a :: {linorder, order_bot}) list ⇒
nat list ⇒
nat list ⇒
nat ⇒
nat list"
where
"abs_rename_mapping' _ [] names _ = names" |
"abs_rename_mapping' _ [x] names i = names[x := i]" |
"abs_rename_mapping' T (a # b # xs) names i =
(if lms_slice T a = lms_slice T b
then abs_rename_mapping' T (b # xs) (names[a := i]) i
else abs_rename_mapping' T (b # xs) (names[a := i]) (Suc i))"
definition abs_rename_mapping :: "('a :: {linorder, order_bot}) list ⇒ nat list ⇒ nat list"
where
"abs_rename_mapping T LMS = abs_rename_mapping' T LMS (replicate (length T) (length T)) 0"
section ‹Rename String›
fun rename_string :: "nat list ⇒ nat list ⇒ nat list"
where
"rename_string [] _ = []" |
"rename_string (x#xs) names = (names ! x) # rename_string xs names"
section ‹Order LMS›
fun order_lms :: "nat list ⇒ nat list ⇒ nat list"
where
"order_lms LMS [] = []" |
"order_lms LMS (x # xs) = LMS ! x # order_lms LMS xs"
section ‹Extract LMS›
abbreviation :: "('a :: {linorder, order_bot}) list ⇒ nat list ⇒ nat list"
where
"abs_extract_lms ≡ filter ∘ abs_is_lms "
section ‹SAIS Definition›
function abs_sais ::
"nat list ⇒
nat list"
where
"abs_sais [] = []" |
"abs_sais [x] = [0]" |
"abs_sais (a # b # xs) =
(let
T = a # b # xs;
LMS0 = abs_extract_lms T [0..<length T];
SA = abs_sa_induce id T LMS0;
LMS = abs_extract_lms T SA;
names = abs_rename_mapping T LMS;
T' = rename_string LMS0 names;
LMS = (if distinct T' then LMS else order_lms LMS0 (abs_sais T'))
in abs_sa_induce id T LMS)"
by pat_completeness blast+
end