-- | Builds a ground network for Markov logic.
groundNetwork :: [Term] -> MLN -> UNetwork Predicate
groundNetwork ts (MLN m) = Set.foldr' (\p acc -> Map.insert p (mb p) acc) Map.empty ps
  where
    -- All groundings from all formulas in the knowledge base:
    gs = Set.foldr' (\g acc -> Set.union (FOL.groundings ts g) acc) Set.empty (Map.keysSet m)
    -- All the predicates
    ps = FS.allPredicates gs
    -- The Markov blanket of predicate 'p', that is: all its neighbours.
    mb p = Set.delete p $ FS.allPredicates $ Set.filter (FOL.hasPred p) gs

-- | Returns all the factors in the MLN. Instead of mappings sets of predicates
-- to weights, this function maps them to the formula (the MLN provides the
-- weight).
groundNetwork :: [Term] -> MLN -> UNetwork Predicate
groundNetwork ts (MLN m) = Set.foldr' (\p acc -> Map.insert p (mb p) acc) Map.empty ps
  where
    -- All groundings from all formulas in the knowledge base:
    gs = Set.foldr' (\g acc -> Set.union (FOL.groundings ts g) acc) Set.empty (Map.keysSet m)
    -- All the predicates
    ps = FS.allPredicates gs
    -- The Markov blanket of predicate 'p', that is: all its neighbours.
    mb p = Set.delete p $ FS.allPredicates $ Set.filter (FOL.hasPred p) gs

-- | Returns all the factors in the MLN. Instead of mappings sets of predicates
-- to weights, this function maps them to the formula (the MLN provides the
-- weight).
groundNetwork ts (MLN m) = Set.foldr' (\p acc -> Map.insert p (mb p) acc) Map.empty ps
  where
    -- All groundings from all formulas in the knowledge base:
    gs = Set.foldr' (\g acc -> Set.union (FOL.groundings ts g) acc) Set.empty (Map.keysSet m)
    -- All the predicates
    ps = FS.allPredicates gs
    -- The Markov blanket of predicate 'p', that is: all its neighbours.
    mb p = Set.delete p $ FS.allPredicates $ Set.filter (FOL.hasPred p) gs

-- | Returns all the factors in the MLN. Instead of mappings sets of predicates
-- to weights, this function maps them to the formula (the MLN provides the
-- weight).