@hackage / moonlight-core

Mathematical basis for Pale Meridian.

Latest0.1.0.0

About

Metadata

  • Last updated , by bluerose
  • License MIT
  • Categories Mathematics
  • Maintained by: rosaliafialkova@gmail.com

  • Lottery factor: 1

Links

Installation

Readme

moonlight-core

Part of Moonlight, the sheaf-theoretic computation layer beneath Melusine and Pale Meridian.

moonlight-core is Moonlight's foundation tier. It is the total vocabulary every layer above shares: numeric classes, structural identity, orders, patterns, fixpoints, persistent union-find, finite registries, a term database, and a host-neutral e-graph program algebra.

Main idea

Every name reachable from the one import, Moonlight.Core, is total. Failure is a value in the return type: tryInv returns Maybe, makeSet returns Either UnionFindAllocationError, fixpointBounded returns Either (FixpointDivergence a), mkTotalRegistry returns Either [missingKey]. Operations with no failure case (magnitude, neg, union) return bare values.

Moonlight.Core.Unsound holds the unchecked constructors: importing it by name asserts a refinement the checker cannot see. Every other constructor reachable through the umbrella validates at construction.

Use

import Moonlight.Core

reciprocalOfThree :: Maybe Double
reciprocalOfThree = tryInv 3

size :: Double
size = magnitude (neg (2.5 :: Double))

Cookbook

Each recipe shows the main idea in practice: the total path returns a value, the failure path returns a typed sum.

Persistent union-find

makeSet mints fresh classes through a checked allocation boundary, union merges them, and the structure is persistent; older versions stay valid after a merge.

import Moonlight.Core

partition :: Either UnionFindAllocationError (Bool, Bool)
partition = do
  (a, uf1) <- makeSet emptyUnionFind
  (b, uf2) <- makeSet uf1
  (c, uf3) <- makeSet uf2
  let uf = union a b uf3
  pure (equivalent a b uf, equivalent a c uf)   -- Right (True, False)
Bounded fixpoints

fixpointBounded iterates a step to a fixed point under an explicit fuel bound. Non-convergence returns a typed Left.

import Moonlight.Core

converge :: Either (FixpointDivergence Int) Int
converge = fixpointBounded 100 (\n -> n `div` 2) 37   -- Right 0

diverges :: Either (FixpointDivergence Int) Int
diverges = fixpointBounded 5 (+1) 0                   -- Left (out of fuel)
Checked total maps

mkTotalRegistry demands every key of a finite universe; a gap is a typed Left [missingKeys]. In exchange, lookupTotal returns a bare value once the registry is constructed.

import Moonlight.Core
import Data.List.NonEmpty (NonEmpty (..))
import qualified Data.Map.Strict as Map

data Slot = Alpha | Beta | Gamma
  deriving (Eq, Ord, Show)

instance FiniteUniverse Slot where
  finiteUniverse = Alpha :| [Beta, Gamma]

palette :: Either [Slot] (TotalRegistry Slot String)
palette = mkTotalRegistry (Map.fromList [(Alpha, "a"), (Beta, "b"), (Gamma, "c")])

labelOfBeta :: Either [Slot] String
labelOfBeta = fmap (\reg -> lookupTotal reg Beta) palette   -- Right "b"
-- mkTotalRegistry (Map.fromList [(Alpha, "a")])  ==  Left [Beta, Gamma]
The matching seam

ZipMatch is one-layer structural matching: zipMatch succeeds iff two nodes share a shape, pairing their children positionally. It is the seam the e-graph and rewriting layers are built on.

import Moonlight.Core

data ExprF a = Lit Int | Add a a
  deriving (Functor, Foldable, Traversable, Eq, Ord, Show)

instance ZipMatch ExprF where
  zipMatch (Lit m)     (Lit n)     | m == n = Just (Lit m)
  zipMatch (Add a1 b1) (Add a2 b2)          = Just (Add (a1, a2) (b1, b2))
  zipMatch _           _                    = Nothing

aligned :: Maybe (ExprF (Int, Int))
aligned = zipMatch (Add 1 2) (Add 10 20)   -- Just (Add (1,10) (2,20))

Surface & boundaries

Most downstream code imports the umbrella. Lower-level packages may depend on one of the public sublibraries.

Cabal dependency Import What you get
moonlight-core Moonlight.Core The ordinary total vocabulary. This is the default.
moonlight-core:moonlight-core-syntax Moonlight.Core.Pattern.AntiUnify Patterns and term anti-unification without the full umbrella.
moonlight-core:moonlight-core-automata Moonlight.Core.Pattern.Automata or .Kernel The bottom-up automata substrate and compiled matcher. Depend on syntax too when naming its types directly.
moonlight-core:moonlight-core-egraph-program Moonlight.Core.EGraph.Program The host-neutral e-graph program algebra without the rest of the foundation.
moonlight-core Moonlight.Core.Unsound The explicit trust boundary; see Main idea.

The private implementation slices remain basis, numeric, solver, and term. Syntax, automata, and e-graph programs are public because other foundation packages consume those exact owners. The umbrella re-exports the syntax and e-graph-program vocabulary; automata are imported only through the sublibrary. Haddock carries the signatures; the laws are named and machine-checked in the law suites.

Test

cabal test moonlight-core:moonlight-core-test

Benchmarks

cabal bench moonlight-core:moonlight-core-bench --benchmark-options='--timeout=2s --csv=comparison.csv'

hackage: rows measure a package-level baseline (containers, memory, scientific, equivalence) on the same fixture; world: rows are source-equivalent baselines where no package owner exists. Fixtures assert result agreement with the baseline before timing. Dated receipts live in docs/BENCHMARKS-m4-pro.md.

License

MIT. See LICENSE.