This is a terrible example, but say I have points a
, b
and c
and blue and red lines, e.g. line(blue,a)
means point a
lines on a blue line.
point(a).
point(b).
point(c).
line(blue,a).
line(blue,b).
line(red,a).
line(red,c).
I want to find out which points P
lie on more than one line (so a
in this case as it's on the blue and red line).
I made a start and got this:
multiple_points(P) :- point(P), point(_,P).
When I run the query ?- multiple_points(P).
all points that are on a line appear, but I only want duplicates shown to see which points appear on more than one line.
Is there an easy one line way to only show values of P
which are duplicates?
The approach is simple to find all the points that lie on the coloured lines. Then find which points occurs multiple times.
point(a).
point(b).
point(c).
line(blue,a).
line(blue,b).
line(red,a).
line(red,c).
points(Z):- findall(X,(line(_,X)) ,Z).
multi([],[]):- !.
multi([H|T],[H|Z]):- member(H,T) , multi(T,Z),!.
multi([H|T],Z):- \+member(H,T) , multi(T,Z),!.
get_points(List):- points(Z) , multi(Z,List).
OUTPUT
?- get_points(List).
List = [a]
It will work even when you have multiple points that lie on multiple lines.
lets your knowledge base is
line(blue,a).
line(blue,b).
line(red,a).
line(red,c).
line(purple,c).
The output for this instance is
OUTPUT
?- get_points(List).
List = [a,c]
If no point exists on multiple lines the output would be an empty list
List= []
.
Hope this helped you.