Parsing 匹配';连接器';和创造结构?

Parsing 匹配';连接器';和创造结构?,parsing,prolog,dcg,Parsing,Prolog,Dcg,我正在尝试匹配,然后转换为结构: text1, connector, text2 ==> connector(text1,text2) 以下内容很有用,但似乎过于笨拙和不惯用: p([]) --> []. p([H|T]) --> [H], p(T). conn(C) :- member(C,[on,in]). req(C) --> p(X), [Fun], p(Y), { C =.. [Fun,X,Y], conn(Fun) }. 有什么更好的方法 有一些问题,所

我正在尝试匹配,然后转换为结构:

text1, connector, text2 ==> connector(text1,text2)
以下内容很有用,但似乎过于笨拙和不惯用:

p([]) --> [].
p([H|T]) --> [H], p(T).
conn(C) :- member(C,[on,in]).
req(C) --> p(X), [Fun], p(Y), { C =.. [Fun,X,Y], conn(Fun) }.
有什么更好的方法


有一些问题,所以这里是大局。。。经过一番探索,这里就是它的位置

我想解析简体英语,这样它就可以生成事实、规则、动作、问题搜索等等。。。这将用于类似env的聊天,即Q/a、req/reply、训练学习…循环

这不太适合于语言解析(np、vp、名词等),但最好先对语言模板(如编程语言)进行解析

模板如:ifthen、repeat、while、in、into、on、part、isa等


。。。(后来我想用python spacy来准备词性信息,如果我需要的话,它解决了词性问题,因为prolog没有NN标记。有python prolog桥,python也有更好的CLI库)

你的问题缺乏上下文,所以我不能说你的任务是否真的需要DCG。在这种情况下,请记住,req//1的组合很糟糕,因为p//1将匹配任何内容,并且只有在回溯时才能识别连接器

如果一个短语中只需要一次连接器,那么这可能会更容易理解:

req(L,in(X,Y)):-append(X,[in | Y],L)。
请求(L,on(X,Y)):-append(X,[on | Y],L)。
编辑

而且很容易概括,就像您已经做的那样:

req(L,C):-append(X[F | Y],L),conn(F),C=…[F,X,Y]。

很好,您将程序简化为一个最小的示例,不幸的是,它变得有点太小了。基于您的其他问题,我将从以下代码版本开始:

noun(box) --> [box].
noun(table) --> [table].

conn(C) :- member(C,[on,in]).

req(C) --> noun(X), [Fun], noun(Y), { C =.. [Fun,X,Y], conn(Fun) }.
以下工作:

?- phrase(req(Req), [box, on, table]).
Req = on(box, table) ;
false.
但最一般的查询不起作用:

?- phrase(req(Req), Phrase).
ERROR: Arguments are not sufficiently instantiated
ERROR: In:
ERROR:   [12] _4008=..[_4014,box|...]
这是不幸的,因为最通用的查询非常方便:它为您提供了一些“免费测试”,允许您运行代码而不必考虑测试用例。这里出现错误的原因是,我们试图使用变量函数符号应用
=../2

我会这样写语法:

noun(box) --> [box].
noun(table) --> [table].

connector(X, Y, on(X, Y)) -->
    [on].
connector(X, Y, in(X, Y)) -->
    [in].

req(C) -->
    noun(X),
    connector(X, Y, C),
    noun(Y).
这有点明确,但它允许我们使用最一般的查询进行测试(完全测试,因为没有递归!):

?- phrase(req(Req), Phrase).
Req = on(box, box),
Phrase = [box, on, box] ;
Req = on(box, table),
Phrase = [box, on, table] ;
Req = in(box, box),
Phrase = [box, in, box] ;
Req = in(box, table),
Phrase = [box, in, table] ;
Req = on(table, box),
Phrase = [table, on, box] ;
Req = on(table, table),
Phrase = [table, on, table] ;
Req = in(table, box),
Phrase = [table, in, box] ;
Req = in(table, table),
Phrase = [table, in, table].
具体测试也很有效(希望这并不奇怪):

连接器
规则构造术语可以让它们为特定连接器做额外的工作。例如,我们可能希望将“inside”视为“in”的同义词:

或者我们可能希望将
Y
下的“
X
”视为
X
上的“
Y
”的同义词:


谢谢你的详细解释。。。我展示的只是一小部分。。f、 e.没有办法列举所有的名词,这必须解析任何文本,这就是为什么我现在通过p()在列表中对其余的进行筛选,直到我把它整理出来。我试着像编程语言一样解析英语,而不是解析np,vp,。。事实上,这就是我要做的事。。首先像Prog lang一样解析它,然后从语言上解析它。我只是从不同的方向探索,看看什么是有效的。。。事情还有很多,但这毕竟太长了;)这是一个引人入胜的话题,祝你好运,保持兴趣和好问题!谢谢是的,p()现在只是占位符。这只是两个连接符,还有:and,or,into,after,before,UPPER,DOWN,FRONE
?- phrase(req(Req), [box, on, table]).
Req = on(box, table) ;
false.
connector(X, Y, in(X, Y)) -->
    [in] | [inside].

?- phrase(req(Req), [box, in, box]).
Req = in(box, box) ;
false.

?- phrase(req(Req), [box, inside, box]).
Req = in(box, box) ;
false.
connector(X, Y, on(Y, X)) -->
    [under].

?- phrase(req(Req), [table, under, box]).
Req = on(box, table) ;
false.