我开始学习Prolog,我想要一个给出整数P
的程序给整数A
和B
这样P = A² + B²
。如果A
和B
的值不满足此等式,则应返回false
例如:如果P = 5
,它应该提供A = 1
和B = 2
(或A = 2
和B = 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很新,所以我仍然犯了很多错误。
提前致谢!
答案 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)约束是完全纯粹的关系,可以按照您期望的方式使用。有关详细信息,请参阅 clpfd 。
我注意到的其他事情:
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只是:关系语言。