File size: 16,340 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 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 | {-# LANGUAGE OverloadedStrings #-}
{-|
Module : Test.StdLib.Lattice
Description : Comprehensive tests for lattice algebraic structure
Copyright : (c) 2026 Ahmad Ali Parr
-}
module Test.StdLib.Lattice
( tests
) where
import Test.Tasty
import Test.Tasty.HUnit
import Test.Tasty.QuickCheck as QC
import Assertica.Core.AST
import Assertica.Core.ProofTerm
import Assertica.StdLib.Setoid
import Assertica.StdLib.Lattice
-- ============================================================================
-- UNIT TESTS: LATTICE STRUCTURE
-- ============================================================================
tests :: TestTree
tests = testGroup "Assertica.StdLib.Lattice"
[ testGroup "Boolean Lattice"
[ testCase "Boolean lattice carrier" testBooleanCarrier
, testCase "Boolean join operation" testBooleanJoin
, testCase "Boolean meet operation" testBooleanMeet
, testCase "Boolean join reflexivity" testBooleanJoinRefl
, testCase "Boolean meet reflexivity" testBooleanMeetRefl
]
, testGroup "Trivial Lattice"
[ testCase "Trivial lattice carrier" testTrivialLatticeCarrier
, testCase "Trivial lattice join" testTrivialLatticeJoin
, testCase "Trivial lattice meet" testTrivialLatticeMeet
]
, testGroup "Join Operation Properties"
[ testCase "Join associativity" testJoinAssociativity
, testCase "Join commutativity" testJoinCommutativity
, testCase "Join idempotence" testJoinIdempotence
, testCase "Join preserves equivalence (left)" testJoinPreservesEqLeft
, testCase "Join preserves equivalence (right)" testJoinPreservesEqRight
]
, testGroup "Meet Operation Properties"
[ testCase "Meet associativity" testMeetAssociativity
, testCase "Meet commutativity" testMeetCommutativity
, testCase "Meet idempotence" testMeetIdempotence
, testCase "Meet preserves equivalence (left)" testMeetPreservesEqLeft
, testCase "Meet preserves equivalence (right)" testMeetPreservesEqRight
]
, testGroup "Lattice Homomorphisms"
[ testCase "Identity homomorphism" testIdentityHomomorphism
, testCase "Identity preserves join" testIdPreservesJoin
, testCase "Identity preserves meet" testIdPreservesMeet
, testCase "Homomorphism composition" testHomomorphismComposition
]
, testGroup "Proof Term Checking"
[ testCase "Join associativity proof checks" testJoinAssocProofChecks
, testCase "Join commutativity proof checks" testJoinCommProofChecks
, testCase "Join idempotence proof checks" testJoinIdempProofChecks
, testCase "Meet associativity proof checks" testMeetAssocProofChecks
, testCase "Meet commutativity proof checks" testMeetCommProofChecks
, testCase "Meet idempotence proof checks" testMeetIdempProofChecks
]
, testGroup "Lattice Laws Interplay"
[ testCase "Join and meet compatibility" testJoinMeetCompat
, testCase "Join properties hold simultaneously" testJoinPropsSimultaneous
, testCase "Meet properties hold simultaneously" testMeetPropsSimultaneous
]
, testGroup "Determinism Tests"
[ testCase "Join operation is deterministic" testJoinDeterminism
, testCase "Meet operation is deterministic" testMeetDeterminism
, testCase "Proof generation is deterministic" testProofDeterminism
]
, testGroup "Negative Tests"
[ testCase "Different elements don't unify wrongly" testElementsDifferent
]
]
-- ============================================================================
-- BOOLEAN LATTICE TESTS
-- ============================================================================
testBooleanCarrier :: Assertion
testBooleanCarrier =
let carrier = latticeCarrier booleanLattice
setoidCarrier' = setoidCarrier carrier
in case setoidCarrier' of
TConst (QName [] "Bool") -> assertBool "Boolean lattice carrier is Bool" True
_ -> assertFailure "Boolean lattice carrier should be Bool"
testBooleanJoin :: Assertion
testBooleanJoin =
let result = join booleanLattice (Const (BoolLit True)) (Const (BoolLit False))
in case result of
Constr (QName [] "or") [_, _] -> assertBool "Join creates OR constructor" True
_ -> assertFailure "Join should create 'or' constructor"
testBooleanMeet :: Assertion
testBooleanMeet =
let result = meet booleanLattice (Const (BoolLit True)) (Const (BoolLit False))
in case result of
Constr (QName [] "and") [_, _] -> assertBool "Meet creates AND constructor" True
_ -> assertFailure "Meet should create 'and' constructor"
testBooleanJoinRefl :: Assertion
testBooleanJoinRefl =
let proof = joinAssociativity booleanLattice
(Const (BoolLit True))
(Const (BoolLit False))
(Const (BoolLit True))
in proof @?= Refl
testBooleanMeetRefl :: Assertion
testBooleanMeetRefl =
let proof = meetAssociativity booleanLattice
(Const (BoolLit True))
(Const (BoolLit False))
(Const (BoolLit True))
in proof @?= Refl
-- ============================================================================
-- TRIVIAL LATTICE TESTS
-- ============================================================================
testTrivialLatticeCarrier :: Assertion
testTrivialLatticeCarrier =
let carrier = latticeCarrier trivialLattice
setoidCarrier' = setoidCarrier carrier
in case setoidCarrier' of
TConst (QName [] "Unit") -> assertBool "Trivial lattice carrier is Unit" True
_ -> assertFailure "Trivial lattice carrier should be Unit"
testTrivialLatticeJoin :: Assertion
testTrivialLatticeJoin =
let result = join trivialLattice (Const UnitConst) (Const UnitConst)
in result @?= Const UnitConst
testTrivialLatticeMeet :: Assertion
testTrivialLatticeMeet =
let result = meet trivialLattice (Const UnitConst) (Const UnitConst)
in result @?= Const UnitConst
-- ============================================================================
-- JOIN OPERATION TESTS
-- ============================================================================
testJoinAssociativity :: Assertion
testJoinAssociativity =
let a = Const (BoolLit True)
b = Const (BoolLit False)
c = Const (BoolLit True)
proof = joinAssociativity booleanLattice a b c
in proof @?= Refl
testJoinCommutativity :: Assertion
testJoinCommutativity =
let a = Const (BoolLit True)
b = Const (BoolLit False)
proof = joinCommutativity booleanLattice a b
in proof @?= Refl
testJoinIdempotence :: Assertion
testJoinIdempotence =
let a = Const (BoolLit True)
proof = joinIdempotence booleanLattice a
in proof @?= Refl
testJoinPreservesEqLeft :: Assertion
testJoinPreservesEqLeft =
let a = Const (BoolLit True)
a' = Const (BoolLit True)
b = Const (BoolLit False)
proof = preserveJoin booleanLattice a a' b b Refl Refl
in proof @?= Refl
testJoinPreservesEqRight :: Assertion
testJoinPreservesEqRight =
let a = Const (BoolLit True)
b = Const (BoolLit False)
b' = Const (BoolLit False)
proof = preserveJoin booleanLattice a a b b' Refl Refl
in proof @?= Refl
-- ============================================================================
-- MEET OPERATION TESTS
-- ============================================================================
testMeetAssociativity :: Assertion
testMeetAssociativity =
let a = Const (BoolLit True)
b = Const (BoolLit False)
c = Const (BoolLit True)
proof = meetAssociativity booleanLattice a b c
in proof @?= Refl
testMeetCommutativity :: Assertion
testMeetCommutativity =
let a = Const (BoolLit True)
b = Const (BoolLit False)
proof = meetCommutativity booleanLattice a b
in proof @?= Refl
testMeetIdempotence :: Assertion
testMeetIdempotence =
let a = Const (BoolLit True)
proof = meetIdempotence booleanLattice a
in proof @?= Refl
testMeetPreservesEqLeft :: Assertion
testMeetPreservesEqLeft =
let a = Const (BoolLit True)
a' = Const (BoolLit True)
b = Const (BoolLit False)
proof = preserveMeet booleanLattice a a' b b Refl Refl
in proof @?= Refl
testMeetPreservesEqRight :: Assertion
testMeetPreservesEqRight =
let a = Const (BoolLit True)
b = Const (BoolLit False)
b' = Const (BoolLit False)
proof = preserveMeet booleanLattice a a b b' Refl Refl
in proof @?= Refl
-- ============================================================================
-- LATTICE HOMOMORPHISM TESTS
-- ============================================================================
testIdentityHomomorphism :: Assertion
testIdentityHomomorphism =
let hom = LatticeHomomorphism
{ homSource = booleanLattice
, homTarget = booleanLattice
, homMap = id
, homPreservesJoin = \_ _ -> Refl
, homPreservesMeet = \_ _ -> Refl
}
a = Const (BoolLit True)
in homMap hom a @?= a
testIdPreservesJoin :: Assertion
testIdPreservesJoin =
let hom = LatticeHomomorphism
{ homSource = booleanLattice
, homTarget = booleanLattice
, homMap = id
, homPreservesJoin = \_ _ -> Refl
, homPreservesMeet = \_ _ -> Refl
}
a = Const (BoolLit True)
b = Const (BoolLit False)
proof = homPreservesJoin hom a b
in proof @?= Refl
testIdPreservesMeet :: Assertion
testIdPreservesMeet =
let hom = LatticeHomomorphism
{ homSource = booleanLattice
, homTarget = booleanLattice
, homMap = id
, homPreservesJoin = \_ _ -> Refl
, homPreservesMeet = \_ _ -> Refl
}
a = Const (BoolLit True)
b = Const (BoolLit False)
proof = homPreservesMeet hom a b
in proof @?= Refl
testHomomorphismComposition :: Assertion
testHomomorphismComposition =
let hom1 = LatticeHomomorphism
{ homSource = booleanLattice
, homTarget = booleanLattice
, homMap = id
, homPreservesJoin = \_ _ -> Refl
, homPreservesMeet = \_ _ -> Refl
}
hom2 = LatticeHomomorphism
{ homSource = booleanLattice
, homTarget = booleanLattice
, homMap = id
, homPreservesJoin = \_ _ -> Refl
, homPreservesMeet = \_ _ -> Refl
}
a = Const (BoolLit True)
composed = homMap hom1 (homMap hom2 a)
in composed @?= a
-- ============================================================================
-- PROOF TERM CHECKING TESTS
-- ============================================================================
testJoinAssocProofChecks :: Assertion
testJoinAssocProofChecks =
let a = Const (BoolLit True)
b = Const (BoolLit False)
c = Const (BoolLit True)
proof = joinAssociativity booleanLattice a b c
-- (a β b) β c β a β (b β c)
lhs = join booleanLattice (join booleanLattice a b) c
rhs = join booleanLattice a (join booleanLattice b c)
prop = EqualityProp lhs rhs
result = proofChecks proof prop
in case result of
Right () -> assertBool "Join associativity proof checks" True
Left err -> assertFailure $ "Proof should check: " ++ show err
testJoinCommProofChecks :: Assertion
testJoinCommProofChecks =
let a = Const (BoolLit True)
b = Const (BoolLit False)
proof = joinCommutativity booleanLattice a b
-- a β b β b β a
lhs = join booleanLattice a b
rhs = join booleanLattice b a
prop = EqualityProp lhs rhs
result = proofChecks proof prop
in case result of
Right () -> assertBool "Join commutativity proof checks" True
Left err -> assertFailure $ "Proof should check: " ++ show err
testJoinIdempProofChecks :: Assertion
testJoinIdempProofChecks =
let a = Const (BoolLit True)
proof = joinIdempotence booleanLattice a
-- a β a β a
lhs = join booleanLattice a a
rhs = a
prop = EqualityProp lhs rhs
result = proofChecks proof prop
in case result of
Right () -> assertBool "Join idempotence proof checks" True
Left err -> assertFailure $ "Proof should check: " ++ show err
testMeetAssocProofChecks :: Assertion
testMeetAssocProofChecks =
let a = Const (BoolLit True)
b = Const (BoolLit False)
c = Const (BoolLit True)
proof = meetAssociativity booleanLattice a b c
-- (a β b) β c β a β (b β c)
lhs = meet booleanLattice (meet booleanLattice a b) c
rhs = meet booleanLattice a (meet booleanLattice b c)
prop = EqualityProp lhs rhs
result = proofChecks proof prop
in case result of
Right () -> assertBool "Meet associativity proof checks" True
Left err -> assertFailure $ "Proof should check: " ++ show err
testMeetCommProofChecks :: Assertion
testMeetCommProofChecks =
let a = Const (BoolLit True)
b = Const (BoolLit False)
proof = meetCommutativity booleanLattice a b
-- a β b β b β a
lhs = meet booleanLattice a b
rhs = meet booleanLattice b a
prop = EqualityProp lhs rhs
result = proofChecks proof prop
in case result of
Right () -> assertBool "Meet commutativity proof checks" True
Left err -> assertFailure $ "Proof should check: " ++ show err
testMeetIdempProofChecks :: Assertion
testMeetIdempProofChecks =
let a = Const (BoolLit True)
proof = meetIdempotence booleanLattice a
-- a β a β a
lhs = meet booleanLattice a a
rhs = a
prop = EqualityProp lhs rhs
result = proofChecks proof prop
in case result of
Right () -> assertBool "Meet idempotence proof checks" True
Left err -> assertFailure $ "Proof should check: " ++ show err
-- ============================================================================
-- LATTICE LAWS INTERPLAY TESTS
-- ============================================================================
testJoinMeetCompat :: Assertion
testJoinMeetCompat =
let a = Const (BoolLit True)
b = Const (BoolLit False)
join_result = join booleanLattice a b
meet_result = meet booleanLattice a b
in (join_result /= meet_result) @? "Join and meet produce different results"
testJoinPropsSimultaneous :: Assertion
testJoinPropsSimultaneous =
let a = Const (BoolLit True)
b = Const (BoolLit False)
c = Const (BoolLit True)
assoc = joinAssociativity booleanLattice a b c
comm = joinCommutativity booleanLattice a b
idemp = joinIdempotence booleanLattice a
in (assoc @?= Refl) >> (comm @?= Refl) >> (idemp @?= Refl)
testMeetPropsSimultaneous :: Assertion
testMeetPropsSimultaneous =
let a = Const (BoolLit True)
b = Const (BoolLit False)
c = Const (BoolLit True)
assoc = meetAssociativity booleanLattice a b c
comm = meetCommutativity booleanLattice a b
idemp = meetIdempotence booleanLattice a
in (assoc @?= Refl) >> (comm @?= Refl) >> (idemp @?= Refl)
-- ============================================================================
-- DETERMINISM TESTS
-- ============================================================================
testJoinDeterminism :: Assertion
testJoinDeterminism =
let a = Const (BoolLit True)
b = Const (BoolLit False)
result1 = join booleanLattice a b
result2 = join booleanLattice a b
in result1 @?= result2
testMeetDeterminism :: Assertion
testMeetDeterminism =
let a = Const (BoolLit True)
b = Const (BoolLit False)
result1 = meet booleanLattice a b
result2 = meet booleanLattice a b
in result1 @?= result2
testProofDeterminism :: Assertion
testProofDeterminism =
let a = Const (BoolLit True)
b = Const (BoolLit False)
proof1 = joinCommutativity booleanLattice a b
proof2 = joinCommutativity booleanLattice a b
in proof1 @?= proof2
-- ============================================================================
-- NEGATIVE TESTS
-- ============================================================================
testElementsDifferent :: Assertion
testElementsDifferent =
let a = Const (BoolLit True)
b = Const (BoolLit False)
in a /= b @? "Different boolean values should not be equal"
|