summaryrefslogtreecommitdiff
path: root/source/Felix/Checking/Materialization.hs
diff options
context:
space:
mode:
Diffstat (limited to 'source/Felix/Checking/Materialization.hs')
-rw-r--r--source/Felix/Checking/Materialization.hs288
1 files changed, 288 insertions, 0 deletions
diff --git a/source/Felix/Checking/Materialization.hs b/source/Felix/Checking/Materialization.hs
new file mode 100644
index 0000000..51944a5
--- /dev/null
+++ b/source/Felix/Checking/Materialization.hs
@@ -0,0 +1,288 @@
+{-# LANGUAGE DerivingStrategies #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+
+-- | Pure applicability checks for later trusted materialization.
+--
+-- Successful checks are inert. Fresh completion and validated loading or
+-- sealing own the runtime authority that may publish a fact.
+module Felix.Checking.Materialization
+ ( CandidateValidation
+ , candidateProofValidation
+ , candidateDeclarationValidation
+ , checkDeclarationValidationRecord
+ , checkCandidateValidation
+ , checkImportedMembership
+ , checkImportedOccurrence
+ , MaterializationError(..)
+ ) where
+
+import Base
+import Felix.Checking.Authority
+import Felix.Checking.Identity
+import Felix.Checking.Semantic
+
+import Control.Monad (unless)
+import Numeric.Natural (Natural)
+
+
+data CandidateValidation
+ = CandidateProofValidation
+ !ProofValidationRecord
+ !ProofSyntaxId
+ | CandidateDeclarationValidation
+ !DeclarationValidationRecord
+ !DeclarationSyntaxId
+ ![ObjectId]
+ ![TheoremId]
+ !Natural
+ deriving stock (Show, Eq)
+
+candidateProofValidation
+ :: ProofValidationRecord
+ -> ProofSyntaxId
+ -> CandidateValidation
+candidateProofValidation =
+ CandidateProofValidation
+
+candidateDeclarationValidation
+ :: DeclarationValidationRecord
+ -> DeclarationSyntaxId
+ -> [ObjectId]
+ -> [TheoremId]
+ -> Natural
+ -> CandidateValidation
+candidateDeclarationValidation =
+ CandidateDeclarationValidation
+
+checkDeclarationValidationRecord
+ :: PrefixContextId
+ -> DeclarationSyntaxId
+ -> [ObjectId]
+ -> [TheoremId]
+ -> DeclarationValidationRecord
+ -> Either MaterializationError ()
+checkDeclarationValidationRecord prefix syntax objects theorems record = do
+ let suppliedKey =
+ declarationValidationRecordKey record
+ certificates =
+ declarationValidationRecordCertificates record
+ expectedKey =
+ declarationValidationKey
+ syntax prefix objects theorems
+ unless
+ (suppliedKey == expectedKey)
+ (Left
+ (DeclarationValidationKeyMismatch
+ suppliedKey expectedKey))
+ let certificateTheorems =
+ theoremId
+ . factAuthorityTheorem
+ . validationTarget
+ <$> certificates
+ unless
+ (certificateTheorems == theorems)
+ (Left
+ (DeclarationCertificateTargetsMismatch
+ theorems certificateTheorems))
+
+data MaterializationError
+ = CandidateValidationIndexMissing !Natural
+ | ProofValidationKeyMismatch
+ !ProofValidationKey
+ !ProofValidationKey
+ | DeclarationValidationKeyMismatch
+ !DeclarationValidationKey
+ !DeclarationValidationKey
+ | DeclarationCertificateTargetsMismatch
+ ![TheoremId]
+ ![TheoremId]
+ | CandidateCertificateTargetMismatch
+ !FactAuthority
+ !FactAuthority
+ | CandidateDirectAuthorizationMismatch
+ !DirectAuthorization
+ !DirectAuthorization
+ | CandidateTheoryMismatch !TheoryId !TheoryId
+ | CandidatePropositionMismatch
+ !PropositionId
+ !PropositionId
+ | ImportedOccurrenceMissing
+ !SemanticFactOccurrenceFingerprint
+ | ImportedAuthorityMismatch
+ !FactAuthority
+ !FactAuthority
+ | ImportedTheoryMismatch !TheoryId !TheoryId
+ | ImportedPropositionMismatch
+ !PropositionId
+ !PropositionId
+ deriving stock (Show, Eq)
+
+
+-- | Check whether inert validation data applies to one exact candidate.
+--
+-- Success deliberately returns no builder authorization. A fresh trusted
+-- completion or compatible validated-store hit must perform this check before
+-- its owner mints runtime authority.
+checkCandidateValidation
+ :: TheoryId
+ -> PrefixContextId
+ -> CheckedPropositionContent
+ -> FactAuthority
+ -> DirectAuthorization
+ -> CandidateValidation
+ -> Either MaterializationError ()
+checkCandidateValidation
+ theory prefix proposition expectedAuthority
+ expectedDirect validation = do
+ certificate <-
+ candidateCertificate
+ prefix expectedAuthority validation
+ validateCertificateTarget
+ theory proposition expectedAuthority expectedDirect certificate
+
+candidateCertificate
+ :: PrefixContextId
+ -> FactAuthority
+ -> CandidateValidation
+ -> Either MaterializationError ValidationCertificate
+candidateCertificate prefix authority = \case
+ CandidateProofValidation record syntax -> do
+ let suppliedKey =
+ proofValidationRecordKey record
+ certificate =
+ proofValidationRecordCertificate record
+ expectedKey =
+ proofValidationKey
+ (theoremId
+ (factAuthorityTheorem authority))
+ syntax
+ prefix
+ unless
+ (suppliedKey == expectedKey)
+ (Left
+ (ProofValidationKeyMismatch
+ suppliedKey expectedKey))
+ pure certificate
+ CandidateDeclarationValidation
+ record syntax objects theorems ordinal -> do
+ checkDeclarationValidationRecord
+ prefix syntax objects theorems record
+ maybe
+ (Left (CandidateValidationIndexMissing ordinal))
+ Right
+ (nthNatural ordinal
+ (declarationValidationRecordCertificates record))
+
+validateCertificateTarget
+ :: TheoryId
+ -> CheckedPropositionContent
+ -> FactAuthority
+ -> DirectAuthorization
+ -> ValidationCertificate
+ -> Either MaterializationError ()
+validateCertificateTarget
+ theory proposition expectedAuthority expectedDirect certificate = do
+ let actualAuthority =
+ validationTarget certificate
+ actualDirect =
+ validationDirectAuthorization certificate
+ reference =
+ factAuthorityTheorem actualAuthority
+ unless
+ (actualAuthority == expectedAuthority)
+ (Left
+ (CandidateCertificateTargetMismatch
+ expectedAuthority actualAuthority))
+ unless
+ (actualDirect == expectedDirect)
+ (Left
+ (CandidateDirectAuthorizationMismatch
+ expectedDirect actualDirect))
+ unless
+ (theoremRefTheory reference == theory)
+ (Left
+ (CandidateTheoryMismatch
+ theory
+ (theoremRefTheory reference)))
+ unless
+ ( theoremRefProposition reference
+ == checkedPropositionId proposition
+ )
+ (Left
+ (CandidatePropositionMismatch
+ (checkedPropositionId proposition)
+ (theoremRefProposition reference)))
+
+
+-- | Validate exact membership in inert canonical interface data.
+--
+-- Logical sealing or atomic cached installation must additionally supply the
+-- opaque runtime evidence before an importer receives builder authority.
+checkImportedMembership
+ :: TheoryId
+ -> SemanticInterface
+ -> SemanticFactOccurrenceFingerprint
+ -> CheckedPropositionContent
+ -> FactAuthority
+ -> Either MaterializationError SemanticFactOccurrence
+checkImportedMembership
+ theory interface fingerprint proposition expectedAuthority = do
+ occurrence <-
+ maybe
+ (Left (ImportedOccurrenceMissing fingerprint))
+ Right
+ (find
+ ((== fingerprint) . semanticFactFingerprint)
+ (concatMap
+ declarationDeltaFacts
+ (semanticInterfaceDeclarations interface)))
+ checkImportedOccurrence
+ theory fingerprint occurrence proposition expectedAuthority
+
+checkImportedOccurrence
+ :: TheoryId
+ -> SemanticFactOccurrenceFingerprint
+ -> SemanticFactOccurrence
+ -> CheckedPropositionContent
+ -> FactAuthority
+ -> Either MaterializationError SemanticFactOccurrence
+checkImportedOccurrence
+ theory fingerprint occurrence proposition expectedAuthority = do
+ unless
+ (semanticFactFingerprint occurrence == fingerprint)
+ (Left (ImportedOccurrenceMissing fingerprint))
+ let actualAuthority =
+ semanticFactAuthority occurrence
+ reference =
+ factAuthorityTheorem actualAuthority
+ unless
+ (actualAuthority == expectedAuthority)
+ (Left
+ (ImportedAuthorityMismatch
+ expectedAuthority actualAuthority))
+ unless
+ (theoremRefTheory reference == theory)
+ (Left
+ (ImportedTheoryMismatch
+ theory
+ (theoremRefTheory reference)))
+ unless
+ (theoremRefProposition reference
+ == checkedPropositionId proposition)
+ (Left
+ (ImportedPropositionMismatch
+ (checkedPropositionId proposition)
+ (theoremRefProposition reference)))
+ pure occurrence
+
+
+nthNatural :: Natural -> [value] -> Maybe value
+nthNatural ordinal =
+ go ordinal
+ where
+ go _ [] =
+ Nothing
+ go 0 (value : _) =
+ Just value
+ go remaining (_ : rest) =
+ go (remaining - 1) rest