2016-11-01 8 views
3

자연 언어 도구 키트 (NLTK) 사용에 의구심이 있습니다. 자연 언어 질문을 논리 표현으로 번역하고 데이터베이스에 쿼리하기 위해 앱을 만들려고합니다.NLTK를 사용하여 논리 표현식을 단순화하십시오.

내가 nltk.sem.logic 패키지 아래의 단순화() 메소드를 사용 후 가지고 다음과 같은 식있어 그 결과

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

을하지만 내가 필요로하는 것은 다음과 같이 그것을 단순화하는 것입니다

owner(fido, z0) 

문장을 줄일 수있는 또 다른 방법이 있습니까?

+2

는 것을주의 할 점점 장난감 문장의 표현은 무제한의 자연어 입력으로 동일한 작업을 수행하는 매우 긴 방법입니다. 현실적으로 성공할 수있는 기회를 얻으려면 실제 의미 론적 분석없이 얕은 접근 방식으로 전환하십시오. – alexis

+0

내가하는 연습 일뿐입니다. 입력은 영어의 매우 제한된 부분 집합으로 제한됩니다. 작은 기능 기반의 문법을 작성하고 람다 표현식을 사용하여 논리 표현식 (간단히 말하면 표현식)을 얻지 만 훨씬 단순화시켜야합니다. 개 이름과 그의 소유자가있는 데이터베이스가 있는데, 논리적 표현을 데이터베이스에 연결하여 답을 얻으려고합니다. 지금 당장 문제가 있습니다. 책이나 링크가 있다면 어떨까요? 감사합니다. – Cas1337

+0

더 의미가 있습니다 ... "제한된 영어"("단편")은 "자연어 질문"과 매우 다른 문제입니다! 계속해라. Prover9 문서를 연구하고 공식 의미론을 소개 할 것을 조언 할 수 있습니다 (아직 익숙하지 않은 경우). – alexis

답변

4

NLTK에서 simplify()은 필요한 것이 아닌 베타 감소 (according to the book)를 수행합니다. 당신이 요구하는 것은 특정 전술을 적용 할 때 정리 해설자들만이 할 수 있습니다. 이 경우 어느 쪽이든 끝에 도달 할 것으로 예상되는 것을 알 필요가 있거나 그런 결과를 얻기 위해 어떤 종류의 공리가 적용될 수 있는지 알고 있어야합니다.

NLTK의 정리 증명자는 Prover9이며 함의 관계를 검사하는 도구를 제공합니다. 기본적으로 표현식 목록 (구내)에서 목표 표현식까지 제한된 수의 단계가있는 증거 만 있는지 확인할 수 있습니다. 예를 들어, 귀하의 경우에는,이 결과였다 : NLTK 파이썬에서

============================== 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 ========================== 

:

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

당신이 파이썬에서 사용할 수있는 도구를 사용하여 주장하는 경우

하고 당신이 원하는 정규 표현식으로이 특정 패턴을 수동으로 확인하십시오. 당신은 아마 정규 표현식과 같은 것을 할 수 있습니다 (I 승인 만의 내 더러운 전술을 시도하지 않음) :

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

제가 말하고자하는 바는 원하는 표현식을 얻기 위해서 전체 표현식에서 "소유자 (fido, z2)"부분을 얻고, RegEx를 사용하고, z2를 z0으로 대체하고, 표현식 I 원했어. – Cas1337

관련 문제