在序言中从数据库调用事实

发布于 2024-12-19 02:18:11 字数 750 浏览 1 评论 0原文

我已使用 assert(....) 将给定的上下文无关语法插入到数据库中 如果语法类似于

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

此语法,则将其插入数据库中。 我必须编写一个dcg来为数据库中的cfg生成句子。 例如,如果我以这种方式定义 dcg myDcg('S',str),则应调用或替换'S'(非终结符)< /em> 由 aSbc|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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

泡沫很甜 2024-12-26 02:18:11

在谓词 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 比这个解释器更通用一些。

非终结符和终结符之间的实际分类必须由分词器完成。

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/2code_type/2

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

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 !.

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, btw are a bit more general than this interpreter.

The actual classification between non-terminals and terminals has to be done by the tokenizer.

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

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

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.

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).

Update: In the meantime, there is char_type/2 and code_type/2 for this purpose.

uppercasecode(C) :-
   code_class(C, upper),
   code_class(C, prolog_var_start).
心奴独伤 2024-12-26 02:18:11

我假设您最近开始使用 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文