read


read
or learn more

On Lisp -> Clojure: ProloG (pt. 1)

Jan 15, 2009

; As always, I will post when the code is “complete”, but my progress can be followed on Github. Also, this post is executable, just copy and paste into a Clojure REPL.

(comment “

Posts in this series: ch. 2, ch. 2 redux, ch. 3, ch. 4, ch. 5, ProloG pt. 1

First, let me thank Stuart Halloway for picking up the On Lisp -> Clojure port where I left off. I do not know if that was intentional, but in any case it makes for nice reading to start with my first 5 chapters and then transition right into Mr. Halloway’s posts (which are much higher quality IMO).

“)

; One of my favorite parts from On Lisp is his implementation of an embedded Prolog interpreter based on a simple database and inference system. My main goal for starting the On Lisp -> Clojure series was to eventually have this embedded Prolog system to use in my own applications. I will start out by just talking about a few preliminary structures and functions and then expand on them in future installments.

;


;;
;; The original Lisp make-hash-table function works on a
;; cons-cell structure, however Clojure provides a persistent
;; hash structure instead.  I am not going to port the Common
;; Lisp function to Clojure, but instead will modify the Prolog
;; implementation to fit a more idiomatic Clojure approach.
;;
(defn makedb []
  nil)

(def *defaultdb* (ref (makedb)))

(defn cleardb
  "Takes a db and clears it"
  ([] (cleardb *defaultdb*))
  ([db] (dosync (refset db nil))))

(defn dbquery
  "Takes a db and a key and returns the mapped val"
  ([key] (dbquery *defaultdb* key))
  ([db key] (get @db key)))

;;
;; db-push in Clojure is a bit trickier since it will be working
;; on a referenced persistent hash map.  This version is larger
;; than the On Lisp version do to the fact that the database
;; being queried is an in-transaction value.  
;;
(defn dbpush
  "Stores a value in a the db"
  ([key val] (dbpush *defaultdb* key val))
  ([db key val]
     (dosync
      (commute db
               (fn [thedb key val]
                 (assoc thedb key (cons val (get thedb key))))
               key
               val))))

;;
;; fact is almost a direct translation save for minor syntax diffs
;;
(defmacro fact
  [pred & args]
  `(do
     (dbpush '~pred '~args)
     '~args))

(defn testpt1 []
  (fact painter reynolds joshua english)
  (fact painter canale antonio venetian)
  (dbquery 'painter))

;

; There is definitely some room for improvement (suggestions/criticisms always welcome), but these initial functions work the same as the On Lisp originals, so that’s all for now. I’ll come back later for more.

;-m

3 Comments, Comment or Ping

  1. Link to github is broken.

  2. Andrew Stoeckley

    Interesting stuff. Do you have a github link updated? I’m curious your motivation to actually use this in software, instead of core.logic, which I would expect to be more robust.

  3. I decided to remove the Github repo because the code was not really up to date with the latest Clojure features. Remember, this post was written when Clojure was very young, so features like protocols, reducers, and even core.logic didn’t yet exist.

Reply to “On Lisp -> Clojure: ProloG (pt. 1)”