this repo has no description
at develop 26 kB view raw
1#!/usr/bin/perl 2# 3# Main authors: 4# Christian Schulte <schulte@gecode.org> 5# 6# Copyright: 7# Christian Schulte, 2007 8# 9# This file is part of Gecode, the generic constraint 10# development environment: 11# http://www.gecode.org 12# 13# Permission is hereby granted, free of charge, to any person obtaining 14# a copy of this software and associated documentation files (the 15# "Software"), to deal in the Software without restriction, including 16# without limitation the rights to use, copy, modify, merge, publish, 17# distribute, sublicense, and/or sell copies of the Software, and to 18# permit persons to whom the Software is furnished to do so, subject to 19# the following conditions: 20# 21# The above copyright notice and this permission notice shall be 22# included in all copies or substantial portions of the Software. 23# 24# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 27# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 28# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 29# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 30# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 31# 32# 33 34while (($arg = $ARGV[$i]) && ($arg =~ /^-/)) { 35 $i++; 36 if ($arg eq "-header") { 37 $gen_header = 1; 38 } elsif ($arg eq "-typehpp") { 39 $gen_typehpp = 1; 40 } 41} 42 43$n_files = 0; 44while ($arg = $ARGV[$i]) { 45 $files[$n_files] = $arg; 46 $n_files++; $i++; 47} 48 49print <<EOF 50/* 51 * CAUTION: 52 * This file has been automatically generated. Do not edit, 53 * edit the following files instead: 54EOF 55; 56 57for ($f=0; $f<$n_files; $f++) { 58 print " * - $files[$f]\n"; 59} 60 61print <<EOF 62 * 63 * This file contains generated code fragments which are 64 * copyrighted as follows: 65 * 66 * Main author: 67 * Christian Schulte <schulte\@gecode.org> 68 * 69 * Copyright: 70 * Christian Schulte, 2007 71 * 72 * The generated code fragments are part of Gecode, the generic 73 * constraint development environment: 74 * http://www.gecode.org 75 * 76 * Permission is hereby granted, free of charge, to any person obtaining 77 * a copy of this software and associated documentation files (the 78 * "Software"), to deal in the Software without restriction, including 79 * without limitation the rights to use, copy, modify, merge, publish, 80 * distribute, sublicense, and/or sell copies of the Software, and to 81 * permit persons to whom the Software is furnished to do so, subject to 82 * the following conditions: 83 * 84 * The above copyright notice and this permission notice shall be 85 * included in all copies or substantial portions of the Software. 86 * 87 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 88 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 89 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 90 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 91 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 92 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 93 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 94 * 95 */ 96 97EOF 98; 99 100for ($f=0; $f<$n_files; $f++) { 101 open (FILE, $files[$f]) || die "Could not open ".$files[$f]; 102 103 ## General values 104 $name[$f] = ""; 105 $vti[$f] = ""; 106 $ifdef[$f] = ""; 107 $endif[$f] = ""; 108 $dispose[$f] = 0; 109 110 ## 111 ## Headers and footers 112 ## 113 $mehdr[$f] = ""; # Header text for modification events 114 $meftr[$f] = ""; # Footer text for modification events 115 116 $pchdr[$f] = ""; # Header text for propagation conditions 117 $pcftr[$f] = ""; # Footer text for propagation conditions 118 119 ## 120 ## Real stuff 121 ## 122 123 # $mec[$f] : combination table 124 # $men[$f] : name table 125 # $meh[$f] : header table 126 $me_n[$f] = 0; # running number of modification events 127 $me_subscribe[$f] = ""; 128 129 # $pcn[$f] : name table 130 # $pch[$f] : header table 131 $pc_n[$f] = 0; # running number of propagation conditions 132 133 134 $free_bits[$f] = 0; 135 136 while ($l = <FILE>) { 137 LINE: 138 next if ($l =~ /^\#/); 139 last if ($l =~ /^\[End\]/io); 140 141 if ($l =~ /^\[General\]/io) { 142 while (($l = <FILE>) && !($l =~ /^\[/)) { 143 next if ($l =~ /^\#/); 144 if ($l =~ /^Name:\s*(\w+)/io) { 145 $name[$f] = $1; 146 $vti[$f] = uc($name[$f]); 147 } elsif ($l =~ /^Ifdef:\s*(\w+)/io) { 148 $ifdef[$f] = "#ifdef $1\n"; 149 $endif[$f] = "#endif\n"; 150 } elsif ($l =~ /^Dispose:\s*true/io) { 151 $dispose[$f] = 1; 152 } elsif ($l =~ /^Namespace:\s*([^ \t\r\n]+)/io) { 153 $namespace[$f] = $1; 154 } elsif ($l =~ /^Bits:\s*([^ \t\r\n]+)/io) { 155 $free_bits[$f] = $1+0; 156 } 157 } 158 goto LINE; 159 } elsif ($l =~ /^\[ModEventHeader\]/io) { 160 while (($l = <FILE>) && !($l =~ /^\[/)) { 161 next if ($l =~ /^\#/); 162 $mehdr[$f] = $mehdr[$f] . $l; 163 } 164 goto LINE; 165 } elsif ($l =~ /^\[ModEvent\]/io) { 166 $n = ""; 167 $h = ""; 168 169 while (($l = <FILE>) && !($l =~ /^\[/)) { 170 next if ($l =~ /^\#/); 171 if ($l =~ /^Name:\s*(\w+)\s*=\s*(\w+)/io) { 172 # Found a special modification event 173 $lhs = $1; $rhs = $2; 174 if (!($rhs eq "FAILED") && !($rhs eq "NONE") && 175 !($rhs eq "ASSIGNED") && !($rhs eq "SUBSCRIBE")) { 176 die "Unknown special modification event: $rhs\n"; 177 } 178 if ($rhs eq "SUBSCRIBE") { 179 $me_subscribe[$f] = "ME_$vti[$f]_$lhs"; 180 } else { 181 $mespecial{$f}{$lhs} = $rhs; 182 if ($rhs eq "ASSIGNED") { 183 $me_assigned[$f] = "ME_$vti[$f]_$lhs"; 184 } elsif ($rhs eq "FAILED") { 185 $me_failed[$f] = "ME_$vti[$f]_$lhs"; 186 } 187 } 188 $n = $lhs; 189 } elsif ($l =~ /^Name:\s*(\w+)/io) { 190 # Found a normal modification event 191 $n = $1; 192 } elsif ($l =~ /^Combine:\s*(.+)/io) { 193 # Found combination information 194 $combines = $1; 195 while ($combines =~ /(\w+)\s*=(\w+)/g) { 196 $mec{$f}{$n}{$1} = $2; 197 $mec{$f}{$1}{$n} = $2; 198 } 199 } else { 200 $h = $h . $l; 201 } 202 } 203 $men[$f][$me_n[$f]] = $n; 204 $meh[$f][$me_n[$f]] = $h; 205 $me_n[$f]++; 206 $mec{$f}{"NONE"}{$n} = $n; 207 $mec{$f}{$n}{"NONE"} = $n; 208 goto LINE; 209 } elsif ($l =~ /^\[ModEventFooter\]/io) { 210 while (($l = <FILE>) && !($l =~ /^\[/)) { 211 next if ($l =~ /^\#/); 212 $meftr[$f] = $meftr[$f] . $l; 213 } 214 goto LINE; 215 } elsif ($l =~ /^\[PropCondHeader\]/io) { 216 while (($l = <FILE>) && !($l =~ /^\[/)) { 217 next if ($l =~ /^\#/); 218 $pchdr[$f] = $pchdr[$f] . $l; 219 } 220 goto LINE; 221 } elsif ($l =~ /^\[PropCond\]/io) { 222 $n = ""; 223 $h = ""; 224 225 while (($l = <FILE>) && !($l =~ /^\[/)) { 226 next if ($l =~ /^\#/); 227 if ($l =~ /^Name:\s*(\w+)\s*=\s*(\w+)/io) { 228 # Found a special propagation condition 229 $lhs = $1; $rhs = $2; 230 if (!($rhs eq "ASSIGNED") && !($rhs eq "NONE")) { 231 die "Unknown special propagation condition: $rhs\n"; 232 } 233 $pcspecial{$f}{$lhs} = $rhs; 234 if ($rhs eq "ASSIGNED") { 235 $pc_assigned[$f] = "PC_$vti[$f]_$lhs"; 236 } 237 if ($rhs eq "NONE") { 238 $pc_none[$f] = "PC_$vti[$f]_$lhs"; 239 } 240 $n = $lhs; 241 } elsif ($l =~ /^Name:\s*(\w+)/io) { 242 # Found a normal modification event 243 $n = $1; 244 } elsif ($l =~ /^ScheduledBy:\s*(.+)/io) { 245 # Found relation to modification events 246 $events = $1; 247 while ($events =~ /(\w+)/g) { 248 $mepc{$f}{$1}{$n} = 1; 249 } 250 } else { 251 $h = $h . $l; 252 } 253 } 254 $pcn[$f][$pc_n[$f]] = $n; 255 $pch[$f][$pc_n[$f]] = $h; 256 $pc_n[$f]++; 257 goto LINE; 258 } elsif ($l =~ /^\[PropCondFooter\]/io) { 259 while (($l = <FILE>) && !($l =~ /^\[/)) { 260 next if ($l =~ /^\#/); 261 $pcftr[$f] = $pcftr[$f] . $l; 262 } 263 goto LINE; 264 } 265 266 } 267 close FILE; 268 269 270 $maxpc[$f] = "PC_$vti[$f]_" . $pcn[$f][$pc_n[$f]-1]; 271 $class[$f] = "$name[$f]VarImpBase"; 272 $conf[$f] = "$name[$f]VarImpConf"; 273 $base[$f] = "Gecode::VarImp<$namespace[$f]::$conf[$f]>"; 274 # Generate namespace header and footer 275 foreach $ns (split('::',$namespace[$f])) { 276 $hdr[$f] = "$hdr[$f]namespace $ns { "; 277 $ftr[$f] = "$ftr[$f]}"; 278 } 279 $hdr[$f] =~ s| $||g; 280 $hdr[$f] = "$hdr[$f]\n"; 281 $ftr[$f] = "$ftr[$f]\n"; 282 283 ## Check whether there is only one real event 284 if ($me_n[$f] == 3) { 285 $me_subscribe[$f] = $me_assigned[$f]; 286 } 287 288 if (!$me_subscribe[$f]) { 289 die "Missing special event specification = SUBSCRIBE"; 290 } 291 292 $o = 2; 293 for ($i=0; $i<$me_n[$f]; $i++) { 294 $n = $men[$f][$i]; 295 if ($mespecial{$f}{$n} eq "NONE") { 296 $val2me[$f][0] = $n; 297 } elsif ($mespecial{$f}{$n} eq "ASSIGNED") { 298 $val2me[$f][1] = $n; 299 } elsif (!$mespecial{$f}{$n}) { 300 $val2me[$f][$o] = $n; $o++; 301 } 302 } 303 $me_max[$f] = "ME_$vti[$f]_" . $val2me[$f][$o-1] . "+1"; 304 $me_max_n[$f] = $o; 305 306 $len = 0; 307 for ($i=0; $i<$me_max_n[$f];$i++) { 308 $n = $val2me[$f][$i]; 309 $me_a{$f}{$n} = "ME_$vti[$f]_$n"; 310 if (length($me_a{$f}{$n}) > $len) { 311 $len = length($me_a{$f}{$n}); 312 } 313 } 314 for ($i=0; $i<$me_max_n[$f]; $i++) { 315 $n = $val2me[$f][$i]; 316 while ($len > length($me_a{$f}{$n})) { 317 $me_a{$f}{$n} = "$me_a{$f}{$n} "; 318 } 319 } 320 321 for ($b=1; (1 << $b) < $me_max_n[$f]; $b++) {} 322 $bits[$f] = $b; 323} 324 325if ($gen_typehpp) { 326 for ($f = 0; $f<$n_files; $f++) { 327 print $ifdef[$f]; 328 print $hdr[$f]; 329 print $mehdr[$f]; 330 $o = 1; 331 for ($i=0; $i<$me_n[$f]; $i++) { 332 $n = $men[$f][$i]; 333 print $meh[$f][$i]; 334 print " const Gecode::ModEvent ME_" . $vti[$f] . "_${n} = "; 335 if ($mespecial{$f}{$n}) { 336 print "Gecode::ME_GEN_" . $mespecial{$f}{$n}; 337 } else { 338 print "Gecode::ME_GEN_ASSIGNED + " . $o; 339 $o++; 340 } 341 print ";\n"; 342 } 343 344 print $meftr[$f]; 345 print $pchdr[$f]; 346 347 $o = 1; 348 for ($i=0; $i<$pc_n[$f]; $i++) { 349 $n = $pcn[$f][$i]; 350 print $pch[$f][$i]; 351 print " const Gecode::PropCond PC_$vti[$f]_${n} = "; 352 if ($pcspecial{$f}{$n}) { 353 print "Gecode::PC_GEN_" . $pcspecial{$f}{$n}; 354 } else { 355 print "Gecode::PC_GEN_ASSIGNED + " . $o; 356 $o++; 357 } 358 print ";\n"; 359 } 360 print $pcftr[$f]; 361 print $ftr[$f]; 362 print $endif[$f]; 363 } 364 365 366 for ($f = 0; $f<$n_files; $f++) { 367 print $ifdef[$f]; 368 if ($dispose[$f]) { 369 print "\n#ifndef GECODE_HAS_VAR_DISPOSE\n"; 370 print "#define GECODE_HAS_VAR_DISPOSE 1\n"; 371 print "#endif\n\n"; 372 } 373 print $hdr[$f]; 374 print " /// Configuration for $name[$f]-variable implementations\n"; 375 print " class $conf[$f] {\n"; 376 print " public:\n"; 377 print " /// Index for cloning\n"; 378 print " static const int idx_c = "; 379 if ($f == 0) { 380 print "0;\n"; 381 } else { 382 print "$namespace[$f-1]::$conf[$f-1]::idx_c+1;\n"; 383 } 384 print " /// Index for disposal\n"; 385 print " static const int idx_d = "; 386 if ($dispose[$f]) { 387 if ($f == 0) { 388 print "0;\n"; 389 } else { 390 print "$namespace[$f-1]::$conf[$f-1]::idx_d+1;\n"; 391 } 392 } else { 393 if ($f == 0) { 394 print "-1;\n"; 395 } else { 396 print "$namespace[$f-1]::$conf[$f-1]::idx_d;\n"; 397 } 398 } 399 print " /// Maximal propagation condition\n"; 400 print " static const Gecode::PropCond pc_max = $maxpc[$f];\n"; 401 print " /// Freely available bits\n"; 402 print " static const int free_bits = $free_bits[$f];\n"; 403 print " /// Start of bits for modification event delta\n"; 404 print " static const int med_fst = "; 405 if ($f == 0) { 406 print "0;\n"; 407 } else { 408 print "$namespace[$f-1]::$conf[$f-1]::med_lst;\n"; 409 } 410 print " /// End of bits for modification event delta\n"; 411 print " static const int med_lst = med_fst + $bits[$f];\n"; 412 print " /// Bitmask for modification event delta\n"; 413 print " static const int med_mask = ((1 << $bits[$f]) - 1) << med_fst;\n"; 414 print " /// Combine modification events \\a me1 and \\a me2\n"; 415 print " static Gecode::ModEvent me_combine(Gecode::ModEvent me1, Gecode::ModEvent me2);\n"; 416 print " /// Update modification even delta \\a med by \\a me, return true on change\n"; 417 print " static bool med_update(Gecode::ModEventDelta& med, Gecode::ModEvent me);\n"; 418 print " };\n"; 419 print $ftr[$f]; 420 if (!($ifdef[$f] eq "")) { 421 print "#else\n"; 422 print $hdr[$f]; 423 print " /// Dummy configuration for $name[$f]-variable implementations\n"; 424 print " class $conf[$f] {\n"; 425 print " public:\n"; 426 print " /// Index for cloning\n"; 427 print " static const int idx_c = "; 428 if ($f == 0) { 429 print "-1;\n"; 430 } else { 431 print "$namespace[$f-1]::$conf[$f-1]::idx_c;\n"; 432 } 433 print " /// Index for disposal\n"; 434 print " static const int idx_d = "; 435 if ($f == 0) { 436 print "-1;\n"; 437 } else { 438 print "$namespace[$f-1]::$conf[$f-1]::idx_d;\n"; 439 } 440 print " /// End of bits for modification event delta\n"; 441 print " static const int med_lst = "; 442 if ($f == 0) { 443 print "0;\n"; 444 } else { 445 print "$namespace[$f-1]::$conf[$f-1]::med_lst;\n"; 446 } 447 print " };\n"; 448 print $ftr[$f]; 449 } 450 print $endif[$f]; 451 } 452 print "\n"; 453 print "namespace Gecode {\n\n"; 454 print " /// Configuration for all variable implementations\n"; 455 print " class AllVarConf {\n"; 456 print " public:\n"; 457 print " /// Index for cloning\n"; 458 print " static const int idx_c = $namespace[$n_files-1]::$conf[$n_files-1]::idx_c+1;\n"; 459 print " /// Index for dispose\n"; 460 print " static const int idx_d = $namespace[$n_files-1]::$conf[$n_files-1]::idx_d+1;\n"; 461 print " /// Combine modification event delta \\a med1 with \\a med2\n"; 462 print " static ModEventDelta med_combine(ModEventDelta med1, ModEventDelta med2);\n"; 463 print " };\n\n}\n\n"; 464 for ($f = 0; $f<$n_files; $f++) { 465 print $ifdef[$f]; 466 print $hdr[$f]; 467 print " forceinline Gecode::ModEvent\n"; 468 print " $conf[$f]::me_combine(Gecode::ModEvent me1, Gecode::ModEvent me2) {\n"; 469 470 if ($me_max_n[$f] == 2) { 471 print " return me1 | me2;\n"; 472 } elsif ($me_max_n[$f] <= 4) { 473 print " static const Gecode::ModEvent me_c = (\n"; 474 475 for ($i=0; $i<$me_max_n[$f];$i++) { 476 $n1 = $val2me[$f][$i]; 477 print " (\n"; 478 for ($j=0; $j<$me_max_n[$f];$j++) { 479 $n2 = $val2me[$f][$j]; 480 $n3 = $mec{$f}{$n1}{$n2}; 481 $shift = (($i << 3) + ($j << 1)); 482 if ($shift < 10) { 483 $shift = " $shift"; 484 } 485 print " ($me_a{$f}{$n3} << $shift)"; 486 if ($j+1 == $me_max_n[$f]) { 487 print " "; 488 } else { 489 print " | "; 490 } 491 print " // [$me_a{$f}{$n1}][$me_a{$f}{$n2}]\n"; 492 } 493 if ($i+1 == $me_max_n[$f]) { 494 print " )\n"; 495 } else { 496 print " ) |\n"; 497 } 498 } 499 print " );\n"; 500 print " return ((me_c >> (me2 << 3)) >> (me1 << 1)) & 3;\n"; 501 } else { 502 print " static const Gecode::ModEvent me_c[$me_max[$f]][$me_max[$f]] = {\n"; 503 for ($i=0; $i<$me_max_n[$f];$i++) { 504 $n1 = $val2me[$f][$i]; 505 print " {\n"; 506 for ($j=0; $j<$me_max_n[$f];$j++) { 507 $n2 = $val2me[$f][$j]; 508 $n3 = $mec{$f}{$n1}{$n2}; 509 print " $me_a{$f}{$n3}"; 510 if ($j+1 == $me_max_n[$f]) { 511 print " "; 512 } else { 513 print ","; 514 } 515 print " // [$me_a{$f}{$n1}][$me_a{$f}{$n2}]\n"; 516 } 517 print " }"; 518 if ($i+1 == $me_max_n[$f]) { 519 print "\n"; 520 } else { 521 print ",\n"; 522 } 523 } 524 print " };\n"; 525 print " return me_c[me1][me2];\n"; 526 } 527 print " }\n"; 528 print " forceinline bool\n"; 529 print " $conf[$f]::med_update(Gecode::ModEventDelta& med, Gecode::ModEvent me) {\n"; 530 531 print " switch (me) {\n"; 532 if ($me_max_n[$f] == 2) { 533 $ME_NONE = "ME_$vti[$f]_NONE"; 534 if ($val2me[$f][0] eq "NONE") { 535 $ME_ASSIGNED = "ME_$vti[$f]_$val2me[$f][1]"; 536 } else { 537 $ME_ASSIGNED = "ME_$vti[$f]_$val2me[$f][0]"; 538 } 539 print " case $ME_NONE:\n"; 540 print " return false;\n"; 541 print " case $ME_ASSIGNED:\n"; 542 print " if ((med & ($ME_ASSIGNED << med_fst)) != 0)\n"; 543 print " return false;\n"; 544 print " med |= $ME_ASSIGNED << med_fst;\n"; 545 print " break;\n"; 546 } else { 547 $lvti = lc($vti[$f]); 548 for ($i=0; $i<$me_max_n[$f];$i++) { 549 $n1 = $val2me[$f][$i]; 550 $weak = 1; 551 for ($j=0; $j<$me_max_n[$f];$j++) { 552 $n2 = $val2me[$f][$j]; 553 if (!($n2 eq "NONE") && !($n2 eq $n1) && 554 !($mec{$f}{$n1}{$n2} eq $n2)) { 555 $weak = 0; 556 } 557 } 558 print " case ME_$vti[$f]_$n1:\n"; 559 if ($n1 eq "NONE") { 560 print " return false;\n"; 561 } elsif ($mespecial{$f}{$n1} eq "ASSIGNED") { 562 print " {\n"; 563 print " Gecode::ModEventDelta med_$lvti = med & med_mask;\n"; 564 print " if (med_$lvti == (ME_$vti[$f]_$n1 << med_fst))\n"; 565 print " return false;\n"; 566 print " med ^= med_$lvti;\n"; 567 print " med ^= ME_$vti[$f]_$n1 << med_fst;\n"; 568 print " break;\n"; 569 print " }\n"; 570 } elsif ($weak) { 571 print " {\n"; 572 print " Gecode::ModEventDelta med_$lvti = med & med_mask;\n"; 573 print " if (med_$lvti != 0)\n"; 574 print " return false;\n"; 575 print " med |= ME_$vti[$f]_$n1 << med_fst;\n"; 576 print " break;\n"; 577 print " }\n"; 578 } else { 579 print " {\n"; 580 if ($me_max_n[$f] <= 8) { 581 print " static const Gecode::ModEvent me_c = (\n"; 582 for ($j=0; $j<$me_max_n[$f];$j++) { 583 $n2 = $val2me[$f][$j]; 584 $n3 = $mec{$f}{$n1}{$n2}; 585 $shift = $j << 2; 586 if ($shift < 10) { 587 $shift = " $shift"; 588 } 589 print " (($me_a{$f}{$n2} ^ $me_a{$f}{$n3}) << $shift)"; 590 if ($j+1 != $me_max_n[$f]) { 591 print " |\n"; 592 } 593 } 594 print "\n );\n"; 595 print " Gecode::ModEvent me_o = (med & med_mask) >> med_fst;\n"; 596 print " Gecode::ModEvent me_n = (me_c >> (me_o << 2)) & (med_mask >> med_fst);\n"; 597 print " if (me_n == 0)\n"; 598 print " return false;\n"; 599 print " med ^= me_n << med_fst;\n"; 600 print " break;\n"; 601 } else { 602 print " static const Gecode::ModEventDelta me_c[$me_max[$f]] = {\n"; 603 for ($j=0; $j<$me_max_n[$f];$j++) { 604 $n2 = $val2me[$f][$j]; 605 $n3 = $mec{$f}{$n1}{$n2}; 606 print " ($me_a{$f}{$n2} ^ $me_a{$f}{$n3}) << med_fst"; 607 if ($j+1 != $me_max_n[$f]) { 608 print ",\n"; 609 } 610 } 611 print "\n };\n"; 612 print " Gecode::ModEvent me_o = (med & med_mask) >> med_fst;\n"; 613 print " Gecode::ModEventDelta med_n = me_c[me_o];\n"; 614 print " if (med_n == 0)\n"; 615 print " return false;\n"; 616 print " med ^= med_n;\n"; 617 print " break;\n"; 618 } 619 print " }\n"; 620 } 621 } 622 } 623 print " default: GECODE_NEVER;\n"; 624 print " }\n"; 625 print " return true;\n"; 626 print " }\n\n"; 627 print $ftr[$f]; 628 print $endif[$f]; 629 } 630 print "namespace Gecode {\n"; 631 print " forceinline ModEventDelta\n"; 632 print " AllVarConf::med_combine(ModEventDelta med1, ModEventDelta med2) {\n"; 633 for ($f = 0; $f<$n_files; $f++) { 634 $vic = "$namespace[$f]::$conf[$f]"; 635 print $ifdef[$f]; 636 print " (void) ${vic}::med_update(med1,(med2 & ${vic}::med_mask) >> ${vic}::med_fst);\n"; 637 print $endif[$f]; 638 } 639 print " return med1;\n"; 640 print " }\n}\n\n"; 641} 642 643if ($gen_header) { 644 for ($f = 0; $f<$n_files; $f++) { 645 print $ifdef[$f]; 646 print $hdr[$f]; 647 print " /// Base-class for $name[$f]-variable implementations\n"; 648 print " class $class[$f] : public $base[$f] {\n"; 649 if ($dispose[$f]) { 650 print <<EOF 651 private: 652 /// Link to next variable, used for disposal 653 $class[$f]* _next_d; 654EOF 655; 656 } 657 658 print <<EOF 659 protected: 660 /// Constructor for cloning \\a x 661 $class[$f](Gecode::Space& home, $class[$f]\& x); 662 public: 663 /// Constructor for creating static instance of variable 664 $class[$f](void); 665 /// Constructor for creating variable 666 $class[$f](Gecode::Space& home); 667 /// \\name Dependencies 668 //\@{ 669 /** \\brief Subscribe propagator \\a p with propagation condition \\a pc 670 * 671 * In case \\a schedule is false, the propagator is just subscribed but 672 * not scheduled for execution (this must be used when creating 673 * subscriptions during propagation). 674 * 675 * In case the variable is assigned (that is, \\a assigned is 676 * true), the subscribing propagator is scheduled for execution. 677 * Otherwise, the propagator subscribes and is scheduled for execution 678 * with modification event \\a me provided that \\a pc is different 679 * from \\a $pc_assigned[$f]. 680 */ 681 void subscribe(Gecode::Space& home, Gecode::Propagator& p, Gecode::PropCond pc, bool assigned, bool schedule); 682 /// Subscribe advisor \\a a if \\a assigned is false. 683 void subscribe(Gecode::Space& home, Gecode::Advisor& a, bool assigned, bool failed); 684 /// Notify that variable implementation has been modified with modification event \\a me and delta information \\a d 685 Gecode::ModEvent notify(Gecode::Space& home, Gecode::ModEvent me, Gecode::Delta& d); 686 /// \\brief Schedule propagator \\a p 687 static void schedule(Gecode::Space& home, Gecode::Propagator& p, Gecode::ModEvent me); 688 /** \\brief Re-schedule propagator \\a p 689 * 690 * In case the variable is assigned (that is, \\a assigned is 691 * true), the propagator is scheduled for execution. 692 * Otherwise, the propagator is scheduled for execution 693 * with modification event \\a me provided that \\a pc is different 694 * from \\a $pc_assigned[$f]. 695 */ 696 void reschedule(Gecode::Space& home, Gecode::Propagator& p, Gecode::PropCond pc, bool assigned); 697 //\@} 698EOF 699; 700 701 if ($dispose[$f]) { 702 print <<EOF 703 /// Return link to next variable to be disposed 704 $class[$f]* next_d(void) const; 705EOF 706; 707 } 708 709 print <<EOF 710 }; 711EOF 712; 713 714 print $ftr[$f]; 715 print $endif[$f]; 716 717 718} 719 720 for ($f = 0; $f<$n_files; $f++) { 721 print $ifdef[$f]; 722 print $hdr[$f]; 723 724if ($dispose[$f]) { 725 print <<EOF 726 727 forceinline 728 $class[$f]::$class[$f](void) {} 729 730 forceinline 731 $class[$f]::$class[$f](Gecode::Space& home) 732 : $base[$f](home) { 733 _next_d = static_cast<$class[$f]*>(vars_d(home)); vars_d(home,this); 734 } 735 736 forceinline 737 $class[$f]::$class[$f](Gecode::Space& home, $class[$f]\& x) 738 : $base[$f](home,x) { 739 _next_d = static_cast<$class[$f]*>(vars_d(home)); vars_d(home,this); 740 } 741 742 forceinline $class[$f]* 743 $class[$f]::next_d(void) const { 744 return _next_d; 745 } 746 747EOF 748; 749} else { 750 print <<EOF 751 752 forceinline 753 $class[$f]::$class[$f](void) {} 754 755 forceinline 756 $class[$f]::$class[$f](Gecode::Space& home) 757 : $base[$f](home) {} 758 759 forceinline 760 $class[$f]::$class[$f](Gecode::Space& home, $class[$f]\& x) 761 : $base[$f](home,x) {} 762EOF 763; 764} 765 print <<EOF 766 767 forceinline void 768 $class[$f]::subscribe(Gecode::Space& home, Gecode::Propagator& p, Gecode::PropCond pc, bool assigned, bool schedule) { 769 $base[$f]::subscribe(home,p,pc,assigned,$me_subscribe[$f],schedule); 770 } 771 forceinline void 772 $class[$f]::subscribe(Gecode::Space& home, Gecode::Advisor& a, bool assigned, bool failed) { 773 $base[$f]::subscribe(home,a,assigned,failed); 774 } 775 776 forceinline void 777 $class[$f]::schedule(Gecode::Space& home, Gecode::Propagator& p, Gecode::ModEvent me) { 778 $base[$f]::schedule(home,p,me); 779 } 780 forceinline void 781 $class[$f]::reschedule(Gecode::Space& home, Gecode::Propagator& p, Gecode::PropCond pc, bool assigned) { 782 $base[$f]::reschedule(home,p,pc,assigned,$me_subscribe[$f]); 783 } 784 785EOF 786; 787 788if ($me_max_n[$f] == 2) { 789 print <<EOF 790 forceinline Gecode::ModEvent 791 $class[$f]::notify(Gecode::Space& home, Gecode::ModEvent, Gecode::Delta& d) { 792 $base[$f]::schedule(home,$pc_assigned[$f],$pc_assigned[$f],$me_assigned[$f]); 793 if (!$base[$f]::advise(home,$me_assigned[$f],d)) 794 return $me_failed[$f]; 795 cancel(home); 796 return $me_assigned[$f]; 797 } 798 799EOF 800; 801} else { 802 print <<EOF 803 forceinline Gecode::ModEvent 804 $class[$f]::notify(Gecode::Space& home, Gecode::ModEvent me, Gecode::Delta& d) { 805 switch (me) { 806EOF 807; 808 809 for ($i=0; $i<$pc_n[$f]; $i++) { 810 if ($pcspecial{$f}{$pcn[$f][$i]} eq "ASSIGNED") { 811 $val2pc[$f][0] = $pcn[$f][$i]; 812 } 813 } 814 $o = 1; 815 for ($i=0; $i<$pc_n[$f]; $i++) { 816 if (!($pcspecial{$f}{$pcn[$f][$i]} eq "ASSIGNED") && 817 !($pcspecial{$f}{$pcn[$f][$i]} eq "NONE")) { 818 $val2pc[$f][$o] = $pcn[$f][$i]; $o++; 819 } 820 } 821 822 for ($i=0; $i<$me_n[$f]; $i++) { 823 $n = $men[$f][$i]; 824 if (!($mespecial{$f}{$n} eq "NONE") && !($mespecial{$f}{$n} eq "FAILED")) { 825 print " case ME_$vti[$f]_$n:\n"; 826 print " // Conditions: "; 827 $fst = 1; 828 for ($j=0; $j<$pc_n[$f]; $j++) { 829 if ($mepc{$f}{$men[$f][$i]}{$pcn[$f][$j]}) { 830 if ($fst) { 831 $fst = 0; 832 } else { 833 print ", "; 834 } 835 print $pcn[$f][$j]; 836 } 837 } 838 print "\n"; 839 for ($j=0; $j<$pc_n[$f]; $j++) { 840 if ($mepc{$f}{$men[$f][$i]}{$val2pc[$f][$j]}) { 841 # Found initial entry (plus one for stopping) 842 print " $base[$f]::schedule(home,PC_$vti[$f]_" . $val2pc[$f][$j] . ","; 843 # Look for all connected entries 844 while ($mepc{$f}{$men[$f][$i]}{$val2pc[$f][$j+1]}) { 845 $j++; 846 } 847 # Found last entry 848 print "PC_$vti[$f]_" . $val2pc[$f][$j] . ",ME_$vti[$f]_$n);\n"; 849 } 850 } 851 print " if (!$base[$f]::advise(home,ME_$vti[$f]_$n,d))\n"; 852 print " return $me_failed[$f];\n"; 853 if ($mespecial{$f}{$n} eq "ASSIGNED") { 854 print " cancel(home);\n"; 855 } 856 print " break;\n"; 857 } 858 } 859 860 861 print <<EOF 862 default: GECODE_NEVER; 863 } 864 return me; 865 } 866 867EOF 868; 869} 870 print $ftr[$f]; 871 print $endif[$f]; 872} 873 874 print <<EOF 875namespace Gecode { 876 877 forceinline void 878 Space::update(ActorLink** sub) { 879EOF 880; 881 882 for ($f = 0; $f<$n_files; $f++) { 883 print $ifdef[$f]; 884 print " $base[$f]::update(*this,sub);\n"; 885 print $endif[$f]; 886 } 887 888 print <<EOF 889 } 890} 891EOF 892; 893 894 895 896} 897 898print "// STATISTICS: kernel-var\n";