/src/AnswerFinding/Answer.java

https://bitbucket.org/Schimodie/aiprojectqa · Java · 533 lines · 448 code · 85 blank · 0 comment · 113 complexity · 3c4aefbf050e23ec034d3d8d4be6aa89 MD5 · raw file

  1. package AnswerFinding;
  2. import InfoExtraction.Action;
  3. import InfoExtraction.InfoExtractionParser;
  4. import InfoExtraction.Place;
  5. import InfoExtraction.Relation;
  6. import QuestionParser.AnswerType;
  7. import QuestionParser.FocusType;
  8. import QuestionParser.Lemmatizer;
  9. import QuestionParser.MainKnowledge;
  10. import QuestionParser.Multiplicity;
  11. import QuestionParser.Question;
  12. import Situations.Situation;
  13. import java.util.ArrayList;
  14. public class Answer
  15. {
  16. private class Pair<T1, T2> {
  17. public T1 first;
  18. public T2 second;
  19. }
  20. private NovelInfo novelInfo;
  21. public Answer(NovelInfo ni) { this.novelInfo = ni; }
  22. public String answer(Question q) {
  23. AnswerType at = q.getAnswerType();
  24. ArrayList<String> dates = q.getDates();
  25. ArrayList<String> keywords = q.getKeywords();
  26. ArrayList<String> mo = q.getMainObjects();
  27. switch (at) {
  28. case DEFINITION: {
  29. if (q.containsFocusType(FocusType.NOVEL)) {
  30. return this.novelInfo.getSummary();
  31. }
  32. else if (q.containsFocusType(FocusType.RELATION)) {
  33. ArrayList<Relation> rels = this.novelInfo.getRelations();
  34. String e1;
  35. String e2;
  36. for (Relation rel : rels) {
  37. e1 = (String)rel.getEntity1();
  38. e2 = (String)rel.getEntity2();
  39. if (
  40. (this.getCharFullName(e1)
  41. .equals(this.getCharFullName(mo.get(0))) &&
  42. this.getCharFullName(e2)
  43. .equals(this.getCharFullName(mo.get(1)))) ||
  44. (this.getCharFullName(e1)
  45. .equals(this.getCharFullName(mo.get(1))) &&
  46. this.getCharFullName(e2)
  47. .equals(this.getCharFullName(mo.get(0))))
  48. ) {
  49. if (rel.getBond().split(" ").length == 1) {
  50. return
  51. this.toName(e1) + " is " +
  52. this.toName(e2) + "'s " +
  53. rel.getBond();
  54. }
  55. else {
  56. return rel.getBond();
  57. }
  58. }
  59. }
  60. }
  61. else if (q.containsFocusType(FocusType.PERSON)) {
  62. String chr = "";
  63. String data = "";
  64. for (String str : mo) {
  65. chr = this.getCharFullName(str);
  66. if ("".equals(chr)) {
  67. chr = this.toName(str);
  68. }
  69. data +=
  70. MainKnowledge.searchWiki(chr, null).trim() + "\n";
  71. }
  72. if ("".equals(chr)) {
  73. break;
  74. }
  75. return data.trim();
  76. }
  77. else if (q.containsFocusType(FocusType.OCCUPATION)) {
  78. int max = Integer.MIN_VALUE;
  79. QueryResult qr;
  80. QueryResult actQr = null;
  81. for (Action act : this.novelInfo.getActions()) {
  82. qr = act.query(q);
  83. if (qr.getScore() > max) {
  84. actQr = qr;
  85. max = qr.getScore();
  86. }
  87. }
  88. if (actQr == null) {
  89. break;
  90. }
  91. return actQr.getResult();
  92. }
  93. else {
  94. String chr = "";
  95. String data = "";
  96. for (String str : mo) {
  97. chr = this.getCharFullName(str);
  98. if ("".equals(chr)) {
  99. chr = this.toName(str);
  100. }
  101. data +=
  102. MainKnowledge.searchWiki(chr, null).trim() + "\n";
  103. }
  104. return data.trim();
  105. }
  106. break;
  107. }
  108. case EVENT: {
  109. int bIndex;
  110. int eIndex;
  111. String after;
  112. String before;
  113. String pattern = "[\\Q.,;:'?!\\E\"\\s]";
  114. String text;
  115. for (Action act : this.novelInfo.getActions()) {
  116. text = act.getText();
  117. for (String date : dates) {
  118. bIndex = text.indexOf(date.toLowerCase());
  119. if (bIndex > -1) {
  120. eIndex = bIndex + date.length() + 1;
  121. after = eIndex <= text.length()
  122. ? text.substring(eIndex -1 , eIndex)
  123. : "";
  124. before = bIndex > 0
  125. ? text.substring(bIndex - 1, bIndex)
  126. : "";
  127. if (
  128. ("".equals(before) || before.matches(pattern)) &&
  129. ("".equals(after) || after.matches(pattern))
  130. ) {
  131. return act.getText();
  132. }
  133. }
  134. }
  135. }
  136. break;
  137. }
  138. case LOCATION: {
  139. if (q.containsFocusType(FocusType.NOVEL)) {
  140. int index;
  141. int max;
  142. ArrayList<String> locs = new ArrayList<String>();
  143. ArrayList<Integer> freq = new ArrayList<Integer>();
  144. for (Action act : this.novelInfo.getActions()) {
  145. for (String loc : act.getPlaces()) {
  146. if (!locs.contains(loc)) {
  147. locs.add(loc);
  148. freq.add(0);
  149. }
  150. else {
  151. index = locs.indexOf(loc);
  152. freq.set(index, freq.get(index) + 1);
  153. break;
  154. }
  155. }
  156. }
  157. if (freq.isEmpty())
  158. break;
  159. index = 0;
  160. max = -1;
  161. for (int i = 0; i < freq.size(); ++i) {
  162. if (freq.get(i) > max) {
  163. max = freq.get(i);
  164. index = i;
  165. }
  166. }
  167. return this.toName(locs.get(index));
  168. }
  169. else {
  170. int max = Integer.MIN_VALUE;
  171. QueryResult actQr = null;
  172. QueryResult qr;
  173. QueryResult sitQr = null;
  174. String str;
  175. ArrayList<QueryResult> qrs = new ArrayList<QueryResult>();
  176. ArrayList<Place> places = this.novelInfo.getPlaces();
  177. ArrayList<String> strs =
  178. new ArrayList<String>(places.size());
  179. for (Place place : places) {
  180. strs.add(place.getName());
  181. }
  182. for (Action act : this.novelInfo.getActions()) {
  183. qr = act.query(q);
  184. if (qr.getScore() > max) {
  185. actQr = qr;
  186. max = qr.getScore();
  187. }
  188. }
  189. max = Integer.MIN_VALUE;
  190. for (Situation sit : this.novelInfo.getSituations()) {
  191. qrs = sit.query(q);
  192. for (QueryResult qr1 : qrs) {
  193. if (qr1.getScore() > max) {
  194. sitQr = qr1;
  195. max = qr1.getScore();
  196. }
  197. }
  198. }
  199. if (actQr == null) {
  200. if (sitQr != null) {
  201. str = this.findInString(strs, sitQr.getResult());
  202. if (!"".equals(str)) {
  203. return this.toName(str);
  204. }
  205. }
  206. }
  207. else if (
  208. sitQr == null ||
  209. actQr.getScore() >= sitQr.getScore()
  210. ) {
  211. Action act = (Action)actQr.getObject();
  212. if (act.getPlaces().length > 0) {
  213. str = act.getPlaces()[0];
  214. return this.toName(str);
  215. }
  216. else {
  217. str = this.findInString(strs, actQr.getResult());
  218. if (!"".equals(str)) {
  219. return this.toName(str);
  220. }
  221. }
  222. }
  223. else {
  224. str = this.findInString(strs, sitQr.getResult());
  225. if (!"".equals(str)) {
  226. return this.toName(str);
  227. }
  228. }
  229. }
  230. break;
  231. }
  232. case MODALITY: {
  233. if (q.containsFocusType(FocusType.NOVEL)) {
  234. if (this.contains(keywords, "begin")) {
  235. return this.novelInfo.getBeginningOfSummary();
  236. }
  237. else if (this.contains(keywords, "end")) {
  238. return this.novelInfo.getEndOfSummary();
  239. }
  240. }
  241. break;
  242. }
  243. case OTHER:
  244. break;
  245. case PERSON: {
  246. if (q.containsFocusType(FocusType.MAIN_CHARACTER)) {
  247. String str = "";
  248. switch (q.getMulitplicity()) {
  249. case SINGLE: {
  250. return
  251. this.toName (
  252. this.novelInfo.getCharacters().get(0)
  253. .getName()
  254. );
  255. }
  256. case MULTIPLE: {
  257. ArrayList<InfoExtraction.Character> chars =
  258. this.novelInfo.getCharacters();
  259. ArrayList<String> strChars =
  260. new ArrayList<String>(chars.size());
  261. for (InfoExtraction.Character chr : chars) {
  262. if (!chr.isMain())
  263. continue;
  264. strChars.add(this.toName(chr.getName()));
  265. }
  266. for (String string : strChars) {
  267. str +=
  268. string.replace("\r", "").replace("\n", "") +
  269. "\n";
  270. }
  271. return str.trim();
  272. }
  273. }
  274. }
  275. else {
  276. int max = Integer.MIN_VALUE;
  277. QueryResult actQr = null;
  278. QueryResult qr;
  279. QueryResult sitQr = null;
  280. String str;
  281. ArrayList<QueryResult> qrs = new ArrayList<QueryResult>();
  282. ArrayList<InfoExtraction.Character> chars =
  283. this.novelInfo.getCharacters();
  284. ArrayList<String> strs =
  285. new ArrayList<String>(chars.size());
  286. ArrayList<Relation> rels = this.novelInfo.getRelations();
  287. String e1;
  288. String e2;
  289. for (String chr : mo)
  290. {
  291. for (Relation rel : rels) {
  292. e1 = (String)rel.getEntity1();
  293. e2 = (String)rel.getEntity2();
  294. if (!"".equals(this.findInString (
  295. q.getVerbs(),
  296. rel.getBond()
  297. ))) {
  298. if (
  299. this.getCharFullName(e1)
  300. .equals(this.getCharFullName(chr))
  301. ) {
  302. return this.getCharFullName(e2);
  303. }
  304. else if (
  305. this.getCharFullName(e2)
  306. .equals(this.getCharFullName(chr))
  307. ) {
  308. return this.getCharFullName(e1);
  309. }
  310. }
  311. }
  312. }
  313. for (InfoExtraction.Character chr : chars) {
  314. for (String string : mo) {
  315. if (
  316. !this.getCharFullName(string)
  317. .equalsIgnoreCase(chr.getName())
  318. ) {
  319. strs.add(chr.getName());
  320. }
  321. }
  322. }
  323. for (Action act : this.novelInfo.getActions()) {
  324. qr = act.query(q);
  325. if (qr.getScore() > max) {
  326. actQr = qr;
  327. max = qr.getScore();
  328. }
  329. }
  330. max = Integer.MIN_VALUE;
  331. for (Situation sit : this.novelInfo.getSituations()) {
  332. qrs = sit.query(q);
  333. for (QueryResult qr1 : qrs) {
  334. if (qr1.getScore() > max) {
  335. sitQr = qr1;
  336. max = qr1.getScore();
  337. }
  338. }
  339. }
  340. if (actQr == null) {
  341. if (sitQr != null) {
  342. str = this.findInString(strs, sitQr.getResult());
  343. if (!"".equals(str)) {
  344. return this.toName(str);
  345. }
  346. }
  347. }
  348. else if (
  349. sitQr == null ||
  350. actQr.getScore() >= sitQr.getScore()
  351. ) {
  352. Action act = (Action)actQr.getObject();
  353. if (act.getCharacters().length > 0) {
  354. str = act.getCharacters()[0];
  355. return this.toName(str);
  356. }
  357. else {
  358. str = this.findInString(strs, actQr.getResult());
  359. if (!"".equals(str)) {
  360. return this.toName(str);
  361. }
  362. }
  363. }
  364. else {
  365. str = this.findInString(strs, sitQr.getResult());
  366. if (!"".equals(str)) {
  367. return this.toName(str);
  368. }
  369. }
  370. }
  371. break;
  372. }
  373. case TIME: {
  374. if (q.containsFocusType(FocusType.NOVEL)) {
  375. String pattern = "[1-2][0-9][0-9][0-9]";
  376. ArrayList<String> summaryDates =
  377. MainKnowledge.getDates(this.novelInfo.getSummary());
  378. for (String date : summaryDates) {
  379. for (int i = 0; i < date.length() - 3; ++i) {
  380. if (date.substring(i, i + 4).matches(pattern)) {
  381. return date;
  382. }
  383. }
  384. }
  385. }
  386. break;
  387. }
  388. }
  389. return "Answer not found!";
  390. }
  391. private String findInString(ArrayList<String> list, String str) {
  392. int bIndex;
  393. int eIndex;
  394. String after;
  395. String before;
  396. String pattern = "[\\Q.,;:'?!\\E\"\\s]";
  397. for (String item : list) {
  398. if ((bIndex = str.indexOf(item.toLowerCase())) != -1) {
  399. eIndex = bIndex + item.length() + 1;
  400. after = eIndex <= str.length()
  401. ? str.substring(eIndex -1 , eIndex)
  402. : "";
  403. before = bIndex > 0
  404. ? str.substring(bIndex - 1, bIndex)
  405. : "";
  406. if (
  407. ("".equals(before) || before.matches(pattern)) &&
  408. ("".equals(after) || after.matches(pattern))
  409. ) {
  410. return item;
  411. }
  412. }
  413. }
  414. return "";
  415. }
  416. private String toName(String str) {
  417. String aux = "";
  418. String[] strs = str.split(" ");
  419. if ("".equals(str)) {
  420. return "";
  421. }
  422. for (String string : strs) {
  423. if ("".equals(string)) {
  424. continue;
  425. }
  426. aux +=
  427. string.substring(0, 1).toUpperCase() +
  428. string.substring(1) + " ";
  429. }
  430. return aux.trim();
  431. }
  432. private String getCharFullName(String someName) {
  433. for (InfoExtraction.Character chr : this.novelInfo.getCharacters()) {
  434. if (this.toName(chr.getName()).contains(this.toName(someName))) {
  435. return this.toName(chr.getName());
  436. }
  437. }
  438. return "";
  439. }
  440. private boolean contains(ArrayList<String> words, String word) {
  441. for (String w : words) {
  442. if (w.equalsIgnoreCase(word)) {
  443. return true;
  444. }
  445. }
  446. return false;
  447. }
  448. }