New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Nominal unification inspired by alphaKanren #12
Changes from 1 commit
475239f
1b38ce4
502007e
ffdbdde
60e54c6
5b5734b
0fc2518
ea3a87f
7c52d1d
211e155
5785a72
0e35e8c
26297e2
a3b9872
10e5f15
b7d272f
0f6e600
8e5a733
a7822f7
b59d7c8
63a9805
3f8b6d1
5dbcf8f
db83189
feb75b3
b419144
74167de
8ee782a
baec652
673babc
104b154
1cc361f
d4a7558
5a98456
bb32fe6
9047dd8
2fb005c
0910252
62bdd93
e00d5a0
2ea7167
369493e
40fe26d
8329675
833979b
9f59a44
974f6ca
f3330bc
a5b9301
7750c88
2c17edb
f1ffc6a
a176adf
1e1bc79
9bba714
a005907
ddb8a4d
64bb9af
5106567
ebd8f63
c33bfac
84d9770
f70b108
d44949c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,6 +20,7 @@ | |
;; ============================================================================= | ||
;; Marker Interfaces | ||
|
||
(definterface IWalkable) | ||
(definterface IVar) | ||
|
||
;; ============================================================================= | ||
|
@@ -309,7 +310,7 @@ | |
;; ============================================================================= | ||
;; Constraint Store | ||
|
||
(declare lvar? interval multi-interval) | ||
(declare lvar? walkable? interval multi-interval) | ||
|
||
(defn bounds [i] | ||
(pair (lb i) (ub i))) | ||
|
@@ -1050,12 +1051,12 @@ | |
(Substitutions. (assoc s u v) l cs cq cqs _meta))) | ||
|
||
(walk [this v] | ||
(if (lvar? v) | ||
(if (walkable? v) | ||
(loop [lv v [v vp :as me] (find s v)] | ||
(cond | ||
(nil? me) lv | ||
|
||
(not (lvar? vp)) | ||
(not (walkable? vp)) | ||
(if-let [sv (and (subst-val? vp) (:v vp))] | ||
(if (= sv ::unbound) | ||
(with-meta v (assoc (meta vp) ::unbound true)) | ||
|
@@ -1268,6 +1269,10 @@ | |
(defn lvar? [x] | ||
(instance? clojure.core.logic.IVar x)) | ||
|
||
(defn walkable? [x] | ||
(or (lvar? x) | ||
(instance? clojure.core.logic.IWalkable x))) | ||
|
||
;; ============================================================================= | ||
;; LCons | ||
|
||
|
@@ -2891,6 +2896,10 @@ | |
a) | ||
((remcg c) a)))) | ||
|
||
(defn addcg-now [c] | ||
(fn [a] | ||
(bind* a (addcg c) (run-constraint c) (fn [a] (queue a c))))) | ||
|
||
;; TODO NOW: try an implementation that allows constraints | ||
;; to run roughly in the order they normaly would. reverse | ||
;; xcs in run-constraints, (into cq (reverse xcs)), cq should | ||
|
@@ -2982,7 +2991,8 @@ | |
(defn reify-constraints [v r cs] | ||
(let [rcs (->> (vals (:cm cs)) | ||
(filter reifiable?) | ||
(map #(reifyc % v r)))] | ||
(map #(reifyc % v r)) | ||
(filter #(not (nil? %))))] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm curious about this, why do we need to check for nil? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In reifyc for the nom-hash constraint, I just reify the constraint if it's relevant to the end result. This is consistent with alphaKanren. For example,
would otherwise return (([-> _0 [-> _1 _0]] :- lvar:x5037#lvar:xc5049 nom:b5036#lvar:gc5025 nom:b5036#_0 nom:b5036#[nom:b5026 lvar:trand5024])) instead of just ((-> _0 (-> _1 _0))) Because the constraints are on vars and noms that are not in the final result, they're just noisy and not interesting to the end user. Simpler examples. Contrast:
For the first case, we don't want:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, makes sense. |
||
(if (empty? rcs) | ||
(choice (list v) empty-f) | ||
(choice (list `(~v :- ~@rcs)) empty-f)))) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ha, that's a fun use of
bind*
, I'm happy how little you had to changelogic.clj
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed! And this could even be in the nominal package, but perhaps, it is generally useful?