module MonusWeightedSearch.Examples.Dijkstra where
import Prelude hiding (head)
import Control.Monad.State.Strict
import Control.Applicative
import Control.Monad.Writer
import Control.Monad
import Data.Foldable
import Data.Monus.Dist
import Data.Set (Set)
import qualified Data.Set as Set
import Data.List.NonEmpty (NonEmpty(..))
import Control.Monad.Heap
graph :: Graph Int
graph :: Graph Int
graph Int
1 = [(Int
2,Dist
7),(Int
3,Dist
9),(Int
6,Dist
14)]
graph Int
2 = [(Int
3,Dist
10),(Int
4,Dist
15)]
graph Int
3 = [(Int
4,Dist
11), (Int
6,Dist
2)]
graph Int
4 = [(Int
5,Dist
6)]
graph Int
5 = []
graph Int
6 = [(Int
5,Dist
9)]
graph Int
_ = []
unique :: Ord a => a -> HeapT w (State (Set a)) a
unique :: forall a w. Ord a => a -> HeapT w (State (Set a)) a
unique a
x = do
Set a
seen <- HeapT w (State (Set a)) (Set a)
forall s (m :: Type -> Type). MonadState s m => m s
get
Bool -> HeapT w (State (Set a)) ()
forall (f :: Type -> Type). Alternative f => Bool -> f ()
guard (a -> Set a -> Bool
forall a. Ord a => a -> Set a -> Bool
Set.notMember a
x Set a
seen)
(Set a -> Set a) -> HeapT w (State (Set a)) ()
forall s (m :: Type -> Type). MonadState s m => (s -> s) -> m ()
modify (a -> Set a -> Set a
forall a. Ord a => a -> Set a -> Set a
Set.insert a
x)
pure a
x
{-# INLINE unique #-}
star :: MonadPlus m => (a -> m a) -> a -> m a
star :: forall (m :: Type -> Type) a. MonadPlus m => (a -> m a) -> a -> m a
star a -> m a
f a
x = a -> m a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure a
x m a -> m a -> m a
forall (f :: Type -> Type) a. Alternative f => f a -> f a -> f a
<|> (a -> m a
f a
x m a -> (a -> m a) -> m a
forall (m :: Type -> Type) a b. Monad m => m a -> (a -> m b) -> m b
>>= (a -> m a) -> a -> m a
forall (m :: Type -> Type) a. MonadPlus m => (a -> m a) -> a -> m a
star a -> m a
f)
{-# INLINE star #-}
pathed :: MonadPlus m => (a -> m a) -> a -> m (NonEmpty a)
pathed :: forall (m :: Type -> Type) a.
MonadPlus m =>
(a -> m a) -> a -> m (NonEmpty a)
pathed a -> m a
f = (NonEmpty a -> m (NonEmpty a)) -> NonEmpty a -> m (NonEmpty a)
forall (m :: Type -> Type) a. MonadPlus m => (a -> m a) -> a -> m a
star (\ ~(a
x :| [a]
xs) -> (a -> NonEmpty a) -> m a -> m (NonEmpty a)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap (a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
:|a
xa -> [a] -> [a]
forall a. a -> [a] -> [a]
:[a]
xs) (a -> m a
f a
x)) (NonEmpty a -> m (NonEmpty a))
-> (a -> NonEmpty a) -> a -> m (NonEmpty a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
:| [])
{-# INLINE pathed #-}
dijkstra :: Ord a => Graph a -> a -> [(a, Dist)]
dijkstra :: forall a. Ord a => Graph a -> Graph a
dijkstra Graph a
g a
x =
State (Set a) [(a, Dist)] -> Set a -> [(a, Dist)]
forall s a. State s a -> s -> a
evalState (HeapT Dist (State (Set a)) a -> State (Set a) [(a, Dist)]
forall (m :: Type -> Type) w a.
(Monad m, Monus w) =>
HeapT w m a -> m [(a, w)]
searchT ((a -> HeapT Dist (State (Set a)) a)
-> a -> HeapT Dist (State (Set a)) a
forall (m :: Type -> Type) a. MonadPlus m => (a -> m a) -> a -> m a
star ([HeapT Dist (State (Set a)) a] -> HeapT Dist (State (Set a)) a
forall (t :: Type -> Type) (f :: Type -> Type) a.
(Foldable t, Alternative f) =>
t (f a) -> f a
asum ([HeapT Dist (State (Set a)) a] -> HeapT Dist (State (Set a)) a)
-> (a -> [HeapT Dist (State (Set a)) a])
-> a
-> HeapT Dist (State (Set a)) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((a, Dist) -> HeapT Dist (State (Set a)) a)
-> [(a, Dist)] -> [HeapT Dist (State (Set a)) a]
forall a b. (a -> b) -> [a] -> [b]
map (\(a
x,Dist
w) -> Dist -> HeapT Dist (State (Set a)) ()
forall w (m :: Type -> Type). MonadWriter w m => w -> m ()
tell Dist
w HeapT Dist (State (Set a)) ()
-> HeapT Dist (State (Set a)) a -> HeapT Dist (State (Set a)) a
forall (m :: Type -> Type) a b. Monad m => m a -> m b -> m b
>> a -> HeapT Dist (State (Set a)) a
forall a w. Ord a => a -> HeapT w (State (Set a)) a
unique a
x) ([(a, Dist)] -> [HeapT Dist (State (Set a)) a])
-> Graph a -> a -> [HeapT Dist (State (Set a)) a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Graph a
g) (a -> HeapT Dist (State (Set a)) a)
-> HeapT Dist (State (Set a)) a -> HeapT Dist (State (Set a)) a
forall (m :: Type -> Type) a b. Monad m => (a -> m b) -> m a -> m b
=<< a -> HeapT Dist (State (Set a)) a
forall a w. Ord a => a -> HeapT w (State (Set a)) a
unique a
x)) Set a
forall a. Set a
Set.empty
{-# INLINE dijkstra #-}
shortestPaths :: Ord a => Graph a -> a -> [(NonEmpty a, Dist)]
shortestPaths :: forall a. Ord a => Graph a -> a -> [(NonEmpty a, Dist)]
shortestPaths Graph a
g a
x =
State (Set a) [(NonEmpty a, Dist)] -> Set a -> [(NonEmpty a, Dist)]
forall s a. State s a -> s -> a
evalState (HeapT Dist (State (Set a)) (NonEmpty a)
-> State (Set a) [(NonEmpty a, Dist)]
forall (m :: Type -> Type) w a.
(Monad m, Monus w) =>
HeapT w m a -> m [(a, w)]
searchT ((a -> HeapT Dist (State (Set a)) a)
-> a -> HeapT Dist (State (Set a)) (NonEmpty a)
forall (m :: Type -> Type) a.
MonadPlus m =>
(a -> m a) -> a -> m (NonEmpty a)
pathed ([HeapT Dist (State (Set a)) a] -> HeapT Dist (State (Set a)) a
forall (t :: Type -> Type) (f :: Type -> Type) a.
(Foldable t, Alternative f) =>
t (f a) -> f a
asum ([HeapT Dist (State (Set a)) a] -> HeapT Dist (State (Set a)) a)
-> (a -> [HeapT Dist (State (Set a)) a])
-> a
-> HeapT Dist (State (Set a)) a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((a, Dist) -> HeapT Dist (State (Set a)) a)
-> [(a, Dist)] -> [HeapT Dist (State (Set a)) a]
forall a b. (a -> b) -> [a] -> [b]
map (\(a
x,Dist
w) -> Dist -> HeapT Dist (State (Set a)) ()
forall w (m :: Type -> Type). MonadWriter w m => w -> m ()
tell Dist
w HeapT Dist (State (Set a)) ()
-> HeapT Dist (State (Set a)) a -> HeapT Dist (State (Set a)) a
forall (m :: Type -> Type) a b. Monad m => m a -> m b -> m b
>> a -> HeapT Dist (State (Set a)) a
forall a w. Ord a => a -> HeapT w (State (Set a)) a
unique a
x) ([(a, Dist)] -> [HeapT Dist (State (Set a)) a])
-> Graph a -> a -> [HeapT Dist (State (Set a)) a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Graph a
g) (a -> HeapT Dist (State (Set a)) (NonEmpty a))
-> HeapT Dist (State (Set a)) a
-> HeapT Dist (State (Set a)) (NonEmpty a)
forall (m :: Type -> Type) a b. Monad m => (a -> m b) -> m a -> m b
=<< a -> HeapT Dist (State (Set a)) a
forall a w. Ord a => a -> HeapT w (State (Set a)) a
unique a
x)) Set a
forall a. Set a
Set.empty
{-# INLINE shortestPaths #-}