在这个例子中你面临的一个主要困难是所谓的模式的低级算术谓词。例如,让我们尝试最一般的查询与您发布的代码:
?- 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.
这似乎仍然相当OK!
?- mins_to_hours(60, H, M).
H = -1,
M = 0 ;
false.
这似乎已经很多少 OK!
通过一些练习,很容易看出原因:在第二个条款中,您无意中混淆了H
和H1
的角色!假设我们写的第二句话是这样的:
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)约束,因为它们让您轻松尝试不同目标订单的效果,同时保持关系正确并且一般。
忘了提及它应该做什么...它应该将分钟转换为小时和分钟,例如,如果给了它140它应该返回H = 2 M = 20 – jdoggg
您可以编辑您的问题进行更新。你应该把你的评论中的信息放入问题中。 –