summaryrefslogtreecommitdiff
path: root/source/Syntax
diff options
context:
space:
mode:
authoradelon <22380201+adelon@users.noreply.github.com>2026-07-26 12:33:06 +0200
committeradelon <22380201+adelon@users.noreply.github.com>2026-07-26 12:33:06 +0200
commit2f68e17be6e2b45f673a207a3cc2813b52a1541e (patch)
treec5c600298690b67e5c3b77ac0bde2260ea0adf76 /source/Syntax
parent4f3f414630bf393963787070e58a3f4b5c2a0f97 (diff)
Simplify
Diffstat (limited to 'source/Syntax')
-rw-r--r--source/Syntax/DeBruijn.hs736
1 files changed, 0 insertions, 736 deletions
diff --git a/source/Syntax/DeBruijn.hs b/source/Syntax/DeBruijn.hs
deleted file mode 100644
index cda54f5..0000000
--- a/source/Syntax/DeBruijn.hs
+++ /dev/null
@@ -1,736 +0,0 @@
-{-# LANGUAGE DeriveAnyClass #-}
-{-# LANGUAGE MonadComprehensions #-}
-{-# LANGUAGE ViewPatterns #-}
-
-module Syntax.DeBruijn
- ( module Syntax.DeBruijn
- , module Syntax.Abstract
- , module Syntax.LexicalPhrase
- , module Syntax.Token
- ) where
-
-import Base
-import Syntax.Lexicon (pattern PairSymbol, pattern ConsSymbol)
-import Syntax.LexicalPhrase (unsafeReadPhrase, unsafeReadPhraseSgPl)
-import Syntax.Token (Token(..))
-
-import Syntax.Abstract
- ( Chain(..)
- , Associativity(..)
- , Connective(..)
- , VarSymbol(..)
- , pattern NamedVar
- , pattern FreshVar
- , FunctionSymbol
- , MixfixItem(..)
- , Pattern(..)
- , LexicalItem
- , LexicalItemSgPl
- , RelationSymbol(..)
- , StructSymbol (..)
- , Relation
- , PropositionalConstant(..)
- , StructPhrase
- , Justification(..)
- , Marker(..)
- , markerFromToken
- , mkLexicalItem
- , mkLexicalItemSgPl
- , pattern CarrierSymbol, pattern ConsSymbol, pattern ElementSymbol
- , pattern NotElementSymbol, pattern EqSymbol, pattern NeqSymbol, pattern SubseteqSymbol
- )
-
-import Data.List qualified as List
-import Data.List.NonEmpty qualified as NonEmpty
-import Data.Map.Strict qualified as Map
-import Data.Maybe
-import Data.Set qualified as Set
-import Text.Megaparsec.Pos (SourcePos)
-
--- | 'Symbol' defined at the top level.
-data Symbol
- = SymbolMixfix FunctionSymbol
- | SymbolFun LexicalItemSgPl
- | SymbolInteger Int
- | SymbolPredicate Predicate
- deriving (Show, Eq, Ord, Generic, Hashable)
-
--- | Predicate symbols.
-data Predicate
- = PredicateAdj LexicalItem
- | PredicateVerb LexicalItemSgPl
- | PredicateNoun LexicalItemSgPl -- ^ /@\<...\> is a \<...\>@/.
- | PredicateRelation RelationSymbol
- | PredicateSymbol Text
- | PredicateNounStruct LexicalItemSgPl -- ^ /@\<...\> is a \<...\>@/.
- deriving (Show, Eq, Ord, Generic, Hashable)
-
-data Quantifier
- = Universally
- | Existentially
- deriving (Show, Eq, Ord, Generic, Hashable)
-
--- | Internal high-order expression, using variables with scoped de Bruijn indices.
-data Expr
- = Var {name :: VarSymbol, index :: Int}
- -- ^ Indexed variables
- | TermSymbol Symbol [Expr]
- -- ^ Direct application of a symbol, in particular first-order function and predicate symbols.
- | TermSymbolStruct StructSymbol (Maybe Expr)
- -- ^ Structure symbol with an optional label.
- | Replacement ReplExpr
- | Apply Expr Expr
- -- ^ Higher-order application.
- | PropositionalConstant PropositionalConstant
- | Not Expr
- | Connected Connective Expr Expr
- | Lambda VarSymbol Expr
- | Quantified Quantifier VarSymbol Expr
- deriving (Show, Eq, Ord, Generic, Hashable)
-
-type Formula = Expr
-type Term = Expr
-
--- | A set comprehension that is a replacement expression with side conditions.
--- They look like @{ f(x,y,z) | x\\in X, y\\in Y(x), z\\in Z(x,y) | \\phi(x,y,z) }@, where
---
--- 1. @f(x,y,z)@ is the replacement value with bound variables @x,y,z@
---
--- 2. @x\\in X@, @y\\in Y(x)@, etc. are the replacement bindings with their domains (which may depend on earlier bound variables)
---
--- 3. @\\phi(x,y,z)@ is the optional replacement condition
---
--- The case of no replacement condition is represented by using the constant @Top@ as the formula.
--- Bound variables scope over inner (later) bindings, the replacement value, and the replacement condition.
--- Similar constructs are sometimes called ReplSep or Fraenkel operator in other systems.
-data ReplExpr
- = ReplExpr {replBindings :: [(VarSymbol, Expr)], replValue :: Expr, replCondition :: Expr}
- deriving (Show, Eq, Ord, Generic, Hashable)
-
-
-makeReplacementIff
- :: Expr -- ^ Newly defined local constant.
- -> ReplExpr
- -> Expr
-makeReplacementIff definiens repl =
- Forall testVar ((Var testVar 0 `IsElementOf` definiens) `Iff` existsPreimage)
- where
- testVar :: VarSymbol
- testVar = "scrutinee"
-
- existsPreimage :: Expr
- existsPreimage = makeExists (fst <$> replBindings repl) replaceBound
-
- replaceBound :: Expr
- replaceBound = makeConjunction [Var x 0 `IsElementOf` dom | (x, dom) <- toList (replBindings repl)] `And` replaceCond
-
- replaceEq :: Expr
- replaceEq = replValue repl `Equals` Var testVar 0
-
- replaceCond :: Expr
- replaceCond = case replCondition repl of
- Top -> replaceEq
- cond' -> replaceEq `And` cond'
-
-
--- | Increase the index of all free variables matching the given variable name
-shift
- :: Int
- -- ^ The amount to shift by
- -> VarSymbol
- -- ^ The variable name to match
- -> Int
- -- ^ The minimum index of variables to match
- -> Expr
- -- ^ The expression to shift
- -> Expr
-shift offset y = go
- where
- go minIndex = \case
- Var x i ->
- let i' = if x == y && minIndex <= i then i + offset else i
- in Var x i'
- Lambda x body ->
- let minIndex' = if x == y then minIndex + 1 else minIndex
- body' = go minIndex' body
- in Lambda x body'
- Quantified q x body ->
- let minIndex' = if x == y then minIndex + 1 else minIndex
- body' = go minIndex' body
- in Quantified q x body'
- Replacement repl -> Replacement (shiftReplacement offset y minIndex repl)
- Apply f a ->
- Apply (go minIndex f) (go minIndex a)
- TermSymbol s args ->
- TermSymbol s (map (go minIndex) args)
- TermSymbolStruct s me ->
- TermSymbolStruct s (fmap (go minIndex) me)
- PropositionalConstant c -> PropositionalConstant c
- Not e -> Not (go minIndex e)
- Connected c e1 e2 -> Connected c (go minIndex e1) (go minIndex e2)
-
-
-shiftReplacement
- :: Int
- -> VarSymbol
- -> Int
- -> ReplExpr
- -> ReplExpr
-shiftReplacement offset y minIndex0 (ReplExpr bindings value cond) =
- let go :: Int -> (VarSymbol, Expr) -> (Int, (VarSymbol, Expr))
- go minIndex (x, domain) =
- let domain' = shift offset y minIndex domain
- minIndex' = if x == y then minIndex + 1 else minIndex
- in (minIndex', (x, domain'))
-
- (minIndexFinal, bindings') = mapAccumL go minIndex0 bindings
-
- value' = shift offset y minIndexFinal value
- cond' = shift offset y minIndexFinal cond
- in ReplExpr bindings' value' cond'
-
-
--- | Substitute all free occurrences of a variable with given name and index with a new expression.
--- For matching names, indices above the target are decremented, i.e. this substitution
--- closes the gap created by replacing one binder occurrence.
-substitute
- :: VarSymbol -- ^ Target variable name
- -> Int -- ^ Target variable index
- -> Expr -- ^ New expression to substitute
- -> Expr -- ^ Expression to perform substitution in
- -> Expr
-substitute targetName targetIndex new = go where
- go = \case
- Var x i
- | x /= targetName -> Var x i
- | i == targetIndex -> new
- | i < targetIndex -> Var x i
- | otherwise -> Var x (i - 1)
- Lambda x body ->
- let targetIndex' = if x == targetName then targetIndex + 1 else targetIndex
- newShifted = shift 1 x 0 new
- body' = substitute targetName targetIndex' newShifted body
- in Lambda x body'
- Quantified q x body ->
- let targetIndex' = if x == targetName then targetIndex + 1 else targetIndex
- newShifted = shift 1 x 0 new
- body' = substitute targetName targetIndex' newShifted body
- in Quantified q x body'
- Replacement repl -> Replacement (substituteReplacement targetName targetIndex new repl)
- Apply e1 e2 -> Apply (go e1) (go e2)
- TermSymbol sym args -> TermSymbol sym (go <$> args)
- TermSymbolStruct s m -> TermSymbolStruct s (go <$> m)
- PropositionalConstant pc -> PropositionalConstant pc
- Not e -> Not (go e)
- Connected c e1 e2 -> Connected c (go e1) (go e2)
-
-
-substituteReplacement
- :: VarSymbol -- ^ Target variable name
- -> Int -- ^ Target variable index
- -> Expr -- ^ New expression to substitute
- -> ReplExpr -- ^ Replacement expression to perform substitution in
- -> ReplExpr
-substituteReplacement targetName targetIndex new (ReplExpr bindings value cond) =
- let go :: (Int, Expr) -> (VarSymbol, Expr) -> ((Int, Expr), (VarSymbol, Expr))
- go (currentTargetIndex, currentNew) (x, domain) =
- let -- The current domain is NOT under the scope of the current binder x, so we proceed directly
- domain' = substitute targetName currentTargetIndex currentNew domain
- -- After this binder, the substitution expression must be lifted by 1...
- newExpr' = shift 1 x 0 currentNew
- -- ...and the target index increments if the binder coincides with the target name.
- currentTargetIndex' = if x == targetName then currentTargetIndex + 1 else currentTargetIndex
- in ((currentTargetIndex', newExpr'), (x, domain'))
-
- ((targetIndex', new'), bindings') = mapAccumL go (targetIndex, new) bindings
-
- value' = substitute targetName targetIndex' new' value
- cond' = substitute targetName targetIndex' new' cond
- in ReplExpr bindings' value' cond'
-
-
--- | β-reduce an expression
-betaReduce :: Expr -> Expr
-betaReduce = \case
- xi@Var{} -> xi
- Lambda x e ->
- Lambda x (betaReduce e)
- Apply function argument ->
- let function' = betaReduce function
- argument' = betaReduce argument
- in case function' of
- Lambda x e ->
- betaReduce (substitute x 0 argument' e)
- _ -> Apply function' argument'
-
- TermSymbol sym args ->
- TermSymbol sym (betaReduce <$> args)
- TermSymbolStruct s m ->
- TermSymbolStruct s (betaReduce <$> m)
- Replacement repl ->
- Replacement (betaReduceReplacement repl)
- PropositionalConstant pc -> PropositionalConstant pc
- Not e' -> Not (betaReduce e')
- Connected c l r -> Connected c (betaReduce l) (betaReduce r)
- Quantified q binder e -> Quantified q binder (betaReduce e)
-
-
-betaReduceReplacement :: ReplExpr -> ReplExpr
-betaReduceReplacement (ReplExpr bs value cond) = ReplExpr [(x, betaReduce dom) | (x, dom) <- bs ] (betaReduce value) (betaReduce cond)
-
--- | Default variable name for α-reduction.
-defaultVarSymbol :: VarSymbol
-defaultVarSymbol = "_"
-
--- | α-reduce an expression, renaming all bound variables to 'defaultVarSymbol'
-alphaReduce :: Expr -> Expr
-alphaReduce e0 = case e0 of
- Var vName vIndex -> Var vName vIndex
-
- Lambda binder e ->
- let shiftedBody = shift 1 defaultVarSymbol 0 e
- substitutedBody = substitute binder 0 (Var defaultVarSymbol 0) shiftedBody
- e' = alphaReduce substitutedBody
- in Lambda defaultVarSymbol e'
-
- Quantified q binder e ->
- let shiftedBody = shift 1 defaultVarSymbol 0 e
- substitutedBody = substitute binder 0 (Var defaultVarSymbol 0) shiftedBody
- e' = alphaReduce substitutedBody
- in Quantified q defaultVarSymbol e'
- Replacement repl -> Replacement (alphaReduceReplacement repl)
- Apply f a -> Apply (alphaReduce f) (alphaReduce a)
- TermSymbol s args -> TermSymbol s (map alphaReduce args)
- TermSymbolStruct s m -> TermSymbolStruct s (fmap alphaReduce m)
- PropositionalConstant pc -> PropositionalConstant pc
- Not e -> Not (alphaReduce e)
- Connected c l r -> Connected c (alphaReduce l) (alphaReduce r)
-
-
--- | α-reduce a replacement expression, renaming all binders to 'defaultVarSymbol'.
-alphaReduceReplacement :: ReplExpr -> ReplExpr
-alphaReduceReplacement (ReplExpr bindings0 value0 cond0) = case bindings0 of
- [] -> ReplExpr [] (alphaReduce value0) (alphaReduce cond0)
- ((binder, domain) : rest) ->
- let shiftedRepl = shiftReplacement 1 defaultVarSymbol 0 (ReplExpr rest value0 cond0)
- substitutedRepl = substituteReplacement binder 0 (Var defaultVarSymbol 0) shiftedRepl
- ReplExpr bindings' value' cond' = alphaReduceReplacement substitutedRepl
- in ReplExpr ((defaultVarSymbol, alphaReduce domain) : bindings') value' cond'
-
-
-
-pattern TermOp :: FunctionSymbol -> [Expr] -> Expr
-pattern TermOp op es = TermSymbol (SymbolMixfix op) es
-
-pattern TermConst :: Token -> Expr
-pattern TermConst c <- TermOp (MixfixItem (TokenCons c End) _ NonAssoc) []
- where
- TermConst c = TermOp (MixfixItem (TokenCons c End) (markerFromToken c) NonAssoc) []
-
-pattern TermPair :: Expr -> Expr -> Expr
-pattern TermPair e1 e2 = TermOp PairSymbol [e1, e2]
-
-pattern Atomic :: Predicate -> [Expr] -> Expr
-pattern Atomic symbol args = TermSymbol (SymbolPredicate symbol) args
-
-pattern FormulaAdj :: Expr -> LexicalItem -> [Expr] -> Expr
-pattern FormulaAdj e adj es = Atomic (PredicateAdj adj) (e:es)
-
-pattern FormulaVerb :: Expr -> LexicalItemSgPl -> [Expr] -> Expr
-pattern FormulaVerb e verb es = Atomic (PredicateVerb verb) (e:es)
-
-pattern FormulaNoun :: Expr -> LexicalItemSgPl -> [Expr] -> Expr
-pattern FormulaNoun e noun es = Atomic (PredicateNoun noun) (e:es)
-
-relationNoun :: Expr -> Formula
-relationNoun arg = FormulaNoun arg (mkLexicalItemSgPl (unsafeReadPhraseSgPl "relation[/s]") "relation") []
-
-rightUniqueAdj :: Expr -> Formula
-rightUniqueAdj arg = FormulaAdj arg (mkLexicalItem (unsafeReadPhrase "right-unique") "rightunique") []
-
--- | Untyped quantification.
-pattern Forall, Exists :: VarSymbol -> Expr -> Expr
-pattern Forall x body = Quantified Universally x body
-pattern Exists x body = Quantified Existentially x body
-
-makeForall, makeExists :: Foldable t => t VarSymbol -> Formula -> Formula
-makeForall xs e = foldr Forall e xs
-makeExists xs e = foldr Exists e xs
-
-
-freeVars :: Expr -> Set VarSymbol
-freeVars = freeVarsWith Map.empty
-
-freeVarsWith :: Map VarSymbol Int -> Expr -> Set VarSymbol
-freeVarsWith counts = \case
- Var x i ->
- let current = Map.findWithDefault 0 x counts
- in if i >= current then Set.singleton x else Set.empty
- Lambda binder body ->
- let counts' = Map.insertWith (+) binder 1 counts
- in freeVarsWith counts' body
- Quantified _ binder body ->
- let counts' = Map.insertWith (+) binder 1 counts
- in freeVarsWith counts' body
- Apply e1 e2 ->
- Set.union (freeVarsWith counts e1) (freeVarsWith counts e2)
- Replacement repl -> freeVarsReplacementWith counts repl
- TermSymbol _s args ->
- List.foldl' (\acc e -> Set.union acc (freeVarsWith counts e)) Set.empty args
- TermSymbolStruct _s me ->
- maybe Set.empty (freeVarsWith counts) me
- PropositionalConstant _ -> Set.empty
- Not e -> freeVarsWith counts e
- Connected _ e1 e2 ->
- Set.union (freeVarsWith counts e1) (freeVarsWith counts e2)
-
-freeVarsReplacement :: ReplExpr -> Set VarSymbol
-freeVarsReplacement = freeVarsReplacementWith Map.empty
-
-
-freeVarsReplacementWith :: Map VarSymbol Int -> ReplExpr -> Set VarSymbol
-freeVarsReplacementWith counts0 (ReplExpr bs value cond) =
- let step (m, acc) (binder, domain) =
- let m' = Map.insertWith (+) binder 1 m
- in (m', acc <> freeVarsWith m domain) -- Crucially, we use the old environment m here, since the domain is not under the scope of its own binder.
- (countsFinal, freeVarsDomain) = foldl' step (counts0, Set.empty) (toList bs)
- freeVarsValue = freeVarsWith countsFinal value
- freeVarsCondition = freeVarsWith countsFinal cond
- in freeVarsDomain <> freeVarsValue <> freeVarsCondition
-
-
-pattern And :: Expr -> Expr -> Expr
-pattern And e1 e2 = Connected Conjunction e1 e2
-
-pattern Or :: Expr -> Expr -> Expr
-pattern Or e1 e2 = Connected Disjunction e1 e2
-
-pattern Implies :: Expr -> Expr -> Expr
-pattern Implies e1 e2 = Connected Implication e1 e2
-
-pattern Iff :: Expr -> Expr -> Expr
-pattern Iff e1 e2 = Connected Equivalence e1 e2
-
-pattern Xor :: Expr -> Expr -> Expr
-pattern Xor e1 e2 = Connected ExclusiveOr e1 e2
-
-pattern Bottom :: Expr
-pattern Bottom = PropositionalConstant IsBottom
-
-pattern Top :: Expr
-pattern Top = PropositionalConstant IsTop
-
-pattern Relation :: RelationSymbol -> [Expr] -> Expr
-pattern Relation rel es = Atomic (PredicateRelation rel) es
-
--- | Set membership.
-pattern IsElementOf, IsNotElementOf :: Expr -> Expr -> Expr
-pattern IsElementOf e1 e2 = Atomic (PredicateRelation ElementSymbol) (e1 : [e2])
-pattern IsNotElementOf e1 e2 = Not (IsElementOf e1 e2)
-
--- | Subset relation (non-strict).
-pattern IsSubsetOf :: Expr -> Expr -> Expr
-pattern IsSubsetOf e1 e2 = Atomic (PredicateRelation SubseteqSymbol) (e1 : [e2])
-
-ordinalNoun :: LexicalItemSgPl
-ordinalNoun = mkLexicalItemSgPl (unsafeReadPhraseSgPl "ordinal[/s]") "ordinal"
-
-isOrdinalNoun :: LexicalItemSgPl -> Bool
-isOrdinalNoun noun = noun == ordinalNoun
-
--- | Ordinal predicate.
-pattern IsOrd :: Expr -> Expr
-pattern IsOrd e1 <- Atomic (PredicateNoun (isOrdinalNoun -> True)) [e1]
- where
- IsOrd e1 = Atomic (PredicateNoun ordinalNoun) [e1]
-
--- | First-order equality.
-pattern Equals :: Expr -> Expr -> Expr
-pattern Equals e1 e2 = Atomic (PredicateRelation EqSymbol) (e1 : [e2])
-
--- | First-order disequality.
-pattern NotEquals :: Expr -> Expr -> Expr
-pattern NotEquals e1 e2 = Atomic (PredicateRelation NeqSymbol) (e1 : [e2])
-
-pattern EmptySet :: Expr
-pattern EmptySet =
- TermSymbol
- (SymbolMixfix (MixfixItem (TokenCons (Command "emptyset") End) "emptyset" NonAssoc))
- []
-
-makeConjunction :: [Expr] -> Expr
-makeConjunction = \case
- [] -> Top
- es -> List.foldl1' (\a b -> And a b) es
-
-makeDisjunction :: [Expr] -> Expr
-makeDisjunction = \case
- [] -> Bottom
- es -> List.foldl1' (\a b -> Or a b) es
-
-makeIff :: [Expr] -> Expr
-makeIff = \case
- [] -> Bottom
- es -> List.foldl1' (\a b -> Iff a b) es
-
-makeXor :: [Expr] -> Expr
-makeXor = \case
- [] -> Bottom
- es -> List.foldl1' (\a b -> Xor a b) es
-
-finiteSet :: NonEmpty Expr -> Expr
-finiteSet = foldr cons EmptySet where
- cons x y = TermSymbol (SymbolMixfix ConsSymbol) [x, y]
-
-isPositive :: Expr -> Bool
-isPositive = \case
- Not _ -> False
- _ -> True
-
-dual :: Expr -> Expr
-dual = \case
- Not f -> f
- f -> Not f
-
-
-
-data Asm
- = Asm Formula
- | AsmStruct VarSymbol StructPhrase
- deriving (Show, Eq, Ord)
-
-data StructAsm = StructAsm VarSymbol StructPhrase deriving (Show, Eq, Ord)
-
-data Axiom = Axiom [Asm] Formula deriving (Show, Eq, Ord)
-
-data Lemma = Lemma [Asm] Formula deriving (Show, Eq, Ord)
-
-
-data Defn
- = DefnPredicate [Asm] Predicate (NonEmpty VarSymbol) Formula
- | DefnFun [Asm] LexicalItemSgPl [VarSymbol] Term
- | DefnOp FunctionSymbol [VarSymbol] Term
- deriving (Show, Eq, Ord)
-
-
-data Inductive = Inductive
- { inductiveSymbol :: FunctionSymbol
- , inductiveParams :: [VarSymbol]
- , inductiveDomain :: Expr
- , inductiveIntros :: NonEmpty IntroRule
- }
- deriving (Show, Eq, Ord)
-
-data IntroRule = IntroRule
- { introConditions :: [Formula] -- The inductively defined set may only appear as an argument of monotone operations on the rhs.
- , introResult :: Formula -- TODO Refine.
- }
- deriving (Show, Eq, Ord)
-
-data CalcQuantifier
- = CalcForall (NonEmpty VarSymbol) (Maybe Formula)
- | CalcUnquantified
- deriving (Show, Eq, Ord)
-
-data Proof
- = Omitted
- -- ^ Ends a proof without further verification.
- -- This results in a “gap” in the formalization.
- | Qed Justification
- -- ^ Ends of a proof, leaving automation to discharge the current goal using the given justification.
- | Contradiction Justification
- -- ^ Ends a proof by deriving absurdity using the given justification.
- | ByContradiction Proof
- -- ^ Take the dual of the current goal as an assumption and
- -- set the goal to absurdity.
- | BySetInduction (Maybe Term) Proof
- -- ^ ∈-induction.
- | ByOrdInduction Proof
- -- ^ Transfinite induction for ordinals.
- | Assume Formula Proof
- -- ^ Simplify goals that are implications or disjunctions.
- | Fix (NonEmpty VarSymbol) Formula Proof
- -- ^ Simplify universal goals (with an optional bound or such that statement)
- | Take (NonEmpty VarSymbol) Formula Justification Proof
- -- ^ Use existential assumptions.
- | Suffices Formula Justification Proof
- | ByCase [Case]
- -- ^ Proof by case. Disjunction of the case hypotheses 'Case'
- -- must hold for this step to succeed. Each case starts a subproof,
- -- keeping the same goal but adding the case hypothesis as an assumption.
- -- Often this will be a classical split between /@P@/ and /@not P@/, in
- -- which case the proof that /@P or not P@/ holds is easy.
- --
- | Have Formula Justification Proof
- -- ^ An affirmation, e.g.: /@We have \<stmt\> by \<ref\>@/.
- --
- | Calc CalcQuantifier Calc Proof
- | Subclaim Formula Proof Proof
- -- ^ A claim is a sublemma with its own proof:
- --
- -- /@Show \<goal stmt\>. \<steps\>. \<continue other proof\>.@/
- --
- -- A successful first proof adds the claimed formula as an assumption
- -- for the remaining proof.
- --
- | Define VarSymbol Term Proof
- | DefineFunction VarSymbol VarSymbol Term Term Proof
- | DefineFunctionLocal VarSymbol VarSymbol VarSymbol Term (NonEmpty (Term, Formula)) Proof
- deriving (Show, Eq, Ord)
-
--- | An individual case in a case split.
-data Case = Case
- { caseOf :: Formula
- , caseProof :: Proof
- } deriving (Show, Eq, Ord)
-
--- | See 'Syntax.Abstract.Calc'.
-data Calc
- = Equation Term (NonEmpty (Term, Justification))
- | Biconditionals Term (NonEmpty (Term, Justification))
- deriving (Show, Eq, Ord)
-
-calcQuant :: CalcQuantifier -> (Formula -> Formula)
-calcQuant = \case
- CalcUnquantified -> id
- CalcForall xs maySuchThat -> case maySuchThat of
- Nothing -> makeForall xs
- Just suchThat -> \phi -> makeForall xs (suchThat `Implies` phi)
-
-calcResult :: CalcQuantifier -> Calc -> Expr
-calcResult quant = \case
- Equation e eqns -> calcQuant quant (e `Equals` fst (NonEmpty.last eqns))
- Biconditionals phi phis -> calcQuant quant (phi `Iff` fst (NonEmpty.last phis))
-
-calculation :: CalcQuantifier -> Calc -> [(Expr, Justification)]
-calculation quant = \case
- Equation e1 eqns@((e2, jst) :| _) -> (calcQuant quant (e1 `Equals` e2), jst) : collectEquations quant (toList eqns)
- Biconditionals p1 ps@((p2, jst) :| _) -> (calcQuant quant (p1 `Iff` p2), jst) : collectBiconditionals quant (toList ps)
-
-
-collectEquations :: CalcQuantifier -> [(Formula, j)] -> [(Formula, j)]
-collectEquations quant = \case
- (e1, _) : eqns'@((e2, jst) : _) -> (calcQuant quant (e1 `Equals` e2), jst) : collectEquations quant eqns'
- _ -> []
-
-collectBiconditionals :: CalcQuantifier -> [(Formula, j)] -> [(Formula, j)]
-collectBiconditionals quant = \case
- (p1, _) : ps@((p2, jst) : _) -> (calcQuant quant (p1 `Iff` p2), jst) : collectBiconditionals quant ps
- _ -> []
-
-
-newtype Datatype = DatatypeFin (NonEmpty Text) deriving (Show, Eq, Ord)
-
-data Signature
- = SignaturePredicate Predicate (NonEmpty VarSymbol)
- | SignatureFormula Formula
- -- LATER: This is a lossy encoding of a symbolic signature declaration.
- -- The checker currently recovers the declared mixfix symbol heuristically
- -- from the generated formula in order to assign ownership. Replace this
- -- with a precise signature representation that carries the declared symbol
- -- directly.
- deriving (Show, Eq, Ord)
-
-data StructDefn = StructDefn
- { structPhrase :: StructPhrase
- -- ^ The noun phrase naming the structure, e.g.: @partial order@ or @abelian group@.
- , structParents :: Set StructPhrase
- , structDefnLabel :: VarSymbol
- , structDefnFixes :: Set StructSymbol
- -- ^ List of commands representing operations,
- -- e.g.: @\\contained@ or @\\inv@. These are used as default operation names
- -- in instantiations such as @Let $G$ be a group@.
- -- The commands should be set up to handle an optional struct label
- -- which would typically be rendered as a sub- or superscript, e.g.:
- -- @\\contained[A]@ could render as ”⊑ᴬ“.
- -- --
- , structDefnAssumes :: [(Marker, Formula)]
- -- ^ The assumption or axioms of the structure.
- -- To be instantiate with the @structFixes@ of a given structure.
- } deriving (Show, Eq, Ord)
-
-data Abbreviation
- = Abbreviation Symbol Expr
- deriving (Show, Eq, Ord)
-
-data Block
- = BlockAxiom SourcePos Marker Axiom
- | BlockLemma SourcePos Marker Lemma
- | BlockProof SourcePos Proof
- | BlockDefn SourcePos Marker Defn
- | BlockAbbr SourcePos Marker Abbreviation
- | BlockStruct SourcePos Marker StructDefn
- | BlockInductive SourcePos Marker Inductive
- | BlockSig SourcePos Marker [Asm] Signature
- deriving (Show, Eq, Ord)
-
-data Task = Task
- { taskDirectness :: Directness
- , taskHypotheses :: [(Marker, Formula)] -- ^ No guarantees on order.
- , taskConjectureLabel :: Marker
- , taskConjecture :: Formula
- } deriving (Show, Eq, Generic, Hashable)
-
--- | Indicates whether a given proof is direct or indirect.
--- An indirect proof (i.e. a proof by contradiction) may
--- cause an ATP to emit a warning about contradictory axioms.
--- When we know that the proof is indirect, we want to ignore
--- this warning. For relevance filtering we also want to know
--- what our actual goal is, so we keep the original conjecture.
-data Directness
- = Indirect Formula -- ^ The former conjecture.
- | Direct
- deriving (Show, Eq, Generic, Hashable)
-
-isIndirect :: Task -> Bool
-isIndirect task = case taskDirectness task of
- Indirect _ -> True
- Direct -> False
-
-contractionTask :: Task -> Task
-contractionTask task = task
- { taskHypotheses = mapMaybe contract (taskHypotheses task)
- , taskConjecture = contraction (taskConjecture task)
- }
-
-contract :: (Marker, Formula) -> Maybe (Marker, Formula)
-contract (m, phi) = case contraction phi of
- Top -> Nothing
- phi' -> Just (m, phi')
-
--- | Full boolean contraction.
-contraction :: Expr -> Expr
-contraction = \case
- Connected conn f1 f2 -> atomicContraction (Connected conn (contraction f1) (contraction f2))
- Quantified quant x body -> atomicContraction (Quantified quant x (contraction body))
- Not f -> Not (contraction f)
- f -> f
-
-
--- | Atomic boolean contraction.
-atomicContraction :: Expr-> Expr
-atomicContraction = \case
- Top `Iff` f -> f
- Bottom `Iff` f -> Not f
- f `Iff` Top -> f
- f `Iff` Bottom -> Not f
-
- Top `Implies` f -> f
- Bottom `Implies` _ -> Top
- _ `Implies` Top -> Top
- f `Implies` Bottom -> Not f
-
- Top `And` f -> f
- Bottom `And` _ -> Bottom
- f `And` Top -> f
- _ `And` Bottom -> Bottom
-
- phi@(Quantified _quant _ body) -> case body of
- Top -> Top
- Bottom -> Bottom
- _ -> phi
-
- Not Top -> Bottom
- Not Bottom -> Top
-
- f -> f