Pergunta

Atualmente estou trabalhando em um curto espaço de projeto no Prolog, e ficou preso tentando aplicar um "filtro" Eu criei a uma lista. Eu tenho o que você poderia chamar o filtro pronto, mas não posso aplicá-la. Seria melhor se eu ilustrar:

filter(A, B) 

... saídas 'true' se forem respeitadas determinadas condições.

filterList(A, [X, Y, Z])

... gera uma lista que inclui todos os elementos do segundo argumento que fazem a saída do filtro false . (Portanto, se o filtro (A, X) é verdadeira, a saída é [Y, Z]).

Eu tenho a função de "filtro" pronto, mas agora eu preciso aplicá-lo a uma lista como mostrado no segundo exemplo, excluindo todos os elementos para os quais o filtro retorna true quando aplicadas com o primeiro argumento.

Assim, se o filtro é um simples Um == B, a função é suposto para receber Um [A, B, A, C, D, A] e de saída [B, C, D], depois de ter removido todo o elementos para os quais o filtro se aplica, obviamente.

Estou tendo problemas com a estrutura básica da função, então se alguém poderia fornecer um esquema básico para uma função como esta seria de grande ajuda. Eu simplificado minha situação, tanto quanto possível para que eu possa tomar o que você pode ser capaz de fornecer e modificá-lo para minhas necessidades.

Agradecemos antecipadamente!

Foi útil?

Solução

Se você está à procura de funções de ordem superior em Prolog, você deve definitivamente consultar Naish (1995) , um recurso muito bom sobre isso.

Sua definição de filter/3 é o seguinte (ele usa a notação-list diferença, portanto, escapa de ter que definir filter/4):


filter(_,[],[]).
filter(P, A0-As0, As) :-
    (
        call(P, A0) -> As = A0-As1
    ;
        As = As1
    )
    , filter(P, As0, As1).

Eu você tem perguntas sobre este predicado, por favor me perguntar no comentário. Lendo o jornal também é altamente recomendável, também definess map, foldr e compose! Note-se que muitas das limitações que ele menciona (como, por exemplo, um call/3 falta ou um apply de ordem superior não se aplicam mais. SWI-Prolog tem o operador =.., que aborda todas as suas preocupações e torna lógica n-ordem arbitrária possível.

Outras dicas

SWI-Prolog ofertas exclude/3 e outras meta-predicados. Seu problema original pode ser codificado como este:

are_identical(X, Y) :-
    X == Y.

filterList(A, In, Out) :-
    exclude(are_identical(A), In, Out).

Exemplo de uso:

?- filterList(A, [A, B, A, C, D, A], Out).
Out = [B, C, D].

Existe um problema inerente com funções de filtro que levam o sucesso ou fracasso de um predicado como critério para filtrar: O programa resultante não é mais um programa monotônica puro. É, por conseguinte, perde a todas as suas propriedades declarativas - a única o que significa que permanece é uma interpretação de procedimento passo-a-passo. Aqui está uma versão pura, reificada de filtrar usando if_/3 :

tfilter(_CT_2,    [], []).
tfilter(CT_2, [E|Es], Fs0) :-
   if_(call(CT_2,E), Fs0 = [E|Fs], Fs0 = Fs ),
   tfilter(CT_2, Es, Fs).

O primeiro argumento é, portanto, um fecho / continuação que vai receber mais dois argumentos:. O elemento e o valor de verdade resultando

=(X,X,true).
=(X,Y,false) :- dif(X,Y).

Agora, os resultados permanecem preciso:

| ?- tfilter(=(X),[A,B],Xs).
B = A,
X = A,
Xs = [A,A] ? ;
X = A,
Xs = [A],
dif(A,B) ? ;
X = B,
Xs = [B],
dif(B,A) ? ;
Xs = [],
dif(X,A),
dif(X,B) ? ;
no

Há quatro possibilidades como uma lista de dois elementos podem ser filtradas pelo critério de ser igual a X. Cada elemento pode ser igual ou pode ser diferente.

A desvantagem dessa abordagem é que um tem para oferecer versões reificadas de todos os critérios.

Bem O que você sabe que eu só percebi isso. Então, aqui vai me enviar uma resposta à minha pergunta, como se espera de um muito curto função fez o trabalho:

filterList(_,[],R,R).           % Returns answer when the list is exhausted.
filterList(L,[A|List],Temp,Res) :-
   filterList(L,List,New,Res),  % Recursive call, New is either the same list
   (  filter(L,A),              % in case the filter outputs true, or the list
      New = Temp
   ;  New = [A|Temp]            % plus the current element otherwise.
   ).

Recebo os adultos de um país // Obtengo los Adultos de un pais, País = Pais, Pessoas = Personas, Pessoa = una sola Persona

habitants(USA, [juan, pedro, david])

adults(Adults, Country) :-
     findall(Person, (habitants(Country,People), member(People, Person), adult(Person)), Adults)

Este é um filtro no prólogo // Asi es filtro un en prólogo

filter(_,[],[]).
filter(Predicate,[First|Rest],[First|Tail]) :-
   filter(Predicate,Rest,Tail).
filter(Predicate,[_|Rest],Result) :-
   filter(Predicate,Rest,Result).
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top