nltk 3.2__zip → 3.3__zip

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (406) hide show
  1. {nltk-3.2 → nltk-3.3}/INSTALL.txt +6 -6
  2. {nltk-3.2 → nltk-3.3}/LICENSE.txt +13 -13
  3. {nltk-3.2 → nltk-3.3}/MANIFEST.in +6 -6
  4. {nltk-3.2/nltk.egg-info → nltk-3.3}/PKG-INFO +13 -5
  5. nltk-3.2/README.txt → nltk-3.3/README.md +49 -48
  6. nltk-3.3/nltk/VERSION +1 -0
  7. {nltk-3.2 → nltk-3.3}/nltk/__init__.py +185 -185
  8. {nltk-3.2 → nltk-3.3}/nltk/app/__init__.py +52 -53
  9. {nltk-3.2 → nltk-3.3}/nltk/app/chartparser_app.py +2276 -2276
  10. {nltk-3.2 → nltk-3.3}/nltk/app/chunkparser_app.py +1262 -1264
  11. {nltk-3.2 → nltk-3.3}/nltk/app/collocations_app.py +347 -350
  12. {nltk-3.2 → nltk-3.3}/nltk/app/concordance_app.py +568 -570
  13. {nltk-3.2 → nltk-3.3}/nltk/app/nemo_app.py +156 -155
  14. {nltk-3.2 → nltk-3.3}/nltk/app/rdparser_app.py +892 -894
  15. {nltk-3.2 → nltk-3.3}/nltk/app/srparser_app.py +809 -809
  16. {nltk-3.2 → nltk-3.3}/nltk/app/wordfreq_app.py +32 -32
  17. {nltk-3.2 → nltk-3.3}/nltk/app/wordnet_app.py +968 -968
  18. {nltk-3.2 → nltk-3.3}/nltk/book.py +91 -90
  19. {nltk-3.2 → nltk-3.3}/nltk/ccg/__init__.py +22 -22
  20. {nltk-3.2 → nltk-3.3}/nltk/ccg/api.py +359 -335
  21. {nltk-3.2 → nltk-3.3}/nltk/ccg/chart.py +394 -361
  22. {nltk-3.2 → nltk-3.3}/nltk/ccg/combinator.py +343 -312
  23. {nltk-3.2 → nltk-3.3}/nltk/ccg/lexicon.py +328 -290
  24. nltk-3.3/nltk/ccg/logic.py +46 -0
  25. {nltk-3.2 → nltk-3.3}/nltk/chat/__init__.py +49 -49
  26. {nltk-3.2 → nltk-3.3}/nltk/chat/eliza.py +244 -244
  27. {nltk-3.2 → nltk-3.3}/nltk/chat/iesha.py +140 -140
  28. {nltk-3.2 → nltk-3.3}/nltk/chat/rude.py +92 -92
  29. {nltk-3.2 → nltk-3.3}/nltk/chat/suntsu.py +117 -117
  30. {nltk-3.2 → nltk-3.3}/nltk/chat/util.py +122 -120
  31. {nltk-3.2 → nltk-3.3}/nltk/chat/zen.py +282 -282
  32. {nltk-3.2 → nltk-3.3}/nltk/chunk/__init__.py +190 -190
  33. {nltk-3.2 → nltk-3.3}/nltk/chunk/api.py +51 -51
  34. {nltk-3.2 → nltk-3.3}/nltk/chunk/named_entity.py +331 -331
  35. {nltk-3.2 → nltk-3.3}/nltk/chunk/regexp.py +1390 -1384
  36. {nltk-3.2 → nltk-3.3}/nltk/chunk/util.py +600 -600
  37. {nltk-3.2 → nltk-3.3}/nltk/classify/__init__.py +98 -98
  38. {nltk-3.2 → nltk-3.3}/nltk/classify/api.py +193 -193
  39. {nltk-3.2 → nltk-3.3}/nltk/classify/decisiontree.py +295 -295
  40. {nltk-3.2 → nltk-3.3}/nltk/classify/maxent.py +1510 -1492
  41. {nltk-3.2 → nltk-3.3}/nltk/classify/megam.py +179 -178
  42. {nltk-3.2 → nltk-3.3}/nltk/classify/naivebayes.py +245 -242
  43. {nltk-3.2 → nltk-3.3}/nltk/classify/positivenaivebayes.py +170 -170
  44. {nltk-3.2 → nltk-3.3}/nltk/classify/rte_classify.py +160 -191
  45. {nltk-3.2 → nltk-3.3}/nltk/classify/scikitlearn.py +153 -151
  46. {nltk-3.2 → nltk-3.3}/nltk/classify/senna.py +183 -181
  47. {nltk-3.2 → nltk-3.3}/nltk/classify/svm.py +15 -15
  48. {nltk-3.2 → nltk-3.3}/nltk/classify/tadm.py +113 -112
  49. {nltk-3.2 → nltk-3.3}/nltk/classify/textcat.py +193 -193
  50. {nltk-3.2 → nltk-3.3}/nltk/classify/util.py +324 -312
  51. {nltk-3.2 → nltk-3.3}/nltk/classify/weka.py +346 -345
  52. {nltk-3.2 → nltk-3.3}/nltk/cluster/__init__.py +86 -86
  53. {nltk-3.2 → nltk-3.3}/nltk/cluster/api.py +74 -70
  54. {nltk-3.2 → nltk-3.3}/nltk/cluster/em.py +247 -247
  55. {nltk-3.2 → nltk-3.3}/nltk/cluster/gaac.py +168 -168
  56. {nltk-3.2 → nltk-3.3}/nltk/cluster/kmeans.py +221 -221
  57. {nltk-3.2 → nltk-3.3}/nltk/cluster/util.py +304 -289
  58. nltk-3.3/nltk/collections.py +640 -0
  59. {nltk-3.2 → nltk-3.3}/nltk/collocations.py +388 -388
  60. nltk-3.3/nltk/compat.py +365 -0
  61. {nltk-3.2 → nltk-3.3}/nltk/corpus/__init__.py +341 -320
  62. {nltk-3.2 → nltk-3.3}/nltk/corpus/europarl_raw.py +44 -44
  63. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/__init__.py +147 -145
  64. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/aligned.py +115 -114
  65. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/api.py +448 -446
  66. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/bnc.py +252 -252
  67. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/bracket_parse.py +227 -227
  68. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/categorized_sents.py +179 -178
  69. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/chasen.py +140 -139
  70. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/childes.py +522 -494
  71. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/chunked.py +212 -212
  72. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/cmudict.py +97 -95
  73. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/comparative_sents.py +280 -278
  74. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/conll.py +528 -521
  75. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/crubadan.py +116 -116
  76. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/dependency.py +101 -101
  77. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/framenet.py +3059 -2093
  78. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/ieer.py +112 -111
  79. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/indian.py +85 -86
  80. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/ipipan.py +332 -331
  81. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/knbc.py +187 -187
  82. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/lin.py +156 -156
  83. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/mte.py +311 -310
  84. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/nkjp.py +429 -428
  85. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/nombank.py +421 -421
  86. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/nps_chat.py +73 -73
  87. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/opinion_lexicon.py +115 -115
  88. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/panlex_lite.py +165 -165
  89. nltk-3.3/nltk/corpus/reader/pl196x.py +292 -0
  90. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/plaintext.py +232 -233
  91. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/ppattach.py +96 -95
  92. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/propbank.py +479 -481
  93. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/pros_cons.py +128 -126
  94. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/reviews.py +330 -328
  95. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/rte.py +144 -146
  96. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/semcor.py +256 -256
  97. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/senseval.py +203 -201
  98. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/sentiwordnet.py +137 -137
  99. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/sinica_treebank.py +75 -75
  100. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/string_category.py +60 -59
  101. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/switchboard.py +119 -119
  102. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/tagged.py +295 -294
  103. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/timit.py +452 -450
  104. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/toolbox.py +68 -68
  105. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/twitter.py +155 -157
  106. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/udhr.py +80 -80
  107. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/util.py +804 -800
  108. nltk-3.3/nltk/corpus/reader/verbnet.py +595 -0
  109. nltk-3.3/nltk/corpus/reader/wordlist.py +134 -0
  110. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/wordnet.py +2108 -2036
  111. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/xmldocs.py +392 -387
  112. {nltk-3.2 → nltk-3.3}/nltk/corpus/reader/ycoe.py +243 -242
  113. {nltk-3.2 → nltk-3.3}/nltk/corpus/util.py +144 -127
  114. {nltk-3.2 → nltk-3.3}/nltk/data.py +1487 -1451
  115. {nltk-3.2 → nltk-3.3}/nltk/decorators.py +219 -215
  116. {nltk-3.2 → nltk-3.3}/nltk/downloader.py +2278 -2274
  117. {nltk-3.2 → nltk-3.3}/nltk/draw/__init__.py +27 -27
  118. {nltk-3.2 → nltk-3.3}/nltk/draw/cfg.py +774 -777
  119. {nltk-3.2 → nltk-3.3}/nltk/draw/dispersion.py +58 -58
  120. {nltk-3.2 → nltk-3.3}/nltk/draw/table.py +1098 -1098
  121. {nltk-3.2 → nltk-3.3}/nltk/draw/tree.py +963 -966
  122. {nltk-3.2 → nltk-3.3}/nltk/draw/util.py +2356 -2356
  123. {nltk-3.2 → nltk-3.3}/nltk/featstruct.py +2617 -2500
  124. {nltk-3.2 → nltk-3.3}/nltk/grammar.py +1559 -1516
  125. {nltk-3.2 → nltk-3.3}/nltk/help.py +56 -56
  126. {nltk-3.2 → nltk-3.3}/nltk/inference/__init__.py +20 -20
  127. {nltk-3.2 → nltk-3.3}/nltk/inference/api.py +597 -589
  128. {nltk-3.2 → nltk-3.3}/nltk/inference/discourse.py +612 -608
  129. {nltk-3.2 → nltk-3.3}/nltk/inference/mace.py +311 -311
  130. {nltk-3.2 → nltk-3.3}/nltk/inference/nonmonotonic.py +509 -509
  131. {nltk-3.2 → nltk-3.3}/nltk/inference/prover9.py +431 -431
  132. {nltk-3.2 → nltk-3.3}/nltk/inference/resolution.py +687 -687
  133. {nltk-3.2 → nltk-3.3}/nltk/inference/tableau.py +607 -607
  134. {nltk-3.2 → nltk-3.3}/nltk/internals.py +982 -982
  135. {nltk-3.2 → nltk-3.3}/nltk/jsontags.py +63 -63
  136. {nltk-3.2 → nltk-3.3}/nltk/lazyimport.py +142 -142
  137. {nltk-3.2 → nltk-3.3}/nltk/metrics/__init__.py +30 -29
  138. {nltk-3.2 → nltk-3.3}/nltk/metrics/agreement.py +421 -401
  139. nltk-3.3/nltk/metrics/aline.py +607 -0
  140. {nltk-3.2 → nltk-3.3}/nltk/metrics/association.py +414 -410
  141. {nltk-3.2 → nltk-3.3}/nltk/metrics/confusionmatrix.py +206 -206
  142. {nltk-3.2 → nltk-3.3}/nltk/metrics/distance.py +207 -202
  143. {nltk-3.2 → nltk-3.3}/nltk/metrics/paice.py +381 -381
  144. {nltk-3.2 → nltk-3.3}/nltk/metrics/scores.py +228 -228
  145. {nltk-3.2 → nltk-3.3}/nltk/metrics/segmentation.py +231 -232
  146. {nltk-3.2 → nltk-3.3}/nltk/metrics/spearman.py +69 -69
  147. {nltk-3.2 → nltk-3.3}/nltk/misc/__init__.py +11 -11
  148. {nltk-3.2 → nltk-3.3}/nltk/misc/babelfish.py +10 -10
  149. {nltk-3.2 → nltk-3.3}/nltk/misc/chomsky.py +135 -133
  150. {nltk-3.2 → nltk-3.3}/nltk/misc/minimalset.py +83 -83
  151. {nltk-3.2 → nltk-3.3}/nltk/misc/sort.py +157 -157
  152. {nltk-3.2 → nltk-3.3}/nltk/misc/wordfinder.py +129 -129
  153. {nltk-3.2 → nltk-3.3}/nltk/parse/__init__.py +81 -80
  154. {nltk-3.2 → nltk-3.3}/nltk/parse/api.py +66 -66
  155. {nltk-3.2 → nltk-3.3}/nltk/parse/bllip.py +282 -282
  156. {nltk-3.2 → nltk-3.3}/nltk/parse/chart.py +1682 -1681
  157. nltk-3.3/nltk/parse/corenlp.py +780 -0
  158. {nltk-3.2 → nltk-3.3}/nltk/parse/dependencygraph.py +760 -758
  159. {nltk-3.2 → nltk-3.3}/nltk/parse/earleychart.py +452 -451
  160. {nltk-3.2 → nltk-3.3}/nltk/parse/evaluate.py +129 -129
  161. {nltk-3.2 → nltk-3.3}/nltk/parse/featurechart.py +580 -578
  162. {nltk-3.2 → nltk-3.3}/nltk/parse/generate.py +87 -76
  163. {nltk-3.2 → nltk-3.3}/nltk/parse/malt.py +356 -356
  164. {nltk-3.2 → nltk-3.3}/nltk/parse/nonprojectivedependencyparser.py +783 -783
  165. {nltk-3.2 → nltk-3.3}/nltk/parse/pchart.py +522 -522
  166. {nltk-3.2 → nltk-3.3}/nltk/parse/projectivedependencyparser.py +579 -578
  167. {nltk-3.2 → nltk-3.3}/nltk/parse/recursivedescent.py +655 -656
  168. {nltk-3.2 → nltk-3.3}/nltk/parse/shiftreduce.py +458 -459
  169. {nltk-3.2 → nltk-3.3}/nltk/parse/stanford.py +431 -406
  170. {nltk-3.2 → nltk-3.3}/nltk/parse/transitionparser.py +774 -772
  171. {nltk-3.2 → nltk-3.3}/nltk/parse/util.py +231 -231
  172. {nltk-3.2 → nltk-3.3}/nltk/parse/viterbi.py +401 -401
  173. {nltk-3.2 → nltk-3.3}/nltk/probability.py +2410 -2355
  174. {nltk-3.2 → nltk-3.3}/nltk/sem/__init__.py +61 -61
  175. {nltk-3.2 → nltk-3.3}/nltk/sem/boxer.py +1261 -1261
  176. {nltk-3.2 → nltk-3.3}/nltk/sem/chat80.py +782 -782
  177. {nltk-3.2 → nltk-3.3}/nltk/sem/cooper_storage.py +118 -118
  178. {nltk-3.2 → nltk-3.3}/nltk/sem/drt.py +1258 -1257
  179. {nltk-3.2 → nltk-3.3}/nltk/sem/drt_glue_demo.py +485 -489
  180. {nltk-3.2 → nltk-3.3}/nltk/sem/evaluate.py +790 -784
  181. {nltk-3.2 → nltk-3.3}/nltk/sem/glue.py +696 -694
  182. {nltk-3.2 → nltk-3.3}/nltk/sem/hole.py +386 -384
  183. {nltk-3.2 → nltk-3.3}/nltk/sem/lfg.py +210 -208
  184. {nltk-3.2 → nltk-3.3}/nltk/sem/linearlogic.py +451 -449
  185. {nltk-3.2 → nltk-3.3}/nltk/sem/logic.py +1910 -1910
  186. {nltk-3.2 → nltk-3.3}/nltk/sem/relextract.py +476 -483
  187. {nltk-3.2 → nltk-3.3}/nltk/sem/skolemize.py +101 -101
  188. {nltk-3.2 → nltk-3.3}/nltk/sem/util.py +249 -249
  189. {nltk-3.2 → nltk-3.3}/nltk/sentiment/__init__.py +14 -14
  190. {nltk-3.2 → nltk-3.3}/nltk/sentiment/sentiment_analyzer.py +229 -229
  191. {nltk-3.2 → nltk-3.3}/nltk/sentiment/util.py +762 -752
  192. {nltk-3.2 → nltk-3.3}/nltk/sentiment/vader.py +443 -445
  193. {nltk-3.2 → nltk-3.3}/nltk/stem/__init__.py +31 -33
  194. {nltk-3.2 → nltk-3.3}/nltk/stem/api.py +28 -25
  195. nltk-3.3/nltk/stem/arlstem.py +369 -0
  196. {nltk-3.2 → nltk-3.3}/nltk/stem/isri.py +345 -345
  197. {nltk-3.2 → nltk-3.3}/nltk/stem/lancaster.py +337 -310
  198. nltk-3.3/nltk/stem/porter.py +710 -0
  199. {nltk-3.2 → nltk-3.3}/nltk/stem/regexp.py +61 -61
  200. {nltk-3.2 → nltk-3.3}/nltk/stem/rslp.py +142 -142
  201. {nltk-3.2 → nltk-3.3}/nltk/stem/snowball.py +4236 -3712
  202. {nltk-3.2 → nltk-3.3}/nltk/stem/util.py +22 -12
  203. {nltk-3.2 → nltk-3.3}/nltk/stem/wordnet.py +51 -51
  204. {nltk-3.2 → nltk-3.3}/nltk/tag/__init__.py +152 -127
  205. {nltk-3.2 → nltk-3.3}/nltk/tag/api.py +86 -81
  206. {nltk-3.2 → nltk-3.3}/nltk/tag/brill.py +424 -426
  207. {nltk-3.2 → nltk-3.3}/nltk/tag/brill_trainer.py +608 -608
  208. {nltk-3.2 → nltk-3.3}/nltk/tag/crf.py +204 -200
  209. {nltk-3.2 → nltk-3.3}/nltk/tag/hmm.py +1277 -1277
  210. {nltk-3.2 → nltk-3.3}/nltk/tag/hunpos.py +132 -132
  211. {nltk-3.2 → nltk-3.3}/nltk/tag/mapping.py +101 -101
  212. {nltk-3.2 → nltk-3.3}/nltk/tag/perceptron.py +329 -314
  213. {nltk-3.2 → nltk-3.3}/nltk/tag/senna.py +147 -145
  214. {nltk-3.2 → nltk-3.3}/nltk/tag/sequential.py +740 -736
  215. {nltk-3.2 → nltk-3.3}/nltk/tag/stanford.py +219 -196
  216. {nltk-3.2 → nltk-3.3}/nltk/tag/tnt.py +595 -604
  217. {nltk-3.2 → nltk-3.3}/nltk/tag/util.py +72 -72
  218. {nltk-3.2 → nltk-3.3}/nltk/tbl/__init__.py +28 -28
  219. {nltk-3.2 → nltk-3.3}/nltk/tbl/api.py +1 -1
  220. {nltk-3.2 → nltk-3.3}/nltk/tbl/demo.py +366 -366
  221. {nltk-3.2 → nltk-3.3}/nltk/tbl/erroranalysis.py +39 -39
  222. {nltk-3.2 → nltk-3.3}/nltk/tbl/feature.py +259 -261
  223. {nltk-3.2 → nltk-3.3}/nltk/tbl/rule.py +321 -321
  224. {nltk-3.2 → nltk-3.3}/nltk/tbl/template.py +303 -308
  225. {nltk-3.2 → nltk-3.3}/nltk/test/__init__.py +18 -18
  226. {nltk-3.2 → nltk-3.3}/nltk/test/all.py +24 -23
  227. {nltk-3.2 → nltk-3.3}/nltk/test/bleu.doctest +14 -14
  228. {nltk-3.2 → nltk-3.3}/nltk/test/bnc.doctest +60 -60
  229. {nltk-3.2 → nltk-3.3}/nltk/test/ccg.doctest +376 -395
  230. nltk-3.3/nltk/test/ccg_semantics.doctest +553 -0
  231. {nltk-3.2 → nltk-3.3}/nltk/test/chat80.doctest +234 -234
  232. {nltk-3.2 → nltk-3.3}/nltk/test/childes.doctest +184 -184
  233. {nltk-3.2 → nltk-3.3}/nltk/test/childes_fixt.py +14 -13
  234. {nltk-3.2 → nltk-3.3}/nltk/test/chunk.doctest +373 -373
  235. {nltk-3.2 → nltk-3.3}/nltk/test/classify.doctest +185 -185
  236. {nltk-3.2 → nltk-3.3}/nltk/test/classify_fixt.py +11 -10
  237. nltk-3.3/nltk/test/collections.doctest +20 -0
  238. {nltk-3.2 → nltk-3.3}/nltk/test/collocations.doctest +276 -276
  239. {nltk-3.2 → nltk-3.3}/nltk/test/compat.doctest +134 -138
  240. {nltk-3.2 → nltk-3.3}/nltk/test/compat_fixt.py +9 -8
  241. nltk-3.3/nltk/test/concordance.doctest +55 -0
  242. {nltk-3.2 → nltk-3.3}/nltk/test/corpus.doctest +2200 -2212
  243. {nltk-3.2 → nltk-3.3}/nltk/test/corpus_fixt.py +3 -3
  244. {nltk-3.2 → nltk-3.3}/nltk/test/crubadan.doctest +65 -65
  245. {nltk-3.2 → nltk-3.3}/nltk/test/data.doctest +379 -379
  246. {nltk-3.2 → nltk-3.3}/nltk/test/dependency.doctest +241 -241
  247. {nltk-3.2 → nltk-3.3}/nltk/test/discourse.doctest +546 -546
  248. {nltk-3.2 → nltk-3.3}/nltk/test/discourse_fixt.py +14 -13
  249. {nltk-3.2 → nltk-3.3}/nltk/test/doctest_nose_plugin.py +159 -156
  250. {nltk-3.2 → nltk-3.3}/nltk/test/drt.doctest +517 -517
  251. {nltk-3.2 → nltk-3.3}/nltk/test/featgram.doctest +607 -607
  252. {nltk-3.2 → nltk-3.3}/nltk/test/featstruct.doctest +1229 -1230
  253. {nltk-3.2 → nltk-3.3}/nltk/test/framenet.doctest +288 -239
  254. {nltk-3.2 → nltk-3.3}/nltk/test/generate.doctest +67 -67
  255. {nltk-3.2 → nltk-3.3}/nltk/test/gensim.doctest +140 -141
  256. {nltk-3.2 → nltk-3.3}/nltk/test/gensim_fixt.py +10 -9
  257. {nltk-3.2 → nltk-3.3}/nltk/test/gluesemantics.doctest +384 -386
  258. {nltk-3.2 → nltk-3.3}/nltk/test/gluesemantics_malt.doctest +68 -68
  259. {nltk-3.2 → nltk-3.3}/nltk/test/gluesemantics_malt_fixt.py +12 -11
  260. {nltk-3.2 → nltk-3.3}/nltk/test/grammar.doctest +48 -48
  261. {nltk-3.2 → nltk-3.3}/nltk/test/grammartestsuites.doctest +109 -109
  262. {nltk-3.2 → nltk-3.3}/nltk/test/index.doctest +100 -100
  263. {nltk-3.2 → nltk-3.3}/nltk/test/inference.doctest +534 -534
  264. {nltk-3.2 → nltk-3.3}/nltk/test/inference_fixt.py +12 -11
  265. {nltk-3.2 → nltk-3.3}/nltk/test/internals.doctest +140 -140
  266. {nltk-3.2 → nltk-3.3}/nltk/test/japanese.doctest +48 -48
  267. {nltk-3.2 → nltk-3.3}/nltk/test/logic.doctest +1098 -1098
  268. {nltk-3.2 → nltk-3.3}/nltk/test/metrics.doctest +270 -270
  269. {nltk-3.2 → nltk-3.3}/nltk/test/misc.doctest +118 -118
  270. {nltk-3.2 → nltk-3.3}/nltk/test/nonmonotonic.doctest +286 -286
  271. {nltk-3.2 → nltk-3.3}/nltk/test/nonmonotonic_fixt.py +12 -11
  272. {nltk-3.2 → nltk-3.3}/nltk/test/paice.doctest +35 -35
  273. {nltk-3.2 → nltk-3.3}/nltk/test/parse.doctest +884 -884
  274. {nltk-3.2 → nltk-3.3}/nltk/test/portuguese_en.doctest +565 -565
  275. {nltk-3.2 → nltk-3.3}/nltk/test/portuguese_en_fixt.py +16 -16
  276. {nltk-3.2 → nltk-3.3}/nltk/test/probability.doctest +304 -304
  277. {nltk-3.2 → nltk-3.3}/nltk/test/probability_fixt.py +13 -12
  278. {nltk-3.2 → nltk-3.3}/nltk/test/propbank.doctest +176 -176
  279. {nltk-3.2 → nltk-3.3}/nltk/test/relextract.doctest +263 -263
  280. {nltk-3.2 → nltk-3.3}/nltk/test/resolution.doctest +221 -221
  281. {nltk-3.2 → nltk-3.3}/nltk/test/runtests.py +86 -64
  282. {nltk-3.2 → nltk-3.3}/nltk/test/segmentation_fixt.py +10 -10
  283. {nltk-3.2 → nltk-3.3}/nltk/test/semantics.doctest +665 -665
  284. {nltk-3.2 → nltk-3.3}/nltk/test/semantics_fixt.py +7 -7
  285. {nltk-3.2 → nltk-3.3}/nltk/test/sentiment.doctest +233 -233
  286. {nltk-3.2 → nltk-3.3}/nltk/test/sentiwordnet.doctest +41 -41
  287. {nltk-3.2 → nltk-3.3}/nltk/test/simple.doctest +85 -85
  288. {nltk-3.2 → nltk-3.3}/nltk/test/stem.doctest +78 -78
  289. {nltk-3.2 → nltk-3.3}/nltk/test/tag.doctest +33 -33
  290. {nltk-3.2 → nltk-3.3}/nltk/test/tokenize.doctest +273 -166
  291. {nltk-3.2 → nltk-3.3}/nltk/test/toolbox.doctest +307 -307
  292. {nltk-3.2 → nltk-3.3}/nltk/test/translate.doctest +242 -242
  293. {nltk-3.2 → nltk-3.3}/nltk/test/translate_fixt.py +3 -3
  294. {nltk-3.2 → nltk-3.3}/nltk/test/tree.doctest +1101 -1101
  295. {nltk-3.2 → nltk-3.3}/nltk/test/treeprettyprinter.doctest +127 -127
  296. {nltk-3.2 → nltk-3.3}/nltk/test/treetransforms.doctest +156 -156
  297. nltk-3.3/nltk/test/unit/test_2x_compat.py +63 -0
  298. nltk-3.3/nltk/test/unit/test_aline.py +52 -0
  299. nltk-3.3/nltk/test/unit/test_chunk.py +56 -0
  300. {nltk-3.2 → nltk-3.3}/nltk/test/unit/test_classify.py +55 -53
  301. {nltk-3.2 → nltk-3.3}/nltk/test/unit/test_collocations.py +88 -79
  302. nltk-3.3/nltk/test/unit/test_concordance.py +98 -0
  303. nltk-3.3/nltk/test/unit/test_corenlp.py +1000 -0
  304. {nltk-3.2 → nltk-3.3}/nltk/test/unit/test_corpora.py +200 -183
  305. {nltk-3.2 → nltk-3.3}/nltk/test/unit/test_corpus_views.py +45 -45
  306. {nltk-3.2 → nltk-3.3}/nltk/test/unit/test_hmm.py +88 -88
  307. {nltk-3.2 → nltk-3.3}/nltk/test/unit/test_json2csv_corpus.py +188 -187
  308. {nltk-3.2 → nltk-3.3}/nltk/test/unit/test_naivebayes.py +26 -26
  309. nltk-3.3/nltk/test/unit/test_rte_classify.py +86 -0
  310. {nltk-3.2 → nltk-3.3}/nltk/test/unit/test_seekable_unicode_stream_reader.py +124 -124
  311. nltk-3.3/nltk/test/unit/test_senna.py +74 -0
  312. nltk-3.3/nltk/test/unit/test_stem.py +121 -0
  313. {nltk-3.2 → nltk-3.3}/nltk/test/unit/test_tag.py +20 -20
  314. {nltk-3.2 → nltk-3.3}/nltk/test/unit/test_tgrep.py +628 -626
  315. nltk-3.3/nltk/test/unit/test_tokenize.py +168 -0
  316. {nltk-3.2 → nltk-3.3}/nltk/test/unit/test_twitter_auth.py +185 -185
  317. nltk-3.3/nltk/test/unit/test_wordnet.py +134 -0
  318. nltk-3.3/nltk/test/unit/translate/test_bleu.py +244 -0
  319. nltk-3.3/nltk/test/unit/translate/test_gdfa.py +57 -0
  320. {nltk-3.2 → nltk-3.3}/nltk/test/unit/translate/test_ibm1.py +75 -75
  321. {nltk-3.2 → nltk-3.3}/nltk/test/unit/translate/test_ibm2.py +87 -87
  322. {nltk-3.2 → nltk-3.3}/nltk/test/unit/translate/test_ibm3.py +105 -105
  323. {nltk-3.2 → nltk-3.3}/nltk/test/unit/translate/test_ibm4.py +126 -126
  324. {nltk-3.2 → nltk-3.3}/nltk/test/unit/translate/test_ibm5.py +166 -166
  325. {nltk-3.2 → nltk-3.3}/nltk/test/unit/translate/test_ibm_model.py +270 -270
  326. nltk-3.3/nltk/test/unit/translate/test_nist.py +37 -0
  327. {nltk-3.2 → nltk-3.3}/nltk/test/unit/translate/test_stack_decoder.py +300 -300
  328. {nltk-3.2 → nltk-3.3}/nltk/test/unit/utils.py +41 -41
  329. {nltk-3.2 → nltk-3.3}/nltk/test/util.doctest +48 -48
  330. {nltk-3.2 → nltk-3.3}/nltk/test/wordnet.doctest +595 -581
  331. {nltk-3.2 → nltk-3.3}/nltk/test/wordnet_fixt.py +7 -6
  332. {nltk-3.2 → nltk-3.3}/nltk/test/wordnet_lch.doctest +53 -53
  333. {nltk-3.2 → nltk-3.3}/nltk/test/wsd.doctest +68 -68
  334. {nltk-3.2 → nltk-3.3}/nltk/text.py +663 -610
  335. {nltk-3.2 → nltk-3.3}/nltk/tgrep.py +938 -937
  336. {nltk-3.2 → nltk-3.3}/nltk/tokenize/__init__.py +130 -107
  337. {nltk-3.2 → nltk-3.3}/nltk/tokenize/api.py +77 -78
  338. {nltk-3.2 → nltk-3.3}/nltk/tokenize/casual.py +343 -342
  339. {nltk-3.2 → nltk-3.3}/nltk/tokenize/mwe.py +120 -120
  340. nltk-3.3/nltk/tokenize/nist.py +173 -0
  341. {nltk-3.2 → nltk-3.3}/nltk/tokenize/punkt.py +1620 -1601
  342. {nltk-3.2 → nltk-3.3}/nltk/tokenize/regexp.py +208 -202
  343. nltk-3.3/nltk/tokenize/repp.py +151 -0
  344. {nltk-3.2 → nltk-3.3}/nltk/tokenize/sexpr.py +140 -142
  345. {nltk-3.2 → nltk-3.3}/nltk/tokenize/simple.py +138 -136
  346. {nltk-3.2 → nltk-3.3}/nltk/tokenize/stanford.py +117 -113
  347. nltk-3.3/nltk/tokenize/stanford_segmenter.py +246 -0
  348. {nltk-3.2 → nltk-3.3}/nltk/tokenize/texttiling.py +458 -460
  349. nltk-3.3/nltk/tokenize/toktok.py +155 -0
  350. nltk-3.3/nltk/tokenize/treebank.py +363 -0
  351. nltk-3.3/nltk/tokenize/util.py +261 -0
  352. {nltk-3.2 → nltk-3.3}/nltk/toolbox.py +499 -497
  353. {nltk-3.2 → nltk-3.3}/nltk/translate/__init__.py +24 -24
  354. {nltk-3.2 → nltk-3.3}/nltk/translate/api.py +331 -321
  355. {nltk-3.2 → nltk-3.3}/nltk/translate/bleu_score.py +615 -556
  356. nltk-3.3/nltk/translate/chrf_score.py +137 -0
  357. {nltk-3.2 → nltk-3.3}/nltk/translate/gale_church.py +248 -235
  358. {nltk-3.2 → nltk-3.3}/nltk/translate/gdfa.py +135 -131
  359. nltk-3.3/nltk/translate/gleu_score.py +193 -0
  360. {nltk-3.2 → nltk-3.3}/nltk/translate/ibm1.py +250 -241
  361. {nltk-3.2 → nltk-3.3}/nltk/translate/ibm2.py +308 -308
  362. {nltk-3.2 → nltk-3.3}/nltk/translate/ibm3.py +337 -337
  363. {nltk-3.2 → nltk-3.3}/nltk/translate/ibm4.py +467 -467
  364. {nltk-3.2 → nltk-3.3}/nltk/translate/ibm5.py +639 -639
  365. {nltk-3.2 → nltk-3.3}/nltk/translate/ibm_model.py +536 -533
  366. {nltk-3.2 → nltk-3.3}/nltk/translate/metrics.py +40 -40
  367. nltk-3.3/nltk/translate/nist_score.py +178 -0
  368. {nltk-3.2 → nltk-3.3}/nltk/translate/phrase_based.py +175 -175
  369. {nltk-3.2 → nltk-3.3}/nltk/translate/ribes_score.py +325 -325
  370. {nltk-3.2 → nltk-3.3}/nltk/translate/stack_decoder.py +499 -495
  371. {nltk-3.2 → nltk-3.3}/nltk/tree.py +1605 -1603
  372. {nltk-3.2 → nltk-3.3}/nltk/treeprettyprinter.py +564 -564
  373. {nltk-3.2 → nltk-3.3}/nltk/treetransforms.py +309 -309
  374. {nltk-3.2 → nltk-3.3}/nltk/twitter/__init__.py +28 -28
  375. {nltk-3.2 → nltk-3.3}/nltk/twitter/api.py +141 -136
  376. {nltk-3.2 → nltk-3.3}/nltk/twitter/common.py +264 -258
  377. {nltk-3.2 → nltk-3.3}/nltk/twitter/twitter_demo.py +288 -288
  378. {nltk-3.2 → nltk-3.3}/nltk/twitter/twitterclient.py +530 -530
  379. {nltk-3.2 → nltk-3.3}/nltk/twitter/util.py +147 -146
  380. nltk-3.3/nltk/util.py +751 -0
  381. {nltk-3.2 → nltk-3.3}/nltk/wsd.py +53 -53
  382. {nltk-3.2 → nltk-3.3/nltk.egg-info}/PKG-INFO +13 -5
  383. {nltk-3.2 → nltk-3.3}/nltk.egg-info/SOURCES.txt +26 -3
  384. nltk-3.3/nltk.egg-info/requires.txt +31 -0
  385. {nltk-3.2 → nltk-3.3}/setup.cfg +0 -1
  386. {nltk-3.2 → nltk-3.3}/setup.py +102 -75
  387. nltk-3.2/nltk/VERSION +0 -1
  388. nltk-3.2/nltk/compat.py +0 -680
  389. nltk-3.2/nltk/corpus/reader/pl196x.py +0 -278
  390. nltk-3.2/nltk/corpus/reader/verbnet.py +0 -408
  391. nltk-3.2/nltk/corpus/reader/wordlist.py +0 -37
  392. nltk-3.2/nltk/sentiment/vader_lexicon.txt +0 -7517
  393. nltk-3.2/nltk/six.py +0 -868
  394. nltk-3.2/nltk/stem/porter.py +0 -692
  395. nltk-3.2/nltk/test/unit/test_2x_compat.py +0 -26
  396. nltk-3.2/nltk/test/unit/test_stem.py +0 -36
  397. nltk-3.2/nltk/test/unit/test_tokenize.py +0 -23
  398. nltk-3.2/nltk/test/unit/translate/test_bleu.py +0 -84
  399. nltk-3.2/nltk/tokenize/treebank.py +0 -124
  400. nltk-3.2/nltk/tokenize/util.py +0 -90
  401. nltk-3.2/nltk/util.py +0 -1364
  402. {nltk-3.2 → nltk-3.3}/nltk/test/unit/__init__.py +0 -0
  403. {nltk-3.2 → nltk-3.3}/nltk/test/unit/translate/__init__.py +0 -0
  404. {nltk-3.2 → nltk-3.3}/nltk.egg-info/dependency_links.txt +0 -0
  405. {nltk-3.2 → nltk-3.3}/nltk.egg-info/not-zip-safe +0 -0
  406. {nltk-3.2 → nltk-3.3}/nltk.egg-info/top_level.txt +0 -0
@@ -1,782 +1,782 @@
1
- # Natural Language Toolkit: Chat-80 KB Reader
2
- # See http://www.w3.org/TR/swbp-skos-core-guide/
3
- #
4
- # Copyright (C) 2001-2015 NLTK Project
5
- # Author: Ewan Klein <ewan@inf.ed.ac.uk>,
6
- # URL: <http://nltk.sourceforge.net>
7
- # For license information, see LICENSE.TXT
8
-
9
- """
10
- Overview
11
- ========
12
-
13
- Chat-80 was a natural language system which allowed the user to
14
- interrogate a Prolog knowledge base in the domain of world
15
- geography. It was developed in the early '80s by Warren and Pereira; see
16
- ``http://www.aclweb.org/anthology/J82-3002.pdf`` for a description and
17
- ``http://www.cis.upenn.edu/~pereira/oldies.html`` for the source
18
- files.
19
-
20
- This module contains functions to extract data from the Chat-80
21
- relation files ('the world database'), and convert then into a format
22
- that can be incorporated in the FOL models of
23
- ``nltk.sem.evaluate``. The code assumes that the Prolog
24
- input files are available in the NLTK corpora directory.
25
-
26
- The Chat-80 World Database consists of the following files::
27
-
28
- world0.pl
29
- rivers.pl
30
- cities.pl
31
- countries.pl
32
- contain.pl
33
- borders.pl
34
-
35
- This module uses a slightly modified version of ``world0.pl``, in which
36
- a set of Prolog rules have been omitted. The modified file is named
37
- ``world1.pl``. Currently, the file ``rivers.pl`` is not read in, since
38
- it uses a list rather than a string in the second field.
39
-
40
- Reading Chat-80 Files
41
- =====================
42
-
43
- Chat-80 relations are like tables in a relational database. The
44
- relation acts as the name of the table; the first argument acts as the
45
- 'primary key'; and subsequent arguments are further fields in the
46
- table. In general, the name of the table provides a label for a unary
47
- predicate whose extension is all the primary keys. For example,
48
- relations in ``cities.pl`` are of the following form::
49
-
50
- 'city(athens,greece,1368).'
51
-
52
- Here, ``'athens'`` is the key, and will be mapped to a member of the
53
- unary predicate *city*.
54
-
55
- The fields in the table are mapped to binary predicates. The first
56
- argument of the predicate is the primary key, while the second
57
- argument is the data in the relevant field. Thus, in the above
58
- example, the third field is mapped to the binary predicate
59
- *population_of*, whose extension is a set of pairs such as
60
- ``'(athens, 1368)'``.
61
-
62
- An exception to this general framework is required by the relations in
63
- the files ``borders.pl`` and ``contains.pl``. These contain facts of the
64
- following form::
65
-
66
- 'borders(albania,greece).'
67
-
68
- 'contains0(africa,central_africa).'
69
-
70
- We do not want to form a unary concept out the element in
71
- the first field of these records, and we want the label of the binary
72
- relation just to be ``'border'``/``'contain'`` respectively.
73
-
74
- In order to drive the extraction process, we use 'relation metadata bundles'
75
- which are Python dictionaries such as the following::
76
-
77
- city = {'label': 'city',
78
- 'closures': [],
79
- 'schema': ['city', 'country', 'population'],
80
- 'filename': 'cities.pl'}
81
-
82
- According to this, the file ``city['filename']`` contains a list of
83
- relational tuples (or more accurately, the corresponding strings in
84
- Prolog form) whose predicate symbol is ``city['label']`` and whose
85
- relational schema is ``city['schema']``. The notion of a ``closure`` is
86
- discussed in the next section.
87
-
88
- Concepts
89
- ========
90
- In order to encapsulate the results of the extraction, a class of
91
- ``Concept`` objects is introduced. A ``Concept`` object has a number of
92
- attributes, in particular a ``prefLabel`` and ``extension``, which make
93
- it easier to inspect the output of the extraction. In addition, the
94
- ``extension`` can be further processed: in the case of the ``'border'``
95
- relation, we check that the relation is symmetric, and in the case
96
- of the ``'contain'`` relation, we carry out the transitive
97
- closure. The closure properties associated with a concept is
98
- indicated in the relation metadata, as indicated earlier.
99
-
100
- The ``extension`` of a ``Concept`` object is then incorporated into a
101
- ``Valuation`` object.
102
-
103
- Persistence
104
- ===========
105
- The functions ``val_dump`` and ``val_load`` are provided to allow a
106
- valuation to be stored in a persistent database and re-loaded, rather
107
- than having to be re-computed each time.
108
-
109
- Individuals and Lexical Items
110
- =============================
111
- As well as deriving relations from the Chat-80 data, we also create a
112
- set of individual constants, one for each entity in the domain. The
113
- individual constants are string-identical to the entities. For
114
- example, given a data item such as ``'zloty'``, we add to the valuation
115
- a pair ``('zloty', 'zloty')``. In order to parse English sentences that
116
- refer to these entities, we also create a lexical item such as the
117
- following for each individual constant::
118
-
119
- PropN[num=sg, sem=<\P.(P zloty)>] -> 'Zloty'
120
-
121
- The set of rules is written to the file ``chat_pnames.cfg`` in the
122
- current directory.
123
-
124
- """
125
- from __future__ import print_function, unicode_literals
126
-
127
- import re
128
- import shelve
129
- import os
130
- import sys
131
-
132
- import nltk.data
133
- from nltk.compat import string_types, python_2_unicode_compatible
134
-
135
- ###########################################################################
136
- # Chat-80 relation metadata bundles needed to build the valuation
137
- ###########################################################################
138
-
139
- borders = {'rel_name': 'borders',
140
- 'closures': ['symmetric'],
141
- 'schema': ['region', 'border'],
142
- 'filename': 'borders.pl'}
143
-
144
- contains = {'rel_name': 'contains0',
145
- 'closures': ['transitive'],
146
- 'schema': ['region', 'contain'],
147
- 'filename': 'contain.pl'}
148
-
149
- city = {'rel_name': 'city',
150
- 'closures': [],
151
- 'schema': ['city', 'country', 'population'],
152
- 'filename': 'cities.pl'}
153
-
154
- country = {'rel_name': 'country',
155
- 'closures': [],
156
- 'schema': ['country', 'region', 'latitude', 'longitude',
157
- 'area', 'population', 'capital', 'currency'],
158
- 'filename': 'countries.pl'}
159
-
160
- circle_of_lat = {'rel_name': 'circle_of_latitude',
161
- 'closures': [],
162
- 'schema': ['circle_of_latitude', 'degrees'],
163
- 'filename': 'world1.pl'}
164
-
165
- circle_of_long = {'rel_name': 'circle_of_longitude',
166
- 'closures': [],
167
- 'schema': ['circle_of_longitude', 'degrees'],
168
- 'filename': 'world1.pl'}
169
-
170
- continent = {'rel_name': 'continent',
171
- 'closures': [],
172
- 'schema': ['continent'],
173
- 'filename': 'world1.pl'}
174
-
175
- region = {'rel_name': 'in_continent',
176
- 'closures': [],
177
- 'schema': ['region', 'continent'],
178
- 'filename': 'world1.pl'}
179
-
180
- ocean = {'rel_name': 'ocean',
181
- 'closures': [],
182
- 'schema': ['ocean'],
183
- 'filename': 'world1.pl'}
184
-
185
- sea = {'rel_name': 'sea',
186
- 'closures': [],
187
- 'schema': ['sea'],
188
- 'filename': 'world1.pl'}
189
-
190
-
191
-
192
- items = ['borders', 'contains', 'city', 'country', 'circle_of_lat',
193
- 'circle_of_long', 'continent', 'region', 'ocean', 'sea']
194
- items = tuple(sorted(items))
195
-
196
- item_metadata = {
197
- 'borders': borders,
198
- 'contains': contains,
199
- 'city': city,
200
- 'country': country,
201
- 'circle_of_lat': circle_of_lat,
202
- 'circle_of_long': circle_of_long,
203
- 'continent': continent,
204
- 'region': region,
205
- 'ocean': ocean,
206
- 'sea': sea
207
- }
208
-
209
- rels = item_metadata.values()
210
-
211
- not_unary = ['borders.pl', 'contain.pl']
212
-
213
- ###########################################################################
214
-
215
- @python_2_unicode_compatible
216
- class Concept(object):
217
- """
218
- A Concept class, loosely based on SKOS
219
- (http://www.w3.org/TR/swbp-skos-core-guide/).
220
- """
221
- def __init__(self, prefLabel, arity, altLabels=[], closures=[], extension=set()):
222
- """
223
- :param prefLabel: the preferred label for the concept
224
- :type prefLabel: str
225
- :param arity: the arity of the concept
226
- :type arity: int
227
- @keyword altLabels: other (related) labels
228
- :type altLabels: list
229
- @keyword closures: closure properties of the extension \
230
- (list items can be ``symmetric``, ``reflexive``, ``transitive``)
231
- :type closures: list
232
- @keyword extension: the extensional value of the concept
233
- :type extension: set
234
- """
235
- self.prefLabel = prefLabel
236
- self.arity = arity
237
- self.altLabels = altLabels
238
- self.closures = closures
239
- #keep _extension internally as a set
240
- self._extension = extension
241
- #public access is via a list (for slicing)
242
- self.extension = sorted(list(extension))
243
-
244
- def __str__(self):
245
- #_extension = ''
246
- #for element in sorted(self.extension):
247
- #if isinstance(element, tuple):
248
- #element = '(%s, %s)' % (element)
249
- #_extension += element + ', '
250
- #_extension = _extension[:-1]
251
-
252
- return "Label = '%s'\nArity = %s\nExtension = %s" % \
253
- (self.prefLabel, self.arity, self.extension)
254
-
255
- def __repr__(self):
256
- return "Concept('%s')" % self.prefLabel
257
-
258
- def augment(self, data):
259
- """
260
- Add more data to the ``Concept``'s extension set.
261
-
262
- :param data: a new semantic value
263
- :type data: string or pair of strings
264
- :rtype: set
265
-
266
- """
267
- self._extension.add(data)
268
- self.extension = sorted(list(self._extension))
269
- return self._extension
270
-
271
-
272
- def _make_graph(self, s):
273
- """
274
- Convert a set of pairs into an adjacency linked list encoding of a graph.
275
- """
276
- g = {}
277
- for (x, y) in s:
278
- if x in g:
279
- g[x].append(y)
280
- else:
281
- g[x] = [y]
282
- return g
283
-
284
- def _transclose(self, g):
285
- """
286
- Compute the transitive closure of a graph represented as a linked list.
287
- """
288
- for x in g:
289
- for adjacent in g[x]:
290
- # check that adjacent is a key
291
- if adjacent in g:
292
- for y in g[adjacent]:
293
- if y not in g[x]:
294
- g[x].append(y)
295
- return g
296
-
297
- def _make_pairs(self, g):
298
- """
299
- Convert an adjacency linked list back into a set of pairs.
300
- """
301
- pairs = []
302
- for node in g:
303
- for adjacent in g[node]:
304
- pairs.append((node, adjacent))
305
- return set(pairs)
306
-
307
-
308
- def close(self):
309
- """
310
- Close a binary relation in the ``Concept``'s extension set.
311
-
312
- :return: a new extension for the ``Concept`` in which the
313
- relation is closed under a given property
314
- """
315
- from nltk.sem import is_rel
316
- assert is_rel(self._extension)
317
- if 'symmetric' in self.closures:
318
- pairs = []
319
- for (x, y) in self._extension:
320
- pairs.append((y, x))
321
- sym = set(pairs)
322
- self._extension = self._extension.union(sym)
323
- if 'transitive' in self.closures:
324
- all = self._make_graph(self._extension)
325
- closed = self._transclose(all)
326
- trans = self._make_pairs(closed)
327
- #print sorted(trans)
328
- self._extension = self._extension.union(trans)
329
- self.extension = sorted(list(self._extension))
330
-
331
-
332
- def clause2concepts(filename, rel_name, schema, closures=[]):
333
- """
334
- Convert a file of Prolog clauses into a list of ``Concept`` objects.
335
-
336
- :param filename: filename containing the relations
337
- :type filename: str
338
- :param rel_name: name of the relation
339
- :type rel_name: str
340
- :param schema: the schema used in a set of relational tuples
341
- :type schema: list
342
- :param closures: closure properties for the extension of the concept
343
- :type closures: list
344
- :return: a list of ``Concept`` objects
345
- :rtype: list
346
- """
347
- concepts = []
348
- # position of the subject of a binary relation
349
- subj = 0
350
- # label of the 'primary key'
351
- pkey = schema[0]
352
- # fields other than the primary key
353
- fields = schema[1:]
354
-
355
- # convert a file into a list of lists
356
- records = _str2records(filename, rel_name)
357
-
358
- # add a unary concept corresponding to the set of entities
359
- # in the primary key position
360
- # relations in 'not_unary' are more like ordinary binary relations
361
- if not filename in not_unary:
362
- concepts.append(unary_concept(pkey, subj, records))
363
-
364
- # add a binary concept for each non-key field
365
- for field in fields:
366
- obj = schema.index(field)
367
- concepts.append(binary_concept(field, closures, subj, obj, records))
368
-
369
- return concepts
370
-
371
- def cities2table(filename, rel_name, dbname, verbose=False, setup=False):
372
- """
373
- Convert a file of Prolog clauses into a database table.
374
-
375
- This is not generic, since it doesn't allow arbitrary
376
- schemas to be set as a parameter.
377
-
378
- Intended usage::
379
-
380
- cities2table('cities.pl', 'city', 'city.db', verbose=True, setup=True)
381
-
382
- :param filename: filename containing the relations
383
- :type filename: str
384
- :param rel_name: name of the relation
385
- :type rel_name: str
386
- :param dbname: filename of persistent store
387
- :type schema: str
388
- """
389
- import sqlite3
390
- records = _str2records(filename, rel_name)
391
- connection = sqlite3.connect(dbname)
392
- cur = connection.cursor()
393
- if setup:
394
- cur.execute('''CREATE TABLE city_table
395
- (City text, Country text, Population int)''')
396
-
397
- table_name = "city_table"
398
- for t in records:
399
- cur.execute('insert into %s values (?,?,?)' % table_name, t)
400
- if verbose:
401
- print("inserting values into %s: " % table_name, t)
402
- connection.commit()
403
- if verbose:
404
- print("Committing update to %s" % dbname)
405
- cur.close()
406
-
407
- def sql_query(dbname, query):
408
- """
409
- Execute an SQL query over a database.
410
- :param dbname: filename of persistent store
411
- :type schema: str
412
- :param query: SQL query
413
- :type rel_name: str
414
- """
415
- import sqlite3
416
- try:
417
- path = nltk.data.find(dbname)
418
- connection = sqlite3.connect(str(path))
419
- cur = connection.cursor()
420
- return cur.execute(query)
421
- except (ValueError, sqlite3.OperationalError):
422
- import warnings
423
- warnings.warn("Make sure the database file %s is installed and uncompressed." % dbname)
424
- raise
425
-
426
- def _str2records(filename, rel):
427
- """
428
- Read a file into memory and convert each relation clause into a list.
429
- """
430
- recs = []
431
- contents = nltk.data.load("corpora/chat80/%s" % filename, format="text")
432
- for line in contents.splitlines():
433
- if line.startswith(rel):
434
- line = re.sub(rel+r'\(', '', line)
435
- line = re.sub(r'\)\.$', '', line)
436
- record = line.split(',')
437
- recs.append(record)
438
- return recs
439
-
440
- def unary_concept(label, subj, records):
441
- """
442
- Make a unary concept out of the primary key in a record.
443
-
444
- A record is a list of entities in some relation, such as
445
- ``['france', 'paris']``, where ``'france'`` is acting as the primary
446
- key.
447
-
448
- :param label: the preferred label for the concept
449
- :type label: string
450
- :param subj: position in the record of the subject of the predicate
451
- :type subj: int
452
- :param records: a list of records
453
- :type records: list of lists
454
- :return: ``Concept`` of arity 1
455
- :rtype: Concept
456
- """
457
- c = Concept(label, arity=1, extension=set())
458
- for record in records:
459
- c.augment(record[subj])
460
- return c
461
-
462
- def binary_concept(label, closures, subj, obj, records):
463
- """
464
- Make a binary concept out of the primary key and another field in a record.
465
-
466
- A record is a list of entities in some relation, such as
467
- ``['france', 'paris']``, where ``'france'`` is acting as the primary
468
- key, and ``'paris'`` stands in the ``'capital_of'`` relation to
469
- ``'france'``.
470
-
471
- More generally, given a record such as ``['a', 'b', 'c']``, where
472
- label is bound to ``'B'``, and ``obj`` bound to 1, the derived
473
- binary concept will have label ``'B_of'``, and its extension will
474
- be a set of pairs such as ``('a', 'b')``.
475
-
476
-
477
- :param label: the base part of the preferred label for the concept
478
- :type label: str
479
- :param closures: closure properties for the extension of the concept
480
- :type closures: list
481
- :param subj: position in the record of the subject of the predicate
482
- :type subj: int
483
- :param obj: position in the record of the object of the predicate
484
- :type obj: int
485
- :param records: a list of records
486
- :type records: list of lists
487
- :return: ``Concept`` of arity 2
488
- :rtype: Concept
489
- """
490
- if not label == 'border' and not label == 'contain':
491
- label = label + '_of'
492
- c = Concept(label, arity=2, closures=closures, extension=set())
493
- for record in records:
494
- c.augment((record[subj], record[obj]))
495
- # close the concept's extension according to the properties in closures
496
- c.close()
497
- return c
498
-
499
-
500
- def process_bundle(rels):
501
- """
502
- Given a list of relation metadata bundles, make a corresponding
503
- dictionary of concepts, indexed by the relation name.
504
-
505
- :param rels: bundle of metadata needed for constructing a concept
506
- :type rels: list(dict)
507
- :return: a dictionary of concepts, indexed by the relation name.
508
- :rtype: dict(str): Concept
509
- """
510
- concepts = {}
511
- for rel in rels:
512
- rel_name = rel['rel_name']
513
- closures = rel['closures']
514
- schema = rel['schema']
515
- filename = rel['filename']
516
-
517
- concept_list = clause2concepts(filename, rel_name, schema, closures)
518
- for c in concept_list:
519
- label = c.prefLabel
520
- if (label in concepts):
521
- for data in c.extension:
522
- concepts[label].augment(data)
523
- concepts[label].close()
524
- else:
525
- concepts[label] = c
526
- return concepts
527
-
528
-
529
- def make_valuation(concepts, read=False, lexicon=False):
530
- """
531
- Convert a list of ``Concept`` objects into a list of (label, extension) pairs;
532
- optionally create a ``Valuation`` object.
533
-
534
- :param concepts: concepts
535
- :type concepts: list(Concept)
536
- :param read: if ``True``, ``(symbol, set)`` pairs are read into a ``Valuation``
537
- :type read: bool
538
- :rtype: list or Valuation
539
- """
540
- vals = []
541
-
542
- for c in concepts:
543
- vals.append((c.prefLabel, c.extension))
544
- if lexicon: read = True
545
- if read:
546
- from nltk.sem import Valuation
547
- val = Valuation({})
548
- val.update(vals)
549
- # add labels for individuals
550
- val = label_indivs(val, lexicon=lexicon)
551
- return val
552
- else:
553
- return vals
554
-
555
-
556
- def val_dump(rels, db):
557
- """
558
- Make a ``Valuation`` from a list of relation metadata bundles and dump to
559
- persistent database.
560
-
561
- :param rels: bundle of metadata needed for constructing a concept
562
- :type rels: list of dict
563
- :param db: name of file to which data is written.
564
- The suffix '.db' will be automatically appended.
565
- :type db: str
566
- """
567
- concepts = process_bundle(rels).values()
568
- valuation = make_valuation(concepts, read=True)
569
- db_out = shelve.open(db, 'n')
570
-
571
- db_out.update(valuation)
572
-
573
- db_out.close()
574
-
575
-
576
- def val_load(db):
577
- """
578
- Load a ``Valuation`` from a persistent database.
579
-
580
- :param db: name of file from which data is read.
581
- The suffix '.db' should be omitted from the name.
582
- :type db: str
583
- """
584
- dbname = db+".db"
585
-
586
- if not os.access(dbname, os.R_OK):
587
- sys.exit("Cannot read file: %s" % dbname)
588
- else:
589
- db_in = shelve.open(db)
590
- from nltk.sem import Valuation
591
- val = Valuation(db_in)
592
- # val.read(db_in.items())
593
- return val
594
-
595
-
596
- #def alpha(str):
597
- #"""
598
- #Utility to filter out non-alphabetic constants.
599
-
600
- #:param str: candidate constant
601
- #:type str: string
602
- #:rtype: bool
603
- #"""
604
- #try:
605
- #int(str)
606
- #return False
607
- #except ValueError:
608
- ## some unknown values in records are labeled '?'
609
- #if not str == '?':
610
- #return True
611
-
612
-
613
- def label_indivs(valuation, lexicon=False):
614
- """
615
- Assign individual constants to the individuals in the domain of a ``Valuation``.
616
-
617
- Given a valuation with an entry of the form ``{'rel': {'a': True}}``,
618
- add a new entry ``{'a': 'a'}``.
619
-
620
- :type valuation: Valuation
621
- :rtype: Valuation
622
- """
623
- # collect all the individuals into a domain
624
- domain = valuation.domain
625
- # convert the domain into a sorted list of alphabetic terms
626
- # use the same string as a label
627
- pairs = [(e, e) for e in domain]
628
- if lexicon:
629
- lex = make_lex(domain)
630
- with open("chat_pnames.cfg", 'w') as outfile:
631
- outfile.writelines(lex)
632
- # read the pairs into the valuation
633
- valuation.update(pairs)
634
- return valuation
635
-
636
- def make_lex(symbols):
637
- """
638
- Create lexical CFG rules for each individual symbol.
639
-
640
- Given a valuation with an entry of the form ``{'zloty': 'zloty'}``,
641
- create a lexical rule for the proper name 'Zloty'.
642
-
643
- :param symbols: a list of individual constants in the semantic representation
644
- :type symbols: sequence -- set(str)
645
- :rtype: list(str)
646
- """
647
- lex = []
648
- header = """
649
- ##################################################################
650
- # Lexical rules automatically generated by running 'chat80.py -x'.
651
- ##################################################################
652
-
653
- """
654
- lex.append(header)
655
- template = "PropN[num=sg, sem=<\P.(P %s)>] -> '%s'\n"
656
-
657
- for s in symbols:
658
- parts = s.split('_')
659
- caps = [p.capitalize() for p in parts]
660
- pname = '_'.join(caps)
661
- rule = template % (s, pname)
662
- lex.append(rule)
663
- return lex
664
-
665
-
666
- ###########################################################################
667
- # Interface function to emulate other corpus readers
668
- ###########################################################################
669
-
670
- def concepts(items = items):
671
- """
672
- Build a list of concepts corresponding to the relation names in ``items``.
673
-
674
- :param items: names of the Chat-80 relations to extract
675
- :type items: list(str)
676
- :return: the ``Concept`` objects which are extracted from the relations
677
- :rtype: list(Concept)
678
- """
679
- if isinstance(items, string_types): items = (items,)
680
-
681
- rels = [item_metadata[r] for r in items]
682
-
683
- concept_map = process_bundle(rels)
684
- return concept_map.values()
685
-
686
-
687
-
688
-
689
- ###########################################################################
690
-
691
-
692
- def main():
693
- import sys
694
- from optparse import OptionParser
695
- description = \
696
- """
697
- Extract data from the Chat-80 Prolog files and convert them into a
698
- Valuation object for use in the NLTK semantics package.
699
- """
700
-
701
- opts = OptionParser(description=description)
702
- opts.set_defaults(verbose=True, lex=False, vocab=False)
703
- opts.add_option("-s", "--store", dest="outdb",
704
- help="store a valuation in DB", metavar="DB")
705
- opts.add_option("-l", "--load", dest="indb",
706
- help="load a stored valuation from DB", metavar="DB")
707
- opts.add_option("-c", "--concepts", action="store_true",
708
- help="print concepts instead of a valuation")
709
- opts.add_option("-r", "--relation", dest="label",
710
- help="print concept with label REL (check possible labels with '-v' option)", metavar="REL")
711
- opts.add_option("-q", "--quiet", action="store_false", dest="verbose",
712
- help="don't print out progress info")
713
- opts.add_option("-x", "--lex", action="store_true", dest="lex",
714
- help="write a file of lexical entries for country names, then exit")
715
- opts.add_option("-v", "--vocab", action="store_true", dest="vocab",
716
- help="print out the vocabulary of concept labels and their arity, then exit")
717
-
718
- (options, args) = opts.parse_args()
719
- if options.outdb and options.indb:
720
- opts.error("Options --store and --load are mutually exclusive")
721
-
722
-
723
- if options.outdb:
724
- # write the valuation to a persistent database
725
- if options.verbose:
726
- outdb = options.outdb+".db"
727
- print("Dumping a valuation to %s" % outdb)
728
- val_dump(rels, options.outdb)
729
- sys.exit(0)
730
- else:
731
- # try to read in a valuation from a database
732
- if options.indb is not None:
733
- dbname = options.indb+".db"
734
- if not os.access(dbname, os.R_OK):
735
- sys.exit("Cannot read file: %s" % dbname)
736
- else:
737
- valuation = val_load(options.indb)
738
- # we need to create the valuation from scratch
739
- else:
740
- # build some concepts
741
- concept_map = process_bundle(rels)
742
- concepts = concept_map.values()
743
- # just print out the vocabulary
744
- if options.vocab:
745
- items = sorted([(c.arity, c.prefLabel) for c in concepts])
746
- for (arity, label) in items:
747
- print(label, arity)
748
- sys.exit(0)
749
- # show all the concepts
750
- if options.concepts:
751
- for c in concepts:
752
- print(c)
753
- print()
754
- if options.label:
755
- print(concept_map[options.label])
756
- sys.exit(0)
757
- else:
758
- # turn the concepts into a Valuation
759
- if options.lex:
760
- if options.verbose:
761
- print("Writing out lexical rules")
762
- make_valuation(concepts, lexicon=True)
763
- else:
764
- valuation = make_valuation(concepts, read=True)
765
- print(valuation)
766
-
767
-
768
- def sql_demo():
769
- """
770
- Print out every row from the 'city.db' database.
771
- """
772
- print()
773
- print("Using SQL to extract rows from 'city.db' RDB.")
774
- for row in sql_query('corpora/city_database/city.db', "SELECT * FROM city_table"):
775
- print(row)
776
-
777
-
778
- if __name__ == '__main__':
779
- main()
780
- sql_demo()
781
-
782
-
1
+ # Natural Language Toolkit: Chat-80 KB Reader
2
+ # See http://www.w3.org/TR/swbp-skos-core-guide/
3
+ #
4
+ # Copyright (C) 2001-2018 NLTK Project
5
+ # Author: Ewan Klein <ewan@inf.ed.ac.uk>,
6
+ # URL: <http://nltk.sourceforge.net>
7
+ # For license information, see LICENSE.TXT
8
+
9
+ """
10
+ Overview
11
+ ========
12
+
13
+ Chat-80 was a natural language system which allowed the user to
14
+ interrogate a Prolog knowledge base in the domain of world
15
+ geography. It was developed in the early '80s by Warren and Pereira; see
16
+ ``http://www.aclweb.org/anthology/J82-3002.pdf`` for a description and
17
+ ``http://www.cis.upenn.edu/~pereira/oldies.html`` for the source
18
+ files.
19
+
20
+ This module contains functions to extract data from the Chat-80
21
+ relation files ('the world database'), and convert then into a format
22
+ that can be incorporated in the FOL models of
23
+ ``nltk.sem.evaluate``. The code assumes that the Prolog
24
+ input files are available in the NLTK corpora directory.
25
+
26
+ The Chat-80 World Database consists of the following files::
27
+
28
+ world0.pl
29
+ rivers.pl
30
+ cities.pl
31
+ countries.pl
32
+ contain.pl
33
+ borders.pl
34
+
35
+ This module uses a slightly modified version of ``world0.pl``, in which
36
+ a set of Prolog rules have been omitted. The modified file is named
37
+ ``world1.pl``. Currently, the file ``rivers.pl`` is not read in, since
38
+ it uses a list rather than a string in the second field.
39
+
40
+ Reading Chat-80 Files
41
+ =====================
42
+
43
+ Chat-80 relations are like tables in a relational database. The
44
+ relation acts as the name of the table; the first argument acts as the
45
+ 'primary key'; and subsequent arguments are further fields in the
46
+ table. In general, the name of the table provides a label for a unary
47
+ predicate whose extension is all the primary keys. For example,
48
+ relations in ``cities.pl`` are of the following form::
49
+
50
+ 'city(athens,greece,1368).'
51
+
52
+ Here, ``'athens'`` is the key, and will be mapped to a member of the
53
+ unary predicate *city*.
54
+
55
+ The fields in the table are mapped to binary predicates. The first
56
+ argument of the predicate is the primary key, while the second
57
+ argument is the data in the relevant field. Thus, in the above
58
+ example, the third field is mapped to the binary predicate
59
+ *population_of*, whose extension is a set of pairs such as
60
+ ``'(athens, 1368)'``.
61
+
62
+ An exception to this general framework is required by the relations in
63
+ the files ``borders.pl`` and ``contains.pl``. These contain facts of the
64
+ following form::
65
+
66
+ 'borders(albania,greece).'
67
+
68
+ 'contains0(africa,central_africa).'
69
+
70
+ We do not want to form a unary concept out the element in
71
+ the first field of these records, and we want the label of the binary
72
+ relation just to be ``'border'``/``'contain'`` respectively.
73
+
74
+ In order to drive the extraction process, we use 'relation metadata bundles'
75
+ which are Python dictionaries such as the following::
76
+
77
+ city = {'label': 'city',
78
+ 'closures': [],
79
+ 'schema': ['city', 'country', 'population'],
80
+ 'filename': 'cities.pl'}
81
+
82
+ According to this, the file ``city['filename']`` contains a list of
83
+ relational tuples (or more accurately, the corresponding strings in
84
+ Prolog form) whose predicate symbol is ``city['label']`` and whose
85
+ relational schema is ``city['schema']``. The notion of a ``closure`` is
86
+ discussed in the next section.
87
+
88
+ Concepts
89
+ ========
90
+ In order to encapsulate the results of the extraction, a class of
91
+ ``Concept`` objects is introduced. A ``Concept`` object has a number of
92
+ attributes, in particular a ``prefLabel`` and ``extension``, which make
93
+ it easier to inspect the output of the extraction. In addition, the
94
+ ``extension`` can be further processed: in the case of the ``'border'``
95
+ relation, we check that the relation is symmetric, and in the case
96
+ of the ``'contain'`` relation, we carry out the transitive
97
+ closure. The closure properties associated with a concept is
98
+ indicated in the relation metadata, as indicated earlier.
99
+
100
+ The ``extension`` of a ``Concept`` object is then incorporated into a
101
+ ``Valuation`` object.
102
+
103
+ Persistence
104
+ ===========
105
+ The functions ``val_dump`` and ``val_load`` are provided to allow a
106
+ valuation to be stored in a persistent database and re-loaded, rather
107
+ than having to be re-computed each time.
108
+
109
+ Individuals and Lexical Items
110
+ =============================
111
+ As well as deriving relations from the Chat-80 data, we also create a
112
+ set of individual constants, one for each entity in the domain. The
113
+ individual constants are string-identical to the entities. For
114
+ example, given a data item such as ``'zloty'``, we add to the valuation
115
+ a pair ``('zloty', 'zloty')``. In order to parse English sentences that
116
+ refer to these entities, we also create a lexical item such as the
117
+ following for each individual constant::
118
+
119
+ PropN[num=sg, sem=<\P.(P zloty)>] -> 'Zloty'
120
+
121
+ The set of rules is written to the file ``chat_pnames.cfg`` in the
122
+ current directory.
123
+
124
+ """
125
+ from __future__ import print_function, unicode_literals
126
+
127
+ import re
128
+ import shelve
129
+ import os
130
+ import sys
131
+
132
+ from six import string_types
133
+
134
+ import nltk.data
135
+ from nltk.compat import python_2_unicode_compatible
136
+
137
+ ###########################################################################
138
+ # Chat-80 relation metadata bundles needed to build the valuation
139
+ ###########################################################################
140
+
141
+ borders = {'rel_name': 'borders',
142
+ 'closures': ['symmetric'],
143
+ 'schema': ['region', 'border'],
144
+ 'filename': 'borders.pl'}
145
+
146
+ contains = {'rel_name': 'contains0',
147
+ 'closures': ['transitive'],
148
+ 'schema': ['region', 'contain'],
149
+ 'filename': 'contain.pl'}
150
+
151
+ city = {'rel_name': 'city',
152
+ 'closures': [],
153
+ 'schema': ['city', 'country', 'population'],
154
+ 'filename': 'cities.pl'}
155
+
156
+ country = {'rel_name': 'country',
157
+ 'closures': [],
158
+ 'schema': ['country', 'region', 'latitude', 'longitude',
159
+ 'area', 'population', 'capital', 'currency'],
160
+ 'filename': 'countries.pl'}
161
+
162
+ circle_of_lat = {'rel_name': 'circle_of_latitude',
163
+ 'closures': [],
164
+ 'schema': ['circle_of_latitude', 'degrees'],
165
+ 'filename': 'world1.pl'}
166
+
167
+ circle_of_long = {'rel_name': 'circle_of_longitude',
168
+ 'closures': [],
169
+ 'schema': ['circle_of_longitude', 'degrees'],
170
+ 'filename': 'world1.pl'}
171
+
172
+ continent = {'rel_name': 'continent',
173
+ 'closures': [],
174
+ 'schema': ['continent'],
175
+ 'filename': 'world1.pl'}
176
+
177
+ region = {'rel_name': 'in_continent',
178
+ 'closures': [],
179
+ 'schema': ['region', 'continent'],
180
+ 'filename': 'world1.pl'}
181
+
182
+ ocean = {'rel_name': 'ocean',
183
+ 'closures': [],
184
+ 'schema': ['ocean'],
185
+ 'filename': 'world1.pl'}
186
+
187
+ sea = {'rel_name': 'sea',
188
+ 'closures': [],
189
+ 'schema': ['sea'],
190
+ 'filename': 'world1.pl'}
191
+
192
+
193
+
194
+ items = ['borders', 'contains', 'city', 'country', 'circle_of_lat',
195
+ 'circle_of_long', 'continent', 'region', 'ocean', 'sea']
196
+ items = tuple(sorted(items))
197
+
198
+ item_metadata = {
199
+ 'borders': borders,
200
+ 'contains': contains,
201
+ 'city': city,
202
+ 'country': country,
203
+ 'circle_of_lat': circle_of_lat,
204
+ 'circle_of_long': circle_of_long,
205
+ 'continent': continent,
206
+ 'region': region,
207
+ 'ocean': ocean,
208
+ 'sea': sea
209
+ }
210
+
211
+ rels = item_metadata.values()
212
+
213
+ not_unary = ['borders.pl', 'contain.pl']
214
+
215
+ ###########################################################################
216
+
217
+ @python_2_unicode_compatible
218
+ class Concept(object):
219
+ """
220
+ A Concept class, loosely based on SKOS
221
+ (http://www.w3.org/TR/swbp-skos-core-guide/).
222
+ """
223
+ def __init__(self, prefLabel, arity, altLabels=[], closures=[], extension=set()):
224
+ """
225
+ :param prefLabel: the preferred label for the concept
226
+ :type prefLabel: str
227
+ :param arity: the arity of the concept
228
+ :type arity: int
229
+ @keyword altLabels: other (related) labels
230
+ :type altLabels: list
231
+ @keyword closures: closure properties of the extension \
232
+ (list items can be ``symmetric``, ``reflexive``, ``transitive``)
233
+ :type closures: list
234
+ @keyword extension: the extensional value of the concept
235
+ :type extension: set
236
+ """
237
+ self.prefLabel = prefLabel
238
+ self.arity = arity
239
+ self.altLabels = altLabels
240
+ self.closures = closures
241
+ #keep _extension internally as a set
242
+ self._extension = extension
243
+ #public access is via a list (for slicing)
244
+ self.extension = sorted(list(extension))
245
+
246
+ def __str__(self):
247
+ #_extension = ''
248
+ #for element in sorted(self.extension):
249
+ #if isinstance(element, tuple):
250
+ #element = '(%s, %s)' % (element)
251
+ #_extension += element + ', '
252
+ #_extension = _extension[:-1]
253
+
254
+ return "Label = '%s'\nArity = %s\nExtension = %s" % \
255
+ (self.prefLabel, self.arity, self.extension)
256
+
257
+ def __repr__(self):
258
+ return "Concept('%s')" % self.prefLabel
259
+
260
+ def augment(self, data):
261
+ """
262
+ Add more data to the ``Concept``'s extension set.
263
+
264
+ :param data: a new semantic value
265
+ :type data: string or pair of strings
266
+ :rtype: set
267
+
268
+ """
269
+ self._extension.add(data)
270
+ self.extension = sorted(list(self._extension))
271
+ return self._extension
272
+
273
+
274
+ def _make_graph(self, s):
275
+ """
276
+ Convert a set of pairs into an adjacency linked list encoding of a graph.
277
+ """
278
+ g = {}
279
+ for (x, y) in s:
280
+ if x in g:
281
+ g[x].append(y)
282
+ else:
283
+ g[x] = [y]
284
+ return g
285
+
286
+ def _transclose(self, g):
287
+ """
288
+ Compute the transitive closure of a graph represented as a linked list.
289
+ """
290
+ for x in g:
291
+ for adjacent in g[x]:
292
+ # check that adjacent is a key
293
+ if adjacent in g:
294
+ for y in g[adjacent]:
295
+ if y not in g[x]:
296
+ g[x].append(y)
297
+ return g
298
+
299
+ def _make_pairs(self, g):
300
+ """
301
+ Convert an adjacency linked list back into a set of pairs.
302
+ """
303
+ pairs = []
304
+ for node in g:
305
+ for adjacent in g[node]:
306
+ pairs.append((node, adjacent))
307
+ return set(pairs)
308
+
309
+
310
+ def close(self):
311
+ """
312
+ Close a binary relation in the ``Concept``'s extension set.
313
+
314
+ :return: a new extension for the ``Concept`` in which the
315
+ relation is closed under a given property
316
+ """
317
+ from nltk.sem import is_rel
318
+ assert is_rel(self._extension)
319
+ if 'symmetric' in self.closures:
320
+ pairs = []
321
+ for (x, y) in self._extension:
322
+ pairs.append((y, x))
323
+ sym = set(pairs)
324
+ self._extension = self._extension.union(sym)
325
+ if 'transitive' in self.closures:
326
+ all = self._make_graph(self._extension)
327
+ closed = self._transclose(all)
328
+ trans = self._make_pairs(closed)
329
+ #print sorted(trans)
330
+ self._extension = self._extension.union(trans)
331
+ self.extension = sorted(list(self._extension))
332
+
333
+
334
+ def clause2concepts(filename, rel_name, schema, closures=[]):
335
+ """
336
+ Convert a file of Prolog clauses into a list of ``Concept`` objects.
337
+
338
+ :param filename: filename containing the relations
339
+ :type filename: str
340
+ :param rel_name: name of the relation
341
+ :type rel_name: str
342
+ :param schema: the schema used in a set of relational tuples
343
+ :type schema: list
344
+ :param closures: closure properties for the extension of the concept
345
+ :type closures: list
346
+ :return: a list of ``Concept`` objects
347
+ :rtype: list
348
+ """
349
+ concepts = []
350
+ # position of the subject of a binary relation
351
+ subj = 0
352
+ # label of the 'primary key'
353
+ pkey = schema[0]
354
+ # fields other than the primary key
355
+ fields = schema[1:]
356
+
357
+ # convert a file into a list of lists
358
+ records = _str2records(filename, rel_name)
359
+
360
+ # add a unary concept corresponding to the set of entities
361
+ # in the primary key position
362
+ # relations in 'not_unary' are more like ordinary binary relations
363
+ if not filename in not_unary:
364
+ concepts.append(unary_concept(pkey, subj, records))
365
+
366
+ # add a binary concept for each non-key field
367
+ for field in fields:
368
+ obj = schema.index(field)
369
+ concepts.append(binary_concept(field, closures, subj, obj, records))
370
+
371
+ return concepts
372
+
373
+ def cities2table(filename, rel_name, dbname, verbose=False, setup=False):
374
+ """
375
+ Convert a file of Prolog clauses into a database table.
376
+
377
+ This is not generic, since it doesn't allow arbitrary
378
+ schemas to be set as a parameter.
379
+
380
+ Intended usage::
381
+
382
+ cities2table('cities.pl', 'city', 'city.db', verbose=True, setup=True)
383
+
384
+ :param filename: filename containing the relations
385
+ :type filename: str
386
+ :param rel_name: name of the relation
387
+ :type rel_name: str
388
+ :param dbname: filename of persistent store
389
+ :type schema: str
390
+ """
391
+ import sqlite3
392
+ records = _str2records(filename, rel_name)
393
+ connection = sqlite3.connect(dbname)
394
+ cur = connection.cursor()
395
+ if setup:
396
+ cur.execute('''CREATE TABLE city_table
397
+ (City text, Country text, Population int)''')
398
+
399
+ table_name = "city_table"
400
+ for t in records:
401
+ cur.execute('insert into %s values (?,?,?)' % table_name, t)
402
+ if verbose:
403
+ print("inserting values into %s: " % table_name, t)
404
+ connection.commit()
405
+ if verbose:
406
+ print("Committing update to %s" % dbname)
407
+ cur.close()
408
+
409
+ def sql_query(dbname, query):
410
+ """
411
+ Execute an SQL query over a database.
412
+ :param dbname: filename of persistent store
413
+ :type schema: str
414
+ :param query: SQL query
415
+ :type rel_name: str
416
+ """
417
+ import sqlite3
418
+ try:
419
+ path = nltk.data.find(dbname)
420
+ connection = sqlite3.connect(str(path))
421
+ cur = connection.cursor()
422
+ return cur.execute(query)
423
+ except (ValueError, sqlite3.OperationalError):
424
+ import warnings
425
+ warnings.warn("Make sure the database file %s is installed and uncompressed." % dbname)
426
+ raise
427
+
428
+ def _str2records(filename, rel):
429
+ """
430
+ Read a file into memory and convert each relation clause into a list.
431
+ """
432
+ recs = []
433
+ contents = nltk.data.load("corpora/chat80/%s" % filename, format="text")
434
+ for line in contents.splitlines():
435
+ if line.startswith(rel):
436
+ line = re.sub(rel+r'\(', '', line)
437
+ line = re.sub(r'\)\.$', '', line)
438
+ record = line.split(',')
439
+ recs.append(record)
440
+ return recs
441
+
442
+ def unary_concept(label, subj, records):
443
+ """
444
+ Make a unary concept out of the primary key in a record.
445
+
446
+ A record is a list of entities in some relation, such as
447
+ ``['france', 'paris']``, where ``'france'`` is acting as the primary
448
+ key.
449
+
450
+ :param label: the preferred label for the concept
451
+ :type label: string
452
+ :param subj: position in the record of the subject of the predicate
453
+ :type subj: int
454
+ :param records: a list of records
455
+ :type records: list of lists
456
+ :return: ``Concept`` of arity 1
457
+ :rtype: Concept
458
+ """
459
+ c = Concept(label, arity=1, extension=set())
460
+ for record in records:
461
+ c.augment(record[subj])
462
+ return c
463
+
464
+ def binary_concept(label, closures, subj, obj, records):
465
+ """
466
+ Make a binary concept out of the primary key and another field in a record.
467
+
468
+ A record is a list of entities in some relation, such as
469
+ ``['france', 'paris']``, where ``'france'`` is acting as the primary
470
+ key, and ``'paris'`` stands in the ``'capital_of'`` relation to
471
+ ``'france'``.
472
+
473
+ More generally, given a record such as ``['a', 'b', 'c']``, where
474
+ label is bound to ``'B'``, and ``obj`` bound to 1, the derived
475
+ binary concept will have label ``'B_of'``, and its extension will
476
+ be a set of pairs such as ``('a', 'b')``.
477
+
478
+
479
+ :param label: the base part of the preferred label for the concept
480
+ :type label: str
481
+ :param closures: closure properties for the extension of the concept
482
+ :type closures: list
483
+ :param subj: position in the record of the subject of the predicate
484
+ :type subj: int
485
+ :param obj: position in the record of the object of the predicate
486
+ :type obj: int
487
+ :param records: a list of records
488
+ :type records: list of lists
489
+ :return: ``Concept`` of arity 2
490
+ :rtype: Concept
491
+ """
492
+ if not label == 'border' and not label == 'contain':
493
+ label = label + '_of'
494
+ c = Concept(label, arity=2, closures=closures, extension=set())
495
+ for record in records:
496
+ c.augment((record[subj], record[obj]))
497
+ # close the concept's extension according to the properties in closures
498
+ c.close()
499
+ return c
500
+
501
+
502
+ def process_bundle(rels):
503
+ """
504
+ Given a list of relation metadata bundles, make a corresponding
505
+ dictionary of concepts, indexed by the relation name.
506
+
507
+ :param rels: bundle of metadata needed for constructing a concept
508
+ :type rels: list(dict)
509
+ :return: a dictionary of concepts, indexed by the relation name.
510
+ :rtype: dict(str): Concept
511
+ """
512
+ concepts = {}
513
+ for rel in rels:
514
+ rel_name = rel['rel_name']
515
+ closures = rel['closures']
516
+ schema = rel['schema']
517
+ filename = rel['filename']
518
+
519
+ concept_list = clause2concepts(filename, rel_name, schema, closures)
520
+ for c in concept_list:
521
+ label = c.prefLabel
522
+ if (label in concepts):
523
+ for data in c.extension:
524
+ concepts[label].augment(data)
525
+ concepts[label].close()
526
+ else:
527
+ concepts[label] = c
528
+ return concepts
529
+
530
+
531
+ def make_valuation(concepts, read=False, lexicon=False):
532
+ """
533
+ Convert a list of ``Concept`` objects into a list of (label, extension) pairs;
534
+ optionally create a ``Valuation`` object.
535
+
536
+ :param concepts: concepts
537
+ :type concepts: list(Concept)
538
+ :param read: if ``True``, ``(symbol, set)`` pairs are read into a ``Valuation``
539
+ :type read: bool
540
+ :rtype: list or Valuation
541
+ """
542
+ vals = []
543
+
544
+ for c in concepts:
545
+ vals.append((c.prefLabel, c.extension))
546
+ if lexicon: read = True
547
+ if read:
548
+ from nltk.sem import Valuation
549
+ val = Valuation({})
550
+ val.update(vals)
551
+ # add labels for individuals
552
+ val = label_indivs(val, lexicon=lexicon)
553
+ return val
554
+ else:
555
+ return vals
556
+
557
+
558
+ def val_dump(rels, db):
559
+ """
560
+ Make a ``Valuation`` from a list of relation metadata bundles and dump to
561
+ persistent database.
562
+
563
+ :param rels: bundle of metadata needed for constructing a concept
564
+ :type rels: list of dict
565
+ :param db: name of file to which data is written.
566
+ The suffix '.db' will be automatically appended.
567
+ :type db: str
568
+ """
569
+ concepts = process_bundle(rels).values()
570
+ valuation = make_valuation(concepts, read=True)
571
+ db_out = shelve.open(db, 'n')
572
+
573
+ db_out.update(valuation)
574
+
575
+ db_out.close()
576
+
577
+
578
+ def val_load(db):
579
+ """
580
+ Load a ``Valuation`` from a persistent database.
581
+
582
+ :param db: name of file from which data is read.
583
+ The suffix '.db' should be omitted from the name.
584
+ :type db: str
585
+ """
586
+ dbname = db+".db"
587
+
588
+ if not os.access(dbname, os.R_OK):
589
+ sys.exit("Cannot read file: %s" % dbname)
590
+ else:
591
+ db_in = shelve.open(db)
592
+ from nltk.sem import Valuation
593
+ val = Valuation(db_in)
594
+ # val.read(db_in.items())
595
+ return val
596
+
597
+
598
+ #def alpha(str):
599
+ #"""
600
+ #Utility to filter out non-alphabetic constants.
601
+
602
+ #:param str: candidate constant
603
+ #:type str: string
604
+ #:rtype: bool
605
+ #"""
606
+ #try:
607
+ #int(str)
608
+ #return False
609
+ #except ValueError:
610
+ ## some unknown values in records are labeled '?'
611
+ #if not str == '?':
612
+ #return True
613
+
614
+
615
+ def label_indivs(valuation, lexicon=False):
616
+ """
617
+ Assign individual constants to the individuals in the domain of a ``Valuation``.
618
+
619
+ Given a valuation with an entry of the form ``{'rel': {'a': True}}``,
620
+ add a new entry ``{'a': 'a'}``.
621
+
622
+ :type valuation: Valuation
623
+ :rtype: Valuation
624
+ """
625
+ # collect all the individuals into a domain
626
+ domain = valuation.domain
627
+ # convert the domain into a sorted list of alphabetic terms
628
+ # use the same string as a label
629
+ pairs = [(e, e) for e in domain]
630
+ if lexicon:
631
+ lex = make_lex(domain)
632
+ with open("chat_pnames.cfg", 'w') as outfile:
633
+ outfile.writelines(lex)
634
+ # read the pairs into the valuation
635
+ valuation.update(pairs)
636
+ return valuation
637
+
638
+ def make_lex(symbols):
639
+ """
640
+ Create lexical CFG rules for each individual symbol.
641
+
642
+ Given a valuation with an entry of the form ``{'zloty': 'zloty'}``,
643
+ create a lexical rule for the proper name 'Zloty'.
644
+
645
+ :param symbols: a list of individual constants in the semantic representation
646
+ :type symbols: sequence -- set(str)
647
+ :rtype: list(str)
648
+ """
649
+ lex = []
650
+ header = """
651
+ ##################################################################
652
+ # Lexical rules automatically generated by running 'chat80.py -x'.
653
+ ##################################################################
654
+
655
+ """
656
+ lex.append(header)
657
+ template = "PropN[num=sg, sem=<\P.(P %s)>] -> '%s'\n"
658
+
659
+ for s in symbols:
660
+ parts = s.split('_')
661
+ caps = [p.capitalize() for p in parts]
662
+ pname = '_'.join(caps)
663
+ rule = template % (s, pname)
664
+ lex.append(rule)
665
+ return lex
666
+
667
+
668
+ ###########################################################################
669
+ # Interface function to emulate other corpus readers
670
+ ###########################################################################
671
+
672
+ def concepts(items = items):
673
+ """
674
+ Build a list of concepts corresponding to the relation names in ``items``.
675
+
676
+ :param items: names of the Chat-80 relations to extract
677
+ :type items: list(str)
678
+ :return: the ``Concept`` objects which are extracted from the relations
679
+ :rtype: list(Concept)
680
+ """
681
+ if isinstance(items, string_types): items = (items,)
682
+
683
+ rels = [item_metadata[r] for r in items]
684
+
685
+ concept_map = process_bundle(rels)
686
+ return concept_map.values()
687
+
688
+
689
+
690
+
691
+ ###########################################################################
692
+
693
+
694
+ def main():
695
+ import sys
696
+ from optparse import OptionParser
697
+ description = \
698
+ """
699
+ Extract data from the Chat-80 Prolog files and convert them into a
700
+ Valuation object for use in the NLTK semantics package.
701
+ """
702
+
703
+ opts = OptionParser(description=description)
704
+ opts.set_defaults(verbose=True, lex=False, vocab=False)
705
+ opts.add_option("-s", "--store", dest="outdb",
706
+ help="store a valuation in DB", metavar="DB")
707
+ opts.add_option("-l", "--load", dest="indb",
708
+ help="load a stored valuation from DB", metavar="DB")
709
+ opts.add_option("-c", "--concepts", action="store_true",
710
+ help="print concepts instead of a valuation")
711
+ opts.add_option("-r", "--relation", dest="label",
712
+ help="print concept with label REL (check possible labels with '-v' option)", metavar="REL")
713
+ opts.add_option("-q", "--quiet", action="store_false", dest="verbose",
714
+ help="don't print out progress info")
715
+ opts.add_option("-x", "--lex", action="store_true", dest="lex",
716
+ help="write a file of lexical entries for country names, then exit")
717
+ opts.add_option("-v", "--vocab", action="store_true", dest="vocab",
718
+ help="print out the vocabulary of concept labels and their arity, then exit")
719
+
720
+ (options, args) = opts.parse_args()
721
+ if options.outdb and options.indb:
722
+ opts.error("Options --store and --load are mutually exclusive")
723
+
724
+
725
+ if options.outdb:
726
+ # write the valuation to a persistent database
727
+ if options.verbose:
728
+ outdb = options.outdb+".db"
729
+ print("Dumping a valuation to %s" % outdb)
730
+ val_dump(rels, options.outdb)
731
+ sys.exit(0)
732
+ else:
733
+ # try to read in a valuation from a database
734
+ if options.indb is not None:
735
+ dbname = options.indb+".db"
736
+ if not os.access(dbname, os.R_OK):
737
+ sys.exit("Cannot read file: %s" % dbname)
738
+ else:
739
+ valuation = val_load(options.indb)
740
+ # we need to create the valuation from scratch
741
+ else:
742
+ # build some concepts
743
+ concept_map = process_bundle(rels)
744
+ concepts = concept_map.values()
745
+ # just print out the vocabulary
746
+ if options.vocab:
747
+ items = sorted([(c.arity, c.prefLabel) for c in concepts])
748
+ for (arity, label) in items:
749
+ print(label, arity)
750
+ sys.exit(0)
751
+ # show all the concepts
752
+ if options.concepts:
753
+ for c in concepts:
754
+ print(c)
755
+ print()
756
+ if options.label:
757
+ print(concept_map[options.label])
758
+ sys.exit(0)
759
+ else:
760
+ # turn the concepts into a Valuation
761
+ if options.lex:
762
+ if options.verbose:
763
+ print("Writing out lexical rules")
764
+ make_valuation(concepts, lexicon=True)
765
+ else:
766
+ valuation = make_valuation(concepts, read=True)
767
+ print(valuation)
768
+
769
+
770
+ def sql_demo():
771
+ """
772
+ Print out every row from the 'city.db' database.
773
+ """
774
+ print()
775
+ print("Using SQL to extract rows from 'city.db' RDB.")
776
+ for row in sql_query('corpora/city_database/city.db', "SELECT * FROM city_table"):
777
+ print(row)
778
+
779
+
780
+ if __name__ == '__main__':
781
+ main()
782
+ sql_demo()