在序言中从数据库调用事实
我已使用 assert(....) 将给定的上下文无关语法插入到数据库中 如果语法类似于
S-->a,S,b
S-->c
此语法,则将其插入数据库中。 我必须编写一个dcg来为数据库中的cfg生成句子。 例如,如果我以这种方式定义 dcg myDcg('S',str),则应调用或替换'S'(非终结符)< /em> 由 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).
每当遇到终端时,应该将其打印出来,而当遇到非终端时,它将回溯。
I've inserted the given context free grammar into the database using assert(....)
If the grammar is something like
S-->a,S,b
S-->c
This grammar is inserted into the database.
I have to write a dcg to generate sentences for the cfg in the database.
For example if i define the dcg in this way myDcg('S',str), the 'S'(non terminal) should be called or substituted by aSb or c|d or so.
The problem is how can i call/substitute 'S' by facts from the database each time a non terminal('S') is encountered to generate sentences.
Hope you understood my question, if not i will try to edit the question.
Below(Sample code) is what i wanted to do exactly
This is not dcg.
myGrammar([], []):-!.
myGrammar([T|Rest], [T|Sentence]):-
myGrammar(Rest, Sentence).
myGrammar([NT|Rest], Sentence):-
grammar(NT, Rest1),
append(Rest1,Rest, NewRest),
myGrammar(NewRest, Sentence).
Whenever a terminal is encountered it should be printed out and when a non terminal is encountered it will backtrack.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在谓词
mygrammar/2
中,第一个参数中有一个非终结符和终结符列表,第二个参数中有一个终结符列表。如果第二个参数是第一个参数的形式,它可能会成功。所以这里本质上是 DCG 的元解释器。一些建议:您的分词器当前生成
[grammar('S',[a,'S',b]),grammar('S',[....]),..].
让它产生[grammar('S',[t(a),nt('S'),t(b)]),grammar('S',[....]),.. ]
代替。通过这种方式,什么是终端、什么是非终端就很明显了。而且,哦,删除它!顺便说一句,DCG 比这个解释器更通用一些。
非终结符和终结符之间的实际分类必须由分词器完成。
如果您使用的是字符(单字符原子),则将使用
char_code(Char, Code)
在它们之间进行转换。完整的 Unicode 支持仍处于起步阶段。它非常棘手,因为像 Ⓐ 这样的字符的所有特殊情况都是大写的,但仍然不能成为标识符的一部分。但目前您可以在 SWI 中执行以下操作。
更新:与此同时,有用于此目的的
char_type/2
和code_type/2
。In your predicate
mygrammar/2
there is a list of non-terminals and terminals in the first argument and a list of terminals in the second. It should probably succeed if the second argument is of the form of the first. So what you have here essentially is a meta interpreter for DCGs. A few suggestions:Your tokenizer produces currently
[grammar('S',[a,'S',b]),grammar('S',[....]),..].
Let it produce[grammar('S',[t(a),nt('S'),t(b)]),grammar('S',[....]),..]
instead. In this manner it's evident what is a terminal and what is a non-terminal. And, oh, remove that !.DCGs, btw are a bit more general than this interpreter.
The actual classification between non-terminals and terminals has to be done by the tokenizer.
If you are using chars (one-character atoms), you will use
char_code(Char, Code)
to convert between them.Full Unicode support is still in its infancy. Its very tricky because of all those special cases for characters like Ⓐ which is upper case but still cannot be part of an identifier. But here is how you can do it in SWI currently.
Update: In the meantime, there is
char_type/2
andcode_type/2
for this purpose.我假设您最近开始使用 Prolog。
是的,您可以将某些内容断言到数据库中,但这并不是您首先要做的常见事情。当您对基本语言感到安全时,您会想在以后使用该功能。
您通常要做的是将语法写入像
myfirstgrammar.pl
这样的文件中,然后将该文件加载到 Prolog 系统中。有关语法的详细信息,请参阅最近的帖子。
I assume that you started with Prolog recently.
Yes, you can assert things into the database, but this isn't the common thing you do in the first place. You will want to use that feature much later when you feel safe with the base language.
What you typically do is to write a grammar into a file like
myfirstgrammar.pl
and then load that file into your Prolog system.Please refer to this recent thread for details concerning the grammar.