PageRenderTime 73ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/code/KinTermDef.java

http://silkin.googlecode.com/
Java | 1273 lines | 1065 code | 98 blank | 110 comment | 329 complexity | 9b5c66e96afc6a7b2e6954d0c15e3204 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. import javax.swing.JOptionPane;
  2. import java.util.* ;
  3. import java.io.*;
  4. public class KinTermDef implements Serializable, Comparable {
  5. Literal clauseHead; // by convention, this is: <kinTerm>(Alter, Ego)
  6. String kinTerm, eqcSigExact, eqcSigStruct, comments;
  7. Gloss gloss;
  8. ArrayList<Object> definitions, // an ArrayList<Object> of ClauseBodies
  9. expandedDefs, // an ArrayList<Object> of ClauseBodies containing only primitive predicates
  10. flags; // ArrayList<Object> of flags (strings) found between angle-brackets within the kinTerm string
  11. TreeMap exactEQCs, structEQCs; // the exact & structural EQCs to which this KTD's clauses belong
  12. Predicate headPred;
  13. DomainTheory domTh; // Ptr to the enclosing Domain Theory
  14. boolean composed = false;
  15. static String[] constraintSymbols = makeConstraintSymbols();
  16. // A list of all primitive predicates that are constraints
  17. static String[] makeConstraintSymbols() {
  18. String[] constraints = {"elder", "younger", "divorced", "dead", "gender",
  19. "contains", "lessThan", "greaterThan", "lessOrEql", "greaterOrEql"};
  20. Arrays.sort(constraints);
  21. return constraints;
  22. }
  23. static String[] standardMacros = {"brother", "children", "half_brother", "half_sister",
  24. "parents", "sibling", "siblings", "sister", "spice", "step_brother", "step_daughter",
  25. "step_father", "step_mother", "step_sister", "step_son" };
  26. static TreeMap<String, String> pcSymbolDecoder = makePCSymbolDecoder();
  27. // Key = a PCString symbol
  28. // Value = the gloss of the symbol.
  29. static TreeMap<String, String> makePCSymbolDecoder() {
  30. TreeMap<String, String> decoder = new TreeMap<String, String>();
  31. decoder.put("Fa", "father");
  32. decoder.put("Mo", "mother");
  33. decoder.put("Bro", "brother");
  34. decoder.put("Sis", "sister");
  35. decoder.put("P", "parent");
  36. decoder.put("C", "child");
  37. decoder.put("Hu", "husband");
  38. decoder.put("Wi", "wife");
  39. decoder.put("S", "spouse");
  40. decoder.put("So", "son");
  41. decoder.put("Da", "daughter");
  42. decoder.put("Sib", "sibling");
  43. decoder.put("Hbro", "half-brother");
  44. decoder.put("Hsis", "half-sister");
  45. decoder.put("Stbro", "step-brother");
  46. decoder.put("Stsis", "step-sister");
  47. decoder.put("Stfa", "stepfather");
  48. decoder.put("Stmo", "stepmother");
  49. decoder.put("Stso", "stepson");
  50. decoder.put("Stda", "stepdaughter");
  51. return decoder;
  52. }
  53. static void decoderTreeInsert(String key, String val0,
  54. TreeMap<String, ArrayList<String>> tree) {
  55. ArrayList<String> list = new ArrayList<String>();
  56. list.add(val0);
  57. tree.put(key, list);
  58. }
  59. static void decoderTreeAdd(String key, String[] vals,
  60. TreeMap<String, ArrayList<String>> tree) {
  61. for (String s : vals) {
  62. tree.get(key).add(s);
  63. }
  64. }
  65. /* This zero-arg constructor is for use ONLY by Serialization */
  66. KinTermDef() {
  67. definitions = new ArrayList<Object>();
  68. expandedDefs = new ArrayList<Object>();
  69. flags = new ArrayList<Object>();
  70. } // end of no-arg constructor
  71. KinTermDef(KinTermDef model) {
  72. definitions = new ArrayList<Object>(model.definitions);
  73. expandedDefs = new ArrayList<Object>(model.expandedDefs);
  74. flags = new ArrayList<Object>(model.flags);
  75. clauseHead = model.clauseHead;
  76. kinTerm = model.kinTerm;
  77. eqcSigExact = model.eqcSigExact;
  78. eqcSigStruct = model.eqcSigStruct;
  79. exactEQCs = model.exactEQCs;
  80. structEQCs = model.structEQCs;
  81. headPred = model.headPred;
  82. comments = model.comments;
  83. } // end of cloning constructor
  84. KinTermDef(String term) {
  85. kinTerm = term;
  86. headPred = new Predicate(term);
  87. headPred.category = new CulturalCategory();
  88. clauseHead = new Literal(headPred, new Variable("Alter"), new Variable("Ego"));
  89. definitions = new ArrayList<Object>();
  90. expandedDefs = new ArrayList<Object>();
  91. flags = makeFlags();
  92. } // end of 'convenience constructor' for making cultural terms
  93. KinTermDef(Literal lit) {
  94. kinTerm = lit.predicate.name;
  95. clauseHead = lit;
  96. definitions = new ArrayList<Object>();
  97. expandedDefs = new ArrayList<Object>();
  98. flags = makeFlags();
  99. } // end of constructor which can make any kind of kinterm,
  100. // based on the Category of the Predicate in the supplied Literal
  101. KinTermDef(Literal head, ClauseBody clause) {
  102. kinTerm = head.predicate.name;
  103. clauseHead = head;
  104. definitions = new ArrayList<Object>();
  105. definitions.add(clause);
  106. expandedDefs = new ArrayList<Object>();
  107. flags = makeFlags();
  108. } // end of constructor making a kinterm from existing Horn clause
  109. public KinTermDef deepCopy() {
  110. // Make an all-new version of this def, with new CBs, new Lits, everything.
  111. KinTermDef theCopy = new KinTermDef(kinTerm);
  112. theCopy.eqcSigExact = eqcSigExact;
  113. theCopy.eqcSigStruct = eqcSigStruct;
  114. theCopy.domTh = domTh;
  115. for (int i=0; i < definitions.size(); i++) {
  116. ClauseBody cb = (ClauseBody)definitions.get(i);
  117. theCopy.addClause(cb.deepCopy());
  118. }
  119. for (int i=0; i < expandedDefs.size(); i++) {
  120. ClauseBody cb = (ClauseBody)expandedDefs.get(i);
  121. theCopy.addExpClause(cb.deepCopy());
  122. }
  123. return theCopy;
  124. } // end of method deepCopy
  125. /** Provide a method of comparing 2 KTDs for use in TreeMaps and TreeSets.
  126. */
  127. public int compareTo(Object obj) throws ClassCastException {
  128. if (obj == null) return -1;
  129. KinTermDef other = (KinTermDef)obj;
  130. int answer = kinTerm.compareTo(other.kinTerm);
  131. if (answer != 0) return answer;
  132. return domTh.languageName.compareTo(other.domTh.languageName);
  133. } // end of compareTo method; required for the Comparable interface
  134. public boolean isEquivalent(KinTermDef otherDef, ArrayList<Object> refutation)
  135. throws KSParsingErrorException, JavaSystemException, KSInternalErrorException, FileNotFoundException,
  136. KSConstraintInconsistency, KSBadHornClauseException, KSNoChainOfRelations2Alter,
  137. ClassNotFoundException {
  138. // We know that otherDef is a complete, correct KTD: the 'right answer'
  139. Library.KTD_EQC eqc = new Library.KTD_EQC(eqcSigExact, this);
  140. boolean answer = eqc.canAssimilate(otherDef, refutation);
  141. if (! answer && refutation.isEmpty()) {
  142. // We know the problem is unequal sigStrings or unequal sizes of ExpDefs.
  143. // Almost certainly unequal sigStrings.
  144. // refutation = A pair = {(String)type, CB}
  145. if (! eqcSigExact.equals(otherDef.eqcSigExact)) {
  146. ArrayList<Object> thisList = decodeString(eqcSigExact),
  147. otherList = decodeString(otherDef.eqcSigExact);
  148. Iterator iter = thisList.iterator();
  149. while (iter.hasNext()) { // Subtract the set-intersection from each set of pcStrings
  150. String thisString = (String)iter.next();
  151. int where = otherList.indexOf(thisString);
  152. if (where > -1) {
  153. iter.remove();
  154. otherList.remove(where);
  155. }
  156. } // end of loop thru exact strings
  157. String refer = null;
  158. if (otherList.size() > 0) {
  159. int where = 0;
  160. refer = (String)otherList.get(where++);
  161. while (where < otherList.size() && refer.indexOf("*") > -1) // UDPs not allowed in refutation
  162. refer = (String)otherList.get(where++);
  163. if (refer.indexOf("*") == -1) for (int i=0; i < otherDef.expandedDefs.size(); i++) {
  164. ClauseBody cb = (ClauseBody)otherDef.expandedDefs.get(i);
  165. if (cb.pcString.equals(refer)) {
  166. refutation.add("missingCB");
  167. refutation.add(cb);
  168. i = otherDef.expandedDefs.size();
  169. }
  170. } // end of search for matching CB
  171. } // end of search in otherList
  172. if (refutation.isEmpty() && thisList.size() > 0) {
  173. int where = 0;
  174. refer = (String)thisList.get(where++);
  175. while (where < thisList.size() && refer.indexOf("*") > -1)
  176. refer = (String)thisList.get(where++);
  177. if (refer.indexOf("*") == -1) for (int i=0; i < expandedDefs.size(); i++) {
  178. ClauseBody cb = (ClauseBody)expandedDefs.get(i);
  179. if (cb.pcString.equals(refer)) {
  180. refutation.add("extraCB");
  181. refutation.add(cb);
  182. i = expandedDefs.size();
  183. }
  184. } // end of search for matching CB
  185. }
  186. if (refutation.size() > 0 || refer != null) // Refutations found, or exist but contain UDPs.
  187. return answer;
  188. else throw new KSInternalErrorException("KTD.isEquivalent failed to find refutation.");
  189. }
  190. /* else {
  191. System.out.println("\n***** NOTICE: 2 KTDs with identical kin Types are not equal.");
  192. System.out.print("\t" + domTh.languageName + ":" + kinTerm);
  193. System.out.println(" and " + otherDef.domTh.languageName + ":" + otherDef.kinTerm);
  194. System.out.println("\tboth have ExactString = " + eqcSigExact);
  195. }
  196. */ }
  197. return answer;
  198. } // end of method isEquivalent
  199. ArrayList<Object> decodeString(String sigString) {
  200. // An eqcSigExact is a concatenation of PCStrings separated by _'s
  201. // Un-concatenate them into an ArrayList<Object>
  202. ArrayList<Object> decoded = new ArrayList<Object>();
  203. if (sigString == null) return decoded;
  204. int start = 0, stop = sigString.indexOf("_");
  205. while (stop > -1) {
  206. decoded.add(sigString.substring(start, stop));
  207. start = stop + 1;
  208. stop = sigString.indexOf("_", start);
  209. } // end of loop thru all but last string
  210. decoded.add(sigString.substring(start));
  211. return decoded;
  212. } // end of method decodeString
  213. void addClause(ClauseBody clause) {
  214. definitions.add(clause);
  215. clause.seqNmbr = definitions.size() -1;
  216. clause.ktd = this;
  217. } // end of method addClause
  218. void addExpClause(ClauseBody clause) {
  219. expandedDefs.add(clause);
  220. clause.seqNmbr = expandedDefs.size() -1;
  221. clause.ktd = this;
  222. } // end of method addExpClause
  223. public ClauseBody findExpDef(String kinType) {
  224. ClauseBody expDef = null;
  225. return expDef;
  226. } // end of method findExpDef
  227. void addToEQCs(ClauseBody cb) { // Add cb to the 2 EQCs it belongs in.
  228. if (cb.pcString != null) {
  229. if (exactEQCs == null) exactEQCs = new TreeMap();
  230. if (exactEQCs.get(cb.pcString) == null)
  231. exactEQCs.put(cb.pcString, new ArrayList<Object>());
  232. ((ArrayList<Object>)exactEQCs.get(cb.pcString)).add(cb);
  233. }
  234. if (cb.pcStringStructural != null) {
  235. if (structEQCs == null) structEQCs = new TreeMap();
  236. if (structEQCs.get(cb.pcStringStructural) == null)
  237. structEQCs.put(cb.pcStringStructural, new ArrayList<Object>());
  238. ((ArrayList<Object>)structEQCs.get(cb.pcStringStructural)).add(cb);
  239. }
  240. } // end of method addToEQCs
  241. public void retrieveSigExact() {
  242. // To avoid a disk read, get signature from Library
  243. TreeMap termTree = (TreeMap) Library.predEncodings.get(domTh.languageName);
  244. Library.KTD_Coder coder = (Library.KTD_Coder) termTree.get(kinTerm);
  245. eqcSigExact = coder.exactSigStr;
  246. } // end of method retrieveSigExact
  247. public void computeEQCSigs() throws KSInternalErrorException {
  248. // Produce the sorted-concatenation of CB PC_Strings = the signature of this KTD
  249. Iterator iter = exactEQCs.keySet().iterator();
  250. if (!iter.hasNext() && eqcSigExact != null) {
  251. return; // Already computed for read-from-file KTD
  252. }
  253. if (!iter.hasNext()) {
  254. throw new KSInternalErrorException("KTD.computeEQCSigs finds no exactEQCs and no eqcSigExact.");
  255. }
  256. String signature = (String) iter.next();
  257. while (iter.hasNext()) {
  258. signature += "_" + (String) iter.next();
  259. }
  260. eqcSigExact = signature;
  261. iter = structEQCs.keySet().iterator();
  262. if (!iter.hasNext() && eqcSigStruct != null) {
  263. return;
  264. }
  265. signature = (String) iter.next();
  266. while (iter.hasNext()) {
  267. signature += "_" + (String) iter.next();
  268. }
  269. eqcSigStruct = signature;
  270. } // end of method computeEQCSigs
  271. public void makeSigStrings() throws KSInternalErrorException {
  272. exactEQCs = new TreeMap();
  273. structEQCs = new TreeMap(); // initialize EQC trees
  274. for (int j = 0; j < expandedDefs.size(); j++) {
  275. ClauseBody cb = (ClauseBody) expandedDefs.get(j);
  276. if (cb.pcStringStructural == null) {
  277. cb.pcStringStructural = ClauseBody.structStr(cb.pcString);
  278. }
  279. addToEQCs(cb);
  280. }
  281. computeEQCSigs();
  282. }
  283. public String toString() {
  284. int nmbrDefs = definitions.size();
  285. String allDefs = " :- ", expDefs, pad = " ", flagList = "";
  286. String ch = clauseHead.toString();
  287. for (int j=2; j < ch.length(); j++)
  288. pad += " ";
  289. for (int i = 0; i < nmbrDefs; i++) {
  290. allDefs += definitions.get(i).toString() + "\n";
  291. if (i < (nmbrDefs - 1))
  292. allDefs += pad + " | ";
  293. } // end of for-all-definitions
  294. nmbrDefs = expandedDefs.size();
  295. if (nmbrDefs > 0) {
  296. expDefs = "E x p a n d s t o : \n" + ch + " :- ";
  297. for (int i = 0; i < nmbrDefs; i++) {
  298. expDefs += expandedDefs.get(i).toString() + "\n";
  299. if (i < (nmbrDefs - 1)) {
  300. if (i < 9) expDefs += (i+1) + pad + " | ";
  301. else expDefs += (i+1) + pad + "| ";
  302. } // end of if-i<nmbrDefs-1
  303. } // end of for-all-expanded-definitions
  304. } // end of if-there-are-any-expandedDefs
  305. else expDefs = "";
  306. if (flags.size() > 0) {
  307. flagList = "Definition Flags: " + (String)flags.get(0);
  308. for (int i=1; i < flags.size(); i++)
  309. flagList += ", " + (String)flags.get(i);
  310. flagList += "\n";
  311. } // end of if-there-are-flags
  312. return ch + allDefs + flagList + expDefs;
  313. } // end of over-riding toString method
  314. public String toString(int limit) {
  315. int nmbrDefs = definitions.size();
  316. String allDefs = " :- ", expDefs, pad = " ", flagList = "";
  317. String ch = clauseHead.toString();
  318. for (int j=2; j < ch.length(); j++)
  319. pad += " ";
  320. for (int i = 0; i < nmbrDefs; i++) {
  321. allDefs += definitions.get(i).toString() + "\n";
  322. if (i < (nmbrDefs - 1))
  323. allDefs += pad + " | ";
  324. } // end of for-all-definitions
  325. if (allDefs.length() > limit)
  326. return ch + allDefs;
  327. int soFar = ch.length() + allDefs.length();
  328. nmbrDefs = expandedDefs.size();
  329. if (nmbrDefs > 0) {
  330. expDefs = "E x p a n d s t o : \n" + ch + " :- ";
  331. for (int i = 0; i < nmbrDefs; i++) {
  332. expDefs += expandedDefs.get(i).toString() + "\n";
  333. if (i < (nmbrDefs - 1)) {
  334. if (i < 9) expDefs += (i+1) + pad + " | ";
  335. else expDefs += (i+1) + pad + "| ";
  336. } // end of if-i<nmbrDefs-1
  337. if (soFar + expDefs.length() > limit)
  338. return ch + allDefs + expDefs + "\n\t...";
  339. } // end of for-all-expanded-definitions
  340. } // end of if-there-are-any-expandedDefs
  341. else expDefs = "";
  342. if (flags.size() > 0) {
  343. flagList = "Definition Flags: " + (String)flags.get(0);
  344. for (int i=1; i < flags.size(); i++)
  345. flagList += ", " + (String)flags.get(i);
  346. flagList += "\n";
  347. } // end of if-there-are-flags
  348. return ch + allDefs + flagList + expDefs;
  349. } // end of abreviated toString method
  350. public String toString(String type, boolean inclPrim, boolean inclExt) {
  351. if (! ((type.equals("original")) || (type.equals("expanded"))))
  352. return "ERROR: only valid type args are 'expanded' and 'original.'";
  353. String allDefs = " :- ", pad = " ", nxt;
  354. String ch = clauseHead.toString();
  355. for (int j=2; j < ch.length(); j++) pad += " ";
  356. int nmbrDefs, lastDef = 0, j=1;
  357. ArrayList<Object> chosen = new ArrayList<Object>();
  358. ClauseBody cb;
  359. if (type.equals("original")) {
  360. nmbrDefs = definitions.size();
  361. for (int i = 0; i < nmbrDefs; i++) {
  362. cb = (ClauseBody)definitions.get(i);
  363. if (((cb.flags.contains("ext")) && (inclExt))
  364. || ((! cb.flags.contains("ext")) && (inclPrim)))
  365. lastDef = i;
  366. }
  367. for (int i = 0; i < nmbrDefs; i++) {
  368. cb = (ClauseBody)definitions.get(i);
  369. if (((cb.flags.contains("ext")) && (inclExt))
  370. || ((! cb.flags.contains("ext")) && (inclPrim))) {
  371. allDefs += cb.toString() + "\n";
  372. if (i < lastDef)
  373. allDefs += pad + " | ";
  374. } // end of if-its-the-right-flavor
  375. } // end of for-all-definitions
  376. }else { // type must be "expanded"
  377. nmbrDefs = expandedDefs.size();
  378. if (nmbrDefs > 0) {
  379. ch = "";
  380. allDefs = "";
  381. for (int i = 0; i < nmbrDefs; i++) {
  382. cb = (ClauseBody)expandedDefs.get(i);
  383. if (((cb.flags.contains("ext")) && (inclExt))
  384. || ((! cb.flags.contains("ext")) && (inclPrim))) {
  385. nxt = String.valueOf(i);
  386. if (nxt.length() == 1) pad = " ";
  387. else pad = " ";
  388. allDefs += nxt + pad + cb.toString() + "\n";
  389. } // end of if-it's-the-right-flavor
  390. } // end of for-all-expanded-definitions
  391. } // end of if-there-are-any-expandedDefs
  392. } // end of else-expanded-defs-are-selected
  393. return ch + allDefs;
  394. } // end of toString method with a single string + 2 booleans
  395. public String toThyString() throws KSInternalErrorException {
  396. int nmbrDefs = definitions.size();
  397. String allDefs = " :- ", expDefs = "", pad = " ", flagList = "";
  398. String ch = clauseHead.toString();
  399. for (int j = 2; j < ch.length(); j++) {
  400. pad += " ";
  401. }
  402. for (int i = 0; i < nmbrDefs; i++) {
  403. allDefs += ((ClauseBody) definitions.get(i)).toThyString() + "\n";
  404. if (i < (nmbrDefs - 1)) {
  405. allDefs += pad + " | ";
  406. }
  407. } // end of for-all-definitions
  408. String eqcStr = (eqcSigExact == null ? "" : "{\"" + eqcSigExact + "\"}\n");
  409. if (comments != null && !comments.isEmpty()) {
  410. eqcStr += "\"" + comments + "\"\n";
  411. }
  412. nmbrDefs = expandedDefs.size();
  413. for (int i = 0; i < nmbrDefs; i++) {
  414. expDefs += ((ClauseBody) expandedDefs.get(i)).toThyString() + "\n";
  415. }
  416. return ch + allDefs + eqcStr + expDefs;
  417. } // end of toThyString method
  418. public String toXML(String bacer) {
  419. String spacer = "\t", dblSpacer = "\t\t";
  420. String s = bacer + "<kin-term-def>\n", langName = null;
  421. s += bacer + spacer + "<head>" + kinTerm + "</head>\n";
  422. if (definitions == null || definitions.isEmpty()) {
  423. try {
  424. langName = domTh.languageName;
  425. String fileName = Library.libraryDirectory + "Domain Theory Files/" + langName + ".thy";
  426. Parser parzer = new Parser(new Tokenizer(Library.getDFA(), new Linus(fileName)));
  427. KinTermDef ktdIn = parzer.parseKinTerm(kinTerm, false);
  428. definitions = ktdIn.definitions;
  429. } catch (Exception exc) {
  430. String msg = "<!-- Disk read error prevented finding definition.";
  431. msg += "\nKinTermDef = " + langName + ":" + kinTerm;
  432. msg += "\nReport this bug! -->";
  433. JOptionPane.showMessageDialog(null, msg, "Internal Error", JOptionPane.ERROR_MESSAGE);
  434. MainPane.activity.log.append(msg);
  435. System.err.println(msg);
  436. s += msg;
  437. }
  438. } // end of definitions-was-empty
  439. for (int i=0; i < definitions.size(); i++) {
  440. s += ((ClauseBody)definitions.get(i)).toXML(bacer + spacer);
  441. }
  442. s += bacer + "</kin-term-def>";
  443. return s;
  444. }
  445. public String toSILKString(String bacer, boolean writeDT) {
  446. String spacer = "\t", dblSpacer = "\t\t";
  447. String ktad = (Arrays.binarySearch(standardMacros, kinTerm) > -1 ?
  448. " non-term=\"yes\"" : "");
  449. String kt = (writeDT ? " term=\"" + kinTerm + "\"" : ktad);
  450. String s = bacer + "<kin-term-def" + kt + ">\n", langName = null;
  451. s += bacer + spacer + "<head>" + kinTerm + "</head>\n";
  452. if (eqcSigExact != null) {
  453. s += bacer + spacer + "<eqcSigExact>" + eqcSigExact + "</eqcSigExact>\n";
  454. }
  455. if (eqcSigStruct != null) {
  456. s += bacer + spacer + "<eqcSigStruct>" + eqcSigStruct + "</eqcSigStruct>\n";
  457. }
  458. if (gloss == null) {
  459. gloss = gloss();
  460. }
  461. if (gloss != null) {
  462. s += gloss.toSILKString(bacer + spacer);
  463. }
  464. if (comments != null && !comments.isEmpty()) {
  465. s += bacer + spacer + "<comments text=\"" + comments + "\"/>\n";
  466. }
  467. if (writeDT) {
  468. s += bacer + spacer + "<ktd-domain-theory>\n";
  469. s += bacer + dblSpacer + "<language name=\"" + domTh.languageName + "\"/>\n";
  470. if (domTh.polygamyOK) {
  471. s += bacer + dblSpacer + "<polygamyOK />\n";
  472. }
  473. if (domTh.author != null && domTh.author.length() > 0) {
  474. s += bacer + dblSpacer + "<author name=\"" + sanitize(domTh.author) + "\"/>\n";
  475. }
  476. s += bacer + dblSpacer + "<create-date value=\"" + domTh.createDate + "\"/>\n";
  477. if (domTh.citation != null && domTh.citation.length() > 0) {
  478. s += bacer + dblSpacer + "<citation txt=\"" + sanitize(domTh.citation) + "\"/>\n";
  479. }
  480. s += bacer + spacer + "</ktd-domain-theory>\n";
  481. }
  482. if (definitions == null || definitions.isEmpty()) {
  483. try {
  484. langName = domTh.languageName;
  485. String fileName = Library.libraryDirectory + "Domain Theory Files/" + langName + ".thy";
  486. Parser parzer = new Parser(new Tokenizer(Library.getDFA(), new Linus(fileName)));
  487. KinTermDef ktdIn = parzer.parseKinTerm(kinTerm, false);
  488. definitions = ktdIn.definitions;
  489. } catch (Exception exc) {
  490. String msg = "<!-- Disk read error prevented finding definition.";
  491. msg += "\nKinTermDef = " + langName + ":" + kinTerm;
  492. msg += "\nReport this bug! -->";
  493. JOptionPane.showMessageDialog(null, msg, "Internal Error", JOptionPane.ERROR_MESSAGE);
  494. MainPane.activity.log.append(msg);
  495. System.err.println(msg);
  496. s += msg;
  497. }
  498. } // end of definitions-was-empty
  499. if (!definitions.isEmpty()) {
  500. s += bacer + spacer + "<definitions>\n";
  501. for (int i = 0; i < definitions.size(); i++) {
  502. s += ((ClauseBody) definitions.get(i)).toSILKString(bacer + dblSpacer);
  503. }
  504. s += bacer + spacer + "</definitions>\n";
  505. }
  506. if (!expandedDefs.isEmpty()) {
  507. s += bacer + spacer + "<expandedDefs>\n";
  508. for (int i = 0; i < expandedDefs.size(); i++) {
  509. s += ((ClauseBody) expandedDefs.get(i)).toSILKString(bacer + dblSpacer);
  510. }
  511. s += bacer + spacer + "</expandedDefs>\n";
  512. }
  513. s += bacer + "</kin-term-def>";
  514. return s;
  515. }
  516. Gloss gloss() {
  517. if (!expandedDefs.isEmpty()) {
  518. ClauseBody sample = (ClauseBody)expandedDefs.get(0);
  519. if (sample.expansionPath != null && !sample.expansionPath.isEmpty()) {
  520. return smartGloss();
  521. }
  522. }
  523. return dumbGloss();
  524. }
  525. /** When a complete KinTermDef is available, for each base clause we generate:
  526. * - a simple gloss of the kin types _OR_
  527. * - a Horn Clause representation of the base clause with constraints
  528. * and cultural predicates PLUS glosses and footnotes for each cultural
  529. * predicate appearing.
  530. *
  531. * @return an English representation of the kin type or Horn clause plus glosses
  532. * of any cultural kin terms used in the definition.
  533. */Gloss smartGloss() {
  534. Gloss glos = new Gloss();
  535. ArrayList<String> cumCulturalPreds = new ArrayList<String>();
  536. for (int i=0; i < definitions.size(); i++) {
  537. ClauseBody cb = (ClauseBody) definitions.get(i);
  538. ArrayList<String> predicates = pluckPredicates(cb);
  539. ArrayList<String> culturalPreds = getCulturalPreds(predicates);
  540. ArrayList<String> pcStrings = getKinTypes(i);
  541. if (hasNoConstraints(predicates) && culturalPreds.isEmpty()) {
  542. for (String s : pcStrings) {
  543. glos.elements.add(glossify(s));
  544. }
  545. }else {
  546. glos.elements.add(cb.toSimpleHornClause());
  547. }
  548. for (String cPred : culturalPreds) { // union set of cPreds
  549. if (!cumCulturalPreds.contains(cPred)) {
  550. cumCulturalPreds.add(cPred);
  551. }
  552. }
  553. } // end of loop thru all base clauses
  554. if (!cumCulturalPreds.isEmpty()) {
  555. // cumCulturalPreds = alphabetize(cumCulturalPreds); // Parser.parseKinTerm reads file in order
  556. String langName = null;
  557. try {
  558. langName = domTh.languageName; // Library domTheory where def was found
  559. String fileName = Library.libraryDirectory + "Domain Theory Files/" + langName + ".thy";
  560. for (String cPred : cumCulturalPreds) {
  561. Parser parzer = new Parser(new Tokenizer(Library.getDFA(), new Linus(fileName)));
  562. KinTermDef culturalKTD = parzer.parseKinTerm(cPred, false);
  563. ArrayList pcStringList = decodeString(culturalKTD.eqcSigExact);
  564. for (Object o : pcStringList) {
  565. glos.addCulturalPred(cPred, glossify((String)o));
  566. }
  567. }
  568. glos.addCitation(domTh.citation);
  569. } catch (Exception exc) {
  570. String msg = "<!-- Disk read error prevented finding definition:\n" + exc;
  571. msg += "\nKinTermDef = " + langName + ":" + kinTerm;
  572. msg += "\nReport this bug! -->";
  573. JOptionPane.showMessageDialog(null, msg, "Internal Error", JOptionPane.ERROR_MESSAGE);
  574. MainPane.activity.log.append(msg);
  575. System.err.println(msg);
  576. glos.elements.add(msg);
  577. }
  578. } // end of optional 'WHERE' section defining cultural predicates used in def.
  579. return glos;
  580. }
  581. ArrayList<String> getCulturalPreds(ArrayList<String> predicates) {
  582. ArrayList<String> cPreds = new ArrayList<String>();
  583. for (String pred : predicates) {
  584. if (!DomainTheory.primitiveCodes.containsKey(pred)) {
  585. cPreds.add(pred);
  586. }
  587. }
  588. return cPreds;
  589. }
  590. ArrayList<String> alphabetize(ArrayList<String> input) {
  591. TreeMap<String, String> sorter = new TreeMap<String,String>();
  592. for (String s : input) {
  593. sorter.put(s,s);
  594. }
  595. return new ArrayList<String>(sorter.keySet());
  596. }
  597. ArrayList<String> getKinTypes(int seqNmbr) {
  598. ArrayList<String> result = new ArrayList<String>();
  599. for (int k=0; k < expandedDefs.size(); k++) {
  600. ClauseBody expDef = (ClauseBody)expandedDefs.get(k);
  601. String path = (String)expDef.expansionPath.get(0);
  602. int colon = path.indexOf(":");
  603. int baseCB = Integer.parseInt(path.substring(colon +1));
  604. if (baseCB == seqNmbr) {
  605. result.add(expDef.pcString);
  606. }
  607. }
  608. return result;
  609. }
  610. ArrayList<String> pluckPredicates(ClauseBody cb) {
  611. ArrayList<String> preds = new ArrayList<String>();
  612. for (int i = 0; i < cb.body.size(); i++) {
  613. Literal lit = (Literal) cb.body.get(i);
  614. if (!preds.contains(lit.predicate.name)) {
  615. preds.add(lit.predicate.name);
  616. }
  617. }
  618. return preds;
  619. }
  620. /** Whenever an internally-generated KinTermDef is not available, this method
  621. * can construct a serviceable gloss from the information contained in the
  622. * SILK file representation of a KTD.
  623. *
  624. * @return an English representation of the kin type
  625. */
  626. Gloss dumbGloss() {
  627. ensureEqcSigExact();
  628. Gloss glos = new Gloss();
  629. ArrayList<String> predicates = pluckAllPredicates();
  630. if (hasNoConstraints(predicates)) {
  631. // Easiest way to gloss is from eqcSigExact. Make a temp copy of this ktd
  632. // and compute its eqcSigExact, & use it to produce this gloss.
  633. ArrayList pcStringList = decodeString(eqcSigExact);
  634. for (Object o : pcStringList) {
  635. glos.elements.add(glossify((String) o));
  636. }
  637. } else {
  638. for (Object o : definitions) {
  639. ClauseBody cb = (ClauseBody) o;
  640. glos.elements.add(cb.toSimpleHornClause());
  641. }
  642. }
  643. return glos;
  644. }
  645. void ensureEqcSigExact() {
  646. if (eqcSigExact == null || eqcSigExact.isEmpty()) {
  647. eqcSigExact = "";
  648. Context permCtxt = domTh.ctxt,
  649. tempCtxt = new Context(domTh);
  650. DomainTheory.current = domTh;
  651. try {
  652. KinTermDef tempKTD = new KinTermDef(this);
  653. tempKTD.expandClauses(tempCtxt);
  654. tempKTD.domTh = domTh;
  655. ArrayList<Object> egoBag = new ArrayList<Object>();
  656. for (Object o : tempKTD.expandedDefs) {
  657. ClauseBody cb = (ClauseBody) o;
  658. cb.ktd = tempKTD;
  659. cb.generateExamples(tempCtxt, egoBag, null, null);
  660. }
  661. tempKTD.makeSigStrings();
  662. eqcSigExact = tempKTD.eqcSigExact;
  663. } catch (Exception exc) { // ignore failures, leave empty
  664. System.err.println("While computing eqcSigEact for a gloss:\n" + exc);
  665. }
  666. Context.current = permCtxt;
  667. domTh.ctxt = permCtxt;
  668. }
  669. }
  670. static String glossify(String pcString) {
  671. String gloz = "";
  672. ArrayList<String> symbols = explodePCSymbols(pcString);
  673. int last = symbols.size() - 1;
  674. for (int i = 0; i < last; i++) {
  675. String symbol = (String) symbols.get(i);
  676. gloz += pcSymbolDecoder.get(symbol) + "'s ";
  677. }
  678. gloz += pcSymbolDecoder.get((String) symbols.get(last));
  679. return gloz;
  680. }
  681. ArrayList<String> pluckAllPredicates() {
  682. ArrayList<String> preds = new ArrayList<String>();
  683. for (Object o : definitions) {
  684. ClauseBody cb = (ClauseBody) o;
  685. for (int i = 0; i < cb.body.size(); i++) {
  686. Literal lit = (Literal) cb.body.get(i);
  687. if (!preds.contains(lit.predicate.name)) {
  688. preds.add(lit.predicate.name);
  689. }
  690. if (lit.predicate.name.equals("not")) {
  691. for (Object obj : lit.args) {
  692. if (obj instanceof Literal) {
  693. Literal innerLit = (Literal) obj;
  694. if (!preds.contains(innerLit.predicate.name)) {
  695. preds.add(innerLit.predicate.name);
  696. }
  697. }
  698. }
  699. }
  700. }
  701. }
  702. return preds;
  703. }
  704. static boolean hasNoConstraints(ArrayList<String> symbols) {
  705. for (String s : symbols) {
  706. if (Arrays.binarySearch(constraintSymbols, s) > -1) {
  707. return false;
  708. }
  709. }
  710. return true;
  711. }
  712. static ArrayList<String> explodePCSymbols(String pcString) {
  713. ArrayList<String> symbols = new ArrayList<String>();
  714. char ch;
  715. int cap = 0;
  716. for (int i = 1; i < pcString.length(); i++) {
  717. ch = pcString.charAt(i);
  718. if (Character.isUpperCase(ch) || ch == '*') {
  719. String symbol = pcString.substring(cap, i);
  720. symbols.add(symbol);
  721. cap = i;
  722. } // end of processing completed symbol
  723. } // end of loop thru the symbols
  724. symbols.add(pcString.substring(cap));
  725. return symbols;
  726. }
  727. static String sanitize(String input) {
  728. return FamilyPanel.convertBannedCharacters(input);
  729. }
  730. void expandClauses(Context hypo) throws KSBadHornClauseException, KSConstraintInconsistency,
  731. KSInternalErrorException {
  732. ClauseBody cb, twin;
  733. for (int i = 0; i < definitions.size(); i++) { // each definition is a ClauseBody
  734. cb = (ClauseBody) definitions.get(i);
  735. cb.expand(hypo, expandedDefs, kinTerm, i);
  736. cb.unifyVariables();
  737. }
  738. // Now tidy up a bit and we're done.
  739. ArrayList<Object> twinList = new ArrayList<Object>();
  740. for (int j = 0; j < expandedDefs.size(); j++) { // 1st loop: look for genderVarTwins
  741. cb = (ClauseBody) expandedDefs.get(j);
  742. twin = cb.makeGenderTwin();
  743. if (twin != null) {
  744. twinList.add(twin);
  745. }
  746. } // end of for-each-Expanded-Definition
  747. expandedDefs.addAll(twinList);
  748. for (int j = 0; j < expandedDefs.size(); j++) { // 2nd loop: unifyVars & number the CBs
  749. cb = (ClauseBody) expandedDefs.get(j);
  750. cb.unifyVariables();
  751. cb.seqNmbr = j;
  752. } // end of for-each-Expanded-Definition
  753. return;
  754. } // end of method expandClauses
  755. /** This method is called during analysis of the Library's Domain Theories. It adds to the list
  756. of Head Clause Variable Constraints. It accumulates the counts and records the booleans needed to
  757. derive all the other features needed for a FeatureVectorObj. It determines which Equivalence Classes
  758. (EQCs) in the ClauseIndex each clause belongs to, and builds the set of EQCs to which this KTD belongs.
  759. @param hcvc a list to which we will add all the Head Clause Variable Constraints.
  760. @param ivc a list to which we will add all the Internal Variable Constraints.
  761. @param params 3 ints: 0=RecipCnt, 1=MultiGenCnt, 2=TotalLat.
  762. @param boolArray 3 booleans: 0=GenSkewing, 1=StepTerms, 2=UDPs.
  763. */
  764. public void analyzeFeatures(ArrayList<Object> hcvc, ArrayList<Object> ivc, int[] params, boolean[] boolArray)
  765. throws KSInternalErrorException {
  766. ClauseBody cb;
  767. Literal lit = new Literal();
  768. Predicate predicate;
  769. exactEQCs = new TreeMap();
  770. structEQCs = new TreeMap(); // initialize EQC trees
  771. int[] lvlsFound = new int[expandedDefs.size()]; // collect one level for each cb processed
  772. ArrayList<Object> headVars = new ArrayList<Object>();
  773. for (int k=0; k < clauseHead.args.size(); k++) headVars.add(clauseHead.args.get(k));
  774. for (int j=0; j < expandedDefs.size(); j++) {
  775. cb = (ClauseBody)expandedDefs.get(j);
  776. lvlsFound[j] = cb.level;
  777. addToEQCs(cb);
  778. params[2] += cb.lateralCount();
  779. Argument arg0, arg1;
  780. for (int i=0; i < cb.body.size(); i++) {
  781. lit = (Literal)cb.body.get(i);
  782. predicate = lit.predicate;
  783. ArrayList<Object> parList;
  784. arg0 = (Argument)lit.args.get(0);
  785. if (lit.args.size() == 1) arg1 = null;
  786. else arg1 = (Argument)lit.args.get(1);
  787. if ((predicate.name.equals("elder")) || (predicate.name.equals("younger"))) { // a binary constraint
  788. String canonicalForm = stdFormLitString(lit);
  789. if ((headVars.contains(arg0)) || (headVars.contains(arg1)))
  790. if (! hcvc.contains(canonicalForm)) hcvc.add(canonicalForm);
  791. if (! ((headVars.contains(arg0)) && (headVars.contains(arg1))))
  792. if (! ivc.contains(canonicalForm)) ivc.add(canonicalForm);
  793. }else if (predicate.name.indexOf("*") > -1) { // i.e. it's a User Defined Property
  794. boolArray[2] = true;
  795. }else if (predicate.name.equals("gender")) { // a math variable is being set for gender
  796. String canonicalForm = stdFormLitString(lit);
  797. if (headVars.contains(arg1)) {
  798. if (! hcvc.contains(canonicalForm)) hcvc.add(canonicalForm);
  799. }else if (! ivc.contains(canonicalForm)) ivc.add(canonicalForm);
  800. }
  801. } // end of loop thru Literals in this ClauseBody
  802. // Analyze for step- or half- relations in this ClauseBody
  803. if (! boolArray[1] && multiSpice(cb)) boolArray[1] = true;
  804. } // end of loop thru each expanded Def for this KTD
  805. if (reciprocal(lvlsFound)) params[0]++;
  806. boolean[] localBools = { false, false };
  807. multiGenAndSkew(lvlsFound, localBools);
  808. if (localBools[0]) params[1]++;
  809. if (localBools[1]) boolArray[0] = true;
  810. computeEQCSigs();
  811. } // end of method analyzeFeatures
  812. boolean multiSpice(ClauseBody cb) {
  813. if (cb.pcString.indexOf("Hb") >= 0) return true;
  814. if (cb.pcString.indexOf("Hs") >= 0) return true;
  815. if (cb.pcString.indexOf("St") >= 0) return true;
  816. return false;
  817. } // end of method multiSpice
  818. /** Return a string representation of a literal, standardizing the arguments as follows:
  819. If the predicate is "not" assume a single negated literal as arg0 and process that as the literal.
  820. If the args to lit are "Ego" or "Alter" leave them alone. Otherwise make 'em "arg0", "arg1" etc.
  821. @param lit the literal to be represented.
  822. @return the standard-form string.
  823. */
  824. public String stdFormLitString(Literal lit) {
  825. String close = ")", litString = new String(lit.predicate.name + "(");
  826. // If the predicate is "not" assume a single negated literal as arg0 and process that.
  827. if (lit.predicate.name.equals("not")) {
  828. lit = (Literal)lit.args.get(0);
  829. litString += lit.predicate.name + "(";
  830. close += ")";
  831. } // end of if-its-a-negated-predicate
  832. // If the args to lit are "Ego" or "Alter" leave them alone. Otherwise make 'em "arg0", "arg1" etc.
  833. Argument arg = (Argument)lit.args.get(0);
  834. if ((arg.argName.equals("Ego")) || (arg.argName.equals("Alter"))) litString += arg.argName;
  835. else litString += "arg0";
  836. for (int i=1; i < lit.args.size(); i++) {
  837. arg = (Argument)lit.args.get(i);
  838. if ((arg.argName.equals("Ego")) || (arg.argName.equals("Alter"))) litString += ", " + arg.argName;
  839. else litString += ", arg" + i;
  840. } // end of loop thru args
  841. return litString + close;
  842. } //end of method stdFormLitString
  843. public boolean reciprocal(int[] lvlsFound) {
  844. // Returns true if for every n in lvlsFound, -n also is present.
  845. // At least 1 n ‚Äö?˘‚Ć 0 is required.
  846. TreeSet tset = new TreeSet();
  847. for (int i=0; i < lvlsFound.length; i++)
  848. tset.add(new Integer(lvlsFound[i]));
  849. Iterator lvlIter = tset.iterator();
  850. Integer target, recip;
  851. boolean nonZero = false;
  852. while (lvlIter.hasNext()) {
  853. target = (Integer)lvlIter.next();
  854. if ((! nonZero) && (target.intValue() != 0)) nonZero = true;
  855. recip = new Integer(-1 * target.intValue());
  856. if (! tset.contains(recip)) return false;
  857. } // if we get to here, no level was found whose reciprocal was missing
  858. // so if at least one nonZero value was there, this is a reciprocal set. Else not.
  859. return nonZero;
  860. } // end of method reciprocal
  861. public void multiGenAndSkew(int[] lvlsFound, boolean[] locals) {
  862. // locals begins as { false, false }
  863. TreeSet tset = new TreeSet();
  864. for (int i=0; i < lvlsFound.length; i++)
  865. tset.add(new Integer(lvlsFound[i]));
  866. // Return true in locals[0] if level n and n+1 are found.
  867. if (tset.size() < 2) return; // no chance of multi-gen or skewing
  868. Iterator treeIter = tset.iterator();
  869. Integer int1, int2, int3, zero = new Integer(0);
  870. int2 = (Integer)treeIter.next();
  871. while ((! locals[0]) && treeIter.hasNext()) {
  872. int1 = int2;
  873. int2 = (Integer)treeIter.next();
  874. if (int1.intValue() == int2.intValue() -1) locals[0] = true;
  875. } // end while-loop
  876. // Return true in locals[1] if level n, n+1, and n+2 are found with one of them = 0.
  877. if (tset.size() < 3) return;
  878. treeIter = tset.iterator();
  879. int2 = (Integer)treeIter.next();
  880. int3 = (Integer)treeIter.next();
  881. boolean zeroFound = false;
  882. while ((! locals[1]) && treeIter.hasNext()) {
  883. int1 = int2;
  884. int2 = int3;
  885. int3 = (Integer)treeIter.next();
  886. if ((int1.intValue() == 0) || (int2.intValue() == 0) || (int3.intValue() == 0))
  887. zeroFound = true;
  888. else zeroFound = false;
  889. if (zeroFound && (int1.intValue() == int2.intValue() -1) && (int2.intValue() == int3.intValue() -1))
  890. locals[1] = true;
  891. }
  892. } // end of method multiGenAndSkew
  893. /** This method is called to generate examples for Simulated Data Generation.
  894. @param hypo the SourceDT Context for this DomainTheory
  895. @param egoBag contains at least 1 male and 1 female {@link Individual} who can serve as Ego in definitions.
  896. @param dt the SourceDT we're using
  897. @param learnedDef the KTD which has been learned for this kinTerm (or null)
  898. */
  899. public void generateExamples(Context hypo, ArrayList<Object> egoBag, Oracle orca, KinTermDef learnedDef)
  900. throws KSBadHornClauseException, KSInternalErrorException, KSConstraintInconsistency,
  901. ClassNotFoundException {
  902. if (learnedDef == null) {
  903. generateExamples(hypo, egoBag, orca);
  904. return;
  905. }
  906. Iterator cbIter = expandedDefs.iterator();
  907. ClauseBody cb;
  908. ArrayList<Object> eqcSigList = decodeString(learnedDef.eqcSigExact);
  909. while (cbIter.hasNext()) {
  910. cb = (ClauseBody)cbIter.next();
  911. // If we've already learned a definition that includes this kinType, we don't need more examples.
  912. if (! eqcSigList.contains(cb.pcString)) {
  913. cb.generateExamples(hypo, egoBag, null, orca);
  914. if (cb.duplicative && ! hypo.simDataGen) {
  915. cbIter.remove();
  916. }
  917. }
  918. } // end of loop thru expanded Defs
  919. } // end of method generateExamples
  920. /** This method is called to generate examples - in the process it identifies and removes
  921. duplicative clauses and re-numbers them.
  922. @param ctxt the (hypothetical) Context for this DomainTheory
  923. @param egoBag contains at least 1 male and 1 female {@link Individual} who can serve as Ego in definitions.
  924. @param dt the DomainTheory we're using
  925. */
  926. public void generateExamples(Context ctxt, ArrayList<Object> egoBag, Oracle orca)
  927. throws KSBadHornClauseException, KSInternalErrorException, KSConstraintInconsistency,
  928. ClassNotFoundException {
  929. Iterator cbIter = expandedDefs.iterator();
  930. ClauseBody cb;
  931. int serial = 0;
  932. while (cbIter.hasNext()) {
  933. cb = (ClauseBody)cbIter.next();
  934. // if (ctxt.languageName.equals("Cogui") && kinTerm.equals("augui")) {
  935. // Context.breakpoint();
  936. // }
  937. cb.generateExamples(ctxt, egoBag, null, orca);
  938. if (cb.duplicative && ! ctxt.simDataGen) {
  939. cbIter.remove();
  940. }else cb.seqNmbr = serial++;
  941. }
  942. } // end of method generateExamples
  943. /** This method is called when we need to be sure that this KTD has been expanded and all its
  944. fields computed during generation.
  945. @param egoBag contains at least 1 male and 1 female {@link Individual} who can serve as Ego in definitions.
  946. */
  947. public void assureExamplesGenerated(ArrayList<Object> egoBag)
  948. throws KSBadHornClauseException, KSInternalErrorException, KSConstraintInconsistency, ClassNotFoundException {
  949. boolean needAnEgo = false;
  950. ClauseBody cb;
  951. if (expandedDefs == null || expandedDefs.isEmpty()) {
  952. expandClauses(Context.current);
  953. }
  954. for (int i = 0; i < expandedDefs.size(); i++) {
  955. cb = (ClauseBody) expandedDefs.get(i); // See if computed by generation
  956. if ((cb.pcCounter + cb.sCounter + cb.starCounter) == 0) { // need to generate examples
  957. needAnEgo = true;
  958. break; // finding one is enough; stop the loop
  959. } // end of need to generate examples
  960. } // end of loop thru expandedDefs
  961. if (needAnEgo) {
  962. generateExamples(Context.current, egoBag, null);
  963. domTh.ctxt.saveState = true;
  964. }
  965. } // end of method assureExamplesGenerated
  966. public ArrayList<Object> makeFlags() {
  967. ArrayList<Object> flagList = new ArrayList<Object>();
  968. int start = 0, left, right;
  969. while (kinTerm.indexOf("[", start) >= 0) {
  970. left = kinTerm.indexOf("[", start) + 1;
  971. right = kinTerm.indexOf("]", start);
  972. start = Math.min((right + 1), (kinTerm.length() - 1));
  973. String flag = kinTerm.substring(left, right);
  974. flagList.add(flag);
  975. } // end of if-flags-are-embedded-in-predicate-name
  976. return flagList;
  977. } // end of method makeFlags
  978. public boolean hasDelayFlags() { // other delayed-ID flags may be added later
  979. for (int i=0; i < expandedDefs.size(); i++) {
  980. ClauseBody cb = (ClauseBody)expandedDefs.get(i);
  981. if (cb.flags.contains("chooseLast")) return true;
  982. }
  983. return false;
  984. } // end of method hasDelayFlags
  985. public void simplifyClauses() throws KSInternalErrorException, KSConstraintInconsistency,
  986. KSBadHornClauseException, ClassNotFoundException {
  987. // This method should only be called on Composed Definitions
  988. ArrayList<Object> superPrims = new ArrayList<Object>(),
  989. normalForm = new ArrayList<Object>();
  990. // if (kinTerm.equals("laveh_khooshkeh_dapeereh")) Context.breakpoint();
  991. // System.out.println("\n\n\t\tBEFORE:");
  992. // for (int i=0; i < definitions.size(); i++) System.out.println(definitions.get(i));
  993. int initialSize = definitions.size();
  994. for (int i=0; i < initialSize; i++) {
  995. ClauseBody orig = (ClauseBody)definitions.get(i),
  996. superPrim = orig.canonicalizePreds(orig);
  997. superPrim.seqNmbr = i;
  998. superPrims.add(superPrim);
  999. }
  1000. // Do pair-wise merging if possible
  1001. boolean progress = true;
  1002. while (progress) {
  1003. ArrayList<Object> triple = new ArrayList<Object>();
  1004. progress = findMergePairs(superPrims, triple);
  1005. if (progress) {
  1006. ClauseBody aCB = (ClauseBody)triple.get(0),
  1007. bCB = (ClauseBody)triple.get(1),
  1008. newCB = (ClauseBody)triple.get(2);
  1009. superPrims.remove(aCB);
  1010. superPrims.remove(bCB);
  1011. superPrims.add(newCB);
  1012. } // end of made-progress
  1013. } // end of while-progress
  1014. for (int i=0; i < superPrims.size(); i++) {
  1015. ClauseBody superPrim = (ClauseBody)superPrims.get(i);
  1016. superPrim.makeNormalPrimitive();
  1017. superPrim.seqNmbr = i;
  1018. superPrim.unifyVariables();
  1019. normalForm.add(superPrim);
  1020. } // end of loop thru merged superPrimitives
  1021. definitions = normalForm;
  1022. if (initialSize > definitions.size()) {
  1023. expandedDefs.clear();
  1024. Context realCtxt = domTh.ctxt,
  1025. tempCtxt = new Context(domTh);
  1026. expandClauses(tempCtxt);
  1027. ArrayList<Object> egoBag = domTh.maleAndFemaleCreatedHeThem();
  1028. for (int i=0; i < expandedDefs.size(); i++) {
  1029. ClauseBody cb = (ClauseBody)expandedDefs.get(i);
  1030. cb.generateExamples(tempCtxt, egoBag, null, null);
  1031. } // end of loop thru newly-expanded Defs
  1032. domTh.ctxt = realCtxt; //
  1033. } // end of if-we-simplified-any-BaseCBs
  1034. // System.out.println("\n\t\tAFTER:");
  1035. // for (int i=0; i < definitions.size(); i++) System.out.println(definitions.get(i));
  1036. // System.out.println("\n");
  1037. // for (int i=0; i < expandedDefs.size(); i++) System.out.println(expandedDefs.get(i));
  1038. // System.out.println("\n");
  1039. } // end of method simplifyClauses
  1040. public boolean findMergePairs(ArrayList<Object> superPrims, ArrayList<Object> triple) throws KSInternalErrorException {
  1041. // Find 2 CBs of identical length that unify except for 1 pair of lits
  1042. // Return the pair plus their merger in triple.
  1043. ClauseBody cb1, cb2;
  1044. for (int i=0; i < superPrims.size() -1; i++) {
  1045. cb1 = (ClauseBody)superPrims.get(i);
  1046. for (int j=i+1; j < superPrims.size(); j++) {
  1047. cb2 = (ClauseBody)superPrims.get(j);
  1048. ArrayList<Object> misMatches = new ArrayList<Object>(),
  1049. boundVars = new ArrayList<Object>(),
  1050. oldNames = new ArrayList<Object>(),
  1051. newNames = new ArrayList<Object>();
  1052. Counter limit = new Counter(1);
  1053. if (cb1.body.size() == cb2.body.size()
  1054. && cb1.almostUnifies(cb1.deepCopy().body, cb2.deepCopy().body, boundVars,
  1055. oldNames, newNames, misMatches, limit, cb2)
  1056. && complementaryPreds(misMatches, cb1, cb2)) {
  1057. triple.add(cb1);
  1058. triple.add(cb2);
  1059. triple.add((misMatches.isEmpty() ? cb1 : misMatches.get(2)));
  1060. return true;
  1061. } // end of they-almostUnify
  1062. } // end of inner loop
  1063. } // end of outer loop
  1064. return false;
  1065. } // end of method findMergePairs
  1066. public boolean complementaryPreds(ArrayList<Object> misMatches, ClauseBody cb1, ClauseBody cb2)
  1067. throws KSInternalErrorException {
  1068. // If the 2 Literals in misMatches are complementary predicates in cb1 & cb2,
  1069. // add the logical merge of cb1 & cb2 to misMatches & return true.
  1070. if (misMatches.isEmpty()) return true; // There aren't any differences. Easy.
  1071. Literal lit1 = (Literal)misMatches.get(0),
  1072. lit2 = (Literal)misMatches.get(1);
  1073. String pred1 = lit1.predicate.name,
  1074. pred2 = lit2.predicate.name;
  1075. int where = cb1.body.indexOf(lit1);
  1076. if (where == -1)
  1077. throw

Large files files are truncated, but you can click here to view the full file