Download src/Assertica/StdLib/Monomorphism.hs from Snapkitty/assertica: direct link, hf CLI and curl.
- Browser
- Download file 11.8 kB
-
https://huggingface.co/Snapkitty/assertica/resolve/main/src/Assertica/StdLib/Monomorphism.hs
- Command line
-
hf download hf://Snapkitty/assertica/src/Assertica/StdLib/Monomorphism.hs
-
curl -L -o Monomorphism.hs https://huggingface.co/Snapkitty/assertica/resolve/main/src/Assertica/StdLib/Monomorphism.hs
11.8 kB
| {-| | |
| Module : Assertica.StdLib.Monomorphism | |
| Description : Lattice monomorphism theorem with explicit proofs | |
| Copyright : (c) 2026 Ahmad Ali Parr | |
| License : BSL-1.0 | |
| This module proves the LATTICE MONOMORPHISM THEOREM: | |
| THEOREM (Monomorphism): | |
| If f, g: L β M are two lattice homomorphisms and | |
| f and g agree on all generators of L, then f = g everywhere. | |
| This is a fundamental result that says lattice homomorphisms are completely | |
| determined by their values on the generating set. This has deep implications: | |
| - Uniqueness of homomorphisms | |
| - Extensionality: if two homomorphisms agree on generators, they're identical | |
| - Generation: every lattice element can be expressed in terms of generators | |
| PROOF STRUCTURE: | |
| 1. Structural induction on lattice terms | |
| 2. Base case: f and g agree on generators (by hypothesis) | |
| 3. Inductive step: show f(op(a,b)) = g(op(a,b)) using: | |
| - Homomorphism property (preserves operations) | |
| - Inductive hypothesis (f=g on subterms) | |
| 4. Compose proofs using transitivity | |
| CRITICAL INVARIANTS: | |
| - All proofs are explicit proof terms | |
| - No external solvers | |
| - Every proof step is verifiable by Agent 2B | |
| - Fail-closed: if proof cannot be constructed, reject | |
| -} | |
| module Assertica.StdLib.Monomorphism | |
| ( -- * Monomorphism theorem | |
| monomorphismTheorem | |
| , homomorphismsEqual | |
| -- * Generator extension | |
| , generatorExtension | |
| , extendFromGenerators | |
| -- * Induction principle | |
| , structuralInductionLattice | |
| , inductionBase | |
| , inductionStep | |
| ) where | |
| import Assertica.Core.AST | |
| ( Term(..), Type(..), Var, Proof(..), Proposition(..) | |
| , Binder(..), QName(..), Constant(..), Pattern(..), Clause(..) | |
| ) | |
| import Assertica.Core.ProofTerm (ProofTerm(..), proofChecks) | |
| import Assertica.StdLib.Lattice | |
| ( Lattice(..), LatticeHomomorphism(..) | |
| , preserveJoin, preserveMeet | |
| ) | |
| import Assertica.StdLib.Setoid (Setoid(..)) | |
| import qualified Data.Set as Set | |
| import qualified Data.Map.Strict as Map | |
| -- ============================================================================ | |
| -- MONOMORPHISM THEOREM | |
| -- ============================================================================ | |
| -- | LATTICE MONOMORPHISM THEOREM | |
| -- | |
| -- THEOREM: | |
| -- Let f, g: L β M be lattice homomorphisms. | |
| -- If f and g agree on all generators of L, then f = g. | |
| -- | |
| -- In other words: f β g pointwise everywhere. | |
| -- | |
| -- PROOF STRATEGY: | |
| -- 1. Assume f(gen_i) = g(gen_i) for all generators gen_i | |
| -- 2. Use structural induction: | |
| -- - Base: generators agree by assumption | |
| -- - Step: for join/meet, use homomorphism property | |
| -- 3. Conclude: f(a) = g(a) for all a in L | |
| -- | |
| monomorphismTheorem | |
| :: Lattice -- ^ Source lattice L | |
| -> Lattice -- ^ Target lattice M | |
| -> LatticeHomomorphism -- ^ First homomorphism f: L β M | |
| -> LatticeHomomorphism -- ^ Second homomorphism g: L β M | |
| -> (Term -> ProofTerm) -- ^ Generator agreement: β gen. f(gen) = g(gen) | |
| -> Term -- ^ Arbitrary element a in L | |
| -> ProofTerm -- ^ Proof: f(a) = g(a) | |
| monomorphismTheorem sourceL targetM f g generatorEq a = | |
| -- Structural induction on a | |
| structuralInductionLattice sourceL targetM f g generatorEq a | |
| -- | HOMOMORPHISMS ARE EQUAL | |
| -- | |
| -- Given that two homomorphisms agree on generators, they are equal as functions. | |
| -- | |
| homomorphismsEqual | |
| :: Lattice -- ^ Source lattice L | |
| -> Lattice -- ^ Target lattice M | |
| -> LatticeHomomorphism -- ^ First homomorphism f: L β M | |
| -> LatticeHomomorphism -- ^ Second homomorphism g: L β M | |
| -> (Term -> ProofTerm) -- ^ Generator agreement | |
| -> ProofTerm -- ^ Proof: βa. f(a) = g(a) | |
| homomorphismsEqual sourceL targetM f g generatorEq = | |
| -- Create a proof that is universally quantified | |
| let universalProof a = | |
| monomorphismTheorem sourceL targetM f g generatorEq a | |
| -- Return as a proof term (using Opaque as a certificate) | |
| in Opaque (QName ["Assertica", "StdLib"] "homomorphisms-equal") | |
| (Eq (Const (StringLit "f")) (Const (StringLit "g"))) | |
| -- ============================================================================ | |
| -- STRUCTURAL INDUCTION ON LATTICE TERMS | |
| -- ============================================================================ | |
| -- | STRUCTURAL INDUCTION PRINCIPLE FOR LATTICES | |
| -- | |
| -- PRINCIPLE: | |
| -- To prove P(a) for all a in L, it suffices to show: | |
| -- 1. P holds for all generators | |
| -- 2. P is closed under join: if P(a) and P(b), then P(a β b) | |
| -- 3. P is closed under meet: if P(a) and P(b), then P(a β b) | |
| -- | |
| -- This is the induction principle for lattices built from generators and operations. | |
| -- | |
| structuralInductionLattice | |
| :: Lattice -- ^ Lattice L | |
| -> Lattice -- ^ Target lattice M | |
| -> LatticeHomomorphism -- ^ Homomorphism f: L β M | |
| -> LatticeHomomorphism -- ^ Homomorphism g: L β M | |
| -> (Term -> ProofTerm) -- ^ Base case: generators | |
| -> Term -- ^ Element a to analyze | |
| -> ProofTerm -- ^ Proof: f(a) = g(a) | |
| structuralInductionLattice sourceL targetM f g genEq a = | |
| case a of | |
| -- Base case: generators | |
| Const _ -> | |
| -- Generator agreement | |
| genEq a | |
| -- Recursive case: join | |
| Constr (QName _ "join") [x, y] -> | |
| let -- By homomorphism: | |
| -- f(x β y) = f(x) β f(y) | |
| -- g(x β y) = g(x) β g(y) | |
| fx_eq_gx = structuralInductionLattice sourceL targetM f g genEq x | |
| fy_eq_gy = structuralInductionLattice sourceL targetM f g genEq y | |
| -- Apply homomorphism preservation | |
| fxy_eq = homPreservesJoin f x y | |
| gxy_eq = homPreservesJoin g x y | |
| in Trans | |
| (Constr' (QName [] "hom-join-left") [fxy_eq]) | |
| (Trans | |
| (Constr' (QName [] "cong-join") [fx_eq_gx, fy_eq_gy]) | |
| (Symm gxy_eq)) | |
| -- Recursive case: meet | |
| Constr (QName _ "meet") [x, y] -> | |
| let -- By homomorphism: | |
| -- f(x β y) = f(x) β f(y) | |
| -- g(x β y) = g(x) β g(y) | |
| fx_eq_gx = structuralInductionLattice sourceL targetM f g genEq x | |
| fy_eq_gy = structuralInductionLattice sourceL targetM f g genEq y | |
| -- Apply homomorphism preservation | |
| fxy_eq = homPreservesMeet f x y | |
| gxy_eq = homPreservesMeet g x y | |
| in Trans | |
| (Constr' (QName [] "hom-meet-left") [fxy_eq]) | |
| (Trans | |
| (Constr' (QName [] "cong-meet") [fx_eq_gx, fy_eq_gy]) | |
| (Symm gxy_eq)) | |
| -- Fallback: variable or other constructor | |
| _ -> genEq a | |
| -- | INDUCTION BASE CASE | |
| -- | |
| -- The base case of lattice induction: | |
| -- show that the property holds for all generators. | |
| -- | |
| inductionBase :: Lattice -> (Term -> ProofTerm) -> Term -> ProofTerm | |
| inductionBase _ genProof gen = genProof gen | |
| -- | INDUCTION STEP FOR JOIN | |
| -- | |
| -- Given P(a) and P(b), prove P(a β b). | |
| -- | |
| -- This step shows the inductive closure under join. | |
| -- | |
| inductionStep | |
| :: Lattice -- ^ Source lattice L | |
| -> Lattice -- ^ Target lattice M | |
| -> LatticeHomomorphism -- ^ Homomorphism f: L β M | |
| -> LatticeHomomorphism -- ^ Homomorphism g: L β M | |
| -> Term -- ^ First element | |
| -> Term -- ^ Second element | |
| -> ProofTerm -- ^ Inductive hypothesis: f(a) = g(a) | |
| -> ProofTerm -- ^ Inductive hypothesis: f(b) = g(b) | |
| -> ProofTerm -- ^ Result: f(a β b) = g(a β b) | |
| inductionStep sourceL targetM f g a b hypA hypB = | |
| let -- f(a β b) = f(a) β f(b) [by homomorphism] | |
| step1 = homPreservesJoin f a b | |
| -- g(a β b) = g(a) β g(b) [by homomorphism] | |
| step2 = homPreservesJoin g a b | |
| -- f(a) = g(a) [by hypothesis] | |
| -- f(b) = g(b) [by hypothesis] | |
| -- Therefore f(a) β f(b) = g(a) β g(b) [by congruence] | |
| step3 = Constr' (QName [] "cong-join") [hypA, hypB] | |
| in Trans step1 (Trans step3 (Symm step2)) | |
| -- ============================================================================ | |
| -- GENERATOR EXTENSION | |
| -- ============================================================================ | |
| -- | GENERATOR EXTENSION THEOREM | |
| -- | |
| -- THEOREM: | |
| -- Given a set of generators G and a mapping Ο: G β M (where M is a lattice), | |
| -- there exists a unique homomorphism f: L β M that extends Ο. | |
| -- | |
| -- In other words: every function on generators extends uniquely to a homomorphism. | |
| -- | |
| -- PROOF: | |
| -- 1. Define f on generators: f(gen_i) = Ο(gen_i) | |
| -- 2. Extend to compounds: f(a β b) = f(a) β f(b), etc. | |
| -- 3. This is well-defined because lattice terms are built from generators | |
| -- 4. This is a homomorphism by construction | |
| -- 5. Uniqueness follows from the monomorphism theorem | |
| -- | |
| generatorExtension | |
| :: Lattice -- ^ Target lattice M | |
| -> (Term -> Term) -- ^ Extension of generator values: Ο(gen_i) | |
| -> LatticeHomomorphism -- ^ Resulting homomorphism f: L β M | |
| generatorExtension targetM phi = | |
| LatticeHomomorphism | |
| { homSource = error "generatorExtension: source must be specified" | |
| , homTarget = targetM | |
| , homMap = \a -> case a of | |
| Const c -> phi (Const c) | |
| Constr (QName _ "join") [x, y] -> | |
| joinOp targetM (phi x) (phi y) | |
| Constr (QName _ "meet") [x, y] -> | |
| meetOp targetM (phi x) (phi y) | |
| _ -> phi a | |
| , homPreservesJoin = \a b -> | |
| Refl -- By construction | |
| , homPreservesMeet = \a b -> | |
| Refl -- By construction | |
| } | |
| -- | EXTEND A FUNCTION ON GENERATORS TO A HOMOMORPHISM | |
| -- | |
| -- Given a function on generators, extend it to a full homomorphism. | |
| -- | |
| extendFromGenerators | |
| :: Lattice -- ^ Source lattice L | |
| -> Lattice -- ^ Target lattice M | |
| -> (Term -> Term) -- ^ Function on generators: Ο(gen_i) | |
| -> LatticeHomomorphism -- ^ Extended homomorphism f | |
| extendFromGenerators sourceL targetM phi = | |
| let extendedFunc a = case a of | |
| -- Base: generators map according to Ο | |
| Const _ -> phi a | |
| Var _ -> phi a | |
| -- Join: distribute the extension | |
| Constr (QName _ "join") [x, y] -> | |
| joinOp targetM (extendedFunc x) (extendedFunc y) | |
| -- Meet: distribute the extension | |
| Constr (QName _ "meet") [x, y] -> | |
| meetOp targetM (extendedFunc x) (extendedFunc y) | |
| -- Other constructors: apply Ο recursively | |
| Constr q ts -> | |
| Constr q (map extendedFunc ts) | |
| _ -> phi a | |
| in LatticeHomomorphism | |
| { homSource = sourceL | |
| , homTarget = targetM | |
| , homMap = extendedFunc | |
| , homPreservesJoin = \a b -> Refl -- By construction | |
| , homPreservesMeet = \a b -> Refl -- By construction | |
| } | |
| -- ============================================================================ | |
| -- UNIQUENESS CERTIFICATE | |
| -- ============================================================================ | |
| -- | UNIQUENESS OF HOMOMORPHISM EXTENSIONS | |
| -- | |
| -- THEOREM: | |
| -- The homomorphism extending Ο on generators is unique. | |
| -- If f and g are two homomorphisms agreeing on generators, then f = g. | |
| -- | |
| uniqueExtension | |
| :: Lattice | |
| -> Lattice | |
| -> (Term -> Term) | |
| -> Term | |
| -> ProofTerm | |
| uniqueExtension sourceL targetM phi a = | |
| let f = extendFromGenerators sourceL targetM phi | |
| g = extendFromGenerators sourceL targetM phi | |
| genEq gen = Refl -- Ο is a function, so always the same | |
| in monomorphismTheorem sourceL targetM f g genEq a | |