+static struct value_node *
+lookup_value (const struct hmap *map, const union value *val, unsigned int hash, int width)
+{
+ struct value_node *vn = NULL;
+ HMAP_FOR_EACH_WITH_HASH (vn, struct value_node, node, hash, map)
+ {
+ if (value_equal (&vn->val, val, width))
+ break;
+ }
+
+ return vn;
+}
+
+struct variable_node
+{
+ struct hmap_node node; /* Node in hash map. */
+ const struct variable *var; /* The variable */
+
+ struct hmap valmap; /* A map of value nodes */
+ int n_vals; /* Number of values for this variable */
+};
+
+
+/* Comparison function to sort value_nodes in ascending order */
+static int
+compare_value_node_3way (const void *vn1_, const void *vn2_, const void *aux)
+{
+ const struct value_node *const *vn1p = vn1_;
+ const struct value_node *const *vn2p = vn2_;
+
+ const struct variable_node *vn = aux;
+
+
+ return value_compare_3way (&(*vn1p)->val, &(*vn2p)->val, var_get_width (vn->var));
+}
+
+
+
+static struct variable_node *
+lookup_variable (const struct hmap *map, const struct variable *var, unsigned int hash)
+{
+ struct variable_node *vn = NULL;
+ HMAP_FOR_EACH_WITH_HASH (vn, struct variable_node, node, hash, map)
+ {
+ if (vn->var == var)
+ break;
+
+ fprintf (stderr, "%s:%d Warning: Hash table collision\n", __FILE__, __LINE__);
+ }
+
+ return vn;
+}
+
+
+struct interact_params
+{
+ /* A map of cases indexed by a interaction_value */
+ struct hmap ivmap;
+
+ const struct interaction *iact;
+
+ int base_subscript_short;
+ int base_subscript_long;
+
+ /* The number of distinct values of this interaction */