semantics.doctest 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666
  1. .. Copyright (C) 2001-2019 NLTK Project
  2. .. For license information, see LICENSE.TXT
  3. =========
  4. Semantics
  5. =========
  6. >>> import nltk
  7. >>> from nltk.sem import Valuation, Model
  8. >>> v = [('adam', 'b1'), ('betty', 'g1'), ('fido', 'd1'),
  9. ... ('girl', set(['g1', 'g2'])), ('boy', set(['b1', 'b2'])),
  10. ... ('dog', set(['d1'])),
  11. ... ('love', set([('b1', 'g1'), ('b2', 'g2'), ('g1', 'b1'), ('g2', 'b1')]))]
  12. >>> val = Valuation(v)
  13. >>> dom = val.domain
  14. >>> m = Model(dom, val)
  15. Evaluation
  16. ----------
  17. The top-level method of a ``Model`` instance is ``evaluate()``, which
  18. assigns a semantic value to expressions of the ``logic`` module, under
  19. an assignment ``g``:
  20. >>> dom = val.domain
  21. >>> g = nltk.sem.Assignment(dom)
  22. >>> m.evaluate('all x.(boy(x) -> - girl(x))', g)
  23. True
  24. ``evaluate()`` calls a recursive function ``satisfy()``, which in turn
  25. calls a function ``i()`` to interpret non-logical constants and
  26. individual variables. ``i()`` delegates the interpretation of these to
  27. the the model's ``Valuation`` and the variable assignment ``g``
  28. respectively. Any atomic expression which cannot be assigned a value
  29. by ``i`` raises an ``Undefined`` exception; this is caught by
  30. ``evaluate``, which returns the string ``'Undefined'``.
  31. >>> m.evaluate('walk(adam)', g, trace=2)
  32. <BLANKLINE>
  33. 'walk(adam)' is undefined under M, g
  34. 'Undefined'
  35. Batch Processing
  36. ----------------
  37. The utility functions ``interpret_sents()`` and ``evaluate_sents()`` are intended to
  38. help with processing multiple sentences. Here's an example of the first of these:
  39. >>> sents = ['Mary walks']
  40. >>> results = nltk.sem.util.interpret_sents(sents, 'grammars/sample_grammars/sem2.fcfg')
  41. >>> for result in results:
  42. ... for (synrep, semrep) in result:
  43. ... print(synrep)
  44. (S[SEM=<walk(mary)>]
  45. (NP[-LOC, NUM='sg', SEM=<\P.P(mary)>]
  46. (PropN[-LOC, NUM='sg', SEM=<\P.P(mary)>] Mary))
  47. (VP[NUM='sg', SEM=<\x.walk(x)>]
  48. (IV[NUM='sg', SEM=<\x.walk(x)>, TNS='pres'] walks)))
  49. In order to provide backwards compatibility with 'legacy' grammars where the semantics value
  50. is specified with a lowercase
  51. ``sem`` feature, the relevant feature name can be passed to the function using the
  52. ``semkey`` parameter, as shown here:
  53. >>> sents = ['raining']
  54. >>> g = nltk.grammar.FeatureGrammar.fromstring("""
  55. ... % start S
  56. ... S[sem=<raining>] -> 'raining'
  57. ... """)
  58. >>> results = nltk.sem.util.interpret_sents(sents, g, semkey='sem')
  59. >>> for result in results:
  60. ... for (synrep, semrep) in result:
  61. ... print(semrep)
  62. raining
  63. The function ``evaluate_sents()`` works in a similar manner, but also needs to be
  64. passed a ``Model`` against which the semantic representations are evaluated.
  65. Unit Tests
  66. ==========
  67. Unit tests for relations and valuations
  68. ---------------------------------------
  69. >>> from nltk.sem import *
  70. Relations are sets of tuples, all of the same length.
  71. >>> s1 = set([('d1', 'd2'), ('d1', 'd1'), ('d2', 'd1')])
  72. >>> is_rel(s1)
  73. True
  74. >>> s2 = set([('d1', 'd2'), ('d1', 'd2'), ('d1',)])
  75. >>> is_rel(s2)
  76. Traceback (most recent call last):
  77. . . .
  78. ValueError: Set set([('d1', 'd2'), ('d1',)]) contains sequences of different lengths
  79. >>> s3 = set(['d1', 'd2'])
  80. >>> is_rel(s3)
  81. Traceback (most recent call last):
  82. . . .
  83. ValueError: Set set(['d2', 'd1']) contains sequences of different lengths
  84. >>> s4 = set2rel(s3)
  85. >>> is_rel(s4)
  86. True
  87. >>> is_rel(set())
  88. True
  89. >>> null_binary_rel = set([(None, None)])
  90. >>> is_rel(null_binary_rel)
  91. True
  92. Sets of entities are converted into sets of singleton tuples
  93. (containing strings).
  94. >>> sorted(set2rel(s3))
  95. [('d1',), ('d2',)]
  96. >>> sorted(set2rel(set([1,3,5,])))
  97. ['1', '3', '5']
  98. >>> set2rel(set()) == set()
  99. True
  100. >>> set2rel(set2rel(s3)) == set2rel(s3)
  101. True
  102. Predication is evaluated by set membership.
  103. >>> ('d1', 'd2') in s1
  104. True
  105. >>> ('d2', 'd2') in s1
  106. False
  107. >>> ('d1',) in s1
  108. False
  109. >>> 'd2' in s1
  110. False
  111. >>> ('d1',) in s4
  112. True
  113. >>> ('d1',) in set()
  114. False
  115. >>> 'd1' in null_binary_rel
  116. False
  117. >>> val = Valuation([('Fido', 'd1'), ('dog', set(['d1', 'd2'])), ('walk', set())])
  118. >>> sorted(val['dog'])
  119. [('d1',), ('d2',)]
  120. >>> val.domain == set(['d1', 'd2'])
  121. True
  122. >>> print(val.symbols)
  123. ['Fido', 'dog', 'walk']
  124. Parse a valuation from a string.
  125. >>> v = """
  126. ... john => b1
  127. ... mary => g1
  128. ... suzie => g2
  129. ... fido => d1
  130. ... tess => d2
  131. ... noosa => n
  132. ... girl => {g1, g2}
  133. ... boy => {b1, b2}
  134. ... dog => {d1, d2}
  135. ... bark => {d1, d2}
  136. ... walk => {b1, g2, d1}
  137. ... chase => {(b1, g1), (b2, g1), (g1, d1), (g2, d2)}
  138. ... see => {(b1, g1), (b2, d2), (g1, b1),(d2, b1), (g2, n)}
  139. ... in => {(b1, n), (b2, n), (d2, n)}
  140. ... with => {(b1, g1), (g1, b1), (d1, b1), (b1, d1)}
  141. ... """
  142. >>> val = Valuation.fromstring(v)
  143. >>> print(val) # doctest: +SKIP
  144. {'bark': set([('d1',), ('d2',)]),
  145. 'boy': set([('b1',), ('b2',)]),
  146. 'chase': set([('b1', 'g1'), ('g2', 'd2'), ('g1', 'd1'), ('b2', 'g1')]),
  147. 'dog': set([('d1',), ('d2',)]),
  148. 'fido': 'd1',
  149. 'girl': set([('g2',), ('g1',)]),
  150. 'in': set([('d2', 'n'), ('b1', 'n'), ('b2', 'n')]),
  151. 'john': 'b1',
  152. 'mary': 'g1',
  153. 'noosa': 'n',
  154. 'see': set([('b1', 'g1'), ('b2', 'd2'), ('d2', 'b1'), ('g2', 'n'), ('g1', 'b1')]),
  155. 'suzie': 'g2',
  156. 'tess': 'd2',
  157. 'walk': set([('d1',), ('b1',), ('g2',)]),
  158. 'with': set([('b1', 'g1'), ('d1', 'b1'), ('b1', 'd1'), ('g1', 'b1')])}
  159. Unit tests for function argument application in a Model
  160. -------------------------------------------------------
  161. >>> v = [('adam', 'b1'), ('betty', 'g1'), ('fido', 'd1'),\
  162. ... ('girl', set(['g1', 'g2'])), ('boy', set(['b1', 'b2'])), ('dog', set(['d1'])),
  163. ... ('love', set([('b1', 'g1'), ('b2', 'g2'), ('g1', 'b1'), ('g2', 'b1')])),
  164. ... ('kiss', null_binary_rel)]
  165. >>> val = Valuation(v)
  166. >>> dom = val.domain
  167. >>> m = Model(dom, val)
  168. >>> g = Assignment(dom)
  169. >>> sorted(val['boy'])
  170. [('b1',), ('b2',)]
  171. >>> ('b1',) in val['boy']
  172. True
  173. >>> ('g1',) in val['boy']
  174. False
  175. >>> ('foo',) in val['boy']
  176. False
  177. >>> ('b1', 'g1') in val['love']
  178. True
  179. >>> ('b1', 'b1') in val['kiss']
  180. False
  181. >>> sorted(val.domain)
  182. ['b1', 'b2', 'd1', 'g1', 'g2']
  183. Model Tests
  184. ===========
  185. Extension of Lambda expressions
  186. >>> v0 = [('adam', 'b1'), ('betty', 'g1'), ('fido', 'd1'),\
  187. ... ('girl', set(['g1', 'g2'])), ('boy', set(['b1', 'b2'])),
  188. ... ('dog', set(['d1'])),
  189. ... ('love', set([('b1', 'g1'), ('b2', 'g2'), ('g1', 'b1'), ('g2', 'b1')]))]
  190. >>> val0 = Valuation(v0)
  191. >>> dom0 = val0.domain
  192. >>> m0 = Model(dom0, val0)
  193. >>> g0 = Assignment(dom0)
  194. >>> print(m0.evaluate(r'\x. \y. love(x, y)', g0) == {'g2': {'g2': False, 'b2': False, 'b1': True, 'g1': False, 'd1': False}, 'b2': {'g2': True, 'b2': False, 'b1': False, 'g1': False, 'd1': False}, 'b1': {'g2': False, 'b2': False, 'b1': False, 'g1': True, 'd1': False}, 'g1': {'g2': False, 'b2': False, 'b1': True, 'g1': False, 'd1': False}, 'd1': {'g2': False, 'b2': False, 'b1': False, 'g1': False, 'd1': False}})
  195. True
  196. >>> print(m0.evaluate(r'\x. dog(x) (adam)', g0))
  197. False
  198. >>> print(m0.evaluate(r'\x. (dog(x) | boy(x)) (adam)', g0))
  199. True
  200. >>> print(m0.evaluate(r'\x. \y. love(x, y)(fido)', g0) == {'g2': False, 'b2': False, 'b1': False, 'g1': False, 'd1': False})
  201. True
  202. >>> print(m0.evaluate(r'\x. \y. love(x, y)(adam)', g0) == {'g2': False, 'b2': False, 'b1': False, 'g1': True, 'd1': False})
  203. True
  204. >>> print(m0.evaluate(r'\x. \y. love(x, y)(betty)', g0) == {'g2': False, 'b2': False, 'b1': True, 'g1': False, 'd1': False})
  205. True
  206. >>> print(m0.evaluate(r'\x. \y. love(x, y)(betty)(adam)', g0))
  207. True
  208. >>> print(m0.evaluate(r'\x. \y. love(x, y)(betty, adam)', g0))
  209. True
  210. >>> print(m0.evaluate(r'\y. \x. love(x, y)(fido)(adam)', g0))
  211. False
  212. >>> print(m0.evaluate(r'\y. \x. love(x, y)(betty, adam)', g0))
  213. True
  214. >>> print(m0.evaluate(r'\x. exists y. love(x, y)', g0) == {'g2': True, 'b2': True, 'b1': True, 'g1': True, 'd1': False})
  215. True
  216. >>> print(m0.evaluate(r'\z. adam', g0) == {'g2': 'b1', 'b2': 'b1', 'b1': 'b1', 'g1': 'b1', 'd1': 'b1'})
  217. True
  218. >>> print(m0.evaluate(r'\z. love(x, y)', g0) == {'g2': False, 'b2': False, 'b1': False, 'g1': False, 'd1': False})
  219. True
  220. Propositional Model Test
  221. ------------------------
  222. >>> tests = [
  223. ... ('P & Q', True),
  224. ... ('P & R', False),
  225. ... ('- P', False),
  226. ... ('- R', True),
  227. ... ('- - P', True),
  228. ... ('- (P & R)', True),
  229. ... ('P | R', True),
  230. ... ('R | P', True),
  231. ... ('R | R', False),
  232. ... ('- P | R', False),
  233. ... ('P | - P', True),
  234. ... ('P -> Q', True),
  235. ... ('P -> R', False),
  236. ... ('R -> P', True),
  237. ... ('P <-> P', True),
  238. ... ('R <-> R', True),
  239. ... ('P <-> R', False),
  240. ... ]
  241. >>> val1 = Valuation([('P', True), ('Q', True), ('R', False)])
  242. >>> dom = set([])
  243. >>> m = Model(dom, val1)
  244. >>> g = Assignment(dom)
  245. >>> for (sent, testvalue) in tests:
  246. ... semvalue = m.evaluate(sent, g)
  247. ... if semvalue == testvalue:
  248. ... print('*', end=' ')
  249. * * * * * * * * * * * * * * * * *
  250. Test of i Function
  251. ------------------
  252. >>> from nltk.sem import Expression
  253. >>> v = [('adam', 'b1'), ('betty', 'g1'), ('fido', 'd1'),
  254. ... ('girl', set(['g1', 'g2'])), ('boy', set(['b1', 'b2'])), ('dog', set(['d1'])),
  255. ... ('love', set([('b1', 'g1'), ('b2', 'g2'), ('g1', 'b1'), ('g2', 'b1')]))]
  256. >>> val = Valuation(v)
  257. >>> dom = val.domain
  258. >>> m = Model(dom, val)
  259. >>> g = Assignment(dom, [('x', 'b1'), ('y', 'g2')])
  260. >>> exprs = ['adam', 'girl', 'love', 'walks', 'x', 'y', 'z']
  261. >>> parsed_exprs = [Expression.fromstring(e) for e in exprs]
  262. >>> sorted_set = lambda x: sorted(x) if isinstance(x, set) else x
  263. >>> for parsed in parsed_exprs:
  264. ... try:
  265. ... print("'%s' gets value %s" % (parsed, sorted_set(m.i(parsed, g))))
  266. ... except Undefined:
  267. ... print("'%s' is Undefined" % parsed)
  268. 'adam' gets value b1
  269. 'girl' gets value [('g1',), ('g2',)]
  270. 'love' gets value [('b1', 'g1'), ('b2', 'g2'), ('g1', 'b1'), ('g2', 'b1')]
  271. 'walks' is Undefined
  272. 'x' gets value b1
  273. 'y' gets value g2
  274. 'z' is Undefined
  275. Test for formulas in Model
  276. --------------------------
  277. >>> tests = [
  278. ... ('love(adam, betty)', True),
  279. ... ('love(adam, sue)', 'Undefined'),
  280. ... ('dog(fido)', True),
  281. ... ('- dog(fido)', False),
  282. ... ('- - dog(fido)', True),
  283. ... ('- dog(sue)', 'Undefined'),
  284. ... ('dog(fido) & boy(adam)', True),
  285. ... ('- (dog(fido) & boy(adam))', False),
  286. ... ('- dog(fido) & boy(adam)', False),
  287. ... ('dog(fido) | boy(adam)', True),
  288. ... ('- (dog(fido) | boy(adam))', False),
  289. ... ('- dog(fido) | boy(adam)', True),
  290. ... ('- dog(fido) | - boy(adam)', False),
  291. ... ('dog(fido) -> boy(adam)', True),
  292. ... ('- (dog(fido) -> boy(adam))', False),
  293. ... ('- dog(fido) -> boy(adam)', True),
  294. ... ('exists x . love(adam, x)', True),
  295. ... ('all x . love(adam, x)', False),
  296. ... ('fido = fido', True),
  297. ... ('exists x . all y. love(x, y)', False),
  298. ... ('exists x . (x = fido)', True),
  299. ... ('all x . (dog(x) | - dog(x))', True),
  300. ... ('adam = mia', 'Undefined'),
  301. ... ('\\x. (boy(x) | girl(x))', {'g2': True, 'b2': True, 'b1': True, 'g1': True, 'd1': False}),
  302. ... ('\\x. exists y. (boy(x) & love(x, y))', {'g2': False, 'b2': True, 'b1': True, 'g1': False, 'd1': False}),
  303. ... ('exists z1. boy(z1)', True),
  304. ... ('exists x. (boy(x) & - (x = adam))', True),
  305. ... ('exists x. (boy(x) & all y. love(y, x))', False),
  306. ... ('all x. (boy(x) | girl(x))', False),
  307. ... ('all x. (girl(x) -> exists y. boy(y) & love(x, y))', False),
  308. ... ('exists x. (boy(x) & all y. (girl(y) -> love(y, x)))', True),
  309. ... ('exists x. (boy(x) & all y. (girl(y) -> love(x, y)))', False),
  310. ... ('all x. (dog(x) -> - girl(x))', True),
  311. ... ('exists x. exists y. (love(x, y) & love(x, y))', True),
  312. ... ]
  313. >>> for (sent, testvalue) in tests:
  314. ... semvalue = m.evaluate(sent, g)
  315. ... if semvalue == testvalue:
  316. ... print('*', end=' ')
  317. ... else:
  318. ... print(sent, semvalue)
  319. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  320. Satisfier Tests
  321. ---------------
  322. >>> formulas = [
  323. ... 'boy(x)',
  324. ... '(x = x)',
  325. ... '(boy(x) | girl(x))',
  326. ... '(boy(x) & girl(x))',
  327. ... 'love(adam, x)',
  328. ... 'love(x, adam)',
  329. ... '- (x = adam)',
  330. ... 'exists z22. love(x, z22)',
  331. ... 'exists y. love(y, x)',
  332. ... 'all y. (girl(y) -> love(x, y))',
  333. ... 'all y. (girl(y) -> love(y, x))',
  334. ... 'all y. (girl(y) -> (boy(x) & love(y, x)))',
  335. ... 'boy(x) & all y. (girl(y) -> love(x, y))',
  336. ... 'boy(x) & all y. (girl(y) -> love(y, x))',
  337. ... 'boy(x) & exists y. (girl(y) & love(y, x))',
  338. ... 'girl(x) -> dog(x)',
  339. ... 'all y. (dog(y) -> (x = y))',
  340. ... '- exists y. love(y, x)',
  341. ... 'exists y. (love(adam, y) & love(y, x))'
  342. ... ]
  343. >>> g.purge()
  344. >>> g.add('x', 'b1')
  345. {'x': 'b1'}
  346. >>> for f in formulas: # doctest: +NORMALIZE_WHITESPACE
  347. ... try:
  348. ... print("'%s' gets value: %s" % (f, m.evaluate(f, g)))
  349. ... except Undefined:
  350. ... print("'%s' is Undefined" % f)
  351. 'boy(x)' gets value: True
  352. '(x = x)' gets value: True
  353. '(boy(x) | girl(x))' gets value: True
  354. '(boy(x) & girl(x))' gets value: False
  355. 'love(adam, x)' gets value: False
  356. 'love(x, adam)' gets value: False
  357. '- (x = adam)' gets value: False
  358. 'exists z22. love(x, z22)' gets value: True
  359. 'exists y. love(y, x)' gets value: True
  360. 'all y. (girl(y) -> love(x, y))' gets value: False
  361. 'all y. (girl(y) -> love(y, x))' gets value: True
  362. 'all y. (girl(y) -> (boy(x) & love(y, x)))' gets value: True
  363. 'boy(x) & all y. (girl(y) -> love(x, y))' gets value: False
  364. 'boy(x) & all y. (girl(y) -> love(y, x))' gets value: True
  365. 'boy(x) & exists y. (girl(y) & love(y, x))' gets value: True
  366. 'girl(x) -> dog(x)' gets value: True
  367. 'all y. (dog(y) -> (x = y))' gets value: False
  368. '- exists y. love(y, x)' gets value: False
  369. 'exists y. (love(adam, y) & love(y, x))' gets value: True
  370. >>> from nltk.sem import Expression
  371. >>> for fmla in formulas: # doctest: +NORMALIZE_WHITESPACE
  372. ... p = Expression.fromstring(fmla)
  373. ... g.purge()
  374. ... print("Satisfiers of '%s':\n\t%s" % (p, sorted(m.satisfiers(p, 'x', g))))
  375. Satisfiers of 'boy(x)':
  376. ['b1', 'b2']
  377. Satisfiers of '(x = x)':
  378. ['b1', 'b2', 'd1', 'g1', 'g2']
  379. Satisfiers of '(boy(x) | girl(x))':
  380. ['b1', 'b2', 'g1', 'g2']
  381. Satisfiers of '(boy(x) & girl(x))':
  382. []
  383. Satisfiers of 'love(adam,x)':
  384. ['g1']
  385. Satisfiers of 'love(x,adam)':
  386. ['g1', 'g2']
  387. Satisfiers of '-(x = adam)':
  388. ['b2', 'd1', 'g1', 'g2']
  389. Satisfiers of 'exists z22.love(x,z22)':
  390. ['b1', 'b2', 'g1', 'g2']
  391. Satisfiers of 'exists y.love(y,x)':
  392. ['b1', 'g1', 'g2']
  393. Satisfiers of 'all y.(girl(y) -> love(x,y))':
  394. []
  395. Satisfiers of 'all y.(girl(y) -> love(y,x))':
  396. ['b1']
  397. Satisfiers of 'all y.(girl(y) -> (boy(x) & love(y,x)))':
  398. ['b1']
  399. Satisfiers of '(boy(x) & all y.(girl(y) -> love(x,y)))':
  400. []
  401. Satisfiers of '(boy(x) & all y.(girl(y) -> love(y,x)))':
  402. ['b1']
  403. Satisfiers of '(boy(x) & exists y.(girl(y) & love(y,x)))':
  404. ['b1']
  405. Satisfiers of '(girl(x) -> dog(x))':
  406. ['b1', 'b2', 'd1']
  407. Satisfiers of 'all y.(dog(y) -> (x = y))':
  408. ['d1']
  409. Satisfiers of '-exists y.love(y,x)':
  410. ['b2', 'd1']
  411. Satisfiers of 'exists y.(love(adam,y) & love(y,x))':
  412. ['b1']
  413. Tests based on the Blackburn & Bos testsuite
  414. --------------------------------------------
  415. >>> v1 = [('jules', 'd1'), ('vincent', 'd2'), ('pumpkin', 'd3'),
  416. ... ('honey_bunny', 'd4'), ('yolanda', 'd5'),
  417. ... ('customer', set(['d1', 'd2'])),
  418. ... ('robber', set(['d3', 'd4'])),
  419. ... ('love', set([('d3', 'd4')]))]
  420. >>> val1 = Valuation(v1)
  421. >>> dom1 = val1.domain
  422. >>> m1 = Model(dom1, val1)
  423. >>> g1 = Assignment(dom1)
  424. >>> v2 = [('jules', 'd1'), ('vincent', 'd2'), ('pumpkin', 'd3'),
  425. ... ('honey_bunny', 'd4'), ('yolanda', 'd4'),
  426. ... ('customer', set(['d1', 'd2', 'd5', 'd6'])),
  427. ... ('robber', set(['d3', 'd4'])),
  428. ... ('love', set([(None, None)]))]
  429. >>> val2 = Valuation(v2)
  430. >>> dom2 = set(['d1', 'd2', 'd3', 'd4', 'd5', 'd6'])
  431. >>> m2 = Model(dom2, val2)
  432. >>> g2 = Assignment(dom2)
  433. >>> g21 = Assignment(dom2)
  434. >>> g21.add('y', 'd3')
  435. {'y': 'd3'}
  436. >>> v3 = [('mia', 'd1'), ('jody', 'd2'), ('jules', 'd3'),
  437. ... ('vincent', 'd4'),
  438. ... ('woman', set(['d1', 'd2'])), ('man', set(['d3', 'd4'])),
  439. ... ('joke', set(['d5', 'd6'])), ('episode', set(['d7', 'd8'])),
  440. ... ('in', set([('d5', 'd7'), ('d5', 'd8')])),
  441. ... ('tell', set([('d1', 'd5'), ('d2', 'd6')]))]
  442. >>> val3 = Valuation(v3)
  443. >>> dom3 = set(['d1', 'd2', 'd3', 'd4', 'd5', 'd6', 'd7', 'd8'])
  444. >>> m3 = Model(dom3, val3)
  445. >>> g3 = Assignment(dom3)
  446. >>> tests = [
  447. ... ('exists x. robber(x)', m1, g1, True),
  448. ... ('exists x. exists y. love(y, x)', m1, g1, True),
  449. ... ('exists x0. exists x1. love(x1, x0)', m2, g2, False),
  450. ... ('all x. all y. love(y, x)', m2, g2, False),
  451. ... ('- (all x. all y. love(y, x))', m2, g2, True),
  452. ... ('all x. all y. - love(y, x)', m2, g2, True),
  453. ... ('yolanda = honey_bunny', m2, g2, True),
  454. ... ('mia = honey_bunny', m2, g2, 'Undefined'),
  455. ... ('- (yolanda = honey_bunny)', m2, g2, False),
  456. ... ('- (mia = honey_bunny)', m2, g2, 'Undefined'),
  457. ... ('all x. (robber(x) | customer(x))', m2, g2, True),
  458. ... ('- (all x. (robber(x) | customer(x)))', m2, g2, False),
  459. ... ('(robber(x) | customer(x))', m2, g2, 'Undefined'),
  460. ... ('(robber(y) | customer(y))', m2, g21, True),
  461. ... ('exists x. (man(x) & exists x. woman(x))', m3, g3, True),
  462. ... ('exists x. (man(x) & exists x. woman(x))', m3, g3, True),
  463. ... ('- exists x. woman(x)', m3, g3, False),
  464. ... ('exists x. (tasty(x) & burger(x))', m3, g3, 'Undefined'),
  465. ... ('- exists x. (tasty(x) & burger(x))', m3, g3, 'Undefined'),
  466. ... ('exists x. (man(x) & - exists y. woman(y))', m3, g3, False),
  467. ... ('exists x. (man(x) & - exists x. woman(x))', m3, g3, False),
  468. ... ('exists x. (woman(x) & - exists x. customer(x))', m2, g2, 'Undefined'),
  469. ... ]
  470. >>> for item in tests:
  471. ... sentence, model, g, testvalue = item
  472. ... semvalue = model.evaluate(sentence, g)
  473. ... if semvalue == testvalue:
  474. ... print('*', end=' ')
  475. ... g.purge()
  476. * * * * * * * * * * * * * * * * * * * * * *
  477. Tests for mapping from syntax to semantics
  478. ------------------------------------------
  479. Load a valuation from a file.
  480. >>> import nltk.data
  481. >>> from nltk.sem.util import parse_sents
  482. >>> val = nltk.data.load('grammars/sample_grammars/valuation1.val')
  483. >>> dom = val.domain
  484. >>> m = Model(dom, val)
  485. >>> g = Assignment(dom)
  486. >>> gramfile = 'grammars/sample_grammars/sem2.fcfg'
  487. >>> inputs = ['John sees a girl', 'every dog barks']
  488. >>> parses = parse_sents(inputs, gramfile)
  489. >>> for sent, trees in zip(inputs, parses):
  490. ... print()
  491. ... print("Sentence: %s" % sent)
  492. ... for tree in trees:
  493. ... print("Parse:\n %s" %tree)
  494. ... print("Semantics: %s" % root_semrep(tree))
  495. <BLANKLINE>
  496. Sentence: John sees a girl
  497. Parse:
  498. (S[SEM=<exists x.(girl(x) & see(john,x))>]
  499. (NP[-LOC, NUM='sg', SEM=<\P.P(john)>]
  500. (PropN[-LOC, NUM='sg', SEM=<\P.P(john)>] John))
  501. (VP[NUM='sg', SEM=<\y.exists x.(girl(x) & see(y,x))>]
  502. (TV[NUM='sg', SEM=<\X y.X(\x.see(y,x))>, TNS='pres'] sees)
  503. (NP[NUM='sg', SEM=<\Q.exists x.(girl(x) & Q(x))>]
  504. (Det[NUM='sg', SEM=<\P Q.exists x.(P(x) & Q(x))>] a)
  505. (Nom[NUM='sg', SEM=<\x.girl(x)>]
  506. (N[NUM='sg', SEM=<\x.girl(x)>] girl)))))
  507. Semantics: exists x.(girl(x) & see(john,x))
  508. <BLANKLINE>
  509. Sentence: every dog barks
  510. Parse:
  511. (S[SEM=<all x.(dog(x) -> bark(x))>]
  512. (NP[NUM='sg', SEM=<\Q.all x.(dog(x) -> Q(x))>]
  513. (Det[NUM='sg', SEM=<\P Q.all x.(P(x) -> Q(x))>] every)
  514. (Nom[NUM='sg', SEM=<\x.dog(x)>]
  515. (N[NUM='sg', SEM=<\x.dog(x)>] dog)))
  516. (VP[NUM='sg', SEM=<\x.bark(x)>]
  517. (IV[NUM='sg', SEM=<\x.bark(x)>, TNS='pres'] barks)))
  518. Semantics: all x.(dog(x) -> bark(x))
  519. >>> sent = "every dog barks"
  520. >>> result = nltk.sem.util.interpret_sents([sent], gramfile)[0]
  521. >>> for (syntree, semrep) in result:
  522. ... print(syntree)
  523. ... print()
  524. ... print(semrep)
  525. (S[SEM=<all x.(dog(x) -> bark(x))>]
  526. (NP[NUM='sg', SEM=<\Q.all x.(dog(x) -> Q(x))>]
  527. (Det[NUM='sg', SEM=<\P Q.all x.(P(x) -> Q(x))>] every)
  528. (Nom[NUM='sg', SEM=<\x.dog(x)>]
  529. (N[NUM='sg', SEM=<\x.dog(x)>] dog)))
  530. (VP[NUM='sg', SEM=<\x.bark(x)>]
  531. (IV[NUM='sg', SEM=<\x.bark(x)>, TNS='pres'] barks)))
  532. <BLANKLINE>
  533. all x.(dog(x) -> bark(x))
  534. >>> result = nltk.sem.util.evaluate_sents([sent], gramfile, m, g)[0]
  535. >>> for (syntree, semrel, value) in result:
  536. ... print(syntree)
  537. ... print()
  538. ... print(semrep)
  539. ... print()
  540. ... print(value)
  541. (S[SEM=<all x.(dog(x) -> bark(x))>]
  542. (NP[NUM='sg', SEM=<\Q.all x.(dog(x) -> Q(x))>]
  543. (Det[NUM='sg', SEM=<\P Q.all x.(P(x) -> Q(x))>] every)
  544. (Nom[NUM='sg', SEM=<\x.dog(x)>]
  545. (N[NUM='sg', SEM=<\x.dog(x)>] dog)))
  546. (VP[NUM='sg', SEM=<\x.bark(x)>]
  547. (IV[NUM='sg', SEM=<\x.bark(x)>, TNS='pres'] barks)))
  548. <BLANKLINE>
  549. all x.(dog(x) -> bark(x))
  550. <BLANKLINE>
  551. True
  552. >>> sents = ['Mary walks', 'John sees a dog']
  553. >>> results = nltk.sem.util.interpret_sents(sents, 'grammars/sample_grammars/sem2.fcfg')
  554. >>> for result in results:
  555. ... for (synrep, semrep) in result:
  556. ... print(synrep)
  557. (S[SEM=<walk(mary)>]
  558. (NP[-LOC, NUM='sg', SEM=<\P.P(mary)>]
  559. (PropN[-LOC, NUM='sg', SEM=<\P.P(mary)>] Mary))
  560. (VP[NUM='sg', SEM=<\x.walk(x)>]
  561. (IV[NUM='sg', SEM=<\x.walk(x)>, TNS='pres'] walks)))
  562. (S[SEM=<exists x.(dog(x) & see(john,x))>]
  563. (NP[-LOC, NUM='sg', SEM=<\P.P(john)>]
  564. (PropN[-LOC, NUM='sg', SEM=<\P.P(john)>] John))
  565. (VP[NUM='sg', SEM=<\y.exists x.(dog(x) & see(y,x))>]
  566. (TV[NUM='sg', SEM=<\X y.X(\x.see(y,x))>, TNS='pres'] sees)
  567. (NP[NUM='sg', SEM=<\Q.exists x.(dog(x) & Q(x))>]
  568. (Det[NUM='sg', SEM=<\P Q.exists x.(P(x) & Q(x))>] a)
  569. (Nom[NUM='sg', SEM=<\x.dog(x)>]
  570. (N[NUM='sg', SEM=<\x.dog(x)>] dog)))))
  571. Cooper Storage
  572. --------------
  573. >>> from nltk.sem import cooper_storage as cs
  574. >>> sentence = 'every girl chases a dog'
  575. >>> trees = cs.parse_with_bindops(sentence, grammar='grammars/book_grammars/storage.fcfg')
  576. >>> semrep = trees[0].label()['SEM']
  577. >>> cs_semrep = cs.CooperStore(semrep)
  578. >>> print(cs_semrep.core)
  579. chase(z2,z4)
  580. >>> for bo in cs_semrep.store:
  581. ... print(bo)
  582. bo(\P.all x.(girl(x) -> P(x)),z2)
  583. bo(\P.exists x.(dog(x) & P(x)),z4)
  584. >>> cs_semrep.s_retrieve(trace=True)
  585. Permutation 1
  586. (\P.all x.(girl(x) -> P(x)))(\z2.chase(z2,z4))
  587. (\P.exists x.(dog(x) & P(x)))(\z4.all x.(girl(x) -> chase(x,z4)))
  588. Permutation 2
  589. (\P.exists x.(dog(x) & P(x)))(\z4.chase(z2,z4))
  590. (\P.all x.(girl(x) -> P(x)))(\z2.exists x.(dog(x) & chase(z2,x)))
  591. >>> for reading in cs_semrep.readings:
  592. ... print(reading)
  593. exists x.(dog(x) & all z3.(girl(z3) -> chase(z3,x)))
  594. all x.(girl(x) -> exists z4.(dog(z4) & chase(x,z4)))