grammar_cop 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
+ }