Prolog过滤掉数字数组

Prolog Filter out array of numbers

将 prolog 作为作业,并尝试过滤数字数组。我有以下代码来过滤掉所有小于 5 的元素并输出带有剩余数字的数组。我遇到的问题是我不能用其他东西改变 5。

delete_smaller([], []).
delete_smaller([Head|Tail], List) :- 
    (  Head < 5
    -> List = Output 
    ;  List = [Head|Output] 
    ), 
    delete_smaller(Tail, Output).

现状:

?- delete_smaller([1,2,3,4,7,8], Output).
Output = [7, 8]

期望的情况: ?- delete_smaller([1,2,3,4,7,8], 5, 输出)。 输出 = [7, 8]

我凭直觉对 prolog 的了解非常有限,尝试执行以下操作:

delete_smaller([], []).
delete_smaller([Head|Tail], Target, List) :- 
    (  Head < Target
    -> List = Output 
    ;  List = [Head|Output] 
    ), 
    delete_smaller(Tail, Target, Output).

然而

?- delete_smaller(Tail, Target, Output).

我收到的查询是假的

提前感谢您的帮助

您忘记修改过程的第一个子句(递归的基本情况)。

您向 delete_smaller/2 添加了另一个参数(Target),所以现在它变成了 delete_smaller/3;您的所有条款都应相应修改。 由于您不关心基本情况下 Target 的值,因此只需使用匿名变量 (_) 作为第二个参数:

delete_smaller([], _, []).
delete_smaller([Head|Tail], Target, List) :- 
    (  Head < Target
    -> List = Output 
    ;  List = [Head|Output] 
    ), 
    delete_smaller(Tail, Target, Output).

你需要做这样的事情:

delete_smaller( []     , _ ,    []  ) .
delete_smaller( [X|Xs] , N ,    Ys  ) :- H <  N , delete_smaller(Xs,N,Ys) .
delete_smaller( [X|Xs] , N , [X|Ys] ) :- H >= N , delete_smaller(Xs,N,Ys) .

如果您通过在谓词中使用附加子句(如上所述)或通过重构为更小、更离散的谓词而不是使用 ; 替代运算符。

另一种可以做到这一点的方法可能是创建一个像这样的谓词,它接受一个值,与一个限制值进行比较并将其添加到结果列表中并返回尾部:

filter( X , N ,    Xs  , Xs ) :- X <  N .
filter( X , N , [X|Xs] , Xs ) :- X >= N .

一旦你有了它,那么你的 delete_smaller/3 会变得更简单:

delete_smaller( []     , _ , [] ) .
delete_smaller( [X|Xs] , N , Ys ) :- filter(X,N,Ys,Zs), delete_smaller(Xs,N,Zs) .

对于这个问题,这是矫枉过正,但是这种不懈的重构使得代码更容易测试,因为您的组件更小更简单。