/[ascend]/trunk/base/generic/solver/analyze.c
ViewVC logotype

Diff of /trunk/base/generic/solver/analyze.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1067 by johnpye, Sun Jan 7 09:15:56 2007 UTC revision 1068 by johnpye, Mon Jan 8 04:45:47 2007 UTC
# Line 70  Line 70 
70      Last modified by: $Author: ballan $      Last modified by: $Author: ballan $
71  */  */
72    
73    /** @addtogroup analyse Analyse
74        @{
75    */
76    
77  #include <stdarg.h>  #include <stdarg.h>
78  #include <utilities/ascConfig.h>  #include <utilities/ascConfig.h>
79  #include <utilities/ascPanic.h>  #include <utilities/ascPanic.h>
# Line 134  Line 138 
138    GLOBAL VARS    GLOBAL VARS
139  */  */
140    
141  static symchar *g_strings[3];  static symchar *g_strings[4];
142    
143  /* symbol table entries we need */  /* symbol table entries we need */
144  #define INCLUDED_A g_strings[0]  #define INCLUDED_A g_strings[0]
145  #define FIXED_A g_strings[1]  #define FIXED_A g_strings[1]
146  #define BASIS_A g_strings[2]  #define BASIS_A g_strings[2]
147    #define DERIV_A g_strings[3]
148    
149  /*  /*
150      Global variable. Set to true by classify if need be      Global variable. Set to true by classify if need be
# Line 170  struct varip { Line 175  struct varip {
175    int solvervar;          /* set in classify_instance */    int solvervar;          /* set in classify_instance */
176    int active;             /* is this var a part of my problem */    int active;             /* is this var a part of my problem */
177    int basis;              /* set in classify_instance */    int basis;              /* set in classify_instance */
178      int deriv;              /* set in classify_instance */
179  };  };
180    
181    
# Line 257  static struct reuse_t { Line 263  static struct reuse_t {
263      In particular, do no operations that can throw an exception      In particular, do no operations that can throw an exception
264      while manipulating a problem_t, as it is way too big to let leak.      while manipulating a problem_t, as it is way too big to let leak.
265    
266      @TODO is this comment in the right place?      We are making the ANSI assumption that this will be init to 0/NULL
267      we are making the ANSI assumption that this will be init to 0/NULL      (K&R 2nd Ed, p 219)
268            
269      @TODO what about this one?:      @TODO what about this one?:
270      container for globals during assembly.      container for globals during assembly.
# Line 394  struct problem_t { Line 400  struct problem_t {
400  /*------------------------------------------------------------------------------  /*------------------------------------------------------------------------------
401    SOME STUFF WITH INTERFACE POINTERS    SOME STUFF WITH INTERFACE POINTERS
402  */  */
403  /* return a pointer to the oncesizefitsall ips we're using.  /**
404      always returns nonnull because if we run out we exit      Return a pointer to the one-size-fits-all ips we're using.
405        Always returns non-NULL because if we run out we exit
406  */  */
407  static struct solver_ipdata *analyze_getip(void)  static
408  {  struct solver_ipdata *analyze_getip(void){
409    if (g_reuse.ipbuf!=NULL && g_reuse.ipused < g_reuse.ipcap) {    if (g_reuse.ipbuf!=NULL && g_reuse.ipused < g_reuse.ipcap) {
410      return &(g_reuse.ipbuf[g_reuse.ipused++]);      return &(g_reuse.ipbuf[g_reuse.ipused++]);
411    } else {    } else {
412      Asc_Panic(2, "ananlyze_getip",      ASC_PANIC("Too many ips requested by analyze_getip");
               "Too many ips requested by analyze_getip\n");  
     exit(2);/* NOT REACHED.  Needed to keep gcc from whining */  
413    }    }
414  }  }
415    
416  /*  /**
417      reallocates to the requested size (newcap) the ipbuf.      Reallocates to the requested size (newcap) the ipbuf.
418      if newcap = 0, frees ipbuf.      If newcap = 0, frees ipbuf.
419      if insufficient memory returns 1.      If newcap > 0 and reset mem != 0, initializes ipbuf to 0s.
     if newcap > 0 and reset mem != 0, initializes ipbuf to 0s.  
420      Resets ipused to 0.      Resets ipused to 0.
421    
422        @return 0 on success, 1 on insufficient memory
423  */  */
424  static  static
425  int resize_ipbuf(size_t newcap, int resetmem)  int resize_ipbuf(size_t newcap, int resetmem){
 {  
426    struct solver_ipdata *tmp;    struct solver_ipdata *tmp;
427    if (newcap ==0) {    if (newcap ==0) {
428      if (g_reuse.ipbuf != NULL) {      if (g_reuse.ipbuf != NULL) {
# Line 465  int resize_ipbuf(size_t newcap, int rese Line 470  int resize_ipbuf(size_t newcap, int rese
470      NULL. p_data->relincidence must have been allocated for this to work.      NULL. p_data->relincidence must have been allocated for this to work.
471  */  */
472  static  static
473  struct var_variable **get_incidence_space(int len, struct problem_t *p_data)  struct var_variable **get_incidence_space(int len, struct problem_t *p_data){
 {  
474    struct var_variable **tmp;    struct var_variable **tmp;
475    if (p_data->relincidence == NULL) {    if (p_data->relincidence == NULL) {
476      ASC_PANIC("get_incidence_space called prematurely. bye.\n");      ASC_PANIC("get_incidence_space called prematurely. bye.\n");
# Line 487  struct var_variable **get_incidence_spac Line 491  struct var_variable **get_incidence_spac
491      NULL. p_data->varincidence must have been allocated for this to work.      NULL. p_data->varincidence must have been allocated for this to work.
492  */  */
493  static  static
494  struct rel_relation **get_var_incidence_space(int len,  struct rel_relation **get_var_incidence_space(int len
495                                                struct problem_t *p_data)          ,struct problem_t *p_data
496  {  ){
497    struct rel_relation **tmp;    struct rel_relation **tmp;
498    if (p_data->varincidence == NULL) {    if (p_data->varincidence == NULL) {
499      ASC_PANIC("get_var_incidence_space called prematurely. bye.\n");      ASC_PANIC("get_var_incidence_space called prematurely. bye.\n");
# Line 509  struct rel_relation **get_var_incidence_ Line 513  struct rel_relation **get_var_incidence_
513      p_data->logrelinciden must have been allocated for this to work.      p_data->logrelinciden must have been allocated for this to work.
514  */  */
515  static  static
516  struct dis_discrete **get_logincidence_space(int len,  struct dis_discrete **get_logincidence_space(int len
517                                               struct problem_t *p_data)          ,struct problem_t *p_data
518  {  ){
519    struct dis_discrete **tmp;    struct dis_discrete **tmp;
520    if (p_data->logrelinciden == NULL) {    if (p_data->logrelinciden == NULL) {
521      ASC_PANIC("get_logincidence_space called prematurely. bye.\n");      ASC_PANIC("get_logincidence_space called prematurely. bye.\n");
# Line 537  struct dis_discrete **get_logincidence_s Line 541  struct dis_discrete **get_logincidence_s
541      of the caller.      of the caller.
542      p_data->root is set to i.      p_data->root is set to i.
543  */  */
544  static void InitTreeCounts(struct Instance *i,struct problem_t *p_data)  static void InitTreeCounts(struct Instance *i,struct problem_t *p_data){
 {  
545    memset((char *)p_data,0,sizeof(struct problem_t));    memset((char *)p_data,0,sizeof(struct problem_t));
546    p_data->root = i;    p_data->root = i;
547  }  }
# Line 549  static void InitTreeCounts(struct Instan Line 552  static void InitTreeCounts(struct Instan
552  #define AVG_GROWTH 2  #define AVG_GROWTH 2
553  #define PART_THRESHOLD 1000  #define PART_THRESHOLD 1000
554    
555  /*  /**
556      The following function should be moved out to the compiler      @param i atom instance in the Instance hierarchy
557      under the guise of a supported attribute.      @param sc name of an supposed child instance of i, a boolean atom.
558    
559        @return the value of the named boolean child instance, or NULL if i or the child doesn't exist
560  */  */
561  static int BooleanChildValue(struct Instance *i,symchar *sc){  static
562    /* FPRINTF(ASCERR,"GETTING BOOLEAN CHILD VALUE OF %s\n",SCP(sc)); */  int BooleanChildValue(struct Instance *i,symchar *sc){
563    if (i == NULL || sc == NULL || (i=ChildByChar(i,sc)) == NULL) {    if(i == NULL || sc == NULL || (i=ChildByChar(i,sc)) == NULL) {
564      return 0;      return 0;
565    } else {    }else{
566      return ( GetBooleanAtomValue(i) );      return ( GetBooleanAtomValue(i) );
567    }    }
568  }  }
569    
570  static void CollectArrayRelsAndWhens(struct Instance *i, long modindex,  /**
571                                       struct problem_t *p_data)      As for BooleanChildValue but for integer child atoms (ode_type in this case)
572  {  */
573    static
574    int IntegerChildValue(struct Instance *i,symchar *sc){
575      if(i == NULL || sc == NULL || (i=ChildByChar(i,sc)) == NULL) {
576        return 0;
577      }else{
578        return ( GetIntegerAtomValue(i) );
579      }
580    }
581    
582    
583    static
584    void CollectArrayRelsAndWhens(struct Instance *i, long modindex
585            ,struct problem_t *p_data
586    ){
587    struct Instance *child;    struct Instance *child;
588    struct solver_ipdata *rip;    struct solver_ipdata *rip;
589    unsigned long nch,c;    unsigned long nch,c;
# Line 639  static void CollectArrayRelsAndWhens(str Line 658  static void CollectArrayRelsAndWhens(str
658      mainly because these arrays don't have interface pointers so we      mainly because these arrays don't have interface pointers so we
659      can't treat them separately.      can't treat them separately.
660  */  */
661  static void CollectRelsAndWhens(struct solver_ipdata *ip,  static
662                                  long modindex,  void CollectRelsAndWhens(struct solver_ipdata *ip
663                                  struct problem_t *p_data)          ,long modindex
664  {          ,struct problem_t *p_data
665    ){
666    struct Instance *child;    struct Instance *child;
667    struct solver_ipdata *rip;    struct solver_ipdata *rip;
668    unsigned long nch,c;    unsigned long nch,c;
# Line 705  static void CollectRelsAndWhens(struct s Line 725  static void CollectRelsAndWhens(struct s
725      will return the pointer to the cache. The nodestamp corresponding      will return the pointer to the cache. The nodestamp corresponding
726      to this relation is returned regardless.      to this relation is returned regardless.
727  */  */
728  static struct ExtRelCache  static
729    *CheckIfCacheExists( struct Instance *relinst, int *nodestamp,  struct ExtRelCache *CheckIfCacheExists(struct Instance *relinst
730                         struct problem_t *p_data)          ,int *nodestamp
731  {          ,struct problem_t *p_data
732    ){
733    struct ExtCallNode *ext;    struct ExtCallNode *ext;
734    struct ExtRelCache *cache;    struct ExtRelCache *cache;
735    CONST struct relation *gut;    CONST struct relation *gut;
# Line 736  static struct ExtRelCache Line 757  static struct ExtRelCache
757    
758      @NOTE Call only with good relation instances.      @NOTE Call only with good relation instances.
759  */  */
760  static void analyze_CountRelation(struct Instance *inst,  static void analyze_CountRelation(struct Instance *inst
761                                    struct problem_t *p_data)          ,struct problem_t *p_data
762  {  ){
763    switch( RelationRelop(GetInstanceRelationOnly(inst)) ) {    switch( RelationRelop(GetInstanceRelationOnly(inst)) ) {
764    case e_maximize:    case e_maximize:
765    case e_minimize:    case e_minimize:
# Line 775  static void analyze_CountRelation(struct Line 796  static void analyze_CountRelation(struct
796      whens anyway ?      whens anyway ?
797  */  */
798    
799  int GetIntFromSymbol(CONST char *symval,  int GetIntFromSymbol(CONST char *symval
800               struct gl_list_t *symbol_list)          ,struct gl_list_t *symbol_list
801  {  ){
802    
803    struct SymbolValues *entry,*dummy;    struct SymbolValues *entry,*dummy;
804    unsigned long length;    unsigned long length;
805    int len,c,value;    int len,c,value;
# Line 841  void DestroySymbolValuesList(struct gl_l Line 863  void DestroySymbolValuesList(struct gl_l
863      vp is a struct problem_t.      vp is a struct problem_t.
864  */  */
865  static  static
866  void *classify_instance(struct Instance *inst, VOIDPTR vp)  void *classify_instance(struct Instance *inst, VOIDPTR vp){
 {  
867    struct solver_ipdata *ip;    struct solver_ipdata *ip;
868    struct problem_t *p_data;    struct problem_t *p_data;
869    CONST char *symval;    CONST char *symval;
# Line 860  void *classify_instance(struct Instance Line 881  void *classify_instance(struct Instance
881        ip->u.v.solvervar = 1; /* must set this regardless of what list */        ip->u.v.solvervar = 1; /* must set this regardless of what list */
882        ip->u.v.fixed = BooleanChildValue(inst,FIXED_A);        ip->u.v.fixed = BooleanChildValue(inst,FIXED_A);
883        ip->u.v.basis = BooleanChildValue(inst,BASIS_A);        ip->u.v.basis = BooleanChildValue(inst,BASIS_A);
884          ip->u.v.deriv = IntegerChildValue(inst,DERIV_A);
885    
886        if (RelationsCount(inst)) {        if(RelationsCount(inst)) {
887          gl_append_ptr(p_data->vars,(POINTER)ip);          gl_append_ptr(p_data->vars,(POINTER)ip);
888        }else{        }else{
889          gl_append_ptr(p_data->unas,(POINTER)ip);          gl_append_ptr(p_data->unas,(POINTER)ip);
890        }        }
891      } else {      }else{
892        ip->u.v.fixed = 1;        ip->u.v.fixed = 1;
893        ip->u.v.solvervar=0;        ip->u.v.solvervar=0;
894        if (solver_par(inst) && RelationsCount(inst)) {        if(solver_par(inst) && RelationsCount(inst)) {
895          gl_append_ptr(p_data->pars,(POINTER)ip);          gl_append_ptr(p_data->pars,(POINTER)ip);
896        } else {        }else{
897          gl_append_ptr(p_data->unas,(POINTER)ip);          gl_append_ptr(p_data->unas,(POINTER)ip);
898        }        }
899      }      }
# Line 885  void *classify_instance(struct Instance Line 907  void *classify_instance(struct Instance
907      ip->u.dv.index = 0;      ip->u.dv.index = 0;
908      ip->u.dv.active = 0;      ip->u.dv.active = 0;
909        ip->u.dv.value = GetBooleanAtomValue(inst);        ip->u.dv.value = GetBooleanAtomValue(inst);
910      if( boolean_var(inst) ) {      if(boolean_var(inst) ) {
911        ip->u.dv.booleanvar = 1;        ip->u.dv.booleanvar = 1;
912        ip->u.dv.fixed = BooleanChildValue(inst,FIXED_A);        ip->u.dv.fixed = BooleanChildValue(inst,FIXED_A);
913      } else {      }else{
914        ip->u.dv.fixed = 1;        ip->u.dv.fixed = 1;
915        ip->u.dv.booleanvar=0;        ip->u.dv.booleanvar=0;
916      }      }
917      if( LogRelationsCount(inst) || WhensCount(inst) ) {      if(LogRelationsCount(inst) || WhensCount(inst) ) {
918        gl_append_ptr(p_data->dvars,(POINTER)ip);        gl_append_ptr(p_data->dvars,(POINTER)ip);
919        if ( WhensCount(inst) ) {        if(WhensCount(inst) ) {
920          ip->u.dv.inwhen = 1;          ip->u.dv.inwhen = 1;
921        } else {        }else{
922          ip->u.dv.inwhen = 0;          ip->u.dv.inwhen = 0;
923        }        }
924      } else {      }else{
925        gl_append_ptr(p_data->dunas,(POINTER)ip);        gl_append_ptr(p_data->dunas,(POINTER)ip);
926      }      }
927      return ip;      return ip;
928    case BOOLEAN_CONSTANT_INST:    case BOOLEAN_CONSTANT_INST:
929      if (WhensCount(inst)) {      if(!WhensCount(inst))return NULL;
930        ip = analyze_getip();      ip = analyze_getip();
931        ip->i = inst;      ip->i = inst;
932        ip->u.dv.isconst = 1;      ip->u.dv.isconst = 1;
933        ip->u.dv.distype = 0;      ip->u.dv.distype = 0;
934        ip->u.dv.index = 0;      ip->u.dv.index = 0;
935        ip->u.dv.incident = 0;      ip->u.dv.incident = 0;
936        ip->u.dv.booleanvar=0;      ip->u.dv.booleanvar=0;
937        ip->u.dv.fixed = 1;      ip->u.dv.fixed = 1;
938        ip->u.dv.active = 0;      ip->u.dv.active = 0;
939        ip->u.dv.value = GetBooleanAtomValue(inst);      ip->u.dv.value = GetBooleanAtomValue(inst);
940        gl_append_ptr(p_data->dvars,(POINTER)ip);      gl_append_ptr(p_data->dvars,(POINTER)ip);
941        return ip;      return ip;
     } else {  
       return NULL;  
     }  
942    case INTEGER_ATOM_INST:    case INTEGER_ATOM_INST:
943      if (WhensCount(inst)) {      if(!WhensCount(inst))return NULL;
944        ip = analyze_getip();      ip = analyze_getip();
945        ip->i = inst;      ip->i = inst;
946        ip->u.dv.isconst = 0;      ip->u.dv.isconst = 0;
947        ip->u.dv.distype = 1;      ip->u.dv.distype = 1;
948        ip->u.dv.index = 0;      ip->u.dv.index = 0;
949        ip->u.dv.incident = 0;      ip->u.dv.incident = 0;
950        ip->u.dv.booleanvar=0;      ip->u.dv.booleanvar=0;
951        ip->u.dv.fixed = 0;      ip->u.dv.fixed = 0;
952        ip->u.dv.active = 0;      ip->u.dv.active = 0;
953        ip->u.dv.value = GetIntegerAtomValue(inst);      ip->u.dv.value = GetIntegerAtomValue(inst);
954        gl_append_ptr(p_data->dvars,(POINTER)ip);      gl_append_ptr(p_data->dvars,(POINTER)ip);
955        return ip;      return ip;
     } else {  
       return NULL;  
     }  
956    case SYMBOL_ATOM_INST:    case SYMBOL_ATOM_INST:
957      if (WhensCount(inst)) {      if(!WhensCount(inst))return NULL;
958        symval = SCP(GetSymbolAtomValue(inst));      symval = SCP(GetSymbolAtomValue(inst));
959        if (symval == NULL) {      if(symval == NULL)return NULL;
960          return NULL;      ip = analyze_getip();
961        }      ip->i = inst;
962        ip = analyze_getip();      ip->u.dv.isconst = 0;
963        ip->i = inst;      ip->u.dv.distype = -1;
964        ip->u.dv.isconst = 0;      ip->u.dv.index = 0;
965        ip->u.dv.distype = -1;      ip->u.dv.incident = 0;
966        ip->u.dv.index = 0;      ip->u.dv.booleanvar=0;
967        ip->u.dv.incident = 0;      ip->u.dv.fixed = 0;
968        ip->u.dv.booleanvar=0;      ip->u.dv.active = 0;
969        ip->u.dv.fixed = 0;      if(g_symbol_values_list == NULL) {
970        ip->u.dv.active = 0;        g_symbol_values_list = gl_create(2L);
       if (g_symbol_values_list == NULL) {  
         g_symbol_values_list = gl_create(2L);  
       }  
       ip->u.dv.value = GetIntFromSymbol(symval,g_symbol_values_list);  
       gl_append_ptr(p_data->dvars,(POINTER)ip);  
       return ip;  
     } else {  
       return NULL;  
971      }      }
972        ip->u.dv.value = GetIntFromSymbol(symval,g_symbol_values_list);
973        gl_append_ptr(p_data->dvars,(POINTER)ip);
974        return ip;
975    case INTEGER_CONSTANT_INST:    case INTEGER_CONSTANT_INST:
976      if (WhensCount(inst)) {      if(!WhensCount(inst))return NULL;
977        ip = analyze_getip();      ip = analyze_getip();
978        ip->i = inst;      ip->i = inst;
979        ip->u.dv.isconst = 1;      ip->u.dv.isconst = 1;
980        ip->u.dv.distype = 1;      ip->u.dv.distype = 1;
981        ip->u.dv.index = 0;      ip->u.dv.index = 0;
982        ip->u.dv.incident = 0;      ip->u.dv.incident = 0;
983        ip->u.dv.booleanvar=0;      ip->u.dv.booleanvar=0;
984        ip->u.dv.fixed = 1;      ip->u.dv.fixed = 1;
985        ip->u.dv.active = 0;      ip->u.dv.active = 0;
986        ip->u.dv.value = GetIntegerAtomValue(inst);      ip->u.dv.value = GetIntegerAtomValue(inst);
987        gl_append_ptr(p_data->dvars,(POINTER)ip);      gl_append_ptr(p_data->dvars,(POINTER)ip);
988        return ip;      return ip;
     } else {  
       return NULL;  
     }  
989    case SYMBOL_CONSTANT_INST:    case SYMBOL_CONSTANT_INST:
990      if (WhensCount(inst)) {      if(!WhensCount(inst))return NULL;
991        symval = SCP(GetSymbolAtomValue(inst));      symval = SCP(GetSymbolAtomValue(inst));
992        if (symval == NULL) {      if(symval==NULL)return NULL;
993          return NULL;      ip = analyze_getip();
994        }      ip->i = inst;
995        ip = analyze_getip();      ip->u.dv.isconst = 1;
996        ip->i = inst;      ip->u.dv.distype = -1;
997        ip->u.dv.isconst = 1;      ip->u.dv.index = 0;
998        ip->u.dv.distype = -1;      ip->u.dv.incident = 0;
999        ip->u.dv.index = 0;      ip->u.dv.booleanvar=0;
1000        ip->u.dv.incident = 0;      ip->u.dv.fixed = 1;
1001        ip->u.dv.booleanvar=0;      ip->u.dv.active = 0;
1002        ip->u.dv.fixed = 1;      if (g_symbol_values_list == NULL) {
1003        ip->u.dv.active = 0;        g_symbol_values_list = gl_create(2L);
       if (g_symbol_values_list == NULL) {  
         g_symbol_values_list = gl_create(2L);  
       }  
       ip->u.dv.value = GetIntFromSymbol(symval,g_symbol_values_list);  
       gl_append_ptr(p_data->dvars,(POINTER)ip);  
       return ip;  
     } else {  
       return NULL;  
1004      }      }
1005        ip->u.dv.value = GetIntFromSymbol(symval,g_symbol_values_list);
1006        gl_append_ptr(p_data->dvars,(POINTER)ip);
1007        return ip;
1008    case REL_INST:               /* Relation (or conditional or objective) */    case REL_INST:               /* Relation (or conditional or objective) */
1009      ip = analyze_getip();      ip = analyze_getip();
1010      ip->i = inst;      ip->i = inst;
# Line 1017  void *classify_instance(struct Instance Line 1020  void *classify_instance(struct Instance
1020        ip->u.r.obj = 0;        ip->u.r.obj = 0;
1021        break;        break;
1022      }      }
1023      if ( GetInstanceRelationType(inst)==e_blackbox ) {      if(GetInstanceRelationType(inst)==e_blackbox){
1024        ip->u.r.ext = 1;        ip->u.r.ext = 1;
1025      } else {      }else{
1026        ip->u.r.ext = 0;        ip->u.r.ext = 0;
1027      }      }
1028      if ( RelationIsCond(GetInstanceRelationOnly(inst)) ) {      if(RelationIsCond(GetInstanceRelationOnly(inst))){
1029        ip->u.r.cond = 1;        ip->u.r.cond = 1;
1030      } else {      }else{
1031        ip->u.r.cond = 0;        ip->u.r.cond = 0;
1032      }      }
1033      if ( WhensCount(inst) ) {      if(WhensCount(inst)){
1034        ip->u.r.inwhen = 1;        ip->u.r.inwhen = 1;
1035      } else {      }else{
1036        ip->u.r.inwhen = 0;        ip->u.r.inwhen = 0;
1037      }      }
1038      ip->u.r.included = BooleanChildValue(inst,INCLUDED_A);      ip->u.r.included = BooleanChildValue(inst,INCLUDED_A);
# Line 1041  void *classify_instance(struct Instance Line 1044  void *classify_instance(struct Instance
1044      ip = analyze_getip();      ip = analyze_getip();
1045      ip->i = inst;      ip->i = inst;
1046      ip->u.lr.active = 1;      ip->u.lr.active = 1;
1047      if ( LogRelIsCond(GetInstanceLogRel(inst)) ) {      if( LogRelIsCond(GetInstanceLogRel(inst)) ) {
1048        ip->u.lr.cond = 1;        ip->u.lr.cond = 1;
1049      } else {      }else{
1050        ip->u.lr.cond = 0;        ip->u.lr.cond = 0;
1051      }      }
1052      if ( WhensCount(inst) ) {      if( WhensCount(inst) ) {
1053        ip->u.lr.inwhen = 1;        ip->u.lr.inwhen = 1;
1054      } else {      }else{
1055        ip->u.lr.inwhen = 0;        ip->u.lr.inwhen = 0;
1056      }      }
1057      ip->u.lr.included = BooleanChildValue(inst,INCLUDED_A);      ip->u.lr.included = BooleanChildValue(inst,INCLUDED_A);
# Line 1060  void *classify_instance(struct Instance Line 1063  void *classify_instance(struct Instance
1063      ip = analyze_getip();      ip = analyze_getip();
1064      ip->i = inst;      ip->i = inst;
1065      ip->u.m.index = 0;      ip->u.m.index = 0;
1066      if ( WhensCount(inst) ) {      if( WhensCount(inst) ) {
1067        ip->u.m.inwhen = 1;        ip->u.m.inwhen = 1;
1068      } else {      }else{
1069        ip->u.m.inwhen = 0;        ip->u.m.inwhen = 0;
1070      }      }
1071      gl_append_ptr(p_data->models,(POINTER)ip);      gl_append_ptr(p_data->models,(POINTER)ip);
# Line 1073  void *classify_instance(struct Instance Line 1076  void *classify_instance(struct Instance
1076      ip->u.w.index = 0;      ip->u.w.index = 0;
1077      if ( WhensCount(inst) ) {      if ( WhensCount(inst) ) {
1078        ip->u.w.inwhen = 1;        ip->u.w.inwhen = 1;
1079      } else {      }else{
1080        ip->u.w.inwhen = 0;        ip->u.w.inwhen = 0;
1081      }      }
1082      return ip;      return ip;
# Line 1093  void *classify_instance(struct Instance Line 1096  void *classify_instance(struct Instance
1096      good, so don't disable the g_bad_rel_in_list feature.      good, so don't disable the g_bad_rel_in_list feature.
1097  */  */
1098  static  static
1099  void CountStuffInTree(struct Instance *inst, struct problem_t *p_data)  void CountStuffInTree(struct Instance *inst, struct problem_t *p_data){
 {  
1100    CONST char *symval;    CONST char *symval;
1101    if (inst!=NULL) {    if (inst!=NULL) {
1102      switch (InstanceKind(inst)) {      switch (InstanceKind(inst)) {
# Line 1189  void CountStuffInTree(struct Instance *i Line 1191  void CountStuffInTree(struct Instance *i
1191    
1192    
1193  /**  /**
1194        Build 'master' lists of variables, relations, etc, from the Instance
1195        hierarchy assigned to the problem p_data.
1196    
1197      This takes the already derived counts,      This takes the already derived counts,
1198      allocates all the memory we need to allocate for master,      allocates all the memory we need to allocate for master,
1199      and builds the var/rel/MODEL/etc master lists.      and actually builds the var/rel/MODEL/etc master lists,
1200      filling in p_data and ips as far as possible.      filling in p_data and interface pointers as far as possible.
1201      Returns 0 normally, or 1 if insufficient memory, 2 if nothing to do.  
1202      If 1, then the user should deallocate any partial results in      In particular, after this is done we have:
1203      a separate cleanup function for p_data->  
1204          - vars with correct ip values for:
1205      In particular, after this is done we have           - index
1206      vars with correct ip values for:           - incident
1207      index;           - in_block
1208       incident;           - fixed (as flag)
1209       in_block;           - basis (as flag)
1210       fixed; (as flag)           - solvervar (as flag)
1211       basis;      (as flag)        - relations and conditional relations with correct ip values for:
1212       solvervar; (as flag)           - index
1213      relations and conditional relations with correct ip values for:           - model
1214       index;           - obj (0 constraint, -1 maximize, +1 minimize)
1215       model;           - ext
1216       obj;       (0 constraint, -1 maximize, +1 minimize)           - inwhen
1217       ext;           - cond
1218       inwhen;           - included (as flag)
1219       cond;        - discrete vars with correct ip values for:
1220       included;  (as flag)           - index
1221      discrete vars with correct ip values for:           - incident
1222       index;           - isconst
1223       incident;           - distype
1224       isconst;           - fixed (as flag)
1225       distype;           - booleanvar (as flag)
1226       fixed; (as flag)           - inwhen
1227       booleanvar;    (as flag)        - logrelations and conditional logrelations with correct ip values for:
1228       inwhen;           - index
1229      logrelations and conditional logrelations with correct ip values for:           - model
1230       index;           - included (as flag)
1231       model;           - inwhen
1232       included;  (as flag)           - cond
1233       inwhen;        - whens with correct ip values for:
1234       cond;           - index
1235      whens with correct ip values for:           - model
1236       index;           - inwhen
1237       model;        - models with correct ip values for:
1238       inwhen;           - index
1239      models with correct ip values for:  
1240       index;      Note that these are all indexed from 1, being stored in gl_list structs (groan).
1241    
1242        @param p_data partial problem definition, include Instance pointer and master list lengths assumed already computed.
1243    
1244      Note that these are all indexed from 1, being stored in gllists.      @return 0 on success, 1 on insufficient memory (user should deallocate any partial results in
1245        a separate cleanup function for p_data->), 2 if nothing to do.
1246  */  */
1247  static int analyze_make_master_lists(struct problem_t *p_data){  static
1248    int analyze_make_master_lists(struct problem_t *p_data){
1249    
1250    long int c, len,v,vlen;    long int c, len,v,vlen;
1251    CONST struct Instance *i;    CONST struct Instance *i;
1252    CONST struct relation *gut;    CONST struct relation *gut;
# Line 1341  static int analyze_make_master_lists(str Line 1351  static int analyze_make_master_lists(str
1351      invariant with hardware and ascend invocation so long as      invariant with hardware and ascend invocation so long as
1352      set FIRSTCHOICE holds in compilation.      set FIRSTCHOICE holds in compilation.
1353    */    */
1354    /* mark vars in constraints incident  and index rels */    /* mark vars in constraints incident and index rels */
1355    len = gl_length(p_data->rels);    len = gl_length(p_data->rels);
1356    for (c=1; c <= len; c++) {    for (c=1; c <= len; c++) {
1357      SIP(gl_fetch(p_data->rels,c))->u.r.index = c;      SIP(gl_fetch(p_data->rels,c))->u.r.index = c;
# Line 1523  static int analyze_make_master_lists(str Line 1533  static int analyze_make_master_lists(str
1533  }  }
1534    
1535  /**  /**
1536       This function cleans up an errant problem_t or a good one that we're      This function cleans up an errant problem_t or a good one that we're
1537       done with. We should have set to null any pointers to memory we are      done with. We should have set to null any pointers to memory we are
1538       keeping elsewhere before calling this.      keeping elsewhere before calling this.
1539  */  */
1540  static void analyze_free_lists(struct problem_t *p_data)  static
1541  {  void analyze_free_lists(struct problem_t *p_data){
1542    
1543    /* memory containing gl_lists of atomic structure pointers */    /* memory containing gl_lists of atomic structure pointers */
1544    /* if(p_data->extrels != NULL)gl_free_and_destroy(p_data->extrels); */    /* if(p_data->extrels != NULL)gl_free_and_destroy(p_data->extrels); */
1545    if(p_data->extrels!=NULL)gl_destroy(p_data->extrels); /* -- JP HACK */    if(p_data->extrels!=NULL)gl_destroy(p_data->extrels); /* -- JP HACK */
# Line 1614  static void analyze_free_lists(struct pr Line 1625  static void analyze_free_lists(struct pr
1625      which will be equivalent to a symbol value      which will be equivalent to a symbol value
1626  */  */
1627  static  static
1628  void ProcessValueList(struct Set *ValueList, int *value,  void ProcessValueList(struct Set *ValueList, int *value
1629                struct gl_list_t *symbol_list)          ,struct gl_list_t *symbol_list
1630  {  ){
1631    CONST struct Expr *expr;    CONST struct Expr *expr;
1632    struct Set *s;    struct Set *s;
1633    
# Line 1655  void ProcessValueList(struct Set *ValueL Line 1666  void ProcessValueList(struct Set *ValueL
1666      @see ProcessSolverWhens      @see ProcessSolverWhens
1667  */  */
1668  static  static
1669  void ProcessArraysInWhens(struct Instance *cur_inst,  void ProcessArraysInWhens(struct Instance *cur_inst
1670                struct gl_list_t *rels,          ,struct gl_list_t *rels
1671                struct gl_list_t *logrels,          ,struct gl_list_t *logrels
1672                struct gl_list_t *whens)          ,struct gl_list_t *whens
1673  {  ){
1674    struct rel_relation *rel;    struct rel_relation *rel;
1675    struct logrel_relation *lrel;    struct logrel_relation *lrel;
1676    struct w_when *w;    struct w_when *w;
# Line 1713  void ProcessArraysInWhens(struct Instanc Line 1724  void ProcessArraysInWhens(struct Instanc
1724      @see ProcessSolverWhens      @see ProcessSolverWhens
1725  */  */
1726  static  static
1727  void ProcessModelsInWhens(struct Instance *cur_inst, struct gl_list_t *rels,  void ProcessModelsInWhens(struct Instance *cur_inst, struct gl_list_t *rels
1728                struct gl_list_t *logrels, struct gl_list_t *whens)          ,struct gl_list_t *logrels, struct gl_list_t *whens
1729  {  ){
1730    struct rel_relation *rel;    struct rel_relation *rel;
1731    struct logrel_relation *lrel;    struct logrel_relation *lrel;
1732    struct w_when *w;    struct w_when *w;
# Line 1782  void ProcessModelsInWhens(struct Instanc Line 1793  void ProcessModelsInWhens(struct Instanc
1793      functions.      functions.
1794  */  */
1795  static  static
1796  void ProcessSolverWhens(struct w_when *when,struct Instance *i)  void ProcessSolverWhens(struct w_when *when,struct Instance *i){
1797  {  
1798    struct gl_list_t *scratch;    struct gl_list_t *scratch;
1799    struct gl_list_t *wvars;    struct gl_list_t *wvars;
1800    struct gl_list_t *ref;    struct gl_list_t *ref;
# Line 1885  void ProcessSolverWhens(struct w_when *w Line 1896  void ProcessSolverWhens(struct w_when *w
1896          1 if discrete var is a member of the when var list,          1 if discrete var is a member of the when var list,
1897          else 0          else 0
1898  */  */
1899  int dis_var_in_a_when(struct Instance *var, struct w_when *when)  int dis_var_in_a_when(struct Instance *var, struct w_when *when){
 {  
1900    struct Instance *winst;    struct Instance *winst;
1901    
1902    winst = (struct Instance *)(when_instance(when));    winst = (struct Instance *)(when_instance(when));
# Line 1898  int dis_var_in_a_when(struct Instance *v Line 1908  int dis_var_in_a_when(struct Instance *v
1908      Determine if the conditional variable inst is part of the      Determine if the conditional variable inst is part of the
1909      variable list of some when in the when list.      variable list of some when in the when list.
1910  */  */
1911  int varinst_found_in_whenlist(slv_system_t sys, struct Instance *inst)  int varinst_found_in_whenlist(slv_system_t sys, struct Instance *inst){
 {  
1912    struct w_when **whenlist;    struct w_when **whenlist;
1913    struct w_when *when;    struct w_when *when;
1914    int c;    int c;
# Line 1924  int varinst_found_in_whenlist(slv_system Line 1933  int varinst_found_in_whenlist(slv_system
1933      side and make the same link in the solver side      side and make the same link in the solver side
1934  */  */
1935  static  static
1936  void GetListOfLogRels(struct bnd_boundary *bnd, struct Instance *inst)  void GetListOfLogRels(struct bnd_boundary *bnd, struct Instance *inst){
 {  
1937    struct gl_list_t *logrels;    struct gl_list_t *logrels;
1938    unsigned long c,len;    unsigned long c,len;
1939    struct Instance *i;    struct Instance *i;
# Line 1952  void GetListOfLogRels(struct bnd_boundar Line 1960  void GetListOfLogRels(struct bnd_boundar
1960      (Defined in the SATISFIED term)      (Defined in the SATISFIED term)
1961  */  */
1962  static  static
1963  void GetTolerance(struct bnd_boundary *bnd)  void GetTolerance(struct bnd_boundary *bnd){
 {  
1964    struct gl_list_t *logrels;    struct gl_list_t *logrels;
1965    unsigned long c,len;    unsigned long c,len;
1966    struct logrel_relation *lrel;    struct logrel_relation *lrel;
# Line 1982  void GetTolerance(struct bnd_boundary *b Line 1989  void GetTolerance(struct bnd_boundary *b
1989      @returns 0 on success, 1 on out-of-memory, or 2 if the problem does not      @returns 0 on success, 1 on out-of-memory, or 2 if the problem does not
1990      contain at least one variable in one equation      contain at least one variable in one equation
1991  */  */
1992  static int analyze_make_solvers_lists(struct problem_t *p_data)  static
1993  {  int analyze_make_solvers_lists(struct problem_t *p_data){
1994    CONST struct relation *gut;    CONST struct relation *gut;
1995    CONST struct logrelation *lgut;    CONST struct logrelation *lgut;
1996  #ifdef DIEDIEDIE  #ifdef DIEDIEDIE
# Line 2120  static int analyze_make_solvers_lists(st Line 2127  static int analyze_make_solvers_lists(st
2127      if (!(dvip->u.dv.fixed)) p_data->logncol++;      if (!(dvip->u.dv.fixed)) p_data->logncol++;
2128    }    }
2129    
   
2130    /* now malloc and build things, remember to punt the matrix soon */    /* now malloc and build things, remember to punt the matrix soon */
2131    /* remember we must NEVER free these things individually. */    /* remember we must NEVER free these things individually. */
2132    
2133  #define ALLOCVARDATA(p,n) (p) = (struct var_variable *)( \  #define ALLOCVARDATA(p,n)    (p)=((n)>0 ? ASC_NEW_ARRAY(struct var_variable,n) : (struct var_variable *)NULL)
2134      ((n)>0) ? ascmalloc((n)*sizeof(struct var_variable)) : NULL)  #define ALLOCRELDATA(p,n)    (p)=((n)>0 ? ASC_NEW_ARRAY(struct rel_relation,n) : (struct rel_relation *)NULL)
2135  #define ALLOCRELDATA(p,n) (p) = (struct rel_relation *)( \  #define ALLOCDISVARDATA(p,n) (p)=((n)>0 ? ASC_NEW_ARRAY(struct dis_discrete,n) : (struct dis_discrete *)NULL)
2136      ((n)>0) ? ascmalloc((n)*sizeof(struct rel_relation)) : NULL)  #define ALLOCLOGRELDATA(p,n) (p)=((n)>0 ? ASC_NEW_ARRAY(struct logrel_relation,n) : (struct logrel_relation *)NULL)
2137  #define ALLOCDISVARDATA(p,n) (p) = (struct dis_discrete *)( \  #define ALLOCWHENDATA(p,n)   (p)=((n)>0 ? ASC_NEW_ARRAY(struct w_when,n)       : (struct w_when *)NULL)
2138      ((n)>0) ? ascmalloc((n)*sizeof(struct dis_discrete)) : NULL)  #define ALLOCBNDDATA(p,n)    (p)=((n)>0 ? ASC_NEW_ARRAY(struct bnd_boundary,n) : (struct bnd_boundary *)NULL)
2139  #define ALLOCLOGRELDATA(p,n) (p) = (struct logrel_relation *)( \  
     ((n)>0) ? ascmalloc((n)*sizeof(struct logrel_relation)) : NULL)  
 #define ALLOCWHENDATA(p,n) (p) = (struct w_when *)( \  
     ((n)>0) ? ascmalloc((n)*sizeof(struct w_when)) : NULL)  
 #define ALLOCBNDDATA(p,n) (p) = (struct bnd_boundary *)( \  
     ((n)>0) ? ascmalloc((n)*sizeof(struct bnd_boundary)) : NULL)  
2140    ALLOCVARDATA(p_data->vardata,p_data->nv);    ALLOCVARDATA(p_data->vardata,p_data->nv);
2141    ALLOCVARDATA(p_data->pardata,p_data->np);    ALLOCVARDATA(p_data->pardata,p_data->np);
2142    ALLOCVARDATA(p_data->undata,p_data->nu);    ALLOCVARDATA(p_data->undata,p_data->nu);
# Line 2149  static int analyze_make_solvers_lists(st Line 2150  static int analyze_make_solvers_lists(st
2150    ALLOCWHENDATA(p_data->whendata,p_data->nw);    ALLOCWHENDATA(p_data->whendata,p_data->nw);
2151    ALLOCBNDDATA(p_data->bnddata,p_data->nc+p_data->ncl);    ALLOCBNDDATA(p_data->bnddata,p_data->nc+p_data->ncl);
2152    
2153  #define ALLOCVARLIST(p,n) (p) = (struct var_variable **)( \  #define ALLOCVARLIST(p,n) (p)=((n)>0 ? ASC_NEW_ARRAY(struct var_variable*,n) :(struct var_variable **)NULL)
2154    ((n)>0) ? ascmalloc((n)*sizeof(struct var_variable *)) : NULL)  #define ALLOCRELLIST(p,n) (p)=((n)>0 ? ASC_NEW_ARRAY(struct rel_relation*,n) :(struct rel_relation **)NULL)
2155  #define ALLOCRELLIST(p,n) (p) = (struct rel_relation **)( \  #define ALLOCDISVARLIST(p,n) (p)=((n)>0 ? ASC_NEW_ARRAY(struct dis_discrete*,n) : (struct dis_discrete **)NULL)
2156      ((n)>0) ? ascmalloc((n)*sizeof(struct rel_relation *)) : NULL)  #define ALLOCLOGRELLIST(p,n) (p)=((n)>0 ? ASC_NEW_ARRAY(struct logrel_relation*,n) : (struct logrel_relation **)NULL)
2157  #define ALLOCDISVARLIST(p,n) (p) = (struct dis_discrete **)( \  #define ALLOCWHENLIST(p,n)(p)=((n)>0 ? ASC_NEW_ARRAY(struct w_when*,n)       :(struct w_when **)NULL)
2158    ((n)>0) ? ascmalloc((n)*sizeof(struct dis_discrete *)) : NULL)  #define ALLOCBNDLIST(p,n) (p)=((n)>0 ? ASC_NEW_ARRAY(struct bnd_boundary*,n) :(struct bnd_boundary **)NULL)
2159  #define ALLOCLOGRELLIST(p,n) (p) = (struct logrel_relation **)( \  
     ((n)>0) ? ascmalloc((n)*sizeof(struct logrel_relation *)) : NULL)  
 #define ALLOCWHENLIST(p,n) (p) = (struct w_when **)( \  
     ((n)>0) ? ascmalloc((n)*sizeof(struct w_when *)) : NULL)  
 #define ALLOCBNDLIST(p,n) (p) = (struct bnd_boundary **)( \  
     ((n)>0) ? ascmalloc((n)*sizeof(struct bnd_boundary *)) : NULL)  
2160    ALLOCVARLIST(p_data->mastervl,p_data->nv+1);    ALLOCVARLIST(p_data->mastervl,p_data->nv+1);
2161    ALLOCVARLIST(p_data->masterpl,p_data->np+1);    ALLOCVARLIST(p_data->masterpl,p_data->np+1);
2162    ALLOCVARLIST(p_data->masterul,p_data->nu+1);    ALLOCVARLIST(p_data->masterul,p_data->nu+1);
# Line 2189  static int analyze_make_solvers_lists(st Line 2185  static int analyze_make_solvers_lists(st
2185    ALLOCVARLIST(p_data->relincidence,p_data->nnztot+p_data->nnzobj +    ALLOCVARLIST(p_data->relincidence,p_data->nnztot+p_data->nnzobj +
2186             p_data->nnzcond);             p_data->nnzcond);
2187    ALLOCDISVARLIST(p_data->logrelinciden,p_data->lrelincsize);    ALLOCDISVARLIST(p_data->logrelinciden,p_data->lrelincsize);
2188    
2189      /* verify mem allocations. */
2190  #define CHECKPTRSIZE(n,p) if ((n)>0 && (p)==NULL) return 1  #define CHECKPTRSIZE(n,p) if ((n)>0 && (p)==NULL) return 1
2191  #define CHECKPTR(p) if ((p)==NULL) return 1  #define CHECKPTR(p) if ((p)==NULL) return 1
2192    /* verify mem allocations. */  
2193    CHECKPTRSIZE(p_data->nv,p_data->vardata);    CHECKPTRSIZE(p_data->nv,p_data->vardata);
2194    CHECKPTRSIZE(p_data->np,p_data->pardata);    CHECKPTRSIZE(p_data->np,p_data->pardata);
2195    CHECKPTRSIZE(p_data->nu,p_data->undata);    CHECKPTRSIZE(p_data->nu,p_data->undata);
# Line 2252  static int analyze_make_solvers_lists(st Line 2250  static int analyze_make_solvers_lists(st
2250      var_set_sindex(var,v);      var_set_sindex(var,v);
2251      flags = 0; /* all init to FALSE */      flags = 0; /* all init to FALSE */
2252      /* turn on appropriate ones */      /* turn on appropriate ones */
2253      if (vip->u.v.incident)  flags |= VAR_INCIDENT;      if(vip->u.v.incident)  flags |= VAR_INCIDENT;
2254      if (vip->u.v.in_block)  flags |= VAR_INBLOCK;      if(vip->u.v.in_block)  flags |= VAR_INBLOCK;
2255      if (vip->u.v.fixed)     flags |= VAR_FIXED;      if(vip->u.v.fixed)     flags |= VAR_FIXED;
2256      if (!vip->u.v.basis)    flags |= VAR_NONBASIC;      if(!vip->u.v.basis)    flags |= VAR_NONBASIC;
2257      if (vip->u.v.solvervar) flags |= VAR_SVAR;      if(vip->u.v.solvervar) flags |= VAR_SVAR;
2258        if(vip->u.v.deriv > 1) flags |= VAR_DERIV;
2259      /* CONSOLE_DEBUG("VAR %p IS IN BLOCK",var); */      /* CONSOLE_DEBUG("VAR %p IS IN BLOCK",var); */
2260      var_set_flags(var,flags);      var_set_flags(var,flags);
2261      p_data->mastervl[v] = var;      p_data->mastervl[v] = var;
# Line 2891  static int analyze_make_solvers_lists(st Line 2890  static int analyze_make_solvers_lists(st
2890    
2891  */  */
2892  static  static
2893  int analyze_configure_system(slv_system_t sys,struct problem_t *p_data)  int analyze_configure_system(slv_system_t sys,struct problem_t *p_data){
2894  {  
2895    slv_set_var_buf(sys,p_data->vardata);    slv_set_var_buf(sys,p_data->vardata);
2896    p_data->vardata = NULL;    p_data->vardata = NULL;
2897    slv_set_par_buf(sys,p_data->pardata);    slv_set_par_buf(sys,p_data->pardata);
# Line 3016  int analyze_configure_system(slv_system_ Line 3015  int analyze_configure_system(slv_system_
3015      errors -- in particular because we must leave the interface ptrs      errors -- in particular because we must leave the interface ptrs
3016      in the state they were found.      in the state they were found.
3017  */  */
3018  int analyze_make_problem(slv_system_t sys, struct Instance *inst)  int analyze_make_problem(slv_system_t sys, struct Instance *inst){
 {  
3019    int stat;    int stat;
3020    struct problem_t thisproblem; /* need to malloc, free, or make &local */  
3021      struct problem_t thisproblem; /* note default zero intitialisation. note also: local var! */
3022    struct problem_t *p_data; /* need to malloc, free, or make &local */    struct problem_t *p_data; /* need to malloc, free, or make &local */
3023    
3024    INCLUDED_A = AddSymbolL("included",8);    INCLUDED_A = AddSymbolL("included",8);
3025    FIXED_A = AddSymbolL("fixed",5);    FIXED_A = AddSymbolL("fixed",5);
3026    BASIS_A = AddSymbolL("basis",5);    BASIS_A = AddSymbolL("basis",5);
3027      DERIV_A = AddSymbol("ode_type");
3028    
3029    p_data = &thisproblem;    p_data = &thisproblem;
3030    g_bad_rel_in_list = FALSE;    g_bad_rel_in_list = FALSE;
# Line 3071  int analyze_make_problem(slv_system_t sy Line 3072  int analyze_make_problem(slv_system_t sy
3072    
3073  extern void analyze_free_reused_mem(void){  extern void analyze_free_reused_mem(void){
3074    resize_ipbuf((size_t)0,0);    resize_ipbuf((size_t)0,0);
   /* analyze_free_lists(); */  
3075  }  }
3076    
3077    /* @} */

Legend:
Removed from v.1067  
changed lines
  Added in v.1068

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