{-# LANGUAGE ScopedTypeVariables#-}
module MultisetOrdering where

import Data.Hashable
import Language.REST.Dot
import qualified Data.Maybe as Mb
import qualified Data.List as L
import qualified Language.REST.Internal.MultiSet as M
import qualified Data.HashMap.Strict as Mp
import qualified Data.HashSet as S
import Language.REST.Types

data Replace a =
    ReplaceOne a a
  | Replace a [a]
  deriving (Int -> Replace a -> ShowS
[Replace a] -> ShowS
Replace a -> String
(Int -> Replace a -> ShowS)
-> (Replace a -> String)
-> ([Replace a] -> ShowS)
-> Show (Replace a)
forall a. Show a => Int -> Replace a -> ShowS
forall a. Show a => [Replace a] -> ShowS
forall a. Show a => Replace a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> Replace a -> ShowS
showsPrec :: Int -> Replace a -> ShowS
$cshow :: forall a. Show a => Replace a -> String
show :: Replace a -> String
$cshowList :: forall a. Show a => [Replace a] -> ShowS
showList :: [Replace a] -> ShowS
Show)

newtype MultisetGE a = MultisetGE [Replace a] deriving (Int -> MultisetGE a -> ShowS
[MultisetGE a] -> ShowS
MultisetGE a -> String
(Int -> MultisetGE a -> ShowS)
-> (MultisetGE a -> String)
-> ([MultisetGE a] -> ShowS)
-> Show (MultisetGE a)
forall a. Show a => Int -> MultisetGE a -> ShowS
forall a. Show a => [MultisetGE a] -> ShowS
forall a. Show a => MultisetGE a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> MultisetGE a -> ShowS
showsPrec :: Int -> MultisetGE a -> ShowS
$cshow :: forall a. Show a => MultisetGE a -> String
show :: MultisetGE a -> String
$cshowList :: forall a. Show a => [MultisetGE a] -> ShowS
showList :: [MultisetGE a] -> ShowS
Show)

type GTE a = a -> a -> Bool

type Indexed a = (a, Int)

type IndexedMultisetPair a = (Indexed (M.MultiSet (Indexed a)) , Indexed (M.MultiSet (Indexed a)))

multisetGE :: forall a . Eq a => GTE a -> M.MultiSet a -> M.MultiSet a -> Maybe (MultisetGE a)
multisetGE :: forall a.
Eq a =>
GTE a -> MultiSet a -> MultiSet a -> Maybe (MultisetGE a)
multisetGE GTE a
gte MultiSet a
ts0 MultiSet a
us0 = [Replace a] -> [a] -> [a] -> Maybe (MultisetGE a)
go [] (MultiSet a -> [a]
forall a. MultiSet a -> [a]
M.toList MultiSet a
ts0) (MultiSet a -> [a]
forall a. MultiSet a -> [a]
M.toList MultiSet a
us0)
  where
    equiv :: GTE a
equiv a
t a
u = a
t GTE a
`gte` a
u Bool -> Bool -> Bool
&& a
u GTE a
`gte` a
t
    gt :: GTE a
gt a
t a
u = a
t GTE a
`gte` a
u Bool -> Bool -> Bool
&& Bool -> Bool
not (a
u GTE a
`gte` a
t)

    go :: [Replace a] -> [a] -> [a] -> Maybe (MultisetGE a)
    go :: [Replace a] -> [a] -> [a] -> Maybe (MultisetGE a)
go [Replace a]
rs (a
t : [a]
ts) [a]
us | Just a
u <- (a -> Bool) -> [a] -> Maybe a
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
L.find (GTE a
equiv a
t) [a]
us
      = [Replace a] -> [a] -> [a] -> Maybe (MultisetGE a)
go (a -> a -> Replace a
forall a. a -> a -> Replace a
ReplaceOne a
t a
uReplace a -> [Replace a] -> [Replace a]
forall a. a -> [a] -> [a]
:[Replace a]
rs) [a]
ts (a -> [a] -> [a]
forall a. Eq a => a -> [a] -> [a]
L.delete a
u [a]
us)

    go [Replace a]
rs (a
t : [a]
ts) [a]
us  =
        let
          ([a]
lts, [a]
us') = (a -> Bool) -> [a] -> ([a], [a])
forall a. (a -> Bool) -> [a] -> ([a], [a])
L.partition (a
t GTE a
`gt`)  [a]
us
        in
          [Replace a] -> [a] -> [a] -> Maybe (MultisetGE a)
go (a -> [a] -> Replace a
forall a. a -> [a] -> Replace a
Replace a
t [a]
lts Replace a -> [Replace a] -> [Replace a]
forall a. a -> [a] -> [a]
: [Replace a]
rs) [a]
ts [a]
us'
    go [Replace a]
rs [a]
ts [] = MultisetGE a -> Maybe (MultisetGE a)
forall a. a -> Maybe a
Just (MultisetGE a -> Maybe (MultisetGE a))
-> MultisetGE a -> Maybe (MultisetGE a)
forall a b. (a -> b) -> a -> b
$ [Replace a] -> MultisetGE a
forall a. [Replace a] -> MultisetGE a
MultisetGE ([Replace a] -> MultisetGE a) -> [Replace a] -> MultisetGE a
forall a b. (a -> b) -> a -> b
$ (a -> Replace a) -> [a] -> [Replace a]
forall a b. (a -> b) -> [a] -> [b]
map (a -> [a] -> Replace a
forall a. a -> [a] -> Replace a
`Replace` []) [a]
ts [Replace a] -> [Replace a] -> [Replace a]
forall a. [a] -> [a] -> [a]
++ [Replace a]
rs
    go [Replace a]
_  [] [a]
_  = Maybe (MultisetGE a)
forall a. Maybe a
Nothing


multisetOrd :: (Eq a, Hashable a, Ord a)  => [a] -> [a] -> Maybe (MultisetGE a)
multisetOrd :: forall a.
(Eq a, Hashable a, Ord a) =>
[a] -> [a] -> Maybe (MultisetGE a)
multisetOrd [a]
ts [a]
us = GTE a -> MultiSet a -> MultiSet a -> Maybe (MultisetGE a)
forall a.
Eq a =>
GTE a -> MultiSet a -> MultiSet a -> Maybe (MultisetGE a)
multisetGE GTE a
forall a. Ord a => a -> a -> Bool
(>=) ([a] -> MultiSet a
forall a. (Eq a, Hashable a) => [a] -> MultiSet a
M.fromList [a]
ts) ([a] -> MultiSet a
forall a. (Eq a, Hashable a) => [a] -> MultiSet a
M.fromList [a]
us)

zindex :: [a] -> [(a, Int)]
zindex :: forall a. [a] -> [(a, Int)]
zindex [a]
xs = [a] -> [Int] -> [(a, Int)]
forall a b. [a] -> [b] -> [(a, b)]
zip [a]
xs [Int
0 ..]

indexMS :: (Eq a, Hashable a) => M.MultiSet a -> M.MultiSet (a, Int)
indexMS :: forall a. (Eq a, Hashable a) => MultiSet a -> MultiSet (a, Int)
indexMS MultiSet a
ms = [(a, Int)] -> MultiSet (a, Int)
forall a. (Eq a, Hashable a) => [a] -> MultiSet a
M.fromList ([(a, Int)] -> MultiSet (a, Int))
-> [(a, Int)] -> MultiSet (a, Int)
forall a b. (a -> b) -> a -> b
$ [a] -> [(a, Int)]
forall a. [a] -> [(a, Int)]
zindex (MultiSet a -> [a]
forall a. MultiSet a -> [a]
M.toList MultiSet a
ms)

mkEdge :: NodeID -> NodeID -> Edge
mkEdge :: String -> String -> Edge
mkEdge String
t String
u = String -> String -> String -> String -> String -> String -> Edge
Edge String
t String
u String
" " String
"black" String
" " String
"solid"

botNodeName :: Int -> Int -> String
botNodeName :: Int -> Int -> String
botNodeName Int
tIndex Int
mIndex = String
"bot_" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
tIndex String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"_" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
mIndex

botNode :: Int -> Int -> Node
botNode :: Int -> Int -> Node
botNode Int
tIndex Int
mIndex =
  String -> String -> String -> String -> Node
Node (Int -> Int -> String
botNodeName Int
tIndex Int
mIndex) String
"⊥" String
"solid" String
"black"

toGraph' :: forall a. (Eq a, Hashable a, Show a) => GTE a -> [M.MultiSet a] -> DiGraph
toGraph' :: forall a.
(Eq a, Hashable a, Show a) =>
GTE a -> [MultiSet a] -> DiGraph
toGraph' GTE a
gte [MultiSet a]
mss0 = String -> Set Node -> Set Edge -> DiGraph
DiGraph String
"msograph" (HashSet Node -> Set Node
forall a. (Eq a, Hashable a, Ord a) => HashSet a -> Set a
toOrderedSet (HashSet Node -> HashSet Node -> HashSet Node
forall a. Eq a => HashSet a -> HashSet a -> HashSet a
S.union HashSet Node
elemNodes HashSet Node
botNodes)) (HashSet Edge -> Set Edge
forall a. (Eq a, Hashable a, Ord a) => HashSet a -> Set a
toOrderedSet HashSet Edge
edges)
  where
    indexed :: [(M.MultiSet (a, Int), Int)]
    indexed :: [(MultiSet (a, Int), Int)]
indexed = [MultiSet (a, Int)] -> [(MultiSet (a, Int), Int)]
forall a. [a] -> [(a, Int)]
zindex ((MultiSet a -> MultiSet (a, Int))
-> [MultiSet a] -> [MultiSet (a, Int)]
forall a b. (a -> b) -> [a] -> [b]
map MultiSet a -> MultiSet (a, Int)
forall a. (Eq a, Hashable a) => MultiSet a -> MultiSet (a, Int)
indexMS [MultiSet a]
mss0)

    pairs :: [((M.MultiSet (a, Int), Int), (M.MultiSet (a, Int), Int))]
    pairs :: [((MultiSet (a, Int), Int), (MultiSet (a, Int), Int))]
pairs = [(MultiSet (a, Int), Int)]
-> [(MultiSet (a, Int), Int)]
-> [((MultiSet (a, Int), Int), (MultiSet (a, Int), Int))]
forall a b. [a] -> [b] -> [(a, b)]
zip [(MultiSet (a, Int), Int)]
indexed ([(MultiSet (a, Int), Int)] -> [(MultiSet (a, Int), Int)]
forall a. HasCallStack => [a] -> [a]
tail [(MultiSet (a, Int), Int)]
indexed)

    elemNodes :: HashSet Node
elemNodes = [Node] -> HashSet Node
forall a. (Eq a, Hashable a) => [a] -> HashSet a
S.fromList ([Node] -> HashSet Node) -> [Node] -> HashSet Node
forall a b. (a -> b) -> a -> b
$ (Node -> Bool) -> [Node] -> [Node]
forall a. (a -> Bool) -> [a] -> [a]
filter Node -> Bool
hasEdge ([Node] -> [Node]) -> [Node] -> [Node]
forall a b. (a -> b) -> a -> b
$ ((MultiSet (a, Int), Int) -> [Node])
-> [(MultiSet (a, Int), Int)] -> [Node]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (MultiSet (a, Int), Int) -> [Node]
forall {a}. Show a => (MultiSet (a, Int), Int) -> [Node]
toNodes [(MultiSet (a, Int), Int)]
indexed

    hasEdge :: Node -> Bool
hasEdge Node
node = (Edge -> Bool) -> [Edge] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Edge -> Node -> Bool
`pointsTo` Node
node) ([Edge] -> Bool) -> [Edge] -> Bool
forall a b. (a -> b) -> a -> b
$ HashSet Edge -> [Edge]
forall a. HashSet a -> [a]
S.toList HashSet Edge
edges

    pointsTo :: Edge -> Node -> Bool
pointsTo Edge
edge Node
node =
      Edge -> String
from Edge
edge String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== Node -> String
nodeID Node
node Bool -> Bool -> Bool
|| Edge -> String
to Edge
edge String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== Node -> String
nodeID Node
node

    edges :: S.HashSet Edge
    edges :: HashSet Edge
edges = [Edge] -> HashSet Edge
forall a. (Eq a, Hashable a) => [a] -> HashSet a
S.fromList ([Edge] -> HashSet Edge) -> [Edge] -> HashSet Edge
forall a b. (a -> b) -> a -> b
$ [Edge]
topEdges [Edge] -> [Edge] -> [Edge]
forall a. [a] -> [a] -> [a]
++ ((Maybe Node, Edge) -> Edge) -> [(Maybe Node, Edge)] -> [Edge]
forall a b. (a -> b) -> [a] -> [b]
map (Maybe Node, Edge) -> Edge
forall a b. (a, b) -> b
snd ([((MultiSet (a, Int), Int), (MultiSet (a, Int), Int))]
-> [(Maybe Node, Edge)]
replEdges [((MultiSet (a, Int), Int), (MultiSet (a, Int), Int))]
pairs)

    topEdges :: [Edge]
topEdges = ((a, Int) -> Edge) -> [(a, Int)] -> [Edge]
forall a b. (a -> b) -> [a] -> [b]
map (a, Int) -> Edge
forall {a}. (a, Int) -> Edge
go (MultiSet (a, Int) -> [(a, Int)]
forall a. MultiSet a -> [a]
M.toList ((MultiSet (a, Int), Int) -> MultiSet (a, Int)
forall a b. (a, b) -> a
fst ((MultiSet (a, Int), Int) -> MultiSet (a, Int))
-> (MultiSet (a, Int), Int) -> MultiSet (a, Int)
forall a b. (a -> b) -> a -> b
$ [(MultiSet (a, Int), Int)] -> (MultiSet (a, Int), Int)
forall a. HasCallStack => [a] -> a
head [(MultiSet (a, Int), Int)]
indexed)) where
      go :: (a, Int) -> Edge
go (a
_, Int
index) =
        String -> String -> Edge
mkEdge String
"⊤" ((Int, Int) -> String
nodeName (Int
index,  Int
0))

    botNodes :: HashSet Node
botNodes = [Node] -> HashSet Node
forall a. (Eq a, Hashable a) => [a] -> HashSet a
S.fromList ([Node] -> HashSet Node) -> [Node] -> HashSet Node
forall a b. (a -> b) -> a -> b
$ ((Maybe Node, Edge) -> Maybe Node)
-> [(Maybe Node, Edge)] -> [Node]
forall a b. (a -> Maybe b) -> [a] -> [b]
Mb.mapMaybe (Maybe Node, Edge) -> Maybe Node
forall a b. (a, b) -> a
fst ([((MultiSet (a, Int), Int), (MultiSet (a, Int), Int))]
-> [(Maybe Node, Edge)]
replEdges [((MultiSet (a, Int), Int), (MultiSet (a, Int), Int))]
pairs)

    nodeName :: (Int,  Int) -> String
    nodeName :: (Int, Int) -> String
nodeName (Int
elemIndex,  Int
msIndex) =
      String
"n" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
elemIndex String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"_" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
msIndex

    replEdges :: [((MultiSet (a, Int), Int), (MultiSet (a, Int), Int))]
-> [(Maybe Node, Edge)]
replEdges = HashMap (Int, Int) (Int, Int)
-> [((MultiSet (a, Int), Int), (MultiSet (a, Int), Int))]
-> [(Maybe Node, Edge)]
toEdges HashMap (Int, Int) (Int, Int)
forall k v. HashMap k v
Mp.empty

    toEdges :: Mp.HashMap (Int, Int) (Int, Int) -> [IndexedMultisetPair a] -> [(Maybe Node, Edge)]
    toEdges :: HashMap (Int, Int) (Int, Int)
-> [((MultiSet (a, Int), Int), (MultiSet (a, Int), Int))]
-> [(Maybe Node, Edge)]
toEdges HashMap (Int, Int) (Int, Int)
_ [] = []
    toEdges HashMap (Int, Int) (Int, Int)
mp (((MultiSet (a, Int)
ts, Int
tsIndex), (MultiSet (a, Int)
us, Int
usIndex)) : [((MultiSet (a, Int), Int), (MultiSet (a, Int), Int))]
mss) =
        (Replace (a, Int) -> [(Maybe Node, Edge)])
-> [Replace (a, Int)] -> [(Maybe Node, Edge)]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Replace (a, Int) -> [(Maybe Node, Edge)]
forall {a}. Replace (a, Int) -> [(Maybe Node, Edge)]
redges [Replace (a, Int)]
repls [(Maybe Node, Edge)]
-> [(Maybe Node, Edge)] -> [(Maybe Node, Edge)]
forall a. [a] -> [a] -> [a]
++ HashMap (Int, Int) (Int, Int)
-> [((MultiSet (a, Int), Int), (MultiSet (a, Int), Int))]
-> [(Maybe Node, Edge)]
toEdges HashMap (Int, Int) (Int, Int)
mp' [((MultiSet (a, Int), Int), (MultiSet (a, Int), Int))]
mss
      where
        Just (MultisetGE [Replace (a, Int)]
repls) = GTE (a, Int)
-> MultiSet (a, Int)
-> MultiSet (a, Int)
-> Maybe (MultisetGE (a, Int))
forall a.
Eq a =>
GTE a -> MultiSet a -> MultiSet a -> Maybe (MultisetGE a)
multisetGE (\(a, Int)
t (a, Int)
u -> GTE a
gte ((a, Int) -> a
forall a b. (a, b) -> a
fst (a, Int)
t) ((a, Int) -> a
forall a b. (a, b) -> a
fst (a, Int)
u)) MultiSet (a, Int)
ts MultiSet (a, Int)
us

        lookupTIndex :: Int -> (Int, Int)
        lookupTIndex :: Int -> (Int, Int)
lookupTIndex Int
tindex = (Int, Int) -> Maybe (Int, Int) -> (Int, Int)
forall a. a -> Maybe a -> a
Mb.fromMaybe (Int
tindex, Int
tsIndex) ((Int, Int) -> HashMap (Int, Int) (Int, Int) -> Maybe (Int, Int)
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> Maybe v
Mp.lookup (Int
tindex, Int
tsIndex) HashMap (Int, Int) (Int, Int)
mp)

        mp' :: HashMap (Int, Int) (Int, Int)
mp' = HashMap (Int, Int) (Int, Int)
-> [Replace (a, Int)] -> HashMap (Int, Int) (Int, Int)
forall {a}.
HashMap (Int, Int) (Int, Int)
-> [Replace (a, Int)] -> HashMap (Int, Int) (Int, Int)
go HashMap (Int, Int) (Int, Int)
mp [Replace (a, Int)]
repls where
          go :: HashMap (Int, Int) (Int, Int)
-> [Replace (a, Int)] -> HashMap (Int, Int) (Int, Int)
go HashMap (Int, Int) (Int, Int)
mpi [] = HashMap (Int, Int) (Int, Int)
mpi
          go HashMap (Int, Int) (Int, Int)
mpi ((ReplaceOne (a
_, Int
i) (a
_, Int
j)):[Replace (a, Int)]
repls')
            = HashMap (Int, Int) (Int, Int)
-> [Replace (a, Int)] -> HashMap (Int, Int) (Int, Int)
go ((Int, Int)
-> (Int, Int)
-> HashMap (Int, Int) (Int, Int)
-> HashMap (Int, Int) (Int, Int)
forall k v.
(Eq k, Hashable k) =>
k -> v -> HashMap k v -> HashMap k v
Mp.insert (Int
j, Int
usIndex) (Int -> (Int, Int)
lookupTIndex Int
i) HashMap (Int, Int) (Int, Int)
mpi) [Replace (a, Int)]
repls'
          go HashMap (Int, Int) (Int, Int)
mpi (Replace (a, Int)
_:[Replace (a, Int)]
repls') = HashMap (Int, Int) (Int, Int)
-> [Replace (a, Int)] -> HashMap (Int, Int) (Int, Int)
go HashMap (Int, Int) (Int, Int)
mpi [Replace (a, Int)]
repls'


        redges :: Replace (a, Int) -> [(Maybe Node, Edge)]
redges (Replace (a
_, Int
index) [])
          = [ ( Node -> Maybe Node
forall a. a -> Maybe a
Just (Int -> Int -> Node
botNode Int
index Int
tsIndex)
              , String -> String -> Edge
mkEdge
                ((Int, Int) -> String
nodeName (Int -> (Int, Int)
lookupTIndex Int
index))
                (Int -> Int -> String
botNodeName Int
index Int
tsIndex)
              ) ]
        redges (ReplaceOne (a, Int)
_ (a, Int)
_) = []
        redges (Replace (a
_, Int
tindex) [(a, Int)]
us') = ((a, Int) -> (Maybe Node, Edge))
-> [(a, Int)] -> [(Maybe Node, Edge)]
forall a b. (a -> b) -> [a] -> [b]
map (a, Int) -> (Maybe Node, Edge)
forall {a} {a}. (a, Int) -> (Maybe a, Edge)
go [(a, Int)]
us' where
          go :: (a, Int) -> (Maybe a, Edge)
go (a
_, Int
uindex) =
            (Maybe a
forall a. Maybe a
Nothing, String -> String -> Edge
mkEdge ((Int, Int) -> String
nodeName (Int -> (Int, Int)
lookupTIndex Int
tindex)) ((Int, Int) -> String
nodeName (Int
uindex,  Int
usIndex)))

    toNodes :: (MultiSet (a, Int), Int) -> [Node]
toNodes (MultiSet (a, Int)
ms, Int
index) = ((a, Int) -> Node) -> [(a, Int)] -> [Node]
forall a b. (a -> b) -> [a] -> [b]
map (a, Int) -> Node
forall {a}. Show a => (a, Int) -> Node
go (MultiSet (a, Int) -> [(a, Int)]
forall a. MultiSet a -> [a]
M.toList MultiSet (a, Int)
ms) where

      go :: (a, Int) -> Node
go (a
e, Int
elemIndex) =
        String -> String -> String -> String -> Node
Node
          ((Int, Int) -> String
nodeName (Int
elemIndex, Int
index))
          (a -> String
forall a. Show a => a -> String
show a
e)
          String
"solid"
          String
"black"

toGraph :: (Ord a, Eq a, Hashable a, Show a) => [[a]] -> DiGraph
toGraph :: forall a. (Ord a, Eq a, Hashable a, Show a) => [[a]] -> DiGraph
toGraph [[a]]
mss = GTE a -> [MultiSet a] -> DiGraph
forall a.
(Eq a, Hashable a, Show a) =>
GTE a -> [MultiSet a] -> DiGraph
toGraph' GTE a
forall a. Ord a => a -> a -> Bool
(>=) ([MultiSet a] -> DiGraph) -> [MultiSet a] -> DiGraph
forall a b. (a -> b) -> a -> b
$ ([a] -> MultiSet a) -> [[a]] -> [MultiSet a]
forall a b. (a -> b) -> [a] -> [b]
map [a] -> MultiSet a
forall a. (Eq a, Hashable a) => [a] -> MultiSet a
M.fromList [[a]]
mss

mkMSOGraph :: (Ord a, Eq a, Hashable a, Show a) => String -> [[a]] -> IO ()
mkMSOGraph :: forall a.
(Ord a, Eq a, Hashable a, Show a) =>
String -> [[a]] -> IO ()
mkMSOGraph String
name [[a]]
mss = String -> DiGraph -> IO ()
mkGraph String
name ([[a]] -> DiGraph
forall a. (Ord a, Eq a, Hashable a, Show a) => [[a]] -> DiGraph
toGraph [[a]]
mss)

mkMSOGraphs :: (Ord a, Eq a, Hashable a, Show a) => String -> [[a]] -> IO ()
mkMSOGraphs :: forall a.
(Ord a, Eq a, Hashable a, Show a) =>
String -> [[a]] -> IO ()
mkMSOGraphs String
name [[a]]
mss0 = ([[a]] -> IO ()) -> [[[a]]] -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ [[a]] -> IO ()
forall {a}. (Ord a, Hashable a, Show a) => [[a]] -> IO ()
go (Int -> [[[a]]] -> [[[a]]]
forall a. Int -> [a] -> [a]
drop Int
1 ([[[a]]] -> [[[a]]]) -> [[[a]]] -> [[[a]]]
forall a b. (a -> b) -> a -> b
$ [[a]] -> [[[a]]]
forall a. [a] -> [[a]]
L.inits [[a]]
mss0) where
  go :: [[a]] -> IO ()
go [[a]]
mss = String -> DiGraph -> IO ()
mkGraph (String
name String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show ([[a]] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [[a]]
mss)) ([[a]] -> DiGraph
forall a. (Ord a, Eq a, Hashable a, Show a) => [[a]] -> DiGraph
toGraph [[a]]
mss)

multisetGE' :: (Ord a, Hashable a) => [a] -> [a] -> Maybe (MultisetGE a)
multisetGE' :: forall a. (Ord a, Hashable a) => [a] -> [a] -> Maybe (MultisetGE a)
multisetGE' [a]
ts [a]
us = GTE a -> MultiSet a -> MultiSet a -> Maybe (MultisetGE a)
forall a.
Eq a =>
GTE a -> MultiSet a -> MultiSet a -> Maybe (MultisetGE a)
multisetGE GTE a
forall a. Ord a => a -> a -> Bool
(>=) ([a] -> MultiSet a
forall a. (Eq a, Hashable a) => [a] -> MultiSet a
M.fromList [a]
ts) ([a] -> MultiSet a
forall a. (Eq a, Hashable a) => [a] -> MultiSet a
M.fromList [a]
us)