List of unique DAG parents with core.logic

Here (hopefully) a simple logic program that I've been stuck on for a while.

I have a DAG represented by the relation to the edge in core.logic, when creating a list of parent nodes I get duplicates when I have "diamond shapes" on the graph (I'm not talking about cycles here).

Is there a way to generate a separate list of parents in this case (by re-writing the parent or similar)?

(defrel edge ab) (fact edge :a :b) (fact edge :a :c) (fact edge :b :d) (fact edge :c :d) (defne parento [xy] ([xy] (edge yx)) ([xy] (fresh [z] (edge zx) (parento zy)))) (run* [q] (parento :dq)) ;; => (:b :c :a :a) 

I want to get (: b: c: a), and I want to do this inside the run * operator (i.e. wrapping the result in the set is not what I am aiming for).

Also, adding "^: tabled" to parento seems to do the trick, but I don't want memoization to be added in it.

+6
source share
1 answer

There is no way to do this without leaving relational programming if you define individual facts for the edges, as you did. One solution is to simply pass the entire list of results to the set Clojure constructor. Another option is to work with all nodes in one pass in your logic program.

It might be useful to look at existing Prolog solutions to this problem and translate what you find.

+1
source

Source: https://habr.com/ru/post/926096/


All Articles