【问题标题】:Solving Dinesman's multiple-dwelling example using clojure's core.logic/core.match使用 clojure 的 core.logic/core.match 解决 Dinesman 的多住宅示例
【发布时间】:2012-06-29 04:55:13
【问题描述】:

看完 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 解决此问题的示例

【问题讨论】:

    标签: clojure clojure-core.logic


    【解决方案1】:

    这是 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])
    

    【讨论】:

    • 哦,太酷了 =) 非常感谢!下周我会玩得很开心,玩弄所有这些是如何工作的。 (我还没有想到在单词后附加元音的整个概念)。
    • 是的,元音对我来说也没有任何意义。我只是将我所有的逻辑函数命名为以o 结尾,并希望一切顺利。 condacondecondu 似乎是语言中的特殊情况。通过阅读 The Reasoned Schemer(我强烈推荐),我觉得o 可能代表“一次”,但对我来说仍然没有意义。
    • 我在这里找到了 core.logic github.com/swannodette/logic-tutorial 的另一个谜题...'斑马谜题'
    • @amalloy 引起我注意 gist.github.com/3043632 之后的另一种可能的方法。 rembero 和 permuteo 现在也是 core.logic 的一部分。
    【解决方案2】:

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

    编辑

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

    【讨论】:

    • 我想当我稍微清醒一点时,我必须玩那个门游戏 =) 你现在如何使用求解器?
    猜你喜欢
    • 2017-03-31
    • 1970-01-01
    • 2020-05-02
    • 2012-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多