{- |
Module      :  ./RDF/Print.hs
Copyright   :  (c) Felix Gabriel Mance
License     :  GPLv2 or higher, see LICENSE.txt

Maintainer  :  f.mance@jacobs-university.de
Stability   :  provisional
Portability :  portable

Printer for N-triples

-}

module RDF.Print where

import Common.AS_Annotation
import Common.IRI
import Common.Doc hiding (sepBySemis, sepByCommas)
import Common.DocUtils hiding (ppWithCommas)

import qualified OWL2.AS as AS
import OWL2.Print ()

import RDF.AS
import RDF.Symbols
import RDF.Sign

import qualified Data.Set as Set
import Data.Maybe (isNothing)

sepBySemis :: [Doc] -> Doc
sepBySemis :: [Doc] -> Doc
sepBySemis = [Doc] -> Doc
vcat ([Doc] -> Doc) -> ([Doc] -> [Doc]) -> [Doc] -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Doc -> [Doc] -> [Doc]
punctuate (String -> Doc
text " ;")

ppWithSemis :: Pretty a => [a] -> Doc
ppWithSemis :: [a] -> Doc
ppWithSemis = [Doc] -> Doc
sepBySemis ([Doc] -> Doc) -> ([a] -> [Doc]) -> [a] -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Doc) -> [a] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map a -> Doc
forall a. Pretty a => a -> Doc
pretty

sepByCommas :: [Doc] -> Doc
sepByCommas :: [Doc] -> Doc
sepByCommas = [Doc] -> Doc
vcat ([Doc] -> Doc) -> ([Doc] -> [Doc]) -> [Doc] -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Doc -> [Doc] -> [Doc]
punctuate (String -> Doc
text " ,")

ppWithCommas :: Pretty a => [a] -> Doc
ppWithCommas :: [a] -> Doc
ppWithCommas = [Doc] -> Doc
sepByCommas ([Doc] -> Doc) -> ([a] -> [Doc]) -> [a] -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Doc) -> [a] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map a -> Doc
forall a. Pretty a => a -> Doc
pretty

instance Pretty Predicate where
    pretty :: Predicate -> Doc
pretty = Predicate -> Doc
printPredicate

printPredicate :: Predicate -> Doc
printPredicate :: Predicate -> Doc
printPredicate (Predicate iri :: IRI
iri) = IRI -> Doc
forall a. Pretty a => a -> Doc
pretty IRI
iri

instance Pretty RDFLiteral where
    pretty :: RDFLiteral -> Doc
pretty lit :: RDFLiteral
lit = case RDFLiteral
lit of
        RDFLiteral b :: Bool
b lexi :: String
lexi ty :: TypedOrUntyped
ty -> String -> Doc
text (if Bool -> Bool
not Bool
b
                then '"' Char -> String -> String
forall a. a -> [a] -> [a]
: String
lexi String -> String -> String
forall a. [a] -> [a] -> [a]
++ "\""
                else "\"\"\"" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
lexi String -> String -> String
forall a. [a] -> [a] -> [a]
++ "\"\"\"") Doc -> Doc -> Doc
forall a. Semigroup a => a -> a -> a
<> case TypedOrUntyped
ty of
            AS.Typed u :: IRI
u -> String -> Doc
keyword String
AS.cTypeS Doc -> Doc -> Doc
forall a. Semigroup a => a -> a -> a
<> IRI -> Doc
forall a. Pretty a => a -> Doc
pretty IRI
u
            AS.Untyped tag :: Maybe String
tag -> if Maybe String -> Bool
forall a. Maybe a -> Bool
isNothing Maybe String
tag then Doc
empty
                    else let Just tag2 :: String
tag2 = Maybe String
tag in String -> Doc
text "@" Doc -> Doc -> Doc
forall a. Semigroup a => a -> a -> a
<> String -> Doc
text String
tag2
        RDFNumberLit f :: FloatLit
f -> String -> Doc
text (FloatLit -> String
forall a. Show a => a -> String
show FloatLit
f)

instance Pretty PredicateObjectList where
    pretty :: PredicateObjectList -> Doc
pretty = PredicateObjectList -> Doc
printPredObjList

printPredObjList :: PredicateObjectList -> Doc
printPredObjList :: PredicateObjectList -> Doc
printPredObjList (PredicateObjectList p :: Predicate
p ol :: [Object]
ol) = Predicate -> Doc
forall a. Pretty a => a -> Doc
pretty Predicate
p Doc -> Doc -> Doc
<+> [Object] -> Doc
forall a. Pretty a => [a] -> Doc
ppWithCommas [Object]
ol

instance Pretty Subject where
    pretty :: Subject -> Doc
pretty = Subject -> Doc
printSubject

printSubject :: Subject -> Doc
printSubject :: Subject -> Doc
printSubject subj :: Subject
subj = case Subject
subj of
    Subject iri :: IRI
iri -> IRI -> Doc
forall a. Pretty a => a -> Doc
pretty IRI
iri
    SubjectList ls :: [PredicateObjectList]
ls -> Doc -> Doc
brackets (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ [PredicateObjectList] -> Doc
forall a. Pretty a => [a] -> Doc
ppWithSemis [PredicateObjectList]
ls
    SubjectCollection c :: [Object]
c -> Doc -> Doc
parens (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ ([Doc] -> Doc
hsep ([Doc] -> Doc) -> ([Object] -> [Doc]) -> [Object] -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Object -> Doc) -> [Object] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map Object -> Doc
forall a. Pretty a => a -> Doc
pretty) [Object]
c

instance Pretty Object where
    pretty :: Object -> Doc
pretty = Object -> Doc
printObject

printObject :: Object -> Doc
printObject :: Object -> Doc
printObject obj :: Object
obj = case Object
obj of
    Object s :: Subject
s -> Subject -> Doc
forall a. Pretty a => a -> Doc
pretty Subject
s
    ObjectLiteral l :: RDFLiteral
l -> RDFLiteral -> Doc
forall a. Pretty a => a -> Doc
pretty RDFLiteral
l

instance Pretty Triples where
    pretty :: Triples -> Doc
pretty = Triples -> Doc
printTriples

printTriples :: Triples -> Doc
printTriples :: Triples -> Doc
printTriples (Triples s :: Subject
s ls :: [PredicateObjectList]
ls) = Subject -> Doc
forall a. Pretty a => a -> Doc
pretty Subject
s Doc -> Doc -> Doc
<+> [PredicateObjectList] -> Doc
forall a. Pretty a => [a] -> Doc
ppWithSemis [PredicateObjectList]
ls Doc -> Doc -> Doc
<+> Doc
dot

instance Pretty Statement where
    pretty :: Statement -> Doc
pretty = Statement -> Doc
printStatement

printStatement :: Statement -> Doc
printStatement :: Statement -> Doc
printStatement s :: Statement
s = case Statement
s of
    Statement t :: Triples
t -> Triples -> Doc
forall a. Pretty a => a -> Doc
pretty Triples
t
    PrefixStatement (PrefixR p :: String
p iri :: IRI
iri)
        -> String -> Doc
text "@prefix" Doc -> Doc -> Doc
<+> String -> Doc
forall a. Pretty a => a -> Doc
pretty String
p Doc -> Doc -> Doc
forall a. Semigroup a => a -> a -> a
<> Doc
colon Doc -> Doc -> Doc
<+> IRI -> Doc
forall a. Pretty a => a -> Doc
pretty IRI
iri Doc -> Doc -> Doc
<+> Doc
dot
    BaseStatement (Base iri :: IRI
iri) -> String -> Doc
text "@base" Doc -> Doc -> Doc
<+> IRI -> Doc
forall a. Pretty a => a -> Doc
pretty IRI
iri Doc -> Doc -> Doc
<+> Doc
dot

instance Pretty TurtleDocument where
    pretty :: TurtleDocument -> Doc
pretty = TurtleDocument -> Doc
printDocument

printDocument :: TurtleDocument -> Doc
printDocument :: TurtleDocument -> Doc
printDocument doc :: TurtleDocument
doc = ([Doc] -> Doc
vcat ([Doc] -> Doc) -> ([Statement] -> [Doc]) -> [Statement] -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Statement -> Doc) -> [Statement] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map Statement -> Doc
forall a. Pretty a => a -> Doc
pretty) (TurtleDocument -> [Statement]
statements TurtleDocument
doc)

printExpandedIRI :: IRI -> Doc
printExpandedIRI :: IRI -> Doc
printExpandedIRI iri :: IRI
iri =
 if (Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ IRI -> Bool
hasFullIRI IRI
iri) Bool -> Bool -> Bool
|| (IRI -> Bool
isBlankNode IRI
iri) then 
       String -> Doc
text (String -> Doc) -> String -> Doc
forall a b. (a -> b) -> a -> b
$ IRI -> String
showIRICompact IRI
iri
  else String -> Doc
text "<" Doc -> Doc -> Doc
forall a. Semigroup a => a -> a -> a
<> String -> Doc
text (IRI -> String
showIRIFull IRI
iri) Doc -> Doc -> Doc
forall a. Semigroup a => a -> a -> a
<> String -> Doc
text ">"

instance Pretty Term where
    pretty :: Term -> Doc
pretty = Term -> Doc
printTerm

printTerm :: Term -> Doc
printTerm :: Term -> Doc
printTerm t :: Term
t = case Term
t of
    SubjectTerm iri :: IRI
iri -> IRI -> Doc
printExpandedIRI IRI
iri
    PredicateTerm iri :: IRI
iri -> IRI -> Doc
printExpandedIRI IRI
iri
    ObjectTerm obj :: Either IRI RDFLiteral
obj -> case Either IRI RDFLiteral
obj of
        Right lit :: RDFLiteral
lit -> RDFLiteral -> Doc
forall a. Pretty a => a -> Doc
pretty RDFLiteral
lit
        Left iri :: IRI
iri -> IRI -> Doc
printExpandedIRI IRI
iri

instance Pretty Axiom where
    pretty :: Axiom -> Doc
pretty = Axiom -> Doc
printAxiom

printAxiom :: Axiom -> Doc
printAxiom :: Axiom -> Doc
printAxiom (Axiom sub :: Term
sub pre :: Term
pre obj :: Term
obj) = Term -> Doc
forall a. Pretty a => a -> Doc
pretty Term
sub Doc -> Doc -> Doc
<+> Term -> Doc
forall a. Pretty a => a -> Doc
pretty Term
pre Doc -> Doc -> Doc
<+> Term -> Doc
forall a. Pretty a => a -> Doc
pretty Term
obj
                                                                    Doc -> Doc -> Doc
<+> String -> Doc
text "."

printAxioms :: [Axiom] -> Doc
printAxioms :: [Axiom] -> Doc
printAxioms = [Doc] -> Doc
vcat ([Doc] -> Doc) -> ([Axiom] -> [Doc]) -> [Axiom] -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Axiom -> Doc) -> [Axiom] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map Axiom -> Doc
forall a. Pretty a => a -> Doc
pretty

-- | RDF signature printing
printRDFBasicTheory :: (Sign, [Named Axiom]) -> Doc
printRDFBasicTheory :: (Sign, [Named Axiom]) -> Doc
printRDFBasicTheory (_, l :: [Named Axiom]
l) = [Doc] -> Doc
vsep ((Named Axiom -> Doc) -> [Named Axiom] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map (Axiom -> Doc
forall a. Pretty a => a -> Doc
pretty (Axiom -> Doc) -> (Named Axiom -> Axiom) -> Named Axiom -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Named Axiom -> Axiom
forall s a. SenAttr s a -> s
sentence) [Named Axiom]
l)

instance Pretty Sign where
    pretty :: Sign -> Doc
pretty = Sign -> Doc
printSign

printNodes :: String -> Set.Set Term -> Doc
printNodes :: String -> Set Term -> Doc
printNodes s :: String
s terms :: Set Term
terms = String -> Doc
text "#" Doc -> Doc -> Doc
<+> String -> Doc
text String
s Doc -> Doc -> Doc
$+$
    [Doc] -> Doc
vcat ((Term -> Doc) -> [Term] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map ((String -> Doc
text "#\t\t" Doc -> Doc -> Doc
<+>) (Doc -> Doc) -> (Term -> Doc) -> Term -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Term -> Doc
forall a. Pretty a => a -> Doc
pretty) (Set Term -> [Term]
forall a. Set a -> [a]
Set.toList Set Term
terms))

printSign :: Sign -> Doc
printSign :: Sign -> Doc
printSign s :: Sign
s = String -> Set Term -> Doc
printNodes "subjects:" (Sign -> Set Term
subjects Sign
s)
    Doc -> Doc -> Doc
$+$ String -> Set Term -> Doc
printNodes "predicates:" (Sign -> Set Term
predicates Sign
s)
    Doc -> Doc -> Doc
$+$ String -> Set Term -> Doc
printNodes "objects:" (Sign -> Set Term
objects Sign
s)

-- | Symbols printing

instance Pretty RDFEntityType where
    pretty :: RDFEntityType -> Doc
pretty ety :: RDFEntityType
ety = String -> Doc
text (String -> Doc) -> String -> Doc
forall a b. (a -> b) -> a -> b
$ RDFEntityType -> String
forall a. Show a => a -> String
show RDFEntityType
ety

instance Pretty RDFEntity where
    pretty :: RDFEntity -> Doc
pretty (RDFEntity ty :: RDFEntityType
ty ent :: Term
ent) = RDFEntityType -> Doc
forall a. Pretty a => a -> Doc
pretty RDFEntityType
ty Doc -> Doc -> Doc
<+> Term -> Doc
forall a. Pretty a => a -> Doc
pretty Term
ent

instance Pretty SymbItems where
    pretty :: SymbItems -> Doc
pretty (SymbItems m :: Maybe RDFEntityType
m us :: [IRI]
us) = Maybe RDFEntityType -> Doc
forall a. Pretty a => a -> Doc
pretty Maybe RDFEntityType
m Doc -> Doc -> Doc
<+> [IRI] -> Doc
forall a. Pretty a => [a] -> Doc
ppWithCommas [IRI]
us

instance Pretty SymbMapItems where
    pretty :: SymbMapItems -> Doc
pretty (SymbMapItems m :: Maybe RDFEntityType
m us :: [(IRI, Maybe IRI)]
us) = Maybe RDFEntityType -> Doc
forall a. Pretty a => a -> Doc
pretty Maybe RDFEntityType
m
        Doc -> Doc -> Doc
<+> [Doc] -> Doc
sepByCommas
            (((IRI, Maybe IRI) -> Doc) -> [(IRI, Maybe IRI)] -> [Doc]
forall a b. (a -> b) -> [a] -> [b]
map (\ (s :: IRI
s, ms :: Maybe IRI
ms) -> [Doc] -> Doc
sep
                [ IRI -> Doc
forall a. Pretty a => a -> Doc
pretty IRI
s
                , case Maybe IRI
ms of
                    Nothing -> Doc
empty
                    Just t :: IRI
t -> Doc
mapsto Doc -> Doc -> Doc
<+> IRI -> Doc
forall a. Pretty a => a -> Doc
pretty IRI
t]) [(IRI, Maybe IRI)]
us)

instance Pretty RawSymb where
    pretty :: RawSymb -> Doc
pretty rs :: RawSymb
rs = case RawSymb
rs of
        ASymbol e :: RDFEntity
e -> RDFEntity -> Doc
forall a. Pretty a => a -> Doc
pretty RDFEntity
e
        AnUri u :: IRI
u -> IRI -> Doc
forall a. Pretty a => a -> Doc
pretty IRI
u