module Load where import "N3Parser" import "IO" import "Utils" import "XML" -- This module takes input from the N3 parser and puts the data -- into an XML tree. -- a prefixlist is a list of prefixes type PrefixList = [String] -- Functions ---------------- -- read a parsed file, load it and print the result saveEngine fileName = readExternN3 fileName (loadAndSave fileName) -- loadFile loads a file into the data structures loadAndSave :: String -> String -> IO () loadAndSave fileName parseString = stringToFile (fileToXML (thdTriple (loadString (parseString, plist, db)))) (fileName ++ ".ld") -- read a parsed file and load it readEngine fileName = readExternN3 fileName loadFile testReadDB fileName = readDB fileName (putStr.fileToXML) -- read a parsed file and return the xml database readDB :: String -> (XMLTree -> IO ()) -> IO () readDB fileName function = do {s <- readFile fileName; function (loadDB (n3Parser s))} -- transform the parse string into the database loadDB :: String -> XMLTree loadDB parseString = db1 where (s1, plist, db) = loadString (parseString, [], Tag ("DB", Empty, Empty)) prefixes = addPrefixToTag plist (Tag ("Prefixes", Empty, Empty)) db1 = addTree db prefixes testAddPrefixToTag = putStr( fileToXML( addPrefixToTag pa6 (Tag ("Prefixes", Empty, Empty)))) addPrefixToTag [] tag = tag addPrefixToTag (x:xs) tag = addPrefixToTag xs (addTree tag (Content (x, Empty))) -- loadFile loads a file into the data structures loadFile :: String -> IO () loadFile parseString = putStr (fileToXML (thdTriple (loadString (parseString, plist, db)))) -- putStr (fstTriple (loadString (parseString, plist, db))) testLoadString = putStr (fileToXML (thdTriple (loadString (pa1, plist, db)))) -- this function creates the datastrucure loadString :: (String, PrefixList, XMLTree) -> (String, PrefixList, XMLTree) loadString ([], p, db) = ([], p, db) loadString (s, p, db) | token == "Prefix" = loadString (s2, p ++ [token1], db) | token == "Subject" = loadString (s3, p, addTree db t) | token == "Set" = loadString (s4, p, addTree db te) | token == "AnonSet" = loadString (s4, p, addTree db te) | otherwise = (s, p, db) where (token, s1) = getNextToken ("", s) (token1, s2) = getNextToken ("", s1) -- get the prefix (s3, t) = loadTriple s (s4, te) = loadTerm (s3, addTree (Tag ("Term",Empty, Empty)) t) testLoadTerm1 = fst (loadTerm (pa5, Tag ("Term", Empty, Empty))) testLoadTerm2 = fileToXML(snd(loadTerm (pa5,Tag ("Term", Empty, Empty)))) -- load a term next token might be Set || AnonSet || Subject || EndOfSet -- otherwise loadTriple -- If Set then create a TermList loadTerm :: (String, XMLTree) -> (String, XMLTree) loadTerm (s, t) | token == "Set" = (s3, t2) | token == "AnonSet" = (s3, t2) | token == "Subject" = (s5, t4) | token == "EndOfSet" = (s1, t) -- return on EndOfSet | otherwise = (s, t) -- this is not a term where (token, s1) = getNextToken ("", s) (s3, t2) = loadTerm (s4, addTree t t3) (s2, t1) = loadTriple s (s5, t4) = loadTerm (s2, addTree t t1) (s4, t3) = loadTriple s1 testLoadTriple = putStr (fileToXML (snd (loadTriple pa1))) testLoadTriple1 = putStr (showXML (snd (loadTriple pa1)) "") testLoadAnonSet = putStr (fileToXML (snd (loadTerm (pa4, Tag ("Term", Empty, Empty))))) testLoadAnonSet1 = putStr (showXML (snd (loadTerm (pa4, Tag ("Term", Empty, Empty)))) "") -- load a triple; load the subject and a propertylist. loadTriple :: String -> (String, XMLTree) loadTriple s | token == "Subject" = (s3, addTree Empty p) | token == "Set" = (s3, addTree Empty p) | otherwise = (s, Tag ("Subject", Empty, Empty)) where (token, s1) = getNextToken ("", s) (s2, sub) = loadSubject s (s3, p) = loadPropertyList (s2, sub) testLoadPropertyList = putStr(fileToXML (snd (loadPropertyList (pa3, Tag ("Top", Empty, Empty))))) testLoadPropertyList1 = putStr(showXML (snd (loadPropertyList (pa3, Tag ("Top", Empty, Empty)))) "") -- load a propertylist loadPropertyList :: (String, XMLTree) -> (String, XMLTree) loadPropertyList ([], p) = ([], p) loadPropertyList (s, p) | token == "_subject" = loadPropertyList (s2, addTree p p1) | otherwise = (s1, addTree p p1) where (s1, p1) = loadProperty s (token, s2) = getNextToken ("", s1) testLoadProperty = putStr(fileToXML(snd(loadProperty pa3))) testLoadProperty1 = putStr(showXML(snd(loadProperty pa3))"") -- load a property -- the next token might be: Verb || _subject loadProperty :: String -> (String, XMLTree) loadProperty s | token == "Verb" = (s5, n) | token == "_subject" = (s6, n1) -- necessary?? | otherwise = (s, (Tag ("Verb", Empty, Empty))) where (token, s1) = getNextToken ("", s) (s3, v1) = loadVerb s (s4, v2) = loadVerb s1 (s5, n) = loadObjectList (s3, v1) (s6, n1) = loadObjectList (s4, v2) testLoadObjectList = putStr(fileToXML(snd(loadObjectList (pa2, Tag ("Top", Empty, Empty)) ))) testLoadObjectList1 = putStr(showXML(snd(loadObjectList (pa2, Tag ("Top", Empty, Empty)) )) "") -- load an objectlist loadObjectList :: (String, XMLTree) -> (String, XMLTree) loadObjectList ([], o) = ([], o) loadObjectList (s, o) | token == "_subject" && token1 == "_verb" = loadObjectList (s3, addTree o o1) | otherwise = (s1, addTree o o1) where (s1, o1) = loadObject s (token, s2) = getNextToken ("", s1) (token1, s3) = getNextToken ("", s2) -- load a subject -- the next token might be: Subject || Set || AnonSet loadSubject :: String -> (String, XMLTree) loadSubject [] = ([], Empty) loadSubject s | token == "Subject" = (s3, addTree (Tag ("Subject", Empty, Empty)) (addContent (Tag ("URI", Empty, Empty)) (Content ((token1 ++ " " ++ token2), Empty)))) | token == "Set" = (s4, Tag ("Subject", t1, Empty)) | token == "AnonSet" = (s4, Tag("Subject", t1, Empty)) | otherwise = (s, Empty) where (token, s1) = getNextToken ("", s) (token1, s2) = getNextToken ("", s1) (token2, s3) = getNextToken ("", s2) (s4, t1) = loadTerm (s, Tag ("Term", Empty, Empty)) testLoadVerb = putStr(fileToXML(snd(loadVerb s2))) testLoadVerb1 = putStr(showXML(snd(loadVerb s2))"") -- load a verb -- the next token might be: Verb || _subject || Set || AnonSet loadVerb :: String -> (String, XMLTree) loadVerb [] = ([], Empty) loadVerb s | token == "Verb" = (s3, addTree (Tag ("Verb", Empty, Empty)) (addContent (Tag ("URI", Empty, Empty)) (Content ((token1 ++ " " ++ token2), Empty)))) | token == "_subject" = (s4, addTree (Tag ("Verb", Empty, Empty)) (addContent (Tag ("URI", Empty, Empty)) (Content ((token2 ++ " " ++ token3), Empty)))) | token == "Set" = (s5, Tag ("Verb", t1, Empty)) | token == "AnonSet" = (s5, Tag ("Verb", t1, Empty)) | otherwise = (s, Empty) where (token, s1) = getNextToken ("", s) (token1, s2) = getNextToken ("", s1) (token2, s3) = getNextToken ("", s2) (token3, s4) = getNextToken ("", s3) (s5, t1) = loadTerm (s, Tag ("Term", Empty, Empty)) testLoadObject = putStr(fileToXML(snd(loadObject s1))) -- load an object -- the next token might be: Object || _subject loadObject :: String -> (String, XMLTree) loadObject [] = ([], Empty) loadObject s | token == "Object" = (s3, addTree (Tag ("Object", Empty, Empty)) (addContent (Tag ("URI", Empty, Empty)) (Content ((token1 ++ " " ++ token2), Empty)))) | token == "_subject" && token1 == "_verb" = (s5, addTree (Tag ("Object", Empty, Empty)) (addContent (Tag ("URI", Empty, Empty)) (Content ((token3 ++ " " ++ token4), Empty)))) | token == "Set" = (s6, Tag ("Object", t1, Empty)) | token == "AnonSet" = (s6, Tag ("Object", t1, Empty)) | otherwise = (s, Empty) where (token, s1) = getNextToken ("", s) (token1, s2) = getNextToken ("", s1) (token2, s3) = getNextToken ("", s2) (token3, s4) = getNextToken ("", s3) (token4, s5) = getNextToken ("", s4) (s6, t1) = loadTerm (s, Tag ("Term", Empty, Empty)) -- getNextToken returns the next token and the rest string -- is normally called with first string empty getNextToken :: (String, String) -> (String, String) getNextToken ([], []) = ([], []) getNextToken (s, []) = (s, []) getNextToken (s1, s2@(x:xs)) | startsWith s2 "/@/" = (s1, drop 3 s2) | otherwise = getNextToken (s1 ++ [x], xs) --Test data ------------------- -- testLoadObject s1 = "Object/@/" ++ "/@/http://www.agfa.com/@/" -- testLoadVerb s2 = "Verb/@/:member/@/" ++ "/@/Object/@/" ++ "/@/http://www.agfa.com/@/" pa1 = "Subject/@//@/" ++ "mailto:jos.deroo.jd@belgium.agfa.com/@/Verb/@/:member/@/" ++ "/@/Object/@/" ++ "/@/http://www.agfa.com/@/" -- test loadObjectList pa2 = "Object/@//@/http://www.agfa.com/@/_subject" ++ "/@/_verb/@/Object/@//@/http://gn/@/Subject/@/" -- test loadPropertyList pa3 = "Verb/@/:member/@/" ++ "/@/Object/@/" ++ "/@/http://www.agfa.com/@/" ++ "_subject/@/Verb/@/:test/@/hp:test/@/" ++ "Object/@/:ok/@/ok:ok/@/" -- test AnonSet pa4 = "AnonSet/@/Subject/@/_T1/@/_T1/@/Verb/@/a/@/rdf:type/@/Object/@/agg:Company" ++ "/@/http://example.com/xmlns/aggregation-demo#Company/@/" ++ "_subject/@/Verb/@/agg:corporateHomepage/@/" ++ "http://example.com/xmlns/aggregation-demo#corporateHomepage/@/" ++ "Object/@//@/" ++ "http://megacorp.example.com//@/_subject/@/Verb/@/agg:name/@/" ++ "http://example.com/xmlns/aggregation-demo#name/@/Object/@/" ++ "MegaCorp Inc./@/MegaCorp Inc./@/_subject/@/Verb/@/agg:owner/@/" ++ "http://example.com/xmlns/aggregation-demo#owner/@/Object/@/agg:gn" ++ "/@/agg:gn/@/EndOfSet/@/" -- test embedded sets pa5 = "Set/@/Set/@/Subject/@/:t/@/:t/@/Verb/@/:v/@/:v/@/Object/@/:o/@/:o" ++ "/@/Subject/@/:t1/@/:t1/@/Verb/@/:v1/@/:v1/@/Object/@/:o1/@/:o1/@/" ++ "EndOfSet/@/Verb/@/:v2/@/:v2/@/Object/@/:o2/@/:o2/@/EndOfSet/@/" -- test prefix loading pa6 = ["@prefix log: .", "@prefix : ."] -- test of rule ("authen.axiom.n3") pa7 = "Prefix/@/@prefix log: ./@/" ++ "Prefix/@/@prefix : ./@/Subject/@/" ++ "/@/mailto:jos.deroo.jd@belgium.agfa.com/@/Verb/@/:member/@/" ++ "/@/Object/@//@/" ++ "http://www.agfa.com/@/Subject/@//@/" ++ "http://www.agfa.com/@/Verb/@/:w3cmember/@/" ++ "/@/Object/@//@/http://www.w3.org/@/Subject" ++ "/@//@/http://www.agfa.com/@/Verb/@/" ++ ":subscribed/@//@/Object/@/" ++ "/@/mailto:w3c-ac-forum@w3.org//@/" ++ "Set/@/Set/@/Subject/@/:person/@//@/Verb/@/:member" ++ "/@//@/Object/@/:institution/@/" ++ "/@/Subject/@/:institution/@//@/" ++ "Verb/@/:w3cmember/@//@/Object/@/" ++ "/@/http://www.w3.org/@/" ++ "Subject/@/:institution/@//@/Verb" ++ "/@/:subscribed/@//@/Object/@/" ++ ":mailinglist/@//@/EndOfSet/@/Verb/@/" ++ "log:implies/@/http://www.w3.org/2000/10/swap/log#implies/@/" ++ "Set/@/Subject/@/:person/@//@/Verb/@/" ++ ":authenticated/@//@/Object/@/" ++ ":mailinglist/@//@/EndOfSet/@/EndOfSet" ++ "/@/Verb/@/a/@/http://www.w3.org/1999/02/22-rdf-syntax-ns#type" ++ "/@/Object/@/log:Truth/@/http://www.w3.org/2000/10/swap/log#Truth" ++ "/@/_subject/@/Verb/@/log:forAll/@/" ++ "http://www.w3.org/2000/10/swap/log#forAll/@/Object/@/" ++ ":person/@//@/_subject/@/_verb/@/Object/@/" ++ ":mailinglist/@//@/_subject/@/_verb/@/" ++ "Object/@/:institution/@//@/" -- test of a query ("authen.lemma.n3") pa8 = "Prefix/@/@prefix log: ." ++ "/@/Prefix/@/@prefix : ./@/Subject/@/_:who/@/_:who/@/" ++ "Verb/@/:authenticated/@//@/Object/@/" ++ "/@/mailto:w3c-ac-forum@w3.org//@/" -- constants -------------------- -- the unloaded database db = Tag ("DB", Empty, Empty) -- the unloaded list of prefixes plist = []