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

Contents of /trunk/base/generic/compiler/check.c

Parent Directory Parent Directory | Revision Log Revision Log


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

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