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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 669 - (hide annotations) (download) (as text)
Wed Jun 21 07:00:45 2006 UTC (13 years, 2 months ago) by johnpye
File MIME type: text/x-csrc
File size: 34466 byte(s)
Merged changes from DAE branch (revisions 702 to 819) back into trunk.
This adds the Integration API to the ASCEND solver (in base/generic).
Also provides pre-alpha support for 'IDA' from the SUNDIALS suite, a DAE solver.
Many other minor code clean-ups, including adoption of new 'ASC_NEW' and friends (to replace 'ascmalloc')
Added some very sketchy stuff providing 'DIFF(...)' syntax, although it is anticipated that this will be removed.
1 aw0a 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 johnpye 399 #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 johnpye 669 #include "expr_types.h"
45 johnpye 399 #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 aw0a 1
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 johnpye 190 ERROR_REPORTER_NOLINE(ASC_PROG_ERROR,"Instance is not of a valid type in CheckInstanceType");
137 aw0a 1 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 johnpye 222 ERROR_REPORTER_START_NOLINE(ASC_PROG_WARNING);
238 aw0a 1 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 johnpye 183 error_reporter_end_flush();
252 aw0a 1 }
253     }
254     if (IncompleteArray(i)) {
255 johnpye 222 ERROR_REPORTER_START_NOLINE(ASC_PROG_WARNING);
256 aw0a 1 WriteInstanceName(f,i,NULL);
257     FPRINTF(f," has the following incomplete arrays.\n");
258 johnpye 183 error_reporter_end_flush();
259 aw0a 1 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 = (struct TypeCount *)ascmalloc(sizeof(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