diff --git a/regex-genex.cabal b/regex-genex.cabal
--- a/regex-genex.cabal
+++ b/regex-genex.cabal
@@ -1,5 +1,5 @@
 Name            : regex-genex
-Version         : 0.2.1
+Version         : 0.3.0
 license         : OtherLicense
 license-file    : LICENSE
 cabal-version   : >= 1.6
@@ -17,16 +17,17 @@
 library
     hs-source-dirs:     . src
     exposed-modules:    Regex.Genex Regex.Genex.Normalize
-    extensions      : ImplicitParams, NamedFieldPuns, ParallelListComp, PatternGuards
+    other-modules:    Regex.Genex.Pure
+    extensions      : ImplicitParams, NamedFieldPuns, ParallelListComp, PatternGuards, RecordWildCards
     build-depends:
-        base >= 3 && < 5, haskell98, mtl, containers, sbv, regex-tdfa
+        base >= 3 && < 5, haskell98, mtl, containers, sbv, regex-tdfa, control-monad-omega, text
 
 executable genex
     main-is:            Main.hs
     hs-source-dirs:     . src
-    extensions      : ImplicitParams, NamedFieldPuns, ParallelListComp, PatternGuards
+    extensions      : ImplicitParams, NamedFieldPuns, ParallelListComp, PatternGuards, RecordWildCards
     build-depends:
-        base >= 3 && < 5, haskell98, mtl, containers, sbv, regex-tdfa
+        base >= 3 && < 5, haskell98, mtl, containers, sbv, regex-tdfa, control-monad-omega, text
 
 source-repository head
   type:     git
diff --git a/src/Regex/Genex.hs b/src/Regex/Genex.hs
--- a/src/Regex/Genex.hs
+++ b/src/Regex/Genex.hs
@@ -1,12 +1,14 @@
 {-# LANGUAGE ImplicitParams, NamedFieldPuns, ParallelListComp, PatternGuards #-}
-module Regex.Genex (Model(..), genex, genexPrint, genexModels) where
+module Regex.Genex (Model(..), genex, genexPure, genexPrint, genexModels) where
 import Data.SBV
 import Data.SBV.Internals (SBV)
 import Data.Set (toList)
 import Data.Monoid
 import Control.Monad.State
 import qualified Data.Char
+import qualified Regex.Genex.Pure as Pure
 import Text.Regex.TDFA.Pattern
+import Regex.Genex.Normalize (normalize)
 import Text.Regex.TDFA.ReadRegex (parseRegex)
 import Data.IntSet (IntSet)
 import qualified Data.IntSet as IntSet
@@ -15,7 +17,8 @@
 import System.IO.Unsafe (unsafeInterleaveIO)
 import Regex.Genex.Normalize (normalize)
 
--- | Given a list of regular repressions, returns all possible strings that matches all of them.
+-- | Given a list of regular repressions, returns all possible strings that matches every one of them.
+-- Guarantees to return shorter strings before longer ones.
 genex :: [String] -> IO [String]
 genex = genexWith getString
 
@@ -34,11 +37,17 @@
 genexPrint :: [String] -> IO ()
 genexPrint = genexWith displayString
 
+-- | A pure and much faster variant of @genex@, but without support for back-references, anchors or word boundaries.
+-- Does not guarantee orders about length of strings.
+-- Does not depend on the external 'yices' SMT solver.
+genexPure :: [String] -> [String]
+genexPure = Pure.genexPure
+
 type Len = Word16
 type SChar = SWord8
 type Str = [SChar]
 type Offset = SBV Len
-type Flips = SWord64
+type Flips = [SWord64]
 type Captures = SFunArray Word8 Len
 type Hits = Word16
 
@@ -119,7 +128,7 @@
 exactMatch :: (?pats :: [(Pattern, GroupLens)]) => Len -> Symbolic SBool
 exactMatch len = do
     str <- mkFreeVars $ fromEnum len
-    initialFlips <- free "flips"
+    initialFlips <- mkFreeVars 1
     captureAt <- newArray_ (Just minBound)
     captureLen <- newArray_ (Just minBound)
     let ?str = str
@@ -134,9 +143,9 @@
         runPat s (pat, groupLens) = let ?pat = pat in let ?grp = groupLens in
             ite (ok s &&& pos s .== strLen)
                 (match s{ pos = 0, captureAt, captureLen })
-                s{ ok = false, pos = maxBound, flips = maxBound }
+                s{ ok = false, pos = maxBound, flips = [maxBound] }
     let Status{ ok, pos, flips } = foldl runPat initialStatus ?pats
-    return (flips .== 0 &&& pos .== strLen &&& ok)
+    return (bAll (.== 0) flips &&& pos .== strLen &&& ok)
 
 data Status = Status
     { ok :: SBool
@@ -158,14 +167,15 @@
 choice :: (?str :: Str, ?pat :: Pattern) => Flips -> [Flips -> Status] -> Status
 choice _ [] = error "X"
 choice flips [a] = a flips
-choice flips [a, b] = ite (lsb flips) (b flips') (a flips')
+choice flips [a, b] = ite (lsb flip) (b flips') (a flips')
     where
-    flips' = flips `shiftR` 1
-choice flips xs = select (map ($ flips') xs) (head xs thisFlip){ ok = false } thisFlip
+    flip = head flips
+    flips' = [flip `shiftR` 1]
+choice flips xs = select (map ($ flips') xs) (head xs [thisFlip]){ ok = false } thisFlip
     where
     bits = log2 $ length xs
-    flips' = flips `shiftR` bits
-    thisFlip = (flips `shiftL` (64 - bits)) `shiftR` (64 - bits)
+    flips' = [head flips `shiftR` bits]
+    thisFlip = head flips `shiftL` (64 - bits) `shiftR` (64 - bits)
 
 log2 :: Int -> Int
 log2 1 = 0
@@ -309,7 +319,7 @@
         | otherwise = (len .<= off) ||| (charAt (pos+off) .== charAt (from+off) &&& matchCapture from len (n+1))
         where
         off = toEnum n
-    __FAIL__ = s{ ok = false, pos = maxBound, flips = maxBound }
+    __FAIL__ = s{ ok = false, pos = maxBound, flips = [maxBound] }
     isEnd = (pos .== toEnum (length ?str))
     isBegin = (pos .== 0)
     isWordCharAt at = let char = charAt at in
diff --git a/src/Regex/Genex/Pure.hs b/src/Regex/Genex/Pure.hs
new file mode 100644
--- /dev/null
+++ b/src/Regex/Genex/Pure.hs
@@ -0,0 +1,56 @@
+module Regex.Genex.Pure (genexPure) where
+import qualified Data.Text as T
+import qualified Data.IntSet as IntSet
+import qualified Data.Set as Set
+import Data.List (intersect, (\\))
+import Control.Monad
+import Control.Monad.Omega
+import Regex.Genex.Normalize (normalize)
+import Text.Regex.TDFA.Pattern
+import Text.Regex.TDFA.ReadRegex (parseRegex)
+
+parse :: String -> Pattern
+parse r = case parseRegex r of
+    Right (pattern, _) -> pattern
+    Left x -> error $ show x
+
+genexPure :: [String] -> [String]
+genexPure = map T.unpack . foldl1 intersect . map (runOmega . omega . normalize IntSet.empty . parse)
+
+maxRepeat :: Int
+maxRepeat = 3
+
+omega :: Pattern -> Omega T.Text
+omega p = case p of
+    PChar{..} -> isChar getPatternChar
+    PAny {getPatternSet = PatternSet (Just cset) _ _ _} -> each $ map T.singleton $ Set.toList cset
+    PQuest p -> join $ each [return T.empty, omega p]
+    PPlus p -> omega $ PBound 1 Nothing p
+    PStar _ p -> omega $ PBound 0 Nothing p
+    PBound low high p -> do
+        p <- omega p
+        n <- each [low..maybe (low+3) id high]
+        return $ T.replicate n p
+    PConcat ps -> fmap T.concat . sequence $ map omega ps
+    POr xs -> foldl1 mplus $ map omega xs
+    PDot{} -> notChars []
+    PEscape {..} -> case getPatternChar of
+        'n' -> isChar '\n'
+        't' -> isChar '\t'
+        'r' -> isChar '\r'
+        'f' -> isChar '\f'
+        'a' -> isChar '\a'
+        'e' -> isChar '\ESC'
+        'd' -> chars $ ['0'..'9']
+        'w' -> chars $ ['0'..'9'] ++ '_' : ['a'..'z'] ++ ['A'..'Z']
+        's' -> chars "\9\10\12\13\32"
+        'W' -> notChars $ ['0'..'9']
+        'S' -> notChars $ ['0'..'9'] ++ '_' : ['a'..'z'] ++ ['A'..'Z']
+        'D' -> notChars "\9\10\12\13\32"
+        ch  -> isChar ch
+    _      -> error $ show p
+    where
+    isChar :: Char -> Omega T.Text
+    isChar = return . T.singleton
+    chars = each . map T.singleton
+    notChars = chars . ([' '..'~'] \\)
