001 /* 002 * The contents of this file are subject to the Mozilla Public 003 * License Version 1.1 (the "License"); you may not use this file 004 * except in compliance with the License. You may obtain a copy of 005 * the License at http://www.mozilla.org/MPL/ 006 * 007 * Software distributed under the License is distributed on an "AS 008 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or 009 * implied. See the License for the specific language governing 010 * rights and limitations under the License. 011 * 012 * The Original Code is Knowtator. 013 * 014 * The Initial Developer of the Original Code is University of Colorado. 015 * Copyright (C) 2005 - 2008. All Rights Reserved. 016 * 017 * Knowtator was developed by the Center for Computational Pharmacology 018 * (http://compbio.uchcs.edu) at the University of Colorado Health 019 * Sciences Center School of Medicine with support from the National 020 * Library of Medicine. 021 * 022 * Current information about Knowtator can be obtained at 023 * http://knowtator.sourceforge.net/ 024 * 025 * Contributor(s): 026 * Philip V. Ogren <philip@ogren.info> (Original Author) 027 * Angus Roberts 028 * 029 */ 030 031 /** 032 * Changes 033 * 2/8/2007 ar fixed recursive infinite loop bug in copyMention 034 * 8/11/2005 pvo added isComplexSlotMention, getComplexMentionSlotValues (2 versions) 035 * getComplexSlotMentions 036 * 037 * 11/19/2005 pvo Added copyMention() method 038 * added documentation for supporting methods. 039 * Refactored a few existing methods. Mostly added code for "null" conditions and javadocs. 040 */ 041 042 package edu.uchsc.ccp.knowtator; 043 044 import java.util.ArrayList; 045 import java.util.Collection; 046 import java.util.HashSet; 047 import java.util.List; 048 import java.util.Map; 049 import java.util.Set; 050 051 import org.apache.log4j.Logger; 052 053 import edu.stanford.smi.protege.model.Cls; 054 import edu.stanford.smi.protege.model.Frame; 055 import edu.stanford.smi.protege.model.Instance; 056 import edu.stanford.smi.protege.model.KnowledgeBase; 057 import edu.stanford.smi.protege.model.SimpleInstance; 058 import edu.stanford.smi.protege.model.Slot; 059 import edu.stanford.smi.protege.model.ValueType; 060 import edu.stanford.smi.protege.util.CollectionUtilities; 061 062 public class MentionUtil { 063 KnowtatorProjectUtil kpu; 064 065 KnowledgeBase kb; 066 067 AnnotationUtil annotationUtil; 068 069 Logger logger = Logger.getLogger(KnowtatorManager.class); 070 071 /** Creates a new instance of MentionUtil */ 072 public MentionUtil(KnowtatorProjectUtil kpu) { 073 this.kpu = kpu; 074 this.kb = kpu.kb; 075 } 076 077 public void setAnnotationUtil(AnnotationUtil annotationUtil) { 078 this.annotationUtil = annotationUtil; 079 } 080 081 /* 082 * Compares two mentions to see if they are exactly the same including 083 * (recursively) the slot mention values. If the values of two slot mentions 084 * are the same but in a different order, then true is returned. 085 * 086 * @param compareAnnotationSpans indicate whether the corresponding 087 * annotations of the mentions must have the same spans for the mentions to 088 * be considered equal. 089 */ 090 public boolean equals(SimpleInstance mention1, SimpleInstance mention2, boolean compareAnnotationSpans) { 091 // return false if either mention (or both) is null. 092 if (mention1 == null || mention2 == null) 093 return false; 094 // The two mentions must be the same type 095 if (!mention1.getDirectType().equals(mention2.getDirectType())) 096 return false; 097 098 if (compareAnnotationSpans) { 099 if (!isSlotMention(mention1) && !compareAnnotationSpans(mention1, mention2)) 100 return false; 101 } 102 103 // if both mentions are class mentions 104 if (isClassMention(mention1) && isClassMention(mention2)) { 105 Cls mentionedCls1 = getMentionCls(mention1); 106 Cls mentionedCls2 = getMentionCls(mention2); 107 if (mentionedCls1 == null && mentionedCls2 == null) 108 return compareSlotMentions(mention1, mention2, compareAnnotationSpans); 109 if (mentionedCls1 == null || mentionedCls2 == null) 110 return false; 111 // return false if the mentioned classes are different 112 if (!mentionedCls1.equals(mentionedCls2)) 113 return false; 114 return compareSlotMentions(mention1, mention2, compareAnnotationSpans); 115 } 116 if (isInstanceMention(mention1) && isInstanceMention(mention2)) { 117 Instance mentionedInstance1 = getMentionInstance(mention1); 118 Instance mentionedInstance2 = getMentionInstance(mention2); 119 if (mentionedInstance1 == null && mentionedInstance2 == null) 120 return compareSlotMentions(mention1, mention2, compareAnnotationSpans); 121 if (mentionedInstance1 == null || mentionedInstance2 == null) 122 return false; 123 // return false if the mentioned classes are different 124 if (!mentionedInstance1.equals(mentionedInstance2)) 125 return false; 126 return compareSlotMentions(mention1, mention2, compareAnnotationSpans); 127 } 128 if (isSlotMention(mention1) && isSlotMention(mention2)) { 129 Slot mentionedSlot1 = getSlotMentionSlot(mention1); 130 Slot mentionedSlot2 = getSlotMentionSlot(mention2); 131 List<Object> slotValues1 = getSlotMentionValues(mention1); 132 List<Object> slotValues2 = getSlotMentionValues(mention2); 133 134 if (mentionedSlot1 == null && mentionedSlot2 == null) 135 return false; 136 if (!mentionedSlot1.equals(mentionedSlot2)) 137 return false; 138 if (slotValues1.size() == 0 && slotValues2.size() == 0) 139 return true; 140 if (slotValues1.size() != slotValues2.size()) 141 return false; 142 143 // This is the only "tricky" code in the method. The values of the 144 // two slot mentions are not 145 // required to be in the same order. The brute force approach was 146 // used to simplify the code and 147 // because it is assumed that few slot mentions will have many 148 // values (usually 1). 149 // For each slot value of mention1 it is assumed that there is no 150 // match until one is found from 151 // the other list of values. If each value is matched then we can 152 // return true. 153 for (Object slotValue1 : slotValues1) { 154 boolean matchedSlotValue = false; 155 for (Object slotValue2 : slotValues2) { 156 if (compareSlotValues(slotValue1, slotValue2, compareAnnotationSpans)) { 157 matchedSlotValue = true; 158 break; 159 } 160 } 161 if (!matchedSlotValue) 162 return false; 163 } 164 return true; 165 } 166 167 return false; 168 } 169 170 private boolean compareSlotValues(Object value1, Object value2, boolean compareAnnotationSpans) { 171 if (value1 instanceof SimpleInstance && value2 instanceof SimpleInstance) { 172 return equals((SimpleInstance) value1, (SimpleInstance) value2, compareAnnotationSpans); 173 } else 174 return value1.equals(value2); 175 } 176 177 private boolean compareSlotMentions(SimpleInstance mention1, SimpleInstance mention2, boolean compareAnnotationSpans) { 178 List<SimpleInstance> slotMentions1 = getSlotMentions(mention1); 179 List<SimpleInstance> slotMentions2 = getSlotMentions(mention2); 180 181 for (SimpleInstance slotMention1 : slotMentions1) { 182 Slot mentionedSlot = getSlotMentionSlot(slotMention1); 183 List<Object> slotMention1Values = getSlotMentionValues(slotMention1); 184 SimpleInstance slotMention2 = getSlotMention(mention2, mentionedSlot); 185 if (slotMention2 == null && slotMention1Values.size() == 0) 186 continue; 187 // return false if the two slot mentions for the slot are not equal 188 if (!equals(slotMention1, slotMention2, compareAnnotationSpans)) 189 return false; 190 } 191 for (SimpleInstance slotMention2 : slotMentions2) { 192 Slot mentionedSlot = getSlotMentionSlot(slotMention2); 193 List<Object> slotMention2Values = getSlotMentionValues(slotMention2); 194 SimpleInstance slotMention1 = getSlotMention(mention1, mentionedSlot); 195 if (slotMention1 == null && slotMention2Values.size() == 0) 196 continue; 197 // return false if the two slot mentions for the slot are not equal 198 if (!equals(slotMention1, slotMention2, compareAnnotationSpans)) 199 return false; 200 } 201 return true; 202 } 203 204 private boolean compareAnnotationSpans(SimpleInstance mention1, SimpleInstance mention2) { 205 SimpleInstance annotation1 = getMentionAnnotation(mention1); 206 if (annotation1 == null) 207 return false; 208 209 SimpleInstance annotation2 = getMentionAnnotation(mention2); 210 if (annotation2 == null) 211 return false; 212 213 return annotationUtil.compareSpans(annotation1, annotation2); 214 } 215 216 /** 217 * 218 * @param mention 219 * @param copiesMap 220 * @return TODO simplify the signature. 221 */ 222 public SimpleInstance copyMention(SimpleInstance mention, Map<SimpleInstance, SimpleInstance> copiesMap) { 223 if (copiesMap != null && copiesMap.containsKey(mention)) 224 return copiesMap.get(mention); 225 226 if (isMention(mention)) { 227 SimpleInstance mentionCopy = kb.createSimpleInstance(null, null, CollectionUtilities 228 .createCollection(mention.getDirectType()), true); 229 if (copiesMap != null) 230 copiesMap.put(mention, mentionCopy); 231 232 // Cls mentionType = mentionCopy.getDirectType(); 233 234 if (isClassMention(mention)) { 235 Cls mentionCls = getMentionCls(mention); 236 if (mentionCls != null) 237 setMentionCls(mentionCopy, mentionCls); 238 } else if (isInstanceMention(mention)) { 239 SimpleInstance mentionInstance = getMentionInstance(mention); 240 if (mentionInstance != null) 241 setMentionInstance(mentionCopy, mentionInstance); 242 } 243 244 if (isClassMention(mention) || isInstanceMention(mention)) { 245 List<SimpleInstance> slotMentions = getSlotMentions(mention); 246 for (SimpleInstance slotMention : slotMentions) { 247 addSlotMention(mentionCopy, copyMention(slotMention, copiesMap)); 248 } 249 } else if (isSlotMention(mention)) { 250 Slot mentionSlot = getSlotMentionSlot(mention); 251 setMentionSlot(mentionCopy, mentionSlot); 252 List<Object> slotValues = getSlotMentionValues(mention); 253 for (Object slotValue : slotValues) { 254 if (slotValue instanceof SimpleInstance) 255 addValueToSlotMention(mentionCopy, copyMention((SimpleInstance) slotValue, copiesMap)); 256 else 257 addValueToSlotMention(mentionCopy, slotValue); 258 } 259 } 260 return mentionCopy; 261 } 262 return null; 263 } 264 265 public SimpleInstance createClassMention(Cls cls) { 266 SimpleInstance clsMention = kb.createSimpleInstance(null, null, CollectionUtilities 267 .createCollection(kpu.classMentionCls), true); 268 // if(cls != null) 269 // { 270 clsMention.setOwnSlotValue(kpu.mentionClassSlot, cls); 271 // } 272 return clsMention; 273 } 274 275 public SimpleInstance createInstanceMention(SimpleInstance simpleInstance) { 276 SimpleInstance instanceMention = kb.createSimpleInstance(null, null, CollectionUtilities 277 .createCollection(kpu.instanceMentionCls), true); 278 instanceMention.setOwnSlotValue(kpu.mentionInstanceSlot, simpleInstance); 279 return instanceMention; 280 } 281 282 /** 283 * This method adds a slotMention to a class or instance mention. Please 284 * refer to the knowtator model in knowtator.pprj and look at the class 285 * definition for "knowtator class mention". This method adds a value to the 286 * slot 'knowtator_slot_mention'. 287 * 288 * @see #addValueToSlotMention(SimpleInstance, Object) 289 */ 290 291 public void addSlotMention(SimpleInstance mention, SimpleInstance slotMention) { 292 if ((isClassMention(mention) || isInstanceMention(mention)) && isSlotMention(slotMention)) { 293 mention.addOwnSlotValue(kpu.getSlotMentionSlot(), slotMention); 294 } 295 } 296 297 /** 298 * This method adds a value to a slotMention. Please refer to the knowtator 299 * model in knowtator.pprj and look at the class definition for "knowtator 300 * slot mention". This method adds a value to the slot 301 * 'knowtator_mention_slot_value'. 302 * 303 * @param slotMention 304 * must be an instance of a slot mention 305 * @param slotValue 306 * can be a class mention, instance mention, or an Integer, 307 * Float, String or Boolean. 308 */ 309 310 public void addValueToSlotMention(SimpleInstance slotMention, Object slotValue) { 311 if (isComplexSlotMention(slotMention)) { 312 if (slotValue instanceof SimpleInstance) { 313 SimpleInstance slotValueInstance = (SimpleInstance) slotValue; 314 if (isClassMention(slotValueInstance) || isInstanceMention(slotValueInstance)) { 315 slotMention.addOwnSlotValue(kpu.getMentionSlotValueSlot(), slotValueInstance); 316 } 317 } 318 } else if (isSlotMention(slotMention)) { 319 slotMention.addOwnSlotValue(kpu.getMentionSlotValueSlot(), slotValue); 320 } 321 } 322 323 public void removeValueFromSlotMention(SimpleInstance slotMention, Object slotValue) { 324 if (isSlotMention(slotMention)) { 325 slotMention.removeOwnSlotValue(kpu.getMentionSlotValueSlot(), slotValue); 326 } 327 } 328 329 public SimpleInstance createSlotMention(Slot slot) { 330 ValueType slotType = slot.getValueType(); 331 Cls instanceType = kpu.stringSlotMentionCls; 332 if (slotType == ValueType.CLS || slotType == ValueType.INSTANCE) 333 instanceType = kpu.complexSlotMentionCls; 334 else if (slotType == ValueType.BOOLEAN) 335 instanceType = kpu.booleanSlotMentionCls; 336 else if (slotType == ValueType.FLOAT) 337 instanceType = kpu.floatSlotMentionCls; 338 else if (slotType == ValueType.INTEGER) 339 instanceType = kpu.integerSlotMentionCls; 340 341 SimpleInstance slotMention = kb.createSimpleInstance(null, null, CollectionUtilities 342 .createCollection(instanceType), true); 343 slotMention.setOwnSlotValue(kpu.mentionSlotSlot, slot); 344 return slotMention; 345 } 346 347 /** 348 * Creates a mention based on the passed in instance. Instance is the super 349 * interface for Cls, SimpleInstance and Slot. Depending on the Class of the 350 * passed instance, the return value will be a "class mention", "instance 351 * mention" or "slot mention". 352 * 353 * @param instance 354 * should be Cls, SimpleInstance or Slot 355 * @return null - if instance is not a Cls, SimpleInstance or Slot. 356 * Otherwise, returns a "class mention", "instance mention", or 357 * "slot mention" 358 */ 359 360 public SimpleInstance createMention(Instance instance) { 361 if (instance instanceof Cls) 362 return createClassMention((Cls) instance); 363 else if (instance instanceof SimpleInstance) 364 return createInstanceMention((SimpleInstance) instance); 365 else if (instance instanceof Slot) 366 return createSlotMention((Slot) instance); 367 return null; 368 } 369 370 public boolean isClassMention(SimpleInstance mention) { 371 if (mention == null) 372 return false; 373 // return mention.getDirectType().equals(kpu.classMentionCls); 374 return mention.hasType(kpu.classMentionCls); 375 } 376 377 public boolean isInstanceMention(SimpleInstance mention) { 378 if (mention == null) 379 return false; 380 // return mention.getDirectType().equals(kpu.instanceMentionCls); 381 return mention.hasType(kpu.instanceMentionCls); 382 383 } 384 385 public boolean isMention(SimpleInstance mention) { 386 if (mention == null) 387 return false; 388 return mention.hasType(kpu.mentionCls); 389 } 390 391 public boolean isSlotMention(SimpleInstance mention) { 392 if (mention == null) 393 return false; 394 if (mention.hasType(kpu.slotMentionCls) || mention.hasType(kpu.complexSlotMentionCls) 395 || mention.hasType(kpu.booleanSlotMentionCls) || mention.hasType(kpu.floatSlotMentionCls) 396 || mention.hasType(kpu.integerSlotMentionCls) || mention.hasType(kpu.stringSlotMentionCls)) 397 return true; 398 399 return false; 400 } 401 402 public boolean isBooleanSlotMention(SimpleInstance mention) { 403 if (mention == null) 404 return false; 405 if (mention.hasType(kpu.booleanSlotMentionCls)) 406 return true; 407 return false; 408 } 409 410 public boolean isFloatSlotMention(SimpleInstance mention) { 411 if (mention == null) 412 return false; 413 if (mention.hasType(kpu.floatSlotMentionCls)) 414 return true; 415 return false; 416 } 417 418 public boolean isIntegerSlotMention(SimpleInstance mention) { 419 if (mention == null) 420 return false; 421 if (mention.hasType(kpu.integerSlotMentionCls)) 422 return true; 423 return false; 424 } 425 426 public boolean isStringSlotMention(SimpleInstance mention) { 427 if (mention == null) 428 return false; 429 if (mention.hasType(kpu.stringSlotMentionCls)) 430 return true; 431 return false; 432 } 433 434 public boolean isSimpleSlotMention(SimpleInstance mention) { 435 if (mention == null) 436 return false; 437 if (isStringSlotMention(mention) || isIntegerSlotMention(mention) || isFloatSlotMention(mention) 438 || isBooleanSlotMention(mention)) 439 return true; 440 else 441 return false; 442 } 443 444 /** 445 * Determines whether an instance is a complex slot mention. Please refer to 446 * the knowtator model in knowtator.pprj and look at the class definition 447 * for "knowtator complex slot mention". If the instance is of type 448 * "knowtator complex slot mention" of one of its descendants, then true is 449 * returned. 450 * 451 * @return true if the instance is of type "knowtator complex slot mention". 452 */ 453 454 public boolean isComplexSlotMention(SimpleInstance mention) { 455 if (mention == null) 456 return false; 457 Cls mentionType = mention.getDirectType(); 458 if (mentionType == null) 459 return false; 460 if (mentionType.equals(kpu.complexSlotMentionCls) || mentionType.hasSuperclass(kpu.complexSlotMentionCls)) { 461 return true; 462 } 463 return false; 464 } 465 466 /** 467 * This method gathers all the mentions (e.g. slot mentions, class mentions 468 * and instance mentions) that are connected to the passed in mention. 469 * Connections are directed and start from the passed in mention and are 470 * found recursively via slot mentions. For example, if a class mention is 471 * passed in, then its slot mentions, the mention values of the slot 472 * mentions, and their slot mentions (and so on) will all be in the returned 473 * set. The returned set does not parallel the structure of the 474 * relationships between the mentions - it simply gathers them up and dumps 475 * in the returned set. The returned set contains the mention that is passed 476 * to the method. 477 * 478 * 479 * @param mention 480 * should be a Protege instance of mention. 481 * @return if mention is not a Protege instance of mention, then an empty 482 * set will be returned. Otherwise, the set will contain the passed 483 * in mention and all mentions (class, instance, and slot) that it 484 * is connected to (see above.) 485 */ 486 public Set<SimpleInstance> getAllConnectedMentions(SimpleInstance mention) { 487 Set<SimpleInstance> mentions = new HashSet<SimpleInstance>(); 488 if (isMention(mention)) { 489 mentions.add(mention); 490 _getAllConnectedMentions(mention, mentions); 491 } 492 return mentions; 493 } 494 495 private void _getAllConnectedMentions(SimpleInstance mention, Set<SimpleInstance> mentions) { 496 if (isClassMention(mention) || isInstanceMention(mention)) { 497 List<SimpleInstance> slotMentions = getSlotMentions(mention); 498 for (SimpleInstance slotMention : slotMentions) { 499 if (!mentions.contains(slotMention)) { 500 mentions.add(slotMention); 501 _getAllConnectedMentions(slotMention, mentions); 502 } 503 } 504 } 505 if (isSlotMention(mention)) { 506 List<Object> slotValues = getSlotMentionValues(mention); 507 for (Object slotValue : slotValues) { 508 if (slotValue instanceof SimpleInstance) { 509 if (isMention((SimpleInstance) slotValue)) { 510 if (!mentions.contains(slotValue)) { 511 mentions.add((SimpleInstance) slotValue); 512 _getAllConnectedMentions((SimpleInstance) slotValue, mentions); 513 } 514 } 515 } 516 } 517 } 518 } 519 520 /** 521 * This method returns all class mentions or instance mentions related to 522 * the passed in mention via slot mentions. 523 * 524 * This method returns all of the complex slot mention values for a class 525 * mention or instance mention. Please refer to the knowtator model in 526 * knowtator.pprj and look at the class definition for "knowtator class 527 * mention" or "knowtator instance mention". The values of the slot 528 * "knowtator_slot_mention" may be of type "knowtator complex slot mention". 529 * Values of the slot "knowtator_mention_slot_value" for values of the 530 * passed in mentions values of the slot "knowtator_slot_mention" are 531 * returned. 532 * 533 * @param mention 534 * should be of type 'knowtator class mention' or 'knowtator 535 * instance mention'. 536 * @return the slot mention values of the mention's slot mentions. All 537 * values in the returned list should be of type 'knowtator class 538 * mention' or 'knowtator instance mention'. This method will return 539 * an empty list if there are no related mentions or if the mention 540 * is not a class mention or instance mention. 541 */ 542 public List<SimpleInstance> getRelatedMentions(SimpleInstance mention) { 543 List<SimpleInstance> returnValues = new ArrayList<SimpleInstance>(); 544 545 if (isClassMention(mention) || isInstanceMention(mention)) { 546 List<SimpleInstance> complexSlotMentions = getComplexSlotMentions(mention); 547 for (SimpleInstance complexSlotMention : complexSlotMentions) { 548 Collection<SimpleInstance> mentionSlotValues = (Collection<SimpleInstance>) complexSlotMention 549 .getOwnSlotValues(kpu.getMentionSlotValueSlot()); 550 if (mentionSlotValues != null) 551 returnValues.addAll(mentionSlotValues); 552 } 553 } 554 return returnValues; 555 } 556 557 /** 558 * This method returns all class mentions or instance mentions related to 559 * the passed in mention via slot mentions whose mentioned slot is the 560 * passed in slot. 561 * 562 * Please refer to the knowtator model in knowtator.pprj and look at the 563 * class definition for "knowtator class mention" or "knowtator instance 564 * mention". The values of the slot "knowtator_slot_mention" may be of type 565 * "knowtator complex slot mention". Values of the slot 566 * "knowtator_mention_slot_value" for values of the passed in mention's 567 * values of the slot "knowtator_slot_mention" are returned if the slot 568 * mention's "knowtator_mention_slot" is the same as the passed in slot. 569 * 570 * @param mention 571 * should be of type 'knowtator class mention' or 'knowtator 572 * instance mention'. 573 * @param slot 574 * a slot corresponding to a knowtator_mention_slot of a 575 * 'knowtator complex slot mention' 576 * 577 * @return All values in the returned list should be of type 'knowtator 578 * class mention' or 'knowtator instance mention'. This method will 579 * return an empty list if there are no related mentions or if the 580 * mention is not a class mention or instance mention. 581 */ 582 public List<SimpleInstance> getRelatedMentions(SimpleInstance mention, Slot slot) { 583 List<SimpleInstance> returnValues = new ArrayList<SimpleInstance>(); 584 if (isClassMention(mention) || isInstanceMention(mention)) { 585 SimpleInstance slotMention = getSlotMention(mention, slot); 586 if (isComplexSlotMention(slotMention)) { 587 Collection<SimpleInstance> values = (Collection<SimpleInstance>) slotMention.getOwnSlotValues(kpu 588 .getMentionSlotValueSlot()); 589 returnValues.addAll(values); 590 } 591 } 592 return returnValues; 593 } 594 595 public Frame getMentionFrame(SimpleInstance mention) { 596 if (mention == null) 597 return null; 598 if (isClassMention(mention)) { 599 return (Cls) mention.getOwnSlotValue(kpu.mentionClassSlot); 600 } else if (isInstanceMention(mention)) { 601 return (Instance) mention.getOwnSlotValue(kpu.mentionInstanceSlot); 602 } 603 return null; 604 } 605 606 /** 607 * If the mention is a "class mention" then the Cls corresponding to the 608 * mentioned class is returned. If the mention is a "instance mention" then 609 * the Cls corresponding to the direct type of the mentioned instance is 610 * returned. 611 * 612 * @return the class of a class mention, or the direct type of the instance 613 * of an instance mention or null if the class or instance no longer 614 * exists 615 */ 616 617 public Cls getMentionCls(SimpleInstance mention) { 618 if (isClassMention(mention)) { 619 return (Cls) mention.getOwnSlotValue(kpu.mentionClassSlot); 620 } else if (isInstanceMention(mention)) { 621 Instance mentionInstance = (Instance) mention.getOwnSlotValue(kpu.mentionInstanceSlot); 622 if (mentionInstance != null) 623 return mentionInstance.getDirectType(); 624 } 625 return null; 626 } 627 628 /** 629 * This method sets the cls that is mentioned by a class mention. Please 630 * refer to the knowtator model in knowtator.pprj and look at the class 631 * definition for "knowtator class mention". This method sets the value for 632 * the slot "knowtator_mention_class". 633 * 634 * @param clsMention 635 * the mention must be a class mention or this method does 636 * nothing 637 * @param mentionCls 638 * the class that is mentioned by the instance mention 639 */ 640 public void setMentionCls(SimpleInstance clsMention, Cls mentionCls) { 641 if (isClassMention(clsMention)) { 642 clsMention.setDirectOwnSlotValue(kpu.getMentionClassSlot(), mentionCls); 643 } 644 } 645 646 /** 647 * This method sets the instance that is mentioned by an instance mention. 648 * Please refer to the knowtator model in knowtator.pprj and look at the 649 * class definition for "knowtator instance mention". This method sets the 650 * value for the slot "knowtator_mention_instance". 651 * 652 * @param instanceMention 653 * the mention must be an instance mention or this method does 654 * nothing 655 * @param mentionInstance 656 * the instance that is mentioned by the instance mention 657 */ 658 public void setMentionInstance(SimpleInstance instanceMention, SimpleInstance mentionInstance) { 659 if (isInstanceMention(instanceMention)) { 660 instanceMention.setDirectOwnSlotValue(kpu.getMentionInstanceSlot(), mentionInstance); 661 } 662 } 663 664 /** 665 * This method sets the slot that is mentioned by a slot mention. Please 666 * refer to the knowtator model in knowtator.pprj and look at the class 667 * definition for "knowtator slot mention". This method sets the value for 668 * the slot "knowtator_mention_slot". 669 * 670 * @param slotMention 671 * the mention must be a slot mention or this method does nothing 672 * @param mentionSlot 673 * the slot that is mentioned by the slot mention 674 */ 675 public void setMentionSlot(SimpleInstance slotMention, Slot mentionSlot) { 676 if (isSlotMention(slotMention)) { 677 slotMention.setDirectOwnSlotValue(kpu.getMentionSlotSlot(), mentionSlot); 678 } 679 } 680 681 public SimpleInstance getMentionInstance(SimpleInstance instanceMention) { 682 if (isInstanceMention(instanceMention)) { 683 return (SimpleInstance) instanceMention.getOwnSlotValue(kpu.mentionInstanceSlot); 684 } 685 return null; 686 } 687 688 /** 689 * This method gets the slot mentions of a class mention or instance 690 * mention. Please refer to the knowtator model in knowtator.pprj and look 691 * at the class definition for "knowtator class mention" or "knowtator 692 * instance mention". This method returns the values of the slot 693 * "knowtator_slot_mention". 694 * 695 * @param mention 696 * must be a class mention or instance mention otherwise an empty 697 * list will be returned 698 * @return all slot mentions for the mention. If none exist, then an empty 699 * list will be returned. 700 */ 701 public List<SimpleInstance> getSlotMentions(SimpleInstance mention) { 702 List<SimpleInstance> returnValues = new ArrayList<SimpleInstance>(); 703 if (isClassMention(mention) || isInstanceMention(mention)) { 704 Collection<SimpleInstance> slotMentions = (Collection<SimpleInstance>) mention.getDirectOwnSlotValues(kpu 705 .getSlotMentionSlot()); 706 if (slotMentions != null) { 707 returnValues.addAll(slotMentions); 708 } 709 } 710 return returnValues; 711 } 712 713 /** 714 * This method gets the complex slot mentions of a class mention or instance 715 * mention. Please refer to the knowtator model in knowtator.pprj and look 716 * at the class definition for "knowtator class mention" or "knowtator 717 * instance mention". This method returns the values of the slot 718 * "knowtator_slot_mention" that are of type "knowtator complex slot 719 * mention". 720 * 721 * @param mention 722 * should be a class mention or instance mention; 723 * @return all complex slot mentions for the mention. If none exist, then an 724 * empty list will be returned. 725 */ 726 public List<SimpleInstance> getComplexSlotMentions(SimpleInstance mention) { 727 List<SimpleInstance> returnValues = new ArrayList<SimpleInstance>(); 728 if (isClassMention(mention) || isInstanceMention(mention)) { 729 List<SimpleInstance> allSlotMentions = getSlotMentions(mention); 730 for (SimpleInstance slotMention : allSlotMentions) { 731 if (isComplexSlotMention(slotMention)) { 732 returnValues.add(slotMention); 733 } 734 } 735 } 736 return returnValues; 737 } 738 739 public List<Slot> getMentionSlots(SimpleInstance mention) { 740 Collection<Slot> slots = null; 741 if (isClassMention(mention)) { 742 Cls mentionCls = getMentionCls(mention); 743 if (mentionCls != null) 744 slots = (Collection<Slot>) mentionCls.getTemplateSlots(); 745 } else if (isInstanceMention(mention)) { 746 Instance mentionInstance = getMentionInstance(mention); 747 if (mentionInstance != null) { 748 slots = mentionInstance.getOwnSlots(); 749 slots.remove(kb.getSlot(":DIRECT-TYPE")); 750 slots.remove(kb.getSlot(":NAME")); 751 } 752 } 753 if (slots != null) { 754 return new ArrayList<Slot>(slots); 755 } else 756 return new ArrayList<Slot>(); 757 } 758 759 /** 760 * gets a slot mention for the given slot of a class mention or instance 761 * mention. Please refer to the knowtator model in knowtator.pprj and look 762 * at the class definition for "knowtator class mention" or "knowtator 763 * instance mention". This method returns the values of the slot 764 * "knowtator_slot_mention" that correspond to the passed in slot. 765 * 766 * @param mention 767 * must be a class mention or instance mention otherwise null 768 * will be returned. 769 * @param mentionSlot 770 * the "knowtator_mention_slot" of the slot mention. 771 * @return an instance of 'knowtator slot mention' or one of its subtypes or 772 * null if none exist. 773 */ 774 775 // what if there are two slot mentions with the same slot? editor does not 776 // allow it but 777 // knowtator model does. 778 public SimpleInstance getSlotMention(SimpleInstance mention, Slot mentionSlot) { 779 if (mentionSlot == null) 780 return null; 781 List<SimpleInstance> slotMentions = getSlotMentions(mention); 782 for (SimpleInstance slotMention : slotMentions) { 783 if (mentionSlot.equals(getSlotMentionSlot(slotMention))) { 784 return slotMention; 785 } 786 } 787 return null; 788 } 789 790 public boolean hasSlotMention(SimpleInstance mention, Slot mentionSlot) { 791 SimpleInstance slotMention = getSlotMention(mention, mentionSlot); 792 if (slotMention != null) 793 return true; 794 return false; 795 } 796 797 public boolean hasSlotValue(SimpleInstance slotMention) { 798 if (isSlotMention(slotMention)) { 799 Object value = slotMention.getOwnSlotValue(kpu.mentionSlotValueSlot); 800 if (value != null) { 801 return true; 802 } 803 } 804 return false; 805 } 806 807 /** 808 * this method takes a mention and initializes slot mentions for slots that 809 * do not yet have a slotMention for the mention. 810 */ 811 812 public void initializeSlotMentions(SimpleInstance mention) { 813 List<Slot> mentionSlots = getMentionSlots(mention); 814 List<SimpleInstance> slotMentions = new ArrayList<SimpleInstance>(getSlotMentions(mention)); 815 for (Slot mentionSlot : mentionSlots) { 816 if (!hasSlotMention(mention, mentionSlot)) { 817 slotMentions.add(createSlotMention(mentionSlot)); 818 } 819 } 820 if (slotMentions.size() > 0) { 821 mention.setOwnSlotValues(kpu.slotMentionSlot, slotMentions); 822 } 823 } 824 825 public void removeEmptySlotMentions(SimpleInstance mention) { 826 List<SimpleInstance> slotMentions = new ArrayList(getSlotMentions(mention)); 827 List<SimpleInstance> deletedMentions = new ArrayList<SimpleInstance>(); 828 for (SimpleInstance slotMention : slotMentions) { 829 Object value = slotMention.getOwnSlotValue(kpu.mentionSlotValueSlot); 830 if (value == null) { 831 deletedMentions.add(slotMention); 832 } 833 } 834 slotMentions.removeAll(deletedMentions); 835 mention.setOwnSlotValues(kpu.slotMentionSlot, slotMentions); 836 for (Instance slotMention : deletedMentions) { 837 kb.deleteInstance(slotMention); 838 } 839 } 840 841 public void deleteMention(SimpleInstance mention) { 842 List<SimpleInstance> slotMentions = getSlotMentions(mention); 843 for (SimpleInstance slotMention : slotMentions) { 844 kb.deleteInstance(slotMention); 845 } 846 kb.deleteInstance(mention); 847 848 } 849 850 public SimpleInstance getMentionAnnotation(SimpleInstance mention) { 851 SimpleInstance mentionAnnotation = (SimpleInstance) mention.getOwnSlotValue(kpu.getMentionAnnotationSlot()); 852 return mentionAnnotation; 853 } 854 855 public void setMentionAnnotations(SimpleInstance mention, Collection<SimpleInstance> annotations) { 856 mention.setOwnSlotValues(kpu.mentionAnnotationSlot, annotations); 857 } 858 859 public Slot getSlotMentionSlot(SimpleInstance mention) { 860 if (isSlotMention(mention)) { 861 return (Slot) mention.getOwnSlotValue(kpu.mentionSlotSlot); 862 } else 863 return null; 864 } 865 866 public List<Object> getSlotMentionValues(SimpleInstance slotMention) { 867 List<Object> returnValues = new ArrayList<Object>(); 868 if (isSlotMention(slotMention)) { 869 Collection<Object> values = (Collection<Object>) slotMention 870 .getOwnSlotValues(kpu.getMentionSlotValueSlot()); 871 if (values != null) { 872 returnValues.addAll(values); 873 } 874 } 875 return returnValues; 876 } 877 878 public void setSlotMentionValues(SimpleInstance slotMention, List<Object> values) { 879 if (isSlotMention(slotMention)) { 880 slotMention.setOwnSlotValues(kpu.getMentionSlotValueSlot(), values); 881 } 882 } 883 884 public SimpleInstance getMentionedBy(SimpleInstance slotMention) { 885 if (isSlotMention(slotMention)) { 886 return (SimpleInstance) slotMention.getOwnSlotValue(kpu.mentionedInSlot); 887 } 888 return null; 889 } 890 891 /** 892 * This method was written and contributed by Angus Roberts. 893 * 894 * This method takes a mention slot with a known value on an annotation 895 * mention, and adds an inverse slot on the value, with the annotation 896 * mentions as its valu. If the inverse slot does not exist, it is added. 897 * Given annotationMention--[mentionSlot]--mentionSlotValueMention, the 898 * method will add 899 * mentionSlotValueMention--[inverse_of_mentionSlot]--annotationMention 900 * 901 * @param annotationMention 902 * an annotation mention with a mention slot 903 * @param mentionSlot 904 * a slot, the inverse of which will be added 905 * @param mentionSlotValueMention 906 * the value of that will be added to mentionSlot 907 */ 908 909 public void addInverse(SimpleInstance annotationMention, Slot mentionSlot, SimpleInstance mentionSlotValueMention) { 910 Slot inverse = mentionSlot.getInverseSlot(); 911 if (inverse != null) { 912 SimpleInstance inverseSlotMention = getSlotMention(mentionSlotValueMention, inverse); 913 if (inverseSlotMention != null) { 914 // The mentionSlotValueMention already has this inverse slot 915 addValueToSlotMention(inverseSlotMention, annotationMention); 916 } else { 917 // It doesn't have this inverse slot, add it 918 inverseSlotMention = createSlotMention(inverse); 919 addValueToSlotMention(inverseSlotMention, annotationMention); 920 addSlotMention(mentionSlotValueMention, inverseSlotMention); 921 } // end of else 922 } // end of if () 923 } 924 925 /** 926 * This method was written and contributed by Angus Roberts. 927 * 928 * This method takes a mention slot with a known value on an annotation 929 * mention, and checks for an inverse slot on the value. If the inverse 930 * exists, it is removed. Given 931 * annotationMention--[mentionSlot]--mentionSlotValueMention, the method 932 * will remove 933 * mentionSlotValueMention--[inverse_of_mentionSlot]--annotationMention 934 * 935 * @param annotationMention 936 * an annotation mention with a mention slot 937 * @param mentionSlot 938 * a slot, the inverse of which will be removed 939 * @param mentionSlotValueMention 940 * the value of mentionSlot 941 */ 942 943 public void removeInverse(SimpleInstance annotationMention, Slot mentionSlot, SimpleInstance mentionSlotValueMention) { 944 Slot inverse = mentionSlot.getInverseSlot(); 945 if (inverse != null) { 946 SimpleInstance inverseSlotMention = getSlotMention(mentionSlotValueMention, inverse); 947 if (inverseSlotMention != null) 948 removeValueFromSlotMention(inverseSlotMention, annotationMention); 949 } // end of if () 950 } 951 952 public List<SimpleInstance> getSlotFillerCandidates(SimpleInstance mention, Slot slot, 953 List<SimpleInstance> annotations) { 954 Set<SimpleInstance> currentSlotValues = new HashSet<SimpleInstance>(getRelatedMentions(mention, slot)); 955 956 List<SimpleInstance> returnValues = new ArrayList<SimpleInstance>(); 957 958 Cls mentionCls = getMentionCls(mention); 959 if (mentionCls == null) 960 return returnValues; 961 962 HashSet<Cls> allowedClses = new HashSet<Cls>((Collection<Cls>) mentionCls.getTemplateSlotAllowedClses(slot)); 963 964 for (SimpleInstance annotation : annotations) { 965 if (annotation.isDeleted()) 966 continue; 967 968 SimpleInstance annotationMention = annotationUtil.getMention(annotation); 969 if (currentSlotValues.contains(annotationMention)) 970 continue; 971 972 if (isInstanceMention(annotationMention)) { 973 SimpleInstance annotatedInstance = getMentionInstance(annotationMention); 974 if (mentionCls.isValidOwnSlotValue(slot, annotatedInstance)) { 975 returnValues.add(annotation); 976 } 977 } else if (isClassMention(annotationMention)) { 978 Cls annotatedCls = getMentionCls(annotationMention); 979 980 if (slot.getValueType().equals(ValueType.INSTANCE)) { 981 HashSet<Cls> annotatedClsAncestors = new HashSet<Cls>((Collection<Cls>) annotatedCls 982 .getSuperclasses()); 983 annotatedClsAncestors.add(annotatedCls); 984 985 annotatedClsAncestors.retainAll(allowedClses); 986 if (annotatedClsAncestors.size() > 0) { 987 returnValues.add(annotation); 988 } 989 } 990 if (slot.getValueType().equals(ValueType.CLS)) { 991 HashSet annotatedClsAncestors = new HashSet(annotatedCls.getSuperclasses()); 992 allowedClses.retainAll(annotatedClsAncestors); 993 if (allowedClses.size() > 0) { 994 returnValues.add(annotation); 995 } 996 } 997 } 998 } 999 return returnValues; 1000 } 1001 1002 public void adjustSlotMentionForCardinality(Cls cls, Slot slot, SimpleInstance mention) { 1003 int maxCardinality = cls.getTemplateSlotMaximumCardinality(slot); 1004 if (maxCardinality > 0) { 1005 SimpleInstance slotMention = getSlotMention(mention, slot); 1006 if (slotMention != null) { 1007 List<Object> slotValues = getSlotMentionValues(slotMention); 1008 List<Object> newValues = new ArrayList<Object>(); 1009 for (int i = slotValues.size() - 1, j = 0; i >= 0 && j < maxCardinality; i--) { 1010 newValues.add(slotValues.get(i)); 1011 j++; 1012 } 1013 setSlotMentionValues(slotMention, newValues); 1014 } 1015 } 1016 } 1017 1018 }