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