-- 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/Generators.chs" #-}
{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
module IGraph.Algorithms.Generators
    ( full
    , star
    , ring
    , ErdosRenyiModel(..)
    , erdosRenyiGame
    , degreeSequenceGame
    , rewire
    ) where
import qualified Foreign.C.Types as C2HSImp
import qualified Foreign.Marshal.Utils as C2HSImp
import qualified Foreign.Ptr as C2HSImp



import           Data.Serialize                 (Serialize)
import Data.Singletons (SingI, Sing, sing, fromSing)
import System.IO.Unsafe (unsafePerformIO)
import qualified Data.Map.Strict as M

import qualified Foreign.Ptr as C2HSImp
import Foreign

import           IGraph
import           IGraph.Mutable (MGraph(..))
import IGraph.Internal
{-# LINE 24 "src/IGraph/Algorithms/Generators.chs" #-}

import IGraph.Internal.Constants
{-# LINE 25 "src/IGraph/Algorithms/Generators.chs" #-}

import IGraph.Internal.Initialization
{-# LINE 26 "src/IGraph/Algorithms/Generators.chs" #-}




full :: forall d. SingI d
     => Int   -- ^ The number of vertices in the graph.
     -> Bool  -- ^ Whether to include self-edges (loops)
     -> Graph d () ()
full n hasLoop = unsafePerformIO $ do
    igraphInit
    gr <- igraphFull n directed hasLoop
    initializeNullAttribute gr
    return $ Graph gr M.empty
  where
    directed = case fromSing (sing :: Sing d) of
        D -> True
        U -> False
igraphFull :: (Int) -> (Bool) -> (Bool) -> IO ((IGraph))
igraphFull a2 a3 a4 =
  allocaIGraph $ \a1' ->
  let {a2' = fromIntegral a2} in
  let {a3' = C2HSImp.fromBool a3} in
  let {a4' = C2HSImp.fromBool a4} in
  igraphFull'_ a1' a2' a3' a4' >>= \res ->
  addIGraphFinalizer  a1'>>= \a1'' ->
  return (a1'')

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


-- | Return the Star graph. The center node is always associated with id 0.
star :: Int    -- ^ The number of nodes
     -> Graph 'U () ()
star n = unsafePerformIO $ do
    igraphInit
    gr <- igraphStar n IgraphStarUndirected 0
    initializeNullAttribute gr
    return $ Graph gr M.empty
igraphStar :: (Int) -> (StarMode) -> (Int) -> IO ((IGraph))
igraphStar a2 a3 a4 =
  allocaIGraph $ \a1' ->
  let {a2' = fromIntegral a2} in
  let {a3' = (fromIntegral . fromEnum) a3} in
  let {a4' = fromIntegral a4} in
  igraphStar'_ a1' a2' a3' a4' >>= \res ->
  addIGraphFinalizer  a1'>>= \a1'' ->
  return (a1'')

{-# LINE 61 "src/IGraph/Algorithms/Generators.chs" #-}


-- | Creates a ring graph, a one dimensional lattice.
ring :: Int -> Graph 'U () ()
ring n = unsafePerformIO $ do
    igraphInit
    gr <- igraphRing n False False True
    initializeNullAttribute gr
    return $ Graph gr M.empty
igraphRing :: (Int) -> (Bool) -> (Bool) -> (Bool) -> IO ((IGraph))
igraphRing a2 a3 a4 a5 =
  allocaIGraph $ \a1' ->
  let {a2' = fromIntegral a2} in
  let {a3' = C2HSImp.fromBool a3} in
  let {a4' = C2HSImp.fromBool a4} in
  let {a5' = C2HSImp.fromBool a5} in
  igraphRing'_ a1' a2' a3' a4' a5' >>= \res ->
  addIGraphFinalizer  a1'>>= \a1'' ->
  return (a1'')

{-# LINE 76 "src/IGraph/Algorithms/Generators.chs" #-}


data ErdosRenyiModel = GNP Int Double
                     | GNM Int Int

erdosRenyiGame :: forall d. SingI d
               => ErdosRenyiModel
               -> Bool  -- ^ self-loop
               -> IO (Graph d () ())
erdosRenyiGame model self = do
    igraphInit
    gr <- case model of
        GNP n p -> igraphErdosRenyiGame IgraphErdosRenyiGnp n p directed self
        GNM n m -> igraphErdosRenyiGame IgraphErdosRenyiGnm n (fromIntegral m)
            directed self
    initializeNullAttribute gr
    return $ Graph gr M.empty
  where
    directed = case fromSing (sing :: Sing d) of
        D -> True
        U -> False
igraphErdosRenyiGame :: (ErdosRenyi) -> (Int) -> (Double) -> (Bool) -> (Bool) -> IO ((IGraph))
igraphErdosRenyiGame a2 a3 a4 a5 a6 =
  allocaIGraph $ \a1' ->
  let {a2' = (fromIntegral . fromEnum) a2} in
  let {a3' = fromIntegral a3} in
  let {a4' = realToFrac a4} in
  let {a5' = C2HSImp.fromBool a5} in
  let {a6' = C2HSImp.fromBool a6} in
  igraphErdosRenyiGame'_ a1' a2' a3' a4' a5' a6' >>= \res ->
  addIGraphFinalizer  a1'>>= \a1'' ->
  return (a1'')

{-# LINE 100 "src/IGraph/Algorithms/Generators.chs" #-}


-- | Generates a random graph with a given degree sequence.
degreeSequenceGame :: [Int]   -- ^ Out degree
                   -> [Int]   -- ^ In degree
                   -> IO (Graph 'D () ())
degreeSequenceGame out_deg in_deg = do
    igraphInit
    withList out_deg $ \out_deg' ->
        withList in_deg $ \in_deg' -> do
            gr <- igraphDegreeSequenceGame out_deg' in_deg' IgraphDegseqSimple
            initializeNullAttribute gr
            return $ Graph gr M.empty
igraphDegreeSequenceGame :: (Ptr Vector) -> (Ptr Vector) -> (Degseq) -> IO ((IGraph))
igraphDegreeSequenceGame a2 a3 a4 =
  allocaIGraph $ \a1' ->
  let {a2' = castPtr a2} in
  let {a3' = castPtr a3} in
  let {a4' = (fromIntegral . fromEnum) a4} in
  igraphDegreeSequenceGame'_ a1' a2' a3' a4' >>= \res ->
  addIGraphFinalizer  a1'>>= \a1'' ->
  return (a1'')

{-# LINE 116 "src/IGraph/Algorithms/Generators.chs" #-}


-- | Randomly rewires a graph while preserving the degree distribution.
rewire :: (Serialize v, Ord v, Serialize e)
       => Int    -- ^ Number of rewiring trials to perform.
       -> Graph d v e
       -> IO (Graph d v e)
rewire n gr = do
    gr' <- thaw gr
    igraphRewire (_mgraph gr') n IgraphRewiringSimple
    unsafeFreeze gr'
igraphRewire :: (IGraph) -> (Int) -> (Rewiring) -> IO ()
igraphRewire a1 a2 a3 =
  (withIGraph) a1 $ \a1' ->
  let {a2' = fromIntegral a2} in
  let {a3' = (fromIntegral . fromEnum) a3} in
  igraphRewire'_ a1' a2' a3' >>= \res ->
  return ()

{-# LINE 127 "src/IGraph/Algorithms/Generators.chs" #-}


foreign import ccall safe "IGraph/Algorithms/Generators.chs.h igraph_full"
  igraphFull'_ :: ((C2HSImp.Ptr (IGraph)) -> (C2HSImp.CInt -> (C2HSImp.CInt -> (C2HSImp.CInt -> (IO C2HSImp.CInt)))))

foreign import ccall safe "IGraph/Algorithms/Generators.chs.h igraph_star"
  igraphStar'_ :: ((C2HSImp.Ptr (IGraph)) -> (C2HSImp.CInt -> (C2HSImp.CInt -> (C2HSImp.CInt -> (IO C2HSImp.CInt)))))

foreign import ccall safe "IGraph/Algorithms/Generators.chs.h igraph_ring"
  igraphRing'_ :: ((C2HSImp.Ptr (IGraph)) -> (C2HSImp.CInt -> (C2HSImp.CInt -> (C2HSImp.CInt -> (C2HSImp.CInt -> (IO C2HSImp.CInt))))))

foreign import ccall safe "IGraph/Algorithms/Generators.chs.h igraph_erdos_renyi_game"
  igraphErdosRenyiGame'_ :: ((C2HSImp.Ptr (IGraph)) -> (C2HSImp.CInt -> (C2HSImp.CInt -> (C2HSImp.CDouble -> (C2HSImp.CInt -> (C2HSImp.CInt -> (IO C2HSImp.CInt)))))))

foreign import ccall safe "IGraph/Algorithms/Generators.chs.h igraph_degree_sequence_game"
  igraphDegreeSequenceGame'_ :: ((C2HSImp.Ptr (IGraph)) -> ((C2HSImp.Ptr ()) -> ((C2HSImp.Ptr ()) -> (C2HSImp.CInt -> (IO C2HSImp.CInt)))))

foreign import ccall safe "IGraph/Algorithms/Generators.chs.h igraph_rewire"
  igraphRewire'_ :: ((C2HSImp.Ptr (IGraph)) -> (C2HSImp.CInt -> (C2HSImp.CInt -> (IO C2HSImp.CInt))))