haskhol-core-1.1.0: src/HaskHOL/Core/Parser/Lib.hs
{-# LANGUAGE FlexibleContexts, PatternSynonyms, TypeFamilies #-}
{-|
Module: HaskHOL.Core.Parser.Lib
Copyright: (c) The University of Kansas 2013
LICENSE: BSD3
Maintainer: ecaustin@ittc.ku.edu
Stability: unstable
Portability: unknown
This module defines or re-exports common utility functions, type classes,
and auxilliary data types used in HaskHOL's parsers. These primarily fall
three classes of objects:
* Types and functions used by the parsers.
* Benign flag and state extensions used by the parsers.
* Predicates and modifiers for state extensions used by the parsers.
Note that, because these state extensions were designed to be used with the
parser, the accessor and predicate functions are written to use 'getExtCtxt'
rather than 'getExt' for convenience.
To see what is actually exported to the user, see the module
"HaskHOL.Core.Parser".
-}
module HaskHOL.Core.Parser.Lib
( -- * Parser Utilities and Types
PreType(..)
, PreTerm(..)
, dpty
, pretypeOfType
, MyParser
, ParseError -- | A re-export of 'ParseError'.
, runParser -- |A re-export of 'runParser'.
, langDef
, lexer
, mysymbol
, myparens
, mybraces
, mybrackets
, mycommaSep1
, mysemiSep
, mysemiSep1
, myreserved
, myidentifier
, myinteger
, myoperator
, myreservedOp
, choiceSym
, choiceId
, mywhiteSpace
, mymany
, mymany1
, mysepBy1
, mytry
-- * Type Elaboration Flags
, FlagIgnoreConstVarstruct(..)
, FlagTyInvWarning(..)
, FlagTyOpInvWarning(..)
, FlagAddTyAppsAuto(..)
-- * Pretty Printer Flags
, FlagRevInterface(..)
, FlagPrintAllThm(..)
-- * Extensible Parser Operators
, HOLContext(..)
, prepHOLContext
, getTypeArityCtxt
, parseAsBinder
, parseAsTyBinder
, parseAsPrefix
, parseAsInfix
, unparseAsBinder
, unparseAsTyBinder
, unparseAsPrefix
, unparseAsInfix
, parsesAsBinder
, parsesAsTyBinder
, isPrefix
, getInfixStatus
-- * Overloading and Interface Mapping
, makeOverloadable
, removeInterface
, reduceInterface
, overrideInterface
, overloadInterface
, prioritizeOverload
, getInterface
, getOverloads
-- * Type Abbreviations
, newTypeAbbrev
, removeTypeAbbrev
, typeAbbrevs
-- * Hidden Constant Mapping
, hideConstant
, unhideConstant
, getHidden
-- * Extensible Printer Operators
, addUnspacedBinop
, addPrebrokenBinop
, removeUnspacedBinop
, removePrebrokenBinop
, getUnspacedBinops
, getPrebrokenBinops
-- * Parser state manipulations
, getState
, setState
, updateState
) where
import HaskHOL.Core.Lib hiding ((<?>))
import HaskHOL.Core.Kernel
import HaskHOL.Core.State
import HaskHOL.Core.Basics
import HaskHOL.Core.Parser.Prims
import Text.Parsec hiding (runParser, setState, getState, updateState
,ParseError, (<|>))
import qualified Text.Parsec as P
import Text.Parsec.Language
import Text.Parsec.Text
import Text.Parsec.Token
import Control.Monad.Identity
import {-# SOURCE #-} HaskHOL.Core.Parser.Rep
-- new flags and extensions
{-|
Flag to say whether to treat a constant varstruct, i.e. @\\ const . bod@, as
variable.
-}
newFlag "FlagIgnoreConstVarstruct" True
{-|
Flag indicating that the user should be warned if a type variable was invented
during parsing.
-}
newFlag "FlagTyInvWarning" False
{-|
Flag indicating that the user should be warned if a type operator variable was
invented during parsing.
-}
newFlag "FlagTyOpInvWarning" False
{-|
Flag to say whether implicit type applications are to be added during parsing.
-}
newFlag "FlagAddTyAppsAuto" True
-- | Flag to indicate whether the interface should be reversed on printing.
newFlag "FlagRevInterface" True
{-|
Flag to indicate if the entirety of a theorem should be printed, as opposed
to just the conclusion term.
-}
newFlag "FlagPrintAllThm" True
data BinderOps = BinderOps ![Text] deriving Typeable
deriveSafeCopy 0 'base ''BinderOps
initBinderOps :: [Text]
initBinderOps = ["\\"]
insertBinder :: Text -> Update BinderOps ()
insertBinder op =
do (BinderOps ops) <- get
put (BinderOps (op:ops))
removeBinder :: Text -> Update BinderOps ()
removeBinder op =
do (BinderOps ops) <- get
put (BinderOps (op `delete` ops))
getBinders :: Query BinderOps [Text]
getBinders =
do (BinderOps ops) <- ask
return ops
makeAcidic ''BinderOps ['insertBinder, 'removeBinder, 'getBinders]
data TyBinderOps = TyBinderOps ![Text] deriving Typeable
deriveSafeCopy 0 'base ''TyBinderOps
initTyBinderOps :: [Text]
initTyBinderOps = ["\\\\"]
insertTyBinder :: Text -> Update TyBinderOps ()
insertTyBinder op =
do (TyBinderOps ops) <- get
put (TyBinderOps (op:ops))
removeTyBinder :: Text -> Update TyBinderOps ()
removeTyBinder op =
do (TyBinderOps ops) <- get
put (TyBinderOps (op `delete` ops))
getTyBinders :: Query TyBinderOps [Text]
getTyBinders =
do (TyBinderOps ops) <- ask
return ops
makeAcidic ''TyBinderOps ['insertTyBinder, 'removeTyBinder, 'getTyBinders]
data PrefixOps = PrefixOps ![Text] deriving Typeable
deriveSafeCopy 0 'base ''PrefixOps
insertPrefix :: Text -> Update PrefixOps ()
insertPrefix op =
do (PrefixOps ops) <- get
put (PrefixOps (op:ops))
removePrefix :: Text -> Update PrefixOps ()
removePrefix op =
do (PrefixOps ops) <- get
put (PrefixOps (op `delete` ops))
getPrefixes :: Query PrefixOps [Text]
getPrefixes =
do (PrefixOps ops) <- ask
return ops
makeAcidic ''PrefixOps ['insertPrefix, 'removePrefix, 'getPrefixes]
data InfixOps = InfixOps ![(Text, (Int, Text))] deriving Typeable
deriveSafeCopy 0 'base ''InfixOps
initInfixOps :: [(Text, (Int, Text))]
initInfixOps = [("=", (12, "right"))]
insertInfix :: (Text, (Int, Text)) -> Update InfixOps ()
insertInfix i@(n, _) =
do (InfixOps is) <- get
let is' = case find (\ (n', _) -> n == n') is of
Just _ -> is
_ ->
sort (\ (s, (x, a)) (t, (y, b)) ->
x < y || x == y && a > b || x == y && a == b && s < t)
(i:is)
put (InfixOps is')
removeInfix :: Text -> Update InfixOps ()
removeInfix op =
do (InfixOps ops) <- get
put (InfixOps (filter (\ (x, _) -> x /= op) ops))
getInfixes :: Query InfixOps [(Text, (Int, Text))]
getInfixes =
do (InfixOps ops) <- ask
return ops
makeAcidic ''InfixOps ['insertInfix, 'removeInfix, 'getInfixes]
data Interface = Interface ![(Text, (Text, HOLType))] deriving Typeable
deriveSafeCopy 0 'base ''Interface
insertInterface :: (Text, (Text, HOLType)) -> Update Interface ()
insertInterface x =
do (Interface xs) <- get
put (Interface (x:xs))
deleteInterface :: (Text, (Text, HOLType)) -> Update Interface ()
deleteInterface x =
do (Interface xs) <- get
put (Interface (x `delete` xs))
filterInterface :: Text -> Update Interface ()
filterInterface s =
do (Interface xs) <- get
put (Interface (filter (\ (x, _) -> x /= s) xs))
getInterfaces :: Query Interface [(Text, (Text, HOLType))]
getInterfaces =
do (Interface xs) <- ask
return xs
makeAcidic ''Interface
['insertInterface, 'deleteInterface, 'filterInterface, 'getInterfaces]
data Overload = Overload !(Map Text HOLType) deriving Typeable
deriveSafeCopy 0 'base ''Overload
insertOverload :: Text -> HOLType -> Update Overload ()
insertOverload s ty =
do (Overload xs) <- get
put (Overload (mapInsert s ty xs))
getOverload :: Query Overload (Map Text HOLType)
getOverload =
do (Overload xs) <- ask
return xs
makeAcidic ''Overload ['insertOverload, 'getOverload]
data TypeAbbreviations = TypeAbbreviations !(Map Text HOLType)
deriving Typeable
deriveSafeCopy 0 'base ''TypeAbbreviations
insertTypeAbbreviation :: Text -> HOLType -> Update TypeAbbreviations ()
insertTypeAbbreviation x ty =
do (TypeAbbreviations xs) <- get
put (TypeAbbreviations (mapInsert x ty xs))
removeTypeAbbreviation :: Text -> Update TypeAbbreviations ()
removeTypeAbbreviation x =
do (TypeAbbreviations xs) <- get
put (TypeAbbreviations (x `mapDelete` xs))
getTypeAbbreviations :: Query TypeAbbreviations (Map Text HOLType)
getTypeAbbreviations =
do (TypeAbbreviations xs) <- ask
return xs
makeAcidic ''TypeAbbreviations
['insertTypeAbbreviation, 'removeTypeAbbreviation, 'getTypeAbbreviations]
data Hidden = Hidden [Text] deriving Typeable
deriveSafeCopy 0 'base ''Hidden
insertHidden :: Text -> Update Hidden ()
insertHidden x =
do (Hidden xs) <- get
put (Hidden (x `insert` xs))
removeHidden :: Text -> Update Hidden ()
removeHidden x =
do (Hidden xs) <- get
put (Hidden (x `delete` xs))
getHiddens :: Query Hidden [Text]
getHiddens =
do (Hidden xs) <- ask
return xs
makeAcidic ''Hidden ['insertHidden, 'removeHidden, 'getHiddens]
data UnspacedBinops = UnspacedBinops ![Text] deriving Typeable
deriveSafeCopy 0 'base ''UnspacedBinops
initUnspaced :: [Text]
initUnspaced = [",", "..", "$"]
insertUnspaced :: Text -> Update UnspacedBinops ()
insertUnspaced op =
do (UnspacedBinops ops) <- get
put (UnspacedBinops (op:ops))
removeUnspaced :: Text -> Update UnspacedBinops ()
removeUnspaced op =
do (UnspacedBinops ops) <- get
put (UnspacedBinops (ops \\ [op]))
getUnspaced :: Query UnspacedBinops [Text]
getUnspaced =
do (UnspacedBinops ops) <- ask
return ops
makeAcidic ''UnspacedBinops ['insertUnspaced, 'removeUnspaced, 'getUnspaced]
data PrebrokenBinops = PrebrokenBinops ![Text] deriving Typeable
deriveSafeCopy 0 'base ''PrebrokenBinops
initPrebroken :: [Text]
initPrebroken = ["==>"]
insertPrebroken :: Text -> Update PrebrokenBinops ()
insertPrebroken op =
do (PrebrokenBinops ops) <- get
put (PrebrokenBinops (op:ops))
removePrebroken :: Text -> Update PrebrokenBinops ()
removePrebroken op =
do (PrebrokenBinops ops) <- get
put (PrebrokenBinops (ops \\ [op]))
getPrebroken :: Query PrebrokenBinops [Text]
getPrebroken =
do (PrebrokenBinops ops) <- ask
return ops
makeAcidic ''PrebrokenBinops ['insertPrebroken, 'removePrebroken, 'getPrebroken]
-- | The default 'PreType' to be used as a blank for the type inference engine.
dpty :: PreType
dpty = PTyComb (PTyCon textEmpty) []
-- | Converts a 'HOLType' to 'PreType'
pretypeOfType :: HOLType -> PreType
pretypeOfType (TyVar f v) = UTyVar f v 0
pretypeOfType (TyApp tyop args) =
let (s, n) = destTypeOp tyop
tyop' = if n == -1 then UTyVar False s (length args) else PTyCon s in
PTyComb tyop' $ map pretypeOfType args
pretypeOfType (UType tv tb) =
PUTy (pretypeOfType tv) $ pretypeOfType tb
pretypeOfType _ = error "pretypeOfType: exhaustive warning."
{-|
An alias to a stateful 'GenParser' that carries a 'HOLContext', a list of
known type operator variables with their arity, and a counter The list of
operators is used to guarantee that all instances of a type operator variable
in a term have the same arity. The counter is used to generate fresh names
in a term.
-}
type MyParser thry = GenParser (HOLContext thry, [(Text, Int)], Int)
-- | The Parsec 'LanguageDef' for HaskHOL.
langDef :: GenLanguageDef Text st Identity
langDef = LanguageDef
{ commentStart = ""
, commentEnd = ""
, commentLine = ""
, nestedComments = True
, identStart = alphaNum <|> char '_'
, identLetter = alphaNum <|> oneOf "_'"
, opStart = oneOf ",:!#$%&*+./<=>?@\\^|-~"
, opLetter = oneOf ":!#$%&*+./<=>?@\\^|-~"
, reservedNames = [ "TYINST", "let", "and", "in", "if", "then", "else"
, "match", "when", "function" ]
, reservedOpNames = ["(", ")", "[", "]", "{", "}"
, "%", "_", "'", "->", ".", ":", ";", "|"]
, caseSensitive = True
}
-- | The Parsec token parser for HaskHOL.
lexer :: GenTokenParser Text (HOLContext thry, [(Text, Int)], Int) Identity
lexer = makeTokenParser langDef
-- | A version of 'symbol' for our language.
mysymbol :: String -> MyParser thry Text
mysymbol = liftM pack . symbol lexer
-- | A version of 'parens' for our language.
myparens :: MyParser thry a -> MyParser thry a
myparens = parens lexer
-- | A version of 'braces' for our language.
mybraces :: MyParser thry a -> MyParser thry a
mybraces = braces lexer
-- | A version of 'brackets' for our language.
mybrackets :: MyParser thry a -> MyParser thry a
mybrackets = brackets lexer
-- | A version of 'commaSep1' for our language.
mycommaSep1 :: MyParser thry a -> MyParser thry [a]
mycommaSep1 = commaSep1 lexer
-- | A version of 'semiSep' for our language.
mysemiSep :: MyParser thry a -> MyParser thry [a]
mysemiSep = semiSep lexer
-- | A version of 'semiSep1' for our language.
mysemiSep1 :: MyParser thry a -> MyParser thry [a]
mysemiSep1 = semiSep1 lexer
-- | A version of 'reserved' for our language.
myreserved :: String -> MyParser thry ()
myreserved = reserved lexer
-- | A version of 'identifier' for our language.
myidentifier :: MyParser thry Text
myidentifier = liftM pack $ identifier lexer
-- | A version of 'integer' for our language.
myinteger :: MyParser thry Integer
myinteger = integer lexer
-- | A version of 'operator' for our language.
myoperator :: MyParser thry Text
myoperator = liftM pack $ operator lexer
-- | A version of 'reservedOp' for our language.
myreservedOp :: String -> MyParser thry ()
myreservedOp = reservedOp lexer
-- | Selects the first matching symbol.
choiceSym :: [String] -> MyParser thry Text
choiceSym ops = choice $ map mysymbol ops
-- | Selects the first matching reserved operator.
choiceId :: [Text] -> MyParser thry Text
choiceId ops = choice $ map
(\ s -> try $ do s' <- myidentifier <|> myoperator
if s' == s
then return s
else fail "choiceId") ops
-- | A version of 'whiteSpace' for our language.
mywhiteSpace :: MyParser thry ()
mywhiteSpace = whiteSpace lexer
-- | A re-export of 'P.many'.
mymany :: MyParser thry a -> MyParser thry [a]
mymany = P.many
-- | A re-export of 'P.many1'.
mymany1 :: MyParser thry a -> MyParser thry [a]
mymany1 = P.many1
-- | A re-export of 'P.sepBy1'.
mysepBy1 :: MyParser thry a -> MyParser thry b -> MyParser thry [a]
mysepBy1 = P.sepBy1
-- | A re-export of 'P.try'.
mytry :: MyParser thry a -> MyParser thry a
mytry = P.try
-- State Extensions
prepHOLContext :: HOL cls thry (HOLContext thry)
prepHOLContext =
do acid1 <- openLocalStateHOL (InfixOps initInfixOps)
is <- queryHOL acid1 GetInfixes
closeAcidStateHOL acid1
acid2 <- openLocalStateHOL (PrefixOps [])
ps <- queryHOL acid2 GetPrefixes
closeAcidStateHOL acid2
acid3 <- openLocalStateHOL (BinderOps initBinderOps)
bs <- queryHOL acid3 GetBinders
closeAcidStateHOL acid3
acid4 <- openLocalStateHOL (TyBinderOps initTyBinderOps)
tbs <- queryHOL acid4 GetTyBinders
closeAcidStateHOL acid4
ts <- types
tas <- typeAbbrevs
iface <- getInterface
cond1 <- getBenignFlag FlagPrintAllThm
cond2 <- getBenignFlag FlagRevInterface
us <- getUnspacedBinops
pbs <- getPrebrokenBinops
return $! HOLContext is ps bs tbs ts tas iface cond1 cond2 us pbs
-- Operators
-- A version of 'getTypeArity' for parser contexts.
getTypeArityCtxt :: HOLContext thry -> Text -> Maybe Int
getTypeArityCtxt ctxt name =
liftM (snd . destTypeOp) . mapLookup name $ typesCtxt ctxt
-- | Specifies a 'Text' to be recognized as a term binder by the parser.
parseAsBinder :: Text -> HOL Theory thry ()
parseAsBinder op =
do acid <- openLocalStateHOL (BinderOps initBinderOps)
updateHOL acid (InsertBinder op)
createCheckpointAndCloseHOL acid
-- | Specifies a 'Text' to be recognized as a type binder by the parser.
parseAsTyBinder :: Text -> HOL Theory thry ()
parseAsTyBinder op =
do acid <- openLocalStateHOL (TyBinderOps initTyBinderOps)
updateHOL acid (InsertTyBinder op)
createCheckpointAndCloseHOL acid
-- | Specifies a 'Text' to be recognized as a prefix operator by the parser.
parseAsPrefix :: Text -> HOL Theory thry ()
parseAsPrefix op =
do acid <- openLocalStateHOL (PrefixOps [])
updateHOL acid (InsertPrefix op)
createCheckpointAndCloseHOL acid
{-|
Specifies a 'Text' to be recognized as an infix operator by the parser with
a given precedence level and associativity.
-}
parseAsInfix :: (Text, (Int, Text)) -> HOL Theory thry ()
parseAsInfix op =
do acid <- openLocalStateHOL (InfixOps initInfixOps)
updateHOL acid (InsertInfix op)
createCheckpointAndCloseHOL acid
-- | Specifies a 'Text' for the parser to stop recognizing as a term binder.
unparseAsBinder :: Text -> HOL Theory thry ()
unparseAsBinder op =
do acid <- openLocalStateHOL (BinderOps initBinderOps)
updateHOL acid (RemoveBinder op)
createCheckpointAndCloseHOL acid
-- | Specifies a 'Text' for the parser to stop recognizing as a type binder.
unparseAsTyBinder :: Text -> HOL Theory thry ()
unparseAsTyBinder op =
do acid <- openLocalStateHOL (TyBinderOps initTyBinderOps)
updateHOL acid (RemoveTyBinder op)
createCheckpointAndCloseHOL acid
{-|
Specifies a 'Text' for the parser to stop recognizing as a prefix operator.
-}
unparseAsPrefix :: Text -> HOL Theory thry ()
unparseAsPrefix op =
do acid <- openLocalStateHOL (PrefixOps [])
updateHOL acid (RemovePrefix op)
createCheckpointAndCloseHOL acid
{-|
Specifies a 'Text' for the parser to stop recognizing as an infix operator.
-}
unparseAsInfix :: Text -> HOL Theory thry ()
unparseAsInfix op =
do acid <- openLocalStateHOL (InfixOps initInfixOps)
updateHOL acid (RemoveInfix op)
createCheckpointAndCloseHOL acid
-- | Predicate for 'Text's recognized as term binders by the parser.
parsesAsBinder :: Text -> HOLContext thry -> Bool
parsesAsBinder op = elem op . binders
-- | Predicate for 'Text's recognized as term binders by the parser.
parsesAsTyBinder :: Text -> HOLContext thry -> Bool
parsesAsTyBinder op = elem op . tyBinders
-- | Predicate for 'Text's recognized as prefix operators by the parser.
isPrefix :: Text -> HOLContext thry -> Bool
isPrefix op = elem op . prefixes
{-|
Predicate for 'Text's recognized as infix operators by the parser. Returns
a precidence and associativity pair guarded by 'Maybe'.
-}
getInfixStatus :: Text -> HOLContext thry -> Maybe (Int, Text)
getInfixStatus op = lookup op . infixes
-- Interface
{-|
Specifies a 'Text' that can act as an overloadable identifier within the
parser. The provided type is the most general type that instances of this
symbol may have. Throws a 'HOLException' if the given symbol has already been
declared as overloadable with a different type.
Note that defining a symbol as overloadable will erase any interface overloads
that were previously introduced via 'overrideInterface' in order to guarantee
that all overloads are matchable with their most general type.
-}
makeOverloadable :: Text -> HOLType -> HOL Theory thry ()
makeOverloadable s gty =
do overs <- getOverloads
case mapLookup s overs of
Just ty
| gty == ty -> return ()
| otherwise ->
fail "makeOverloadable: differs from existing skeleton"
_ -> do acid1 <- openLocalStateHOL (Overload mapEmpty)
updateHOL acid1 (InsertOverload s gty)
createCheckpointAndCloseHOL acid1
acid2 <- openLocalStateHOL (Interface [])
updateHOL acid2 (FilterInterface s)
createCheckpointAndCloseHOL acid2
-- | Removes all instances of an overloaded symbol from the interface.
removeInterface :: Text -> HOL Theory thry ()
removeInterface sym =
do acid <- openLocalStateHOL (Interface [])
updateHOL acid (FilterInterface sym)
createCheckpointAndCloseHOL acid
{-|
Removes a specific instance of an overloaded symbol from the interface.
Throws a 'HOLException' if the provided term is not a constant or varible term
representing an instance of the overloaded symbol.
-}
reduceInterface :: Text -> HOLTerm -> HOL Theory thry ()
reduceInterface sym tm =
do namty <- liftMaybe "reduceInterface: term not a constant or variable" $
destConst tm <|> destVar tm
acid <- openLocalStateHOL (Interface [])
updateHOL acid (DeleteInterface (sym, namty))
createCheckpointAndCloseHOL acid
{-|
Removes all existing overloads for a given symbol and replaces them with a
single, specific instance. Throws a 'HOLException' if the provided term is
not a constant or variable term representing an instance of the overloaded
symbol.
Note that because 'overrideInterface' can introduce at most one overload for
a symbol it does not have to be previously defined as overloadable via
'makeOverloadable'. However, if the symbol is defined as overloadable then
the provided term must have a type that is matchable with the symbol's most
general type.
-}
overrideInterface :: Text -> HOLTerm -> HOL Theory thry ()
overrideInterface sym tm =
do namty <- liftMaybe "overrideInterface: term not a constant or variable" $
destConst tm <|> destVar tm
let m = do acid <- openLocalStateHOL (Interface [])
updateHOL acid (FilterInterface sym)
updateHOL acid (InsertInterface (sym, namty))
createCheckpointAndCloseHOL acid
overs <- getOverloads
case sym `mapLookup` overs of
Just gty -> if isNothing $ typeMatch gty (snd namty) ([], [], [])
then fail $ "overrideInterface: " ++
"not an instance of type skeleton"
else m
_ -> m
{-|
Introduces a new overload for a given symbol. Throws a 'HOLException' in the
following cases:
* The symbol has not previously been defined as overloadable via
'makeOverloadable'.
* The provided term is not a constant or variable term representing a
specific instance of the overloaded symbol.
* The provided term does not have a type that is matchable with the
overloadable symbol's specified most general type.
Note that specifying an overload that already exists will move it to the front
of the interface list, effectively prioritizing it. This behavior is utilized
by 'prioritizeOverload'.
-}
overloadInterface :: Text -> HOLTerm -> HOL Theory thry ()
overloadInterface sym tm =
do overs <- getOverloads
gty <- liftMaybe ("overloadInstace: symbol " ++ show sym ++
" is not overloadable.") $ mapLookup sym overs
namty <- liftMaybe "overloadInstance: term not a constant or variable" $
destConst tm <|> destVar tm
if isNothing $ typeMatch gty (snd namty) ([], [], [])
then fail "overloadInstance: not an instance of type skeleton"
else do acid <- openLocalStateHOL (Interface [])
let i = (sym, namty)
updateHOL acid (DeleteInterface i)
updateHOL acid (InsertInterface i)
createCheckpointAndCloseHOL acid
{-|
Specifies a type to prioritize when the interface is used to overload a
symbol. Note that this applies to all overloads in the system whose match
with the specified most general type involves the provided type.
Prioritization is done by redefining overloads via 'overloadInterface'.
-}
prioritizeOverload :: HOLType -> HOL Theory thry ()
prioritizeOverload ty =
do overs <- getOverloads
mapM_ (\ (s, gty) ->
(do iface <- getInterface
let (n, t') = fromJust $
tryFind (\ (s', x@(_, t)) ->
if s' /= s then Nothing
else do (ts, _, _) <- typeMatch gty t
([], [], [])
_ <- ty `revLookup` ts
return x) iface
overloadInterface s $ mkVar n t')
<|> return ()) $ mapToList overs
-- | Returns the list of all currently defined interface overloads.
getInterface :: HOL cls thry [(Text, (Text, HOLType))]
getInterface =
do acid <- openLocalStateHOL (Interface [])
iface <- queryHOL acid GetInterfaces
closeAcidStateHOL acid
return iface
{-|
Returns the list of all overloadable symbols paired with their most generic
types.
-}
getOverloads :: HOL cls thry (Map Text HOLType)
getOverloads =
do acid <- openLocalStateHOL (Overload mapEmpty)
ovrlds <- queryHOL acid GetOverload
closeAcidStateHOL acid
return ovrlds
-- Type Abbreviations
{-|
Specifies a 'Text' to act as an abbreviation for a given type in the parser.
Upon recognizing the abbreviation the parser will replace it with the
'PreType' value for it's associated 'HOLType' such that the elaborator can
infer the correct type for polymorphic abbreviations.
-}
newTypeAbbrev :: HOLTypeRep ty Theory thry => Text -> ty -> HOL Theory thry ()
newTypeAbbrev s pty =
do ty <- toHTy pty
acid <- openLocalStateHOL (TypeAbbreviations mapEmpty)
updateHOL acid (InsertTypeAbbreviation s ty)
createCheckpointAndCloseHOL acid
{-|
Specifies a 'Text' for the parser to stop recognizing as a type
abbreviation.
-}
removeTypeAbbrev :: Text -> HOL Theory thry ()
removeTypeAbbrev s =
do acid <- openLocalStateHOL (TypeAbbreviations mapEmpty)
updateHOL acid (RemoveTypeAbbreviation s)
createCheckpointAndCloseHOL acid
{-|
Returns all 'Text's currently acting as type abbreviations in the parser
paired with their associated types.
-}
typeAbbrevs :: HOL cls thry (Map Text HOLType)
typeAbbrevs =
do acid <- openLocalStateHOL (TypeAbbreviations mapEmpty)
abvs <- queryHOL acid GetTypeAbbreviations
closeAcidStateHOL acid
return abvs
-- Hidden Constant Mapping
-- | Specifies a 'Text' for the parser to stop recognizing as a constant.
hideConstant :: Text -> HOL Theory thry ()
hideConstant c =
do acid <- openLocalStateHOL (Hidden [])
updateHOL acid (InsertHidden c)
createCheckpointAndCloseHOL acid
-- | Specifies a 'Text' for the parser to resume recognizing as a constant.
unhideConstant :: Text -> HOL Theory thry ()
unhideConstant c =
do acid <- openLocalStateHOL (Hidden [])
updateHOL acid (RemoveHidden c)
createCheckpointAndCloseHOL acid
-- | Returns all 'Text's currently acting as constants hidden from the parser.
getHidden :: HOL cls thry [Text]
getHidden =
do acid <- openLocalStateHOL (Hidden [])
hids <- queryHOL acid GetHiddens
closeAcidStateHOL acid
return hids
{-|
Specifies a symbol to be recognized as an unspaced, binary operator by the
printer. Applications involving these operators will be built with the '<>'
combinator as opposed to '<+>'.
Note that technically this method should be considered benign, however, for
simplicity of implementation it is defined using 'modifyExt' and thus must be
tagged a 'Theory' computation.
-}
addUnspacedBinop :: Text -> HOL Theory thry ()
addUnspacedBinop op =
do acid <- openLocalStateHOL (UnspacedBinops initUnspaced)
updateHOL acid (InsertUnspaced op)
createCheckpointAndCloseHOL acid
{-|
Specifies a symbol to be recognized as a prebroken, binary operator by the
printer. Applications involving these operators will have their right-hand
side argument printed on the next line using the 'hang' combinator.
Note that technically this method should be considered benign, however, for
simplicity of implementation it is defined using 'modifyExt' and thus must be
tagged a 'Theory' computation.
-}
addPrebrokenBinop :: Text -> HOL Theory thry ()
addPrebrokenBinop op =
do acid <- openLocalStateHOL (PrebrokenBinops initPrebroken)
updateHOL acid (InsertPrebroken op)
createCheckpointAndCloseHOL acid
{-|
Specifies a symbol to stop being recognized as an unspaced, binary operator
by the printer.
Note that technically this method should be considered benign, however, for
simplicity of implementation it is defined using 'modifyExt' and thus must be
tagged a 'Theory' computation.
-}
removeUnspacedBinop :: Text -> HOL Theory thry ()
removeUnspacedBinop op =
do acid <- openLocalStateHOL (UnspacedBinops initUnspaced)
updateHOL acid (RemoveUnspaced op)
createCheckpointAndCloseHOL acid
{-|
Specifies a symbol to stop being recognized as an prebroken, binary operator
by the printer.
Note that technically this method should be considered benign, however, for
simplicity of implementation it is defined using 'modifyExt' and thus must be
tagged a 'Theory' computation.
-}
removePrebrokenBinop :: Text -> HOL Theory thry ()
removePrebrokenBinop op =
do acid <- openLocalStateHOL (PrebrokenBinops initPrebroken)
updateHOL acid (RemovePrebroken op)
createCheckpointAndCloseHOL acid
{-|
Returns the list of all symbols current recognized as unspaced, binary
operators by the printer.
-}
getUnspacedBinops :: HOL cls thry [Text]
getUnspacedBinops =
do acid <- openLocalStateHOL (UnspacedBinops initUnspaced)
ops <- queryHOL acid GetUnspaced
closeAcidStateHOL acid
return ops
{-|
Returns the list of all symbols current recognized as prebroken, binary
operators by the printer.
-}
getPrebrokenBinops :: HOL cls thry [Text]
getPrebrokenBinops =
do acid <- openLocalStateHOL (PrebrokenBinops initUnspaced)
ops <- queryHOL acid GetPrebroken
closeAcidStateHOL acid
return ops
-- Re-exports
-- | A re-export of 'P.runParser'.
runParser :: GenParser st a -> st -> P.SourceName -> Text
-> Either ParseError a
runParser = P.runParser
-- | A re-export of 'P.getState'.
getState :: Monad m => P.ParsecT s u m u
getState = P.getState
-- | A re-export of 'P.setState'.
setState :: Monad m => u -> P.ParsecT s u m ()
setState = P.setState
-- | A re-export of 'P.updateState'.
updateState :: Monad m => (u -> u) -> P.ParsecT s u m ()
updateState = P.updateState