(require :agraph)

(in-package :db.agraph.user)

;;;------------------------------------------------
;; create new triple-store (overwrite existing 
;; AllegroGraph files if any)
;;;------------------------------------------------
(create-triple-store "ag-test")

;;;------------------------------------------------
;;; Namespaces
;;;------------------------------------------------
(register-namespace 
 "ex" "http://www.franz.com/things#" 
 :errorp nil)

(display-namespaces)

;;;------------------------------------------------
;;; Parts, nodes, UPIs
;;;------------------------------------------------
!ex:Dog
!<http://www.franz.com/things#Dog>
!"Dog"

(setf dog-upi (upi !ex:dog))

(describe !ex:dog)

(part->string dog-upi)

!"A string"

(setf string-upi (upi !"A string"))

(part->string string-upi)

(part->concise dog-upi)
(part->concise string-upi)

;;;------------------------------------------------
;;; Adding triples by hand
;;;------------------------------------------------
(add-triple !ex:Mammal !rdf:type !owl:Class)
(add-triple !ex:Dog !rdfs:subClassOf !ex:Mammal)
(add-triple !ex:Fido !rdf:type !ex:Dog)
(add-triple !ex:Fido !ex:has-owner !ex:John)
(add-triple !ex:Company !rdf:type !owl:Class)
(add-triple !ex:CommercialCompany !rdfs:subClassOf !ex:Company)
(add-triple !ex:Franz !rdf:type !owl:CommercialCompany)
(add-triple !ex:John !ex:works-at !ex:Franz)
(add-triple !ex:Franz !ex:has-product !ex:Agraph)

;;;------------------------------------------------
;;; looking at triples and parts
;;;------------------------------------------------
(setf tr (get-triple-by-id 4)) 

(triple-id tr)
(subject tr)

;; turn off encoded triple printing
(enable-print-decoded nil)

;; and look again
(triple-id tr)
(subject tr)

;; turn it back on
(enable-print-decoded t)

(print-triple tr :format :concise)

(dolist (e (get-triples-list))
  (print-triple e :format :concise))

(print-triple tr :format :long)
(print-triple tr :format :ntriple)

(pprint-subject !ex:Fido :format :concise)
(pprint-subject !ex:Fido :maximum-depth 3 :format :concise)
(pprint-object !ex:Mammal :maximum-depth 2 :format :concise)

;;;------------------------------------------------
;;; Querying
;;;------------------------------------------------
(get-triples-list :limit nil)

(print-triples
 (get-triples-list :o !ex:John) :format :concise)
(print-triples
 (get-triples-list :s !ex:Franz :p !rdf:type) 
 :format :concise)
(print-triples
 (get-triples-list :s !ex:John) :format :concise)

;;; cursor version
(get-triples :s !ex:Franz)

(defun my-get-triples-list (&optional s p o)
  (loop with cursor = (get-triples :s s :p p :o o)
     while (nextp cursor) collect (copy-triple (next-row cursor))))

;;; add-triple
(add-triple !ex:John !rdf:comment !"john")

(print-triples (get-triples-list :s !ex:John) :format :concise)

(resource "http://www.franz.com/simple#Peter")
(literal "Peter")

(let ((str1 "http://www.franz.com/simple#Peter") 
      (str2 "Peter"))
  (setf triple-id
	(add-triple (resource str1) !rdf:comment (literal str2))))

(print-triple (get-triple-by-id triple-id) :format :concise)

(close-triple-store)


;;;------------------------------------------------
;;; Loading triples from a file
;;;------------------------------------------------

(create-triple-store  "ag-test" :directory "/tmp/")

(load-ntriples "sys:agraph;tutorial-files;wilburwine.ntriples")

(register-namespace 
 "vin" "http://www.w3.org/TR/2003/CR-owl-guide-20030818/wine#")

(indexing-needed-p)

(triple-count)

(get-triples-list)

(length (get-triples-list))

(length (get-triples-list :limit nil))

(part->string !<http://www.w3.org/TR/2003/CR-owl-guide-20030818/wine#Wine>)
(part->string !vin:Wine)
(get-triples-list :s !vin:Wine)
(print-triple (get-triple-by-id 14) :format :concise)

(index-all-triples)

(print-triples (get-triples-list :s !vin:Wine) :format :concise)

(register-namespace "ex" "http://www.franz.com/things#"
		    :errorp nil)
(register-namespace 
 "guide" "http://www.w3.org/TR/2003/WD-owl-guide-20030331/")

(add-triple !guide:wine !ex:better-than !ex:beer)

(print-triples (get-triples-list :s !guide:wine) :format :concise)

;;;------------------------------------------------
;;; read in more triples
;;;------------------------------------------------
(triple-count)
(index-new-triples)

;;;------------------------------------------------
;;; deleting
;;;------------------------------------------------
(delete-triples :s !guide:wine :o !ex:beer)
(count-cursor (get-triples :s !guide:wine))

(time 
 (count-cursor (get-triples :s !vin:wine)))

(time
 (count-query :s !vin:wine))

;;; add it back
(add-triple !guide:wine !ex:better-than !ex:beer)

;;;------------------------------------------------
;;; reification - RDF style
;;;------------------------------------------------
(let ((bn (new-blank-node)))
  (add-triple bn !rdf:type !rdf:Statement)
  (add-triple bn !rdf:subject !guide:wine)
  (add-triple bn !rdf:predicate !ex:better-than)
  (add-triple bn !rdf:object !ex:beer)
  (add-triple bn !rdf:source !ex:Jans)
  (add-triple bn !rdf:content !ex:Nonsense))

(?- (q- ?st !rdf:type !rdf:Statement)
    (q- ?st !rdf:subject !guide:wine)
    (q- ?st !rdf:predicate !ex:better-than)
    (q- ?st !rdf:object !ex:beer)
    (q- ?st !rdf:source !ex:Jans)
    (q- ?st !rdf:content ?x)
    (lisp (print (part->string ?x))))

(setq tr
 (car (get-triples-list :s !guide:wine :p !ex:better-than :o !ex:beer)))

(print-triple tr :format :concise)

;;;------------------------------------------------
;;; reification - direct style
;;;------------------------------------------------
(setf nonsense-triple
      (add-triple !ex:Jans !ex:classifies-as-nonsense
		  (value->upi (triple-id tr) :triple-id)))

(print-triple (get-triple-by-id nonsense-triple) :format :concise)

(let ((bn (new-blank-node)))
  (add-triple 
   bn !rdf:statementAbout 
   (value->upi (triple-id tr) :triple-id))
  (add-triple bn !rdf:source !ex:Jans)
  (add-triple bn !rdf:content !ex:Nonsense))

(?- (q- ?st !rdf:statementAbout ?id)
    (q- ?st !rdf:source !ex:Jans)
    (q- ?st !rdf:content !ex:Nonsense)
    (lisp (print-triple (get-triple-by-id ?id) :format :concise)))

;;; clean up
(close-triple-store)

;;;------------------------------------------------
;; PROLOG tutorial
;;;------------------------------------------------

(<-- (parent pam bob))
(<- (parent tom bob))
(<- (parent tom liz))
(<- (parent bob ann))
(<- (parent bob pat))
(<- (parent pat jim))

(<-- (female pam))
(<- (female liz))
(<- (female ann))
(<- (female pat))

(<-- (male bob))
(<- (male tom))
(<- (male jim))

;; Interactive Prolog queries
;;
;; (?- (parent ?x ?y))
;; (?- (parent pam ?x))
;; (?- (parent ?x bob))
;; (?- (parent pam bob))

(<-- (offspring ?x ?y)
     (parent ?y ?x))

(<-- (mother ?x ?y)
     (parent ?x ?y)
     (female ?x))

(<-- (grandparent ?x ?y)
     (parent ?x ?z)
     (parent ?z ?y))
     
(<-- (sister ?x ?y)
     (parent ?p ?x)
     (parent ?p ?y)
     (female ?x)
     (not (= ?x ?y)))

(<-- (ancestor ?x ?y)
     (parent ?x ?y))

(<- (ancestor ?x ?y)
    (parent ?x ?z)
    (ancestor ?x ?y))

(defun find-father-son-pairs ()
  (let ((e))
    (prolog 
     (parent ?x ?y)
     (male ?x)
     (male ?y)
     (lisp (setq e (cons ?x ?y))))
    e))
	   
(find-father-son-pairs)


;;;------------------------------------------------
;;; AllegroGraph and Prolog
;;;------------------------------------------------

(create-triple-store 
 "/tmp/test" :if-exists :supersede)

(load-ntriples "sys:agraph;tutorial-files;wilburwine.ntriples")
(get-triples-list :p !rdfs:subClassOf)
(register-namespace "ex" "http://www.franz.com/things#"
		    :errorp nil)
(register-namespace "guide"
       "http://www.w3.org/TR/2003/WD-owl-guide-20030331/")

(let ((bn (new-blank-node)))
  (add-triple bn !rdf:statementAbout 
	      (value->upi
	       (add-triple !guide:wine !ex:better-than !ex:beer)
	       :triple-id))
  (add-triple bn !rdf:source !ex:Jans)
  (add-triple bn !rdf:content !ex:Nonsense))

(index-all-triples)   

;; The main interface to prolog is the function 'q'

(?- (q- ?x ?y ?z))

;; you can stop it by typing a '.'

(?- (q- ?x !rdfs:subClassOf ?y))

(?- (q- ?st !rdf:statementAbout ?id)
    (q- ?st !rdf:source !ex:Jans)
    (q- ?st !rdf:content !ex:Nonsense)
    (lisp (print-triple (get-triple-by-id ?id))))


(select (?x ?y ?z)
        (q- ?x !rdfs:subClassOf ?y)
        (q- ?y !rdfs:subClassOf ?z))

(close-triple-store)
