/[ascend]/trunk/ascend/compiler/link.c
ViewVC logotype

Annotation of /trunk/ascend/compiler/link.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2565 - (hide annotations) (download) (as text)
Fri Feb 3 23:25:40 2012 UTC (10 years, 6 months ago) by jpye
File MIME type: text/x-csrc
File size: 26679 byte(s)
cleanup
1 jpye 2559 /* ASCEND modelling environment
2     Copyright (C) 1990, 1993, 1994 Thomas Guthrie Epperly
3     Copyright (C) 2006 Carnegie Mellon University
4    
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2, or (at your option)
8     any later version.
9    
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13     GNU General Public License for more details.
14    
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 59 Temple Place - Suite 330,
18     Boston, MA 02111-1307, USA.
19     *//**
20     @file
21     Link Routines.
22    
23     *//*
24     by Dante Stroe
25     Created: 07/07/2009
26     */
27    
28    
29    
30     #include "link.h"
31     #include <stdarg.h>
32     #include <ascend/general/list.h>
33     #include <ascend/general/ascMalloc.h>
34     #include <ascend/general/panic.h>
35     #include <ascend/utilities/error.h>
36    
37     #include "cmpfunc.h"
38     #include "find.h"
39     #include "forvars.h"
40     #include "instance_types.h"
41     #include "instance_enum.h"
42     #include "instmacro.h"
43     #include "instquery.h"
44     #include "statement.h"
45     #include "stattypes.h"
46     #include "stdio.h"
47     #include "symtab.h"
48     #include "visitinst.h"
49     #include "vlist.h"
50     #include "name.h"
51     #include "instance_io.h"
52    
53    
54    
55     /**< DS: beginning of LINK functions *******/
56     /* implemented functions related to the LINK statements, probably they shouldn't be here*/
57    
58     /**
59     Find instances: Make sure at least one thing is found for each name item
60     on list (else returned list will be NULL) and return the collected instances.
61     DS: it returns a non-flattened list of the instances
62     */
63 jpye 2565 static struct gl_list_t *FindInstsNonFlat(
64     struct Instance *inst,CONST struct VariableList *list,enum find_errors *err
65     ){
66 jpye 2559 struct gl_list_t *result,*temp;
67    
68     result = gl_create(AVG_LINKS_INST);
69     while(list!=NULL){
70     temp = FindInstances(inst,NamePointer(list),err);
71     if (temp==NULL){
72     gl_destroy(result);
73     return NULL;
74     }
75     gl_append_ptr(result,temp);
76     list = NextVariableNode(list);
77     }
78     return result;
79     }
80    
81     /**
82     Find instances: Make sure at least one thing is found for each name item
83     on list (else returned list will be NULL) and return the collected instances.
84     DS: it returns a flattened list of the instances
85     */
86 jpye 2565 static struct gl_list_t *FindInsts(
87     struct Instance *inst, CONST struct VariableList *list, enum find_errors *err
88     ){
89 jpye 2559 struct gl_list_t *result,*temp;
90     unsigned c,len;
91     result = gl_create(AVG_LINKS_INST);
92     while(list!=NULL){
93     temp = FindInstances(inst,NamePointer(list),err);
94     if (temp==NULL){
95     gl_destroy(result);
96     return NULL;
97     }
98     len = gl_length(temp);
99     for(c=1;c<=len;c++) {
100     gl_append_ptr(result,gl_fetch(temp,c));
101     }
102     gl_destroy(temp);
103     list = NextVariableNode(list);
104     }
105     return result;
106     }
107    
108    
109     /**
110 jpye 2565 DS: Helper function that compares a key and a list of instances with a link_entry
111     @return 0 if the tuple (key, instances) is the same as the link entry,
112     otherwise return 1.
113 jpye 2559 */
114 jpye 2565 static int CmpLinkEntry(symchar *key, struct VariableList *vlist,struct link_entry_t *linkEntry){
115     /* DS: Note: the key_cache and the u.vl were used instead of
116     LINKStatKey(linkEntry->u.statptr) and LINKStatVlist(linkEntry->u.statptr),
117     because for some reason the pointer to the statement becomes NULL after the
118     statement is executed */
119 jpye 2559
120     struct VariableList *linkEntry_vlist;
121    
122 jpye 2565 if(CmpSymchar(key,linkEntry->key_cache) != 0) {
123     /* if the keys are different, the LINKs are different */
124 jpye 2559 return 1;
125     }
126    
127     linkEntry_vlist = linkEntry->u.vl;
128 jpye 2565 if(VariableListLength(vlist) != VariableListLength(linkEntry_vlist)) {
129     /* if the number of variables linked are different, the LINKs are different */
130 jpye 2559 return 1;
131     }
132    
133     if(CompareVariableLists(vlist,linkEntry_vlist) != 0) { /* if the variables linked are different, the LINKs are different */
134 jpye 2565 return 1; /* DS Note: it is ordered biased */
135 jpye 2559 }
136    
137 jpye 2565 return 0; /* (key, instances) is the same as linkEntry */
138 jpye 2559 }
139    
140    
141     void CollectLinkTypes(struct Instance *model, struct gl_list_t *result)
142     {
143     struct TypeDescription *modelType;
144     struct link_entry_t *link_entry;
145 jpye 2565 symchar *key, *key_result;
146 jpye 2559 int c1, c2, len_table, len_result, existent;
147    
148     modelType = InstanceTypeDesc(model);
149     if(modelType->t == model_type) {
150 jpye 2565
151     /* probe instance given (if appropriate kind) to get link info needed
152     from the TypeDescription link_table */
153 jpye 2559 len_table = gl_length(modelType->u.modarg.link_table);
154    
155     for(c1=1;c1<=len_table;c1++){
156     link_entry = (struct link_entry_t *)gl_fetch(modelType->u.modarg.link_table,c1);
157     if(link_entry->key_cache == NULL){ /**< in case the cache is empty we need to find keys from the statements */
158     key = LINKStatKey(link_entry->u.statptr);
159 jpye 2565 }else{
160 jpye 2559 key = link_entry->key_cache;
161     }
162     // verify that any new info obtained is kept uniquely in the result list.(not efficient at all DS TODO)
163     len_result = gl_length(result);
164     existent = 0;
165     for(c2=1;c2<=len_result;c2++){
166     key_result = (symchar *)gl_fetch(result,c2);
167     if(CmpSymchar(key,key_result) == 0){
168     existent = 1;
169     }
170     }
171     if(!existent){
172     gl_append_ptr(result,(VOIDPTR)key);
173     }
174     }
175    
176 jpye 2565 /* probe instance given (if appropriate kind) to get link info needed
177     from the ModelInstances link_table */
178 jpye 2559 len_table = gl_length(MOD_INST(model)->link_table);
179     for(c1=1;c1<=len_table;c1++){
180     link_entry = (struct link_entry_t *)gl_fetch(MOD_INST(model)->link_table,c1);
181     if(link_entry->key_cache == NULL){ /**< in case the cache is empty we need to find keys from the statements */
182     key = LINKStatKey(link_entry->u.statptr);
183 jpye 2565 }else{
184 jpye 2559 key = link_entry->key_cache;
185     }
186 jpye 2565 /* verify that any new info obtained is kept uniquely in the result
187     list.(not efficient at all DS TODO) */
188 jpye 2559 len_result = gl_length(result);
189     existent = 0;
190     for(c2=1;c2<=len_result;c2++){
191     key_result = (symchar *)gl_fetch(result,c2);
192     if(CmpSymchar(key,key_result) == 0){
193     existent = 1;
194     }
195     }
196     if(!existent){
197     gl_append_ptr(result,(VOIDPTR)key);
198     }
199     }
200     }
201 jpye 2565 /*DS:If the instance or the child instance is not a model we do nothing
202     since a "link_table" is only present in the typedescription of a model (modarg) */
203 jpye 2559 }
204    
205    
206     /** find all the keys in link table(s), optionally recursive. */
207 jpye 2565 extern struct gl_list_t *getLinkTypes (struct Instance *model, int recursive){
208 jpye 2559 struct gl_list_t *result = gl_create(AVG_LINKS);
209    
210     if (recursive) {
211 jpye 2565 VisitInstanceTreeTwo(model, (VisitTwoProc)CollectLinkTypes, 0,0, result);
212     }else{
213     CollectLinkTypes(model, result);
214     }
215     return result;
216 jpye 2559 }
217    
218    
219 jpye 2565 void CollectLinks(struct Instance *model, struct gl_list_t *result){
220 jpye 2559 struct TypeDescription *modelType;
221     struct link_entry_t *link_entry, *link_entry_result;
222     int c1, c2, len_table, len_result, existent;
223    
224     modelType = InstanceTypeDesc(model);
225     if(modelType->t == model_type) {
226 jpye 2565
227     /* probe instance given (if appropriate kind) to get link info needed
228     from the TypeDescription link_table */
229 jpye 2559 len_table = gl_length(modelType->u.modarg.link_table);
230     for(c1=1;c1<=len_table;c1++){
231     link_entry = (struct link_entry_t *)gl_fetch(modelType->u.modarg.link_table,c1);
232     // verify if the LINK is unique in the result list
233     len_result = gl_length(result);
234     existent = 0;
235    
236     for(c2=1;c2<=len_result;c2++){
237     link_entry_result = (struct link_entry_t *)gl_fetch(result,c2);
238     if(CmpLinkEntry(link_entry->key_cache,link_entry->u.vl,link_entry_result) == 0){
239     existent = 1;
240     }
241     }
242     if(!existent){
243 jpye 2565 gl_append_ptr(result,(VOIDPTR)link_entry);
244 jpye 2559 }
245     }
246    
247 jpye 2565 /* probe instance given (if appropriate kind) to get link info needed
248     from the ModelInstance link_table */
249 jpye 2559 len_table = gl_length(MOD_INST(model)->link_table);
250     for(c1=1;c1<=len_table;c1++){
251     link_entry = (struct link_entry_t *)gl_fetch(MOD_INST(model)->link_table,c1);
252     existent = 0;
253     // verify if the LINK is unique in the result list
254     len_result = gl_length(result);
255    
256     for(c2=1;c2<=len_result;c2++){
257     link_entry_result = (struct link_entry_t *)gl_fetch(result,c2);
258     if(CmpLinkEntry(link_entry->key_cache,link_entry->u.vl,link_entry_result) == 0){
259     existent = 1;
260     }
261     }
262     if(!existent){
263 jpye 2565 gl_append_ptr(result,(VOIDPTR)link_entry);
264 jpye 2559 }
265     }
266     }
267 jpye 2565 /*DS:If the instance or the child instance is not a model we do nothing since
268     a "link_table" is only present in the typedescription of a model (modarg) */
269 jpye 2559 }
270    
271    
272 jpye 2565 extern struct gl_list_t *getLinks(struct Instance *model
273     , symchar *target_key, int recursive
274     ){
275 jpye 2559 struct gl_list_t *result = gl_create(AVG_LINKS); /**< DS: hardcoded for now but will eventually be a constant */
276     int c1, len_result;
277     struct link_entry_t *link_entry;
278 jpye 2565
279     if(recursive){
280     VisitInstanceTreeTwo(model, (VisitTwoProc)CollectLinks, 0,0, result);
281     }else{
282     CollectLinks(model, result);
283     }
284 jpye 2559
285     len_result = gl_length(result);
286    
287     for(c1=1;c1<=len_result;c1++) {
288     link_entry = (struct link_entry_t *)gl_fetch(result,c1);
289     if(CmpSymchar(link_entry->key_cache,target_key) !=0 ){
290     gl_delete(result,c1,0); /* if the link entry does not have sought key we delete it from the result list */
291     len_result--;
292     }
293     }
294 jpye 2565 return result;
295 jpye 2559 }
296    
297    
298     /**<DS: get all links matching key, optionally recursive. */
299 jpye 2565 extern struct gl_list_t *getLinksReferencing (struct Instance *model
300     , symchar* key, struct Instance *targetInstance, int recursive
301     ){
302 jpye 2559 struct gl_list_t *link_instances,*result = gl_create(AVG_LINKS);
303     struct link_entry_t *link_entry;
304     struct Instance *inst;
305 jpye 2565 enum find_errors err;
306 jpye 2559 int c1, c2, len_result, len_inst, containsInst;
307    
308 jpye 2565 if(recursive){
309     VisitInstanceTreeTwo(model, (VisitTwoProc)CollectLinks, 0,0, result);
310     }else{
311     CollectLinks(model, result);
312     }
313 jpye 2559
314     /* DS: get all the links that contain the target instance */
315     len_result = gl_length(result);
316 jpye 2565 for(c1=1;c1<=len_result;c1++){
317     link_entry = (struct link_entry_t *)gl_fetch(result,c1);
318 jpye 2559 if(link_entry->instances_cache == NULL ) {
319     link_instances = FindInsts(model,link_entry->u.vl,&err);
320 jpye 2565 }else{
321 jpye 2559 link_instances = link_entry->instances_cache;
322     }
323 jpye 2565
324 jpye 2559 len_inst = gl_length(link_instances);
325     containsInst = 0;
326     if(CmpSymchar(link_entry->key_cache,key) == 0){
327     for(c2=1;c2<=len_inst;c2++){
328     inst = (struct Instance *)gl_fetch(link_instances,c2);
329     if(inst == targetInstance){
330     containsInst = 1;
331     }
332 jpye 2565 }
333 jpye 2559 }
334     if(!containsInst){
335     gl_delete(result,c1,0); /* if the link entry does not have sought key we delete it from the result list */
336     len_result--;
337 jpye 2565 }
338 jpye 2559 }
339     return result;
340     }
341    
342 jpye 2565 /** DS: called by the ASCEND LINK command, both in the declarative and the non-declarative section */
343     extern void addLinkEntry(struct Instance *model, symchar *key
344     , struct gl_list_t *instances, struct Statement *stat, unsigned int declarative
345     ){
346 jpye 2559 struct TypeDescription *modelType;
347     struct link_entry_t *link_entry, *old_link_entry;
348 jpye 2565 struct for_var_t *ptr;
349 jpye 2559 int c,len,exist = 0;
350    
351     if(strcmp("TestingRoutine",SCP(key)) == 0) {
352     TestingRoutine(model);
353     return;
354     }
355    
356 jpye 2565 /* in case the LINK key is in fact the index of a for loop, the value of the
357     index at the current iteration is turned into a symchar and stored as a key*/
358 jpye 2559 if(GetEvaluationForTable() && (ptr = FindForVar((struct gl_list_t *)GetEvaluationForTable(),key)) != NULL) {
359     char index_key[10];
360     sprintf(index_key,"%ld",GetForInteger(ptr));
361     key = AddSymbol(index_key);
362     }
363    
364     if(declarative == 0) {
365     /* we first check if the LINK we are about to add isn't already present in the declartive LINK table */
366     len = gl_length(MOD_INST(model)->link_table);
367     for(c=1;c<=len;c++){
368     old_link_entry = (struct link_entry_t *)gl_fetch(MOD_INST(model)->link_table,c);
369     if(CmpLinkEntry(key,LINKStatVlist(stat),old_link_entry) == 0){
370     exist = 1;
371     }
372     }
373    
374     if(!exist){
375    
376     link_entry = (struct link_entry_t *)ascmalloc(sizeof(struct link_entry_t));
377     link_entry->key_cache = key;
378     link_entry->u.statptr = stat;
379     link_entry->link_type = stat->v.lnk.key_type;
380     link_entry->u.vl = LINKStatVlist(stat);
381     link_entry->instances_cache = instances;
382     link_entry->flags = 1;
383     link_entry->length = gl_length(instances);
384    
385     /**< DS: in case the link entry is non-declartive, it is appended to the linktable in the model instance */
386     gl_append_ptr(MOD_INST(model)->link_table,(VOIDPTR)link_entry);
387     printf("\n non-declarative LINK no of instances in cache: %ld \n", gl_length(link_entry->instances_cache));
388     printf("\n non-declarative LINK key %s \n", SCP(key));
389 jpye 2565 }else{
390 jpye 2559 ERROR_REPORTER_HERE(ASC_USER_WARNING,"The LINK entry to-be added is already present in the non-declarative LINK table.");
391     }
392 jpye 2565 }else{
393 jpye 2559 if(link_entry->link_type == link_ignore) {
394     ignoreDeclLinkEntry(model,key,LINKStatVlist(stat));
395 jpye 2565 }else {
396 jpye 2559 modelType = InstanceTypeDesc(model);
397     len = gl_length(modelType->u.modarg.link_table);
398    
399     for(c=1;c<=len;c++){
400 jpye 2565 old_link_entry = (struct link_entry_t *)gl_fetch(modelType->u.modarg.link_table,c);
401 jpye 2559 if(CmpLinkEntry(key,LINKStatVlist(stat),old_link_entry) == 0){
402     exist = 1;
403     }
404     }
405    
406     if(!exist){
407     link_entry = (struct link_entry_t *)ascmalloc(sizeof(struct link_entry_t));
408     link_entry->key_cache = key;
409     link_entry->u.statptr = stat;
410     link_entry->link_type = stat->v.lnk.key_type;
411     link_entry->u.vl = LINKStatVlist(stat);
412     link_entry->instances_cache = instances;
413     link_entry->flags = 1;
414     link_entry->length = gl_length(instances);
415    
416     /**< DS: in case the link entry is declarative, it is appeneded to the linktable in the model type description */
417     gl_append_ptr(modelType->u.modarg.link_table,(VOIDPTR)link_entry);
418    
419     /* DS: testing purposes: */
420     printf("\n declarative LINK no of instances in cache: %ld \n", gl_length(link_entry->instances_cache));
421     printf("\n declarative LINK key %s \n", SCP(key));
422 jpye 2565 }else{
423     ERROR_REPORTER_HERE(ASC_USER_WARNING,"The LINK entry to-be added is already present in the declarative LINK table.");
424 jpye 2559 }
425     }
426     }
427     }
428    
429 jpye 2565 extern void ignoreDeclLinkEntry(struct Instance *model
430     , symchar *key, struct VariableList *vlist
431     ){
432 jpye 2559 /*DS: used in case the 'ignore' key is used for a declarative link */
433     struct TypeDescription *modelType;
434     struct link_entry_t *link_entry;
435     modelType = InstanceTypeDesc(model);
436     int c, len, exist = 0;
437    
438     len = gl_length(modelType->u.modarg.link_table);
439     printf("\n declarative link_table size %d\n",len);
440     for(c=1;c<=len;c++){
441     link_entry = (struct link_entry_t *)gl_fetch(modelType->u.modarg.link_table,c);
442     if (CmpLinkEntry(key,vlist,link_entry) == 0) {
443     exist = 1;
444     printf("\n ignored LinkEntry from declarative link_table \n");
445     gl_delete(modelType->u.modarg.link_table,c,1);
446     len--;
447     }
448     }
449     len = gl_length(modelType->u.modarg.link_table);
450     printf("\n new declarative link_table size %d\n",len);
451    
452     if(!exist){
453     ERROR_REPORTER_HERE(ASC_USER_ERROR,"The LINK entry to-be ignored does not exist.");
454     }
455     }
456 jpye 2565
457     /**
458     DS: (current Implementation) check if the the non-declarative or declarative
459     link table contains any of the instances in the list under the given key, if
460     so remove them from the entries
461     */
462     extern void removeLinkEntry(struct Instance *model
463     , symchar *key, struct VariableList *vlist
464     ){
465 jpye 2559 /* used when called by the UNLINK command in the METHODS section by ASCEND */
466     struct link_entry_t *link_entry;
467 jpye 2565 struct for_var_t *ptr;
468 jpye 2559 int c, len, exist = 0;
469    
470    
471     printf("\n execute removeLinkEntry \n");
472    
473 jpye 2565 /* in case the LINK key is in fact the index of a for loop, the value of
474     the index at the current iteration is turned into a symchar and stored as a key*/
475 jpye 2559 if(GetEvaluationForTable() && (ptr = FindForVar((struct gl_list_t *)GetEvaluationForTable(),key)) != NULL) {
476     char index_key[10];
477     sprintf(index_key,"%ld",GetForInteger(ptr));
478     key = AddSymbol(index_key);
479     }
480    
481     len = gl_length(MOD_INST(model)->link_table);
482     printf("\n non-declarative link_table size %d\n",len);
483 jpye 2565 for(c=1;c<=len;c++){
484     link_entry = (struct link_entry_t *)gl_fetch(MOD_INST(model)->link_table,c);
485     if(CmpLinkEntry(key,vlist,link_entry) == 0) {
486 jpye 2559 exist = 1;
487     printf("\n removed LinkEntry from non-declarative link_table\n");
488     gl_delete(MOD_INST(model)->link_table,c,1); /* we also deallocate the memory allocated for the link_entry */
489     len--;
490     }
491     }
492    
493     len = gl_length(MOD_INST(model)->link_table);
494     printf("\n new non-declarative link_table size %d\n",len);
495    
496    
497     if(!exist){
498     ERROR_REPORTER_HERE(ASC_USER_ERROR,"The LINK entry to-be removed does not exist.");
499     }
500     }
501    
502    
503 jpye 2565 /** DS: (current Implementation) check if the the non-declarative link table contains any of the instances in the list under the given key, if so remove them from the entries */
504     extern void removeNonDeclarativeLinkEntry(struct Instance *model
505     , symchar *key, int recursive
506     ){
507 jpye 2559 struct gl_list_t *result=gl_create(AVG_LINKS);
508     struct link_entry_t *link_entry;
509     int c=1, len;
510    
511    
512     if (recursive) {
513 jpye 2565 VisitInstanceTreeTwo(model, (VisitTwoProc)CollectLinks, 0,0, result);
514     }else{
515     CollectLinks(model, result);
516     }
517 jpye 2559
518     printf("\n execute removeNonDeclarativeLinkEntry \n");
519     len = gl_length(MOD_INST(model)->link_table);
520     printf("\n non-declarative link_table size: %d\n",len);
521     while(len != 0 || c<=len) {
522     link_entry = (struct link_entry_t *)gl_fetch( MOD_INST(model)->link_table,c);
523    
524     if ((key == NULL || CmpSymchar(key,link_entry->key_cache) == 0) && isDeclarative(model,link_entry) == 0 ) { /*DS: if the key is NULL then remove all entries from the link_table */
525     printf("\n execute removed LinkEntry \n");
526     gl_delete(MOD_INST(model)->link_table,c,1);
527     len--;
528 jpye 2565 }else{
529 jpye 2559 c++;
530     }
531     }
532    
533     len = gl_length(MOD_INST(model)->link_table);
534     printf("\n non-declarative link_table size: %d\n",len);
535     }
536    
537    
538 jpye 2565 const struct gl_list_t *getLinkInstances(struct Instance *inst
539     , struct link_entry_t *link_entry,int status
540     ){
541 jpye 2559 struct gl_list_t *result = gl_create(AVG_LINKS_INST);
542 jpye 2565 enum find_errors err;
543 jpye 2559
544     result = FindInstsNonFlat(inst,link_entry->u.vl,&err);
545    
546     if (result==NULL) {
547 jpye 2565 switch(err){
548     case impossible_instance:
549 jpye 2559 ERROR_REPORTER_HERE(ASC_USER_ERROR,"LINK entry contains imposible instance name");
550 jpye 2565 default:
551 jpye 2559 ERROR_REPORTER_HERE(ASC_USER_ERROR,"incomplete instances in LINK entry");
552 jpye 2565 }
553     }
554     return result;
555 jpye 2559 }
556    
557    
558 jpye 2565 const struct gl_list_t *getLinkInstancesFlat(struct Instance *inst
559     , struct link_entry_t *link_entry,int status
560     ){
561 jpye 2559 struct gl_list_t *result = gl_create(AVG_LINKS_INST);
562 jpye 2565 enum find_errors err;
563 jpye 2559 if(link_entry->instances_cache == NULL) {
564     result = FindInsts(inst,link_entry->u.vl,&err);
565     if (result==NULL) {
566 jpye 2565 switch(err){
567     case impossible_instance:
568 jpye 2559 ERROR_REPORTER_HERE(ASC_USER_ERROR,"LINK entry contains impossible instance name");
569 jpye 2565 default:
570 jpye 2559 ERROR_REPORTER_HERE(ASC_USER_ERROR,"incomplete instances in LINK entry");
571 jpye 2565 /* statement is not ready to be executed */
572     }
573     }
574     return result;
575     }else{
576 jpye 2559 result = link_entry->instances_cache;
577     }
578 jpye 2565 return result;
579 jpye 2559 }
580    
581    
582 jpye 2565 /** DS: get the list (link_table) with all the declarative link entries located in the TypeDescription */
583     extern struct gl_list_t *getLinkTableDeclarative(struct Instance *model){
584 jpye 2559 struct TypeDescription *modelType;
585     modelType = InstanceTypeDesc(model);
586    
587     if(modelType->t == model_type) {
588     return modelType->u.modarg.link_table;
589 jpye 2565 }else{
590 jpye 2559 return NULL;
591     ERROR_REPORTER_HERE(ASC_USER_WARNING,"the getLinkTableDeclarative procedure is called by a non-model instance");
592     }
593     }
594    
595    
596 jpye 2565 /** DS: get the list (link_table) with all the non-declarative link entries located in the ModelInstance */
597     extern struct gl_list_t *getLinkTableProcedural(struct Instance *model){
598 jpye 2559 struct TypeDescription *modelType;
599     modelType = InstanceTypeDesc(model);
600     if(modelType->t == model_type) {
601     return MOD_INST(model)->link_table;
602 jpye 2565 }else{
603 jpye 2559 return NULL;
604     ERROR_REPORTER_HERE(ASC_USER_WARNING,"the getLinkTableProcedural procedure is called by a non-model instance");
605     }
606     }
607    
608    
609 jpye 2565 extern int isDeclarative(struct Instance* model, struct link_entry_t *target_link_entry){
610 jpye 2559 struct TypeDescription *modelType;
611     struct link_entry_t *link_entry;
612     int c, len;
613    
614     /* DS: get all the links that contain the target instance from the declarative part (i.e. stored in the model TypeDescription) */
615     modelType = InstanceTypeDesc(model);
616     len = gl_length(modelType->u.modarg.link_table);
617    
618 jpye 2565 for(c=1;c<=len;c++){
619     link_entry = (struct link_entry_t *)gl_fetch(modelType->u.modarg.link_table,c);
620     if(CmpLinkEntry(target_link_entry->key_cache,target_link_entry->u.vl,link_entry) == 0) {
621     return 1;
622     }
623 jpye 2559 }
624     return 0;
625     }
626    
627    
628 jpye 2565 extern void clearLinkCache(struct Instance* model){
629 jpye 2559 struct gl_list_t* link_table;
630     struct link_entry_t *link_entry;
631     int c,len;
632    
633     link_table = getLinkTableDeclarative(model);
634     len = gl_length(link_table);
635     for(c=1;c<=len;c++) {
636     link_entry = gl_fetch(link_table,c);
637     link_entry->instances_cache = NULL;
638     }
639    
640     link_table = getLinkTableProcedural(model);
641     len = gl_length(link_table);
642     for(c=1;c<=len;c++) {
643     link_entry = gl_fetch(link_table,c);
644     link_entry->instances_cache = NULL;
645     }
646     }
647    
648 jpye 2565 extern void populateLinkCache(struct Instance* model){
649 jpye 2559 struct gl_list_t *link_table;
650     struct link_entry_t *link_entry;
651 jpye 2565 enum find_errors err;
652 jpye 2559 int c,len;
653    
654     link_table = getLinkTableDeclarative(model);
655     len = gl_length(link_table);
656     for(c=1;c<=len;c++) {
657     link_entry = gl_fetch(link_table,c);
658     link_entry->instances_cache = FindInsts(model,link_entry->u.vl,&err);
659 jpye 2565 if (link_entry->instances_cache==NULL) {
660     switch(err){
661     case impossible_instance:
662     ERROR_REPORTER_HERE(ASC_USER_ERROR,"LINK statement contains an impossible instance name (populateLinkCache)");
663     default:
664     ERROR_REPORTER_HERE(ASC_USER_ERROR,"Incomplete instances in LINK (populateLinkCache)");
665     }
666     }
667 jpye 2559 }
668    
669     link_table = getLinkTableProcedural(model);
670     len = gl_length(link_table);
671     for(c=1;c<=len;c++) {
672     link_entry = gl_fetch(link_table,c);
673     link_entry->instances_cache = FindInsts(model,link_entry->u.vl,&err);
674 jpye 2565 if (link_entry->instances_cache==NULL) {
675     switch(err){
676     case impossible_instance:
677     ERROR_REPORTER_HERE(ASC_USER_ERROR,"LINK statement contains an impossible instance name (populateLinkCache)");
678     default:
679     ERROR_REPORTER_HERE(ASC_USER_ERROR,"Incomplete instances in LINK (populateLinkCache)");
680     }
681     }
682 jpye 2559 }
683     }
684    
685    
686     extern int getOdeType(struct Instance *model ,struct Instance *inst){
687    
688     struct link_entry_t *link_entry;
689     struct gl_list_t *der_links,*independent_links;
690     symchar *der_key,*independent_key;
691     CONST struct VariableList *var;
692     int i,k,maxorder;
693    
694     der_key = AddSymbol("ode");
695     der_links = getLinks(model,der_key,0);
696    
697     for(i=1;i<=gl_length(der_links);i++) {
698     link_entry = (struct link_entry_t*) gl_fetch(der_links,i);
699     var = link_entry->u.vl;
700    
701     maxorder = link_entry->length;
702     k = 0;
703     while(var!=NULL){
704 jpye 2564 char *s = WriteInstanceNameString(inst,model);
705     int c = strcmp(SCP(SimpleNameIdPtr(NamePointer(var))),s);
706     ASC_FREE(s);
707     if(c == 0 ) {
708     gl_destroy(der_links);
709 jpye 2559 return maxorder - k;
710     }
711     k++;
712     var = NextVariableNode(var);
713     }
714     }
715    
716 jpye 2564 gl_destroy(der_links);
717 jpye 2559 independent_key = AddSymbol("independent");
718     independent_links = getLinks(model,independent_key,0);
719    
720     for(i=1;i<=gl_length(independent_links);i++) {
721     link_entry = (struct link_entry_t*) gl_fetch(independent_links,i);
722     var = link_entry->u.vl;
723    
724     k = 0;
725     while(var!=NULL){
726 jpye 2564 char *s = WriteInstanceNameString(inst,model);
727     int c = strcmp(SCP(SimpleNameIdPtr(NamePointer(var))),s);
728     ASC_FREE(s);
729     if(c == 0 ) {
730     gl_destroy(independent_links);
731 jpye 2559 return -1;
732     }
733     k++;
734     var = NextVariableNode(var);
735     }
736     }
737    
738 jpye 2564 gl_destroy(independent_links);
739 jpye 2559 return 0;
740     }
741    
742     extern int getOdeId(struct Instance *model,struct Instance *inst){
743     struct link_entry_t *link_entry;
744     struct gl_list_t *der_links;
745     symchar *der_key;
746     CONST struct VariableList *var;
747     int i;
748    
749     der_key = AddSymbol("ode");
750     der_links = getLinks(model,der_key,0);
751    
752     for(i=1;i<=gl_length(der_links);i++) {
753     CONSOLE_DEBUG("Inside for");
754     link_entry = (struct link_entry_t*) gl_fetch(der_links,i);
755     var = link_entry->u.vl;
756    
757     while(var!=NULL){
758 jpye 2564 char *s = WriteInstanceNameString(inst,model);
759     int c = strcmp(SCP(SimpleNameIdPtr(NamePointer(var))),s);
760     ASC_FREE(s);
761     if(c == 0){
762     gl_destroy(der_links);
763 jpye 2559 return i;
764     }
765     var = NextVariableNode(var);
766     }
767     }
768 jpye 2564 gl_destroy(der_links);
769 jpye 2559 return 0;
770     }
771    
772    
773     /**< DS: End of LINK functions *******/
774    
775     /* function that tests the LINK functions implemented - prints the output in the console */
776     void TestingRoutine(struct Instance *model)
777     {
778     struct TypeDescription *modelType;
779     modelType = InstanceTypeDesc(model);
780     int c1, len1, len2;
781    
782     /* test getLinkTypes */
783     struct gl_list_t *linkTypes;
784     symchar *keyc1;
785     linkTypes = getLinkTypes(model,0);
786     len1 = gl_length(linkTypes);
787     CONSOLE_DEBUG("\n number of unique link types: %d \n",len1);
788     CONSOLE_DEBUG("\n The unique link keys are: ");
789 jpye 2565 for(c1=1;c1<=len1;c1++){
790     keyc1= (symchar *)gl_fetch(linkTypes,c1);
791 jpye 2559 CONSOLE_DEBUG("%s ",SCP(keyc1));
792 jpye 2565 }
793 jpye 2559 CONSOLE_DEBUG("\n");
794    
795     /* test getLinks */
796     struct gl_list_t *links;
797     struct link_entry_t *lnk;
798     struct Instance *i1;
799     links = getLinks(model,keyc1,0);
800     len2 = gl_length(links);
801     CONSOLE_DEBUG("\n number of links with key %s is: %d \n",SCP(keyc1),len2);
802    
803     /* just a test for comparing two instances pointer-wise */
804     /*
805     struct Instance *i11,*i22;
806     struct link_entry_t *lnk1,lnk2;
807    
808     lnk1 = (struct link_entry_t *)gl_fetch(modelType->u.modarg.link_table,1);
809     lnk2 = (struct link_entry_t *)gl_fetch(MOD_INST(model)->link_table,1);
810     i11 = (struct Instance *)gl_fetch(lnk1->instances_cache,2);
811     i22 = (struct Instance *)gl_fetch(lnk2->instances_cache,1);
812     if(i11 == i22){
813     printf("\n are equal \n");
814     } */
815    
816     /* test getLinksReferencing */
817 jpye 2565 lnk = (struct link_entry_t *)gl_fetch(MOD_INST(model)->link_table,1);
818     /* take the first link from all the non-declarative and declarative LINK Tables, just for testing */
819 jpye 2559 populateLinkCache(model);
820     i1= (struct Instance *)gl_fetch(lnk->instances_cache,1);
821 jpye 2565 CONSOLE_DEBUG("\n number links referencing the first instance and key %s is %ld \n"
822     ,SCP(keyc1),gl_length(getLinksReferencing(model,keyc1,i1,0))
823     );
824 jpye 2559
825     /* test getLinkInstances */
826    
827     /* test getLinkInstancesFlat */
828    
829     /* test isDeclarative */
830     modelType = InstanceTypeDesc(model);
831 jpye 2565 CONSOLE_DEBUG("\n the link should be declarative %d\n"
832     ,isDeclarative(model,(struct link_entry_t *)gl_fetch(modelType->u.modarg.link_table,1))
833     );
834     CONSOLE_DEBUG("\n the link should be non-declarative %d\n"
835     ,isDeclarative(model,(struct link_entry_t *)gl_fetch(MOD_INST(model)->link_table,1))
836     );
837 jpye 2559
838     /* test removeNonDeclarative LINKs */
839     removeNonDeclarativeLinkEntry(model,NULL,0); /*since the key is NULL, all non declarative LINKS are removed */
840    
841    
842     /* test getLinkTableDeclarative (already tested in previous functions) */
843     /* test getLinkTableProcedural (already tested in previous functions) */
844     }
845    

john.pye@anu.edu.au
ViewVC Help
Powered by ViewVC 1.1.22