(in-package #:db.agraph)

;;;; setup - split wilburwine into four stores and federate them
;;;;

(create-triple-store "/tmp/wilburwine-full")

(load-ntriples (sample-file "wilburwine.ntriples"))

(loop for index from 1 to 4 do
     (create-triple-store (string+ "/tmp/wilburwine-" index)))

(setf ww-full (find-triple-store "wilburwine-full"))

(map-cursor nil (lambda (triple)
		  (let* ((id (triple-id triple))
			 (store (1+ (mod id 4))))
		    (with-triple-store (db (string+ "wilburwine-" store))
		      (let ((*db* ww-full))
			(add-triple
			 (part->string (subject triple) :format :ntriple)
			 (part->string (predicate triple) :format :ntriple)
			 (part->string (object triple) :format :ntriple) 
			 :db db)))))
	    (get-triples :db "wilburwine-full"))

;; see what we have.

(mapcar (lambda (db)
	  (list (name db) (triple-count :db db)))
	(collect-all-triple-stores))

(setf ww-fed
      (federate-triple-stores
       "wilburwine-combine"
       (loop for index from 1 to 4 collect
	    (string+ "/tmp/wilburwine-" index))))

;;; get-triples works

(count-cursor 
 (get-triples 
  :p !rdf:type 
  :o !<http://www.w3.org/TR/2003/CR-owl-guide-20030818/wine#Winery>
  :db ww-full))
==> 84

(count-cursor 
 (get-triples 
  :p !rdf:type 
  :o !<http://www.w3.org/TR/2003/CR-owl-guide-20030818/wine#Winery>
  :db ww-fed))
==> 84

;;; prolog select works too

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

;; for UPIs
(let ((*db* ww-fed))
  (select0 (?wine ?type)
    (q- ?wine !vin:locatedIn !vin:GermanyRegion)
    (q- ?wine !vin:hasSugar !vin:Sweet)
    (q- ?wine !rdf:type ?type)))


;; and strings
(time
 (let ((*db* ww-fed))
   (select (?wine ?type)
     (q- ?wine !vin:locatedIn !vin:GermanyRegion)
     (q- ?wine !vin:hasSugar !vin:Sweet)
     (q- ?wine !rdf:type ?type))))

;; same answer, same time too
(time
 (let ((*db* ww-full))
   (select (?wine ?type)
     (q- ?wine !vin:locatedIn !vin:GermanyRegion)
     (q- ?wine !vin:hasSugar !vin:Sweet)
     (q- ?wine !rdf:type ?type))))


;;;; SPARQL seems to work too

;####
;# In principle, running this query with a 'depth' of 1 will have the same
;# effect as running it once with a higher 'depth'.
;# This generates the triples to emulate the transitivity of locatedIn.
;# Produces 23 new triples.
;####

(setf query-01
"PREFIX vin:  <http://www.w3.org/TR/2003/CR-owl-guide-20030818/wine#>
CONSTRUCT {
  ?x vin:locatedIn vin:CaliforniaRegion .
}
WHERE {
  { ?x vin:locatedIn [ vin:locatedIn vin:CaliforniaRegion ] . }
  UNION
  { ?wine vin:locatedIn
    [ vin:locatedIn [ vin:locatedIn vin:CaliforniaRegion ] ] }
  UNION
  { ?wine vin:locatedIn
    [ vin:locatedIn
      [ vin:locatedIn
        [ vin:locatedIn vin:CaliforniaRegion ] ] ] }
}")


(let ((*db* ww-full))
  (with-output (*standard-output* #p"/tmp/query-01-full.xml")
    (sparql:run-sparql query-01 :results-format :xml)))

(let ((*db* ww-fed))
  (with-output (*standard-output* #p"/tmp/query-01-fed.xml")
    (sparql:run-sparql query-01 :results-format :xml)))


;;?? The file differ but I believe the contain the same information. 
;; I need a better comparison function...

;; Missing bits: 
;; caching strings
;; reification -- need to associate triples with particular stores
;;  use UUIDs, add triples to name siblings, alter triple-ids to 
;;  include a short store ID that can be associated with full UUIDs,
;;  and more bookkeeping of the same sort
;; no reasoning
;; efficiency -- tracking which stores contain which information
