Вызов фактов из базы данных в prolog
-
26-10-2019 - |
Вопрос
Я вставил данную контекстно-свободную грамматику в базу данных, используя утверждать (....) Если грамматика представляет собой что-то вроде
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.
Пожалуйста, обратитесь к эта недавняя тема для получения подробной информации о грамматике.