Пример #1
0
 /**
  * Add a type to the slice at a given position, possibly changing the endpoints of some descendant
  * intervals.
  *
  * @param type the type to add to the slice
  * @param position a type already in the slice before which the new type will be placed, <code>
  *     null</code> if the type should be placed at the end of the slice
  * @param ancestors the new type's ancestors
  * @return the event for the endpoint changes, though there might be none
  */
 protected EndpointsChangedEvent add(Constant type, Constant position, Set<Constant> ancestors) {
   EndpointsChangedEvent event = new EndpointsChangedEvent(this, type);
   order.add(type, position);
   int typeLambda = lambdas.get(position), positionLambda = typeLambda;
   Set<Constant> reducedAncestors = new HashSet<Constant>(ancestors);
   for (Map.Entry<Constant, Interval<Constant>> entry : descendentIntervals.entrySet()) {
     Interval<Constant> value = entry.getValue();
     if (reducedAncestors.remove(entry.getKey())) {
       if (value.getMin() == position) {
         ++positionLambda;
         value.setMin(type);
         event.addMinChange(entry.getKey());
       }
       if (value.getMax() == position) {
         ++typeLambda;
       }
     } else if (value.getMax() == position) {
       value.setMax(type);
       event.addMaxChange(entry.getKey());
     }
   }
   descendentIntervals.put(type, new Interval<Constant>(order, type, position));
   for (Constant ancestor : reducedAncestors) {
     descendentIntervals.put(ancestor, new Interval<Constant>(order, type, position));
   }
   lambdas.put(type, typeLambda);
   lambdas.put(position, positionLambda);
   return event;
 }
Пример #2
0
 /**
  * Attempt to add a type to the slice, possibly changing the endpoints of some descendant
  * intervals.
  *
  * @param type the type to add to the slice
  * @param ancestors the new type's ancestors
  * @return if the addition was successful, the event for the endpoint changes, though there might
  *     be none; if the addition failed, <code>null</code>
  */
 public EndpointsChangedEvent add(Constant type, Set<Constant> ancestors) {
   Interval<Constant> common = asInterval();
   for (Constant ancestor : ancestors) {
     Interval<Constant> mask = descendentIntervals.get(ancestor);
     if (mask != null) {
       common.intersect(mask);
     }
   }
   // empty is okay, as long as we still have location
   if (order.compare(common.getMin(), common.getMax()) > 0) {
     return null;
   }
   int surroundMin = 0, surroundMax = 0;
   for (Constant ancestor : ancestors) {
     Interval<Constant> range = descendentIntervals.get(ancestor);
     if (range != null) {
       if (order.compare(range.getMin(), common.getMin()) < 0
           && order.compare(range.getMax(), common.getMin()) > 0) {
         ++surroundMin;
       }
       if (order.compare(range.getMin(), common.getMax()) < 0
           && order.compare(range.getMax(), common.getMax()) > 0) {
         ++surroundMax;
       }
     }
   }
   if (lambdas.get(common.getMin()) == surroundMin) {
     return add(type, common.getMin(), ancestors);
   }
   if (lambdas.get(common.getMax()) == surroundMax) {
     return add(type, common.getMax(), ancestors);
   }
   //// fast slicing: don't check between min and max
   return null;
 }
Пример #3
0
 /**
  * Construct a slice with a single element.
  *
  * @param type the element of the new slice
  * @param ancestors its ancestors
  */
 public Slice(Constant type, Set<Constant> ancestors) {
   order.add(type, null);
   descendentIntervals.put(type, new Interval<Constant>(order, type, null));
   for (Constant ancestor : ancestors) {
     descendentIntervals.put(ancestor, new Interval<Constant>(order, type, null));
   }
   lambdas.put(type, 0);
   lambdas.put(null, 0);
 }