Skip to content

Instantly share code, notes, and snippets.

@nberger
Created August 1, 2015 16:14
Show Gist options
  • Save nberger/6b0ad2a68c52a6005c6a to your computer and use it in GitHub Desktop.
Save nberger/6b0ad2a68c52a6005c6a to your computer and use it in GitHub Desktop.
(ns isorto.core-test
(:require [clojure.core.logic :as l :refer [run run*]]
[clojure.test :refer :all]
[isorto.core :refer [isorto]]))
(deftest isorto-test
(is (= [[]]
(run* [q] (isorto q ()))))
(is (= [[]]
(run* [q] (isorto () q))))
(is (= [[1]]
(run* [q] (isorto (list 1) q))))
(is (= [[1]]
(run* [q] (isorto q (list 1)))))
(is (= [[1 2 3] [1 3 2] [2 1 3] [2 3 1] [3 1 2] [3 2 1]]
(->> (run* [q] (isorto q (list 1 2 3)))
(map vec)
sort)))
(is (= [[0 1 2 3 4 5 6 7 8 9]]
(run* [q]
(isorto (shuffle (range 10)) q)))))
(ns isorto.core
(:require [clojure.core.logic :as l :refer :all]
[clojure.core.logic.fd :as fd])
(:refer-clojure :exclude [==]))
(declare inserto)
(defn isorto
([l sl]
(isorto l () sl))
([l acc sl]
(conde
[(l/emptyo l) (== acc sl)]
[(fresh [f r nacc]
(project [sl acc]
(if (and (not (lvar? sl))
(= (count acc) (count sl)))
fail ; acc is already long as sl, let's stop here
s#))
(conso f r l)
(inserto f acc nacc)
(isorto r nacc sl))])))
(defn inserto
([x l nl]
(conde
[(== l ()) (== nl (list x))]
[(fresh [f r nr]
(conso f r l)
(conde
[(fd/<= x f) (conso x l nl)]
[(fd/> x f)
(conso f nr nl)
(inserto x r nr)]))])))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment