00001 /* 00002 * Copyright 2007 Martin von Gagern 00003 * 00004 * 00005 * This file is part of mqn2mps. 00006 * 00007 * mqn2mps is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 3 of the License, or 00010 * (at your option) any later version. 00011 * 00012 * mqn2mps is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00019 */ 00020 00021 00022 #ifndef BOUNDS_HH 00023 #define BOUNDS_HH 00024 00025 /** 00026 * @file 00027 * Interface and implementation of class bounds. 00028 */ 00029 00030 /** 00031 * A bounds object represents a pair of integer %bounds. 00032 * Each bound can have three types, as specified by the enum 00033 * bounds::bound_type. 00034 */ 00035 class bounds { 00036 public: 00037 00038 /** 00039 * Both %bounds have one of these types. 00040 */ 00041 enum bound_type { 00042 00043 /** 00044 * The bound is a real %constraint to be enforced. 00045 * This is a real bound that must be encoded in the output. 00046 */ 00047 strict, 00048 00049 /** 00050 * A hint for where working with unbounded values is difficult. 00051 * The bound given here will always be implied by a set of strict 00052 * %bounds. However as some output formats or solution finding 00053 * programs may benefit from additional %bounds being specified, 00054 * whenever some loose bound is known, it should be stated as a 00055 * hint. 00056 */ 00057 hint, 00058 00059 /** 00060 * There is no bound at this side, only infinity. 00061 * The value of the bound is irrelevant in this case. 00062 */ 00063 infinite, 00064 }; 00065 00066 /** 00067 * The value of the lower bound, unless the lower bound is of type 00068 * infinite. 00069 */ 00070 int lower_value; 00071 00072 /** 00073 * The value of the upper bound, unless the upper bound is of type 00074 * infinite. 00075 */ 00076 int upper_value; 00077 00078 /** The type of the lower bound. */ 00079 bound_type lower_type; 00080 00081 /** The type of the upper bound. */ 00082 bound_type upper_type; 00083 00084 /** 00085 * Initialize bounds to infinity in both directions. 00086 */ 00087 bounds() : lower_value(std::numeric_limits<int>::min()), 00088 upper_value(std::numeric_limits<int>::max()), 00089 lower_type(infinite), upper_type(infinite) { } 00090 00091 /** 00092 * Initialize bounds to a strict equality. 00093 * @param value the value that will become lower and upper bound. 00094 */ 00095 bounds(int value) : lower_value(value), upper_value(value), 00096 lower_type(strict), upper_type(strict) { } 00097 00098 /** 00099 * Initialize bounds to a strict range. 00100 * @param lower the value of the lower bound. 00101 * @param upper the value of the upper bound. 00102 */ 00103 bounds(int lower, int upper) : lower_value(lower), upper_value(upper), 00104 lower_type(strict), upper_type(strict) { } 00105 00106 /** 00107 * Initialize bounds to given range and types. 00108 * @param lower the value of the lower bound. 00109 * @param lt the type of the lower bound. 00110 * @param upper the value of the upper bound. 00111 * @param ut the type of the upper bound. 00112 */ 00113 bounds(int lower, bound_type lt, int upper, bound_type ut) 00114 : lower_value(lower), upper_value(upper), 00115 lower_type(lt), upper_type(ut) { } 00116 00117 /** 00118 * Return lower bound. 00119 * @param want_limit whether a limit should be returned if it is 00120 * only a hint. 00121 * @param inf the value to be used for infinity. 00122 * @return the stored lower bound or the passed inf value. 00123 */ 00124 int lower(bool want_limit, int inf) { 00125 if (lower_type == strict || (lower_type == hint && want_limit)) 00126 return lower_value; 00127 else 00128 return inf; 00129 } 00130 00131 /** 00132 * Return upper bound. 00133 * @param want_limit whether a limit should be returned if it is 00134 * only a hint. 00135 * @param inf the value to be used for infinity. 00136 * @return the stored lower bound or the passed inf value. 00137 */ 00138 int upper(bool want_limit, int inf) { 00139 if (upper_type == strict || (upper_type == hint && want_limit)) 00140 return upper_value; 00141 else 00142 return inf; 00143 } 00144 00145 /** 00146 * Return lower bound as double. 00147 * @param want_limit whether a limit should be returned if it is 00148 * only a hint. 00149 * @param inf the value to be used for infinity. 00150 * @return the stored lower bound or the passed inf value. 00151 */ 00152 double lower(bool want_limit = false, 00153 double inf = -std::numeric_limits<double>::infinity()) { 00154 if (lower_type == strict || (lower_type == hint && want_limit)) 00155 return lower_value; 00156 else 00157 return inf; 00158 } 00159 00160 /** 00161 * Return upper bound as double. 00162 * @param want_limit whether a limit should be returned if it is 00163 * only a hint. 00164 * @param inf the value to be used for infinity. 00165 * @return the stored lower bound or the passed inf value. 00166 */ 00167 double upper(bool want_limit = false, 00168 double inf = std::numeric_limits<double>::infinity()) { 00169 if (upper_type == strict || (upper_type == hint && want_limit)) 00170 return upper_value; 00171 else 00172 return inf; 00173 } 00174 00175 /** 00176 * Set to strict equality. 00177 * The lower and upper bound will be set to the specified value. 00178 * @param value the value that will be the new lower and upper 00179 * bound. 00180 * @return a reference to the left hand side of the assignment. 00181 */ 00182 bounds& operator=(int value) { 00183 lower_value = upper_value = value; 00184 lower_type = upper_type = strict; 00185 return *this; 00186 } 00187 00188 }; 00189 00190 #endif // ifndef BOUNDS_HH
1.6.0