module Numeric.YHSeq.V0111.Expansion
( badRoot
, goodPart
, badPart
, cuttedPart
, pnt
, anc
, badRootL
, delta
, amt
, bas
, rising
, ris
, newD
, newP
, newN
, copiedBadPart
, expand
) where
import Prelude hiding (length)
import Numeric.YHSeq.V0111.Type
badRoot :: DPN -> Index
badRoot z = last $ indexP z (lengthDPN z)
goodPart :: DPN -> DPN
goodPart z = sliceDPN 1 (badRoot z - 1) z
badPart :: DPN -> DPN
badPart z = sliceDPN (badRoot z) (lengthDPN z - 1) z
cuttedPart :: DPN -> DPN
cuttedPart z = sliceDPN (lengthDPN z) (lengthDPN z) z
pnt :: DPN -> Index -> Depth -> ParentIndex
pnt z x n = if x <= 0
then error "pnt: non-positive index"
else if n > indexN z x
then 0
else idx (reverse $ indexP z x) (indexN z x - n)
anc :: DPN -> Index -> Depth -> [ParentIndex]
anc z x n = if x <= 0
then error "anc: non-positive index"
else if n <= 0
then error "anc: non-positive depth"
else anc' z x n
anc' :: DPN -> Index -> Depth -> [ParentIndex]
anc' z x n = case x `compare` 0 of
LT -> error "anc: irregular value of pnt"
EQ -> []
GT -> x : anc' z (pnt z x n) n
badRootL :: DPN -> Index
badRootL z = badRoot z
delta :: DPN -> Integer
delta z = lengthDPN z - badRootL z
amt :: DPN -> Index -> Bool
amt z y = badRootL z `elem` anc z (badRootL z - 1 + y) 1
bas :: DPN -> Index -> ParentList
bas z y = if y == 1
then indexP z (lengthDPN z)
else indexP z (badRootL z - 1 + y)
rising :: DPN -> Integer -> Index -> ParentIndex -> ParentIndex
rising z m y p = if amt z y
then p + m * delta z
else p
ris :: DPN -> Integer -> Index -> ParentList -> ParentList
ris z m y p = map (\q -> rising z m y q) p
newD :: DPN -> Integer -> Index -> Diff
newD z m y = indexD z (badRootL z - 1 + y)
newP :: DPN -> Integer -> Index -> ParentList
newP z m y = if y == 1
then ris z (m - 1) y (bas z y)
else ris z m y (bas z y)
newN :: DPN -> Integer -> Index -> Depth
newN z m y = indexN z (badRootL z - 1 + y)
copiedBadPart :: DPN -> Integer -> DPN
copiedBadPart z m = if m == 0
then badPart z
else map (\y -> (newD z m y, newP z m y, newN z m y)) $
enumFromTo 1 (delta z)
expand :: DPN -> Class -> Integer -> DPN
expand z c n = case c `compare` 1 of
LT -> error "expand: non-positive class"
EQ -> goodPart z ++ concat (map (\m -> copiedBadPart z m) $ enumFromTo 0 n)
GT -> error "expand: is undefined at 0.1.1.0 when class is greater than 1"