-- |Module `TuringMachine.Optimization.Safe` include function `secure` for
--  increasing of security of Turing machine.
module TuringMachine.Optimization.Safe (
    secure,
  ) where

import TuringMachine as TM
import Containers.Set (cartesianProduct)

loop :: State -> Symbol -> TM.Quadruple
loop :: State -> Symbol -> Quadruple
loop State
q Symbol
s = ((State
q, Symbol
s), (Symbol -> MoveOr Symbol
forall s. s -> MoveOr s
S Symbol
s, State
q))

addQs :: TuringMachine -> Quadruples
addQs :: TuringMachine -> Quadruples
addQs TuringMachine
tm =
    let allQs :: Set State
allQs = (TuringMachine
tmTuringMachine
-> Getting (Set State) TuringMachine (Set State) -> Set State
forall s a. s -> Getting a s a -> a
^.Getting (Set State) TuringMachine (Set State)
TMGetter (Set State)
allStates) Set State -> State -> Set State
forall c v. Deletable c v => c -> v -> c
<\ State
finalState
        allSs :: Set Symbol
allSs = TuringMachine
tmTuringMachine
-> Getting (Set Symbol) TuringMachine (Set Symbol) -> Set Symbol
forall s a. s -> Getting a s a -> a
^.Getting (Set Symbol) TuringMachine (Set Symbol)
TMGetter (Set Symbol)
allSymbols
        qsFstParts :: Set (State, Symbol)
qsFstParts = Quadruples -> Set (State, Symbol)
forall c k. (Keyable c k, Ord k) => c -> Set k
keysSet (TuringMachine
tmTuringMachine
-> Getting Quadruples TuringMachine Quadruples -> Quadruples
forall s a. s -> Getting a s a -> a
^.Getting Quadruples TuringMachine Quadruples
Lens' TuringMachine Quadruples
quadruples)
        allFstParts :: Set (State, Symbol)
allFstParts = Set State -> Set Symbol -> Set (State, Symbol)
forall a b. Set a -> Set b -> Set (a, b)
cartesianProduct Set State
allQs Set Symbol
allSs
        notQsFstParts :: Set (State, Symbol)
notQsFstParts = Set (State, Symbol)
allFstParts Set (State, Symbol) -> Set (State, Symbol) -> Set (State, Symbol)
forall c. Operable c => c -> c -> c
\\ Set (State, Symbol)
qsFstParts
    in  [Quadruple] -> Quadruples
forall c v. FastUnsafeListable c v => [v] -> c
fromDistinctAscList ([Quadruple] -> Quadruples) -> [Quadruple] -> Quadruples
forall a b. (a -> b) -> a -> b
$
            ((State, Symbol) -> Quadruple) -> [(State, Symbol)] -> [Quadruple]
forall a b. (a -> b) -> [a] -> [b]
map ((State -> Symbol -> Quadruple) -> (State, Symbol) -> Quadruple
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry State -> Symbol -> Quadruple
loop) ([(State, Symbol)] -> [Quadruple])
-> [(State, Symbol)] -> [Quadruple]
forall a b. (a -> b) -> a -> b
$
                Set (State, Symbol) -> [(State, Symbol)]
forall c v. Listable c v => c -> [v]
toList Set (State, Symbol)
notQsFstParts

secure :: TuringMachine -> TuringMachine
secure :: TuringMachine -> TuringMachine
secure = do
    Quadruples
aqs <- TuringMachine -> Quadruples
addQs
    (Quadruples -> Identity Quadruples)
-> TuringMachine -> Identity TuringMachine
Lens' TuringMachine Quadruples
quadruples ((Quadruples -> Identity Quadruples)
 -> TuringMachine -> Identity TuringMachine)
-> (Quadruples -> Quadruples) -> TuringMachine -> TuringMachine
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ (Quadruples -> Quadruples -> Quadruples
forall c. Operable c => c -> c -> c
\/ Quadruples
aqs)