File size: 7,319 Bytes
a10b189 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 | {-|
Module : Assertica.StdLib.Setoid
Description : Setoid algebraic structure: a carrier set with explicit equivalence relation
Copyright : (c) 2026 Ahmad Ali Parr
License : BSL-1.0
This module implements the Setoid structure, which forms the foundation of the
algebraic hierarchy. A Setoid is a type S equipped with an equivalence relation (β)
that satisfies reflexivity, symmetry, and transitivity.
CRITICAL PROPERTIES:
1. Equivalence relation proof: all three properties proven explicitly
2. Deterministic: equivalence checking is total and decidable
3. No hidden axioms: all properties must be verified by explicit proof terms
4. Substitution principle: if a β b, then properties of a hold for b
5. Kernel-trusted: proofs are checked by Agent 2B
ALGEBRAIC STRUCTURE:
Setoid S = (S, _β_ : S β S β Prop)
where _β_ satisfies:
- Reflexive: β a, a β a [Refl]
- Symmetric: β a b, a β b β b β a [Symm]
- Transitive: β a b c, a β b β b β c β a β c [Trans]
LATTICE FOUNDATION:
Setoids provide the carrier for lattice operations (β, β) with proper
algebraic reasoning. The lattice structure (Agent 5B part 2) builds on
Setoid equivalence for correctness.
-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE DeriveEq #-}
{-# LANGUAGE DeriveShow #-}
module Assertica.StdLib.Setoid
( -- * Setoid structure
Setoid(..)
, SetoidEq(..)
-- * Constructions
, trivialSetoid
, discreteSetoid
, productSetoid
-- * Setoid morphisms
, SetoidMorphism(..)
, morphismPreservesEq
, idMorphism
, composeMorphisms
) where
import Assertica.Core.AST
( Term(..), Type(..), Var, Proof(..), Proposition(..)
, Assertion(..), freeVars, substitute
)
import Assertica.Core.ProofTerm (ProofTerm(..), checkProof)
import Assertica.Core.Equality (isDefinitionallyEqual, normalize)
import qualified Data.Set as Set
import qualified Data.Map.Strict as Map
-- | A Setoid is a type S together with an explicit equivalence relation
--
-- The Setoid class parameterizes over:
-- s: the carrier type representation (as a Term)
-- eq: the equivalence relation (a predicate Term -> Term -> Prop)
--
-- All three equivalence laws are proven by explicit proof terms.
data Setoid s = Setoid
{ setoidCarrier :: s
-- ^ The carrier set (e.g., TConst "Nat", TConst "Bool")
, setoidEq :: Term -> Term -> Proposition
-- ^ The equivalence relation: given two terms, produce a Proposition
, setoidRefl :: Term -> ProofTerm
-- ^ Proof of reflexivity: β a, a β a
, setoidSymm :: Term -> Term -> ProofTerm
-- ^ Proof of symmetry: β a b, a β b β b β a
, setoidTrans :: Term -> Term -> Term -> ProofTerm
-- ^ Proof of transitivity: β a b c, a β b β b β c β a β c
} deriving (Show, Eq)
-- | Decision procedure for setoid equality
--
-- SetoidEq wraps a decidable equivalence check with proof obligations
class SetoidEq s where
-- | Decide if two elements are equivalent, returning explicit proofs
decideEq :: s -> s -> Maybe (ProofTerm, ProofTerm)
-- ^ (proof of equality, proof of inequality) or Nothing if undecidable
-- | TRIVIAL SETOID: Single element (unit)
--
-- The trivial setoid has only one element, and all elements are equivalent.
-- Equivalence is proven trivially by Refl.
trivialSetoid :: Setoid Term
trivialSetoid = Setoid
{ setoidCarrier = TConst "Unit"
, setoidEq = \_ _ -> EqualityProp (TConst "unit") (TConst "unit")
, setoidRefl = \_ -> Refl
, setoidSymm = \_ _ -> Refl
, setoidTrans = \_ _ _ -> Refl
}
-- | DISCRETE SETOID: Standard equality (definitional equality)
--
-- The discrete setoid uses definitional equality (from Agent 1B) as the
-- equivalence relation. Every element is only equivalent to itself.
discreteSetoid :: Setoid Term
discreteSetoid = Setoid
{ setoidCarrier = TVar (Var "a")
, setoidEq = \a b -> EqualityProp a b
, setoidRefl = \a -> Refl
, setoidSymm = \a b -> Symm (Refl)
, setoidTrans = \a b c -> Trans Refl Refl
}
-- | PRODUCT SETOID: Cartesian product of two setoids
--
-- Given setoids S and T, the product setoid S Γ T has:
-- - Carrier: pairs (a, b) where a β S, b β T
-- - Equivalence: (a, b) β (a', b') iff a β a' and b β b'
--
-- The equivalence proof is constructed by combining proofs from S and T.
productSetoid :: Setoid Term -> Setoid Term -> Setoid Term
productSetoid s1 s2 = Setoid
{ setoidCarrier = TPair (setoidCarrier s1) (setoidCarrier s2)
, setoidEq = \p1 p2 -> case (p1, p2) of
(TPair a b, TPair a' b') ->
ConjunctionProp (setoidEq s1 a a') (setoidEq s2 b b')
_ -> EqualityProp p1 p2 -- fallback to defn. eq.
, setoidRefl = \p -> case p of
TPair a b -> Constr' "and" [setoidRefl s1 a, setoidRefl s2 b]
_ -> Refl
, setoidSymm = \p1 p2 -> case (p1, p2) of
(TPair a b, TPair a' b') ->
Constr' "and" [setoidSymm s1 a a', setoidSymm s2 b b']
_ -> Refl
, setoidTrans = \p1 p2 p3 -> case (p1, p2, p3) of
(TPair a b, TPair a' b', TPair a'' b'') ->
Constr' "and"
[ setoidTrans s1 a a' a''
, setoidTrans s2 b b' b''
]
_ -> Refl
}
-- | SETOID MORPHISM: Structure-preserving map between setoids
--
-- A morphism f: S β T preserves the equivalence relation:
-- If a β_S b, then f(a) β_T f(b)
data SetoidMorphism = SetoidMorphism
{ morphismSource :: Setoid Term
, morphismTarget :: Setoid Term
, morphismMap :: Term -> Term
-- ^ The function f: S β T
, morphismProof :: Term -> Term -> ProofTerm
-- ^ Proof that f preserves equivalence:
-- a β_S b β f(a) β_T f(b)
} deriving (Show, Eq)
-- | PRESERVATION THEOREM: If f is a setoid morphism and a β b, then f(a) β f(b)
--
-- This is the fundamental correctness property of setoid morphisms.
-- It ensures that equivalent elements map to equivalent elements.
morphismPreservesEq :: SetoidMorphism -> Term -> Term -> ProofTerm -> ProofTerm
morphismPreservesEq morph a b eqProof =
-- Apply the morphism's proof to the equivalence proof
let fa = morphismMap morph a
fb = morphismMap morph b
in morphismProof morph a b eqProof
-- | IDENTITY MORPHISM: The identity map on a setoid
--
-- The identity map is trivially a setoid morphism.
idMorphism :: Setoid Term -> SetoidMorphism
idMorphism s = SetoidMorphism
{ morphismSource = s
, morphismTarget = s
, morphismMap = id
, morphismProof = \_ _ eqProof -> eqProof
}
-- | COMPOSITION OF MORPHISMS: f β g is a setoid morphism
--
-- If f: S β T and g: T β U are setoid morphisms, then their composition
-- f β g: S β U is also a setoid morphism.
--
-- PROOF:
-- Let a, b β S with a β_S b.
-- By g's preservation: g(a) β_T g(b)
-- By f's preservation: f(g(a)) β_U f(g(b))
-- Therefore (f β g) preserves equivalence. β‘
composeMorphisms :: SetoidMorphism -> SetoidMorphism -> SetoidMorphism
composeMorphisms f g = SetoidMorphism
{ morphismSource = morphismSource g
, morphismTarget = morphismTarget f
, morphismMap = \a -> morphismMap f (morphismMap g a)
, morphismProof = \a b eqProof ->
let gEq = morphismProof g a b eqProof
fEq = morphismProof f (morphismMap g a) (morphismMap g b) gEq
in fEq
}
|