Blame view

Debug/src/constraints/all_different.c 11.1 KB
0c8ce2b0   Pedro Roque   missing files
1
2
3
4
/*
 * all_different.c
 *
 *  Created on: 27/08/2014
4d26a735   Pedro Roque   Increased recogni...
5
 *      Author: Pedro
0c8ce2b0   Pedro Roque   missing files
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
 */

#ifndef __OPENCL_VERSION__

#include <stddef.h>
#include <stdio.h>

#include "all_different.h"

#include "../bitmaps.h"
#include "../config.h"
#include "../variables.h"

#endif

#include "../kernels/cl_aux_functions.h"
#if CL_D_TYPE == CL_BITMAP
#include "../kernels/cl_bitmaps.h"
#elif CL_D_TYPE == CL_INTERVAL
#include  "../kernels/cl_intervals.h"
#endif
#include "../kernels/cl_constraints.h"
#include "../kernels/cl_variables.h"
#include "../kernels/cl_ttl.h"

#ifndef __OPENCL_VERSION__

/*
 * Creates a new constraint of the all_different type and return the constraint ID
 * ∀ 0 ≤ i, j < n; i != j → X[i] != X[j]
 * X_ids - array with the IDs of the variables that are constrained by this constraint
 * n_vs - number of ID variables in vs_id
 */
4d26a735   Pedro Roque   Increased recogni...
39
unsigned int c_all_different(unsigned int *X_ids, unsigned int n_vs) {
0c8ce2b0   Pedro Roque   missing files
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62

	// set to include in kernel compilation
	USE_CS[ALL_DIFFERENT] = 1;
	USE_NON_CS_REIFI[ALL_DIFFERENT] = 1;

	// creates a new generic constraint
	unsigned int c_id = c_new(X_ids, n_vs, NULL, 0, -1);

	// pointers to this type of constraint functions
	CS[c_id].kind = ALL_DIFFERENT;
	CS[c_id].check_sol_f = &all_different_check;
	CS[c_id].constant_val = 0;

	return c_id;
}

/*
 * Creates a new reified constraint of the all_different type and return the constraint ID
 * ∀ 0 ≤ i, j < n; i != j → X[i] != X[j]
 * X_id - array with the IDs of the variables that are constrained by this constraint
 * n_vs - number of ID variables in vs_id
 * reif_v_id - ID of the reification variable
 */
4d26a735   Pedro Roque   Increased recogni...
63
unsigned int c_all_different_reif(unsigned int *X_ids, unsigned int n_vs, int reif_v_id) {
0c8ce2b0   Pedro Roque   missing files
64
65
66
67
68

	if (VS[reif_v_id].max > 1) {
		v_del_gt(&VS[reif_v_id], 1);

		if (VS[reif_v_id].n_vals == 0) {
4d26a735   Pedro Roque   Increased recogni...
69
70
71
72
73
74
75
76
			printf("\nConstraint ALL_DIFFERENT_REIF makes model inconsistent at creation. No solution found.\n");

#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__)
	printf("\nPress any key to exit\n");
	int a = getchar();
#endif

			exit(0);
0c8ce2b0   Pedro Roque   missing files
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
		}
	}

	// set to include in kernel compilation
	USE_CS[ALL_DIFFERENT] = 1;
	USE_CS_REIFI[ALL_DIFFERENT] = 1;

	// creates a new generic constraint
	unsigned int c_id = c_new(X_ids, n_vs, NULL, 0, reif_v_id);

	// pointers to this type of constraint functions
	CS[c_id].kind = ALL_DIFFERENT;
	CS[c_id].check_sol_f = &all_different_check;
	CS[c_id].constant_val = 0;

	return c_id;
}

/*
 * Return true if the all_different constraint is respected or false if not
 * ∀ 0 ≤ i, j < n; i != j → X[i] != X[j]
 * c - constraint to check if is respected
 * explored - if the CSP was already explored, which mean that all the variables must already be singletons
 * */
4d26a735   Pedro Roque   Increased recogni...
101
102
bool all_different_check(constr *c, bool explored) {

0c8ce2b0   Pedro Roque   missing files
103
	unsigned int i, j;
4d26a735   Pedro Roque   Increased recogni...
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119

	if (!explored) {
		for (i = 0; i < c->n_c_vs; i++) {
			if (c->c_vs[i]->n_vals > 1) {
				return false;
			}
		}
	}

	if (c->reified && VS[c->reif_v_id].n_vals > 1) {
		if (explored) {
			fprintf(stderr, "\nError: Reification variable of constraint ALL_DIFFERENT_REIF (%d) has 2 values.\n", c->c_id);
			return false;
		}
	}

0c8ce2b0   Pedro Roque   missing files
120
121
122
123
	// check if any variable inside the all_diff constraint has the same value, has domain 0 or more than
	// one value in the domain. If so, return false. Else return true.
	for (i = 0; i < c->n_c_vs; i++) {
		for (j = i + 1; j < c->n_c_vs; j++) {
4d26a735   Pedro Roque   Increased recogni...
124
125
			if (((!c->reified || (c->reified && VS[c->reif_v_id].min == 1)) && c->c_vs[i]->min == c->c_vs[j]->min)
					|| (c->reified && VS[c->reif_v_id].min == 0 && c->c_vs[i]->min != c->c_vs[j]->min)) {
0c8ce2b0   Pedro Roque   missing files
126
127

				if (explored) {
4d26a735   Pedro Roque   Increased recogni...
128
129
130
131
132
133
134
135
136

					if (c->reified) {
						fprintf(stderr, "\nError: Constraint ALL_DIFFERENT_REIF (%d) not respected:\n", c->c_id);
						fprintf(stderr, "Reif ID=%u -> minimum=%u, maximum=%u, number of values=%u\n\n", c->reif_v_id,
								b_get_min_val(&VS[c->reif_v_id].domain_b), b_get_max_val(&VS[c->reif_v_id].domain_b), b_cnt_vals(&VS[c->reif_v_id].domain_b));

					} else {
						fprintf(stderr, "\nError: Constraint ALL_DIFFERENT (%d) not respected:\n", c->c_id);
					}
0c8ce2b0   Pedro Roque   missing files
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155

					fprintf(stderr, "Variable ID=%u -> minimum=%u, maximum=%u, number of values=%u\n\n", c->c_vs[i]->v_id, b_get_min_val(&c->c_vs[i]->domain_b),
							b_get_max_val(&c->c_vs[i]->domain_b), b_cnt_vals(&c->c_vs[i]->domain_b));
					fprintf(stderr, "Variable ID=%u -> minimum=%u, maximum=%u, number of values=%u\n\n", c->c_vs[j]->v_id, b_get_min_val(&c->c_vs[j]->domain_b),
							b_get_max_val(&c->c_vs[j]->domain_b), b_cnt_vals(&c->c_vs[j]->domain_b));
				}
				return false;
			}
		}
	}
	return true;
}

#endif

#if CS_ALL_DIFFERENT == 1
/*
 * Propagate the domain of the variable with the ID prop_v_id through all the other variables on the same c_numb ID all_diff constraint
 * ∀ 0 ≤ i, j < n; i != j → X[i] != X[j]
0c8ce2b0   Pedro Roque   missing files
156
 * vs_per_c_idx - vector with all constrained variables ID per constraint, per constraint ID order
4d26a735   Pedro Roque   Increased recogni...
157
158
 * vs_prop_ - all CSP variables with current step values
 * prop_v_id - ID of the variable to propagate
0c8ce2b0   Pedro Roque   missing files
159
160
 * current_cs - constraint that should be propagated for the variable with prop_v_id ID
 * vs_id_to_prop_ - circular vector with the ids of the variables to propagate
4d26a735   Pedro Roque   Increased recogni...
161
 * prop_ok - will be set to 1 or 0 if the constraint is respected or not
0c8ce2b0   Pedro Roque   missing files
162
 */
4d26a735   Pedro Roque   Increased recogni...
163
164
165
166
167
168
169
170
CUDA_FUNC void all_different_prop( CL_INTS_MEM int *vs_per_c_idx, CL_MEMORY VARS_PROP *vs_prop_, unsigned int prop_v_id,
		CL_CS_MEM cl_constr *current_cs, CL_MEMORY unsigned short *vs_id_to_prop_, bool *prop_ok TTL_CTR) {

#if CS_R_ALL_DIFFERENT == 1
	if (current_cs->reified == 1 && prop_v_id == current_cs->reif_var_id) {
		return;
	}
#endif
0c8ce2b0   Pedro Roque   missing files
171
172
173

	if (V_N_VALS(vs_prop_[prop_v_id]) == 1) {
		int x_id;	// index of the variable which domain may be pruned with this propagation
4d26a735   Pedro Roque   Increased recogni...
174
		bool changed;
0c8ce2b0   Pedro Roque   missing files
175
176
177
178
179
180
181
182
183
184
		int i;

		// search for variables in constraint c_numb to reduce domain

		for (i = 0; i < current_cs->n_c_vs; i++) {
			CHECK_TTL(ttl_ctr, 22)

			x_id = vs_per_c_idx[i];

			// If variables are not the same
4d26a735   Pedro Roque   Increased recogni...
185
			if (x_id != convert_int (prop_v_id)) {
0c8ce2b0   Pedro Roque   missing files
186
187
188
189
190
191
192
193

				// remove singleton domain value from the other domain
				cl_v_del_val_m(&changed, &vs_prop_[x_id], V_MIN(vs_prop_[prop_v_id]) TTL_CTR_V);
				if (changed) {

					// if the removal of the value resulted in an empty domain return 0
					if (V_IS_EMPTY(vs_prop_[x_id])) {
						*prop_ok = 0;
4d26a735   Pedro Roque   Increased recogni...
194
						return;
0c8ce2b0   Pedro Roque   missing files
195
					}
4d26a735   Pedro Roque   Increased recogni...
196
197
					// Add variable to the vector that contains the variables that must be propagated
					v_add_to_prop(vs_id_to_prop_, vs_prop_, x_id);
0c8ce2b0   Pedro Roque   missing files
198
199
200
201
202
203
204
205
206
207
208
209
				}
			}
		}
	}
}

#if CS_R_ALL_DIFFERENT == 1
/*
 * Validate all_different constraint to be normally propagated, when reified
 * ∀ 0 ≤ i, j < n; i != j → X[i] != X[j]
 * vs_per_c_idx - vector with all constrained variables ID per constraint, per constraint ID order
 * vs_prop_ - all CSP variables with current step values
4d26a735   Pedro Roque   Increased recogni...
210
 * prop_v_id - ID of the variable to propagate
0c8ce2b0   Pedro Roque   missing files
211
212
213
 * current_cs - constraint that should be propagated for the variable with prop_v_id ID
 * vs_id_to_prop_ - circular vector with the ids of the variables to propagate
 */
4d26a735   Pedro Roque   Increased recogni...
214
215
CUDA_FUNC void all_different_reif( CL_INTS_MEM int *vs_per_c_idx, CL_MEMORY VARS_PROP *vs_prop_, unsigned int prop_v_id,
		CL_CS_MEM cl_constr *current_cs, CL_MEMORY unsigned short *vs_id_to_prop_ TTL_CTR) {
0c8ce2b0   Pedro Roque   missing files
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230

	if (V_N_VALS(vs_prop_[prop_v_id]) == 1) {
		VARS_PROP x;
		int x_id;	// index of the variable which domain may be pruned with this propagation
		bool changed = 0;
		bool all_singl = true;
		int i;

		// search for variables in constraint c_numb to reduce domain
		for (i = 0; i < current_cs->n_c_vs; i++) {
			CHECK_TTL(ttl_ctr, 36)

			x_id = vs_per_c_idx[i];

			// If variables are not the same
4d26a735   Pedro Roque   Increased recogni...
231
			if (x_id != convert_int (prop_v_id)) {
0c8ce2b0   Pedro Roque   missing files
232
233
234
235
236
237
238
239
240
241
242
243

				if (V_N_VALS(vs_prop_[x_id]) != 1) {
					all_singl = false;
				}

				cl_v_copy_pm(&x, &vs_prop_[x_id] TTL_CTR_V);

				// remove singleton domain value from the other domain
				cl_v_del_val_n(&changed, &x, V_MIN(vs_prop_[prop_v_id]) TTL_CTR_V);
				// if the removal of the value resulted in an empty domain return 0
				if (V_IS_EMPTY(x)) {
					cl_v_bool_del_val_m(&vs_prop_[current_cs->reif_var_id], 1 TTL_CTR_V);
4d26a735   Pedro Roque   Increased recogni...
244
					v_add_to_prop(vs_id_to_prop_, vs_prop_, convert_int (current_cs->reif_var_id));
0c8ce2b0   Pedro Roque   missing files
245
246
247
248
249
250
251
252
					return;
				}
			}
		}

		// constraint already fixed
		if (all_singl) {
			cl_v_bool_del_val_m(&vs_prop_[current_cs->reif_var_id], 0 TTL_CTR_V);
4d26a735   Pedro Roque   Increased recogni...
253
			v_add_to_prop(vs_id_to_prop_, vs_prop_, convert_int (current_cs->reif_var_id));
0c8ce2b0   Pedro Roque   missing files
254
255
256
257
258
259
260
261
262
			return;
		}
	}
}

/*
 * Propagate the domain of the variable with the ID prop_v_id through all the other variables on the same c_numb ID all_diff opposit constraint
 * ∃ 0 ≤ i, j < n; i != j → X[i] == X[j]
 * vs_per_c_idx - vector with all constrained variables ID per constraint, per constraint ID order
4d26a735   Pedro Roque   Increased recogni...
263
264
 * vs_prop_ - all CSP variables with current step values
 * prop_v_id - ID of the variable to propagate
0c8ce2b0   Pedro Roque   missing files
265
 * current_cs - constraint that should be propagated for the variable with prop_v_id ID
4d26a735   Pedro Roque   Increased recogni...
266
 * prop_ok - will be set to 1 or 0 if the constraint is respected or not
0c8ce2b0   Pedro Roque   missing files
267
 */
4d26a735   Pedro Roque   Increased recogni...
268
269
CUDA_FUNC void all_different_prop_opposite(CL_INTS_MEM int *vs_per_c_idx, CL_MEMORY VARS_PROP *vs_prop_, unsigned int prop_v_id,
		CL_CS_MEM cl_constr *current_cs, bool *prop_ok TTL_CTR) {
0c8ce2b0   Pedro Roque   missing files
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284

	if (V_N_VALS(vs_prop_[prop_v_id]) == 1) {
		int x_id;	// index of the variable which domain may be pruned with this propagation
		bool contains;
		int i;

		// search for variables in constraint c_numb to reduce domain

		for (i = 0; i < current_cs->n_c_vs; i++) {
			CHECK_TTL(ttl_ctr, 22)

			x_id = vs_per_c_idx[i];
			cl_v_contains_val_m(&contains, &vs_prop_[x_id], V_MIN(vs_prop_[prop_v_id]) TTL_CTR_V);

			// If a variable contains the prop_v_id value
4d26a735   Pedro Roque   Increased recogni...
285
			if (x_id != convert_int (prop_v_id) && contains) {
0c8ce2b0   Pedro Roque   missing files
286
287
288
289
290
291
292
293
				return;
			}
		}
		*prop_ok = 0;
	}
}
#endif

4d26a735   Pedro Roque   Increased recogni...
294
295
296
297
298
299
300
301
302
303
304
/*
 * Decides the propagator to call for this constraint
 * vs_per_c_idx - vector with all constrained variables ID per constraint, per constraint ID order
 * vs_prop_ - all CSP variables with current step values
 * prop_v_id - ID of the variable to propagate
 * current_cs - constraint that should be propagated for the variable with prop_v_id ID
 * vs_id_to_prop_ - circular vector with the ids of the variables to propagate
 * prop_ok - will be set to 1 or 0 if the constraint is respected or not
 */
CUDA_FUNC void all_different_propagate( CL_INTS_MEM int *vs_per_c_idx, CL_MEMORY VARS_PROP *vs_prop_, unsigned int prop_v_id,
		CL_CS_MEM cl_constr *current_cs, CL_MEMORY unsigned short *vs_id_to_prop_, bool *prop_ok PROPAGATED_FUNC TTL_CTR) {
0c8ce2b0   Pedro Roque   missing files
305
306
307
308
309
310

#if CS_R_ALL_DIFFERENT == 0
	all_different_prop(vs_per_c_idx, vs_prop_, prop_v_id, current_cs, vs_id_to_prop_, prop_ok TTL_CTR_V);
#if CL_STATS == 1
	*propagated = true;
#endif
4d26a735   Pedro Roque   Increased recogni...
311

0c8ce2b0   Pedro Roque   missing files
312
313
#elif CS_R_ALL_DIFFERENT == 1
	if (current_cs->reified == 1) {
4d26a735   Pedro Roque   Increased recogni...
314
315
316
317
318
319
320
321
		if (V_N_VALS(vs_prop_[current_cs->reif_var_id]) > 1) {
			all_different_reif(vs_per_c_idx, vs_prop_, prop_v_id, current_cs, vs_id_to_prop_ TTL_CTR_V);

		} else {
			if (V_MIN(vs_prop_[current_cs->reif_var_id]) == 1) {
				all_different_prop(vs_per_c_idx, vs_prop_, prop_v_id, current_cs, vs_id_to_prop_, prop_ok TTL_CTR_V);
			} else {
				all_different_prop_opposite(vs_per_c_idx, vs_prop_, prop_v_id, current_cs, prop_ok TTL_CTR_V);
0c8ce2b0   Pedro Roque   missing files
322
			}
0c8ce2b0   Pedro Roque   missing files
323
#if CL_STATS == 1
4d26a735   Pedro Roque   Increased recogni...
324
			*propagated = true;
0c8ce2b0   Pedro Roque   missing files
325
#endif
0c8ce2b0   Pedro Roque   missing files
326
327
328
329
330
331
332
333
334
		}
	} else {
		all_different_prop(vs_per_c_idx, vs_prop_, prop_v_id, current_cs, vs_id_to_prop_, prop_ok TTL_CTR_V);
#if CL_STATS == 1
		*propagated = true;
#endif
	}
#endif
}
4d26a735   Pedro Roque   Increased recogni...
335

0c8ce2b0   Pedro Roque   missing files
336
#endif
4d26a735   Pedro Roque   Increased recogni...