在prolog中调用数据库中的事实

时间:2011-12-01 03:20:03

标签: prolog dcg prolog-assert

我使用 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). 

每当遇到终端时,都应打印出来,当遇到非终端时,它会回溯。

2 个答案:

答案 0 :(得分:2)

我假设您最近开始使用Prolog。 是的,您可以将内容置于数据库中,但这不是您首先要做的常见事情。当您对基本语言感到安全时,您将希望稍后使用该功能。

您通常要将语法写入myfirstgrammar.pl等文件,然后将该文件加载到Prolog系统中。

有关语法的详细信息,请参阅this recent thread

答案 1 :(得分:2)

在谓词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).

DCGs,btw比这个解释器更通用。

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

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