packages feed

abcBridge 0.11 → 0.12

raw patch · 10 files changed

+231/−111 lines, 10 filesdep +randomdep +tf-randomdep +unixdep ~aigdep ~basedep ~tasty-quickchecksetup-changednew-component:exe:find-segfaultPVP ok

version bump matches the API change (PVP)

Dependencies added: random, tf-random, unix

Dependency ranges changed: aig, base, tasty-quickcheck

API changes (from Hackage documentation)

- Data.ABC.Internal.GIA: giaManRegNum :: Gia_Man_t -> IO CInt
+ Data.ABC.GIA: writeAigerWithLatches :: FilePath -> Network Lit GIA -> Int -> IO ()
+ Data.ABC.Internal.GIA: getGiaManRegNum :: Gia_Man_t -> IO CInt
+ Data.ABC.Internal.GIA: setGiaManRegNum :: Gia_Man_t -> CInt -> IO ()
- Data.ABC.GIA: Input :: UnpkInt -> LitView a
+ Data.ABC.GIA: Input :: SrictNotUnpackedInt -> LitView a
- Data.ABC.GIA: NotInput :: UnpkInt -> LitView a
+ Data.ABC.GIA: NotInput :: SrictNotUnpackedInt -> LitView a
- Data.ABC.GIA: check_exists_forall :: GIA s -> Int -> Lit s -> [Bool] -> Int -> IO (Either String SatResult)
+ Data.ABC.GIA: check_exists_forall :: GIA s -> Int -> Lit s -> [Bool] -> CInt -> IO (Either String SatResult)
- Data.ABC.Internal.ABC: abcNtkQbf :: (Abc_Ntk_t) -> (Int) -> (Int) -> (Vec_Int_t) -> IO ((Int))
+ Data.ABC.Internal.ABC: abcNtkQbf :: (Abc_Ntk_t) -> (Int) -> (CInt) -> (Vec_Int_t) -> IO ((Int))

Files

Setup.hs view
@@ -9,6 +9,7 @@         updatePackageDescription, FlagAssignment(..), FlagName(..)) import Distribution.Verbosity (verbose, Verbosity(..)) import Distribution.System (OS(..), Arch(..), Platform (..), buildOS, buildPlatform)+import qualified Distribution.Simple.Utils import Data.Version( Version, showVersion ) import System.Directory import System.FilePath@@ -29,21 +30,22 @@ -- Finally, we must also include some information about where do find the libabc.a -- and libabc.dll files. ----- The way we have to do this is sort of nasty, but implementing the "readDesc" user--- hook doesn't seem to work the way I expect, so we have to modify the package description--- "in flight" inside each of the various hooks.+-- We do this by modifying the configure hook so it modifies the package description+-- read from disk before returing the local build info that is used by other cabal actions.+-- However, we also have to modify the sDistHook because it reads from the package description+-- file directly rather than using the one from the confHook.  The 'clean' action likewise reads+-- the description file directly, but it causes no problems to use the unmodified package+-- description for the clean action, so we do not modify that hook.  main = defaultMainWithHooks simpleUserHooks-    { postConf = \a f pkg_desc lbi -> do-                    pkg_desc' <- abcPkgDesc pkg_desc-                    postConf simpleUserHooks a f pkg_desc' lbi--    ,  confHook = \(gpkg_desc, hbi) f -> do+    {  confHook = \(gpkg_desc, hbi) f -> do                     let v = fromFlag $ configVerbosity f                     let fs = configConfigurationsFlags f                     setupAbc v (packageDescription gpkg_desc)                     buildAbc v fs-                    confHook simpleUserHooks (gpkg_desc, hbi) f+                    lbi <- confHook simpleUserHooks (gpkg_desc, hbi) f+                    pkg_desc' <- abcPkgDesc (localPkgDescr lbi)+                    return lbi{ localPkgDescr = pkg_desc' }      , sDistHook = \pkg_desc lbi h f -> do                     let v = fromFlag $ sDistVerbosity f@@ -51,31 +53,6 @@                     pkg_desc' <- abcPkgDesc pkg_desc                     sDistHook simpleUserHooks pkg_desc' lbi h f -    , buildHook = \pkg_desc lbi h f -> do-                    pkg_desc' <- abcPkgDesc pkg_desc-                    buildHook simpleUserHooks pkg_desc' lbi h f-    , haddockHook = \pkg_desc lbi h f -> do-                    pkg_desc' <- abcPkgDesc pkg_desc-                    haddockHook simpleUserHooks pkg_desc' lbi h f-    , copyHook = \pkg_desc lbi h f -> do-                    pkg_desc' <- abcPkgDesc pkg_desc-                    copyHook simpleUserHooks pkg_desc' lbi h f-    , instHook = \pkg_desc lbi h f -> do-                    pkg_desc' <- abcPkgDesc pkg_desc-                    instHook simpleUserHooks pkg_desc' lbi h f-    , regHook = \pkg_desc lbi h f -> do-                    pkg_desc' <- abcPkgDesc pkg_desc-                    regHook simpleUserHooks pkg_desc' lbi h f-    , unregHook = \pkg_desc lbi h f -> do-                    pkg_desc' <- abcPkgDesc pkg_desc-                    unregHook simpleUserHooks pkg_desc' lbi h f-    , hscolourHook = \pkg_desc lbi h f -> do-                    pkg_desc' <- abcPkgDesc pkg_desc-                    hscolourHook simpleUserHooks pkg_desc' lbi h f-    , testHook = \pkg_desc lbi h f -> do-                    pkg_desc' <- abcPkgDesc pkg_desc-                    testHook simpleUserHooks pkg_desc' lbi h f-     , postCopy = postCopyAbc     , postInst = postInstAbc     }@@ -109,6 +86,7 @@ -- If necessary, fetch the ABC sources and prepare for building setupAbc :: Verbosity -> PackageDescription -> IO () setupAbc verbosity pkg_desc = do+    putStrLn $ unwords ["Cabal library version:", showVersion Distribution.Simple.Utils.cabalVersion]     let version = pkgVersion $ package $ pkg_desc     let packageVersion = "PACKAGE_VERSION"     env <- getEnvironment
abc-build/galois-abcBridge.version view
@@ -1,1 +1,1 @@-0.11+0.12
abcBridge.cabal view
@@ -1,5 +1,5 @@ Name:               abcBridge-Version:            0.11+Version:            0.12 Synopsis:           Bindings for ABC, A System for Sequential                     Synthesis and Verification Description:        Bindings for ABC focused on creating And-Inverter@@ -9,10 +9,10 @@ License-file:       LICENSE Author:             Galois Inc. Maintainer:         jhendrix@galois.com-Copyright:          (c) 2010-2014 Galois Inc.+Copyright:          (c) 2010-2015 Galois Inc. Category:           Data build-type:         Custom-cabal-Version:      >= 1.10+cabal-Version:      >= 1.18  extra-source-files:   include/*.h@@ -20,15 +20,14 @@   scripts/*.sh   tests/eijk.S298.S.aig +flag enable-extra-tests+  Description: Enable building the long-test and find-segfault utility progams+  Default: False+ flag enable-pthreads   Description: Turn on multithreading   Default: True --- Ugh. Temporary fix to make Hackage happy.---flag enable-hpc---  Description: Collect HPC coverage information.---  Default: False- source-repository head   type: git   location: https://github.com/GaloisInc/abcBridge.git@@ -61,7 +60,8 @@                         FlexibleContexts,                         MultiParamTypeClasses,                         EmptyDataDecls-  Ghc-options:          -Wall  -auto-all -caf-all -fno-ignore-asserts+  Ghc-options:          -Wall -fno-ignore-asserts+  -- Ghc-prof-options:     -auto-all -caf-all   -- -U__BLOCKS__ to work around https://github.com/haskell/c2hs/issues/29   Cc-options:           -U__BLOCKS__ -U__has_attribute -w @@ -84,10 +84,10 @@   }   Include-dirs:         include -  +   Build-depends:     base >= 4,-    aig,+    aig >= 0.2.1,     containers,     directory,     vector@@ -99,28 +99,15 @@                         cbits/abcBridgeGiaDup.c                         cbits/pthread_stubs.c -  -- Ugh. Temporary fix to make Hackage happy.-  --if flag(enable-hpc)-  --  ghc-options: -fhpc -hpcdir .hpc-- test-suite abc-test   type: exitcode-stdio-1.0   hs-source-dirs: tests    ghc-options: -Wall-  ghc-prof-options: -fprof-auto -O2--  -- Ugh. Temporary fix to make Hackage happy.-  --if flag(enable-hpc)-  --  ghc-options: -fhpc+  -- ghc-prof-options: -fprof-auto    default-Language: Haskell98 -  -- Ugh. Temporary fix to make Hackage happy.-  --if flag(enable-hpc)-  --  ghc-options: -fhpc-   other-modules:     Tests.Basic     Tests.Operations@@ -137,19 +124,47 @@     tasty,     tasty-ant-xml,     tasty-hunit,-    tasty-quickcheck,+    tasty-quickcheck >= 0.8.1,     QuickCheck >= 2.7  +Executable find-segfault+  hs-source-dirs: tests+  ghc-options: -Wall++  default-Language: Haskell2010++  main-is:+    find-segfault.hs++  if !flag(enable-extra-tests)+     buildable: False+  else+     buildable: True+     build-depends:+       base == 4.*,+       abcBridge,+       aig,+       directory,+       vector,+       random,+       tf-random,+       unix >= 2.7,+       tasty,+       tasty-hunit,+       tasty-quickcheck,+       QuickCheck >= 2.7+++ Executable long-test   hs-source-dirs: tests -  ghc-options: -Wall-  ghc-prof-options: -fprof-auto -O2+  if !flag(enable-extra-tests)+     buildable: False -  -- Ugh. Temporary fix to make Hackage happy.-  --if flag(enable-hpc)-  --  ghc-options: -fhpc+  ghc-options: -Wall+  -- ghc-prof-options: -fprof-auto    default-Language: Haskell98 
scripts/build-abc.sh view
@@ -44,4 +44,3 @@  cd abc-build make -j4 ARCHFLAGS="-DABC_LIB $A" REMOVE_DRECTVE="$REMOVE_CMD" READLINE=0 PTHREADS="$PTHREADS" libabc.a $S-
src/Data/ABC/AIG.hs view
@@ -272,11 +272,12 @@       ioWriteAiger p path True False False    checkSat g l = do-    withNetworkPtr (AIG.Network g [l]) $ \p -> do-      alloca $ \pp -> do-        poke pp =<< abcNtkDup p-        flip finally (abcNtkDelete =<< peek pp) $ do-        checkSat' pp+    withNetworkPtr (AIG.Network g [l]) $ \p ->+      alloca $ \pp ->+        bracket_+          (poke pp =<< abcNtkDup p)+          (abcNtkDelete =<< peek pp)+          (checkSat' pp)    abstractEvaluateAIG = memoFoldAIG @@ -288,9 +289,10 @@     withNetworkPtr x $ \xp -> do     withNetworkPtr y $ \yp -> do       alloca $ \pp -> do-        flip finally (abcNtkDelete =<< peek pp) $ do-          poke pp =<< abcNtkMiter xp yp False 0 False False-          AIG.toVerifyResult <$> checkSat' pp+        bracket_+          (poke pp =<< abcNtkMiter xp yp False 0 False False)+          (abcNtkDelete =<< peek pp)+          (AIG.toVerifyResult <$> checkSat' pp)    evaluator g inputs_l = do     withAIGPtr g $ \ntk -> do@@ -327,7 +329,7 @@           r1 <- evaluateFn v . Lit =<< abcObjLit1 o           VM.write v i (r0 && r1)       -- Return evaluation function.-      pureEvaluateFn <$> V.freeze v+      pureEvaluateFn g <$> V.freeze v  forI_ :: Monad m => Int -> (Int -> m ()) -> m () forI_ = go 0@@ -335,8 +337,8 @@                  | otherwise = return ()  {-# NOINLINE pureEvaluateFn #-}-pureEvaluateFn :: V.Vector Bool -> Lit s -> Bool-pureEvaluateFn v (Lit l) = Unsafe.unsafePerformIO $ do+pureEvaluateFn :: AIG s -> V.Vector Bool -> Lit s -> Bool+pureEvaluateFn g v (Lit l) = Unsafe.unsafePerformIO $ withAIGPtr g $ \_ -> do   let c = abcObjIsComplement l   let o = abcObjRegular l   i <- fromIntegral <$> abcObjId o@@ -367,17 +369,16 @@                -> (Abc_Ntk_t -> IO a)                -> IO a withNetworkPtr (AIG.Network x o) m = do-  withAIGPtr x $ \p -> do-  flip finally (deletePos p) $ do-    mapM_ (addPo p) o-    m p+  withAIGPtr x $ \p ->+    bracket_+      (mapM_ (addPo p) o)+      (deletePos p)+      (m p)  addPo :: Abc_Ntk_t -> Lit s -> IO () addPo p (Lit ptr) = do   po <- abcNtkCreateObj p AbcObjPo   abcObjAddFanin po ptr--  checkIsConstant :: Abc_Ntk_t -> IO (Maybe Bool) checkIsConstant p = do
src/Data/ABC/GIA.hs view
@@ -40,6 +40,7 @@     , litView       -- * File IO     , readAiger+    , writeAigerWithLatches     , writeCNF       -- * QBF     , check_exists_forall@@ -93,6 +94,7 @@ -- | An and-invertor graph network in GIA form. newtype GIA s = GIA { _giaPtr :: ForeignPtr Gia_Man_t_ } +-- | Represent a literal. newtype Lit s = L { _unLit :: GiaLit }   deriving (Eq, Storable, Ord) @@ -119,7 +121,7 @@     fail $ "Data.ABC.GIA.readAiger: file does not exist"   let skipStrash = False   bracketOnError (giaAigerRead path skipStrash False) giaManStop $ \p -> do-    rn <- giaManRegNum p+    rn <- getGiaManRegNum p     when (rn /= 0) $ fail "Networks do not yet support latches."      cov <- giaManCos p@@ -153,6 +155,27 @@   compareLit x y = compare x y   showLit x = show (unGiaLit (_unLit x)) +-- | Write an AIGER file with the given number of latches.+-- If the number of latches is denoted by "n", then the last n inputs and last n outputs+-- are treated as the latch input and outputs respectively.  The other inputs and outputs+-- represent primary inputs and outputs.+writeAigerWithLatches :: FilePath+                      -> AIG.Network Lit GIA+                      -> Int -- ^ Number of latches.+                      -> IO ()+writeAigerWithLatches path ntk latchCount =+  withNetworkPtr ntk $ \p -> do+    flip finally (setGiaManRegNum p 0) $ do+      ci_num <- giaManCiNum p+      let co_num = AIG.networkOutputCount ntk+      when (latchCount < 0) $ fail "Latch count must be positive."+      when (fromIntegral latchCount > ci_num) $ do+        fail "Latch count exceeds number of inputs."+      when (latchCount > co_num) $ do+        fail "Latch count exceeds number of outputs."+      setGiaManRegNum p (fromIntegral latchCount)+      giaAigerWrite p path False False+ instance AIG.IsAIG Lit GIA where    newGraph _ = newGIA@@ -184,9 +207,10 @@     giaNetworkAsAIGMan (AIG.Network ntk [l]) $ \pMan -> do     -- Allocate a pointer to an ABC network.     alloca $ \pp -> do-      flip finally (abcNtkDelete =<< peek pp) $ do-        poke pp =<< abcNtkFromAigPhase pMan-        AIG.checkSat' pp+      bracket_+        (poke pp =<< abcNtkFromAigPhase pMan)+        (abcNtkDelete =<< peek pp)+        (AIG.checkSat' pp)    cec gx gy = do     withNetworkPtr gx $ \x -> do@@ -249,6 +273,7 @@     -- return the outputs     pureEvaluateFn <$> V.freeze vec +-- | Evaluate a literal on an assignment. pureEvaluateFn :: V.Vector Bool -> Lit s -> Bool pureEvaluateFn v (L l) = assert inRange (c /= (v V.! i))   where i = fromIntegral $ unGiaVar $ giaLitVar l@@ -263,7 +288,6 @@ --withNetworkPtr = withNetworkPtr_Copy  - -- This is a safer method for implementing withNetworkPtr; it copies the -- entire graph before adding the required COs and disposes of the copied -- graph afterwards.  Obviously, this has substantial memory usage implications.@@ -272,7 +296,7 @@   withGIAPtr ntk $ \p -> do      ncos <- vecIntSize =<< giaManCos p      assert( ncos == 0 ) $ do-     bracket (giaManDupNormalize p) giaManStop +     bracket (giaManDupNormalize p) giaManStop          (\p' -> mapM_ (\(L o) -> giaManAppendCo p' o) out >> m p')  @@ -303,8 +327,8 @@           -- clear the objects for reuse           forN_ (fromIntegral ncos) $ \i -> do              var <- vecIntEntry cov (fromIntegral i)-             -- Assert that all the objects we are clearing are above the old object count; that is,-             -- they must have been allocated when we shoved in the new COs.+             -- Assert that all the objects we are clearing are above the old object count;+             -- that is, they must have been allocated when we shoved in the new COs.              assert (var >= orig_oc) $ do              -- clear the memory assocaited with the GIA object              clearGiaObj =<< giaManObj p (GiaVar var)@@ -316,13 +340,13 @@           writeAt giaManNObjs p orig_oc      -- Run computation, then reset.-    flip finally reset $ do+    bracket_       -- Add combinational outputs.-      mapM_ (\(L o) -> giaManAppendCo p o) out-+      (mapM_ (\(L o) -> giaManAppendCo p o) out)+      -- reset the graph afterwards+      reset       -- Run computation.-      m p-+      (m p)  -- | Run a computation with an AIG man created from a GIA netowrk. giaNetworkAsAIGMan :: AIG.Network Lit GIA@@ -358,7 +382,6 @@         return t   r <- newIORef Map.empty   let objTerm o = do-        --putStrLn $ "objTerm " ++ show o         m0 <- readIORef r         case Map.lookup o m0 of           Just t -> return t@@ -444,6 +467,7 @@       ci <- aigManCi pMan (fromIntegral i)       ((vars SV.!) . fromIntegral) `fmap` (aigObjId ci) +data PartialSatResult -- | Check a formula of the form Ex.Ay p(x,y)@. -- This function takes a network where input variables are used to -- represent both the existentially and the universally quantified variables.@@ -459,7 +483,7 @@                     -> [Bool]                        -- ^ Initial value to use in search for universal variables.                        -- (should equal number of universal variables.).-                    -> Int+                    -> CInt                        -- ^ Number of iterations to try solver.                     -> IO (Either String AIG.SatResult) check_exists_forall ntk exists_cnt prop init_assign iter_cnt = do
src/Data/ABC/Internal/ABC.chs view
@@ -405,6 +405,6 @@ {#fun AbcBridge_NtkQbf as abcNtkQbf     { id `Abc_Ntk_t' -- Network     , `Int' -- Number of parameters-    , `Int' -- Maximum number of iterations.+    , id `CInt' -- Maximum number of iterations.     , id `Vec_Int_t' -- Vector for storing result.     } -> `Int' #}
src/Data/ABC/Internal/ABCGlobal.chs view
@@ -28,6 +28,7 @@ #include "abc_global.h" #include "abcbridge.h" +import Data.Word import Control.Applicative import Control.Exception (assert) import Foreign@@ -77,14 +78,17 @@     nRegs   <- fromIntegral <$> {#get Abc_Cex_t->nRegs #} p     nPis    <- fromIntegral <$> {#get Abc_Cex_t->nPis #} p     nBits   <- fromIntegral <$> {#get Abc_Cex_t->nBits #} p++    let size = 32 -- this is what the assume in the code!+     -- read out the data (it's a big bit field, so we'll     -- convert it into a flat [Bool] before slicing and dicing);     -- there might be a little extra left over-    ws <- peekArray (nBits `divUp` (sizeOf (undefined :: CUInt)))-                    (castPtr (plusPtr p {#sizeof Abc_Cex_t#}) :: Ptr CUInt)-                    :: IO [CUInt]-    let size = 32 -- this is what the assume in the code!-        bits = concatMap (\x -> map (testBit x) [0..size-1]) ws :: [Bool]+    ws <- peekArray (nBits `divUp` size)+                    (castPtr (plusPtr p {#sizeof Abc_Cex_t#}) :: Ptr Word32)+                    :: IO [Word32]++    let bits = concatMap (\x -> map (testBit x) [0..size-1]) ws :: [Bool]         -- slice it up         (regs, flatInputs) = splitAt nRegs bits         inputs = chunksOf nPis ((take ((iFrame + 1) * nPis)) flatInputs)
src/Data/ABC/Internal/GIA.chs view
@@ -51,7 +51,8 @@     , giaManPiNum     , giaManPoNum     , giaManAndNum-    , giaManRegNum+    , getGiaManRegNum+    , setGiaManRegNum      , giaManCiVar     , giaManCoVar@@ -299,7 +300,6 @@ giaManCexComb :: Gia_Man_t -> IO Abc_Cex_t giaManCexComb = {#get Gia_Man_t->pCexComb #} - giaManNObjs :: Field Gia_Man_t CInt giaManNObjs = fieldFromOffset {#offsetof Gia_Man_t->nObjs #} @@ -327,14 +327,17 @@ giaManCoNum :: Gia_Man_t -> IO CInt giaManCoNum = vecIntSize <=< giaManCos -giaManRegNum :: Gia_Man_t -> IO CInt-giaManRegNum = {#get Gia_Man_t->nRegs #}+getGiaManRegNum :: Gia_Man_t -> IO CInt+getGiaManRegNum = {#get Gia_Man_t->nRegs #} +setGiaManRegNum :: Gia_Man_t -> CInt -> IO ()+setGiaManRegNum = {#set Gia_Man_t->nRegs #}+ giaManPiNum :: Gia_Man_t -> IO CInt-giaManPiNum m = (-) <$> giaManCiNum m <*> giaManRegNum m+giaManPiNum m = (-) <$> giaManCiNum m <*> getGiaManRegNum m  giaManPoNum :: Gia_Man_t -> IO CInt-giaManPoNum m = (-) <$> giaManCoNum m <*> giaManRegNum m+giaManPoNum m = (-) <$> giaManCoNum m <*> getGiaManRegNum m  giaManAndNum :: Gia_Man_t -> IO CInt giaManAndNum m = fn <$> giaManObjNum m <*> giaManCiNum m <*> giaManCoNum m
+ tests/find-segfault.hs view
@@ -0,0 +1,96 @@+module Main where++import Test.Tasty+import Test.Tasty.Ingredients+import Test.Tasty.QuickCheck++import qualified Data.ABC as ABC++import Tests.Basic+import Tests.Operations+import Tests.QBF++import System.Environment+import System.Posix.Process+import System.Posix.IO+import System.Posix.Files++import System.Random+import System.Random.TF+import System.Random.TF.Init++import Test.QuickCheck.Random++{-+This utility runs the test suite in a separate process with differently-chosen random seeds.+It continually runs the test suite until the child process exits on a signal.  We are trying to+track down an infrequently-occuring segfault.  The idea is to find a random seed that tickles+the error so we can run it in a repeatable way.+-}++------------------------------------------------------------------------+-- Runner+------------------------------------------------------------------------++main :: IO ()+main = do+  args <- getArgs+  case args of+    [strSize, strNum] -> do+       let testsize = read strSize+       let numtests = read strNum+       gen <- initTFGen+       searchForSegfault gen testsize numtests+    [strSize, strNum, strSeed] -> do+       let testsize = read strSize+       let numtests = read strNum+       let seed = read strSeed+       withArgs [] (runTests seed testsize numtests)+    _ -> error "incorrect arguments"++searchForSegfault :: TFGen -> Int -> Int -> IO ()+searchForSegfault gen testsize numtests = do+  let (seed,gen') = next gen+  putStrLn $ unwords ["Running test with seed: ", show seed, "and size:", show testsize,"and number",show numtests]+  pid <- forkProcess (forkTests seed testsize numtests)+  putStrLn $ unwords ["child forked", show pid]+  st <- getProcessStatus True False pid+  print st+  case st of+     Nothing -> error "process status not avaliable?"+     Just (Exited cd) -> do+           putStrLn $ unwords ["Normal Exit", show cd]+           searchForSegfault gen' testsize numtests+     Just (Terminated sig _coreDumped) -> do+           putStrLn $ unwords ["Terminated by signal:", show sig]+     Just (Stopped sig) -> do+           putStrLn $ unwords ["Stopped by signal:", show sig]++forkTests :: Int -> Int -> Int -> IO ()+forkTests seed sz num = do+  fd <- openFd "child.output" WriteOnly (Just stdFileMode) defaultFileFlags{ trunc = True }+  _ <- dupTo fd stdOutput+  withArgs [] (runTests seed sz num)++runTests :: Int -> Int -> Int -> IO ()+runTests seed sz num = do+  ABC.initialize+  putStrLn $ unwords ["running tests in child process..."]+  defaultMainWithIngredients ingrs+      ( localOption (QuickCheckReplay (Just (mkQCGen seed, sz)))+      $ localOption (QuickCheckTests num)+      $ tests+      )++ingrs :: [Ingredient]+ingrs = defaultIngredients++tests :: TestTree+tests =+    testGroup "ABC Bridge"+    [ testGroup "AIG basic" $ basic_tests ABC.aigNetwork+    , testGroup "AIG operations" $ op_tests ABC.aigNetwork+    , testGroup "GIA basic" $ basic_tests ABC.giaNetwork+    , testGroup "GIA operations" $ op_tests ABC.giaNetwork+    , testGroup "GIA QBF tests" $ qbf_tests+    ]