problem.c 4.52 KB
#include <stdio.h>
#include <stdlib.h>

#ifdef SPLITGO_MPI
#include <mpi.h>
#endif

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

extern int fd__workers;

static void _fd_cleanup(void);

static void _fd_parse_general_options(int *argc, char *argv[])
{
  int args = *argc;
  int i, j;

  bool sort = true;	// the default is to sort labelled variables

  // variable selection function
  _fd_var_select2 = _fd_select_first_var;

  // value selection function
  _fd_val_select = _fd_val_min;
  _fd_val_del_select = _fd_val_del_min;

  // variable comparison function
  fd__cmp_variables = NULL;

#ifdef SPLITGO
  // running mode (the default is to return the first solution)
  _fd_counting_solutions = 0;
#endif

  for (i = j = 1; i < args; i++)
    if (!strcmp(argv[i], "--first-var"))    /* variable selection heuristics */
      _fd_var_select2 = _fd_select_first_var;
    else if (!strcmp(argv[i], "--first-fail"))
      {
	_fd_var_select2 = _fd_select_first_fail;
	if (sort)
	  fd__cmp_variables = fd__cmp_var_size;
      }
    else if (!strcmp(argv[i], "--most-constrained"))
      {
	// once sorted, select the first unassigned variable
	if (sort)
	  fd__cmp_variables = fd__cmp_var_constraints;
	else
	  _fd_var_select2 = _fd_select_most_constrained;
      }
    else if (!strcmp(argv[i], "--size-degree"))
      {
	_fd_var_select2 = _fd_select_size_degree;
	if (sort)
	  fd__cmp_variables = fd__cmp_var_size_degree;
      }
    else if (!strcmp(argv[i], "--most-connected"))
      {
	// once sorted, select the first unassigned variable
	if (sort)
	  fd__cmp_variables = fd__cmp_var_connections;
	else
	  _fd_var_select2 = _fd_select_most_connected;
      }
    else if (!strcmp(argv[i], "--random-var"))
      _fd_var_select2 = _fd_select_random_var;
    else if (!strcmp(argv[i], "--min-value"))
      {
	_fd_var_select2 = _fd_select_min_value;
	if (sort)
	  fd__cmp_variables = fd__cmp_var_min;
      }
    else if (!strcmp(argv[i], "--max-value"))
      {
	_fd_var_select2 = _fd_select_max_value;
	if (sort)
	  fd__cmp_variables = fd__cmp_var_max;
      }
    else if (!strcmp(argv[i], "--val-min"))    /* value selection heuristics */
      {
	_fd_val_select = _fd_val_min;
	_fd_val_del_select = _fd_val_del_min;
      }
    else if (!strcmp(argv[i], "--val-max"))
      {
	_fd_val_select = _fd_val_max;
	_fd_val_del_select = _fd_val_del_max;
      }
    else if (!strcmp(argv[i], "--count-solutions"))          /* running mode */
#ifdef SPLITGO
      _fd_counting_solutions = 1;
#else
      ;
#endif
    else if (!strcmp(argv[i], "--no-sort"))		    /* miscellaneous */
      // Note: the meaning of this option depends on whether it
      // appears in the command line before or after the choice of the
      // variable selection heuristic (see the code above)
      sort = false;
    else if (!strncmp(argv[i], "--workers=", sizeof("--workers=") - 1))
      fd__workers = atoi(argv[i] + sizeof("--workers=") - 1);
    else
      argv[j++] = argv[i];

  *argc = j;
}

void fd_init(int *argc, char **argv[])
{
#ifdef SPLITGO_MPI
  if (MPI_Init(argc, argv))
    _fd_fatal("MPI_Init failed");
#endif

  _fd_parse_general_options(argc, *argv);

#ifdef SPLITGO
  fd__init_splitgo(argc, *argv);
#endif

#ifdef CONSTRAINT_CLASS
  _fd_init_constraints();
#endif

#ifdef USE_STORE
  _fd_init_main_store();
#endif
}

void fd_end()
{
#ifdef SPLITGO_MPI
  {
    int rank;

    MPI_Comm_rank(MPI_COMM_WORLD, &rank);

    _fd_cleanup_mpi_state(rank);
  }
#endif

  _fd_cleanup();
}

// XXX: called from the constraints' initialisation functions
void _fd_add_constraint(fd_constraint constraint)
{
}

int fd_solve()
{
#ifdef DISTRIBUTED_SOLVER
#ifdef PACK_PROBLEM
  _fd_pack_problem();
#endif

  return _fd_dsolve();
#else // PROPAGATE
#ifdef PACK_PROBLEM
  _fd_pack_problem();
#endif

  return _fd_filter_domains();
#endif
}

/* it helps finding if all allocated memory is accounted for */
static void _fd_cleanup()
{
  extern void _fd_free_value();
  int i, j;

#ifndef PACK_PROBLEM
  for (i = 0; i < _fd_constraint_count; ++i)
    {
      fd_constraint c = _fd_constraints[i];

      free(c->variables);
      if (c->constants)
	free(c->constants);

      free(c);
    }

  for (i = 0; i < fd_variables_count && _fd_variables[i]; ++i)
    {
      _fd_free_value(DOMAIN(_fd_variables[i]));
      free(_fd_variables[i]->constraints);
      free(_fd_variables[i]);
    }
#else /* PACK_PROBLEM */
  // XXX: some things are missing
  _fd_free_packed_memory();
#endif /* PACK_PROBLEM */

  _fd_cleanup_revisions();

#ifdef USE_STORE
  free(store);
#endif

  // XXX
  fd_variables_count = 0;
}