| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098 |
- .. Copyright (C) 2001-2020 NLTK Project
- .. For license information, see LICENSE.TXT
- =======================
- Logic & Lambda Calculus
- =======================
- The `nltk.logic` package allows expressions of First-Order Logic (FOL) to be
- parsed into ``Expression`` objects. In addition to FOL, the parser
- handles lambda-abstraction with variables of higher order.
- --------
- Overview
- --------
- >>> from nltk.sem.logic import *
- The default inventory of logical constants is the following:
- >>> boolean_ops() # doctest: +NORMALIZE_WHITESPACE
- negation -
- conjunction &
- disjunction |
- implication ->
- equivalence <->
- >>> equality_preds() # doctest: +NORMALIZE_WHITESPACE
- equality =
- inequality !=
- >>> binding_ops() # doctest: +NORMALIZE_WHITESPACE
- existential exists
- universal all
- lambda \
- ----------------
- Regression Tests
- ----------------
- Untyped Logic
- +++++++++++++
- Process logical expressions conveniently:
- >>> read_expr = Expression.fromstring
- Test for equality under alpha-conversion
- ========================================
- >>> e1 = read_expr('exists x.P(x)')
- >>> print(e1)
- exists x.P(x)
- >>> e2 = e1.alpha_convert(Variable('z'))
- >>> print(e2)
- exists z.P(z)
- >>> e1 == e2
- True
- >>> l = read_expr(r'\X.\X.X(X)(1)').simplify()
- >>> id = read_expr(r'\X.X(X)')
- >>> l == id
- True
- Test numerals
- =============
- >>> zero = read_expr(r'\F x.x')
- >>> one = read_expr(r'\F x.F(x)')
- >>> two = read_expr(r'\F x.F(F(x))')
- >>> three = read_expr(r'\F x.F(F(F(x)))')
- >>> four = read_expr(r'\F x.F(F(F(F(x))))')
- >>> succ = read_expr(r'\N F x.F(N(F,x))')
- >>> plus = read_expr(r'\M N F x.M(F,N(F,x))')
- >>> mult = read_expr(r'\M N F.M(N(F))')
- >>> pred = read_expr(r'\N F x.(N(\G H.H(G(F)))(\u.x)(\u.u))')
- >>> v1 = ApplicationExpression(succ, zero).simplify()
- >>> v1 == one
- True
- >>> v2 = ApplicationExpression(succ, v1).simplify()
- >>> v2 == two
- True
- >>> v3 = ApplicationExpression(ApplicationExpression(plus, v1), v2).simplify()
- >>> v3 == three
- True
- >>> v4 = ApplicationExpression(ApplicationExpression(mult, v2), v2).simplify()
- >>> v4 == four
- True
- >>> v5 = ApplicationExpression(pred, ApplicationExpression(pred, v4)).simplify()
- >>> v5 == two
- True
- Overloaded operators also exist, for convenience.
- >>> print(succ(zero).simplify() == one)
- True
- >>> print(plus(one,two).simplify() == three)
- True
- >>> print(mult(two,two).simplify() == four)
- True
- >>> print(pred(pred(four)).simplify() == two)
- True
- >>> john = read_expr(r'john')
- >>> man = read_expr(r'\x.man(x)')
- >>> walk = read_expr(r'\x.walk(x)')
- >>> man(john).simplify()
- <ApplicationExpression man(john)>
- >>> print(-walk(john).simplify())
- -walk(john)
- >>> print((man(john) & walk(john)).simplify())
- (man(john) & walk(john))
- >>> print((man(john) | walk(john)).simplify())
- (man(john) | walk(john))
- >>> print((man(john) > walk(john)).simplify())
- (man(john) -> walk(john))
- >>> print((man(john) < walk(john)).simplify())
- (man(john) <-> walk(john))
- Python's built-in lambda operator can also be used with Expressions
- >>> john = VariableExpression(Variable('john'))
- >>> run_var = VariableExpression(Variable('run'))
- >>> run = lambda x: run_var(x)
- >>> run(john)
- <ApplicationExpression run(john)>
- ``betaConversionTestSuite.pl``
- ------------------------------
- Tests based on Blackburn & Bos' book, *Representation and Inference
- for Natural Language*.
- >>> x1 = read_expr(r'\P.P(mia)(\x.walk(x))').simplify()
- >>> x2 = read_expr(r'walk(mia)').simplify()
- >>> x1 == x2
- True
- >>> x1 = read_expr(r'exists x.(man(x) & ((\P.exists x.(woman(x) & P(x)))(\y.love(x,y))))').simplify()
- >>> x2 = read_expr(r'exists x.(man(x) & exists y.(woman(y) & love(x,y)))').simplify()
- >>> x1 == x2
- True
- >>> x1 = read_expr(r'\a.sleep(a)(mia)').simplify()
- >>> x2 = read_expr(r'sleep(mia)').simplify()
- >>> x1 == x2
- True
- >>> x1 = read_expr(r'\a.\b.like(b,a)(mia)').simplify()
- >>> x2 = read_expr(r'\b.like(b,mia)').simplify()
- >>> x1 == x2
- True
- >>> x1 = read_expr(r'\a.(\b.like(b,a)(vincent))').simplify()
- >>> x2 = read_expr(r'\a.like(vincent,a)').simplify()
- >>> x1 == x2
- True
- >>> x1 = read_expr(r'\a.((\b.like(b,a)(vincent)) & sleep(a))').simplify()
- >>> x2 = read_expr(r'\a.(like(vincent,a) & sleep(a))').simplify()
- >>> x1 == x2
- True
- >>> x1 = read_expr(r'(\a.\b.like(b,a)(mia)(vincent))').simplify()
- >>> x2 = read_expr(r'like(vincent,mia)').simplify()
- >>> x1 == x2
- True
- >>> x1 = read_expr(r'P((\a.sleep(a)(vincent)))').simplify()
- >>> x2 = read_expr(r'P(sleep(vincent))').simplify()
- >>> x1 == x2
- True
- >>> x1 = read_expr(r'\A.A((\b.sleep(b)(vincent)))').simplify()
- >>> x2 = read_expr(r'\A.A(sleep(vincent))').simplify()
- >>> x1 == x2
- True
- >>> x1 = read_expr(r'\A.A(sleep(vincent))').simplify()
- >>> x2 = read_expr(r'\A.A(sleep(vincent))').simplify()
- >>> x1 == x2
- True
- >>> x1 = read_expr(r'(\A.A(vincent)(\b.sleep(b)))').simplify()
- >>> x2 = read_expr(r'sleep(vincent)').simplify()
- >>> x1 == x2
- True
- >>> x1 = read_expr(r'\A.believe(mia,A(vincent))(\b.sleep(b))').simplify()
- >>> x2 = read_expr(r'believe(mia,sleep(vincent))').simplify()
- >>> x1 == x2
- True
- >>> x1 = read_expr(r'(\A.(A(vincent) & A(mia)))(\b.sleep(b))').simplify()
- >>> x2 = read_expr(r'(sleep(vincent) & sleep(mia))').simplify()
- >>> x1 == x2
- True
- >>> x1 = read_expr(r'\A.\B.(\C.C(A(vincent))(\d.probably(d)) & (\C.C(B(mia))(\d.improbably(d))))(\f.walk(f))(\f.talk(f))').simplify()
- >>> x2 = read_expr(r'(probably(walk(vincent)) & improbably(talk(mia)))').simplify()
- >>> x1 == x2
- True
- >>> x1 = read_expr(r'(\a.\b.(\C.C(a,b)(\d.\f.love(d,f))))(jules)(mia)').simplify()
- >>> x2 = read_expr(r'love(jules,mia)').simplify()
- >>> x1 == x2
- True
- >>> x1 = read_expr(r'(\A.\B.exists c.(A(c) & B(c)))(\d.boxer(d),\d.sleep(d))').simplify()
- >>> x2 = read_expr(r'exists c.(boxer(c) & sleep(c))').simplify()
- >>> x1 == x2
- True
- >>> x1 = read_expr(r'\A.Z(A)(\c.\a.like(a,c))').simplify()
- >>> x2 = read_expr(r'Z(\c.\a.like(a,c))').simplify()
- >>> x1 == x2
- True
- >>> x1 = read_expr(r'\A.\b.A(b)(\c.\b.like(b,c))').simplify()
- >>> x2 = read_expr(r'\b.(\c.\b.like(b,c)(b))').simplify()
- >>> x1 == x2
- True
- >>> x1 = read_expr(r'(\a.\b.(\C.C(a,b)(\b.\a.loves(b,a))))(jules)(mia)').simplify()
- >>> x2 = read_expr(r'loves(jules,mia)').simplify()
- >>> x1 == x2
- True
- >>> x1 = read_expr(r'(\A.\b.(exists b.A(b) & A(b)))(\c.boxer(c))(vincent)').simplify()
- >>> x2 = read_expr(r'((exists b.boxer(b)) & boxer(vincent))').simplify()
- >>> x1 == x2
- True
- Test Parser
- ===========
- >>> print(read_expr(r'john'))
- john
- >>> print(read_expr(r'x'))
- x
- >>> print(read_expr(r'-man(x)'))
- -man(x)
- >>> print(read_expr(r'--man(x)'))
- --man(x)
- >>> print(read_expr(r'(man(x))'))
- man(x)
- >>> print(read_expr(r'((man(x)))'))
- man(x)
- >>> print(read_expr(r'man(x) <-> tall(x)'))
- (man(x) <-> tall(x))
- >>> print(read_expr(r'(man(x) <-> tall(x))'))
- (man(x) <-> tall(x))
- >>> print(read_expr(r'(man(x) & tall(x) & walks(x))'))
- (man(x) & tall(x) & walks(x))
- >>> print(read_expr(r'(man(x) & tall(x) & walks(x))').first)
- (man(x) & tall(x))
- >>> print(read_expr(r'man(x) | tall(x) & walks(x)'))
- (man(x) | (tall(x) & walks(x)))
- >>> print(read_expr(r'((man(x) & tall(x)) | walks(x))'))
- ((man(x) & tall(x)) | walks(x))
- >>> print(read_expr(r'man(x) & (tall(x) | walks(x))'))
- (man(x) & (tall(x) | walks(x)))
- >>> print(read_expr(r'(man(x) & (tall(x) | walks(x)))'))
- (man(x) & (tall(x) | walks(x)))
- >>> print(read_expr(r'P(x) -> Q(x) <-> R(x) | S(x) & T(x)'))
- ((P(x) -> Q(x)) <-> (R(x) | (S(x) & T(x))))
- >>> print(read_expr(r'exists x.man(x)'))
- exists x.man(x)
- >>> print(read_expr(r'exists x.(man(x) & tall(x))'))
- exists x.(man(x) & tall(x))
- >>> print(read_expr(r'exists x.(man(x) & tall(x) & walks(x))'))
- exists x.(man(x) & tall(x) & walks(x))
- >>> print(read_expr(r'-P(x) & Q(x)'))
- (-P(x) & Q(x))
- >>> read_expr(r'-P(x) & Q(x)') == read_expr(r'(-P(x)) & Q(x)')
- True
- >>> print(read_expr(r'\x.man(x)'))
- \x.man(x)
- >>> print(read_expr(r'\x.man(x)(john)'))
- \x.man(x)(john)
- >>> print(read_expr(r'\x.man(x)(john) & tall(x)'))
- (\x.man(x)(john) & tall(x))
- >>> print(read_expr(r'\x.\y.sees(x,y)'))
- \x y.sees(x,y)
- >>> print(read_expr(r'\x y.sees(x,y)'))
- \x y.sees(x,y)
- >>> print(read_expr(r'\x.\y.sees(x,y)(a)'))
- (\x y.sees(x,y))(a)
- >>> print(read_expr(r'\x y.sees(x,y)(a)'))
- (\x y.sees(x,y))(a)
- >>> print(read_expr(r'\x.\y.sees(x,y)(a)(b)'))
- ((\x y.sees(x,y))(a))(b)
- >>> print(read_expr(r'\x y.sees(x,y)(a)(b)'))
- ((\x y.sees(x,y))(a))(b)
- >>> print(read_expr(r'\x.\y.sees(x,y)(a,b)'))
- ((\x y.sees(x,y))(a))(b)
- >>> print(read_expr(r'\x y.sees(x,y)(a,b)'))
- ((\x y.sees(x,y))(a))(b)
- >>> print(read_expr(r'((\x.\y.sees(x,y))(a))(b)'))
- ((\x y.sees(x,y))(a))(b)
- >>> print(read_expr(r'P(x)(y)(z)'))
- P(x,y,z)
- >>> print(read_expr(r'P(Q)'))
- P(Q)
- >>> print(read_expr(r'P(Q(x))'))
- P(Q(x))
- >>> print(read_expr(r'(\x.exists y.walks(x,y))(x)'))
- (\x.exists y.walks(x,y))(x)
- >>> print(read_expr(r'exists x.(x = john)'))
- exists x.(x = john)
- >>> print(read_expr(r'((\P.\Q.exists x.(P(x) & Q(x)))(\x.dog(x)))(\x.bark(x))'))
- ((\P Q.exists x.(P(x) & Q(x)))(\x.dog(x)))(\x.bark(x))
- >>> a = read_expr(r'exists c.exists b.A(b,c) & A(b,c)')
- >>> b = read_expr(r'(exists c.(exists b.A(b,c))) & A(b,c)')
- >>> print(a == b)
- True
- >>> a = read_expr(r'exists c.(exists b.A(b,c) & A(b,c))')
- >>> b = read_expr(r'exists c.((exists b.A(b,c)) & A(b,c))')
- >>> print(a == b)
- True
- >>> print(read_expr(r'exists x.x = y'))
- exists x.(x = y)
- >>> print(read_expr('A(B)(C)'))
- A(B,C)
- >>> print(read_expr('(A(B))(C)'))
- A(B,C)
- >>> print(read_expr('A((B)(C))'))
- A(B(C))
- >>> print(read_expr('A(B(C))'))
- A(B(C))
- >>> print(read_expr('(A)(B(C))'))
- A(B(C))
- >>> print(read_expr('(((A)))(((B))(((C))))'))
- A(B(C))
- >>> print(read_expr(r'A != B'))
- -(A = B)
- >>> print(read_expr('P(x) & x=y & P(y)'))
- (P(x) & (x = y) & P(y))
- >>> try: print(read_expr(r'\walk.walk(x)'))
- ... except LogicalExpressionException as e: print(e)
- 'walk' is an illegal variable name. Constants may not be abstracted.
- \walk.walk(x)
- ^
- >>> try: print(read_expr(r'all walk.walk(john)'))
- ... except LogicalExpressionException as e: print(e)
- 'walk' is an illegal variable name. Constants may not be quantified.
- all walk.walk(john)
- ^
- >>> try: print(read_expr(r'x(john)'))
- ... except LogicalExpressionException as e: print(e)
- 'x' is an illegal predicate name. Individual variables may not be used as predicates.
- x(john)
- ^
- >>> from nltk.sem.logic import LogicParser # hack to give access to custom quote chars
- >>> lpq = LogicParser()
- >>> lpq.quote_chars = [("'", "'", "\\", False)]
- >>> print(lpq.parse(r"(man(x) & 'tall\'s,' (x) & walks (x) )"))
- (man(x) & tall's,(x) & walks(x))
- >>> lpq.quote_chars = [("'", "'", "\\", True)]
- >>> print(lpq.parse(r"'tall\'s,'"))
- 'tall\'s,'
- >>> print(lpq.parse(r"'spaced name(x)'"))
- 'spaced name(x)'
- >>> print(lpq.parse(r"-'tall\'s,'(x)"))
- -'tall\'s,'(x)
- >>> print(lpq.parse(r"(man(x) & 'tall\'s,' (x) & walks (x) )"))
- (man(x) & 'tall\'s,'(x) & walks(x))
- Simplify
- ========
- >>> print(read_expr(r'\x.man(x)(john)').simplify())
- man(john)
- >>> print(read_expr(r'\x.((man(x)))(john)').simplify())
- man(john)
- >>> print(read_expr(r'\x.\y.sees(x,y)(john, mary)').simplify())
- sees(john,mary)
- >>> print(read_expr(r'\x y.sees(x,y)(john, mary)').simplify())
- sees(john,mary)
- >>> print(read_expr(r'\x.\y.sees(x,y)(john)(mary)').simplify())
- sees(john,mary)
- >>> print(read_expr(r'\x y.sees(x,y)(john)(mary)').simplify())
- sees(john,mary)
- >>> print(read_expr(r'\x.\y.sees(x,y)(john)').simplify())
- \y.sees(john,y)
- >>> print(read_expr(r'\x y.sees(x,y)(john)').simplify())
- \y.sees(john,y)
- >>> print(read_expr(r'(\x.\y.sees(x,y)(john))(mary)').simplify())
- sees(john,mary)
- >>> print(read_expr(r'(\x y.sees(x,y)(john))(mary)').simplify())
- sees(john,mary)
- >>> print(read_expr(r'exists x.(man(x) & (\x.exists y.walks(x,y))(x))').simplify())
- exists x.(man(x) & exists y.walks(x,y))
- >>> e1 = read_expr(r'exists x.(man(x) & (\x.exists y.walks(x,y))(y))').simplify()
- >>> e2 = read_expr(r'exists x.(man(x) & exists z1.walks(y,z1))')
- >>> e1 == e2
- True
- >>> print(read_expr(r'(\P Q.exists x.(P(x) & Q(x)))(\x.dog(x))').simplify())
- \Q.exists x.(dog(x) & Q(x))
- >>> print(read_expr(r'((\P.\Q.exists x.(P(x) & Q(x)))(\x.dog(x)))(\x.bark(x))').simplify())
- exists x.(dog(x) & bark(x))
- >>> print(read_expr(r'\P.(P(x)(y))(\a b.Q(a,b))').simplify())
- Q(x,y)
- Replace
- =======
- >>> a = read_expr(r'a')
- >>> x = read_expr(r'x')
- >>> y = read_expr(r'y')
- >>> z = read_expr(r'z')
- >>> print(read_expr(r'man(x)').replace(x.variable, a, False))
- man(a)
- >>> print(read_expr(r'(man(x) & tall(x))').replace(x.variable, a, False))
- (man(a) & tall(a))
- >>> print(read_expr(r'exists x.man(x)').replace(x.variable, a, False))
- exists x.man(x)
- >>> print(read_expr(r'exists x.man(x)').replace(x.variable, a, True))
- exists a.man(a)
- >>> print(read_expr(r'exists x.give(x,y,z)').replace(y.variable, a, False))
- exists x.give(x,a,z)
- >>> print(read_expr(r'exists x.give(x,y,z)').replace(y.variable, a, True))
- exists x.give(x,a,z)
- >>> e1 = read_expr(r'exists x.give(x,y,z)').replace(y.variable, x, False)
- >>> e2 = read_expr(r'exists z1.give(z1,x,z)')
- >>> e1 == e2
- True
- >>> e1 = read_expr(r'exists x.give(x,y,z)').replace(y.variable, x, True)
- >>> e2 = read_expr(r'exists z1.give(z1,x,z)')
- >>> e1 == e2
- True
- >>> print(read_expr(r'\x y z.give(x,y,z)').replace(y.variable, a, False))
- \x y z.give(x,y,z)
- >>> print(read_expr(r'\x y z.give(x,y,z)').replace(y.variable, a, True))
- \x a z.give(x,a,z)
- >>> print(read_expr(r'\x.\y.give(x,y,z)').replace(z.variable, a, False))
- \x y.give(x,y,a)
- >>> print(read_expr(r'\x.\y.give(x,y,z)').replace(z.variable, a, True))
- \x y.give(x,y,a)
- >>> e1 = read_expr(r'\x.\y.give(x,y,z)').replace(z.variable, x, False)
- >>> e2 = read_expr(r'\z1.\y.give(z1,y,x)')
- >>> e1 == e2
- True
- >>> e1 = read_expr(r'\x.\y.give(x,y,z)').replace(z.variable, x, True)
- >>> e2 = read_expr(r'\z1.\y.give(z1,y,x)')
- >>> e1 == e2
- True
- >>> print(read_expr(r'\x.give(x,y,z)').replace(z.variable, y, False))
- \x.give(x,y,y)
- >>> print(read_expr(r'\x.give(x,y,z)').replace(z.variable, y, True))
- \x.give(x,y,y)
- >>> from nltk.sem import logic
- >>> logic._counter._value = 0
- >>> e1 = read_expr('e1')
- >>> e2 = read_expr('e2')
- >>> print(read_expr('exists e1 e2.(walk(e1) & talk(e2))').replace(e1.variable, e2, True))
- exists e2 e01.(walk(e2) & talk(e01))
- Variables / Free
- ================
- >>> examples = [r'walk(john)',
- ... r'walk(x)',
- ... r'?vp(?np)',
- ... r'see(john,mary)',
- ... r'exists x.walk(x)',
- ... r'\x.see(john,x)',
- ... r'\x.see(john,x)(mary)',
- ... r'P(x)',
- ... r'\P.P(x)',
- ... r'aa(x,bb(y),cc(z),P(w),u)',
- ... r'bo(?det(?n),@x)']
- >>> examples = [read_expr(e) for e in examples]
- >>> for e in examples:
- ... print('%-25s' % e, sorted(e.free()))
- walk(john) []
- walk(x) [Variable('x')]
- ?vp(?np) []
- see(john,mary) []
- exists x.walk(x) []
- \x.see(john,x) []
- (\x.see(john,x))(mary) []
- P(x) [Variable('P'), Variable('x')]
- \P.P(x) [Variable('x')]
- aa(x,bb(y),cc(z),P(w),u) [Variable('P'), Variable('u'), Variable('w'), Variable('x'), Variable('y'), Variable('z')]
- bo(?det(?n),@x) []
- >>> for e in examples:
- ... print('%-25s' % e, sorted(e.constants()))
- walk(john) [Variable('john')]
- walk(x) []
- ?vp(?np) [Variable('?np')]
- see(john,mary) [Variable('john'), Variable('mary')]
- exists x.walk(x) []
- \x.see(john,x) [Variable('john')]
- (\x.see(john,x))(mary) [Variable('john'), Variable('mary')]
- P(x) []
- \P.P(x) []
- aa(x,bb(y),cc(z),P(w),u) []
- bo(?det(?n),@x) [Variable('?n'), Variable('@x')]
- >>> for e in examples:
- ... print('%-25s' % e, sorted(e.predicates()))
- walk(john) [Variable('walk')]
- walk(x) [Variable('walk')]
- ?vp(?np) [Variable('?vp')]
- see(john,mary) [Variable('see')]
- exists x.walk(x) [Variable('walk')]
- \x.see(john,x) [Variable('see')]
- (\x.see(john,x))(mary) [Variable('see')]
- P(x) []
- \P.P(x) []
- aa(x,bb(y),cc(z),P(w),u) [Variable('aa'), Variable('bb'), Variable('cc')]
- bo(?det(?n),@x) [Variable('?det'), Variable('bo')]
- >>> for e in examples:
- ... print('%-25s' % e, sorted(e.variables()))
- walk(john) []
- walk(x) [Variable('x')]
- ?vp(?np) [Variable('?np'), Variable('?vp')]
- see(john,mary) []
- exists x.walk(x) []
- \x.see(john,x) []
- (\x.see(john,x))(mary) []
- P(x) [Variable('P'), Variable('x')]
- \P.P(x) [Variable('x')]
- aa(x,bb(y),cc(z),P(w),u) [Variable('P'), Variable('u'), Variable('w'), Variable('x'), Variable('y'), Variable('z')]
- bo(?det(?n),@x) [Variable('?det'), Variable('?n'), Variable('@x')]
- `normalize`
- >>> print(read_expr(r'\e083.(walk(e083, z472) & talk(e092, z938))').normalize())
- \e01.(walk(e01,z3) & talk(e02,z4))
- Typed Logic
- +++++++++++
- >>> from nltk.sem.logic import LogicParser
- >>> tlp = LogicParser(True)
- >>> print(tlp.parse(r'man(x)').type)
- ?
- >>> print(tlp.parse(r'walk(angus)').type)
- ?
- >>> print(tlp.parse(r'-man(x)').type)
- t
- >>> print(tlp.parse(r'(man(x) <-> tall(x))').type)
- t
- >>> print(tlp.parse(r'exists x.(man(x) & tall(x))').type)
- t
- >>> print(tlp.parse(r'\x.man(x)').type)
- <e,?>
- >>> print(tlp.parse(r'john').type)
- e
- >>> print(tlp.parse(r'\x y.sees(x,y)').type)
- <e,<e,?>>
- >>> print(tlp.parse(r'\x.man(x)(john)').type)
- ?
- >>> print(tlp.parse(r'\x.\y.sees(x,y)(john)').type)
- <e,?>
- >>> print(tlp.parse(r'\x.\y.sees(x,y)(john)(mary)').type)
- ?
- >>> print(tlp.parse(r'\P.\Q.exists x.(P(x) & Q(x))').type)
- <<e,t>,<<e,t>,t>>
- >>> print(tlp.parse(r'\x.y').type)
- <?,e>
- >>> print(tlp.parse(r'\P.P(x)').type)
- <<e,?>,?>
- >>> parsed = tlp.parse('see(john,mary)')
- >>> print(parsed.type)
- ?
- >>> print(parsed.function)
- see(john)
- >>> print(parsed.function.type)
- <e,?>
- >>> print(parsed.function.function)
- see
- >>> print(parsed.function.function.type)
- <e,<e,?>>
- >>> parsed = tlp.parse('P(x,y)')
- >>> print(parsed)
- P(x,y)
- >>> print(parsed.type)
- ?
- >>> print(parsed.function)
- P(x)
- >>> print(parsed.function.type)
- <e,?>
- >>> print(parsed.function.function)
- P
- >>> print(parsed.function.function.type)
- <e,<e,?>>
- >>> print(tlp.parse(r'P').type)
- ?
- >>> print(tlp.parse(r'P', {'P': 't'}).type)
- t
- >>> a = tlp.parse(r'P(x)')
- >>> print(a.type)
- ?
- >>> print(a.function.type)
- <e,?>
- >>> print(a.argument.type)
- e
- >>> a = tlp.parse(r'-P(x)')
- >>> print(a.type)
- t
- >>> print(a.term.type)
- t
- >>> print(a.term.function.type)
- <e,t>
- >>> print(a.term.argument.type)
- e
- >>> a = tlp.parse(r'P & Q')
- >>> print(a.type)
- t
- >>> print(a.first.type)
- t
- >>> print(a.second.type)
- t
- >>> a = tlp.parse(r'(P(x) & Q(x))')
- >>> print(a.type)
- t
- >>> print(a.first.type)
- t
- >>> print(a.first.function.type)
- <e,t>
- >>> print(a.first.argument.type)
- e
- >>> print(a.second.type)
- t
- >>> print(a.second.function.type)
- <e,t>
- >>> print(a.second.argument.type)
- e
- >>> a = tlp.parse(r'\x.P(x)')
- >>> print(a.type)
- <e,?>
- >>> print(a.term.function.type)
- <e,?>
- >>> print(a.term.argument.type)
- e
- >>> a = tlp.parse(r'\P.P(x)')
- >>> print(a.type)
- <<e,?>,?>
- >>> print(a.term.function.type)
- <e,?>
- >>> print(a.term.argument.type)
- e
- >>> a = tlp.parse(r'(\x.P(x)(john)) & Q(x)')
- >>> print(a.type)
- t
- >>> print(a.first.type)
- t
- >>> print(a.first.function.type)
- <e,t>
- >>> print(a.first.function.term.function.type)
- <e,t>
- >>> print(a.first.function.term.argument.type)
- e
- >>> print(a.first.argument.type)
- e
- >>> a = tlp.parse(r'\x y.P(x,y)(john)(mary) & Q(x)')
- >>> print(a.type)
- t
- >>> print(a.first.type)
- t
- >>> print(a.first.function.type)
- <e,t>
- >>> print(a.first.function.function.type)
- <e,<e,t>>
- >>> a = tlp.parse(r'--P')
- >>> print(a.type)
- t
- >>> print(a.term.type)
- t
- >>> print(a.term.term.type)
- t
- >>> tlp.parse(r'\x y.P(x,y)').type
- <e,<e,?>>
- >>> tlp.parse(r'\x y.P(x,y)', {'P': '<e,<e,t>>'}).type
- <e,<e,t>>
- >>> a = tlp.parse(r'\P y.P(john,y)(\x y.see(x,y))')
- >>> a.type
- <e,?>
- >>> a.function.type
- <<e,<e,?>>,<e,?>>
- >>> a.function.term.term.function.function.type
- <e,<e,?>>
- >>> a.argument.type
- <e,<e,?>>
- >>> a = tlp.parse(r'exists c f.(father(c) = f)')
- >>> a.type
- t
- >>> a.term.term.type
- t
- >>> a.term.term.first.type
- e
- >>> a.term.term.first.function.type
- <e,e>
- >>> a.term.term.second.type
- e
- typecheck()
- >>> a = tlp.parse('P(x)')
- >>> b = tlp.parse('Q(x)')
- >>> a.type
- ?
- >>> c = a & b
- >>> c.first.type
- ?
- >>> c.typecheck() # doctest: +ELLIPSIS
- {...}
- >>> c.first.type
- t
- >>> a = tlp.parse('P(x)')
- >>> b = tlp.parse('P(x) & Q(x)')
- >>> a.type
- ?
- >>> typecheck([a,b]) # doctest: +ELLIPSIS
- {...}
- >>> a.type
- t
- >>> e = tlp.parse(r'man(x)')
- >>> print(dict((k,str(v)) for k,v in e.typecheck().items()) == {'x': 'e', 'man': '<e,?>'})
- True
- >>> sig = {'man': '<e, t>'}
- >>> e = tlp.parse(r'man(x)', sig)
- >>> print(e.function.type)
- <e,t>
- >>> print(dict((k,str(v)) for k,v in e.typecheck().items()) == {'x': 'e', 'man': '<e,t>'})
- True
- >>> print(e.function.type)
- <e,t>
- >>> print(dict((k,str(v)) for k,v in e.typecheck(sig).items()) == {'x': 'e', 'man': '<e,t>'})
- True
- findtype()
- >>> print(tlp.parse(r'man(x)').findtype(Variable('man')))
- <e,?>
- >>> print(tlp.parse(r'see(x,y)').findtype(Variable('see')))
- <e,<e,?>>
- >>> print(tlp.parse(r'P(Q(R(x)))').findtype(Variable('Q')))
- ?
- reading types from strings
- >>> Type.fromstring('e')
- e
- >>> Type.fromstring('<e,t>')
- <e,t>
- >>> Type.fromstring('<<e,t>,<e,t>>')
- <<e,t>,<e,t>>
- >>> Type.fromstring('<<e,?>,?>')
- <<e,?>,?>
- alternative type format
- >>> Type.fromstring('e').str()
- 'IND'
- >>> Type.fromstring('<e,?>').str()
- '(IND -> ANY)'
- >>> Type.fromstring('<<e,t>,t>').str()
- '((IND -> BOOL) -> BOOL)'
- Type.__eq__()
- >>> from nltk.sem.logic import *
- >>> e = ENTITY_TYPE
- >>> t = TRUTH_TYPE
- >>> a = ANY_TYPE
- >>> et = ComplexType(e,t)
- >>> eet = ComplexType(e,ComplexType(e,t))
- >>> at = ComplexType(a,t)
- >>> ea = ComplexType(e,a)
- >>> aa = ComplexType(a,a)
- >>> e == e
- True
- >>> t == t
- True
- >>> e == t
- False
- >>> a == t
- False
- >>> t == a
- False
- >>> a == a
- True
- >>> et == et
- True
- >>> a == et
- False
- >>> et == a
- False
- >>> a == ComplexType(a,aa)
- True
- >>> ComplexType(a,aa) == a
- True
- matches()
- >>> e.matches(t)
- False
- >>> a.matches(t)
- True
- >>> t.matches(a)
- True
- >>> a.matches(et)
- True
- >>> et.matches(a)
- True
- >>> ea.matches(eet)
- True
- >>> eet.matches(ea)
- True
- >>> aa.matches(et)
- True
- >>> aa.matches(t)
- True
- Type error during parsing
- =========================
- >>> try: print(tlp.parse(r'exists x y.(P(x) & P(x,y))'))
- ... except InconsistentTypeHierarchyException as e: print(e)
- The variable 'P' was found in multiple places with different types.
- >>> try: tlp.parse(r'\x y.see(x,y)(\x.man(x))')
- ... except TypeException as e: print(e)
- The function '\x y.see(x,y)' is of type '<e,<e,?>>' and cannot be applied to '\x.man(x)' of type '<e,?>'. Its argument must match type 'e'.
- >>> try: tlp.parse(r'\P x y.-P(x,y)(\x.-man(x))')
- ... except TypeException as e: print(e)
- The function '\P x y.-P(x,y)' is of type '<<e,<e,t>>,<e,<e,t>>>' and cannot be applied to '\x.-man(x)' of type '<e,t>'. Its argument must match type '<e,<e,t>>'.
- >>> a = tlp.parse(r'-talk(x)')
- >>> signature = a.typecheck()
- >>> try: print(tlp.parse(r'-talk(x,y)', signature))
- ... except InconsistentTypeHierarchyException as e: print(e)
- The variable 'talk' was found in multiple places with different types.
- >>> a = tlp.parse(r'-P(x)')
- >>> b = tlp.parse(r'-P(x,y)')
- >>> a.typecheck() # doctest: +ELLIPSIS
- {...}
- >>> b.typecheck() # doctest: +ELLIPSIS
- {...}
- >>> try: typecheck([a,b])
- ... except InconsistentTypeHierarchyException as e: print(e)
- The variable 'P' was found in multiple places with different types.
- >>> a = tlp.parse(r'P(x)')
- >>> b = tlp.parse(r'P(x,y)')
- >>> signature = {'P': '<e,t>'}
- >>> a.typecheck(signature) # doctest: +ELLIPSIS
- {...}
- >>> try: typecheck([a,b], signature)
- ... except InconsistentTypeHierarchyException as e: print(e)
- The variable 'P' was found in multiple places with different types.
- Parse errors
- ============
- >>> try: read_expr(r'')
- ... except LogicalExpressionException as e: print(e)
- End of input found. Expression expected.
- <BLANKLINE>
- ^
- >>> try: read_expr(r'(')
- ... except LogicalExpressionException as e: print(e)
- End of input found. Expression expected.
- (
- ^
- >>> try: read_expr(r')')
- ... except LogicalExpressionException as e: print(e)
- Unexpected token: ')'. Expression expected.
- )
- ^
- >>> try: read_expr(r'()')
- ... except LogicalExpressionException as e: print(e)
- Unexpected token: ')'. Expression expected.
- ()
- ^
- >>> try: read_expr(r'(P(x) & Q(x)')
- ... except LogicalExpressionException as e: print(e)
- End of input found. Expected token ')'.
- (P(x) & Q(x)
- ^
- >>> try: read_expr(r'(P(x) &')
- ... except LogicalExpressionException as e: print(e)
- End of input found. Expression expected.
- (P(x) &
- ^
- >>> try: read_expr(r'(P(x) | )')
- ... except LogicalExpressionException as e: print(e)
- Unexpected token: ')'. Expression expected.
- (P(x) | )
- ^
- >>> try: read_expr(r'P(x) ->')
- ... except LogicalExpressionException as e: print(e)
- End of input found. Expression expected.
- P(x) ->
- ^
- >>> try: read_expr(r'P(x')
- ... except LogicalExpressionException as e: print(e)
- End of input found. Expected token ')'.
- P(x
- ^
- >>> try: read_expr(r'P(x,')
- ... except LogicalExpressionException as e: print(e)
- End of input found. Expression expected.
- P(x,
- ^
- >>> try: read_expr(r'P(x,)')
- ... except LogicalExpressionException as e: print(e)
- Unexpected token: ')'. Expression expected.
- P(x,)
- ^
- >>> try: read_expr(r'exists')
- ... except LogicalExpressionException as e: print(e)
- End of input found. Variable and Expression expected following quantifier 'exists'.
- exists
- ^
- >>> try: read_expr(r'exists x')
- ... except LogicalExpressionException as e: print(e)
- End of input found. Expression expected.
- exists x
- ^
- >>> try: read_expr(r'exists x.')
- ... except LogicalExpressionException as e: print(e)
- End of input found. Expression expected.
- exists x.
- ^
- >>> try: read_expr(r'\ ')
- ... except LogicalExpressionException as e: print(e)
- End of input found. Variable and Expression expected following lambda operator.
- \
- ^
- >>> try: read_expr(r'\ x')
- ... except LogicalExpressionException as e: print(e)
- End of input found. Expression expected.
- \ x
- ^
- >>> try: read_expr(r'\ x y')
- ... except LogicalExpressionException as e: print(e)
- End of input found. Expression expected.
- \ x y
- ^
- >>> try: read_expr(r'\ x.')
- ... except LogicalExpressionException as e: print(e)
- End of input found. Expression expected.
- \ x.
- ^
- >>> try: read_expr(r'P(x)Q(x)')
- ... except LogicalExpressionException as e: print(e)
- Unexpected token: 'Q'.
- P(x)Q(x)
- ^
- >>> try: read_expr(r'(P(x)Q(x)')
- ... except LogicalExpressionException as e: print(e)
- Unexpected token: 'Q'. Expected token ')'.
- (P(x)Q(x)
- ^
- >>> try: read_expr(r'exists x y')
- ... except LogicalExpressionException as e: print(e)
- End of input found. Expression expected.
- exists x y
- ^
- >>> try: read_expr(r'exists x y.')
- ... except LogicalExpressionException as e: print(e)
- End of input found. Expression expected.
- exists x y.
- ^
- >>> try: read_expr(r'exists x -> y')
- ... except LogicalExpressionException as e: print(e)
- Unexpected token: '->'. Expression expected.
- exists x -> y
- ^
- >>> try: read_expr(r'A -> ((P(x) & Q(x)) -> Z')
- ... except LogicalExpressionException as e: print(e)
- End of input found. Expected token ')'.
- A -> ((P(x) & Q(x)) -> Z
- ^
- >>> try: read_expr(r'A -> ((P(x) &) -> Z')
- ... except LogicalExpressionException as e: print(e)
- Unexpected token: ')'. Expression expected.
- A -> ((P(x) &) -> Z
- ^
- >>> try: read_expr(r'A -> ((P(x) | )) -> Z')
- ... except LogicalExpressionException as e: print(e)
- Unexpected token: ')'. Expression expected.
- A -> ((P(x) | )) -> Z
- ^
- >>> try: read_expr(r'A -> (P(x) ->) -> Z')
- ... except LogicalExpressionException as e: print(e)
- Unexpected token: ')'. Expression expected.
- A -> (P(x) ->) -> Z
- ^
- >>> try: read_expr(r'A -> (P(x) -> Z')
- ... except LogicalExpressionException as e: print(e)
- End of input found. Expected token ')'.
- A -> (P(x) -> Z
- ^
- >>> try: read_expr(r'A -> (P(x,) -> Z')
- ... except LogicalExpressionException as e: print(e)
- Unexpected token: ')'. Expression expected.
- A -> (P(x,) -> Z
- ^
- >>> try: read_expr(r'A -> (P(x,)) -> Z')
- ... except LogicalExpressionException as e: print(e)
- Unexpected token: ')'. Expression expected.
- A -> (P(x,)) -> Z
- ^
- >>> try: read_expr(r'A -> (exists) -> Z')
- ... except LogicalExpressionException as e: print(e)
- ')' is an illegal variable name. Constants may not be quantified.
- A -> (exists) -> Z
- ^
- >>> try: read_expr(r'A -> (exists x) -> Z')
- ... except LogicalExpressionException as e: print(e)
- Unexpected token: ')'. Expression expected.
- A -> (exists x) -> Z
- ^
- >>> try: read_expr(r'A -> (exists x.) -> Z')
- ... except LogicalExpressionException as e: print(e)
- Unexpected token: ')'. Expression expected.
- A -> (exists x.) -> Z
- ^
- >>> try: read_expr(r'A -> (\ ) -> Z')
- ... except LogicalExpressionException as e: print(e)
- ')' is an illegal variable name. Constants may not be abstracted.
- A -> (\ ) -> Z
- ^
- >>> try: read_expr(r'A -> (\ x) -> Z')
- ... except LogicalExpressionException as e: print(e)
- Unexpected token: ')'. Expression expected.
- A -> (\ x) -> Z
- ^
- >>> try: read_expr(r'A -> (\ x y) -> Z')
- ... except LogicalExpressionException as e: print(e)
- Unexpected token: ')'. Expression expected.
- A -> (\ x y) -> Z
- ^
- >>> try: read_expr(r'A -> (\ x.) -> Z')
- ... except LogicalExpressionException as e: print(e)
- Unexpected token: ')'. Expression expected.
- A -> (\ x.) -> Z
- ^
- >>> try: read_expr(r'A -> (P(x)Q(x)) -> Z')
- ... except LogicalExpressionException as e: print(e)
- Unexpected token: 'Q'. Expected token ')'.
- A -> (P(x)Q(x)) -> Z
- ^
- >>> try: read_expr(r'A -> ((P(x)Q(x)) -> Z')
- ... except LogicalExpressionException as e: print(e)
- Unexpected token: 'Q'. Expected token ')'.
- A -> ((P(x)Q(x)) -> Z
- ^
- >>> try: read_expr(r'A -> (all x y) -> Z')
- ... except LogicalExpressionException as e: print(e)
- Unexpected token: ')'. Expression expected.
- A -> (all x y) -> Z
- ^
- >>> try: read_expr(r'A -> (exists x y.) -> Z')
- ... except LogicalExpressionException as e: print(e)
- Unexpected token: ')'. Expression expected.
- A -> (exists x y.) -> Z
- ^
- >>> try: read_expr(r'A -> (exists x -> y) -> Z')
- ... except LogicalExpressionException as e: print(e)
- Unexpected token: '->'. Expression expected.
- A -> (exists x -> y) -> Z
- ^
|