diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,29 @@
 
 ## Unreleased
 
+## 0.2.0.0 - 2026-03-05
+
+### Added
+- `stepPure`, `walkPure`, `resetPure` exported from `Haal.BlackBox`
+- `Config` record types for all equivalence oracles: `WMethodConfig`, `WpMethodConfig`,
+  `RandomWalkConfig`, `RandomWordsConfig`, `RandomWMethodConfig`, `RandomWpMethodConfig`
+- `mkCombinedOracle` smart constructor for `CombinedOracle`
+- `randomWordsConfig` accessor for `RandomWords`
+- `mealyDelta`, `mealyLambda` as explicit named exports from `Haal.Automaton.MealyAutomaton`
+
+### Changed
+- All oracle constructors now take a `Config` record instead of positional arguments:
+  `mkWMethod :: WMethodConfig -> WMethod`, `mkWpMethod :: WpMethodConfig -> WpMethod`, etc.
+- `mkRandomWMethod` and `mkRandomWpMethod` now take a `Config` record instead of
+  positional arguments (also fixes an argument-order bug in the old interface)
+
+### Removed
+- `mealyStep` from `Haal.Automaton.MealyAutomaton`; use `stepPure` from `Haal.BlackBox`
+- `mooreStep` from `Haal.Automaton.MooreAutomaton`; use `stepPure` from `Haal.BlackBox`
+- Raw constructor exports (`MealyAutomaton (..)`, `WMethod (..)`, `WpMethod (..)`,
+  `RandomWalk (..)`, `RandomWords (..)`, `CombinedOracle (..)`, `LMstar (..)`);
+  use the corresponding `mk`-prefixed smart constructors instead
+
 ## 0.1.0.0 - 2025-12-02
 
 - Initial release of `haal`.
@@ -17,5 +40,3 @@
         - LPlus.
     - Basic equivalence oracles. 
     - Examples that showcase usage of the library.
-
-
diff --git a/examples/demo.hs b/examples/demo.hs
--- a/examples/demo.hs
+++ b/examples/demo.hs
@@ -18,7 +18,7 @@
 sulTransitions S2 B = (S0, Y)
 
 -- Set up the experiment.
-myexperiment = experiment (mkLMstar Star) (mkWMethod 2)
+myexperiment = experiment (mkLMstar Star) (mkWMethod (WMethodConfig 2))
 
 -- Define the Mealy system under learning. Remember that automata can act as suls.
 mysul = mkMealyAutomaton2 sulTransitions (Set.fromList [S0, S1, S2]) S0
diff --git a/examples/div.hs b/examples/div.hs
--- a/examples/div.hs
+++ b/examples/div.hs
@@ -3,7 +3,7 @@
 
 import Haal.Automaton.MealyAutomaton
 import Haal.BlackBox (SUL (..), StateID)
-import Haal.EquivalenceOracle.WpMethod (WpMethod, mkWpMethod)
+import Haal.EquivalenceOracle.WpMethod (WpMethod, WpMethodConfig (..), mkWpMethod)
 import Haal.Experiment
 import Haal.Learning.LMstar (LMstar, LMstarConfig (Star), mkLMstar)
 import Control.Monad.Identity (Identity)
@@ -83,7 +83,7 @@
 learner = mkLMstar Star
 
 oracle :: WpMethod
-oracle = mkWpMethod 3
+oracle = mkWpMethod (WpMethodConfig 3)
 
 exper :: Experiment (Program Binary Bool) (MealyAutomaton StateID Binary Bool, Statistics MealyAutomaton StateID Binary Bool)
 exper = experiment learner oracle
diff --git a/examples/io.hs b/examples/io.hs
--- a/examples/io.hs
+++ b/examples/io.hs
@@ -77,7 +77,7 @@
 learner = mkLMstar Star
 
 oracle :: WpMethod
-oracle = mkWpMethod 3
+oracle = mkWpMethod (WpMethodConfig 3)
 
 exper ::
     ExperimentT
diff --git a/examples/website.hs b/examples/website.hs
--- a/examples/website.hs
+++ b/examples/website.hs
@@ -3,7 +3,7 @@
 
 import qualified Data.List as List
 import Haal.BlackBox
-import Haal.EquivalenceOracle.WMethod (mkWMethod)
+import Haal.EquivalenceOracle.WMethod (WMethodConfig (..), mkWMethod)
 import Haal.Experiment
 import Haal.Learning.LMstar
 import System.Process (readProcess)
@@ -85,7 +85,7 @@
 --------------------------------------------------------------------------------
 
 learner = mkLMstar Star
-teacher = mkWMethod 2
+teacher = mkWMethod (WMethodConfig 2)
 exper = experiment learner teacher
 
 --------------------------------------------------------------------------------
diff --git a/haal.cabal b/haal.cabal
--- a/haal.cabal
+++ b/haal.cabal
@@ -5,7 +5,7 @@
 -- see: https://github.com/sol/hpack
 
 name:           haal
-version:        0.1.0.0
+version:        0.2.0.0
 synopsis:       A Haskell library for Active Automata Learning.
 description:    Please see the README on GitHub at <https://github.com/steve-anunknown/haal#readme>
 category:       Model Learning
diff --git a/src/Haal/Automaton/MealyAutomaton.hs b/src/Haal/Automaton/MealyAutomaton.hs
--- a/src/Haal/Automaton/MealyAutomaton.hs
+++ b/src/Haal/Automaton/MealyAutomaton.hs
@@ -4,11 +4,11 @@
 
 -- | This module implements a Mealy automaton.
 module Haal.Automaton.MealyAutomaton (
-    MealyAutomaton (..),
+    MealyAutomaton,
     mkMealyAutomaton,
     mkMealyAutomaton2,
-    mealyStep,
-    mealyReset,
+    mealyDelta,
+    mealyLambda,
     mealyTransitions,
 )
 where
diff --git a/src/Haal/Automaton/MooreAutomaton.hs b/src/Haal/Automaton/MooreAutomaton.hs
--- a/src/Haal/Automaton/MooreAutomaton.hs
+++ b/src/Haal/Automaton/MooreAutomaton.hs
@@ -6,7 +6,6 @@
 module Haal.Automaton.MooreAutomaton (
     MooreAutomaton,
     mkMooreAutomaton,
-    mooreStep,
     mooreTransitions,
 )
 where
diff --git a/src/Haal/BlackBox.hs b/src/Haal/BlackBox.hs
--- a/src/Haal/BlackBox.hs
+++ b/src/Haal/BlackBox.hs
@@ -16,6 +16,9 @@
     inputs,
     outputs,
     walk,
+    stepPure,
+    walkPure,
+    resetPure,
     initial,
     distinguish,
     accessSequences,
diff --git a/src/Haal/EquivalenceOracle/CombinedOracle.hs b/src/Haal/EquivalenceOracle/CombinedOracle.hs
--- a/src/Haal/EquivalenceOracle/CombinedOracle.hs
+++ b/src/Haal/EquivalenceOracle/CombinedOracle.hs
@@ -1,6 +1,7 @@
 -- | This module implements a combined equivalence oracle for two oracles.
 module Haal.EquivalenceOracle.CombinedOracle (
-    CombinedOracle (..),
+    CombinedOracle,
+    mkCombinedOracle,
 ) where
 
 import Haal.Experiment
@@ -10,6 +11,10 @@
 of the first oracle and then using the second oracle.
 -}
 data CombinedOracle a b = CombinedOracle a b deriving (Show, Eq)
+
+-- | Constructor for a 'CombinedOracle' value.
+mkCombinedOracle :: a -> b -> CombinedOracle a b
+mkCombinedOracle = CombinedOracle
 
 instance
     ( EquivalenceOracle a
diff --git a/src/Haal/EquivalenceOracle/RandomWalk.hs b/src/Haal/EquivalenceOracle/RandomWalk.hs
--- a/src/Haal/EquivalenceOracle/RandomWalk.hs
+++ b/src/Haal/EquivalenceOracle/RandomWalk.hs
@@ -1,6 +1,6 @@
 -- | This module implements the Random Walk equivalence oracle.
 module Haal.EquivalenceOracle.RandomWalk (
-    RandomWalk (..),
+    RandomWalk,
     RandomWalkConfig (..),
     mkRandomWalk,
 )
diff --git a/src/Haal/EquivalenceOracle/RandomWords.hs b/src/Haal/EquivalenceOracle/RandomWords.hs
--- a/src/Haal/EquivalenceOracle/RandomWords.hs
+++ b/src/Haal/EquivalenceOracle/RandomWords.hs
@@ -1,8 +1,9 @@
 -- | This module implements a simple random words equivalence oracle.
 module Haal.EquivalenceOracle.RandomWords (
-    RandomWords (..),
+    RandomWords,
     RandomWordsConfig (..),
     mkRandomWords,
+    randomWordsConfig,
 )
 where
 
@@ -29,6 +30,10 @@
 -- | Constructor for a 'RandomWords' data type.
 mkRandomWords :: RandomWordsConfig -> RandomWords
 mkRandomWords = RandomWords
+
+-- | Accessor for the 'RandomWordsConfig' of a 'RandomWords' value.
+randomWordsConfig :: RandomWords -> RandomWordsConfig
+randomWordsConfig (RandomWords config) = config
 
 -- | Return the test suite of the 'RandomWords' algorithm.
 generateRandomWords :: (FiniteOrd a) => RandomWords -> sul a o -> (RandomWords, [[a]])
diff --git a/src/Haal/EquivalenceOracle/WMethod.hs b/src/Haal/EquivalenceOracle/WMethod.hs
--- a/src/Haal/EquivalenceOracle/WMethod.hs
+++ b/src/Haal/EquivalenceOracle/WMethod.hs
@@ -2,9 +2,10 @@
 
 -- | This module implements the W-method equivalence oracle.
 module Haal.EquivalenceOracle.WMethod (
-    WMethod (..),
+    WMethod,
+    WMethodConfig (..),
     wmethodSuiteSize,
-    RandomWMethod (..),
+    RandomWMethod,
     RandomWMethodConfig (..),
     mkWMethod,
     mkRandomWMethod,
@@ -16,18 +17,24 @@
 import qualified Data.Set as Set
 import qualified Data.Vector as Vec
 import Haal.BlackBox
-import Haal.EquivalenceOracle.RandomWords
+import Haal.EquivalenceOracle.RandomWords (RandomWordsConfig (..), mkRandomWords, randomWordsConfig)
 import Haal.Experiment
 import System.Random (Random (randomRs), RandomGen (split), StdGen)
 
+{- | The 'WMethodConfig' type is used to configure the W-method equivalence oracle.
+-}
+data WMethodConfig = WMethodConfig
+    { wmDepth :: Int
+    -- ^ The number of extra states beyond the hypothesis to account for.
+    }
+    deriving (Show, Eq)
+
 {- | The 'WMethod' type represents the W-method equivalence oracle.
-It is just a wrapper around an integer, which is used for configuring
-the exploration depth of the method.
 -}
-newtype WMethod = WMethod Int deriving (Show, Eq)
+newtype WMethod = WMethod WMethodConfig deriving (Show, Eq)
 
 -- | Constructor for a 'WMethod' value.
-mkWMethod :: Int -> WMethod
+mkWMethod :: WMethodConfig -> WMethod
 mkWMethod = WMethod
 
 -- | The 'wmethodSuiteSize' function computes the size of the test suite for the W-method.
@@ -40,7 +47,7 @@
     WMethod ->
     aut s i o ->
     Int
-wmethodSuiteSize (WMethod d) aut = size
+wmethodSuiteSize (WMethod (WMethodConfig d)) aut = size
   where
     alphabet = Set.size $ inputs aut
     accessSeqs = Map.size $ accessSequences aut
@@ -58,7 +65,7 @@
     WMethod ->
     aut s i o ->
     (WMethod, [[i]])
-wmethodSuite wm@(WMethod d) aut = (wm, suite)
+wmethodSuite wm@(WMethod (WMethodConfig d)) aut = (wm, suite)
   where
     alphabet = Set.toList $ inputs aut
     accessSeqs = accessSequences aut
@@ -90,8 +97,8 @@
 newtype RandomWMethod = RandomWMethod RandomWMethodConfig deriving (Show, Eq)
 
 -- | Constructor for a 'RandomWMethod' value.
-mkRandomWMethod :: StdGen -> Int -> Int -> RandomWMethod
-mkRandomWMethod g l n = RandomWMethod (RandomWMethodConfig g n l)
+mkRandomWMethod :: RandomWMethodConfig -> RandomWMethod
+mkRandomWMethod = RandomWMethod
 
 -- | The 'randomWMethodSuite' function generates the test suite for the random W-method and a new oracle.
 randomWMethodSuite ::
@@ -105,20 +112,20 @@
     aut s i o ->
     (RandomWMethod, [[i]])
 randomWMethodSuite (RandomWMethod (RandomWMethodConfig g wpr wl)) aut =
-    let rorc = RandomWords (RandomWordsConfig{rwMaxLength = wl, rwMinLength = 1, rwLimit = wpr, rwGen = g})
+    let rorc = mkRandomWords (RandomWordsConfig{rwMaxLength = wl, rwMinLength = 1, rwLimit = wpr, rwGen = g})
         prefixes = Map.elems $ accessSequences aut
         vecSuffixes = Vec.fromList $ Set.toList $ globalCharacterizingSet aut
 
-        (RandomWords roc', wordBatches) = List.mapAccumL testSuite rorc (replicate (length prefixes) (undefined :: aut s i o))
+        (rorc', wordBatches) = List.mapAccumL testSuite rorc (replicate (length prefixes) (undefined :: aut s i o))
         flatWords = concat wordBatches
 
-        (gen'', gen''') = split (rwGen roc')
+        (gen'', gen''') = split (rwGen (randomWordsConfig rorc'))
         samples = length prefixes * wpr
         randomSuffixes = take samples $ randomRs (0, Vec.length vecSuffixes - 1) gen''
         suffixes = map (vecSuffixes Vec.!) randomSuffixes
 
         suite = [prefix ++ rand ++ suffix | prefix <- prefixes, rand <- flatWords, suffix <- suffixes]
-     in (mkRandomWMethod gen''' wpr wl, suite)
+     in (mkRandomWMethod (RandomWMethodConfig gen''' wpr wl), suite)
 
 instance EquivalenceOracle RandomWMethod where
     testSuite = randomWMethodSuite
diff --git a/src/Haal/EquivalenceOracle/WpMethod.hs b/src/Haal/EquivalenceOracle/WpMethod.hs
--- a/src/Haal/EquivalenceOracle/WpMethod.hs
+++ b/src/Haal/EquivalenceOracle/WpMethod.hs
@@ -2,11 +2,11 @@
 
 -- | This module implements the WpMethod.
 module Haal.EquivalenceOracle.WpMethod (
-    WpMethod (..),
-    RandomWpMethod (..),
+    WpMethod,
+    WpMethodConfig (..),
+    RandomWpMethod,
     RandomWpMethodConfig (..),
     wpmethodSuiteSize,
-    randomWpMethodSuite,
     mkWpMethod,
     mkRandomWpMethod,
 ) where
@@ -20,17 +20,65 @@
 import Haal.Experiment
 import System.Random (Random (randomR), StdGen)
 
--- | Type for the WpMethod. It simply wraps the depth of the method.
-newtype WpMethod = WpMethod Int deriving (Eq, Show)
+-- | The 'WpMethodConfig' type is used to configure the Wp-method equivalence oracle.
+data WpMethodConfig = WpMethodConfig
+    { wpmDepth :: Int
+    -- ^ The number of extra states beyond the hypothesis to account for.
+    }
+    deriving (Show, Eq)
 
+-- | The 'WpMethod' type represents the Wp-method equivalence oracle.
+newtype WpMethod = WpMethod WpMethodConfig deriving (Eq, Show)
+
 -- | Constructor for a 'WpMethod' value.
-mkWpMethod :: Int -> WpMethod
+mkWpMethod :: WpMethodConfig -> WpMethod
 mkWpMethod = WpMethod
 
--- | The 'wpmethodSuiteSize' returns the nunmber of test cases in the test suite of WpMethod
-wpmethodSuiteSize :: a
-wpmethodSuiteSize = error "todo"
+-- | The 'wpmethodSuiteSize' returns the number of test cases in the test suite of WpMethod.
+wpmethodSuiteSize ::
+    ( Automaton aut s i o
+    , FiniteOrd i
+    , FiniteOrd s
+    , Eq o
+    ) =>
+    WpMethod ->
+    aut s i o ->
+    Int
+wpmethodSuiteSize (WpMethod (WpMethodConfig d)) aut = firstPhaseSize + secondPhaseSize
+  where
+    alphabetList = Set.toList (inputs aut)
+    alphabetSize = length alphabetList
+    stateCover = accessSequences aut
+    localSufSizes =
+        Map.fromAscList
+            [ (st, Set.size (localCharacterizingSet aut st))
+            | st <- Set.toAscList (states aut)
+            ]
+    globalSufSize = Set.size (globalCharacterizingSet aut)
+    transitionCover =
+        Set.fromList
+            [ acc ++ [a]
+            | acc <- Map.elems stateCover
+            , a <- alphabetList
+            ]
+    difference = Set.fromList (Map.elems stateCover) `Set.difference` transitionCover
 
+    -- Closed form: |S| * |W| * (1 + |Σ| + ... + |Σ|^d)
+    firstPhaseSize =
+        Map.size stateCover
+            * globalSufSize
+            * sum [alphabetSize ^ k | k <- [0 .. d]]
+
+    -- Walk each acc once, then enumerate middles from that state; no test strings built.
+    secondPhaseSize =
+        sum
+            [ localSufSizes Map.! current (fst (runIdentity (walk afterAcc middle)))
+            | acc <- Set.toList difference
+            , let afterAcc = fst (runIdentity (walk aut acc))
+            , fixed <- [0 .. d]
+            , middle <- replicateM fixed alphabetList
+            ]
+
 -- | Returns the test suite for the WpMethod.
 wpmethodSuite ::
     forall aut i o s.
@@ -42,7 +90,7 @@
     WpMethod ->
     aut s i o ->
     (WpMethod, [[i]])
-wpmethodSuite wpm@(WpMethod d) aut = (wpm, suite)
+wpmethodSuite wpm@(WpMethod (WpMethodConfig d)) aut = (wpm, suite)
   where
     alphabet = inputs aut
     stateCover = accessSequences aut
diff --git a/src/Haal/Learning/LMstar.hs b/src/Haal/Learning/LMstar.hs
--- a/src/Haal/Learning/LMstar.hs
+++ b/src/Haal/Learning/LMstar.hs
@@ -6,7 +6,7 @@
 -- | This module implements the LM* algorithm for learning Mealy automata.
 module Haal.Learning.LMstar (
     lmstar,
-    LMstar (..),
+    LMstar,
     LMstarConfig (..),
     mkLMstar,
 )
@@ -111,7 +111,9 @@
     ExperimentT (sul i o) m (LMstar i o, MealyAutomaton StateID i o)
 lmstar (LMstar ot) = case otIsClosed ot of
     [] -> case otIsConsistent ot of
-        ([], []) -> return (LMstar ot, makeHypothesis ot)
+        ([], []) -> case makeHypothesis ot of
+            Just hyp -> return (LMstar ot, hyp)
+            Nothing -> error "LM*: invariant violation — makeHypothesis failed on closed consistent table"
         inc' -> do
             ot' <- makeConsistent ot inc'
             lmstar (LMstar ot')
@@ -119,7 +121,9 @@
         ot' <- makeClosed ot inc
         lmstar (LMstar ot')
 lmstar (LMplus ot) = case otIsClosed ot of
-    [] -> return (LMplus ot, makeHypothesis ot)
+    [] -> case makeHypothesis ot of
+        Just hyp -> return (LMplus ot, hyp)
+        Nothing -> error "LM+: invariant violation — makeHypothesis failed on closed table"
     inc -> do
         ot' <- makeClosed ot inc
         lmstar (LMplus ot')
@@ -176,39 +180,45 @@
 
 {- | The 'makeHypothesis' function constructs a Mealy automaton from the observation table. It uses
 the default 'StateID' type defined in the 'Experiment' module for representing the automaton states.
+Returns 'Nothing' if the observation table is malformed (invariant violated).
 -}
-makeHypothesis :: forall i o. (FiniteOrd i, Eq o) => ObservationTable i o -> MealyAutomaton StateID i o
-makeHypothesis ot = mkMealyAutomaton delta' lambda' (Set.fromList [0 .. length repList - 1]) starting
+makeHypothesis :: forall i o. (FiniteOrd i, Eq o) => ObservationTable i o -> Maybe (MealyAutomaton StateID i o)
+makeHypothesis ot = do
+    startId <- getStateId []
+    let stateInputPairs = [(sid, i) | sid <- [0 .. numStates - 1], i <- alphaList]
+    deltaEntries <- mapM buildDeltaEntry stateInputPairs
+    lambdaEntries <- mapM buildLambdaEntry stateInputPairs
+    let deltaMap = Map.fromList deltaEntries
+        lambdaMap = Map.fromList lambdaEntries
+        delta' sid i = deltaMap Map.! (sid, i)
+        lambda' sid i = lambdaMap Map.! (sid, i)
+    return $ mkMealyAutomaton delta' lambda' (Set.fromList [0 .. numStates - 1]) startId
   where
-    -- Equivalence classes: Map from representative prefix to class members
-    equivMap :: Map.Map [i] [[i]]
     equivMap = equivalenceClasses ot
-
-    -- Assign an integer ID to each class representative
-    repList :: [[i]]
     repList = Map.keys equivMap
-
-    repToId :: Map.Map [i] StateID
+    numStates = length repList
     repToId = Map.fromList (zip repList [0 ..])
+    alphaList = [minBound .. maxBound] :: [i]
 
-    -- Helper: get the ID for the class a string belongs to
-    getStateId :: [i] -> StateID
-    getStateId s =
-        case List.find (equivalentRows ot s) repList of
-            Just rep -> repToId Map.! rep
-            Nothing -> error "No equivalent class found for string!"
+    getStateId :: [i] -> Maybe StateID
+    getStateId s = List.find (equivalentRows ot s) repList >>= flip Map.lookup repToId
 
-    delta' :: StateID -> i -> StateID
-    delta' sid i =
-        let rep = repList !! sid
-         in getStateId (rep ++ [i])
+    repAt :: StateID -> Maybe [i]
+    repAt sid
+        | sid >= 0 && sid < numStates = Just (repList !! sid)
+        | otherwise = Nothing
 
-    lambda' :: StateID -> i -> o
-    lambda' sid i =
-        let rep = repList !! sid
-         in mappingT ot Map.! (rep, [i])
+    buildDeltaEntry :: (StateID, i) -> Maybe ((StateID, i), StateID)
+    buildDeltaEntry (sid, i) = do
+        rep <- repAt sid
+        target <- getStateId (rep ++ [i])
+        return ((sid, i), target)
 
-    starting = getStateId []
+    buildLambdaEntry :: (StateID, i) -> Maybe ((StateID, i), o)
+    buildLambdaEntry (sid, i) = do
+        rep <- repAt sid
+        o <- Map.lookup (rep, [i]) (mappingT ot)
+        return ((sid, i), o)
 
 -- | The 'makeConsistent' function makes the observation table consistent by adding missing prefixes.
 makeConsistent ::
diff --git a/test/EquivalenceOracleSpec.hs b/test/EquivalenceOracleSpec.hs
--- a/test/EquivalenceOracleSpec.hs
+++ b/test/EquivalenceOracleSpec.hs
@@ -3,7 +3,7 @@
 ) where
 
 import Control.Monad.Reader
-import Haal.EquivalenceOracle.WMethod (WMethod (..), wmethodSuiteSize)
+import Haal.EquivalenceOracle.WMethod (wmethodSuiteSize)
 import Haal.Experiment
 import Test.Hspec (Spec, context, describe, it)
 import Test.QuickCheck (Property, property, (==>))
@@ -19,8 +19,8 @@
 
 -- WMethod-specific cardinality law
 prop_WMethodCardinality :: ArbWMethod -> Mealy State Input Output -> Bool
-prop_WMethodCardinality (ArbWMethod (WMethod d)) (Mealy aut) =
-    length (snd (testSuite (WMethod d) aut)) == wmethodSuiteSize (WMethod d) aut
+prop_WMethodCardinality (ArbWMethod wm) (Mealy aut) =
+    length (snd (testSuite wm aut)) == wmethodSuiteSize wm aut
 
 spec :: Spec
 spec = do
diff --git a/test/Utils.hs b/test/Utils.hs
--- a/test/Utils.hs
+++ b/test/Utils.hs
@@ -24,39 +24,45 @@
 import qualified Data.Maybe
 import qualified Data.Set as Set
 import Haal.Automaton.MealyAutomaton (
-    MealyAutomaton (..),
-    mealyDelta,
-    mealyLambda,
+    MealyAutomaton,
+    mkMealyAutomaton,
+    mealyTransitions,
  )
 import Haal.BlackBox
 import Haal.EquivalenceOracle.RandomWalk (
-    RandomWalk (RandomWalk),
-    RandomWalkConfig (RandomWalkConfig),
+    RandomWalk,
+    RandomWalkConfig (..),
+    mkRandomWalk,
  )
 import Haal.EquivalenceOracle.RandomWords (
-    RandomWords (RandomWords),
-    RandomWordsConfig (RandomWordsConfig),
+    RandomWords,
+    RandomWordsConfig (..),
+    mkRandomWords,
  )
 import Haal.EquivalenceOracle.WMethod (
-    RandomWMethod (RandomWMethod),
-    RandomWMethodConfig (RandomWMethodConfig),
-    WMethod (WMethod),
+    RandomWMethod,
+    RandomWMethodConfig (..),
+    WMethod,
+    WMethodConfig (..),
     mkWMethod,
+    mkRandomWMethod,
  )
 import Haal.EquivalenceOracle.WpMethod (
-    RandomWpMethod (RandomWpMethod),
-    RandomWpMethodConfig (RandomWpMethodConfig),
-    WpMethod (WpMethod),
+    RandomWpMethod,
+    RandomWpMethodConfig (..),
+    WpMethod,
+    WpMethodConfig (..),
     mkWpMethod,
+    mkRandomWpMethod,
  )
 import Haal.Experiment (EquivalenceOracle)
 import System.Random
 import Test.QuickCheck (Arbitrary (..), Gen, choose, elements, vectorOf)
 
-newtype ArbWMethodConfig = ArbWMethodConfig Int deriving (Show, Eq)
+newtype ArbWMethodConfig = ArbWMethodConfig WMethodConfig deriving (Show, Eq)
 newtype ArbWMethod = ArbWMethod WMethod deriving (Show, Eq)
 
-newtype ArbWpMethodConfig = ArbWpMethodConfig Int deriving (Show, Eq)
+newtype ArbWpMethodConfig = ArbWpMethodConfig WpMethodConfig deriving (Show, Eq)
 newtype ArbWpMethod = ArbWpMethod WpMethod deriving (Show, Eq)
 
 newtype ArbRandomWordsConfig = ArbRandomWordsConfig RandomWordsConfig deriving (Show, Eq)
@@ -74,7 +80,7 @@
 instance Arbitrary ArbWMethodConfig where
     arbitrary = do
         d <- choose (1, 5)
-        return (ArbWMethodConfig d)
+        return (ArbWMethodConfig (WMethodConfig d))
 instance Arbitrary ArbWMethod where
     arbitrary = do
         (ArbWMethodConfig config) <- arbitrary :: Gen ArbWMethodConfig
@@ -83,7 +89,7 @@
 instance Arbitrary ArbWpMethodConfig where
     arbitrary = do
         d <- choose (1, 5)
-        return (ArbWpMethodConfig d)
+        return (ArbWpMethodConfig (WpMethodConfig d))
 instance Arbitrary ArbWpMethod where
     arbitrary = do
         (ArbWpMethodConfig config) <- arbitrary :: Gen ArbWpMethodConfig
@@ -100,7 +106,7 @@
 instance Arbitrary ArbRandomWords where
     arbitrary = do
         (ArbRandomWordsConfig config) <- arbitrary :: Gen ArbRandomWordsConfig
-        return (ArbRandomWords (RandomWords config))
+        return (ArbRandomWords (mkRandomWords config))
 
 instance Arbitrary ArbRandomWalkConfig where
     arbitrary = do
@@ -112,7 +118,7 @@
 instance Arbitrary ArbRandomWalk where
     arbitrary = do
         (ArbRandomWalkConfig config) <- arbitrary :: Gen ArbRandomWalkConfig
-        return (ArbRandomWalk (RandomWalk config))
+        return (ArbRandomWalk (mkRandomWalk config))
 
 instance Arbitrary ArbRandomWMethodConfig where
     arbitrary = do
@@ -124,7 +130,7 @@
 instance Arbitrary ArbRandomWMethod where
     arbitrary = do
         (ArbRandomWMethodConfig config) <- arbitrary :: Gen ArbRandomWMethodConfig
-        return (ArbRandomWMethod (RandomWMethod config))
+        return (ArbRandomWMethod (mkRandomWMethod config))
 
 instance Arbitrary ArbRandomWpMethodConfig where
     arbitrary = do
@@ -138,7 +144,7 @@
 instance Arbitrary ArbRandomWpMethod where
     arbitrary = do
         (ArbRandomWpMethodConfig config) <- arbitrary :: Gen ArbRandomWpMethodConfig
-        return (ArbRandomWpMethod (RandomWpMethod config))
+        return (ArbRandomWpMethod (mkRandomWpMethod config))
 
 class (EquivalenceOracle oracle) => OracleWrapper w oracle | w -> oracle where
     unwrap :: w -> oracle
@@ -183,13 +189,9 @@
 
         return
             ( Mealy
-                ( MealyAutomaton
-                    { mealyDelta = delta
-                    , mealyLambda = lambda
-                    , mealyInitialS = initialState
-                    , mealyCurrentS = currentState
-                    , mealyStates = Set.fromList sts
-                    }
+                ( update
+                    (mkMealyAutomaton delta lambda (Set.fromList sts) initialState)
+                    currentState
                 )
             )
       where
@@ -246,13 +248,9 @@
 
         return
             ( NonMinimalMealy
-                ( MealyAutomaton
-                    { mealyDelta = delta
-                    , mealyLambda = lambda
-                    , mealyInitialS = initialState
-                    , mealyCurrentS = currentState
-                    , mealyStates = Set.fromList sts
-                    }
+                ( update
+                    (mkMealyAutomaton delta lambda (Set.fromList sts) initialState)
+                    currentState
                 )
             )
       where
@@ -294,8 +292,6 @@
 statesAreEquivalent :: MealyAutomaton State Input Output -> State -> State -> Bool
 statesAreEquivalent _ s1 s2 | s1 == s2 = True
 statesAreEquivalent automaton s1 s2 =
-    all (\i -> (delta s1 i, lambda s1 i) == (delta s2 i, lambda s2 i)) alphabet
+    all (\i -> trans Map.! (s1, i) == trans Map.! (s2, i)) (inputs automaton)
   where
-    delta = mealyDelta automaton
-    lambda = mealyLambda automaton
-    alphabet = inputs automaton
+    trans = mealyTransitions automaton
