我已经使用clojure了一段时间,但只是从core.logic开始。
给定一个像1 2 3 4
这样的域,我想得到一个像([[1 2] [3 4]])
这样的两个向量的向量。
注意:这只是我真正想做的事情的简化版本。 :)参见:https://github.com/adamhoward/lineup
我在网上找到了非成员(member)的定义:
(defne not-membero [x l]
([_ []])
([_ [?y . ?r]]
(!= x ?y)
(not-membero x ?r)))
我正在尝试像这样使用它:
(run 1 [q]
(fresh [w x
y z]
(== q [[w x]
[y z]])
(infd w x y z (domain 1 2 3 4))
(everyg distinctfd [[w x] [y z]])
(everyg #(not-membero % [y z]) [w x])))
在Emacs中运行此命令会给我一条
Evaluation aborted.
消息。当我尝试将
membero
替换为not-membero
时,我得到了([[1 2] [1 2]])
,这对我来说很有意义。第一个矢量[w x]
中的每个元素都是第二个矢量[y z]
的成员。但是,当我调用
run 2
时,我得到了([[1 2] [1 2]] [[1 2] [1 3]])
。我不明白[[1 2] [1 3]]
对于上述规则如何正确。我不正确了解everyg
吗?任何指导(包括rtfmanual,rtfbook,rtfdissertation)都将受到赞赏。谢谢。
编辑:可能已解决此问题。
仍然不确定
membero
的奇怪结果,但是我发现我可以做到这一点,而不是not-membero
目标:(everyg #(distinctfd (conj [y z] %)) [w x])
映射到
[w x]
的[y z]
的每个元素都包含所有不同的值。这可能比没有成员(member)的效率低,所以我仍然愿意寻求帮助。 最佳答案
您的示例似乎与此相同:
(run* [q]
(fresh [w x y z]
(fd/in w x y z (fd/domain 1 2 3 4))
(== q [[w x] [y z]])
(fd/distinct [w x y z])))
但是看到足球问题...
(ns test
(:refer-clojure :exclude [==])
(:use clojure.core.logic)
(require [clojure.core.logic.fd :as fd]))
(defn game [g] (fresh [a b c d e] (== g [a b c d e])))
(def players (range 1 11))
(defne not-membero [x l]
([_ []])
([_ [?y . ?r]]
(!= x ?y)
(not-membero x ?r)))
(defne plays [player games]
([_ []])
([_ [?f ?s . ?r]]
(membero player ?f) ; if you play this game
(not-membero player ?s) ; do not play next game
(plays player ?r))
([_ [?f ?s . ?r]]
(membero player ?s)
(not-membero player ?f)
(plays player ?r)))
(defne goalies [games]
([[[_ _ _ _ ?a]
[_ _ _ _ ?b]
[_ _ _ _ ?c]
[_ _ _ _ ?d]]]
(fd/in ?a ?b ?c ?d (apply fd/domain players))
(not-membero 1 [?a ?b ?c ?d]) ; star player != goalie
(fd/distinct [?a ?b ?c ?d]))) ; not goalie twice
(defn -main [& args]
(run 1 [q]
(fresh [a b c d]
(game a)
(game b)
(game c)
(game d)
(== q [a b c d])
(goalies q)
(everyg #(plays % q) players))))