kleene-0.1: Kleene algebra

Safe HaskellSafe
LanguageHaskell2010

Kleene

Contents

Description

Kleene algebra.

This package provides means to work with kleene algebra, at the moment specifically concentrating on regular expressions over Char.

Implements ideas from Regular-expression derivatives re-examined by Scott Owens, John Reppy and Aaron Turon https://doi.org/10.1017/S0956796808007090.

>>> :set -XOverloadedStrings
>>> import Algebra.Lattice
>>> import Algebra.PartialOrd
>>> import Data.Semigroup
>>> import Kleene.Internal.Pretty (putPretty)

Kleene.RE module provides RE type. Kleene.Classes module provides various classes to work with the type. All of that is re-exported from Kleene module.

First let's construct a regular expression value:

>>> let re = star "abc" <> "def" <> ("x" \/ "yz") :: RE Char
>>> putPretty re
^(abc)*def(x|yz)$

We can convert it to DFA (there are 8 states)

>>> let dfa = fromTM re
>>> putPretty dfa
0 -> \x -> if
    | x <= '`'  -> 8
    | x <= 'a'  -> 5
    | x <= 'c'  -> 8
    | x <= 'd'  -> 3
    | otherwise -> 8
1 -> \x -> if
    | x <= 'w'  -> 8
    | x <= 'x'  -> 6
    | x <= 'y'  -> 7
    | otherwise -> 8
2 -> ...
...

It's also possible to graphically visualise DFAs

λ> writeFile "example.dot' (toDot dfa)
%  dot -Tpng -oexample.png example.dot

And we can convert back from DFA to RE:

>>> let re' = toKleene dfa :: RE Char
>>> putPretty re'
^(a(bca)*bcdefx|defx|(a(bca)*bcdefy|defy)z)$

As you see, we don't get what we started with. Yet, these regular expressions are equivalent;

>>> equivalent re re'
True

or using Equiv wrapper

>>> Equiv re == Equiv re'
True

(The paper doesn't outline decision procedure for the equivalence, though it's right there - seems to be fast enough at least for toy examples like here).

We can use regular expressions to generate word examples in the language:

>>> import Data.Foldable
>>> import qualified Test.QuickCheck as QC
>>> import Kleene.RE (generate)
>>> traverse_ print $ take 5 $ generate (curry QC.choose) 42 re
"abcabcabcabcabcabcdefyz"
"abcabcabcabcdefyz"
"abcabcabcabcabcabcabcabcabcdefx"
"abcabcdefx"
"abcabcabcabcabcabcdefyz"

In addition to the "normal" regular expressions, there are extended regular expressions. Regular expressions which we can complement, and therefore intersect:

>>> let ere = star "aa" /\ star "aaa" :: ERE Char
>>> putPretty ere
^~(~((aa)*)|~((aaa)*))$

We can convert ERE to RE via DFA:

>>> let re'' = toKleene (fromTM ere) :: RE Char
>>> putPretty re''
^(a(aaaaaa)*aaaaa)?$

Machine works own ways, we don't (always) get as pretty results as we'd like:

>>> equivalent re'' (star "aaaaaa")
True

Another feature of the library is an Applciative Functor,

>>> import Control.Applicative
>>> import qualified Kleene.Functor as F
>>> let f = (,) <$> many (F.char 'x') <* F.few F.anyChar <*> many (F.char 'z')
>>> putPretty f
^x*[^]*z*$

By relying on http://hackage.haskell.org/package/regex-applicative library, we can match and capture with regular expression.

>>> F.match f "xyyzzz"
Just ("x","zzz")

Where with RE we can only get True or False:

>>> match (F.toRE f) "xyyzzz"
True

Which in this case is not even interesting because:

>>> equivalent (F.toRE f) everything
True

Converting from RE to K is also possible, which may be handy:

>>> let g = (,) <$> F.few F.anyChar <*> F.fromRE re''
>>> putPretty g
^[^]*(a(aaaaaa)*aaaaa)?$
>>> F.match g (replicate 20 'a')
Just ("aa","aaaaaaaaaaaaaaaaaa")

We got longest divisible by 6 prefix of as. That's because fromRE uses many for star.

Synopsis

Regular expressions

data RE c Source #

Regular expression

Constructors are exposed, but you should use smart constructors in this module to construct RE.

The Eq and Ord instances are structural. The Kleene etc constructors do "weak normalisation", so for values constructed using those operations Eq witnesses "weak equivalence". See equivalent for regular-expression equivalence.

Structure is exposed in Kleene.RE module but consider constructors as half-internal. There are soft-invariants, but violating them shouldn't break anything in the package. (e.g. transitionMap will eventually terminate, but may create more redundant states if starting regexp is not "weakly normalised").

Instances
ToLatin1 RE Source # 
Instance details

Defined in Kleene.Internal.RE

Methods

toLatin1 :: RE Char -> RE Word8 Source #

(Ord c, Enum c, Bounded c) => Complement c (RE c) Source # 
Instance details

Defined in Kleene.DFA

Methods

complement :: RE c -> RE c Source #

(Ord c, Enum c, Bounded c) => TransitionMap c (RE c) Source # 
Instance details

Defined in Kleene.Internal.RE

Methods

transitionMap :: RE c -> Map (RE c) (SF c (RE c)) Source #

(Ord c, Enum c, Bounded c) => Equivalent c (RE c) Source # 
Instance details

Defined in Kleene.Internal.RE

Methods

equivalent :: RE c -> RE c -> Bool Source #

(Ord c, Enum c, Bounded c) => Match c (RE c) Source # 
Instance details

Defined in Kleene.Internal.RE

Methods

match :: RE c -> [c] -> Bool Source #

match8 :: RE c -> ByteString -> Bool Source #

(Ord c, Enum c, Bounded c) => Derivate c (RE c) Source # 
Instance details

Defined in Kleene.Internal.RE

Methods

nullable :: RE c -> Bool Source #

derivate :: c -> RE c -> RE c Source #

(Ord c, Enum c, Bounded c) => FiniteKleene c (RE c) Source # 
Instance details

Defined in Kleene.Internal.RE

Methods

everything :: RE c Source #

charRange :: c -> c -> RE c Source #

fromRSet :: RSet c -> RE c Source #

dot :: RE c Source #

anyChar :: RE c Source #

notChar :: c -> RE c Source #

(Ord c, Enum c, Bounded c) => CharKleene c (RE c) Source # 
Instance details

Defined in Kleene.Internal.RE

Methods

char :: c -> RE c Source #

string :: [c] -> RE c Source #

Eq c => Eq (RE c) Source # 
Instance details

Defined in Kleene.Internal.RE

Methods

(==) :: RE c -> RE c -> Bool #

(/=) :: RE c -> RE c -> Bool #

Ord c => Ord (RE c) Source # 
Instance details

Defined in Kleene.Internal.RE

Methods

compare :: RE c -> RE c -> Ordering #

(<) :: RE c -> RE c -> Bool #

(<=) :: RE c -> RE c -> Bool #

(>) :: RE c -> RE c -> Bool #

(>=) :: RE c -> RE c -> Bool #

max :: RE c -> RE c -> RE c #

min :: RE c -> RE c -> RE c #

Show c => Show (RE c) Source # 
Instance details

Defined in Kleene.Internal.RE

Methods

showsPrec :: Int -> RE c -> ShowS #

show :: RE c -> String #

showList :: [RE c] -> ShowS #

c ~ Char => IsString (RE c) Source # 
Instance details

Defined in Kleene.Internal.RE

Methods

fromString :: String -> RE c #

Eq c => Semigroup (RE c) Source # 
Instance details

Defined in Kleene.Internal.RE

Methods

(<>) :: RE c -> RE c -> RE c #

sconcat :: NonEmpty (RE c) -> RE c #

stimes :: Integral b => b -> RE c -> RE c #

Eq c => Monoid (RE c) Source # 
Instance details

Defined in Kleene.Internal.RE

Methods

mempty :: RE c #

mappend :: RE c -> RE c -> RE c #

mconcat :: [RE c] -> RE c #

(Ord c, Enum c, Bounded c, Arbitrary c) => Arbitrary (RE c) Source # 
Instance details

Defined in Kleene.Internal.RE

Methods

arbitrary :: Gen (RE c) #

shrink :: RE c -> [RE c] #

CoArbitrary c => CoArbitrary (RE c) Source # 
Instance details

Defined in Kleene.Internal.RE

Methods

coarbitrary :: RE c -> Gen b -> Gen b #

(Ord c, Enum c, Bounded c) => Lattice (RE c) Source #

WARNING: The /\ is inefficient, it actually computes the conjunction:

>>> putPretty $ asREChar $ "a" /\ "b"
^[]$
>>> putPretty $ asREChar $ "a" /\ star "a"
^a$
>>> putPretty $ asREChar $ star "aa" /\ star "aaa"
^(a(aaaaaa)*aaaaa)?$
Instance details

Defined in Kleene.DFA

Methods

(\/) :: RE c -> RE c -> RE c #

(/\) :: RE c -> RE c -> RE c #

(Ord c, Enum c, Bounded c) => BoundedJoinSemiLattice (RE c) Source # 
Instance details

Defined in Kleene.DFA

Methods

bottom :: RE c #

(Ord c, Enum c, Bounded c) => BoundedMeetSemiLattice (RE c) Source # 
Instance details

Defined in Kleene.DFA

Methods

top :: RE c #

c ~ Char => Pretty (RE c) Source # 
Instance details

Defined in Kleene.Internal.RE

Methods

pretty :: RE c -> String Source #

prettyS :: RE c -> ShowS Source #

(Ord c, Enum c, Bounded c) => Kleene (RE c) Source # 
Instance details

Defined in Kleene.Internal.RE

Methods

empty :: RE c Source #

eps :: RE c Source #

appends :: [RE c] -> RE c Source #

unions :: [RE c] -> RE c Source #

star :: RE c -> RE c Source #

data ERE c Source #

Extended regular expression

It's both, Kleene and Boolean algebra. (If we add only intersections, it wouldn't be Boolean).

Note: we don't have special constructor for intersections. We use de Morgan formula \(a \land b = \neg (\neg a \lor \neg b)\).

>>> putPretty $ asEREChar $ "a" /\ "b"
^~(~a|~b)$

There is no generator, as intersections makes it hard.

Instances
ToLatin1 ERE Source # 
Instance details

Defined in Kleene.ERE

Complement c (ERE c) Source # 
Instance details

Defined in Kleene.ERE

Methods

complement :: ERE c -> ERE c Source #

(Ord c, Enum c, Bounded c) => TransitionMap c (ERE c) Source # 
Instance details

Defined in Kleene.ERE

Methods

transitionMap :: ERE c -> Map (ERE c) (SF c (ERE c)) Source #

(Ord c, Enum c, Bounded c) => Equivalent c (ERE c) Source # 
Instance details

Defined in Kleene.ERE

Methods

equivalent :: ERE c -> ERE c -> Bool Source #

(Ord c, Enum c) => Match c (ERE c) Source # 
Instance details

Defined in Kleene.ERE

Methods

match :: ERE c -> [c] -> Bool Source #

match8 :: ERE c -> ByteString -> Bool Source #

(Ord c, Enum c) => Derivate c (ERE c) Source # 
Instance details

Defined in Kleene.ERE

Methods

nullable :: ERE c -> Bool Source #

derivate :: c -> ERE c -> ERE c Source #

(Ord c, Enum c, Bounded c) => FiniteKleene c (ERE c) Source # 
Instance details

Defined in Kleene.ERE

Methods

everything :: ERE c Source #

charRange :: c -> c -> ERE c Source #

fromRSet :: RSet c -> ERE c Source #

dot :: ERE c Source #

anyChar :: ERE c Source #

notChar :: c -> ERE c Source #

(Ord c, Enum c, Bounded c) => CharKleene c (ERE c) Source # 
Instance details

Defined in Kleene.ERE

Methods

char :: c -> ERE c Source #

string :: [c] -> ERE c Source #

Eq c => Eq (ERE c) Source # 
Instance details

Defined in Kleene.ERE

Methods

(==) :: ERE c -> ERE c -> Bool #

(/=) :: ERE c -> ERE c -> Bool #

Ord c => Ord (ERE c) Source # 
Instance details

Defined in Kleene.ERE

Methods

compare :: ERE c -> ERE c -> Ordering #

(<) :: ERE c -> ERE c -> Bool #

(<=) :: ERE c -> ERE c -> Bool #

(>) :: ERE c -> ERE c -> Bool #

(>=) :: ERE c -> ERE c -> Bool #

max :: ERE c -> ERE c -> ERE c #

min :: ERE c -> ERE c -> ERE c #

Show c => Show (ERE c) Source # 
Instance details

Defined in Kleene.ERE

Methods

showsPrec :: Int -> ERE c -> ShowS #

show :: ERE c -> String #

showList :: [ERE c] -> ShowS #

c ~ Char => IsString (ERE c) Source # 
Instance details

Defined in Kleene.ERE

Methods

fromString :: String -> ERE c #

Eq c => Semigroup (ERE c) Source # 
Instance details

Defined in Kleene.ERE

Methods

(<>) :: ERE c -> ERE c -> ERE c #

sconcat :: NonEmpty (ERE c) -> ERE c #

stimes :: Integral b => b -> ERE c -> ERE c #

Eq c => Monoid (ERE c) Source # 
Instance details

Defined in Kleene.ERE

Methods

mempty :: ERE c #

mappend :: ERE c -> ERE c -> ERE c #

mconcat :: [ERE c] -> ERE c #

(Ord c, Enum c, Bounded c, Arbitrary c) => Arbitrary (ERE c) Source # 
Instance details

Defined in Kleene.ERE

Methods

arbitrary :: Gen (ERE c) #

shrink :: ERE c -> [ERE c] #

CoArbitrary c => CoArbitrary (ERE c) Source # 
Instance details

Defined in Kleene.ERE

Methods

coarbitrary :: ERE c -> Gen b -> Gen b #

(Ord c, Enum c) => Lattice (ERE c) Source # 
Instance details

Defined in Kleene.ERE

Methods

(\/) :: ERE c -> ERE c -> ERE c #

(/\) :: ERE c -> ERE c -> ERE c #

(Ord c, Enum c) => BoundedJoinSemiLattice (ERE c) Source # 
Instance details

Defined in Kleene.ERE

Methods

bottom :: ERE c #

(Ord c, Enum c) => BoundedMeetSemiLattice (ERE c) Source # 
Instance details

Defined in Kleene.ERE

Methods

top :: ERE c #

c ~ Char => Pretty (ERE c) Source # 
Instance details

Defined in Kleene.ERE

Methods

pretty :: ERE c -> String Source #

prettyS :: ERE c -> ShowS Source #

(Ord c, Enum c, Bounded c) => Kleene (ERE c) Source # 
Instance details

Defined in Kleene.ERE

Methods

empty :: ERE c Source #

eps :: ERE c Source #

appends :: [ERE c] -> ERE c Source #

unions :: [ERE c] -> ERE c Source #

star :: ERE c -> ERE c Source #

Equivalence (and partial order)

newtype Equiv r c Source #

Regular-expressions for which == is equivalent.

>>> let re1 = star "a" <> "a" :: RE Char
>>> let re2 = "a" <> star "a" :: RE Char
>>> re1 == re2
False
>>> Equiv re1 == Equiv re2
True

Equiv is also a PartialOrd (but not Ord!)

>>> Equiv "a" `leq` Equiv (star "a" :: RE Char)
True

Not all regular expessions are comparable:

>>> let reA = Equiv "a" :: Equiv RE Char
>>> let reB = Equiv "b" :: Equiv RE Char
>>> (leq reA reB, leq reB reA)
(False,False)

Constructors

Equiv (r c) 
Instances
Complement c (r c) => Complement c (Equiv r c) Source # 
Instance details

Defined in Kleene.Equiv

Methods

complement :: Equiv r c -> Equiv r c Source #

Equivalent c (r c) => Equivalent c (Equiv r c) Source # 
Instance details

Defined in Kleene.Equiv

Methods

equivalent :: Equiv r c -> Equiv r c -> Bool Source #

Match c (r c) => Match c (Equiv r c) Source # 
Instance details

Defined in Kleene.Equiv

Methods

match :: Equiv r c -> [c] -> Bool Source #

match8 :: Equiv r c -> ByteString -> Bool Source #

Derivate c (r c) => Derivate c (Equiv r c) Source # 
Instance details

Defined in Kleene.Equiv

Methods

nullable :: Equiv r c -> Bool Source #

derivate :: c -> Equiv r c -> Equiv r c Source #

CharKleene c (r c) => CharKleene c (Equiv r c) Source # 
Instance details

Defined in Kleene.Equiv

Methods

char :: c -> Equiv r c Source #

string :: [c] -> Equiv r c Source #

Equivalent c (r c) => Eq (Equiv r c) Source # 
Instance details

Defined in Kleene.Equiv

Methods

(==) :: Equiv r c -> Equiv r c -> Bool #

(/=) :: Equiv r c -> Equiv r c -> Bool #

Show (r c) => Show (Equiv r c) Source # 
Instance details

Defined in Kleene.Equiv

Methods

showsPrec :: Int -> Equiv r c -> ShowS #

show :: Equiv r c -> String #

showList :: [Equiv r c] -> ShowS #

Semigroup (r c) => Semigroup (Equiv r c) Source # 
Instance details

Defined in Kleene.Equiv

Methods

(<>) :: Equiv r c -> Equiv r c -> Equiv r c #

sconcat :: NonEmpty (Equiv r c) -> Equiv r c #

stimes :: Integral b => b -> Equiv r c -> Equiv r c #

Monoid (r c) => Monoid (Equiv r c) Source # 
Instance details

Defined in Kleene.Equiv

Methods

mempty :: Equiv r c #

mappend :: Equiv r c -> Equiv r c -> Equiv r c #

mconcat :: [Equiv r c] -> Equiv r c #

Lattice (r c) => Lattice (Equiv r c) Source # 
Instance details

Defined in Kleene.Equiv

Methods

(\/) :: Equiv r c -> Equiv r c -> Equiv r c #

(/\) :: Equiv r c -> Equiv r c -> Equiv r c #

BoundedJoinSemiLattice (r c) => BoundedJoinSemiLattice (Equiv r c) Source # 
Instance details

Defined in Kleene.Equiv

Methods

bottom :: Equiv r c #

BoundedMeetSemiLattice (r c) => BoundedMeetSemiLattice (Equiv r c) Source # 
Instance details

Defined in Kleene.Equiv

Methods

top :: Equiv r c #

(Lattice (r c), Equivalent c (r c)) => PartialOrd (Equiv r c) Source #

\(a \preceq b := a \lor b = b \)

Instance details

Defined in Kleene.Equiv

Methods

leq :: Equiv r c -> Equiv r c -> Bool #

comparable :: Equiv r c -> Equiv r c -> Bool #

Pretty (r c) => Pretty (Equiv r c) Source # 
Instance details

Defined in Kleene.Equiv

Methods

pretty :: Equiv r c -> String Source #

prettyS :: Equiv r c -> ShowS Source #

Kleene (r c) => Kleene (Equiv r c) Source # 
Instance details

Defined in Kleene.Equiv

Methods

empty :: Equiv r c Source #

eps :: Equiv r c Source #

appends :: [Equiv r c] -> Equiv r c Source #

unions :: [Equiv r c] -> Equiv r c Source #

star :: Equiv r c -> Equiv r c Source #

Deterministic finite automaton

data DFA c Source #

Deterministic finite automaton.

A deterministic finite automaton (DFA) over an alphabet \(\Sigma\) (type variable c) is 4-tuple \(Q\), \(q_0\) , \(F\), \(\delta\), where

  • \(Q\) is a finite set of states (subset of s),
  • \(q_0 \in Q\) is the distinguised start state (dfaInitial),
  • \(F \subset Q\) is a set of final (or accepting) states (dfaAcceptable), and
  • \(\delta : Q \times \Sigma \to Q\) is a function called the state transition function (dfaTransition).

Constructors

DFA 

Fields

Instances
Complement c (DFA c) Source #

Complement DFA.

Complement of DFA is way easier than of RE: complement accept states.

>>> let dfa = complement $ fromRE $ RE.star "abc"
>>> putPretty dfa
0 -> \x -> if
    | x <= '`'  -> 3
    | x <= 'a'  -> 2
    | otherwise -> 3
1+ -> \x -> if
    | x <= 'b'  -> 3
    | x <= 'c'  -> 0
    | otherwise -> 3
2+ -> \x -> if
    | x <= 'a'  -> 3
    | x <= 'b'  -> 1
    | otherwise -> 3
3+ -> \_ -> 3 -- black hole
>>> map (match dfa) ["", "abc", "abcabc", "aa","abca", 'a' : 'a' : undefined]
[False,False,False,True,True,True]
Instance details

Defined in Kleene.DFA

Methods

complement :: DFA c -> DFA c Source #

Ord c => Match c (DFA c) Source #

Run DFA on the input.

Because we have analysed a language, in some cases we can determine a result without traversing all of the input. That's not the cases with RE match.

>>> let dfa = fromRE $ RE.star "abc"
>>> map (match dfa) ["", "abc", "abcabc", "aa", 'a' : 'a' : undefined]
[True,True,True,False,False]

Holds:

match (fromRE re) xs == match re xs
all (match (fromRE r)) $ take 10 $ RE.generate (curry QC.choose) 42 (r :: RE.RE Char)
Instance details

Defined in Kleene.DFA

Methods

match :: DFA c -> [c] -> Bool Source #

match8 :: DFA c -> ByteString -> Bool Source #

Ord c => Derivate c (DFA c) Source # 
Instance details

Defined in Kleene.DFA

Methods

nullable :: DFA c -> Bool Source #

derivate :: c -> DFA c -> DFA c Source #

Show c => Show (DFA c) Source # 
Instance details

Defined in Kleene.DFA

Methods

showsPrec :: Int -> DFA c -> ShowS #

show :: DFA c -> String #

showList :: [DFA c] -> ShowS #

Show c => Pretty (DFA c) Source # 
Instance details

Defined in Kleene.DFA

Methods

pretty :: DFA c -> String Source #

prettyS :: DFA c -> ShowS Source #

fromTM :: forall k c. (Ord k, Ord c, TransitionMap c k) => k -> DFA c Source #

Create from TransitionMap.

See fromRE for a specific example.

fromTMEquiv :: forall k c. (Ord k, Ord c, TransitionMap c k, Equivalent c k) => k -> DFA c Source #

Create from TransitonMap minimising states with Equivalent.

See fromERE for an example.

toKleene :: forall k c. (Ord c, Enum c, Bounded c, FiniteKleene c k) => DFA c -> k Source #

Convert to any Kleene.

See toRE for a specific example.

toDot :: DFA Char -> String Source #

Get Graphviz dot-code of DFA.

>>> let dfa = fromRE $ RE.star "abc"
>>> putStr $ toDot dfa
digraph dfa {
rankdir=LR;
// states
"0" [shape=doublecircle];
"1" [shape=circle];
"2" [shape=circle];
// initial state
"" [shape=none];
"" -> "0";
// transitions
"0" -> "2"[label="a"]
"1" -> "0"[label="c"]
"2" -> "1"[label="b"]
}

Classes

Most operations are defined in following type-classes.

See Kleene.RE module for a specific version with examples.

class Kleene k where Source #

Kleene algebra.

If k is Monoid it's expected that appends = mappend; if k is Lattice it's expected that unions = joins.

Wikipedia: Kleene Algebra.

Methods

empty :: k Source #

Empty regex. Doesn't accept anything.

eps :: k Source #

Empty string. Note: different than empty.

appends :: [k] -> k Source #

Concatenation.

unions :: [k] -> k Source #

Union.

star :: k -> k Source #

Kleene star.

Instances
(Ord c, Enum c, Bounded c) => Kleene (RE c) Source # 
Instance details

Defined in Kleene.Internal.RE

Methods

empty :: RE c Source #

eps :: RE c Source #

appends :: [RE c] -> RE c Source #

unions :: [RE c] -> RE c Source #

star :: RE c -> RE c Source #

(Ord c, Enum c, Bounded c) => Kleene (ERE c) Source # 
Instance details

Defined in Kleene.ERE

Methods

empty :: ERE c Source #

eps :: ERE c Source #

appends :: [ERE c] -> ERE c Source #

unions :: [ERE c] -> ERE c Source #

star :: ERE c -> ERE c Source #

Kleene (M c) Source # 
Instance details

Defined in Kleene.Monad

Methods

empty :: M c Source #

eps :: M c Source #

appends :: [M c] -> M c Source #

unions :: [M c] -> M c Source #

star :: M c -> M c Source #

Kleene (r c) => Kleene (Equiv r c) Source # 
Instance details

Defined in Kleene.Equiv

Methods

empty :: Equiv r c Source #

eps :: Equiv r c Source #

appends :: [Equiv r c] -> Equiv r c Source #

unions :: [Equiv r c] -> Equiv r c Source #

star :: Equiv r c -> Equiv r c Source #

class Kleene k => CharKleene c k | k -> c where Source #

Minimal complete definition

char

Methods

char :: c -> k Source #

Single character

string :: [c] -> k Source #

Instances
(Ord c, Enum c, Bounded c) => CharKleene c (RE c) Source # 
Instance details

Defined in Kleene.Internal.RE

Methods

char :: c -> RE c Source #

string :: [c] -> RE c Source #

(Ord c, Enum c, Bounded c) => CharKleene c (ERE c) Source # 
Instance details

Defined in Kleene.ERE

Methods

char :: c -> ERE c Source #

string :: [c] -> ERE c Source #

CharKleene c (M c) Source # 
Instance details

Defined in Kleene.Monad

Methods

char :: c -> M c Source #

string :: [c] -> M c Source #

CharKleene c (r c) => CharKleene c (Equiv r c) Source # 
Instance details

Defined in Kleene.Equiv

Methods

char :: c -> Equiv r c Source #

string :: [c] -> Equiv r c Source #

class CharKleene c k => FiniteKleene c k | k -> c where Source #

Minimal complete definition

charRange, fromRSet, anyChar

Methods

everything :: k Source #

Everything. \(\Sigma^\star\).

charRange :: c -> c -> k Source #

charRange a z = ^[a-z]$.

fromRSet :: RSet c -> k Source #

Generalisation of charRange.

dot :: c ~ Char => k Source #

. Every character except new line \n.

anyChar :: k Source #

Any character. Note: different than dot!

notChar :: c -> k Source #

notChar :: (Ord c, Enum c, Bounded c) => c -> k Source #

Instances
(Ord c, Enum c, Bounded c) => FiniteKleene c (RE c) Source # 
Instance details

Defined in Kleene.Internal.RE

Methods

everything :: RE c Source #

charRange :: c -> c -> RE c Source #

fromRSet :: RSet c -> RE c Source #

dot :: RE c Source #

anyChar :: RE c Source #

notChar :: c -> RE c Source #

(Ord c, Enum c, Bounded c) => FiniteKleene c (ERE c) Source # 
Instance details

Defined in Kleene.ERE

Methods

everything :: ERE c Source #

charRange :: c -> c -> ERE c Source #

fromRSet :: RSet c -> ERE c Source #

dot :: ERE c Source #

anyChar :: ERE c Source #

notChar :: c -> ERE c Source #

class Derivate c k | k -> c where Source #

Methods

nullable :: k -> Bool Source #

Does language contain an empty string?

derivate :: c -> k -> k Source #

Derivative of a language.

Instances
(Ord c, Enum c, Bounded c) => Derivate c (RE c) Source # 
Instance details

Defined in Kleene.Internal.RE

Methods

nullable :: RE c -> Bool Source #

derivate :: c -> RE c -> RE c Source #

(Ord c, Enum c) => Derivate c (ERE c) Source # 
Instance details

Defined in Kleene.ERE

Methods

nullable :: ERE c -> Bool Source #

derivate :: c -> ERE c -> ERE c Source #

Ord c => Derivate c (DFA c) Source # 
Instance details

Defined in Kleene.DFA

Methods

nullable :: DFA c -> Bool Source #

derivate :: c -> DFA c -> DFA c Source #

(Eq c, Enum c, Bounded c) => Derivate c (M c) Source # 
Instance details

Defined in Kleene.Monad

Methods

nullable :: M c -> Bool Source #

derivate :: c -> M c -> M c Source #

Derivate c (r c) => Derivate c (Equiv r c) Source # 
Instance details

Defined in Kleene.Equiv

Methods

nullable :: Equiv r c -> Bool Source #

derivate :: c -> Equiv r c -> Equiv r c Source #

class Match c k | k -> c where Source #

An f can be used to match on the input.

Minimal complete definition

match

Methods

match :: k -> [c] -> Bool Source #

match8 :: c ~ Word8 => k -> ByteString -> Bool Source #

Instances
(Ord c, Enum c, Bounded c) => Match c (RE c) Source # 
Instance details

Defined in Kleene.Internal.RE

Methods

match :: RE c -> [c] -> Bool Source #

match8 :: RE c -> ByteString -> Bool Source #

(Ord c, Enum c) => Match c (ERE c) Source # 
Instance details

Defined in Kleene.ERE

Methods

match :: ERE c -> [c] -> Bool Source #

match8 :: ERE c -> ByteString -> Bool Source #

Ord c => Match c (DFA c) Source #

Run DFA on the input.

Because we have analysed a language, in some cases we can determine a result without traversing all of the input. That's not the cases with RE match.

>>> let dfa = fromRE $ RE.star "abc"
>>> map (match dfa) ["", "abc", "abcabc", "aa", 'a' : 'a' : undefined]
[True,True,True,False,False]

Holds:

match (fromRE re) xs == match re xs
all (match (fromRE r)) $ take 10 $ RE.generate (curry QC.choose) 42 (r :: RE.RE Char)
Instance details

Defined in Kleene.DFA

Methods

match :: DFA c -> [c] -> Bool Source #

match8 :: DFA c -> ByteString -> Bool Source #

(Eq c, Enum c, Bounded c) => Match c (M c) Source # 
Instance details

Defined in Kleene.Monad

Methods

match :: M c -> [c] -> Bool Source #

match8 :: M c -> ByteString -> Bool Source #

Match c (r c) => Match c (Equiv r c) Source # 
Instance details

Defined in Kleene.Equiv

Methods

match :: Equiv r c -> [c] -> Bool Source #

match8 :: Equiv r c -> ByteString -> Bool Source #

class Derivate c k => TransitionMap c k | k -> c where Source #

Transition map.

Methods

transitionMap :: k -> Map k (SF c k) Source #

Instances
(Ord c, Enum c, Bounded c) => TransitionMap c (RE c) Source # 
Instance details

Defined in Kleene.Internal.RE

Methods

transitionMap :: RE c -> Map (RE c) (SF c (RE c)) Source #

(Ord c, Enum c, Bounded c) => TransitionMap c (ERE c) Source # 
Instance details

Defined in Kleene.ERE

Methods

transitionMap :: ERE c -> Map (ERE c) (SF c (ERE c)) Source #

class Complement c k | k -> c where Source #

Complement of the language.

Law:

match (complement f) xs = not (match f) xs

Methods

complement :: k -> k Source #

Instances
Complement c (ERE c) Source # 
Instance details

Defined in Kleene.ERE

Methods

complement :: ERE c -> ERE c Source #

(Ord c, Enum c, Bounded c) => Complement c (RE c) Source # 
Instance details

Defined in Kleene.DFA

Methods

complement :: RE c -> RE c Source #

Complement c (DFA c) Source #

Complement DFA.

Complement of DFA is way easier than of RE: complement accept states.

>>> let dfa = complement $ fromRE $ RE.star "abc"
>>> putPretty dfa
0 -> \x -> if
    | x <= '`'  -> 3
    | x <= 'a'  -> 2
    | otherwise -> 3
1+ -> \x -> if
    | x <= 'b'  -> 3
    | x <= 'c'  -> 0
    | otherwise -> 3
2+ -> \x -> if
    | x <= 'a'  -> 3
    | x <= 'b'  -> 1
    | otherwise -> 3
3+ -> \_ -> 3 -- black hole
>>> map (match dfa) ["", "abc", "abcabc", "aa","abca", 'a' : 'a' : undefined]
[False,False,False,True,True,True]
Instance details

Defined in Kleene.DFA

Methods

complement :: DFA c -> DFA c Source #

Complement c (r c) => Complement c (Equiv r c) Source # 
Instance details

Defined in Kleene.Equiv

Methods

complement :: Equiv r c -> Equiv r c Source #

class ToLatin1 k where Source #

Methods

toLatin1 :: k Char -> k Word8 Source #

Instances
ToLatin1 RSet Source # 
Instance details

Defined in Kleene.Classes

ToLatin1 RE Source # 
Instance details

Defined in Kleene.Internal.RE

Methods

toLatin1 :: RE Char -> RE Word8 Source #

ToLatin1 ERE Source # 
Instance details

Defined in Kleene.ERE

Functor

Only the type is exported so it can be referred to.

See Kleene.Functor for operations.

data K c a Source #

Applicative Functor regular expression.

Instances
Functor (K c) Source # 
Instance details

Defined in Kleene.Internal.Functor

Methods

fmap :: (a -> b) -> K c a -> K c b #

(<$) :: a -> K c b -> K c a #

Applicative (K c) Source # 
Instance details

Defined in Kleene.Internal.Functor

Methods

pure :: a -> K c a #

(<*>) :: K c (a -> b) -> K c a -> K c b #

liftA2 :: (a -> b -> c0) -> K c a -> K c b -> K c c0 #

(*>) :: K c a -> K c b -> K c b #

(<*) :: K c a -> K c b -> K c a #

Alternative (K c) Source # 
Instance details

Defined in Kleene.Internal.Functor

Methods

empty :: K c a #

(<|>) :: K c a -> K c a -> K c a #

some :: K c a -> K c [a] #

many :: K c a -> K c [a] #

Alt (K c) Source # 
Instance details

Defined in Kleene.Internal.Functor

Methods

(<!>) :: K c a -> K c a -> K c a #

some :: Applicative (K c) => K c a -> K c [a] #

many :: Applicative (K c) => K c a -> K c [a] #

Apply (K c) Source # 
Instance details

Defined in Kleene.Internal.Functor

Methods

(<.>) :: K c (a -> b) -> K c a -> K c b #

(.>) :: K c a -> K c b -> K c b #

(<.) :: K c a -> K c b -> K c a #

liftF2 :: (a -> b -> c0) -> K c a -> K c b -> K c c0 #

(c ~ Char, IsString a) => IsString (K c a) Source # 
Instance details

Defined in Kleene.Internal.Functor

Methods

fromString :: String -> K c a #

c ~ Char => Pretty (K c a) Source #

Convert to non-matching JavaScript string which can be used as an argument to new RegExp

>>> putPretty ("foobar" :: K Char String)
^foobar$
>>> putPretty $ many ("foobar" :: K Char String)
^(foobar)*$
Instance details

Defined in Kleene.Internal.Functor

Methods

pretty :: K c a -> String Source #

prettyS :: K c a -> ShowS Source #