Blame view

src/constraints/all_different.c 9.69 KB
94b2b13d   Pedro Roque   PHACT source
1
2
3
4
/*
 * all_different.c
 *
 *  Created on: 27/08/2014
4d26a735   Pedro Roque   Increased recogni...
5
 *      Author: pedro
94b2b13d   Pedro Roque   PHACT source
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) {
94b2b13d   Pedro Roque   PHACT source
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) {
94b2b13d   Pedro Roque   PHACT source
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
			fprintf(stderr, "\nError: Constraint ALL_DIFFERENT_REIF makes model inconsistent at creation:\n");
			exit(-1);
		}
	}

	// set to include in kernel compilation
	USE_CS[ALL_DIFFERENT] = 1;
	USE_CS_REIFI[ALL_DIFFERENT] = 1;
94b2b13d   Pedro Roque   PHACT source
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100

	// 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
 * */
bool all_different_check(constr* c, bool explored) {
	unsigned int i, j;
	// 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...
101
102
			if (
#if CHECK_SOL_N_VALS
94b2b13d   Pedro Roque   PHACT source
103
				(c->c_vs[i]->to_label && c->c_vs[i]->n_vals != 1) || (c->c_vs[j]->to_label && c->c_vs[j]->n_vals != 1) ||
4d26a735   Pedro Roque   Increased recogni...
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#endif
				c->c_vs[i]->min == c->c_vs[j]->min) {

				if (explored) {
					fprintf(stderr, "\nError: Constraint ALL_DIFFERENT (%d) not respected:\n", c->c_id);

					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;
94b2b13d   Pedro Roque   PHACT source
120
121
122
123
}

#endif

4d26a735   Pedro Roque   Increased recogni...
124
125
#if CS_ALL_DIFFERENT == 1
/*
94b2b13d   Pedro Roque   PHACT source
126
127
 * 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]
4d26a735   Pedro Roque   Increased recogni...
128
129
130
131
132
133
134
135
136
  * prop_ok will be set to 1 if success or to 0 if any domain became empty
 * vs_per_c_idx - vector with all constrained variables ID per constraint, per constraint ID order
 * vs_prop_ - all CSP variables
 * prop_v_id - variable ID 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
 */
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) {
94b2b13d   Pedro Roque   PHACT source
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155

	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 changed = 0;
		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
			if (x_id != convert_int(prop_v_id)) {

				// 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) {
94b2b13d   Pedro Roque   PHACT source
156

4d26a735   Pedro Roque   Increased recogni...
157
158
					// if the removal of the value resulted in an empty domain return 0
					if (V_IS_EMPTY(vs_prop_[x_id])) {
94b2b13d   Pedro Roque   PHACT source
159
160
						*prop_ok = 0;
						i = current_cs->n_c_vs;
4d26a735   Pedro Roque   Increased recogni...
161
					} else {
94b2b13d   Pedro Roque   PHACT source
162
						// Add variable to the vector that contains the variables that must be propagated
4d26a735   Pedro Roque   Increased recogni...
163
164
165
166
167
168
169
170
						v_add_to_prop(vs_id_to_prop_, vs_prop_, x_id);
					}
				}
			}
		}
	}
}

94b2b13d   Pedro Roque   PHACT source
171
172
173
#if CS_R_ALL_DIFFERENT == 1
/*
 * Validate all_different constraint to be normally propagated, when reified
4d26a735   Pedro Roque   Increased recogni...
174
 * ∀ 0 ≤ i, j < n; i != j → X[i] != X[j]
94b2b13d   Pedro Roque   PHACT source
175
176
177
178
179
180
181
182
183
184
 * 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
 * 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
 */
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) {

	if (V_N_VALS(vs_prop_[prop_v_id]) == 1) {
		VARS_PROP x;
4d26a735   Pedro Roque   Increased recogni...
185
		int x_id;	// index of the variable which domain may be pruned with this propagation
94b2b13d   Pedro Roque   PHACT source
186
187
188
189
190
191
192
193
		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)

4d26a735   Pedro Roque   Increased recogni...
194
			x_id = vs_per_c_idx[i];
94b2b13d   Pedro Roque   PHACT source
195

4d26a735   Pedro Roque   Increased recogni...
196
197
			// If variables are not the same
			if (x_id != convert_int(prop_v_id)) {
94b2b13d   Pedro Roque   PHACT source
198
199
200
201
202
203
204
205
206
207
208
209

				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...
210
					v_add_to_prop(vs_id_to_prop_, vs_prop_, convert_int(current_cs->reif_var_id));
94b2b13d   Pedro Roque   PHACT source
211
212
213
					return;
				}
			}
4d26a735   Pedro Roque   Increased recogni...
214
215
		}

94b2b13d   Pedro Roque   PHACT source
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
		// constraint already fixed
		if (all_singl) {
			cl_v_bool_del_val_m(&vs_prop_[current_cs->reif_var_id], 0 TTL_CTR_V);
			v_add_to_prop(vs_id_to_prop_, vs_prop_, convert_int(current_cs->reif_var_id));
			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
 * vs_prop_ - all CSP variables
 * prop_v_id - variable ID to propagate
4d26a735   Pedro Roque   Increased recogni...
231
 * current_cs - constraint that should be propagated for the variable with prop_v_id ID
94b2b13d   Pedro Roque   PHACT source
232
233
234
235
236
237
238
239
240
241
242
243
 * vs_id_to_prop_ - circular vector with the ids of the variables to propagate
 */
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) {

	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

4d26a735   Pedro Roque   Increased recogni...
244
		for (i = 0; i < current_cs->n_c_vs; i++) {
94b2b13d   Pedro Roque   PHACT source
245
246
247
248
249
250
251
252
			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
			if (x_id != convert_int(prop_v_id) && contains) {
				return;
4d26a735   Pedro Roque   Increased recogni...
253
			}
94b2b13d   Pedro Roque   PHACT source
254
255
256
257
258
259
260
261
262
		}
		*prop_ok = 0;
	}
}
#endif

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) {

4d26a735   Pedro Roque   Increased recogni...
263
264
#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);
94b2b13d   Pedro Roque   PHACT source
265
#if CL_STATS == 1
4d26a735   Pedro Roque   Increased recogni...
266
	*propagated = true;
94b2b13d   Pedro Roque   PHACT source
267
#endif
4d26a735   Pedro Roque   Increased recogni...
268
269
#elif CS_R_ALL_DIFFERENT == 1
	if (current_cs->reified == 1) {
94b2b13d   Pedro Roque   PHACT source
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
		if (prop_v_id != current_cs->reif_var_id) {
			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);
			}
			if (V_N_VALS(vs_prop_[current_cs->reif_var_id]) == 1) {
				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);
				}
#if CL_STATS == 1
				*propagated = true;
#endif
			}
		}
4d26a735   Pedro Roque   Increased recogni...
285
	} else {
94b2b13d   Pedro Roque   PHACT source
286
287
288
289
290
291
292
293
		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
}
#endif
4d26a735   Pedro Roque   Increased recogni...

94b2b13d   Pedro Roque   PHACT source

4d26a735   Pedro Roque   Increased recogni...

94b2b13d   Pedro Roque   PHACT source

4d26a735   Pedro Roque   Increased recogni...

94b2b13d   Pedro Roque   PHACT source

94b2b13d   Pedro Roque   PHACT source

4d26a735   Pedro Roque   Increased recogni...

94b2b13d   Pedro Roque   PHACT source

94b2b13d   Pedro Roque   PHACT source

4d26a735   Pedro Roque   Increased recogni...

94b2b13d   Pedro Roque   PHACT source

4d26a735   Pedro Roque   Increased recogni...