module Helpers where

import GrammarType
import TMType
import qualified Data.Map.Strict as Map
import GRType
import Data.Set (Set)
import qualified Data.Set as Set
import Text.Regex.TDFA
import Data.Maybe (fromMaybe)

disjoinQuotes :: Int -> Square -> Square
disjoinQuotes :: Int -> Square -> Square
disjoinQuotes Int
i (Value String
s Int
q_cnt) = String -> Int -> Square
Value String
s (Int -> Square) -> Int -> Square
forall a b. (a -> b) -> a -> b
$ Int
q_cnt Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
i
disjoinQuotes Int
_ (BCommand [TapeCommand]
c) = [TapeCommand] -> Square
PCommand [TapeCommand]
c
disjoinQuotes Int
_ Square
ES = Square
ES
disjoinQuotes Int
_ Square
s = String -> Square
forall a. HasCallStack => String -> a
error (String -> Square) -> String -> Square
forall a b. (a -> b) -> a -> b
$ String
"Must be Value, BCommand or ES: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Square -> String
forall a. Show a => a -> String
show Square
s

getDisjoinSquare2 :: Square -> Square
getDisjoinSquare2 :: Square -> Square
getDisjoinSquare2 = Int -> Square -> Square
disjoinQuotes Int
2

getDisjoinSquare :: Square -> Square
getDisjoinSquare :: Square -> Square
getDisjoinSquare = Int -> Square -> Square
disjoinQuotes Int
1

disjoinIfTerminal :: Symbol -> Square
disjoinIfTerminal :: Symbol -> Square
disjoinIfTerminal Symbol
letter =
    case Symbol
letter of
        GrammarType.T (Terminal String
c) -> String -> Int -> Square
Value String
c Int
1
        N (Nonterminal String
c) -> String -> Int -> Square
Value String
c Int
0
        Symbol
GrammarType.Eps -> String -> Square
forall a. HasCallStack => String -> a
error String
"Can not disjoin eps"

mapValue :: [String] -> [Square]
mapValue :: [String] -> [Square]
mapValue = (String -> Square) -> [String] -> [Square]
forall a b. (a -> b) -> [a] -> [b]
map (String -> Int -> Square
`Value` Int
0)

printSmb :: Map.Map A String -> SmbR -> String
printSmb :: Map A String -> SmbR -> String
printSmb Map A String
genmap (SmbA A
a) = String -> Maybe String -> String
forall a. a -> Maybe a -> a
fromMaybe (String -> String
forall a. HasCallStack => String -> a
error (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ A -> String
forall a. Show a => a -> String
show A
a) (A -> Map A String -> Maybe String
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup A
a Map A String
genmap)
printSmb Map A String
genmap (SmbA' A
a) = case A -> Map A String -> Maybe String
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup A
a Map A String
genmap of Just String
s -> String
"(" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
s String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")^(-1)" ; Maybe String
Nothing -> String -> String
forall a. HasCallStack => String -> a
error (A -> String
forall a. Show a => a -> String
show A
a)

revertSmb :: SmbR -> SmbR
revertSmb :: SmbR -> SmbR
revertSmb SmbR
smb = case SmbR
smb of SmbA A
a -> A -> SmbR
SmbA' A
a ; SmbA' A
a -> A -> SmbR
SmbA A
a

revertRel :: GrRelation -> [SmbR]
revertRel :: GrRelation -> [SmbR]
revertRel (GRType.Relation ([SmbR]
from, [SmbR]
to)) = ([SmbR] -> SmbR -> [SmbR]) -> [SmbR] -> [SmbR] -> [SmbR]
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl (\[SmbR]
x SmbR
y -> SmbR -> SmbR
revertSmb SmbR
y SmbR -> [SmbR] -> [SmbR]
forall a. a -> [a] -> [a]
: [SmbR]
x) [SmbR]
from [SmbR]
to
revertRel (Relator [SmbR]
smb) = [SmbR]
smb

genNextStateList :: [TMType.State] -> TMType.State
genNextStateList :: [State] -> State
genNextStateList [State]
tapeList = do
    let getNumber :: State -> Int
getNumber (TMType.State String
s) = String -> Int
forall a. Read a => String -> a
read String
n :: Int
            where (String
_, String
_, String
_, [String
n]) = String
s String -> String -> (String, String, String, [String])
forall source source1 target.
(RegexMaker Regex CompOption ExecOption source,
 RegexContext Regex source1 target) =>
source1 -> source -> target
=~ String
"q_{?([0-9]+)}?\\^{?[0-9]+\\.?[0-9]*}?" :: (String, String, String, [String])
    let stateNumber :: Int
stateNumber = Int -> Int -> Int
forall a. Num a => a -> a -> a
(+) Int
1 (Int -> Int) -> Int -> Int
forall a b. (a -> b) -> a -> b
$ [Int] -> Int
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum ([Int] -> Int) -> [Int] -> Int
forall a b. (a -> b) -> a -> b
$ (State -> Int) -> [State] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map State -> Int
getNumber [State]
tapeList
    let getTapeNumber :: State -> String
getTapeNumber (TMType.State String
s) = String
n
            where (String
_, String
_, String
_, [String
n]) = String
s String -> String -> (String, String, String, [String])
forall source source1 target.
(RegexMaker Regex CompOption ExecOption source,
 RegexContext Regex source1 target) =>
source1 -> source -> target
=~ String
"q_{?[0-9]+}?\\^{?([0-9]+\\.?[0-9]*)}?" :: (String, String, String, [String])
    let tapeNumber :: String
tapeNumber = State -> String
getTapeNumber (State -> String) -> State -> String
forall a b. (a -> b) -> a -> b
$ [State] -> State
forall a. [a] -> a
head [State]
tapeList
    String -> State
TMType.State (String -> State) -> String -> State
forall a b. (a -> b) -> a -> b
$ String
"q_{" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
stateNumber String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}^{" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
tapeNumber String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"}"

genNextState :: Set TMType.State -> TMType.State
genNextState :: Set State -> State
genNextState Set State
t = [State] -> State
genNextStateList ([State] -> State) -> [State] -> State
forall a b. (a -> b) -> a -> b
$ Set State -> [State]
forall a. Set a -> [a]
Set.toList Set State
t

mapTuple :: (a -> b) -> (a, a) -> (b, b)
mapTuple :: (a -> b) -> (a, a) -> (b, b)
mapTuple a -> b
f (a
a1, a
a2) = (a -> b
f a
a1, a -> b
f a
a2)

defValue :: String -> Square
defValue :: String -> Square
defValue String
s = String -> Int -> Square
Value String
s Int
0