Prolog程序得到一个(整数)数作为两个整数平方的总和,为什么它不起作用?

时间:2016-07-20 12:25:26

标签: prolog numbers clpfd number-theory logical-purity

我开始学习Prolog,我想要一个给出整数P的程序给整数AB这样P = A² + B²。如果AB的值不满足此等式,则应返回false

例如:如果P = 5,它应该提供A = 1B = 2(或A = 2B = 1),因为1² + 2² = 5

我认为这应该有效:

giveSum(P, A, B) :- integer(A), integer(B), integer(P), P is A*A + B*B.

查询:

giveSum(5, A, B).

然而,它没有。我该怎么办?我对Prolog很新,所以我仍然犯了很多错误。

提前致谢!

2 个答案:

答案 0 :(得分:6)

integer/1是非单调谓词。 关系允许您希望在这种情况下应用的推理。举例说明:

?- integer(I).
false.

不存在整数,是吗? 让我感到惊讶,至少可以说!

使用Prolog系统的 CLP(FD)约束来代替这种非关系结构来推理整数。

例如:

?- 5 #= A*A + B*B.
A in -2..-1\/1..2,
A^2#=_G1025,
_G1025 in 1..4,
_G1025+_G1052#=5,
_G1052 in 1..4,
B^2#=_G406,
B in -2..-1\/1..2

具体解决方案:

?- 5 #= A*A + B*B, label([A,B]).
A = -2,
B = -1 ;
A = -2,
B = 1 ;
A = -1,
B = -2 ;
etc.

CLP(FD)约束是完全纯粹的关系,可以按照您期望的方式使用。有关详细信息,请参阅

我注意到的其他事情:

  • use_underscores_for_readability_as_is_the_convention_in_prolog代替ofMixingTheCasesToMakePredicatesHardToRead
  • 使用声明性名称,避免命令。例如,为什么称它为give_sum?如果总和已经给出,这个谓词也很有意义。那么,例如sum_of_squares/3呢?

答案 1 :(得分:1)

为了提高效率,Prolog实施者已经选择 - 许多年前 - 做出了一些妥协。现在,你的Prolog有可能实现高级整数运算,就像CLP(FD)那样。如果是这种情况,垫子'答案很完美。但是一些Prolog(可能是一个天真的ISO Prolog兼容处理器),可能会抱怨缺少label / 1和(#=)/ 2。因此,传统的Prolog解决方案:该技术称为生成和测试

giveSum(P, A, B) :-
  ( integer(P) -> between(1,P,A), between(1,P,B) ; integer(A),integer(B) ),
  P is A*A + B*B.
/ p之间它不是ISO内置的,但它比(#=)/ 2和标签/ 1更容易写:)

无论如何,请按照mat'建议并避免“必要的”#39;命名。通常对关系的描述更好,因为Prolog只是:关系语言。

相关问题