1 |
/* ASCEND modelling environment |
2 |
Copyright (C) 1990 Karl Michael Westerberg |
3 |
Copyright (C) 1993 Joseph Zaher |
4 |
Copyright (C) 1994 Joseph Zaher, Benjamin Andrew Allan |
5 |
Copyright (C) 2006 Carnegie Mellon University |
6 |
|
7 |
This program is free software; you can redistribute it and/or |
8 |
modify it under the terms of the GNU General Public License |
9 |
as published by the Free Software Foundation; either version 2 |
10 |
of the License, or (at your option) any later version. |
11 |
|
12 |
This program is distributed in the hope that it will be useful, |
13 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 |
GNU General Public License for more details. |
16 |
|
17 |
You should have received a copy of the GNU General Public License |
18 |
along with this program; if not, write to the Free Software |
19 |
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
20 |
*//** |
21 |
@file |
22 |
Relation module for the SLV solver. |
23 |
|
24 |
This is the ascend version of the rel module. This |
25 |
version should be used by any user who receives his/her |
26 |
equations directly from an instance tree created by the |
27 |
ASCEND compiler. |
28 |
|
29 |
Dates: 06/90 - original version |
30 |
04/94 - added rel_apply_filter() which uses the new |
31 |
rel_filter_t data structure for perfoming all |
32 |
relation filtering needs (eliminating the |
33 |
filter module) |
34 |
|
35 |
Requires: #include "utilities/ascConfig.h" |
36 |
#include "var.h" |
37 |
|
38 |
SERVER ONLY: #include "expr.h" |
39 |
#include "types.h" |
40 |
#include "extfunc.h" |
41 |
#include "relation.h" |
42 |
#include "packages.h" |
43 |
#include "extcall.h" |
44 |
#include "mtx.h" |
45 |
*//* |
46 |
by Karl Michael Westerberg and Joseph Zaher |
47 |
Created: 2/6/90 |
48 |
Version: $Revision: 1.41 $ |
49 |
Version control file: $RCSfile: rel.h,v $ |
50 |
Date last modified: $Date: 1998/02/05 15:59:24 $ |
51 |
Last modified by: $Author: ballan $ |
52 |
*/ |
53 |
|
54 |
#ifndef ASC_REL_H |
55 |
#define ASC_REL_H |
56 |
|
57 |
#include <utilities/ascConfig.h> |
58 |
|
59 |
/* |
60 |
* rel_relation data type and basic type operators. |
61 |
*/ |
62 |
|
63 |
#define rel_TOK_less 0x1 |
64 |
#define rel_TOK_equal 0x2 |
65 |
#define rel_TOK_greater 0x4 |
66 |
|
67 |
struct rel_extnode { |
68 |
int32 whichvar; |
69 |
struct ExtRelCache *cache; /**< pointer to private structure */ |
70 |
}; |
71 |
|
72 |
/** The exact operator of a relation. */ |
73 |
enum rel_enum { |
74 |
e_rel_minimize, |
75 |
e_rel_maximize, |
76 |
e_rel_equal, |
77 |
e_rel_not_equal, |
78 |
e_rel_less, |
79 |
e_rel_greater, |
80 |
e_rel_lesseq, |
81 |
e_rel_greatereq |
82 |
}; |
83 |
|
84 |
/** Backend relation types. */ |
85 |
enum backend_enum { |
86 |
e_rel_token, |
87 |
e_rel_glassbox, |
88 |
e_rel_blackbox |
89 |
}; |
90 |
|
91 |
/** |
92 |
* Relation data structure. |
93 |
* If you mess with this struct, change the defaults for it in .c file. |
94 |
*/ |
95 |
struct rel_relation { |
96 |
SlvBackendToken instance; |
97 |
struct rel_extnode *nodeinfo; /**< Not NULL if blackbox relation */ |
98 |
struct var_variable **incidence; |
99 |
/**< array of atomic vars and nonvars in rel */ |
100 |
/* |
101 |
* For future use: |
102 |
* |
103 |
* struct var_variable **incidentals; array of nonvars, |
104 |
* once solveratoms arrive. |
105 |
* |
106 |
* int32 n_incidentals; |
107 |
*/ |
108 |
enum backend_enum type; /**< tokens, glassbox or blackbox */ |
109 |
int32 n_incidences; /**< length of incidence. */ |
110 |
int32 mindex; /**< index in the slv_system_t master list */ |
111 |
int32 sindex; /**< index in the slv_system_t solver list */ |
112 |
int32 model; /**< index of a hypothetical MODEL rel is from */ |
113 |
uint32 flags; /**< flags */ |
114 |
}; |
115 |
|
116 |
extern struct rel_relation *rel_create(SlvBackendToken instance, |
117 |
struct rel_relation *rel); |
118 |
/**< |
119 |
* Creates a relation given the relation instance. |
120 |
* If the rel supplied is NULL, we allocate the memory for the |
121 |
* rel we return, else we just init the memory you hand us and |
122 |
* return it to you.<br><br> |
123 |
* We set the fields instance, nodeinfo, type following |
124 |
* the instance. Setting the rest of the information is the job |
125 |
* of the bridge building function between the ascend instance |
126 |
* tree (or other relation back end) and the slv_system_t. |
127 |
* In particular, the incidence list and indexing info is not |
128 |
* handled here. |
129 |
*/ |
130 |
|
131 |
extern void rel_destroy(struct rel_relation *rel); |
132 |
/**< |
133 |
* Destroys a relation. |
134 |
*/ |
135 |
|
136 |
extern void rel_write_name(slv_system_t sys, struct rel_relation *rel, FILE *file); |
137 |
/**< |
138 |
* Writes a name to the file given. Handles NULL inputs gracefully. |
139 |
* Does not print any whitespace, including carriage returns. |
140 |
* Is faster than slv_print_var_name. |
141 |
* If sys is NULL, writes full ascend name. If file or rel is NULL |
142 |
* does not write. |
143 |
*/ |
144 |
|
145 |
/** Relation filter structure */ |
146 |
typedef struct rel_filter_structure { |
147 |
uint32 matchbits; /**< Bits to match. */ |
148 |
uint32 matchvalue; /**< Value to match. */ |
149 |
} rel_filter_t; |
150 |
/**< Relation filter type */ |
151 |
|
152 |
ASC_DLLSPEC(SlvBackendToken) rel_instance(struct rel_relation *rel); |
153 |
/**< |
154 |
* Returns the instance pointer from a rel. |
155 |
*/ |
156 |
|
157 |
extern void rel_set_extnodeinfo(struct rel_relation *rel, |
158 |
struct rel_extnode *nodeinfo); |
159 |
/**< Sets the external node information structure for a relation. */ |
160 |
extern struct rel_extnode *rel_extnodeinfo(struct rel_relation *rel); |
161 |
/**< |
162 |
* Fetches the pointer to the external node information structure for |
163 |
* a relation. If this is NULL, which will be the case for most |
164 |
* relations, then there are no external call nodes present. |
165 |
*/ |
166 |
|
167 |
extern void rel_set_extwhichvar(struct rel_relation *rel, int whichvar); |
168 |
/**< Sets the argument list index for a relation having external nodes. */ |
169 |
extern int32 rel_extwhichvar(struct rel_relation *rel); |
170 |
/**< |
171 |
* Returns the index into the argument list from which rel was |
172 |
* constructed. This applies ONLY to rels that have external nodes ! |
173 |
* Relations that have external nodes have associated with them an |
174 |
* index into the argument list from which the relation was constructed. |
175 |
* rel_whichvar returns that index. e.g. if when this relation was |
176 |
* constructed from an external procedure call, the number of output |
177 |
* variables was 4, and the number of inputs was 6, valid results from |
178 |
* this rel_whichvar would be 7, 8, 9, 10. |
179 |
* A return value <= 0 is an error. |
180 |
*/ |
181 |
|
182 |
extern boolean rel_less(struct rel_relation *rel); |
183 |
/**< |
184 |
* Returns true if the given relation is satisfied if "less than" |
185 |
* is among those that make up the comparator of the relation |
186 |
* (i.e. <>, <, or <=).<br><br> |
187 |
* le==TRUE implies rel would be satisfied if lhs < rhs |
188 |
*/ |
189 |
extern boolean rel_equal(struct rel_relation *rel); |
190 |
/**< |
191 |
* Returns true if the given relation is satisfied if "equals" |
192 |
* is among those that make up the comparator of the relation |
193 |
* (i.e. =, >=, or <=).<br><br> |
194 |
* eq==TRUE implies rel would be satisfied if lhs ~ rhs |
195 |
*/ |
196 |
extern boolean rel_greater(struct rel_relation *rel); |
197 |
/**< |
198 |
* Returns true if the given relation is satisfied if "greater than" |
199 |
* is among those that make up the comparator of the relation |
200 |
* (i.e. <>, >, or >=).<br><br> |
201 |
* gr==TRUE implies rel would be satisfied if lhs > rhs |
202 |
*/ |
203 |
/* OLD GROUP COMMENT */ |
204 |
/* |
205 |
* le = rel_less(rel) |
206 |
* eq = rel_equal(rel) |
207 |
* gr = rel_greater(rel) |
208 |
* boolean le,eq,gr; |
209 |
* struct rel_relation *rel; |
210 |
* |
211 |
* Returns true if the given relation is satisfied if the |
212 |
* operator in question is among those that make up the |
213 |
* comparator of the relation. (e.g. rel_less is satisfied |
214 |
* by (<>,<.<=). |
215 |
* le==TRUE implies rel would be satisfied if lhs < rhs |
216 |
* gr==TRUE implies rel would be satisfied if lhs > rhs |
217 |
* eq==TRUE implies rel would be satisfied if lhs ~ rhs |
218 |
*/ |
219 |
|
220 |
extern enum rel_enum rel_relop(struct rel_relation *rel); |
221 |
/**< |
222 |
* Returns the type of the relational operator of a given relation. |
223 |
*/ |
224 |
|
225 |
extern char *rel_make_name(slv_system_t sys, struct rel_relation *rel); |
226 |
/**< |
227 |
* Copies of the relation instance name can be made and returned. |
228 |
* The string returned should be freed when no longer in use. |
229 |
*/ |
230 |
|
231 |
extern int32 rel_mindex(struct rel_relation *rel); |
232 |
/**< |
233 |
* Retrieves the index number of the given relation as it |
234 |
* appears in a slv_system_t master relation list. |
235 |
*/ |
236 |
extern void rel_set_mindex(struct rel_relation *rel, int32 index); |
237 |
/**< |
238 |
* Sets the index number of the given relation as it |
239 |
* appears in a slv_system_t master relation list. |
240 |
*/ |
241 |
|
242 |
extern int32 rel_sindex(const struct rel_relation *rel); |
243 |
/**< |
244 |
* Retrieves the index number of the given relation as it |
245 |
* appears in a solvers relation list. The index is most often used |
246 |
* to assign the relation to a specific original row of a matrix. |
247 |
*/ |
248 |
extern void rel_set_sindex(struct rel_relation *rel, int32 index); |
249 |
/**< |
250 |
* Sets the index number of the given relation as it |
251 |
* appears in a solvers relation list. The index is most often used |
252 |
* to assign the relation to a specific original row of a matrix. |
253 |
*/ |
254 |
|
255 |
extern int32 rel_model(const struct rel_relation *rel); |
256 |
/**< |
257 |
* Retrieves the model number of the given relation. |
258 |
* In a hierarchy, relations come in groups associated with |
259 |
* models. Models are numbered from 1 to some upper limit. |
260 |
*/ |
261 |
extern void rel_set_model(struct rel_relation *rel, int32 index); |
262 |
/**< |
263 |
* Sets the model number of the given relation. |
264 |
* In a hierarchy, relations come in groups associated with |
265 |
* models. Models are numbered from 1 to some upper limit. |
266 |
*/ |
267 |
|
268 |
ASC_DLLSPEC(real64) rel_residual(struct rel_relation *rel); |
269 |
/**< |
270 |
* Retrieves the residual field of the given relation. |
271 |
* Note that the residual is not actually computed by rel_residual: |
272 |
* there is no guarantee (from this function) that the residual is |
273 |
* actually correct. |
274 |
*/ |
275 |
ASC_DLLSPEC(void) rel_set_residual(struct rel_relation *rel, real64 residual); |
276 |
/**< |
277 |
* Sets the residual field of the given relation. |
278 |
*/ |
279 |
|
280 |
extern real64 rel_nominal(struct rel_relation *rel); |
281 |
/**< |
282 |
* Retrieves the nominal field of the given relation. |
283 |
* No slv client has any business being able to set the nominal, |
284 |
* so no such operator is provided. |
285 |
*/ |
286 |
|
287 |
extern void rel_set_nominal(struct rel_relation *rel, real64 nominal); |
288 |
/**< |
289 |
* Breaking the 'rule' of rel_nominal() for the time being. |
290 |
* @todo Remove rel_set_nominal() or change "rule" stated by rel_nominal(). |
291 |
*/ |
292 |
|
293 |
#ifdef NDEBUG |
294 |
#define rel_n_incidences(rel) ((rel)->n_incidences) |
295 |
#else |
296 |
#define rel_n_incidences(rel) rel_n_incidencesF(rel) |
297 |
#endif |
298 |
/**< |
299 |
* Returns the length of the incidence_list for a relation. |
300 |
* Not everything in the incidence list is necessarily a |
301 |
* variable for your particular solver -- check the flags. |
302 |
* @param rel struct rel_relation *, the relation to query. |
303 |
* @return Returns the length as an int32. |
304 |
* @see rel_n_incidencesF() |
305 |
*/ |
306 |
|
307 |
#ifdef NDEBUG |
308 |
#define rel_set_incidences(rel,n,ilist) \ |
309 |
(rel)->n_incidences=(n); (rel)->incidence = (ilist) |
310 |
#else |
311 |
#define rel_set_incidences(rel,n,ilist) rel_set_incidencesF((rel),(n),(ilist)) |
312 |
#endif |
313 |
/**< |
314 |
* Sets the length and incidence_list for a relation. |
315 |
* Not everything in the incidence list is necessarily a |
316 |
* variable for your particular solver -- check the flags. |
317 |
* Solver clients should not call rel_set_incidences, |
318 |
* it is only for use by constructors of bridges to relation |
319 |
* back ends. |
320 |
* @param rel struct rel_relation *, the relation to modify. |
321 |
* @param n int32 |
322 |
* @param ilist struct var_variable **, the incidence list |
323 |
* @return No return value. |
324 |
* @see rel_set_incidencesF() |
325 |
*/ |
326 |
|
327 |
ASC_DLLSPEC(int32) rel_n_incidencesF(struct rel_relation *rel); |
328 |
/**< |
329 |
* Implementation function for rel_n_incidences(). Do not call |
330 |
* this function directly - use rel_n_incidences() instead. |
331 |
*/ |
332 |
extern void rel_set_incidencesF(struct rel_relation *rel, |
333 |
int32 n, |
334 |
struct var_variable **ilist); |
335 |
/**< |
336 |
* Implementation function for rel_set_incidences(). Do not call |
337 |
* this function directly - use rel_set_incidences() instead. |
338 |
*/ |
339 |
/* OLD GROUP COMMENTS */ |
340 |
/* |
341 |
* rel_n_incidences(rel) |
342 |
* rel_set_incidences(rel,n,ilist) //SERVER ONLY |
343 |
* struct rel_relation *rel; |
344 |
* struct var_variable **ilist; |
345 |
* int32 n; |
346 |
* |
347 |
* rel_n_incidences returns the length of the incidence_list. |
348 |
* Not everything in the incidence list is necessarily a |
349 |
* variable for your particular solver -- check the flags. |
350 |
* Solver clients should not call rel_set_incidences, |
351 |
* it is only for use by constructors of bridges to relation |
352 |
* back ends. |
353 |
*/ |
354 |
|
355 |
extern struct var_variable |
356 |
**rel_incidence_list_to_modify(struct rel_relation *rel); |
357 |
/**< |
358 |
* Returns a non-const pointer to an array rel_n_incidences(rel) |
359 |
* long of vars. |
360 |
* @see rel_incidence_list(). |
361 |
*/ |
362 |
ASC_DLLSPEC(const struct var_variable**) rel_incidence_list(struct rel_relation *rel); |
363 |
/**< |
364 |
* Returns a pointer to an array rel_n_incidences(rel) long of vars. |
365 |
* Each element of the array is a struct var_variable *. |
366 |
* Check the var sindex to see where each might go in a jacobian. |
367 |
* If there is no incidence, NULL is returned. |
368 |
* Pointers in this array will be unique.<br><br> |
369 |
* The list belongs to the relation. Do not destroy it. Do not change it.<br><br> |
370 |
* |
371 |
* The return value IS NOT A NULL-TERMINATED LIST. |
372 |
*/ |
373 |
|
374 |
/* |
375 |
* relation filtration functions. |
376 |
* We have a lot (32) of binary (one bit) flags a client may want to query |
377 |
* in arbitrary combinations and paying attention to only certain of |
378 |
* the bits. We will provide a set of macros and functions for each of |
379 |
* these bits and for operations on the whole set. |
380 |
*/ |
381 |
|
382 |
extern int32 rel_apply_filter(const struct rel_relation *rel, |
383 |
rel_filter_t *filter); |
384 |
/**< |
385 |
* Returns 1 only if all of the positions specified in |
386 |
* filter->matchbits have the same values in |
387 |
* filter->matchvalue and the relation's flags value. |
388 |
* Bits set to 0 in filter->matchbits are ignored for the test.<br><br> |
389 |
* |
390 |
* EXAMPLE: |
391 |
* To find out if a relation is an unsatisfied equality: |
392 |
* We don't care about anything except satisfaction and equality, |
393 |
* so set filter->matchbits = (REL_SATISFIED | REL_EQUALITY); |
394 |
* We want relation NOT satisfied, so leave REL_SATISFIED = 0 |
395 |
* in filter->matchvalue, i.e. filter->matchvalue = REL_EQUALITY; |
396 |
* Usually it is most convenient to just declare a rel_filter_t filt; |
397 |
* locally in a function and then take the address of it (&filt) after |
398 |
* setting filt.matchbits = (| of all your interesting bits) and |
399 |
* setting filt.matchvalue = (| of the bits you want to be TRUE). |
400 |
*/ |
401 |
|
402 |
extern uint32 rel_flags(struct rel_relation *rel); |
403 |
/**< |
404 |
* Returns the flags field of the relation. |
405 |
*/ |
406 |
extern void rel_set_flags(struct rel_relation *rel, uint32 flags); |
407 |
/**< |
408 |
* Sets the entire flag field to the value of flags given. |
409 |
*/ |
410 |
|
411 |
ASC_DLLSPEC(uint32) rel_flagbit(struct rel_relation *rel, uint32 name); |
412 |
/**< |
413 |
* Returns the value of the bit specified from the relation flags. |
414 |
* name should be a REL_xx flag defined above) |
415 |
*/ |
416 |
|
417 |
extern void rel_set_flagbit(struct rel_relation *rel, |
418 |
uint32 NAME, uint32 oneorzero); |
419 |
/**< |
420 |
* Sets the bit, which should be referred to by its macro name, |
421 |
* on if oneorzero is >0 and off is oneorzero is 0. |
422 |
* The macro names are the defined up at the top of this file. |
423 |
* <pre> |
424 |
* Example: |
425 |
* rel_set_flags(rel,REL_PARTITION,1) turns on the REL_PARTITION bit. |
426 |
* |
427 |
* What it really does is: |
428 |
* if (oneorzero) { |
429 |
* rel->flags |= field; |
430 |
* } else { |
431 |
* rel->flags &= ~field; |
432 |
* } |
433 |
* </pre> |
434 |
* In unix, see also man 3f bit or man not. |
435 |
*/ |
436 |
|
437 |
/* |
438 |
* the bit flags. explained afterward. several are for use of |
439 |
* transient clients and should be ignored by solver engines |
440 |
*/ |
441 |
#define REL_PARTITION 0x1 |
442 |
/**< Is it in the interesting region? Reordering clients. */ |
443 |
#define REL_TORN 0x2 |
444 |
/**< Is it a tear? Reordering clients output. */ |
445 |
#define REL_INTERFACE 0x4 |
446 |
/**< User suggests it's a tear eqn. Solvers, ui clients. */ |
447 |
#define REL_INCLUDED 0x8 |
448 |
/**< |
449 |
* User wants eqn in problem. Solvers, ui clients. |
450 |
* Use rel_set_* to change. |
451 |
* INCLUDED is as yet a funny one. Treat it as readonly because |
452 |
* you can only change it using a real function and not the |
453 |
* bit manipulation functions. It is here in the bits because |
454 |
* it is useful in filters sometimes. |
455 |
*/ |
456 |
#define REL_OBJNEGATE 0x10 |
457 |
/**< Read_only for clients. Rel module. */ |
458 |
#define REL_BLACKBOX 0x20 |
459 |
/**< Read_only for clients. Rel module. */ |
460 |
#define REL_SATISFIED 0x40 |
461 |
/**< |
462 |
* Has rel been pronounced satisfied by someone? |
463 |
* Bit should be treated as readonly. use rel_set_* to change. |
464 |
*/ |
465 |
#define REL_EQUALITY 0x80 |
466 |
/**< Is relation an equality? Readonly for clients. */ |
467 |
#define REL_INBLOCK 0x100 |
468 |
/**< Is the relation in the current block of registered client? For clients. */ |
469 |
/* Conditional Modeling */ |
470 |
#define REL_INWHEN 0x200 |
471 |
/**< Is relation in a when? Readonly for clients. */ |
472 |
#define REL_ACTIVE 0x400 |
473 |
/**< Is this relation currently a part of my problem? */ |
474 |
#define REL_INVARIANT 0x800 |
475 |
/**< Is this relation an invariant in the conditional modeling analysis? */ |
476 |
/* Conditional Relations (Boundaries) */ |
477 |
#define REL_CONDITIONAL 0x1000 |
478 |
/**< Is relation conditional? Readonly for clients. */ |
479 |
#define REL_IN_CUR_SUBREGION 0x2000 |
480 |
/**< Is the relation in the subregion currently analyzed? */ |
481 |
#define REL_GENERATED 0x10000 |
482 |
/**< |
483 |
* Temporary relation that doesn't exist independently in the backend, |
484 |
* but is made by some process of the backend or the solver client. |
485 |
* Is rel fake and cooked up for this system only? */ |
486 |
|
487 |
/* OLD GROUP COMMENTS */ |
488 |
/* |
489 |
* REL_PARTITION reordering clients. is it in the interesting region |
490 |
* REL_TORN reordering clients output. is it a tear. |
491 |
* REL_INTERFACE solvers, ui clients. user suggests it's a tear eqn. |
492 |
* REL_INCLUDED solvers, ui clients. user wants eqn in problem. |
493 |
* bit should be treated as readonly. use rel_set_* |
494 |
* to change. |
495 |
* REL_OBJNEGATE rel module. read_only for clients. |
496 |
* REL_BLACKBOX rel module. read_only for clients. |
497 |
* REL_SATISFIED has rel been pronounced satisfied by someone? |
498 |
* bit should be treated as readonly. use rel_set_* |
499 |
* to change. |
500 |
* REL_EQUALITY is relation an equality? readonly for clients. |
501 |
* REL_INBLOCK is the relation in the current block of registered |
502 |
* client? for clients. |
503 |
* REL_INWHEN is relation in a when? readonly for clients. |
504 |
* REL_ACTIVE is this relation currently a part of my problem ? |
505 |
* REL_INVARIANT is this relation an invariant in the conditional |
506 |
* modeling analysis |
507 |
* REL_CONDITIONAL is relation conditional? readonly for clients |
508 |
* REL_IN_CUR_SUBREGION is the relation in the subregion currently |
509 |
* analyzed ? |
510 |
* REL_GENERATED is rel fake and cooked up for this system only? |
511 |
*/ |
512 |
|
513 |
/* |
514 |
* the bit flag lookups |
515 |
*/ |
516 |
#ifdef NDEBUG |
517 |
#define rel_partition(rel) ((rel)->flags & REL_PARTITION) |
518 |
#define rel_torn(rel) ((rel)->flags & REL_TORN) |
519 |
#define rel_interface(rel) ((rel)->flags & REL_INTERFACE) |
520 |
#define rel_obj_negate(rel) ((rel)->flags & REL_OBJNEGATE) |
521 |
/**< |
522 |
* Returns TRUE if relation is of type e_maximize. |
523 |
* Returns FALSE if relation is of type e_minimize. |
524 |
* Note: should only be used on objectives. other relations |
525 |
* will give a meaningless result (probably FALSE). |
526 |
*/ |
527 |
#define rel_blackbox(rel) ((rel)->flags & REL_BLACKBOX) |
528 |
#define rel_satisfied(rel) ((rel)->flags & REL_SATISFIED) |
529 |
/**< Retrieves the satisfied field of the given relation. |
530 |
* See rel_residual() for disclaimer. */ |
531 |
#define rel_equality(rel) ((rel)->flags & REL_EQUALITY) |
532 |
/**< TRUE if relation is of form lhs = rhs. */ |
533 |
#define rel_in_block(rel) ((rel)->flags & REL_INBLOCK) |
534 |
/**< Retrieves the INBLOCK member of the given relation flags |
535 |
* which determines if the relation is within the current block. */ |
536 |
#define rel_in_when(rel) ((rel)->flags & REL_INWHEN) |
537 |
#define rel_active(rel) ((rel)->flags & REL_ACTIVE) |
538 |
#define rel_invariant(rel) ((rel)->flags & REL_INVARIANT) |
539 |
#define rel_conditional(rel) ((rel)->flags & REL_CONDITIONAL) |
540 |
#define rel_in_cur_subregion(rel) ((rel)->flags & REL_IN_CUR_SUBREGION) |
541 |
#define rel_generated(rel) ((rel)->flags & REL_GENERATED) |
542 |
#else |
543 |
#define rel_partition(rel) rel_flagbit((rel),REL_PARTITION) |
544 |
#define rel_torn(rel) rel_flagbit((rel),REL_TORN) |
545 |
#define rel_interface(rel) rel_flagbit((rel),REL_INTERFACE) |
546 |
#define rel_obj_negate(rel) rel_flagbit((rel),REL_OBJNEGATE) |
547 |
/**< |
548 |
* Returns TRUE if relation is of type e_maximize. |
549 |
* Returns FALSE if relation is of type e_minimize. |
550 |
* Note: should only be used on objectives. other relations |
551 |
* will give a meaningless result (probably FALSE). |
552 |
*/ |
553 |
#define rel_blackbox(rel) rel_flagbit((rel),REL_BLACKBOX) |
554 |
#define rel_satisfied(rel) rel_flagbit((rel),REL_SATISFIED) |
555 |
/**< Retrieves the satisfied field of the given relation. |
556 |
* See rel_residual() for disclaimer. */ |
557 |
#define rel_equality(rel) rel_flagbit((rel),REL_EQUALITY) |
558 |
/**< TRUE if relation is of form lhs = rhs. */ |
559 |
#define rel_in_block(rel) rel_flagbit((rel),REL_INBLOCK) |
560 |
/**< Retrieves the INBLOCK member of the given relation flags |
561 |
* which determines if the relation is within the current block. */ |
562 |
#define rel_in_when(rel) rel_flagbit((rel),REL_INWHEN) |
563 |
#define rel_active(rel) rel_flagbit((rel),REL_ACTIVE) |
564 |
#define rel_invariant(rel) rel_flagbit((rel),REL_INVARIANT) |
565 |
#define rel_conditional(rel) rel_flagbit((rel),REL_CONDITIONAL) |
566 |
#define rel_in_cur_subregion(rel) rel_flagbit((rel),REL_IN_CUR_SUBREGION) |
567 |
#define rel_generated(rel) rel_flagbit((rel),REL_GENERATED) |
568 |
#endif /* NDEBUG */ |
569 |
|
570 |
/* |
571 |
* bit flag assignments. any value other than 0 for bv turns the |
572 |
* named flag to 1. 0 sets it to 0. |
573 |
* Many of these bits have read-only semantics for clients. |
574 |
* Take care when setting them. |
575 |
*/ |
576 |
#define rel_set_partition(rel,bitval) rel_set_flagbit((rel),REL_PARTITION,(bitval)) |
577 |
#define rel_set_torn(rel,bitval) rel_set_flagbit((rel),REL_TORN,(bitval)) |
578 |
#define rel_set_interface(rel,bitval) rel_set_flagbit((rel),REL_INTERFACE,(bitval)) |
579 |
#define rel_set_obj_negate(rel,bitval) rel_set_flagbit((rel),REL_OBJNEGATE,(bitval)) |
580 |
#define rel_set_blackbox(rel,bitval) rel_set_flagbit((rel),REL_BLACKBOX,(bitval)) |
581 |
#define rel_set_satisfied(rel,bitval) rel_set_flagbit((rel),REL_SATISFIED,(bitval)) |
582 |
#define rel_set_equality(rel,bitval) rel_set_flagbit((rel),REL_EQUALITY,(bitval)) |
583 |
#define rel_set_in_block(rel,bitval) rel_set_flagbit((rel),REL_INBLOCK,(bitval)) |
584 |
#define rel_set_in_when(rel,bitval) rel_set_flagbit((rel),REL_INWHEN,(bitval)) |
585 |
#define rel_set_active(rel,bitval) rel_set_flagbit((rel),REL_ACTIVE,(bitval)) |
586 |
#define rel_set_invariant(rel,bitval) rel_set_flagbit((rel),REL_INVARIANT,(bitval)) |
587 |
#define rel_set_conditional(rel,bitval) \ |
588 |
rel_set_flagbit((rel),REL_CONDITIONAL,(bitval)) |
589 |
#define rel_set_in_cur_subregion(rel,bitval) \ |
590 |
rel_set_flagbit((rel),REL_IN_CUR_SUBREGION,(bitval)) |
591 |
#define rel_set_generated(rel,bitval) rel_set_flagbit((rel),REL_GENERATED,(bitval)) |
592 |
|
593 |
ASC_DLLSPEC(uint32) rel_included(struct rel_relation *rel); |
594 |
/**< |
595 |
* Retrieves the included field of the given relation. |
596 |
* @todo This has side effects on the ascend instance, so it isn't |
597 |
* implemented with the rest of the macros above. This needs to |
598 |
* change. |
599 |
*/ |
600 |
extern void rel_set_included(struct rel_relation *rel, uint32 included); |
601 |
/**< |
602 |
* Sets the included field of the given relation. |
603 |
* <!-- This has side effect on the ascend instance, so it isn't --> |
604 |
* <!-- implemented with the rest of the macros above. This needs to --> |
605 |
* <!-- change. --> |
606 |
*/ |
607 |
|
608 |
/* |
609 |
* in_block = rel_in_block(rel) |
610 |
* rel_set_in_block(rel,in_block) |
611 |
* uint32 in_block; |
612 |
* struct rel_relation *rel; |
613 |
* |
614 |
* Sets or retrieves the INBLOCK member of the given relation flags |
615 |
* which determines if the relation is within the current block. |
616 |
*/ |
617 |
|
618 |
/* |
619 |
* rel_obj_negate(rel) |
620 |
* struct rel_relation *rel; |
621 |
* |
622 |
* Returns TRUE if relation is of type e_maximize. |
623 |
* Returns FALSE if relation is of type e_minimize. |
624 |
* Note: should only be used on objectives. other relations |
625 |
* will give a meaningless result (probably FALSE). |
626 |
*/ |
627 |
|
628 |
/* |
629 |
* satisfied = rel_satisfied(rel) |
630 |
* rel_set_satisfied(rel,satisfied) |
631 |
* uint32 satisfied; |
632 |
* struct rel_relation *rel; |
633 |
* |
634 |
* Sets or retrieves the satisfied field of the given relation (see |
635 |
* rel_residual() for disclaimer). |
636 |
*/ |
637 |
|
638 |
/* |
639 |
* equality = rel_equality(rel) |
640 |
* rel_set_equality(rel,equality) |
641 |
* uint32 equality; |
642 |
* struct rel_relation *rel; |
643 |
* |
644 |
* TRUE if relation is of form lhs = rhs. |
645 |
*/ |
646 |
|
647 |
extern real64 rel_multiplier(struct rel_relation *rel); |
648 |
/**< |
649 |
* Retrieves the multiplier field of the given relation. |
650 |
* This is expected to be computed as a lagrange multiplier which will |
651 |
* relate the gradient of the relation rel with that of some objective |
652 |
* function. |
653 |
*/ |
654 |
extern void rel_set_multiplier(struct rel_relation *rel, real64 multiplier); |
655 |
/**< |
656 |
* (<!-- won a temporary reprieve. this should be a system property, not rel.) --> |
657 |
* Sets the multiplier field of the given relation. |
658 |
* This is expected to be computed as a lagrange multiplier which will |
659 |
* relate the gradient of the relation rel with that of some objective |
660 |
* function. |
661 |
*/ |
662 |
|
663 |
/* |
664 |
* rel_relation utility functions. |
665 |
* |
666 |
* Things for the server side only. Not visible to clients. |
667 |
* |
668 |
* Ok, really nosy clients courting death can cheat. Don't cry when |
669 |
* they break. |
670 |
* We make absolutely no commitment to being compatible with this portion |
671 |
* of the header at any time in the future. |
672 |
*/ |
673 |
#ifdef _SLV_SERVER_C_SEEN_ |
674 |
/* |
675 |
* requires #include "expr.h" |
676 |
* requires #include "types.h" |
677 |
* requires #include "extfunc.h" |
678 |
* requires #include "relation.h" |
679 |
* requires #include "packages.h" |
680 |
* requires #include "extcall.h" |
681 |
* requires #include "mtx.h" |
682 |
*/ |
683 |
|
684 |
extern double g_external_tolerance; /**< DEFAULT 1e-12 */ |
685 |
|
686 |
struct ExtRelCache { |
687 |
int32 nodestamp; |
688 |
struct ExternalFunc *efunc; /**< pre_slv, eval and deriv funcs */ |
689 |
SlvBackendToken data; /**< only passed on pre_slv */ |
690 |
struct gl_list_t *arglist; /**< only passed on pre_slv */ |
691 |
struct gl_list_t *inputlist; |
692 |
void *user_data; /**< user data */ |
693 |
int32 ninputs, noutputs; |
694 |
double *inputs; |
695 |
double *outputs; |
696 |
double *jacobian; |
697 |
unsigned newcalc_done :1; /**< bits needed to control */ |
698 |
unsigned first_func_eval :1; /**< recalculation. until we can */ |
699 |
unsigned first_deriv_eval :1; /**< do proper block coding */ |
700 |
}; |
701 |
|
702 |
extern struct ExtRelCache *rel_extcache(struct rel_relation *rel); |
703 |
/**< |
704 |
* Retrieve external relation information. |
705 |
* This applies ONLY to rels that have external nodes ! |
706 |
* Ensure this by calling rel_extnodeinfo FIRST ! |
707 |
* This is the gateway to the external relation information |
708 |
* stashed away to make processing of external relations efficient. |
709 |
* See the file extrel.[ch] for functions to deal with the external |
710 |
* relations cache, unless of course you are a client in which CASE |
711 |
* don't. |
712 |
*/ |
713 |
extern void rel_set_extcache(struct rel_relation *rel, struct ExtRelCache *cache); |
714 |
/**< |
715 |
* cache = rel_extcache(rel); |
716 |
* rel_set_extcache(rel,cache); |
717 |
* struct rel_relation *rel; |
718 |
* struct ExtRelCache *cache; |
719 |
* |
720 |
* Set external relation information. |
721 |
* This applies ONLY to rels that have external nodes ! |
722 |
* Ensure this by calling rel_extnodeinfo FIRST ! |
723 |
* This is the gateway to the external relation information |
724 |
* stashed away to make processing of external relations efficient. |
725 |
* See the file extrel.[ch] for functions to deal with the external |
726 |
* relations cache, unless of course you are a client in which CASE |
727 |
* don't. |
728 |
*/ |
729 |
|
730 |
/* |
731 |
* The following aren't commented because Kirk Abbott didn't comment them. |
732 |
* It's all server magic anyway? |
733 |
*/ |
734 |
|
735 |
extern struct ExtRelCache *CreateExtRelCache(struct ExtCallNode *ext); |
736 |
struct ExtRelCache *CreateCacheFromInstance(SlvBackendToken relinst); |
737 |
extern void ExtRel_DestroyCache(struct ExtRelCache *cache); |
738 |
extern int32 ExtRel_PreSolve(struct ExtRelCache *cache, int32 setup); |
739 |
extern real64 ExtRel_Evaluate_RHS(struct rel_relation *rel); |
740 |
extern real64 ExtRel_Evaluate_LHS(struct rel_relation *rel); |
741 |
extern real64 ExtRel_Diffs_RHS(struct rel_relation *rel, |
742 |
var_filter_t *filter, |
743 |
int32 row, |
744 |
mtx_matrix_t matrix); |
745 |
extern real64 ExtRel_Diffs_LHS(struct rel_relation *rel, |
746 |
var_filter_t *filter, |
747 |
int32 row, |
748 |
mtx_matrix_t matrix); /**< not implemented */ |
749 |
|
750 |
#endif /* _SLV_SERVER_C_SEEN_ */ |
751 |
|
752 |
/* |
753 |
* Things dead. |
754 |
*/ |
755 |
/* DEFUNCT |
756 |
* extern struct rel_relation *rel_objcreate(SlvBackendToken, boolean); |
757 |
* rel = rel_objcreate(instance,negate) |
758 |
* struct rel_relation *rel; |
759 |
* boolean negate; |
760 |
* SlvBackendToken instance; |
761 |
* |
762 |
* Creates an objective relation given the relation instance. |
763 |
* The other fields are given default values. The lhs will be NULL. |
764 |
* objrels may not have extrel caches. Use a dummy relation if |
765 |
* necessary. Negate must be TRUE for a maximize relation, FALSE for |
766 |
* a minimize relation. |
767 |
*/ |
768 |
|
769 |
/* DEFUNCT |
770 |
* If you're smart enough to understand the answer to this question, |
771 |
* then you should be asking the instance directly, not asking us. |
772 |
* extern enum rel_enum rel_type(struct rel_relation *); |
773 |
* rtype = rel_type(rel); |
774 |
* rel_enum rtype; |
775 |
* struct rel_relation *rel; |
776 |
* Returns the type of a given relation. This indicates whether the |
777 |
* the relation is a token, opcode, glassbox, or blackbox relation. |
778 |
*/ |
779 |
|
780 |
/* DEFUNCT for now. |
781 |
* extern boolean rel_in_subregion(struct rel_relation *); |
782 |
* in_subregion = rel_in_subregion(rel) |
783 |
* boolean in_subregion; |
784 |
* struct rel_relation *rel; |
785 |
* |
786 |
* Computes if the conditions of the relation are all met by the |
787 |
* current values of the subregion field of each relevant boundary. |
788 |
* It will return TRUE even if there are no conditions. |
789 |
*/ |
790 |
|
791 |
/* DEFUNCT the solver has no business knowing about sides. this is the |
792 |
* compilers job. temporarily still active. |
793 |
* extern expr_t rel_lhs(struct rel_relation *); |
794 |
* extern expr_t rel_rhs(struct rel_relation *); |
795 |
* lhs = rel_lhs(rel) |
796 |
* rhs = rel_rhs(rel) |
797 |
* expr_t lhs,rhs; |
798 |
* struct rel_relation *rel; |
799 |
* |
800 |
* Fetches the (internal copy of the) rhs and lhs of the relation. |
801 |
* The user should not modify the expression, nor should the user |
802 |
* use the expression after the relation is destroyed or the |
803 |
* lhs/rhs has been re-set. |
804 |
*/ |
805 |
|
806 |
#endif /* ASC_REL_H */ |
807 |
|