module StringRewriting.Rewrite (
    rewrite,
    rewrite',
    module StringRewriting,
  ) where

import StringRewriting

import qualified Math.Algebra.Group.StringRewriting as SR
import Control.Monad (forM)

rewrite' :: StringRewriting -> GWord -> GWord
rewrite' :: StringRewriting -> GWord -> GWord
rewrite' = [(GWord, GWord)] -> GWord -> GWord
forall a. Eq a => [([a], [a])] -> [a] -> [a]
SR.rewrite ([(GWord, GWord)] -> GWord -> GWord)
-> (StringRewriting -> [(GWord, GWord)])
-> StringRewriting
-> GWord
-> GWord
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Rule -> (GWord, GWord)) -> [Rule] -> [(GWord, GWord)]
forall a b. (a -> b) -> [a] -> [b]
map Rule -> (GWord, GWord)
toPair ([Rule] -> [(GWord, GWord)])
-> (StringRewriting -> [Rule])
-> StringRewriting
-> [(GWord, GWord)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rules -> [Rule]
forall c v. Listable c v => c -> [v]
toList (Rules -> [Rule])
-> (StringRewriting -> Rules) -> StringRewriting -> [Rule]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Getting Rules StringRewriting Rules -> StringRewriting -> Rules
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Rules StringRewriting Rules
Lens' StringRewriting Rules
rules

rewrite :: MonadFail m => StringRewriting -> String -> m String
rewrite :: StringRewriting -> String -> m String
rewrite StringRewriting
sr String
strIni = do
    GWord
gwIni <- [String] -> (String -> m Generator) -> m GWord
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM (String -> [String]
words String
strIni) ((String -> m Generator) -> m GWord)
-> (String -> m Generator) -> m GWord
forall a b. (a -> b) -> a -> b
$ \String
strGen -> StringRewriting
srStringRewriting
-> Getting (m Generator) StringRewriting (m Generator)
-> m Generator
forall s a. s -> Getting a s a -> a
^.(GeneratorsDescr -> Const (m Generator) GeneratorsDescr)
-> StringRewriting -> Const (m Generator) StringRewriting
Lens' StringRewriting GeneratorsDescr
generatorsDescr((GeneratorsDescr -> Const (m Generator) GeneratorsDescr)
 -> StringRewriting -> Const (m Generator) StringRewriting)
-> String -> Getting (m Generator) StringRewriting (m Generator)
forall c k v (m :: * -> *) x y.
(Indexable c k v, MonadFail m) =>
Getting x y c -> k -> Getting x y (m v)
.@String
strGen
    let gwRes :: GWord
gwRes = StringRewriting -> GWord -> GWord
rewrite' StringRewriting
sr GWord
gwIni
    [String]
strGens <- GWord -> (Generator -> m String) -> m [String]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM GWord
gwRes ((Generator -> m String) -> m [String])
-> (Generator -> m String) -> m [String]
forall a b. (a -> b) -> a -> b
$ \Generator
gen -> StringRewriting
srStringRewriting
-> Getting (m String) StringRewriting (m String) -> m String
forall s a. s -> Getting a s a -> a
^.(GeneratorsDescr -> Const (m String) GeneratorsDescr)
-> StringRewriting -> Const (m String) StringRewriting
Lens' StringRewriting GeneratorsDescr
generatorsDescr((GeneratorsDescr -> Const (m String) GeneratorsDescr)
 -> StringRewriting -> Const (m String) StringRewriting)
-> Generator -> Getting (m String) StringRewriting (m String)
forall c k v (m :: * -> *) x y.
(Indexable c k v, MonadFail m) =>
Getting x y c -> k -> Getting x y (m v)
.@Generator
gen
    String -> m String
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> m String) -> String -> m String
forall a b. (a -> b) -> a -> b
$ [String] -> String
unwords [String]
strGens