 (ns sparqlab.exercise
   (:require [sparqlab.sparql :as sparql]
             [sparqlab.store :as store]
+            [sparqlab.rdf :as rdf]
             [clojure.set :refer [union]]
             [clojure.tools.logging :as log])
   (:import (org.apache.jena.rdf.model Model)))

  (let [sparql-query (partial sparql/sparql-query sparql/sparql-endpoint)
        canonical-query (sparql/parse-query canonical-query-string)
        query (sparql/parse-query query-string)
        equal-query-result (equal-query? canonical-query query)
        all-ask-queries? (every? (comp (partial = ::sparql/ask) :query-type) [canonical-query query])
        ; If the queries are the same, retrieve only the canonical results.
        results (if equal-query-result
                  (let [res (sparql/sparql-query-cached sparql/sparql-endpoint canonical-query)]
                    {:canonical-results res
                     :query-results res})

  "Test if queries `a` and `b` are equal. Starts by testing string equality, then tests equality
  of the parsed queries, then tests equality of the parsed algebras."
  [a b]
  (letfn [(equal-where? [{a :query} {b :query}]
            (.equalTo (sparql/normalize-query a) (sparql/normalize-query b) sparql/node-isomorphism-map))
          (equal-construct? [a b]
            ; If not CONSTRUCT, then skip the equality test.
            (or (not= (:query-type a) ::sparql/construct)
                (sparql/equal-construct? (:query a) (:query b))))]
    (or (= (:query-string a) (:query-string b))
      (and (= (:query-type a) (:query-type b))
           (or (= (:query a) (:query b))
               (and (equal-where? a b) (equal-construct? a b)))))))

(defn get-construct-labels
  "Get labels of `constructs` in `lang`."
