1 /** 2 * FloatOperationConstraints.java 3 * This file is part of JaCoP. 4 * <p> 5 * JaCoP is a Java Constraint Programming solver. 6 * <p> 7 * Copyright (C) 2000-2008 Krzysztof Kuchcinski and Radoslaw Szymanek 8 * <p> 9 * This program is free software: you can redistribute it and/or modify 10 * it under the terms of the GNU Affero General Public License as published by 11 * the Free Software Foundation, either version 3 of the License, or 12 * (at your option) any later version. 13 * <p> 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU Affero General Public License for more details. 18 * <p> 19 * Notwithstanding any other provision of this License, the copyright 20 * owners of this work supplement the terms of this License with terms 21 * prohibiting misrepresentation of the origin of this work and requiring 22 * that modified versions of this work be marked in reasonable ways as 23 * different from the original version. This supplement of the license 24 * terms is in accordance with Section 7 of GNU Affero General Public 25 * License version 3. 26 * <p> 27 * You should have received a copy of the GNU Affero General Public License 28 * along with this program. If not, see <http://www.gnu.org/licenses/>. 29 */ 30 package org.jacop.fz.constraints; 31 32 import org.jacop.constraints.IfThenElse; 33 import org.jacop.core.Store; 34 import org.jacop.floats.constraints.*; 35 import org.jacop.floats.core.FloatVar; 36 import org.jacop.fz.ASTScalarFlatExpr; 37 import org.jacop.fz.ParserTreeConstants; 38 import org.jacop.fz.SimpleNode; 39 40 /** 41 * Generation of set constraints in flatzinc 42 * 43 * @author Krzysztof Kuchcinski 44 */ 45 class FloatOperationConstraints implements ParserTreeConstants { 46 47 Support support; 48 Store store; 49 FloatOperationConstraints(Support support)50 public FloatOperationConstraints(Support support) { 51 this.support = support; 52 this.store = support.store; 53 } 54 gen_float_abs(SimpleNode node)55 void gen_float_abs(SimpleNode node) { 56 ASTScalarFlatExpr p1 = (ASTScalarFlatExpr) node.jjtGetChild(0); 57 ASTScalarFlatExpr p2 = (ASTScalarFlatExpr) node.jjtGetChild(1); 58 59 support.pose(new AbsPeqR(support.getFloatVariable(p1), support.getFloatVariable(p2))); 60 } 61 gen_float_acos(SimpleNode node)62 void gen_float_acos(SimpleNode node) { 63 ASTScalarFlatExpr p1 = (ASTScalarFlatExpr) node.jjtGetChild(0); 64 ASTScalarFlatExpr p2 = (ASTScalarFlatExpr) node.jjtGetChild(1); 65 66 support.pose(new AcosPeqR(support.getFloatVariable(p1), support.getFloatVariable(p2))); 67 } 68 gen_float_asin(SimpleNode node)69 void gen_float_asin(SimpleNode node) { 70 ASTScalarFlatExpr p1 = (ASTScalarFlatExpr) node.jjtGetChild(0); 71 ASTScalarFlatExpr p2 = (ASTScalarFlatExpr) node.jjtGetChild(1); 72 73 support.pose(new AsinPeqR(support.getFloatVariable(p1), support.getFloatVariable(p2))); 74 } 75 gen_float_atan(SimpleNode node)76 void gen_float_atan(SimpleNode node) { 77 ASTScalarFlatExpr p1 = (ASTScalarFlatExpr) node.jjtGetChild(0); 78 ASTScalarFlatExpr p2 = (ASTScalarFlatExpr) node.jjtGetChild(1); 79 80 support.pose(new AtanPeqR(support.getFloatVariable(p1), support.getFloatVariable(p2))); 81 } 82 gen_float_cos(SimpleNode node)83 void gen_float_cos(SimpleNode node) { 84 ASTScalarFlatExpr p1 = (ASTScalarFlatExpr) node.jjtGetChild(0); 85 ASTScalarFlatExpr p2 = (ASTScalarFlatExpr) node.jjtGetChild(1); 86 87 support.pose(new CosPeqR(support.getFloatVariable(p1), support.getFloatVariable(p2))); 88 } 89 90 // void gen_float_cosh(SimpleNode node) { 91 // } 92 gen_float_exp(SimpleNode node)93 void gen_float_exp(SimpleNode node) { 94 ASTScalarFlatExpr p1 = (ASTScalarFlatExpr) node.jjtGetChild(0); 95 ASTScalarFlatExpr p2 = (ASTScalarFlatExpr) node.jjtGetChild(1); 96 97 support.pose(new ExpPeqR(support.getFloatVariable(p1), support.getFloatVariable(p2))); 98 } 99 gen_float_ln(SimpleNode node)100 void gen_float_ln(SimpleNode node) { 101 ASTScalarFlatExpr p1 = (ASTScalarFlatExpr) node.jjtGetChild(0); 102 ASTScalarFlatExpr p2 = (ASTScalarFlatExpr) node.jjtGetChild(1); 103 104 support.pose(new LnPeqR(support.getFloatVariable(p1), support.getFloatVariable(p2))); 105 } 106 gen_float_log10(SimpleNode node)107 void gen_float_log10(SimpleNode node) { 108 ASTScalarFlatExpr p1 = (ASTScalarFlatExpr) node.jjtGetChild(0); 109 ASTScalarFlatExpr p2 = (ASTScalarFlatExpr) node.jjtGetChild(1); 110 111 FloatVar tmp = new FloatVar(store, -1e150, 1e150); 112 support.pose(new LnPeqR(support.getFloatVariable(p1), tmp)); 113 support.pose(new PdivCeqR(tmp, java.lang.Math.log(10), support.getFloatVariable(p2))); 114 } 115 gen_float_log2(SimpleNode node)116 void gen_float_log2(SimpleNode node) { 117 ASTScalarFlatExpr p1 = (ASTScalarFlatExpr) node.jjtGetChild(0); 118 ASTScalarFlatExpr p2 = (ASTScalarFlatExpr) node.jjtGetChild(1); 119 120 FloatVar tmp = new FloatVar(store, -1e150, 1e150); 121 support.pose(new LnPeqR(support.getFloatVariable(p1), tmp)); 122 support.pose(new PdivCeqR(tmp, java.lang.Math.log(2), support.getFloatVariable(p2))); 123 } 124 gen_float_sqrt(SimpleNode node)125 void gen_float_sqrt(SimpleNode node) { 126 ASTScalarFlatExpr p1 = (ASTScalarFlatExpr) node.jjtGetChild(0); 127 ASTScalarFlatExpr p2 = (ASTScalarFlatExpr) node.jjtGetChild(1); 128 129 support.pose(new SqrtPeqR(support.getFloatVariable(p1), support.getFloatVariable(p2))); 130 } 131 gen_float_sin(SimpleNode node)132 void gen_float_sin(SimpleNode node) { 133 ASTScalarFlatExpr p1 = (ASTScalarFlatExpr) node.jjtGetChild(0); 134 ASTScalarFlatExpr p2 = (ASTScalarFlatExpr) node.jjtGetChild(1); 135 136 support.pose(new SinPeqR(support.getFloatVariable(p1), support.getFloatVariable(p2))); 137 } 138 139 // void gen_float_sinh(SimpleNode node) { 140 // } 141 gen_float_tan(SimpleNode node)142 void gen_float_tan(SimpleNode node) { 143 ASTScalarFlatExpr p1 = (ASTScalarFlatExpr) node.jjtGetChild(0); 144 ASTScalarFlatExpr p2 = (ASTScalarFlatExpr) node.jjtGetChild(1); 145 146 support.pose(new TanPeqR(support.getFloatVariable(p1), support.getFloatVariable(p2))); 147 } 148 149 // void gen_float_tanh(SimpleNode node) { 150 // } 151 gen_float_max(SimpleNode node)152 void gen_float_max(SimpleNode node) { 153 ASTScalarFlatExpr p1 = (ASTScalarFlatExpr) node.jjtGetChild(0); 154 ASTScalarFlatExpr p2 = (ASTScalarFlatExpr) node.jjtGetChild(1); 155 ASTScalarFlatExpr p3 = (ASTScalarFlatExpr) node.jjtGetChild(2); 156 157 FloatVar v1 = support.getFloatVariable(p1); 158 FloatVar v2 = support.getFloatVariable(p2); 159 FloatVar v3 = support.getFloatVariable(p3); 160 161 support.pose(new org.jacop.floats.constraints.Max(new FloatVar[] {v1, v2}, v3)); 162 } 163 gen_float_min(SimpleNode node)164 void gen_float_min(SimpleNode node) { 165 ASTScalarFlatExpr p1 = (ASTScalarFlatExpr) node.jjtGetChild(0); 166 ASTScalarFlatExpr p2 = (ASTScalarFlatExpr) node.jjtGetChild(1); 167 ASTScalarFlatExpr p3 = (ASTScalarFlatExpr) node.jjtGetChild(2); 168 169 FloatVar v1 = support.getFloatVariable(p1); 170 FloatVar v2 = support.getFloatVariable(p2); 171 FloatVar v3 = support.getFloatVariable(p3); 172 173 support.pose(new org.jacop.floats.constraints.Min(new FloatVar[] {v1, v2}, v3)); 174 } 175 gen_float_plus(SimpleNode node)176 void gen_float_plus(SimpleNode node) { 177 ASTScalarFlatExpr p1 = (ASTScalarFlatExpr) node.jjtGetChild(0); 178 ASTScalarFlatExpr p2 = (ASTScalarFlatExpr) node.jjtGetChild(1); 179 ASTScalarFlatExpr p3 = (ASTScalarFlatExpr) node.jjtGetChild(2); 180 181 if (p1.getType() == 5) {// p1 int 182 support.pose(new PplusCeqR(support.getFloatVariable(p2), support.getFloat(p1), support.getFloatVariable(p3))); 183 } else if (p2.getType() == 5) {// p2 int 184 support.pose(new PplusCeqR(support.getFloatVariable(p1), support.getFloat(p2), support.getFloatVariable(p3))); 185 } else 186 support.pose(new PplusQeqR(support.getFloatVariable(p1), support.getFloatVariable(p2), support.getFloatVariable(p3))); 187 } 188 gen_float_times(SimpleNode node)189 void gen_float_times(SimpleNode node) { 190 ASTScalarFlatExpr p1 = (ASTScalarFlatExpr) node.jjtGetChild(0); 191 ASTScalarFlatExpr p2 = (ASTScalarFlatExpr) node.jjtGetChild(1); 192 ASTScalarFlatExpr p3 = (ASTScalarFlatExpr) node.jjtGetChild(2); 193 194 if (p1.getType() == 5) {// p1 float 195 support.pose(new PmulCeqR(support.getFloatVariable(p2), support.getFloat(p1), support.getFloatVariable(p3))); 196 } else if (p2.getType() == 5) {// p2 float 197 support.pose(new PmulCeqR(support.getFloatVariable(p1), support.getFloat(p2), support.getFloatVariable(p3))); 198 } else 199 support.pose(new PmulQeqR(support.getFloatVariable(p1), support.getFloatVariable(p2), support.getFloatVariable(p3))); 200 } 201 gen_float_pow(SimpleNode node)202 void gen_float_pow(SimpleNode node) { 203 ASTScalarFlatExpr p1 = (ASTScalarFlatExpr) node.jjtGetChild(0); 204 ASTScalarFlatExpr p2 = (ASTScalarFlatExpr) node.jjtGetChild(1); 205 ASTScalarFlatExpr p3 = (ASTScalarFlatExpr) node.jjtGetChild(2); 206 207 FloatVar v1 = support.getFloatVariable(p1); 208 FloatVar v2 = support.getFloatVariable(p2); 209 FloatVar v3 = support.getFloatVariable(p3); 210 211 if (v1.min() < 0) 212 if (v2.min() == v2.max() && Math.ceil(v2.max()) == v2.max()) { 213 // case for integer exponent 214 215 double exponent = v2.min(); 216 217 FloatVar tmp0 = new FloatVar(store, 0, 1e150); 218 FloatVar tmp1 = new FloatVar(store, -1e150, 1e150); 219 FloatVar tmp2 = new FloatVar(store, -1e150, 1e150); 220 FloatVar tmp3 = new FloatVar(store, -1e150, 1e150); 221 support.pose(new AbsPeqR(v1, tmp0)); 222 support.pose(new LnPeqR(tmp0, tmp1)); 223 support.pose(new PmulQeqR(tmp1, v2, tmp2)); 224 support.pose(new ExpPeqR(tmp2, tmp3)); 225 226 if (exponent % 2 == 0) 227 // even 228 support.pose(new PeqQ(tmp3, v3)); 229 else 230 // odd 231 support.pose(new IfThenElse(new PltC(v1, 0), new PplusQeqR(tmp3, v3, new FloatVar(store, 0, 0)), new PeqQ(tmp3, v3))); 232 233 return; 234 } else 235 System.err.println( 236 "%% WARNING: constraint float_pow is not defined for negative numbers as first argument (decomposition x^y = exp(y*ln(x))); " 237 + v1 + " has minimal value negative (will be pruned)."); 238 239 FloatVar tmp1 = new FloatVar(store, -1e150, 1e150); 240 FloatVar tmp2 = new FloatVar(store, -1e150, 1e150); 241 support.pose(new LnPeqR(v1, tmp1)); 242 support.pose(new PmulQeqR(tmp1, v2, tmp2)); 243 support.pose(new ExpPeqR(tmp2, v3)); 244 } 245 246 // not supported any longer gen_float_div(SimpleNode node)247 void gen_float_div(SimpleNode node) { 248 ASTScalarFlatExpr p1 = (ASTScalarFlatExpr) node.jjtGetChild(0); 249 ASTScalarFlatExpr p2 = (ASTScalarFlatExpr) node.jjtGetChild(1); 250 ASTScalarFlatExpr p3 = (ASTScalarFlatExpr) node.jjtGetChild(2); 251 252 support.pose(new PdivQeqR(support.getFloatVariable(p1), support.getFloatVariable(p2), support.getFloatVariable(p3))); 253 } 254 } 255