-- This module exports some useful join functions for propagator cells. -- A join function describes how an old cell value is combined with a new one. -- See the package @propeller@ for details on the propagator implementation. module AI.Search.FiniteDomain.Int.Cell ( domainJoin , eqJoin , mustHoldJoin ) where -- domain import Numeric.Domain ( Domain, intersect, isSubsetOf ) -- propeller import Data.Propagator.Change ( Change(..) ) -- | Compares an old and a new domain of integer values to see if the new -- domain is a subset of the old domain (i.e., the cell has changed). -- -- Never returns 'Incompatible'. domainJoin :: Domain Int -> Domain Int -> Change (Domain Int) domainJoin old new = case intersect old new of reduced | reduced `isSubsetOf` old -> Changed reduced | otherwise -> Unchanged -- | Compares an old and a new value to see if there was a change. -- -- Never returns 'Incompatible'. eqJoin :: Eq a => a -> a -> Change a eqJoin old new | old == new = Unchanged | otherwise = Changed new -- | Checks if a new cell value is ... -- -- * 'True', then 'Unchanged' is returned, or -- * 'False', then 'Incompatible' is returned. -- -- This can be used to represent conditions which must always hold -- (i.e., the cell value must always be 'True'). -- -- The old value of the cell is ignored. Never returns 'Changed'. mustHoldJoin :: a -> Bool -> Change b mustHoldJoin _ True = Unchanged mustHoldJoin _ False = Incompatible