4632N/ADescription : printing Isabelle entities
4632N/ACopyright : (c) University of Cambridge, Cambridge, England
4632N/A adaption (c) Till Mossakowski, Uni Bremen 2002-2006
4632N/AMaintainer : Christian.Maeder@dfki.de
4632N/APrinting functions for Isabelle logic.
4632N/AprintIsaTheory :: String -> Sign -> [Named Sentence] -> Doc
4632N/AprintIsaTheory tn sign sens = let
4632N/A in text theoryS <+> text tn
4632N/A $+$ text importsS <+> fsep ((if case b of
4632N/A _ -> True then doubleQuotes $ text $ ld ++ bs else text bs)
4632N/A : map (doubleQuotes . text) (imports sign))
4632N/A $++$ printTheoryBody sign sens
4632N/AprintTheoryBody :: Sign -> [Named Sentence] -> Doc
4632N/A let (sens',recFuns) = findTypesForRecFuns sens (constTab sig)
4632N/A in callSetup "initialize" (brackets $ sepByCommas
4632N/A $ map (text . show . Quote . senAttr)
4632N/A $ filter (\ s -> not (isConstDef s || isRecDef s || isInstance s)
4632N/A $++$ printNamedSentences sens'
4632N/AfindTypesForRecFuns :: [Named Sentence] -> ConstTab
4632N/A -> ([Named Sentence], [String])
4632N/AfindTypesForRecFuns ns ctab =
4632N/A let (sens,recFuns') = unzip $ map (\ sen ->
4632N/A RecDef kw cName cType tm ->
4632N/A RecDef kw cName (Just t) tm
4632N/A if t /= t' then error "recFun: two types given"
4632N/A _ -> (sentence sen,Nothing)
4632N/A in (sen {sentence=sen'},recFns')) ns
4632N/A in (sens,map new $ catMaybes recFuns')
4632N/AprintNamedSentences :: [Named Sentence] -> Doc
4632N/AprintNamedSentences sens = case sens of
4632N/A let (axs, rest) = span isAxiom sens in
4632N/A text axiomsS $+$ vsep (map printNamedSen axs)
4632N/A $++$ vcat (map ( \ a -> text declareS <+> text (senAttr a)
4632N/A $ filter ( \ a -> case sentence a of
4632N/A b@Sentence {} -> isSimp b && senAttr a /= ""
4632N/A $++$ printNamedSentences rest
4632N/A let (defs, rest) = span isConstDef sens in
4632N/A text defsS $+$ vsep (map printNamedSen defs)
4632N/A $++$ printNamedSentences rest
4632N/A printNamedSen s $++$ (case senAttr s of
4632N/A n | n == "" || isRecDef s -> empty
4632N/A | otherwise -> callSetup "record" (text $ show $ Quote n))
4632N/AcallSetup :: String -> Doc -> Doc
4632N/A text "setup" <+> doubleQuotes (fsep [text ("Header." ++ fun), args])
4632N/Adata QuotedString = Quote String
4632N/Ainstance Show QuotedString where
4632N/A show (Quote s) = init . tail . show $ show s
4632N/AgetAxioms :: [Named Sentence] -> ([Named Sentence], [Named Sentence])
4632N/AgetAxioms = partition isIsaAxiom
4632N/AisIsaAxiom :: Named Sentence -> Bool
4632N/AisIsaAxiom s = case sentence s of
4632N/AisInstance :: Named Sentence -> Bool
4632N/AisInstance s = case sentence s of
4632N/AisConstDef :: Named Sentence -> Bool
4632N/AisConstDef s = case sentence s of
4632N/AisRecDef :: Named Sentence -> Bool
4632N/AisRecDef s = case sentence s of
4632N/A-- --------------------- Printing functions -----------------------------
4632N/AshowBaseSig :: BaseSig -> String
4632N/AshowBaseSig = takeWhile (/= '_') . show
4632N/AprintClass :: IsaClass -> Doc
4632N/AprintClass (IsaClass x) = text x
4632N/AprintSort = printSortAux False
4632N/AprintSortAux :: Bool -> Sort -> Doc
4632N/AprintSortAux b l = case l of
4632N/A _ -> (if b then doubleQuotes else id)
4632N/A . braces . hcat . punctuate comma $ map printClass l
4632N/Adata SynFlag = Quoted | Unquoted | Null
4632N/Abar = punctuate $ space <> text "|"
4632N/AprintType = printTyp Unquoted
4632N/AprintTyp :: SynFlag -> Typ -> Doc
4632N/AprintTyp a = fst . printTypeAux a
4632N/AprintTypeAux :: SynFlag -> Typ -> (Doc, Int)
4632N/AprintTypeAux a t = case t of
4632N/A d = text $ if isPrefixOf "\'" v || isPrefixOf "?\'" v
4632N/A in if null s then d else case a of
4632N/A Quoted -> d <> doubleColon <> if null
4632N/A $ tail s then c else doubleQuotes c
4632N/A Unquoted -> d <> doubleColon <> c
4632N/A TVar iv s -> printTypeAux a $ TFree (unindexed iv) s
4632N/A Type name _ args -> case args of
4632N/A [t1, t2] | elem name [prodS, sProdS, funS, cFunS, lFunS, sSumS] ->
4632N/A [arg] -> let (d, i) = printTypeAux a arg in
if i < 1000 then parens d else d
_ -> parens $ hsep $ punctuate comma $
map (fst . printTypeAux a) args)
printTypeOp :: SynFlag -> TName -> Typ -> Typ -> (Doc, Int)
printTypeOp x name r1 r2 =
let (d1, i1) = printTypeAux x r1
(d2, i2) = printTypeAux x r2
d3 = if i1 < l then parens d1 else d1
d4 = if i2 < r then parens d2 else d2
in (d3 <+> text name <+> d4, r)
and_docs ds = vcat $ prepPunctuate (text andS <> space) ds
-- | printing a named sentence
printNamedSen :: Named Sentence -> Doc
_ -> let dd = doubleQuotes d in
if isRefute s then text lemmaS <+> text lab <+> colon
else if null lab then dd else fsep [ (case s of
ConstDef {} -> text $ lab ++ "_def"
(if b then empty else text theoremS)
<+> text lab <+> (if b then text "[rule_format]" else
if isSimp s then text "[simp]" else empty)
_ -> error "printNamedSen") <+> colon, dd] $+$ case s of
Sentence {} -> if b then empty else case thmProof s of
printSentence :: Sentence -> Doc
printSentence s = case s of
TypeDef nt td pr -> text typedefS
<+> doubleQuotes (printSetDecl td)
RecDef kw cName cType xs ->
let preparedEq = map (doubleQuotes . printTerm) xs
map (<+> text barS) (init preparedEq) ++ [last preparedEq]
Just t -> doubleColon <+> doubleQuotes (printType t)
in kw' <+> text (new cName) <+> tp <+> printAlt cName <+> text whereS $+$
Instance { tName = t, arityArgs = args, arityRes = res, definitions = defs,
text instantiationS <+> text t <> doubleColon <> (case args of
_ -> parens $ hsep $ punctuate comma $ map (printSortAux True) args)
<+> printSortAux True res $+$ text beginS $++$ printDefs defs $++$
text instanceS <+> pretty prf $+$ text endS
where printDefs :: [(String, Term)] -> Doc
printDefs defs' = vcat (map printDef defs')
printDef :: (String, Term) -> Doc
printNamedSen (makeNamed name (ConstDef def))
Sentence { isRefuteAux = b, metaTerm = t } -> printPlainMetaTerm (not b) t
ConstDef t -> printTerm t
Lemmas name lemmas -> if null lemmas
then empty {- only have this lemmas if we have some in
else text lemmasS <+> text name <+>
equals <+> sep (map text lemmas)
printSetDecl :: SetDecl -> Doc
SubSet v t f -> braces $ printTerm v <> doubleColon <> printType t <> dot
FixedSet elems -> braces $ sepByCommas $ map printTerm elems
printPlainMetaTerm :: Bool -> MetaTerm -> Doc
printPlainMetaTerm b mt = case mt of
Term t -> printPlainTerm b t
Conditional conds t -> sep
<+> fsep (punctuate semi $ map printTerm conds)
, text metaImplS <+> printTerm t ]
printTerm = printPlainTerm True
printPlainTerm :: Bool -> Term -> Doc
printPlainTerm b = fst . printTrm b
-- | print parens but leave a space if doc starts or ends with a bar
parensForTerm :: Doc -> Doc
in parens $ if null s then d
else (if head s == b then (space <>) else id)
((if last s == b then (<> space) else id) d)
printParenTerm :: Bool -> Int -> Term -> Doc
printParenTerm b i t = case printTrm b t of
(d, j) -> if j < i then parensForTerm d else d
flatTuplex :: [Term] -> Continuity -> [Term]
flatTuplex cs c = case cs of
Tuplex rs@(_ : _ : _) d | d == c -> init cs ++ flatTuplex rs d
printMixfixAppl :: Bool -> Continuity -> Term -> [Term] -> (Doc, Int)
printMixfixAppl b c f args = case f of
Const (VName n (Just (AltSyntax s is i))) (Hide _ _ _) ->
if length is == length args &&
(b || n == cNot || isPrefixOf "op " n) then
(fsep $ replaceUnderlines s
$ zipWith (printParenTerm b) is args, i)
Const vn _ | new vn `elem` [allS, exS, ex1S] -> case args of
[Abs v t _] -> (fsep [text (new vn) <+> printPlainTerm False v
, printPlainTerm b t], lowPrio)
App g a d | c == d -> printMixfixAppl b c g (a : args)
-- | print the term using the alternative syntax (if True)
printTrm :: Bool -> Term -> (Doc, Int)
printTrm b trm = case trm of
Disp w _ _ -> parens $ dvn <+> doubleColon <+> printType w
Nothing -> (nvn, maxPrio)
Just (AltSyntax s is i) -> if b && null is then
(fsep $ replaceUnderlines s [], i) else (nvn, maxPrio)
Free vn -> (text $ new vn, maxPrio)
Abs v t c -> (text (case c of
IsCont _ -> "Lam") <+> printPlainTerm False v <> dot
<+> printPlainTerm b t, lowPrio)
If i t e c -> let d = fsep [printPlainTerm b i,
NotCont -> (text "if" <+> d, lowPrio)
IsCont _ -> (text "IF" <+> d <+> text "FI", maxPrio)
Case e ps -> (text "case" <+> printPlainTerm b e <+> text "of"
$+$ vcat (bar $ map (\ (p, t) ->
fsep [ printPlainTerm b p <+> text "=>"
, printParenTerm b (lowPrio + 1) t]) ps), lowPrio)
Let es i -> (fsep [text "let" <+>
map (\ (p, t) -> fsep [ printPlainTerm b p <+> equals
, printPlainTerm b t]) es)
, text "in" <+> printPlainTerm b i], lowPrio)
(fsep [ printParenTerm b (isaEqPrio + 1) t1 <+> isaEquals
, printParenTerm b isaEqPrio t2], isaEqPrio)
NotCont -> (parensForTerm
$ sepByCommas (map (printPlainTerm b)
[] -> error "IsaPrint, printTrm"
a : aa -> printTrm b $ App (App
lpairTerm a $ IsCont False)
(Tuplex aa c) (IsCont False)
App f a c -> printMixfixAppl b c f [a]
Set setdecl -> (printSetDecl setdecl, lowPrio)
printApp :: Bool -> Continuity -> Term -> [Term] -> (Doc, Int)
printApp b c t l = case l of
_ -> printDocApp b c (printParenTerm b (maxPrio - 1) t) l
printDocApp :: Bool -> Continuity -> Doc -> [Term] -> (Doc, Int)
IsCont True -> punctuate $ text " $$"
IsCont False -> punctuate $ text " $")
$ d : map (printParenTerm b maxPrio) l
replaceUnderlines :: String -> [Doc] -> [Doc]
replaceUnderlines str l = case str of
'\'' : r@(q : s) -> if q `elem` "_/'()"
then consDocBarSep (text [q]) $ replaceUnderlines s l
else consDocBarSep (text "'") $ replaceUnderlines r l
h : t -> consDocBarSep h $ replaceUnderlines r t
_ -> error "replaceUnderlines"
'/' : ' ' : r -> empty : replaceUnderlines r l
q : r -> if q `elem` "()/" then replaceUnderlines r l
else consDocBarSep (text [q]) $ replaceUnderlines r l
consDocBarSep :: Doc -> [Doc] -> [Doc]
consDocBarSep d r = case r of
in if null hs || null ds then (d <> h) : t else
if hhs == b && lds == '(' || last ds == b && hhs == ')'
printLocales :: Locales -> Doc
printLocales = vsep . map printLocale . orderLDecs .
Map.toListprintLocale :: (String,LocaleDecl) -> Doc
printLocale (n,(parents,in_ax,ex_ax,params)) =
a = map (\ (s,t) -> text s <+> text ":"
<+> (doubleQuotes . printTerm) t) in_ax
else (head a):(map (text "and" <+>) (tail a))
f = map (\ (s,t,alt) -> text s <+> text "::"
<+> (doubleQuotes . (printTyp Null)) t
Just (AltSyntax s' [i1,i2] i) -> parens ((
if i1==i2 then text "infix "
else if i1 < i2 then text "infixr "
else text "infixl ") <+> doubleQuotes (text s')
else (head f):(map (text "and" <+>) (tail f))
vcat [text "locale" <+> text n <+>
(if length (p'++a'++f') > 0
then text "=" else empty) <+>
hsep p' <+> if length p' > 0 &&
(length a' > 0 || length f' > 0)
then text "+" else empty,
(if length f' > 0 then text "fixes" else empty) <+> vcat f',
(if length a' > 0 then text "assumes" else empty) <+> vcat a'],
vcat (map (\ (s,t) -> text ("theorem (in "++ n ++")")
<+> (doubleQuotes . printTerm) t) ex_ax)]
printClassrel :: Classrel -> Doc
printClassrel = vsep . map printClassR . orderCDecs .
Map.toListprintClassR :: (IsaClass,ClassDecl) -> Doc
printClassR (y, (parents, assumptions,fixes)) =
let a = map (\ (s,t) -> text s <+> text ":"
<+> (doubleQuotes . printTerm) t) assumptions
else (head a):(map (text "and" <+>) (tail a))
f = map (\ (s,t) -> text s <+> text "::"
<+> (doubleQuotes . (printTyp Null)) t) fixes
else (head f):(map (text "and" <+>) (tail f))
parents' = filter (\ (IsaClass s) -> not $ elem s
in vcat [text "class" <+> printClass y <+>
(if length (p'++a'++f') > 0 then text "=" else empty)
<+> hsep p' <+> if length p' > 0 &&
(length a' > 0 || length f' > 0)
then text "+" else empty,
(if length f' > 0 then text "fixes" else empty) <+> vcat f',
(if length a' > 0 then text "assumes" else empty) <+> vcat a']
orderCDecs :: [(IsaClass,ClassDecl)] -> [(IsaClass,ClassDecl)]
crord (_,(cs,_,_)) (c,_) = elem c cs
orderLDecs :: [(String,LocaleDecl)] -> [(String,LocaleDecl)]
crord (_,(cs,_,_,_)) (c,_) = elem c cs
printMonArities :: String -> Arities -> Doc
printMonArities tn = vcat . map ( \ (t, cl) ->
printThMorp :: String -> TName -> (IsaClass, [(Typ, Sort)]) -> Doc
printThMorp tn t xs = case xs of
if isSuffixOf "_mh" tn || isSuffixOf "_mhc" tn
else error "IsaPrint, printInstance: monads not supported"
printMInstance :: String -> TName -> Doc
printMInstance tn t = let nM = text (t ++ "_tm")
in prnThymorph nM "MonadType" tn t [("
MonadType.M", "'a")] []
$+$ text "t_instantiate MonadOps mapping" <+> nM
brackMapList (\ x -> t ++ "_" ++ x)
$+$ text "without_syntax"
$+$ text (t ++ "_eta_def:") <+> doubleQuotes
(text (t ++ "_eta") <+> isaEquals <+> text ("return_" ++ t))
$+$ text (t ++ "_bind_def:") <+> doubleQuotes
(text (t ++ "_bind") <+> isaEquals <+> text ("mbind_" ++ t))
$++$ prnThymorph nM2 "MonadAxms" tn t [("
MonadType.M", "'a")]
$+$ text "t_instantiate Monad mapping" <+> nM2
brackMapList (\ x -> t ++ "_" ++ x)
$+$ text "without_syntax"
lunitLemma w = text lemmaS <+> text (w ++ "_lunit:")
<+> doubleQuotes (text (w ++ "_bind")
<+> parens (text (w ++ "_eta x"))
<+> parens (text $ "t::'a => 'b " ++ w)
<+> equals <+> text "t x")
runitLemma w = text lemmaS <+> text (w ++ "_runit:")
<+> doubleQuotes (text (w ++ "_bind")
<+> parens (text $ "t::'a " ++ w) <+> text (w ++ "_eta")
assocLemma w = text lemmaS <+> text (w ++ "_assoc:")
<+> doubleQuotes (text (w ++ "_bind")
<+> parens (text (w ++ "_bind")
<+> parens (text $ "s::'a " ++ w) <+> text "t") <+> text "u"
<+> equals <+> text (w ++ "_bind s")
<+> parens (text "%x." <+>
text (w ++ "_bind") <+> text "(t x) u"))
etaInjLemma w = text lemmaS <+> text (w ++ "_eta_inj:")
<+> doubleQuotes (parens (text $ w ++ "_eta::'a => 'a " ++ w)
<+> equals <+> text (w ++ "_eta y")
<+> text "==>" <+> text "x = y")
prnThymorph :: Doc -> String -> String -> TName -> [(String, String)]
-> [(String, String)] -> Doc
prnThymorph nm xn tn t ts ws = let qual s = tn ++ "." ++ s in
text "thymorph" <+> nm <+> colon <+>
text xn <+> cfun <+> text tn
$+$ text " maps" <+> brackets
(hcat [ parens $ doubleQuotes (text b <+> text a) <+> mapsto
<+> doubleQuotes (text b <+> text (qual t))
brackMapList :: (String -> String) -> [(String, String)] -> Doc
brackMapList f ws = brackets $ hsep $ punctuate comma
[ parens $ doubleQuotes (text a) <+> mapsto <+> doubleQuotes (text $ f b)
-- filter out types that are given in the domain table
printTypeDecls :: BaseSig -> DomainTab -> Arities -> Doc
printTypeDecls bs odt ars =
let dt =
Map.fromList $ map (\ (t, _) -> (typeId t, [])) $ concat odt
printTycon :: BaseSig -> (TName, [(IsaClass, [(Typ, Sort)])]) -> Doc
printTycon bs (t, arity') = case arity' of
(if null rs then empty else
parens $ hsep $ punctuate comma
$ map (text . ("'a" ++) . show . snd) $ number rs) <+> text t
-- | show alternative syntax (computed by comorphisms)
printAlt (VName _ altV) = case altV of
Just (AltSyntax s is i) -> parens $ doubleQuotes (text s)
<+> if null is then empty else text (show is) <+>
if i == maxPrio then empty else text (show i)
instance Pretty Sign where
-- | a dummy constant table with wrong types
constructors :: DomainTab -> ConstTab
. concatMap (map fst . snd) . concat
printMonSign :: Sign -> Doc
printMonSign sig = let ars = arities $ tsig sig
printMonArities (theoryName sig) ars
printSign sig = let dt = ordDoms $ domainTab sig
printAbbrs (abbrs $ tsig sig) $++$
printTypeDecls (baseSig sig) dt ars $++$
printLocales (locales $ tsig sig) $++$
printClassrel (classrel $ tsig sig) $++$
then showCaseLemmata dt else empty)
printAbbrs tab = if
Map.null tab then empty else text typesS
printAbbr (n, (vs, t)) = case vs of
_ -> parens $ hsep $ punctuate comma $
<+> text n <+> equals <+> doubleQuotes (printType t)
printConstTab tab = if
Map.null tab then empty else text constsS
printConst (vn, t) = text (new vn) <+> doubleColon <+>
doubleQuotes (printType t) <+> printAlt vn
isDomain = case baseSig sig of
printDomainDefs dtDefs = vcat $ map printDomainDef dtDefs
printDomainDef dts = if null dts then empty else
text (if isDomain then domainS else datatypeS)
<+> and_docs (map printDomain dts)
printTyp (if isDomain then Quoted else Null) t <+> equals <+>
fsep (bar $ map printDOp ops)
printDOp (vn, args) = let opname = new vn in
text (if any isSpace opname then show opname else opname)
<+> hsep (map (printDOpArg opname) $ number args)
printDOpArg o (a, i) = let
TFree _ _ -> printTyp Null a
_ -> doubleQuotes $ printTyp Null a
text (o ++ "_" ++ show i) <> doubleColon <> d
showCaseLemmata dtDefs = text (concatMap showCaseLemmata1 dtDefs)
showCaseLemmata1 = concatMap showCaseLemma
showCaseLemma (_, []) = ""
showCaseLemma (tyCons, c : cns) =
let cs = "case caseVar of" ++ sp
sc b = showCons b c ++ concatMap ((" | " ++) . showCons b) cns
showCons b (VName {new = cName}, args) =
let pat = cName ++ concatMap ((sp ++) . showArg) args
term = showCaseTerm cName args
if b then pat ++ "Some" ++ sp ++ lb ++ term ++ rb ++ "\n"
showCaseTerm name args = case name of
where sa = concatMap ((sp ++) . showArg) args
showArg (TFree [] _) = "varName"
showArg (TFree (n : ns) _) = toLower n : ns
showArg (TVar v s) = showArg (TFree (unindexed v) s)
showArg (Type [] _ _) = "varName"
showArg (Type m@(n : ns) _ s) =
if elem m ["typeAppl", "fun", "*"]
showName (TVar v _) = unindexed v
showName (Type n _ _) = n
proof' = "apply (case_tac caseVar)\napply (auto)\ndone\n"
lemmaS ++ sp ++ "case_" ++ showName tyCons ++ "_SomeProm" ++ sp
++ "[simp]:\"" ++ sp ++ lb ++ cs ++ clSome ++ rb ++ sp
++ "=\n" ++ "Some" ++ sp ++ lb ++ cs ++ cl ++ rb ++ "\"\n"
instance Pretty Sentence where
-- Pretty printing of proofs
instance Pretty IsaProof where
printIsaProof :: IsaProof -> Doc
printIsaProof (IsaProof p e) = fsep $ map pretty p ++ [pretty e]
instance Pretty ProofCommand where
pretty = printProofCommand
printProofCommand :: ProofCommand -> Doc
let plusDoc = if plus then text "+" else empty
in text applyS <+> parens
(sepByCommas $ map pretty pms) <> plusDoc
Using ls -> text usingS <+> fsep (map text ls)
Defer x -> text deferS <+> pretty x
Prefer x -> text preferS <+> pretty x
instance Pretty ProofEnd where
printProofEnd :: ProofEnd -> Doc
By pm -> text byS <+> parens (pretty pm)
instance Pretty Modifier where
printModifier :: Modifier -> Doc
No_asm_simp -> text "no_asm_simp"
No_asm_use -> text "no_asm_use"
instance Pretty ProofMethod where
pretty = printProofMethod
printProofMethod :: ProofMethod -> Doc
AutoSimpAdd m names -> let modDoc = case m of
Just mod' -> parens $ pretty mod'
in fsep $ [text autoS, text simpS, modDoc,
text "add:"] ++ map text names
SimpAdd m names -> let modDoc = case m of
Just mod' -> parens $ pretty mod'
in fsep $ [text simpS, modDoc, text "add:"] ++
Induct var -> text inductS <+> doubleQuotes (printTerm var)
CaseTac t -> text caseTacS <+> doubleQuotes (printTerm t)
SubgoalTac t -> text subgoalTacS <+> doubleQuotes (printTerm t)
Insert ts -> fsep (text insertS : map text ts)