2016-11-01 6 views
3

Natural Language ToolKit(NLTK)の使用に疑問があります。自然言語の質問をロジック表現に変換し、データベースにクエリするためにアプリケーションを作成しようとしています。NLTKを使用した論理式の簡略化

私はnltk.sem.logicパッケージの下の簡素化()メソッドを使用した後に得て、次の式だ結果:

exists z2.(owner(fido, z2) & (z0 = z2)) 

をしかし、私は必要なのフォローとして、それを簡単にすることである。

owner(fido, z0) 

文章を減らす方法がありますか?

+2

があることに注意して取得おもちゃの文の表現は、無制限の自然言語の入力で同じことをすることから、非常に**非常に**長い道のりです。現実的な成功のチャンスを得るには、実際のセマンティック分析なしに浅いアプローチに切り替えます。 – alexis

+0

私はやっている練習です。入力は、英語の非常に限られたサブセットに制限されています。私は小さなフィーチャベースの文法を構築し、ラムダ式を使って論理式(単純化したもの)を得るが、それをさらに単純化する必要がある。犬の名前とその所有者のデータベースがあります。論理式をデータベースに接続して答えを得ようとしています。 私は今、いくつかの問題を抱えています。私はそれを達成することができる本またはリンクがあるかどうか知っていますか? ありがとう! – Cas1337

+0

それはもっと意味があります... "英語の限定されたサブセット"(a.k.a. "フラグメント")は、 "自然言語の質問"とはまったく異なる問題です!キャリーオン。私はProver9のドキュメントを勉強するよう助言することができます。正式なセマンティクスを紹介することもできます。 – alexis

答えて

4

NLTKでは、simplify()は、必要なものではないベータ還元(according to the book)を実行します。あなたが何を求めているのかは、あなたが特定の戦術を適用するときに定理証明者だけが行うことができます。この場合、最終的に得られると予想されることを知る必要がありますか、そのような結果を得るためにどのような公理を適用できるかを知っています。

NLTKの定理証明はProver9であり、同値関係をチェックするツールを提供します。基本的には、式(敷地)のリストから目標式までのステップ数が限られた校正があるかどうかだけを確認することができます。 NLTKのpythonで

============================== PROOF ================================= 

% -------- Comments from original proof -------- 
% Proof 1 at 0.00 (+ 0.00) seconds. 
% Length of proof is 8. 
% Level of proof is 4. 
% Maximum clause weight is 4. 
% Given clauses 0. 

1 (exists x (owner(fido,x) & y = x)) # label(non_clause). [assumption]. 
2 owner(fido,x) # label(non_clause) # label(goal). [goal]. 
3 owner(fido,f1(x)). [clausify(1)]. 
4 x = f1(x). [clausify(1)]. 
5 f1(x) = x. [copy(4),flip(a)]. 
6 -owner(fido,c1). [deny(2)]. 
7 owner(fido,x). [back_rewrite(3),rewrite([5(2)])]. 
8 $F. [resolve(7,a,6,a)]. 

============================== end of proof ========================== 

あなたがpythonで利用可能なツールを使用して主張して、必要な場合には
from nltk import Prover9 
from nltk.sem import Expression 
read_expr = Expression.fromstring 
p1 = read_expr('exists z2.(owner(fido, z2) & (z0 = z2))') 
c = read_expr('owner(fido, z0)') 
result = Prover9().prove(c, [p1]) 
print(result) 
# returns True 

UPDATE

例えばあなたのケースでは、これは結果でしたこの特定のパターンを正規表現で手動でチェックします。おそらく、正規表現を使用してこのような何かを行うことができます(私が承認したがのが私の厄介な戦術を試してみましょうしないでください):

def my_nasty_tactic(exp): 
    parameter = re.findall(r'exists ([^.]*)\..*', exp) 
    if len(parameter) == 1: 
     parameter = parameter[0] 
     substitution = re.findall(r'&[ ]*\([ ]*([^ ]+)[ ]*=[ ]*'+parameter+r'[ ]*\)', exp) 
     if len(substitution) == 1: 
      substitution = substitution[0] 
      exp_abs = re.sub(r'exists(?= [^.]*\..*)', "\ ", exp) 
      exp_abs = re.sub(r'&[ ]*\([ ]*' + substitution + '[ ]*=[ ]*'+parameter+r'[ ]*\)', '', exp_abs) 
      return read_expr('(%s)(%s)' % (exp_abs, substitution)).simplify() 

その後、あなたはこのようにそれを使用することができます:

my_nasty_tactic('exists z2.(owner(fido, z2) & (z0 = z2))') 
# <ApplicationExpression owner(fido,z0)> 
+0

証明が真であるので、私は正規表現で希望の結果を得ることができました。 「存在する」という表現はすべて似ています。番号付きの変数で表現し、最後にz0変数との等価性があります。 – Cas1337

+0

「望みの結果を得る」という言い方は正確には分かりませんが、正規表現と定理証明は一緒に行かないのです。あなたはリンゴと高層ビルを混ぜています! – alexis

+0

私が言っていることは、所望の式を得るためには、正規表現を使って "owner(fido、z2)"部分を得ることができ、z2をz0に置き換え、式I欲しかった – Cas1337

関連する問題