Estoy modelando un árbol genealógico con core.logic. Me gustaría run*
las consultas y hacer que devuelvan todos los resultados sin duplicación. Reemplazar todos defn
con def tabled
me da los resultados que espero (al menos por ahora), y sé que condu
y onceo
pueden reducir el número de resultados, pero no estoy seguro si alguno de ellos es la mejor manera de eliminar duplicados.Eliminando resultados duplicados al consultar un árbol genealógico con core.logic
Estoy particularmente preocupado por mi enfoque actual, ya que parece duplicar el trabajo para declarar tanto las relaciones como las funciones. Sé que algunas de mis relaciones son 'mutuamente recursivas' (mothero
y womano
se refieren entre sí), pero lo hice porque en el futuro podría agregar un nuevo (defrel mother*)
, lo que debería permitir inferir que una madre es a la vez madre y padre una mujer.
(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])))
La razón por la que he definido las funciones parento, fathero, siblingso, etc. es que luego quiero usarlas como bloques de construcción para definir relaciones más grandes. Como primo sería más fácil de definir usando siblingso y parento. en lugar de restringirlo a solo padre *. Me gustaría terminar las funciones de compilación para cualquier tipo de relación, hermanos, tíos, primos segundo, antepasados, descendientes, relacionados, etc. Simplemente no sé cómo definirlos para que acepten nuevas relaciones como hermana * mientras también termina cuando se ejecuta con ejecución *. – WuHoUnited
He actualizado mi respuesta para incluir un ejemplo de (versión simplificada) de 'brothero', ¡espero que esto lo ayude a lograr sus objetivos! ;-) –
He hecho otro pequeño cambio en el último ejemplo, ya que no había necesidad de usar 'defne' en este caso. –