{- |
Module      : Control.Lens.Grammar.Kleene
Description : Kleene star algebras, regular expressions & token classes
Copyright   : (C) 2026 - Eitan Chatav
License     : BSD-style (see the file LICENSE)
Maintainer  : Eitan Chatav <eitan.chatav@gmail.com>
Stability   : provisional
Portability : non-portable

Regular expressions form a Kleene star algebra. See Kleene,
[Representation of Events in Nerve Nets and Finite Automata]
(https://www.rand.org/pubs/research_memoranda/RM704.html)
-}

module Control.Lens.Grammar.Kleene
  ( -- * KleeneStarAlgebra
    KleeneStarAlgebra (..)
  , orK, anyK
    -- * TokenAlgebra
  , TokenAlgebra (..)
    -- * RegEx & TokenClass
  , RegEx (..)
  , TokenClass (..)
  , RegExam (..)
  , CategoryTest (..)
  ) where

import Control.Applicative
import Control.Lens.Grammar.Boole
import Control.Lens.Grammar.Symbol
import Control.Lens.Grammar.Token
import Control.Monad.Loops
import Control.Monad.State (StateT, state)
import Data.Bifunctor.Joker
import Data.Foldable
import Data.MemoTrie
import Data.Monoid
import Data.Profunctor
import Data.Profunctor.Distributor
import Data.Set (Set)
import qualified Data.Set as Set
import GHC.Generics
import System.Random (RandomGen, Random, random)
import Test.QuickCheck.Arbitrary
import Test.QuickCheck.Gen (Gen)
import qualified Test.QuickCheck.Gen as Gen
import Text.ParserCombinators.ReadP (ReadP)
import qualified Text.ParserCombinators.ReadP as ReadP

{- | A `KleeneStarAlgebra` is a ring
with a generally non-commutative multiplication,
the `Monoid` concatenation operator `<>` with identity `mempty`;
and an idempotent addition, the alternation operator `>|<`
with identity `zeroK`.

It has three unary operators `optK`, `plusK` and the eponymous `starK`.

prop> starK x = optK (plusK x)
prop> plusK x = x <> starK x
prop> optK x = mempty >|< x

The following invariants should hold.

prop> x >|< x = x
prop> zeroK >|< x = x = x >|< zeroK
prop> mempty >|< x = optK x = x >|< mempty
prop> zeroK <> x = zeroK = x <> zeroK
prop> mempty <> x = x = x <> mempty

-}
class Monoid k => KleeneStarAlgebra k where
  starK, plusK, optK :: k -> k
  starK k
x = k -> k
forall k. KleeneStarAlgebra k => k -> k
optK (k -> k
forall k. KleeneStarAlgebra k => k -> k
plusK k
x)
  plusK k
x = k
x k -> k -> k
forall a. Semigroup a => a -> a -> a
<> k -> k
forall k. KleeneStarAlgebra k => k -> k
starK k
x
  optK k
x = k
forall a. Monoid a => a
mempty k -> k -> k
forall k. KleeneStarAlgebra k => k -> k -> k
>|< k
x
  infixl 3 >|<
  (>|<) :: k -> k -> k
  zeroK :: k
  default (>|<) :: (k ~ f a, Alternative f) => k -> k -> k
  default zeroK :: (k ~ f a, Alternative f) => k
  (>|<) = k -> k -> k
f a -> f a -> f a
forall a. f a -> f a -> f a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
(<|>)
  zeroK = k
f a
forall a. f a
forall (f :: * -> *) a. Alternative f => f a
empty

-- | cumulative alternation
orK :: (Foldable f, KleeneStarAlgebra k) => f k -> k
orK :: forall (f :: * -> *) k.
(Foldable f, KleeneStarAlgebra k) =>
f k -> k
orK = (k -> k -> k) -> k -> f k -> k
forall b a. (b -> a -> b) -> b -> f a -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' k -> k -> k
forall k. KleeneStarAlgebra k => k -> k -> k
(>|<) k
forall k. KleeneStarAlgebra k => k
zeroK

-- | existential
anyK :: (Foldable f, KleeneStarAlgebra k) => (a -> k) -> f a -> k
anyK :: forall (f :: * -> *) k a.
(Foldable f, KleeneStarAlgebra k) =>
(a -> k) -> f a -> k
anyK a -> k
f = (k -> a -> k) -> k -> f a -> k
forall b a. (b -> a -> b) -> b -> f a -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (\k
b a
a -> k
b k -> k -> k
forall k. KleeneStarAlgebra k => k -> k -> k
>|< a -> k
f a
a) k
forall k. KleeneStarAlgebra k => k
zeroK

{- | The `RegEx`pression type forms the prototypical `KleeneStarAlgebra`.
It is also a `TokenAlgebra`, such that the following invariants hold.

prop> zeroK = tokenClass falseB
prop> tokenClass x >|< tokenClass y = tokenClass (x >||< y)

-}
data RegEx token
  = SeqEmpty
  | Sequence (RegEx token) (RegEx token)
  | NonTerminal String
  | KleeneStar (RegEx token)
  | KleeneOpt (RegEx token)
  | KleenePlus (RegEx token)
  | RegExam (RegExam token (RegEx token))

{- | A component of both `RegEx`pressions and `TokenClass`es,
so that the latter can be embedded in the former with `tokenClass`.
-}
data RegExam token alg
  = OneOf (Set token)
  | NotOneOf (Set token) (CategoryTest token)
  | Alternate alg alg

failExam :: RegExam token alg
failExam :: forall token alg. RegExam token alg
failExam = Set token -> RegExam token alg
forall token alg. Set token -> RegExam token alg
OneOf Set token
forall a. Set a
Set.empty

passExam :: RegExam token alg
passExam :: forall token alg. RegExam token alg
passExam = Set token -> CategoryTest token -> RegExam token alg
forall token alg.
Set token -> CategoryTest token -> RegExam token alg
NotOneOf Set token
forall a. Set a
Set.empty (Set (Categorize token) -> CategoryTest token
forall token. Set (Categorize token) -> CategoryTest token
AndNotAsIn Set (Categorize token)
forall a. Set a
Set.empty)

isFailExam :: RegExam token alg -> Bool
isFailExam :: forall token alg. RegExam token alg -> Bool
isFailExam (OneOf Set token
xs) = Set token -> Bool
forall a. Set a -> Bool
Set.null Set token
xs
isFailExam RegExam token alg
_ = Bool
False

isPassExam :: RegExam token alg -> Bool
isPassExam :: forall token alg. RegExam token alg -> Bool
isPassExam (NotOneOf Set token
xs (AndNotAsIn Set (Categorize token)
ys)) = Set token -> Bool
forall a. Set a -> Bool
Set.null Set token
xs Bool -> Bool -> Bool
&& Set (Categorize token) -> Bool
forall a. Set a -> Bool
Set.null Set (Categorize token)
ys
isPassExam RegExam token alg
_ = Bool
False

{- | `CategoryTest`s for `Categorized` tokens.-}
data CategoryTest token
  = AndAsIn (Categorize token)
  | AndNotAsIn (Set (Categorize token))

{- | `TokenClass` forms a `Tokenized` `BooleanAlgebra`,
such that the following invariants hold.

prop> trueB = anyToken
prop> trueB = notOneOf []
prop> falseB = oneOf []
prop> notB . oneOf = notOneOf
prop> notB . notOneOf = oneOf
prop> notB . asIn = notAsIn
prop> notB . notAsIn = asIn

-}
newtype TokenClass token = TokenClass (RegExam token (TokenClass token))

{- | `TokenAlgebra` extends `Tokenized` methods to support
`BooleanAlgebra` operations within a `tokenClass`.
When a `TokenAlgebra` is an `Alternative`,
then `tokenClass` is expected to act homomorphically on disjunction.

prop> empty = tokenClass falseB
prop> tokenClass x <|> tokenClass y = tokenClass (x >||< y)

-}
class Tokenized token p => TokenAlgebra token p where
  tokenClass :: TokenClass token -> p
  default tokenClass
    :: (p ~ q token token, Alternator q, Cochoice q)
    => TokenClass token -> p
  tokenClass (TokenClass RegExam token (TokenClass token)
exam) = case RegExam token (TokenClass token)
exam of
    OneOf Set token
chars -> Set token -> p
forall token p (f :: * -> *).
(Tokenized token p, Foldable f) =>
f token -> p
forall (f :: * -> *). Foldable f => f token -> p
oneOf Set token
chars
    NotOneOf Set token
chars (AndAsIn Categorize token
cat) ->
      (token -> Bool) -> q token token
forall a (p :: * -> * -> *).
(Tokenized a (p a a), Choice p, Cochoice p) =>
(a -> Bool) -> p a a
satisfy (Set token -> token -> Bool
forall token p (f :: * -> *).
(Tokenized token p, Foldable f) =>
f token -> p
forall (f :: * -> *). Foldable f => f token -> token -> Bool
notOneOf Set token
chars (token -> Bool) -> (token -> Bool) -> token -> Bool
forall b. BooleanAlgebra b => b -> b -> b
>&&< Categorize token -> token -> Bool
forall token p. Tokenized token p => Categorize token -> p
asIn Categorize token
cat)
    NotOneOf Set token
chars (AndNotAsIn Set (Categorize token)
cats) ->
      (token -> Bool) -> q token token
forall a (p :: * -> * -> *).
(Tokenized a (p a a), Choice p, Cochoice p) =>
(a -> Bool) -> p a a
satisfy (Set token -> token -> Bool
forall token p (f :: * -> *).
(Tokenized token p, Foldable f) =>
f token -> p
forall (f :: * -> *). Foldable f => f token -> token -> Bool
notOneOf Set token
chars (token -> Bool) -> (token -> Bool) -> token -> Bool
forall b. BooleanAlgebra b => b -> b -> b
>&&< (Categorize token -> token -> Bool)
-> Set (Categorize token) -> token -> Bool
forall (f :: * -> *) b a.
(Foldable f, BooleanAlgebra b) =>
(a -> b) -> f a -> b
allB Categorize token -> token -> Bool
forall token p. Tokenized token p => Categorize token -> p
notAsIn Set (Categorize token)
cats)
    Alternate TokenClass token
exam1 TokenClass token
exam2 -> TokenClass token -> q token token
forall token p. TokenAlgebra token p => TokenClass token -> p
tokenClass TokenClass token
exam1 q token token -> q token token -> q token token
forall a. q token a -> q token a -> q token a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> TokenClass token -> q token token
forall token p. TokenAlgebra token p => TokenClass token -> p
tokenClass TokenClass token
exam2

--instances
instance (Alternative f, Monoid k) => KleeneStarAlgebra (Ap f k)
deriving stock instance Generic (RegEx token)
deriving stock instance Generic (RegExam token alg)
deriving stock instance Generic1 (RegExam token)
deriving stock instance Generic (TokenClass token)
deriving stock instance Generic (CategoryTest token)
deriving stock instance Categorized token => Eq (RegEx token)
deriving stock instance Categorized token => Ord (RegEx token)
deriving stock instance
  (Categorized token, Read token, Read (Categorize token))
    => Read (RegEx token)
deriving stock instance
  (Categorized token, Show token, Show (Categorize token))
    => Show (RegEx token)
deriving stock instance
  (Categorized token, Read token, Read (Categorize token))
    => Read (TokenClass token)
deriving stock instance
  (Categorized token, Show token, Show (Categorize token))
    => Show (TokenClass token)
deriving newtype instance Categorized token => Eq (TokenClass token)
deriving newtype instance Categorized token => Ord (TokenClass token)
deriving newtype instance Categorized token => Tokenized token (TokenClass token)
deriving newtype instance Categorized token => BooleanAlgebra (TokenClass token)
instance Categorized token
  => TokenAlgebra token (TokenClass token) where
  tokenClass :: TokenClass token -> TokenClass token
tokenClass = TokenClass token -> TokenClass token
forall a. a -> a
id
instance Categorized token
  => TokenAlgebra token (RegExam token (TokenClass token)) where
  tokenClass :: TokenClass token -> RegExam token (TokenClass token)
tokenClass (TokenClass RegExam token (TokenClass token)
exam) = RegExam token (TokenClass token)
exam
instance Categorized token => TerminalSymbol token (RegEx token) where
  terminal :: [token] -> RegEx token
terminal = (RegEx token -> token -> RegEx token)
-> RegEx token -> [token] -> RegEx token
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl (\RegEx token
acc token
t -> RegEx token
acc RegEx token -> RegEx token -> RegEx token
forall a. Semigroup a => a -> a -> a
<> token -> RegEx token
forall token p. Tokenized token p => token -> p
token token
t) RegEx token
forall a. Monoid a => a
mempty
instance NonTerminalSymbol (RegEx token) where
  nonTerminal :: String -> RegEx token
nonTerminal = String -> RegEx token
forall token. String -> RegEx token
NonTerminal
instance Categorized token => Tokenized token (RegEx token) where
  anyToken :: RegEx token
anyToken = RegExam token (RegEx token) -> RegEx token
forall token. RegExam token (RegEx token) -> RegEx token
RegExam RegExam token (RegEx token)
forall token alg. RegExam token alg
passExam
  token :: token -> RegEx token
token token
a = RegExam token (RegEx token) -> RegEx token
forall token. RegExam token (RegEx token) -> RegEx token
RegExam (Set token -> RegExam token (RegEx token)
forall token alg. Set token -> RegExam token alg
OneOf (token -> Set token
forall a. a -> Set a
Set.singleton token
a))
  oneOf :: forall (f :: * -> *). Foldable f => f token -> RegEx token
oneOf f token
as = RegExam token (RegEx token) -> RegEx token
forall token. RegExam token (RegEx token) -> RegEx token
RegExam (Set token -> RegExam token (RegEx token)
forall token alg. Set token -> RegExam token alg
OneOf ([token] -> Set token
forall a. Ord a => [a] -> Set a
Set.fromList (f token -> [token]
forall a. f a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList f token
as)))
  notOneOf :: forall (f :: * -> *). Foldable f => f token -> RegEx token
notOneOf f token
as =
    RegExam token (RegEx token) -> RegEx token
forall token. RegExam token (RegEx token) -> RegEx token
RegExam (Set token -> CategoryTest token -> RegExam token (RegEx token)
forall token alg.
Set token -> CategoryTest token -> RegExam token alg
NotOneOf ([token] -> Set token
forall a. Ord a => [a] -> Set a
Set.fromList (f token -> [token]
forall a. f a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList f token
as)) (Set (Categorize token) -> CategoryTest token
forall token. Set (Categorize token) -> CategoryTest token
AndNotAsIn Set (Categorize token)
forall a. Set a
Set.empty))
  asIn :: Categorize token -> RegEx token
asIn Categorize token
cat = RegExam token (RegEx token) -> RegEx token
forall token. RegExam token (RegEx token) -> RegEx token
RegExam (Set token -> CategoryTest token -> RegExam token (RegEx token)
forall token alg.
Set token -> CategoryTest token -> RegExam token alg
NotOneOf Set token
forall a. Set a
Set.empty (Categorize token -> CategoryTest token
forall token. Categorize token -> CategoryTest token
AndAsIn Categorize token
cat))
  notAsIn :: Categorize token -> RegEx token
notAsIn Categorize token
cat = RegExam token (RegEx token) -> RegEx token
forall token. RegExam token (RegEx token) -> RegEx token
RegExam (Set token -> CategoryTest token -> RegExam token (RegEx token)
forall token alg.
Set token -> CategoryTest token -> RegExam token alg
NotOneOf Set token
forall a. Set a
Set.empty (Set (Categorize token) -> CategoryTest token
forall token. Set (Categorize token) -> CategoryTest token
AndNotAsIn (Categorize token -> Set (Categorize token)
forall a. a -> Set a
Set.singleton Categorize token
cat)))
instance Categorized token => TokenAlgebra token (token -> Bool) where
  tokenClass :: TokenClass token -> token -> Bool
tokenClass (TokenClass RegExam token (TokenClass token)
exam) token
x = case RegExam token (TokenClass token)
exam of
    OneOf Set token
xs -> token -> Set token -> Bool
forall a. Ord a => a -> Set a -> Bool
Set.member token
x Set token
xs
    NotOneOf Set token
xs (AndAsIn Categorize token
y) ->
      token -> Set token -> Bool
forall a. Ord a => a -> Set a -> Bool
Set.notMember token
x Set token
xs Bool -> Bool -> Bool
&& token -> Categorize token
forall token. Categorized token => token -> Categorize token
categorize token
x Categorize token -> Categorize token -> Bool
forall a. Eq a => a -> a -> Bool
== Categorize token
y
    NotOneOf Set token
xs (AndNotAsIn Set (Categorize token)
ys) ->
      token -> Set token -> Bool
forall a. Ord a => a -> Set a -> Bool
Set.notMember token
x Set token
xs Bool -> Bool -> Bool
&& Categorize token -> Set (Categorize token) -> Bool
forall a. Ord a => a -> Set a -> Bool
Set.notMember (token -> Categorize token
forall token. Categorized token => token -> Categorize token
categorize token
x) Set (Categorize token)
ys
    Alternate TokenClass token
exam1 TokenClass token
exam2 ->
      TokenClass token -> token -> Bool
forall token p. TokenAlgebra token p => TokenClass token -> p
tokenClass TokenClass token
exam1 token
x Bool -> Bool -> Bool
|| TokenClass token -> token -> Bool
forall token p. TokenAlgebra token p => TokenClass token -> p
tokenClass TokenClass token
exam2 token
x
instance Categorized token => TokenAlgebra token (RegEx token) where
  tokenClass :: TokenClass token -> RegEx token
tokenClass (TokenClass RegExam token (TokenClass token)
exam) = case RegExam token (TokenClass token)
exam of
    OneOf Set token
as -> RegExam token (RegEx token) -> RegEx token
forall token. RegExam token (RegEx token) -> RegEx token
RegExam (Set token -> RegExam token (RegEx token)
forall token alg. Set token -> RegExam token alg
OneOf Set token
as)
    NotOneOf Set token
as CategoryTest token
catTest -> RegExam token (RegEx token) -> RegEx token
forall token. RegExam token (RegEx token) -> RegEx token
RegExam (Set token -> CategoryTest token -> RegExam token (RegEx token)
forall token alg.
Set token -> CategoryTest token -> RegExam token alg
NotOneOf Set token
as CategoryTest token
catTest)
    Alternate TokenClass token
exam1 TokenClass token
exam2 ->
      RegExam token (RegEx token) -> RegEx token
forall token. RegExam token (RegEx token) -> RegEx token
RegExam (RegEx token -> RegEx token -> RegExam token (RegEx token)
forall token alg. alg -> alg -> RegExam token alg
Alternate (TokenClass token -> RegEx token
forall token p. TokenAlgebra token p => TokenClass token -> p
tokenClass TokenClass token
exam1) (TokenClass token -> RegEx token
forall token p. TokenAlgebra token p => TokenClass token -> p
tokenClass TokenClass token
exam2))
instance TokenAlgebra token (f token)
  => TokenAlgebra token (Joker f token token) where
    tokenClass :: TokenClass token -> Joker f token token
tokenClass = f token -> Joker f token token
forall {k} {k1} (g :: k -> *) (a :: k1) (b :: k).
g b -> Joker g a b
Joker (f token -> Joker f token token)
-> (TokenClass token -> f token)
-> TokenClass token
-> Joker f token token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TokenClass token -> f token
forall token p. TokenAlgebra token p => TokenClass token -> p
tokenClass
instance TokenAlgebra Char (ReadP Char) where
  tokenClass :: TokenClass Char -> ReadP Char
tokenClass = (Char -> Bool) -> ReadP Char
ReadP.satisfy ((Char -> Bool) -> ReadP Char)
-> (TokenClass Char -> Char -> Bool)
-> TokenClass Char
-> ReadP Char
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TokenClass Char -> Char -> Bool
forall token p. TokenAlgebra token p => TokenClass token -> p
tokenClass
instance (Categorized token, Arbitrary token) => TokenAlgebra token (Gen token) where
  tokenClass :: TokenClass token -> Gen token
tokenClass (TokenClass RegExam token (TokenClass token)
exam) = case RegExam token (TokenClass token)
exam of
    OneOf Set token
xs -> Set token -> Gen token
forall token p (f :: * -> *).
(Tokenized token p, Foldable f) =>
f token -> p
forall (f :: * -> *). Foldable f => f token -> Gen token
oneOf Set token
xs
    NotOneOf Set token
xs (AndAsIn Categorize token
cat) -> Gen token
forall a. Arbitrary a => Gen a
arbitrary Gen token -> (token -> Bool) -> Gen token
forall a. Gen a -> (a -> Bool) -> Gen a
`Gen.suchThat`
      (\token
x -> token
x token -> Set token -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` Set token
xs Bool -> Bool -> Bool
&& token -> Categorize token
forall token. Categorized token => token -> Categorize token
categorize token
x Categorize token -> Categorize token -> Bool
forall a. Eq a => a -> a -> Bool
== Categorize token
cat)
    NotOneOf Set token
xs (AndNotAsIn Set (Categorize token)
cats) -> Gen token
forall a. Arbitrary a => Gen a
arbitrary Gen token -> (token -> Bool) -> Gen token
forall a. Gen a -> (a -> Bool) -> Gen a
`Gen.suchThat`
      (\token
x -> token
x token -> Set token -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` Set token
xs Bool -> Bool -> Bool
&& token -> Categorize token
forall token. Categorized token => token -> Categorize token
categorize token
x Categorize token -> Set (Categorize token) -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` Set (Categorize token)
cats)
    Alternate TokenClass token
cls1 TokenClass token
cls2 -> [Gen token] -> Gen token
forall a. HasCallStack => [Gen a] -> Gen a
Gen.oneof [TokenClass token -> Gen token
forall token p. TokenAlgebra token p => TokenClass token -> p
tokenClass TokenClass token
cls1, TokenClass token -> Gen token
forall token p. TokenAlgebra token p => TokenClass token -> p
tokenClass TokenClass token
cls2]
instance (RandomGen g, Monad m, Categorized token, Random token)
  => TokenAlgebra token (StateT g m token) where
  tokenClass :: TokenClass token -> StateT g m token
tokenClass (TokenClass RegExam token (TokenClass token)
exam) = case RegExam token (TokenClass token)
exam of
    OneOf Set token
xs -> Set token -> StateT g m token
forall token p (f :: * -> *).
(Tokenized token p, Foldable f) =>
f token -> p
forall (f :: * -> *). Foldable f => f token -> StateT g m token
oneOf Set token
xs
    NotOneOf Set token
xs (AndAsIn Categorize token
cat) ->
      (token -> Bool) -> StateT g m token -> StateT g m token
forall (m :: * -> *) a. Monad m => (a -> Bool) -> m a -> m a
iterateUntil (\token
x -> token
x token -> Set token -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` Set token
xs Bool -> Bool -> Bool
&& token -> Categorize token
forall token. Categorized token => token -> Categorize token
categorize token
x Categorize token -> Categorize token -> Bool
forall a. Eq a => a -> a -> Bool
== Categorize token
cat) StateT g m token
forall token p. Tokenized token p => p
anyToken
    NotOneOf Set token
xs (AndNotAsIn Set (Categorize token)
cats) ->
      (token -> Bool) -> StateT g m token -> StateT g m token
forall (m :: * -> *) a. Monad m => (a -> Bool) -> m a -> m a
iterateUntil (\token
x -> token
x token -> Set token -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` Set token
xs Bool -> Bool -> Bool
&& token -> Categorize token
forall token. Categorized token => token -> Categorize token
categorize token
x Categorize token -> Set (Categorize token) -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` Set (Categorize token)
cats) StateT g m token
forall token p. Tokenized token p => p
anyToken
    Alternate TokenClass token
cls1 TokenClass token
cls2 -> do
      Bool
b <- (g -> (Bool, g)) -> StateT g m Bool
forall a. (g -> (a, g)) -> StateT g m a
forall s (m :: * -> *) a. MonadState s m => (s -> (a, s)) -> m a
state g -> (Bool, g)
forall g. RandomGen g => g -> (Bool, g)
forall a g. (Random a, RandomGen g) => g -> (a, g)
random
      if (Bool
b :: Bool) then TokenClass token -> StateT g m token
forall token p. TokenAlgebra token p => TokenClass token -> p
tokenClass TokenClass token
cls1 else TokenClass token -> StateT g m token
forall token p. TokenAlgebra token p => TokenClass token -> p
tokenClass TokenClass token
cls2
instance Categorized token => Monoid (RegEx token) where
  mempty :: RegEx token
mempty = RegEx token
forall token. RegEx token
SeqEmpty
instance Categorized token => Semigroup (RegEx token) where
  RegEx token
SeqEmpty <> :: RegEx token -> RegEx token -> RegEx token
<> RegEx token
rex = RegEx token
rex
  RegEx token
rex <> RegEx token
SeqEmpty = RegEx token
rex
  RegExam RegExam token (RegEx token)
exam <> RegEx token
_ | RegExam token (RegEx token) -> Bool
forall token alg. RegExam token alg -> Bool
isFailExam RegExam token (RegEx token)
exam = RegEx token
forall k. KleeneStarAlgebra k => k
zeroK
  RegEx token
_ <> RegExam RegExam token (RegEx token)
exam | RegExam token (RegEx token) -> Bool
forall token alg. RegExam token alg -> Bool
isFailExam RegExam token (RegEx token)
exam = RegEx token
forall k. KleeneStarAlgebra k => k
zeroK
  KleeneStar RegEx token
rex0 <> RegEx token
rex1 | RegEx token
rex0 RegEx token -> RegEx token -> Bool
forall a. Eq a => a -> a -> Bool
== RegEx token
rex1 = RegEx token -> RegEx token
forall k. KleeneStarAlgebra k => k -> k
plusK RegEx token
rex0
  RegEx token
rex0 <> KleeneStar RegEx token
rex1 | RegEx token
rex0 RegEx token -> RegEx token -> Bool
forall a. Eq a => a -> a -> Bool
== RegEx token
rex1 = RegEx token -> RegEx token
forall k. KleeneStarAlgebra k => k -> k
plusK RegEx token
rex1
  RegEx token
rex0 <> RegEx token
rex1 = RegEx token -> RegEx token -> RegEx token
forall token. RegEx token -> RegEx token -> RegEx token
Sequence RegEx token
rex0 RegEx token
rex1
instance Categorized token => KleeneStarAlgebra (RegEx token) where
  zeroK :: RegEx token
zeroK = RegExam token (RegEx token) -> RegEx token
forall token. RegExam token (RegEx token) -> RegEx token
RegExam RegExam token (RegEx token)
forall token alg. RegExam token alg
failExam
  optK :: RegEx token -> RegEx token
optK (RegExam RegExam token (RegEx token)
exam) | RegExam token (RegEx token) -> Bool
forall token alg. RegExam token alg -> Bool
isFailExam RegExam token (RegEx token)
exam = RegEx token
forall a. Monoid a => a
mempty
  optK RegEx token
SeqEmpty = RegEx token
forall a. Monoid a => a
mempty
  optK (KleenePlus RegEx token
rex) = RegEx token -> RegEx token
forall k. KleeneStarAlgebra k => k -> k
starK RegEx token
rex
  optK RegEx token
rex = RegEx token -> RegEx token
forall token. RegEx token -> RegEx token
KleeneOpt RegEx token
rex
  starK :: RegEx token -> RegEx token
starK (RegExam RegExam token (RegEx token)
exam) | RegExam token (RegEx token) -> Bool
forall token alg. RegExam token alg -> Bool
isFailExam RegExam token (RegEx token)
exam = RegEx token
forall a. Monoid a => a
mempty
  starK RegEx token
SeqEmpty = RegEx token
forall a. Monoid a => a
mempty
  starK RegEx token
rex = RegEx token -> RegEx token
forall token. RegEx token -> RegEx token
KleeneStar RegEx token
rex
  plusK :: RegEx token -> RegEx token
plusK (RegExam RegExam token (RegEx token)
exam) | RegExam token (RegEx token) -> Bool
forall token alg. RegExam token alg -> Bool
isFailExam RegExam token (RegEx token)
exam = RegEx token
forall k. KleeneStarAlgebra k => k
zeroK
  plusK RegEx token
SeqEmpty = RegEx token
forall a. Monoid a => a
mempty
  plusK RegEx token
rex = RegEx token -> RegEx token
forall token. RegEx token -> RegEx token
KleenePlus RegEx token
rex
  RegEx token
rex0 >|< :: RegEx token -> RegEx token -> RegEx token
>|< RegEx token
rex1 | RegEx token
rex0 RegEx token -> RegEx token -> Bool
forall a. Eq a => a -> a -> Bool
== RegEx token
rex1 = RegEx token
rex0
  KleenePlus RegEx token
rex >|< RegEx token
SeqEmpty = RegEx token -> RegEx token
forall k. KleeneStarAlgebra k => k -> k
starK RegEx token
rex
  RegEx token
SeqEmpty >|< KleenePlus RegEx token
rex = RegEx token -> RegEx token
forall k. KleeneStarAlgebra k => k -> k
starK RegEx token
rex
  RegEx token
rex >|< RegEx token
SeqEmpty = RegEx token -> RegEx token
forall k. KleeneStarAlgebra k => k -> k
optK RegEx token
rex
  RegEx token
SeqEmpty >|< RegEx token
rex = RegEx token -> RegEx token
forall k. KleeneStarAlgebra k => k -> k
optK RegEx token
rex
  RegEx token
rex >|< RegExam RegExam token (RegEx token)
exam | RegExam token (RegEx token) -> Bool
forall token alg. RegExam token alg -> Bool
isFailExam RegExam token (RegEx token)
exam = RegEx token
rex
  RegExam RegExam token (RegEx token)
exam >|< RegEx token
rex | RegExam token (RegEx token) -> Bool
forall token alg. RegExam token alg -> Bool
isFailExam RegExam token (RegEx token)
exam = RegEx token
rex
  RegEx token
rex0 >|< RegEx token
rex1 | Just TokenClass token
tokenOr <- Maybe (TokenClass token)
maybeOr = TokenClass token -> RegEx token
forall token p. TokenAlgebra token p => TokenClass token -> p
tokenClass TokenClass token
tokenOr
    where
      toTokenClass :: RegEx token -> Maybe (TokenClass token)
toTokenClass (RegExam RegExam token (RegEx token)
exam) =
        RegExam token (TokenClass token) -> TokenClass token
forall token. RegExam token (TokenClass token) -> TokenClass token
TokenClass (RegExam token (TokenClass token) -> TokenClass token)
-> Maybe (RegExam token (TokenClass token))
-> Maybe (TokenClass token)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (RegEx token -> Maybe (TokenClass token))
-> RegExam token (RegEx token)
-> Maybe (RegExam token (TokenClass token))
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> RegExam token a -> f (RegExam token b)
traverse RegEx token -> Maybe (TokenClass token)
toTokenClass RegExam token (RegEx token)
exam
      toTokenClass RegEx token
_ = Maybe (TokenClass token)
forall a. Maybe a
Nothing
      maybeOr :: Maybe (TokenClass token)
maybeOr = TokenClass token -> TokenClass token -> TokenClass token
forall b. BooleanAlgebra b => b -> b -> b
(>||<) (TokenClass token -> TokenClass token -> TokenClass token)
-> Maybe (TokenClass token)
-> Maybe (TokenClass token -> TokenClass token)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> RegEx token -> Maybe (TokenClass token)
forall {token}. RegEx token -> Maybe (TokenClass token)
toTokenClass RegEx token
rex0 Maybe (TokenClass token -> TokenClass token)
-> Maybe (TokenClass token) -> Maybe (TokenClass token)
forall a b. Maybe (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> RegEx token -> Maybe (TokenClass token)
forall {token}. RegEx token -> Maybe (TokenClass token)
toTokenClass RegEx token
rex1
  RegEx token
rex0 >|< RegEx token
rex1 = RegExam token (RegEx token) -> RegEx token
forall token. RegExam token (RegEx token) -> RegEx token
RegExam (RegEx token -> RegEx token -> RegExam token (RegEx token)
forall token alg. alg -> alg -> RegExam token alg
Alternate RegEx token
rex0 RegEx token
rex1)
instance Categorized token => Tokenized token (RegExam token alg) where
  anyToken :: RegExam token alg
anyToken = RegExam token alg
forall token alg. RegExam token alg
passExam
  token :: token -> RegExam token alg
token token
a = Set token -> RegExam token alg
forall token alg. Set token -> RegExam token alg
OneOf (token -> Set token
forall a. a -> Set a
Set.singleton token
a)
  oneOf :: forall (f :: * -> *). Foldable f => f token -> RegExam token alg
oneOf f token
as | f token -> Bool
forall a. f a -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null f token
as = RegExam token alg
forall token alg. RegExam token alg
failExam
  oneOf f token
as = Set token -> RegExam token alg
forall token alg. Set token -> RegExam token alg
OneOf ([token] -> Set token
forall a. Ord a => [a] -> Set a
Set.fromList (f token -> [token]
forall a. f a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList f token
as))
  notOneOf :: forall (f :: * -> *). Foldable f => f token -> RegExam token alg
notOneOf f token
as | f token -> Bool
forall a. f a -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null f token
as = RegExam token alg
forall token alg. RegExam token alg
passExam
  notOneOf f token
as =
    Set token -> CategoryTest token -> RegExam token alg
forall token alg.
Set token -> CategoryTest token -> RegExam token alg
NotOneOf ([token] -> Set token
forall a. Ord a => [a] -> Set a
Set.fromList (f token -> [token]
forall a. f a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList f token
as)) (Set (Categorize token) -> CategoryTest token
forall token. Set (Categorize token) -> CategoryTest token
AndNotAsIn Set (Categorize token)
forall a. Set a
Set.empty)
  asIn :: Categorize token -> RegExam token alg
asIn Categorize token
cat = Set token -> CategoryTest token -> RegExam token alg
forall token alg.
Set token -> CategoryTest token -> RegExam token alg
NotOneOf Set token
forall a. Set a
Set.empty (Categorize token -> CategoryTest token
forall token. Categorize token -> CategoryTest token
AndAsIn Categorize token
cat)
  notAsIn :: Categorize token -> RegExam token alg
notAsIn Categorize token
cat = Set token -> CategoryTest token -> RegExam token alg
forall token alg.
Set token -> CategoryTest token -> RegExam token alg
NotOneOf Set token
forall a. Set a
Set.empty (Set (Categorize token) -> CategoryTest token
forall token. Set (Categorize token) -> CategoryTest token
AndNotAsIn (Categorize token -> Set (Categorize token)
forall a. a -> Set a
Set.singleton Categorize token
cat))
instance Categorized token
  => BooleanAlgebra (RegExam token (TokenClass token)) where
  falseB :: RegExam token (TokenClass token)
falseB = RegExam token (TokenClass token)
forall token alg. RegExam token alg
failExam
  trueB :: RegExam token (TokenClass token)
trueB = RegExam token (TokenClass token)
forall token alg. RegExam token alg
passExam
  notB :: RegExam token (TokenClass token)
-> RegExam token (TokenClass token)
notB RegExam token (TokenClass token)
exam | RegExam token (TokenClass token) -> Bool
forall token alg. RegExam token alg -> Bool
isFailExam RegExam token (TokenClass token)
exam = RegExam token (TokenClass token)
forall token alg. RegExam token alg
passExam
  notB RegExam token (TokenClass token)
exam | RegExam token (TokenClass token) -> Bool
forall token alg. RegExam token alg -> Bool
isPassExam RegExam token (TokenClass token)
exam = RegExam token (TokenClass token)
forall token alg. RegExam token alg
failExam
  notB (Alternate (TokenClass RegExam token (TokenClass token)
x) (TokenClass RegExam token (TokenClass token)
y)) = RegExam token (TokenClass token)
-> RegExam token (TokenClass token)
forall b. BooleanAlgebra b => b -> b
notB RegExam token (TokenClass token)
x RegExam token (TokenClass token)
-> RegExam token (TokenClass token)
-> RegExam token (TokenClass token)
forall b. BooleanAlgebra b => b -> b -> b
>&&< RegExam token (TokenClass token)
-> RegExam token (TokenClass token)
forall b. BooleanAlgebra b => b -> b
notB RegExam token (TokenClass token)
y
  notB (OneOf Set token
xs) = Set token -> RegExam token (TokenClass token)
forall token p (f :: * -> *).
(Tokenized token p, Foldable f) =>
f token -> p
forall (f :: * -> *).
Foldable f =>
f token -> RegExam token (TokenClass token)
notOneOf Set token
xs
  notB (NotOneOf Set token
xs (AndAsIn Categorize token
y)) = Set token -> RegExam token (TokenClass token)
forall token p (f :: * -> *).
(Tokenized token p, Foldable f) =>
f token -> p
forall (f :: * -> *).
Foldable f =>
f token -> RegExam token (TokenClass token)
oneOf Set token
xs RegExam token (TokenClass token)
-> RegExam token (TokenClass token)
-> RegExam token (TokenClass token)
forall b. BooleanAlgebra b => b -> b -> b
>||< Categorize token -> RegExam token (TokenClass token)
forall token p. Tokenized token p => Categorize token -> p
notAsIn Categorize token
y
  notB (NotOneOf Set token
xs (AndNotAsIn Set (Categorize token)
ys)) = Set token -> RegExam token (TokenClass token)
forall token p (f :: * -> *).
(Tokenized token p, Foldable f) =>
f token -> p
forall (f :: * -> *).
Foldable f =>
f token -> RegExam token (TokenClass token)
oneOf Set token
xs RegExam token (TokenClass token)
-> RegExam token (TokenClass token)
-> RegExam token (TokenClass token)
forall b. BooleanAlgebra b => b -> b -> b
>||< (Categorize token -> RegExam token (TokenClass token))
-> Set (Categorize token) -> RegExam token (TokenClass token)
forall (f :: * -> *) b a.
(Foldable f, BooleanAlgebra b) =>
(a -> b) -> f a -> b
anyB Categorize token -> RegExam token (TokenClass token)
forall token p. Tokenized token p => Categorize token -> p
asIn Set (Categorize token)
ys
  RegExam token (TokenClass token)
x >&&< :: RegExam token (TokenClass token)
-> RegExam token (TokenClass token)
-> RegExam token (TokenClass token)
>&&< RegExam token (TokenClass token)
y | RegExam token (TokenClass token)
x RegExam token (TokenClass token)
-> RegExam token (TokenClass token) -> Bool
forall a. Eq a => a -> a -> Bool
== RegExam token (TokenClass token)
y = RegExam token (TokenClass token)
x
  RegExam token (TokenClass token)
_ >&&< RegExam token (TokenClass token)
exam | RegExam token (TokenClass token) -> Bool
forall token alg. RegExam token alg -> Bool
isFailExam RegExam token (TokenClass token)
exam = RegExam token (TokenClass token)
forall token alg. RegExam token alg
failExam
  RegExam token (TokenClass token)
exam >&&< RegExam token (TokenClass token)
_ | RegExam token (TokenClass token) -> Bool
forall token alg. RegExam token alg -> Bool
isFailExam RegExam token (TokenClass token)
exam = RegExam token (TokenClass token)
forall token alg. RegExam token alg
failExam
  RegExam token (TokenClass token)
x >&&< RegExam token (TokenClass token)
exam | RegExam token (TokenClass token) -> Bool
forall token alg. RegExam token alg -> Bool
isPassExam RegExam token (TokenClass token)
exam = RegExam token (TokenClass token)
x
  RegExam token (TokenClass token)
exam >&&< RegExam token (TokenClass token)
z | RegExam token (TokenClass token) -> Bool
forall token alg. RegExam token alg -> Bool
isPassExam RegExam token (TokenClass token)
exam = RegExam token (TokenClass token)
z
  RegExam token (TokenClass token)
x >&&< Alternate (TokenClass RegExam token (TokenClass token)
y) (TokenClass RegExam token (TokenClass token)
z) = (RegExam token (TokenClass token)
x RegExam token (TokenClass token)
-> RegExam token (TokenClass token)
-> RegExam token (TokenClass token)
forall b. BooleanAlgebra b => b -> b -> b
>&&< RegExam token (TokenClass token)
y) RegExam token (TokenClass token)
-> RegExam token (TokenClass token)
-> RegExam token (TokenClass token)
forall b. BooleanAlgebra b => b -> b -> b
>||< (RegExam token (TokenClass token)
x RegExam token (TokenClass token)
-> RegExam token (TokenClass token)
-> RegExam token (TokenClass token)
forall b. BooleanAlgebra b => b -> b -> b
>&&< RegExam token (TokenClass token)
z)
  Alternate (TokenClass RegExam token (TokenClass token)
x) (TokenClass RegExam token (TokenClass token)
y) >&&< RegExam token (TokenClass token)
z = (RegExam token (TokenClass token)
x RegExam token (TokenClass token)
-> RegExam token (TokenClass token)
-> RegExam token (TokenClass token)
forall b. BooleanAlgebra b => b -> b -> b
>&&< RegExam token (TokenClass token)
z) RegExam token (TokenClass token)
-> RegExam token (TokenClass token)
-> RegExam token (TokenClass token)
forall b. BooleanAlgebra b => b -> b -> b
>||< (RegExam token (TokenClass token)
y RegExam token (TokenClass token)
-> RegExam token (TokenClass token)
-> RegExam token (TokenClass token)
forall b. BooleanAlgebra b => b -> b -> b
>&&< RegExam token (TokenClass token)
z)
  OneOf Set token
xs >&&< OneOf Set token
ys = Set token -> RegExam token (TokenClass token)
forall token alg. Set token -> RegExam token alg
OneOf (Set token -> Set token -> Set token
forall a. Ord a => Set a -> Set a -> Set a
Set.intersection Set token
xs Set token
ys)
  OneOf Set token
xs >&&< NotOneOf Set token
ys (AndAsIn Categorize token
z) = Set token -> RegExam token (TokenClass token)
forall token alg. Set token -> RegExam token alg
OneOf
    ((token -> Bool) -> Set token -> Set token
forall a. (a -> Bool) -> Set a -> Set a
Set.filter (\token
x -> token -> Categorize token
forall token. Categorized token => token -> Categorize token
categorize token
x Categorize token -> Categorize token -> Bool
forall a. Eq a => a -> a -> Bool
== Categorize token
z) (Set token -> Set token -> Set token
forall a. Ord a => Set a -> Set a -> Set a
Set.difference Set token
xs Set token
ys))
  NotOneOf Set token
xs (AndAsIn Categorize token
y) >&&< OneOf Set token
zs = Set token -> RegExam token (TokenClass token)
forall token alg. Set token -> RegExam token alg
OneOf
    ((token -> Bool) -> Set token -> Set token
forall a. (a -> Bool) -> Set a -> Set a
Set.filter (\token
z -> token -> Categorize token
forall token. Categorized token => token -> Categorize token
categorize token
z Categorize token -> Categorize token -> Bool
forall a. Eq a => a -> a -> Bool
== Categorize token
y) (Set token -> Set token -> Set token
forall a. Ord a => Set a -> Set a -> Set a
Set.difference Set token
zs Set token
xs))
  OneOf Set token
xs >&&< NotOneOf Set token
ys (AndNotAsIn Set (Categorize token)
zs) = Set token -> RegExam token (TokenClass token)
forall token alg. Set token -> RegExam token alg
OneOf
    ((token -> Bool) -> Set token -> Set token
forall a. (a -> Bool) -> Set a -> Set a
Set.filter (\token
x -> token -> Categorize token
forall token. Categorized token => token -> Categorize token
categorize token
x Categorize token -> Set (Categorize token) -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` Set (Categorize token)
zs) (Set token -> Set token -> Set token
forall a. Ord a => Set a -> Set a -> Set a
Set.difference Set token
xs Set token
ys))
  NotOneOf Set token
xs (AndNotAsIn Set (Categorize token)
ys) >&&< OneOf Set token
zs = Set token -> RegExam token (TokenClass token)
forall token alg. Set token -> RegExam token alg
OneOf
    ((token -> Bool) -> Set token -> Set token
forall a. (a -> Bool) -> Set a -> Set a
Set.filter (\token
z -> token -> Categorize token
forall token. Categorized token => token -> Categorize token
categorize token
z Categorize token -> Set (Categorize token) -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` Set (Categorize token)
ys) (Set token -> Set token -> Set token
forall a. Ord a => Set a -> Set a -> Set a
Set.difference Set token
zs Set token
xs))
  NotOneOf Set token
xs (AndAsIn Categorize token
y) >&&< NotOneOf Set token
ws (AndAsIn Categorize token
z) =
    if Categorize token
y Categorize token -> Categorize token -> Bool
forall a. Eq a => a -> a -> Bool
/= Categorize token
z then RegExam token (TokenClass token)
forall token alg. RegExam token alg
failExam else Set token -> CategoryTest token -> RegExam token (TokenClass token)
forall token alg.
Set token -> CategoryTest token -> RegExam token alg
NotOneOf
      ((token -> Bool) -> Set token -> Set token
forall a. (a -> Bool) -> Set a -> Set a
Set.filter (\token
x -> token -> Categorize token
forall token. Categorized token => token -> Categorize token
categorize token
x Categorize token -> Categorize token -> Bool
forall a. Eq a => a -> a -> Bool
== Categorize token
y) (Set token -> Set token -> Set token
forall a. Ord a => Set a -> Set a -> Set a
Set.union Set token
xs Set token
ws)) (Categorize token -> CategoryTest token
forall token. Categorize token -> CategoryTest token
AndAsIn Categorize token
y)
  NotOneOf Set token
xs (AndAsIn Categorize token
y) >&&< NotOneOf Set token
ws (AndNotAsIn Set (Categorize token)
zs) =
    if Categorize token
y Categorize token -> Set (Categorize token) -> Bool
forall a. Eq a => a -> Set a -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` Set (Categorize token)
zs then RegExam token (TokenClass token)
forall token alg. RegExam token alg
failExam else Set token -> CategoryTest token -> RegExam token (TokenClass token)
forall token alg.
Set token -> CategoryTest token -> RegExam token alg
NotOneOf
      ((token -> Bool) -> Set token -> Set token
forall a. (a -> Bool) -> Set a -> Set a
Set.filter (\token
x -> token -> Categorize token
forall token. Categorized token => token -> Categorize token
categorize token
x Categorize token -> Categorize token -> Bool
forall a. Eq a => a -> a -> Bool
== Categorize token
y) (Set token -> Set token -> Set token
forall a. Ord a => Set a -> Set a -> Set a
Set.union Set token
xs Set token
ws)) (Categorize token -> CategoryTest token
forall token. Categorize token -> CategoryTest token
AndAsIn Categorize token
y)
  NotOneOf Set token
xs (AndNotAsIn Set (Categorize token)
ys) >&&< NotOneOf Set token
ws (AndAsIn Categorize token
z) =
    if Categorize token
z Categorize token -> Set (Categorize token) -> Bool
forall a. Eq a => a -> Set a -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` Set (Categorize token)
ys then RegExam token (TokenClass token)
forall token alg. RegExam token alg
failExam else Set token -> CategoryTest token -> RegExam token (TokenClass token)
forall token alg.
Set token -> CategoryTest token -> RegExam token alg
NotOneOf
      ((token -> Bool) -> Set token -> Set token
forall a. (a -> Bool) -> Set a -> Set a
Set.filter (\token
x -> token -> Categorize token
forall token. Categorized token => token -> Categorize token
categorize token
x Categorize token -> Categorize token -> Bool
forall a. Eq a => a -> a -> Bool
== Categorize token
z) (Set token -> Set token -> Set token
forall a. Ord a => Set a -> Set a -> Set a
Set.union Set token
xs Set token
ws)) (Categorize token -> CategoryTest token
forall token. Categorize token -> CategoryTest token
AndAsIn Categorize token
z)
  NotOneOf Set token
xs (AndNotAsIn Set (Categorize token)
ys) >&&< NotOneOf Set token
ws (AndNotAsIn Set (Categorize token)
zs) =
    let
      xws :: Set token
xws = Set token -> Set token -> Set token
forall a. Ord a => Set a -> Set a -> Set a
Set.union Set token
xs Set token
ws
      yzs :: Set (Categorize token)
yzs = Set (Categorize token)
-> Set (Categorize token) -> Set (Categorize token)
forall a. Ord a => Set a -> Set a -> Set a
Set.union Set (Categorize token)
ys Set (Categorize token)
zs
    in
      Set token -> CategoryTest token -> RegExam token (TokenClass token)
forall token alg.
Set token -> CategoryTest token -> RegExam token alg
NotOneOf
        ((token -> Bool) -> Set token -> Set token
forall a. (a -> Bool) -> Set a -> Set a
Set.filter (\token
x -> token -> Categorize token
forall token. Categorized token => token -> Categorize token
categorize token
x Categorize token -> Set (Categorize token) -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` Set (Categorize token)
yzs) Set token
xws)
        (Set (Categorize token) -> CategoryTest token
forall token. Set (Categorize token) -> CategoryTest token
AndNotAsIn Set (Categorize token)
yzs)
  RegExam token (TokenClass token)
x >||< :: RegExam token (TokenClass token)
-> RegExam token (TokenClass token)
-> RegExam token (TokenClass token)
>||< RegExam token (TokenClass token)
y | RegExam token (TokenClass token)
x RegExam token (TokenClass token)
-> RegExam token (TokenClass token) -> Bool
forall a. Eq a => a -> a -> Bool
== RegExam token (TokenClass token)
y = RegExam token (TokenClass token)
x
  RegExam token (TokenClass token)
x >||< RegExam token (TokenClass token)
exam | RegExam token (TokenClass token) -> Bool
forall token alg. RegExam token alg -> Bool
isFailExam RegExam token (TokenClass token)
exam = RegExam token (TokenClass token)
x
  RegExam token (TokenClass token)
exam >||< RegExam token (TokenClass token)
y | RegExam token (TokenClass token) -> Bool
forall token alg. RegExam token alg -> Bool
isFailExam RegExam token (TokenClass token)
exam = RegExam token (TokenClass token)
y
  RegExam token (TokenClass token)
_ >||< RegExam token (TokenClass token)
exam | RegExam token (TokenClass token) -> Bool
forall token alg. RegExam token alg -> Bool
isPassExam RegExam token (TokenClass token)
exam = RegExam token (TokenClass token)
forall token alg. RegExam token alg
passExam
  RegExam token (TokenClass token)
exam >||< RegExam token (TokenClass token)
_ | RegExam token (TokenClass token) -> Bool
forall token alg. RegExam token alg -> Bool
isPassExam RegExam token (TokenClass token)
exam = RegExam token (TokenClass token)
forall token alg. RegExam token alg
passExam
  OneOf Set token
xs >||< OneOf Set token
ys = Set token -> RegExam token (TokenClass token)
forall token p (f :: * -> *).
(Tokenized token p, Foldable f) =>
f token -> p
forall (f :: * -> *).
Foldable f =>
f token -> RegExam token (TokenClass token)
oneOf (Set token -> Set token -> Set token
forall a. Ord a => Set a -> Set a -> Set a
Set.union Set token
xs Set token
ys)
  RegExam token (TokenClass token)
x >||< RegExam token (TokenClass token)
y = TokenClass token
-> TokenClass token -> RegExam token (TokenClass token)
forall token alg. alg -> alg -> RegExam token alg
Alternate (RegExam token (TokenClass token) -> TokenClass token
forall token. RegExam token (TokenClass token) -> TokenClass token
TokenClass RegExam token (TokenClass token)
x) (RegExam token (TokenClass token) -> TokenClass token
forall token. RegExam token (TokenClass token) -> TokenClass token
TokenClass RegExam token (TokenClass token)
y)
deriving stock instance
  (Categorized token, Read token, Read alg, Read (Categorize token))
    => Read (RegExam token alg)
deriving stock instance
  (Categorized token, Show token, Show alg, Show (Categorize token))
    => Show (RegExam token alg)
deriving stock instance Functor (RegExam token)
deriving stock instance Foldable (RegExam token)
deriving stock instance Traversable (RegExam token)
deriving stock instance (Categorized token, Eq alg) => Eq (RegExam token alg)
deriving stock instance (Categorized token, Ord alg) => Ord (RegExam token alg)
deriving stock instance Categorized token => Eq (CategoryTest token)
deriving stock instance Categorized token => Ord (CategoryTest token)
deriving stock instance
  (Categorized token, Read token, Read (Categorize token))
    => Read (CategoryTest token)
deriving stock instance
  (Categorized token, Show token, Show (Categorize token))
    => Show (CategoryTest token)
instance (Categorized token, HasTrie token)
  => HasTrie (RegEx token) where
    data (RegEx token :->: b) = RegExTrie
      { forall token b. (RegEx token :->: b) -> b
seqEmptyTrie :: b
      , forall token b. (RegEx token :->: b) -> String :->: b
nonTerminalTrie :: String :->: b
      , forall token b.
(RegEx token :->: b) -> (RegEx token, RegEx token) :->: b
sequenceTrie :: (RegEx token, RegEx token) :->: b
      , forall token b.
(RegEx token :->: b) -> (RegEx token, RegEx token) :->: b
alternateTrie :: (RegEx token, RegEx token) :->: b
      , forall token b. (RegEx token :->: b) -> RegEx token :->: b
kleeneStarTrie :: RegEx token :->: b
      , forall token b. (RegEx token :->: b) -> RegEx token :->: b
kleeneOptTrie :: RegEx token :->: b
      , forall token b. (RegEx token :->: b) -> RegEx token :->: b
kleenePlusTrie :: RegEx token :->: b
      , forall token b. (RegEx token :->: b) -> [token] :->: b
oneOfTrie :: [token] :->: b
      , forall token b.
(RegEx token :->: b) -> ([token], Either Int [Int]) :->: b
notOneOfTrie :: ([token], Either Int [Int]) :->: b
      }
    trie :: forall b. (RegEx token -> b) -> RegEx token :->: b
trie RegEx token -> b
f = RegExTrie
      { seqEmptyTrie :: b
seqEmptyTrie = RegEx token -> b
f RegEx token
forall a. Monoid a => a
mempty
      , nonTerminalTrie :: String :->: b
nonTerminalTrie = (String -> b) -> String :->: b
forall a b. HasTrie a => (a -> b) -> a :->: b
forall b. (String -> b) -> String :->: b
trie (RegEx token -> b
f (RegEx token -> b) -> (String -> RegEx token) -> String -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> RegEx token
forall s. NonTerminalSymbol s => String -> s
nonTerminal)
      , sequenceTrie :: (RegEx token, RegEx token) :->: b
sequenceTrie = ((RegEx token, RegEx token) -> b)
-> (RegEx token, RegEx token) :->: b
forall a b. HasTrie a => (a -> b) -> a :->: b
forall b.
((RegEx token, RegEx token) -> b)
-> (RegEx token, RegEx token) :->: b
trie (RegEx token -> b
f (RegEx token -> b)
-> ((RegEx token, RegEx token) -> RegEx token)
-> (RegEx token, RegEx token)
-> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (RegEx token -> RegEx token -> RegEx token)
-> (RegEx token, RegEx token) -> RegEx token
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry RegEx token -> RegEx token -> RegEx token
forall a. Semigroup a => a -> a -> a
(<>))
      , alternateTrie :: (RegEx token, RegEx token) :->: b
alternateTrie = ((RegEx token, RegEx token) -> b)
-> (RegEx token, RegEx token) :->: b
forall a b. HasTrie a => (a -> b) -> a :->: b
forall b.
((RegEx token, RegEx token) -> b)
-> (RegEx token, RegEx token) :->: b
trie (RegEx token -> b
f (RegEx token -> b)
-> ((RegEx token, RegEx token) -> RegEx token)
-> (RegEx token, RegEx token)
-> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (RegEx token -> RegEx token -> RegEx token)
-> (RegEx token, RegEx token) -> RegEx token
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry RegEx token -> RegEx token -> RegEx token
forall k. KleeneStarAlgebra k => k -> k -> k
(>|<))
      , kleeneStarTrie :: RegEx token :->: b
kleeneStarTrie = (RegEx token -> b) -> RegEx token :->: b
forall a b. HasTrie a => (a -> b) -> a :->: b
forall b. (RegEx token -> b) -> RegEx token :->: b
trie (RegEx token -> b
f (RegEx token -> b)
-> (RegEx token -> RegEx token) -> RegEx token -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RegEx token -> RegEx token
forall k. KleeneStarAlgebra k => k -> k
starK)
      , kleeneOptTrie :: RegEx token :->: b
kleeneOptTrie = (RegEx token -> b) -> RegEx token :->: b
forall a b. HasTrie a => (a -> b) -> a :->: b
forall b. (RegEx token -> b) -> RegEx token :->: b
trie (RegEx token -> b
f (RegEx token -> b)
-> (RegEx token -> RegEx token) -> RegEx token -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RegEx token -> RegEx token
forall k. KleeneStarAlgebra k => k -> k
optK)
      , kleenePlusTrie :: RegEx token :->: b
kleenePlusTrie = (RegEx token -> b) -> RegEx token :->: b
forall a b. HasTrie a => (a -> b) -> a :->: b
forall b. (RegEx token -> b) -> RegEx token :->: b
trie (RegEx token -> b
f (RegEx token -> b)
-> (RegEx token -> RegEx token) -> RegEx token -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RegEx token -> RegEx token
forall k. KleeneStarAlgebra k => k -> k
plusK)
      , oneOfTrie :: [token] :->: b
oneOfTrie = ([token] -> b) -> [token] :->: b
forall a b. HasTrie a => (a -> b) -> a :->: b
forall b. ([token] -> b) -> [token] :->: b
trie (RegEx token -> b
f (RegEx token -> b) -> ([token] -> RegEx token) -> [token] -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [token] -> RegEx token
forall token p (f :: * -> *).
(Tokenized token p, Foldable f) =>
f token -> p
forall (f :: * -> *). Foldable f => f token -> RegEx token
oneOf)
      , notOneOfTrie :: ([token], Either Int [Int]) :->: b
notOneOfTrie = (([token], Either Int [Int]) -> b)
-> ([token], Either Int [Int]) :->: b
forall a b. HasTrie a => (a -> b) -> a :->: b
forall b.
(([token], Either Int [Int]) -> b)
-> ([token], Either Int [Int]) :->: b
trie (RegEx token -> b
f (RegEx token -> b)
-> (([token], Either Int [Int]) -> RegEx token)
-> ([token], Either Int [Int])
-> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([token], Either Int [Int]) -> RegEx token
forall token.
Categorized token =>
([token], Either Int [Int]) -> RegEx token
testNotOneOf)
      }
    untrie :: forall b. (RegEx token :->: b) -> RegEx token -> b
untrie RegEx token :->: b
rex = \case
      RegEx token
SeqEmpty -> (RegEx token :->: b) -> b
forall token b. (RegEx token :->: b) -> b
seqEmptyTrie RegEx token :->: b
rex
      NonTerminal String
name -> (String :->: b) -> String -> b
forall a b. HasTrie a => (a :->: b) -> a -> b
forall b. (String :->: b) -> String -> b
untrie ((RegEx token :->: b) -> String :->: b
forall token b. (RegEx token :->: b) -> String :->: b
nonTerminalTrie RegEx token :->: b
rex) String
name
      Sequence RegEx token
x1 RegEx token
x2 -> ((RegEx token, RegEx token) :->: b)
-> (RegEx token, RegEx token) -> b
forall a b. HasTrie a => (a :->: b) -> a -> b
forall b.
((RegEx token, RegEx token) :->: b)
-> (RegEx token, RegEx token) -> b
untrie ((RegEx token :->: b) -> (RegEx token, RegEx token) :->: b
forall token b.
(RegEx token :->: b) -> (RegEx token, RegEx token) :->: b
sequenceTrie RegEx token :->: b
rex) (RegEx token
x1,RegEx token
x2)
      KleeneStar RegEx token
x -> (RegEx token :->: b) -> RegEx token -> b
forall a b. HasTrie a => (a :->: b) -> a -> b
forall b. (RegEx token :->: b) -> RegEx token -> b
untrie ((RegEx token :->: b) -> RegEx token :->: b
forall token b. (RegEx token :->: b) -> RegEx token :->: b
kleeneStarTrie RegEx token :->: b
rex) RegEx token
x
      KleenePlus RegEx token
x -> (RegEx token :->: b) -> RegEx token -> b
forall a b. HasTrie a => (a :->: b) -> a -> b
forall b. (RegEx token :->: b) -> RegEx token -> b
untrie ((RegEx token :->: b) -> RegEx token :->: b
forall token b. (RegEx token :->: b) -> RegEx token :->: b
kleenePlusTrie RegEx token :->: b
rex) RegEx token
x
      KleeneOpt RegEx token
x -> (RegEx token :->: b) -> RegEx token -> b
forall a b. HasTrie a => (a :->: b) -> a -> b
forall b. (RegEx token :->: b) -> RegEx token -> b
untrie ((RegEx token :->: b) -> RegEx token :->: b
forall token b. (RegEx token :->: b) -> RegEx token :->: b
kleeneOptTrie RegEx token :->: b
rex) RegEx token
x
      RegExam (OneOf Set token
chars) -> ([token] :->: b) -> [token] -> b
forall a b. HasTrie a => (a :->: b) -> a -> b
forall b. ([token] :->: b) -> [token] -> b
untrie ((RegEx token :->: b) -> [token] :->: b
forall token b. (RegEx token :->: b) -> [token] :->: b
oneOfTrie RegEx token :->: b
rex) (Set token -> [token]
forall a. Set a -> [a]
Set.toList Set token
chars)
      RegExam (NotOneOf Set token
chars (AndAsIn Categorize token
cat)) ->
        (([token], Either Int [Int]) :->: b)
-> ([token], Either Int [Int]) -> b
forall a b. HasTrie a => (a :->: b) -> a -> b
forall b.
(([token], Either Int [Int]) :->: b)
-> ([token], Either Int [Int]) -> b
untrie ((RegEx token :->: b) -> ([token], Either Int [Int]) :->: b
forall token b.
(RegEx token :->: b) -> ([token], Either Int [Int]) :->: b
notOneOfTrie RegEx token :->: b
rex) (Set token -> [token]
forall a. Set a -> [a]
Set.toList Set token
chars, Int -> Either Int [Int]
forall a b. a -> Either a b
Left (Categorize token -> Int
forall a. Enum a => a -> Int
fromEnum Categorize token
cat))
      RegExam (NotOneOf Set token
chars (AndNotAsIn Set (Categorize token)
cats)) ->
        (([token], Either Int [Int]) :->: b)
-> ([token], Either Int [Int]) -> b
forall a b. HasTrie a => (a :->: b) -> a -> b
forall b.
(([token], Either Int [Int]) :->: b)
-> ([token], Either Int [Int]) -> b
untrie ((RegEx token :->: b) -> ([token], Either Int [Int]) :->: b
forall token b.
(RegEx token :->: b) -> ([token], Either Int [Int]) :->: b
notOneOfTrie RegEx token :->: b
rex)
          (Set token -> [token]
forall a. Set a -> [a]
Set.toList Set token
chars, [Int] -> Either Int [Int]
forall a b. b -> Either a b
Right (Set Int -> [Int]
forall a. Set a -> [a]
Set.toList ((Categorize token -> Int) -> Set (Categorize token) -> Set Int
forall b a. Ord b => (a -> b) -> Set a -> Set b
Set.map Categorize token -> Int
forall a. Enum a => a -> Int
fromEnum Set (Categorize token)
cats)))
      RegExam (Alternate RegEx token
x1 RegEx token
x2) -> ((RegEx token, RegEx token) :->: b)
-> (RegEx token, RegEx token) -> b
forall a b. HasTrie a => (a :->: b) -> a -> b
forall b.
((RegEx token, RegEx token) :->: b)
-> (RegEx token, RegEx token) -> b
untrie ((RegEx token :->: b) -> (RegEx token, RegEx token) :->: b
forall token b.
(RegEx token :->: b) -> (RegEx token, RegEx token) :->: b
alternateTrie RegEx token :->: b
rex) (RegEx token
x1,RegEx token
x2)
    enumerate :: forall b. (RegEx token :->: b) -> [(RegEx token, b)]
enumerate RegEx token :->: b
rex = [[(RegEx token, b)]] -> [(RegEx token, b)]
forall a. Monoid a => [a] -> a
mconcat
      [ [(RegEx token
forall token. RegEx token
SeqEmpty, (RegEx token :->: b) -> b
forall token b. (RegEx token :->: b) -> b
seqEmptyTrie RegEx token :->: b
rex)]
      , (String -> RegEx token) -> (String, b) -> (RegEx token, b)
forall a b c. (a -> b) -> (a, c) -> (b, c)
forall (p :: * -> * -> *) a b c.
Strong p =>
p a b -> p (a, c) (b, c)
first' String -> RegEx token
forall token. String -> RegEx token
NonTerminal ((String, b) -> (RegEx token, b))
-> [(String, b)] -> [(RegEx token, b)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (String :->: b) -> [(String, b)]
forall a b. HasTrie a => (a :->: b) -> [(a, b)]
forall b. (String :->: b) -> [(String, b)]
enumerate ((RegEx token :->: b) -> String :->: b
forall token b. (RegEx token :->: b) -> String :->: b
nonTerminalTrie RegEx token :->: b
rex)
      , ((RegEx token, RegEx token) -> RegEx token)
-> ((RegEx token, RegEx token), b) -> (RegEx token, b)
forall a b c. (a -> b) -> (a, c) -> (b, c)
forall (p :: * -> * -> *) a b c.
Strong p =>
p a b -> p (a, c) (b, c)
first' ((RegEx token -> RegEx token -> RegEx token)
-> (RegEx token, RegEx token) -> RegEx token
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry RegEx token -> RegEx token -> RegEx token
forall token. RegEx token -> RegEx token -> RegEx token
Sequence) (((RegEx token, RegEx token), b) -> (RegEx token, b))
-> [((RegEx token, RegEx token), b)] -> [(RegEx token, b)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((RegEx token, RegEx token) :->: b)
-> [((RegEx token, RegEx token), b)]
forall a b. HasTrie a => (a :->: b) -> [(a, b)]
forall b.
((RegEx token, RegEx token) :->: b)
-> [((RegEx token, RegEx token), b)]
enumerate ((RegEx token :->: b) -> (RegEx token, RegEx token) :->: b
forall token b.
(RegEx token :->: b) -> (RegEx token, RegEx token) :->: b
sequenceTrie RegEx token :->: b
rex)
      , ((RegEx token, RegEx token) -> RegEx token)
-> ((RegEx token, RegEx token), b) -> (RegEx token, b)
forall a b c. (a -> b) -> (a, c) -> (b, c)
forall (p :: * -> * -> *) a b c.
Strong p =>
p a b -> p (a, c) (b, c)
first' (RegExam token (RegEx token) -> RegEx token
forall token. RegExam token (RegEx token) -> RegEx token
RegExam (RegExam token (RegEx token) -> RegEx token)
-> ((RegEx token, RegEx token) -> RegExam token (RegEx token))
-> (RegEx token, RegEx token)
-> RegEx token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (RegEx token -> RegEx token -> RegExam token (RegEx token))
-> (RegEx token, RegEx token) -> RegExam token (RegEx token)
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry RegEx token -> RegEx token -> RegExam token (RegEx token)
forall token alg. alg -> alg -> RegExam token alg
Alternate) (((RegEx token, RegEx token), b) -> (RegEx token, b))
-> [((RegEx token, RegEx token), b)] -> [(RegEx token, b)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((RegEx token, RegEx token) :->: b)
-> [((RegEx token, RegEx token), b)]
forall a b. HasTrie a => (a :->: b) -> [(a, b)]
forall b.
((RegEx token, RegEx token) :->: b)
-> [((RegEx token, RegEx token), b)]
enumerate ((RegEx token :->: b) -> (RegEx token, RegEx token) :->: b
forall token b.
(RegEx token :->: b) -> (RegEx token, RegEx token) :->: b
alternateTrie RegEx token :->: b
rex)
      , (RegEx token -> RegEx token)
-> (RegEx token, b) -> (RegEx token, b)
forall a b c. (a -> b) -> (a, c) -> (b, c)
forall (p :: * -> * -> *) a b c.
Strong p =>
p a b -> p (a, c) (b, c)
first' RegEx token -> RegEx token
forall token. RegEx token -> RegEx token
KleeneStar ((RegEx token, b) -> (RegEx token, b))
-> [(RegEx token, b)] -> [(RegEx token, b)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (RegEx token :->: b) -> [(RegEx token, b)]
forall a b. HasTrie a => (a :->: b) -> [(a, b)]
forall b. (RegEx token :->: b) -> [(RegEx token, b)]
enumerate ((RegEx token :->: b) -> RegEx token :->: b
forall token b. (RegEx token :->: b) -> RegEx token :->: b
kleeneStarTrie RegEx token :->: b
rex)
      , (RegEx token -> RegEx token)
-> (RegEx token, b) -> (RegEx token, b)
forall a b c. (a -> b) -> (a, c) -> (b, c)
forall (p :: * -> * -> *) a b c.
Strong p =>
p a b -> p (a, c) (b, c)
first' RegEx token -> RegEx token
forall token. RegEx token -> RegEx token
KleeneOpt ((RegEx token, b) -> (RegEx token, b))
-> [(RegEx token, b)] -> [(RegEx token, b)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (RegEx token :->: b) -> [(RegEx token, b)]
forall a b. HasTrie a => (a :->: b) -> [(a, b)]
forall b. (RegEx token :->: b) -> [(RegEx token, b)]
enumerate ((RegEx token :->: b) -> RegEx token :->: b
forall token b. (RegEx token :->: b) -> RegEx token :->: b
kleeneOptTrie RegEx token :->: b
rex)
      , (RegEx token -> RegEx token)
-> (RegEx token, b) -> (RegEx token, b)
forall a b c. (a -> b) -> (a, c) -> (b, c)
forall (p :: * -> * -> *) a b c.
Strong p =>
p a b -> p (a, c) (b, c)
first' RegEx token -> RegEx token
forall token. RegEx token -> RegEx token
KleenePlus ((RegEx token, b) -> (RegEx token, b))
-> [(RegEx token, b)] -> [(RegEx token, b)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (RegEx token :->: b) -> [(RegEx token, b)]
forall a b. HasTrie a => (a :->: b) -> [(a, b)]
forall b. (RegEx token :->: b) -> [(RegEx token, b)]
enumerate ((RegEx token :->: b) -> RegEx token :->: b
forall token b. (RegEx token :->: b) -> RegEx token :->: b
kleenePlusTrie RegEx token :->: b
rex)
      , ([token] -> RegEx token) -> ([token], b) -> (RegEx token, b)
forall a b c. (a -> b) -> (a, c) -> (b, c)
forall (p :: * -> * -> *) a b c.
Strong p =>
p a b -> p (a, c) (b, c)
first' (RegExam token (RegEx token) -> RegEx token
forall token. RegExam token (RegEx token) -> RegEx token
RegExam (RegExam token (RegEx token) -> RegEx token)
-> ([token] -> RegExam token (RegEx token))
-> [token]
-> RegEx token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Set token -> RegExam token (RegEx token)
forall token alg. Set token -> RegExam token alg
OneOf (Set token -> RegExam token (RegEx token))
-> ([token] -> Set token) -> [token] -> RegExam token (RegEx token)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [token] -> Set token
forall a. Ord a => [a] -> Set a
Set.fromList) (([token], b) -> (RegEx token, b))
-> [([token], b)] -> [(RegEx token, b)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ([token] :->: b) -> [([token], b)]
forall a b. HasTrie a => (a :->: b) -> [(a, b)]
forall b. ([token] :->: b) -> [([token], b)]
enumerate ((RegEx token :->: b) -> [token] :->: b
forall token b. (RegEx token :->: b) -> [token] :->: b
oneOfTrie RegEx token :->: b
rex)
      , (([token], Either Int [Int]) -> RegEx token)
-> (([token], Either Int [Int]), b) -> (RegEx token, b)
forall a b c. (a -> b) -> (a, c) -> (b, c)
forall (p :: * -> * -> *) a b c.
Strong p =>
p a b -> p (a, c) (b, c)
first' ([token], Either Int [Int]) -> RegEx token
forall token.
Categorized token =>
([token], Either Int [Int]) -> RegEx token
testNotOneOf ((([token], Either Int [Int]), b) -> (RegEx token, b))
-> [(([token], Either Int [Int]), b)] -> [(RegEx token, b)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (([token], Either Int [Int]) :->: b)
-> [(([token], Either Int [Int]), b)]
forall a b. HasTrie a => (a :->: b) -> [(a, b)]
forall b.
(([token], Either Int [Int]) :->: b)
-> [(([token], Either Int [Int]), b)]
enumerate ((RegEx token :->: b) -> ([token], Either Int [Int]) :->: b
forall token b.
(RegEx token :->: b) -> ([token], Either Int [Int]) :->: b
notOneOfTrie RegEx token :->: b
rex)
      ]
testNotOneOf
  :: Categorized token
  => ([token], Either Int [Int]) -> RegEx token
testNotOneOf :: forall token.
Categorized token =>
([token], Either Int [Int]) -> RegEx token
testNotOneOf ([token]
chars, Either Int [Int]
catTest) = RegExam token (RegEx token) -> RegEx token
forall token. RegExam token (RegEx token) -> RegEx token
RegExam (RegExam token (RegEx token) -> RegEx token)
-> RegExam token (RegEx token) -> RegEx token
forall a b. (a -> b) -> a -> b
$ Set token -> CategoryTest token -> RegExam token (RegEx token)
forall token alg.
Set token -> CategoryTest token -> RegExam token alg
NotOneOf
  ([token] -> Set token
forall a. Ord a => [a] -> Set a
Set.fromList [token]
chars)
  ((Int -> CategoryTest token)
-> ([Int] -> CategoryTest token)
-> Either Int [Int]
-> CategoryTest token
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (Categorize token -> CategoryTest token
forall token. Categorize token -> CategoryTest token
AndAsIn (Categorize token -> CategoryTest token)
-> (Int -> Categorize token) -> Int -> CategoryTest token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Categorize token
forall a. Enum a => Int -> a
toEnum) (Set (Categorize token) -> CategoryTest token
forall token. Set (Categorize token) -> CategoryTest token
AndNotAsIn (Set (Categorize token) -> CategoryTest token)
-> ([Int] -> Set (Categorize token)) -> [Int] -> CategoryTest token
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> Categorize token) -> Set Int -> Set (Categorize token)
forall b a. Ord b => (a -> b) -> Set a -> Set b
Set.map Int -> Categorize token
forall a. Enum a => Int -> a
toEnum (Set Int -> Set (Categorize token))
-> ([Int] -> Set Int) -> [Int] -> Set (Categorize token)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Int] -> Set Int
forall a. Ord a => [a] -> Set a
Set.fromList) Either Int [Int]
catTest)