我正在用 core.logic 建模一个家谱。我想run*
查询并让他们返回所有结果而不重复。将所有defn
替换def tabled
为我所期望的结果(至少现在是这样),我知道这一点condu
并且onceo
可以减少结果的数量,但我不确定其中任何一个是否是消除重复项的最佳方法。
我特别担心我目前的方法,因为声明关系和函数似乎是重复的工作。我知道我的一些关系是“相互递归的”(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])))