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   reader_cor.c
26   	 * @ingroup DEFPLUGINS_READER
27   	 * @brief  COR file reader (MPS format of the core problem for stochastic programs)
28   	 * @author Stephen J. Maher
29   	 */
30   	
31   	/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
32   	
33   	#include "scip/pub_message.h"
34   	#include "scip/pub_reader.h"
35   	#include "scip/reader_cor.h"
36   	#include "scip/reader_mps.h"
37   	#include "scip/scip_mem.h"
38   	#include "scip/scip_reader.h"
39   	#include <string.h>
40   	
41   	#define READER_NAME             "correader"
42   	#define READER_DESC             "file reader for CORE problem of stochastic programs in the SMPS file format"
43   	#define READER_EXTENSION        "cor"
44   	
45   	#define SCIP_DEFAULT_ARRAYSIZE      100
46   	
47   	/** COR reading data */
48   	struct SCIP_ReaderData
49   	{
50   	   const char**          varnames;
51   	   const char**          consnames;
52   	   int                   varnamessize;
53   	   int                   consnamessize;
54   	   int                   nvarnames;
55   	   int                   nconsnames;
56   	   SCIP_Bool             read;
57   	};
58   	
59   	/** creates the reader data  */
60   	static
61   	SCIP_RETCODE createReaderdata(
62   	   SCIP*                 scip,               /**< SCIP data structure */
63   	   SCIP_READERDATA*      readerdata          /**< the reader data structure */
64   	   )
65   	{
66   	   assert(scip != NULL);
67   	   assert(readerdata != NULL);
68   	
69   	   readerdata->read = FALSE;
70   	   readerdata->nvarnames = 0;
71   	   readerdata->nconsnames = 0;
72   	   readerdata->varnamessize = SCIP_DEFAULT_ARRAYSIZE;
73   	   readerdata->consnamessize = SCIP_DEFAULT_ARRAYSIZE;
74   	
75   	   SCIP_CALL( SCIPallocBlockMemoryArray(scip, &readerdata->varnames, readerdata->varnamessize) );
76   	   SCIP_CALL( SCIPallocBlockMemoryArray(scip, &readerdata->consnames, readerdata->consnamessize) );
77   	
78   	   return SCIP_OKAY;
79   	}
80   	
81   	/** creates the reader data  */
82   	static
83   	SCIP_RETCODE freeReaderdata(
84   	   SCIP*                 scip,               /**< SCIP data structure */
85   	   SCIP_READERDATA*      readerdata          /**< the reader data structure */
86   	   )
87   	{
88   	   int i;
89   	
90   	   assert(scip != NULL);
91   	   assert(readerdata != NULL);
92   	
93   	   for( i = readerdata->nvarnames - 1; i >= 0; i-- )
94   	      SCIPfreeBlockMemoryArray(scip, &readerdata->varnames[i], strlen(readerdata->varnames[i]) + 1);
95   	
96   	   for( i = readerdata->nconsnames - 1; i >= 0; i-- )
97   	      SCIPfreeBlockMemoryArray(scip, &readerdata->consnames[i], strlen(readerdata->consnames[i]) + 1);
98   	
99   	   SCIPfreeBlockMemoryArray(scip, &readerdata->consnames, readerdata->consnamessize);
100  	   SCIPfreeBlockMemoryArray(scip, &readerdata->varnames, readerdata->varnamessize);
101  	
102  	   return SCIP_OKAY;
103  	}
104  	
105  	/*
106  	 * Callback methods of reader
107  	 */
108  	
109  	/** copy method for reader plugins (called when SCIP copies plugins) */
110  	static
111  	SCIP_DECL_READERCOPY(readerCopyCor)
112  	{  /*lint --e{715}*/
113  	   assert(scip != NULL);
114  	   assert(reader != NULL);
115  	   assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
116  	
117  	   /* call inclusion method of reader */
118  	   SCIP_CALL( SCIPincludeReaderCor(scip) );
119  	
120  	   return SCIP_OKAY;
121  	}
122  	
123  	
124  	/** destructor of reader to free user data (called when SCIP is exiting) */
125  	/**! [SnippetReaderFreeCor] */
126  	static
127  	SCIP_DECL_READERFREE(readerFreeCor)
128  	{
129  	   SCIP_READERDATA* readerdata;
130  	
131  	   assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
132  	   readerdata = SCIPreaderGetData(reader);
133  	   assert(readerdata != NULL);
134  	
135  	   SCIP_CALL( freeReaderdata(scip, readerdata) );
136  	
137  	   SCIPfreeBlockMemory(scip, &readerdata);
138  	
139  	   return SCIP_OKAY;
140  	}
141  	/**! [SnippetReaderFreeCor] */
142  	
143  	
144  	/** problem reading method of reader */
145  	static
146  	SCIP_DECL_READERREAD(readerReadCor)
147  	{  /*lint --e{715}*/
148  	
149  	   SCIP_CALL( SCIPreadCor(scip, filename, result) );
150  	
151  	   return SCIP_OKAY;
152  	}
153  	
154  	
155  	/*
156  	 * reader specific interface methods
157  	 */
158  	
159  	/** includes the cor file reader in SCIP */
160  	SCIP_RETCODE SCIPincludeReaderCor(
161  	   SCIP*                 scip                /**< SCIP data structure */
162  	   )
163  	{
164  	   SCIP_READERDATA* readerdata;
165  	   SCIP_READER* reader;
166  	
167  	   /* create reader data */
168  	   SCIP_CALL( SCIPallocBlockMemory(scip, &readerdata) );
169  	   SCIP_CALL( createReaderdata(scip, readerdata) );
170  	
171  	   /* include reader */
172  	   SCIP_CALL( SCIPincludeReaderBasic(scip, &reader, READER_NAME, READER_DESC, READER_EXTENSION, readerdata) );
173  	
174  	   assert(reader != NULL);
175  	
176  	   /* set non fundamental callbacks via setter functions */
177  	   SCIP_CALL( SCIPsetReaderCopy(scip, reader, readerCopyCor) );
178  	   SCIP_CALL( SCIPsetReaderFree(scip, reader, readerFreeCor) );
179  	   SCIP_CALL( SCIPsetReaderRead(scip, reader, readerReadCor) );
180  	
181  	   return SCIP_OKAY;
182  	}
183  	
184  	
185  	
186  	/** reads problem from file */
187  	SCIP_RETCODE SCIPreadCor(
188  	   SCIP*                 scip,               /**< SCIP data structure */
189  	   const char*           filename,           /**< full path and name of file to read, or NULL if stdin should be used */
190  	   SCIP_RESULT*          result              /**< pointer to store the result of the file reading call */
191  	   )
192  	{
193  	   SCIP_READER* reader;
194  	   SCIP_READERDATA* readerdata;
195  	
196  	   reader = SCIPfindReader(scip, READER_NAME);
197  	   assert(reader != NULL);
198  	
199  	   readerdata = SCIPreaderGetData(reader);
200  	   assert(readerdata != NULL);
201  	
202  	   SCIP_CALL( SCIPreadMps(scip, reader, filename, result, &readerdata->varnames, &readerdata->consnames,
203  	         &readerdata->varnamessize, &readerdata->consnamessize, &readerdata->nvarnames, &readerdata->nconsnames) );
204  	
205  	   if( (*result) == SCIP_SUCCESS )
206  	      readerdata->read = TRUE;
207  	
208  	   return SCIP_OKAY;
209  	}
210  	
211  	/*
212  	 * Interface method for the tim and sto readers
213  	 */
214  	
215  	
216  	/** returns whether the COR file has been successfully read. This is used by the TIM and STO readers. */
217  	SCIP_Bool SCIPcorHasRead(
218  	   SCIP_READER*          reader              /**< the file reader itself */
219  	   )
220  	{
221  	   SCIP_READERDATA* readerdata;
222  	
223  	   assert(reader != NULL);
224  	   assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
225  	
226  	   readerdata = SCIPreaderGetData(reader);
227  	   assert(readerdata != NULL);
228  	
229  	   return readerdata->read;
230  	}
231  	
232  	/** returns the number of variable names in the COR problem */
233  	int SCIPcorGetNVarNames(
234  	   SCIP_READER*          reader              /**< the file reader itself */
235  	   )
236  	{
237  	   SCIP_READERDATA* readerdata;
238  	
239  	   assert(reader != NULL);
240  	   assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
241  	
242  	   readerdata = SCIPreaderGetData(reader);
243  	   assert(readerdata != NULL);
244  	
245  	   return readerdata->nvarnames;
246  	}
247  	
248  	/** returns the number of constraint names in the COR problem */
249  	int SCIPcorGetNConsNames(
250  	   SCIP_READER*          reader              /**< the file reader itself */
251  	   )
252  	{
253  	   SCIP_READERDATA* readerdata;
254  	
255  	   assert(reader != NULL);
256  	   assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
257  	
258  	   readerdata = SCIPreaderGetData(reader);
259  	   assert(readerdata != NULL);
260  	
261  	   return readerdata->nconsnames;
262  	}
263  	
264  	/** returns the variable name for the given index */
265  	const char* SCIPcorGetVarName(
266  	   SCIP_READER*          reader,             /**< the file reader itself */
267  	   int                   i                   /**< the index of the variable that is requested */
268  	   )
269  	{
270  	   SCIP_READERDATA* readerdata;
271  	
272  	   assert(reader != NULL);
273  	   assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
274  	
275  	   readerdata = SCIPreaderGetData(reader);
276  	   assert(readerdata != NULL);
277  	   assert(i >= 0 && i < readerdata->nvarnames);
278  	
279  	   return readerdata->varnames[i];
280  	}
281  	
282  	/** returns the constraint name for the given index */
283  	const char* SCIPcorGetConsName(
284  	   SCIP_READER*          reader,             /**< the file reader itself */
285  	   int                   i                   /**< the index of the constraint that is requested */
286  	   )
287  	{
288  	   SCIP_READERDATA* readerdata;
289  	
290  	   assert(reader != NULL);
291  	   assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
292  	
293  	   readerdata = SCIPreaderGetData(reader);
294  	   assert(readerdata != NULL);
295  	   assert(i >= 0 && i < readerdata->nconsnames);
296  	
297  	   return readerdata->consnames[i];
298  	}
299