Clojure core.logic找到满足所有谓词的所有成员?

时间:2016-04-11 22:08:58

标签: clojure clojure-core.logic

我在Clojure中有以下代码(使用core.logic):

(db-rel parent x y)
(db-rel go-to-school x y)

(def schools
  (db
    [parent 'Adam 'Ana]
    [parent 'Adam 'Andre]
    [parent 'Adam 'Alan]
    [parent 'Bernard 'Bia]
    [parent 'Bernard 'Beatrice]
    [parent 'Carl 'Carlos]
    [parent 'Carl 'Connie]

    [go-to-school 'School1 'Ana]
    [go-to-school 'School1 'Andre]
    [go-to-school 'School2 'Alan]
    [go-to-school 'School2 'Bia]
    [go-to-school 'School2 'Beatrice]
    [go-to-school 'School1 'Carlos]
    [go-to-school 'School2 'Connie]))

我想要的是找到所有孩子都去同一所学校的所有父母。所以,按照上面的列表,我的预期回报是('Bernard),因为他的两个女儿去了“school2”,其中每个其他父母至少有一个孩子不会去其他人的同一所学校。 / p>

core.logic可以实现吗?如果是这样,我该怎么做?

1 个答案:

答案 0 :(得分:1)

永远不要忘记,当您使用Core.logic时,您可以完全访问Clojure。让我们将每位家长与学校联系起来,并在那里工作:

set

我使用标准的Clojure函数group-by来获得独特的结果。从那里开始,我们可以filter第一个元素,first输出计数大于1的所有内容,结果将是将所有孩子送到一所学校的父母(作为键,所以我们和#39;我需要从每个项目中取(defn parent-with-one-school [] (->> (set (pldb/with-db schools (run* [par sch] (fresh [kid] (go-to-school sch kid) (parent par kid))))) (group-by first) (filter #(= 1 (count (second %)))) (map first))) 元素。)

stack-prj.logic-school> (parent-with-one-school)
(Bernard)

让我们测试吧!

patient1.size()<N