{- | Examples of networks

/Creating a simple network/

The 'example' function is the typical example.
It is using the monad 'BNMonad'. The goal of this monad is to offer
a way of describing the network which is natural.

There are only three functions to understand inside the monad:

  * 'variable' to create a discrete variable of type 'DV'. Creating a discrete
  variable is using a 'Bounded' and 'Enum' type like for instance 'Bool'.

  * 'proba' to define the probability P(A) of a variable A

  * 'cpt'  to define the conditional probability table P(A | BC)

It is important to understand how the values are organized. If you define
P( wet | sprinkler road) then you have to give the values in the order:

@
wet=False, sprinkler=False, road=False
wet=False, sprinkler=False, road=True
wet=False, sprinkler=True, road=False
wet=False, sprinkler=True, road=True
@

Finally, don't forget to return the discrete variables at the end of your network
construction because those variables are used for making inferences.

@
example :: ('DVSet','SBN' 'CPT')
example = 'runBN' $ do 
    winter <- 'variable' \"winter\" (t :: Bool)
    sprinkler <- 'variable' \"sprinkler\" (t :: Bool) 
    wet <- 'variable' \"wet grass\" (t :: Bool) 
    rain <- 'variable' \"rain\" (t :: Bool) 
    road <- 'variable' \"slippery road\" (t :: Bool) 
--
    'proba' winter ~~ [0.4,0.6]
    'cpt' sprinkler [winter] ~~ [0.25,0.8,0.75,0.2]
    'cpt' rain [winter] ~~ [0.9,0.2,0.1,0.8]
    'cpt' wet [sprinkler,rain] ~~ [1,0.2,0.1,0.05,0,0.8,0.9,0.95]
    'cpt' road [rain] ~~ [1,0.3,0,0.7]
    return [winter,sprinkler,rain,wet,road]
@

/Importing a network from a Hugin file/

The 'exampleImport' function can be used to import a file in Hugin format.
Only a subset of the format is supported.
The function will return a mapping from node names to Discrete Variables 'DV'.
The node name is used and not the node's label.
The function is also returning a simple bayesian network 'SBN' using 'CPT'
as factors.

The implementation is using 'getDataFileName' to find the path of the
test pattern installed by cabal.

@
exampleImport :: IO (Map.Map String 'DV','SBN' 'CPT')
exampleImport = do 
    path <- 'getDataFileName' \"cancer.net\"
    r <- 'importBayesianGraph' path
    return ('runBN' $ fromJust r)
@

-}
module Bayes.Examples(
   example
 , exampleJunction
#ifndef LOCAL
 , exampleImport
#endif
 , exampleDiabete
 , exampleAsia
 , examplePoker
 , exampleFarm
 , examplePerso
 , testJunction
 , anyExample
 ) where 

import Bayes
import Bayes.Factor
import Bayes.ImportExport.HuginNet
import Data.Maybe(fromJust)
import qualified Data.Map as Map
import System.Directory(getHomeDirectory)
import System.FilePath((</>))

#ifndef LOCAL
import Paths_hbayes

-- | Example showing how to import a graph described into
-- a Hugin file.
exampleImport :: IO (Map.Map String DV,SBN CPT)
exampleImport = do 
    path <- getDataFileName "cancer.net"
    r <- importBayesianGraph path
    return (runBN $ fromJust r)
#endif

-- | Genereic loading functions to load some other
-- examples from the author's dropbox.
-- Those additional examples are not distributed with this package.
-- They are used only for testing and debugging purposes
genericExample :: String -> IO (Map.Map String DV,SBN CPT)
genericExample s = do 
    r <- importBayesianGraph s
    return (runBN $ fromJust r)

anyExample s = do
    h <- getHomeDirectory
    genericExample $ h </> "Dropbox/bayes_examples" </> s
   
-- | Diabete example (not provided with this package)
exampleDiabete = do 
    h <- getHomeDirectory
    genericExample $ h </> "Dropbox/bayes_examples/Diabetes.hugin"

-- | Asia example (not provided with this package)
exampleAsia = do 
    h <- getHomeDirectory
    genericExample $ h </> "Dropbox/bayes_examples/asia.net"

-- | Poker example (not provided with this package)
examplePoker = do 
    h <- getHomeDirectory
    genericExample $ h </> "Dropbox/bayes_examples/poker.net"

-- | Farm example (not provided with this package)
exampleFarm = do 
    h <- getHomeDirectory
    genericExample $ h </> "Dropbox/bayes_examples/studfarm.net"

-- | Perso example (not provided with this package)
examplePerso = do 
    h <- getHomeDirectory
    genericExample $ h </> "Dropbox/bayes_examples/mytest.net"


-- | Standard example found in many books about Bayesian Networks.
example :: ([DV],SBN CPT)
example = runBN $ do 
    winter <- variable "winter" (t :: Bool)
    sprinkler <- variable "sprinkler" (t :: Bool) 
    wet <- variable "wet grass" (t :: Bool) 
    rain <- variable "rain" (t :: Bool) 
    road <- variable "slippery road" (t :: Bool) 

    proba winter ~~ [0.4,0.6]
    cpt sprinkler [winter] ~~ [0.25,0.8,0.75,0.2]
    cpt rain [winter] ~~ [0.9,0.2,0.1,0.8]
    cpt wet [sprinkler,rain] ~~ [1,0.2,0.1,0.05,0,0.8,0.9,0.95]
    cpt road [rain] ~~ [1,0.3,0,0.7]
    return [winter,sprinkler,rain,wet,road]

testJunction  :: DirectedSG () Vertex
testJunction = execGraph $ do
    a <- graphNode "A" (Vertex 0) 
    b <- graphNode "B" (Vertex 1) 
    c <- graphNode "C" (Vertex 2) 
    newEdge a b () 
    newEdge a c ()

exampleJunction :: UndirectedSG () Vertex
exampleJunction = execGraph $ do 
    a <- graphNode "A" (Vertex 0) 
    b <- graphNode "B" (Vertex 1) 
    c <- graphNode "C" (Vertex 2) 
    d <- graphNode "D" (Vertex 3) 
    e <- graphNode "E" (Vertex 4) 
    f <- graphNode "F" (Vertex 5) 
    g <- graphNode "G" (Vertex 6) 
    h <- graphNode "H" (Vertex 7) 

    newEdge a b () 
    newEdge a c ()
    newEdge b d ()
    newEdge c e () 
    newEdge d e ()
    newEdge d f ()
    newEdge e f ()
    newEdge c g ()
    newEdge e h ()
    newEdge g h ()
    newEdge g e ()
    
    return ()