I have the following knowledge base representing a directed graph:
edge(1, 2).
edge(2, 3).
edge(2, 4).
edge(3, 3).
edge(3, 4).
edge(3, 5).
edge(4, 3).
I want to print difference between number of incoming and outgoing edges for each node. Here is what I have so far:
outgoing(E) :- edge(E, _).
ingoing(E) :- edge(_, E).
count_outgoing(E, Count) :- findall(E, outgoing(E), Bag), length(Bag, Count).
count_ingoing(E, Count) :- findall(E, ingoing(E), Bag), length(Bag, Count).
count(E, D) :- count_outgoing(E, OC), count_ingoing(E, IC), D is IC - OC.
count :- edge(E, _), count(E, D), write(E), write(' '), write(D), nl, fail; true.
However, this solution repeats nodes that have more than one outgoing edge. How can I fix it? (Let's skip the fact that if a node doesn't have any outgoing edges, it won't get printed for now).
The problem is that
count_outgoing/2
andcount_incoming/2
are implicitly finding your nodes. If you did it explicitly, you'd have the control you need. The simplest thing to do is get a set of nodes and iterate that. Like this:Your main could then use
member/2
to generate the nodes: