Blame view

src/bound.c 2.42 KB
965dadaa   Salvador Abreu   initial commit fr...
1
2
3
4
5
6
7
#include <stdio.h>
#include <stdlib.h>

#include <assert.h>

#include "fdc_int.h"
#include "store.h"
965dadaa   Salvador Abreu   initial commit fr...
8

eef94371   Vasco Pedro   Update to PaCCS v...
9
10
11
#include "bound.h"

bool _fd_optimising = false;
965dadaa   Salvador Abreu   initial commit fr...
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

struct _fd_bound_data {
  int value;
  C_VAR_T variable;
  fd_constraint constraint;
  int (*check)(fd_constraint, _fd_store, int *);
  int (*valid)(int, int);
  int (*compare)(fd_constraint, _fd_store, _fd_store);
  bool (*bound)(fd_constraint, int);
};

_fd_bound_data *_fd_bound = NULL;


_fd_bound_data *_fd_init_bound(int n, C_VAR_T v, fd_constraint c,
			       int (*f)(fd_constraint, _fd_store, int *),
			       int (*g)(int, int),
			       int (*h)(fd_constraint, _fd_store, _fd_store),
			       bool (*i)(fd_constraint, int))
{
  _fd_bound_data *b;

  if (_fd_bound)
    _fd_fatal("trying to set a 2nd optimisation constraint");

eef94371   Vasco Pedro   Update to PaCCS v...
37
  if ((b = malloc(sizeof(*_fd_bound))) == NULL)
965dadaa   Salvador Abreu   initial commit fr...
38
39
    _fd_fatal("could not allocate memory for the optimisation bound");

eef94371   Vasco Pedro   Update to PaCCS v...
40
  b->value = n;
965dadaa   Salvador Abreu   initial commit fr...
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
  b->variable = v;
  b->constraint = c;
  b->check = f;
  b->valid = g;
  b->compare = h;
  b->bound = i;

  _fd_bound = b;

  _fd_optimising = true;

  return b;
}

bool _fd_set_bound(int value)
{
  assert(_fd_bound != NULL);

  if (!_fd_bound->valid(_fd_bound->value, value))
    return false;

  _fd_bound->value = value;

  return true;
}

int _fd_bound_value()
{
  assert(_fd_bound != NULL);

  return _fd_bound->value;
}

bool _fd_bound_check_set(_fd_store store)
{
  int value;

  assert(_fd_bound != NULL);

  if (!_fd_bound->check(_fd_bound->constraint, store, &value))
    return false;

  _fd_bound->value = value;

  return true;
}

bool _fd_bound_check(_fd_store store)
{
  int value;

  assert(_fd_bound != NULL);

  return _fd_bound->check(_fd_bound->constraint, store, &value) ||
	 value == _fd_bound->value;
}

int _fd_better_solution(_fd_store s1, _fd_store s2)
{
  assert(_fd_bound != NULL);

  return _fd_bound->compare(_fd_bound->constraint, s1, s2) < 0;
}

fd_int _fd_bound_variable()
{
  assert(_fd_bound != NULL);

  return _fd_variables[_fd_bound->variable];
}

/* Bound the optimisation variable and propagate the change. */
int fd__bound_and_revise()
{
  assert(_fd_bound != NULL);

  if (_fd_bound->bound(_fd_bound->constraint, _fd_bound_value()))
    {
      if (fd_domain_empty(_fd_bound_variable()))
	return FD_NOSOLUTION;

      if (_fd_revise_wrt_variable(_fd_bound_variable()) == FD_NOSOLUTION)
	{
#ifdef CONSTRAINT_TEMPS
	  fd__constraint_data_reset();
965dadaa   Salvador Abreu   initial commit fr...
126
#endif
965dadaa   Salvador Abreu   initial commit fr...
127
128
129
130
131
132
133

	  return FD_NOSOLUTION;
	}
    }

  return FD_OK;
}