this repo has no description
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ 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 34#include <gecode/int/rel.hh> 35#include <gecode/int/bool.hh> 36 37/** 38 * \namespace Gecode::Int::Unshare 39 * \brief Unsharing shared variables 40 */ 41 42namespace Gecode { namespace Int { namespace Unshare { 43 44 /// Sort order for variables 45 template<class Var> 46 class VarPtrLess { 47 public: 48 forceinline bool 49 operator ()(const Var* a, const Var* b) { 50 return a->varimp() < b->varimp(); 51 } 52 }; 53 54 55 /// Replace by fresh yet equal integer variables 56 forceinline void 57 link(Home home, IntVar** x, int n, IntPropLevel ipl) { 58 if (home.failed()) { 59 for (int i=1; i<n; i++) 60 *x[i]=IntVar(home,x[0]->min(),x[0]->min()); 61 } else if (n > 2) { 62 ViewArray<IntView> y(home,n); 63 y[0]=*x[0]; 64 for (int i=1; i<n; i++) 65 y[i]=*x[i]=IntVar(home,x[0]->min(),x[0]->max()); 66 if ((ipl == IPL_DOM) || (ipl == IPL_DEF)) { 67 ExecStatus es = Rel::NaryEqDom<IntView>::post(home,y); 68 (void) es; assert(es == ES_OK); 69 } else { 70 ExecStatus es = Rel::NaryEqBnd<IntView>::post(home,y); 71 (void) es; assert(es == ES_OK); 72 } 73 } else if (n == 2) { 74 *x[1]=IntVar(home,x[0]->min(),x[0]->max()); 75 if ((ipl == IPL_DOM) || (ipl == IPL_DEF)) { 76 ExecStatus es = Rel::EqDom<IntView,IntView>::post(home,*x[0],*x[1]); 77 (void) es; assert(es == ES_OK); 78 } else { 79 ExecStatus es = Rel::EqBnd<IntView,IntView>::post(home,*x[0],*x[1]); 80 (void) es; assert(es == ES_OK); 81 } 82 } 83 } 84 85 /// Replace by fresh yet equal Boolean variables 86 forceinline void 87 link(Home home, BoolVar** x, int n, IntPropLevel) { 88 if (home.failed()) { 89 for (int i=1; i<n; i++) 90 *x[i]=BoolVar(home,0,0); 91 } else if (n > 2) { 92 ViewArray<BoolView> y(home,n); 93 y[0]=*x[0]; 94 for (int i=1; i<n; i++) 95 y[i]=*x[i]=BoolVar(home,0,1); 96 ExecStatus es = Bool::NaryEq<BoolView>::post(home,y); 97 (void) es; assert(es == ES_OK); 98 } else if (n == 2) { 99 *x[1] = BoolVar(home,0,1); 100 ExecStatus es = Bool::Eq<BoolView,BoolView>::post(home,*x[0],*x[1]); 101 (void) es; assert(es == ES_OK); 102 } 103 } 104 105 /// Replace unassigned shared variables by fresh, yet equal variables 106 template<class Var> 107 forceinline void 108 unshare(Home home, VarArgArray<Var>& x, IntPropLevel ipl) { 109 int n=x.size(); 110 if (n < 2) 111 return; 112 113 Region r; 114 Var** y = r.alloc<Var*>(n); 115 for (int i=0; i<n; i++) 116 y[i]=&x[i]; 117 118 VarPtrLess<Var> vpl; 119 Support::quicksort<Var*,VarPtrLess<Var> >(y,n,vpl); 120 121 // Replace all shared variables with new and equal variables 122 for (int i=0; i<n;) { 123 int j=i++; 124 while ((i<n) && (y[j]->varimp() == y[i]->varimp())) 125 i++; 126 if (!y[j]->assigned()) 127 link(home,&y[j],i-j,ipl); 128 } 129 } 130 131}}} 132 133namespace Gecode { 134 135 void 136 unshare(Home home, IntVarArgs& x, IntPropLevel ipl) { 137 Int::Unshare::unshare<IntVar>(home,x,vbd(ipl)); 138 } 139 140 void 141 unshare(Home home, BoolVarArgs& x, IntPropLevel) { 142 Int::Unshare::unshare<BoolVar>(home,x,IPL_DEF); 143 } 144 145} 146 147// STATISTICS: int-post