aboutsummaryrefslogtreecommitdiffstats
path: root/src/VeriFuzz/Reduce.hs
diff options
context:
space:
mode:
authorYann Herklotz <git@ymhg.org>2019-04-02 19:47:32 +0100
committerYann Herklotz <git@ymhg.org>2019-04-02 19:47:32 +0100
commitfd4b0b5152f94cd406f2e5de86ce7ed0a4d2cbd0 (patch)
tree673439d49fa095bf3ae9b7bbbca5f30d7ff20838 /src/VeriFuzz/Reduce.hs
parentc0c799ab3f79c370e4c33b8f824489ce8b1c96ec (diff)
downloadverismith-fd4b0b5152f94cd406f2e5de86ce7ed0a4d2cbd0.tar.gz
verismith-fd4b0b5152f94cd406f2e5de86ce7ed0a4d2cbd0.zip
Large refactor with passing tests
Diffstat (limited to 'src/VeriFuzz/Reduce.hs')
-rw-r--r--src/VeriFuzz/Reduce.hs176
1 files changed, 0 insertions, 176 deletions
diff --git a/src/VeriFuzz/Reduce.hs b/src/VeriFuzz/Reduce.hs
deleted file mode 100644
index 4f1ccea..0000000
--- a/src/VeriFuzz/Reduce.hs
+++ /dev/null
@@ -1,176 +0,0 @@
-{-|
-Module : VeriFuzz.Reduce
-Description : Test case reducer implementation.
-Copyright : (c) 2019, Yann Herklotz
-License : GPL-3
-Maintainer : ymherklotz [at] gmail [dot] com
-Stability : experimental
-Portability : POSIX
-
-Test case reducer implementation.
--}
-
-{-# LANGUAGE RankNTypes #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-
-module VeriFuzz.Reduce
- ( reduce
- )
-where
-
-import Control.Lens
-import VeriFuzz.AST
-import VeriFuzz.CodeGen
-import VeriFuzz.Internal
-import VeriFuzz.Mutate
-
-data Replacement a = Dual a a
- | Single a
- | None
- deriving (Eq, Show)
-
-instance Functor Replacement where
- fmap f (Dual a b) = Dual (f a) $ f b
- fmap f (Single a) = Single $ f a
- fmap _ None = None
-
-instance Applicative Replacement where
- pure = Single
- (Dual a b) <*> (Dual c d) = Dual (a c) $ b d
- (Dual a b) <*> (Single c) = Dual (a c) $ b c
- (Single a) <*> (Dual b c) = Dual (a b) $ a c
- (Single a) <*> (Single b) = Single $ a b
- None <*> _ = None
- _ <*> None = None
-
-instance Foldable Replacement where
- foldMap _ None = mempty
- foldMap f (Single a) = f a
- foldMap f (Dual a b) = f a <> f b
-
-instance Traversable Replacement where
- traverse _ None = pure None
- traverse f (Single a) = Single <$> f a
- traverse f (Dual a b) = Dual <$> f a <*> f b
-
--- | Split a list in two halves.
-halve :: [a] -> Replacement [a]
-halve [] = None
-halve [a] = Single [a]
-halve l = Dual a b where (a, b) = splitAt (length l `div` 2) l
-
-combine :: Lens' a b -> (b -> Replacement b) -> a -> Replacement a
-combine l f i = modify <$> f (i ^. l) where modify res = i & l .~ res
-
-filterExpr :: [Identifier] -> Expr -> Expr
-filterExpr ids (Id i) = if i `notElem` ids then Number 1 0 else Id i
-filterExpr _ e = e
-
-filterDecl :: [Identifier] -> ModItem -> Bool
-filterDecl ids (Decl Nothing (Port _ _ _ i)) = i `elem` ids
-filterDecl _ _ = True
-
-filterAssigns :: [Port] -> ModItem -> Bool
-filterAssigns out (ModCA (ContAssign i _)) =
- notElem i $ out ^.. traverse . portName
-filterAssigns _ _ = False
-
-cleanUndefined :: [Identifier] -> [ModItem] -> [ModItem]
-cleanUndefined ids mis =
- filter (filterDecl usedWires) mis
- & traverse
- . modContAssign
- . contAssignExpr
- %~ transform (filterExpr usedWires)
- where
- usedWires = mis ^.. traverse . modContAssign . contAssignNetLVal <> ids
-
-halveModAssign :: ModDecl -> Replacement ModDecl
-halveModAssign m = cleanMod m $ modify <$> assigns (m ^. modItems)
- where
- assigns = halve . filter (filterAssigns $ m ^. modOutPorts)
- modify l = m & modItems .~ l
-
-cleanMod :: ModDecl -> Replacement ModDecl -> Replacement ModDecl
-cleanMod m newm = modify . change <$> newm
- where
- mis = m ^. modItems
- modify l = m & modItems .~ l
- change l =
- cleanUndefined (m ^.. modInPorts . traverse . portName)
- . combineAssigns (head $ m ^. modOutPorts)
- . (filter (not . filterAssigns []) mis <>)
- $ l
- ^. modItems
-
--- | Split a module declaration in half by trying to remove assign statements.
-halveAssigns :: SourceInfo -> Replacement SourceInfo
-halveAssigns = combine mainModule halveModAssign
-
-halveIndExpr :: Expr -> Replacement Expr
-halveIndExpr (Concat l ) = Concat <$> halve l
-halveIndExpr (BinOp e1 _ e2) = Dual e1 e2
-halveIndExpr (Cond _ e1 e2) = Dual e1 e2
-halveIndExpr (UnOp _ e ) = Single e
-halveIndExpr (Func _ e ) = Single e
-halveIndExpr e = Single e
-
-halveModExpr :: ModItem -> Replacement ModItem
-halveModExpr (ModCA ca) = ModCA <$> combine contAssignExpr halveIndExpr ca
-halveModExpr a = Single a
-
-halveExpr :: SourceInfo -> Replacement SourceInfo
-halveExpr = combine contexpr $ traverse halveModExpr
- where
- contexpr :: Lens' SourceInfo [ModItem]
- contexpr = mainModule . modItems
-
-reduce_
- :: (SourceInfo -> Replacement SourceInfo)
- -> (SourceInfo -> IO Bool)
- -> SourceInfo
- -> IO SourceInfo
-reduce_ repl eval src = do
- replAnswer <- sequenceA $ evalIfNotEmpty <$> replacement
- case (replacement, replAnswer) of
- (Single s, Single False) -> do
- putStrLn "########## 1 ##########"
- runIf s
- (Dual _ l, Dual True False) -> do
- putStrLn "########## 2 ##########"
- runIf l
- (Dual r _, Dual False True) -> do
- putStrLn "########## 3 ##########"
- runIf r
- (Dual r l, Dual False False) -> do
- putStrLn "########## 4 ##########"
- lreduced <- runIf l
- rreduced <- runIf r
- if runSource lreduced < runSource rreduced
- then return lreduced
- else return rreduced
- (None, None) -> do
- putStrLn "########## 5 ##########"
- return src
- _ -> do
- putStrLn "########## 6 ##########"
- return src
- where
- replacement = repl src
- runIf s = if s /= src then reduce eval s else return s
- evalIfNotEmpty m = do
- print
- $ GenVerilog
- <$> m
- ^.. mainModule
- . modItems
- . traverse
- . modContAssign
- eval m
-
--- | Reduce an input to a minimal representation.
-reduce
- :: (SourceInfo -> IO Bool) -- ^ Failed or not.
- -> SourceInfo -- ^ Input verilog source to be reduced.
- -> IO SourceInfo -- ^ Reduced output.
-reduce eval src = reduce_ halveAssigns eval src >>= reduce_ halveExpr eval