这是 core.logic 中的一个解决方案。它不完全等同于 picolisp 算法,因为我们没有可用的相同原语,但它是相同的一般思想。感谢您向我介绍这个问题 - 发明很有趣permuteo
,beforeo
而且我有了第一个使用的借口conda
。 编辑:使用conda
那里是可怕和错误的,我又回到了conde
现在。哦,好吧,总有一天。
(ns dwelling.core
(:refer-clojure :exclude [==])
(:use clojure.core.logic))
(defn rembero [x l out]
(fresh [head tail]
(conso head tail l)
(conde [(== x head) (== out tail)]
[(fresh [new-out]
(conso head new-out out)
(rembero x tail new-out))])))
(defn permuteo [a b]
(conde [(emptyo a) (emptyo b)]
[(fresh [head tail b-tail]
(conso head tail a)
(rembero head b b-tail)
(permuteo tail b-tail))]))
(defn beforeo [x y l]
(fresh [head tail]
(conso head tail l)
(conde [(== x head) (fresh [more-tail]
(rembero y tail more-tail))]
[(beforeo x y tail)])))
(defn not-adjacento [x y l]
(fresh [head tail more]
(conso head tail l)
(resto tail more)
(conde [(== x head) (membero y more)]
[(== y head) (membero x more)]
[(not-adjacento x y tail)])))
(run* [tenants]
(fresh [a b c d e]
(== [a b c d e] tenants)
(permuteo tenants '[Cooper Baker Fletcher Miller Smith])
(!= e 'Baker)
(!= a 'Cooper)
(!= a 'Fletcher)
(!= e 'Fletcher)
(beforeo 'Cooper 'Miller tenants)
(not-adjacento 'Smith 'Fletcher tenants)
(not-adjacento 'Fletcher 'Cooper tenants)))
;; ([Smith Cooper Baker Fletcher Miller])