{-# LANGUAGE RankNTypes #-}

module SemigroupPresentation.Relation (
    Relation,
    relation,
    relator,
    Relations,
    StrRelation,
    forAll,
    replaceGenerator,
    module SemigroupPresentation.Generator,
  ) where

import SemigroupPresentation.Generator

import Containers
import Lens

type Relation = Pair GWord

relation :: GWord -> GWord -> Relation
relation :: GWord -> GWord -> Relation
relation = ((GWord, GWord) -> Relation) -> GWord -> GWord -> Relation
forall a b c. ((a, b) -> c) -> a -> b -> c
curry (GWord, GWord) -> Relation
forall a. (a, a) -> Pair a
Pair

relator :: GWord -> Relation
relator :: GWord -> Relation
relator GWord
gw = GWord -> GWord -> Relation
relation GWord
gw []

type Relations = Set Relation

type StrRelation = Pair StrGWord

forAll :: Ord b => (a -> b) -> Getter (Set (Pair a)) (Set (Pair b))
forAll :: (a -> b) -> Getter (Set (Pair a)) (Set (Pair b))
forAll a -> b
f = (Set (Pair a) -> Set (Pair b))
-> Optic' (->) f (Set (Pair a)) (Set (Pair b))
forall (p :: * -> * -> *) (f :: * -> *) s a.
(Profunctor p, Contravariant f) =>
(s -> a) -> Optic' p f s a
to ((Set (Pair a) -> Set (Pair b))
 -> Optic' (->) f (Set (Pair a)) (Set (Pair b)))
-> (Set (Pair a) -> Set (Pair b))
-> Optic' (->) f (Set (Pair a)) (Set (Pair b))
forall a b. (a -> b) -> a -> b
$ ((Pair a -> Pair b) -> Set (Pair a) -> Set (Pair b)
forall c1 c2 v1 v2. Gunctor c1 c2 v1 v2 => (v1 -> v2) -> c1 -> c2
gmap((Pair a -> Pair b) -> Set (Pair a) -> Set (Pair b))
-> ((a -> b) -> Pair a -> Pair b)
-> (a -> b)
-> Set (Pair a)
-> Set (Pair b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(a -> b) -> Pair a -> Pair b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap) a -> b
f

replaceGenerator :: (String, String) -> StrGWord -> StrGWord
replaceGenerator :: (String, String) -> StrGWord -> StrGWord
replaceGenerator (String
gFrom, String
gTo) = (String -> String) -> StrGWord -> StrGWord
forall a b. (a -> b) -> [a] -> [b]
map (\String
g -> if String
g String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
gFrom then String
gTo else String
g)