Debugging 为什么Prolog中的min()函数不起作用?
这是Prolog中我的min函数,它应该在数字列表中找到最小的元素。我的想法是测试结果是否小于或等于列表中的每个元素。列表的标题将被删除,直到其为空。当达到该点时,设定结果是正确的Debugging 为什么Prolog中的min()函数不起作用?,debugging,prolog,min,Debugging,Prolog,Min,这是Prolog中我的min函数,它应该在数字列表中找到最小的元素。我的想法是测试结果是否小于或等于列表中的每个元素。列表的标题将被删除,直到其为空。当达到该点时,设定结果是正确的 min([], Result). min([Head|Tail], Result) :- Result =< Head, min(Tail, Result). 在SWI Prolog中查阅此文件时,它可以测试值是否是最小元素,最小值为min[5,3,7,6],3返回true。但是min[5,3
min([], Result).
min([Head|Tail], Result) :-
Result =< Head,
min(Tail, Result).
在SWI Prolog中查阅此文件时,它可以测试值是否是最小元素,最小值为min[5,3,7,6],3返回true。但是min[5,3,7,6],X没有找到X的值,只是返回true
如何使其找到X的值?无法设置空列表的最小值。 你可以直接写
min([X], X).
希望X是一个整数;我想是吧!
然后
无法设置空列表的最小值。 你可以直接写
min([X], X).
希望X是一个整数;我想是吧!
然后
我的SWI Prolog报告
?- min([5, 3, 7, 6], X).
ERROR: user://1:18:
=</2: Arguments are not sufficiently instantiated
请注意,最后一行返回到内置的最小值,该值由is计算
或者,您可以取元素对的最小值,给出
min([X], X).
min([X,Y|L], Min) :-
MinXY is min(X, Y),
min([MinXY|L], Min).
此版本是尾部递归的。我的SWI Prolog报告
?- min([5, 3, 7, 6], X).
ERROR: user://1:18:
=</2: Arguments are not sufficiently instantiated
请注意,最后一行返回到内置的最小值,该值由is计算
或者,您可以取元素对的最小值,给出
min([X], X).
min([X,Y|L], Min) :-
MinXY is min(X, Y),
min([MinXY|L], Min).
这个版本是尾部递归的。它不可能在那里返回true。X=<3导致错误:=它不可能在那里返回true。X=<3导致错误:=如果打开跟踪,您可以看到脚本有什么问题
1 ?- trace.
true.
原文:
/** Version 0 */
min([], Result).
min([Head|Tail], Result) :-
Result =< Head,
min(Tail, Result).
/** version 3 */
min([Result], Result).
min([Head|Tail], Result) :-
min(Tail, Result),
Result =< Head.
min([Head|Tail], Result) :-
min(Tail, R1),
Head < R1,
Result is Head.
输出:
[trace] 5 ?- min([5,3,7,6],X).
Call: (6) min([5, 3, 7, 6], _G517) ? creep
Call: (7) min([3, 7, 6], _G517) ? creep
Call: (8) min([7, 6], _G517) ? creep
Call: (9) min([6], _G517) ? creep
Call: (10) min([], _G517) ? creep
Exit: (10) min([], _G517) ? creep
Call: (10) _G517=<6 ? creep
ERROR: =</2: Arguments are not sufficiently instantiated
Exception: (10) _G517=<6 ?
[trace] 102 ?- min([5,3,7,6],X).
Call: (6) min([5, 3, 7, 6], _G3067) ? creep
Call: (7) min([3, 7, 6], _G3067) ? creep
Call: (8) min([7, 6], _G3067) ? creep
Call: (9) min([6], _G3067) ? creep
Call: (10) min([], _G3067) ? creep
Exit: (10) min([], _G3067) ? creep
Call: (10) _G3067=<6 ? creep
ERROR: =</2: Arguments are not sufficiently instantiated
Exception: (10) _G3067=<6 ?
[trace] 8 ?- min([5,3,7,6],3).
Call: (6) min([5, 3, 7, 6], 3) ? creep
Call: (7) min([3, 7, 6], 3) ? creep
Call: (8) min([7, 6], 3) ? creep
Call: (9) min([6], 3) ? creep
Call: (10) min([], 3) ? creep
Fail: (10) min([], 3) ? creep
Fail: (9) min([6], 3) ? creep
Fail: (8) min([7, 6], 3) ? creep
Fail: (7) min([3, 7, 6], 3) ? creep
Fail: (6) min([5, 3, 7, 6], 3) ? creep
false.
程序现在只返回false。这是因为你只考虑的情况下,最小的尾巴是小于或等于头部。当输入列表按递减顺序排序,使尾部的最小值递归地小于头部时,此程序将仅返回正确的结果
[trace] 10 ?- min([5,4,3,2],X).
Call: (6) min([5, 4, 3, 2], _G2469) ? creep
Call: (7) min([4, 3, 2], _G2469) ? creep
Call: (8) min([3, 2], _G2469) ? creep
Call: (9) min([2], _G2469) ? creep
Exit: (9) min([2], 2) ? creep
Call: (9) 2=<3 ? creep
Exit: (9) 2=<3 ? creep
Exit: (8) min([3, 2], 2) ? creep
Call: (8) 2=<4 ? creep
Exit: (8) 2=<4 ? creep
Exit: (7) min([4, 3, 2], 2) ? creep
Call: (7) 2=<5 ? creep
Exit: (7) 2=<5 ? creep
Exit: (6) min([5, 4, 3, 2], 2) ? creep
X = 2 .
因此,您需要注意尾部的最小值严格大于头部的情况,添加以下条款:
min([Head|Tail], Result) :-
min(Tail, R1),
Head < R1,
Result is Head.
以下是最终版本:
/** Version 0 */
min([], Result).
min([Head|Tail], Result) :-
Result =< Head,
min(Tail, Result).
/** version 3 */
min([Result], Result).
min([Head|Tail], Result) :-
min(Tail, Result),
Result =< Head.
min([Head|Tail], Result) :-
min(Tail, R1),
Head < R1,
Result is Head.
使用nodebug关闭跟踪。如果打开跟踪,您可以看到脚本有什么问题
1 ?- trace.
true.
原文:
/** Version 0 */
min([], Result).
min([Head|Tail], Result) :-
Result =< Head,
min(Tail, Result).
/** version 3 */
min([Result], Result).
min([Head|Tail], Result) :-
min(Tail, Result),
Result =< Head.
min([Head|Tail], Result) :-
min(Tail, R1),
Head < R1,
Result is Head.
输出:
[trace] 5 ?- min([5,3,7,6],X).
Call: (6) min([5, 3, 7, 6], _G517) ? creep
Call: (7) min([3, 7, 6], _G517) ? creep
Call: (8) min([7, 6], _G517) ? creep
Call: (9) min([6], _G517) ? creep
Call: (10) min([], _G517) ? creep
Exit: (10) min([], _G517) ? creep
Call: (10) _G517=<6 ? creep
ERROR: =</2: Arguments are not sufficiently instantiated
Exception: (10) _G517=<6 ?
[trace] 102 ?- min([5,3,7,6],X).
Call: (6) min([5, 3, 7, 6], _G3067) ? creep
Call: (7) min([3, 7, 6], _G3067) ? creep
Call: (8) min([7, 6], _G3067) ? creep
Call: (9) min([6], _G3067) ? creep
Call: (10) min([], _G3067) ? creep
Exit: (10) min([], _G3067) ? creep
Call: (10) _G3067=<6 ? creep
ERROR: =</2: Arguments are not sufficiently instantiated
Exception: (10) _G3067=<6 ?
[trace] 8 ?- min([5,3,7,6],3).
Call: (6) min([5, 3, 7, 6], 3) ? creep
Call: (7) min([3, 7, 6], 3) ? creep
Call: (8) min([7, 6], 3) ? creep
Call: (9) min([6], 3) ? creep
Call: (10) min([], 3) ? creep
Fail: (10) min([], 3) ? creep
Fail: (9) min([6], 3) ? creep
Fail: (8) min([7, 6], 3) ? creep
Fail: (7) min([3, 7, 6], 3) ? creep
Fail: (6) min([5, 3, 7, 6], 3) ? creep
false.
程序现在只返回false。这是因为你只考虑的情况下,最小的尾巴是小于或等于头部。当输入列表按递减顺序排序,使尾部的最小值递归地小于头部时,此程序将仅返回正确的结果
[trace] 10 ?- min([5,4,3,2],X).
Call: (6) min([5, 4, 3, 2], _G2469) ? creep
Call: (7) min([4, 3, 2], _G2469) ? creep
Call: (8) min([3, 2], _G2469) ? creep
Call: (9) min([2], _G2469) ? creep
Exit: (9) min([2], 2) ? creep
Call: (9) 2=<3 ? creep
Exit: (9) 2=<3 ? creep
Exit: (8) min([3, 2], 2) ? creep
Call: (8) 2=<4 ? creep
Exit: (8) 2=<4 ? creep
Exit: (7) min([4, 3, 2], 2) ? creep
Call: (7) 2=<5 ? creep
Exit: (7) 2=<5 ? creep
Exit: (6) min([5, 4, 3, 2], 2) ? creep
X = 2 .
因此,您需要注意尾部的最小值严格大于头部的情况,添加以下条款:
min([Head|Tail], Result) :-
min(Tail, R1),
Head < R1,
Result is Head.
以下是最终版本:
/** Version 0 */
min([], Result).
min([Head|Tail], Result) :-
Result =< Head,
min(Tail, Result).
/** version 3 */
min([Result], Result).
min([Head|Tail], Result) :-
min(Tail, Result),
Result =< Head.
min([Head|Tail], Result) :-
min(Tail, R1),
Head < R1,
Result is Head.
使用nodebug关闭跟踪。如果使用@yes,则可以使用任意atom X,但danijar似乎需要整数列表的最小值。如果使用@yes,则可以使用任意atom X,但danijar似乎需要整数列表的最小值。