PageRenderTime 46ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 1ms

/code/DT_Abstract1.java

http://silkin.googlecode.com/
Java | 865 lines | 741 code | 39 blank | 85 comment | 241 complexity | 77a2d1a7c52c599cdeeb8d8d05383291 MD5 | raw file
  1. import java.util.*;
  2. import java.text.*;
  3. import java.io.*;
  4. /** This class begins the definition of a Domain Theory in Prolog syntax. In this system, a Domain Theory is a grammar
  5. defining a Kinship System. This is the level at which 90% of the action takes place in Active Learning.
  6. <p>
  7. Because so many methods are defined at the Domain Theory level, the code files are broken into 4 classes:
  8. DT_Abstract1, DT_Abstract12, & DomainTheory.
  9. @author Gary Morris, Northern Virginia Community College garymorris2245@verizon.net
  10. */
  11. public abstract class DT_Abstract1 implements Serializable {
  12. /** This global variable records whether the Domain Theory currently in focus concerns
  13. Terms of Address (true) or Terms of Reference (false).
  14. */
  15. public static boolean addrTerms = false;
  16. public static DomainTheory current;
  17. public static final TreeMap standardMacroTree = new TreeMap(); // quick index of these macros
  18. public static String[] primPredNames = {"father", "mother", "parent", "child", "husband", "wife", "spouse",
  19. "son", "daughter", "male", "female", "elder", "younger", "equal", "not", "divorced", "dead",
  20. "gender", "lessThan", "greaterThan", "lessOrEql ", "greaterOrEql", "contains", "allowCreation",
  21. "sibling", "parents", "siblings", "brother", "sister", "half_brother", "half_sister", "step_brother",
  22. "step_sister", "step_father", "step_mother", "children", "step_son", "step_daughter", "spice"};
  23. // A single instance of each of the 24 primitive predicate names; to be replaced by codes
  24. // in the CompactCBStrings used in CB_Index
  25. public static final TreeMap primitiveCodes = loadPrimitiveCodes();
  26. public static TreeMap loadPrimitiveCodes() {
  27. TreeMap theMap = new TreeMap();
  28. for (int i = 0; i < 24; i++) {
  29. theMap.put(primPredNames[i], new Integer(i));
  30. }
  31. for (int i = 24; i < 39; i++) {
  32. theMap.put(primPredNames[i], new Integer(i));
  33. standardMacroTree.put(primPredNames[i], primPredNames[i]);
  34. }
  35. return theMap;
  36. } // end of static method loadPrimitiveCodes
  37. public static boolean isPrimOrMacro(String predName) {
  38. for (int i = 0; i < primPredNames.length; i++) {
  39. if (primPredNames[i].equals(predName)) {
  40. return true;
  41. }
  42. }
  43. return false;
  44. } // end of class method isPrimOrMacro
  45. public static TreeMap mergeTrees(TreeMap tree1, TreeMap tree2) {
  46. // merge 2 trees that are exactStr -> dyadList.
  47. if (tree1 == null || tree1.isEmpty()) {
  48. return tree2;
  49. }
  50. if (tree2 == null || tree2.isEmpty()) {
  51. return tree1;
  52. }
  53. TreeMap merg = new TreeMap(tree1);
  54. Iterator trIter = tree2.entrySet().iterator();
  55. while (trIter.hasNext()) {
  56. Map.Entry entry = (Map.Entry) trIter.next();
  57. String exactStr = (String) entry.getKey();
  58. if (merg.get(exactStr) == null) {
  59. merg.put(exactStr, entry.getValue());
  60. } else { // leave old entry un-modified -- make new copy
  61. ArrayList<Object> list1 = new ArrayList<Object>((ArrayList<Object>) merg.get(exactStr)),
  62. list2 = (ArrayList<Object>) entry.getValue();
  63. for (int i = 0; i < list2.size(); i++) {
  64. Dyad dy = (Dyad) list2.get(i);
  65. if (!list1.contains(dy)) {
  66. list1.add(dy);
  67. }
  68. }
  69. merg.put(exactStr, list1);
  70. } // end of make-merged-list
  71. } // end of loop thru tree2 entries
  72. return merg;
  73. } // end of method mergeTrees
  74. public static TreeMap mergeNestedTrees(TreeMap tree1, TreeMap tree2) {
  75. // merge 2 trees that are kinTerm => exactStr => dyadList.
  76. if (tree1 == null || tree1.isEmpty()) {
  77. return new TreeMap(tree2);
  78. }
  79. if (tree2 == null || tree2.isEmpty()) {
  80. return new TreeMap(tree1);
  81. }
  82. TreeMap merg = new TreeMap(tree1),
  83. source = new TreeMap(tree2);
  84. Iterator trIter = source.entrySet().iterator();
  85. while (trIter.hasNext()) {
  86. Map.Entry entry = (Map.Entry) trIter.next();
  87. String kinTerm = (String) entry.getKey();
  88. if (merg.get(kinTerm) == null) {
  89. merg.put(kinTerm, entry.getValue());
  90. } else { // merge the 2 sub-trees
  91. TreeMap subTree1 = (TreeMap) merg.get(kinTerm);
  92. TreeMap subTree2 = (TreeMap) entry.getValue();
  93. merg.put(kinTerm, mergeTrees(subTree2, subTree1));
  94. } // end of merge-the-sub-trees
  95. } // end of loop thru tree2 entries
  96. return merg;
  97. } // end of method mergeNestedTrees
  98. // Class Variables //
  99. Context ctxt; // Ptr to enclosing Context.
  100. String languageName; // name of the language or people group
  101. String author; // field worker who devised theory or gathered data
  102. String createDate; // date domain theory was developed (not necessarily the date computerized).
  103. String citation; // documents source of this domain theory in the literature.
  104. String filePath; // pathname to the file which contains this domain theory.
  105. ArrayList<Object> nonTerms = new ArrayList<Object>(); // predicates that should not be printed. Not really kinTerms.
  106. // These flags (enclosed in square brackets) on any definition make it non-printing.
  107. ArrayList<Object> nonTermFlags = new ArrayList<Object>();
  108. boolean partial = false; // 'true' if this is a partial theory, an example
  109. // of a particular kinship pattern from the literature.
  110. boolean polygamyOK = true; // default: true = multiple spice allowed
  111. boolean addressTerms = false; // default = this is a theory for Terms of Reference
  112. int levelsOfRecursion = 1; // the number of recursive levels to 'unwind' explicitly in an expanded def
  113. TreeMap theory; // structure: kinTerm => KinTermDef.
  114. TreeMap userDefinedProperties; // A TMap of UDPs, stored here during parsing. Then moved to Context.
  115. DyadTMap dyadsUndefined = new DyadTMap(),
  116. dyadsDefined = new DyadTMap();
  117. TreeMap synonyms, umbrellas, overlaps, potUmbrellas, nonUmbrellas, nonOverlaps;
  118. TreeMap<String, ArrayList<Issue>> issuesForUser = new TreeMap<String, ArrayList<Issue>>();
  119. ArrayList<Object> nonSynonyms;
  120. // NOTE: structure of umbrellas is: umbTerm -> list-of-subsumed-terms
  121. // structure of potUmbrellas is: umbTerm -> {list of pcStrings, Quad, ... Quad }
  122. // where Quad = {subTerm, list of its pcStrings, list of Dyads, filterType}
  123. // structure of synonyms is: synonym -> baseTerm
  124. // structure of overlaps is: term => ArrayList<Object> of overlapping terms
  125. // structure of nonOverlaps is: term => ArrayList<Object> of rejected terms
  126. // structure of issuesForUser is: kinTerm -> ArrayList<Object>-of-Issues
  127. // The nonUmbrellas & nonSynonyms record suggested terms specifically rejected by User.
  128. // structure of nonSynonymns is: ArrayList<Object>-of word1_word2 pairs (words in lexico order)
  129. // structure of nonUmbrellas is: RejectedUmbTerm => ArrayList<Object>-of-rejectedSubTerms
  130. public boolean isEmpty() {
  131. if (theory != null && ! theory.isEmpty()) return false;
  132. if (userDefinedProperties != null && ! userDefinedProperties.isEmpty()) return false;
  133. if (! dyadsUndefined.isEmpty()) return false;
  134. if (! dyadsDefined.isEmpty()) return false;
  135. if (synonyms != null && ! synonyms.isEmpty()) return false;
  136. if (umbrellas != null && ! umbrellas.isEmpty()) return false;
  137. if (overlaps != null && ! overlaps.isEmpty()) return false;
  138. if (issuesForUser != null && ! issuesForUser.isEmpty()) return false;
  139. return true;
  140. }
  141. void addTerm(KinTermDef ktd) throws KSParsingErrorException {
  142. KinTermDef priorDef = (KinTermDef) theory.get(ktd.kinTerm);
  143. // It is OK to overwrite a temporary aux during learning.
  144. if (priorDef == null || ktd.kinTerm.indexOf("<temp_aux>") > -1) {
  145. theory.put(ktd.kinTerm, ktd);
  146. ktd.domTh = (DomainTheory) this;
  147. } else {
  148. throw new KSParsingErrorException("Attempt to re-define kinTerm " + ktd.kinTerm
  149. + "\nin DomainTheory " + languageName); // identify where the activity is
  150. }
  151. } // end of method for adding a term to the theory
  152. public void toThyFile(PrintWriter file) throws KSInternalErrorException {
  153. file.println(";; Horn Clause Representation of " + languageName
  154. + " Kinship Term-of-" + (addressTerms ? "Address" : "Reference") + " Rules");
  155. file.println("\n;; The following 'header' gives some basic parameters of this kinship system:");
  156. file.print("(languageName, \"" + languageName + "\") ");
  157. if (author != null) {
  158. file.print("(author, \"" + author + "\") ");
  159. }
  160. if (createDate != null) {
  161. file.print("(date, \"" + createDate + "\") ");
  162. }
  163. if (citation != null) {
  164. file.println("(citation, \"" + citation + "\") ");
  165. }
  166. if ((nonTerms.size() + nonTermFlags.size()) > 0) {
  167. String image = "(non_term, ";
  168. for (int i = 0; i < nonTermFlags.size(); i++) {
  169. image += "[" + nonTermFlags.get(i) + "], ";
  170. }
  171. for (int i = 0; i < nonTerms.size(); i++) {
  172. image += nonTerms.get(i) + ", ";
  173. }
  174. image = image.substring(0, image.length() - 2) + ") ";
  175. file.print(image);
  176. } // end of if-there-are-non-Terms-or-flags
  177. file.print("(partial, " + (partial ? "true) " : "false) "));
  178. file.print("(polygamyOK, " + (ctxt.polygamyPermit ? "true) " : "false) "));
  179. file.print("(address, " + (addressTerms ? "true) " : "false) "));
  180. file.println("(recursiveLevels, " + levelsOfRecursion + ")");
  181. if (synonyms != null) {
  182. file.print("(synonyms, ");
  183. Iterator synIter = synonyms.entrySet().iterator();
  184. while (synIter.hasNext()) {
  185. Map.Entry entry = (Map.Entry) synIter.next();
  186. file.print("(" + entry.getValue() + ", " + entry.getKey() + ")");
  187. if (synIter.hasNext()) {
  188. file.print(", ");
  189. }
  190. }
  191. file.println(")");
  192. } // end of writing synonyms
  193. if (overlaps != null) {
  194. file.print("(overlaps, ");
  195. String holder = "";
  196. Iterator iter = overlaps.entrySet().iterator();
  197. while (iter.hasNext()) {
  198. Map.Entry entry = (Map.Entry) iter.next();
  199. holder += "(" + entry.getKey() + ", " + entry.getValue() + ")";
  200. if (iter.hasNext()) {
  201. holder += ", ";
  202. }
  203. }
  204. holder = holder.replace(", [", ", (");
  205. holder = holder.replace("])", "))");
  206. file.println(holder + ")");
  207. } // end of writing overlaps
  208. if (umbrellas != null) {
  209. file.print("(umbrellas, ");
  210. String holder = "", smpl = "[]()";
  211. char leftSq = smpl.charAt(0), rightSq = smpl.charAt(1),
  212. leftParen = smpl.charAt(2), rightParen = smpl.charAt(3);
  213. Iterator umbIter = umbrellas.entrySet().iterator();
  214. while (umbIter.hasNext()) {
  215. Map.Entry entry = (Map.Entry) umbIter.next();
  216. holder += "(" + entry.getKey() + ", " + entry.getValue() + ")";
  217. if (umbIter.hasNext()) {
  218. holder += ", ";
  219. }
  220. }
  221. holder = holder.replace(leftSq, leftParen);
  222. holder = holder.replace(rightSq, rightParen);
  223. file.println(holder + ")");
  224. } // end of writing umbrellas
  225. TreeMap udps = ctxt.userDefinedProperties;
  226. // Define UDPs, if any
  227. if ((udps != null) && (udps.size() > 0)) {
  228. file.println("(userDefinedProperties, ");
  229. UserDefinedProperty udp;
  230. String quoter;
  231. Iterator udIter = udps.values().iterator();
  232. while (udIter.hasNext()) {
  233. udp = (UserDefinedProperty) udIter.next();
  234. file.print("\t(" + udp.starName + ", type, " + udp.typ + ", single_value, " + udp.singleValue);
  235. // next items are optional
  236. if ((udp.typ.equals("string")) || (udp.typ.equals("boolean"))) {
  237. quoter = "\"";
  238. } else {
  239. quoter = "";
  240. }
  241. if ((udp.validEntries != null) && (udp.validEntries.size() > 0)) {
  242. int sz = udp.validEntries.size();
  243. file.print(", restricted_to, (");
  244. for (int i = 0; i < sz; i++) {
  245. if (i > 0) {
  246. file.print(", ");
  247. }
  248. file.print(quoter + udp.validEntries.get(i) + quoter);
  249. } // end of loop through validEntries
  250. file.print(")");
  251. } // end of there-are-validEntries
  252. if (udp.defaultValue != null) {
  253. file.print(", default, " + quoter + udp.defaultValue + quoter);
  254. }
  255. file.println(")" + (udIter.hasNext() ? "," : ""));
  256. } // end of loop thru UDP's
  257. file.println(" )");
  258. } // end of there-are-UDPs
  259. Iterator iter = theory.values().iterator();
  260. file.println("\n\n;; Kin Term Definitions:");
  261. file.println(";;\t(Standard Macros are automatically incorporated.)");
  262. while (iter.hasNext()) {
  263. file.println("\n" + ((KinTermDef) iter.next()).toThyString());
  264. }
  265. file.flush();
  266. file.close();
  267. } // end of method toThyFile
  268. public String toSILKString(String bacer) {
  269. String spacer = "\t", dblSpacer = "\t\t";
  270. String s = bacer + "<domain-theory type=\"" + (addressTerms ? "Adr" : "Ref") + "\">\n";
  271. if (citation != null && !citation.isEmpty()) {
  272. s += bacer + spacer + "<citation text=\"" + citation + "\"/>\n";
  273. }
  274. if (nonTerms != null && !nonTerms.isEmpty()) {
  275. s += bacer + spacer + "<non-terms>\n";
  276. for (Object o : nonTerms) {
  277. s += bacer + dblSpacer + "<non-term value=\"" + o + "\"/>\n";
  278. }
  279. s += bacer + spacer + "</non-terms>\n";
  280. }
  281. if (nonTermFlags != null && !nonTermFlags.isEmpty()) {
  282. s += bacer + spacer + "<non-term-flags>\n";
  283. for (Object o : nonTermFlags) {
  284. s += bacer + dblSpacer + "<non-term-flag value=\"" + o + "\"/>\n";
  285. }
  286. s += bacer + spacer + "</non-term-flags>\n";
  287. }
  288. s += bacer + spacer + "<levels-of-recursion n=\"" + levelsOfRecursion + "\"/>\n";
  289. if (theory != null && !theory.isEmpty()) {
  290. s += bacer + spacer + "<theory>\n";
  291. Iterator iter = theory.values().iterator();
  292. while (iter.hasNext()) {
  293. KinTermDef ktd = (KinTermDef)iter.next();
  294. s += ktd.toSILKString(bacer + dblSpacer, false) + "\n";
  295. }
  296. s += bacer + spacer + "</theory>\n";
  297. }
  298. if (synonyms != null && !synonyms.isEmpty()) {
  299. s += bacer + spacer + "<synonyms>\n";
  300. Iterator iter = synonyms.entrySet().iterator();
  301. while (iter.hasNext()) {
  302. Map.Entry<String, String> entry = (Map.Entry<String, String>)iter.next();
  303. String sub = entry.getKey(), base = entry.getValue();
  304. s += bacer + dblSpacer + "<pair subTerm=\"" + sub + "\" baseTerm=\"" + base + "\"/>\n";
  305. }
  306. s += bacer + spacer + "</synonyms>\n";
  307. }
  308. if (umbrellas != null && !umbrellas.isEmpty()) {
  309. s += bacer + spacer + "<umbrellas>\n";
  310. Iterator iter = umbrellas.entrySet().iterator();
  311. while (iter.hasNext()) {
  312. Map.Entry<String, ArrayList<String>> entry = (Map.Entry<String, ArrayList<String>>)iter.next();
  313. String umbTerm = entry.getKey();
  314. ArrayList<String> subTerms = entry.getValue();
  315. s += bacer + dblSpacer + "<umbrella umbTerm=\"" + umbTerm + "\">\n";
  316. for (String subTerm : subTerms) {
  317. s += bacer + dblSpacer + spacer + "<sub-term value=\"" + subTerm + "\"/>\n";
  318. }
  319. s += bacer + dblSpacer + "</umbrella>\n";
  320. }
  321. s += bacer + spacer + "</umbrellas>\n";
  322. }
  323. if (overlaps != null && !overlaps.isEmpty()) {
  324. s += bacer + spacer + "<overlaps>\n";
  325. Iterator iter = overlaps.entrySet().iterator();
  326. while (iter.hasNext()) {
  327. Map.Entry<String, ArrayList<String>> entry = (Map.Entry<String, ArrayList<String>>)iter.next();
  328. String baseTerm = entry.getKey();
  329. ArrayList<String> olapTerms = entry.getValue();
  330. s += bacer + dblSpacer + "<overlap baseTerm=\"" + baseTerm + "\">\n";
  331. for (String olapTerm : olapTerms) {
  332. s += bacer + dblSpacer + spacer + "<overlap-term value=\"" + olapTerm + "\"/>\n";
  333. }
  334. s += bacer + dblSpacer + "</overlap>\n";
  335. }
  336. s += bacer + spacer + "</overlaps>\n";
  337. }
  338. if (nonSynonyms != null && !nonSynonyms.isEmpty()) {
  339. s += bacer + spacer + "<nonSynonyms>\n";
  340. for (Object o : nonSynonyms) {
  341. String nonPair = (String)o;
  342. int slash = nonPair.indexOf("/");
  343. String tm1 = nonPair.substring(0, slash);
  344. String tm2 = nonPair.substring(slash +1);
  345. s += bacer + dblSpacer + "<nonSynonym term1=\"" + tm1 + "\" term2=\"" + tm2 + "\"/>\n";
  346. }
  347. s += bacer + spacer + "</nonSynonyms>\n";
  348. }
  349. if (nonOverlaps != null && !nonOverlaps.isEmpty()) {
  350. s += bacer + spacer + "<nonOverlaps>\n";
  351. Iterator iter = nonOverlaps.entrySet().iterator();
  352. while (iter.hasNext()) {
  353. Map.Entry<String, ArrayList<String>> entry = (Map.Entry<String, ArrayList<String>>)iter.next();
  354. String baseTerm = entry.getKey();
  355. ArrayList<String> olapTerms = entry.getValue();
  356. s += bacer + dblSpacer + "<nonOverlap baseTerm=\"" + baseTerm + "\">\n";
  357. for (String olapTerm : olapTerms) {
  358. s += bacer + dblSpacer + spacer + "<nonOverlap-term value=\"" + olapTerm + "\"/>\n";
  359. }
  360. s += bacer + dblSpacer + "</nonOverlap>\n";
  361. }
  362. s += bacer + spacer + "</nonOverlaps>\n";
  363. }
  364. if (nonUmbrellas != null && !nonUmbrellas.isEmpty()) {
  365. s += bacer + spacer + "<nonUmbrellas>\n";
  366. Iterator iter = nonUmbrellas.entrySet().iterator();
  367. while (iter.hasNext()) {
  368. Map.Entry<String, ArrayList<String>> entry = (Map.Entry<String, ArrayList<String>>)iter.next();
  369. String umbTerm = entry.getKey();
  370. ArrayList<String> subTerms = entry.getValue();
  371. s += bacer + dblSpacer + "<nonUmbrella umbTerm=\"" + umbTerm + "\">\n";
  372. for (String subTerm : subTerms) {
  373. s += bacer + dblSpacer + spacer + "<sub-term value=\"" + subTerm + "\"/>\n";
  374. }
  375. s += bacer + dblSpacer + "</nonUmbrella>\n";
  376. }
  377. s += bacer + spacer + "</nonUmbrellas>\n";
  378. }
  379. s += bacer + "</domain-theory>\n";
  380. return s;
  381. }
  382. public String toString() {
  383. String partiality = "", polygamy, recursion = "", image = "Kin Term Domain: " + languageName;
  384. if (ctxt.polygamyPermit) {
  385. polygamy = " (polygamous)";
  386. } else {
  387. polygamy = " (monogamous)";
  388. }
  389. if (partial) {
  390. partiality = " (partial theory)";
  391. }
  392. if (levelsOfRecursion != 1) {
  393. recursion = " (" + levelsOfRecursion + " levels of recursion)";
  394. }
  395. image += polygamy + partiality + recursion + "\nField Worker/Analyst: " + author;
  396. image += "\nCreate Date: " + createDate + "\n";
  397. if (citation != null) {
  398. image += "Source: " + citation + "\n";
  399. }
  400. Collection values = theory.values();
  401. Iterator iter = values.iterator();
  402. image += "\nKin Term Definitions: ";
  403. while (iter.hasNext()) {
  404. image += "\n" + iter.next();
  405. }
  406. image += "\n---- End ----\n";
  407. return image;
  408. } // end for now.
  409. public boolean printableTerm(KinTermDef ktd) {
  410. if (nonTerms.contains(ktd.kinTerm)) {
  411. return false;
  412. }
  413. if (synonyms != null && synonyms.containsKey(ktd.kinTerm)) {
  414. return false;
  415. }
  416. for (int i = 0; i < ktd.flags.size(); i++) {
  417. if (nonTermFlags.contains(ktd.flags.get(i))) {
  418. return false;
  419. }
  420. }
  421. return true;
  422. } // end of method printableTerm
  423. public boolean nonSynNonMacro(KinTermDef ktd) {
  424. if ((synonyms != null && synonyms.containsKey(ktd.kinTerm)) // a synonym
  425. || standardMacroTree.containsKey(ktd.kinTerm)) {
  426. return false;
  427. } else {
  428. return true;
  429. }
  430. } // end of method nonSynNonMacro
  431. public boolean nonMacro(KinTermDef ktd) {
  432. if (standardMacroTree.containsKey(ktd.kinTerm)) {
  433. return false;
  434. } else {
  435. return true;
  436. }
  437. } // end of method nonMacro
  438. public boolean nonTerm(String term) {
  439. if (nonTerms.contains(term)) {
  440. return true;
  441. }
  442. KinTermDef ktd = (KinTermDef) theory.get(term);
  443. if (ktd == null) {
  444. return true;
  445. }
  446. for (int i = 0; i < ktd.flags.size(); i++) {
  447. if (nonTermFlags.contains(ktd.flags.get(i))) {
  448. return true;
  449. }
  450. }
  451. return false;
  452. } // end of method nonMacro
  453. public boolean printableBaseTerm(KinTermDef ktd) {
  454. if (ktd == null) {
  455. return true;
  456. }
  457. if (nonTerms.contains(ktd.kinTerm)) {
  458. return false;
  459. }
  460. for (int i = 0; i < ktd.flags.size(); i++) {
  461. if (nonTermFlags.contains(ktd.flags.get(i))) {
  462. return false;
  463. }
  464. }
  465. return true;
  466. } // end of method printableBaseTerm
  467. public ArrayList<Object> maleAndFemaleCreatedHeThem() {
  468. Individual malEgo = new Individual("Ego", "M"), femalEgo = new Individual("Ego", "F");
  469. // NOTE: May be creating egos for some other DT & Context.current
  470. if (Context.current.domTheoryAdrExists()) {
  471. malEgo.node.kinTermsAddr.add("Ego");
  472. femalEgo.node.kinTermsAddr.add("Ego");
  473. }
  474. if (Context.current.domTheoryRefExists()) {
  475. malEgo.node.kinTermsRef.add("Ego");
  476. femalEgo.node.kinTermsRef.add("Ego");
  477. }
  478. malEgo.setDateOfBirth("1970-01-01");
  479. femalEgo.setDateOfBirth("1970-01-01");
  480. malEgo.node.setLevel(0);
  481. femalEgo.node.setLevel(0);
  482. ArrayList<Object> result = new ArrayList<Object>();
  483. result.add(malEgo);
  484. result.add(femalEgo);
  485. return result;
  486. } // end of pretentiously-titled-method
  487. public void fillInNames(Individual ego) throws KSBadHornClauseException, KSInternalErrorException,
  488. KSConstraintInconsistency, KSNoChainOfRelations2Alter, ClassNotFoundException {
  489. // For all the persons in a context, fill in their kinTerm names (relative to Ego)
  490. // per this domain theory.
  491. KinTermDef ktd;
  492. String kinTerm;
  493. ClauseBody cb;
  494. Iterator ktditer = theory.values().iterator();
  495. boolean suppressPrint;
  496. // first we'll fill_in_names for all gender-neutral kin terms
  497. while (ktditer.hasNext()) {
  498. ktd = (KinTermDef) ktditer.next();
  499. kinTerm = ktd.kinTerm;
  500. suppressPrint = false;
  501. for (int i = 0; i < ktd.flags.size(); i++) {
  502. if (nonTermFlags.contains(ktd.flags.get(i))) {
  503. suppressPrint = true;
  504. }
  505. }
  506. if (!(nonTerms.contains(kinTerm) || suppressPrint)) {
  507. Iterator defiter = ktd.expandedDefs.iterator();
  508. while (defiter.hasNext()) {
  509. cb = (ClauseBody) defiter.next();
  510. // fill in egoNum the first time thru
  511. cb.egoNum = ego.serialNmbr;
  512. if (cb.genderOfAlter.equals("?")) {
  513. cb.fillInNames(ego, kinTerm);
  514. }
  515. } // end of for each expanded definition
  516. } // end of if-not-convenience-kinterm
  517. } // end of for-each-kinTermDef
  518. ktditer = theory.values().iterator();
  519. // now do it for gender-specific terms.
  520. // delayed-ID terms can be handled like the others, 'cuz we're not creating any people, just labeling
  521. while (ktditer.hasNext()) {
  522. ktd = (KinTermDef) ktditer.next();
  523. kinTerm = ktd.kinTerm;
  524. suppressPrint = false;
  525. for (int i = 0; i < ktd.flags.size(); i++) {
  526. if (nonTermFlags.contains(ktd.flags.get(i))) {
  527. suppressPrint = true;
  528. }
  529. }
  530. if (!(nonTerms.contains(kinTerm) || suppressPrint)) {
  531. Iterator defiter = ktd.expandedDefs.iterator();
  532. while (defiter.hasNext()) {
  533. cb = (ClauseBody) defiter.next();
  534. if (!(cb.genderOfAlter.equals("?"))) {
  535. cb.fillInNames(ego, kinTerm);
  536. }
  537. } // end of for each expanded definition
  538. } // end of if-not-convenience-kinterm
  539. } // end of for-each-kinTermDef
  540. } // end of method fillInNames
  541. /**
  542. Create a GEDCOM file containing hypothetical people who illustrate each definition of each kinTerm
  543. in this Domain Theory.
  544. @param fileName the filename to create in GEDCOM format.
  545. @param sex the gender of Ego in the hypothetical population
  546. @throws KSBadHornClauseException if a clause is encountered for which it cannot create an example
  547. @throws JavaSystemException if Java throws a run-time exception
  548. @throws KSInternalErrorException if an internal processing activity occurs
  549. @throws KSConstraintInconsistency if the constraints on a person (imposed by the literals in a clause)
  550. are inconsistent. For example: male(X) and female(X).
  551. @throws KSNoChainOfRelations2Alter if a clause is encountered with no "path" from Ego to Alter via its literals.
  552. For example: 'foo(Alter,Ego) :- parent(P,Ego), child(Alter,Q).' is wrong.
  553. But 'foo(Alter,Ego) :- parent(P,Ego), sibling(P,Q), child(Alter,Q).' is OK.
  554. */
  555. public void makeExampleGEDCOMFile(String fileName, String sex)
  556. throws KSBadHornClauseException, JavaSystemException, KSInternalErrorException, KSConstraintInconsistency,
  557. KSNoChainOfRelations2Alter, ClassNotFoundException {
  558. makeExampleGEDCOMFile(fileName, sex, Context.current, null);
  559. } // end of makeExampleGEDCOMFile with 2 args
  560. /**
  561. Create a GEDCOM file containing hypothetical people who illustrate each definition of each kinTerm
  562. in this Domain Theory.
  563. @param fileName the filename to create in GEDCOM format.
  564. @param sex the gender of Ego in the hypothetical population
  565. @param hypo the hypothetical context.
  566. @param options If it contains 'theory' then a file will be written with a full expansion of this
  567. domain theory and some diagnostic information. If it contains 'census' then a printable
  568. listing of all Individuals and Families will be written to a file.
  569. @throws KSBadHornClauseException if a clause is encountered for which it cannot create an example
  570. @throws JavaSystemException if Java throws a run-time exception
  571. @throws KSInternalErrorException if an internal processing activity occurs
  572. @throws KSConstraintInconsistency if the constraints on a person (imposed by the literals in a clause)
  573. are inconsistent. For example: male(X) and female(X).
  574. @throws KSNoChainOfRelations2Alter if a clause is encountered with no "path" from Ego to Alter via its literals.
  575. For example: 'foo(Alter,Ego) :- parent(P,Ego), child(Alter,Q).' is wrong.
  576. But 'foo(Alter,Ego) :- parent(P,Ego), sibling(P,Q), child(Alter,Q).' is OK.
  577. */
  578. public void makeExampleGEDCOMFile(String fileName, String sex, Context hypo, String options)
  579. throws KSBadHornClauseException, JavaSystemException, KSInternalErrorException, KSConstraintInconsistency,
  580. KSNoChainOfRelations2Alter, ClassNotFoundException {
  581. try {
  582. PrintWriter outFile = new PrintWriter(new BufferedWriter(new FileWriter(fileName)));
  583. addrTerms = addressTerms;
  584. current = (DomainTheory) this;
  585. KinTermDef ktd;
  586. ArrayList<Object> egoBag = maleAndFemaleCreatedHeThem();
  587. Collection values = theory.values();
  588. Iterator iter = values.iterator(); // each value is a KinTermDef
  589. boolean suppressPrint, selectedKinTerm, selectAll = false;
  590. if (hypo.selectedKinTerms == null) {
  591. selectAll = true;
  592. }
  593. // If the term selection list is empty, select all terms; else, pick only those in the list.
  594. // Terms deemed 'non_terms' in the domain theory (or those with non_term Flags) are NEVER printed
  595. ArrayList<Object> round2 = new ArrayList<Object>();
  596. while (iter.hasNext()) {
  597. ktd = (KinTermDef) iter.next();
  598. if (ktd.expandedDefs == null || ktd.expandedDefs.isEmpty()) // Std Macros are already expanded
  599. {
  600. ktd.expandClauses(hypo);
  601. }
  602. suppressPrint = false;
  603. for (int i = 0; i < ktd.flags.size(); i++) {
  604. if (nonTermFlags.contains(ktd.flags.get(i))) {
  605. suppressPrint = true;
  606. }
  607. }
  608. if ((!(nonTerms.contains(ktd.kinTerm) || suppressPrint))
  609. && (selectAll || (Context.current.selectedKinTerms.contains(ktd.kinTerm)))) {
  610. if (ktd.hasDelayFlags()) {
  611. round2.add(ktd);
  612. } else {
  613. ktd.generateExamples(hypo, egoBag, null);
  614. }
  615. }
  616. } // end of while hasNext()
  617. MainPane.fill_In_Flag = true;
  618. for (int j = 0; j < round2.size(); j++) { // in Round 2, process delayed-ID terms
  619. ktd = (KinTermDef) round2.get(j);
  620. ktd.generateExamples(hypo, egoBag, null);
  621. }
  622. MainPane.fill_In_Flag = false;
  623. Individual ego;
  624. for (int i = 0; i < egoBag.size(); i++) {
  625. ego = (Individual) egoBag.get(i);
  626. fillInNames(ego);
  627. }
  628. hypo.exportGEDCOM(outFile, fileName, "Include");
  629. outFile.flush();
  630. outFile.close();
  631. if (options != null) {
  632. int stop = fileName.lastIndexOf("/") + 1;
  633. String pathname = fileName.substring(0, stop);
  634. int bodyStop = fileName.lastIndexOf(".");
  635. if (bodyStop < stop + 1) {
  636. bodyStop = fileName.length();
  637. }
  638. String fileBodyName = fileName.substring(stop, bodyStop);
  639. if (options.indexOf("theory") >= 0) {
  640. String theoryFile = pathname + fileBodyName + ".thy", addRef = "reference";
  641. PrintWriter thyFile = new PrintWriter(new BufferedWriter(new FileWriter(theoryFile)));
  642. if (addressTerms) {
  643. addRef = "address";
  644. }
  645. hypo.printTheory(thyFile, addRef);
  646. System.out.println(" ");
  647. System.out.println("\n * * * * * * * * * * * * * * * * * *");
  648. System.out.println(" Domain Theory File was created.");
  649. System.out.println(" * * * * * * * * * * * * * * * * * *");
  650. } // end of theory-option-is-invoked
  651. if (options.indexOf("census") >= 0) {
  652. String censusFile = pathname + languageName + ".cen";
  653. PrintWriter cenFile = new PrintWriter(new BufferedWriter(new FileWriter(censusFile)));
  654. hypo.printCensus(cenFile);
  655. System.out.println(" ");
  656. System.out.println("\n * * * * * * * * * * * * * *");
  657. System.out.println(languageName + " Census File was created.");
  658. System.out.println(" * * * * * * * * * * * * * *");
  659. } // end of theory-option-is-invoked
  660. } // end of options-isn't-null
  661. } catch (IOException e) {
  662. throw new JavaSystemException("DomainTheory File Creation failed:\n" + e);
  663. } // end of catch block
  664. return;
  665. } // end of method makeExampleGEDCOMFile
  666. public static ArrayList<Object> harvestLeaves(TreeMap tree) {
  667. // gather leaves from TreeMaps with sub-trees as TreeMaps or ALists
  668. ArrayList<Object> bag = new ArrayList<Object>();
  669. if (tree == null) {
  670. return bag;
  671. }
  672. Iterator topIter = tree.values().iterator();
  673. while (topIter.hasNext()) {
  674. Object level2 = topIter.next();
  675. if (level2 instanceof TreeMap) {
  676. bag.addAll(harvestLeaves((TreeMap) level2));
  677. } else if (level2 instanceof ArrayList) {
  678. bag.addAll((ArrayList<Object>) level2);
  679. }
  680. }
  681. return bag;
  682. } // end of method harvestLeaves
  683. public static int countLeaves(TreeMap tree) {
  684. // designed to work on TreeMaps with sub-trees as TreeMaps or ALists
  685. // if the subtree contains Nodes, count each node as 1 item
  686. if (tree == null) {
  687. return 0;
  688. }
  689. int leafCnt = 0;
  690. Iterator topIter = tree.values().iterator();
  691. while (topIter.hasNext()) {
  692. Object level2 = topIter.next();
  693. if (level2 instanceof TreeMap) {
  694. leafCnt += countLeaves((TreeMap) level2);
  695. } else if (level2 instanceof ArrayList) {
  696. leafCnt += ((ArrayList<Object>) level2).size();
  697. } else if (level2 instanceof Node) {
  698. leafCnt++;
  699. }
  700. }
  701. return leafCnt;
  702. } // end of method countLeaves
  703. public Dyad makeExampleDyad(ClauseBody cb, Context workingCtxt, ArrayList<Object> egoBag) throws KSBadHornClauseException,
  704. KSInternalErrorException, KSConstraintInconsistency, ClassNotFoundException {
  705. Context oldCurrent = Context.current;
  706. Context.current = workingCtxt;
  707. if (egoBag == null) {
  708. egoBag = maleAndFemaleCreatedHeThem();
  709. }
  710. Dyad dyad = new Dyad((Individual) egoBag.get(0));
  711. dyad.pcString = cb.pcString;
  712. dyad.pcStringStructural = cb.pcStringStructural;
  713. cb.unifyVariables();
  714. MainPane.fill_In_Flag = true;
  715. cb.generateExamples(workingCtxt, egoBag, dyad, null); // ego & alter will be set by CB.genExamples
  716. MainPane.fill_In_Flag = false;
  717. Context.current = oldCurrent;
  718. return dyad;
  719. } // end of method makeExampleDyad()
  720. public boolean notFound(int seqNmbr, ArrayList<Object> cbList) {
  721. // cbList contains CB_Ptrs. If one has cbSeqNmbr = SeqNmbr, return false.
  722. // else, return true.
  723. for (int i = 0; i < cbList.size(); i++) {
  724. if (((Library.CB_Ptr) cbList.get(i)).cbSeqNmbr == seqNmbr) {
  725. return false;
  726. }
  727. }
  728. return true;
  729. } // end of method notFound
  730. public boolean found(int seqNmbr, ArrayList<Object> cbList) {
  731. return !notFound(seqNmbr, cbList);
  732. }
  733. public boolean foundInSigStr(String sigString, String pcStr) {
  734. // Standard Macros (e.g. sister) don't have a sigString, and are not what we're looking for.
  735. if (sigString == null) {
  736. return false;
  737. }
  738. String embeddedStr = "_" + pcStr + "_";
  739. if (sigString.indexOf(embeddedStr) > -1) {
  740. return true; // found in the middle
  741. }
  742. int stop = Math.min(pcStr.length(), sigString.length());
  743. if (pcStr.equals(sigString.substring(0, stop))) {
  744. return true; // found up front
  745. }
  746. int start = sigString.lastIndexOf("_");
  747. if (start > -1 && pcStr.equals(sigString.substring(start + 1))) {
  748. return true; // found at end
  749. }
  750. return false;
  751. } // end of method foundInSigStr
  752. public boolean equivalentLists(ArrayList<Object> list1, ArrayList<Object> list2) {
  753. if (list1.size() != list2.size()) {
  754. return false;
  755. }
  756. for (int i = 0; i < list1.size(); i++) {
  757. if (!list2.contains(list1.get(i))) {
  758. return false;
  759. }
  760. }
  761. return true;
  762. } // end of method equivalentLists
  763. public boolean isSupersetOf(ArrayList<Object> list1, ArrayList<Object> list2) {
  764. // Return true if list1 contains all of list2, IN ANY ORDER
  765. if (list2.isEmpty()) {
  766. return false; // Don't want trivial supersets of nil
  767. }
  768. for (int i = 0; i < list2.size(); i++) {
  769. Object obj = list2.get(i);
  770. if (!list1.contains(obj)) {
  771. return false;
  772. }
  773. }
  774. return true;
  775. } // end of method isSupersetOf
  776. public String[] genKTDarray(String first) {
  777. int extra = ((first == null || first.equals("")) ? 0 : 1);
  778. String[] lst = new String[theory.size() + extra];
  779. Iterator ktdIter = theory.keySet().iterator();
  780. if (extra == 1) {
  781. lst[0] = first;
  782. }
  783. for (int i = extra; i < theory.size() + extra; i++) {
  784. lst[i] = (String) ktdIter.next();
  785. }
  786. return lst;
  787. } // end of method genKTDarray
  788. public class ScoreObj implements Comparable, Serializable {
  789. String pcString;
  790. double weight;
  791. public ScoreObj() {
  792. } // default constructor for serialization.
  793. public ScoreObj(String pcStr, double wt) {
  794. pcString = pcStr;
  795. weight = wt;
  796. } // end of normal constructor
  797. /** Provide a method of comparing 2 ScoreObjs for use in TreeMaps and TreeSets. */
  798. public int compareTo(Object obj) throws ClassCastException {
  799. // Sort order = weight, then pcString length.
  800. if (obj == null) {
  801. return -1;
  802. }
  803. ScoreObj other = (ScoreObj) obj;
  804. if (weight < other.weight) {
  805. return -1;
  806. }
  807. if (weight > other.weight) {
  808. return 1;
  809. }
  810. if (pcString.length() < other.pcString.length()) {
  811. return -1;
  812. }
  813. if (pcString.length() > other.pcString.length()) {
  814. return 1;
  815. }
  816. return 0;
  817. } // end of compareTo method; required for the Comparable interface
  818. } // end of inner class ScoreObj
  819. public abstract boolean fit(ClauseBody cb, Dyad dad) throws KSBadHornClauseException, KSNoChainOfRelations2Alter,
  820. KSInternalErrorException, KSConstraintInconsistency, ClassNotFoundException;
  821. }