1 |
/* |
2 |
* Relation Data Type |
3 |
* by Tom Epperly |
4 |
* Created: 1/18/90 |
5 |
* Version: $Revision: 1.12 $ |
6 |
* Version control file: $RCSfile: relation_type.h,v $ |
7 |
* Date last modified: $Date: 1998/01/06 12:05:31 $ |
8 |
* Last modified by: $Author: ballan $ |
9 |
* |
10 |
* This file is part of the Ascend Language Interpreter. |
11 |
* |
12 |
* Copyright (C) 1990, 1993, 1994 Thomas Guthrie Epperly |
13 |
* |
14 |
* The Ascend Language Interpreter is free software; you can redistribute |
15 |
* it and/or modify it under the terms of the GNU General Public License as |
16 |
* published by the Free Software Foundation; either version 2 of the |
17 |
* License, or (at your option) any later version. |
18 |
* |
19 |
* The Ascend Language Interpreter is distributed in hope that it will be |
20 |
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of |
21 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
22 |
* General Public License for more details. |
23 |
* |
24 |
* You should have received a copy of the GNU General Public License along |
25 |
* with the program; if not, write to the Free Software Foundation, Inc., 675 |
26 |
* Mass Ave, Cambridge, MA 02139 USA. Check the file named COPYING. |
27 |
*/ |
28 |
|
29 |
/** @file |
30 |
* Relation Data Type. |
31 |
* <pre> |
32 |
* When #including relation_type.h, make sure these files are #included first: |
33 |
* #include "utilities/ascConfig.h" |
34 |
* #include "fractions.h" |
35 |
* #include "compiler.h" |
36 |
* #include "dimen.h" |
37 |
* #include "types.h" |
38 |
* #include "list.h" |
39 |
* #include "func.h" |
40 |
* #include "extfunc.h" |
41 |
* #include "extcall.h" |
42 |
* </pre> |
43 |
*/ |
44 |
|
45 |
#ifndef ASC_RELATION_TYPE_H |
46 |
#define ASC_RELATION_TYPE_H |
47 |
|
48 |
/** If TOKENDOMINANT is 1, then we assume union RelationUnion fields |
49 |
* other than relop and ref_count are all going to be initialized |
50 |
* to 0/NULL if we do the initializations for the token unions. |
51 |
* If it is 0, we do a memset (bytewise initialization) which |
52 |
* is slower. |
53 |
*/ |
54 |
#define TOKENDOMINANT 1 |
55 |
|
56 |
/* |
57 |
* The following relation term types should only be accessed through the |
58 |
* operators in relation.h. |
59 |
*/ |
60 |
|
61 |
/** constants invariant with loop index */ |
62 |
struct RelationReal{ |
63 |
/* this is the dominant size term */ |
64 |
enum Expr_enum t; /**< type of term */ |
65 |
CONST dim_type *dimensions; |
66 |
double value; |
67 |
}; |
68 |
|
69 |
struct RelationInteger { |
70 |
enum Expr_enum t; /**< type of term */ |
71 |
long ivalue; |
72 |
}; |
73 |
|
74 |
/* constants varying with loop index, coming soon to a compiler near you. */ |
75 |
/* The purpose of these is to allow isomorphic relations, up to the values |
76 |
* of the constant coefficients, to share a single token string. This can |
77 |
* only be accomplished in a second visitation of relation arrays after the |
78 |
* relations of the array in question have been created and simplified. |
79 |
*/ |
80 |
struct RelationRealConst{ |
81 |
enum Expr_enum t; /**< type of term */ |
82 |
CONST dim_type *dimensions; |
83 |
int cnum; /**< index in constant array, from 0 */ |
84 |
}; |
85 |
|
86 |
struct RelationIntegerConst { |
87 |
enum Expr_enum t; /**< type of term */ |
88 |
int cnum; /**< index in constant array, from 0 */ |
89 |
}; |
90 |
|
91 |
/** real variables */ |
92 |
struct RelationVar { |
93 |
enum Expr_enum t; /**< type of term */ |
94 |
unsigned int flags; /**< flags for future use */ |
95 |
unsigned long varnum; /**< index in variable gl_list, from 1 */ |
96 |
}; |
97 |
|
98 |
/** operators */ |
99 |
struct RelationFunc { |
100 |
enum Expr_enum t; /**< type of term */ |
101 |
unsigned int flags; /**< flags for future use */ |
102 |
CONST struct Func *fptr; |
103 |
struct relation_term *left; |
104 |
}; |
105 |
|
106 |
/** unary minus */ |
107 |
struct RelationUnary { |
108 |
enum Expr_enum t; /**< type of term */ |
109 |
unsigned int flags; /**< flags for future use */ |
110 |
struct relation_term *left; |
111 |
}; |
112 |
|
113 |
/** binary, plus,minus,divide,times,power */ |
114 |
struct RelationBinary { |
115 |
enum Expr_enum t; /**< type of term */ |
116 |
unsigned int flags; /**< flags for future use */ |
117 |
struct relation_term *left; |
118 |
struct relation_term *right; |
119 |
}; |
120 |
|
121 |
/** future existence */ |
122 |
struct RelationNary { |
123 |
enum Expr_enum t; /**< type of term */ |
124 |
unsigned int flags; /**< flags for future use */ |
125 |
CONST struct Func *fptr; |
126 |
struct gl_list_t *args; |
127 |
}; |
128 |
|
129 |
/** New token type designed just as struct Instance */ |
130 |
struct relation_term { |
131 |
enum Expr_enum t; /**< type of term */ |
132 |
unsigned int flags; /**< flags for future use. only valid for operator and var terms */ |
133 |
}; |
134 |
|
135 |
/** |
136 |
* A union type for sizeof folks and other nosy sorts. |
137 |
* The size should be 16 bytes on 4byte ptr machines and 24 on |
138 |
* fat pointer machines. |
139 |
* Not really intended for actual use except in sizeof and array declarations. |
140 |
* All members of this union are able to align on N byte boundaries |
141 |
* where N is sizeof(union RelationTermUnion) for the machine in question. |
142 |
* Do not try to pack the union subtypes into an array like atom children. |
143 |
*/ |
144 |
union RelationTermUnion { |
145 |
struct relation_term anon; /**< anonymous relation term type */ |
146 |
struct RelationInteger i; /**< integer value */ |
147 |
struct RelationReal r; /**< real value */ |
148 |
struct RelationIntegerConst ic; /**< integer value */ |
149 |
struct RelationRealConst rc; /**< real value */ |
150 |
struct RelationVar var; /**< vars */ |
151 |
struct RelationFunc func; /**< funcs */ |
152 |
struct RelationUnary uni; /**< standard unary function */ |
153 |
struct RelationBinary bin; /**< standard binary functions */ |
154 |
struct RelationNary n; /**< numeric functions with a list argument */ |
155 |
}; |
156 |
|
157 |
/* |
158 |
* The different types of relation structures that need to |
159 |
* be supported by the relation module. |
160 |
*/ |
161 |
|
162 |
/** Each RelationUnion element should start with these two entries |
163 |
* so we can ask a the RelationUnion its relop, rather than storing |
164 |
* the information redundantly in every struct relation refering |
165 |
* to the shared info. |
166 |
* Keep TokenRelation, OpCodeRelation, GlassBoxRelation, BlackBoxRelation |
167 |
* matched to this. And see the definition of TOKENDOMINANT above |
168 |
* if these structs are changed. |
169 |
*/ |
170 |
struct SharedRelation { |
171 |
enum Expr_enum relop; /**< relation kind etc */ |
172 |
REFCOUNT_T ref_count; /**< number of instances looking here */ |
173 |
}; |
174 |
|
175 |
/** TokenRelations: |
176 |
* Under NO CIRCUMSTANCES should you attempt to free any element |
177 |
* of the infix trees. They share memory with the postfix arrays. |
178 |
* Also you should not dereference the pointers in a relation |
179 |
* except by appropriate operators from the header. |
180 |
*/ |
181 |
struct TokenRelation { |
182 |
enum Expr_enum relop; /**< type of relation */ |
183 |
REFCOUNT_T ref_count; /**< number of instances looking here */ |
184 |
unsigned long lhs_len, rhs_len; |
185 |
union RelationTermUnion *lhs, *rhs; /**< postfix arrays */ |
186 |
struct relation_term *lhs_term, *rhs_term; /**< infix trees */ |
187 |
unsigned btable, bindex; /**< indices to table and entry of machine code */ |
188 |
}; |
189 |
|
190 |
/** Unimplemented OpCodes */ |
191 |
struct OpCodeRelation { |
192 |
enum Expr_enum relop; /**< type of constraint */ |
193 |
REFCOUNT_T ref_count; /**< number of instances looking here */ |
194 |
int *lhs, *rhs; /**< array of opcodes */ |
195 |
int *args; |
196 |
int nargs; |
197 |
double *constants; /**< array of reals */ |
198 |
}; |
199 |
|
200 |
struct GlassBoxRelation { |
201 |
enum Expr_enum relop; /**< type of constraint */ |
202 |
REFCOUNT_T ref_count; /**< number of instances looking here */ |
203 |
struct ExternalFunc *efunc; |
204 |
int *args; /**< an array of indexes into the varlist */ |
205 |
int nargs; |
206 |
int index; /**< the *external* index of this relation */ |
207 |
}; |
208 |
|
209 |
struct BlackBoxRelation { |
210 |
enum Expr_enum relop; /**< type of constraint */ |
211 |
REFCOUNT_T ref_count; /**< number of instances looking here */ |
212 |
struct ExtCallNode *ext; /**< external call info */ |
213 |
int *args; /**< an array of indexes into the varlist */ |
214 |
int nargs; |
215 |
}; |
216 |
|
217 |
union RelationUnion { |
218 |
struct SharedRelation s; |
219 |
struct TokenRelation token; |
220 |
struct OpCodeRelation opcode; |
221 |
struct GlassBoxRelation gbox; |
222 |
struct BlackBoxRelation bbox; |
223 |
}; |
224 |
|
225 |
/** a union type for double and long constants. */ |
226 |
union doublong { |
227 |
double dval; |
228 |
long lval; |
229 |
}; |
230 |
|
231 |
/** |
232 |
* Most of the attributes in this structure are instance |
233 |
* attributes that cannot be shared among relation instances, |
234 |
* not attributes of the relation recipe for calculating them. |
235 |
* The calculation recipe, 'share' is sharable among all relations with |
236 |
* identical symbolic form; roughly 80+% of relations |
237 |
* in physical models are duplicates in differing contexts. |
238 |
* That part (calculation recipe) which is instance independent |
239 |
* is stored in the union 'share'. <br><br> |
240 |
* |
241 |
* Share contains information mapping from the index in *vars |
242 |
* to value slots in the calculation. Each RelationInstance |
243 |
* has its own struct relation and vars gl_list-- if the |
244 |
* vars list is changed for one of the instances sharing |
245 |
* a the RelationUnion, then a new share structure must |
246 |
* be created for that instance. If this is not done, |
247 |
* the other instances will miscalculate or core dump. |
248 |
* Usually just miscalculates in silence.<br><br> |
249 |
* |
250 |
* To compile really large models, these must be memory |
251 |
* pooled and properly aligned. |
252 |
*/ |
253 |
struct relation { |
254 |
union RelationUnion *share; /**< should never be NULL but at creation */ |
255 |
double residual; |
256 |
double multiplier; |
257 |
double nominal; |
258 |
int iscond; |
259 |
struct gl_list_t *vars; /**< list starting from 1 of RealAtomInst ptrs */ |
260 |
/* coming soon. |
261 |
* union doublong *constants; loop variant constants. maybe NULL. |
262 |
*/ |
263 |
dim_type *d; |
264 |
}; |
265 |
|
266 |
/* casts to fix things up, should they really be needed. */ |
267 |
#define A_TERM(i) ((struct relation_term *)(i)) |
268 |
/* anonymous term */ |
269 |
#define R_TERM(i) ((struct RelationReal *)(i)) |
270 |
#define I_TERM(i) ((struct RelationInteger *)(i)) |
271 |
#define RC_TERM(i) ((struct RelationRealConst *)(i)) |
272 |
#define IC_TERM(i) ((struct RelationIntegerConst *)(i)) |
273 |
#define V_TERM(i) ((struct RelationVar *)(i)) |
274 |
#define L_TERM(i) ((struct RelationLogical *)(i)) |
275 |
#define F_TERM(i) ((struct RelationFunc *)(i)) |
276 |
#define B_TERM(i) ((struct RelationBinary *)(i)) |
277 |
#define U_TERM(i) ((struct RelationUnary *)(i)) |
278 |
#define N_TERM(i) ((struct RelationNary *)(i)) |
279 |
#define UNION_TERM(i) ((union RelationTermUnion *)(i)) |
280 |
|
281 |
/** |
282 |
* The following define is for people who expect each term |
283 |
* allocated to be individually deallocated and interchangable |
284 |
* to all types of term. It returns a struct relation_term *. |
285 |
* Cast as needed if you must. |
286 |
* Use of individually allocated terms is a really bad idea! |
287 |
*/ |
288 |
#define TERM_ALLOC A_TERM(ascmalloc(sizeof(union RelationTermUnion))) |
289 |
|
290 |
#endif /* ASC_RELATION_TYPE_H */ |
291 |
|