+ }
+ result->intr = var_create_internal (0);
+
+ return result;
+}
+void interaction_variable_destroy (struct interaction_variable *iv)
+{
+ var_destroy (iv->intr);
+ free (iv->members);
+ free (iv);
+}
+
+/*
+ Get one of the member variables.
+ */
+const struct variable *
+interaction_variable_get_member (const struct interaction_variable *iv, size_t i)
+{
+ return iv->members[i];
+}
+
+size_t
+interaction_get_n_vars (const struct interaction_variable *iv)
+{
+ return (iv == NULL) ? 0 : iv->n_vars;
+}
+
+size_t
+interaction_get_n_alpha (const struct interaction_variable *iv)
+{
+ return iv->n_alpha;
+}
+
+size_t
+interaction_get_n_numeric (const struct interaction_variable *iv)
+{
+ return (interaction_get_n_vars (iv) - interaction_get_n_alpha (iv));
+}
+
+/*
+ Get the interaction varibale itself.
+ */
+const struct variable *
+interaction_variable_get_var (const struct interaction_variable *iv)
+{
+ return iv->intr;
+}
+/*
+ Given list of values, compute the value of the corresponding
+ interaction. This "value" is not stored as the typical vector of
+ 0's and one double, but rather the string values are concatenated to
+ make one big string value, and the numerical values are multiplied
+ together to give the non-zero entry of the corresponding vector.
+ */
+struct interaction_value *
+interaction_value_create (const struct interaction_variable *var, const union value **vals)
+{
+ struct interaction_value *result = NULL;
+ const struct variable *member;
+ size_t i;
+ size_t n_vars;
+
+ if (var != NULL)
+ {
+ int val_width;
+ char *val;
+
+ result = xmalloc (sizeof (*result));
+ result->intr = var;
+ n_vars = interaction_get_n_vars (var);
+ val_width = n_vars * MAX_SHORT_STRING + 1;
+ value_init (&result->val, val_width);
+ val = value_str_rw (&result->val, val_width);
+ val[0] = '\0';
+ result->f = 1.0;
+ for (i = 0; i < n_vars; i++)
+ {
+ member = interaction_variable_get_member (var, i);
+
+ if (var_is_value_missing (member, vals[i], MV_ANY))
+ {
+ value_set_missing (&result->val, MAX_SHORT_STRING);
+ result->f = SYSMIS;
+ break;
+ }
+ else
+ {
+ if (var_is_alpha (var->members[i]))
+ {
+ int w = var_get_width (var->members[i]);
+ strncat (val, value_str (vals[i], w), MAX_SHORT_STRING);
+ }
+ else if (var_is_numeric (var->members[i]))
+ {
+ result->f *= vals[i]->f;
+ }
+ }
+ }
+ if (interaction_get_n_alpha (var) == 0)