module RegExp where
--import List
import MUtils(usort)

infixl 2 !,-!,:!,:-!
infixr 3 &,:&

Transitions for transducers:

data Trans i o = I i | O o deriving (Show,Eq,Ord)

type Transducer i o = RegExp (Trans i o)

Regular expressions:

data RegExp t
  = One -- the language containing the empty string, unit of :&
  | Zero -- the empty language, unit of :!
  | S t -- a single symbol
  | RegExp t :& RegExp t -- sequence (associative)
  | RegExp t :! RegExp t -- alternative (cummutative and associative)
  | RegExp t :-! RegExp t -- difference
  | Many (RegExp t) -- sequence of zero or more
  | Some (RegExp t) -- sequence of one or more
-- An experimental extension with a fix-point operator:
  | Fix (RegExp t)
  | Self
  deriving (Eq,Ord,Show)

Some convenient constructor functions:

e     = One
z     = Zero
t     = S . I
o     = S . O
ts rs = seqs $ map t rs
a  rs = alts $ map t rs

opt r = r ! e

alts rs = foldr (!) z rs
seqs rs = foldr (&) e rs

Optimizing regular expression constructors:

many One = One
many Zero = One
many (Many r) = Many r
many (Some r) = Many r
many r = Many r

some One = One
some Zero = Zero
some (Many r) = Many r
some (Some r) = Some r
some r = Some r

r1 ! r2   = alts' (usort ts)
  where
    ts = terms r1 . terms r2 $ []

    alts' [] = z
    alts' ts = foldr1 (:!) ts

    terms Zero = id
    terms (r1 :! r2) = terms r1 . terms r2
    terms r = (r:)

r1 & Zero = Zero
r1 & One  = r1
r1 & r2   = consFactors r1 r2
  where
    consFactors One = id
    consFactors Zero = const Zero
    consFactors (r1:&r2) = consFactors r1 . consFactors r2
    consFactors r = (r:&)

Zero -! r = Zero
r -! Zero = r
r1 -! r2 = if r1==r2 then Zero else r1 :-! r2

fix Zero = Zero
fix One = One
fix Self = Zero
fix ((One:!Self):&r) | not (selfIn r) = some r
fix r = if selfIn r then Fix r else r

selfIn r =
     case r of
       Zero -> False
       One -> False
       S _ -> False
       r1 :& r2  -> selfIn r1 || selfIn r2
       r1 :! r2  -> selfIn r1 || selfIn r2
       r1 :-! r2 -> selfIn r1 || selfIn r2
       Many r -> selfIn r
       Some r -> selfIn r
       Fix r -> False
       Self -> True