{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}

-- |
-- Module      : Verismith.Reduce
-- Description : Test case reducer implementation.
-- Copyright   : (c) 2019, Yann Herklotz
-- License     : GPL-3
-- Maintainer  : yann [at] yannherklotz [dot] com
-- Stability   : experimental
-- Portability : POSIX
--
-- Test case reducer implementation.
module Verismith.Reduce
  ( -- $strategy
    reduceWithScript,
    reduceSynth,
    reduceSynthesis,
    reduceSimIc,
    reduce,
    reduce_,
    Replacement (..),
    halveModules,
    halveModItems,
    halveStatements,
    halveExpr,
    halveAssigns,
    findActiveWires,
    clean,
    cleanSourceInfo,
    cleanSourceInfoAll,
    removeDecl,
    removeConstInConcat,
    takeReplace,
    filterExpr,
    ReduceAnn (..),
    tagAlways,
    untagAlways,
  )
where

import Control.Lens hiding ((<.>))
import Control.Monad (void)
import Control.Monad.IO.Class (MonadIO, liftIO)
import Data.ByteString (ByteString)
import Data.Foldable (foldrM)
import Data.IORef (newIORef, readIORef, writeIORef)
import Data.List (nub)
import Data.List.NonEmpty (NonEmpty (..))
import qualified Data.List.NonEmpty as NonEmpty
import Data.Maybe (mapMaybe)
import Data.Text (Text, unpack)
import Shelly (fromText, (<.>))
import qualified Shelly
import Shelly.Lifted (MonadSh, liftSh, rm_rf, writefile)
import Verismith.Result
import Verismith.Tool
import Verismith.Tool.Icarus
import Verismith.Tool.Identity
import Verismith.Tool.Internal
import Verismith.Utils
import Verismith.Verilog
import Verismith.Verilog.AST
import Verismith.Verilog.CodeGen
import Verismith.Verilog.Mutate
import Verismith.Verilog.Parser

-- $strategy
-- The reduction strategy has multiple different steps. 'reduce' will run these
-- strategies one after another, starting at the most coarse grained one. The
-- supported reduction strategies are the following:
--
--   [Modules] First of all, the reducer will try and remove all the modules
--   except the top module.
--
--   [Module Items] Then, the module items will be reduced by using standard
--   delta debugging. Half of the module items will be removed, and both
--   versions will be tested. If both succeed, they will be divided further and
--   tested further. Finally, the shortest version will be returned.
--
--   [Statements] Once the module items have been reduced, the statements will
--   be reduced as well. This is done using delta debugging, just like the
--   module items.
--
--   [Expressions] Finally, the expressions themselves will be reduced. This is
--   done by splitting the top most binary expressions in half and testing each
--   half.

-- | Replacement type that supports returning different kinds of reduced
-- replacements that could be tried.
data Replacement a
  = Dual a a
  | Single a
  | None
  deriving (Int -> Replacement a -> ShowS
[Replacement a] -> ShowS
Replacement a -> String
(Int -> Replacement a -> ShowS)
-> (Replacement a -> String)
-> ([Replacement a] -> ShowS)
-> Show (Replacement a)
forall a. Show a => Int -> Replacement a -> ShowS
forall a. Show a => [Replacement a] -> ShowS
forall a. Show a => Replacement a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> Replacement a -> ShowS
showsPrec :: Int -> Replacement a -> ShowS
$cshow :: forall a. Show a => Replacement a -> String
show :: Replacement a -> String
$cshowList :: forall a. Show a => [Replacement a] -> ShowS
showList :: [Replacement a] -> ShowS
Show, Replacement a -> Replacement a -> Bool
(Replacement a -> Replacement a -> Bool)
-> (Replacement a -> Replacement a -> Bool) -> Eq (Replacement a)
forall a. Eq a => Replacement a -> Replacement a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Eq a => Replacement a -> Replacement a -> Bool
== :: Replacement a -> Replacement a -> Bool
$c/= :: forall a. Eq a => Replacement a -> Replacement a -> Bool
/= :: Replacement a -> Replacement a -> Bool
Eq)

data ReduceAnn
  = Active
  | Reduced
  | Idle
  deriving (Int -> ReduceAnn -> ShowS
[ReduceAnn] -> ShowS
ReduceAnn -> String
(Int -> ReduceAnn -> ShowS)
-> (ReduceAnn -> String)
-> ([ReduceAnn] -> ShowS)
-> Show ReduceAnn
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> ReduceAnn -> ShowS
showsPrec :: Int -> ReduceAnn -> ShowS
$cshow :: ReduceAnn -> String
show :: ReduceAnn -> String
$cshowList :: [ReduceAnn] -> ShowS
showList :: [ReduceAnn] -> ShowS
Show, ReduceAnn -> ReduceAnn -> Bool
(ReduceAnn -> ReduceAnn -> Bool)
-> (ReduceAnn -> ReduceAnn -> Bool) -> Eq ReduceAnn
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ReduceAnn -> ReduceAnn -> Bool
== :: ReduceAnn -> ReduceAnn -> Bool
$c/= :: ReduceAnn -> ReduceAnn -> Bool
/= :: ReduceAnn -> ReduceAnn -> Bool
Eq)

type Replace a = (a -> Replacement a)

instance Functor Replacement where
  fmap :: forall a b. (a -> b) -> Replacement a -> Replacement b
fmap a -> b
f (Dual a
a a
b) = b -> b -> Replacement b
forall a. a -> a -> Replacement a
Dual (a -> b
f a
a) (b -> Replacement b) -> b -> Replacement b
forall a b. (a -> b) -> a -> b
$ a -> b
f a
b
  fmap a -> b
f (Single a
a) = b -> Replacement b
forall a. a -> Replacement a
Single (b -> Replacement b) -> b -> Replacement b
forall a b. (a -> b) -> a -> b
$ a -> b
f a
a
  fmap a -> b
_ Replacement a
None = Replacement b
forall a. Replacement a
None

instance Applicative Replacement where
  pure :: forall a. a -> Replacement a
pure = a -> Replacement a
forall a. a -> Replacement a
Single
  (Dual a -> b
a a -> b
b) <*> :: forall a b. Replacement (a -> b) -> Replacement a -> Replacement b
<*> (Dual a
c a
d) = b -> b -> Replacement b
forall a. a -> a -> Replacement a
Dual (a -> b
a a
c) (b -> Replacement b) -> b -> Replacement b
forall a b. (a -> b) -> a -> b
$ a -> b
b a
d
  (Dual a -> b
a a -> b
b) <*> (Single a
c) = b -> b -> Replacement b
forall a. a -> a -> Replacement a
Dual (a -> b
a a
c) (b -> Replacement b) -> b -> Replacement b
forall a b. (a -> b) -> a -> b
$ a -> b
b a
c
  (Single a -> b
a) <*> (Dual a
b a
c) = b -> b -> Replacement b
forall a. a -> a -> Replacement a
Dual (a -> b
a a
b) (b -> Replacement b) -> b -> Replacement b
forall a b. (a -> b) -> a -> b
$ a -> b
a a
c
  (Single a -> b
a) <*> (Single a
b) = b -> Replacement b
forall a. a -> Replacement a
Single (b -> Replacement b) -> b -> Replacement b
forall a b. (a -> b) -> a -> b
$ a -> b
a a
b
  Replacement (a -> b)
None <*> Replacement a
_ = Replacement b
forall a. Replacement a
None
  Replacement (a -> b)
_ <*> Replacement a
None = Replacement b
forall a. Replacement a
None

instance Foldable Replacement where
  foldMap :: forall m a. Monoid m => (a -> m) -> Replacement a -> m
foldMap a -> m
_ Replacement a
None = m
forall a. Monoid a => a
mempty
  foldMap a -> m
f (Single a
a) = a -> m
f a
a
  foldMap a -> m
f (Dual a
a a
b) = a -> m
f a
a m -> m -> m
forall a. Semigroup a => a -> a -> a
<> a -> m
f a
b

instance Traversable Replacement where
  traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Replacement a -> f (Replacement b)
traverse a -> f b
_ Replacement a
None = Replacement b -> f (Replacement b)
forall a. a -> f a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Replacement b
forall a. Replacement a
None
  traverse a -> f b
f (Single a
a) = b -> Replacement b
forall a. a -> Replacement a
Single (b -> Replacement b) -> f b -> f (Replacement b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> a -> f b
f a
a
  traverse a -> f b
f (Dual a
a a
b) = b -> b -> Replacement b
forall a. a -> a -> Replacement a
Dual (b -> b -> Replacement b) -> f b -> f (b -> Replacement b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> a -> f b
f a
a f (b -> Replacement b) -> f b -> f (Replacement b)
forall a b. f (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> a -> f b
f a
b

-- | Split a list in two halves.
halve :: Replace [a]
halve :: forall a. Replace [a]
halve [] = [a] -> Replacement [a]
forall a. a -> Replacement a
Single []
halve [a
_] = [a] -> Replacement [a]
forall a. a -> Replacement a
Single []
halve [a]
l = [a] -> [a] -> Replacement [a]
forall a. a -> a -> Replacement a
Dual [a]
a [a]
b where ([a]
a, [a]
b) = Int -> [a] -> ([a], [a])
forall a. Int -> [a] -> ([a], [a])
splitAt ([a] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
l Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
2) [a]
l

remove1 :: Replace [a]
remove1 :: forall a. Replace [a]
remove1 [] = [a] -> Replacement [a]
forall a. a -> Replacement a
Single []
remove1 [a
_] = [a] -> Replacement [a]
forall a. a -> Replacement a
Single []
remove1 (a
a : [a]
b) = [a] -> [a] -> Replacement [a]
forall a. a -> a -> Replacement a
Dual [a
a] [a]
b

halveNonEmpty :: Replace (NonEmpty a)
halveNonEmpty :: forall a. Replace (NonEmpty a)
halveNonEmpty NonEmpty a
l = case Int -> NonEmpty a -> ([a], [a])
forall a. Int -> NonEmpty a -> ([a], [a])
NonEmpty.splitAt (NonEmpty a -> Int
forall a. NonEmpty a -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length NonEmpty a
l Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
2) NonEmpty a
l of
  ([], []) -> Replacement (NonEmpty a)
forall a. Replacement a
None
  ([], a
a : [a]
b) -> NonEmpty a -> Replacement (NonEmpty a)
forall a. a -> Replacement a
Single (NonEmpty a -> Replacement (NonEmpty a))
-> NonEmpty a -> Replacement (NonEmpty a)
forall a b. (a -> b) -> a -> b
$ a
a a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
:| [a]
b
  (a
a : [a]
b, []) -> NonEmpty a -> Replacement (NonEmpty a)
forall a. a -> Replacement a
Single (NonEmpty a -> Replacement (NonEmpty a))
-> NonEmpty a -> Replacement (NonEmpty a)
forall a b. (a -> b) -> a -> b
$ a
a a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
:| [a]
b
  (a
a : [a]
b, a
c : [a]
d) -> NonEmpty a -> NonEmpty a -> Replacement (NonEmpty a)
forall a. a -> a -> Replacement a
Dual (a
a a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
:| [a]
b) (NonEmpty a -> Replacement (NonEmpty a))
-> NonEmpty a -> Replacement (NonEmpty a)
forall a b. (a -> b) -> a -> b
$ a
c a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
:| [a]
d

-- | When given a Lens and a function that works on a lower replacement, it will
-- go down, apply the replacement, and return a replacement of the original
-- module.
combine :: (Monoid b) => Traversal' a b -> Replace b -> Replace a
combine :: forall b a. Monoid b => Traversal' a b -> Replace b -> Replace a
combine Traversal' a b
l Replace b
f a
i = b -> a
modify (b -> a) -> Replacement b -> Replacement a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Replace b
f (a
i a -> Getting b a b -> b
forall s a. s -> Getting a s a -> a
^. Getting b a b
Traversal' a b
l) where modify :: b -> a
modify b
res = a
i a -> (a -> a) -> a
forall a b. a -> (a -> b) -> b
& (b -> Identity b) -> a -> Identity a
Traversal' a b
l ((b -> Identity b) -> a -> Identity a) -> b -> a -> a
forall s t a b. ASetter s t a b -> b -> s -> t
.~ b
res

-- | When given a Lens and a function that works on a lower replacement, it will
-- go down, apply the replacement, and return a replacement of the original
-- module.
combineL :: Lens' a b -> Replace b -> Replace a
combineL :: forall a b. Lens' a b -> Replace b -> Replace a
combineL Lens' a b
l Replace b
f a
i = b -> a
modify (b -> a) -> Replacement b -> Replacement a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Replace b
f (a
i a -> Getting b a b -> b
forall s a. s -> Getting a s a -> a
^. Getting b a b
Lens' a b
l) where modify :: b -> a
modify b
res = a
i a -> (a -> a) -> a
forall a b. a -> (a -> b) -> b
& (b -> Identity b) -> a -> Identity a
Lens' a b
l ((b -> Identity b) -> a -> Identity a) -> b -> a -> a
forall s t a b. ASetter s t a b -> b -> s -> t
.~ b
res

-- | Deletes Id 'Expr' if they are not part of the current scope, and replaces
-- these by 0.
filterExpr :: [Identifier] -> Expr -> Expr
filterExpr :: [Identifier] -> Expr -> Expr
filterExpr [Identifier]
ids (Id Identifier
i) = if Identifier
i Identifier -> [Identifier] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Identifier]
ids then Identifier -> Expr
Id Identifier
i else BitVec -> Expr
Number BitVec
0
filterExpr [Identifier]
ids (VecSelect Identifier
i Expr
e) =
  if Identifier
i Identifier -> [Identifier] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Identifier]
ids then Identifier -> Expr -> Expr
VecSelect Identifier
i Expr
e else BitVec -> Expr
Number BitVec
0
filterExpr [Identifier]
ids (RangeSelect Identifier
i Range
r) =
  if Identifier
i Identifier -> [Identifier] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Identifier]
ids then Identifier -> Range -> Expr
RangeSelect Identifier
i Range
r else BitVec -> Expr
Number BitVec
0
filterExpr [Identifier]
_ Expr
e = Expr
e

-- | Checks if a declaration is part of the current scope. If not, it returns
-- 'False', otherwise 'True', as it should be kept.
-- filterDecl :: [Identifier] -> (ModItem ReduceAnn) -> Bool
-- filterDecl ids (Decl Nothing (Port _ _ _ i) _) = i `elem` ids
-- filterDecl _   _                               = True

-- | Checks if a continuous assignment is in the current scope, if not, it
-- returns 'False'.
filterAssigns :: [Port] -> (ModItem ReduceAnn) -> Bool
filterAssigns :: [Port] -> ModItem ReduceAnn -> Bool
filterAssigns [Port]
out (ModCA (ContAssign Identifier
i Expr
_)) =
  Identifier -> [Identifier] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
elem Identifier
i ([Identifier] -> Bool) -> [Identifier] -> Bool
forall a b. (a -> b) -> a -> b
$ [Port]
out [Port]
-> Getting (Endo [Identifier]) [Port] Identifier -> [Identifier]
forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. (Port -> Const (Endo [Identifier]) Port)
-> [Port] -> Const (Endo [Identifier]) [Port]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ((Port -> Const (Endo [Identifier]) Port)
 -> [Port] -> Const (Endo [Identifier]) [Port])
-> ((Identifier -> Const (Endo [Identifier]) Identifier)
    -> Port -> Const (Endo [Identifier]) Port)
-> Getting (Endo [Identifier]) [Port] Identifier
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Identifier -> Const (Endo [Identifier]) Identifier)
-> Port -> Const (Endo [Identifier]) Port
Lens' Port Identifier
portName
filterAssigns [Port]
_ ModItem ReduceAnn
_ = Bool
True

clean :: (Mutate a) => [Identifier] -> a -> a
clean :: forall a. Mutate a => [Identifier] -> a -> a
clean [Identifier]
ids = (Expr -> Expr) -> a -> a
forall a. Mutate a => (Expr -> Expr) -> a -> a
mutExpr ((Expr -> Expr) -> Expr -> Expr
forall a. Plated a => (a -> a) -> a -> a
transform ((Expr -> Expr) -> Expr -> Expr) -> (Expr -> Expr) -> Expr -> Expr
forall a b. (a -> b) -> a -> b
$ [Identifier] -> Expr -> Expr
filterExpr [Identifier]
ids)

takeReplace :: (Monoid a) => Replacement a -> a
takeReplace :: forall m. Monoid m => Replacement m -> m
takeReplace (Single a
a) = a
a
takeReplace (Dual a
a a
_) = a
a
takeReplace Replacement a
None = a
forall a. Monoid a => a
mempty

-- | Remove all the constants that are in the concatination.
removeConstInConcat :: Replace (SourceInfo ReduceAnn)
removeConstInConcat :: Replace (SourceInfo ReduceAnn)
removeConstInConcat = Replace (SourceInfo ReduceAnn)
forall a. a -> Replacement a
Single Replace (SourceInfo ReduceAnn)
-> (SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> Replace (SourceInfo ReduceAnn)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Expr -> Expr) -> SourceInfo ReduceAnn -> SourceInfo ReduceAnn
forall a. Mutate a => (Expr -> Expr) -> a -> a
mutExpr Expr -> Expr
replace
  where
    replace :: Expr -> Expr
    replace :: Expr -> Expr
replace (Concat NonEmpty Expr
expr) =
      Expr -> (NonEmpty Expr -> Expr) -> Maybe (NonEmpty Expr) -> Expr
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (BitVec -> Expr
Number BitVec
0) NonEmpty Expr -> Expr
Concat (Maybe (NonEmpty Expr) -> Expr)
-> ([Expr] -> Maybe (NonEmpty Expr)) -> [Expr] -> Expr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Expr] -> Maybe (NonEmpty Expr)
forall a. [a] -> Maybe (NonEmpty a)
NonEmpty.nonEmpty ([Expr] -> Expr) -> [Expr] -> Expr
forall a b. (a -> b) -> a -> b
$
        (Expr -> Bool) -> NonEmpty Expr -> [Expr]
forall a. (a -> Bool) -> NonEmpty a -> [a]
NonEmpty.filter Expr -> Bool
notConstant NonEmpty Expr
expr
    replace Expr
e = Expr
e
    notConstant :: Expr -> Bool
notConstant (Number BitVec
_) = Bool
False
    notConstant Expr
_ = Bool
True

cleanUndefined :: [Identifier] -> [ModItem ReduceAnn] -> [ModItem ReduceAnn]
cleanUndefined :: [Identifier] -> [ModItem ReduceAnn] -> [ModItem ReduceAnn]
cleanUndefined [Identifier]
ids [ModItem ReduceAnn]
mis = [Identifier] -> [ModItem ReduceAnn] -> [ModItem ReduceAnn]
forall a. Mutate a => [Identifier] -> a -> a
clean [Identifier]
usedWires [ModItem ReduceAnn]
mis
  where
    usedWires :: [Identifier]
usedWires = [ModItem ReduceAnn]
mis [ModItem ReduceAnn]
-> Getting (Endo [Identifier]) [ModItem ReduceAnn] Identifier
-> [Identifier]
forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. (ModItem ReduceAnn
 -> Const (Endo [Identifier]) (ModItem ReduceAnn))
-> [ModItem ReduceAnn]
-> Const (Endo [Identifier]) [ModItem ReduceAnn]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ((ModItem ReduceAnn
  -> Const (Endo [Identifier]) (ModItem ReduceAnn))
 -> [ModItem ReduceAnn]
 -> Const (Endo [Identifier]) [ModItem ReduceAnn])
-> ((Identifier -> Const (Endo [Identifier]) Identifier)
    -> ModItem ReduceAnn
    -> Const (Endo [Identifier]) (ModItem ReduceAnn))
-> Getting (Endo [Identifier]) [ModItem ReduceAnn] Identifier
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ContAssign -> Const (Endo [Identifier]) ContAssign)
-> ModItem ReduceAnn
-> Const (Endo [Identifier]) (ModItem ReduceAnn)
forall a (f :: * -> *).
Applicative f =>
(ContAssign -> f ContAssign) -> ModItem a -> f (ModItem a)
modContAssign ((ContAssign -> Const (Endo [Identifier]) ContAssign)
 -> ModItem ReduceAnn
 -> Const (Endo [Identifier]) (ModItem ReduceAnn))
-> ((Identifier -> Const (Endo [Identifier]) Identifier)
    -> ContAssign -> Const (Endo [Identifier]) ContAssign)
-> (Identifier -> Const (Endo [Identifier]) Identifier)
-> ModItem ReduceAnn
-> Const (Endo [Identifier]) (ModItem ReduceAnn)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Identifier -> Const (Endo [Identifier]) Identifier)
-> ContAssign -> Const (Endo [Identifier]) ContAssign
Lens' ContAssign Identifier
contAssignNetLVal [Identifier] -> [Identifier] -> [Identifier]
forall a. Semigroup a => a -> a -> a
<> [Identifier]
ids

halveModAssign :: Replace (ModDecl ReduceAnn)
halveModAssign :: Replace (ModDecl ReduceAnn)
halveModAssign ModDecl ReduceAnn
m = ModDecl ReduceAnn
-> Replacement (ModDecl ReduceAnn)
-> Replacement (ModDecl ReduceAnn)
cleanMod ModDecl ReduceAnn
m (Replacement (ModDecl ReduceAnn)
 -> Replacement (ModDecl ReduceAnn))
-> Replacement (ModDecl ReduceAnn)
-> Replacement (ModDecl ReduceAnn)
forall a b. (a -> b) -> a -> b
$ [ModItem ReduceAnn] -> ModDecl ReduceAnn
modify ([ModItem ReduceAnn] -> ModDecl ReduceAnn)
-> Replacement [ModItem ReduceAnn]
-> Replacement (ModDecl ReduceAnn)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [ModItem ReduceAnn] -> Replacement [ModItem ReduceAnn]
assigns (ModDecl ReduceAnn
m ModDecl ReduceAnn
-> Getting
     [ModItem ReduceAnn] (ModDecl ReduceAnn) [ModItem ReduceAnn]
-> [ModItem ReduceAnn]
forall s a. s -> Getting a s a -> a
^. Getting [ModItem ReduceAnn] (ModDecl ReduceAnn) [ModItem ReduceAnn]
forall a (f :: * -> *).
Applicative f =>
([ModItem a] -> f [ModItem a]) -> ModDecl a -> f (ModDecl a)
modItems)
  where
    assigns :: [ModItem ReduceAnn] -> Replacement [ModItem ReduceAnn]
assigns = [ModItem ReduceAnn] -> Replacement [ModItem ReduceAnn]
forall a. Replace [a]
halve ([ModItem ReduceAnn] -> Replacement [ModItem ReduceAnn])
-> ([ModItem ReduceAnn] -> [ModItem ReduceAnn])
-> [ModItem ReduceAnn]
-> Replacement [ModItem ReduceAnn]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ModItem ReduceAnn -> Bool)
-> [ModItem ReduceAnn] -> [ModItem ReduceAnn]
forall a. (a -> Bool) -> [a] -> [a]
filter ([Port] -> ModItem ReduceAnn -> Bool
filterAssigns ([Port] -> ModItem ReduceAnn -> Bool)
-> [Port] -> ModItem ReduceAnn -> Bool
forall a b. (a -> b) -> a -> b
$ ModDecl ReduceAnn
m ModDecl ReduceAnn
-> Getting [Port] (ModDecl ReduceAnn) [Port] -> [Port]
forall s a. s -> Getting a s a -> a
^. Getting [Port] (ModDecl ReduceAnn) [Port]
forall a (f :: * -> *).
Applicative f =>
([Port] -> f [Port]) -> ModDecl a -> f (ModDecl a)
modOutPorts)
    modify :: [ModItem ReduceAnn] -> ModDecl ReduceAnn
modify [ModItem ReduceAnn]
l = ModDecl ReduceAnn
m ModDecl ReduceAnn
-> (ModDecl ReduceAnn -> ModDecl ReduceAnn) -> ModDecl ReduceAnn
forall a b. a -> (a -> b) -> b
& ([ModItem ReduceAnn] -> Identity [ModItem ReduceAnn])
-> ModDecl ReduceAnn -> Identity (ModDecl ReduceAnn)
forall a (f :: * -> *).
Applicative f =>
([ModItem a] -> f [ModItem a]) -> ModDecl a -> f (ModDecl a)
modItems (([ModItem ReduceAnn] -> Identity [ModItem ReduceAnn])
 -> ModDecl ReduceAnn -> Identity (ModDecl ReduceAnn))
-> [ModItem ReduceAnn] -> ModDecl ReduceAnn -> ModDecl ReduceAnn
forall s t a b. ASetter s t a b -> b -> s -> t
.~ [ModItem ReduceAnn]
l

cleanMod :: (ModDecl ReduceAnn) -> Replacement (ModDecl ReduceAnn) -> Replacement (ModDecl ReduceAnn)
cleanMod :: ModDecl ReduceAnn
-> Replacement (ModDecl ReduceAnn)
-> Replacement (ModDecl ReduceAnn)
cleanMod ModDecl ReduceAnn
m Replacement (ModDecl ReduceAnn)
newm = [ModItem ReduceAnn] -> ModDecl ReduceAnn
modify ([ModItem ReduceAnn] -> ModDecl ReduceAnn)
-> (ModDecl ReduceAnn -> [ModItem ReduceAnn])
-> ModDecl ReduceAnn
-> ModDecl ReduceAnn
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ModDecl ReduceAnn -> [ModItem ReduceAnn]
change (ModDecl ReduceAnn -> ModDecl ReduceAnn)
-> Replacement (ModDecl ReduceAnn)
-> Replacement (ModDecl ReduceAnn)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Replacement (ModDecl ReduceAnn)
newm
  where
    mis :: [ModItem ReduceAnn]
mis = ModDecl ReduceAnn
m ModDecl ReduceAnn
-> Getting
     [ModItem ReduceAnn] (ModDecl ReduceAnn) [ModItem ReduceAnn]
-> [ModItem ReduceAnn]
forall s a. s -> Getting a s a -> a
^. Getting [ModItem ReduceAnn] (ModDecl ReduceAnn) [ModItem ReduceAnn]
forall a (f :: * -> *).
Applicative f =>
([ModItem a] -> f [ModItem a]) -> ModDecl a -> f (ModDecl a)
modItems
    modify :: [ModItem ReduceAnn] -> ModDecl ReduceAnn
modify [ModItem ReduceAnn]
l = ModDecl ReduceAnn
m ModDecl ReduceAnn
-> (ModDecl ReduceAnn -> ModDecl ReduceAnn) -> ModDecl ReduceAnn
forall a b. a -> (a -> b) -> b
& ([ModItem ReduceAnn] -> Identity [ModItem ReduceAnn])
-> ModDecl ReduceAnn -> Identity (ModDecl ReduceAnn)
forall a (f :: * -> *).
Applicative f =>
([ModItem a] -> f [ModItem a]) -> ModDecl a -> f (ModDecl a)
modItems (([ModItem ReduceAnn] -> Identity [ModItem ReduceAnn])
 -> ModDecl ReduceAnn -> Identity (ModDecl ReduceAnn))
-> [ModItem ReduceAnn] -> ModDecl ReduceAnn -> ModDecl ReduceAnn
forall s t a b. ASetter s t a b -> b -> s -> t
.~ [ModItem ReduceAnn]
l
    change :: ModDecl ReduceAnn -> [ModItem ReduceAnn]
change ModDecl ReduceAnn
l =
      [Identifier] -> [ModItem ReduceAnn] -> [ModItem ReduceAnn]
cleanUndefined (ModDecl ReduceAnn
m ModDecl ReduceAnn
-> Getting (Endo [Identifier]) (ModDecl ReduceAnn) Identifier
-> [Identifier]
forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. ([Port] -> Const (Endo [Identifier]) [Port])
-> ModDecl ReduceAnn
-> Const (Endo [Identifier]) (ModDecl ReduceAnn)
forall a (f :: * -> *).
Applicative f =>
([Port] -> f [Port]) -> ModDecl a -> f (ModDecl a)
modInPorts (([Port] -> Const (Endo [Identifier]) [Port])
 -> ModDecl ReduceAnn
 -> Const (Endo [Identifier]) (ModDecl ReduceAnn))
-> Getting (Endo [Identifier]) [Port] Identifier
-> Getting (Endo [Identifier]) (ModDecl ReduceAnn) Identifier
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Port -> Const (Endo [Identifier]) Port)
-> [Port] -> Const (Endo [Identifier]) [Port]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ((Port -> Const (Endo [Identifier]) Port)
 -> [Port] -> Const (Endo [Identifier]) [Port])
-> ((Identifier -> Const (Endo [Identifier]) Identifier)
    -> Port -> Const (Endo [Identifier]) Port)
-> Getting (Endo [Identifier]) [Port] Identifier
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Identifier -> Const (Endo [Identifier]) Identifier)
-> Port -> Const (Endo [Identifier]) Port
Lens' Port Identifier
portName)
        ([ModItem ReduceAnn] -> [ModItem ReduceAnn])
-> ([ModItem ReduceAnn] -> [ModItem ReduceAnn])
-> [ModItem ReduceAnn]
-> [ModItem ReduceAnn]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Port -> [ModItem ReduceAnn] -> [ModItem ReduceAnn]
forall ann. Port -> [ModItem ann] -> [ModItem ann]
combineAssigns ([Port] -> Port
forall a. HasCallStack => [a] -> a
head ([Port] -> Port) -> [Port] -> Port
forall a b. (a -> b) -> a -> b
$ ModDecl ReduceAnn
m ModDecl ReduceAnn
-> Getting [Port] (ModDecl ReduceAnn) [Port] -> [Port]
forall s a. s -> Getting a s a -> a
^. Getting [Port] (ModDecl ReduceAnn) [Port]
forall a (f :: * -> *).
Applicative f =>
([Port] -> f [Port]) -> ModDecl a -> f (ModDecl a)
modOutPorts)
        ([ModItem ReduceAnn] -> [ModItem ReduceAnn])
-> ([ModItem ReduceAnn] -> [ModItem ReduceAnn])
-> [ModItem ReduceAnn]
-> [ModItem ReduceAnn]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((ModItem ReduceAnn -> Bool)
-> [ModItem ReduceAnn] -> [ModItem ReduceAnn]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool)
-> (ModItem ReduceAnn -> Bool) -> ModItem ReduceAnn -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Port] -> ModItem ReduceAnn -> Bool
filterAssigns []) [ModItem ReduceAnn]
mis [ModItem ReduceAnn] -> [ModItem ReduceAnn] -> [ModItem ReduceAnn]
forall a. Semigroup a => a -> a -> a
<>)
        ([ModItem ReduceAnn] -> [ModItem ReduceAnn])
-> [ModItem ReduceAnn] -> [ModItem ReduceAnn]
forall a b. (a -> b) -> a -> b
$ ModDecl ReduceAnn
l
          ModDecl ReduceAnn
-> Getting
     [ModItem ReduceAnn] (ModDecl ReduceAnn) [ModItem ReduceAnn]
-> [ModItem ReduceAnn]
forall s a. s -> Getting a s a -> a
^. Getting [ModItem ReduceAnn] (ModDecl ReduceAnn) [ModItem ReduceAnn]
forall a (f :: * -> *).
Applicative f =>
([ModItem a] -> f [ModItem a]) -> ModDecl a -> f (ModDecl a)
modItems

halveIndExpr :: Replace Expr
halveIndExpr :: Replace Expr
halveIndExpr (Concat NonEmpty Expr
l) = NonEmpty Expr -> Expr
Concat (NonEmpty Expr -> Expr)
-> Replacement (NonEmpty Expr) -> Replacement Expr
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Replace (NonEmpty Expr)
forall a. Replace (NonEmpty a)
halveNonEmpty NonEmpty Expr
l
halveIndExpr (BinOp Expr
e1 BinaryOperator
_ Expr
e2) = Expr -> Replace Expr
forall a. a -> a -> Replacement a
Dual Expr
e1 Expr
e2
halveIndExpr (Cond Expr
_ Expr
e1 Expr
e2) = Expr -> Replace Expr
forall a. a -> a -> Replacement a
Dual Expr
e1 Expr
e2
halveIndExpr (UnOp UnaryOperator
_ Expr
e) = Replace Expr
forall a. a -> Replacement a
Single Expr
e
halveIndExpr (Appl Identifier
_ Expr
e) = Replace Expr
forall a. a -> Replacement a
Single Expr
e
halveIndExpr Expr
e = Replace Expr
forall a. a -> Replacement a
Single Expr
e

halveModExpr :: Replace (ModItem ReduceAnn)
halveModExpr :: Replace (ModItem ReduceAnn)
halveModExpr (ModCA ContAssign
ca) = ContAssign -> ModItem ReduceAnn
forall a. ContAssign -> ModItem a
ModCA (ContAssign -> ModItem ReduceAnn)
-> Replacement ContAssign -> Replacement (ModItem ReduceAnn)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Traversal' ContAssign Expr -> Replace Expr -> Replace ContAssign
forall b a. Monoid b => Traversal' a b -> Replace b -> Replace a
combine (Expr -> f Expr) -> ContAssign -> f ContAssign
Lens' ContAssign Expr
Traversal' ContAssign Expr
contAssignExpr Replace Expr
halveIndExpr ContAssign
ca
halveModExpr ModItem ReduceAnn
a = Replace (ModItem ReduceAnn)
forall a. a -> Replacement a
Single ModItem ReduceAnn
a

-- | Split a module declaration in half by trying to remove assign
-- statements. This is only done in the main module of the source.
halveAssigns :: Replace (SourceInfo ReduceAnn)
halveAssigns :: Replace (SourceInfo ReduceAnn)
halveAssigns = Lens' (SourceInfo ReduceAnn) (ModDecl ReduceAnn)
-> Replace (ModDecl ReduceAnn) -> Replace (SourceInfo ReduceAnn)
forall a b. Lens' a b -> Replace b -> Replace a
combineL (ModDecl ReduceAnn -> f (ModDecl ReduceAnn))
-> SourceInfo ReduceAnn -> f (SourceInfo ReduceAnn)
forall a (f :: * -> *).
Functor f =>
(ModDecl a -> f (ModDecl a)) -> SourceInfo a -> f (SourceInfo a)
Lens' (SourceInfo ReduceAnn) (ModDecl ReduceAnn)
mainModule Replace (ModDecl ReduceAnn)
halveModAssign

-- | Checks if a module item is needed in the module declaration.
relevantModItem :: (ModDecl ReduceAnn) -> (ModItem ReduceAnn) -> Bool
relevantModItem :: ModDecl ReduceAnn -> ModItem ReduceAnn -> Bool
relevantModItem (ModDecl Identifier
_ [Port]
out [Port]
_ [ModItem ReduceAnn]
_ [Parameter]
_) (ModCA (ContAssign Identifier
i Expr
_)) =
  Identifier
i Identifier -> [Identifier] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` (Port -> Identifier) -> [Port] -> [Identifier]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Port -> Identifier
_portName [Port]
out
relevantModItem ModDecl ReduceAnn
_ Decl {} = Bool
True
relevantModItem ModDecl ReduceAnn
_ ModItem ReduceAnn
_ = Bool
False

isAssign :: (Statement ReduceAnn) -> Bool
isAssign :: Statement ReduceAnn -> Bool
isAssign (BlockAssign Assign
_) = Bool
True
isAssign (NonBlockAssign Assign
_) = Bool
True
isAssign (ForLoop Assign
_ Expr
_ Assign
_ Statement ReduceAnn
_) = Bool
True
isAssign Statement ReduceAnn
_ = Bool
False

lValName :: LVal -> [Identifier]
lValName :: LVal -> [Identifier]
lValName (RegId Identifier
i) = [Identifier
i]
lValName (RegExpr Identifier
i Expr
_) = [Identifier
i]
lValName (RegSize Identifier
i Range
_) = [Identifier
i]
lValName (RegConcat [Expr]
e) = (Expr -> Maybe Identifier) -> [Expr] -> [Identifier]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe Expr -> Maybe Identifier
getId ([Expr] -> [Identifier])
-> ([[Expr]] -> [Expr]) -> [[Expr]] -> [Identifier]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[Expr]] -> [Expr]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[Expr]] -> [Identifier]) -> [[Expr]] -> [Identifier]
forall a b. (a -> b) -> a -> b
$ Expr -> [Expr]
forall a. Plated a => a -> [a]
universe (Expr -> [Expr]) -> [Expr] -> [[Expr]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Expr]
e
  where
    getId :: Expr -> Maybe Identifier
getId (Id Identifier
i) = Identifier -> Maybe Identifier
forall a. a -> Maybe a
Just Identifier
i
    getId Expr
_ = Maybe Identifier
forall a. Maybe a
Nothing

-- | Pretending that expr is an LVal for the case that it is in a module
-- instantiation.
exprName :: Expr -> [Identifier]
exprName :: Expr -> [Identifier]
exprName (Id Identifier
i) = [Identifier
i]
exprName (VecSelect Identifier
i Expr
_) = [Identifier
i]
exprName (RangeSelect Identifier
i Range
_) = [Identifier
i]
exprName (Concat NonEmpty Expr
i) = [[Identifier]] -> [Identifier]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[Identifier]] -> [Identifier])
-> (NonEmpty [Identifier] -> [[Identifier]])
-> NonEmpty [Identifier]
-> [Identifier]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmpty [Identifier] -> [[Identifier]]
forall a. NonEmpty a -> [a]
NonEmpty.toList (NonEmpty [Identifier] -> [Identifier])
-> NonEmpty [Identifier] -> [Identifier]
forall a b. (a -> b) -> a -> b
$ Expr -> [Identifier]
exprName (Expr -> [Identifier]) -> NonEmpty Expr -> NonEmpty [Identifier]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NonEmpty Expr
i
exprName Expr
_ = []

-- | Returns the only identifiers that are directly tied to an expression. This
-- is useful if one does not have to recurse deeper into the expressions.
exprId :: Expr -> Maybe Identifier
exprId :: Expr -> Maybe Identifier
exprId (Id Identifier
i) = Identifier -> Maybe Identifier
forall a. a -> Maybe a
Just Identifier
i
exprId (VecSelect Identifier
i Expr
_) = Identifier -> Maybe Identifier
forall a. a -> Maybe a
Just Identifier
i
exprId (RangeSelect Identifier
i Range
_) = Identifier -> Maybe Identifier
forall a. a -> Maybe a
Just Identifier
i
exprId Expr
_ = Maybe Identifier
forall a. Maybe a
Nothing

eventId :: Event -> Maybe Identifier
eventId :: Event -> Maybe Identifier
eventId (EId Identifier
i) = Identifier -> Maybe Identifier
forall a. a -> Maybe a
Just Identifier
i
eventId (EPosEdge Identifier
i) = Identifier -> Maybe Identifier
forall a. a -> Maybe a
Just Identifier
i
eventId (ENegEdge Identifier
i) = Identifier -> Maybe Identifier
forall a. a -> Maybe a
Just Identifier
i
eventId Event
_ = Maybe Identifier
forall a. Maybe a
Nothing

portToId :: Port -> Identifier
portToId :: Port -> Identifier
portToId (Port PortType
_ Bool
_ Range
_ Identifier
i) = Identifier
i

paramToId :: Parameter -> Identifier
paramToId :: Parameter -> Identifier
paramToId (Parameter Identifier
i ConstExpr
_) = Identifier
i

isModule :: Identifier -> (ModDecl ReduceAnn) -> Bool
isModule :: Identifier -> ModDecl ReduceAnn -> Bool
isModule Identifier
i (ModDecl Identifier
n [Port]
_ [Port]
_ [ModItem ReduceAnn]
_ [Parameter]
_) = Identifier
i Identifier -> Identifier -> Bool
forall a. Eq a => a -> a -> Bool
== Identifier
n

modInstActive :: [(ModDecl ReduceAnn)] -> (ModItem ReduceAnn) -> [Identifier]
modInstActive :: [ModDecl ReduceAnn] -> ModItem ReduceAnn -> [Identifier]
modInstActive [ModDecl ReduceAnn]
decl (ModInst Identifier
n [ModConn]
_ Identifier
_ [ModConn]
i) = case Maybe (ModDecl ReduceAnn)
m of
  Maybe (ModDecl ReduceAnn)
Nothing -> []
  Just ModDecl ReduceAnn
m' -> [[Identifier]] -> [Identifier]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[Identifier]] -> [Identifier]) -> [[Identifier]] -> [Identifier]
forall a b. (a -> b) -> a -> b
$ ModDecl ReduceAnn -> (ModConn, Int) -> [Identifier]
forall {a}. ModDecl a -> (ModConn, Int) -> [Identifier]
calcActive ModDecl ReduceAnn
m' ((ModConn, Int) -> [Identifier])
-> [(ModConn, Int)] -> [[Identifier]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [ModConn] -> [Int] -> [(ModConn, Int)]
forall a b. [a] -> [b] -> [(a, b)]
zip [ModConn]
i [Int
0 ..]
  where
    m :: Maybe (ModDecl ReduceAnn)
m = ([ModDecl ReduceAnn] -> ModDecl ReduceAnn)
-> [ModDecl ReduceAnn] -> Maybe (ModDecl ReduceAnn)
forall a b. ([a] -> b) -> [a] -> Maybe b
safe [ModDecl ReduceAnn] -> ModDecl ReduceAnn
forall a. HasCallStack => [a] -> a
head ([ModDecl ReduceAnn] -> Maybe (ModDecl ReduceAnn))
-> [ModDecl ReduceAnn] -> Maybe (ModDecl ReduceAnn)
forall a b. (a -> b) -> a -> b
$ (ModDecl ReduceAnn -> Bool)
-> [ModDecl ReduceAnn] -> [ModDecl ReduceAnn]
forall a. (a -> Bool) -> [a] -> [a]
filter (Identifier -> ModDecl ReduceAnn -> Bool
isModule Identifier
n) [ModDecl ReduceAnn]
decl
    calcActive :: ModDecl a -> (ModConn, Int) -> [Identifier]
calcActive (ModDecl Identifier
_ [Port]
o [Port]
_ [ModItem a]
_ [Parameter]
_) (ModConn Expr
e, Int
n')
      | Int
n' Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< [Port] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Port]
o = Expr -> [Identifier]
exprName Expr
e
      | Bool
otherwise = []
    calcActive (ModDecl Identifier
_ [Port]
o [Port]
_ [ModItem a]
_ [Parameter]
_) (ModConnNamed Identifier
i' Expr
e, Int
_)
      | Identifier
i' Identifier -> [Identifier] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` (Port -> Identifier) -> [Port] -> [Identifier]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Port -> Identifier
_portName [Port]
o = Expr -> [Identifier]
exprName Expr
e
      | Bool
otherwise = []
modInstActive [ModDecl ReduceAnn]
_ ModItem ReduceAnn
_ = []

fixModInst :: (SourceInfo ReduceAnn) -> (ModItem ReduceAnn) -> (ModItem ReduceAnn)
fixModInst :: SourceInfo ReduceAnn -> ModItem ReduceAnn -> ModItem ReduceAnn
fixModInst (SourceInfo Text
_ (Verilog [ModDecl ReduceAnn]
decl)) (ModInst Identifier
n [ModConn]
p Identifier
g [ModConn]
i) = case Maybe (ModDecl ReduceAnn)
m of
  Maybe (ModDecl ReduceAnn)
Nothing -> String -> ModItem ReduceAnn
forall a. HasCallStack => String -> a
error String
"Moditem not found"
  Just ModDecl ReduceAnn
m' -> Identifier
-> [ModConn] -> Identifier -> [ModConn] -> ModItem ReduceAnn
forall a.
Identifier -> [ModConn] -> Identifier -> [ModConn] -> ModItem a
ModInst Identifier
n [ModConn]
p Identifier
g ([ModConn] -> ModItem ReduceAnn)
-> ([(ModConn, Int)] -> [ModConn])
-> [(ModConn, Int)]
-> ModItem ReduceAnn
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((ModConn, Int) -> Maybe ModConn) -> [(ModConn, Int)] -> [ModConn]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe (ModDecl ReduceAnn -> (ModConn, Int) -> Maybe ModConn
forall {a}. ModDecl a -> (ModConn, Int) -> Maybe ModConn
fixModInst' ModDecl ReduceAnn
m') ([(ModConn, Int)] -> ModItem ReduceAnn)
-> [(ModConn, Int)] -> ModItem ReduceAnn
forall a b. (a -> b) -> a -> b
$ [ModConn] -> [Int] -> [(ModConn, Int)]
forall a b. [a] -> [b] -> [(a, b)]
zip [ModConn]
i [Int
0 ..]
  where
    m :: Maybe (ModDecl ReduceAnn)
m = ([ModDecl ReduceAnn] -> ModDecl ReduceAnn)
-> [ModDecl ReduceAnn] -> Maybe (ModDecl ReduceAnn)
forall a b. ([a] -> b) -> [a] -> Maybe b
safe [ModDecl ReduceAnn] -> ModDecl ReduceAnn
forall a. HasCallStack => [a] -> a
head ([ModDecl ReduceAnn] -> Maybe (ModDecl ReduceAnn))
-> [ModDecl ReduceAnn] -> Maybe (ModDecl ReduceAnn)
forall a b. (a -> b) -> a -> b
$ (ModDecl ReduceAnn -> Bool)
-> [ModDecl ReduceAnn] -> [ModDecl ReduceAnn]
forall a. (a -> Bool) -> [a] -> [a]
filter (Identifier -> ModDecl ReduceAnn -> Bool
isModule Identifier
n) [ModDecl ReduceAnn]
decl
    fixModInst' :: ModDecl a -> (ModConn, Int) -> Maybe ModConn
fixModInst' (ModDecl Identifier
_ [Port]
o [Port]
i' [ModItem a]
_ [Parameter]
_) (ModConn Expr
e, Int
n')
      | Int
n' Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< [Port] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Port]
o Int -> Int -> Int
forall a. Num a => a -> a -> a
+ [Port] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Port]
i' = ModConn -> Maybe ModConn
forall a. a -> Maybe a
Just (ModConn -> Maybe ModConn) -> ModConn -> Maybe ModConn
forall a b. (a -> b) -> a -> b
$ Expr -> ModConn
ModConn Expr
e
      | Bool
otherwise = Maybe ModConn
forall a. Maybe a
Nothing
    fixModInst' (ModDecl Identifier
_ [Port]
o [Port]
i'' [ModItem a]
_ [Parameter]
_) (ModConnNamed Identifier
i' Expr
e, Int
_)
      | Identifier
i' Identifier -> [Identifier] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` (Port -> Identifier) -> [Port] -> [Identifier]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Port -> Identifier
_portName ([Port]
o [Port] -> [Port] -> [Port]
forall a. Semigroup a => a -> a -> a
<> [Port]
i'') = ModConn -> Maybe ModConn
forall a. a -> Maybe a
Just (ModConn -> Maybe ModConn) -> ModConn -> Maybe ModConn
forall a b. (a -> b) -> a -> b
$ Identifier -> Expr -> ModConn
ModConnNamed Identifier
i' Expr
e
      | Bool
otherwise = Maybe ModConn
forall a. Maybe a
Nothing
fixModInst SourceInfo ReduceAnn
_ ModItem ReduceAnn
a = ModItem ReduceAnn
a

eventIdent :: Event -> [Identifier]
eventIdent :: Event -> [Identifier]
eventIdent (EId Identifier
i) = [Identifier
i]
eventIdent (EExpr Expr
e) =
  case Expr -> Maybe Identifier
exprId Expr
e of
    Maybe Identifier
Nothing -> []
    Just Identifier
eid -> [Identifier
eid]
eventIdent Event
EAll = []
eventIdent (EPosEdge Identifier
i) = [Identifier
i]
eventIdent (ENegEdge Identifier
i) = [Identifier
i]
eventIdent (EOr Event
e1 Event
e2) = Event -> [Identifier]
eventIdent Event
e1 [Identifier] -> [Identifier] -> [Identifier]
forall a. Semigroup a => a -> a -> a
<> Event -> [Identifier]
eventIdent Event
e2
eventIdent (EComb Event
e1 Event
e2) = Event -> [Identifier]
eventIdent Event
e1 [Identifier] -> [Identifier] -> [Identifier]
forall a. Semigroup a => a -> a -> a
<> Event -> [Identifier]
eventIdent Event
e2

findActiveWires :: Identifier -> (SourceInfo ReduceAnn) -> [Identifier]
findActiveWires :: Identifier -> SourceInfo ReduceAnn -> [Identifier]
findActiveWires Identifier
t SourceInfo ReduceAnn
src =
  [Identifier] -> [Identifier]
forall a. Eq a => [a] -> [a]
nub ([Identifier] -> [Identifier]) -> [Identifier] -> [Identifier]
forall a b. (a -> b) -> a -> b
$
    [Identifier]
assignWires
      [Identifier] -> [Identifier] -> [Identifier]
forall a. Semigroup a => a -> a -> a
<> [Identifier]
assignStat
      [Identifier] -> [Identifier] -> [Identifier]
forall a. Semigroup a => a -> a -> a
<> (Port -> Identifier) -> [Port] -> [Identifier]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Port -> Identifier
portToId [Port]
i
      [Identifier] -> [Identifier] -> [Identifier]
forall a. Semigroup a => a -> a -> a
<> (Port -> Identifier) -> [Port] -> [Identifier]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Port -> Identifier
portToId [Port]
o
      [Identifier] -> [Identifier] -> [Identifier]
forall a. Semigroup a => a -> a -> a
<> (Parameter -> Identifier) -> [Parameter] -> [Identifier]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Parameter -> Identifier
paramToId [Parameter]
p
      [Identifier] -> [Identifier] -> [Identifier]
forall a. Semigroup a => a -> a -> a
<> [Identifier]
modinstwires
      [Identifier] -> [Identifier] -> [Identifier]
forall a. Semigroup a => a -> a -> a
<> [Identifier]
events
  where
    assignWires :: [Identifier]
assignWires = ModDecl ReduceAnn
m ModDecl ReduceAnn
-> Getting (Endo [Identifier]) (ModDecl ReduceAnn) Identifier
-> [Identifier]
forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. ([ModItem ReduceAnn]
 -> Const (Endo [Identifier]) [ModItem ReduceAnn])
-> ModDecl ReduceAnn
-> Const (Endo [Identifier]) (ModDecl ReduceAnn)
forall a (f :: * -> *).
Applicative f =>
([ModItem a] -> f [ModItem a]) -> ModDecl a -> f (ModDecl a)
modItems (([ModItem ReduceAnn]
  -> Const (Endo [Identifier]) [ModItem ReduceAnn])
 -> ModDecl ReduceAnn
 -> Const (Endo [Identifier]) (ModDecl ReduceAnn))
-> Getting (Endo [Identifier]) [ModItem ReduceAnn] Identifier
-> Getting (Endo [Identifier]) (ModDecl ReduceAnn) Identifier
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ModItem ReduceAnn
 -> Const (Endo [Identifier]) (ModItem ReduceAnn))
-> [ModItem ReduceAnn]
-> Const (Endo [Identifier]) [ModItem ReduceAnn]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ((ModItem ReduceAnn
  -> Const (Endo [Identifier]) (ModItem ReduceAnn))
 -> [ModItem ReduceAnn]
 -> Const (Endo [Identifier]) [ModItem ReduceAnn])
-> ((Identifier -> Const (Endo [Identifier]) Identifier)
    -> ModItem ReduceAnn
    -> Const (Endo [Identifier]) (ModItem ReduceAnn))
-> Getting (Endo [Identifier]) [ModItem ReduceAnn] Identifier
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ContAssign -> Const (Endo [Identifier]) ContAssign)
-> ModItem ReduceAnn
-> Const (Endo [Identifier]) (ModItem ReduceAnn)
forall a (f :: * -> *).
Applicative f =>
(ContAssign -> f ContAssign) -> ModItem a -> f (ModItem a)
modContAssign ((ContAssign -> Const (Endo [Identifier]) ContAssign)
 -> ModItem ReduceAnn
 -> Const (Endo [Identifier]) (ModItem ReduceAnn))
-> ((Identifier -> Const (Endo [Identifier]) Identifier)
    -> ContAssign -> Const (Endo [Identifier]) ContAssign)
-> (Identifier -> Const (Endo [Identifier]) Identifier)
-> ModItem ReduceAnn
-> Const (Endo [Identifier]) (ModItem ReduceAnn)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Identifier -> Const (Endo [Identifier]) Identifier)
-> ContAssign -> Const (Endo [Identifier]) ContAssign
Lens' ContAssign Identifier
contAssignNetLVal
    assignStat :: [Identifier]
assignStat =
      (LVal -> [Identifier]) -> [LVal] -> [Identifier]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap LVal -> [Identifier]
lValName ([LVal] -> [Identifier]) -> [LVal] -> [Identifier]
forall a b. (a -> b) -> a -> b
$
        ([Statement ReduceAnn]
allStat [Statement ReduceAnn]
-> Getting (Endo [LVal]) [Statement ReduceAnn] LVal -> [LVal]
forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. (Statement ReduceAnn -> Const (Endo [LVal]) (Statement ReduceAnn))
-> [Statement ReduceAnn]
-> Const (Endo [LVal]) [Statement ReduceAnn]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ((Statement ReduceAnn -> Const (Endo [LVal]) (Statement ReduceAnn))
 -> [Statement ReduceAnn]
 -> Const (Endo [LVal]) [Statement ReduceAnn])
-> ((LVal -> Const (Endo [LVal]) LVal)
    -> Statement ReduceAnn
    -> Const (Endo [LVal]) (Statement ReduceAnn))
-> Getting (Endo [LVal]) [Statement ReduceAnn] LVal
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Assign -> Const (Endo [LVal]) Assign)
-> Statement ReduceAnn -> Const (Endo [LVal]) (Statement ReduceAnn)
forall a (f :: * -> *).
Applicative f =>
(Assign -> f Assign) -> Statement a -> f (Statement a)
stmntBA ((Assign -> Const (Endo [LVal]) Assign)
 -> Statement ReduceAnn
 -> Const (Endo [LVal]) (Statement ReduceAnn))
-> ((LVal -> Const (Endo [LVal]) LVal)
    -> Assign -> Const (Endo [LVal]) Assign)
-> (LVal -> Const (Endo [LVal]) LVal)
-> Statement ReduceAnn
-> Const (Endo [LVal]) (Statement ReduceAnn)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (LVal -> Const (Endo [LVal]) LVal)
-> Assign -> Const (Endo [LVal]) Assign
Lens' Assign LVal
assignReg)
          [LVal] -> [LVal] -> [LVal]
forall a. Semigroup a => a -> a -> a
<> ([Statement ReduceAnn]
allStat [Statement ReduceAnn]
-> Getting (Endo [LVal]) [Statement ReduceAnn] LVal -> [LVal]
forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. (Statement ReduceAnn -> Const (Endo [LVal]) (Statement ReduceAnn))
-> [Statement ReduceAnn]
-> Const (Endo [LVal]) [Statement ReduceAnn]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ((Statement ReduceAnn -> Const (Endo [LVal]) (Statement ReduceAnn))
 -> [Statement ReduceAnn]
 -> Const (Endo [LVal]) [Statement ReduceAnn])
-> ((LVal -> Const (Endo [LVal]) LVal)
    -> Statement ReduceAnn
    -> Const (Endo [LVal]) (Statement ReduceAnn))
-> Getting (Endo [LVal]) [Statement ReduceAnn] LVal
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Assign -> Const (Endo [LVal]) Assign)
-> Statement ReduceAnn -> Const (Endo [LVal]) (Statement ReduceAnn)
forall a (f :: * -> *).
Applicative f =>
(Assign -> f Assign) -> Statement a -> f (Statement a)
stmntNBA ((Assign -> Const (Endo [LVal]) Assign)
 -> Statement ReduceAnn
 -> Const (Endo [LVal]) (Statement ReduceAnn))
-> ((LVal -> Const (Endo [LVal]) LVal)
    -> Assign -> Const (Endo [LVal]) Assign)
-> (LVal -> Const (Endo [LVal]) LVal)
-> Statement ReduceAnn
-> Const (Endo [LVal]) (Statement ReduceAnn)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (LVal -> Const (Endo [LVal]) LVal)
-> Assign -> Const (Endo [LVal]) Assign
Lens' Assign LVal
assignReg)
          [LVal] -> [LVal] -> [LVal]
forall a. Semigroup a => a -> a -> a
<> ([Statement ReduceAnn]
allStat [Statement ReduceAnn]
-> Getting (Endo [LVal]) [Statement ReduceAnn] LVal -> [LVal]
forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. (Statement ReduceAnn -> Const (Endo [LVal]) (Statement ReduceAnn))
-> [Statement ReduceAnn]
-> Const (Endo [LVal]) [Statement ReduceAnn]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ((Statement ReduceAnn -> Const (Endo [LVal]) (Statement ReduceAnn))
 -> [Statement ReduceAnn]
 -> Const (Endo [LVal]) [Statement ReduceAnn])
-> ((LVal -> Const (Endo [LVal]) LVal)
    -> Statement ReduceAnn
    -> Const (Endo [LVal]) (Statement ReduceAnn))
-> Getting (Endo [LVal]) [Statement ReduceAnn] LVal
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Assign -> Const (Endo [LVal]) Assign)
-> Statement ReduceAnn -> Const (Endo [LVal]) (Statement ReduceAnn)
forall a (f :: * -> *).
Applicative f =>
(Assign -> f Assign) -> Statement a -> f (Statement a)
forAssign ((Assign -> Const (Endo [LVal]) Assign)
 -> Statement ReduceAnn
 -> Const (Endo [LVal]) (Statement ReduceAnn))
-> ((LVal -> Const (Endo [LVal]) LVal)
    -> Assign -> Const (Endo [LVal]) Assign)
-> (LVal -> Const (Endo [LVal]) LVal)
-> Statement ReduceAnn
-> Const (Endo [LVal]) (Statement ReduceAnn)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (LVal -> Const (Endo [LVal]) LVal)
-> Assign -> Const (Endo [LVal]) Assign
Lens' Assign LVal
assignReg)
          [LVal] -> [LVal] -> [LVal]
forall a. Semigroup a => a -> a -> a
<> ([Statement ReduceAnn]
allStat [Statement ReduceAnn]
-> Getting (Endo [LVal]) [Statement ReduceAnn] LVal -> [LVal]
forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. (Statement ReduceAnn -> Const (Endo [LVal]) (Statement ReduceAnn))
-> [Statement ReduceAnn]
-> Const (Endo [LVal]) [Statement ReduceAnn]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ((Statement ReduceAnn -> Const (Endo [LVal]) (Statement ReduceAnn))
 -> [Statement ReduceAnn]
 -> Const (Endo [LVal]) [Statement ReduceAnn])
-> ((LVal -> Const (Endo [LVal]) LVal)
    -> Statement ReduceAnn
    -> Const (Endo [LVal]) (Statement ReduceAnn))
-> Getting (Endo [LVal]) [Statement ReduceAnn] LVal
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Assign -> Const (Endo [LVal]) Assign)
-> Statement ReduceAnn -> Const (Endo [LVal]) (Statement ReduceAnn)
forall a (f :: * -> *).
Applicative f =>
(Assign -> f Assign) -> Statement a -> f (Statement a)
forIncr ((Assign -> Const (Endo [LVal]) Assign)
 -> Statement ReduceAnn
 -> Const (Endo [LVal]) (Statement ReduceAnn))
-> ((LVal -> Const (Endo [LVal]) LVal)
    -> Assign -> Const (Endo [LVal]) Assign)
-> (LVal -> Const (Endo [LVal]) LVal)
-> Statement ReduceAnn
-> Const (Endo [LVal]) (Statement ReduceAnn)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (LVal -> Const (Endo [LVal]) LVal)
-> Assign -> Const (Endo [LVal]) Assign
Lens' Assign LVal
assignReg)
    events :: [Identifier]
events = (Event -> [Identifier]) -> [Event] -> [Identifier]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Event -> [Identifier]
eventIdent ([Event] -> [Identifier]) -> [Event] -> [Identifier]
forall a b. (a -> b) -> a -> b
$ ([Statement ReduceAnn]
allStat [Statement ReduceAnn]
-> Getting (Endo [Event]) [Statement ReduceAnn] Event -> [Event]
forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. (Statement ReduceAnn -> Const (Endo [Event]) (Statement ReduceAnn))
-> [Statement ReduceAnn]
-> Const (Endo [Event]) [Statement ReduceAnn]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ((Statement ReduceAnn
  -> Const (Endo [Event]) (Statement ReduceAnn))
 -> [Statement ReduceAnn]
 -> Const (Endo [Event]) [Statement ReduceAnn])
-> ((Event -> Const (Endo [Event]) Event)
    -> Statement ReduceAnn
    -> Const (Endo [Event]) (Statement ReduceAnn))
-> Getting (Endo [Event]) [Statement ReduceAnn] Event
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Event -> Const (Endo [Event]) Event)
-> Statement ReduceAnn
-> Const (Endo [Event]) (Statement ReduceAnn)
forall a (f :: * -> *).
Applicative f =>
(Event -> f Event) -> Statement a -> f (Statement a)
statEvent)
    allStat :: [Statement ReduceAnn]
allStat = (Statement ReduceAnn -> Bool)
-> [Statement ReduceAnn] -> [Statement ReduceAnn]
forall a. (a -> Bool) -> [a] -> [a]
filter Statement ReduceAnn -> Bool
isAssign ([Statement ReduceAnn] -> [Statement ReduceAnn])
-> ([[Statement ReduceAnn]] -> [Statement ReduceAnn])
-> [[Statement ReduceAnn]]
-> [Statement ReduceAnn]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[Statement ReduceAnn]] -> [Statement ReduceAnn]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[Statement ReduceAnn]] -> [Statement ReduceAnn])
-> [[Statement ReduceAnn]] -> [Statement ReduceAnn]
forall a b. (a -> b) -> a -> b
$ (Statement ReduceAnn -> [Statement ReduceAnn])
-> [Statement ReduceAnn] -> [[Statement ReduceAnn]]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Statement ReduceAnn -> [Statement ReduceAnn]
forall a. Plated a => a -> [a]
universe [Statement ReduceAnn]
stat
    stat :: [Statement ReduceAnn]
stat =
      (ModDecl ReduceAnn
m ModDecl ReduceAnn
-> Getting
     (Endo [Statement ReduceAnn])
     (ModDecl ReduceAnn)
     (Statement ReduceAnn)
-> [Statement ReduceAnn]
forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. ([ModItem ReduceAnn]
 -> Const (Endo [Statement ReduceAnn]) [ModItem ReduceAnn])
-> ModDecl ReduceAnn
-> Const (Endo [Statement ReduceAnn]) (ModDecl ReduceAnn)
forall a (f :: * -> *).
Applicative f =>
([ModItem a] -> f [ModItem a]) -> ModDecl a -> f (ModDecl a)
modItems (([ModItem ReduceAnn]
  -> Const (Endo [Statement ReduceAnn]) [ModItem ReduceAnn])
 -> ModDecl ReduceAnn
 -> Const (Endo [Statement ReduceAnn]) (ModDecl ReduceAnn))
-> ((Statement ReduceAnn
     -> Const (Endo [Statement ReduceAnn]) (Statement ReduceAnn))
    -> [ModItem ReduceAnn]
    -> Const (Endo [Statement ReduceAnn]) [ModItem ReduceAnn])
-> Getting
     (Endo [Statement ReduceAnn])
     (ModDecl ReduceAnn)
     (Statement ReduceAnn)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ModItem ReduceAnn
 -> Const (Endo [Statement ReduceAnn]) (ModItem ReduceAnn))
-> [ModItem ReduceAnn]
-> Const (Endo [Statement ReduceAnn]) [ModItem ReduceAnn]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ((ModItem ReduceAnn
  -> Const (Endo [Statement ReduceAnn]) (ModItem ReduceAnn))
 -> [ModItem ReduceAnn]
 -> Const (Endo [Statement ReduceAnn]) [ModItem ReduceAnn])
-> ((Statement ReduceAnn
     -> Const (Endo [Statement ReduceAnn]) (Statement ReduceAnn))
    -> ModItem ReduceAnn
    -> Const (Endo [Statement ReduceAnn]) (ModItem ReduceAnn))
-> (Statement ReduceAnn
    -> Const (Endo [Statement ReduceAnn]) (Statement ReduceAnn))
-> [ModItem ReduceAnn]
-> Const (Endo [Statement ReduceAnn]) [ModItem ReduceAnn]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Statement ReduceAnn
 -> Const (Endo [Statement ReduceAnn]) (Statement ReduceAnn))
-> ModItem ReduceAnn
-> Const (Endo [Statement ReduceAnn]) (ModItem ReduceAnn)
forall a (p :: * -> * -> *) (f :: * -> *).
(Choice p, Applicative f) =>
p (Statement a) (f (Statement a)) -> p (ModItem a) (f (ModItem a))
_Initial)
        [Statement ReduceAnn]
-> [Statement ReduceAnn] -> [Statement ReduceAnn]
forall a. Semigroup a => a -> a -> a
<> (ModDecl ReduceAnn
m ModDecl ReduceAnn
-> Getting
     (Endo [Statement ReduceAnn])
     (ModDecl ReduceAnn)
     (Statement ReduceAnn)
-> [Statement ReduceAnn]
forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. ([ModItem ReduceAnn]
 -> Const (Endo [Statement ReduceAnn]) [ModItem ReduceAnn])
-> ModDecl ReduceAnn
-> Const (Endo [Statement ReduceAnn]) (ModDecl ReduceAnn)
forall a (f :: * -> *).
Applicative f =>
([ModItem a] -> f [ModItem a]) -> ModDecl a -> f (ModDecl a)
modItems (([ModItem ReduceAnn]
  -> Const (Endo [Statement ReduceAnn]) [ModItem ReduceAnn])
 -> ModDecl ReduceAnn
 -> Const (Endo [Statement ReduceAnn]) (ModDecl ReduceAnn))
-> ((Statement ReduceAnn
     -> Const (Endo [Statement ReduceAnn]) (Statement ReduceAnn))
    -> [ModItem ReduceAnn]
    -> Const (Endo [Statement ReduceAnn]) [ModItem ReduceAnn])
-> Getting
     (Endo [Statement ReduceAnn])
     (ModDecl ReduceAnn)
     (Statement ReduceAnn)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ModItem ReduceAnn
 -> Const (Endo [Statement ReduceAnn]) (ModItem ReduceAnn))
-> [ModItem ReduceAnn]
-> Const (Endo [Statement ReduceAnn]) [ModItem ReduceAnn]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ((ModItem ReduceAnn
  -> Const (Endo [Statement ReduceAnn]) (ModItem ReduceAnn))
 -> [ModItem ReduceAnn]
 -> Const (Endo [Statement ReduceAnn]) [ModItem ReduceAnn])
-> ((Statement ReduceAnn
     -> Const (Endo [Statement ReduceAnn]) (Statement ReduceAnn))
    -> ModItem ReduceAnn
    -> Const (Endo [Statement ReduceAnn]) (ModItem ReduceAnn))
-> (Statement ReduceAnn
    -> Const (Endo [Statement ReduceAnn]) (Statement ReduceAnn))
-> [ModItem ReduceAnn]
-> Const (Endo [Statement ReduceAnn]) [ModItem ReduceAnn]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Statement ReduceAnn
 -> Const (Endo [Statement ReduceAnn]) (Statement ReduceAnn))
-> ModItem ReduceAnn
-> Const (Endo [Statement ReduceAnn]) (ModItem ReduceAnn)
forall a (p :: * -> * -> *) (f :: * -> *).
(Choice p, Applicative f) =>
p (Statement a) (f (Statement a)) -> p (ModItem a) (f (ModItem a))
_Always)
    modinstwires :: [Identifier]
modinstwires =
      [[Identifier]] -> [Identifier]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[Identifier]] -> [Identifier]) -> [[Identifier]] -> [Identifier]
forall a b. (a -> b) -> a -> b
$ [ModDecl ReduceAnn] -> ModItem ReduceAnn -> [Identifier]
modInstActive (SourceInfo ReduceAnn
src SourceInfo ReduceAnn
-> Getting
     [ModDecl ReduceAnn] (SourceInfo ReduceAnn) [ModDecl ReduceAnn]
-> [ModDecl ReduceAnn]
forall s a. s -> Getting a s a -> a
^. (Verilog ReduceAnn
 -> Const [ModDecl ReduceAnn] (Verilog ReduceAnn))
-> SourceInfo ReduceAnn
-> Const [ModDecl ReduceAnn] (SourceInfo ReduceAnn)
forall a1 a2 (f :: * -> *).
Functor f =>
(Verilog a1 -> f (Verilog a2))
-> SourceInfo a1 -> f (SourceInfo a2)
infoSrc ((Verilog ReduceAnn
  -> Const [ModDecl ReduceAnn] (Verilog ReduceAnn))
 -> SourceInfo ReduceAnn
 -> Const [ModDecl ReduceAnn] (SourceInfo ReduceAnn))
-> (([ModDecl ReduceAnn]
     -> Const [ModDecl ReduceAnn] [ModDecl ReduceAnn])
    -> Verilog ReduceAnn
    -> Const [ModDecl ReduceAnn] (Verilog ReduceAnn))
-> Getting
     [ModDecl ReduceAnn] (SourceInfo ReduceAnn) [ModDecl ReduceAnn]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([ModDecl ReduceAnn]
 -> Const [ModDecl ReduceAnn] [ModDecl ReduceAnn])
-> Verilog ReduceAnn
-> Const [ModDecl ReduceAnn] (Verilog ReduceAnn)
(Unwrapped (Verilog ReduceAnn)
 -> Const [ModDecl ReduceAnn] (Unwrapped (Verilog ReduceAnn)))
-> Verilog ReduceAnn
-> Const [ModDecl ReduceAnn] (Verilog ReduceAnn)
forall s t. Rewrapping s t => Iso s t (Unwrapped s) (Unwrapped t)
Iso
  (Verilog ReduceAnn)
  (Verilog ReduceAnn)
  (Unwrapped (Verilog ReduceAnn))
  (Unwrapped (Verilog ReduceAnn))
_Wrapped) (ModItem ReduceAnn -> [Identifier])
-> [ModItem ReduceAnn] -> [[Identifier]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ModDecl ReduceAnn
m ModDecl ReduceAnn
-> Getting
     [ModItem ReduceAnn] (ModDecl ReduceAnn) [ModItem ReduceAnn]
-> [ModItem ReduceAnn]
forall s a. s -> Getting a s a -> a
^. Getting [ModItem ReduceAnn] (ModDecl ReduceAnn) [ModItem ReduceAnn]
forall a (f :: * -> *).
Applicative f =>
([ModItem a] -> f [ModItem a]) -> ModDecl a -> f (ModDecl a)
modItems
    m :: ModDecl ReduceAnn
m@(ModDecl Identifier
_ [Port]
o [Port]
i [ModItem ReduceAnn]
_ [Parameter]
p) = SourceInfo ReduceAnn
src SourceInfo ReduceAnn
-> Getting
     (ModDecl ReduceAnn) (SourceInfo ReduceAnn) (ModDecl ReduceAnn)
-> ModDecl ReduceAnn
forall s a. s -> Getting a s a -> a
^. Identifier -> Lens' (SourceInfo ReduceAnn) (ModDecl ReduceAnn)
forall a. Identifier -> Lens' (SourceInfo a) (ModDecl a)
aModule Identifier
t

-- | Clean a specific module. Have to be carful that the module is in the
-- '(SourceInfo ReduceAnn)', otherwise it will crash.
cleanSourceInfo :: Identifier -> (SourceInfo ReduceAnn) -> (SourceInfo ReduceAnn)
cleanSourceInfo :: Identifier -> SourceInfo ReduceAnn -> SourceInfo ReduceAnn
cleanSourceInfo Identifier
t SourceInfo ReduceAnn
src = SourceInfo ReduceAnn
src SourceInfo ReduceAnn
-> (SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> SourceInfo ReduceAnn
forall a b. a -> (a -> b) -> b
& Identifier -> Lens' (SourceInfo ReduceAnn) (ModDecl ReduceAnn)
forall a. Identifier -> Lens' (SourceInfo a) (ModDecl a)
aModule Identifier
t ((ModDecl ReduceAnn -> Identity (ModDecl ReduceAnn))
 -> SourceInfo ReduceAnn -> Identity (SourceInfo ReduceAnn))
-> (ModDecl ReduceAnn -> ModDecl ReduceAnn)
-> SourceInfo ReduceAnn
-> SourceInfo ReduceAnn
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ [Identifier] -> ModDecl ReduceAnn -> ModDecl ReduceAnn
forall a. Mutate a => [Identifier] -> a -> a
clean (Identifier -> SourceInfo ReduceAnn -> [Identifier]
findActiveWires Identifier
t SourceInfo ReduceAnn
src)

cleanSourceInfoAll :: (SourceInfo ReduceAnn) -> (SourceInfo ReduceAnn)
cleanSourceInfoAll :: SourceInfo ReduceAnn -> SourceInfo ReduceAnn
cleanSourceInfoAll SourceInfo ReduceAnn
src = (Identifier -> SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> SourceInfo ReduceAnn -> [Identifier] -> SourceInfo ReduceAnn
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Identifier -> SourceInfo ReduceAnn -> SourceInfo ReduceAnn
cleanSourceInfo SourceInfo ReduceAnn
src [Identifier]
allMods
  where
    allMods :: [Identifier]
allMods = SourceInfo ReduceAnn
src SourceInfo ReduceAnn
-> Getting (Endo [Identifier]) (SourceInfo ReduceAnn) Identifier
-> [Identifier]
forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. (Verilog ReduceAnn
 -> Const (Endo [Identifier]) (Verilog ReduceAnn))
-> SourceInfo ReduceAnn
-> Const (Endo [Identifier]) (SourceInfo ReduceAnn)
forall a1 a2 (f :: * -> *).
Functor f =>
(Verilog a1 -> f (Verilog a2))
-> SourceInfo a1 -> f (SourceInfo a2)
infoSrc ((Verilog ReduceAnn
  -> Const (Endo [Identifier]) (Verilog ReduceAnn))
 -> SourceInfo ReduceAnn
 -> Const (Endo [Identifier]) (SourceInfo ReduceAnn))
-> ((Identifier -> Const (Endo [Identifier]) Identifier)
    -> Verilog ReduceAnn
    -> Const (Endo [Identifier]) (Verilog ReduceAnn))
-> Getting (Endo [Identifier]) (SourceInfo ReduceAnn) Identifier
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([ModDecl ReduceAnn]
 -> Const (Endo [Identifier]) [ModDecl ReduceAnn])
-> Verilog ReduceAnn
-> Const (Endo [Identifier]) (Verilog ReduceAnn)
(Unwrapped (Verilog ReduceAnn)
 -> Const (Endo [Identifier]) (Unwrapped (Verilog ReduceAnn)))
-> Verilog ReduceAnn
-> Const (Endo [Identifier]) (Verilog ReduceAnn)
forall s t. Rewrapping s t => Iso s t (Unwrapped s) (Unwrapped t)
Iso
  (Verilog ReduceAnn)
  (Verilog ReduceAnn)
  (Unwrapped (Verilog ReduceAnn))
  (Unwrapped (Verilog ReduceAnn))
_Wrapped (([ModDecl ReduceAnn]
  -> Const (Endo [Identifier]) [ModDecl ReduceAnn])
 -> Verilog ReduceAnn
 -> Const (Endo [Identifier]) (Verilog ReduceAnn))
-> ((Identifier -> Const (Endo [Identifier]) Identifier)
    -> [ModDecl ReduceAnn]
    -> Const (Endo [Identifier]) [ModDecl ReduceAnn])
-> (Identifier -> Const (Endo [Identifier]) Identifier)
-> Verilog ReduceAnn
-> Const (Endo [Identifier]) (Verilog ReduceAnn)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ModDecl ReduceAnn
 -> Const (Endo [Identifier]) (ModDecl ReduceAnn))
-> [ModDecl ReduceAnn]
-> Const (Endo [Identifier]) [ModDecl ReduceAnn]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ((ModDecl ReduceAnn
  -> Const (Endo [Identifier]) (ModDecl ReduceAnn))
 -> [ModDecl ReduceAnn]
 -> Const (Endo [Identifier]) [ModDecl ReduceAnn])
-> Getting (Endo [Identifier]) (ModDecl ReduceAnn) Identifier
-> (Identifier -> Const (Endo [Identifier]) Identifier)
-> [ModDecl ReduceAnn]
-> Const (Endo [Identifier]) [ModDecl ReduceAnn]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Getting (Endo [Identifier]) (ModDecl ReduceAnn) Identifier
forall a (f :: * -> *).
Applicative f =>
(Identifier -> f Identifier) -> ModDecl a -> f (ModDecl a)
modId

-- | Returns true if the text matches the name of a module.
matchesModName :: Identifier -> (ModDecl ReduceAnn) -> Bool
matchesModName :: Identifier -> ModDecl ReduceAnn -> Bool
matchesModName Identifier
top (ModDecl Identifier
i [Port]
_ [Port]
_ [ModItem ReduceAnn]
_ [Parameter]
_) = Identifier
top Identifier -> Identifier -> Bool
forall a. Eq a => a -> a -> Bool
== Identifier
i

halveStatement :: Replace (Statement ReduceAnn)
halveStatement :: Replace (Statement ReduceAnn)
halveStatement (SeqBlock [Statement ReduceAnn
s]) = Replace (Statement ReduceAnn)
halveStatement Statement ReduceAnn
s
halveStatement (SeqBlock [Statement ReduceAnn]
s) = [Statement ReduceAnn] -> Statement ReduceAnn
forall a. [Statement a] -> Statement a
SeqBlock ([Statement ReduceAnn] -> Statement ReduceAnn)
-> Replacement [Statement ReduceAnn]
-> Replacement (Statement ReduceAnn)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Replace [Statement ReduceAnn]
forall a. Replace [a]
halve [Statement ReduceAnn]
s
halveStatement (CondStmnt Expr
_ (Just Statement ReduceAnn
s1) (Just Statement ReduceAnn
s2)) = Statement ReduceAnn -> Replace (Statement ReduceAnn)
forall a. a -> a -> Replacement a
Dual Statement ReduceAnn
s1 Statement ReduceAnn
s2
halveStatement (CondStmnt Expr
_ (Just Statement ReduceAnn
s1) Maybe (Statement ReduceAnn)
Nothing) = Replace (Statement ReduceAnn)
forall a. a -> Replacement a
Single Statement ReduceAnn
s1
halveStatement (CondStmnt Expr
_ Maybe (Statement ReduceAnn)
Nothing (Just Statement ReduceAnn
s1)) = Replace (Statement ReduceAnn)
forall a. a -> Replacement a
Single Statement ReduceAnn
s1
halveStatement (EventCtrl Event
e (Just Statement ReduceAnn
s)) = Event -> Maybe (Statement ReduceAnn) -> Statement ReduceAnn
forall a. Event -> Maybe (Statement a) -> Statement a
EventCtrl Event
e (Maybe (Statement ReduceAnn) -> Statement ReduceAnn)
-> (Statement ReduceAnn -> Maybe (Statement ReduceAnn))
-> Statement ReduceAnn
-> Statement ReduceAnn
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Statement ReduceAnn -> Maybe (Statement ReduceAnn)
forall a. a -> Maybe a
Just (Statement ReduceAnn -> Statement ReduceAnn)
-> Replacement (Statement ReduceAnn)
-> Replacement (Statement ReduceAnn)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Replace (Statement ReduceAnn)
halveStatement Statement ReduceAnn
s
halveStatement (TimeCtrl Delay
e (Just Statement ReduceAnn
s)) = Delay -> Maybe (Statement ReduceAnn) -> Statement ReduceAnn
forall a. Delay -> Maybe (Statement a) -> Statement a
TimeCtrl Delay
e (Maybe (Statement ReduceAnn) -> Statement ReduceAnn)
-> (Statement ReduceAnn -> Maybe (Statement ReduceAnn))
-> Statement ReduceAnn
-> Statement ReduceAnn
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Statement ReduceAnn -> Maybe (Statement ReduceAnn)
forall a. a -> Maybe a
Just (Statement ReduceAnn -> Statement ReduceAnn)
-> Replacement (Statement ReduceAnn)
-> Replacement (Statement ReduceAnn)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Replace (Statement ReduceAnn)
halveStatement Statement ReduceAnn
s
halveStatement Statement ReduceAnn
a = Replace (Statement ReduceAnn)
forall a. a -> Replacement a
Single Statement ReduceAnn
a

halveAlways :: Replace (ModItem ReduceAnn)
halveAlways :: Replace (ModItem ReduceAnn)
halveAlways (ModItemAnn ReduceAnn
Active (Always Statement ReduceAnn
s)) = ReduceAnn -> ModItem ReduceAnn -> ModItem ReduceAnn
forall a. a -> ModItem a -> ModItem a
ModItemAnn ReduceAnn
Active (ModItem ReduceAnn -> ModItem ReduceAnn)
-> (Statement ReduceAnn -> ModItem ReduceAnn)
-> Statement ReduceAnn
-> ModItem ReduceAnn
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Statement ReduceAnn -> ModItem ReduceAnn
forall a. Statement a -> ModItem a
Always (Statement ReduceAnn -> ModItem ReduceAnn)
-> Replacement (Statement ReduceAnn)
-> Replacement (ModItem ReduceAnn)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Replace (Statement ReduceAnn)
halveStatement Statement ReduceAnn
s
halveAlways r :: ModItem ReduceAnn
r@(ModItemAnn ReduceAnn
Reduced (Always Statement ReduceAnn
s)) = Replace (ModItem ReduceAnn)
forall a. a -> Replacement a
Single ModItem ReduceAnn
r
halveAlways ModItem ReduceAnn
a = Replace (ModItem ReduceAnn)
forall a. a -> Replacement a
Single ModItem ReduceAnn
a

-- | Check if a mod instance is in the current context.
validModInst :: [Identifier] -> (ModItem ReduceAnn) -> Bool
validModInst :: [Identifier] -> ModItem ReduceAnn -> Bool
validModInst [Identifier]
ids (ModInst Identifier
i [ModConn]
_ Identifier
_ [ModConn]
_) = Identifier
i Identifier -> [Identifier] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Identifier]
ids
validModInst [Identifier]
_ ModItem ReduceAnn
_ = Bool
True

-- | Clean all the undefined module instances in a specific module using a
-- context.
cleanModInst' :: [Identifier] -> (ModDecl ReduceAnn) -> (ModDecl ReduceAnn)
cleanModInst' :: [Identifier] -> ModDecl ReduceAnn -> ModDecl ReduceAnn
cleanModInst' [Identifier]
ids ModDecl ReduceAnn
m = ModDecl ReduceAnn
m ModDecl ReduceAnn
-> (ModDecl ReduceAnn -> ModDecl ReduceAnn) -> ModDecl ReduceAnn
forall a b. a -> (a -> b) -> b
& ([ModItem ReduceAnn] -> Identity [ModItem ReduceAnn])
-> ModDecl ReduceAnn -> Identity (ModDecl ReduceAnn)
forall a (f :: * -> *).
Applicative f =>
([ModItem a] -> f [ModItem a]) -> ModDecl a -> f (ModDecl a)
modItems (([ModItem ReduceAnn] -> Identity [ModItem ReduceAnn])
 -> ModDecl ReduceAnn -> Identity (ModDecl ReduceAnn))
-> [ModItem ReduceAnn] -> ModDecl ReduceAnn -> ModDecl ReduceAnn
forall s t a b. ASetter s t a b -> b -> s -> t
.~ [ModItem ReduceAnn]
newModItem
  where
    newModItem :: [ModItem ReduceAnn]
newModItem = (ModItem ReduceAnn -> Bool)
-> [ModItem ReduceAnn] -> [ModItem ReduceAnn]
forall a. (a -> Bool) -> [a] -> [a]
filter ([Identifier] -> ModItem ReduceAnn -> Bool
validModInst [Identifier]
ids) ([ModItem ReduceAnn] -> [ModItem ReduceAnn])
-> [ModItem ReduceAnn] -> [ModItem ReduceAnn]
forall a b. (a -> b) -> a -> b
$ ModDecl ReduceAnn
m ModDecl ReduceAnn
-> Getting
     (Endo [ModItem ReduceAnn]) (ModDecl ReduceAnn) (ModItem ReduceAnn)
-> [ModItem ReduceAnn]
forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. ([ModItem ReduceAnn]
 -> Const (Endo [ModItem ReduceAnn]) [ModItem ReduceAnn])
-> ModDecl ReduceAnn
-> Const (Endo [ModItem ReduceAnn]) (ModDecl ReduceAnn)
forall a (f :: * -> *).
Applicative f =>
([ModItem a] -> f [ModItem a]) -> ModDecl a -> f (ModDecl a)
modItems (([ModItem ReduceAnn]
  -> Const (Endo [ModItem ReduceAnn]) [ModItem ReduceAnn])
 -> ModDecl ReduceAnn
 -> Const (Endo [ModItem ReduceAnn]) (ModDecl ReduceAnn))
-> ((ModItem ReduceAnn
     -> Const (Endo [ModItem ReduceAnn]) (ModItem ReduceAnn))
    -> [ModItem ReduceAnn]
    -> Const (Endo [ModItem ReduceAnn]) [ModItem ReduceAnn])
-> Getting
     (Endo [ModItem ReduceAnn]) (ModDecl ReduceAnn) (ModItem ReduceAnn)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ModItem ReduceAnn
 -> Const (Endo [ModItem ReduceAnn]) (ModItem ReduceAnn))
-> [ModItem ReduceAnn]
-> Const (Endo [ModItem ReduceAnn]) [ModItem ReduceAnn]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse

-- | Remove all the undefined mod instances.
cleanModInst :: (SourceInfo ReduceAnn) -> (SourceInfo ReduceAnn)
cleanModInst :: SourceInfo ReduceAnn -> SourceInfo ReduceAnn
cleanModInst SourceInfo ReduceAnn
srcInfo = SourceInfo ReduceAnn
srcInfo SourceInfo ReduceAnn
-> (SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> SourceInfo ReduceAnn
forall a b. a -> (a -> b) -> b
& (Verilog ReduceAnn -> Identity (Verilog ReduceAnn))
-> SourceInfo ReduceAnn -> Identity (SourceInfo ReduceAnn)
forall a1 a2 (f :: * -> *).
Functor f =>
(Verilog a1 -> f (Verilog a2))
-> SourceInfo a1 -> f (SourceInfo a2)
infoSrc ((Verilog ReduceAnn -> Identity (Verilog ReduceAnn))
 -> SourceInfo ReduceAnn -> Identity (SourceInfo ReduceAnn))
-> ((Unwrapped (Verilog ReduceAnn) -> Identity [ModDecl ReduceAnn])
    -> Verilog ReduceAnn -> Identity (Verilog ReduceAnn))
-> (Unwrapped (Verilog ReduceAnn) -> Identity [ModDecl ReduceAnn])
-> SourceInfo ReduceAnn
-> Identity (SourceInfo ReduceAnn)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Unwrapped (Verilog ReduceAnn) -> Identity [ModDecl ReduceAnn])
-> Verilog ReduceAnn -> Identity (Verilog ReduceAnn)
(Unwrapped (Verilog ReduceAnn)
 -> Identity (Unwrapped (Verilog ReduceAnn)))
-> Verilog ReduceAnn -> Identity (Verilog ReduceAnn)
forall s t. Rewrapping s t => Iso s t (Unwrapped s) (Unwrapped t)
Iso
  (Verilog ReduceAnn)
  (Verilog ReduceAnn)
  (Unwrapped (Verilog ReduceAnn))
  (Unwrapped (Verilog ReduceAnn))
_Wrapped ((Unwrapped (Verilog ReduceAnn) -> Identity [ModDecl ReduceAnn])
 -> SourceInfo ReduceAnn -> Identity (SourceInfo ReduceAnn))
-> [ModDecl ReduceAnn]
-> SourceInfo ReduceAnn
-> SourceInfo ReduceAnn
forall s t a b. ASetter s t a b -> b -> s -> t
.~ [ModDecl ReduceAnn]
cleaned
  where
    validInst :: [Identifier]
validInst = SourceInfo ReduceAnn
srcInfo SourceInfo ReduceAnn
-> Getting (Endo [Identifier]) (SourceInfo ReduceAnn) Identifier
-> [Identifier]
forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. (Verilog ReduceAnn
 -> Const (Endo [Identifier]) (Verilog ReduceAnn))
-> SourceInfo ReduceAnn
-> Const (Endo [Identifier]) (SourceInfo ReduceAnn)
forall a1 a2 (f :: * -> *).
Functor f =>
(Verilog a1 -> f (Verilog a2))
-> SourceInfo a1 -> f (SourceInfo a2)
infoSrc ((Verilog ReduceAnn
  -> Const (Endo [Identifier]) (Verilog ReduceAnn))
 -> SourceInfo ReduceAnn
 -> Const (Endo [Identifier]) (SourceInfo ReduceAnn))
-> ((Identifier -> Const (Endo [Identifier]) Identifier)
    -> Verilog ReduceAnn
    -> Const (Endo [Identifier]) (Verilog ReduceAnn))
-> Getting (Endo [Identifier]) (SourceInfo ReduceAnn) Identifier
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([ModDecl ReduceAnn]
 -> Const (Endo [Identifier]) [ModDecl ReduceAnn])
-> Verilog ReduceAnn
-> Const (Endo [Identifier]) (Verilog ReduceAnn)
(Unwrapped (Verilog ReduceAnn)
 -> Const (Endo [Identifier]) (Unwrapped (Verilog ReduceAnn)))
-> Verilog ReduceAnn
-> Const (Endo [Identifier]) (Verilog ReduceAnn)
forall s t. Rewrapping s t => Iso s t (Unwrapped s) (Unwrapped t)
Iso
  (Verilog ReduceAnn)
  (Verilog ReduceAnn)
  (Unwrapped (Verilog ReduceAnn))
  (Unwrapped (Verilog ReduceAnn))
_Wrapped (([ModDecl ReduceAnn]
  -> Const (Endo [Identifier]) [ModDecl ReduceAnn])
 -> Verilog ReduceAnn
 -> Const (Endo [Identifier]) (Verilog ReduceAnn))
-> ((Identifier -> Const (Endo [Identifier]) Identifier)
    -> [ModDecl ReduceAnn]
    -> Const (Endo [Identifier]) [ModDecl ReduceAnn])
-> (Identifier -> Const (Endo [Identifier]) Identifier)
-> Verilog ReduceAnn
-> Const (Endo [Identifier]) (Verilog ReduceAnn)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ModDecl ReduceAnn
 -> Const (Endo [Identifier]) (ModDecl ReduceAnn))
-> [ModDecl ReduceAnn]
-> Const (Endo [Identifier]) [ModDecl ReduceAnn]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ((ModDecl ReduceAnn
  -> Const (Endo [Identifier]) (ModDecl ReduceAnn))
 -> [ModDecl ReduceAnn]
 -> Const (Endo [Identifier]) [ModDecl ReduceAnn])
-> Getting (Endo [Identifier]) (ModDecl ReduceAnn) Identifier
-> (Identifier -> Const (Endo [Identifier]) Identifier)
-> [ModDecl ReduceAnn]
-> Const (Endo [Identifier]) [ModDecl ReduceAnn]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Getting (Endo [Identifier]) (ModDecl ReduceAnn) Identifier
forall a (f :: * -> *).
Applicative f =>
(Identifier -> f Identifier) -> ModDecl a -> f (ModDecl a)
modId
    cleaned :: [ModDecl ReduceAnn]
cleaned = [Identifier] -> ModDecl ReduceAnn -> ModDecl ReduceAnn
cleanModInst' [Identifier]
validInst (ModDecl ReduceAnn -> ModDecl ReduceAnn)
-> [ModDecl ReduceAnn] -> [ModDecl ReduceAnn]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> SourceInfo ReduceAnn
srcInfo SourceInfo ReduceAnn
-> Getting
     [ModDecl ReduceAnn] (SourceInfo ReduceAnn) [ModDecl ReduceAnn]
-> [ModDecl ReduceAnn]
forall s a. s -> Getting a s a -> a
^. (Verilog ReduceAnn
 -> Const [ModDecl ReduceAnn] (Verilog ReduceAnn))
-> SourceInfo ReduceAnn
-> Const [ModDecl ReduceAnn] (SourceInfo ReduceAnn)
forall a1 a2 (f :: * -> *).
Functor f =>
(Verilog a1 -> f (Verilog a2))
-> SourceInfo a1 -> f (SourceInfo a2)
infoSrc ((Verilog ReduceAnn
  -> Const [ModDecl ReduceAnn] (Verilog ReduceAnn))
 -> SourceInfo ReduceAnn
 -> Const [ModDecl ReduceAnn] (SourceInfo ReduceAnn))
-> (([ModDecl ReduceAnn]
     -> Const [ModDecl ReduceAnn] [ModDecl ReduceAnn])
    -> Verilog ReduceAnn
    -> Const [ModDecl ReduceAnn] (Verilog ReduceAnn))
-> Getting
     [ModDecl ReduceAnn] (SourceInfo ReduceAnn) [ModDecl ReduceAnn]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([ModDecl ReduceAnn]
 -> Const [ModDecl ReduceAnn] [ModDecl ReduceAnn])
-> Verilog ReduceAnn
-> Const [ModDecl ReduceAnn] (Verilog ReduceAnn)
(Unwrapped (Verilog ReduceAnn)
 -> Const [ModDecl ReduceAnn] (Unwrapped (Verilog ReduceAnn)))
-> Verilog ReduceAnn
-> Const [ModDecl ReduceAnn] (Verilog ReduceAnn)
forall s t. Rewrapping s t => Iso s t (Unwrapped s) (Unwrapped t)
Iso
  (Verilog ReduceAnn)
  (Verilog ReduceAnn)
  (Unwrapped (Verilog ReduceAnn))
  (Unwrapped (Verilog ReduceAnn))
_Wrapped

-- | Adds a '(ModDecl ReduceAnn)' to a '(SourceInfo ReduceAnn)'.
addMod :: (ModDecl ReduceAnn) -> (SourceInfo ReduceAnn) -> (SourceInfo ReduceAnn)
addMod :: ModDecl ReduceAnn -> SourceInfo ReduceAnn -> SourceInfo ReduceAnn
addMod ModDecl ReduceAnn
m SourceInfo ReduceAnn
srcInfo = SourceInfo ReduceAnn
srcInfo SourceInfo ReduceAnn
-> (SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> SourceInfo ReduceAnn
forall a b. a -> (a -> b) -> b
& (Verilog ReduceAnn -> Identity (Verilog ReduceAnn))
-> SourceInfo ReduceAnn -> Identity (SourceInfo ReduceAnn)
forall a1 a2 (f :: * -> *).
Functor f =>
(Verilog a1 -> f (Verilog a2))
-> SourceInfo a1 -> f (SourceInfo a2)
infoSrc ((Verilog ReduceAnn -> Identity (Verilog ReduceAnn))
 -> SourceInfo ReduceAnn -> Identity (SourceInfo ReduceAnn))
-> (([ModDecl ReduceAnn] -> Identity [ModDecl ReduceAnn])
    -> Verilog ReduceAnn -> Identity (Verilog ReduceAnn))
-> ([ModDecl ReduceAnn] -> Identity [ModDecl ReduceAnn])
-> SourceInfo ReduceAnn
-> Identity (SourceInfo ReduceAnn)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([ModDecl ReduceAnn] -> Identity [ModDecl ReduceAnn])
-> Verilog ReduceAnn -> Identity (Verilog ReduceAnn)
(Unwrapped (Verilog ReduceAnn)
 -> Identity (Unwrapped (Verilog ReduceAnn)))
-> Verilog ReduceAnn -> Identity (Verilog ReduceAnn)
forall s t. Rewrapping s t => Iso s t (Unwrapped s) (Unwrapped t)
Iso
  (Verilog ReduceAnn)
  (Verilog ReduceAnn)
  (Unwrapped (Verilog ReduceAnn))
  (Unwrapped (Verilog ReduceAnn))
_Wrapped (([ModDecl ReduceAnn] -> Identity [ModDecl ReduceAnn])
 -> SourceInfo ReduceAnn -> Identity (SourceInfo ReduceAnn))
-> ([ModDecl ReduceAnn] -> [ModDecl ReduceAnn])
-> SourceInfo ReduceAnn
-> SourceInfo ReduceAnn
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ (ModDecl ReduceAnn
m ModDecl ReduceAnn -> [ModDecl ReduceAnn] -> [ModDecl ReduceAnn]
forall a. a -> [a] -> [a]
:)

-- | Removes half the modules randomly, until it reaches a minimal amount of
-- modules. This is done by doing a binary search on the list of modules and
-- removing the instantiations from the main module body.
halveModules :: Replace (SourceInfo ReduceAnn)
halveModules :: Replace (SourceInfo ReduceAnn)
halveModules srcInfo :: SourceInfo ReduceAnn
srcInfo@(SourceInfo Text
top Verilog ReduceAnn
_) =
  SourceInfo ReduceAnn -> SourceInfo ReduceAnn
cleanSourceInfoAll
    (SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> (SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> SourceInfo ReduceAnn
-> SourceInfo ReduceAnn
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SourceInfo ReduceAnn -> SourceInfo ReduceAnn
cleanModInst
    (SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> (SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> SourceInfo ReduceAnn
-> SourceInfo ReduceAnn
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ModDecl ReduceAnn -> SourceInfo ReduceAnn -> SourceInfo ReduceAnn
addMod ModDecl ReduceAnn
main
    (SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> Replacement (SourceInfo ReduceAnn)
-> Replacement (SourceInfo ReduceAnn)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Traversal' (SourceInfo ReduceAnn) [ModDecl ReduceAnn]
-> Replace [ModDecl ReduceAnn] -> Replace (SourceInfo ReduceAnn)
forall b a. Monoid b => Traversal' a b -> Replace b -> Replace a
combine ((Verilog ReduceAnn -> f (Verilog ReduceAnn))
-> SourceInfo ReduceAnn -> f (SourceInfo ReduceAnn)
forall a1 a2 (f :: * -> *).
Functor f =>
(Verilog a1 -> f (Verilog a2))
-> SourceInfo a1 -> f (SourceInfo a2)
infoSrc ((Verilog ReduceAnn -> f (Verilog ReduceAnn))
 -> SourceInfo ReduceAnn -> f (SourceInfo ReduceAnn))
-> (([ModDecl ReduceAnn] -> f [ModDecl ReduceAnn])
    -> Verilog ReduceAnn -> f (Verilog ReduceAnn))
-> ([ModDecl ReduceAnn] -> f [ModDecl ReduceAnn])
-> SourceInfo ReduceAnn
-> f (SourceInfo ReduceAnn)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([ModDecl ReduceAnn] -> f [ModDecl ReduceAnn])
-> Verilog ReduceAnn -> f (Verilog ReduceAnn)
(Unwrapped (Verilog ReduceAnn)
 -> f (Unwrapped (Verilog ReduceAnn)))
-> Verilog ReduceAnn -> f (Verilog ReduceAnn)
forall s t. Rewrapping s t => Iso s t (Unwrapped s) (Unwrapped t)
Iso
  (Verilog ReduceAnn)
  (Verilog ReduceAnn)
  (Unwrapped (Verilog ReduceAnn))
  (Unwrapped (Verilog ReduceAnn))
_Wrapped) Replace [ModDecl ReduceAnn]
repl SourceInfo ReduceAnn
srcInfo
  where
    repl :: Replace [ModDecl ReduceAnn]
repl = Replace [ModDecl ReduceAnn]
forall a. Replace [a]
halve Replace [ModDecl ReduceAnn]
-> ([ModDecl ReduceAnn] -> [ModDecl ReduceAnn])
-> Replace [ModDecl ReduceAnn]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ModDecl ReduceAnn -> Bool)
-> [ModDecl ReduceAnn] -> [ModDecl ReduceAnn]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool)
-> (ModDecl ReduceAnn -> Bool) -> ModDecl ReduceAnn -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Identifier -> ModDecl ReduceAnn -> Bool
matchesModName (Text -> Identifier
Identifier Text
top))
    main :: ModDecl ReduceAnn
main = SourceInfo ReduceAnn
srcInfo SourceInfo ReduceAnn
-> Getting
     (ModDecl ReduceAnn) (SourceInfo ReduceAnn) (ModDecl ReduceAnn)
-> ModDecl ReduceAnn
forall s a. s -> Getting a s a -> a
^. Getting
  (ModDecl ReduceAnn) (SourceInfo ReduceAnn) (ModDecl ReduceAnn)
forall a (f :: * -> *).
Functor f =>
(ModDecl a -> f (ModDecl a)) -> SourceInfo a -> f (SourceInfo a)
mainModule

moduleBot :: (SourceInfo ReduceAnn) -> Bool
moduleBot :: SourceInfo ReduceAnn -> Bool
moduleBot (SourceInfo Text
_ (Verilog [])) = Bool
True
moduleBot (SourceInfo Text
_ (Verilog [ModDecl ReduceAnn
_])) = Bool
True
moduleBot (SourceInfo Text
_ (Verilog [ModDecl ReduceAnn]
_)) = Bool
False

-- | Reducer for module items. It does a binary search on all the module items,
-- except assignments to outputs and input-output declarations.
halveModItems :: Identifier -> Replace (SourceInfo ReduceAnn)
halveModItems :: Identifier -> Replace (SourceInfo ReduceAnn)
halveModItems Identifier
t SourceInfo ReduceAnn
srcInfo = Identifier -> SourceInfo ReduceAnn -> SourceInfo ReduceAnn
cleanSourceInfo Identifier
t (SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> (SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> SourceInfo ReduceAnn
-> SourceInfo ReduceAnn
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SourceInfo ReduceAnn -> SourceInfo ReduceAnn
addRelevant (SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> Replacement (SourceInfo ReduceAnn)
-> Replacement (SourceInfo ReduceAnn)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Replacement (SourceInfo ReduceAnn)
src
  where
    repl :: [ModItem ReduceAnn] -> Replacement [ModItem ReduceAnn]
repl = [ModItem ReduceAnn] -> Replacement [ModItem ReduceAnn]
forall a. Replace [a]
halve ([ModItem ReduceAnn] -> Replacement [ModItem ReduceAnn])
-> ([ModItem ReduceAnn] -> [ModItem ReduceAnn])
-> [ModItem ReduceAnn]
-> Replacement [ModItem ReduceAnn]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ModItem ReduceAnn -> Bool)
-> [ModItem ReduceAnn] -> [ModItem ReduceAnn]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool)
-> (ModItem ReduceAnn -> Bool) -> ModItem ReduceAnn -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ModDecl ReduceAnn -> ModItem ReduceAnn -> Bool
relevantModItem ModDecl ReduceAnn
main)
    relevant :: [ModItem ReduceAnn]
relevant = (ModItem ReduceAnn -> Bool)
-> [ModItem ReduceAnn] -> [ModItem ReduceAnn]
forall a. (a -> Bool) -> [a] -> [a]
filter (ModDecl ReduceAnn -> ModItem ReduceAnn -> Bool
relevantModItem ModDecl ReduceAnn
main) ([ModItem ReduceAnn] -> [ModItem ReduceAnn])
-> [ModItem ReduceAnn] -> [ModItem ReduceAnn]
forall a b. (a -> b) -> a -> b
$ ModDecl ReduceAnn
main ModDecl ReduceAnn
-> Getting
     [ModItem ReduceAnn] (ModDecl ReduceAnn) [ModItem ReduceAnn]
-> [ModItem ReduceAnn]
forall s a. s -> Getting a s a -> a
^. Getting [ModItem ReduceAnn] (ModDecl ReduceAnn) [ModItem ReduceAnn]
forall a (f :: * -> *).
Applicative f =>
([ModItem a] -> f [ModItem a]) -> ModDecl a -> f (ModDecl a)
modItems
    main :: ModDecl ReduceAnn
main = SourceInfo ReduceAnn
srcInfo SourceInfo ReduceAnn
-> Getting
     (ModDecl ReduceAnn) (SourceInfo ReduceAnn) (ModDecl ReduceAnn)
-> ModDecl ReduceAnn
forall s a. s -> Getting a s a -> a
^. Identifier -> Lens' (SourceInfo ReduceAnn) (ModDecl ReduceAnn)
forall a. Identifier -> Lens' (SourceInfo a) (ModDecl a)
aModule Identifier
t
    src :: Replacement (SourceInfo ReduceAnn)
src = Traversal' (SourceInfo ReduceAnn) [ModItem ReduceAnn]
-> ([ModItem ReduceAnn] -> Replacement [ModItem ReduceAnn])
-> Replace (SourceInfo ReduceAnn)
forall b a. Monoid b => Traversal' a b -> Replace b -> Replace a
combine (Identifier -> Lens' (SourceInfo ReduceAnn) (ModDecl ReduceAnn)
forall a. Identifier -> Lens' (SourceInfo a) (ModDecl a)
aModule Identifier
t ((ModDecl ReduceAnn -> f (ModDecl ReduceAnn))
 -> SourceInfo ReduceAnn -> f (SourceInfo ReduceAnn))
-> (([ModItem ReduceAnn] -> f [ModItem ReduceAnn])
    -> ModDecl ReduceAnn -> f (ModDecl ReduceAnn))
-> ([ModItem ReduceAnn] -> f [ModItem ReduceAnn])
-> SourceInfo ReduceAnn
-> f (SourceInfo ReduceAnn)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([ModItem ReduceAnn] -> f [ModItem ReduceAnn])
-> ModDecl ReduceAnn -> f (ModDecl ReduceAnn)
forall a (f :: * -> *).
Applicative f =>
([ModItem a] -> f [ModItem a]) -> ModDecl a -> f (ModDecl a)
modItems) [ModItem ReduceAnn] -> Replacement [ModItem ReduceAnn]
repl SourceInfo ReduceAnn
srcInfo
    addRelevant :: SourceInfo ReduceAnn -> SourceInfo ReduceAnn
addRelevant = Identifier -> Lens' (SourceInfo ReduceAnn) (ModDecl ReduceAnn)
forall a. Identifier -> Lens' (SourceInfo a) (ModDecl a)
aModule Identifier
t ((ModDecl ReduceAnn -> Identity (ModDecl ReduceAnn))
 -> SourceInfo ReduceAnn -> Identity (SourceInfo ReduceAnn))
-> (([ModItem ReduceAnn] -> Identity [ModItem ReduceAnn])
    -> ModDecl ReduceAnn -> Identity (ModDecl ReduceAnn))
-> ([ModItem ReduceAnn] -> Identity [ModItem ReduceAnn])
-> SourceInfo ReduceAnn
-> Identity (SourceInfo ReduceAnn)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([ModItem ReduceAnn] -> Identity [ModItem ReduceAnn])
-> ModDecl ReduceAnn -> Identity (ModDecl ReduceAnn)
forall a (f :: * -> *).
Applicative f =>
([ModItem a] -> f [ModItem a]) -> ModDecl a -> f (ModDecl a)
modItems (([ModItem ReduceAnn] -> Identity [ModItem ReduceAnn])
 -> SourceInfo ReduceAnn -> Identity (SourceInfo ReduceAnn))
-> ([ModItem ReduceAnn] -> [ModItem ReduceAnn])
-> SourceInfo ReduceAnn
-> SourceInfo ReduceAnn
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ ([ModItem ReduceAnn]
relevant [ModItem ReduceAnn] -> [ModItem ReduceAnn] -> [ModItem ReduceAnn]
forall a. [a] -> [a] -> [a]
++)

modItemBot :: Identifier -> (SourceInfo ReduceAnn) -> Bool
modItemBot :: Identifier -> SourceInfo ReduceAnn -> Bool
modItemBot Identifier
t SourceInfo ReduceAnn
srcInfo
  | [ModItem ReduceAnn] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [ModItem ReduceAnn]
modItemsNoDecl Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
2 = Bool
False
  | Bool
otherwise = Bool
True
  where
    modItemsNoDecl :: [ModItem ReduceAnn]
modItemsNoDecl =
      (ModItem ReduceAnn -> Bool)
-> [ModItem ReduceAnn] -> [ModItem ReduceAnn]
forall a. (a -> Bool) -> [a] -> [a]
filter ModItem ReduceAnn -> Bool
forall {a}. ModItem a -> Bool
noDecl ([ModItem ReduceAnn] -> [ModItem ReduceAnn])
-> [ModItem ReduceAnn] -> [ModItem ReduceAnn]
forall a b. (a -> b) -> a -> b
$ SourceInfo ReduceAnn
srcInfo SourceInfo ReduceAnn
-> Getting
     (Endo [ModItem ReduceAnn])
     (SourceInfo ReduceAnn)
     (ModItem ReduceAnn)
-> [ModItem ReduceAnn]
forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. Identifier -> Lens' (SourceInfo ReduceAnn) (ModDecl ReduceAnn)
forall a. Identifier -> Lens' (SourceInfo a) (ModDecl a)
aModule Identifier
t ((ModDecl ReduceAnn
  -> Const (Endo [ModItem ReduceAnn]) (ModDecl ReduceAnn))
 -> SourceInfo ReduceAnn
 -> Const (Endo [ModItem ReduceAnn]) (SourceInfo ReduceAnn))
-> Getting
     (Endo [ModItem ReduceAnn]) (ModDecl ReduceAnn) (ModItem ReduceAnn)
-> Getting
     (Endo [ModItem ReduceAnn])
     (SourceInfo ReduceAnn)
     (ModItem ReduceAnn)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([ModItem ReduceAnn]
 -> Const (Endo [ModItem ReduceAnn]) [ModItem ReduceAnn])
-> ModDecl ReduceAnn
-> Const (Endo [ModItem ReduceAnn]) (ModDecl ReduceAnn)
forall a (f :: * -> *).
Applicative f =>
([ModItem a] -> f [ModItem a]) -> ModDecl a -> f (ModDecl a)
modItems (([ModItem ReduceAnn]
  -> Const (Endo [ModItem ReduceAnn]) [ModItem ReduceAnn])
 -> ModDecl ReduceAnn
 -> Const (Endo [ModItem ReduceAnn]) (ModDecl ReduceAnn))
-> ((ModItem ReduceAnn
     -> Const (Endo [ModItem ReduceAnn]) (ModItem ReduceAnn))
    -> [ModItem ReduceAnn]
    -> Const (Endo [ModItem ReduceAnn]) [ModItem ReduceAnn])
-> Getting
     (Endo [ModItem ReduceAnn]) (ModDecl ReduceAnn) (ModItem ReduceAnn)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ModItem ReduceAnn
 -> Const (Endo [ModItem ReduceAnn]) (ModItem ReduceAnn))
-> [ModItem ReduceAnn]
-> Const (Endo [ModItem ReduceAnn]) [ModItem ReduceAnn]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse
    noDecl :: ModItem a -> Bool
noDecl Decl {} = Bool
False
    noDecl ModItem a
_ = Bool
True

halveStatements :: Identifier -> Replace (SourceInfo ReduceAnn)
halveStatements :: Identifier -> Replace (SourceInfo ReduceAnn)
halveStatements Identifier
t SourceInfo ReduceAnn
m =
  Identifier -> SourceInfo ReduceAnn -> SourceInfo ReduceAnn
cleanSourceInfo Identifier
t (SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> Replacement (SourceInfo ReduceAnn)
-> Replacement (SourceInfo ReduceAnn)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Traversal' (SourceInfo ReduceAnn) [ModItem ReduceAnn]
-> ([ModItem ReduceAnn] -> Replacement [ModItem ReduceAnn])
-> Replace (SourceInfo ReduceAnn)
forall b a. Monoid b => Traversal' a b -> Replace b -> Replace a
combine (Identifier -> Lens' (SourceInfo ReduceAnn) (ModDecl ReduceAnn)
forall a. Identifier -> Lens' (SourceInfo a) (ModDecl a)
aModule Identifier
t ((ModDecl ReduceAnn -> f (ModDecl ReduceAnn))
 -> SourceInfo ReduceAnn -> f (SourceInfo ReduceAnn))
-> (([ModItem ReduceAnn] -> f [ModItem ReduceAnn])
    -> ModDecl ReduceAnn -> f (ModDecl ReduceAnn))
-> ([ModItem ReduceAnn] -> f [ModItem ReduceAnn])
-> SourceInfo ReduceAnn
-> f (SourceInfo ReduceAnn)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([ModItem ReduceAnn] -> f [ModItem ReduceAnn])
-> ModDecl ReduceAnn -> f (ModDecl ReduceAnn)
forall a (f :: * -> *).
Applicative f =>
([ModItem a] -> f [ModItem a]) -> ModDecl a -> f (ModDecl a)
modItems) (Replace (ModItem ReduceAnn)
-> [ModItem ReduceAnn] -> Replacement [ModItem ReduceAnn]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse Replace (ModItem ReduceAnn)
halveAlways) SourceInfo ReduceAnn
m

-- | Reduce expressions by splitting them in half and keeping the half that
-- succeeds.
halveExpr :: Identifier -> Replace (SourceInfo ReduceAnn)
halveExpr :: Identifier -> Replace (SourceInfo ReduceAnn)
halveExpr Identifier
t = Traversal' (SourceInfo ReduceAnn) [ModItem ReduceAnn]
-> ([ModItem ReduceAnn] -> Replacement [ModItem ReduceAnn])
-> Replace (SourceInfo ReduceAnn)
forall b a. Monoid b => Traversal' a b -> Replace b -> Replace a
combine (Identifier -> Lens' (SourceInfo ReduceAnn) (ModDecl ReduceAnn)
forall a. Identifier -> Lens' (SourceInfo a) (ModDecl a)
aModule Identifier
t ((ModDecl ReduceAnn -> f (ModDecl ReduceAnn))
 -> SourceInfo ReduceAnn -> f (SourceInfo ReduceAnn))
-> (([ModItem ReduceAnn] -> f [ModItem ReduceAnn])
    -> ModDecl ReduceAnn -> f (ModDecl ReduceAnn))
-> ([ModItem ReduceAnn] -> f [ModItem ReduceAnn])
-> SourceInfo ReduceAnn
-> f (SourceInfo ReduceAnn)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([ModItem ReduceAnn] -> f [ModItem ReduceAnn])
-> ModDecl ReduceAnn -> f (ModDecl ReduceAnn)
forall a (f :: * -> *).
Applicative f =>
([ModItem a] -> f [ModItem a]) -> ModDecl a -> f (ModDecl a)
modItems) (([ModItem ReduceAnn] -> Replacement [ModItem ReduceAnn])
 -> Replace (SourceInfo ReduceAnn))
-> ([ModItem ReduceAnn] -> Replacement [ModItem ReduceAnn])
-> Replace (SourceInfo ReduceAnn)
forall a b. (a -> b) -> a -> b
$ Replace (ModItem ReduceAnn)
-> [ModItem ReduceAnn] -> Replacement [ModItem ReduceAnn]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse Replace (ModItem ReduceAnn)
halveModExpr

toIds :: [Expr] -> [Identifier]
toIds :: [Expr] -> [Identifier]
toIds = [Identifier] -> [Identifier]
forall a. Eq a => [a] -> [a]
nub ([Identifier] -> [Identifier])
-> ([Expr] -> [Identifier]) -> [Expr] -> [Identifier]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Expr -> Maybe Identifier) -> [Expr] -> [Identifier]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe Expr -> Maybe Identifier
exprId ([Expr] -> [Identifier])
-> ([Expr] -> [Expr]) -> [Expr] -> [Identifier]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Expr -> [Expr]) -> [Expr] -> [Expr]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Expr -> [Expr]
forall a. Plated a => a -> [a]
universe

toIdsConst :: [ConstExpr] -> [Identifier]
toIdsConst :: [ConstExpr] -> [Identifier]
toIdsConst = [Expr] -> [Identifier]
toIds ([Expr] -> [Identifier])
-> ([ConstExpr] -> [Expr]) -> [ConstExpr] -> [Identifier]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ConstExpr -> Expr) -> [ConstExpr] -> [Expr]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ConstExpr -> Expr
constToExpr

toIdsEvent :: [Event] -> [Identifier]
toIdsEvent :: [Event] -> [Identifier]
toIdsEvent = [Identifier] -> [Identifier]
forall a. Eq a => [a] -> [a]
nub ([Identifier] -> [Identifier])
-> ([Event] -> [Identifier]) -> [Event] -> [Identifier]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Event -> Maybe Identifier) -> [Event] -> [Identifier]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe Event -> Maybe Identifier
eventId ([Event] -> [Identifier])
-> ([Event] -> [Event]) -> [Event] -> [Identifier]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Event -> [Event]) -> [Event] -> [Event]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Event -> [Event]
forall a. Plated a => a -> [a]
universe

allStatIds' :: (Statement ReduceAnn) -> [Identifier]
allStatIds' :: Statement ReduceAnn -> [Identifier]
allStatIds' Statement ReduceAnn
s = [Identifier] -> [Identifier]
forall a. Eq a => [a] -> [a]
nub ([Identifier] -> [Identifier]) -> [Identifier] -> [Identifier]
forall a b. (a -> b) -> a -> b
$ [Identifier]
assignIds [Identifier] -> [Identifier] -> [Identifier]
forall a. Semigroup a => a -> a -> a
<> [Identifier]
otherExpr [Identifier] -> [Identifier] -> [Identifier]
forall a. Semigroup a => a -> a -> a
<> [Identifier]
eventProcessedIds
  where
    assignIds :: [Identifier]
assignIds =
      [Expr] -> [Identifier]
toIds ([Expr] -> [Identifier]) -> [Expr] -> [Identifier]
forall a b. (a -> b) -> a -> b
$
        (Statement ReduceAnn
s Statement ReduceAnn
-> Getting (Endo [Expr]) (Statement ReduceAnn) Expr -> [Expr]
forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. (Assign -> Const (Endo [Expr]) Assign)
-> Statement ReduceAnn -> Const (Endo [Expr]) (Statement ReduceAnn)
forall a (f :: * -> *).
Applicative f =>
(Assign -> f Assign) -> Statement a -> f (Statement a)
stmntBA ((Assign -> Const (Endo [Expr]) Assign)
 -> Statement ReduceAnn
 -> Const (Endo [Expr]) (Statement ReduceAnn))
-> ((Expr -> Const (Endo [Expr]) Expr)
    -> Assign -> Const (Endo [Expr]) Assign)
-> Getting (Endo [Expr]) (Statement ReduceAnn) Expr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Expr -> Const (Endo [Expr]) Expr)
-> Assign -> Const (Endo [Expr]) Assign
Lens' Assign Expr
assignExpr)
          [Expr] -> [Expr] -> [Expr]
forall a. Semigroup a => a -> a -> a
<> (Statement ReduceAnn
s Statement ReduceAnn
-> Getting (Endo [Expr]) (Statement ReduceAnn) Expr -> [Expr]
forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. (Assign -> Const (Endo [Expr]) Assign)
-> Statement ReduceAnn -> Const (Endo [Expr]) (Statement ReduceAnn)
forall a (f :: * -> *).
Applicative f =>
(Assign -> f Assign) -> Statement a -> f (Statement a)
stmntNBA ((Assign -> Const (Endo [Expr]) Assign)
 -> Statement ReduceAnn
 -> Const (Endo [Expr]) (Statement ReduceAnn))
-> ((Expr -> Const (Endo [Expr]) Expr)
    -> Assign -> Const (Endo [Expr]) Assign)
-> Getting (Endo [Expr]) (Statement ReduceAnn) Expr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Expr -> Const (Endo [Expr]) Expr)
-> Assign -> Const (Endo [Expr]) Assign
Lens' Assign Expr
assignExpr)
          [Expr] -> [Expr] -> [Expr]
forall a. Semigroup a => a -> a -> a
<> (Statement ReduceAnn
s Statement ReduceAnn
-> Getting (Endo [Expr]) (Statement ReduceAnn) Expr -> [Expr]
forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. (Assign -> Const (Endo [Expr]) Assign)
-> Statement ReduceAnn -> Const (Endo [Expr]) (Statement ReduceAnn)
forall a (f :: * -> *).
Applicative f =>
(Assign -> f Assign) -> Statement a -> f (Statement a)
forAssign ((Assign -> Const (Endo [Expr]) Assign)
 -> Statement ReduceAnn
 -> Const (Endo [Expr]) (Statement ReduceAnn))
-> ((Expr -> Const (Endo [Expr]) Expr)
    -> Assign -> Const (Endo [Expr]) Assign)
-> Getting (Endo [Expr]) (Statement ReduceAnn) Expr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Expr -> Const (Endo [Expr]) Expr)
-> Assign -> Const (Endo [Expr]) Assign
Lens' Assign Expr
assignExpr)
          [Expr] -> [Expr] -> [Expr]
forall a. Semigroup a => a -> a -> a
<> (Statement ReduceAnn
s Statement ReduceAnn
-> Getting (Endo [Expr]) (Statement ReduceAnn) Expr -> [Expr]
forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. (Assign -> Const (Endo [Expr]) Assign)
-> Statement ReduceAnn -> Const (Endo [Expr]) (Statement ReduceAnn)
forall a (f :: * -> *).
Applicative f =>
(Assign -> f Assign) -> Statement a -> f (Statement a)
forIncr ((Assign -> Const (Endo [Expr]) Assign)
 -> Statement ReduceAnn
 -> Const (Endo [Expr]) (Statement ReduceAnn))
-> ((Expr -> Const (Endo [Expr]) Expr)
    -> Assign -> Const (Endo [Expr]) Assign)
-> Getting (Endo [Expr]) (Statement ReduceAnn) Expr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Expr -> Const (Endo [Expr]) Expr)
-> Assign -> Const (Endo [Expr]) Assign
Lens' Assign Expr
assignExpr)
    otherExpr :: [Identifier]
otherExpr = [Expr] -> [Identifier]
toIds ([Expr] -> [Identifier]) -> [Expr] -> [Identifier]
forall a b. (a -> b) -> a -> b
$ (Statement ReduceAnn
s Statement ReduceAnn
-> Getting (Endo [Expr]) (Statement ReduceAnn) Expr -> [Expr]
forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. Getting (Endo [Expr]) (Statement ReduceAnn) Expr
forall a (f :: * -> *).
Applicative f =>
(Expr -> f Expr) -> Statement a -> f (Statement a)
forExpr) [Expr] -> [Expr] -> [Expr]
forall a. Semigroup a => a -> a -> a
<> (Statement ReduceAnn
s Statement ReduceAnn
-> Getting (Endo [Expr]) (Statement ReduceAnn) Expr -> [Expr]
forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. Getting (Endo [Expr]) (Statement ReduceAnn) Expr
forall a (f :: * -> *).
Applicative f =>
(Expr -> f Expr) -> Statement a -> f (Statement a)
stmntCondExpr)
    eventProcessedIds :: [Identifier]
eventProcessedIds = [Event] -> [Identifier]
toIdsEvent ([Event] -> [Identifier]) -> [Event] -> [Identifier]
forall a b. (a -> b) -> a -> b
$ Statement ReduceAnn
s Statement ReduceAnn
-> ((Event -> Const (Endo [Event]) Event)
    -> Statement ReduceAnn
    -> Const (Endo [Event]) (Statement ReduceAnn))
-> [Event]
forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. (Event -> Const (Endo [Event]) Event)
-> Statement ReduceAnn
-> Const (Endo [Event]) (Statement ReduceAnn)
forall a (f :: * -> *).
Applicative f =>
(Event -> f Event) -> Statement a -> f (Statement a)
statEvent

allStatIds :: (Statement ReduceAnn) -> [Identifier]
allStatIds :: Statement ReduceAnn -> [Identifier]
allStatIds Statement ReduceAnn
s = [Identifier] -> [Identifier]
forall a. Eq a => [a] -> [a]
nub ([Identifier] -> [Identifier])
-> ([[Identifier]] -> [Identifier])
-> [[Identifier]]
-> [Identifier]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[Identifier]] -> [Identifier]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[Identifier]] -> [Identifier]) -> [[Identifier]] -> [Identifier]
forall a b. (a -> b) -> a -> b
$ Statement ReduceAnn -> [Identifier]
allStatIds' (Statement ReduceAnn -> [Identifier])
-> [Statement ReduceAnn] -> [[Identifier]]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Statement ReduceAnn -> [Statement ReduceAnn]
forall a. Plated a => a -> [a]
universe Statement ReduceAnn
s

fromRange :: Range -> [ConstExpr]
fromRange :: Range -> [ConstExpr]
fromRange Range
r = [Range -> ConstExpr
rangeMSB Range
r, Range -> ConstExpr
rangeLSB Range
r]

allExprIds :: (ModDecl ReduceAnn) -> [Identifier]
allExprIds :: ModDecl ReduceAnn -> [Identifier]
allExprIds ModDecl ReduceAnn
m =
  [Identifier] -> [Identifier]
forall a. Eq a => [a] -> [a]
nub ([Identifier] -> [Identifier]) -> [Identifier] -> [Identifier]
forall a b. (a -> b) -> a -> b
$
    [Identifier]
contAssignIds
      [Identifier] -> [Identifier] -> [Identifier]
forall a. Semigroup a => a -> a -> a
<> [Identifier]
modInstIds
      [Identifier] -> [Identifier] -> [Identifier]
forall a. Semigroup a => a -> a -> a
<> [Identifier]
modInitialIds
      [Identifier] -> [Identifier] -> [Identifier]
forall a. Semigroup a => a -> a -> a
<> [Identifier]
modAlwaysIds
      [Identifier] -> [Identifier] -> [Identifier]
forall a. Semigroup a => a -> a -> a
<> [Identifier]
modPortIds
      [Identifier] -> [Identifier] -> [Identifier]
forall a. Semigroup a => a -> a -> a
<> [Identifier]
modDeclIds
      [Identifier] -> [Identifier] -> [Identifier]
forall a. Semigroup a => a -> a -> a
<> [Identifier]
paramIds
  where
    contAssignIds :: [Identifier]
contAssignIds =
      [Expr] -> [Identifier]
toIds ([Expr] -> [Identifier]) -> [Expr] -> [Identifier]
forall a b. (a -> b) -> a -> b
$ ModDecl ReduceAnn
m ModDecl ReduceAnn
-> Getting (Endo [Expr]) (ModDecl ReduceAnn) Expr -> [Expr]
forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. ([ModItem ReduceAnn] -> Const (Endo [Expr]) [ModItem ReduceAnn])
-> ModDecl ReduceAnn -> Const (Endo [Expr]) (ModDecl ReduceAnn)
forall a (f :: * -> *).
Applicative f =>
([ModItem a] -> f [ModItem a]) -> ModDecl a -> f (ModDecl a)
modItems (([ModItem ReduceAnn] -> Const (Endo [Expr]) [ModItem ReduceAnn])
 -> ModDecl ReduceAnn -> Const (Endo [Expr]) (ModDecl ReduceAnn))
-> ((Expr -> Const (Endo [Expr]) Expr)
    -> [ModItem ReduceAnn] -> Const (Endo [Expr]) [ModItem ReduceAnn])
-> Getting (Endo [Expr]) (ModDecl ReduceAnn) Expr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ModItem ReduceAnn -> Const (Endo [Expr]) (ModItem ReduceAnn))
-> [ModItem ReduceAnn] -> Const (Endo [Expr]) [ModItem ReduceAnn]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ((ModItem ReduceAnn -> Const (Endo [Expr]) (ModItem ReduceAnn))
 -> [ModItem ReduceAnn] -> Const (Endo [Expr]) [ModItem ReduceAnn])
-> ((Expr -> Const (Endo [Expr]) Expr)
    -> ModItem ReduceAnn -> Const (Endo [Expr]) (ModItem ReduceAnn))
-> (Expr -> Const (Endo [Expr]) Expr)
-> [ModItem ReduceAnn]
-> Const (Endo [Expr]) [ModItem ReduceAnn]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ContAssign -> Const (Endo [Expr]) ContAssign)
-> ModItem ReduceAnn -> Const (Endo [Expr]) (ModItem ReduceAnn)
forall a (f :: * -> *).
Applicative f =>
(ContAssign -> f ContAssign) -> ModItem a -> f (ModItem a)
modContAssign ((ContAssign -> Const (Endo [Expr]) ContAssign)
 -> ModItem ReduceAnn -> Const (Endo [Expr]) (ModItem ReduceAnn))
-> ((Expr -> Const (Endo [Expr]) Expr)
    -> ContAssign -> Const (Endo [Expr]) ContAssign)
-> (Expr -> Const (Endo [Expr]) Expr)
-> ModItem ReduceAnn
-> Const (Endo [Expr]) (ModItem ReduceAnn)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Expr -> Const (Endo [Expr]) Expr)
-> ContAssign -> Const (Endo [Expr]) ContAssign
Lens' ContAssign Expr
contAssignExpr
    modInstIds :: [Identifier]
modInstIds =
      [Expr] -> [Identifier]
toIds ([Expr] -> [Identifier]) -> [Expr] -> [Identifier]
forall a b. (a -> b) -> a -> b
$ ModDecl ReduceAnn
m ModDecl ReduceAnn
-> Getting (Endo [Expr]) (ModDecl ReduceAnn) Expr -> [Expr]
forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. ([ModItem ReduceAnn] -> Const (Endo [Expr]) [ModItem ReduceAnn])
-> ModDecl ReduceAnn -> Const (Endo [Expr]) (ModDecl ReduceAnn)
forall a (f :: * -> *).
Applicative f =>
([ModItem a] -> f [ModItem a]) -> ModDecl a -> f (ModDecl a)
modItems (([ModItem ReduceAnn] -> Const (Endo [Expr]) [ModItem ReduceAnn])
 -> ModDecl ReduceAnn -> Const (Endo [Expr]) (ModDecl ReduceAnn))
-> ((Expr -> Const (Endo [Expr]) Expr)
    -> [ModItem ReduceAnn] -> Const (Endo [Expr]) [ModItem ReduceAnn])
-> Getting (Endo [Expr]) (ModDecl ReduceAnn) Expr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ModItem ReduceAnn -> Const (Endo [Expr]) (ModItem ReduceAnn))
-> [ModItem ReduceAnn] -> Const (Endo [Expr]) [ModItem ReduceAnn]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ((ModItem ReduceAnn -> Const (Endo [Expr]) (ModItem ReduceAnn))
 -> [ModItem ReduceAnn] -> Const (Endo [Expr]) [ModItem ReduceAnn])
-> ((Expr -> Const (Endo [Expr]) Expr)
    -> ModItem ReduceAnn -> Const (Endo [Expr]) (ModItem ReduceAnn))
-> (Expr -> Const (Endo [Expr]) Expr)
-> [ModItem ReduceAnn]
-> Const (Endo [Expr]) [ModItem ReduceAnn]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([ModConn] -> Const (Endo [Expr]) [ModConn])
-> ModItem ReduceAnn -> Const (Endo [Expr]) (ModItem ReduceAnn)
forall a (f :: * -> *).
Applicative f =>
([ModConn] -> f [ModConn]) -> ModItem a -> f (ModItem a)
modInstConns (([ModConn] -> Const (Endo [Expr]) [ModConn])
 -> ModItem ReduceAnn -> Const (Endo [Expr]) (ModItem ReduceAnn))
-> ((Expr -> Const (Endo [Expr]) Expr)
    -> [ModConn] -> Const (Endo [Expr]) [ModConn])
-> (Expr -> Const (Endo [Expr]) Expr)
-> ModItem ReduceAnn
-> Const (Endo [Expr]) (ModItem ReduceAnn)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ModConn -> Const (Endo [Expr]) ModConn)
-> [ModConn] -> Const (Endo [Expr]) [ModConn]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ((ModConn -> Const (Endo [Expr]) ModConn)
 -> [ModConn] -> Const (Endo [Expr]) [ModConn])
-> ((Expr -> Const (Endo [Expr]) Expr)
    -> ModConn -> Const (Endo [Expr]) ModConn)
-> (Expr -> Const (Endo [Expr]) Expr)
-> [ModConn]
-> Const (Endo [Expr]) [ModConn]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Expr -> Const (Endo [Expr]) Expr)
-> ModConn -> Const (Endo [Expr]) ModConn
Lens' ModConn Expr
modExpr
    modInitialIds :: [Identifier]
modInitialIds =
      [Identifier] -> [Identifier]
forall a. Eq a => [a] -> [a]
nub ([Identifier] -> [Identifier])
-> ([Statement ReduceAnn] -> [Identifier])
-> [Statement ReduceAnn]
-> [Identifier]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Statement ReduceAnn -> [Identifier])
-> [Statement ReduceAnn] -> [Identifier]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Statement ReduceAnn -> [Identifier]
allStatIds ([Statement ReduceAnn] -> [Identifier])
-> [Statement ReduceAnn] -> [Identifier]
forall a b. (a -> b) -> a -> b
$ ModDecl ReduceAnn
m ModDecl ReduceAnn
-> Getting
     (Endo [Statement ReduceAnn])
     (ModDecl ReduceAnn)
     (Statement ReduceAnn)
-> [Statement ReduceAnn]
forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. ([ModItem ReduceAnn]
 -> Const (Endo [Statement ReduceAnn]) [ModItem ReduceAnn])
-> ModDecl ReduceAnn
-> Const (Endo [Statement ReduceAnn]) (ModDecl ReduceAnn)
forall a (f :: * -> *).
Applicative f =>
([ModItem a] -> f [ModItem a]) -> ModDecl a -> f (ModDecl a)
modItems (([ModItem ReduceAnn]
  -> Const (Endo [Statement ReduceAnn]) [ModItem ReduceAnn])
 -> ModDecl ReduceAnn
 -> Const (Endo [Statement ReduceAnn]) (ModDecl ReduceAnn))
-> ((Statement ReduceAnn
     -> Const (Endo [Statement ReduceAnn]) (Statement ReduceAnn))
    -> [ModItem ReduceAnn]
    -> Const (Endo [Statement ReduceAnn]) [ModItem ReduceAnn])
-> Getting
     (Endo [Statement ReduceAnn])
     (ModDecl ReduceAnn)
     (Statement ReduceAnn)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ModItem ReduceAnn
 -> Const (Endo [Statement ReduceAnn]) (ModItem ReduceAnn))
-> [ModItem ReduceAnn]
-> Const (Endo [Statement ReduceAnn]) [ModItem ReduceAnn]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ((ModItem ReduceAnn
  -> Const (Endo [Statement ReduceAnn]) (ModItem ReduceAnn))
 -> [ModItem ReduceAnn]
 -> Const (Endo [Statement ReduceAnn]) [ModItem ReduceAnn])
-> ((Statement ReduceAnn
     -> Const (Endo [Statement ReduceAnn]) (Statement ReduceAnn))
    -> ModItem ReduceAnn
    -> Const (Endo [Statement ReduceAnn]) (ModItem ReduceAnn))
-> (Statement ReduceAnn
    -> Const (Endo [Statement ReduceAnn]) (Statement ReduceAnn))
-> [ModItem ReduceAnn]
-> Const (Endo [Statement ReduceAnn]) [ModItem ReduceAnn]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Statement ReduceAnn
 -> Const (Endo [Statement ReduceAnn]) (Statement ReduceAnn))
-> ModItem ReduceAnn
-> Const (Endo [Statement ReduceAnn]) (ModItem ReduceAnn)
forall a (p :: * -> * -> *) (f :: * -> *).
(Choice p, Applicative f) =>
p (Statement a) (f (Statement a)) -> p (ModItem a) (f (ModItem a))
_Initial
    modAlwaysIds :: [Identifier]
modAlwaysIds =
      [Identifier] -> [Identifier]
forall a. Eq a => [a] -> [a]
nub ([Identifier] -> [Identifier])
-> ([Statement ReduceAnn] -> [Identifier])
-> [Statement ReduceAnn]
-> [Identifier]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Statement ReduceAnn -> [Identifier])
-> [Statement ReduceAnn] -> [Identifier]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Statement ReduceAnn -> [Identifier]
allStatIds ([Statement ReduceAnn] -> [Identifier])
-> [Statement ReduceAnn] -> [Identifier]
forall a b. (a -> b) -> a -> b
$ ModDecl ReduceAnn
m ModDecl ReduceAnn
-> Getting
     (Endo [Statement ReduceAnn])
     (ModDecl ReduceAnn)
     (Statement ReduceAnn)
-> [Statement ReduceAnn]
forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. ([ModItem ReduceAnn]
 -> Const (Endo [Statement ReduceAnn]) [ModItem ReduceAnn])
-> ModDecl ReduceAnn
-> Const (Endo [Statement ReduceAnn]) (ModDecl ReduceAnn)
forall a (f :: * -> *).
Applicative f =>
([ModItem a] -> f [ModItem a]) -> ModDecl a -> f (ModDecl a)
modItems (([ModItem ReduceAnn]
  -> Const (Endo [Statement ReduceAnn]) [ModItem ReduceAnn])
 -> ModDecl ReduceAnn
 -> Const (Endo [Statement ReduceAnn]) (ModDecl ReduceAnn))
-> ((Statement ReduceAnn
     -> Const (Endo [Statement ReduceAnn]) (Statement ReduceAnn))
    -> [ModItem ReduceAnn]
    -> Const (Endo [Statement ReduceAnn]) [ModItem ReduceAnn])
-> Getting
     (Endo [Statement ReduceAnn])
     (ModDecl ReduceAnn)
     (Statement ReduceAnn)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ModItem ReduceAnn
 -> Const (Endo [Statement ReduceAnn]) (ModItem ReduceAnn))
-> [ModItem ReduceAnn]
-> Const (Endo [Statement ReduceAnn]) [ModItem ReduceAnn]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ((ModItem ReduceAnn
  -> Const (Endo [Statement ReduceAnn]) (ModItem ReduceAnn))
 -> [ModItem ReduceAnn]
 -> Const (Endo [Statement ReduceAnn]) [ModItem ReduceAnn])
-> ((Statement ReduceAnn
     -> Const (Endo [Statement ReduceAnn]) (Statement ReduceAnn))
    -> ModItem ReduceAnn
    -> Const (Endo [Statement ReduceAnn]) (ModItem ReduceAnn))
-> (Statement ReduceAnn
    -> Const (Endo [Statement ReduceAnn]) (Statement ReduceAnn))
-> [ModItem ReduceAnn]
-> Const (Endo [Statement ReduceAnn]) [ModItem ReduceAnn]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Statement ReduceAnn
 -> Const (Endo [Statement ReduceAnn]) (Statement ReduceAnn))
-> ModItem ReduceAnn
-> Const (Endo [Statement ReduceAnn]) (ModItem ReduceAnn)
forall a (p :: * -> * -> *) (f :: * -> *).
(Choice p, Applicative f) =>
p (Statement a) (f (Statement a)) -> p (ModItem a) (f (ModItem a))
_Always
    modPortIds :: [Identifier]
modPortIds =
      [Identifier] -> [Identifier]
forall a. Eq a => [a] -> [a]
nub
        ([Identifier] -> [Identifier])
-> ([Range] -> [Identifier]) -> [Range] -> [Identifier]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Range -> [Identifier]) -> [Range] -> [Identifier]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ([ConstExpr] -> [Identifier]
toIdsConst ([ConstExpr] -> [Identifier])
-> (Range -> [ConstExpr]) -> Range -> [Identifier]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Range -> [ConstExpr]
fromRange)
        ([Range] -> [Identifier]) -> [Range] -> [Identifier]
forall a b. (a -> b) -> a -> b
$ ModDecl ReduceAnn
m
          ModDecl ReduceAnn
-> Getting (Endo [Range]) (ModDecl ReduceAnn) Range -> [Range]
forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. ([ModItem ReduceAnn] -> Const (Endo [Range]) [ModItem ReduceAnn])
-> ModDecl ReduceAnn -> Const (Endo [Range]) (ModDecl ReduceAnn)
forall a (f :: * -> *).
Applicative f =>
([ModItem a] -> f [ModItem a]) -> ModDecl a -> f (ModDecl a)
modItems
            (([ModItem ReduceAnn] -> Const (Endo [Range]) [ModItem ReduceAnn])
 -> ModDecl ReduceAnn -> Const (Endo [Range]) (ModDecl ReduceAnn))
-> ((Range -> Const (Endo [Range]) Range)
    -> [ModItem ReduceAnn] -> Const (Endo [Range]) [ModItem ReduceAnn])
-> Getting (Endo [Range]) (ModDecl ReduceAnn) Range
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ModItem ReduceAnn -> Const (Endo [Range]) (ModItem ReduceAnn))
-> [ModItem ReduceAnn] -> Const (Endo [Range]) [ModItem ReduceAnn]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse
            ((ModItem ReduceAnn -> Const (Endo [Range]) (ModItem ReduceAnn))
 -> [ModItem ReduceAnn] -> Const (Endo [Range]) [ModItem ReduceAnn])
-> ((Range -> Const (Endo [Range]) Range)
    -> ModItem ReduceAnn -> Const (Endo [Range]) (ModItem ReduceAnn))
-> (Range -> Const (Endo [Range]) Range)
-> [ModItem ReduceAnn]
-> Const (Endo [Range]) [ModItem ReduceAnn]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Port -> Const (Endo [Range]) Port)
-> ModItem ReduceAnn -> Const (Endo [Range]) (ModItem ReduceAnn)
forall a (f :: * -> *).
Applicative f =>
(Port -> f Port) -> ModItem a -> f (ModItem a)
declPort
            ((Port -> Const (Endo [Range]) Port)
 -> ModItem ReduceAnn -> Const (Endo [Range]) (ModItem ReduceAnn))
-> ((Range -> Const (Endo [Range]) Range)
    -> Port -> Const (Endo [Range]) Port)
-> (Range -> Const (Endo [Range]) Range)
-> ModItem ReduceAnn
-> Const (Endo [Range]) (ModItem ReduceAnn)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Range -> Const (Endo [Range]) Range)
-> Port -> Const (Endo [Range]) Port
Lens' Port Range
portSize
    modDeclIds :: [Identifier]
modDeclIds = [ConstExpr] -> [Identifier]
toIdsConst ([ConstExpr] -> [Identifier]) -> [ConstExpr] -> [Identifier]
forall a b. (a -> b) -> a -> b
$ ModDecl ReduceAnn
m ModDecl ReduceAnn
-> Getting (Endo [ConstExpr]) (ModDecl ReduceAnn) ConstExpr
-> [ConstExpr]
forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. ([ModItem ReduceAnn]
 -> Const (Endo [ConstExpr]) [ModItem ReduceAnn])
-> ModDecl ReduceAnn
-> Const (Endo [ConstExpr]) (ModDecl ReduceAnn)
forall a (f :: * -> *).
Applicative f =>
([ModItem a] -> f [ModItem a]) -> ModDecl a -> f (ModDecl a)
modItems (([ModItem ReduceAnn]
  -> Const (Endo [ConstExpr]) [ModItem ReduceAnn])
 -> ModDecl ReduceAnn
 -> Const (Endo [ConstExpr]) (ModDecl ReduceAnn))
-> ((ConstExpr -> Const (Endo [ConstExpr]) ConstExpr)
    -> [ModItem ReduceAnn]
    -> Const (Endo [ConstExpr]) [ModItem ReduceAnn])
-> Getting (Endo [ConstExpr]) (ModDecl ReduceAnn) ConstExpr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ModItem ReduceAnn -> Const (Endo [ConstExpr]) (ModItem ReduceAnn))
-> [ModItem ReduceAnn]
-> Const (Endo [ConstExpr]) [ModItem ReduceAnn]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ((ModItem ReduceAnn
  -> Const (Endo [ConstExpr]) (ModItem ReduceAnn))
 -> [ModItem ReduceAnn]
 -> Const (Endo [ConstExpr]) [ModItem ReduceAnn])
-> ((ConstExpr -> Const (Endo [ConstExpr]) ConstExpr)
    -> ModItem ReduceAnn
    -> Const (Endo [ConstExpr]) (ModItem ReduceAnn))
-> (ConstExpr -> Const (Endo [ConstExpr]) ConstExpr)
-> [ModItem ReduceAnn]
-> Const (Endo [ConstExpr]) [ModItem ReduceAnn]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Maybe ConstExpr -> Const (Endo [ConstExpr]) (Maybe ConstExpr))
-> ModItem ReduceAnn
-> Const (Endo [ConstExpr]) (ModItem ReduceAnn)
forall a (f :: * -> *).
Applicative f =>
(Maybe ConstExpr -> f (Maybe ConstExpr))
-> ModItem a -> f (ModItem a)
declVal ((Maybe ConstExpr -> Const (Endo [ConstExpr]) (Maybe ConstExpr))
 -> ModItem ReduceAnn
 -> Const (Endo [ConstExpr]) (ModItem ReduceAnn))
-> ((ConstExpr -> Const (Endo [ConstExpr]) ConstExpr)
    -> Maybe ConstExpr -> Const (Endo [ConstExpr]) (Maybe ConstExpr))
-> (ConstExpr -> Const (Endo [ConstExpr]) ConstExpr)
-> ModItem ReduceAnn
-> Const (Endo [ConstExpr]) (ModItem ReduceAnn)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ConstExpr -> Const (Endo [ConstExpr]) ConstExpr)
-> Maybe ConstExpr -> Const (Endo [ConstExpr]) (Maybe ConstExpr)
forall a b (p :: * -> * -> *) (f :: * -> *).
(Choice p, Applicative f) =>
p a (f b) -> p (Maybe a) (f (Maybe b))
_Just
    paramIds :: [Identifier]
paramIds =
      [ConstExpr] -> [Identifier]
toIdsConst ([ConstExpr] -> [Identifier]) -> [ConstExpr] -> [Identifier]
forall a b. (a -> b) -> a -> b
$
        (ModDecl ReduceAnn
m ModDecl ReduceAnn
-> Getting (Endo [ConstExpr]) (ModDecl ReduceAnn) ConstExpr
-> [ConstExpr]
forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. ([ModItem ReduceAnn]
 -> Const (Endo [ConstExpr]) [ModItem ReduceAnn])
-> ModDecl ReduceAnn
-> Const (Endo [ConstExpr]) (ModDecl ReduceAnn)
forall a (f :: * -> *).
Applicative f =>
([ModItem a] -> f [ModItem a]) -> ModDecl a -> f (ModDecl a)
modItems (([ModItem ReduceAnn]
  -> Const (Endo [ConstExpr]) [ModItem ReduceAnn])
 -> ModDecl ReduceAnn
 -> Const (Endo [ConstExpr]) (ModDecl ReduceAnn))
-> ((ConstExpr -> Const (Endo [ConstExpr]) ConstExpr)
    -> [ModItem ReduceAnn]
    -> Const (Endo [ConstExpr]) [ModItem ReduceAnn])
-> Getting (Endo [ConstExpr]) (ModDecl ReduceAnn) ConstExpr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ModItem ReduceAnn -> Const (Endo [ConstExpr]) (ModItem ReduceAnn))
-> [ModItem ReduceAnn]
-> Const (Endo [ConstExpr]) [ModItem ReduceAnn]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ((ModItem ReduceAnn
  -> Const (Endo [ConstExpr]) (ModItem ReduceAnn))
 -> [ModItem ReduceAnn]
 -> Const (Endo [ConstExpr]) [ModItem ReduceAnn])
-> ((ConstExpr -> Const (Endo [ConstExpr]) ConstExpr)
    -> ModItem ReduceAnn
    -> Const (Endo [ConstExpr]) (ModItem ReduceAnn))
-> (ConstExpr -> Const (Endo [ConstExpr]) ConstExpr)
-> [ModItem ReduceAnn]
-> Const (Endo [ConstExpr]) [ModItem ReduceAnn]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (NonEmpty Parameter
 -> Const (Endo [ConstExpr]) (NonEmpty Parameter))
-> ModItem ReduceAnn
-> Const (Endo [ConstExpr]) (ModItem ReduceAnn)
forall a (f :: * -> *).
Applicative f =>
(NonEmpty Parameter -> f (NonEmpty Parameter))
-> ModItem a -> f (ModItem a)
paramDecl ((NonEmpty Parameter
  -> Const (Endo [ConstExpr]) (NonEmpty Parameter))
 -> ModItem ReduceAnn
 -> Const (Endo [ConstExpr]) (ModItem ReduceAnn))
-> ((ConstExpr -> Const (Endo [ConstExpr]) ConstExpr)
    -> NonEmpty Parameter
    -> Const (Endo [ConstExpr]) (NonEmpty Parameter))
-> (ConstExpr -> Const (Endo [ConstExpr]) ConstExpr)
-> ModItem ReduceAnn
-> Const (Endo [ConstExpr]) (ModItem ReduceAnn)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Parameter -> Const (Endo [ConstExpr]) Parameter)
-> NonEmpty Parameter
-> Const (Endo [ConstExpr]) (NonEmpty Parameter)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> NonEmpty a -> f (NonEmpty b)
traverse ((Parameter -> Const (Endo [ConstExpr]) Parameter)
 -> NonEmpty Parameter
 -> Const (Endo [ConstExpr]) (NonEmpty Parameter))
-> ((ConstExpr -> Const (Endo [ConstExpr]) ConstExpr)
    -> Parameter -> Const (Endo [ConstExpr]) Parameter)
-> (ConstExpr -> Const (Endo [ConstExpr]) ConstExpr)
-> NonEmpty Parameter
-> Const (Endo [ConstExpr]) (NonEmpty Parameter)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ConstExpr -> Const (Endo [ConstExpr]) ConstExpr)
-> Parameter -> Const (Endo [ConstExpr]) Parameter
Lens' Parameter ConstExpr
paramValue)
          [ConstExpr] -> [ConstExpr] -> [ConstExpr]
forall a. Semigroup a => a -> a -> a
<> ( ModDecl ReduceAnn
m
                 ModDecl ReduceAnn
-> Getting (Endo [ConstExpr]) (ModDecl ReduceAnn) ConstExpr
-> [ConstExpr]
forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. ([ModItem ReduceAnn]
 -> Const (Endo [ConstExpr]) [ModItem ReduceAnn])
-> ModDecl ReduceAnn
-> Const (Endo [ConstExpr]) (ModDecl ReduceAnn)
forall a (f :: * -> *).
Applicative f =>
([ModItem a] -> f [ModItem a]) -> ModDecl a -> f (ModDecl a)
modItems
                   (([ModItem ReduceAnn]
  -> Const (Endo [ConstExpr]) [ModItem ReduceAnn])
 -> ModDecl ReduceAnn
 -> Const (Endo [ConstExpr]) (ModDecl ReduceAnn))
-> ((ConstExpr -> Const (Endo [ConstExpr]) ConstExpr)
    -> [ModItem ReduceAnn]
    -> Const (Endo [ConstExpr]) [ModItem ReduceAnn])
-> Getting (Endo [ConstExpr]) (ModDecl ReduceAnn) ConstExpr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ModItem ReduceAnn -> Const (Endo [ConstExpr]) (ModItem ReduceAnn))
-> [ModItem ReduceAnn]
-> Const (Endo [ConstExpr]) [ModItem ReduceAnn]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse
                   ((ModItem ReduceAnn
  -> Const (Endo [ConstExpr]) (ModItem ReduceAnn))
 -> [ModItem ReduceAnn]
 -> Const (Endo [ConstExpr]) [ModItem ReduceAnn])
-> ((ConstExpr -> Const (Endo [ConstExpr]) ConstExpr)
    -> ModItem ReduceAnn
    -> Const (Endo [ConstExpr]) (ModItem ReduceAnn))
-> (ConstExpr -> Const (Endo [ConstExpr]) ConstExpr)
-> [ModItem ReduceAnn]
-> Const (Endo [ConstExpr]) [ModItem ReduceAnn]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (NonEmpty LocalParam
 -> Const (Endo [ConstExpr]) (NonEmpty LocalParam))
-> ModItem ReduceAnn
-> Const (Endo [ConstExpr]) (ModItem ReduceAnn)
forall a (f :: * -> *).
Applicative f =>
(NonEmpty LocalParam -> f (NonEmpty LocalParam))
-> ModItem a -> f (ModItem a)
localParamDecl
                   ((NonEmpty LocalParam
  -> Const (Endo [ConstExpr]) (NonEmpty LocalParam))
 -> ModItem ReduceAnn
 -> Const (Endo [ConstExpr]) (ModItem ReduceAnn))
-> ((ConstExpr -> Const (Endo [ConstExpr]) ConstExpr)
    -> NonEmpty LocalParam
    -> Const (Endo [ConstExpr]) (NonEmpty LocalParam))
-> (ConstExpr -> Const (Endo [ConstExpr]) ConstExpr)
-> ModItem ReduceAnn
-> Const (Endo [ConstExpr]) (ModItem ReduceAnn)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (LocalParam -> Const (Endo [ConstExpr]) LocalParam)
-> NonEmpty LocalParam
-> Const (Endo [ConstExpr]) (NonEmpty LocalParam)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> NonEmpty a -> f (NonEmpty b)
traverse
                   ((LocalParam -> Const (Endo [ConstExpr]) LocalParam)
 -> NonEmpty LocalParam
 -> Const (Endo [ConstExpr]) (NonEmpty LocalParam))
-> ((ConstExpr -> Const (Endo [ConstExpr]) ConstExpr)
    -> LocalParam -> Const (Endo [ConstExpr]) LocalParam)
-> (ConstExpr -> Const (Endo [ConstExpr]) ConstExpr)
-> NonEmpty LocalParam
-> Const (Endo [ConstExpr]) (NonEmpty LocalParam)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ConstExpr -> Const (Endo [ConstExpr]) ConstExpr)
-> LocalParam -> Const (Endo [ConstExpr]) LocalParam
Lens' LocalParam ConstExpr
localParamValue
             )

isUsedDecl :: [Identifier] -> (ModItem ReduceAnn) -> Bool
isUsedDecl :: [Identifier] -> ModItem ReduceAnn -> Bool
isUsedDecl [Identifier]
ids (Decl Maybe PortDir
_ (Port PortType
_ Bool
_ Range
_ Identifier
i) Maybe ConstExpr
_) = Identifier
i Identifier -> [Identifier] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Identifier]
ids
isUsedDecl [Identifier]
_ ModItem ReduceAnn
_ = Bool
True

isUsedParam :: [Identifier] -> Parameter -> Bool
isUsedParam :: [Identifier] -> Parameter -> Bool
isUsedParam [Identifier]
ids (Parameter Identifier
i ConstExpr
_) = Identifier
i Identifier -> [Identifier] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Identifier]
ids

isUsedPort :: [Identifier] -> Port -> Bool
isUsedPort :: [Identifier] -> Port -> Bool
isUsedPort [Identifier]
ids (Port PortType
_ Bool
_ Range
_ Identifier
i) = Identifier
i Identifier -> [Identifier] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Identifier]
ids

-- | Should return true if there is any active tag present.
checkActiveTag :: ModDecl ReduceAnn -> Bool
checkActiveTag :: ModDecl ReduceAnn -> Bool
checkActiveTag ModDecl ReduceAnn
m = ([ModItem ReduceAnn] -> [ModItem ReduceAnn] -> Bool
forall a. Eq a => a -> a -> Bool
/= []) ([ModItem ReduceAnn] -> Bool)
-> ([ModItem ReduceAnn] -> [ModItem ReduceAnn])
-> [ModItem ReduceAnn]
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ModItem ReduceAnn -> Bool)
-> [ModItem ReduceAnn] -> [ModItem ReduceAnn]
forall a. (a -> Bool) -> [a] -> [a]
filter ModItem ReduceAnn -> Bool
hasActiveTag ([ModItem ReduceAnn] -> Bool) -> [ModItem ReduceAnn] -> Bool
forall a b. (a -> b) -> a -> b
$ ModDecl ReduceAnn -> [ModItem ReduceAnn]
forall a. ModDecl a -> [ModItem a]
_modItems ModDecl ReduceAnn
m
  where
    hasActiveTag :: ModItem ReduceAnn -> Bool
hasActiveTag (ModItemAnn ReduceAnn
Active (Always Statement ReduceAnn
_)) = Bool
True
    hasActiveTag ModItem ReduceAnn
_ = Bool
False

tagAlwaysBlockMis :: [ModItem ReduceAnn] -> [ModItem ReduceAnn]
tagAlwaysBlockMis :: [ModItem ReduceAnn] -> [ModItem ReduceAnn]
tagAlwaysBlockMis [] = []
tagAlwaysBlockMis (mi :: ModItem ReduceAnn
mi@(Always Statement ReduceAnn
_) : [ModItem ReduceAnn]
mis) = ReduceAnn -> ModItem ReduceAnn -> ModItem ReduceAnn
forall a. a -> ModItem a -> ModItem a
ModItemAnn ReduceAnn
Active ModItem ReduceAnn
mi ModItem ReduceAnn -> [ModItem ReduceAnn] -> [ModItem ReduceAnn]
forall a. a -> [a] -> [a]
: [ModItem ReduceAnn]
mis
tagAlwaysBlockMis (ModItem ReduceAnn
mi : [ModItem ReduceAnn]
mis) = ModItem ReduceAnn
mi ModItem ReduceAnn -> [ModItem ReduceAnn] -> [ModItem ReduceAnn]
forall a. a -> [a] -> [a]
: [ModItem ReduceAnn] -> [ModItem ReduceAnn]
tagAlwaysBlockMis [ModItem ReduceAnn]
mis

-- | Tag an always block to be reduced if there are no active ones.
tagAlwaysBlock :: ModDecl ReduceAnn -> ModDecl ReduceAnn
tagAlwaysBlock :: ModDecl ReduceAnn -> ModDecl ReduceAnn
tagAlwaysBlock ModDecl ReduceAnn
m
  | ModDecl ReduceAnn -> Bool
checkActiveTag ModDecl ReduceAnn
m = ModDecl ReduceAnn
m
  | Bool
otherwise = ModDecl ReduceAnn
m {_modItems = tagAlwaysBlockMis (_modItems m)}

tagAlwaysBlockReducedMis :: [ModItem ReduceAnn] -> [ModItem ReduceAnn]
tagAlwaysBlockReducedMis :: [ModItem ReduceAnn] -> [ModItem ReduceAnn]
tagAlwaysBlockReducedMis [] = []
tagAlwaysBlockReducedMis ((ModItemAnn ReduceAnn
Active ModItem ReduceAnn
mi) : [ModItem ReduceAnn]
mis) =
  ReduceAnn -> ModItem ReduceAnn -> ModItem ReduceAnn
forall a. a -> ModItem a -> ModItem a
ModItemAnn ReduceAnn
Reduced ModItem ReduceAnn
mi ModItem ReduceAnn -> [ModItem ReduceAnn] -> [ModItem ReduceAnn]
forall a. a -> [a] -> [a]
: [ModItem ReduceAnn] -> [ModItem ReduceAnn]
tagAlwaysBlockReducedMis [ModItem ReduceAnn]
mis
tagAlwaysBlockReducedMis (ModItem ReduceAnn
mi : [ModItem ReduceAnn]
mis) = ModItem ReduceAnn
mi ModItem ReduceAnn -> [ModItem ReduceAnn] -> [ModItem ReduceAnn]
forall a. a -> [a] -> [a]
: [ModItem ReduceAnn] -> [ModItem ReduceAnn]
tagAlwaysBlockReducedMis [ModItem ReduceAnn]
mis

-- | Tag an always block to be reduced if there are no active ones.
tagAlwaysBlockReduced :: ModDecl ReduceAnn -> ModDecl ReduceAnn
tagAlwaysBlockReduced :: ModDecl ReduceAnn -> ModDecl ReduceAnn
tagAlwaysBlockReduced ModDecl ReduceAnn
m = ModDecl ReduceAnn
m {_modItems = tagAlwaysBlockReducedMis (_modItems m)}

tAlways ::
  (ModDecl ReduceAnn -> ModDecl ReduceAnn) ->
  Identifier ->
  SourceInfo ReduceAnn ->
  SourceInfo ReduceAnn
tAlways :: (ModDecl ReduceAnn -> ModDecl ReduceAnn)
-> Identifier -> SourceInfo ReduceAnn -> SourceInfo ReduceAnn
tAlways ModDecl ReduceAnn -> ModDecl ReduceAnn
f Identifier
t SourceInfo ReduceAnn
m =
  SourceInfo ReduceAnn
m SourceInfo ReduceAnn
-> (SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> SourceInfo ReduceAnn
forall a b. a -> (a -> b) -> b
& Identifier -> Lens' (SourceInfo ReduceAnn) (ModDecl ReduceAnn)
forall a. Identifier -> Lens' (SourceInfo a) (ModDecl a)
aModule Identifier
t ((ModDecl ReduceAnn -> Identity (ModDecl ReduceAnn))
 -> SourceInfo ReduceAnn -> Identity (SourceInfo ReduceAnn))
-> (ModDecl ReduceAnn -> ModDecl ReduceAnn)
-> SourceInfo ReduceAnn
-> SourceInfo ReduceAnn
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ ModDecl ReduceAnn -> ModDecl ReduceAnn
f

tagAlways, untagAlways, idTag :: Identifier -> SourceInfo ReduceAnn -> SourceInfo ReduceAnn
tagAlways :: Identifier -> SourceInfo ReduceAnn -> SourceInfo ReduceAnn
tagAlways = (ModDecl ReduceAnn -> ModDecl ReduceAnn)
-> Identifier -> SourceInfo ReduceAnn -> SourceInfo ReduceAnn
tAlways ModDecl ReduceAnn -> ModDecl ReduceAnn
tagAlwaysBlock
untagAlways :: Identifier -> SourceInfo ReduceAnn -> SourceInfo ReduceAnn
untagAlways = (ModDecl ReduceAnn -> ModDecl ReduceAnn)
-> Identifier -> SourceInfo ReduceAnn -> SourceInfo ReduceAnn
tAlways ModDecl ReduceAnn -> ModDecl ReduceAnn
tagAlwaysBlockReduced
idTag :: Identifier -> SourceInfo ReduceAnn -> SourceInfo ReduceAnn
idTag = (SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> Identifier -> SourceInfo ReduceAnn -> SourceInfo ReduceAnn
forall a b. a -> b -> a
const SourceInfo ReduceAnn -> SourceInfo ReduceAnn
forall a. a -> a
id

removeDecl :: SourceInfo ReduceAnn -> SourceInfo ReduceAnn
removeDecl :: SourceInfo ReduceAnn -> SourceInfo ReduceAnn
removeDecl SourceInfo ReduceAnn
src = (Identifier -> SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> SourceInfo ReduceAnn -> [Identifier] -> SourceInfo ReduceAnn
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Identifier -> SourceInfo ReduceAnn -> SourceInfo ReduceAnn
fix SourceInfo ReduceAnn
removed [Identifier]
allMods
  where
    removeDecl' :: Identifier -> SourceInfo ReduceAnn -> SourceInfo ReduceAnn
removeDecl' Identifier
t SourceInfo ReduceAnn
src' =
      SourceInfo ReduceAnn
src'
        SourceInfo ReduceAnn
-> (SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> SourceInfo ReduceAnn
forall a b. a -> (a -> b) -> b
& ( \SourceInfo ReduceAnn
a ->
              SourceInfo ReduceAnn
a
                SourceInfo ReduceAnn
-> (SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> SourceInfo ReduceAnn
forall a b. a -> (a -> b) -> b
& Identifier -> Lens' (SourceInfo ReduceAnn) (ModDecl ReduceAnn)
forall a. Identifier -> Lens' (SourceInfo a) (ModDecl a)
aModule Identifier
t ((ModDecl ReduceAnn -> Identity (ModDecl ReduceAnn))
 -> SourceInfo ReduceAnn -> Identity (SourceInfo ReduceAnn))
-> (([ModItem ReduceAnn] -> Identity [ModItem ReduceAnn])
    -> ModDecl ReduceAnn -> Identity (ModDecl ReduceAnn))
-> ([ModItem ReduceAnn] -> Identity [ModItem ReduceAnn])
-> SourceInfo ReduceAnn
-> Identity (SourceInfo ReduceAnn)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([ModItem ReduceAnn] -> Identity [ModItem ReduceAnn])
-> ModDecl ReduceAnn -> Identity (ModDecl ReduceAnn)
forall a (f :: * -> *).
Applicative f =>
([ModItem a] -> f [ModItem a]) -> ModDecl a -> f (ModDecl a)
modItems
                  (([ModItem ReduceAnn] -> Identity [ModItem ReduceAnn])
 -> SourceInfo ReduceAnn -> Identity (SourceInfo ReduceAnn))
-> ([ModItem ReduceAnn] -> [ModItem ReduceAnn])
-> SourceInfo ReduceAnn
-> SourceInfo ReduceAnn
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ (ModItem ReduceAnn -> Bool)
-> [ModItem ReduceAnn] -> [ModItem ReduceAnn]
forall a. (a -> Bool) -> [a] -> [a]
filter
                    ([Identifier] -> ModItem ReduceAnn -> Bool
isUsedDecl ([Identifier]
used [Identifier] -> [Identifier] -> [Identifier]
forall a. Semigroup a => a -> a -> a
<> Identifier -> SourceInfo ReduceAnn -> [Identifier]
findActiveWires Identifier
t SourceInfo ReduceAnn
a))
          )
          (SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> (SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> SourceInfo ReduceAnn
-> SourceInfo ReduceAnn
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Identifier -> Lens' (SourceInfo ReduceAnn) (ModDecl ReduceAnn)
forall a. Identifier -> Lens' (SourceInfo a) (ModDecl a)
aModule Identifier
t ((ModDecl ReduceAnn -> Identity (ModDecl ReduceAnn))
 -> SourceInfo ReduceAnn -> Identity (SourceInfo ReduceAnn))
-> (([Parameter] -> Identity [Parameter])
    -> ModDecl ReduceAnn -> Identity (ModDecl ReduceAnn))
-> ([Parameter] -> Identity [Parameter])
-> SourceInfo ReduceAnn
-> Identity (SourceInfo ReduceAnn)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Parameter] -> Identity [Parameter])
-> ModDecl ReduceAnn -> Identity (ModDecl ReduceAnn)
forall a (f :: * -> *).
Applicative f =>
([Parameter] -> f [Parameter]) -> ModDecl a -> f (ModDecl a)
modParams (([Parameter] -> Identity [Parameter])
 -> SourceInfo ReduceAnn -> Identity (SourceInfo ReduceAnn))
-> ([Parameter] -> [Parameter])
-> SourceInfo ReduceAnn
-> SourceInfo ReduceAnn
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ (Parameter -> Bool) -> [Parameter] -> [Parameter]
forall a. (a -> Bool) -> [a] -> [a]
filter ([Identifier] -> Parameter -> Bool
isUsedParam [Identifier]
used))
          (SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> (SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> SourceInfo ReduceAnn
-> SourceInfo ReduceAnn
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Identifier -> Lens' (SourceInfo ReduceAnn) (ModDecl ReduceAnn)
forall a. Identifier -> Lens' (SourceInfo a) (ModDecl a)
aModule Identifier
t ((ModDecl ReduceAnn -> Identity (ModDecl ReduceAnn))
 -> SourceInfo ReduceAnn -> Identity (SourceInfo ReduceAnn))
-> (([Port] -> Identity [Port])
    -> ModDecl ReduceAnn -> Identity (ModDecl ReduceAnn))
-> ([Port] -> Identity [Port])
-> SourceInfo ReduceAnn
-> Identity (SourceInfo ReduceAnn)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Port] -> Identity [Port])
-> ModDecl ReduceAnn -> Identity (ModDecl ReduceAnn)
forall a (f :: * -> *).
Applicative f =>
([Port] -> f [Port]) -> ModDecl a -> f (ModDecl a)
modInPorts (([Port] -> Identity [Port])
 -> SourceInfo ReduceAnn -> Identity (SourceInfo ReduceAnn))
-> ([Port] -> [Port])
-> SourceInfo ReduceAnn
-> SourceInfo ReduceAnn
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ (Port -> Bool) -> [Port] -> [Port]
forall a. (a -> Bool) -> [a] -> [a]
filter ([Identifier] -> Port -> Bool
isUsedPort [Identifier]
used))
      where
        used :: [Identifier]
used = [Identifier] -> [Identifier]
forall a. Eq a => [a] -> [a]
nub ([Identifier] -> [Identifier]) -> [Identifier] -> [Identifier]
forall a b. (a -> b) -> a -> b
$ ModDecl ReduceAnn -> [Identifier]
allExprIds (SourceInfo ReduceAnn
src' SourceInfo ReduceAnn
-> Getting
     (ModDecl ReduceAnn) (SourceInfo ReduceAnn) (ModDecl ReduceAnn)
-> ModDecl ReduceAnn
forall s a. s -> Getting a s a -> a
^. Identifier -> Lens' (SourceInfo ReduceAnn) (ModDecl ReduceAnn)
forall a. Identifier -> Lens' (SourceInfo a) (ModDecl a)
aModule Identifier
t)
    allMods :: [Identifier]
allMods = SourceInfo ReduceAnn
src SourceInfo ReduceAnn
-> Getting (Endo [Identifier]) (SourceInfo ReduceAnn) Identifier
-> [Identifier]
forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. (Verilog ReduceAnn
 -> Const (Endo [Identifier]) (Verilog ReduceAnn))
-> SourceInfo ReduceAnn
-> Const (Endo [Identifier]) (SourceInfo ReduceAnn)
forall a1 a2 (f :: * -> *).
Functor f =>
(Verilog a1 -> f (Verilog a2))
-> SourceInfo a1 -> f (SourceInfo a2)
infoSrc ((Verilog ReduceAnn
  -> Const (Endo [Identifier]) (Verilog ReduceAnn))
 -> SourceInfo ReduceAnn
 -> Const (Endo [Identifier]) (SourceInfo ReduceAnn))
-> ((Identifier -> Const (Endo [Identifier]) Identifier)
    -> Verilog ReduceAnn
    -> Const (Endo [Identifier]) (Verilog ReduceAnn))
-> Getting (Endo [Identifier]) (SourceInfo ReduceAnn) Identifier
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([ModDecl ReduceAnn]
 -> Const (Endo [Identifier]) [ModDecl ReduceAnn])
-> Verilog ReduceAnn
-> Const (Endo [Identifier]) (Verilog ReduceAnn)
(Unwrapped (Verilog ReduceAnn)
 -> Const (Endo [Identifier]) (Unwrapped (Verilog ReduceAnn)))
-> Verilog ReduceAnn
-> Const (Endo [Identifier]) (Verilog ReduceAnn)
forall s t. Rewrapping s t => Iso s t (Unwrapped s) (Unwrapped t)
Iso
  (Verilog ReduceAnn)
  (Verilog ReduceAnn)
  (Unwrapped (Verilog ReduceAnn))
  (Unwrapped (Verilog ReduceAnn))
_Wrapped (([ModDecl ReduceAnn]
  -> Const (Endo [Identifier]) [ModDecl ReduceAnn])
 -> Verilog ReduceAnn
 -> Const (Endo [Identifier]) (Verilog ReduceAnn))
-> ((Identifier -> Const (Endo [Identifier]) Identifier)
    -> [ModDecl ReduceAnn]
    -> Const (Endo [Identifier]) [ModDecl ReduceAnn])
-> (Identifier -> Const (Endo [Identifier]) Identifier)
-> Verilog ReduceAnn
-> Const (Endo [Identifier]) (Verilog ReduceAnn)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ModDecl ReduceAnn
 -> Const (Endo [Identifier]) (ModDecl ReduceAnn))
-> [ModDecl ReduceAnn]
-> Const (Endo [Identifier]) [ModDecl ReduceAnn]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ((ModDecl ReduceAnn
  -> Const (Endo [Identifier]) (ModDecl ReduceAnn))
 -> [ModDecl ReduceAnn]
 -> Const (Endo [Identifier]) [ModDecl ReduceAnn])
-> Getting (Endo [Identifier]) (ModDecl ReduceAnn) Identifier
-> (Identifier -> Const (Endo [Identifier]) Identifier)
-> [ModDecl ReduceAnn]
-> Const (Endo [Identifier]) [ModDecl ReduceAnn]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Getting (Endo [Identifier]) (ModDecl ReduceAnn) Identifier
forall a (f :: * -> *).
Applicative f =>
(Identifier -> f Identifier) -> ModDecl a -> f (ModDecl a)
modId
    fix :: Identifier -> SourceInfo ReduceAnn -> SourceInfo ReduceAnn
fix Identifier
t SourceInfo ReduceAnn
a = SourceInfo ReduceAnn
a SourceInfo ReduceAnn
-> (SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> SourceInfo ReduceAnn
forall a b. a -> (a -> b) -> b
& Identifier -> Lens' (SourceInfo ReduceAnn) (ModDecl ReduceAnn)
forall a. Identifier -> Lens' (SourceInfo a) (ModDecl a)
aModule Identifier
t ((ModDecl ReduceAnn -> Identity (ModDecl ReduceAnn))
 -> SourceInfo ReduceAnn -> Identity (SourceInfo ReduceAnn))
-> (([ModItem ReduceAnn] -> Identity [ModItem ReduceAnn])
    -> ModDecl ReduceAnn -> Identity (ModDecl ReduceAnn))
-> ([ModItem ReduceAnn] -> Identity [ModItem ReduceAnn])
-> SourceInfo ReduceAnn
-> Identity (SourceInfo ReduceAnn)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([ModItem ReduceAnn] -> Identity [ModItem ReduceAnn])
-> ModDecl ReduceAnn -> Identity (ModDecl ReduceAnn)
forall a (f :: * -> *).
Applicative f =>
([ModItem a] -> f [ModItem a]) -> ModDecl a -> f (ModDecl a)
modItems (([ModItem ReduceAnn] -> Identity [ModItem ReduceAnn])
 -> SourceInfo ReduceAnn -> Identity (SourceInfo ReduceAnn))
-> ([ModItem ReduceAnn] -> [ModItem ReduceAnn])
-> SourceInfo ReduceAnn
-> SourceInfo ReduceAnn
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~ (ModItem ReduceAnn -> ModItem ReduceAnn)
-> [ModItem ReduceAnn] -> [ModItem ReduceAnn]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (SourceInfo ReduceAnn -> ModItem ReduceAnn -> ModItem ReduceAnn
fixModInst SourceInfo ReduceAnn
a)
    removed :: SourceInfo ReduceAnn
removed = (Identifier -> SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> SourceInfo ReduceAnn -> [Identifier] -> SourceInfo ReduceAnn
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Identifier -> SourceInfo ReduceAnn -> SourceInfo ReduceAnn
removeDecl' SourceInfo ReduceAnn
src [Identifier]
allMods

defaultBot :: (SourceInfo ReduceAnn) -> Bool
defaultBot :: SourceInfo ReduceAnn -> Bool
defaultBot = Bool -> SourceInfo ReduceAnn -> Bool
forall a b. a -> b -> a
const Bool
False

-- | Reduction using custom reduction strategies.
reduce_ ::
  (MonadSh m) =>
  Shelly.FilePath ->
  (SourceInfo ReduceAnn -> m Bool) ->
  Text ->
  (SourceInfo ReduceAnn -> SourceInfo ReduceAnn) ->
  (SourceInfo ReduceAnn -> SourceInfo ReduceAnn) ->
  Replace (SourceInfo ReduceAnn) ->
  (SourceInfo ReduceAnn -> Bool) ->
  SourceInfo ReduceAnn ->
  m (SourceInfo ReduceAnn)
reduce_ :: forall (m :: * -> *).
MonadSh m =>
String
-> (SourceInfo ReduceAnn -> m Bool)
-> Text
-> (SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> (SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> Replace (SourceInfo ReduceAnn)
-> (SourceInfo ReduceAnn -> Bool)
-> SourceInfo ReduceAnn
-> m (SourceInfo ReduceAnn)
reduce_ String
out SourceInfo ReduceAnn -> m Bool
eval Text
title SourceInfo ReduceAnn -> SourceInfo ReduceAnn
tag SourceInfo ReduceAnn -> SourceInfo ReduceAnn
untag Replace (SourceInfo ReduceAnn)
repl SourceInfo ReduceAnn -> Bool
bot SourceInfo ReduceAnn
usrc = do
  String -> Text -> m ()
forall (m :: * -> *). MonadSh m => String -> Text -> m ()
writefile String
out (Text -> m ()) -> Text -> m ()
forall a b. (a -> b) -> a -> b
$ SourceInfo ReduceAnn -> Text
forall a. Source a => a -> Text
genSource SourceInfo ReduceAnn
src
  Sh () -> m ()
forall a. Sh a -> m a
forall (m :: * -> *) a. MonadSh m => Sh a -> m a
liftSh
    (Sh () -> m ()) -> (Text -> Sh ()) -> Text -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Sh ()
Shelly.echo
    (Text -> m ()) -> Text -> m ()
forall a b. (a -> b) -> a -> b
$ Text
"Reducing "
      Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
title
      Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" (modules: "
      Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Int -> Text
forall a. Show a => a -> Text
showT ([ModDecl ReduceAnn] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([ModDecl ReduceAnn] -> Int)
-> (Verilog ReduceAnn -> [ModDecl ReduceAnn])
-> Verilog ReduceAnn
-> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Verilog ReduceAnn -> [ModDecl ReduceAnn]
forall a. Verilog a -> [ModDecl a]
getVerilog (Verilog ReduceAnn -> Int) -> Verilog ReduceAnn -> Int
forall a b. (a -> b) -> a -> b
$ SourceInfo ReduceAnn -> Verilog ReduceAnn
forall a. SourceInfo a -> Verilog a
_infoSrc SourceInfo ReduceAnn
src)
      Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
", module items: "
      Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Int -> Text
forall a. Show a => a -> Text
showT ([ModItem ReduceAnn] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length (SourceInfo ReduceAnn
src SourceInfo ReduceAnn
-> Getting
     (Endo [ModItem ReduceAnn])
     (SourceInfo ReduceAnn)
     (ModItem ReduceAnn)
-> [ModItem ReduceAnn]
forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. (Verilog ReduceAnn
 -> Const (Endo [ModItem ReduceAnn]) (Verilog ReduceAnn))
-> SourceInfo ReduceAnn
-> Const (Endo [ModItem ReduceAnn]) (SourceInfo ReduceAnn)
forall a1 a2 (f :: * -> *).
Functor f =>
(Verilog a1 -> f (Verilog a2))
-> SourceInfo a1 -> f (SourceInfo a2)
infoSrc ((Verilog ReduceAnn
  -> Const (Endo [ModItem ReduceAnn]) (Verilog ReduceAnn))
 -> SourceInfo ReduceAnn
 -> Const (Endo [ModItem ReduceAnn]) (SourceInfo ReduceAnn))
-> ((ModItem ReduceAnn
     -> Const (Endo [ModItem ReduceAnn]) (ModItem ReduceAnn))
    -> Verilog ReduceAnn
    -> Const (Endo [ModItem ReduceAnn]) (Verilog ReduceAnn))
-> Getting
     (Endo [ModItem ReduceAnn])
     (SourceInfo ReduceAnn)
     (ModItem ReduceAnn)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([ModDecl ReduceAnn]
 -> Const (Endo [ModItem ReduceAnn]) [ModDecl ReduceAnn])
-> Verilog ReduceAnn
-> Const (Endo [ModItem ReduceAnn]) (Verilog ReduceAnn)
(Unwrapped (Verilog ReduceAnn)
 -> Const
      (Endo [ModItem ReduceAnn]) (Unwrapped (Verilog ReduceAnn)))
-> Verilog ReduceAnn
-> Const (Endo [ModItem ReduceAnn]) (Verilog ReduceAnn)
forall s t. Rewrapping s t => Iso s t (Unwrapped s) (Unwrapped t)
Iso
  (Verilog ReduceAnn)
  (Verilog ReduceAnn)
  (Unwrapped (Verilog ReduceAnn))
  (Unwrapped (Verilog ReduceAnn))
_Wrapped (([ModDecl ReduceAnn]
  -> Const (Endo [ModItem ReduceAnn]) [ModDecl ReduceAnn])
 -> Verilog ReduceAnn
 -> Const (Endo [ModItem ReduceAnn]) (Verilog ReduceAnn))
-> ((ModItem ReduceAnn
     -> Const (Endo [ModItem ReduceAnn]) (ModItem ReduceAnn))
    -> [ModDecl ReduceAnn]
    -> Const (Endo [ModItem ReduceAnn]) [ModDecl ReduceAnn])
-> (ModItem ReduceAnn
    -> Const (Endo [ModItem ReduceAnn]) (ModItem ReduceAnn))
-> Verilog ReduceAnn
-> Const (Endo [ModItem ReduceAnn]) (Verilog ReduceAnn)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ModDecl ReduceAnn
 -> Const (Endo [ModItem ReduceAnn]) (ModDecl ReduceAnn))
-> [ModDecl ReduceAnn]
-> Const (Endo [ModItem ReduceAnn]) [ModDecl ReduceAnn]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ((ModDecl ReduceAnn
  -> Const (Endo [ModItem ReduceAnn]) (ModDecl ReduceAnn))
 -> [ModDecl ReduceAnn]
 -> Const (Endo [ModItem ReduceAnn]) [ModDecl ReduceAnn])
-> Getting
     (Endo [ModItem ReduceAnn]) (ModDecl ReduceAnn) (ModItem ReduceAnn)
-> (ModItem ReduceAnn
    -> Const (Endo [ModItem ReduceAnn]) (ModItem ReduceAnn))
-> [ModDecl ReduceAnn]
-> Const (Endo [ModItem ReduceAnn]) [ModDecl ReduceAnn]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([ModItem ReduceAnn]
 -> Const (Endo [ModItem ReduceAnn]) [ModItem ReduceAnn])
-> ModDecl ReduceAnn
-> Const (Endo [ModItem ReduceAnn]) (ModDecl ReduceAnn)
forall a (f :: * -> *).
Applicative f =>
([ModItem a] -> f [ModItem a]) -> ModDecl a -> f (ModDecl a)
modItems (([ModItem ReduceAnn]
  -> Const (Endo [ModItem ReduceAnn]) [ModItem ReduceAnn])
 -> ModDecl ReduceAnn
 -> Const (Endo [ModItem ReduceAnn]) (ModDecl ReduceAnn))
-> ((ModItem ReduceAnn
     -> Const (Endo [ModItem ReduceAnn]) (ModItem ReduceAnn))
    -> [ModItem ReduceAnn]
    -> Const (Endo [ModItem ReduceAnn]) [ModItem ReduceAnn])
-> Getting
     (Endo [ModItem ReduceAnn]) (ModDecl ReduceAnn) (ModItem ReduceAnn)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ModItem ReduceAnn
 -> Const (Endo [ModItem ReduceAnn]) (ModItem ReduceAnn))
-> [ModItem ReduceAnn]
-> Const (Endo [ModItem ReduceAnn]) [ModItem ReduceAnn]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse))
      Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
", loc: "
      Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Int -> Text
forall a. Show a => a -> Text
showT ([String] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([String] -> Int) -> (Text -> [String]) -> Text -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String]
lines (String -> [String]) -> (Text -> String) -> Text -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
unpack (Text -> Int) -> Text -> Int
forall a b. (a -> b) -> a -> b
$ SourceInfo ReduceAnn -> Text
forall a. Source a => a -> Text
genSource SourceInfo ReduceAnn
usrc)
      Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")"
  if SourceInfo ReduceAnn -> Bool
bot SourceInfo ReduceAnn
src
    then SourceInfo ReduceAnn -> m (SourceInfo ReduceAnn)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (SourceInfo ReduceAnn -> m (SourceInfo ReduceAnn))
-> SourceInfo ReduceAnn -> m (SourceInfo ReduceAnn)
forall a b. (a -> b) -> a -> b
$ SourceInfo ReduceAnn -> SourceInfo ReduceAnn
untag SourceInfo ReduceAnn
src
    else case Replace (SourceInfo ReduceAnn)
repl SourceInfo ReduceAnn
src of
      Single SourceInfo ReduceAnn
s -> do
        Bool
red <- SourceInfo ReduceAnn -> m Bool
eval SourceInfo ReduceAnn
s
        if Bool
red
          then if SourceInfo ReduceAnn
s SourceInfo ReduceAnn -> SourceInfo ReduceAnn -> Bool
forall a. Eq a => a -> a -> Bool
/= SourceInfo ReduceAnn
src then SourceInfo ReduceAnn -> m (SourceInfo ReduceAnn)
recReduction SourceInfo ReduceAnn
s else SourceInfo ReduceAnn -> m (SourceInfo ReduceAnn)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (SourceInfo ReduceAnn -> m (SourceInfo ReduceAnn))
-> SourceInfo ReduceAnn -> m (SourceInfo ReduceAnn)
forall a b. (a -> b) -> a -> b
$ SourceInfo ReduceAnn -> SourceInfo ReduceAnn
untag SourceInfo ReduceAnn
src
          else SourceInfo ReduceAnn -> m (SourceInfo ReduceAnn)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (SourceInfo ReduceAnn -> m (SourceInfo ReduceAnn))
-> SourceInfo ReduceAnn -> m (SourceInfo ReduceAnn)
forall a b. (a -> b) -> a -> b
$ SourceInfo ReduceAnn -> SourceInfo ReduceAnn
untag SourceInfo ReduceAnn
src
      Dual SourceInfo ReduceAnn
l SourceInfo ReduceAnn
r -> do
        Bool
red <- SourceInfo ReduceAnn -> m Bool
eval SourceInfo ReduceAnn
l
        if Bool
red
          then if SourceInfo ReduceAnn
l SourceInfo ReduceAnn -> SourceInfo ReduceAnn -> Bool
forall a. Eq a => a -> a -> Bool
/= SourceInfo ReduceAnn
src then SourceInfo ReduceAnn -> m (SourceInfo ReduceAnn)
recReduction SourceInfo ReduceAnn
l else SourceInfo ReduceAnn -> m (SourceInfo ReduceAnn)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (SourceInfo ReduceAnn -> m (SourceInfo ReduceAnn))
-> SourceInfo ReduceAnn -> m (SourceInfo ReduceAnn)
forall a b. (a -> b) -> a -> b
$ SourceInfo ReduceAnn -> SourceInfo ReduceAnn
untag SourceInfo ReduceAnn
src
          else do
            Bool
red' <- SourceInfo ReduceAnn -> m Bool
eval SourceInfo ReduceAnn
r
            if Bool
red'
              then if SourceInfo ReduceAnn
r SourceInfo ReduceAnn -> SourceInfo ReduceAnn -> Bool
forall a. Eq a => a -> a -> Bool
/= SourceInfo ReduceAnn
src then SourceInfo ReduceAnn -> m (SourceInfo ReduceAnn)
recReduction SourceInfo ReduceAnn
r else SourceInfo ReduceAnn -> m (SourceInfo ReduceAnn)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (SourceInfo ReduceAnn -> m (SourceInfo ReduceAnn))
-> SourceInfo ReduceAnn -> m (SourceInfo ReduceAnn)
forall a b. (a -> b) -> a -> b
$ SourceInfo ReduceAnn -> SourceInfo ReduceAnn
untag SourceInfo ReduceAnn
src
              else SourceInfo ReduceAnn -> m (SourceInfo ReduceAnn)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (SourceInfo ReduceAnn -> m (SourceInfo ReduceAnn))
-> SourceInfo ReduceAnn -> m (SourceInfo ReduceAnn)
forall a b. (a -> b) -> a -> b
$ SourceInfo ReduceAnn -> SourceInfo ReduceAnn
untag SourceInfo ReduceAnn
src
      Replacement (SourceInfo ReduceAnn)
None -> SourceInfo ReduceAnn -> m (SourceInfo ReduceAnn)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (SourceInfo ReduceAnn -> m (SourceInfo ReduceAnn))
-> SourceInfo ReduceAnn -> m (SourceInfo ReduceAnn)
forall a b. (a -> b) -> a -> b
$ SourceInfo ReduceAnn -> SourceInfo ReduceAnn
untag SourceInfo ReduceAnn
src
  where
    src :: SourceInfo ReduceAnn
src = SourceInfo ReduceAnn -> SourceInfo ReduceAnn
tag SourceInfo ReduceAnn
usrc
    recReduction :: SourceInfo ReduceAnn -> m (SourceInfo ReduceAnn)
recReduction = String
-> (SourceInfo ReduceAnn -> m Bool)
-> Text
-> (SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> (SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> Replace (SourceInfo ReduceAnn)
-> (SourceInfo ReduceAnn -> Bool)
-> SourceInfo ReduceAnn
-> m (SourceInfo ReduceAnn)
forall (m :: * -> *).
MonadSh m =>
String
-> (SourceInfo ReduceAnn -> m Bool)
-> Text
-> (SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> (SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> Replace (SourceInfo ReduceAnn)
-> (SourceInfo ReduceAnn -> Bool)
-> SourceInfo ReduceAnn
-> m (SourceInfo ReduceAnn)
reduce_ String
out SourceInfo ReduceAnn -> m Bool
eval Text
title SourceInfo ReduceAnn -> SourceInfo ReduceAnn
tag SourceInfo ReduceAnn -> SourceInfo ReduceAnn
untag Replace (SourceInfo ReduceAnn)
repl SourceInfo ReduceAnn -> Bool
bot

-- | Reduce an input to a minimal representation. It follows the reduction
-- strategy mentioned above.
reduce ::
  (MonadSh m) =>
  -- | Filepath for temporary file.
  Shelly.FilePath ->
  -- | Failed or not.
  (SourceInfo ReduceAnn -> m Bool) ->
  -- | Input verilog source to be reduced.
  SourceInfo () ->
  -- | Reduced output.
  m (SourceInfo ())
reduce :: forall (m :: * -> *).
MonadSh m =>
String
-> (SourceInfo ReduceAnn -> m Bool)
-> SourceInfo ()
-> m (SourceInfo ())
reduce String
fp SourceInfo ReduceAnn -> m Bool
eval SourceInfo ()
rsrc =
  (SourceInfo ReduceAnn -> SourceInfo ())
-> m (SourceInfo ReduceAnn) -> m (SourceInfo ())
forall a b. (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap SourceInfo ReduceAnn -> SourceInfo ()
forall a. SourceInfo a -> SourceInfo ()
forall (m :: * -> *) a. Annotations m => m a -> m ()
clearAnn (m (SourceInfo ReduceAnn) -> m (SourceInfo ()))
-> m (SourceInfo ReduceAnn) -> m (SourceInfo ())
forall a b. (a -> b) -> a -> b
$
    Text
-> (SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> (SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> Replace (SourceInfo ReduceAnn)
-> (SourceInfo ReduceAnn -> Bool)
-> SourceInfo ReduceAnn
-> m (SourceInfo ReduceAnn)
red Text
"Modules" SourceInfo ReduceAnn -> SourceInfo ReduceAnn
forall a. a -> a
id SourceInfo ReduceAnn -> SourceInfo ReduceAnn
forall a. a -> a
id Replace (SourceInfo ReduceAnn)
halveModules SourceInfo ReduceAnn -> Bool
moduleBot SourceInfo ReduceAnn
src
      m (SourceInfo ReduceAnn)
-> (SourceInfo ReduceAnn -> m (SourceInfo ReduceAnn))
-> m (SourceInfo ReduceAnn)
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Text
-> (Identifier -> SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> (Identifier -> SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> (Identifier -> Replace (SourceInfo ReduceAnn))
-> (Identifier -> SourceInfo ReduceAnn -> Bool)
-> SourceInfo ReduceAnn
-> m (SourceInfo ReduceAnn)
redAll Text
"Module items" Identifier -> SourceInfo ReduceAnn -> SourceInfo ReduceAnn
idTag Identifier -> SourceInfo ReduceAnn -> SourceInfo ReduceAnn
idTag Identifier -> Replace (SourceInfo ReduceAnn)
halveModItems Identifier -> SourceInfo ReduceAnn -> Bool
modItemBot
      m (SourceInfo ReduceAnn)
-> (SourceInfo ReduceAnn -> m (SourceInfo ReduceAnn))
-> m (SourceInfo ReduceAnn)
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Text
-> (Identifier -> SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> (Identifier -> SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> (Identifier -> Replace (SourceInfo ReduceAnn))
-> (Identifier -> SourceInfo ReduceAnn -> Bool)
-> SourceInfo ReduceAnn
-> m (SourceInfo ReduceAnn)
redAll Text
"Statements" Identifier -> SourceInfo ReduceAnn -> SourceInfo ReduceAnn
tagAlways Identifier -> SourceInfo ReduceAnn -> SourceInfo ReduceAnn
untagAlways Identifier -> Replace (SourceInfo ReduceAnn)
halveStatements ((SourceInfo ReduceAnn -> Bool)
-> Identifier -> SourceInfo ReduceAnn -> Bool
forall a b. a -> b -> a
const SourceInfo ReduceAnn -> Bool
defaultBot)
      -- >>= redAll "Expressions" halveExpr (const defaultBot)
      m (SourceInfo ReduceAnn)
-> (SourceInfo ReduceAnn -> m (SourceInfo ReduceAnn))
-> m (SourceInfo ReduceAnn)
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Text
-> (SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> (SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> Replace (SourceInfo ReduceAnn)
-> (SourceInfo ReduceAnn -> Bool)
-> SourceInfo ReduceAnn
-> m (SourceInfo ReduceAnn)
red Text
"Remove constants in concat" SourceInfo ReduceAnn -> SourceInfo ReduceAnn
forall a. a -> a
id SourceInfo ReduceAnn -> SourceInfo ReduceAnn
forall a. a -> a
id Replace (SourceInfo ReduceAnn)
removeConstInConcat SourceInfo ReduceAnn -> Bool
defaultBot
      m (SourceInfo ReduceAnn)
-> (SourceInfo ReduceAnn -> m (SourceInfo ReduceAnn))
-> m (SourceInfo ReduceAnn)
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Text
-> (SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> (SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> Replace (SourceInfo ReduceAnn)
-> (SourceInfo ReduceAnn -> Bool)
-> SourceInfo ReduceAnn
-> m (SourceInfo ReduceAnn)
red Text
"Cleaning" SourceInfo ReduceAnn -> SourceInfo ReduceAnn
forall a. a -> a
id SourceInfo ReduceAnn -> SourceInfo ReduceAnn
forall a. a -> a
id (Replace (SourceInfo ReduceAnn)
forall a. a -> Replacement a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Replace (SourceInfo ReduceAnn)
-> (SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> Replace (SourceInfo ReduceAnn)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SourceInfo ReduceAnn -> SourceInfo ReduceAnn
removeDecl) SourceInfo ReduceAnn -> Bool
defaultBot
  where
    red :: Text
-> (SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> (SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> Replace (SourceInfo ReduceAnn)
-> (SourceInfo ReduceAnn -> Bool)
-> SourceInfo ReduceAnn
-> m (SourceInfo ReduceAnn)
red = String
-> (SourceInfo ReduceAnn -> m Bool)
-> Text
-> (SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> (SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> Replace (SourceInfo ReduceAnn)
-> (SourceInfo ReduceAnn -> Bool)
-> SourceInfo ReduceAnn
-> m (SourceInfo ReduceAnn)
forall (m :: * -> *).
MonadSh m =>
String
-> (SourceInfo ReduceAnn -> m Bool)
-> Text
-> (SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> (SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> Replace (SourceInfo ReduceAnn)
-> (SourceInfo ReduceAnn -> Bool)
-> SourceInfo ReduceAnn
-> m (SourceInfo ReduceAnn)
reduce_ String
fp SourceInfo ReduceAnn -> m Bool
eval
    redAll :: Text
-> (Identifier -> SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> (Identifier -> SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> (Identifier -> Replace (SourceInfo ReduceAnn))
-> (Identifier -> SourceInfo ReduceAnn -> Bool)
-> SourceInfo ReduceAnn
-> m (SourceInfo ReduceAnn)
redAll Text
s Identifier -> SourceInfo ReduceAnn -> SourceInfo ReduceAnn
tag Identifier -> SourceInfo ReduceAnn -> SourceInfo ReduceAnn
untag Identifier -> Replace (SourceInfo ReduceAnn)
halve' Identifier -> SourceInfo ReduceAnn -> Bool
bot SourceInfo ReduceAnn
src' =
      (Identifier -> SourceInfo ReduceAnn -> m (SourceInfo ReduceAnn))
-> SourceInfo ReduceAnn -> [Identifier] -> m (SourceInfo ReduceAnn)
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> b -> m b) -> b -> t a -> m b
foldrM
        (\Identifier
t -> Text
-> (SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> (SourceInfo ReduceAnn -> SourceInfo ReduceAnn)
-> Replace (SourceInfo ReduceAnn)
-> (SourceInfo ReduceAnn -> Bool)
-> SourceInfo ReduceAnn
-> m (SourceInfo ReduceAnn)
red (Text
s Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" (" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Identifier -> Text
getIdentifier Identifier
t Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")") (Identifier -> SourceInfo ReduceAnn -> SourceInfo ReduceAnn
tag Identifier
t) (Identifier -> SourceInfo ReduceAnn -> SourceInfo ReduceAnn
untag Identifier
t) (Identifier -> Replace (SourceInfo ReduceAnn)
halve' Identifier
t) (Identifier -> SourceInfo ReduceAnn -> Bool
bot Identifier
t))
        SourceInfo ReduceAnn
src'
        (SourceInfo ReduceAnn
src' SourceInfo ReduceAnn
-> Getting (Endo [Identifier]) (SourceInfo ReduceAnn) Identifier
-> [Identifier]
forall s a. s -> Getting (Endo [a]) s a -> [a]
^.. (Verilog ReduceAnn
 -> Const (Endo [Identifier]) (Verilog ReduceAnn))
-> SourceInfo ReduceAnn
-> Const (Endo [Identifier]) (SourceInfo ReduceAnn)
forall a1 a2 (f :: * -> *).
Functor f =>
(Verilog a1 -> f (Verilog a2))
-> SourceInfo a1 -> f (SourceInfo a2)
infoSrc ((Verilog ReduceAnn
  -> Const (Endo [Identifier]) (Verilog ReduceAnn))
 -> SourceInfo ReduceAnn
 -> Const (Endo [Identifier]) (SourceInfo ReduceAnn))
-> ((Identifier -> Const (Endo [Identifier]) Identifier)
    -> Verilog ReduceAnn
    -> Const (Endo [Identifier]) (Verilog ReduceAnn))
-> Getting (Endo [Identifier]) (SourceInfo ReduceAnn) Identifier
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([ModDecl ReduceAnn]
 -> Const (Endo [Identifier]) [ModDecl ReduceAnn])
-> Verilog ReduceAnn
-> Const (Endo [Identifier]) (Verilog ReduceAnn)
(Unwrapped (Verilog ReduceAnn)
 -> Const (Endo [Identifier]) (Unwrapped (Verilog ReduceAnn)))
-> Verilog ReduceAnn
-> Const (Endo [Identifier]) (Verilog ReduceAnn)
forall s t. Rewrapping s t => Iso s t (Unwrapped s) (Unwrapped t)
Iso
  (Verilog ReduceAnn)
  (Verilog ReduceAnn)
  (Unwrapped (Verilog ReduceAnn))
  (Unwrapped (Verilog ReduceAnn))
_Wrapped (([ModDecl ReduceAnn]
  -> Const (Endo [Identifier]) [ModDecl ReduceAnn])
 -> Verilog ReduceAnn
 -> Const (Endo [Identifier]) (Verilog ReduceAnn))
-> ((Identifier -> Const (Endo [Identifier]) Identifier)
    -> [ModDecl ReduceAnn]
    -> Const (Endo [Identifier]) [ModDecl ReduceAnn])
-> (Identifier -> Const (Endo [Identifier]) Identifier)
-> Verilog ReduceAnn
-> Const (Endo [Identifier]) (Verilog ReduceAnn)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ModDecl ReduceAnn
 -> Const (Endo [Identifier]) (ModDecl ReduceAnn))
-> [ModDecl ReduceAnn]
-> Const (Endo [Identifier]) [ModDecl ReduceAnn]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ((ModDecl ReduceAnn
  -> Const (Endo [Identifier]) (ModDecl ReduceAnn))
 -> [ModDecl ReduceAnn]
 -> Const (Endo [Identifier]) [ModDecl ReduceAnn])
-> Getting (Endo [Identifier]) (ModDecl ReduceAnn) Identifier
-> (Identifier -> Const (Endo [Identifier]) Identifier)
-> [ModDecl ReduceAnn]
-> Const (Endo [Identifier]) [ModDecl ReduceAnn]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Getting (Endo [Identifier]) (ModDecl ReduceAnn) Identifier
forall a (f :: * -> *).
Applicative f =>
(Identifier -> f Identifier) -> ModDecl a -> f (ModDecl a)
modId)
    src :: SourceInfo ReduceAnn
src = (() -> ReduceAnn) -> SourceInfo () -> SourceInfo ReduceAnn
forall a b. (a -> b) -> SourceInfo a -> SourceInfo b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\()
_ -> ReduceAnn
Idle) SourceInfo ()
rsrc

runScript ::
  (MonadSh m, Show ann) =>
  Shelly.FilePath ->
  Shelly.FilePath ->
  (SourceInfo ann) ->
  m Bool
runScript :: forall (m :: * -> *) ann.
(MonadSh m, Show ann) =>
String -> String -> SourceInfo ann -> m Bool
runScript String
fp String
file SourceInfo ann
src = do
  Int
e <- Sh Int -> m Int
forall a. Sh a -> m a
forall (m :: * -> *) a. MonadSh m => Sh a -> m a
liftSh (Sh Int -> m Int) -> Sh Int -> m Int
forall a b. (a -> b) -> a -> b
$ do
    String -> Text -> Sh ()
Shelly.writefile String
file (Text -> Sh ()) -> Text -> Sh ()
forall a b. (a -> b) -> a -> b
$ SourceInfo ann -> Text
forall a. Source a => a -> Text
genSource SourceInfo ann
src
    Sh () -> Sh ()
forall a. Sh a -> Sh a
noPrint (Sh () -> Sh ()) -> (Sh () -> Sh ()) -> Sh () -> Sh ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Sh () -> Sh ()
forall a. Bool -> Sh a -> Sh a
Shelly.errExit Bool
False (Sh () -> Sh ()) -> Sh () -> Sh ()
forall a b. (a -> b) -> a -> b
$ String -> [Text] -> Sh ()
Shelly.run_ String
fp []
    Sh Int
Shelly.lastExitCode
  Bool -> m Bool
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool -> m Bool) -> Bool -> m Bool
forall a b. (a -> b) -> a -> b
$ Int
e Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0

-- | Reduce using a script that is passed to it
reduceWithScript ::
  (MonadSh m, MonadIO m) =>
  Text ->
  Shelly.FilePath ->
  Shelly.FilePath ->
  m ()
reduceWithScript :: forall (m :: * -> *).
(MonadSh m, MonadIO m) =>
Text -> String -> String -> m ()
reduceWithScript Text
top String
script String
file = do
  Sh () -> m ()
forall a. Sh a -> m a
forall (m :: * -> *) a. MonadSh m => Sh a -> m a
liftSh (Sh () -> m ()) -> (String -> Sh ()) -> String -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String -> Sh ()
Shelly.cp String
file (String -> m ()) -> String -> m ()
forall a b. (a -> b) -> a -> b
$ String
file String -> Text -> String
forall filepath. ToFilePath filepath => filepath -> Text -> String
<.> Text
"original"
  (SourceInfo ()
srcInfo :: SourceInfo ()) <- IO (SourceInfo ()) -> m (SourceInfo ())
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (SourceInfo ()) -> m (SourceInfo ()))
-> (Text -> IO (SourceInfo ())) -> Text -> m (SourceInfo ())
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text -> IO (SourceInfo ())
forall ann. Text -> Text -> IO (SourceInfo ann)
parseSourceInfoFile Text
top (Text -> m (SourceInfo ())) -> Text -> m (SourceInfo ())
forall a b. (a -> b) -> a -> b
$ String -> Text
Shelly.toTextIgnore String
file
  m (SourceInfo ()) -> m ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (m (SourceInfo ()) -> m ()) -> m (SourceInfo ()) -> m ()
forall a b. (a -> b) -> a -> b
$ String
-> (SourceInfo ReduceAnn -> m Bool)
-> SourceInfo ()
-> m (SourceInfo ())
forall (m :: * -> *).
MonadSh m =>
String
-> (SourceInfo ReduceAnn -> m Bool)
-> SourceInfo ()
-> m (SourceInfo ())
reduce (Text -> String
fromText Text
"reduce_script.v") (String -> String -> SourceInfo ReduceAnn -> m Bool
forall (m :: * -> *) ann.
(MonadSh m, Show ann) =>
String -> String -> SourceInfo ann -> m Bool
runScript String
script String
file) SourceInfo ()
srcInfo

-- | Reduce a '(SourceInfo ReduceAnn)' using two 'Synthesiser' that are passed to it.
reduceSynth ::
  (Synthesiser a, Synthesiser b, MonadSh m) =>
  Maybe Text ->
  Shelly.FilePath ->
  a ->
  b ->
  SourceInfo () ->
  m (SourceInfo ())
reduceSynth :: forall a b (m :: * -> *).
(Synthesiser a, Synthesiser b, MonadSh m) =>
Maybe Text
-> String -> a -> b -> SourceInfo () -> m (SourceInfo ())
reduceSynth Maybe Text
mt String
datadir a
a b
b SourceInfo ()
src = do
  IORef Int
counter <- Sh (IORef Int) -> m (IORef Int)
forall a. Sh a -> m a
forall (m :: * -> *) a. MonadSh m => Sh a -> m a
liftSh (Sh (IORef Int) -> m (IORef Int))
-> (IO (IORef Int) -> Sh (IORef Int))
-> IO (IORef Int)
-> m (IORef Int)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO (IORef Int) -> Sh (IORef Int)
forall a. IO a -> Sh a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (IORef Int) -> m (IORef Int))
-> IO (IORef Int) -> m (IORef Int)
forall a b. (a -> b) -> a -> b
$ Int -> IO (IORef Int)
forall a. a -> IO (IORef a)
newIORef (Int
0 :: Int)
  String
-> (SourceInfo ReduceAnn -> m Bool)
-> SourceInfo ()
-> m (SourceInfo ())
forall (m :: * -> *).
MonadSh m =>
String
-> (SourceInfo ReduceAnn -> m Bool)
-> SourceInfo ()
-> m (SourceInfo ())
reduce (Text -> String
fromText (Text -> String) -> Text -> String
forall a b. (a -> b) -> a -> b
$ Text
prefix Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
".v") (IORef Int -> SourceInfo ReduceAnn -> m Bool
forall {m :: * -> *} {a} {ann}.
(MonadSh m, Num a, Show a, Show ann) =>
IORef a -> SourceInfo ann -> m Bool
synth IORef Int
counter) SourceInfo ()
src
  where
    synth :: IORef a -> SourceInfo ann -> m Bool
synth IORef a
counter SourceInfo ann
src' = Sh Bool -> m Bool
forall a. Sh a -> m a
forall (m :: * -> *) a. MonadSh m => Sh a -> m a
liftSh (Sh Bool -> m Bool) -> Sh Bool -> m Bool
forall a b. (a -> b) -> a -> b
$ do
      a
count <- IO a -> Sh a
forall a. IO a -> Sh a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO a -> Sh a) -> IO a -> Sh a
forall a b. (a -> b) -> a -> b
$ IORef a -> IO a
forall a. IORef a -> IO a
readIORef IORef a
counter
      IO () -> Sh ()
forall a. IO a -> Sh a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> Sh ()) -> IO () -> Sh ()
forall a b. (a -> b) -> a -> b
$ IORef a -> a -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef a
counter (a
count a -> a -> a
forall a. Num a => a -> a -> a
+ a
1)
      String -> Sh ()
Shelly.mkdir (Text -> String
fromText (Text -> String) -> Text -> String
forall a b. (a -> b) -> a -> b
$ Text
prefix Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"_" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> a -> Text
forall a. Show a => a -> Text
showT a
count)
      String
current_dir <- Sh String
Shelly.pwd
      String -> Sh ()
Shelly.cd (Text -> String
fromText (Text -> String) -> Text -> String
forall a b. (a -> b) -> a -> b
$ Text
prefix Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"_" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> a -> Text
forall a. Show a => a -> Text
showT a
count)
      Result Failed ()
r <- ResultT Failed Sh () -> Sh (Result Failed ())
forall a (m :: * -> *) b. ResultT a m b -> m (Result a b)
runResultT (ResultT Failed Sh () -> Sh (Result Failed ()))
-> ResultT Failed Sh () -> Sh (Result Failed ())
forall a b. (a -> b) -> a -> b
$ do
        a -> SourceInfo ann -> ResultT Failed Sh ()
forall ann. Show ann => a -> SourceInfo ann -> ResultT Failed Sh ()
forall a ann.
(Synthesiser a, Show ann) =>
a -> SourceInfo ann -> ResultT Failed Sh ()
runSynth a
a SourceInfo ann
src'
        b -> SourceInfo ann -> ResultT Failed Sh ()
forall ann. Show ann => b -> SourceInfo ann -> ResultT Failed Sh ()
forall a ann.
(Synthesiser a, Show ann) =>
a -> SourceInfo ann -> ResultT Failed Sh ()
runSynth b
b SourceInfo ann
src'
        Maybe Text
-> String -> a -> b -> SourceInfo ann -> ResultT Failed Sh ()
forall a b ann.
(Synthesiser a, Synthesiser b, Show ann) =>
Maybe Text
-> String -> a -> b -> SourceInfo ann -> ResultT Failed Sh ()
runEquiv Maybe Text
mt String
datadir a
a b
b SourceInfo ann
src'
      String -> Sh ()
Shelly.cd String
current_dir
      Bool -> Sh Bool
forall a. a -> Sh a
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool -> Sh Bool) -> Bool -> Sh Bool
forall a b. (a -> b) -> a -> b
$ case Result Failed ()
r of
        Fail (EquivFail Maybe CounterEg
_) -> Bool
True
        Result Failed ()
_ -> Bool
False
    prefix :: Text
prefix = Text
"reduce_" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> a -> Text
forall a. Tool a => a -> Text
toText a
a Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"_" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> b -> Text
forall a. Tool a => a -> Text
toText b
b

reduceSynthesis :: (Synthesiser a, MonadSh m) => a -> SourceInfo () -> m (SourceInfo ())
reduceSynthesis :: forall a (m :: * -> *).
(Synthesiser a, MonadSh m) =>
a -> SourceInfo () -> m (SourceInfo ())
reduceSynthesis a
a = String
-> (SourceInfo ReduceAnn -> m Bool)
-> SourceInfo ()
-> m (SourceInfo ())
forall (m :: * -> *).
MonadSh m =>
String
-> (SourceInfo ReduceAnn -> m Bool)
-> SourceInfo ()
-> m (SourceInfo ())
reduce (Text -> String
fromText (Text -> String) -> Text -> String
forall a b. (a -> b) -> a -> b
$ Text
"reduce_" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> a -> Text
forall a. Tool a => a -> Text
toText a
a Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
".v") SourceInfo ReduceAnn -> m Bool
forall {m :: * -> *} {ann}.
(MonadSh m, Show ann) =>
SourceInfo ann -> m Bool
synth
  where
    synth :: SourceInfo ann -> m Bool
synth SourceInfo ann
src = Sh Bool -> m Bool
forall a. Sh a -> m a
forall (m :: * -> *) a. MonadSh m => Sh a -> m a
liftSh (Sh Bool -> m Bool) -> Sh Bool -> m Bool
forall a b. (a -> b) -> a -> b
$ do
      Result Failed ()
r <- ResultT Failed Sh () -> Sh (Result Failed ())
forall a (m :: * -> *) b. ResultT a m b -> m (Result a b)
runResultT (ResultT Failed Sh () -> Sh (Result Failed ()))
-> ResultT Failed Sh () -> Sh (Result Failed ())
forall a b. (a -> b) -> a -> b
$ a -> SourceInfo ann -> ResultT Failed Sh ()
forall ann. Show ann => a -> SourceInfo ann -> ResultT Failed Sh ()
forall a ann.
(Synthesiser a, Show ann) =>
a -> SourceInfo ann -> ResultT Failed Sh ()
runSynth a
a SourceInfo ann
src
      Bool -> Sh Bool
forall a. a -> Sh a
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool -> Sh Bool) -> Bool -> Sh Bool
forall a b. (a -> b) -> a -> b
$ case Result Failed ()
r of
        Fail Failed
SynthFail -> Bool
True
        Result Failed ()
_ -> Bool
False

runInTmp :: Shelly.Sh a -> Shelly.Sh a
runInTmp :: forall a. Sh a -> Sh a
runInTmp Sh a
a =
  (String -> Sh a) -> Sh a
forall a. (String -> Sh a) -> Sh a
Shelly.withTmpDir ((String -> Sh a) -> Sh a) -> (String -> Sh a) -> Sh a
forall a b. (a -> b) -> a -> b
$
    ( \String
f -> do
        String
dir <- Sh String
Shelly.pwd
        String -> Sh ()
Shelly.cd String
f
        a
r <- Sh a
a
        String -> Sh ()
Shelly.cd String
dir
        a -> Sh a
forall a. a -> Sh a
forall (m :: * -> *) a. Monad m => a -> m a
return a
r
    )

reduceSimIc ::
  (Synthesiser a, MonadSh m) =>
  Shelly.FilePath ->
  [ByteString] ->
  a ->
  SourceInfo () ->
  m (SourceInfo ())
reduceSimIc :: forall a (m :: * -> *).
(Synthesiser a, MonadSh m) =>
String -> [ByteString] -> a -> SourceInfo () -> m (SourceInfo ())
reduceSimIc String
fp [ByteString]
bs a
a = String
-> (SourceInfo ReduceAnn -> m Bool)
-> SourceInfo ()
-> m (SourceInfo ())
forall (m :: * -> *).
MonadSh m =>
String
-> (SourceInfo ReduceAnn -> m Bool)
-> SourceInfo ()
-> m (SourceInfo ())
reduce (Text -> String
fromText (Text -> String) -> Text -> String
forall a b. (a -> b) -> a -> b
$ Text
"reduce_sim_" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> a -> Text
forall a. Tool a => a -> Text
toText a
a Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
".v") SourceInfo ReduceAnn -> m Bool
forall {m :: * -> *} {ann}.
(MonadSh m, Show ann) =>
SourceInfo ann -> m Bool
synth
  where
    synth :: SourceInfo ann -> m Bool
synth SourceInfo ann
src = Sh Bool -> m Bool
forall a. Sh a -> m a
forall (m :: * -> *) a. MonadSh m => Sh a -> m a
liftSh (Sh Bool -> m Bool) -> (Sh Bool -> Sh Bool) -> Sh Bool -> m Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Sh Bool -> Sh Bool
forall a. Sh a -> Sh a
runInTmp (Sh Bool -> m Bool) -> Sh Bool -> m Bool
forall a b. (a -> b) -> a -> b
$ do
      Result Failed ByteString
r <- ResultT Failed Sh ByteString -> Sh (Result Failed ByteString)
forall a (m :: * -> *) b. ResultT a m b -> m (Result a b)
runResultT (ResultT Failed Sh ByteString -> Sh (Result Failed ByteString))
-> ResultT Failed Sh ByteString -> Sh (Result Failed ByteString)
forall a b. (a -> b) -> a -> b
$ do
        a -> SourceInfo ann -> ResultT Failed Sh ()
forall ann. Show ann => a -> SourceInfo ann -> ResultT Failed Sh ()
forall a ann.
(Synthesiser a, Show ann) =>
a -> SourceInfo ann -> ResultT Failed Sh ()
runSynth a
a SourceInfo ann
src
        Identity -> SourceInfo ann -> ResultT Failed Sh ()
forall ann.
Show ann =>
Identity -> SourceInfo ann -> ResultT Failed Sh ()
forall a ann.
(Synthesiser a, Show ann) =>
a -> SourceInfo ann -> ResultT Failed Sh ()
runSynth Identity
defaultIdentity SourceInfo ann
src
        ByteString
i <- String
-> Icarus
-> Identity
-> SourceInfo ann
-> [ByteString]
-> Maybe ByteString
-> ResultT Failed Sh ByteString
forall b ann.
(Synthesiser b, Show ann) =>
String
-> Icarus
-> b
-> SourceInfo ann
-> [ByteString]
-> Maybe ByteString
-> ResultT Failed Sh ByteString
runSimIc String
fp Icarus
defaultIcarus Identity
defaultIdentity SourceInfo ann
src [ByteString]
bs Maybe ByteString
forall a. Maybe a
Nothing
        String
-> Icarus
-> a
-> SourceInfo ann
-> [ByteString]
-> Maybe ByteString
-> ResultT Failed Sh ByteString
forall b ann.
(Synthesiser b, Show ann) =>
String
-> Icarus
-> b
-> SourceInfo ann
-> [ByteString]
-> Maybe ByteString
-> ResultT Failed Sh ByteString
runSimIc String
fp Icarus
defaultIcarus a
a SourceInfo ann
src [ByteString]
bs (Maybe ByteString -> ResultT Failed Sh ByteString)
-> Maybe ByteString -> ResultT Failed Sh ByteString
forall a b. (a -> b) -> a -> b
$ ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just ByteString
i
      Bool -> Sh Bool
forall a. a -> Sh a
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool -> Sh Bool) -> Bool -> Sh Bool
forall a b. (a -> b) -> a -> b
$ case Result Failed ByteString
r of
        Fail (SimFail ByteString
_) -> Bool
True
        Result Failed ByteString
_ -> Bool
False