fdc_int.h
6.21 KB
1
2
3
4
5
6
7
8
9
10
11
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
37
38
39
40
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
#ifdef FAKE_ALLDIFF
#warning "-DFAKE_ALLDIFF deprecated, use the fake-all-different constraint instead"
#endif
#include "config.h"
#include "misc.h"
#ifdef HAVE_WORDSIZE_H
#include <bits/wordsize.h> // XXX: to get __WORDSIZE; non portable?
#endif
#include <stdbool.h>
#include <stdint.h>
/* internal definitions for fdc solver */
typedef struct fd_int *fd_int;
#ifdef INLINE_DOMAINS
# define COMPACT_DOMAINS 1
#endif
#ifdef COMPACT_DOMAINS
# ifndef DOMAIN_BITS
# ifdef __SIZEOF_LONG_LONG__
# define DOMAIN_BITS (__SIZEOF_LONG_LONG__ << 3)
# else
# define DOMAIN_BITS (__SIZEOF_LONG__ << 3)
# endif
# endif
/* _fd_bitmap is the native integral type used for the bitmaps */
# ifndef UNIT_BITS
# if DOMAIN_BITS <= (__SIZEOF_INT__ << 3)
# define UNIT_BITS (__SIZEOF_INT__ << 3)
# elif DOMAIN_BITS == (__SIZEOF_LONG__ << 3)
# define UNIT_BITS (__SIZEOF_LONG__ << 3)
# elif DOMAIN_BITS == (__SIZEOF_LONG_LONG__ << 3)
# define UNIT_BITS (__SIZEOF_LONG_LONG__ << 3)
# else
# define UNIT_BITS (__SIZEOF_LONG__ << 3)
# endif
# endif
# if UNIT_BITS == (__SIZEOF_INT__ << 3)
typedef unsigned int _fd_bitmap;
# elif UNIT_BITS == (__SIZEOF_LONG__ << 3)
typedef unsigned long _fd_bitmap;
# elif UNIT_BITS == (__SIZEOF_LONG_LONG__ << 3)
typedef unsigned long long _fd_bitmap;
# else
# error "invalid UNIT_BITS definition"
# endif
# if defined(INLINE_DOMAINS) && DOMAIN_BITS > UNIT_BITS
# error "can't have INLINE_DOMAINS with those bits"
# endif
# define DOMAIN_MAP_WORDS ((DOMAIN_BITS + UNIT_BITS - 1) / UNIT_BITS)
# ifdef DOMAIN_BOUNDS
# define DOMAIN_WORDS (DOMAIN_MAP_WORDS + 1)
# else
# define DOMAIN_WORDS DOMAIN_MAP_WORDS
# endif
# if DOMAIN_BITS != DOMAIN_MAP_WORDS * UNIT_BITS
# error "DOMAIN_BITS is not a multiple of UNIT_BITS"
# endif
# if defined(INLINE_DOMAINS) && defined(DOMAIN_BOUNDS)
# error "DOMAIN_BOUNDS won't work with INLINE_DOMAINS"
# endif
/* _fd_value_core represents the data part of a domain (and is what is
kept in a store) */
# ifdef INLINE_DOMAINS
typedef _fd_bitmap _fd_value_core;
typedef _fd_bitmap fd_value;
# else
# ifndef DOMAIN_BOUNDS
typedef _fd_bitmap _fd_value_core[DOMAIN_MAP_WORDS];
typedef _fd_value_core *fd_value;
# else
# if UNIT_BITS == 32
typedef uint16_t _fd_boundary;
# else
typedef uint32_t _fd_boundary;
# endif
typedef struct {
_fd_bitmap map[DOMAIN_MAP_WORDS];
_fd_boundary min, max;
} _fd_value_core;
typedef _fd_value_core *fd_value;
# endif
# endif
# ifdef INLINE_DOMAINS
typedef _fd_bitmap *fd_iterator;
# else
typedef fd_value fd_iterator;
# endif
#else /* COMPACT_DOMAINS */
typedef struct fd_value *fd_value;
typedef struct fd_value *_fd_value_core;
typedef struct fd_iterator *fd_iterator;
#endif /* COMPACT_DOMAINS */
typedef struct fd_constraint *fd_constraint;
#define FD_OK 0
#define FD_NOSOLUTION 1
/* lists */
#include "list.h"
/* values */
fd_value fd_new_value(int, int);
#ifndef COMPACT_DOMAINS
/* kinds of value */
typedef enum { FD_EMPTY, FD_SINGLETON, FD_MULTIPLE } fd_kind;
struct fd_value {
fd_kind kind;
union {
int value;
struct {
int lower, upper;
} interval;
} value;
fd_value next; // points to values greater than this one
};
#else /* COMPACT_DOMAINS */
// XXX: these are kind of fictitious
#define MIN_VALUE 0
#define MAX_VALUE (DOMAIN_BITS - 1)
#endif /* COMPACT_DOMAINS */
/* constraints */
// type for a constraint's variables
#define C_VAR_T int
#define VAR(c,v) _fd_variables[(c)->variables[v]]
#define FD_INT2C_VAR(v) ((v)->index)
struct fd_constraint {
#if defined(CONSTRAINT_TEMPS) || !defined(DISABLE_ENTAILED)
int index;
#endif
C_VAR_T *variables; // variables involved in the constraint
int nvariables; // number of variables
int *constants; // constraint's constants (where applicable)
int nconstants; // number of constants
// _fd_constraint_kind kind; // what kind of constraint is this?
int kind; // what kind of constraint is this? // XXX
};
#define fd_cvariable(c,v) ((c)->variables[v]) // XXX: not being used
int _fd_undefined();
/* variables */
#define MAX_VARIABLES (64 * (1 << 10))
// variables' flags
#define FD_INSTANTIATED 0x0001 // variable has been instantiated
extern int fd_variables_count;
extern __thread fd_int _fd_variables[];
fd_int fd_new(int, int);
fd_int fd_const(int);
// type for the variable's constraints
#define VAR_C_T int
#ifdef USE_STORE
# include "store.h"
# ifdef INLINE_DOMAINS
# define DOMAIN(v) store[(v)->index]
# define DOMAIN_REF(v) (store + (v)->index)
# define DOMAIN_REF_T(d) fd_value *d
# else
# define DOMAIN(v) (store + (v)->index)
# define DOMAIN_REF DOMAIN
# define DOMAIN_REF_T(d) fd_value d
# endif
#else /* USE_STORE */
# define DOMAIN(v) (v)->domain
# ifdef INLINE_DOMAINS
# define DOMAIN_REF(v) (&(v)->domain)
# define DOMAIN_REF_T(d) fd_value *d
# else
# define DOMAIN_REF DOMAIN
# define DOMAIN_REF_T(d) fd_value d
# endif
#endif /* USE_STORE */
struct fd_int {
int index; // variable index within the state (XXX: needed?)
#ifndef USE_STORE
fd_value domain;
#endif
VAR_C_T *constraints; // constraints involving the variable
int nconstraints;
int nconnections; // number of variables sharing a constraint
// (it this the degree of the variable?)
int epoch; // epoch of the last change to the domain
// (for backtracking)
bool assigned; // has the variable been assigned during search?
int flags;
#ifdef USE_VALUE
int value; // the value assigned to the variable
#endif
};
/* global variables */
extern int _fd_counting_solutions; // are we counting solutions?
/* messages */
#if defined(DISTRIBUTED_SOLVER)
#if !defined(SPLITGO)
#error "SPLITGO must be defined"
#endif
#ifdef SPLITGO_MPI
typedef enum {
FD_MSG_STORE, FD_MSG_SOLUTION, FD_MSG_FEED_ME, FD_MSG_NO_WORK, FD_MSG_FAIL,
FD_MSG_DONE, FD_MSG_SHARE, FD_MSG_NO_SHARE, FD_MSG_COUNT, FD_MSG_QUIT,
FD_MSG_BOUND, FD_MSG_READY, FD_MSG_ANY,
FD_MSG_NONE = -1 // not a valid message tag
} _fd_message;
#endif /* SPLITGO_MPI */
#endif /* DISTRIBUTED_SOLVER */
#ifdef TRACE
# define fd__trace fd__debug
#else
# define fd__trace(...) ((void) 0)
#endif