grammar_cop 0.1.0

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 (344) hide show
  1. data/.DS_Store +0 -0
  2. data/.gitignore +4 -0
  3. data/Gemfile +4 -0
  4. data/Rakefile +8 -0
  5. data/data/.DS_Store +0 -0
  6. data/data/Makefile +511 -0
  7. data/data/Makefile.am +4 -0
  8. data/data/Makefile.in +511 -0
  9. data/data/de/.DS_Store +0 -0
  10. data/data/de/4.0.affix +7 -0
  11. data/data/de/4.0.dict +474 -0
  12. data/data/de/Makefile +387 -0
  13. data/data/de/Makefile.am +9 -0
  14. data/data/de/Makefile.in +387 -0
  15. data/data/en/.DS_Store +0 -0
  16. data/data/en/4.0.affix +26 -0
  17. data/data/en/4.0.batch +1002 -0
  18. data/data/en/4.0.biolg.batch +411 -0
  19. data/data/en/4.0.constituent-knowledge +127 -0
  20. data/data/en/4.0.dict +8759 -0
  21. data/data/en/4.0.dict.m4 +6928 -0
  22. data/data/en/4.0.enwiki.batch +14 -0
  23. data/data/en/4.0.fixes.batch +2776 -0
  24. data/data/en/4.0.knowledge +306 -0
  25. data/data/en/4.0.regex +225 -0
  26. data/data/en/4.0.voa.batch +114 -0
  27. data/data/en/Makefile +554 -0
  28. data/data/en/Makefile.am +19 -0
  29. data/data/en/Makefile.in +554 -0
  30. data/data/en/README +173 -0
  31. data/data/en/tiny.dict +157 -0
  32. data/data/en/words/.DS_Store +0 -0
  33. data/data/en/words/Makefile +456 -0
  34. data/data/en/words/Makefile.am +78 -0
  35. data/data/en/words/Makefile.in +456 -0
  36. data/data/en/words/currency +205 -0
  37. data/data/en/words/currency.p +28 -0
  38. data/data/en/words/entities.given-bisex.sing +39 -0
  39. data/data/en/words/entities.given-female.sing +4141 -0
  40. data/data/en/words/entities.given-male.sing +1633 -0
  41. data/data/en/words/entities.locations.sing +68 -0
  42. data/data/en/words/entities.national.sing +253 -0
  43. data/data/en/words/entities.organizations.sing +7 -0
  44. data/data/en/words/entities.us-states.sing +11 -0
  45. data/data/en/words/units.1 +45 -0
  46. data/data/en/words/units.1.dot +4 -0
  47. data/data/en/words/units.3 +2 -0
  48. data/data/en/words/units.4 +5 -0
  49. data/data/en/words/units.4.dot +1 -0
  50. data/data/en/words/words-medical.adv.1 +1191 -0
  51. data/data/en/words/words-medical.prep.1 +67 -0
  52. data/data/en/words/words-medical.v.4.1 +2835 -0
  53. data/data/en/words/words-medical.v.4.2 +2848 -0
  54. data/data/en/words/words-medical.v.4.3 +3011 -0
  55. data/data/en/words/words-medical.v.4.4 +3036 -0
  56. data/data/en/words/words-medical.v.4.5 +3050 -0
  57. data/data/en/words/words.adj.1 +6794 -0
  58. data/data/en/words/words.adj.2 +638 -0
  59. data/data/en/words/words.adj.3 +667 -0
  60. data/data/en/words/words.adv.1 +1573 -0
  61. data/data/en/words/words.adv.2 +67 -0
  62. data/data/en/words/words.adv.3 +157 -0
  63. data/data/en/words/words.adv.4 +80 -0
  64. data/data/en/words/words.n.1 +11464 -0
  65. data/data/en/words/words.n.1.wiki +264 -0
  66. data/data/en/words/words.n.2.s +2017 -0
  67. data/data/en/words/words.n.2.s.biolg +1 -0
  68. data/data/en/words/words.n.2.s.wiki +298 -0
  69. data/data/en/words/words.n.2.x +65 -0
  70. data/data/en/words/words.n.2.x.wiki +10 -0
  71. data/data/en/words/words.n.3 +5717 -0
  72. data/data/en/words/words.n.t +23 -0
  73. data/data/en/words/words.v.1.1 +1038 -0
  74. data/data/en/words/words.v.1.2 +1043 -0
  75. data/data/en/words/words.v.1.3 +1052 -0
  76. data/data/en/words/words.v.1.4 +1023 -0
  77. data/data/en/words/words.v.1.p +17 -0
  78. data/data/en/words/words.v.10.1 +14 -0
  79. data/data/en/words/words.v.10.2 +15 -0
  80. data/data/en/words/words.v.10.3 +88 -0
  81. data/data/en/words/words.v.10.4 +17 -0
  82. data/data/en/words/words.v.2.1 +1253 -0
  83. data/data/en/words/words.v.2.2 +1304 -0
  84. data/data/en/words/words.v.2.3 +1280 -0
  85. data/data/en/words/words.v.2.4 +1285 -0
  86. data/data/en/words/words.v.2.5 +1287 -0
  87. data/data/en/words/words.v.4.1 +2472 -0
  88. data/data/en/words/words.v.4.2 +2487 -0
  89. data/data/en/words/words.v.4.3 +2441 -0
  90. data/data/en/words/words.v.4.4 +2478 -0
  91. data/data/en/words/words.v.4.5 +2483 -0
  92. data/data/en/words/words.v.5.1 +98 -0
  93. data/data/en/words/words.v.5.2 +98 -0
  94. data/data/en/words/words.v.5.3 +103 -0
  95. data/data/en/words/words.v.5.4 +102 -0
  96. data/data/en/words/words.v.6.1 +388 -0
  97. data/data/en/words/words.v.6.2 +401 -0
  98. data/data/en/words/words.v.6.3 +397 -0
  99. data/data/en/words/words.v.6.4 +405 -0
  100. data/data/en/words/words.v.6.5 +401 -0
  101. data/data/en/words/words.v.8.1 +117 -0
  102. data/data/en/words/words.v.8.2 +118 -0
  103. data/data/en/words/words.v.8.3 +118 -0
  104. data/data/en/words/words.v.8.4 +119 -0
  105. data/data/en/words/words.v.8.5 +119 -0
  106. data/data/en/words/words.y +104 -0
  107. data/data/lt/.DS_Store +0 -0
  108. data/data/lt/4.0.affix +6 -0
  109. data/data/lt/4.0.constituent-knowledge +24 -0
  110. data/data/lt/4.0.dict +135 -0
  111. data/data/lt/4.0.knowledge +38 -0
  112. data/data/lt/Makefile +389 -0
  113. data/data/lt/Makefile.am +11 -0
  114. data/data/lt/Makefile.in +389 -0
  115. data/ext/.DS_Store +0 -0
  116. data/ext/link_grammar/.DS_Store +0 -0
  117. data/ext/link_grammar/extconf.rb +2 -0
  118. data/ext/link_grammar/link-grammar/.DS_Store +0 -0
  119. data/ext/link_grammar/link-grammar/.deps/analyze-linkage.Plo +198 -0
  120. data/ext/link_grammar/link-grammar/.deps/and.Plo +202 -0
  121. data/ext/link_grammar/link-grammar/.deps/api.Plo +244 -0
  122. data/ext/link_grammar/link-grammar/.deps/build-disjuncts.Plo +212 -0
  123. data/ext/link_grammar/link-grammar/.deps/command-line.Plo +201 -0
  124. data/ext/link_grammar/link-grammar/.deps/constituents.Plo +201 -0
  125. data/ext/link_grammar/link-grammar/.deps/count.Plo +202 -0
  126. data/ext/link_grammar/link-grammar/.deps/disjunct-utils.Plo +126 -0
  127. data/ext/link_grammar/link-grammar/.deps/disjuncts.Plo +123 -0
  128. data/ext/link_grammar/link-grammar/.deps/error.Plo +121 -0
  129. data/ext/link_grammar/link-grammar/.deps/expand.Plo +133 -0
  130. data/ext/link_grammar/link-grammar/.deps/extract-links.Plo +198 -0
  131. data/ext/link_grammar/link-grammar/.deps/fast-match.Plo +200 -0
  132. data/ext/link_grammar/link-grammar/.deps/idiom.Plo +200 -0
  133. data/ext/link_grammar/link-grammar/.deps/jni-client.Plo +217 -0
  134. data/ext/link_grammar/link-grammar/.deps/link-parser.Po +1 -0
  135. data/ext/link_grammar/link-grammar/.deps/massage.Plo +202 -0
  136. data/ext/link_grammar/link-grammar/.deps/post-process.Plo +202 -0
  137. data/ext/link_grammar/link-grammar/.deps/pp_knowledge.Plo +202 -0
  138. data/ext/link_grammar/link-grammar/.deps/pp_lexer.Plo +201 -0
  139. data/ext/link_grammar/link-grammar/.deps/pp_linkset.Plo +200 -0
  140. data/ext/link_grammar/link-grammar/.deps/prefix.Plo +102 -0
  141. data/ext/link_grammar/link-grammar/.deps/preparation.Plo +202 -0
  142. data/ext/link_grammar/link-grammar/.deps/print-util.Plo +200 -0
  143. data/ext/link_grammar/link-grammar/.deps/print.Plo +201 -0
  144. data/ext/link_grammar/link-grammar/.deps/prune.Plo +202 -0
  145. data/ext/link_grammar/link-grammar/.deps/read-dict.Plo +223 -0
  146. data/ext/link_grammar/link-grammar/.deps/read-regex.Plo +123 -0
  147. data/ext/link_grammar/link-grammar/.deps/regex-morph.Plo +131 -0
  148. data/ext/link_grammar/link-grammar/.deps/resources.Plo +203 -0
  149. data/ext/link_grammar/link-grammar/.deps/spellcheck-aspell.Plo +1 -0
  150. data/ext/link_grammar/link-grammar/.deps/spellcheck-hun.Plo +115 -0
  151. data/ext/link_grammar/link-grammar/.deps/string-set.Plo +198 -0
  152. data/ext/link_grammar/link-grammar/.deps/tokenize.Plo +160 -0
  153. data/ext/link_grammar/link-grammar/.deps/utilities.Plo +222 -0
  154. data/ext/link_grammar/link-grammar/.deps/word-file.Plo +201 -0
  155. data/ext/link_grammar/link-grammar/.deps/word-utils.Plo +212 -0
  156. data/ext/link_grammar/link-grammar/.libs/analyze-linkage.o +0 -0
  157. data/ext/link_grammar/link-grammar/.libs/and.o +0 -0
  158. data/ext/link_grammar/link-grammar/.libs/api.o +0 -0
  159. data/ext/link_grammar/link-grammar/.libs/build-disjuncts.o +0 -0
  160. data/ext/link_grammar/link-grammar/.libs/command-line.o +0 -0
  161. data/ext/link_grammar/link-grammar/.libs/constituents.o +0 -0
  162. data/ext/link_grammar/link-grammar/.libs/count.o +0 -0
  163. data/ext/link_grammar/link-grammar/.libs/disjunct-utils.o +0 -0
  164. data/ext/link_grammar/link-grammar/.libs/disjuncts.o +0 -0
  165. data/ext/link_grammar/link-grammar/.libs/error.o +0 -0
  166. data/ext/link_grammar/link-grammar/.libs/expand.o +0 -0
  167. data/ext/link_grammar/link-grammar/.libs/extract-links.o +0 -0
  168. data/ext/link_grammar/link-grammar/.libs/fast-match.o +0 -0
  169. data/ext/link_grammar/link-grammar/.libs/idiom.o +0 -0
  170. data/ext/link_grammar/link-grammar/.libs/jni-client.o +0 -0
  171. data/ext/link_grammar/link-grammar/.libs/liblink-grammar-java-symbols.expsym +31 -0
  172. data/ext/link_grammar/link-grammar/.libs/liblink-grammar-java.4.dylib +0 -0
  173. data/ext/link_grammar/link-grammar/.libs/liblink-grammar-java.4.dylib.dSYM/Contents/Info.plist +20 -0
  174. data/ext/link_grammar/link-grammar/.libs/liblink-grammar-java.4.dylib.dSYM/Contents/Resources/DWARF/liblink-grammar-java.4.dylib +0 -0
  175. data/ext/link_grammar/link-grammar/.libs/liblink-grammar-java.a +0 -0
  176. data/ext/link_grammar/link-grammar/.libs/liblink-grammar-java.dylib +0 -0
  177. data/ext/link_grammar/link-grammar/.libs/liblink-grammar-symbols.expsym +194 -0
  178. data/ext/link_grammar/link-grammar/.libs/liblink-grammar.4.dylib +0 -0
  179. data/ext/link_grammar/link-grammar/.libs/liblink-grammar.4.dylib.dSYM/Contents/Info.plist +20 -0
  180. data/ext/link_grammar/link-grammar/.libs/liblink-grammar.4.dylib.dSYM/Contents/Resources/DWARF/liblink-grammar.4.dylib +0 -0
  181. data/ext/link_grammar/link-grammar/.libs/liblink-grammar.a +0 -0
  182. data/ext/link_grammar/link-grammar/.libs/liblink-grammar.dylib +0 -0
  183. data/ext/link_grammar/link-grammar/.libs/liblink-grammar.la +41 -0
  184. data/ext/link_grammar/link-grammar/.libs/liblink-grammar.lai +41 -0
  185. data/ext/link_grammar/link-grammar/.libs/massage.o +0 -0
  186. data/ext/link_grammar/link-grammar/.libs/post-process.o +0 -0
  187. data/ext/link_grammar/link-grammar/.libs/pp_knowledge.o +0 -0
  188. data/ext/link_grammar/link-grammar/.libs/pp_lexer.o +0 -0
  189. data/ext/link_grammar/link-grammar/.libs/pp_linkset.o +0 -0
  190. data/ext/link_grammar/link-grammar/.libs/prefix.o +0 -0
  191. data/ext/link_grammar/link-grammar/.libs/preparation.o +0 -0
  192. data/ext/link_grammar/link-grammar/.libs/print-util.o +0 -0
  193. data/ext/link_grammar/link-grammar/.libs/print.o +0 -0
  194. data/ext/link_grammar/link-grammar/.libs/prune.o +0 -0
  195. data/ext/link_grammar/link-grammar/.libs/read-dict.o +0 -0
  196. data/ext/link_grammar/link-grammar/.libs/read-regex.o +0 -0
  197. data/ext/link_grammar/link-grammar/.libs/regex-morph.o +0 -0
  198. data/ext/link_grammar/link-grammar/.libs/resources.o +0 -0
  199. data/ext/link_grammar/link-grammar/.libs/spellcheck-aspell.o +0 -0
  200. data/ext/link_grammar/link-grammar/.libs/spellcheck-hun.o +0 -0
  201. data/ext/link_grammar/link-grammar/.libs/string-set.o +0 -0
  202. data/ext/link_grammar/link-grammar/.libs/tokenize.o +0 -0
  203. data/ext/link_grammar/link-grammar/.libs/utilities.o +0 -0
  204. data/ext/link_grammar/link-grammar/.libs/word-file.o +0 -0
  205. data/ext/link_grammar/link-grammar/.libs/word-utils.o +0 -0
  206. data/ext/link_grammar/link-grammar/Makefile +900 -0
  207. data/ext/link_grammar/link-grammar/Makefile.am +202 -0
  208. data/ext/link_grammar/link-grammar/Makefile.in +900 -0
  209. data/ext/link_grammar/link-grammar/analyze-linkage.c +1317 -0
  210. data/ext/link_grammar/link-grammar/analyze-linkage.h +24 -0
  211. data/ext/link_grammar/link-grammar/and.c +1603 -0
  212. data/ext/link_grammar/link-grammar/and.h +27 -0
  213. data/ext/link_grammar/link-grammar/api-structures.h +362 -0
  214. data/ext/link_grammar/link-grammar/api-types.h +72 -0
  215. data/ext/link_grammar/link-grammar/api.c +1887 -0
  216. data/ext/link_grammar/link-grammar/api.h +96 -0
  217. data/ext/link_grammar/link-grammar/autoit/.DS_Store +0 -0
  218. data/ext/link_grammar/link-grammar/autoit/README +10 -0
  219. data/ext/link_grammar/link-grammar/autoit/_LGTest.au3 +22 -0
  220. data/ext/link_grammar/link-grammar/autoit/_LinkGrammar.au3 +545 -0
  221. data/ext/link_grammar/link-grammar/build-disjuncts.c +487 -0
  222. data/ext/link_grammar/link-grammar/build-disjuncts.h +21 -0
  223. data/ext/link_grammar/link-grammar/command-line.c +458 -0
  224. data/ext/link_grammar/link-grammar/command-line.h +15 -0
  225. data/ext/link_grammar/link-grammar/constituents.c +1836 -0
  226. data/ext/link_grammar/link-grammar/constituents.h +26 -0
  227. data/ext/link_grammar/link-grammar/corpus/.DS_Store +0 -0
  228. data/ext/link_grammar/link-grammar/corpus/.deps/cluster.Plo +1 -0
  229. data/ext/link_grammar/link-grammar/corpus/.deps/corpus.Plo +1 -0
  230. data/ext/link_grammar/link-grammar/corpus/Makefile +527 -0
  231. data/ext/link_grammar/link-grammar/corpus/Makefile.am +46 -0
  232. data/ext/link_grammar/link-grammar/corpus/Makefile.in +527 -0
  233. data/ext/link_grammar/link-grammar/corpus/README +17 -0
  234. data/ext/link_grammar/link-grammar/corpus/cluster.c +286 -0
  235. data/ext/link_grammar/link-grammar/corpus/cluster.h +32 -0
  236. data/ext/link_grammar/link-grammar/corpus/corpus.c +483 -0
  237. data/ext/link_grammar/link-grammar/corpus/corpus.h +46 -0
  238. data/ext/link_grammar/link-grammar/count.c +828 -0
  239. data/ext/link_grammar/link-grammar/count.h +25 -0
  240. data/ext/link_grammar/link-grammar/disjunct-utils.c +261 -0
  241. data/ext/link_grammar/link-grammar/disjunct-utils.h +27 -0
  242. data/ext/link_grammar/link-grammar/disjuncts.c +138 -0
  243. data/ext/link_grammar/link-grammar/disjuncts.h +13 -0
  244. data/ext/link_grammar/link-grammar/error.c +92 -0
  245. data/ext/link_grammar/link-grammar/error.h +35 -0
  246. data/ext/link_grammar/link-grammar/expand.c +67 -0
  247. data/ext/link_grammar/link-grammar/expand.h +13 -0
  248. data/ext/link_grammar/link-grammar/externs.h +22 -0
  249. data/ext/link_grammar/link-grammar/extract-links.c +625 -0
  250. data/ext/link_grammar/link-grammar/extract-links.h +16 -0
  251. data/ext/link_grammar/link-grammar/fast-match.c +309 -0
  252. data/ext/link_grammar/link-grammar/fast-match.h +17 -0
  253. data/ext/link_grammar/link-grammar/idiom.c +373 -0
  254. data/ext/link_grammar/link-grammar/idiom.h +15 -0
  255. data/ext/link_grammar/link-grammar/jni-client.c +779 -0
  256. data/ext/link_grammar/link-grammar/jni-client.h +236 -0
  257. data/ext/link_grammar/link-grammar/liblink-grammar-java.la +42 -0
  258. data/ext/link_grammar/link-grammar/liblink-grammar.la +41 -0
  259. data/ext/link_grammar/link-grammar/link-features.h +37 -0
  260. data/ext/link_grammar/link-grammar/link-features.h.in +37 -0
  261. data/ext/link_grammar/link-grammar/link-grammar-java.def +31 -0
  262. data/ext/link_grammar/link-grammar/link-grammar.def +194 -0
  263. data/ext/link_grammar/link-grammar/link-includes.h +465 -0
  264. data/ext/link_grammar/link-grammar/link-parser.c +849 -0
  265. data/ext/link_grammar/link-grammar/massage.c +329 -0
  266. data/ext/link_grammar/link-grammar/massage.h +13 -0
  267. data/ext/link_grammar/link-grammar/post-process.c +1113 -0
  268. data/ext/link_grammar/link-grammar/post-process.h +45 -0
  269. data/ext/link_grammar/link-grammar/pp_knowledge.c +376 -0
  270. data/ext/link_grammar/link-grammar/pp_knowledge.h +14 -0
  271. data/ext/link_grammar/link-grammar/pp_lexer.c +1920 -0
  272. data/ext/link_grammar/link-grammar/pp_lexer.h +19 -0
  273. data/ext/link_grammar/link-grammar/pp_linkset.c +158 -0
  274. data/ext/link_grammar/link-grammar/pp_linkset.h +20 -0
  275. data/ext/link_grammar/link-grammar/prefix.c +482 -0
  276. data/ext/link_grammar/link-grammar/prefix.h +139 -0
  277. data/ext/link_grammar/link-grammar/preparation.c +412 -0
  278. data/ext/link_grammar/link-grammar/preparation.h +20 -0
  279. data/ext/link_grammar/link-grammar/print-util.c +87 -0
  280. data/ext/link_grammar/link-grammar/print-util.h +32 -0
  281. data/ext/link_grammar/link-grammar/print.c +1085 -0
  282. data/ext/link_grammar/link-grammar/print.h +16 -0
  283. data/ext/link_grammar/link-grammar/prune.c +1864 -0
  284. data/ext/link_grammar/link-grammar/prune.h +17 -0
  285. data/ext/link_grammar/link-grammar/read-dict.c +1785 -0
  286. data/ext/link_grammar/link-grammar/read-dict.h +29 -0
  287. data/ext/link_grammar/link-grammar/read-regex.c +161 -0
  288. data/ext/link_grammar/link-grammar/read-regex.h +12 -0
  289. data/ext/link_grammar/link-grammar/regex-morph.c +126 -0
  290. data/ext/link_grammar/link-grammar/regex-morph.h +17 -0
  291. data/ext/link_grammar/link-grammar/resources.c +180 -0
  292. data/ext/link_grammar/link-grammar/resources.h +23 -0
  293. data/ext/link_grammar/link-grammar/sat-solver/.DS_Store +0 -0
  294. data/ext/link_grammar/link-grammar/sat-solver/.deps/fast-sprintf.Plo +1 -0
  295. data/ext/link_grammar/link-grammar/sat-solver/.deps/sat-encoder.Plo +1 -0
  296. data/ext/link_grammar/link-grammar/sat-solver/.deps/util.Plo +1 -0
  297. data/ext/link_grammar/link-grammar/sat-solver/.deps/variables.Plo +1 -0
  298. data/ext/link_grammar/link-grammar/sat-solver/.deps/word-tag.Plo +1 -0
  299. data/ext/link_grammar/link-grammar/sat-solver/Makefile +527 -0
  300. data/ext/link_grammar/link-grammar/sat-solver/Makefile.am +29 -0
  301. data/ext/link_grammar/link-grammar/sat-solver/Makefile.in +527 -0
  302. data/ext/link_grammar/link-grammar/sat-solver/clock.hpp +33 -0
  303. data/ext/link_grammar/link-grammar/sat-solver/fast-sprintf.cpp +26 -0
  304. data/ext/link_grammar/link-grammar/sat-solver/fast-sprintf.hpp +7 -0
  305. data/ext/link_grammar/link-grammar/sat-solver/guiding.hpp +244 -0
  306. data/ext/link_grammar/link-grammar/sat-solver/matrix-ut.hpp +79 -0
  307. data/ext/link_grammar/link-grammar/sat-solver/sat-encoder.cpp +2811 -0
  308. data/ext/link_grammar/link-grammar/sat-solver/sat-encoder.h +11 -0
  309. data/ext/link_grammar/link-grammar/sat-solver/sat-encoder.hpp +381 -0
  310. data/ext/link_grammar/link-grammar/sat-solver/trie.hpp +118 -0
  311. data/ext/link_grammar/link-grammar/sat-solver/util.cpp +23 -0
  312. data/ext/link_grammar/link-grammar/sat-solver/util.hpp +14 -0
  313. data/ext/link_grammar/link-grammar/sat-solver/variables.cpp +5 -0
  314. data/ext/link_grammar/link-grammar/sat-solver/variables.hpp +829 -0
  315. data/ext/link_grammar/link-grammar/sat-solver/word-tag.cpp +159 -0
  316. data/ext/link_grammar/link-grammar/sat-solver/word-tag.hpp +162 -0
  317. data/ext/link_grammar/link-grammar/spellcheck-aspell.c +148 -0
  318. data/ext/link_grammar/link-grammar/spellcheck-hun.c +136 -0
  319. data/ext/link_grammar/link-grammar/spellcheck.h +34 -0
  320. data/ext/link_grammar/link-grammar/string-set.c +169 -0
  321. data/ext/link_grammar/link-grammar/string-set.h +16 -0
  322. data/ext/link_grammar/link-grammar/structures.h +498 -0
  323. data/ext/link_grammar/link-grammar/tokenize.c +1049 -0
  324. data/ext/link_grammar/link-grammar/tokenize.h +15 -0
  325. data/ext/link_grammar/link-grammar/utilities.c +847 -0
  326. data/ext/link_grammar/link-grammar/utilities.h +281 -0
  327. data/ext/link_grammar/link-grammar/word-file.c +124 -0
  328. data/ext/link_grammar/link-grammar/word-file.h +15 -0
  329. data/ext/link_grammar/link-grammar/word-utils.c +526 -0
  330. data/ext/link_grammar/link-grammar/word-utils.h +152 -0
  331. data/ext/link_grammar/link_grammar.c +202 -0
  332. data/ext/link_grammar/link_grammar.h +99 -0
  333. data/grammar_cop.gemspec +24 -0
  334. data/lib/.DS_Store +0 -0
  335. data/lib/grammar_cop.rb +9 -0
  336. data/lib/grammar_cop/.DS_Store +0 -0
  337. data/lib/grammar_cop/dictionary.rb +19 -0
  338. data/lib/grammar_cop/linkage.rb +30 -0
  339. data/lib/grammar_cop/parse_options.rb +32 -0
  340. data/lib/grammar_cop/sentence.rb +36 -0
  341. data/lib/grammar_cop/version.rb +3 -0
  342. data/test/.DS_Store +0 -0
  343. data/test/grammar_cop_test.rb +27 -0
  344. metadata +407 -0
@@ -0,0 +1,33 @@
1
+ #ifndef __CLOCK_H__
2
+ #define __CLOCK_H__
3
+
4
+ /**
5
+ * Time measurment functions
6
+ */
7
+
8
+ #include <iostream>
9
+ #include <ctime>
10
+
11
+ class Clock {
12
+ private:
13
+ clock_t start;
14
+ public:
15
+ Clock() {
16
+ reset();
17
+ }
18
+
19
+ void reset()
20
+ {
21
+ start = clock();
22
+ }
23
+
24
+ public:
25
+ double elapsed()
26
+ {
27
+ clock_t stop = clock();
28
+ return ((double)stop-(double)start)/CLOCKS_PER_SEC;
29
+
30
+ }
31
+ };
32
+
33
+ #endif
@@ -0,0 +1,26 @@
1
+ #include "fast-sprintf.hpp"
2
+
3
+ char* fast_sprintf(char* buffer, int num) {
4
+ char* begin = buffer;
5
+ do {
6
+ *buffer++ = '0' + num % 10;
7
+ num /= 10;
8
+ } while (num > 0);
9
+ char* end = buffer - 1;
10
+
11
+ for (; begin < end; begin++, end--) {
12
+ char tmp = *begin;
13
+ *begin = *end;
14
+ *end = tmp;
15
+ }
16
+
17
+ *buffer = '\0';
18
+
19
+ return buffer;
20
+ }
21
+
22
+ char* fast_sprintf(char* buffer, const char* str) {
23
+ while(*buffer++ = *str++)
24
+ ;
25
+ return buffer - 1;
26
+ }
@@ -0,0 +1,7 @@
1
+ #ifndef __FAST_SPRINTF_HPP__
2
+ #define __FAST_SPRINTF_HPP__
3
+
4
+ char* fast_sprintf(char* buffer, int num);
5
+ char* fast_sprintf(char* buffer, const char* str);
6
+
7
+ #endif
@@ -0,0 +1,244 @@
1
+ #ifndef __GUIDING_HPP__
2
+ #define __GUIDING_HPP__
3
+
4
+ #include "Solver.h"
5
+ #include "util.hpp"
6
+
7
+ // This class represents different guding strategies of LinkParser SAT search
8
+ class Guiding {
9
+ public:
10
+ struct SATParameters {
11
+ /* Should the variable with the given number be used as a decision
12
+ variable during the SAT search? */
13
+ bool isDecision;
14
+ /* What is the decision priority of the variable with the given number
15
+ during the SAT search? */
16
+ double priority;
17
+ /* What is the preffered polarity of the variable with the given number
18
+ during the SAT search? */
19
+ double polarity;
20
+ };
21
+
22
+ Guiding(Sentence sent)
23
+ : _sent(sent) {
24
+ }
25
+
26
+ /* Abstract functions that calculate params for each type of variable */
27
+
28
+ /* string variables */
29
+ virtual void setStringParameters (int var, const char* str) {
30
+ bool isDecision = false;
31
+ setParameters(var, isDecision, 0.0, 0.0);
32
+ }
33
+ virtual void setStringParameters (int var, const char* str, int cost) = 0;
34
+
35
+ /* epsilon variables */
36
+ virtual void setEpsilonParameters (int var) {
37
+ bool isDecision = false;
38
+ setParameters(var, isDecision, 0.0, 0.0);
39
+ }
40
+
41
+ /* link_cc variables */
42
+ virtual void setLinkParameters (int var, int wi, const char* ci, int wj, const char* cj, const char* label) = 0;
43
+ virtual void setLinkParameters (int var, int wi, const char* ci, int wj, const char* cj, const char* label,
44
+ int cost) = 0;
45
+
46
+ /* linked_variables */
47
+ virtual void setLinkedParameters (int var, int wi, int wj) {
48
+ bool isDecision = false;
49
+ setParameters(var, isDecision, 0.0, 0.0);
50
+ }
51
+
52
+ virtual void setLinkedMinMaxParameters (int var, int wi, int wj) {
53
+ bool isDecision = false;
54
+ setParameters(var, isDecision, 0.0, 0.0);
55
+ }
56
+
57
+ /* link_cw_variables */
58
+ virtual void setLinkCWParameters (int var, int wi, int wj, const char* cj) {
59
+ bool isDecision = false;
60
+ setParameters(var, isDecision, 0.0, 0.0);
61
+ }
62
+
63
+ /* link_top_cw variables */
64
+ virtual void setLinkTopCWParameters (int var, int wi, int wj, const char* cj) {
65
+ bool isDecision = false;
66
+ setParameters(var, isDecision, 0.0, 0.0);
67
+ }
68
+
69
+ /* link_top_ww variables */
70
+ virtual void setLinkTopWWParameters (int var, int wi, int wj) {
71
+ bool isDecision = false;
72
+ setParameters(var, isDecision, 0.0, 0.0);
73
+ }
74
+
75
+ /* fat_link variables */
76
+ virtual void setFatLinkParameters (int var, int wi, int wj) = 0;
77
+ /* thin_link variables */
78
+ virtual void setThinLinkParameters (int var, int wi, int wj) = 0;
79
+ /* neighbor fat link variables */
80
+ virtual void setNeighborFatLinkParameters (int var, int w) = 0;
81
+
82
+ /* Pass SAT search parameters to the MiniSAT solver */
83
+ void passParametersToSolver(Solver* solver) {
84
+ for (int v = 0; v < _parameters.size(); v++) {
85
+ solver->setDecisionVar(v, _parameters[v].isDecision);
86
+ if (_parameters[v].isDecision) {
87
+ solver->setActivity(v, _parameters[v].priority);
88
+ /* TODO: make polarity double instead of boolean*/
89
+ solver->setPolarity(v, _parameters[v].polarity > 0.0);
90
+ }
91
+ }
92
+ }
93
+
94
+ protected:
95
+ /* Set the parameters for the given variable to given values */
96
+ void setParameters(int var, bool isDecision, double priority, double polarity) {
97
+ if (var >= _parameters.size())
98
+ _parameters.resize(var + 1);
99
+ _parameters[var].isDecision = isDecision;
100
+ _parameters[var].priority = priority;
101
+ _parameters[var].polarity = polarity;
102
+
103
+ // printf("Set: %d %s .%g. .%g.\n", var, isDecision ? "true" : "false", priority, polarity);
104
+ }
105
+
106
+
107
+ /* Sentence that is being parsed */
108
+ Sentence _sent;
109
+
110
+ /* Parameters for each variable */
111
+ std::vector<SATParameters> _parameters;
112
+ };
113
+
114
+ ////////////////////////////////////////////////////////////////////////////
115
+ class CostDistanceGuiding : public Guiding {
116
+ public:
117
+ double cost2priority(int cost) {
118
+ return cost == 0 ? 0.0 : (double)(_sent->length + cost);
119
+ }
120
+
121
+ CostDistanceGuiding(Sentence sent)
122
+ : Guiding(sent) {
123
+ }
124
+
125
+ virtual void setStringParameters (int var, const char* str, int cost) {
126
+ bool isDecision = cost > 0.0;
127
+ double priority = cost2priority(cost);
128
+ double polarity = 0.0;
129
+ setParameters(var, isDecision, priority, polarity);
130
+ }
131
+
132
+ virtual void setLinkParameters (int var, int wi, const char* ci, int wj, const char* cj, const char* label) {
133
+ bool isDecision = true;
134
+ double priority = 0.0;
135
+ double polarity = 0.0;
136
+ setParameters(var, isDecision, priority, polarity);
137
+ }
138
+
139
+ virtual void setLinkParameters(int var, int i, const char* ci, int j, const char* cj, const char* label,
140
+ int cost) {
141
+ bool isDecision = true;
142
+ double priority = cost2priority(cost);
143
+ double polarity = 0.0;
144
+ setParameters(var, isDecision, priority, polarity);
145
+ }
146
+
147
+ void setFatLinkParameters(int var, int i, int j) {
148
+ bool isDecision = true;
149
+ double priority = (double)abs(j - i);
150
+
151
+ if (_sent->is_conjunction[i])
152
+ priority = 0.0;
153
+
154
+ double polarity = abs(j - i) == 1 ? 1.0 : 0.0;
155
+ setParameters(var, isDecision, priority, polarity);
156
+ }
157
+
158
+ void setThinLinkParameters(int var, int i, int j) {
159
+ bool isDecision = true;
160
+
161
+ double priority = (double)(j - i);
162
+ if (_sent->is_conjunction[i] || _sent->is_conjunction[j])
163
+ priority = priority / 2;
164
+
165
+ double polarity = j - i == 1 ? 1.0 : 0.0;
166
+ if (i == 0 && j == _sent->length - 2 && isEndingInterpunction(_sent->word[j].string)) {
167
+ polarity = 1.0;
168
+ }
169
+ if (i == 0 && j == _sent->length - 1 && !isEndingInterpunction(_sent->word[j - 1].string)) {
170
+ polarity = 1.0;
171
+ }
172
+
173
+ setParameters(var, isDecision, priority, polarity);
174
+ }
175
+
176
+ void setNeighborFatLinkParameters(int var, int w) {
177
+ bool isDecision = true;
178
+ double priority = _sent->length;
179
+ double polarity = 1.0;
180
+ setParameters(var, isDecision, priority, polarity);
181
+ }
182
+
183
+ };
184
+
185
+
186
+
187
+ ////////////////////////////////////////////////////////////////////////////
188
+ class CostDistanceGuidingOnlyLink : public Guiding {
189
+ public:
190
+ double cost2priority(int cost) {
191
+ return cost == 0 ? 0.0 : (double)(_sent->length + cost);
192
+ }
193
+
194
+ CostDistanceGuidingOnlyLink(Sentence sent)
195
+ : Guiding(sent) {
196
+ }
197
+
198
+ virtual void setStringParameters (int var, const char* str, int cost) {
199
+ bool isDecision = cost > 0.0;
200
+ double priority = cost2priority(cost);
201
+ double polarity = 0.0;
202
+ setParameters(var, isDecision, priority, polarity);
203
+ }
204
+
205
+ virtual void setLinkParameters (int var, int wi, const char* ci, int wj, const char* cj, const char* label) {
206
+ bool isDecision = true;
207
+ double priority = _sent->length - (wj - wi);
208
+ double polarity = wj - wi <= 3 ? 1.0 : 0.0;;
209
+ setParameters(var, isDecision, priority, polarity);
210
+ }
211
+
212
+ virtual void setLinkParameters(int var, int wi, const char* ci, int wj, const char* cj, const char* label,
213
+ int cost) {
214
+ bool isDecision = true;
215
+ double priority = cost > 0 ? cost2priority(cost) : wj - wi;
216
+ double polarity = wj - wi <= 3 ? 1.0 : 0.0;
217
+ setParameters(var, isDecision, priority, polarity);
218
+ }
219
+
220
+ void setFatLinkParameters(int var, int i, int j) {
221
+ bool isDecision = true;
222
+ double priority = (double)abs(j - i);
223
+
224
+ if (_sent->is_conjunction[i])
225
+ priority = 0.0;
226
+
227
+ double polarity = abs(j - i) == 1 ? 1.0 : 0.0;
228
+ setParameters(var, isDecision, priority, polarity);
229
+ }
230
+
231
+ void setThinLinkParameters(int var, int i, int j) {
232
+ bool isDecision = false;
233
+ setParameters(var, isDecision, 0.0, 0.0);
234
+ }
235
+
236
+ void setNeighborFatLinkParameters(int var, int w) {
237
+ bool isDecision = true;
238
+ double priority = _sent->length;
239
+ double polarity = 1.0;
240
+ setParameters(var, isDecision, priority, polarity);
241
+ }
242
+
243
+ };
244
+ #endif
@@ -0,0 +1,79 @@
1
+ #ifndef __MATRIX_UPPER_TRIANGLE_HPP__
2
+ #define __MATRIX_UPPER_TRIANGLE_HPP__
3
+
4
+ #include <vector>
5
+
6
+ #ifndef assert
7
+ #define assert(ex,string) { \
8
+ if (!(ex)) { \
9
+ printf("Assertion failed: %s\n", string); \
10
+ exit(1); \
11
+ } \
12
+ }
13
+ #endif
14
+
15
+ template<class T>
16
+ class Matrix {
17
+ public:
18
+ Matrix(int n = 1, T init = T()) {
19
+ resize(n, init);
20
+ }
21
+
22
+ virtual void resize(int n, T init = T()) {
23
+ _n = n;
24
+ _data.resize(size(_n), init);
25
+ }
26
+
27
+ virtual const T& operator() (int i, int j) const {
28
+ return _data[pos(i, j, _n)];
29
+ }
30
+
31
+ virtual T& operator() (int i, int j) {
32
+ return _data[pos(i, j, _n)];
33
+ }
34
+
35
+ void set(int i, int j, T t) {
36
+ (*this)(i, j) = t;
37
+ }
38
+
39
+ protected:
40
+ virtual int pos (int i, int j, int n) const {
41
+ return n*i + j;
42
+ }
43
+
44
+ virtual int size(int n) const {
45
+ return n*n;
46
+ }
47
+
48
+ std::vector<T> _data;
49
+ int _n;
50
+ };
51
+
52
+ template <class T>
53
+ class MatrixUpperTriangle : public Matrix<T> {
54
+ public:
55
+ MatrixUpperTriangle(int n = 1, T init = T())
56
+ : Matrix<T>(n, init) {
57
+ }
58
+
59
+ const T& operator() (int i, int j) const {
60
+ assert(i < j, "MatrixUpperTriangle: i >= j");
61
+ return Matrix<T>::_data[pos(i, j, Matrix<T>::_n)];
62
+ }
63
+
64
+ T& operator() (int i, int j) {
65
+ assert(i < j, "MatrixUpperTriangle: i >= j");
66
+ return Matrix<T>::_data[pos(i, j, Matrix<T>::_n)];
67
+ }
68
+
69
+ protected:
70
+ virtual int size(int n) const {
71
+ return n*(n-1)/2;
72
+ }
73
+
74
+ virtual int pos (int i, int j, int n) const {
75
+ return i*(n-2) - i*(i-1)/2 + j - 1;
76
+ }
77
+ };
78
+
79
+ #endif
@@ -0,0 +1,2811 @@
1
+ #include <cstdlib>
2
+ #include <cstdio>
3
+ #include <cstring>
4
+ #include <iostream>
5
+ #include <vector>
6
+ #include <map>
7
+ #include <algorithm>
8
+ #include <iterator>
9
+ using std::cout;
10
+ using std::cerr;
11
+ using std::endl;
12
+
13
+ #include "sat-encoder.hpp"
14
+ #include "variables.hpp"
15
+ #include "word-tag.hpp"
16
+ #include "matrix-ut.hpp"
17
+ #include "clock.hpp"
18
+ #include "fast-sprintf.hpp"
19
+ #include "minisat/Solver.h"
20
+
21
+
22
+ extern "C" {
23
+ #include <link-grammar/api.h>
24
+ #include "preparation.h"
25
+ }
26
+
27
+ // Macro DEBUG_print is used to dump to stdout information while debugging
28
+ #ifdef _DEBUG
29
+ #define DEBUG_print(x) (cout << x << endl)
30
+ #else
31
+ #define DEBUG_print(x) (0)
32
+ #endif
33
+
34
+ /*-------------------------------------------------------------------------*
35
+ * C N F C O N V E R S I O N *
36
+ *-------------------------------------------------------------------------*/
37
+ void SATEncoder::generate_literal(Lit l) {
38
+ vec<Lit> clause(1);
39
+ clause[0] = l;
40
+ add_clause(clause);
41
+ }
42
+
43
+ void SATEncoder::generate_and_definition(Lit lhs, vec<Lit>& rhs) {
44
+ vec<Lit> clause;
45
+ for (int i = 0; i < rhs.size(); i++) {
46
+ clause.growTo(2);
47
+ clause[0] = ~lhs;
48
+ clause[1] = rhs[i];
49
+ add_clause(clause);
50
+ }
51
+
52
+ for (int i = 0; i < rhs.size(); i++) {
53
+ clause.growTo(2);
54
+ clause[0] = ~rhs[i];
55
+ clause[1] = lhs;
56
+ add_clause(clause);
57
+ }
58
+ }
59
+ void SATEncoder::generate_classical_and_definition(Lit lhs, vec<Lit>& rhs) {
60
+ {
61
+ vec<Lit> clause;
62
+ for (int i = 0; i < rhs.size(); i++) {
63
+ clause.growTo(2);
64
+
65
+ clause[0] = ~lhs;
66
+ clause[1] = rhs[i];
67
+ add_clause(clause);
68
+ }
69
+ }
70
+
71
+ {
72
+ vec<Lit> clause(rhs.size() + 1);
73
+ for (int i = 0; i < rhs.size(); i++) {
74
+ clause[i] = ~rhs[i];
75
+ }
76
+ clause[rhs.size()] = lhs;
77
+ add_clause(clause);
78
+ }
79
+ }
80
+
81
+ void SATEncoder::generate_or_definition(Lit lhs, vec<Lit>& rhs) {
82
+ {
83
+ vec<Lit> clause;
84
+ for (int i = 0; i < rhs.size(); i++) {
85
+ clause.growTo(2);
86
+ clause[0] = lhs;
87
+ clause[1] = ~rhs[i];
88
+ add_clause(clause);
89
+ }
90
+ }
91
+
92
+ {
93
+ vec<Lit> clause(rhs.size() + 1);
94
+ for (int i = 0; i < rhs.size(); i++) {
95
+ clause[i] = rhs[i];
96
+ }
97
+ clause[rhs.size()] = ~lhs;
98
+ add_clause(clause);
99
+ }
100
+ }
101
+
102
+ void SATEncoder::generate_conditional_or_definition(Lit condition, Lit lhs, vec<Lit>& rhs) {
103
+ {
104
+ vec<Lit> clause;
105
+ for (int i = 0; i < rhs.size(); i++) {
106
+ clause.growTo(3);
107
+ clause[0] = ~condition;
108
+ clause[1] = lhs;
109
+ clause[2] = ~rhs[i];
110
+ add_clause(clause);
111
+ }
112
+ }
113
+
114
+ {
115
+ vec<Lit> clause(rhs.size() + 2);
116
+ for (int i = 0; i < rhs.size(); i++) {
117
+ clause[i] = rhs[i];
118
+ }
119
+ clause[rhs.size()] = ~lhs;
120
+ clause[rhs.size()+1] = ~condition;
121
+ add_clause(clause);
122
+ }
123
+ }
124
+
125
+ void SATEncoder::generate_conditional_lr_implication_or_definition(Lit condition, Lit lhs, vec<Lit>& rhs) {
126
+ {
127
+ vec<Lit> clause;
128
+ for (int i = 0; i < rhs.size(); i++) {
129
+ clause.growTo(2);
130
+ clause[0] = lhs;
131
+ clause[1] = ~rhs[i];
132
+ add_clause(clause);
133
+ }
134
+ }
135
+
136
+ {
137
+ vec<Lit> clause(rhs.size() + 2);
138
+ for (int i = 0; i < rhs.size(); i++) {
139
+ clause[i] = rhs[i];
140
+ }
141
+ clause[rhs.size()] = ~lhs;
142
+ clause[rhs.size()+1] = ~condition;
143
+ add_clause(clause);
144
+ }
145
+ }
146
+
147
+ void SATEncoder::generate_conditional_lr_implication_or_definition(Lit condition1, Lit condition2, Lit lhs, vec<Lit>& rhs) {
148
+ {
149
+ vec<Lit> clause;
150
+ for (int i = 0; i < rhs.size(); i++) {
151
+ clause.growTo(2);
152
+ clause[0] = lhs;
153
+ clause[1] = ~rhs[i];
154
+ add_clause(clause);
155
+ }
156
+ }
157
+
158
+ {
159
+ vec<Lit> clause(rhs.size() + 3);
160
+ for (int i = 0; i < rhs.size(); i++) {
161
+ clause[i] = rhs[i];
162
+ }
163
+ clause[rhs.size()] = ~lhs;
164
+ clause[rhs.size()+1] = ~condition1;
165
+ clause[rhs.size()+2] = ~condition2;
166
+ add_clause(clause);
167
+ }
168
+ }
169
+
170
+ void SATEncoder::generate_xor_conditions(vec<Lit>& vect) {
171
+ vec<Lit> clause;
172
+ for (int i = 0; i < vect.size(); i++) {
173
+ for (int j = i + 1; j < vect.size(); j++) {
174
+ if (vect[i] == vect[j])
175
+ continue;
176
+ clause.growTo(2);
177
+ clause[0] = ~vect[i];
178
+ clause[1] = ~vect[j];
179
+ add_clause(clause);
180
+ }
181
+ }
182
+ }
183
+
184
+ void SATEncoder::generate_and(vec<Lit>& vect) {
185
+ for (int i = 0; i < vect.size(); i++) {
186
+ generate_literal(vect[i]);
187
+ }
188
+ }
189
+
190
+
191
+ void SATEncoder::generate_or(vec<Lit>& vect) {
192
+ add_clause(vect);
193
+ }
194
+
195
+ void SATEncoder::generate_equivalence_definition(Lit l1, Lit l2) {
196
+ {
197
+ vec<Lit> clause(2);
198
+ clause[0] = ~l1;
199
+ clause[1] = l2;
200
+ add_clause(clause);
201
+ }
202
+ {
203
+ vec<Lit> clause(2);
204
+ clause[0] = l1;
205
+ clause[1] = ~l2;
206
+ add_clause(clause);
207
+ }
208
+ }
209
+
210
+
211
+ /*-------------------------------------------------------------------------*
212
+ * E N C O D I N G *
213
+ *-------------------------------------------------------------------------*/
214
+ void SATEncoder::encode() {
215
+ Clock clock;
216
+ generate_satisfaction_conditions();
217
+ DEBUG_print(clock.elapsed());
218
+ generate_linked_definitions();
219
+ DEBUG_print(clock.elapsed());
220
+ generate_planarity_conditions();
221
+ DEBUG_print(clock.elapsed());
222
+
223
+ #ifdef _CONNECTIVITY_
224
+ generate_connectivity();
225
+ DEBUG_print(clock.elapsed());
226
+ #endif
227
+
228
+ generate_encoding_specific_clauses();
229
+ DEBUG_print(clock.elapsed());
230
+
231
+ pp_prune();
232
+ power_prune();
233
+ DEBUG_print(clock.elapsed());
234
+
235
+ _variables->setVariableParameters(_solver);
236
+ }
237
+
238
+
239
+
240
+ /*-------------------------------------------------------------------------*
241
+ * W O R D - T A G S *
242
+ *-------------------------------------------------------------------------*/
243
+ void SATEncoder::build_word_tags() {
244
+ for (int w = 0; w < _sent->length; w++) {
245
+ _word_tags.push_back(WordTag(w, _variables, _sent, _opts));
246
+ int dfs_position = 0;
247
+
248
+ if (_sent->word[w].x == NULL) {
249
+ DEBUG_print("Word ." << w << ".: " << _sent->word[w].string << " (null)" << endl);
250
+ continue;
251
+ }
252
+
253
+ bool join = _sent->word[w].x->next != NULL;
254
+ Exp* exp = join ? join_alternatives(w) : _sent->word[w].x->exp;
255
+
256
+ #ifdef _DEBUG
257
+ cout << "Word ." << w << ".: " << _sent->word[w].string << endl;
258
+ print_expression(exp);
259
+ cout << endl;
260
+ #endif
261
+
262
+ char name[MAX_VARIABLE_NAME];
263
+ sprintf(name, "w%d", w);
264
+ bool leading_right = true;
265
+ bool leading_left = true;
266
+ std::vector<int> eps_right, eps_left;
267
+
268
+ _word_tags[w].insert_connectors(exp, dfs_position, leading_right, leading_left, eps_right, eps_left, name, true, 0);
269
+
270
+ if (join)
271
+ free_alternatives(exp);
272
+ }
273
+
274
+ for (int wl = 0; wl < _sent->length - 1; wl++) {
275
+ for (int wr = wl + 1; wr < _sent->length; wr++) {
276
+ _word_tags[wl].add_matches_with_word(_word_tags[wr]);
277
+ }
278
+ }
279
+ }
280
+
281
+ void SATEncoder::find_all_matches_between_words(int w1, int w2,
282
+ std::vector<std::pair<const PositionConnector*, const PositionConnector*> >& matches) {
283
+ const std::vector<PositionConnector>& w1_right = _word_tags[w1].get_right_connectors();
284
+ std::vector<PositionConnector>::const_iterator i;
285
+ for (i = w1_right.begin(); i != w1_right.end(); i++) {
286
+ const std::vector<PositionConnector*>& w2_left_c = (*i).matches;
287
+ std::vector<PositionConnector*>::const_iterator j;
288
+ for (j = w2_left_c.begin(); j != w2_left_c.end(); j++) {
289
+ if ((*j)->word == w2) {
290
+ matches.push_back(std::pair<const PositionConnector*, const PositionConnector*>(&(*i), *j));
291
+ }
292
+ }
293
+ }
294
+ }
295
+
296
+ bool SATEncoder::matches_in_interval(int wi, int pi, int l, int r) {
297
+ for (int w = l; w < r; w++) {
298
+ if (_word_tags[w].match_possible(wi, pi))
299
+ return true;
300
+ }
301
+ return false;
302
+ }
303
+
304
+ /*-------------------------------------------------------------------------*
305
+ * S A T I S F A C T I O N *
306
+ *-------------------------------------------------------------------------*/
307
+
308
+ void SATEncoder::generate_satisfaction_conditions() {
309
+ for (int w = 0; w < _sent->length; w++) {
310
+ if (_sent->word[w].x == NULL) {
311
+ DEBUG_print("Word: " << _sent->word[w].string << " : " << "(null)" << endl);
312
+ handle_null_expression(w);
313
+ continue;
314
+ }
315
+
316
+ bool join = _sent->word[w].x->next != NULL;
317
+ Exp* exp = join ? join_alternatives(w) : _sent->word[w].x->exp;
318
+
319
+ #ifdef _DEBUG
320
+ cout << "Word: " << _sent->word[w].string << endl;
321
+ print_expression(exp);
322
+ cout << endl;
323
+ #endif
324
+
325
+ char name[MAX_VARIABLE_NAME];
326
+ sprintf(name, "w%d", w);
327
+
328
+ determine_satisfaction(w, name);
329
+ int dfs_position = 0;
330
+ generate_satisfaction_for_expression(w, dfs_position, exp, name, 0);
331
+
332
+ if (join)
333
+ free_alternatives(exp);
334
+ }
335
+ }
336
+
337
+
338
+ void SATEncoder::generate_satisfaction_for_expression(int w, int& dfs_position, Exp* e, char* var, int parrent_cost) {
339
+ E_list *l;
340
+ int total_cost = parrent_cost + e->cost;
341
+
342
+ if (e->type == CONNECTOR_type) {
343
+ dfs_position++;
344
+
345
+ generate_satisfaction_for_connector(w, dfs_position, e->u.string, e->dir, e->multi, e->cost, var);
346
+
347
+ if (total_cost > _cost_cutoff) {
348
+ Lit lhs = Lit(_variables->string_cost(var, e->cost));
349
+ generate_literal(~lhs);
350
+ }
351
+ } else {
352
+ if (e->type == AND_type) {
353
+ if (e->u.l == NULL) {
354
+ /* zeroary and */
355
+ _variables->string_cost(var, e->cost);
356
+ if (total_cost > _cost_cutoff) {
357
+ generate_literal(~Lit(_variables->string_cost(var, e->cost)));
358
+ }
359
+ } else if (e->u.l != NULL && e->u.l->next == NULL) {
360
+ /* unary and - skip */
361
+ generate_satisfaction_for_expression(w, dfs_position, e->u.l->e, var, total_cost);
362
+ } else {
363
+ /* n-ary and */
364
+ int i;
365
+
366
+ char new_var[MAX_VARIABLE_NAME];
367
+ char* last_new_var = new_var;
368
+ char* last_var = var;
369
+ while(*last_new_var = *last_var) {
370
+ last_new_var++;
371
+ last_var++;
372
+ }
373
+
374
+ vec<Lit> rhs;
375
+ for (i = 0, l=e->u.l; l!=NULL; l=l->next, i++) {
376
+ // sprintf(new_var, "%sc%d", var, i)
377
+ char* s = last_new_var;
378
+ *s++ = 'c';
379
+ fast_sprintf(s, i);
380
+ rhs.push(Lit(_variables->string(new_var)));
381
+ }
382
+
383
+ Lit lhs = Lit(_variables->string_cost(var, e->cost));
384
+ generate_and_definition(lhs, rhs);
385
+
386
+ /* Preceeds */
387
+ int dfs_position_tmp = dfs_position;
388
+ for (l = e->u.l; l->next != NULL; l = l->next) {
389
+ generate_conjunct_order_constraints(w, l->e, l->next->e, dfs_position_tmp);
390
+ }
391
+
392
+ /* Recurse */
393
+ for (i = 0, l=e->u.l; l!=NULL; l=l->next, i++) {
394
+ // sprintf(new_var, "%sc%d", var, i)
395
+ char* s = last_new_var;
396
+ *s++ = 'c';
397
+ fast_sprintf(s, i);
398
+
399
+ generate_satisfaction_for_expression(w, dfs_position, l->e, new_var, total_cost);
400
+ }
401
+ }
402
+ } else if (e->type == OR_type) {
403
+ if (e->u.l == NULL) {
404
+ /* zeroary or */
405
+ cerr << "Zeroary OR" << endl;
406
+ exit(EXIT_FAILURE);
407
+ } else if (e->u.l != NULL && e->u.l->next == NULL) {
408
+ /* unary or */
409
+ generate_satisfaction_for_expression(w, dfs_position, e->u.l->e, var, total_cost);
410
+ } else {
411
+ /* n-ary or */
412
+ int i;
413
+
414
+ char new_var[MAX_VARIABLE_NAME];
415
+ char* last_new_var = new_var;
416
+ char* last_var = var;
417
+ while(*last_new_var = *last_var) {
418
+ last_new_var++;
419
+ last_var++;
420
+ }
421
+
422
+ vec<Lit> rhs;
423
+ for (i = 0, l=e->u.l; l!=NULL; l=l->next, i++) {
424
+ // sprintf(new_var, "%sc%d", var, i)
425
+ char* s = last_new_var;
426
+ *s++ = 'd';
427
+ fast_sprintf(s, i);
428
+ rhs.push(Lit(_variables->string(new_var)));
429
+ }
430
+
431
+ Lit lhs = Lit(_variables->string_cost(var, e->cost));
432
+ generate_or_definition(lhs, rhs);
433
+ generate_xor_conditions(rhs);
434
+
435
+ /* Recurse */
436
+ for (i = 0, l=e->u.l; l!=NULL; l=l->next, i++) {
437
+ char* s = last_new_var;
438
+ *s++ = 'd';
439
+ fast_sprintf(s, i);
440
+
441
+ generate_satisfaction_for_expression(w, dfs_position, l->e, new_var, total_cost);
442
+ }
443
+ }
444
+ }
445
+ }
446
+ }
447
+
448
+ Exp* SATEncoder::join_alternatives(int w) {
449
+ // join all alternatives using and OR_type node
450
+ Exp* exp;
451
+ E_list* or_list = NULL;;
452
+ for (X_node* x = _sent->word[w].x; x != NULL; x = x->next) {
453
+ E_list* new_node = (E_list*)xalloc(sizeof(E_list));
454
+ new_node->e = x->exp;
455
+ new_node->next = NULL;
456
+ if (or_list == NULL) {
457
+ or_list = new_node;
458
+ } else {
459
+ E_list *y;
460
+ for (y = or_list; y->next != NULL; y = y->next)
461
+ ;
462
+ y->next = new_node;
463
+ }
464
+ }
465
+ exp = (Exp*)xalloc(sizeof(Exp));
466
+ exp->type = OR_type;
467
+ exp->u.l = or_list;
468
+ exp->cost = 0;
469
+
470
+ return exp;
471
+ }
472
+
473
+ void SATEncoder::free_alternatives(Exp* exp) {
474
+ E_list *l = exp->u.l;
475
+ while (l != NULL) {
476
+ E_list* next = l->next;
477
+ xfree(l, sizeof(E_list));
478
+ l = next;
479
+ }
480
+ xfree(exp, sizeof(exp));
481
+ }
482
+
483
+
484
+ void SATEncoder::generate_link_cw_ordinary_definition(int wi, int pi, const char* Ci, char dir, int cost, int wj) {
485
+ Lit lhs = Lit(_variables->link_cw(wj, wi, pi, Ci));
486
+
487
+ char str[MAX_VARIABLE_NAME];
488
+ sprintf(str, "w%d", wj);
489
+ Lit condition = Lit(_variables->string(str));
490
+
491
+ vec<Lit> rhs;
492
+
493
+ // Collect matches (wi, pi) with word wj
494
+ std::vector<PositionConnector*>& matches = _word_tags[wi].get(pi)->matches;
495
+ std::vector<PositionConnector*>::const_iterator i;
496
+ for (i = matches.begin(); i != matches.end(); i++) {
497
+ /* TODO: PositionConnector->matches[wj] */
498
+ if ((*i)->word != wj)
499
+ continue;
500
+
501
+ if (dir == '+') {
502
+ rhs.push(Lit(_variables->link_cost(wi, pi, Ci,
503
+ (*i)->word, (*i)->position, (*i)->connector->string,
504
+ cost + (*i)->cost)));
505
+ } else if (dir == '-'){
506
+ rhs.push(Lit(_variables->link((*i)->word, (*i)->position, (*i)->connector->string,
507
+ wi, pi, Ci)));
508
+ }
509
+ }
510
+
511
+ // Generate clauses
512
+ DEBUG_print("--------- link_cw as ordinary down");
513
+ generate_conditional_lr_implication_or_definition(condition, lhs, rhs);
514
+ generate_xor_conditions(rhs);
515
+ DEBUG_print("--------- end link_cw as ordinary down");
516
+ }
517
+
518
+ /*--------------------------------------------------------------------------*
519
+ * C O N J U N C T O R D E R I N G *
520
+ *--------------------------------------------------------------------------*/
521
+ int SATEncoder::num_connectors(Exp* e) {
522
+ if (e->type == CONNECTOR_type)
523
+ return 1;
524
+ else {
525
+ int num = 0;
526
+ for (E_list* l = e->u.l; l != NULL; l = l->next) {
527
+ num += num_connectors(l->e);
528
+ }
529
+ return num;
530
+ }
531
+ }
532
+
533
+ int SATEncoder::empty_connectors(Exp* e, char dir) {
534
+ if (e->type == CONNECTOR_type) {
535
+ return e->dir != dir;
536
+ } else if (e->type == OR_type) {
537
+ for (E_list* l = e->u.l; l != NULL; l = l->next) {
538
+ if (empty_connectors(l->e, dir))
539
+ return true;
540
+ }
541
+ return false;
542
+ } else if (e->type == AND_type) {
543
+ for (E_list* l = e->u.l; l != NULL; l = l->next) {
544
+ if (!empty_connectors(l->e, dir))
545
+ return false;
546
+ }
547
+ return true;
548
+ } else
549
+ throw std::string("Unkown connector type");
550
+ }
551
+
552
+ int SATEncoder::non_empty_connectors(Exp* e, char dir) {
553
+ if (e->type == CONNECTOR_type) {
554
+ return e->dir == dir;
555
+ } else if (e->type == OR_type) {
556
+ for (E_list* l = e->u.l; l != NULL; l = l->next) {
557
+ if (non_empty_connectors(l->e, dir))
558
+ return true;
559
+ }
560
+ return false;
561
+ } else if (e->type == AND_type) {
562
+ for (E_list* l = e->u.l; l != NULL; l = l->next) {
563
+ if (non_empty_connectors(l->e, dir))
564
+ return true;
565
+ }
566
+ return false;
567
+ } else
568
+ throw std::string("Unkown connector type");
569
+ }
570
+
571
+ bool SATEncoder::trailing_connectors_and_aux(int w, E_list* l, char dir, int& dfs_position,
572
+ std::vector<PositionConnector*>& connectors) {
573
+ if (l == NULL) {
574
+ return true;
575
+ } else {
576
+ int dfs_position_in = dfs_position;
577
+ dfs_position += num_connectors(l->e);
578
+ if (trailing_connectors_and_aux(w, l->next, dir, dfs_position, connectors)) {
579
+ trailing_connectors(w, l->e, dir, dfs_position_in, connectors);
580
+ }
581
+ return empty_connectors(l->e, dir);
582
+ }
583
+ }
584
+
585
+ void SATEncoder::trailing_connectors(int w, Exp* exp, char dir, int& dfs_position,
586
+ std::vector<PositionConnector*>& connectors) {
587
+ if (exp->type == CONNECTOR_type) {
588
+ dfs_position++;
589
+ if (exp->dir == dir) {
590
+ connectors.push_back(_word_tags[w].get(dfs_position));
591
+ }
592
+ } else if (exp->type == OR_type) {
593
+ for (E_list* l = exp->u.l; l != NULL; l = l->next) {
594
+ trailing_connectors(w, l->e, dir, dfs_position, connectors);
595
+ }
596
+ } else if (exp->type == AND_type) {
597
+ trailing_connectors_and_aux(w, exp->u.l, dir, dfs_position, connectors);
598
+ }
599
+ }
600
+
601
+ void SATEncoder::certainly_non_trailing(int w, Exp* exp, char dir, int& dfs_position,
602
+ std::vector<PositionConnector*>& connectors, bool has_right) {
603
+ if (exp->type == CONNECTOR_type) {
604
+ dfs_position++;
605
+ if (exp->dir == dir && has_right) {
606
+ connectors.push_back(_word_tags[w].get(dfs_position));
607
+ }
608
+ } else if (exp->type == OR_type) {
609
+ for (E_list* l = exp->u.l; l != NULL; l = l->next) {
610
+ certainly_non_trailing(w, l->e, dir, dfs_position, connectors, has_right);
611
+ }
612
+ } else if (exp->type == AND_type) {
613
+ if (has_right) {
614
+ for (E_list* l = exp->u.l; l != NULL; l = l->next) {
615
+ certainly_non_trailing(w, l->e, dir, dfs_position, connectors, true);
616
+ }
617
+ } else {
618
+ for (E_list* l = exp->u.l; l != NULL; l = l->next) {
619
+ has_right = false;
620
+ for (E_list* m = l->next; m != NULL; m = m->next) {
621
+ if (non_empty_connectors(m->e, dir) && !empty_connectors(m->e, dir)) {
622
+ has_right = true;
623
+ break;
624
+ }
625
+ }
626
+ certainly_non_trailing(w, l->e, dir, dfs_position, connectors, has_right);
627
+ }
628
+ }
629
+ }
630
+ }
631
+
632
+ void SATEncoder::leading_connectors(int w, Exp* exp, char dir, int& dfs_position, vector<PositionConnector*>& connectors) {
633
+ if (exp->type == CONNECTOR_type) {
634
+ dfs_position++;
635
+ if (exp->dir == dir) {
636
+ connectors.push_back(_word_tags[w].get(dfs_position));
637
+ }
638
+ } else if (exp->type == OR_type) {
639
+ for (E_list* l = exp->u.l; l != NULL; l = l->next) {
640
+ leading_connectors(w, l->e, dir, dfs_position, connectors);
641
+ }
642
+ } else if (exp->type == AND_type) {
643
+ E_list* l;
644
+ for (l = exp->u.l; l != NULL; l = l->next) {
645
+ leading_connectors(w, l->e, dir, dfs_position, connectors);
646
+ if (!empty_connectors(l->e, dir))
647
+ break;
648
+ }
649
+
650
+ if (l != NULL) {
651
+ for (l = l->next; l != NULL; l = l->next)
652
+ dfs_position += num_connectors(l->e);
653
+ }
654
+ }
655
+ }
656
+
657
+ void SATEncoder::generate_conjunct_order_constraints(int w, Exp *e1, Exp* e2, int& dfs_position) {
658
+ DEBUG_print("----- conjunct order constraints");
659
+ int dfs_position_e1 = dfs_position;
660
+ std::vector<PositionConnector*> last_right_in_e1, first_right_in_e2;
661
+ trailing_connectors(w, e1, '+', dfs_position_e1, last_right_in_e1);
662
+
663
+ int dfs_position_e2 = dfs_position_e1;
664
+ leading_connectors(w, e2, '+', dfs_position_e2, first_right_in_e2);
665
+
666
+ vec<Lit> clause;
667
+
668
+ if (!last_right_in_e1.empty() && !first_right_in_e2.empty()) {
669
+ std::vector<PositionConnector*>::iterator i, j;
670
+ for (i = last_right_in_e1.begin(); i != last_right_in_e1.end(); i++) {
671
+ std::vector<PositionConnector*>& matches_e1 = (*i)->matches;
672
+
673
+ for (j = first_right_in_e2.begin(); j != first_right_in_e2.end(); j++) {
674
+ std::vector<PositionConnector*>& matches_e2 = (*j)->matches;
675
+ std::vector<PositionConnector*>::const_iterator m1, m2;
676
+
677
+ std::vector<int> mw1;
678
+ for (m1 = matches_e1.begin(); m1 != matches_e1.end(); m1++) {
679
+ if ((m1+1) == matches_e1.end() || (*m1)->word != (*(m1 + 1))->word)
680
+ mw1.push_back((*m1)->word);
681
+ }
682
+
683
+ std::vector<int> mw2;
684
+ for (m2 = matches_e2.begin(); m2 != matches_e2.end(); m2++) {
685
+ if ((m2+1) == matches_e2.end() || (*m2)->word != (*(m2 + 1))->word)
686
+ mw2.push_back((*m2)->word);
687
+ }
688
+
689
+ std::vector<int>::const_iterator mw1i, mw2i;
690
+ for (mw1i = mw1.begin(); mw1i != mw1.end(); mw1i++) {
691
+ for (mw2i = mw2.begin(); mw2i != mw2.end(); mw2i++) {
692
+ if (*mw1i >= *mw2i) {
693
+ clause.growTo(2);
694
+ clause[0] = ~Lit(_variables->link_cw(*mw1i, w, (*i)->position, (*i)->connector->string));
695
+ clause[1] = ~Lit(_variables->link_cw(*mw2i, w, (*j)->position, (*j)->connector->string));
696
+ add_clause(clause);
697
+ }
698
+ }
699
+ }
700
+ }
701
+ }
702
+ }
703
+
704
+ DEBUG_print("----");
705
+ dfs_position_e1 = dfs_position;
706
+ std::vector<PositionConnector*> last_left_in_e1, first_left_in_e2;
707
+ trailing_connectors(w, e1, '-', dfs_position_e1, last_left_in_e1);
708
+
709
+ dfs_position_e2 = dfs_position_e1;
710
+ leading_connectors(w, e2, '-', dfs_position_e2, first_left_in_e2);
711
+
712
+ if (!last_left_in_e1.empty() && !first_left_in_e2.empty()) {
713
+ std::vector<PositionConnector*>::iterator i, j;
714
+ for (i = last_left_in_e1.begin(); i != last_left_in_e1.end(); i++) {
715
+ std::vector<PositionConnector*>& matches_e1 = (*i)->matches;
716
+
717
+ for (j = first_left_in_e2.begin(); j != first_left_in_e2.end(); j++) {
718
+ std::vector<PositionConnector*>& matches_e2 = (*j)->matches;
719
+
720
+ std::vector<PositionConnector*>::const_iterator m1, m2;
721
+
722
+
723
+ std::vector<int> mw1;
724
+ for (m1 = matches_e1.begin(); m1 != matches_e1.end(); m1++) {
725
+ if ((m1+1) == matches_e1.end() || (*m1)->word != (*(m1 + 1))->word)
726
+ mw1.push_back((*m1)->word);
727
+ }
728
+
729
+ std::vector<int> mw2;
730
+ for (m2 = matches_e2.begin(); m2 != matches_e2.end(); m2++) {
731
+ if ((m2+1) == matches_e2.end() || (*m2)->word != (*(m2 + 1))->word)
732
+ mw2.push_back((*m2)->word);
733
+ }
734
+
735
+ std::vector<int>::const_iterator mw1i, mw2i;
736
+ for (mw1i = mw1.begin(); mw1i != mw1.end(); mw1i++) {
737
+ for (mw2i = mw2.begin(); mw2i != mw2.end(); mw2i++) {
738
+ if (*mw1i <= *mw2i) {
739
+ clause.growTo(2);
740
+ clause[0] = ~Lit(_variables->link_cw(*mw1i, w, (*i)->position, (*i)->connector->string));
741
+ clause[1] = ~Lit(_variables->link_cw(*mw2i, w, (*j)->position, (*j)->connector->string));
742
+ add_clause(clause);
743
+ }
744
+ }
745
+ }
746
+ }
747
+ }
748
+ }
749
+
750
+ dfs_position = dfs_position_e1;
751
+
752
+ DEBUG_print("---end conjunct order constraints");
753
+ }
754
+
755
+
756
+
757
+ /*--------------------------------------------------------------------------*
758
+ * C O N N E C T I V I T Y *
759
+ *--------------------------------------------------------------------------*/
760
+
761
+ #ifdef _CONNECTIVITY_
762
+ void SATEncoder::generate_connectivity() {
763
+ for (int w = 1; w < _sent->length; w++) {
764
+ if (!_linkage_possible(0, w)) {
765
+ vec<Lit> clause;
766
+ clause.push(~Lit(_variables->con(w, 1)));
767
+ generate_and(clause);
768
+ }
769
+ else {
770
+ generate_equivalence_definition(Lit(_variables->con(w, 1)),
771
+ Lit(_variables->linked(0, w)));
772
+ }
773
+ }
774
+
775
+ for (int d = 2; d < _sent->length; d++) {
776
+ for (int w = 1; w < _sent->length; w++) {
777
+ Lit lhs = Lit(_variables->con(w, d));
778
+
779
+ vec<Lit> rhs;
780
+ rhs.push(Lit(_variables->con(w, d-1)));
781
+ for (int w1 = 1; w1 < _sent->length; w1++) {
782
+ if (w == w1)
783
+ continue;
784
+
785
+ if (!_linkage_possible(std::min(w, w1), std::max(w, w1))) {
786
+ continue;
787
+ }
788
+ rhs.push(Lit(_variables->l_con(w, w1, d-1)));
789
+ }
790
+ generate_or_definition(lhs, rhs);
791
+
792
+
793
+ /* lc definitions*/
794
+ for (int w1 = 1; w1 < _sent->length; w1++) {
795
+ if (w == w1)
796
+ continue;
797
+
798
+ int mi = std::min(w, w1), ma = std::max(w, w1);
799
+ if (!_linked_possible(mi, ma))
800
+ continue;
801
+
802
+ Lit lhs = Lit(_variables->l_con(w, w1, d-1));
803
+ vec<Lit> rhs(2);
804
+ rhs[0] = Lit(_variables->linked(mi, ma));
805
+ rhs[1] = Lit(_variables->con(w1, d-1));
806
+ generate_classical_and_definition(lhs, rhs);
807
+ }
808
+ }
809
+ }
810
+
811
+
812
+ for (int w = 1; w < _sent->length; w++) {
813
+ generate_literal(Lit(_variables->con(w, _sent->length-1)));
814
+ }
815
+ }
816
+ #endif
817
+
818
+ void SATEncoder::dfs(int node, const MatrixUpperTriangle<int>& graph, int component, std::vector<int>& components) {
819
+ if (components[node] != -1)
820
+ return;
821
+
822
+ components[node] = component;
823
+ for (int other_node = node + 1; other_node < components.size(); other_node++) {
824
+ if (graph(node, other_node))
825
+ dfs(other_node, graph, component, components);
826
+ }
827
+ for (int other_node = 0; other_node < node; other_node++) {
828
+ if (graph(other_node, node))
829
+ dfs(other_node, graph, component, components);
830
+ }
831
+ }
832
+
833
+
834
+ bool SATEncoder::connectivity_components(std::vector<int>& components) {
835
+ // get satisfied linked(wi, wj) variables
836
+ const std::vector<int>& linked_variables = _variables->linked_variables();
837
+ std::vector<int> satisfied_linked_variables;
838
+ for (std::vector<int>::const_iterator i = linked_variables.begin(); i != linked_variables.end(); i++) {
839
+ int var = *i;
840
+ if (_solver->model[var] == l_True) {
841
+ satisfied_linked_variables.push_back(var);
842
+ }
843
+ }
844
+
845
+ // build the connectivity graph
846
+ MatrixUpperTriangle<int> graph(_sent->length, 0);
847
+ std::vector<int>::const_iterator i;
848
+ for (i = satisfied_linked_variables.begin(); i != satisfied_linked_variables.end(); i++) {
849
+ graph.set(_variables->linked_variable(*i)->left_word,
850
+ _variables->linked_variable(*i)->right_word, 1);
851
+ }
852
+
853
+ // determine the connectivity components
854
+ components.resize(_sent->length);
855
+ std::fill(components.begin(), components.end(), -1);
856
+ for (int node = 0; node < _sent->length; node++)
857
+ dfs(node, graph, node, components);
858
+ bool connected = true;
859
+ for (int node = 0; node < _sent->length; node++) {
860
+ if (components[node] != 0) {
861
+ connected = false;
862
+ }
863
+ }
864
+
865
+ return connected;
866
+ }
867
+
868
+ void SATEncoder::generate_disconnectivity_prohibiting(std::vector<int> components) {
869
+ // vector of unique components
870
+ std::vector<int> different_components = components;
871
+ std::sort(different_components.begin(), different_components.end());
872
+ different_components.erase(std::unique(different_components.begin(), different_components.end()),
873
+ different_components.end());
874
+
875
+ // Each connected component must contain a branch going out of it
876
+ std::vector<int>::const_iterator c;
877
+ for (c = different_components.begin(); c != different_components.end(); c++) {
878
+ vec<Lit> clause;
879
+ const std::vector<int>& linked_variables = _variables->linked_variables();
880
+ for (std::vector<int>::const_iterator i = linked_variables.begin(); i != linked_variables.end(); i++) {
881
+ int var = *i;
882
+ const Variables::LinkedVar* lv = _variables->linked_variable(var);
883
+ if ((components[lv->left_word] == *c && components[lv->right_word] != *c) ||
884
+ (components[lv->left_word] != *c && components[lv->right_word] == *c)) {
885
+ clause.push(Lit(var));
886
+ }
887
+ }
888
+ _solver->addConflictingClause(clause);
889
+ if (different_components.size() == 2)
890
+ break;
891
+ }
892
+ }
893
+
894
+ /*--------------------------------------------------------------------------*
895
+ * P L A N A R I T Y *
896
+ *--------------------------------------------------------------------------*/
897
+ void SATEncoder::generate_planarity_conditions() {
898
+ vec<Lit> clause;
899
+ for (int wi1 = 0; wi1 < _sent->length; wi1++) {
900
+ for (int wj1 = wi1+1; wj1 < _sent->length; wj1++) {
901
+ for (int wi2 = wj1+1; wi2 < _sent->length; wi2++) {
902
+ if (!_linked_possible(wi1, wi2))
903
+ continue;
904
+ for (int wj2 = wi2+1; wj2 < _sent->length; wj2++) {
905
+ if (!_linked_possible(wj1, wj2))
906
+ continue;
907
+ clause.growTo(2);
908
+ clause[0] = ~Lit(_variables->linked(wi1, wi2));
909
+ clause[1] = ~Lit(_variables->linked(wj1, wj2));
910
+ add_clause(clause);
911
+ }
912
+ }
913
+ }
914
+ }
915
+
916
+ // generate_linked_min_max_planarity();
917
+ }
918
+
919
+ /*--------------------------------------------------------------------------*
920
+ * P O W E R P R U N I N G *
921
+ *--------------------------------------------------------------------------*/
922
+
923
+ void SATEncoder::generate_epsilon_definitions() {
924
+ for (int w = 0; w < _sent->length; w++) {
925
+ if (_sent->word[w].x == NULL) {
926
+ continue;
927
+ }
928
+
929
+ bool join = _sent->word[w].x->next != NULL;
930
+ Exp* exp = join ? join_alternatives(w) : _sent->word[w].x->exp;
931
+
932
+ char name[MAX_VARIABLE_NAME];
933
+ sprintf(name, "w%d", w);
934
+
935
+ int dfs_position;
936
+
937
+ dfs_position = 0;
938
+ generate_epsilon_for_expression(w, dfs_position, exp, name, true, '+');
939
+
940
+ dfs_position = 0;
941
+ generate_epsilon_for_expression(w, dfs_position, exp, name, true, '-');
942
+
943
+ if (join)
944
+ free_alternatives(exp);
945
+ }
946
+ }
947
+
948
+ bool SATEncoder::generate_epsilon_for_expression(int w, int& dfs_position, Exp* e,
949
+ char* var, bool root, char dir) {
950
+ E_list *l;
951
+ if (e->type == CONNECTOR_type) {
952
+ dfs_position++;
953
+ if (var != NULL) {
954
+ if (e->dir == dir) {
955
+ // generate_literal(-_variables->epsilon(name, var, e->dir));
956
+ return false;
957
+ } else {
958
+ generate_equivalence_definition(Lit(_variables->epsilon(var, dir)),
959
+ Lit(_variables->string(var)));
960
+ return true;
961
+ }
962
+ }
963
+ } else if (e->type == AND_type) {
964
+ if (e->u.l == NULL) {
965
+ /* zeroary and */
966
+ generate_equivalence_definition(Lit(_variables->string(var)),
967
+ Lit(_variables->epsilon(var, dir)));
968
+ return true;
969
+ } else
970
+ if (e->u.l != NULL && e->u.l->next == NULL) {
971
+ /* unary and - skip */
972
+ return generate_epsilon_for_expression(w, dfs_position, e->u.l->e, var, root, dir);
973
+ } else {
974
+ /* Recurse */
975
+ E_list* l;
976
+ int i;
977
+ bool eps = true;
978
+
979
+ char new_var[MAX_VARIABLE_NAME];
980
+ char* last_new_var = new_var;
981
+ char* last_var = var;
982
+ while(*last_new_var = *last_var) {
983
+ last_new_var++;
984
+ last_var++;
985
+ }
986
+
987
+
988
+ for (i = 0, l = e->u.l; l != NULL; l = l->next, i++) {
989
+ // sprintf(new_var, "%sc%d", var, i)
990
+ char* s = last_new_var;
991
+ *s++ = 'c';
992
+ fast_sprintf(s, i);
993
+
994
+ if (!generate_epsilon_for_expression(w, dfs_position, l->e, new_var, false, dir)) {
995
+ eps = false;
996
+ break;
997
+ }
998
+ }
999
+
1000
+ if (l != NULL) {
1001
+ for (l = l->next; l != NULL; l = l->next)
1002
+ dfs_position += num_connectors(l->e);
1003
+ }
1004
+
1005
+ if (!root && eps) {
1006
+ Lit lhs = Lit(_variables->epsilon(var, dir));
1007
+ vec<Lit> rhs;
1008
+ for (i = 0, l=e->u.l; l!=NULL; l=l->next, i++) {
1009
+ // sprintf(new_var, "%sc%d", var, i)
1010
+ char* s = last_new_var;
1011
+ *s++ = 'c';
1012
+ fast_sprintf(s, i);
1013
+ rhs.push(Lit(_variables->epsilon(new_var, dir)));
1014
+ }
1015
+ generate_classical_and_definition(lhs, rhs);
1016
+ }
1017
+ return eps;
1018
+ }
1019
+ } else if (e->type == OR_type) {
1020
+ if (e->u.l != NULL && e->u.l->next == NULL) {
1021
+ /* unary or - skip */
1022
+ return generate_epsilon_for_expression(w, dfs_position, e->u.l->e, var, root, dir);
1023
+ } else {
1024
+ /* Recurse */
1025
+ E_list* l;
1026
+ int i;
1027
+ bool eps = false;
1028
+
1029
+ char new_var[MAX_VARIABLE_NAME];
1030
+ char* last_new_var = new_var;
1031
+ char* last_var = var;
1032
+ while(*last_new_var = *last_var) {
1033
+ last_new_var++;
1034
+ last_var++;
1035
+ }
1036
+
1037
+ vec<Lit> rhs;
1038
+ for (i = 0, l = e->u.l; l != NULL; l = l->next, i++) {
1039
+ // sprintf(new_var, "%sc%d", var, i)
1040
+ char* s = last_new_var;
1041
+ *s++ = 'd';
1042
+ fast_sprintf(s, i);
1043
+
1044
+ if (generate_epsilon_for_expression(w, dfs_position, l->e, new_var, false, dir) && !root) {
1045
+ rhs.push(Lit(_variables->epsilon(new_var, dir)));
1046
+ eps = true;
1047
+ }
1048
+ }
1049
+
1050
+ if (!root && eps) {
1051
+ Lit lhs = Lit(_variables->epsilon(var, dir));
1052
+ generate_or_definition(lhs, rhs);
1053
+ }
1054
+
1055
+ return eps;
1056
+ }
1057
+ }
1058
+ return false;
1059
+ }
1060
+
1061
+ void SATEncoder::power_prune() {
1062
+ generate_epsilon_definitions();
1063
+
1064
+ // on two non-adjacent words, a pair of connectors can be used only
1065
+ // if not [both of them are the deepest].
1066
+
1067
+ for (int wl = 0; wl < _sent->length - 2; wl++) {
1068
+ const std::vector<PositionConnector>& rc = _word_tags[wl].get_right_connectors();
1069
+ std::vector<PositionConnector>::const_iterator rci;
1070
+ for (rci = rc.begin(); rci != rc.end(); rci++) {
1071
+ if (!(*rci).leading_right || (*rci).connector->multi)
1072
+ continue;
1073
+
1074
+ const std::vector<PositionConnector*>& matches = rci->matches;
1075
+ for (std::vector<PositionConnector*>::const_iterator lci = matches.begin(); lci != matches.end(); lci++) {
1076
+ if (!(*lci)->leading_left || (*lci)->connector->multi || (*lci)->word <= wl + 2)
1077
+ continue;
1078
+
1079
+ // printf("LR: .%d. .%d. %s\n", wl, rci->position, rci->connector->string);
1080
+ // printf("LL: .%d. .%d. %s\n", (*lci)->word, (*lci)->position, (*lci)->connector->string);
1081
+
1082
+ vec<Lit> clause;
1083
+ for (std::vector<int>::const_iterator i = rci->eps_right.begin(); i != rci->eps_right.end(); i++) {
1084
+ clause.push(~Lit(*i));
1085
+ }
1086
+
1087
+ for (std::vector<int>::const_iterator i = (*lci)->eps_left.begin(); i != (*lci)->eps_left.end(); i++) {
1088
+ clause.push(~Lit(*i));
1089
+ }
1090
+
1091
+ add_additional_power_pruning_conditions(clause, wl, (*lci)->word);
1092
+
1093
+ clause.push(~Lit(_variables->link(wl, rci->position, rci->connector->string,
1094
+ (*lci)->word, (*lci)->position, (*lci)->connector->string)));
1095
+ add_clause(clause);
1096
+ }
1097
+ }
1098
+ }
1099
+
1100
+ /*
1101
+ // on two adjacent words, a pair of connectors can be used only if
1102
+ // they're the deepest ones on their disjuncts
1103
+ for (int wl = 0; wl < _sent->length - 2; wl++) {
1104
+ const std::vector<PositionConnector>& rc = _word_tags[wl].get_right_connectors();
1105
+ std::vector<PositionConnector>::const_iterator rci;
1106
+ for (rci = rc.begin(); rci != rc.end(); rci++) {
1107
+ if (!(*rci).leading_right)
1108
+ continue;
1109
+
1110
+ const std::vector<PositionConnector*>& matches = rci->matches;
1111
+ for (std::vector<PositionConnector*>::const_iterator lci = matches.begin(); lci != matches.end(); lci++) {
1112
+ if (!(*lci)->leading_left || (*lci)->word != wl + 1)
1113
+ continue;
1114
+ int link = _variables->link(wl, rci->position, rci->connector->string,
1115
+ (*lci)->word, (*lci)->position, (*lci)->connector->string);
1116
+ std::vector<int> clause(2);
1117
+ clause[0] = -link;
1118
+
1119
+ for (std::vector<int>::const_iterator i = rci->eps_right.begin(); i != rci->eps_right.end(); i++) {
1120
+ clause[1] = *i;
1121
+ }
1122
+
1123
+ for (std::vector<int>::const_iterator i = (*lci)->eps_left.begin(); i != (*lci)->eps_left.end(); i++) {
1124
+ clause[1] = *i;
1125
+ }
1126
+
1127
+ add_clause(clause);
1128
+ }
1129
+ }
1130
+ }
1131
+
1132
+
1133
+ // Two deep connectors cannot match (deep means notlast)
1134
+ std::vector<std::vector<PositionConnector*> > certainly_deep_left(_sent->length), certainly_deep_right(_sent->length);
1135
+ for (int w = 0; w < _sent->length; w++) {
1136
+ if (_sent->word[w].x == NULL)
1137
+ continue;
1138
+
1139
+ bool join = _sent->word[w].x->next != NULL;
1140
+ Exp* exp = join ? join_alternatives(w) : _sent->word[w].x->exp;
1141
+
1142
+ int dfs_position = 0;
1143
+ certainly_non_trailing(w, exp, '+', dfs_position, certainly_deep_right[w], false);
1144
+ dfs_position = 0;
1145
+ certainly_non_trailing(w, exp, '-', dfs_position, certainly_deep_left[w], false);
1146
+
1147
+ if (join)
1148
+ free_alternatives(exp);
1149
+ }
1150
+
1151
+ for (int w = 0; w < _sent->length; w++) {
1152
+ std::vector<PositionConnector*>::const_iterator i;
1153
+ for (i = certainly_deep_right[w].begin(); i != certainly_deep_right[w].end(); i++) {
1154
+ const std::vector<PositionConnector*>& matches = (*i)->matches;
1155
+ std::vector<PositionConnector*>::const_iterator j;
1156
+ for (j = matches.begin(); j != matches.end(); j++) {
1157
+ if (std::find(certainly_deep_left[(*j)->word].begin(), certainly_deep_left[(*j)->word].end(),
1158
+ *j) != certainly_deep_left[(*j)->word].end()) {
1159
+ generate_literal(-_variables->link((*i)->word, (*i)->position, (*i)->connector->string,
1160
+ (*j)->word, (*j)->position, (*j)->connector->string));
1161
+ }
1162
+ }
1163
+ }
1164
+ }
1165
+ */
1166
+ }
1167
+
1168
+ /*--------------------------------------------------------------------------*
1169
+ * P O S T P R O C E S S I N G & P P P R U N I N G *
1170
+ *--------------------------------------------------------------------------*/
1171
+ void SATEncoder::pp_prune() {
1172
+ const std::vector<int>& link_variables = _variables->link_variables();
1173
+
1174
+
1175
+ if (_sent->dict->postprocessor == NULL)
1176
+ return;
1177
+
1178
+ pp_knowledge * knowledge;
1179
+ knowledge = _sent->dict->postprocessor->knowledge;
1180
+
1181
+ for (int i=0; i<knowledge->n_contains_one_rules; i++) {
1182
+ pp_rule rule;
1183
+ const char * selector;
1184
+ pp_linkset * link_set;
1185
+
1186
+ rule = knowledge->contains_one_rules[i];
1187
+ selector = rule.selector; /* selector string for this rule */
1188
+ link_set = rule.link_set; /* the set of criterion links */
1189
+
1190
+
1191
+ vec<Lit> triggers;
1192
+ for (int i = 0; i < link_variables.size(); i++) {
1193
+ const Variables::LinkVar* var = _variables->link_variable(link_variables[i]);
1194
+ if (post_process_match(rule.selector, var->label)) {
1195
+ triggers.push(Lit(link_variables[i]));
1196
+ }
1197
+ }
1198
+
1199
+ if (triggers.size() == 0)
1200
+ continue;
1201
+
1202
+ vec<Lit> criterions;
1203
+ for (int j = 0; j < link_variables.size(); j++) {
1204
+ pp_linkset_node *p;
1205
+ for (int hashval = 0; hashval < link_set->hash_table_size; hashval++) {
1206
+ for (p = link_set->hash_table[hashval]; p!=NULL; p=p->next) {
1207
+ const Variables::LinkVar* var = _variables->link_variable(link_variables[j]);
1208
+ if (post_process_match(p->str, var->label)) {
1209
+ criterions.push(Lit(link_variables[j]));
1210
+ }
1211
+ }
1212
+ }
1213
+ }
1214
+
1215
+ DEBUG_print("---pp_pruning--");
1216
+ for (int k = 0; k < triggers.size(); k++) {
1217
+ vec<Lit> clause(criterions.size() + 1);
1218
+ for (int i = 0; i < criterions.size(); i++)
1219
+ clause[i] = criterions[i];
1220
+ clause[criterions.size()] = (~triggers[k]);
1221
+ add_clause(clause);
1222
+ }
1223
+ DEBUG_print("---end pp_pruning--");
1224
+ }
1225
+ }
1226
+
1227
+ /* TODO: replace with analyze_xxx_linkage */
1228
+ bool SATEncoder::post_process_linkage(Linkage linkage)
1229
+ {
1230
+ if (parse_options_get_use_fat_links(_opts) &&
1231
+ set_has_fat_down(_sent)) {
1232
+ Linkage_info li = analyze_fat_linkage(_sent, _opts, PP_SECOND_PASS);
1233
+ return li.N_violations == 0;
1234
+ } else {
1235
+ Linkage_info li = analyze_thin_linkage(_sent, _opts, PP_SECOND_PASS);
1236
+ return li.N_violations == 0;
1237
+ }
1238
+ return 1;
1239
+ }
1240
+
1241
+ /*--------------------------------------------------------------------------*
1242
+ * D E C O D I N G *
1243
+ *--------------------------------------------------------------------------*/
1244
+ Linkage SATEncoder::create_linkage()
1245
+ {
1246
+ /* Using exalloc since this is external to the parser itself. */
1247
+ Linkage linkage = (Linkage) exalloc(sizeof(struct Linkage_s));
1248
+ memset(linkage, 0, sizeof(struct Linkage_s));
1249
+
1250
+ linkage->num_words = _sent->length;
1251
+ linkage->word = (const char **) exalloc(linkage->num_words*sizeof(char *));
1252
+ linkage->sent = _sent;
1253
+ linkage->opts = _opts;
1254
+ // linkage->info = sent->link_info[k];
1255
+
1256
+ if (_sent->parse_info) {
1257
+ Parse_info pi = _sent->parse_info;
1258
+ for (int i=0; i< MAX_LINKS; i++) {
1259
+ free_connectors(pi->link_array[i].lc);
1260
+ free_connectors(pi->link_array[i].rc);
1261
+ }
1262
+ free_parse_info(_sent->parse_info);
1263
+ _sent->parse_info = NULL;
1264
+ }
1265
+ Parse_info pi = _sent->parse_info = parse_info_new(_sent->length);
1266
+ bool fat = extract_links(pi);
1267
+
1268
+ // compute_chosen_words(sent, linkage);
1269
+ /* TODO: this is just a simplified version of the
1270
+ compute_chosen_words. */
1271
+ for (int i = 0; i < _sent->length; i++) {
1272
+ char *s = (char *) exalloc(strlen(_sent->word[i].string)+1);
1273
+ strcpy(s, _sent->word[i].string);
1274
+ linkage->word[i] = s;
1275
+ }
1276
+ linkage->num_words = _sent->length;
1277
+ pi->N_words = _sent->length;
1278
+
1279
+ if (!fat || !parse_options_get_use_fat_links(_opts))
1280
+ extract_thin_linkage(_sent, _opts, linkage);
1281
+ else
1282
+ extract_fat_linkage(_sent, _opts, linkage);
1283
+
1284
+ linkage_set_current_sublinkage(linkage, 0);
1285
+ return linkage;
1286
+ }
1287
+
1288
+ void SATEncoder::generate_linkage_prohibiting()
1289
+ {
1290
+ vec<Lit> clause;
1291
+ const std::vector<int>& link_variables = _variables->link_variables();
1292
+ for (std::vector<int>::const_iterator i = link_variables.begin(); i != link_variables.end(); i++) {
1293
+ int var = *i;
1294
+ if (_solver->model[var] == l_True) {
1295
+ clause.push(~Lit(var));
1296
+ } else if (_solver->model[var] == l_False) {
1297
+ clause.push(Lit(var));
1298
+ }
1299
+ }
1300
+ _solver->addConflictingClause(clause);
1301
+ }
1302
+
1303
+ Linkage SATEncoder::get_next_linkage()
1304
+ {
1305
+ if (l_False == _solver->solve()) return NULL;
1306
+ Linkage linkage = create_linkage();
1307
+
1308
+ std::vector<int> components;
1309
+ bool connected = connectivity_components(components);
1310
+ if (connected) {
1311
+ // num_connected_linkages++;
1312
+
1313
+ if (post_process_linkage(linkage)) {
1314
+ cout << "Linkage PP OK" << endl;
1315
+ _sent->num_valid_linkages++;
1316
+ } else {
1317
+ cout << "Linkage PP NOT OK" << endl;
1318
+ }
1319
+
1320
+ generate_linkage_prohibiting();
1321
+ } else {
1322
+ cout << "Linkage DISCONNECTED" << endl;
1323
+ generate_disconnectivity_prohibiting(components);
1324
+ }
1325
+
1326
+ _solver->printStats();
1327
+ return linkage;
1328
+ }
1329
+
1330
+ /*******************************************************************************
1331
+ * SAT encoding for sentences that do not contain conjunction. *
1332
+ *******************************************************************************/
1333
+
1334
+ void SATEncoderConjunctionFreeSentences::generate_encoding_specific_clauses() {
1335
+ }
1336
+
1337
+ void SATEncoderConjunctionFreeSentences::handle_null_expression(int w) {
1338
+ // Formula is unsatisfiable
1339
+ vec<Lit> clause;
1340
+ add_clause(clause);
1341
+ }
1342
+
1343
+ void SATEncoderConjunctionFreeSentences::determine_satisfaction(int w, char* name) {
1344
+ // All tags must be satisfied
1345
+ generate_literal(Lit(_variables->string(name)));
1346
+ }
1347
+
1348
+ void SATEncoderConjunctionFreeSentences::generate_satisfaction_for_connector(int wi, int pi, const char* Ci,
1349
+ char dir, bool multi, int cost, char* var) {
1350
+ Lit lhs = Lit(_variables->string_cost(var, cost));
1351
+
1352
+ #ifdef _DEBUG
1353
+ cout << "*** Connector: ." << wi << ". ." << pi << ". " << Ci << dir << endl;
1354
+ #endif
1355
+
1356
+ // words that can potentially match (wi, pi)
1357
+ int low = (dir == '-') ? 0 : wi + 1;
1358
+ int hi = (dir == '-') ? wi : _sent->length;
1359
+
1360
+ std::vector<int> _w_;
1361
+ for (int wj = low; wj < hi; wj++) {
1362
+ // Eliminate words that cannot be connected to (wi, pi)
1363
+ if (!_word_tags[wj].match_possible(wi, pi))
1364
+ continue;
1365
+
1366
+ // Now we know that there is a potential link between the
1367
+ // connector (wi, pi) and the word wj
1368
+ _w_.push_back(wj);
1369
+
1370
+ generate_link_cw_ordinary_definition(wi, pi, Ci, dir, cost, wj);
1371
+ }
1372
+
1373
+ vec<Lit> _link_cw_;
1374
+ for (int i = 0; i < _w_.size(); i++)
1375
+ _link_cw_.push(Lit(_variables->link_cw(_w_[i], wi, pi, Ci)));
1376
+ generate_or_definition(lhs, _link_cw_);
1377
+
1378
+ DEBUG_print("--------- multi");
1379
+ if (!multi) {
1380
+ generate_xor_conditions(_link_cw_);
1381
+ }
1382
+ DEBUG_print("--------- end multi");
1383
+
1384
+ #ifdef _DEBUG
1385
+ cout << "*** End Connector: ." << wi << ". ." << pi << ". " << Ci << endl;
1386
+ #endif
1387
+ }
1388
+
1389
+ void SATEncoderConjunctionFreeSentences::generate_linked_definitions() {
1390
+ _linked_possible.resize(_sent->length, 1);
1391
+
1392
+ DEBUG_print("------- linked definitions");
1393
+ for (int w1 = 0; w1 < _sent->length; w1++) {
1394
+ for (int w2 = w1 + 1; w2 < _sent->length; w2++) {
1395
+ DEBUG_print("---------- ." << w1 << ". ." << w2 << ".");
1396
+ Lit lhs = Lit(_variables->linked(w1, w2));
1397
+
1398
+ vec<Lit> rhs;
1399
+ const std::vector<PositionConnector>& w1_connectors = _word_tags[w1].get_right_connectors();
1400
+ std::vector<PositionConnector>::const_iterator c;
1401
+ for (c = w1_connectors.begin(); c != w1_connectors.end(); c++) {
1402
+ assert(c->word == w1, "Connector word must match");
1403
+ if (_word_tags[w2].match_possible(c->word, c->position)) {
1404
+ rhs.push(Lit(_variables->link_cw(w2, c->word, c->position, c->connector->string)));
1405
+ }
1406
+ }
1407
+
1408
+ _linked_possible.set(w1, w2, rhs.size() > 0);
1409
+ generate_or_definition(lhs, rhs);
1410
+ }
1411
+ }
1412
+ DEBUG_print("------- end linked definitions");
1413
+ }
1414
+
1415
+ void SATEncoder::generate_linked_min_max_planarity() {
1416
+ DEBUG_print("---- linked_max");
1417
+ for (int w1 = 0; w1 < _sent->length; w1++) {
1418
+ for (int w2 = 0; w2 < _sent->length; w2++) {
1419
+ Lit lhs = Lit(_variables->linked_max(w1, w2));
1420
+ vec<Lit> rhs;
1421
+ if (w2 < _sent->length - 1) {
1422
+ rhs.push(Lit(_variables->linked_max(w1, w2 + 1)));
1423
+ if (w1 != w2 + 1 && _linked_possible(std::min(w1, w2+1), std::max(w1, w2+1)))
1424
+ rhs.push(~Lit(_variables->linked(std::min(w1, w2+1), std::max(w1, w2+1))));
1425
+ }
1426
+ generate_classical_and_definition(lhs, rhs);
1427
+ }
1428
+ }
1429
+ DEBUG_print("---- end linked_max");
1430
+
1431
+
1432
+ DEBUG_print("---- linked_min");
1433
+ for (int w1 = 0; w1 < _sent->length; w1++) {
1434
+ for (int w2 = 0; w2 < _sent->length; w2++) {
1435
+ Lit lhs = Lit(_variables->linked_min(w1, w2));
1436
+ vec<Lit> rhs;
1437
+ if (w2 > 0) {
1438
+ rhs.push(Lit(_variables->linked_min(w1, w2 - 1)));
1439
+ if (w1 != w2-1 && _linked_possible(std::min(w1, w2 - 1), std::max(w1, w2 - 1)))
1440
+ rhs.push(~Lit(_variables->linked(std::min(w1, w2 - 1), std::max(w1, w2 - 1))));
1441
+ }
1442
+ generate_classical_and_definition(lhs, rhs);
1443
+ }
1444
+ }
1445
+ DEBUG_print("---- end linked_min");
1446
+
1447
+
1448
+ vec<Lit> clause;
1449
+ for (int wi = 3; wi < _sent->length; wi++) {
1450
+ for (int wj = 1; wj < wi - 1; wj++) {
1451
+ for (int wl = wj + 1; wl < wi; wl++) {
1452
+ clause.growTo(3);
1453
+ clause[0] = ~Lit(_variables->linked_min(wi, wj));
1454
+ clause[1] = ~Lit(_variables->linked_max(wi, wl - 1));
1455
+ clause[2] = Lit(_variables->linked_min(wl, wj));
1456
+ add_clause(clause);
1457
+ }
1458
+ }
1459
+ }
1460
+
1461
+ DEBUG_print("------------");
1462
+
1463
+ for (int wi = 0; wi < _sent->length - 1; wi++) {
1464
+ for (int wj = wi + 1; wj < _sent->length - 1; wj++) {
1465
+ for (int wl = wi+1; wl < wj; wl++) {
1466
+ clause.growTo(3);
1467
+ clause[0] = ~Lit(_variables->linked_max(wi, wj));
1468
+ clause[1] = ~Lit(_variables->linked_min(wi, wl + 1));
1469
+ clause[2] = Lit(_variables->linked_max(wl, wj));
1470
+ add_clause(clause);
1471
+ }
1472
+ }
1473
+ }
1474
+
1475
+ DEBUG_print("------------");
1476
+ clause.clear();
1477
+ for (int wi = 1; wi < _sent->length; wi++) {
1478
+ for (int wj = wi + 2; wj < _sent->length - 1; wj++) {
1479
+ for (int wl = wi + 1; wl < wj; wl++) {
1480
+ clause.growTo(2);
1481
+ clause[0] = ~Lit(_variables->linked_min(wi, wj));
1482
+ clause[1] = Lit(_variables->linked_min(wl, wi));
1483
+ add_clause(clause);
1484
+
1485
+ clause.growTo(2);
1486
+ clause[0] = ~Lit(_variables->linked_max(wj, wi));
1487
+ clause[1] = Lit(_variables->linked_max(wl, wj));
1488
+ add_clause(clause);
1489
+ }
1490
+ }
1491
+ }
1492
+ }
1493
+
1494
+ bool SATEncoderConjunctionFreeSentences::extract_links(Parse_info pi)
1495
+ {
1496
+ int current_link = 0;
1497
+ const std::vector<int>& link_variables = _variables->link_variables();
1498
+ std::vector<int>::const_iterator i;
1499
+ for (i = link_variables.begin(); i != link_variables.end(); i++) {
1500
+ if (_solver->model[*i] != l_True)
1501
+ continue;
1502
+
1503
+ const Variables::LinkVar* var = _variables->link_variable(*i);
1504
+ if (_solver->model[_variables->linked(var->left_word, var->right_word)] != l_True)
1505
+ continue;
1506
+
1507
+ pi->link_array[current_link].l = var->left_word;
1508
+ pi->link_array[current_link].r = var->right_word;
1509
+ // pi->link_array[j].name = var->label;
1510
+
1511
+ Connector* connector;
1512
+
1513
+ connector = connector_new();
1514
+ connector->string = var->left_connector;
1515
+ pi->link_array[current_link].lc = connector;
1516
+
1517
+ connector = connector_new();
1518
+ connector->string = var->right_connector;
1519
+ pi->link_array[current_link].rc = connector;
1520
+
1521
+ current_link++;
1522
+ }
1523
+
1524
+ pi->N_links = current_link;
1525
+ DEBUG_print("Total: ." << pi->N_links << "." << endl);
1526
+ return false;
1527
+ }
1528
+
1529
+
1530
+ /*******************************************************************************
1531
+ * SAT encoding for sentences that contain conjunction. *
1532
+ *******************************************************************************/
1533
+
1534
+ // Check if a connector is andable
1535
+ static int is_andable(Sentence sent, Connector* c, char dir) {
1536
+ /* if no set, then everything is considered andable */
1537
+ if (sent->dict->andable_connector_set == NULL)
1538
+ return TRUE;
1539
+ return match_in_connector_set(sent, sent->dict->andable_connector_set, c, dir);
1540
+ }
1541
+
1542
+ void SATEncoderConjunctiveSentences::handle_null_expression(int w)
1543
+ {
1544
+ // Formula is unsatisfiable, but only if w is not a conjunctive
1545
+ // word. Conjunctive words can have empty tags, but then they must
1546
+ // have fat-links attached.
1547
+ if (!isConnectiveOrComma(w)) {
1548
+ vec<Lit> clause;
1549
+ add_clause(clause);
1550
+ } else {
1551
+ char str[MAX_VARIABLE_NAME];
1552
+ sprintf(str, "fl_d_%d", w);
1553
+ generate_literal(Lit(_variables->string(str)));
1554
+ sprintf(str, "w%d", w);
1555
+ generate_literal(~Lit(_variables->string(str)));
1556
+ }
1557
+ }
1558
+
1559
+ void SATEncoderConjunctiveSentences::determine_satisfaction(int w, char* name) {
1560
+ if (!parse_options_get_use_fat_links(_opts) ||
1561
+ !isConnectiveOrComma(w)) {
1562
+ // Non-conjunctive words must have their tags satisfied
1563
+ generate_literal(Lit(_variables->string(name)));
1564
+ } else {
1565
+ // Tags of conjunctive words are satisfied iff they are not fat-linked
1566
+ either_tag_or_fat_link(w, Lit(_variables->string(name)));
1567
+ }
1568
+ }
1569
+
1570
+
1571
+ void SATEncoderConjunctiveSentences::generate_satisfaction_for_connector(int wi, int pi, const char* Ci,
1572
+ char dir, bool multi, int cost, char* var) {
1573
+ Lit lhs = Lit(_variables->string_cost(var, cost));
1574
+
1575
+ #ifdef _DEBUG
1576
+ cout << "*** Connector: ." << wi << ". ." << pi << ". " << Ci << dir << endl;
1577
+ #endif
1578
+ // words that can potentially match (wi, pi)
1579
+ int low = (dir == '-') ? 0 : wi + 1;
1580
+ int hi = (dir == '-') ? wi : _sent->length;
1581
+
1582
+ // determine if opposite of (wi, pi) is andable
1583
+ Connector conn;
1584
+ init_connector(&conn);
1585
+ conn.label = NORMAL_LABEL;
1586
+ conn.priority = THIN_priority;
1587
+ conn.string = Ci;
1588
+ bool andable_opposite = is_andable(_sent, &conn, dir == '+' ? '-' : '+');
1589
+
1590
+ std::vector<int> _w_;
1591
+ for (int wj = low; wj < hi; wj++) {
1592
+ // Eliminate words that cannot be connected to (wi, pi)
1593
+ if (!link_cw_possible(wi, pi, Ci, dir, wj, 1, _sent->length-1))
1594
+ continue;
1595
+
1596
+ // Now we know that there is a potential link between the
1597
+ // connector (wi, pi) and the word w
1598
+ _w_.push_back(wj);
1599
+
1600
+ // link_cw down definitions as ordinary words
1601
+ if (_word_tags[wj].match_possible(wi, pi) || isConnectiveOrComma(wj)) {
1602
+ generate_link_cw_ordinary_definition(wi, pi, Ci, dir, cost, wj);
1603
+ }
1604
+
1605
+ // link_cw down definitions as special words
1606
+ if (isConnectiveOrComma(wj)) {
1607
+ if (!link_cw_possible_with_fld(wi, pi, Ci, dir, wj, 1, _sent->length-1)) {
1608
+ generate_link_cw_connective_impossible(wi, pi, Ci, wj);
1609
+ } else {
1610
+ generate_link_cw_connective_definition(wi, pi, Ci, wj);
1611
+ }
1612
+ }
1613
+
1614
+ // ------------------------------------------------------------------------
1615
+
1616
+ // link_top_cw up defintions
1617
+ if (andable_opposite) {
1618
+ // connections can be either directly established or inherited from above
1619
+ generate_link_top_cw_up_definition(wj, wi, pi, Ci, multi);
1620
+ } else {
1621
+ // connection is established iff it is directly established
1622
+ // i.e., it cannot be inherited from above
1623
+ generate_link_top_cw_iff_link_cw(wj, wi, pi, Ci);
1624
+ }
1625
+
1626
+ // Commas cannot be directly connected if they have fat links down
1627
+ if (parse_options_get_use_fat_links(_opts) &&
1628
+ isComma(_sent, wj)) {
1629
+ vec<Lit> clause;
1630
+ char str[MAX_VARIABLE_NAME];
1631
+ sprintf(str,"fl_d_%d", wj);
1632
+ clause.push(~Lit(_variables->string(str)));
1633
+ clause.push(~Lit(_variables->link_top_cw(wj, wi, pi, Ci)));
1634
+ add_clause(clause);
1635
+ }
1636
+ }
1637
+
1638
+ vec<Lit> _link_cw_;
1639
+ for (int i = 0; i < _w_.size(); i++)
1640
+ _link_cw_.push(Lit(_variables->link_cw(_w_[i], wi, pi, Ci)));
1641
+ generate_or_definition(lhs, _link_cw_);
1642
+
1643
+ vec<Lit> _link_top_cw_;
1644
+ for (int i = 0; i < _w_.size(); i++)
1645
+ _link_top_cw_.push(Lit(_variables->link_top_cw(_w_[i], wi, pi, Ci)));
1646
+ // Faster
1647
+ generate_or_definition(lhs, _link_top_cw_);
1648
+
1649
+ DEBUG_print("--------- multi");
1650
+ if (!multi) {
1651
+ generate_xor_conditions(_link_top_cw_);
1652
+ }
1653
+ DEBUG_print("--------- end multi");
1654
+
1655
+ #ifdef _DEBUG
1656
+ cout << "*** End Connector: ." << wi << ". ." << pi << ". " << Ci << endl;
1657
+ #endif
1658
+ }
1659
+
1660
+ void SATEncoderConjunctiveSentences::add_additional_power_pruning_conditions(vec<Lit>& clause, int wl, int wr) {
1661
+ char str[MAX_VARIABLE_NAME];
1662
+ sprintf(str, "fl_ur_%d", wl);
1663
+ clause.push(Lit(_variables->string(str)));
1664
+ sprintf(str, "fl_ul_%d", wl);
1665
+ clause.push(Lit(_variables->string(str)));
1666
+ sprintf(str, "fl_ul_%d", wr);
1667
+ clause.push(Lit(_variables->string(str)));
1668
+ sprintf(str, "fl_ur_%d", wr);
1669
+ clause.push(Lit(_variables->string(str)));
1670
+ }
1671
+
1672
+ void SATEncoderConjunctiveSentences::generate_encoding_specific_clauses() {
1673
+ generate_label_compatibility();
1674
+ generate_fat_link_existence();
1675
+ generate_fat_link_up_definitions();
1676
+ generate_fat_link_down_definitions();
1677
+ generate_fat_link_up_between_down_conditions();
1678
+ generate_fat_link_comma_conditions();
1679
+ generate_fat_link_crossover_conditions();
1680
+ generate_fat_link_Left_Wall_not_inside();
1681
+ generate_fat_link_linked_upperside();
1682
+ generate_fat_link_neighbor();
1683
+ }
1684
+
1685
+ void SATEncoderConjunctiveSentences::init_connective_words() {
1686
+ for (int i = 0; i < _sent->length; i++) {
1687
+ if (::isConnectiveOrComma(_sent, i)) {
1688
+ _connectives.push_back(i);
1689
+ _is_connective_or_comma.push_back(true);
1690
+ } else {
1691
+ _is_connective_or_comma.push_back(false);
1692
+ }
1693
+ }
1694
+
1695
+
1696
+ }
1697
+
1698
+ /* If there is a direct link between a connective word wi and a
1699
+ connector (w,p), then there is an indirect link between wi and (w, p).
1700
+ */
1701
+ void SATEncoderConjunctiveSentences::generate_link_top_cw_iff_link_cw(int wi, int wj, int pj, const char* Cj) {
1702
+ DEBUG_print("--------- link_top_cw iff link_cw");
1703
+ vec<Lit> clause;
1704
+
1705
+ clause.growTo(2);
1706
+ clause[0] = ~Lit(_variables->link_cw(wi, wj, pj, Cj));
1707
+ clause[1] = Lit(_variables->link_top_cw(wi, wj, pj, Cj));
1708
+ add_clause(clause);
1709
+
1710
+ clause.growTo(2);
1711
+ clause[0] = ~Lit(_variables->link_top_cw(wi, wj, pj, Cj));
1712
+ clause[1] = Lit(_variables->link_cw(wi, wj, pj, Cj));
1713
+ add_clause(clause);
1714
+
1715
+ DEBUG_print("--------- end link_top_cw iff link_cw");
1716
+ }
1717
+
1718
+
1719
+
1720
+ void SATEncoderConjunctiveSentences::generate_link_top_cw_up_definition(int wj, int wi, int pi, const char* Ci, bool multi) {
1721
+ DEBUG_print("--------- link_top_cw definition");
1722
+ Lit link_cw_wj = Lit(_variables->link_cw(wj, wi, pi, Ci));
1723
+ Lit link_top_cw_wj = Lit(_variables->link_top_cw(wj, wi, pi, Ci));
1724
+ char dir = wi < wj ? '+' : '-';
1725
+
1726
+ vec<Lit> clause;
1727
+
1728
+ clause.growTo(2);
1729
+ clause[0] = ~link_top_cw_wj;
1730
+ clause[1] = link_cw_wj;
1731
+ add_clause(clause);
1732
+
1733
+
1734
+ // Collect connectors up
1735
+ std::vector<int> Wk;
1736
+ for (int k = 0; k < _connectives.size(); k++) {
1737
+ int wk = _connectives[k];
1738
+ if (wk != wj && (wj - wi)*(wk - wi) > 0 &&
1739
+ link_cw_possible_with_fld(wi, pi, Ci, dir, wk, 1, _sent->length - 1))
1740
+ Wk.push_back(wk);
1741
+ }
1742
+
1743
+
1744
+ for (int k = 0; k < Wk.size(); k++) {
1745
+ int wk = Wk[k];
1746
+ clause.growTo(4);
1747
+ clause[0] = link_top_cw_wj;
1748
+ clause[1] = ~link_cw_wj;
1749
+ clause[2] = ~Lit(_variables->fat_link(wj, wk));
1750
+ clause[3] = Lit(_variables->link_cw(wk, wi, pi, Ci));
1751
+ add_clause(clause);
1752
+ }
1753
+
1754
+ clause.clear();
1755
+ for (int k = 0; k < Wk.size(); k++) {
1756
+ int wk = Wk[k];
1757
+ clause.growTo(3);
1758
+ clause[0] = ~link_top_cw_wj;
1759
+ clause[1] = ~Lit(_variables->fat_link(wj, wk));
1760
+ clause[2] = ~Lit(_variables->link_cw(wk, wi, pi, Ci));
1761
+ add_clause(clause);
1762
+ }
1763
+
1764
+
1765
+ clause.clear();
1766
+ clause.push(~link_cw_wj);
1767
+ clause.push(link_top_cw_wj);
1768
+ for (int k = 0; k < Wk.size(); k++) {
1769
+ int wk = Wk[k];
1770
+ clause.push(Lit(_variables->fat_link(wj, wk)));
1771
+ }
1772
+ add_clause(clause);
1773
+
1774
+
1775
+ if (clause.size() == 2)
1776
+ return;
1777
+
1778
+ // Faster
1779
+ clause.clear();
1780
+ clause.push(~link_cw_wj);
1781
+ clause.push(link_top_cw_wj);
1782
+ for (int k = 0; k < Wk.size(); k++) {
1783
+ int wk = Wk[k];
1784
+ clause.push(Lit(_variables->link_cw(wk, wi, pi, Ci)));
1785
+ }
1786
+ add_clause(clause);
1787
+
1788
+
1789
+ if (multi) {
1790
+ // cannot directly link to both ends of the fat link
1791
+ clause.clear();
1792
+ for (int k = 0; k < Wk.size(); k++) {
1793
+ int wk = Wk[k];
1794
+ clause.growTo(3);
1795
+ clause[0] = ~Lit(_variables->fat_link(wj, wk));
1796
+ clause[1] = ~Lit(_variables->link_top_cw(wj, wi, pi, Ci));
1797
+ clause[2] = ~Lit(_variables->link_top_cw(wk, wi, pi, Ci));
1798
+ add_clause(clause);
1799
+ }
1800
+ }
1801
+
1802
+ DEBUG_print("--------- end link_top_cw definition");
1803
+ }
1804
+
1805
+ /* If there is an indirect link from a connective word or a comma wi to a
1806
+ connector (wj, pj), then, there exist two words wk1 and wk2, such that:
1807
+ (1)
1808
+ (a) wk1 is between wi and wj
1809
+ (b) there is a fat-link between wk1 and wi
1810
+ (c) there is an indirect link between wk1 and (wj, pj)
1811
+ (2)
1812
+ (a) wi is between wk2 and wj
1813
+ (b) there is a fat-link between wk2 and wi
1814
+ (c) there is an indirect link between wk2 and (wj, pj)
1815
+ */
1816
+ void SATEncoderConjunctiveSentences::generate_link_cw_connective_definition(int wj, int pj, const char* Cj, int wi) {
1817
+ DEBUG_print("--------- link_cw as special");
1818
+
1819
+ char str[MAX_VARIABLE_NAME];
1820
+ sprintf(str, "fl_d_%d", wi);
1821
+ Lit not_wi_fld = ~Lit(_variables->string(str));
1822
+
1823
+ char link_cw_k1_str[MAX_VARIABLE_NAME];
1824
+ sprintf(link_cw_k1_str, "%d_%d_%d__1", wj, pj, wi);
1825
+ Lit link_cw_k1(_variables->string(link_cw_k1_str));
1826
+
1827
+ char link_cw_k2_str[MAX_VARIABLE_NAME];
1828
+ sprintf(link_cw_k2_str, "%d_%d_%d__2", wj, pj, wi);
1829
+ Lit link_cw_k2(_variables->string(link_cw_k2_str));
1830
+
1831
+ Lit not_link_wi_wjpj = ~Lit(_variables->link_cw(wi, wj, pj, Cj));
1832
+
1833
+ char dir = wj < wi ? '+' : '-';
1834
+
1835
+ vec<Lit> clause;
1836
+ clause.growTo(3);
1837
+ clause[0] = not_wi_fld;
1838
+ clause[1] = not_link_wi_wjpj;
1839
+ clause[2] = link_cw_k1;
1840
+ add_clause(clause);
1841
+
1842
+ clause.growTo(3);
1843
+ clause[0] = not_wi_fld;
1844
+ clause[1] = not_link_wi_wjpj;
1845
+ clause[2] = link_cw_k2;
1846
+ add_clause(clause);
1847
+
1848
+ clause.growTo(3);
1849
+ clause[0] = ~link_cw_k1;
1850
+ clause[1] = ~link_cw_k2;
1851
+ clause[2] = ~not_link_wi_wjpj;
1852
+ add_clause(clause);
1853
+
1854
+ clause.clear();
1855
+
1856
+ // B(wi, w, wj)
1857
+ int wl, wr;
1858
+ if (wi < wj) {
1859
+ wl = wi + 1;
1860
+ wr = wj;
1861
+ } else {
1862
+ wl = wj + 1;
1863
+ wr = wi;
1864
+ }
1865
+
1866
+ std::vector<bool> link_cw_possible_cache(wr - wl);
1867
+
1868
+ for (int wk1 = wl; wk1 < wr; wk1++) {
1869
+ if (!(link_cw_possible_cache[wk1 - wl] = link_cw_possible(wj, pj, Cj, dir, wk1, wl, wr)))
1870
+ continue;
1871
+
1872
+ clause.growTo(3);
1873
+ clause[0] = ~link_cw_k1;
1874
+ clause[1] = ~Lit(_variables->fat_link(wk1, wi));
1875
+ clause[2] = Lit(_variables->link_cw(wk1, wj, pj, Cj));
1876
+ add_clause(clause);
1877
+ }
1878
+
1879
+ clause.clear();
1880
+ clause.push(~link_cw_k1);
1881
+ for (int wk1 = wl; wk1 < wr; wk1++) {
1882
+ if (!link_cw_possible_cache[wk1 - wl])
1883
+ continue;
1884
+
1885
+ clause.push(Lit(_variables->fat_link(wk1, wi)));
1886
+ }
1887
+ add_clause(clause);
1888
+
1889
+ // Faster
1890
+ clause.clear();
1891
+ clause.push(~link_cw_k1);
1892
+ for (int wk1 = wl; wk1 < wr; wk1++) {
1893
+ if (!link_cw_possible_cache[wk1 - wl])
1894
+ continue;
1895
+
1896
+ clause.push(Lit(_variables->link_cw(wk1, wj, pj, Cj)));
1897
+ }
1898
+ add_clause(clause);
1899
+
1900
+
1901
+ clause.clear();
1902
+ for (int wk1 = wl; wk1 < wr; wk1++) {
1903
+ if (!link_cw_possible_cache[wk1 - wl])
1904
+ continue;
1905
+ clause.growTo(3);
1906
+ clause[0] = ~Lit(_variables->fat_link(wk1, wi));
1907
+ clause[1] = ~Lit(_variables->link_cw(wk1, wj, pj, Cj));
1908
+ clause[2] = link_cw_k1;
1909
+ add_clause(clause);
1910
+ }
1911
+
1912
+ DEBUG_print("---");
1913
+
1914
+ // B(wk2, wi, wj)
1915
+ if (wi < wj) {
1916
+ wl = 1;
1917
+ wr = wi;
1918
+ } else {
1919
+ wl = wi + 1;
1920
+ wr = _sent->length - 1;
1921
+ }
1922
+ link_cw_possible_cache.resize(wr - wl);
1923
+
1924
+ clause.clear();
1925
+ for (int wk2 = wl; wk2 < wr; wk2++) {
1926
+ if (!(link_cw_possible_cache[wk2 - wl] = link_cw_possible(wj, pj, Cj, dir, wk2, wl, wr)))
1927
+ continue;
1928
+
1929
+ clause.growTo(3);
1930
+ clause[0] = ~link_cw_k2;
1931
+ clause[1] = ~Lit(_variables->fat_link(wk2, wi));
1932
+ clause[2] = Lit(_variables->link_cw(wk2, wj, pj, Cj));
1933
+ add_clause(clause);
1934
+ }
1935
+
1936
+ clause.clear();
1937
+ clause.push(~link_cw_k2);
1938
+ for (int wk2 = wl; wk2 < wr; wk2++) {
1939
+ if (!link_cw_possible_cache[wk2 - wl])
1940
+ continue;
1941
+
1942
+ clause.push(Lit(_variables->fat_link(wk2, wi)));
1943
+ }
1944
+ add_clause(clause);
1945
+
1946
+ // Faster
1947
+ clause.clear();
1948
+ clause.push(~link_cw_k2);
1949
+ for (int wk2 = wl; wk2 < wr; wk2++) {
1950
+ if (!link_cw_possible_cache[wk2 - wl])
1951
+ continue;
1952
+
1953
+ clause.push(Lit(_variables->link_cw(wk2, wj, pj, Cj)));
1954
+ }
1955
+ add_clause(clause);
1956
+
1957
+ clause.clear();
1958
+ for (int wk2 = wl; wk2 < wr; wk2++) {
1959
+ if (!link_cw_possible_cache[wk2 - wl])
1960
+ continue;
1961
+ clause.growTo(3);
1962
+ clause[0] = ~Lit(_variables->fat_link(wk2, wi));
1963
+ clause[1] = ~Lit(_variables->link_cw(wk2, wj, pj, Cj));
1964
+ clause[2] = link_cw_k2;
1965
+ add_clause(clause);
1966
+ }
1967
+
1968
+ DEBUG_print("--------- end link_cw as special");
1969
+ }
1970
+
1971
+ void SATEncoderConjunctiveSentences::generate_link_cw_connective_impossible(int wi, int pi, const char* Ci, int wj) {
1972
+ DEBUG_print("--------- link_cw as special down - impossible");
1973
+ // If the connective word w has fat-links down it cannot be
1974
+ // connected to (wi, pi)
1975
+ vec<Lit> clause;
1976
+ char str[MAX_VARIABLE_NAME];
1977
+ sprintf(str,"fl_d_%d", wj);
1978
+ clause.push(~Lit(_variables->string(str)));
1979
+ clause.push(~Lit(_variables->link_cw(wj, wi, pi, Ci)));
1980
+ add_clause(clause);
1981
+ DEBUG_print("--------- end link_cw as special down - impossible");
1982
+ }
1983
+
1984
+
1985
+ void SATEncoderConjunctiveSentences::generate_fat_link_up_definitions() {
1986
+ Lit lhs;
1987
+ vec<Lit> rhs;
1988
+ char fl_str[MAX_VARIABLE_NAME];
1989
+ vec<Lit> clause;
1990
+
1991
+ for (int w = 1; w < _sent->length - 1; w++) {
1992
+ DEBUG_print("----fat_link up definition");
1993
+ // Fatlink up left definition
1994
+ rhs.clear();
1995
+ for (std::vector<int>::const_iterator cl = _connectives.begin(); cl != _connectives.end(); cl++) {
1996
+ if (*cl < w)
1997
+ rhs.push(Lit(_variables->fat_link(w, *cl)));
1998
+ }
1999
+ sprintf(fl_str, "fl_ul_%d", w);
2000
+ lhs = Lit(_variables->string(fl_str));
2001
+ generate_or_definition(lhs, rhs);
2002
+ generate_xor_conditions(rhs);
2003
+
2004
+ // Fatlink up right definition
2005
+ rhs.clear();
2006
+ for (std::vector<int>::const_iterator cr = _connectives.begin(); cr != _connectives.end(); cr++) {
2007
+ if (*cr > w)
2008
+ rhs.push(Lit(_variables->fat_link(w, *cr)));
2009
+ }
2010
+ sprintf(fl_str, "fl_ur_%d", w);
2011
+ lhs = Lit(_variables->string(fl_str));
2012
+ generate_or_definition(lhs, rhs);
2013
+ generate_xor_conditions(rhs);
2014
+
2015
+ // There can not be two links up
2016
+ clause.growTo(2);
2017
+ sprintf(fl_str, "fl_ul_%d", w);
2018
+ clause[0] = ~Lit(_variables->string(fl_str));
2019
+ sprintf(fl_str, "fl_ur_%d", w);
2020
+ clause[1] = ~Lit(_variables->string(fl_str));
2021
+ add_clause(clause);
2022
+
2023
+
2024
+ DEBUG_print("----end fat_link up definition");
2025
+ }
2026
+ }
2027
+
2028
+
2029
+ void SATEncoderConjunctiveSentences::generate_fat_link_down_definitions() {
2030
+ // Fat links down
2031
+ char fl_str[MAX_VARIABLE_NAME];
2032
+ std::vector<int>::const_iterator w;
2033
+ for (w = _connectives.begin(); w != _connectives.end(); w++) {
2034
+ DEBUG_print("----fat_link down definition");
2035
+ // Fatlink down left definition
2036
+ vec<Lit> rhs;
2037
+ for (int wl = 1; wl < *w; wl++) {
2038
+ rhs.push(Lit(_variables->fat_link(wl, *w)));
2039
+ }
2040
+ sprintf(fl_str, "fl_d_%d", *w);
2041
+ Lit lhs = Lit(_variables->string(fl_str));
2042
+ generate_or_definition(lhs, rhs);
2043
+ generate_xor_conditions(rhs);
2044
+
2045
+ // Fatlink down right definition
2046
+ rhs.clear();
2047
+ for (int wr = *w + 1; wr < _sent->length - 1; wr++) {
2048
+ rhs.push(Lit(_variables->fat_link(wr, *w)));
2049
+ }
2050
+ sprintf(fl_str, "fl_d_%d", *w);
2051
+ lhs = Lit(_variables->string(fl_str));
2052
+ generate_or_definition(lhs, rhs);
2053
+ generate_xor_conditions(rhs);
2054
+ DEBUG_print("----end fat_link down definition");
2055
+ }
2056
+ }
2057
+
2058
+ void SATEncoderConjunctiveSentences::generate_fat_link_comma_conditions() {
2059
+ char fl_str[MAX_VARIABLE_NAME];
2060
+ std::vector<int>::const_iterator w;
2061
+ vec<Lit> clause;
2062
+ for (w = _connectives.begin(); w != _connectives.end(); w++) {
2063
+ if (isComma(_sent, *w)) {
2064
+ DEBUG_print("---comma---");
2065
+
2066
+ // If comma has a link down it has to have a link up to the right
2067
+ sprintf(fl_str, "fl_d_%d", *w);
2068
+ clause.growTo(2);
2069
+ clause[0] = ~Lit(_variables->string(fl_str));
2070
+ sprintf(fl_str, "fl_ur_%d", *w);
2071
+ clause[1] = Lit(_variables->string(fl_str));
2072
+ add_clause(clause);
2073
+
2074
+
2075
+ // If comma has a link down it cannot have a link up to the left
2076
+ sprintf(fl_str, "fl_d_%d", *w);
2077
+ clause.growTo(2);
2078
+ clause[0] = ~Lit(_variables->string(fl_str));
2079
+ sprintf(fl_str, "fl_ul_%d", *w);
2080
+ clause[1] = ~Lit(_variables->string(fl_str));
2081
+ add_clause(clause);
2082
+
2083
+ DEBUG_print("---end comma---");
2084
+ }
2085
+ }
2086
+ }
2087
+
2088
+
2089
+ void SATEncoderConjunctiveSentences::generate_fat_link_crossover_conditions() {
2090
+ vec<Lit> clause;
2091
+ // If a word has a fat link up, than it cannot establish links with words behind that connective
2092
+ for (int w = 1; w < _sent->length - 1; w++) {
2093
+ DEBUG_print("----links cannot crossover the fat-links");
2094
+ std::vector<int>::const_iterator c1, c2;
2095
+ for (c1 = _connectives.begin(); c1 != _connectives.end(); c1++) {
2096
+ if (*c1 > w) {
2097
+ for (int w1 = *c1 + 1; w1 < _sent->length; w1++) {
2098
+ if (!_linked_possible(w, w1))
2099
+ continue;
2100
+
2101
+ clause.growTo(3);
2102
+ clause[0] = ~Lit(_variables->fat_link(w, *c1));
2103
+ clause[1] = Lit(_variables->link_top_ww(*c1, w1));
2104
+ clause[2] = ~Lit(_variables->link_top_ww(w, w1));
2105
+ add_clause(clause);
2106
+ }
2107
+ }
2108
+
2109
+ if (*c1 < w) {
2110
+ for (int w1 = 0; w1 < *c1; w1++) {
2111
+ if (!_linked_possible(w1, w))
2112
+ continue;
2113
+
2114
+ clause.growTo(3);
2115
+ clause[0] = ~Lit(_variables->fat_link(w, *c1));
2116
+ clause[1] = Lit(_variables->link_top_ww(*c1, w1));
2117
+ clause[2] = ~Lit(_variables->link_top_ww(w, w1));
2118
+ add_clause(clause);
2119
+ }
2120
+ }
2121
+ }
2122
+ DEBUG_print("----end links cannot cross over the fat-links");
2123
+ }
2124
+
2125
+
2126
+ // One step structure violation pruning heuristic If a word is
2127
+ // directly linked to a fat linked word, than it cannot establish
2128
+ // links with words behind that connective
2129
+ std::vector<int>::const_iterator c;
2130
+ for (c = _connectives.begin(); c != _connectives.end(); c++) {
2131
+ DEBUG_print("----links cannot crossover the fat-links heuristic");
2132
+ for (int w = 1; w < *c; w++) {
2133
+ for (int w1 = 0; w1 < w; w1++) {
2134
+ if (!_linked_possible(w1, w))
2135
+ continue;
2136
+ for (int w2 = *c; w2 < _sent->length; w2++) {
2137
+ if (!_linked_possible(w1, w2))
2138
+ continue;
2139
+
2140
+
2141
+ vec<Lit> clause;
2142
+ clause.push(~Lit(_variables->fat_link(w, *c)));
2143
+ clause.push(~Lit(_variables->linked(w1, w)));
2144
+ clause.push(~Lit(_variables->linked(w1, w2)));
2145
+ add_clause(clause);
2146
+ }
2147
+ }
2148
+ }
2149
+ for (int w = *c + 1; w < _sent->length - 1; w++) {
2150
+ for (int w1 = w+1; w1 < _sent->length; w1++) {
2151
+ if (!_linked_possible(w, w1))
2152
+ continue;
2153
+ for (int w2 = 0; w2 <= *c; w2++) {
2154
+ if (!_linked_possible(w2, w1))
2155
+ continue;
2156
+
2157
+ vec<Lit> clause;
2158
+ clause.push(~Lit(_variables->fat_link(w, *c)));
2159
+ clause.push(~Lit(_variables->linked(w, w1)));
2160
+ clause.push(~Lit(_variables->linked(w2, w1)));
2161
+ add_clause(clause);
2162
+ }
2163
+ }
2164
+ }
2165
+ DEBUG_print("----end links cannot cross over the fat-links heuristic");
2166
+ }
2167
+
2168
+ }
2169
+
2170
+ void SATEncoderConjunctiveSentences::generate_fat_link_up_between_down_conditions() {
2171
+ // If a connective wi has a fat-link down to wj, it cannot have
2172
+ // links up between wi and wj.
2173
+ vec<Lit> clause;
2174
+ for (std::vector<int>::const_iterator wi = _connectives.begin(); wi != _connectives.end(); wi++) {
2175
+ DEBUG_print("---up between down---");
2176
+ for (int wj = 1; wj < _sent->length - 1; wj++) {
2177
+ if (*wi == wj)
2178
+ continue;
2179
+ int l = std::min(*wi, wj) + 1;
2180
+ int r = std::max(*wi, wj);
2181
+
2182
+ for (int wk = l; wk < r; wk++) {
2183
+ int mi = std::min(*wi, wk);
2184
+ int ma = std::max(*wi, wk);
2185
+ if (!_linked_possible(mi, ma))
2186
+ continue;
2187
+
2188
+ clause.growTo(2);
2189
+ clause[0] = ~Lit(_variables->fat_link(wj, *wi));
2190
+ clause[1] = ~Lit(_variables->linked(mi, ma));
2191
+ add_clause(clause);
2192
+ }
2193
+
2194
+ if (isConnectiveOrComma(wj)) {
2195
+ clause.growTo(2);
2196
+ clause[0] = ~Lit(_variables->fat_link(wj, *wi));
2197
+ clause[1] = ~Lit(_variables->fat_link(*wi, wj));
2198
+ add_clause(clause);
2199
+ }
2200
+
2201
+
2202
+ }
2203
+ DEBUG_print("---end up between down---");
2204
+ }
2205
+ }
2206
+
2207
+ void SATEncoderConjunctiveSentences::generate_fat_link_neighbor() {
2208
+ // Search guiding heuristic: one fat-link is usually just next to the word
2209
+ Lit lhs;
2210
+ vec<Lit> rhs;
2211
+ char fl_str[MAX_VARIABLE_NAME];
2212
+ std::vector<int>::const_iterator w;
2213
+ for (w = _connectives.begin(); w != _connectives.end(); w++) {
2214
+ DEBUG_print("----fat-link-neighbor");
2215
+ if (*w > 1 && *w < _sent->length - 1) {
2216
+ rhs.clear();
2217
+ rhs.push(Lit(_variables->fat_link(*w - 1, *w)));
2218
+ rhs.push(Lit(_variables->fat_link(*w + 1, *w)));
2219
+ lhs = Lit(_variables->neighbor_fat_link(*w));
2220
+ sprintf(fl_str, "fl_d_%d", *w);
2221
+ Lit fld = Lit(_variables->string(fl_str));
2222
+ generate_conditional_or_definition(fld, lhs, rhs);
2223
+ }
2224
+ DEBUG_print("----end fat-link-neighbor");
2225
+ }
2226
+ }
2227
+
2228
+ void SATEncoderConjunctiveSentences::generate_label_compatibility() {
2229
+ // Eliminate non-matching indirect links
2230
+ DEBUG_print("----label compatibility");
2231
+ vec<Lit> clause;
2232
+ const std::vector<int>& vars = _variables->link_variables();
2233
+ std::vector<int>::const_iterator i, j;
2234
+ for (i = vars.begin(); i != vars.end(); i++) {
2235
+ const Variables::LinkVar* vari = _variables->link_variable(*i);
2236
+
2237
+ const std::vector<int>& varsjr = _variables->link_variables(vari->right_word, vari->right_position);
2238
+ for (j = varsjr.begin(); j != varsjr.end(); j++) {
2239
+ const Variables::LinkVar* varj = _variables->link_variable(*j);
2240
+ if (!labels_match(vari->label, varj->label)) {
2241
+ clause.growTo(2);
2242
+ clause[0] = ~Lit(*i);
2243
+ clause[1] = ~Lit(*j);
2244
+ add_clause(clause);
2245
+ }
2246
+ }
2247
+
2248
+ const std::vector<int>& varsjl = _variables->link_variables(vari->left_word, vari->left_position);
2249
+ for (j = varsjl.begin(); j != varsjl.end(); j++) {
2250
+ const Variables::LinkVar* varj = _variables->link_variable(*j);
2251
+ if (!labels_match(vari->label, varj->label)) {
2252
+ clause.growTo(2);
2253
+ clause[0] = ~Lit(*i);
2254
+ clause[1] = ~Lit(*j);
2255
+ add_clause(clause);
2256
+ }
2257
+ }
2258
+ }
2259
+ DEBUG_print("----label compatibility");
2260
+ }
2261
+
2262
+ void SATEncoderConjunctiveSentences::generate_fat_link_existence() {
2263
+ // If there is a fat link from wa to wb then there should be
2264
+ // at least one connector in the wa word tag that is indirectly
2265
+ // connected to words between:
2266
+ // if wa < wb: [0, wa) and [wb+2, n)
2267
+ // if wa > wb: [0, wb-1) and [wa+1, n)
2268
+ DEBUG_print("----fat-link-existence");
2269
+ vec<Lit> clause_a, clause_b;
2270
+ for (std::vector<int>::const_iterator wb = _connectives.begin(); wb != _connectives.end(); wb++) {
2271
+ for (int wa = 1; wa < _sent->length-1; wa++) {
2272
+ if (isConnectiveOrComma(wa))
2273
+ continue;
2274
+ if (wa == *wb)
2275
+ continue;
2276
+
2277
+ int up = (wa < *wb) ? wa : *wb - 1;
2278
+ int low = (wa < *wb) ? *wb + 2 : wa + 1;
2279
+
2280
+ clause_a.clear();
2281
+ clause_b.clear();
2282
+ clause_a.push(~Lit(_variables->fat_link(wa, *wb)));
2283
+ clause_b.push(~Lit(_variables->fat_link(wa, *wb)));
2284
+
2285
+ std::vector<PositionConnector>::const_iterator ci;
2286
+ char dir;
2287
+
2288
+ const std::vector<PositionConnector>& lconnectors = _word_tags[wa].get_left_connectors();
2289
+ for (ci = lconnectors.begin(); ci != lconnectors.end(); ci++) {
2290
+ const std::vector<PositionConnector*>& matches = ci->matches;
2291
+ std::vector<PositionConnector*>::const_iterator m;
2292
+ for (m = matches.begin(); m != matches.end(); m++) {
2293
+ if ((0 <= (*m)->word && (*m)->word < up) &&
2294
+ link_cw_possible_with_fld((*m)->word, (*m)->position, (*m)->connector->string,
2295
+ '+', *wb, 1, _sent->length - 1)) {
2296
+ clause_a.push(Lit(_variables->link_cw(wa, (*m)->word, (*m)->position, (*m)->connector->string)));
2297
+ clause_b.push(Lit(_variables->link_cw(*wb, (*m)->word, (*m)->position, (*m)->connector->string)));
2298
+ }
2299
+ }
2300
+ }
2301
+
2302
+ const std::vector<PositionConnector>& rconnectors = _word_tags[wa].get_right_connectors();
2303
+ for (ci = rconnectors.begin(); ci != rconnectors.end(); ci++) {
2304
+ const std::vector<PositionConnector*>& matches = ci->matches;
2305
+ std::vector<PositionConnector*>::const_iterator m;
2306
+ for (m = matches.begin(); m != matches.end(); m++) {
2307
+ if ((low <= (*m)->word && (*m)->word < _sent->length) &&
2308
+ link_cw_possible_with_fld((*m)->word, (*m)->position, (*m)->connector->string,
2309
+ '-', *wb, 1, _sent->length - 1)) {
2310
+ clause_a.push(Lit(_variables->link_cw(wa, (*m)->word, (*m)->position, (*m)->connector->string)));
2311
+ clause_b.push(Lit(_variables->link_cw(*wb, (*m)->word, (*m)->position, (*m)->connector->string)));
2312
+ }
2313
+ }
2314
+ }
2315
+
2316
+ add_clause(clause_a);
2317
+ add_clause(clause_b);
2318
+ }
2319
+ }
2320
+ DEBUG_print("----end fat-link-existence");
2321
+ }
2322
+
2323
+ void SATEncoderConjunctiveSentences::generate_fat_link_Left_Wall_not_inside() {
2324
+ // Wall cannot be connected just inside the fat-link tree
2325
+ for (int w = 1; w < _sent->length-1; w++) {
2326
+ DEBUG_print("---Left Wall cannot be connected inside");
2327
+ vec<Lit> clause;
2328
+ std::vector<int>::const_iterator c;
2329
+
2330
+ if (!_linked_possible(0, w))
2331
+ continue;
2332
+
2333
+ for (c = _connectives.begin(); c != _connectives.end(); c++) {
2334
+ if (w == *c)
2335
+ continue;
2336
+ if (!_linked_possible(0, *c))
2337
+ continue;
2338
+
2339
+ clause.growTo(3);
2340
+ clause[0] = ~Lit(_variables->linked(0, w));
2341
+ clause[1] = ~Lit(_variables->fat_link(w, *c));
2342
+ clause[2] = Lit(_variables->linked(0, *c));
2343
+ add_clause(clause);
2344
+ }
2345
+ DEBUG_print("---end Left Wall cannot be connected inside");
2346
+ }
2347
+ }
2348
+
2349
+ void SATEncoderConjunctiveSentences::generate_fat_link_linked_upperside() {
2350
+ // Fat link must be linked on the upper side
2351
+ DEBUG_print("--- Fat link must be linked on the upper side");
2352
+ vec<Lit> clause;
2353
+ std::vector<int>::const_iterator c;
2354
+ for (c = _connectives.begin(); c != _connectives.end(); c++) {
2355
+ if (isComma(_sent, *c))
2356
+ continue;
2357
+
2358
+ clause.clear();
2359
+ char fl_str[MAX_VARIABLE_NAME];
2360
+ sprintf(fl_str, "fl_d_%d", *c);
2361
+ clause.push(~Lit(_variables->string(fl_str)));
2362
+
2363
+ for (int wl = 0; wl < *c - 1; wl++) {
2364
+ if (_linked_possible(wl, *c)) {
2365
+ const std::vector<PositionConnector>& vc = _word_tags[wl].get_right_connectors();
2366
+ std::vector<PositionConnector>::const_iterator i;
2367
+ for (i = vc.begin(); i != vc.end(); i++) {
2368
+ if (link_cw_possible(wl, i->position, i->connector->string, '+', *c, 1, _sent->length - 1))
2369
+ clause.push(Lit(_variables->link_cw(*c, wl, (*i).position, (*i).connector->string)));
2370
+ }
2371
+ }
2372
+ }
2373
+ for (int wr = *c+2; wr < _sent->length; wr++) {
2374
+ if (_linked_possible(*c, wr)) {
2375
+ const std::vector<PositionConnector>& vc = _word_tags[wr].get_left_connectors();
2376
+ std::vector<PositionConnector>::const_iterator i;
2377
+ for (i = vc.begin(); i != vc.end(); i++) {
2378
+ if (link_cw_possible(wr, i->position, i->connector->string, '-', *c, 1, _sent->length - 1))
2379
+ clause.push(Lit(_variables->link_cw(*c, wr, (*i).position, (*i).connector->string)));
2380
+ }
2381
+ }
2382
+ }
2383
+
2384
+ std::vector<int>::const_iterator c1;
2385
+ for (c1 = _connectives.begin(); c1 != _connectives.end(); c1++) {
2386
+ if (c1 != c)
2387
+ clause.push(Lit(_variables->fat_link(*c, *c1)));
2388
+ }
2389
+ add_clause(clause);
2390
+ }
2391
+ DEBUG_print("---end Fat link must be connected on the upper side");
2392
+ }
2393
+
2394
+ void SATEncoderConjunctiveSentences::either_tag_or_fat_link(int w, Lit tag) {
2395
+ DEBUG_print("----either tag or fat_link");
2396
+ vec<Lit> clause;
2397
+ char fl_str[MAX_VARIABLE_NAME];
2398
+ sprintf(fl_str, "fl_d_%d", w);
2399
+
2400
+ // Either tag of the word is satisfied or there must be fat-link on
2401
+ // this word
2402
+ clause.growTo(2);
2403
+ clause[0] = tag;
2404
+ clause[1] = Lit(_variables->string(fl_str));
2405
+ add_clause(clause);
2406
+
2407
+ // There cannot be both fat-links and a satisfied tag
2408
+ clause.growTo(2);
2409
+ clause[0] = ~tag;
2410
+ clause[1] = ~Lit(_variables->string(fl_str));
2411
+ add_clause(clause);
2412
+
2413
+ DEBUG_print("----end either tag or fat_link");
2414
+ }
2415
+
2416
+ // Check if there can be a connection between the connector (wi, pi)
2417
+ // with the word w when the word w has fat links down
2418
+ bool SATEncoderConjunctiveSentences::link_cw_possible_with_fld(int wi, int pi, const char* Ci,
2419
+ char dir, int w, int llim, int rlim) {
2420
+ // Connective word can match iff the connector is andable and there
2421
+ // are words wk1 and wk2 such that B(wi, wk1, w) and B(wi, w, wk1)
2422
+ // and there are connectors on wk1 and wk2 that can match (wi, pi)
2423
+ Connector conn;
2424
+ init_connector(&conn);
2425
+ conn.label = NORMAL_LABEL;
2426
+ conn.priority = THIN_priority;
2427
+ conn.string = Ci;
2428
+ bool andable_opposite = is_andable(_sent, &conn, dir == '+' ? '-' : '+');
2429
+
2430
+ if (!andable_opposite) {
2431
+ return false;
2432
+ }
2433
+
2434
+ int low = wi < w ? std::max(llim, wi + 1) : llim;
2435
+ int hi = wi < w ? rlim : std::min(wi, rlim);
2436
+
2437
+ return matches_in_interval(wi, pi, low, w) && matches_in_interval(wi, pi, w + 1, hi);
2438
+ }
2439
+
2440
+ // Check if there can be a connection between the connector (wi, pi) with the word w
2441
+ bool SATEncoderConjunctiveSentences::link_cw_possible(int wi, int pi, const char* Ci, char dir, int w, int llim, int rlim) {
2442
+ if (!isConnectiveOrComma(w)) {
2443
+ // Ordinary word can match iff it has a connector that can match
2444
+ return _word_tags[w].match_possible(wi, pi);
2445
+ } else {
2446
+ // Connective word can match iff it can match as an ordinary word
2447
+ // or the connector is andable and there are words wk1 and wk2
2448
+ // such that B(wi, wk1, w) and B(wi, w, wk1) and there are
2449
+ // connectors on wk1 and wk2 that can match (wi, pi)
2450
+ return _word_tags[w].match_possible(wi, pi) ||
2451
+ link_cw_possible_with_fld(wi, pi, Ci, dir, w, llim, rlim);
2452
+ }
2453
+ }
2454
+
2455
+
2456
+
2457
+
2458
+ void SATEncoderConjunctiveSentences::generate_link_top_ww_connective_comma_definition(Lit lhs, int w1, int w2) {
2459
+ DEBUG_print("---- link_top_connective_comma");
2460
+
2461
+ vec<Lit> clause;
2462
+
2463
+ vec<Lit> fatlinks_left, fatlinks_right, link_top_left, link_top_right;
2464
+ int low = w1 < w2 ? 1 : w2+1;
2465
+ int hi = w1 < w2 ? w2 : _sent->length - 1;
2466
+ for (int w = low; w < w1; w++) {
2467
+ Lit fl(_variables->fat_link(w, w1));
2468
+ Lit tl(_variables->link_top_ww(w, w2));
2469
+
2470
+ clause.growTo(3);
2471
+ clause[0] = ~fl;
2472
+ clause[1] = ~lhs;
2473
+ clause[2] = tl;
2474
+ add_clause(clause);
2475
+
2476
+ fatlinks_left.push(fl);
2477
+ link_top_left.push(tl);
2478
+ }
2479
+
2480
+ DEBUG_print("---------");
2481
+
2482
+ for (int w = w1 + 1; w < hi; w++) {
2483
+ Lit fr(_variables->fat_link(w, w1));
2484
+ Lit tr(_variables->link_top_ww(w, w2));
2485
+
2486
+ clause.growTo(3);
2487
+ clause[0] = ~fr;
2488
+ clause[1] = ~lhs;
2489
+ clause[2] = tr;
2490
+ add_clause(clause);
2491
+
2492
+ fatlinks_right.push(fr);
2493
+ link_top_right.push(tr);
2494
+ }
2495
+
2496
+ clause.clear();
2497
+ for (int i = 0; i < fatlinks_left.size(); i++) {
2498
+ for (int j = 0; j < fatlinks_right.size(); j++) {
2499
+ clause.growTo(5);
2500
+ clause[0] = ~fatlinks_left[i];
2501
+ clause[1] = ~link_top_left[i];
2502
+ clause[2] = ~fatlinks_right[j];
2503
+ clause[3] = ~link_top_right[j];
2504
+ clause[4] = lhs;
2505
+ add_clause(clause);
2506
+ }
2507
+ }
2508
+
2509
+ DEBUG_print("---- end link_top_connective_comma");
2510
+ }
2511
+
2512
+
2513
+ void SATEncoderConjunctiveSentences::generate_linked_definitions() {
2514
+ Matrix<int> _thin_link_possible;
2515
+ _thin_link_possible.resize(_sent->length, 1);
2516
+
2517
+ DEBUG_print("------- link_top_ww definitions");
2518
+ for (int w1 = 0; w1 < _sent->length; w1++) {
2519
+ for (int w2 = 0; w2 < _sent->length; w2++) {
2520
+ if (w1 == w2)
2521
+ continue;
2522
+ DEBUG_print("---------- ." << w1 << ". ." << w2 << ".");
2523
+ Lit lhs;
2524
+ vec<Lit> rhs;
2525
+ const std::vector<PositionConnector>& w1_connectors =
2526
+ (w1 < w2) ? _word_tags[w1].get_right_connectors() : _word_tags[w1].get_left_connectors();
2527
+ std::vector<PositionConnector>::const_iterator c;
2528
+ for (c = w1_connectors.begin(); c != w1_connectors.end(); c++) {
2529
+ if (link_cw_possible(w1, c->position, c->connector->string, c->dir, w2, 1, _sent->length - 1)) {
2530
+ rhs.push(Lit(_variables->link_top_cw(w2, w1, c->position, c->connector->string)));
2531
+ }
2532
+ }
2533
+ lhs = Lit(_variables->link_top_ww(w1, w2));
2534
+
2535
+ if (!isConnectiveOrComma(w1) || abs(w1 - w2) == 1) {
2536
+ if (rhs.size() == 0)
2537
+ _thin_link_possible.set(w1, w2, 0);
2538
+
2539
+ generate_or_definition(lhs, rhs);
2540
+ } else {
2541
+ char w1_str[MAX_VARIABLE_NAME];
2542
+ sprintf(w1_str, "w%d", w1);
2543
+ generate_conditional_or_definition(Lit(_variables->string(w1_str)), lhs, rhs);
2544
+ generate_link_top_ww_connective_comma_definition(lhs, w1, w2);
2545
+ }
2546
+
2547
+ DEBUG_print("----------");
2548
+ }
2549
+ }
2550
+ DEBUG_print("------- end link_top_ww definitions");
2551
+
2552
+
2553
+ DEBUG_print("------- thin_link definitions");
2554
+ Lit lhs;
2555
+ vec<Lit> rhs;
2556
+ for (int w1 = 0; w1 < _sent->length - 1; w1++) {
2557
+ for (int w2 = w1 + 1; w2 < _sent->length; w2++) {
2558
+ rhs.clear();
2559
+ if (_thin_link_possible(w1, w2)) {
2560
+ lhs = Lit(_variables->thin_link(w1, w2));
2561
+ rhs.growTo(2);
2562
+ rhs[0] = Lit(_variables->link_top_ww(w1, w2));
2563
+ rhs[1] = Lit(_variables->link_top_ww(w2, w1));
2564
+ generate_classical_and_definition(lhs, rhs);
2565
+ }
2566
+ }
2567
+ }
2568
+ DEBUG_print("------- thin_linked definitions");
2569
+
2570
+
2571
+ DEBUG_print("------- linked definitions");
2572
+ _linked_possible.resize(_sent->length, 1);
2573
+ for (int w1 = 0; w1 < _sent->length - 1; w1++) {
2574
+ for (int w2 = w1 + 1; w2 < _sent->length; w2++) {
2575
+ rhs.clear();
2576
+ if (_thin_link_possible(w1, w2))
2577
+ rhs.push(Lit(_variables->thin_link(w1, w2)));
2578
+ if (isConnectiveOrComma(w1) && w2 < _sent->length - 1)
2579
+ rhs.push(Lit(_variables->fat_link(w2, w1)));
2580
+ if (isConnectiveOrComma(w2) && w1 > 0)
2581
+ rhs.push(Lit(_variables->fat_link(w1, w2)));
2582
+
2583
+ if (rhs.size() > 0) {
2584
+ lhs = Lit(_variables->linked(w1, w2));
2585
+ generate_or_definition(lhs, rhs);
2586
+ _linked_possible.set(w1, w2, 1);
2587
+ }
2588
+ else {
2589
+ _linked_possible.set(w1, w2, 0);
2590
+ }
2591
+ }
2592
+ }
2593
+ DEBUG_print("------- linked definitions");
2594
+
2595
+
2596
+ DEBUG_print("---Weak connectivity");
2597
+ for (int w1 = 0; w1 < _sent->length; w1++) {
2598
+ // At least one link should exist (weak connectivity)
2599
+ vec<Lit> clause;
2600
+ for (int w2 = 0; w2 < w1; w2++) {
2601
+ if (_linked_possible(w2, w1))
2602
+ clause.push(Lit(_variables->linked(w2, w1)));
2603
+ }
2604
+ for (int w2 = w1+1; w2 < _sent->length; w2++) {
2605
+ if (_linked_possible(w1, w2))
2606
+ clause.push(Lit(_variables->linked(w1, w2)));
2607
+ }
2608
+ add_clause(clause);
2609
+ }
2610
+ DEBUG_print("---end Weak connectivity");
2611
+
2612
+ }
2613
+
2614
+
2615
+ void SATEncoderConjunctiveSentences::get_satisfied_link_top_cw_connectors(int word, int top_word,
2616
+ std::vector<int>& link_top_cw_vars) {
2617
+ static int tab = 0;
2618
+
2619
+ // Check if top_word acts as an ordinary or as a special connective words
2620
+ char str[MAX_VARIABLE_NAME];
2621
+ sprintf(str, "w%d", top_word);
2622
+ bool ordinary = _solver->model[_variables->string(str)] == l_True;
2623
+
2624
+ if (ordinary) {
2625
+ const std::vector<int>& link_top_cw_variables = _variables->link_top_cw_variables();
2626
+ std::vector<int>::const_iterator i;
2627
+ for (i = link_top_cw_variables.begin(); i != link_top_cw_variables.end(); i++) {
2628
+ if (_solver->model[*i] != l_True)
2629
+ continue;
2630
+
2631
+ const Variables::LinkTopCWVar* var = _variables->link_top_cw_variable(*i);
2632
+ if (var->top_word != word || var->connector_word != top_word)
2633
+ continue;
2634
+
2635
+ link_top_cw_vars.push_back(*i);
2636
+ }
2637
+
2638
+ } else {
2639
+ // Find two words that are fat_linked up to the top word
2640
+ for (int w = 1; w < _sent->length - 1; w++) {
2641
+ if (w == top_word)
2642
+ continue;
2643
+ if (_solver->model[_variables->fat_link(w, top_word)] == l_True) {
2644
+ get_satisfied_link_top_cw_connectors(word, w, link_top_cw_vars);
2645
+ }
2646
+ }
2647
+ }
2648
+ }
2649
+
2650
+ bool SATEncoderConjunctiveSentences::extract_links(Parse_info pi)
2651
+ {
2652
+ int current_link = 0;
2653
+ bool fat = false;
2654
+
2655
+ const std::vector<int>& linked_variables = _variables->linked_variables();
2656
+ std::vector<int>::const_iterator i;
2657
+ for (i = linked_variables.begin(); i != linked_variables.end(); i++) {
2658
+ if (_solver->model[*i] != l_True)
2659
+ continue;
2660
+
2661
+ const Variables::LinkedVar* var = _variables->linked_variable(*i);
2662
+
2663
+ // Check if words are connected with a fat-link
2664
+ bool fl_lr = 0 < var->left_word && var->right_word < _sent->length - 1 &&
2665
+ parse_options_get_use_fat_links(_opts) &&
2666
+ isConnectiveOrComma(var->right_word) &&
2667
+ _solver->model[_variables->fat_link(var->left_word, var->right_word)] == l_True;
2668
+ bool fl_rl = 0 < var->left_word && var->right_word < _sent->length - 1 &&
2669
+ parse_options_get_use_fat_links(_opts) &&
2670
+ isConnectiveOrComma(var->left_word) &&
2671
+ _solver->model[_variables->fat_link(var->right_word, var->left_word)] == l_True;
2672
+ if (fl_lr || fl_rl) {
2673
+ // a fat link
2674
+ pi->link_array[current_link].l = var->left_word;
2675
+ pi->link_array[current_link].r = var->right_word;
2676
+
2677
+ Connector* connector;
2678
+
2679
+ connector = connector_new();
2680
+ connector->priority = fl_lr ? UP_priority : DOWN_priority;
2681
+ connector->string = "fat";
2682
+ pi->link_array[current_link].lc = connector;
2683
+
2684
+ connector = connector_new();
2685
+ connector->priority = fl_lr ? DOWN_priority : UP_priority;
2686
+ connector->string = "fat";
2687
+ pi->link_array[current_link].rc = connector;
2688
+
2689
+ current_link++;
2690
+ fat = true;
2691
+ } else {
2692
+ // a thin link
2693
+ std::vector<int> link_top_cw_vars_right;
2694
+ std::vector<int> link_top_cw_vars_left;
2695
+ get_satisfied_link_top_cw_connectors(var->left_word, var->right_word, link_top_cw_vars_left);
2696
+ get_satisfied_link_top_cw_connectors(var->right_word, var->left_word, link_top_cw_vars_right);
2697
+
2698
+ std::vector<const char*> strings_right;
2699
+ std::vector<int>::const_iterator rc, lc;
2700
+ for (rc = link_top_cw_vars_right.begin(); rc != link_top_cw_vars_right.end(); rc++) {
2701
+ const Variables::LinkTopCWVar* var = _variables->link_top_cw_variable(*rc);
2702
+ strings_right.push_back(var->connector);
2703
+ }
2704
+
2705
+ std::vector<const char*> strings_left;
2706
+ for (lc = link_top_cw_vars_left.begin(); lc != link_top_cw_vars_left.end(); lc++) {
2707
+ const Variables::LinkTopCWVar* var = _variables->link_top_cw_variable(*lc);
2708
+ strings_left.push_back(var->connector);
2709
+ }
2710
+
2711
+ // String unification
2712
+ std::vector<const char*>::const_iterator li, ri;
2713
+ const char* left_string = strings_left[0];
2714
+ for (li = strings_left.begin() + 1; li != strings_left.end(); li++) {
2715
+ left_string = intersect_strings(_sent, left_string, *li);
2716
+ }
2717
+
2718
+ const char* right_string = strings_right[0];
2719
+ for (ri = strings_right.begin() + 1; ri != strings_right.end(); ri++) {
2720
+ right_string = intersect_strings(_sent, right_string, *ri);
2721
+ }
2722
+
2723
+ pi->link_array[current_link].l = var->left_word;
2724
+ pi->link_array[current_link].r = var->right_word;
2725
+
2726
+ Connector* connector;
2727
+
2728
+ connector = connector_new();
2729
+ connector->string = right_string;
2730
+ pi->link_array[current_link].lc = connector;
2731
+
2732
+ connector = connector_new();
2733
+ connector->string = left_string;
2734
+ pi->link_array[current_link].rc = connector;
2735
+
2736
+ current_link++;
2737
+ }
2738
+ }
2739
+
2740
+ pi->N_links = current_link;
2741
+ return fat;
2742
+ }
2743
+
2744
+
2745
+ /****************************************************************************
2746
+ * Main entry point into the SAT parser *
2747
+ ****************************************************************************/
2748
+ extern "C" int sat_parse(Sentence sent, Parse_Options opts)
2749
+ {
2750
+ SATEncoder* encoder = (SATEncoder*) sent->hook;
2751
+ if (encoder) delete encoder;
2752
+
2753
+ // Prepare for parsing - extracted for "preparation.c"
2754
+ build_deletable(sent, 0);
2755
+ build_effective_dist(sent, 0);
2756
+ init_count(sent);
2757
+ count_set_effective_distance(sent);
2758
+
2759
+ bool conjunction = FALSE;
2760
+ if (parse_options_get_use_fat_links(opts)) {
2761
+ conjunction = sentence_contains_conjunction(sent);
2762
+ }
2763
+
2764
+ // Create the encoder, encode the formula and solve it
2765
+ if (conjunction) {
2766
+ DEBUG_print("Conjunctive sentence\n");
2767
+ encoder = new SATEncoderConjunctiveSentences(sent, opts);
2768
+ } else {
2769
+ DEBUG_print("Conjunction free sentence\n");
2770
+ encoder = new SATEncoderConjunctionFreeSentences(sent, opts);
2771
+ }
2772
+ sent->hook = encoder;
2773
+ encoder->encode();
2774
+
2775
+ // XXX this is wrong, we actually don't know yet ...
2776
+ // If we don't return some large number here, then the
2777
+ // Command-line client will fail to print all of the possible
2778
+ // linkages. Work around this by lying ...
2779
+ sent->num_valid_linkages = 222;
2780
+ sent->num_linkages_post_processed = 222;
2781
+
2782
+ return 0;
2783
+ }
2784
+
2785
+ extern "C" Linkage sat_create_linkage(int k, Sentence sent, Parse_Options opts)
2786
+ {
2787
+ SATEncoder* encoder = (SATEncoder*) sent->hook;
2788
+ if (!encoder) return NULL;
2789
+
2790
+ return encoder->get_next_linkage();
2791
+ }
2792
+
2793
+ extern "C" void sat_sentence_delete(Sentence sent)
2794
+ {
2795
+ SATEncoder* encoder = (SATEncoder*) sent->hook;
2796
+ if (!encoder) return;
2797
+ delete encoder;
2798
+
2799
+ // Don't do this parse-info-free stuff, if there's no encoder.
2800
+ // That's because it will screw up the regular parser.
2801
+ if (sent->parse_info) {
2802
+ Parse_info pi = sent->parse_info;
2803
+ for (int i=0; i< MAX_LINKS; i++) {
2804
+ free_connectors(pi->link_array[i].lc);
2805
+ free_connectors(pi->link_array[i].rc);
2806
+ }
2807
+ free_parse_info(sent->parse_info);
2808
+ sent->parse_info = NULL;
2809
+ }
2810
+
2811
+ }