5

在观看了 Sussman 的讲座http://www.infoq.com/presentations/We-Really-Dont-Know-How-To-Compute后,我受到启发,尝试了一下 core.logic 和 core.match。我知道的唯一例子是我小时候做过的那些约束问题解决者。这是一个在 SICP 课程中使用的示例,并且在演讲中被提及:

贝克、库珀、弗莱彻、米勒和史密斯住在一栋只有五层楼的公寓的不同楼层。贝克不住在顶层。库珀不住在底层。弗莱彻既不住在顶层也不住在底层。米勒住在比库珀更高的楼层。史密斯不住在弗莱彻家附近的楼层。弗莱彻不住在库珀附近的楼层。每个人都住在哪里?

我在 Rosettacode 网站上找到了这个: http ://rosettacode.org/wiki/Dinesman%27s_multiple-dwelling_problem#PicoLisp

但不太清楚这如何转化为clojure。我希望有人可以提供使用 core.logic 或 core.match 解决此问题的示例

4

2 回答 2

3

这是 core.logic 中的一个解决方案。它不完全等同于 picolisp 算法,因为我们没有可用的相同原语,但它是相同的一般思想。感谢您向我介绍这个问题 - 发明很有趣permuteobeforeo而且我有了第一个使用的借口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])
于 2012-07-01T08:27:14.457 回答
2

我自己刚开始接触 LP,我的第一个尝试是https://github.com/amalloy/doors ,它是http://rooms.jmpup.com上自动生成的逻辑谜题的求解器。现在我定义了一些对所有谜题普遍有用的关系,但我还没有做任何工作以编程方式将特定谜题实际翻译成 core.logic。你可以看到我手动翻译的一个谜题——网页展示core.logic 编码。也许这会让您了解如何使用 core.logic,尽管我自己还是新手,所以肯定会有不完美之处。

编辑

查看 picolisp 解决方案后,我认为它不会直接转换为 core.logic,因为据我所知,直接否定支持还不存在。

于 2012-06-29T06:11:51.913 回答