Debugging 为什么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

这是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,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似乎需要整数列表的最小值。