conditional
  :: MLN -- ^ The Markov logic network.
  -> [Term] -- ^ List of constants to ground the Markov logic network.
  -> Set (Predicate, Bool) -- ^ An set of assignments for the query.
  -> Set (Predicate, Bool) -- ^ Conditions.
  -> Double -- ^ A probability in [0.0, 1.0]
conditional mln ts query cond = vnum / vden
   where
     vnum = sum $ map evalNet numerator
     vden = sum $ map evalNet denom
     -- All possible assignments
     allass = allAss ts fs
     -- Assignments to evaluate:
     (numerator, _) = partitionAss (Set.union query cond) allass
     (denom, _ ) = partitionAss cond allass
     -- The formula (the factors) to evaluate
     fs = allWGroundings ts mln
     -- Value of the network for a given assignment.
     evalNet ass' = exp $ Map.foldrWithKey (\f w a -> val f w ass' + a) 0.0 (network fs)
     -- Values of a factor
     val f w ass' = let v = FOL.eval ass' f in
       if v == FOL.top then w
       else if v == FOL.bot then 0.0
       else error ("Eval failed for " ++ show v ++ " given " ++ show ass')

-- | Algorithm to construct a network for Markov logic network inference.
--
-- Reference:
--   P Domingos and D Lowd, Markov Logic: An Interface Layer for Artificial
-- Intelligence, 2009, Morgan & Claypool. p. 26.
conditional
  :: MLN -- ^ The Markov logic network.
  -> [Term] -- ^ List of constants to ground the Markov logic network.
  -> Set (Predicate, Bool) -- ^ An set of assignments for the query.
  -> Set (Predicate, Bool) -- ^ Conditions.
  -> Double
conditional mln ts query cond = vnum / vden
   where
     vnum = sum $ map evalNet numerator
     vden = sum $ map evalNet denom
     -- All possible assignments
     allass = allAss ts fs
     -- Assignments to evaluate:
     (numerator, _) = partitionAss (Set.union query cond) allass
     (denom, _ ) = partitionAss cond allass
     -- The formula (the factors) to evaluate
     fs = allWGroundings ts mln
     -- Value of the network for a given assignment.
     evalNet ass' = exp $ Map.foldrWithKey (\f w a -> val f w ass' + a) 0.0 (network fs)
     -- Values of a factor
     val f w ass' = let v = FOL.eval ass' f in
       if v == FOL.top then w
       else if v == FOL.bot then 0.0
       else error ("Eval failed for " ++ show v ++ " given " ++ show ass')

-- | Algorithm to construct a network for Markov logic network inference.
--
-- Reference:
--   P Domingos and D Lowd, Markov Logic: An Interface Layer for Artificial
-- Intelligence, 2009, Morgan & Claypool. p. 26.
conditional mln ts query cond = vnum / vden
   where
     vnum = sum $ map evalNet numerator
     vden = sum $ map evalNet denom
     -- All possible assignments
     allass = allAss ts fs
     -- Assignments to evaluate:
     (numerator, _) = partitionAss (Set.union query cond) allass
     (denom, _ ) = partitionAss cond allass
     -- The formula (the factors) to evaluate
     fs = allWGroundings ts mln
     -- Value of the network for a given assignment.
     evalNet ass' = exp $ Map.foldrWithKey (\f w a -> val f w ass' + a) 0.0 (network fs)
     -- Values of a factor
     val f w ass' = let v = FOL.eval ass' f in
       if v == FOL.top then w
       else if v == FOL.bot then 0.0
       else error ("Eval failed for " ++ show v ++ " given " ++ show ass')

-- | Algorithm to construct a network for Markov logic network inference.
--
-- Reference:
--   P Domingos and D Lowd, Markov Logic: An Interface Layer for Artificial
-- Intelligence, 2009, Morgan & Claypool. p. 26.