Knowledge Graphs

Triples

RDF triples are the interlingua for knowledge on the Semantic Web.

subject relation object.

Represent subject and object as nodes and relations as labeled edges to form a knowledge graph.

Read Section 3.1 of the W3C overview of triples.

SPARQL queries

  • SPARQL is the W3 standard query language for RDF triples.
  • Reduced to basics:
    • A query is a list of triples with zero or more variables.
    • A query retrieves zero or more lists of variable bindings.
    • Each list represents a different subset of triples in the knowledge graph that can match the query with consistent variable bindings.

Read RDF and Querying.

Triple queries in Lisp

Implement variables

A variable is a symbol beginning with a question mark.

(defun var-p (x)
  (and (symbolp x) (eql (char (symbol-name x) 0) #\?)))

Implement variable matching

A variable matches an item only if it has not been matched before or has been matched to that item before. Track variable matches with a binding list, using a Lisp association list.

(defun match-var (x y blst)
  (let ((bdg (assoc x blst)))
    (cond ((null bdg) (list (cons (list x y) blst)))
          ((equal y (cadr bdg)) (list blst))
          (t nil))))

Implement triple matching

To matching a triple pattern to another triple, match corresponding elements left to right, passing the lists of binding list from one call to the next.

(defun match-lists (lst1 lst2 &optional (blsts '(nil)))
  (cond ((null blsts) nil)
        ((null lst1) blsts)
        (t
          (match-lists (cdr lst1) (cdr lst2)
            (match-item (car lst1) (car lst2) blsts)))))

(defun match-item (x y blsts)
  (cond ((eql x y) blsts)
        ((var-p x)
         (mapcan (lambda (blst) (match-var x y blst)) blsts))
        (t nil)))

Implement queries

Given a list of triples, match the first triple against all facts. Append the resulting binding lists. Repeat with each remaining query triple, using the binding lists from the previous step. Stop when all query triples have been processed or the list of bindings lists becomes empty.

(defun query (triples &optional (blsts '(nil)))
  (cond ((null triples) blsts)
        ((null blsts) blsts)
        (t
          (query (cdr triples)
                 (query-triple (car triples) blsts)))))

(defun query-triple (triple blsts)
  (mapcan (lambda (fact)
            (match-lists triple fact blsts))
          *facts*))