Вопрос

Я вставил данную контекстно-свободную грамматику в базу данных, используя утверждать (....) Если грамматика представляет собой что-то вроде

S-->a,S,b
S-->c

Эта грамматика вставляется в базу данных.Мне нужно написать dcg для генерации предложений для cfg в базе данных.Например, если я определю dcg таким образом myDcg ('S',str), тот самый "С"(нетерминальный) должен быть вызван или замененный Автор: aSb или c|d или около того.

Проблема в том, как я могу вызвать / заменить "С" по фактам из базы данных каждый раз, когда встречается нетерминал ('Ы') для генерации предложений.

Надеюсь, вы поняли мой вопрос, если нет, я попытаюсь отредактировать вопрос.


Ниже (пример кода) приведено то, что я хотел сделать именно Это не dcg.

myGrammar([], []):-!.

myGrammar([T|Rest], [T|Sentence]):-
          myGrammar(Rest, Sentence).

myGrammar([NT|Rest], Sentence):-
          grammar(NT, Rest1),
          append(Rest1,Rest, NewRest),
          myGrammar(NewRest, Sentence). 

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

Это было полезно?

Решение

В вашем предикате mygrammar/2 в первом аргументе есть список нетерминалов и терминалов, а во втором - список терминалов.Вероятно, это должно увенчаться успехом, если второй аргумент имеет форму первого.Итак, то, что у вас здесь есть, по сути, является мета-интерпретатором для DCGS.Несколько предложений:

Ваш токенизатор производит в данный момент [grammar('S',[a,'S',b]),grammar('S',[....]),..]. Пусть это произведет [grammar('S',[t(a),nt('S'),t(b)]),grammar('S',[....]),..] вместо этого.Таким образом, становится очевидным, что является терминальным, а что нетерминальным.И, о, уберите это!.

myGrammar([], []).
myGrammar([t(T)|Rest], [T|Sentence]):-
   myGrammar(Rest, Sentence).
myGrammar([nt(NT)|Rest], Sentence):-
   grammar(NT, Rest1),
   append(Rest1,Rest, NewRest),
   myGrammar(NewRest, Sentence).

DCGS, кстати, немного более общие, чем этот интерпретатор.

Фактическая классификация между нетерминалами и терминалами должна выполняться токенизатором.

uppercasecode(C) :-
   between(0'A,0'Z,C).

lowercasecode(C) :-
   between(0'a,0'z,C).

Если вы используете символы (односимвольные атомы), вы будете использовать char_code(Char, Code) чтобы конвертировать между ними.

Полная поддержка Unicode все еще находится в зачаточном состоянии.Это очень сложно из-за всех этих особых случаев для символов типа Ⓐ, которые являются заглавными, но все равно не могут быть частью идентификатора.Но вот как вы можете сделать это в SWI в настоящее время.

uppercasecode(C) :-
   '$code_class'(C,upper),
   '$code_class'(C,id_start).

lowercasecode(C) :-
   '$code_class'(C,id_start),
   '$code_class'(C,id_continue),
   \+ '$code_class'(C,upper).

Обновить:В то же время, есть char_type/2 и code_type/2 для этой цели.

uppercasecode(C) :-
   code_class(C, upper),
   code_class(C, prolog_var_start).

Другие советы

Я предполагаю, что вы недавно начали работать с Prolog.Да, вы можете утверждать что-либо в базе данных, но это не самое обычное, что вы делаете в первую очередь.Вам захочется использовать эту функцию гораздо позже, когда вы почувствуете себя в безопасности с базовым языком.

Что вы обычно делаете, так это записываете грамматику в файл, подобный myfirstgrammar.pl а затем загрузите этот файл в свою систему Prolog.

Пожалуйста, обратитесь к эта недавняя тема для получения подробной информации о грамматике.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top