module Bayes.EliminationOrdering
( EliminationOrdering, nextVariable
, simpleOrder, staticOrder, minFactorOrder, minFactorVars
) where
import Bayes.Factor
import Data.List
newtype EliminationOrdering = Elim { fromElim :: [Dimensions] -> [String] -> Maybe (String, EliminationOrdering) }
nextVariable :: EliminationOrdering -> [Factor] -> [String] -> Maybe (String, EliminationOrdering)
nextVariable (Elim f) fs = f (map dimensions fs)
simpleOrder :: EliminationOrdering
simpleOrder = Elim $ \ds keeps ->
case filter (`notElem` keeps) (vars ds) of
[] -> Nothing
y:_ -> Just (y, simpleOrder)
staticOrder :: [String] -> EliminationOrdering
staticOrder xs = Elim $ \ds keeps ->
let rec [] = fromElim simpleOrder ds keeps
rec (y:ys)
| y `elem` keeps = rec ys
| otherwise = Just (y, staticOrder ys)
in rec xs
minFactorOrder :: EliminationOrdering
minFactorOrder = Elim $ \ds keeps ->
case minFactorNext (`notElem` keeps) ds of
Just v -> Just (v, minFactorOrder)
Nothing -> Nothing
minFactorNext :: (String -> Bool) -> [Dimensions] -> Maybe String
minFactorNext p ds =
case sortOn fst (map f vs) of
[] -> Nothing
(_, v):_ -> Just v
where
vs = filter p (vars ds)
f v = let xs = filter (hasVarD v) ds
res = mergesD xs
in (size res - size xs, v)
minFactorVars :: [Factor] -> [String]
minFactorVars fs =
case minFactorNext (const True) (map dimensions fs) of
Just v -> v : minFactorVars (eliminate fs v)
Nothing -> []