Print.hs revision a921ae1da1302f673204e7b63cdce01439a9bd5e
bbae6e6ca0de7f2ffbb44d2c8da179f2b717237fChristian Maeder{- |
bbae6e6ca0de7f2ffbb44d2c8da179f2b717237fChristian MaederModule : $Header$
bbae6e6ca0de7f2ffbb44d2c8da179f2b717237fChristian MaederCopyright : (c) Heng Jiang, Uni Bremen 2005-2006
97018cf5fa25b494adffd7e9b4e87320dae6bf47Christian MaederLicense : GPLv2 or higher, see LICENSE.txt
bbae6e6ca0de7f2ffbb44d2c8da179f2b717237fChristian Maeder
b4fbc96e05117839ca409f5f20f97b3ac872d1edTill MossakowskiMaintainer : Christian.Maeder@dfki.de
bbae6e6ca0de7f2ffbb44d2c8da179f2b717237fChristian MaederStability : provisional
bbae6e6ca0de7f2ffbb44d2c8da179f2b717237fChristian MaederPortability : portable
f3a94a197960e548ecd6520bb768cb0d547457bbChristian Maeder
bbae6e6ca0de7f2ffbb44d2c8da179f2b717237fChristian MaederPretty printing for OWL 2 DL theories.
bbae6e6ca0de7f2ffbb44d2c8da179f2b717237fChristian Maeder-}
bbae6e6ca0de7f2ffbb44d2c8da179f2b717237fChristian Maeder
bbae6e6ca0de7f2ffbb44d2c8da179f2b717237fChristian Maedermodule OWL2.Print ({-printOWLBasicTheory,-} printAxiom) where
bbae6e6ca0de7f2ffbb44d2c8da179f2b717237fChristian Maeder
bbae6e6ca0de7f2ffbb44d2c8da179f2b717237fChristian Maederimport Common.AS_Annotation
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maederimport Common.Doc
ee9eddfa6953868fd6fbaff0d9ff68675a13675aChristian Maederimport Common.DocUtils
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maederimport Common.Id
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maederimport Common.Keywords
bbae6e6ca0de7f2ffbb44d2c8da179f2b717237fChristian Maeder
bbae6e6ca0de7f2ffbb44d2c8da179f2b717237fChristian Maederimport OWL2.AS
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maederimport OWL.Keywords
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maederimport OWL.ColonKeywords
ee9eddfa6953868fd6fbaff0d9ff68675a13675aChristian Maeder
bbae6e6ca0de7f2ffbb44d2c8da179f2b717237fChristian Maederimport qualified Data.Set as Set
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maederimport qualified Data.Map as Map
33a5d53a412ba0a4e5847f7538d6da2e22bd116cChristian Maeder
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maeder
e774ab5733a1d673b123b0e63b14dd533e6fd4fcChristian Maederinstance Pretty QName where
bbae6e6ca0de7f2ffbb44d2c8da179f2b717237fChristian Maeder pretty = printURIreference
b645cf3dc1e449038ed291bbd11fcc6e02b2fc7fChristian Maeder
ebcaad207cafc89eeb49d431f40de2ef4c48411cChristian MaederprintURIreference :: QName -> Doc
b645cf3dc1e449038ed291bbd11fcc6e02b2fc7fChristian MaederprintURIreference q =
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maeder (if localPart q == "Thing" && elem (namePrefix q) ["", "owl"]
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maeder then keyword else text) $ showQN q
b645cf3dc1e449038ed291bbd11fcc6e02b2fc7fChristian Maeder
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maederinstance Pretty SymbItems where
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maeder pretty (SymbItems m us) = maybe empty (keyword . show) m
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maeder <+> ppWithCommas us
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maeder
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maederinstance Pretty SymbMapItems where
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maeder pretty (SymbMapItems m us) = maybe empty (keyword . show) m
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maeder <+> sepByCommas
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maeder (map (\ (s, ms) -> sep
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maeder [ pretty s
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maeder , case ms of
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maeder Nothing -> empty
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maeder Just t -> mapsto <+> pretty t]) us)
38775225cf810f5895cc03b4acbcfe8f84f2513aChristian Maeder
ccf3de3d66b521a260e5c22d335c64a48e3f0195Christian Maederinstance GetRange RawSymb -- no position by default
ccf3de3d66b521a260e5c22d335c64a48e3f0195Christian Maeder
ccf3de3d66b521a260e5c22d335c64a48e3f0195Christian Maederinstance Pretty RawSymb where
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder pretty rs = case rs of
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder ASymbol e -> pretty e
dfa74d066ea0f00a70276aedecc624c6b3c86deaChristian Maeder AnUri u -> pretty u
ccf3de3d66b521a260e5c22d335c64a48e3f0195Christian Maeder
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maederinstance Pretty Entity where
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maeder pretty (Entity ty e) = keyword (show ty) <+> pretty e
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maeder
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian MaedercardinalityType :: CardinalityType -> Doc
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian MaedercardinalityType = keyword . showCardinalityType
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maeder
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian MaederquantifierType :: QuantifierType -> Doc
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian MaederquantifierType = keyword . showQuantifierType
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maeder
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian MaederprintIndividual :: Individual -> Doc
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian MaederprintIndividual ind =
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maeder case ind of
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maeder NamedInd n -> pretty n
d17834302eaa101395b4b806cd73670fd864445fChristian Maeder AnonymousIndividual a -> pretty a
ccf3de3d66b521a260e5c22d335c64a48e3f0195Christian Maeder
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maederinstance Pretty Individual where
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder pretty = printIndividual
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maederinstance Pretty ClassExpression where
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder pretty desc = case desc of
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder Expression ocUri -> printURIreference ocUri
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maeder ObjectJunction ty ds -> let
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maeder (k, p) = case ty of
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maeder UnionOf -> (orS, pretty)
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maeder IntersectionOf -> (andS, printPrimary)
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maeder in fsep $ prepPunctuate (keyword k <> space) $ map p ds
715ffaf874309df081d1e1cd8e05073fc1227729Christian Maeder ObjectComplementOf d -> keyword notS <+> printNegatedPrimary d
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maeder ObjectOneOf indUriList -> specBraces $ ppWithCommas indUriList
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maeder ObjectValuesFrom ty opExp d ->
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maeder printObjPropExp opExp <+> quantifierType ty <+> printNegatedPrimary d
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maeder ObjectHasSelf opExp ->
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder printObjPropExp opExp <+> keyword selfS
836e72a3c413366ba9801726f3b249c7791cb9caChristian Maeder ObjectHasValue opExp indUri ->
836e72a3c413366ba9801726f3b249c7791cb9caChristian Maeder pretty opExp <+> keyword valueS <+> pretty indUri
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maeder ObjectCardinality (Cardinality ty card opExp maybeDesc) ->
7dec34aee2b609b9535c48d060e0f7baf3536457Christian Maeder printObjPropExp opExp <+> cardinalityType ty
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder <+> text (show card)
7dec34aee2b609b9535c48d060e0f7baf3536457Christian Maeder <+> maybe (keyword "owl:Thing") printPrimary maybeDesc
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maeder DataValuesFrom ty dpExp dpExpList dRange ->
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maeder printURIreference dpExp <+> quantifierType ty
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maeder <+> (if null dpExpList then empty
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maeder else specBraces $ ppWithCommas dpExpList) <+> pretty dRange
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder DataHasValue dpExp cons -> pretty dpExp <+> keyword valueS <+> pretty cons
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maeder DataCardinality (Cardinality ty card dpExp maybeRange) ->
bbae6e6ca0de7f2ffbb44d2c8da179f2b717237fChristian Maeder pretty dpExp <+> cardinalityType ty <+> text (show card)
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maeder <+> maybe empty pretty maybeRange
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian MaederprintPrimary :: ClassExpression -> Doc
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian MaederprintPrimary d = let dd = pretty d in case d of
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maeder ObjectJunction _ _ -> parens dd
797f811e57952d59e73b8cd03b667eef276db972Christian Maeder _ -> dd
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maeder
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian MaederprintNegatedPrimary :: ClassExpression -> Doc
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian MaederprintNegatedPrimary d = let r = parens $ pretty d in case d of
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maeder ObjectComplementOf _ -> r
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maeder ObjectValuesFrom _ _ _ -> r
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maeder DataValuesFrom _ _ _ _ -> r
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maeder ObjectHasValue _ _ -> r
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maeder DataHasValue _ _ -> r
bbae6e6ca0de7f2ffbb44d2c8da179f2b717237fChristian Maeder _ -> printPrimary d
ccf3de3d66b521a260e5c22d335c64a48e3f0195Christian Maeder
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maederinstance Pretty ObjectPropertyExpression where
d17834302eaa101395b4b806cd73670fd864445fChristian Maeder pretty = printObjPropExp
e1839fb37a3a2ccd457464cb0dcc5efd466dbe22Christian Maeder
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian MaederprintObjPropExp :: ObjectPropertyExpression -> Doc
e774ab5733a1d673b123b0e63b14dd533e6fd4fcChristian MaederprintObjPropExp obExp =
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maeder case obExp of
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maeder ObjectProp ou -> pretty ou
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder ObjectInverseOf iopExp -> keyword inverseS <+> printObjPropExp iopExp
7dec34aee2b609b9535c48d060e0f7baf3536457Christian Maeder
7dec34aee2b609b9535c48d060e0f7baf3536457Christian Maederinstance Pretty DataRange where
1738d16957389457347bee85075d3d33d002158fChristian Maeder pretty = printDataRange
1738d16957389457347bee85075d3d33d002158fChristian Maeder
1738d16957389457347bee85075d3d33d002158fChristian MaederprintDataRange :: DataRange -> Doc
33a5d53a412ba0a4e5847f7538d6da2e22bd116cChristian MaederprintDataRange dr = case dr of
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder DataType du -> pretty du
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maeder DataComplementOf drange -> keyword notS <+> pretty drange
2a598ff0c1b7b51c33aee7029b43bc5cfcbea6b8Christian Maeder DataOneOf constList -> specBraces $ ppWithCommas constList
0f67ca7b0c738a28f6688ba6e96d44d7c14af611Christian Maeder DatatypeRestriction dtype l -> pretty dtype <+>
c70d42540b8f8c3c141cc0779599d25f7eb69bbfChristian Maeder if null l then empty else brackets $ sepByCommas $ map printFV l
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maeder DataIntersectionOrUnionOf ty drlist -> let
b645cf3dc1e449038ed291bbd11fcc6e02b2fc7fChristian Maeder k = case ty of
5e26bfc8d7b18cf3a3fa7b919b4450fb669f37a5Christian Maeder UnionOf -> orS
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder IntersectionOf -> andS
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder in fsep $ prepPunctuate (keyword k <> space) $ map pretty drlist
88ece6e49930670e8fd3ee79c89a2e918d2fbd0cChristian Maeder
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian MaederprintFV ::(ConstrainingFacet, RestrictionValue) -> Doc
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian MaederprintFV (facet, restValue) = pretty facet <+> pretty restValue
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder
88ece6e49930670e8fd3ee79c89a2e918d2fbd0cChristian Maederinstance Pretty DatatypeFacet where
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder pretty = keyword . showFacet
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maederinstance Pretty Literal where
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder pretty (Literal lexi ty) =
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder text (case lexi of
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder '"' : _ -> lexi
88ece6e49930670e8fd3ee79c89a2e918d2fbd0cChristian Maeder _ -> show lexi) <> case ty of
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder Typed u -> keyword cTypeS <> pretty u
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder Untyped tag -> if tag == Nothing then empty else
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder let Just tag2 = tag in text asP <> text tag2
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maederinstance Pretty Axiom where
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder pretty = printAxiom
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian MaederprintEquivOrDisjoint :: EquivOrDisjoint -> Doc
88ece6e49930670e8fd3ee79c89a2e918d2fbd0cChristian MaederprintEquivOrDisjoint = keyword . showEquivOrDisjoint
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian MaederprintObjDomainOrRange :: ObjDomainOrRange -> Doc
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian MaederprintObjDomainOrRange = keyword . showObjDomainOrRange
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian MaederprintDataDomainOrRange :: DataDomainOrRange -> Doc
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian MaederprintDataDomainOrRange dr = case dr of
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder DataDomain d -> keyword domainC <+> pretty d
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder DataRange d -> keyword rangeC <+> pretty d
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian Maeder
1d589334ba6b4a4cbfb35307a7a732261e77b0cdChristian MaederprintSameOrDifferent :: SameOrDifferent -> Doc
88ece6e49930670e8fd3ee79c89a2e918d2fbd0cChristian MaederprintSameOrDifferent = keyword . showSameOrDifferent
aff01ee50b66032469c232e00c945d1fd4f57d1bChristian Maeder
printAssertion :: (Pretty a, Pretty b) => Assertion a b -> Doc
printAssertion (Assertion a p s b) = indStart <+> pretty s $+$
let d = fsep [pretty a, pretty b] in
keyword factsC <+> case p of
Positive -> d
Negative -> keyword notS <+> d
printAxiom :: Axiom -> Doc
printAxiom axiom = case axiom of
EntityAnno _ -> empty -- EntityAnnotation
PlainAxiom _ paxiom -> case paxiom of
SubClassOf sub super -> case super of
Expression curi
| localPart curi == "Thing" && namePrefix curi == "owl" -> empty
_ -> classStart <+> pretty sub $+$ keyword subClassOfC <+> pretty super
EquivOrDisjointClasses ty (clazz : equiList) ->
classStart <+> pretty clazz $+$ printEquivOrDisjoint ty <+>
setToDocV (Set.fromList equiList)
DisjointUnion curi discList ->
classStart <+> pretty curi $+$ keyword disjointUnionOfC <+>
setToDocV (Set.fromList discList)
-- ObjectPropertyAxiom
SubObjectPropertyOf sopExp opExp ->
opStart <+> pretty opExp $+$ keyword (case sopExp of
SubObjectPropertyChain _ -> subPropertyChainC
_ -> subPropertyOfC)
<+> pretty sopExp
EquivOrDisjointObjectProperties ty (opExp : opList) ->
opStart <+> pretty opExp $+$ printEquivOrDisjoint ty <+>
setToDocV (Set.fromList opList)
ObjectPropertyDomainOrRange ty opExp desc ->
opStart <+> pretty opExp $+$ printObjDomainOrRange ty <+> pretty desc
InverseObjectProperties opExp1 opExp2 ->
opStart <+> pretty opExp1 $+$ keyword inverseOfC <+> pretty opExp2
ObjectPropertyCharacter ch opExp ->
opStart <+> pretty opExp $+$ printCharact (show ch)
-- DataPropertyAxiom
SubDataPropertyOf dpExp1 dpExp2 ->
dpStart <+> pretty dpExp1 $+$ keyword subPropertyOfC <+> pretty dpExp2
EquivOrDisjointDataProperties ty (dpExp : dpList) ->
dpStart <+> pretty dpExp $+$ printEquivOrDisjoint ty <+>
setToDocV (Set.fromList dpList)
DataPropertyDomainOrRange ddr dpExp ->
dpStart <+> pretty dpExp $+$ printDataDomainOrRange ddr
FunctionalDataProperty dpExp ->
dpStart <+> pretty dpExp $+$ printCharact functionalS
-- Fact
SameOrDifferentIndividual ty (ind : indList) ->
indStart <+> pretty ind $+$ printSameOrDifferent ty <+>
setToDocV (Set.fromList indList)
ClassAssertion desc ind ->
indStart <+> pretty ind $+$ keyword typesC <+> pretty desc
ObjectPropertyAssertion ass -> printAssertion ass
DataPropertyAssertion ass -> printAssertion ass
Declaration _ -> empty -- [Annotation] Entity
DatatypeDefinition dt dr ->
keyword datatypeC <+> pretty dt $+$ keyword equivalentToC <+> pretty dr
HasKey cexpr objlist datalist -> classStart <+> pretty cexpr $+$ keyword hasKeyC
<+> vcat (punctuate comma $ map pretty objlist ++ map pretty datalist)
u -> error $ "unknow axiom " ++ show u
classStart :: Doc
classStart = keyword classC
opStart :: Doc
opStart = keyword objectPropertyC
dpStart :: Doc
dpStart = keyword dataPropertyC
indStart :: Doc
indStart = keyword individualC
printCharact :: String -> Doc
printCharact charact =
keyword characteristicsC <+> text charact
instance Pretty SubObjectPropertyExpression where
pretty sopExp =
case sopExp of
OPExpression opExp -> pretty opExp
SubObjectPropertyChain opExpList ->
fsep $ prepPunctuate (keyword oS <> space) $ map pretty opExpList
instance Pretty OntologyFile where
pretty = vsep . map pretty . axiomsList . ontology
setToDocs :: Pretty a => Set.Set a -> [Doc]
setToDocs = punctuate comma . map pretty . Set.toList
setToDocV :: (Pretty a) => Set.Set a -> Doc
setToDocV = vcat . setToDocs