Создать список из Prolog DCG - PullRequest
0 голосов
/ 19 мая 2019

Я не могу понять, как создать список, содержащий элементы, которые использовались для формирования предложения с использованием определенной DCG.

Предположим, у нас есть следующие DCG:

father --> [Peter].
mother --> [Isabel].

child --> [Guido].
child --> [Claudia].

verb --> [is].
relation --> [father, of].
relation --> [mother, of].

pronoun --> [he].
pronoun --> [she].

adjective --> [a, male].
adjective --> [a, female].

s --> father, verb, relation, child.
s --> mother, verb, relation, child.
s --> pronoun, verb, adjective.

Предложения могут быть запрошены следующим образом: phrase(s, [peter, is, father, of, guido]), phrase(s, [he, is, a, male])., который возвращает true.

Как я могу создавать и поддерживатьсписок элементов этих исполненных предложений, чтобы получить false при выполнении следующих предложений (поскольку Петр - мужчина, обратите внимание на she вместо he):

phrase(s, [peter, is, father, of, guido]), phrase(s, [she, is, a, female]).

ThisВопрос использует тот же пример, что и здесь .

Ответы [ 2 ]

0 голосов
/ 20 мая 2019

Чтобы ответить на дополнительный вопрос, который был добавлен позже: вы можете передавать информацию, добавляя дополнительные аргументы, но вам нужно описать последовательность предложений.Пример phrase(s, [peter, is, father, of, guido]), phrase(s, [he, is, a, male]) должен быть успешным, то, что не должно быть успешным, - это произносить два предложения друг за другом phrase(ss, [peter, is, father, of, guido, '.', he, is, a, male,'.']) (Или это может быть успешным, оставляя «он» в качестве ссылки на кого-то, кого мы не знаем. Все зависит от того, насколько мы строгиес контекстом.).

Чтобы сделать это правильно, нам нужно прыгнуть довольно много обручей.Сначала нам нужно добавить информацию об анализе в правила DCG.Например, np(np([A,O],object)) --> %... будет анализировать статью, за которой следует объект, в структуру np([A,O],object).Давайте разберем ['a', 'male'] и [guido] с ним:

?- phrase(np(NP), [a, male]).
NP = np([article(a), object(male, male)], object) ;
false.

?- phrase(np(NP), [guido]).
NP = np([name(guido, male)], name) ;
false.

Первый аргумент np - это список, потому что другие правила np имеют только для компонента.Обратите внимание, что мы добавили пол в качестве атрибута к name и object.На других языках, например на французском, статья также имеет пол, который должен согласовываться с объектом, но на английском языке мы можем оставить это в стороне.Более сложные реализации также будут учитывать, если объект находится в единственном или множественном числе (то же самое относится и к различным модам глагола).

Для глаголов нам нужно различать, сколько фраз существительного им нужно.Это делается с помощью проверок is_transitive/1, is_intransitive/1 и is_bitransitive/1.

Найти хорошее решение для наглядных местоимений сложно: местоимению не нужно ссылаться на предыдущий предмет, например, в «Гейле женат на Петре. Он старше ее».Даже не нужно ссылаться на последнее предложение, например, «Питер там, где он хочет быть».Это означает, что: а) вы должны заранее решить, какие случаи вы действительно хотите охватить, и б) лучше всего принимать эти решения во втором прогоне анализа, когда у вас есть полная структурированная информация.Это отражает лингвистическое различие между синтаксическими, семантическими и прагматическими рассуждениями , где я бы классифицировал проблему, которую вы хотели бы решить, как прагматическую, которая зависит от двух других шагов.

Мое решение здесьпросто включает конкретное решение, которое вы хотели принять, в один анализ, за ​​счет читабельности правила ss DCG: мы добавляем дополнительный аргумент, который собирает уже проанализированные предложения, так называемый аккумулятор.Когда мы начинаем синтаксический анализ, история пуста, что отражается правилом ss(S) --> ss(S,[])..Для фактических правил нам нужно различать, начинается ли текущее предложение с демонстративного местоимения или нет.В первом случае нам нужно решить эту проблему, что мы делаем здесь, посмотрев на возможные фразы существительного в предыдущем предложении, которые согласуются по полу.Имея этот механизм, мы можем разобрать предложение [peter, is, a father, '.', he, is a father,'.']:

?- phrase(ss(Tree), [peter,is,a,father,'.', he, is, a, father, '.']).
Tree = [s(np([name(peter, male)], name), vp([verb(is), np([article(a), object(father, male)], object)])), s(np([pronoun(he, male)], dpronoun), vp([verb(is), np([article(a), object(..., ...)], object)]))] ;

, но не можем разобрать [peter,is,a,father,'.', she, is, a, father, '.']:

?- phrase(ss(Tree), [peter,is,a,father,'.', she, is, a, father, '.']).
false.

В правильном семантическом / прагматическом анализе мыобогатит местоименную фразу фактической именованной именной фразой, но это будет сделано как переписывание исходного дерева разбора.Вот код для этого:

%%%% utility predicates
% gender_of(X,Y) is true if X is the gender of the syntax tree node Y
gender_of(X,name(_,X)).
gender_of(X,pronoun(_,X)).
gender_of(X,object(_,X)).
gender_of(G,np([X],_)) :-
    gender_of(G,X).
gender_of(G,np([_,X],_)) :-
    gender_of(G,X).

% nps_of(X,Y) is true if X is the list of nps occurring in the syntax tree node Y
nps_of([],vp([_])).
nps_of([NP],vp([_,NP])).
nps_of([NP|Rest],s(NP,VP)) :-
    nps_of(Rest, VP).

% nountype_of(X,Y) is true if X is the type of the np node Y
nountype_of(X, np(_,X)).

% is_intransitive(X) is true if the verb X does not require an object phrase
is_intransitive(is).
is_intransitive(walk).
% is_transitive(X) is true if the verb X requires an object phrase
is_transitive(is).
% is_bitransitive(X) is true if the verb X requires two object phrases
is_bitransitive(is).

%%%% DCG rules

% name are distinct from objects because they do not require articles
name(name(peter,male)) --> [peter].
name(name(isabel,female)) --> [isabel].
name(name(guido,male)) --> [guido].
name(name(claudia,female)) --> [claudia].

% nouns that require an article
object(object(mother,female)) --> [mother].
object(object(father,male)) --> [father].
object(object(male,male)) --> [male].
object(object(female,female)) --> [female].

% verbs
verb(verb(is)) --> [is].
verb(verb(walk)) --> [walks].

% pronouns
pronoun(pronoun(he,male)) --> [he].
pronoun(pronoun(she,female)) --> [she].

% articles
article(article(a)) -->
    [a].
article(article(the)) -->
    [the].

% noun phrases
np(np([A,O],object)) -->
    article(A),
    object(O).
np(np([N],name)) -->
    name(N).
np(np([PN], dpronoun)) -->
    pronoun(PN).

% verb phrases
vp(vp([V,NP])) -->
    verb(V),
    { V = verb(Name), is_transitive(Name) },
    np(NP).
vp(vp([V])) -->
    verb(V),
    { V = verb(Name), is_intransitive(Name) }.

end -->
    ['.'].

% a single sentence
s(s(NP,VP)) -->
    np(NP),
    vp(VP),
    end.

% a list of sentences, with accumulator
ss([],_Acc) -->
    [].
ss([S|Sentences],[]) -->
    s(S),
    ss(Sentences, [S]).
ss([S|Sentences], [LastS | Acc]) -->
    { S = s(np([Pronoun], dpronoun),_) },
    s(S),
    { gender_of(G, Pronoun), nps_of(LastNPS, LastS), member(LNP, LastNPS), gender_of(G,LNP) },
    ss(Sentences, [S, LastS | Acc]).
ss([S|Sentences], [LastS | Acc]) -->
    { S = s(NP,_), nountype_of(NT,NP), dif(NT,dpronoun) },
    s(S),
    ss(Sentences, [S, LastS | Acc]).

% wrapper of ss with empty accumulator
ss(S) -->
    ss(S,[]).
0 голосов
/ 19 мая 2019

Правильный интерфейс для DCG - через phrase/2, упрощенную версию phrase/3:

?- phrase(s, X).
X = [_8304, is, father, of, _8328] ;
X = [_8304, is, father, of, _8328] ;
X = [_8304, is, mother, of, _8328] ;
% etc

Переменные _8404 взяты из правил, таких как father --> [Peter]., поскольку в Peter также есть переменная (переменные начинаются с _ или с заглавной буквы. Вы можете исправить это, экранируя атом как 'Peter' - см. также другой вопрос, который вы задали).

Первое имя фразы - это правило DCG, второй аргумент - список. Когда вы используете определенный список в качестве второго аргумента, подстановка ответа пуста, и Пролог просто сообщает, что он может получить список. В моем примере я использовал переменную X и получил для нее возможные замены, которые можно вывести.

Ограничения могут быть добавлены в виде целей, заключенных в фигурные скобки:

dupnum(X) --> 
   { member(X, [0,1,2,3,4,5,6,7,8,9]) },
   [X,X].

ведет к

?- phrase(dupnum(X), Y).
X = 0,
Y = [0, 0] ;
X = 1,
Y = [1, 1] ;
% etc

В примере также показано, что в DCG-производствах могут быть аргументы, которые вы можете использовать для распространения дерева разбора или некоторого общего контекста синтаксического анализа.

...