this.result = result;
this.phase = target;
this.node = node;
+ target.reductionQueue.add(this);
}
public void perform() {
node.finish(position, result, phase);
}
- public String toString() { return position+""; }
-
public int compareTo(Reduction r) {
int ret = compareTo0(r);
- if (ret == 0) {
- Walk.Cache cache = node.state().cache();
- if (canKill(cache, position, r.position) && canKill(cache, r.position, position)) throw new Error();
- if (canKill(cache, position, r.position)) ret = 1;
- else if (canKill(cache, r.position, position)) ret = -1;
- if (canNeed(cache, position, r.position)) ret = 1;
- else if (canNeed(cache, r.position, position)) ret = -1;
- }
- return -1 * ret;
+ if (ret != 0) return -1 * ret;
+ return (position.ord - r.position.ord);
}
- private boolean isRightNullable(Walk.Cache c, Position p) {
+ private static boolean isRightNullable(Walk.Cache c, Position p) {
if (p.isLast()) return true;
if (!c.possiblyEpsilon(p.element())) return false;
return isRightNullable(c, p.next());
}
- public boolean canKill(Walk.Cache cache, Position mep, Position himp) {
+ public static boolean canKill(Walk.Cache cache, Position mep, Position himp) {
if (!isRightNullable(cache, mep)) return false;
if (!isRightNullable(cache, himp)) return false;
Sequence me = mep.owner();
Sequence him = himp.owner();
+ Boolean b = me.canKill.get(him);
+ if (b!=null) return b;
for(Sequence killer : him.hates()) {
HashSet<Sequence> eq2 = new Walk.EquivalentTo(killer, cache).walk();
- if (eq2.contains(me)) return true;
+ if (eq2.contains(me)) { me.canKill.put(him, true); return true; }
}
+ me.canKill.put(him, false);
return false;
}
public int pos() { return targetPhase()==null ? 0 : targetPhase().pos; }
public GSS.Phase targetPhase() { return node.phase(); }
- public boolean canNeed(Walk.Cache cache, Position mep, Position himp) {
+ public static boolean canNeed(Walk.Cache cache, Position mep, Position himp) {
if (!isRightNullable(cache, mep)) return false;
if (!isRightNullable(cache, himp)) return false;
Sequence me = mep.owner();
Sequence him = himp.owner();
+ Boolean b = me.canNeed.get(him);
+ if (b!=null) return b;
for(Sequence needer : him.needs()) {
HashSet<Sequence> eq2 = new Walk.EquivalentTo(needer, cache).walk();
- if (eq2.contains(me)) return true;
+ if (eq2.contains(me)) { me.canNeed.put(him, true); return true; }
}
+ me.canNeed.put(him, false);
return false;
}
}