在序言中从数据库调用事实 [英] Calling facts from database in prolog

查看:50
本文介绍了在序言中从数据库调用事实的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

这个语法被插入到数据库中.我必须写一个dcg来为数据库中的cfg生成句子.例如,如果我以这种方式定义 dcgmyDcg('S',str)'S'(非终结符)应该被调用或替换aSbc|d 左右.

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.

问题是每次遇到非终结符('S')来生成句子时,我如何通过数据库中的事实调用/替换'S'.

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.

下面(示例代码)正是我想要做的这不是dcg.

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.

推荐答案

在你的谓词 mygrammar/2 中,第一个参数中有一个非终结符和终结符列表,以及第二.如果第二个参数是第一个参数的形式,它可能应该成功.因此,您在这里拥有的本质上是 DCG 的元解释器.一些建议:

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:

您的分词器当前生成 [grammar('S',[a,'S',b]),grammar('S',[....]),..].让它产生 [grammar('S',[t(a),nt('S'),t(b)]),grammar('S',[....]),..] 代替.通过这种方式,很明显什么是终端,什么是非终端.而且,哦,删除那个!

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

DCG,顺便说一句,比这个解释器更通用.

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

如果您使用字符(一个字符的原子),您将使用 char_code(Char, Code) 在它们之间进行转换.

If you are using chars (one-character atoms), you will use char_code(Char, Code) to convert between them.

完整的 Unicode 支持仍处于起步阶段.它非常棘手,因为所有像 Ⓐ 这样的字符的特殊情况都是大写,但仍然不能成为标识符的一部分.但是,您目前可以在 SWI 中执行此操作.

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

更新:同时,有 char_type/2code_type/2 用于此目的.

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

这篇关于在序言中从数据库调用事实的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆