-- GENERATED by C->Haskell Compiler, version 0.28.3 Switcheroo, 25 November 2017 (Haskell)
-- Edit the ORIGNAL .chs file instead!


{-# LINE 1 "src/IGraph/Isomorphism.chs" #-}
{-# LANGUAGE ForeignFunctionInterface #-}
module IGraph.Isomorphism
    ( getSubisomorphisms
    , isomorphic
    , isoclassCreate
    , isoclass3
    , isoclass4
    ) where
import qualified Foreign.C.Types as C2HSImp
import qualified Foreign.Marshal.Utils as C2HSImp
import qualified Foreign.Ptr as C2HSImp



import           System.IO.Unsafe               (unsafePerformIO)

import Foreign
import Foreign.C.Types

import           IGraph
import           IGraph.Internal.Initialization (igraphInit)
import           IGraph.Mutable
import IGraph.Internal
{-# LINE 18 "src/IGraph/Isomorphism.chs" #-}




getSubisomorphisms :: Graph d
                   => LGraph d v1 e1  -- ^ graph to be searched in
                   -> LGraph d v2 e2   -- ^ smaller graph
                   -> [[Int]]
getSubisomorphisms g1 g2 = unsafePerformIO $ do
    vpptr <- igraphVectorPtrNew 0
    igraphGetSubisomorphismsVf2 gptr1 gptr2 nullPtr nullPtr nullPtr nullPtr vpptr
        nullFunPtr nullFunPtr nullPtr
    (map.map) truncate <$> toLists vpptr
  where
    gptr1 = _graph g1
    gptr2 = _graph g2
{-# INLINE getSubisomorphisms #-}
igraphGetSubisomorphismsVf2 :: (IGraph) -> (IGraph) -> (Ptr ()) -> (Ptr ()) -> (Ptr ()) -> (Ptr ()) -> (VectorPtr) -> (FunPtr (Ptr IGraph -> Ptr IGraph -> CInt -> CInt -> Ptr () -> IO CInt)) -> (FunPtr (Ptr IGraph -> Ptr IGraph -> CInt -> CInt -> Ptr () -> IO CInt)) -> (Ptr ()) -> IO ()
igraphGetSubisomorphismsVf2 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 =
  (withIGraph) a1 $ \a1' ->
  (withIGraph) a2 $ \a2' ->
  let {a3' = id a3} in
  let {a4' = id a4} in
  let {a5' = id a5} in
  let {a6' = id a6} in
  (withVectorPtr) a7 $ \a7' ->
  let {a8' = id a8} in
  let {a9' = id a9} in
  let {a10' = id a10} in
  igraphGetSubisomorphismsVf2'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' >>= \res ->
  return ()

{-# LINE 46 "src/IGraph/Isomorphism.chs" #-}


-- | Determine whether two graphs are isomorphic.
isomorphic :: Graph d
           => LGraph d v1 e1
           -> LGraph d v2 e2
           -> Bool
isomorphic g1 g2 = unsafePerformIO $ alloca $ \ptr -> do
    _ <- igraphIsomorphic (_graph g1) (_graph g2) ptr
    x <- peek ptr
    return (x /= 0)
igraphIsomorphic :: (IGraph) -> (IGraph) -> (Ptr CInt) -> IO ()
igraphIsomorphic a1 a2 a3 =
  (withIGraph) a1 $ \a1' ->
  (withIGraph) a2 $ \a2' ->
  let {a3' = id a3} in
  igraphIsomorphic'_ a1' a2' a3' >>= \res ->
  return ()

{-# LINE 57 "src/IGraph/Isomorphism.chs" #-}


-- | Creates a graph from the given isomorphism class.
-- This function is implemented only for graphs with three or four vertices.
isoclassCreate :: Graph d
               => Int   -- ^ The number of vertices to add to the graph.
               -> Int   -- ^ The isomorphism class
               -> d
               -> LGraph d () ()
isoclassCreate size idx d = unsafePerformIO $ do
    gp <- igraphInit >> igraphIsoclassCreate size idx (isD d)
    unsafeFreeze $ MLGraph gp
igraphIsoclassCreate :: (Int) -> (Int) -> (Bool) -> IO ((IGraph))
igraphIsoclassCreate a2 a3 a4 =
  allocaIGraph $ \a1' ->
  let {a2' = fromIntegral a2} in
  let {a3' = fromIntegral a3} in
  let {a4' = C2HSImp.fromBool a4} in
  igraphIsoclassCreate'_ a1' a2' a3' a4' >>= \res ->
  addIGraphFinalizer  a1'>>= \a1'' ->
  return (a1'')

{-# LINE 72 "src/IGraph/Isomorphism.chs" #-}


isoclass3 :: Graph d => d -> [LGraph d () ()]
isoclass3 d = map (flip (isoclassCreate 3) d) n
  where
    n | isD d = [0..15]
      | otherwise = [0..3]

isoclass4 :: Graph d => d -> [LGraph d () ()]
isoclass4 d = map (flip (isoclassCreate 4) d) n
  where
    n | isD d = [0..217]
      | otherwise = [0..10]

foreign import ccall safe "IGraph/Isomorphism.chs.h igraph_get_subisomorphisms_vf2"
  igraphGetSubisomorphismsVf2'_ :: ((C2HSImp.Ptr (IGraph)) -> ((C2HSImp.Ptr (IGraph)) -> ((C2HSImp.Ptr ()) -> ((C2HSImp.Ptr ()) -> ((C2HSImp.Ptr ()) -> ((C2HSImp.Ptr ()) -> ((C2HSImp.Ptr (VectorPtr)) -> ((C2HSImp.FunPtr ((C2HSImp.Ptr (IGraph)) -> ((C2HSImp.Ptr (IGraph)) -> (C2HSImp.CInt -> (C2HSImp.CInt -> ((C2HSImp.Ptr ()) -> (IO C2HSImp.CInt))))))) -> ((C2HSImp.FunPtr ((C2HSImp.Ptr (IGraph)) -> ((C2HSImp.Ptr (IGraph)) -> (C2HSImp.CInt -> (C2HSImp.CInt -> ((C2HSImp.Ptr ()) -> (IO C2HSImp.CInt))))))) -> ((C2HSImp.Ptr ()) -> (IO C2HSImp.CInt)))))))))))

foreign import ccall safe "IGraph/Isomorphism.chs.h igraph_isomorphic"
  igraphIsomorphic'_ :: ((C2HSImp.Ptr (IGraph)) -> ((C2HSImp.Ptr (IGraph)) -> ((C2HSImp.Ptr C2HSImp.CInt) -> (IO C2HSImp.CInt))))

foreign import ccall safe "IGraph/Isomorphism.chs.h igraph_isoclass_create"
  igraphIsoclassCreate'_ :: ((C2HSImp.Ptr (IGraph)) -> (C2HSImp.CInt -> (C2HSImp.CInt -> (C2HSImp.CInt -> (IO C2HSImp.CInt)))))