Skip to content

Instantly share code, notes, and snippets.

@gfredericks
Created June 5, 2012 18:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gfredericks/2876680 to your computer and use it in GitHub Desktop.
Save gfredericks/2876680 to your computer and use it in GitHub Desktop.
condr
(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