```module Numeric.YHSeq.V0111.Expansion
, goodPart
, cuttedPart
, pnt
, anc
, delta
, amt
, bas
, rising
, ris
, newD
, newP
, newN
, expand
) where

import Prelude hiding (length)

import Numeric.YHSeq.V0111.Type

badRoot z = last \$ indexP z (lengthDPN z)

goodPart :: DPN -> DPN
goodPart z = sliceDPN 1 (badRoot 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

delta :: DPN -> Integer
delta z = lengthDPN z - badRootL z

-- ascension matrix
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