生成勾股三元数到无穷大

时间:2018-10-24 11:33:01

标签: prolog

我想生成所有勾股三元组(每次用户在序言中使用;生成新的三元组)。

我试图修改以下代码,该代码显示所有的勾股三元组,直到给定的N值(最大限制)。

原始算法生成三倍数直到给定值N:

pythagora(X,Y,Z,N) :-
   length(_, N),
   between(1,N,X),
   between(1,N,Y),
   between(1,N,Z),
   Z*Z =:= X*X + Y*Y.

我试图消除最大限制数N并将其替换为infinfinite,但是显然程序死了。除了between以外,我还可以使用其他哪些谓词来生成要测试的数字?

我的尝试如下:

pythagora(X,Y,Z):- between(1,inf,X), between(1,inf,Y), between(1,inf,Z), Z*Z =:= X*X + Y*Y.

我对Prolog完全陌生,因此,如果问题似乎不太乐观,我深表歉意。希望您能告诉我实现目标的正确方法。谢谢。

1 个答案:

答案 0 :(得分:1)

您提出的方法的问题在于,XY是通过between/3调用设置的,但随后也设置了Z。现在无论是否Z*Z =:= X*X + Y*Y,我们都只会递增 Z ,直到无穷大。因此,在为Z确定某个值之后,将不再产生勾股三重态,但是between/3将继续为Z提出新的值。

我们可以通过首先设置Z(此处始终是三元组的最大值)来解决问题。然后我们知道XY将始终在1Z之间(可以将边界设置得更“紧密”,但我将其保留为练习) ,因此我们可以将其实现为:

pythagora(X,Y,Z) :-
    between(1, inf, Z),
    between(1, Z, X),
    between(1, Z, Y),
    Z*Z =:= X*X + Y*Y.

由于XY是通过between/3调用统一的,并且值的数量限制为 ,因此我们可以确定最终这些调用将结束,因此我们将尝试为Z更高值查找三元组。

通过这种方法,我们得到:

?- pythagora(X, Y, Z).
X = 3,
Y = 4,
Z = 5 ;
X = 4,
Y = 3,
Z = 5 ;
X = 6,
Y = 8,
Z = 10 ;
X = 8,
Y = 6,
Z = 10 ;
X = 5,
Y = 12,
Z = 13 ;
X = 12,
Y = 5,
Z = 13 ;
X = 9,
Y = 12,
Z = 15 

这里有些重复,因此我们可以决定添加一个额外的限制,即X总是小于Y

pythagora(X,Y,Z) :-
    between(1, inf, Z),
    between(1, Z, X),
    between(X, Z, Y),
    Z*Z =:= X*X + Y*Y.

然后我们得到:

?- pythagora(X, Y, Z).
X = 3,
Y = 4,
Z = 5 ;
X = 6,
Y = 8,
Z = 10 ;
X = 5,
Y = 12,
Z = 13 ;
X = 9,
Y = 12,
Z = 15 ;