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) .
对于这个问题,这是矫枉过正,但是这种不懈的重构使得代码更容易测试,因为您的组件更小更简单。
将 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) .
对于这个问题,这是矫枉过正,但是这种不懈的重构使得代码更容易测试,因为您的组件更小更简单。