3 static void extendsplits(void) {
5 * Whenever we have a node which has one or more moveable feature
6 * subsegments, part of the same moveable feature, on one side, and
7 * fixed portion of the same segment on the other, we eliminate
8 * the fixed portion and add its length to both the moveables,
9 * so that we have one subsegspec for the whole of each position:
11 * <---l---> <----l'---> <---------(l+l')------>
13 * *----A1---*----A1/P0--* becomes *--------A1/P0----------*
14 * `---A1/P1---* `-------A1/P1-----------*
16 * <----l''---> <---------(l+l'')------>
21 for (node=nodes_head; node; node=node->next) {
22 for (rightside=0; rightside<2; rightside++) {
23 trace("extendsplit pass %d node ",pass); trace_node(node);
24 trace("/%d ",rightside);
25 if ((n= count_edges(&node->sides[!rightside])) != 1) {
26 trace("no: lhs edges=%d\n", n);
29 leftedge= node->sides[!rightside].head;
30 if (leftedge->edge->movfeatpos) {
31 trace("no: lhs moveable\n");
34 if (!node->sides[rightside].head) {
35 trace("no: rhs absent\n");
38 for (rightedge= node->sides[rightside].head;
40 rightedge= rightedge->next) {
41 if (!rightedge->edge->movfeatpos) {
42 trace("no: rhs fixed ("); trace_edgeend(rightedge); trace(")\n");
45 if (strcmp(leftedge->edge->segment, rightedge->edge->segment)) {
46 trace("no: lhs seg %s, rhs seg %s (",
47 leftedge->edge->segment
48 rightedge->edge->segment);
49 trace_edgeend(rightedge); trace(")\n");
61 trace("yes, lhs "); trace_edgeend(leftedge); trace(":\n");
62 for (rightedge= node->sides[rightside].head;
64 rightedge= rightedge->next) {
65 rightedge->edge->distance += leftedge->edge->distance;
66 edge_replumb(rightedge, edgeend_otherend(leftedge)->node);
68 edge_delete(leftedge->edge);
69 node_surely_orphaned(node);
70 trace(" extendsplit operation complete\n");
74 static EdgeEnd *edgeend_otherend(EdgeEnd *thisend) {
75 return &thisend->edge->ends[!thisend->end];
78 static void elimtrivial(void) {
79 /* Eliminate trivial nodes: ones which have only two edges, which
80 * come in on opposite sides, have the same subsegspec, and with the
81 * two ends identically aligned.
83 for (node=nodes_head; node; node=next_node) {
85 trace("elimtrivial node "); trace_node(node); trace(" ");
86 if (!(count_edges(&node->sides[0])==1 &&
87 count_edges(&node->sides[1])==1)) {
88 trace("no, a non-unitary side\n");
91 leftedge= node->sides[0].head;
92 rightedge= node->sides[0].head;
93 if (strcmp(leftedge->edge.segment,rightedge->edge.segment)) {
94 trace("no, segments differ\n");
97 if (!!leftedge->edge.movfeatpos != !!rightedge->edge.movfeatpos ||
98 strcmp(leftedge->edge.movfeatpos, rightedge->edge.movfeatpos)) {
99 trace("no, movfeatpos's differ\n");
102 if (leftedge->end == rightedge->end) {
103 trace("no, opposite alignment\n");
107 rightedge->edge->distance += leftedge->edge->distance;
108 edge_replumb(rightedge, edgeend_otherend(leftedge)->node);
109 edge_delete(leftedge->edge);
110 node_surely_orphaned(node);
111 trace(" elimtrivial operation complete\n");