我正在尝试编写一个谓词pythagorean(X,Y,Z,W)
,它可以生成所有三元组,例如X^2 + Y^2 = Z^2
,其中W >= X,Y,Z > 0
。
这就是我写的:
pyth(X,Y,Z,W) :-
X > 0,
Y > 0,
Z > 0,
S1 is X*X + Y*Y,
S2 is Z*Z,
S1 == S2,
W @> Z.
答案 0 :(得分:1)
使用clpfd!
:- use_module(library(clpfd)).
我们根据FD约束sum/3
,chain/2
,(#=)/2
和(#<)/2
定义pytri/2
:
pytri(Zs,Perimeter) :-
Zs = [A,B,C],
maplist(#<(1),Zs),
sum(Zs,#=,Perimeter),
chain(Zs,#<),
A^2 + B^2 #= C^2.
让我们找到周长≤100的所有17个Pythagorean triples(16个基元+ 1个非基元):
?- pytri([X,Y,Z],Perimeter), Perimeter #=< 100, labeling([],[Z,Y,X]).
Perimeter = 12, X = 3, Y = 4, Z = 5
; Perimeter = 24, X = 6, Y = 8, Z = 10
; Perimeter = 30, X = 5, Y = 12, Z = 13
; Perimeter = 36, X = 9, Y = 12, Z = 15
; Perimeter = 40, X = 8, Y = 15, Z = 17
; Perimeter = 48, X = 12, Y = 16, Z = 20
; Perimeter = 60, X = 15, Y = 20, Z = 25
; Perimeter = 56, X = 7, Y = 24, Z = 25
; Perimeter = 60, X = 10, Y = 24, Z = 26
; Perimeter = 70, X = 20, Y = 21, Z = 29
; Perimeter = 72, X = 18, Y = 24, Z = 30
; Perimeter = 80, X = 16, Y = 30, Z = 34
; Perimeter = 84, X = 21, Y = 28, Z = 35
; Perimeter = 84, X = 12, Y = 35, Z = 37
; Perimeter = 90, X = 15, Y = 36, Z = 39
; Perimeter = 96, X = 24, Y = 32, Z = 40
; Perimeter = 90, X = 9, Y = 40, Z = 41
; false. % terminates universally
答案 1 :(得分:0)
如果X
,Y
或Z
未绑定到数字,则<
测试将失败。即使你提供了价值(测试三元组而不是生成它们),我也不确定@>
是否是一个合法的谓词。
这使用inrange
来处理X,Y和Z的候选者(假设它们是整数)。请注意,因为您没有对X&amp;的相对值设置约束。是的,你得到&#34;重复&#34;答案。
pyth(X,Y,Z,W) :- W1 is W-1,
inrange(X,1,W1), inrange(Y,1,W1), inrange(Z,1,W1),
S1 is X* X + Y* Y, S2 is Z*Z, S1 == S2.
% inrange(A,B,C) B <= A <= C
inrange( V, V, _ ).
inrange( V, L, H ) :- L < H, L2 is L + 1, inrange( V, L2, H ).