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

Contents of /trunk/ascend/compiler/check.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2318 - (show annotations) (download) (as text)
Tue Dec 14 06:27:47 2010 UTC (11 years, 6 months ago) by jpye
File MIME type: text/x-csrc
File size: 34197 byte(s)
removing some unneeded #includes of 'slist.h'.
1 /*
2 * Instance Checking Routines
3 * by Tom Epperly
4 * Created: 5/4/1990
5 * Version: $Revision: 1.25 $
6 * Version control file: $RCSfile: check.c,v $
7 * Date last modified: $Date: 1998/06/23 13:44:24 $
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
25 * along with the program; if not, write to the Free Software Foundation,
26 * Inc., 675 Mass Ave, Cambridge, MA 02139 USA. Check the file named
27 * COPYING.
28 *
29 */
30
31 #include <stdarg.h>
32 #include <ascend/utilities/ascConfig.h>
33 #include <ascend/utilities/ascMalloc.h>
34 #include <ascend/utilities/ascPanic.h>
35 #include <ascend/general/pool.h>
36 #include <ascend/general/list.h>
37 #include <ascend/general/dstring.h>
38
39 #include "symtab.h"
40 #include "slist.h"
41
42 #include "functype.h"
43 #include "expr_types.h"
44 #include "stattypes.h"
45 #include "statio.h"
46 #include "module.h"
47 #include "statement.h"
48 #include "instance_types.h" /* for sizes */
49 #include "parentchild.h"
50 #include "atomvalue.h"
51 #include "instquery.h"
52 #include "mathinst.h"
53 #include "visitinst.h"
54 #include "arrayinst.h"
55 #include "instance_io.h"
56 #include "instantiate.h"
57 #include "find.h"
58 #include "logical_relation.h"
59 #include "rel_blackbox.h"
60 #include "relation.h"
61 #include "logrelation.h"
62 #include "relation_util.h"
63 #include "logrel_util.h"
64 #include "exprio.h"
65 #include "child.h"
66 #include "type_desc.h"
67 #include "library.h"
68 #include "instance_types.h"
69 #include "instance_name.h"
70 #include "cmpfunc.h"
71 #include "check.h"
72
73 /*
74 * If 1, statistics can take a real long time.
75 */
76 #define EXTRAPATHS 0
77
78 #define CLIQUE_WARNINGS 10000
79 #define NONZERO(x) ((x) ? (x) : 1)
80 /* array of statements we don't want written in errors */
81 static int *g_suppressions = NULL;
82 #define SUP(st) (g_suppressions[st])
83
84 /*
85 * the following is a little batch of lists for catching unassigned
86 * constants by type.
87 * They should always be null outside the scope of an executing check
88 * function since we have no operator for deallocating them.
89 */
90 static struct {
91 struct gl_list_t *rlist;
92 struct gl_list_t *blist;
93 struct gl_list_t *ilist;
94 struct gl_list_t *slist;
95 } g_cons = {NULL,NULL,NULL,NULL};
96
97 static
98 int CheckInstanceType(FILE *f, CONST struct Instance *i,
99 CONST struct Instance *parent)
100 {
101 switch(InstanceKind(i)) {
102 case MODEL_INST:
103 case REAL_ATOM_INST:
104 case BOOLEAN_ATOM_INST:
105 case INTEGER_ATOM_INST:
106 case SET_ATOM_INST:
107 case SYMBOL_ATOM_INST:
108
109 case LREL_INST:
110 case REL_INST:
111 case WHEN_INST:
112 case ARRAY_INT_INST:
113 case ARRAY_ENUM_INST:
114
115 case REAL_INST:
116 case INTEGER_INST:
117 case BOOLEAN_INST:
118 case SET_INST:
119 case SYMBOL_INST:
120
121 case REAL_CONSTANT_INST:
122 case INTEGER_CONSTANT_INST:
123 case BOOLEAN_CONSTANT_INST:
124 case SYMBOL_CONSTANT_INST:
125 case DUMMY_INST:
126 return 0;
127 default:
128 ERROR_REPORTER_NOLINE(ASC_PROG_ERROR,"Instance is not of a valid type in CheckInstanceType");
129 FPRINTF(f,"A child of ");
130 WriteInstanceName(f,parent,NULL);
131 FPRINTF(f," is an incorrect data type. Please report this bug!");
132 return 1;
133 }
134 }
135
136 /*
137 * at present, the lists are unsorted because we want them in order found
138 */
139 static void AppendUnique(struct gl_list_t *l, CONST struct Instance *i)
140 {
141 if (gl_ptr_search(l,i,0)==0) gl_append_ptr(l,(VOIDPTR)i);
142 }
143
144 /*
145 *this function now records rather than reporting constants.
146 * It's pretty gross. Blame the whiney users.
147 */
148 static
149 void CheckUnassignedConstants(FILE *f, CONST struct Instance *i)
150 {
151 unsigned long c,len;
152 struct Instance *child;
153
154 (void)f; /* stop gcc whine about unused parameter */
155
156 len = NumberChildren(i);
157 for(c=1;c<=len;c++){
158 child = InstanceChild(i,c);
159 if (child != NULL){
160 switch(InstanceKind(child)){
161 case REAL_CONSTANT_INST:
162 if (IsWild(RealAtomDims(child)) || !AtomAssigned(child)) {
163 AppendUnique(g_cons.rlist,child);
164 }
165 break;
166 case INTEGER_CONSTANT_INST:
167 if (!AtomAssigned(child)) {
168 AppendUnique(g_cons.ilist,child);
169 }
170 break;
171 case BOOLEAN_CONSTANT_INST:
172 if (!AtomAssigned(child)) {
173 AppendUnique(g_cons.blist,child);
174 }
175 break;
176 case SYMBOL_CONSTANT_INST:
177 if (!AtomAssigned(child)) {
178 AppendUnique(g_cons.slist,child);
179 }
180 break;
181 default:
182 break;
183 }
184 }
185 }
186 }
187
188 static
189 void CheckIncompleteArray(FILE *f, CONST struct Instance *i)
190 {
191 unsigned long c,len;
192 struct Instance *child;
193 struct TypeDescription *desc;
194 len = NumberChildren(i);
195 for(c=1;c<=len;c++){
196 child = InstanceChild(i,c);
197 if (child != NULL){
198 switch(InstanceKind(child)){
199 case ARRAY_INT_INST:
200 case ARRAY_ENUM_INST:
201 desc = InstanceTypeDesc(child);
202 if ((!GetArrayBaseIsRelation(desc)) &&
203 (!RectangleArrayExpanded(child)) &&
204 (!GetArrayBaseIsLogRel(desc)) ) {
205 WriteInstanceName(f,child,NULL);
206 FPRINTF(f,"[UNDEFINED]\n");
207 }
208 default:
209 break;
210 }
211 }
212 }
213 }
214
215 static
216 void CheckCompleteness(FILE *f, CONST struct Instance *i,int pass)
217 {
218 unsigned long c, length;
219 CONST struct BitList *blist;
220 CONST struct TypeDescription *desc;
221 CONST struct StatementList *slist;
222 CONST struct Statement *stat;
223 CONST struct gl_list_t *list;
224 if (pass) {
225 blist = InstanceBitList(i);
226 if (blist!=NULL && !BitListEmpty(blist)){
227 ERROR_REPORTER_START_NOLINE(ASC_PROG_WARNING);
228 WriteInstanceName(f,i,NULL);
229 FPRINTF(f," has the following unexecuted statements.\n");
230 desc = InstanceTypeDesc(i);
231 slist = GetStatementList(desc);
232 list = GetList(slist);
233 length = gl_length(list);
234 assert(length == BLength(blist));
235 for(c=1;c<=length;c++){
236 if (ReadBit(blist,c-1)){
237 stat = (struct Statement *)gl_fetch(list,c);
238 WSEMSPARSE(f,stat,"Unable to execute",g_suppressions);
239 }
240 }
241 error_reporter_end_flush();
242 }
243 }
244 if (IncompleteArray(i)) {
245 ERROR_REPORTER_START_NOLINE(ASC_PROG_WARNING);
246 WriteInstanceName(f,i,NULL);
247 FPRINTF(f," has the following incomplete arrays.\n");
248 error_reporter_end_flush();
249 CheckIncompleteArray(f,i);
250 }
251 CheckUnassignedConstants(f,i);
252 }
253
254 static
255 int SuppressNullInstance(CONST struct TypeDescription *d)
256 {
257 if (d==NULL) return 0;
258 switch (GetBaseType(d)) {
259 case relation_type:
260 return SUP(REL);
261 case logrel_type:
262 return SUP(LOGREL);
263 case when_type:
264 return SUP(WHEN);
265 case set_type:
266 case real_type:
267 case integer_type:
268 case boolean_type:
269 case symbol_type:
270 case real_constant_type:
271 case integer_constant_type:
272 case boolean_constant_type:
273 case symbol_constant_type:
274 case dummy_type:
275 case model_type:
276 return (SUP(ISA) || SUP(ALIASES));
277 case patch_type:
278 case array_type:
279 return 0;
280 }
281 return 0;
282 }
283
284 static
285 void RecursiveCheckInstance(FILE *f, CONST struct Instance *i,
286 CONST struct Instance *parent,CONST int pass)
287 {
288 CONST struct Instance *ptr;
289 struct TypeDescription *desc;
290 struct InstanceName name;
291 unsigned long c=0;
292 /* check for erroneous instance types */
293 if (CheckInstanceType(f,i,parent)) return;
294 /* check for unexecuted statements */
295 CheckCompleteness(f,i,pass);
296 /* check if i is connected to its parent */
297 if (parent != NULL &&
298 InstanceKind(i) != DUMMY_INST &&
299 SearchForParent(i,parent) == 0
300 ){
301 WriteInstanceName(f,parent,NULL);
302 FPRINTF(f," thinks that it is a parent of ");
303 WriteInstanceName(f,i,NULL);
304 FPRINTF(f,"\nbut ");
305 WriteInstanceName(f,i,NULL);
306 FPRINTF(f," doesn't have it in its parent list.\n");
307 }
308 desc = InstanceTypeDesc(i);
309 /* check the clique links */
310 ptr = NextCliqueMember(i);
311 while(ptr != i){
312 ptr = NextCliqueMember(ptr);
313 if (InstanceTypeDesc(ptr) != desc){
314 FPRINTF(f,"CLIQUE ERROR\n");
315 WriteInstanceName(f,i,NULL);
316 FPRINTF(f," is of type %s and ", SCP(InstanceType(i)));
317 WriteInstanceName(f,ptr,NULL);
318 FPRINTF(f," is of type %s.\n",SCP(InstanceType(ptr)));
319 }
320 if ((++c % CLIQUE_WARNINGS)==0){
321 FPRINTF(f,"POSSIBLE ERROR\n");
322 WriteInstanceName(f,i,NULL);
323 FPRINTF(f," is in a clique with %lu or more instances.\n",c);
324 FPRINTF(f,
325 "This is very large, so it may indicate an improper clique link.\n");
326 }
327 }
328 if (c > CLIQUE_WARNINGS){
329 FPRINTF(f,"Please ignore the clique warnings. ");
330 FPRINTF(f,"The clique was properly terminated.\n");
331 }
332 /* check i's parents */
333 for(c=NumberParents(i);c>=1;c--){
334 ptr = InstanceParent(i,c);
335 if (!ChildIndex(ptr,i)){
336 WriteInstanceName(f,i,NULL);
337 FPRINTF(f," thinks that ");
338 WriteInstanceName(f,ptr,NULL);
339 FPRINTF(f," is one of its parents.\n");
340 FPRINTF(f,"But ");
341 WriteInstanceName(f,ptr,NULL);
342 FPRINTF(f," doesn't think that ");
343 WriteInstanceName(f,i,NULL);
344 FPRINTF(f," is one of its children.\n");
345 }
346 }
347 /* check children */
348 for(c=NumberChildren(i);c>=1;c--){
349 ptr = InstanceChild(i,c);
350 if (ptr) {
351 RecursiveCheckInstance(f,ptr,i,pass);
352 } else {
353 if(!SuppressNullInstance(ChildRefines(i,c))) {
354 ERROR_REPORTER_START_NOLINE(ASC_USER_WARNING);
355 FPRINTF(f,"Instance '");
356 WriteInstanceName(f,i,NULL);
357 FPRINTF(f,"' is missing part '");
358 name = ChildName(i,c);
359 switch(InstanceNameType(name)){
360 case IntArrayIndex:
361 FPRINTF(f,"[%ld]'",InstanceIntIndex(name));
362 break;
363 case StrArrayIndex:
364 FPRINTF(f,"[%s]'",SCP(InstanceStrIndex(name)));
365 break;
366 case StrName:
367 FPRINTF(f,"%s'",SCP(InstanceNameStr(name)));
368 break;
369 default:
370 FPRINTF(f,"<BAD NAME>");
371 break;
372 }
373 error_reporter_end_flush();
374 }
375 }
376 }
377 }
378
379 static void InitConsLists(void)
380 {
381 g_cons.rlist = gl_create(100);
382 g_cons.blist = gl_create(10);
383 g_cons.slist = gl_create(20);
384 g_cons.ilist = gl_create(20);
385 }
386 static void ClearConsLists(void)
387 {
388 gl_destroy(g_cons.rlist);
389 g_cons.rlist=NULL;
390 gl_destroy(g_cons.blist);
391 g_cons.blist=NULL;
392 gl_destroy(g_cons.slist);
393 g_cons.slist=NULL;
394 gl_destroy(g_cons.ilist);
395 g_cons.ilist=NULL;
396 }
397
398 static FILE *g_diagf;
399 /*
400 * global pointer so gliterate will have a file to print to in WriteConsLists
401 */
402
403 static
404 void Diagnose(struct Instance *i) {
405 if (InstanceKind(i)== REAL_CONSTANT_INST) {
406 if (IsWild(RealAtomDims(i))) {
407 FPRINTF(g_diagf,"Undimensioned ");
408 }
409 if (!AtomAssigned(i)) {
410 FPRINTF(g_diagf,"Unassigned ");
411 }
412 FPRINTF(g_diagf,"real constant ");
413 WriteInstanceName(g_diagf,i,NULL);
414 FPRINTF(g_diagf,"\n");
415 } else {
416 FPRINTF(g_diagf,"Unassigned constant ");
417 WriteInstanceName(g_diagf,i,NULL);
418 FPRINTF(g_diagf,"\n");
419 }
420 }
421
422 /* writes out the unassigned foo based on the flags given (pr,b,s,i) */
423 static void WriteConsLists(FILE *f, int pr, int pb, int pi, int ps)
424 {
425 g_diagf = f;
426 if (pr) gl_iterate(g_cons.rlist,(void (*)(VOIDPTR))Diagnose);
427 if (pb) gl_iterate(g_cons.blist,(void (*)(VOIDPTR))Diagnose);
428 if (pi) gl_iterate(g_cons.ilist,(void (*)(VOIDPTR))Diagnose);
429 if (ps) gl_iterate(g_cons.slist,(void (*)(VOIDPTR))Diagnose);
430 }
431
432 void CheckInstanceLevel(FILE *f, CONST struct Instance *i,int pass)
433 {
434 InitConsLists();
435 g_suppressions = GetStatioSuppressions();
436 if (pass<5) g_suppressions[ASGN]=1;
437 if (pass<4) g_suppressions[WHEN]=1;
438 if (pass<3) g_suppressions[LOGREL]=1;
439 if (pass<2) g_suppressions[REL]=1;
440 RecursiveCheckInstance(f,i,NULL,pass);
441 DestroySuppressions(g_suppressions);
442 WriteConsLists(f,1,1,1,1);
443 ClearConsLists();
444 }
445
446 void CheckInstanceStructure(FILE *f,CONST struct Instance *i)
447 {
448 InitConsLists();
449 RecursiveCheckInstance(f,i,NULL,5);
450 WriteConsLists(f,0,1,1,1);
451 ClearConsLists();
452 }
453
454 /*********************************************************************\
455 Implementation of the InstanceStatistics procedure.
456 \*********************************************************************/
457
458 struct TypeCount {
459 CONST char *name; /* the name of the type. !symchar */
460 enum inst_t basetype; /* kind of the instance */
461 unsigned count; /* the number present in the instance tree */
462 };
463
464 /*********************************************************************\
465 Global for counting number of each type present in the instance
466 tree.
467 \*********************************************************************/
468 static struct gl_list_t *g_type_count_list=NULL;
469 /* a list of struct TypeCount */
470
471 /*********************************************************************\
472 Globals for counting instances
473 \*********************************************************************/
474 static unsigned long g_num_complex_instances=0;
475 /* number of models and atoms(excluding children of atoms) */
476 static unsigned long g_num_model_instances=0;
477 /* number of models */
478 static unsigned long g_model_bytes=0;
479 /* number of model bytes */
480 static unsigned long g_num_atom_instances=0;
481 /* number of atoms (nonfundamental) */
482 static unsigned long g_atom_bytes=0;
483 /* number of atom bytes */
484 static unsigned long g_tree_bytes=0;
485 /* number of nonshared instance tree bytes,
486 (ignore struct relation*, set_t*, dim_type *, char *)*/
487 static unsigned long g_num_constant_real=0;
488 static unsigned long g_num_constant_bool=0;
489 static unsigned long g_num_constant_int=0;
490 static unsigned long g_num_constant_sym=0;
491 static unsigned long g_num_constant_all=0;
492 /* number of constants of various types */
493 static unsigned long g_num_atom_children=0;
494 /* number of children of atoms or relations */
495 static unsigned long g_num_relation_instances=0;
496 /* number of relations */
497 static struct gl_list_t *g_relation_guts = NULL;
498 /* list of token relation guts */
499 static unsigned long g_num_array_instances=0;
500 /* number of array instances */
501 static unsigned long g_num_unsel_instances=0;
502 /* number of unselected instances */
503 /*********************************************************************\
504 The total number of instances should be equal to:
505 g_num_complex_instances + g_num_atom_children +
506 g_num_relation_instances + g_num_array_instances +
507 g_num_constant_all
508 \*********************************************************************/
509
510 /*********************************************************************\
511 Globals for counting number of parents
512 All of the following are counted for models, atoms(excluding
513 children of atoms), and arrays. Relations and children of atoms
514 aren't counted because they can realistically only have one
515 parent.
516 Parents of constants aren't counted yet. need more vars.
517 \*********************************************************************/
518 static unsigned g_minimum_parents=0;
519 static unsigned g_maximum_parents=0;
520 static unsigned g_extra_paths=0;
521 static unsigned g_extra_parents=0;
522 static unsigned g_extra_parents_sum=0;
523 static unsigned g_total_parents=0;
524
525 /*********************************************************************\
526 Globals for counting numbers of children
527 The following are counted for models, atoms(excluding children
528 of atoms), arrays, and relations. These globals are used to
529 report the minimum, maximum, and average number of children.
530 \*********************************************************************/
531 static unsigned g_minimum_children=0;
532 static unsigned g_maximum_children=0;
533 static unsigned g_total_children=0;
534
535 /*********************************************************************\
536 Globals for counting the number of cliques
537 This global is used to estimate the number and min, max, and average
538 size of the cliques in this tree.
539 \*********************************************************************/
540 static struct gl_list_t *g_clique_list=NULL; /* of struct Instance * */
541
542 /*********************************************************************\
543 Globals for estimating the number of relations in which each real appears.
544 These are used to estimate the min, max, and average size of the relation
545 list.
546 \*********************************************************************/
547 static unsigned g_total_variables=0;
548 static unsigned g_minimum_relations=0;
549 static unsigned g_maximum_relations=0;
550 static unsigned g_total_relations=0;
551
552
553 /*********************************************************************\
554 Globals for counting the number of terms in a relation.
555 A count is also made of all the reals in relations. This is
556 to get an estimate of how expensive the relations are.
557 \*********************************************************************/
558 static unsigned long g_total_reals_in_rels=0;
559 static unsigned long g_relation_terms=0;
560
561 /*********************************************************************\
562 Globals for calculating the minimum, maximum, and average number
563 of array elements per array.
564 \*********************************************************************/
565 static unsigned g_total_array_children=0;
566
567 /*********************************************************************\
568 \*********************************************************************/
569
570 long g_token_counts[NUM_EXPR_ENUMS];
571
572 /* this sorts by inst_t with a secondary alpha sort */
573 static
574 int CompareTypeCounts(CONST struct TypeCount *one,
575 CONST struct TypeCount *two)
576 {
577 if (one == two) return 0;
578 if (!one) return 1; /* NULLs float to top */
579 if (!two) return -1; /* NULLs float to top */
580
581 if (one->basetype==two->basetype) {
582 return strcmp(one->name,two->name);
583 } else {
584 return (one->basetype < two->basetype) ? -1 : 1;
585 }
586 }
587
588 static unsigned CliqueSize(CONST struct Instance *i)
589 {
590 unsigned result = 0;
591 CONST struct Instance *ptr;
592 ptr = i;
593 do {
594 result++;
595 ptr = NextCliqueMember(ptr);
596 } while(ptr != i);
597 return result;
598 }
599
600 static unsigned MinimumCliqueSize(struct gl_list_t *l)
601 {
602 unsigned result = UINT_MAX,size;
603 unsigned long c, length;
604 CONST struct Instance *i;
605 for(c=1, length = gl_length(l);c <= length;c++){
606 i = gl_fetch(l,c);
607 size = CliqueSize(i);
608 if (size < result) result = size;
609 }
610 return length ? result : 0;
611 }
612
613 static unsigned MaximumCliqueSize(struct gl_list_t *l)
614 {
615 unsigned result = 0,size;
616 unsigned long c, length;
617 CONST struct Instance *i;
618 for(c=1, length = gl_length(l);c <= length;c++){
619 i = gl_fetch(l,c);
620 size = CliqueSize(i);
621 if (size > result) result = size;
622 }
623 return length ? result : 0;
624 }
625
626 static double AverageCliqueSize(struct gl_list_t *l)
627 {
628 unsigned long total_clique_members=0;
629 unsigned long c, length;
630 CONST struct Instance *i;
631 for(c=1, length = gl_length(l);c <= length;c++){
632 i = gl_fetch(l,c);
633 total_clique_members += CliqueSize(i);
634 }
635 return length ? (double)total_clique_members/(double)length : 1;
636 }
637
638 static void IncrementTypeCount(CONST struct Instance *i)
639 {
640 unsigned long tindex;
641 struct TypeCount rec,*ptr;
642 symchar *name;
643
644 name = InstanceType(i);
645 if (*SCP(name)) {
646 rec.name = SCP(name);
647 } else {
648 rec.name = "UNNAMED ARRAY NODE";
649 }
650 rec.basetype = InstanceKind(i);
651 tindex = gl_search(g_type_count_list,&rec, (CmpFunc)CompareTypeCounts);
652 if (tindex != 0){
653 /* increment the current count by one */
654 ptr = (struct TypeCount *)gl_fetch(g_type_count_list,tindex);
655 ptr->count++;
656 } else{ /* add a new type count to the list */
657 ptr = ASC_NEW(struct TypeCount);
658 ptr->name = rec.name;
659 ptr->count = 1;
660 ptr->basetype = rec.basetype;
661 gl_insert_sorted(g_type_count_list,ptr, (CmpFunc)CompareTypeCounts);
662 }
663 }
664
665 static int InClique(CONST struct Instance *test,
666 CONST struct Instance *clique)
667 /* return true iff test is in clique */
668 {
669 CONST struct Instance *ptr;
670 ptr = clique;
671 do{
672 if (ptr == test) return 1;
673 ptr = NextCliqueMember(ptr);
674 } while(ptr != clique);
675 return 0;
676 }
677
678 static void CheckCliqueList(CONST struct Instance *i)
679 {
680 unsigned c, length;
681 CONST struct Instance *clique;
682 for(c=1, length = gl_length(g_clique_list); c <= length;c++){
683 clique = gl_fetch(g_clique_list,c);
684 if (InClique(i,clique)) return;
685 }
686 /* add to clique list */
687 gl_append_ptr(g_clique_list,(VOIDPTR)i);
688 }
689
690 static
691 void AccParents(CONST struct Instance *i)
692 {
693 unsigned long temp;
694 #if EXTRAPATHS
695 unsigned long c;
696 struct gl_list_t *plist;
697 #endif
698 temp = NumberParents(i);
699 if (temp < g_minimum_parents) {
700 g_minimum_parents = temp;
701 }
702 if (temp > g_maximum_parents) {
703 g_maximum_parents = temp;
704 }
705 if (temp > 1 && !InstanceUniversal(i)) {
706 g_extra_parents++;
707 g_extra_parents_sum += (temp-1);
708 #if EXTRAPATHS
709 plist = AllPaths(i);
710 g_extra_paths += gl_length(plist);
711 for(c=1;c <= gl_length(plist);c++){
712 gl_free_and_destroy(gl_fetch(plist,c));
713 }
714 gl_destroy(plist);
715 #endif /* extrapaths */
716 }
717 g_total_parents += temp;
718 }
719
720 static
721 void AccStatistics(CONST struct Instance *i)
722 {
723 unsigned long temp;
724 CONST struct relation *rel;
725 enum Expr_enum reltype;
726
727 IncrementTypeCount(i);
728 if (NextCliqueMember(i) != i)
729 CheckCliqueList(i);
730 switch(InstanceKind(i)){
731 case MODEL_INST:
732 g_num_complex_instances++;
733 g_num_model_instances++;
734 AccParents(i);
735 temp = NumberChildren(i);
736 if (temp < g_minimum_children) g_minimum_children = temp;
737 if (temp > g_maximum_children) g_maximum_children = temp;
738 g_total_children += temp;
739 g_model_bytes +=
740 (sizeof(struct ModelInstance) + temp*sizeof(struct Instance *));
741 break;
742 case REAL_ATOM_INST:
743 g_num_complex_instances++;
744 g_num_atom_instances++;
745 g_atom_bytes += GetByteSize(InstanceTypeDesc(i));
746 AccParents(i);
747 temp = NumberChildren(i);
748 if (temp < g_minimum_children) g_minimum_children = temp;
749 if (temp > g_maximum_children) g_maximum_children = temp;
750 g_total_children += temp;
751 g_total_variables++;
752 temp = RelationsCount(i);
753 if (temp < g_minimum_relations) g_minimum_relations = temp;
754 if (temp > g_maximum_relations) g_maximum_relations = temp;
755 g_total_relations += temp;
756 break;
757 case BOOLEAN_ATOM_INST:
758 g_num_complex_instances++;
759 g_num_atom_instances++;
760 g_atom_bytes += GetByteSize(InstanceTypeDesc(i));
761 AccParents(i);
762 temp = NumberChildren(i);
763 if (temp < g_minimum_children) g_minimum_children = temp;
764 if (temp > g_maximum_children) g_maximum_children = temp;
765 g_total_children += temp;
766 break;
767 case INTEGER_ATOM_INST:
768 g_num_complex_instances++;
769 g_num_atom_instances++;
770 g_atom_bytes += GetByteSize(InstanceTypeDesc(i));
771 AccParents(i);
772 temp = NumberChildren(i);
773 if (temp < g_minimum_children) g_minimum_children = temp;
774 if (temp > g_maximum_children) g_maximum_children = temp;
775 g_total_children += temp;
776 break;
777 case SET_ATOM_INST:
778 g_num_complex_instances++;
779 g_num_atom_instances++;
780 g_atom_bytes += GetByteSize(InstanceTypeDesc(i));
781 AccParents(i);
782 temp = NumberChildren(i);
783 if (temp < g_minimum_children) g_minimum_children = temp;
784 if (temp > g_maximum_children) g_maximum_children = temp;
785 g_total_children += temp;
786 break;
787 case SYMBOL_ATOM_INST:
788 g_num_complex_instances++;
789 g_num_atom_instances++;
790 g_atom_bytes += GetByteSize(InstanceTypeDesc(i));
791 AccParents(i);
792 temp = NumberChildren(i);
793 if (temp < g_minimum_children) g_minimum_children = temp;
794 if (temp > g_maximum_children) g_maximum_children = temp;
795 g_total_children += temp;
796 break;
797 case REL_INST:
798 g_num_relation_instances++;
799 temp = NumberChildren(i);
800 if (temp < g_minimum_children) g_minimum_children = temp;
801 if (temp > g_maximum_children) g_maximum_children = temp;
802 g_total_children += temp;
803 /* count terms */
804 rel = GetInstanceRelation(i,&reltype);
805 if (rel&&(reltype==e_token)) {
806 g_relation_terms += RelationLength(rel,0);
807 g_relation_terms += RelationLength(rel,1);
808 g_total_reals_in_rels += NumberVariables(rel);
809 }
810 break;
811 case ARRAY_INT_INST:
812 g_num_array_instances++;
813 AccParents(i);
814 temp = NumberChildren(i);
815 if (temp < g_minimum_children) g_minimum_children = temp;
816 if (temp > g_maximum_children) g_maximum_children = temp;
817 g_total_children += temp;
818 g_total_array_children += temp;
819 break;
820 case ARRAY_ENUM_INST:
821 g_num_array_instances++;
822 AccParents(i);
823 temp = NumberChildren(i);
824 if (temp < g_minimum_children) g_minimum_children = temp;
825 if (temp > g_maximum_children) g_maximum_children = temp;
826 g_total_children += temp;
827 g_total_array_children += temp;
828 break;
829 case REAL_CONSTANT_INST:
830 g_num_constant_real++;
831 g_num_constant_all++;
832 break;
833 case INTEGER_CONSTANT_INST:
834 g_num_constant_int++;
835 g_num_constant_all++;
836 break;
837 case BOOLEAN_CONSTANT_INST:
838 g_num_constant_bool++;
839 g_num_constant_all++;
840 break;
841 case SYMBOL_CONSTANT_INST:
842 g_num_constant_sym++;
843 g_num_constant_all++;
844 break;
845 case REAL_INST:
846 g_num_atom_children++;
847 break;
848 case INTEGER_INST:
849 g_num_atom_children++;
850 break;
851 case BOOLEAN_INST:
852 g_num_atom_children++;
853 break;
854 case SET_INST:
855 g_num_atom_children++;
856 break;
857 case SYMBOL_INST:
858 g_num_atom_children++;
859 break;
860 case DUMMY_INST:
861 g_num_unsel_instances++;
862 break;
863 case WHEN_INST:
864 case LREL_INST:
865 /* vicente we should be collecting info here */
866 break;
867 default:
868 ASC_PANIC("Invalid arguments to AccStatistics.\n");
869 break;
870 }
871 }
872
873 static void AccBytes(CONST struct Instance *i)
874 {
875 g_tree_bytes += InstanceSize(i);
876 }
877
878 /*
879 * Does not account properly for shared external rels.
880 */
881 static void AccTokenStatistics(CONST struct Instance *i)
882 {
883 unsigned long p,len,llen,rlen;
884 CONST struct relation *rel;
885 enum Expr_enum t;
886 CONST union RelationTermUnion *rside;
887 switch(InstanceKind(i)){
888 case REL_INST:
889 g_num_relation_instances++;
890 /* count terms */
891 rel = GetInstanceRelation(i,&t);
892 if (rel&&(t==e_token)) {
893 g_total_reals_in_rels += NumberVariables(rel);
894
895 /* count all the terms that would be evaluated */
896 rside = PostFix_RhsSide(rel);
897 rlen = RelationLength(rel,0);
898 g_relation_terms += rlen;
899 rside = PostFix_LhsSide(rel);
900 llen = RelationLength(rel,1);
901 g_relation_terms += llen;
902 /* if not on list, add and count tokens in fine */
903 if ( !gl_search(g_relation_guts,rside,(CmpFunc)CmpPtrs) ) {
904 gl_append_ptr(g_relation_guts,(VOIDPTR)rside);
905 len = llen;
906 rside = PostFix_LhsSide(rel);
907 for (p=0; p<len; p++) {
908 t = RelationTermType(RelationSideTerm(rside,p));
909 g_token_counts[t]++;
910 }
911 len = rlen;
912 rside = PostFix_RhsSide(rel);
913 for (p=0; p<len; p++) {
914 t = RelationTermType(RelationSideTerm(rside,p));
915 g_token_counts[t]++;
916 }
917 }
918 }
919 break;
920 case MODEL_INST:
921 case REAL_ATOM_INST:
922 case BOOLEAN_ATOM_INST:
923 case INTEGER_ATOM_INST:
924 case SET_ATOM_INST:
925 case SYMBOL_ATOM_INST:
926 case ARRAY_INT_INST:
927 case ARRAY_ENUM_INST:
928 case REAL_CONSTANT_INST:
929 case INTEGER_CONSTANT_INST:
930 case BOOLEAN_CONSTANT_INST:
931 case SYMBOL_CONSTANT_INST:
932 case REAL_INST:
933 case INTEGER_INST:
934 case BOOLEAN_INST:
935 case SET_INST:
936 case SYMBOL_INST:
937 case DUMMY_INST:
938 break;
939 default:
940 ASC_PANIC("Invalid arguments to AccTokenStatistics.\n");
941 break;
942 }
943 }
944
945 void InstanceTokenStatistics(FILE *f, CONST struct Instance *i)
946 {
947 int j;
948 if (i==NULL) return;
949 g_relation_guts = gl_create(10000);
950 for (j=0; j < NUM_EXPR_ENUMS; j++) g_token_counts[j] = 0;
951 g_num_relation_instances = g_relation_terms = g_total_reals_in_rels = 0;
952 SilentVisitInstanceTree((struct Instance *)i,
953 (void (*)(struct Instance *))AccTokenStatistics,1,0);
954 FPRINTF(f,"Token relation statistics\n===================\n");
955 FPRINTF(f,"Total number of relation instances: %lu\n",
956 g_num_relation_instances);
957 FPRINTF(f,"Total number of 'unique' relations: %lu\n",
958 gl_length(g_relation_guts));
959 FPRINTF(f,"Total number of relation terms: %lu\n", g_relation_terms);
960 FPRINTF(f,"Total number of reals in relation: %lu\n",
961 g_total_reals_in_rels);
962 FPRINTF(f,"Number\t\tType of term:\n");
963 g_relation_terms = 0;
964 for (j=0; j < NUM_EXPR_ENUMS; j++) {
965 if (g_token_counts[j]) {
966 FPRINTF(f,"%lu\t\t%s\n", g_token_counts[j], ExprEnumName(j));
967 g_relation_terms += g_token_counts[j];
968 }
969 }
970 FPRINTF(f,"Total compiled tokens:\t%lu\n",g_relation_terms);
971 FPRINTF(f,"===================\n");
972
973 gl_destroy(g_relation_guts);
974 g_relation_guts = NULL;
975 }
976
977 void InstanceStatistics(FILE *f, CONST struct Instance *i)
978 {
979 struct TypeCount *count;
980 unsigned long c, length;
981 /*
982 * initialize global variables
983 */
984 g_type_count_list = gl_create(50L);
985 g_clique_list = gl_create(300L);
986 g_num_complex_instances = g_num_atom_children =
987 g_num_relation_instances = g_num_array_instances =
988 g_num_unsel_instances = g_maximum_parents = g_total_parents =
989 g_maximum_children = g_total_children = g_total_variables =
990 g_maximum_relations = g_total_relations = g_total_array_children =
991 g_relation_terms = g_total_reals_in_rels =
992 g_num_constant_sym = g_num_constant_real =
993 g_num_constant_bool = g_num_constant_int =
994 g_num_constant_all = g_num_model_instances =
995 g_num_atom_instances = g_model_bytes = g_atom_bytes =
996 g_tree_bytes = g_extra_parents = g_extra_parents_sum =
997 g_extra_paths =
998 0;
999 g_minimum_parents = g_minimum_children = g_minimum_relations = UINT_MAX;
1000
1001 VisitInstanceTree((struct Instance *)i,
1002 (void (*)(struct Instance *))AccStatistics,1,1);
1003 SilentVisitInstanceTree((struct Instance *)i,
1004 (void (*)(struct Instance *))AccBytes,0,0);
1005
1006 FPRINTF(f,"General Instance Tree Numbers\n=============================\n");
1007 FPRINTF(f,"Number of models and complex atoms: %lu\n",
1008 g_num_complex_instances);
1009 FPRINTF(f,"Number of models: %lu (%lu bytes)\n",
1010 g_num_model_instances,g_model_bytes);
1011 FPRINTF(f,"Number of atoms: %lu (%lu bytes)\n",
1012 g_num_atom_instances,g_atom_bytes);
1013 FPRINTF(f,"Number of atom children instances: %lu\n",
1014 g_num_atom_children);
1015 FPRINTF(f,"Number of constant instances: %lu\n",
1016 g_num_constant_all);
1017 if (FindRelationType() !=NULL) {
1018 length = GetByteSize(FindRelationType());
1019 } else {
1020 length = 0;
1021 }
1022 FPRINTF(f,"Number of relation heads: %lu (%lu bytes)\n",
1023 g_num_relation_instances, length*g_num_relation_instances);
1024 FPRINTF(f,"Number of array instances: %lu\n",
1025 g_num_array_instances);
1026 FPRINTF(f,"Number of unselected instances: %lu\n",
1027 g_num_unsel_instances);
1028 FPRINTF(f,"TOTAL INSTANCES: %lu\n",
1029 g_num_complex_instances + g_num_atom_children +
1030 g_num_relation_instances + g_num_relation_instances +
1031 g_num_array_instances + g_num_constant_all);
1032 FPRINTF(f,"TOTAL BYTES (neglecting shared internals): %lu\n", g_tree_bytes);
1033
1034 FPRINTF(f,"Instance number by type\n=======================\n");
1035 length = gl_length(g_type_count_list);
1036 for(c=1; c <= length;c++){
1037 count = gl_fetch(g_type_count_list,c);
1038 if (count){
1039 FPRINTF(f,"%-40s %lu\n",count->name,(unsigned long)count->count);
1040 } else {
1041 FPRINTF(f,"NULL pointer in type count list\n");
1042 }
1043 }
1044 FPRINTF(f,"Parental statistics\n===================\n");
1045 FPRINTF(f,"Minimum number of parents: %u\n",g_minimum_parents);
1046 FPRINTF(f,"Maximum number of parents: %u\n",g_maximum_parents);
1047 FPRINTF(f,"Average number of parents: %g\n",
1048 (double)g_total_parents/
1049 (double)NONZERO(g_num_complex_instances + g_num_array_instances));
1050 FPRINTF(f,"Instances with nP > 1: %u\n",g_extra_parents);
1051 FPRINTF(f,"Total extra parents: %u\n",g_extra_parents_sum);
1052 #if EXTRAPATHS
1053 FPRINTF(f,"Total extra paths: %u\n",g_extra_paths);
1054 #endif /* extrapaths */
1055
1056 FPRINTF(f,"Children statistics\n===================\n");
1057 FPRINTF(f,"Minimum number of children: %u\n",g_minimum_children);
1058 FPRINTF(f,"Maximum number of children: %u\n",g_maximum_children);
1059 FPRINTF(f,"Average number of children: %g\n",
1060 (double)g_total_children/
1061 (double)NONZERO(g_num_complex_instances + g_num_array_instances +
1062 g_num_relation_instances));
1063
1064 FPRINTF(f,"Clique statistics\n=================\n");
1065 FPRINTF(f,"Number of cliques: %lu\n",gl_length(g_clique_list));
1066 FPRINTF(f,"Minimum clique size: %u\n",MinimumCliqueSize(g_clique_list));
1067 FPRINTF(f,"Maximum clique size: %u\n",MaximumCliqueSize(g_clique_list));
1068 FPRINTF(f,"Average clique size: %g\n",AverageCliqueSize(g_clique_list));
1069
1070 FPRINTF(f,"Variable statistics\n===================\n");
1071 FPRINTF(f,"Number of complex reals: %u\n",g_total_variables);
1072 FPRINTF(f,"Minimum number of relations per real: %u\n",
1073 g_minimum_relations);
1074 FPRINTF(f,"Maximum number of relations per real: %u\n",
1075 g_maximum_relations);
1076 FPRINTF(f,"Average number of relations per real: %g\n",
1077 (double)g_total_relations/(double)NONZERO(g_total_variables));
1078
1079 FPRINTF(f,"Constant statistics\n===================\n");
1080 FPRINTF(f,"Number of constant reals:\t %lu\n",g_num_constant_real);
1081 FPRINTF(f,"Number of constant booleans:\t %lu\n",g_num_constant_bool);
1082 FPRINTF(f,"Number of constant integers:\t %lu\n",g_num_constant_int);
1083 FPRINTF(f,"Number of constant symbols:\t %lu\n",g_num_constant_sym);
1084
1085 FPRINTF(f,"Relation statistics\n===================\n");
1086 FPRINTF(f,"Total number of relation terms: %lu\n", g_relation_terms);
1087 FPRINTF(f,"Total number of reals in relation: %lu\n",
1088 g_total_reals_in_rels);
1089
1090 FPRINTF(f,"Array statistics\n================\n");
1091 FPRINTF(f,"Average children per array node: %g\n",
1092 (double)g_total_array_children /
1093 (double)NONZERO(g_num_array_instances));
1094
1095 gl_destroy(g_clique_list);
1096 gl_free_and_destroy(g_type_count_list);
1097 }

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