summaryrefslogtreecommitdiff
path: root/source/Felix/Checking/Exact.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.hs
parent1a25421c2a168d420581358c8733fcd8f36f379b (diff)
Migrate to `Felix` namespaceHEADhotg
Diffstat (limited to 'source/Felix/Checking/Exact.hs')
-rw-r--r--source/Felix/Checking/Exact.hs3936
1 files changed, 3936 insertions, 0 deletions
diff --git a/source/Felix/Checking/Exact.hs b/source/Felix/Checking/Exact.hs
new file mode 100644
index 0000000..c829743
--- /dev/null
+++ b/source/Felix/Checking/Exact.hs
@@ -0,0 +1,3936 @@
+{-# LANGUAGE DerivingStrategies #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+
+-- | Direct compiler for the first exact monomorphic declaration family.
+module Felix.Checking.Exact
+ ( ExactLocalId
+ , exactLocalId
+ , exactLocalIdValue
+ , ExactBinderContext
+ , emptyExactBinderContext
+ , extendExactBinderContext
+ , extendExactAnonymousBinderContext
+ , exactBinderContextSupport
+ , exactBinderContextIndex
+ , PreparedExactProposition
+ , preparedExactPropositionCore
+ , prepareExactProposition
+ , prepareExactSymbolicBoundConstraints
+ , prepareExactSymbolicWitnessConstraints
+ , prepareExactNounWitnessConstraints
+ , PreparedExactSetExpression
+ , PreparedExactSetConstruction(..)
+ , preparedExactSetExpressionCore
+ , preparedExactSetExpressionConstruction
+ , prepareExactSetExpression
+ , PreparedExactLocalFunctionGraph
+ , preparedExactLocalFunctionGraphCore
+ , preparedExactLocalFunctionGraphDomain
+ , preparedExactLocalFunctionGraphMap
+ , prepareExactLocalFunctionGraph
+ , PreparedExactClaimEnvelope
+ , preparedExactClaimTarget
+ , preparedExactClaimVariables
+ , preparedExactClaimContext
+ , preparedExactClaimAntecedentCount
+ , prepareExactClaimEnvelope
+ , PreparedExactDeclaration
+ , preparedExactLocation
+ , preparedExactGlobalKey
+ , preparedExactObjectId
+ , preparedExactObject
+ , preparedExactSyntaxId
+ , preparedExactIsDefinition
+ , prepareExactDeclaration
+ , lowerPreparedExactBinding
+ , CheckedExactBindingAuthorization
+ , authorizeCheckedExactBinding
+ , PreparedExactStructure
+ , prepareExactStructure
+ , CheckedExactStructureAuthorization
+ , lowerPreparedExactStructure
+ , authorizeCheckedExactStructure
+ , PreparedExactSourceAxiom
+ , prepareExactSourceAxiom
+ , lowerPreparedExactSourceAxiom
+ , authorizeCheckedExactSourceAxiom
+ , ExactCompileError(..)
+ , exactCompileErrorLocation
+ , renderExactCompileError
+ ) where
+
+import Base hiding (Empty)
+import Felix.Cache.Codec
+import Felix.Checking.Core
+import Felix.Checking.Declaration qualified as Declaration
+import Felix.Checking.Exact.Vocabulary
+import Felix.Checking.Identity
+import Felix.Checking.Semantic
+import Felix.Checking.SetConstruction
+import Felix.Module
+import Felix.Report.Location
+import Felix.Syntax.Abstract qualified as Raw
+import Felix.Syntax.Interface (CanonicalLexicalEntry(..))
+import Felix.Syntax.Lexicon qualified as Lexicon
+
+import Control.Monad.Except (ExceptT)
+import Control.Monad.Except (MonadError, throwError)
+import Control.Monad.Except qualified as Except
+import Control.Monad (foldM, unless, when)
+import Control.Monad.State.Strict (StateT)
+import Control.Monad.State.Strict qualified as State
+import Data.ByteString (ByteString)
+import Data.Bifunctor (first)
+import Data.List.NonEmpty qualified as NonEmpty
+import Data.Map.Strict qualified as Map
+import Data.Maybe (catMaybes)
+import Data.Set qualified as Set
+import Data.Text qualified as Text
+import Data.Vector (Vector)
+import Data.Vector qualified as Vector
+import Numeric.Natural (Natural)
+
+
+-- | A disposable identity allocated in source order within one proof.
+newtype ExactLocalId = ExactLocalId Natural
+ deriving stock (Show, Eq, Ord)
+
+exactLocalId :: Natural -> ExactLocalId
+exactLocalId = ExactLocalId
+
+exactLocalIdValue :: ExactLocalId -> Natural
+exactLocalIdValue (ExactLocalId value) = value
+
+data ExactBinder = ExactBinder
+ !ExactLocalId
+ !(Maybe Raw.VarSymbol)
+ !CoreType
+ !(Maybe ExactStructureAnnotation)
+
+data ExactStructureAnnotation = ExactStructureAnnotation
+ !SemanticStructurePhrase
+ !(Maybe ObjectId)
+ !(Map.Map Raw.StructSymbol ObjectId)
+
+-- | The active nearest-first binders of one exact proof scope.
+newtype ExactBinderContext = ExactBinderContext [ExactBinder]
+
+emptyExactBinderContext :: ExactBinderContext
+emptyExactBinderContext = ExactBinderContext []
+
+extendExactBinderContext
+ :: NonEmpty (ExactLocalId, Raw.VarSymbol)
+ -> ExactBinderContext
+ -> Either ExactCompileError ExactBinderContext
+extendExactBinderContext additions (ExactBinderContext initial) =
+ ExactBinderContext <$> foldM add initial (toList additions)
+ where
+ add binders (identity, variable)
+ | any (sameVariable variable) binders =
+ Left (ExactDuplicateLocalBinder (locate variable) variable)
+ | any (sameIdentity identity) binders =
+ Left (ExactDuplicateLocalIdentity (locate variable) identity)
+ | otherwise =
+ Right (ExactBinder identity (Just variable) TySet Nothing : binders)
+
+ sameVariable variable (ExactBinder _identity existing _coreType _structure) =
+ existing == Just variable
+
+ sameIdentity identity (ExactBinder existing _variable _coreType _structure) =
+ existing == identity
+
+-- | Add one proof-owned binder which deliberately has no source-resolvable
+-- spelling. This is used for a nameless singular witness; it participates in
+-- checked support and de Bruijn weakening but cannot shadow or be looked up by
+-- a later source variable.
+extendExactAnonymousBinderContext
+ :: ExactLocalId
+ -> ExactBinderContext
+ -> Either ExactCompileError ExactBinderContext
+extendExactAnonymousBinderContext identity (ExactBinderContext binders)
+ | any sameIdentity binders =
+ Left (ExactDuplicateLocalIdentity Nowhere identity)
+ | otherwise =
+ Right
+ (ExactBinderContext
+ (ExactBinder identity Nothing TySet Nothing : binders))
+ where
+ sameIdentity (ExactBinder existing _variable _coreType _structure) =
+ existing == identity
+
+exactBinderContextSupport
+ :: ExactBinderContext
+ -> Vector (ExactLocalId, CoreType)
+exactBinderContextSupport (ExactBinderContext binders) =
+ Vector.fromList
+ [ (identity, coreType)
+ | ExactBinder identity _variable coreType _structure <- binders
+ ]
+
+exactBinderContextIndex
+ :: Raw.VarSymbol
+ -> ExactBinderContext
+ -> Maybe Natural
+exactBinderContextIndex variable (ExactBinderContext binders) =
+ go 0 binders
+ where
+ go _index [] =
+ Nothing
+ go index (ExactBinder _identity candidate _coreType _structure : rest)
+ | candidate == Just variable = Just index
+ | otherwise = go (index + 1) rest
+
+newtype PreparedExactProposition = PreparedExactProposition
+ (ScopedCheckedCore ObjectId)
+
+preparedExactPropositionCore
+ :: PreparedExactProposition
+ -> ScopedCheckedCore ObjectId
+preparedExactPropositionCore (PreparedExactProposition proposition) =
+ proposition
+
+data PreparedExactSetExpression = PreparedExactSetExpression
+ !(ScopedCheckedCore ObjectId)
+ !(Maybe PreparedExactSetConstruction)
+
+data PreparedExactSetConstruction
+ = PreparedUnconditionalSetConstruction
+ !(NamedSetConstruction ObjectId)
+ | PreparedRelationalSetConstruction
+ !(CheckedRelationalSetConstruction ObjectId)
+
+preparedExactSetExpressionCore
+ :: PreparedExactSetExpression
+ -> ScopedCheckedCore ObjectId
+preparedExactSetExpressionCore (PreparedExactSetExpression expression _construction) =
+ expression
+
+preparedExactSetExpressionConstruction
+ :: PreparedExactSetExpression
+ -> Maybe PreparedExactSetConstruction
+preparedExactSetExpressionConstruction
+ (PreparedExactSetExpression _expression construction) =
+ construction
+
+-- | A checked replacement graph and the two checked arguments used to
+-- specialize its foundation characteristic. This is transient proof
+-- preparation data, not a declaration or durable object.
+data PreparedExactLocalFunctionGraph = PreparedExactLocalFunctionGraph
+ !(ScopedCheckedCore ObjectId)
+ !(ScopedCheckedCore ObjectId)
+ !(ScopedCheckedCore ObjectId)
+
+preparedExactLocalFunctionGraphCore
+ :: PreparedExactLocalFunctionGraph
+ -> ScopedCheckedCore ObjectId
+preparedExactLocalFunctionGraphCore
+ (PreparedExactLocalFunctionGraph graph _domain _function) =
+ graph
+
+preparedExactLocalFunctionGraphDomain
+ :: PreparedExactLocalFunctionGraph
+ -> ScopedCheckedCore ObjectId
+preparedExactLocalFunctionGraphDomain
+ (PreparedExactLocalFunctionGraph _graph domain _function) =
+ domain
+
+preparedExactLocalFunctionGraphMap
+ :: PreparedExactLocalFunctionGraph
+ -> ScopedCheckedCore ObjectId
+preparedExactLocalFunctionGraphMap
+ (PreparedExactLocalFunctionGraph _graph _domain function) =
+ function
+
+-- | One authoritative closed proposition prepared from a top-level claim
+-- header and conclusion. The remaining fields are transient opening data for
+-- the proof compiler.
+data PreparedExactClaimEnvelope = PreparedExactClaimEnvelope
+ !(ScopedCheckedCore ObjectId)
+ ![Raw.VarSymbol]
+ !ExactBinderContext
+ !Natural
+
+preparedExactClaimTarget
+ :: PreparedExactClaimEnvelope
+ -> ScopedCheckedCore ObjectId
+preparedExactClaimTarget
+ (PreparedExactClaimEnvelope target _variables _context _antecedents) =
+ target
+
+preparedExactClaimVariables
+ :: PreparedExactClaimEnvelope
+ -> [Raw.VarSymbol]
+preparedExactClaimVariables
+ (PreparedExactClaimEnvelope _target variables _context _antecedents) =
+ variables
+
+preparedExactClaimContext
+ :: PreparedExactClaimEnvelope
+ -> ExactBinderContext
+preparedExactClaimContext
+ (PreparedExactClaimEnvelope _target _variables context _antecedents) =
+ context
+
+preparedExactClaimAntecedentCount
+ :: PreparedExactClaimEnvelope
+ -> Natural
+preparedExactClaimAntecedentCount
+ (PreparedExactClaimEnvelope _target _variables _context antecedents) =
+ antecedents
+
+
+data ExactDeclarationFamily
+ = ExactSignature
+ | ExactAbbreviation
+ | ExactDefinition
+ deriving stock (Show, Eq, Ord)
+
+data PreparedExactDeclaration = PreparedExactDeclaration
+ !Location
+ !ExactDeclarationFamily
+ !SemanticGlobalKey
+ !SemanticGlobalTarget
+ !(Maybe AssertedObject)
+ !(Maybe SemanticName)
+ !(Maybe PreparedExactSetConstruction)
+ !DeclarationSyntaxId
+
+preparedExactLocation :: PreparedExactDeclaration -> Location
+preparedExactLocation
+ (PreparedExactDeclaration location _family _key _target _object _alias _construction _syntax) =
+ location
+
+preparedExactGlobalKey :: PreparedExactDeclaration -> SemanticGlobalKey
+preparedExactGlobalKey
+ (PreparedExactDeclaration _location _family key _target _object _alias _construction _syntax) =
+ key
+
+preparedExactObjectId :: PreparedExactDeclaration -> ObjectId
+preparedExactObjectId
+ (PreparedExactDeclaration _location _family _key target _object _alias _construction _syntax) =
+ semanticGlobalTargetObject target
+
+preparedExactObject
+ :: PreparedExactDeclaration
+ -> Maybe AssertedObject
+preparedExactObject
+ (PreparedExactDeclaration _location _family _key _target object _alias _construction _syntax) =
+ object
+
+preparedExactSyntaxId
+ :: PreparedExactDeclaration
+ -> DeclarationSyntaxId
+preparedExactSyntaxId
+ (PreparedExactDeclaration _location _family _key _target _object _alias _construction syntax) =
+ syntax
+
+preparedExactIsDefinition :: PreparedExactDeclaration -> Bool
+preparedExactIsDefinition
+ (PreparedExactDeclaration _location family _key _target _object _alias _construction _syntax) =
+ family == ExactDefinition
+
+preparedExactGlobalTarget
+ :: PreparedExactDeclaration
+ -> SemanticGlobalTarget
+preparedExactGlobalTarget
+ (PreparedExactDeclaration
+ _location _family _key target _object _alias _construction _syntax) =
+ target
+
+preparedDefinitionAlias
+ :: PreparedExactDeclaration
+ -> Maybe SemanticName
+preparedDefinitionAlias
+ (PreparedExactDeclaration
+ _location _family _key _target _object alias _construction _syntax) =
+ alias
+
+preparedDefinitionConstruction
+ :: PreparedExactDeclaration
+ -> Maybe PreparedExactSetConstruction
+preparedDefinitionConstruction
+ (PreparedExactDeclaration
+ _location _family _key _target _object _alias construction _syntax) =
+ construction
+
+data PreparedExactSourceAxiom = PreparedExactSourceAxiom
+ !Location
+ !SemanticName
+ !(ScopedCheckedCore ObjectId)
+ !DeclarationSyntaxId
+
+data PreparedExactStructureFact = PreparedExactStructureFact
+ !Location
+ !(FrozenCheckedCore ObjectId)
+ !SemanticName
+
+data PreparedExactStructure = PreparedExactStructure
+ !Location
+ ![AssertedObject]
+ !ObjectId
+ !SemanticStructureDescriptor
+ !SemanticName
+ ![PreparedExactStructureFact]
+ !DeclarationSyntaxId
+
+data CheckedExactStructureAuthorization =
+ CheckedExactStructureAuthorization
+ !ObjectId
+ ![(Location, Declaration.PreparedVampireObligation Void ())]
+
+data ExactCompileError
+ = ExactUnsupportedDeclaration !Location
+ | ExactUnsupportedDeclarationBody !Location
+ | ExactNonCanonicalSetDefinitionAnnotation !Location
+ | ExactGuardedTransparentDefinition !Location
+ | ExactGuardedOpaqueSignature !Location
+ | ExactDefinitionCombinedSymbolicAlias !Location
+ | ExactRelationalReplacementRequiresNamedDefinition !Location
+ | ExactDeclarationOccurrenceMissing !Location
+ | ExactDeclarationOccurrenceAmbiguous !Location
+ | ExactDeclarationHeadMismatch !Location
+ | ExactFixedSemanticCollision !Location !SemanticGlobalKey
+ | ExactGlobalAlreadyVisible !Location !SemanticGlobalKey
+ | ExactGlobalNotVisible !Location !SemanticGlobalKey
+ | ExactDuplicateParameter !Location !Raw.VarSymbol
+ | ExactDuplicateLocalBinder !Location !Raw.VarSymbol
+ | ExactDuplicateLocalIdentity !Location !ExactLocalId
+ | ExactFreeVariable !Location !Raw.VarSymbol
+ | ExactApplicationExpectedFunction !Location !CoreType
+ | ExactApplicationArgumentMismatch
+ !Location !CoreType !CoreType
+ | ExactExpressionExpectedSet !Location !CoreType
+ | ExactFormulaExpectedProposition !Location !CoreType
+ | ExactCoreCheckFailed !Location !CoreCheckError
+ | ExactObjectTypeMismatch !Location !CoreType !CoreType
+ | ExactUnsupportedHeaderAssumption !Location
+ | ExactQuantifiedTermRequiresPropositionContext !Location
+ | ExactStructureNotVisible !Location !SemanticStructurePhrase
+ | ExactBaseStructureNotAssertable !Location !SemanticStructurePhrase
+ | ExactDuplicateStructureAnnotation !Location !Raw.VarSymbol
+ | ExactStructureOperationNotAvailable !Location !Raw.StructSymbol
+ | ExactStructureOperationAmbiguous
+ !Location !Raw.StructSymbol ![ObjectId]
+ | ExactContextualExpansionNotAvailable
+ !Location !SemanticGlobalKey
+ | ExactContextualRequirementConflict
+ !Location !Raw.StructSymbol !ObjectId !ObjectId
+ | ExactStructureOccurrenceMismatch !Location
+ | ExactStructureSelfParent !Location !SemanticStructurePhrase
+ | ExactStructureDuplicateParent !Location !SemanticStructurePhrase
+ | ExactStructureAlreadyVisible !Location !SemanticStructurePhrase
+ | ExactStructureDuplicateOperation !Location !Raw.StructSymbol
+ | ExactStructureOperationAlreadyInherited !Location !Raw.StructSymbol
+ | ExactStructureOperationConflict
+ !Location !Raw.StructSymbol
+ !SemanticStructurePhrase !SemanticStructurePhrase
+ | ExactStructureHasNoCarrier !Location !SemanticStructurePhrase
+ | ExactStructureDescriptorInvalid !Location !SemanticEnvironmentError
+ | ExactStructureObjectNotVisible !Location !ObjectId
+ deriving stock (Show, Eq)
+
+exactCompileErrorLocation :: ExactCompileError -> Location
+exactCompileErrorLocation = \case
+ ExactUnsupportedDeclaration location -> location
+ ExactUnsupportedDeclarationBody location -> location
+ ExactNonCanonicalSetDefinitionAnnotation location -> location
+ ExactGuardedTransparentDefinition location -> location
+ ExactGuardedOpaqueSignature location -> location
+ ExactDefinitionCombinedSymbolicAlias location -> location
+ ExactRelationalReplacementRequiresNamedDefinition location -> location
+ ExactDeclarationOccurrenceMissing location -> location
+ ExactDeclarationOccurrenceAmbiguous location -> location
+ ExactDeclarationHeadMismatch location -> location
+ ExactFixedSemanticCollision location _key -> location
+ ExactGlobalAlreadyVisible location _key -> location
+ ExactGlobalNotVisible location _key -> location
+ ExactDuplicateParameter location _parameter -> location
+ ExactDuplicateLocalBinder location _variable -> location
+ ExactDuplicateLocalIdentity location _identity -> location
+ ExactFreeVariable location _variable -> location
+ ExactApplicationExpectedFunction location _actual -> location
+ ExactApplicationArgumentMismatch location _expected _actual -> location
+ ExactExpressionExpectedSet location _actual -> location
+ ExactFormulaExpectedProposition location _actual -> location
+ ExactCoreCheckFailed location _failure -> location
+ ExactObjectTypeMismatch location _expected _actual -> location
+ ExactUnsupportedHeaderAssumption location -> location
+ ExactQuantifiedTermRequiresPropositionContext location -> location
+ ExactStructureNotVisible location _phrase -> location
+ ExactBaseStructureNotAssertable location _phrase -> location
+ ExactDuplicateStructureAnnotation location _variable -> location
+ ExactStructureOperationNotAvailable location _symbol -> location
+ ExactStructureOperationAmbiguous location _symbol _objects -> location
+ ExactContextualExpansionNotAvailable location _key -> location
+ ExactContextualRequirementConflict location _symbol _first _second -> location
+ ExactStructureOccurrenceMismatch location -> location
+ ExactStructureSelfParent location _phrase -> location
+ ExactStructureDuplicateParent location _phrase -> location
+ ExactStructureAlreadyVisible location _phrase -> location
+ ExactStructureDuplicateOperation location _symbol -> location
+ ExactStructureOperationAlreadyInherited location _symbol -> location
+ ExactStructureOperationConflict location _symbol _first _second -> location
+ ExactStructureHasNoCarrier location _phrase -> location
+ ExactStructureDescriptorInvalid location _failure -> location
+ ExactStructureObjectNotVisible location _object -> location
+
+renderExactCompileError :: ExactCompileError -> Text
+renderExactCompileError = \case
+ ExactUnsupportedDeclaration location ->
+ at location <> "this declaration is not yet supported by the typed checker"
+ ExactUnsupportedDeclarationBody location ->
+ at location <> "this source form is not yet supported by exact elaboration"
+ ExactNonCanonicalSetDefinitionAnnotation location ->
+ at location
+ <> "only the unmodified built-in noun `set` is a harmless definition annotation; "
+ <> "state a total condition in the definiens, or, where a corresponding opaque signature form exists, use it with a following explicit axiom; otherwise migrate the spelling or leave it unsupported"
+ ExactGuardedTransparentDefinition location ->
+ at location
+ <> "a transparent definition cannot have a header assumption; "
+ <> "state a total condition in the definiens, or, where a corresponding opaque signature form exists, use it with a following explicit axiom; otherwise migrate the spelling or leave it unsupported"
+ ExactGuardedOpaqueSignature location ->
+ at location
+ <> "an opaque signature cannot have a header assumption; "
+ <> "state the condition in a following explicit axiom"
+ ExactDefinitionCombinedSymbolicAlias location ->
+ at location
+ <> "a functional definition cannot declare a symbolic equivalent at the same time; "
+ <> "define the symbolic operator first, then define the functional phrase as an abbreviation applying it"
+ ExactRelationalReplacementRequiresNamedDefinition location ->
+ at location
+ <> "relational replacement is supported only as the outer body of a named definition"
+ ExactDeclarationOccurrenceMissing location ->
+ at location <> "the declaration has no associated syntax occurrence"
+ ExactDeclarationOccurrenceAmbiguous location ->
+ at location <> "the declaration has more than one semantic head"
+ ExactDeclarationHeadMismatch location ->
+ at location <> "the parsed declaration head does not match its syntax occurrence"
+ ExactFixedSemanticCollision location key ->
+ at location <> "the declaration collides with fixed semantics for "
+ <> shown key
+ ExactGlobalAlreadyVisible location key ->
+ at location <> "the global " <> shown key <> " is already declared"
+ ExactGlobalNotVisible location key ->
+ at location <> "the global " <> shown key <> " is not visible"
+ ExactDuplicateParameter location parameter ->
+ at location <> "the declaration parameter " <> shown parameter <> " is repeated"
+ ExactDuplicateLocalBinder location variable ->
+ at location <> "the proof binder " <> shown variable <> " is already active"
+ ExactDuplicateLocalIdentity location identity ->
+ at location <> "the proof-local identity " <> shown identity <> " is already active"
+ ExactFreeVariable location variable ->
+ at location <> "the exact source form contains the free variable " <> shown variable
+ ExactApplicationExpectedFunction location actual ->
+ at location <> "an application expected a function, but found " <> shown actual
+ ExactApplicationArgumentMismatch location expected actual ->
+ at location <> "an application expected " <> shown expected
+ <> ", but found " <> shown actual
+ ExactExpressionExpectedSet location actual ->
+ at location <> "an expression has type " <> shown actual <> " instead of Set"
+ ExactFormulaExpectedProposition location actual ->
+ at location <> "a formula has type " <> shown actual <> " instead of Prop"
+ ExactCoreCheckFailed location failure ->
+ at location <> "the checked declaration core is invalid: " <> shown failure
+ ExactObjectTypeMismatch location expected actual ->
+ at location <> "the declaration object has type " <> shown actual
+ <> " instead of " <> shown expected
+ ExactUnsupportedHeaderAssumption location ->
+ at location <> "this top-level header assumption is not yet supported by exact elaboration"
+ ExactQuantifiedTermRequiresPropositionContext location ->
+ at location
+ <> "a quantified term requires a containing proposition"
+ ExactStructureNotVisible location structurePhrase ->
+ at location <> "the structure " <> shown structurePhrase <> " is not visible"
+ ExactBaseStructureNotAssertable location structurePhrase ->
+ at location <> "the metadata-only structure " <> shown structurePhrase
+ <> " cannot be asserted"
+ ExactDuplicateStructureAnnotation location variable ->
+ at location <> "the structure binder " <> shown variable
+ <> " is annotated more than once"
+ ExactStructureOperationNotAvailable location symbol ->
+ at location <> "the structure operation " <> shown symbol
+ <> " is not available in the active structure scope"
+ ExactStructureOperationAmbiguous location symbol objects ->
+ at location <> "the structure operation " <> shown symbol
+ <> " is ambiguous between " <> shown objects
+ ExactContextualExpansionNotAvailable location key ->
+ at location <> "the contextual abbreviation " <> shown key
+ <> " has no compatible active structure"
+ ExactContextualRequirementConflict location symbol firstObject secondObject ->
+ at location <> "the contextual abbreviation requires incompatible "
+ <> shown symbol <> " operations " <> shown firstObject
+ <> " and " <> shown secondObject
+ ExactStructureOccurrenceMismatch location ->
+ at location <> "the structure syntax occurrences do not match the declaration"
+ ExactStructureSelfParent location structurePhrase ->
+ at location <> "the structure " <> shown structurePhrase
+ <> " cannot inherit from itself"
+ ExactStructureDuplicateParent location structurePhrase ->
+ at location <> "the parent structure " <> shown structurePhrase
+ <> " is repeated"
+ ExactStructureAlreadyVisible location structurePhrase ->
+ at location <> "the structure " <> shown structurePhrase
+ <> " is already declared"
+ ExactStructureDuplicateOperation location symbol ->
+ at location <> "the structure operation " <> shown symbol
+ <> " is repeated"
+ ExactStructureOperationAlreadyInherited location symbol ->
+ at location <> "the structure operation " <> shown symbol
+ <> " is already inherited"
+ ExactStructureOperationConflict location symbol firstOrigin secondOrigin ->
+ at location <> "the inherited structure operation " <> shown symbol
+ <> " conflicts between " <> shown firstOrigin
+ <> " and " <> shown secondOrigin
+ ExactStructureHasNoCarrier location structurePhrase ->
+ at location <> "the structure " <> shown structurePhrase
+ <> " does not inherit the base carrier operation"
+ ExactStructureDescriptorInvalid location _failure ->
+ at location <> "the canonical structure descriptor is inconsistent"
+ ExactStructureObjectNotVisible location identity ->
+ at location <> "the structure fact mentions unavailable object "
+ <> shown identity
+ where
+ at location = locationToText location <> ": "
+ shown :: Show value => value -> Text
+ shown = Text.pack . show
+
+data ElaborationState = ElaborationState
+ { elaborationBinders :: !(Map.Map Raw.VarSymbol Natural)
+ -- Counts every active de Bruijn binder, including anonymous and
+ -- contextual binders which have no entry in 'elaborationBinders'.
+ , elaborationBinderDepth :: !Natural
+ , elaborationStructures :: !(Map.Map Natural ExactStructureAnnotation)
+ , elaborationGlobals :: !(Map.Map ObjectId CoreType)
+ , elaborationContextualBinder :: !(Maybe Natural)
+ , elaborationContextualRequirements
+ :: !(Map.Map Raw.StructSymbol ObjectId)
+ }
+
+type Elaborate =
+ StateT
+ ElaborationState
+ (ExceptT ExactCompileError (Declaration.LoweringDriver))
+
+data PreparedHead = PreparedHead
+ !SemanticGlobalKey
+ ![Raw.VarSymbol]
+ !CoreType
+
+data PreparedBody
+ = OpaqueBody
+ | TransparentBody
+ !(CanonicalTerm ObjectId)
+ !(Maybe PreparedExactSetConstruction)
+ | ContextualTransparentBody
+ !(Map.Map Raw.StructSymbol ObjectId)
+ !(CanonicalTerm ObjectId)
+
+data CompiledBody = CompiledBody
+ !(CanonicalTerm ObjectId)
+ !(Maybe CompiledNamedSetConstruction)
+
+data CompiledNamedSetConstruction
+ = CompiledSeparationConstruction
+ !(CanonicalTerm ObjectId)
+ !(CanonicalTerm ObjectId)
+ | CompiledFunctionalReplacementConstruction
+ !(NonEmpty (CanonicalTerm ObjectId))
+ !(CanonicalTerm ObjectId)
+ !(Maybe (CanonicalTerm ObjectId))
+ | CompiledRelationalReplacementConstruction
+ !(CanonicalTerm ObjectId)
+ !(CanonicalTerm ObjectId)
+
+prepareExactProposition
+ :: ExactBinderContext
+ -> Raw.Stmt
+ -> Declaration.LoweringDriver
+ (Either ExactCompileError PreparedExactProposition)
+prepareExactProposition context statement =
+ prepareExactPropositionTerm
+ context
+ (locate statement)
+ (compileStatement statement)
+
+-- | Compile the source bound of already-opened symbolic binders. This is the
+-- shared checked constraint seam used by quantified statements and proof
+-- binders, so relation signs, carrier casts, and global occurrences are
+-- elaborated exactly once by the ordinary expression compiler.
+prepareExactSymbolicBoundConstraints
+ :: ExactBinderContext
+ -> NonEmpty Raw.VarSymbol
+ -> Raw.Bound
+ -> Declaration.LoweringDriver
+ (Either ExactCompileError PreparedExactProposition)
+prepareExactSymbolicBoundConstraints context variables bound =
+ prepareExactPropositionTerm
+ context
+ (case bound of
+ Raw.Unbounded -> locate (NonEmpty.head variables)
+ _ -> locate bound)
+ (logicalConjunction
+ <$> compileSymbolicBoundConstraintList variables bound)
+
+-- | Compile the opened body used by a symbolic existential witness. Its
+-- grouping is deliberately identical to 'SymbolicExists': all bound
+-- constraints form the existential restriction and the stated proposition is
+-- its body.
+prepareExactSymbolicWitnessConstraints
+ :: ExactBinderContext
+ -> NonEmpty Raw.VarSymbol
+ -> Raw.Bound
+ -> Raw.Stmt
+ -> Declaration.LoweringDriver
+ (Either ExactCompileError PreparedExactProposition)
+prepareExactSymbolicWitnessConstraints context variables bound statement =
+ prepareExactPropositionTerm context (locate statement) do
+ constraints <-
+ logicalConjunction
+ <$> compileSymbolicBoundConstraintList variables bound
+ body <- compileStatement statement
+ pure
+ (if constraints == logicalTruth
+ then body
+ else logicalAnd constraints body)
+
+-- | Compile the checked constraint of an already-opened noun witness. Named
+-- binders are resolved normally; a nameless singular noun uses the nearest
+-- anonymous binder and therefore introduces no lookup spelling.
+prepareExactNounWitnessConstraints
+ :: ExactBinderContext
+ -> Raw.NounPhrase []
+ -> Declaration.LoweringDriver
+ (Either ExactCompileError PreparedExactProposition)
+prepareExactNounWitnessConstraints context nounPhrase =
+ case nounPhrase of
+ Raw.NounPhrase left noun variables right suchThat ->
+ prepareExactPropositionTerm context (locate noun) do
+ subjects <-
+ case NonEmpty.nonEmpty variables of
+ Just binders ->
+ toList
+ <$> traverse compileIntroducedVariable binders
+ Nothing ->
+ pure [CBound 0]
+ compileNounPhraseConstraints
+ subjects left noun right suchThat
+
+prepareExactPropositionTerm
+ :: ExactBinderContext
+ -> Location
+ -> Elaborate (CanonicalTerm ObjectId)
+ -> Declaration.LoweringDriver
+ (Either ExactCompileError PreparedExactProposition)
+prepareExactPropositionTerm context location compile =
+ Except.runExceptT do
+ let initialElaboration = initialElaborationState context
+ (term, finalElaboration) <-
+ State.runStateT compile initialElaboration
+ checked <-
+ either
+ (Except.throwError . ExactCoreCheckFailed location)
+ pure
+ (checkScopedCanonicalCore
+ (`Map.lookup` elaborationGlobals finalElaboration)
+ (binderTypes context)
+ term)
+ unless (scopedCoreType checked == TyProp)
+ (Except.throwError
+ (ExactFormulaExpectedProposition
+ location
+ (scopedCoreType checked)))
+ pure (PreparedExactProposition checked)
+
+prepareExactSetExpression
+ :: ExactBinderContext
+ -> Raw.Expr
+ -> Declaration.LoweringDriver
+ (Either ExactCompileError PreparedExactSetExpression)
+prepareExactSetExpression context expression =
+ Except.runExceptT do
+ let initialElaboration = initialElaborationState context
+ (compiled, finalElaboration) <-
+ State.runStateT
+ (compileNamedSetExpression expression)
+ initialElaboration
+ let CompiledBody term rawConstruction = compiled
+ checked <-
+ either
+ (Except.throwError
+ . ExactCoreCheckFailed (locate expression))
+ pure
+ (checkScopedCanonicalCore
+ (`Map.lookup` elaborationGlobals finalElaboration)
+ (binderTypes context)
+ term)
+ unless (scopedCoreType checked == TySet)
+ (Except.throwError
+ (ExactExpressionExpectedSet
+ (locate expression)
+ (scopedCoreType checked)))
+ construction <-
+ Except.liftEither
+ (traverse
+ (checkCompiledNamedSetConstruction
+ (`Map.lookup` elaborationGlobals finalElaboration)
+ (binderTypes context))
+ rawConstruction)
+ traverse_
+ (\checkedConstruction ->
+ unless
+ (preparedSetConstructionTerm checkedConstruction == checked)
+ (impossible
+ "exact named construction disagrees with its checked expression"))
+ construction
+ pure (PreparedExactSetExpression checked construction)
+
+checkCompiledNamedSetConstruction
+ :: (ObjectId -> Maybe CoreType)
+ -> [CoreType]
+ -> CompiledNamedSetConstruction
+ -> Either ExactCompileError PreparedExactSetConstruction
+checkCompiledNamedSetConstruction globalType context = \case
+ CompiledSeparationConstruction bound predicate -> do
+ checkedBound <- checkAt context TySet bound
+ checkedPredicate <- checkAt (TySet : context) TyProp predicate
+ maybe
+ (Left
+ (ExactCoreCheckFailed
+ Nowhere
+ (ExpectedCoreType TySet TyProp)))
+ (Right . PreparedUnconditionalSetConstruction)
+ (checkedSeparationConstruction
+ globalType checkedBound checkedPredicate)
+ CompiledFunctionalReplacementConstruction domains value condition -> do
+ let domainList = NonEmpty.toList domains
+ fullContext = replicate (length domainList) TySet <> context
+ checkedDomains <-
+ traverse
+ (\(depth, domain) ->
+ checkAt
+ (replicate depth TySet <> context)
+ TySet
+ domain)
+ (zip [0..] domainList)
+ checkedValue <- checkAt fullContext TySet value
+ checkedCondition <- traverse (checkAt fullContext TyProp) condition
+ maybe
+ (Left
+ (ExactCoreCheckFailed
+ Nowhere
+ (ExpectedCoreType TySet TyProp)))
+ (Right . PreparedUnconditionalSetConstruction)
+ (checkedFunctionalReplacementConstruction
+ globalType
+ (NonEmpty.fromList checkedDomains)
+ checkedValue
+ checkedCondition)
+ CompiledRelationalReplacementConstruction domain relation -> do
+ checkedDomain <- checkAt context TySet domain
+ checkedRelation <- checkAt (TySet : TySet : context) TyProp relation
+ maybe
+ (Left
+ (ExactCoreCheckFailed
+ Nowhere
+ (ExpectedCoreType TySet TyProp)))
+ (Right . PreparedRelationalSetConstruction)
+ (checkedRelationalReplacementConstruction
+ globalType checkedDomain checkedRelation)
+ where
+ checkAt expectedContext expectedType term = do
+ checked <-
+ first
+ (ExactCoreCheckFailed Nowhere)
+ (checkScopedCanonicalCore globalType expectedContext term)
+ unless
+ (scopedCoreType checked == expectedType)
+ (Left
+ (ExactCoreCheckFailed
+ Nowhere
+ (ExpectedCoreType
+ expectedType
+ (scopedCoreType checked))))
+ pure checked
+
+preparedSetConstructionTerm
+ :: PreparedExactSetConstruction
+ -> ScopedCheckedCore ObjectId
+preparedSetConstructionTerm = \case
+ PreparedUnconditionalSetConstruction construction ->
+ namedSetConstructionTerm construction
+ PreparedRelationalSetConstruction construction ->
+ relationalSetConstructionTerm construction
+
+preparedSetConstructionClosedBody
+ :: PreparedExactSetConstruction
+ -> FrozenCheckedCore ObjectId
+preparedSetConstructionClosedBody = \case
+ PreparedUnconditionalSetConstruction construction ->
+ namedSetConstructionClosedBody construction
+ PreparedRelationalSetConstruction construction ->
+ relationalSetConstructionClosedBody construction
+
+prepareExactLocalFunctionGraph
+ :: Location
+ -> ExactBinderContext
+ -> ExactBinderContext
+ -> Raw.Expr
+ -> Raw.Expr
+ -> Declaration.LoweringDriver
+ (Either ExactCompileError PreparedExactLocalFunctionGraph)
+prepareExactLocalFunctionGraph
+ location context argumentContext domainExpression valueExpression =
+ Except.runExceptT do
+ domain <-
+ preparedExactSetExpressionCore
+ <$> ( Except.lift
+ (prepareExactSetExpression context domainExpression)
+ >>= Except.liftEither
+ )
+ value <-
+ preparedExactSetExpressionCore
+ <$> ( Except.lift
+ (prepareExactSetExpression
+ argumentContext valueExpression)
+ >>= Except.liftEither
+ )
+ pair <- prepareOrderedPair
+ case scopedReplacementGraph pair domain value of
+ Just (graph, checkedDomain, function) ->
+ pure
+ (PreparedExactLocalFunctionGraph
+ graph checkedDomain function)
+ Nothing ->
+ impossible
+ "checked local-function components did not form a replacement graph"
+ where
+ prepareOrderedPair = do
+ let initialElaboration = initialElaborationState context
+ key =
+ SemanticExpressionFunction
+ (Raw.mixfixPattern Raw.PairSymbol)
+ expected = TySet `TyArrow` (TySet `TyArrow` TySet)
+ ((term, actual), finalElaboration) <-
+ State.runStateT
+ (applyResolvedTyped location key [])
+ initialElaboration
+ unless (actual == expected)
+ (Except.throwError
+ (ExactObjectTypeMismatch location expected actual))
+ either
+ (Except.throwError . ExactCoreCheckFailed location)
+ pure
+ (checkScopedCanonicalCore
+ (`Map.lookup` elaborationGlobals finalElaboration)
+ (binderTypes context)
+ term)
+
+prepareExactClaimEnvelope
+ :: [Raw.Asm]
+ -> Raw.Stmt
+ -> Declaration.LoweringDriver
+ (Either ExactCompileError PreparedExactClaimEnvelope)
+prepareExactClaimEnvelope assumptions statement =
+ discover [] emptyExactBinderContext
+ where
+ discover variables context = do
+ attempted <- prepareExactClaimAttempt context assumptions statement
+ case attempted of
+ Left (ExactFreeVariable _location variable)
+ | variable `elem` variables ->
+ impossible
+ "exact claim discovery repeated an active free variable"
+ | otherwise ->
+ case extendExactBinderContext
+ ( ( exactLocalId
+ (fromIntegral (length variables))
+ , variable
+ ) :| []
+ )
+ context of
+ Left failure ->
+ pure (Left failure)
+ Right extended ->
+ discover (variables <> [variable]) extended
+ Left failure ->
+ pure (Left failure)
+ Right (target, antecedentCount, structures) ->
+ pure
+ (Right
+ (PreparedExactClaimEnvelope
+ target
+ variables
+ (annotateBinderContext structures context)
+ antecedentCount))
+
+prepareExactClaimAttempt
+ :: ExactBinderContext
+ -> [Raw.Asm]
+ -> Raw.Stmt
+ -> Declaration.LoweringDriver
+ (Either
+ ExactCompileError
+ ( ScopedCheckedCore ObjectId
+ , Natural
+ , Map.Map Natural ExactStructureAnnotation
+ ))
+prepareExactClaimAttempt context assumptions statement =
+ Except.runExceptT do
+ let initialElaboration = initialElaborationState context
+ ((antecedents, conclusion), finalElaboration) <-
+ State.runStateT
+ ( do
+ antecedents <-
+ concat <$> traverse compileHeaderAssumption assumptions
+ conclusion <- compileStatement statement
+ pure (antecedents, conclusion)
+ )
+ initialElaboration
+ checkedAntecedents <-
+ traverse
+ (uncurry
+ (checkEnvelopeProposition
+ finalElaboration
+ context))
+ antecedents
+ checkedConclusion <-
+ checkEnvelopeProposition
+ finalElaboration
+ context
+ (locate statement)
+ conclusion
+ let implication =
+ foldr
+ (\antecedent continuation ->
+ fromMaybe
+ (impossible
+ "checked claim antecedents have unequal contexts")
+ (implyScopedCore antecedent continuation))
+ checkedConclusion
+ checkedAntecedents
+ closed = closeClaimBinders implication
+ unless (null (scopedCoreContext closed))
+ (impossible "exact claim closure retained a binder")
+ pure
+ ( closed
+ , fromIntegral (length antecedents)
+ , elaborationStructures finalElaboration
+ )
+
+checkEnvelopeProposition
+ :: ElaborationState
+ -> ExactBinderContext
+ -> Location
+ -> CanonicalTerm ObjectId
+ -> ExceptT
+ ExactCompileError
+ (Declaration.LoweringDriver)
+ (ScopedCheckedCore ObjectId)
+checkEnvelopeProposition elaboration context location term = do
+ checked <-
+ either
+ (Except.throwError . ExactCoreCheckFailed location)
+ pure
+ (checkScopedCanonicalCore
+ (`Map.lookup` elaborationGlobals elaboration)
+ (binderTypes context)
+ term)
+ unless (scopedCoreType checked == TyProp)
+ (Except.throwError
+ (ExactFormulaExpectedProposition
+ location
+ (scopedCoreType checked)))
+ pure checked
+
+closeClaimBinders
+ :: ScopedCheckedCore global
+ -> ScopedCheckedCore global
+closeClaimBinders scoped =
+ case scopedCoreContext scoped of
+ [] -> scoped
+ _binder : _remaining ->
+ closeClaimBinders
+ (fromMaybe
+ (impossible
+ "a checked claim binder could not be closed")
+ (closeScopedForall scoped))
+
+binderIndices :: ExactBinderContext -> Map.Map Raw.VarSymbol Natural
+binderIndices (ExactBinderContext binders) =
+ Map.fromList
+ [ (variable, fromIntegral index)
+ | (index, ExactBinder _identity (Just variable) _coreType _structure) <-
+ zip [0 :: Int ..] binders
+ ]
+
+binderStructures
+ :: ExactBinderContext
+ -> Map.Map Natural ExactStructureAnnotation
+binderStructures (ExactBinderContext binders) =
+ Map.fromList
+ [ (fromIntegral index, structure)
+ | (index, ExactBinder _identity _variable _coreType (Just structure)) <-
+ zip [0 :: Int ..] binders
+ ]
+
+binderTypes :: ExactBinderContext -> [CoreType]
+binderTypes (ExactBinderContext binders) =
+ [ coreType
+ | ExactBinder _identity _variable coreType _structure <- binders
+ ]
+
+initialElaborationState :: ExactBinderContext -> ElaborationState
+initialElaborationState context =
+ ElaborationState
+ { elaborationBinders = binderIndices context
+ , elaborationBinderDepth =
+ fromIntegral (length (binderTypes context))
+ , elaborationStructures = binderStructures context
+ , elaborationGlobals = mempty
+ , elaborationContextualBinder = Nothing
+ , elaborationContextualRequirements = mempty
+ }
+
+annotateBinderContext
+ :: Map.Map Natural ExactStructureAnnotation
+ -> ExactBinderContext
+ -> ExactBinderContext
+annotateBinderContext structures (ExactBinderContext binders) =
+ ExactBinderContext
+ [ ExactBinder identity variable coreType
+ (Map.lookup (fromIntegral index) structures)
+ | (index, ExactBinder identity variable coreType _old) <-
+ zip [0 :: Int ..] binders
+ ]
+
+compileHeaderAssumption
+ :: Raw.Asm
+ -> Elaborate [(Location, CanonicalTerm ObjectId)]
+compileHeaderAssumption = \case
+ Raw.AsmSuppose statement -> do
+ proposition <- compileStatement statement
+ pure [(locate statement, proposition)]
+ Raw.AsmLetNoun variables nounPhrase
+ | exactSetNounPhrase nounPhrase -> do
+ traverse_ compileIntroducedVariable variables
+ pure []
+ | otherwise -> do
+ subjects <- traverse compileIntroducedVariable variables
+ constraints <-
+ traverse (`compileNounPhraseMaybe` nounPhrase) subjects
+ pure
+ [ (locate variable, constraint)
+ | (variable, constraint) <-
+ zip (toList variables) (toList constraints)
+ ]
+ Raw.AsmLetIn variables domain -> do
+ variableTerms <- traverse compileIntroducedVariable variables
+ domainTerm <- compileExpressionAsSet domain
+ traverse
+ (\(variable, variableTerm) -> do
+ proposition <-
+ compileMembership
+ (locate domain)
+ Raw.Positive
+ variableTerm
+ domainTerm
+ pure (locate variable, proposition))
+ (zip (toList variables) (toList variableTerms))
+ Raw.AsmLetEq variable expression -> do
+ variableTerm <- compileIntroducedVariable variable
+ expressionTerm <- compileExpressionAsSet expression
+ pure
+ [ ( locate variable
+ , CEq TySet variableTerm expressionTerm
+ )
+ ]
+ Raw.AsmLetThe variable _function ->
+ Except.throwError
+ (ExactUnsupportedHeaderAssumption (locate variable))
+ Raw.AsmLetStruct variable structure -> do
+ subject <- compileIntroducedVariable variable
+ annotation <-
+ resolveStructureAnnotation
+ (locate variable)
+ structure
+ index <-
+ maybe
+ (impossible "an introduced structure variable is unbound")
+ pure
+ =<< Map.lookup variable <$> State.gets elaborationBinders
+ existing <- State.gets (Map.lookup index . elaborationStructures)
+ when
+ (isJust existing)
+ (Except.throwError
+ (ExactDuplicateStructureAnnotation
+ (locate variable) variable))
+ State.modify' \state ->
+ state
+ { elaborationStructures =
+ Map.insert index annotation
+ (elaborationStructures state)
+ }
+ predicate <-
+ maybe
+ (impossible "an assertable structure has no predicate")
+ pure
+ (structureAnnotationPredicate annotation)
+ recordExactGlobal
+ predicate
+ (TyArrow TySet TyProp)
+ pure
+ [ ( locate variable
+ , CApp
+ (CGlobal predicate)
+ subject
+ )
+ ]
+
+compileIntroducedVariable
+ :: Raw.VarSymbol
+ -> Elaborate (CanonicalTerm ObjectId)
+compileIntroducedVariable variable =
+ compileExpressionAsSet (Raw.ExprVar variable)
+
+resolveStructureAnnotation
+ :: Location
+ -> Raw.StructPhrase
+ -> Elaborate ExactStructureAnnotation
+resolveStructureAnnotation location rawPhrase = do
+ let structurePhrase = semanticStructurePhrase rawPhrase
+ resolved <-
+ State.lift
+ (Except.lift
+ (Declaration.resolveVisibleStructureLowering structurePhrase))
+ structure <-
+ maybe
+ (Except.throwError
+ (ExactStructureNotVisible location structurePhrase))
+ pure
+ resolved
+ predicate <-
+ maybe
+ (Except.throwError
+ (ExactBaseStructureNotAssertable location structurePhrase))
+ pure
+ (Declaration.resolvedStructurePredicate structure)
+ pure
+ (ExactStructureAnnotation
+ structurePhrase
+ (Just predicate)
+ (Declaration.resolvedStructureOperations structure))
+
+structureAnnotationPredicate :: ExactStructureAnnotation -> Maybe ObjectId
+structureAnnotationPredicate
+ (ExactStructureAnnotation _ predicate _operations) =
+ predicate
+
+structureAnnotationOperation
+ :: Raw.StructSymbol
+ -> ExactStructureAnnotation
+ -> Maybe ObjectId
+structureAnnotationOperation symbol
+ (ExactStructureAnnotation _phrase _predicate operations) =
+ Map.lookup symbol operations
+
+recordExactGlobal :: ObjectId -> CoreType -> Elaborate ()
+recordExactGlobal identity coreType = do
+ existing <- State.gets (Map.lookup identity . elaborationGlobals)
+ case existing of
+ Nothing ->
+ State.modify' \state ->
+ state
+ { elaborationGlobals =
+ Map.insert identity coreType
+ (elaborationGlobals state)
+ }
+ Just actual
+ | actual == coreType -> pure ()
+ | otherwise ->
+ impossible "one exact global acquired two checked types"
+
+prepareExactSourceAxiom
+ :: Raw.Block
+ -> Declaration.LoweringDriver
+ (Either ExactCompileError PreparedExactSourceAxiom)
+prepareExactSourceAxiom = \case
+ Raw.BlockAxiom
+ location _title (Raw.Marker marker)
+ (Raw.Axiom assumptions statement) -> do
+ prepared <- prepareExactClaimEnvelope assumptions statement
+ pure do
+ envelope <- prepared
+ let core = preparedExactClaimTarget envelope
+ alias = semanticName marker
+ unless (null (scopedCoreContext core))
+ (Left (ExactUnsupportedDeclarationBody location))
+ pure
+ (PreparedExactSourceAxiom
+ location
+ alias
+ core
+ (declarationSyntaxId
+ (encodePreparedSourceAxiom core alias)))
+ block ->
+ pure (Left (ExactUnsupportedDeclaration (locate block)))
+
+lowerPreparedExactSourceAxiom
+ :: PreparedExactSourceAxiom
+ -> Declaration.LoweringDriver
+ (Either
+ Declaration.DeclarationError
+ (Declaration.CheckedDeclaration ()))
+lowerPreparedExactSourceAxiom
+ (PreparedExactSourceAxiom _location alias target syntax) =
+ fmap
+ (\spec ->
+ Declaration.checkedCompiledDeclaration
+ syntax [] [] [] []
+ [ Declaration.checkedCandidate
+ spec
+ Declaration.checkedSourceAxiomPlanning
+ :| []
+ ]
+ ())
+ <$> Declaration.prepareCandidateSpecLowering
+ [] target SearchEligible [alias]
+
+authorizeCheckedExactSourceAxiom
+ :: ()
+ -> [NonEmpty Declaration.ReservedCandidate]
+ -> Declaration.Declaration ()
+authorizeCheckedExactSourceAxiom () = \case
+ [candidate :| []] ->
+ Declaration.authorizeSourceAxiomCandidate candidate
+ stages ->
+ Declaration.failDeclaration
+ (Declaration.CheckedAuthorizationCandidateShapeMismatch
+ 1 (length stages))
+
+prepareExactDeclaration
+ :: Raw.Block
+ -> [CanonicalLexicalEntry]
+ -> Declaration.LoweringDriver
+ (Either ExactCompileError PreparedExactDeclaration)
+prepareExactDeclaration block entries =
+ Except.runExceptT do
+ entry <-
+ case entries of
+ [] -> Except.throwError
+ (ExactDeclarationOccurrenceMissing (locate block))
+ [single] -> pure single
+ _ -> Except.throwError
+ (ExactDeclarationOccurrenceAmbiguous (locate block))
+ key <-
+ maybe
+ (Except.throwError
+ (ExactUnsupportedDeclaration (locate block)))
+ pure
+ (semanticGlobalKeyFromLexicalEntry entry)
+ when
+ (isJust (fixedSemanticMeaning key))
+ (Except.throwError
+ (ExactFixedSemanticCollision (locate block) key))
+ visible <- Except.lift
+ (Declaration.resolveVisibleGlobalLowering key)
+ when
+ (isJust visible)
+ (Except.throwError
+ (ExactGlobalAlreadyVisible (locate block) key))
+ (head', family, rawBody) <-
+ prepareHead block key
+ slot <- Except.lift Declaration.nextDeclarationSlotLowering
+ theory <- Except.lift Declaration.currentTheoryLowering
+ (body, globals) <-
+ case rawBody of
+ Nothing -> pure (OpaqueBody, Map.empty)
+ Just buildBody -> do
+ let initialElaboration =
+ ElaborationState
+ { elaborationBinders = mempty
+ , elaborationBinderDepth = 0
+ , elaborationStructures = mempty
+ , elaborationGlobals = mempty
+ , elaborationContextualBinder = Nothing
+ , elaborationContextualRequirements = mempty
+ }
+ (CompiledBody canonical rawConstruction, finalElaboration) <-
+ State.runStateT buildBody initialElaboration
+ let PreparedHead _semanticKey parameters _coreType = head'
+ construction <-
+ Except.liftEither
+ (traverse
+ (checkCompiledNamedSetConstruction
+ (`Map.lookup`
+ elaborationGlobals finalElaboration)
+ (replicate (length parameters) TySet))
+ rawConstruction)
+ traverse_
+ (\checkedConstruction ->
+ unless
+ (frozenCoreTerm
+ (preparedSetConstructionClosedBody
+ checkedConstruction)
+ == canonical)
+ (impossible
+ "exact named construction disagrees with its transparent body"))
+ construction
+ let requirements =
+ elaborationContextualRequirements finalElaboration
+ body
+ | Map.null requirements =
+ TransparentBody canonical construction
+ | family == ExactAbbreviation =
+ ContextualTransparentBody
+ requirements
+ (CLam TySet canonical)
+ | otherwise =
+ impossible
+ "a non-abbreviation acquired contextual requirements"
+ pure (body, elaborationGlobals finalElaboration)
+ let PreparedHead semanticKey _parameters coreType = head'
+ unless (semanticKey == key)
+ (Except.throwError
+ (ExactDeclarationHeadMismatch (locate block)))
+ (target, content) <-
+ case body of
+ OpaqueBody -> do
+ let seed =
+ opaqueDeclarationSeed
+ (declarationSlotModule slot)
+ (declarationSlotOrdinal slot)
+ SignatureDeclaration
+ (generatedObjectSlot 0)
+ content' =
+ OpaqueObjectContent theory seed coreType
+ identity = opaqueObjectId theory seed coreType
+ pure (GlobalReference identity, content')
+ TransparentBody canonical _construction -> do
+ checked <-
+ either
+ (Except.throwError
+ . ExactCoreCheckFailed (locate block))
+ pure
+ (checkCanonicalCore
+ (`Map.lookup` globals)
+ canonical)
+ unless
+ (frozenCoreType checked == coreType)
+ (Except.throwError
+ (ExactObjectTypeMismatch
+ (locate block)
+ coreType
+ (frozenCoreType checked)))
+ let content' =
+ TransparentObjectContent
+ theory
+ coreType
+ canonical
+ let identity =
+ transparentObjectId theory coreType canonical
+ semanticTarget =
+ case family of
+ ExactAbbreviation ->
+ TransparentExpansion identity
+ ExactDefinition -> GlobalReference identity
+ ExactSignature ->
+ impossible
+ "a signature acquired a transparent body"
+ pure (semanticTarget, content')
+ ContextualTransparentBody requirements canonical -> do
+ let contextualType = TyArrow TySet coreType
+ checked <-
+ either
+ (Except.throwError
+ . ExactCoreCheckFailed (locate block))
+ pure
+ (checkCanonicalCore
+ (`Map.lookup` globals)
+ canonical)
+ unless
+ (frozenCoreType checked == contextualType)
+ (Except.throwError
+ (ExactObjectTypeMismatch
+ (locate block)
+ contextualType
+ (frozenCoreType checked)))
+ let content' =
+ TransparentObjectContent
+ theory
+ contextualType
+ canonical
+ identity =
+ transparentObjectId
+ theory contextualType canonical
+ pure
+ ( ContextualTransparentExpansion
+ identity requirements
+ , content'
+ )
+ let targetObject = semanticGlobalTargetObject target
+ available <-
+ Except.lift (Declaration.objectAvailableLowering targetObject)
+ let alias = definitionAlias block
+ asserted
+ | available = Nothing
+ | otherwise = Just (assertedObject targetObject content)
+ syntax =
+ declarationSyntaxId
+ (encodePreparedSyntax family head' body alias)
+ pure
+ (PreparedExactDeclaration
+ (locate block)
+ family
+ key
+ target
+ asserted
+ alias
+ (case family of
+ ExactDefinition -> case body of
+ TransparentBody _canonical construction -> construction
+ _ -> Nothing
+ _ -> Nothing)
+ syntax)
+
+lowerPreparedExactBinding
+ :: PreparedExactDeclaration
+ -> Declaration.LoweringDriver
+ (Either
+ Declaration.DeclarationError
+ (Declaration.CheckedDeclaration CheckedExactBindingAuthorization))
+lowerPreparedExactBinding prepared =
+ case preparedDefinitionAlias prepared of
+ Nothing ->
+ pure
+ (Right
+ (checked [] CheckedExactBindingNone))
+ Just alias -> case preparedDefinitionConstruction prepared of
+ Nothing ->
+ fmap
+ (\spec ->
+ checked
+ [ Declaration.checkedCandidate
+ spec
+ (Declaration.checkedDefinitionEquationPlanning
+ identity)
+ :| []
+ ]
+ (CheckedExactBindingDefinition identity))
+ <$> Declaration.prepareDefinitionEquationSpecLowering
+ objects identity alias
+ Just (PreparedUnconditionalSetConstruction construction) ->
+ Except.runExceptT do
+ equation <-
+ Except.lift
+ (Declaration.prepareDefinitionEquationSpecWithEligibilityLowering
+ objects identity SearchIneligible alias)
+ >>= Except.liftEither
+ (extensional, descriptor) <-
+ Except.lift
+ (Declaration.prepareNamedSetConstructionSpecLowering
+ objects identity construction)
+ >>= Except.liftEither
+ pure
+ (checked
+ [ Declaration.checkedCandidate
+ equation
+ (Declaration.checkedDefinitionEquationPlanning
+ identity)
+ :| [ Declaration.checkedCandidate
+ extensional
+ (Declaration.checkedKernelPlanning
+ descriptor [])
+ ]
+ ]
+ (CheckedExactBindingConstruction
+ identity construction))
+ Just (PreparedRelationalSetConstruction construction) ->
+ Except.runExceptT do
+ equation <-
+ Except.lift
+ (Declaration.prepareDefinitionEquationSpecWithEligibilityLowering
+ objects identity SearchIneligible alias)
+ >>= Except.liftEither
+ let functionality =
+ relationalSetConstructionClosedFunctionality
+ construction
+ functionalityScoped =
+ embedClosedCore [] functionality
+ functionalitySpec <-
+ Except.lift
+ (Declaration.prepareFrozenCandidateSpecLowering
+ objects functionality SearchIneligible [])
+ >>= Except.liftEither
+ obligation <-
+ Except.lift
+ (Declaration.prepareScopedVampireObligationLowering
+ Vector.empty
+ functionalityScoped
+ []
+ []
+ Declaration.VampireImplicitPremises)
+ >>= either
+ (Except.throwError
+ . Declaration.ProofObligationFailedAt location
+ . Declaration.CurrentCandidateVampirePreparationFailed)
+ pure
+ (extensional, descriptor) <-
+ Except.lift
+ (Declaration.prepareRelationalSetConstructionSpecLowering
+ objects identity construction functionality)
+ >>= Except.liftEither
+ pure
+ (checked
+ [ Declaration.checkedCandidate
+ equation
+ (Declaration.checkedDefinitionEquationPlanning
+ identity)
+ :| [ Declaration.checkedCandidate
+ functionalitySpec
+ (Declaration.checkedSourceProofPlanning
+ [Declaration.checkedPlannedVampireRequest
+ location obligation]
+ [])
+ ]
+ , Declaration.checkedCandidate
+ extensional
+ (Declaration.checkedStagedKernelPlanning
+ descriptor
+ [Declaration.plannedEarlierCandidate 0 1])
+ :| []
+ ]
+ (CheckedExactBindingRelationalConstruction
+ identity construction obligation))
+ where
+ identity = preparedExactObjectId prepared
+ objects = maybeToList (preparedExactObject prepared)
+ location = preparedExactLocation prepared
+ checked stages body =
+ Declaration.checkedCompiledDeclaration
+ (preparedExactSyntaxId prepared)
+ objects
+ []
+ [semanticGlobalBinding
+ (preparedExactGlobalKey prepared)
+ (preparedExactGlobalTarget prepared)]
+ []
+ stages
+ body
+
+data CheckedExactBindingAuthorization
+ = CheckedExactBindingNone
+ | CheckedExactBindingDefinition !ObjectId
+ | CheckedExactBindingConstruction
+ !ObjectId
+ !(NamedSetConstruction ObjectId)
+ | CheckedExactBindingRelationalConstruction
+ !ObjectId
+ !(CheckedRelationalSetConstruction ObjectId)
+ !(Declaration.PreparedVampireObligation Void ())
+
+authorizeCheckedExactBinding
+ :: CheckedExactBindingAuthorization
+ -> [NonEmpty Declaration.ReservedCandidate]
+ -> Declaration.Declaration ()
+authorizeCheckedExactBinding body stages =
+ case (body, stages) of
+ (CheckedExactBindingNone, []) -> pure ()
+ (CheckedExactBindingDefinition identity, [candidate :| []]) ->
+ Declaration.authorizeDefinitionEquationCandidate
+ identity candidate
+ ( CheckedExactBindingConstruction identity construction
+ , [equation :| [extensional]]
+ ) -> do
+ Declaration.authorizeDefinitionEquationCandidate
+ identity equation
+ Declaration.authorizeNamedSetConstructionCandidate
+ identity construction extensional
+ ( CheckedExactBindingRelationalConstruction
+ identity construction obligation
+ , [equation :| [functionality], extensional :| []]
+ ) -> do
+ Declaration.authorizeDefinitionEquationCandidate
+ identity equation
+ Declaration.authorizeVampireCandidate
+ functionality
+ (Declaration.acceptPreparedVampireObligation obligation)
+ Declaration.authorizeRelationalSetConstructionCandidate
+ identity construction functionality extensional
+ _ ->
+ Declaration.failDeclaration
+ (Declaration.CheckedAuthorizationCandidateShapeMismatch
+ (case body of
+ CheckedExactBindingNone -> 0
+ CheckedExactBindingDefinition{} -> 1
+ CheckedExactBindingConstruction{} -> 1
+ CheckedExactBindingRelationalConstruction{} -> 2)
+ (length stages))
+
+prepareExactStructure
+ :: Raw.Block
+ -> [CanonicalLexicalEntry]
+ -> Declaration.LoweringDriver
+ (Either ExactCompileError PreparedExactStructure)
+prepareExactStructure block entries =
+ Except.runExceptT do
+ (location, marker, structure) <-
+ case block of
+ Raw.BlockStruct location _title (Raw.Marker marker) structure ->
+ pure (location, marker, structure)
+ _ -> Except.throwError
+ (ExactUnsupportedDeclaration (locate block))
+ validateStructureOccurrences location structure entries
+ let structurePhrase =
+ semanticStructurePhrase (Raw.structPhrase structure)
+ parentPhrases =
+ semanticStructurePhrase <$> Raw.structParents structure
+ when
+ (structurePhrase `elem` parentPhrases)
+ (Except.throwError
+ (ExactStructureSelfParent location structurePhrase))
+ case firstDuplicate parentPhrases of
+ Just duplicate ->
+ Except.throwError
+ (ExactStructureDuplicateParent location duplicate)
+ Nothing -> pure ()
+ visible <- Except.lift
+ (Declaration.resolveVisibleStructureLowering structurePhrase)
+ when
+ (isJust visible)
+ (Except.throwError
+ (ExactStructureAlreadyVisible location structurePhrase))
+ parents <- traverse (resolveParent location) parentPhrases
+ inherited <-
+ foldM mergeParentOperations Map.empty
+ (zip parentPhrases parents)
+ case firstDuplicate (Raw.structFixes structure) of
+ Just duplicate ->
+ Except.throwError
+ (ExactStructureDuplicateOperation location duplicate)
+ Nothing -> pure ()
+ traverse_
+ (\symbol ->
+ when
+ (Map.member symbol inherited)
+ (Except.throwError
+ (ExactStructureOperationAlreadyInherited
+ location symbol)))
+ (Raw.structFixes structure)
+ slot <- Except.lift Declaration.nextDeclarationSlotLowering
+ theory <- Except.lift Declaration.currentTheoryLowering
+ let operationType = TyArrow TySet TySet
+ makeOperation index symbol =
+ let seed =
+ opaqueDeclarationSeed
+ (declarationSlotModule slot)
+ (declarationSlotOrdinal slot)
+ StructureDeclaration
+ (generatedObjectSlot index)
+ content = OpaqueObjectContent theory seed operationType
+ identity = opaqueObjectId theory seed operationType
+ in ( symbol
+ , identity
+ , assertedObject identity content
+ )
+ ownOperations =
+ zipWith makeOperation [0 ..] (Raw.structFixes structure)
+ operationObjects =
+ [ asserted
+ | (_symbol, _identity, asserted) <- ownOperations
+ ]
+ completeOperations =
+ Map.union
+ (Map.fromList
+ [ (symbol, identity)
+ | (symbol, identity, _asserted) <- ownOperations
+ ])
+ (fst <$> inherited)
+ unless
+ (Map.member Raw.CarrierSymbol completeOperations)
+ (Except.throwError
+ (ExactStructureHasNoCarrier location structurePhrase))
+ context <-
+ either Except.throwError pure
+ (extendExactBinderContext
+ ((exactLocalId 0, Raw.structLabel structure) :| [])
+ emptyExactBinderContext)
+ let provisionalAnnotation =
+ ExactStructureAnnotation
+ structurePhrase Nothing completeOperations
+ structureContext =
+ annotateBinderContext
+ (Map.singleton 0 provisionalAnnotation)
+ context
+ checkedAssumptions <-
+ traverse
+ (\(assumptionMarker, assumption) -> do
+ prepared <- Except.lift
+ (prepareExactProposition structureContext assumption)
+ proposition <- Except.liftEither prepared
+ pure
+ ( locate assumption
+ , assumptionMarker
+ , preparedExactPropositionCore proposition
+ ))
+ (Raw.structAssumes structure)
+ parentTerms <-
+ fmap catMaybes
+ (traverse
+ (\parent ->
+ case Declaration.resolvedStructurePredicate parent of
+ Nothing -> pure Nothing
+ Just predicate ->
+ pure
+ (Just
+ (CApp
+ (CGlobal predicate)
+ (CBound 0))))
+ parents)
+ let assumptionTerms =
+ [ scopedCoreTerm proposition
+ | (_assumptionLocation, _assumptionMarker, proposition) <-
+ checkedAssumptions
+ ]
+ predicateBody =
+ CLam TySet
+ (logicalConjunction
+ (parentTerms <> assumptionTerms))
+ predicateType = TyArrow TySet TyProp
+ predicateContent =
+ TransparentObjectContent theory predicateType predicateBody
+ predicate =
+ transparentObjectId theory predicateType predicateBody
+ predicateAvailable <-
+ Except.lift (Declaration.objectAvailableLowering predicate)
+ let predicateObject =
+ [ assertedObject predicate predicateContent
+ | not predicateAvailable
+ ]
+ ownBindings =
+ [ semanticStructureOperation symbol identity
+ | (symbol, identity, _asserted) <- ownOperations
+ ]
+ descriptor <-
+ Except.liftEither
+ (first
+ (ExactStructureDescriptorInvalid location)
+ (semanticStructureDescriptor
+ structurePhrase
+ (Just predicate)
+ parentPhrases
+ ownBindings))
+ let structureApplication =
+ CApp (CGlobal predicate) (CBound 0)
+ inheritance =
+ [ ( location
+ , semanticName (marker <> "inherit")
+ , CForall TySet
+ (CImp structureApplication
+ (logicalConjunction parentTerms))
+ )
+ | not (null parentTerms)
+ ]
+ projections =
+ [ ( assumptionLocation
+ , semanticName assumptionMarker
+ , CForall TySet
+ (CImp structureApplication
+ (scopedCoreTerm proposition))
+ )
+ | ( assumptionLocation
+ , Raw.Marker assumptionMarker
+ , proposition
+ ) <- checkedAssumptions
+ ]
+ generatedTerms = inheritance <> projections
+ localTypes =
+ Map.fromList
+ ((predicate, predicateType)
+ : [ (identity, operationType)
+ | (_symbol, identity, _asserted) <- ownOperations
+ ])
+ resolvedTypes <-
+ resolveStructureGlobalTypes
+ localTypes
+ [ term
+ | (_factLocation, _alias, term) <- generatedTerms
+ ]
+ generated <-
+ traverse
+ (\(factLocation, alias, term) -> do
+ frozen <-
+ either
+ (Except.throwError
+ . ExactCoreCheckFailed factLocation)
+ pure
+ (checkCanonicalCore
+ (`Map.lookup` resolvedTypes)
+ term)
+ pure
+ (PreparedExactStructureFact
+ factLocation frozen alias))
+ generatedTerms
+ environment <-
+ Except.liftEither
+ (first
+ (ExactStructureDescriptorInvalid location)
+ (semanticEnvironmentWithStructures [] [descriptor]))
+ let syntax =
+ declarationSyntaxId
+ (encodePreparedStructure
+ environment
+ predicate
+ generated)
+ pure
+ (PreparedExactStructure
+ location
+ (operationObjects <> predicateObject)
+ predicate
+ descriptor
+ (semanticName marker)
+ generated
+ syntax)
+ where
+ resolveParent location structurePhrase = do
+ resolved <- Except.lift
+ (Declaration.resolveVisibleStructureLowering structurePhrase)
+ maybe
+ (Except.throwError
+ (ExactStructureNotVisible location structurePhrase))
+ pure
+ resolved
+
+ mergeParentOperations inherited (parentPhrase, parent) =
+ foldM
+ (insertParentOperation parentPhrase)
+ inherited
+ (Map.toAscList
+ (Declaration.resolvedStructureOperations parent))
+
+ insertParentOperation parentPhrase inherited (symbol, identity) =
+ case Map.lookup symbol inherited of
+ Nothing ->
+ pure
+ (Map.insert symbol (identity, parentPhrase) inherited)
+ Just (existing, existingOrigin)
+ | existing == identity -> pure inherited
+ | otherwise ->
+ Except.throwError
+ (ExactStructureOperationConflict
+ (locate block)
+ symbol
+ existingOrigin
+ parentPhrase)
+
+ resolveStructureGlobalTypes localTypes terms = do
+ let dependencies = Set.unions (canonicalTermGlobals <$> terms)
+ foldM
+ (\types identity ->
+ case Map.lookup identity types of
+ Just{} -> pure types
+ Nothing -> do
+ coreType <- Except.lift
+ (Declaration.objectTypeLowering identity)
+ case coreType of
+ Nothing ->
+ Except.throwError
+ (ExactStructureObjectNotVisible
+ (locate block) identity)
+ Just actual ->
+ pure (Map.insert identity actual types))
+ localTypes
+ (Set.toAscList dependencies)
+
+lowerPreparedExactStructure
+ :: PreparedExactStructure
+ -> Declaration.LoweringDriver
+ (Either
+ Declaration.DeclarationError
+ (Declaration.CheckedDeclaration
+ CheckedExactStructureAuthorization))
+lowerPreparedExactStructure
+ (PreparedExactStructure
+ _location objects predicate descriptor alias generatedFacts syntax) =
+ Except.runExceptT do
+ definition <-
+ Except.lift
+ (Declaration.preparePointwiseDefinitionEquationSpecLowering
+ objects predicate alias)
+ >>= Except.liftEither
+ generatedCandidates <-
+ traverse
+ (\(PreparedExactStructureFact
+ factLocation target factAlias) -> do
+ generatedSpec <- Except.lift
+ (Declaration.prepareFrozenCandidateSpecLowering
+ objects target SearchEligible [factAlias])
+ >>= Except.liftEither
+ obligation <- Except.lift
+ (Declaration.prepareStagedCandidateVampireLowering
+ factLocation objects definition generatedSpec)
+ >>= Except.liftEither
+ pure
+ ( Declaration.checkedCandidate generatedSpec
+ (Declaration.checkedSourceProofPlanning
+ [ Declaration.checkedPlannedVampireRequest
+ factLocation obligation
+ ]
+ [ Declaration.plannedEarlierCandidate 0 0
+ ])
+ , (factLocation, obligation)
+ ))
+ generatedFacts
+ let generatedAuthorizations =
+ snd <$> generatedCandidates
+ stages =
+ [ Declaration.checkedCandidate definition
+ (Declaration.checkedDefinitionEquationPlanning predicate)
+ :| []
+ ]
+ <> maybeToList
+ (NonEmpty.nonEmpty
+ (fst <$> generatedCandidates))
+ body =
+ CheckedExactStructureAuthorization
+ predicate
+ generatedAuthorizations
+ pure
+ (Declaration.checkedCompiledDeclaration
+ syntax objects [] [] [descriptor] stages
+ body)
+
+authorizeCheckedExactStructure
+ :: CheckedExactStructureAuthorization
+ -> [NonEmpty Declaration.ReservedCandidate]
+ -> Declaration.Declaration ()
+authorizeCheckedExactStructure
+ (CheckedExactStructureAuthorization predicate obligations)
+ stages =
+ case (obligations, stages) of
+ ([], [definition :| []]) ->
+ Declaration.authorizeDefinitionEquationCandidate
+ predicate definition
+ (_, [definition :| [], generatedCandidates])
+ | length obligations == NonEmpty.length generatedCandidates -> do
+ Declaration.authorizeDefinitionEquationCandidate
+ predicate definition
+ Declaration.authorizeVampireCandidateBatch
+ (NonEmpty.zipWith
+ (\candidate (factLocation, obligation) ->
+ ( factLocation
+ , candidate
+ , do
+ void
+ (Declaration.useStagedCandidate
+ definition)
+ pure obligation
+ ))
+ generatedCandidates
+ (NonEmpty.fromList obligations))
+ _ ->
+ Declaration.failDeclaration
+ (Declaration.CheckedAuthorizationCandidateShapeMismatch
+ (if null obligations then 1 else 2)
+ (length stages))
+
+validateStructureOccurrences
+ :: Location
+ -> Raw.StructDefn
+ -> [CanonicalLexicalEntry]
+ -> ExceptT ExactCompileError (Declaration.LoweringDriver) ()
+validateStructureOccurrences location structure entries = do
+ let Raw.LexicalItemSgPl forms structureMarker =
+ Raw.structPhrase structure
+ expected =
+ CanonicalStructureNoun
+ (Raw.sg forms)
+ (Raw.pl forms)
+ structureMarker
+ : [ CanonicalStructureOperation command
+ | Raw.StructSymbol command <- Raw.structFixes structure
+ ]
+ unless
+ (entries == expected)
+ (Except.throwError
+ (ExactStructureOccurrenceMismatch location))
+
+encodePreparedStructure
+ :: SemanticEnvironmentDelta
+ -> ObjectId
+ -> [PreparedExactStructureFact]
+ -> ByteString
+encodePreparedStructure environment predicate generated =
+ encodeCache do
+ putCacheTag 0x04
+ putSemanticEnvironmentDeltaCache environment
+ putObjectIdCache predicate
+ putCacheList
+ (\(PreparedExactStructureFact _location target alias) -> do
+ putCanonicalTermCache putObjectIdCache
+ (frozenCoreTerm target)
+ putCacheText (semanticNameText alias))
+ generated
+
+prepareHead
+ :: Raw.Block
+ -> SemanticGlobalKey
+ -> ExceptT
+ ExactCompileError
+ (Declaration.LoweringDriver)
+ ( PreparedHead
+ , ExactDeclarationFamily
+ , Maybe (Elaborate CompiledBody)
+ )
+prepareHead block key =
+ case block of
+ Raw.BlockSig location _title _marker assumptions signature -> do
+ rejectHeaderAssumptions ExactGuardedOpaqueSignature assumptions
+ head' <- prepareSignature location key signature
+ pure (head', ExactSignature, Nothing)
+ Raw.BlockAbbr location _title _marker abbreviation -> do
+ (head', buildBody) <-
+ prepareAbbreviation location key abbreviation
+ pure (head', ExactAbbreviation, Just buildBody)
+ Raw.BlockDefn location _title _marker definition -> do
+ (head', buildBody) <-
+ prepareDefinition location key definition
+ pure (head', ExactDefinition, Just buildBody)
+ _ ->
+ Except.throwError (ExactUnsupportedDeclaration (locate block))
+
+prepareSignature
+ :: Location
+ -> SemanticGlobalKey
+ -> Raw.Signature
+ -> ExceptT
+ ExactCompileError
+ (Declaration.LoweringDriver)
+ PreparedHead
+prepareSignature location key = \case
+ Raw.SignatureAdj subject (Raw.Adj _ item arguments) -> do
+ ensureAdjectiveKey location item key
+ makePreparedHead
+ location key (subject : arguments) TyProp
+ Raw.SignatureSymbolic (Raw.SymbolPattern symbol parameters) nounPhrase -> do
+ unless
+ ( key
+ == SemanticExpressionFunction
+ (Raw.mixfixPattern symbol)
+ )
+ (Except.throwError (ExactDeclarationHeadMismatch location))
+ unless
+ (exactSetNounPhrase nounPhrase)
+ (Except.throwError (ExactUnsupportedDeclarationBody location))
+ makePreparedHead location key parameters TySet
+ _ ->
+ Except.throwError (ExactUnsupportedDeclaration location)
+
+prepareAbbreviation
+ :: Location
+ -> SemanticGlobalKey
+ -> Raw.Abbreviation
+ -> ExceptT
+ ExactCompileError
+ (Declaration.LoweringDriver)
+ ( PreparedHead
+ , Elaborate CompiledBody
+ )
+prepareAbbreviation location key = \case
+ Raw.AbbreviationEq (Raw.SymbolPattern symbol parameters) expression -> do
+ ensureExpressionKey location symbol key
+ makeContextualTransparentHead
+ location key parameters TySet
+ (ordinaryCompiledBody <$> compileExpressionAsSet expression)
+ Raw.AbbreviationFun (Raw.Fun _ item parameters) term -> do
+ ensureFunctionPhraseKey location item key
+ makeContextualTransparentHead
+ location key parameters TySet
+ (ordinaryCompiledBody <$> compileTermAsSet term)
+ Raw.AbbreviationAdj subject (Raw.Adj _ item arguments) statement -> do
+ ensureAdjectiveKey location item key
+ makeContextualTransparentHead
+ location key (subject : arguments) TyProp
+ (ordinaryCompiledBody <$> compileStatement statement)
+ Raw.AbbreviationVerb subject (Raw.Verb _ item arguments) statement -> do
+ ensureVerbKey location item key
+ makeContextualTransparentHead
+ location key (subject : arguments) TyProp
+ (ordinaryCompiledBody <$> compileStatement statement)
+ Raw.AbbreviationNoun subject (Raw.Noun _ item arguments) statement -> do
+ ensureNounKey location item key
+ makeContextualTransparentHead
+ location key (subject : arguments) TyProp
+ (ordinaryCompiledBody <$> compileStatement statement)
+ Raw.AbbreviationRel left relation parameters right statement -> do
+ ensureRelationKey location relation key
+ makeContextualTransparentHead
+ location key (parameters <> [left, right]) TyProp
+ (ordinaryCompiledBody <$> compileStatement statement)
+
+prepareDefinition
+ :: Location
+ -> SemanticGlobalKey
+ -> Raw.Defn
+ -> ExceptT
+ ExactCompileError
+ (Declaration.LoweringDriver)
+ ( PreparedHead
+ , Elaborate CompiledBody
+ )
+prepareDefinition location key = \case
+ Raw.Defn assumptions head' statement -> do
+ rejectHeaderAssumptions ExactGuardedTransparentDefinition assumptions
+ (parameters, resultType) <-
+ definitionHead location key head'
+ makeTransparentHead
+ location key parameters resultType
+ (ordinaryCompiledBody <$> compileStatement statement)
+ Raw.DefnFun assumptions (Raw.Fun _ item parameters) symbolic term -> do
+ rejectHeaderAssumptions ExactGuardedTransparentDefinition assumptions
+ traverse_
+ (Except.throwError
+ . ExactDefinitionCombinedSymbolicAlias
+ . locate)
+ symbolic
+ ensureFunctionPhraseKey location item key
+ makeTransparentHead
+ location key parameters TySet
+ (compileNamedSetTerm term)
+ Raw.DefnOp (Raw.SymbolPattern symbol parameters) expression -> do
+ ensureExpressionKey location symbol key
+ makeTransparentHead
+ location key parameters TySet
+ (compileNamedSetExpression expression)
+
+definitionHead
+ :: Location
+ -> SemanticGlobalKey
+ -> Raw.DefnHead
+ -> ExceptT
+ ExactCompileError
+ (Declaration.LoweringDriver)
+ ([Raw.VarSymbol], CoreType)
+definitionHead location key = \case
+ Raw.DefnAdj annotation subject (Raw.Adj _ item arguments) -> do
+ validateDefinitionAnnotation annotation
+ ensureAdjectiveKey location item key
+ pure (subject : arguments, TyProp)
+ Raw.DefnVerb annotation subject (Raw.Verb _ item arguments) -> do
+ validateDefinitionAnnotation annotation
+ ensureVerbKey location item key
+ pure (subject : arguments, TyProp)
+ Raw.DefnNoun subject (Raw.Noun _ item arguments) -> do
+ ensureNounKey location item key
+ pure (subject : arguments, TyProp)
+ Raw.DefnRel left relation parameters right -> do
+ ensureRelationKey location relation key
+ pure (parameters <> [left, right], TyProp)
+ Raw.DefnSymbolicPredicate
+ (Raw.PrefixPredicate command arity)
+ _marker
+ parameters -> do
+ unless
+ ( key
+ == SemanticPrefixPredicate
+ command
+ (fromIntegral arity)
+ )
+ (Except.throwError (ExactDeclarationHeadMismatch location))
+ pure (toList parameters, TyProp)
+
+validateDefinitionAnnotation
+ :: MonadError ExactCompileError monad
+ => Maybe (Raw.NounPhrase Maybe)
+ -> monad ()
+validateDefinitionAnnotation = traverse_ \nounPhrase ->
+ unless (exactSetNounPhrase nounPhrase)
+ (throwError
+ (ExactNonCanonicalSetDefinitionAnnotation
+ (exactNounPhraseLocation nounPhrase)))
+
+rejectHeaderAssumptions
+ :: MonadError ExactCompileError monad
+ => (Location -> ExactCompileError)
+ -> [Raw.Asm]
+ -> monad ()
+rejectHeaderAssumptions makeError = \case
+ [] -> pure ()
+ assumption : _ ->
+ throwError (makeError (exactAssumptionLocation assumption))
+
+exactAssumptionLocation :: Raw.Asm -> Location
+exactAssumptionLocation = \case
+ Raw.AsmSuppose statement -> locate statement
+ Raw.AsmLetNoun variables _nounPhrase -> locate variables
+ Raw.AsmLetIn variables _expression -> locate variables
+ Raw.AsmLetThe variable _function -> locate variable
+ Raw.AsmLetEq variable _expression -> locate variable
+ Raw.AsmLetStruct variable _structure -> locate variable
+
+exactNounPhraseLocation :: Raw.NounPhraseOf t argument -> Location
+exactNounPhraseLocation
+ (Raw.NounPhrase _left noun _variables _right _suchThat) =
+ locate noun
+
+makeTransparentHead
+ :: Location
+ -> SemanticGlobalKey
+ -> [Raw.VarSymbol]
+ -> CoreType
+ -> Elaborate CompiledBody
+ -> ExceptT
+ ExactCompileError
+ (Declaration.LoweringDriver)
+ ( PreparedHead
+ , Elaborate CompiledBody
+ )
+makeTransparentHead location key parameters resultType body = do
+ (prepared, binders) <-
+ prepareParameters location key parameters resultType
+ let close = do
+ State.modify' \state ->
+ state
+ { elaborationBinders = binders
+ , elaborationBinderDepth =
+ fromIntegral (length parameters)
+ }
+ CompiledBody body' construction <- body
+ pure
+ (CompiledBody
+ (foldr (const (CLam TySet)) body' parameters)
+ construction)
+ pure (prepared, close)
+
+makeContextualTransparentHead
+ :: Location
+ -> SemanticGlobalKey
+ -> [Raw.VarSymbol]
+ -> CoreType
+ -> Elaborate CompiledBody
+ -> ExceptT
+ ExactCompileError
+ (Declaration.LoweringDriver)
+ ( PreparedHead
+ , Elaborate CompiledBody
+ )
+makeContextualTransparentHead location key parameters resultType body = do
+ (prepared, binders) <-
+ prepareParameters location key parameters resultType
+ let close = do
+ State.modify' \state ->
+ state
+ { elaborationBinders = binders
+ , elaborationBinderDepth =
+ fromIntegral (length parameters) + 1
+ , elaborationContextualBinder =
+ Just (fromIntegral (length parameters))
+ }
+ CompiledBody body' _construction <- body
+ pure
+ (CompiledBody
+ (foldr (const (CLam TySet)) body' parameters)
+ Nothing)
+ pure (prepared, close)
+
+makePreparedHead
+ :: Location
+ -> SemanticGlobalKey
+ -> [Raw.VarSymbol]
+ -> CoreType
+ -> ExceptT
+ ExactCompileError
+ (Declaration.LoweringDriver)
+ PreparedHead
+makePreparedHead location key parameters resultType = do
+ (prepared, _binders) <-
+ prepareParameters location key parameters resultType
+ pure prepared
+
+prepareParameters
+ :: Location
+ -> SemanticGlobalKey
+ -> [Raw.VarSymbol]
+ -> CoreType
+ -> ExceptT
+ ExactCompileError
+ (Declaration.LoweringDriver)
+ ( PreparedHead
+ , Map.Map Raw.VarSymbol Natural
+ )
+prepareParameters
+ location key parameters resultType = do
+ case firstDuplicate parameters of
+ Just duplicate ->
+ Except.throwError
+ (ExactDuplicateParameter location duplicate)
+ Nothing -> pure ()
+ let indices =
+ reverse (take (length parameters) [0 ..])
+ binders =
+ Map.fromList
+ (zip parameters indices)
+ coreType = foldr (const (TyArrow TySet)) resultType parameters
+ pure
+ ( PreparedHead key parameters coreType
+ , binders
+ )
+
+compileExpressionAsSet
+ :: Raw.Expr
+ -> Elaborate (CanonicalTerm ObjectId)
+compileExpressionAsSet expression = do
+ (term, actual) <- compileExpression expression
+ unless (actual == TySet)
+ (Except.throwError
+ (ExactExpressionExpectedSet (locate expression) actual))
+ pure term
+
+-- | Compile one set expression once while retaining the checked-source shape
+-- needed only when that expression is subsequently named by a definition.
+-- Nested constructions remain ordinary exact terms.
+compileNamedSetExpression
+ :: Raw.Expr
+ -> Elaborate CompiledBody
+compileNamedSetExpression = \case
+ Raw.ExprSep _location variable bound predicate -> do
+ (term, bound', predicate') <-
+ compileSeparation variable bound predicate
+ pure
+ (CompiledBody term
+ (Just
+ (CompiledSeparationConstruction
+ bound' predicate')))
+ Raw.ExprReplace _location value bounds condition -> do
+ replacement <-
+ compileFunctionalReplacement value bounds condition
+ pure
+ (CompiledBody
+ (compiledFunctionalReplacementTerm replacement)
+ (Just
+ (CompiledFunctionalReplacementConstruction
+ (compiledFunctionalReplacementDomains replacement)
+ (compiledFunctionalReplacementValue replacement)
+ (compiledFunctionalReplacementCondition replacement))))
+ Raw.ExprReplacePred _location range domainVariable bound predicate -> do
+ (term, domain, relation) <-
+ compileRelationalReplacement
+ range domainVariable bound predicate
+ pure
+ (CompiledBody term
+ (Just
+ (CompiledRelationalReplacementConstruction
+ domain relation)))
+ expression ->
+ (`CompiledBody` Nothing)
+ <$> compileExpressionAsSet expression
+
+compileNamedSetTerm :: Raw.Term -> Elaborate CompiledBody
+compileNamedSetTerm = \case
+ Raw.TermExpr expression -> compileNamedSetExpression expression
+ term -> ordinaryCompiledBody <$> compileTermAsSet term
+
+ordinaryCompiledBody :: CanonicalTerm ObjectId -> CompiledBody
+ordinaryCompiledBody term = CompiledBody term Nothing
+
+compileTermAsSet
+ :: Raw.Term
+ -> Elaborate (CanonicalTerm ObjectId)
+compileTermAsSet = \case
+ Raw.TermExpr expression ->
+ compileExpressionAsSet expression
+ Raw.TermFun (Raw.Fun location item arguments) -> do
+ let patterns = Raw.lexicalItemSgPlPattern item
+ key = SemanticFunctionPhrase (Raw.sg patterns) (Raw.pl patterns)
+ compiled <- traverse compileTermAsSet arguments
+ applyResolved location key compiled
+ Raw.TermQuantified _quantifier location _nounPhrase ->
+ Except.throwError
+ (ExactQuantifiedTermRequiresPropositionContext location)
+ term ->
+ Except.throwError
+ (ExactUnsupportedDeclarationBody (locate term))
+
+-- | Compile a source term only at a proposition consumer. Indefinite terms
+-- own the continuation, so their noun constraints and quantifier surround
+-- exactly the proposition which consumes the resulting set. Function-phrase
+-- arguments recurse through the same seam and therefore never masquerade as
+-- independently set-valued terms.
+compileTermInProposition
+ :: Raw.Term
+ -> (CanonicalTerm ObjectId
+ -> Elaborate (CanonicalTerm ObjectId))
+ -> Elaborate (CanonicalTerm ObjectId)
+compileTermInProposition term continuation =
+ case term of
+ Raw.TermExpr expression ->
+ compileExpressionAsSet expression >>= continuation
+ Raw.TermFun (Raw.Fun location item arguments) -> do
+ let patterns = Raw.lexicalItemSgPlPattern item
+ key =
+ SemanticFunctionPhrase
+ (Raw.sg patterns)
+ (Raw.pl patterns)
+ compileTermsInProposition arguments \compiled -> do
+ value <- applyResolved location key compiled
+ continuation value
+ Raw.TermQuantified quantifier _location nounPhrase ->
+ compileQuantifiedTermInProposition
+ quantifier nounPhrase continuation
+ Raw.TermIota location _variable _statement ->
+ Except.throwError (ExactUnsupportedDeclarationBody location)
+
+-- | Compile source-ordered proposition terms. The first source occurrence
+-- receives the outermost continuation and therefore the widest scope.
+compileTermsInProposition
+ :: [Raw.Term]
+ -> ([CanonicalTerm ObjectId]
+ -> Elaborate (CanonicalTerm ObjectId))
+ -> Elaborate (CanonicalTerm ObjectId)
+compileTermsInProposition terms continuation =
+ case terms of
+ [] -> continuation []
+ term : remaining ->
+ compileTermInProposition term \compiled -> do
+ compiledDepth <- State.gets elaborationBinderDepth
+ compileTermsInProposition remaining \rest -> do
+ compiled' <-
+ weakenElaboratedTermFrom compiledDepth compiled
+ continuation (compiled' : rest)
+
+weakenElaboratedTermFrom
+ :: Natural
+ -> CanonicalTerm ObjectId
+ -> Elaborate (CanonicalTerm ObjectId)
+weakenElaboratedTermFrom originalDepth term = do
+ currentDepth <- State.gets elaborationBinderDepth
+ when (currentDepth < originalDepth)
+ (impossible
+ "a proposition-term continuation escaped its binder scope")
+ pure
+ (shiftCanonical
+ (currentDepth - originalDepth)
+ 0
+ term)
+
+compileExpression
+ :: Raw.Expr
+ -> Elaborate (CanonicalTerm ObjectId, CoreType)
+compileExpression = \case
+ Raw.ExprVar variable -> do
+ binders <- State.gets elaborationBinders
+ case Map.lookup variable binders of
+ Just index ->
+ pure (CBound index, TySet)
+ Nothing ->
+ Except.throwError
+ (ExactFreeVariable (locate variable) variable)
+ Raw.ExprInteger _location integer ->
+ pure (COpaqueInteger (toInteger integer), TySet)
+ Raw.ExprOp location symbol arguments -> do
+ let key =
+ SemanticExpressionFunction
+ (Raw.mixfixPattern symbol)
+ compiled <- traverse compileExpression arguments
+ case fixedSemanticMeaning key of
+ Just (FixedIntrinsic intrinsic) ->
+ applyTyped
+ location
+ (CIntrinsic intrinsic)
+ (coreIntrinsicType intrinsic)
+ compiled
+ Just (FixedNegatedIntrinsic _intrinsic) ->
+ impossible
+ "expression key resolved to a negated intrinsic"
+ Just FixedEquality ->
+ impossible
+ "expression key resolved to fixed equality"
+ Just FixedDisequality ->
+ impossible
+ "expression key resolved to fixed disequality"
+ Nothing ->
+ applyResolvedTyped
+ location
+ key
+ compiled
+ Raw.ExprStructOp location symbol maybeArgument ->
+ compileStructureOperation location symbol maybeArgument
+ Raw.ExprFiniteSet _location elements -> do
+ compiled <- traverse compileExpressionAsSet elements
+ pure
+ ( foldr
+ canonicalSetInsert
+ (CIntrinsic Empty)
+ compiled
+ , TySet
+ )
+ Raw.ExprSep _location variable bound predicate -> do
+ (term, _bound, _predicate) <-
+ compileSeparation variable bound predicate
+ pure (term, TySet)
+ Raw.ExprReplace _location value bounds condition -> do
+ replacement <-
+ compileFunctionalReplacement value bounds condition
+ pure (compiledFunctionalReplacementTerm replacement, TySet)
+ Raw.ExprReplacePred location _value _variable _bound _predicate ->
+ Except.throwError
+ (ExactRelationalReplacementRequiresNamedDefinition location)
+
+compileStructureOperation
+ :: Location
+ -> Raw.StructSymbol
+ -> Maybe Raw.Expr
+ -> Elaborate (CanonicalTerm ObjectId, CoreType)
+compileStructureOperation location symbol maybeArgument = do
+ (argument, object) <-
+ case maybeArgument of
+ Just expression -> do
+ term <- compileExpressionAsSet expression
+ structures <- State.gets elaborationStructures
+ case termStructureAnnotation term structures of
+ Just annotation -> do
+ object <-
+ maybe
+ (Except.throwError
+ (ExactStructureOperationNotAvailable
+ location symbol))
+ pure
+ (structureAnnotationOperation
+ symbol annotation)
+ pure (term, object)
+ Nothing -> do
+ object <-
+ resolveUniqueStructureOperation location symbol
+ pure (term, object)
+ Nothing -> do
+ structures <- State.gets elaborationStructures
+ case
+ [ (CBound index, object)
+ | (index, structure) <- Map.toAscList structures
+ , Just object <-
+ [structureAnnotationOperation symbol structure]
+ ] of
+ firstMatch : _ -> pure firstMatch
+ [] -> do
+ contextual <- State.gets elaborationContextualBinder
+ case contextual of
+ Nothing ->
+ Except.throwError
+ (ExactStructureOperationNotAvailable
+ location symbol)
+ Just index -> do
+ object <-
+ resolveUniqueStructureOperation
+ location symbol
+ recordContextualRequirement
+ location symbol object
+ pure (CBound index, object)
+ recordExactGlobal object (TyArrow TySet TySet)
+ pure (CApp (CGlobal object) argument, TySet)
+ where
+ termStructureAnnotation term structures =
+ case term of
+ CBound index -> Map.lookup index structures
+ _ -> Nothing
+
+resolveUniqueStructureOperation
+ :: Location
+ -> Raw.StructSymbol
+ -> Elaborate ObjectId
+resolveUniqueStructureOperation location symbol = do
+ objects <-
+ State.lift
+ (Except.lift
+ (Declaration.resolveVisibleStructureOperationObjectsLowering
+ symbol))
+ case objects of
+ [] ->
+ Except.throwError
+ (ExactStructureOperationNotAvailable location symbol)
+ [object] -> pure object
+ _ ->
+ Except.throwError
+ (ExactStructureOperationAmbiguous location symbol objects)
+
+recordContextualRequirement
+ :: Location
+ -> Raw.StructSymbol
+ -> ObjectId
+ -> Elaborate ()
+recordContextualRequirement location symbol object = do
+ existing <-
+ State.gets
+ (Map.lookup symbol . elaborationContextualRequirements)
+ case existing of
+ Nothing ->
+ State.modify' \state ->
+ state
+ { elaborationContextualRequirements =
+ Map.insert symbol object
+ (elaborationContextualRequirements state)
+ }
+ Just actual
+ | actual == object -> pure ()
+ | otherwise ->
+ Except.throwError
+ (ExactContextualRequirementConflict
+ location symbol actual object)
+
+structureCarrierCast
+ :: Location
+ -> CanonicalTerm ObjectId
+ -> Elaborate (CanonicalTerm ObjectId)
+structureCarrierCast location term =
+ case term of
+ CBound index -> do
+ annotation <- State.gets (Map.lookup index . elaborationStructures)
+ case annotation of
+ Nothing -> pure term
+ Just structure -> do
+ carrier <-
+ maybe
+ (Except.throwError
+ (ExactStructureOperationNotAvailable
+ location Raw.CarrierSymbol))
+ pure
+ (structureAnnotationOperation
+ Raw.CarrierSymbol structure)
+ recordExactGlobal carrier (TyArrow TySet TySet)
+ pure (CApp (CGlobal carrier) term)
+ _ -> pure term
+
+compileMembership
+ :: Location
+ -> Raw.Sign
+ -> CanonicalTerm ObjectId
+ -> CanonicalTerm ObjectId
+ -> Elaborate (CanonicalTerm ObjectId)
+compileMembership location sign element set = do
+ checkedSet <- structureCarrierCast location set
+ let proposition =
+ CApp
+ (CApp (CIntrinsic Member) element)
+ checkedSet
+ pure case sign of
+ Raw.Positive -> proposition
+ Raw.Negative -> logicalNot proposition
+
+compileSeparation
+ :: Raw.VarSymbol
+ -> Raw.Expr
+ -> Raw.Stmt
+ -> Elaborate
+ ( CanonicalTerm ObjectId
+ , CanonicalTerm ObjectId
+ , CanonicalTerm ObjectId
+ )
+compileSeparation variable bound predicate = do
+ bound' <- compileExpressionAsSet bound
+ predicate' <-
+ withSetBinders (variable :| [])
+ (compileStatement predicate)
+ pure
+ ( CApp
+ (CApp (CIntrinsic Sep) bound')
+ (CLam TySet predicate')
+ , bound'
+ , predicate'
+ )
+
+compileRelationalReplacement
+ :: Raw.VarSymbol
+ -> Raw.VarSymbol
+ -> Raw.Expr
+ -> Raw.Stmt
+ -> Elaborate
+ ( CanonicalTerm ObjectId
+ , CanonicalTerm ObjectId
+ , CanonicalTerm ObjectId
+ )
+compileRelationalReplacement range domainVariable bound predicate = do
+ domain <- compileExpressionAsSet bound
+ relation <-
+ withSetBinders (domainVariable :| [range])
+ (compileStatement predicate)
+ let restrictedDomain =
+ CApp
+ (CApp (CIntrinsic Sep) domain)
+ (CLam TySet (logicalExists relation))
+ choiceFunction =
+ CLam TySet
+ (CApp (CIntrinsic SetChoose) (CLam TySet relation))
+ replacement =
+ CApp
+ (CApp (CIntrinsic Repl) restrictedDomain)
+ choiceFunction
+ pure (replacement, domain, relation)
+
+data CompiledFunctionalReplacement = CompiledFunctionalReplacement
+ !(CanonicalTerm ObjectId)
+ !(NonEmpty (CanonicalTerm ObjectId))
+ !(CanonicalTerm ObjectId)
+ !(Maybe (CanonicalTerm ObjectId))
+
+compiledFunctionalReplacementTerm
+ :: CompiledFunctionalReplacement
+ -> CanonicalTerm ObjectId
+compiledFunctionalReplacementTerm
+ (CompiledFunctionalReplacement term _domains _value _condition) =
+ term
+
+compiledFunctionalReplacementDomains
+ :: CompiledFunctionalReplacement
+ -> NonEmpty (CanonicalTerm ObjectId)
+compiledFunctionalReplacementDomains
+ (CompiledFunctionalReplacement _term domains _value _condition) =
+ domains
+
+compiledFunctionalReplacementValue
+ :: CompiledFunctionalReplacement
+ -> CanonicalTerm ObjectId
+compiledFunctionalReplacementValue
+ (CompiledFunctionalReplacement _term _domains value _condition) =
+ value
+
+compiledFunctionalReplacementCondition
+ :: CompiledFunctionalReplacement
+ -> Maybe (CanonicalTerm ObjectId)
+compiledFunctionalReplacementCondition
+ (CompiledFunctionalReplacement _term _domains _value condition) =
+ condition
+
+compileFunctionalReplacement
+ :: Raw.Expr
+ -> NonEmpty (Raw.VarSymbol, Raw.Expr)
+ -> Maybe Raw.Stmt
+ -> Elaborate CompiledFunctionalReplacement
+compileFunctionalReplacement
+ value ((variable, domain) :| remaining) condition = do
+ domain' <- compileExpressionAsSet domain
+ case remaining of
+ [] -> do
+ (value', condition') <-
+ withSetBinders (variable :| []) do
+ value' <- compileExpressionAsSet value
+ condition' <- traverse compileStatement condition
+ pure (value', condition')
+ let filteredDomain =
+ case condition' of
+ Nothing -> domain'
+ Just predicate ->
+ CApp
+ (CApp (CIntrinsic Sep) domain')
+ (CLam TySet predicate)
+ pure
+ (CompiledFunctionalReplacement
+ (CApp
+ (CApp (CIntrinsic Repl) filteredDomain)
+ (CLam TySet value'))
+ (domain' :| [])
+ value'
+ condition')
+ next : rest -> do
+ nested <-
+ withSetBinders (variable :| [])
+ (compileFunctionalReplacement
+ value (next :| rest) condition)
+ pure
+ (CompiledFunctionalReplacement
+ (CApp
+ (CIntrinsic FamilyUnion)
+ (CApp
+ (CApp (CIntrinsic Repl) domain')
+ (CLam TySet
+ (compiledFunctionalReplacementTerm nested))))
+ (domain'
+ NonEmpty.<|
+ compiledFunctionalReplacementDomains nested)
+ (compiledFunctionalReplacementValue nested)
+ (compiledFunctionalReplacementCondition nested))
+
+compileStatement
+ :: Raw.Stmt
+ -> Elaborate (CanonicalTerm ObjectId)
+compileStatement = \case
+ Raw.StmtFormula formula ->
+ compileFormula formula
+ Raw.StmtVerbPhrase terms verbPhrase ->
+ compileTermsInProposition (toList terms) \subjects ->
+ logicalConjunction
+ <$> traverse (`compileVerbPhrase` verbPhrase) subjects
+ Raw.StmtNoun terms nounPhrase ->
+ compileTermsInProposition (toList terms) \subjects ->
+ logicalConjunction
+ <$> traverse (`compileNounPhraseMaybe` nounPhrase) subjects
+ Raw.StmtExists _location nounPhrase ->
+ compileExistentialNounPhrase nounPhrase
+ Raw.StmtQuantPhrase
+ _location
+ (Raw.QuantPhrase quantifier nounPhrase)
+ statement ->
+ compileQuantifiedNounPhrase quantifier nounPhrase statement
+ Raw.StmtConnected connective location left right ->
+ compileConnective
+ (fromMaybe (locate left) location)
+ connective
+ compileStatement
+ left
+ right
+ Raw.StmtNeg _location statement ->
+ logicalNot <$> compileStatement statement
+ Raw.SymbolicQuantified
+ _location quantifier variables bound suchThat statement ->
+ compileSymbolicQuantified
+ quantifier variables bound suchThat (compileStatement statement)
+ Raw.StmtStruct term rawPhrase ->
+ compileTermInProposition term \subject -> do
+ annotation <-
+ resolveStructureAnnotation (locate term) rawPhrase
+ predicate <-
+ maybe
+ (impossible "an assertable structure has no predicate")
+ pure
+ (structureAnnotationPredicate annotation)
+ recordExactGlobal
+ predicate
+ (TyArrow TySet TyProp)
+ pure
+ (CApp
+ (CGlobal predicate)
+ subject)
+
+compileQuantifiedTermInProposition
+ :: Raw.Quantifier
+ -> Raw.NounPhrase Maybe
+ -> (CanonicalTerm ObjectId
+ -> Elaborate (CanonicalTerm ObjectId))
+ -> Elaborate (CanonicalTerm ObjectId)
+compileQuantifiedTermInProposition quantifier
+ (Raw.NounPhrase left noun named right suchThat)
+ compileBody =
+ case named of
+ Nothing ->
+ withAnonymousSetBinder compileFor
+ Just variable ->
+ withSetBinders (variable :| []) do
+ subject <- compileIntroducedVariable variable
+ compileFor subject
+ where
+ compileFor subject = do
+ constraints <-
+ compileNounPhraseConstraints
+ [subject] left noun right suchThat
+ body <- compileBody subject
+ pure (quantifyNounPhrase quantifier 1 constraints body)
+
+compileSymbolicQuantified
+ :: Raw.Quantifier
+ -> NonEmpty Raw.VarSymbol
+ -> Raw.Bound
+ -> Maybe Raw.Stmt
+ -> Elaborate (CanonicalTerm ObjectId)
+ -> Elaborate (CanonicalTerm ObjectId)
+compileSymbolicQuantified quantifier variables bound suchThat compileBody =
+ withSetBinders variables do
+ boundConstraints <-
+ compileSymbolicBoundConstraintList variables bound
+ suchThatConstraints <-
+ maybeToList <$> traverse compileStatement suchThat
+ body <- compileBody
+ pure
+ (quantifyNounPhrase
+ quantifier
+ (length (toList variables))
+ (logicalConjunction
+ (boundConstraints <> suchThatConstraints))
+ body)
+
+compileSymbolicBoundConstraintList
+ :: NonEmpty Raw.VarSymbol
+ -> Raw.Bound
+ -> Elaborate [CanonicalTerm ObjectId]
+compileSymbolicBoundConstraintList variables = \case
+ Raw.Unbounded ->
+ pure []
+ Raw.Bounded _location sign relation domain -> do
+ subjects <- traverse compileIntroducedVariable variables
+ domain' <- compileExpressionAsSet domain
+ traverse
+ (\subject -> do
+ proposition <-
+ compileAtomicRelationTerms subject relation domain'
+ pure case sign of
+ Raw.Positive -> proposition
+ Raw.Negative -> logicalNot proposition)
+ (toList subjects)
+
+compileAtomicRelationTerms
+ :: CanonicalTerm ObjectId
+ -> Raw.Relation
+ -> CanonicalTerm ObjectId
+ -> Elaborate (CanonicalTerm ObjectId)
+compileAtomicRelationTerms left relation right =
+ case relation of
+ Raw.Relation location symbol parameters -> do
+ let key =
+ SemanticRelation
+ (Raw.relationSymbolToken symbol)
+ (Raw.relationSymbolParameterArity symbol)
+ compiledParameters <- traverse compileExpressionAsSet parameters
+ case fixedSemanticMeaning key of
+ Just FixedEquality
+ | null parameters -> pure (CEq TySet left right)
+ Just FixedDisequality
+ | null parameters ->
+ pure (logicalNot (CEq TySet left right))
+ Just (FixedIntrinsic Member)
+ | null parameters ->
+ compileMembership location Raw.Positive left right
+ Just (FixedNegatedIntrinsic Member)
+ | null parameters ->
+ compileMembership location Raw.Negative left right
+ Just (FixedIntrinsic intrinsic) -> do
+ (term, actual) <-
+ applyTyped
+ location
+ (CIntrinsic intrinsic)
+ (coreIntrinsicType intrinsic)
+ ((\term -> (term, TySet))
+ <$> (compiledParameters <> [left, right]))
+ unless (actual == TyProp)
+ (Except.throwError
+ (ExactFormulaExpectedProposition location actual))
+ pure term
+ Just (FixedNegatedIntrinsic intrinsic) -> do
+ (term, actual) <-
+ applyTyped
+ location
+ (CIntrinsic intrinsic)
+ (coreIntrinsicType intrinsic)
+ ((\term -> (term, TySet))
+ <$> (compiledParameters <> [left, right]))
+ unless (actual == TyProp)
+ (Except.throwError
+ (ExactFormulaExpectedProposition location actual))
+ pure (logicalNot term)
+ _ -> do
+ (term, actual) <-
+ applyResolvedTyped
+ location key
+ ((\term -> (term, TySet))
+ <$> (compiledParameters <> [left, right]))
+ unless (actual == TyProp)
+ (Except.throwError
+ (ExactFormulaExpectedProposition location actual))
+ pure term
+ Raw.RelationExpr location expression ->
+ compileRelationExpression location expression left right
+
+compileVerbPhrase
+ :: CanonicalTerm ObjectId
+ -> Raw.VerbPhrase
+ -> Elaborate (CanonicalTerm ObjectId)
+compileVerbPhrase subject = \case
+ Raw.VPVerb verb ->
+ compileVerb subject verb
+ Raw.VPVerbNot verb ->
+ logicalNot <$> compileVerb subject verb
+ Raw.VPAdj adjectives ->
+ logicalConjunction
+ <$> traverse (compileAdjective subject) adjectives
+ Raw.VPAdjNot adjectives ->
+ logicalNot . logicalConjunction
+ <$> traverse (compileAdjective subject) adjectives
+
+compilePredicateArguments
+ :: CanonicalTerm ObjectId
+ -> [Raw.Term]
+ -> ( CanonicalTerm ObjectId
+ -> [CanonicalTerm ObjectId]
+ -> Elaborate (CanonicalTerm ObjectId)
+ )
+ -> Elaborate (CanonicalTerm ObjectId)
+compilePredicateArguments subject arguments continuation = do
+ subjectDepth <- State.gets elaborationBinderDepth
+ compileTermsInProposition arguments \compiled -> do
+ subject' <- weakenElaboratedTermFrom subjectDepth subject
+ continuation subject' compiled
+
+compileVerb
+ :: CanonicalTerm ObjectId
+ -> Raw.Verb
+ -> Elaborate (CanonicalTerm ObjectId)
+compileVerb subject (Raw.Verb location item arguments) = do
+ let patterns = Raw.lexicalItemSgPlPattern item
+ compilePredicateArguments subject arguments \subject' compiled ->
+ applyResolvedPredicate
+ location
+ (SemanticVerb (Raw.sg patterns) (Raw.pl patterns))
+ (subject' : compiled)
+
+compileAdjective
+ :: CanonicalTerm ObjectId
+ -> Raw.Adj
+ -> Elaborate (CanonicalTerm ObjectId)
+compileAdjective subject (Raw.Adj location item arguments) =
+ compilePredicateArguments subject arguments \subject' compiled ->
+ applyResolvedPredicateChoice
+ location
+ ( SemanticRightAdjective (Raw.lexicalItemPattern item)
+ :| [SemanticLeftAdjective (Raw.lexicalItemPattern item)]
+ )
+ (subject' : compiled)
+
+compileLeftAdjective
+ :: CanonicalTerm ObjectId
+ -> Raw.AdjL
+ -> Elaborate (CanonicalTerm ObjectId)
+compileLeftAdjective subject (Raw.AdjL location item arguments) =
+ compilePredicateArguments subject arguments \subject' compiled ->
+ applyResolvedPredicate
+ location
+ (SemanticLeftAdjective (Raw.lexicalItemPattern item))
+ (subject' : compiled)
+
+compileRightAttribute
+ :: CanonicalTerm ObjectId
+ -> Raw.AdjR
+ -> Elaborate (CanonicalTerm ObjectId)
+compileRightAttribute subject = \case
+ Raw.AdjR location item arguments ->
+ compilePredicateArguments subject arguments \subject' compiled ->
+ applyResolvedPredicate
+ location
+ (SemanticRightAdjective (Raw.lexicalItemPattern item))
+ (subject' : compiled)
+ Raw.AttrRThat verbPhrase ->
+ compileVerbPhrase subject verbPhrase
+
+compileNoun
+ :: CanonicalTerm ObjectId
+ -> Raw.Noun
+ -> Elaborate (CanonicalTerm ObjectId)
+compileNoun subject (Raw.Noun location item arguments)
+ | Lexicon.isBuiltinSetNoun item =
+ pure logicalTruth
+ | otherwise = do
+ let patterns = Raw.lexicalItemSgPlPattern item
+ key = SemanticNoun (Raw.sg patterns) (Raw.pl patterns)
+ compilePredicateArguments subject arguments \subject' compiled ->
+ case fixedSemanticMeaning key of
+ Just (FixedIntrinsic Member) ->
+ case compiled of
+ [set] ->
+ compileMembership
+ location Raw.Positive subject' set
+ _ ->
+ impossible
+ "the fixed element noun does not have one argument"
+ Just (FixedIntrinsic intrinsic) -> do
+ (term, actual) <-
+ applyTyped
+ location
+ (CIntrinsic intrinsic)
+ (coreIntrinsicType intrinsic)
+ ((\argument -> (argument, TySet))
+ <$> (subject' : compiled))
+ unless (actual == TyProp)
+ (Except.throwError
+ (ExactFormulaExpectedProposition location actual))
+ pure term
+ Just{} ->
+ impossible "a fixed noun is not a predicate intrinsic"
+ Nothing ->
+ applyResolvedPredicate
+ location key (subject' : compiled)
+
+compileNounPhraseConstraints
+ :: [CanonicalTerm ObjectId]
+ -> [Raw.AdjL]
+ -> Raw.Noun
+ -> [Raw.AdjR]
+ -> Maybe Raw.Stmt
+ -> Elaborate (CanonicalTerm ObjectId)
+compileNounPhraseConstraints subjects left noun right suchThat = do
+ nounConstraints <- traverse (`compileNoun` noun) subjects
+ leftConstraints <- concat
+ <$> traverse
+ (\subject -> traverse (compileLeftAdjective subject) left)
+ subjects
+ rightConstraints <- concat
+ <$> traverse
+ (\subject -> traverse (compileRightAttribute subject) right)
+ subjects
+ suchThatConstraint <- traverse compileStatement suchThat
+ pure
+ (logicalConjunction
+ ( nounConstraints
+ <> leftConstraints
+ <> rightConstraints
+ <> maybeToList suchThatConstraint
+ ))
+
+compileNounPhraseMaybe
+ :: CanonicalTerm ObjectId
+ -> Raw.NounPhrase Maybe
+ -> Elaborate (CanonicalTerm ObjectId)
+compileNounPhraseMaybe subject
+ (Raw.NounPhrase left noun named right suchThat) =
+ case named of
+ Nothing ->
+ compileNounPhraseConstraints
+ [subject] left noun right suchThat
+ Just variable -> do
+ abstracted <-
+ withSetBinders (variable :| [])
+ (compileNounPhraseConstraints
+ [CBound 0] left noun right suchThat)
+ pure (instantiateCanonical subject abstracted)
+
+compileExistentialNounPhrase
+ :: Raw.NounPhrase []
+ -> Elaborate (CanonicalTerm ObjectId)
+compileExistentialNounPhrase
+ (Raw.NounPhrase left noun variables right suchThat) =
+ case NonEmpty.nonEmpty variables of
+ Just binders ->
+ withSetBinders binders do
+ subjects <- traverse compileIntroducedVariable binders
+ constraints <-
+ compileNounPhraseConstraints
+ (toList subjects) left noun right suchThat
+ pure
+ (foldr
+ (const logicalExists)
+ constraints
+ binders)
+ Nothing ->
+ withAnonymousSetBinder \subject ->
+ logicalExists
+ <$> compileNounPhraseConstraints
+ [subject] left noun right suchThat
+
+compileQuantifiedNounPhrase
+ :: Raw.Quantifier
+ -> Raw.NounPhrase []
+ -> Raw.Stmt
+ -> Elaborate (CanonicalTerm ObjectId)
+compileQuantifiedNounPhrase quantifier
+ (Raw.NounPhrase left noun variables right suchThat)
+ statement =
+ case NonEmpty.nonEmpty variables of
+ Just binders ->
+ withSetBinders binders do
+ subjects <- traverse compileIntroducedVariable binders
+ constraints <-
+ compileNounPhraseConstraints
+ (toList subjects) left noun right suchThat
+ body <- compileStatement statement
+ pure
+ (quantifyNounPhrase
+ quantifier
+ (length (toList binders))
+ constraints
+ body)
+ Nothing ->
+ withAnonymousSetBinder \subject -> do
+ constraints <-
+ compileNounPhraseConstraints
+ [subject] left noun right suchThat
+ body <- compileStatement statement
+ pure (quantifyNounPhrase quantifier 1 constraints body)
+
+quantifyNounPhrase
+ :: Raw.Quantifier
+ -> Int
+ -> CanonicalTerm ObjectId
+ -> CanonicalTerm ObjectId
+ -> CanonicalTerm ObjectId
+quantifyNounPhrase quantifier binderCount constraints body =
+ case quantifier of
+ Raw.Universally ->
+ quantify
+ (if constraints == logicalTruth
+ then body
+ else CImp constraints body)
+ Raw.Existentially ->
+ quantify
+ (if constraints == logicalTruth
+ then body
+ else logicalAnd constraints body)
+ Raw.Nonexistentially ->
+ logicalNot
+ (quantify
+ (if constraints == logicalTruth
+ then body
+ else logicalAnd constraints body))
+ where
+ quantify scoped =
+ foldr (const binder) scoped [1 .. binderCount]
+ binder = case quantifier of
+ Raw.Universally -> CForall TySet
+ Raw.Existentially -> logicalExists
+ Raw.Nonexistentially -> logicalExists
+
+withAnonymousSetBinder
+ :: (CanonicalTerm ObjectId -> Elaborate value)
+ -> Elaborate value
+withAnonymousSetBinder action = do
+ outer <- State.gets elaborationBinders
+ outerDepth <- State.gets elaborationBinderDepth
+ outerStructures <- State.gets elaborationStructures
+ outerContextual <- State.gets elaborationContextualBinder
+ State.modify' \state ->
+ state
+ { elaborationBinders = (+ 1) <$> outer
+ , elaborationBinderDepth = outerDepth + 1
+ , elaborationStructures =
+ Map.mapKeysMonotonic (+ 1) outerStructures
+ , elaborationContextualBinder = (+ 1) <$> outerContextual
+ }
+ result <- action (CBound 0)
+ State.modify' \state ->
+ state
+ { elaborationBinders = outer
+ , elaborationBinderDepth = outerDepth
+ , elaborationStructures = outerStructures
+ , elaborationContextualBinder = outerContextual
+ }
+ pure result
+
+withSetBinders
+ :: NonEmpty Raw.VarSymbol
+ -> Elaborate value
+ -> Elaborate value
+withSetBinders variables action = do
+ outer <- State.gets elaborationBinders
+ outerDepth <- State.gets elaborationBinderDepth
+ outerStructures <- State.gets elaborationStructures
+ outerContextual <- State.gets elaborationContextualBinder
+ case firstDuplicate (toList variables) of
+ Just duplicate ->
+ Except.throwError
+ (ExactDuplicateLocalBinder
+ (locate duplicate)
+ duplicate)
+ Nothing -> pure ()
+ case find (`Map.member` outer) (toList variables) of
+ Just shadowed ->
+ Except.throwError
+ (ExactDuplicateLocalBinder
+ (locate shadowed)
+ shadowed)
+ Nothing -> pure ()
+ let binderCount = fromIntegral (length (toList variables))
+ shifted = (+ binderCount) <$> outer
+ introduced =
+ Map.fromList
+ (zip
+ (toList variables)
+ (reverse [0 .. binderCount - 1]))
+ State.modify' \state ->
+ state
+ { elaborationBinders = introduced <> shifted
+ , elaborationBinderDepth = outerDepth + binderCount
+ , elaborationStructures =
+ Map.mapKeysMonotonic (+ binderCount) outerStructures
+ , elaborationContextualBinder =
+ (+ binderCount) <$> outerContextual
+ }
+ result <- action
+ State.modify' \state ->
+ state
+ { elaborationBinders = outer
+ , elaborationBinderDepth = outerDepth
+ , elaborationStructures = outerStructures
+ , elaborationContextualBinder = outerContextual
+ }
+ pure result
+
+compileFormula
+ :: Raw.Formula
+ -> Elaborate (CanonicalTerm ObjectId)
+compileFormula = \case
+ Raw.FormulaChain chain ->
+ compileRelationChain chain
+ Raw.PropositionalConstant _ Raw.IsBottom ->
+ pure CFalsum
+ Raw.PropositionalConstant _ Raw.IsTop ->
+ pure (CImp CFalsum CFalsum)
+ Raw.FormulaNeg _ formula ->
+ logicalNot <$> compileFormula formula
+ Raw.FormulaPredicate
+ location
+ (Raw.PrefixPredicate command arity)
+ _marker
+ arguments -> do
+ compiled <- traverse compileExpression arguments
+ (term, actual) <-
+ applyResolvedTyped
+ location
+ (SemanticPrefixPredicate
+ command
+ (fromIntegral arity))
+ (toList compiled)
+ unless (actual == TyProp)
+ (Except.throwError
+ (ExactFormulaExpectedProposition location actual))
+ pure term
+ Raw.Connected location connective left right ->
+ compileConnective
+ location
+ connective
+ compileFormula
+ left
+ right
+ Raw.FormulaQuantified
+ _location quantifier variables bound formula ->
+ compileSymbolicQuantified
+ quantifier variables bound Nothing (compileFormula formula)
+compileConnective
+ :: Location
+ -> Raw.Connective
+ -> (input -> Elaborate (CanonicalTerm ObjectId))
+ -> input
+ -> input
+ -> Elaborate (CanonicalTerm ObjectId)
+compileConnective _location connective compile left right = do
+ left' <- compile left
+ right' <- compile right
+ case connective of
+ Raw.Conjunction ->
+ pure (logicalAnd left' right')
+ Raw.Disjunction ->
+ pure (logicalOr left' right')
+ Raw.Implication ->
+ pure (CImp left' right')
+ Raw.Equivalence ->
+ pure (CEq TyProp left' right')
+ Raw.ExclusiveOr ->
+ pure
+ (logicalAnd
+ (logicalOr left' right')
+ (logicalNot (logicalAnd left' right')))
+ Raw.NegatedDisjunction ->
+ pure (logicalNot (logicalOr left' right'))
+
+logicalAnd
+ :: CanonicalTerm global
+ -> CanonicalTerm global
+ -> CanonicalTerm global
+logicalAnd left right =
+ logicalNot (CImp left (logicalNot right))
+
+logicalTruth :: CanonicalTerm global
+logicalTruth =
+ CImp CFalsum CFalsum
+
+logicalConjunction
+ :: (Foldable collection, Eq global)
+ => collection (CanonicalTerm global)
+ -> CanonicalTerm global
+logicalConjunction =
+ foldr combine logicalTruth
+ where
+ combine proposition remaining
+ | proposition == logicalTruth = remaining
+ | remaining == logicalTruth = proposition
+ | otherwise = logicalAnd proposition remaining
+
+logicalOr
+ :: CanonicalTerm global
+ -> CanonicalTerm global
+ -> CanonicalTerm global
+logicalOr left right =
+ CImp (logicalNot left) right
+
+logicalExists
+ :: CanonicalTerm global
+ -> CanonicalTerm global
+logicalExists body =
+ logicalNot (CForall TySet (logicalNot body))
+
+compileAtomicRelation
+ :: NonEmpty Raw.Expr
+ -> Raw.Relation
+ -> NonEmpty Raw.Expr
+ -> Elaborate (CanonicalTerm ObjectId)
+compileAtomicRelation left relation right =
+ case (toList left, relation, toList right) of
+ ([leftExpression], Raw.Relation location symbol parameters, [rightExpression]) -> do
+ let key =
+ SemanticRelation
+ (Raw.relationSymbolToken symbol)
+ (Raw.relationSymbolParameterArity symbol)
+ case fixedSemanticMeaning key of
+ Just FixedEquality
+ | null parameters -> do
+ left' <- compileExpressionAsSet leftExpression
+ right' <- compileExpressionAsSet rightExpression
+ pure (CEq TySet left' right')
+ | otherwise ->
+ Except.throwError
+ (ExactUnsupportedDeclarationBody location)
+ Just FixedDisequality
+ | null parameters -> do
+ left' <- compileExpressionAsSet leftExpression
+ right' <- compileExpressionAsSet rightExpression
+ pure (logicalNot (CEq TySet left' right'))
+ | otherwise ->
+ Except.throwError
+ (ExactUnsupportedDeclarationBody location)
+ Just (FixedIntrinsic Member)
+ | null parameters -> do
+ left' <- compileExpressionAsSet leftExpression
+ right' <- compileExpressionAsSet rightExpression
+ compileMembership
+ location Raw.Positive left' right'
+ Just (FixedNegatedIntrinsic Member)
+ | null parameters -> do
+ left' <- compileExpressionAsSet leftExpression
+ right' <- compileExpressionAsSet rightExpression
+ compileMembership
+ location Raw.Negative left' right'
+ Just (FixedIntrinsic intrinsic) -> do
+ compiled <- traverse compileExpression
+ (parameters <> [leftExpression, rightExpression])
+ (term, actual) <-
+ applyTyped
+ location
+ (CIntrinsic intrinsic)
+ (coreIntrinsicType intrinsic)
+ compiled
+ unless (actual == TyProp)
+ (Except.throwError
+ (ExactFormulaExpectedProposition location actual))
+ pure term
+ Just (FixedNegatedIntrinsic intrinsic) -> do
+ compiled <- traverse compileExpression
+ (parameters <> [leftExpression, rightExpression])
+ (term, actual) <-
+ applyTyped
+ location
+ (CIntrinsic intrinsic)
+ (coreIntrinsicType intrinsic)
+ compiled
+ unless (actual == TyProp)
+ (Except.throwError
+ (ExactFormulaExpectedProposition location actual))
+ pure (logicalNot term)
+ Nothing -> do
+ compiled <- traverse compileExpression
+ (parameters <> [leftExpression, rightExpression])
+ (term, actual) <-
+ applyResolvedTyped location key compiled
+ unless (actual == TyProp)
+ (Except.throwError
+ (ExactFormulaExpectedProposition location actual))
+ pure term
+ ([leftExpression], Raw.RelationExpr location expression, [rightExpression]) -> do
+ left' <- compileExpressionAsSet leftExpression
+ right' <- compileExpressionAsSet rightExpression
+ compileRelationExpression location expression left' right'
+ _ ->
+ Except.throwError
+ (ExactUnsupportedDeclarationBody (locate relation))
+
+compileRelationExpression
+ :: Location
+ -> Raw.Expr
+ -> CanonicalTerm ObjectId
+ -> CanonicalTerm ObjectId
+ -> Elaborate (CanonicalTerm ObjectId)
+compileRelationExpression location expression left right = do
+ relation <- compileExpressionAsSet expression
+ pair <-
+ applyResolved
+ location
+ (SemanticExpressionFunction
+ (Raw.mixfixPattern Raw.PairSymbol))
+ [left, right]
+ compileMembership location Raw.Positive pair relation
+
+compileRelationChain
+ :: Raw.Chain
+ -> Elaborate (CanonicalTerm ObjectId)
+compileRelationChain chain =
+ logicalConjunction <$> traverse compileLink (chainLinks chain)
+ where
+ compileLink (sign, relation, left, right) = do
+ proposition <-
+ compileAtomicRelation
+ (left :| []) relation (right :| [])
+ pure case sign of
+ Raw.Positive -> proposition
+ Raw.Negative -> logicalNot proposition
+
+ chainLinks = \case
+ Raw.ChainBase left sign relation right ->
+ [ (sign, relation, leftExpression, rightExpression)
+ | leftExpression <- toList left
+ , rightExpression <- toList right
+ ]
+ Raw.ChainCons left sign relation rest ->
+ let firstRight = chainFirstLeft rest
+ in
+ [ (sign, relation, leftExpression, rightExpression)
+ | leftExpression <- toList left
+ , rightExpression <- toList firstRight
+ ]
+ <> chainLinks rest
+
+ chainFirstLeft = \case
+ Raw.ChainBase left _sign _relation _right -> left
+ Raw.ChainCons left _sign _relation _rest -> left
+
+applyResolved
+ :: Location
+ -> SemanticGlobalKey
+ -> [CanonicalTerm ObjectId]
+ -> Elaborate (CanonicalTerm ObjectId)
+applyResolved location key arguments = do
+ (term, actual) <-
+ applyResolvedTyped
+ location key ((\argument -> (argument, TySet)) <$> arguments)
+ unless (actual == TySet)
+ (Except.throwError
+ (ExactExpressionExpectedSet location actual))
+ pure term
+
+applyResolvedPredicate
+ :: Location
+ -> SemanticGlobalKey
+ -> [CanonicalTerm ObjectId]
+ -> Elaborate (CanonicalTerm ObjectId)
+applyResolvedPredicate location key =
+ applyResolvedPredicateChoice location (key :| [])
+
+applyResolvedPredicateChoice
+ :: Location
+ -> NonEmpty SemanticGlobalKey
+ -> [CanonicalTerm ObjectId]
+ -> Elaborate (CanonicalTerm ObjectId)
+applyResolvedPredicateChoice location keys arguments = do
+ case firstFixedMeaning (toList keys) of
+ Just meaning ->
+ maybe
+ (impossible
+ "a fixed equality predicate has an invalid source arity")
+ pure
+ (lowerFixedEqualityPredicate meaning arguments)
+ Nothing -> do
+ visible <- for (toList keys) \key -> do
+ found <-
+ State.lift
+ (Except.lift
+ (Declaration.resolveVisibleGlobalLowering key))
+ pure ((\target -> (key, target)) <$> found)
+ case catMaybes visible of
+ [(key, _target)] -> do
+ (term, actual) <-
+ applyResolvedTyped
+ location key
+ ((\argument -> (argument, TySet)) <$> arguments)
+ unless (actual == TyProp)
+ (Except.throwError
+ (ExactFormulaExpectedProposition location actual))
+ pure term
+ [] ->
+ Except.throwError
+ (ExactGlobalNotVisible location (NonEmpty.head keys))
+ _ ->
+ impossible
+ "one adjective surface resolves to several exact globals"
+ where
+ firstFixedMeaning =
+ foldr
+ (\key found -> fixedSemanticMeaning key <|> found)
+ Nothing
+
+applyResolvedTyped
+ :: Location
+ -> SemanticGlobalKey
+ -> [(CanonicalTerm ObjectId, CoreType)]
+ -> Elaborate (CanonicalTerm ObjectId, CoreType)
+applyResolvedTyped location key arguments = do
+ visible <-
+ State.lift
+ (Except.lift
+ (Declaration.resolveVisibleGlobalContentLowering key))
+ (target, content, dependencies) <-
+ maybe
+ (Except.throwError (ExactGlobalNotVisible location key))
+ pure
+ visible
+ case target of
+ GlobalReference identity -> do
+ let coreType = objectContentType content
+ State.modify' \state ->
+ state
+ { elaborationGlobals =
+ Map.insert
+ identity coreType
+ (elaborationGlobals state)
+ }
+ applyTyped location (CGlobal identity) coreType arguments
+ TransparentExpansion _identity ->
+ case content of
+ TransparentObjectContent _theory coreType body -> do
+ State.modify' \state ->
+ state
+ { elaborationGlobals =
+ Map.union
+ dependencies
+ (elaborationGlobals state)
+ }
+ applyExpandedTyped
+ location body coreType arguments
+ _ ->
+ impossible
+ "validated transparent expansion has opaque content"
+ ContextualTransparentExpansion _identity requirements ->
+ case content of
+ TransparentObjectContent _theory coreType body -> do
+ State.modify' \state ->
+ state
+ { elaborationGlobals =
+ Map.union
+ dependencies
+ (elaborationGlobals state)
+ }
+ contextArgument <-
+ resolveContextualExpansionArgument
+ location key requirements
+ applyExpandedTyped
+ location body coreType
+ ((contextArgument, TySet) : arguments)
+ _ ->
+ impossible
+ "validated contextual expansion has opaque content"
+
+resolveContextualExpansionArgument
+ :: Location
+ -> SemanticGlobalKey
+ -> Map.Map Raw.StructSymbol ObjectId
+ -> Elaborate (CanonicalTerm ObjectId)
+resolveContextualExpansionArgument location key requirements = do
+ contextual <- State.gets elaborationContextualBinder
+ case contextual of
+ Just index -> do
+ traverse_
+ (uncurry (recordContextualRequirement location))
+ (Map.toAscList requirements)
+ pure (CBound index)
+ Nothing -> do
+ structures <- State.gets elaborationStructures
+ case
+ [ CBound index
+ | (index, structure) <- Map.toAscList structures
+ , all
+ (\(symbol, object) ->
+ structureAnnotationOperation symbol structure
+ == Just object)
+ (Map.toAscList requirements)
+ ] of
+ firstMatch : _ -> pure firstMatch
+ [] ->
+ Except.throwError
+ (ExactContextualExpansionNotAvailable location key)
+
+applyExpandedTyped
+ :: Location
+ -> CanonicalTerm ObjectId
+ -> CoreType
+ -> [(CanonicalTerm ObjectId, CoreType)]
+ -> Elaborate (CanonicalTerm ObjectId, CoreType)
+applyExpandedTyped location body coreType arguments =
+ foldM step (body, coreType) arguments
+ where
+ step (current, currentType) (argument, argumentType) =
+ case currentType of
+ TyArrow expected result
+ | expected == argumentType ->
+ pure
+ ( case current of
+ CLam binderType lambdaBody
+ | binderType == expected ->
+ instantiateCanonical
+ argument lambdaBody
+ _ -> CApp current argument
+ , result
+ )
+ | otherwise ->
+ Except.throwError
+ (ExactApplicationArgumentMismatch
+ location expected argumentType)
+ actual ->
+ Except.throwError
+ (ExactApplicationExpectedFunction location actual)
+
+applyTyped
+ :: Location
+ -> CanonicalTerm ObjectId
+ -> CoreType
+ -> [(CanonicalTerm ObjectId, CoreType)]
+ -> Elaborate (CanonicalTerm ObjectId, CoreType)
+applyTyped location function functionType arguments =
+ foldM step (function, functionType) arguments
+ where
+ step (currentFunction, currentType) (argument, argumentType) =
+ case currentType of
+ TyArrow expected result
+ | expected == argumentType ->
+ pure (CApp currentFunction argument, result)
+ | otherwise ->
+ Except.throwError
+ (ExactApplicationArgumentMismatch
+ location expected argumentType)
+ actual ->
+ Except.throwError
+ (ExactApplicationExpectedFunction location actual)
+
+logicalNot :: CanonicalTerm global -> CanonicalTerm global
+logicalNot proposition =
+ CImp proposition CFalsum
+
+ensureExpressionKey
+ :: MonadError ExactCompileError monad
+ => Location
+ -> Raw.FunctionSymbol
+ -> SemanticGlobalKey
+ -> monad ()
+ensureExpressionKey location symbol key =
+ unless
+ (key == SemanticExpressionFunction (Raw.mixfixPattern symbol))
+ (throwError (ExactDeclarationHeadMismatch location))
+
+ensureAdjectiveKey
+ :: MonadError ExactCompileError monad
+ => Location
+ -> Raw.LexicalItem
+ -> SemanticGlobalKey
+ -> monad ()
+ensureAdjectiveKey location item key =
+ unless
+ ( key == SemanticLeftAdjective (Raw.lexicalItemPattern item)
+ || key == SemanticRightAdjective (Raw.lexicalItemPattern item)
+ )
+ (throwError (ExactDeclarationHeadMismatch location))
+
+ensureFunctionPhraseKey
+ :: MonadError ExactCompileError monad
+ => Location
+ -> Raw.LexicalItemSgPl
+ -> SemanticGlobalKey
+ -> monad ()
+ensureFunctionPhraseKey location item key =
+ let patterns = Raw.lexicalItemSgPlPattern item
+ in unless
+ (key == SemanticFunctionPhrase (Raw.sg patterns) (Raw.pl patterns))
+ (throwError (ExactDeclarationHeadMismatch location))
+
+ensureNounKey
+ :: MonadError ExactCompileError monad
+ => Location
+ -> Raw.LexicalItemSgPl
+ -> SemanticGlobalKey
+ -> monad ()
+ensureNounKey location item key =
+ let patterns = Raw.lexicalItemSgPlPattern item
+ in unless
+ (key == SemanticNoun (Raw.sg patterns) (Raw.pl patterns))
+ (throwError (ExactDeclarationHeadMismatch location))
+
+ensureVerbKey
+ :: MonadError ExactCompileError monad
+ => Location
+ -> Raw.LexicalItemSgPl
+ -> SemanticGlobalKey
+ -> monad ()
+ensureVerbKey location item key =
+ let patterns = Raw.lexicalItemSgPlPattern item
+ in unless
+ (key == SemanticVerb (Raw.sg patterns) (Raw.pl patterns))
+ (throwError (ExactDeclarationHeadMismatch location))
+
+ensureRelationKey
+ :: MonadError ExactCompileError monad
+ => Location
+ -> Raw.RelationSymbol
+ -> SemanticGlobalKey
+ -> monad ()
+ensureRelationKey location relation key =
+ unless
+ ( key
+ == SemanticRelation
+ (Raw.relationSymbolToken relation)
+ (Raw.relationSymbolParameterArity relation)
+ )
+ (throwError (ExactDeclarationHeadMismatch location))
+
+exactSetNounPhrase :: Raw.NounPhrase Maybe -> Bool
+exactSetNounPhrase = \case
+ Raw.NounPhrase
+ []
+ (Raw.Noun _ item [])
+ Nothing
+ []
+ Nothing ->
+ Lexicon.isBuiltinSetNoun item
+ _ -> False
+
+encodePreparedSyntax
+ :: ExactDeclarationFamily
+ -> PreparedHead
+ -> PreparedBody
+ -> Maybe SemanticName
+ -> ByteString
+encodePreparedSyntax
+ family (PreparedHead key _parameters coreType) body alias =
+ encodeCache do
+ putCacheTag case family of
+ ExactSignature -> 0x00
+ ExactAbbreviation -> 0x01
+ ExactDefinition -> 0x02
+ putSemanticGlobalKeyCache key
+ putCoreTypeCache coreType
+ case body of
+ OpaqueBody -> putCacheTag 0x00
+ TransparentBody canonical _construction -> do
+ putCacheTag 0x01
+ putCanonicalTermCache putObjectIdCache canonical
+ ContextualTransparentBody requirements canonical -> do
+ putCacheTag 0x02
+ putCanonicalCacheMap
+ (\(Raw.StructSymbol symbol) -> putCacheText symbol)
+ putObjectIdCache
+ requirements
+ putCanonicalTermCache putObjectIdCache canonical
+ putCacheMaybe
+ (putCacheText . semanticNameText)
+ alias
+
+encodePreparedSourceAxiom
+ :: ScopedCheckedCore ObjectId
+ -> SemanticName
+ -> ByteString
+encodePreparedSourceAxiom proposition alias =
+ encodeCache do
+ putCacheTag 0x03
+ putCanonicalTermCache putObjectIdCache
+ (scopedCoreTerm proposition)
+ putCacheText (semanticNameText alias)
+
+definitionAlias :: Raw.Block -> Maybe SemanticName
+definitionAlias = \case
+ Raw.BlockDefn _location _title (Raw.Marker marker) _definition ->
+ Just (semanticName marker)
+ _ -> Nothing
+
+firstDuplicate :: Ord value => [value] -> Maybe value
+firstDuplicate =
+ go Set.empty
+ where
+ go _seen [] = Nothing
+ go seen (value : rest)
+ | value `Set.member` seen = Just value
+ | otherwise = go (Set.insert value seen) rest