2013-12-03 2 views
1

Я недавно начал возиться с Prolog, но ударил камень преткновения со списками.Поиск имен в списке - Sicstus Prolog

Предположим, у меня есть список [dom,is,a,man,jane,is,a,woman,mary,is,a,woman], и я хочу создать новый список имен женщин [jane,mary]. Как мне это сделать? Я предполагаю, что мне придется искать в списке для любого X, за которым следует is,a,woman, но я понятия не имею, как этого добиться. Я работаю в течение нескольких часов безрезультатно. Я бы разместил код, если бы у меня были: s

Спасибо за вашу помощь!

+0

Какой "алгоритм" (ну, в декларативный смысл), о чем вы думали? Потому что, вы знаете, для нас важно быть уверенным, что наш ответ не помешает вам подумать о назначении вашего класса ... –

+0

Я бы подумал, что это более пролог-y, чтобы перебирать список фактов - то есть ' [женщина (mary), мужчина (dom), женщина (jane)] ', так что предикат подразумевает, что mary - женщина. Является ли этот список слов ограничением? –

+3

«Гуглинг в течение нескольких часов» для ответа, не изучая язык и тратя время на то, чтобы попробовать что-то, не является оптимальным путем для изучения. Это не очень изящный сценарий, но на мгновение он не будет «искать список» для таких вещей, как 'is, a, woman', что является императивным способом взглянуть на него. Если ваша структура списка действительно такая строгая, вы можете (хотя и негибко), например, использовать шаблон, такой как '[X, is, a, woman | T]', чтобы выбрать женщину из передней части списка и записаться на 'T'. – lurker

ответ

2

Как всегда при описании списков, используйте DCG. Например:

men_women([], [])  --> []. 
men_women(Ms, [W|Ws]) --> [W,is,a,woman], men_women(Ms, Ws). 
men_women([M|Ms], Ws) --> [M,is,a,man], men_women(Ms, Ws). 

Пример запроса и его результат:

?- phrase(men_women(_, Ws), [dom,is,a,man,jane,is,a,woman,mary,is,a,woman]). 
Ws = [jane, mary] ; 
false. 

Это DCG также работает для очень общих запросов, таких как:

?- length(Ls, _), phrase(men_women(_, Ws), Ls). 
Ls = [], Ws = [] ; 
Ls = [_G376, is, a, woman], Ws = [_G376] ; 
Ls = [_G376, is, a, man], Ws = [] ; 
Ls = [_G376, is, a, woman, _G388, is, a, woman], Ws = [_G376, _G388] . 
+0

Ничего себе, я даже никогда не встречался с DCG. Спасибо, мат! Это выглядит великолепно, может потребоваться некоторое время, чтобы полностью понять это – Peach

1
% end once the input is empty 
find_gender([], _, []). 

% Compare the first 4 "entries" in the list. 
% Name and Gender are variables, b/c they are written in upper case. 
% 'is' and 'a' are atom. 
% If the pattern matches, prepend the Name to the results. 
find_gender([Name,is,a,Gender|Tail], Gender, [Name|Names]) :- 
    % Find further Names in the Tail of the input list. 
    find_gender(Tail, Gender, Names). 

% The person is not of that Gender. 
% You don't need to catch the Name here, b/c it won't be used. 
find_gender([_,is,a,X|Tail], Gender, Names) :- 
    X \= Gender, % otherwise you would have wrong results when backtracking 
    find_gender(Tail, Gender, Names). 

% This is your usage example: 
find_women(List, Names) :- 
    find_gender(List, woman, Names). 
find_men(List, Names) :- 
    find_gender(List, man, Names). 

Реверс работает хорошо:

?- find_women(List, [jane,marry]). 
List = [jane, is, a, woman, marry, is, a, woman] ; 
false. 

Если список ввода может содержать другие данные, как в [jane,owns,a,car,jane,is,a,woman,the,car,is,red], то вы можете просто удалить записи, пока вы не найдете свой рисунок снова, добавив этот пункт:

find_gender([_|T], Gender, Names) :- 
    find_gender(T, Gender, Names). 

Но это приведет к нескольким результатам при обратном отслеживании, с некоторыми пропущенными именами. Возможно, вы захотите ввести разрезы (!) в первых предложениях в этом случае.

+0

Спасибо за ваш ответ Кей. Я работал над этим и пытался понять это. Попробуйте вы пример для списка, который может содержать дополнительные данные, такие как [jane, owns, a, car, jane, is, a, woman, the, car, is, red], похоже, не работает. Даже с последним предложением, которое вы добавили. Пролог говорит, что нет! Не можете понять, какие идеи? Спасибо =) – Peach

+0

Извините, я забыл параметр «Пол». Исправлено. – kay

Смежные вопросы