2015-07-05 35 views
4

我試了幾天,寫了一個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這個詞不是真正的邏輯謂詞。它將用於我程序的下一步(當它將此公式轉換爲另一種表示形式時)。

但是,我有很多困難來寫關於佔有關係的規則。我想,該規則接受像「無限」遞歸:

  • 打開廚房的燈(光屬於廚房在我的數據庫)
  • 打開的廚房的光屋(廚房屬於房子在我的數據庫)
  • 打開的[...](等)的房子廚房的光

我成功的第一句話轉換但不其他。在這裏我的語法(我爲更好地理解翻譯法文英文):

% start SV 

SV[SEM=<?v(?sn)>] -> V[SEM=?v] SN[SEM=?sn] 

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

N[SEM=<?adj(?n)>] -> ADJ[SEM=?adj] N[SEM=?n] 

V[SEM=<\P.P(\x.turn_on(x))>] -> 'turn' 'on' 

N[SEM=<\x.light(x)>] -> 'light' 
N[SEM=<\x.kitchen(x)>] -> 'kitchen' 
N[SEM=<\x.house(x)>] -> 'house' 

ADJ[SEM=<\P x.(P(x) & big(x))>] -> 'big' 
ADJ[SEM=<\P x.(P(x) & green(x))>] -> 'green' 

AD[SEM=<\P Q.exists x.(P(x) & Q(x))>]   -> 'the' 
AP[SEM=<\P Q R.Q(\x.P(\y.(in(y,x) & R(y))))>] -> 'of' 

有了這個語法和,我得到的命令「在廚房的燈轉」:

exists x.(kitchen(x) & exists z1.(light(z1) & in(z1,x) & turn_on(z1))) 

但是,該訂單「的房子的廚房的光轉向」:

exists x.(house(x) & exists z5.(kitchen(z5) & exists z2.(light(z2) & in(z2,z5) & in(z2,x) & turn_on(z2)))) 

更可讀的,相同的公式沒有「存在」:

(house(x4) & kitchen(x6) & light(x7) & in(x7,x6) & in(x7,x4) & turn_on(x7)) 

「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') 

非常感謝和抱歉,我的英語水平。

+0

我不不知道是什麼樣的語法,以及(控制的)NL文本是如何解析的,但是也許你可以定義某種運算符的優先級來解釋「of」 - 它應該比右邊更強,而不是左邊例。 – lenz

+0

我正在使用'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)&turn_on(x6))''。在這種情況下,「in」謂詞是正確的,但'turn_on'應用於房子=/ – Julien

+0

應該有幾種基於語法的解釋,你會看到其中一種解釋。您能否顯示能夠產生文本邏輯解釋的Python代碼? – Mehdi

回答

1

很難說存在量詞是命令句的邏輯形式。但是,你的問題在於另一個問題。

看起來你有一個模棱兩可的語法。特別是當你與in(x, y)功能intrepret的x of y,可以想象到有類似的模糊性,如第二句話:

在家裏廚房的燈。

孩子在院子裏的球。

  1. 在院子裏的球。
  2. 院子裏的孩子。

你根據你的代碼的語法產生兩種解釋爲所需的句子:

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.(kitchen(z3) & in(z3,x) ...是你想要確切的事情。

UPDATE:

讓我們儘量避免在x of y of 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] 
+0

是的,我知道存在量詞不是命令式句子的最佳表示。也許我應該只使用一個沒有量詞的簡單變量?那麼,你知道是否有可能爲這種用途寫出明確的語法?再次感謝:D! – Julien

+0

這是一個挑戰。我會在找到答案後嘗試用你的答案更新這篇文章。 – Mehdi

+0

我不知道這個語法。這是完美的!非常感謝Mehdi:D! – Julien