module SP2SR (
    sp2sr,
    sp2sr',
  ) where

import qualified SemigroupPresentation as SP
import SemigroupPresentation (
    SemigroupPresentation,
    relations,
    generatorsDescr
  )
import qualified StringRewriting as SR
import StringRewriting.KnuthBendix (StringRewriting, Order, knuthBendixBy)
import Containers
import Lens

gen :: SP.Generator -> SR.Generator
gen :: Generator -> Generator
gen = Int -> Generator
SR.generator (Int -> Generator) -> (Generator -> Int) -> Generator -> Generator
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Generator -> Int
SP.numGenerator

genOrder :: Order SP.Generator -> Order SR.Generator
genOrder :: Order Generator -> Order Generator
genOrder = (Order Generator -> (Generator -> Generator) -> Order Generator
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` (Int -> Generator
SP.generator (Int -> Generator) -> (Generator -> Int) -> Generator -> Generator
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Generator -> Int
SR.numGenerator))

sp2sr ::
    MonadFail m =>
    Order SP.Generator ->
    SemigroupPresentation ->
    m StringRewriting
sp2sr :: Order Generator -> SemigroupPresentation -> m StringRewriting
sp2sr Order Generator
go SemigroupPresentation
sp = StringRewriting -> m StringRewriting
forall (m :: * -> *) a. Monad m => a -> m a
return (StringRewriting -> m StringRewriting)
-> StringRewriting -> m StringRewriting
forall a b. (a -> b) -> a -> b
$
    Order Generator
-> Set (Pair GWord) -> GeneratorsDescr -> StringRewriting
knuthBendixBy
        (Order Generator -> Order Generator
genOrder Order Generator
go)
        (((Pair [Generator] -> Pair GWord) -> Relations -> Set (Pair GWord)
forall c1 c2 v1 v2. Gunctor c1 c2 v1 v2 => (v1 -> v2) -> c1 -> c2
gmap((Pair [Generator] -> Pair GWord) -> Relations -> Set (Pair GWord))
-> ((Generator -> Generator) -> Pair [Generator] -> Pair GWord)
-> (Generator -> Generator)
-> Relations
-> Set (Pair GWord)
forall b c a. (b -> c) -> (a -> b) -> a -> c
.([Generator] -> GWord) -> Pair [Generator] -> Pair GWord
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap(([Generator] -> GWord) -> Pair [Generator] -> Pair GWord)
-> ((Generator -> Generator) -> [Generator] -> GWord)
-> (Generator -> Generator)
-> Pair [Generator]
-> Pair GWord
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(Generator -> Generator) -> [Generator] -> GWord
forall a b. (a -> b) -> [a] -> [b]
map) Generator -> Generator
gen (Relations -> Set (Pair GWord)) -> Relations -> Set (Pair GWord)
forall a b. (a -> b) -> a -> b
$ SemigroupPresentation
spSemigroupPresentation
-> Getting Relations SemigroupPresentation Relations -> Relations
forall s a. s -> Getting a s a -> a
^.Getting Relations SemigroupPresentation Relations
Lens' SemigroupPresentation Relations
relations)
        ((Generator -> Generator) -> GeneratorsDescr -> GeneratorsDescr
forall c1 c2 v1 v2. Gunctor c1 c2 v1 v2 => (v1 -> v2) -> c1 -> c2
gmap Generator -> Generator
gen (GeneratorsDescr -> GeneratorsDescr)
-> GeneratorsDescr -> GeneratorsDescr
forall a b. (a -> b) -> a -> b
$ SemigroupPresentation
spSemigroupPresentation
-> Getting GeneratorsDescr SemigroupPresentation GeneratorsDescr
-> GeneratorsDescr
forall s a. s -> Getting a s a -> a
^.Getting GeneratorsDescr SemigroupPresentation GeneratorsDescr
Lens' SemigroupPresentation GeneratorsDescr
generatorsDescr)

sp2sr' :: MonadFail m => SemigroupPresentation -> m StringRewriting
sp2sr' :: SemigroupPresentation -> m StringRewriting
sp2sr' = Order Generator -> SemigroupPresentation -> m StringRewriting
forall (m :: * -> *).
MonadFail m =>
Order Generator -> SemigroupPresentation -> m StringRewriting
sp2sr Order Generator
forall a. Ord a => a -> a -> Ordering
compare