根据Prolog中的目标值过滤数字元素


public class Filter {
public static List<Number> apply(List<Number> lst, Double target){
return lst.stream()
.mapToDouble( Number::doubleValue )
.filter( elem -> elem > target )
.boxed()
.collect( Collectors.toCollection(ArrayList::new ));
}
public static void main(String[] args) {
//    Integer[] nums = new Integer[] {1,2,3,4,5,6,7,8,9};
Double[] nums = new Double[] {2.1,3.2,4.3,5.4,6.5,7.6,8.7};
System.out.println(Filter.apply( Arrays.asList(nums), 5.0 ) 
);
}
}

可以这样做:

%---------------------------
% find all Xs greater than Y
%---------------------------
items_greater_than( []     , _ , []    ) .
items_greater_than( [X|Xs] , Y , [X|Zs ) :- X @>  Y, items_greater_than(Xs,Y,Zs).
items_greater_than( [X|Xs] , Y , Zs    ) :- X @=< Y, items_greater_than(Xs,Y,Zs).

执行

items_greater_than( [2.1, 3.2, 4.3, 5.4, 6.5, 7.6, 8.7], 5.0, R ).

应该屈服

R = [ 5.4, 6.5, 7.6, 8.7 ]

如果您使用的是wi - prolog,您可以使用include/3,如下所示:

?- include(<(5.0), [2.1,3.2,4.3,5.4,6.5,7.6,8.7], R).
R = [5.4, 6.5, 7.6, 8.7].

这与Java代码完全相同:它接受一个列表,对每个元素应用谓词,并仅收集谓词成功的元素。

类似于Javafilter是include/3 from library(apply),而library(yall)给我们匿名谓词,类似于arrow functions:

items_greater_than(Items,Value,ItemsGreater) :-
include({Value}/[I]>>(I>Value),Items,ItemsGreater).

如果您的Prolog缺少上述任何一个库,这可以工作:

items_greater_than(Items,Value,ItemsGreater) :-
findall(I,(member(I,Items),I>Value),ItemsGreater).

请记住,在Prolog中我们没有函数,只有谓词。

编辑

感谢@TA_intern的明智评论,这里有一个不需要library(yall)的解决方案:

items_greater_than(Items,Value,ItemsGreater) :-
include(<(Value),Items,ItemsGreater).

由于library(apply)将列表项附加到谓词的实参末尾,因此我们使用(<)/2谓词而不是(>)/2。

请记住split/3和merge/3是" help-predicate ":

split([X], [], [X]).
split([H1, H2 | List], [H1 | ListA], [H2 | Result]) :-
split(List, ListA, Result).
merge([], L, L).
merge(L, [], L).
merge([H1 | List], [H2 | ListA], [H1 | Result]) :-
H1 < H2,
!,
merge(List, [H2 | ListA], Result).
merge(List, [H2 | ListA], [H2 | Result]) :-
merge(List, ListA, Result).

merge_sort([], []).
merge_sort([A], [A]).
merge_sort(List, SList):-
split(List, List1, List2),
merge_sort(List1, SList1),
merge_sort(List2, SList2),
merge(SList1, SList2, SList).

如果你查询,你应该得到这个:

?- split([2, 5, 7, 4, 3, 1, 9, 8, 6], ListA, ListB).
ListA = [2, 7, 3, 9],
ListB = [5, 4, 1, 8, 6] .
?- merge([1, 3, 5, 7, 9], [2, 4, 6, 8], MergedList).
MergedList = [1, 2, 3, 4, 5, 6, 7, 8, 9] .
?- merge_sort([2, 5, 7, 4, 3, 1, 9, 8, 6], Result).
Result= [1, 2, 3, 4, 5, 6, 7, 8, 9].

最新更新