this repo has no description
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ 2/* 3 * Main authors: 4 * Matthias Balzer <matthias.balzer@itwm.fraunhofer.de> 5 * 6 * Copyright: 7 * Fraunhofer ITWM, 2017 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/minimodel.hh> 35 36#include <cstddef> 37#include <tuple> 38#include <utility> 39 40/// reproduce C++-14 std::index_sequence 41namespace { namespace cxx14 { 42 43 namespace detail { 44 45 template<std::size_t...> 46 struct sequence {}; 47 48 template<std::size_t N, std::size_t... I> 49 struct make_sequence : make_sequence<N - 1, N - 1, I...> {}; 50 51 template<std::size_t... I> 52 struct make_sequence<0, I...> { 53 using type = sequence<I...>; 54 }; 55 } 56 57 template<std::size_t... I> 58 using index_sequence = detail::sequence<I...>; 59 60 template<typename... Ts> 61 using index_sequence_for = typename detail::make_sequence<sizeof...(Ts)>::type; 62}} 63 64 65namespace Gecode { 66 67 namespace { 68 /// Buffer for domain constraint arguments 69 template<typename... Args> 70 class DomArgs { 71 public: 72 /// Constructor 73 DomArgs(Args...); 74 75 protected: 76 /// Post reified domain constraint using the stored arguments 77 template<std::size_t... I> 78 void apply(Home, BoolVar, const IntPropLevels&, 79 cxx14::index_sequence<I...>); 80 81 private: 82 /// Storage for the arguments 83 std::tuple<Args...> _args; 84 }; 85 86 /// Buffer for domain constraint arguments - partial specialization for IntVar 87 template<typename... Args> 88 class DomArgs<IntVar, Args...> { 89 public: 90 /// Constructor 91 DomArgs(IntVar, Args...); 92 93 protected: 94 /// Post reified domain constraint using stored arguments 95 template<std::size_t... I> 96 void apply(Home, BoolVar, const IntPropLevels&, 97 cxx14::index_sequence<I...>); 98 99 private: 100 /// Storage for the arguments 101 std::tuple<IntVar, Args...> _args; 102 }; 103 104 /* 105 * Operations for argument buffer 106 * 107 */ 108 template<typename... Args> 109 DomArgs<Args...>::DomArgs(Args... args) 110 : _args(std::forward<Args>(args)...) {} 111 112 template<typename... Args> 113 template<std::size_t... I> 114 void 115 DomArgs<Args...>::apply(Home home, BoolVar b, const IntPropLevels&, 116 cxx14::index_sequence<I...>) { 117 dom(home, std::get<I>(_args)..., b); 118 } 119 120 template<typename... Args> 121 DomArgs<IntVar, Args...>::DomArgs(IntVar x, Args... args) 122 : _args (x, std::forward<Args>(args)...) {} 123 124 template<typename... Args> 125 template<std::size_t... I> 126 void 127 DomArgs<IntVar, Args...>::apply(Home home, BoolVar b, 128 const IntPropLevels&, 129 cxx14::index_sequence<I...>) { 130 dom(home, std::get<I>(_args)..., b); 131 } 132 133 134 /// Domain expression 135 template<typename... Args> 136 class DomExpr : public DomArgs<Args...>, public BoolExpr::Misc 137 { 138 public: 139 using DomArgs<Args...>::DomArgs; 140 141 /// Constrain \a b to be equivalent to the expression (negated if \a neg) 142 virtual void post(Home, BoolVar b, bool neg, 143 const IntPropLevels&) override; 144 /// Destructor 145 virtual ~DomExpr() = default; 146 }; 147 148 template<typename... Args> 149 void 150 DomExpr<Args...>::post(Home home, BoolVar b, bool neg, 151 const IntPropLevels& ipls) 152 { 153 DomArgs<Args...>::apply(home, neg ? (!b).expr (home, ipls) : b, ipls, 154 cxx14::index_sequence_for<Args...>{}); 155 } 156 } 157 158 159 /* 160 * Domain constraints 161 * 162 */ 163 BoolExpr 164 dom(const IntVar& x, int n) { 165 return BoolExpr(new DomExpr<IntVar, int>(x, n)); 166 } 167 168 BoolExpr 169 dom(const IntVar& x, int l, int u) { 170 return BoolExpr(new DomExpr<IntVar, int, int>(x, l, u)); 171 } 172 173 BoolExpr 174 dom(const IntVar& x, const IntSet& s) { 175 return BoolExpr(new DomExpr<IntVar, IntSet>(x, s)); 176 } 177 178#ifdef GECODE_HAS_SET_VARS 179 BoolExpr 180 dom(const SetVar& x, SetRelType rt, int i) { 181 return BoolExpr(new DomExpr<SetVar, SetRelType, int>(x, rt, i)); 182 } 183 184 BoolExpr 185 dom(const SetVar& x, SetRelType rt, int i, int j) { 186 return BoolExpr(new DomExpr<SetVar, SetRelType, int, int>(x, rt, i, j)); 187 } 188 189 BoolExpr 190 dom(const SetVar& x, SetRelType rt, const IntSet& s) { 191 return BoolExpr(new DomExpr<SetVar, SetRelType, IntSet>(x, rt, s)); 192 } 193#endif 194 195#ifdef GECODE_HAS_FLOAT_VARS 196 BoolExpr 197 dom(const FloatVar& x, const FloatVal& n) { 198 return BoolExpr(new DomExpr<FloatVar, FloatVal>(x, n)); 199 } 200 201 BoolExpr 202 dom(const FloatVar& x, FloatNum l, FloatNum u) { 203 return BoolExpr(new DomExpr<FloatVar, FloatNum, FloatNum>(x, l, u)); 204 } 205#endif 206} 207 208// STATISTICS: minimodel-any