packages feed

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")