Prolog Filter List

I am trying to rewrite code from Haskell to Prolog.

count :: Eq a => a -> [a] -> Int
count x = length . filter (x==)

f :: [Integer] -> [Integer]
f [] = []
f list = filter (\x -> count x list == 1) list 

This code return list contains items that appear only once in the list. Therefore, if I have a list [1,1,2,2,3,4,4,5], this function returns. [3,5] I tried to find the filter construct in Prolog, but there seems to be no such thing. How can I make a similar function in Prolog?

+4
source share
4 answers

To the existing answers, I would like to add an answer that is pretty general in the sense that you can use it in several ways.

Building block: list_element_number/3

I start with the following predicate, defining the relationship between:

  • list Ls0
  • element E
  • N E Ls0

:

list_element_number(Ls0, E, N) :-
        tfilter(=(E), Ls0, Ls),
        length(Ls, N).

tfilter/3 library(reif). count, . , , Haskell , :

?- list_element_number([a,b,c], a, N).
N = 1.

, , :

?- list_element_number([a,b,c], X, 1).
X = a ;
X = b ;
X = c ;
false.

:

?- list_element_number([a,b,E], X, 2).
E = X, X = a ;
E = X, X = b ;
false.

:

?- list_element_number([A,B,C], X, 3).
A = B, B = C, C = X ;
false.

, :

?- list_element_number(Ls, E, N).
Ls = [],
N = 0 ;
Ls = [E],
N = 1 ;
Ls = [E, E],
N = 2 ;
Ls = [E, E, E],
N = 3 .

:

?- length(Ls, _), list_element_number(Ls, E, N).
Ls = [],
N = 0 ;
Ls = [E],
N = 1 ;
Ls = [_160],
N = 0,
dif(E, _160) ;
Ls = [E, E],
N = 2 .

: list_singletons/2

, list_singletons/2 :

list_singletons(Ls, Singles) :-
        tfilter(count_one(Ls), Ls, Singles).

count_one(Ls, E, T) :-
        list_element_number(Ls, E, Num),
        cond_t(Num=1, true, T).

cond_t/3 () tfilter/3 library(reif).

. -, , :

?- list_singletons([1,1,2,2,3,4,4,5], Singles).
Singles = [3, 5].

.

:

?- list_singletons([A,B], Singles).
A = B,
Singles = [] ;
Singles = [A, B],
dif(A, B).

: A = B, , . A B, A, B .

:

?- list_singletons([A,A], Singles).
Singles = [].

, :

?- length(Ls, _), list_singletons(Ls, Singles).
Ls = Singles, Singles = [] ;
Ls = Singles, Singles = [_7216] ;
Ls = [_7216, _7216],
Singles = [] ;
Ls = Singles, Singles = [_7828, _7834],
dif(_7828, _7834) ;
Ls = [_7216, _7216, _7216],
Singles = [] ;
Ls = [_7910, _7910, _7922],
Singles = [_7922],
dif(_7910, _7922) .

, .

+5

:

(. @false , findall/3 , , ).

filter_list(L,OutList):-findall(X, (member(X,L),count(X,L,N),N=:=1) , OutList).

count(_,[],0).
count(X,[X|T],N):-count(X,T,N1),N is N1+1.
count(X,[X1|T],N):-dif(X,X1),count(X,T,N).

filter_list/2 findall/3, X, L, count 1 OutList.

:

?- filter_list([1,1,2,2,3,4,4,5],L).
L = [3, 5].

filter_list/2 findall/3, :

filter_list(L,OutList):- filter_list(L,OutList,L).
filter_list([],[],_).
filter_list([H|T],[H|T1],L):-count(H,L,N), N=:=1, filter_list(T,T1,L).
filter_list([H|T],T1,L):-count(H,L,N), N > 1, filter_list(T,T1,L).
+3

:

filter_list(L,OutList):-findall(X, (select(X,L, L1),\+member(X, L1)) , OutList).

?- filter_list([1,1,2,2,3,4,4,5],L).
L = [3, 5].

findall

filter_list(In, Out) :- filter_list(In, _, Out).

filter_list([], [], []).

filter_list([H|T], L1, L2) :-
             filter_list(T, LL1, LL2),
             (   member(H, LL1)
             ->  L1 = LL1, L2 = LL2
             ;   (select(H, LL2, L2)
                 ->  L1 = [H|LL1]
                 ;   L1 = LL1, L2 = [H|LL2])).
+3

...

filter_uniques([],[]).
filter_uniques([H|T],F) :-
    delete(T,H,D),
    ( D=T -> F=[H|R],S=T ; F=R,S=D ),
    filter_uniques(S,R).

(yall) ( /3)

filt_uniq(L,F) :-
    include({L}/[E]>>aggregate(count,member(E,L),1),L,F).
+3
source

Source: https://habr.com/ru/post/1677296/


All Articles