mirror of
https://git.cs.ou.nl/joshua.moerman/mealy-decompose.git
synced 2025-04-30 02:07:44 +02:00
Made isRefinementOf much faster
This commit is contained in:
parent
e20251c07d
commit
a20e5e9317
2 changed files with 46 additions and 16 deletions
25
app/Main.hs
25
app/Main.hs
|
@ -10,9 +10,7 @@ import Control.Monad.Trans.State.Strict
|
||||||
import Control.Monad (forM_, when, forever)
|
import Control.Monad (forM_, when, forever)
|
||||||
import Data.Map.Strict qualified as Map
|
import Data.Map.Strict qualified as Map
|
||||||
import Data.Maybe (mapMaybe)
|
import Data.Maybe (mapMaybe)
|
||||||
-- import Data.Semigroup (Arg(..))
|
import Data.List.Ordered (nubSort)
|
||||||
-- import Data.Set qualified as Set
|
|
||||||
-- import Data.List.Ordered (nubSort)
|
|
||||||
import Data.List (minimumBy)
|
import Data.List (minimumBy)
|
||||||
import Data.Function (on)
|
import Data.Function (on)
|
||||||
import System.Environment
|
import System.Environment
|
||||||
|
@ -61,8 +59,8 @@ main = do
|
||||||
|
|
||||||
-- Then compute each projection
|
-- Then compute each projection
|
||||||
-- I did some manual preprocessing, these are the only interesting bits
|
-- I did some manual preprocessing, these are the only interesting bits
|
||||||
let outs = ["10", "10-O9", "2.2", "3.0", "3.1", "3.10", "3.12", "3.13", "3.14", "3.16", "3.17", "3.18", "3.19", "3.2", "3.20", "3.21", "3.3", "3.4", "3.6", "3.7", "3.8", "3.9", "5.0", "5.1", "5.12", "5.13", "5.17", "5.2", "5.21", "5.23", "5.6", "5.7", "5.8", "5.9", "quiescence"]
|
let -- outs = ["10", "10-O9", "2.2", "3.0", "3.1", "3.10", "3.12", "3.13", "3.14", "3.16", "3.17", "3.18", "3.19", "3.2", "3.20", "3.21", "3.3", "3.4", "3.6", "3.7", "3.8", "3.9", "5.0", "5.1", "5.12", "5.13", "5.17", "5.2", "5.21", "5.23", "5.6", "5.7", "5.8", "5.9", "quiescence"]
|
||||||
-- outs = outputs machine
|
outs = outputs machine
|
||||||
projections0 = allProjections machine outs
|
projections0 = allProjections machine outs
|
||||||
projections = zip outs $ fmap refineMealy projections0
|
projections = zip outs $ fmap refineMealy projections0
|
||||||
|
|
||||||
|
@ -72,6 +70,7 @@ main = do
|
||||||
printPartition partition
|
printPartition partition
|
||||||
)
|
)
|
||||||
|
|
||||||
|
{-
|
||||||
let totalSize = sum (fmap (numBlocks . snd) projections)
|
let totalSize = sum (fmap (numBlocks . snd) projections)
|
||||||
|
|
||||||
putStrLn $ "total size = " <> show totalSize
|
putStrLn $ "total size = " <> show totalSize
|
||||||
|
@ -93,10 +92,10 @@ main = do
|
||||||
)
|
)
|
||||||
|
|
||||||
print "done"
|
print "done"
|
||||||
|
-}
|
||||||
|
|
||||||
|
|
||||||
{-
|
{-
|
||||||
|
|
||||||
-- Check refinement relations for all pairs
|
-- Check refinement relations for all pairs
|
||||||
-- This is a bit messy, it skips machines which are equivalent
|
-- This is a bit messy, it skips machines which are equivalent
|
||||||
-- to earlier checked machines, so we thread some state through this
|
-- to earlier checked machines, so we thread some state through this
|
||||||
|
@ -112,20 +111,17 @@ main = do
|
||||||
forM_ projections (\(o2, b2) -> do
|
forM_ projections (\(o2, b2) -> do
|
||||||
(repr0, _) <- get
|
(repr0, _) <- get
|
||||||
when (o1 < o2 && o2 `Map.notMember` repr0) $ do
|
when (o1 < o2 && o2 `Map.notMember` repr0) $ do
|
||||||
case (isRefinementOf b1 b2, isRefinementOf b2 b1) of
|
case comparePartitions b1 b2 of
|
||||||
(True, True) -> do
|
Equivalent -> do
|
||||||
(repr, ls) <- get
|
(repr, ls) <- get
|
||||||
put (Map.insert o2 o1 repr, ls)
|
put (Map.insert o2 o1 repr, ls)
|
||||||
(True, False) -> do
|
Refinement -> do
|
||||||
(repr, ls) <- get
|
(repr, ls) <- get
|
||||||
put (repr, (o1, o2):ls)
|
put (repr, (o1, o2):ls)
|
||||||
(False, True) -> do
|
Coarsening -> do
|
||||||
(repr, ls) <- get
|
(repr, ls) <- get
|
||||||
put (repr, (o2, o1):ls)
|
put (repr, (o2, o1):ls)
|
||||||
(False, False) -> return ()
|
Incomparable -> return ()
|
||||||
|
|
||||||
-- liftIO $ putStr " vs. "
|
|
||||||
-- liftIO $ print o2
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -143,5 +139,4 @@ main = do
|
||||||
)
|
)
|
||||||
|
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
-}
|
-}
|
||||||
|
|
|
@ -4,7 +4,7 @@ module Partition
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Control.Monad.Trans.State.Strict (runState, get, put)
|
import Control.Monad.Trans.State.Strict (runState, get, put)
|
||||||
import Data.Partition (Partition(..), isRefinementOf, numStates)
|
import Data.Partition (Partition(..), numStates)
|
||||||
import Data.Vector qualified as V
|
import Data.Vector qualified as V
|
||||||
import Data.Map.Strict qualified as Map
|
import Data.Map.Strict qualified as Map
|
||||||
import Unsafe.Coerce (unsafeCoerce)
|
import Unsafe.Coerce (unsafeCoerce)
|
||||||
|
@ -27,3 +27,38 @@ commonRefinement p1 p2 =
|
||||||
(vect, (_, nextBlock)) = runState (V.generateM n blockAtIdx) (Map.empty, 0)
|
(vect, (_, nextBlock)) = runState (V.generateM n blockAtIdx) (Map.empty, 0)
|
||||||
in Partition { numBlocks = unsafeCoerce nextBlock, stateAssignment = vect }
|
in Partition { numBlocks = unsafeCoerce nextBlock, stateAssignment = vect }
|
||||||
|
|
||||||
|
-- Could be made faster by doing what commonRefinement is doing but
|
||||||
|
-- stopping early. This is already much faster than what is in
|
||||||
|
-- the CoPaR library, so I won't bother.
|
||||||
|
isRefinementOf2 :: Partition -> Partition -> Bool
|
||||||
|
isRefinementOf2 refined original =
|
||||||
|
numBlocks refined == numBlocks (commonRefinement refined original)
|
||||||
|
|
||||||
|
-- See comment at isRefinementOf2
|
||||||
|
isEquivalent :: Partition -> Partition -> Bool
|
||||||
|
isEquivalent p1 p2 =
|
||||||
|
p1 == p2 || (numBlocks p1 == numBlocks p2 && numBlocks p1 == numBlocks (commonRefinement p1 p2))
|
||||||
|
|
||||||
|
-- Instead of checking whether one partition is a refinement of another AND
|
||||||
|
-- also checking vice versa. We can check the direction at once, computing the
|
||||||
|
-- common refinement only once. It saves some time.
|
||||||
|
data Comparison
|
||||||
|
= Equivalent
|
||||||
|
| Refinement
|
||||||
|
| Coarsening
|
||||||
|
| Incomparable
|
||||||
|
deriving (Eq, Ord, Read, Show, Enum, Bounded)
|
||||||
|
|
||||||
|
-- See comment at isRefinementOf2
|
||||||
|
comparePartitions :: Partition -> Partition -> Comparison
|
||||||
|
comparePartitions p1 p2
|
||||||
|
| p1 == p2 = Equivalent
|
||||||
|
| otherwise = let glb = commonRefinement p1 p2
|
||||||
|
n1 = numBlocks p1
|
||||||
|
n2 = numBlocks p2
|
||||||
|
n3 = numBlocks glb
|
||||||
|
in case (n1 == n3, n2 == n3) of
|
||||||
|
(True, True) -> Equivalent
|
||||||
|
(True, False) -> Refinement
|
||||||
|
(False, True) -> Coarsening
|
||||||
|
(False, False) -> Incomparable
|
||||||
|
|
Loading…
Add table
Reference in a new issue