1 |
/* |
2 |
* Logical Relation Module |
3 |
* by Vicente Rico-Ramirez |
4 |
* Created: 09/96 |
5 |
* Version: $Revision: 1.8 $ |
6 |
* Version control file: $RCSfile: logrel.c,v $ |
7 |
* Date last modified: $Date: 1998/01/29 00:42:26 $ |
8 |
* Last modified by: $Author: ballan $ |
9 |
* |
10 |
* This file is part of the SLV solver. |
11 |
* |
12 |
* The SLV solver is free software; you can redistribute |
13 |
* it and/or modify it under the terms of the GNU General Public License as |
14 |
* published by the Free Software Foundation; either version 2 of the |
15 |
* License, or (at your option) any later version. |
16 |
* |
17 |
* The SLV solver is distributed in hope that it will be |
18 |
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of |
19 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
20 |
* General Public License for more details. |
21 |
* |
22 |
* You should have received a copy of the GNU General Public License |
23 |
* along with the program; if not, write to the Free Software Foundation, |
24 |
* Inc., 675 Mass Ave, Cambridge, MA 02139 USA. Check the file named |
25 |
* COPYING. COPYING is found in ../compiler. |
26 |
* |
27 |
*/ |
28 |
|
29 |
#include <math.h> |
30 |
#include "utilities/ascConfig.h" |
31 |
#include "utilities/ascMalloc.h" |
32 |
#include "utilities/mem.h" |
33 |
#include "general/list.h" |
34 |
#include "general/dstring.h" |
35 |
#include "compiler/fractions.h" |
36 |
#include "compiler/instance_enum.h" |
37 |
#include "compiler/compiler.h" |
38 |
#include "compiler/symtab.h" |
39 |
#include "compiler/extfunc.h" |
40 |
#include "compiler/extcall.h" |
41 |
#include "compiler/functype.h" |
42 |
#include "compiler/safe.h" |
43 |
#include "compiler/dimen.h" |
44 |
#include "compiler/types.h" |
45 |
#include "compiler/find.h" |
46 |
#include "compiler/atomvalue.h" |
47 |
#include "compiler/instquery.h" |
48 |
#include "compiler/mathinst.h" |
49 |
#include "compiler/parentchild.h" |
50 |
#include "compiler/instance_io.h" |
51 |
#include "compiler/logical_relation.h" |
52 |
#include "compiler/logrelation.h" |
53 |
#include "compiler/logrel_util.h" |
54 |
#include "compiler/packages.h" |
55 |
#define _SLV_SERVER_C_SEEN_ /* for the extrel stuff in header */ |
56 |
#include "solver/mtx.h" |
57 |
#include "solver/slv_types.h" |
58 |
#include "solver/var.h" |
59 |
#include "solver/rel.h" |
60 |
#include "solver/discrete.h" |
61 |
#include "solver/conditional.h" |
62 |
#include "solver/logrel.h" |
63 |
#include "solver/bnd.h" |
64 |
#include "solver/slv_server.h" |
65 |
|
66 |
#ifndef IPTR |
67 |
#define IPTR(i) ((struct Instance *)(i)) |
68 |
#endif |
69 |
#define LOGREL_DEBUG FALSE |
70 |
|
71 |
/* define symchar names needed */ |
72 |
static symchar *g_strings[1]; |
73 |
#define INCLUDED_R g_strings[0] |
74 |
|
75 |
|
76 |
static const struct logrel_relation g_logrel_defaults = { |
77 |
NULL, /* instance */ |
78 |
NULL, /* incidence */ |
79 |
0, /* n_incidences */ |
80 |
-1, /* mindex */ |
81 |
-1, /* sindex */ |
82 |
-1, /* model index */ |
83 |
(LOGREL_INCLUDED) /* flags */ |
84 |
}; |
85 |
|
86 |
/* |
87 |
* Don't forget to update the |
88 |
* initialization when the structure |
89 |
* is modified. |
90 |
*/ |
91 |
|
92 |
|
93 |
static struct logrel_relation |
94 |
*logrel_copy(const struct logrel_relation *logrel) |
95 |
{ |
96 |
struct logrel_relation *newlogrel; |
97 |
newlogrel = (struct logrel_relation *) |
98 |
ascmalloc( sizeof(struct logrel_relation) ); |
99 |
*newlogrel = *logrel; |
100 |
return(newlogrel); |
101 |
} |
102 |
|
103 |
|
104 |
struct logrel_relation *logrel_create(SlvBackendToken instance, |
105 |
struct logrel_relation *newlogrel) |
106 |
{ |
107 |
if (newlogrel==NULL) { |
108 |
newlogrel = logrel_copy(&g_logrel_defaults); /* malloc the logrelation */ |
109 |
} else { |
110 |
*newlogrel = g_logrel_defaults; /* init the space we've been sent */ |
111 |
} |
112 |
assert(newlogrel!=NULL); |
113 |
newlogrel->instance = instance; |
114 |
return(newlogrel); |
115 |
} |
116 |
|
117 |
|
118 |
|
119 |
SlvBackendToken logrel_instance(struct logrel_relation *logrel) |
120 |
{ |
121 |
if (logrel==NULL) return NULL; |
122 |
return (SlvBackendToken) logrel->instance; |
123 |
} |
124 |
|
125 |
void logrel_write_name(slv_system_t sys,struct logrel_relation *logrel, |
126 |
FILE *fp) |
127 |
{ |
128 |
if (logrel == NULL || fp==NULL) return; |
129 |
if (sys!=NULL) { |
130 |
WriteInstanceName(fp,logrel_instance(logrel),slv_instance(sys)); |
131 |
} else { |
132 |
WriteInstanceName(fp,logrel_instance(logrel),NULL); |
133 |
} |
134 |
} |
135 |
|
136 |
|
137 |
void logrel_destroy(struct logrel_relation *logrel) |
138 |
{ |
139 |
struct Instance *inst; |
140 |
|
141 |
ascfree((POINTER)logrel->incidence); |
142 |
inst = IPTR(logrel->instance); |
143 |
if (inst) { |
144 |
if (GetInterfacePtr(inst)==logrel) { |
145 |
SetInterfacePtr(inst,NULL); |
146 |
} |
147 |
} |
148 |
ascfree((POINTER)logrel); |
149 |
} |
150 |
|
151 |
|
152 |
uint32 logrel_flags( struct logrel_relation *logrel) |
153 |
{ |
154 |
return logrel->flags; |
155 |
} |
156 |
|
157 |
void logrel_set_flags(struct logrel_relation *logrel, unsigned int flags) |
158 |
{ |
159 |
logrel->flags = flags; |
160 |
} |
161 |
|
162 |
|
163 |
uint32 logrel_flagbit(struct logrel_relation *logrel, uint32 one) |
164 |
{ |
165 |
if (logrel==NULL || logrel->instance == NULL) { |
166 |
FPRINTF(stderr,"ERROR: logrel_flagbit called with bad logrel.\n"); |
167 |
return 0; |
168 |
} |
169 |
return (logrel->flags & one); |
170 |
} |
171 |
|
172 |
|
173 |
void logrel_set_flagbit(struct logrel_relation *logrel, uint32 field, |
174 |
uint32 one) |
175 |
{ |
176 |
if (one) { |
177 |
logrel->flags |= field; |
178 |
} else { |
179 |
logrel->flags &= ~field; |
180 |
} |
181 |
} |
182 |
|
183 |
|
184 |
boolean logrel_not_equal(struct logrel_relation *logrel) |
185 |
{ |
186 |
switch( LogRelRelop(GetInstanceLogRelOnly(IPTR(logrel->instance))) ) { |
187 |
case e_boolean_neq: |
188 |
return(TRUE); |
189 |
default: |
190 |
return(FALSE); |
191 |
} |
192 |
} |
193 |
|
194 |
|
195 |
boolean logrel_equal( struct logrel_relation *logrel) |
196 |
{ |
197 |
switch( LogRelRelop(GetInstanceLogRelOnly(IPTR(logrel->instance))) ) { |
198 |
case e_boolean_eq: |
199 |
return(TRUE); |
200 |
default: |
201 |
return(FALSE); |
202 |
} |
203 |
} |
204 |
|
205 |
|
206 |
static enum logrel_enum compenum2logrelenum(enum Expr_enum t) |
207 |
{ |
208 |
switch (t) { |
209 |
case e_boolean_eq: |
210 |
return e_logrel_equal; |
211 |
case e_boolean_neq: |
212 |
return e_logrel_not_equal; |
213 |
default: |
214 |
FPRINTF(ASCERR,"ERROR (logrel.c): compenum2logrelenum miscalled.\n"); |
215 |
return e_logrel_equal; |
216 |
} |
217 |
} |
218 |
|
219 |
|
220 |
enum logrel_enum logrel_relop( struct logrel_relation *logrel) |
221 |
{ |
222 |
return |
223 |
compenum2logrelenum(LogRelRelop( |
224 |
GetInstanceLogRelOnly(IPTR(logrel->instance)))); |
225 |
} |
226 |
|
227 |
|
228 |
char *logrel_make_name(slv_system_t sys,struct logrel_relation *logrel) |
229 |
{ |
230 |
return WriteInstanceNameString(IPTR(logrel->instance), |
231 |
IPTR(slv_instance(sys))); |
232 |
} |
233 |
|
234 |
|
235 |
int32 logrel_mindex( struct logrel_relation *logrel) |
236 |
{ |
237 |
return( logrel->mindex ); |
238 |
} |
239 |
|
240 |
|
241 |
void logrel_set_mindex( struct logrel_relation *logrel, int32 index) |
242 |
{ |
243 |
logrel->mindex = index; |
244 |
} |
245 |
|
246 |
|
247 |
int32 logrel_sindex( struct logrel_relation *logrel) |
248 |
{ |
249 |
return( logrel->sindex ); |
250 |
} |
251 |
|
252 |
void logrel_set_sindex( struct logrel_relation *logrel, int32 index) |
253 |
{ |
254 |
logrel->sindex = index; |
255 |
} |
256 |
|
257 |
|
258 |
int32 logrel_model(const struct logrel_relation *logrel) |
259 |
{ |
260 |
return((const int32) logrel->model ); |
261 |
} |
262 |
|
263 |
|
264 |
void logrel_set_model( struct logrel_relation *logrel, int32 index) |
265 |
{ |
266 |
logrel->model = index; |
267 |
} |
268 |
|
269 |
|
270 |
int32 logrel_residual(struct logrel_relation *logrel) |
271 |
{ |
272 |
return( LogRelResidual(GetInstanceLogRelOnly(IPTR(logrel->instance)))); |
273 |
} |
274 |
|
275 |
|
276 |
void logrel_set_residual( struct logrel_relation *logrel, int32 residual) |
277 |
{ |
278 |
struct logrelation *logreln; |
279 |
logreln = (struct logrelation *) |
280 |
GetInstanceLogRelOnly(IPTR(logrel->instance)); |
281 |
SetLogRelResidual(logreln,residual); |
282 |
} |
283 |
|
284 |
|
285 |
|
286 |
int32 logrel_nominal( struct logrel_relation *logrel) |
287 |
{ |
288 |
return( LogRelNominal(GetInstanceLogRelOnly(IPTR(logrel->instance)))); |
289 |
} |
290 |
|
291 |
|
292 |
int32 logrel_n_incidencesF(struct logrel_relation *logrel) |
293 |
{ |
294 |
if (logrel!=NULL) return logrel->n_incidences; |
295 |
FPRINTF(stderr,"logrel_n_incidences miscalled with NULL\n"); |
296 |
return 0; |
297 |
} |
298 |
|
299 |
|
300 |
void logrel_set_incidencesF(struct logrel_relation *logrel,int n, |
301 |
struct dis_discrete **bv) |
302 |
{ |
303 |
if(logrel!=NULL && n >=0) { |
304 |
if (n && bv==NULL) { |
305 |
FPRINTF(stderr,"logrel_set_incidence miscalled with NULL list\n"); |
306 |
} |
307 |
logrel->n_incidences = n; |
308 |
logrel->incidence = bv; |
309 |
return; |
310 |
} |
311 |
FPRINTF(stderr,"logrel_set_incidence miscalled with NULL or n < 0\n"); |
312 |
} |
313 |
|
314 |
|
315 |
const struct dis_discrete |
316 |
**logrel_incidence_list( struct logrel_relation *logrel) |
317 |
{ |
318 |
if (logrel==NULL) return NULL; |
319 |
return( (const struct dis_discrete **)logrel->incidence ); |
320 |
} |
321 |
|
322 |
|
323 |
struct dis_discrete |
324 |
**logrel_incidence_list_to_modify( struct logrel_relation *logrel) |
325 |
{ |
326 |
if (logrel==NULL) return NULL; |
327 |
return( (struct dis_discrete **)logrel->incidence ); |
328 |
} |
329 |
|
330 |
|
331 |
int logrel_apply_filter( struct logrel_relation *logrel, |
332 |
logrel_filter_t *filter) |
333 |
{ |
334 |
if (logrel==NULL || filter==NULL) { |
335 |
FPRINTF(stderr,"logrel_apply_filter miscalled with NULL\n"); |
336 |
return FALSE; |
337 |
} |
338 |
/* AND to mask off irrelevant bits in flags and match value, |
339 |
then compare */ |
340 |
return ( (filter->matchbits & logrel->flags) == |
341 |
(filter->matchbits & filter->matchvalue) ); |
342 |
} |
343 |
|
344 |
/* to bad there's no entry point that rel must call before being used |
345 |
* generally, like the FindType checking stuff in var.c |
346 |
*/ |
347 |
static void check_included_flag(void){ |
348 |
if (INCLUDED_R == NULL || AscFindSymbol(INCLUDED_R) == NULL) { |
349 |
INCLUDED_R = AddSymbolL("included",8); |
350 |
} |
351 |
} |
352 |
|
353 |
uint32 logrel_included( struct logrel_relation *logrel) |
354 |
{ |
355 |
struct Instance *c; |
356 |
check_included_flag(); |
357 |
c = ChildByChar(IPTR(logrel->instance),INCLUDED_R); |
358 |
if( c == NULL ) { |
359 |
FPRINTF(stderr,"ERROR: (logrel) logrel_included\n"); |
360 |
FPRINTF(stderr," No 'included' field in logrelation.\n"); |
361 |
WriteInstance(stderr,IPTR(logrel->instance)); |
362 |
return FALSE; |
363 |
} |
364 |
logrel_set_flagbit(logrel,LOGREL_INCLUDED,GetBooleanAtomValue(c)); |
365 |
return( GetBooleanAtomValue(c) ); |
366 |
} |
367 |
|
368 |
|
369 |
void logrel_set_included( struct logrel_relation *logrel, uint32 included) |
370 |
{ |
371 |
struct Instance *c; |
372 |
check_included_flag(); |
373 |
c = ChildByChar(IPTR(logrel->instance),INCLUDED_R); |
374 |
if( c == NULL ) { |
375 |
FPRINTF(stderr,"ERROR: (logrel) logrel_set_included\n"); |
376 |
FPRINTF(stderr," No 'included' field in logrelation.\n"); |
377 |
WriteInstance(stderr,IPTR(logrel->instance)); |
378 |
return; |
379 |
} |
380 |
SetBooleanAtomValue(c,included,(unsigned)0); |
381 |
logrel_set_flagbit(logrel,LOGREL_INCLUDED,included); |
382 |
} |