如何使用 prolog 用逻辑语言翻译句子? [英] How to translate a sentence in a logical language using prolog?

查看:34
本文介绍了如何使用 prolog 用逻辑语言翻译句子?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个句子及其语法,在哪里可以找到允许我用逻辑语言编写句子的谓词序言?

I have a sentence and its syntax, where can I find the predicates prolog that allow me to write the sentence in a logical language?

存在或你们中的任何人都可以帮助我创建一个谓词

Exists or any of you can help me to create a predicate that

将以下字符串作为输入

(S (NP (NNP John))
    (VP (VBP see)
      (NP (NNP Mary))))

并返回这个

see(John,Mary)

推荐答案

我认为 @CapelliC 的答案更好 (+1),但我想尝试一下,看看我想出了什么.你可以不用 LisProlog 来解决这个问题,但你可以肯定 LisProlog 会比我的现成 DCG 废话做更好的工作.

I think @CapelliC's answer is better (+1), but I wanted to take a crack at it and see what I came up with. You can solve this without LisProlog, but you can be quite sure that LisProlog will do a much better job than my off-the-cuff DCG crap.

首先,为了方便起见,我想将您的例句粘贴到代码中,这样我就不必不断重新输入:

First for my convenience I wanted to stick your example sentence into the code so I don't have to keep retyping it:

sent("(S (NP (NNP John))
         (VP (VBP see)
             (NP (NNP Mary))))").

现在一些辅助 DCG 规则:

Now some helper DCG rules:

whitespace --> [X], { char_type(X, white) ; char_type(X, space) }, whitespace.
whitespace --> [].

char(C) --> [C], { char_type(C, graph), \+ memberchk(C, "()") }.

我需要 memberchk 以确保我不会将括号放入原子中.

I need the memberchk in there to ensure that I don't put parenthesis into atoms.

chars([C|Rest]) --> char(C), chars(Rest).
chars([C]) --> char(C).

term(T) --> chars(C), { atom_chars(T, C) }.
term(L) --> list(L).

list(T) --> "(", terms(T), ")".

terms([]) --> [].
terms([T|Terms]) --> term(T), whitespace, !, terms(Terms).

term 和 list 之间存在相互递归,但这正是我们想要的,因为我们希望列表能够嵌套出现在任何地方.让我们测试一下解析:

There's mutual recursion between term and list, but this is what we want, because we want a list to be able to appear nested anywhere. Let's test the parsing:

?- sent(X), phrase(list(Y), X).
X = [40, 83, 32, 40, 78, 80, 32, 40, 78|...],
Y = ['S', ['NP', ['NNP', 'John']], ['VP', ['VBP', see], ['NP', ['NNP'|...]]]] ;

目前看起来不错.模式匹配看起来与@CapelliC 的非常相似:

This looks good so far. The pattern matching looks very similar to @CapelliC's:

simplify(['S', ['NP', ['NNP', Subject]], 
               ['VP', ['VBP', Verb], 
                      ['NP', ['NNP', Object]]]], 
         Result) :-
    Result =.. [Verb, Subject, Object].

不幸的是,使用大写的原子会模糊这里的意图,这实际上很自然.如果我们可以使用小写字母,则模式看起来更像这样:

Unfortunately, using capitalized atoms is obscuring the intent here, which is actually quite natural. If we could use lowercase letters the pattern would look more like this:

simplify([s, [np, [nnp, Subject]], 
             [vp, [vbp, Verb], 
                  [np, [nnp, Object]]]], 
         Result) :-
    Result =.. [Verb, Subject, Object].

我们在这里使用强大的univ"运算符 (=..) 从列表中生成 Prolog 术语.您可以将这个运算符视为 Lisp 翻译器,因为它本质上就是这样做的:

We're using the powerful "univ" operator here (=..) to generate a Prolog term from a list. You can think of this operator as the Lisp translator, because that's essentially what it does:

?- s(this, that) =.. X.
X = [s, this, that].

?- X =.. [s, this, that].
X = s(this, that).

所以应该清楚模式匹配是如何工作的.让我们看看整个事情是如何组合在一起的:

So it should be clear how the pattern matching works. Let's see how the whole thing fits together:

?- sent(X), phrase(list(Y), X), simplify(Y, Z).
X = [40, 83, 32, 40, 78, 80, 32, 40, 78|...],
Y = ['S', ['NP', ['NNP', 'John']], ['VP', ['VBP', see], ['NP', ['NNP'|...]]]],
Z = see('John', 'Mary') .

就其价值而言,将自然语言句子翻译成逻辑命题是一个大问题.通常不会这么容易,但有些书讨论了如何解决这个问题.我建议查看自然语言的表示和推理,了解有关这个大问题的更多信息.

For what it's worth, translating natural language sentences into logical propositions is a big question. It won't usually be this easy, but there are books that discuss how to approach the problem. I'd suggest checking out Representation and Inference for Natural Language for more information on this large problem.

所以你有它.像这样手工完成的好处是你可以控制你想要采用的 Lisp 语法中的确切内容,并且很容易扩展或修改.缺点是你必须调试语法——我很确定这个语法有问题,我没有注意到或花时间去发现(我远不是 DCG 专家!).如果没有更好的要求,我肯定会接受@CapelliC 的回答,但我认为了解如何从头开始处理这可能会有所帮助.

So there you have it. The advantage to doing it by hand like this is that you can control what exactly from Lisp's grammar you want to take, and it's easy to extend or modify. The downside is that you will have to debug the grammar—and I'm quite sure there are problems with this one I didn't notice or take time to find (I am far from a DCG expert!). Absent better requirements I would definitely take @CapelliC's answer, but I thought it might be helpful to see how this could be approached from scratch.

这篇关于如何使用 prolog 用逻辑语言翻译句子?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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