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


{-# LINE 1 "src/IGraph/Algorithms/Isomorphism.chs" #-}
{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE ScopedTypeVariables #-}
module IGraph.Algorithms.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 Data.Singletons (SingI, Sing, sing, fromSing)

import Foreign
import Foreign.C.Types

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




getSubisomorphisms :: Graph d v1 e1  -- ^ graph to be searched in
                   -> Graph d v2 e2   -- ^ smaller graph
                   -> [[Int]]
getSubisomorphisms g1 g2 = unsafePerformIO $ allocaVectorPtr $ \vpptr -> do
    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 ()) -> (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
  let {a7' = castPtr a7} in
  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 45 "src/IGraph/Algorithms/Isomorphism.chs" #-}


-- | Determine whether two graphs are isomorphic.
isomorphic :: Graph d v1 e1
           -> Graph 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 55 "src/IGraph/Algorithms/Isomorphism.chs" #-}


-- | Creates a graph from the given isomorphism class.
-- This function is implemented only for graphs with three or four vertices.
isoclassCreate :: forall d. SingI d
               => Int   -- ^ The number of vertices to add to the graph.
               -> Int   -- ^ The isomorphism class
               -> Graph d () ()
isoclassCreate size idx = unsafePerformIO $ do
    gp <- igraphInit >> igraphIsoclassCreate size idx directed
    return $ Graph gp $ mkLabelToId gp
  where
    directed = case fromSing (sing :: Sing d) of
        D -> True
        U -> False
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 73 "src/IGraph/Algorithms/Isomorphism.chs" #-}


isoclass3 :: forall d. SingI d => [Graph d () ()]
isoclass3 = map (isoclassCreate 3) (if directed then [0..15] else [0..3])
  where
    directed = case fromSing (sing :: Sing d) of
        D -> True
        U -> False

isoclass4 :: forall d. SingI d => [Graph d () ()]
isoclass4 = map (isoclassCreate 4) (if directed then [0..217] else [0..10])
  where
    directed = case fromSing (sing :: Sing d) of
        D -> True
        U -> False

foreign import ccall safe "IGraph/Algorithms/Isomorphism.chs.h igraph_get_subisomorphisms_vf2"
  igraphGetSubisomorphismsVf2'_ :: ((C2HSImp.Ptr (IGraph)) -> ((C2HSImp.Ptr (IGraph)) -> ((C2HSImp.Ptr ()) -> ((C2HSImp.Ptr ()) -> ((C2HSImp.Ptr ()) -> ((C2HSImp.Ptr ()) -> ((C2HSImp.Ptr ()) -> ((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/Algorithms/Isomorphism.chs.h igraph_isomorphic"
  igraphIsomorphic'_ :: ((C2HSImp.Ptr (IGraph)) -> ((C2HSImp.Ptr (IGraph)) -> ((C2HSImp.Ptr C2HSImp.CInt) -> (IO C2HSImp.CInt))))

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