1 |
aw0a |
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 |
|
|
} |