summaryrefslogtreecommitdiff
path: root/source/Felix/Checking/Exact/Datatype.hs
diff options
context:
space:
mode:
authoradelon <22380201+adelon@users.noreply.github.com>2026-08-06 17:54:00 +0200
committeradelon <22380201+adelon@users.noreply.github.com>2026-08-06 17:54:00 +0200
commit82328890108bae64b372b8d58620ebc62699de76 (patch)
tree575404c6b425c19259c0ded296f1c8ffb7ff0e2b /source/Felix/Checking/Exact/Datatype.hs
parent1a25421c2a168d420581358c8733fcd8f36f379b (diff)
Migrate to `Felix` namespaceHEADhotg
Diffstat (limited to 'source/Felix/Checking/Exact/Datatype.hs')
-rw-r--r--source/Felix/Checking/Exact/Datatype.hs751
1 files changed, 751 insertions, 0 deletions
diff --git a/source/Felix/Checking/Exact/Datatype.hs b/source/Felix/Checking/Exact/Datatype.hs
new file mode 100644
index 0000000..be943cd
--- /dev/null
+++ b/source/Felix/Checking/Exact/Datatype.hs
@@ -0,0 +1,751 @@
+{-# LANGUAGE DerivingStrategies #-}
+{-# LANGUAGE NamedFieldPuns #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+
+-- | Exact preparation of deterministic datatype declarations.
+module Felix.Checking.Exact.Datatype
+ ( PreparedExactDatatype
+ , preparedExactDatatypeObjects
+ , preparedExactDatatypeBindings
+ , PreparedExactDatatypeFact
+ , preparedExactDatatypeFacts
+ , preparedExactDatatypeFactMarker
+ , preparedExactDatatypeFactTarget
+ , preparedExactDatatypeFactReference
+ , preparedExactDatatypeDescriptor
+ , prepareExactDatatype
+ , CheckedExactDatatypeAuthorization
+ , lowerPreparedExactDatatype
+ , authorizeCheckedExactDatatype
+ , ExactDatatypeError(..)
+ , exactDatatypeErrorLocation
+ , renderExactDatatypeError
+ ) where
+
+import Base hiding (Empty)
+import Felix.Checking.Authority
+import Felix.Checking.Core
+import Felix.Checking.Datatype qualified as Datatype
+import Felix.Checking.Declaration qualified as Declaration
+import Felix.Checking.Exact.Global qualified as ExactGlobal
+import Felix.Checking.Exact.Vocabulary
+import Felix.Checking.Identity
+import Felix.Checking.Semantic
+import Felix.Checking.Typed.Inductive qualified as Typed
+import Felix.Cache.Codec
+import Felix.Module
+import Felix.Meaning qualified as Meaning
+import Felix.Report.Location
+import Felix.Syntax.Abstract qualified as Raw
+import Felix.Syntax.Interface
+import Felix.Syntax.Internal qualified as Internal
+
+import Control.Monad (unless, when)
+import Control.Monad.Except (ExceptT)
+import Control.Monad.Except qualified as Except
+import Data.Bifunctor (first)
+import Data.ByteString (ByteString)
+import Data.List.NonEmpty qualified as NonEmpty
+import Data.Map.Strict qualified as Map
+import Data.Set qualified as Set
+import Data.Text qualified as Text
+import Numeric.Natural (Natural)
+
+
+data PreparedDatatypeObject = PreparedDatatypeObject
+ !Internal.Symbol
+ !SemanticGlobalKey
+ !CoreType
+ !ObjectId
+ !AssertedObject
+
+data PreparedExactDatatypeFact = PreparedExactDatatypeFact
+ !Internal.Marker
+ !(FrozenCheckedCore ObjectId)
+ !TheoremRef
+
+preparedExactDatatypeFactMarker
+ :: PreparedExactDatatypeFact
+ -> Internal.Marker
+preparedExactDatatypeFactMarker
+ (PreparedExactDatatypeFact marker _target _reference) =
+ marker
+
+preparedExactDatatypeFactTarget
+ :: PreparedExactDatatypeFact
+ -> FrozenCheckedCore ObjectId
+preparedExactDatatypeFactTarget
+ (PreparedExactDatatypeFact _marker target _reference) =
+ target
+
+preparedExactDatatypeFactReference
+ :: PreparedExactDatatypeFact
+ -> TheoremRef
+preparedExactDatatypeFactReference
+ (PreparedExactDatatypeFact _marker _target reference) =
+ reference
+
+data PreparedExactDatatype = PreparedExactDatatype
+ !Location
+ !DeclarationSyntaxId
+ !(NonEmpty PreparedDatatypeObject)
+ !(NonEmpty PreparedExactDatatypeFact)
+ !DatatypeCompilationDescriptor
+
+data CheckedExactDatatypeAuthorization =
+ CheckedExactDatatypeAuthorization
+ !DatatypeCompilationDescriptor
+ !ObjectId
+ !(NonEmpty ObjectId)
+
+preparedExactDatatypeObjects
+ :: PreparedExactDatatype
+ -> NonEmpty (ObjectId, CoreType)
+preparedExactDatatypeObjects
+ (PreparedExactDatatype _location _syntax objects _facts _descriptor) =
+ fmap
+ (\(PreparedDatatypeObject _symbol _key coreType identity _asserted) ->
+ (identity, coreType))
+ objects
+
+preparedExactDatatypeBindings
+ :: PreparedExactDatatype
+ -> NonEmpty (SemanticGlobalKey, SemanticGlobalTarget)
+preparedExactDatatypeBindings
+ (PreparedExactDatatype _location _syntax objects _facts _descriptor) =
+ fmap
+ (\(PreparedDatatypeObject _symbol key _coreType identity _asserted) ->
+ (key, GlobalReference identity))
+ objects
+
+preparedExactDatatypeFacts
+ :: PreparedExactDatatype
+ -> NonEmpty PreparedExactDatatypeFact
+preparedExactDatatypeFacts
+ (PreparedExactDatatype _location _syntax _objects facts _descriptor) =
+ facts
+
+preparedExactDatatypeDescriptor
+ :: PreparedExactDatatype
+ -> DatatypeCompilationDescriptor
+preparedExactDatatypeDescriptor
+ (PreparedExactDatatype _location _syntax _objects _facts descriptor) =
+ descriptor
+
+lowerPreparedExactDatatype
+ :: PreparedExactDatatype
+ -> Declaration.LoweringDriver
+ (Either
+ Declaration.DeclarationError
+ (Declaration.CheckedDeclaration
+ CheckedExactDatatypeAuthorization))
+lowerPreparedExactDatatype
+ (PreparedExactDatatype _location syntax objects facts descriptor) =
+ do
+ prepared <-
+ traverse
+ (\(PreparedExactDatatypeFact marker target _reference) ->
+ Declaration.prepareFrozenCandidateSpecLowering
+ assertedObjects
+ target
+ SearchEligible
+ [markerAlias marker])
+ facts
+ pure (buildChecked <$> sequence prepared)
+ where
+ assertedObjects =
+ toList
+ (fmap
+ (\(PreparedDatatypeObject
+ _symbol _key _coreType _identity asserted) -> asserted)
+ objects)
+ bindings =
+ toList
+ (fmap
+ (\(PreparedDatatypeObject
+ _symbol key _coreType identity _asserted) ->
+ semanticGlobalBinding key (GlobalReference identity))
+ objects)
+ carrier :| constructors = fmap objectIdentity objects
+ constructorIds =
+ case constructors of
+ firstConstructor : remainingConstructors ->
+ firstConstructor :| remainingConstructors
+ [] -> impossible "a prepared datatype has no constructor"
+ buildChecked specs =
+ Declaration.checkedCompiledDeclaration
+ syntax
+ assertedObjects
+ []
+ bindings
+ []
+ [ fmap
+ (\spec ->
+ Declaration.checkedCandidate
+ spec
+ (Declaration.checkedDatatypePlanning descriptor))
+ specs
+ ]
+ (CheckedExactDatatypeAuthorization
+ descriptor carrier constructorIds)
+
+ markerAlias (Internal.Marker name) = semanticName name
+
+ objectIdentity
+ (PreparedDatatypeObject
+ _symbol _key _coreType identity _asserted) =
+ identity
+
+authorizeCheckedExactDatatype
+ :: CheckedExactDatatypeAuthorization
+ -> [NonEmpty Declaration.ReservedCandidate]
+ -> Declaration.Declaration ()
+authorizeCheckedExactDatatype
+ (CheckedExactDatatypeAuthorization descriptor carrier constructors) =
+ \case
+ [candidates] ->
+ Declaration.authorizeDatatypeCompilationCandidates
+ descriptor carrier constructors candidates
+ stages ->
+ Declaration.failDeclaration
+ (Declaration.CheckedAuthorizationCandidateShapeMismatch
+ 1 (length stages))
+
+data ExactDatatypeError
+ = ExactDatatypeUnsupportedBlock !Location
+ | ExactDatatypeOccurrenceCountMismatch !Location !Int !Int
+ | ExactDatatypeOccurrenceMismatch !Location
+ | ExactDatatypeGlossFailed !Location !Meaning.GlossError
+ | ExactDatatypeInvalid !Location !Text
+ | ExactDatatypeDuplicateGlobal !Location !SemanticGlobalKey
+ | ExactDatatypeFixedSemanticCollision !Location !SemanticGlobalKey
+ | ExactDatatypeGlobalAlreadyVisible !Location !SemanticGlobalKey
+ | ExactDatatypeObjectAlreadyAvailable !Location !ObjectId
+ | ExactDatatypeGlobalResolutionFailed
+ !Location
+ !ExactGlobal.ExactGlobalResolutionError
+ | ExactDatatypeLoweringFailed !Location !Typed.TypedInductiveError
+ | ExactDatatypeExpectedSet !Location !CoreType
+ | ExactDatatypeExpectedProposition !Location !CoreType
+ deriving stock (Show, Eq)
+
+exactDatatypeErrorLocation :: ExactDatatypeError -> Location
+exactDatatypeErrorLocation = \case
+ ExactDatatypeUnsupportedBlock location -> location
+ ExactDatatypeOccurrenceCountMismatch location _expected _actual -> location
+ ExactDatatypeOccurrenceMismatch location -> location
+ ExactDatatypeGlossFailed location _failure -> location
+ ExactDatatypeInvalid location _message -> location
+ ExactDatatypeDuplicateGlobal location _key -> location
+ ExactDatatypeFixedSemanticCollision location _key -> location
+ ExactDatatypeGlobalAlreadyVisible location _key -> location
+ ExactDatatypeObjectAlreadyAvailable location _identity -> location
+ ExactDatatypeGlobalResolutionFailed location _failure -> location
+ ExactDatatypeLoweringFailed location _failure -> location
+ ExactDatatypeExpectedSet location _actual -> location
+ ExactDatatypeExpectedProposition location _actual -> location
+
+renderExactDatatypeError :: ExactDatatypeError -> Text
+renderExactDatatypeError failure =
+ locationToText (exactDatatypeErrorLocation failure)
+ <> ": "
+ <> case failure of
+ ExactDatatypeUnsupportedBlock{} ->
+ "this datatype source form is not supported by the typed checker"
+ ExactDatatypeOccurrenceCountMismatch _location expected actual ->
+ "the datatype has " <> shown actual
+ <> " syntax occurrences, but " <> shown expected
+ <> " are required"
+ ExactDatatypeOccurrenceMismatch{} ->
+ "a datatype syntax occurrence does not match its declaration"
+ ExactDatatypeGlossFailed _location glossFailure ->
+ "datatype elaboration failed: " <> shown glossFailure
+ ExactDatatypeInvalid _location message ->
+ "invalid datatype declaration: " <> message
+ ExactDatatypeDuplicateGlobal _location key ->
+ "the datatype declares the semantic key more than once: "
+ <> shown key
+ ExactDatatypeFixedSemanticCollision _location key ->
+ "the datatype collides with fixed semantics for " <> shown key
+ ExactDatatypeGlobalAlreadyVisible _location key ->
+ "the datatype global is already visible: " <> shown key
+ ExactDatatypeObjectAlreadyAvailable _location identity ->
+ "the datatype opaque object is already available: "
+ <> shown identity
+ ExactDatatypeGlobalResolutionFailed _location resolution ->
+ "datatype global resolution failed: " <> shown resolution
+ ExactDatatypeLoweringFailed _location typedFailure ->
+ "typed datatype lowering failed: " <> shown typedFailure
+ ExactDatatypeExpectedSet _location actual ->
+ "a datatype premise domain has type " <> shown actual
+ <> " instead of Set"
+ ExactDatatypeExpectedProposition _location actual ->
+ "a generated datatype fact has type " <> shown actual
+ <> " instead of Prop"
+ where
+ shown :: Show value => value -> Text
+ shown = Text.pack . show
+
+type Prepare =
+ ExceptT ExactDatatypeError (Declaration.LoweringDriver)
+
+type SourceOccurrence = (Location, Raw.Marker, CanonicalLexicalEntry)
+
+exactDatatypeInvalid
+ :: Location
+ -> Datatype.DatatypeValidationError
+ -> ExactDatatypeError
+exactDatatypeInvalid declarationLocation failure =
+ ExactDatatypeInvalid
+ (fromMaybe
+ declarationLocation
+ (Datatype.datatypeValidationErrorLocation failure))
+ (Datatype.renderDatatypeValidationError failure)
+
+prepareExactDatatype
+ :: Raw.Block
+ -> [SourceOccurrence]
+ -> Declaration.LoweringDriver
+ (Either ExactDatatypeError PreparedExactDatatype)
+prepareExactDatatype block occurrences =
+ Except.runExceptT do
+ (location, marker, rawDatatype) <-
+ case block of
+ Raw.BlockData blockLocation _title blockMarker datatype ->
+ pure (blockLocation, blockMarker, datatype)
+ _ ->
+ Except.throwError
+ (ExactDatatypeUnsupportedBlock (locate block))
+ keys <- validateOccurrences location marker rawDatatype occurrences
+ internal <-
+ case Meaning.meaning [block] of
+ Right
+ [Internal.BlockData
+ _internalLocation _internalMarker datatype] ->
+ pure datatype
+ Left failure ->
+ Except.throwError
+ (ExactDatatypeGlossFailed location failure)
+ Right _ ->
+ Except.throwError
+ (ExactDatatypeUnsupportedBlock location)
+ checked <-
+ -- The new opaque carrier has no semantic binding while its
+ -- declaration is prepared, so premise recursion cannot depend on
+ -- abbreviation expansion. Revisit this if forward aliases become
+ -- available.
+ Except.lift
+ (Datatype.prepareCheckedDatatype pure internal)
+ >>= Except.liftEither
+ . first (exactDatatypeInvalid location)
+ let symbols =
+ Datatype.checkedDatatypeHeadSymbol checked
+ :| toList
+ (Datatype.checkedDatatypeConstructorSymbols checked)
+ views = Datatype.checkedDatatypeClauseViews checked
+ arities =
+ 0 :| (length
+ . Datatype.checkedDatatypeClauseViewArguments
+ <$> toList views)
+ unless (NonEmpty.length symbols == NonEmpty.length keys)
+ (Except.throwError
+ (ExactDatatypeOccurrenceCountMismatch
+ location
+ (NonEmpty.length symbols)
+ (NonEmpty.length keys)))
+ validateKeys occurrences keys
+ slot <- Except.lift Declaration.nextDeclarationSlotLowering
+ theory <- Except.lift Declaration.currentTheoryLowering
+ objects <-
+ sequence
+ (NonEmpty.zipWith
+ (\index (occurrenceLocation, symbol, key, arity) ->
+ prepareObject
+ occurrenceLocation
+ slot theory index symbol key arity)
+ (0 :| [1 ..])
+ (NonEmpty.zipWith
+ (\occurrenceLocation (symbol, key, arity) ->
+ (occurrenceLocation, symbol, key, arity))
+ (validatedOccurrenceLocations occurrences)
+ (NonEmpty.zipWith
+ (\(symbol, key) arity ->
+ (symbol, key, arity))
+ (NonEmpty.zip symbols keys)
+ arities)))
+ let ownedSymbols = Set.fromList (toList symbols)
+ generated = Datatype.checkedDatatypeGeneratedFacts checked
+ externalSymbols =
+ (foldMap
+ (Internal.mentionedSymbols . snd)
+ generated
+ <> foldMap premiseSymbols views)
+ `Set.difference` ownedSymbols
+ external <-
+ Except.lift
+ (ExactGlobal.resolveExactSourceGlobals externalSymbols)
+ >>= Except.liftEither
+ . first (ExactDatatypeGlobalResolutionFailed location)
+ let (externalGlobals, externalTypes) = external
+ ownedGlobals =
+ Map.fromList
+ [ (symbol, Typed.SourceGlobal identity Nothing)
+ | PreparedDatatypeObject
+ symbol _key _coreType identity _asserted <-
+ toList objects
+ ]
+ ownedTypes =
+ Map.fromList
+ [ (identity, coreType)
+ | PreparedDatatypeObject
+ _symbol _key coreType identity _asserted <-
+ toList objects
+ ]
+ sourceGlobals = Map.union ownedGlobals externalGlobals
+ globalTypes = Map.union ownedTypes externalTypes
+ resolveGlobal = (`Map.lookup` sourceGlobals)
+ globalType identity =
+ fromMaybe
+ (impossible
+ "prepared datatype global has no checked type")
+ (Map.lookup identity globalTypes)
+ preparedClauses <-
+ Except.liftEither
+ (traverse
+ (prepareClause location globalType resolveGlobal)
+ views)
+ facts <-
+ Except.liftEither
+ (traverse
+ (prepareFact location theory globalType resolveGlobal)
+ generated)
+ let carrier = objectIdentity (NonEmpty.head objects)
+ constructors = objectIdentity <$> NonEmpty.tail objects
+ descriptor =
+ case NonEmpty.nonEmpty constructors of
+ Nothing ->
+ impossible
+ "a checked datatype has no constructors"
+ Just nonemptyConstructors ->
+ datatypeCompilationDescriptor
+ carrier
+ nonemptyConstructors
+ (preparedExactDatatypeFactReference
+ <$> toList facts)
+ syntax =
+ declarationSyntaxId
+ (encodePreparedDatatype
+ objects
+ preparedClauses
+ facts
+ descriptor)
+ pure
+ (PreparedExactDatatype
+ location
+ syntax
+ objects
+ facts
+ descriptor)
+ where
+ objectIdentity
+ (PreparedDatatypeObject _symbol _key _coreType identity _asserted) =
+ identity
+
+validateOccurrences
+ :: Location
+ -> Raw.Marker
+ -> Raw.Datatype
+ -> [SourceOccurrence]
+ -> Prepare (NonEmpty SemanticGlobalKey)
+validateOccurrences location marker datatype occurrences = do
+ expected <-
+ Except.liftEither
+ (expectedOccurrences location marker datatype)
+ unless (length occurrences == NonEmpty.length expected)
+ (Except.throwError
+ (ExactDatatypeOccurrenceCountMismatch
+ location
+ (NonEmpty.length expected)
+ (length occurrences)))
+ keys <-
+ sequence
+ (NonEmpty.zipWith validateOne expected
+ (case NonEmpty.nonEmpty occurrences of
+ Just nonempty -> nonempty
+ Nothing ->
+ impossible
+ "equal nonzero occurrence counts became empty"))
+ pure keys
+ where
+ validateOne
+ (expectedLocation, expectedMarker, expectedPattern)
+ (actualLocation, actualMarker, entry) =
+ case entry of
+ CanonicalExpressionFunction pat marker' _fixity
+ | actualMarker == expectedMarker
+ , marker' == expectedMarker
+ , pat == expectedPattern ->
+ pure
+ (SemanticExpressionFunction pat)
+ _ ->
+ Except.throwError
+ (ExactDatatypeOccurrenceMismatch
+ (bestLocation actualLocation expectedLocation))
+
+ bestLocation actual expected
+ | actual == Nowhere = expected
+ | otherwise = actual
+
+expectedOccurrences
+ :: Location
+ -> Raw.Marker
+ -> Raw.Datatype
+ -> Either
+ ExactDatatypeError
+ (NonEmpty (Location, Raw.Marker, Raw.Pattern))
+expectedOccurrences location blockMarker datatype = do
+ headOccurrence <-
+ expectedSymbol blockMarker (Raw.datatypeHeadExpr datatype)
+ clauses <-
+ traverse
+ (\clause ->
+ case Raw.datatypeClauseConstructorExpr clause of
+ Raw.ExprOp constructorLocation symbol _arguments ->
+ Right
+ ( constructorLocation
+ , Raw.mixfixMarker symbol
+ , Raw.mixfixPattern symbol
+ )
+ expression ->
+ Left
+ (ExactDatatypeOccurrenceMismatch
+ (locate expression)))
+ (Raw.datatypeClauses datatype)
+ pure (headOccurrence :| toList clauses)
+ where
+ expectedSymbol expectedMarker = \case
+ Raw.ExprOp symbolLocation symbol [] ->
+ Right
+ ( symbolLocation
+ , expectedMarker
+ , Raw.mixfixPattern symbol
+ )
+ expression ->
+ Left
+ (ExactDatatypeOccurrenceMismatch
+ (case locate expression of
+ Nowhere -> location
+ expressionLocation -> expressionLocation))
+
+validateKeys
+ :: [SourceOccurrence]
+ -> NonEmpty SemanticGlobalKey
+ -> Prepare ()
+validateKeys occurrences keys = do
+ case duplicateWithLocation of
+ Just (duplicate, duplicateLocation) ->
+ Except.throwError
+ (ExactDatatypeDuplicateGlobal
+ duplicateLocation
+ duplicate)
+ Nothing -> pure ()
+ traverse_ validateOne (NonEmpty.zip locations keys)
+ where
+ locations = validatedOccurrenceLocations occurrences
+
+ duplicateWithLocation =
+ go Set.empty
+ [ (key, occurrenceLocation)
+ | (key, (occurrenceLocation, _marker, _entry)) <-
+ zip (toList keys) occurrences
+ ]
+
+ go _seen [] = Nothing
+ go seen ((key, occurrenceLocation) : remaining)
+ | key `Set.member` seen = Just (key, occurrenceLocation)
+ | otherwise = go (Set.insert key seen) remaining
+
+ validateOne (occurrenceLocation, key) = do
+ when (isJust (fixedSemanticMeaning key))
+ (Except.throwError
+ (ExactDatatypeFixedSemanticCollision occurrenceLocation key))
+ visible <-
+ Except.lift
+ (Declaration.resolveVisibleGlobalLowering key)
+ when (isJust visible)
+ (Except.throwError
+ (ExactDatatypeGlobalAlreadyVisible occurrenceLocation key))
+
+validatedOccurrenceLocations
+ :: [SourceOccurrence]
+ -> NonEmpty Location
+validatedOccurrenceLocations occurrences =
+ case NonEmpty.nonEmpty
+ [ occurrenceLocation
+ | (occurrenceLocation, _marker, _entry) <- occurrences
+ ] of
+ Just nonempty -> nonempty
+ Nothing ->
+ impossible "validated datatype occurrences are empty"
+
+prepareObject
+ :: Location
+ -> DeclarationSlot
+ -> TheoryId
+ -> Natural
+ -> Internal.Symbol
+ -> SemanticGlobalKey
+ -> Int
+ -> Prepare PreparedDatatypeObject
+prepareObject location slot theory index symbol key arity = do
+ let coreType =
+ foldr (const (TyArrow TySet)) TySet [1 .. arity]
+ seed =
+ opaqueDeclarationSeed
+ (declarationSlotModule slot)
+ (declarationSlotOrdinal slot)
+ DatatypeDeclaration
+ (generatedObjectSlot index)
+ content = OpaqueObjectContent theory seed coreType
+ identity = opaqueObjectId theory seed coreType
+ available <- Except.lift (Declaration.objectAvailableLowering identity)
+ when available
+ (Except.throwError
+ (ExactDatatypeObjectAlreadyAvailable location identity))
+ pure
+ (PreparedDatatypeObject
+ symbol
+ key
+ coreType
+ identity
+ (assertedObject identity content))
+
+data PreparedClause = PreparedClause
+ !Internal.FunctionSymbol
+ ![PreparedPremise]
+
+data PreparedPremise
+ = PreparedRecursivePremise !(FrozenCheckedCore ObjectId)
+ | PreparedNonRecursivePremise !(FrozenCheckedCore ObjectId)
+
+prepareClause
+ :: Location
+ -> (ObjectId -> CoreType)
+ -> (Internal.Symbol -> Maybe (Typed.SourceGlobal ObjectId))
+ -> Datatype.CheckedDatatypeClauseView
+ -> Either ExactDatatypeError PreparedClause
+prepareClause location globalType resolveGlobal view =
+ PreparedClause
+ (Datatype.checkedDatatypeClauseViewConstructor view)
+ <$> traverse preparePremise
+ (Datatype.checkedDatatypeClauseViewPremises view)
+ where
+ preparePremise = \case
+ Datatype.CheckedRecursiveDatatypePremise _variable domain ->
+ PreparedRecursivePremise
+ <$> prepareDomain domain
+ Datatype.CheckedNonRecursiveDatatypePremise _variable domain ->
+ PreparedNonRecursivePremise
+ <$> prepareDomain domain
+
+ prepareDomain domain = do
+ checked <-
+ first (ExactDatatypeLoweringFailed location)
+ (Typed.prepareTypedClosedTerm
+ globalType
+ resolveGlobal
+ domain)
+ unless (frozenCoreType checked == TySet)
+ (Left
+ (ExactDatatypeExpectedSet
+ location
+ (frozenCoreType checked)))
+ pure checked
+
+prepareFact
+ :: Location
+ -> TheoryId
+ -> (ObjectId -> CoreType)
+ -> (Internal.Symbol -> Maybe (Typed.SourceGlobal ObjectId))
+ -> (Internal.Marker, Internal.Formula)
+ -> Either ExactDatatypeError PreparedExactDatatypeFact
+prepareFact location theory globalType resolveGlobal (marker, formula) = do
+ checked <-
+ first (ExactDatatypeLoweringFailed location)
+ (Typed.prepareTypedClosedFormula
+ globalType
+ resolveGlobal
+ formula)
+ unless (frozenCoreType checked == TyProp)
+ (Left
+ (ExactDatatypeExpectedProposition
+ location
+ (frozenCoreType checked)))
+ pure
+ (PreparedExactDatatypeFact
+ marker
+ checked
+ (theoremRef theory
+ (propositionIdOf (frozenCoreTerm checked))))
+
+premiseSymbols
+ :: Datatype.CheckedDatatypeClauseView
+ -> Set.Set Internal.Symbol
+premiseSymbols view =
+ foldMap symbols
+ (Datatype.checkedDatatypeClauseViewPremises view)
+ where
+ symbols = \case
+ Datatype.CheckedRecursiveDatatypePremise _variable domain ->
+ Internal.mentionedSymbols domain
+ Datatype.CheckedNonRecursiveDatatypePremise _variable domain ->
+ Internal.mentionedSymbols domain
+
+encodePreparedDatatype
+ :: NonEmpty PreparedDatatypeObject
+ -> NonEmpty PreparedClause
+ -> NonEmpty PreparedExactDatatypeFact
+ -> DatatypeCompilationDescriptor
+ -> ByteString
+encodePreparedDatatype objects clauses facts descriptor =
+ encodeCache do
+ putCacheTag 0x05
+ putCacheList putObject (toList objects)
+ putCacheList putClause (toList clauses)
+ putCacheList putFact (toList facts)
+ putDirectAuthorizationCache
+ (TrustedCompilation
+ (DatatypeCompilation descriptor))
+ where
+ putObject
+ (PreparedDatatypeObject
+ _symbol key coreType identity _asserted) = do
+ putSemanticGlobalKeyCache key
+ putCoreTypeCache coreType
+ putObjectIdCache identity
+
+ putClause (PreparedClause constructor premises) = do
+ putSemanticGlobalKeyCache
+ (SemanticExpressionFunction
+ (Raw.mixfixPattern constructor))
+ putCacheList putPremise premises
+
+ putPremise = \case
+ PreparedRecursivePremise domain -> do
+ putCacheTag 0x00
+ putCanonicalTermCache putObjectIdCache
+ (frozenCoreTerm domain)
+ PreparedNonRecursivePremise domain -> do
+ putCacheTag 0x01
+ putCanonicalTermCache putObjectIdCache
+ (frozenCoreTerm domain)
+
+ putFact fact = do
+ let Internal.Marker marker =
+ preparedExactDatatypeFactMarker fact
+ putCacheText marker
+ putCanonicalTermCache putObjectIdCache
+ (frozenCoreTerm
+ (preparedExactDatatypeFactTarget fact))
+ putTheoremRefCache
+ (preparedExactDatatypeFactReference fact)