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,1101 +1,1101 @@
1
- .. Copyright (C) 2001-2015 NLTK Project
2
- .. For license information, see LICENSE.TXT
3
-
4
- ===============================
5
- Unit tests for nltk.tree.Tree
6
- ===============================
7
-
8
- >>> from nltk.tree import *
9
-
10
- Some trees to run tests on:
11
-
12
- >>> dp1 = Tree('dp', [Tree('d', ['the']), Tree('np', ['dog'])])
13
- >>> dp2 = Tree('dp', [Tree('d', ['the']), Tree('np', ['cat'])])
14
- >>> vp = Tree('vp', [Tree('v', ['chased']), dp2])
15
- >>> tree = Tree('s', [dp1, vp])
16
- >>> print(tree)
17
- (s (dp (d the) (np dog)) (vp (v chased) (dp (d the) (np cat))))
18
-
19
- The node label is accessed using the `label()` method:
20
-
21
- >>> dp1.label(), dp2.label(), vp.label(), tree.label()
22
- ('dp', 'dp', 'vp', 's')
23
-
24
- >>> print(tree[1,1,1,0])
25
- cat
26
-
27
- The `treepositions` method returns a list of the tree positions of
28
- subtrees and leaves in a tree. By default, it gives the position of
29
- every tree, subtree, and leaf, in prefix order:
30
-
31
- >>> print(tree.treepositions())
32
- [(), (0,), (0, 0), (0, 0, 0), (0, 1), (0, 1, 0), (1,), (1, 0), (1, 0, 0), (1, 1), (1, 1, 0), (1, 1, 0, 0), (1, 1, 1), (1, 1, 1, 0)]
33
-
34
- In addition to `str` and `repr`, several methods exist to convert a
35
- tree object to one of several standard tree encodings:
36
-
37
- >>> print(tree.pformat_latex_qtree())
38
- \Tree [.s
39
- [.dp [.d the ] [.np dog ] ]
40
- [.vp [.v chased ] [.dp [.d the ] [.np cat ] ] ] ]
41
-
42
- There is also a fancy ASCII art representation:
43
-
44
- >>> tree.pretty_print()
45
- s
46
- ________|_____
47
- | vp
48
- | _____|___
49
- dp | dp
50
- ___|___ | ___|___
51
- d np v d np
52
- | | | | |
53
- the dog chased the cat
54
-
55
- >>> tree.pretty_print(unicodelines=True, nodedist=4)
56
- s
57
- ┌──────────────┴────────┐
58
- │ vp
59
- │ ┌────────┴──────┐
60
- dp │ dp
61
- ┌──────┴──────┐ │ ┌──────┴──────┐
62
- d np v d np
63
- │ │ │ │ │
64
- the dog chased the cat
65
-
66
- Trees can be initialized from treebank strings:
67
-
68
- >>> tree2 = Tree.fromstring('(S (NP I) (VP (V enjoyed) (NP my cookie)))')
69
- >>> print(tree2)
70
- (S (NP I) (VP (V enjoyed) (NP my cookie)))
71
-
72
- Trees can be compared for equality:
73
-
74
- >>> tree == Tree.fromstring(str(tree))
75
- True
76
- >>> tree2 == Tree.fromstring(str(tree2))
77
- True
78
- >>> tree == tree2
79
- False
80
- >>> tree == Tree.fromstring(str(tree2))
81
- False
82
- >>> tree2 == Tree.fromstring(str(tree))
83
- False
84
-
85
- >>> tree != Tree.fromstring(str(tree))
86
- False
87
- >>> tree2 != Tree.fromstring(str(tree2))
88
- False
89
- >>> tree != tree2
90
- True
91
- >>> tree != Tree.fromstring(str(tree2))
92
- True
93
- >>> tree2 != Tree.fromstring(str(tree))
94
- True
95
-
96
- >>> tree < tree2 or tree > tree2
97
- True
98
-
99
- Tree Parsing
100
- ============
101
-
102
- The class method `Tree.fromstring()` can be used to parse trees, and it
103
- provides some additional options.
104
-
105
- >>> tree = Tree.fromstring('(S (NP I) (VP (V enjoyed) (NP my cookie)))')
106
- >>> print(tree)
107
- (S (NP I) (VP (V enjoyed) (NP my cookie)))
108
-
109
- When called on a subclass of `Tree`, it will create trees of that
110
- type:
111
-
112
- >>> tree = ImmutableTree.fromstring('(VP (V enjoyed) (NP my cookie))')
113
- >>> print(tree)
114
- (VP (V enjoyed) (NP my cookie))
115
- >>> print(type(tree))
116
- <class 'nltk.tree.ImmutableTree'>
117
- >>> tree[1] = 'x'
118
- Traceback (most recent call last):
119
- . . .
120
- ValueError: ImmutableTree may not be modified
121
- >>> del tree[0]
122
- Traceback (most recent call last):
123
- . . .
124
- ValueError: ImmutableTree may not be modified
125
-
126
- The ``brackets`` parameter can be used to specify two characters that
127
- should be used as brackets:
128
-
129
- >>> print(Tree.fromstring('[S [NP I] [VP [V enjoyed] [NP my cookie]]]',
130
- ... brackets='[]'))
131
- (S (NP I) (VP (V enjoyed) (NP my cookie)))
132
- >>> print(Tree.fromstring('<S <NP I> <VP <V enjoyed> <NP my cookie>>>',
133
- ... brackets='<>'))
134
- (S (NP I) (VP (V enjoyed) (NP my cookie)))
135
-
136
- If ``brackets`` is not a string, or is not exactly two characters,
137
- then `Tree.fromstring` raises an exception:
138
-
139
- >>> Tree.fromstring('<VP <V enjoyed> <NP my cookie>>', brackets='')
140
- Traceback (most recent call last):
141
- . . .
142
- TypeError: brackets must be a length-2 string
143
- >>> Tree.fromstring('<VP <V enjoyed> <NP my cookie>>', brackets='<<>>')
144
- Traceback (most recent call last):
145
- . . .
146
- TypeError: brackets must be a length-2 string
147
- >>> Tree.fromstring('<VP <V enjoyed> <NP my cookie>>', brackets=12)
148
- Traceback (most recent call last):
149
- . . .
150
- TypeError: brackets must be a length-2 string
151
- >>> Tree.fromstring('<<NP my cookie>>', brackets=('<<','>>'))
152
- Traceback (most recent call last):
153
- . . .
154
- TypeError: brackets must be a length-2 string
155
-
156
- (We may add support for multi-character brackets in the future, in
157
- which case the ``brackets=('<<','>>')`` example would start working.)
158
-
159
- Whitespace brackets are not permitted:
160
-
161
- >>> Tree.fromstring('(NP my cookie\n', brackets='(\n')
162
- Traceback (most recent call last):
163
- . . .
164
- TypeError: whitespace brackets not allowed
165
-
166
- If an invalid tree is given to Tree.fromstring, then it raises a
167
- ValueError, with a description of the problem:
168
-
169
- >>> Tree.fromstring('(NP my cookie) (NP my milk)')
170
- Traceback (most recent call last):
171
- . . .
172
- ValueError: Tree.fromstring(): expected 'end-of-string' but got '(NP'
173
- at index 15.
174
- "...y cookie) (NP my mil..."
175
- ^
176
- >>> Tree.fromstring(')NP my cookie(')
177
- Traceback (most recent call last):
178
- . . .
179
- ValueError: Tree.fromstring(): expected '(' but got ')'
180
- at index 0.
181
- ")NP my coo..."
182
- ^
183
- >>> Tree.fromstring('(NP my cookie))')
184
- Traceback (most recent call last):
185
- . . .
186
- ValueError: Tree.fromstring(): expected 'end-of-string' but got ')'
187
- at index 14.
188
- "...my cookie))"
189
- ^
190
- >>> Tree.fromstring('my cookie)')
191
- Traceback (most recent call last):
192
- . . .
193
- ValueError: Tree.fromstring(): expected '(' but got 'my'
194
- at index 0.
195
- "my cookie)"
196
- ^
197
- >>> Tree.fromstring('(NP my cookie')
198
- Traceback (most recent call last):
199
- . . .
200
- ValueError: Tree.fromstring(): expected ')' but got 'end-of-string'
201
- at index 13.
202
- "... my cookie"
203
- ^
204
- >>> Tree.fromstring('')
205
- Traceback (most recent call last):
206
- . . .
207
- ValueError: Tree.fromstring(): expected '(' but got 'end-of-string'
208
- at index 0.
209
- ""
210
- ^
211
-
212
- Trees with no children are supported:
213
-
214
- >>> print(Tree.fromstring('(S)'))
215
- (S )
216
- >>> print(Tree.fromstring('(X (Y) (Z))'))
217
- (X (Y ) (Z ))
218
-
219
- Trees with an empty node label and no children are supported:
220
-
221
- >>> print(Tree.fromstring('()'))
222
- ( )
223
- >>> print(Tree.fromstring('(X () ())'))
224
- (X ( ) ( ))
225
-
226
- Trees with an empty node label and children are supported, but only if the
227
- first child is not a leaf (otherwise, it will be treated as the node label).
228
-
229
- >>> print(Tree.fromstring('((A) (B) (C))'))
230
- ( (A ) (B ) (C ))
231
- >>> print(Tree.fromstring('((A) leaf)'))
232
- ( (A ) leaf)
233
- >>> print(Tree.fromstring('(((())))'))
234
- ( ( ( ( ))))
235
-
236
- The optional arguments `read_node` and `read_leaf` may be used to
237
- transform the string values of nodes or leaves.
238
-
239
- >>> print(Tree.fromstring('(A b (C d e) (F (G h i)))',
240
- ... read_node=lambda s: '<%s>' % s,
241
- ... read_leaf=lambda s: '"%s"' % s))
242
- (<A> "b" (<C> "d" "e") (<F> (<G> "h" "i")))
243
-
244
- These transformation functions are typically used when the node or
245
- leaf labels should be parsed to a non-string value (such as a feature
246
- structure). If node and leaf labels need to be able to include
247
- whitespace, then you must also use the optional `node_pattern` and
248
- `leaf_pattern` arguments.
249
-
250
- >>> from nltk.featstruct import FeatStruct
251
- >>> tree = Tree.fromstring('([cat=NP] [lex=the] [lex=dog])',
252
- ... read_node=FeatStruct, read_leaf=FeatStruct)
253
- >>> tree.set_label(tree.label().unify(FeatStruct('[num=singular]')))
254
- >>> print(tree)
255
- ([cat='NP', num='singular'] [lex='the'] [lex='dog'])
256
-
257
- The optional argument ``remove_empty_top_bracketing`` can be used to
258
- remove any top-level empty bracketing that occurs.
259
-
260
- >>> print(Tree.fromstring('((S (NP I) (VP (V enjoyed) (NP my cookie))))',
261
- ... remove_empty_top_bracketing=True))
262
- (S (NP I) (VP (V enjoyed) (NP my cookie)))
263
-
264
- It will not remove a top-level empty bracketing with multiple children:
265
-
266
- >>> print(Tree.fromstring('((A a) (B b))'))
267
- ( (A a) (B b))
268
-
269
- Parented Trees
270
- ==============
271
- `ParentedTree` is a subclass of `Tree` that automatically maintains
272
- parent pointers for single-parented trees. Parented trees can be
273
- created directly from a node label and a list of children:
274
-
275
- >>> ptree = (
276
- ... ParentedTree('VP', [
277
- ... ParentedTree('VERB', ['saw']),
278
- ... ParentedTree('NP', [
279
- ... ParentedTree('DET', ['the']),
280
- ... ParentedTree('NOUN', ['dog'])])]))
281
- >>> print(ptree)
282
- (VP (VERB saw) (NP (DET the) (NOUN dog)))
283
-
284
- Parented trees can be created from strings using the classmethod
285
- `ParentedTree.fromstring`:
286
-
287
- >>> ptree = ParentedTree.fromstring('(VP (VERB saw) (NP (DET the) (NOUN dog)))')
288
- >>> print(ptree)
289
- (VP (VERB saw) (NP (DET the) (NOUN dog)))
290
- >>> print(type(ptree))
291
- <class 'nltk.tree.ParentedTree'>
292
-
293
- Parented trees can also be created by using the classmethod
294
- `ParentedTree.convert` to convert another type of tree to a parented
295
- tree:
296
-
297
- >>> tree = Tree.fromstring('(VP (VERB saw) (NP (DET the) (NOUN dog)))')
298
- >>> ptree = ParentedTree.convert(tree)
299
- >>> print(ptree)
300
- (VP (VERB saw) (NP (DET the) (NOUN dog)))
301
- >>> print(type(ptree))
302
- <class 'nltk.tree.ParentedTree'>
303
-
304
- .. clean-up:
305
-
306
- >>> del tree
307
-
308
- `ParentedTree`\ s should never be used in the same tree as `Tree`\ s
309
- or `MultiParentedTree`\ s. Mixing tree implementations may result in
310
- incorrect parent pointers and in `TypeError` exceptions:
311
-
312
- >>> # Inserting a Tree in a ParentedTree gives an exception:
313
- >>> ParentedTree('NP', [
314
- ... Tree('DET', ['the']), Tree('NOUN', ['dog'])])
315
- Traceback (most recent call last):
316
- . . .
317
- TypeError: Can not insert a non-ParentedTree into a ParentedTree
318
-
319
- >>> # inserting a ParentedTree in a Tree gives incorrect parent pointers:
320
- >>> broken_tree = Tree('NP', [
321
- ... ParentedTree('DET', ['the']), ParentedTree('NOUN', ['dog'])])
322
- >>> print(broken_tree[0].parent())
323
- None
324
-
325
- Parented Tree Methods
326
- ------------------------
327
- In addition to all the methods defined by the `Tree` class, the
328
- `ParentedTree` class adds six new methods whose values are
329
- automatically updated whenver a parented tree is modified: `parent()`,
330
- `parent_index()`, `left_sibling()`, `right_sibling()`, `root()`, and
331
- `treeposition()`.
332
-
333
- The `parent()` method contains a `ParentedTree`\ 's parent, if it has
334
- one; and ``None`` otherwise. `ParentedTree`\ s that do not have
335
- parents are known as "root trees."
336
-
337
- >>> for subtree in ptree.subtrees():
338
- ... print(subtree)
339
- ... print(' Parent = %s' % subtree.parent())
340
- (VP (VERB saw) (NP (DET the) (NOUN dog)))
341
- Parent = None
342
- (VERB saw)
343
- Parent = (VP (VERB saw) (NP (DET the) (NOUN dog)))
344
- (NP (DET the) (NOUN dog))
345
- Parent = (VP (VERB saw) (NP (DET the) (NOUN dog)))
346
- (DET the)
347
- Parent = (NP (DET the) (NOUN dog))
348
- (NOUN dog)
349
- Parent = (NP (DET the) (NOUN dog))
350
-
351
- The `parent_index()` method stores the index of a tree in its parent's
352
- child list. If a tree does not have a parent, then its `parent_index`
353
- is ``None``.
354
-
355
- >>> for subtree in ptree.subtrees():
356
- ... print(subtree)
357
- ... print(' Parent Index = %s' % subtree.parent_index())
358
- ... assert (subtree.parent() is None or
359
- ... subtree.parent()[subtree.parent_index()] is subtree)
360
- (VP (VERB saw) (NP (DET the) (NOUN dog)))
361
- Parent Index = None
362
- (VERB saw)
363
- Parent Index = 0
364
- (NP (DET the) (NOUN dog))
365
- Parent Index = 1
366
- (DET the)
367
- Parent Index = 0
368
- (NOUN dog)
369
- Parent Index = 1
370
-
371
- Note that ``ptree.parent().index(ptree)`` is *not* equivalent to
372
- ``ptree.parent_index()``. In particular, ``ptree.parent().index(ptree)``
373
- will return the index of the first child of ``ptree.parent()`` that is
374
- equal to ``ptree`` (using ``==``); and that child may not be
375
- ``ptree``:
376
-
377
- >>> on_and_on = ParentedTree('CONJP', [
378
- ... ParentedTree('PREP', ['on']),
379
- ... ParentedTree('COJN', ['and']),
380
- ... ParentedTree('PREP', ['on'])])
381
- >>> second_on = on_and_on[2]
382
- >>> print(second_on.parent_index())
383
- 2
384
- >>> print(second_on.parent().index(second_on))
385
- 0
386
-
387
- The methods `left_sibling()` and `right_sibling()` can be used to get a
388
- parented tree's siblings. If a tree does not have a left or right
389
- sibling, then the corresponding method's value is ``None``:
390
-
391
- >>> for subtree in ptree.subtrees():
392
- ... print(subtree)
393
- ... print(' Left Sibling = %s' % subtree.left_sibling())
394
- ... print(' Right Sibling = %s' % subtree.right_sibling())
395
- (VP (VERB saw) (NP (DET the) (NOUN dog)))
396
- Left Sibling = None
397
- Right Sibling = None
398
- (VERB saw)
399
- Left Sibling = None
400
- Right Sibling = (NP (DET the) (NOUN dog))
401
- (NP (DET the) (NOUN dog))
402
- Left Sibling = (VERB saw)
403
- Right Sibling = None
404
- (DET the)
405
- Left Sibling = None
406
- Right Sibling = (NOUN dog)
407
- (NOUN dog)
408
- Left Sibling = (DET the)
409
- Right Sibling = None
410
-
411
- A parented tree's root tree can be accessed using the `root()`
412
- method. This method follows the tree's parent pointers until it
413
- finds a tree without a parent. If a tree does not have a parent, then
414
- it is its own root:
415
-
416
- >>> for subtree in ptree.subtrees():
417
- ... print(subtree)
418
- ... print(' Root = %s' % subtree.root())
419
- (VP (VERB saw) (NP (DET the) (NOUN dog)))
420
- Root = (VP (VERB saw) (NP (DET the) (NOUN dog)))
421
- (VERB saw)
422
- Root = (VP (VERB saw) (NP (DET the) (NOUN dog)))
423
- (NP (DET the) (NOUN dog))
424
- Root = (VP (VERB saw) (NP (DET the) (NOUN dog)))
425
- (DET the)
426
- Root = (VP (VERB saw) (NP (DET the) (NOUN dog)))
427
- (NOUN dog)
428
- Root = (VP (VERB saw) (NP (DET the) (NOUN dog)))
429
-
430
- The `treeposition()` method can be used to find a tree's treeposition
431
- relative to its root:
432
-
433
- >>> for subtree in ptree.subtrees():
434
- ... print(subtree)
435
- ... print(' Tree Position = %s' % (subtree.treeposition(),))
436
- ... assert subtree.root()[subtree.treeposition()] is subtree
437
- (VP (VERB saw) (NP (DET the) (NOUN dog)))
438
- Tree Position = ()
439
- (VERB saw)
440
- Tree Position = (0,)
441
- (NP (DET the) (NOUN dog))
442
- Tree Position = (1,)
443
- (DET the)
444
- Tree Position = (1, 0)
445
- (NOUN dog)
446
- Tree Position = (1, 1)
447
-
448
- Whenever a parented tree is modified, all of the methods described
449
- above (`parent()`, `parent_index()`, `left_sibling()`, `right_sibling()`,
450
- `root()`, and `treeposition()`) are automatically updated. For example,
451
- if we replace ``ptree``\ 's subtree for the word "dog" with a new
452
- subtree for "cat," the method values for both the "dog" subtree and the
453
- "cat" subtree get automatically updated:
454
-
455
- >>> # Replace the dog with a cat
456
- >>> dog = ptree[1,1]
457
- >>> cat = ParentedTree('NOUN', ['cat'])
458
- >>> ptree[1,1] = cat
459
-
460
- >>> # the noun phrase is no longer the dog's parent:
461
- >>> print(dog.parent(), dog.parent_index(), dog.left_sibling())
462
- None None None
463
- >>> # dog is now its own root.
464
- >>> print(dog.root())
465
- (NOUN dog)
466
- >>> print(dog.treeposition())
467
- ()
468
-
469
- >>> # the cat's parent is now the noun phrase:
470
- >>> print(cat.parent())
471
- (NP (DET the) (NOUN cat))
472
- >>> print(cat.parent_index())
473
- 1
474
- >>> print(cat.left_sibling())
475
- (DET the)
476
- >>> print(cat.root())
477
- (VP (VERB saw) (NP (DET the) (NOUN cat)))
478
- >>> print(cat.treeposition())
479
- (1, 1)
480
-
481
- ParentedTree Regression Tests
482
- -----------------------------
483
- Keep track of all trees that we create (including subtrees) using this
484
- variable:
485
-
486
- >>> all_ptrees = []
487
-
488
- Define a helper funciton to create new parented trees:
489
-
490
- >>> def make_ptree(s):
491
- ... ptree = ParentedTree.convert(Tree.fromstring(s))
492
- ... all_ptrees.extend(t for t in ptree.subtrees()
493
- ... if isinstance(t, Tree))
494
- ... return ptree
495
-
496
- Define a test function that examines every subtree in all_ptrees; and
497
- checks that all six of its methods are defined correctly. If any
498
- ptrees are passed as arguments, then they are printed.
499
-
500
- >>> def pcheck(*print_ptrees):
501
- ... for ptree in all_ptrees:
502
- ... # Check ptree's methods.
503
- ... if ptree.parent() is not None:
504
- ... i = ptree.parent_index()
505
- ... assert ptree.parent()[i] is ptree
506
- ... if i > 0:
507
- ... assert ptree.left_sibling() is ptree.parent()[i-1]
508
- ... if i < (len(ptree.parent())-1):
509
- ... assert ptree.right_sibling() is ptree.parent()[i+1]
510
- ... assert len(ptree.treeposition()) > 0
511
- ... assert (ptree.treeposition() ==
512
- ... ptree.parent().treeposition() + (ptree.parent_index(),))
513
- ... assert ptree.root() is not ptree
514
- ... assert ptree.root() is not None
515
- ... assert ptree.root() is ptree.parent().root()
516
- ... assert ptree.root()[ptree.treeposition()] is ptree
517
- ... else:
518
- ... assert ptree.parent_index() is None
519
- ... assert ptree.left_sibling() is None
520
- ... assert ptree.right_sibling() is None
521
- ... assert ptree.root() is ptree
522
- ... assert ptree.treeposition() == ()
523
- ... # Check ptree's children's methods:
524
- ... for i, child in enumerate(ptree):
525
- ... if isinstance(child, Tree):
526
- ... # pcheck parent() & parent_index() methods
527
- ... assert child.parent() is ptree
528
- ... assert child.parent_index() == i
529
- ... # pcheck sibling methods
530
- ... if i == 0:
531
- ... assert child.left_sibling() is None
532
- ... else:
533
- ... assert child.left_sibling() is ptree[i-1]
534
- ... if i == len(ptree)-1:
535
- ... assert child.right_sibling() is None
536
- ... else:
537
- ... assert child.right_sibling() is ptree[i+1]
538
- ... if print_ptrees:
539
- ... print('ok!', end=' ')
540
- ... for ptree in print_ptrees: print(ptree)
541
- ... else:
542
- ... print('ok!')
543
-
544
- Run our test function on a variety of newly-created trees:
545
-
546
- >>> pcheck(make_ptree('(A)'))
547
- ok! (A )
548
- >>> pcheck(make_ptree('(A (B (C (D) (E f)) g) h)'))
549
- ok! (A (B (C (D ) (E f)) g) h)
550
- >>> pcheck(make_ptree('(A (B) (C c) (D d d) (E e e e))'))
551
- ok! (A (B ) (C c) (D d d) (E e e e))
552
- >>> pcheck(make_ptree('(A (B) (C (c)) (D (d) (d)) (E (e) (e) (e)))'))
553
- ok! (A (B ) (C (c )) (D (d ) (d )) (E (e ) (e ) (e )))
554
-
555
- Run our test function after performing various tree-modification
556
- operations:
557
-
558
- **__delitem__()**
559
-
560
- >>> ptree = make_ptree('(A (B (C (D) (E f) (Q p)) g) h)')
561
- >>> e = ptree[0,0,1]
562
- >>> del ptree[0,0,1]; pcheck(ptree); pcheck(e)
563
- ok! (A (B (C (D ) (Q p)) g) h)
564
- ok! (E f)
565
- >>> del ptree[0,0,0]; pcheck(ptree)
566
- ok! (A (B (C (Q p)) g) h)
567
- >>> del ptree[0,1]; pcheck(ptree)
568
- ok! (A (B (C (Q p))) h)
569
- >>> del ptree[-1]; pcheck(ptree)
570
- ok! (A (B (C (Q p))))
571
- >>> del ptree[-100]
572
- Traceback (most recent call last):
573
- . . .
574
- IndexError: index out of range
575
- >>> del ptree[()]
576
- Traceback (most recent call last):
577
- . . .
578
- IndexError: The tree position () may not be deleted.
579
-
580
- >>> # With slices:
581
- >>> ptree = make_ptree('(A (B c) (D e) f g (H i) j (K l))')
582
- >>> b = ptree[0]
583
- >>> del ptree[0:0]; pcheck(ptree)
584
- ok! (A (B c) (D e) f g (H i) j (K l))
585
- >>> del ptree[:1]; pcheck(ptree); pcheck(b)
586
- ok! (A (D e) f g (H i) j (K l))
587
- ok! (B c)
588
- >>> del ptree[-2:]; pcheck(ptree)
589
- ok! (A (D e) f g (H i))
590
- >>> del ptree[1:3]; pcheck(ptree)
591
- ok! (A (D e) (H i))
592
- >>> ptree = make_ptree('(A (B c) (D e) f g (H i) j (K l))')
593
- >>> del ptree[5:1000]; pcheck(ptree)
594
- ok! (A (B c) (D e) f g (H i))
595
- >>> del ptree[-2:1000]; pcheck(ptree)
596
- ok! (A (B c) (D e) f)
597
- >>> del ptree[-100:1]; pcheck(ptree)
598
- ok! (A (D e) f)
599
- >>> ptree = make_ptree('(A (B c) (D e) f g (H i) j (K l))')
600
- >>> del ptree[1:-2:2]; pcheck(ptree)
601
- ok! (A (B c) f (H i) j (K l))
602
-
603
- **__setitem__()**
604
-
605
- >>> ptree = make_ptree('(A (B (C (D) (E f) (Q p)) g) h)')
606
- >>> d, e, q = ptree[0,0]
607
- >>> ptree[0,0,0] = 'x'; pcheck(ptree); pcheck(d)
608
- ok! (A (B (C x (E f) (Q p)) g) h)
609
- ok! (D )
610
- >>> ptree[0,0,1] = make_ptree('(X (Y z))'); pcheck(ptree); pcheck(e)
611
- ok! (A (B (C x (X (Y z)) (Q p)) g) h)
612
- ok! (E f)
613
- >>> ptree[1] = d; pcheck(ptree)
614
- ok! (A (B (C x (X (Y z)) (Q p)) g) (D ))
615
- >>> ptree[-1] = 'x'; pcheck(ptree)
616
- ok! (A (B (C x (X (Y z)) (Q p)) g) x)
617
- >>> ptree[-100] = 'y'
618
- Traceback (most recent call last):
619
- . . .
620
- IndexError: index out of range
621
- >>> ptree[()] = make_ptree('(X y)')
622
- Traceback (most recent call last):
623
- . . .
624
- IndexError: The tree position () may not be assigned to.
625
-
626
- >>> # With slices:
627
- >>> ptree = make_ptree('(A (B c) (D e) f g (H i) j (K l))')
628
- >>> b = ptree[0]
629
- >>> ptree[0:0] = ('x', make_ptree('(Y)')); pcheck(ptree)
630
- ok! (A x (Y ) (B c) (D e) f g (H i) j (K l))
631
- >>> ptree[2:6] = (); pcheck(ptree); pcheck(b)
632
- ok! (A x (Y ) (H i) j (K l))
633
- ok! (B c)
634
- >>> ptree[-2:] = ('z', 'p'); pcheck(ptree)
635
- ok! (A x (Y ) (H i) z p)
636
- >>> ptree[1:3] = [make_ptree('(X)') for x in range(10)]; pcheck(ptree)
637
- ok! (A x (X ) (X ) (X ) (X ) (X ) (X ) (X ) (X ) (X ) (X ) z p)
638
- >>> ptree[5:1000] = []; pcheck(ptree)
639
- ok! (A x (X ) (X ) (X ) (X ))
640
- >>> ptree[-2:1000] = ['n']; pcheck(ptree)
641
- ok! (A x (X ) (X ) n)
642
- >>> ptree[-100:1] = [make_ptree('(U v)')]; pcheck(ptree)
643
- ok! (A (U v) (X ) (X ) n)
644
- >>> ptree[-1:] = (make_ptree('(X)') for x in range(3)); pcheck(ptree)
645
- ok! (A (U v) (X ) (X ) (X ) (X ) (X ))
646
- >>> ptree[1:-2:2] = ['x', 'y']; pcheck(ptree)
647
- ok! (A (U v) x (X ) y (X ) (X ))
648
-
649
- **append()**
650
-
651
- >>> ptree = make_ptree('(A (B (C (D) (E f) (Q p)) g) h)')
652
- >>> ptree.append('x'); pcheck(ptree)
653
- ok! (A (B (C (D ) (E f) (Q p)) g) h x)
654
- >>> ptree.append(make_ptree('(X (Y z))')); pcheck(ptree)
655
- ok! (A (B (C (D ) (E f) (Q p)) g) h x (X (Y z)))
656
-
657
- **extend()**
658
-
659
- >>> ptree = make_ptree('(A (B (C (D) (E f) (Q p)) g) h)')
660
- >>> ptree.extend(['x', 'y', make_ptree('(X (Y z))')]); pcheck(ptree)
661
- ok! (A (B (C (D ) (E f) (Q p)) g) h x y (X (Y z)))
662
- >>> ptree.extend([]); pcheck(ptree)
663
- ok! (A (B (C (D ) (E f) (Q p)) g) h x y (X (Y z)))
664
- >>> ptree.extend(make_ptree('(X)') for x in range(3)); pcheck(ptree)
665
- ok! (A (B (C (D ) (E f) (Q p)) g) h x y (X (Y z)) (X ) (X ) (X ))
666
-
667
- **insert()**
668
-
669
- >>> ptree = make_ptree('(A (B (C (D) (E f) (Q p)) g) h)')
670
- >>> ptree.insert(0, make_ptree('(X (Y z))')); pcheck(ptree)
671
- ok! (A (X (Y z)) (B (C (D ) (E f) (Q p)) g) h)
672
- >>> ptree.insert(-1, make_ptree('(X (Y z))')); pcheck(ptree)
673
- ok! (A (X (Y z)) (B (C (D ) (E f) (Q p)) g) (X (Y z)) h)
674
- >>> ptree.insert(-4, make_ptree('(X (Y z))')); pcheck(ptree)
675
- ok! (A (X (Y z)) (X (Y z)) (B (C (D ) (E f) (Q p)) g) (X (Y z)) h)
676
- >>> # Note: as with ``list``, inserting at a negative index that
677
- >>> # gives a position before the start of the list does *not*
678
- >>> # raise an IndexError exception; it just inserts at 0.
679
- >>> ptree.insert(-400, make_ptree('(X (Y z))')); pcheck(ptree)
680
- ok! (A
681
- (X (Y z))
682
- (X (Y z))
683
- (X (Y z))
684
- (B (C (D ) (E f) (Q p)) g)
685
- (X (Y z))
686
- h)
687
-
688
- **pop()**
689
-
690
- >>> ptree = make_ptree('(A (B (C (D) (E f) (Q p)) g) h)')
691
- >>> ptree[0,0].pop(1); pcheck(ptree)
692
- ParentedTree('E', ['f'])
693
- ok! (A (B (C (D ) (Q p)) g) h)
694
- >>> ptree[0].pop(-1); pcheck(ptree)
695
- 'g'
696
- ok! (A (B (C (D ) (Q p))) h)
697
- >>> ptree.pop(); pcheck(ptree)
698
- 'h'
699
- ok! (A (B (C (D ) (Q p))))
700
- >>> ptree.pop(-100)
701
- Traceback (most recent call last):
702
- . . .
703
- IndexError: index out of range
704
-
705
- **remove()**
706
-
707
- >>> ptree = make_ptree('(A (B (C (D) (E f) (Q p)) g) h)')
708
- >>> e = ptree[0,0,1]
709
- >>> ptree[0,0].remove(ptree[0,0,1]); pcheck(ptree); pcheck(e)
710
- ok! (A (B (C (D ) (Q p)) g) h)
711
- ok! (E f)
712
- >>> ptree[0,0].remove(make_ptree('(Q p)')); pcheck(ptree)
713
- ok! (A (B (C (D )) g) h)
714
- >>> ptree[0,0].remove(make_ptree('(Q p)'))
715
- Traceback (most recent call last):
716
- . . .
717
- ValueError: ParentedTree('Q', ['p']) is not in list
718
- >>> ptree.remove('h'); pcheck(ptree)
719
- ok! (A (B (C (D )) g))
720
- >>> ptree.remove('h');
721
- Traceback (most recent call last):
722
- . . .
723
- ValueError: 'h' is not in list
724
- >>> # remove() removes the first subtree that is equal (==) to the
725
- >>> # given tree, which may not be the identical tree we give it:
726
- >>> ptree = make_ptree('(A (X x) (Y y) (X x))')
727
- >>> x1, y, x2 = ptree
728
- >>> ptree.remove(ptree[-1]); pcheck(ptree)
729
- ok! (A (Y y) (X x))
730
- >>> print(x1.parent()); pcheck(x1)
731
- None
732
- ok! (X x)
733
- >>> print(x2.parent())
734
- (A (Y y) (X x))
735
-
736
- Test that a tree can not be given multiple parents:
737
-
738
- >>> ptree = make_ptree('(A (X x) (Y y) (Z z))')
739
- >>> ptree[0] = ptree[1]
740
- Traceback (most recent call last):
741
- . . .
742
- ValueError: Can not insert a subtree that already has a parent.
743
- >>> pcheck()
744
- ok!
745
-
746
- [more to be written]
747
-
748
-
749
- ImmutableParentedTree Regression Tests
750
- --------------------------------------
751
-
752
- >>> iptree = ImmutableParentedTree.convert(ptree)
753
- >>> type(iptree)
754
- <class 'nltk.tree.ImmutableParentedTree'>
755
- >>> del iptree[0]
756
- Traceback (most recent call last):
757
- . . .
758
- ValueError: ImmutableParentedTree may not be modified
759
- >>> iptree.set_label('newnode')
760
- Traceback (most recent call last):
761
- . . .
762
- ValueError: ImmutableParentedTree may not be modified
763
-
764
-
765
- MultiParentedTree Regression Tests
766
- ----------------------------------
767
- Keep track of all trees that we create (including subtrees) using this
768
- variable:
769
-
770
- >>> all_mptrees = []
771
-
772
- Define a helper funciton to create new parented trees:
773
-
774
- >>> def make_mptree(s):
775
- ... mptree = MultiParentedTree.convert(Tree.fromstring(s))
776
- ... all_mptrees.extend(t for t in mptree.subtrees()
777
- ... if isinstance(t, Tree))
778
- ... return mptree
779
-
780
- Define a test function that examines every subtree in all_mptrees; and
781
- checks that all six of its methods are defined correctly. If any
782
- mptrees are passed as arguments, then they are printed.
783
-
784
- >>> def mpcheck(*print_mptrees):
785
- ... def has(seq, val): # uses identity comparison
786
- ... for item in seq:
787
- ... if item is val: return True
788
- ... return False
789
- ... for mptree in all_mptrees:
790
- ... # Check mptree's methods.
791
- ... if len(mptree.parents()) == 0:
792
- ... assert len(mptree.left_siblings()) == 0
793
- ... assert len(mptree.right_siblings()) == 0
794
- ... assert len(mptree.roots()) == 1
795
- ... assert mptree.roots()[0] is mptree
796
- ... assert mptree.treepositions(mptree) == [()]
797
- ... left_siblings = right_siblings = ()
798
- ... roots = {id(mptree): 1}
799
- ... else:
800
- ... roots = dict((id(r), 0) for r in mptree.roots())
801
- ... left_siblings = mptree.left_siblings()
802
- ... right_siblings = mptree.right_siblings()
803
- ... for parent in mptree.parents():
804
- ... for i in mptree.parent_indices(parent):
805
- ... assert parent[i] is mptree
806
- ... # check left siblings
807
- ... if i > 0:
808
- ... for j in range(len(left_siblings)):
809
- ... if left_siblings[j] is parent[i-1]:
810
- ... del left_siblings[j]
811
- ... break
812
- ... else:
813
- ... assert 0, 'sibling not found!'
814
- ... # check ight siblings
815
- ... if i < (len(parent)-1):
816
- ... for j in range(len(right_siblings)):
817
- ... if right_siblings[j] is parent[i+1]:
818
- ... del right_siblings[j]
819
- ... break
820
- ... else:
821
- ... assert 0, 'sibling not found!'
822
- ... # check roots
823
- ... for root in parent.roots():
824
- ... assert id(root) in roots, 'missing root'
825
- ... roots[id(root)] += 1
826
- ... # check that we don't have any unexplained values
827
- ... assert len(left_siblings)==0, 'unexpected sibling'
828
- ... assert len(right_siblings)==0, 'unexpected sibling'
829
- ... for v in roots.values(): assert v>0, roots #'unexpected root'
830
- ... # check treepositions
831
- ... for root in mptree.roots():
832
- ... for treepos in mptree.treepositions(root):
833
- ... assert root[treepos] is mptree
834
- ... # Check mptree's children's methods:
835
- ... for i, child in enumerate(mptree):
836
- ... if isinstance(child, Tree):
837
- ... # mpcheck parent() & parent_index() methods
838
- ... assert has(child.parents(), mptree)
839
- ... assert i in child.parent_indices(mptree)
840
- ... # mpcheck sibling methods
841
- ... if i > 0:
842
- ... assert has(child.left_siblings(), mptree[i-1])
843
- ... if i < len(mptree)-1:
844
- ... assert has(child.right_siblings(), mptree[i+1])
845
- ... if print_mptrees:
846
- ... print('ok!', end=' ')
847
- ... for mptree in print_mptrees: print(mptree)
848
- ... else:
849
- ... print('ok!')
850
-
851
- Run our test function on a variety of newly-created trees:
852
-
853
- >>> mpcheck(make_mptree('(A)'))
854
- ok! (A )
855
- >>> mpcheck(make_mptree('(A (B (C (D) (E f)) g) h)'))
856
- ok! (A (B (C (D ) (E f)) g) h)
857
- >>> mpcheck(make_mptree('(A (B) (C c) (D d d) (E e e e))'))
858
- ok! (A (B ) (C c) (D d d) (E e e e))
859
- >>> mpcheck(make_mptree('(A (B) (C (c)) (D (d) (d)) (E (e) (e) (e)))'))
860
- ok! (A (B ) (C (c )) (D (d ) (d )) (E (e ) (e ) (e )))
861
- >>> subtree = make_mptree('(A (B (C (D) (E f)) g) h)')
862
-
863
- Including some trees that contain multiple parents:
864
-
865
- >>> mpcheck(MultiParentedTree('Z', [subtree, subtree]))
866
- ok! (Z (A (B (C (D ) (E f)) g) h) (A (B (C (D ) (E f)) g) h))
867
-
868
- Run our test function after performing various tree-modification
869
- operations (n.b., these are the same tests that we ran for
870
- `ParentedTree`, above; thus, none of these trees actually *uses*
871
- multiple parents.)
872
-
873
- **__delitem__()**
874
-
875
- >>> mptree = make_mptree('(A (B (C (D) (E f) (Q p)) g) h)')
876
- >>> e = mptree[0,0,1]
877
- >>> del mptree[0,0,1]; mpcheck(mptree); mpcheck(e)
878
- ok! (A (B (C (D ) (Q p)) g) h)
879
- ok! (E f)
880
- >>> del mptree[0,0,0]; mpcheck(mptree)
881
- ok! (A (B (C (Q p)) g) h)
882
- >>> del mptree[0,1]; mpcheck(mptree)
883
- ok! (A (B (C (Q p))) h)
884
- >>> del mptree[-1]; mpcheck(mptree)
885
- ok! (A (B (C (Q p))))
886
- >>> del mptree[-100]
887
- Traceback (most recent call last):
888
- . . .
889
- IndexError: index out of range
890
- >>> del mptree[()]
891
- Traceback (most recent call last):
892
- . . .
893
- IndexError: The tree position () may not be deleted.
894
-
895
- >>> # With slices:
896
- >>> mptree = make_mptree('(A (B c) (D e) f g (H i) j (K l))')
897
- >>> b = mptree[0]
898
- >>> del mptree[0:0]; mpcheck(mptree)
899
- ok! (A (B c) (D e) f g (H i) j (K l))
900
- >>> del mptree[:1]; mpcheck(mptree); mpcheck(b)
901
- ok! (A (D e) f g (H i) j (K l))
902
- ok! (B c)
903
- >>> del mptree[-2:]; mpcheck(mptree)
904
- ok! (A (D e) f g (H i))
905
- >>> del mptree[1:3]; mpcheck(mptree)
906
- ok! (A (D e) (H i))
907
- >>> mptree = make_mptree('(A (B c) (D e) f g (H i) j (K l))')
908
- >>> del mptree[5:1000]; mpcheck(mptree)
909
- ok! (A (B c) (D e) f g (H i))
910
- >>> del mptree[-2:1000]; mpcheck(mptree)
911
- ok! (A (B c) (D e) f)
912
- >>> del mptree[-100:1]; mpcheck(mptree)
913
- ok! (A (D e) f)
914
- >>> mptree = make_mptree('(A (B c) (D e) f g (H i) j (K l))')
915
- >>> del mptree[1:-2:2]; mpcheck(mptree)
916
- ok! (A (B c) f (H i) j (K l))
917
-
918
- **__setitem__()**
919
-
920
- >>> mptree = make_mptree('(A (B (C (D) (E f) (Q p)) g) h)')
921
- >>> d, e, q = mptree[0,0]
922
- >>> mptree[0,0,0] = 'x'; mpcheck(mptree); mpcheck(d)
923
- ok! (A (B (C x (E f) (Q p)) g) h)
924
- ok! (D )
925
- >>> mptree[0,0,1] = make_mptree('(X (Y z))'); mpcheck(mptree); mpcheck(e)
926
- ok! (A (B (C x (X (Y z)) (Q p)) g) h)
927
- ok! (E f)
928
- >>> mptree[1] = d; mpcheck(mptree)
929
- ok! (A (B (C x (X (Y z)) (Q p)) g) (D ))
930
- >>> mptree[-1] = 'x'; mpcheck(mptree)
931
- ok! (A (B (C x (X (Y z)) (Q p)) g) x)
932
- >>> mptree[-100] = 'y'
933
- Traceback (most recent call last):
934
- . . .
935
- IndexError: index out of range
936
- >>> mptree[()] = make_mptree('(X y)')
937
- Traceback (most recent call last):
938
- . . .
939
- IndexError: The tree position () may not be assigned to.
940
-
941
- >>> # With slices:
942
- >>> mptree = make_mptree('(A (B c) (D e) f g (H i) j (K l))')
943
- >>> b = mptree[0]
944
- >>> mptree[0:0] = ('x', make_mptree('(Y)')); mpcheck(mptree)
945
- ok! (A x (Y ) (B c) (D e) f g (H i) j (K l))
946
- >>> mptree[2:6] = (); mpcheck(mptree); mpcheck(b)
947
- ok! (A x (Y ) (H i) j (K l))
948
- ok! (B c)
949
- >>> mptree[-2:] = ('z', 'p'); mpcheck(mptree)
950
- ok! (A x (Y ) (H i) z p)
951
- >>> mptree[1:3] = [make_mptree('(X)') for x in range(10)]; mpcheck(mptree)
952
- ok! (A x (X ) (X ) (X ) (X ) (X ) (X ) (X ) (X ) (X ) (X ) z p)
953
- >>> mptree[5:1000] = []; mpcheck(mptree)
954
- ok! (A x (X ) (X ) (X ) (X ))
955
- >>> mptree[-2:1000] = ['n']; mpcheck(mptree)
956
- ok! (A x (X ) (X ) n)
957
- >>> mptree[-100:1] = [make_mptree('(U v)')]; mpcheck(mptree)
958
- ok! (A (U v) (X ) (X ) n)
959
- >>> mptree[-1:] = (make_mptree('(X)') for x in range(3)); mpcheck(mptree)
960
- ok! (A (U v) (X ) (X ) (X ) (X ) (X ))
961
- >>> mptree[1:-2:2] = ['x', 'y']; mpcheck(mptree)
962
- ok! (A (U v) x (X ) y (X ) (X ))
963
-
964
- **append()**
965
-
966
- >>> mptree = make_mptree('(A (B (C (D) (E f) (Q p)) g) h)')
967
- >>> mptree.append('x'); mpcheck(mptree)
968
- ok! (A (B (C (D ) (E f) (Q p)) g) h x)
969
- >>> mptree.append(make_mptree('(X (Y z))')); mpcheck(mptree)
970
- ok! (A (B (C (D ) (E f) (Q p)) g) h x (X (Y z)))
971
-
972
- **extend()**
973
-
974
- >>> mptree = make_mptree('(A (B (C (D) (E f) (Q p)) g) h)')
975
- >>> mptree.extend(['x', 'y', make_mptree('(X (Y z))')]); mpcheck(mptree)
976
- ok! (A (B (C (D ) (E f) (Q p)) g) h x y (X (Y z)))
977
- >>> mptree.extend([]); mpcheck(mptree)
978
- ok! (A (B (C (D ) (E f) (Q p)) g) h x y (X (Y z)))
979
- >>> mptree.extend(make_mptree('(X)') for x in range(3)); mpcheck(mptree)
980
- ok! (A (B (C (D ) (E f) (Q p)) g) h x y (X (Y z)) (X ) (X ) (X ))
981
-
982
- **insert()**
983
-
984
- >>> mptree = make_mptree('(A (B (C (D) (E f) (Q p)) g) h)')
985
- >>> mptree.insert(0, make_mptree('(X (Y z))')); mpcheck(mptree)
986
- ok! (A (X (Y z)) (B (C (D ) (E f) (Q p)) g) h)
987
- >>> mptree.insert(-1, make_mptree('(X (Y z))')); mpcheck(mptree)
988
- ok! (A (X (Y z)) (B (C (D ) (E f) (Q p)) g) (X (Y z)) h)
989
- >>> mptree.insert(-4, make_mptree('(X (Y z))')); mpcheck(mptree)
990
- ok! (A (X (Y z)) (X (Y z)) (B (C (D ) (E f) (Q p)) g) (X (Y z)) h)
991
- >>> # Note: as with ``list``, inserting at a negative index that
992
- >>> # gives a position before the start of the list does *not*
993
- >>> # raise an IndexError exception; it just inserts at 0.
994
- >>> mptree.insert(-400, make_mptree('(X (Y z))')); mpcheck(mptree)
995
- ok! (A
996
- (X (Y z))
997
- (X (Y z))
998
- (X (Y z))
999
- (B (C (D ) (E f) (Q p)) g)
1000
- (X (Y z))
1001
- h)
1002
-
1003
- **pop()**
1004
-
1005
- >>> mptree = make_mptree('(A (B (C (D) (E f) (Q p)) g) h)')
1006
- >>> mptree[0,0].pop(1); mpcheck(mptree)
1007
- MultiParentedTree('E', ['f'])
1008
- ok! (A (B (C (D ) (Q p)) g) h)
1009
- >>> mptree[0].pop(-1); mpcheck(mptree)
1010
- 'g'
1011
- ok! (A (B (C (D ) (Q p))) h)
1012
- >>> mptree.pop(); mpcheck(mptree)
1013
- 'h'
1014
- ok! (A (B (C (D ) (Q p))))
1015
- >>> mptree.pop(-100)
1016
- Traceback (most recent call last):
1017
- . . .
1018
- IndexError: index out of range
1019
-
1020
- **remove()**
1021
-
1022
- >>> mptree = make_mptree('(A (B (C (D) (E f) (Q p)) g) h)')
1023
- >>> e = mptree[0,0,1]
1024
- >>> mptree[0,0].remove(mptree[0,0,1]); mpcheck(mptree); mpcheck(e)
1025
- ok! (A (B (C (D ) (Q p)) g) h)
1026
- ok! (E f)
1027
- >>> mptree[0,0].remove(make_mptree('(Q p)')); mpcheck(mptree)
1028
- ok! (A (B (C (D )) g) h)
1029
- >>> mptree[0,0].remove(make_mptree('(Q p)'))
1030
- Traceback (most recent call last):
1031
- . . .
1032
- ValueError: MultiParentedTree('Q', ['p']) is not in list
1033
- >>> mptree.remove('h'); mpcheck(mptree)
1034
- ok! (A (B (C (D )) g))
1035
- >>> mptree.remove('h');
1036
- Traceback (most recent call last):
1037
- . . .
1038
- ValueError: 'h' is not in list
1039
- >>> # remove() removes the first subtree that is equal (==) to the
1040
- >>> # given tree, which may not be the identical tree we give it:
1041
- >>> mptree = make_mptree('(A (X x) (Y y) (X x))')
1042
- >>> x1, y, x2 = mptree
1043
- >>> mptree.remove(mptree[-1]); mpcheck(mptree)
1044
- ok! (A (Y y) (X x))
1045
- >>> print([str(p) for p in x1.parents()])
1046
- []
1047
- >>> print([str(p) for p in x2.parents()])
1048
- ['(A (Y y) (X x))']
1049
-
1050
-
1051
- ImmutableMultiParentedTree Regression Tests
1052
- -------------------------------------------
1053
-
1054
- >>> imptree = ImmutableMultiParentedTree.convert(mptree)
1055
- >>> type(imptree)
1056
- <class 'nltk.tree.ImmutableMultiParentedTree'>
1057
- >>> del imptree[0]
1058
- Traceback (most recent call last):
1059
- . . .
1060
- ValueError: ImmutableMultiParentedTree may not be modified
1061
- >>> imptree.set_label('newnode')
1062
- Traceback (most recent call last):
1063
- . . .
1064
- ValueError: ImmutableMultiParentedTree may not be modified
1065
-
1066
-
1067
- ProbabilisticTree Regression Tests
1068
- ----------------------------------
1069
-
1070
- >>> prtree = ProbabilisticTree("S", [ProbabilisticTree("NP", ["N"], prob=0.3)], prob=0.6)
1071
- >>> print(prtree)
1072
- (S (NP N)) (p=0.6)
1073
- >>> import copy
1074
- >>> prtree == copy.deepcopy(prtree) == prtree.copy(deep=True) == prtree.copy()
1075
- True
1076
- >>> prtree[0] is prtree.copy()[0]
1077
- True
1078
- >>> prtree[0] is prtree.copy(deep=True)[0]
1079
- False
1080
-
1081
- >>> imprtree = ImmutableProbabilisticTree.convert(prtree)
1082
- >>> type(imprtree)
1083
- <class 'nltk.tree.ImmutableProbabilisticTree'>
1084
- >>> del imprtree[0]
1085
- Traceback (most recent call last):
1086
- . . .
1087
- ValueError: ImmutableProbabilisticTree may not be modified
1088
- >>> imprtree.set_label('newnode')
1089
- Traceback (most recent call last):
1090
- . . .
1091
- ValueError: ImmutableProbabilisticTree may not be modified
1092
-
1093
-
1094
- Squashed Bugs
1095
- =============
1096
-
1097
- This used to discard the ``(B b)`` subtree (fixed in svn 6270):
1098
-
1099
- >>> print(Tree.fromstring('((A a) (B b))'))
1100
- ( (A a) (B b))
1101
-
1
+ .. Copyright (C) 2001-2018 NLTK Project
2
+ .. For license information, see LICENSE.TXT
3
+
4
+ ===============================
5
+ Unit tests for nltk.tree.Tree
6
+ ===============================
7
+
8
+ >>> from nltk.tree import *
9
+
10
+ Some trees to run tests on:
11
+
12
+ >>> dp1 = Tree('dp', [Tree('d', ['the']), Tree('np', ['dog'])])
13
+ >>> dp2 = Tree('dp', [Tree('d', ['the']), Tree('np', ['cat'])])
14
+ >>> vp = Tree('vp', [Tree('v', ['chased']), dp2])
15
+ >>> tree = Tree('s', [dp1, vp])
16
+ >>> print(tree)
17
+ (s (dp (d the) (np dog)) (vp (v chased) (dp (d the) (np cat))))
18
+
19
+ The node label is accessed using the `label()` method:
20
+
21
+ >>> dp1.label(), dp2.label(), vp.label(), tree.label()
22
+ ('dp', 'dp', 'vp', 's')
23
+
24
+ >>> print(tree[1,1,1,0])
25
+ cat
26
+
27
+ The `treepositions` method returns a list of the tree positions of
28
+ subtrees and leaves in a tree. By default, it gives the position of
29
+ every tree, subtree, and leaf, in prefix order:
30
+
31
+ >>> print(tree.treepositions())
32
+ [(), (0,), (0, 0), (0, 0, 0), (0, 1), (0, 1, 0), (1,), (1, 0), (1, 0, 0), (1, 1), (1, 1, 0), (1, 1, 0, 0), (1, 1, 1), (1, 1, 1, 0)]
33
+
34
+ In addition to `str` and `repr`, several methods exist to convert a
35
+ tree object to one of several standard tree encodings:
36
+
37
+ >>> print(tree.pformat_latex_qtree())
38
+ \Tree [.s
39
+ [.dp [.d the ] [.np dog ] ]
40
+ [.vp [.v chased ] [.dp [.d the ] [.np cat ] ] ] ]
41
+
42
+ There is also a fancy ASCII art representation:
43
+
44
+ >>> tree.pretty_print()
45
+ s
46
+ ________|_____
47
+ | vp
48
+ | _____|___
49
+ dp | dp
50
+ ___|___ | ___|___
51
+ d np v d np
52
+ | | | | |
53
+ the dog chased the cat
54
+
55
+ >>> tree.pretty_print(unicodelines=True, nodedist=4)
56
+ s
57
+ ┌──────────────┴────────┐
58
+ │ vp
59
+ │ ┌────────┴──────┐
60
+ dp │ dp
61
+ ┌──────┴──────┐ │ ┌──────┴──────┐
62
+ d np v d np
63
+ │ │ │ │ │
64
+ the dog chased the cat
65
+
66
+ Trees can be initialized from treebank strings:
67
+
68
+ >>> tree2 = Tree.fromstring('(S (NP I) (VP (V enjoyed) (NP my cookie)))')
69
+ >>> print(tree2)
70
+ (S (NP I) (VP (V enjoyed) (NP my cookie)))
71
+
72
+ Trees can be compared for equality:
73
+
74
+ >>> tree == Tree.fromstring(str(tree))
75
+ True
76
+ >>> tree2 == Tree.fromstring(str(tree2))
77
+ True
78
+ >>> tree == tree2
79
+ False
80
+ >>> tree == Tree.fromstring(str(tree2))
81
+ False
82
+ >>> tree2 == Tree.fromstring(str(tree))
83
+ False
84
+
85
+ >>> tree != Tree.fromstring(str(tree))
86
+ False
87
+ >>> tree2 != Tree.fromstring(str(tree2))
88
+ False
89
+ >>> tree != tree2
90
+ True
91
+ >>> tree != Tree.fromstring(str(tree2))
92
+ True
93
+ >>> tree2 != Tree.fromstring(str(tree))
94
+ True
95
+
96
+ >>> tree < tree2 or tree > tree2
97
+ True
98
+
99
+ Tree Parsing
100
+ ============
101
+
102
+ The class method `Tree.fromstring()` can be used to parse trees, and it
103
+ provides some additional options.
104
+
105
+ >>> tree = Tree.fromstring('(S (NP I) (VP (V enjoyed) (NP my cookie)))')
106
+ >>> print(tree)
107
+ (S (NP I) (VP (V enjoyed) (NP my cookie)))
108
+
109
+ When called on a subclass of `Tree`, it will create trees of that
110
+ type:
111
+
112
+ >>> tree = ImmutableTree.fromstring('(VP (V enjoyed) (NP my cookie))')
113
+ >>> print(tree)
114
+ (VP (V enjoyed) (NP my cookie))
115
+ >>> print(type(tree))
116
+ <class 'nltk.tree.ImmutableTree'>
117
+ >>> tree[1] = 'x'
118
+ Traceback (most recent call last):
119
+ . . .
120
+ ValueError: ImmutableTree may not be modified
121
+ >>> del tree[0]
122
+ Traceback (most recent call last):
123
+ . . .
124
+ ValueError: ImmutableTree may not be modified
125
+
126
+ The ``brackets`` parameter can be used to specify two characters that
127
+ should be used as brackets:
128
+
129
+ >>> print(Tree.fromstring('[S [NP I] [VP [V enjoyed] [NP my cookie]]]',
130
+ ... brackets='[]'))
131
+ (S (NP I) (VP (V enjoyed) (NP my cookie)))
132
+ >>> print(Tree.fromstring('<S <NP I> <VP <V enjoyed> <NP my cookie>>>',
133
+ ... brackets='<>'))
134
+ (S (NP I) (VP (V enjoyed) (NP my cookie)))
135
+
136
+ If ``brackets`` is not a string, or is not exactly two characters,
137
+ then `Tree.fromstring` raises an exception:
138
+
139
+ >>> Tree.fromstring('<VP <V enjoyed> <NP my cookie>>', brackets='')
140
+ Traceback (most recent call last):
141
+ . . .
142
+ TypeError: brackets must be a length-2 string
143
+ >>> Tree.fromstring('<VP <V enjoyed> <NP my cookie>>', brackets='<<>>')
144
+ Traceback (most recent call last):
145
+ . . .
146
+ TypeError: brackets must be a length-2 string
147
+ >>> Tree.fromstring('<VP <V enjoyed> <NP my cookie>>', brackets=12)
148
+ Traceback (most recent call last):
149
+ . . .
150
+ TypeError: brackets must be a length-2 string
151
+ >>> Tree.fromstring('<<NP my cookie>>', brackets=('<<','>>'))
152
+ Traceback (most recent call last):
153
+ . . .
154
+ TypeError: brackets must be a length-2 string
155
+
156
+ (We may add support for multi-character brackets in the future, in
157
+ which case the ``brackets=('<<','>>')`` example would start working.)
158
+
159
+ Whitespace brackets are not permitted:
160
+
161
+ >>> Tree.fromstring('(NP my cookie\n', brackets='(\n')
162
+ Traceback (most recent call last):
163
+ . . .
164
+ TypeError: whitespace brackets not allowed
165
+
166
+ If an invalid tree is given to Tree.fromstring, then it raises a
167
+ ValueError, with a description of the problem:
168
+
169
+ >>> Tree.fromstring('(NP my cookie) (NP my milk)')
170
+ Traceback (most recent call last):
171
+ . . .
172
+ ValueError: Tree.fromstring(): expected 'end-of-string' but got '(NP'
173
+ at index 15.
174
+ "...y cookie) (NP my mil..."
175
+ ^
176
+ >>> Tree.fromstring(')NP my cookie(')
177
+ Traceback (most recent call last):
178
+ . . .
179
+ ValueError: Tree.fromstring(): expected '(' but got ')'
180
+ at index 0.
181
+ ")NP my coo..."
182
+ ^
183
+ >>> Tree.fromstring('(NP my cookie))')
184
+ Traceback (most recent call last):
185
+ . . .
186
+ ValueError: Tree.fromstring(): expected 'end-of-string' but got ')'
187
+ at index 14.
188
+ "...my cookie))"
189
+ ^
190
+ >>> Tree.fromstring('my cookie)')
191
+ Traceback (most recent call last):
192
+ . . .
193
+ ValueError: Tree.fromstring(): expected '(' but got 'my'
194
+ at index 0.
195
+ "my cookie)"
196
+ ^
197
+ >>> Tree.fromstring('(NP my cookie')
198
+ Traceback (most recent call last):
199
+ . . .
200
+ ValueError: Tree.fromstring(): expected ')' but got 'end-of-string'
201
+ at index 13.
202
+ "... my cookie"
203
+ ^
204
+ >>> Tree.fromstring('')
205
+ Traceback (most recent call last):
206
+ . . .
207
+ ValueError: Tree.fromstring(): expected '(' but got 'end-of-string'
208
+ at index 0.
209
+ ""
210
+ ^
211
+
212
+ Trees with no children are supported:
213
+
214
+ >>> print(Tree.fromstring('(S)'))
215
+ (S )
216
+ >>> print(Tree.fromstring('(X (Y) (Z))'))
217
+ (X (Y ) (Z ))
218
+
219
+ Trees with an empty node label and no children are supported:
220
+
221
+ >>> print(Tree.fromstring('()'))
222
+ ( )
223
+ >>> print(Tree.fromstring('(X () ())'))
224
+ (X ( ) ( ))
225
+
226
+ Trees with an empty node label and children are supported, but only if the
227
+ first child is not a leaf (otherwise, it will be treated as the node label).
228
+
229
+ >>> print(Tree.fromstring('((A) (B) (C))'))
230
+ ( (A ) (B ) (C ))
231
+ >>> print(Tree.fromstring('((A) leaf)'))
232
+ ( (A ) leaf)
233
+ >>> print(Tree.fromstring('(((())))'))
234
+ ( ( ( ( ))))
235
+
236
+ The optional arguments `read_node` and `read_leaf` may be used to
237
+ transform the string values of nodes or leaves.
238
+
239
+ >>> print(Tree.fromstring('(A b (C d e) (F (G h i)))',
240
+ ... read_node=lambda s: '<%s>' % s,
241
+ ... read_leaf=lambda s: '"%s"' % s))
242
+ (<A> "b" (<C> "d" "e") (<F> (<G> "h" "i")))
243
+
244
+ These transformation functions are typically used when the node or
245
+ leaf labels should be parsed to a non-string value (such as a feature
246
+ structure). If node and leaf labels need to be able to include
247
+ whitespace, then you must also use the optional `node_pattern` and
248
+ `leaf_pattern` arguments.
249
+
250
+ >>> from nltk.featstruct import FeatStruct
251
+ >>> tree = Tree.fromstring('([cat=NP] [lex=the] [lex=dog])',
252
+ ... read_node=FeatStruct, read_leaf=FeatStruct)
253
+ >>> tree.set_label(tree.label().unify(FeatStruct('[num=singular]')))
254
+ >>> print(tree)
255
+ ([cat='NP', num='singular'] [lex='the'] [lex='dog'])
256
+
257
+ The optional argument ``remove_empty_top_bracketing`` can be used to
258
+ remove any top-level empty bracketing that occurs.
259
+
260
+ >>> print(Tree.fromstring('((S (NP I) (VP (V enjoyed) (NP my cookie))))',
261
+ ... remove_empty_top_bracketing=True))
262
+ (S (NP I) (VP (V enjoyed) (NP my cookie)))
263
+
264
+ It will not remove a top-level empty bracketing with multiple children:
265
+
266
+ >>> print(Tree.fromstring('((A a) (B b))'))
267
+ ( (A a) (B b))
268
+
269
+ Parented Trees
270
+ ==============
271
+ `ParentedTree` is a subclass of `Tree` that automatically maintains
272
+ parent pointers for single-parented trees. Parented trees can be
273
+ created directly from a node label and a list of children:
274
+
275
+ >>> ptree = (
276
+ ... ParentedTree('VP', [
277
+ ... ParentedTree('VERB', ['saw']),
278
+ ... ParentedTree('NP', [
279
+ ... ParentedTree('DET', ['the']),
280
+ ... ParentedTree('NOUN', ['dog'])])]))
281
+ >>> print(ptree)
282
+ (VP (VERB saw) (NP (DET the) (NOUN dog)))
283
+
284
+ Parented trees can be created from strings using the classmethod
285
+ `ParentedTree.fromstring`:
286
+
287
+ >>> ptree = ParentedTree.fromstring('(VP (VERB saw) (NP (DET the) (NOUN dog)))')
288
+ >>> print(ptree)
289
+ (VP (VERB saw) (NP (DET the) (NOUN dog)))
290
+ >>> print(type(ptree))
291
+ <class 'nltk.tree.ParentedTree'>
292
+
293
+ Parented trees can also be created by using the classmethod
294
+ `ParentedTree.convert` to convert another type of tree to a parented
295
+ tree:
296
+
297
+ >>> tree = Tree.fromstring('(VP (VERB saw) (NP (DET the) (NOUN dog)))')
298
+ >>> ptree = ParentedTree.convert(tree)
299
+ >>> print(ptree)
300
+ (VP (VERB saw) (NP (DET the) (NOUN dog)))
301
+ >>> print(type(ptree))
302
+ <class 'nltk.tree.ParentedTree'>
303
+
304
+ .. clean-up:
305
+
306
+ >>> del tree
307
+
308
+ `ParentedTree`\ s should never be used in the same tree as `Tree`\ s
309
+ or `MultiParentedTree`\ s. Mixing tree implementations may result in
310
+ incorrect parent pointers and in `TypeError` exceptions:
311
+
312
+ >>> # Inserting a Tree in a ParentedTree gives an exception:
313
+ >>> ParentedTree('NP', [
314
+ ... Tree('DET', ['the']), Tree('NOUN', ['dog'])])
315
+ Traceback (most recent call last):
316
+ . . .
317
+ TypeError: Can not insert a non-ParentedTree into a ParentedTree
318
+
319
+ >>> # inserting a ParentedTree in a Tree gives incorrect parent pointers:
320
+ >>> broken_tree = Tree('NP', [
321
+ ... ParentedTree('DET', ['the']), ParentedTree('NOUN', ['dog'])])
322
+ >>> print(broken_tree[0].parent())
323
+ None
324
+
325
+ Parented Tree Methods
326
+ ------------------------
327
+ In addition to all the methods defined by the `Tree` class, the
328
+ `ParentedTree` class adds six new methods whose values are
329
+ automatically updated whenver a parented tree is modified: `parent()`,
330
+ `parent_index()`, `left_sibling()`, `right_sibling()`, `root()`, and
331
+ `treeposition()`.
332
+
333
+ The `parent()` method contains a `ParentedTree`\ 's parent, if it has
334
+ one; and ``None`` otherwise. `ParentedTree`\ s that do not have
335
+ parents are known as "root trees."
336
+
337
+ >>> for subtree in ptree.subtrees():
338
+ ... print(subtree)
339
+ ... print(' Parent = %s' % subtree.parent())
340
+ (VP (VERB saw) (NP (DET the) (NOUN dog)))
341
+ Parent = None
342
+ (VERB saw)
343
+ Parent = (VP (VERB saw) (NP (DET the) (NOUN dog)))
344
+ (NP (DET the) (NOUN dog))
345
+ Parent = (VP (VERB saw) (NP (DET the) (NOUN dog)))
346
+ (DET the)
347
+ Parent = (NP (DET the) (NOUN dog))
348
+ (NOUN dog)
349
+ Parent = (NP (DET the) (NOUN dog))
350
+
351
+ The `parent_index()` method stores the index of a tree in its parent's
352
+ child list. If a tree does not have a parent, then its `parent_index`
353
+ is ``None``.
354
+
355
+ >>> for subtree in ptree.subtrees():
356
+ ... print(subtree)
357
+ ... print(' Parent Index = %s' % subtree.parent_index())
358
+ ... assert (subtree.parent() is None or
359
+ ... subtree.parent()[subtree.parent_index()] is subtree)
360
+ (VP (VERB saw) (NP (DET the) (NOUN dog)))
361
+ Parent Index = None
362
+ (VERB saw)
363
+ Parent Index = 0
364
+ (NP (DET the) (NOUN dog))
365
+ Parent Index = 1
366
+ (DET the)
367
+ Parent Index = 0
368
+ (NOUN dog)
369
+ Parent Index = 1
370
+
371
+ Note that ``ptree.parent().index(ptree)`` is *not* equivalent to
372
+ ``ptree.parent_index()``. In particular, ``ptree.parent().index(ptree)``
373
+ will return the index of the first child of ``ptree.parent()`` that is
374
+ equal to ``ptree`` (using ``==``); and that child may not be
375
+ ``ptree``:
376
+
377
+ >>> on_and_on = ParentedTree('CONJP', [
378
+ ... ParentedTree('PREP', ['on']),
379
+ ... ParentedTree('COJN', ['and']),
380
+ ... ParentedTree('PREP', ['on'])])
381
+ >>> second_on = on_and_on[2]
382
+ >>> print(second_on.parent_index())
383
+ 2
384
+ >>> print(second_on.parent().index(second_on))
385
+ 0
386
+
387
+ The methods `left_sibling()` and `right_sibling()` can be used to get a
388
+ parented tree's siblings. If a tree does not have a left or right
389
+ sibling, then the corresponding method's value is ``None``:
390
+
391
+ >>> for subtree in ptree.subtrees():
392
+ ... print(subtree)
393
+ ... print(' Left Sibling = %s' % subtree.left_sibling())
394
+ ... print(' Right Sibling = %s' % subtree.right_sibling())
395
+ (VP (VERB saw) (NP (DET the) (NOUN dog)))
396
+ Left Sibling = None
397
+ Right Sibling = None
398
+ (VERB saw)
399
+ Left Sibling = None
400
+ Right Sibling = (NP (DET the) (NOUN dog))
401
+ (NP (DET the) (NOUN dog))
402
+ Left Sibling = (VERB saw)
403
+ Right Sibling = None
404
+ (DET the)
405
+ Left Sibling = None
406
+ Right Sibling = (NOUN dog)
407
+ (NOUN dog)
408
+ Left Sibling = (DET the)
409
+ Right Sibling = None
410
+
411
+ A parented tree's root tree can be accessed using the `root()`
412
+ method. This method follows the tree's parent pointers until it
413
+ finds a tree without a parent. If a tree does not have a parent, then
414
+ it is its own root:
415
+
416
+ >>> for subtree in ptree.subtrees():
417
+ ... print(subtree)
418
+ ... print(' Root = %s' % subtree.root())
419
+ (VP (VERB saw) (NP (DET the) (NOUN dog)))
420
+ Root = (VP (VERB saw) (NP (DET the) (NOUN dog)))
421
+ (VERB saw)
422
+ Root = (VP (VERB saw) (NP (DET the) (NOUN dog)))
423
+ (NP (DET the) (NOUN dog))
424
+ Root = (VP (VERB saw) (NP (DET the) (NOUN dog)))
425
+ (DET the)
426
+ Root = (VP (VERB saw) (NP (DET the) (NOUN dog)))
427
+ (NOUN dog)
428
+ Root = (VP (VERB saw) (NP (DET the) (NOUN dog)))
429
+
430
+ The `treeposition()` method can be used to find a tree's treeposition
431
+ relative to its root:
432
+
433
+ >>> for subtree in ptree.subtrees():
434
+ ... print(subtree)
435
+ ... print(' Tree Position = %s' % (subtree.treeposition(),))
436
+ ... assert subtree.root()[subtree.treeposition()] is subtree
437
+ (VP (VERB saw) (NP (DET the) (NOUN dog)))
438
+ Tree Position = ()
439
+ (VERB saw)
440
+ Tree Position = (0,)
441
+ (NP (DET the) (NOUN dog))
442
+ Tree Position = (1,)
443
+ (DET the)
444
+ Tree Position = (1, 0)
445
+ (NOUN dog)
446
+ Tree Position = (1, 1)
447
+
448
+ Whenever a parented tree is modified, all of the methods described
449
+ above (`parent()`, `parent_index()`, `left_sibling()`, `right_sibling()`,
450
+ `root()`, and `treeposition()`) are automatically updated. For example,
451
+ if we replace ``ptree``\ 's subtree for the word "dog" with a new
452
+ subtree for "cat," the method values for both the "dog" subtree and the
453
+ "cat" subtree get automatically updated:
454
+
455
+ >>> # Replace the dog with a cat
456
+ >>> dog = ptree[1,1]
457
+ >>> cat = ParentedTree('NOUN', ['cat'])
458
+ >>> ptree[1,1] = cat
459
+
460
+ >>> # the noun phrase is no longer the dog's parent:
461
+ >>> print(dog.parent(), dog.parent_index(), dog.left_sibling())
462
+ None None None
463
+ >>> # dog is now its own root.
464
+ >>> print(dog.root())
465
+ (NOUN dog)
466
+ >>> print(dog.treeposition())
467
+ ()
468
+
469
+ >>> # the cat's parent is now the noun phrase:
470
+ >>> print(cat.parent())
471
+ (NP (DET the) (NOUN cat))
472
+ >>> print(cat.parent_index())
473
+ 1
474
+ >>> print(cat.left_sibling())
475
+ (DET the)
476
+ >>> print(cat.root())
477
+ (VP (VERB saw) (NP (DET the) (NOUN cat)))
478
+ >>> print(cat.treeposition())
479
+ (1, 1)
480
+
481
+ ParentedTree Regression Tests
482
+ -----------------------------
483
+ Keep track of all trees that we create (including subtrees) using this
484
+ variable:
485
+
486
+ >>> all_ptrees = []
487
+
488
+ Define a helper funciton to create new parented trees:
489
+
490
+ >>> def make_ptree(s):
491
+ ... ptree = ParentedTree.convert(Tree.fromstring(s))
492
+ ... all_ptrees.extend(t for t in ptree.subtrees()
493
+ ... if isinstance(t, Tree))
494
+ ... return ptree
495
+
496
+ Define a test function that examines every subtree in all_ptrees; and
497
+ checks that all six of its methods are defined correctly. If any
498
+ ptrees are passed as arguments, then they are printed.
499
+
500
+ >>> def pcheck(*print_ptrees):
501
+ ... for ptree in all_ptrees:
502
+ ... # Check ptree's methods.
503
+ ... if ptree.parent() is not None:
504
+ ... i = ptree.parent_index()
505
+ ... assert ptree.parent()[i] is ptree
506
+ ... if i > 0:
507
+ ... assert ptree.left_sibling() is ptree.parent()[i-1]
508
+ ... if i < (len(ptree.parent())-1):
509
+ ... assert ptree.right_sibling() is ptree.parent()[i+1]
510
+ ... assert len(ptree.treeposition()) > 0
511
+ ... assert (ptree.treeposition() ==
512
+ ... ptree.parent().treeposition() + (ptree.parent_index(),))
513
+ ... assert ptree.root() is not ptree
514
+ ... assert ptree.root() is not None
515
+ ... assert ptree.root() is ptree.parent().root()
516
+ ... assert ptree.root()[ptree.treeposition()] is ptree
517
+ ... else:
518
+ ... assert ptree.parent_index() is None
519
+ ... assert ptree.left_sibling() is None
520
+ ... assert ptree.right_sibling() is None
521
+ ... assert ptree.root() is ptree
522
+ ... assert ptree.treeposition() == ()
523
+ ... # Check ptree's children's methods:
524
+ ... for i, child in enumerate(ptree):
525
+ ... if isinstance(child, Tree):
526
+ ... # pcheck parent() & parent_index() methods
527
+ ... assert child.parent() is ptree
528
+ ... assert child.parent_index() == i
529
+ ... # pcheck sibling methods
530
+ ... if i == 0:
531
+ ... assert child.left_sibling() is None
532
+ ... else:
533
+ ... assert child.left_sibling() is ptree[i-1]
534
+ ... if i == len(ptree)-1:
535
+ ... assert child.right_sibling() is None
536
+ ... else:
537
+ ... assert child.right_sibling() is ptree[i+1]
538
+ ... if print_ptrees:
539
+ ... print('ok!', end=' ')
540
+ ... for ptree in print_ptrees: print(ptree)
541
+ ... else:
542
+ ... print('ok!')
543
+
544
+ Run our test function on a variety of newly-created trees:
545
+
546
+ >>> pcheck(make_ptree('(A)'))
547
+ ok! (A )
548
+ >>> pcheck(make_ptree('(A (B (C (D) (E f)) g) h)'))
549
+ ok! (A (B (C (D ) (E f)) g) h)
550
+ >>> pcheck(make_ptree('(A (B) (C c) (D d d) (E e e e))'))
551
+ ok! (A (B ) (C c) (D d d) (E e e e))
552
+ >>> pcheck(make_ptree('(A (B) (C (c)) (D (d) (d)) (E (e) (e) (e)))'))
553
+ ok! (A (B ) (C (c )) (D (d ) (d )) (E (e ) (e ) (e )))
554
+
555
+ Run our test function after performing various tree-modification
556
+ operations:
557
+
558
+ **__delitem__()**
559
+
560
+ >>> ptree = make_ptree('(A (B (C (D) (E f) (Q p)) g) h)')
561
+ >>> e = ptree[0,0,1]
562
+ >>> del ptree[0,0,1]; pcheck(ptree); pcheck(e)
563
+ ok! (A (B (C (D ) (Q p)) g) h)
564
+ ok! (E f)
565
+ >>> del ptree[0,0,0]; pcheck(ptree)
566
+ ok! (A (B (C (Q p)) g) h)
567
+ >>> del ptree[0,1]; pcheck(ptree)
568
+ ok! (A (B (C (Q p))) h)
569
+ >>> del ptree[-1]; pcheck(ptree)
570
+ ok! (A (B (C (Q p))))
571
+ >>> del ptree[-100]
572
+ Traceback (most recent call last):
573
+ . . .
574
+ IndexError: index out of range
575
+ >>> del ptree[()]
576
+ Traceback (most recent call last):
577
+ . . .
578
+ IndexError: The tree position () may not be deleted.
579
+
580
+ >>> # With slices:
581
+ >>> ptree = make_ptree('(A (B c) (D e) f g (H i) j (K l))')
582
+ >>> b = ptree[0]
583
+ >>> del ptree[0:0]; pcheck(ptree)
584
+ ok! (A (B c) (D e) f g (H i) j (K l))
585
+ >>> del ptree[:1]; pcheck(ptree); pcheck(b)
586
+ ok! (A (D e) f g (H i) j (K l))
587
+ ok! (B c)
588
+ >>> del ptree[-2:]; pcheck(ptree)
589
+ ok! (A (D e) f g (H i))
590
+ >>> del ptree[1:3]; pcheck(ptree)
591
+ ok! (A (D e) (H i))
592
+ >>> ptree = make_ptree('(A (B c) (D e) f g (H i) j (K l))')
593
+ >>> del ptree[5:1000]; pcheck(ptree)
594
+ ok! (A (B c) (D e) f g (H i))
595
+ >>> del ptree[-2:1000]; pcheck(ptree)
596
+ ok! (A (B c) (D e) f)
597
+ >>> del ptree[-100:1]; pcheck(ptree)
598
+ ok! (A (D e) f)
599
+ >>> ptree = make_ptree('(A (B c) (D e) f g (H i) j (K l))')
600
+ >>> del ptree[1:-2:2]; pcheck(ptree)
601
+ ok! (A (B c) f (H i) j (K l))
602
+
603
+ **__setitem__()**
604
+
605
+ >>> ptree = make_ptree('(A (B (C (D) (E f) (Q p)) g) h)')
606
+ >>> d, e, q = ptree[0,0]
607
+ >>> ptree[0,0,0] = 'x'; pcheck(ptree); pcheck(d)
608
+ ok! (A (B (C x (E f) (Q p)) g) h)
609
+ ok! (D )
610
+ >>> ptree[0,0,1] = make_ptree('(X (Y z))'); pcheck(ptree); pcheck(e)
611
+ ok! (A (B (C x (X (Y z)) (Q p)) g) h)
612
+ ok! (E f)
613
+ >>> ptree[1] = d; pcheck(ptree)
614
+ ok! (A (B (C x (X (Y z)) (Q p)) g) (D ))
615
+ >>> ptree[-1] = 'x'; pcheck(ptree)
616
+ ok! (A (B (C x (X (Y z)) (Q p)) g) x)
617
+ >>> ptree[-100] = 'y'
618
+ Traceback (most recent call last):
619
+ . . .
620
+ IndexError: index out of range
621
+ >>> ptree[()] = make_ptree('(X y)')
622
+ Traceback (most recent call last):
623
+ . . .
624
+ IndexError: The tree position () may not be assigned to.
625
+
626
+ >>> # With slices:
627
+ >>> ptree = make_ptree('(A (B c) (D e) f g (H i) j (K l))')
628
+ >>> b = ptree[0]
629
+ >>> ptree[0:0] = ('x', make_ptree('(Y)')); pcheck(ptree)
630
+ ok! (A x (Y ) (B c) (D e) f g (H i) j (K l))
631
+ >>> ptree[2:6] = (); pcheck(ptree); pcheck(b)
632
+ ok! (A x (Y ) (H i) j (K l))
633
+ ok! (B c)
634
+ >>> ptree[-2:] = ('z', 'p'); pcheck(ptree)
635
+ ok! (A x (Y ) (H i) z p)
636
+ >>> ptree[1:3] = [make_ptree('(X)') for x in range(10)]; pcheck(ptree)
637
+ ok! (A x (X ) (X ) (X ) (X ) (X ) (X ) (X ) (X ) (X ) (X ) z p)
638
+ >>> ptree[5:1000] = []; pcheck(ptree)
639
+ ok! (A x (X ) (X ) (X ) (X ))
640
+ >>> ptree[-2:1000] = ['n']; pcheck(ptree)
641
+ ok! (A x (X ) (X ) n)
642
+ >>> ptree[-100:1] = [make_ptree('(U v)')]; pcheck(ptree)
643
+ ok! (A (U v) (X ) (X ) n)
644
+ >>> ptree[-1:] = (make_ptree('(X)') for x in range(3)); pcheck(ptree)
645
+ ok! (A (U v) (X ) (X ) (X ) (X ) (X ))
646
+ >>> ptree[1:-2:2] = ['x', 'y']; pcheck(ptree)
647
+ ok! (A (U v) x (X ) y (X ) (X ))
648
+
649
+ **append()**
650
+
651
+ >>> ptree = make_ptree('(A (B (C (D) (E f) (Q p)) g) h)')
652
+ >>> ptree.append('x'); pcheck(ptree)
653
+ ok! (A (B (C (D ) (E f) (Q p)) g) h x)
654
+ >>> ptree.append(make_ptree('(X (Y z))')); pcheck(ptree)
655
+ ok! (A (B (C (D ) (E f) (Q p)) g) h x (X (Y z)))
656
+
657
+ **extend()**
658
+
659
+ >>> ptree = make_ptree('(A (B (C (D) (E f) (Q p)) g) h)')
660
+ >>> ptree.extend(['x', 'y', make_ptree('(X (Y z))')]); pcheck(ptree)
661
+ ok! (A (B (C (D ) (E f) (Q p)) g) h x y (X (Y z)))
662
+ >>> ptree.extend([]); pcheck(ptree)
663
+ ok! (A (B (C (D ) (E f) (Q p)) g) h x y (X (Y z)))
664
+ >>> ptree.extend(make_ptree('(X)') for x in range(3)); pcheck(ptree)
665
+ ok! (A (B (C (D ) (E f) (Q p)) g) h x y (X (Y z)) (X ) (X ) (X ))
666
+
667
+ **insert()**
668
+
669
+ >>> ptree = make_ptree('(A (B (C (D) (E f) (Q p)) g) h)')
670
+ >>> ptree.insert(0, make_ptree('(X (Y z))')); pcheck(ptree)
671
+ ok! (A (X (Y z)) (B (C (D ) (E f) (Q p)) g) h)
672
+ >>> ptree.insert(-1, make_ptree('(X (Y z))')); pcheck(ptree)
673
+ ok! (A (X (Y z)) (B (C (D ) (E f) (Q p)) g) (X (Y z)) h)
674
+ >>> ptree.insert(-4, make_ptree('(X (Y z))')); pcheck(ptree)
675
+ ok! (A (X (Y z)) (X (Y z)) (B (C (D ) (E f) (Q p)) g) (X (Y z)) h)
676
+ >>> # Note: as with ``list``, inserting at a negative index that
677
+ >>> # gives a position before the start of the list does *not*
678
+ >>> # raise an IndexError exception; it just inserts at 0.
679
+ >>> ptree.insert(-400, make_ptree('(X (Y z))')); pcheck(ptree)
680
+ ok! (A
681
+ (X (Y z))
682
+ (X (Y z))
683
+ (X (Y z))
684
+ (B (C (D ) (E f) (Q p)) g)
685
+ (X (Y z))
686
+ h)
687
+
688
+ **pop()**
689
+
690
+ >>> ptree = make_ptree('(A (B (C (D) (E f) (Q p)) g) h)')
691
+ >>> ptree[0,0].pop(1); pcheck(ptree)
692
+ ParentedTree('E', ['f'])
693
+ ok! (A (B (C (D ) (Q p)) g) h)
694
+ >>> ptree[0].pop(-1); pcheck(ptree)
695
+ 'g'
696
+ ok! (A (B (C (D ) (Q p))) h)
697
+ >>> ptree.pop(); pcheck(ptree)
698
+ 'h'
699
+ ok! (A (B (C (D ) (Q p))))
700
+ >>> ptree.pop(-100)
701
+ Traceback (most recent call last):
702
+ . . .
703
+ IndexError: index out of range
704
+
705
+ **remove()**
706
+
707
+ >>> ptree = make_ptree('(A (B (C (D) (E f) (Q p)) g) h)')
708
+ >>> e = ptree[0,0,1]
709
+ >>> ptree[0,0].remove(ptree[0,0,1]); pcheck(ptree); pcheck(e)
710
+ ok! (A (B (C (D ) (Q p)) g) h)
711
+ ok! (E f)
712
+ >>> ptree[0,0].remove(make_ptree('(Q p)')); pcheck(ptree)
713
+ ok! (A (B (C (D )) g) h)
714
+ >>> ptree[0,0].remove(make_ptree('(Q p)'))
715
+ Traceback (most recent call last):
716
+ . . .
717
+ ValueError: ParentedTree('Q', ['p']) is not in list
718
+ >>> ptree.remove('h'); pcheck(ptree)
719
+ ok! (A (B (C (D )) g))
720
+ >>> ptree.remove('h');
721
+ Traceback (most recent call last):
722
+ . . .
723
+ ValueError: 'h' is not in list
724
+ >>> # remove() removes the first subtree that is equal (==) to the
725
+ >>> # given tree, which may not be the identical tree we give it:
726
+ >>> ptree = make_ptree('(A (X x) (Y y) (X x))')
727
+ >>> x1, y, x2 = ptree
728
+ >>> ptree.remove(ptree[-1]); pcheck(ptree)
729
+ ok! (A (Y y) (X x))
730
+ >>> print(x1.parent()); pcheck(x1)
731
+ None
732
+ ok! (X x)
733
+ >>> print(x2.parent())
734
+ (A (Y y) (X x))
735
+
736
+ Test that a tree can not be given multiple parents:
737
+
738
+ >>> ptree = make_ptree('(A (X x) (Y y) (Z z))')
739
+ >>> ptree[0] = ptree[1]
740
+ Traceback (most recent call last):
741
+ . . .
742
+ ValueError: Can not insert a subtree that already has a parent.
743
+ >>> pcheck()
744
+ ok!
745
+
746
+ [more to be written]
747
+
748
+
749
+ ImmutableParentedTree Regression Tests
750
+ --------------------------------------
751
+
752
+ >>> iptree = ImmutableParentedTree.convert(ptree)
753
+ >>> type(iptree)
754
+ <class 'nltk.tree.ImmutableParentedTree'>
755
+ >>> del iptree[0]
756
+ Traceback (most recent call last):
757
+ . . .
758
+ ValueError: ImmutableParentedTree may not be modified
759
+ >>> iptree.set_label('newnode')
760
+ Traceback (most recent call last):
761
+ . . .
762
+ ValueError: ImmutableParentedTree may not be modified
763
+
764
+
765
+ MultiParentedTree Regression Tests
766
+ ----------------------------------
767
+ Keep track of all trees that we create (including subtrees) using this
768
+ variable:
769
+
770
+ >>> all_mptrees = []
771
+
772
+ Define a helper funciton to create new parented trees:
773
+
774
+ >>> def make_mptree(s):
775
+ ... mptree = MultiParentedTree.convert(Tree.fromstring(s))
776
+ ... all_mptrees.extend(t for t in mptree.subtrees()
777
+ ... if isinstance(t, Tree))
778
+ ... return mptree
779
+
780
+ Define a test function that examines every subtree in all_mptrees; and
781
+ checks that all six of its methods are defined correctly. If any
782
+ mptrees are passed as arguments, then they are printed.
783
+
784
+ >>> def mpcheck(*print_mptrees):
785
+ ... def has(seq, val): # uses identity comparison
786
+ ... for item in seq:
787
+ ... if item is val: return True
788
+ ... return False
789
+ ... for mptree in all_mptrees:
790
+ ... # Check mptree's methods.
791
+ ... if len(mptree.parents()) == 0:
792
+ ... assert len(mptree.left_siblings()) == 0
793
+ ... assert len(mptree.right_siblings()) == 0
794
+ ... assert len(mptree.roots()) == 1
795
+ ... assert mptree.roots()[0] is mptree
796
+ ... assert mptree.treepositions(mptree) == [()]
797
+ ... left_siblings = right_siblings = ()
798
+ ... roots = {id(mptree): 1}
799
+ ... else:
800
+ ... roots = dict((id(r), 0) for r in mptree.roots())
801
+ ... left_siblings = mptree.left_siblings()
802
+ ... right_siblings = mptree.right_siblings()
803
+ ... for parent in mptree.parents():
804
+ ... for i in mptree.parent_indices(parent):
805
+ ... assert parent[i] is mptree
806
+ ... # check left siblings
807
+ ... if i > 0:
808
+ ... for j in range(len(left_siblings)):
809
+ ... if left_siblings[j] is parent[i-1]:
810
+ ... del left_siblings[j]
811
+ ... break
812
+ ... else:
813
+ ... assert 0, 'sibling not found!'
814
+ ... # check ight siblings
815
+ ... if i < (len(parent)-1):
816
+ ... for j in range(len(right_siblings)):
817
+ ... if right_siblings[j] is parent[i+1]:
818
+ ... del right_siblings[j]
819
+ ... break
820
+ ... else:
821
+ ... assert 0, 'sibling not found!'
822
+ ... # check roots
823
+ ... for root in parent.roots():
824
+ ... assert id(root) in roots, 'missing root'
825
+ ... roots[id(root)] += 1
826
+ ... # check that we don't have any unexplained values
827
+ ... assert len(left_siblings)==0, 'unexpected sibling'
828
+ ... assert len(right_siblings)==0, 'unexpected sibling'
829
+ ... for v in roots.values(): assert v>0, roots #'unexpected root'
830
+ ... # check treepositions
831
+ ... for root in mptree.roots():
832
+ ... for treepos in mptree.treepositions(root):
833
+ ... assert root[treepos] is mptree
834
+ ... # Check mptree's children's methods:
835
+ ... for i, child in enumerate(mptree):
836
+ ... if isinstance(child, Tree):
837
+ ... # mpcheck parent() & parent_index() methods
838
+ ... assert has(child.parents(), mptree)
839
+ ... assert i in child.parent_indices(mptree)
840
+ ... # mpcheck sibling methods
841
+ ... if i > 0:
842
+ ... assert has(child.left_siblings(), mptree[i-1])
843
+ ... if i < len(mptree)-1:
844
+ ... assert has(child.right_siblings(), mptree[i+1])
845
+ ... if print_mptrees:
846
+ ... print('ok!', end=' ')
847
+ ... for mptree in print_mptrees: print(mptree)
848
+ ... else:
849
+ ... print('ok!')
850
+
851
+ Run our test function on a variety of newly-created trees:
852
+
853
+ >>> mpcheck(make_mptree('(A)'))
854
+ ok! (A )
855
+ >>> mpcheck(make_mptree('(A (B (C (D) (E f)) g) h)'))
856
+ ok! (A (B (C (D ) (E f)) g) h)
857
+ >>> mpcheck(make_mptree('(A (B) (C c) (D d d) (E e e e))'))
858
+ ok! (A (B ) (C c) (D d d) (E e e e))
859
+ >>> mpcheck(make_mptree('(A (B) (C (c)) (D (d) (d)) (E (e) (e) (e)))'))
860
+ ok! (A (B ) (C (c )) (D (d ) (d )) (E (e ) (e ) (e )))
861
+ >>> subtree = make_mptree('(A (B (C (D) (E f)) g) h)')
862
+
863
+ Including some trees that contain multiple parents:
864
+
865
+ >>> mpcheck(MultiParentedTree('Z', [subtree, subtree]))
866
+ ok! (Z (A (B (C (D ) (E f)) g) h) (A (B (C (D ) (E f)) g) h))
867
+
868
+ Run our test function after performing various tree-modification
869
+ operations (n.b., these are the same tests that we ran for
870
+ `ParentedTree`, above; thus, none of these trees actually *uses*
871
+ multiple parents.)
872
+
873
+ **__delitem__()**
874
+
875
+ >>> mptree = make_mptree('(A (B (C (D) (E f) (Q p)) g) h)')
876
+ >>> e = mptree[0,0,1]
877
+ >>> del mptree[0,0,1]; mpcheck(mptree); mpcheck(e)
878
+ ok! (A (B (C (D ) (Q p)) g) h)
879
+ ok! (E f)
880
+ >>> del mptree[0,0,0]; mpcheck(mptree)
881
+ ok! (A (B (C (Q p)) g) h)
882
+ >>> del mptree[0,1]; mpcheck(mptree)
883
+ ok! (A (B (C (Q p))) h)
884
+ >>> del mptree[-1]; mpcheck(mptree)
885
+ ok! (A (B (C (Q p))))
886
+ >>> del mptree[-100]
887
+ Traceback (most recent call last):
888
+ . . .
889
+ IndexError: index out of range
890
+ >>> del mptree[()]
891
+ Traceback (most recent call last):
892
+ . . .
893
+ IndexError: The tree position () may not be deleted.
894
+
895
+ >>> # With slices:
896
+ >>> mptree = make_mptree('(A (B c) (D e) f g (H i) j (K l))')
897
+ >>> b = mptree[0]
898
+ >>> del mptree[0:0]; mpcheck(mptree)
899
+ ok! (A (B c) (D e) f g (H i) j (K l))
900
+ >>> del mptree[:1]; mpcheck(mptree); mpcheck(b)
901
+ ok! (A (D e) f g (H i) j (K l))
902
+ ok! (B c)
903
+ >>> del mptree[-2:]; mpcheck(mptree)
904
+ ok! (A (D e) f g (H i))
905
+ >>> del mptree[1:3]; mpcheck(mptree)
906
+ ok! (A (D e) (H i))
907
+ >>> mptree = make_mptree('(A (B c) (D e) f g (H i) j (K l))')
908
+ >>> del mptree[5:1000]; mpcheck(mptree)
909
+ ok! (A (B c) (D e) f g (H i))
910
+ >>> del mptree[-2:1000]; mpcheck(mptree)
911
+ ok! (A (B c) (D e) f)
912
+ >>> del mptree[-100:1]; mpcheck(mptree)
913
+ ok! (A (D e) f)
914
+ >>> mptree = make_mptree('(A (B c) (D e) f g (H i) j (K l))')
915
+ >>> del mptree[1:-2:2]; mpcheck(mptree)
916
+ ok! (A (B c) f (H i) j (K l))
917
+
918
+ **__setitem__()**
919
+
920
+ >>> mptree = make_mptree('(A (B (C (D) (E f) (Q p)) g) h)')
921
+ >>> d, e, q = mptree[0,0]
922
+ >>> mptree[0,0,0] = 'x'; mpcheck(mptree); mpcheck(d)
923
+ ok! (A (B (C x (E f) (Q p)) g) h)
924
+ ok! (D )
925
+ >>> mptree[0,0,1] = make_mptree('(X (Y z))'); mpcheck(mptree); mpcheck(e)
926
+ ok! (A (B (C x (X (Y z)) (Q p)) g) h)
927
+ ok! (E f)
928
+ >>> mptree[1] = d; mpcheck(mptree)
929
+ ok! (A (B (C x (X (Y z)) (Q p)) g) (D ))
930
+ >>> mptree[-1] = 'x'; mpcheck(mptree)
931
+ ok! (A (B (C x (X (Y z)) (Q p)) g) x)
932
+ >>> mptree[-100] = 'y'
933
+ Traceback (most recent call last):
934
+ . . .
935
+ IndexError: index out of range
936
+ >>> mptree[()] = make_mptree('(X y)')
937
+ Traceback (most recent call last):
938
+ . . .
939
+ IndexError: The tree position () may not be assigned to.
940
+
941
+ >>> # With slices:
942
+ >>> mptree = make_mptree('(A (B c) (D e) f g (H i) j (K l))')
943
+ >>> b = mptree[0]
944
+ >>> mptree[0:0] = ('x', make_mptree('(Y)')); mpcheck(mptree)
945
+ ok! (A x (Y ) (B c) (D e) f g (H i) j (K l))
946
+ >>> mptree[2:6] = (); mpcheck(mptree); mpcheck(b)
947
+ ok! (A x (Y ) (H i) j (K l))
948
+ ok! (B c)
949
+ >>> mptree[-2:] = ('z', 'p'); mpcheck(mptree)
950
+ ok! (A x (Y ) (H i) z p)
951
+ >>> mptree[1:3] = [make_mptree('(X)') for x in range(10)]; mpcheck(mptree)
952
+ ok! (A x (X ) (X ) (X ) (X ) (X ) (X ) (X ) (X ) (X ) (X ) z p)
953
+ >>> mptree[5:1000] = []; mpcheck(mptree)
954
+ ok! (A x (X ) (X ) (X ) (X ))
955
+ >>> mptree[-2:1000] = ['n']; mpcheck(mptree)
956
+ ok! (A x (X ) (X ) n)
957
+ >>> mptree[-100:1] = [make_mptree('(U v)')]; mpcheck(mptree)
958
+ ok! (A (U v) (X ) (X ) n)
959
+ >>> mptree[-1:] = (make_mptree('(X)') for x in range(3)); mpcheck(mptree)
960
+ ok! (A (U v) (X ) (X ) (X ) (X ) (X ))
961
+ >>> mptree[1:-2:2] = ['x', 'y']; mpcheck(mptree)
962
+ ok! (A (U v) x (X ) y (X ) (X ))
963
+
964
+ **append()**
965
+
966
+ >>> mptree = make_mptree('(A (B (C (D) (E f) (Q p)) g) h)')
967
+ >>> mptree.append('x'); mpcheck(mptree)
968
+ ok! (A (B (C (D ) (E f) (Q p)) g) h x)
969
+ >>> mptree.append(make_mptree('(X (Y z))')); mpcheck(mptree)
970
+ ok! (A (B (C (D ) (E f) (Q p)) g) h x (X (Y z)))
971
+
972
+ **extend()**
973
+
974
+ >>> mptree = make_mptree('(A (B (C (D) (E f) (Q p)) g) h)')
975
+ >>> mptree.extend(['x', 'y', make_mptree('(X (Y z))')]); mpcheck(mptree)
976
+ ok! (A (B (C (D ) (E f) (Q p)) g) h x y (X (Y z)))
977
+ >>> mptree.extend([]); mpcheck(mptree)
978
+ ok! (A (B (C (D ) (E f) (Q p)) g) h x y (X (Y z)))
979
+ >>> mptree.extend(make_mptree('(X)') for x in range(3)); mpcheck(mptree)
980
+ ok! (A (B (C (D ) (E f) (Q p)) g) h x y (X (Y z)) (X ) (X ) (X ))
981
+
982
+ **insert()**
983
+
984
+ >>> mptree = make_mptree('(A (B (C (D) (E f) (Q p)) g) h)')
985
+ >>> mptree.insert(0, make_mptree('(X (Y z))')); mpcheck(mptree)
986
+ ok! (A (X (Y z)) (B (C (D ) (E f) (Q p)) g) h)
987
+ >>> mptree.insert(-1, make_mptree('(X (Y z))')); mpcheck(mptree)
988
+ ok! (A (X (Y z)) (B (C (D ) (E f) (Q p)) g) (X (Y z)) h)
989
+ >>> mptree.insert(-4, make_mptree('(X (Y z))')); mpcheck(mptree)
990
+ ok! (A (X (Y z)) (X (Y z)) (B (C (D ) (E f) (Q p)) g) (X (Y z)) h)
991
+ >>> # Note: as with ``list``, inserting at a negative index that
992
+ >>> # gives a position before the start of the list does *not*
993
+ >>> # raise an IndexError exception; it just inserts at 0.
994
+ >>> mptree.insert(-400, make_mptree('(X (Y z))')); mpcheck(mptree)
995
+ ok! (A
996
+ (X (Y z))
997
+ (X (Y z))
998
+ (X (Y z))
999
+ (B (C (D ) (E f) (Q p)) g)
1000
+ (X (Y z))
1001
+ h)
1002
+
1003
+ **pop()**
1004
+
1005
+ >>> mptree = make_mptree('(A (B (C (D) (E f) (Q p)) g) h)')
1006
+ >>> mptree[0,0].pop(1); mpcheck(mptree)
1007
+ MultiParentedTree('E', ['f'])
1008
+ ok! (A (B (C (D ) (Q p)) g) h)
1009
+ >>> mptree[0].pop(-1); mpcheck(mptree)
1010
+ 'g'
1011
+ ok! (A (B (C (D ) (Q p))) h)
1012
+ >>> mptree.pop(); mpcheck(mptree)
1013
+ 'h'
1014
+ ok! (A (B (C (D ) (Q p))))
1015
+ >>> mptree.pop(-100)
1016
+ Traceback (most recent call last):
1017
+ . . .
1018
+ IndexError: index out of range
1019
+
1020
+ **remove()**
1021
+
1022
+ >>> mptree = make_mptree('(A (B (C (D) (E f) (Q p)) g) h)')
1023
+ >>> e = mptree[0,0,1]
1024
+ >>> mptree[0,0].remove(mptree[0,0,1]); mpcheck(mptree); mpcheck(e)
1025
+ ok! (A (B (C (D ) (Q p)) g) h)
1026
+ ok! (E f)
1027
+ >>> mptree[0,0].remove(make_mptree('(Q p)')); mpcheck(mptree)
1028
+ ok! (A (B (C (D )) g) h)
1029
+ >>> mptree[0,0].remove(make_mptree('(Q p)'))
1030
+ Traceback (most recent call last):
1031
+ . . .
1032
+ ValueError: MultiParentedTree('Q', ['p']) is not in list
1033
+ >>> mptree.remove('h'); mpcheck(mptree)
1034
+ ok! (A (B (C (D )) g))
1035
+ >>> mptree.remove('h');
1036
+ Traceback (most recent call last):
1037
+ . . .
1038
+ ValueError: 'h' is not in list
1039
+ >>> # remove() removes the first subtree that is equal (==) to the
1040
+ >>> # given tree, which may not be the identical tree we give it:
1041
+ >>> mptree = make_mptree('(A (X x) (Y y) (X x))')
1042
+ >>> x1, y, x2 = mptree
1043
+ >>> mptree.remove(mptree[-1]); mpcheck(mptree)
1044
+ ok! (A (Y y) (X x))
1045
+ >>> print([str(p) for p in x1.parents()])
1046
+ []
1047
+ >>> print([str(p) for p in x2.parents()])
1048
+ ['(A (Y y) (X x))']
1049
+
1050
+
1051
+ ImmutableMultiParentedTree Regression Tests
1052
+ -------------------------------------------
1053
+
1054
+ >>> imptree = ImmutableMultiParentedTree.convert(mptree)
1055
+ >>> type(imptree)
1056
+ <class 'nltk.tree.ImmutableMultiParentedTree'>
1057
+ >>> del imptree[0]
1058
+ Traceback (most recent call last):
1059
+ . . .
1060
+ ValueError: ImmutableMultiParentedTree may not be modified
1061
+ >>> imptree.set_label('newnode')
1062
+ Traceback (most recent call last):
1063
+ . . .
1064
+ ValueError: ImmutableMultiParentedTree may not be modified
1065
+
1066
+
1067
+ ProbabilisticTree Regression Tests
1068
+ ----------------------------------
1069
+
1070
+ >>> prtree = ProbabilisticTree("S", [ProbabilisticTree("NP", ["N"], prob=0.3)], prob=0.6)
1071
+ >>> print(prtree)
1072
+ (S (NP N)) (p=0.6)
1073
+ >>> import copy
1074
+ >>> prtree == copy.deepcopy(prtree) == prtree.copy(deep=True) == prtree.copy()
1075
+ True
1076
+ >>> prtree[0] is prtree.copy()[0]
1077
+ True
1078
+ >>> prtree[0] is prtree.copy(deep=True)[0]
1079
+ False
1080
+
1081
+ >>> imprtree = ImmutableProbabilisticTree.convert(prtree)
1082
+ >>> type(imprtree)
1083
+ <class 'nltk.tree.ImmutableProbabilisticTree'>
1084
+ >>> del imprtree[0]
1085
+ Traceback (most recent call last):
1086
+ . . .
1087
+ ValueError: ImmutableProbabilisticTree may not be modified
1088
+ >>> imprtree.set_label('newnode')
1089
+ Traceback (most recent call last):
1090
+ . . .
1091
+ ValueError: ImmutableProbabilisticTree may not be modified
1092
+
1093
+
1094
+ Squashed Bugs
1095
+ =============
1096
+
1097
+ This used to discard the ``(B b)`` subtree (fixed in svn 6270):
1098
+
1099
+ >>> print(Tree.fromstring('((A a) (B b))'))
1100
+ ( (A a) (B b))
1101
+