char rcsid_trim[] = "$Id$"; #include #include "b.h" #include "fe.h" Relation *allpairs; int trimflag = 0; int debugTrim = 0; static void siblings ARGS((int, int)); static void findAllNexts ARGS((void)); static Relation *newAllPairs ARGS((void)); static void siblings(i, j) int i; int j; { int k; List pl; DeltaCost Max; int foundmax; allpairs[i][j].sibComputed = 1; if (i == 1) { return; /* never trim start symbol */ } if (i==j) { return; } ZEROCOST(Max); foundmax = 0; for (k = 1; k < max_nonterminal; k++) { DeltaCost tmp; if (k==i || k==j) { continue; } if (!allpairs[k][i].rule) { continue; } if (!allpairs[k][j].rule) { return; } ASSIGNCOST(tmp, allpairs[k][j].chain); MINUSCOST(tmp, allpairs[k][i].chain); if (foundmax) { if (LESSCOST(Max, tmp)) { ASSIGNCOST(Max, tmp); } } else { foundmax = 1; ASSIGNCOST(Max, tmp); } } for (pl = rules; pl; pl = pl->next) { Rule p = (Rule) pl->x; Operator op = p->pat->op; List oprule; DeltaCost Min; int foundmin; if (!op) { continue; } switch (op->arity) { case 0: continue; case 1: if (!allpairs[p->pat->children[0]->num ][ i].rule) { continue; } foundmin = 0; for (oprule = op->table->rules; oprule; oprule = oprule->next) { Rule s = (Rule) oprule->x; DeltaPtr Cx; DeltaPtr Csj; DeltaPtr Cpi; DeltaCost tmp; if (!allpairs[p->lhs->num ][ s->lhs->num].rule || !allpairs[s->pat->children[0]->num ][ j].rule) { continue; } Cx = allpairs[p->lhs->num ][ s->lhs->num].chain; Csj= allpairs[s->pat->children[0]->num ][ j].chain; Cpi= allpairs[p->pat->children[0]->num ][ i].chain; ASSIGNCOST(tmp, Cx); ADDCOST(tmp, s->delta); ADDCOST(tmp, Csj); MINUSCOST(tmp, Cpi); MINUSCOST(tmp, p->delta); if (foundmin) { if (LESSCOST(tmp, Min)) { ASSIGNCOST(Min, tmp); } } else { foundmin = 1; ASSIGNCOST(Min, tmp); } } if (!foundmin) { return; } if (foundmax) { if (LESSCOST(Max, Min)) { ASSIGNCOST(Max, Min); } } else { foundmax = 1; ASSIGNCOST(Max, Min); } break; case 2: /* do first dimension */ if (allpairs[p->pat->children[0]->num ][ i].rule) { foundmin = 0; for (oprule = op->table->rules; oprule; oprule = oprule->next) { Rule s = (Rule) oprule->x; DeltaPtr Cx; DeltaPtr Cb; DeltaPtr Csj; DeltaPtr Cpi; DeltaCost tmp; if (allpairs[p->lhs->num ][ s->lhs->num].rule && allpairs[s->pat->children[0]->num ][ j].rule && allpairs[s->pat->children[1]->num ][ p->pat->children[1]->num].rule) { Cx = allpairs[p->lhs->num ][ s->lhs->num].chain; Csj= allpairs[s->pat->children[0]->num ][ j].chain; Cpi= allpairs[p->pat->children[0]->num ][ i].chain; Cb = allpairs[s->pat->children[1]->num ][ p->pat->children[1]->num].chain; ASSIGNCOST(tmp, Cx); ADDCOST(tmp, s->delta); ADDCOST(tmp, Csj); ADDCOST(tmp, Cb); MINUSCOST(tmp, Cpi); MINUSCOST(tmp, p->delta); if (foundmin) { if (LESSCOST(tmp, Min)) { ASSIGNCOST(Min, tmp); } } else { foundmin = 1; ASSIGNCOST(Min, tmp); } } } if (!foundmin) { return; } if (foundmax) { if (LESSCOST(Max, Min)) { ASSIGNCOST(Max, Min); } } else { foundmax = 1; ASSIGNCOST(Max, Min); } } /* do second dimension */ if (allpairs[p->pat->children[1]->num ][ i].rule) { foundmin = 0; for (oprule = op->table->rules; oprule; oprule = oprule->next) { Rule s = (Rule) oprule->x; DeltaPtr Cx; DeltaPtr Cb; DeltaPtr Csj; DeltaPtr Cpi; DeltaCost tmp; if (allpairs[p->lhs->num ][ s->lhs->num].rule && allpairs[s->pat->children[1]->num ][ j].rule && allpairs[s->pat->children[0]->num ][ p->pat->children[0]->num].rule) { Cx = allpairs[p->lhs->num ][ s->lhs->num].chain; Csj= allpairs[s->pat->children[1]->num ][ j].chain; Cpi= allpairs[p->pat->children[1]->num ][ i].chain; Cb = allpairs[s->pat->children[0]->num ][ p->pat->children[0]->num].chain; ASSIGNCOST(tmp, Cx); ADDCOST(tmp, s->delta); ADDCOST(tmp, Csj); ADDCOST(tmp, Cb); MINUSCOST(tmp, Cpi); MINUSCOST(tmp, p->delta); if (foundmin) { if (LESSCOST(tmp, Min)) { ASSIGNCOST(Min, tmp); } } else { foundmin = 1; ASSIGNCOST(Min, tmp); } } } if (!foundmin) { return; } if (foundmax) { if (LESSCOST(Max, Min)) { ASSIGNCOST(Max, Min); } } else { foundmax = 1; ASSIGNCOST(Max, Min); } } break; default: assert(0); } } allpairs[i ][ j].sibFlag = foundmax; ASSIGNCOST(allpairs[i ][ j].sibling, Max); } static void findAllNexts() { int i,j; int last; for (i = 1; i < max_nonterminal; i++) { last = 0; for (j = 1; j < max_nonterminal; j++) { if (allpairs[i ][j].rule) { allpairs[i ][ last].nextchain = j; last = j; } } } /* for (i = 1; i < max_nonterminal; i++) { last = 0; for (j = 1; j < max_nonterminal; j++) { if (allpairs[i ][j].sibFlag) { allpairs[i ][ last].nextsibling = j; last = j; } } } */ } static Relation * newAllPairs() { int i; Relation *rv; rv = (Relation*) zalloc(max_nonterminal * sizeof(Relation)); for (i = 0; i < max_nonterminal; i++) { rv[i] = (Relation) zalloc(max_nonterminal * sizeof(struct relation)); } return rv; } void findAllPairs() { List pl; int changes; int j; allpairs = newAllPairs(); for (pl = chainrules; pl; pl = pl->next) { Rule p = (Rule) pl->x; NonTerminalNum rhs = p->pat->children[0]->num; NonTerminalNum lhs = p->lhs->num; Relation r = &allpairs[lhs ][ rhs]; if (LESSCOST(p->delta, r->chain)) { ASSIGNCOST(r->chain, p->delta); r->rule = p; } } for (j = 1; j < max_nonterminal; j++) { Relation r = &allpairs[j ][ j]; ZEROCOST(r->chain); r->rule = &stub_rule; } changes = 1; while (changes) { changes = 0; for (pl = chainrules; pl; pl = pl->next) { Rule p = (Rule) pl->x; NonTerminalNum rhs = p->pat->children[0]->num; NonTerminalNum lhs = p->lhs->num; int i; for (i = 1; i < max_nonterminal; i++) { Relation r = &allpairs[rhs ][ i]; Relation s = &allpairs[lhs ][ i]; DeltaCost dc; if (!r->rule) { continue; } ASSIGNCOST(dc, p->delta); ADDCOST(dc, r->chain); if (!s->rule || LESSCOST(dc, s->chain)) { s->rule = p; ASSIGNCOST(s->chain, dc); changes = 1; } } } } findAllNexts(); } void trim(t) Item_Set t; { int m,n; static short *vec = 0; int last; assert(!t->closed); debug(debugTrim, printf("Begin Trim\n")); debug(debugTrim, dumpItem_Set(t)); last = 0; if (!vec) { vec = (short*) zalloc(max_nonterminal * sizeof(*vec)); } for (m = 1; m < max_nonterminal; m++) { if (t->virgin[m].rule) { vec[last++] = m; } } for (m = 0; m < last; m++) { DeltaCost tmp; int j; int i; i = vec[m]; for (j = allpairs[i ][ 0].nextchain; j; j = allpairs[i ][ j].nextchain) { if (i == j) { continue; } if (!t->virgin[j].rule) { continue; } ASSIGNCOST(tmp, t->virgin[j].delta); ADDCOST(tmp, allpairs[i ][ j].chain); if (!LESSCOST(t->virgin[i].delta, tmp)) { t->virgin[i].rule = 0; ZEROCOST(t->virgin[i].delta); debug(debugTrim, printf("Trimmed Chain (%d,%d)\n", i,j)); goto outer; } } if (!trimflag) { continue; } for (n = 0; n < last; n++) { j = vec[n]; if (i == j) { continue; } if (!t->virgin[j].rule) { continue; } if (!allpairs[i][j].sibComputed) { siblings(i,j); } if (!allpairs[i][j].sibFlag) { continue; } ASSIGNCOST(tmp, t->virgin[j].delta); ADDCOST(tmp, allpairs[i ][ j].sibling); if (!LESSCOST(t->virgin[i].delta, tmp)) { t->virgin[i].rule = 0; ZEROCOST(t->virgin[i].delta); goto outer; } } outer: ; } debug(debugTrim, dumpItem_Set(t)); debug(debugTrim, printf("End Trim\n")); } void dumpRelation(r) Relation r; { printf("{ %d %ld %d %ld }", r->rule->erulenum, (long) r->chain, r->sibFlag, (long) r->sibling); } void dumpAllPairs() { int i,j; printf("Dumping AllPairs\n"); for (i = 1; i < max_nonterminal; i++) { for (j = 1; j < max_nonterminal; j++) { dumpRelation(&allpairs[i ][j]); } printf("\n"); } }