Вызов фактов из базы данных в прологе - PullRequest
1 голос
/ 01 декабря 2011

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

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

Эта грамматика вставляется вбаза данных.Я должен написать DCG для генерации предложений для CFG в базе данных.Например, если я определяю dcg таким образом myDcg ('S', str) , 'S' (нетерминал) должен быть вызван или замещен aSb или c | d или около того.

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

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

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

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

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

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

Ответы [ 2 ]

2 голосов
/ 02 декабря 2011

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

Ваш токенизатор в настоящее время производит [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).

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

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

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

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

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

Полная поддержка Юникода все еще находится в зачаточном состоянии.Это очень сложно из-за всех тех особых случаев для символов, как Ⓐ, который является заглавным, но все еще не может быть частью идентификатора.Но вот как вы можете сделать это в 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).
2 голосов
/ 01 декабря 2011

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

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

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

...