module Math.Model.Automaton.Finite
(
Delta(..)
,liftD
,Lambda1(..)
,liftL1
,Lambda2(..)
,liftL2
,FiniteA(..)
,Transductor(..)
,checkString
,translate
,DeltaN(..)
,liftDN
,FiniteAN(..)
,checkStringN
) where
import Data.State
import Data.Sigma
import Data.Delta
import Data.List
import Data.Monoid
import Control.Monad
import qualified Data.Map.Lazy as Map
import qualified Data.Foldable as Fold
type Delta a = (:->:) a Symbol ()
liftD::(Ord a) => [(a,Symbol,a)] -> Delta a
liftD ds = let
(xs,ys,zs) = unzip3 ds
f = map return
xys = zip (f xs) ys
qzs = zip (f zs) (repeat ())
in Map.fromList (zip xys qzs)
type Lambda1 a = (:*>:) a () Symbol
liftL1::(Ord a) => [(a, Symbol)] -> Lambda1 a
liftL1 ds = let
(xs, ys) = unzip ds
f = map return
nds = zip (zip (f xs) (repeat ())) ys
in Map.fromList nds
type Lambda2 a = (:*>:) a Symbol Symbol
liftL2::(Ord a) => [(a, Symbol, Symbol)] -> Lambda2 a
liftL2 ds = let
(xs, ys, zs) = unzip3 ds
f = map return
nds = zip (zip (f xs) ys) zs
in Map.fromList nds
data FiniteA a =
F (Delta a) (Final a) (State a) deriving(Show, Eq)
checkString::(Ord a) => FiniteA a -> Wd -> Bool
checkString (F d qF s) ws = let
q = checkString' d s ws
f y = ((not.isError) y)&&(terminal qF y)
in f q
where
checkString' _ q [] = q
checkString' dt q (x:xs) = checkString' dt (nextD dt (q,x)) xs
data Transductor a =
Moore (Delta a) (Lambda1 a) (Final a) (State a)
|Mealy (Delta a) (Lambda2 a) (Final a) (State a) deriving(Show, Eq)
translate::(Ord a) => Transductor a -> Wd -> Wd
translate (Moore d l qF s) ws = let
(q, w) = translate d l s ws []
in w
where
translate _ _ QE xs ys = (QE, "Error: \nCadena:"++xs++"\nResp parcial: "++ys)
translate _ _ q [] xs = (q, xs)
translate dt lm q (y:ys) xs = translate dt lm (nextD dt (q,y)) ys (xs++[lm Map.! (q, ())])
translate (Mealy d l qF s) ws = let
(q, w) = translate d l s ws []
in ws
where
translate _ _ QE xs ys = (QE, "Error: \nCadena:"++xs++"\nResp parcial: "++ys)
translate _ _ q [] xs = (q, xs)
translate dt lm q (x:xs) ys = translate dt lm (nextD dt (q, x)) xs (ys++[lm Map.! (q,x)])
type DeltaN a = (:>-:) a Symbol ()
liftDN::(Ord a) => [(a,Symbol,[a])] -> DeltaN a
liftDN ds = let
(xs,ys,zs) = unzip3 ds
f = map return
xys = zip (f xs) ys
qzs = zip (map f zs) (repeat ())
in Map.fromList (zip xys qzs)
data FiniteAN a =
FN (DeltaN a) (Final a) (State a) deriving(Show,Eq)
checkStringN::(Ord a) => FiniteAN a -> Wd -> Bool
checkStringN (FN dn qF s) ws = let
qs = checkStringN' dn [s] ws
f y = ((not.isError) y)&&(terminal qF y)
g y = or (map f y)
in g qs
where
check dt k = if Map.member k dt then dt Map.! k else ([QE], ())
mDelta dt lq a = (nub.concat.(map fst)) (map (\q -> check dt (q,a)) lq)
checkStringN' _ qs [] = qs
checkStringN' dn qs (x:xs) = checkStringN' dn (mDelta dn qs x) xs