-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | And-inverter graphs in Haskell. -- -- This package provides a generic interfaces for working with -- And-Inverter graphs (AIGs) in Haskell. And-Inverter graphs are a -- useful format for representing combinatorial and sequential boolean -- circuits in a way that is amenable to simulation and analysis. These -- interfaces allow clients to write code that can create and use AIGs -- without depending on a particular AIG package. @package aig @version 0.2 -- | Interfaces for building, simulating and analysing And-Inverter Graphs -- (AIG). module Data.AIG.Interface class IsLit l not :: IsLit l => l s -> l s (===) :: IsLit l => l s -> l s -> Bool -- | An And-Inverter-Graph is a data structure storing bit-level nodes. -- -- Graphs are and-inverter graphs, which contain a number of input -- literals and Boolean operations for creating new literals. Every -- literal is part of a specific graph, and literals from different -- networks may not be mixed. -- -- Both the types for literals and graphs must take a single phantom type -- for an arugment that is used to ensure that literals from different -- networks cannot be used in the same operation. class IsLit l => IsAIG l g | g -> l where withNewGraph p f = newGraph p >>= (`withSomeGraph` f) newGraph p = withNewGraph p (return . SomeGraph) constant g True = trueLit g constant g False = falseLit g asConstant g l | l === trueLit g = Just True | l === falseLit g = Just False | otherwise = Nothing ands g [] = return (trueLit g) ands g (x : r) = foldM (and g) x r or g x y = not <$> and g (not x) (not y) eq g x y = not <$> xor g x y implies g x y = or g (not x) y xor g x y = do { o <- or g x y; a <- and g x y; and g o (not a) } mux g c x y = do { x' <- and g c x; y' <- and g (not c) y; or g x' y' } evaluate (Network g outputs) inputs = do { f <- evaluator g inputs; return (f <$> outputs) } withNewGraph :: IsAIG l g => Proxy l g -> (forall s. g s -> IO a) -> IO a newGraph :: IsAIG l g => Proxy l g -> IO (SomeGraph g) aigerNetwork :: IsAIG l g => Proxy l g -> FilePath -> IO (Network l g) trueLit :: IsAIG l g => g s -> l s falseLit :: IsAIG l g => g s -> l s constant :: IsAIG l g => g s -> Bool -> l s asConstant :: IsAIG l g => g s -> l s -> Maybe Bool newInput :: IsAIG l g => g s -> IO (l s) and :: IsAIG l g => g s -> l s -> l s -> IO (l s) ands :: IsAIG l g => g s -> [l s] -> IO (l s) or :: IsAIG l g => g s -> l s -> l s -> IO (l s) eq :: IsAIG l g => g s -> l s -> l s -> IO (l s) implies :: IsAIG l g => g s -> l s -> l s -> IO (l s) xor :: IsAIG l g => g s -> l s -> l s -> IO (l s) mux :: IsAIG l g => g s -> l s -> l s -> l s -> IO (l s) inputCount :: IsAIG l g => g s -> IO Int getInput :: IsAIG l g => g s -> Int -> IO (l s) writeAiger :: IsAIG l g => FilePath -> Network l g -> IO () checkSat :: IsAIG l g => g s -> l s -> IO SatResult cec :: IsAIG l g => Network l g -> Network l g -> IO VerifyResult evaluator :: IsAIG l g => g s -> [Bool] -> IO (l s -> Bool) evaluate :: IsAIG l g => Network l g -> [Bool] -> IO [Bool] abstractEvaluateAIG :: IsAIG l g => g s -> (LitView a -> IO a) -> IO (l s -> IO a) -- | Short-cutting mux operator that optimizes the case where the test bit -- is a concrete literal lazyMux :: IsAIG l g => g s -> l s -> IO (l s) -> IO (l s) -> IO (l s) -- | A proxy is used to identify a specific AIG instance when calling -- methods that create new AIGs. data Proxy l g Proxy :: (forall a. a -> a) -> Proxy l g -- | Some graph quantifies over the state phantom variable for a graph. data SomeGraph g SomeGraph :: g s -> SomeGraph g -- | A network is an and-inverstor graph paired with it's outputs, thus -- representing a complete combinational circuit. data Network l g Network :: g s -> [l s] -> Network l g networkInputCount :: Network l g -> IO Int -- | Concrete datatype representing the ways an AIG can be constructed. data LitView a And :: !a -> !a -> LitView a NotAnd :: !a -> !a -> LitView a Input :: !Int -> LitView a NotInput :: !Int -> LitView a TrueLit :: LitView a FalseLit :: LitView a newtype LitTree LitTree :: LitView LitTree -> LitTree unLitTree :: LitTree -> LitView LitTree -- | Extract a tree representation of the given literal toLitTree :: IsAIG l g => g s -> l s -> IO LitTree -- | Construct an AIG literal from a tree representation fromLitTree :: IsAIG l g => g s -> LitTree -> IO (l s) -- | Extract a forest representation of the given list of literal s toLitForest :: IsAIG l g => g s -> [l s] -> IO [LitTree] -- | Construct a list of AIG literals from a forest representation fromLitForest :: IsAIG l g => g s -> [LitTree] -> IO [l s] -- | Evaluate the given literal using the provided view function foldAIG :: IsAIG l g => g s -> (LitView a -> IO a) -> l s -> IO a -- | Evaluate the given list of literals using the provided view function foldAIGs :: IsAIG l g => g s -> (LitView a -> IO a) -> [l s] -> IO [a] -- | Build an AIG literal by unfolding a constructor function unfoldAIG :: IsAIG l g => g s -> (a -> IO (LitView a)) -> a -> IO (l s) -- | Build a list of AIG literals by unfolding a constructor function unfoldAIGs :: IsAIG l g => g s -> (a -> IO (LitView a)) -> [a] -> IO [l s] -- | Satisfiability check result. data SatResult Unsat :: SatResult Sat :: !([Bool]) -> SatResult SatUnknown :: SatResult -- | Result of a verification check. data VerifyResult Valid :: VerifyResult Invalid :: [Bool] -> VerifyResult VerifyUnknown :: VerifyResult -- | Convert a verify result to a sat result by negating it. toSatResult :: VerifyResult -> SatResult -- | Convert a sat result to a verify result by negating it. toVerifyResult :: SatResult -> VerifyResult -- | Generate an arbitrary LitView given a generator for a genLitView :: Gen a -> Gen (LitView a) -- | Generate an arbitrary LitTree genLitTree :: Gen LitTree -- | Given a LitTree, calculate the maximum input number in the tree. -- Returns 0 if no inputs are referenced. getMaxInput :: LitTree -> Int -- | Given a list of LitTree, construct a corresponding AIG network buildNetwork :: IsAIG l g => Proxy l g -> [LitTree] -> IO (Network l g) -- | Generate a random network by building a random LitTree and -- using that to construct a network. randomNetwork :: IsAIG l g => Proxy l g -> IO (Network l g) instance Eq a => Eq (LitView a) instance Show a => Show (LitView a) instance Ord a => Ord (LitView a) instance Functor LitView instance Eq LitTree instance Show LitTree instance Ord LitTree instance Eq SatResult instance Show SatResult instance Eq VerifyResult instance Show VerifyResult instance Arbitrary LitTree -- | A collection of higher-level operations (mostly 2's complement -- arithmetic operations) that can be built from the primitive -- And-Inverter Graph interface. module Data.AIG.Operations -- | A BitVector consists of a sequence of symbolic bits and can be used -- for symbolic machine-word arithmetic. data BV l -- | Empty bitvector empty :: BV l -- | Number of bits in a bit vector length :: BV l -> Int -- | Project the individual bits of a BitVector. x at 0 is -- the most significant bit. It is an error to request an out-of-bounds -- bit. at :: BV l -> Int -> l -- | Select bits from a bitvector, starting from the least significant bit. -- x ! 0 is the least significant bit. It is an error to request -- an out-of-bounds bit. (!) :: BV l -> Int -> l -- | Append two bitvectors, with the most significant bitvector given -- first. (++) :: BV l -> BV l -> BV l -- | Concatenate a list of bitvectors, with the most significant bitvector -- at the head of the list. concat :: [BV l] -> BV l -- | Project out the n most significant bits from a bitvector. take :: Int -> BV l -> BV l -- | Drop the n most significant bits from a bitvector. drop :: Int -> BV l -> BV l -- | Extract n bits starting at index i. The vector must -- contain at least i+n elements slice :: BV l -> Int -> Int -> BV l -- | Extract n bits starting at index i, counting from -- the end of the vector instead of the beginning. The vector must -- contain at least i+n elements. sliceRev :: BV l -> Int -> Int -> BV l -- | Apply a monadic operation to each element of a bitvector in sequence mapM :: Monad m => (a -> m b) -> BV a -> m (BV b) -- | Combine two bitvectors with a bitwise function zipWith :: (l -> l -> l) -> BV l -> BV l -> BV l -- | Combine two bitvectors with a bitwise monadic combiner action. zipWithM :: Monad m => (l -> l -> m l) -> BV l -> BV l -> m (BV l) -- | Retrieve the most significant bit of a bitvector. msb :: BV l -> l -- | Retrieve the least significant bit of a bitvector. lsb :: BV l -> l -- | Test syntactic equalify of two bitvectors using the === -- operation bvSame :: IsLit l => BV (l s) -> BV (l s) -> Bool -- | Display a bitvector as a string of bits with most significant bits -- first. Concrete literals are displayed as '0' or '1', whereas symbolic -- literals are displayed as x. bvShow :: IsAIG l g => g s -> BV (l s) -> String -- | Generate a bitvector of length n, using monadic function -- f to generate the bit literals. The indexes to f are -- given in MSB-first order, i.e., f 0 is the most significant -- bit. generateM_msb0 :: Monad m => Int -> (Int -> m l) -> m (BV l) -- | Generate a bitvector of length n, using function f -- to specify the bit literals. The indexes to f are given in -- MSB-first order, i.e., f 0 is the most significant bit. generate_msb0 :: Int -> (Int -> l) -> BV l -- | Generate a bitvector of length n, using monadic function -- f to generate the bit literals. The indexes to f are -- given in LSB-first order, i.e., f 0 is the least significant -- bit. generateM_lsb0 :: MonadIO m => Int -> (Int -> m l) -> m (BV l) -- | Generate a bitvector of length n, using function f -- to specify the bit literals. The indexes to f are given in -- LSB-first order, i.e., f 0 is the least significant bit. generate_lsb0 :: Int -> (Int -> l) -> BV l -- | Generate a bit vector of length n where every bit value is -- literal l. replicate :: Int -> l -> BV l -- | Generate a bit vector of length n where every bit value is -- generated in turn by m. replicateM :: Monad m => Int -> m l -> m (BV l) -- | Generate a bitvector from an integer value, using 2's complement -- representation. bvFromInteger :: IsAIG l g => g s -> Int -> Integer -> BV (l s) -- | Convert a list to a bitvector, assuming big-endian bit order. bvFromList :: [l] -> BV l -- | muxInteger mergeFn maxValue lv valueFn returns a circuit -- whose result is valueFn v when lv has value -- v. muxInteger :: (Integral i, Monad m) => (l -> m a -> m a -> m a) -> i -> BV l -> (i -> m a) -> m a -- | Generate a one-element bitvector containing the given literal singleton :: l -> BV l -- | Build a short-cut AND circuit. If the left argument evaluates to the -- constant false, the right argument will not be evaluated. lAnd :: IsAIG l g => g s -> IO (l s) -> IO (l s) -> IO (l s) lAnd' :: IsAIG l g => g s -> l s -> l s -> IO (l s) -- | Build a short-cut OR circuit. If the left argument evaluates to the -- constant true, the right argument will not be evaluated. lOr :: IsAIG l g => g s -> IO (l s) -> IO (l s) -> IO (l s) lOr' :: IsAIG l g => g s -> l s -> l s -> IO (l s) -- | Construct a lazy xor. If both arguments are constants, the output will -- also be a constant. lXor :: IsAIG l g => g s -> IO (l s) -> IO (l s) -> IO (l s) lXor' :: IsAIG l g => g s -> l s -> l s -> IO (l s) -- | Construct a lazy equality test. If both arguments are constants, the -- output will also be a constant. lEq :: IsAIG l g => g s -> IO (l s) -> IO (l s) -> IO (l s) lEq' :: IsAIG l g => g s -> l s -> l s -> IO (l s) -- | Lazy negation of a circuit. lNot :: IsAIG l g => g s -> IO (l s) -> IO (l s) lNot' :: IsAIG l g => g s -> l s -> l s -- | If-then-else combinator for bitvectors. ite :: IsAIG l g => g s -> l s -> BV (l s) -> BV (l s) -> IO (BV (l s)) -- | If-then-else combinator for bitvector computations with optimistic -- shortcutting. If the test bit is concrete, we can avoid generating -- either the if or the else circuit. iteM :: IsAIG l g => g s -> l s -> IO (BV (l s)) -> IO (BV (l s)) -> IO (BV (l s)) -- | Interpret a bitvector as an unsigned integer. Return Nothing -- if the bitvector is not concrete. asUnsigned :: IsAIG l g => g s -> BV (l s) -> Maybe Integer -- | Interpret a bitvector as a signed integer. Return Nothing if -- the bitvector is not concrete. asSigned :: IsAIG l g => g s -> BV (l s) -> Maybe Integer -- | Convert a bitvector to a list, most significant bit first. bvToList :: BV l -> [l] -- | Compute the 2's complement negation of a bitvector neg :: IsAIG l g => g s -> BV (l s) -> IO (BV (l s)) -- | Add two bitvectors with the same size. Discard carry bit. add :: IsAIG l g => g s -> BV (l s) -> BV (l s) -> IO (BV (l s)) -- | Add two bitvectors with the same size with carry. addC :: IsAIG l g => g s -> BV (l s) -> BV (l s) -> IO (BV (l s), l s) -- | Subtract one bitvector from another with the same size. Discard carry -- bit. sub :: IsAIG l g => g s -> BV (l s) -> BV (l s) -> IO (BV (l s)) -- | Subtract one bitvector from another with the same size with carry. subC :: IsAIG l g => g s -> BV (l s) -> BV (l s) -> IO (BV (l s), l s) -- | Add a constant value to a bitvector addConst :: IsAIG l g => g s -> BV (l s) -> Integer -> IO (BV (l s)) -- | Add a constant value to a bitvector subConst :: IsAIG l g => g s -> BV (l s) -> Integer -> IO (BV (l s)) -- | Multiply two bitvectors with the same size, with result of the same -- size as the arguments. Overflow is silently discarded. mul :: IsAIG l g => g s -> BV (l s) -> BV (l s) -> IO (BV (l s)) -- | Unsigned multiply two bitvectors with size m and size -- n, resulting in a vector of size m+n. mulFull :: IsAIG l g => g s -> BV (l s) -> BV (l s) -> IO (BV (l s)) -- | Signed multiply two bitvectors with size m and size -- n, resulting in a vector of size m+n. smulFull :: IsAIG l g => g s -> BV (l s) -> BV (l s) -> IO (BV (l s)) -- | Compute the signed quotient of two signed bitvectors with the same -- size. squot :: IsAIG l g => g s -> BV (l s) -> BV (l s) -> IO (BV (l s)) -- | Compute the signed division remainder of two signed bitvectors with -- the same size. srem :: IsAIG l g => g s -> BV (l s) -> BV (l s) -> IO (BV (l s)) -- | Compute the unsigned quotient of two unsigned bitvectors with the same -- size. uquot :: IsAIG l g => g s -> BV (l s) -> BV (l s) -> IO (BV (l s)) -- | Compute the unsigned division remainder of two unsigned bitvectors -- with the same size. urem :: IsAIG l g => g s -> BV (l s) -> BV (l s) -> IO (BV (l s)) -- | Shift left. The least significant bit becomes 0. shl :: IsAIG l g => g s -> BV (l s) -> BV (l s) -> IO (BV (l s)) -- | Signed right shift. The most significant bit is copied. sshr :: IsAIG l g => g s -> BV (l s) -> BV (l s) -> IO (BV (l s)) -- | Unsigned right shift. The most significant bit becomes 0. ushr :: IsAIG l g => g s -> BV (l s) -> BV (l s) -> IO (BV (l s)) -- | Rotate left. rol :: IsAIG l g => g s -> BV (l s) -> BV (l s) -> IO (BV (l s)) -- | Rotate right. ror :: IsAIG l g => g s -> BV (l s) -> BV (l s) -> IO (BV (l s)) -- | Test equality of two bitvectors with the same size. bvEq :: IsAIG l g => g s -> BV (l s) -> BV (l s) -> IO (l s) -- | Test if a bitvector is equal to zero isZero :: IsAIG l g => g s -> BV (l s) -> IO (l s) -- | Test if a bitvector is distinct from zero nonZero :: IsAIG l g => g s -> BV (l s) -> IO (l s) -- | Signed less-than-or-equal on bitvector with the same size. sle :: IsAIG l g => g s -> BV (l s) -> BV (l s) -> IO (l s) -- | Signed less-than on bitvector with the same size. slt :: IsAIG l g => g s -> BV (l s) -> BV (l s) -> IO (l s) -- | Unsigned less-than-or-equal on bitvector with the same size. ule :: IsAIG l g => g s -> BV (l s) -> BV (l s) -> IO (l s) -- | Unsigned less-than on bitvector with the same size. ult :: IsAIG l g => g s -> BV (l s) -> BV (l s) -> IO (l s) -- | Return absolute value of signed bitvector. sabs :: IsAIG l g => g s -> BV (l s) -> IO (BV (l s)) -- | sext v n sign extends v to be a vector with length -- n. This function requires that n >= length v and -- length v > 0. sext :: IsAIG l g => g s -> BV (l s) -> Int -> BV (l s) -- | zext g v n zero extends v to be a vector with length -- n. This function requires that n >= length v. zext :: IsAIG l g => g s -> BV (l s) -> Int -> BV (l s) -- | Truncate the given bit vector to the specified length trunc :: Int -> BV (l s) -> BV (l s) -- | Truncate or zero-extend a bitvector to have the specified number of -- bits zeroIntCoerce :: IsAIG l g => g s -> Int -> BV (l s) -> BV (l s) -- | Truncate or sign-extend a bitvector to have the specified number of -- bits signIntCoerce :: IsAIG l g => g s -> Int -> BV (l s) -> BV (l s) -- | Polynomial multiplication. Note that the algorithm works the same no -- matter which endianness convention is used. Result length is max 0 -- (m+n-1), where m and n are the lengths of the -- inputs. pmul :: IsAIG l g => g s -> BV (l s) -> BV (l s) -> IO (BV (l s)) -- | Polynomial mod with symbolic modulus. Return value has length one less -- than the length of the modulus. pmod :: IsAIG l g => g s -> BV (l s) -> BV (l s) -> IO (BV (l s)) instance Eq l => Eq (BV l) instance Ord l => Ord (BV l) instance Show l => Show (BV l) instance Functor BV -- | A tracing wrapper AIG interface. Given an underlying AIG interface, -- this wrapper intercepts all interface calls and logs them to a file -- for debugging purposes. module Data.AIG.Trace class Traceable l compareLit :: Traceable l => l s -> l s -> Ordering showLit :: Traceable l => l s -> String newtype TraceLit l s TraceLit :: l s -> TraceLit l s unTraceLit :: TraceLit l s -> l s data TraceGraph (l :: * -> *) g s TraceGraph :: g s -> IORef (Maybe Handle) -> TraceGraph g s tGraph :: TraceGraph g s -> g s tActive :: TraceGraph g s -> IORef (Maybe Handle) proxy :: Traceable l => Proxy l g -> Proxy (TraceLit l) (TraceGraph l g) activateTracing :: TraceGraph l g s -> FilePath -> IO () deactiveTracing :: TraceGraph l g s -> IO () withTracing :: TraceGraph l g s -> FilePath -> IO a -> IO a class TraceOp l g a traceOp :: (TraceOp l g a, Traceable l, IsAIG l g) => TraceGraph l g s -> String -> a -> a class TraceOutput l g x traceOutput :: (TraceOutput l g x, Traceable l, IsAIG l g) => TraceGraph l g s -> x -> String withNewGraphTracing :: (IsAIG l g, Traceable l) => Proxy l g -> FilePath -> (forall s. TraceGraph l g s -> IO a) -> IO a instance (IsAIG l g, Traceable l) => IsAIG (TraceLit l) (TraceGraph l g) instance TraceOutput l g VerifyResult instance TraceOutput l g SatResult instance TraceOutput l g () instance TraceOutput l g Int instance TraceOutput l g (TraceLit l s) instance TraceOutput l g x => TraceOp l g (IO x) instance TraceOp l g b => TraceOp l g (FilePath -> b) instance TraceOp l g b => TraceOp l g ([TraceLit l s] -> b) instance TraceOp l g b => TraceOp l g (TraceLit l s -> b) instance TraceOp l g b => TraceOp l g (Int -> b) instance Traceable l => Ord (TraceLit l s) instance Traceable l => Eq (TraceLit l s) instance IsLit l => IsLit (TraceLit l) module Data.AIG