检查三角形在Prolog中是否是等边的
Check if triangle is equilateral in Prolog
我正在学习 Prolog 并尝试创建一个程序来检查三角形是否是等边的。
这是我的代码
equilateral(point2d(X1,Y1),point2d(X2,Y2),point2d(X3,Y3)):-
((X2-X1)*(X2-X1) + (Y2-Y1)*(Y2-Y1)) =:= ((X3-X2)*(X3-X2) + (Y3-Y2)*(Y3-Y2)),
((X3-X2)*(X3-X2) + (Y3-Y2)*(Y3-Y2)) =:= ((X3-X1)*(X3-X1) + (Y3-Y1)*(Y3-Y1)).
当我运行equilateral(point2d(2,3),point2d(6,3),point2d(4,3+sqrt(12))).
时,结果给了false,我知道三个点(2,3)(6,3)(4,3+sqrt(12))做一个等边三角形(已经用手检查过)。请让我知道我错过了什么?
比较浮点数是否相等通常很危险。在您的特定情况下,如果您跟踪查询,您将获得:
| ?- trace.
The debugger will first creep -- showing everything (trace)
yes
{trace}
| ?- equilateral(point2d(2,3),point2d(6,3),point2d(4,3+sqrt(12))).
1 1 Call: equilateral(point2d(2,3),point2d(6,3),point2d(4,3+sqrt(12))) ?
2 2 Call: (6-2)*(6-2)+(3-3)*(3-3)=:=(4-6)*(4-6)+(3+sqrt(12)-3)*(3+sqrt(12)-3) ?
2 2 Fail: (6-2)*(6-2)+(3-3)*(3-3)=:=(4-6)*(4-6)+(3+sqrt(12)-3)*(3+sqrt(12)-3) ?
1 1 Fail: equilateral(point2d(2,3),point2d(6,3),point2d(4,3+sqrt(12))) ?
如果您单独评估 =:=/2
个参数,您可以看到查询失败的原因:
| ?- X is (6-2)*(6-2)+(3-3)*(3-3).
X = 16
yes
| ?- X is (4-6)*(4-6)+(3+sqrt(12)-3)*(3+sqrt(12)-3).
X = 15.999999999999998
yes
通常,如果两个浮点值相等或接近,您就会认为它们相同。关闭的一个好的定义取决于应用程序,并且有几个可用的标准定义(例如近似相等、基本相等或公差相等)。我强烈建议您找到并阅读一本很好的浮点运算介绍。
P.S。您可以 运行 与大多数 Prolog 系统一起使用的 Logtalk 为四种不同的相等性测试提供了库支持:https://logtalk.org/library/number_0.html 使用这些库谓词之一将使您能够获得 equilateral/3
的工作定义谓词。
我正在学习 Prolog 并尝试创建一个程序来检查三角形是否是等边的。
这是我的代码
equilateral(point2d(X1,Y1),point2d(X2,Y2),point2d(X3,Y3)):-
((X2-X1)*(X2-X1) + (Y2-Y1)*(Y2-Y1)) =:= ((X3-X2)*(X3-X2) + (Y3-Y2)*(Y3-Y2)),
((X3-X2)*(X3-X2) + (Y3-Y2)*(Y3-Y2)) =:= ((X3-X1)*(X3-X1) + (Y3-Y1)*(Y3-Y1)).
当我运行equilateral(point2d(2,3),point2d(6,3),point2d(4,3+sqrt(12))).
时,结果给了false,我知道三个点(2,3)(6,3)(4,3+sqrt(12))做一个等边三角形(已经用手检查过)。请让我知道我错过了什么?
比较浮点数是否相等通常很危险。在您的特定情况下,如果您跟踪查询,您将获得:
| ?- trace.
The debugger will first creep -- showing everything (trace)
yes
{trace}
| ?- equilateral(point2d(2,3),point2d(6,3),point2d(4,3+sqrt(12))).
1 1 Call: equilateral(point2d(2,3),point2d(6,3),point2d(4,3+sqrt(12))) ?
2 2 Call: (6-2)*(6-2)+(3-3)*(3-3)=:=(4-6)*(4-6)+(3+sqrt(12)-3)*(3+sqrt(12)-3) ?
2 2 Fail: (6-2)*(6-2)+(3-3)*(3-3)=:=(4-6)*(4-6)+(3+sqrt(12)-3)*(3+sqrt(12)-3) ?
1 1 Fail: equilateral(point2d(2,3),point2d(6,3),point2d(4,3+sqrt(12))) ?
如果您单独评估 =:=/2
个参数,您可以看到查询失败的原因:
| ?- X is (6-2)*(6-2)+(3-3)*(3-3).
X = 16
yes
| ?- X is (4-6)*(4-6)+(3+sqrt(12)-3)*(3+sqrt(12)-3).
X = 15.999999999999998
yes
通常,如果两个浮点值相等或接近,您就会认为它们相同。关闭的一个好的定义取决于应用程序,并且有几个可用的标准定义(例如近似相等、基本相等或公差相等)。我强烈建议您找到并阅读一本很好的浮点运算介绍。
P.S。您可以 运行 与大多数 Prolog 系统一起使用的 Logtalk 为四种不同的相等性测试提供了库支持:https://logtalk.org/library/number_0.html 使用这些库谓词之一将使您能够获得 equilateral/3
的工作定义谓词。