理解prolog中的简单递归

时间:2017-02-13 18:38:20

标签: recursion prolog

我在掌握Prolog的书中有以下Prolog,我正在尝试学习一些简单的递归。

Json

我不完全确定为什么它不起作用,我已经花了好几个小时摆弄它。任何帮助甚至指向我正确的方向非常感谢。提前谢谢。

1 个答案:

答案 0 :(得分:2)

您在此示例中遇到的主要困难是低级算术谓词的所谓 modedness 。例如,让我们使用您发布的代码尝试最常规查询

?- mins_to_hours(In, H, M).
ERROR: Arguments are not sufficiently instantiated

为了摆脱这个缺点,我首先用CLP(FD)约束替换低级谓词,这些谓词在所有主要的Prolog系统中都可用,并简化了对代码的推理。

为此,我只需将(<)/2替换为(#<)/2,将(is)/2替换为(#=)/2等。(根据您的Prolog系统,您可能还需要导入库为此):

mins_to_hours(In, H, M):-
    In #< 60,
    H = 0,
    M #= In.
mins_to_hours(In, H, M):-
    In #>= 60,
    In1 #= In-60,
    H1 #= H+1,
    mins_to_hours(In1, H1, M).

现在,让我们再次尝试最常见的查询,其中所有参数都是新变量

?- mins_to_hours(In, H, M).
In = M,
H = 0,
M in inf..59 ;
H = -1,
In in 60..119,
M+60#=In,
M in 0..59 ;
H = -2,
In in 120..179,
_5238+60#=In,
_5238 in 60..119,
M+60#=_5238,
M in 0..59 .

在这里,H可以假设值似乎很奇怪!

让我们尝试一些具体的案例:

?- mins_to_hours(30, H, M).
H = 0,
M = 30 ;
false.

这似乎还算不错!

?- mins_to_hours(60, H, M).
H = -1,
M = 0 ;
false.

这似乎已经确定了!

通过一些练习,很容易看出原因:在第二个条款中,您无意中混淆了HH1的角色!假设我们写这样的第二个句子:

mins_to_hours(In, H, M):-
    In #>= 60,
    In1 #= In-60,
    H #= H1+1,
    mins_to_hours(In1, H1, M).

然后我们得到:

?- mins_to_hours(60, H, M).
H = 1,
M = 0 ;
false.

还有两个案例:

?- mins_to_hours(500, H, M).
H = 8,
M = 20 ;
false.

?- mins_to_hours(1000, H, M).
H = 16,
M = 40 ;
false.

看起来很不错!

请注意,如果您坚持使用较低级别的算术,则无法轻松纠正错误:使用(<)/2(is)/2等谓词要求您还要考虑实际的执行顺序的Prolog,这对几乎所有初学者来说都太难了。我强烈建议您使用CLP(FD)约束,因为它们可以让您轻松尝试不同目标顺序的效果,同时保持关系正确并且一般