这是我创建的代码。
mins_to_hours(In,H,M):-
在<60,
H = 0,
M在。
mins_to_hours(In,H,M):-
在> = 60中,
H是H1 + 1,
In1是In-60,
mins_to_hours(In1,H1,M)。
当分钟少于60分钟时,例如,
?-mins_to_hours(20,H,M)。
H = 0,
M = 20;
假。
但是尝试运行60分钟以上
?-mins_to_hours(80,H,M)。
它输出一个异常
错误:参数没有充分实例化
错误:在:
错误:[9] _3198是_3204 + 1
错误:[8] mins_to_hours(80,_3232,_3234)在c:/.../ xyz.pl:11
错误:[7] <用户>
在 H位置的是H1 + 1,
。
有什么办法解决此问题吗?
答案 0 :(得分:3)
这是您的代码的更正版本。
mins_to_hours(Minutes_in, H, M) :-
mins_to_hours_helper(0, Minutes_in, H, M).
mins_to_hours_helper(H0, M0, H0, M0):-
M0 < 60, !.
mins_to_hours_helper(H0, M0, H, M):-
M0 >= 60,
H1 is H0+1,
M1 is M0-60,
mins_to_hours_helper(H1, M1, H, M).
主要变化是:
H0
和H1
,以及M0
和{{ 1}}。M1
。以下是一些测试案例(使用SWI-Prolog):
mins_to_hours_helper
要运行测试用例:
:- begin_tests(mins_to_hours).
test(-1) :-
mins_to_hours(-1,H,M),
assertion(H == 0),
assertion(M == -1).
test(0) :-
mins_to_hours(0,H,M),
assertion(H == 0),
assertion(M == 0).
test(1) :-
mins_to_hours(1,H,M),
assertion(H == 0),
assertion(M == 1).
test(59) :-
mins_to_hours(59,H,M),
assertion(H == 0),
assertion(M == 59).
test(60) :-
mins_to_hours(60,H,M),
assertion(H == 1),
assertion(M == 0).
test(600) :-
mins_to_hours(600,H,M),
assertion(H == 10),
assertion(M == 0).
test(601) :-
mins_to_hours(601,H,M),
assertion(H == 10),
assertion(M == 1).
:- end_tests(mins_to_hours).
注意:?- run_tests.
% PL-Unit: mins_to_hours ....... done
% All 7 tests passed
true.
与SWISH不兼容,
run_tests.
所以您将不得不手动输入每个查询并手动检查结果。
请参阅:sandbox.pl
现在是一种更好的方法。
No permission to call sandboxed `'$current_module'(_4002,_4004)'
请注意,这是确定性的,不是递归的,并且可以通过所有测试用例。
请参阅:f-///2(整数除法)和rem/2(整数除法的余数)
注意。
由于您没有指定分钟数为负数时应该发生的情况,而是提供了将分钟数少于60分钟并将其移至结果的代码,因此该代码会重现该响应。
代码的一种变化是使用mod/2而不是rem / 2。根据输入内容,这将给出不同的答案,但可能是所需的结果。
根据来自@false的反馈进行更新。
编写代码超出了简单的练习范围时,就需要牢记modes。
原始答案代码写为
声明:mins_to_hours(++ Minutes_in:int,-H:int,-M:int)是
表示
Minutes_in必须绑定到整数
H必须是变量
M必须是变量
不过是@false注释
mins_to_hours(Minutes_in, H, M) :-
H is Minutes_in // 60,
M is Minutes_in rem 60.
第一个示例返回?- mins_to_hours(Total, H, 1), Total = 61, H = 1.
false.
Declaration: mins_to_hours(-Minutes_in:int, -H:int, +M:int) is det.
?- Total = 61, H = 1, mins_to_hours(Total, H, 1).
Total = 61,
H = 1.
Declaration: mins_to_hours(+Minutes_in:int, +H:int, +M:int) is det.
,(失败),但应该返回false
,
第二个示例返回相同值但模式不同的有效答案。
虽然我的回答仅在一种模式下有效,但Daniel Lyons的answer与其他模式兼容,因为它使用了约束。
true
因此,为了避免@false的第一个示例返回实际上是错误的?- mins_to_hours(Total, H, 1), Total = 61, H = 1.
Total = 61,
H = 1.
,它应该引发false
错误。 @false还指出最简单的方法是
剪切后延迟统一
这是更新的代码:
Arguments are not sufficiently instantiated
通过测试用例
mins_to_hours(Minutes_in, H, M) :-
mins_to_hours_helper(0, Minutes_in, H, M).
mins_to_hours_helper(H0, M0, H1, M1):-
M0 < 60, !,
H0 = H1,
M0 = M1.
mins_to_hours_helper(H0, M0, H, M):-
M0 >= 60,
H1 is H0+1,
M1 is M0-60,
mins_to_hours_helper(H1, M1, H, M).
并给出第一个示例的错误:
?- run_tests.
% PL-Unit: mins_to_hours ....... done
% All 7 tests passed
true.
答案 1 :(得分:3)
另一个有趣的版本可能是使用clpfd:
class DocumentDetailView(generic.DetailView):
model = Document
def get_context_data(self, object, **kwargs):
context = super().get_context_data(object, **kwargs)
context["doc_list"] = Document.objects.filter(document_title=object.document_title).order_by('revision_number')
return context
其优点是可以与不同的实例一起使用:
:- use_module(library(clpfd)).
min_hours(TotalMinutes, Hours, Minutes) :-
[TotalMinutes, Hours] ins 0..sup,
Minutes in 0..59,
TotalMinutes #= Hours*60 + Minutes.
答案 2 :(得分:0)
太多的代码让我感到头晕。
对于SWI-Prolog:
mins_to_hours(Min, H, M) :-
divmod(Min, 60, H, M).
对于任何序言:
mins_to_hours(Min, H, M) :-
H is Min div 60,
M is Min mod 60.