排除列表中所有出现的最小数量

G_c*_*_cy 12 list prolog

作为Prolog新手,我尝试定义一个谓词filter_min/2,该谓词采用两个列表来确定第二个列表是否与第一个列表相同,但是删除了所有出现的最小值.

具有预期结果的示例查询:

?- filter_min([3,2,7,8], N).
N = [3,7,8].

?- filter_min([3,2,7,8], [3,7,8]).
true.
Run Code Online (Sandbox Code Playgroud)

我试过但总是得到相同的结果:false.我不知道问题是什么.我需要帮助!

这是我的代码:

filter_min(X,Y) :-
    X == [],
    write("ERROR: List parameter is empty!"),
    !;
    min_list(X,Z),
    filter(X,Y,Z).

filter([],[],0).
filter([H1|T1],[H2|T2],Z) :-
    \+ number(H1),
    write("ERROR: List parameter contains a non-number element"),
    !;
    H1 \= Z -> H2 is H1, filter(T1,T2,Z);
    filter(T1,T2,Z).
Run Code Online (Sandbox Code Playgroud)

Fat*_*ize 4

您的代码存在几个问题:

  • filter([],[],0).当处理任何不以 0 作为最小值的列表时,将不会统一,这不是您想要的。无论结束递归的最小值是多少,您都希望它统一。
  • 您编写的方式filter([H1|T1],[H2|T2],Z)及其正文将使两个列表始终具有相同数量的元素,而实际上第二个列表应该至少少一个。

正确的实现filter/3如下:

filter([],[],_).
filter([H1|T1],L2,Z):-
    \+ number(H1),
    write("ERROR: List parameter contains a non-number element"),
    !;
    H1 \= Z -> filter(T1,T2,Z), L2 = [H1|T2];
    filter(T1,L2,Z).
Run Code Online (Sandbox Code Playgroud)

  • `E = 2, filter([1],[1],E).` 成功,但 `filter([1],[1],E), E = 2.` 错误地失败。它应该:要么成功,要么产生实例化错误,或者(不是在这里,但原则上)循环。 (2认同)
  • 我看不出您建议的修复会改进什么:您要么需要实例化错误,要么需要正确的成功 (2认同)