Commit eef943717e684b6713d306f59ac369edb4104387
1 parent
a2ec137b
Exists in
master
Update to PaCCS version 0.91
* Renamed _fd_* output functions to fd__* (meaning that they are intended to be private to the library) and put them in the new util.h file. * Use fd__trace() and -DTRACE to produce tracing messages. fd__debug() is now reserved for real debugging output. * Use fd_const() to create variables with singleton domains. * New poly-le-k constraint. * Include paccs.h where possible. * Committed to INDEX_IN_POOL and CONSTRAINT_CLASS. * Improved domain filtering for le, lt, poly-eq, poly-eq-k and var-eq-minus. * Decoupled recording that a constraint is entailed from using CONSTRAINT_TEMPS. (Use -DDISABLE_ENTAILED to disable.)
Showing
75 changed files
with
1655 additions
and
1467 deletions
Show diff stats
Makefile
@@ -34,11 +34,11 @@ CPPFLAGS = -I$(SRC) $(ALL_DEFINES) | @@ -34,11 +34,11 @@ CPPFLAGS = -I$(SRC) $(ALL_DEFINES) | ||
34 | 34 | ||
35 | EXTRA_DEFINES = | 35 | EXTRA_DEFINES = |
36 | 36 | ||
37 | -DEFINES = -DFAST # -DNDEBUG | ||
38 | -DEFAULTS = -DREVISION_IS_VAR -DGROWABLE_POOL -DINDEX_IN_POOL -DSTORE_IN_POOL \ | 37 | +DEFINES = # -DTRACE -DNDEBUG |
38 | +DEFAULTS = -DREVISION_IS_VAR -DGROWABLE_POOL -DSTORE_IN_POOL \ | ||
39 | -DNEW_ENTRANCE -DRANDOM_VICTIM -DDOMAIN_BOUNDS | 39 | -DNEW_ENTRANCE -DRANDOM_VICTIM -DDOMAIN_BOUNDS |
40 | -REQUIRED = -DDISTRIBUTED_SOLVER -DSPLITGO -DCOMPACT_DOMAINS -DCONSTRAINT_CLASS \ | ||
41 | - -DUSE_STORE -DPACK_PROBLEM | 40 | +REQUIRED = -DDISTRIBUTED_SOLVER -DSPLITGO -DCOMPACT_DOMAINS -DUSE_STORE \ |
41 | + -DPACK_PROBLEM | ||
42 | 42 | ||
43 | ALL_DEFINES = $(REQUIRED) $(DEFAULTS) $(DEFINES) $(EXTRA_DEFINES) | 43 | ALL_DEFINES = $(REQUIRED) $(DEFAULTS) $(DEFINES) $(EXTRA_DEFINES) |
44 | 44 | ||
@@ -119,6 +119,8 @@ list.o: $(SRC)/list.c $(SRC)/list.h | @@ -119,6 +119,8 @@ list.o: $(SRC)/list.c $(SRC)/list.h | ||
119 | values.o: values.h values-bitmap.c values-intervals.c fdc_int.h | 119 | values.o: values.h values-bitmap.c values-intervals.c fdc_int.h |
120 | 120 | ||
121 | 121 | ||
122 | +queens queens-mpi : override DEFAULTS += -DDISABLE_ENTAILED | ||
123 | + | ||
122 | costas costas-mpi : override DEFAULTS += -DCONSTRAINT_TEMPS | 124 | costas costas-mpi : override DEFAULTS += -DCONSTRAINT_TEMPS |
123 | 125 | ||
124 | qap qap-mpi : override DEFAULTS += \ | 126 | qap qap-mpi : override DEFAULTS += \ |
@@ -131,7 +133,7 @@ graphs graphs-mpi : matching.c | @@ -131,7 +133,7 @@ graphs graphs-mpi : matching.c | ||
131 | 133 | ||
132 | partition partition-mpi : override DEFAULTS += -DCONSTRAINT_TEMPS | 134 | partition partition-mpi : override DEFAULTS += -DCONSTRAINT_TEMPS |
133 | 135 | ||
134 | -golomb golomb-mpi : override DEFAULTS += -DDOMAIN_BOUNDS | 136 | +golomb golomb-mpi : override DEFAULTS += -DDOMAIN_BOUNDS -DDOMAIN_BITS=128 |
135 | 137 | ||
136 | langford langford-mpi : override DEFAULTS += \ | 138 | langford langford-mpi : override DEFAULTS += \ |
137 | -UDOMAIN_BOUNDS -DINLINE_DOMAINS -DCONSTRAINT_TEMPS -DDISABLE_ENTAILED | 139 | -UDOMAIN_BOUNDS -DINLINE_DOMAINS -DCONSTRAINT_TEMPS -DDISABLE_ENTAILED |
README
1 | -PaCCS version 0.90d | 1 | +PaCCS version 0.91 |
2 | 2 | ||
3 | All files Copyright (C) 2009-2016 Vasco Pedro <vp@di.uevora.pt> | 3 | All files Copyright (C) 2009-2016 Vasco Pedro <vp@di.uevora.pt> |
4 | All rights reserved. | 4 | All rights reserved. |
@@ -38,7 +38,7 @@ Useful options include: | @@ -38,7 +38,7 @@ Useful options include: | ||
38 | -DDOMAIN_BOUNDS include the domain's current minimum and maximum values | 38 | -DDOMAIN_BOUNDS include the domain's current minimum and maximum values |
39 | in its representation (DEFAULT) | 39 | in its representation (DEFAULT) |
40 | 40 | ||
41 | - -DFAST be quiet (DEFAULT) | 41 | + -DTRACE show what's happening (part of it, anyway) |
42 | 42 | ||
43 | For other options, take a look at the Makefile, at src/options.c, or | 43 | For other options, take a look at the Makefile, at src/options.c, or |
44 | at the full solver source. | 44 | at the full solver source. |
@@ -150,6 +150,8 @@ Integer constants | @@ -150,6 +150,8 @@ Integer constants | ||
150 | 150 | ||
151 | fd_int fd_new(int min, int max) create a new variable with domain | 151 | fd_int fd_new(int min, int max) create a new variable with domain |
152 | [min, max] | 152 | [min, max] |
153 | + fd_int fd_const(int value) create a new variable with domain | ||
154 | + [value, value] | ||
153 | fd_label(fd_int vars[], int nvars) set variables to be labelled (the | 155 | fd_label(fd_int vars[], int nvars) set variables to be labelled (the |
154 | DEFAULT is to label all variables) | 156 | DEFAULT is to label all variables) |
155 | fd_var_single(fd_int var, int *val) tests whether the variable domain | 157 | fd_var_single(fd_int var, int *val) tests whether the variable domain |
@@ -181,6 +183,10 @@ Global constraints | @@ -181,6 +183,10 @@ Global constraints | ||
181 | fd_all_different(fd_int X[], int n) | 183 | fd_all_different(fd_int X[], int n) |
182 | all n variables in X have different values | 184 | all n variables in X have different values |
183 | 185 | ||
186 | + fd_fake_all_different(fd_int X[], int n) | ||
187 | + all-different implemented with pairwise fd_ne() constraints | ||
188 | + between the variables in X | ||
189 | + | ||
184 | fd_element(fd_int X[], int n, fd_int y, int k) X[y] = k | 190 | fd_element(fd_int X[], int n, fd_int y, int k) X[y] = k |
185 | fd_element_var(fd_int X[], int n, fd_int y, fd_int z) X[y] = z | 191 | fd_element_var(fd_int X[], int n, fd_int y, fd_int z) X[y] = z |
186 | 192 | ||
@@ -191,6 +197,7 @@ Global constraints | @@ -191,6 +197,7 @@ Global constraints | ||
191 | 197 | ||
192 | fd_poly_eq(int C[], fd_int Y[], int n, fd_int z) z <= C . Y <= z | 198 | fd_poly_eq(int C[], fd_int Y[], int n, fd_int z) z <= C . Y <= z |
193 | fd_poly_eq_k(int C[], fd_int Y[], int n, int k) C . Y = k | 199 | fd_poly_eq_k(int C[], fd_int Y[], int n, int k) C . Y = k |
200 | + fd_poly_le_k(int C[], fd_int Y[], int n, int k) C . Y <= k | ||
194 | fd_poly_ne(int C[], fd_int Y[], int n, fd_int z) C . Y != z | 201 | fd_poly_ne(int C[], fd_int Y[], int n, fd_int z) C . Y != z |
195 | fd_poly_ne_k(int C[], fd_int Y[], int n, int k) C . Y != k | 202 | fd_poly_ne_k(int C[], fd_int Y[], int n, int k) C . Y != k |
196 | fd_knapsack2(fd_int X[], fd_int Y[], int n, fd_int z) z <= X . Y <= z | 203 | fd_knapsack2(fd_int X[], fd_int Y[], int n, fd_int z) z <= X . Y <= z |
TUNING
@@ -11,11 +11,14 @@ qap | @@ -11,11 +11,14 @@ qap | ||
11 | costas | 11 | costas |
12 | -DCONSTRAINT_TEMPS -DDOMAIN_BOUNDS | 12 | -DCONSTRAINT_TEMPS -DDOMAIN_BOUNDS |
13 | --label --most-constrained | 13 | --label --most-constrained |
14 | + (--label --first-var performs better in some cases, at least for the 1st solution) | ||
15 | + | ||
14 | --split-even (first solution) | 16 | --split-even (first solution) |
15 | 17 | ||
16 | N <= DOMAIN_BITS / 2 | 18 | N <= DOMAIN_BITS / 2 |
17 | 19 | ||
18 | queens | 20 | queens |
21 | + -DDISABLE_ENTAILED | ||
19 | -DDOMAIN_BOUNDS ??? [not ism] | 22 | -DDOMAIN_BOUNDS ??? [not ism] |
20 | --first-fail | 23 | --first-fail |
21 | 24 | ||
@@ -41,7 +44,7 @@ golomb | @@ -41,7 +44,7 @@ golomb | ||
41 | -DDOMAIN_BOUNDS (-DCONSTRAINT_TEMPS -DDISABLE_ENTAILED [cri-lima]) | 44 | -DDOMAIN_BOUNDS (-DCONSTRAINT_TEMPS -DDISABLE_ENTAILED [cri-lima]) |
42 | --label{, --most-connected, --most-constrained} | 45 | --label{, --most-connected, --most-constrained} |
43 | --split-eager | 46 | --split-eager |
44 | - (--split-even is generally slower, but more regular) | 47 | + (--split-even is generally slower, but more stable) |
45 | 48 | ||
46 | langford | 49 | langford |
47 | [bicho] | 50 | [bicho] |
@@ -59,13 +62,15 @@ langford | @@ -59,13 +62,15 @@ langford | ||
59 | -DINLINE_DOMAINS -DCONSTRAINT_TEMPS (third best) | 62 | -DINLINE_DOMAINS -DCONSTRAINT_TEMPS (third best) |
60 | -DDOMAIN_BOUNDS -DCONSTRAINT_TEMPS -DDISABLE_ENTAILED (fourth best) | 63 | -DDOMAIN_BOUNDS -DCONSTRAINT_TEMPS -DDISABLE_ENTAILED (fourth best) |
61 | -DDOMAIN_BOUNDS (fifth best) | 64 | -DDOMAIN_BOUNDS (fifth best) |
62 | - | ||
63 | - --first-fail --val-max (--count-solutions or failure) | ||
64 | - --size-degree --val-max (first solution, not always but when | ||
65 | - it works, the effect is dramatic) | 65 | + [*] |
66 | + ? -DDOMAIN_BOUNDS | ||
66 | 67 | ||
67 | --split-eager | 68 | --split-eager |
68 | 69 | ||
70 | + --first-fail {,--val-max} (--count-solutions or inconsistent instances) | ||
71 | + --size-degree (first solution) | ||
72 | + (--first --val-max is a good overall compromise) | ||
73 | + | ||
69 | golfers | 74 | golfers |
70 | -D? | 75 | -D? |
71 | --label --val-max? | 76 | --label --val-max? |
bench/all.c
@@ -28,7 +28,7 @@ int main(int argc, char *argv[]) | @@ -28,7 +28,7 @@ int main(int argc, char *argv[]) | ||
28 | NV = atoi(argv[i]); | 28 | NV = atoi(argv[i]); |
29 | 29 | ||
30 | if (NV > MAX_VARIABLES) | 30 | if (NV > MAX_VARIABLES) |
31 | - _fd_fatal("more than MAX_VARIABLES variables requested"); | 31 | + fd__fatal("more than MAX_VARIABLES variables requested"); |
32 | 32 | ||
33 | for (i = 0; i < NV; ++i) | 33 | for (i = 0; i < NV; ++i) |
34 | vars[i] = fd_new(0, MV); | 34 | vars[i] = fd_new(0, MV); |
bench/bibd.c
@@ -33,7 +33,7 @@ int main(int argc, char *argv[]) | @@ -33,7 +33,7 @@ int main(int argc, char *argv[]) | ||
33 | #ifndef GECODE_STYLE | 33 | #ifndef GECODE_STYLE |
34 | else if (argc - i < 3) | 34 | else if (argc - i < 3) |
35 | { | 35 | { |
36 | - _fd_debug("must give V, B, and K (or nothing)\n"); | 36 | + fd__error("must give V, B, and K (or nothing)\n"); |
37 | return 1; | 37 | return 1; |
38 | } | 38 | } |
39 | else | 39 | else |
@@ -47,7 +47,7 @@ int main(int argc, char *argv[]) | @@ -47,7 +47,7 @@ int main(int argc, char *argv[]) | ||
47 | 47 | ||
48 | if (R * V != K * B) | 48 | if (R * V != K * B) |
49 | { | 49 | { |
50 | - _fd_debug("%d * %d / %d must be an integer\n", K, B, V); | 50 | + fd__error("%d * %d / %d must be an integer\n", K, B, V); |
51 | return 1; | 51 | return 1; |
52 | } | 52 | } |
53 | 53 | ||
@@ -55,13 +55,13 @@ int main(int argc, char *argv[]) | @@ -55,13 +55,13 @@ int main(int argc, char *argv[]) | ||
55 | 55 | ||
56 | if (lambda * (V - 1) != R * (K - 1)) | 56 | if (lambda * (V - 1) != R * (K - 1)) |
57 | { | 57 | { |
58 | - _fd_debug("%d * (%d - 1) / (%d - 1) must be an integer\n", R, K, V); | 58 | + fd__error("%d * (%d - 1) / (%d - 1) must be an integer\n", R, K, V); |
59 | return 1; | 59 | return 1; |
60 | } | 60 | } |
61 | #else /* GECODE_STYLE */ | 61 | #else /* GECODE_STYLE */ |
62 | else if (argc - i < 3) | 62 | else if (argc - i < 3) |
63 | { | 63 | { |
64 | - _fd_debug("must give V, K, and lambda (or nothing)\n"); | 64 | + fd__error("must give V, K, and lambda (or nothing)\n"); |
65 | return 1; | 65 | return 1; |
66 | } | 66 | } |
67 | else | 67 | else |
@@ -75,7 +75,7 @@ int main(int argc, char *argv[]) | @@ -75,7 +75,7 @@ int main(int argc, char *argv[]) | ||
75 | 75 | ||
76 | if (B * K * (K - 1) != lambda * V * (V - 1)) | 76 | if (B * K * (K - 1) != lambda * V * (V - 1)) |
77 | { | 77 | { |
78 | - _fd_debug("warning: %d * %d * (%d - 1) / %d / (%d - 1) must be an integer\n", | 78 | + fd__error("warning: %d * %d * (%d - 1) / %d / (%d - 1) must be an integer\n", |
79 | lambda, V, V, K, K); | 79 | lambda, V, V, K, K); |
80 | // return 1; | 80 | // return 1; |
81 | } | 81 | } |
@@ -84,12 +84,12 @@ int main(int argc, char *argv[]) | @@ -84,12 +84,12 @@ int main(int argc, char *argv[]) | ||
84 | 84 | ||
85 | if (R * V != K * B) | 85 | if (R * V != K * B) |
86 | { | 86 | { |
87 | - _fd_debug("warning: %d * %d / %d must be an integer\n", K, B, V); | 87 | + fd__error("warning: %d * %d / %d must be an integer\n", K, B, V); |
88 | // return 1; | 88 | // return 1; |
89 | } | 89 | } |
90 | #endif /* GECODE_STYLE */ | 90 | #endif /* GECODE_STYLE */ |
91 | 91 | ||
92 | - _fd_debug("V = %d, B = %d, K = %d, R = %d, lambda = %d\n", V, B, K, R, lambda); | 92 | + fd__info("V = %d, B = %d, K = %d, R = %d, lambda = %d\n", V, B, K, R, lambda); |
93 | 93 | ||
94 | vs = calloc(V * B, sizeof(fd_int)); | 94 | vs = calloc(V * B, sizeof(fd_int)); |
95 | ts = calloc(V > B ? V : B, sizeof(fd_int)); | 95 | ts = calloc(V > B ? V : B, sizeof(fd_int)); |
bench/c-exactly.c
1 | #include <stdio.h> | 1 | #include <stdio.h> |
2 | +#include <string.h> | ||
2 | 3 | ||
3 | -#include "fdc_int.h" | 4 | +#include <paccs.h> |
4 | 5 | ||
5 | #define N 3 | 6 | #define N 3 |
6 | 7 | ||
7 | -main(int argc, char *argv[]) | 8 | +int main(int argc, char *argv[]) |
8 | { | 9 | { |
9 | fd_int vs[N], cardinal; | 10 | fd_int vs[N], cardinal; |
10 | int solutions = 0, one_solution = 1; | 11 | int solutions = 0, one_solution = 1; |
bench/change.c
1 | #include <stdio.h> | 1 | #include <stdio.h> |
2 | +#include <stdlib.h> | ||
2 | #include <fcntl.h> | 3 | #include <fcntl.h> |
3 | #include <errno.h> | 4 | #include <errno.h> |
4 | #include <ctype.h> | 5 | #include <ctype.h> |
@@ -6,13 +7,6 @@ | @@ -6,13 +7,6 @@ | ||
6 | 7 | ||
7 | #include "fdc_int.h" | 8 | #include "fdc_int.h" |
8 | 9 | ||
9 | -// try to save on variables | ||
10 | -static fd_int fd_const[MAX_VALUE + 1]; | ||
11 | - | ||
12 | -#define FD_CONST(n) (fd_const[n] ? fd_const[n] : (fd_const[n] = fd_new(n, n))) | ||
13 | - | ||
14 | -//#define FD_CONST(n) fd_new(n, n) | ||
15 | - | ||
16 | #define NCOINS (sizeof(coins_value) / sizeof(*coins_value)) | 10 | #define NCOINS (sizeof(coins_value) / sizeof(*coins_value)) |
17 | 11 | ||
18 | int coins_value[] = { 1, 2, 5, 10, 20, 50 }; | 12 | int coins_value[] = { 1, 2, 5, 10, 20, 50 }; |
@@ -33,15 +27,15 @@ int main(int argc, char *argv[]) | @@ -33,15 +27,15 @@ int main(int argc, char *argv[]) | ||
33 | else if (isdigit(*argv[i])) | 27 | else if (isdigit(*argv[i])) |
34 | am = atoi(argv[i]); | 28 | am = atoi(argv[i]); |
35 | else | 29 | else |
36 | - _fd_error("%s: unknown argument `%s'\n", argv[0], argv[i]); | 30 | + fd__error("%s: unknown argument `%s'\n", argv[0], argv[i]); |
37 | 31 | ||
38 | for (i = 0; i < NCOINS; ++i) | 32 | for (i = 0; i < NCOINS; ++i) |
39 | - coins[i] = FD_CONST(coins_value[i]); | 33 | + coins[i] = fd_const(coins_value[i]); |
40 | 34 | ||
41 | for (i = 0; i < NCOINS; ++i) | 35 | for (i = 0; i < NCOINS; ++i) |
42 | change[i] = fd_new(0, MAX_VALUE); | 36 | change[i] = fd_new(0, MAX_VALUE); |
43 | 37 | ||
44 | - amount = FD_CONST(am); | 38 | + amount = fd_const(am); |
45 | fd_knapsack2(change, coins, NCOINS, amount); | 39 | fd_knapsack2(change, coins, NCOINS, amount); |
46 | 40 | ||
47 | ncoins = fd_new(0, MAX_VALUE); | 41 | ncoins = fd_new(0, MAX_VALUE); |
bench/costas.c
@@ -3,17 +3,10 @@ | @@ -3,17 +3,10 @@ | ||
3 | 3 | ||
4 | //#include <fcntl.h> | 4 | //#include <fcntl.h> |
5 | //#include <errno.h> | 5 | //#include <errno.h> |
6 | -//#include <ctype.h> | 6 | +#include <ctype.h> |
7 | #include <string.h> | 7 | #include <string.h> |
8 | 8 | ||
9 | -#include "fdc_int.h" | ||
10 | - | ||
11 | -// try to save on variables | ||
12 | -static fd_int fd_const[MAX_VALUE + 1]; | ||
13 | - | ||
14 | -#define FD_CONST(n) (fd_const[n] ? fd_const[n] : (fd_const[n] = fd_new(n, n))) | ||
15 | - | ||
16 | -//#define FD_CONST(n) fd_new(n, n) | 9 | +#include <paccs.h> |
17 | 10 | ||
18 | /* | 11 | /* |
19 | Costas arrays (communicated by Daniel Diaz) | 12 | Costas arrays (communicated by Daniel Diaz) |
@@ -57,7 +50,7 @@ int main(int argc, char *argv[]) | @@ -57,7 +50,7 @@ int main(int argc, char *argv[]) | ||
57 | break; | 50 | break; |
58 | } | 51 | } |
59 | else | 52 | else |
60 | - _fd_error("%s: unknown option `%s'\n", argv[0], argv[i]); | 53 | + fd__error("%s: unknown option `%s'\n", argv[0], argv[i]); |
61 | 54 | ||
62 | array = calloc(N, sizeof(*array)); | 55 | array = calloc(N, sizeof(*array)); |
63 | 56 | ||
@@ -69,7 +62,7 @@ int main(int argc, char *argv[]) | @@ -69,7 +62,7 @@ int main(int argc, char *argv[]) | ||
69 | if (strchr(argv[i], '-')) | 62 | if (strchr(argv[i], '-')) |
70 | b = atoi(strchr(argv[i], '-') + 1); | 63 | b = atoi(strchr(argv[i], '-') + 1); |
71 | 64 | ||
72 | - array[j] = (a == b) ? FD_CONST(a - 1) : fd_new(a - 1, b - 1); | 65 | + array[j] = fd_new(a - 1, b - 1); |
73 | } | 66 | } |
74 | 67 | ||
75 | for (; j < N; ++j) | 68 | for (; j < N; ++j) |
@@ -91,7 +84,7 @@ int main(int argc, char *argv[]) | @@ -91,7 +84,7 @@ int main(int argc, char *argv[]) | ||
91 | for (j = 0; j < N - 1 - i; ++j) | 84 | for (j = 0; j < N - 1 - i; ++j) |
92 | diffs(i, j) = fd_new(0, 2 * (N - 1)); | 85 | diffs(i, j) = fd_new(0, 2 * (N - 1)); |
93 | 86 | ||
94 | - diffeq[0] = FD_CONST(N - 1); | 87 | + diffeq[0] = fd_const(N - 1); |
95 | 88 | ||
96 | for (k = 1; k < N - 1; ++k) | 89 | for (k = 1; k < N - 1; ++k) |
97 | { | 90 | { |
bench/golfers.c
@@ -34,7 +34,7 @@ int main(int argc, char *argv[]) | @@ -34,7 +34,7 @@ int main(int argc, char *argv[]) | ||
34 | use_label = 1; | 34 | use_label = 1; |
35 | else if (argc - i < 3) | 35 | else if (argc - i < 3) |
36 | { | 36 | { |
37 | - _fd_debug("must give G, K, and W (or nothing)\n"); | 37 | + fd__error("must give G, K, and W (or nothing)\n"); |
38 | return 1; | 38 | return 1; |
39 | } | 39 | } |
40 | else | 40 | else |
bench/golomb.c
@@ -74,17 +74,17 @@ int main(int argc, char *argv[]) | @@ -74,17 +74,17 @@ int main(int argc, char *argv[]) | ||
74 | seed = time(0); | 74 | seed = time(0); |
75 | #else | 75 | #else |
76 | if ((dev_random = open("/dev/urandom", O_RDONLY)) == -1) | 76 | if ((dev_random = open("/dev/urandom", O_RDONLY)) == -1) |
77 | - _fd_fatal("/dev/urandom: %s\n", strerror(errno)); | 77 | + fd__fatal("/dev/urandom: %s\n", strerror(errno)); |
78 | 78 | ||
79 | read(dev_random, &seed, sizeof(seed)); | 79 | read(dev_random, &seed, sizeof(seed)); |
80 | #endif | 80 | #endif |
81 | 81 | ||
82 | srandom(seed); | 82 | srandom(seed); |
83 | - _fd_debug("seed = %u\n", seed); | 83 | + fd__trace("seed = %u\n", seed); |
84 | #endif | 84 | #endif |
85 | 85 | ||
86 | if (!fixed) | 86 | if (!fixed) |
87 | - _fd_debug("length upper bound is %d\n", DOMMAX); | 87 | + fd__trace("length upper bound is %d\n", DOMMAX); |
88 | 88 | ||
89 | D = M * (M - 1) / 2; | 89 | D = M * (M - 1) / 2; |
90 | 90 | ||
@@ -147,7 +147,7 @@ int main(int argc, char *argv[]) | @@ -147,7 +147,7 @@ int main(int argc, char *argv[]) | ||
147 | j = 0; | 147 | j = 0; |
148 | for (d = 1; d < M; ++d) | 148 | for (d = 1; d < M; ++d) |
149 | { | 149 | { |
150 | - fd_int s = fd_new(d * (d + 1) / 2, d * (d + 1) / 2); | 150 | + fd_int s = fd_const(d * (d + 1) / 2); |
151 | 151 | ||
152 | for (i = d; i < M; ++i) | 152 | for (i = d; i < M; ++i) |
153 | fd_ge(differences[j++], s); | 153 | fd_ge(differences[j++], s); |
@@ -157,7 +157,7 @@ int main(int argc, char *argv[]) | @@ -157,7 +157,7 @@ int main(int argc, char *argv[]) | ||
157 | j = 0; | 157 | j = 0; |
158 | for (d = 1; d < M; ++d) | 158 | for (d = 1; d < M; ++d) |
159 | { | 159 | { |
160 | - fd_int grl = fd_new(minimum_length[d + 1], minimum_length[d + 1]); | 160 | + fd_int grl = fd_const(minimum_length[d + 1]); |
161 | 161 | ||
162 | for (i = d; i < M; ++i) | 162 | for (i = d; i < M; ++i) |
163 | fd_ge(differences[j++], grl); | 163 | fd_ge(differences[j++], grl); |
bench/graphs.c
bench/k-queens.c
1 | #include <stdio.h> | 1 | #include <stdio.h> |
2 | +#include <stdlib.h> | ||
2 | #include <string.h> | 3 | #include <string.h> |
3 | #include <fcntl.h> | 4 | #include <fcntl.h> |
4 | #include <errno.h> | 5 | #include <errno.h> |
@@ -16,8 +17,6 @@ int main(int argc, char *argv[]) | @@ -16,8 +17,6 @@ int main(int argc, char *argv[]) | ||
16 | fd_int queens[NMAX]; | 17 | fd_int queens[NMAX]; |
17 | int solutions = 0, one_solution = 1; | 18 | int solutions = 0, one_solution = 1; |
18 | int i, j; | 19 | int i, j; |
19 | - int seed; | ||
20 | - int dev_random; | ||
21 | fd_int copy; | 20 | fd_int copy; |
22 | int ncopies = 4; | 21 | int ncopies = 4; |
23 | 22 | ||
@@ -41,7 +40,7 @@ int main(int argc, char *argv[]) | @@ -41,7 +40,7 @@ int main(int argc, char *argv[]) | ||
41 | } | 40 | } |
42 | 41 | ||
43 | if (N > NMAX) | 42 | if (N > NMAX) |
44 | - _fd_fatal("queens: more than NMAX queens requested"); | 43 | + fd__fatal("queens: more than NMAX queens requested"); |
45 | 44 | ||
46 | if (ncopies < 1) | 45 | if (ncopies < 1) |
47 | ncopies = 1; | 46 | ncopies = 1; |
@@ -49,20 +48,23 @@ int main(int argc, char *argv[]) | @@ -49,20 +48,23 @@ int main(int argc, char *argv[]) | ||
49 | copy = fd_new(0, ncopies - 1); // XXX: only allows MAX_VALUE+1 copies | 48 | copy = fd_new(0, ncopies - 1); // XXX: only allows MAX_VALUE+1 copies |
50 | 49 | ||
51 | #ifdef LOCAL_SEARCH | 50 | #ifdef LOCAL_SEARCH |
51 | + int seed; | ||
52 | #if 01 | 52 | #if 01 |
53 | seed = time(0); | 53 | seed = time(0); |
54 | seed = 1206987119; | 54 | seed = 1206987119; |
55 | //seed = 1207917731; // N = 6, best improvement termina | 55 | //seed = 1207917731; // N = 6, best improvement termina |
56 | //seed = 0; | 56 | //seed = 0; |
57 | #else | 57 | #else |
58 | - if ((dev_random = open("/dev/urandom", O_RDONLY)) == -1) | ||
59 | - _fd_fatal("/dev/urandom: %s\n", strerror(errno)); | 58 | + int dev_random; |
59 | + | ||
60 | + if ((dev_random = open("/dev/urandom", O_RDONLY)) == -1) | ||
61 | + fd__fatal("/dev/urandom: %s\n", strerror(errno)); | ||
60 | 62 | ||
61 | read(dev_random, &seed, sizeof(seed)); | 63 | read(dev_random, &seed, sizeof(seed)); |
62 | #endif | 64 | #endif |
63 | 65 | ||
64 | srandom(seed); | 66 | srandom(seed); |
65 | - _fd_debug("seed = %u\n", seed); | 67 | + fd__trace("seed = %u\n", seed); |
66 | #endif | 68 | #endif |
67 | 69 | ||
68 | /* | 70 | /* |
@@ -118,7 +120,7 @@ int main(int argc, char *argv[]) | @@ -118,7 +120,7 @@ int main(int argc, char *argv[]) | ||
118 | { | 120 | { |
119 | int j; | 121 | int j; |
120 | 122 | ||
121 | - _fd_error("\nsolution contains non-singleton variable\n"); | 123 | + fd__error("\nsolution contains non-singleton variable\n"); |
122 | 124 | ||
123 | for (j = 0; j < N; ++j) | 125 | for (j = 0; j < N; ++j) |
124 | { | 126 | { |
bench/langford.c
1 | #include <stdio.h> | 1 | #include <stdio.h> |
2 | +#include <stdlib.h> | ||
2 | #include <string.h> | 3 | #include <string.h> |
4 | +#include <ctype.h> | ||
3 | 5 | ||
4 | -#include "fdc_int.h" | 6 | +#include <paccs.h> |
5 | 7 | ||
6 | // Langford's number problem (CSPLib 024) | 8 | // Langford's number problem (CSPLib 024) |
7 | 9 | ||
@@ -58,7 +60,7 @@ int main(int argc, char *argv[]) | @@ -58,7 +60,7 @@ int main(int argc, char *argv[]) | ||
58 | break; | 60 | break; |
59 | else | 61 | else |
60 | { | 62 | { |
61 | - _fd_error("%s: invalid argument `%s'\n", argv[0], argv[arg]); | 63 | + fd__error("%s: invalid argument `%s'\n", argv[0], argv[arg]); |
62 | 64 | ||
63 | return 2; | 65 | return 2; |
64 | } | 66 | } |
@@ -74,7 +76,7 @@ int main(int argc, char *argv[]) | @@ -74,7 +76,7 @@ int main(int argc, char *argv[]) | ||
74 | //seed = 1206468701; | 76 | //seed = 1206468701; |
75 | //seed = 1208196137; // converges to a local minimum with MCH | 77 | //seed = 1208196137; // converges to a local minimum with MCH |
76 | srandom(seed); | 78 | srandom(seed); |
77 | - _fd_debug("seed = %u\n", seed); | 79 | + fd__trace("seed = %u\n", seed); |
78 | #endif | 80 | #endif |
79 | 81 | ||
80 | for (i = 0; arg < argc; ++arg, ++i) | 82 | for (i = 0; arg < argc; ++arg, ++i) |
bench/magic-seq.c
1 | #include <stdio.h> | 1 | #include <stdio.h> |
2 | +#include <stdlib.h> | ||
3 | +#include <string.h> | ||
2 | 4 | ||
3 | -#include "fdc_int.h" | 5 | +#include <paccs.h> |
4 | 6 | ||
5 | #define MAX_N 512 | 7 | #define MAX_N 512 |
6 | 8 | ||
@@ -20,7 +22,7 @@ main(int argc, char *argv[]) | @@ -20,7 +22,7 @@ main(int argc, char *argv[]) | ||
20 | N = atoi(argv[i]); | 22 | N = atoi(argv[i]); |
21 | 23 | ||
22 | if (N > MAX_N) | 24 | if (N > MAX_N) |
23 | - _fd_fatal("N > MAX_N"); | 25 | + fd__fatal("N > MAX_N"); |
24 | 26 | ||
25 | for (i = 0; i < N; ++i) | 27 | for (i = 0; i < N; ++i) |
26 | vs[i] = fd_new(0, N - 1); | 28 | vs[i] = fd_new(0, N - 1); |
bench/magic-square.c
1 | #include <stdio.h> | 1 | #include <stdio.h> |
2 | +#include <stdlib.h> | ||
2 | #include <string.h> | 3 | #include <string.h> |
3 | #include <fcntl.h> | 4 | #include <fcntl.h> |
4 | #include <errno.h> | 5 | #include <errno.h> |
5 | 6 | ||
6 | -#include "fdc_int.h" | 7 | +#include <paccs.h> |
7 | 8 | ||
8 | // (CSPLib 019) | 9 | // (CSPLib 019) |
9 | 10 | ||
@@ -37,7 +38,7 @@ int main(int argc, char *argv[]) | @@ -37,7 +38,7 @@ int main(int argc, char *argv[]) | ||
37 | } | 38 | } |
38 | 39 | ||
39 | if (N > NMAX) | 40 | if (N > NMAX) |
40 | - _fd_fatal("magic-square: maximum order exceeded"); | 41 | + fd__fatal("magic-square: maximum order exceeded"); |
41 | 42 | ||
42 | j = 0; | 43 | j = 0; |
43 | for (++i; i < argc; ++i) | 44 | for (++i; i < argc; ++i) |
@@ -158,7 +159,7 @@ int main(int argc, char *argv[]) | @@ -158,7 +159,7 @@ int main(int argc, char *argv[]) | ||
158 | for (l = 0; l < N; ++l) | 159 | for (l = 0; l < N; ++l) |
159 | for (c = 0; c < N; ++c) | 160 | for (c = 0; c < N; ++c) |
160 | if (!fd_var_single(square[l][c], NULL)) | 161 | if (!fd_var_single(square[l][c], NULL)) |
161 | - _fd_fatal("solution contains non-singleton variable"); | 162 | + fd__fatal("solution contains non-singleton variable"); |
162 | #endif | 163 | #endif |
163 | 164 | ||
164 | for (l = 0; l < N; ++l) | 165 | for (l = 0; l < N; ++l) |
bench/money.c
@@ -2,7 +2,7 @@ | @@ -2,7 +2,7 @@ | ||
2 | #include <string.h> | 2 | #include <string.h> |
3 | #include <ctype.h> | 3 | #include <ctype.h> |
4 | 4 | ||
5 | -#include "fdc_int.h" | 5 | +#include <paccs.h> |
6 | 6 | ||
7 | #define LETTERS 26 | 7 | #define LETTERS 26 |
8 | #define MAX_SIZE (10 * LETTERS) // whatever | 8 | #define MAX_SIZE (10 * LETTERS) // whatever |
bench/partition.c
@@ -3,8 +3,9 @@ | @@ -3,8 +3,9 @@ | ||
3 | 3 | ||
4 | #include <stdio.h> | 4 | #include <stdio.h> |
5 | #include <stdlib.h> | 5 | #include <stdlib.h> |
6 | +#include <string.h> | ||
6 | 7 | ||
7 | -#include "fdc_int.h" | 8 | +#include <paccs.h> |
8 | 9 | ||
9 | int main(int argc, char *argv[]) | 10 | int main(int argc, char *argv[]) |
10 | { | 11 | { |
@@ -25,7 +26,7 @@ int main(int argc, char *argv[]) | @@ -25,7 +26,7 @@ int main(int argc, char *argv[]) | ||
25 | 26 | ||
26 | if ((vs = malloc(2 * N * sizeof(*vs))) == NULL || | 27 | if ((vs = malloc(2 * N * sizeof(*vs))) == NULL || |
27 | (sqs0 = malloc(N * sizeof(*sqs0))) == NULL) | 28 | (sqs0 = malloc(N * sizeof(*sqs0))) == NULL) |
28 | - _fd_fatal("could not allocate enough memory"); | 29 | + fd__fatal("could not allocate enough memory"); |
29 | 30 | ||
30 | values = 2 * N; | 31 | values = 2 * N; |
31 | sum = N * (2 * N + 1); | 32 | sum = N * (2 * N + 1); |
bench/qap.c
@@ -21,13 +21,6 @@ | @@ -21,13 +21,6 @@ | ||
21 | 21 | ||
22 | #include "fdc_int.h" | 22 | #include "fdc_int.h" |
23 | 23 | ||
24 | -// try to save on variables | ||
25 | -static fd_int fd_const[MAX_VALUE + 1]; | ||
26 | - | ||
27 | -#define FD_CONST(n) (fd_const[n] ? fd_const[n] : (fd_const[n] = fd_new(n, n))) | ||
28 | - | ||
29 | -//#define FD_CONST(n) fd_new(n, n) | ||
30 | - | ||
31 | #define NMAX 128 | 24 | #define NMAX 128 |
32 | 25 | ||
33 | typedef struct { | 26 | typedef struct { |
@@ -249,7 +242,7 @@ int main(int argc, char *argv[]) | @@ -249,7 +242,7 @@ int main(int argc, char *argv[]) | ||
249 | ; | 242 | ; |
250 | else | 243 | else |
251 | { | 244 | { |
252 | - _fd_error("%s: invalid argument `%s'\n", argv[0], argv[j]); | 245 | + fd__error("%s: invalid argument `%s'\n", argv[0], argv[j]); |
253 | 246 | ||
254 | return 2; | 247 | return 2; |
255 | } | 248 | } |
@@ -260,10 +253,10 @@ int main(int argc, char *argv[]) | @@ -260,10 +253,10 @@ int main(int argc, char *argv[]) | ||
260 | N = P->size; | 253 | N = P->size; |
261 | 254 | ||
262 | if (N > NMAX) | 255 | if (N > NMAX) |
263 | - _fd_fatal("qap: problem too big (increase NMAX)"); | 256 | + fd__fatal("qap: problem too big (increase NMAX)"); |
264 | #ifdef QAP_MODEL_B | 257 | #ifdef QAP_MODEL_B |
265 | if (N * N > DOMAIN_BITS) | 258 | if (N * N > DOMAIN_BITS) |
266 | - _fd_fatal("qap: problem too big (model B) (increase DOMAIN_BITS)"); | 259 | + fd__fatal("qap: problem too big (model B) (increase DOMAIN_BITS)"); |
267 | #endif | 260 | #endif |
268 | 261 | ||
269 | if (swap) | 262 | if (swap) |
@@ -272,7 +265,7 @@ int main(int argc, char *argv[]) | @@ -272,7 +265,7 @@ int main(int argc, char *argv[]) | ||
272 | } | 265 | } |
273 | 266 | ||
274 | if (P->name) | 267 | if (P->name) |
275 | - _fd_debug("%s\n", P->name); | 268 | + fd__trace("%s\n", P->name); |
276 | 269 | ||
277 | { | 270 | { |
278 | int diag_cost = 0, tb = 0; | 271 | int diag_cost = 0, tb = 0; |
@@ -284,7 +277,7 @@ int main(int argc, char *argv[]) | @@ -284,7 +277,7 @@ int main(int argc, char *argv[]) | ||
284 | for (c = 0; c < N; ++c) | 277 | for (c = 0; c < N; ++c) |
285 | tb += Pflow(l, c) * Pdist(l, c); | 278 | tb += Pflow(l, c) * Pdist(l, c); |
286 | 279 | ||
287 | - _fd_debug("tight bound %d (diagonal %d)\n", tb, diag_cost); | 280 | + fd__trace("tight bound %d (diagonal %d)\n", tb, diag_cost); |
288 | } | 281 | } |
289 | 282 | ||
290 | // see if the problem is symmetric | 283 | // see if the problem is symmetric |
@@ -317,11 +310,11 @@ int main(int argc, char *argv[]) | @@ -317,11 +310,11 @@ int main(int argc, char *argv[]) | ||
317 | 310 | ||
318 | if (symmetrical) | 311 | if (symmetrical) |
319 | if (symmetrical0) | 312 | if (symmetrical0) |
320 | - _fd_debug("symmetrical problem with 0 diagonal\n"); | 313 | + fd__trace("symmetrical problem with 0 diagonal\n"); |
321 | else | 314 | else |
322 | - _fd_debug("symmetrical problem\n"); | 315 | + fd__trace("symmetrical problem\n"); |
323 | else | 316 | else |
324 | - _fd_debug("asymmetrical problem (%d, %d)\n", l, c); | 317 | + fd__trace("asymmetrical problem (%d, %d)\n", l, c); |
325 | 318 | ||
326 | if (generic) | 319 | if (generic) |
327 | symmetrical0 = 0; | 320 | symmetrical0 = 0; |
@@ -405,7 +398,7 @@ int main(int argc, char *argv[]) | @@ -405,7 +398,7 @@ int main(int argc, char *argv[]) | ||
405 | // the *transpose* of the distance matrix | 398 | // the *transpose* of the distance matrix |
406 | for (l = 0; l < N; ++l) | 399 | for (l = 0; l < N; ++l) |
407 | for (c = 0; c < N; ++c) | 400 | for (c = 0; c < N; ++c) |
408 | - distt[l][c] = FD_CONST(Pdist(c, l)); | 401 | + distt[l][c] = fd_const(Pdist(c, l)); |
409 | 402 | ||
410 | for (l = 0; l < N; ++l) | 403 | for (l = 0; l < N; ++l) |
411 | for (c = 0; c < N; ++c) | 404 | for (c = 0; c < N; ++c) |
@@ -430,7 +423,7 @@ int main(int argc, char *argv[]) | @@ -430,7 +423,7 @@ int main(int argc, char *argv[]) | ||
430 | 423 | ||
431 | for (l = 0; l < N; ++l) | 424 | for (l = 0; l < N; ++l) |
432 | for (c = 0; c < N; ++c) | 425 | for (c = 0; c < N; ++c) |
433 | - distt[l][c] = FD_CONST(Pflow(l, c)); | 426 | + distt[l][c] = fd_const(Pflow(l, c)); |
434 | 427 | ||
435 | for (l = 0; l < N; ++l) | 428 | for (l = 0; l < N; ++l) |
436 | fd_knapsack2(ndist[l], distt[l], N, sums[l]); | 429 | fd_knapsack2(ndist[l], distt[l], N, sums[l]); |
@@ -443,7 +436,7 @@ int main(int argc, char *argv[]) | @@ -443,7 +436,7 @@ int main(int argc, char *argv[]) | ||
443 | for (c = 0; c < N; ++c) | 436 | for (c = 0; c < N; ++c) |
444 | { | 437 | { |
445 | prods[0][i] = ndist[l][c]; | 438 | prods[0][i] = ndist[l][c]; |
446 | - prods[1][i] = FD_CONST(Pflow(l, c)); | 439 | + prods[1][i] = fd_const(Pflow(l, c)); |
447 | 440 | ||
448 | ++i; | 441 | ++i; |
449 | } | 442 | } |
@@ -471,7 +464,7 @@ int main(int argc, char *argv[]) | @@ -471,7 +464,7 @@ int main(int argc, char *argv[]) | ||
471 | 464 | ||
472 | for (l = 1; l < N; ++l) | 465 | for (l = 1; l < N; ++l) |
473 | for (c = 0; c < l; ++c) | 466 | for (c = 0; c < l; ++c) |
474 | - distt[l][c] = FD_CONST(Pflow(l, c)); | 467 | + distt[l][c] = fd_const(Pflow(l, c)); |
475 | 468 | ||
476 | for (l = 1; l < N; ++l) | 469 | for (l = 1; l < N; ++l) |
477 | fd_knapsack2(ndist[l], distt[l], l, sums[l - 1]); | 470 | fd_knapsack2(ndist[l], distt[l], l, sums[l - 1]); |
@@ -484,7 +477,7 @@ int main(int argc, char *argv[]) | @@ -484,7 +477,7 @@ int main(int argc, char *argv[]) | ||
484 | for (c = 0; c < l; ++c) | 477 | for (c = 0; c < l; ++c) |
485 | { | 478 | { |
486 | prods[0][i] = ndist[l][c]; | 479 | prods[0][i] = ndist[l][c]; |
487 | - prods[1][i] = FD_CONST(Pflow(l, c)); | 480 | + prods[1][i] = fd_const(Pflow(l, c)); |
488 | 481 | ||
489 | ++i; | 482 | ++i; |
490 | } | 483 | } |
@@ -499,7 +492,7 @@ int main(int argc, char *argv[]) | @@ -499,7 +492,7 @@ int main(int argc, char *argv[]) | ||
499 | for (c = 0; c < l; ++c) | 492 | for (c = 0; c < l; ++c) |
500 | { | 493 | { |
501 | prods[0][i] = ndist[l][c]; | 494 | prods[0][i] = ndist[l][c]; |
502 | - prods[1][i] = FD_CONST(Pflow(l, c)); | 495 | + prods[1][i] = fd_const(Pflow(l, c)); |
503 | 496 | ||
504 | ++i; | 497 | ++i; |
505 | } | 498 | } |
@@ -540,7 +533,7 @@ int main(int argc, char *argv[]) | @@ -540,7 +533,7 @@ int main(int argc, char *argv[]) | ||
540 | 533 | ||
541 | // distances | 534 | // distances |
542 | for (i = 0; i < N * N; ++i) | 535 | for (i = 0; i < N * N; ++i) |
543 | - dist[i] = FD_CONST(P->dist[i]); | 536 | + dist[i] = fd_const(P->dist[i]); |
544 | 537 | ||
545 | // costs | 538 | // costs |
546 | 539 | ||
@@ -585,8 +578,8 @@ int main(int argc, char *argv[]) | @@ -585,8 +578,8 @@ int main(int argc, char *argv[]) | ||
585 | 578 | ||
586 | for (l = 0; l < N; ++l) | 579 | for (l = 0; l < N; ++l) |
587 | { | 580 | { |
588 | - new_dist[l * N + l] = FD_CONST(0); | ||
589 | - npos[l * N + l] = FD_CONST(0); | 581 | + new_dist[l * N + l] = fd_const(0); |
582 | + npos[l * N + l] = fd_const(0); | ||
590 | } | 583 | } |
591 | 584 | ||
592 | for (l = 1; l < N; ++l) | 585 | for (l = 1; l < N; ++l) |
bench/queens.c
1 | #include <stdio.h> | 1 | #include <stdio.h> |
2 | +#include <stdlib.h> | ||
2 | #include <string.h> | 3 | #include <string.h> |
3 | #include <fcntl.h> | 4 | #include <fcntl.h> |
4 | #include <errno.h> | 5 | #include <errno.h> |
@@ -32,7 +33,7 @@ int main(int argc, char *argv[]) | @@ -32,7 +33,7 @@ int main(int argc, char *argv[]) | ||
32 | } | 33 | } |
33 | 34 | ||
34 | if (N > NMAX) | 35 | if (N > NMAX) |
35 | - _fd_fatal("queens: more than NMAX queens requested"); | 36 | + fd__fatal("queens: more than NMAX queens requested"); |
36 | 37 | ||
37 | #ifdef LOCAL_SEARCH | 38 | #ifdef LOCAL_SEARCH |
38 | #if 01 | 39 | #if 01 |
@@ -42,13 +43,13 @@ int main(int argc, char *argv[]) | @@ -42,13 +43,13 @@ int main(int argc, char *argv[]) | ||
42 | //seed = 0; | 43 | //seed = 0; |
43 | #else | 44 | #else |
44 | if ((dev_random = open("/dev/urandom", O_RDONLY)) == -1) | 45 | if ((dev_random = open("/dev/urandom", O_RDONLY)) == -1) |
45 | - _fd_fatal("/dev/urandom: %s\n", strerror(errno)); | 46 | + fd__fatal("/dev/urandom: %s\n", strerror(errno)); |
46 | 47 | ||
47 | read(dev_random, &seed, sizeof(seed)); | 48 | read(dev_random, &seed, sizeof(seed)); |
48 | #endif | 49 | #endif |
49 | 50 | ||
50 | srandom(seed); | 51 | srandom(seed); |
51 | - _fd_debug("seed = %u\n", seed); | 52 | + fd__trace("seed = %u\n", seed); |
52 | #endif | 53 | #endif |
53 | 54 | ||
54 | /* | 55 | /* |
@@ -104,7 +105,7 @@ int main(int argc, char *argv[]) | @@ -104,7 +105,7 @@ int main(int argc, char *argv[]) | ||
104 | { | 105 | { |
105 | int j; | 106 | int j; |
106 | 107 | ||
107 | - _fd_error("\nsolution contains non-singleton variable\n"); | 108 | + fd__error("\nsolution contains non-singleton variable\n"); |
108 | 109 | ||
109 | 110 | ||
110 | for (j = 0; j < N; ++j) | 111 | for (j = 0; j < N; ++j) |
bench/queens2.c
1 | /* solves two unconnected queens problems */ | 1 | /* solves two unconnected queens problems */ |
2 | 2 | ||
3 | #include <stdio.h> | 3 | #include <stdio.h> |
4 | +#include <stdlib.h> | ||
5 | +#include <string.h> | ||
4 | #include <fcntl.h> | 6 | #include <fcntl.h> |
5 | #include <errno.h> | 7 | #include <errno.h> |
6 | 8 | ||
7 | -#include "fdc_int.h" | 9 | +#include <paccs.h> |
8 | 10 | ||
9 | #define NMAX 200 // maximum number of queens | 11 | #define NMAX 200 // maximum number of queens |
10 | 12 | ||
@@ -75,8 +77,6 @@ int main(int argc, char *argv[]) | @@ -75,8 +77,6 @@ int main(int argc, char *argv[]) | ||
75 | fd_int queens[2 * NMAX]; | 77 | fd_int queens[2 * NMAX]; |
76 | int solutions = 0, one_solution = 1; | 78 | int solutions = 0, one_solution = 1; |
77 | int i, j; | 79 | int i, j; |
78 | - int seed; | ||
79 | - int dev_random; | ||
80 | 80 | ||
81 | fd_init(&argc, &argv); | 81 | fd_init(&argc, &argv); |
82 | 82 | ||
@@ -92,20 +92,23 @@ int main(int argc, char *argv[]) | @@ -92,20 +92,23 @@ int main(int argc, char *argv[]) | ||
92 | } | 92 | } |
93 | 93 | ||
94 | #ifdef LOCAL_SEARCH | 94 | #ifdef LOCAL_SEARCH |
95 | + int seed; | ||
95 | #if 01 | 96 | #if 01 |
96 | seed = time(0); | 97 | seed = time(0); |
97 | seed = 1206987119; | 98 | seed = 1206987119; |
98 | //seed = 1207917731; // N = 6, best improvement termina | 99 | //seed = 1207917731; // N = 6, best improvement termina |
99 | //seed = 0; | 100 | //seed = 0; |
100 | #else | 101 | #else |
101 | - if ((dev_random = open("/dev/urandom", O_RDONLY)) == -1) | ||
102 | - _fd_fatal("/dev/urandom: %s\n", strerror(errno)); | 102 | + int dev_random; |
103 | + | ||
104 | + if ((dev_random = open("/dev/urandom", O_RDONLY)) == -1) | ||
105 | + fd__fatal("/dev/urandom: %s\n", strerror(errno)); | ||
103 | 106 | ||
104 | read(dev_random, &seed, sizeof(seed)); | 107 | read(dev_random, &seed, sizeof(seed)); |
105 | #endif | 108 | #endif |
106 | 109 | ||
107 | srandom(seed); | 110 | srandom(seed); |
108 | - _fd_debug("seed = %u\n", seed); | 111 | + fd__trace("seed = %u\n", seed); |
109 | #endif | 112 | #endif |
110 | 113 | ||
111 | init_queens(queens, N1); | 114 | init_queens(queens, N1); |
@@ -120,7 +123,7 @@ int main(int argc, char *argv[]) | @@ -120,7 +123,7 @@ int main(int argc, char *argv[]) | ||
120 | #if 01 | 123 | #if 01 |
121 | for (i = 0; i < N1; ++i) | 124 | for (i = 0; i < N1; ++i) |
122 | if (!fd_var_single(queens[i], NULL)) | 125 | if (!fd_var_single(queens[i], NULL)) |
123 | - _fd_fatal("solution contains non-singleton variable"); | 126 | + fd__fatal("solution contains non-singleton variable"); |
124 | #endif | 127 | #endif |
125 | 128 | ||
126 | for (i = 0; i < N1; ++i) | 129 | for (i = 0; i < N1; ++i) |
@@ -135,7 +138,7 @@ int main(int argc, char *argv[]) | @@ -135,7 +138,7 @@ int main(int argc, char *argv[]) | ||
135 | #if 01 | 138 | #if 01 |
136 | for (i = N1; i < N1 + N2; ++i) | 139 | for (i = N1; i < N1 + N2; ++i) |
137 | if (!fd_var_single(queens[i], NULL)) | 140 | if (!fd_var_single(queens[i], NULL)) |
138 | - _fd_fatal("solution contains non-singleton variable"); | 141 | + fd__fatal("solution contains non-singleton variable"); |
139 | #endif | 142 | #endif |
140 | 143 | ||
141 | for (i = N1; i < N1 + N2; ++i) | 144 | for (i = N1; i < N1 + N2; ++i) |
bench/sudoku.c
1 | #include <stdio.h> | 1 | #include <stdio.h> |
2 | +#include <stdlib.h> | ||
3 | +#include <string.h> | ||
2 | 4 | ||
3 | -#include "fdc_int.h" | 5 | +#include <paccs.h> |
4 | 6 | ||
5 | #define floor_sqrt(s, n) {for ((s) = 0; (s) * (s) <= (n); ++(s)); --(s);} | 7 | #define floor_sqrt(s, n) {for ((s) = 0; (s) * (s) <= (n); ++(s)); --(s);} |
6 | 8 | ||
@@ -316,7 +318,7 @@ void constrain_piece(fd_int *variables, int nvariables) | @@ -316,7 +318,7 @@ void constrain_piece(fd_int *variables, int nvariables) | ||
316 | #endif | 318 | #endif |
317 | } | 319 | } |
318 | 320 | ||
319 | -main(int argc, char *argv[]) | 321 | +int main(int argc, char *argv[]) |
320 | { | 322 | { |
321 | fd_int board[N][N]; | 323 | fd_int board[N][N]; |
322 | sudoku_i *problem; | 324 | sudoku_i *problem; |
@@ -324,16 +326,17 @@ main(int argc, char *argv[]) | @@ -324,16 +326,17 @@ main(int argc, char *argv[]) | ||
324 | int sqrN; | 326 | int sqrN; |
325 | int solutions = 0, one_solution = 1; | 327 | int solutions = 0, one_solution = 1; |
326 | int i, j, np = -1; | 328 | int i, j, np = -1; |
327 | - int seed; | ||
328 | 329 | ||
329 | fd_init(&argc, &argv); | 330 | fd_init(&argc, &argv); |
330 | 331 | ||
331 | #ifdef LOCAL_SEARCH | 332 | #ifdef LOCAL_SEARCH |
333 | + int seed; | ||
334 | + | ||
332 | seed = time(0); | 335 | seed = time(0); |
333 | //seed = 1206468701; | 336 | //seed = 1206468701; |
334 | seed = 1208196137; // converges to a local minimum with MCH | 337 | seed = 1208196137; // converges to a local minimum with MCH |
335 | srandom(seed); | 338 | srandom(seed); |
336 | - _fd_debug("seed = %u\n", seed); | 339 | + fd__trace("seed = %u\n", seed); |
337 | #endif | 340 | #endif |
338 | 341 | ||
339 | for (i = 1; i < argc; ++i) | 342 | for (i = 1; i < argc; ++i) |
bench/times.c
src/VERSION
src/agents-splitgo-mpi.c
@@ -17,6 +17,8 @@ | @@ -17,6 +17,8 @@ | ||
17 | #include "splitting.h" | 17 | #include "splitting.h" |
18 | #include "bound.h" | 18 | #include "bound.h" |
19 | 19 | ||
20 | +#include "util.h" | ||
21 | + | ||
20 | #ifndef COMPACT_DOMAINS | 22 | #ifndef COMPACT_DOMAINS |
21 | #error "only works with COMPACT_DOMAINS" | 23 | #error "only works with COMPACT_DOMAINS" |
22 | #endif | 24 | #endif |
@@ -135,7 +137,7 @@ void _fd_statistics_msgs() | @@ -135,7 +137,7 @@ void _fd_statistics_msgs() | ||
135 | { | 137 | { |
136 | extern int tid; | 138 | extern int tid; |
137 | 139 | ||
138 | - _fd_output("[%d] messages: %lu sent, %lu received\n", tid, _fd_msgs_sent, | 140 | + fd__output("[%d] messages: %lu sent, %lu received\n", tid, _fd_msgs_sent, |
139 | _fd_msgs_received); | 141 | _fd_msgs_received); |
140 | } | 142 | } |
141 | #else /* STATS_MSGS */ | 143 | #else /* STATS_MSGS */ |
@@ -214,7 +216,7 @@ int _fd_agent(int n) | @@ -214,7 +216,7 @@ int _fd_agent(int n) | ||
214 | int result; | 216 | int result; |
215 | struct timeval ti, tis, to, tos; | 217 | struct timeval ti, tis, to, tos; |
216 | 218 | ||
217 | - _fd_debug("[%d.%d] agent starting\n", tid, n); | 219 | + fd__trace("[%d.%d] agent starting\n", tid, n); |
218 | 220 | ||
219 | gettimeofday(&ti, NULL); | 221 | gettimeofday(&ti, NULL); |
220 | 222 | ||
@@ -238,17 +240,17 @@ int _fd_agent(int n) | @@ -238,17 +240,17 @@ int _fd_agent(int n) | ||
238 | gettimeofday(&to, NULL); | 240 | gettimeofday(&to, NULL); |
239 | timersub(&to, &tis, &tos); | 241 | timersub(&to, &tis, &tos); |
240 | timersub(&to, &ti, &to); | 242 | timersub(&to, &ti, &to); |
241 | - _fd_debug("[%d.%d] took %d.%06ds (%d.%06ds)\n", tid, n, | 243 | + fd__trace("[%d.%d] took %d.%06ds (%d.%06ds)\n", tid, n, |
242 | tos.tv_sec, tos.tv_usec, to.tv_sec, to.tv_usec); | 244 | tos.tv_sec, tos.tv_usec, to.tv_sec, to.tv_usec); |
243 | 245 | ||
244 | while (result == FD_OK) | 246 | while (result == FD_OK) |
245 | { | 247 | { |
246 | - _fd_debug("[%d.%d] agent was successful\n", tid, n); | 248 | + fd__trace("[%d.%d] agent was successful\n", tid, n); |
247 | 249 | ||
248 | // ensure that only one agent signals its success | 250 | // ensure that only one agent signals its success |
249 | // XXX: only good (?) if only looking for the 1st solution | 251 | // XXX: only good (?) if only looking for the 1st solution |
250 | pthread_mutex_lock(&success_mutex); | 252 | pthread_mutex_lock(&success_mutex); |
251 | - _fd_debug("[%d.%d] acquired success mutex\n", tid, n); | 253 | + fd__trace("[%d.%d] acquired success mutex\n", tid, n); |
252 | 254 | ||
253 | // tell the main thread that this agent is done | 255 | // tell the main thread that this agent is done |
254 | if (sem_wait(&ready_semaphore)) | 256 | if (sem_wait(&ready_semaphore)) |
@@ -260,14 +262,14 @@ int _fd_agent(int n) | @@ -260,14 +262,14 @@ int _fd_agent(int n) | ||
260 | perror("sem_post"); | 262 | perror("sem_post"); |
261 | 263 | ||
262 | pthread_mutex_unlock(&success_mutex); | 264 | pthread_mutex_unlock(&success_mutex); |
263 | - _fd_debug("[%d.%d] released success mutex\n", tid, n); | 265 | + fd__trace("[%d.%d] released success mutex\n", tid, n); |
264 | 266 | ||
265 | if (!_fd_optimising) | 267 | if (!_fd_optimising) |
266 | break; | 268 | break; |
267 | 269 | ||
268 | if (sem_wait(&resume_semaphore)) | 270 | if (sem_wait(&resume_semaphore)) |
269 | perror("sem_post (resume)"); | 271 | perror("sem_post (resume)"); |
270 | - _fd_debug("[%d.%d] resuming, new bound is %d\n", tid, n, _fd_bound_value()); | 272 | + fd__trace("[%d.%d] resuming, new bound is %d\n", tid, n, _fd_bound_value()); |
271 | 273 | ||
272 | // find the next solution | 274 | // find the next solution |
273 | gettimeofday(&tis, NULL); | 275 | gettimeofday(&tis, NULL); |
@@ -277,7 +279,7 @@ int _fd_agent(int n) | @@ -277,7 +279,7 @@ int _fd_agent(int n) | ||
277 | gettimeofday(&to, NULL); | 279 | gettimeofday(&to, NULL); |
278 | timersub(&to, &tis, &tos); | 280 | timersub(&to, &tis, &tos); |
279 | timersub(&to, &ti, &to); | 281 | timersub(&to, &ti, &to); |
280 | - _fd_debug("[%d.%d] took %d.%06ds (%d.%06ds)\n", tid, n, | 282 | + fd__trace("[%d.%d] took %d.%06ds (%d.%06ds)\n", tid, n, |
281 | tos.tv_sec, tos.tv_usec, to.tv_sec, to.tv_usec); | 283 | tos.tv_sec, tos.tv_usec, to.tv_sec, to.tv_usec); |
282 | } | 284 | } |
283 | 285 | ||
@@ -286,7 +288,7 @@ int _fd_agent(int n) | @@ -286,7 +288,7 @@ int _fd_agent(int n) | ||
286 | break; | 288 | break; |
287 | 289 | ||
288 | // eventually, the agent will fail to find a solution | 290 | // eventually, the agent will fail to find a solution |
289 | - _fd_debug("[%d.%d] agent was unsuccessful\n", tid, n); | 291 | + fd__trace("[%d.%d] agent was unsuccessful\n", tid, n); |
290 | 292 | ||
291 | // tell the main thread that this agent is done | 293 | // tell the main thread that this agent is done |
292 | if (sem_wait(&ready_semaphore)) | 294 | if (sem_wait(&ready_semaphore)) |
@@ -304,7 +306,7 @@ int _fd_agent(int n) | @@ -304,7 +306,7 @@ int _fd_agent(int n) | ||
304 | #if STEAL_WORK >= 2 | 306 | #if STEAL_WORK >= 2 |
305 | do { | 307 | do { |
306 | // wait for more work | 308 | // wait for more work |
307 | - _fd_debug("[%d.%d] waiting for more work\n", tid, n); | 309 | + fd__trace("[%d.%d] waiting for more work\n", tid, n); |
308 | pthread_cond_wait(&continue_cond, &continue_mutex); | 310 | pthread_cond_wait(&continue_cond, &continue_mutex); |
309 | } while(n >= agents_to_run); | 311 | } while(n >= agents_to_run); |
310 | 312 | ||
@@ -325,7 +327,7 @@ int _fd_agent(int n) | @@ -325,7 +327,7 @@ int _fd_agent(int n) | ||
325 | unsigned long long solutions; | 327 | unsigned long long solutions; |
326 | struct timeval ti, tis, to, tos; | 328 | struct timeval ti, tis, to, tos; |
327 | 329 | ||
328 | - _fd_debug("[%d.%d] agent starting\n", tid, n); | 330 | + fd__trace("[%d.%d] agent starting\n", tid, n); |
329 | 331 | ||
330 | gettimeofday(&ti, NULL); | 332 | gettimeofday(&ti, NULL); |
331 | 333 | ||
@@ -346,10 +348,10 @@ int _fd_agent(int n) | @@ -346,10 +348,10 @@ int _fd_agent(int n) | ||
346 | gettimeofday(&to, NULL); | 348 | gettimeofday(&to, NULL); |
347 | timersub(&to, &tis, &tos); | 349 | timersub(&to, &tis, &tos); |
348 | timersub(&to, &ti, &to); | 350 | timersub(&to, &ti, &to); |
349 | - _fd_debug("[%d.%d] took %d.%06ds (%d.%06ds)\n", tid, n, | 351 | + fd__trace("[%d.%d] took %d.%06ds (%d.%06ds)\n", tid, n, |
350 | tos.tv_sec, tos.tv_usec, to.tv_sec, to.tv_usec); | 352 | tos.tv_sec, tos.tv_usec, to.tv_sec, to.tv_usec); |
351 | 353 | ||
352 | - _fd_debug("[%d.%d] found %llu solutions\n", tid, n, solutions); | 354 | + fd__trace("[%d.%d] found %llu solutions\n", tid, n, solutions); |
353 | 355 | ||
354 | // tell the main thread that this agent is done | 356 | // tell the main thread that this agent is done |
355 | if (sem_wait(&ready_semaphore)) | 357 | if (sem_wait(&ready_semaphore)) |
@@ -370,7 +372,7 @@ int _fd_agent(int n) | @@ -370,7 +372,7 @@ int _fd_agent(int n) | ||
370 | #if STEAL_WORK >= 2 | 372 | #if STEAL_WORK >= 2 |
371 | do { | 373 | do { |
372 | // wait for more work | 374 | // wait for more work |
373 | - _fd_debug("[%d.%d] waiting for more work\n", tid, n); | 375 | + fd__trace("[%d.%d] waiting for more work\n", tid, n); |
374 | pthread_cond_wait(&continue_cond, &continue_mutex); | 376 | pthread_cond_wait(&continue_cond, &continue_mutex); |
375 | } while (n >= agents_to_run); | 377 | } while (n >= agents_to_run); |
376 | 378 | ||
@@ -406,7 +408,7 @@ static void _fd_send(int to, int tag) | @@ -406,7 +408,7 @@ static void _fd_send(int to, int tag) | ||
406 | MPI_Request mpi_request = MPI_REQUEST_NULL; | 408 | MPI_Request mpi_request = MPI_REQUEST_NULL; |
407 | 409 | ||
408 | if (MPI_Isend(NULL, 0, MPI_CHAR, to, tag, MPI_COMM_WORLD, &mpi_request)) | 410 | if (MPI_Isend(NULL, 0, MPI_CHAR, to, tag, MPI_COMM_WORLD, &mpi_request)) |
409 | - _fd_fatal("MPI_Isend failed"); | 411 | + fd__fatal("MPI_Isend failed"); |
410 | } | 412 | } |
411 | 413 | ||
412 | /* send TO a message with data (non-blocking) */ | 414 | /* send TO a message with data (non-blocking) */ |
@@ -415,7 +417,7 @@ static void _fd_send_data(int to, int tag, void *buf, int n, MPI_Datatype type) | @@ -415,7 +417,7 @@ static void _fd_send_data(int to, int tag, void *buf, int n, MPI_Datatype type) | ||
415 | MPI_Request mpi_request = MPI_REQUEST_NULL; | 417 | MPI_Request mpi_request = MPI_REQUEST_NULL; |
416 | 418 | ||
417 | if (MPI_Isend(buf, n, type, to, tag, MPI_COMM_WORLD, &mpi_request)) | 419 | if (MPI_Isend(buf, n, type, to, tag, MPI_COMM_WORLD, &mpi_request)) |
418 | - _fd_fatal("MPI_Isend failed"); | 420 | + fd__fatal("MPI_Isend failed"); |
419 | } | 421 | } |
420 | 422 | ||
421 | #if STEAL_WORK >= 2 | 423 | #if STEAL_WORK >= 2 |
@@ -427,26 +429,26 @@ static void _fd_ssend_data(int to, int tag, void *buf, int n, MPI_Datatype type, | @@ -427,26 +429,26 @@ static void _fd_ssend_data(int to, int tag, void *buf, int n, MPI_Datatype type, | ||
427 | { | 429 | { |
428 | #ifndef MAD_MPI | 430 | #ifndef MAD_MPI |
429 | if (MPI_Issend(buf, n, type, to, tag, MPI_COMM_WORLD, request)) | 431 | if (MPI_Issend(buf, n, type, to, tag, MPI_COMM_WORLD, request)) |
430 | - _fd_fatal("MPI_Issend failed"); | 432 | + fd__fatal("MPI_Issend failed"); |
431 | 433 | ||
432 | #if 0 | 434 | #if 0 |
433 | { | 435 | { |
434 | int mpi_flag; | 436 | int mpi_flag; |
435 | 437 | ||
436 | - _fd_debug("[%d] MPI_Test = %d\n", tid, | 438 | + fd__debug("[%d] MPI_Test = %d\n", tid, |
437 | MPI_Test(request, &mpi_flag, MPI_STATUS_IGNORE)); | 439 | MPI_Test(request, &mpi_flag, MPI_STATUS_IGNORE)); |
438 | 440 | ||
439 | if (mpi_flag) | 441 | if (mpi_flag) |
440 | - _fd_debug("[%d] send completed\n", tid); | 442 | + fd__debug("[%d] send completed\n", tid); |
441 | else | 443 | else |
442 | - _fd_debug("[%d] send didn't complete yet\n", tid); | 444 | + fd__debug("[%d] send didn't complete yet\n", tid); |
443 | } | 445 | } |
444 | #endif | 446 | #endif |
445 | #else /* MAD_MPI */ | 447 | #else /* MAD_MPI */ |
446 | // XXX: NMAD doesn't have MPI_Issend | 448 | // XXX: NMAD doesn't have MPI_Issend |
447 | // XXX: no record of the sending is left | 449 | // XXX: no record of the sending is left |
448 | if (MPI_Ssend(buf, n, type, to, tag, MPI_COMM_WORLD)) | 450 | if (MPI_Ssend(buf, n, type, to, tag, MPI_COMM_WORLD)) |
449 | - _fd_fatal("MPI_Send failed"); | 451 | + fd__fatal("MPI_Send failed"); |
450 | 452 | ||
451 | *request = MPI_REQUEST_NULL; | 453 | *request = MPI_REQUEST_NULL; |
452 | #endif /* MAD_MPI */ | 454 | #endif /* MAD_MPI */ |
@@ -456,7 +458,7 @@ static void _fd_ssend_data(int to, int tag, void *buf, int n, MPI_Datatype type, | @@ -456,7 +458,7 @@ static void _fd_ssend_data(int to, int tag, void *buf, int n, MPI_Datatype type, | ||
456 | MPI_Request mpi_request = MPI_REQUEST_NULL; | 458 | MPI_Request mpi_request = MPI_REQUEST_NULL; |
457 | 459 | ||
458 | if (MPI_Isend(buf, n, type, to, tag, MPI_COMM_WORLD, &mpi_request)) | 460 | if (MPI_Isend(buf, n, type, to, tag, MPI_COMM_WORLD, &mpi_request)) |
459 | - _fd_fatal("MPI_Isend failed"); | 461 | + fd__fatal("MPI_Isend failed"); |
460 | } | 462 | } |
461 | } | 463 | } |
462 | #endif /* STEAL_WORK >= 2 */ | 464 | #endif /* STEAL_WORK >= 2 */ |
@@ -466,7 +468,7 @@ static void fd__send_empty_store(int to, int tag, _fd_store buffer, | @@ -466,7 +468,7 @@ static void fd__send_empty_store(int to, int tag, _fd_store buffer, | ||
466 | { | 468 | { |
467 | if (MPI_Isend(buffer, 0, MPI_DOMAIN_TYPE, | 469 | if (MPI_Isend(buffer, 0, MPI_DOMAIN_TYPE, |
468 | to, tag, MPI_COMM_WORLD, request)) | 470 | to, tag, MPI_COMM_WORLD, request)) |
469 | - _fd_fatal("MPI_Isend failed"); | 471 | + fd__fatal("MPI_Isend failed"); |
470 | } | 472 | } |
471 | 473 | ||
472 | static void _fd_send_store(int to, int tag, _fd_store buffer, | 474 | static void _fd_send_store(int to, int tag, _fd_store buffer, |
@@ -481,7 +483,7 @@ static void _fd_send_store(int to, int tag, _fd_store buffer, | @@ -481,7 +483,7 @@ static void _fd_send_store(int to, int tag, _fd_store buffer, | ||
481 | { | 483 | { |
482 | if (MPI_Isend(buffer, fd_variables_count * DOMAIN_WORDS, MPI_DOMAIN_TYPE, | 484 | if (MPI_Isend(buffer, fd_variables_count * DOMAIN_WORDS, MPI_DOMAIN_TYPE, |
483 | to, tag, MPI_COMM_WORLD, request)) | 485 | to, tag, MPI_COMM_WORLD, request)) |
484 | - _fd_fatal("MPI_Isend failed"); | 486 | + fd__fatal("MPI_Isend failed"); |
485 | } | 487 | } |
486 | } | 488 | } |
487 | 489 | ||
@@ -492,7 +494,7 @@ static int _fd_recv_store(int from, int tag, _fd_store buffer) | @@ -492,7 +494,7 @@ static int _fd_recv_store(int from, int tag, _fd_store buffer) | ||
492 | 494 | ||
493 | if (MPI_Recv(buffer, fd_variables_count * DOMAIN_WORDS, MPI_DOMAIN_TYPE, | 495 | if (MPI_Recv(buffer, fd_variables_count * DOMAIN_WORDS, MPI_DOMAIN_TYPE, |
494 | from, tag, MPI_COMM_WORLD, &status)) | 496 | from, tag, MPI_COMM_WORLD, &status)) |
495 | - _fd_fatal("MPI_Recv failed"); | 497 | + fd__fatal("MPI_Recv failed"); |
496 | 498 | ||
497 | MPI_Get_count(&status, MPI_DOMAIN_TYPE, &count); | 499 | MPI_Get_count(&status, MPI_DOMAIN_TYPE, &count); |
498 | 500 | ||
@@ -511,7 +513,7 @@ static void _fd_broadcast(int msg, int processes, int from) | @@ -511,7 +513,7 @@ static void _fd_broadcast(int msg, int processes, int from) | ||
511 | mpi_request = malloc(sizeof(MPI_Request)); | 513 | mpi_request = malloc(sizeof(MPI_Request)); |
512 | 514 | ||
513 | if (MPI_Isend(NULL, 0, MPI_CHAR, i, msg, MPI_COMM_WORLD, mpi_request)) | 515 | if (MPI_Isend(NULL, 0, MPI_CHAR, i, msg, MPI_COMM_WORLD, mpi_request)) |
514 | - _fd_fatal("MPI_Isend failed"); | 516 | + fd__fatal("MPI_Isend failed"); |
515 | 517 | ||
516 | fd_list_append(pending_requests, mpi_request); | 518 | fd_list_append(pending_requests, mpi_request); |
517 | } | 519 | } |
@@ -522,7 +524,7 @@ static void _fd_broadcast(int msg, int processes, int from) | @@ -522,7 +524,7 @@ static void _fd_broadcast(int msg, int processes, int from) | ||
522 | for (i = 0; i < processes; ++i) | 524 | for (i = 0; i < processes; ++i) |
523 | if (i != from) | 525 | if (i != from) |
524 | if (MPI_Isend(NULL, 0, MPI_CHAR, i, msg, MPI_COMM_WORLD, &mpi_request)) | 526 | if (MPI_Isend(NULL, 0, MPI_CHAR, i, msg, MPI_COMM_WORLD, &mpi_request)) |
525 | - _fd_fatal("MPI_Isend failed"); | 527 | + fd__fatal("MPI_Isend failed"); |
526 | #endif | 528 | #endif |
527 | } | 529 | } |
528 | 530 | ||
@@ -560,9 +562,9 @@ static bool _fd_probe_external(int tag, char *name, int *source, bool consume) | @@ -560,9 +562,9 @@ static bool _fd_probe_external(int tag, char *name, int *source, bool consume) | ||
560 | if (s) | 562 | if (s) |
561 | { | 563 | { |
562 | char es[1024]; int _; | 564 | char es[1024]; int _; |
563 | - _fd_debug("MPI_Iprobe %s returned %d\n", name, s); | 565 | + fd__debug("MPI_Iprobe %s returned %d\n", name, s); |
564 | MPI_Error_string(s, es, &_); | 566 | MPI_Error_string(s, es, &_); |
565 | - _fd_debug("%s\n", es); | 567 | + fd__debug("%s\n", es); |
566 | } | 568 | } |
567 | #endif | 569 | #endif |
568 | 570 | ||
@@ -570,13 +572,13 @@ static bool _fd_probe_external(int tag, char *name, int *source, bool consume) | @@ -570,13 +572,13 @@ static bool _fd_probe_external(int tag, char *name, int *source, bool consume) | ||
570 | { | 572 | { |
571 | *source = mpi_status.MPI_SOURCE; | 573 | *source = mpi_status.MPI_SOURCE; |
572 | 574 | ||
573 | - _fd_debug("[%d] got %s from %d\n", tid, name, *source); | 575 | + fd__trace("[%d] got %s from %d\n", tid, name, *source); |
574 | 576 | ||
575 | // consume message | 577 | // consume message |
576 | if (consume) | 578 | if (consume) |
577 | if (MPI_Recv(NULL, 0, MPI_CHAR, mpi_status.MPI_SOURCE, tag, | 579 | if (MPI_Recv(NULL, 0, MPI_CHAR, mpi_status.MPI_SOURCE, tag, |
578 | MPI_COMM_WORLD, &mpi_status)) | 580 | MPI_COMM_WORLD, &mpi_status)) |
579 | - _fd_fatal("MPI_Recv failed"); | 581 | + fd__fatal("MPI_Recv failed"); |
580 | 582 | ||
581 | return true; | 583 | return true; |
582 | } | 584 | } |
@@ -590,7 +592,7 @@ static int _fd_get_event(int running, int *source, int *timeout) | @@ -590,7 +592,7 @@ static int _fd_get_event(int running, int *source, int *timeout) | ||
590 | double tin, tmout = 0; | 592 | double tin, tmout = 0; |
591 | int event; | 593 | int event; |
592 | 594 | ||
593 | - _fd_debug("[%d] getting next event\n", tid); | 595 | + fd__trace("[%d] getting next event\n", tid); |
594 | 596 | ||
595 | if (timeout && *timeout) | 597 | if (timeout && *timeout) |
596 | { | 598 | { |
@@ -606,14 +608,14 @@ static int _fd_get_event(int running, int *source, int *timeout) | @@ -606,14 +608,14 @@ static int _fd_get_event(int running, int *source, int *timeout) | ||
606 | if (sem_trywait(¬ify_semaphore)) | 608 | if (sem_trywait(¬ify_semaphore)) |
607 | { | 609 | { |
608 | if (errno == EAGAIN) | 610 | if (errno == EAGAIN) |
609 | - ; //_fd_debug("[%d] notify semaphore is busy\n", tid); | 611 | + ; //fd__trace("[%d] notify semaphore is busy\n", tid); |
610 | else | 612 | else |
611 | perror("sem_trywait (notify)"); | 613 | perror("sem_trywait (notify)"); |
612 | } | 614 | } |
613 | else | 615 | else |
614 | { | 616 | { |
615 | // got something from one of the agents | 617 | // got something from one of the agents |
616 | - _fd_debug("[%d] got something from an agent\n", tid); | 618 | + fd__trace("[%d] got something from an agent\n", tid); |
617 | 619 | ||
618 | if (!_fd_counting_solutions) | 620 | if (!_fd_counting_solutions) |
619 | { | 621 | { |
@@ -622,7 +624,7 @@ static int _fd_get_event(int running, int *source, int *timeout) | @@ -622,7 +624,7 @@ static int _fd_get_event(int running, int *source, int *timeout) | ||
622 | if (sem_post(&ready_semaphore)) | 624 | if (sem_post(&ready_semaphore)) |
623 | perror("sem_post"); | 625 | perror("sem_post"); |
624 | 626 | ||
625 | - _fd_debug("[%d] got an answer from %s%d\n", tid, | 627 | + fd__trace("[%d] got an answer from %s%d\n", tid, |
626 | s == -1 ? "-" : "", s + (s < 0)); | 628 | s == -1 ? "-" : "", s + (s < 0)); |
627 | 629 | ||
628 | if (s >= 0) | 630 | if (s >= 0) |
@@ -719,17 +721,17 @@ static int _fd_get_event(int running, int *source, int *timeout) | @@ -719,17 +721,17 @@ static int _fd_get_event(int running, int *source, int *timeout) | ||
719 | event = EV_EXT_READY; | 721 | event = EV_EXT_READY; |
720 | break; | 722 | break; |
721 | default: | 723 | default: |
722 | - _fd_debug("[%d] unknown tag %d\n", tid, mpi_status.MPI_TAG); | ||
723 | - _fd_fatal("unknown tag in message"); | 724 | + fd__debug("[%d] unknown tag %d\n", tid, mpi_status.MPI_TAG); |
725 | + fd__fatal("unknown tag in message"); | ||
724 | } | 726 | } |
725 | 727 | ||
726 | - _fd_debug("[%d] got %s from %d\n", tid, name, *source); | 728 | + fd__trace("[%d] got %s from %d\n", tid, name, *source); |
727 | 729 | ||
728 | // consume message | 730 | // consume message |
729 | if (consume) | 731 | if (consume) |
730 | if (MPI_Recv(NULL, 0, MPI_CHAR, mpi_status.MPI_SOURCE, | 732 | if (MPI_Recv(NULL, 0, MPI_CHAR, mpi_status.MPI_SOURCE, |
731 | mpi_status.MPI_TAG, MPI_COMM_WORLD, &mpi_status)) | 733 | mpi_status.MPI_TAG, MPI_COMM_WORLD, &mpi_status)) |
732 | - _fd_fatal("MPI_Recv failed"); | 734 | + fd__fatal("MPI_Recv failed"); |
733 | 735 | ||
734 | break; | 736 | break; |
735 | } | 737 | } |
@@ -862,22 +864,22 @@ static void _fd_flush_events(int procno) | @@ -862,22 +864,22 @@ static void _fd_flush_events(int procno) | ||
862 | while (mpi_request = fd_list_remove(pending_requests)) | 864 | while (mpi_request = fd_list_remove(pending_requests)) |
863 | { | 865 | { |
864 | if (MPI_Test(mpi_request, &mpi_flag, MPI_STATUS_IGNORE)) | 866 | if (MPI_Test(mpi_request, &mpi_flag, MPI_STATUS_IGNORE)) |
865 | - _fd_debug("[%d] MPI_Test failed\n", procno); | 867 | + fd__debug("[%d] MPI_Test failed\n", procno); |
866 | 868 | ||
867 | if (!mpi_flag) | 869 | if (!mpi_flag) |
868 | { | 870 | { |
869 | #if 0 // this is probably the solution just sent, not cancelling it | 871 | #if 0 // this is probably the solution just sent, not cancelling it |
870 | - _fd_debug("[%d] cancelling request\n", procno); | 872 | + fd__trace("[%d] cancelling request\n", procno); |
871 | 873 | ||
872 | if (MPI_Cancel(mpi_request)) | 874 | if (MPI_Cancel(mpi_request)) |
873 | - _fd_debug("[%d] MPI_Cancel failed\n", procno); | 875 | + fd__debug("[%d] MPI_Cancel failed\n", procno); |
874 | 876 | ||
875 | - _fd_debug("[%d] waiting for cancellation completion\n", procno); | 877 | + fd__trace("[%d] waiting for cancellation completion\n", procno); |
876 | 878 | ||
877 | if (MPI_Wait(mpi_request, MPI_STATUS_IGNORE)) | 879 | if (MPI_Wait(mpi_request, MPI_STATUS_IGNORE)) |
878 | - _fd_debug("[%d] MPI_Wait failed\n", procno); | 880 | + fd__debug("[%d] MPI_Wait failed\n", procno); |
879 | #else | 881 | #else |
880 | - _fd_debug("[%d] found a not completed request\n", procno); | 882 | + fd__debug("[%d] found a not completed request\n", procno); |
881 | #endif | 883 | #endif |
882 | } | 884 | } |
883 | 885 | ||
@@ -911,7 +913,7 @@ static void _fd_flush_events(int procno) | @@ -911,7 +913,7 @@ static void _fd_flush_events(int procno) | ||
911 | name = "FD_MSG_SOLUTION"; | 913 | name = "FD_MSG_SOLUTION"; |
912 | type = MPI_DOMAIN_TYPE; | 914 | type = MPI_DOMAIN_TYPE; |
913 | count = fd_variables_count * DOMAIN_WORDS; | 915 | count = fd_variables_count * DOMAIN_WORDS; |
914 | - _fd_error("[%d] dropping %s from %d\n", tid, name, source); | 916 | + fd__error("[%d] dropping %s from %d\n", tid, name, source); |
915 | break; | 917 | break; |
916 | case FD_MSG_FAIL: | 918 | case FD_MSG_FAIL: |
917 | name = "FD_MSG_FAIL"; | 919 | name = "FD_MSG_FAIL"; |
@@ -928,13 +930,13 @@ static void _fd_flush_events(int procno) | @@ -928,13 +930,13 @@ static void _fd_flush_events(int procno) | ||
928 | name = "FD_MSG_COUNT"; | 930 | name = "FD_MSG_COUNT"; |
929 | type = MPI_LONG_LONG; | 931 | type = MPI_LONG_LONG; |
930 | count = 1; | 932 | count = 1; |
931 | - _fd_error("[%d] dropping %s from %d\n", tid, name, source); | 933 | + fd__error("[%d] dropping %s from %d\n", tid, name, source); |
932 | break; | 934 | break; |
933 | case FD_MSG_STORE: | 935 | case FD_MSG_STORE: |
934 | name = "FD_MSG_STORE"; | 936 | name = "FD_MSG_STORE"; |
935 | type = MPI_DOMAIN_TYPE; | 937 | type = MPI_DOMAIN_TYPE; |
936 | count = fd_variables_count * DOMAIN_WORDS; | 938 | count = fd_variables_count * DOMAIN_WORDS; |
937 | - _fd_error("[%d] *** dropping %s from %d\n", tid, name, source); | 939 | + fd__error("[%d] *** dropping %s from %d\n", tid, name, source); |
938 | break; | 940 | break; |
939 | case FD_MSG_FEED_ME: | 941 | case FD_MSG_FEED_ME: |
940 | name = "FD_MSG_FEED_ME"; | 942 | name = "FD_MSG_FEED_ME"; |
@@ -955,11 +957,11 @@ static void _fd_flush_events(int procno) | @@ -955,11 +957,11 @@ static void _fd_flush_events(int procno) | ||
955 | name = "FD_MSG_READY"; | 957 | name = "FD_MSG_READY"; |
956 | break; | 958 | break; |
957 | default: | 959 | default: |
958 | - _fd_debug("[%d] unknown tag %d\n", tid, mpi_status.MPI_TAG); | ||
959 | - _fd_fatal("unknown tag in message"); | 960 | + fd__debug("[%d] unknown tag %d\n", tid, mpi_status.MPI_TAG); |
961 | + fd__fatal("unknown tag in message"); | ||
960 | } | 962 | } |
961 | 963 | ||
962 | - _fd_debug("[%d] dropping %s from %d\n", tid, name, source); | 964 | + fd__debug("[%d] dropping %s from %d\n", tid, name, source); |
963 | 965 | ||
964 | // consume message | 966 | // consume message |
965 | { | 967 | { |
@@ -967,7 +969,7 @@ static void _fd_flush_events(int procno) | @@ -967,7 +969,7 @@ static void _fd_flush_events(int procno) | ||
967 | 969 | ||
968 | if (MPI_Recv(buffer, count, type, source, mpi_status.MPI_TAG, | 970 | if (MPI_Recv(buffer, count, type, source, mpi_status.MPI_TAG, |
969 | MPI_COMM_WORLD, MPI_STATUS_IGNORE)) | 971 | MPI_COMM_WORLD, MPI_STATUS_IGNORE)) |
970 | - _fd_error("[%d] MPI_Recv failed (dropping %s)\n", tid, name); | 972 | + fd__error("[%d] MPI_Recv failed (dropping %s)\n", tid, name); |
971 | } | 973 | } |
972 | } | 974 | } |
973 | #else /* MAD_MPI */ | 975 | #else /* MAD_MPI */ |
@@ -986,7 +988,7 @@ static void _fd_flush_events(int procno) | @@ -986,7 +988,7 @@ static void _fd_flush_events(int procno) | ||
986 | { | 988 | { |
987 | _fd_store null = alloca(fd_variables_count * sizeof(*null)); | 989 | _fd_store null = alloca(fd_variables_count * sizeof(*null)); |
988 | 990 | ||
989 | - _fd_debug("[%d] dropping FD_MSG_SOLUTION from %d\n", procno, mpi_status.MPI_SOURCE); | 991 | + fd__trace("[%d] dropping FD_MSG_SOLUTION from %d\n", procno, mpi_status.MPI_SOURCE); |
990 | 992 | ||
991 | _fd_recv_store(mpi_status.MPI_SOURCE, FD_MSG_SOLUTION, null); | 993 | _fd_recv_store(mpi_status.MPI_SOURCE, FD_MSG_SOLUTION, null); |
992 | 994 | ||
@@ -997,12 +999,12 @@ static void _fd_flush_events(int procno) | @@ -997,12 +999,12 @@ static void _fd_flush_events(int procno) | ||
997 | 999 | ||
998 | if (mpi_flag) | 1000 | if (mpi_flag) |
999 | { | 1001 | { |
1000 | - _fd_debug("[%d] dropping FD_MSG_FEED_ME from %d\n", procno, mpi_status.MPI_SOURCE); | 1002 | + fd__trace("[%d] dropping FD_MSG_FEED_ME from %d\n", procno, mpi_status.MPI_SOURCE); |
1001 | 1003 | ||
1002 | // consume message | 1004 | // consume message |
1003 | if (MPI_Recv(NULL, 0, MPI_CHAR, mpi_status.MPI_SOURCE, FD_MSG_FEED_ME, | 1005 | if (MPI_Recv(NULL, 0, MPI_CHAR, mpi_status.MPI_SOURCE, FD_MSG_FEED_ME, |
1004 | MPI_COMM_WORLD, &mpi_status)) | 1006 | MPI_COMM_WORLD, &mpi_status)) |
1005 | - _fd_fatal("MPI_Recv failed"); | 1007 | + fd__fatal("MPI_Recv failed"); |
1006 | 1008 | ||
1007 | got_one++; | 1009 | got_one++; |
1008 | } | 1010 | } |
@@ -1011,12 +1013,12 @@ static void _fd_flush_events(int procno) | @@ -1011,12 +1013,12 @@ static void _fd_flush_events(int procno) | ||
1011 | 1013 | ||
1012 | if (mpi_flag) | 1014 | if (mpi_flag) |
1013 | { | 1015 | { |
1014 | - _fd_debug("[%d] dropping FD_MSG_NO_WORK from %d\n", procno, mpi_status.MPI_SOURCE); | 1016 | + fd__trace("[%d] dropping FD_MSG_NO_WORK from %d\n", procno, mpi_status.MPI_SOURCE); |
1015 | 1017 | ||
1016 | // consume message | 1018 | // consume message |
1017 | if (MPI_Recv(NULL, 0, MPI_CHAR, mpi_status.MPI_SOURCE, FD_MSG_NO_WORK, | 1019 | if (MPI_Recv(NULL, 0, MPI_CHAR, mpi_status.MPI_SOURCE, FD_MSG_NO_WORK, |
1018 | MPI_COMM_WORLD, &mpi_status)) | 1020 | MPI_COMM_WORLD, &mpi_status)) |
1019 | - _fd_fatal("MPI_Recv failed"); | 1021 | + fd__fatal("MPI_Recv failed"); |
1020 | 1022 | ||
1021 | got_one++; | 1023 | got_one++; |
1022 | } | 1024 | } |
@@ -1027,7 +1029,7 @@ static void _fd_flush_events(int procno) | @@ -1027,7 +1029,7 @@ static void _fd_flush_events(int procno) | ||
1027 | { | 1029 | { |
1028 | _fd_store null = alloca(fd_variables_count * sizeof(*null)); | 1030 | _fd_store null = alloca(fd_variables_count * sizeof(*null)); |
1029 | 1031 | ||
1030 | - _fd_debug("[%d] dropping FD_MSG_STORE from %d\n", procno, mpi_status.MPI_SOURCE); | 1032 | + fd__trace("[%d] dropping FD_MSG_STORE from %d\n", procno, mpi_status.MPI_SOURCE); |
1031 | 1033 | ||
1032 | _fd_recv_store(mpi_status.MPI_SOURCE, FD_MSG_STORE, null); | 1034 | _fd_recv_store(mpi_status.MPI_SOURCE, FD_MSG_STORE, null); |
1033 | 1035 | ||
@@ -1038,12 +1040,12 @@ static void _fd_flush_events(int procno) | @@ -1038,12 +1040,12 @@ static void _fd_flush_events(int procno) | ||
1038 | 1040 | ||
1039 | if (mpi_flag) | 1041 | if (mpi_flag) |
1040 | { | 1042 | { |
1041 | - _fd_debug("[%d] dropping FD_MSG_FAIL from %d\n", procno, mpi_status.MPI_SOURCE); | 1043 | + fd__trace("[%d] dropping FD_MSG_FAIL from %d\n", procno, mpi_status.MPI_SOURCE); |
1042 | 1044 | ||
1043 | // consume message | 1045 | // consume message |
1044 | if (MPI_Recv(NULL, 0, MPI_CHAR, mpi_status.MPI_SOURCE, FD_MSG_FAIL, | 1046 | if (MPI_Recv(NULL, 0, MPI_CHAR, mpi_status.MPI_SOURCE, FD_MSG_FAIL, |
1045 | MPI_COMM_WORLD, &mpi_status)) | 1047 | MPI_COMM_WORLD, &mpi_status)) |
1046 | - _fd_fatal("MPI_Recv failed"); | 1048 | + fd__fatal("MPI_Recv failed"); |
1047 | 1049 | ||
1048 | got_one++; | 1050 | got_one++; |
1049 | } | 1051 | } |
@@ -1052,12 +1054,12 @@ static void _fd_flush_events(int procno) | @@ -1052,12 +1054,12 @@ static void _fd_flush_events(int procno) | ||
1052 | 1054 | ||
1053 | if (mpi_flag) | 1055 | if (mpi_flag) |
1054 | { | 1056 | { |
1055 | - _fd_debug("[%d] dropping FD_MSG_DONE from %d\n", procno, mpi_status.MPI_SOURCE); | 1057 | + fd__trace("[%d] dropping FD_MSG_DONE from %d\n", procno, mpi_status.MPI_SOURCE); |
1056 | 1058 | ||
1057 | // consume message | 1059 | // consume message |
1058 | if (MPI_Recv(NULL, 0, MPI_CHAR, mpi_status.MPI_SOURCE, FD_MSG_DONE, | 1060 | if (MPI_Recv(NULL, 0, MPI_CHAR, mpi_status.MPI_SOURCE, FD_MSG_DONE, |
1059 | MPI_COMM_WORLD, &mpi_status)) | 1061 | MPI_COMM_WORLD, &mpi_status)) |
1060 | - _fd_fatal("MPI_Recv failed"); | 1062 | + fd__fatal("MPI_Recv failed"); |
1061 | 1063 | ||
1062 | got_one++; | 1064 | got_one++; |
1063 | } | 1065 | } |
@@ -1066,12 +1068,12 @@ static void _fd_flush_events(int procno) | @@ -1066,12 +1068,12 @@ static void _fd_flush_events(int procno) | ||
1066 | 1068 | ||
1067 | if (mpi_flag) | 1069 | if (mpi_flag) |
1068 | { | 1070 | { |
1069 | - _fd_debug("[%d] dropping FD_MSG_SHARE from %d\n", procno, mpi_status.MPI_SOURCE); | 1071 | + fd__trace("[%d] dropping FD_MSG_SHARE from %d\n", procno, mpi_status.MPI_SOURCE); |
1070 | 1072 | ||
1071 | // consume message | 1073 | // consume message |
1072 | if (MPI_Recv(NULL, 0, MPI_CHAR, mpi_status.MPI_SOURCE, FD_MSG_SHARE, | 1074 | if (MPI_Recv(NULL, 0, MPI_CHAR, mpi_status.MPI_SOURCE, FD_MSG_SHARE, |
1073 | MPI_COMM_WORLD, &mpi_status)) | 1075 | MPI_COMM_WORLD, &mpi_status)) |
1074 | - _fd_fatal("MPI_Recv failed"); | 1076 | + fd__fatal("MPI_Recv failed"); |
1075 | 1077 | ||
1076 | got_one++; | 1078 | got_one++; |
1077 | } | 1079 | } |
@@ -1080,12 +1082,12 @@ static void _fd_flush_events(int procno) | @@ -1080,12 +1082,12 @@ static void _fd_flush_events(int procno) | ||
1080 | 1082 | ||
1081 | if (mpi_flag) | 1083 | if (mpi_flag) |
1082 | { | 1084 | { |
1083 | - _fd_debug("[%d] dropping FD_MSG_NO_SHARE from %d\n", procno, mpi_status.MPI_SOURCE); | 1085 | + fd__trace("[%d] dropping FD_MSG_NO_SHARE from %d\n", procno, mpi_status.MPI_SOURCE); |
1084 | 1086 | ||
1085 | // consume message | 1087 | // consume message |
1086 | if (MPI_Recv(NULL, 0, MPI_CHAR, mpi_status.MPI_SOURCE, FD_MSG_NO_SHARE, | 1088 | if (MPI_Recv(NULL, 0, MPI_CHAR, mpi_status.MPI_SOURCE, FD_MSG_NO_SHARE, |
1087 | MPI_COMM_WORLD, &mpi_status)) | 1089 | MPI_COMM_WORLD, &mpi_status)) |
1088 | - _fd_fatal("MPI_Recv failed"); | 1090 | + fd__fatal("MPI_Recv failed"); |
1089 | 1091 | ||
1090 | got_one++; | 1092 | got_one++; |
1091 | } | 1093 | } |
@@ -1102,45 +1104,45 @@ void _fd_cleanup_mpi_state(int process) | @@ -1102,45 +1104,45 @@ void _fd_cleanup_mpi_state(int process) | ||
1102 | // a still running process has a chance to see it | 1104 | // a still running process has a chance to see it |
1103 | // XXX: New Madeleine can't cope with messages en route | 1105 | // XXX: New Madeleine can't cope with messages en route |
1104 | #if 0 //#ifndef MAD_MPI | 1106 | #if 0 //#ifndef MAD_MPI |
1105 | - _fd_debug("[%d] setting up barrier 1\n", process); | 1107 | + fd__trace("[%d] setting up barrier 1\n", process); |
1106 | if (MPI_Barrier(MPI_COMM_WORLD)) | 1108 | if (MPI_Barrier(MPI_COMM_WORLD)) |
1107 | - _fd_error("[%d] MPI_Barrier failed\n", process); | 1109 | + fd__error("[%d] MPI_Barrier failed\n", process); |
1108 | else | 1110 | else |
1109 | - _fd_debug("[%d] leaving barrier 1\n", process); | 1111 | + fd__trace("[%d] leaving barrier 1\n", process); |
1110 | #endif | 1112 | #endif |
1111 | 1113 | ||
1112 | _fd_flush_events(process); | 1114 | _fd_flush_events(process); |
1113 | 1115 | ||
1114 | #if 0 | 1116 | #if 0 |
1115 | - _fd_debug("[%d] setting up barrier 2\n", process); | 1117 | + fd__trace("[%d] setting up barrier 2\n", process); |
1116 | if (MPI_Barrier(MPI_COMM_WORLD)) | 1118 | if (MPI_Barrier(MPI_COMM_WORLD)) |
1117 | - _fd_error("[%d] MPI_Barrier failed\n", process); | 1119 | + fd__error("[%d] MPI_Barrier failed\n", process); |
1118 | else | 1120 | else |
1119 | - _fd_debug("[%d] leaving barrier 2\n", process); | 1121 | + fd__trace("[%d] leaving barrier 2\n", process); |
1120 | #endif | 1122 | #endif |
1121 | } | 1123 | } |
1122 | 1124 | ||
1123 | _fd_statistics_msgs(); | 1125 | _fd_statistics_msgs(); |
1124 | 1126 | ||
1125 | - _fd_debug("[%d] calling MPI_Finalize\n", process); | 1127 | + fd__trace("[%d] calling MPI_Finalize\n", process); |
1126 | if (MPI_Finalize()) | 1128 | if (MPI_Finalize()) |
1127 | - _fd_error("[%d] MPI_Finalize failed\n", process); | 1129 | + fd__error("[%d] MPI_Finalize failed\n", process); |
1128 | else | 1130 | else |
1129 | - _fd_debug("[%d] returned from MPI_Finalize\n", process); | 1131 | + fd__trace("[%d] returned from MPI_Finalize\n", process); |
1130 | } | 1132 | } |
1131 | 1133 | ||
1132 | static void _fd_exit_process(int process) | 1134 | static void _fd_exit_process(int process) |
1133 | { | 1135 | { |
1134 | _fd_cleanup_mpi_state(process); | 1136 | _fd_cleanup_mpi_state(process); |
1135 | 1137 | ||
1136 | - _fd_debug("[%d] exiting\n", process); | 1138 | + fd__trace("[%d] exiting\n", process); |
1137 | 1139 | ||
1138 | exit(0); | 1140 | exit(0); |
1139 | } | 1141 | } |
1140 | 1142 | ||
1141 | void _fd_search_space_sizes(_fd_store stores[], int n) | 1143 | void _fd_search_space_sizes(_fd_store stores[], int n) |
1142 | { | 1144 | { |
1143 | -#ifndef FAST | 1145 | +#ifdef TRACE |
1144 | double s; | 1146 | double s; |
1145 | int i, v; | 1147 | int i, v; |
1146 | 1148 | ||
@@ -1155,14 +1157,14 @@ void _fd_search_space_sizes(_fd_store stores[], int n) | @@ -1155,14 +1157,14 @@ void _fd_search_space_sizes(_fd_store stores[], int n) | ||
1155 | for (v = 0; v < fd__label_vars_count; ++v) | 1157 | for (v = 0; v < fd__label_vars_count; ++v) |
1156 | s *= _fd_val_size(SVALUE(stores[i][fd__label_vars[v]->index])); | 1158 | s *= _fd_val_size(SVALUE(stores[i][fd__label_vars[v]->index])); |
1157 | 1159 | ||
1158 | - _fd_debug("[%d] search space %d size is %g\n", tid, i, s); | 1160 | + fd__trace("[%d] search space %d size is %g\n", tid, i, s); |
1159 | } | 1161 | } |
1160 | -#endif /* FAST */ | 1162 | +#endif /* TRACE */ |
1161 | } | 1163 | } |
1162 | 1164 | ||
1163 | static void count_singletons(_fd_store store) | 1165 | static void count_singletons(_fd_store store) |
1164 | { | 1166 | { |
1165 | -#ifndef FAST | 1167 | +#ifdef TRACE |
1166 | int i, n; | 1168 | int i, n; |
1167 | 1169 | ||
1168 | n = 0; | 1170 | n = 0; |
@@ -1171,7 +1173,7 @@ static void count_singletons(_fd_store store) | @@ -1171,7 +1173,7 @@ static void count_singletons(_fd_store store) | ||
1171 | if (_fd_val_single(SVALUE(store[i]), NULL)) | 1173 | if (_fd_val_single(SVALUE(store[i]), NULL)) |
1172 | ++n; | 1174 | ++n; |
1173 | 1175 | ||
1174 | - _fd_debug("[%d] store has %d/%d/%d singletons\n", tid, n, | 1176 | + fd__trace("[%d] store has %d/%d/%d singletons\n", tid, n, |
1175 | fd__label_vars_count, fd_variables_count); | 1177 | fd__label_vars_count, fd_variables_count); |
1176 | #endif | 1178 | #endif |
1177 | } | 1179 | } |
@@ -1185,7 +1187,7 @@ static int _fd_restart_agents(int tid, int nagents) | @@ -1185,7 +1187,7 @@ static int _fd_restart_agents(int tid, int nagents) | ||
1185 | parts = fd__split_problem(nagents, _fd_agents_stores, fd__split_team_problem_f); | 1187 | parts = fd__split_problem(nagents, _fd_agents_stores, fd__split_team_problem_f); |
1186 | 1188 | ||
1187 | if (parts < nagents) | 1189 | if (parts < nagents) |
1188 | - _fd_debug("[%d] WARNING: store only good for %d agents (out of %d)\n", | 1190 | + fd__debug("[%d] WARNING: store only good for %d agents (out of %d)\n", |
1189 | tid, parts, nagents); | 1191 | tid, parts, nagents); |
1190 | 1192 | ||
1191 | agents_to_run = parts; | 1193 | agents_to_run = parts; |
@@ -1200,7 +1202,7 @@ static int _fd_restart_agents(int tid, int nagents) | @@ -1200,7 +1202,7 @@ static int _fd_restart_agents(int tid, int nagents) | ||
1200 | if (pthread_mutex_unlock(&continue_mutex)) | 1202 | if (pthread_mutex_unlock(&continue_mutex)) |
1201 | perror("pthread_mutex_unlock"); | 1203 | perror("pthread_mutex_unlock"); |
1202 | 1204 | ||
1203 | - _fd_debug("[%d] told waiting agents to proceed\n", tid); | 1205 | + fd__trace("[%d] told waiting agents to proceed\n", tid); |
1204 | 1206 | ||
1205 | return parts; | 1207 | return parts; |
1206 | } | 1208 | } |
@@ -1222,7 +1224,7 @@ static int _fd_poll_next(int last, int skip) | @@ -1222,7 +1224,7 @@ static int _fd_poll_next(int last, int skip) | ||
1222 | if (poll >= 0) | 1224 | if (poll >= 0) |
1223 | { | 1225 | { |
1224 | // send a forceful request for work | 1226 | // send a forceful request for work |
1225 | - _fd_debug("[%d] polling %d\n", tid, poll); | 1227 | + fd__trace("[%d] polling %d\n", tid, poll); |
1226 | _fd_send(poll, FD_MSG_SHARE); | 1228 | _fd_send(poll, FD_MSG_SHARE); |
1227 | } | 1229 | } |
1228 | 1230 | ||
@@ -1261,7 +1263,7 @@ static int _fd_poll_rr(bool starting, int np_or_last, int skip) | @@ -1261,7 +1263,7 @@ static int _fd_poll_rr(bool starting, int np_or_last, int skip) | ||
1261 | return -1; | 1263 | return -1; |
1262 | 1264 | ||
1263 | // send a forceful request for work | 1265 | // send a forceful request for work |
1264 | - _fd_debug("[%d] polling %d\n", tid, poll); | 1266 | + fd__trace("[%d] polling %d\n", tid, poll); |
1265 | _fd_send(poll, FD_MSG_SHARE); | 1267 | _fd_send(poll, FD_MSG_SHARE); |
1266 | 1268 | ||
1267 | last_polled = poll; | 1269 | last_polled = poll; |
@@ -1286,7 +1288,7 @@ static bool _fd_share_work(int peer, MPI_Request *request, fd_list saved_stores, | @@ -1286,7 +1288,7 @@ static bool _fd_share_work(int peer, MPI_Request *request, fd_list saved_stores, | ||
1286 | if (!mpi_flag) | 1288 | if (!mpi_flag) |
1287 | { | 1289 | { |
1288 | // the previous send has not completed | 1290 | // the previous send has not completed |
1289 | - _fd_debug("[%d] there's a store in transit to %d\n", tid, peer); | 1291 | + fd__trace("[%d] there's a store in transit to %d\n", tid, peer); |
1290 | 1292 | ||
1291 | /* despite MPI_Test() having failed, the store may already have | 1293 | /* despite MPI_Test() having failed, the store may already have |
1292 | been received and processed; since process 0 must receive or | 1294 | been received and processed; since process 0 must receive or |
@@ -1306,7 +1308,7 @@ static bool _fd_share_work(int peer, MPI_Request *request, fd_list saved_stores, | @@ -1306,7 +1308,7 @@ static bool _fd_share_work(int peer, MPI_Request *request, fd_list saved_stores, | ||
1306 | memcpy(_fd_processes_stores[peer], saved, | 1308 | memcpy(_fd_processes_stores[peer], saved, |
1307 | fd_variables_count * sizeof(*saved)); | 1309 | fd_variables_count * sizeof(*saved)); |
1308 | 1310 | ||
1309 | - _fd_debug("[%d] sending store (saved) to %d\n", tid, peer); | 1311 | + fd__trace("[%d] sending store (saved) to %d\n", tid, peer); |
1310 | _fd_send_store(peer, FD_MSG_STORE, _fd_processes_stores[peer], request, | 1312 | _fd_send_store(peer, FD_MSG_STORE, _fd_processes_stores[peer], request, |
1311 | true); | 1313 | true); |
1312 | 1314 | ||
@@ -1315,13 +1317,9 @@ static bool _fd_share_work(int peer, MPI_Request *request, fd_list saved_stores, | @@ -1315,13 +1317,9 @@ static bool _fd_share_work(int peer, MPI_Request *request, fd_list saved_stores, | ||
1315 | return true; | 1317 | return true; |
1316 | } | 1318 | } |
1317 | 1319 | ||
1318 | -#ifndef INDEX_IN_POOL | ||
1319 | - if (_fd_steal_store(_fd_processes_stores[peer], -1, 0)) | ||
1320 | -#else | ||
1321 | if (_fd_steal_store(_fd_processes_stores[peer], NULL, -1, 0)) | 1320 | if (_fd_steal_store(_fd_processes_stores[peer], NULL, -1, 0)) |
1322 | -#endif | ||
1323 | { | 1321 | { |
1324 | - _fd_debug("[%d] sending store to %d\n", tid, peer); | 1322 | + fd__trace("[%d] sending store to %d\n", tid, peer); |
1325 | _fd_send_store(peer, FD_MSG_STORE, _fd_processes_stores[peer], request, | 1323 | _fd_send_store(peer, FD_MSG_STORE, _fd_processes_stores[peer], request, |
1326 | true); | 1324 | true); |
1327 | 1325 | ||
@@ -1331,12 +1329,12 @@ static bool _fd_share_work(int peer, MPI_Request *request, fd_list saved_stores, | @@ -1331,12 +1329,12 @@ static bool _fd_share_work(int peer, MPI_Request *request, fd_list saved_stores, | ||
1331 | // tell the requester that there is no work available | 1329 | // tell the requester that there is no work available |
1332 | if (polled) | 1330 | if (polled) |
1333 | { | 1331 | { |
1334 | - _fd_debug("[%d] no work to share with %d\n", tid, peer); | 1332 | + fd__trace("[%d] no work to share with %d\n", tid, peer); |
1335 | _fd_send(peer, FD_MSG_NO_SHARE); | 1333 | _fd_send(peer, FD_MSG_NO_SHARE); |
1336 | } | 1334 | } |
1337 | else | 1335 | else |
1338 | { | 1336 | { |
1339 | - _fd_debug("[%d] can't find work requested by %d\n", tid, peer); | 1337 | + fd__trace("[%d] can't find work requested by %d\n", tid, peer); |
1340 | _fd_send(peer, FD_MSG_NO_WORK); | 1338 | _fd_send(peer, FD_MSG_NO_WORK); |
1341 | } | 1339 | } |
1342 | 1340 | ||
@@ -1355,13 +1353,13 @@ static bool _fd_share_work(int peer, MPI_Request *request, fd_list saved_stores, | @@ -1355,13 +1353,13 @@ static bool _fd_share_work(int peer, MPI_Request *request, fd_list saved_stores, | ||
1355 | { \ | 1353 | { \ |
1356 | /* record polling process as idle */ \ | 1354 | /* record polling process as idle */ \ |
1357 | gettimeofday(&to, NULL); timersub(&to, &ti, &to); \ | 1355 | gettimeofday(&to, NULL); timersub(&to, &ti, &to); \ |
1358 | - _fd_debug("[%d] %d idled after %d.%06ds\n", tid, _p, \ | 1356 | + fd__trace("[%d] %d idled after %d.%06ds\n", tid, _p, \ |
1359 | to.tv_sec, to.tv_usec); \ | 1357 | to.tv_sec, to.tv_usec); \ |
1360 | \ | 1358 | \ |
1361 | process_idle[_p] = true; \ | 1359 | process_idle[_p] = true; \ |
1362 | if (++idle_processes == live_procs - 1) \ | 1360 | if (++idle_processes == live_procs - 1) \ |
1363 | { \ | 1361 | { \ |
1364 | - _fd_debug("[%d] sending 2nd quit\n", tid); \ | 1362 | + fd__trace("[%d] sending 2nd quit\n", tid); \ |
1365 | \ | 1363 | \ |
1366 | _fd_broadcast(FD_MSG_QUIT, processes, tid); \ | 1364 | _fd_broadcast(FD_MSG_QUIT, processes, tid); \ |
1367 | } \ | 1365 | } \ |
@@ -1401,21 +1399,21 @@ int _fd_dsolve() | @@ -1401,21 +1399,21 @@ int _fd_dsolve() | ||
1401 | gettimeofday(&ti, NULL); | 1399 | gettimeofday(&ti, NULL); |
1402 | 1400 | ||
1403 | if (MPI_Comm_rank(MPI_COMM_WORLD, &tid)) | 1401 | if (MPI_Comm_rank(MPI_COMM_WORLD, &tid)) |
1404 | - _fd_fatal("MPI_Comm_rank failed\n"); | 1402 | + fd__fatal("MPI_Comm_rank failed\n"); |
1405 | 1403 | ||
1406 | - _fd_debug("I'm MPI rank %d\n", tid); | 1404 | + fd__trace("I'm MPI rank %d\n", tid); |
1407 | 1405 | ||
1408 | { | 1406 | { |
1409 | char host[512]; | 1407 | char host[512]; |
1410 | 1408 | ||
1411 | - gethostname(host, sizeof(host)); | ||
1412 | - _fd_debug("[%d] process %d at %s\n", tid, getpid(), host); | 1409 | + fd__trace("[%d] process %d at %s\n", tid, getpid(), |
1410 | + (gethostname(host, sizeof(host)), host)); | ||
1413 | } | 1411 | } |
1414 | 1412 | ||
1415 | if (MPI_Comm_size(MPI_COMM_WORLD, &processes)) | 1413 | if (MPI_Comm_size(MPI_COMM_WORLD, &processes)) |
1416 | - _fd_fatal("MPI_Comm_size failed\n"); | 1414 | + fd__fatal("MPI_Comm_size failed\n"); |
1417 | 1415 | ||
1418 | - _fd_debug("[%d] There are %d of us\n", tid, processes); | 1416 | + fd__trace("[%d] There are %d of us\n", tid, processes); |
1419 | 1417 | ||
1420 | pending_requests = fd_list_new(); | 1418 | pending_requests = fd_list_new(); |
1421 | 1419 | ||
@@ -1474,7 +1472,7 @@ int _fd_dsolve() | @@ -1474,7 +1472,7 @@ int _fd_dsolve() | ||
1474 | parts = fd__split_problem(processes, _fd_processes_stores, fd__split_problem_f); | 1472 | parts = fd__split_problem(processes, _fd_processes_stores, fd__split_problem_f); |
1475 | _fd_search_space_sizes(_fd_processes_stores, parts); | 1473 | _fd_search_space_sizes(_fd_processes_stores, parts); |
1476 | if (parts < processes) | 1474 | if (parts < processes) |
1477 | - _fd_error("WARNING: work enough for %d processes only\n", parts); | 1475 | + fd__error("WARNING: work enough for %d processes only\n", parts); |
1478 | 1476 | ||
1479 | // now send the resulting parts to the other processes | 1477 | // now send the resulting parts to the other processes |
1480 | // XXX: could each have done what this did and now pick its share? | 1478 | // XXX: could each have done what this did and now pick its share? |
@@ -1494,17 +1492,17 @@ int _fd_dsolve() | @@ -1494,17 +1492,17 @@ int _fd_dsolve() | ||
1494 | { | 1492 | { |
1495 | // code for the remaining processes | 1493 | // code for the remaining processes |
1496 | 1494 | ||
1497 | - _fd_debug("[%d] waiting for initial store\n", tid); | 1495 | + fd__trace("[%d] waiting for initial store\n", tid); |
1498 | 1496 | ||
1499 | // retrieve the domains assigned to the process | 1497 | // retrieve the domains assigned to the process |
1500 | if (!_fd_recv_store(0, FD_MSG_STORE, store)) | 1498 | if (!_fd_recv_store(0, FD_MSG_STORE, store)) |
1501 | { | 1499 | { |
1502 | - _fd_debug("[%d] empty initial store\n", tid); | 1500 | + fd__debug("[%d] empty initial store\n", tid); |
1503 | 1501 | ||
1504 | _fd_exit_process(tid); | 1502 | _fd_exit_process(tid); |
1505 | } | 1503 | } |
1506 | 1504 | ||
1507 | - _fd_debug("[%d] received initial store\n", tid); | 1505 | + fd__trace("[%d] received initial store\n", tid); |
1508 | } | 1506 | } |
1509 | 1507 | ||
1510 | #if FILTER_DOMAINS > 1 | 1508 | #if FILTER_DOMAINS > 1 |
@@ -1530,7 +1528,7 @@ int _fd_dsolve() | @@ -1530,7 +1528,7 @@ int _fd_dsolve() | ||
1530 | 1528 | ||
1531 | if (parts < nagents) | 1529 | if (parts < nagents) |
1532 | { | 1530 | { |
1533 | - _fd_debug("[%d] reducing to %d agents!\n", tid, parts); | 1531 | + fd__trace("[%d] reducing to %d agents!\n", tid, parts); |
1534 | 1532 | ||
1535 | nagents = parts; | 1533 | nagents = parts; |
1536 | } | 1534 | } |
@@ -1542,7 +1540,7 @@ int _fd_dsolve() | @@ -1542,7 +1540,7 @@ int _fd_dsolve() | ||
1542 | 1540 | ||
1543 | gettimeofday(&to, NULL); | 1541 | gettimeofday(&to, NULL); |
1544 | timersub(&to, &ti, &to); | 1542 | timersub(&to, &ti, &to); |
1545 | - _fd_debug("[%d] setup took %d.%06ds\n", tid, to.tv_sec, to.tv_usec); | 1543 | + fd__trace("[%d] setup took %d.%06ds\n", tid, to.tv_sec, to.tv_usec); |
1546 | 1544 | ||
1547 | #if 0 | 1545 | #if 0 |
1548 | for (i = 0; i < nagents; ++i) | 1546 | for (i = 0; i < nagents; ++i) |
@@ -1593,7 +1591,7 @@ int _fd_dsolve() | @@ -1593,7 +1591,7 @@ int _fd_dsolve() | ||
1593 | } | 1591 | } |
1594 | } | 1592 | } |
1595 | 1593 | ||
1596 | - _fd_debug("[%d] main thread waiting\n", tid); | 1594 | + fd__trace("[%d] main thread waiting\n", tid); |
1597 | 1595 | ||
1598 | running = started; | 1596 | running = started; |
1599 | live_procs = processes; | 1597 | live_procs = processes; |
@@ -1607,7 +1605,7 @@ int _fd_dsolve() | @@ -1607,7 +1605,7 @@ int _fd_dsolve() | ||
1607 | { | 1605 | { |
1608 | #if STEAL_WORK >= 2 | 1606 | #if STEAL_WORK >= 2 |
1609 | case EV_INT_TIMEOUT: | 1607 | case EV_INT_TIMEOUT: |
1610 | - _fd_debug("[%d] timed out waiting for event\n", tid); | 1608 | + fd__trace("[%d] timed out waiting for event\n", tid); |
1611 | 1609 | ||
1612 | switch (waiting_on) | 1610 | switch (waiting_on) |
1613 | { | 1611 | { |
@@ -1644,7 +1642,7 @@ int _fd_dsolve() | @@ -1644,7 +1642,7 @@ int _fd_dsolve() | ||
1644 | else | 1642 | else |
1645 | { | 1643 | { |
1646 | // resend request for work | 1644 | // resend request for work |
1647 | - _fd_debug("[%d] re-asking for work\n", tid); | 1645 | + fd__trace("[%d] re-asking for work\n", tid); |
1648 | _fd_broadcast(FD_MSG_FEED_ME, processes, tid); | 1646 | _fd_broadcast(FD_MSG_FEED_ME, processes, tid); |
1649 | 1647 | ||
1650 | timeout = FEED2_TIMEOUT; | 1648 | timeout = FEED2_TIMEOUT; |
@@ -1687,8 +1685,8 @@ int _fd_dsolve() | @@ -1687,8 +1685,8 @@ int _fd_dsolve() | ||
1687 | 1685 | ||
1688 | break; | 1686 | break; |
1689 | default: | 1687 | default: |
1690 | - _fd_debug("[%d] unknown timeout: %d\n", tid, waiting_on); | ||
1691 | - _fd_fatal("unknown timeout reason"); | 1688 | + fd__debug("[%d] unknown timeout: %d\n", tid, waiting_on); |
1689 | + fd__fatal("unknown timeout reason"); | ||
1692 | } | 1690 | } |
1693 | 1691 | ||
1694 | break; | 1692 | break; |
@@ -1697,7 +1695,7 @@ int _fd_dsolve() | @@ -1697,7 +1695,7 @@ int _fd_dsolve() | ||
1697 | /* first solution internal events (from the workers) */ | 1695 | /* first solution internal events (from the workers) */ |
1698 | 1696 | ||
1699 | case EV_INT_SUCCESS: | 1697 | case EV_INT_SUCCESS: |
1700 | - _fd_debug("[%d] using agent %d's results\n", tid, peer); | 1698 | + fd__trace("[%d] using agent %d's results\n", tid, peer); |
1701 | 1699 | ||
1702 | assert(!_fd_counting_solutions); | 1700 | assert(!_fd_counting_solutions); |
1703 | 1701 | ||
@@ -1706,7 +1704,7 @@ int _fd_dsolve() | @@ -1706,7 +1704,7 @@ int _fd_dsolve() | ||
1706 | // check and update bound | 1704 | // check and update bound |
1707 | if (!_fd_bound_check_set(_fd_agents_stores[peer])) | 1705 | if (!_fd_bound_check_set(_fd_agents_stores[peer])) |
1708 | { | 1706 | { |
1709 | - _fd_debug("[%d] invalid solution, releasing %d\n", tid, peer); | 1707 | + fd__trace("[%d] invalid solution, releasing %d\n", tid, peer); |
1710 | if (sem_post(&resume_semaphore)) | 1708 | if (sem_post(&resume_semaphore)) |
1711 | perror("sem_post (resume)"); | 1709 | perror("sem_post (resume)"); |
1712 | 1710 | ||
@@ -1720,11 +1718,11 @@ int _fd_dsolve() | @@ -1720,11 +1718,11 @@ int _fd_dsolve() | ||
1720 | fd_variables_count * sizeof(*solution)); | 1718 | fd_variables_count * sizeof(*solution)); |
1721 | 1719 | ||
1722 | // release agent | 1720 | // release agent |
1723 | - _fd_debug("[%d] releasing agent %d\n", tid, peer); | 1721 | + fd__trace("[%d] releasing agent %d\n", tid, peer); |
1724 | if (sem_post(&resume_semaphore)) | 1722 | if (sem_post(&resume_semaphore)) |
1725 | perror("sem_post (resume)"); | 1723 | perror("sem_post (resume)"); |
1726 | 1724 | ||
1727 | - _fd_debug("[%d] bound updated to %d\n", tid, _fd_bound_value()); | 1725 | + fd__trace("[%d] bound updated to %d\n", tid, _fd_bound_value()); |
1728 | 1726 | ||
1729 | // broadcast new bound | 1727 | // broadcast new bound |
1730 | bound = _fd_bound_value(); | 1728 | bound = _fd_bound_value(); |
@@ -1746,7 +1744,7 @@ int _fd_dsolve() | @@ -1746,7 +1744,7 @@ int _fd_dsolve() | ||
1746 | 1744 | ||
1747 | break; | 1745 | break; |
1748 | case EV_INT_FAIL: | 1746 | case EV_INT_FAIL: |
1749 | - _fd_debug("[%d] agent %d found no solution\n", tid, peer); | 1747 | + fd__trace("[%d] agent %d found no solution\n", tid, peer); |
1750 | 1748 | ||
1751 | assert(!_fd_counting_solutions); | 1749 | assert(!_fd_counting_solutions); |
1752 | 1750 | ||
@@ -1770,7 +1768,7 @@ int _fd_dsolve() | @@ -1770,7 +1768,7 @@ int _fd_dsolve() | ||
1770 | { | 1768 | { |
1771 | if (!supplier) | 1769 | if (!supplier) |
1772 | { | 1770 | { |
1773 | - _fd_debug("[%d] asking for work\n", tid); | 1771 | + fd__trace("[%d] asking for work\n", tid); |
1774 | _fd_broadcast(FD_MSG_FEED_ME, processes, tid); | 1772 | _fd_broadcast(FD_MSG_FEED_ME, processes, tid); |
1775 | 1773 | ||
1776 | waiting_on = FD_MSG_FEED_ME; | 1774 | waiting_on = FD_MSG_FEED_ME; |
@@ -1802,7 +1800,7 @@ int _fd_dsolve() | @@ -1802,7 +1800,7 @@ int _fd_dsolve() | ||
1802 | // see if there's some store saved up | 1800 | // see if there's some store saved up |
1803 | if (saved = fd_list_remove(saved_stores)) | 1801 | if (saved = fd_list_remove(saved_stores)) |
1804 | { | 1802 | { |
1805 | - _fd_debug("[%d] using saved store\n", tid); | 1803 | + fd__trace("[%d] using saved store\n", tid); |
1806 | 1804 | ||
1807 | memcpy(store, saved, | 1805 | memcpy(store, saved, |
1808 | fd_variables_count * sizeof(*saved)); | 1806 | fd_variables_count * sizeof(*saved)); |
@@ -1840,7 +1838,7 @@ int _fd_dsolve() | @@ -1840,7 +1838,7 @@ int _fd_dsolve() | ||
1840 | if (!supplier) | 1838 | if (!supplier) |
1841 | { | 1839 | { |
1842 | // ask the other processes for more work | 1840 | // ask the other processes for more work |
1843 | - _fd_debug("[%d] asking for work\n", tid); | 1841 | + fd__trace("[%d] asking for work\n", tid); |
1844 | _fd_broadcast(FD_MSG_FEED_ME, processes, tid); | 1842 | _fd_broadcast(FD_MSG_FEED_ME, processes, tid); |
1845 | 1843 | ||
1846 | waiting_on = FD_MSG_FEED_ME; | 1844 | waiting_on = FD_MSG_FEED_ME; |
@@ -1873,18 +1871,18 @@ int _fd_dsolve() | @@ -1873,18 +1871,18 @@ int _fd_dsolve() | ||
1873 | /* first solution external events (from the other processes) */ | 1871 | /* first solution external events (from the other processes) */ |
1874 | 1872 | ||
1875 | case EV_EXT_SUCCESS: | 1873 | case EV_EXT_SUCCESS: |
1876 | - _fd_debug("[%d] received a solution from %d\n", tid, peer); | 1874 | + fd__trace("[%d] received a solution from %d\n", tid, peer); |
1877 | 1875 | ||
1878 | assert(!_fd_counting_solutions); | 1876 | assert(!_fd_counting_solutions); |
1879 | 1877 | ||
1880 | _fd_recv_store(peer, FD_MSG_SOLUTION, store); | 1878 | _fd_recv_store(peer, FD_MSG_SOLUTION, store); |
1881 | 1879 | ||
1882 | - _fd_debug("[%d] using process %d's results\n", tid, peer); | 1880 | + fd__trace("[%d] using process %d's results\n", tid, peer); |
1883 | 1881 | ||
1884 | gettimeofday(&to, NULL); | 1882 | gettimeofday(&to, NULL); |
1885 | timersub(&to, &ti, &to); | 1883 | timersub(&to, &ti, &to); |
1886 | -#if defined(STATS_PROCS) || !defined(FAST) | ||
1887 | - fd__info("[%d] process %d took %d.%06ds\n", tid, peer, to.tv_sec, to.tv_usec); | 1884 | +#if defined(STATS_PROCS) || defined(TRACE) |
1885 | + fd__debug("[%d] process %d took %d.%06ds\n", tid, peer, to.tv_sec, to.tv_usec); | ||
1888 | #endif | 1886 | #endif |
1889 | 1887 | ||
1890 | if (_fd_optimising) | 1888 | if (_fd_optimising) |
@@ -1892,7 +1890,7 @@ int _fd_dsolve() | @@ -1892,7 +1890,7 @@ int _fd_dsolve() | ||
1892 | // see if it is the better solution | 1890 | // see if it is the better solution |
1893 | if (!have_solution || _fd_better_solution(store, solution)) | 1891 | if (!have_solution || _fd_better_solution(store, solution)) |
1894 | { | 1892 | { |
1895 | - _fd_debug("[%d] process %d solution is better\n", tid, peer); | 1893 | + fd__trace("[%d] process %d solution is better\n", tid, peer); |
1896 | 1894 | ||
1897 | memcpy(solution, store, | 1895 | memcpy(solution, store, |
1898 | fd_variables_count * sizeof(*store)); | 1896 | fd_variables_count * sizeof(*store)); |
@@ -1916,14 +1914,14 @@ int _fd_dsolve() | @@ -1916,14 +1914,14 @@ int _fd_dsolve() | ||
1916 | 1914 | ||
1917 | break; | 1915 | break; |
1918 | case EV_EXT_FAIL: | 1916 | case EV_EXT_FAIL: |
1919 | - _fd_debug("[%d] process %d found no solution\n", tid, peer); | 1917 | + fd__trace("[%d] process %d found no solution\n", tid, peer); |
1920 | 1918 | ||
1921 | assert(!_fd_counting_solutions); | 1919 | assert(!_fd_counting_solutions); |
1922 | 1920 | ||
1923 | gettimeofday(&to, NULL); | 1921 | gettimeofday(&to, NULL); |
1924 | timersub(&to, &ti, &to); | 1922 | timersub(&to, &ti, &to); |
1925 | -#if defined(STATS_PROCS) || !defined(FAST) | ||
1926 | - fd__info("[%d] process %d took %d.%06ds\n", tid, peer, to.tv_sec, to.tv_usec); | 1923 | +#if defined(STATS_PROCS) || defined(TRACE) |
1924 | + fd__debug("[%d] process %d took %d.%06ds\n", tid, peer, to.tv_sec, to.tv_usec); | ||
1927 | #endif | 1925 | #endif |
1928 | 1926 | ||
1929 | live_procs--; | 1927 | live_procs--; |
@@ -1943,7 +1941,7 @@ int _fd_dsolve() | @@ -1943,7 +1941,7 @@ int _fd_dsolve() | ||
1943 | 1941 | ||
1944 | break; | 1942 | break; |
1945 | case EV_EXT_DONE: | 1943 | case EV_EXT_DONE: |
1946 | - _fd_debug("[%d] process %d told me to stop\n", tid, peer); | 1944 | + fd__trace("[%d] process %d told me to stop\n", tid, peer); |
1947 | 1945 | ||
1948 | assert(!_fd_counting_solutions); | 1946 | assert(!_fd_counting_solutions); |
1949 | 1947 | ||
@@ -1954,7 +1952,7 @@ int _fd_dsolve() | @@ -1954,7 +1952,7 @@ int _fd_dsolve() | ||
1954 | /* optimisation external events (from the other processes) */ | 1952 | /* optimisation external events (from the other processes) */ |
1955 | 1953 | ||
1956 | case EV_EXT_BOUND: | 1954 | case EV_EXT_BOUND: |
1957 | - _fd_debug("[%d] received new bound from %d\n", tid, peer); | 1955 | + fd__trace("[%d] received new bound from %d\n", tid, peer); |
1958 | 1956 | ||
1959 | assert(!_fd_counting_solutions && _fd_optimising); | 1957 | assert(!_fd_counting_solutions && _fd_optimising); |
1960 | 1958 | ||
@@ -1963,24 +1961,24 @@ int _fd_dsolve() | @@ -1963,24 +1961,24 @@ int _fd_dsolve() | ||
1963 | 1961 | ||
1964 | if (MPI_Recv(&bound, 1, MPI_INT, peer, FD_MSG_BOUND, | 1962 | if (MPI_Recv(&bound, 1, MPI_INT, peer, FD_MSG_BOUND, |
1965 | MPI_COMM_WORLD, &mpi_status)) | 1963 | MPI_COMM_WORLD, &mpi_status)) |
1966 | - _fd_fatal("MPI_Recv failed"); | 1964 | + fd__fatal("MPI_Recv failed"); |
1967 | 1965 | ||
1968 | // try to set new bound | 1966 | // try to set new bound |
1969 | if (_fd_set_bound(bound)) | 1967 | if (_fd_set_bound(bound)) |
1970 | { | 1968 | { |
1971 | - _fd_debug("[%d] new bound is %d\n", tid, bound); | 1969 | + fd__trace("[%d] new bound is %d\n", tid, bound); |
1972 | 1970 | ||
1973 | // bound has been reset, invalidate previous solution | 1971 | // bound has been reset, invalidate previous solution |
1974 | if (have_solution && !_fd_bound_check(solution)) | 1972 | if (have_solution && !_fd_bound_check(solution)) |
1975 | { | 1973 | { |
1976 | - _fd_debug("[%d] invalidating current solution\n", tid); | 1974 | + fd__trace("[%d] invalidating current solution\n", tid); |
1977 | 1975 | ||
1978 | status = FD_NOSOLUTION; | 1976 | status = FD_NOSOLUTION; |
1979 | have_solution = false; | 1977 | have_solution = false; |
1980 | } | 1978 | } |
1981 | } | 1979 | } |
1982 | else | 1980 | else |
1983 | - _fd_debug("[%d] invalid bound %d\n", tid, bound); | 1981 | + fd__trace("[%d] invalid bound %d\n", tid, bound); |
1984 | } | 1982 | } |
1985 | 1983 | ||
1986 | break; | 1984 | break; |
@@ -1988,7 +1986,7 @@ int _fd_dsolve() | @@ -1988,7 +1986,7 @@ int _fd_dsolve() | ||
1988 | /* counting solutions internal events (from the workers) */ | 1986 | /* counting solutions internal events (from the workers) */ |
1989 | 1987 | ||
1990 | case EV_INT_COUNT: | 1988 | case EV_INT_COUNT: |
1991 | - _fd_debug("[%d] agent %d is done\n", tid, peer); | 1989 | + fd__trace("[%d] agent %d is done\n", tid, peer); |
1992 | 1990 | ||
1993 | assert(_fd_counting_solutions); | 1991 | assert(_fd_counting_solutions); |
1994 | 1992 | ||
@@ -2012,7 +2010,7 @@ int _fd_dsolve() | @@ -2012,7 +2010,7 @@ int _fd_dsolve() | ||
2012 | { | 2010 | { |
2013 | if (!supplier) | 2011 | if (!supplier) |
2014 | { | 2012 | { |
2015 | - _fd_debug("[%d] asking for work\n", tid); | 2013 | + fd__trace("[%d] asking for work\n", tid); |
2016 | _fd_broadcast(FD_MSG_FEED_ME, processes, tid); | 2014 | _fd_broadcast(FD_MSG_FEED_ME, processes, tid); |
2017 | 2015 | ||
2018 | waiting_on = FD_MSG_FEED_ME; | 2016 | waiting_on = FD_MSG_FEED_ME; |
@@ -2044,7 +2042,7 @@ int _fd_dsolve() | @@ -2044,7 +2042,7 @@ int _fd_dsolve() | ||
2044 | // see if there's some store saved up | 2042 | // see if there's some store saved up |
2045 | if (saved = fd_list_remove(saved_stores)) | 2043 | if (saved = fd_list_remove(saved_stores)) |
2046 | { | 2044 | { |
2047 | - _fd_debug("[%d] using saved store\n", tid); | 2045 | + fd__trace("[%d] using saved store\n", tid); |
2048 | 2046 | ||
2049 | memcpy(store, saved, | 2047 | memcpy(store, saved, |
2050 | fd_variables_count * sizeof(*saved)); | 2048 | fd_variables_count * sizeof(*saved)); |
@@ -2082,7 +2080,7 @@ int _fd_dsolve() | @@ -2082,7 +2080,7 @@ int _fd_dsolve() | ||
2082 | if (!supplier) | 2080 | if (!supplier) |
2083 | { | 2081 | { |
2084 | // ask the other processes for more work | 2082 | // ask the other processes for more work |
2085 | - _fd_debug("[%d] asking for work\n", tid); | 2083 | + fd__trace("[%d] asking for work\n", tid); |
2086 | _fd_broadcast(FD_MSG_FEED_ME, processes, tid); | 2084 | _fd_broadcast(FD_MSG_FEED_ME, processes, tid); |
2087 | 2085 | ||
2088 | waiting_on = FD_MSG_FEED_ME; | 2086 | waiting_on = FD_MSG_FEED_ME; |
@@ -2115,7 +2113,7 @@ int _fd_dsolve() | @@ -2115,7 +2113,7 @@ int _fd_dsolve() | ||
2115 | /* counting solutions external events (from the other processes) */ | 2113 | /* counting solutions external events (from the other processes) */ |
2116 | 2114 | ||
2117 | case EV_EXT_COUNT: | 2115 | case EV_EXT_COUNT: |
2118 | - _fd_debug("[%d] receiving count from %d\n", tid, peer); | 2116 | + fd__trace("[%d] receiving count from %d\n", tid, peer); |
2119 | 2117 | ||
2120 | assert(_fd_counting_solutions); | 2118 | assert(_fd_counting_solutions); |
2121 | 2119 | ||
@@ -2124,17 +2122,17 @@ int _fd_dsolve() | @@ -2124,17 +2122,17 @@ int _fd_dsolve() | ||
2124 | 2122 | ||
2125 | if (MPI_Recv(&ull, 1, MPI_LONG_LONG, peer, FD_MSG_COUNT, | 2123 | if (MPI_Recv(&ull, 1, MPI_LONG_LONG, peer, FD_MSG_COUNT, |
2126 | MPI_COMM_WORLD, &mpi_status)) | 2124 | MPI_COMM_WORLD, &mpi_status)) |
2127 | - _fd_fatal("MPI_Recv failed"); | 2125 | + fd__fatal("MPI_Recv failed"); |
2128 | 2126 | ||
2129 | external_solutions += ull; | 2127 | external_solutions += ull; |
2130 | 2128 | ||
2131 | - _fd_debug("[%d] process %d found %llu solutions\n", tid, peer, ull); | 2129 | + fd__trace("[%d] process %d found %llu solutions\n", tid, peer, ull); |
2132 | } | 2130 | } |
2133 | 2131 | ||
2134 | gettimeofday(&to, NULL); | 2132 | gettimeofday(&to, NULL); |
2135 | timersub(&to, &ti, &to); | 2133 | timersub(&to, &ti, &to); |
2136 | -#if defined(STATS_PROCS) || !defined(FAST) | ||
2137 | - fd__info("[%d] process %d took %d.%06ds\n", tid, peer, to.tv_sec, to.tv_usec); | 2134 | +#if defined(STATS_PROCS) || defined(TRACE) |
2135 | + fd__debug("[%d] process %d took %d.%06ds\n", tid, peer, to.tv_sec, to.tv_usec); | ||
2138 | #endif | 2136 | #endif |
2139 | 2137 | ||
2140 | live_procs--; | 2138 | live_procs--; |
@@ -2158,9 +2156,9 @@ int _fd_dsolve() | @@ -2158,9 +2156,9 @@ int _fd_dsolve() | ||
2158 | /* work stealing events (external) */ | 2156 | /* work stealing events (external) */ |
2159 | 2157 | ||
2160 | case EV_EXT_STORE: | 2158 | case EV_EXT_STORE: |
2161 | - _fd_debug("[%d] process %d sent a store\n", tid, peer); | 2159 | + fd__trace("[%d] process %d sent a store\n", tid, peer); |
2162 | 2160 | ||
2163 | -if (waiting_on == FD_MSG_ANY) _fd_debug("[%d] recovered store\n", tid); | 2161 | +if (waiting_on == FD_MSG_ANY) fd__trace("[%d] recovered store\n", tid); |
2164 | 2162 | ||
2165 | if (running == 0) | 2163 | if (running == 0) |
2166 | { | 2164 | { |
@@ -2198,7 +2196,7 @@ if (waiting_on == FD_MSG_ANY) _fd_debug("[%d] recovered store\n", tid); | @@ -2198,7 +2196,7 @@ if (waiting_on == FD_MSG_ANY) _fd_debug("[%d] recovered store\n", tid); | ||
2198 | 2196 | ||
2199 | break; | 2197 | break; |
2200 | case EV_EXT_REQ_WORK: | 2198 | case EV_EXT_REQ_WORK: |
2201 | - _fd_debug("[%d] process %d wants more work\n", tid, peer); | 2199 | + fd__trace("[%d] process %d wants more work\n", tid, peer); |
2202 | 2200 | ||
2203 | if (supplier) | 2201 | if (supplier) |
2204 | { | 2202 | { |
@@ -2216,7 +2214,7 @@ if (waiting_on == FD_MSG_ANY) _fd_debug("[%d] recovered store\n", tid); | @@ -2216,7 +2214,7 @@ if (waiting_on == FD_MSG_ANY) _fd_debug("[%d] recovered store\n", tid); | ||
2216 | 2214 | ||
2217 | break; | 2215 | break; |
2218 | case EV_EXT_NO_WORK: | 2216 | case EV_EXT_NO_WORK: |
2219 | - _fd_debug("[%d] process %d can't supply work\n", tid, peer); | 2217 | + fd__trace("[%d] process %d can't supply work\n", tid, peer); |
2220 | 2218 | ||
2221 | // no work sharing after having been told to stop | 2219 | // no work sharing after having been told to stop |
2222 | if (quitting || ready) | 2220 | if (quitting || ready) |
@@ -2268,7 +2266,7 @@ if (waiting_on == FD_MSG_ANY) _fd_debug("[%d] recovered store\n", tid); | @@ -2268,7 +2266,7 @@ if (waiting_on == FD_MSG_ANY) _fd_debug("[%d] recovered store\n", tid); | ||
2268 | 2266 | ||
2269 | break; | 2267 | break; |
2270 | case EV_EXT_NO_SHARE: | 2268 | case EV_EXT_NO_SHARE: |
2271 | - _fd_debug("[%d] process %d can't share work\n", tid, peer); | 2269 | + fd__trace("[%d] process %d can't share work\n", tid, peer); |
2272 | 2270 | ||
2273 | // no work sharing after having been told to stop | 2271 | // no work sharing after having been told to stop |
2274 | if (quitting || ready) | 2272 | if (quitting || ready) |
@@ -2284,7 +2282,7 @@ if (waiting_on == FD_MSG_ANY) _fd_debug("[%d] recovered store\n", tid); | @@ -2284,7 +2282,7 @@ if (waiting_on == FD_MSG_ANY) _fd_debug("[%d] recovered store\n", tid); | ||
2284 | 2282 | ||
2285 | if (peer != polling) | 2283 | if (peer != polling) |
2286 | { | 2284 | { |
2287 | - _fd_debug("[%d] polling %d but got answer from %d\n", | 2285 | + fd__trace("[%d] polling %d but got answer from %d\n", |
2288 | tid, polling, peer); | 2286 | tid, polling, peer); |
2289 | 2287 | ||
2290 | // belated answer, ignore | 2288 | // belated answer, ignore |
@@ -2331,14 +2329,14 @@ if (waiting_on == FD_MSG_ANY) _fd_debug("[%d] recovered store\n", tid); | @@ -2331,14 +2329,14 @@ if (waiting_on == FD_MSG_ANY) _fd_debug("[%d] recovered store\n", tid); | ||
2331 | 2329 | ||
2332 | break; | 2330 | break; |
2333 | case EV_EXT_REQ_SHARE: | 2331 | case EV_EXT_REQ_SHARE: |
2334 | - _fd_debug("[%d] process %d really wants work\n", tid, peer); | 2332 | + fd__trace("[%d] process %d really wants work\n", tid, peer); |
2335 | 2333 | ||
2336 | // if we're idle, there's nothing to share | 2334 | // if we're idle, there's nothing to share |
2337 | if (running == 0 || quitting || ready) // XXX: could be < nagents | 2335 | if (running == 0 || quitting || ready) // XXX: could be < nagents |
2338 | { | 2336 | { |
2339 | // notify the asking process that there really isn't | 2337 | // notify the asking process that there really isn't |
2340 | // work to be shared | 2338 | // work to be shared |
2341 | - _fd_debug("[%d] no work to share with %d\n", tid, peer); | 2339 | + fd__trace("[%d] no work to share with %d\n", tid, peer); |
2342 | _fd_send(peer, FD_MSG_NO_SHARE); | 2340 | _fd_send(peer, FD_MSG_NO_SHARE); |
2343 | 2341 | ||
2344 | break; | 2342 | break; |
@@ -2352,14 +2350,14 @@ if (waiting_on == FD_MSG_ANY) _fd_debug("[%d] recovered store\n", tid); | @@ -2352,14 +2350,14 @@ if (waiting_on == FD_MSG_ANY) _fd_debug("[%d] recovered store\n", tid); | ||
2352 | break; | 2350 | break; |
2353 | case EV_EXT_READY: | 2351 | case EV_EXT_READY: |
2354 | // peer has no work and no outgoing communications pending | 2352 | // peer has no work and no outgoing communications pending |
2355 | - _fd_debug("[%d] %d is done\n", tid, peer); | 2353 | + fd__trace("[%d] %d is done\n", tid, peer); |
2356 | 2354 | ||
2357 | assert(tid == 0); | 2355 | assert(tid == 0); |
2358 | 2356 | ||
2359 | mark_process_idle(peer); | 2357 | mark_process_idle(peer); |
2360 | 2358 | ||
2361 | // XXX: in mark_process_idle() | 2359 | // XXX: in mark_process_idle() |
2362 | - //_fd_debug("[%d] sending 2nd quit\n", tid); | 2360 | + //fd__trace("[%d] sending 2nd quit\n", tid); |
2363 | //_fd_broadcast(FD_MSG_QUIT, processes, tid); | 2361 | //_fd_broadcast(FD_MSG_QUIT, processes, tid); |
2364 | 2362 | ||
2365 | //done = running == 0 && live_procs == 1; | 2363 | //done = running == 0 && live_procs == 1; |
@@ -2371,7 +2369,7 @@ if (waiting_on == FD_MSG_ANY) _fd_debug("[%d] recovered store\n", tid); | @@ -2371,7 +2369,7 @@ if (waiting_on == FD_MSG_ANY) _fd_debug("[%d] recovered store\n", tid); | ||
2371 | break; | 2369 | break; |
2372 | case EV_EXT_QUIT: | 2370 | case EV_EXT_QUIT: |
2373 | // possibilities for finding work have been exhausted | 2371 | // possibilities for finding work have been exhausted |
2374 | - _fd_debug("[%d] %d told me to stop\n", tid, peer); | 2372 | + fd__trace("[%d] %d told me to stop\n", tid, peer); |
2375 | 2373 | ||
2376 | assert(tid != 0); | 2374 | assert(tid != 0); |
2377 | 2375 | ||
@@ -2385,12 +2383,12 @@ if (waiting_on == FD_MSG_ANY) _fd_debug("[%d] recovered store\n", tid); | @@ -2385,12 +2383,12 @@ if (waiting_on == FD_MSG_ANY) _fd_debug("[%d] recovered store\n", tid); | ||
2385 | break; | 2383 | break; |
2386 | #endif /* STEAL_WORK >= 2 */ | 2384 | #endif /* STEAL_WORK >= 2 */ |
2387 | default: | 2385 | default: |
2388 | - _fd_debug("[%d] unknown event in main loop: %d\n", tid, event); | ||
2389 | - _fd_fatal("unknown event in main loop"); | 2386 | + fd__debug("[%d] unknown event in main loop: %d\n", tid, event); |
2387 | + fd__fatal("unknown event in main loop"); | ||
2390 | } | 2388 | } |
2391 | 2389 | ||
2392 | #if STEAL_WORK >= 2 | 2390 | #if STEAL_WORK >= 2 |
2393 | -if (done) _fd_debug("[%d] done (quitting = %d, ready = %d, timeout = %d)\n", tid, quitting, ready, timeout); | 2391 | +if (done) fd__trace("[%d] done (quitting = %d, ready = %d, timeout = %d)\n", tid, quitting, ready, timeout); |
2394 | 2392 | ||
2395 | // if it is important that the full search space is explored, | 2393 | // if it is important that the full search space is explored, |
2396 | // make an extra effort for receiving messages that may have | 2394 | // make an extra effort for receiving messages that may have |
@@ -2400,7 +2398,7 @@ if (done) _fd_debug("[%d] done (quitting = %d, ready = %d, timeout = %d)\n", tid | @@ -2400,7 +2398,7 @@ if (done) _fd_debug("[%d] done (quitting = %d, ready = %d, timeout = %d)\n", tid | ||
2400 | _fd_optimising || | 2398 | _fd_optimising || |
2401 | status != FD_OK && !stopped)) | 2399 | status != FD_OK && !stopped)) |
2402 | { | 2400 | { |
2403 | - _fd_debug("[%d] checking for any event before leaving\n", tid); | 2401 | + fd__trace("[%d] checking for any event before leaving\n", tid); |
2404 | 2402 | ||
2405 | done = 0; | 2403 | done = 0; |
2406 | waiting_on = FD_MSG_ANY; | 2404 | waiting_on = FD_MSG_ANY; |
@@ -2438,14 +2436,14 @@ if (done) _fd_debug("[%d] done (quitting = %d, ready = %d, timeout = %d)\n", tid | @@ -2438,14 +2436,14 @@ if (done) _fd_debug("[%d] done (quitting = %d, ready = %d, timeout = %d)\n", tid | ||
2438 | 2436 | ||
2439 | if (!mpi_flag) // request hasn't completed | 2437 | if (!mpi_flag) // request hasn't completed |
2440 | { | 2438 | { |
2441 | - _fd_debug("[%d] recovering outstanding store to %d\n", | 2439 | + fd__trace("[%d] recovering outstanding store to %d\n", |
2442 | tid, i); | 2440 | tid, i); |
2443 | 2441 | ||
2444 | // try cancelling the send (or the cancel?) | 2442 | // try cancelling the send (or the cancel?) |
2445 | if (MPI_Cancel(stores_pending + i)) | 2443 | if (MPI_Cancel(stores_pending + i)) |
2446 | perror("MPI_Cancel"); | 2444 | perror("MPI_Cancel"); |
2447 | 2445 | ||
2448 | - _fd_debug("[%d] cancelled request\n", tid); | 2446 | + fd__trace("[%d] cancelled request\n", tid); |
2449 | 2447 | ||
2450 | // allow the cancel some time to complete | 2448 | // allow the cancel some time to complete |
2451 | do | 2449 | do |
@@ -2457,7 +2455,7 @@ if (done) _fd_debug("[%d] done (quitting = %d, ready = %d, timeout = %d)\n", tid | @@ -2457,7 +2455,7 @@ if (done) _fd_debug("[%d] done (quitting = %d, ready = %d, timeout = %d)\n", tid | ||
2457 | if (mpi_flag) | 2455 | if (mpi_flag) |
2458 | break; | 2456 | break; |
2459 | 2457 | ||
2460 | - _fd_debug("[%d] cancelling store to %d didn't complete\n", | 2458 | + fd__trace("[%d] cancelling store to %d didn't complete\n", |
2461 | tid, i); | 2459 | tid, i); |
2462 | 2460 | ||
2463 | if (--tries == 0) | 2461 | if (--tries == 0) |
@@ -2469,7 +2467,7 @@ if (done) _fd_debug("[%d] done (quitting = %d, ready = %d, timeout = %d)\n", tid | @@ -2469,7 +2467,7 @@ if (done) _fd_debug("[%d] done (quitting = %d, ready = %d, timeout = %d)\n", tid | ||
2469 | 2467 | ||
2470 | if (!mpi_flag) // cancel didn't complete, give up for now | 2468 | if (!mpi_flag) // cancel didn't complete, give up for now |
2471 | { | 2469 | { |
2472 | - _fd_debug("[%d] giving up cancelling store to %i for now\n", | 2470 | + fd__trace("[%d] giving up cancelling store to %i for now\n", |
2473 | tid, i); | 2471 | tid, i); |
2474 | 2472 | ||
2475 | // if no store is cancelled, will have to wait | 2473 | // if no store is cancelled, will have to wait |
@@ -2482,7 +2480,7 @@ if (done) _fd_debug("[%d] done (quitting = %d, ready = %d, timeout = %d)\n", tid | @@ -2482,7 +2480,7 @@ if (done) _fd_debug("[%d] done (quitting = %d, ready = %d, timeout = %d)\n", tid | ||
2482 | continue; | 2480 | continue; |
2483 | } | 2481 | } |
2484 | 2482 | ||
2485 | - _fd_debug("[%d] status = (%d, %d, %d, %d, %d)\n", tid, | 2483 | + fd__trace("[%d] status = (%d, %d, %d, %d, %d)\n", tid, |
2486 | mpi_status.MPI_SOURCE, mpi_status.MPI_TAG, | 2484 | mpi_status.MPI_SOURCE, mpi_status.MPI_TAG, |
2487 | mpi_status.MPI_ERROR, mpi_status._count, | 2485 | mpi_status.MPI_ERROR, mpi_status._count, |
2488 | mpi_status._cancelled); | 2486 | mpi_status._cancelled); |
@@ -2491,12 +2489,12 @@ if (done) _fd_debug("[%d] done (quitting = %d, ready = %d, timeout = %d)\n", tid | @@ -2491,12 +2489,12 @@ if (done) _fd_debug("[%d] done (quitting = %d, ready = %d, timeout = %d)\n", tid | ||
2491 | 2489 | ||
2492 | if (!mpi_flag) | 2490 | if (!mpi_flag) |
2493 | { | 2491 | { |
2494 | - _fd_debug("[%d] cancel did not succeed\n", tid); | 2492 | + fd__trace("[%d] cancel did not succeed\n", tid); |
2495 | 2493 | ||
2496 | continue; | 2494 | continue; |
2497 | } | 2495 | } |
2498 | 2496 | ||
2499 | - _fd_debug("[%d] cancel succeeded\n", tid); | 2497 | + fd__trace("[%d] cancel succeeded\n", tid); |
2500 | } | 2498 | } |
2501 | else | 2499 | else |
2502 | { | 2500 | { |
@@ -2506,7 +2504,7 @@ if (done) _fd_debug("[%d] done (quitting = %d, ready = %d, timeout = %d)\n", tid | @@ -2506,7 +2504,7 @@ if (done) _fd_debug("[%d] done (quitting = %d, ready = %d, timeout = %d)\n", tid | ||
2506 | if (!mpi_flag) | 2504 | if (!mpi_flag) |
2507 | continue; // the send has completed | 2505 | continue; // the send has completed |
2508 | 2506 | ||
2509 | - _fd_debug("[%d] previously cancelled store to %d\n", | 2507 | + fd__trace("[%d] previously cancelled store to %d\n", |
2510 | tid, i); | 2508 | tid, i); |
2511 | } | 2509 | } |
2512 | 2510 | ||
@@ -2533,7 +2531,7 @@ if (done) _fd_debug("[%d] done (quitting = %d, ready = %d, timeout = %d)\n", tid | @@ -2533,7 +2531,7 @@ if (done) _fd_debug("[%d] done (quitting = %d, ready = %d, timeout = %d)\n", tid | ||
2533 | { | 2531 | { |
2534 | if (tid != 0) | 2532 | if (tid != 0) |
2535 | { | 2533 | { |
2536 | - _fd_debug("[%d] ready to leave\n", tid); | 2534 | + fd__trace("[%d] ready to leave\n", tid); |
2537 | 2535 | ||
2538 | _fd_send(0, FD_MSG_READY); | 2536 | _fd_send(0, FD_MSG_READY); |
2539 | 2537 | ||
@@ -2566,11 +2564,11 @@ if (done) _fd_debug("[%d] done (quitting = %d, ready = %d, timeout = %d)\n", tid | @@ -2566,11 +2564,11 @@ if (done) _fd_debug("[%d] done (quitting = %d, ready = %d, timeout = %d)\n", tid | ||
2566 | // stop the other processes | 2564 | // stop the other processes |
2567 | if (live_procs > 1) | 2565 | if (live_procs > 1) |
2568 | { | 2566 | { |
2569 | - _fd_debug("[%d] stopping all processes\n", tid); | 2567 | + fd__trace("[%d] stopping all processes\n", tid); |
2570 | _fd_broadcast(FD_MSG_DONE, processes, tid); | 2568 | _fd_broadcast(FD_MSG_DONE, processes, tid); |
2571 | } | 2569 | } |
2572 | else | 2570 | else |
2573 | - _fd_debug("[%d] all other processes already stopped\n", tid); | 2571 | + fd__trace("[%d] all other processes already stopped\n", tid); |
2574 | 2572 | ||
2575 | if (_fd_optimising && status == FD_OK) | 2573 | if (_fd_optimising && status == FD_OK) |
2576 | { | 2574 | { |
@@ -2581,7 +2579,7 @@ if (done) _fd_debug("[%d] done (quitting = %d, ready = %d, timeout = %d)\n", tid | @@ -2581,7 +2579,7 @@ if (done) _fd_debug("[%d] done (quitting = %d, ready = %d, timeout = %d)\n", tid | ||
2581 | if (ts.tv_sec) | 2579 | if (ts.tv_sec) |
2582 | { | 2580 | { |
2583 | timersub(&ts, &ti, &ts); | 2581 | timersub(&ts, &ti, &ts); |
2584 | - _fd_debug("[%d] time to solution was %d.%06ds\n", tid, | 2582 | + fd__trace("[%d] time to solution was %d.%06ds\n", tid, |
2585 | ts.tv_sec, ts.tv_usec); | 2583 | ts.tv_sec, ts.tv_usec); |
2586 | } | 2584 | } |
2587 | } | 2585 | } |
@@ -2594,7 +2592,7 @@ if (done) _fd_debug("[%d] done (quitting = %d, ready = %d, timeout = %d)\n", tid | @@ -2594,7 +2592,7 @@ if (done) _fd_debug("[%d] done (quitting = %d, ready = %d, timeout = %d)\n", tid | ||
2594 | { | 2592 | { |
2595 | MPI_Request *mpi_request = malloc(sizeof(MPI_Request)); | 2593 | MPI_Request *mpi_request = malloc(sizeof(MPI_Request)); |
2596 | 2594 | ||
2597 | - _fd_debug("[%d] sending solution\n", tid); | 2595 | + fd__trace("[%d] sending solution\n", tid); |
2598 | 2596 | ||
2599 | if (_fd_optimising) | 2597 | if (_fd_optimising) |
2600 | assert(have_solution); | 2598 | assert(have_solution); |
@@ -2605,7 +2603,7 @@ if (done) _fd_debug("[%d] done (quitting = %d, ready = %d, timeout = %d)\n", tid | @@ -2605,7 +2603,7 @@ if (done) _fd_debug("[%d] done (quitting = %d, ready = %d, timeout = %d)\n", tid | ||
2605 | if (ts.tv_sec) | 2603 | if (ts.tv_sec) |
2606 | { | 2604 | { |
2607 | timersub(&ts, &ti, &ts); | 2605 | timersub(&ts, &ti, &ts); |
2608 | - _fd_debug("[%d] time to solution was %d.%06ds\n", tid, | 2606 | + fd__trace("[%d] time to solution was %d.%06ds\n", tid, |
2609 | ts.tv_sec, ts.tv_usec); | 2607 | ts.tv_sec, ts.tv_usec); |
2610 | } | 2608 | } |
2611 | 2609 | ||
@@ -2613,19 +2611,19 @@ if (done) _fd_debug("[%d] done (quitting = %d, ready = %d, timeout = %d)\n", tid | @@ -2613,19 +2611,19 @@ if (done) _fd_debug("[%d] done (quitting = %d, ready = %d, timeout = %d)\n", tid | ||
2613 | } | 2611 | } |
2614 | else | 2612 | else |
2615 | { | 2613 | { |
2616 | - _fd_debug("[%d] sending failure notice\n", tid); | 2614 | + fd__trace("[%d] sending failure notice\n", tid); |
2617 | _fd_send(0, FD_MSG_FAIL); | 2615 | _fd_send(0, FD_MSG_FAIL); |
2618 | } | 2616 | } |
2619 | } | 2617 | } |
2620 | 2618 | ||
2621 | // stop all the agents | 2619 | // stop all the agents |
2622 | - _fd_debug("[%d] stopping agents\n", tid); | 2620 | + fd__trace("[%d] stopping agents\n", tid); |
2623 | for (i = 0; i < started; ++i) | 2621 | for (i = 0; i < started; ++i) |
2624 | { | 2622 | { |
2625 | int s; | 2623 | int s; |
2626 | 2624 | ||
2627 | if ((s = pthread_cancel(threads[i])) && s != ESRCH) | 2625 | if ((s = pthread_cancel(threads[i])) && s != ESRCH) |
2628 | - _fd_debug("[%d] error cancelling thread %d = %d\n", tid, i, s); | 2626 | + fd__debug("[%d] error cancelling thread %d = %d\n", tid, i, s); |
2629 | } | 2627 | } |
2630 | 2628 | ||
2631 | // make sure all agents have stopped before exiting | 2629 | // make sure all agents have stopped before exiting |
@@ -2634,9 +2632,9 @@ if (done) _fd_debug("[%d] done (quitting = %d, ready = %d, timeout = %d)\n", tid | @@ -2634,9 +2632,9 @@ if (done) _fd_debug("[%d] done (quitting = %d, ready = %d, timeout = %d)\n", tid | ||
2634 | { | 2632 | { |
2635 | int s; | 2633 | int s; |
2636 | 2634 | ||
2637 | - _fd_debug("[%d] joining agent %d\n", tid, i); | 2635 | + fd__trace("[%d] joining agent %d\n", tid, i); |
2638 | if ((s = pthread_join(threads[i], NULL)) && s != ESRCH) | 2636 | if ((s = pthread_join(threads[i], NULL)) && s != ESRCH) |
2639 | - _fd_debug("[%d] error joining thread %d = %d\n", tid, i, s); | 2637 | + fd__debug("[%d] error joining thread %d = %d\n", tid, i, s); |
2640 | } | 2638 | } |
2641 | 2639 | ||
2642 | #if STEAL_WORK >= 2 | 2640 | #if STEAL_WORK >= 2 |
@@ -2652,13 +2650,13 @@ if (done) _fd_debug("[%d] done (quitting = %d, ready = %d, timeout = %d)\n", tid | @@ -2652,13 +2650,13 @@ if (done) _fd_debug("[%d] done (quitting = %d, ready = %d, timeout = %d)\n", tid | ||
2652 | 2650 | ||
2653 | #if STEAL_WORK >= 2 | 2651 | #if STEAL_WORK >= 2 |
2654 | // stop all the agents, which are waiting for work | 2652 | // stop all the agents, which are waiting for work |
2655 | - _fd_debug("[%d] stopping agents\n", tid); | 2653 | + fd__trace("[%d] stopping agents\n", tid); |
2656 | for (i = 0; i < started; ++i) | 2654 | for (i = 0; i < started; ++i) |
2657 | { | 2655 | { |
2658 | int s; | 2656 | int s; |
2659 | 2657 | ||
2660 | if ((s = pthread_cancel(threads[i])) && s != ESRCH) | 2658 | if ((s = pthread_cancel(threads[i])) && s != ESRCH) |
2661 | - _fd_debug("[%d] error cancelling thread %d = %d\n", tid, i, s); | 2659 | + fd__debug("[%d] error cancelling thread %d = %d\n", tid, i, s); |
2662 | } | 2660 | } |
2663 | 2661 | ||
2664 | // make sure all agents have stopped before exiting | 2662 | // make sure all agents have stopped before exiting |
@@ -2666,13 +2664,13 @@ if (done) _fd_debug("[%d] done (quitting = %d, ready = %d, timeout = %d)\n", tid | @@ -2666,13 +2664,13 @@ if (done) _fd_debug("[%d] done (quitting = %d, ready = %d, timeout = %d)\n", tid | ||
2666 | { | 2664 | { |
2667 | int s; | 2665 | int s; |
2668 | 2666 | ||
2669 | - _fd_debug("[%d] joining agent %d\n", tid, i); | 2667 | + fd__trace("[%d] joining agent %d\n", tid, i); |
2670 | if ((s = pthread_join(threads[i], NULL)) && s != ESRCH) | 2668 | if ((s = pthread_join(threads[i], NULL)) && s != ESRCH) |
2671 | - _fd_debug("[%d] error joining thread %d = %d\n", tid, i, s); | 2669 | + fd__debug("[%d] error joining thread %d = %d\n", tid, i, s); |
2672 | } | 2670 | } |
2673 | 2671 | ||
2674 | if (!fd_list_empty(saved_stores)) | 2672 | if (!fd_list_empty(saved_stores)) |
2675 | - _fd_fatal("saved_stores not empty on exit"); | 2673 | + fd__fatal("saved_stores not empty on exit"); |
2676 | 2674 | ||
2677 | fd_list_dispose(saved_stores); | 2675 | fd_list_dispose(saved_stores); |
2678 | #endif /* STEAL_WORK >= 2 */ | 2676 | #endif /* STEAL_WORK >= 2 */ |
@@ -2699,15 +2697,15 @@ if (done) _fd_debug("[%d] done (quitting = %d, ready = %d, timeout = %d)\n", tid | @@ -2699,15 +2697,15 @@ if (done) _fd_debug("[%d] done (quitting = %d, ready = %d, timeout = %d)\n", tid | ||
2699 | 2697 | ||
2700 | if (_fd_counting_solutions) | 2698 | if (_fd_counting_solutions) |
2701 | { | 2699 | { |
2702 | - _fd_output("found %llu solutions\n", total_solutions + external_solutions); // XXX | 2700 | + fd__output("found %llu solutions\n", total_solutions + external_solutions); // XXX |
2703 | 2701 | ||
2704 | status = FD_NOSOLUTION; // XXX | 2702 | status = FD_NOSOLUTION; // XXX |
2705 | } | 2703 | } |
2706 | 2704 | ||
2707 | gettimeofday(&to, NULL); | 2705 | gettimeofday(&to, NULL); |
2708 | timersub(&to, &ti, &to); | 2706 | timersub(&to, &ti, &to); |
2709 | -#if defined(STATS_PROCS) || !defined(FAST) | ||
2710 | - fd__info("process %d took %d.%06ds\n", tid, to.tv_sec, to.tv_usec); | 2707 | +#if defined(STATS_PROCS) || defined(TRACE) |
2708 | + fd__debug("process %d took %d.%06ds\n", tid, to.tv_sec, to.tv_usec); | ||
2711 | #endif | 2709 | #endif |
2712 | 2710 | ||
2713 | return status; | 2711 | return status; |
src/agents-splitgo.c
@@ -13,6 +13,8 @@ | @@ -13,6 +13,8 @@ | ||
13 | #include "splitting.h" | 13 | #include "splitting.h" |
14 | #include "bound.h" | 14 | #include "bound.h" |
15 | 15 | ||
16 | +#include "util.h" | ||
17 | + | ||
16 | #ifndef COMPACT_DOMAINS | 18 | #ifndef COMPACT_DOMAINS |
17 | #error "only works with COMPACT_DOMAINS" | 19 | #error "only works with COMPACT_DOMAINS" |
18 | #endif | 20 | #endif |
@@ -81,7 +83,7 @@ int _fd_agent(int n) | @@ -81,7 +83,7 @@ int _fd_agent(int n) | ||
81 | int result; | 83 | int result; |
82 | struct timeval ti, tis, to, tos; | 84 | struct timeval ti, tis, to, tos; |
83 | 85 | ||
84 | - _fd_debug("starting agent %d\n", n); | 86 | + fd__trace("starting agent %d\n", n); |
85 | 87 | ||
86 | gettimeofday(&ti, NULL); | 88 | gettimeofday(&ti, NULL); |
87 | 89 | ||
@@ -93,11 +95,11 @@ int _fd_agent(int n) | @@ -93,11 +95,11 @@ int _fd_agent(int n) | ||
93 | 95 | ||
94 | gettimeofday(&to, NULL); | 96 | gettimeofday(&to, NULL); |
95 | timersub(&to, &ti, &to); | 97 | timersub(&to, &ti, &to); |
96 | - _fd_debug("agent %d took %d.%06ds\n", n, to.tv_sec, to.tv_usec); | 98 | + fd__trace("agent %d took %d.%06ds\n", n, to.tv_sec, to.tv_usec); |
97 | 99 | ||
98 | while (result == FD_OK) | 100 | while (result == FD_OK) |
99 | { | 101 | { |
100 | - _fd_debug("agent %d was successful\n", n); | 102 | + fd__trace("agent %d was successful\n", n); |
101 | 103 | ||
102 | // ensure that only one agent signals its success | 104 | // ensure that only one agent signals its success |
103 | // XXX: only good (?) if only looking for the 1st solution | 105 | // XXX: only good (?) if only looking for the 1st solution |
@@ -106,7 +108,7 @@ int _fd_agent(int n) | @@ -106,7 +108,7 @@ int _fd_agent(int n) | ||
106 | // in sem_wait() | 108 | // in sem_wait() |
107 | pthread_cleanup_push((void (*)(void *)) pthread_mutex_unlock, | 109 | pthread_cleanup_push((void (*)(void *)) pthread_mutex_unlock, |
108 | &success_mutex); | 110 | &success_mutex); |
109 | - _fd_debug("agent %d acquired success mutex\n", n); | 111 | + fd__trace("agent %d acquired success mutex\n", n); |
110 | 112 | ||
111 | // tell the main thread that this agent is done | 113 | // tell the main thread that this agent is done |
112 | if (sem_wait(&ready_semaphore)) | 114 | if (sem_wait(&ready_semaphore)) |
@@ -119,14 +121,14 @@ int _fd_agent(int n) | @@ -119,14 +121,14 @@ int _fd_agent(int n) | ||
119 | 121 | ||
120 | pthread_mutex_unlock(&success_mutex); | 122 | pthread_mutex_unlock(&success_mutex); |
121 | pthread_cleanup_pop(0); | 123 | pthread_cleanup_pop(0); |
122 | - _fd_debug("agent %d released success mutex\n", n); | 124 | + fd__trace("agent %d released success mutex\n", n); |
123 | 125 | ||
124 | if (!_fd_optimising) | 126 | if (!_fd_optimising) |
125 | return result; | 127 | return result; |
126 | 128 | ||
127 | if (sem_wait(&resume_semaphore)) | 129 | if (sem_wait(&resume_semaphore)) |
128 | perror("sem_post (resume)"); | 130 | perror("sem_post (resume)"); |
129 | - _fd_debug("[%d] resuming, new bound is %d\n", n, _fd_bound_value()); | 131 | + fd__trace("[%d] resuming, new bound is %d\n", n, _fd_bound_value()); |
130 | 132 | ||
131 | // find the next solution | 133 | // find the next solution |
132 | gettimeofday(&tis, NULL); | 134 | gettimeofday(&tis, NULL); |
@@ -136,12 +138,12 @@ int _fd_agent(int n) | @@ -136,12 +138,12 @@ int _fd_agent(int n) | ||
136 | gettimeofday(&to, NULL); | 138 | gettimeofday(&to, NULL); |
137 | timersub(&to, &tis, &tos); | 139 | timersub(&to, &tis, &tos); |
138 | timersub(&to, &ti, &to); | 140 | timersub(&to, &ti, &to); |
139 | - _fd_debug("agent %d took %d.%06ds (%d.%06ds)\n", n, | 141 | + fd__trace("agent %d took %d.%06ds (%d.%06ds)\n", n, |
140 | tos.tv_sec, tos.tv_usec, to.tv_sec, to.tv_usec); | 142 | tos.tv_sec, tos.tv_usec, to.tv_sec, to.tv_usec); |
141 | } | 143 | } |
142 | 144 | ||
143 | // eventually, the agent will fail to find a solution | 145 | // eventually, the agent will fail to find a solution |
144 | - _fd_debug("agent %d was unsuccessful\n", n); | 146 | + fd__trace("agent %d was unsuccessful\n", n); |
145 | 147 | ||
146 | // tell the main thread that this agent is done | 148 | // tell the main thread that this agent is done |
147 | if (sem_wait(&ready_semaphore)) | 149 | if (sem_wait(&ready_semaphore)) |
@@ -159,7 +161,7 @@ int _fd_agent(int n) | @@ -159,7 +161,7 @@ int _fd_agent(int n) | ||
159 | unsigned long long solutions; | 161 | unsigned long long solutions; |
160 | struct timeval ti, to; | 162 | struct timeval ti, to; |
161 | 163 | ||
162 | - _fd_debug("starting agent %d\n", n); | 164 | + fd__trace("starting agent %d\n", n); |
163 | 165 | ||
164 | gettimeofday(&ti, NULL); | 166 | gettimeofday(&ti, NULL); |
165 | 167 | ||
@@ -171,9 +173,9 @@ int _fd_agent(int n) | @@ -171,9 +173,9 @@ int _fd_agent(int n) | ||
171 | 173 | ||
172 | gettimeofday(&to, NULL); | 174 | gettimeofday(&to, NULL); |
173 | timersub(&to, &ti, &to); | 175 | timersub(&to, &ti, &to); |
174 | - _fd_debug("agent %d took %d.%06ds\n", n, to.tv_sec, to.tv_usec); | 176 | + fd__trace("agent %d took %d.%06ds\n", n, to.tv_sec, to.tv_usec); |
175 | 177 | ||
176 | - _fd_debug("agent %d found %llu solutions\n", n, solutions); | 178 | + fd__trace("agent %d found %llu solutions\n", n, solutions); |
177 | 179 | ||
178 | // tell the main thread that this agent is done | 180 | // tell the main thread that this agent is done |
179 | if (sem_wait(&ready_semaphore)) | 181 | if (sem_wait(&ready_semaphore)) |
@@ -193,7 +195,7 @@ int _fd_agent(int n) | @@ -193,7 +195,7 @@ int _fd_agent(int n) | ||
193 | 195 | ||
194 | void _fd_search_space_sizes(_fd_store stores[], int n) | 196 | void _fd_search_space_sizes(_fd_store stores[], int n) |
195 | { | 197 | { |
196 | -#ifndef FAST | 198 | +#ifdef TRACE |
197 | double s; | 199 | double s; |
198 | int i, v; | 200 | int i, v; |
199 | 201 | ||
@@ -208,9 +210,9 @@ void _fd_search_space_sizes(_fd_store stores[], int n) | @@ -208,9 +210,9 @@ void _fd_search_space_sizes(_fd_store stores[], int n) | ||
208 | for (v = 0; v < fd__label_vars_count; ++v) | 210 | for (v = 0; v < fd__label_vars_count; ++v) |
209 | s *= _fd_val_size(SVALUE(stores[i][fd__label_vars[v]->index])); | 211 | s *= _fd_val_size(SVALUE(stores[i][fd__label_vars[v]->index])); |
210 | 212 | ||
211 | - _fd_debug("search space %d size is %g\n", i, s); | 213 | + fd__trace("search space %d size is %g\n", i, s); |
212 | } | 214 | } |
213 | -#endif /* FAST */ | 215 | +#endif /* TRACE */ |
214 | } | 216 | } |
215 | 217 | ||
216 | int _fd_dsolve() | 218 | int _fd_dsolve() |
@@ -265,7 +267,7 @@ int _fd_dsolve() | @@ -265,7 +267,7 @@ int _fd_dsolve() | ||
265 | 267 | ||
266 | if (parts < nagents) | 268 | if (parts < nagents) |
267 | { | 269 | { |
268 | - _fd_debug("reducing to %d agents!\n", parts); | 270 | + fd__trace("reducing to %d agents!\n", parts); |
269 | 271 | ||
270 | nagents = parts; | 272 | nagents = parts; |
271 | } | 273 | } |
@@ -274,7 +276,7 @@ int _fd_dsolve() | @@ -274,7 +276,7 @@ int _fd_dsolve() | ||
274 | 276 | ||
275 | gettimeofday(&to, NULL); | 277 | gettimeofday(&to, NULL); |
276 | timersub(&to, &ti, &to); | 278 | timersub(&to, &ti, &to); |
277 | - _fd_debug("setup took %d.%06ds\n", to.tv_sec, to.tv_usec); | 279 | + fd__trace("setup took %d.%06ds\n", to.tv_sec, to.tv_usec); |
278 | 280 | ||
279 | #if 0 | 281 | #if 0 |
280 | for (i = 0; i < nagents; ++i) | 282 | for (i = 0; i < nagents; ++i) |
@@ -316,7 +318,7 @@ int _fd_dsolve() | @@ -316,7 +318,7 @@ int _fd_dsolve() | ||
316 | } | 318 | } |
317 | } | 319 | } |
318 | 320 | ||
319 | - _fd_debug("main thread waiting\n"); | 321 | + fd__trace("main thread waiting\n"); |
320 | 322 | ||
321 | running = started; | 323 | running = started; |
322 | do | 324 | do |
@@ -329,7 +331,7 @@ int _fd_dsolve() | @@ -329,7 +331,7 @@ int _fd_dsolve() | ||
329 | if (sem_post(&ready_semaphore)) | 331 | if (sem_post(&ready_semaphore)) |
330 | perror("sem_post"); | 332 | perror("sem_post"); |
331 | 333 | ||
332 | - _fd_debug("got an answer from %s%d\n", solver == -1 ? "-" : "", | 334 | + fd__trace("got an answer from %s%d\n", solver == -1 ? "-" : "", |
333 | solver + (solver < 0)); | 335 | solver + (solver < 0)); |
334 | 336 | ||
335 | if (_fd_optimising && solver >= 0) | 337 | if (_fd_optimising && solver >= 0) |
@@ -344,10 +346,10 @@ int _fd_dsolve() | @@ -344,10 +346,10 @@ int _fd_dsolve() | ||
344 | memcpy(store, _fd_agents_stores[solver], | 346 | memcpy(store, _fd_agents_stores[solver], |
345 | fd_variables_count * sizeof(*store)); | 347 | fd_variables_count * sizeof(*store)); |
346 | 348 | ||
347 | - _fd_debug("releasing %d\n", solver); | 349 | + fd__trace("releasing %d\n", solver); |
348 | } | 350 | } |
349 | else | 351 | else |
350 | - _fd_debug("invalid solution, releasing %d\n", solver); | 352 | + fd__trace("invalid solution, releasing %d\n", solver); |
351 | 353 | ||
352 | if (sem_post(&resume_semaphore)) | 354 | if (sem_post(&resume_semaphore)) |
353 | perror("sem_post (resume)"); | 355 | perror("sem_post (resume)"); |
@@ -359,14 +361,14 @@ int _fd_dsolve() | @@ -359,14 +361,14 @@ int _fd_dsolve() | ||
359 | } | 361 | } |
360 | while ((_fd_optimising || solver < 0) && running > 0); | 362 | while ((_fd_optimising || solver < 0) && running > 0); |
361 | 363 | ||
362 | - _fd_debug("%s solution\n", solver < 0 ? "found no" : "got a"); | 364 | + fd__trace("%s solution\n", solver < 0 ? "found no" : "got a"); |
363 | 365 | ||
364 | for (i = 0; i < started; ++i) | 366 | for (i = 0; i < started; ++i) |
365 | { | 367 | { |
366 | int s; | 368 | int s; |
367 | 369 | ||
368 | if ((s = pthread_cancel(threads[i])) && s != ESRCH) | 370 | if ((s = pthread_cancel(threads[i])) && s != ESRCH) |
369 | - _fd_debug("error cancelling thread %d = %d\n", i, s); | 371 | + fd__debug("error cancelling thread %d = %d\n", i, s); |
370 | } | 372 | } |
371 | 373 | ||
372 | // make sure all agents have stopped before exiting | 374 | // make sure all agents have stopped before exiting |
@@ -376,24 +378,26 @@ int _fd_dsolve() | @@ -376,24 +378,26 @@ int _fd_dsolve() | ||
376 | int s; | 378 | int s; |
377 | 379 | ||
378 | if ((s = pthread_join(threads[i], NULL)) && s != ESRCH) | 380 | if ((s = pthread_join(threads[i], NULL)) && s != ESRCH) |
379 | - _fd_debug("error joining thread %d = %d\n", i, s); | 381 | + fd__debug("error joining thread %d = %d\n", i, s); |
380 | } | 382 | } |
381 | 383 | ||
382 | if (_fd_optimising) | 384 | if (_fd_optimising) |
383 | { | 385 | { |
384 | if (have_solution >= 0) | 386 | if (have_solution >= 0) |
385 | { | 387 | { |
386 | - _fd_debug("using agent %d's results\n", have_solution); | 388 | + fd__trace("using agent %d's results\n", have_solution); |
387 | 389 | ||
390 | +#if defined(STATS_TIME_SOLUTION) || defined(TRACE) | ||
388 | timersub(&ts, &ti, &ts); | 391 | timersub(&ts, &ti, &ts); |
389 | - _fd_debug("time to solution was %d.%06ds\n", ts.tv_sec, ts.tv_usec); | 392 | + fd__debug("time to solution was %d.%06ds\n", ts.tv_sec, ts.tv_usec); |
393 | +#endif | ||
390 | 394 | ||
391 | status = FD_OK; | 395 | status = FD_OK; |
392 | } | 396 | } |
393 | } | 397 | } |
394 | else if (solver >= 0) | 398 | else if (solver >= 0) |
395 | { | 399 | { |
396 | - _fd_debug("using agent %d's results\n", solver); | 400 | + fd__trace("using agent %d's results\n", solver); |
397 | 401 | ||
398 | status = FD_OK; | 402 | status = FD_OK; |
399 | 403 | ||
@@ -404,7 +408,7 @@ int _fd_dsolve() | @@ -404,7 +408,7 @@ int _fd_dsolve() | ||
404 | else /* agents == 0 */ | 408 | else /* agents == 0 */ |
405 | { | 409 | { |
406 | if (_fd_optimising) | 410 | if (_fd_optimising) |
407 | - _fd_fatal("need at least one agent when optimising"); | 411 | + fd__fatal("need at least one agent when optimising"); |
408 | 412 | ||
409 | _fd_agents_stores[0] = store; | 413 | _fd_agents_stores[0] = store; |
410 | 414 | ||
@@ -439,7 +443,7 @@ int _fd_dsolve() | @@ -439,7 +443,7 @@ int _fd_dsolve() | ||
439 | started++; | 443 | started++; |
440 | } | 444 | } |
441 | 445 | ||
442 | - _fd_debug("main thread waiting\n"); | 446 | + fd__trace("main thread waiting\n"); |
443 | 447 | ||
444 | running = started; | 448 | running = started; |
445 | do | 449 | do |
@@ -465,7 +469,7 @@ int _fd_dsolve() | @@ -465,7 +469,7 @@ int _fd_dsolve() | ||
465 | 469 | ||
466 | _fd_statistics_steal(); | 470 | _fd_statistics_steal(); |
467 | 471 | ||
468 | - _fd_output("found %llu solutions\n", total_solutions); // XXX | 472 | + fd__output("found %llu solutions\n", total_solutions); // XXX |
469 | 473 | ||
470 | return FD_NOSOLUTION; // XXX | 474 | return FD_NOSOLUTION; // XXX |
471 | } | 475 | } |
src/bound.c
@@ -5,8 +5,10 @@ | @@ -5,8 +5,10 @@ | ||
5 | 5 | ||
6 | #include "fdc_int.h" | 6 | #include "fdc_int.h" |
7 | #include "store.h" | 7 | #include "store.h" |
8 | - | ||
9 | #include "bound.h" | 8 | #include "bound.h" |
9 | +#include "constraints.h" | ||
10 | + | ||
11 | +#include "util.h" | ||
10 | 12 | ||
11 | bool _fd_optimising = false; | 13 | bool _fd_optimising = false; |
12 | 14 | ||
@@ -32,10 +34,10 @@ _fd_bound_data *_fd_init_bound(int n, C_VAR_T v, fd_constraint c, | @@ -32,10 +34,10 @@ _fd_bound_data *_fd_init_bound(int n, C_VAR_T v, fd_constraint c, | ||
32 | _fd_bound_data *b; | 34 | _fd_bound_data *b; |
33 | 35 | ||
34 | if (_fd_bound) | 36 | if (_fd_bound) |
35 | - _fd_fatal("trying to set a 2nd optimisation constraint"); | 37 | + fd__fatal("trying to set a 2nd optimisation constraint"); |
36 | 38 | ||
37 | if ((b = malloc(sizeof(*_fd_bound))) == NULL) | 39 | if ((b = malloc(sizeof(*_fd_bound))) == NULL) |
38 | - _fd_fatal("could not allocate memory for the optimisation bound"); | 40 | + fd__fatal("could not allocate memory for the optimisation bound"); |
39 | 41 | ||
40 | b->value = n; | 42 | b->value = n; |
41 | b->variable = v; | 43 | b->variable = v; |
@@ -121,9 +123,7 @@ int fd__bound_and_revise() | @@ -121,9 +123,7 @@ int fd__bound_and_revise() | ||
121 | 123 | ||
122 | if (_fd_revise_wrt_variable(_fd_bound_variable()) == FD_NOSOLUTION) | 124 | if (_fd_revise_wrt_variable(_fd_bound_variable()) == FD_NOSOLUTION) |
123 | { | 125 | { |
124 | -#ifdef CONSTRAINT_TEMPS | ||
125 | fd__constraint_data_reset(); | 126 | fd__constraint_data_reset(); |
126 | -#endif | ||
127 | 127 | ||
128 | return FD_NOSOLUTION; | 128 | return FD_NOSOLUTION; |
129 | } | 129 | } |
src/constraints.c
@@ -7,31 +7,46 @@ | @@ -7,31 +7,46 @@ | ||
7 | #include "variables.h" | 7 | #include "variables.h" |
8 | #include "constraints.h" | 8 | #include "constraints.h" |
9 | 9 | ||
10 | +#include "util.h" | ||
11 | + | ||
10 | #define MAX_CONSTRAINTS (512 * 512) | 12 | #define MAX_CONSTRAINTS (512 * 512) |
11 | 13 | ||
12 | int _fd_constraint_count = 0; | 14 | int _fd_constraint_count = 0; |
13 | fd_constraint _fd_constraints[MAX_CONSTRAINTS]; | 15 | fd_constraint _fd_constraints[MAX_CONSTRAINTS]; |
14 | 16 | ||
15 | -#ifdef CONSTRAINT_TEMPS | 17 | + |
18 | +#define CONSTRAINT_INITIALISATION(name, code) \ | ||
19 | + static void fd_ ## name ## _init(_fd_constraint_class data[]) \ | ||
20 | + { \ | ||
21 | + data[code].propagator2 = fd_ ## name ## _propagate2; \ | ||
22 | + data[code].filter = fd_ ## name ## _filter; \ | ||
23 | + } | ||
24 | + | ||
25 | +#define initialise_constraint(name) fd_ ## name ## _init(_fd_constraint_data) | ||
26 | + | ||
27 | + | ||
28 | +#ifdef CONSTRAINTS_HAVE_STATE | ||
16 | #define CSTR_DATA_VALID 0x01 | 29 | #define CSTR_DATA_VALID 0x01 |
17 | #define CSTR_ENTAILED 0x02 | 30 | #define CSTR_ENTAILED 0x02 |
18 | 31 | ||
19 | static __thread uint8_t constraint_state_info[MAX_CONSTRAINTS]; | 32 | static __thread uint8_t constraint_state_info[MAX_CONSTRAINTS]; |
33 | +# ifdef CONSTRAINT_TEMPS | ||
20 | static __thread void *constraint_memory[MAX_CONSTRAINTS]; | 34 | static __thread void *constraint_memory[MAX_CONSTRAINTS]; |
21 | -#endif | 35 | +# endif |
36 | +#endif /* CONSTRAINTS_HAVE_STATE */ | ||
22 | 37 | ||
23 | /* generic functions */ | 38 | /* generic functions */ |
24 | 39 | ||
25 | -fd_constraint _fd_constraint_new(int nvariables, int nconstants) | 40 | +fd_constraint fd__constraint_new(int nvariables, int nconstants) |
26 | { | 41 | { |
27 | fd_constraint c; | 42 | fd_constraint c; |
28 | 43 | ||
29 | if (_fd_constraint_count == MAX_CONSTRAINTS) | 44 | if (_fd_constraint_count == MAX_CONSTRAINTS) |
30 | - _fd_fatal("too many constraints, increase MAX_CONSTRAINTS"); | 45 | + fd__fatal("too many constraints, increase MAX_CONSTRAINTS"); |
31 | 46 | ||
32 | if (c = malloc(sizeof(struct fd_constraint))) | 47 | if (c = malloc(sizeof(struct fd_constraint))) |
33 | { | 48 | { |
34 | -#ifdef CONSTRAINT_TEMPS | 49 | +#if defined(CONSTRAINT_TEMPS) || !defined(DISABLE_ENTAILED) |
35 | c->index = _fd_constraint_count; | 50 | c->index = _fd_constraint_count; |
36 | #endif | 51 | #endif |
37 | c->variables = calloc(nvariables, sizeof(C_VAR_T)); // XXX: check for NULL | 52 | c->variables = calloc(nvariables, sizeof(C_VAR_T)); // XXX: check for NULL |
@@ -41,12 +56,7 @@ fd_constraint _fd_constraint_new(int nvariables, int nconstants) | @@ -41,12 +56,7 @@ fd_constraint _fd_constraint_new(int nvariables, int nconstants) | ||
41 | else | 56 | else |
42 | c->constants = 0; | 57 | c->constants = 0; |
43 | c->nconstants = nconstants; | 58 | c->nconstants = nconstants; |
44 | -#ifdef CONSTRAINT_CLASS | ||
45 | c->kind = -1; // XXX | 59 | c->kind = -1; // XXX |
46 | -#else /* CONSTRAINT_CLASS */ | ||
47 | - c->propagator2 = _fd_undefined; | ||
48 | - c->propagator = 0; | ||
49 | -#endif /* CONSTRAINT_CLASS */ | ||
50 | 60 | ||
51 | _fd_constraints[_fd_constraint_count++] = c; | 61 | _fd_constraints[_fd_constraint_count++] = c; |
52 | } | 62 | } |
@@ -56,7 +66,7 @@ fd_constraint _fd_constraint_new(int nvariables, int nconstants) | @@ -56,7 +66,7 @@ fd_constraint _fd_constraint_new(int nvariables, int nconstants) | ||
56 | 66 | ||
57 | int _fd_undefined() | 67 | int _fd_undefined() |
58 | { | 68 | { |
59 | - _fd_fatal("called an undefined function"); | 69 | + fd__fatal("called an undefined function"); |
60 | } | 70 | } |
61 | 71 | ||
62 | #ifdef DISTRIBUTED_SOLVER | 72 | #ifdef DISTRIBUTED_SOLVER |
@@ -77,9 +87,17 @@ void _fd_import_constraints(fd_int variables[]) | @@ -77,9 +87,17 @@ void _fd_import_constraints(fd_int variables[]) | ||
77 | #endif /* DISTRIBUTED_SOLVER */ | 87 | #endif /* DISTRIBUTED_SOLVER */ |
78 | 88 | ||
79 | 89 | ||
80 | -#ifdef CONSTRAINT_TEMPS | 90 | +#ifdef CONSTRAINTS_HAVE_STATE |
81 | #include <string.h> | 91 | #include <string.h> |
82 | 92 | ||
93 | +void fd__constraint_data_reset(void) | ||
94 | +{ | ||
95 | + memset(constraint_state_info, 0, | ||
96 | + _fd_constraint_count * sizeof(*constraint_state_info)); | ||
97 | +} | ||
98 | +#endif /* CONSTRAINTS_HAVE_STATE */ | ||
99 | + | ||
100 | +#ifdef CONSTRAINT_TEMPS | ||
83 | int fd__constraint_data_valid(fd_constraint constraint) | 101 | int fd__constraint_data_valid(fd_constraint constraint) |
84 | { | 102 | { |
85 | return constraint_state_info[constraint->index] & CSTR_DATA_VALID; | 103 | return constraint_state_info[constraint->index] & CSTR_DATA_VALID; |
@@ -90,6 +108,16 @@ void fd__constraint_remember(fd_constraint constraint) | @@ -90,6 +108,16 @@ void fd__constraint_remember(fd_constraint constraint) | ||
90 | constraint_state_info[constraint->index] |= CSTR_DATA_VALID; | 108 | constraint_state_info[constraint->index] |= CSTR_DATA_VALID; |
91 | } | 109 | } |
92 | 110 | ||
111 | +void fd__constraint_free_memory(void) | ||
112 | +{ | ||
113 | + int i; | ||
114 | + | ||
115 | + for (i = 0; i < _fd_constraint_count; ++i) | ||
116 | + if (constraint_memory[i]) | ||
117 | + free(constraint_memory[i]); | ||
118 | +} | ||
119 | +#endif /* CONSTRAINT_TEMPS */ | ||
120 | + | ||
93 | #ifndef DISABLE_ENTAILED | 121 | #ifndef DISABLE_ENTAILED |
94 | void fd__constraint_set_entailed(fd_constraint constraint) | 122 | void fd__constraint_set_entailed(fd_constraint constraint) |
95 | { | 123 | { |
@@ -100,27 +128,12 @@ int fd__constraint_entailed(fd_constraint constraint) | @@ -100,27 +128,12 @@ int fd__constraint_entailed(fd_constraint constraint) | ||
100 | { | 128 | { |
101 | return constraint_state_info[constraint->index] & CSTR_ENTAILED; | 129 | return constraint_state_info[constraint->index] & CSTR_ENTAILED; |
102 | } | 130 | } |
103 | -#else | 131 | +#else /* DISABLE_ENTAILED */ |
104 | #define fd__constraint_set_entailed(_) ((void) 0) | 132 | #define fd__constraint_set_entailed(_) ((void) 0) |
105 | -#endif | ||
106 | - | ||
107 | -void fd__constraint_data_reset() | ||
108 | -{ | ||
109 | - memset(constraint_state_info, 0, | ||
110 | - _fd_constraint_count * sizeof(*constraint_state_info)); | ||
111 | -} | 133 | +#endif /* DISABLE_ENTAILED */ |
112 | 134 | ||
113 | -void fd__constraint_free_memory() | ||
114 | -{ | ||
115 | - int i; | ||
116 | 135 | ||
117 | - for (i = 0; i < _fd_constraint_count; ++i) | ||
118 | - if (constraint_memory[i]) | ||
119 | - free(constraint_memory[i]); | ||
120 | -} | ||
121 | -#else /* CONSTRAINT_TEMPS */ | ||
122 | -#define fd__constraint_set_entailed(_) ((void) 0) | ||
123 | -#endif /* CONSTRAINT_TEMPS */ | 136 | +/* Import the constraints' code. */ |
124 | 137 | ||
125 | #include <constraints/lt.c> | 138 | #include <constraints/lt.c> |
126 | #include <constraints/le.c> | 139 | #include <constraints/le.c> |
@@ -152,40 +165,45 @@ void fd__constraint_free_memory() | @@ -152,40 +165,45 @@ void fd__constraint_free_memory() | ||
152 | #include <constraints/poly-eq-k.c> | 165 | #include <constraints/poly-eq-k.c> |
153 | #include <constraints/poly-ne.c> | 166 | #include <constraints/poly-ne.c> |
154 | #include <constraints/poly-ne-k.c> | 167 | #include <constraints/poly-ne-k.c> |
168 | +#include <constraints/poly-le-k.c> | ||
155 | 169 | ||
156 | -#ifdef CONSTRAINT_CLASS | ||
157 | 170 | ||
158 | _fd_constraint_class _fd_constraint_data[FD_CONSTR_KINDS]; | 171 | _fd_constraint_class _fd_constraint_data[FD_CONSTR_KINDS]; |
159 | 172 | ||
160 | -_FD_CONSTRAINT_INITIALISATION(ne, FD_CONSTR_NE) | ||
161 | -_FD_CONSTRAINT_INITIALISATION(eq, FD_CONSTR_EQ) | ||
162 | -_FD_CONSTRAINT_INITIALISATION(lt, FD_CONSTR_LT) | ||
163 | -_FD_CONSTRAINT_INITIALISATION(le, FD_CONSTR_LE) | ||
164 | -_FD_CONSTRAINT_INITIALISATION(minus_ne, FD_CONSTR_MINUS_NE) | ||
165 | -_FD_CONSTRAINT_INITIALISATION(minus_eq, FD_CONSTR_MINUS_EQ) | ||
166 | -// _FD_CONSTRAINT_INITIALISATION(plus_gt, FD_CONSTR_PLUS_GT) | ||
167 | -_FD_CONSTRAINT_INITIALISATION(var_eq_minus, FD_CONSTR_VAR_EQ_MINUS) | ||
168 | -_FD_CONSTRAINT_INITIALISATION(all_different, FD_CONSTR_ALL_DIFFERENT) | ||
169 | -// _FD_CONSTRAINT_INITIALISATION(exactly_one, FD_CONSTR_EXACTLY_ONE) | ||
170 | -// _FD_CONSTRAINT_INITIALISATION(nogoods, FD_CONSTR_NOGOODS) | ||
171 | -_FD_CONSTRAINT_INITIALISATION(exactly, FD_CONSTR_EXACTLY) | ||
172 | -_FD_CONSTRAINT_INITIALISATION(exactly_var, FD_CONSTR_EXACTLY_VAR) | ||
173 | -_FD_CONSTRAINT_INITIALISATION(sum, FD_CONSTR_SUM) | ||
174 | -_FD_CONSTRAINT_INITIALISATION(var_eq_times, FD_CONSTR_VAR_EQ_TIMES) | ||
175 | -_FD_CONSTRAINT_INITIALISATION(sum_prod, FD_CONSTR_SUM_PROD) | ||
176 | -_FD_CONSTRAINT_INITIALISATION(element, FD_CONSTR_ELEMENT) | ||
177 | -_FD_CONSTRAINT_INITIALISATION(knapsack2, FD_CONSTR_KNAPSACK2) | ||
178 | -_FD_CONSTRAINT_INITIALISATION(sum2, FD_CONSTR_SUM2) | ||
179 | -_FD_CONSTRAINT_INITIALISATION(min, FD_CONSTR_MIN) | ||
180 | -_FD_CONSTRAINT_INITIALISATION(max, FD_CONSTR_MAX) | ||
181 | -_FD_CONSTRAINT_INITIALISATION(poly_eq, FD_CONSTR_POLY_EQ) | ||
182 | -_FD_CONSTRAINT_INITIALISATION(element_var, FD_CONSTR_ELEMENT_VAR) | ||
183 | -_FD_CONSTRAINT_INITIALISATION(exactly_vars, FD_CONSTR_EXACTLY_VARS) | ||
184 | -_FD_CONSTRAINT_INITIALISATION(poly_eq_k, FD_CONSTR_POLY_EQ_K) | ||
185 | -_FD_CONSTRAINT_INITIALISATION(poly_ne, FD_CONSTR_POLY_NE) | ||
186 | -_FD_CONSTRAINT_INITIALISATION(poly_ne_k, FD_CONSTR_POLY_NE_K) | ||
187 | - | ||
188 | -void _fd_init_constraints() | 173 | + |
174 | +/* Define the constraints' initialisation functions. */ | ||
175 | + | ||
176 | +CONSTRAINT_INITIALISATION(ne, FD_CONSTR_NE) | ||
177 | +CONSTRAINT_INITIALISATION(eq, FD_CONSTR_EQ) | ||
178 | +CONSTRAINT_INITIALISATION(lt, FD_CONSTR_LT) | ||
179 | +CONSTRAINT_INITIALISATION(le, FD_CONSTR_LE) | ||
180 | +CONSTRAINT_INITIALISATION(minus_ne, FD_CONSTR_MINUS_NE) | ||
181 | +CONSTRAINT_INITIALISATION(minus_eq, FD_CONSTR_MINUS_EQ) | ||
182 | +// CONSTRAINT_INITIALISATION(plus_gt, FD_CONSTR_PLUS_GT) | ||
183 | +CONSTRAINT_INITIALISATION(var_eq_minus, FD_CONSTR_VAR_EQ_MINUS) | ||
184 | +CONSTRAINT_INITIALISATION(all_different, FD_CONSTR_ALL_DIFFERENT) | ||
185 | +// CONSTRAINT_INITIALISATION(exactly_one, FD_CONSTR_EXACTLY_ONE) | ||
186 | +// CONSTRAINT_INITIALISATION(nogoods, FD_CONSTR_NOGOODS) | ||
187 | +CONSTRAINT_INITIALISATION(exactly, FD_CONSTR_EXACTLY) | ||
188 | +CONSTRAINT_INITIALISATION(exactly_var, FD_CONSTR_EXACTLY_VAR) | ||
189 | +CONSTRAINT_INITIALISATION(sum, FD_CONSTR_SUM) | ||
190 | +CONSTRAINT_INITIALISATION(var_eq_times, FD_CONSTR_VAR_EQ_TIMES) | ||
191 | +CONSTRAINT_INITIALISATION(sum_prod, FD_CONSTR_SUM_PROD) | ||
192 | +CONSTRAINT_INITIALISATION(element, FD_CONSTR_ELEMENT) | ||
193 | +CONSTRAINT_INITIALISATION(knapsack2, FD_CONSTR_KNAPSACK2) | ||
194 | +CONSTRAINT_INITIALISATION(sum2, FD_CONSTR_SUM2) | ||
195 | +CONSTRAINT_INITIALISATION(min, FD_CONSTR_MIN) | ||
196 | +CONSTRAINT_INITIALISATION(max, FD_CONSTR_MAX) | ||
197 | +CONSTRAINT_INITIALISATION(poly_eq, FD_CONSTR_POLY_EQ) | ||
198 | +CONSTRAINT_INITIALISATION(element_var, FD_CONSTR_ELEMENT_VAR) | ||
199 | +CONSTRAINT_INITIALISATION(exactly_vars, FD_CONSTR_EXACTLY_VARS) | ||
200 | +CONSTRAINT_INITIALISATION(poly_eq_k, FD_CONSTR_POLY_EQ_K) | ||
201 | +CONSTRAINT_INITIALISATION(poly_ne, FD_CONSTR_POLY_NE) | ||
202 | +CONSTRAINT_INITIALISATION(poly_ne_k, FD_CONSTR_POLY_NE_K) | ||
203 | +CONSTRAINT_INITIALISATION(poly_le_k, FD_CONSTR_POLY_LE_K) | ||
204 | + | ||
205 | +/* Initialises the constraints. */ | ||
206 | +void fd__init_constraints() | ||
189 | { | 207 | { |
190 | static int done = 0; | 208 | static int done = 0; |
191 | 209 | ||
@@ -194,35 +212,34 @@ void _fd_init_constraints() | @@ -194,35 +212,34 @@ void _fd_init_constraints() | ||
194 | 212 | ||
195 | memset(_fd_constraint_data, 0, sizeof(_fd_constraint_data)); // XXX? | 213 | memset(_fd_constraint_data, 0, sizeof(_fd_constraint_data)); // XXX? |
196 | 214 | ||
197 | - _fd_init_constraint(ne); | ||
198 | - _fd_init_constraint(eq); | ||
199 | - _fd_init_constraint(lt); | ||
200 | - _fd_init_constraint(le); | ||
201 | - _fd_init_constraint(minus_ne); | ||
202 | - _fd_init_constraint(minus_eq); | ||
203 | -// _fd_init_constraint(plus_gt); | ||
204 | - _fd_init_constraint(var_eq_minus); | ||
205 | - _fd_init_constraint(all_different); | ||
206 | -// _fd_init_constraint(exactly_one); | ||
207 | -// _fd_init_constraint(nogoods); | ||
208 | - _fd_init_constraint(exactly); | ||
209 | - _fd_init_constraint(exactly_var); | ||
210 | - _fd_init_constraint(sum); | ||
211 | - _fd_init_constraint(var_eq_times); | ||
212 | - _fd_init_constraint(sum_prod); | ||
213 | - _fd_init_constraint(element); | ||
214 | - _fd_init_constraint(knapsack2); | ||
215 | - _fd_init_constraint(sum2); | ||
216 | - _fd_init_constraint(min); | ||
217 | - _fd_init_constraint(max); | ||
218 | - _fd_init_constraint(poly_eq); | ||
219 | - _fd_init_constraint(element_var); | ||
220 | - _fd_init_constraint(exactly_vars); | ||
221 | - _fd_init_constraint(poly_eq_k); | ||
222 | - _fd_init_constraint(poly_ne); | ||
223 | - _fd_init_constraint(poly_ne_k); | 215 | + initialise_constraint(ne); |
216 | + initialise_constraint(eq); | ||
217 | + initialise_constraint(lt); | ||
218 | + initialise_constraint(le); | ||
219 | + initialise_constraint(minus_ne); | ||
220 | + initialise_constraint(minus_eq); | ||
221 | +// initialise_constraint(plus_gt); | ||
222 | + initialise_constraint(var_eq_minus); | ||
223 | + initialise_constraint(all_different); | ||
224 | +// initialise_constraint(exactly_one); | ||
225 | +// initialise_constraint(nogoods); | ||
226 | + initialise_constraint(exactly); | ||
227 | + initialise_constraint(exactly_var); | ||
228 | + initialise_constraint(sum); | ||
229 | + initialise_constraint(var_eq_times); | ||
230 | + initialise_constraint(sum_prod); | ||
231 | + initialise_constraint(element); | ||
232 | + initialise_constraint(knapsack2); | ||
233 | + initialise_constraint(sum2); | ||
234 | + initialise_constraint(min); | ||
235 | + initialise_constraint(max); | ||
236 | + initialise_constraint(poly_eq); | ||
237 | + initialise_constraint(element_var); | ||
238 | + initialise_constraint(exactly_vars); | ||
239 | + initialise_constraint(poly_eq_k); | ||
240 | + initialise_constraint(poly_ne); | ||
241 | + initialise_constraint(poly_ne_k); | ||
242 | + initialise_constraint(poly_le_k); | ||
224 | 243 | ||
225 | done = 1; | 244 | done = 1; |
226 | } | 245 | } |
227 | - | ||
228 | -#endif /* CONSTRAINT_CLASS */ |
src/constraints.h
@@ -4,8 +4,6 @@ extern fd_constraint _fd_constraints[]; | @@ -4,8 +4,6 @@ extern fd_constraint _fd_constraints[]; | ||
4 | 4 | ||
5 | #define CONSTRAINT(v,c) _fd_constraints[(v)->constraints[c]] | 5 | #define CONSTRAINT(v,c) _fd_constraints[(v)->constraints[c]] |
6 | 6 | ||
7 | -#ifdef CONSTRAINT_CLASS | ||
8 | - | ||
9 | typedef enum { | 7 | typedef enum { |
10 | FD_CONSTR_NE = 0, | 8 | FD_CONSTR_NE = 0, |
11 | FD_CONSTR_EQ, | 9 | FD_CONSTR_EQ, |
@@ -36,37 +34,42 @@ typedef enum { | @@ -36,37 +34,42 @@ typedef enum { | ||
36 | FD_CONSTR_POLY_EQ_K, | 34 | FD_CONSTR_POLY_EQ_K, |
37 | FD_CONSTR_POLY_NE, | 35 | FD_CONSTR_POLY_NE, |
38 | FD_CONSTR_POLY_NE_K, | 36 | FD_CONSTR_POLY_NE_K, |
37 | + FD_CONSTR_POLY_LE_K, | ||
39 | FD_CONSTR_KINDS // number of kinds of constraints | 38 | FD_CONSTR_KINDS // number of kinds of constraints |
40 | } _fd_constraint_kind; | 39 | } _fd_constraint_kind; |
41 | 40 | ||
42 | typedef struct _fd_constraint_class { | 41 | typedef struct _fd_constraint_class { |
43 | int (*propagator2)(fd_constraint, fd_int); | 42 | int (*propagator2)(fd_constraint, fd_int); |
43 | + // propagates changes in a variable's | ||
44 | + // domain; 2nd argument is the variable | ||
45 | + // against which to revise the domains of | ||
46 | + // the other variables in the constraint; | ||
47 | + // returns FD_NOSOLUTION if some domain | ||
48 | + // becomes empty, and FD_OK otherwise | ||
44 | int (*filter)(fd_constraint); | 49 | int (*filter)(fd_constraint); |
50 | + // performs an initial filtering of the | ||
51 | + // domains of the constraint variables | ||
45 | } _fd_constraint_class; | 52 | } _fd_constraint_class; |
46 | 53 | ||
47 | -extern _fd_constraint_class _fd_constraint_data[FD_CONSTR_KINDS]; | ||
48 | - | ||
49 | - | ||
50 | -#define _FD_CONSTRAINT_INITIALISATION(name, code) \ | ||
51 | - static void _fd_ ## name ## _init(_fd_constraint_class data[]) \ | ||
52 | - { \ | ||
53 | - data[code].propagator2 = fd_ ## name ## _propagate2; \ | ||
54 | - data[code].filter = fd_ ## name ## _filter; \ | ||
55 | - } | ||
56 | - | ||
57 | -#define _fd_init_constraint(name) _fd_ ## name ## _init(_fd_constraint_data) | 54 | +extern _fd_constraint_class _fd_constraint_data[]; |
58 | 55 | ||
59 | #define _fd_propagate(c,v) (_fd_constraint_data[(c)->kind].propagator2(c, v)) | 56 | #define _fd_propagate(c,v) (_fd_constraint_data[(c)->kind].propagator2(c, v)) |
60 | #define _fd_filter(c) (_fd_constraint_data[(c)->kind].filter(c)) | 57 | #define _fd_filter(c) (_fd_constraint_data[(c)->kind].filter(c)) |
61 | 58 | ||
62 | -#else /* CONSTRAINT_CLASS */ | 59 | +void fd__init_constraints(); |
63 | 60 | ||
64 | -#define _fd_propagate(c,v) ((c)->propagator2(c, v)) | ||
65 | -#define _fd_filter(c) ((c)->filter(c)) | ||
66 | 61 | ||
67 | -#endif /* CONSTRAINT_CLASS */ | 62 | +#if defined(CONSTRAINT_TEMPS) || !defined(DISABLE_ENTAILED) |
63 | +#define CONSTRAINTS_HAVE_STATE 1 | ||
64 | +#endif | ||
65 | + | ||
66 | +#ifdef CONSTRAINTS_HAVE_STATE | ||
67 | +void fd__constraint_data_reset(void); | ||
68 | +#else | ||
69 | +#define fd__constraint_data_reset() ((void) 0) | ||
70 | +#endif | ||
68 | 71 | ||
69 | -#if defined(CONSTRAINT_TEMPS) && !defined(DISABLE_ENTAILED) | 72 | +#ifndef DISABLE_ENTAILED |
70 | int fd__constraint_entailed(fd_constraint); | 73 | int fd__constraint_entailed(fd_constraint); |
71 | #else | 74 | #else |
72 | #define fd__constraint_entailed(_) 0 | 75 | #define fd__constraint_entailed(_) 0 |
src/constraints/all-different.c
@@ -128,7 +128,7 @@ static int fd_all_different_propagate(fd_constraint this, fd_int revise) | @@ -128,7 +128,7 @@ static int fd_all_different_propagate(fd_constraint this, fd_int revise) | ||
128 | #if defined(USE_ENTAILED) && 0 | 128 | #if defined(USE_ENTAILED) && 0 |
129 | // XXX: hampers performance when not optimised | 129 | // XXX: hampers performance when not optimised |
130 | if (set == this->nvariables - 1) | 130 | if (set == this->nvariables - 1) |
131 | - _fd_constraint_set_entailed(this); | 131 | + fd__constraint_set_entailed(this); |
132 | #endif | 132 | #endif |
133 | 133 | ||
134 | if (changed) | 134 | if (changed) |
@@ -148,18 +148,14 @@ fd_constraint fd_all_different(fd_int *variables, int nvariables) | @@ -148,18 +148,14 @@ fd_constraint fd_all_different(fd_int *variables, int nvariables) | ||
148 | if (nvariables == 2) | 148 | if (nvariables == 2) |
149 | return fd_ne(variables[0], variables[1]); | 149 | return fd_ne(variables[0], variables[1]); |
150 | 150 | ||
151 | - c = _fd_constraint_new(nvariables, 0); | 151 | + c = fd__constraint_new(nvariables, 0); |
152 | 152 | ||
153 | if (c) | 153 | if (c) |
154 | { | 154 | { |
155 | for (i = 0; i < nvariables; ++i) | 155 | for (i = 0; i < nvariables; ++i) |
156 | c->variables[i] = FD_INT2C_VAR(variables[i]); | 156 | c->variables[i] = FD_INT2C_VAR(variables[i]); |
157 | -#ifdef CONSTRAINT_CLASS | 157 | + |
158 | c->kind = FD_CONSTR_ALL_DIFFERENT; | 158 | c->kind = FD_CONSTR_ALL_DIFFERENT; |
159 | -#else /* CONSTRAINT_CLASS */ | ||
160 | - c->propagator2 = fd_all_different_propagate2; | ||
161 | - c->propagator = fd_all_different_propagate; | ||
162 | -#endif /* CONSTRAINT_CLASS */ | ||
163 | 159 | ||
164 | for (i = 0; i < nvariables; ++i) | 160 | for (i = 0; i < nvariables; ++i) |
165 | _fd_var_add_constraint(VAR(c, i), c); | 161 | _fd_var_add_constraint(VAR(c, i), c); |
src/constraints/element-var.c
@@ -143,7 +143,7 @@ static int fd_element_var_propagate2(fd_constraint this, fd_int culprit) | @@ -143,7 +143,7 @@ static int fd_element_var_propagate2(fd_constraint this, fd_int culprit) | ||
143 | fd_constraint fd_element_var(fd_int *variables, int nvariables, fd_int index, | 143 | fd_constraint fd_element_var(fd_int *variables, int nvariables, fd_int index, |
144 | fd_int value) | 144 | fd_int value) |
145 | { | 145 | { |
146 | - fd_constraint c = _fd_constraint_new(nvariables + 2, 0); | 146 | + fd_constraint c = fd__constraint_new(nvariables + 2, 0); |
147 | int i; | 147 | int i; |
148 | 148 | ||
149 | // XXX: add a constraint 0 <= INDEX < nvariables | 149 | // XXX: add a constraint 0 <= INDEX < nvariables |
@@ -154,11 +154,8 @@ fd_constraint fd_element_var(fd_int *variables, int nvariables, fd_int index, | @@ -154,11 +154,8 @@ fd_constraint fd_element_var(fd_int *variables, int nvariables, fd_int index, | ||
154 | c->variables[i] = FD_INT2C_VAR(variables[i]); | 154 | c->variables[i] = FD_INT2C_VAR(variables[i]); |
155 | c->variables[nvariables] = FD_INT2C_VAR(index); | 155 | c->variables[nvariables] = FD_INT2C_VAR(index); |
156 | c->variables[nvariables + 1] = FD_INT2C_VAR(value); | 156 | c->variables[nvariables + 1] = FD_INT2C_VAR(value); |
157 | -#ifdef CONSTRAINT_CLASS | 157 | + |
158 | c->kind = FD_CONSTR_ELEMENT_VAR; | 158 | c->kind = FD_CONSTR_ELEMENT_VAR; |
159 | -#else /* CONSTRAINT_CLASS */ | ||
160 | - c->propagator2 = fd_element_var_propagate2; | ||
161 | -#endif /* CONSTRAINT_CLASS */ | ||
162 | 159 | ||
163 | for (i = 0; i < c->nvariables; ++i) | 160 | for (i = 0; i < c->nvariables; ++i) |
164 | _fd_var_add_constraint(VAR(c, i), c); | 161 | _fd_var_add_constraint(VAR(c, i), c); |
src/constraints/element.c
@@ -102,7 +102,7 @@ static int fd_element_propagate2(fd_constraint this, fd_int culprit) | @@ -102,7 +102,7 @@ static int fd_element_propagate2(fd_constraint this, fd_int culprit) | ||
102 | 102 | ||
103 | fd_constraint fd_element(fd_int *variables, int nvariables, fd_int index, int k) | 103 | fd_constraint fd_element(fd_int *variables, int nvariables, fd_int index, int k) |
104 | { | 104 | { |
105 | - fd_constraint c = _fd_constraint_new(nvariables + 1, 1); | 105 | + fd_constraint c = fd__constraint_new(nvariables + 1, 1); |
106 | int i; | 106 | int i; |
107 | 107 | ||
108 | // XXX: add a constraint 0 <= INDEX < nvariables | 108 | // XXX: add a constraint 0 <= INDEX < nvariables |
@@ -113,11 +113,8 @@ fd_constraint fd_element(fd_int *variables, int nvariables, fd_int index, int k) | @@ -113,11 +113,8 @@ fd_constraint fd_element(fd_int *variables, int nvariables, fd_int index, int k) | ||
113 | c->variables[i] = FD_INT2C_VAR(variables[i]); | 113 | c->variables[i] = FD_INT2C_VAR(variables[i]); |
114 | c->variables[nvariables] = FD_INT2C_VAR(index); | 114 | c->variables[nvariables] = FD_INT2C_VAR(index); |
115 | c->constants[0] = k; | 115 | c->constants[0] = k; |
116 | -#ifdef CONSTRAINT_CLASS | 116 | + |
117 | c->kind = FD_CONSTR_ELEMENT; | 117 | c->kind = FD_CONSTR_ELEMENT; |
118 | -#else /* CONSTRAINT_CLASS */ | ||
119 | - c->propagator2 = fd_element_propagate2; | ||
120 | -#endif /* CONSTRAINT_CLASS */ | ||
121 | 118 | ||
122 | for (i = 0; i < c->nvariables; ++i) | 119 | for (i = 0; i < c->nvariables; ++i) |
123 | _fd_var_add_constraint(VAR(c, i), c); | 120 | _fd_var_add_constraint(VAR(c, i), c); |
src/constraints/eq.c
@@ -62,17 +62,13 @@ int fd_eq_propagate(fd_constraint this, fd_int revise) | @@ -62,17 +62,13 @@ int fd_eq_propagate(fd_constraint this, fd_int revise) | ||
62 | 62 | ||
63 | fd_constraint fd_eq(fd_int x, fd_int y) | 63 | fd_constraint fd_eq(fd_int x, fd_int y) |
64 | { | 64 | { |
65 | - fd_constraint c = _fd_constraint_new(2, 0); | 65 | + fd_constraint c = fd__constraint_new(2, 0); |
66 | 66 | ||
67 | if (c) | 67 | if (c) |
68 | { | 68 | { |
69 | c->variables[0] = FD_INT2C_VAR(x); c->variables[1] = FD_INT2C_VAR(y); | 69 | c->variables[0] = FD_INT2C_VAR(x); c->variables[1] = FD_INT2C_VAR(y); |
70 | -#ifdef CONSTRAINT_CLASS | 70 | + |
71 | c->kind = FD_CONSTR_EQ; | 71 | c->kind = FD_CONSTR_EQ; |
72 | -#else /* CONSTRAINT_CLASS */ | ||
73 | - c->propagator2 = fd_eq_propagate2; | ||
74 | - c->propagator = fd_eq_propagate; | ||
75 | -#endif /* CONSTRAINT_CLASS */ | ||
76 | 72 | ||
77 | _fd_var_add_constraint(x, c); | 73 | _fd_var_add_constraint(x, c); |
78 | _fd_var_add_constraint(y, c); | 74 | _fd_var_add_constraint(y, c); |
src/constraints/exactly-one.c
@@ -72,7 +72,7 @@ static int fd_exactly_one_propagate(fd_constraint this, fd_int revise) | @@ -72,7 +72,7 @@ static int fd_exactly_one_propagate(fd_constraint this, fd_int revise) | ||
72 | 72 | ||
73 | fd_constraint fd_exactly_one(fd_int *variables, int nvariables, int value) | 73 | fd_constraint fd_exactly_one(fd_int *variables, int nvariables, int value) |
74 | { | 74 | { |
75 | - fd_constraint c = _fd_constraint_new(nvariables, 1); | 75 | + fd_constraint c = fd__constraint_new(nvariables, 1); |
76 | int i; | 76 | int i; |
77 | 77 | ||
78 | if (c) | 78 | if (c) |
@@ -80,11 +80,8 @@ fd_constraint fd_exactly_one(fd_int *variables, int nvariables, int value) | @@ -80,11 +80,8 @@ fd_constraint fd_exactly_one(fd_int *variables, int nvariables, int value) | ||
80 | for (i = 0; i < nvariables; ++i) | 80 | for (i = 0; i < nvariables; ++i) |
81 | c->variables[i] = FD_INT2C_VAR(variables[i]); | 81 | c->variables[i] = FD_INT2C_VAR(variables[i]); |
82 | c->constants[0] = value; | 82 | c->constants[0] = value; |
83 | -#ifdef CONSTRAINT_CLASS | 83 | + |
84 | c->kind = FD_CONSTR_EXACTLY_ONE; | 84 | c->kind = FD_CONSTR_EXACTLY_ONE; |
85 | -#else /* CONSTRAINT_CLASS */ | ||
86 | - c->propagator = fd_exactly_one_propagate; | ||
87 | -#endif /* CONSTRAINT_CLASS */ | ||
88 | 85 | ||
89 | for (i = 0; i < nvariables; ++i) | 86 | for (i = 0; i < nvariables; ++i) |
90 | _fd_var_add_constraint(VAR(c, i), c); | 87 | _fd_var_add_constraint(VAR(c, i), c); |
src/constraints/exactly-var.c
@@ -159,7 +159,7 @@ static int fd_exactly_var_propagate2(fd_constraint this, fd_int culprit) | @@ -159,7 +159,7 @@ static int fd_exactly_var_propagate2(fd_constraint this, fd_int culprit) | ||
159 | 159 | ||
160 | fd_constraint fd_exactly_var(fd_int *variables, int nvariables, fd_int card, int k) | 160 | fd_constraint fd_exactly_var(fd_int *variables, int nvariables, fd_int card, int k) |
161 | { | 161 | { |
162 | - fd_constraint c = _fd_constraint_new(nvariables + 1, 1); | 162 | + fd_constraint c = fd__constraint_new(nvariables + 1, 1); |
163 | int i; | 163 | int i; |
164 | 164 | ||
165 | if (c) | 165 | if (c) |
@@ -168,11 +168,8 @@ fd_constraint fd_exactly_var(fd_int *variables, int nvariables, fd_int card, int | @@ -168,11 +168,8 @@ fd_constraint fd_exactly_var(fd_int *variables, int nvariables, fd_int card, int | ||
168 | c->variables[i] = FD_INT2C_VAR(variables[i]); | 168 | c->variables[i] = FD_INT2C_VAR(variables[i]); |
169 | c->variables[nvariables] = FD_INT2C_VAR(card); | 169 | c->variables[nvariables] = FD_INT2C_VAR(card); |
170 | c->constants[0] = k; | 170 | c->constants[0] = k; |
171 | -#ifdef CONSTRAINT_CLASS | 171 | + |
172 | c->kind = FD_CONSTR_EXACTLY_VAR; | 172 | c->kind = FD_CONSTR_EXACTLY_VAR; |
173 | -#else /* CONSTRAINT_CLASS */ | ||
174 | - c->propagator2 = fd_exactly_var_propagate2; | ||
175 | -#endif /* CONSTRAINT_CLASS */ | ||
176 | 173 | ||
177 | for (i = 0; i <= nvariables; ++i) | 174 | for (i = 0; i <= nvariables; ++i) |
178 | _fd_var_add_constraint(VAR(c, i), c); | 175 | _fd_var_add_constraint(VAR(c, i), c); |
src/constraints/exactly-vars.c
@@ -166,7 +166,7 @@ static int fd_exactly_vars_propagate2(fd_constraint this, fd_int culprit) | @@ -166,7 +166,7 @@ static int fd_exactly_vars_propagate2(fd_constraint this, fd_int culprit) | ||
166 | 166 | ||
167 | fd_constraint fd_exactly_vars(fd_int *variables, int nvariables, fd_int card, fd_int k) | 167 | fd_constraint fd_exactly_vars(fd_int *variables, int nvariables, fd_int card, fd_int k) |
168 | { | 168 | { |
169 | - fd_constraint c = _fd_constraint_new(nvariables + 2, 0); | 169 | + fd_constraint c = fd__constraint_new(nvariables + 2, 0); |
170 | int i; | 170 | int i; |
171 | 171 | ||
172 | if (c) | 172 | if (c) |
@@ -175,11 +175,8 @@ fd_constraint fd_exactly_vars(fd_int *variables, int nvariables, fd_int card, fd | @@ -175,11 +175,8 @@ fd_constraint fd_exactly_vars(fd_int *variables, int nvariables, fd_int card, fd | ||
175 | c->variables[i] = FD_INT2C_VAR(variables[i]); | 175 | c->variables[i] = FD_INT2C_VAR(variables[i]); |
176 | c->variables[nvariables] = FD_INT2C_VAR(card); | 176 | c->variables[nvariables] = FD_INT2C_VAR(card); |
177 | c->variables[nvariables + 1] = FD_INT2C_VAR(k); | 177 | c->variables[nvariables + 1] = FD_INT2C_VAR(k); |
178 | -#ifdef CONSTRAINT_CLASS | 178 | + |
179 | c->kind = FD_CONSTR_EXACTLY_VARS; | 179 | c->kind = FD_CONSTR_EXACTLY_VARS; |
180 | -#else /* CONSTRAINT_CLASS */ | ||
181 | - c->propagator2 = fd_exactly_vars_propagate2; | ||
182 | -#endif /* CONSTRAINT_CLASS */ | ||
183 | 180 | ||
184 | for (i = 0; i < nvariables + 2; ++i) | 181 | for (i = 0; i < nvariables + 2; ++i) |
185 | _fd_var_add_constraint(VAR(c, i), c); | 182 | _fd_var_add_constraint(VAR(c, i), c); |
src/constraints/exactly.c
@@ -74,7 +74,7 @@ static int fd_exactly_propagate2(fd_constraint this, fd_int culprit) | @@ -74,7 +74,7 @@ static int fd_exactly_propagate2(fd_constraint this, fd_int culprit) | ||
74 | 74 | ||
75 | fd_constraint fd_exactly(fd_int *variables, int nvariables, int cardinal, int k) | 75 | fd_constraint fd_exactly(fd_int *variables, int nvariables, int cardinal, int k) |
76 | { | 76 | { |
77 | - fd_constraint c = _fd_constraint_new(nvariables, 2); | 77 | + fd_constraint c = fd__constraint_new(nvariables, 2); |
78 | int i; | 78 | int i; |
79 | 79 | ||
80 | if (c) | 80 | if (c) |
@@ -83,11 +83,8 @@ fd_constraint fd_exactly(fd_int *variables, int nvariables, int cardinal, int k) | @@ -83,11 +83,8 @@ fd_constraint fd_exactly(fd_int *variables, int nvariables, int cardinal, int k) | ||
83 | c->variables[i] = FD_INT2C_VAR(variables[i]); | 83 | c->variables[i] = FD_INT2C_VAR(variables[i]); |
84 | c->constants[0] = k; | 84 | c->constants[0] = k; |
85 | c->constants[1] = cardinal; | 85 | c->constants[1] = cardinal; |
86 | -#ifdef CONSTRAINT_CLASS | 86 | + |
87 | c->kind = FD_CONSTR_EXACTLY; | 87 | c->kind = FD_CONSTR_EXACTLY; |
88 | -#else /* CONSTRAINT_CLASS */ | ||
89 | - c->propagator2 = fd_exactly_propagate2; | ||
90 | -#endif /* CONSTRAINT_CLASS */ | ||
91 | 88 | ||
92 | for (i = 0; i < nvariables; ++i) | 89 | for (i = 0; i < nvariables; ++i) |
93 | _fd_var_add_constraint(VAR(c, i), c); | 90 | _fd_var_add_constraint(VAR(c, i), c); |
src/constraints/knapsack.c
@@ -105,7 +105,7 @@ static int fd_knapsack_propagate2(fd_constraint this, fd_int culprit) | @@ -105,7 +105,7 @@ static int fd_knapsack_propagate2(fd_constraint this, fd_int culprit) | ||
105 | 105 | ||
106 | fd_constraint fd_knapsack(fd_int variables[], int nvariables, fd_int limits) | 106 | fd_constraint fd_knapsack(fd_int variables[], int nvariables, fd_int limits) |
107 | { | 107 | { |
108 | - fd_constraint c = _fd_constraint_new(nvariables + 1, 0); | 108 | + fd_constraint c = fd__constraint_new(nvariables + 1, 0); |
109 | int i; | 109 | int i; |
110 | 110 | ||
111 | if (c) | 111 | if (c) |
@@ -113,11 +113,8 @@ fd_constraint fd_knapsack(fd_int variables[], int nvariables, fd_int limits) | @@ -113,11 +113,8 @@ fd_constraint fd_knapsack(fd_int variables[], int nvariables, fd_int limits) | ||
113 | for (i = 0; i < nvariables; ++i) | 113 | for (i = 0; i < nvariables; ++i) |
114 | c->variables[i] = FD_INT2C_VAR(variables[i]); | 114 | c->variables[i] = FD_INT2C_VAR(variables[i]); |
115 | c->variables[nvariables] = FD_INT2C_VAR(limits); | 115 | c->variables[nvariables] = FD_INT2C_VAR(limits); |
116 | -#ifdef CONSTRAINT_CLASS | 116 | + |
117 | c->kind = FD_CONSTR_KNAPSACK; | 117 | c->kind = FD_CONSTR_KNAPSACK; |
118 | -#else /* CONSTRAINT_CLASS */ | ||
119 | - c->propagator2 = fd_knapsack_propagate2; | ||
120 | -#endif /* CONSTRAINT_CLASS */ | ||
121 | 118 | ||
122 | for (i = 0; i < c->nvariables; ++i) | 119 | for (i = 0; i < c->nvariables; ++i) |
123 | _fd_var_add_constraint(VAR(c, i), c); | 120 | _fd_var_add_constraint(VAR(c, i), c); |
src/constraints/knapsack2.c
@@ -4,12 +4,12 @@ | @@ -4,12 +4,12 @@ | ||
4 | 4 | ||
5 | static int fd_knapsack2_filter(fd_constraint this) | 5 | static int fd_knapsack2_filter(fd_constraint this) |
6 | { | 6 | { |
7 | -#ifdef CONSTRAINT_TEMPS | ||
8 | int ub, lb; | 7 | int ub, lb; |
9 | int min, max; | 8 | int min, max; |
10 | int terms = (this->nvariables - 1) / 2; | 9 | int terms = (this->nvariables - 1) / 2; |
11 | int *mins, *maxs; // XXX: trouble possible if a variable appears repeated | 10 | int *mins, *maxs; // XXX: trouble possible if a variable appears repeated |
12 | int i; | 11 | int i; |
12 | +#ifdef CONSTRAINT_TEMPS | ||
13 | int *base; | 13 | int *base; |
14 | 14 | ||
15 | assert(!fd__constraint_data_valid(this)); | 15 | assert(!fd__constraint_data_valid(this)); |
@@ -21,6 +21,10 @@ static int fd_knapsack2_filter(fd_constraint this) | @@ -21,6 +21,10 @@ static int fd_knapsack2_filter(fd_constraint this) | ||
21 | 21 | ||
22 | mins = base + 4; | 22 | mins = base + 4; |
23 | maxs = mins + 2 * terms; | 23 | maxs = mins + 2 * terms; |
24 | +#else | ||
25 | + mins = alloca(2 * terms * sizeof(*mins)); | ||
26 | + maxs = alloca(2 * terms * sizeof(*maxs)); | ||
27 | +#endif | ||
24 | 28 | ||
25 | lb = _fd_var_min(VAR(this, this->nvariables - 1)); // lower bound | 29 | lb = _fd_var_min(VAR(this, this->nvariables - 1)); // lower bound |
26 | ub = _fd_var_max(VAR(this, this->nvariables - 1)); // upper bound | 30 | ub = _fd_var_max(VAR(this, this->nvariables - 1)); // upper bound |
@@ -115,6 +119,7 @@ static int fd_knapsack2_filter(fd_constraint this) | @@ -115,6 +119,7 @@ static int fd_knapsack2_filter(fd_constraint this) | ||
115 | (max < ub && _fd_var_del_gt(max, VAR(this, this->nvariables - 1)))) | 119 | (max < ub && _fd_var_del_gt(max, VAR(this, this->nvariables - 1)))) |
116 | _fd_revise_connected(this, VAR(this, this->nvariables - 1)); | 120 | _fd_revise_connected(this, VAR(this, this->nvariables - 1)); |
117 | 121 | ||
122 | +#ifdef CONSTRAINT_TEMPS | ||
118 | // save values | 123 | // save values |
119 | *base = lb; | 124 | *base = lb; |
120 | *(base + 1) = ub; | 125 | *(base + 1) = ub; |
@@ -122,120 +127,16 @@ static int fd_knapsack2_filter(fd_constraint this) | @@ -122,120 +127,16 @@ static int fd_knapsack2_filter(fd_constraint this) | ||
122 | *(base + 3) = max; | 127 | *(base + 3) = max; |
123 | 128 | ||
124 | fd__constraint_remember(this); | 129 | fd__constraint_remember(this); |
130 | +#endif | ||
125 | 131 | ||
126 | return FD_OK; | 132 | return FD_OK; |
127 | -#else /* CONSTRAINT_TEMPS */ | ||
128 | - int ub, lb; | ||
129 | - int min, max; | ||
130 | - int terms = (this->nvariables - 1) / 2; | ||
131 | - int *mins, *maxs; // XXX: trouble possible if a variable appears repeated | ||
132 | - int i; | ||
133 | - | ||
134 | - mins = alloca(2 * terms * sizeof(*mins)); | ||
135 | - maxs = alloca(2 * terms * sizeof(*maxs)); | ||
136 | - | ||
137 | - lb = _fd_var_min(VAR(this, this->nvariables - 1)); // lower bound | ||
138 | - ub = _fd_var_max(VAR(this, this->nvariables - 1)); // upper bound | ||
139 | - | ||
140 | - // sum the minima of the terms | ||
141 | - min = 0; | ||
142 | - | ||
143 | - for (i = 0; i < terms; ++i) | ||
144 | - { | ||
145 | - mins[i] = _fd_var_min(VAR(this, i)); | ||
146 | - mins[terms + i] = _fd_var_min(VAR(this, terms + i)); | ||
147 | - | ||
148 | - min += mins[i] * mins[terms + i]; | ||
149 | - | ||
150 | - if (min > ub) | ||
151 | - return FD_NOSOLUTION; | ||
152 | - } | ||
153 | - | ||
154 | - // sum the maxima of the terms | ||
155 | - max = 0; | ||
156 | - | ||
157 | - for (i = 0; i < terms; ++i) | ||
158 | - { | ||
159 | - maxs[i] = _fd_var_max(VAR(this, i)); | ||
160 | - maxs[terms + i] = _fd_var_max(VAR(this, terms + i)); | ||
161 | - | ||
162 | - max += maxs[i] * maxs[terms + i]; | ||
163 | - } | ||
164 | - | ||
165 | - if (max < lb) | ||
166 | - return FD_NOSOLUTION; | ||
167 | - | ||
168 | - // XXX: poor man's propagation | ||
169 | - if (min == ub) | ||
170 | - for (i = 0; i < terms; ++i) | ||
171 | - { | ||
172 | - int min_x = mins[i]; | ||
173 | - int min_y = mins[terms + i]; | ||
174 | - | ||
175 | - if (min_x != 0 || min_y != 0) | ||
176 | - { | ||
177 | - if (min_y != 0 && _fd_var_del_gt(min_x, VAR(this, i))) | ||
178 | - _fd_revise_connected(this, VAR(this, i)); | ||
179 | - | ||
180 | - if (min_x != 0 && _fd_var_del_gt(min_y, VAR(this, terms + i))) | ||
181 | - _fd_revise_connected(this, VAR(this, terms + i)); | ||
182 | - } | ||
183 | - } | ||
184 | - else if (max == lb) | ||
185 | - for (i = 0; i < terms; ++i) | ||
186 | - { | ||
187 | - int max_x = maxs[i]; | ||
188 | - int max_y = maxs[terms + i]; | ||
189 | - | ||
190 | - if (max_x != 0 && max_y != 0) | ||
191 | - { | ||
192 | - if (_fd_var_del_lt(max_x, VAR(this, i))) | ||
193 | - _fd_revise_connected(this, VAR(this, i)); | ||
194 | - | ||
195 | - if (_fd_var_del_lt(max_y, VAR(this, terms + i))) | ||
196 | - _fd_revise_connected(this, VAR(this, terms + i)); | ||
197 | - } | ||
198 | - } | ||
199 | - else if (max > ub) | ||
200 | - for (i = 0; i < terms; ++i) | ||
201 | - { | ||
202 | - int min_x = mins[i]; | ||
203 | - int max_x = maxs[i]; | ||
204 | - int min_y = mins[terms + i]; | ||
205 | - int max_y = maxs[terms + i]; | ||
206 | - | ||
207 | - if (min_x * (max_y - min_y) > ub - min) | ||
208 | - { | ||
209 | - max_y = (ub - min + min_x * min_y) / min_x; | ||
210 | - | ||
211 | - _fd_var_del_gt(max_y, VAR(this, terms + i)); | ||
212 | - | ||
213 | - _fd_revise_connected(this, VAR(this, terms + i)); | ||
214 | - } | ||
215 | - | ||
216 | - if ((max_x - min_x) * min_y > ub - min) | ||
217 | - { | ||
218 | - max_x = (ub - min + min_x * min_y) / min_y; | ||
219 | - | ||
220 | - _fd_var_del_gt(max_x, VAR(this, i)); | ||
221 | - | ||
222 | - _fd_revise_connected(this, VAR(this, i)); | ||
223 | - } | ||
224 | - } | ||
225 | - | ||
226 | - if ((min > lb && _fd_var_del_lt(min, VAR(this, this->nvariables - 1))) | | ||
227 | - (max < ub && _fd_var_del_gt(max, VAR(this, this->nvariables - 1)))) | ||
228 | - _fd_revise_connected(this, VAR(this, this->nvariables - 1)); | ||
229 | - | ||
230 | - return FD_OK; | ||
231 | -#endif /* CONSTRAINT_TEMPS */ | ||
232 | } | 133 | } |
233 | 134 | ||
234 | static int fd_knapsack2_propagate2(fd_constraint this, fd_int culprit) | 135 | static int fd_knapsack2_propagate2(fd_constraint this, fd_int culprit) |
235 | { | 136 | { |
236 | #ifdef CONSTRAINT_TEMPS | 137 | #ifdef CONSTRAINT_TEMPS |
237 | int ub, lb; | 138 | int ub, lb; |
238 | - unsigned int min, max; | 139 | + int min, max; |
239 | int terms = (this->nvariables - 1) / 2; | 140 | int terms = (this->nvariables - 1) / 2; |
240 | int *mins, *maxs; // XXX: trouble possible if a variable appears repeated | 141 | int *mins, *maxs; // XXX: trouble possible if a variable appears repeated |
241 | int i; | 142 | int i; |
@@ -379,7 +280,7 @@ static int fd_knapsack2_propagate2(fd_constraint this, fd_int culprit) | @@ -379,7 +280,7 @@ static int fd_knapsack2_propagate2(fd_constraint this, fd_int culprit) | ||
379 | 280 | ||
380 | fd_constraint fd_knapsack2(fd_int xs[], fd_int ys[], int nvariables, fd_int limits) | 281 | fd_constraint fd_knapsack2(fd_int xs[], fd_int ys[], int nvariables, fd_int limits) |
381 | { | 282 | { |
382 | - fd_constraint c = _fd_constraint_new(2 * nvariables + 1, 0); | 283 | + fd_constraint c = fd__constraint_new(2 * nvariables + 1, 0); |
383 | int i; | 284 | int i; |
384 | 285 | ||
385 | if (c) | 286 | if (c) |
@@ -389,11 +290,8 @@ fd_constraint fd_knapsack2(fd_int xs[], fd_int ys[], int nvariables, fd_int limi | @@ -389,11 +290,8 @@ fd_constraint fd_knapsack2(fd_int xs[], fd_int ys[], int nvariables, fd_int limi | ||
389 | for (; i < 2 * nvariables; ++i) | 290 | for (; i < 2 * nvariables; ++i) |
390 | c->variables[i] = FD_INT2C_VAR(ys[i - nvariables]); | 291 | c->variables[i] = FD_INT2C_VAR(ys[i - nvariables]); |
391 | c->variables[2 * nvariables] = FD_INT2C_VAR(limits); | 292 | c->variables[2 * nvariables] = FD_INT2C_VAR(limits); |
392 | -#ifdef CONSTRAINT_CLASS | 293 | + |
393 | c->kind = FD_CONSTR_KNAPSACK2; | 294 | c->kind = FD_CONSTR_KNAPSACK2; |
394 | -#else /* CONSTRAINT_CLASS */ | ||
395 | - c->propagator2 = fd_knapsack2_propagate2; | ||
396 | -#endif /* CONSTRAINT_CLASS */ | ||
397 | 295 | ||
398 | for (i = 0; i < c->nvariables; ++i) | 296 | for (i = 0; i < c->nvariables; ++i) |
399 | _fd_var_add_constraint(VAR(c, i), c); | 297 | _fd_var_add_constraint(VAR(c, i), c); |
src/constraints/le.c
1 | -/* X le Y */ | 1 | +/* x <= y */ |
2 | 2 | ||
3 | static int fd_le_filter(fd_constraint this) | 3 | static int fd_le_filter(fd_constraint this) |
4 | { | 4 | { |
@@ -7,12 +7,21 @@ static int fd_le_filter(fd_constraint this) | @@ -7,12 +7,21 @@ static int fd_le_filter(fd_constraint this) | ||
7 | x = VAR(this, 0); | 7 | x = VAR(this, 0); |
8 | y = VAR(this, 1); | 8 | y = VAR(this, 1); |
9 | 9 | ||
10 | +#ifndef DISABLE_ENTAILED | ||
11 | + if (_fd_var_max(x) <= _fd_var_min(y)) | ||
12 | + { | ||
13 | + fd__constraint_set_entailed(this); | ||
14 | + | ||
15 | + return FD_OK; | ||
16 | + } | ||
17 | +#endif | ||
18 | + | ||
10 | if (_fd_var_del_lt(_fd_var_min(x), y)) | 19 | if (_fd_var_del_lt(_fd_var_min(x), y)) |
11 | { | 20 | { |
12 | if (fd_domain_empty(y)) | 21 | if (fd_domain_empty(y)) |
13 | return FD_NOSOLUTION; | 22 | return FD_NOSOLUTION; |
14 | 23 | ||
15 | - _fd_revise_connected(NULL, y); | 24 | + _fd_revise_connected(this, y); |
16 | } | 25 | } |
17 | 26 | ||
18 | if (_fd_var_del_gt(_fd_var_max(y), x)) | 27 | if (_fd_var_del_gt(_fd_var_max(y), x)) |
@@ -20,10 +29,10 @@ static int fd_le_filter(fd_constraint this) | @@ -20,10 +29,10 @@ static int fd_le_filter(fd_constraint this) | ||
20 | if (fd_domain_empty(x)) | 29 | if (fd_domain_empty(x)) |
21 | return FD_NOSOLUTION; | 30 | return FD_NOSOLUTION; |
22 | 31 | ||
23 | - _fd_revise_connected(NULL, x); | 32 | + _fd_revise_connected(this, x); |
24 | } | 33 | } |
25 | 34 | ||
26 | -#if CONSTRAINT_TEMPS > 3 | 35 | +#ifndef DISABLE_ENTAILED |
27 | if (_fd_var_max(x) <= _fd_var_min(y)) | 36 | if (_fd_var_max(x) <= _fd_var_min(y)) |
28 | fd__constraint_set_entailed(this); | 37 | fd__constraint_set_entailed(this); |
29 | #endif | 38 | #endif |
@@ -31,39 +40,63 @@ static int fd_le_filter(fd_constraint this) | @@ -31,39 +40,63 @@ static int fd_le_filter(fd_constraint this) | ||
31 | return FD_OK; | 40 | return FD_OK; |
32 | } | 41 | } |
33 | 42 | ||
34 | -int fd_le_propagate2(fd_constraint this, fd_int culprit) | 43 | +static int fd_le_propagate2(fd_constraint this, fd_int culprit) |
35 | { | 44 | { |
45 | + fd_int x, y; | ||
46 | + int vmax, vmin; | ||
36 | fd_int revise; | 47 | fd_int revise; |
37 | int changed = 0; | 48 | int changed = 0; |
38 | 49 | ||
39 | - if (culprit == VAR(this, 0)) | 50 | + x = VAR(this, 0); |
51 | + y = VAR(this, 1); | ||
52 | + | ||
53 | +#ifndef DISABLE_ENTAILED | ||
54 | + vmax = _fd_var_max(x); | ||
55 | + vmin = _fd_var_min(y); | ||
56 | + | ||
57 | + if (vmax <= vmin) | ||
40 | { | 58 | { |
41 | - revise = VAR(this, 1); | 59 | + fd__constraint_set_entailed(this); |
42 | 60 | ||
43 | - changed = _fd_var_del_lt(_fd_var_min(culprit), revise); | 61 | + return FD_OK; |
44 | } | 62 | } |
45 | - else | 63 | +#endif |
64 | + | ||
65 | + if (culprit == x) | ||
46 | { | 66 | { |
47 | - revise = VAR(this, 0); | 67 | + revise = y; |
48 | 68 | ||
49 | - changed = _fd_var_del_gt(_fd_var_max(culprit), revise); | 69 | + vmin = _fd_var_min(x); |
70 | + | ||
71 | + changed = _fd_var_del_lt(vmin, y); | ||
50 | } | 72 | } |
73 | + else | ||
74 | + { | ||
75 | + revise = x; | ||
51 | 76 | ||
52 | - if (changed && fd_domain_empty(revise)) | ||
53 | - return FD_NOSOLUTION; | 77 | + vmax = _fd_var_max(y); |
54 | 78 | ||
55 | -#if CONSTRAINT_TEMPS > 3 | ||
56 | - if (_fd_var_max(VAR(this, 0)) <= _fd_var_min(VAR(this, 1))) | ||
57 | - fd__constraint_set_entailed(this); | ||
58 | -#endif | 79 | + changed = _fd_var_del_gt(vmax, x); |
80 | + } | ||
59 | 81 | ||
60 | if (changed) | 82 | if (changed) |
61 | - _fd_revise_connected(0, revise); | 83 | + { |
84 | + if (fd_domain_empty(revise)) | ||
85 | + return FD_NOSOLUTION; | ||
86 | + | ||
87 | + _fd_revise_connected(this, revise); | ||
88 | + | ||
89 | +#ifndef DISABLE_ENTAILED | ||
90 | + // see if the culprit's domain is a singleton | ||
91 | + if (vmin == vmax) | ||
92 | + fd__constraint_set_entailed(this); | ||
93 | +#endif | ||
94 | + } | ||
62 | 95 | ||
63 | return FD_OK; | 96 | return FD_OK; |
64 | } | 97 | } |
65 | 98 | ||
66 | -int fd_le_propagate(fd_constraint this, fd_int revise) | 99 | +static int fd_le_propagate(fd_constraint this, fd_int revise) |
67 | { | 100 | { |
68 | int changed = 0; | 101 | int changed = 0; |
69 | 102 | ||
@@ -77,7 +110,7 @@ int fd_le_propagate(fd_constraint this, fd_int revise) | @@ -77,7 +110,7 @@ int fd_le_propagate(fd_constraint this, fd_int revise) | ||
77 | 110 | ||
78 | #ifdef USE_ENTAILED | 111 | #ifdef USE_ENTAILED |
79 | if (_fd_var_max(VAR(this, 0)) <= _fd_var_min(VAR(this, 1))) | 112 | if (_fd_var_max(VAR(this, 0)) <= _fd_var_min(VAR(this, 1))) |
80 | - _fd_constraint_set_entailed(this); | 113 | + fd__constraint_set_entailed(this); |
81 | #endif | 114 | #endif |
82 | 115 | ||
83 | // XXX: enqueue further updates here? | 116 | // XXX: enqueue further updates here? |
@@ -89,17 +122,13 @@ int fd_le_propagate(fd_constraint this, fd_int revise) | @@ -89,17 +122,13 @@ int fd_le_propagate(fd_constraint this, fd_int revise) | ||
89 | 122 | ||
90 | fd_constraint fd_le(fd_int x, fd_int y) | 123 | fd_constraint fd_le(fd_int x, fd_int y) |
91 | { | 124 | { |
92 | - fd_constraint c = _fd_constraint_new(2, 0); | 125 | + fd_constraint c = fd__constraint_new(2, 0); |
93 | 126 | ||
94 | if (c) | 127 | if (c) |
95 | { | 128 | { |
96 | c->variables[0] = FD_INT2C_VAR(x); c->variables[1] = FD_INT2C_VAR(y); | 129 | c->variables[0] = FD_INT2C_VAR(x); c->variables[1] = FD_INT2C_VAR(y); |
97 | -#ifdef CONSTRAINT_CLASS | 130 | + |
98 | c->kind = FD_CONSTR_LE; | 131 | c->kind = FD_CONSTR_LE; |
99 | -#else /* CONSTRAINT_CLASS */ | ||
100 | - c->propagator2 = fd_le_propagate2; | ||
101 | - c->propagator = fd_le_propagate; | ||
102 | -#endif /* CONSTRAINT_CLASS */ | ||
103 | 132 | ||
104 | _fd_var_add_constraint(x, c); | 133 | _fd_var_add_constraint(x, c); |
105 | _fd_var_add_constraint(y, c); | 134 | _fd_var_add_constraint(y, c); |
src/constraints/lt.c
1 | -/* X lt Y */ | 1 | +/* x < y */ |
2 | 2 | ||
3 | -int fd_lt_filter(fd_constraint this) | 3 | +static int fd_lt_filter(fd_constraint this) |
4 | { | 4 | { |
5 | fd_int x, y; | 5 | fd_int x, y; |
6 | 6 | ||
@@ -9,7 +9,11 @@ int fd_lt_filter(fd_constraint this) | @@ -9,7 +9,11 @@ int fd_lt_filter(fd_constraint this) | ||
9 | 9 | ||
10 | #ifndef DISABLE_ENTAILED | 10 | #ifndef DISABLE_ENTAILED |
11 | if (_fd_var_max(x) < _fd_var_min(y)) | 11 | if (_fd_var_max(x) < _fd_var_min(y)) |
12 | - fd__constraint_set_entailed(this); | 12 | + { |
13 | + fd__constraint_set_entailed(this); | ||
14 | + | ||
15 | + return FD_OK; | ||
16 | + } | ||
13 | #endif | 17 | #endif |
14 | 18 | ||
15 | if (_fd_var_del_le(_fd_var_min(x), y)) | 19 | if (_fd_var_del_le(_fd_var_min(x), y)) |
@@ -17,7 +21,7 @@ int fd_lt_filter(fd_constraint this) | @@ -17,7 +21,7 @@ int fd_lt_filter(fd_constraint this) | ||
17 | if (fd_domain_empty(y)) | 21 | if (fd_domain_empty(y)) |
18 | return FD_NOSOLUTION; | 22 | return FD_NOSOLUTION; |
19 | 23 | ||
20 | - _fd_revise_connected(NULL, y); | 24 | + _fd_revise_connected(this, y); |
21 | } | 25 | } |
22 | 26 | ||
23 | if (_fd_var_del_ge(_fd_var_max(y), x)) | 27 | if (_fd_var_del_ge(_fd_var_max(y), x)) |
@@ -25,19 +29,32 @@ int fd_lt_filter(fd_constraint this) | @@ -25,19 +29,32 @@ int fd_lt_filter(fd_constraint this) | ||
25 | if (fd_domain_empty(x)) | 29 | if (fd_domain_empty(x)) |
26 | return FD_NOSOLUTION; | 30 | return FD_NOSOLUTION; |
27 | 31 | ||
28 | - _fd_revise_connected(NULL, x); | 32 | + _fd_revise_connected(this, x); |
29 | } | 33 | } |
30 | 34 | ||
35 | +#ifndef DISABLE_ENTAILED | ||
36 | + if (_fd_var_max(x) < _fd_var_min(y)) | ||
37 | + fd__constraint_set_entailed(this); | ||
38 | +#endif | ||
39 | + | ||
31 | return FD_OK; | 40 | return FD_OK; |
32 | } | 41 | } |
33 | 42 | ||
34 | -int fd_lt_propagate2(fd_constraint this, fd_int culprit) | 43 | +static int fd_lt_propagate2(fd_constraint this, fd_int culprit) |
35 | { | 44 | { |
45 | + fd_int x, y; | ||
46 | + int vmax, vmin; | ||
36 | fd_int revise; | 47 | fd_int revise; |
37 | int changed = 0; | 48 | int changed = 0; |
38 | 49 | ||
39 | -#if !defined(DISABLE_ENTAILED) && CONSTRAINT_TEMPS > 2 | ||
40 | - if (_fd_var_max(VAR(this, 0)) < _fd_var_min(VAR(this, 1))) | 50 | + x = VAR(this, 0); |
51 | + y = VAR(this, 1); | ||
52 | + | ||
53 | +#ifndef DISABLE_ENTAILED | ||
54 | + vmax = _fd_var_max(x); | ||
55 | + vmin = _fd_var_min(y); | ||
56 | + | ||
57 | + if (vmax < vmin) | ||
41 | { | 58 | { |
42 | fd__constraint_set_entailed(this); | 59 | fd__constraint_set_entailed(this); |
43 | 60 | ||
@@ -45,29 +62,41 @@ int fd_lt_propagate2(fd_constraint this, fd_int culprit) | @@ -45,29 +62,41 @@ int fd_lt_propagate2(fd_constraint this, fd_int culprit) | ||
45 | } | 62 | } |
46 | #endif | 63 | #endif |
47 | 64 | ||
48 | - if (culprit == VAR(this, 0)) | 65 | + if (culprit == x) |
49 | { | 66 | { |
50 | - revise = VAR(this, 1); | 67 | + revise = y; |
51 | 68 | ||
52 | - changed = _fd_var_del_le(_fd_var_min(culprit), revise); | 69 | + vmin = _fd_var_min(x); |
70 | + | ||
71 | + changed = _fd_var_del_le(vmin, y); | ||
53 | } | 72 | } |
54 | else | 73 | else |
55 | { | 74 | { |
56 | - revise = VAR(this, 0); | 75 | + revise = x; |
57 | 76 | ||
58 | - changed = _fd_var_del_ge(_fd_var_max(culprit), revise); | ||
59 | - } | 77 | + vmax = _fd_var_max(y); |
60 | 78 | ||
61 | - if (changed && fd_domain_empty(revise)) | ||
62 | - return FD_NOSOLUTION; | 79 | + changed = _fd_var_del_ge(vmax, x); |
80 | + } | ||
63 | 81 | ||
64 | if (changed) | 82 | if (changed) |
65 | - _fd_revise_connected(0, revise); | 83 | + { |
84 | + if (fd_domain_empty(revise)) | ||
85 | + return FD_NOSOLUTION; | ||
86 | + | ||
87 | + _fd_revise_connected(this, revise); | ||
88 | + | ||
89 | +#ifndef DISABLE_ENTAILED | ||
90 | + // see if the culprit's domain is a singleton | ||
91 | + if (vmin == vmax) | ||
92 | + fd__constraint_set_entailed(this); | ||
93 | +#endif | ||
94 | + } | ||
66 | 95 | ||
67 | return FD_OK; | 96 | return FD_OK; |
68 | } | 97 | } |
69 | 98 | ||
70 | -int fd_lt_propagate(fd_constraint this, fd_int revise) | 99 | +static int fd_lt_propagate(fd_constraint this, fd_int revise) |
71 | { | 100 | { |
72 | int changed = 0; | 101 | int changed = 0; |
73 | 102 | ||
@@ -81,7 +110,7 @@ int fd_lt_propagate(fd_constraint this, fd_int revise) | @@ -81,7 +110,7 @@ int fd_lt_propagate(fd_constraint this, fd_int revise) | ||
81 | 110 | ||
82 | #ifdef USE_ENTAILED | 111 | #ifdef USE_ENTAILED |
83 | if (_fd_var_max(VAR(this, 0)) < _fd_var_min(VAR(this, 1))) | 112 | if (_fd_var_max(VAR(this, 0)) < _fd_var_min(VAR(this, 1))) |
84 | - _fd_constraint_set_entailed(this); | 113 | + fd__constraint_set_entailed(this); |
85 | #endif | 114 | #endif |
86 | 115 | ||
87 | // XXX: enqueue further updates here? | 116 | // XXX: enqueue further updates here? |
@@ -93,17 +122,13 @@ int fd_lt_propagate(fd_constraint this, fd_int revise) | @@ -93,17 +122,13 @@ int fd_lt_propagate(fd_constraint this, fd_int revise) | ||
93 | 122 | ||
94 | fd_constraint fd_lt(fd_int x, fd_int y) | 123 | fd_constraint fd_lt(fd_int x, fd_int y) |
95 | { | 124 | { |
96 | - fd_constraint c = _fd_constraint_new(2, 0); | 125 | + fd_constraint c = fd__constraint_new(2, 0); |
97 | 126 | ||
98 | if (c) | 127 | if (c) |
99 | { | 128 | { |
100 | c->variables[0] = FD_INT2C_VAR(x); c->variables[1] = FD_INT2C_VAR(y); | 129 | c->variables[0] = FD_INT2C_VAR(x); c->variables[1] = FD_INT2C_VAR(y); |
101 | -#ifdef CONSTRAINT_CLASS | 130 | + |
102 | c->kind = FD_CONSTR_LT; | 131 | c->kind = FD_CONSTR_LT; |
103 | -#else /* CONSTRAINT_CLASS */ | ||
104 | - c->propagator2 = fd_lt_propagate2; | ||
105 | - c->propagator = fd_lt_propagate; | ||
106 | -#endif /* CONSTRAINT_CLASS */ | ||
107 | 132 | ||
108 | _fd_var_add_constraint(x, c); | 133 | _fd_var_add_constraint(x, c); |
109 | _fd_var_add_constraint(y, c); | 134 | _fd_var_add_constraint(y, c); |
src/constraints/max.c
@@ -84,16 +84,13 @@ bool fd_max_bound_variable(fd_constraint this, int bound) | @@ -84,16 +84,13 @@ bool fd_max_bound_variable(fd_constraint this, int bound) | ||
84 | 84 | ||
85 | fd_constraint fd_max(fd_int variable) | 85 | fd_constraint fd_max(fd_int variable) |
86 | { | 86 | { |
87 | - fd_constraint c = _fd_constraint_new(1, 0); | 87 | + fd_constraint c = fd__constraint_new(1, 0); |
88 | 88 | ||
89 | if (c) | 89 | if (c) |
90 | { | 90 | { |
91 | c->variables[0] = FD_INT2C_VAR(variable); | 91 | c->variables[0] = FD_INT2C_VAR(variable); |
92 | -#ifdef CONSTRAINT_CLASS | 92 | + |
93 | c->kind = FD_CONSTR_MAX; | 93 | c->kind = FD_CONSTR_MAX; |
94 | -#else /* CONSTRAINT_CLASS */ | ||
95 | - c->propagator2 = fd_max_propagate2; | ||
96 | -#endif /* CONSTRAINT_CLASS */ | ||
97 | 94 | ||
98 | _fd_var_add_constraint(variable, c); | 95 | _fd_var_add_constraint(variable, c); |
99 | 96 |
src/constraints/min.c
@@ -84,16 +84,13 @@ bool fd_min_bound_variable(fd_constraint this, int bound) | @@ -84,16 +84,13 @@ bool fd_min_bound_variable(fd_constraint this, int bound) | ||
84 | 84 | ||
85 | fd_constraint fd_min(fd_int variable) | 85 | fd_constraint fd_min(fd_int variable) |
86 | { | 86 | { |
87 | - fd_constraint c = _fd_constraint_new(1, 0); | 87 | + fd_constraint c = fd__constraint_new(1, 0); |
88 | 88 | ||
89 | if (c) | 89 | if (c) |
90 | { | 90 | { |
91 | c->variables[0] = FD_INT2C_VAR(variable); | 91 | c->variables[0] = FD_INT2C_VAR(variable); |
92 | -#ifdef CONSTRAINT_CLASS | 92 | + |
93 | c->kind = FD_CONSTR_MIN; | 93 | c->kind = FD_CONSTR_MIN; |
94 | -#else /* CONSTRAINT_CLASS */ | ||
95 | - c->propagator2 = fd_min_propagate2; | ||
96 | -#endif /* CONSTRAINT_CLASS */ | ||
97 | 94 | ||
98 | _fd_var_add_constraint(variable, c); | 95 | _fd_var_add_constraint(variable, c); |
99 | 96 |
src/constraints/minus-eq.c
@@ -105,18 +105,14 @@ int fd_minus_eq_propagate(fd_constraint this, fd_int revise) | @@ -105,18 +105,14 @@ int fd_minus_eq_propagate(fd_constraint this, fd_int revise) | ||
105 | 105 | ||
106 | fd_constraint fd_minus_eq(fd_int x, fd_int y, int k) | 106 | fd_constraint fd_minus_eq(fd_int x, fd_int y, int k) |
107 | { | 107 | { |
108 | - fd_constraint c = _fd_constraint_new(2, 1); | 108 | + fd_constraint c = fd__constraint_new(2, 1); |
109 | 109 | ||
110 | if (c) | 110 | if (c) |
111 | { | 111 | { |
112 | c->variables[0] = FD_INT2C_VAR(x); c->variables[1] = FD_INT2C_VAR(y); | 112 | c->variables[0] = FD_INT2C_VAR(x); c->variables[1] = FD_INT2C_VAR(y); |
113 | c->constants[0] = k; | 113 | c->constants[0] = k; |
114 | -#ifdef CONSTRAINT_CLASS | 114 | + |
115 | c->kind = FD_CONSTR_MINUS_EQ; | 115 | c->kind = FD_CONSTR_MINUS_EQ; |
116 | -#else /* CONSTRAINT_CLASS */ | ||
117 | - c->propagator2 = fd_minus_eq_propagate2; | ||
118 | - c->propagator = fd_minus_eq_propagate; | ||
119 | -#endif /* CONSTRAINT_CLASS */ | ||
120 | 116 | ||
121 | _fd_var_add_constraint(x, c); | 117 | _fd_var_add_constraint(x, c); |
122 | _fd_var_add_constraint(y, c); | 118 | _fd_var_add_constraint(y, c); |
src/constraints/minus-ne.c
@@ -99,18 +99,14 @@ int fd_minus_ne_propagate(fd_constraint this, fd_int revise) | @@ -99,18 +99,14 @@ int fd_minus_ne_propagate(fd_constraint this, fd_int revise) | ||
99 | 99 | ||
100 | fd_constraint fd_minus_ne(fd_int x, fd_int y, int k) | 100 | fd_constraint fd_minus_ne(fd_int x, fd_int y, int k) |
101 | { | 101 | { |
102 | - fd_constraint c = _fd_constraint_new(2, 1); | 102 | + fd_constraint c = fd__constraint_new(2, 1); |
103 | 103 | ||
104 | if (c) | 104 | if (c) |
105 | { | 105 | { |
106 | c->variables[0] = FD_INT2C_VAR(x); c->variables[1] = FD_INT2C_VAR(y); | 106 | c->variables[0] = FD_INT2C_VAR(x); c->variables[1] = FD_INT2C_VAR(y); |
107 | c->constants[0] = k; | 107 | c->constants[0] = k; |
108 | -#ifdef CONSTRAINT_CLASS | 108 | + |
109 | c->kind = FD_CONSTR_MINUS_NE; | 109 | c->kind = FD_CONSTR_MINUS_NE; |
110 | -#else /* CONSTRAINT_CLASS */ | ||
111 | - c->propagator2 = fd_minus_ne_propagate2; | ||
112 | - c->propagator = fd_minus_ne_propagate; | ||
113 | -#endif /* CONSTRAINT_CLASS */ | ||
114 | 110 | ||
115 | _fd_var_add_constraint(x, c); | 111 | _fd_var_add_constraint(x, c); |
116 | _fd_var_add_constraint(y, c); | 112 | _fd_var_add_constraint(y, c); |
src/constraints/ne.c
@@ -86,17 +86,13 @@ int fd_ne_propagate(fd_constraint this, fd_int revise) | @@ -86,17 +86,13 @@ int fd_ne_propagate(fd_constraint this, fd_int revise) | ||
86 | 86 | ||
87 | fd_constraint fd_ne(fd_int x, fd_int y) | 87 | fd_constraint fd_ne(fd_int x, fd_int y) |
88 | { | 88 | { |
89 | - fd_constraint c = _fd_constraint_new(2, 0); | 89 | + fd_constraint c = fd__constraint_new(2, 0); |
90 | 90 | ||
91 | if (c) | 91 | if (c) |
92 | { | 92 | { |
93 | c->variables[0] = FD_INT2C_VAR(x); c->variables[1] = FD_INT2C_VAR(y); | 93 | c->variables[0] = FD_INT2C_VAR(x); c->variables[1] = FD_INT2C_VAR(y); |
94 | -#ifdef CONSTRAINT_CLASS | 94 | + |
95 | c->kind = FD_CONSTR_NE; | 95 | c->kind = FD_CONSTR_NE; |
96 | -#else /* CONSTRAINT_CLASS */ | ||
97 | - c->propagator2 = fd_ne_propagate2; | ||
98 | - c->propagator = fd_ne_propagate; | ||
99 | -#endif /* CONSTRAINT_CLASS */ | ||
100 | 96 | ||
101 | _fd_var_add_constraint(x, c); | 97 | _fd_var_add_constraint(x, c); |
102 | _fd_var_add_constraint(y, c); | 98 | _fd_var_add_constraint(y, c); |
src/constraints/nogoods.c
@@ -35,16 +35,13 @@ int fd_nogoods_propagate(fd_constraint this, fd_int revise) | @@ -35,16 +35,13 @@ int fd_nogoods_propagate(fd_constraint this, fd_int revise) | ||
35 | 35 | ||
36 | fd_constraint fd_nogoods(fd_int x, fd_int y, int *nogoods, int nnogoods) | 36 | fd_constraint fd_nogoods(fd_int x, fd_int y, int *nogoods, int nnogoods) |
37 | { | 37 | { |
38 | - fd_constraint c = _fd_constraint_new(2, 2 * nnogoods); | 38 | + fd_constraint c = fd__constraint_new(2, 2 * nnogoods); |
39 | 39 | ||
40 | if (c) | 40 | if (c) |
41 | { | 41 | { |
42 | c->variables[0] = FD_INT2C_VAR(x); c->variables[1] = FD_INT2C_VAR(y); | 42 | c->variables[0] = FD_INT2C_VAR(x); c->variables[1] = FD_INT2C_VAR(y); |
43 | -#ifdef CONSTRAINT_CLASS | 43 | + |
44 | c->kind = FD_CONSTR_NOGOODS; | 44 | c->kind = FD_CONSTR_NOGOODS; |
45 | -#else /* CONSTRAINT_CLASS */ | ||
46 | - c->propagator = fd_nogoods_propagate; | ||
47 | -#endif /* CONSTRAINT_CLASS */ | ||
48 | 45 | ||
49 | memcpy(c->constants, nogoods, 2 * nnogoods * sizeof(int)); | 46 | memcpy(c->constants, nogoods, 2 * nnogoods * sizeof(int)); |
50 | 47 |
src/constraints/plus-gt.c
@@ -23,17 +23,14 @@ int fd_plus_gt_propagate(fd_constraint this, fd_int revise) | @@ -23,17 +23,14 @@ int fd_plus_gt_propagate(fd_constraint this, fd_int revise) | ||
23 | 23 | ||
24 | fd_constraint fd_plus_gt(fd_int x, fd_int y, int k) | 24 | fd_constraint fd_plus_gt(fd_int x, fd_int y, int k) |
25 | { | 25 | { |
26 | - fd_constraint c = _fd_constraint_new(2, 1); | 26 | + fd_constraint c = fd__constraint_new(2, 1); |
27 | 27 | ||
28 | if (c) | 28 | if (c) |
29 | { | 29 | { |
30 | c->variables[0] = FD_INT2C_VAR(x); c->variables[1] = FD_INT2C_VAR(y); | 30 | c->variables[0] = FD_INT2C_VAR(x); c->variables[1] = FD_INT2C_VAR(y); |
31 | c->constants[0] = k; | 31 | c->constants[0] = k; |
32 | -#ifdef CONSTRAINT_CLASS | 32 | + |
33 | c->kind = FD_CONSTR_PLUS_GT; | 33 | c->kind = FD_CONSTR_PLUS_GT; |
34 | -#else /* CONSTRAINT_CLASS */ | ||
35 | - c->propagator = fd_plus_gt_propagate; | ||
36 | -#endif /* CONSTRAINT_CLASS */ | ||
37 | 34 | ||
38 | _fd_var_add_constraint(x, c); | 35 | _fd_var_add_constraint(x, c); |
39 | _fd_var_add_constraint(y, c); | 36 | _fd_var_add_constraint(y, c); |
src/constraints/poly-eq-k.c
1 | /* poly-eq-k(C, X, k) == sum(C . X) = k */ | 1 | /* poly-eq-k(C, X, k) == sum(C . X) = k */ |
2 | 2 | ||
3 | +// caveat: may not work correctly when there are more than one | ||
4 | +// occurrences of some variable | ||
5 | + | ||
3 | static int fd_poly_eq_k_filter(fd_constraint this) | 6 | static int fd_poly_eq_k_filter(fd_constraint this) |
4 | { | 7 | { |
5 | int k; | 8 | int k; |
@@ -52,142 +55,99 @@ static int fd_poly_eq_k_filter(fd_constraint this) | @@ -52,142 +55,99 @@ static int fd_poly_eq_k_filter(fd_constraint this) | ||
52 | return FD_NOSOLUTION; | 55 | return FD_NOSOLUTION; |
53 | 56 | ||
54 | if (min == max) | 57 | if (min == max) |
55 | - return FD_OK; | ||
56 | - | ||
57 | - // XXX: poor man's propagation | ||
58 | - if (min == k) | ||
59 | { | 58 | { |
60 | - for (i = 0; i < terms; ++i) | ||
61 | - { | ||
62 | - int c = this->constants[i]; | ||
63 | - | ||
64 | - if (c && mins[i] != maxs[i]) | ||
65 | - { | ||
66 | - if (c > 0) | ||
67 | - _fd_var_del_gt(mins[i], VAR(this, i)); | ||
68 | - else | ||
69 | - _fd_var_del_lt(maxs[i], VAR(this, i)); | ||
70 | - | ||
71 | - // check needed for when variables occur more than once | ||
72 | - // and with opposite signs | ||
73 | - if (fd_domain_empty(VAR(this, i))) | ||
74 | - return FD_NOSOLUTION; | ||
75 | - | ||
76 | - _fd_revise_connected(this, VAR(this, i)); | ||
77 | - } | ||
78 | - } | ||
79 | - | ||
80 | fd__constraint_set_entailed(this); | 59 | fd__constraint_set_entailed(this); |
81 | } | 60 | } |
82 | - else if (max == k) | 61 | + else |
83 | { | 62 | { |
84 | - for (i = 0; i < terms; ++i) | ||
85 | - { | ||
86 | - int c = this->constants[i]; | 63 | + // bounds domain filtering |
64 | + // XXX: number of iterations depends on the size of the domains | ||
87 | 65 | ||
88 | - if (c && mins[i] != maxs[i]) | ||
89 | - { | ||
90 | - if (c > 0) | ||
91 | - _fd_var_del_lt(maxs[i], VAR(this, i)); | ||
92 | - else | ||
93 | - _fd_var_del_gt(mins[i], VAR(this, i)); | 66 | + int omin, omax; |
94 | 67 | ||
95 | - if (fd_domain_empty(VAR(this, i))) | ||
96 | - return FD_NOSOLUTION; | ||
97 | - | ||
98 | - _fd_revise_connected(this, VAR(this, i)); | ||
99 | - } | ||
100 | - } | 68 | + do { |
69 | + omin = min; | ||
70 | + omax = max; | ||
101 | 71 | ||
102 | - fd__constraint_set_entailed(this); | ||
103 | - } | ||
104 | - else | ||
105 | - { | ||
106 | - if (max > k) | ||
107 | for (i = 0; i < terms; ++i) | 72 | for (i = 0; i < terms; ++i) |
108 | { | 73 | { |
109 | int c = this->constants[i]; | 74 | int c = this->constants[i]; |
110 | - int xmin = mins[i]; | ||
111 | - int xmax = maxs[i]; | 75 | + int imin = mins[i]; |
76 | + int imax = maxs[i]; | ||
77 | + | ||
78 | + if (c == 0 || imin == imax) continue; | ||
112 | 79 | ||
113 | if (c > 0) | 80 | if (c > 0) |
114 | { | 81 | { |
115 | - // enforce sum{j!=i}(c[j] * min[j]) + c[i] * max[i] <= k | 82 | + // enforce max(sum{j!=i}(c[j] * x[j])) + c[i] * min[i] >= k |
116 | 83 | ||
117 | - if ((xmax - xmin) * c > k - min) | 84 | + if (max + (imin - imax) * c < k) |
118 | { | 85 | { |
119 | - // xmax = floor((k - min) / c) + xmin | ||
120 | - xmax = (k - min) / c + xmin; | 86 | + // imin = ceil((k - max) / c) + imax |
87 | + imin = (k - max) / c + imax; | ||
121 | 88 | ||
122 | - _fd_var_del_gt(xmax, VAR(this, i)); | 89 | + fd_update_domain_and_check(del_lt, imin, VAR(this, i)); |
123 | 90 | ||
124 | - if (fd_domain_empty(VAR(this, i))) | 91 | + min += (imin - mins[i]) * c; |
92 | + | ||
93 | + if (min > k) | ||
125 | return FD_NOSOLUTION; | 94 | return FD_NOSOLUTION; |
126 | 95 | ||
127 | - _fd_revise_connected(this, VAR(this, i)); | 96 | + mins[i] = imin; |
128 | } | 97 | } |
129 | - } | ||
130 | - else if (c < 0) | ||
131 | - { | ||
132 | - // enforce sum{j!=i}(c[j] * min[j]) + c[i] * min[i] <= k | ||
133 | 98 | ||
134 | - if ((xmin - xmax) * c > k - min) | 99 | + // enforce min(sum{j!=i}(c[j] * x[j])) + c[i] * max[i] <= k |
100 | + | ||
101 | + if (min + (imax - imin) * c > k) | ||
135 | { | 102 | { |
136 | - // xmin = ceil((k - min) / c) + xmax | ||
137 | - xmin = (k - min) / c + xmax; | 103 | + // imax = floor((k - min) / c) + imin |
104 | + imax = (k - min) / c + imin; | ||
138 | 105 | ||
139 | - _fd_var_del_lt(xmin, VAR(this, i)); | 106 | + fd_update_domain_and_check(del_gt, imax, VAR(this, i)); |
140 | 107 | ||
141 | - if (fd_domain_empty(VAR(this, i))) | ||
142 | - return FD_NOSOLUTION; | 108 | + max -= (maxs[i] - imax) * c; // max >= k! |
143 | 109 | ||
144 | - _fd_revise_connected(this, VAR(this, i)); | 110 | + maxs[i] = imax; |
145 | } | 111 | } |
146 | } | 112 | } |
147 | - } | ||
148 | - | ||
149 | - if (min < k) | ||
150 | - for (i = 0; i < terms; ++i) | ||
151 | - { | ||
152 | - int c = this->constants[i]; | ||
153 | - int xmin = mins[i]; | ||
154 | - int xmax = maxs[i]; | ||
155 | - | ||
156 | - if (c > 0) | 113 | + else |
157 | { | 114 | { |
158 | - // enforce sum{j!=i}(c[j] * max[j]) + c[i] * min[i] >= k | 115 | + // enforce max(sum{j!=i}(c[j] * x[j])) + c[i] * max[i] >= k |
159 | 116 | ||
160 | - if ((xmax - xmin) * c > max - k) | 117 | + if (max + (imax - imin) * c < k) |
161 | { | 118 | { |
162 | - // xmin = ceil((k - max) / c) + xmax | ||
163 | - xmin = (k - max) / c + xmax; | 119 | + // imax = floor((k - max) / c) + imin |
120 | + imax = (k - max) / c + imin; | ||
121 | + | ||
122 | + fd_update_domain_and_check(del_gt, imax, VAR(this, i)); | ||
164 | 123 | ||
165 | - _fd_var_del_lt(xmin, VAR(this, i)); | 124 | + min += (imax - maxs[i]) * c; |
166 | 125 | ||
167 | - if (fd_domain_empty(VAR(this, i))) // domains may have holes | 126 | + if (min > k) |
168 | return FD_NOSOLUTION; | 127 | return FD_NOSOLUTION; |
169 | 128 | ||
170 | - _fd_revise_connected(this, VAR(this, i)); | 129 | + maxs[i] = imax; |
171 | } | 130 | } |
172 | - } | ||
173 | - else if (c < 0) | ||
174 | - { | ||
175 | - // enforce sum{j!=i}(c[j] * max[j]) + c[i] * max[i] >= k | ||
176 | 131 | ||
177 | - if ((xmax - xmin) * c < k - max) | 132 | + // enforce min(sum{j!=i}(c[j] * x[j])) + c[i] * min[i] <= k |
133 | + | ||
134 | + if (min + (imin - imax) * c > k) | ||
178 | { | 135 | { |
179 | - // xmax = floor((k - max) / c) + xmin | ||
180 | - xmax = (k - max) / c + xmin; | 136 | + // imin = ceil((k - min) / c) + imax |
137 | + imin = (k - min) / c + imax; | ||
181 | 138 | ||
182 | - _fd_var_del_gt(xmax, VAR(this, i)); | 139 | + fd_update_domain_and_check(del_lt, imin, VAR(this, i)); |
183 | 140 | ||
184 | - if (fd_domain_empty(VAR(this, i))) // domains may have holes | ||
185 | - return FD_NOSOLUTION; | 141 | + max -= (mins[i] - imin) * c; // max >= k! |
186 | 142 | ||
187 | - _fd_revise_connected(this, VAR(this, i)); | 143 | + mins[i] = imin; |
188 | } | 144 | } |
189 | } | 145 | } |
190 | } | 146 | } |
147 | + } while (min != max && (min != omin || max != omax)); | ||
148 | + | ||
149 | + if (min == max) | ||
150 | + fd__constraint_set_entailed(this); | ||
191 | } | 151 | } |
192 | 152 | ||
193 | #ifdef CONSTRAINT_TEMPS | 153 | #ifdef CONSTRAINT_TEMPS |
@@ -267,170 +227,104 @@ static int fd_poly_eq_k_propagate2(fd_constraint this, fd_int culprit) | @@ -267,170 +227,104 @@ static int fd_poly_eq_k_propagate2(fd_constraint this, fd_int culprit) | ||
267 | } | 227 | } |
268 | while (x < terms); | 228 | while (x < terms); |
269 | 229 | ||
270 | - // XXX: poor man's propagation | ||
271 | - if (nmin == k) | ||
272 | - { | ||
273 | - for (i = 0; i < terms; ++i) | ||
274 | - { | ||
275 | - int c = this->constants[i]; | ||
276 | - | ||
277 | - if (c && mins[i] != maxs[i]) | ||
278 | - { | ||
279 | - if (c > 0) | ||
280 | - { | ||
281 | - _fd_var_del_gt(mins[i], VAR(this, i)); | ||
282 | - | ||
283 | - maxs[i] = mins[i]; | ||
284 | - } | ||
285 | - else | ||
286 | - { | ||
287 | - _fd_var_del_lt(maxs[i], VAR(this, i)); | ||
288 | - | ||
289 | - mins[i] = maxs[i]; | ||
290 | - } | ||
291 | - | ||
292 | - if (fd_domain_empty(VAR(this, i))) | ||
293 | - return FD_NOSOLUTION; | ||
294 | - | ||
295 | - _fd_revise_connected(this, VAR(this, i)); | ||
296 | - } | ||
297 | - } | 230 | + if (nmin == min && nmax == max) |
231 | + return FD_OK; | ||
298 | 232 | ||
233 | + if (nmin == nmax) | ||
234 | + { | ||
299 | fd__constraint_set_entailed(this); | 235 | fd__constraint_set_entailed(this); |
300 | } | 236 | } |
301 | - else if (nmax == k) | 237 | + else |
302 | { | 238 | { |
303 | - for (i = 0; i < terms; ++i) | ||
304 | - { | ||
305 | - int c = this->constants[i]; | ||
306 | - | ||
307 | - if (c && mins[i] != maxs[i]) | ||
308 | - { | ||
309 | - if (c > 0) | ||
310 | - { | ||
311 | - _fd_var_del_lt(maxs[i], VAR(this, i)); | 239 | + // bounds domain propagation |
240 | + // XXX: number of iterations depends on the size of the domains | ||
312 | 241 | ||
313 | - mins[i] = maxs[i]; | ||
314 | - } | ||
315 | - else | ||
316 | - { | ||
317 | - _fd_var_del_gt(mins[i], VAR(this, i)); | 242 | + int onmin, onmax; |
318 | 243 | ||
319 | - maxs[i] = mins[i]; | ||
320 | - } | 244 | + do { |
245 | + onmin = nmin; | ||
246 | + onmax = nmax; | ||
321 | 247 | ||
322 | - if (fd_domain_empty(VAR(this, i))) | ||
323 | - return FD_NOSOLUTION; | ||
324 | - | ||
325 | - _fd_revise_connected(this, VAR(this, i)); | ||
326 | - } | ||
327 | - } | ||
328 | - | ||
329 | - fd__constraint_set_entailed(this); | ||
330 | - } | ||
331 | - | ||
332 | -#if 0 // this is too expensive | ||
333 | - { | ||
334 | - if (nmax < max && nmax > k) | ||
335 | for (i = 0; i < terms; ++i) | 248 | for (i = 0; i < terms; ++i) |
336 | { | 249 | { |
337 | int c = this->constants[i]; | 250 | int c = this->constants[i]; |
338 | - int xmin = mins[i]; | ||
339 | - int xmax = maxs[i]; | 251 | + int imin = mins[i]; |
252 | + int imax = maxs[i]; | ||
253 | + | ||
254 | + if (c == 0 || imin == imax) continue; | ||
340 | 255 | ||
341 | if (c > 0) | 256 | if (c > 0) |
342 | { | 257 | { |
343 | - // enforce sum{j!=i}(c[j] * min[j]) + c[i] * max[i] <= k | 258 | + // enforce max(sum{j!=i}(c[j] * x[j])) + c[i] * min[i] >= k |
344 | 259 | ||
345 | - if ((xmax - xmin) * c > k - nmin) | 260 | + if (nmax + (imin - imax) * c < k) |
346 | { | 261 | { |
347 | - // xmax = floor((k - nmin) / c) + xmin | ||
348 | - xmax = (k - nmin) / c + xmin; | 262 | + // imin = ceil((k - nmax) / c) + imax |
263 | + imin = (k - nmax) / c + imax; | ||
264 | + | ||
265 | + fd_update_domain_and_check(del_lt, imin, VAR(this, i)); | ||
349 | 266 | ||
350 | - if (_fd_var_del_gt(xmax, VAR(this, i))) | ||
351 | - { | ||
352 | - if (fd_domain_empty(VAR(this, i))) | ||
353 | - return FD_NOSOLUTION; | 267 | + nmin += (imin - mins[i]) * c; |
354 | 268 | ||
355 | - _fd_revise_connected(this, VAR(this, i)); | ||
356 | - } | 269 | + if (nmin > k) |
270 | + return FD_NOSOLUTION; | ||
357 | 271 | ||
358 | - maxs[i] = xmax; | 272 | + mins[i] = imin; |
359 | } | 273 | } |
360 | - } | ||
361 | - else if (c < 0) | ||
362 | - { | ||
363 | - // enforce sum{j!=i}(c[j] * min[j]) + c[i] * min[i] <= k | ||
364 | 274 | ||
365 | - if ((xmin - xmax) * c > k - nmin) | 275 | + // enforce min(sum{j!=i}(c[j] * x[j])) + c[i] * max[i] <= k |
276 | + | ||
277 | + if (nmin + (imax - imin) * c > k) | ||
366 | { | 278 | { |
367 | - // xmin = ceil((k - nmin) / c) + xmax | ||
368 | - xmin = (k - nmin) / c + xmax; | 279 | + // imax = floor((k - nmin) / c) + imin |
280 | + imax = (k - nmin) / c + imin; | ||
369 | 281 | ||
370 | - if (_fd_var_del_lt(xmin, VAR(this, i))) | ||
371 | - { | ||
372 | - if (fd_domain_empty(VAR(this, i))) | ||
373 | - return FD_NOSOLUTION; | 282 | + fd_update_domain_and_check(del_gt, imax, VAR(this, i)); |
374 | 283 | ||
375 | - _fd_revise_connected(this, VAR(this, i)); | ||
376 | - } | 284 | + nmax -= (maxs[i] - imax) * c; // nmax >= k! |
377 | 285 | ||
378 | - mins[i] = xmin; | 286 | + maxs[i] = imax; |
379 | } | 287 | } |
380 | } | 288 | } |
381 | - } | ||
382 | - | ||
383 | - if (nmin > min && nmin < k) | ||
384 | - for (i = 0; i < terms; ++i) | ||
385 | - { | ||
386 | - int c = this->constants[i]; | ||
387 | - int xmin = mins[i]; | ||
388 | - int xmax = maxs[i]; | ||
389 | - | ||
390 | - if (c > 0) | 289 | + else |
391 | { | 290 | { |
392 | - // enforce sum{j!=i}(c[j] * max[j]) + c[i] * min[i] >= k | 291 | + // enforce max(sum{j!=i}(c[j] * x[j])) + c[i] * max[i] >= k |
393 | 292 | ||
394 | - if ((xmax - xmin) * c > nmax - k) | 293 | + if (nmax + (imax - imin) * c < k) |
395 | { | 294 | { |
396 | - // xmin = ceil((k - nmax) / c) + xmax | ||
397 | - xmin = (k - nmax) / c + xmax; | 295 | + // imax = floor((k - nmax) / c) + imin |
296 | + imax = (k - nmax) / c + imin; | ||
398 | 297 | ||
399 | - if (_fd_var_del_lt(xmin, VAR(this, i))) | ||
400 | - { | 298 | + fd_update_domain_and_check(del_gt, imax, VAR(this, i)); |
401 | 299 | ||
402 | - if (fd_domain_empty(VAR(this, i))) // domains may have holes | ||
403 | - return FD_NOSOLUTION; | 300 | + nmin += (imax - maxs[i]) * c; |
404 | 301 | ||
405 | - _fd_revise_connected(this, VAR(this, i)); | ||
406 | - } | 302 | + if (nmin > k) |
303 | + return FD_NOSOLUTION; | ||
407 | 304 | ||
408 | - mins[i] = xmin; | 305 | + maxs[i] = imax; |
409 | } | 306 | } |
410 | - } | ||
411 | - else if (c < 0) | ||
412 | - { | ||
413 | - // enforce sum{j!=i}(c[j] * max[j]) + c[i] * max[i] >= k | ||
414 | 307 | ||
415 | - if ((xmax - xmin) * c < k - nmax) | 308 | + // enforce min(sum{j!=i}(c[j] * x[j])) + c[i] * min[i] <= k |
309 | + | ||
310 | + if (nmin + (imin - imax) * c > k) | ||
416 | { | 311 | { |
417 | - // xmax = floor((k - nmax) / c) + xmin | ||
418 | - xmax = (k - nmax) / c + xmin; | 312 | + // imin = ceil((k - nmin) / c) + imax |
313 | + imin = (k - nmin) / c + imax; | ||
419 | 314 | ||
420 | - if (_fd_var_del_gt(xmax, VAR(this, i))) | ||
421 | - { | ||
422 | - if (fd_domain_empty(VAR(this, i))) // domains may have holes | ||
423 | - return FD_NOSOLUTION; | 315 | + fd_update_domain_and_check(del_lt, imin, VAR(this, i)); |
424 | 316 | ||
425 | - _fd_revise_connected(this, VAR(this, i)); | ||
426 | - } | 317 | + nmax -= (mins[i] - imin) * c; // nmax >= k! |
427 | 318 | ||
428 | - maxs[i] = xmax; | 319 | + mins[i] = imin; |
429 | } | 320 | } |
430 | } | 321 | } |
431 | } | 322 | } |
323 | + } while (nmin != nmax && (nmin != onmin || nmax != onmax)); | ||
324 | + | ||
325 | + if (nmin == nmax) | ||
326 | + fd__constraint_set_entailed(this); | ||
432 | } | 327 | } |
433 | -#endif | ||
434 | 328 | ||
435 | *base = nmin; | 329 | *base = nmin; |
436 | *(base + 1) = nmax; | 330 | *(base + 1) = nmax; |
@@ -443,7 +337,7 @@ static int fd_poly_eq_k_propagate2(fd_constraint this, fd_int culprit) | @@ -443,7 +337,7 @@ static int fd_poly_eq_k_propagate2(fd_constraint this, fd_int culprit) | ||
443 | 337 | ||
444 | fd_constraint fd_poly_eq_k(int cs[], fd_int xs[], int nterms, int k) | 338 | fd_constraint fd_poly_eq_k(int cs[], fd_int xs[], int nterms, int k) |
445 | { | 339 | { |
446 | - fd_constraint c = _fd_constraint_new(nterms, nterms + 1); | 340 | + fd_constraint c = fd__constraint_new(nterms, nterms + 1); |
447 | int i; | 341 | int i; |
448 | 342 | ||
449 | if (c) | 343 | if (c) |
@@ -453,11 +347,8 @@ fd_constraint fd_poly_eq_k(int cs[], fd_int xs[], int nterms, int k) | @@ -453,11 +347,8 @@ fd_constraint fd_poly_eq_k(int cs[], fd_int xs[], int nterms, int k) | ||
453 | for (i = 0; i < nterms; ++i) | 347 | for (i = 0; i < nterms; ++i) |
454 | c->constants[i] = cs[i]; | 348 | c->constants[i] = cs[i]; |
455 | c->constants[nterms] = k; | 349 | c->constants[nterms] = k; |
456 | -#ifdef CONSTRAINT_CLASS | 350 | + |
457 | c->kind = FD_CONSTR_POLY_EQ_K; | 351 | c->kind = FD_CONSTR_POLY_EQ_K; |
458 | -#else /* CONSTRAINT_CLASS */ | ||
459 | - c->propagator2 = fd_poly_eq_k_propagate2; | ||
460 | -#endif /* CONSTRAINT_CLASS */ | ||
461 | 352 | ||
462 | for (i = 0; i < c->nvariables; ++i) | 353 | for (i = 0; i < c->nvariables; ++i) |
463 | _fd_var_add_constraint(VAR(c, i), c); | 354 | _fd_var_add_constraint(VAR(c, i), c); |
src/constraints/poly-eq.c
1 | -/* poly-eq(C, X, y) == min(y) <= sum(C . X) <= max(y) */ | 1 | +/* poly-eq(C, X, y) == sum(C . X) = y */ |
2 | + | ||
3 | +// caveat: may not work correctly when there are more than one | ||
4 | +// occurrences of some variable | ||
2 | 5 | ||
3 | static int fd_poly_eq_filter(fd_constraint this) | 6 | static int fd_poly_eq_filter(fd_constraint this) |
4 | { | 7 | { |
@@ -52,154 +55,155 @@ static int fd_poly_eq_filter(fd_constraint this) | @@ -52,154 +55,155 @@ static int fd_poly_eq_filter(fd_constraint this) | ||
52 | if (min > ub || max < lb) | 55 | if (min > ub || max < lb) |
53 | return FD_NOSOLUTION; | 56 | return FD_NOSOLUTION; |
54 | 57 | ||
55 | - if ((min > lb && _fd_var_del_lt(min, VAR(this, this->nvariables - 1))) | | ||
56 | - (max < ub && _fd_var_del_gt(max, VAR(this, this->nvariables - 1)))) | 58 | + if (min > lb) |
57 | { | 59 | { |
58 | - if (fd_domain_empty(VAR(this, this->nvariables - 1))) | ||
59 | - return FD_NOSOLUTION; | 60 | + fd_update_domain_and_check(del_lt, min, VAR(this, this->nvariables - 1)); |
61 | + | ||
62 | + lb = min; | ||
63 | + } | ||
64 | + | ||
65 | + if (max < ub) | ||
66 | + { | ||
67 | + fd_update_domain_and_check(del_gt, max, VAR(this, this->nvariables - 1)); | ||
60 | 68 | ||
61 | - _fd_revise_connected(this, VAR(this, this->nvariables - 1)); | 69 | + ub = max; |
62 | } | 70 | } |
63 | 71 | ||
64 | if (min == max) | 72 | if (min == max) |
65 | - return FD_OK; | 73 | + { |
74 | + fd__constraint_set_entailed(this); | ||
75 | + } | ||
76 | + else | ||
77 | + { | ||
78 | + // bounds domain filtering | ||
79 | + // XXX: number of iterations depends on the size of the domains | ||
66 | 80 | ||
67 | - // XXX: poor man's propagation | ||
68 | - if (min == ub) | ||
69 | - for (i = 0; i < terms; ++i) | ||
70 | - { | ||
71 | - int c = this->constants[i]; | 81 | + int omin, omax; |
72 | 82 | ||
73 | - if (c && mins[i] != maxs[i]) | 83 | + do { |
84 | + omin = min; | ||
85 | + omax = max; | ||
86 | + | ||
87 | + if (max > ub) | ||
74 | { | 88 | { |
75 | - if (c > 0) | 89 | + for (i = 0; i < terms; ++i) |
76 | { | 90 | { |
77 | - _fd_var_del_gt(mins[i], VAR(this, i)); | 91 | + int c = this->constants[i]; |
92 | + int imin = mins[i]; | ||
93 | + int imax = maxs[i]; | ||
78 | 94 | ||
79 | - // check needed for when variables occur twice and | ||
80 | - // with opposite signs | ||
81 | - if (fd_domain_empty(VAR(this, i))) | ||
82 | - return FD_NOSOLUTION; | 95 | + if (c == 0 || imin == imax) continue; |
83 | 96 | ||
84 | - _fd_revise_connected(this, VAR(this, i)); | ||
85 | - } | ||
86 | - else | ||
87 | - { | ||
88 | - _fd_var_del_lt(maxs[i], VAR(this, i)); | 97 | + if (c > 0) |
98 | + { | ||
99 | + // enforce min(sum{j!=i}(c[j] * x[j])) + c[i] * max[i] <= max[y] | ||
89 | 100 | ||
90 | - if (fd_domain_empty(VAR(this, i))) | ||
91 | - return FD_NOSOLUTION; | 101 | + if (min + (imax - imin) * c > ub) |
102 | + { | ||
103 | + // imax = floor((ub - min) / c) + imin | ||
104 | + imax = (ub - min) / c + imin; | ||
92 | 105 | ||
93 | - _fd_revise_connected(this, VAR(this, i)); | ||
94 | - } | ||
95 | - } | ||
96 | - } | ||
97 | - else if (max == lb) | ||
98 | - for (i = 0; i < terms; ++i) | ||
99 | - { | ||
100 | - int c = this->constants[i]; | 106 | + fd_update_domain_and_check(del_gt, imax, VAR(this, i)); |
101 | 107 | ||
102 | - if (c && mins[i] != maxs[i]) | ||
103 | - { | ||
104 | - if (c > 0) | ||
105 | - { | ||
106 | - _fd_var_del_lt(maxs[i], VAR(this, i)); | 108 | + max -= (maxs[i] - imax) * c; |
107 | 109 | ||
108 | - if (fd_domain_empty(VAR(this, i))) | ||
109 | - return FD_NOSOLUTION; | 110 | + maxs[i] = imax; |
111 | + } | ||
112 | + } | ||
113 | + else | ||
114 | + { | ||
115 | + // enforce min(sum{j!=i}(c[j] * x[j])) + c[i] * min[i] <= max[y] | ||
110 | 116 | ||
111 | - _fd_revise_connected(this, VAR(this, i)); | ||
112 | - } | ||
113 | - else | ||
114 | - { | ||
115 | - _fd_var_del_gt(mins[i], VAR(this, i)); | 117 | + if (min + (imin - imax) * c > ub) |
118 | + { | ||
119 | + // imin = ceil((ub - min) / c) + imax | ||
120 | + imin = (ub - min) / c + imax; | ||
121 | + | ||
122 | + fd_update_domain_and_check(del_lt, imin, VAR(this, i)); | ||
116 | 123 | ||
117 | - if (fd_domain_empty(VAR(this, i))) | ||
118 | - return FD_NOSOLUTION; | 124 | + max -= (mins[i] - imin) * c; |
119 | 125 | ||
120 | - _fd_revise_connected(this, VAR(this, i)); | 126 | + mins[i] = imin; |
127 | + } | ||
128 | + } | ||
121 | } | 129 | } |
130 | + | ||
131 | + if (max < lb) | ||
132 | + return FD_NOSOLUTION; | ||
122 | } | 133 | } |
123 | - } | ||
124 | - else | ||
125 | - { | ||
126 | - if (max > ub) | ||
127 | - for (i = 0; i < terms; ++i) | ||
128 | - { | ||
129 | - int c = this->constants[i]; | ||
130 | - int xmin = mins[i]; | ||
131 | - int xmax = maxs[i]; | ||
132 | 134 | ||
133 | - if (c > 0) | 135 | + if (min < lb) |
136 | + { | ||
137 | + for (i = 0; i < terms; ++i) | ||
134 | { | 138 | { |
135 | - if ((xmax - xmin) * c > ub - min) | 139 | + int c = this->constants[i]; |
140 | + int imin = mins[i]; | ||
141 | + int imax = maxs[i]; | ||
142 | + | ||
143 | + if (c == 0 || imin == imax) continue; | ||
144 | + | ||
145 | + if (c > 0) | ||
136 | { | 146 | { |
137 | - // xmax = floor((ub - min) / c) + xmin | ||
138 | - xmax = (ub - min) / c + xmin; | 147 | + // enforce max(sum{j!=i}(c[j] * x[j])) + c[i] * min[i] >= min[y] |
148 | + | ||
149 | + if (max + (imin - imax) * c < lb) | ||
150 | + { | ||
151 | + // imin = ceil((lb - max) / c) + imax | ||
152 | + imin = (lb - max) / c + imax; | ||
139 | 153 | ||
140 | - _fd_var_del_gt(xmax, VAR(this, i)); | 154 | + fd_update_domain_and_check(del_lt, imin, VAR(this, i)); |
141 | 155 | ||
142 | - if (fd_domain_empty(VAR(this, i))) | ||
143 | - return FD_NOSOLUTION; | 156 | + min += (imin - mins[i]) * c; |
144 | 157 | ||
145 | - _fd_revise_connected(this, VAR(this, i)); | 158 | + mins[i] = imin; |
159 | + } | ||
146 | } | 160 | } |
147 | - } | ||
148 | - else if (c < 0) | ||
149 | - { | ||
150 | - if ((xmin - xmax) * c > ub - min) | 161 | + else |
151 | { | 162 | { |
152 | - // xmin = ceil((ub - min) / c) + xmax | ||
153 | - xmin = (ub - min) / c + xmax; | 163 | + // enforce max(sum{j!=i}(c[j] * x[j])) + c[i] * max[i] >= min[y] |
164 | + | ||
165 | + if (max + (imax - imin) * c < lb) | ||
166 | + { | ||
167 | + // imax = floor((lb - max) / c) + imin | ||
168 | + imax = (lb - max) / c + imin; | ||
154 | 169 | ||
155 | - _fd_var_del_lt(xmin, VAR(this, i)); | 170 | + fd_update_domain_and_check(del_gt, imax, VAR(this, i)); |
156 | 171 | ||
157 | - if (fd_domain_empty(VAR(this, i))) | ||
158 | - return FD_NOSOLUTION; | 172 | + min += (imax - maxs[i]) * c; |
159 | 173 | ||
160 | - _fd_revise_connected(this, VAR(this, i)); | 174 | + maxs[i] = imax; |
175 | + } | ||
161 | } | 176 | } |
162 | } | 177 | } |
178 | + | ||
179 | + if (min > ub) | ||
180 | + return FD_NOSOLUTION; | ||
163 | } | 181 | } |
164 | 182 | ||
165 | - if (min < lb) | ||
166 | - for (i = 0; i < terms; ++i) | 183 | + if (min > lb && _fd_var_del_lt(min, VAR(this, this->nvariables - 1))) |
167 | { | 184 | { |
168 | - int c = this->constants[i]; | ||
169 | - int xmin = mins[i]; | ||
170 | - int xmax = maxs[i]; | 185 | + if (fd_domain_empty(VAR(this, this->nvariables - 1))) |
186 | + return FD_NOSOLUTION; | ||
171 | 187 | ||
172 | - if (c > 0) | ||
173 | - { | ||
174 | - if ((xmax - xmin) * c > max - lb) | ||
175 | - { | ||
176 | - // xmin = ceil((lb - max) / c) + xmax | ||
177 | - xmin = (lb - max) / c + xmax; | 188 | + _fd_revise_connected(this, VAR(this, this->nvariables - 1)); |
178 | 189 | ||
179 | - _fd_var_del_lt(xmin, VAR(this, i)); | 190 | + lb = min; |
191 | + } | ||
180 | 192 | ||
181 | - if (fd_domain_empty(VAR(this, i))) // domains may have holes | ||
182 | - return FD_NOSOLUTION; | 193 | + if (max < ub && _fd_var_del_gt(max, VAR(this, this->nvariables - 1))) |
194 | + { | ||
195 | + if (fd_domain_empty(VAR(this, this->nvariables - 1))) | ||
196 | + return FD_NOSOLUTION; | ||
183 | 197 | ||
184 | - _fd_revise_connected(this, VAR(this, i)); | ||
185 | - } | ||
186 | - } | ||
187 | - else if (c < 0) | ||
188 | - { | ||
189 | - if ((xmax - xmin) * c < lb - max) | ||
190 | - { | ||
191 | - // xmax = floor((lb - max) / c) + xmin | ||
192 | - xmax = (lb - max) / c + xmin; | 198 | + _fd_revise_connected(this, VAR(this, this->nvariables - 1)); |
193 | 199 | ||
194 | - _fd_var_del_gt(xmax, VAR(this, i)); | 200 | + ub = max; |
201 | + } | ||
195 | 202 | ||
196 | - if (fd_domain_empty(VAR(this, i))) // domains may have holes | ||
197 | - return FD_NOSOLUTION; | 203 | + } while (min != max && (min != omin || max != omax)); |
198 | 204 | ||
199 | - _fd_revise_connected(this, VAR(this, i)); | ||
200 | - } | ||
201 | - } | ||
202 | - } | 205 | + if (min == max) |
206 | + fd__constraint_set_entailed(this); | ||
203 | } | 207 | } |
204 | 208 | ||
205 | #ifdef CONSTRAINT_TEMPS | 209 | #ifdef CONSTRAINT_TEMPS |
@@ -226,6 +230,7 @@ static int fd_poly_eq_propagate2(fd_constraint this, fd_int culprit) | @@ -226,6 +230,7 @@ static int fd_poly_eq_propagate2(fd_constraint this, fd_int culprit) | ||
226 | int *base; | 230 | int *base; |
227 | int x, c; | 231 | int x, c; |
228 | int nmin, nmin_x, nmax, nmax_x; | 232 | int nmin, nmin_x, nmax, nmax_x; |
233 | + int nlb, nub; | ||
229 | 234 | ||
230 | if (!fd__constraint_data_valid(this)) | 235 | if (!fd__constraint_data_valid(this)) |
231 | return fd_poly_eq_filter(this); // ignores culprit | 236 | return fd_poly_eq_filter(this); // ignores culprit |
@@ -237,16 +242,15 @@ static int fd_poly_eq_propagate2(fd_constraint this, fd_int culprit) | @@ -237,16 +242,15 @@ static int fd_poly_eq_propagate2(fd_constraint this, fd_int culprit) | ||
237 | mins = base + 4; | 242 | mins = base + 4; |
238 | maxs = mins + terms; | 243 | maxs = mins + terms; |
239 | 244 | ||
240 | - lb = *base; | ||
241 | - ub = *(base + 1); | 245 | + nlb = lb = *base; |
246 | + nub = ub = *(base + 1); | ||
242 | 247 | ||
243 | - min = *(base + 2); | ||
244 | - max = *(base + 3); | 248 | + nmin = min = *(base + 2); |
249 | + nmax = max = *(base + 3); | ||
245 | 250 | ||
246 | if (culprit == VAR(this, this->nvariables - 1)) | 251 | if (culprit == VAR(this, this->nvariables - 1)) |
247 | { | 252 | { |
248 | // the culprit is the sum variable | 253 | // the culprit is the sum variable |
249 | - int nlb, nub; | ||
250 | 254 | ||
251 | nlb = _fd_var_min(culprit); | 255 | nlb = _fd_var_min(culprit); |
252 | nub = _fd_var_max(culprit); | 256 | nub = _fd_var_max(culprit); |
@@ -254,203 +258,205 @@ static int fd_poly_eq_propagate2(fd_constraint this, fd_int culprit) | @@ -254,203 +258,205 @@ static int fd_poly_eq_propagate2(fd_constraint this, fd_int culprit) | ||
254 | if (nlb == lb && nub == ub) | 258 | if (nlb == lb && nub == ub) |
255 | return FD_OK; | 259 | return FD_OK; |
256 | 260 | ||
257 | - if (nlb != lb) | ||
258 | - { | ||
259 | - if (max < nlb) | ||
260 | - return FD_NOSOLUTION; | 261 | + if (min > nub || max < nlb) |
262 | + return FD_NOSOLUTION; | ||
263 | + } | ||
264 | + else | ||
265 | + { | ||
266 | + // the culprit appears in one of the terms, find out which one(s) | ||
267 | + for (x = 0; culprit != VAR(this, x); ++x) | ||
268 | + ; | ||
261 | 269 | ||
262 | - if (max == nlb) | ||
263 | - for (i = 0; i < terms; ++i) | ||
264 | - { | ||
265 | - if (this->constants[i] > 0) | ||
266 | - { | ||
267 | - if (_fd_var_del_lt(maxs[i], VAR(this, i))) | ||
268 | - { | ||
269 | - if (fd_domain_empty(VAR(this, i))) | ||
270 | - return FD_NOSOLUTION; | 270 | + nmin_x = _fd_var_min(VAR(this, x)); |
271 | + nmax_x = _fd_var_max(VAR(this, x)); | ||
271 | 272 | ||
272 | - _fd_revise_connected(this, VAR(this, i)); | ||
273 | - } | ||
274 | - } | ||
275 | - else if (this->constants[i] < 0) | ||
276 | - { | ||
277 | - if (_fd_var_del_gt(mins[i], VAR(this, i))) | ||
278 | - { | ||
279 | - if (fd_domain_empty(VAR(this, i))) | ||
280 | - return FD_NOSOLUTION; | 273 | + if (nmin_x == mins[x] && nmax_x == maxs[x]) |
274 | + return FD_OK; | ||
281 | 275 | ||
282 | - _fd_revise_connected(this, VAR(this, i)); | ||
283 | - } | ||
284 | - } | ||
285 | - } | 276 | + do |
277 | + { | ||
278 | + c = this->constants[x]; | ||
279 | + | ||
280 | + if (c > 0) | ||
281 | + { | ||
282 | + nmin = nmin + (nmin_x - mins[x]) * c; | ||
283 | + nmax = nmax - (maxs[x] - nmax_x) * c; | ||
284 | + } | ||
285 | + else if (c < 0) | ||
286 | + { | ||
287 | + nmin = nmin - (maxs[x] - nmax_x) * c; | ||
288 | + nmax = nmax + (nmin_x - mins[x]) * c; | ||
289 | + } | ||
290 | + | ||
291 | + if (nmin > ub || nmax < lb) | ||
292 | + return FD_NOSOLUTION; | ||
286 | 293 | ||
287 | - if (min < nlb) | ||
288 | - for (i = 0; i < terms; ++i) | ||
289 | - { | ||
290 | - int c = this->constants[i]; | ||
291 | - int xmin = mins[i]; | ||
292 | - int xmax = maxs[i]; | 294 | + mins[x] = nmin_x; |
295 | + maxs[x] = nmax_x; | ||
293 | 296 | ||
294 | - if (c > 0) | ||
295 | - { | ||
296 | - if ((xmax - xmin) * c > max - nlb) | ||
297 | - { | ||
298 | - // xmin = ceil((nlb - max) / c) + xmax | ||
299 | - xmin = (nlb - max) / c + xmax; | 297 | + while (++x < terms && culprit != VAR(this, x)) |
298 | + ; | ||
299 | + } | ||
300 | + while (x < terms); | ||
300 | 301 | ||
301 | - _fd_var_del_lt(xmin, VAR(this, i)); | 302 | + if (nmin == min && nmax == max) |
303 | + return FD_OK; | ||
302 | 304 | ||
303 | - if (fd_domain_empty(VAR(this, i))) // domains may have holes | ||
304 | - return FD_NOSOLUTION; | 305 | + if (nmin > lb) |
306 | + { | ||
307 | + fd_update_domain_and_check(del_lt, nmin, VAR(this, this->nvariables - 1)); | ||
305 | 308 | ||
306 | - _fd_revise_connected(this, VAR(this, i)); | ||
307 | - } | ||
308 | - } | ||
309 | - else if (c < 0) | ||
310 | - { | ||
311 | - if ((xmax - xmin) * c < nlb - max) | ||
312 | - { | ||
313 | - // xmax = floor((nlb - max) / c) + xmin | ||
314 | - xmax = (nlb - max) / c + xmin; | 309 | + nlb = nmin; |
310 | + } | ||
315 | 311 | ||
316 | - _fd_var_del_gt(xmax, VAR(this, i)); | 312 | + if (nmax < ub) |
313 | + { | ||
314 | + fd_update_domain_and_check(del_gt, nmax, VAR(this, this->nvariables - 1)); | ||
317 | 315 | ||
318 | - if (fd_domain_empty(VAR(this, i))) // domains may have holes | ||
319 | - return FD_NOSOLUTION; | 316 | + nub = nmax; |
317 | + } | ||
318 | + } | ||
320 | 319 | ||
321 | - _fd_revise_connected(this, VAR(this, i)); | ||
322 | - } | ||
323 | - } | ||
324 | - } | 320 | + // (nmin, nlb, nub, nmax) != (min, lb, ub, max) |
325 | 321 | ||
326 | - *base = nlb; | ||
327 | - } | 322 | + if (nmin == nmax) |
323 | + { | ||
324 | + fd__constraint_set_entailed(this); | ||
325 | + } | ||
326 | + else | ||
327 | + { | ||
328 | + // bounds domain propagation | ||
329 | + // XXX: number of iterations depends on the size of the domains | ||
328 | 330 | ||
329 | - if (nub != ub) | ||
330 | - { | ||
331 | - if (min > nub) | ||
332 | - return FD_NOSOLUTION; | 331 | + int onmin, onmax; |
333 | 332 | ||
334 | - if (min == nub) | 333 | + do { |
334 | + onmin = nmin; | ||
335 | + onmax = nmax; | ||
336 | + | ||
337 | + if (nmin < nlb) | ||
338 | + { | ||
335 | for (i = 0; i < terms; ++i) | 339 | for (i = 0; i < terms; ++i) |
336 | { | 340 | { |
337 | - if (this->constants[i] > 0) | 341 | + int c = this->constants[i]; |
342 | + int imin = mins[i]; | ||
343 | + int imax = maxs[i]; | ||
344 | + | ||
345 | + if (c == 0 || imin == imax) continue; | ||
346 | + | ||
347 | + if (c > 0) | ||
338 | { | 348 | { |
339 | - if (_fd_var_del_gt(mins[i], VAR(this, i))) | 349 | + // enforce max(sum{j!=i}(c[j] * x[j])) + c[i] * min[i] >= min[y] |
350 | + | ||
351 | + if (nmax + (imin - imax) * c < nlb) | ||
340 | { | 352 | { |
341 | - if (fd_domain_empty(VAR(this, i))) | ||
342 | - return FD_NOSOLUTION; | 353 | + // imin = ceil((nlb - nmax) / c) + imax |
354 | + imin = (nlb - nmax) / c + imax; | ||
355 | + | ||
356 | + fd_update_domain_and_check(del_lt, imin, VAR(this, i)); | ||
357 | + | ||
358 | + nmin += (imin - mins[i]) * c; | ||
343 | 359 | ||
344 | - _fd_revise_connected(this, VAR(this, i)); | 360 | + mins[i] = imin; |
345 | } | 361 | } |
346 | } | 362 | } |
347 | - else if (this->constants[i] < 0) | 363 | + else |
348 | { | 364 | { |
349 | - if (_fd_var_del_lt(maxs[i], VAR(this, i))) | 365 | + // enforce max(sum{j!=i}(c[j] * x[j])) + c[i] * max[i] >= min[y] |
366 | + | ||
367 | + if (nmax + (imax - imin) * c < nlb) | ||
350 | { | 368 | { |
351 | - if (fd_domain_empty(VAR(this, i))) | ||
352 | - return FD_NOSOLUTION; | 369 | + // imax = floor((nlb - nmax) / c) + imin |
370 | + imax = (nlb - nmax) / c + imin; | ||
371 | + | ||
372 | + fd_update_domain_and_check(del_gt, imax, VAR(this, i)); | ||
353 | 373 | ||
354 | - _fd_revise_connected(this, VAR(this, i)); | 374 | + nmin += (imax - maxs[i]) * c; |
375 | + | ||
376 | + maxs[i] = imax; | ||
355 | } | 377 | } |
356 | } | 378 | } |
357 | } | 379 | } |
358 | 380 | ||
359 | - if (max > nub) | ||
360 | - for (i = 0; i < terms; ++i) | ||
361 | - { | ||
362 | - int c = this->constants[i]; | ||
363 | - int xmin = mins[i]; | ||
364 | - int xmax = maxs[i]; | 381 | + if (nmin > nub) |
382 | + return FD_NOSOLUTION; | ||
383 | + } | ||
365 | 384 | ||
366 | - if (c > 0) | 385 | + if (nmax > nub) |
386 | + { | ||
387 | + for (i = 0; i < terms; ++i) | ||
367 | { | 388 | { |
368 | - if ((xmax - xmin) * c > nub - min) | 389 | + int c = this->constants[i]; |
390 | + int imin = mins[i]; | ||
391 | + int imax = maxs[i]; | ||
392 | + | ||
393 | + if (c == 0 || imin == imax) continue; | ||
394 | + | ||
395 | + if (c > 0) | ||
369 | { | 396 | { |
370 | - // xmax = floor((nub - min) / c) + xmin | ||
371 | - xmax = (nub - min) / c + xmin; | 397 | + // enforce min(sum{j!=i}(c[j] * x[j])) + c[i] * max[i] <= max[y] |
372 | 398 | ||
373 | - if (_fd_var_del_gt(xmax, VAR(this, i))) | 399 | + if (nmin + (imax - imin) * c > nub) |
374 | { | 400 | { |
375 | - if (fd_domain_empty(VAR(this, i))) | ||
376 | - return FD_NOSOLUTION; | 401 | + // imax = floor((nub - nmin) / c) + imin |
402 | + imax = (nub - nmin) / c + imin; | ||
377 | 403 | ||
378 | - _fd_revise_connected(this, VAR(this, i)); | 404 | + fd_update_domain_and_check(del_gt, imax, VAR(this, i)); |
405 | + | ||
406 | + nmax -= (maxs[i] - imax) * c; | ||
407 | + | ||
408 | + maxs[i] = imax; | ||
379 | } | 409 | } |
380 | } | 410 | } |
381 | - } | ||
382 | - else if (c < 0) | ||
383 | - { | ||
384 | - if ((xmin - xmax) * c > nub - min) | 411 | + else |
385 | { | 412 | { |
386 | - // xmin = ceil((nub - min) / c) + xmax | ||
387 | - xmin = (nub - min) / c + xmax; | 413 | + // enforce min(sum{j!=i}(c[j] * x[j])) + c[i] * min[i] <= max[y] |
388 | 414 | ||
389 | - if (_fd_var_del_lt(xmin, VAR(this, i))) | 415 | + if (nmin + (imin - imax) * c > nub) |
390 | { | 416 | { |
391 | - if (fd_domain_empty(VAR(this, i))) | ||
392 | - return FD_NOSOLUTION; | 417 | + // imin = ceil((nub - nmin) / c) + imax |
418 | + imin = (nub - nmin) / c + imax; | ||
419 | + | ||
420 | + fd_update_domain_and_check(del_lt, imin, VAR(this, i)); | ||
393 | 421 | ||
394 | - _fd_revise_connected(this, VAR(this, i)); | 422 | + nmax -= (mins[i] - imin) * c; |
423 | + | ||
424 | + mins[i] = imin; | ||
395 | } | 425 | } |
396 | } | 426 | } |
397 | } | 427 | } |
398 | - } | ||
399 | - | ||
400 | - *(base + 1) = nub; | ||
401 | - } | ||
402 | - | ||
403 | - return FD_OK; | ||
404 | - } | ||
405 | - | ||
406 | - // the culprit appears in one of the terms, find out which one(s) | ||
407 | - for (x = 0; culprit != VAR(this, x); ++x) | ||
408 | - ; | ||
409 | - | ||
410 | - nmin_x = _fd_var_min(VAR(this, x)); | ||
411 | - nmax_x = _fd_var_max(VAR(this, x)); | ||
412 | - | ||
413 | - if (nmin_x == mins[x] && nmax_x == maxs[x]) | ||
414 | - return FD_OK; | ||
415 | 428 | ||
416 | - nmin = min; | ||
417 | - nmax = max; | 429 | + if (nmax < nlb) |
430 | + return FD_NOSOLUTION; | ||
431 | + } | ||
418 | 432 | ||
419 | - do | ||
420 | - { | ||
421 | - c = this->constants[x]; | 433 | + if (nmin > nlb && _fd_var_del_lt(nmin, VAR(this, this->nvariables - 1))) |
434 | + { | ||
435 | + if (fd_domain_empty(VAR(this, this->nvariables - 1))) | ||
436 | + return FD_NOSOLUTION; | ||
422 | 437 | ||
423 | - if (c > 0) | ||
424 | - { | ||
425 | - nmin = nmin + (nmin_x - mins[x]) * c; | ||
426 | - nmax = nmax - (maxs[x] - nmax_x) * c; | ||
427 | - } | ||
428 | - else if (c < 0) | ||
429 | - { | ||
430 | - nmin = nmin - (maxs[x] - nmax_x) * c; | ||
431 | - nmax = nmax + (nmin_x - mins[x]) * c; | ||
432 | - } | 438 | + _fd_revise_connected(this, VAR(this, this->nvariables - 1)); |
433 | 439 | ||
434 | - if (nmin > ub || nmax < lb) | ||
435 | - return FD_NOSOLUTION; | 440 | + nlb = nmin; |
441 | + } | ||
436 | 442 | ||
437 | - mins[x] = nmin_x; | ||
438 | - maxs[x] = nmax_x; | 443 | + if (nmax < nub && _fd_var_del_gt(nmax, VAR(this, this->nvariables - 1))) |
444 | + { | ||
445 | + if (fd_domain_empty(VAR(this, this->nvariables - 1))) | ||
446 | + return FD_NOSOLUTION; | ||
439 | 447 | ||
440 | - while (++x < terms && culprit != VAR(this, x)) | ||
441 | - ; | ||
442 | - } | ||
443 | - while (x < terms); | 448 | + _fd_revise_connected(this, VAR(this, this->nvariables - 1)); |
444 | 449 | ||
445 | - if ((nmin > lb && _fd_var_del_lt(nmin, VAR(this, this->nvariables - 1))) | | ||
446 | - (nmax < ub && _fd_var_del_gt(nmax, VAR(this, this->nvariables - 1)))) | ||
447 | - { | ||
448 | - if (fd_domain_empty(VAR(this, this->nvariables - 1))) | ||
449 | - return FD_NOSOLUTION; | 450 | + nub = nmax; |
451 | + } | ||
452 | + } while (nmin != nmax && (nmin != onmin || nmax != onmax)); | ||
450 | 453 | ||
451 | - _fd_revise_connected(this, VAR(this, this->nvariables - 1)); | 454 | + if (nmin == nmax) |
455 | + fd__constraint_set_entailed(this); | ||
452 | } | 456 | } |
453 | 457 | ||
458 | + *(base + 0) = nlb; | ||
459 | + *(base + 1) = nub; | ||
454 | *(base + 2) = nmin; | 460 | *(base + 2) = nmin; |
455 | *(base + 3) = nmax; | 461 | *(base + 3) = nmax; |
456 | 462 | ||
@@ -462,8 +468,15 @@ static int fd_poly_eq_propagate2(fd_constraint this, fd_int culprit) | @@ -462,8 +468,15 @@ static int fd_poly_eq_propagate2(fd_constraint this, fd_int culprit) | ||
462 | 468 | ||
463 | fd_constraint fd_poly_eq(int cs[], fd_int xs[], int nterms, fd_int y) | 469 | fd_constraint fd_poly_eq(int cs[], fd_int xs[], int nterms, fd_int y) |
464 | { | 470 | { |
465 | - fd_constraint c = _fd_constraint_new(nterms + 1, nterms); | ||
466 | - int i; | 471 | + fd_constraint fd_poly_eq_k(int[], fd_int[], int, int); |
472 | + fd_constraint c; | ||
473 | + int i, k; | ||
474 | + | ||
475 | + // specialise when y is a singleton | ||
476 | + if (fd_var_single(y, &k)) | ||
477 | + return fd_poly_eq_k(cs, xs, nterms, k); | ||
478 | + | ||
479 | + c = fd__constraint_new(nterms + 1, nterms); | ||
467 | 480 | ||
468 | if (c) | 481 | if (c) |
469 | { | 482 | { |
@@ -472,11 +485,8 @@ fd_constraint fd_poly_eq(int cs[], fd_int xs[], int nterms, fd_int y) | @@ -472,11 +485,8 @@ fd_constraint fd_poly_eq(int cs[], fd_int xs[], int nterms, fd_int y) | ||
472 | c->variables[nterms] = FD_INT2C_VAR(y); | 485 | c->variables[nterms] = FD_INT2C_VAR(y); |
473 | for (i = 0; i < nterms; ++i) | 486 | for (i = 0; i < nterms; ++i) |
474 | c->constants[i] = cs[i]; | 487 | c->constants[i] = cs[i]; |
475 | -#ifdef CONSTRAINT_CLASS | 488 | + |
476 | c->kind = FD_CONSTR_POLY_EQ; | 489 | c->kind = FD_CONSTR_POLY_EQ; |
477 | -#else /* CONSTRAINT_CLASS */ | ||
478 | - c->propagator2 = fd_poly_eq_propagate2; | ||
479 | -#endif /* CONSTRAINT_CLASS */ | ||
480 | 490 | ||
481 | for (i = 0; i < c->nvariables; ++i) | 491 | for (i = 0; i < c->nvariables; ++i) |
482 | _fd_var_add_constraint(VAR(c, i), c); | 492 | _fd_var_add_constraint(VAR(c, i), c); |
@@ -0,0 +1,346 @@ | @@ -0,0 +1,346 @@ | ||
1 | +/* poly-le-k(C, X, k) == sum(C . X) <= k */ | ||
2 | + | ||
3 | +static int fd_poly_le_k_filter(fd_constraint this) | ||
4 | +{ | ||
5 | + int k; | ||
6 | + int min, max; | ||
7 | + int terms = this->nvariables; | ||
8 | + int *mins, *maxs; | ||
9 | + int i; | ||
10 | +#ifdef CONSTRAINT_TEMPS | ||
11 | + int *base; | ||
12 | + | ||
13 | + assert(!fd__constraint_data_valid(this)); | ||
14 | + | ||
15 | + if (!constraint_memory[this->index]) | ||
16 | + constraint_memory[this->index] = malloc((2 * terms + 2) * sizeof(int)); | ||
17 | + | ||
18 | + base = constraint_memory[this->index]; | ||
19 | + | ||
20 | + mins = base + 2; | ||
21 | + maxs = mins + terms; | ||
22 | +#else | ||
23 | + mins = alloca(terms * sizeof(*mins)); | ||
24 | + maxs = alloca(terms * sizeof(*maxs)); | ||
25 | +#endif | ||
26 | + | ||
27 | + k = this->constants[terms]; | ||
28 | + | ||
29 | + // sum the minima and the maxima of the terms | ||
30 | + min = max = 0; | ||
31 | + | ||
32 | + for (i = 0; i < terms; ++i) | ||
33 | + { | ||
34 | + int vl, vh; | ||
35 | + | ||
36 | + if (this->constants[i] > 0) | ||
37 | + { | ||
38 | + vl = mins[i] = _fd_var_min(VAR(this, i)); | ||
39 | + vh = maxs[i] = _fd_var_max(VAR(this, i)); | ||
40 | + } | ||
41 | + else | ||
42 | + { | ||
43 | + vl = maxs[i] = _fd_var_max(VAR(this, i)); | ||
44 | + vh = mins[i] = _fd_var_min(VAR(this, i)); | ||
45 | + } | ||
46 | + | ||
47 | + min += this->constants[i] * vl; | ||
48 | + max += this->constants[i] * vh; | ||
49 | + } | ||
50 | + | ||
51 | + if (min > k) | ||
52 | + return FD_NOSOLUTION; | ||
53 | + | ||
54 | + if (max <= k) | ||
55 | + { | ||
56 | + fd__constraint_set_entailed(this); | ||
57 | + } | ||
58 | + else if (min == k) | ||
59 | + { | ||
60 | + for (i = 0; i < terms; ++i) | ||
61 | + { | ||
62 | + int c = this->constants[i]; | ||
63 | + | ||
64 | + if (c == 0 || mins[i] == maxs[i]) continue; | ||
65 | + | ||
66 | + if (c > 0) | ||
67 | + { | ||
68 | + _fd_var_del_gt(mins[i], VAR(this, i)); | ||
69 | + | ||
70 | + // check needed for when variables occur more than once | ||
71 | + // and with opposite signs | ||
72 | + if (fd_domain_empty(VAR(this, i))) | ||
73 | + return FD_NOSOLUTION; | ||
74 | + | ||
75 | + _fd_revise_connected(this, VAR(this, i)); | ||
76 | + | ||
77 | + maxs[i] = mins[i]; | ||
78 | + } | ||
79 | + else | ||
80 | + { | ||
81 | + _fd_var_del_lt(maxs[i], VAR(this, i)); | ||
82 | + | ||
83 | + // check needed for when variables occur more than once | ||
84 | + // and with opposite signs | ||
85 | + if (fd_domain_empty(VAR(this, i))) | ||
86 | + return FD_NOSOLUTION; | ||
87 | + | ||
88 | + _fd_revise_connected(this, VAR(this, i)); | ||
89 | + | ||
90 | + mins[i] = maxs[i]; | ||
91 | + } | ||
92 | + } | ||
93 | + | ||
94 | + max = min; | ||
95 | + | ||
96 | + fd__constraint_set_entailed(this); | ||
97 | + } | ||
98 | + else // max > k | ||
99 | + { | ||
100 | + // bounds domain filtering | ||
101 | + | ||
102 | + for (i = 0; i < terms; ++i) | ||
103 | + { | ||
104 | + int c = this->constants[i]; | ||
105 | + int imin = mins[i]; | ||
106 | + int imax = maxs[i]; | ||
107 | + | ||
108 | + if (c > 0) | ||
109 | + { | ||
110 | + // enforce min(sum{j!=i}(c[j] * x[j])) + c[i] * max[i] <= k | ||
111 | + | ||
112 | + if (min + (imax - imin) * c > k) | ||
113 | + { | ||
114 | + // max[i] = floor((k - min) / c[i]) + min[i] | ||
115 | + imax = (k - min) / c + imin; | ||
116 | + | ||
117 | + _fd_var_del_gt(imax, VAR(this, i)); | ||
118 | + | ||
119 | + if (fd_domain_empty(VAR(this, i))) | ||
120 | + return FD_NOSOLUTION; | ||
121 | + | ||
122 | + _fd_revise_connected(this, VAR(this, i)); | ||
123 | + | ||
124 | + max -= (maxs[i] - imax) * c; | ||
125 | + | ||
126 | + maxs[i] = imax; | ||
127 | + } | ||
128 | + } | ||
129 | + else // c < 0 (does nothing if c is 0) | ||
130 | + { | ||
131 | + // enforce min(sum{j!=i}(c[j] * x[j])) + c[i] * min[i] <= k | ||
132 | + | ||
133 | + if (min + (imin - imax) * c > k) | ||
134 | + { | ||
135 | + // min[i] = ceil((k - min) / c[i]) + max[i] | ||
136 | + imin = (k - min) / c + imax; | ||
137 | + | ||
138 | + _fd_var_del_lt(imin, VAR(this, i)); | ||
139 | + | ||
140 | + if (fd_domain_empty(VAR(this, i))) | ||
141 | + return FD_NOSOLUTION; | ||
142 | + | ||
143 | + _fd_revise_connected(this, VAR(this, i)); | ||
144 | + | ||
145 | + max -= (mins[i] - imin) * c; | ||
146 | + | ||
147 | + mins[i] = imin; | ||
148 | + } | ||
149 | + } | ||
150 | + } | ||
151 | + | ||
152 | + if (max <= k) | ||
153 | + fd__constraint_set_entailed(this); | ||
154 | + } | ||
155 | + | ||
156 | +#ifdef CONSTRAINT_TEMPS | ||
157 | + // save values | ||
158 | + *base = min; | ||
159 | + *(base + 1) = max; | ||
160 | + | ||
161 | + fd__constraint_remember(this); | ||
162 | +#endif | ||
163 | + | ||
164 | + return FD_OK; | ||
165 | +} | ||
166 | + | ||
167 | +static int fd_poly_le_k_propagate2(fd_constraint this, fd_int culprit) | ||
168 | +{ | ||
169 | +#ifdef CONSTRAINT_TEMPS | ||
170 | + int k; | ||
171 | + int min, max; | ||
172 | + int terms = this->nvariables; | ||
173 | + int *mins, *maxs; | ||
174 | + int i; | ||
175 | + int *base; | ||
176 | + int x, c; | ||
177 | + int nmin, nmin_x, nmax, nmax_x; | ||
178 | + | ||
179 | + if (!fd__constraint_data_valid(this)) | ||
180 | + return fd_poly_le_k_filter(this); // ignores culprit | ||
181 | + | ||
182 | + // bounds filtering | ||
183 | + | ||
184 | + base = constraint_memory[this->index]; | ||
185 | + | ||
186 | + mins = base + 2; | ||
187 | + maxs = mins + terms; | ||
188 | + | ||
189 | + min = *base; | ||
190 | + max = *(base + 1); | ||
191 | + | ||
192 | + k = this->constants[terms]; | ||
193 | + | ||
194 | + // find the (first) term where the culprit appears | ||
195 | + for (x = 0; culprit != VAR(this, x); ++x) | ||
196 | + ; | ||
197 | + | ||
198 | + nmin_x = _fd_var_min(VAR(this, x)); | ||
199 | + nmax_x = _fd_var_max(VAR(this, x)); | ||
200 | + | ||
201 | + if (nmin_x == mins[x] && nmax_x == maxs[x]) | ||
202 | + return FD_OK; | ||
203 | + | ||
204 | + nmin = min; | ||
205 | + nmax = max; | ||
206 | + | ||
207 | + do | ||
208 | + { | ||
209 | + c = this->constants[x]; | ||
210 | + | ||
211 | + if (c > 0) | ||
212 | + { | ||
213 | + nmin = nmin + (nmin_x - mins[x]) * c; | ||
214 | + nmax = nmax - (maxs[x] - nmax_x) * c; | ||
215 | + } | ||
216 | + else if (c < 0) | ||
217 | + { | ||
218 | + nmin = nmin - (maxs[x] - nmax_x) * c; | ||
219 | + nmax = nmax + (nmin_x - mins[x]) * c; | ||
220 | + } | ||
221 | + | ||
222 | + if (nmin > k) | ||
223 | + return FD_NOSOLUTION; | ||
224 | + | ||
225 | + mins[x] = nmin_x; | ||
226 | + maxs[x] = nmax_x; | ||
227 | + | ||
228 | + // search for the next term where the culprit appears | ||
229 | + while (++x < terms && culprit != VAR(this, x)) | ||
230 | + ; | ||
231 | + } | ||
232 | + while (x < terms); | ||
233 | + | ||
234 | + if (nmin == min && nmax == max) | ||
235 | + return FD_OK; | ||
236 | + | ||
237 | + if (nmax <= k) | ||
238 | + { | ||
239 | + fd__constraint_set_entailed(this); | ||
240 | + } | ||
241 | + else if (nmin == k) | ||
242 | + { | ||
243 | + for (i = 0; i < terms; ++i) | ||
244 | + { | ||
245 | + int c = this->constants[i]; | ||
246 | + | ||
247 | + if (c == 0 || mins[i] == maxs[i]) continue; | ||
248 | + | ||
249 | + if (c > 0) | ||
250 | + { | ||
251 | + fd_update_domain_and_check(del_gt, mins[i], VAR(this, i)); | ||
252 | + | ||
253 | + maxs[i] = mins[i]; | ||
254 | + } | ||
255 | + else | ||
256 | + { | ||
257 | + fd_update_domain_and_check(del_lt, maxs[i], VAR(this, i)); | ||
258 | + | ||
259 | + mins[i] = maxs[i]; | ||
260 | + } | ||
261 | + } | ||
262 | + | ||
263 | + nmax = nmin; | ||
264 | + | ||
265 | + fd__constraint_set_entailed(this); | ||
266 | + } | ||
267 | + else if (nmin > min) // nmax > k | ||
268 | + { | ||
269 | + // bounds domain propagation | ||
270 | + | ||
271 | + for (i = 0; i < terms; ++i) | ||
272 | + { | ||
273 | + int c = this->constants[i]; | ||
274 | + int imin = mins[i]; | ||
275 | + int imax = maxs[i]; | ||
276 | + | ||
277 | + if (c > 0) | ||
278 | + { | ||
279 | + // enforce min(sum{j!=i}(c[j] * x[j])) + c[i] * max[i] <= k | ||
280 | + | ||
281 | + if (nmin + (imax - imin) * c > k) | ||
282 | + { | ||
283 | + // max[i] = floor((k - nmin) / c[i]) + min[i] | ||
284 | + imax = (k - nmin) / c + imin; | ||
285 | + | ||
286 | + fd_update_domain_and_check(del_gt, imax, VAR(this, i)); | ||
287 | + | ||
288 | + nmax -= (maxs[i] - imax) * c; | ||
289 | + | ||
290 | + maxs[i] = imax; | ||
291 | + } | ||
292 | + } | ||
293 | + else // c < 0 (does nothing if c is 0) | ||
294 | + { | ||
295 | + // enforce min(sum{j!=i}(c[j] * x[j])) + c[i] * min[i] <= k | ||
296 | + | ||
297 | + if (nmin + (imin - imax) * c > k) | ||
298 | + { | ||
299 | + // min[i] = ceil((k - nmin) / c[i]) + max[i] | ||
300 | + imin = (k - nmin) / c + imax; | ||
301 | + | ||
302 | + fd_update_domain_and_check(del_lt, imin, VAR(this, i)); | ||
303 | + | ||
304 | + nmax -= (mins[i] - imin) * c; | ||
305 | + | ||
306 | + mins[i] = imin; | ||
307 | + } | ||
308 | + } | ||
309 | + } | ||
310 | + | ||
311 | + if (nmax <= k) | ||
312 | + fd__constraint_set_entailed(this); | ||
313 | + } | ||
314 | + | ||
315 | + *base = nmin; | ||
316 | + *(base + 1) = nmax; | ||
317 | + | ||
318 | + return FD_OK; | ||
319 | +#else /* CONSTRAINT_TEMPS */ | ||
320 | + return fd_poly_le_k_filter(this); // ignores culprit | ||
321 | +#endif /* CONSTRAINT_TEMPS */ | ||
322 | +} | ||
323 | + | ||
324 | +fd_constraint fd_poly_le_k(int cs[], fd_int xs[], int nterms, int k) | ||
325 | +{ | ||
326 | + fd_constraint c = fd__constraint_new(nterms, nterms + 1); | ||
327 | + int i; | ||
328 | + | ||
329 | + if (c) | ||
330 | + { | ||
331 | + for (i = 0; i < nterms; ++i) | ||
332 | + c->variables[i] = FD_INT2C_VAR(xs[i]); | ||
333 | + for (i = 0; i < nterms; ++i) | ||
334 | + c->constants[i] = cs[i]; | ||
335 | + c->constants[nterms] = k; | ||
336 | + | ||
337 | + c->kind = FD_CONSTR_POLY_LE_K; | ||
338 | + | ||
339 | + for (i = 0; i < c->nvariables; ++i) | ||
340 | + _fd_var_add_constraint(VAR(c, i), c); | ||
341 | + | ||
342 | + _fd_add_constraint(c); | ||
343 | + } | ||
344 | + | ||
345 | + return c; | ||
346 | +} |
src/constraints/poly-ne-k.c
@@ -199,11 +199,13 @@ static int fd_poly_ne_k_propagate2(fd_constraint this, fd_int culprit) | @@ -199,11 +199,13 @@ static int fd_poly_ne_k_propagate2(fd_constraint this, fd_int culprit) | ||
199 | if (this->constants[i] && mins[i] != maxs[i]) | 199 | if (this->constants[i] && mins[i] != maxs[i]) |
200 | break; | 200 | break; |
201 | 201 | ||
202 | + // m = sum{j != i} c[j] * x[j] | ||
202 | if (this->constants[i] > 0) | 203 | if (this->constants[i] > 0) |
203 | - m = min - this->constants[i] * mins[i]; | 204 | + m = nmin - this->constants[i] * mins[i]; |
204 | else | 205 | else |
205 | - m = min - this->constants[i] * maxs[i]; | 206 | + m = nmin - this->constants[i] * maxs[i]; |
206 | 207 | ||
208 | + // v * c[i] + m = k (if v were a real value) | ||
207 | v = (k - m) / this->constants[i]; | 209 | v = (k - m) / this->constants[i]; |
208 | 210 | ||
209 | if (v * this->constants[i] + m == k) | 211 | if (v * this->constants[i] + m == k) |
@@ -224,7 +226,7 @@ static int fd_poly_ne_k_propagate2(fd_constraint this, fd_int culprit) | @@ -224,7 +226,7 @@ static int fd_poly_ne_k_propagate2(fd_constraint this, fd_int culprit) | ||
224 | 226 | ||
225 | fd_constraint fd_poly_ne_k(int cs[], fd_int xs[], int nterms, int k) | 227 | fd_constraint fd_poly_ne_k(int cs[], fd_int xs[], int nterms, int k) |
226 | { | 228 | { |
227 | - fd_constraint c = _fd_constraint_new(nterms, nterms + 1); | 229 | + fd_constraint c = fd__constraint_new(nterms, nterms + 1); |
228 | int i; | 230 | int i; |
229 | 231 | ||
230 | if (c) | 232 | if (c) |
@@ -234,11 +236,8 @@ fd_constraint fd_poly_ne_k(int cs[], fd_int xs[], int nterms, int k) | @@ -234,11 +236,8 @@ fd_constraint fd_poly_ne_k(int cs[], fd_int xs[], int nterms, int k) | ||
234 | for (i = 0; i < nterms; ++i) | 236 | for (i = 0; i < nterms; ++i) |
235 | c->constants[i] = cs[i]; | 237 | c->constants[i] = cs[i]; |
236 | c->constants[nterms] = k; | 238 | c->constants[nterms] = k; |
237 | -#ifdef CONSTRAINT_CLASS | 239 | + |
238 | c->kind = FD_CONSTR_POLY_NE_K; | 240 | c->kind = FD_CONSTR_POLY_NE_K; |
239 | -#else /* CONSTRAINT_CLASS */ | ||
240 | - c->propagator2 = fd_poly_ne_k_propagate2; | ||
241 | -#endif /* CONSTRAINT_CLASS */ | ||
242 | 241 | ||
243 | for (i = 0; i < c->nvariables; ++i) | 242 | for (i = 0; i < c->nvariables; ++i) |
244 | _fd_var_add_constraint(VAR(c, i), c); | 243 | _fd_var_add_constraint(VAR(c, i), c); |
src/constraints/poly-ne.c
@@ -237,11 +237,13 @@ static int fd_poly_ne_propagate2(fd_constraint this, fd_int culprit) | @@ -237,11 +237,13 @@ static int fd_poly_ne_propagate2(fd_constraint this, fd_int culprit) | ||
237 | if (this->constants[i] && mins[i] != maxs[i]) | 237 | if (this->constants[i] && mins[i] != maxs[i]) |
238 | break; | 238 | break; |
239 | 239 | ||
240 | + // m = sum{j != i} c[j] * x[j] | ||
240 | if (this->constants[i] > 0) | 241 | if (this->constants[i] > 0) |
241 | - m = min - this->constants[i] * mins[i]; | 242 | + m = nmin - this->constants[i] * mins[i]; |
242 | else | 243 | else |
243 | - m = min - this->constants[i] * maxs[i]; | 244 | + m = nmin - this->constants[i] * maxs[i]; |
244 | 245 | ||
246 | + // v * c[i] + m = y (if v were a real value) | ||
245 | v = (lb - m) / this->constants[i]; | 247 | v = (lb - m) / this->constants[i]; |
246 | 248 | ||
247 | if (v * this->constants[i] + m == lb) | 249 | if (v * this->constants[i] + m == lb) |
@@ -262,7 +264,7 @@ static int fd_poly_ne_propagate2(fd_constraint this, fd_int culprit) | @@ -262,7 +264,7 @@ static int fd_poly_ne_propagate2(fd_constraint this, fd_int culprit) | ||
262 | 264 | ||
263 | fd_constraint fd_poly_ne(int cs[], fd_int xs[], int nterms, fd_int y) | 265 | fd_constraint fd_poly_ne(int cs[], fd_int xs[], int nterms, fd_int y) |
264 | { | 266 | { |
265 | - fd_constraint c = _fd_constraint_new(nterms + 1, nterms); | 267 | + fd_constraint c = fd__constraint_new(nterms + 1, nterms); |
266 | int i; | 268 | int i; |
267 | 269 | ||
268 | if (c) | 270 | if (c) |
@@ -272,11 +274,8 @@ fd_constraint fd_poly_ne(int cs[], fd_int xs[], int nterms, fd_int y) | @@ -272,11 +274,8 @@ fd_constraint fd_poly_ne(int cs[], fd_int xs[], int nterms, fd_int y) | ||
272 | c->variables[nterms] = FD_INT2C_VAR(y); | 274 | c->variables[nterms] = FD_INT2C_VAR(y); |
273 | for (i = 0; i < nterms; ++i) | 275 | for (i = 0; i < nterms; ++i) |
274 | c->constants[i] = cs[i]; | 276 | c->constants[i] = cs[i]; |
275 | -#ifdef CONSTRAINT_CLASS | 277 | + |
276 | c->kind = FD_CONSTR_POLY_NE; | 278 | c->kind = FD_CONSTR_POLY_NE; |
277 | -#else /* CONSTRAINT_CLASS */ | ||
278 | - c->propagator2 = fd_poly_ne_propagate2; | ||
279 | -#endif /* CONSTRAINT_CLASS */ | ||
280 | 279 | ||
281 | for (i = 0; i < c->nvariables; ++i) | 280 | for (i = 0; i < c->nvariables; ++i) |
282 | _fd_var_add_constraint(VAR(c, i), c); | 281 | _fd_var_add_constraint(VAR(c, i), c); |
src/constraints/sum-prod.c
@@ -393,7 +393,7 @@ static int fd_sum_prod_propagate2(fd_constraint this, fd_int culprit) | @@ -393,7 +393,7 @@ static int fd_sum_prod_propagate2(fd_constraint this, fd_int culprit) | ||
393 | 393 | ||
394 | fd_constraint fd_sum_prod(fd_int *xs, fd_int *ys, int nvariables, int k) | 394 | fd_constraint fd_sum_prod(fd_int *xs, fd_int *ys, int nvariables, int k) |
395 | { | 395 | { |
396 | - fd_constraint c = _fd_constraint_new(2 * nvariables, 1); | 396 | + fd_constraint c = fd__constraint_new(2 * nvariables, 1); |
397 | int i; | 397 | int i; |
398 | 398 | ||
399 | if (c) | 399 | if (c) |
@@ -403,11 +403,8 @@ fd_constraint fd_sum_prod(fd_int *xs, fd_int *ys, int nvariables, int k) | @@ -403,11 +403,8 @@ fd_constraint fd_sum_prod(fd_int *xs, fd_int *ys, int nvariables, int k) | ||
403 | for (; i < 2 * nvariables; ++i) | 403 | for (; i < 2 * nvariables; ++i) |
404 | c->variables[i] = FD_INT2C_VAR(ys[i - nvariables]); | 404 | c->variables[i] = FD_INT2C_VAR(ys[i - nvariables]); |
405 | c->constants[0] = k; | 405 | c->constants[0] = k; |
406 | -#ifdef CONSTRAINT_CLASS | 406 | + |
407 | c->kind = FD_CONSTR_SUM_PROD; | 407 | c->kind = FD_CONSTR_SUM_PROD; |
408 | -#else /* CONSTRAINT_CLASS */ | ||
409 | - c->propagator2 = fd_sum_prod_propagate2; | ||
410 | -#endif /* CONSTRAINT_CLASS */ | ||
411 | 408 | ||
412 | for (i = 0; i < 2 * nvariables; ++i) | 409 | for (i = 0; i < 2 * nvariables; ++i) |
413 | _fd_var_add_constraint(VAR(c, i), c); | 410 | _fd_var_add_constraint(VAR(c, i), c); |
src/constraints/sum.c
@@ -177,7 +177,7 @@ static int fd_sum_propagate2(fd_constraint this, fd_int culprit) | @@ -177,7 +177,7 @@ static int fd_sum_propagate2(fd_constraint this, fd_int culprit) | ||
177 | 177 | ||
178 | fd_constraint fd_sum(fd_int *variables, int nvariables, int k) | 178 | fd_constraint fd_sum(fd_int *variables, int nvariables, int k) |
179 | { | 179 | { |
180 | - fd_constraint c = _fd_constraint_new(nvariables, 1); | 180 | + fd_constraint c = fd__constraint_new(nvariables, 1); |
181 | int i; | 181 | int i; |
182 | 182 | ||
183 | if (c) | 183 | if (c) |
@@ -185,11 +185,8 @@ fd_constraint fd_sum(fd_int *variables, int nvariables, int k) | @@ -185,11 +185,8 @@ fd_constraint fd_sum(fd_int *variables, int nvariables, int k) | ||
185 | for (i = 0; i < nvariables; ++i) | 185 | for (i = 0; i < nvariables; ++i) |
186 | c->variables[i] = FD_INT2C_VAR(variables[i]); | 186 | c->variables[i] = FD_INT2C_VAR(variables[i]); |
187 | c->constants[0] = k; | 187 | c->constants[0] = k; |
188 | -#ifdef CONSTRAINT_CLASS | 188 | + |
189 | c->kind = FD_CONSTR_SUM; | 189 | c->kind = FD_CONSTR_SUM; |
190 | -#else /* CONSTRAINT_CLASS */ | ||
191 | - c->propagator2 = fd_sum_propagate2; | ||
192 | -#endif /* CONSTRAINT_CLASS */ | ||
193 | 190 | ||
194 | for (i = 0; i < nvariables; ++i) | 191 | for (i = 0; i < nvariables; ++i) |
195 | _fd_var_add_constraint(VAR(c, i), c); | 192 | _fd_var_add_constraint(VAR(c, i), c); |
src/constraints/sum2.c
@@ -94,7 +94,7 @@ static int fd_sum2_propagate2(fd_constraint this, fd_int culprit) | @@ -94,7 +94,7 @@ static int fd_sum2_propagate2(fd_constraint this, fd_int culprit) | ||
94 | 94 | ||
95 | fd_constraint fd_sum2(fd_int *variables, int nvariables, fd_int x) | 95 | fd_constraint fd_sum2(fd_int *variables, int nvariables, fd_int x) |
96 | { | 96 | { |
97 | - fd_constraint c = _fd_constraint_new(nvariables + 1, 0); | 97 | + fd_constraint c = fd__constraint_new(nvariables + 1, 0); |
98 | int i; | 98 | int i; |
99 | 99 | ||
100 | if (c) | 100 | if (c) |
@@ -102,11 +102,8 @@ fd_constraint fd_sum2(fd_int *variables, int nvariables, fd_int x) | @@ -102,11 +102,8 @@ fd_constraint fd_sum2(fd_int *variables, int nvariables, fd_int x) | ||
102 | for (i = 0; i < nvariables; ++i) | 102 | for (i = 0; i < nvariables; ++i) |
103 | c->variables[i] = FD_INT2C_VAR(variables[i]); | 103 | c->variables[i] = FD_INT2C_VAR(variables[i]); |
104 | c->variables[nvariables] = FD_INT2C_VAR(x); | 104 | c->variables[nvariables] = FD_INT2C_VAR(x); |
105 | -#ifdef CONSTRAINT_CLASS | 105 | + |
106 | c->kind = FD_CONSTR_SUM2; | 106 | c->kind = FD_CONSTR_SUM2; |
107 | -#else /* CONSTRAINT_CLASS */ | ||
108 | - c->propagator2 = fd_sum2_propagate2; | ||
109 | -#endif /* CONSTRAINT_CLASS */ | ||
110 | 107 | ||
111 | for (i = 0; i < nvariables + 1; ++i) | 108 | for (i = 0; i < nvariables + 1; ++i) |
112 | _fd_var_add_constraint(VAR(c, i), c); | 109 | _fd_var_add_constraint(VAR(c, i), c); |
src/constraints/var-eq-minus.c
1 | -/* X = Y - Z */ | 1 | +/* x = y - z */ |
2 | 2 | ||
3 | static int fd_var_eq_minus_filter(fd_constraint this) | 3 | static int fd_var_eq_minus_filter(fd_constraint this) |
4 | { | 4 | { |
@@ -10,7 +10,7 @@ static int fd_var_eq_minus_filter(fd_constraint this) | @@ -10,7 +10,7 @@ static int fd_var_eq_minus_filter(fd_constraint this) | ||
10 | y = VAR(this, 1); | 10 | y = VAR(this, 1); |
11 | z = VAR(this, 2); | 11 | z = VAR(this, 2); |
12 | 12 | ||
13 | - // XXX: just do bounds consistency, for now | 13 | + // bounds consistency |
14 | 14 | ||
15 | xmin = _fd_var_min(x); | 15 | xmin = _fd_var_min(x); |
16 | xmax = _fd_var_max(x); | 16 | xmax = _fd_var_max(x); |
@@ -28,6 +28,15 @@ static int fd_var_eq_minus_filter(fd_constraint this) | @@ -28,6 +28,15 @@ static int fd_var_eq_minus_filter(fd_constraint this) | ||
28 | _fd_revise_connected(NULL, y); | 28 | _fd_revise_connected(NULL, y); |
29 | } | 29 | } |
30 | 30 | ||
31 | +#ifndef DISABLE_ENTAILED | ||
32 | + if ((xmin == xmax) + (zmin == zmax) == 2) | ||
33 | + { | ||
34 | + fd__constraint_set_entailed(this); | ||
35 | + | ||
36 | + return FD_OK; | ||
37 | + } | ||
38 | +#endif | ||
39 | + | ||
31 | ymin = _fd_var_min(y); | 40 | ymin = _fd_var_min(y); |
32 | ymax = _fd_var_max(y); | 41 | ymax = _fd_var_max(y); |
33 | 42 | ||
@@ -54,98 +63,129 @@ static int fd_var_eq_minus_filter(fd_constraint this) | @@ -54,98 +63,129 @@ static int fd_var_eq_minus_filter(fd_constraint this) | ||
54 | _fd_revise_connected(NULL, x); | 63 | _fd_revise_connected(NULL, x); |
55 | } | 64 | } |
56 | 65 | ||
57 | -#if CONSTRAINT_TEMPS > 3 | ||
58 | - if (fd_var_single(x, 0) && fd_var_single(y, 0) && fd_var_single(z, 0)) | 66 | +#ifndef DISABLE_ENTAILED |
67 | + if ((ymin == ymax) + (zmin == zmax) == 2) | ||
59 | fd__constraint_set_entailed(this); | 68 | fd__constraint_set_entailed(this); |
60 | #endif | 69 | #endif |
61 | 70 | ||
62 | return FD_OK; | 71 | return FD_OK; |
63 | } | 72 | } |
64 | 73 | ||
65 | -int fd_var_eq_minus_propagate2(fd_constraint this, fd_int culprit) | 74 | +static int fd_var_eq_minus_propagate2(fd_constraint this, fd_int culprit) |
66 | { | 75 | { |
67 | fd_int x, y, z; | 76 | fd_int x, y, z; |
77 | + int xmin, xmax, ymin, ymax, zmin, zmax; | ||
68 | int changed_x = 0, changed_y = 0, changed_z = 0; | 78 | int changed_x = 0, changed_y = 0, changed_z = 0; |
69 | 79 | ||
70 | x = VAR(this, 0); | 80 | x = VAR(this, 0); |
71 | y = VAR(this, 1); | 81 | y = VAR(this, 1); |
72 | z = VAR(this, 2); | 82 | z = VAR(this, 2); |
73 | 83 | ||
74 | - // XXX: just do bounds consistency, for now | 84 | + // bounds consistency |
75 | 85 | ||
76 | if (culprit == x) | 86 | if (culprit == x) |
77 | { | 87 | { |
78 | - changed_y = | ||
79 | - _fd_var_del_lt(_fd_var_min(x) + _fd_var_min(z), y); | ||
80 | - changed_y |= | ||
81 | - _fd_var_del_gt(_fd_var_max(x) + _fd_var_max(z), y); | 88 | + xmin = _fd_var_min(x); |
89 | + xmax = _fd_var_max(x); | ||
82 | 90 | ||
83 | - if (changed_y && fd_domain_empty(y)) | ||
84 | - return FD_NOSOLUTION; | 91 | + changed_y = _fd_var_del_lt(xmin + _fd_var_min(z), y) | |
92 | + _fd_var_del_gt(xmax + _fd_var_max(z), y); | ||
93 | + | ||
94 | + if (changed_y) | ||
95 | + { | ||
96 | + if (fd_domain_empty(y)) | ||
97 | + return FD_NOSOLUTION; | ||
98 | + | ||
99 | + _fd_revise_connected(NULL, y); // XXX: NULL or this? | ||
100 | + } | ||
101 | + | ||
102 | + ymin = _fd_var_min(y); | ||
103 | + ymax = _fd_var_max(y); | ||
85 | 104 | ||
86 | changed_z = | 105 | changed_z = |
87 | - _fd_var_del_lt(_fd_var_min(y) - _fd_var_max(x), z); | ||
88 | - changed_z |= | ||
89 | - _fd_var_del_gt(_fd_var_max(y) - _fd_var_min(x), z); | 106 | + _fd_var_del_lt(ymin - xmax, z) | _fd_var_del_gt(ymax - xmin, z); |
90 | 107 | ||
91 | - if (changed_z && fd_domain_empty(z)) | ||
92 | - return FD_NOSOLUTION; | 108 | + if (changed_z) |
109 | + { | ||
110 | + if (fd_domain_empty(z)) | ||
111 | + return FD_NOSOLUTION; | ||
112 | + | ||
113 | + _fd_revise_connected(NULL, z); // XXX: NULL or this? | ||
114 | + } | ||
93 | } | 115 | } |
94 | else if (culprit == y) | 116 | else if (culprit == y) |
95 | { | 117 | { |
96 | - changed_x = | ||
97 | - _fd_var_del_lt(_fd_var_min(y) - _fd_var_max(z), x); | ||
98 | - changed_x |= | ||
99 | - _fd_var_del_gt(_fd_var_max(y) - _fd_var_min(z), x); | 118 | + ymin = _fd_var_min(y); |
119 | + ymax = _fd_var_max(y); | ||
100 | 120 | ||
101 | - if (changed_x && fd_domain_empty(x)) | ||
102 | - return FD_NOSOLUTION; | 121 | + changed_x = _fd_var_del_lt(ymin - _fd_var_max(z), x) | |
122 | + _fd_var_del_gt(ymax - _fd_var_min(z), x); | ||
123 | + | ||
124 | + if (changed_x) | ||
125 | + { | ||
126 | + if (fd_domain_empty(x)) | ||
127 | + return FD_NOSOLUTION; | ||
128 | + | ||
129 | + _fd_revise_connected(NULL, x); // XXX: NULL or this? | ||
130 | + } | ||
131 | + | ||
132 | + xmin = _fd_var_min(x); | ||
133 | + xmax = _fd_var_max(x); | ||
103 | 134 | ||
104 | changed_z = | 135 | changed_z = |
105 | - _fd_var_del_lt(_fd_var_min(y) - _fd_var_max(x), z); | ||
106 | - changed_z |= | ||
107 | - _fd_var_del_gt(_fd_var_max(y) - _fd_var_min(x), z); | 136 | + _fd_var_del_lt(ymin - xmax, z) | _fd_var_del_gt(ymax - xmin, z); |
108 | 137 | ||
109 | - if (changed_z && fd_domain_empty(z)) | ||
110 | - return FD_NOSOLUTION; | 138 | + if (changed_z) |
139 | + { | ||
140 | + if (fd_domain_empty(z)) | ||
141 | + return FD_NOSOLUTION; | ||
142 | + | ||
143 | + _fd_revise_connected(NULL, z); // XXX: NULL or this? | ||
144 | + } | ||
111 | } | 145 | } |
112 | else // culprit == z | 146 | else // culprit == z |
113 | { | 147 | { |
114 | - changed_x = | ||
115 | - _fd_var_del_lt(_fd_var_min(y) - _fd_var_max(z), x); | ||
116 | - changed_x |= | ||
117 | - _fd_var_del_gt(_fd_var_max(y) - _fd_var_min(z), x); | 148 | + zmin = _fd_var_min(z); |
149 | + zmax = _fd_var_max(z); | ||
118 | 150 | ||
119 | - if (changed_x && fd_domain_empty(x)) | ||
120 | - return FD_NOSOLUTION; | 151 | + changed_x = _fd_var_del_lt(_fd_var_min(y) - zmax, x) | |
152 | + _fd_var_del_gt(_fd_var_max(y) - zmin, x); | ||
121 | 153 | ||
122 | - changed_y = | ||
123 | - _fd_var_del_lt(_fd_var_min(x) + _fd_var_min(z), y); | ||
124 | - changed_y |= | ||
125 | - _fd_var_del_gt(_fd_var_max(x) + _fd_var_max(z), y); | 154 | + if (changed_x) |
155 | + { | ||
156 | + if (fd_domain_empty(x)) | ||
157 | + return FD_NOSOLUTION; | ||
126 | 158 | ||
127 | - if (changed_y && fd_domain_empty(y)) | ||
128 | - return FD_NOSOLUTION; | ||
129 | - } | 159 | + _fd_revise_connected(NULL, x); // XXX: NULL or this? |
160 | + } | ||
130 | 161 | ||
131 | - if (changed_x) | ||
132 | - _fd_revise_connected(NULL, x); // XXX: NULL or this? | 162 | + xmin = _fd_var_min(x); |
163 | + xmax = _fd_var_max(x); | ||
133 | 164 | ||
134 | - if (changed_y) | ||
135 | - _fd_revise_connected(NULL, y); // XXX: NULL or this? | 165 | + changed_y = |
166 | + _fd_var_del_lt(xmin + zmin, y) | _fd_var_del_gt(xmax + zmax, y); | ||
136 | 167 | ||
137 | - if (changed_z) | ||
138 | - _fd_revise_connected(NULL, z); // XXX: NULL or this? | 168 | + if (changed_y) |
169 | + { | ||
170 | + if (fd_domain_empty(y)) | ||
171 | + return FD_NOSOLUTION; | ||
139 | 172 | ||
140 | -#if CONSTRAINT_TEMPS > 3 | ||
141 | - if (fd_var_single(x, 0) && fd_var_single(y, 0) && fd_var_single(z, 0)) | 173 | + _fd_revise_connected(NULL, y); // XXX: NULL or this? |
174 | + } | ||
175 | + | ||
176 | + ymin = zmin + xmin; | ||
177 | + ymax = zmax + xmax; | ||
178 | + } | ||
179 | + | ||
180 | +#ifndef DISABLE_ENTAILED | ||
181 | + if ((xmin == xmax) + (ymin == ymax) == 2) | ||
142 | fd__constraint_set_entailed(this); | 182 | fd__constraint_set_entailed(this); |
143 | #endif | 183 | #endif |
144 | 184 | ||
145 | return FD_OK; | 185 | return FD_OK; |
146 | } | 186 | } |
147 | 187 | ||
148 | -int fd_var_eq_minus_propagate(fd_constraint this, fd_int revise) | 188 | +static int fd_var_eq_minus_propagate(fd_constraint this, fd_int revise) |
149 | { | 189 | { |
150 | fd_int x, y, z; | 190 | fd_int x, y, z; |
151 | int changed; | 191 | int changed; |
@@ -190,19 +230,15 @@ int fd_var_eq_minus_propagate(fd_constraint this, fd_int revise) | @@ -190,19 +230,15 @@ int fd_var_eq_minus_propagate(fd_constraint this, fd_int revise) | ||
190 | 230 | ||
191 | fd_constraint fd_var_eq_minus(fd_int x, fd_int y, fd_int z) | 231 | fd_constraint fd_var_eq_minus(fd_int x, fd_int y, fd_int z) |
192 | { | 232 | { |
193 | - fd_constraint c = _fd_constraint_new(3, 0); | 233 | + fd_constraint c = fd__constraint_new(3, 0); |
194 | 234 | ||
195 | if (c) | 235 | if (c) |
196 | { | 236 | { |
197 | c->variables[0] = FD_INT2C_VAR(x); | 237 | c->variables[0] = FD_INT2C_VAR(x); |
198 | c->variables[1] = FD_INT2C_VAR(y); | 238 | c->variables[1] = FD_INT2C_VAR(y); |
199 | c->variables[2] = FD_INT2C_VAR(z); | 239 | c->variables[2] = FD_INT2C_VAR(z); |
200 | -#ifdef CONSTRAINT_CLASS | 240 | + |
201 | c->kind = FD_CONSTR_VAR_EQ_MINUS; | 241 | c->kind = FD_CONSTR_VAR_EQ_MINUS; |
202 | -#else /* CONSTRAINT_CLASS */ | ||
203 | - c->propagator2 = fd_var_eq_minus_propagate2; | ||
204 | - c->propagator = fd_var_eq_minus_propagate; | ||
205 | -#endif /* CONSTRAINT_CLASS */ | ||
206 | 242 | ||
207 | _fd_var_add_constraint(x, c); | 243 | _fd_var_add_constraint(x, c); |
208 | _fd_var_add_constraint(y, c); | 244 | _fd_var_add_constraint(y, c); |
src/constraints/var-eq-times.c
@@ -177,18 +177,15 @@ int fd_var_eq_times_propagate2(fd_constraint this, fd_int culprit) | @@ -177,18 +177,15 @@ int fd_var_eq_times_propagate2(fd_constraint this, fd_int culprit) | ||
177 | 177 | ||
178 | fd_constraint fd_var_eq_times(fd_int x, fd_int y, fd_int z) | 178 | fd_constraint fd_var_eq_times(fd_int x, fd_int y, fd_int z) |
179 | { | 179 | { |
180 | - fd_constraint c = _fd_constraint_new(3, 0); | 180 | + fd_constraint c = fd__constraint_new(3, 0); |
181 | 181 | ||
182 | if (c) | 182 | if (c) |
183 | { | 183 | { |
184 | c->variables[0] = FD_INT2C_VAR(x); | 184 | c->variables[0] = FD_INT2C_VAR(x); |
185 | c->variables[1] = FD_INT2C_VAR(y); | 185 | c->variables[1] = FD_INT2C_VAR(y); |
186 | c->variables[2] = FD_INT2C_VAR(z); | 186 | c->variables[2] = FD_INT2C_VAR(z); |
187 | -#ifdef CONSTRAINT_CLASS | 187 | + |
188 | c->kind = FD_CONSTR_VAR_EQ_TIMES; | 188 | c->kind = FD_CONSTR_VAR_EQ_TIMES; |
189 | -#else /* CONSTRAINT_CLASS */ | ||
190 | - c->propagator2 = fd_var_eq_times_propagate2; | ||
191 | -#endif /* CONSTRAINT_CLASS */ | ||
192 | 189 | ||
193 | _fd_var_add_constraint(x, c); | 190 | _fd_var_add_constraint(x, c); |
194 | _fd_var_add_constraint(y, c); | 191 | _fd_var_add_constraint(y, c); |
src/dsearch-sg.c
@@ -15,6 +15,9 @@ | @@ -15,6 +15,9 @@ | ||
15 | #include "variables.h" | 15 | #include "variables.h" |
16 | #include "values.h" | 16 | #include "values.h" |
17 | #include "bound.h" | 17 | #include "bound.h" |
18 | +#include "constraints.h" | ||
19 | + | ||
20 | +#include "util.h" | ||
18 | 21 | ||
19 | #if STEAL_WORK > 0 | 22 | #if STEAL_WORK > 0 |
20 | #include <time.h> | 23 | #include <time.h> |
@@ -52,9 +55,7 @@ void _fd_epoch_forward() | @@ -52,9 +55,7 @@ void _fd_epoch_forward() | ||
52 | 55 | ||
53 | void _fd_epoch_rewind() | 56 | void _fd_epoch_rewind() |
54 | { | 57 | { |
55 | -#ifdef CONSTRAINT_TEMPS | ||
56 | fd__constraint_data_reset(); | 58 | fd__constraint_data_reset(); |
57 | -#endif | ||
58 | } | 59 | } |
59 | 60 | ||
60 | int _fd_dsearch(fd_int variables[], int agent_no) | 61 | int _fd_dsearch(fd_int variables[], int agent_no) |
@@ -69,20 +70,20 @@ int _fd_dsearch(fd_int variables[], int agent_no) | @@ -69,20 +70,20 @@ int _fd_dsearch(fd_int variables[], int agent_no) | ||
69 | agent = agent_no; | 70 | agent = agent_no; |
70 | 71 | ||
71 | #if defined(NEW_ENTRANCE) && defined(DEBUG_SPLITGO) | 72 | #if defined(NEW_ENTRANCE) && defined(DEBUG_SPLITGO) |
72 | - _fd_debug("[%d.%d] agents_searching = %d, agents_failed = %d\n", tid, agent, agents_searching, agents_failed); | 73 | + fd__debug("[%d.%d] agents_searching = %d, agents_failed = %d\n", tid, agent, agents_searching, agents_failed); |
73 | #endif | 74 | #endif |
74 | 75 | ||
75 | _fd_init_local_depository(); | 76 | _fd_init_local_depository(); |
76 | 77 | ||
77 | #if DEBUG_SPLITGO > 1 | 78 | #if DEBUG_SPLITGO > 1 |
78 | - _fd_output("[%d.%d] ", tid, agent); _fd_cprint2(variables); | 79 | + fd__output("[%d.%d] ", tid, agent); _fd_cprint2(variables); |
79 | #endif | 80 | #endif |
80 | 81 | ||
81 | if (_fd_filter_domains() == FD_NOSOLUTION) | 82 | if (_fd_filter_domains() == FD_NOSOLUTION) |
82 | { | 83 | { |
83 | fd_int variable = NULL; | 84 | fd_int variable = NULL; |
84 | 85 | ||
85 | - _fd_debug("[%d.%d] failed before beginning\n", tid, agent); | 86 | + fd__trace("[%d.%d] failed before beginning\n", tid, agent); |
86 | 87 | ||
87 | #if STEAL_WORK > 0 | 88 | #if STEAL_WORK > 0 |
88 | #ifdef NEW_ENTRANCE | 89 | #ifdef NEW_ENTRANCE |
@@ -106,20 +107,14 @@ int _fd_dsearch(fd_int variables[], int agent_no) | @@ -106,20 +107,14 @@ int _fd_dsearch(fd_int variables[], int agent_no) | ||
106 | 107 | ||
107 | do | 108 | do |
108 | { | 109 | { |
109 | -#ifndef INDEX_IN_POOL | ||
110 | - if (!_fd_steal_store(store, agent_no, 7)) | ||
111 | -#else | ||
112 | if (!_fd_steal_store(store, &variable, agent_no, 7)) | 110 | if (!_fd_steal_store(store, &variable, agent_no, 7)) |
113 | -#endif | ||
114 | { | 111 | { |
115 | - _fd_debug("[%d.%d] giving up\n", tid, agent); | 112 | + fd__trace("[%d.%d] giving up\n", tid, agent); |
116 | 113 | ||
117 | return FD_NOSOLUTION; | 114 | return FD_NOSOLUTION; |
118 | } | 115 | } |
119 | 116 | ||
120 | -#ifdef CONSTRAINT_TEMPS | ||
121 | fd__constraint_data_reset(); // XXX: this doesn't belong here! | 117 | fd__constraint_data_reset(); // XXX: this doesn't belong here! |
122 | -#endif | ||
123 | } | 118 | } |
124 | while (_fd_revise_wrt_variable(variable) == FD_NOSOLUTION); | 119 | while (_fd_revise_wrt_variable(variable) == FD_NOSOLUTION); |
125 | #else /* STEAL_WORK > 0 */ | 120 | #else /* STEAL_WORK > 0 */ |
@@ -128,7 +123,7 @@ int _fd_dsearch(fd_int variables[], int agent_no) | @@ -128,7 +123,7 @@ int _fd_dsearch(fd_int variables[], int agent_no) | ||
128 | } | 123 | } |
129 | 124 | ||
130 | #if DEBUG_SPLITGO > 1 | 125 | #if DEBUG_SPLITGO > 1 |
131 | - _fd_output("[%d.%d] ", tid, agent); _fd_cprint2(variables); | 126 | + fd__output("[%d.%d] ", tid, agent); _fd_cprint2(variables); |
132 | #endif | 127 | #endif |
133 | 128 | ||
134 | #ifdef NEW_ENTRANCE | 129 | #ifdef NEW_ENTRANCE |
@@ -139,7 +134,7 @@ int _fd_dsearch(fd_int variables[], int agent_no) | @@ -139,7 +134,7 @@ int _fd_dsearch(fd_int variables[], int agent_no) | ||
139 | pthread_spin_unlock(&entrance_lock); | 134 | pthread_spin_unlock(&entrance_lock); |
140 | #endif | 135 | #endif |
141 | 136 | ||
142 | - _fd_debug("[%d.%d] about to start searching\n", tid, agent); | 137 | + fd__trace("[%d.%d] about to start searching\n", tid, agent); |
143 | 138 | ||
144 | return _fd_dsearch_(variables); | 139 | return _fd_dsearch_(variables); |
145 | } | 140 | } |
@@ -170,7 +165,7 @@ static int _fd_dsearch_(fd_int _fd_variables[]) | @@ -170,7 +165,7 @@ static int _fd_dsearch_(fd_int _fd_variables[]) | ||
170 | instantiations++; | 165 | instantiations++; |
171 | #ifdef DEBUG_PROGRESS | 166 | #ifdef DEBUG_PROGRESS |
172 | if (instantiations % 100000 == 0) | 167 | if (instantiations % 100000 == 0) |
173 | - _fd_debug("[%d.%d] still alive (%d stores)\n", tid, agent, | 168 | + fd__debug("[%d.%d] still alive (%d stores)\n", tid, agent, |
174 | next_split_index - base_split_index); | 169 | next_split_index - base_split_index); |
175 | #endif | 170 | #endif |
176 | 171 | ||
@@ -202,7 +197,7 @@ static int _fd_dsearch_(fd_int _fd_variables[]) | @@ -202,7 +197,7 @@ static int _fd_dsearch_(fd_int _fd_variables[]) | ||
202 | { | 197 | { |
203 | if (!_fd_counting_solutions) | 198 | if (!_fd_counting_solutions) |
204 | { | 199 | { |
205 | - _fd_debug("[%d.%d] performed %d instantiations and %d backtracks\n", | 200 | + fd__trace("[%d.%d] performed %d instantiations and %d backtracks\n", |
206 | tid, agent, instantiations, backtrack); | 201 | tid, agent, instantiations, backtrack); |
207 | 202 | ||
208 | _fd_statistics_pool(); | 203 | _fd_statistics_pool(); |
@@ -229,10 +224,10 @@ static int _fd_dsearch_(fd_int _fd_variables[]) | @@ -229,10 +224,10 @@ static int _fd_dsearch_(fd_int _fd_variables[]) | ||
229 | 224 | ||
230 | if (!_fd_counting_solutions) | 225 | if (!_fd_counting_solutions) |
231 | { | 226 | { |
232 | - _fd_debug("[%d.%d] performed %d instantiations and %d backtracks\n", tid, | 227 | + fd__trace("[%d.%d] performed %d instantiations and %d backtracks\n", tid, |
233 | agent, instantiations, backtrack); | 228 | agent, instantiations, backtrack); |
234 | 229 | ||
235 | - _fd_debug("[%d.%d] %d stores in store\n", tid, agent, next_split_index - base_split_index); | 230 | + fd__trace("[%d.%d] %d stores in store\n", tid, agent, next_split_index - base_split_index); |
236 | 231 | ||
237 | _fd_statistics_pool(); | 232 | _fd_statistics_pool(); |
238 | } | 233 | } |
src/fdc_int.h
@@ -152,33 +152,15 @@ struct fd_value { | @@ -152,33 +152,15 @@ struct fd_value { | ||
152 | #define FD_INT2C_VAR(v) ((v)->index) | 152 | #define FD_INT2C_VAR(v) ((v)->index) |
153 | 153 | ||
154 | struct fd_constraint { | 154 | struct fd_constraint { |
155 | -#ifdef CONSTRAINT_TEMPS | 155 | +#if defined(CONSTRAINT_TEMPS) || !defined(DISABLE_ENTAILED) |
156 | int index; | 156 | int index; |
157 | #endif | 157 | #endif |
158 | C_VAR_T *variables; // variables involved in the constraint | 158 | C_VAR_T *variables; // variables involved in the constraint |
159 | int nvariables; // number of variables | 159 | int nvariables; // number of variables |
160 | int *constants; // constraint's constants (where applicable) | 160 | int *constants; // constraint's constants (where applicable) |
161 | int nconstants; // number of constants | 161 | int nconstants; // number of constants |
162 | -#ifdef CONSTRAINT_CLASS | ||
163 | // _fd_constraint_kind kind; // what kind of constraint is this? | 162 | // _fd_constraint_kind kind; // what kind of constraint is this? |
164 | int kind; // what kind of constraint is this? // XXX | 163 | int kind; // what kind of constraint is this? // XXX |
165 | -#else /* CONSTRAINT_CLASS */ | ||
166 | - int (*propagator2)(fd_constraint, fd_int); | ||
167 | - // how to propagate changes in a variable's | ||
168 | - // domain; 2nd argument is the variable | ||
169 | - // against which to revise the domains of | ||
170 | - // the other variables in the constraint; | ||
171 | - // returns 1 if some domain becomes empty | ||
172 | - int (*filter)(fd_constraint); | ||
173 | - // performs an initial filtering of the | ||
174 | - // domains of the constraint variables | ||
175 | - int (*propagator)(fd_constraint, fd_int); | ||
176 | - // how to propagate changes in a variable's | ||
177 | - // domain; 2nd argument is the variable to | ||
178 | - // revise (against the domains of every | ||
179 | - // other variable in the constraint); | ||
180 | - // returns 1 if some domain became empty | ||
181 | -#endif /* CONSTRAINT_CLASS */ | ||
182 | }; | 164 | }; |
183 | 165 | ||
184 | #define fd_cvariable(c,v) ((c)->variables[v]) // XXX: not being used | 166 | #define fd_cvariable(c,v) ((c)->variables[v]) // XXX: not being used |
@@ -197,6 +179,7 @@ extern int fd_variables_count; | @@ -197,6 +179,7 @@ extern int fd_variables_count; | ||
197 | extern __thread fd_int _fd_variables[]; | 179 | extern __thread fd_int _fd_variables[]; |
198 | 180 | ||
199 | fd_int fd_new(int, int); | 181 | fd_int fd_new(int, int); |
182 | +fd_int fd_const(int); | ||
200 | 183 | ||
201 | // type for the variable's constraints | 184 | // type for the variable's constraints |
202 | #define VAR_C_T int | 185 | #define VAR_C_T int |
@@ -266,6 +249,8 @@ typedef enum { | @@ -266,6 +249,8 @@ typedef enum { | ||
266 | 249 | ||
267 | #endif /* DISTRIBUTED_SOLVER */ | 250 | #endif /* DISTRIBUTED_SOLVER */ |
268 | 251 | ||
269 | -#ifdef FAST | ||
270 | -# define _fd_debug(...) ((void) 0) | ||
271 | -#endif /* FAST */ | 252 | +#ifdef TRACE |
253 | +# define fd__trace fd__debug | ||
254 | +#else | ||
255 | +# define fd__trace(...) ((void) 0) | ||
256 | +#endif |
src/matching.c
@@ -9,6 +9,10 @@ | @@ -9,6 +9,10 @@ | ||
9 | #include "values.h" | 9 | #include "values.h" |
10 | #include "matching.h" | 10 | #include "matching.h" |
11 | 11 | ||
12 | +#ifdef DEBUG_MATCH | ||
13 | +# include "util.h" | ||
14 | +#endif | ||
15 | + | ||
12 | #define UNSEEN (-2) // value not seen in any domain | 16 | #define UNSEEN (-2) // value not seen in any domain |
13 | 17 | ||
14 | #define WHITE (-1) | 18 | #define WHITE (-1) |
@@ -297,7 +301,7 @@ static void _fd_mark_cycles(fd_constraint c, int8_t *vgraph, int r_verts, | @@ -297,7 +301,7 @@ static void _fd_mark_cycles(fd_constraint c, int8_t *vgraph, int r_verts, | ||
297 | 301 | ||
298 | if (vgraph[var * r_verts + val] == 1) | 302 | if (vgraph[var * r_verts + val] == 1) |
299 | { | 303 | { |
300 | -// _fd_debug("marking %d in %d's domain\n", val + min, VAR(c, var)->index); | 304 | +// fd__debug("marking %d in %d's domain\n", val + min, VAR(c, var)->index); |
301 | 305 | ||
302 | vgraph[var * r_verts + val] = 3; | 306 | vgraph[var * r_verts + val] = 3; |
303 | } | 307 | } |
@@ -604,7 +608,7 @@ static void _fd_remark_cycles(fd_constraint c, int culprit, int8_t *vgraph, | @@ -604,7 +608,7 @@ static void _fd_remark_cycles(fd_constraint c, int culprit, int8_t *vgraph, | ||
604 | 608 | ||
605 | if (vgraph[var * r_verts + val] == 1) | 609 | if (vgraph[var * r_verts + val] == 1) |
606 | { | 610 | { |
607 | -// _fd_debug("marking %d in %d's domain\n", val + min, VAR(c, var)->index); | 611 | +// fd__debug("marking %d in %d's domain\n", val + min, VAR(c, var)->index); |
608 | 612 | ||
609 | vgraph[var * r_verts + val] = 3; | 613 | vgraph[var * r_verts + val] = 3; |
610 | } | 614 | } |
@@ -620,7 +624,7 @@ static void _fd_remark_cycles(fd_constraint c, int culprit, int8_t *vgraph, | @@ -620,7 +624,7 @@ static void _fd_remark_cycles(fd_constraint c, int culprit, int8_t *vgraph, | ||
620 | for (i = 0; i < nvariables; ++i) | 624 | for (i = 0; i < nvariables; ++i) |
621 | if (l_scc[i] == r_scc[v] && vgraph[i * r_verts + v] == 1) | 625 | if (l_scc[i] == r_scc[v] && vgraph[i * r_verts + v] == 1) |
622 | { | 626 | { |
623 | -// _fd_debug("marking %d in %d's domain\n", v + min, VAR(c, i)->index); | 627 | +// fd__debug("marking %d in %d's domain\n", v + min, VAR(c, i)->index); |
624 | 628 | ||
625 | vgraph[i * r_verts + v] = 3; | 629 | vgraph[i * r_verts + v] = 3; |
626 | } | 630 | } |
@@ -694,7 +698,7 @@ static void _fd_mark_paths(fd_constraint c, int8_t *vgraph, int r_verts, | @@ -694,7 +698,7 @@ static void _fd_mark_paths(fd_constraint c, int8_t *vgraph, int r_verts, | ||
694 | continue; | 698 | continue; |
695 | 699 | ||
696 | #if DEBUG_MATCH > 1 | 700 | #if DEBUG_MATCH > 1 |
697 | - _fd_debug("marking %d in %d's domain\n", | 701 | + fd__debug("marking %d in %d's domain\n", |
698 | queue[head] + min, VAR(c, v)->index); | 702 | queue[head] + min, VAR(c, v)->index); |
699 | #endif | 703 | #endif |
700 | // this edge is in an M-alternating path | 704 | // this edge is in an M-alternating path |
@@ -772,7 +776,7 @@ int _fd_find_matching(fd_constraint c, int **memory) | @@ -772,7 +776,7 @@ int _fd_find_matching(fd_constraint c, int **memory) | ||
772 | if (*memory == NULL) | 776 | if (*memory == NULL) |
773 | { | 777 | { |
774 | #ifdef DEBUG_MATCH | 778 | #ifdef DEBUG_MATCH |
775 | - _fd_debug("all-different memory size is %d\n", size); | 779 | + fd__debug("all-different memory size is %d\n", size); |
776 | #endif | 780 | #endif |
777 | 781 | ||
778 | *memory = malloc(size); // XXX: NULL | 782 | *memory = malloc(size); // XXX: NULL |
@@ -784,7 +788,7 @@ int _fd_find_matching(fd_constraint c, int **memory) | @@ -784,7 +788,7 @@ int _fd_find_matching(fd_constraint c, int **memory) | ||
784 | { | 788 | { |
785 | // the allocated memory is not enough | 789 | // the allocated memory is not enough |
786 | #ifdef DEBUG_MATCH | 790 | #ifdef DEBUG_MATCH |
787 | - _fd_debug("all-different new memory size is %d\n", size); | 791 | + fd__debug("all-different new memory size is %d\n", size); |
788 | #endif | 792 | #endif |
789 | 793 | ||
790 | *memory = realloc(*memory, size); // XXX: NULL | 794 | *memory = realloc(*memory, size); // XXX: NULL |
@@ -808,13 +812,13 @@ int _fd_find_matching(fd_constraint c, int **memory) | @@ -808,13 +812,13 @@ int _fd_find_matching(fd_constraint c, int **memory) | ||
808 | l_scc = r_edge + r_verts; | 812 | l_scc = r_edge + r_verts; |
809 | r_scc = l_scc + nvariables; | 813 | r_scc = l_scc + nvariables; |
810 | vgraph = (int8_t *) (r_scc + r_verts); | 814 | vgraph = (int8_t *) (r_scc + r_verts); |
811 | -#else | 815 | +#else /* CONSTRAINT_TEMPS */ |
812 | l_edge = alloca(nvariables * sizeof(*l_edge)); | 816 | l_edge = alloca(nvariables * sizeof(*l_edge)); |
813 | r_edge = alloca(r_verts * sizeof(*r_edge)); | 817 | r_edge = alloca(r_verts * sizeof(*r_edge)); |
814 | l_scc = alloca(nvariables * sizeof(*l_scc)); | 818 | l_scc = alloca(nvariables * sizeof(*l_scc)); |
815 | r_scc = alloca(r_verts * sizeof(*r_scc)); | 819 | r_scc = alloca(r_verts * sizeof(*r_scc)); |
816 | vgraph = alloca(nvariables * r_verts * sizeof(*vgraph)); | 820 | vgraph = alloca(nvariables * r_verts * sizeof(*vgraph)); |
817 | -#endif | 821 | +#endif /* CONSTRAINT_TEMPS */ |
818 | 822 | ||
819 | l_parent = alloca(nvariables * sizeof(*l_parent)); | 823 | l_parent = alloca(nvariables * sizeof(*l_parent)); |
820 | l_colour = alloca(nvariables * sizeof(*l_colour)); | 824 | l_colour = alloca(nvariables * sizeof(*l_colour)); |
@@ -967,7 +971,7 @@ int _fd_find_matching(fd_constraint c, int **memory) | @@ -967,7 +971,7 @@ int _fd_find_matching(fd_constraint c, int **memory) | ||
967 | if (vgraph[i * r_verts + v] == 1) | 971 | if (vgraph[i * r_verts + v] == 1) |
968 | { | 972 | { |
969 | #ifdef DEBUG_MATCH | 973 | #ifdef DEBUG_MATCH |
970 | - _fd_debug("removing %d from %d's domain\n", v + min, | 974 | + fd__debug("removing %d from %d's domain\n", v + min, |
971 | VAR(c, i)->index); | 975 | VAR(c, i)->index); |
972 | #endif | 976 | #endif |
973 | changed |= _fd_var_del_val(v + min, VAR(c, i)); | 977 | changed |= _fd_var_del_val(v + min, VAR(c, i)); |
@@ -1198,7 +1202,7 @@ int _fd_update_matching(fd_constraint c, fd_int culprit, int *memory) | @@ -1198,7 +1202,7 @@ int _fd_update_matching(fd_constraint c, fd_int culprit, int *memory) | ||
1198 | if (vgraph[i * r_verts + v] == 1 && /* {XXX */ r_scc[v] == -1 /* XXX} */) | 1202 | if (vgraph[i * r_verts + v] == 1 && /* {XXX */ r_scc[v] == -1 /* XXX} */) |
1199 | { | 1203 | { |
1200 | #ifdef DEBUG_MATCH | 1204 | #ifdef DEBUG_MATCH |
1201 | - _fd_debug("removing %d from %d's domain\n", v + min, | 1205 | + fd__debug("removing %d from %d's domain\n", v + min, |
1202 | VAR(c, i)->index); | 1206 | VAR(c, i)->index); |
1203 | #endif | 1207 | #endif |
1204 | changed |= _fd_var_del_val(v + min, VAR(c, i)); | 1208 | changed |= _fd_var_del_val(v + min, VAR(c, i)); |
src/options.c
@@ -117,7 +117,7 @@ static char *_fd_options = "@(#) $Options: " | @@ -117,7 +117,7 @@ static char *_fd_options = "@(#) $Options: " | ||
117 | #endif | 117 | #endif |
118 | 118 | ||
119 | #ifdef CONSTRAINT_CLASS | 119 | #ifdef CONSTRAINT_CLASS |
120 | - "CONSTRAINT_CLASS" " " | 120 | +#warning "CONSTRAINT_CLASS committed (16JUN16)" |
121 | #endif | 121 | #endif |
122 | #ifdef CONSTRAINT_TEMPS | 122 | #ifdef CONSTRAINT_TEMPS |
123 | "CONSTRAINT_TEMPS" " " | 123 | "CONSTRAINT_TEMPS" " " |
@@ -143,7 +143,7 @@ static char *_fd_options = "@(#) $Options: " | @@ -143,7 +143,7 @@ static char *_fd_options = "@(#) $Options: " | ||
143 | "GROWABLE_POOL" " " | 143 | "GROWABLE_POOL" " " |
144 | #endif | 144 | #endif |
145 | #ifdef INDEX_IN_POOL | 145 | #ifdef INDEX_IN_POOL |
146 | - "INDEX_IN_POOL" " " | 146 | +#warning "INDEX_IN_POOL committed (24APR16)" |
147 | #endif | 147 | #endif |
148 | #ifdef STORE_IN_POOL | 148 | #ifdef STORE_IN_POOL |
149 | "STORE_IN_POOL" " " | 149 | "STORE_IN_POOL" " " |
src/paccs.h
@@ -14,6 +14,7 @@ void fd_init(int *argc, char **argv[]); | @@ -14,6 +14,7 @@ void fd_init(int *argc, char **argv[]); | ||
14 | void fd_end(void); | 14 | void fd_end(void); |
15 | int fd_solve(void); | 15 | int fd_solve(void); |
16 | 16 | ||
17 | +fd_int fd_const(int value); | ||
17 | fd_int fd_new(int min, int max); | 18 | fd_int fd_new(int min, int max); |
18 | 19 | ||
19 | void fd_label(fd_int vars[], int nvars); | 20 | void fd_label(fd_int vars[], int nvars); |
@@ -40,6 +41,7 @@ fd_constraint fd_var_eq_times(fd_int x, fd_int y, fd_int z); | @@ -40,6 +41,7 @@ fd_constraint fd_var_eq_times(fd_int x, fd_int y, fd_int z); | ||
40 | /* Global constraints */ | 41 | /* Global constraints */ |
41 | 42 | ||
42 | fd_constraint fd_all_different(fd_int X[], int n); | 43 | fd_constraint fd_all_different(fd_int X[], int n); |
44 | +fd_constraint fd_fake_all_different(fd_int X[], int n); | ||
43 | 45 | ||
44 | fd_constraint fd_element(fd_int X[], int n, fd_int y, int k); | 46 | fd_constraint fd_element(fd_int X[], int n, fd_int y, int k); |
45 | fd_constraint fd_element_var(fd_int X[], int n, fd_int y, fd_int z); | 47 | fd_constraint fd_element_var(fd_int X[], int n, fd_int y, fd_int z); |
@@ -51,6 +53,7 @@ fd_constraint fd_sum_prod(fd_int X[], fd_int Y[], int n, int k); | @@ -51,6 +53,7 @@ fd_constraint fd_sum_prod(fd_int X[], fd_int Y[], int n, int k); | ||
51 | 53 | ||
52 | fd_constraint fd_poly_eq(int C[], fd_int Y[], int n, fd_int z); | 54 | fd_constraint fd_poly_eq(int C[], fd_int Y[], int n, fd_int z); |
53 | fd_constraint fd_poly_eq_k(int C[], fd_int Y[], int n, int k); | 55 | fd_constraint fd_poly_eq_k(int C[], fd_int Y[], int n, int k); |
56 | +fd_constraint fd_poly_le_k(int C[], fd_int Y[], int n, int k); | ||
54 | fd_constraint fd_poly_ne(int C[], fd_int Y[], int n, fd_int y); | 57 | fd_constraint fd_poly_ne(int C[], fd_int Y[], int n, fd_int y); |
55 | fd_constraint fd_poly_ne_k(int C[], fd_int Y[], int n, int k); | 58 | fd_constraint fd_poly_ne_k(int C[], fd_int Y[], int n, int k); |
56 | fd_constraint fd_knapsack2(fd_int X[], fd_int Y[], int n, fd_int z); | 59 | fd_constraint fd_knapsack2(fd_int X[], fd_int Y[], int n, fd_int z); |
src/packed.c
@@ -11,6 +11,8 @@ | @@ -11,6 +11,8 @@ | ||
11 | #include "constraints.h" | 11 | #include "constraints.h" |
12 | #include "packed.h" | 12 | #include "packed.h" |
13 | 13 | ||
14 | +#include "util.h" | ||
15 | + | ||
14 | static struct _fd_packed_problem *packed_memory; // XXX: so it can be freed | 16 | static struct _fd_packed_problem *packed_memory; // XXX: so it can be freed |
15 | #ifdef USE_MMAP | 17 | #ifdef USE_MMAP |
16 | static size_t packed_memory_size; | 18 | static size_t packed_memory_size; |
@@ -42,7 +44,7 @@ static struct _fd_packed_problem *_fd_allocate_memory() | @@ -42,7 +44,7 @@ static struct _fd_packed_problem *_fd_allocate_memory() | ||
42 | tconsts += _fd_constraints[i]->nconstants; | 44 | tconsts += _fd_constraints[i]->nconstants; |
43 | } | 45 | } |
44 | 46 | ||
45 | - _fd_debug("packed size is %d + %d + %d + %d\n", | 47 | + fd__trace("packed size is %d + %d + %d + %d\n", |
46 | sizeof(*p), | 48 | sizeof(*p), |
47 | p->nvariables * sizeof(*p->variables), | 49 | p->nvariables * sizeof(*p->variables), |
48 | p->nconstraints * sizeof(*p->constraints), | 50 | p->nconstraints * sizeof(*p->constraints), |
@@ -86,7 +88,7 @@ static struct _fd_packed_problem *_fd_allocate_memory() | @@ -86,7 +88,7 @@ static struct _fd_packed_problem *_fd_allocate_memory() | ||
86 | { | 88 | { |
87 | perror("mmap"); | 89 | perror("mmap"); |
88 | 90 | ||
89 | - _fd_fatal("mmap() failed"); | 91 | + fd__fatal("mmap() failed"); |
90 | } | 92 | } |
91 | 93 | ||
92 | p = m; | 94 | p = m; |
@@ -141,10 +143,6 @@ void _fd_pack_problem() | @@ -141,10 +143,6 @@ void _fd_pack_problem() | ||
141 | int offset; | 143 | int offset; |
142 | int i, j; | 144 | int i, j; |
143 | 145 | ||
144 | -#ifndef CONSTRAINT_CLASS | ||
145 | - _fd_fatal("packed problems require CONSTRAINT_CLASS"); | ||
146 | -#endif | ||
147 | - | ||
148 | packed = _fd_allocate_memory(); | 146 | packed = _fd_allocate_memory(); |
149 | 147 | ||
150 | assert(packed != NULL); // XXX | 148 | assert(packed != NULL); // XXX |
src/packed.h
@@ -36,7 +36,7 @@ struct _fd_packed_int { | @@ -36,7 +36,7 @@ struct _fd_packed_int { | ||
36 | 36 | ||
37 | /* fields must correspond to an initial segment of fd_constraint */ | 37 | /* fields must correspond to an initial segment of fd_constraint */ |
38 | struct _fd_packed_constraint { | 38 | struct _fd_packed_constraint { |
39 | -#ifdef CONSTRAINT_TEMPS | 39 | +#if defined(CONSTRAINT_TEMPS) || !defined(DISABLE_ENTAILED) |
40 | int index; | 40 | int index; |
41 | #endif | 41 | #endif |
42 | C_VAR_T *variables; | 42 | C_VAR_T *variables; |
src/pool.c
@@ -10,12 +10,9 @@ static __thread _fd_store alt_store; // the other side of the split | @@ -10,12 +10,9 @@ static __thread _fd_store alt_store; // the other side of the split | ||
10 | static _fd_store *split_stores_; | 10 | static _fd_store *split_stores_; |
11 | #define split_stores split_stores_[agent] | 11 | #define split_stores split_stores_[agent] |
12 | 12 | ||
13 | -#ifndef INDEX_IN_POOL | ||
14 | -static __thread fd_int *split_variable; | ||
15 | -#else | ||
16 | static int **split_variable_; | 13 | static int **split_variable_; |
17 | -static __thread int *split_variable; | ||
18 | -#endif | 14 | +static __thread int *split_variable; // (index of the) variable whose domain |
15 | + // was split to obtain the store | ||
19 | 16 | ||
20 | #ifdef GROWABLE_POOL | 17 | #ifdef GROWABLE_POOL |
21 | // number of stores in the pool | 18 | // number of stores in the pool |
@@ -100,9 +97,7 @@ void _fd_init_store_depository(int agents) | @@ -100,9 +97,7 @@ void _fd_init_store_depository(int agents) | ||
100 | for (i = 0; i < agents; ++i) | 97 | for (i = 0; i < agents; ++i) |
101 | split_indexes[i] = EMPTY_POOL; | 98 | split_indexes[i] = EMPTY_POOL; |
102 | 99 | ||
103 | -#ifdef INDEX_IN_POOL | ||
104 | split_variable_ = calloc(agents, sizeof(*split_variable_)); | 100 | split_variable_ = calloc(agents, sizeof(*split_variable_)); |
105 | -#endif | ||
106 | 101 | ||
107 | stores_mutexes = calloc(agents, sizeof(*stores_mutexes)); | 102 | stores_mutexes = calloc(agents, sizeof(*stores_mutexes)); |
108 | for (i = 0; i < agents; ++i) | 103 | for (i = 0; i < agents; ++i) |
@@ -130,18 +125,15 @@ void _fd_init_store_depository(int agents) | @@ -130,18 +125,15 @@ void _fd_init_store_depository(int agents) | ||
130 | 125 | ||
131 | static void _fd_init_local_depository() | 126 | static void _fd_init_local_depository() |
132 | { | 127 | { |
133 | - if (split_stores) | 128 | + if (split_stores) // see if it has already been initialised |
134 | { | 129 | { |
135 | #ifdef STORE_IN_POOL | 130 | #ifdef STORE_IN_POOL |
136 | // copy the new store to the pool | 131 | // copy the new store to the pool |
137 | store = split_stores; | 132 | store = split_stores; |
138 | memcpy(store, main_store, STORE_SIZE); | 133 | memcpy(store, main_store, STORE_SIZE); |
139 | -#ifdef INDEX_IN_POOL | ||
140 | - split_variable[next_split_index] = -1; | ||
141 | -#else | ||
142 | - split_variable[next_split_index] = NULL; | ||
143 | -#endif | ||
144 | - ++next_split_index; | 134 | + |
135 | + split_variable[next_split_index] = -1; // starting anew | ||
136 | + next_split_index++; | ||
145 | #endif /* STORE_IN_POOL */ | 137 | #endif /* STORE_IN_POOL */ |
146 | 138 | ||
147 | return; | 139 | return; |
@@ -149,24 +141,24 @@ static void _fd_init_local_depository() | @@ -149,24 +141,24 @@ static void _fd_init_local_depository() | ||
149 | 141 | ||
150 | #ifndef GROWABLE_POOL | 142 | #ifndef GROWABLE_POOL |
151 | #ifndef STORE_IN_POOL | 143 | #ifndef STORE_IN_POOL |
152 | - _fd_debug("[%d.%d] stores size %d + %d\n", tid, agent, | 144 | + fd__trace("[%d.%d] stores size %d + %d\n", tid, agent, |
153 | fd_variables_count * STORE_SIZE, | 145 | fd_variables_count * STORE_SIZE, |
154 | fd_variables_count * sizeof(*split_variable)); | 146 | fd_variables_count * sizeof(*split_variable)); |
155 | if (posix_memalign((void **) &split_stores, sysconf(_SC_PAGESIZE), | 147 | if (posix_memalign((void **) &split_stores, sysconf(_SC_PAGESIZE), |
156 | fd_variables_count * STORE_SIZE + | 148 | fd_variables_count * STORE_SIZE + |
157 | fd_variables_count * sizeof(*split_variable))) | 149 | fd_variables_count * sizeof(*split_variable))) |
158 | - _fd_fatal("unable to allocate pool memory"); | 150 | + fd__fatal("unable to allocate pool memory"); |
159 | 151 | ||
160 | // XXX: alignment problems possible | 152 | // XXX: alignment problems possible |
161 | split_variable = ((void *) split_stores) + fd_variables_count * STORE_SIZE; | 153 | split_variable = ((void *) split_stores) + fd_variables_count * STORE_SIZE; |
162 | #else | 154 | #else |
163 | - _fd_debug("[%d.%d] stores size %d + %d\n", tid, agent, | 155 | + fd__trace("[%d.%d] stores size %d + %d\n", tid, agent, |
164 | (fd_variables_count + 1) * STORE_SIZE, | 156 | (fd_variables_count + 1) * STORE_SIZE, |
165 | fd_variables_count * sizeof(*split_variable)); | 157 | fd_variables_count * sizeof(*split_variable)); |
166 | if (posix_memalign((void **) &split_stores, sysconf(_SC_PAGESIZE), | 158 | if (posix_memalign((void **) &split_stores, sysconf(_SC_PAGESIZE), |
167 | (fd_variables_count + 1) * STORE_SIZE + | 159 | (fd_variables_count + 1) * STORE_SIZE + |
168 | fd_variables_count * sizeof(*split_variable))) | 160 | fd_variables_count * sizeof(*split_variable))) |
169 | - _fd_fatal("unable to allocate pool memory"); | 161 | + fd__fatal("unable to allocate pool memory"); |
170 | 162 | ||
171 | // XXX: alignment problems possible | 163 | // XXX: alignment problems possible |
172 | split_variable = ((void *) split_stores) + (fd_variables_count + 1) * STORE_SIZE; | 164 | split_variable = ((void *) split_stores) + (fd_variables_count + 1) * STORE_SIZE; |
@@ -180,21 +172,19 @@ static void _fd_init_local_depository() | @@ -180,21 +172,19 @@ static void _fd_init_local_depository() | ||
180 | fd__label_vars_count + 1 : POOL_DEFAULT_SIZE; | 172 | fd__label_vars_count + 1 : POOL_DEFAULT_SIZE; |
181 | #endif | 173 | #endif |
182 | 174 | ||
183 | - _fd_debug("[%d.%d] stores size %d + %d\n", tid, agent, pool_size * STORE_SIZE, | 175 | + fd__trace("[%d.%d] stores size %d + %d\n", tid, agent, pool_size * STORE_SIZE, |
184 | fd_variables_count * sizeof(*split_variable)); | 176 | fd_variables_count * sizeof(*split_variable)); |
185 | - | 177 | + |
186 | if (posix_memalign((void **) &split_stores, sysconf(_SC_PAGESIZE), | 178 | if (posix_memalign((void **) &split_stores, sysconf(_SC_PAGESIZE), |
187 | pool_size * STORE_SIZE)) | 179 | pool_size * STORE_SIZE)) |
188 | - _fd_fatal("unable to allocate pool memory"); | 180 | + fd__fatal("unable to allocate pool memory"); |
189 | 181 | ||
190 | if (posix_memalign((void **) &split_variable, sysconf(_SC_PAGESIZE), | 182 | if (posix_memalign((void **) &split_variable, sysconf(_SC_PAGESIZE), |
191 | fd_variables_count * sizeof(*split_variable))) | 183 | fd_variables_count * sizeof(*split_variable))) |
192 | - _fd_fatal("unable to allocate pool variable memory"); | 184 | + fd__fatal("unable to allocate pool variable memory"); |
193 | #endif /* GROWABLE_POOL */ | 185 | #endif /* GROWABLE_POOL */ |
194 | 186 | ||
195 | -#if defined(INDEX_IN_POOL) && !defined(split_variable) | ||
196 | split_variable_[agent] = split_variable; | 187 | split_variable_[agent] = split_variable; |
197 | -#endif | ||
198 | 188 | ||
199 | local_split_indexes = calloc(POOL_INDEXES, sizeof(*local_split_indexes)); | 189 | local_split_indexes = calloc(POOL_INDEXES, sizeof(*local_split_indexes)); |
200 | split_indexes[agent] = local_split_indexes; | 190 | split_indexes[agent] = local_split_indexes; |
@@ -204,12 +194,8 @@ static void _fd_init_local_depository() | @@ -204,12 +194,8 @@ static void _fd_init_local_depository() | ||
204 | main_store = store; | 194 | main_store = store; |
205 | store = split_stores; | 195 | store = split_stores; |
206 | memcpy(store, main_store, STORE_SIZE); | 196 | memcpy(store, main_store, STORE_SIZE); |
207 | -#ifdef INDEX_IN_POOL | ||
208 | split_variable[next_split_index] = -1; | 197 | split_variable[next_split_index] = -1; |
209 | -#else | ||
210 | - split_variable[next_split_index] = NULL; | ||
211 | -#endif | ||
212 | - ++next_split_index; | 198 | + next_split_index++; |
213 | #endif /* STORE_IN_POOL */ | 199 | #endif /* STORE_IN_POOL */ |
214 | } | 200 | } |
215 | 201 | ||
@@ -225,11 +211,11 @@ static void _fd_grow_pool(void) | @@ -225,11 +211,11 @@ static void _fd_grow_pool(void) | ||
225 | #else | 211 | #else |
226 | nsize = (fd_variables_count + 1 < nsize) ? fd_variables_count + 1 : nsize; | 212 | nsize = (fd_variables_count + 1 < nsize) ? fd_variables_count + 1 : nsize; |
227 | #endif | 213 | #endif |
228 | - _fd_debug("[%d.%d] new pool size is %d\n", tid, agent, nsize * STORE_SIZE); | ||
229 | - | 214 | + fd__trace("[%d.%d] new pool size is %d\n", tid, agent, nsize * STORE_SIZE); |
215 | + | ||
230 | if (posix_memalign((void **) &npool, sysconf(_SC_PAGESIZE), | 216 | if (posix_memalign((void **) &npool, sysconf(_SC_PAGESIZE), |
231 | nsize * STORE_SIZE)) | 217 | nsize * STORE_SIZE)) |
232 | - _fd_fatal("unable to allocate pool memory"); | 218 | + fd__fatal("unable to allocate pool memory"); |
233 | 219 | ||
234 | memcpy(npool, split_stores, pool_size * STORE_SIZE); | 220 | memcpy(npool, split_stores, pool_size * STORE_SIZE); |
235 | 221 | ||
@@ -251,7 +237,7 @@ static void _fd_grow_pool(void) | @@ -251,7 +237,7 @@ static void _fd_grow_pool(void) | ||
251 | } | 237 | } |
252 | #endif /* GROWABLE_POOL */ | 238 | #endif /* GROWABLE_POOL */ |
253 | 239 | ||
254 | -/* | 240 | +/* |
255 | saving a store to the pool is done in two steps: | 241 | saving a store to the pool is done in two steps: |
256 | 242 | ||
257 | 1. a copy of the store which is about to be split is saved (to have | 243 | 1. a copy of the store which is about to be split is saved (to have |
@@ -280,30 +266,18 @@ static void _fd_start_saving_store(_fd_store *dst) | @@ -280,30 +266,18 @@ static void _fd_start_saving_store(_fd_store *dst) | ||
280 | static void _fd_end_saving_store(fd_int variable) | 266 | static void _fd_end_saving_store(fd_int variable) |
281 | { | 267 | { |
282 | #ifndef STORE_IN_POOL | 268 | #ifndef STORE_IN_POOL |
283 | -#ifndef INDEX_IN_POOL | ||
284 | - split_variable[next_split_index] = variable; | ||
285 | -#else | ||
286 | split_variable[next_split_index] = variable->index; | 269 | split_variable[next_split_index] = variable->index; |
287 | -#endif | ||
288 | #else /* STORE_IN_POOL */ | 270 | #else /* STORE_IN_POOL */ |
289 | // here, the split also affects the store which is below the | 271 | // here, the split also affects the store which is below the |
290 | // (about to be) current one | 272 | // (about to be) current one |
291 | -#ifndef INDEX_IN_POOL | ||
292 | - split_variable[next_split_index - 1] = variable; | ||
293 | -#else | ||
294 | split_variable[next_split_index - 1] = variable->index; | 273 | split_variable[next_split_index - 1] = variable->index; |
295 | -#endif | ||
296 | #endif /* STORE_IN_POOL */ | 274 | #endif /* STORE_IN_POOL */ |
297 | 275 | ||
298 | - ++next_split_index; | 276 | + next_split_index++; |
299 | } | 277 | } |
300 | 278 | ||
301 | // try to steal a store from another agent | 279 | // try to steal a store from another agent |
302 | -#ifndef INDEX_IN_POOL | ||
303 | -bool _fd_steal_store(_fd_store store_, int agent, int retries) | ||
304 | -#else | ||
305 | bool _fd_steal_store(_fd_store store_, fd_int *variable, int agent, int retries) | 280 | bool _fd_steal_store(_fd_store store_, fd_int *variable, int agent, int retries) |
306 | -#endif | ||
307 | { | 281 | { |
308 | #ifndef RANDOM_VICTIM | 282 | #ifndef RANDOM_VICTIM |
309 | int v; // the victim | 283 | int v; // the victim |
@@ -317,7 +291,7 @@ bool _fd_steal_store(_fd_store store_, fd_int *variable, int agent, int retries) | @@ -317,7 +291,7 @@ bool _fd_steal_store(_fd_store store_, fd_int *variable, int agent, int retries) | ||
317 | 291 | ||
318 | #if defined(STORE_IN_POOL) && defined(DECREMENT_EARLY) | 292 | #if defined(STORE_IN_POOL) && defined(DECREMENT_EARLY) |
319 | if (agent != -1) | 293 | if (agent != -1) |
320 | - --next_split_index; | 294 | + next_split_index--; |
321 | #endif | 295 | #endif |
322 | 296 | ||
323 | // only let one agent in at a time | 297 | // only let one agent in at a time |
@@ -381,7 +355,7 @@ bool _fd_steal_store(_fd_store store_, fd_int *variable, int agent, int retries) | @@ -381,7 +355,7 @@ bool _fd_steal_store(_fd_store store_, fd_int *variable, int agent, int retries) | ||
381 | v = candidate; | 355 | v = candidate; |
382 | 356 | ||
383 | if (retrying) | 357 | if (retrying) |
384 | - _fd_debug("[%d.%d] %d tries left\n", tid, agent, retries); | 358 | + fd__trace("[%d.%d] %d tries left\n", tid, agent, retries); |
385 | 359 | ||
386 | break; | 360 | break; |
387 | } | 361 | } |
@@ -392,10 +366,10 @@ bool _fd_steal_store(_fd_store store_, fd_int *variable, int agent, int retries) | @@ -392,10 +366,10 @@ bool _fd_steal_store(_fd_store store_, fd_int *variable, int agent, int retries) | ||
392 | 366 | ||
393 | if (active == 0 || retries == 0) | 367 | if (active == 0 || retries == 0) |
394 | { | 368 | { |
395 | - _fd_debug("[%d.%d] no agent can supply work\n", tid, agent); | 369 | + fd__trace("[%d.%d] no agent can supply work\n", tid, agent); |
396 | 370 | ||
397 | if (retrying) | 371 | if (retrying) |
398 | - _fd_debug("[%d.%d] %d tries left\n", tid, agent, retries); | 372 | + fd__trace("[%d.%d] %d tries left\n", tid, agent, retries); |
399 | 373 | ||
400 | return false; | 374 | return false; |
401 | } | 375 | } |
@@ -429,13 +403,13 @@ bool _fd_steal_store(_fd_store store_, fd_int *variable, int agent, int retries) | @@ -429,13 +403,13 @@ bool _fd_steal_store(_fd_store store_, fd_int *variable, int agent, int retries) | ||
429 | // lock access to victim's stores | 403 | // lock access to victim's stores |
430 | pthread_mutex_lock(&stores_mutexes[v]); | 404 | pthread_mutex_lock(&stores_mutexes[v]); |
431 | #if DEBUG_STEALING > 1 | 405 | #if DEBUG_STEALING > 1 |
432 | - _fd_debug("[%d.%d] locked %d stores' mutex\n", tid, agent, v); | 406 | + fd__debug("[%d.%d] locked %d stores' mutex\n", tid, agent, v); |
433 | #endif | 407 | #endif |
434 | 408 | ||
435 | stores = split_indexes[v][1] - split_indexes[v][0]; | 409 | stores = split_indexes[v][1] - split_indexes[v][0]; |
436 | 410 | ||
437 | #if DEBUG_STEALING > 1 | 411 | #if DEBUG_STEALING > 1 |
438 | - _fd_debug("[%d.%d] %d stores left at %d\n", tid, agent, stores, v); | 412 | + fd__debug("[%d.%d] %d stores left at %d\n", tid, agent, stores, v); |
439 | #endif | 413 | #endif |
440 | 414 | ||
441 | // don't steal the last few stores from an agent | 415 | // don't steal the last few stores from an agent |
@@ -445,7 +419,7 @@ bool _fd_steal_store(_fd_store store_, fd_int *variable, int agent, int retries) | @@ -445,7 +419,7 @@ bool _fd_steal_store(_fd_store store_, fd_int *variable, int agent, int retries) | ||
445 | pthread_mutex_unlock(&thieves_mutex); | 419 | pthread_mutex_unlock(&thieves_mutex); |
446 | 420 | ||
447 | #ifdef DEBUG_STEALING | 421 | #ifdef DEBUG_STEALING |
448 | - _fd_debug("[%d.%d] not enough stores (%d) at %d\n", tid, agent, stores, v); | 422 | + fd__debug("[%d.%d] not enough stores (%d) at %d\n", tid, agent, stores, v); |
449 | #endif | 423 | #endif |
450 | 424 | ||
451 | return false; | 425 | return false; |
@@ -463,14 +437,12 @@ bool _fd_steal_store(_fd_store store_, fd_int *variable, int agent, int retries) | @@ -463,14 +437,12 @@ bool _fd_steal_store(_fd_store store_, fd_int *variable, int agent, int retries) | ||
463 | 437 | ||
464 | memcpy(store_, &split_stores_[v][s * fd_variables_count], STORE_SIZE); | 438 | memcpy(store_, &split_stores_[v][s * fd_variables_count], STORE_SIZE); |
465 | 439 | ||
466 | -#ifdef INDEX_IN_POOL | ||
467 | #ifndef STORE_IN_POOL | 440 | #ifndef STORE_IN_POOL |
468 | if (variable) | 441 | if (variable) |
469 | #else | 442 | #else |
470 | if (variable && split_variable_[v][s] != -1) | 443 | if (variable && split_variable_[v][s] != -1) |
471 | #endif | 444 | #endif |
472 | *variable = _fd_variables[split_variable_[v][s]]; | 445 | *variable = _fd_variables[split_variable_[v][s]]; |
473 | -#endif | ||
474 | 446 | ||
475 | // this agent will likely become the one with the largest search space | 447 | // this agent will likely become the one with the largest search space |
476 | // (if work is being stolen by the controller, most_work will be set | 448 | // (if work is being stolen by the controller, most_work will be set |
@@ -490,14 +462,10 @@ bool _fd_steal_store(_fd_store store_, fd_int *variable, int agent, int retries) | @@ -490,14 +462,10 @@ bool _fd_steal_store(_fd_store store_, fd_int *variable, int agent, int retries) | ||
490 | } | 462 | } |
491 | 463 | ||
492 | #ifdef DEBUG_STEALING | 464 | #ifdef DEBUG_STEALING |
493 | -#ifdef INDEX_IN_POOL | ||
494 | - _fd_debug("[%d.%d] stole work (%d/%d) from %d (var %d)\n", tid, agent, s, | 465 | + fd__debug("[%d.%d] stole work (%d/%d) from %d (var %d)\n", tid, agent, s, |
495 | stores, v, split_variable_[v][s]); | 466 | stores, v, split_variable_[v][s]); |
496 | -#else | ||
497 | - _fd_debug("[%d.%d] stole work (%d/%d) from %d\n", tid, agent, s, stores, v); | ||
498 | -#endif | ||
499 | #if DEBUG_STEALING > 2 | 467 | #if DEBUG_STEALING > 2 |
500 | - _fd_output("[%d.%d] ", tid, agent); _fd_cprint3(store_); | 468 | + fd__output("[%d.%d] ", tid, agent); _fd_cprint3(store_); |
501 | #endif | 469 | #endif |
502 | #endif | 470 | #endif |
503 | 471 | ||
@@ -523,7 +491,7 @@ bool _fd_steal_store(_fd_store store_, fd_int *variable, int agent, int retries) | @@ -523,7 +491,7 @@ bool _fd_steal_store(_fd_store store_, fd_int *variable, int agent, int retries) | ||
523 | 491 | ||
524 | #if defined(STORE_IN_POOL) && defined(DECREMENT_EARLY) | 492 | #if defined(STORE_IN_POOL) && defined(DECREMENT_EARLY) |
525 | if (agent != -1) | 493 | if (agent != -1) |
526 | - --next_split_index; | 494 | + next_split_index--; |
527 | #endif | 495 | #endif |
528 | 496 | ||
529 | pthread_spin_lock(&starving_lock); | 497 | pthread_spin_lock(&starving_lock); |
@@ -535,7 +503,7 @@ bool _fd_steal_store(_fd_store store_, fd_int *variable, int agent, int retries) | @@ -535,7 +503,7 @@ bool _fd_steal_store(_fd_store store_, fd_int *variable, int agent, int retries) | ||
535 | if (as == nagents) | 503 | if (as == nagents) |
536 | { | 504 | { |
537 | #ifdef DEBUG_STEALING | 505 | #ifdef DEBUG_STEALING |
538 | - _fd_debug("[%d.%d] all agents starving...\n", tid, agent); | 506 | + fd__debug("[%d.%d] all agents starving...\n", tid, agent); |
539 | #endif | 507 | #endif |
540 | 508 | ||
541 | return false; | 509 | return false; |
@@ -565,14 +533,14 @@ bool _fd_steal_store(_fd_store store_, fd_int *variable, int agent, int retries) | @@ -565,14 +533,14 @@ bool _fd_steal_store(_fd_store store_, fd_int *variable, int agent, int retries) | ||
565 | // lock access to victim's stores ... | 533 | // lock access to victim's stores ... |
566 | pthread_mutex_lock(&stores_mutexes[v]); | 534 | pthread_mutex_lock(&stores_mutexes[v]); |
567 | #if DEBUG_STEALING > 1 | 535 | #if DEBUG_STEALING > 1 |
568 | - _fd_debug("[%d.%d] locked %d stores' mutex\n", tid, agent, v); | 536 | + fd__debug("[%d.%d] locked %d stores' mutex\n", tid, agent, v); |
569 | #endif | 537 | #endif |
570 | 538 | ||
571 | // ... and make sure that the victim has enough stores | 539 | // ... and make sure that the victim has enough stores |
572 | stores = split_indexes[v][1] - split_indexes[v][0]; | 540 | stores = split_indexes[v][1] - split_indexes[v][0]; |
573 | 541 | ||
574 | #if DEBUG_STEALING > 1 | 542 | #if DEBUG_STEALING > 1 |
575 | - _fd_debug("[%d.%d] %d stores left at %d\n", tid, agent, stores, v); | 543 | + fd__debug("[%d.%d] %d stores left at %d\n", tid, agent, stores, v); |
576 | #endif | 544 | #endif |
577 | 545 | ||
578 | // don't steal the last few stores from an agent | 546 | // don't steal the last few stores from an agent |
@@ -583,7 +551,7 @@ bool _fd_steal_store(_fd_store store_, fd_int *variable, int agent, int retries) | @@ -583,7 +551,7 @@ bool _fd_steal_store(_fd_store store_, fd_int *variable, int agent, int retries) | ||
583 | pthread_mutex_unlock(&stores_mutexes[v]); | 551 | pthread_mutex_unlock(&stores_mutexes[v]); |
584 | 552 | ||
585 | #ifdef DEBUG_STEALING | 553 | #ifdef DEBUG_STEALING |
586 | - _fd_debug("[%d.%d] not enough stores (%d) at %d\n", tid, agent, | 554 | + fd__debug("[%d.%d] not enough stores (%d) at %d\n", tid, agent, |
587 | stores, v); | 555 | stores, v); |
588 | #endif | 556 | #endif |
589 | } | 557 | } |
@@ -596,7 +564,7 @@ bool _fd_steal_store(_fd_store store_, fd_int *variable, int agent, int retries) | @@ -596,7 +564,7 @@ bool _fd_steal_store(_fd_store store_, fd_int *variable, int agent, int retries) | ||
596 | // the main thread won't keep trying | 564 | // the main thread won't keep trying |
597 | if (agent == -1) | 565 | if (agent == -1) |
598 | { | 566 | { |
599 | - _fd_debug("[%d] giving up stealing\n", tid); | 567 | + fd__trace("[%d] giving up stealing\n", tid); |
600 | 568 | ||
601 | return false; | 569 | return false; |
602 | } | 570 | } |
@@ -608,7 +576,7 @@ bool _fd_steal_store(_fd_store store_, fd_int *variable, int agent, int retries) | @@ -608,7 +576,7 @@ bool _fd_steal_store(_fd_store store_, fd_int *variable, int agent, int retries) | ||
608 | if (as == nagents) | 576 | if (as == nagents) |
609 | { | 577 | { |
610 | #ifdef DEBUG_STEALING | 578 | #ifdef DEBUG_STEALING |
611 | - _fd_debug("[%d.%d] all agents starving...\n", tid, agent); | 579 | + fd__debug("[%d.%d] all agents starving...\n", tid, agent); |
612 | #endif | 580 | #endif |
613 | 581 | ||
614 | return false; | 582 | return false; |
@@ -619,7 +587,7 @@ bool _fd_steal_store(_fd_store store_, fd_int *variable, int agent, int retries) | @@ -619,7 +587,7 @@ bool _fd_steal_store(_fd_store store_, fd_int *variable, int agent, int retries) | ||
619 | #endif | 587 | #endif |
620 | 588 | ||
621 | #ifdef DEBUG_STEALING | 589 | #ifdef DEBUG_STEALING |
622 | - _fd_debug("[%d.%d] pausing...\n", tid, agent); | 590 | + fd__debug("[%d.%d] pausing...\n", tid, agent); |
623 | #endif | 591 | #endif |
624 | 592 | ||
625 | nanosleep(&delay, NULL); | 593 | nanosleep(&delay, NULL); |
@@ -631,7 +599,7 @@ bool _fd_steal_store(_fd_store store_, fd_int *variable, int agent, int retries) | @@ -631,7 +599,7 @@ bool _fd_steal_store(_fd_store store_, fd_int *variable, int agent, int retries) | ||
631 | if (as == nagents) | 599 | if (as == nagents) |
632 | { | 600 | { |
633 | #ifdef DEBUG_STEALING | 601 | #ifdef DEBUG_STEALING |
634 | - _fd_debug("[%d.%d] all agents starving...\n", tid, agent); | 602 | + fd__debug("[%d.%d] all agents starving...\n", tid, agent); |
635 | #endif | 603 | #endif |
636 | 604 | ||
637 | return false; | 605 | return false; |
@@ -667,14 +635,12 @@ bool _fd_steal_store(_fd_store store_, fd_int *variable, int agent, int retries) | @@ -667,14 +635,12 @@ bool _fd_steal_store(_fd_store store_, fd_int *variable, int agent, int retries) | ||
667 | 635 | ||
668 | memcpy(store_, &split_stores_[v][s * fd_variables_count], STORE_SIZE); | 636 | memcpy(store_, &split_stores_[v][s * fd_variables_count], STORE_SIZE); |
669 | 637 | ||
670 | -#ifdef INDEX_IN_POOL | ||
671 | #ifndef STORE_IN_POOL | 638 | #ifndef STORE_IN_POOL |
672 | if (variable) | 639 | if (variable) |
673 | #else | 640 | #else |
674 | if (variable && split_variable_[v][s] != -1) | 641 | if (variable && split_variable_[v][s] != -1) |
675 | #endif | 642 | #endif |
676 | *variable = _fd_variables[split_variable_[v][s]]; | 643 | *variable = _fd_variables[split_variable_[v][s]]; |
677 | -#endif | ||
678 | 644 | ||
679 | // this agent will likely become the one with the largest search space | 645 | // this agent will likely become the one with the largest search space |
680 | // (if work is being stolen by the controller, most_work will be set | 646 | // (if work is being stolen by the controller, most_work will be set |
@@ -697,14 +663,10 @@ bool _fd_steal_store(_fd_store store_, fd_int *variable, int agent, int retries) | @@ -697,14 +663,10 @@ bool _fd_steal_store(_fd_store store_, fd_int *variable, int agent, int retries) | ||
697 | } | 663 | } |
698 | 664 | ||
699 | #if DEBUG_STEALING > 0 | 665 | #if DEBUG_STEALING > 0 |
700 | -#ifdef INDEX_IN_POOL | ||
701 | - _fd_debug("[%d.%d] stole work (%d/%d) from %d (var %d)\n", tid, agent, s, | 666 | + fd__debug("[%d.%d] stole work (%d/%d) from %d (var %d)\n", tid, agent, s, |
702 | stores, v, split_variable_[v][s]); | 667 | stores, v, split_variable_[v][s]); |
703 | -#else | ||
704 | - _fd_debug("[%d.%d] stole work (%d/%d) from %d\n", tid, agent, s, stores, v); | ||
705 | -#endif | ||
706 | #if DEBUG_STEALING > 2 | 668 | #if DEBUG_STEALING > 2 |
707 | - _fd_output("[%d.%d] ", tid, agent); _fd_cprint3(store_); | 669 | + fd__output("[%d.%d] ", tid, agent); _fd_cprint3(store_); |
708 | #endif | 670 | #endif |
709 | #endif | 671 | #endif |
710 | 672 | ||
@@ -733,24 +695,20 @@ static bool _fd_restore_store(fd_int *variable) | @@ -733,24 +695,20 @@ static bool _fd_restore_store(fd_int *variable) | ||
733 | #if STEAL_WORK < 1 | 695 | #if STEAL_WORK < 1 |
734 | return false; | 696 | return false; |
735 | #else /* STEAL_WORK < 1 */ | 697 | #else /* STEAL_WORK < 1 */ |
736 | -#ifndef INDEX_IN_POOL | ||
737 | - return _fd_steal_store(store, agent, 0); | ||
738 | -#else | ||
739 | return _fd_steal_store(store, variable, agent, 0); | 698 | return _fd_steal_store(store, variable, agent, 0); |
740 | -#endif | ||
741 | #endif /* STEAL_WORK < 1 */ | 699 | #endif /* STEAL_WORK < 1 */ |
742 | 700 | ||
743 | #if STEAL_WORK > 0 | 701 | #if STEAL_WORK > 0 |
744 | if (next_split_index - base_split_index < INDEX_SAFE) | 702 | if (next_split_index - base_split_index < INDEX_SAFE) |
745 | { | 703 | { |
746 | - //_fd_debug("[%d.%d] have %d stores\n", tid, agent, next_split_index - base_split_index); | ||
747 | -#ifndef FAST | 704 | + //fd__trace("[%d.%d] have %d stores\n", tid, agent, next_split_index - base_split_index); |
705 | +#ifdef TRACE | ||
748 | if (pthread_mutex_trylock(&stores_mutexes[agent])) | 706 | if (pthread_mutex_trylock(&stores_mutexes[agent])) |
749 | - _fd_debug("[%d.%d] *** found stores locked [%d,%d[\n", tid, agent, | 707 | + fd__trace("[%d.%d] *** found stores locked [%d,%d[\n", tid, agent, |
750 | base_split_index, next_split_index), | 708 | base_split_index, next_split_index), |
751 | #endif | 709 | #endif |
752 | pthread_mutex_lock(&stores_mutexes[agent]); | 710 | pthread_mutex_lock(&stores_mutexes[agent]); |
753 | - //_fd_debug("[%d.%d] locked stores\n", tid, agent); | 711 | + //fd__trace("[%d.%d] locked stores\n", tid, agent); |
754 | 712 | ||
755 | locked = true; | 713 | locked = true; |
756 | } | 714 | } |
@@ -763,7 +721,7 @@ static bool _fd_restore_store(fd_int *variable) | @@ -763,7 +721,7 @@ static bool _fd_restore_store(fd_int *variable) | ||
763 | ++pool_gets; | 721 | ++pool_gets; |
764 | #endif | 722 | #endif |
765 | 723 | ||
766 | - --next_split_index; | 724 | + next_split_index--; |
767 | 725 | ||
768 | #ifndef STORE_IN_POOL | 726 | #ifndef STORE_IN_POOL |
769 | memcpy(store, &split_stores[next_split_index * fd_variables_count], | 727 | memcpy(store, &split_stores[next_split_index * fd_variables_count], |
@@ -774,18 +732,10 @@ static bool _fd_restore_store(fd_int *variable) | @@ -774,18 +732,10 @@ static bool _fd_restore_store(fd_int *variable) | ||
774 | #endif | 732 | #endif |
775 | 733 | ||
776 | #ifndef STORE_IN_POOL | 734 | #ifndef STORE_IN_POOL |
777 | -# ifndef INDEX_IN_POOL | ||
778 | - *variable = split_variable[next_split_index]; | ||
779 | -# else | ||
780 | *variable = _fd_variables[split_variable[next_split_index]]; | 735 | *variable = _fd_variables[split_variable[next_split_index]]; |
781 | -# endif /* INDEX_IN_POOL */ | ||
782 | #else | 736 | #else |
783 | -# ifndef INDEX_IN_POOL | ||
784 | - *variable = split_variable[next_split_index - 1]; | ||
785 | -# else | ||
786 | assert(split_variable[next_split_index - 1] != -1); | 737 | assert(split_variable[next_split_index - 1] != -1); |
787 | *variable = _fd_variables[split_variable[next_split_index - 1]]; | 738 | *variable = _fd_variables[split_variable[next_split_index - 1]]; |
788 | -# endif /* INDEX_IN_POOL */ | ||
789 | #endif /* STORE_IN_POOL */ | 739 | #endif /* STORE_IN_POOL */ |
790 | 740 | ||
791 | #if STEAL_WORK > 0 | 741 | #if STEAL_WORK > 0 |
src/problem.c
@@ -10,6 +10,8 @@ | @@ -10,6 +10,8 @@ | ||
10 | #include "values.h" | 10 | #include "values.h" |
11 | #include "constraints.h" | 11 | #include "constraints.h" |
12 | 12 | ||
13 | +#include "util.h" | ||
14 | + | ||
13 | extern int fd__workers; | 15 | extern int fd__workers; |
14 | 16 | ||
15 | static void _fd_cleanup(void); | 17 | static void _fd_cleanup(void); |
@@ -114,7 +116,7 @@ void fd_init(int *argc, char **argv[]) | @@ -114,7 +116,7 @@ void fd_init(int *argc, char **argv[]) | ||
114 | { | 116 | { |
115 | #ifdef SPLITGO_MPI | 117 | #ifdef SPLITGO_MPI |
116 | if (MPI_Init(argc, argv)) | 118 | if (MPI_Init(argc, argv)) |
117 | - _fd_fatal("MPI_Init failed"); | 119 | + fd__fatal("MPI_Init failed"); |
118 | #endif | 120 | #endif |
119 | 121 | ||
120 | _fd_parse_general_options(argc, *argv); | 122 | _fd_parse_general_options(argc, *argv); |
@@ -123,9 +125,7 @@ void fd_init(int *argc, char **argv[]) | @@ -123,9 +125,7 @@ void fd_init(int *argc, char **argv[]) | ||
123 | fd__init_splitgo(argc, *argv); | 125 | fd__init_splitgo(argc, *argv); |
124 | #endif | 126 | #endif |
125 | 127 | ||
126 | -#ifdef CONSTRAINT_CLASS | ||
127 | - _fd_init_constraints(); | ||
128 | -#endif | 128 | + fd__init_constraints(); |
129 | 129 | ||
130 | #ifdef USE_STORE | 130 | #ifdef USE_STORE |
131 | _fd_init_main_store(); | 131 | _fd_init_main_store(); |
src/revisions.c
@@ -7,6 +7,8 @@ | @@ -7,6 +7,8 @@ | ||
7 | #include "fdc_int.h" | 7 | #include "fdc_int.h" |
8 | #include "constraints.h" | 8 | #include "constraints.h" |
9 | 9 | ||
10 | +#include "util.h" | ||
11 | + | ||
10 | #ifdef REVISION_IS_VAR | 12 | #ifdef REVISION_IS_VAR |
11 | typedef fd_int revision; | 13 | typedef fd_int revision; |
12 | #else /* REVISION_IS_VAR */ | 14 | #else /* REVISION_IS_VAR */ |
@@ -181,7 +183,7 @@ int _fd_perform_revisions() | @@ -181,7 +183,7 @@ int _fd_perform_revisions() | ||
181 | if (_fd_propagate(c, v) == FD_NOSOLUTION) | 183 | if (_fd_propagate(c, v) == FD_NOSOLUTION) |
182 | { | 184 | { |
183 | #ifdef COUNT_REVISIONS | 185 | #ifdef COUNT_REVISIONS |
184 | - _fd_debug("failed after %d revisions\n", nr + 1); | 186 | + fd__debug("failed after %d revisions\n", nr + 1); |
185 | #endif | 187 | #endif |
186 | 188 | ||
187 | return FD_NOSOLUTION; | 189 | return FD_NOSOLUTION; |
@@ -212,7 +214,7 @@ int _fd_perform_revisions() | @@ -212,7 +214,7 @@ int _fd_perform_revisions() | ||
212 | free(r); | 214 | free(r); |
213 | 215 | ||
214 | #ifdef COUNT_REVISIONS | 216 | #ifdef COUNT_REVISIONS |
215 | - _fd_debug("failed after %d revisions\n", nr + 1); | 217 | + fd__debug("failed after %d revisions\n", nr + 1); |
216 | #endif | 218 | #endif |
217 | 219 | ||
218 | return FD_NOSOLUTION; | 220 | return FD_NOSOLUTION; |
@@ -228,7 +230,7 @@ int _fd_perform_revisions() | @@ -228,7 +230,7 @@ int _fd_perform_revisions() | ||
228 | #endif /* ORDER_REVISIONS */ | 230 | #endif /* ORDER_REVISIONS */ |
229 | 231 | ||
230 | #ifdef COUNT_REVISIONS | 232 | #ifdef COUNT_REVISIONS |
231 | - _fd_debug("performed %d revisions\n", nr); | 233 | + fd__debug("performed %d revisions\n", nr); |
232 | #endif | 234 | #endif |
233 | 235 | ||
234 | return FD_OK; | 236 | return FD_OK; |
@@ -251,7 +253,7 @@ static int filter_domains() | @@ -251,7 +253,7 @@ static int filter_domains() | ||
251 | if (_fd_filter(c) == FD_NOSOLUTION) | 253 | if (_fd_filter(c) == FD_NOSOLUTION) |
252 | { | 254 | { |
253 | #ifdef COUNT_REVISIONS | 255 | #ifdef COUNT_REVISIONS |
254 | - _fd_debug("failed after %d filtering steps\n", nr + 1); | 256 | + fd__debug("failed after %d filtering steps\n", nr + 1); |
255 | #endif | 257 | #endif |
256 | 258 | ||
257 | return FD_NOSOLUTION; | 259 | return FD_NOSOLUTION; |
@@ -263,7 +265,7 @@ static int filter_domains() | @@ -263,7 +265,7 @@ static int filter_domains() | ||
263 | } | 265 | } |
264 | 266 | ||
265 | #ifdef COUNT_REVISIONS | 267 | #ifdef COUNT_REVISIONS |
266 | - _fd_debug("performed %d filtering steps\n", nr); | 268 | + fd__debug("performed %d filtering steps\n", nr); |
267 | #endif | 269 | #endif |
268 | 270 | ||
269 | // revise domains wrt the variables whose domains changed | 271 | // revise domains wrt the variables whose domains changed |
@@ -272,9 +274,7 @@ static int filter_domains() | @@ -272,9 +274,7 @@ static int filter_domains() | ||
272 | 274 | ||
273 | int _fd_filter_domains() | 275 | int _fd_filter_domains() |
274 | { | 276 | { |
275 | -#ifdef CONSTRAINT_TEMPS | ||
276 | fd__constraint_data_reset(); | 277 | fd__constraint_data_reset(); |
277 | -#endif | ||
278 | 278 | ||
279 | return filter_domains(); | 279 | return filter_domains(); |
280 | } | 280 | } |
src/splitting.c
@@ -5,6 +5,8 @@ | @@ -5,6 +5,8 @@ | ||
5 | #include "values.h" | 5 | #include "values.h" |
6 | #include "store.h" | 6 | #include "store.h" |
7 | 7 | ||
8 | +#include "util.h" | ||
9 | + | ||
8 | #ifndef COMPACT_DOMAINS | 10 | #ifndef COMPACT_DOMAINS |
9 | #error "only works with COMPACT_DOMAINS" | 11 | #error "only works with COMPACT_DOMAINS" |
10 | #endif | 12 | #endif |
@@ -210,7 +212,7 @@ static int fd__split_even_one(int n, _fd_store stores[]) | @@ -210,7 +212,7 @@ static int fd__split_even_one(int n, _fd_store stores[]) | ||
210 | 212 | ||
211 | if (v == fd__label_vars_count) | 213 | if (v == fd__label_vars_count) |
212 | { | 214 | { |
213 | - _fd_debug("[%d] cannot split %d-ways evenly, resorting to even " | 215 | + fd__debug("[%d] cannot split %d-ways evenly, resorting to even " |
214 | "splitting\n", tid, n); | 216 | "splitting\n", tid, n); |
215 | 217 | ||
216 | return fd__split_even(n, stores); | 218 | return fd__split_even(n, stores); |
@@ -258,7 +260,7 @@ int fd__split_problem(int n, _fd_store stores[], | @@ -258,7 +260,7 @@ int fd__split_problem(int n, _fd_store stores[], | ||
258 | int v, p; | 260 | int v, p; |
259 | 261 | ||
260 | #ifdef DEBUG_SPLITTING | 262 | #ifdef DEBUG_SPLITTING |
261 | - _fd_output("before splitting: "); _fd_cprint3(store); | 263 | + fd__output("before splitting: "); _fd_cprint3(store); |
262 | #endif | 264 | #endif |
263 | 265 | ||
264 | parts = splitter(n, stores); | 266 | parts = splitter(n, stores); |
@@ -272,9 +274,9 @@ int fd__split_problem(int n, _fd_store stores[], | @@ -272,9 +274,9 @@ int fd__split_problem(int n, _fd_store stores[], | ||
272 | _fd_copy_value(SVALUE(stores[p][v]), DOMAIN(_fd_variables[v])); | 274 | _fd_copy_value(SVALUE(stores[p][v]), DOMAIN(_fd_variables[v])); |
273 | 275 | ||
274 | #ifdef DEBUG_SPLITTING | 276 | #ifdef DEBUG_SPLITTING |
275 | - _fd_output("split into %d out of %d stores\n", np, n); | 277 | + fd__output("split into %d out of %d stores\n", np, n); |
276 | for (p = 0; p < n; ++p) | 278 | for (p = 0; p < n; ++p) |
277 | - _fd_output("store %d: ", p), _fd_cprint3(stores[p]); | 279 | + fd__output("store %d: ", p), _fd_cprint3(stores[p]); |
278 | #endif | 280 | #endif |
279 | 281 | ||
280 | return parts; | 282 | return parts; |
src/util.c
@@ -2,13 +2,15 @@ | @@ -2,13 +2,15 @@ | ||
2 | #include <stdlib.h> | 2 | #include <stdlib.h> |
3 | #include <stdarg.h> | 3 | #include <stdarg.h> |
4 | 4 | ||
5 | -void _fd_fatal(char *msg) | 5 | +#include "util.h" |
6 | + | ||
7 | +void fd__fatal(char *msg) | ||
6 | { | 8 | { |
7 | fprintf(stderr, "%s\n", msg); | 9 | fprintf(stderr, "%s\n", msg); |
8 | abort(); // XXX | 10 | abort(); // XXX |
9 | } | 11 | } |
10 | 12 | ||
11 | -void _fd_error(char *format, ...) | 13 | +void fd__error(char *format, ...) |
12 | { | 14 | { |
13 | va_list args; | 15 | va_list args; |
14 | 16 | ||
@@ -17,7 +19,7 @@ void _fd_error(char *format, ...) | @@ -17,7 +19,7 @@ void _fd_error(char *format, ...) | ||
17 | va_end (args); | 19 | va_end (args); |
18 | } | 20 | } |
19 | 21 | ||
20 | -void _fd_output(char *format, ...) | 22 | +void fd__output(char *format, ...) |
21 | { | 23 | { |
22 | va_list args; | 24 | va_list args; |
23 | 25 | ||
@@ -35,9 +37,9 @@ void fd__info(char *format, ...) | @@ -35,9 +37,9 @@ void fd__info(char *format, ...) | ||
35 | va_end (args); | 37 | va_end (args); |
36 | } | 38 | } |
37 | 39 | ||
38 | -#ifndef _fd_debug | 40 | +#ifndef fd__debug |
39 | 41 | ||
40 | -void _fd_debug(char *format, ...) | 42 | +void fd__debug(char *format, ...) |
41 | { | 43 | { |
42 | va_list args; | 44 | va_list args; |
43 | 45 |
src/values-bitmap.c
@@ -58,10 +58,10 @@ fd_value fd_new_value(int min, int max) | @@ -58,10 +58,10 @@ fd_value fd_new_value(int min, int max) | ||
58 | fd_value v; | 58 | fd_value v; |
59 | 59 | ||
60 | if (min < MIN_VALUE) | 60 | if (min < MIN_VALUE) |
61 | - _fd_fatal("value less than MIN_VALUE"); | 61 | + fd__fatal("value less than MIN_VALUE"); |
62 | 62 | ||
63 | if (max > MAX_VALUE) | 63 | if (max > MAX_VALUE) |
64 | - _fd_fatal("value greater than MAX_VALUE"); | 64 | + fd__fatal("value greater than MAX_VALUE"); |
65 | 65 | ||
66 | #ifdef INLINE_DOMAINS | 66 | #ifdef INLINE_DOMAINS |
67 | return (ALL_ONES >> min) & (ALL_ONES << DOMAIN_BITS - max - 1); | 67 | return (ALL_ONES >> min) & (ALL_ONES << DOMAIN_BITS - max - 1); |
@@ -95,10 +95,10 @@ fd_value fd_new_value(int min, int max) | @@ -95,10 +95,10 @@ fd_value fd_new_value(int min, int max) | ||
95 | void _fd_init_domain(DOMAIN_REF_T(domain), int min, int max) | 95 | void _fd_init_domain(DOMAIN_REF_T(domain), int min, int max) |
96 | { | 96 | { |
97 | if (min < MIN_VALUE) | 97 | if (min < MIN_VALUE) |
98 | - _fd_fatal("value less than MIN_VALUE"); | 98 | + fd__fatal("value less than MIN_VALUE"); |
99 | 99 | ||
100 | if (max > MAX_VALUE) | 100 | if (max > MAX_VALUE) |
101 | - _fd_fatal("value greater than MAX_VALUE"); | 101 | + fd__fatal("value greater than MAX_VALUE"); |
102 | 102 | ||
103 | #if WORDS == 1 | 103 | #if WORDS == 1 |
104 | (*domain)[0] = (ALL_ONES >> min) & (ALL_ONES << DOMAIN_BITS - max - 1); | 104 | (*domain)[0] = (ALL_ONES >> min) & (ALL_ONES << DOMAIN_BITS - max - 1); |
@@ -1278,10 +1278,10 @@ fd_value fd_new_value(int min, int max) | @@ -1278,10 +1278,10 @@ fd_value fd_new_value(int min, int max) | ||
1278 | fd_value v; | 1278 | fd_value v; |
1279 | 1279 | ||
1280 | if (min < MIN_VALUE) | 1280 | if (min < MIN_VALUE) |
1281 | - _fd_fatal("value less than MIN_VALUE"); | 1281 | + fd__fatal("value less than MIN_VALUE"); |
1282 | 1282 | ||
1283 | if (max > MAX_VALUE) | 1283 | if (max > MAX_VALUE) |
1284 | - _fd_fatal("value greater than MAX_VALUE"); | 1284 | + fd__fatal("value greater than MAX_VALUE"); |
1285 | 1285 | ||
1286 | #if WORDS == 1 | 1286 | #if WORDS == 1 |
1287 | if (v = malloc(sizeof(*v))) | 1287 | if (v = malloc(sizeof(*v))) |
@@ -1320,10 +1320,10 @@ fd_value fd_new_value(int min, int max) | @@ -1320,10 +1320,10 @@ fd_value fd_new_value(int min, int max) | ||
1320 | void _fd_init_domain(DOMAIN_REF_T(domain), int min, int max) | 1320 | void _fd_init_domain(DOMAIN_REF_T(domain), int min, int max) |
1321 | { | 1321 | { |
1322 | if (min < MIN_VALUE) | 1322 | if (min < MIN_VALUE) |
1323 | - _fd_fatal("value less than MIN_VALUE"); | 1323 | + fd__fatal("value less than MIN_VALUE"); |
1324 | 1324 | ||
1325 | if (max > MAX_VALUE) | 1325 | if (max > MAX_VALUE) |
1326 | - _fd_fatal("value greater than MAX_VALUE"); | 1326 | + fd__fatal("value greater than MAX_VALUE"); |
1327 | 1327 | ||
1328 | #if WORDS == 1 | 1328 | #if WORDS == 1 |
1329 | *domain->map = (ALL_ONES >> min) & (ALL_ONES << DOMAIN_BITS - max - 1); | 1329 | *domain->map = (ALL_ONES >> min) & (ALL_ONES << DOMAIN_BITS - max - 1); |
src/values-intervals.c
@@ -90,10 +90,10 @@ int _fd_val_max(fd_value domain) | @@ -90,10 +90,10 @@ int _fd_val_max(fd_value domain) | ||
90 | case FD_MULTIPLE: | 90 | case FD_MULTIPLE: |
91 | return v->value.interval.upper; | 91 | return v->value.interval.upper; |
92 | case FD_EMPTY: | 92 | case FD_EMPTY: |
93 | - _fd_fatal("empty domain in _fd_val_max"); | 93 | + fd__fatal("empty domain in _fd_val_max"); |
94 | /* NOTREACHED */ | 94 | /* NOTREACHED */ |
95 | default: | 95 | default: |
96 | - _fd_fatal("corrupt domain in _fd_val_max?"); | 96 | + fd__fatal("corrupt domain in _fd_val_max?"); |
97 | /* NOTREACHED */ | 97 | /* NOTREACHED */ |
98 | } | 98 | } |
99 | } | 99 | } |
@@ -108,10 +108,10 @@ int _fd_val_min(fd_value domain) | @@ -108,10 +108,10 @@ int _fd_val_min(fd_value domain) | ||
108 | case FD_MULTIPLE: | 108 | case FD_MULTIPLE: |
109 | return domain->value.interval.lower; | 109 | return domain->value.interval.lower; |
110 | case FD_EMPTY: | 110 | case FD_EMPTY: |
111 | - _fd_fatal("empty domain in _fd_val_min"); | 111 | + fd__fatal("empty domain in _fd_val_min"); |
112 | /* NOTREACHED */ | 112 | /* NOTREACHED */ |
113 | default: | 113 | default: |
114 | - _fd_fatal("corrupt domain in _fd_val_min?"); | 114 | + fd__fatal("corrupt domain in _fd_val_min?"); |
115 | /* NOTREACHED */ | 115 | /* NOTREACHED */ |
116 | } | 116 | } |
117 | } | 117 | } |
@@ -151,10 +151,10 @@ int _fd_val_del_min(fd_value domain) | @@ -151,10 +151,10 @@ int _fd_val_del_min(fd_value domain) | ||
151 | 151 | ||
152 | break; | 152 | break; |
153 | case FD_EMPTY: | 153 | case FD_EMPTY: |
154 | - _fd_fatal("empty domain in _fd_val_del_min"); | 154 | + fd__fatal("empty domain in _fd_val_del_min"); |
155 | /* NOTREACHED */ | 155 | /* NOTREACHED */ |
156 | default: | 156 | default: |
157 | - _fd_fatal("corrupt domain in _fd_val_del_min?"); | 157 | + fd__fatal("corrupt domain in _fd_val_del_min?"); |
158 | /* NOTREACHED */ | 158 | /* NOTREACHED */ |
159 | } | 159 | } |
160 | 160 | ||
@@ -198,10 +198,10 @@ int _fd_val_del_max(fd_value domain) | @@ -198,10 +198,10 @@ int _fd_val_del_max(fd_value domain) | ||
198 | 198 | ||
199 | break; | 199 | break; |
200 | case FD_EMPTY: | 200 | case FD_EMPTY: |
201 | - _fd_fatal("empty domain in _fd_val_del_max"); | 201 | + fd__fatal("empty domain in _fd_val_del_max"); |
202 | /* NOTREACHED */ | 202 | /* NOTREACHED */ |
203 | default: | 203 | default: |
204 | - _fd_fatal("corrupt domain in _fd_val_del_max?"); | 204 | + fd__fatal("corrupt domain in _fd_val_del_max?"); |
205 | /* NOTREACHED */ | 205 | /* NOTREACHED */ |
206 | } | 206 | } |
207 | 207 | ||
@@ -230,10 +230,10 @@ int _fd_val_contains_val(fd_value domain, int value) | @@ -230,10 +230,10 @@ int _fd_val_contains_val(fd_value domain, int value) | ||
230 | 230 | ||
231 | break; | 231 | break; |
232 | case FD_EMPTY: | 232 | case FD_EMPTY: |
233 | - _fd_fatal("empty domain in _fd_val_contains_val"); | 233 | + fd__fatal("empty domain in _fd_val_contains_val"); |
234 | /* NOTREACHED */ | 234 | /* NOTREACHED */ |
235 | default: | 235 | default: |
236 | - _fd_fatal("corrupt domain in _fd_val_contains_val?"); | 236 | + fd__fatal("corrupt domain in _fd_val_contains_val?"); |
237 | /* NOTREACHED */ | 237 | /* NOTREACHED */ |
238 | } | 238 | } |
239 | 239 | ||
@@ -249,7 +249,7 @@ void _fd_val_set_value(fd_value domain, int value) | @@ -249,7 +249,7 @@ void _fd_val_set_value(fd_value domain, int value) | ||
249 | switch (domain->kind) | 249 | switch (domain->kind) |
250 | { | 250 | { |
251 | case FD_EMPTY: | 251 | case FD_EMPTY: |
252 | - _fd_fatal("_fd_val_set_val called on a variable with empty domain"); | 252 | + fd__fatal("_fd_val_set_val called on a variable with empty domain"); |
253 | /* NOTREACHED */ | 253 | /* NOTREACHED */ |
254 | case FD_MULTIPLE: | 254 | case FD_MULTIPLE: |
255 | domain->kind = FD_SINGLETON; | 255 | domain->kind = FD_SINGLETON; |
@@ -262,7 +262,7 @@ void _fd_val_set_value(fd_value domain, int value) | @@ -262,7 +262,7 @@ void _fd_val_set_value(fd_value domain, int value) | ||
262 | } | 262 | } |
263 | break; | 263 | break; |
264 | default: | 264 | default: |
265 | - _fd_fatal("corrupt domain in _fd_val_set_value?"); | 265 | + fd__fatal("corrupt domain in _fd_val_set_value?"); |
266 | /* NOTREACHED */ | 266 | /* NOTREACHED */ |
267 | } | 267 | } |
268 | } | 268 | } |
@@ -702,7 +702,7 @@ fd_value _fd_val_clone(fd_value value) | @@ -702,7 +702,7 @@ fd_value _fd_val_clone(fd_value value) | ||
702 | *next = fd_new_value(1, 0); | 702 | *next = fd_new_value(1, 0); |
703 | break; | 703 | break; |
704 | default: | 704 | default: |
705 | - _fd_fatal("corrupt domain in _fd_val_clone?"); | 705 | + fd__fatal("corrupt domain in _fd_val_clone?"); |
706 | /* NOTREACHED */ | 706 | /* NOTREACHED */ |
707 | } | 707 | } |
708 | 708 | ||
@@ -744,7 +744,7 @@ void _fd_val_copy(fd_value to, fd_value from) | @@ -744,7 +744,7 @@ void _fd_val_copy(fd_value to, fd_value from) | ||
744 | break; | 744 | break; |
745 | #endif | 745 | #endif |
746 | default: | 746 | default: |
747 | - _fd_fatal("corrupt domain in _fd_val_copy?"); | 747 | + fd__fatal("corrupt domain in _fd_val_copy?"); |
748 | /* NOTREACHED */ | 748 | /* NOTREACHED */ |
749 | } | 749 | } |
750 | 750 | ||
@@ -769,7 +769,7 @@ int _fd_val_size(fd_value domain) | @@ -769,7 +769,7 @@ int _fd_val_size(fd_value domain) | ||
769 | s += v->value.interval.upper - v->value.interval.lower + 1; | 769 | s += v->value.interval.upper - v->value.interval.lower + 1; |
770 | break; | 770 | break; |
771 | default: | 771 | default: |
772 | - _fd_fatal("corrupt domain in _fd_val_size?"); | 772 | + fd__fatal("corrupt domain in _fd_val_size?"); |
773 | /* NOTREACHED */ | 773 | /* NOTREACHED */ |
774 | } | 774 | } |
775 | 775 |
src/values.c
src/variables.c
@@ -9,18 +9,31 @@ | @@ -9,18 +9,31 @@ | ||
9 | #include "store.h" | 9 | #include "store.h" |
10 | #include "constraints.h" | 10 | #include "constraints.h" |
11 | 11 | ||
12 | +#include "util.h" | ||
13 | + | ||
12 | int fd_variables_count = 0; | 14 | int fd_variables_count = 0; |
13 | __thread fd_int _fd_variables[MAX_VARIABLES]; | 15 | __thread fd_int _fd_variables[MAX_VARIABLES]; |
14 | 16 | ||
17 | +// variables with singleton domains (ie, constants) | ||
18 | +static fd_int fd__constants[MAX_VALUE + 1]; | ||
19 | + | ||
15 | fd_int *fd__label_vars = 0; // variables subject to labelling | 20 | fd_int *fd__label_vars = 0; // variables subject to labelling |
16 | int fd__label_vars_count = 0; | 21 | int fd__label_vars_count = 0; |
17 | bool *fd__var_labelled; // identifies the variables subject to labelling | 22 | bool *fd__var_labelled; // identifies the variables subject to labelling |
18 | 23 | ||
19 | -fd_int fd_new(int min, int max) | 24 | + |
25 | +/* | ||
26 | + Create and return a new variable with domain { MIN, ..., MAX }. | ||
27 | + Also store it in the global variable table. | ||
28 | +*/ | ||
29 | +static fd_int create_variable(int min, int max) | ||
20 | { | 30 | { |
21 | - fd_int v = malloc(sizeof(struct fd_int)); | 31 | + fd_int v; |
22 | 32 | ||
23 | - assert(fd_variables_count < MAX_VARIABLES); | 33 | + if (fd_variables_count == MAX_VARIABLES) |
34 | + fd__fatal("too many variables, increase MAX_VARIABLES"); | ||
35 | + | ||
36 | + v = malloc(sizeof(struct fd_int)); | ||
24 | 37 | ||
25 | if (v) | 38 | if (v) |
26 | { | 39 | { |
@@ -39,6 +52,31 @@ fd_int fd_new(int min, int max) | @@ -39,6 +52,31 @@ fd_int fd_new(int min, int max) | ||
39 | return v; | 52 | return v; |
40 | } | 53 | } |
41 | 54 | ||
55 | +/* Return a variable with singleton domain { VALUE }. */ | ||
56 | +fd_int fd_const(int value) | ||
57 | +{ | ||
58 | + if (value < MIN_VALUE) | ||
59 | + fd__fatal("value less than MIN_VALUE"); | ||
60 | + | ||
61 | + if (value > MAX_VALUE) | ||
62 | + fd__fatal("value greater than MAX_VALUE"); | ||
63 | + | ||
64 | + // only create the variable if it has not yet been created | ||
65 | + if (fd__constants[value] == NULL) | ||
66 | + fd__constants[value] = create_variable(value, value); | ||
67 | + | ||
68 | + return fd__constants[value]; | ||
69 | +} | ||
70 | + | ||
71 | +/* Return a variable with domain { MIN, ..., MAX }. */ | ||
72 | +fd_int fd_new(int min, int max) | ||
73 | +{ | ||
74 | + if (min == max) | ||
75 | + return fd_const(min); | ||
76 | + else | ||
77 | + return create_variable(min, max); | ||
78 | +} | ||
79 | + | ||
42 | #ifdef SPLITGO | 80 | #ifdef SPLITGO |
43 | /* create a skeletal copy of VARIABLE */ // XXX: description | 81 | /* create a skeletal copy of VARIABLE */ // XXX: description |
44 | fd_int _fd_var_copy(fd_int variable) | 82 | fd_int _fd_var_copy(fd_int variable) |
@@ -302,7 +340,7 @@ void _fd_var_set_value(fd_int variable, int value) | @@ -302,7 +340,7 @@ void _fd_var_set_value(fd_int variable, int value) | ||
302 | void fd_label(fd_int variables[], int n) | 340 | void fd_label(fd_int variables[], int n) |
303 | { | 341 | { |
304 | if (fd__label_vars) | 342 | if (fd__label_vars) |
305 | - _fd_fatal("fd_label() can only be called once"); | 343 | + fd__fatal("fd_label() can only be called once"); |
306 | 344 | ||
307 | fd__label_vars = malloc(n * sizeof(*fd__label_vars)); // XXX: NULL | 345 | fd__label_vars = malloc(n * sizeof(*fd__label_vars)); // XXX: NULL |
308 | fd__label_vars_count = n; | 346 | fd__label_vars_count = n; |
src/variables.h
@@ -7,6 +7,7 @@ extern fd_int *fd__label_vars; | @@ -7,6 +7,7 @@ extern fd_int *fd__label_vars; | ||
7 | extern int fd__label_vars_count; | 7 | extern int fd__label_vars_count; |
8 | extern bool *fd__var_labelled; | 8 | extern bool *fd__var_labelled; |
9 | 9 | ||
10 | +fd_int fd_const(int value); | ||
10 | fd_int fd_new(int min, int max); | 11 | fd_int fd_new(int min, int max); |
11 | fd_int _fd_var_copy(fd_int variable); | 12 | fd_int _fd_var_copy(fd_int variable); |
12 | void _fd_var_copy_domain(fd_int to, fd_int from); | 13 | void _fd_var_copy_domain(fd_int to, fd_int from); |
@@ -36,15 +37,15 @@ int _fd_var_intersect(fd_int variable1, fd_int variable2); | @@ -36,15 +37,15 @@ int _fd_var_intersect(fd_int variable1, fd_int variable2); | ||
36 | int _fd_var_contains_val(fd_int variable, int value); | 37 | int _fd_var_contains_val(fd_int variable, int value); |
37 | void _fd_var_set_value(fd_int variable, int value); | 38 | void _fd_var_set_value(fd_int variable, int value); |
38 | 39 | ||
39 | -#define fd_update_domain(op,var,value) \ | ||
40 | - { \ | ||
41 | - _fd_var_ ## op(var, value); \ | ||
42 | - \ | ||
43 | - _fd_revise_connected(var); \ | ||
44 | - } | 40 | +#define fd_update_domain(op, val, var) \ |
41 | + do { \ | ||
42 | + _fd_var_ ## op(val, var); \ | ||
43 | + \ | ||
44 | + _fd_revise_connected(this, var); \ | ||
45 | + } while (0) | ||
45 | 46 | ||
46 | #define fd_update_domain_and_check(op, val, var) \ | 47 | #define fd_update_domain_and_check(op, val, var) \ |
47 | - { \ | 48 | + do { \ |
48 | if (_fd_var_ ## op(val, var)) \ | 49 | if (_fd_var_ ## op(val, var)) \ |
49 | { \ | 50 | { \ |
50 | if (fd_domain_empty(var)) \ | 51 | if (fd_domain_empty(var)) \ |
@@ -52,7 +53,7 @@ void _fd_var_set_value(fd_int variable, int value); | @@ -52,7 +53,7 @@ void _fd_var_set_value(fd_int variable, int value); | ||
52 | \ | 53 | \ |
53 | _fd_revise_connected(this, var); \ | 54 | _fd_revise_connected(this, var); \ |
54 | } \ | 55 | } \ |
55 | - } | 56 | + } while (0) |
56 | 57 | ||
57 | // SEARCH | 58 | // SEARCH |
58 | extern int (*fd__cmp_variables)(fd_int, fd_int); | 59 | extern int (*fd__cmp_variables)(fd_int, fd_int); |