-- GENERATED by C->Haskell Compiler, version 0.28.1 Switcheroo, 1 April 2016 (Haskell)
-- Edit the ORIGNAL .chs file instead!


{-# LINE 1 "src/Data/ABC/Internal/GIA.chs" #-}
{- |
Module      : Data.ABC.Internal.GIA
Copyright   : Galois, Inc. 2010-2014
License     : BSD3
Maintainer  : jhendrix@galois.com
Stability   : experimental
Portability : non-portable (c2hs, language extensions)

Bindings to @aig\/gia\/gia.h@ for manipulating and
running algorithms on scalable and-inverter graphs (GIA), a
representation that is optimized for memory-efficiency.  These
functions power the next-generation of ABC algorithms that have
not been officially released yet, and can be identified by the
prefix of an ampersand, as in @&cec@, in the interactive ABC
interface.
-}
{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# OPTIONS_GHC -fno-warn-unused-imports #-}
{-# OPTIONS_GHC -fno-warn-unused-matches #-}
module Data.ABC.Internal.GIA (
      Gia_Man_t
    , Gia_Man_t_
    , giaManNObjs
    , giaManFanData
    , Gia_Obj_t
    , getGiaObjValue
    , setGiaObjValue
    , GiaVar(..)
    , GiaLit(..)
    , giaManConst0Lit
    , giaManConst1Lit
    , giaLitIsCompl
    , giaLitVar
    , giaVarLit
    , giaLitNotCond
    -- * Memory management
    -- * Base
    -- ** Network getters
    , giaManCexComb
    , giaManConst0
    , giaManCis
    , giaManCos
    , giaManCiNum
    , giaManCoNum
    , giaManPiNum
    , giaManPoNum
    , giaManAndNum
    , getGiaManRegNum
    , setGiaManRegNum

    , giaManCiVar
    , giaManCoVar
    , giaManCi
    , giaManCo
    , giaManObj
    , gia_none
    , giaObjIsCo
    , giaObjDiff0
    , giaObjDiff1
    , giaObjFaninC0
    , giaObjFaninC1
    , giaObjMark0
    , giaObjMark1
    , giaObjChild0
    , giaObjChild1
    , giaObjFaninId0
    , giaObjFaninId1
    , giaObjIsTerm
    , giaObjIsAndOrConst0
    , giaObjId
    , giaManObjNum
    -- ** Handling literals
    , giaLitNot
    , giaRegular
    , giaIsComplement
    , giaObjToLit
    , giaObjFromLit
    -- ** Iterators
    , giaManForEachObj1_
    , giaManForEachCo
    -- ** Construction
    , giaManAppendCi
    , giaManAppendCo
    , giaManAppendAnd
    -- * Functions
    -- ** giaAiger.c
    , giaAigerRead
    , giaAigerWrite
    -- ** giaDup.c
    , giaManMiter
    , giaDupLit
    , giaManDupNormalize
    -- ** giaHash.c
    , giaManHashAlloc
    , giaManHashStart
    , giaManHashStop
    , giaManHashAnd
    , giaManHashXor
    , giaManHashMux
     -- ** giaMan.c
    , giaManStart
    , giaManStop
    , p_giaManStop
    , giaManCleanup
    , giaManFillValue

      -- ** misc
    , clearGiaObj
    ) where
import qualified Data.Bits as C2HSImp
import qualified Foreign.C.String as C2HSImp
import qualified Foreign.C.Types as C2HSImp
import qualified Foreign.Marshal.Utils as C2HSImp
import qualified Foreign.Ptr as C2HSImp
import qualified Foreign.Storable as C2HSImp



import Control.Applicative ((<$>), (<*>))
import Control.Exception
import Control.Monad
import Foreign hiding (void)
import Foreign.C

import Data.ABC.Internal.ABCGlobal
{-# LINE 121 "src/Data/ABC/Internal/GIA.chs" #-}

import Data.ABC.Internal.VecInt
{-# LINE 122 "src/Data/ABC/Internal/GIA.chs" #-}


import Data.ABC.Internal.Field




-- Iterators

enumRange :: (Eq a, Enum a) => a -> a -> [a]
enumRange i n | i == n = []
              | otherwise = i : enumRange (succ i) n

lazyAnd :: Monad m => m Bool -> m Bool -> m Bool
lazyAnd mx my = do
  x <- mx
  if x then my else return False

asWordPtr :: (WordPtr -> WordPtr) -> Ptr a -> Ptr b
asWordPtr f = wordPtrToPtr . f . ptrToWordPtr

------------------------------------------------------------------------
-- Gia_Obj_t

data Gia_Obj_t_

-- | A pointer to a GIA object.
-- GIA objects are pointers to structs in ABC, and represent literals
-- in the AIG.  The low-order bit of the pointer is set to 1 if the
-- literal has been complemented, and so care must be taken to only
-- dereference positive pointers.  The object is also a bitfield, so
-- care must be taken when accessing fields.
--
-- Pointers to GIA objects may be invalidated when adding a new
-- object.
type Gia_Obj_t = C2HSImp.Ptr (Gia_Obj_t_)
{-# LINE 157 "src/Data/ABC/Internal/GIA.chs" #-}


sizeOfGiaObj :: Int
sizeOfGiaObj = 12
{-# LINE 160 "src/Data/ABC/Internal/GIA.chs" #-}


-- | Remove negation.
giaRegular :: Gia_Obj_t -> Gia_Obj_t
giaRegular = asWordPtr (.&. complement 0x1)

-- | Returns iDiff0 field of object
-- Note: iDiff0 is a bitfield, so this may be more likely to break on
-- unexpected compilers.
giaObjDiff0 :: Gia_Obj_t -> IO CUInt
giaObjDiff0 = (\ptr -> do {val <- C2HSImp.peekByteOff ptr 0 :: IO C2HSImp.CUInt{-:29-}; return $ (val `C2HSImp.shiftL` (32 - 29)) `C2HSImp.shiftR` (32 - 29)})
{-# LINE 170 "src/Data/ABC/Internal/GIA.chs" #-}


-- | Get the complement attribute of first fanin
giaObjFaninC0 :: Gia_Obj_t -> IO Bool
giaObjFaninC0 o = toBool `fmap` (\ptr -> do {val <- C2HSImp.peekByteOff ptr 0 :: IO C2HSImp.CUInt{-:1-}; return $ (val `C2HSImp.shiftL` (32 - 30)) `C2HSImp.shiftR` (32 - 1)}) o

-- | Get first user defined mark
giaObjMark0 :: Gia_Obj_t -> IO Bool
giaObjMark0 o = toBool `fmap` (\ptr -> do {val <- C2HSImp.peekByteOff ptr 0 :: IO C2HSImp.CUInt{-:1-}; return $ (val `C2HSImp.shiftL` (32 - 31)) `C2HSImp.shiftR` (32 - 1)}) o

giaObjIsTerm :: Gia_Obj_t -> IO Bool
giaObjIsTerm o = toBool `fmap` (\ptr -> do {val <- C2HSImp.peekByteOff ptr 0 :: IO C2HSImp.CUInt{-:1-}; return $ (val `C2HSImp.shiftL` (32 - 32)) `C2HSImp.shiftR` (32 - 1)}) o

-- | Returns iDiff1 field of object
-- Note: iDiff1 is a bitfield, so this may be more likely to break on
-- unexpected compilers.
giaObjDiff1 :: Gia_Obj_t -> IO CUInt
giaObjDiff1 = (\ptr -> do {val <- C2HSImp.peekByteOff ptr 4 :: IO C2HSImp.CUInt{-:29-}; return $ (val `C2HSImp.shiftL` (32 - 29)) `C2HSImp.shiftR` (32 - 29)})
{-# LINE 187 "src/Data/ABC/Internal/GIA.chs" #-}


giaObjFaninC1 :: Gia_Obj_t -> IO Bool
giaObjFaninC1 o = toBool `fmap` (\ptr -> do {val <- C2HSImp.peekByteOff ptr 4 :: IO C2HSImp.CUInt{-:1-}; return $ (val `C2HSImp.shiftL` (32 - 30)) `C2HSImp.shiftR` (32 - 1)}) o

-- | Get second user defined mark
giaObjMark1 :: Gia_Obj_t -> IO Bool
giaObjMark1 o = toBool `fmap` (\ptr -> do {val <- C2HSImp.peekByteOff ptr 4 :: IO C2HSImp.CUInt{-:1-}; return $ (val `C2HSImp.shiftL` (32 - 31)) `C2HSImp.shiftR` (32 - 1)}) o

getGiaObjValue :: Gia_Obj_t -> IO CUInt
getGiaObjValue = (\ptr -> do {C2HSImp.peekByteOff ptr 8 :: IO C2HSImp.CUInt})
{-# LINE 197 "src/Data/ABC/Internal/GIA.chs" #-}


setGiaObjValue :: Gia_Obj_t -> CUInt -> IO ()
setGiaObjValue = (\ptr val -> do {C2HSImp.pokeByteOff ptr 8 (val :: C2HSImp.CUInt)})
{-# LINE 200 "src/Data/ABC/Internal/GIA.chs" #-}


-- GIA_NONE
gia_none :: CUInt
gia_none = 0x1FFFFFFF

giaObjIsAndOrConst0 :: Gia_Obj_t -> IO Bool
giaObjIsAndOrConst0 o = not <$> giaObjIsTerm o

giaObjDiff0Assigned :: Gia_Obj_t -> IO Bool
giaObjDiff0Assigned o = (/= gia_none) <$> giaObjDiff0 o

giaIsComplement :: Gia_Obj_t -> Bool
giaIsComplement o = ptrToWordPtr o `testBit` 0

giaNot :: Gia_Obj_t -> Gia_Obj_t
giaNot = asWordPtr (xor 1)

giaNotCond :: Gia_Obj_t -> Bool -> Gia_Obj_t
giaNotCond o b = if b then giaNot o else o

-- | Returns true if this is a combinational output (latch or primary output).
giaObjIsCo :: Gia_Obj_t -> IO Bool
giaObjIsCo o = lazyAnd (giaObjIsTerm o) (giaObjDiff0Assigned o)

incObjPtr :: Gia_Obj_t -> CInt -> Gia_Obj_t
incObjPtr o i = o `plusPtr` (sizeOfGiaObj * fromIntegral i)

decObjPtr :: Gia_Obj_t -> CUInt -> Gia_Obj_t
decObjPtr o i = incObjPtr o (negate (fromIntegral i))

objDiff :: Gia_Obj_t -> Gia_Obj_t -> Int
objDiff p q = (p `minusPtr` q) `div` sizeOfGiaObj

-- Gia_ObjFanin0
giaObjFanin0 :: Gia_Obj_t -> IO Gia_Obj_t
giaObjFanin0 o = decObjPtr o <$> giaObjDiff0 o

-- Gia_ObjFanin1
giaObjFanin1 :: Gia_Obj_t -> IO Gia_Obj_t
giaObjFanin1 o = decObjPtr o <$> giaObjDiff1 o

-- Gia_ObjChild0
giaObjChild0 :: Gia_Obj_t -> IO Gia_Obj_t
giaObjChild0 o = giaNotCond <$> giaObjFanin0 o <*> giaObjFaninC0 o

-- Gia_ObjChild1
giaObjChild1 :: Gia_Obj_t -> IO Gia_Obj_t
giaObjChild1 o = giaNotCond <$> giaObjFanin1 o <*> giaObjFaninC1 o

-- Gia_ObjFaninId0
giaObjFaninId0 :: Gia_Obj_t -> GiaVar -> IO GiaVar
giaObjFaninId0 o (GiaVar v) = (\d -> GiaVar (v - fromIntegral d)) <$> giaObjDiff0 o

-- Gia_ObjFaninId1
giaObjFaninId1 :: Gia_Obj_t -> GiaVar -> IO GiaVar
giaObjFaninId1 o (GiaVar v) = (\d -> GiaVar (v - fromIntegral d)) <$> giaObjDiff1 o

------------------------------------------------------------------------
-- GiaVar and GiaLit

-- | Also known as the node's id.  No complement info.
newtype GiaVar = GiaVar { unGiaVar :: CInt } deriving (Eq, Ord, Storable)

-- | Literals store complement information.
newtype GiaLit = GiaLit { unGiaLit :: CInt } deriving (Eq, Ord, Storable)

giaManConst0Lit :: GiaLit
giaManConst0Lit = GiaLit 0

giaManConst1Lit :: GiaLit
giaManConst1Lit = GiaLit 1

giaLitIsCompl :: GiaLit -> Bool
giaLitIsCompl l = unGiaLit l `testBit` 0

giaLitVar :: GiaLit -> GiaVar
giaLitVar (GiaLit l) = GiaVar (l `shiftR` 1)

-- | Returns positive literal associated to var.
giaVarLit :: GiaVar -> GiaLit
giaVarLit (GiaVar v) = GiaLit (v `shiftL` 1)

giaLitNot :: GiaLit -> GiaLit
giaLitNot = GiaLit . xor 1 . unGiaLit

giaLitNotCond :: GiaLit -> Bool -> GiaLit
giaLitNotCond (GiaLit l) b = GiaLit (l `xor` (if b then 1 else 0))

------------------------------------------------------------------------
-- Gia_Man_t

data Gia_Man_t_
type Gia_Man_t = C2HSImp.Ptr (Gia_Man_t_)
{-# LINE 293 "src/Data/ABC/Internal/GIA.chs" #-}


-- member access

-- this structures are memory managed by Gia_Man_.
giaManCexComb :: Gia_Man_t -> IO Abc_Cex_t
giaManCexComb = (\ptr -> do {C2HSImp.peekByteOff ptr 248 :: IO (Abc_Cex_t)})
{-# LINE 299 "src/Data/ABC/Internal/GIA.chs" #-}


giaManNObjs :: Field Gia_Man_t CInt
giaManNObjs = fieldFromOffset (24)
{-# LINE 302 "src/Data/ABC/Internal/GIA.chs" #-}


giaManObjs :: Field Gia_Man_t Gia_Obj_t
giaManObjs = fieldFromOffset (32)
{-# LINE 305 "src/Data/ABC/Internal/GIA.chs" #-}


giaManConst0 :: Gia_Man_t -> IO Gia_Obj_t
giaManConst0 = readAt giaManObjs

giaManCis :: Gia_Man_t -> IO Vec_Int_t
giaManCis = (\ptr -> do {C2HSImp.peekByteOff ptr 64 :: IO (Vec_Int_t)})
{-# LINE 311 "src/Data/ABC/Internal/GIA.chs" #-}


giaManCos :: Gia_Man_t -> IO Vec_Int_t
giaManCos = (\ptr -> do {C2HSImp.peekByteOff ptr 72 :: IO (Vec_Int_t)})
{-# LINE 314 "src/Data/ABC/Internal/GIA.chs" #-}


giaManFanData :: Gia_Man_t -> IO (Ptr CInt)
giaManFanData = (\ptr -> do {C2HSImp.peekByteOff ptr 184 :: IO (C2HSImp.Ptr C2HSImp.CInt)})
{-# LINE 317 "src/Data/ABC/Internal/GIA.chs" #-}


giaManObjNum :: Gia_Man_t -> IO CInt
giaManObjNum = readAt giaManNObjs

giaManCiNum :: Gia_Man_t -> IO CInt
giaManCiNum = vecIntSize <=< giaManCis

giaManCoNum :: Gia_Man_t -> IO CInt
giaManCoNum = vecIntSize <=< giaManCos

getGiaManRegNum :: Gia_Man_t -> IO CInt
getGiaManRegNum = (\ptr -> do {C2HSImp.peekByteOff ptr 16 :: IO C2HSImp.CInt})
{-# LINE 329 "src/Data/ABC/Internal/GIA.chs" #-}


setGiaManRegNum :: Gia_Man_t -> CInt -> IO ()
setGiaManRegNum = (\ptr val -> do {C2HSImp.pokeByteOff ptr 16 (val :: C2HSImp.CInt)})
{-# LINE 332 "src/Data/ABC/Internal/GIA.chs" #-}


giaManPiNum :: Gia_Man_t -> IO CInt
giaManPiNum m = (-) <$> giaManCiNum m <*> getGiaManRegNum m

giaManPoNum :: Gia_Man_t -> IO CInt
giaManPoNum m = (-) <$> giaManCoNum m <*> getGiaManRegNum m

giaManAndNum :: Gia_Man_t -> IO CInt
giaManAndNum m = fn <$> giaManObjNum m <*> giaManCiNum m <*> giaManCoNum m
  where fn t i o = t - i - o - 1

-- XXX refactor
giaManForEachObj1_ :: Gia_Man_t -> (Gia_Obj_t -> GiaVar -> IO b) -> IO ()
giaManForEachObj1_ fp action = do
  nMax <- giaManObjNum fp
  forM_ (enumRange 1 nMax) $ \i -> do
    let var = GiaVar (fromIntegral i)
    pObj <- giaManObj fp var
    void $ action pObj var

giaManForEachCo :: Gia_Man_t -> (Gia_Obj_t -> Int -> IO b) -> IO [b]
giaManForEachCo fp action = do
  nMax <- giaManCoNum fp
  forM (enumRange 0 nMax) $ \i -> do
    pObj <- giaManCo fp i
    action pObj (fromIntegral i)

foreign import ccall unsafe "AbcBridge_Gia_ManAppendCi"
  giaManAppendCi_ :: Gia_Man_t -> IO CInt

giaManAppendCi :: Gia_Man_t -> IO GiaLit
giaManAppendCi m = GiaLit <$> giaManAppendCi_ m

foreign import ccall unsafe "AbcBridge_Gia_ManAppendAnd"
  giaManAppendAnd_ :: Gia_Man_t -> CInt -> CInt -> IO CInt

-- | This directly appends the literal to the GIA bypassing
-- any hash-consing.
giaManAppendAnd :: Gia_Man_t -> GiaLit -> GiaLit -> IO GiaLit
giaManAppendAnd m (GiaLit x) (GiaLit y) =
  GiaLit <$> giaManAppendAnd_ m x y

foreign import ccall unsafe "AbcBridge_Gia_ManAppendCo"
  giaManAppendCo_ :: Gia_Man_t -> CInt -> IO CInt

giaManAppendCo :: Gia_Man_t -> GiaLit -> IO GiaLit
giaManAppendCo m (GiaLit l) = GiaLit <$> giaManAppendCo_ m l

-- | Return object associated with gia var.
giaManObj :: Gia_Man_t -> GiaVar -> IO Gia_Obj_t
giaManObj m (GiaVar v) = do
  cnt <- giaManObjNum m
  assert (0 <= v && v < cnt) $ do
    (`incObjPtr` v) <$> giaManConst0 m

-- | Get var index of combinational input at given index.
giaManCiVar :: Gia_Man_t -> CInt -> IO GiaVar
giaManCiVar m i = do
  v <- giaManCis m
  GiaVar <$> vecIntEntry v i

-- | Get combinational input at given index.
giaManCi :: Gia_Man_t -> CInt -> IO Gia_Obj_t
giaManCi m i = giaManObj m =<< giaManCiVar m i

-- | Get combinational output at given index.
giaManCoVar :: Gia_Man_t -> CInt -> IO GiaVar
giaManCoVar m i = do
  v <- giaManCos m
  GiaVar <$> vecIntEntry v i

-- | Get combinational output at given index.
giaManCo :: Gia_Man_t -> CInt -> IO Gia_Obj_t
giaManCo m i = giaManObj m =<< giaManCoVar m i

-- | Returns the variable index associated with the object.
giaObjId :: Gia_Man_t -> Gia_Obj_t -> IO GiaVar
giaObjId p pObj = do
  objs <- giaManConst0 p
  nObjs <- readAt giaManNObjs p
  assert (objs <= pObj && pObj < objs `incObjPtr` nObjs) $ do
    return $ GiaVar $ fromIntegral $ pObj `objDiff` objs

giaObjToLit :: (Gia_Man_t) -> (Gia_Obj_t) -> IO ((GiaLit))
giaObjToLit a1 a2 =
  let {a1' = id a1} in 
  let {a2' = id a2} in 
  giaObjToLit'_ a1' a2' >>= \res ->
  let {res' = GiaLit res} in
  return (res')

{-# LINE 419 "src/Data/ABC/Internal/GIA.chs" #-}

giaObjFromLit :: (Gia_Man_t) -> (GiaLit) -> IO ((Gia_Obj_t))
giaObjFromLit a1 a2 =
  let {a1' = id a1} in 
  let {a2' = unGiaLit a2} in 
  giaObjFromLit'_ a1' a2' >>= \res ->
  let {res' = id res} in
  return (res')

{-# LINE 423 "src/Data/ABC/Internal/GIA.chs" #-}


-- giaAiger.c
giaAigerRead :: (String) -- pFileName
 -> (Bool) -- fSkipStrash
 -> (Bool) -- fCheck (doesn't do anything)
 -> IO ((Gia_Man_t))
giaAigerRead a1 a2 a3 =
  C2HSImp.withCString a1 $ \a1' -> 
  let {a2' = C2HSImp.fromBool a2} in 
  let {a3' = C2HSImp.fromBool a3} in 
  giaAigerRead'_ a1' a2' a3' >>= \res ->
  let {res' = id res} in
  return (res')

{-# LINE 430 "src/Data/ABC/Internal/GIA.chs" #-}




giaAigerWrite :: (Gia_Man_t) -> (String) -- pFileName
 -> (Bool) -- fWriteSymbols
 -> (Bool) -- fCompact
 -> IO ()
giaAigerWrite a1 a2 a3 a4 =
  let {a1' = id a1} in 
  C2HSImp.withCString a2 $ \a2' -> 
  let {a3' = C2HSImp.fromBool a3} in 
  let {a4' = C2HSImp.fromBool a4} in 
  giaAigerWrite'_ a1' a2' a3' a4' >>
  return ()

{-# LINE 439 "src/Data/ABC/Internal/GIA.chs" #-}


giaManMiter :: (Gia_Man_t) -- pAig0cd
 -> (Gia_Man_t) -- pAig1
 -> (Int) -- nInsDup
 -> (Bool) -- fDualOut
 -> (Bool) -- fSeq
 -> (Bool) -- fImplic
 -> (Bool) -- fVerbose
 -> IO ((Gia_Man_t))
giaManMiter a1 a2 a3 a4 a5 a6 a7 =
  let {a1' = id a1} in 
  let {a2' = id a2} in 
  let {a3' = fromIntegral a3} in 
  let {a4' = C2HSImp.fromBool a4} in 
  let {a5' = C2HSImp.fromBool a5} in 
  let {a6' = C2HSImp.fromBool a6} in 
  let {a7' = C2HSImp.fromBool a7} in 
  giaManMiter'_ a1' a2' a3' a4' a5' a6' a7' >>= \res ->
  let {res' = id res} in
  return (res')

{-# LINE 449 "src/Data/ABC/Internal/GIA.chs" #-}


foreign import ccall unsafe "Gia_ManDupNormalize" giaManDupNormalize
  :: Gia_Man_t -> IO Gia_Man_t

-- | @giaManDupDfsLazyLit pNew p l@ copies a lit @l@ in @p@ to @pNew@
-- and returns the lit in @pNew@.
giaDupLit :: Gia_Man_t -> Gia_Man_t -> GiaLit -> IO GiaLit
giaDupLit pNew p (GiaLit l) = GiaLit <$> giaDupLit' pNew p l

foreign import ccall unsafe "AbcBridge_Gia_DupLit" giaDupLit'
  :: Gia_Man_t -> Gia_Man_t -> CInt -> IO CInt

-- giaHash.c
foreign import ccall unsafe "Gia_ManHashAlloc" giaManHashAlloc
  :: Gia_Man_t -> IO ()

foreign import ccall unsafe "Gia_ManHashStart" giaManHashStart
  :: Gia_Man_t -> IO ()

foreign import ccall unsafe "Gia_ManHashStop" giaManHashStop
  :: Gia_Man_t -> IO ()

giaManHashAnd :: (Gia_Man_t) -- p
 -> (GiaLit) -- iLit0
 -> (GiaLit) -- iLit1
 -> IO ((GiaLit))
giaManHashAnd a1 a2 a3 =
  let {a1' = id a1} in 
  let {a2' = unGiaLit a2} in 
  let {a3' = unGiaLit a3} in 
  giaManHashAnd'_ a1' a2' a3' >>= \res ->
  let {res' = GiaLit res} in
  return (res')

{-# LINE 476 "src/Data/ABC/Internal/GIA.chs" #-}

giaManHashXor :: (Gia_Man_t) -- p
 -> (GiaLit) -- iLit0
 -> (GiaLit) -- iLit1
 -> IO ((GiaLit))
giaManHashXor a1 a2 a3 =
  let {a1' = id a1} in 
  let {a2' = unGiaLit a2} in 
  let {a3' = unGiaLit a3} in 
  giaManHashXor'_ a1' a2' a3' >>= \res ->
  let {res' = GiaLit res} in
  return (res')

{-# LINE 481 "src/Data/ABC/Internal/GIA.chs" #-}

giaManHashMux :: (Gia_Man_t) -- p
 -> (GiaLit) -- iCtrl
 -> (GiaLit) -- iData1
 -> (GiaLit) -- iData0
 -> IO ((GiaLit))
giaManHashMux a1 a2 a3 a4 =
  let {a1' = id a1} in 
  let {a2' = unGiaLit a2} in 
  let {a3' = unGiaLit a3} in 
  let {a4' = unGiaLit a4} in 
  giaManHashMux'_ a1' a2' a3' a4' >>= \res ->
  let {res' = GiaLit res} in
  return (res')

{-# LINE 487 "src/Data/ABC/Internal/GIA.chs" #-}


-- giaMan.c
foreign import ccall unsafe "Gia_ManStop"
    giaManStop :: Gia_Man_t -> IO ()

foreign import ccall unsafe "gia.h &Gia_ManStop"
    p_giaManStop :: FunPtr (Gia_Man_t -> IO ())

foreign import ccall unsafe "AbcBridge_Gia_ClearGiaObj"
    clearGiaObj :: Gia_Obj_t -> IO ()

giaManStart :: (CInt) -> IO ((Gia_Man_t))
giaManStart a1 =
  let {a1' = id a1} in 
  giaManStart'_ a1' >>= \res ->
  let {res' = id res} in
  return (res')

{-# LINE 499 "src/Data/ABC/Internal/GIA.chs" #-}


giaManCleanup :: (Gia_Man_t) -- p
 -> IO ((Gia_Man_t))
giaManCleanup a1 =
  let {a1' = id a1} in 
  giaManCleanup'_ a1' >>= \res ->
  let {res' = id res} in
  return (res')

{-# LINE 503 "src/Data/ABC/Internal/GIA.chs" #-}


giaManFillValue :: (Gia_Man_t) -- p
 -> IO ()
giaManFillValue a1 =
  let {a1' = id a1} in 
  giaManFillValue'_ a1' >>
  return ()

{-# LINE 507 "src/Data/ABC/Internal/GIA.chs" #-}


foreign import ccall safe "Data/ABC/Internal/GIA.chs.h AbcBridge_Gia_ObjToLit"
  giaObjToLit'_ :: ((Gia_Man_t) -> ((Gia_Obj_t) -> (IO C2HSImp.CInt)))

foreign import ccall safe "Data/ABC/Internal/GIA.chs.h AbcBridge_Gia_ObjFromLit"
  giaObjFromLit'_ :: ((Gia_Man_t) -> (C2HSImp.CInt -> (IO (Gia_Obj_t))))

foreign import ccall safe "Data/ABC/Internal/GIA.chs.h Gia_AigerRead"
  giaAigerRead'_ :: ((C2HSImp.Ptr C2HSImp.CChar) -> (C2HSImp.CInt -> (C2HSImp.CInt -> (IO (Gia_Man_t)))))

foreign import ccall safe "Data/ABC/Internal/GIA.chs.h Gia_AigerWrite"
  giaAigerWrite'_ :: ((Gia_Man_t) -> ((C2HSImp.Ptr C2HSImp.CChar) -> (C2HSImp.CInt -> (C2HSImp.CInt -> (IO ())))))

foreign import ccall safe "Data/ABC/Internal/GIA.chs.h Gia_ManMiter"
  giaManMiter'_ :: ((Gia_Man_t) -> ((Gia_Man_t) -> (C2HSImp.CInt -> (C2HSImp.CInt -> (C2HSImp.CInt -> (C2HSImp.CInt -> (C2HSImp.CInt -> (IO (Gia_Man_t)))))))))

foreign import ccall safe "Data/ABC/Internal/GIA.chs.h Gia_ManHashAnd"
  giaManHashAnd'_ :: ((Gia_Man_t) -> (C2HSImp.CInt -> (C2HSImp.CInt -> (IO C2HSImp.CInt))))

foreign import ccall safe "Data/ABC/Internal/GIA.chs.h Gia_ManHashXor"
  giaManHashXor'_ :: ((Gia_Man_t) -> (C2HSImp.CInt -> (C2HSImp.CInt -> (IO C2HSImp.CInt))))

foreign import ccall safe "Data/ABC/Internal/GIA.chs.h Gia_ManHashMux"
  giaManHashMux'_ :: ((Gia_Man_t) -> (C2HSImp.CInt -> (C2HSImp.CInt -> (C2HSImp.CInt -> (IO C2HSImp.CInt)))))

foreign import ccall safe "Data/ABC/Internal/GIA.chs.h Gia_ManStart"
  giaManStart'_ :: (C2HSImp.CInt -> (IO (Gia_Man_t)))

foreign import ccall safe "Data/ABC/Internal/GIA.chs.h Gia_ManCleanup"
  giaManCleanup'_ :: ((Gia_Man_t) -> (IO (Gia_Man_t)))

foreign import ccall safe "Data/ABC/Internal/GIA.chs.h Gia_ManFillValue"
  giaManFillValue'_ :: ((Gia_Man_t) -> (IO ()))