문제

저는 현재 Prolog에서 매우 짧은 프로젝트를 진행하고 있는데, 제가 만든 "필터"를 목록에 적용하려고 하다가 막혔습니다.필터라고 할 수 있는 것이 준비되어 있지만 적용할 수는 없습니다.다음과 같이 설명하면 더 좋을 것 같습니다.

filter(A, B) 

...특정 조건이 충족되면 'true'를 출력합니다.

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

...필터 출력을 만드는 두 번째 인수의 모든 요소를 ​​포함하는 목록을 출력합니다. 거짓.(따라서 filter(A, X)가 참이면 출력은 [Y, Z] 입니다).

"필터" 함수가 준비되어 있지만 이제 두 번째 예에 표시된 대로 목록에 적용해야 합니다. 이때 첫 번째 인수를 적용할 때 필터가 true를 반환하는 모든 요소를 ​​제외해야 합니다.

따라서 필터가 단순한 A == B인 경우 함수는 A [A,B,A,C,D,A]를 수신하고 [B,C,D]를 출력해야 하며, 이에 대한 모든 요소를 ​​제거해야 합니다. 당연히 필터가 적용됩니다.

함수의 기본 구조에 문제가 있습니다. 따라서 누구든지 이와 같은 함수에 대한 기본 개요를 제공할 수 있다면 큰 도움이 될 것입니다.나는 가능한 한 내 상황을 단순화하여 귀하가 제공할 수 있는 모든 것을 취하고 내 필요에 맞게 수정할 수 있습니다.

미리 감사드립니다!

도움이 되었습니까?

해결책

Prolog에서 고차 기능을 검색하는 경우 반드시 문의해야 합니다. 나이쉬 (1995), 이에 대한 아주 좋은 자료입니다.

그의 정의 filter/3 다음은 다음과 같습니다(그는 차이 목록 표기법을 사용하므로 정의할 필요가 없습니다). filter/4):


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

이 술어에 대해 궁금한 점이 있으면 댓글로 질문해 주세요.논문을 읽는 것도 적극 권장됩니다. map, foldr 그리고 compose!그가 언급한 많은 제한 사항(예: 누락된 항목)에 유의하세요. call/3 또는 더 높은 차수 apply 더 이상 신청하지 마세요.SWI-프롤로그에는 =.. 그의 모든 관심사를 해결하고 임의의 n차 논리를 가능하게 만드는 연산자입니다.

다른 팁

SWI-프롤로그 제안 exclude/3 및 기타 그러한 메타 술어.원래 문제는 다음과 같이 코딩될 수 있습니다.

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

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

사용 예:

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

조건자의 성공 또는 실패를 필터링 기준으로 삼는 필터 함수에는 본질적인 문제가 있습니다.결과 프로그램은 더 이상 순수한 단조로운 프로그램이 아닙니다.따라서 모든 선언적 속성을 잃습니다. 남아 있는 유일한 의미는 절차적 단계별 해석입니다.다음은 필터링의 순수하고 구체화된 버전입니다. 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).

따라서 첫 번째 인수는 두 개의 추가 인수를 받는 클로저/연속입니다.요소와 결과 진리값입니다.

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

이제 결과는 정확하게 유지됩니다.

| ?- 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

두 요소의 목록을 다음과 같은 기준으로 필터링하는 방법에는 네 가지 가능성이 있습니다. X.각 요소는 동일할 수도 있고 다를 수도 있습니다.

이 접근 방식의 단점은 모든 기준의 구체화된 버전을 제공해야 한다는 것입니다.

글쎄요, 제가 방금 알아낸 게 뭘까요?그래서 여기에 제가 제 질문에 대한 답변을 제출했습니다. 예상대로 매우 짧은 함수가 작업을 수행했습니다.

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.
   ).

나는 그 나라의 어른들을 얻습니다 // Obtengo los Adultos de un pais, Country = Pais, People = Personas, Person = una sola Persona

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

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

이것은 프롤로그의 필터입니다. // Asi es un filter en prolog

filter(_,[],[]).
filter(Predicate,[First|Rest],[First|Tail]) :-
   filter(Predicate,Rest,Tail).
filter(Predicate,[_|Rest],Result) :-
   filter(Predicate,Rest,Result).
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top