1    	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2    	/*                                                                           */
3    	/*                  This file is part of the program and library             */
4    	/*         SCIP --- Solving Constraint Integer Programs                      */
5    	/*                                                                           */
6    	/*  Copyright (c) 2002-2023 Zuse Institute Berlin (ZIB)                      */
7    	/*                                                                           */
8    	/*  Licensed under the Apache License, Version 2.0 (the "License");          */
9    	/*  you may not use this file except in compliance with the License.         */
10   	/*  You may obtain a copy of the License at                                  */
11   	/*                                                                           */
12   	/*      http://www.apache.org/licenses/LICENSE-2.0                           */
13   	/*                                                                           */
14   	/*  Unless required by applicable law or agreed to in writing, software      */
15   	/*  distributed under the License is distributed on an "AS IS" BASIS,        */
16   	/*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17   	/*  See the License for the specific language governing permissions and      */
18   	/*  limitations under the License.                                           */
19   	/*                                                                           */
20   	/*  You should have received a copy of the Apache-2.0 license                */
21   	/*  along with SCIP; see the file LICENSE. If not visit scipopt.org.         */
22   	/*                                                                           */
23   	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24   	
25   	/**@file   expr_value.c
26   	 * @ingroup DEFPLUGINS_EXPR
27   	 * @brief  constant value expression handler
28   	 * @author Stefan Vigerske
29   	 * @author Benjamin Mueller
30   	 */
31   	
32   	/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
33   	
34   	#include <string.h>
35   	
36   	#include "scip/expr_value.h"
37   	
38   	#define EXPRHDLR_NAME            "val"
39   	#define EXPRHDLR_DESC            "constant value"
40   	#define EXPRHDLR_PRECEDENCE      10000
41   	#define EXPRHDLR_HASHKEY         SCIPcalcFibHash(36787.0)
42   	
43   	/*
44   	 * Data structures
45   	 */
46   	
47   	/** expression data */
48   	struct SCIP_ExprData
49   	{
50   	   SCIP_Real             value;              /**< value that expression represents */
51   	};
52   	
53   	/*
54   	 * Callback methods of expression handler
55   	 */
56   	
57   	/** the order of two values is the real order */
58   	static
59   	SCIP_DECL_EXPRCOMPARE(compareValue)
60   	{  /*lint --e{715}*/
61   	   SCIP_Real val1;
62   	   SCIP_Real val2;
63   	
64   	   assert(SCIPexprGetData(expr1) != NULL);
65   	   assert(SCIPexprGetData(expr2) != NULL);
66   	
67   	   val1 = SCIPexprGetData(expr1)->value;
68   	   val2 = SCIPexprGetData(expr2)->value;
69   	
70   	   return val1 < val2 ? -1 : val1 == val2 ? 0 : 1; /*lint !e777*/
71   	}
72   	
73   	/** expression handler copy callback */
74   	static
75   	SCIP_DECL_EXPRCOPYHDLR(copyhdlrValue)
76   	{  /*lint --e{715}*/
77   	   SCIP_CALL( SCIPincludeExprhdlrValue(scip) );
78   	
79   	   return SCIP_OKAY;
80   	}
81   	
82   	/** expression data copy callback */
83   	static
84   	SCIP_DECL_EXPRCOPYDATA(copydataValue)
85   	{  /*lint --e{715}*/
86   	   assert(targetexprdata != NULL);
87   	   assert(sourceexpr != NULL);
88   	
89   	   SCIP_CALL( SCIPallocBlockMemory(targetscip, targetexprdata) );
90   	   (*targetexprdata)->value = SCIPexprGetData(sourceexpr)->value;
91   	
92   	   return SCIP_OKAY;
93   	}
94   	
95   	/** expression data free callback */
96   	static
97   	SCIP_DECL_EXPRFREEDATA(freedataValue)
98   	{  /*lint --e{715}*/
99   	   SCIP_EXPRDATA* exprdata;
100  	
101  	   assert(expr != NULL);
102  	
103  	   exprdata = SCIPexprGetData(expr);
104  	   assert(exprdata != NULL);
105  	
106  	   SCIPfreeBlockMemory(scip, &exprdata);
107  	   SCIPexprSetData(expr, NULL);
108  	
109  	   return SCIP_OKAY;
110  	}
111  	
112  	/** expression print callback */
113  	static
114  	SCIP_DECL_EXPRPRINT(printValue)
115  	{  /*lint --e{715}*/
116  	   assert(expr != NULL);
117  	   assert(SCIPexprGetData(expr) != NULL);
118  	
119  	   if( stage == SCIP_EXPRITER_ENTEREXPR )
120  	   {
121  	      SCIP_Real v = SCIPexprGetData(expr)->value;
122  	      if( v < 0.0 && EXPRHDLR_PRECEDENCE <= parentprecedence )
123  	      {
124  	         SCIPinfoMessage(scip, file, "(%g)", v);
125  	      }
126  	      else
127  	      {
128  	         SCIPinfoMessage(scip, file, "%g", v);
129  	      }
130  	   }
131  	
132  	   return SCIP_OKAY;
133  	}
134  	
135  	/** expression point evaluation callback */
136  	static
137  	SCIP_DECL_EXPREVAL(evalValue)
138  	{  /*lint --e{715}*/
139  	   assert(expr != NULL);
140  	   assert(SCIPexprGetData(expr) != NULL);
141  	
142  	   *val = SCIPexprGetData(expr)->value;
143  	
144  	   return SCIP_OKAY;
145  	}
146  	
147  	/** expression backward derivative evaluation callback */
148  	static
149  	SCIP_DECL_EXPRBWDIFF(bwdiffValue)
150  	{  /*lint --e{715}*/
151  	   /* should never be called since value expressions do not have children */
152  	   return SCIP_INVALIDCALL;
153  	}
154  	
155  	/** expression forward derivative evaluation callback */
156  	static
157  	SCIP_DECL_EXPRFWDIFF(fwdiffValue)
158  	{  /*lint --e{715}*/
159  	   assert(expr != NULL);
160  	
161  	   *dot = 0.0;
162  	
163  	   return SCIP_OKAY;
164  	}
165  	
166  	/** derivative evaluation callback for Hessian directions (backward over forward) */
167  	static
168  	SCIP_DECL_EXPRBWFWDIFF(bwfwdiffValue)
169  	{  /*lint --e{715}*/
170  	   /* should never be called since value expressions do not have children */
171  	   return SCIP_INVALIDCALL;
172  	}
173  	
174  	/** expression interval evaluation callback */
175  	static
176  	SCIP_DECL_EXPRINTEVAL(intevalValue)
177  	{  /*lint --e{715}*/
178  	   assert(expr != NULL);
179  	   assert(SCIPexprGetData(expr) != NULL);
180  	
181  	   SCIPintervalSet(interval, SCIPexprGetData(expr)->value);
182  	
183  	   return SCIP_OKAY;
184  	}
185  	
186  	/** expression hash callback */
187  	static
188  	SCIP_DECL_EXPRHASH(hashValue)
189  	{  /*lint --e{715}*/
190  	   assert(scip != NULL);
191  	   assert(expr != NULL);
192  	   assert(SCIPexprGetData(expr) != NULL);
193  	   assert(SCIPexprGetNChildren(expr) == 0);
194  	   assert(hashkey != NULL);
195  	
196  	   *hashkey = EXPRHDLR_HASHKEY;
197  	   *hashkey ^= SCIPcalcFibHash(SCIPexprGetData(expr)->value);
198  	
199  	   return SCIP_OKAY;
200  	}
201  	
202  	/** expression curvature detection callback */
203  	static
204  	SCIP_DECL_EXPRCURVATURE(curvatureValue)
205  	{  /*lint --e{715}*/
206  	   assert(scip != NULL);
207  	   assert(expr != NULL);
208  	   assert(success != NULL);
209  	   assert(SCIPexprGetNChildren(expr) == 0);
210  	
211  	   *success = TRUE;
212  	
213  	   return SCIP_OKAY;
214  	}
215  	
216  	/** expression monotonicity detection callback */
217  	static
218  	SCIP_DECL_EXPRMONOTONICITY(monotonicityValue)
219  	{  /*lint --e{715}*/
220  	   assert(scip != NULL);
221  	   assert(expr != NULL);
222  	   assert(result != NULL);
223  	   assert(SCIPexprGetNChildren(expr) == 0);
224  	
225  	   *result = SCIP_MONOTONE_CONST;
226  	
227  	   return SCIP_OKAY;
228  	}
229  	
230  	/** expression integrality detection callback */
231  	static
232  	SCIP_DECL_EXPRINTEGRALITY(integralityValue)
233  	{  /*lint --e{715}*/
234  	   assert(scip != NULL);
235  	   assert(expr != NULL);
236  	   assert(isintegral != NULL);
237  	   assert(SCIPexprGetData(expr) != NULL);
238  	
239  	   *isintegral = EPSISINT(SCIPexprGetData(expr)->value, 0.0); /*lint !e835 !e666*/
240  	
241  	   return SCIP_OKAY;
242  	}
243  	
244  	/** creates the handler for constant value expression and includes it into SCIP */
245  	SCIP_RETCODE SCIPincludeExprhdlrValue(
246  	   SCIP*                 scip                /**< SCIP data structure */
247  	   )
248  	{
249  	   SCIP_EXPRHDLR* exprhdlr;
250  	
251  	   SCIP_CALL( SCIPincludeExprhdlr(scip, &exprhdlr, EXPRHDLR_NAME, EXPRHDLR_DESC, EXPRHDLR_PRECEDENCE,
252  	         evalValue, NULL) );
253  	   assert(exprhdlr != NULL);
254  	
255  	   SCIPexprhdlrSetCopyFreeHdlr(exprhdlr, copyhdlrValue, NULL);
256  	   SCIPexprhdlrSetCopyFreeData(exprhdlr, copydataValue, freedataValue);
257  	   SCIPexprhdlrSetCompare(exprhdlr, compareValue);
258  	   SCIPexprhdlrSetPrint(exprhdlr, printValue);
259  	   SCIPexprhdlrSetIntEval(exprhdlr, intevalValue);
260  	   SCIPexprhdlrSetHash(exprhdlr, hashValue);
261  	   SCIPexprhdlrSetDiff(exprhdlr, bwdiffValue, fwdiffValue, bwfwdiffValue);
262  	   SCIPexprhdlrSetCurvature(exprhdlr, curvatureValue);
263  	   SCIPexprhdlrSetMonotonicity(exprhdlr, monotonicityValue);
264  	   SCIPexprhdlrSetIntegrality(exprhdlr, integralityValue);
265  	
266  	   return SCIP_OKAY;
267  	}
268  	
269  	/** creates constant value expression */
270  	SCIP_RETCODE SCIPcreateExprValue(
271  	   SCIP*                 scip,               /**< SCIP data structure */
272  	   SCIP_EXPR**           expr,               /**< pointer where to store expression */
273  	   SCIP_Real             value,              /**< value to be stored */
274  	   SCIP_DECL_EXPR_OWNERCREATE((*ownercreate)), /**< function to call to create ownerdata */
275  	   void*                 ownercreatedata     /**< data to pass to ownercreate */
276  	   )
277  	{
278  	   SCIP_EXPRDATA* exprdata;
279  	
280  	   assert(expr != NULL);
281  	   assert(SCIPisFinite(value));
282  	
283  	   SCIP_CALL( SCIPallocBlockMemory(scip, &exprdata) );
284  	   exprdata->value = value;
285  	
286  	   SCIP_CALL( SCIPcreateExpr(scip, expr, SCIPgetExprhdlrValue(scip), exprdata, 0, NULL, ownercreate, ownercreatedata) );
287  	
288  	   return SCIP_OKAY;
289  	}
290  	
291  	/* from pub_expr.h */
292  	
293  	/** gets the value of a constant value expression */
294  	SCIP_Real SCIPgetValueExprValue(
295  	   SCIP_EXPR*            expr                /**< sum expression */
296  	   )
297  	{
298  	   assert(expr != NULL);
299  	   assert(SCIPexprGetData(expr) != NULL);
300  	
301  	   return SCIPexprGetData(expr)->value;
302  	}
303