我想生成所有勾股三元组(每次用户在序言中使用;生成新的三元组)。
我试图修改以下代码,该代码显示所有的勾股三元组,直到给定的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并将其替换为inf
或infinite
,但是显然程序死了。除了between
以外,我还可以使用其他哪些谓词来生成要测试的数字?
我的尝试如下:
pythagora(X,Y,Z):- between(1,inf,X), between(1,inf,Y), between(1,inf,Z), Z*Z =:= X*X + Y*Y.
我对Prolog完全陌生,因此,如果问题似乎不太乐观,我深表歉意。希望您能告诉我实现目标的正确方法。谢谢。
答案 0 :(得分:1)
您提出的方法的问题在于,X
和Y
是通过between/3
调用设置的,但随后也设置了Z
。现在无论是否Z*Z =:= X*X + Y*Y
,我们都只会递增 Z
,直到无穷大。因此,在为Z
确定某个值之后,将不再产生勾股三重态,但是between/3
将继续为Z
提出新的值。
我们可以通过首先设置Z
(此处始终是三元组的最大值)来解决问题。然后我们知道X
和Y
将始终在1
和Z
之间(可以将边界设置得更“紧密”,但我将其保留为练习) ,因此我们可以将其实现为:
pythagora(X,Y,Z) :-
between(1, inf, Z),
between(1, Z, X),
between(1, Z, Y),
Z*Z =:= X*X + Y*Y.
由于X
和Y
是通过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 ;