Пролог: Фильтр и список
Создайте предикат с именем 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
Больше можно сказать об этой проблеме и об этом конкретном решении, но, как упоминалось в комментариях, это не упражнение для начинающих. Примите во внимание рекомендации комментариев и после того, как вы освоитесь с нотацией списка Пролога, поиграйте с этим решением.