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 }