2016-07-20 13 views
5

我开始学习Prolog,我想要一个给定整数P的程序给整数AB,使得P = A² + B²。如果没有满足这个方程的AB值,false应退还Prolog程序获取(整数)数字作为两个整数正方形的总和,为什么它不起作用?

例如:如果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很陌生,所以我仍然犯了很多错误。

在此先感谢!

回答

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呢?
+0

非常感谢您的回复。 我有几个问题。如果你能回答他们,那将是非常棒的。 '非单调谓词'是什么意思,/ 1或/ 3是什么意思,以及label()函数做了什么? 在因特网上,我读了“为Vars中的每个变量赋值”,标签意味着系统地尝试使用有限域变量Vars的值,直到所有变量都被研磨为止。为函数标签(),但我不是很明白它。 也感谢您注意到不好的做法,我更改了名称,将来会使用下划线和声明式名称。 – Kevin

+1

请为此单独提出问题。他们都值得自己讨论:1)单调性的定义和2)什么是“标签”?只有一个问题很简单,可以在评论中回答:'f/3'是一个**谓词指示符**,表示一个名为'f'的谓词,带有3 *个参数*。请注意,我们总是讨论**谓词**,它们比*函数*更普遍。伟大的名字!查找和使用对谓词**一般性**公平的好的陈述性名称是在Prolog中编程时非常重要的一个方面,也可能是其中较难的一个。 – mat

1

出于效率考虑,Prolog的实施者已经选择了很多年前的许多妥协方案。现在,您的Prolog有可能实现高级整数运算,就像CLP(FD)一样。如果是这样的话,mat答案是完美的。但是一些序言(可能是一个天真的ISO Prolog兼容处理器)可能会抱怨缺少标签/ 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. 

之间/ 3它不是一个ISO内置,但它而不是更容易(#=)/ 2和标签/ 1至写:)

无论如何,请遵循垫'的建议,并避免'命令'的命名。通常对关系的描述更好,因为Prolog就是这样的:关系语言。

+2

我通常不会downvoting,但... – repeat

相关问题