Created
June 5, 2012 18:19
-
-
Save gfredericks/2876680 to your computer and use it in GitHub Desktop.
condr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns numerology.logic.extensions | |
(:refer-clojure :exclude [==]) | |
(:use clojure.core.logic)) | |
;; private function pasted from core.logic | |
(defn- bind-conde-clause [a] | |
(fn [g-rest] | |
`(bind* ~a ~@g-rest))) | |
(defmacro condr | |
[& clauses] | |
(let [a (gensym "a")] | |
`(fn [~a] | |
(let [shuffled-clauses# (shuffle [~@(for [clause clauses] | |
(list 'fn [] ((bind-conde-clause a) clause)))])] | |
(-inc | |
((reduce (fn [acc# clause#] (fn [] (mplus (clause#) acc#))) shuffled-clauses#))))))) | |
(ns numerology.logic.number-play | |
(:refer-clojure :exclude [==]) | |
(:use clojure.core.logic numerology.logic.extensions)) | |
(def nums 1000) | |
(def num? (set (range nums))) | |
(defrel +o ^:index x ^:index y ^:index z) | |
(defrel *o ^:index x ^:index y ^:index z) | |
(doseq [x (range nums) | |
y (range nums)] | |
(when (and (num? (+ x y)) (pos? x) (pos? y)) | |
(fact +o x y (+ x y))) | |
(when (and (num? (* x y)) (< 1 x) (< 1 y)) | |
(fact *o x y (* x y)))) | |
(defn expresso | |
[x expr] | |
(condr | |
((== expr x)) | |
((fresh [a b a' b'] | |
(condr | |
((+o a b x) (== expr (list '+ a' b'))) | |
((+o a x b) (== expr (list '- b' a'))) | |
((*o a b x) (== expr (list '* a' b'))) | |
((*o a x b) (== expr (list '/ b' a')))) | |
(expresso a a') | |
(expresso b b'))))) | |
(run 2 [q] (expresso 42 q)) ;; second value is nondeterministic like we want, but first value is consistently 42 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment