AS_Annotation.der.hs revision f04a144ec0ad002400f820bd857352c2cc7c5e9d
8267b99c0d7a187abe6f87ad50530dc08f5d1cdcAndy Gimblett{- |
8267b99c0d7a187abe6f87ad50530dc08f5d1cdcAndy GimblettModule : $Header$
e071fb22ea9923a2a4ff41184d80ca46b55ee932Till MossakowskiDescription : datastructures for annotations of (Het)CASL.
8267b99c0d7a187abe6f87ad50530dc08f5d1cdcAndy GimblettCopyright : (c) Klaus Luettich, Christian Maeder, and Uni Bremen 2002-2006
8267b99c0d7a187abe6f87ad50530dc08f5d1cdcAndy GimblettLicense : GPLv2 or higher, see LICENSE.txt
8267b99c0d7a187abe6f87ad50530dc08f5d1cdcAndy Gimblett
8267b99c0d7a187abe6f87ad50530dc08f5d1cdcAndy GimblettMaintainer : Christian.Maeder@dfki.de
8267b99c0d7a187abe6f87ad50530dc08f5d1cdcAndy GimblettStability : provisional
8267b99c0d7a187abe6f87ad50530dc08f5d1cdcAndy GimblettPortability : portable
8267b99c0d7a187abe6f87ad50530dc08f5d1cdcAndy Gimblett
8267b99c0d7a187abe6f87ad50530dc08f5d1cdcAndy GimblettDatastructures for annotations of (Het)CASL.
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett There is also a paramterized data type for an 'Annoted' 'item'.
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett See also chapter II.5 of the CASL Reference Manual.
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett-}
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett
2cf5a456da8bb3a2bbb695414d8304426e3bd277Andy Gimblettmodule Common.AS_Annotation where
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblettimport Common.Id
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblettimport Common.IRI (IRI)
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblettimport Data.Maybe
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett-- DrIFT command
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett{-! global: GetRange !-}
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett-- | start of an annote with its WORD or a comment
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblettdata Annote_word = Annote_word String | Comment_start deriving (Show, Eq, Ord)
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett-- | line or group for 'Unparsed_anno'
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblettdata Annote_text = Line_anno String | Group_anno [String]
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett deriving (Show, Eq, Ord)
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett{- | formats to be displayed (may be extended in the future).
020cdb5dad6b871aba61136a0e1567c00426de87Andy GimblettDrop 3 from the show result to get the string for parsing and printing -}
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblettdata Display_format = DF_HTML | DF_LATEX | DF_RTF deriving (Show, Eq, Ord)
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett-- | swap the entries of a lookup table
020cdb5dad6b871aba61136a0e1567c00426de87Andy GimblettswapTable :: [(a, b)] -> [(b, a)]
020cdb5dad6b871aba61136a0e1567c00426de87Andy GimblettswapTable = map $ \ (a, b) -> (b, a)
2cf5a456da8bb3a2bbb695414d8304426e3bd277Andy Gimblett
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett-- | drop the first 3 characters from the show result
020cdb5dad6b871aba61136a0e1567c00426de87Andy GimbletttoTable :: (Show a) => [a] -> [(a, String)]
020cdb5dad6b871aba61136a0e1567c00426de87Andy GimbletttoTable = map $ \ a -> (a, drop 3 $ show a)
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett-- | a lookup table for the textual representation of display formats
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblettdisplay_format_table :: [(Display_format, String)]
2cf5a456da8bb3a2bbb695414d8304426e3bd277Andy Gimblettdisplay_format_table = toTable [ DF_HTML, DF_LATEX, DF_RTF ]
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett{- | lookup the textual representation of a display format
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblettin 'display_format_table' -}
020cdb5dad6b871aba61136a0e1567c00426de87Andy GimblettlookupDisplayFormat :: Display_format -> String
020cdb5dad6b871aba61136a0e1567c00426de87Andy GimblettlookupDisplayFormat df =
2cf5a456da8bb3a2bbb695414d8304426e3bd277Andy Gimblett fromMaybe (error "lookupDisplayFormat: unknown display format")
2cf5a456da8bb3a2bbb695414d8304426e3bd277Andy Gimblett $ lookup df display_format_table
2cf5a456da8bb3a2bbb695414d8304426e3bd277Andy Gimblett
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett{- | precedence 'Lower' means less and 'BothDirections' means less and greater.
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett'Higher' means greater but this is syntactically not allowed in 'Prec_anno'.
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett'NoDirection' can also not be specified explicitly,
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblettbut covers those ids that are not mentionend in precedences. -}
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblettdata PrecRel = Higher | Lower | BothDirections | NoDirection
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett deriving (Show, Eq, Ord)
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett-- | either left or right associative
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblettdata AssocEither = ALeft | ARight deriving (Show, Eq, Ord)
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett{- | semantic (line) annotations without further information.
020cdb5dad6b871aba61136a0e1567c00426de87Andy GimblettUse the same drop-3-trick as for the 'Display_format'. -}
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblettdata Semantic_anno = SA_cons | SA_def | SA_implies | SA_mono | SA_implied
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett | SA_mcons | SA_ccons
020cdb5dad6b871aba61136a0e1567c00426de87Andy Gimblett deriving (Show, Eq, Ord)
-- | a lookup table for the textual representation of semantic annos
semantic_anno_table :: [(Semantic_anno, String)]
semantic_anno_table =
toTable [SA_cons, SA_def, SA_implies, SA_mono, SA_implied, SA_mcons, SA_ccons]
{- | lookup the textual representation of a semantic anno
in 'semantic_anno_table' -}
lookupSemanticAnno :: Semantic_anno -> String
lookupSemanticAnno sa =
fromMaybe (error "lookupSemanticAnno: no semantic anno")
$ lookup sa semantic_anno_table
-- | all possible annotations (without comment-outs)
data Annotation = -- | constructor for comments or unparsed annotes
Unparsed_anno Annote_word Annote_text Range
-- | known annotes
| Display_anno Id [(Display_format, String)] Range
-- position of anno start, keywords and anno end
| List_anno Id Id Id Range
-- position of anno start, commas and anno end
| Number_anno Id Range
-- position of anno start, commas and anno end
| Float_anno Id Id Range
-- position of anno start, commas and anno end
| String_anno Id Id Range
-- position of anno start, commas and anno end
| Prec_anno PrecRel [Id] [Id] Range
{- positions: "{",commas,"}", RecRel, "{",commas,"}"
Lower = "< " BothDirections = "<>" -}
| Assoc_anno AssocEither [Id] Range -- position of commas
| Label [String] Range
-- position of anno start and anno end
| Prefix_anno [(String, IRI)] Range
-- position of anno start and anno end
-- All annotations below are only as annote line allowed
| Semantic_anno Semantic_anno Range
{- position information for annotations is provided
by every annotation -}
deriving (Show, Eq, Ord)
{- | 'isLabel' tests if the given 'Annotation' is a label
(a 'Label' typically follows a formula) -}
isLabel :: Annotation -> Bool
isLabel a = case a of
Label _ _ -> True
_ -> False
isImplies :: Annotation -> Bool
isImplies a = case a of
Semantic_anno SA_implies _ -> True
_ -> False
isImplied :: Annotation -> Bool
isImplied a = case a of
Semantic_anno SA_implied _ -> True
_ -> False
-- | 'isSemanticAnno' tests if the given 'Annotation' is a semantic one
isSemanticAnno :: Annotation -> Bool
isSemanticAnno a = case a of
Semantic_anno _ _ -> True
_ -> False
{- | 'isComment' tests if the given 'Annotation' is a comment line or a
comment group -}
isComment :: Annotation -> Bool
isComment c = case c of
Unparsed_anno Comment_start _ _ -> True
_ -> False
-- | 'isAnnote' is the negation of 'isComment'
isAnnote :: Annotation -> Bool
isAnnote = not . isComment
{- | an item wrapped in preceding (left 'l_annos')
and following (right 'r_annos') annotations.
'opt_pos' should carry the position of an optional semicolon
following a formula (but is currently unused). -}
data Annoted a = Annoted
{ item :: a
, opt_pos :: Range
, l_annos :: [Annotation]
, r_annos :: [Annotation] } deriving (Show, Ord, Eq)
annoRange :: (a -> [Pos]) -> Annoted a -> [Pos]
annoRange f a =
joinRanges $ map (rangeToList . getRange) (l_annos a) ++ [f $ item a]
++ [rangeToList (opt_pos a)] ++ map (rangeToList . getRange) (r_annos a)
notImplied :: Annoted a -> Bool
notImplied = not . any isImplied . r_annos
-- | naming or labelling sentences
data SenAttr s a = SenAttr
{ senAttr :: a
, isAxiom :: Bool
, isDef :: Bool
, wasTheorem :: Bool
{- will be set to True when status of isAxiom
changes from False to True -}
, simpAnno :: Maybe Bool -- for %simp or %nosimp annotations
, attrOrigin :: Maybe Id
, sentence :: s } deriving (Eq, Ord, Show)
-- | equip a sentence with a name
makeNamed :: a -> s -> SenAttr s a
makeNamed a s = SenAttr
{ senAttr = a
, isAxiom = True
, isDef = False
, wasTheorem = False
, simpAnno = Nothing
, attrOrigin = Nothing
, sentence = s }
type Named s = SenAttr s String
reName :: (a -> b) -> SenAttr s a -> SenAttr s b
reName f x = x { senAttr = f $ senAttr x }
-- | extending sentence maps to maps on labelled sentences
mapNamed :: (s -> t) -> SenAttr s a -> SenAttr t a
mapNamed f x = x { sentence = f $ sentence x }
-- | extending sentence maybe-maps to maps on labelled sentences
mapNamedM :: Monad m => (s -> m t) -> Named s -> m (Named t)
mapNamedM f x = do
y <- f $ sentence x
return x {sentence = y}
-- | process all items and wrap matching annotations around the results
mapAnM :: (Monad m) => (a -> m b) -> [Annoted a] -> m [Annoted b]
mapAnM f al =
do il <- mapM (f . item) al
return $ zipWith (flip replaceAnnoted) al il
instance Functor Annoted where
fmap f (Annoted x o l r) = Annoted (f x) o l r
-- | replace the 'item'
replaceAnnoted :: b -> Annoted a -> Annoted b
replaceAnnoted x (Annoted _ o l r) = Annoted x o l r
{- one could use this fmap variant instead (less efficient)
replaceAnnoted x = fmap (const x)
or even:
replaceAnnoted = (<$) -}
-- | add further following annotations
appendAnno :: Annoted a -> [Annotation] -> Annoted a
appendAnno (Annoted x p l r) = Annoted x p l . (r ++)
-- | put together preceding annotations and an item
addLeftAnno :: [Annotation] -> a -> Annoted a
addLeftAnno l i = Annoted i nullRange l []
-- | decorate with no annotations
emptyAnno :: a -> Annoted a
emptyAnno = addLeftAnno []
-- | get the label following (or to the right of) an 'item'
getRLabel :: Annoted a -> String
getRLabel a =
case filter isLabel (r_annos a) of
Label l _ : _ -> unwords $ concatMap words l
_ -> ""
{- | check for an annotation starting with % and the input str
(does not work for known annotation words) -}
identAnno :: String -> Annotation -> Bool
identAnno str an = case an of
Unparsed_anno (Annote_word wrd) _ _ -> wrd == str
_ -> False
-- | test all anntotions for an item
hasIdentAnno :: String -> Annoted a -> Bool
hasIdentAnno str a = any (identAnno str) $ l_annos a ++ r_annos a
makeNamedSen :: Annoted a -> Named a
makeNamedSen a = (makeNamed (getRLabel a) $ item a)
{ isAxiom = notImplied a
, simpAnno = case (hasIdentAnno "simp" a, hasIdentAnno "nosimp" a) of
(True, False) -> Just True
(False, True) -> Just False
_ -> Nothing }
annoArg :: Annote_text -> String
annoArg txt = case txt of
Line_anno str -> str
Group_anno ls -> unlines ls
newtype Name = Name String
instance Show Name where
show (Name s) = s
getAnnoName :: Annoted a -> Name
getAnnoName = Name . foldr (\ an -> case an of
Unparsed_anno (Annote_word wrd) txt _ | wrd == "name" ->
(annoArg txt ++)
_ -> id) "" . l_annos