Use ordinal pre-sorting rather than on-the-fly compares
[sbp.git] / src / edu / berkeley / sbp / Reduction.java
1 // Copyright 2006 all rights reserved; see LICENSE file for BSD-style license
2
3 package edu.berkeley.sbp;
4 import edu.berkeley.sbp.*;
5 import edu.berkeley.sbp.util.*;
6 import edu.berkeley.sbp.Parser.Table.*;
7 import edu.berkeley.sbp.Sequence.Position;
8 import java.io.*;
9 import java.util.*;
10 import java.lang.reflect.*;
11
12 final class Reduction implements Comparable<Reduction> {
13
14     public Position position;
15     public GSS.Phase phase;
16     public Forest result;
17     public Node node;
18     boolean done = false;
19     
20     public Reduction(Node node, Position position, Forest result, GSS.Phase target) {
21         this.position = position;
22         this.result = result;
23         this.phase = target;
24         this.node = node;
25         target.reductionQueue.add(this);
26     }
27
28     public void perform() {
29         if (done) return;
30         done = true;
31         node.finish(position, result, phase);
32     }
33
34     public int compareTo(Reduction r) {
35         int ret = compareTo0(r);
36         if (ret != 0) return -1 * ret;
37         return (position.ord - r.position.ord);
38     }
39
40     private static boolean isRightNullable(Walk.Cache c, Position p) {
41         if (p.isLast()) return true;
42         if (!c.possiblyEpsilon(p.element())) return false;
43         return isRightNullable(c, p.next());
44     }
45
46     public static boolean canKill(Walk.Cache cache, Position mep, Position himp) {
47         if (!isRightNullable(cache, mep))  return false;
48         if (!isRightNullable(cache, himp)) return false;
49         Sequence me  = mep.owner();
50         Sequence him = himp.owner();
51         Boolean b = me.canKill.get(him);
52         if (b!=null) return b;
53         for(Sequence killer : him.hates()) {
54             HashSet<Sequence> eq2 = new Walk.EquivalentTo(killer, cache).walk();
55             if (eq2.contains(me)) { me.canKill.put(him, true); return true; }
56         }
57         me.canKill.put(him, false);
58         return false;
59     }
60
61     public static final int LESS_THAN = -1;
62     public static final int EQUAL_TO = 0;
63     public static final int GREATER_THAN = 1;
64
65     public int compareTo0(Reduction n) {
66         if (targetPhase()==null && n.targetPhase()==null) return EQUAL_TO;
67         if (targetPhase()==null) return LESS_THAN;
68         if (n.targetPhase()==null) return GREATER_THAN;
69         if (targetPhase().pos < n.targetPhase().pos) return LESS_THAN;
70         if (targetPhase().pos > n.targetPhase().pos) return GREATER_THAN;
71         return 0;
72     }
73     public int pos() { return targetPhase()==null ? 0 : targetPhase().pos; }
74     public GSS.Phase targetPhase() { return node.phase(); }
75
76     public static boolean canNeed(Walk.Cache cache, Position mep, Position himp) {
77         if (!isRightNullable(cache, mep))  return false;
78         if (!isRightNullable(cache, himp)) return false;
79         Sequence me  = mep.owner();
80         Sequence him = himp.owner();
81         Boolean b = me.canNeed.get(him);
82         if (b!=null) return b;
83         for(Sequence needer : him.needs()) {
84             HashSet<Sequence> eq2 = new Walk.EquivalentTo(needer, cache).walk();
85             if (eq2.contains(me)) { me.canNeed.put(him, true); return true; }
86         }
87         me.canNeed.put(him, false);
88         return false;
89     }
90 }