summaryrefslogtreecommitdiff
path: root/source/Encoding.hs
diff options
context:
space:
mode:
Diffstat (limited to 'source/Encoding.hs')
-rw-r--r--source/Encoding.hs588
1 files changed, 0 insertions, 588 deletions
diff --git a/source/Encoding.hs b/source/Encoding.hs
deleted file mode 100644
index fd988de..0000000
--- a/source/Encoding.hs
+++ /dev/null
@@ -1,588 +0,0 @@
-module Encoding
- ( PreparedTptpTask
- , prepareTptpTask
- , prepareTrainingTptpTask
- , preparedTptpSyntax
- , preparedTptpText
- , preparedTptpTextNewline
- , preparedTptpConjectureText
- , preparedTptpNameOrigins
- , encodeTask
- , encodeTaskText
- , writeTask
- , contractionTask
- ) where
-
-
-import Base
-import Syntax.Internal
-import Tptp.UnsortedFirstOrder qualified as Tptp
-
-import Bound
-import Control.Monad.State.Strict qualified as State
-import Data.List qualified as List
-import Data.Map.Strict qualified as Map
-import Data.Set qualified as Set
-import Data.Text qualified as Text
-import Data.Text.IO qualified as TextIO
-import TextBuilder
-
-
--- | The structural semantic keys available before nominal identities land.
-data LegacyTaskKey
- = LegacyObjectSymbolKey !Symbol
- | LegacyFreeConstantKey !VarSymbol
- | LegacyStructureSymbolKey !StructSymbol
- deriving (Show, Eq, Ord)
-
-newtype EncodingEnv = EncodingEnv
- { legacyTargetNames :: Map LegacyTaskKey Tptp.AtomicWord
- }
-
-data FormulaOccurrenceKey
- = ConjectureFormulaOccurrence
- | HypothesisFormulaOccurrence !Tptp.Role !Int
- deriving (Show, Eq, Ord)
-
-data TptpNameOrigin
- = LegacyTaskNameOrigin !LegacyTaskKey
- | BinderPositionOrigin !Int
- | FormulaOccurrenceOrigin !FormulaOccurrenceKey
- deriving (Show, Eq, Ord)
-
-data PreparedTptpTask = PreparedTptpTask
- { preparedTptpSyntax :: !Tptp.Task
- , preparedTptpText :: !Text
- , preparedTptpConjectureText :: !Text
- , _preparedTptpNameTable :: !EncodingEnv
- , preparedTptpReverseNames :: !(Map Text TptpNameOrigin)
- }
-
-preparedTptpTextNewline :: PreparedTptpTask -> Text
-preparedTptpTextNewline =
- (`Text.snoc` '\n') . preparedTptpText
-
--- | Target name to location-free semantic meaning.
-preparedTptpNameOrigins :: PreparedTptpTask -> Map Text Text
-preparedTptpNameOrigins =
- Map.map (Text.pack . show) . preparedTptpReverseNames
-
-data SelectedFormula = SelectedFormula
- { selectedFormulaRole :: !Tptp.Role
- , selectedFormulaBody :: !Formula
- }
-
-prepareTptpTask :: Task -> PreparedTptpTask
-prepareTptpTask task =
- prepareSelectedTptpTask
- (SelectedFormula Tptp.Conjecture (taskConjecture task))
- [ SelectedFormula
- Tptp.Axiom
- (contraction (hypothesisFormula hypothesis))
- | hypothesis <- taskHypotheses task
- ]
-
-prepareTrainingTptpTask
- :: Formula
- -> [Hypothesis]
- -> [Hypothesis]
- -> PreparedTptpTask
-prepareTrainingTptpTask conjecture usefuls redundants =
- prepareSelectedTptpTask
- (SelectedFormula Tptp.Conjecture conjecture)
- ( trainingFormulas Tptp.AxiomUseful usefuls
- <> trainingFormulas Tptp.AxiomRedundant redundants
- )
- where
- trainingFormulas role hypotheses =
- [ SelectedFormula role (contraction (hypothesisFormula hypothesis))
- | hypothesis <- hypotheses
- ]
-
-prepareSelectedTptpTask
- :: SelectedFormula
- -> [SelectedFormula]
- -> PreparedTptpTask
-prepareSelectedTptpTask conjecture hypotheses =
- let allFormulas = conjecture : hypotheses
- (encodingEnv, semanticReverseNames) =
- allocateLegacyNames
- (Set.unions
- (legacyFormulaKeys . selectedFormulaBody <$> allFormulas))
- orderedHypotheses =
- -- Hypothesis list order is not semantic. Equal lowered records stay
- -- duplicated.
- List.sortOn
- (\selected ->
- ( selectedFormulaRole selected
- , canonicalFormulaText encodingEnv selected
- ))
- hypotheses
- initialEncodingState =
- EncodingState
- { nextBinderPosition = 0
- , encodingReverseNames = semanticReverseNames
- }
- ((encodedConjecture, encodedHypotheses), finalEncodingState) =
- State.runState
- (do
- conjectureFormula <-
- encodeSelectedFormula
- encodingEnv
- (generatedAtomicWord "zf_q" 0)
- ConjectureFormulaOccurrence
- conjecture
- hypothesisFormulas <-
- for
- (zip [0..] orderedHypotheses)
- \(ordinal, selected) ->
- encodeSelectedFormula
- encodingEnv
- (generatedAtomicWord "zf_h" ordinal)
- (HypothesisFormulaOccurrence
- (selectedFormulaRole selected)
- ordinal)
- selected
- pure (conjectureFormula, hypothesisFormulas))
- initialEncodingState
- syntax = Tptp.Task (encodedConjecture : encodedHypotheses)
- in
- PreparedTptpTask
- { preparedTptpSyntax = syntax
- , preparedTptpText = Tptp.toText syntax
- , preparedTptpConjectureText =
- Tptp.toText (Tptp.Task [encodedConjecture])
- , _preparedTptpNameTable = encodingEnv
- , preparedTptpReverseNames =
- encodingReverseNames finalEncodingState
- }
-
-encodeTask :: Task -> Tptp.Task
-encodeTask = preparedTptpSyntax . prepareTptpTask
-
-encodeTaskText :: Task -> Text
-encodeTaskText = preparedTptpText . prepareTptpTask
-
-writeTask :: Handle -> Task -> IO ()
-writeTask handle =
- TextIO.hPutStr handle . preparedTptpTextNewline . prepareTptpTask
-
--- | Boolean contraction of a task.
-contractionTask :: Task -> Task
-contractionTask task = task
- { taskConjecture = contraction (taskConjecture task)
- }
-
-allocateLegacyNames
- :: Set LegacyTaskKey
- -> (EncodingEnv, Map Text TptpNameOrigin)
-allocateLegacyNames keys =
- let orderedKeys = Set.toAscList keys
- objectKeys =
- [ key
- | key@LegacyObjectSymbolKey{} <- orderedKeys
- ]
- freeConstantKeys =
- [ key
- | key@LegacyFreeConstantKey{} <- orderedKeys
- ]
- structureKeys =
- [ key
- | key@LegacyStructureSymbolKey{} <- orderedKeys
- ]
- allocations =
- allocateCategory "zf_u" objectKeys
- <> allocateCategory "zf_f" freeConstantKeys
- <> allocateCategory "zf_s" structureKeys
- targetNames =
- Map.fromList
- [ (key, target)
- | (key, target) <- allocations
- ]
- reverseNames =
- foldl'
- (\reverseNames' (key, target) ->
- insertReverseName
- (Tptp.atomicWordText target)
- (LegacyTaskNameOrigin key)
- reverseNames')
- mempty
- allocations
- in
- (EncodingEnv targetNames, reverseNames)
- where
- allocateCategory prefix =
- zipWith
- (\ordinal key ->
- (key, generatedAtomicWord prefix ordinal))
- [0..]
-
-legacyFormulaKeys :: Formula -> Set LegacyTaskKey
-legacyFormulaKeys formula =
- Set.fromList
- (LegacyFreeConstantKey <$> toList formula)
- <> Set.map
- LegacyObjectSymbolKey
- (Set.filter requiresAllocatedName (mentionedSymbols formula))
- <> Set.map
- LegacyStructureSymbolKey
- (mentionedStructureSymbols formula)
-
-requiresAllocatedName :: Symbol -> Bool
-requiresAllocatedName = \case
- SymbolPredicate (PredicateRelation relation) ->
- relation /= EqSymbol && relation /= NeqSymbol
- _ ->
- True
-
-mentionedStructureSymbols :: ExprOf a -> Set StructSymbol
-mentionedStructureSymbols = \case
- TermVar{} ->
- mempty
- TermSymbol _loc _symbol args ->
- Set.unions (mentionedStructureSymbols <$> args)
- TermSymbolStruct symbol maybeArgument ->
- Set.insert symbol (foldMap mentionedStructureSymbols maybeArgument)
- Apply expression arguments ->
- mentionedStructureSymbols expression
- <> Set.unions
- (mentionedStructureSymbols <$> toList arguments)
- TermSep _variable bound scope ->
- mentionedStructureSymbols bound
- <> mentionedStructureSymbols (fromScope scope)
- ReplacePred _rangeVariable _domainVariable bound scope ->
- mentionedStructureSymbols bound
- <> mentionedStructureSymbols (fromScope scope)
- ReplaceFun bounds lhs condition ->
- Set.unions
- (mentionedStructureSymbols . snd <$> toList bounds)
- <> mentionedStructureSymbols (fromScope lhs)
- <> mentionedStructureSymbols (fromScope condition)
- Connected _connective left right ->
- mentionedStructureSymbols left <> mentionedStructureSymbols right
- Lambda scope ->
- mentionedStructureSymbols (fromScope scope)
- Quantified _quantifier scope ->
- mentionedStructureSymbols (fromScope scope)
- PropositionalConstant{} ->
- mempty
- Not _loc expression ->
- mentionedStructureSymbols expression
-
-canonicalFormulaText :: EncodingEnv -> SelectedFormula -> Text
-canonicalFormulaText encodingEnv selected =
- TextBuilder.toText
- (State.evalState
- (encodeExpr encodingEnv (selectedFormulaBody selected))
- EncodingState
- { nextBinderPosition = 0
- , encodingReverseNames = mempty
- })
-
-data EncodingState = EncodingState
- { nextBinderPosition :: !Int
- , encodingReverseNames :: !(Map Text TptpNameOrigin)
- }
-
-type Encode = State.State EncodingState
-
-encodeSelectedFormula
- :: EncodingEnv
- -> Tptp.AtomicWord
- -> FormulaOccurrenceKey
- -> SelectedFormula
- -> Encode Tptp.FofFormula
-encodeSelectedFormula encodingEnv targetName occurrence selected = do
- registerReverseName
- (Tptp.atomicWordText targetName)
- (FormulaOccurrenceOrigin occurrence)
- body <- encodeExpr encodingEnv (selectedFormulaBody selected)
- pure
- (Tptp.FofFormula
- (Tptp.NameAtomicWord targetName)
- (selectedFormulaRole selected)
- body)
-
-encodeExpr :: EncodingEnv -> Expr -> Encode TextBuilder
-encodeExpr encodingEnv =
- buildExpr . fmap (encodeFreeVar encodingEnv)
- where
- -- Source tasks reach encoding only after checker canonicalization.
- buildExpr :: ExprOf EncodedVar -> Encode TextBuilder
- buildExpr = \case
- Equals _pos left right -> do
- left' <- buildExpr left
- right' <- buildExpr right
- pure (left' <> char '=' <> right')
- NotEquals _pos left right -> do
- left' <- buildExpr left
- right' <- buildExpr right
- pure (left' <> text "!=" <> right')
- Atomic _pos predicate arguments -> do
- arguments' <- traverse buildExpr arguments
- pure
- (buildApply
- (encodePredicate encodingEnv predicate)
- arguments')
- PropositionalConstant IsBottom ->
- pure (text "$false")
- PropositionalConstant IsTop ->
- pure (text "$true")
- Not _pos formula -> do
- formula' <- buildUnitary formula
- pure (char '~' <> formula')
- Connected Conjunction left right -> do
- left' <- buildAnd left
- right' <- buildAnd right
- pure (left' <> char '&' <> right')
- Connected Disjunction left right -> do
- left' <- buildOr left
- right' <- buildOr right
- pure (left' <> char '|' <> right')
- Connected Implication left right -> do
- left' <- buildUnitary left
- right' <- buildUnitary right
- pure (left' <> text "=>" <> right')
- Connected Equivalence left right -> do
- left' <- buildUnitary left
- right' <- buildUnitary right
- pure (left' <> text "<=>" <> right')
- Connected NegatedDisjunction left right -> do
- formula' <-
- buildUnitary (Connected Disjunction left right)
- pure (char '~' <> formula')
- Connected ExclusiveOr left right -> do
- formula' <-
- buildUnitary (Connected Equivalence left right)
- pure (char '~' <> formula')
- Quantified quantifier scope ->
- buildQuantified buildExpr buildUnitary quantifier scope
- TermVar variable ->
- pure (buildTermVar variable)
- Apply expression arguments -> case expression of
- TermVar (FreeConst targetName) -> do
- arguments' <- traverse buildExpr (toList arguments)
- pure (buildApply targetName arguments')
- _ ->
- error
- ("encodeExpr: complex term as head of application: "
- <> show expression)
- TermSymbol _pos symbol arguments -> do
- arguments' <- traverse buildExpr arguments
- pure
- (buildApply
- (encodeSymbol encodingEnv symbol)
- arguments')
- expression@ReplaceFun{} ->
- error
- ("Precondition failed in encodeTerm, cannot encode terms with comprehensions directly: "
- <> show expression)
- expression@ReplacePred{} ->
- error
- ("Precondition failed in encodeTerm, cannot encode terms with comprehensions directly: "
- <> show expression)
- expression@TermSep{} ->
- error
- ("Precondition failed in encodeTerm, cannot encode terms with comprehensions directly: "
- <> show expression)
- TermSymbolStruct symbol maybeArgument -> case maybeArgument of
- Just argument -> do
- argument' <- buildExpr argument
- pure
- (buildApply
- (lookupLegacyName
- encodingEnv
- (LegacyStructureSymbolKey symbol))
- [argument'])
- Nothing ->
- error
- ("encodeExpr (precondition failed): unannotated struct symbol "
- <> show symbol)
- _ ->
- error "encodeExpr: missing case"
-
- buildTermVar :: EncodedVar -> TextBuilder
- buildTermVar = \case
- BoundVar variable ->
- Tptp.buildVariable variable
- FreeConst targetName ->
- Tptp.buildAtomicWord targetName
-
- buildApply :: Tptp.AtomicWord -> [TextBuilder] -> TextBuilder
- buildApply function arguments = case arguments of
- [] ->
- Tptp.buildAtomicWord function
- _ ->
- Tptp.buildAtomicWord function <> Tptp.buildTuple arguments
-
- isAtom :: ExprOf EncodedVar -> Bool
- isAtom = \case
- TermVar{} -> True
- TermSymbol{} -> True
- TermSymbolStruct{} -> True
- Apply{} -> True
- PropositionalConstant{} -> True
- Equals{} -> True
- NotEquals{} -> True
- _ -> False
-
- buildQuantified
- :: (ExprOf EncodedVar -> Encode TextBuilder)
- -> (ExprOf EncodedVar -> Encode TextBuilder)
- -> Quantifier
- -> Scope VarSymbol ExprOf EncodedVar
- -> Encode TextBuilder
- buildQuantified renderEmpty renderBody quantifier scope = do
- let boundKeys = currentScopeBindings scope
- targetVariables <- traverse (const allocateBinderVariable) boundKeys
- let binderNames = Map.fromList (zip boundKeys targetVariables)
- instantiateBinder key =
- TermVar
- (BoundVar
- (Map.lookup key binderNames
- ?? impossible
- ("encodeExpr: missing binder position for "
- <> show key)))
- body = instantiate instantiateBinder scope
- case targetVariables of
- [] ->
- renderEmpty body
- _ -> do
- body' <- renderBody body
- pure
- ( buildQuantifier quantifier
- <> Tptp.buildList
- (Tptp.buildVariable <$> targetVariables)
- <> char ':'
- <> body'
- )
-
- buildQuantifier :: Quantifier -> TextBuilder
- buildQuantifier = \case
- Universally ->
- text "!"
- Existentially ->
- text "?"
-
- buildUnitary :: ExprOf EncodedVar -> Encode TextBuilder
- buildUnitary = \case
- atom | isAtom atom ->
- buildExpr atom
- Quantified quantifier scope ->
- buildQuantified buildUnitary buildUnitary quantifier scope
- Not _ formula -> do
- formula' <- buildUnitary formula
- pure (char '~' <> formula')
- formula -> do
- formula' <- buildExpr formula
- pure (char '(' <> formula' <> char ')')
-
- buildAnd :: ExprOf EncodedVar -> Encode TextBuilder
- buildAnd = \case
- Connected Conjunction left right -> do
- left' <- buildAnd left
- right' <- buildAnd right
- pure (left' <> char '&' <> right')
- formula ->
- buildUnitary formula
-
- buildOr :: ExprOf EncodedVar -> Encode TextBuilder
- buildOr = \case
- Connected Disjunction left right -> do
- left' <- buildOr left
- right' <- buildUnitary right
- pure (left' <> char '|' <> right')
- formula ->
- buildUnitary formula
-
-currentScopeBindings
- :: Scope VarSymbol ExprOf a
- -> [VarSymbol]
-currentScopeBindings scope =
- nubOrd
- [ binder
- | B binder <- toList (fromScope scope)
- ]
-
-data EncodedVar
- = BoundVar Tptp.Variable
- | FreeConst Tptp.AtomicWord
- deriving (Show, Eq, Ord)
-
-encodeFreeVar :: EncodingEnv -> VarSymbol -> EncodedVar
-encodeFreeVar encodingEnv variable =
- FreeConst
- (lookupLegacyName
- encodingEnv
- (LegacyFreeConstantKey variable))
-
-encodeSymbol :: EncodingEnv -> Symbol -> Tptp.AtomicWord
-encodeSymbol encodingEnv symbol =
- lookupLegacyName encodingEnv (LegacyObjectSymbolKey symbol)
-
-encodePredicate :: EncodingEnv -> Predicate -> Tptp.AtomicWord
-encodePredicate encodingEnv predicate =
- encodeSymbol encodingEnv (SymbolPredicate predicate)
-
-lookupLegacyName :: EncodingEnv -> LegacyTaskKey -> Tptp.AtomicWord
-lookupLegacyName encodingEnv key =
- Map.lookup key (legacyTargetNames encodingEnv)
- ?? impossible
- ("Encoding lookup missed inventoried key " <> show key)
-
-allocateBinderVariable :: Encode Tptp.Variable
-allocateBinderVariable = do
- position <- State.gets nextBinderPosition
- let targetVariable = generatedVariable "V" position
- State.modify' \state ->
- state{nextBinderPosition = position + 1}
- registerReverseName
- (Tptp.variableText targetVariable)
- (BinderPositionOrigin position)
- pure targetVariable
-
-registerReverseName :: Text -> TptpNameOrigin -> Encode ()
-registerReverseName target origin =
- State.modify' \state ->
- state
- { encodingReverseNames =
- insertReverseName
- target
- origin
- (encodingReverseNames state)
- }
-
-insertReverseName
- :: Text
- -> TptpNameOrigin
- -> Map Text TptpNameOrigin
- -> Map Text TptpNameOrigin
-insertReverseName target origin reverseNames =
- case Map.lookup target reverseNames of
- Nothing ->
- Map.insert target origin reverseNames
- Just existing ->
- impossible
- ( "TPTP target name "
- <> show target
- <> " was allocated for both "
- <> show existing
- <> " and "
- <> show origin
- )
-
-generatedAtomicWord :: Text -> Int -> Tptp.AtomicWord
-generatedAtomicWord prefix ordinal =
- let target = prefix <> Text.pack (show ordinal)
- in
- Tptp.atomicWord target
- ?? impossible
- ("generated invalid TPTP atomic word " <> show target)
-
-generatedVariable :: Text -> Int -> Tptp.Variable
-generatedVariable prefix ordinal =
- let target = prefix <> Text.pack (show ordinal)
- in
- Tptp.variable target
- ?? impossible
- ("generated invalid TPTP variable " <> show target)