moonlight-triangulation-0.1.0.0: test/algebra/Moonlight/Triangulation/ScheduleAgreementSpec.hs
-- | The schedule-agreement slice: the seam merge publishes what the reference
-- rebuild publishes. It travels and dies with the schedule it names.
module Moonlight.Triangulation.ScheduleAgreementSpec (tests) where
import Control.Monad (forM_, when)
import Data.IORef (modifyIORef', newIORef, readIORef)
import Moonlight.Triangulation (Point (Point), canonicalize, union)
import Moonlight.Triangulation.AlgebraFixtures
( assertMesh
, meshOf
, operands
, separatedOperands
, siteList
)
import Moonlight.Triangulation.Internal.Join.Seam (executeSeam, planSeam)
import Support (requireRight)
tests :: IO ()
tests = do
testSeamAgreesWithReference
putStrLn "schedule agreement: ok"
-- | The seam schedule and the reference schedule are the same function.
--
-- A join has one meaning and several internal schedules, so this is the law
-- that lets a second one exist at all: for every input where the seam applies,
-- it must publish the value the rebuild publishes — not an isomorphic mesh, the
-- same value, once both are canonically numbered.
--
-- The guard matters more than the equality. 'executeSeam' can only be reached
-- with the opaque proof returned by 'planSeam'; the run fails if too few cases
-- obtain that proof, so the reference cannot quietly be compared with itself.
testSeamAgreesWithReference :: IO ()
testSeamAgreesWithReference = do
separable <- separatedOperands
overlapping <- operands
taken <- newIORef (0 :: Int)
forM_ separable $ \((leftName, left), (rightName, right)) -> do
let label = "seam " <> leftName <> " / " <> rightName
seamPlan <- case planSeam left right of
Nothing ->
fail (label <> ": the operands are separated but planSeam refused them")
Just admitted -> do
modifyIORef' taken (+ 1)
pure admitted
rawRebuild <- meshOf label [Point x y | (x, y) <- siteList left <> siteList right]
rebuilt <- requireRight (label <> ", canonical rebuild") (canonicalize rawRebuild)
seamed <- requireRight (label <> ", direct seam") (executeSeam seamPlan left right)
canonicalSeam <- requireRight (label <> ", canonical seam") (canonicalize seamed)
assertMesh (label <> ", against a rebuild") rebuilt canonicalSeam
joined <- requireRight (label <> ", through union") (union left right)
canonicalJoined <- requireRight (label <> ", canonical union") (canonicalize joined)
assertMesh (label <> ", through the operator") rebuilt canonicalJoined
forM_ [(l, r) | l <- overlapping, r <- overlapping] $ \((leftName, left), (rightName, right)) ->
case planSeam left right of
Nothing -> pure ()
Just seamPlan -> do
rawRebuild <-
meshOf
("seam admission " <> leftName <> " / " <> rightName)
[Point x y | (x, y) <- siteList left <> siteList right]
rebuilt <- requireRight "seam admission canonical rebuild" (canonicalize rawRebuild)
seamed <- requireRight "seam admission" (executeSeam seamPlan left right)
canonicalSeam <- requireRight "seam admission canonical seam" (canonicalize seamed)
assertMesh
("seam admission " <> leftName <> " / " <> rightName)
rebuilt
canonicalSeam
modifyIORef' taken (+ 1)
count <- readIORef taken
when (count < 3) $
fail ("seam agreement: only " <> show count <> " cases entered the seam, so the law asserted nothing")