constraints.c 6.04 KB
#include <stdlib.h>

#include <assert.h>

#include "fdc_int.h"
#include "values.h"
#include "variables.h"
#include "constraints.h"

#define MAX_CONSTRAINTS (512 * 512)

int _fd_constraint_count = 0;
fd_constraint _fd_constraints[MAX_CONSTRAINTS];

#ifdef CONSTRAINT_TEMPS
#define CSTR_DATA_VALID	0x01
#define CSTR_ENTAILED	0x02

static __thread uint8_t constraint_state_info[MAX_CONSTRAINTS];
static __thread void *constraint_memory[MAX_CONSTRAINTS];
#endif

/* generic functions */

fd_constraint _fd_constraint_new(int nvariables, int nconstants)
{
  fd_constraint c;

  if (_fd_constraint_count == MAX_CONSTRAINTS)
    _fd_fatal("too many constraints, increase MAX_CONSTRAINTS");

  if (c = malloc(sizeof(struct fd_constraint)))
    {
#ifdef CONSTRAINT_TEMPS
      c->index = _fd_constraint_count;
#endif
      c->variables = calloc(nvariables, sizeof(C_VAR_T)); // XXX: check for NULL
      c->nvariables = nvariables;
      if (nconstants)
	c->constants = calloc(nconstants, sizeof(int));  // XXX: check for NULL
      else
	c->constants = 0;
      c->nconstants = nconstants;
#ifdef CONSTRAINT_CLASS
      c->kind = -1;	// XXX
#else /* CONSTRAINT_CLASS */
      c->propagator2 = _fd_undefined;
      c->propagator = 0;
#endif /* CONSTRAINT_CLASS */

      _fd_constraints[_fd_constraint_count++] = c;
    }

  return c;
}

int _fd_undefined()
{
  _fd_fatal("called an undefined function");
}

#ifdef DISTRIBUTED_SOLVER

/* create a copy of CONSTRAINT that uses VARIABLES */
// XXX: no longer needed!?
fd_constraint _fd_constraint_adapt(fd_constraint constraint, fd_int variables[])
{
  return constraint;
}

/* import constraints into VARIABLES (XXX: description!) */
// XXX: no longer needed!?
void _fd_import_constraints(fd_int variables[])
{
}

#endif /* DISTRIBUTED_SOLVER */


#ifdef CONSTRAINT_TEMPS
#include <string.h>

int fd__constraint_data_valid(fd_constraint constraint)
{
  return constraint_state_info[constraint->index] & CSTR_DATA_VALID;
}

void fd__constraint_remember(fd_constraint constraint)
{
  constraint_state_info[constraint->index] |= CSTR_DATA_VALID;
}

#ifndef DISABLE_ENTAILED
void fd__constraint_set_entailed(fd_constraint constraint)
{
  constraint_state_info[constraint->index] |= CSTR_ENTAILED;
}

int fd__constraint_entailed(fd_constraint constraint)
{
  return constraint_state_info[constraint->index] & CSTR_ENTAILED;
}
#else
#define fd__constraint_set_entailed(_) ((void) 0)
#endif

void fd__constraint_data_reset()
{
  memset(constraint_state_info, 0,
	 _fd_constraint_count * sizeof(*constraint_state_info));
}

void fd__constraint_free_memory()
{
  int i;

  for (i = 0; i < _fd_constraint_count; ++i)
    if (constraint_memory[i])
      free(constraint_memory[i]);
}
#else /* CONSTRAINT_TEMPS */
#define fd__constraint_set_entailed(_) ((void) 0)
#endif /* CONSTRAINT_TEMPS */

#include <constraints/lt.c>
#include <constraints/le.c>
#include <constraints/gt.c>
#include <constraints/ge.c>
#include <constraints/ne.c>
#include <constraints/eq.c>
#include <constraints/all-different.c>
#include <constraints/minus-ne.c>
#include <constraints/plus-gt.c>
#include <constraints/exactly-one.c>
#include <constraints/minus-eq.c>
#include <constraints/fake-all-different.c>
#include <constraints/nogoods.c>
#include <constraints/var-eq-minus.c>
#include <constraints/exactly.c>
#include <constraints/exactly-var.c>
#include <constraints/sum.c>
#include <constraints/var-eq-times.c>
#include <constraints/sum-prod.c>
#include <constraints/element.c>
#include <constraints/knapsack2.c>
#include <constraints/sum2.c>
#include <constraints/min.c>
#include <constraints/max.c>
#include <constraints/poly-eq.c>
#include <constraints/element-var.c>
#include <constraints/exactly-vars.c>

#ifdef CONSTRAINT_CLASS

_fd_constraint_class _fd_constraint_data[FD_CONSTR_KINDS];

_FD_CONSTRAINT_INITIALISATION(ne, FD_CONSTR_NE)
_FD_CONSTRAINT_INITIALISATION(eq, FD_CONSTR_EQ)
_FD_CONSTRAINT_INITIALISATION(lt, FD_CONSTR_LT)
_FD_CONSTRAINT_INITIALISATION(le, FD_CONSTR_LE)
_FD_CONSTRAINT_INITIALISATION(minus_ne, FD_CONSTR_MINUS_NE)
_FD_CONSTRAINT_INITIALISATION(minus_eq, FD_CONSTR_MINUS_EQ)
// _FD_CONSTRAINT_INITIALISATION(plus_gt, FD_CONSTR_PLUS_GT)
_FD_CONSTRAINT_INITIALISATION(var_eq_minus, FD_CONSTR_VAR_EQ_MINUS)
_FD_CONSTRAINT_INITIALISATION(all_different, FD_CONSTR_ALL_DIFFERENT)
// _FD_CONSTRAINT_INITIALISATION(exactly_one, FD_CONSTR_EXACTLY_ONE)
// _FD_CONSTRAINT_INITIALISATION(nogoods, FD_CONSTR_NOGOODS)
_FD_CONSTRAINT_INITIALISATION(exactly, FD_CONSTR_EXACTLY)
_FD_CONSTRAINT_INITIALISATION(exactly_var, FD_CONSTR_EXACTLY_VAR)
_FD_CONSTRAINT_INITIALISATION(sum, FD_CONSTR_SUM)
_FD_CONSTRAINT_INITIALISATION(var_eq_times, FD_CONSTR_VAR_EQ_TIMES)
_FD_CONSTRAINT_INITIALISATION(sum_prod, FD_CONSTR_SUM_PROD)
_FD_CONSTRAINT_INITIALISATION(element, FD_CONSTR_ELEMENT)
_FD_CONSTRAINT_INITIALISATION(knapsack2, FD_CONSTR_KNAPSACK2)
_FD_CONSTRAINT_INITIALISATION(sum2, FD_CONSTR_SUM2)
_FD_CONSTRAINT_INITIALISATION(min, FD_CONSTR_MIN)
_FD_CONSTRAINT_INITIALISATION(max, FD_CONSTR_MAX)
_FD_CONSTRAINT_INITIALISATION(poly_eq, FD_CONSTR_POLY_EQ)
_FD_CONSTRAINT_INITIALISATION(element_var, FD_CONSTR_ELEMENT_VAR)
_FD_CONSTRAINT_INITIALISATION(exactly_vars, FD_CONSTR_EXACTLY_VARS)

void _fd_init_constraints()
{
  static int done = 0;

  if (done)
    return;

  memset(_fd_constraint_data, 0, sizeof(_fd_constraint_data)); // XXX?

  _fd_init_constraint(ne);
  _fd_init_constraint(eq);
  _fd_init_constraint(lt);
  _fd_init_constraint(le);
  _fd_init_constraint(minus_ne);
  _fd_init_constraint(minus_eq);
//  _fd_init_constraint(plus_gt);
  _fd_init_constraint(var_eq_minus);
  _fd_init_constraint(all_different);
//  _fd_init_constraint(exactly_one);
//  _fd_init_constraint(nogoods);
  _fd_init_constraint(exactly);
  _fd_init_constraint(exactly_var);
  _fd_init_constraint(sum);
  _fd_init_constraint(var_eq_times);
  _fd_init_constraint(sum_prod);
  _fd_init_constraint(element);
  _fd_init_constraint(knapsack2);
  _fd_init_constraint(sum2);
  _fd_init_constraint(min);
  _fd_init_constraint(max);
  _fd_init_constraint(poly_eq);
  _fd_init_constraint(element_var);
  _fd_init_constraint(exactly_vars);

  done = 1;
}

#endif /* CONSTRAINT_CLASS */