Skip to content

Commit

Permalink
* update README
Browse files Browse the repository at this point in the history
* clj -> cljc
* generalize macro usage, macro is only used internally
  • Loading branch information
swannodette committed Sep 27, 2024
1 parent 8de557b commit 1d06241
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 29 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
clojure.core.unify
========================================

core.unify is a Clojure contrib library providing the following features:
core.unify is a Clojure & ClojureScript contrib library providing the following features:

* Factory functions for constructing unification binding, subst, and unification functions, with or without occurs checking

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
(ns ^{:doc "A unification library for Clojure."
:author "Michael Fogus"}
clojure.core.unify
#?(:cljs (:require-macros [clojure.core.unify-macros :refer [create-var-unification-fn]]))
(:require [clojure.zip :as zip]
#?(:clj [clojure.core.unify-macros :refer [create-var-unification-fn]])
[clojure.walk :as walk]))

(defn ignore-variable? [sym] (= '_ sym))
Expand All @@ -36,12 +38,13 @@
predicate. At the moment, the only meaning of `composite?` is:
Returns true if `(seq x)` will succeed, false otherwise."
[x]
(or (coll? x)
(nil? x)
(instance? Iterable x)
(-> x class .isArray)
(string? x)
(instance? java.util.Map x)))
#?(:clj (or (coll? x)
(nil? x)
(instance? Iterable x)
(-> x class .isArray)
(string? x)
(instance? java.util.Map x))
:cljs (seqable? x)))

(declare garner-unifiers)

Expand All @@ -58,6 +61,9 @@
(recur (zip/next (zip/insert-right z (binds current))))
:else (recur (zip/next z))))))

(defn occurs-check-error [expr]
#?(:clj (throw (IllegalStateException. (str "Cycle found in the path " expr)))
:cljs (throw (js/Error. (str "Cycle found in the path " expr)))) )

(defn- bind-phase
[binds variable expr]
Expand All @@ -66,28 +72,6 @@
binds
(assoc binds variable expr)))

(defn- determine-occursness
[want-occurs? variable? v expr binds]
(if want-occurs?
`(if (occurs? ~variable? ~v ~expr ~binds)
(throw (IllegalStateException. (str "Cycle found in the path " ~expr)))
(bind-phase ~binds ~v ~expr))
`(bind-phase ~binds ~v ~expr)))

(defmacro create-var-unification-fn
[want-occurs?]
(let [varp (gensym)
v (gensym)
expr (gensym)
binds (gensym)]
`(fn ~'var-unify
[~varp ~v ~expr ~binds]
(if-let [vb# (~binds ~v)]
(garner-unifiers ~varp vb# ~expr ~binds)
(if-let [vexpr# (and (~varp ~expr) (~binds ~expr))]
(garner-unifiers ~varp ~v vexpr# ~binds)
~(determine-occursness want-occurs? varp v expr binds))))))


(def ^{:doc "Unify the variable v with expr. Uses the bindings supplied and possibly returns an extended bindings map."
:private true}
Expand Down
33 changes: 33 additions & 0 deletions src/main/clojure/clojure/core/unify_macros.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
; Copyright (c) Rich Hickey. All rights reserved.
; The use and distribution terms for this software are covered by the
; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
; which can be found in the file epl-v10.html at the root of this distribution.
; By using this software in any fashion, you are agreeing to be bound by
; the terms of this license.
; You must not remove this notice, or any other, from this software.

(ns ^{:doc "A unification library for Clojure."
:author "Michael Fogus"}
clojure.core.unify-macros)

(defn- determine-occursness
[want-occurs? variable? v expr binds]
(if want-occurs?
`(if (clojure.core.unify/occurs? ~variable? ~v ~expr ~binds)
(clojure.core.unify/occurs-check-error ~expr)
(clojure.core.unify/bind-phase ~binds ~v ~expr))
`(clojure.core.unify/bind-phase ~binds ~v ~expr)))

(defmacro create-var-unification-fn
[want-occurs?]
(let [varp (gensym)
v (gensym)
expr (gensym)
binds (gensym)]
`(fn ~'var-unify
[~varp ~v ~expr ~binds]
(if-let [vb# (~binds ~v)]
(clojure.core.unify/garner-unifiers ~varp vb# ~expr ~binds)
(if-let [vexpr# (and (~varp ~expr) (~binds ~expr))]
(clojure.core.unify/garner-unifiers ~varp ~v vexpr# ~binds)
~(determine-occursness want-occurs? varp v expr binds))))))

0 comments on commit 1d06241

Please sign in to comment.