+ int df = 1;
+ const struct interaction *iact = cat->iap[i].iact;
+
+ cat->iap[i].df_prod = iact->n_vars ? xcalloc (iact->n_vars, sizeof (int)) : NULL;
+
+ cat->iap[i].n_cats = 1;
+
+ for (v = 0 ; v < iact->n_vars; ++v)
+ {
+ const struct variable *var = iact->vars[v];
+
+ struct variable_node *vn = lookup_variable (&cat->varmap, var, hash_pointer (var, 0));
+
+ if (hmap_count (&vn->valmap) == 0)
+ return false;
+
+ cat->iap[i].df_prod[v] = df * (hmap_count (&vn->valmap) - 1);
+ df = cat->iap[i].df_prod[v];
+
+ cat->iap[i].n_cats *= hmap_count (&vn->valmap);
+ }
+
+ assert (v == iact->n_vars);
+ if (v > 0)
+ cat->df_sum += cat->iap[i].df_prod [v - 1];
+
+ cat->n_cats_total += cat->iap[i].n_cats;
+ }
+
+
+ cat->reverse_variable_map_short = pool_calloc (cat->pool,
+ cat->df_sum,
+ sizeof *cat->reverse_variable_map_short);
+
+ cat->reverse_variable_map_long = pool_calloc (cat->pool,
+ cat->n_cats_total,
+ sizeof *cat->reverse_variable_map_long);
+
+ for (i = 0 ; i < cat->n_iap; ++i)
+ {
+ struct interaction_value *ivn = NULL;
+ int x = 0;
+ int ii;
+ struct interact_params *iap = &cat->iap[i];
+
+ iap->base_subscript_short = idx_short;
+ iap->base_subscript_long = idx_long;
+
+ iap->reverse_interaction_value_map = pool_calloc (cat->pool, iap->n_cats,
+ sizeof *iap->reverse_interaction_value_map);
+
+ HMAP_FOR_EACH (ivn, struct interaction_value, node, &iap->ivmap)
+ {
+ iap->reverse_interaction_value_map[x++] = ivn;
+
+ }
+
+ assert (x <= iap->n_cats);