Пролог: Фильтр и список

Создайте предикат с именем fPairsAtoms/3, чтобы для данного атома (первый аргумент) и списка пар объединяли третий параметр с отфильтрованным списком пар, выбирая только пары, у которых первый компонент является атомом первого аргумента.,

Пример:

fPairsAtoms(sA,[[basA,absAb],[ab,bbsA],[sA,abbsB],[bsA,sAsB],[sA,bb]],X)  

Результат:

X = [[sA,abbsB],[sA,bb]]

Я не понимаю..... Что я должен столкнуться с этими типами упражнений? Можете ли вы помочь мне найти решение?

Сегодня я начал с пролога, я новичок во всех отношениях.

2 ответа

Если вы только начали сегодня, возможно, вам еще слишком рано решать эту проблему.

Сначала вы должны понять, что такое термины Пролог: atomsлогично Variables, сложные условия foo(x,X,bar(baz)),

Тогда вы должны понимать объединение, a = a, a = A, A = a, A = foo(a), foo(A) = foo(a), [atom, B] = [A, bar],

Вы должны понимать представление списков, где

[  A,   B,   C     ] 
= [A,   B | [C]    ] 
= [A | [B ,  C    ]] 
= [A | [B | [C]   ]] 
= .... 
= [A ,  B ,  C | []] 

так что объединяющий [A | B] = [a] успешно, что также приводит к объединению A = a а также B = [], но объединяющий [A | B] = [] не удается

Тогда вам нужно понять предикаты, которые под процедурной интерпретацией означают:

to_prove(This) :- need_to_prove(This) , and_also(That).

Чтобы

fPairsAtoms(sA, [[basA,absAb],[ab,bbsA],[sA,abbsB],[bsA,sAsB],[sA,bb]], X) :-
            X = [                       [sA,abbsB],           [sA,bb]].

это совершенно правильное, хотя и чрезвычайно узкое определение.

Но тогда тоже

fPairsAtoms(sA, [[basA,absAb],[ab,bbsA],[sA,abbsB] | [[bsA,sAsB],[sA,bb]] ], X) :-
            X = [                       [sA,abbsB] | [           [sA,bb]] ].
% and 
fPairsAtoms(sA, [             [ab,bbsA],[sA,abbsB] | [[bsA,sAsB],[sA,bb]] ], X) :-
            X = [                       [sA,abbsB] | [           [sA,bb]] ].
% and 
fPairsAtoms(sA, [                       [sA,abbsB] | [[bsA,sAsB],[sA,bb]] ], X) :-
            X = [                       [sA,abbsB] | [           [sA,bb]] ].
% and 
fPairsAtoms(sA,                                      [[bsA,sAsB],[sA,bb]]  , Y) :-
            Y =                                      [           [sA,bb]].
% ... and 
fPairsAtoms(sA,                                                        []  , Y) :-
            Y =                                                        [].

и так же

fPairsAtoms(sA, [                       [sA,abbsB] | L                    ], X) :- 
            L =                                      [[bsA,sAsB],[sA,bb]], 
            Y =                                      [           [sA,bb]],
            X = [                       [sA,abbsB] | Y                    ].

и поэтому

fPairsAtoms(sA, [                       [sA,abbsB] | L                    ], X) :- 
            L =                                      [[bsA,sAsB],[sA,bb]], 
            fPairsAtoms( L, Y),
            Y =                                      [           [sA,bb]],
            X = [                       [sA,abbsB] | Y                    ].
% and
fPairsAtoms(sA, [                       [sA,abbsB] | L                    ], X) :-
            L =                                      [[bsA,sAsB],[sA,bb]], 
            fPairsAtoms( L, Y),
            X = [                       [sA,abbsB] | Y                    ].
% and
fPairsAtoms(sA, [                       [sA,abbsB] | L                    ], X) :-
            fPairsAtoms( L, Y),
            X = [                       [sA,abbsB] | Y                    ].
% and so
fPairsAtoms(sA, [                       A          | L                    ], X) :-
            A =                         [sA, B   ],
            fPairsAtoms( L, Y),
            X = [                       A          | Y                    ].
% and even
fPairsAtoms(SA, [                       A          | L                    ], X) :-
            A =                         [SA, B   ],
            fPairsAtoms( SA, L, Y),
            X = [                       A          | Y                    ].

Но с другой стороны, в случаях, когда не было совпадения, мы видели, что это

fPairsAtoms(SA, [                       A          | L                    ], X) :-
            A =                         [SB, B   ],
            dif( SA, SB),
            fPairsAtoms( SA, L, Y),
            X =                                      Y                     .
% i.e.
fPairsAtoms(SA, [                       [SB, B   ] | L                    ], X) :-
            dif( SA, SB),
            fPairsAtoms( SA, L,                      X)                    .

Итак, какой из двух пунктов, которые мы закончили,

fPairsAtoms( SA, [ [SA, _] | L ], X) :-
            fPairsAtoms( SA, L, Y),
            X = [A |            Y].

fPairsAtoms( SA, [ [SB, _] | L ], X) :-
            dif( SA, SB),
            fPairsAtoms( SA, L,   X).

правильный? Ответ: оба!

Чтобы отфильтровать пары в списке, вам нужно пройти его, сравнивая данный атом с первым элементом каждой пары. Тривиальный предикат для прохождения списка будет:

traverse([]).
traverse([Head| Tail]) :-
    traverse(Tail).

Предикат в описании вашей проблемы ужасно назван и не следует рекомендуемым рекомендациям по кодированию Prolog. Давайте переименуем его в filter_pairs_by_key/3 и измените порядок аргументов на filter_pairs_by_key(Pairs, SearchKey, FilteredPairs), Кроме того, рекомендуемое представление для пары в Прологе Key-Value, Существуют стандартные предикаты и предикаты библиотеки, которые ожидают этого представления (например, keysort/2). На основе traverse/2 Шаблон предиката и рекомендации по стилю кода мы можем написать:

filter_pairs_by_key([], _, []).
filter_pairs_by_key([Key-Value| Pairs], SearchKey, [Key-Value| FilteredPairs]) :-
     Key = SearchKey, 
     filter_pairs_by_key(Pairs, Atom, FilteredPairs).
filter_pairs_by_key([Key-_| Pairs], SearchKey, FilteredPairs) :-
     Key \= SearchKey, 
     filter_pairs_by_key(Pairs, SearchKey, FilteredPairs).

Обратите внимание, что я использую два предложения для непустого списка: одно, когда ключ пары соответствует атому, и одно, когда совпадение не удается.

Образец звонка:

| ?- filter_pairs_by_key([basA-absAb,ab-bbsA,sA-abbsB,bsA-sAsB,sA-bb], sA, FilteredPairs).          

FilteredPairs = [sA-abbsB,sA-bb] ? 

yes

Больше можно сказать об этой проблеме и об этом конкретном решении, но, как упоминалось в комментариях, это не упражнение для начинающих. Примите во внимание рекомендации комментариев и после того, как вы освоитесь с нотацией списка Пролога, поиграйте с этим решением.

Другие вопросы по тегам