char rcsid_table[] = "$Id: table.c,v 1.1 1998-12-17 06:36:49 fur%netscape.com Exp $"; #include "b.h" #include #include static void growIndex_Map ARGS((Index_Map *)); static Relevant newRelevant ARGS((void)); static Dimension newDimension ARGS((Operator, int)); static void GT_1 ARGS((Table)); static void GT_2_0 ARGS((Table)); static void GT_2_1 ARGS((Table)); static void growTransition ARGS((Table, int)); static Item_Set restrict ARGS((Dimension, Item_Set)); static void addHP_1 ARGS((Table, Item_Set)); static void addHP_2_0 ARGS((Table, Item_Set)); static void addHP_2_1 ARGS((Table, Item_Set)); static void addHyperPlane ARGS((Table, int, Item_Set)); static void growIndex_Map(r) Index_Map *r; { Index_Map new; new.max_size = r->max_size + STATES_INCR; new.class = (Item_Set*) zalloc(new.max_size * sizeof(Item_Set)); assert(new.class); memcpy(new.class, r->class, r->max_size * sizeof(Item_Set)); zfree(r->class); *r = new; } static Relevant newRelevant() { Relevant r = (Relevant) zalloc(max_nonterminal * sizeof(*r)); return r; } void addRelevant(r, nt) Relevant r; NonTerminalNum nt; { int i; for (i = 0; r[i]; i++) { if (r[i] == nt) { break; } } if (!r[i]) { r[i] = nt; } } static Dimension newDimension(op, index) Operator op; ArityNum index; { Dimension d; List pl; Relevant r; assert(op); assert(index >= 0 && index < op->arity); d = (Dimension) zalloc(sizeof(struct dimension)); assert(d); r = d->relevant = newRelevant(); for (pl = rules; pl; pl = pl->next) { Rule pr = (Rule) pl->x; if (pr->pat->op == op) { addRelevant(r, pr->pat->children[index]->num); } } d->index_map.max_size = STATES_INCR; d->index_map.class = (Item_Set*) zalloc(d->index_map.max_size * sizeof(Item_Set)); d->map = newMapping(DIM_MAP_SIZE); d->max_size = TABLE_INCR; return d; } Table newTable(op) Operator op; { Table t; int i, size; assert(op); t = (Table) zalloc(sizeof(struct table)); assert(t); t->op = op; for (i = 0; i < op->arity; i++) { t->dimen[i] = newDimension(op, i); } size = 1; for (i = 0; i < op->arity; i++) { size *= t->dimen[i]->max_size; } t->transition = (Item_Set*) zalloc(size * sizeof(Item_Set)); t->relevant = newRelevant(); assert(t->transition); return t; } static void GT_1(t) Table t; { Item_Set *ts; ItemSetNum oldsize = t->dimen[0]->max_size; ItemSetNum newsize = t->dimen[0]->max_size + TABLE_INCR; t->dimen[0]->max_size = newsize; ts = (Item_Set*) zalloc(newsize * sizeof(Item_Set)); assert(ts); memcpy(ts, t->transition, oldsize * sizeof(Item_Set)); zfree(t->transition); t->transition = ts; } static void GT_2_0(t) Table t; { Item_Set *ts; ItemSetNum oldsize = t->dimen[0]->max_size; ItemSetNum newsize = t->dimen[0]->max_size + TABLE_INCR; int size; t->dimen[0]->max_size = newsize; size = newsize * t->dimen[1]->max_size; ts = (Item_Set*) zalloc(size * sizeof(Item_Set)); assert(ts); memcpy(ts, t->transition, oldsize*t->dimen[1]->max_size * sizeof(Item_Set)); zfree(t->transition); t->transition = ts; } static void GT_2_1(t) Table t; { Item_Set *ts; ItemSetNum oldsize = t->dimen[1]->max_size; ItemSetNum newsize = t->dimen[1]->max_size + TABLE_INCR; int size; Item_Set *from; Item_Set *to; int i1, i2; t->dimen[1]->max_size = newsize; size = newsize * t->dimen[0]->max_size; ts = (Item_Set*) zalloc(size * sizeof(Item_Set)); assert(ts); from = t->transition; to = ts; for (i1 = 0; i1 < t->dimen[0]->max_size; i1++) { for (i2 = 0; i2 < oldsize; i2++) { to[i2] = from[i2]; } to += newsize; from += oldsize; } zfree(t->transition); t->transition = ts; } static void growTransition(t, dim) Table t; ArityNum dim; { assert(t); assert(t->op); assert(dim < t->op->arity); switch (t->op->arity) { default: assert(0); break; case 1: GT_1(t); return; case 2: switch (dim) { default: assert(0); break; case 0: GT_2_0(t); return; case 1: GT_2_1(t); return; } } } static Item_Set restrict(d, ts) Dimension d; Item_Set ts; { DeltaCost base; Item_Set r; int found; register Relevant r_ptr = d->relevant; register Item *ts_current = ts->closed; register Item *r_current; register int i; register int nt; ZEROCOST(base); found = 0; r = newItem_Set(d->relevant); r_current = r->virgin; for (i = 0; (nt = r_ptr[i]) != 0; i++) { if (ts_current[nt].rule) { r_current[nt].rule = &stub_rule; if (!found) { found = 1; ASSIGNCOST(base, ts_current[nt].delta); } else { if (LESSCOST(ts_current[nt].delta, base)) { ASSIGNCOST(base, ts_current[nt].delta); } } } } /* zero align */ for (i = 0; (nt = r_ptr[i]) != 0; i++) { if (r_current[nt].rule) { ASSIGNCOST(r_current[nt].delta, ts_current[nt].delta); MINUSCOST(r_current[nt].delta, base); } } assert(!r->closed); r->representative = ts; return r; } static void addHP_1(t, ts) Table t; Item_Set ts; { List pl; Item_Set e; Item_Set tmp; int new; e = newItem_Set(t->relevant); assert(e); e->kids[0] = ts->representative; for (pl = t->rules; pl; pl = pl->next) { Rule p = (Rule) pl->x; if (t->op == p->pat->op && ts->virgin[p->pat->children[0]->num].rule) { DeltaCost dc; ASSIGNCOST(dc, ts->virgin[p->pat->children[0]->num].delta); ADDCOST(dc, p->delta); if (!e->virgin[p->lhs->num].rule || LESSCOST(dc, e->virgin[p->lhs->num].delta)) { e->virgin[p->lhs->num].rule = p; ASSIGNCOST(e->virgin[p->lhs->num].delta, dc); e->op = t->op; } } } trim(e); zero(e); tmp = encode(globalMap, e, &new); assert(ts->num < t->dimen[0]->map->max_size); t->transition[ts->num] = tmp; if (new) { closure(e); addQ(globalQ, tmp); } else { freeItem_Set(e); } } static void addHP_2_0(t, ts) Table t; Item_Set ts; { List pl; register Item_Set e; Item_Set tmp; int new; int i2; assert(t->dimen[1]->map->count <= t->dimen[1]->map->max_size); for (i2 = 0; i2 < t->dimen[1]->map->count; i2++) { e = newItem_Set(t->relevant); assert(e); e->kids[0] = ts->representative; e->kids[1] = t->dimen[1]->map->set[i2]->representative; for (pl = t->rules; pl; pl = pl->next) { register Rule p = (Rule) pl->x; if (t->op == p->pat->op && ts->virgin[p->pat->children[0]->num].rule && t->dimen[1]->map->set[i2]->virgin[p->pat->children[1]->num].rule){ DeltaCost dc; ASSIGNCOST(dc, p->delta); ADDCOST(dc, ts->virgin[p->pat->children[0]->num].delta); ADDCOST(dc, t->dimen[1]->map->set[i2]->virgin[p->pat->children[1]->num].delta); if (!e->virgin[p->lhs->num].rule || LESSCOST(dc, e->virgin[p->lhs->num].delta)) { e->virgin[p->lhs->num].rule = p; ASSIGNCOST(e->virgin[p->lhs->num].delta, dc); e->op = t->op; } } } trim(e); zero(e); tmp = encode(globalMap, e, &new); assert(ts->num < t->dimen[0]->map->max_size); t->transition[ts->num * t->dimen[1]->max_size + i2] = tmp; if (new) { closure(e); addQ(globalQ, tmp); } else { freeItem_Set(e); } } } static void addHP_2_1(t, ts) Table t; Item_Set ts; { List pl; register Item_Set e; Item_Set tmp; int new; int i1; assert(t->dimen[0]->map->count <= t->dimen[0]->map->max_size); for (i1 = 0; i1 < t->dimen[0]->map->count; i1++) { e = newItem_Set(t->relevant); assert(e); e->kids[0] = t->dimen[0]->map->set[i1]->representative; e->kids[1] = ts->representative; for (pl = t->rules; pl; pl = pl->next) { register Rule p = (Rule) pl->x; if (t->op == p->pat->op && ts->virgin[p->pat->children[1]->num].rule && t->dimen[0]->map->set[i1]->virgin[p->pat->children[0]->num].rule){ DeltaCost dc; ASSIGNCOST(dc, p->delta ); ADDCOST(dc, ts->virgin[p->pat->children[1]->num].delta); ADDCOST(dc, t->dimen[0]->map->set[i1]->virgin[p->pat->children[0]->num].delta); if (!e->virgin[p->lhs->num].rule || LESSCOST(dc, e->virgin[p->lhs->num].delta)) { e->virgin[p->lhs->num].rule = p; ASSIGNCOST(e->virgin[p->lhs->num].delta, dc); e->op = t->op; } } } trim(e); zero(e); tmp = encode(globalMap, e, &new); assert(ts->num < t->dimen[1]->map->max_size); t->transition[i1 * t->dimen[1]->max_size + ts->num] = tmp; if (new) { closure(e); addQ(globalQ, tmp); } else { freeItem_Set(e); } } } static void addHyperPlane(t, i, ts) Table t; ArityNum i; Item_Set ts; { switch (t->op->arity) { default: assert(0); break; case 1: addHP_1(t, ts); return; case 2: switch (i) { default: assert(0); break; case 0: addHP_2_0(t, ts); return; case 1: addHP_2_1(t, ts); return; } } } void addToTable(t, ts) Table t; Item_Set ts; { ArityNum i; assert(t); assert(ts); assert(t->op); for (i = 0; i < t->op->arity; i++) { Item_Set r; Item_Set tmp; int new; r = restrict(t->dimen[i], ts); tmp = encode(t->dimen[i]->map, r, &new); if (t->dimen[i]->index_map.max_size <= ts->num) { growIndex_Map(&t->dimen[i]->index_map); } assert(ts->num < t->dimen[i]->index_map.max_size); t->dimen[i]->index_map.class[ts->num] = tmp; if (new) { if (t->dimen[i]->max_size <= r->num) { growTransition(t, i); } addHyperPlane(t, i, r); } else { freeItem_Set(r); } } } Item_Set * transLval(t, row, col) Table t; int row; int col; { switch (t->op->arity) { case 0: assert(row == 0); assert(col == 0); return t->transition; case 1: assert(col == 0); return t->transition + row; case 2: return t->transition + row * t->dimen[1]->max_size + col; default: assert(0); } return 0; } void dumpRelevant(r) Relevant r; { for (; *r; r++) { printf("%4d", *r); } } void dumpIndex_Map(r) Index_Map *r; { int i; printf("BEGIN Index_Map: MaxSize (%d)\n", r->max_size); for (i = 0; i < globalMap->count; i++) { printf("\t#%d: -> %d\n", i, r->class[i]->num); } printf("END Index_Map:\n"); } void dumpDimension(d) Dimension d; { printf("BEGIN Dimension:\n"); printf("Relevant: "); dumpRelevant(d->relevant); printf("\n"); dumpIndex_Map(&d->index_map); dumpMapping(d->map); printf("MaxSize of dimension = %d\n", d->max_size); printf("END Dimension\n"); } void dumpTable(t, full) Table t; int full; { int i; if (!t) { printf("NO Table yet.\n"); return; } printf("BEGIN Table:\n"); if (full) { dumpOperator(t->op, 0); } for (i = 0; i < t->op->arity; i++) { printf("BEGIN dimension(%d)\n", i); dumpDimension(t->dimen[i]); printf("END dimension(%d)\n", i); } dumpTransition(t); printf("END Table:\n"); } void dumpTransition(t) Table t; { int i,j; switch (t->op->arity) { case 0: printf("{ %d }", t->transition[0]->num); break; case 1: printf("{"); for (i = 0; i < t->dimen[0]->map->count; i++) { if (i > 0) { printf(","); } printf("%5d", t->transition[i]->num); } printf("}"); break; case 2: printf("{"); for (i = 0; i < t->dimen[0]->map->count; i++) { if (i > 0) { printf(","); } printf("\n"); printf("{"); for (j = 0; j < t->dimen[1]->map->count; j++) { Item_Set *ts = transLval(t, i, j); if (j > 0) { printf(","); } printf("%5d", (*ts)->num); } printf("}"); } printf("\n}\n"); break; default: assert(0); } }