Home > database >  Prolog: Find all equilateral triangles which are built from DB points
Prolog: Find all equilateral triangles which are built from DB points

Time:06-13

I'm new to Prolog and my task requires finding all equilateral triangles which are built from DB points. As a result, I'm getting identical points of the triangles. I do not understand what the problem is. Help me pls!

:- dynamic
 point/3.
%?Point_Sign, ?Abscissa, ?Ordinate
db_filling:-
    point(_,_,_),!.
db_filling:-
    assert(point(a,1,1)),
    assert(point(b,1,2)),
    assert(point(c,1,3)),
    assert(point(d,2,2)),
    assert(point(e,3,3)),
    assert(point(f,-1,1)),
    assert(point(g,-2,1)),
    assert(point(h,-2,2)),
    assert(point(i,-3,3)),
    assert(point(j,-3,-1)),
    assert(point(k,-3,-2)),
    assert(point(l,-3,-3)),
    assert(point(n,-1,-1)),
    assert(point(m,-3,0)),
    assert(point(o,3,0)),
    assert(point(p,0,3)).

%  List
points_main(Xs):-
    db_filling,
    findall(Xs1,equilateral_triangles(Xs1),Xs).

%  Points
equilateral_triangles([P1,P2,P3]):-
    point(P1,X1,Y1),
    point(P2,X2,Y2),
    point(P3,X3,Y3),
    L1 is sqrt((X2 - X1)^2   (Y2 - Y1)^2),
    L2 is sqrt((X3 - X2)^2   (Y3 - Y2)^2),
    L3 is sqrt((X1 - X3)^2   (Y1 - Y3)^2),
    L1 = L2,
    L2 = L3.

Result:

?- points_main(Res).
Res = [[a, a, a], [b, b, b], [c, c, c], [d, d, d], [e, e, e], [f, f, f], [g, g|...], [h|...], [...|...]|...].

CodePudding user response:

You have a couple of fundamental issues here.

From memory, the two-dimensional coordinates of an equilateral triangle cannot all be integers. You must have at least one irrational number. Computers are good a representing irrational numbers.

So, you're also confusing real maths with computer maths. You can't simply get the sqrt and check for equality.

To illustrate I produced these three points:

point(j1,0,0).
point(j2,1,0).
point(j3,0.5,0.866025403784439). % 1/2 & sqrt(3)/2

That's an equilateral triangle.

When I run that with your code, the lengths that get produced are like this:

[1.0,1.0000000000000004,1.0000000000000004]

They are all effectively 1.0, but of course 1.0000000000000004 is not 1.0. So, even this doesn't comeback as a equal.

So you are really forced to check the confidence as an epsilon to say two numbers are equal.

Here's what I did to do that:

points_main(Xs):-
    findall(Xs1,equilateral_triangles(Xs1),Xs).

equilateral_triangles([P1,P2,P3]):-
    point(P1,X1,Y1),
    point(P2,X2,Y2),
    P1 \= P2,
    point(P3,X3,Y3),
    P1 \= P3,
    P2 \= P3,
    L12 is sqrt((X2 - X1)^2   (Y2 - Y1)^2),
    L23 is sqrt((X3 - X2)^2   (Y3 - Y2)^2),
    L31 is sqrt((X1 - X3)^2   (Y1 - Y3)^2),
    D1223 is abs(L12 - L23),
    D1223<0.00000001,
    D2331 is abs(L23 - L31),
    D2331<0.00000001,
    D3112 is abs(L31 - L12),
    D3112<0.00000001.

Now, if I run that against my points above I get this:

?- points_main(Xs).
Xs = [[j1, j2, j3], [j1, j3, j2], [j2, j1, j3], [j2, j3, j1], [j3, j1, j2], [j3, j2, j1]].

All combinations of the above three points - so, yes, they are all equilateral triangles.

If I run against your original points, as expected, there are no equilateral triangles.

A few side notes.

(1) I removed all of the assert code. It wasn't helpful nor necessary to get your code working.

(2) you could define my j3 point as point(j3,0.5,X) :- X is sqrt(3)/2. and your original maths would work. However, this is just lucky. When dealing will floating-point numbers you can never be sure that two numbers are equal even though they should be.

(3) I introduced P1 \= P2, etc, to prevent the points unifying to themselves. That's why you got [a,a,a],... etc.

  • Related