我正在使用core.logic建模家族树。我想run*
的查询并让他们返回所有结果而没有重复。用def tabled
替换所有defn
给我我期望的结果(至少现在),并且我知道condu
和onceo
可以减少结果的数量,但我不确定这些是否是消除重复的最佳方法。使用core.logic查询家族树时消除重复结果
我特别担心我目前的方法,因为它似乎是重复的工作来声明关系和功能。我知道我的一些关系是'相互递归的'(mothero
和womano
互相引用),但我这样做是因为将来我可能会添加一个新的(defrel mother*)
,这应该允许它推断出母亲既是父母也是一个女人。
(defrel man* person)
(defrel woman* person)
(defrel parent* child father)
(fact man* :Father)
(fact woman* :Mother)
(fact man* :Son)
(fact woman* :Daughter)
(fact parent* :Son :Father)
(fact parent* :Son :Mother)
(fact parent* :Daughter :Father)
(fact parent* :Daughter :Mother)
(defn mano [person]
(conde
[(man* person)]
[(fresh [c]
(fathero c person))]))
(defn womano [person]
(conde
[(woman* person)]
[(fresh [c]
(mothero c person))]))
(defn parento [child person]
(conde
[(parent* child person)]
[(mothero child person)]
[(fathero child person)]))
(defn fathero [child father]
(all
(mano father)
(parento child father)))
(defn mothero [child mother]
(all
(womano mother)
(parento child mother)))
(defn siblingso [c1 c2 mother father]
(all
(mothero c1 mother)
(mothero c2 mother)
(fathero c1 father)
(fathero c2 father)
(!= c1 c2)))
(run 10 [q]
(fresh [child parent]
(parento child parent)
(== q [child parent])))
(run 10 [q]
(fresh [c1 c2 p1 p2]
(siblingso c1 c2 p1 p2)
(== q [c1 c2 p1 p2])))
我定义函数parento,fathero,siblingso等的原因是我想用它们作为构建块来定义更大的关系。就像cousinso一样,使用siblingso和parento会更容易定义。而不是仅限于父*。我想最终为任何类型的关系,兄弟,叔叔,表弟,祖先,后代,相关等构建函数。我只是不知道如何定义这些关系,以便他们将接受新的关系姊妹*,同时在运行时也终止*。 – WuHoUnited 2012-03-16 02:59:49
我已经更新了我的答案,以包含brothero(简化版)的示例,希望这可以帮助您实现目标! ;-) – 2012-03-16 04:27:11
我在最后一个例子中做了一个小改动,因为在这种情况下不需要使用'defne'。 – 2012-03-16 20:48:19