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