Logic 将自然语言转换为逻辑公式

Logic 将自然语言转换为逻辑公式,logic,nlp,nltk,lambda-calculus,Logic,Nlp,Nltk,Lambda Calculus,我花了好几天的时间写NLTK语法,把简单的法语句子转换成逻辑公式。我的问题可能与英语句子相似。我的目标是该语法接受多个命令(家庭自动化),并将它们转换为逻辑公式。订单的一些示例: 打开灯: exists x.(turn_on(x) & light(x)) 打开绿灯: exists x.(turn_on(x) & light(x) & green(x)) 打开厨房的灯 exists x.(turn_on(x) & light(x) & exists y.

我花了好几天的时间写NLTK语法,把简单的法语句子转换成逻辑公式。我的问题可能与英语句子相似。我的目标是该语法接受多个命令(家庭自动化),并将它们转换为逻辑公式。订单的一些示例:

打开灯:

exists x.(turn_on(x) & light(x))
打开绿灯:

exists x.(turn_on(x) & light(x) & green(x))
打开厨房的灯

exists x.(turn_on(x) & light(x) & exists y.(kitchen(y) & in(x, y)))
在这些示例中,单词turn_on实际上不是一个逻辑谓词。它将在我的程序的下一步中使用(当它将此公式转换为另一个表示形式时)

然而,我很难写出关于占有关系的规则。我希望规则接受“无限”递归,如:

  • 打开厨房的灯(灯属于我数据库中的厨房)
  • 打开房子厨房的灯(厨房属于我数据库中的房子)
  • 打开[…]家厨房的灯(等)
我成功地转换了第一句话,但没有转换其他句子。这里是我的语法(为了更好地理解,我将法语翻译成英语):

但是,对于“打开房子厨房的灯”的命令:

为了更具可读性,相同的公式没有“exists”:

“in”谓词有一个问题。事实上,我希望灯在厨房里,厨房在房子里。然而,在这种情况下,灯在厨房和房子里(是的,这是真的,但我不希望那样=/)。以下是我想要的:

(house(x4) & kitchen(x6) & light(x7) & in(x7,x6) & in(x6,x4) & turn_on(x7))
                                   the difference -----^
我尝试了几种方法,但都不管用。。。你能帮我吗?我不知道我的语法是否可行。我在逻辑和lambda计算方面的知识有限,我对这些话题才刚刚开始感兴趣

编辑: 以下是我用于测试的python代码:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import nltk

def exec(parser, query):
    try:
        trees = list(parser.parse(query.split()))
    except ValueError:
        print('Invalid query')
        return
    if len(trees) == 0:
        print('Invalid query')
        return
    print('query: %s' % query)
    print('results:')
    for t in trees:
        sem = t.label()['SEM']
        print('\t%s' % sem)
    print('')

if __name__ == '__main__':
    parser = nltk.load_parser('./en_grammar.fcfg')
    exec(parser, 'turn on the light')
    exec(parser, 'turn on the light of the kitchen')
    exec(parser, 'turn on the light of the kitchen of the house')

非常感谢,也很抱歉我的英语。很难说存在量词是祈使句的逻辑形式。然而,你的问题在于另一个问题

你的语法似乎模棱两可。特别是当您在(x,y)函数中使用
勇敢地表示y的
x
时,可以想象到与第二个短语类似的歧义:

屋子里厨房的灯光

院子里孩子的球

  • 院子里的球
  • 在院子里的那个孩子
  • 基于代码的语法为所需句子生成以下两种解释:

    query: turn on the light of the kitchen of the house
    results:
        exists x.(house(x) & exists z5.(kitchen(z5) & exists z2.(light(z2) & in(z2,z5) & in(z2,x) & turn_on(z2))))
        exists x.(house(x) & exists z3.(kitchen(z3) & in(z3,x) & exists z6.(light(z6) & in(z6,z3) & turn_on(z6))))
    
    在第二种解释中:
    house(x)&exists z3.(厨房(z3)&In(z3,x)…
    正是你们想要的东西

    更新:

    让我们尽量避免
    x/y/z
    链中的歧义

    强制
    x of(y of z)
    而不是
    (x of y)of z
    的一个非常快速的解决方案是跟踪
    of
    在所有名词短语中的用法,然后强制它在
    of
    的左侧没有
    of

    SN[SEM=<?ap(?sn1, ?sn2)>, +OF] -> SN[SEM=?sn1, -OF] AP[SEM=?ap] SN[SEM=?sn2]
    SN[SEM=<?ad(?n)>, -OF]         -> AD[SEM=?ad] N[SEM=?n]
    SN[SEM=?n, -OF]                -> N[SEM=?n]
    

    SN[SEM=我不知道这是哪种语法,也不知道(受控)NL文本是如何解析的,但也许您可以定义某种运算符优先级来解释“of”–在你的例子中,它应该绑定到右边,而不是左边。我正在使用
    nltk.parse.featurechart.FeatureChartParser
    来使用这个语法。如果我将NP规则的SEM改为
    ?ap(?sn2,sn1)
    ,而ap规则的
    in(y,x)
    改为
    in(x,y)
    ,我得到这个:
    (光(x4)和厨房(x7)&in(x4,x7)&house(x6)&in(x7,x6)&打开(x6)
    。在这种情况下,“in”谓词是正确的,但是
    turn\u on
    应用于房子=/根据你的语法应该有几种解释,你正在看到其中一种解释。请你展示一下产生文本逻辑解释的python代码好吗?我不理解这个定律:
    SN[SEM=?n]>n[SEM=?n]
    。你需要一个没有定冠词的名词短语吗?在你发表评论之前,我只显示了第一棵树。我修改了我的程序来显示所有的树,事实上,你是对的!第二种解释给出了
    (house(x)&kitchen(z3)&in(z3,x)&light(z6)&in(z6,z3)&开启(z6))
    。我编辑了我的问题,添加了我的脚本的新版本。你知道我如何修改我的语法,使其只有一种解释吗?对于你不理解的规则,它在这个语法中是无用的,但我的法语语法有更多的规则,而这个规则是有用的。非常感谢Medhi。是的,我知道存在量词不是他是祈使句的最佳表达方式。也许我应该只使用一个没有量词的简单变量?那么,你知道是否有可能为这个用法编写一个明确的语法吗?再次感谢:D!这是一个挑战。在找到答案后,我会尝试用你的答案更新这篇文章。我不知道这个语法。太完美了!谢谢很多我的朋友!
    (house(x4) & kitchen(x6) & light(x7) & in(x7,x6) & in(x6,x4) & turn_on(x7))
                                       the difference -----^
    
    #!/usr/bin/env python3
    # -*- coding: utf-8 -*-
    
    import nltk
    
    def exec(parser, query):
        try:
            trees = list(parser.parse(query.split()))
        except ValueError:
            print('Invalid query')
            return
        if len(trees) == 0:
            print('Invalid query')
            return
        print('query: %s' % query)
        print('results:')
        for t in trees:
            sem = t.label()['SEM']
            print('\t%s' % sem)
        print('')
    
    if __name__ == '__main__':
        parser = nltk.load_parser('./en_grammar.fcfg')
        exec(parser, 'turn on the light')
        exec(parser, 'turn on the light of the kitchen')
        exec(parser, 'turn on the light of the kitchen of the house')
    
    query: turn on the light of the kitchen of the house
    results:
        exists x.(house(x) & exists z5.(kitchen(z5) & exists z2.(light(z2) & in(z2,z5) & in(z2,x) & turn_on(z2))))
        exists x.(house(x) & exists z3.(kitchen(z3) & in(z3,x) & exists z6.(light(z6) & in(z6,z3) & turn_on(z6))))
    
    SN[SEM=<?ap(?sn1, ?sn2)>, +OF] -> SN[SEM=?sn1, -OF] AP[SEM=?ap] SN[SEM=?sn2]
    SN[SEM=<?ad(?n)>, -OF]         -> AD[SEM=?ad] N[SEM=?n]
    SN[SEM=?n, -OF]                -> N[SEM=?n]