/*
 Copyright (C) Andrew Wuensche
 
 This file is part of DDLab (Discrete Dynamics Lab) <www.ddlab.org> 
 DDLab is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with DDLab.  If not, see <http://www.gnu.org/licenses/>.
 */

/************ capara, select ca parameters *********************/
#include "edecfunc.h"
#include <ctype.h>
/***************  list of functions in this file *************/
/*void select_linelength_singlebasin(void)*/
/*void select_linelength_31(void)*/
/*void select_linelength_range(void)*/
/*void select_nhood_size(char inbox)*/
void set_dif_nhoods(void);
/*void draw_k_hist(char in_out);*/
/*void nhood_lb_ub(void)*/
/*void load_nhoodmix(void)*/
/*void select_totalistic(void)*/
signed int setup_nhood_matrix(char amend);
void post_samples(signed int tablemax,
                  signed int tablebytes,
                  signed int t_codemax,signed int t_codebytes,
		  signed int v_codemax,signed int v_codebytes);
void restrict_post(void);
/*char post_func(char nhoodz, char *thisrule,
  char details, char box,signed int fid, char filedata)*/

/*-------------------------------------------------------------*/
/*signed int rule_selection(void)*/
void shift_outputs_unanimous(char *thisrule,signed int this_tablemax, 
			     signed int thisnhood,signed int poss);
char select_forcezero(char totalistic);
unsigned char set_canal_color(char just_this_k,
		  unsigned int canaltotal,char this_k);
/*void set_canalyzing_net(char forcezero)*/
/*void set_canalyzing_rule(unsigned int poss)*/
char reselect_rule_prompts(signed int cellindex,char select,unsigned long rule_dec_max);
char accept_rule_method(char select,unsigned long this_dec_max,char tnhood);
signed int reselect_rule_index(signed int cellindex,signed int number_rules);
/*-------------------------------------------------------------*/
signed int select_rule(char inbox,char one_cell,char** thisrule,
               signed int number_rules,unsigned int poss,char forcezero);

/*unsigned long max_dec_rule(signed int tablemax, 
                                   char tvalue_range)*/
/*void chain_rule(char *thisrule, char thisnhood, 
        signed int tablemax, unsigned int cindex)*/
/*void altenberg_rule(char *thisrule, char thisnhood, 
                                   signed int tablemax)*/
void set_reaction_diffusion_rule(char *thisrule, char thisnhood, 
				 signed int tablemax);
void game_of_Life_para(char which, char thisnhood);
void game_of_Life_rule(char *thisrule, char thisnhood, 
                       signed int tablemax);
void game_of_Life_kcode(char *thiskcode, char thisnhood, 
			signed int kcodemax, char center_value);
/*void majority_rule(char *thisrule, char thisnhood, 
                                    signed int tablemax);*/
/*void isotropic_rule(char show_details, char *thisrule, char thisnhood, 
     signed int start_index,signed int end_index,
                signed int tablemax,char do_what);*/
void iso_Hensel_setup(signed int set_count,signed int ccindex,
	  signed int *group_types, unsigned char *pattern_types, signed int **Hensel_group_matrix);
void assign_Hensel_matrix(char birth_survival,
		    unsigned char **birth_or_survival_matrix,unsigned char *Hensel_string,
		    unsigned char hensel_range[10],unsigned char labels_array[15],
		    unsigned char numbers_array[10],unsigned char start_pos,unsigned char end_pos);
/*char transform_rule(unsigned int cellindex)*/
void complementary_transformation(char *xrule,
                           signed int xtablebytes,signed int xtablemax);
void negative_transformation(char *xrule,
			     signed int xtablebytes,signed int xtablemax);
void reflection_transformation(char *xrule, char xnhood,
			   signed int xtablebytes,signed int xtablemax);

void reduce_max_k(void);
char loadlast_rule_tcode_vcode(char *thisrule,char tnhood,
		  signed int thistablemax,unsigned int cposs);

/*-------------------------------------------------------------*/
signed int select_t_v_code(char inbox,char one_cell,char** thiscode,
      char** thisrule,signed int number_rules,unsigned int poss,char forcezero);

void majority_tcode(char *thistcode, char thisnhood, 
                                 signed int tablemax);
/*void altenberg_kcode(char *thiskcode, char thisnhood, 
                                 signed int tablemax);*/
void set_reaction_diffusion_outer(char ex_color, char *thiskcode, 
		      char thisnhood, signed int tablecodemax);

/*void code2rule(char *ruletable, char *codetable, char this_nhood)*/
/*void majority_or_fprintf_vcode(char majority,
                            char *codetable,char this_nhood);*/
void swap_values_vcode(char *codetable, char this_nhood);
void fprintf_vcode(char code_lay, char *codetable, char this_nhood);
void v_code2rule(char *ruletable, char *codetable,char this_nhood, char c2r);
/*void revise_rule_or_code(unsigned int thisposs)*/

/*-------------------------------------------------------------*/
/*signed int select_seed(char box_top_only, 
                   char* thisseed, char *text, char restore_box)*/
/*void check_wiring_still_local(void)*/
/*void set_cellscale(char nhoodz, char isrule)*/


unsigned long Post_total_i, Post_total_3, Post_total_2; /*Post classes*/

/*for game of life*/
signed int *survival,*birth;
char *totv, *winv, empty_center;
signed int centrec,outer_k,count_birth,count_survival;
signed int Ltempx,Ltempy;

signed int iso_x,iso_y; //to clear space for isotropic ruletable jan2020
 
/******** specify line length for single basin, 13 May 1993 **************/
         /*or forwards only, or TFO-mode (Totalist Forwards Only)*/
void select_linelength_singlebasin(void){
  signed int def_L;
  signed long this_lineL;
  signed int tempx,tempy,xbox;
  unsigned int this_limit;

   if (exLimit==0) this_limit=maxL_lu; //=Maxu/512
   else this_limit=Maxu;
   if (tot_only==1) def_L=150;
   else def_L=14;

   tempx=getx;
   tempy=gety; 
   xbox=draw_prompt_box(2);   
   if (tot_only==1) sprintf(textb[0],
      "TFO-mode: network size n: safe<=%d, nLimit=%u",
		   Max_ushort,this_limit);
   else sprintf(textb[0],
      "SEED-mode: network size n: safe<=%d, nLimit=%u",
		   Max_ushort,this_limit);
   outtext(textb[0]);
   moveto(xbox, gety+CHeight);
   setcolor(lightred);
   outtext(" increase with caution!");
   setcolor(white);
   outtext(" can be reset in WIRING for 1/2/3d, rnd/special");
   moveto(tempx,tempy);
      
   sprintf(textb[0],"Network size n, 1d (other: see WIRING), def %i:",def_L);
   next_line(xtext,1);
   outtext(textb[0]);
   sprintf(textb[1],"%u",this_limit);
   input_string(strlen(textb[1]),1);
   
   /*32 bit: max unsigned int=65535
     64 bit: max unsigned int=4294967295*/
   this_lineL=atol(is);
   if (is[0]==13) lineL = def_L;
   else if (this_lineL<1 || this_lineL > this_limit){
        lineL = def_L;
        setcolor(lightred);
        sprintf(textb[0]," too big! limit=%u! n=%d",this_limit,def_L);
        outtext(textb[0]);
        setcolor(white); 
   }
   else lineL=(unsigned int) this_lineL;

   L=lineL-1;  /*lineL gives actual line length*/
	       /*L is max array index, ie.*/
	       /*L,L-1,L-2, . . . . . . . . . . .,3,2,1,0*/
   /*no of bytes required to contain lineL bits*/
   bytesL=(signed int)ceil(((double)(value_bits*lineL))/8);
   erase_prompt_box(2);
}

/******** specify line length for basin field, 26 June 1993 **************/
void select_linelength_31(void){  
  signed int defaultL;
  signed int tempx,tempy,xbox;

   tempx=getx;
   tempy=gety;
   xbox=draw_prompt_box(2);
   
   sprintf(textb[0],
      "FIELD-mode: network size n: safe<=%d, nLimit=%d",
		   (maxLu32*2)/3,maxL_lu);   
   outtext(textb[0]);
   moveto(xbox, gety+CHeight); 
   sprintf(textb[0],"exceed safe with caution!");
   setcolor(lightred); 
   outtext(textb[0]);
   setcolor(white);
   moveto(tempx,tempy);


   if (value_range==2) defaultL=10;
   else if (value_range==3) defaultL=7;
   else if (value_range==4) defaultL=6;
   else if (value_range==5) defaultL=5;
   else if (value_range==6) defaultL=5;
   else if (value_range==7) defaultL=4;
   else if (value_range==8) defaultL=4;
   sprintf(textb[0],"Network size n, limit %d, default %d:",
                      maxL_lu,defaultL);
   
   next_line(xtext,1);
   outtext(textb[0]);
   input_string(2,1);
   if (is[0]=='q') return;
   lineL=atoi(is);
   if (is[0]==13){ 
        lineL = defaultL;
        /*sprintf(textb[0]," n=%d",defaultL);
	  outtext(textb[0]);*/
   }
   else if (lineL<1 || lineL > maxL_lu){ 
        lineL = defaultL;
        sprintf(textb[0]," too big! n=%d",defaultL);
        setcolor(lightred);
        outtext(textb[0]);
        setcolor(white);
   }
 
   L=lineL-1;  /*lineL gives actual line length*/
	       /*L is max array index, ie.*/
	       /*L,L-1,L-2, . . . . . . . . . . .,3,2,1,0*/
   /*no of bytes required to contain lineL bits*/
   bytesL=(signed int)ceil(((double)(value_bits*lineL))/8);
   erase_prompt_box(2);   
}

/******************** specify range of network size, Aug 1993 **************/
void select_linelength_range(void){
  char dstartL,dendL,string_length;
  signed int tempx,tempy,xbox,range_reduce=1;
      
   tempx=getx;
   tempy=gety;
   if (basinfield){
      dstartL=maxLu32/5;
      dendL=maxLu32/2;
   }
   else{
      dstartL=defMaxk; //5;
      dendL=defMaxk+5; //12;
   }
   xbox=draw_prompt_box(2);
   
   if (basinfield) sprintf(textb[0],
       "FIELD-mode range n: safe<=%d",maxLu32*2/3);
   else{
       sprintf(textb[0], "SEED-mode range n: safe<=%d",defMaxk*2+1);
       range_reduce=64;
   }
   outtext(textb[0]);
   setcolor(lightred);
   outtext(" exceed with caution!");
   setcolor(white);
   //sprintf(textb[0]," nLimit=%d",maxL_lu);
   sprintf(textb[0]," nLimit=%d",maxL_lu/range_reduce);
   outtext(textb[0]);
   sprintf(textb[0],"%d",maxL_lu/range_reduce);
   string_length=strlen(textb[0]);
   /*fprintf(stderr,"\n exLimit==%d: (%u %u) maxL_lu=%u",
     exLimit,Maxu/512,Maxu,maxL_lu);*/
   
   moveto(xbox,gety+CHeight);

   sprintf(textb[0],"range size: start (def %d):",dstartL);
   outtext(textb[0]);
   input_string(string_length,1);
   if (is[0]=='q') goto skip;
   startL=atoi(is);
   if (is[0]==13 || lineL > maxL_lu || startL<1) startL = dstartL;
   if (startL>=dendL){ 
     if (startL<maxL_lu) dendL=dstartL+1;
     else dendL=startL;
   }
   sprintf(textb[0]," end (def %d):",dendL);
   outtext(textb[0]);
   input_string(string_length,1);
   if (is[0]=='q') goto skip;
   endL=atoi(is);

   if (is[0]==13 || endL > maxL_lu) endL = dendL;
   moveto(tempx,tempy);
   setcolor(lightred); 
   if (endL<=startL){ 
       rangeL=0; /*cancel range, revert to one size only*/      
       outtext(" range cancelled");                    
   }
   else{
       sprintf(textb[0]," range %d to %d",startL,endL);
       outtext(textb[0]);
   }
    setcolor(white);
   /*no of bytes required to contain lineL bits*/
   lineL=startL;
   L=lineL-1;
   bytesL=(signed int)ceil(((double)(value_bits*lineL))/8);
  skip:
   erase_prompt_box(2);
   moveto(tempx,tempy);
}

/**** select size of neighborhood 1-Maxnhood, 13 May 1993, rev Dec 93 *******/
void select_nhood_size(char inbox){
 unsigned int z;
 signed int tempx,tempy;

   /* for 3d the max nhood defined at present is 13 */
   /*if (threed){ //no longer limited
       if (Maxnhood>13) Maxnhood=13;
   }*/
   iso_tablemax=0;//to keep track if isotropic_rule(...) was activated
 
   setcolor(white);
   if (!inbox) next_line(xtext,1);

   nhood_mixed=0;//this line was missing, caused k=0 after backtrack is mix was set*/ 
   if ((nhoodm=(char *)calloc(lineL,sizeof(char)))
				   ==NULL) outof_memory("nhoodm");
   if (nhood==0) nhood=3;
   if (nhood>Maxnhood) nhood=Maxnhood;
   nhood_lb=nhood_ub=nhood;

   if (!inbox){
      tempx=getx;
      tempy=gety; 
      draw_prompt_box(1);   
      outtext("k and kmix can be reset in WIRING for 1/2/3d, rnd/special");
      moveto(tempx,tempy);
   }

   sprintf(textb[0],
      "Neighborhood size k: kmix-m, or enter 1-%d (def %d):",
	                                         Maxnhood,nhood);
   if (!inbox){
      setfillstyle(SOLID_FILL,black);
      bar(getx,gety+2,getx+textwidth(textb[0])+vgax(20),
					    gety+CHeight);
   }
   else draw_prompt_box(1);
   outtext(textb[0]);
   input_string(2,0);
   // if (!inbox) erase_prompt_box(1);
   if (inbox) erase_prompt_box(1);

   if (is[0]=='m') set_dif_nhoods();
   if (is[0]=='q'){
     /*if (!inbox) setpback_x_lines(1);*/
      return;
   }
   else if (is[0]==13); /*do nout*/
   else if (atoi(is)<1 || atoi(is)>Maxnhood){
      sprintf(textb[0]," too big! k=%d",nhood);
      setcolor(lightred); 
      outtext(textb[0]);
      setcolor(white);
      input_string(1,0);
   }
   else nhood=atoi(is); 
   if (!nhood_mixed){
      for (z=0; z<=lineL-1;z++) nhoodm[z]=nhood;
      //if (z%1000==0) fprintf(stderr," %u",z);
      nhood_lb=nhood_ub=nhood;
   }
}

/**************** set different neighbourhood sizes **************/
void set_dif_nhoods(void){
 float *k_mix_percent,tot_percent_left;
 unsigned int *k_count,
                *shuffled_poss,temp_shuffle,temp_poss,check_tot,
                *k_mix_no,z,zz,k_tot,k_mix_tot,
                tempL,startindex,poss,endposs;
 char shuffle,*nhoodm_temp,maxk;
 signed int valid_k,rows,tempx,tempy,xbox;
 char indexjump=0,temp_ub;
 unsigned char tempcolor;
 float av_k;
 unsigned long tot_wires;
		
   tempx=getx;
   tempy=gety;
   erase_prompt_box(2);

   nhood_mixed=1;

  startm:
   for (poss=0;poss<=lineL-1;poss++) nhoodm[poss]=0;
   tempL=lineL;
   nhood_lb=1;
   nhood_ub=Maxnhood;
   draw_prompt_box(1);
   if (lineL>=Maxnhood) outtext(
        "set k-mix: load-l hand-h norm-n power/specify-s rnd-(def):");
   else outtext(
        "set k-mix: load-l hand-h specify-s rnd-(def):");
  
   input_string(1,0);
   if (lineL<Maxnhood){
     if (is[0]=='n') is[0]=13;
   }
   if (is[0]=='q'){
      moveto(tempx,tempy);
      return;
   }
   if (is[0]=='l'){      
      load_nhoodmix();      
      if (is[0]=='q') goto startm;
   }

   else if (is[0]=='h'){
     char rest_rand=0;
      for (poss=0;poss<=lineL-1;poss++){
         if (rest_rand==0){
	    draw_prompt_box(1);
	    sprintf(textb[0],
	       "set nhood size (1-%d) at cell %d (back-b restrnd-r):",Maxnhood,poss);
	    outtext(textb[0]);
	    input_string(2,0);
	    if (is[0]=='q') goto startm;
	    if (is[0]=='b'){
	       if (poss>0) poss-=2;
	    }
            if (is[0]=='r') rest_rand=1; 
	    if (atoi(is)>=1 && atoi(is)<=Maxnhood) nhoodm[poss]=atoi(is);
	    else nhoodm[poss]=myrand()%(Maxnhood+1);
	 }
         else nhoodm[poss]=myrand()%(Maxnhood+1); 
      }
      nhood_lb_ub();
   }
   else if (is[0]=='n'){
       unsigned int pick;
    
       start_n:
        nhood_lb=1;        
        nhood_ub=Maxnhood;
        xbox=draw_prompt_box(2);
        sprintf(textb[0],"set k upper bounds (def %d, limit %d):",
                                              nhood_ub,Maxnhood);
        outtext(textb[0]);
        input_string(2,0);
        if (is[0]=='q') goto startm;
        if (is[0]==13); /*do nout*/
        else if (atoi(is)<=Maxnhood) nhood_ub=atoi(is);
        moveto(xbox,gety+CHeight);
        av_k=(float)nhood_ub/5;
        sprintf(textb[0],"set average k (def %.2f, max %.2f):",
                              (float)nhood_ub/5,(float)nhood_ub/1.5);
        outtext(textb[0]);
        input_string(4,0);
        if (is[0]=='q') goto start_n;
        if (is[0]==13); /*do nout*/   
        else if (atof(is)>=1.0 && atof(is)<=nhood_ub/1.5) av_k=atof(is);
 
        /*fprintf(stderr,"\n low=%d up=%d av_k=%f %lu",nhood_lb,
	      nhood_ub,av_k,(unsigned long)(av_k*lineL));*/
        tot_wires=0;
	while(tot_wires<=(unsigned long)(av_k*lineL)){
           tot_wires+=1;
	   pick=rand()%lineL;
           nhoodm[pick]+=1;
           if (nhoodm[pick]>nhood_ub){ 
              nhoodm[pick]-=1;
              tot_wires-=1;
           }
        }
        tot_wires=0;
        /*fprintf(stderr,"\n");*/
        for (poss=0;poss<=lineL-1;poss++){
	  if (nhoodm[poss]==0) nhoodm[poss]=1;
          /*fprintf(stderr,"\n %d:%d ",poss,nhoodm[poss]);*/
          tot_wires+=nhoodm[poss];
        }
        av_k=(float)tot_wires/lineL;
        /*fprintf(stderr,"\n n=%d tot=%lu av_k=%.2f",
	                      lineL, tot_wires, av_k);*/
   }

   else if (is[0]=='s'){
     char stype;
     
     start_s:
      draw_prompt_box(1);
      if (lineL>=Maxnhood){ 
         outtext("power-law-p, specify-(def):");
         input_string(1,0);
      
         if (is[0]=='q') goto startm;
         else if (is[0]=='n') stype='n';
         else if (is[0]=='p') stype='p';
         else stype='s'; 
      }
      else stype='s';
      /*array of % of different k's*/
      if ((k_mix_percent=(float *)calloc(nhood_ub+1,sizeof(float)))
			      ==NULL) outof_memory("k_mix_percent");
      if ((k_mix_no=(unsigned int *)calloc(nhood_ub+1,sizeof(unsigned int)))
			      ==NULL) outof_memory("k_mix_percent");
      if ((shuffled_poss=
	    (unsigned int *)calloc(lineL,sizeof(unsigned int)))
			      ==NULL) outof_memory("shuffled_poss");
       if ((nhoodm_temp=(char *)calloc(lineL,sizeof(char)))
			      ==NULL) outof_memory("nhoodm_temp");
      tot_percent_left=100.0;

      if (stype=='s'){
        for (z=1;z<=Maxnhood;z++){
          draw_prompt_box(1);
	  if (z>=2)		      
            sprintf(textb[0],
               "enter %% k=%d (%.1f%% left) back-b:"
		                      ,z,tot_percent_left);	      
          else sprintf(textb[0],
               "enter %% k=%d (%.1f%% left):"
		                      ,z,tot_percent_left);	  
          outtext(textb[0]);
          input_string(5,0);
	  if (is[0]=='q'){
	      free(k_mix_percent);
	      free(k_mix_no);
	      free(shuffled_poss);
	      free(nhoodm_temp);
              if (z==1) goto startm;
	      else goto start_s;
	  }
	  if (is[0]=='b' && z>=2){
	     z-=2;
	  }
          if (is[0]==13 || is[0]<=0) continue;
	  if (atof(is)<=tot_percent_left) k_mix_percent[z]=atof(is);
	  else if (atof(is)>tot_percent_left){
               k_mix_percent[z]=tot_percent_left;
               tot_percent_left=0;
               break;
          }
	  tot_percent_left-= k_mix_percent[z];
          if (tot_percent_left<=0) break; 	  
        }

        k_mix_tot=valid_k=0;
        for (z=1;z<=Maxnhood;z++){
	  k_mix_no[z]=lineL*(k_mix_percent[z]/100);
          if (k_mix_no[z]>0){
	       valid_k+=1;
	       k_mix_tot+= k_mix_no[z];
	  }
        }
      }
      
      else if (stype=='p'){
        float expon, con;
        unsigned long k_mix_tot1,k_mix_tot_temp,
                      k_mix_tot_temp2,excess_tot,tot_wires;

      start_p:
        nhood_lb=1;        
        nhood_ub=Maxnhood;
        xbox=draw_prompt_box(2);
        sprintf(textb[0],"set k upper bounds (def %d limit %d):",
                                              nhood_ub,Maxnhood);
        outtext(textb[0]);
        input_string(2,0);
        if (is[0]=='q'){
	      free(k_mix_percent);
	      free(k_mix_no);
	      free(shuffled_poss);
	      free(nhoodm_temp);
	      goto start_s;
	}   
        if (is[0]==13); /*do nout*/
        else if (atoi(is)>0 && atoi(is)<=Maxnhood) nhood_ub=atoi(is);

        /*fprintf(stderr,"\n nhood_ub=%d",nhood_ub);*/
        expon=2.0;
        moveto(xbox,gety+CHeight);
        outtext("enter power-law exponent 1 to 3 (def 2.0):");
        input_string(4,0);
        if (is[0]=='q') goto start_p;
        if (is[0]==13);    
        else if (atof(is)>=1 && atof(is)<=3) expon=atof(is); 
        /*fprintf(stderr,"\n expon=%f",expon);*/         
        con= (expon-1.0) / 
	  (1.0 - (1.0/(pow((double)nhood_ub,(double)(expon-1.0)))));

        /*fprintf(stderr,"\n con=%f/(1-(1/%f))\n",expon-1.0,con);*/
        /*fprintf(stderr,"\n expo=%f con=%f \n",expon,con);*/
        k_mix_tot_temp=k_mix_tot1=0; 
        /*first try*/      
        for (z=1;z<=nhood_ub;z++){
           k_mix_no[z]=(unsigned int)
	        (lineL*con*(pow((double)z,-expon)));
	   /*fprintf(stderr,"\n k_mix_no[%d]=%d",z, k_mix_no[z]);*/
           k_mix_tot_temp+= k_mix_no[z];
        }
        /*fprintf(stderr,"\ntot=%lu first try",k_mix_tot_temp);*/
        /*this gives k_mix_tot_temp>lineL, corrected below*/

        /*second try*/
        k_mix_tot_temp2=k_mix_tot1=0;
        for (z=1;z<=nhood_ub;z++){
	  k_mix_no[z]=(unsigned int)
	    ceil((double)lineL*(float)k_mix_no[z]/k_mix_tot_temp);
          
          k_mix_tot_temp2+= k_mix_no[z];
          /*fprintf(stderr,"\n k_mix_no[%d]=%d",z, k_mix_no[z]);*/
        }
        /*fprintf(stderr,"\ntot=%lu second try",k_mix_tot_temp2);*/

        /*still k_mix_tot_temp>lineL, corrected below*/
        /*fprintf(stderr,"\ncorrecting excess");*/
	k_mix_tot1=0;
        if (k_mix_tot_temp2>lineL){
	   excess_tot=k_mix_tot_temp2-lineL;
           /*fprintf(stderr,"\nexcess=%lu-%d=%lu",
	              k_mix_tot_temp2,lineL,excess_tot);*/
           for (z=1;z<=excess_tot;z++){
             if (excess_tot>=2){ 
                k_mix_no[z]-=excess_tot/2;
                excess_tot-=excess_tot/2;
             }
             else if (excess_tot>=1){
                k_mix_no[z]-=1;
                excess_tot-=1;
             }
             if (excess_tot==0) break;
             /*fprintf(stderr,"\n k_mix_no[%d]=%d",z, k_mix_no[z]);*/
           }          
        }
        
        /*fprintf(stderr,"\ncorrect ??");*/
	k_mix_tot1=0;
        for (z=1;z<=nhood_ub;z++){
          /*if (k_mix_no[z]==0) k_mix_no[z]=1;*/
          k_mix_tot1+= k_mix_no[z];
          /*fprintf(stderr,"\n k_mix_no[%d]=%d",z, k_mix_no[z]);*/
	}
        /*fprintf(stderr,"\nn=%d tot=%lu",lineL,k_mix_tot1);*/
        if (k_mix_tot1>lineL) k_mix_no[1]-=(k_mix_tot1-lineL);
        else if (k_mix_tot1<lineL) k_mix_no[1]+=(lineL-k_mix_tot1);
 
        k_mix_tot1=0;
        av_k=0;
        tot_wires=0;
        for (z=1;z<=nhood_ub;z++){
           k_mix_tot1+= k_mix_no[z];
           tot_wires+=(unsigned long)k_mix_no[z]*z;
           /*fprintf(stderr,
             "\n k_mix_no[%d]=%d this_tot=%lu tot_wires=%lu",
	       z, k_mix_no[z],(unsigned long)k_mix_no[z]*z,tot_wires);*/
	}
        k_mix_tot= k_mix_tot1;        
        /*fprintf(stderr,"\nk_mix_tot=%d av-k=%.2f",
	              k_mix_tot,(double)tot_wires/lineL);*/
      }
    	
      /*if nothing was assigned, start again*/
      if (k_mix_tot==0) goto startm;
      
      if (k_mix_tot<lineL){
          for (z=nhood_ub;z>=1;z--){
	      if (k_mix_no[z]>0){
                  k_mix_no[z]+=lineL-k_mix_tot;
		  break;
	      }
          }
      }      
      /*if (valid_k<=5 && nhood_ub<=5) xbox=draw_prompt_box(2);
      else xbox=draw_prompt_box(3);*/
      xbox=draw_prompt_box(4);
      valid_k=check_tot=0;
      /*print k_mix assigned*/
   
      for (z=1;z<=Maxnhood;z++){
          if (k_mix_no[z]==0) continue;
	  valid_k+=1;
	  /*if (valid_k==6) moveto(xbox,gety+CHeight);*/
          sprintf(textb[0],"k%d=%.1f%%=%d ",
		z, (float)(k_mix_no[z]*100)/lineL, k_mix_no[z]);
	  outtext(textb[0]);
          if (Maxx-getx<CWidth*7) moveto(xbox,gety+CHeight);
          check_tot+=k_mix_no[z];
	  
      }
      moveto(xbox,gety+CHeight);
      if (check_tot!=lineL){
	 sprintf(textb[0],"error: tot=%d lineL=%d ",check_tot,lineL);
	 outtext(textb[0]);
      }     
      shuffle=0;
      outtext("shuffle: no-n yes-(def):");
      input_string(1,0);
      if (is[0]!='n') shuffle=1;
      /*if (valid_k<=5 && nhood_ub<=5) erase_prompt_box(2);*/
      else erase_prompt_box(4);           
      
                            
      /*find actual lower and upper bound*/
      nhood_lb=Maxnhood;
      nhood_ub=1;
      for (z=1;z<=Maxnhood;z++){
	 if (k_mix_no[z]>=1){ 
             nhood_lb=z;
             break;
         }
      }
      for (z=Maxnhood;z>=1;z--){
	 if (k_mix_no[z]>=1){
             nhood_ub=z;
             break;
         }
      }
      
      /*fprintf(stderr,"\nlb=%d ub=%d",nhood_lb,nhood_ub);*/
      /*load k's straight in to temp buffer*/
      k_tot=0;
      for (z=1;z<=nhood_ub;z++){
	 if (k_mix_no[z]==0) continue; 
         else{
	     for (zz=1;zz<=k_mix_no[z];zz++){               
		if (k_tot>lineL-1){
		   draw_prompt_box(1);
		   sprintf(textb[0],
			   "error: k_tot=%d > lineL-1=%d",k_tot,lineL-1);
		   outtext(textb[0]);
		   input_string(1,0);
		}
		nhoodm_temp[k_tot]=z;
		k_tot+=1;      
	     }     
	  }	
      }
      /*fprintf(stderr,"\nk_tot=%d",k_tot);*/
            
      /*shuffle the pack 40 times by swapping cards*/
      if (shuffle==1){
         for (poss=0;poss<=lineL-1;poss++) shuffled_poss[poss]=poss;
     
         for (zz=1;zz<=40;zz++){ 
            for (z=0;z<=lineL-1;z++){         
	       temp_shuffle=myrand()%lineL;

	       temp_poss=shuffled_poss[z];
               shuffled_poss[z]=shuffled_poss[temp_shuffle];
	       shuffled_poss[temp_shuffle]=temp_poss;	  
            }
         }
      
         for (z=0;z<=lineL-1;z++)
	      nhoodm[z]=nhoodm_temp[shuffled_poss[z]];         
      }
      else memmove(nhoodm,nhoodm_temp,lineL*sizeof(char));
 
      free(k_mix_percent);
      free(k_mix_no);     
      free(shuffled_poss);
      free(nhoodm_temp);
   }
   
   else{
     startm1:
      nhood_lb=1;
      /*if (value_range==2){
         if (nhood<=9) nhood_ub=9;
         else  nhood_ub=nhood;
      }
      else */
      nhood_ub=Maxnhood;
      draw_prompt_box(1);
      sprintf(textb[0],"set k bounds 1-%d: lower (def 1):",Maxnhood);
      outtext(textb[0]);
      input_string(2,0);
      if (is[0]=='q') goto startm;
      if (is[0]==13); /*do nout*/
      else if (atoi(is)>=1 && atoi(is)<=Maxnhood) nhood_lb=atoi(is);
      if (value_range==2){
         if (nhood_lb<=9) temp_ub=nhood_ub=9;
         else (nhood_ub=temp_ub=nhood_lb);
      }
      else temp_ub=Maxnhood;
      sprintf(textb[0]," upper (def %d, limit %d):",temp_ub,Maxnhood);
      outtext(textb[0]);
      input_string(2,0);
      if (is[0]=='q') goto startm1;
      if (is[0]==13); /*do nout*/
      else if (atoi(is)>=nhood_lb && atoi(is)<=Maxnhood) nhood_ub=atoi(is);

      if (nhood_lb==nhood_ub){
         for (poss=0;poss<=lineL-1;poss++) nhoodm[poss]=nhood_lb; 
      }
      else{
         for (poss=0;poss<=lineL-1;poss++){
	    while(!(nhoodm[poss]>=nhood_lb && nhoodm[poss]<=nhood_ub)){
	       nhoodm[poss]=myrand()%(Maxnhood+1);
	    }
         }
      }
   }
  
   draw_prompt_box(1);
   maxk=nhood_ub;
   if (nhood_ub<Maxnhood){ 
      sprintf(textb[0]," set greater k-max (def %d, limit %d):",nhood_ub,Maxnhood);
      outtext(textb[0]);
      input_string(2,1);
      if (is[0]!=13 && atof(is)>nhood_ub && atof(is)<=Maxnhood) 
                                                   maxk=atof(is);
   }
   
  startjump:
   if (!indexjump) startindex=lineL;
   indexjump=0;
   nhood_lb_ub(); /*update neighbouhood lower and upper bounds*/
   if (nhood_ub<=9) rows=6+(signed int)
                          ceil((double)(startindex*CWidth)/(trboxw));
   else rows=5+(signed int)
      ceil((1+((double)nhood_ub)/25) * (double)(startindex*CWidth)/(trboxw));

                          ceil((double)(startindex*CWidth)/(trboxw));
   if (rows*CHeight>Maxy-vgay(100)){
      rows=(Maxy-vgay(5))/CHeight;
   }
   
   sprintf(textb[0],
      "k-mix %d-%d, maxk=%d, net size=%d, startindex=%d",
			nhood_lb,nhood_ub,maxk,lineL,startindex-1);
   if (lineL!=tempL)
      sprintf(textb[0],
	"k-mix %d-%d, maxk=%d, net size=%d (was %d) startindex=%d",
			nhood_lb,nhood_ub,maxk,lineL,tempL,startindex-1);
   if ((basinfield && lineL>32)){
      sprintf(textb[1],"(network>32, field changed to single)");
      rows+=1;
   }
   xbox=draw_prompt_box(rows);
   outtext(textb[0]);
   if (basinfield && lineL>32){
      basinfield=0;
      moveto(xbox,gety+CHeight);
      outtext(textb[1]);
   }
   moveto(xbox,gety+CHeight);
   for (poss=startindex-1;poss!=Maxu;poss--){
      if (getx>getmaxx()-vgax(10)){
	 moveto(xbox,gety+CHeight);
	 if (gety>=Maxy-vgay(20)-6*CHeight){
	    moveto(xbox,gety-CHeight);
	    break;
	 }
      }
      sprintf(textb[0],"%d",nhoodm[poss]);
      if (poss%2==0){
	  tempcolor=getcolor();
	  setcolor(lightred);
	  outtext(textb[0]);
	  setcolor(tempcolor);
      }
      else outtext(textb[0]);
   }

   if ((k_count=(unsigned int*)calloc(nhood_ub+1,sizeof(unsigned int)))
			    ==NULL) outof_memory("k_count");
   tot_wires=0;
   for (z=0;z<=lineL-1;z++){
      k_count[(signed int)nhoodm[z]]+=1;
      if (nhoodm[z]==0) nhoodm[z]=1;
      tot_wires+=nhoodm[z];    
   }
   av_k=(float)tot_wires/lineL;

   moveto(xbox,gety+CHeight);        
   for (z=1;z<=nhood_ub;z++){
      if (k_count[z]>0){
	 sprintf(textb[0],"%d=%.1f%% ",
		            z,(float)(k_count[z]*100)/lineL);
         outtext(textb[0]);
         if (z<Maxnhood && getx>=Maxx-CWidth*6) moveto(xbox,gety+CHeight); 
      }
   }
   free(k_count);

   if (poss==Maxu) endposs=0;
   else endposs=poss+1;
   moveto(xbox,gety+CHeight);
   sprintf(textb[0],
      "n=%d tot_wires=%lu av-k=%.2f, mix shown from cell index %d-%d",
	   lineL,tot_wires,av_k,startindex-1,endposs);
   outtext(textb[0]);
   moveto(xbox,gety+CHeight);

   if (poss!=Maxu) sprintf(textb[0],
	   "hist-h reset-r save-s more-m jump-j cont-ret:");
   else sprintf(textb[0],
	   "hist-h reset-r save-s jump-j cont-ret:");

   outtext(textb[0]);
   input_string(1,0);
   if (is[0]=='q' || is[0]=='r'){
      erase_prompt_box(rows);
      goto startm;
   }
   else if (is[0]=='j'){ /*jump to new cell poss*/
      setfillstyle(SOLID_FILL,black);
      bar(xbox,gety+2,Maxx-3,gety+CHeight+2);
      sprintf(textb[0],"jump to index (%d-0):",lineL-1 );
      moveto(xbox,gety);
      outtext(textb[0]);

      sprintf(textb[0],"%d",lineL-1);
      input_string(strlen(textb[0]),0);

      if (atoi(is)>=0 && atoi(is)<=lineL-1){
	 startindex=atoi(is)+1;
	 indexjump=1;
	 erase_prompt_box(rows); 
	 goto startjump;
      }
   }
   else if (is[0]=='m' && poss!=Maxu){ /*continue to next cell poss*/
      startindex=poss+1;
      indexjump=1;
      erase_prompt_box(rows);
      goto startjump;
   }
   else if (is[0]=='s'){
     load_save_nhoodmix('s');
     if (is[0]=='q'){ 
        goto startjump;
     }
   } 
   else if (is[0]=='h'){
       erase_prompt_box(rows); 
       draw_k_hist(1);
       goto startjump;
   }

   erase_prompt_box(rows);
   nhood_lb_ub(); /*update neighbouhood lower and upper bounds*/
   if (maxk>nhood_ub) nhood=maxk; /*if selected, set greater max k*/
   else nhood=nhood_ub;
   /*fprintf(stderr,"\nlb=%d ub=%d nhood=%d",nhood_lb,nhood_ub,nhood);*/
   moveto(tempx,tempy);
}

/******** draw a histogram of the k-frequency  ***********/
void draw_k_hist(char in_out){
   signed int bottom,top,right,left,
                topy,cindex=0,barbase,
                bar_height,barleft,tempx,z,
                start=0,finish=0,bar_no,
                max_freq,bar_width,box_width,box_height,
                bar_fact;
   float av_k;
   unsigned int zu,*k_count;
   unsigned long tot_wires=0;
     
     if (in_out==1){ 
        if ((k_count=(unsigned int*)
                 calloc(nhood_ub+1,sizeof(unsigned int)))
			    ==NULL) outof_memory("k_count");        
        for (zu=0;zu<=lineL-1;zu++){
           k_count[(signed int)nhoodm[zu]]+=1;
           if (nhoodm[zu]==0) nhoodm[zu]=1;
           tot_wires+=nhoodm[zu];   
        }
        av_k=(float)tot_wires/lineL;        
        nhood_lb_ub(); /*update neighbouhood lower and upper bounds*/
        start=nhood_lb;
        finish=nhood_ub;
     }
     else if (in_out==2){
        cell_out_freq();
        /*find highest outputs*/
        for (zu=0;zu<=lineL-1;zu++)
	  if (celloutfreq[zu]>finish) finish=celloutfreq[zu];
        if ((k_count=(unsigned int*)
                 calloc(finish+1,sizeof(unsigned int)))
			    ==NULL) outof_memory("k_count");              
        /*save output frequencies, min 0, max = lineL*/
        for (zu=0;zu<=lineL-1;zu++){  
	   k_count[celloutfreq[zu]]+=1; /*max celloutfreq[zu]=nhood;*/
           tot_wires+=celloutfreq[zu];
	}        
        av_k=(float)tot_wires/lineL;           
     }
    
     else if (in_out==3){
       unsigned int *in_out_freq;
       if ((in_out_freq=(unsigned int*)calloc(lineL,sizeof(unsigned int)))
					==NULL) outof_memory("in_out_freq");
       /*compute in-out frequency*/
       for (zu=0;zu<=lineL-1;zu++)
	       in_out_freq[zu]=nhoodm[zu]+celloutfreq[zu];
       for (zu=0;zu<=lineL-1;zu++)
	  if (in_out_freq[zu]>finish) finish=in_out_freq[zu];
       if ((k_count=(unsigned int*)
                 calloc(finish+1,sizeof(unsigned int)))
			    ==NULL) outof_memory("k_count");       
       /*save in-out frequencies, min 0, max = lineL*/
        for (zu=0;zu<=lineL-1;zu++){  
	   k_count[in_out_freq[zu]]+=1; /*max celloutfreq[zu]=nhood;*/
           tot_wires+=in_out_freq[zu];
	}        
        av_k=(float)tot_wires/lineL;  
        free(in_out_freq);       
     }
     /*find maximum freq*/
     max_freq=0;     
     for (zu=start;zu<=finish;zu++){
       if (k_count[zu]>max_freq) max_freq=k_count[zu];
     }
    
     bar_no=(finish+1)-start;

     if (bar_no<=13) box_width=vgax(400);
     else if (bar_no<=25) box_width=(signed int)(vgax(400)+vgax(100)*(float)bar_no/25);
     else box_width=Maxx; /*as wide as possible*/

     box_height=vgay(200);

     left=vgax(50);     
     right=left+box_width;
     if (right>Maxx-1){
       right=Maxx-1;
       box_width=right-left+1;
     } 
     top=vgay(200);
     bottom=top+box_height;

     draw_box(18,left,top,right,bottom,1,0);
     moveto(left+vgax(75),bottom-vgax(60));
     barbase=gety;
     barleft=getx;    
     
     /*draw y axis*/
     moveto(barleft-vgax(5),barbase);
     lineto(barleft-vgax(5),barbase-(signed int)
                          (float)box_height*.6);
     lineto(getx-vgax(10), gety);
     moveto(getx-vgax(22), gety-CHeight/2);
     if (in_out<=2)
        sprintf(textb[0],"%.1f%%",(float)max_freq*100/lineL);
     else if (in_out==3) 
       sprintf(textb[0],"%.1f%%",(float)max_freq*100/(lineL*2));     
     outtext(textb[0]);

     moveto(left+vgax(75),bottom-vgax(60));

     if (bar_no<=13) bar_fact=13;
     else bar_fact=finish+1;
     bar_width= (box_width*.8)/bar_fact;

     if (bar_no>25 ) set_small_font();
     else if (bar_no>13) set_medium_font();

     /*draw x axis bars*/            
     for (z=start;z<=finish;z++){         
         setfillstyle(SOLID_FILL,yellow);
         bar_height=(signed int)
                (float)box_height*.6 * (float)k_count[z]/max_freq;

         topy=barbase-bar_height;
         if (topy<top+1) topy=top+1;
                  
	 tempx=getx;
         bar(getx,topy,getx+bar_width*0.8,barbase);
	 	                       
	 cindex++;
	 moveto(tempx,barbase+CHeight*.5);
         if (cindex==1){ 
             moverel(-vgax(66),0);
             if (in_out==1) outtext("k frequency %");
             else if (in_out==2) outtext("output freq %");
             else if (in_out==3) outtext("in-out freq %");
             moveto(tempx-vgax(30),barbase+CHeight*1.5);
             outtext("total=");
             if (in_out==1){
                moveto(tempx-vgax(18),barbase+CHeight*2.5);
                outtext("k=");
             }
             else if (in_out==2 || in_out==3) {
                moveto(tempx-vgax(42),barbase+CHeight*2.5);
                if (in_out==2) outtext("outputs=");
                else if (in_out==3) outtext("in-out=");
             }
         }        
 
         setcolor(yellow);
         moveto(tempx,barbase+CHeight*.5);         
         if (in_out<=2)
             sprintf(textb[0],"%.1f",(float)k_count[z]*100/lineL);
         else if (in_out==3)
             sprintf(textb[0],"%.1f",(float)k_count[z]*100/(lineL*2));
         outtext(textb[0]);
         moveto(tempx,barbase+CHeight*1.5);         
         sprintf(textb[0],"%d",k_count[z]);
         outtext(textb[0]);
         setcolor(white);
         moveto(tempx,barbase+CHeight*2.5);
         sprintf(textb[0],"%d",z);
         outtext(textb[0]);

         moveto(barleft+cindex*bar_width,barbase);
     }
     if (bar_no>13) restore_def_font();	

   prompt:
     moveto(barleft,barbase+CHeight*3.5);
     setfillstyle(SOLID_FILL,black);
     bar(getx,gety,right-2,gety+CHeight);
     if (in_out==1) sprintf(textb[0],
         "n=%d av-k=%.2f save/load-s/l cont-ret:",lineL,av_k);
     else if (in_out==2) sprintf(textb[0],
         "n=%d av-out=%.2f save/load-s/l cont-ret:",lineL,av_k);
     else if (in_out==3) sprintf(textb[0],
         "n=%d av-in-out=%.2f save/load-s/l cont-ret:",lineL,av_k);
     outtext(textb[0]);
     input_string(1,0);

     if (is[0]=='s' || is[0]=='l'){
	 hist_save_load((unsigned int)finish,k_count);
         goto prompt;
     }
     
     free(k_count);
     sprintf(textb[9],"%s","boximage[18]");
     putimage(left,top,boximage[18],COPY_PUT,textb[9]);
     freeimage(boximage[18]);
     is[0]=0;   
}

/******** update neighbouhood lower and upper bounds ***********/
void nhood_lb_ub(void){
 unsigned int poss;

      nhood_lb=Maxnhood;
      nhood_ub=1;
      for (poss=0;poss<=lineL-1;poss++){
	 /*find lower and upper bounds*/
	 if (nhoodm[poss]<nhood_lb) nhood_lb=nhoodm[poss];
	 if (nhoodm[poss]>nhood_ub) nhood_ub=nhoodm[poss];
      }
}

/******** load the neighbouhood mix (k-mix) ***********/
void load_nhoodmix(void){
     unsigned int mixloaded,poss;
     char bmix;
     signed int xbox;
     
      /*load from standard file format*/
      if (is[0]=='l') mixloaded=load_save_nhoodmix('l');
      /*load from Manor's file format*/
      if (is[0]=='L') mixloaded=load_save_nhoodmix('L');
      if (is[0]=='q') return;
      if (mixloaded<lineL){
	 xbox=draw_prompt_box(2);
	 sprintf(textb[0],"k-mix loaded (%d) less than net size (%d)",
	                                       mixloaded,lineL);
	 sprintf(textb[1],"enter background k-mix 1-%d (def 5):",Maxnhood);
	 outtext(textb[0]);
	 moveto(xbox,gety+CHeight);
	 outtext(textb[1]);
	 input_string(2,0);
	 if (atoi(is)>=1 && atoi(is)<=Maxnhood) bmix=atoi(is);
	 else bmix=5;
	 for (poss=mixloaded;poss<=lineL-1;poss++) nhoodm[poss]=bmix;
	 erase_prompt_box(2);
      }
      nhood_lb_ub();
}
/**** select if totalistic, 13 May 1993, rev Dec 93 *******/
void select_totalistic(void){
 
   outer_tot=0;
   setcolor(white);
   next_line(xtext,1);
   if (tot_only==0) outtext("totalistic: tcode-t kcode-k (def-rcode):");      
   else{ /*outer totalistic not allowed if nhood_mixed*/ 
       if (nhood_mixed) outtext("totalistic only: tcode-t, (def-kcode):");   
       else outtext("totalistic only: outertot-o/+o, tcode-t, (def-kcode):");
   }
   
   is[0]=is[1]=0; /*turn outertot off in case it was activated*/
   input_string(2,0);
   if (is[0]=='q'){
      setpback_x_lines(0);
      return;
   }
   if (tot_only==0) totalistic=0;
   else totalistic=2;
   if (is[0]=='t') totalistic=1; /*add up absolute total in nhood*/
   else if (is[0]=='k') totalistic=2; /*add up total of each value*/
   if (tot_only==1 && nhood_mixed==0){ /*outer-totalistic rules*/
      if (is[0]=='o' || is[1]=='o') outer_tot=1;
   }
}

/*****set up and draw n'hood matrix (rule table),13 May 1993***********/
signed int setup_nhood_matrix(char amend){
 unsigned int z,outertable,start_table;
 signed int ii,zz,sod,xbox,
     startx,starty,topy,tempx,tempx1,tempy1,boty,spacing;
 char color,mscale,msep,xleft,outernhood; /*  *value_string */
   
   
   if (nhood_mixed) outernhood=nhood_ub;/*keep nhood matrix simple*/
   else outernhood=nhood;

   /*if ((value_string=(char *)
	       calloc(outernhood,sizeof(char)))
	                    ==NULL) outof_memory("value_string");*/
   xleft=4; /*offset from left of nhood matrix in textwidth units*/
   mscale=vgax(5);
   setfillstyle(SOLID_FILL,black);
   bar(xtext-xleft,gety+3*mscale-1,Maxx-5,Maxy-vgay(37));

   if (outernhood>5) mscale=vgax(4);
   msep=(ceil)( (double)mscale/4);
   start_table=outertable=(signed int)pow(value_range,(double)outernhood)-1;

   if ((mscale+1)*outertable > Maxx-20){
      sod= (Maxx-10)/outertable;
      mscale=sod-1;
      if (mscale<=2){
	 mscale=2;
	 msep=1;
      }
      if (mscale==3) msep=1;
      if (outernhood>=9){
	 mscale=1;
	 msep=0;
      }
      if (outernhood==8 && hires) mscale=3;
   }
   next_line(xtext,2);
   topy=gety;
   startx=getx;
   starty=gety;

   is[0]=0;
   wiring_postscript=0;
   
 amend_matrix:   
   if (amend==1){
      xbox=draw_prompt_box(3);     
      outtext("nhood-matrix: exit-q, % of index to show (def 100%): ");
      input_string(2,0);
    
      
      if (is[0]=='q') goto end_matrix;
      else if (is[0]==13) start_table=outertable;
      else if (atoi(is)>1 && atoi(is)<100) 
                        start_table=outertable*(float)atoi(is)/100;
      moveto(xbox,gety+CHeight);
      sprintf(textb[0],"index=%d, scale in pixels (def %d, max 30): ",start_table,mscale);
      outtext(textb[0]);
      input_string(2,0);

      if (is[0]==13);
      else if (atoi(is)>=1 && atoi(is)<=30){
          mscale=atoi(is);         
      }
      //draw_matrix:
      msep=(ceil)( (double)mscale/4);
      if (mscale>=4) msep=1;
      if (mscale<=3) msep=0;
      //if (start_table>128) msep=0;

      moveto(getx,gety);
      outtext(" PScript-p:");
      input_string(1,0);
      if (is[0]=='p'){
		 char filename_mrx_PS[13],file_ret;
		 signed int tempPy;		 
		            tempPy=gety;
                            /*to redraw the whole thing exactly as is 
                            and save vector PostScript*/
                            wiring_postscript=1;
                            file_ret=select_filename("SAVE","PostScript file","*.ps","my_mrxPS");
                            if (file_ret=='q'){
			       wiring_postscript=0;
                               goto amend_matrix;
                            }
	                    memmove(filename_mrx_PS,filename,13);
                            /*delete previous*/
                            fid_PS=myopen(filename_mrx_PS,1,0);
                            vret=write(fid_PS, "",0);
                            close(fid_PS);
                            /*start new*/
                            fid_PS=myopen(filename_mrx_PS,1,1);
                            if (fid_PS==-1){ 
                                  file_error(filename_mrx_PS);
                                  close(fid_PS); 
                                  wiring_postscript=0;
                                  goto amend_matrix;  
                            }
                            psize_ps=pointsize;
                            prepare_basinPS(2,2); /*write/define postScipt for wiring*/
		            moveto(getx,tempPy);
      }

      moveto(xbox,gety+CHeight);
      outtext("show matrix, back-q redo-r cont-ret:");
      input_string(1,0);
      if (is[0]==13) amend=0;
            
      
      moveto(startx,starty);
      setfillstyle(SOLID_FILL,black);
      //setfillstyle(SOLID_FILL,green);
      bar(0,starty-CHeight/2,Maxx,Maxy);
   }
   

   /*matrix allocated in main and alloc, 
      allocate_mem_nhood_matrix(char thisnhood)*/
   
   spacing= (outertable+1)/value_range; /*label x axis*/
   for (ii=1;ii<=10;ii++){
      if ((spacing/value_range)*mscale > CWidth*10) spacing/=value_range;
      else break;
   }
   if (spacing<1) spacing=1;
   for (z=start_table;z!=Maxu;z--){
     //input_string(0,1);
      tempx=getx;
      if (getx > Maxx+mscale*2) break;
      /*convert dec value to value string length k, superceded*/
      /*dec_to_value_line(value_string,(unsigned long)z,
	               (signed int)nhood);*/

      for(zz=outernhood-1;zz>=0;zz--){
	 if (value_range>2)
	   /*color=color_v[get_value(value_string,
                  (unsigned int)zz)];superceded */
           color=color_v[get_value(nm[zz],z)];
	 else{		 
	    if (get_bit(nm[zz],z)==1) color=yellow;
	    else color=darkgray;
         }

         setfillstyle(SOLID_FILL,color);
	 
        
	 if (wiring_postscript){
			   color_ps(wiring_postscript-1,fillcolor);
                           rect_fill_ps(tempx,gety,mscale-msep,mscale-msep);
	 }
	 bar(tempx,gety,tempx+mscale-msep,gety+mscale-msep);
	  
         moveto(tempx,gety);
	 /*put a green dot on zero cell, for printout */
	 if (value_range>2){
	   /*if (get_value(value_string,(unsigned int)zz)==0 && mscale>=3) superceded*/
	   if (get_value(nm[zz],z)==0 && mscale>=3){
	        putpixel(getx+(mscale-msep)/2,gety+(mscale-msep)/2,green);
	        if (wiring_postscript){
		    color_ps(wiring_postscript-1,green);
		    smallspot_ps(getx+(mscale-msep)/2,gety+(mscale-msep)/2,1);
		}
           }		
         }
	 else{
	    if (get_bit(nm[zz],(unsigned int)z)==0 && mscale>=3){
	        putpixel(getx+(mscale-msep)/2,gety+(mscale-msep)/2,green);
		if (wiring_postscript){
                  color_ps(wiring_postscript-1,green);
		  smallspot_ps(getx+(mscale-msep)/2,gety+(mscale-msep)/2,1);
	        }	  
	    }	
         }
       
	 tempx1=getx;
	 tempy1=gety;
      

         //nhood index
	 if ((zz==outernhood-1 || zz==0) && z==start_table){
	     if (wiring_postscript) color_ps(wiring_postscript-1,white);
             line(tempx1-CWidth*2,tempy1,tempx1-CWidth/2,tempy1);
	     if (wiring_postscript) line_ps(tempx1-CWidth*2,tempy1,tempx1-CWidth/2,tempy1);
             sprintf(textb[1],"%d",zz);               
             moveto(tempx1-CWidth*2-textwidth(textb[1])-1,
		 tempy1-CHeight/2+(mscale-msep)/2);
	     
	     if (wiring_postscript){
		   nodetext_ps(3,bground,textb[1],getx,gety+CHeight);
	     }
	     outtext(textb[1]);
             boty=gety;                   
	 }
	 
	 moveto(tempx1,tempy1);
       
	 /*nhood horizontal scale*/
         if ((zz==0) && ((z+1)%spacing==0 || z==0)){
	    if (wiring_postscript) color_ps(wiring_postscript-1,white);
	    moveto(getx,gety+mscale);
	    line(getx,gety,getx,gety+CHeight/2);
	    if (wiring_postscript) line_ps(getx,gety,getx,gety+CHeight/2);
	    moveto(getx-CWidth/2,gety+CHeight/2);
	    sprintf(textb[1],"%d",z);	    
	    if (wiring_postscript){
		   nodetext_ps(3,bground,textb[1],getx,gety+CHeight);
	    }
	    outtext(textb[1]);
	 }
	 moveto(tempx1,tempy1);
         moverel(0,mscale);
      }
      moveto(tempx+mscale,topy);
   }
   if (boty>0) moveto(getx,boty+CHeight*2);
   else{ 
      moverel(0,CHeight*3);
   }
   boty=gety;

 end_matrix:
   if (is[0]=='q');
   else if (amend==1 && is[0]=='r'){
      moveto(startx,starty);
      goto amend_matrix;
   }
   /*free(value_string); superceded*/
   return(boty);
}

/************ Post functions, samples or rule-space Dec 2002 ********/
void post_samples(signed int tablemax,
                  signed int tablebytes,
                  signed int t_codemax,signed int t_codebytes,
		  signed int v_codemax,signed int v_codebytes){
     
  char thisname[6],*temprule,*temp_code,post=0,
          post_all,post_type,filedata;
     unsigned long maxdec,rule_dec_max,zu,post_sample,post_count;
     signed int max_codetable,max_table,fid,z,zz;

        ptype=pmu=-1;
   
        if (totalistic==0) max_table=tablemax;
        else if (totalistic==1) max_table=t_codemax;
        else if (totalistic==2) max_table=v_codemax;

        rule_dec_max=max_dec_rule(max_table,value_range);        
        if (totalistic==0) sprintf(thisname,"rcode");
        else if (totalistic==1) sprintf(thisname,"tcode");
        else if (totalistic==2) sprintf(thisname,"kcode");
      startpost:
        is[1]=0;
        post_all=0;
         
        draw_prompt_box(1);
        /*if rule can be expressed as dec, can show all, otherwise just sample*/
        if (rule_dec_max>0){
           if (rule_dec_max<Maxlu) sprintf(textb[0],
           "Post functions: sample-s, %s-space (%d^%d=%lu rules)-p, all +a:",
                                  thisname,value_range,max_table+1,rule_dec_max+1);
           else if (rule_dec_max>0 && rule_dec_max==Maxlu) sprintf(textb[0],
           "Post functions: sample-s, %s-space (%d^%d=%lu+1 rules)-p, all +a:",
                                  thisname,value_range,max_table+1,rule_dec_max);
        }
        else sprintf(textb[0],
           "Post functions: sample-s, (%d^%d %ss), all +a:",
                                  value_range,max_table+1,thisname);
        outtext(textb[0]);
        input_string(2,0);
        if (is[0]=='q') return;
        else if (is[0]=='p' && rule_dec_max>0) post_type=is[0];
        else if (is[0]=='s') post_type=is[0];
        else goto startpost;
	if (is[1]=='a') post_all=1; 
        else post_all=0; 

        if (post_all==0) restrict_post();
        /*fprintf(stderr,"\n ptype=%d pmu=%d",ptype,pmu);*/

        if (post_type=='s'){  /*sample rule-space*/
      
           draw_prompt_box(1);           
           sprintf(textb[0],"sample (def %d):",10000);
           outtext(textb[0]);
           input_string(9,1);
           if (is[0]=='q') goto startpost;
           if (atolu(is)!=0) zu=atolu(is);
           else (zu=10000);
           post_sample=zu;           
        }
        filedata=0;
        draw_prompt_box(1);
        if (post_type=='p') sprintf(textb[1],"all %ss",thisname);
        else if (post_type=='s') sprintf(textb[1],"%s sample (%lu)",thisname,zu);
        if (post_all==1) sprintf(textb[2]," (full list)");
	else sprintf(textb[2]," (Post only)");
        sprintf(textb[0],
        "%s%s: print xterm-(def), save-s, both-b:",textb[1],textb[2]);
        outtext(textb[0]);
        input_string(1,0);
        if (is[0]=='q') goto startpost;
        filedata=0;
        if (is[0]==13);
        else if (is[0]=='s' || is[0]=='b'){
            if (is[0]=='s') filedata=2;
            else if (is[0]=='b') filedata=1;
	    select_filename("SAVE","DATA","*.dat","post_data");
	    memmove(filename_data,filename,13);
	    fid=myopen(filename_data,1,0);	   
	    if (fid==-1){
               filedata=0;
               file_error(filename);
               draw_prompt_box(1);
	       outtext(textb[0]);
	       input_string(1,0);
	       erase_prompt_box(1);	    
	    }
	    close(fid);
	}
        if ((temprule=(char *)calloc(tablebytes,sizeof(char)))
				       ==NULL) outof_memory("temprule");
        if (totalistic==1){ 
           max_codetable=t_codemax;
           if ((temp_code=(char *)calloc(t_codebytes,sizeof(char)))
				       ==NULL) outof_memory("temp_code");
        }
        else if (totalistic==2){
           max_codetable=v_codemax;     
           if ((temp_code=(char *)calloc(v_codebytes,sizeof(char)))
				       ==NULL) outof_memory("temp_code");
        }
        if (post_type=='p'){
           if (totalistic==0) maxdec=(unsigned long) 
                          (pow(value_range,(double)(tablemax+1))-1);
           else if (totalistic){
              maxdec=(unsigned long) 
                          (pow(value_range,(double)(max_codetable+1))-1);
           }
           zu=maxdec+1;
        }
        post_count=Post_total_i=Post_total_3=Post_total_2=0;
        memory_box(2,"stop Post -q");
	do{
          zu--;
          /*fprintf(stderr,"\n zu=%lu",zu);*/        
	  if (event_ready()){ /*chance to give up*/
	       if (is[0]=='q') break;
          }      
          if (totalistic==0){
              if (post_type=='p') dec_to_value_line(temprule,zu,tablemax+1);
              else if (post_type=='s'){ 
                 for (zz=0;zz<=tablemax;zz++) 
                    set_value(temprule,zz,myrand()%(value_range));
              }
          }
	  else if (totalistic==1){
	     if (post_type=='p') dec_to_value_line(temp_code,zu,t_codemax+1);
             else if (post_type=='s'){
                for (zz=0;zz<=t_codemax;zz++) 
                   set_value(temp_code,zz,myrand()%(value_range));
             }
             code2rule(temprule,temp_code,nhood);
          }
          else if (totalistic==2){
             if (post_type=='p') dec_to_value_line(temp_code,zu,v_codemax+1);
             else if (post_type=='s'){
                for (zz=0;zz<=v_codemax;zz++)
                   set_value(temp_code,zz,myrand()%(value_range));
             }
             v_code2rule(temprule,temp_code,nhood,1);
	  }
	  if (post_all==0){ 
              post=post_func(nhood, temprule,0,0,0,0); /*check post*/
              if (post==1) post_count+=1;
          }
          if ((post==1 && post_all==0) || post_all==1){
             sprintf(textb[0],"\n %lu: ",zu);
             if (totalistic && max_codetable<=127){ 
                for (z=max_codetable;z>=0;z--)
                   sprintf(textb[0],"%s%d",textb[0],get_value(temp_code,z));
	     }
             sprintf(textb[0],"%s ",textb[0]);

             if (tablemax<=127){
                for (z=tablemax;z>=0;z--)
                   sprintf(textb[0],"%s%d",textb[0],get_value(temprule,z));
             }
             if (filedata) save_data(textb[0]);
	     if (filedata<2) fprintf(stderr,"%s",textb[0]);
             post=post_func(nhood, temprule,2,0,fid,filedata); //check and print

             if (post==1 && post_all==1) post_count+=1;
             if (value_range==2) z_parameter_all(nhood,0,temprule);
             else z_parameter_all_mvalue(nhood,0,temprule);             
             sprintf(textb[0],"  C=%d",canaltotal);   
             if (value_range==2)
                sprintf(textb[0],"%s P=%g",textb[0],.5+(1.0-lratio)/2);
             sprintf(textb[0],"%s Z=%g",textb[0],zparam[0]);
             if (filedata) save_data(textb[0]);
             if (filedata<2) fprintf(stderr,"%s",textb[0]); 
          }
             
          if (zu==0) break;         
	} while(1);
        erase_memory_box(0);
        
        if (post_type=='p'){
	   if (totalistic==0) sprintf(textb[1],"%s-space=%lu",thisname,maxdec+1);
           sprintf(textb[0],
               "\n v%dk%d: Post count=%lu=%.3f%% (2=%lu 3=%lu i=%lu) %s%s",
                  value_range,nhood,post_count, 
                         100*(float)post_count/(maxdec+1),
                               Post_total_2,Post_total_3,Post_total_i,textb[1],textb[2]);
        }
        else if (post_type=='s') sprintf(textb[0],
            "\n v%dk%d: Post count=%lu=%.3f%% (2=%lu 3=%lu i=%lu) %s-sample=%lu%s",
                value_range,nhood,post_count, 
                  100*(float)post_count/(post_sample),
                    Post_total_2,Post_total_3,Post_total_i,thisname,post_sample,textb[2]);
        if (filedata) save_data(textb[0]);
        if (filedata<2) fprintf(stderr,"%s",textb[0]); 
        close(fid);
        free(temprule);
        if (totalistic) free(temp_code);
        goto startpost;      
}

/*********** restrict range of Post functions Dec 2002 **************/
void restrict_post(void){
  char temp_is0;
           temp_is0=is[0];         
           ptype=pmu=-1;
           draw_prompt_box(1);
           sprintf(textb[0],
           "restrict Post value (0-%d):",value_range-1);
           outtext(textb[0]);
           input_string(1,0);
           if (is[0]==13 || atoi(is)<0  || atoi(is)>value_range-1) ptype=-1;
           else ptype=(char)atoi(is);

           pmu=-1;
           /*restricting the class cancelled - not useful as 
             class i is IN class 3 is IN class 2*/ 
           /*outtext(" mu(i,3,2):");
           input_string(1,0);
           if (is[0]=='i') pmu='i'; 
           else if (is[0]==13 || atoi(is)>3 || atoi(is)<2) pmu=-1;
           else pmu=(char)atoi(is);
           fprintf(stderr,"\n  restrict_post:ptype=%d pmu=%d",ptype,pmu);*/

           is[0]=temp_is0;
} 
/*********** compute binary  Post functions Dec 2002 **************/
char post_func(char nhoodz, char *thisrule,
	  char details, char box,signed int fid, char filedata){

 char *pAi,*pA2,*pA3,type,temp,
      thistemp,post=0;
 signed int z,zz,nextz,nextz1,tablemax;

        tablemax=(signed int)pow(value_range,(double)nhoodz)-1;
        if ((pAi=(char*)calloc(value_range,sizeof(char)))==NULL)
					    outof_memory("pAi");
        if ((pA3=(char*)calloc(value_range,sizeof(char)))==NULL)
					    outof_memory("pA3");
        if ((pA2=(char*)calloc(value_range,sizeof(char)))==NULL)
					    outof_memory("pA2");

        /* global variables
           ptype= -1, 0,1, (...2,3,etc. for multi-state) '-1'=any
           pmu=   -1, 2,3,..'i'  '-1'=any        
	*/
       
       /*-------------compute A[1]i A[0]i------------------*/    
       for (type=value_range-1;type>=0;type--){ /* 0s, 1s, 2s etc*/
	 for (zz=nhoodz-1;zz>=0;zz--){  /*nhood rows*/ 
	        /*if (details==1) fprintf(stderr," h%d",nhoodz);*/    
                temp=1;
                for (z=tablemax;z>=0;z--){
                   if (get_value(thisrule,z)==type){ /*check for Ai*/
		      /*if (details==1){
		          fprintf(stderr,"%d%d ",
		             get_value(thisrule,z),get_value(nm[zz],z));
		      }*/
	              if (get_value(nm[zz],z)==type){
		         temp=1;
                      }
                      else{
			 temp=0;
                         break; /*try next nhood row*/
                      }
                   }
                }
                if (temp==1) break; 
             }
             if (temp==1){ 
	        /*if (details==1){
                   fprintf(stderr,"A[%d]i(%d) ",type=zz);
		}*/
                pAi[type]=1;
                post=1;               
                if (ptype==-1 && pmu==-1 && details==0) goto end_post;
             }
       }
       
       /*-------------compute A[x]3 - all triples-----------------*/
       /*all triples, (tablemax+1) choose 3*/
       for (type=value_range-1;type>=0;type--){ 
	     temp=1;
             for (z=tablemax;z>=0;z--){
                if (get_value(thisrule,z)==type){ /*check for 1/0 in table*/
                   temp=1; /*find the mext one*/                    
                   for (nextz=z;nextz>=0;nextz--){
		      if (get_value(thisrule,nextz)==type){
                         temp=1;
                         for (nextz1=nextz;nextz1>=0;nextz1--){
		            if (get_value(thisrule,nextz1)==type){
		               /*check triple has commom 1/0 in some nhood row*/
                               for (zz=nhoodz-1;zz>=0;zz--){ 
                                  thistemp=0;
	                          if (get_value(nm[zz],z)==type && 
				      get_value(nm[zz],nextz)==type &&
                                      get_value(nm[zz],nextz1)==type){
                                      thistemp=1;
                                      break; /*tripple ok, try next tripple*/
                                  }
                               }
                               if (thistemp==1) temp=1;
			       else{
			          temp=0; /*tripple that didnt fit*/
                                  break;
                               }
                            }
                            if (temp==0) break;
		         }
                      }
                      if (temp==0) break;
                   }   
                }
                if (temp==0) break;                  
             }
             if (temp==1){ 
                pA3[type]=1;
                post=1;                
                if (ptype==-1 && pmu==-1 && details==0) goto end_post;
             }
       }

       /*-------------compute A[x]2 - all pairs-----------------*/
       /*all pairs, (tablemax+1) choose 2*/
       for (type=value_range-1;type>=0;type--){ 
	     temp=1;
             for (z=tablemax;z>=0;z--){
                if (get_value(thisrule,z)==type){ /*check for 1/0 in table*/
                   temp=1;/*find the mext one*/                   
                   for (nextz=z;nextz>=0;nextz--){
		      if (get_value(thisrule,nextz)==type){
		         /*check pair has commom 1/0 in some nhood row*/
                         for (zz=nhoodz-1;zz>=0;zz--){ 
                            thistemp=0;
	                    if (get_value(nm[zz],z)==type && 
				 get_value(nm[zz],nextz)==type){
                               thistemp=1;
                               break; /*pair ok, try nexy pair*/
                            }
                         }
                         if (thistemp==1) temp=1;
			 else{
			    temp=0; /*pair that didnt fit*/
                            break;
                         }
		      }
                      if (temp==0) break;
                   }
                }
                if (temp==0) break;                
             }
             if (temp==1){ 
                pA2[type]=1;
                post=1;
                if (ptype==-1 && pmu==-1 && details==0) goto end_post;
             }
       }

       /*----------------------------------------------------*/
       if (box==0){
          if (details==1) sprintf(textb[0],"\n");
           else if (details==2) sprintf(textb[0]," ");
           if (details){
              if (filedata) save_data(textb[0]);
              if (filedata<2) fprintf(stderr,"%s",textb[0]);
          }
          if (details==1){
	    for (type=value_range-1;type>=0;type--){
               sprintf(textb[0],"A[%d]i=%d ",type,pAi[type]);
               sprintf(textb[0],"A[%d]3=%d ",type,pA3[type]);
               sprintf(textb[0],"A[%d]2=%d ",type,pA2[type]);    
               if (filedata) save_data(textb[0]);
               if (filedata<2) fprintf(stderr,"%s",textb[0]);
            }
          }
       }

       if (details==2){
	  char Pi=0,P3=0,P2=0;
	  for (type=value_range-1;type>=0;type--){
             if (pAi[type]==1){
	        Pi=1;
                sprintf(textb[0],"A[%d]i ",type);
                if (box==0){
                   if (filedata) save_data(textb[0]);
                   if (filedata<2) fprintf(stderr,"%s",textb[0]);
                }
                else if (box==1) outtext(textb[0]);
             }
          }
	  for (type=value_range-1;type>=0;type--){       
	     if (pAi[type]==0 && pA3[type]==1){ 
                P3=1;
                sprintf(textb[0],"A[%d]3 ",type);
                if (box==0){
                   if (filedata) save_data(textb[0]);
                   if (filedata<2) fprintf(stderr,"%s",textb[0]);
                }
                else if (box==1) outtext(textb[0]);
	     }
          }
          for (type=value_range-1;type>=0;type--){
             if (pAi[type]==0 &&  pA3[type]==0 && pA2[type]==1){ 
                sprintf(textb[0],"A[%d]2 ",type);
                P2=1;
                if (box==0){
                   if (filedata) save_data(textb[0]);
                   if (filedata<2) fprintf(stderr,"%s",textb[0]);
                }
                else if (box==1) outtext(textb[0]);
             }
	  }
          if (Pi==1) Post_total_i+=1; /*keep count of Post classes*/
          if (P3==1) Post_total_3+=1;
          if (P2==1) Post_total_2+=1;
       } 
      end_post:
       if (ptype==-1 && pmu==-1) goto skip_pcheck;
       post=0;
       if (pmu=='i'){
          /*for specific combinations of  ptype and pmu*/
          if (ptype==-1){ /*pmu='i'for any ptype*/
             for (type=value_range-1;type>=0;type--){
	        if (pAi[ptype]==1){ 
                   post=1;
                   break; 
                }
	     }
           }
           else if (ptype>-1){ /*pmu='i' for given ptype*/
              if (pAi[ptype]==1) post=1;
           }
       }
       if (pmu==3 && post==0){
          if (ptype==-1){ /*pmu=3 for given ptype*/
             for (type=value_range-1;type>=0;type--){
	        if (pA3[ptype]==1){ 
                   post=1;
                   break; 
                }
	     }
           }
           else if (ptype>-1){ /*pmu=2 for given ptype*/
              if (pA3[ptype]==1) post=1;                 
           }
       }
       if ((pmu==-1 || pmu==2) && post==0){
          if (ptype==-1){ /*pmu=2 for any ptype*/
             for (type=value_range-1;type>=0;type--){
	        if (pA2[ptype]==1){ 
                   post=1;
                   break; 
                }
	     }
           }
           else if (ptype>-1){ /*pmu=2 for given ptype*/
              if (pA2[ptype]==1) post=1;
           }
       }
       /*----------------------------------------*/
     skip_pcheck:
       free(pA3); 
       free(pA2);
       free(pAi);
       return(post);
}
    
/****************** select rule/code/mix, Dec 1993 *********************/
signed int rule_selection(void){
  unsigned int self_k1;
  char k1_same_as_k0=0,repeating_blocks=0;
  unsigned int poss,
           temp_lineL, /*for outer-totalistic rules*/
           temp_L;
  signed int  tablemax,tablebytes,
                t_codemax,t_codebytes,
                v_codemax,v_codebytes,
       whichdiff,z,zz,diffz,
       tempx,tempy,tempx1,xbox,endy,boty,
       barlen; /*for progress bar*/
  char amend, /*start and scale of nhood matrix*/
       setcanalyzing,
       thisnhood,
       diffbyhand,
       forcezero,
       post,
       do_progress_bar=0;
  signed int temprand;

   moveto(getx,gety+CHeight);
   isotropic_set=0;
   ptype=-1; /*for post functions*/
   pmu=-1;   /*global variables*/
   if (lineL>=5000 || nhood>=10 ||
            (lineL>=500 && (nhood>=10 || (nhood>=5 && value_range>4)))) 
                 do_progress_bar=1;
   if (tot_only==0){
      tablemax= (signed int)pow(value_range,(double)nhood)-1;
      tablebytes=(signed int)ceil(value_bits * (double)(tablemax+1)/8);
   }
   /*fprintf(stderr,"\n >t_codemax");*/
   t_codemax=nhood*(value_range-1); /*max index of codetable*/
   t_codebytes=(signed int)ceil(value_bits * (double)(t_codemax+1)/8);
   /*fprintf(stderr,"\n >v_codemax");*/
   v_codemax=v_tablecodemax[nhood];
   v_codebytes=(signed int) /*bytes for k-code, min=1*/
            ceil(value_bits * (double)(v_codemax+1)/8);
   tempx=getx;
   tempy=gety;
   amend=0;
   /*show color key, top left*/
   show_multistate_color_key(3); 
   
   /*fprintf(stderr,"\n >rule_selection");*/
 selectrule: 
   if (nhood_mixed==0 || nhood_lb==nhood_ub){
     signed int max_mix; /*max limit for rule-mix*/
      if (lineL<200) max_mix=lineL;
      else max_mix=200;

      if (tot_only==0){
          if (totalistic==0) sprintf(textb[4],
                "single rcode (def), load rcodemix-l");
	  else if (totalistic==1) sprintf(textb[4],
                 "single tcode (def), load tcodemix-l");
          else if (totalistic==2) sprintf(textb[4],
                 "single kcode (def), load kcodemix-l");
      
         sprintf(textb[0],
             "RULES: %s, list Post-P, nhood-matrix-a",textb[4]);
         sprintf(textb[1],"mix: no limit-n, or set limit up to %d:",max_mix);
      }
      else{ /*tot_only==1*/
         if (outer_tot==0){
	    if (totalistic==1) 
              sprintf(textb[2],"TCODES: single tcode (def), load tcodemix-l");
	    else if (totalistic==2) sprintf(textb[2],
              "KCODES: single kcode (def), load kcodemix-l");
            sprintf(textb[0], "%s",textb[2]);
            sprintf(textb[1],"mix: no limit-n, or set limit up to %d:",max_mix);
         }
         else{ /*outer-totalistic rules*/
             if (totalistic==1) sprintf(textb[2],"OuterTcode: number of tcodes");
	     else if (totalistic==2) sprintf(textb[2],"OuterKcode: number of kcodes");
             sprintf(textb[0],"%s to be set=value-range=%d",textb[2],value_range);
             sprintf(textb[1],"cont-ret:");
	 }
      }
      
      xbox=draw_prompt_box(3);
      setcolor(lightred);
      if (TFO_SEED_FIELD==1) outtext("TFO-mode, ");
      else {
         if (TFO_SEED_FIELD==2) outtext("SEED-mode, ");
         else if (TFO_SEED_FIELD==3) outtext("FIELD-mode, ");
      }
      if (outer_tot==0){
         sprintf(textb[4],"density-bias (def %.2f%%)-s:", bias_density_rule);       
         outtext(textb[4]); /*bias lambda, fraction of non-zero entries*/
      }
      setcolor(white);
      moveto(xbox,gety+CHeight);
      outtext(textb[0]);
      moveto(xbox,gety+CHeight);
      outtext(textb[1]);
      input_string(3,0);
      erase_prompt_box(3);
      moveto(tempx,tempy);

     exit_matrix: //to continue after: else if (tot_only==0 && is[0]=='a'){
      if (is[0]=='s'){
         erase_prompt_box(3);
         draw_prompt_box(1);
         sprintf(textb[4],
           "density-bias: enter %% (def %.2f%%):", bias_density_rule);       
         outtext(textb[4]);

         input_string(5,0);
         if (is[0]==13);
	 else if (atof(is)>=0 && atof(is)<=100) bias_density_rule=atof(is);
         goto  selectrule;
      }

      else if (is[0]=='q'){
         /*delete color key, top left*/ 
         show_multistate_color_key(2); 
         return(0);
      }
      else if (outer_tot==1){    /*outer-totalistic rules*/
         temp_lineL=lineL;  /*will be kept in first x=value-range*/
         temp_L=L;          /*cells, as if there was a rule-mix*/
         lineL=value_range;
         L=value_range-1;
         rulemix=1;
	 nodiffrules=0;
         goto outer_tot_skip1;
      } 
      else if (is[0]=='P' && tot_only==0){ /* list Post functions etc */
          post_samples(tablemax,tablebytes,
                     t_codemax,t_codebytes,
                     v_codemax,v_codebytes);
          goto selectrule;
      }
      else if (tot_only==0 && is[0]=='a'){
	  amend=1;
          moveto(tempx,tempy);
          boty=setup_nhood_matrix(amend);
          moveto(tempx,boty+CHeight);
          if (is[0]==13) goto exit_matrix; //to continue
          else{
             is[0]=0;
             goto selectrule;
          } 
      }
      else if (is[0]=='l'){
	 rulemix=1;
	 if (tot_only==0) allocate_mem_rulemix(nhood);
	 allocate_mem_tcodemix(nhood);
	 load_save_wrs('l',NULL,2);/*dummy rule, load a rulemix*/
         /*delete color key, top left*/ 
         show_multistate_color_key(2); 
	 return(tempy);
      }
      else if (is[0]==13){ /*single rule/code*/
	if (tot_only==0){ 
	    if (amend==0){
                boty=setup_nhood_matrix(amend);
                moveto(tempx,boty);
            }
            else if (amend==1)  moveto(tempx,boty);
         }
         else moveto(tempx,gety+CHeight);
	 rulemix=0;
	 if (totalistic==0) select_rule(0,1,carule,1,Maxu,forcezero);
	 else if (totalistic==1) select_t_v_code(0,1,cacode,carule,1,Maxu,forcezero);
         else if (totalistic==2) select_t_v_code(0,1,v_code,carule,1,Maxu,forcezero);
	 /*endy=gety;*/
         endy=boty;
         if (nhood_mixed==1 && nhood_lb==nhood_ub){
            /*if nhood_mixed then must be rulemix even if just 1 rule*/
            rulemix=1; 
	    /*copy the same rule everywhere*/
            if (tot_only==0) allocate_mem_rulemix(nhood);
            allocate_mem_tcodemix(nhood);
            for (poss=lineL-1;poss>=1;poss--){
               if (tot_only==0) memmove(carule[poss],carule[0],tablebytes);
	       if (totalistic==1) memmove(cacode[poss],cacode[0],t_codebytes);
               else if (totalistic==2) memmove(v_code[poss],v_code[0],v_codebytes);
            }
         }
         /*delete color key, top left*/ 
         show_multistate_color_key(2);
	 return(endy); 
      }
      else if (atoi(is)<=max_mix && atoi(is)>0){
	 rulemix=1;
	 nodiffrules=atoi(is);
      }
      else { /* is[0]=='n' or anything else, no-limit to rulemix*/
	 rulemix=1;
	 nodiffrules=0;
      }
   }
   else{ /*mixed nhoods, allocate mem as if for largest nhood*/
      rulemix=1;
      nodiffrules=0;
   }

   outer_tot_skip1:
   /**** rulemix only from here , including outer-totalistic rules****/
   if (tot_only==0) allocate_mem_rulemix(nhood);
   allocate_mem_tcodemix(nhood);
   /*forcezero was here*/
   /*to force nhood=1 wired to itself to equivalent to nhood=0*/
   self_k1=0;
   /*check if they occur*/
   for (poss=lineL-1;poss!=Maxu;poss--){
      if (nhoodm[poss]==1 && wiring[poss][0]==poss) self_k1+=1;      
   }
   if (self_k1>0){
      k1_same_as_k0=0;
      sprintf(textb[0],
      "single self wirings=%d, set rule for k=0 equiv -0:",
	                                self_k1);
      draw_prompt_box(1);
      outtext(textb[0]);
      input_string(1,0);
      erase_prompt_box(1);
      if (is[0]=='q'){
         if (nhood_mixed==0){	    
	    if (tot_only==0) free_mem_rulemix();
	    free_mem_tcodemix();
            rulemix=0;
            if (outer_tot==1){  /*outer-totalistic rulesm - added*/ 
               lineL= temp_lineL;
               L=temp_L;
            } 
	    goto selectrule;
         }
         else{
            /*delete color key, top left*/ 
            show_multistate_color_key(2);
            return(0);
         }
      }
      if (is[0]=='0') k1_same_as_k0=1;
   }
   
   /*select limited rule set min=1, allocate to cells at ramdom from list*/
   /*outer_tot==0*/
   if (nodiffrules>0 && (!nhood_mixed || nhood_lb==nhood_ub)){
      diffbyhand=0;
      if (tot_only==0 && totalistic==0){
         sprintf(textb[0],
	      "RcodeSubset (%d): select by hand-h",nodiffrules);
         sprintf(textb[1],"Alt-A chain-c iso-i Post-P rnd-(def):");
         xbox=draw_prompt_box(2);
         outtext(textb[0]);
         moveto(xbox,gety+CHeight);
         outtext(textb[1]);
         input_string(1,0);
         erase_prompt_box(2);
      }
      else if (totalistic){
	 if (totalistic==2){
            sprintf(textb[0],
	        "KcodeSubset (%d): select by hand-h, Alt-A, rnd-(def):",
						     nodiffrules);
         }
	 else if (totalistic==1) sprintf(textb[0],
	        "TcodeSubset (%d): select by hand-h, rnd-(def):",
						     nodiffrules);
         draw_prompt_box(1);
         outtext(textb[0]);
         input_string(1,0);
         erase_prompt_box(1);
      }
      if (is[0]=='q'){
	 rulemix=0;
	 if (tot_only==0) free_mem_rulemix();
	 free_mem_tcodemix();
	 goto selectrule;
      }
      if (is[0]=='h') diffbyhand=1;
      if (tot_only==0 && is[0]=='P') restrict_post(); 
      if (tot_only==0) allocate_mem_diffrules(nhood,nodiffrules);
      allocate_mem_diffcodes(nhood,nodiffrules);
      if (diffbyhand==1){
	 draw_prompt_box(1);
	 if (totalistic==0) sprintf(textb[0],
               "by hand: subset of %d rcodes",nodiffrules);
	 else if (totalistic==1) sprintf(textb[0],
              "by hand: subset of %d tcodes",nodiffrules);	    
         else if (totalistic==2) sprintf(textb[0],
              "by hand: subset of %d kcodes",nodiffrules);
	   
         outtext(textb[0]);
         
	 moveto(tempx,tempy);
         if (totalistic==0) select_rule(0,2,diffrule,nodiffrules,Maxu,forcezero);
         else if (totalistic==1) 
            select_t_v_code(0,2,diffcode,diffrule,nodiffrules,Maxu,forcezero);
         else if (totalistic==2) 
            select_t_v_code(0,2,v_diffcode,diffrule,nodiffrules,Maxu,forcezero);

	 endy=gety;
	 if (is[0]=='q'){
	    if (tot_only==0) free_mem_diffrules(nodiffrules);
	    free_mem_diffcodes(nodiffrules);
	    goto selectrule;
	 }
      }
      else{
	 if (is[0]!='P' && is[0]!='A' && is[0]!='c' && is[0]!='i' && is[0]!='h') 
                          forcezero=select_forcezero(totalistic);
	 for (diffz=0;diffz<=nodiffrules-1;diffz++){
	    if (totalistic==0){
               if (is[0]=='c')
                  chain_rule(diffrule[diffz],nhood,tablemax,poss);
               else if (is[0]=='A')
                  altenberg_rule(diffrule[diffz],nhood,tablemax);
               else if (is[0]=='i')
		 isotropic_rule(0,diffrule[diffz],nhood,0,tablemax,tablemax,-1);
               else if (is[0]=='P'){	  
	          while(1){
                     post=0;
                     for (zz=0;zz<=tablemax;zz++) 
                         set_value(diffrule[diffz],zz,myrand()%(value_range));
	             post=post_func(nhood, diffrule[diffz],0,0,0,0); /*check post*/
                     if (post==1) break;
                  }
               } 	       
               else{  /*set at random (with bias) */
                  if (bias_density_rule==100*(((float)value_range-1)/value_range)){
	             for (zz=tablemax;zz>=0;zz--)
	                set_value(diffrule[diffz],zz,myrand()%value_range);
                  }
	          else{
	             for (zz=tablemax;zz>=0;zz--){
	                temprand=myrand()%10000; /*0 to 9999*/
                        if (temprand>bias_density_rule*100){
                            set_value(diffrule[diffz],zz,0);
                        }   
                        else{
                           temprand=myrand()%(value_range-1);
                           set_value(diffrule[diffz],zz,temprand+1);
                        }
	             }
	          }
	          if (forcezero==1) set_value(diffrule[diffz],0,0);
               } 
	    }
	    else if (totalistic==1){ /*set at random (with bias) */
               if (bias_density_rule==100*(((float)value_range-1)/value_range)){
	          for (zz=t_codemax;zz>=0;zz--)
	            set_value(diffcode[diffz],zz,myrand()%value_range);
               }
	       else{
	          for (zz=t_codemax;zz>=0;zz--){
	             temprand=myrand()%10000; /*0 to 9999*/
                     if (temprand>bias_density_rule*100){
                        set_value(diffcode[diffz],zz,0);
                     }   
                     else{
                        temprand=myrand()%(value_range-1);
                        set_value(diffcode[diffz],zz,temprand+1);
                     }
	          }
	       }
	       if (forcezero==1) set_value(diffcode[diffz],0,0);
               if (tot_only==0) code2rule(diffrule[diffz],diffcode[diffz],nhood);
	    }
            else if (totalistic==2){
	       if (is[0]=='A'){
                  altenberg_kcode(v_diffcode[diffz],nhood,v_codemax);
                  //if (tot_only==0) v_code2rule(diffrule[diffz],v_diffcode[diffz],nhood,1);
               }
	       else{ /*set at random (with bias) */
                  if (bias_density_rule==100*(((float)value_range-1)/value_range)){
	             for (zz=v_codemax;zz>=0;zz--)
	                   set_value(v_diffcode[diffz],zz,myrand()%value_range);
                  }
	          else{
	             for (zz=v_codemax;zz>=0;zz--){
	                temprand=myrand()%10000; /*0 to 9999*/
                        if (temprand>bias_density_rule*100){
                           set_value(v_diffcode[diffz],zz,0);
                        }   
                        else{
                           temprand=myrand()%(value_range-1);
                           set_value(v_diffcode[diffz],zz,temprand+1);
                        }
	             }
	          }
               }
	       if (forcezero==1) set_value(v_diffcode[diffz],0,0);               
               if (tot_only==0) v_code2rule(diffrule[diffz],
                                  v_diffcode[diffz],nhood,1);
	    }
	 }
      }
      
      
      /*option to assign sub-rules, randomly or repeating/consecutive blocks*/
      whichdiff=-1;
      repeating_blocks=0;
      xbox=draw_prompt_box(2);
      if (tot_only==0 && totalistic==0) sprintf(textb[0],
				      "%d Rcodes were set",nodiffrules);
      else if (totalistic){
           if (totalistic==2) sprintf(textb[0],
                                      "%d Kcodes were set",nodiffrules);
           if (totalistic==1) sprintf(textb[0],
                                      "%d Tcodes were set",nodiffrules);
      }
      outtext(textb[0]);
      moveto(xbox,gety+CHeight);
	   sprintf(textb[0],"apply as repeating blocks-b, or randomly-(def):");
      outtext(textb[0]);        
      input_string(1,0);
      erase_prompt_box(2);
      if (is[0]=='b') repeating_blocks=1;

      if (do_progress_bar==1 && outer_tot==0){
         progress_bar();
         /*wont work without this - dont understand why necessary*/
         while(event_ready()==0){
            break;
         }
      }

      for (poss=lineL-1;poss!=Maxu;poss--){
	//fprintf(stderr,"\n%d:",poss);
	 /*count down cells allocated*/
       if (do_progress_bar==1){
            if (poss%(lineL/10)==0){
               setfillstyle(SOLID_FILL,green);
	       barlen=(signed int)((double)(barxr-barxl-2)*
				  ((double)(L-poss)/L));
	       bar(barxl+1,baryt+vgay(2),barxl+barlen,baryb-vgay(2));
               /*wont work without this - dont understand why necessary ??*/
               while(event_ready()==0){
                  break;
               }     
	    } 
	}

        if (repeating_blocks==1){ /*consecutive/repeating rules, alternating if nodiffrules=2*/
	   whichdiff++;
           if (whichdiff>=nodiffrules){
	      poss+=1;
              whichdiff=-1;
              continue;
           }
           //fprintf(stderr,"%d ",whichdiff);
        }
        else whichdiff= myrand()%nodiffrules;

	if (tot_only==0) memmove(carule[poss],diffrule[whichdiff],tablebytes);
	if (totalistic==1) memmove(cacode[poss],
				 diffcode[whichdiff],t_codebytes);
        else if (totalistic==2) memmove(v_code[poss],
				 v_diffcode[whichdiff],v_codebytes);
      }
      if (tot_only==0) free_mem_diffrules(nodiffrules);
      free_mem_diffcodes(nodiffrules);
      moveto(tempx,tempy);
      if (do_progress_bar==1){
         xbox=(signed int)((float)Maxx)/2;/*erase progress bar*/
         erase_box(xbox,vgay(30),Maxx-2,vgay(30)+vgay(9)+vgay(3));
      }
      if (diffbyhand==1){
          /*delete color key, top left*/ 
          show_multistate_color_key(2);
          return(endy);
      }
      else{
          /*delete color key, top left*/ 
          show_multistate_color_key(2);
          return(tempy);
      }
   }
   /*------------------------------------------------------------------------------*/
   else{ /*not limited rule-set, the whole network, or v cells for outer k-totalistic*/
      /*
      if (!nhood_mixed)
	sprintf(textb[0],"select by hand-h, glider-g, random-(def):");
      else sprintf(textb[0],"select by hand-h, random-(def):");
      */
     selectnet:
      setcanalyzing=0;
      sprintf(textb[0],"");
      sprintf(textb[1],"");
      if (tot_only==0 && totalistic==0){
	 if (nhood_mixed==0) sprintf(textb[0],
              "RcodeMix: select by hand-h, maj-m/u Alt-A chain-c iso-i Post-P");
         else sprintf(textb[0], //iso-i and Post-P do not work for RcodeMix 
              "RcodeMix: select by hand-h, maj-m/u Alt-A chain-c");
         sprintf(textb[1],"canalyzing-C/+C, rnd-(def):");
      }
      else if (totalistic){ 
	  if (totalistic==2){ /*outer including ReactionDiffusion, outer tcode applies when tot_only==1*/
	     if (tot_only==1 && outer_tot==1) sprintf(textb[0], /*outer including ReactionDiffusion*/
                "OuterKcode (%d): select by hand-h, RD-R Life-L maj-m/u  Alt-A rnd-(def):",
                           value_range);
             else sprintf(textb[0],"KcodeMix: select by hand-h, maj-m/u Alt-A rnd-(def):");
          }
	  else if (totalistic==1){ /*outer tcode applies when tot_only==1*/
             if (tot_only==1 && outer_tot==1) sprintf(textb[0], 
                "OuterTcode (%d): select by hand-h, maj-m/u rnd-(def):",value_range);
             else sprintf(textb[0],"TcodeMix: select by hand-h, maj-m rnd-(def):");
          }
      }
      
      if (tot_only==0 && totalistic==0){
         xbox=draw_prompt_box(2);
         outtext(textb[0]);
         moveto(xbox,gety+CHeight);
         outtext(textb[1]);
      }
      else{ 
         xbox=draw_prompt_box(1);
         outtext(textb[0]);
      }
      input_string(2,0);
      erase_prompt_box(2);
      if (is[0]=='q'){
	 if (nhood_mixed==0){	    
	    if (tot_only==0) free_mem_rulemix();
	    free_mem_tcodemix();
            rulemix=0;
            if (outer_tot==1){    /*outer-totalistic rules*/
               lineL= temp_lineL;
               L=temp_L;
            } 
	    goto selectrule;
	 }
	 else{
            return(0);
            /*delete color key, top left*/ 
            show_multistate_color_key(2); 
	 }
      }
      else if (is[0]=='h'){
         draw_prompt_box(1);
	 if (outer_tot==1){            
            if (totalistic==1) sprintf(textb[0],
                    "by hand: outertot of %d tcodes",lineL);
	    else if (totalistic==2) sprintf(textb[0],
                       "by hand: outertot of %d kcodes",lineL);
         }
         else{
            if (totalistic==0) sprintf(textb[0],
                    "by hand: rcodemix of %d rcodes",lineL);
            if (totalistic==1) sprintf(textb[0],
                    "by hand: tcodemix of %d tcodes",lineL);
	    else if (totalistic==2) sprintf(textb[0],
                       "by hand: kcodemix of %d kcodes",lineL);
         }
         outtext(textb[0]);
         if (nhood_mixed==1){
	   sprintf(textb[0]," (kmix %d-%d)",nhood_lb, nhood_ub);
           outtext(textb[0]);
         }
	 moveto(tempx,tempy);
	 if (totalistic==0) select_rule(0,0,carule,lineL,Maxu,forcezero);
	 else if (totalistic==1) select_t_v_code(0,0,cacode,carule,lineL,Maxu,forcezero);
         else if (totalistic==2) select_t_v_code(0,0,v_code,carule,lineL,Maxu,forcezero);
	 endy=gety;
         /*delete color key, top left*/ 
         show_multistate_color_key(2);
         if (outer_tot==1){    /*outer-totalistic rules*/
               lineL= temp_lineL;
               L=temp_L;
               rulemix=0;
         } 
	 return(endy);
      }

      /*create rule-scheme of all glider rule files, save later
        was needed for converting old v=2 .r_s to multi-value encoding*/
      /*else if (is[0]=='g' && !nhood_mixed){
	 fprintf(stderr,"no_glider_rules[%d][%d] tablebytes=%d: ",
                   value_range,nhood,tablebytes); 
	 for (poss=1;poss<=no_glider_rules[value_range][nhood]-1;poss++){
           memmove(carule[poss],glider_buf+6+poss*tablebytes,tablebytes);
           fprintf(stderr,"%d ",poss);
           
         }
	 erase_prompt_box(1);
	 moveto(tempx,tempy);
	 
         show_multistate_color_key(2); 
         return(tempy);
      }*/

      /*create complex rule sample - 1d rules, first set n=sample size
      from series of single rcodes named v%dk%d_c%d.rul -- no longer needed*/
      else if (tot_only==0 && is[0]=='G' && !nhood_mixed){
        unsigned char *buf;
        signed int fid,rulebytesM,tablemaxM;
        fprintf(stderr,"\n loading %d rules :",
                    no_glider_rules[value_range][nhood]);
        tablemaxM= (signed int)pow(value_range,(double)nhood)-1;
        rulebytesM=(signed int)ceil(value_bits * (double)(tablemaxM+1)/8);
        if ((buf=(unsigned char *)calloc(2+rulebytesM,sizeof(unsigned char)))
		 ==NULL) outof_memory("buf for loading complex rule sample");

	for (poss=0;poss<=no_glider_rules[value_range][nhood]-1;poss++){
          fprintf(stderr,"\n v%dk%d_c%d.rul",value_range,nhood,poss);
	  sprintf(filename,"v%dk%d_c%d.rul",value_range,nhood,poss);
          /*max buffer to store bytes, for max nhoood*/
          fid=myopen(filename,0,0);
          if (fid==-1) file_error(filename);
          /*first byte=k, second=nhood size, read into buf*/
          vret=read(fid,buf,2+rulebytesM);
          memmove(carule[poss],buf+2,rulebytesM);         
        }
	free(buf);
        /*dont forget to save the rule scheme 
          from the 1d wiring graphic, with a filename like g_v4k3.r_s
          this is loaded on-the-fly with 'g', see glider_rule( in forvar*.c */
      }
      /*create complex rule sample - 2d k-code,  first set n=sample size
        from series of single kcodes named v%dk%dc%d.vco -- no longer needed*/
      else if (tot_only==1 && totalistic==2  && is[0]=='G' && !nhood_mixed){
        unsigned char *buf;
	signed int fid,rulebytesM,tablemaxM;
        fprintf(stderr,"\n loading %d rules :",
                    no_glider_rules[value_range][nhood]);
        tablemaxM= v_tablecodemax[nhood];
        rulebytesM=(signed int) /*bytes for k-code, min=1*/
            ceil(value_bits * (double)(tablemaxM+1)/8);
        if ((buf=(unsigned char *)calloc(2+rulebytesM,sizeof(unsigned char)))
		 ==NULL) outof_memory("buf for loading complex rule sample");

        for (poss=0;poss<=no_glider_rules[value_range][nhood]-1;poss++){
          fprintf(stderr,"\n v%dk%dc%d.vco",value_range,nhood,poss);
	  sprintf(filename,"v%dk%dc%d.vco",value_range,nhood,poss);
          /*max buffer to store bytes, for max nhoood*/
          fid=myopen(filename,0,0);
          if (fid==-1) file_error(filename);
          /*first byte=k, second=nhood size, read into buf*/
          vret=read(fid,buf,2+rulebytesM);
           
          memmove(v_code[poss],buf+2,rulebytesM);         
        }
	free(buf);
        /*dont forget to save the rule scheme 
          from the 1d wiring graphic, with a filename like g_v3k6.r_s
          this is loaded on-the-fly with 'g', see glider_rule( in forvar*.c */
      }
      else{
         if (tot_only==0 && is[0]=='P') restrict_post();
         if (tot_only==0 && (is[0]=='C' || (is[1]=='C' && is[0]!='P')) ) setcanalyzing=1;
         if (is[0]!='m' && is[0]!='u' && is[0]!='P' && is[0]!='A' 
              && is[0]!='R' && is[0]!='L' && is[0]!='c'
              && is[0]!='i' && is[0]!='h') forcezero=select_forcezero(totalistic); 
         if (do_progress_bar==1 && outer_tot==0){ 
            progress_bar();
            /*wont work without this - dont understand why necessary*/
            while(event_ready()==0){
               break;
            }
	 }
       	 for (poss=lineL-1;poss!=Maxu;poss--){
           /*fprintf(stderr,"\n---poss=%d---",poss);*/
	   /*if (poss%(lineL/10)==0) fprintf(stderr,"\nposs=%d",poss);*/
	    if (nhood_mixed){
	       thisnhood=nhoodm[poss];
	       /*max index of ruletable*/
               if (tot_only==0){
                  tablemax= 
                   (signed int)pow(value_range,(double)thisnhood)-1;
                  tablebytes=(signed int)ceil(
                            value_bits * pow(value_range,(double)thisnhood)/8);
               }
               t_codemax=thisnhood*(value_range-1);
               t_codebytes=(signed int)ceil(value_bits * (double)(t_codemax+1)/8);
               v_codemax=v_tablecodemax[thisnhood];
               v_codebytes=(signed int) /*bytes for vcode, min=1*/
                      ceil(value_bits * (double)(v_codemax+1)/8);
	    }
	    else thisnhood=nhood;
	    /*progress bar for cells allocated*/
            if (do_progress_bar==1 && outer_tot==0){
               if (poss%(lineL/10)==0){
		  /*fprintf(stderr,"  bar:poss=%d\n",poss);*/
                  setfillstyle(SOLID_FILL,green);
	          barlen=(signed int)((double)(barxr-barxl-2)*
				  ((double)(L-poss)/L));
	          bar(barxl+1,baryt+vgay(2),barxl+barlen,baryb-vgay(2));
                  /*wont work without this - dont understand why necessary*/
                  while(event_ready()==0){
                     break;
                  }
               }         
	    }
            /*majority rule - rule,kcode,tcode 'u' for unanimous*/
            if (is[0]=='m' || is[0]=='u'){
              
	       if (tot_only==0 && totalistic==0){
		  majority_rule(carule[poss],thisnhood,tablemax);
	          
                  if (is[0]=='u') /*flip or shift outputs from unanimous (uniform) nhoods*/
		    shift_outputs_unanimous(carule[poss],tablemax,thisnhood,poss);

	       }
               else if (totalistic==1){
                  majority_tcode(cacode[poss],thisnhood,t_codemax);
                  if (tot_only==0) code2rule(carule[poss],cacode[poss],thisnhood);
               }
               else if (totalistic==2){                   
                  majority_or_fprintf_vcode(1,v_code[poss],thisnhood);
                  if (is[0]=='u') /*flip or alter outputs from unanimous (uniform) states*/
                     shift_outputs_unanimous(v_code[poss],v_codemax,thisnhood,poss);
  
                  if (tot_only==0) v_code2rule(carule[poss],v_code[poss],thisnhood,1);
	       } 
	    } /*end majority rule - rule,kcode,tcode -- if (is[0]=='m'*/

            else if (tot_only==0 && is[0]=='c') /*rule only*/
              chain_rule(carule[poss],thisnhood,tablemax,nhoodm[poss]);
            else if (tot_only==0 && is[0]=='A' && totalistic==0)
               altenberg_rule(carule[poss],thisnhood,tablemax);
            else if (is[0]=='A' && totalistic==2){ /*added Dec 04, corrected 08*/
               altenberg_kcode(v_code[poss],thisnhood,v_codemax);
               if (tot_only==0) v_code2rule(carule[poss],v_code[poss],thisnhood,1);
	    }
            /*reaction-diffusion outer-totalistic rules, added Dec 04*/
            else if (tot_only==1 && outer_tot==1 && totalistic==2){
               if (is[0]=='R'){
                  if (poss==0) set_reaction_diffusion_outer(
                               1,v_code[poss],thisnhood,v_codemax);
                  else{
                    signed int temp;
                     temp=poss+1;
                     if (poss==value_range-1) temp=0;
	             for (z=0;z<=v_codemax;z++) set_value(v_code[poss],z,temp);
                  }
               }
               else if (is[0]=='L'){ /*game-of-Life using outer-totalistic kcode*/
		  if (poss==lineL-1){
                     Ltempx=getx;
                     Ltempy=gety;
                     game_of_Life_para('k',nhoodm[poss]);
		     game_of_Life_kcode(v_code[poss],thisnhood,v_codemax,(char)poss);
                  }

                  if (poss<lineL-1){
                     game_of_Life_kcode(v_code[poss],thisnhood,v_codemax,(char)poss);

                  }
                  if (poss==0){
                     free(birth);
                     free(survival);
                     moveto(Ltempx,Ltempy);
                  }
                  is[0]='L'; /*restore the choice -- changed when setting birth/survival*/
               }
	    }
            /*-------------*/
            else if (tot_only==0 && is[0]=='i' && nhood_mixed==0)
	      isotropic_rule(0,carule[poss],thisnhood,0,tablemax,tablemax,-1);
            else if (tot_only==0 && is[0]=='P' && nhood_mixed==0){
	       while(1){
		  post=0;
                  for (zz=0;zz<=tablemax;zz++) 
                      set_value(carule[poss],zz,myrand()%(value_range));
	          post=post_func(thisnhood, carule[poss],0,0,0,0); /*check post*/
                  if (post==1) break;
               }
            }
            /*random rules*/
	    else if (totalistic==0){ /*set at random (with bias) */
               if (bias_density_rule==100*(((float)value_range-1)/value_range)){
	          for (zz=tablemax;zz>=0;zz--)
	                set_value(carule[poss],zz,myrand()%value_range);
               }
	       else{
	          for (zz=tablemax;zz>=0;zz--){
	             temprand=myrand()%10000; /*0 to 9999*/
                     if (temprand>bias_density_rule*100){
                         set_value(carule[poss],zz,0);
                     }   
                     else{
                        temprand=myrand()%(value_range-1);
                        set_value(carule[poss],zz,temprand+1);
                     }
	          }
	       }
	       if (forcezero==1) set_value(carule[poss],0,0);
	    }    	    
	    /*random tcodes*/
	    else if (totalistic==1){ /*set at random (with bias) */
               if (bias_density_rule==100*(((float)value_range-1)/value_range)){
	          for (zz=t_codemax;zz>=0;zz--)
	            set_value(cacode[poss],zz,myrand()%value_range);
               }
	       else{
	          for (zz=t_codemax;zz>=0;zz--){
	             temprand=myrand()%10000; /*0 to 9999*/
                     if (temprand>bias_density_rule*100){
                        set_value(cacode[poss],zz,0);
                     }   
                     else{
                        temprand=myrand()%(value_range-1);
                        set_value(cacode[poss],zz,temprand+1);
                     }
	          }
	       }
	       if (forcezero==1) set_value(cacode[poss],0,0);
               if (tot_only==0) code2rule(carule[poss],cacode[poss],thisnhood);
            }
            /*random kcodes*/           
            else if (totalistic==2){  /*set at random (with bias) */
               if (bias_density_rule==100*(((float)value_range-1)/value_range)){
	             for (zz=v_codemax;zz>=0;zz--)
	                   set_value(v_code[poss],zz,myrand()%value_range);
               }
	       else{
	          for (zz=v_codemax;zz>=0;zz--){
	             temprand=myrand()%10000; /*0 to 9999*/
                     if (temprand>bias_density_rule*100){
                        set_value(v_code[poss],zz,0);
                     }   
                     else{
                        temprand=myrand()%(value_range-1);
                        set_value(v_code[poss],zz,temprand+1);
                     }
	          }
	       }
	       if (forcezero==1) set_value(v_code[poss],0,0);               
               if (tot_only==0) v_code2rule(carule[poss],v_code[poss],thisnhood,1);
            }
            /*sequence of rule numbers*/
	    /*else dec_to_bit_line(carule[poss],255-poss,tablemax+1);*/
	    
	    /*to force nhood=1 wire to itself to equivalent to nhood=0*/
            if (k1_same_as_k0==1){	      
	       if (thisnhood==1 && wiring[poss][0]==poss){
		   for (zz=value_range-1;zz>=0;zz--){
                       if (tot_only==0) set_value(carule[poss],zz,zz);
                       if (totalistic==1) set_value(cacode[poss],zz,zz);
                       if (totalistic==2) set_value(v_code[poss],zz,zz);
                   }
	        }	       
	    }
	    moveto(tempx1,gety);
      	 }
                  
	 if (tot_only==0 && setcanalyzing){
	    set_canalyzing_net(forcezero);
	    if (is[0]=='q') goto selectnet;
	 }
         /*erase progress bar*/
	 moveto(tempx,tempy);
         if (do_progress_bar==1 && outer_tot==0){
            xbox=(signed int)((float)Maxx)/2;
            erase_box(xbox,vgay(30),Maxx-2,vgay(30)+vgay(9)+vgay(3));
         }
         /*delete color key, top left*/ 
         show_multistate_color_key(2); 
         if (outer_tot==1){    /*outer-totalistic rules*/
               lineL= temp_lineL;
               L=temp_L;
               rulemix=0;
         }       
	 return(tempy);
      }
   }
   /*delete color key, top left*/ 
   show_multistate_color_key(2);
   if (outer_tot==1){  /*outer-totalistic rules*/ 
      lineL= temp_lineL;
      L=temp_L;
      rulemix=0;
   } 
   return(tempy);   
}

/**************majority rules - flip or shift outputs from unanimous (uniform) nhoods ******/
void shift_outputs_unanimous(char *thisrule,signed int this_tablemax, 
                                      signed int thisnhood,signed int poss){
  char uniform; 
  signed int zz,z;

                 if (tot_only==0 && totalistic==0){
                   signed int firstv;

                    for (zz=0;zz<=this_tablemax;zz++){		       
		       if (value_range==2){
                          if (zz==0 || zz==this_tablemax)
		            set_bit(thisrule,zz,abs(get_bit(thisrule,zz))-1);
		       }
		       else if (value_range>2){
			   uniform=1;
			   firstv=get_value(nm[0],zz);
			   for (z=thisnhood-1;z>=1;z--){
			      if (firstv!=get_value(nm[z],zz)){ 
                                  uniform=0;
                                  break;
			      }
			   }
			   if (uniform==1){
			      if (zz==0) set_value(thisrule,zz,value_range-1);
                              else set_value(carule[poss],zz,get_value(thisrule,zz)-1);
                              
                           }
                        }
                     }
		  }
                  else if (totalistic==2){
                    signed int v_bits,temptot;

                     for (zz=0;zz<=this_tablemax;zz++){		       
		       if (value_range==2){
                          if (zz==0 || zz==this_tablemax)
		            set_bit(v_code[poss],zz,abs(get_bit(v_code[poss],zz))-1);
		       }
		       else if (value_range>2){
                           v_bits=check_value_bits(thisnhood+1);
			   /*fprintf(stderr,"\n");*/
                           uniform=0;
                           for (z=value_range-1; z>=0; z--){
			       temptot=get_value_flex(v_index[thisnhood][zz],z,v_bits);
			       /*fprintf(stderr,"%d ",temptot);*/
                               if (temptot>0 && temptot<thisnhood) break;
                               else if (temptot==thisnhood){ 
                                  uniform=1;   
                                  break;
                               }
                           }   			  
			   if (uniform==1){
			      if (zz==0) set_value(v_code[poss],zz,value_range-1);
                              else set_value(v_code[poss],zz,get_value(v_code[poss],zz)-1);
                           }
                        }
                      }
		   }

}

/************ select forcezero, all0s->0  *************/
char select_forcezero(char totalistic){
  char forcezero,temp_is0;

   temp_is0=is[0];
   if (totalistic){ 
      forcezero=0;
      if (totalistic==1)
          sprintf(textb[0],"tcodemix, force all 0s->0 -0:");
      else if (totalistic==2)
          sprintf(textb[0],"kcodemix, force all 0s->0 -0:");
   }
   else{
      forcezero=1;
      sprintf(textb[0],
	   "rcodemix: allow any rule-a, or force all 0s->0-(def):");
   }
   draw_prompt_box(1);
   outtext(textb[0]);
   input_string(1,0);
   erase_prompt_box(1);
   
   if (totalistic){
      if (is[0]=='0') forcezero=1;
   }
   else{
      if (is[0]=='a') forcezero=0;
   }
   is[0]=temp_is0;
   return(forcezero);
}

/************ set colors for canalising - mixed k *************/
unsigned char set_canal_color(   
   char just_this_k,unsigned int canaltotal,char this_k){
  unsigned char c_color;
   
   if ((nhood_mixed && just_this_k==0)  
              || just_this_k>9 || (!nhood_mixed && nhood>9)){
      /*set colors for canalising - mixed k or k>9*/ 	    
      if (canaltotal==(unsigned int)this_k) c_color=5;
      else if ((float)canaltotal/this_k>=.75) c_color=4;
      else if ((float)canaltotal/this_k>=.5)  c_color=3;
      else if ((float)canaltotal/this_k>=.25) c_color=2;
      else if ((float)canaltotal/this_k>0)    c_color=1;
      else c_color=0;	       
   }
   else{ /*set colors for canalising - single k*/
      if (canaltotal==(unsigned int) this_k) c_color=9;
      else if (canaltotal==(unsigned int) this_k-1
		     && this_k>=4)             c_color=8;
      else if (canaltotal==(unsigned int) this_k-2
		     && this_k>=7)             c_color=7;
      else if (
	 (canaltotal==(unsigned int) this_k-3 && this_k>=7)||
         (canaltotal==(unsigned int) this_k-2 && this_k==6)
		                       )       c_color=6;
      else if (canaltotal==(unsigned int) this_k-4
		           && this_k>=8)       c_color=5;
      else if (
	 (canaltotal==(unsigned int) this_k-5 && this_k>=8)||
	 (canaltotal==(unsigned int) this_k-4 && this_k==7)||
	 (canaltotal==(unsigned int) this_k-3 && this_k==6)||
	 (canaltotal==(unsigned int) this_k-2 && (this_k==5||
		                                    this_k==4))||
         (canaltotal==(unsigned int) this_k-1 && (this_k==3||
		                                    this_k==2))
		                             ) c_color=4;
      else if (
	 (canaltotal==(unsigned int) this_k-6 && this_k>=8)||
	 (canaltotal==(unsigned int) this_k-5 && this_k==7)||
	 (canaltotal==(unsigned int) this_k-4 && this_k==6)||
	 (canaltotal==(unsigned int) this_k-3 && (this_k==5||
		                                    this_k==4))||
         (canaltotal==(unsigned int) this_k-2 && this_k==3)
		                             ) c_color=3;
      else if (canaltotal==(unsigned int) this_k-7
	                         && this_k>=9) c_color=2;
      else if (canaltotal==1 && this_k>=5)     c_color=1;
      else                                     c_color=0;
   }        
   return c_color;
}
/**** show/select percentage/number of canalizing genes/inputs, Feb 95 ****/
void set_canalyzing_net(char forcezero){
  unsigned int poss,temp,cgenenet,newcgenenet,
		 zu,zu1;
  unsigned long  zulong,count_tries,inputtotal,cinputnet,newcinputnet,
		 canalcount;
  float newcinputfreq,
	cgenefreq,newcgenefreq;
  signed int  topy,tempx,tempy,
                tablemax,tempx1,
		cindex,z,zz,xbox,ybox;
  unsigned int show_tries,
                 thistotal,**k_buf,*k_tempcount,*k_count,netsize,
                 startcanaltotal,
                  *freq_no_canal, *freq_percent_canal;
  signed int just_this_k,wire,cz;
  char thisnhood,
       thisbit,
       search_direction,nleft,nright,
       reducecanal,
       binv,
       boutv,
       settype,
       ctype,       
       outvalue;
  signed int *shuff_wire;

  float left=0,boxleft=0,top=0,right=0,bottom=0,
	cellscale=0,cellsep=0,
	maxside=0;
  unsigned char thiscolor,c_color,*color_p,*color_n;
  signed int ii,jj,width_diagram;

   /*alloc buffers for color-canalizing frequency*/
   if ((color_p=(unsigned char*)calloc(6,sizeof(unsigned char)))
			    ==NULL) outof_memory("color_p");   
   if ((color_n=(unsigned char*)calloc(10,sizeof(unsigned char)))
			    ==NULL) outof_memory("color_n");   
   color_p[5]=white; /*percent colors*/
   color_p[4]=yellow;
   color_p[3]=lightred;
   color_p[2]=green;
   color_p[1]=blue;
   color_p[0]=darkgray;

   color_n[9]=white; /*number colors*/
   color_n[8]=brown;
   color_n[7]=lightcyan;
   color_n[6]=yellow;
   color_n[5]=red;
   color_n[4]=lightred;
   color_n[3]=green;
   color_n[2]=blue;
   color_n[1]=lightgray;
   color_n[0]=darkgray;
   /*to shuffle wiring*/
   if ((shuff_wire=(signed int*)calloc(Maxnhood,sizeof(signed int)))
			    ==NULL) outof_memory("shuff_wire");

   if (!nhood_mixed) tablemax= (signed int)pow(value_range,(double)nhood)-1;
   
   if (nhood_mixed || nhood>9){ 
      if ((k_count=(unsigned int*)calloc(Maxnhood+1,sizeof(unsigned int)))
			    ==NULL) outof_memory("k_count");
      for (poss=0;poss<=lineL-1;poss++){
         k_count[(signed int)nhoodm[poss]]+=1;    
      }

      if ((k_buf=(unsigned int**)calloc(Maxnhood+1,
	    sizeof(unsigned int*)))==NULL) outof_memory("k_buf*");     
      for (z=1;z<=Maxnhood;z++){
         if ((k_buf[z]=(unsigned int*)calloc(k_count[z]+1,
	    sizeof(unsigned int)))==NULL) outof_memory("k_buf");
      }
      if ((k_tempcount=(unsigned int*)calloc(Maxnhood+1,
	    sizeof(unsigned int)))==NULL) outof_memory("k_tempcount");
       
      /*fill arrays with positions of ks*/
      for (poss=0;poss<=lineL-1;poss++){
         for (z=1;z<=Maxnhood;z++){
	    if (nhoodm[poss]!=z) continue;
	    else{
		k_buf[z][k_tempcount[z]]=poss;
		k_tempcount[z]+=1;
		break;
	    }                    
	 }
      }
      free(k_tempcount);
   }
   
   /*draw basic grid for % canalyzing input distribution diagram*/
   if (!twod){  	 
       for (z=(signed int)ceil(pow((double)lineL,.5));z>=1;z--){
	       if (lineL%z==0) break;
       }
       j2d=z;
       i2d=(signed int)ceil((double)lineL/j2d);  
   }
   
   if (i2d>=j2d)  maxside=i2d;
   else maxside=j2d;

   if (i2d<=30 && j2d<=30){
      cellscale=vgax(7);
      cellsep=vgax(3);
   }
   else {
      cellscale=floor((float)vgax(250)/maxside);
      if (cellscale>=3) cellsep=2;
      else cellsep=1;
   }
   if (cellscale<1){
      cellscale=1;
      cellsep=1;
   }		
   width_diagram=(i2d+1)*cellscale;
   if (width_diagram<Maxx/3) width_diagram=Maxx/3; 
   /*bottom=vgay(390);*/
   bottom=vgay(400);
   top=bottom-(j2d+1)*cellscale;
   right=Maxx-vgax(45);
   boxleft=right-width_diagram;
   left=right-(i2d+1)*cellscale;

   /*remember the box to restore*/
   draw_box(18,boxleft-vgax(40),top-vgay(100),
			       right+vgax(40),bottom+vgay(20),0,-1);
  start:
   just_this_k=0;
   if (!nhood_mixed && nhood>9) just_this_k=nhood;
   if (!nhood_mixed) xbox=draw_prompt_box(2);
   else xbox=draw_prompt_box(4);
   outtext("set canalyzing genes-g inputs-(def):");
   input_string(1,0);

   if (is[0]=='q'){
      if (!nhood_mixed && nhood<=9){
	  erase_prompt_box(2);
      }
      else{
	  erase_prompt_box(4);
          free(k_count);
	  for (z=1;z<=Maxnhood;z++) free(k_buf[z]);
	  free(k_buf);
      }
      free(shuff_wire);

      sprintf(textb[9],"%s","boximage[18]");
      putimage(boxleft-vgax(40),top-vgay(100),
		            boximage[18],COPY_PUT,textb[9]);
      freeimage(boximage[18]);

      free(color_p);
      free(color_n);
      erase_memory_box(0);
      return;
   }
   if (is[0]=='g') ctype='g';
   else ctype='i';

   moveto(xbox,gety+CHeight);
   if (nhood_mixed) outtext("mixed k, ");
   if (ctype=='i')
	outtext("c-inputs: redo-q number-n, %-(def):");
   else outtext("c-genes: redo-q number-n, %-(def):");
   input_string(1,0);
   if (is[0]=='q') goto start;
   if (is[0]=='n') settype='n';
   else settype='p';
   
   if (nhood_mixed){      
      moveto(xbox,gety+CHeight);   
      outtext("%k: ");
      for (z=1;z<=Maxnhood;z++){
	  if (k_count[z]>0){
	     sprintf(textb[0],"%d:%.1f ",
		            z,(float)(k_count[z]*100)/lineL);
             outtext(textb[0]);
          }
      }
      moveto(xbox,gety+CHeight);   
       
      just_this_k=0;
      outtext("enter k for just one nhood, all-(def):");
      input_string(2,0);
      if (is[0]==13); 
      else if (atoi(is)>=1 && atoi(is)<=Maxnhood){
         if (k_count[atoi(is)]>0) just_this_k=atoi(is);
      }
   }
   if (!nhood_mixed) erase_prompt_box(2);
   else erase_prompt_box(4);
   
  resetcanal:
   cgenenet=inputtotal=0;
   cinputnet=0;
   
   /*draw net color coded to show % canalyzing input distribution*/
   draw_box(-1,boxleft-vgax(40),top-vgay(100),
			       right+vgax(40),bottom+vgay(20),1,0);
   for (z=0;z<=bytesL-1;z++) iscanal[z]=0; /*set to null*/
   /*draw 2-d outline*/
   draw_box(-1,left+cellscale-2,top+cellscale-2,right,bottom,1,0);     
   /*add co-ords to grid*/
   moveto(right-i2d*cellscale+(cellscale-cellsep)/2,
		     bottom-j2d*cellscale+(cellscale-cellsep)/2);
   line(getx,gety-vgay(10),getx,gety-vgay(5));
   sprintf(textb[0],"%d",i2d-1);
   moveto(getx-textwidth(textb[0])/2,gety-vgay(12)-CHeight);
   outtext(textb[0]);

   moveto(right-i2d*cellscale+(cellscale-cellsep)/2,
		     bottom-j2d*cellscale+(cellscale-cellsep)/2);
   line(getx-vgax(10),gety,getx-vgax(5),gety);
   sprintf(textb[0],"%d",j2d-1);
   moveto(getx-textwidth(textb[0])-vgax(11),
				     gety-(float)CHeight*.7);
   outtext(textb[0]);

   moveto(right-cellscale+((cellscale-cellsep)/2),
		     bottom-cellscale+((cellscale-cellsep)/2));
   line(getx+vgax(5),gety,getx+vgax(10),gety);
   moveto(getx+vgax(12),gety-(float)CHeight*.7);
   outtext("0");

   moveto(right-cellscale+((cellscale-cellsep)/2),
		     bottom-cellscale+((cellscale-cellsep)/2));
   line(getx,gety+vgax(5),getx,gety+vgax(10));
   moveto(getx-CHeight/2,gety+vgay(9));
   outtext("0");
   
   /*alloc buffers for canalizing frequency*/
   if ((freq_percent_canal=(unsigned int*)
	calloc(6,sizeof(unsigned int)))
		       ==NULL) outof_memory("freq_percent_canal");   
   if ((freq_no_canal=(unsigned int*)calloc(10,sizeof(unsigned int)))
			    ==NULL) outof_memory("freq_no_canal");
   
   for (poss=lineL-1;poss!=Maxu;poss--){
      if (nhood_mixed && just_this_k>0){
         if (just_this_k!=nhoodm[poss]) continue;
      }
      if (nhood_mixed) inputtotal+=nhoodm[poss];
      canalyzing(nhoodm[poss],0,carule[poss]);
      ii=poss%i2d;
      jj=poss/i2d;
      moveto(right-(ii+1)*cellscale,bottom-(jj+1)*cellscale);
      /*set colors for canalising*/
      c_color=set_canal_color(just_this_k,canaltotal,nhoodm[poss]);
      
      freq_no_canal[c_color]+=1;

      if ((nhood_mixed && just_this_k==0)  
              || just_this_k>9 || (!nhood_mixed && nhood>9)){
	/*if ((nhood_mixed && just_this_k==0) || just_this_k>=10){*/
	     freq_percent_canal[c_color]+=1;  
             thiscolor=color_p[c_color];
      }
      else thiscolor=color_n[c_color];
      
      /*draw pixel or block*/
      if (cellscale>1){	  
	 setfillstyle(SOLID_FILL,thiscolor);
	 /*draw a border around zero valoue*/
	 bar(getx,gety,getx+cellscale-cellsep,
		          gety+cellscale-cellsep);
	 if (nhood_mixed && just_this_k>0 && cellscale>=3 &&
	                                   thiscolor==color_p[0])
	    rectangle(getx,gety,getx+cellscale-cellsep,
		          gety+cellscale-cellsep);
	 
      }
      else if (cellscale==1) putpixel(getx,gety,thiscolor);	 
      
      if (canaltotal>0){
	 cinputnet+=canaltotal;
	 cgenenet+=1;
	 set_bit1(iscanal,poss);/*note gens already canalyzing*/
      }
   }
   
   if (nhood_mixed && just_this_k>0){
       inputtotal=k_count[just_this_k]*just_this_k;
       cgenefreq=(float)cgenenet/k_count[just_this_k];
   }
   else if (!nhood_mixed){
       inputtotal=lineL*nhood;
       cgenefreq=(float)cgenenet/lineL;
   }    
   cinputfreq=(float)cinputnet/inputtotal;
        
   /*display histogram of canalyzing freq*/      
   /*% canalization*/   
   if ((nhood_mixed && just_this_k==0)  
              || just_this_k>9 || (!nhood_mixed && nhood>9)){
      moveto(boxleft+cellscale+CWidth*4,top-CHeight*3);
      cindex=0;
      moveto(getx,gety-CWidth*2);
      for (z=0;z<=5;z++){
         setfillstyle(SOLID_FILL,color_p[z]);
         topy=gety-vgax(100)*
	           ((float)freq_percent_canal[z]/lineL);
	 if (topy<top-vgay(100)) topy=top-vgay(100); 
	 if (z==0){               
	     bar3d(getx,topy,getx+CWidth*2,gety ,0,0);
	     bar3d(getx,gety+2,
			 getx+CWidth*2,gety+vgay(6),0,0);
	 }
	 else if (nhood_ub==1 && z<5) continue;    
         else if (nhood_ub==2 && z!=3 && z!=5) continue;
	 else if (nhood_ub==3 && z==1 && z==4) continue;
	 else if (nhood_ub==4 && z==1) continue;
         else{
	     moveto(getx+CWidth*5+2,gety);
             if (topy<gety) bar(getx,topy,getx+CWidth*2,gety);
             bar(getx,gety+2,getx+CWidth*2,gety+vgay(6));
	 }	               
	 cindex++;
         tempx=getx;
	 tempy=gety;
	 moveto(getx,gety+vgay(8));

         if (cindex==1){ 
             moverel(-CWidth*10,0);
             outtext("saturation %");
             moveto(tempx,gety);
         }  
	   
	 if (z==0) outtext("0");
	 else if (z==1) outtext("<25");
         else if (z==2) outtext("<50");
	 else if (z==3) outtext("<75");
         else if (z==4) outtext("<100");
	 else outtext("100%");
	           
         moveto(tempx,gety+CHeight);
	 /*if (freq_percent_canal[z]==0) outtext("0");
	 else{
	    sprintf(textb[0],"%.2f",
                    (float)freq_percent_canal[z]/lineL);
	    outtext(textb[0]+1);
	 }*/

         if (cindex==1){ 
             moverel(-CWidth*10,0);
             outtext("frequency %");
             moveto(tempx,gety);
         }        
	 sprintf(textb[0],"%.1f",
               100*(float)freq_percent_canal[z]/lineL);
	 outtext(textb[0]);

	 moveto(tempx,tempy);
      }
   }
   /*number canalization*/      
   else{
      if (just_this_k>0){
	 thisnhood=just_this_k;
         thistotal=k_count[just_this_k];
      }
      else{
	  thisnhood=nhood;
          thistotal=lineL;
      }
      /*moveto(boxleft+cellscale+CWidth*4,top-CHeight*3);*/
      moveto(boxleft+cellscale+CWidth*4,top-CHeight*4);
      cindex=0;
      moveto(getx,gety-CWidth*2);
      for (z=0;z<=9;z++){           
	 setfillstyle(SOLID_FILL,color_n[z]);
         topy=gety-vgax(100)*
	              ((float)freq_no_canal[z]/thistotal);
	 if (topy<top-vgay(100)) topy=top-vgay(100); 
	 if (z==0){               
	     bar3d(getx,topy,getx+CWidth*2,gety ,0,0);
	     bar3d(getx,gety+2,
			    getx+CWidth*2,gety+vgay(6),0,0);
	 }
	 else if (thisnhood==1 && z<9) continue;    
         else if (thisnhood==2 && z!=9 && z!=4) continue;
	 else if (thisnhood==3 && z!=9 && z!=4 && z!=3) continue;
	 else if (thisnhood==4 &&
		       z!=9 && z!=8 && z!=4 && z!=3) continue;
         else if (thisnhood==5 &&
		       (z==7 || z==6 || z==5 || z==2)) continue;
         else if (thisnhood==6 && (z==7 || z==5 || z==2)) continue;
	 else if (thisnhood==7 && (z==5 || z==2)) continue;
	 else if (thisnhood==8 && z==2) continue;
	 else{
	     moveto(getx+CWidth*3+2,gety);
             if (topy<gety) bar(getx,topy,getx+CWidth*2,gety);
             bar(getx,gety+2,getx+CWidth*2,gety+vgay(6)); 
	 }	    
	 /*if (topy<top-vgay(100)){
	       if (z>2) setcolor(black);
	       line(getx,topy+CWidth,getx+CWidth,topy);
               line(getx+CWidth,topy,getx+CWidth*2,topy-CWidth);
	       setcolor(white);
	 }*/
	 cindex++;
         tempx=getx;
	 tempy=gety;
	 moveto(getx,gety+vgay(8));

         if (cindex==1){ 
             moverel(-CWidth*10,0);
             sprintf(textb[0],"fraction c/%d",nhood);
             outtext(textb[0]);
             moveto(tempx,gety);
         }  

	 sprintf(textb[0],"%d",cindex-1);
	 outtext(textb[0]);

         moveto(tempx,gety+CHeight);

         if (cindex==1){ 
             moverel(-CWidth*10,0);
             outtext("frequency %");
             moveto(tempx,gety);
         }        
	 sprintf(textb[0],"%.1f",
                   100*(float)freq_no_canal[z]/thistotal);
	 outtext(textb[0]);
	 
	 moveto(tempx,tempy);
      } 
   }
   /*
   draw_prompt_box(1);
   sprintf(textb[0],"jtk=%d, %d/%lu=%f",just_this_k,
              freq_percent_canal[z],inputtotal,
	         (float)freq_percent_canal[z]/inputtotal);
   outtext(textb[0]);
   input_string(0,1);*/
   
   free(freq_percent_canal);
   free(freq_no_canal);
   
   if (nhood_mixed && just_this_k>0){
      sprintf(textb[0],
       "k=%d (%.1f%%) c-inputs=%lu/%lu=%.1f%%  genes=%d/%d=%.1f%%",
              just_this_k,
	         (float)(k_count[just_this_k]*100)/lineL,
	           cinputnet,
	             inputtotal,
	               cinputfreq*100,
	                 cgenenet,
	                   k_count[just_this_k],
	                     (float)(cgenenet*100)/k_count[just_this_k]);
	      /*cgenefreq*100);*/       

      /*keep info in text buffer*/
      /*for (z=1;z<=Maxnhood;z++){
	  if (k_count[z]>0){
	     sprintf(textb[1],"%d=%.1f%% C=%.1f%%",
		            z,(float)(k_count[z]*100)/lineL);
             outtext(textb[0]);
          }
      }
      moveto(xbox,gety+CHeight); */  

   }
   else sprintf(textb[0],
     "c-inputs=%lu/%lu=%.1f%%  genes=%d/%d=%.1f%%", 
       cinputnet,inputtotal,cinputfreq*100,cgenenet,lineL,
                                      ((float)cgenenet/lineL)*100);

   if (ctype=='i'){
      if (settype=='p') sprintf(textb[1],
	  "set new %% c-inputs, redo-q accept-ret:");
      else sprintf(textb[1],
	  "set new number c-inputs, redo-q accept-ret:");
   }
   else{
      if (settype=='p') sprintf(textb[1],
	  "set new %% c-genes, redo-q accept-ret:");
      else sprintf(textb[1],
	  "set new number c-genes, redo-q accept-ret:");
   }
   if (lineL<=64){
      xbox=draw_prompt_box(3);
      ybox=gety;
      moveto(xbox,ybox+3);
      foldposs=64;
      print_layered_bitstring(iscanal,lineL-1,scale,sep,0,1);
      moveto(xbox,ybox+CHeight);
   }
   else xbox=draw_prompt_box(2);
   outtext(textb[0]);
   moveto(xbox,gety+CHeight);
   outtext(textb[1]);
   if (settype=='p') input_string(5,0);
   else{
      /*input_string(strlen(itoa(lineL,textb[0],10)),0);*/
      if (ctype=='i' && settype!='p')
		 sprintf(textb[0],"%lu",lineL*inputtotal);
      else sprintf(textb[0],"%d",lineL);
      input_string(strlen(textb[0]),0);
   }
   if (is[0]=='q' || (is[0]==13 && nhood_mixed && just_this_k>0)){
      if (lineL<=64) erase_prompt_box(3);
      else erase_prompt_box(2);
      goto start;
   }
   if (is[0]==13){
      if (lineL<=64) erase_prompt_box(3);
      else erase_prompt_box(2);
      free(shuff_wire);
      if (nhood_mixed || nhood>9){
	 free(k_count);
         for (z=1;z<=Maxnhood;z++) free(k_buf[z]);
	 free(k_buf);
      } 
      sprintf(textb[9],"%s","boximage[18]"); 
      putimage(boxleft-vgax(40),top-vgay(100),boximage[18],COPY_PUT,textb[9]);
      freeimage(boximage[18]);

      free(color_p);
      free(color_n);
      return;
   }
   if (nhood_mixed && just_this_k==1){	
      draw_prompt_box(1);
      outtext(
	 "k=1 is fully canalyzing and can't be altered, cont-ret");
      input_string(1,0);
      goto resetcanal;
   }  
   if (ctype=='g'){
      canalcount=reducecanal=0;
      if (nhood_mixed && just_this_k>0) netsize=k_count[just_this_k];
      else netsize=lineL;
      if (settype=='p'){
         if (atof(is)<=100 && atof(is)>=0){
	    newcgenefreq=atof(is)/100;
	    newcgenenet=newcgenefreq*netsize;
	    /*if more*/
	    if (cgenefreq<newcgenefreq){
	       reducecanal=0;              
	       canalcount=(unsigned int)
			       ((newcgenefreq-cgenefreq)*netsize);
	    }
	    /*if less*/
	    else{
	       reducecanal=1;
	       canalcount=(unsigned int)((cgenefreq-newcgenefreq)*netsize);
	    }
	 }
      }
      else{
	 if (atoi(is)<=netsize && atoi(is)>=0){
	    newcgenenet=atoi(is);
	    newcgenefreq=(float)newcgenenet/netsize;
	    /*if more*/
	    if (cgenenet<newcgenenet){
	       reducecanal=0;
	       canalcount=newcgenenet-cgenenet;
	    }
	    /*if less*/
	    else{
	       reducecanal=1;
	       canalcount=cgenenet-newcgenenet;
	    }
	 }
      }
      if (canalcount==0) goto resetcanal;

      count_tries=0;
      for (zu=canalcount;zu>=1;zu--){
	 count_tries+=1;
	 if (count_tries>netsize) break;

         if (nhood_mixed && just_this_k>0)	    
            poss=k_buf[just_this_k][myrand()% k_count[just_this_k]];	    
	 else poss=myrand()%lineL;
	 
	 search_direction=myrand()%2;

	 if (search_direction){  /*start search towards left <-*/
	    nleft=0;
	    for (zu1=poss;zu1<=lineL-1;zu1++){
	       if (nhood_mixed && just_this_k>0){
		   if (nhoodm[zu1]!=just_this_k) continue;
	       }
	       thisbit=get_bit(iscanal,zu1);
	       if ((!reducecanal && !thisbit) /*increase canal*/
		      || (reducecanal && thisbit) ){ /*reduce canal*/
		  poss=zu1;
		  nleft=1;  /*found*/
		  break;
	       }
	    }
	    if (!nleft){ /*if not found search towards right ->*/
	       nright=0;
	       for (zu1=poss-1;zu1!=Maxu;zu1--){
		  if (nhood_mixed && just_this_k>0){
		     if (nhoodm[zu1]!=just_this_k) continue;
	          }  
		  thisbit=get_bit(iscanal,zu1);
		  if ((!reducecanal && !thisbit) /*increase canal*/
			 || (reducecanal && thisbit) ){ /*reduce canal*/
		     poss=zu1;
		     nright=1;  /*found*/
		     break;
		  }
	       }
	    }
	 }
	 else {  /*start search towards right ->*/
	    nright=0;
	    for (zu1=poss;zu1!=Maxu;zu1--){
	       if (nhood_mixed && just_this_k>0){
		  if (nhoodm[zu1]!=just_this_k) continue;
	       } 
	       thisbit=get_bit(iscanal,zu1);
	       if ((!reducecanal && !thisbit) /*increase canal*/
		      || (reducecanal && thisbit) ){ /*reduce canal*/
		  poss=zu1;
		  nright=1;  /*found*/
		  break;
	       }
	    }
	    if (!nright){ /*if not found search towards left ->*/
	       nleft=0;
	       for (zu1=poss+1;zu1<=lineL-1;zu1++){
		  if (nhood_mixed && just_this_k>0){
		     if (nhoodm[zu1]!=just_this_k) continue;
	          } 
		  thisbit=get_bit(iscanal,zu1);
		  if ((!reducecanal && !thisbit) /*increase canal*/
			 || (reducecanal && thisbit) ){ /*reduce canal*/
		     poss=zu1;
		     nleft=1;  /*found*/
		     break;
		  }
	       }
	    }
	 }
	 if (!nleft && !nright) break; /*if not found*/

	 if (nhoodm[poss]==1 && reducecanal){
	    zu++;
	    continue;/*cant be altered*/
	 }
	 /*max index of ruletable*/
	 if (nhood_mixed)
		 tablemax=(signed int)pow(value_range,(double)nhoodm[poss])-1;
	 /*reduce canalyzing*/
	 if (reducecanal){
	    /*reset canalyzing gene at random to non canalyzing*/
	    while (1){
	       for (zz=tablemax;zz>=0;zz--){
		  set_value(carule[poss],zz,myrand()%value_range);
               }
               if (forcezero==1) set_value(carule[poss],0,0);
	       /*test if still canalyzing*/
	       canalyzing(nhoodm[poss],0,carule[poss]);
	       if (canaltotal==0) break;
	    }
	    set_bit0(iscanal,poss);
	 }
	 /*increase canalyzing*/
	 else{
	    /*reset non-canalyzing gene at to canalyzing*/
	    wire=myrand()%nhoodm[poss];/*random wire*/
	    binv=myrand()%2;           /*input variable 0 or 1*/
	    outvalue=canalyzing(nhoodm[poss],0,carule[poss]);
	    if (canaltotal==0) boutv=myrand()%value_range; /*output variable 0 or 1*/
	    else boutv=outvalue;/*same value as existing canalyzing output*/
	    /*make input "wire" canalyzing*/
	    for (zz=0;zz<=tablemax;zz++){
	       if (get_value(nm[wire],zz)==binv) set_value(carule[poss],zz,boutv);
	    }
	    set_bit1(iscanal,poss);
	 }
      }
   }
   /*alter % or number of canalyzing inputs*/
   if (ctype=='i'){
      canalcount=reducecanal=0;
      if (settype=='p'){
          if (atof(is)<=100 && atof(is)>=0){
	    newcinputfreq=atof(is)/100;
	    newcinputnet=newcinputfreq*inputtotal;
	    /*if more*/
	    if (cinputfreq<newcinputfreq){
	       reducecanal=0;
	       canalcount=(unsigned int)
		      ((newcinputfreq-cinputfreq)*inputtotal);
	    }
	    /*if less*/
	    else{
	       reducecanal=1;
	       canalcount=(unsigned int)
		      ((cinputfreq-newcinputfreq)*inputtotal);
	    }
	 }
      }
      else{
	 if (atol(is)<=inputtotal && atol(is)>=0){
	    newcinputnet=atol(is);
	    newcinputfreq=(float)newcinputnet/inputtotal;
	    /*if more*/
	    if (cinputnet<newcinputnet){
	       reducecanal=0;
	       canalcount=newcinputnet-cinputnet;
	    }
	    /*if less*/
	    else{
	       reducecanal=1;
	       canalcount=cinputnet-newcinputnet;
	    }
	 }
      }
      if (canalcount==0) goto resetcanal;

      count_tries=0;      
      show_tries=25+lineL/300;
      moveto(memory_box(0,NULL)+2,2);
      outtext("  cf=");
      tempx1=getx;
      setfillstyle(SOLID_FILL,black);
       
      /*show % canalyzing inputs so far*/       
      bar(tempx1,3,tempx1+vgax(50),3+CHeight);
      moveto(tempx1,gety);
      sprintf(textb[0],"%.1f%%",cinputfreq*100);
      outtext(textb[0]);
	    
      for (zulong=canalcount;zulong>=1;zulong--){
	 nleft=nright=0;
	 count_tries+=1;
	 if (reducecanal){
	    if (cinputfreq<=newcinputfreq) break;
	 }
	 else{
	    if (cinputfreq>=newcinputfreq) break;
	 }

	 /*show % canalyzing inputs so far*/
	 if (count_tries%show_tries==0){
	    bar(tempx1,3,tempx1+vgax(50),3+CHeight);
	    moveto(tempx1,gety);
	    sprintf(textb[0],"%.1f%%",cinputfreq*100);
	    outtext(textb[0]);
            /*wont work without this - dont understand why necessary*/
            while(event_ready()==0){
               break;
            }	     
	 }

	 /*if (count_tries>inputtotal*10) break;*//*limit search cycles*/
	 /*problem setting random position in large net size*/
	 if (nhood_mixed && just_this_k>0)	    
            poss=k_buf[just_this_k][myrand()% k_count[just_this_k]];	    
	 else poss=myrand()%lineL;
	 
	 /*shuffle_order(shuff_wire,nhoodm[0]);*/
	 shuffle_order(shuff_wire,nhoodm[poss]);
	 /*
	 draw_prompt_box(1);
	 for (cz=nhoodm[0]-1;cz>=0;cz--){
	    sprintf(textb[0],"%d=%d ",cz,shuff_wire[cz]);
	    outtext(textb[0]);
	 }
	 input_string(1,0);
	 */
	 search_direction=myrand()%2;
	 /*to reduce, search for canalyzing genes*/
	 /*to inceace, search for non-canalyzing genes for preferance*/

	 if (search_direction){  /*start search towards left <-*/
	    nleft=0;
	    for (zu1=poss;zu1<=lineL-1;zu1++){
                if (nhood_mixed && just_this_k>0){
		   if (nhoodm[zu1]!=just_this_k) continue;		   
	        } 
		outvalue=canalyzing(nhoodm[zu1],0,carule[zu1]);
		if (rulemix) shuffle_order(shuff_wire,nhoodm[zu1]);
		/*draw_prompt_box(1);*/
		for (cz=nhoodm[zu1]-1;cz>=0;cz--){
		    wire=shuff_wire[cz];

		    /*sprintf(textb[0],"%d=%d ",cz,wire);
		    outtext(textb[0]);
		    input_string(1,0);*/
                    /*increase or reduce canalyzing*/
		    if ((get_bit(canal,wire)==0 && !reducecanal) 
			  || (get_bit(canal,wire)==1 && reducecanal)){
		       poss=zu1;

		       nleft=1;  /*found*/
		       break;
		    }
		}
		if (nleft==1) break;
	    }
	    if (nleft==0){ /*if not found search towards right ->*/
	       nright=0;
	       for (zu1=poss-1;zu1!=Maxu;zu1--){
		  if (nhood_mixed && just_this_k>0){
		     if (nhoodm[zu1]!=just_this_k) continue;
	          } 
		  outvalue=canalyzing(nhoodm[zu1],0,carule[zu1]);
		  if (rulemix) shuffle_order(shuff_wire,nhoodm[zu1]);
		  /*draw_prompt_box(1);*/
		  for (cz=nhoodm[zu1]-1;cz>=0;cz--){
		     wire=shuff_wire[cz];

		     /*sprintf(textb[0],"%d=%d ",cz,wire);
		     outtext(textb[0]);
		     input_string(1,0);*/
                     /*increase or reduce canalyzing*/
		     if ((get_bit(canal,wire)==0 && !reducecanal)
			  || (get_bit(canal,wire)==1 && reducecanal)){

			poss=zu1;
			nright=1;  /*found*/
			break;
		     }
		  }
		  if (nright==1) break;
	       }
	    }
	 }
	 else {  /*start search towards right ->*/
	    nright=0;
	    for (zu1=poss;zu1!=Maxu;zu1--){
	       if (nhood_mixed && just_this_k>0){
		   if (nhoodm[zu1]!=just_this_k) continue;		   
	       } 
	       outvalue=canalyzing(nhoodm[zu1],0,carule[zu1]);
	       if (rulemix) shuffle_order(shuff_wire,nhoodm[zu1]);
	       /*draw_prompt_box(1);*/
	       for (cz=nhoodm[zu1]-1;cz>=0;cz--){
		   wire=shuff_wire[cz];

		   /*sprintf(textb[0],"%d=%d ",cz,wire);
		   outtext(textb[0]);
		   input_string(1,0);*/

		   if ((get_bit(canal,wire)==0 && !reducecanal)
			  || (get_bit(canal,wire)==1 && reducecanal)){

		     poss=zu1;
		     nright=1;  /*found*/
		     break;
		  }
	       }
	       if (nright==1) break;
	    }
	    if (!nright){ /*if not found search towards left ->*/
	       nleft=0;
	       for (zu1=poss+1;zu1<=lineL-1;zu1++){
		   if (nhood_mixed && just_this_k>0){
		      if (nhoodm[zu1]!=just_this_k) continue;
      	           } 
		   outvalue=canalyzing(nhoodm[zu1],0,carule[zu1]);
		   if (rulemix) shuffle_order(shuff_wire,nhoodm[zu1]);
		   /*draw_prompt_box(1);*/
		   for (cz=nhoodm[zu1]-1;cz>=0;cz--){
		       wire=shuff_wire[cz];

		       /*sprintf(textb[0],"%d=%d ",cz,wire);
		       outtext(textb[0]);
		       input_string(1,0);*/

		       if ((get_bit(canal,wire)==0 && !reducecanal)
			  || (get_bit(canal,wire)==1 && reducecanal)){

			poss=zu1;
			nleft=1;  /*found*/
			break;
		     }
		  }
		  if (nleft==1) break;
	       }
	    }
	 }

	 /*draw_prompt_box(1);
	 sprintf(textb[0],"cz=%d wire=%d poss=%d nleft=%d nright=%d",
				     cz,wire,poss,nleft,nright);
	 outtext(textb[0]);
	 input_string(1,0);*/

	  /*if (reducecanal){*/
	 if (!nleft && !nright) break; /*if not found*/
	 /*}*/
	 if (nhoodm[poss]==1 && reducecanal){
	    zulong--;
	    count_tries--;
	    continue;/*cant be altered*/
	 }
	 /*max index of ruletable*/
	 if (nhood_mixed) tablemax=
               (signed int)pow(value_range,(double)nhoodm[poss])-1;
	 /*reduce canalyzing*/
	 startcanaltotal=canaltotal;
	 if (reducecanal && canaltotal>0){
	    /*reset canalyzing input at random to non-canalyzing*/
	    /*flip 1 or 2  bit at random, likely to reduce canalyzing*/
	    for (z=0;z<=1;z++){
	       temp=myrand() % tablemax+1;
	       if (value_range==2){
                  set_bit(carule[poss],temp,
		    abs(get_bit(carule[poss],myrand()%temp)-1));
               }
               else set_value(carule[poss],temp,myrand()%value_range);
	       temp=myrand()%2;
	       if (temp==0) break;
	    }
	    /*this doesnt seem to work*/
	    /*while(1){
	       temp=myrand() % tablemax+1;
	       set_bit(carule[poss],temp,
		    abs(get_bit(carule[poss],myrand()%temp)-1));
	       canalyzing(nhoodm[poss],0,carule[poss]);
	       if (canaltotal<startcanaltotal) break;
	       else  set_bit(carule[poss],temp,
		       abs(get_bit(carule[poss],myrand()%temp)-1));
	    }*/
	    canalyzing(nhoodm[poss],0,carule[poss]);
	    if (canaltotal==0) set_bit0(iscanal,poss);
	 }
	 /*increase canalyzing*/
	 else if (!reducecanal){
	    /*make input "wire" canalyzing*/
	    binv=myrand()%value_range;   /*input variable 0 or 1*/
	    if (canaltotal==0) boutv=myrand()%value_range; /*output variable 0 or 1*/
	    else boutv=outvalue;/*same vale as existing canalyzing output*/
	    for (zz=0;zz<=tablemax;zz++){
	       if (get_value(nm[wire],zz)==binv)
			    set_value(carule[poss],zz,boutv);
	    }
	    canalyzing(nhoodm[poss],0,carule[poss]);
	    if (canaltotal>startcanaltotal) set_bit1(iscanal,poss);
	 }
	 cinputnet+=canaltotal-startcanaltotal;
	 cinputfreq=(float)cinputnet/inputtotal;

      }
   }
   goto resetcanal;
}

/**** show/select percentage/number of canalyzing genes/inputs, Feb 95 ****/
void set_canalyzing_rule(unsigned int poss){ 
  signed int  tries,
		tablemax,
		z,zz,countn;
  char newcanaltotal,
       *notewires,
       reducecanal,
       binv,
       boutv,
       ctype;
   signed int wire;
   if (tot_only) return;/*canalizing needs full lookup-table*/

   tablemax=(signed int)pow(value_range,(double)nhoodm[poss])-1;
   /*to note position of (non)canalyzing inputs in nmhood*/
   sprintf(textb[0],"notewires");
   if ((notewires=(char *)calloc(nhoodm[poss],sizeof(char)))==NULL)
						outof_memory(textb[0]);
   if ((direction=='f' && limitcheck==0) && secondpart)
      draw_box(12,trboxw,Maxy-CHeight-vgay(6),Maxx-2,Maxy,1,0);
  start:
   if (value_range==2) z_parameter_all(nhoodm[poss],0,carule[poss]);
   else z_parameter_all_mvalue(nhoodm[poss],0,carule[poss]);
   if (!(direction=='f' && limitcheck==0) || secondpart==0){
      show_rule_bottom(nhoodm[poss],1,carule[poss],0);
      draw_prompt_box(1);
   }
   else draw_box(-1,trboxw,Maxy-CHeight-vgay(6),Maxx-2,Maxy,1,0);
   if (rulemix) outtext(
    "canalyzing inputs: explicitly-e random-n, or whole net-N:");
   else outtext(
    "canalyzing inputs: explicitly-e random-n:");
   input_string(1,0);

   if (is[0]=='e') ctype='e';
   else if (is[0]=='n' || is[0]=='N') ctype=is[0];
   else{
      free(notewires);
      if ((direction=='f' && limitcheck==0) && secondpart){
         sprintf(textb[9],"%s","boximage[12]"); 
	 putimage(trboxw,Maxy-CHeight-vgay(6),boximage[12],COPY_PUT,textb[9]);
	 freeimage(boximage[12]);
      }
      else erase_prompt_box(1);
      return;
   }
   if (ctype=='e'){
     explicit1:
      if (!(direction=='f' && limitcheck==0) || secondpart==0){
	 draw_prompt_box(1);
      }
      else draw_box(-1,trboxw,Maxy-CHeight-vgay(6),
						    Maxx-2,Maxy,1,0);
      sprintf(textb[0],"wire (0-%d):",nhoodm[poss]-1);
      outtext(textb[0]);
      input_string(1,0);
      if (is[0]==13){
	 wire=myrand()%nhoodm[poss];
	 sprintf(textb[0],"%d",wire);
	 outtext(textb[0]);
      }
      else if (atoi(is)>=0 && atoi(is)<=nhoodm[poss]-1) wire=atoi(is);
      else goto start;

      sprintf(textb[0]," input value (%d - 0):",value_range-1);
      outtext(textb[0]);
      input_string(1,0);
      if (is[0]==13){
	 binv=myrand()%value_range;
	 sprintf(textb[0],"%d",binv);
	 outtext(textb[0]);
      }
      else if (atoi(is)>=0 && atoi(is)<=value_range-1) binv=atoi(is);
      else goto explicit1;
      sprintf(textb[0]," output value (%d - 0):",value_range-1);
      outtext(textb[0]);
      input_string(1,0);
      if (is[0]==13){
	 boutv=myrand()%value_range;
	 sprintf(textb[0],"%d",boutv);
	 outtext(textb[0]);
      }
      else if (atoi(is)>=0 && atoi(is)<=value_range-1)  boutv=atoi(is);
      else goto explicit1;
      for (zz=0;zz<=tablemax;zz++){
	 if (get_value(nm[wire],zz)==binv) set_value(carule[poss],zz,boutv);
      }
      canalyzing(nhoodm[poss],0,carule[poss]);
      goto start;
   }
   if (ctype=='n' || ctype=='N'){
      reducecanal=0;

      if (ctype=='N' && rulemix){
        signed int zu;
         draw_prompt_box(1);
         sprintf(textb[0],
	   "canalyzing inputs, whole net - set new number (0-%d):",
				               nhoodm[poss]);
         outtext(textb[0]);
         input_string(2,0);
         if (atoi(is)>=0 && atoi(is)<=nhoodm[poss]) newcanaltotal=atoi(is);
         else goto start;         
         /*make non-canalyzing "wire" canalyzing*/
         fprintf(stderr,"\n");
         for (zu=0; zu<=lineL-1;zu++){
            /*check and record (non)canalyzing inputs*/
            canalyzing(nhoodm[zu],0,carule[zu]); /* sets canaltotal */
            countn=0;
            for (z=0;z<=nhoodm[poss]-1;z++){
	       if (get_bit(canal,z)==reducecanal){
	          notewires[countn]=z;
	          countn++;
	       }
            }
            tries=0;
	    while(1){
               wire=notewires[myrand()%countn];
	       if (tries>100) break;
	       tries+=1;
	       binv=myrand()%value_range;
               /*binv=0;*/
	       if (canaltotal==0) boutv=myrand()%value_range;
               /*boutv=1;*/
	       if (tries>20){ /*if bitflips arent working, scramble*/
	          for (zz=0;zz<=tablemax;zz++)
		     set_value(carule[zu],zz,myrand()%value_range);
	       }
	       for (zz=0;zz<=tablemax;zz++){
	          if (get_value(nm[wire],zz)==binv)
				set_value(carule[zu],zz,boutv);
	       }
	       canalyzing(nhoodm[zu],0,carule[zu]); /* sets canaltotal */
	       if (canaltotal==newcanaltotal) break;
	    }     
	 }
         goto start;
      }
     
      else if (rulemix==0)
           sprintf(textb[0],
	   "canalyzing inputs=%d, set new number (0-%d):",
				       canaltotal,nhoodm[poss]);
         else 
           sprintf(textb[0],
	   "cell %d canalyzing inputs=%d, set new number (0-%d):",
				       poss, canaltotal,nhoodm[poss]);
      if (!(direction=='f' && limitcheck==0) || secondpart==0){
	 draw_prompt_box(1);
      }
      else draw_box(-1,trboxw,Maxy-CHeight-vgay(6),
						    Maxx-2,Maxy,1,0);

      outtext(textb[0]);
      input_string(2,0);
      if (is[0]=='q' || is[0]==13) goto start;
      if (atoi(is)>=0 && atoi(is)<=nhoodm[poss]) newcanaltotal=atoi(is);
      if (newcanaltotal==canaltotal) goto start;
      if (newcanaltotal<canaltotal) reducecanal=1;

      /*check and record (non)canalyzing inputs*/
      canalyzing(nhoodm[poss],0,carule[poss]);
      countn=0;
      for (z=0;z<=nhoodm[poss]-1;z++){
	 if (get_bit(canal,z)==reducecanal){
	    notewires[countn]=z;
	    countn++;
	 }
      }
      /*wire=notewires[myrand()%countn];*/ /*select a (non)canalyzing input*/
      tries=0;
      /*make non-canalyzing "wire" canalyzing*/
      if (!reducecanal){
	 while(1){
            wire=notewires[myrand()%countn];
	    if (tries>100) break;
	    tries+=1;
	    binv=myrand()%value_range;   /*input value*/
	    if (canaltotal==0)       /*output value*/
                        boutv=myrand()%value_range;         
	    if (tries>20){ /*if bitflips arent working, scramble*/
	       for (zz=0;zz<=tablemax;zz++)
		     set_value(carule[poss],zz,myrand()%value_range);
	    }
	    for (zz=0;zz<=tablemax;zz++){
	       if (get_value(nm[wire],zz)==binv)
				set_value(carule[poss],zz,boutv);

	    }
	    canalyzing(nhoodm[poss],0,carule[poss]);
	    if (canaltotal==newcanaltotal) break;
	 }
      }
      /*make canalyzing "wire" non-canalyzing*/
      else{
	 while(1){
	    if (tries>100) break;
	    tries+=1;
	    binv=myrand()%value_range; /*input value*/
	    boutv=myrand()%value_range;/*output value*/
	    if (tries>20){ /*if valueflips arent working, scramble*/
	       for (zz=0;zz<=tablemax;zz++)
			     set_value(carule[poss],zz,myrand()%value_range);
	    }
	    else{
	       zz=myrand()%tablemax+1;
               if (value_range==2){
	          /*flip a bit in canalyzing output*/
	          if (get_bit(nm[wire],zz)==binv)
			    set_bit(carule[poss],zz,abs(boutv-1));
               }
               else{
                  if (get_value(nm[wire],zz)==binv)
			set_value(carule[poss],zz,myrand()%value_range);
               }
	    }
	    canalyzing(nhoodm[poss],0,carule[poss]);
	    if (canaltotal==newcanaltotal) break;
	 }
      }
      goto start;
   }
}

/********************* reselect rule prompts, Dec 1993 **********************/
char reselect_rule_prompts(signed int cellindex,char select,unsigned long this_rule_dec_max){
 signed int xbox,tempx,tempy;
 char rselect,valid_select,tnhood;
 
   tempx=getx;
   tempy=gety;
   if (this_rule_dec_max>0) sprintf(textb[3],"/d");
   else sprintf(textb[3],"");
   if (tnhood>=5) sprintf(textb[4],"/L"); 
   else sprintf(textb[4],"");/*too small for Life*/
   

   sprintf(textb[0],
	 "index=%d (v%dk%d), change selection method (now %c), abort-q",
		  cellindex,nhoodm[cellindex],value_range,select);
   if (totalistic==0)  sprintf(textb[1],
     "as main sequence choices - e/f/r/b/h%s/m/u/A%s/c/i/R/p/l/v/x:",textb[3],textb[4]);

   else if (totalistic==1) sprintf(textb[1],
     "as main sequence choices - e/f/r/b/h%s/m/p/l/v/x:",textb[3]);
   else if (totalistic==2) sprintf(textb[1],
     "as main sequence choices - e/f/r/b/h%s/m/u/A/p/l/v/x:",textb[3]);
   
   xbox=draw_prompt_box(2);
   outtext(textb[0]);
   moveto(xbox,gety+CHeight);
   outtext(textb[1]);

   input_string(1,0);
   rselect=is[0];
   if (accept_rule_method(rselect,this_rule_dec_max,tnhood)==1) valid_select=rselect;
   else valid_select=select; /*don't change*/
   erase_prompt_box(2);
   moveto(tempx,tempy);

   return(rselect);
}

/********* acceptable key inputs for rule selection method ***************/
char accept_rule_method(char select,unsigned long this_dec_max,char tnhood){
  char accept=0;

   if (select=='d' && this_dec_max==0) goto skip_accept;
   else if (select=='R' && tot_only==1) goto skip_accept;
   else if (select=='R' && tot_only==0 && totalistic>0 && rulemix==1) goto skip_accept;
   else if ((select=='A' || select=='u') && totalistic==1) goto skip_accept;
   else if (select=='L' && tnhood<5) goto skip_accept;

   if (totalistic==0){      
      if (select=='e' || select=='f' || select=='m' ||select=='u' ||  select=='x' || 
               select=='A' || select=='L' || select=='c' || select=='r' || 
               select=='i' || select=='R' || select=='b' || 
               select=='h' || select=='d' || select=='p' || select=='l' || select=='v')
                                                          accept=1;/*accept*/     
   }
   else if (totalistic==1 || totalistic==2){ /*tcode or kcode*/
      if (select=='R' || select=='e' || select=='f' || select=='x' ||
               select=='m' || select=='u' || 
               select=='A' || select=='r' || select=='b' || select=='h' ||
	       select=='d' || select=='p' || select=='l' || select=='v' 
	       || (select=='k' && tot_only==1 && totalistic==2) )
                                                           accept=1;/*accept*/
   }
  skip_accept:
   return(accept);
}

/***************** change the current index in rulemix ***************/
signed int reselect_rule_index(signed int cellindex,
				  signed int number_rules){
 signed int tempx,tempy,newindex;

   tempx=getx;
   tempy=gety;
   if (nhood_mixed==0)  /*for mixed-k only change index back - not forward*/
        sprintf(textb[0],"this index=%d, enter new index 0-%d:",
                  cellindex,number_rules-1);
  
   else sprintf(textb[0],"this index=%d, enter new index 0-%d:",
                                   cellindex,cellindex);
   draw_prompt_box(1);
   outtext(textb[0]);
   input_string(4,0);
   newindex=atoi(is);
   erase_prompt_box(1);
   moveto(tempx,tempy);
   if (nhood_mixed==0){
     if (newindex>=0 && newindex<=number_rules-1) return(newindex);
   }
   else if (newindex>=0 && newindex<=cellindex) return(newindex);
   return(cellindex);
}

/********************* specify rule, 13 May 1993 **********************/
signed int select_rule(char inbox,char one_cell,char** thisrule,
               signed int number_rules,unsigned int poss,char forcezero){
  char select,all_remaining=0,ruleloaded=0,tnhood,select_def;
  unsigned long ruledec,rule_dec_max;
  signed int tablemax,tablebytes,zz,z,temp2,
      tempxr,tempyr,tempy3,startx,starty,xbox,tempx,tempy;
  unsigned int cellindex,cindex=0;
  char *k_seen, **k_rule;

  /*number_rules=1 for single rules, 1 or  more for a rule-mix*/
  /*this is for mixed rules of 1+, index and entry changes*/
# define revise {\
     tempxr=getx;\
     tempyr=gety;\
     if (number_rules==1) goto start;\
     else{\
	sprintf(textb[0],\
	"change: index(%d)-i, start again-a, selection-s, cont-ret:",\
						cellindex);\
	draw_prompt_box(1);\
	outtext(textb[0]);\
	input_string(1,0);\
	if (is[0]=='q') goto start;\
	else if (is[0]=='s'){\
	   select=reselect_rule_prompts(cellindex,select,rule_dec_max);\
	   if (select=='q') goto start;\
	   else{\
	      cellindex-=1;\
	      continue;\
	   }\
	}\
	else if (is[0]=='i'){\
	   cellindex=\
	   reselect_rule_index(cellindex,number_rules)-1;\
	   continue;\
	}\
	else if (is[0]=='a') goto start;\
	moveto(tempxr,tempyr);\
     }\
  }

  /*first set bits/values - then (in main sequence only) show bits/values+hex*/
# define reconfirm_rule {\
        tempx=getx;\
        tempy=gety;\
        if (number_rules==1){\
	   define_bits(nhoodm[cindex],1,thisrule[cindex],tablemax,0);\
           if (is[0]=='q'){\
              select_def='b';\
              goto start;\
           }\
        }\
  }

  setcolor(white);
  startx=getx;
  starty=gety;

  if (poss!=Maxu) tnhood=nhoodm[poss];
  else tnhood=nhood;

  set_cellscale(tnhood,1);
  
  if (inbox==0) select_def='r';
  else if (inbox==1) select_def='b';

 start:
  setcolor(white);
  if (inbox==0){
     setfillstyle(SOLID_FILL,black);
     bar(xtext,starty+CHeight/2,Maxx,Maxy);
  }
  else if (inbox==1){
     sprintf(textb[9],"%s","boximage[9]");
     putimage(trboxw,vgay(343),boximage[5],COPY_PUT,textb[9]);
     draw_box(-1,trboxw,vgay(343),Maxx-2,Maxy,1,0);
     startx=trboxw+3;
  }
  moveto(startx,starty);
  tablemax= (signed int)pow(value_range,(double)tnhood)-1;
  tablebytes=(signed int)ceil(value_bits * (double)(tablemax+1)/8); 
  rule_dec_max=max_dec_rule(tablemax,value_range);
  if (rule_dec_max>0) sprintf(textb[3]," dec-d ");
  else sprintf(textb[3]," ");
  if (tnhood>=5) sprintf(textb[4]," life-L "); /*too small for Life*/
  else sprintf(textb[4]," ");
  if (oned || (twod && nhood>=2 && nhood<=10) ||
		 (threed && (nhood==6 || nhood==7)))
      sprintf(textb[0],
        "Select v%dk%d rcode (S=%d): empty-e fill-f prtx-x ascii-v rnd-r rnd-iso-i",
                     value_range,tnhood,tablemax+1);
  else sprintf(textb[0],
    "Select v%dk%d rcode (S=%d): empty-e fill-f prtx-x ascii-v rnd-r",
                     value_range,tnhood,tablemax+1);
  
  sprintf(textb[1],
  "bits-b hex-h%smaj-m/u Alt-A%schain-c RD-R rep-p load-l (def-%c): ",
                  textb[3],textb[4],select_def);

  if (inbox==0) next_line(xtext,1);
  else moveto(startx,gety+CHeight);
  outtext(textb[0]);
  if (inbox==0) next_line(xtext,1);
  else moveto(startx,gety+CHeight);
  outtext(textb[1]);
  input_string(1,0);
  select=is[0];
  if (is[0]=='q') return(0);
  
  else if (accept_rule_method(select,rule_dec_max,tnhood)==1);/*accept*/
  else  select=select_def;/*don't accept*/
  
  tempy3=gety;
  
  //to clear space for isotropic ruletable jan2020  
  if (inbox==0) iso_x=xtext* CWidth;
  else iso_x=Maxx/2 +vgax(1);
  iso_y=gety+CHeight +vgay(1);
 
  /*to record if particular k occured and record latest rule*/
  if (nhood_mixed && poss==Maxu){
     signed int k_bytes;

     if ((k_seen=(char *)calloc(nhood+1,sizeof(char)))
				  ==NULL) outof_memory("(k_seen");
     if ((k_rule=(char**)calloc(nhood+1,sizeof(char*)))
				  ==NULL) outof_memory("k_rule");
     for (z=1;z<=nhood;z++){
        k_bytes=value_bits * (signed int)ceil(pow(value_range,(double)z)/8);
        sprintf(textb[0],"k_bytes[%d]",z);
        if ((k_rule[z]=(char*)calloc(k_bytes,sizeof(char*)))
				       ==NULL) outof_memory(textb[0]);
     }
  }
  all_remaining=0;


  for (cellindex=0;cellindex<=number_rules-1;cellindex++){    
    if (one_cell==1){ /*to revise rule at one cell*/
       if (poss==Maxu) cindex=0;
       else cindex=poss;
    }
    else if (rulemix && poss==Maxu){ /*includes:  && nhood_mixed*/
       cindex=cellindex;        /*one_cell='2' for rule subset*/
       if (nhood_mixed) tnhood=nhoodm[cindex];
    }

    if (nhood_mixed){
       tablemax= (signed int)pow(value_range,(double)nhoodm[cindex])-1;
       tablebytes=(signed int)ceil(value_bits * (double)(tablemax+1)/8);
       rule_dec_max=max_dec_rule(tablemax,value_range);
    }
    if (inbox==0 && rulemix){
      char k_was_seen=0;
       
       xbox=draw_prompt_box(2);
       if (nhood_mixed==0) sprintf(textb[0],"index=%d (v%dk%d rcodemix) ",
                                           cellindex,value_range,nhoodm[cindex]);
       else sprintf(textb[0],"index=%d k(%d-%d) (v%dk%d rcodemix) ",
               cellindex,nhood_lb,nhood_ub,value_range,nhoodm[cindex]);
       outtext(textb[0]);

       if (nhood_mixed && poss==Maxu && cindex>0){   
	 if (k_seen[(signed int)nhoodm[cindex]]==1){
	     k_was_seen=1;
             sprintf(textb[0],", same as last-s, all remaining-a:");
             outtext(textb[0]);
             input_string(1,0);
             if (is[0]=='s' || is[0]=='a' ){
                 memmove(thisrule[cindex],
                      k_rule[(signed int)nhoodm[cindex]],tablebytes);
                 if (is[0]=='a') k_seen[(signed int)nhoodm[cindex]]='a';
                 moveto(xtext,tempy3);
                 continue;
             }
         }
         else if (k_seen[(signed int)nhoodm[cindex]]=='a'){
            memmove(thisrule[cindex],
                k_rule[(signed int)nhoodm[cindex]],tablebytes);
            moveto(xtext,tempy3);
            continue;
	 }
       }

       if (all_remaining==0){
	  char latest_select;
	    latest_select=select;
            moveto(xbox,gety+CHeight);
            sprintf(textb[0],
	      "hand=%c, change-(any valid entry) or index-q",select);
            outtext(textb[0]);
            if (nhood_mixed==0 &&
               (select=='r' || select=='m' || select=='u' || select=='c' 
                     || select=='A' || select=='i')) outtext(", rnd all-a");
            outtext(":");          
            input_string(1,0);           
            if (is[0]=='q'){
                 {revise}
                 is[0]=' ';
            }
            else{          
               /*set all remaining at random  automatically - only for this method*/
               if (nhood_mixed==0 && is[0]=='a' && 
		 (select=='r' || select=='m' || select=='u' || select=='c'
                        || select=='A' || select=='i')) all_remaining=1;

               /*or change selection by entering any of the following*/
               else{
		   select=is[0];
                   if (accept_rule_method(select,rule_dec_max,tnhood)==1);/*accept*/
                   else select=latest_select;
               }
            }
       }
       moveto(xtext,tempy3);
       setfillstyle(SOLID_FILL,black); /*to blank out extra text after 'r'*/
       bar(getx,gety+CHeight,Maxx,Maxy);      
    }

    /*----------------------------------------------------------------*/
    if (select=='e'){ /*empty, all 0s*/
       for (z=tablemax;z>=0;z--){
          if (value_range==2)  set_bit0(thisrule[cindex],z);
          else set_value(thisrule[cindex],z,0);
       }
       {reconfirm_rule}
    }
    else if (select=='f'){ /*fill with chosen value*/
       char temp;
        if (value_range>2){
           tempx=getx;
           tempy=gety; 
           draw_prompt_box(1);       
           sprintf(textb[0],"fill with value 0-%d (def %d):",
                               value_range-1,value_range-1);
           outtext(textb[0]);
           input_string(1,0);
           temp=atoi(is);
           if (is[0]!=13 && atoi(is)>=0 && atoi(is)<=value_range-1) temp=atoi(is);
           else temp=value_range-1;
           if (inbox==0) erase_prompt_box(1);
           moveto(tempx,tempy);
        }
        else temp=1;
	for (z=0;z<=tablemax;z++) set_value(thisrule[cindex],z,temp);
        {reconfirm_rule}
    }
    else if (select=='r'){ /*random rule*/
       signed int temprand;
       if (inbox==0 && rulemix && nhood_mixed==0 && all_remaining==1){
           /*set the remainder of rule-mix automatically*/  
	   if (bias_density_rule==100*(((float)value_range-1)/value_range)){
	      for (z=tablemax;z>=0;z--)
	         set_value(thisrule[cindex],z,myrand()%value_range);
           }
	   else{
	      for (z=tablemax;z>=0;z--){
	         temprand=myrand()%10000; /*0 to 9999*/
                 if (temprand>bias_density_rule*100){
                       set_value(thisrule[cindex],z,0);
                 }   
                 else{
                    temprand=myrand()%(value_range-1);
                    set_value(thisrule[cindex],z,temprand+1);
                 }
	      }
	   }
	   if (forcezero==1) set_value(thisrule[cindex],0,0);/*forcezero nhood -> 0*/
        }
        else{ 
	   random_bits(nhoodm[cindex],1,0,1,thisrule[cindex],tablemax);
           if (number_rules==1 && is[0]=='q'){
              select_def='b';
              goto start;
           }
        }
    }
    else if (select=='c'){ /*random chain-rule, for encryption*/
       chain_rule(thisrule[cindex],nhoodm[cindex],tablemax,cindex);
       {reconfirm_rule}  
    }
    else if (select=='v'){ /*load/save value rule-table*/
      /*unsigned int filebytes=0;*/
        tempx=getx;
        tempy=gety;
        draw_prompt_box(1);
        sprintf(textb[0],
            "ASCII rcode-table (v=%d k=%d S=%d) load/save-l/s:",
		                            value_range,tnhood,tablemax+1);
        outtext(textb[0]);
        input_string(1,0);
        if (is[0]=='l' || is[0]=='s'){
          load_save_ascii_rule_seed(
	     is[0],'r',thisrule[cindex],tablemax+1);
        }
        moveto(tempx,tempy);
        {reconfirm_rule}
    } 
    else if (select=='l'){ /*load rule*/
        tempx=getx;
        tempy=gety;
        ruleloaded=loadlast_rule_tcode_vcode(thisrule[cindex],
                             tnhood,tablemax,cindex);
        moveto(tempx,tempy);
        if (ruleloaded==nhoodm[cindex]) {reconfirm_rule}
    }
    else if (select=='p'){   /*repeat last rule*/
       /*to copy the last valid rule in a rulemix/nhood_mix*/ 
       if (rulemix && poss==Maxu && cindex>0){ 
	  if (nhood_mixed){   
	     if (k_seen[(signed int)nhoodm[cindex]]==1){
                memmove(thisrule[cindex],
                      k_rule[(signed int)nhoodm[cindex]],tablebytes);
             }	     
          }
          else if (rulemix) memmove(thisrule[cindex],thisrule[cindex-1],tablebytes);
       }
       else if (cindex==0) load_last_rule(thisrule[cindex],nhoodm[cindex]);
       else memmove(thisrule[cindex],thisrule[cindex-1],tablebytes);
       {reconfirm_rule}
    }
    else if (select=='b'){   /*enter as bits/values*/
        tempx=getx;
        tempy=gety;
        define_bits(nhoodm[cindex],1,thisrule[cindex],tablemax,0);
        if (number_rules==1 && is[0]=='q'){
           select_def='b';
           goto start;
        } 
        if (number_rules==1) select_def='b';
    }
    else if (select=='L'){ /*Life and Life-like rules*/
        tempx=getx;
        tempy=gety;
        
        game_of_Life_para('r',nhoodm[cindex]);
        game_of_Life_rule(thisrule[cindex],nhoodm[cindex],tablemax);

        free(birth);
        free(survival);
        if (value_range>2){
	   free(totv);
           free(winv);
        }
        moveto(tempx,tempy);
        {reconfirm_rule}
    }

    else if (select=='m' || select=='u'){
       majority_rule(thisrule[cindex],nhoodm[cindex],tablemax);
       if (select=='u') /*flip or shift outputs from unanimous (uniform) nhoods*/
	  shift_outputs_unanimous(thisrule[cindex],tablemax,
                                  nhoodm[cindex],cindex);
       {reconfirm_rule}
    }

    /*Lee Altenberg's random subset, set the output of each
      nhood in the rule table to a value, with prob of the frequency
      of that value in the nhood*/ 
    else if (select=='A'){ 
       altenberg_rule(thisrule[cindex],nhoodm[cindex],tablemax);
       {reconfirm_rule}
    }
     else if (select=='R'){
       tempx=getx;
       tempy=gety;
       set_reaction_diffusion_rule(thisrule[cindex],nhoodm[cindex],tablemax);
       moveto(tempx,tempy);
       {reconfirm_rule}
    }
    else if (select=='i'){ 
       isotropic_rule(0,thisrule[cindex],nhoodm[cindex],0,tablemax,tablemax,-1);
       {reconfirm_rule}
    }
    else if (select=='d' && rule_dec_max>0){ /*enter as dec*/
       tempx=getx;
       tempy=gety;
       sprintf(textb[0],"decimal equivalent: enter 0-%lu (def-rnd):",rule_dec_max);
       //tablemax= (signed int)pow(value_range,(double)tnhood)-1;
       next_line(xtext,1);
       outtext(textb[0]);
       sprintf(textb[0],"%lu",rule_dec_max);
       input_string(strlen(textb[0]),1);

       if (is[0]=='q') {revise};         
       if (is[0]==13) ruledec=myrand()%(rule_dec_max);
       else ruledec=atolu(is);/*string->unsigned long*/
       if (ruledec<=rule_dec_max){
          if (is[0]!=13)  ruledec=atolu(is);/*string->unsigned long*/
          else{
	     sprintf(textb[0]," %lu",ruledec);
	     outtext(textb[0]);
          }
          /*convert dec to valuestring*/
	  dec_to_value_line(thisrule[cindex],ruledec,tablemax+1);
          {reconfirm_rule}
       }
       else{
           setcolor(lightred);
	   outtext(" - too big! back-ret:");
           setcolor(white);
           input_string(1,0);
    
           select_def='d';
           goto start;
	}
    }
    else if (select=='h'){  /*enter as hex*/
      char bad_value_found=0;
       tempx=getx;
       tempy=gety;
       temp2=((signed int)ceil((double)((tablemax+1)*value_bits)/8));
       if (temp2<0) temp2=0;
       /*draw boxes, input hex*/
       bad_value_found=
             define_hex(nhoodm[cindex],1,thisrule[cindex],temp2-1,0,xtext);
       if (value_range==2){
          if (nhoodm[cindex]<3) thisrule[cindex][0] &= 0xf;
          if (nhoodm[cindex]==1){
	     for (z=3;z>=2;z--) set_bit0(thisrule[cindex],z);
          }
       }       
       moveto(tempx,tempy);
       setfillstyle(SOLID_FILL,black);
       if (inbox==0){
              moveto(xtext,tempy3);
              bar(getx,gety+CHeight,Maxx,Maxy);
       }
       else if (inbox==1)
              bar(trboxw+1,tempy3+CHeight*1.3,Maxx-2-1,Maxy-1);
       moveto(tempx,tempy);
       {reconfirm_rule}
    } 
   
    else if (select=='x'){ /*print rule to xterm*/
	char temp_pdata,temp_filedata;
        unsigned int vfreq[8],ttot=0;
           /*print hex, table, then the index/code/table to the terminal*/
	   if (inside_wiring_graphic==0){ 
              if (rulemix){ /*show details for the previous rule, otherwise all 0's */
                 if (cellindex==0) goto skip_x;
	         else{ 
                    cindex=cellindex-1;
                    tablemax= (signed int)pow(value_range,(double)nhoodm[cindex])-1;
                 } 
              }
           }
           if (rulemix) fprintf(stderr,"\nv%dk%d rcodeSize=%d cindex=%d\n",
		    value_range, nhoodm[cindex],tablemax+1,cindex);
           else fprintf(stderr,"\nv%dk%d rcodeSize=%d\n",
                              value_range, nhood,tablemax+1);           
           fprintf(stderr,"(hex) ");
           temp_pdata=pdata;
           temp_filedata=filedata;
           pdata=1;
           filedata=0;
           //print_current_bitstring_hexbytes(16,1,thisrule[cindex],-2,Maxx,white,3); why -2 ??
           print_current_bitstring_hexbytes(16,1,thisrule[cindex],nhoodm[cindex],Maxx,white,3);
           pdata=temp_pdata;
           filedata=temp_filedata;
 
           fprintf(stderr,"\nrcode-table:%d-0\n",value_range-1);
           for (z=value_range-1;z>=0;z--) vfreq[z]=0;  
           for (z=tablemax;z>=0;z--){
	      /*spaces for JM -- compatible with Mathematica*/
	      /*fprintf(stderr,"%d ",get_value(thisrule[cindex],z));*/
              fprintf(stderr,"%d",get_value(thisrule[cindex],z));
	      vfreq[get_value(thisrule[cindex],z)]+=1;
           }
           fprintf(stderr,"\nvfreq=");
           for (z=value_range-1;z>=0;z--){ 
              fprintf(stderr,"%d", vfreq[z]);
              if (z>0) fprintf(stderr,"+"); 
              ttot+=vfreq[z];
           }
           fprintf(stderr,"=%d", ttot);

           if (value_range==2) z_parameter_all(nhoodm[cindex],0,thisrule[cindex]);
           else z_parameter_all_mvalue(nhoodm[cindex],0,thisrule[cindex]);
           post_func(nhoodm[cindex], thisrule[cindex], 0,0,0,0);

           if (value_range==2) fprintf(stderr," ld=%.3g ld-r=%.3g P=%.3g ",
		     lambda,lratio,.5+(1.0-lratio)/2);
           else fprintf(stderr," ld=%.3g ld-r=%.3g",lambda,lratio);
           /*print Z parameter*/
           fprintf(stderr," zl=%f zr=%f", zparam[1],zparam[2]);

           if (ttot!=tablemax+1)
                        fprintf(stderr," !=tablesize=%d: ERROR",tablemax+1);

           draw_prompt_box(1);  
	   sprintf(textb[0],"print rcode-table (S=%d) to xterm (vert) -v:",
		      tablemax+1);
           outtext(textb[0]);
           input_string(1,0);
           if (is[0]=='v'){
	      for (z=tablemax;z>=0;z--){
                  fprintf(stderr,"\n%4d: ", z);
		  for(zz=nhood-1;zz>=0;zz--) 
                               fprintf(stderr,"%d",get_value(nm[zz],z));
	          fprintf(stderr," -> %d",
                        get_value(thisrule[cindex],z));
              }             
           }
          skip_x:
           if (number_rules==1){
              select_def='b';
              goto start;
           }
           else if (rulemix){
              select_def=select='r';
              continue;
           }
     }    

    /*-------------------------------------------------------------*/
    /*show details in bottom window for "by hand"
       but not if all_remaining set automatic*/
    if (rulemix && all_remaining==0){
       if (!(direction=='f' && limitcheck==0) || secondpart==0){
	  show_rule_bottom(nhoodm[cindex],0,thisrule[cindex],cindex);
       }
       else show_rule_bottom(nhoodm[cindex],0,carule[0],0); /*???*/
    }
    /*-------------compute/show Post functions------------------*/
    /*post_func(nhoodm[cindex], thisrule[cindex], 1,0,0); */
    if (rulemix==0) break;

    /*to record the last k rule*/
    if (nhood_mixed && poss==Maxu){
       if (k_seen[(signed int)nhoodm[cindex]]==0) 
                  k_seen[(signed int)nhoodm[cindex]]=1;
       /*record last k_rule set, if not copying automatically*/
       if (k_seen[(signed int)nhoodm[cindex]]!='a') 
             memmove(k_rule[(signed int)nhoodm[cindex]],
                   thisrule[cindex],tablebytes);
       
    }   
  }/*next cellindex*/
 
  if (inbox==0 && rulemix==0){
    char k_changed=0;
     show_rule_bottom(nhoodm[0],0,carule[0],0);
     k_changed=transform_rule(0); /*also saved here*/
     show_rule_bottom(nhoodm[0],0,carule[0],0);
     if (is[0]=='q' && k_changed==0) goto start;
  } 

  if (rulemix==0){
      save_last_rule(carule[0],nhood);
      if (is[0]=='q') is[0]=0;
  }  
   
# if __WATCOM__
     setviewport(0,0,Maxx,Maxy, 1);
# endif
  if (nhood_mixed && poss==Maxu){ 
     free(k_seen);
     for (z=1;z<=nhood;z++) free(k_rule[z]);
     free(k_rule);    
  }
  erase_prompt_box(2);
  return(gety);
}

/************* max decimal rule/tcode/kcode **************/
unsigned long max_dec_rule(signed int tablemax, char tvalue_range){
  unsigned long dec_max=0;
  
  /*fprintf(stderr,"\ntvalue_range=%d, tablemax=%d",tvalue_range, tablemax);*/ 
  if (  (tvalue_range==2 && tablemax+1<=32) ||
        (tvalue_range==3 && tablemax+1<=20) ||
        (tvalue_range==4 && tablemax+1<=16) ||
        (tvalue_range==5 && tablemax+1<=13) ||
        (tvalue_range==6 && tablemax+1<=12) ||
        (tvalue_range==7 && tablemax+1<=11) ||
        (tvalue_range==8 && tablemax+1<=10)){
 
    dec_max=(unsigned long)pow(tvalue_range,(double)(tablemax+1))-1;/*max code dec*/

    /*
    fprintf(stderr,"\n v=%d S=%d dec_max=%lu \n",tvalue_range,tablemax+1,dec_max);
   
    fprintf(stderr,"\n v=2 string=32 dec_max=%llu",(unsigned long long)pow(2,(double)32)-1);
    fprintf(stderr,"\n v=3 string=20 dec_max=%llu",(unsigned long long)pow(3,(double)20)-1);
    fprintf(stderr,"\n v=4 string=16 dec_max=%llu",(unsigned long long)pow(4,(double)16)-1);
    fprintf(stderr,"\n v=5 string=13 dec_max=%llu",(unsigned long long)pow(5,(double)13)-1);
    fprintf(stderr,"\n v=6 string=12 dec_max=%llu",(unsigned long long)pow(6,(double)12)-1);
    fprintf(stderr,"\n v=7 string=11 dec_max=%llu",(unsigned long long)pow(7,(double)11)-1);
    fprintf(stderr,"\n v=8 string=10 dec_max=%llu",(unsigned long long)pow(8,(double)10)-1);
    */
  }
 
  return(dec_max);
}

/***************** set a chain rule, July 2002  ****************/
void chain_rule(char *thisrule, char thisnhood, 
          signed int tablemax, unsigned int cindex){
 char temprand;

       startC:     
       temprand=myrand()%2;
       if (value_range==2){
          signed int bitcount;
          if (temprand==0){ /*left to right*/
             for (bitcount=0;bitcount<=tablemax-1;bitcount+=2){	    
                temprand=myrand()%2;
                set_bit(thisrule,bitcount,temprand);  
                set_bit(thisrule,bitcount+1,abs(temprand-1));
             }
          }
          else{
             for (bitcount=0;bitcount<=(tablemax-1)/2;bitcount++){            
                temprand=myrand()%2;
                set_bit(thisrule,bitcount,temprand);  
                set_bit(thisrule,bitcount+(tablemax+1)/2,abs(temprand-1));
             }
          }
       }
       else{
	  char *temprule,*kv_string;
          signed int tcount,vcount,i,ii,tablebytes;

          tablebytes=(signed int)ceil(value_bits * (double)(tablemax+1)/8);
          if ((temprule=(char *)calloc
              (tablebytes,sizeof(char)))==NULL) outof_memory("revrule");
          
          if ((kv_string=(char *)calloc 
                     (value_range,sizeof(char)))==NULL) outof_memory("(kv_string");
	  
          if (temprand==0) /*left to right*/
              memmove(temprule,thisrule,tablebytes);
          else /*left to right*/
             reflect_m_ruletable(thisnhood,thisrule,temprule);
          for (tcount=0;tcount<=tablemax-1;tcount+=value_range){
             /*make a value_range set of all different values*/
             for (i=0;i<=value_range-1;i++){
	        starti:
                kv_string[i]=myrand()%value_range;
                for (ii=0;ii<i;ii++){
		   if (kv_string[i]==kv_string[ii]) goto starti;
                }
             }
             for (vcount=tcount;vcount<=tcount+value_range-1;vcount++)
		 set_value(temprule,vcount,kv_string[vcount-tcount]);            
          }
          /*left to right or right to left*/
          if (temprand==0) memmove(thisrule,temprule,tablebytes);
          else reflect_m_ruletable(thisnhood,temprule,thisrule); 
          free(temprule);
	  free(kv_string);
       }
       if (value_range==2) z_parameter_all(thisnhood,0,thisrule);
       else z_parameter_all_mvalue(thisnhood,0,thisrule);
       /*fprintf(stderr,"\nz1=%.2f z2=%.2f Z=%.2f", 
	                     zparam[1],zparam[2],zparam[0]);*/ 
       if (cindex==0 && value_range==2){ 
          /*otherwize there might be structure - encryption*/
          if (zparam[1]<.5 || zparam[2]<.5) goto startC;
       }
       /*Z=1 in one direction only for chain rule*/
       if ((value_range==2 && thisnhood>=3) || 
                      (value_range>2 && thisnhood>=2)){
         if (zparam[1]==1 && zparam[2]==1) goto startC;
       }
}


/***************** set Life or Life-like rules  ****************/
void game_of_Life_para(char which, char thisnhood){

        /*1-D or 2-D game of LIFE*/
        /*A cell is "born" if it has exactly 3 live neighbours, 
        survives if it has 2 or 3 living neighbours, 
        and dies otherwise, is symbolised as (23/3)*/

       /*signed int *survival,*birth, are file variables*/
   
      signed int z,xbox;

       empty_center=0;
       centrec=ceil((double)thisnhood/2)-1; /*for 1d*/
       if (oned || thisnhood<=3) outer_k=thisnhood-1; 
       else if (twod==2 || (threed && thisnhood>=4 && thisnhood<=5)){
	   if (regular2d_tgrid==0){ /*square lattice*/
              if (thisnhood%2==0){ /*even k has empty centre*/ 
                 outer_k=thisnhood;
                 empty_center=1;
              }
              else outer_k=thisnhood-1;
               /*centre of nhood or rectangle*/
          
           }
           else if (regular2d_tgrid==1){ /*hex tiling*/
	      if (thisnhood==6 || thisnhood==9
                            || thisnhood==12){
                 outer_k=thisnhood; /*empty centre*/
                 empty_center=1;
              }
              else outer_k=thisnhood-1;

              /*centre of nhood or rectangle*/
	      if (thisnhood==7) centrec=3;
              else if (thisnhood==10) centrec=5;
              else if (thisnhood==13) centrec=6;
           }
       }
       else if (threed  && thisnhood>=6){
          if (thisnhood%2==1){ /*odd k has empty centre*/ 
                 outer_k=thisnhood;
                 empty_center=1;
          }
          else outer_k=thisnhood-1;
       }

       if ((birth=(signed int *)calloc(outer_k+1,sizeof(signed int)))
				       ==NULL) outof_memory("birth");
       if ((survival=(signed int *)calloc(outer_k+1,sizeof(signed int)))
				       ==NULL) outof_memory("survival");
       if (which=='r' && value_range>2){
           if ((totv=(char *)calloc(value_range,sizeof(char)))
				       ==NULL) outof_memory("totv");
           if ((winv=(char *)calloc(value_range,sizeof(char)))
				       ==NULL) outof_memory("winv");
       }

       /*set up default Life*/
       count_birth=0; /*1 valies birth[0]*/ 
       count_survival=1; /*2 valies count_survival[0], count_survival[1]*/ 
       for (z=0;z<=outer_k;z++){
          if (z==0) birth[z]=(signed int)ceil(((3.0/8)*outer_k));
	  else birth[z]=-1;

          if (z==0 && birth[0]>=1) survival[z]=birth[z]-1;
	  else if (z==1) survival[z]=birth[0];
          else survival[z]=-1;
       }
       
       
       /*fprintf(stderr,"\n1: outerk=%d centrec=%d",outer_k,centrec);
       fprintf(stderr,"\nsurvival(%d)=",outer_k,count_survival+1);
       for (z=0;z<=outer_k;z++) fprintf(stderr,"%d,", survival[z]);
       fprintf(stderr,"\nbirth(%d)=", outer_k,count_birth+1);
       for (z=0;z<=outer_k;z++) fprintf(stderr,"%d,", birth[z]);*/
       

    startLife:
       xbox=draw_prompt_box(4);
       sprintf(textb[0],"Life k=%d (def:  survival ",thisnhood);
       outtext(textb[0]);
       for (z=0;z<=outer_k-1;z++){ 
	 if (survival[z]>=0){
             sprintf(textb[0],"%d,", survival[z]);
	     outtext(textb[0]);
         }
       }
       /*enter no outer k for birth*/
       outtext(" birth ");
       for (z=0;z<=outer_k-1;z++){ 
	 if (birth[z]>=0){
             sprintf(textb[0],"%d,", birth[z]);
	     outtext(textb[0]);
         }
       }
       
       outtext(") accept-ret amend-a:");
       input_string(1,0);
       if (is[0]=='a');
       else goto skip_amend_Life;

       moveto(xbox,gety+CHeight);
       sprintf(textb[0],
	       "accept-ret, or enter number+ret, max entries=%d, max value=%d",
                                outer_k+1,outer_k);
       outtext(textb[0]);
       moveto(xbox,gety+CHeight);

       /*enter no outer k for survival*/
       outtext("enter survival (def=");
       for (z=0;z<=outer_k;z++){
	  if (survival[z]>=0){
	     sprintf(textb[0],"%d,", survival[z]);
             outtext(textb[0]);
          }
       }
       outtext("):");
      
       for (z=0;z<=outer_k;z++){ 
	  if (outer_k>9) input_string(2,0);
          else input_string(1,0);
          if (is[0]=='q') goto startLife;
          if (is[0]==13){ 
	     count_survival=z-1;/*no entered from 0*/
             break;
          }
          if (atoi(is)>=0 && atoi(is)<=outer_k){
             survival[z]=atoi(is);
             outtext(",");
          }          
       } 
       moveto(xbox,gety+CHeight);
        /*enter no outer k for birth*/
       outtext("enter birth (def=");
       for (z=0;z<=outer_k;z++){ 
	  if (birth[z]>=0){
             sprintf(textb[0],"%d,", birth[z]);
             outtext(textb[0]);
          }
       }
       outtext("):");
       for (z=0;z<=outer_k;z++){
          if (outer_k>9) input_string(2,0);
          else input_string(1,0);
          if (is[0]=='q') goto startLife;
          if (is[0]==13){
             count_birth=z;/*no entered from 0*/
             break;
          }
          if (atoi(is)>=0 && atoi(is)<=outer_k){ 
             birth[z]=atoi(is);
             outtext(",");
          }
       }
       
      skip_amend_Life:
       
       erase_prompt_box(4);
              
}

/***************** set Life or Life-like rules  ****************/
void game_of_Life_rule(char *thisrule, char thisnhood, 
                       signed int tablemax){
    
  signed int z,zz,tot,
               zv,totalive,majv,ties,temprand;

       
     /*fprintf(stderr,"\n2:outerk=%d centrec=%d",outer_k,centrec);
       fprintf(stderr,"\nsurvival(%d,%d)=",outer_k,count_survival+1);
       fprintf(stderr,"\n1: outerk=%d centrec=%d",outer_k,centrec);
       fprintf(stderr,"\nsurvival(%d)=",outer_k,count_survival+1);
       for (z=0;z<=outer_k;z++) fprintf(stderr,"%d,", survival[z]);
       fprintf(stderr,"\nbirth(%d)=", outer_k,count_birth+1);
       for (z=0;z<=outer_k;z++) fprintf(stderr,"%d,", birth[z]);*/
      
       for (zz=0;zz<=tablemax;zz++){
        
	  if (value_range==2){
              set_bit0(thisrule,zz);/*empty the rule*/   
	      tot=0;
	      /*count total of 1s in outer nhood*/
	      for (z=thisnhood-1;z>=0;z--){
	         if (get_bit(nm[z],zz)) tot+=1;
	      }
              if (empty_center==0) tot-=get_bit(nm[centrec],zz); /*delete center if empty*/             
	      /*birth*/
	      if (get_bit(nm[centrec],zz)==0){
                  for (z=0;z<=count_birth;z++){
		     if (tot==birth[z]){ 
                        set_bit1(thisrule,zz);
                        break;
                     }
                  }
	      }
	      /*survival*/
              else if (get_bit(nm[centrec],zz)==1){
                  for (z=0;z<=count_survival;z++){
		     if (tot==survival[z]){
                        set_bit1(thisrule,zz);
                        break;                        
                     }
                  }
	      }
	  }

          else if (value_range>2){   
	      totalive=0;
	      /*empty the rule*/
              set_value(thisrule,zz,0);    

	      for (zv=0;zv<=value_range-1;zv++){
                   totv[zv]=0;
                   winv[zv]=0;
              }  
              //*fprintf(stderr,"\ncolor freq=");*/
	      /*count totals of each value in outer nhood*/
              for (z=thisnhood-1;z>=0;z--)
	          if (!(empty_center==0 && z==centrec)
                        && get_value(nm[z],zz)>0 ) totv[get_value(nm[z],zz)]+=1;
              for (zv=0;zv<=value_range-1;zv++) totalive+=totv[zv];
              
              /*fprintf(stderr,"\n%d=",totalive);
		for (zv=0;zv<=value_range-1;zv++) fprintf(stderr," %d",totv[zv]);*/

              /*find the most frequent value other than 0*/
              tot=0;
              for (z=value_range-1;z>=1;z--){
	         if (totv[z]>=tot){ 
                    tot=totv[z];
                    majv=z;
                 }
              }
           
              ties=-1;
              for (z=value_range-1;z>=1;z--){
	         if (totv[z]==tot){
                    ties++;
                    winv[ties]=z;
	         }
              }
              if (ties>0){
                  temprand=myrand()%(ties+1);
                  majv=winv[temprand];
              }
              
	      /*birth*/
	      if (get_value(nm[centrec],zz)==0){
                  for (z=0;z<=count_birth;z++){
		     if (totalive==birth[z]){ 
                        set_value(thisrule,zz,majv);
                        break;
                     }
                  }
	      }
	      /*survival*/
              else if (get_value(nm[centrec],zz)>0){
                  for (z=0;z<=count_survival;z++){
		     if (totalive==survival[z]){
                        set_value(thisrule,zz,get_value(nm[centrec],zz));
                        break;                        
                     }
                  }
	      }
	  }          
       }
       
}

/***************** set Life or Life-like rules  ****************/
void game_of_Life_kcode(char *thiskcode, char thisnhood, 
                       signed int kcodemax, char center_value){
    
  signed int z,zz,totalive,v_bits,
               majtot,majvalue,no_of_maj,count,pick_rand;
  char *maj_tie;
       
      /*fprintf(stderr,"\n2:outerk=%d centrec=%d",outer_k,centrec);
       fprintf(stderr,"\nsurvival(%d,%d)=",outer_k,count_survival+1);
       fprintf(stderr,"\n1: outerk=%d centrec=%d",outer_k,centrec);
       fprintf(stderr,"\nsurvival(%d)=",outer_k,count_survival+1);
       for (z=0;z<=outer_k;z++) fprintf(stderr,"%d,", survival[z]);
       fprintf(stderr,"\nbirth(%d)=", outer_k,count_birth+1);
       for (z=0;z<=outer_k;z++) fprintf(stderr,"%d,", birth[z]);*/


       if ((maj_tie=(char *)calloc(value_range,sizeof(char)))
                            ==NULL) outof_memory("maj_tie");

       v_bits=check_value_bits(thisnhood+1);

       for (zz=0;zz<=kcodemax;zz++){        
	      totalive=0;
	      /*empty the kcode*/
              set_value(thiskcode,zz,0);    
              
              majtot=0;
              majvalue=0;
              for (z=value_range-1; z>=1; z--){ /*count total of values >=1 in nhood*/
                 maj_tie[z]=0;
	         if (get_value_flex(v_index[thisnhood][zz],z,v_bits)>majtot){
		     majtot=get_value_flex(v_index[thisnhood][zz],z,v_bits);
                     totalive+=majtot;
                     majvalue=z;
                 } 
           
              } 
              no_of_maj=0;
              for (z=value_range-1; z>=1; z--){
	         if (get_value_flex(v_index[thisnhood][zz],z,v_bits)
                                                             ==majtot){
		     maj_tie[z]=1;
                     no_of_maj+=1;
                 }
	      } 
              
              if (no_of_maj>1){/*majority tie, pick one at random*/
                 pick_rand=myrand()%(no_of_maj+1);
	         count=-1;
                 for (z=value_range; z>=1; z--){
                    if (maj_tie[z]==1){ 
                       count+=1;
                       if (count==pick_rand){
			  majvalue=z;
                          break;
                       }
                    }
                 }
	      }
              /*fprintf(stderr,"\ncenter_value=%d count_birth=%d totalive=%d, majvalue=%d",
		             center_value,count_birth,totalive,majvalue);*/
	      /*birth*/              
	      if (center_value==0){
                  for (z=0;z<=count_birth;z++){
		     if (totalive==birth[z]){ 
                        set_value(thiskcode,zz,majvalue);
                        break;
                     }
                  }
	      }
	      /*survival*/
              else if (center_value>=1){
                  for (z=0;z<=count_survival;z++){
		     if (totalive==survival[z]){
                        set_value(thiskcode,zz,center_value);
                        break;                        
                     }
                  }
	      }         
       }
       free(maj_tie);
       
}

/***************** set Majority rule  ****************/
void majority_rule(char *thisrule, char thisnhood, 
                                signed int tablemax){
 signed int zz,z,tot;
         if (value_range>2){
         /*majority rule for v>2,if tie pick at random from tied values*/
         signed int totv[8],winv[8],majv,ties,temprand;
          for (zz=0;zz<=tablemax;zz++){  
             for (z=value_range-1;z>=0;z--) totv[z]=0;
           
             for (z= thisnhood-1;z>=0;z--)
	                 totv[get_value(nm[z],zz)]+=1;
             tot=0;
             for (z=value_range-1;z>=0;z--){
	        if (totv[z]>=tot){ 
                   tot=totv[z];
                   majv=z;
                }
             }
             set_value(thisrule,zz,majv);

             ties=-1;
             for (z=value_range-1;z>=0;z--){
	        if (totv[z]==tot){
                   ties++;
                   winv[ties]=z;
	        }
             }
             if (ties>0){
                temprand=myrand()%(ties+1);
                set_value(thisrule,zz, winv[temprand]);
             }
          }
       }
       /*majority rule for v=2, if tie, center cell wins (as before)*/
       else{  
	 /*centre of nhood or rectangle*/
	 signed int centrec;
          centrec=ceil((double)thisnhood/2)-1;
          for (zz=0;zz<=tablemax;zz++){
	     tot=0;
	     /*find total of 1s in nhood*/
	     for (z=thisnhood-1;z>=0;z--){
	        if (get_bit(nm[z],zz)) tot+=1;
	     }
	     set_bit0(thisrule,zz);
	     /*odd or even nhoods, output=majority*/
	     if (tot>thisnhood/2) set_bit1(thisrule,zz);
	     /*even nhoods & tie, output=centre*/
	     if (thisnhood%2==0 && tot==thisnhood/2)
	       set_bit(thisrule,zz,get_bit(nm[centrec],zz));
          }
	}
}

/***************** set Altenberg rule  ****************/
void altenberg_rule(char *thisrule, char thisnhood, 
                                signed int tablemax){          
 signed int temprand,zz;
       for (zz=tablemax;zz>=0;zz--){
          temprand=myrand()%(thisnhood);
          if (value_range==2)
             set_bit(thisrule,zz,get_bit(nm[temprand],zz))
          else
             set_value(thisrule,zz,get_value(nm[temprand],zz));
       }
 }


/********** Reaction-Diffusion rule ****************/
void set_reaction_diffusion_rule(char *thisrule, char thisnhood, 
                                signed int tablemax){
    signed int zz,tempx,tempy;
    char *total1s,z,tempv,center_cell,center_v,lower_t,upper_t;

       tempx=getx;
       tempy=gety;

       if ((total1s=(char *)calloc(tablemax+1,sizeof(char)))
                            ==NULL) outof_memory("total1s");
      start_r:       
       lower_t=0;
       upper_t=thisnhood-1;
       draw_prompt_box(1);
       sprintf(textb[0],
	  "thresholds: lower (%d-%d def=%d):",lower_t,thisnhood,lower_t);
       outtext(textb[0]);
       input_string(2,0);
       if (is[0]=='q') goto skipRD;
       if (atoi(is)>=0 && atoi(is)<=thisnhood) lower_t=atoi(is);
       if (lower_t<=thisnhood-1) upper_t=thisnhood-1;
       else upper_t=thisnhood;
        
       sprintf(textb[0],
	  " upper (%d-%d  def=%d):",lower_t,thisnhood,upper_t);
       outtext(textb[0]);  
       input_string(2,0);
       if (is[0]=='q') goto start_r;
       if (atoi(is)>=lower_t && atoi(is)<=thisnhood) upper_t=atoi(is);
       center_cell=thisnhood/2;
       /*total of 1s excluding center_cell*/
       for (zz=tablemax;zz>=0;zz--){
	  if (get_value(nm[center_cell],zz)==0){
	     for (z=thisnhood-1;z>=0;z--){ 
		 if (get_value(nm[z],zz)==1) total1s[zz]+=1;
             }
          }
       }
       for (zz=tablemax;zz>=0;zz--){
	   /*if center cell is resting (0),
             threshold is invoked*/
           if (get_value(nm[center_cell],zz)==0){
	       /*if number of (1s) active  cells is within threshold
               change center to (1) active*/ 
               if (total1s[zz]>=lower_t && total1s[zz]<=upper_t)
                      set_value(thisrule,zz,1);
               /*if number of (1s) active cells is outside the threshold
                change or keep center to (0) resting*/ 
               else set_value(thisrule,zz,0);
           }
           /*if center cell is not resting (0)*/
           else{
	       /*increace output to v+1 (next refractory color)
               if value reaches max, change to resting*/
               center_v=get_value(nm[center_cell],zz);
	       tempv=center_v+1;
               if (tempv>value_range-1) tempv=0;
               set_value(thisrule,zz,tempv);               
           }
       }
      skipRD:
       free(total1s);
       erase_prompt_box(1);
       moveto(tempx,tempy);
 }

/****** set isotropic rules by rotation and reflection, also legal  **********/
void isotropic_rule(char show_details, char *thisrule, char thisnhood, 
         signed int start_index,signed int end_index,
                     signed int tablemax, char do_what){
  signed int z,zz,s,rotations,flips_extra,nhoodbytes,maxR,
             ref_dec,set_count,group_size=0,sz;
 char **xd_n,*ref_n,*tick_pos,*tick_group_pos,temp_value,temp_zero,*t;
 char unsorted,*temp_string,this_output,center_cell=-1;
 signed int *temp_group,temp_no,**isotropic_list,this_count,iso_tablebytes;

       /*show_details: 0..I (size) and hex in terminal
                       1..* (max output in terminal)
                       2..H (only for 2d 3x3 v2k9 Hensel notation in terminal, and Hensel s/ls)
                       3..R (allows iso-rule graphic edit, (size) and hex in terminal befor/after
         start_index, end_index: range to effect below, or one position start_index=end_index 
         do_what: 0..flip/(random mutate) iso-groups
                       used for on-the-fly 1/2 or ?. flip/flipback or select position
                    -1.. rnd isotropic rule
                    -2.. convert existing rule (rcode) to isotropic    
       */
       /*this uses full lookup table, so for 1d max-k is limited, unless extended*/
       /*omit 2d nhood >10. 3d applies for nhoods 6 and 7 only*/
       if (twod &&  (thisnhood==1 || thisnhood>=11) ) return;
       if (threed && (thisnhood<6 || thisnhood>7) )  return;
 
       nhoodbytes=(signed int)ceil( (float)(value_range*nhood)/8);
       flips_extra=0;/*extra for reflections*/
       if (oned)
	  maxR=2;  //just reflections, what about rotations?

       else if (twod){
	  if ((thisnhood==2 || thisnhood==3) && regular2d_tgrid==0){
              maxR=2; /*3 rotatons + 0 reflections*/
              rotations=2;
              flips_extra=0; 
	  }  
	  else if ((thisnhood==3 || thisnhood==4) && regular2d_tgrid==1){
              maxR=6; /*3 rotatons + 3 reflections*/
              rotations=3;
              flips_extra=3; 
	  } 	 	   
	  else if (thisnhood==6 || thisnhood==7){
              maxR=12; /*6 rotatons + 6 reflections*/
              rotations=6;
              flips_extra=6;
          }
          else if ((thisnhood==9 || thisnhood==10)  && regular2d_tgrid==1){
              maxR=6; /*3 rotatons + 3 reflections*/
              rotations=3;
              flips_extra=3;
          }         
          else{
              maxR=8; /*4 rotatons + 4 reflections*/
              rotations=4; /* 0 to 3, 0 is start for rotating*/
              flips_extra=4; /* 4 to 7, 4 is start for flipping*/
          }
       }             
       else if (threed) maxR=24;
       
       if ((t=(char*) calloc(7,sizeof(char)))  //to transform k=6 to k=7, 3d
	                  ==NULL) outof_memory("t");     
       if ((xd_n=(char**) calloc(maxR,sizeof(char*)))
					==NULL) outof_memory("xd_n");
       for (z=0;z<=maxR-1;z++){
          if ((xd_n[z]=(char*) calloc(nhoodbytes,sizeof(char)))
					==NULL) outof_memory("xd_n[]");
       }
       if (thisnhood>=2){           
          /*nominal pointers to list of isotropic nhood groups, expressed as dec numbers, 
	    to be realloced when the number of groups, and size of each, is known*/
          if ((isotropic_list=(signed int**) calloc(1,sizeof(signed int*)))
					==NULL) outof_memory("isotropic_list");
	  if ((temp_group=(signed int*) calloc(maxR,sizeof(signed int)))
					==NULL) outof_memory("temp_group");          
          if ((temp_string=(char*) calloc(nhoodbytes,sizeof(char)))
					==NULL) outof_memory("temp_string");
       }
       
       if ((ref_n=(char*) calloc(nhoodbytes,sizeof(char)))
					==NULL) outof_memory("ref_n");

       if ((tick_pos=(char*) calloc((signed int)ceil /*tick positions that have been allocated*/
                            (tablemax/sizeof(char)),sizeof(char)))
					==NULL) outof_memory("tick_pos");
       if ((tick_group_pos=(char*) calloc((signed int)ceil /*tick start of each group*/
                            (tablemax/sizeof(char)),sizeof(char)))
					==NULL) outof_memory("tick_group_pos");
       

       set_count=0; /*count of sub-set of symmetric lookup table*/
       
       for (zz=start_index;zz<=end_index;zz++){
	  if (do_what==-1){ /*random isotropic rule, and "legal"*/ 
             temp_value=myrand()%(value_range-1)+1; /*equal prob each value>0*/
             temp_zero= myrand()%(100); /*set chance of 0 at .5*/
             if (temp_zero>bias_density_rule) temp_value=0;
          }
	  else if (do_what==-2){ /*convert existing rule table to isotropic*/
	     temp_value=get_value(thisrule,zz);
	  }   
          else temp_value=do_what; /*mutate one random iso group at position=do_what
                                       (with '1' on-the-fly, back with '2'*/

	  /*-------------------------1d-------------------------------------*/
	  if (oned){
             if (get_bit(tick_pos,zz)==0){
	        set_bit1(tick_group_pos,zz);
                set_count+=1;
		//make xd_n[0] the original nhood*/
	        for (z=thisnhood-1;z>=0;z--) set_value(xd_n[0],z,get_value(nm[z],zz));
		//make xd_n[1] the flipped nhood*/
		for (z=thisnhood-1;z>=0;z--) set_value(xd_n[1],z,get_value(nm[thisnhood-1-z],zz));
		
                if (thisnhood % 2==1)  center_cell=get_value(xd_n[0],thisnhood/2);
		else center_cell=-1;//asymmetric omitt
		
	        for (z=thisnhood-1;z>=0;z--){
                   /*reverse the nhood order for 1d symm*/
                   set_value(ref_n,z,get_value(nm[(thisnhood-1)-z],zz));
	           ref_dec=(signed int)dec_equiv(ref_n,thisnhood-1);             
                }
                set_value(thisrule,zz,temp_value);
                set_value(thisrule,ref_dec,temp_value);
                set_bit1(tick_pos,ref_dec);
		
                /*******************************************************/
                for (s=0;s<=maxR-1;s++){

		     /*fprintf(stderr,"\ns=%d: ",s);
		     for (z=thisnhood-1;z>=0;z--) fprintf(stderr,"%d",get_value(xd_n[s],z));*/
		                         
		     ref_dec=(signed int)dec_equiv(xd_n[s],thisnhood-1); /*find dec equivs*/
		     //save dec equivs
		     temp_group[s]=ref_dec;
		     
                     //fprintf(stderr," = %d",ref_dec);

                     set_value(thisrule,ref_dec,temp_value); /*set these rotated output same*/ 
                     set_bit1(tick_pos,ref_dec); /*set 1 to tick this ruleindex set*/

                }
		this_output=temp_value;
                if (show_details==1){
                  /*full lookup table according to groups*/		     
                     if (do_what<0) fprintf(stderr,"\nindex=%d output=%d",
		                  set_count-1, this_output);
		     /*just one entry, including isotropic group*/		  		     
                     else fprintf(stderr,"\n1d v=%d k=%d index==%d output=%d",
				  value_range,thisnhood,temp_value-1, this_output);
		     
                     if (value_range==2 && this_output==1){
		        //if (center_cell > -1) fprintf(stderr," ccv=%d", center_cell); /*center_cell value*/
		        if (center_cell==1)      fprintf(stderr,"(survival)");
		        else if (center_cell==0) fprintf(stderr,"(birth)");
		     }

		  
		  /*fprintf(stderr,"\n1d-count=%d: zz=%d: ",set_count,zz);
		    for (z=thisnhood-1;z>=0;z--) fprintf(stderr,"%d",get_value(nm[z],zz));*/
		}
		
		  group_size=0;
                  unsorted=1;
                  while(unsorted==1){ /*sort group from low to high*/
		     unsorted=0;
		     for (s=0;s<=maxR-2;s++){
		        if (temp_group[s]>temp_group[s+1]){
			   unsorted=1;
                           temp_no=temp_group[s];
			   temp_group[s]=temp_group[s+1];
			   temp_group[s+1]=temp_no;
		        }
		     }
		   }
		  //for (s=0;s<=maxR-1;s++) fprintf(stderr," %d,",temp_group[s]);
		  group_size=maxR;
                  for (s=0;s<=maxR-2;s++){
		    if (temp_group[s]==temp_group[s+1]) group_size-=1; /*repeat found*/
		  }
		 
		  //fprintf(stderr," group_size=%d: ",group_size);
                  /*realloc for count of new group as dec number*/
		  if ((isotropic_list=(signed int**)realloc(isotropic_list,
				    (set_count+1)*sizeof(signed int*)))
					 ==NULL) outof_memory("isotropic_list");
		  if ((isotropic_list[set_count]=
		       (signed int*) calloc(group_size+1,sizeof(signed int*)))
					==NULL) outof_memory("isotropic_list[set_count]");
		  
		  isotropic_list[set_count][0]=group_size; /*0 gives size of the group*/

		  this_count=0;
	          for (s=0;s<=maxR-1;s++){ /*then list the position of nhoods in the rule-table*/
		    
		    if (s==0){
                      this_count+=1;
		      isotropic_list[set_count][this_count]=temp_group[s];
		    }  
		    else if (temp_group[s]==temp_group[s-1]) continue;
		    else{
		      this_count+=1;
		      isotropic_list[set_count][this_count]=temp_group[s];
		    }
		  }
		  if (show_details==1){
		     fprintf(stderr," group_size=%d\n",isotropic_list[set_count][0]);
		     for (s=1;s<=group_size;s++){
		        dec_to_value_line(temp_string,
				      (unsigned long)isotropic_list[set_count][s],thisnhood);
		        for (z=thisnhood-1;z>=0;z--) fprintf(stderr,"%d",get_value(temp_string,z));
		        fprintf(stderr,"=%d\n",isotropic_list[set_count][s]); 
		     }
		  }
		
             }
	  }
	  /*-------------------------end 1d-------------------------------------*/
	  /*-------------------------2d-------------------------------------*/
          else if (twod && thisnhood>=2){
               if (get_bit(tick_pos,zz)==0){
		  set_bit1(tick_group_pos,zz);
                  set_count+=1;
		  //make xd_n[0] the original nhood*/
	          for (z=thisnhood-1;z>=0;z--) set_value(xd_n[0],z,get_value(nm[z],zz));
		  /*(thisnhood==2 && regular2d_tgrid==0) no flips required*/
		  if (thisnhood==3 && regular2d_tgrid==0){ /*no flips required*/
		      center_cell=get_value(xd_n[0],1);
 		  } 
		  else if (thisnhood==3 && regular2d_tgrid==1){ 
                      memmove(xd_n[3],xd_n[0], nhoodbytes);
                      set_value(xd_n[3],2,get_value(xd_n[0],1));/*start pattern flip, NE-E*/
                      set_value(xd_n[3],1,get_value(xd_n[0],2));                 
                  }
		  else if (thisnhood==4 && regular2d_tgrid==1){
		      center_cell=get_value(xd_n[0],2);
                      memmove(xd_n[3],xd_n[0], nhoodbytes);
                      set_value(xd_n[3],3,get_value(xd_n[0],1));/*start pattern flip, NE-E*/
                      set_value(xd_n[3],1,get_value(xd_n[0],3));                 
                  }
                  else if (thisnhood==4 && regular2d_tgrid==0){ /*start pattern flip, l-r*/
                      memmove(xd_n[4],xd_n[0], nhoodbytes);
                      set_value(xd_n[4],2,get_value(xd_n[0],1));
                      set_value(xd_n[4],1,get_value(xd_n[0],2));                 
                  }
                  else if (thisnhood==5){ /*start pattern flip, l-r*/
		      center_cell=get_value(xd_n[0],2);
                      memmove(xd_n[4],xd_n[0], nhoodbytes);
                      set_value(xd_n[4],3,get_value(xd_n[0],1));
                      set_value(xd_n[4],1,get_value(xd_n[0],3));
                  }
                  else if (thisnhood==6 && regular2d_tgrid==1){ /*start pattern flip, l-r*/
                      memmove(xd_n[6],xd_n[0], nhoodbytes);
                      set_value(xd_n[6],5,get_value(xd_n[0],4));
                      set_value(xd_n[6],4,get_value(xd_n[0],5));
                      set_value(xd_n[6],3,get_value(xd_n[0],2));
                      set_value(xd_n[6],2,get_value(xd_n[0],3));
                      set_value(xd_n[6],1,get_value(xd_n[0],0)); 
                      set_value(xd_n[6],0,get_value(xd_n[0],1)); 
                  }
                  else if (thisnhood==7 && regular2d_tgrid==1){ /*start pattern flip, l-r*/
		      center_cell=get_value(xd_n[0],3);
                      memmove(xd_n[6],xd_n[0], nhoodbytes);
                      set_value(xd_n[6],6,get_value(xd_n[0],5));
                      set_value(xd_n[6],5,get_value(xd_n[0],6));
                      set_value(xd_n[6],4,get_value(xd_n[0],2));
                      set_value(xd_n[6],2,get_value(xd_n[0],4));
                      set_value(xd_n[6],1,get_value(xd_n[0],0)); 
                      set_value(xd_n[6],0,get_value(xd_n[0],1)); 
                  }
                  else if (thisnhood==8 && regular2d_tgrid==0){ /*start pattern flip, l-r*/
                      memmove(xd_n[4],xd_n[0], nhoodbytes);
                      set_value(xd_n[4],7,get_value(xd_n[0],5));
                      set_value(xd_n[4],5,get_value(xd_n[0],7));
                      set_value(xd_n[4],4,get_value(xd_n[0],3));
                      set_value(xd_n[4],3,get_value(xd_n[0],4));
                      set_value(xd_n[4],2,get_value(xd_n[0],0)); 
                      set_value(xd_n[4],0,get_value(xd_n[0],2)); 
                  }
                  else if (thisnhood==9 && regular2d_tgrid==0){ /*start pattern flip, l-r*/
		      center_cell=get_value(xd_n[0],4);
                      memmove(xd_n[4],xd_n[0], nhoodbytes);
                      set_value(xd_n[4],8,get_value(xd_n[0],6));
                      set_value(xd_n[4],6,get_value(xd_n[0],8));
                      set_value(xd_n[4],5,get_value(xd_n[0],3));
                      set_value(xd_n[4],3,get_value(xd_n[0],5));
                      set_value(xd_n[4],2,get_value(xd_n[0],0)); 
                      set_value(xd_n[4],0,get_value(xd_n[0],2)); 
                  }
                  else if (thisnhood==9 && regular2d_tgrid==1){ /*start pattern flip, l-r*/
                      memmove(xd_n[3],xd_n[0], nhoodbytes);
                      set_value(xd_n[3],7,get_value(xd_n[0],6));
                      set_value(xd_n[3],6,get_value(xd_n[0],7));
                      set_value(xd_n[3],5,get_value(xd_n[0],4));
                      set_value(xd_n[3],4,get_value(xd_n[0],5)); 
                      set_value(xd_n[3],2,get_value(xd_n[0],1)); 
                      set_value(xd_n[3],1,get_value(xd_n[0],2)); 
                      set_value(xd_n[3],3,get_value(xd_n[0],0)); 
                      set_value(xd_n[3],0,get_value(xd_n[0],3)); 
                  }
		   else if (thisnhood==10 && regular2d_tgrid==1){ /*start pattern flip, l-r*/
		      center_cell=get_value(xd_n[0],5);
                      memmove(xd_n[3],xd_n[0], nhoodbytes);
                      set_value(xd_n[3],8,get_value(xd_n[0],7));
                      set_value(xd_n[3],7,get_value(xd_n[0],8));
                      set_value(xd_n[3],6,get_value(xd_n[0],4));
                      set_value(xd_n[3],4,get_value(xd_n[0],6)); 
                      set_value(xd_n[3],2,get_value(xd_n[0],1)); 
                      set_value(xd_n[3],1,get_value(xd_n[0],2)); 
                      set_value(xd_n[3],3,get_value(xd_n[0],0)); 
                      set_value(xd_n[3],0,get_value(xd_n[0],3)); 
                  }
                  for (s=1;s<=rotations-1;s++){ 
                        /*nhoods that are equivalent by rotation + reflection*/
		        if (thisnhood==2 && regular2d_tgrid==0){
		           set_value(xd_n[s],1,get_value(xd_n[s-1],0));
                           set_value(xd_n[s],0,get_value(xd_n[s-1],1));
		        }
		        else if (thisnhood==3 && regular2d_tgrid==0){
		           set_value(xd_n[s],1,get_value(xd_n[s-1],1));
		           set_value(xd_n[s],2,get_value(xd_n[s-1],0));
                           set_value(xd_n[s],0,get_value(xd_n[s-1],2));
		        }
		        if (thisnhood==3 && regular2d_tgrid==1){ 
                           set_value(xd_n[s],2,get_value(xd_n[s-1],0));
                           set_value(xd_n[s],1,get_value(xd_n[s-1],2));
                           set_value(xd_n[s],0,get_value(xd_n[s-1],1));
			   memmove(xd_n[s+3],xd_n[s], nhoodbytes); /*rotate start flip*/
			   set_value(xd_n[s+3],2,get_value(xd_n[s],1));/*start pattern flip, NE-E*/
                           set_value(xd_n[s+3],1,get_value(xd_n[s],2));
			}
			if (thisnhood==4 && regular2d_tgrid==1){
			   set_value(xd_n[s],2,get_value(xd_n[s-1],2));/*center*/
			   set_value(xd_n[s],3,get_value(xd_n[s-1],1));
                           set_value(xd_n[s],1,get_value(xd_n[s-1],0));
                           set_value(xd_n[s],0,get_value(xd_n[s-1],3));
			   memmove(xd_n[s+3],xd_n[s], nhoodbytes); /*rotate start flip*/
			   set_value(xd_n[s+3],3,get_value(xd_n[s],1));/*start pattern flip, NE-E*/
                           set_value(xd_n[s+3],1,get_value(xd_n[s],3));
			}   
		        else if (thisnhood==4){
		           set_value(xd_n[s],3,get_value(xd_n[s-1],1));
                           set_value(xd_n[s],2,get_value(xd_n[s-1],3));
                           set_value(xd_n[s],0,get_value(xd_n[s-1],2));
                           set_value(xd_n[s],1,get_value(xd_n[s-1],0));
                           memmove(xd_n[s+4],xd_n[s], nhoodbytes);
			   set_value(xd_n[s+4],2,get_value(xd_n[s],1));/*start pattern flip, NE-E*/
                           set_value(xd_n[s+4],1,get_value(xd_n[s],2));
		        }
                        else if (thisnhood==5){
                           set_value(xd_n[s],2,get_value(xd_n[s-1],2));/*center*/
		           set_value(xd_n[s],4,get_value(xd_n[s-1],1));
                           set_value(xd_n[s],3,get_value(xd_n[s-1],4));
                           set_value(xd_n[s],0,get_value(xd_n[s-1],3));
                           set_value(xd_n[s],1,get_value(xd_n[s-1],0));
                           memmove(xd_n[s+4],xd_n[s], nhoodbytes);
			   set_value(xd_n[s+4],3,get_value(xd_n[s],1));
                           set_value(xd_n[s+4],1,get_value(xd_n[s],3));
		        }   
                        else if (thisnhood==6){
                           set_value(xd_n[s],5,get_value(xd_n[s-1],4));
		           set_value(xd_n[s],3,get_value(xd_n[s-1],5));
                           set_value(xd_n[s],1,get_value(xd_n[s-1],3));
                           set_value(xd_n[s],0,get_value(xd_n[s-1],1));
                           set_value(xd_n[s],2,get_value(xd_n[s-1],0));
                           set_value(xd_n[s],4,get_value(xd_n[s-1],2));
                           memmove(xd_n[s+6],xd_n[s], nhoodbytes);
                           set_value(xd_n[s+6],5,get_value(xd_n[s],4));
                           set_value(xd_n[s+6],4,get_value(xd_n[s],5));
                           set_value(xd_n[s+6],3,get_value(xd_n[s],2));
                           set_value(xd_n[s+6],2,get_value(xd_n[s],3));
                           set_value(xd_n[s+6],1,get_value(xd_n[s],0)); 
                           set_value(xd_n[s+6],0,get_value(xd_n[s],1)); 
		        }
                        else if (thisnhood==7){
                           set_value(xd_n[s],3,get_value(xd_n[s-1],3));/*center*/
                           set_value(xd_n[s],6,get_value(xd_n[s-1],5));
		           set_value(xd_n[s],4,get_value(xd_n[s-1],6));
                           set_value(xd_n[s],1,get_value(xd_n[s-1],4));
                           set_value(xd_n[s],0,get_value(xd_n[s-1],1));
                           set_value(xd_n[s],2,get_value(xd_n[s-1],0));
                           set_value(xd_n[s],5,get_value(xd_n[s-1],2));
                           memmove(xd_n[s+6],xd_n[s], nhoodbytes);
                           set_value(xd_n[s+6],6,get_value(xd_n[s],5));
                           set_value(xd_n[s+6],5,get_value(xd_n[s],6));
                           set_value(xd_n[s+6],4,get_value(xd_n[s],2));
                           set_value(xd_n[s+6],2,get_value(xd_n[s],4));
                           set_value(xd_n[s+6],1,get_value(xd_n[s],0)); 
                           set_value(xd_n[s+6],0,get_value(xd_n[s],1));
		        }
                        else if (thisnhood==8){                        
                           set_value(xd_n[s],6,get_value(xd_n[s-1],3));/*rot NWSE*/
                           set_value(xd_n[s],4,get_value(xd_n[s-1],6));
                           set_value(xd_n[s],1,get_value(xd_n[s-1],4));
                           set_value(xd_n[s],3,get_value(xd_n[s-1],1));        
                           set_value(xd_n[s],7,get_value(xd_n[s-1],5));/*rot corners*/
                           set_value(xd_n[s],2,get_value(xd_n[s-1],7));
                           set_value(xd_n[s],0,get_value(xd_n[s-1],2));
                           set_value(xd_n[s],5,get_value(xd_n[s-1],0));
                           /*flip each rotation l-r -  is enough*/
                           memmove(xd_n[s+4],xd_n[s], nhoodbytes);
			   set_value(xd_n[s+4],7,get_value(xd_n[s],5));
                           set_value(xd_n[s+4],5,get_value(xd_n[s],7));
                           set_value(xd_n[s+4],4,get_value(xd_n[s],3));
                           set_value(xd_n[s+4],3,get_value(xd_n[s],4));
                           set_value(xd_n[s+4],2,get_value(xd_n[s],0)); 
                           set_value(xd_n[s+4],0,get_value(xd_n[s],2)); 
		        }
                        else if (thisnhood==9 && regular2d_tgrid==0){	   
			   set_value(xd_n[s],4,get_value(xd_n[s-1],4));/*center*/
                           set_value(xd_n[s],7,get_value(xd_n[s-1],3));/*rot NWSE*/
                           set_value(xd_n[s],5,get_value(xd_n[s-1],7));
                           set_value(xd_n[s],1,get_value(xd_n[s-1],5)); 
                           set_value(xd_n[s],3,get_value(xd_n[s-1],1));
                           set_value(xd_n[s],8,get_value(xd_n[s-1],6));/*rot corners*/
                           set_value(xd_n[s],2,get_value(xd_n[s-1],8));
                           set_value(xd_n[s],0,get_value(xd_n[s-1],2));
                           set_value(xd_n[s],6,get_value(xd_n[s-1],0));
                           /*flip each rotation l-r -  is enough*/
                           memmove(xd_n[s+4],xd_n[s], nhoodbytes);
                           set_value(xd_n[s+4],8,get_value(xd_n[s],6));
                           set_value(xd_n[s+4],6,get_value(xd_n[s],8));
                           set_value(xd_n[s+4],5,get_value(xd_n[s],3));
                           set_value(xd_n[s+4],3,get_value(xd_n[s],5));
                           set_value(xd_n[s+4],2,get_value(xd_n[s],0)); 
                           set_value(xd_n[s+4],0,get_value(xd_n[s],2)); 
		        }
                        else if (thisnhood==9 && regular2d_tgrid==1){
			   set_value(xd_n[s],8,get_value(xd_n[s-1],0));
                           set_value(xd_n[s],7,get_value(xd_n[s-1],4));
                           set_value(xd_n[s],5,get_value(xd_n[s-1],6));
			   
                           set_value(xd_n[s],3,get_value(xd_n[s-1],8));			   
                           set_value(xd_n[s],2,get_value(xd_n[s-1],7));
                           set_value(xd_n[s],1,get_value(xd_n[s-1],5));

			   set_value(xd_n[s],0,get_value(xd_n[s-1],3));			   
                           set_value(xd_n[s],4,get_value(xd_n[s-1],2));
                           set_value(xd_n[s],6,get_value(xd_n[s-1],1));

			   
                           /*flip each rotation l-r -  is enough*/
                           memmove(xd_n[s+3],xd_n[s], nhoodbytes);
                           set_value(xd_n[s+3],7,get_value(xd_n[s],6));
                           set_value(xd_n[s+3],6,get_value(xd_n[s],7));
                           set_value(xd_n[s+3],5,get_value(xd_n[s],4));
                           set_value(xd_n[s+3],4,get_value(xd_n[s],5));
                           set_value(xd_n[s+3],3,get_value(xd_n[s],0));
                           set_value(xd_n[s+3],0,get_value(xd_n[s],3));
                           set_value(xd_n[s+3],2,get_value(xd_n[s],1)); 
                           set_value(xd_n[s+3],1,get_value(xd_n[s],2));
		        }
			else if (thisnhood==10 && regular2d_tgrid==1){
			   set_value(xd_n[s],5,get_value(xd_n[s-1],5));/*center*/
			   set_value(xd_n[s],9,get_value(xd_n[s-1],0));
                           set_value(xd_n[s],8,get_value(xd_n[s-1],4));
                           set_value(xd_n[s],6,get_value(xd_n[s-1],7));
			   
                           set_value(xd_n[s],3,get_value(xd_n[s-1],9));
                           set_value(xd_n[s],2,get_value(xd_n[s-1],8));
                           set_value(xd_n[s],1,get_value(xd_n[s-1],6));
			   
                           set_value(xd_n[s],0,get_value(xd_n[s-1],3));
                           set_value(xd_n[s],4,get_value(xd_n[s-1],2));
                           set_value(xd_n[s],7,get_value(xd_n[s-1],1));
                           /*flip each rotation l-r -  is enough*/
                           memmove(xd_n[s+3],xd_n[s], nhoodbytes);
                           set_value(xd_n[s+3],8,get_value(xd_n[s],7));
                           set_value(xd_n[s+3],7,get_value(xd_n[s],8));
                           set_value(xd_n[s+3],6,get_value(xd_n[s],4));
                           set_value(xd_n[s+3],4,get_value(xd_n[s],6));
                           set_value(xd_n[s+3],3,get_value(xd_n[s],0));
                           set_value(xd_n[s+3],0,get_value(xd_n[s],3));
                           set_value(xd_n[s+3],2,get_value(xd_n[s],1)); 
                           set_value(xd_n[s+3],1,get_value(xd_n[s],2));
		        }
                        
                        else if (thisnhood==11){ /*not a symmetric nhood*/
                           set_value(xd_n[s],5,get_value(xd_n[s-1],5));/*center*/
                           set_value(xd_n[s],8,get_value(xd_n[s-1],4));/*rot NWSE*/
                           set_value(xd_n[s],6,get_value(xd_n[s-1],8));
                           set_value(xd_n[s],2,get_value(xd_n[s-1],6));
                           set_value(xd_n[s],4,get_value(xd_n[s-1],2));
                           set_value(xd_n[s],9,get_value(xd_n[s-1],7));/*rot corners*/
                           set_value(xd_n[s],3,get_value(xd_n[s-1],9));
                           set_value(xd_n[s],1,get_value(xd_n[s-1],3));
                           set_value(xd_n[s],7,get_value(xd_n[s-1],1));
                           set_value(xd_n[s],10,get_value(xd_n[s-1],0));/*swap top and bottom*/
                           set_value(xd_n[s],0,get_value(xd_n[s-1],10));
		        }
                        else if (thisnhood==12){ /*not a symmetric nhood*/
                           set_value(xd_n[s],11,get_value(xd_n[s-1],4));/*rot NWSE outer*/
                           set_value(xd_n[s],7,get_value(xd_n[s-1],11));
                           set_value(xd_n[s],0,get_value(xd_n[s-1],7));
                           set_value(xd_n[s],4,get_value(xd_n[s-1],0));
                           set_value(xd_n[s],9,get_value(xd_n[s-1],5));/*rot NWSE inner*/
                           set_value(xd_n[s],6,get_value(xd_n[s-1],9)); 
                           set_value(xd_n[s],2,get_value(xd_n[s-1],6));
                           set_value(xd_n[s],5,get_value(xd_n[s-1],2));
                           set_value(xd_n[s],10,get_value(xd_n[s-1],8));/*rot corners*/
                           set_value(xd_n[s],3,get_value(xd_n[s-1],10));
                           set_value(xd_n[s],1,get_value(xd_n[s-1],3));
                           set_value(xd_n[s],8,get_value(xd_n[s-1],1));
		        }
                        else if (thisnhood==13){ /*not a symmetric nhood*/
                           set_value(xd_n[s],6,get_value(xd_n[s-1],6));/*center*/
                           set_value(xd_n[s],12,get_value(xd_n[s-1],4));/*rot NWSE outer*/
                           set_value(xd_n[s],8,get_value(xd_n[s-1],12)); 
                           set_value(xd_n[s],0,get_value(xd_n[s-1],8));
                           set_value(xd_n[s],4,get_value(xd_n[s-1],0));
                           set_value(xd_n[s],10,get_value(xd_n[s-1],5));/*rot NWSE inner*/
                           set_value(xd_n[s],7,get_value(xd_n[s-1],10)); 
                           set_value(xd_n[s],2,get_value(xd_n[s-1],7));
                           set_value(xd_n[s],5,get_value(xd_n[s-1],2));
                           set_value(xd_n[s],11,get_value(xd_n[s-1],9));/*rot corners*/
                           set_value(xd_n[s],3,get_value(xd_n[s-1],11));
                           set_value(xd_n[s],1,get_value(xd_n[s-1],3));
                           set_value(xd_n[s],9,get_value(xd_n[s-1],1));
		        }
                  }/*next s*/

		  /*******************************************************/
                  /*fprintf(stderr,"\nr=%d f=%d",rotations,flips_extra);*/
                  for (s=0;s<=rotations-1+flips_extra;s++){

		     /*fprintf(stderr,"\ns=%d: ",s);
		     for (z=thisnhood-1;z>=0;z--) fprintf(stderr,"%d",get_value(xd_n[s],z));*/
		                         
		     ref_dec=(signed int)dec_equiv(xd_n[s],thisnhood-1); /*find dec equivs*/
		     //save dec equivs
		     temp_group[s]=ref_dec;
		     
                     //fprintf(stderr," = %d",ref_dec);

                     set_value(thisrule,ref_dec,temp_value); /*set these rotated output same*/ 
                     set_bit1(tick_pos,ref_dec); /*set 1 to tick this ruleindex set*/

                  }
                  this_output=temp_value;
                  //if (do_what<0) this_output=get_value(thisrule,set_count); >logical bug??
		  //else this_output=get_value(thisrule,temp_value);  >logical bug??
		  
		  if (show_details==1){
		     /*full lookup table according to groups*/
		     if (do_what<0) fprintf(stderr,"\nindex=%d output=%d",
					   set_count-1, this_output);
		     /*just one entry, including isotropic group*/		  
		     else fprintf(stderr,"\n2d v=%d k=%d index=%d output=%d",
				  value_range,thisnhood,temp_value-1, this_output);

		     if (value_range==2 && this_output==1){
                       /*center_cell value, and not empty*/
		       //if (center_cell > -1) fprintf(stderr," ccv=%d", center_cell); 
		        if (center_cell==1)      fprintf(stderr,"(survival)");
		        else if (center_cell==0) fprintf(stderr,"(birth)");
		     }
		  }
		  
		  group_size=0;
                  unsorted=1;
                  while(unsorted==1){ /*sort group from low to high*/
		     unsorted=0;
		     for (s=0;s<=maxR-2;s++){
		        if (temp_group[s]>temp_group[s+1]){
			   unsorted=1;
                           temp_no=temp_group[s];
			   temp_group[s]=temp_group[s+1];
			   temp_group[s+1]=temp_no;
		        }
		     }
		   }
		  //for (s=0;s<=maxR-1;s++) fprintf(stderr," %d,",temp_group[s]);
		  group_size=maxR;
                  for (s=0;s<=maxR-2;s++){
		    if (temp_group[s]==temp_group[s+1]) group_size-=1; /*repeat found*/
		  }
		 
		  //fprintf(stderr," group_size=%d: ",group_size);
                  /*realloc for count of new group as dec number*/
		  if ((isotropic_list=(signed int**)realloc(isotropic_list,
				    (set_count+1)*sizeof(signed int*)))
					 ==NULL) outof_memory("isotropic_list");
		  if ((isotropic_list[set_count]=
		       (signed int*) calloc(group_size+1,sizeof(signed int*)))
					==NULL) outof_memory("isotropic_list[set_count]");
		  
		  isotropic_list[set_count][0]=group_size; /*0 gives size of the group*/

		  this_count=0;
	          for (s=0;s<=maxR-1;s++){ /*then list the position of nhoods in the rule-table*/
		    
		    if (s==0){
                      this_count+=1;
		      isotropic_list[set_count][this_count]=temp_group[s];
		    }  
		    else if (temp_group[s]==temp_group[s-1]) continue;
		    else{
		      this_count+=1;
		      isotropic_list[set_count][this_count]=temp_group[s];
		    }
		  }
		  if (show_details==1){
		              fprintf(stderr," group_size=%d\n",isotropic_list[set_count][0]);
		     for (s=1;s<=group_size;s++){
		        dec_to_value_line(temp_string,
				      (unsigned long)isotropic_list[set_count][s],thisnhood);
		        for (z=thisnhood-1;z>=0;z--) fprintf(stderr,"%d",get_value(temp_string,z));
		        fprintf(stderr,"=%d\n",isotropic_list[set_count][s]);
		     }
		   }
               }
          }
	  /*-------------------------end 2d---------------------------------*/
          /*-------------------------3d-------------------------------------*/
          else if (threed && (thisnhood==6 || thisnhood==7)){
               if (get_bit(tick_pos,zz)==0){
		  set_bit1(tick_group_pos,zz);
                  set_count+=1;          
                  if (thisnhood==6){
		     for (z=0;z<=5;z++) t[z]=z;
                  }
                  else if (thisnhood==7){
		     t[6]=3;/*center, not used*/
		     t[5]=6;
                     t[4]=5;
		     t[3]=4;
		     t[2]=2;
		     t[1]=1;
                     t[0]=0;
                  }
                  for (z=thisnhood-1;z>=0;z--) 
                          set_value(xd_n[0],z,get_value(nm[z],zz));                 
                  rotations=24; /*25 rot symm*/

		          /*symm1 rotate horiz plane*/
                          set_value(xd_n[1],t[2],get_value(xd_n[0],t[5])); 
                          set_value(xd_n[1],t[5],get_value(xd_n[0],t[3]));
                          set_value(xd_n[1],t[3],get_value(xd_n[0],t[0])); 
                          set_value(xd_n[1],t[0],get_value(xd_n[0],t[2]));
                          set_value(xd_n[1],t[4],get_value(xd_n[0],t[4]));/*axis same*/
                          set_value(xd_n[1],t[1],get_value(xd_n[0],t[1]));
                          if (thisnhood==7) set_value(xd_n[1],3,
                                             get_value(xd_n[0],3));/*center*/
                          /*symm2*/
                          set_value(xd_n[2],t[0],get_value(xd_n[0],t[5])); 
                          set_value(xd_n[2],t[2],get_value(xd_n[0],t[3]));
                          set_value(xd_n[2],t[5],get_value(xd_n[0],t[0])); 
                          set_value(xd_n[2],t[3],get_value(xd_n[0],t[2]));
                          set_value(xd_n[2],t[4],get_value(xd_n[0],t[4]));/*axis same*/
                          set_value(xd_n[2],t[1],get_value(xd_n[0],t[1]));
                          if (thisnhood==7) set_value(xd_n[2],3,
                                             get_value(xd_n[0],3));/*center*/
                          /*symm3*/
                          set_value(xd_n[3],t[3],get_value(xd_n[0],t[5]));
                          set_value(xd_n[3],t[0],get_value(xd_n[0],t[3]));
                          set_value(xd_n[3],t[2],get_value(xd_n[0],t[0])); 
                          set_value(xd_n[3],t[5],get_value(xd_n[0],t[2]));
                          set_value(xd_n[3],t[4],get_value(xd_n[0],t[4]));/*axis same*/
                          set_value(xd_n[3],t[1],get_value(xd_n[0],t[1]));
                          if (thisnhood==7) set_value(xd_n[3],3,
                                             get_value(xd_n[0],3));/*center*/
                          /*symm4: rotate vert plane flat*/
                          set_value(xd_n[4],t[2],get_value(xd_n[0],t[4])); 
                          set_value(xd_n[4],t[4],get_value(xd_n[0],t[3]));
                          set_value(xd_n[4],t[3],get_value(xd_n[0],t[1])); 
                          set_value(xd_n[4],t[1],get_value(xd_n[0],t[2]));
                          set_value(xd_n[4],t[5],get_value(xd_n[0],t[5]));/*axis same*/
                          set_value(xd_n[4],t[0],get_value(xd_n[0],t[0]));
                          if (thisnhood==7) set_value(xd_n[4],3,
                                             get_value(xd_n[0],3));/*center*/
                          /*symm5: rotate vert plane flat*/
                          set_value(xd_n[5],t[1],get_value(xd_n[0],t[4])); 
                          set_value(xd_n[5],t[2],get_value(xd_n[0],t[3]));
                          set_value(xd_n[5],t[4],get_value(xd_n[0],t[1])); 
                          set_value(xd_n[5],t[3],get_value(xd_n[0],t[2]));
                          set_value(xd_n[5],t[5],get_value(xd_n[0],t[5]));/*axis same*/
                          set_value(xd_n[5],t[0],get_value(xd_n[0],t[0]));
                          if (thisnhood==7) set_value(xd_n[5],3,
                                             get_value(xd_n[0],3));/*center*/
                          /*symm6: rotate vert plane flat*/
                          set_value(xd_n[6],t[3],get_value(xd_n[0],t[4])); 
                          set_value(xd_n[6],t[1],get_value(xd_n[0],t[3]));
                          set_value(xd_n[6],t[2],get_value(xd_n[0],t[1])); 
                          set_value(xd_n[6],t[4],get_value(xd_n[0],t[2]));
                          set_value(xd_n[6],t[5],get_value(xd_n[0],t[5]));/*axis same*/
                          set_value(xd_n[6],t[0],get_value(xd_n[0],t[0]));
                          if (thisnhood==7) set_value(xd_n[6],3,
                                             get_value(xd_n[0],3));/*center*/  
                          /*symm7: rotate vert edge on*/
                          set_value(xd_n[7],t[0],get_value(xd_n[0],t[4])); 
                          set_value(xd_n[7],t[4],get_value(xd_n[0],t[5]));
                          set_value(xd_n[7],t[5],get_value(xd_n[0],t[1])); 
                          set_value(xd_n[7],t[1],get_value(xd_n[0],t[0]));
                          set_value(xd_n[7],t[3],get_value(xd_n[0],t[3]));/*axis same*/
                          set_value(xd_n[7],t[2],get_value(xd_n[0],t[2]));
                          if (thisnhood==7) set_value(xd_n[7],3,
                                             get_value(xd_n[0],3));/*center*/
                          /*symm8: rotate vert edge on*/
                          set_value(xd_n[8],t[1],get_value(xd_n[0],t[4])); 
                          set_value(xd_n[8],t[0],get_value(xd_n[0],t[5]));
                          set_value(xd_n[8],t[4],get_value(xd_n[0],t[1])); 
                          set_value(xd_n[8],t[5],get_value(xd_n[0],t[0]));
                          set_value(xd_n[8],t[3],get_value(xd_n[0],t[3]));/*axis same*/
                          set_value(xd_n[8],t[2],get_value(xd_n[0],t[2]));
                          if (thisnhood==7) set_value(xd_n[8],3,
                                             get_value(xd_n[0],3));/*center*/
                          /*symm9: rotate vert edge on*/
                          set_value(xd_n[9],t[5],get_value(xd_n[0],t[4])); 
                          set_value(xd_n[9],t[1],get_value(xd_n[0],t[5]));
                          set_value(xd_n[9],t[0],get_value(xd_n[0],t[1])); 
                          set_value(xd_n[9],t[4],get_value(xd_n[0],t[0]));
                          set_value(xd_n[9],t[3],get_value(xd_n[0],t[3]));/*axis same*/
                          set_value(xd_n[9],t[2],get_value(xd_n[0],t[2]));
                          if (thisnhood==7) set_value(xd_n[9],3,
                                             get_value(xd_n[0],3));/*center*/
                          /*symm10 rotate vert plane flat of symm1*/
                          set_value(xd_n[10],t[0],get_value(xd_n[1],t[4])); 
                          set_value(xd_n[10],t[4],get_value(xd_n[1],t[5]));
                          set_value(xd_n[10],t[5],get_value(xd_n[1],t[1])); 
                          set_value(xd_n[10],t[1],get_value(xd_n[1],t[0]));
                          set_value(xd_n[10],t[2],get_value(xd_n[1],t[2]));/*axis same*/
                          set_value(xd_n[10],t[3],get_value(xd_n[1],t[3]));
                          if (thisnhood==7) set_value(xd_n[10],3,
                                             get_value(xd_n[1],3));/*center*/
                          /*symm11 rotate vert plane flat of symm1*/
                          set_value(xd_n[11],t[1],get_value(xd_n[1],t[4])); 
                          set_value(xd_n[11],t[0],get_value(xd_n[1],t[5]));
                          set_value(xd_n[11],t[4],get_value(xd_n[1],t[1])); 
                          set_value(xd_n[11],t[5],get_value(xd_n[1],t[0]));
                          set_value(xd_n[11],t[2],get_value(xd_n[1],t[2]));/*axis same*/
                          set_value(xd_n[11],t[3],get_value(xd_n[1],t[3]));
                          if (thisnhood==7) set_value(xd_n[11],3,
                                             get_value(xd_n[1],3));/*center*/
                          /*symm12 rotate vert plane flat of symm1*/
                          set_value(xd_n[12],t[5],get_value(xd_n[1],t[4])); 
                          set_value(xd_n[12],t[1],get_value(xd_n[1],t[5]));
                          set_value(xd_n[12],t[0],get_value(xd_n[1],t[1])); 
                          set_value(xd_n[12],t[4],get_value(xd_n[1],t[0]));
                          set_value(xd_n[12],t[2],get_value(xd_n[1],t[2]));/*axis same*/
                          set_value(xd_n[12],t[3],get_value(xd_n[1],t[3]));
                          if (thisnhood==7) set_value(xd_n[12],3,
                                             get_value(xd_n[1],3));/*center*/
                          /*symm13: rotate vert edge on of symm1*/
                          set_value(xd_n[13],t[3],get_value(xd_n[1],t[4])); 
                          set_value(xd_n[13],t[4],get_value(xd_n[1],t[2]));
                          set_value(xd_n[13],t[2],get_value(xd_n[1],t[1])); 
                          set_value(xd_n[13],t[1],get_value(xd_n[1],t[3]));
                          set_value(xd_n[13],t[5],get_value(xd_n[1],t[5]));/*axis same*/
                          set_value(xd_n[13],t[0],get_value(xd_n[1],t[0]));
                          if (thisnhood==7) set_value(xd_n[13],3,
                                             get_value(xd_n[1],3));/*center*/
                          /*symm14: rotate vert edge on of symm1*/
                          set_value(xd_n[14],t[1],get_value(xd_n[1],t[4])); 
                          set_value(xd_n[14],t[3],get_value(xd_n[1],t[2]));
                          set_value(xd_n[14],t[4],get_value(xd_n[1],t[1])); 
                          set_value(xd_n[14],t[2],get_value(xd_n[1],t[3]));
                          set_value(xd_n[14],t[5],get_value(xd_n[1],t[5]));/*axis same*/
                          set_value(xd_n[14],t[0],get_value(xd_n[1],t[0]));
                          if (thisnhood==7) set_value(xd_n[14],3,
                                             get_value(xd_n[1],3));/*center*/
                          /*symm15: rotate vert edge on of symm1*/
                          set_value(xd_n[15],t[2],get_value(xd_n[1],t[4])); 
                          set_value(xd_n[15],t[1],get_value(xd_n[1],t[2]));
                          set_value(xd_n[15],t[3],get_value(xd_n[1],t[1])); 
                          set_value(xd_n[15],t[4],get_value(xd_n[1],t[3]));
                          set_value(xd_n[15],t[5],get_value(xd_n[1],t[5]));/*axis same*/
                          set_value(xd_n[15],t[0],get_value(xd_n[1],t[0]));
                          if (thisnhood==7) set_value(xd_n[15],3,
                                             get_value(xd_n[1],3));/*center*/
                          /*symm16 rotate vert plane flat of symm2 (2 only)*/
                          set_value(xd_n[16],t[3],get_value(xd_n[2],t[4])); 
                          set_value(xd_n[16],t[4],get_value(xd_n[2],t[2]));
                          set_value(xd_n[16],t[2],get_value(xd_n[2],t[1])); 
                          set_value(xd_n[16],t[1],get_value(xd_n[2],t[3]));
                          set_value(xd_n[16],t[0],get_value(xd_n[2],t[0]));/*axis same*/
                          set_value(xd_n[16],t[5],get_value(xd_n[2],t[5]));
			  if (thisnhood==7) set_value(xd_n[16],3,
                                             get_value(xd_n[2],3));/*center*/
                          /*symm17 rotate vert plane flat of symm2 (2 only)*/
                          set_value(xd_n[17],t[2],get_value(xd_n[2],t[4])); 
                          set_value(xd_n[17],t[1],get_value(xd_n[2],t[2]));
                          set_value(xd_n[17],t[3],get_value(xd_n[2],t[1])); 
                          set_value(xd_n[17],t[4],get_value(xd_n[2],t[3]));
                          set_value(xd_n[17],t[0],get_value(xd_n[2],t[0]));/*axis same*/
                          set_value(xd_n[17],t[5],get_value(xd_n[2],t[5]));
			  if (thisnhood==7) set_value(xd_n[17],3,
                                             get_value(xd_n[2],3));/*center*/

                          /*symm18 rotate vert edge on symm2 (2 only)*/
                          set_value(xd_n[18],t[5],get_value(xd_n[2],t[4])); 
                          set_value(xd_n[18],t[4],get_value(xd_n[2],t[0]));
                          set_value(xd_n[18],t[0],get_value(xd_n[2],t[1])); 
                          set_value(xd_n[18],t[1],get_value(xd_n[2],t[5]));
                          set_value(xd_n[18],t[2],get_value(xd_n[2],t[2]));/*axis same*/
                          set_value(xd_n[18],t[3],get_value(xd_n[2],t[3]));
			  if (thisnhood==7) set_value(xd_n[18],3,
                                             get_value(xd_n[2],3));/*center*/
                          /*symm19 rotate vert edge on symm2 (2 only)*/
                          set_value(xd_n[19],t[0],get_value(xd_n[2],t[4])); 
                          set_value(xd_n[19],t[1],get_value(xd_n[2],t[0]));
                          set_value(xd_n[19],t[5],get_value(xd_n[2],t[1])); 
                          set_value(xd_n[19],t[4],get_value(xd_n[2],t[5]));
                          set_value(xd_n[19],t[2],get_value(xd_n[2],t[2]));/*axis same*/
                          set_value(xd_n[19],t[3],get_value(xd_n[2],t[3]));
                          if (thisnhood==7) set_value(xd_n[19],3,
                                             get_value(xd_n[2],3));/*center*/
                           /*symm20 rotate vert plane flat of symm3 (2 only)*/
                          set_value(xd_n[20],t[5],get_value(xd_n[3],t[4])); 
                          set_value(xd_n[20],t[4],get_value(xd_n[3],t[0]));
                          set_value(xd_n[20],t[0],get_value(xd_n[3],t[1])); 
                          set_value(xd_n[20],t[1],get_value(xd_n[3],t[5]));
                          set_value(xd_n[20],t[3],get_value(xd_n[3],t[3]));/*axis same*/
                          set_value(xd_n[20],t[2],get_value(xd_n[3],t[2]));
			  if (thisnhood==7) set_value(xd_n[20],3,
                                             get_value(xd_n[3],3));/*center*/
                          /*symm21 rotate vert plane flat of symm2 (2 only)*/
                          set_value(xd_n[21],t[0],get_value(xd_n[3],t[4])); 
                          set_value(xd_n[21],t[1],get_value(xd_n[3],t[0]));
                          set_value(xd_n[21],t[5],get_value(xd_n[3],t[1])); 
                          set_value(xd_n[21],t[4],get_value(xd_n[3],t[5]));
                          set_value(xd_n[21],t[3],get_value(xd_n[3],t[3]));/*axis same*/
                          set_value(xd_n[21],t[2],get_value(xd_n[3],t[2]));
			  if (thisnhood==7) set_value(xd_n[21],3,
                                             get_value(xd_n[3],3));/*center*/
                          /*symm22 rotate vert edge on symm2 (2 only)*/
                          set_value(xd_n[22],t[2],get_value(xd_n[3],t[4])); 
                          set_value(xd_n[22],t[4],get_value(xd_n[3],t[3]));
                          set_value(xd_n[22],t[3],get_value(xd_n[3],t[1])); 
                          set_value(xd_n[22],t[1],get_value(xd_n[3],t[2]));
                          set_value(xd_n[22],t[0],get_value(xd_n[3],t[0]));/*axis same*/
                          set_value(xd_n[22],t[5],get_value(xd_n[3],t[5]));
			  if (thisnhood==7) set_value(xd_n[22],3,
                                             get_value(xd_n[3],3));/*center*/
                          /*symm23 rotate vert edge on symm2 (2 only)*/
                          set_value(xd_n[23],t[3],get_value(xd_n[3],t[4])); 
                          set_value(xd_n[23],t[1],get_value(xd_n[3],t[3]));
                          set_value(xd_n[23],t[2],get_value(xd_n[3],t[1])); 
                          set_value(xd_n[23],t[4],get_value(xd_n[3],t[2]));
                          set_value(xd_n[23],t[0],get_value(xd_n[3],t[0]));/*axis same*/
                          set_value(xd_n[23],t[5],get_value(xd_n[3],t[5]));
			  if (thisnhood==7) set_value(xd_n[23],3,
                                             get_value(xd_n[3],3));/*center*/
                    
		     for (s=0;s<=rotations-1+flips_extra;s++){		         
		         /*for (z=thisnhood-1;z>=0;z--)      
			      fprintf(stderr,"%d",get_value(xd_n[s],z));*/
                         ref_dec=(signed int)dec_equiv(xd_n[s],thisnhood-1);
                         set_value(thisrule,ref_dec,temp_value);
                         set_bit1(tick_pos,ref_dec);
                     }
		     
		     /*******************************************************/
                     for (s=0;s<=maxR-1;s++){

		        /*fprintf(stderr,"\ns=%d: ",s);
		        for (z=thisnhood-1;z>=0;z--) fprintf(stderr,"%d",get_value(xd_n[s],z));*/
		                         
		        ref_dec=(signed int)dec_equiv(xd_n[s],thisnhood-1); /*find dec equivs*/
		        //save dec equivs
		        temp_group[s]=ref_dec; 
		     
                        //fprintf(stderr," = %d",ref_dec);

                        set_value(thisrule,ref_dec,temp_value); /*set these rotated output same*/ 
                        set_bit1(tick_pos,ref_dec); /*set 1 to tick this ruleindex set*/

                     }
                     this_output=temp_value;
		     
		 if (show_details==1){
                     /*full lookup table according to groups*/
		     if (do_what<0) fprintf(stderr,"\ncount=%d output=%d",
					      set_count-1, this_output);
		     /*just one entry, including isotropic group*/		  
		     else fprintf(stderr,"\n3d v=%d k=%d count=%d output=%d",
			       value_range,thisnhood,temp_value, this_output);
		     
                     if (value_range==2 && this_output==1){
                        /*center_cell value, and not empty*/
		        //if (center_cell > -1) fprintf(stderr," ccv=%d", center_cell); 
		        if (center_cell==1)      fprintf(stderr,"(survival)");
		        else if (center_cell==0) fprintf(stderr,"(birth)");
		     }

		  
		    /*fprintf(stderr,"\n1d-count=%d: zz=%d: ",set_count,zz);
		    for (z=thisnhood-1;z>=0;z--) fprintf(stderr,"%d",get_value(nm[z],zz));*/
		 }
                 group_size=0;
                  unsorted=1;
                  while(unsorted==1){ /*sort group from low to high*/
		     unsorted=0;
		     for (s=0;s<=maxR-2;s++){
		        if (temp_group[s]>temp_group[s+1]){
			   unsorted=1;
                           temp_no=temp_group[s];
			   temp_group[s]=temp_group[s+1];
			   temp_group[s+1]=temp_no;
		        }
		     }
		   }
		  //for (s=0;s<=maxR-1;s++) fprintf(stderr," %d,",temp_group[s]);
		  group_size=maxR;
                  for (s=0;s<=maxR-2;s++){
		    if (temp_group[s]==temp_group[s+1]) group_size-=1; /*repeat found*/
		  }
		 
		  //fprintf(stderr," group_size=%d: ",group_size);
                  /*realloc for count of new group as dec number*/
		  if ((isotropic_list=(signed int**)realloc(isotropic_list,
				    (set_count+1)*sizeof(signed int*)))
					 ==NULL) outof_memory("isotropic_list");
		  if ((isotropic_list[set_count]=
		       (signed int*) calloc(group_size+1,sizeof(signed int*)))
					==NULL) outof_memory("isotropic_list[set_count]");
		  
		  isotropic_list[set_count][0]=group_size; /*0 gives size of the group*/

		  this_count=0;
	          for (s=0;s<=maxR-1;s++){ /*then list the position of nhoods in the rule-table*/
		    
		    if (s==0){
                      this_count+=1;
		      isotropic_list[set_count][this_count]=temp_group[s];
		    }  
		    else if (temp_group[s]==temp_group[s-1]) continue;
		    else{
		      this_count+=1;
		      isotropic_list[set_count][this_count]=temp_group[s];
		    }
		  }
		  if (show_details==1){
		        fprintf(stderr," group_size=%d\n",isotropic_list[set_count][0]);
		     for (s=1;s<=group_size;s++){
		        dec_to_value_line(temp_string,
				      (unsigned long)isotropic_list[set_count][s],thisnhood);
		        for (z=thisnhood-1;z>=0;z--) fprintf(stderr,"%d",get_value(temp_string,z));
		        fprintf(stderr,"=%d\n",isotropic_list[set_count][s]); 
		     }
		  }
		  /******************************  *******************************/   
                     /*fprintf(stderr,"\n3d-count=%d: zz=%d: ",set_count,zz);*/
                 } 
	  }   //end... else if (threed && (thisnhood==6 || thisnhood==7)){
	  /*------------------------------end 3d--------------------------------------*/
	  
       }  //end... for (zz=start_index;zz<=end_index;zz++){

       /*-----------------------------------------------------------------------------------*/
       /*unless a kcode (isotropic or not) was loaded,
        make it "legal": i.e. make uniform states have same outputs as the nhood*/
       /* i.e. 000..->0 111..->1 222..->2 etc */
       if (do_what!=-2){ /*not for a kcode already loaded. Non-iso will be converted to iso*/
          if (value_range==2){
                set_bit0(thisrule,0);
                set_bit1(thisrule,tablemax); 
          }
          else{
	       for (z=value_range-1;z>=0;z--){ 
	         for (zz=thisnhood-1;zz>=0;zz--) set_value(ref_n,zz,z); 
                 ref_dec=(signed int)dec_equiv(ref_n,thisnhood-1);
                 set_value(thisrule,ref_dec,z);  
               }
          }
       }
       
       //(show_details==1 all, show_details==2 for Hensel notation
       //if ((show_details==1 || show_details==2) && do_what<0){
       if (do_what<0){
	 signed int *group_types,*group_outer_count,this_count=0,ccindex=0,thisdim;
	 char *iso_table;
	 
	 if (thisnhood>=2){ /*ccindex is the nhood index of the center cell*/
	   if (thisnhood==3 && regular2d_tgrid==0) ccindex=1;
	   else if (thisnhood==4 && regular2d_tgrid==1) ccindex=2;
	   else if (thisnhood==5 && regular2d_tgrid==0) ccindex=2;
	   else if (thisnhood==7 && regular2d_tgrid==1) ccindex=3;
	   else if (thisnhood==9 && regular2d_tgrid==0) ccindex=4;
	   else if (thisnhood==10 && regular2d_tgrid==0) ccindex=5;
	 }

	 if ((group_types=(signed int*) calloc(set_count+1,sizeof(signed int)))
					==NULL) outof_memory("group_types");
	 if ((group_outer_count=(signed int*) calloc(set_count+1,sizeof(signed int)))
					==NULL) outof_memory("group_outer_count");

	 iso_tablebytes=(signed int)ceil(value_bits * (double)(set_count)/8);
         if ((iso_table=(char *)calloc(iso_tablebytes,sizeof(char)))
				       ==NULL) outof_memory("iso_table");
	 
	 /*-----------------------------------------------------------------------*/  
	 /**** show details in terminal, make/edit/file iso-group table **********/
         /*show iso rule-table, and list of groups in reverse position order*/
	 this_count=0;
	 if (oned) thisdim=1;
	 else if (twod) thisdim=2;
	 else if  (threed) thisdim=3;
	 
	 if (show_details==1) fprintf(stderr,
		"\n%dd v=%d k=%d iso-table(%d)=",thisdim,value_range,thisnhood,set_count);
         for (zz=tablemax;zz>=0;zz--){	        
	        if (get_bit(tick_group_pos,zz)==1){
		   if (show_details==1) fprintf(stderr,"%d",get_value(thisrule,zz));
		   if (thisnhood>=2){
		      this_count++;
		      group_types[set_count+1-this_count]=zz;
		      set_value(iso_table,set_count-this_count, get_value(thisrule,zz));
		   }
		}    		     		
         }
	 	 
         /*------------------------------???-----------------------------*/
	 /*list of group types, based on lowest decimal value, in descending order*/
         if (show_details==1){
	    fprintf(stderr,"\ngroup-types (%d/%d=%f)=",
		         set_count,tablemax+1,(float)(set_count)/(tablemax+1));
	 
	    for (s=set_count;s>=1;s--){
	       //fprintf(stderr,"%d:%d:",s,group_types[s]);
	        fprintf(stderr,"%d ",group_types[s]);	         
	    }
	 }
	 
         iso_tablemax=set_count-1; //iso_tablemax is global
         //fprintf(stderr,"\niso_tablemax=%d iso_tablebytes=%d",iso_tablemax,iso_tablebytes);
	 
	   
         memmove(iso_rule,iso_table,iso_tablebytes); //iso_rule is global
         if (show_details==3 || show_details==1 ||  show_details==0 ){
	    //print iso-table as hex in terminal, (unless single index - no, needed for mutation)
	    //if (iso_tablemax>0){ 
	       //fprintf(stderr,"\niso-size=%d iso-hex=",iso_tablemax+1);
	       /*black to be invisible onscreen*/
               print_current_bitstring_hexbytes(16,4,iso_table,nhood,Maxx,black,6);
	    //}
	 }
	 //this is just a check, no need to print
         //fprintf(stderr,"\ncheck iso-table-count(%d)=",set_count);
         //for (zz=set_count-1;zz>=0;zz--) fprintf(stderr,"%d",get_value(iso_table,zz));

	 //fprintf(stderr,"\ntick_group_pos rcode-table(%d)=",tablemax+1);
	 //for (zz=tablemax;zz>=0;zz--) fprintf(stderr,"%d",get_value(tick_group_pos,zz));
	 
	 //fprintf(stderr,"\niso_rule=");
	 //for (zz=set_count-1;zz>=0;zz--) fprintf(stderr,"%d",get_value(iso_rule,zz));

	 //no need to print, take too much space
	 //fprintf(stderr,"\nrcode-table(%d)=",tablemax+1);
	 //for (zz=tablemax;zz>=0;zz--) fprintf(stderr,"%d",get_value(thisrule,zz));
	 
	 //transfer changes to iso_rule to full carule
	 if (show_details==1) fprintf(stderr,"\niso_tablemax=%d",iso_tablemax);
         for (z=iso_tablemax; z>=0; z--){
	       //if (show_details==1) fprintf(stderr,"\n%d:",z);
	       temp_value=get_value(iso_rule,z);
               //if (show_details==1) fprintf(stderr,"(%d)", temp_value);
               for (s=1;s<=isotropic_list[z+1][0];s++){
		     //if (show_details==1) fprintf(stderr," %d", isotropic_list[z+1][s]);
	             set_value(thisrule,isotropic_list[z+1][s],temp_value);
		      /*list of all nhoods and iso-rule index for each*/
		     group_list_iso[isotropic_list[z+1][s]]=z;
	       }
	 }
          
	 /*copy to global*/
         for (z=iso_tablemax; z>=0; z--){
	     //fprintf(stderr,"\n%d:",z);
             for (s=0;s<=isotropic_list[z+1][0];s++){
	         glbl_iso_list[z][s]=isotropic_list[z+1][s]; /*copy to global*/
		 //fprintf(stderr," %d", glbl_iso_list[z][s]);
	     }
	 }    
	 /*show nhood-value:group-number, to use in the iso-lookup-histogram*/         
	 //for (z=tablemax;z>=0; z--)
	 //fprintf(stderr,"\n%d:%d",z,group_list_iso[z]);
	 
         /*isotropic bit pattern, and bit/value editing and transformations
	   show/edit/save/load interactive iso-rule table graphic, or in hex
           or show group for selected iso-index + graphic patterns 1d,2d,3d*/
         isotropic_set=1;
         if (show_details==3){
	    setfillstyle(SOLID_FILL,black);/*(black) to clear area before bit/value string*/
	    bar(iso_x,iso_y,Maxx-vgax(1),Maxy-vgay(1));
            define_bits(thisnhood,4,iso_rule,iso_tablemax,0);
	    setfillstyle(SOLID_FILL,black);/*(black) to clear area after bit/value string*/
	    bar(iso_x,iso_y,Maxx-vgax(1),Maxy-vgay(1)); 
	    
	    if (memcmp(iso_rule,iso_table,iso_tablemax)!=0) { //iso-rule changed
	       fprintf(stderr,"\nrevised iso-table:");
	       fprintf(stderr,"\niso_tablemax=(%d)",iso_tablemax);
               for (z=iso_tablemax; z>=0; z--){
		    fprintf(stderr,"%d", get_value(iso_rule,z));
	       }
	       //print iso-table as hex in terminal
	       fprintf(stderr,"\niso-hex="); //black to be invisible on screen
               print_current_bitstring_hexbytes(16,4,iso_rule,nhood,Maxx,black,6);	       
	    }
	    /*if changes, update the full rule-table*/
	    for (z=iso_tablemax; z>=0; z--){
	       //if (show_details==1) fprintf(stderr,"\n%d:",z);
	       temp_value=get_value(iso_rule,z);
               //if (show_details==1) fprintf(stderr,"(%d)", temp_value);
               for (s=1;s<=isotropic_list[z+1][0];s++){
		     //if (show_details==1) fprintf(stderr," %d", isotropic_list[z+1][s]);
	             set_value(thisrule,isotropic_list[z+1][s],temp_value);
		      //list of all nhoods and iso-rule index for each
		     //group_list_iso[isotropic_list[z+1][s]]=z;
	       }
	    }
	 } 
	 	  	 
         isotropic_set=0;       
         set_iso_bitflip=1;/*isotropic rules, toggle while running forward - not iso*/
	 //set_iso_input_histogram=1;/*input-histogran according to iso-rule in forx.c*/
	 
         /*---------------------------if (show_details==3)----------------------*/
	 
         //fprintf(stderr,"\ntick_group_pos rcode-table(%d)=",tablemax+1);
	 //for (zz=tablemax;zz>=0;zz--) fprintf(stderr,"%d",get_value(tick_group_pos,zz));

         //no need to print, takes too much space
	 //fprintf(stderr,"\nrcode-table(%d)=",tablemax+1);
	 //for (zz=tablemax;zz>=0;zz--) fprintf(stderr,"%d",get_value(thisrule,zz));
       
	 if (twod && thisnhood>=2){
	    signed int nhood_outer_count=0;
	     /*
	     fprintf(stderr,"\n%d groups-types:\n",set_count);
	     for (s=set_count;s>=1;s--){
	        fprintf(stderr,"%d=%d ",group_types[s],get_value(iso_table,s));
	     }*/

	  //set up Hensel notation, first outer-count, then pattern-type   
	  if (show_details==2 && thisnhood==9){ 
            //fprintf(stderr,"\n%d groups-types and Hensel notation outer-count:\n",set_count);	    

	    unsigned char **Hensel_matrix_birth,**Hensel_matrix_survival,
	      *pattern_types,*pattern_labels,labels_array[15],numbers_array[10],
	      show_once,Hsl=0,*Hensel_string; //Hsl is Hensel_string_length
	    signed int **Hensel_group_matrix;
	    
            //big enough to contain max string length
	    if ((Hensel_string=(unsigned char*) calloc(255,sizeof(unsigned char))) 
					==NULL) outof_memory("Hensel_string");
	    
            if ((pattern_types=(unsigned char*) calloc(set_count+1,sizeof(unsigned char)))
					==NULL) outof_memory("pattern_types");
	    if ((pattern_labels=(unsigned char*) calloc(123,sizeof(unsigned char))) //to cover ascii labels 'c'-'z'
					==NULL) outof_memory("pattern_types");
	    
	    if ((Hensel_matrix_birth=(unsigned char**) calloc(9,sizeof(unsigned char*)))
					==NULL) outof_memory("Hensel_matrix_birth");
	    if ((Hensel_matrix_survival=(unsigned char**) calloc(9,sizeof(unsigned char*)))
					==NULL) outof_memory("Hensel_matrix_survival");
	    
	     
	     for (z=0;z<=8;z++){
	         sprintf(textb[0],"Hensel_matrix[%d]",z);
	         if ((Hensel_matrix_birth[z]=(char*) calloc(15,sizeof(char)))
					==NULL) outof_memory(textb[0]);
		 if ((Hensel_matrix_survival[z]=(char*) calloc(15,sizeof(char)))
					==NULL) outof_memory(textb[0]);
	     }

	     if ((Hensel_group_matrix=(signed int**) calloc(9,sizeof(signed int*)))
					==NULL) outof_memory("Hensel_group_matrix");
	     for (z=0;z<=8;z++){
		 if ((Hensel_group_matrix[z]=(signed int*) calloc(15,sizeof(signed int)))
		                        ==NULL) outof_memory(textb[0]);
	     }
	      
	     nhood_outer_count=0;
	     //fprintf(stderr,"\ngroup number:outer_count"); 
	     for (s=set_count;s>=1;s--){
	       //fprintf(stderr,"%d:%d:",s-1,group_types[s]);
	        nhood_outer_count=0;
	        for (z=thisnhood-1;z>=0;z--){
		  if (z==ccindex) continue;
		  if (get_value(nm[z],group_types[s])==1) nhood_outer_count+=1;
		}
		group_outer_count[s]=nhood_outer_count;
	        //fprintf(stderr,"%d ",group_outer_count[s]);
	     }
	     

	     // setup Hensel notation for each pattern-type c,e,k,a,i,n,q,j,r,t,w,z
	     //fprintf(stderr,"\nset_count=%d ccindex=%d",set_count,ccindex);
             iso_Hensel_setup(set_count,ccindex,group_types,pattern_types,Hensel_group_matrix);
	     /*
	     fprintf(stderr,"\n%d Birth nhoods:\n",set_count);
	     for (s=set_count;s>=1;s--){
	       if (get_value(nm[ccindex],s)==0) fprintf(stderr,"%d ",group_types[s]);
	     }
	     fprintf(stderr,"\n%d Survival  nhoods:\n",set_count);
	     for (s=set_count;s>=1;s--){
	       if (get_value(nm[ccindex],s)==1)fprintf(stderr,"%d ",group_types[s]);
	     }
             */
	     /*print Hensel notation, this shows the notation in jumbled order
	       and group_outer_count's repeated*/
	     
	     /*     
	     fprintf(stderr,"\n%d Birth:\n",set_count);
	     for (s=1;s<=set_count;s++){
	       if (get_value(nm[ccindex],group_types[s])==0 && get_value(iso_table,s)==1){
	         fprintf(stderr,"%d",group_outer_count[s]);
		 fprintf(stderr,"%c",pattern_types[s]);
		 //fprintf(stderr,"(%d)",pattern_types[s]);
	       }
	     }
	     fprintf(stderr,"\n%d Survival:\n",set_count);
	     for (s=1;s<=set_count;s++){
	       if (get_value(nm[ccindex],group_types[s])==1 && get_value(iso_table,s)==1 ){
		  fprintf(stderr,"%d",group_outer_count[s]);
		  fprintf(stderr,"%c",pattern_types[s]);
		  //fprintf(stderr,"(%d)",pattern_types[s]);
   	       }
	     }*/
	     
             pattern_labels['0']=0; //ascii 0=48;
             pattern_labels['c']=1; //ascii c=99;
	     pattern_labels['e']=2; //ascii e=101
	     pattern_labels['k']=3; //ascii k=107
	     pattern_labels['a']=4; //ascii a=97
             pattern_labels['i']=5; //ascii i=105
             pattern_labels['n']=6; //ascii n=110
             pattern_labels['y']=7; //ascii y=121
             pattern_labels['q']=8; //ascii q=113
             pattern_labels['j']=9; //ascii j=106
             pattern_labels['r']=10; //ascii r=114
	     pattern_labels['t']=11; //ascii t=116
	     pattern_labels['w']=12; //ascii w=119 
             pattern_labels['z']=13; //ascii z=122
	     pattern_labels['8']=14; //ascii 8=56
	     
             //unsigned char labels_array[15]
	     labels_array[0]='0';
	     labels_array[1]='c';
	     labels_array[2]='e';
	     labels_array[3]='k';
	     labels_array[4]='a';
	     labels_array[5]='i';
	     labels_array[6]='n';
	     labels_array[7]='y';
	     labels_array[8]='q';
	     labels_array[9]='j';
	     labels_array[10]='r';
	     labels_array[11]='t';
	     labels_array[12]='w';
	     labels_array[13]='z';
	     labels_array[14]='8';

	     //unsigned char numbers_array[10]
	     numbers_array[0]='0';
             numbers_array[1]='1';
	     numbers_array[2]='2';
             numbers_array[3]='3';
	     numbers_array[4]='4';
             numbers_array[5]='5';
	     numbers_array[6]='6';
	     numbers_array[7]='7';
             numbers_array[8]='8';
	     numbers_array[9]='9';
             
	     //fprintf(stderr,"\n%d fill Hensel_matrix_birth:\n",set_count);
	     //capara83.c revised here, iso_count 0-(set_count-1),
	     //group_types,group_outer_count,pattern_labels,pattern_types: 1-(set_count-)
             for (s=0;s<=set_count-1;s++){
	        if (get_value(iso_table,s)==1 ){
		  if (get_value(nm[ccindex],group_types[s+1])==0)
		     Hensel_matrix_birth[group_outer_count[s+1]][pattern_labels[pattern_types[s+1]]]=pattern_types[s+1];
		  else if (get_value(nm[ccindex],group_types[s+1])==1)
                     Hensel_matrix_survival[group_outer_count[s+1]][pattern_labels[pattern_types[s+1]]]=pattern_types[s+1];
		}   	       
	     }
	     if (show_details==1){ //show Hensel_matrix for birth and survival
	        fprintf(stderr,"\nHensel Birth\n");
	        for (z=0;z<=8;z++) fprintf(stderr,"%d ",z);
	        fprintf(stderr,"\n");
	        for (zz=0;zz<=14;zz++){
		      for (z=0;z<=8;z++){
			 if (Hensel_matrix_birth[z][zz]==0) fprintf(stderr,"- ");
			 else fprintf(stderr,"%c ",Hensel_matrix_birth[z][zz]);
		      }
		      fprintf(stderr,"\n");
	        }
		
	        fprintf(stderr,"\nHensel Survival\n");
	        for (z=0;z<=8;z++) fprintf(stderr,"%d ",z);		    
	        fprintf(stderr,"\n");
	        for (zz=0;zz<=14;zz++){
		      for (z=0;z<=8;z++){
			 if (Hensel_matrix_survival[z][zz]==0) fprintf(stderr,"- ");
		         else fprintf(stderr,"%c ",Hensel_matrix_survival[z][zz]);
		      }
		      fprintf(stderr,"\n");
	        }
	     }
	     Hsl=0; //Hensel_string_length
             fprintf(stderr,"\nHensel string\n"); 
	     fprintf(stderr,"B");
	     Hensel_string[Hsl]='B';
	     Hsl+=1;
	     for (z=0;z<=8;z++){
		   show_once=0;
	           for (zz=0;zz<=14;zz++){		      
			if (Hensel_matrix_birth[z][zz]>0){
			   if (show_once==0 //*don't repeat 0 ot 8 (46,56 ascii)
			          && Hensel_matrix_birth[z][zz]!=48 &&
			             Hensel_matrix_birth[z][zz]!=56){
			      fprintf(stderr,"%d",z);
                              Hensel_string[Hsl]=(unsigned char)z+'0';
	                      Hsl+=1;
			   }  
			   show_once=1;
			   fprintf(stderr,"%c",Hensel_matrix_birth[z][zz]);
			   Hensel_string[Hsl]=Hensel_matrix_birth[z][zz];
	                   Hsl+=1;
		        }
		   }	
	      }
	      fprintf(stderr,"/S");
	      Hensel_string[Hsl]='/';
	      Hsl+=1;
	      Hensel_string[Hsl]='S';
	      Hsl+=1;
	      for (z=0;z<=8;z++){
		   show_once=0;
	           for (zz=0;zz<=14;zz++){		      
			if (Hensel_matrix_survival[z][zz]>0){
			  if (show_once==0 //*don't repeat 0 ot 8 (46,56 ascii)
			          && Hensel_matrix_survival[z][zz]!=48 &&
			             Hensel_matrix_survival[z][zz]!=56){
			      fprintf(stderr,"%d",z);
			      Hensel_string[Hsl]=(unsigned char)z+'0';
	                      Hsl+=1;
			   }  
			   show_once=1;
			   fprintf(stderr,"%c",Hensel_matrix_survival[z][zz]);
			   Hensel_string[Hsl]=Hensel_matrix_survival[z][zz];
	                   Hsl+=1;
		        }
		   }	
	      }

	     if (show_details==2){ //save or load Hensel notation
	       signed int fid,filebytes;
	       char birth,survival,file_ret,*buff;
		
	           //fprintf(stderr,"\nshow_details==2. Hsl=%d\n",Hsl);
		   Hensel_string[Hsl]='\0';
                   //fprintf(stderr,"%s",Hensel_string);		   

		   draw_prompt_box(1);
		   sprintf(textb[0],"Golly iso-rule: transform-ret, Hensel notation save/load-s/l:");
		   outtext(textb[0]);
		   input_string(1,0);
		   
		   if (is[0]=='s'){		
		      file_ret=select_filename("SAVE","Hensel","*.hen","isoRule");
	              memmove(filename_data,filename,13);
                      fid=myopen(filename_data,1,0);
                      if (file_ret=='q' || fid==-1){
			  file_error(filename_data);
	                  close(fid);
			  goto skip0;
		      }	  
                      save_data(Hensel_string);
		   }
		   else if (is[0]=='l'){
                     unsigned char BSpos,end_string=0,hensel_range[10];
                     signed int ii,jj,digit_found=0,filled_in=0;

	             hensel_range[0]=1; //'0'
	             hensel_range[1]=2;
	             hensel_range[2]=6;
	             hensel_range[3]=10;
	             hensel_range[4]=13;
	             hensel_range[5]=10;
	             hensel_range[6]=6;
	             hensel_range[7]=2;
	             hensel_range[8]=1;
		     
		      file_ret=select_filename("LOAD","Hensel","*.hen","isoRule");
		      fid=myopen(filename,0,0);
                      if (file_ret=='q' || fid==-1 || filelength==0){
                         file_error(filename);//file not found
	                 close(fid);
			 goto skip0;
                      }
		      
                      filebytes= filelength(fid);		      
		      
                      vret=read(fid,Hensel_string,filebytes);
		      //fprintf(stderr,"\n\nloaded=2, vret=%d filebytes=%d\n",vret,filebytes);
                      //fprintf(stderr,"Hensel_string=%s\n",Hensel_string);		      
                      
	              for (zz=0;zz<=14;zz++){ //clear birth and survival matrix
		         for (z=0;z<=8;z++){
			    Hensel_matrix_birth[z][zz]=0;
			    Hensel_matrix_survival[z][zz]=0;
		         }
	              }
		      
		      //it seems for very short files saved in emacs there are 4 extra bytes
		      // e.g. short form of life B3/S23 (lifeS.hen) should have 6 bytes but has 10 bytes
		      //this makes sure the end byte position is correct so lifeS.hen can be loaded
                      fprintf(stderr,"\n"); 
                      for (z=0;z<=filebytes-1;z++){ //find pos of / (forward slash)
			if (Hensel_string[z]=='/') BSpos=z;
			if (isgraph(Hensel_string[z])){ //any printable char
			  //fprintf(stderr," %d=%c ",z,Hensel_string[z]);
			}
			else{
			  //fprintf(stderr," %d: ",z);
			   end_string=z-1;
			   break;
			}
		      }
		      //because for longer strings the above does not work, filebytes is correct
                      if (end_string==0) end_string=filebytes-1;

		      fprintf(stderr,"Hensel_string=");
		      for (z=0;z<=end_string;z++) fprintf(stderr,"%c",Hensel_string[z]);
		      
                      //fprintf(stderr,"\nBSpos=%d end_string=%d", BSpos,end_string);
		      //fprintf(stderr,"\nallocate to matrix: %d..%d %d..%d\n",1,BSpos-1,BSpos+2,end_string);
		      
                      //birth, assign and show, Hensel_matrix_birth
		      assign_Hensel_matrix('b',Hensel_matrix_birth,Hensel_string,hensel_range,
					   labels_array,numbers_array,1,BSpos-1);
		      //survival, assign and show, Hensel_matrix_survival
		      assign_Hensel_matrix('s',Hensel_matrix_survival,Hensel_string,hensel_range,
					   labels_array,numbers_array,BSpos+2,end_string/*filebytes-1*/);
		
		//capara83.c revised here
		for (s=set_count-1;s>=0;s--) set_value(iso_table,s,0); //clear iso-table
		for (zz=tablemax;zz>=0;zz--) set_value(thisrule,zz,0); //clear start of each group

		
		//show Hensel_matrix groups for birth and survival, and set rule-table			
		fprintf(stderr,"\nHensel_group_matrix Birth (loaded)\n");
	        for (z=0;z<=8;z++) fprintf(stderr," %d  ",z);		    
	        fprintf(stderr,"\n");
	        for (zz=0;zz<=14;zz++){
		      for (z=0;z<=8;z++){
			 if (Hensel_matrix_birth[z][zz]==0) fprintf(stderr," -  ");
		         else{
			    fprintf(stderr,"%3d ",Hensel_group_matrix[z][zz]);
                            for (s=1;s<=set_count;s++){
			      if (isotropic_list[s][1]==Hensel_group_matrix[z][zz]){
				 group_size=isotropic_list[s][0];
                                 for (ii=1;ii<=group_size;ii++){
			            set_value(thisrule,isotropic_list[s][ii],1);
	                         }	
		              }
			    }
			 }
		      }
		      fprintf(stderr,"\n");
	        }
                fprintf(stderr,"\nHensel_group_matrix Survival (loaded)\n");
	        for (z=0;z<=8;z++) fprintf(stderr," %d  ",z);		    
	        fprintf(stderr,"\n");
	        for (zz=0;zz<=14;zz++){
		      for (z=0;z<=8;z++){
			 if (Hensel_matrix_survival[z][zz]==0) fprintf(stderr," -  ");
		         else{
			    fprintf(stderr,"%3d ",Hensel_group_matrix[z][zz]+16);
			    for (s=1;s<=set_count;s++){
			      if (isotropic_list[s][1]==Hensel_group_matrix[z][zz]+16){
				 group_size=isotropic_list[s][0];
                                 for (ii=1;ii<=group_size;ii++){
			            set_value(thisrule,isotropic_list[s][ii],1);
	                         }	
		              }
			    } 
			 }
		      }
		      fprintf(stderr,"\n");
	        }
		
	       } //else if (is[0]=='l'){
	     }//if (show_details==2){ //save or load Hensel notation
	    
	     /**************************************************/
	     skip0:
	     
	     for (z=0;z<=8;z++){
	        free(Hensel_matrix_birth[z]);
		free(Hensel_matrix_survival[z]);
		free(Hensel_group_matrix[z]);
             }		
	     free(Hensel_matrix_birth);
	     free(Hensel_matrix_survival);
	     free(Hensel_group_matrix);
	     free(pattern_types);
	     free(Hensel_string);
		  
	  } //end... if (thisnhood==9) ... from set up Hensel notation
	     	     
	 } //ens... if (twod && thisnhood>=2){
	 
         if (thisnhood>=2){
	    free(group_outer_count);
	    free(group_types); 
	    free(iso_table);
         }			 
       } //end... if (do_what<0) end... if ((show_details==1 || show_details==2) && do_what<0){
       
       free(tick_group_pos);
       free(t);
       free(ref_n); 
       free(tick_pos);
       for (z=0;z<=maxR-1;z++) free(xd_n[z]);
       free(xd_n);
       if (thisnhood>=2){
	   for (z=1;z<=set_count;z++){
	     free(isotropic_list[z]);
	   }
	   free(isotropic_list);
           free(temp_group);
	   free(temp_string);
       }
       set_iso_bitflip=1; /*not for iso - changes a set of isotropic values with bit/value flip '1'*/
       //set_iso_input_histogram=1;/*input-histogran according to iso-rule in forx.c*/
}


/****** set Hensel notation for each pattern-type c,e,k,a,i,n,q,j,r,t,w,z Nov2017 *************/
void iso_Hensel_setup(signed int set_count,signed int ccindex,
	     signed int *group_types, unsigned char *pattern_types, signed int **Hensel_group_matrix){
  
             signed int s, temp=0;        
	   
	     /*fprintf(stderr,
	       "\n%d groups-types and Hensel notation pattern-types: c,e,k,a,i,n,q,j,r,t,w,z:\n",
	                           set_count);*/
	     /* dec values of binary k=9 square
           256 128  64
            32  16   8
	     4   2   1 */
	     
	     for (s=set_count;s>=1;s--){
	       //fprintf(stderr,"%d:%d:",s,group_types[s]);
	       temp=group_types[s]; //pattern should be the lowest dec equivalent, 16 is the center
	       
               /*              /  \ /   |     |     |/
                    1    2    3    4   -5-   -6-   -7-    
		     \  / \  / \  / \   |\   /|\   /|\  */
	          if (   temp==1 || temp==(1+16) //1 outer:1,17
		   || temp==(1+4) || temp==(1+4+16) //2 outers:5,21
		   || temp==(1+4+64) || temp==(1+4+64+16) //3 outers:69,85
		   || temp==(1+4+64+256) || temp==(1+4+64+256+16) //4 outers:325,342
		   || temp==(1+2+8+32+128) || temp==(1+2+8+32+128+16) //5 outers:171,187
		   || temp==(1+2+4+8+32+128) || temp==(1+2+4+8+32+128+16) //6 outers:175,191
		   || temp==(1+2+4+8+32+64+128) || temp==(1+2+4+8+32+64+128+16)){ //7 outers:239,255
		      pattern_types[s]='c'; //ascii c=99
	              //fprintf(stderr,"%d:%d=%c ",s,group_types[s],pattern_types[s]);
		      Hensel_group_matrix[1][1]=1; //Hensel_group_matrix[size=cols][type=rows]
                      Hensel_group_matrix[2][1]=5;
		      Hensel_group_matrix[3][1]=69;
                      Hensel_group_matrix[4][1]=325;
		      Hensel_group_matrix[5][1]=171;
		      Hensel_group_matrix[6][1]=175;
                      Hensel_group_matrix[7][1]=239;
		  }

                  /*                  |   \ /   \ /    \ /
                       1    2-  -3-  -4-   5     6-    -7-    
		       |    |    |    |   /|\   /|\    /|\  */	       
		  else if (
		      temp==2 || temp==(2+16) //1 outer:2,18
		   || temp==(2+8) || temp==(2+8+16) //2 outers:10,26
		   || temp==(2+8+32) || temp==(2+8+32+16) //3 outers:42,58
		   || temp==(2+8+32+128) || temp==(2+8+32+128+16) //4 outers:170,186
		   || temp==(1+2+4+64+256) || temp==(1+2+4+64+256+16) //5 outers:327,343
		   || temp==(1+2+4+8+64+256) || temp==(1+2+4+8+64+256+16) //6 outers:335,351
		   || temp==(1+2+4+8+32+64+256) || temp==(1+2+4+8+32+64+256+16)) {//7 outers:367,383		 
		      pattern_types[s]='e'; //ascii e=101
	              //fprintf(stderr,"%d:%d=%c ",s,group_types[s],pattern_types[s]);
		      Hensel_group_matrix[1][2]=2; //Hensel_group_matrix[size=cols][type=rows]
                      Hensel_group_matrix[2][2]=10;
		      Hensel_group_matrix[3][2]=42;
                      Hensel_group_matrix[4][2]=170;
		      Hensel_group_matrix[5][2]=327;
		      Hensel_group_matrix[6][2]=335;
                      Hensel_group_matrix[7][2]=367;
		  }
	       
                  /*          /    /    |/   |/
                        2-  -3   -4    -5   -6
	               /     |    |\   / \  /|\  */
		  else if (
		      temp==(4+8) || temp==(4+8+16) //2 outers:12,28
		   || temp==(2+32+64) || temp==(2+32+64+16) //3 outers:98,114
		   || temp==(1+2+32+64) || temp==(1+2+32+64+16) //4 outers:99,115
		   || temp==(1+4+32+64+128) || temp==(1+4+32+64+128+16) //5 outers:229,245
		   || temp==(1+2+4+32+64+128) || temp==(1+2+4+32+64+128+16)) { //6 outers:231,247
		 
		      pattern_types[s]='k'; //ascii k=107
	              //fprintf(stderr,"%d:%d=%c ",s,group_types[s],pattern_types[s]);
		      Hensel_group_matrix[2][3]=12; //Hensel_group_matrix[size=cols][type=rows]
		      Hensel_group_matrix[3][3]=98;
                      Hensel_group_matrix[4][3]=99;
		      Hensel_group_matrix[5][3]=229;
		      Hensel_group_matrix[6][3]=231;
                 }
	       
		 /*                /     /
                 /     2    3-    4-   5-   -6-
		 /     |\   |\   /|\  /|\   /|\ */
		  else if (
		      temp==(1+2) || temp==(1+2+16) //2 outers:3,19
		   || temp==(1+2+8) || temp==(1+2+8+16) //3 outers:11,27
		   || temp==(1+2+4+8) || temp==(1+2+4+8+16) //4 outers:15,31
		   || temp==(1+2+4+8+64) || temp==(1+2+4+8+64+16) //5 outers:79,95
		   || temp==(1+2+4+8+32+64) || temp==(1+2+4+8+32+64+16) ) { //6 outers:111,127		 
		      pattern_types[s]='a'; //ascii a=97
	              //fprintf(stderr,"%d:%d=%c ",s,group_types[s],pattern_types[s]);
		      Hensel_group_matrix[2][4]=3; //Hensel_group_matrix[size=cols][type=rows]
		      Hensel_group_matrix[3][4]=11;
                      Hensel_group_matrix[4][4]=15;
		      Hensel_group_matrix[5][4]=79;
		      Hensel_group_matrix[6][4]=111;
		  }

                  /*                          \ /
                       -2-    3    -4-  -5-   -6-
		             /|\   / \  /|\   / \   */
		  else if (
		      temp==(8+32) || temp==(8+32+16) //2 outers:40,56
		   || temp==(1+2+4) || temp==(1+2+4+16) //3 outers:7,23
		   || temp==(1+4+8+32) || temp==(1+4+8+32+16) //4 outers:45,61
		   || temp==(1+2+4+8+32) || temp==(1+2+4+8+32+16) //5 outers:47,63
		   || temp==(1+4+8+32+64+256) || temp==(1+4+8+32+64+256+16) ) { //6 outers:365,381		 
		      pattern_types[s]='i'; //ascii i=105
	              //fprintf(stderr,"%d:%d=%c ",s,group_types[s],pattern_types[s]);
		      Hensel_group_matrix[2][5]=40; //Hensel_group_matrix[size=cols][type=rows]
		      Hensel_group_matrix[3][5]=7;
                      Hensel_group_matrix[4][5]=45;
		      Hensel_group_matrix[5][5]=47;
		      Hensel_group_matrix[6][5]=365;
		  }

                  /*     /           /    /    |/           
		  /     2    3-     4   -5-   -6-
		  /    /    / \    /|\   |\   /|   */ 
		  else if (
		      temp==(4+64) || temp==(4+64+16) //2 outers:68,84
		   || temp==(1+4+8) || temp==(1+4+8+16) //3 outers:13,29
		   || temp==(1+2+4+64) || temp==(1+2+4+64+16) //4 outers:71,87
		   || temp==(1+2+8+32+64) || temp==(1+2+8+32+64+16) //5 outers:107,123
		   || temp==(2+4+8+32+64+128) || temp==(2+4+8+32+64+128+16) ) { //6 outers:238,254		 
		      pattern_types[s]='n'; //ascii n=110
	              //fprintf(stderr,"%d:%d=%c ",s,group_types[s],pattern_types[s]);
		      Hensel_group_matrix[2][6]=68; //Hensel_group_matrix[size=cols][type=rows]
		      Hensel_group_matrix[3][6]=13;
                      Hensel_group_matrix[4][6]=71;
		      Hensel_group_matrix[5][6]=107;
		      Hensel_group_matrix[6][6]=238;
		 }

		 /*      /      /    |                
		       -3     -4    -5-  
		         \    / \   / \  */
		  else if (		     
		   temp==(1+32+64) || temp==(1+32+64+16) //3 outers:97,113
		   || temp==(1+4+32+64) || temp==(1+4+32+64+16) //4 outers:101,117
		   || temp==(1+4+8+32+128) || temp==(1+4+8+32+128+16) ) { //5 outers:173,189		 
		      pattern_types[s]='y'; //ascii y=121
	              //fprintf(stderr,"%d:%d=%c ",s,group_types[s],pattern_types[s]);
		      Hensel_group_matrix[3][7]=97; //Hensel_group_matrix[size=cols][type=rows]
                      Hensel_group_matrix[4][7]=101;
		      Hensel_group_matrix[5][7]=173;
		 }

		 /*      /      /     /                
		        3     -4    -5-  
	               /|     /|    /|  */ 
		 else if (		     
		   temp==(2+4+64) || temp==(2+4+64+16) //3 outers:70,86
		   || temp==(2+4+32+64) || temp==(2+4+32+64+16) //4 outers:102,118
		   || temp==(2+4+8+32+64) || temp==(2+4+8+32+64+16) ) { //5 outers:110,126		 
		      pattern_types[s]='q'; //ascii q=113
	              //fprintf(stderr,"%d:%d=%c ",s,group_types[s],pattern_types[s]);
		      Hensel_group_matrix[3][8]=70; //Hensel_group_matrix[size=cols][type=rows]
                      Hensel_group_matrix[4][8]=102;
		      Hensel_group_matrix[5][8]=110;
		 }

		 /*              /     /                
		         3-    -4-   -5  
			/|      |    /|\  */
		 else if (		     
		   temp==(2+4+8) || temp==(2+4+8+16) //3 outers:14,30
		   || temp==(2+8+32+64) || temp==(2+8+32+64+16) //4 outers:106,122
		   || temp==(1+2+4+32+64) || temp==(1+2+4+32+64+16) ) { //5 outers:103,119		 
		      pattern_types[s]='j'; //ascii j=106
	              //fprintf(stderr,"%d:%d=%c ",s,group_types[s],pattern_types[s]);
		      Hensel_group_matrix[3][9]=14; //Hensel_group_matrix[size=cols][type=rows]
                      Hensel_group_matrix[4][9]=106;
		      Hensel_group_matrix[5][9]=103;
		 }

		 /*                   /                
		       -3-    -4-   -5-  
		         \     |\   / \  */
		 else if (		     
		   temp==(1+8+32) || temp==(1+8+32+16) //3 outers:41,57
		   || temp==(1+2+8+32) || temp==(1+2+8+32+16) //4 outers:43,59
		   || temp==(1+4+8+32+64) || temp==(1+4+8+32+64+16) ) { //5 outers:109,125		 
		      pattern_types[s]='r'; //ascii r=114
	              //fprintf(stderr,"%d:%d=%c ",s,group_types[s],pattern_types[s]);
		      Hensel_group_matrix[3][10]=41; //Hensel_group_matrix[size=cols][type=rows]
                      Hensel_group_matrix[4][10]=43;
		      Hensel_group_matrix[5][10]=109;
		 }
 
		 /*           /                     
		            -4-   
			      \   */
	         else if (		     
		     temp==(1+8+32+64) || temp==(1+8+32+64+16) ) { //4 outers:105,121		 
		      pattern_types[s]='t'; //ascii t=116
	              //fprintf(stderr,"%d:%d=%c ",s,group_types[s],pattern_types[s]);
		      Hensel_group_matrix[4][11]=105; //Hensel_group_matrix[size=cols][type=rows]
                 }
		  
		 /*           /                     
		             4-   
		            /|   */
	        else if (		     
		     temp==(2+4+8+64) || temp==(2+4+8+64+16) ) {//4 outers:78,94		 
		      pattern_types[s]='w'; //ascii w=119
	              //fprintf(stderr,"%d:%d=%c ",s,group_types[s],pattern_types[s]);
		      Hensel_group_matrix[4][12]=78; //Hensel_group_matrix[size=cols][type=rows]
                 }
		  
		 /*           /                     
		            -4-   
		            /    */
	         else if (		     
		     temp==(4+8+32+64) || temp==(4+8+32+64+16) ) {//4 outers:108,124		 
		      pattern_types[s]='z'; //ascii z=122
	              //fprintf(stderr,"%d:%d=%c ",s,group_types[s],pattern_types[s]);
		       Hensel_group_matrix[4][13]=108; //Hensel_group_matrix[size=cols][type=rows]
                 }

		  /*         \|/                     
		             -8-   
		             /|\   */
	         else if (		     
		     temp==(1+2+4+8+32+64+128+256) || temp==(1+2+4+8+32+64+128+256+16) ) {//8outers:495,511 
		      pattern_types[s]=8+'0'; //ascii 8=56
	              //fprintf(stderr,"%d:%d=%c ",s,group_types[s],pattern_types[s]);
		      Hensel_group_matrix[8][14]=495; //Hensel_group_matrix[size=cols][type=rows]
                 }
		  
                 /*                         
		             0
		                  */
	         else if (		     
		     temp==(0) || temp==(0+16) ) {//0outers:0,16		 
		      pattern_types[s]=0+'0'; //ascii 0=48
	              //fprintf(stderr,"%d:%d=%c ",s,group_types[s],pattern_types[s]);
		      Hensel_group_matrix[0][0]=0; //Hensel_group_matrix[size=cols][type=rows]
                 }
	       
	     }
}

/**************************************** 16 Nov 2017 ******************************************/
void assign_Hensel_matrix(char birth_survival,
		    unsigned char **birth_or_survival_matrix,unsigned char *Hensel_string,
		    unsigned char hensel_range[10],unsigned char labels_array[15],
			  unsigned char numbers_array[10],unsigned char start_pos,unsigned char end_pos){  
  unsigned int z,zz,jj,ii,digit_found=0,filled_in=0;

        //assign to Hensel_matrix_birth[z][zz] or Hensel_matrix_survival[z][zz]
        //fprintf(stderr,"\n%d...%d\n",start_pos,end_pos);
  
              for (z=start_pos;z<=end_pos;z++){
		        //fprintf(stderr,"z=%d (%c) ",z,Hensel_string[z]); 
		        //assign 0 and 8 if pressent
                        if (Hensel_string[z]=='0') birth_or_survival_matrix[0][0]='0';
			if (Hensel_string[z]=='8') birth_or_survival_matrix[8][14]='8';

                        for (jj=1;jj<=7;jj++){
			    //fprintf(stderr,"jj=%d ",jj); 
			    digit_found=0;
			    filled_in=0;
			    if (Hensel_string[z]==numbers_array[jj]){ //if the current item is a number 1 to 7
			       //fprintf(stderr," %c==%c ",Hensel_string[z],numbers_array[jj]); 
			       filled_in=0;
			       for (zz=1; zz<=hensel_range[jj]; zz++){ //'c','e', 'k','a','i','n','y','q','j','r','t','w','z'
				 
				 if ( isdigit(Hensel_string[z+1]) //if next item is not an alpha
				      || (isdigit(Hensel_string[z]) && z==end_pos) ) {
				       //fprintf(stderr," zz=%d ",zz); 
				       //fill the birth_or_survival_matrix with all possible labels
                                       for (ii=1; ii<=hensel_range[jj]; ii++){ //fill the birth_or_survival_matrix
				                 birth_or_survival_matrix[jj][ii]=labels_array[ii];
				       } 
				       digit_found=1;
				       break;
				  }
				  //if next item is a "minus"  
				  else if (Hensel_string[z+1]=='-'){
				     //fill the birth_or_survival_matrix with all possible labels
				    if (filled_in==0){ //but do this just once
				        for (ii=1; ii<=hensel_range[jj]; ii++){ //fill the birth_or_survival_matrix
				                 birth_or_survival_matrix[jj][ii]=labels_array[ii];
				        }
				        filled_in=1;
				    }
				    if (isdigit(Hensel_string[z+zz+1])){
				        digit_found=1;
				        break;
				    }
				    else{
                                       for (ii=1; ii<=hensel_range[jj]; ii++){
					 //fprintf(stderr," %c=%c",Hensel_string[z+zz+1],labels_array[ii]);
					  if (Hensel_string[z+zz+1]==labels_array[ii]){ //for labels following "minus"
					           birth_or_survival_matrix[jj][ii]=0; //set matrix to zero
					           //fprintf(stderr," %dx%d -%c-",jj,ii,birth_or_survival_matrix[jj][ii]);
					  }
				        }
				    }
				  }
				  else if (isdigit(Hensel_string[z+zz])){
				     //fprintf(stderr," l=6757 ");
				     digit_found=1;
				     break;
			          }
			          else{
				     //fprintf(stderr," l=6762 ");
				     for (ii=1; ii<=hensel_range[jj]; ii++){
				        if (Hensel_string[z+zz]==labels_array[ii])
				                 birth_or_survival_matrix[jj][ii]=labels_array[ii];
				     }
                                  }
			       }
			   }
			   if (digit_found==1) break;
			}
			 
	      }
	      //show Hensel_matrix alpha-numeric for birth and survival			
	      if (birth_survival=='b') fprintf(stderr,"\nHensel Birth (loaded)\n");
	      else if (birth_survival=='s') fprintf(stderr,"\nHensel Survival (loaded)\n");
	      
	      for (z=0;z<=8;z++) fprintf(stderr,"%d ",z);
	      fprintf(stderr,"\n");
	      for (zz=0;zz<=14;zz++){
		      for (z=0;z<=8;z++){
			 if (birth_or_survival_matrix[z][zz]==0) fprintf(stderr,"- ");
			 else fprintf(stderr,"%c ",birth_or_survival_matrix[z][zz]);
		      }
		      fprintf(stderr,"\n");
	      }	      
	      
}
/******* rcode only convert k-rule to equivalent >k-rule, and other rule transformations *********/
/*either a single cell or whole network ("block" from wiring prompt not implimented)*/
char transform_rule(unsigned int cellindex){
 signed int tablemax,tablebytes,
              tablecodemax,codebytes,
              mtablebytes,mtablemax,
              xbox,z,zz,temp,wire;
 char k_changed=0, max_k,bit, *catemp,*nhoodtemp,
      final_nhood,gnhood,startnhood,dontmesswith_k=0;
 unsigned int poss,startloop,maxloop;
 unsigned long rule_dec_max;

 /*----------------------------------------------------------*/
 /*NOTE: transform kcode -> rule -> rule_k+ ok for rule
                   rule k+ -> kcode k+, kcode and kcode k+ not equiv
         i.e. equiv rule does not translate to equiv kcode*/

#define rulechanged\
  if (rulemix==0){\
     if (totalistic==1) code2rule(carule[0],cacode[0],nhoodm[0]);\
     else if (totalistic==2)\
        v_code2rule(carule[0],v_code[0],nhoodm[0],0);\
  }\
  show_rule_bottom(nhoodm[cellindex],1,carule[cellindex],0);\
  if (rulemix==0){\
     if (tot_only==0){\
        char temptot;\
         temptot=totalistic;\
         totalistic=0;\
         save_last_rule(carule[0],nhoodm[0]);\
         totalistic=temptot;\
     }\
     if (totalistic==1) save_last_rule(cacode[0],nhoodm[0]);\
     else if (totalistic==2) save_last_rule(v_code[0],nhoodm[0]);\
  }\

  setcolor(white);

  if (secondpart && direction=='f' && limitcheck==0) dontmesswith_k=1;
  /*transform k at the start, or if running basins. Don't mess with k
      if running space-time patterns because lookup entropy etc makes it
      too complicated*/
  filedata=0;
  if (nhood_mixed) max_k=nhood;
  else max_k=Maxnhood;
 
  start:
     setcolor(white);
     /*there must be a k-mix to change the k of just one rule*/
    if (rulemix) sprintf(textb[0],
       "transform rcode: invert-v solid-o comp-m neg-n ref-r canal-C (all+a)");
    else sprintf(textb[0],
     "transform rcode: invert-v solid-o comp-m neg-n ref-r canal-C ");
#   if __WATCOM__
       if (totalistic==1) sprintf(textb[5],"save: rcode/tcode-s/S ");
       else if (totalistic==2) sprintf(textb[5],"save: rcode/kcode-s/S ");
       else sprintf(textb[5],"save rcode-s ");
#   elif __UNIX__
       if (totalistic==1) sprintf(textb[5],
                     "save/prtx: rcode/tcode-s/S/x/X ");
       else if (totalistic==2) sprintf(textb[5],
                                  "save/prtx: rcode/kcode-s/S/x/X ");
       else sprintf(textb[5],"save/prtx: rcode-s/x ");
       
#   endif

    if (rulemix && !nhood_mixed) sprintf(textb[1],"%s",textb[5]);
    else if (dontmesswith_k==1) sprintf(textb[1],"");        
    else{ 
       if (rulemix) sprintf(textb[2],": all-K this-k");
       else sprintf(textb[2],"-k");

       if (nhood_mixed && value_range==2) sprintf(textb[3]," max k-M, ");
       else sprintf(textb[3]," ");

       if (nhoodm[cellindex]<max_k) 
             sprintf(textb[4],"equiv>k(%d): (%d-%d), ", 
                          nhoodm[cellindex],nhoodm[cellindex]+1,max_k);
       else if (nhoodm[cellindex]==max_k) 
             sprintf(textb[4],"k(%d)=max, ",max_k);
       if (nhoodm[cellindex]<=max_k-1) sprintf(textb[1],
	  "%s %seff k%s", textb[4],textb[3],textb[2]);
       
       else sprintf(textb[1],"%seff k%s",textb[3],textb[2]);
    }
    if (nhood_mixed && nhood==lineL && lineL<=31 && value_range==2)
                                sprintf(textb[3],"exh map-e, ");

    tablemax= (signed int)pow(value_range,(double)nhoodm[cellindex])-1;
    tablebytes=(signed int)ceil(value_bits * (double)(tablemax+1)/8);
    if (totalistic==1) /*max index of tcode table*/
       tablecodemax=nhoodm[cellindex]*(value_range-1); 
    else if (totalistic==2) 
             tablecodemax=v_tablecodemax[nhoodm[cellindex]]; 
    codebytes=(signed int) /*bytes for tcode, kcode, min=1*/
             ceil(value_bits * (double)(tablecodemax+1)/8);

    /*for equiv-rules and clusters, for binary v=2 only*/
    rule_dec_max=max_dec_rule(tablemax,value_range);
    //fprintf(stderr,"\nrule_dec_max=%lu ",rule_dec_max);
    /*if too big, out of dec range, rule_dec_max=0*/       
     

    if (rulemix && !nhood_mixed){
        xbox=draw_prompt_box(3);
        outtext(textb[0]);
        moveto(xbox,gety+CHeight);
        outtext(textb[1]);
    }
    else{
        xbox=draw_prompt_box(3);
        outtext(textb[0]);
        moveto(xbox,gety+CHeight);
        if (nhood_mixed && nhood==lineL) outtext(textb[3]);
        outtext(textb[1]);
        moveto(xbox,gety+CHeight);
        outtext(textb[5]);
    }
    outtext(" EquivClass-E RuleCluster-R:");/*new option Jan2013*/
    input_string(2,0);
    erase_prompt_box(3);
 
    if (is[0]=='q' || is[0]==13){
        setcolor(white);
        return(k_changed);
    }
    else if (is[0]=='e'){ /*load exhaustive pairs if max_nhood=L (fully connected) */
       unsigned long state_space,prestate;
       /*does not work for value_range>=3 -- to be resolved*/
       if (!nhood_mixed || nhood!=lineL || lineL>31 || value_range>=3) goto start;

       tablemax= (signed int)pow(value_range,(double)nhood)-1;
              
       /*load exhaustive map and assign rules accordingly*/
       /*memory for exhaustive pairs, index=prestate,
                             char array=successor state*/
       state_space=(unsigned long)(pow(value_range,(double)lineL));
       if ((exh_pairs=(char*)calloc(state_space*bytesL,sizeof(char)))
				      ==NULL) outof_memory("exh_pairs");
       
       load_save_exhaustive('l');/*this is correct, for v=2 and for v>=3*/

       /*fprintf(stderr,"\nload_exhaustive\n");
       for (prestate=0;prestate<=state_space-1;prestate++){
          memmove(F,exh_pairs+prestate*bytesL,bytesL);
          fprintf(stderr,"\n %lu",prestate);
          fprintf(stderr," %lu",dec_equiv(F,L));
       }*/


       /*rewire consecutively*/
       for (poss=0;poss<=lineL-1;poss++){
           nhoodm[poss]=nhood;
           for (z=0;z<=nhood-1;z++) wiring[poss][z]=z;
	       /*oneD_local_wire_cell(poss,lineL-1);*/
       }
       /*set the rule from exh_pairs*/
       for (poss=0;poss<=lineL-1;poss++){
	  fprintf(stderr,"\n");         
	  for (zz=0;zz<=tablemax;zz++){
              if (value_range==2){ 
                  set_bit(carule[poss],zz,
		    get_bit(exh_pairs,zz*bytesL*8+poss));
              } 
              else{ /*something wrong here*/
                  set_value(carule[poss],zz, 
			     get_value(exh_pairs,zz*bytesL*8+poss));
                  fprintf(stderr,"%d ",get_value(exh_pairs,zz*bytesL*8+poss));
	      }              
          }           	 
       } 

       free(exh_pairs);
       nhood_lb_ub();
       cell_out_freq();
       rulechanged;
    }
    else if (is[0]=='s'){ /*save the rule*/
      char temp_totalistic;
       temp_totalistic=totalistic;
       totalistic=0;
       load_save_wrs('s',carule[cellindex],0);
       totalistic=temp_totalistic;
       goto start;
    }
    else if (is[0]=='S'){ /*save t_code or v_code*/      
       if (totalistic==1) load_save_wrs('s',cacode[cellindex],0);
       else if (totalistic==2) load_save_wrs('s',v_code[cellindex],0);
       goto start;
    }
    else if (is[0]=='x' || is[0]=='X'){ 
       /*print the index, code and table to the terminal*/ 
#      if __UNIX__
          if (totalistic==1 && is[0]=='X'){
             fprintf(stderr,"\n");
             for (z=tablecodemax;z>=0;z--)
	          fprintf(stderr,"%d",get_value(cacode[cellindex],z));
	  }
          else if (totalistic==2 && is[0]=='X'){
	     fprintf(stderr,"\n");
             for (z=tablecodemax;z>=0;z--)
	          fprintf(stderr,"%d",get_value(v_code[cellindex],z));
          }
          else if (is[0]=='x' && tot_only==0){
	     fprintf(stderr,"\n");
             for (z=tablemax;z>=0;z--)
	          fprintf(stderr,"%d",get_value(carule[cellindex],z));
          }
#      endif
       goto start;
    }
    /*canalyzing*/
    else if (is[0]=='C'){
       if (rulemix){
          if (is[1]=='a') 
            set_canalyzing_net(0);/*all cells, dont force null nhood->0*/
          else set_canalyzing_rule(cellindex); /*just one cell*/
       }
       else set_canalyzing_rule(cellindex); /*just one cell*/
       rulechanged;     
    }

    /*change to solidifying rule - binary: value 1 cell stays on
                                   v>=3: max-value cell stays on*/
    else if (is[0]=='o'){
        if (rulemix && is[1]=='a'){
            startloop=0;
            maxloop=lineL-1;       
       }
       else startloop=maxloop=cellindex;
       for (poss=startloop;poss<=maxloop;poss++){
          if (nhood_mixed){
	     mtablemax= (signed int)
                      pow(value_range,(double)nhoodm[poss])-1;
	     mtablebytes=(signed int)
                      ceil(value_bits * (double)(mtablemax+1)/8);
	  }
	  else{
		mtablemax=tablemax;
		mtablebytes=tablebytes;
	  }	
          for (z=0;z<=mtablemax;z++){
	     if  (value_range==2){
	        if (get_bit(carule[poss],z)==1) continue;
	        else if (get_bit(nm[nhoodm[poss]/2],z)==1)
		      set_bit(carule[poss],z,1);
             }
	     else{ /* seems to work */
                if (get_value(carule[poss],z)==value_range-1) continue;
	        else if (get_value(nm[nhoodm[poss]/2],z)==value_range-1)
		      set_value(carule[poss],z,value_range-1);
             }
          }
       }
       rulechanged;
       goto start; //added
    }
    
    /*invert transformation*/
    else if (is[0]=='v'){
       if ((catemp=(char *)calloc(tablebytes,sizeof(char)))
				    ==NULL) outof_memory("catemp");
       if (rulemix && is[1]=='a'){
            startloop=0;
            maxloop=lineL-1;       
       }
       else startloop=maxloop=cellindex;
       for (poss=startloop;poss<=maxloop;poss++){
          if (nhood_mixed){
                mtablemax= (signed int)pow(value_range,(double)nhood)-1;
                mtablebytes=(signed int)
                               ceil(value_bits *(double)(mtablemax+1)/8);
	  }
	  else{
		mtablemax=tablemax;
		mtablebytes=tablebytes;
	  }	
          for (z=0;z<=mtablemax;z++){
             if (value_range==2){ 
                set_bit(catemp,mtablemax-z,get_bit(carule[poss],z));
             }
             else set_value(catemp,mtablemax-z,get_value(carule[poss],z));
          }
          memmove(carule[poss],catemp,mtablebytes);
          
       }	  
       free(catemp);                    
       rulechanged;
       goto start; //added
    }

    /*print Equivelent rules (and complimentary) to xterm -- i.e. rule cluster*/
    else if (is[0]=='E' || is[0]=='R'){
      char *catemp,xnhood,temp_pdata,rule_type;
      unsigned long ruledec;

#      define print_rule {\
          ruledec=dec_equiv(catemp,mtablemax);\
          if (rule_dec_max>0 && xnhood<=3 && value_range==2){\
             fprintf(stderr,"%lu",ruledec);\
          }\
          else if (rule_dec_max>0 && xnhood<=5 && rule_type==2 && value_range==2)\
                  fprintf(stderr,"%lu ",ruledec);\
          else{\
	     print_current_bitstring_hexbytes(0,rule_type,catemp,xnhood,32,white,3);\
          }\
       }

       xnhood=nhoodm[cellindex];
       //mtablemax= (signed int) pow(value_range,(double)xnhood)-1;
       //mtablebytes=(signed int) ceil(value_bits * (double)(mtablemax+1)/8);

       if (tot_only==0 && totalistic==0){
	  rule_type=1; //rcode
          mtablemax= (signed int)pow(value_range,(double)xnhood)-1;/*rcode*/
       }
       else{ //not rcode
          rule_type=2; //tcode or kcode
	  if (totalistic==1)
             mtablemax=xnhood*(value_range-1);//tcode, totalistic=1
	  else if (totalistic==2) 
             mtablemax=v_tablecodemax[xnhood];//kcode, totalistic=2
       }
       mtablebytes=(signed int) ceil(value_bits * (double)(mtablemax+1)/8);


       if ((catemp=(char *)calloc(mtablebytes,sizeof(char)))
				    ==NULL) outof_memory("catemp");
       if  (totalistic==0) memmove(catemp,carule[cellindex],mtablebytes);
       else if (totalistic==1) memmove(catemp,cacode[cellindex],mtablebytes);
       else if (totalistic==2) memmove(catemp,v_code[cellindex],mtablebytes);

       temp_pdata=pdata; 
       pdata=1; /*to allow printing hex to xterm*/
    redo_complementary:
       fprintf(stderr,"\ns=");      
       /*start rule*/
       print_rule;
       /*n=negative_transformation*/
       negative_transformation(catemp,mtablebytes,mtablemax);/*neg*/
       fprintf(stderr," n=");
       print_rule;
       if (totalistic==0){
          /*r=reflection_transformation -- first revert to start rule*/
          negative_transformation(catemp,mtablebytes,mtablemax);/*back*/
          reflection_transformation(catemp,xnhood,mtablebytes,mtablemax);/*ref*/
          fprintf(stderr," r=");
          print_rule;
          /*nr=negative-reflection -- keep reflection above, make negative*/
          negative_transformation(catemp,mtablebytes,mtablemax);/*neg of ref*/
          ruledec=dec_equiv(catemp,(signed int)pow(value_range,(float)xnhood)-1);
          fprintf(stderr," nr=");
          print_rule;
       }
       if (is[0]=='R'){
          if  (totalistic==0) memmove(catemp,carule[cellindex],mtablebytes);
          else if (totalistic==1) memmove(catemp,cacode[cellindex],mtablebytes);
          else if (totalistic==2) memmove(catemp,v_code[cellindex],mtablebytes);
          complementary_transformation(catemp,mtablebytes,mtablemax);
          is[0]='E';
          goto redo_complementary;
       }
       pdata=temp_pdata;       
       free(catemp);
       goto start;  
    }
       
    /*complementary transformation*/    
    else if (is[0]=='m'){
       if (rulemix && is[1]=='a'){
            startloop=0;
            maxloop=lineL-1;       
       }
       else startloop=maxloop=cellindex;
       for (poss=startloop;poss<=maxloop;poss++){
      	  if (nhood_mixed){
                mtablemax= (signed int)pow(value_range,(double)nhood)-1;
                mtablebytes=(signed int)
                                ceil(value_bits *(double)(mtablemax+1)/8);
	  }
	  else{
		mtablemax=tablemax;
		mtablebytes=tablebytes;
	  }
	  complementary_transformation(carule[poss],mtablebytes,mtablemax);
       }
       rulechanged;
       goto start; //added
    }
    /*negative transformation*/
    else if (is[0]=='n'){
       if (rulemix && is[1]=='a'){
            startloop=0;
            maxloop=lineL-1;       
       }
       else startloop=maxloop=cellindex;
       for (poss=startloop;poss<=maxloop;poss++){
          if (nhood_mixed){
                mtablemax= (signed int)pow(value_range,(double)nhood)-1;
                mtablebytes=(signed int)
                       ceil(value_bits * (double)(tablemax+1)/8);
	  }
	  else{
		mtablemax=tablemax;
		mtablebytes=tablebytes;
	  }
          negative_transformation(carule[poss],tablebytes,tablemax);          
       }                 
       rulechanged;
       goto start; //added
    }

    /*reflection transformation*/
    else if (is[0]=='r'){
       if (rulemix && is[1]=='a'){
            startloop=0;
            maxloop=lineL-1; 
       }
       else startloop=maxloop=cellindex;
       for (poss=startloop;poss<=maxloop;poss++){
          if (nhood_mixed){
              mtablemax= (signed int)pow(value_range,(double)nhood)-1;
              mtablebytes=
                   (signed int)ceil(value_bits *(double)(tablemax+1)/8);
	  }
	  else{
	      mtablemax=tablemax;
	      mtablebytes=tablebytes;
	  }
	
          /*swap outputs of pairs of (asymmetric) reflected nhoods*/
          reflection_transformation(carule[poss],nhoodm[poss],
				                 mtablebytes,mtablemax); 
       }
       rulechanged;
        goto start; //added
    }

    else if (is[0]=='M' && nhood_mixed){
        reduce_max_k();
        goto start;         
    }

    /*------------ reduce to effective k --------------------------*/
    /*do this only at start, or if basin, not running forward*/
    else if ((is[0]=='k' || is[0]=='K') && dontmesswith_k==0){
       char k,*i_active,outpt,maxk;
       char effective_found;
       signed int i,j,zv;
       unsigned int element; 

       if (!rulemix) is[0]='k'; /*just element 0*/
       if ((nhoodtemp=(char *)calloc(2,sizeof(char)))
				    ==NULL) outof_memory("nhoodtemp");
       if ((i_active=(char *)calloc(14,sizeof(char)))
				    ==NULL) outof_memory("i_active");
       for (element=0;element<=lineL-1;element++){
          if (is[0]=='K') cellindex=element; /*whole network*/
          k= nhoodm[cellindex];

          tablemax= (signed int)pow(value_range,(double)k)-1;
	  tablebytes=(signed int)ceil(value_bits * (double)(tablemax+1)/8);

          effective_found=0;      
          for (i=k-1;i>=0;i--){
             i_active[i]=0;
             for (z=tablemax;z>=0;z--){
	        if (value_range==2){ 
                   dec_to_bit_line(nhoodtemp,(unsigned long)z,k);
                   /*flip bit i*/
                   set_bit(nhoodtemp,i,abs(get_bit(nhoodtemp,i))-1 );
                   poss=(unsigned int) dec_equiv(nhoodtemp,k-1);
                   /*compare same pairs with i-th bit opposite*/
                   if (get_bit(carule[cellindex],z) !=
		                    get_bit(carule[cellindex],poss)){
                      i_active[i]=1;
                      continue;	         
                   }
	        }
                else{ /*multi-value*/
                   dec_to_value_line(nhoodtemp,(unsigned long)z,k);
                   /*try diff values at pos i*/
                   for (zv=0;zv<=value_range-1;zv++){
		      set_value(nhoodtemp,i,zv);
                      poss=(unsigned int) dec_equiv(nhoodtemp,k-1);
                      /*compare same pairs with i-th value opposite*/
                      if (get_value(carule[cellindex],z) !=
		                    get_value(carule[cellindex],poss)){
                         i_active[i]=1;
                         break;
                      }
                      if (i_active[i]==1) continue;	         
                   }
                }                                   
             }
             if (i_active[i]==0){ 
		effective_found=1;
                k_changed=1;
	     } 
          }
	  
/*#         if __UNIX__
             if (effective_found){
                fprintf(stderr,"\nci=%d, inactive wires=",cellindex);
                for (z=k-1;z>=0;z--){
                   if (i_active[z]==0) fprintf(stderr,"%d,", z);
                }   
                fprintf(stderr,"\n");
             }
#         endif*/
	  
          maxk=k-1;
          tablemax= (signed int)pow(value_range,(double)k)-1;
	  tablebytes=(signed int)ceil(value_bits * (double)(tablemax+1)/8);
     
          for (z=maxk;z>=0;z--){
                if (i_active[z]==1 || k==1) continue;
                i=z;
                /*prune i-th wire, reduce k*/
	        /*transform the rule table*/
                if ((catemp=(char *)calloc(tablebytes,sizeof(char)))
				    ==NULL) outof_memory("catemp");
                for (zz=tablemax;zz>=0;zz--){
                   outpt=get_value(carule[cellindex],zz);
                   /*compress the nhood by removing i-th bit*/
                   if (value_range==2) 
                          dec_to_bit_line(nhoodtemp,(unsigned long)zz,k);
                   else dec_to_value_line(nhoodtemp,(unsigned long)zz,k);
                   for (j=i;j<=k-2;j++){ 
		      /*close gap*/
                      set_value(nhoodtemp,j,get_value(nhoodtemp,j+1) );
		   }
                   set_value(nhoodtemp,k-1,0);
                   poss=(unsigned int) dec_equiv(nhoodtemp,k-2);
                   set_value(catemp,poss,outpt);
                }
	        for (j=i;j<=k-2;j++) /*shift wires*/
                       wiring[cellindex][j]=wiring[cellindex][j+1];
                wiring[cellindex][k-1]=0;
                nhoodm[cellindex]=k-1;
                k-=1;
                tablemax= (signed int)pow(value_range,(double)k)-1;
                tablebytes=(signed int)ceil(value_bits * 
                                              (double)(tablemax+1)/8);
                memmove(carule[cellindex],catemp,tablebytes);
                free(catemp);
          }
          if (is[0]=='k' || !rulemix) break; 
                                 /*just this network element*/
       }
        
       if (!rulemix){
          /*prune same redundant wire for rest of network, and realloc*/
          if ((wiring[0]=(unsigned int*)realloc(wiring[0],
                                  k*sizeof(unsigned int)))
					==NULL) outof_memory("wiring[0]");   
          for (element=1;element<=lineL-1;element++){
             cellindex=element;
	     k=maxk+1;
             for (z=maxk;z>=0;z--){
                if (i_active[z]==1 || k==1) continue;
                i=z;
                /*prune i-th wire, reduce k*/
	        for (j=i;j<=k-2;j++) /*shift wires*/
                       wiring[cellindex][j]=wiring[cellindex][j+1];
                wiring[cellindex][k-1]=0;
                nhoodm[cellindex]=k-1;
                k-=1;                         
             }
             sprintf(textb[0],"wiring[%d]",element);
                if ((wiring[cellindex]=
                      (unsigned int*)realloc(wiring[cellindex],
                                  k*sizeof(unsigned int)))
					==NULL) outof_memory(textb[0]);
          }
          
          free_v_code_arrays();
          free_mem_all_0s_all_1s_rules();

	  free_mem_iso(nhood);
          nhood=k;
          allocate_mem_iso(nhood);
          cellindex=0;
          if ((carule[0]=(char *)realloc(carule[0],tablebytes*sizeof(char)))
				       ==NULL) outof_memory("carule[0]");
          if ((cacode[0]=(char *)realloc(cacode[0],
                     (signed int)ceil((double)(nhood+1)/8)*
			 sizeof(char)))==NULL)outof_memory("cacode[0]");
          set_up_v_code(); /*new method using recursive tree*/

          codebytes=(signed int) /*bytes for v-code, min=1*/
              ceil(value_bits * (double)v_tablecodemax[nhood]/8);
          if ((v_code[0]=(char *)realloc(v_code[0],codebytes*
			sizeof(char)))==NULL)outof_memory("v_code[0]");
          allocate_mem_all_0s_all_1s_rules(nhood);
       }
       free(nhoodtemp);
       free(i_active);
       nhood_lb_ub();    
       k_changed=1;
       
       if (rulemix==0 && (twod==2 || threed==3) && !loc_twod_fonly){
	  nhood+=1;
          free_mem_wiring();
          nhood-=1;
          allocate_mem_wiring();
          if (twod==2) wireup_2d_nhood(i2d-1,j2d-1,0,0);
          else if (threed==3) wireup_3d_nhood(i3d-1,j3d-1,h3d-1,0,0,0);
       }
       rulechanged;
       goto start; //added
    }

    /*--------------------------------------------------------------*/
    /*change to equivalent rule with greater nhood*/
    /*do this only at start, or if basin, not running forward*/
    else if ((rulemix && !nhood_mixed) || dontmesswith_k==1);/*dont transform*/
    else if ((atoi(is)>nhoodm[cellindex] && atoi(is)<=max_k)
                                  && nhoodm[cellindex]<max_k){
      char rnd_wiring=0;
      signed int zv,step,t_max_temp,t_bytes_temp;

       if (!rulemix && !nhood_mixed && !rnd_wiring){
          free_v_code_arrays();
          free_mem_tcode0();
       }
       
       free_mem_iso(nhood);
       final_nhood=atoi(is);
       allocate_mem_iso(final_nhood);
       
       startnhood=nhoodm[cellindex];
       /*cellindex=0;*/
       for (zz=startnhood;zz<=final_nhood-1;zz++){
	  gnhood=zz+1;
          /*fprintf(stderr,"\nzz=%d nhoodm[%d]=%d",
                          zz,cellindex,nhoodm[cellindex]);*/
          tablemax= (signed int)pow(value_range,nhoodm[cellindex])-1;
          tablebytes=(signed int)ceil(value_bits *(double)(tablemax+1)/8);
          /*fprintf(stderr,"\ntablebytes=%d",tablebytes);*/
	  if ((catemp=(char *)calloc(tablebytes,sizeof(char)))
				       ==NULL) outof_memory(catemp);
	  memmove(catemp,carule[cellindex],tablebytes);
   	 
          if (nonlocal && regular2d==0 && regular2d_tgrid==0
                          &&  regular3d==0) rnd_wiring=1;

	  if (!rulemix && !nhood_mixed && !rnd_wiring){
             free_mem_rule0_extra();
	     free_mem_all_0s_all_1s_rules();
	     if (!loc_twod_fonly) free_mem_wiring();

             nhood=gnhood;

	     for (poss=0; poss<=lineL-1;poss++) nhoodm[poss]=nhood;
             allocate_mem_rule0_extra(nhood);
             allocate_mem_all_0s_all_1s_rules(nhood);

             t_max_temp= (signed int)pow(value_range,nhood)-1;
             t_bytes_temp=(signed int)ceil(
                                  value_bits *(double)(t_max_temp+1)/8);
             if ((carule[0]=(char *)
                   realloc(carule[0],t_bytes_temp*sizeof(char)))
	                     ==NULL) outof_memory("carule[0]");  	  
	     if (!loc_twod_fonly) allocate_mem_wiring();
          }
	  else nhoodm[cellindex]=gnhood;
          if (nhood<gnhood) nhood=gnhood;
          
	  /*convert n rule to n+1.rule*/
          if (value_range==2){	 
	     for (z=tablemax; z>=0; z--){
	       
                bit=get_bit(catemp,z);
	        temp=1;
	        if (nhoodm[cellindex]%2==0){ /*new even nhood*/
                   /*oldnhood+1, added on right*/
		   set_bit(carule[cellindex],(z<<1)+1,bit);
                   /*oldnhood+0, added on right*/
		   set_bit(carule[cellindex],z<<1,bit);
	        }
	        else{ /*new odd nhood*/
		   /*1 + oldnhood, added on left*/
		   set_bit(carule[cellindex],
                          (z+(temp<<(nhoodm[cellindex]-1))),bit);
		   /*0 + oldnhood, added on left, no change*/
		   set_bit(carule[cellindex],z,bit);
	        }
	     }
          }
          else{ /*multi_value*/
             if (nhoodm[cellindex]%2==0){ /*new even nhood*/
               for (z=0;z<=tablemax;z++){
		  /*fprintf(stderr,"\n%d:",z);*/
                  bit=get_value(catemp,z);
                  for (zv=0;zv<=value_range-1;zv++){  /*added on right*/
		     /*fprintf(stderr," %d",(z*value_range)+zv);*/
		     set_value(carule[cellindex],(z*value_range)+zv,bit); 
                  }
	       }
	     }
	     else{ /*new odd nhood*/
               for (z=0;z<=tablemax;z++){
		  /*fprintf(stderr,"\n%d:",z);*/
                  bit=get_value(catemp,z);
                  step=tablemax+1;
                  for (zv=0;zv<=value_range-1;zv++){  /*added on right*/
		     /*fprintf(stderr," %d",z+step*zv);*/
		     set_value(carule[cellindex],z+step*zv,bit); 
                  }
                  /*fprintf(stderr,": %d",bit);*/
	       }	        
	     }           
	  }
	  free(catemp);
       }
       tablemax= (signed int)pow(value_range,nhoodm[cellindex])-1;
       if (nhood_mixed){
             /*wire extra pseudo-nhood cells as 1d local*/	
             poss=cellindex;
             for (zz=startnhood;zz<=final_nhood-1;zz++){              
                   nhoodm[poss]=zz+1;
                   sprintf(textb[0],"wiring[%d]",poss);
                   if ((wiring[poss]=(unsigned int*)realloc(wiring[poss],
                                  nhoodm[poss]*sizeof(unsigned int)))
					==NULL) outof_memory(textb[0]);
	           /*for neutral trans, smaller psuedo-nhood 
                                               must remain central*/  
                   /*if before nhood is even, add new wire on left*/
                   if (zz%2==0) wiring[poss][zz]=
                              (lineL+poss-(nhoodm[poss]/2)+zz)%(lineL);
                   /*if before nhood is odd, add new wire on right, p-index 0*/
                   else{
                      for (wire=zz-1;wire>=0;wire--)
		          wiring[poss][wire+1]=wiring[poss][wire];
                      wiring[poss][0]=(lineL+poss-nhoodm[poss]/2)%(lineL);
                   }		
             }           	            
       }

       else if (!rulemix && !nhood_mixed){
       
          if (nonlocal==0){ /*if regular1d*/
	     for (poss=lineL-1;poss!=Maxu;poss--)
			   oneD_local_wire_cell(poss,lineL-1);
          }
          else if (regular2d || regular2d_tgrid)
              wireup_2d_nhood(i2d-1,j2d-1,0,0);
          else if (regular3d) wireup_3d_nhood(i3d-1,j3d-1,h3d-1,0,0,0);
          else if (nonlocal){ 
             /*wire extra pseudo-nhood cells as 1d*/	
             for (zz=startnhood;zz<=final_nhood-1;zz++){
	        /*fprintf(stderr,"\n zz=%d pos=",zz); */           
                nhood=nhood_ub=zz+1;
                for (poss=lineL-1;poss!=Maxu;poss--){
		  /*fprintf(stderr,"%lu ",poss);*/
                   nhoodm[poss]=nhood;
                   sprintf(textb[0],"wiring[%d]",poss);
                   if ((wiring[poss]=(unsigned int*)realloc(wiring[poss],
                                  nhood*sizeof(unsigned int)))
					==NULL) outof_memory(textb[0]);
	           /*for neutral trans, smaller p-nhood must remain central*/
		   /*if before nhood is even, add new wire on left*/
                   if (zz%2==0)
			wiring[poss][zz]=(lineL+poss-(nhood/2)+zz)%(lineL);
                   /*if before nhood is odd, add new wire on right, p-index 0*/
                   else{
                      for (wire=zz-1;wire>=0;wire--)
		          wiring[poss][wire+1]=wiring[poss][wire];
                      wiring[poss][0]=(lineL+poss-nhood/2)%(lineL);

                      /*for (wire=zz;wire>=0;wire--){
                         fprintf(stderr,"%lu ",wiring[poss][wire]);
                      }
                      fprintf(stderr,"\n");*/ 
                   }	
                }
             }     
	  }       	            
       }
       nhood_lb_ub();   
       cell_out_freq();
       
       k_changed=2; 
       if (rulemix==0 && (twod==2 || threed==3) && !loc_twod_fonly){
	  nhood-=1;
          free_mem_wiring();
          nhood+=1;
          allocate_mem_wiring();
          if (twod==2) wireup_2d_nhood(i2d-1,j2d-1,0,0);
          else if (threed==3) wireup_3d_nhood(i3d-1,j3d-1,h3d-1,0,0,0);
       }
       if (!rulemix && !nhood_mixed && !rnd_wiring){
          allocate_mem_tcode0(nhood);
          set_up_v_code();
       }
       rulechanged;
       goto start; //added
    } 
    return(k_changed);
}

/***** complementary_transformation, seperate function Jan 2013   ******/
void complementary_transformation(char *xrule,
                            signed int xtablebytes,signed int xtablemax){
  signed int z;
  char xvalue;

          if (value_range==2){
             for (z=0;z<=xtablebytes-1;z++)
                     xrule[z]=~xrule[z];
	  }
          else{
             for (z=0;z<=xtablemax;z++){
                /*compliment multivalue by subtraction*/    
	        xvalue=get_value(xrule,z);
                xvalue=(value_range-1)-xvalue;
                set_value(xrule,z,xvalue);
             }
          }        
}

/***** negative_transformation_transformation, seperate function Jan 2013   ******/
void negative_transformation(char *xrule,
                            signed int xtablebytes,signed int xtablemax){
  signed int z;
  char *catemp,tempvalue;

          if ((catemp=(char *)calloc(xtablebytes,sizeof(char)))
				    ==NULL) outof_memory("catemp");
          if (value_range==2){	
	     for (z=0;z<=xtablemax;z++){
                set_bit(catemp,xtablemax-z,abs(1-get_bit(xrule,z)));
             }
             memmove(xrule,catemp,xtablebytes); 
          } 
          else{
	     for (z=0;z<=xtablemax;z++) /*invert*/
                set_value(catemp,xtablemax-z,get_value(xrule,z));
             memmove(xrule,catemp,xtablebytes);
             for (z=0;z<=xtablemax;z++){
                /*compliment multivalue by subtraction*/    
	        tempvalue=get_value(xrule,z);
                tempvalue=(value_range-1)-tempvalue;
                set_value(xrule,z,tempvalue);
             }
          }
          free(catemp);
}       

/***** reflection_transformation, seperate function Jan 2013   ******/
void reflection_transformation(char *xrule, char xnhood,
                            signed int xtablebytes,signed int xtablemax){
  signed int z,zz;
  char *catemp,*nhoodtemp;
  unsigned int tposs;

          if ((nhoodtemp=(char *)calloc(2,sizeof(char)))
				    ==NULL) outof_memory("nhoodtemp");
          if ((catemp=(char *)calloc(xtablebytes,sizeof(char)))
				    ==NULL) outof_memory("catemp");

          /*swap outputs of pairs of (asymmetric) reflected nhoods*/
          for (z=0;z<=xtablemax;z++){
             if (value_range==2) 
                   dec_to_bit_line(nhoodtemp,(unsigned long)z,xnhood);
             else dec_to_value_line(nhoodtemp,(unsigned long)z,xnhood);
	     /*reflect bits*/
	     for (zz=0;zz<=xnhood-1;zz++){
	        if (value_range==2){
	            set_bit(nhoodtemp,(xnhood-1)-zz,get_bit(nm[zz],z));
	        }
                else set_value(nhoodtemp,(xnhood-1)-zz,get_value(nm[zz],z));
	     }
	     tposs=(unsigned int) dec_equiv(nhoodtemp,xnhood-1);
             if (value_range==2){
	        set_bit(catemp,tposs,get_bit(xrule,z)); 
             }
             else set_value(catemp,tposs,get_value(xrule,z));
          }
          memmove(xrule,catemp,xtablebytes); 

          free(catemp);
          free(nhoodtemp);
}

/*************** reduce max k to max found Feb 1997  *******************/
void reduce_max_k(void){
   char maxk=0;
   unsigned int zu;
   signed int tablemax,tablebytes;
   
   if (!nhood_mixed || value_range>2) return;
   /*find biggest k in network*/
   for (zu=0;zu<=lineL-1;zu++){
     if (maxk<nhoodm[zu]) maxk=nhoodm[zu];
   }
   if (maxk==nhood) return;
   /*all rules have mem allocated as for largest nhood*/
   if (tot_only==0){
      tablemax= (signed int)pow(value_range,(double)nhood)-1;
   }
   else if (totalistic==1) tablemax= nhood*(value_range-1);
   else if (totalistic==2) tablemax= v_tablecodemax[nhood];
   tablebytes=(signed int)ceil(value_bits * (double)(tablemax+1)/8);

   for (zu=0;zu<=lineL-1;zu++){
       /*rellocate rulemix*/
       if (tot_only==0){
          sprintf(textb[0],"carule[%d]",zu);
          if ((carule[zu]=(char *)realloc(carule[zu],tablebytes*sizeof(char)))
  					==NULL) outof_memory(textb[0]);
       }
       else{
          if (totalistic==1){
             /*rellocate codemix*/
             sprintf(textb[0],"cacode[%d]",zu);
             if ((cacode[zu]=
	     (char *)realloc(cacode[zu],(signed int)ceil((double)(maxk+1)/8)*
			  sizeof(char)))==NULL) outof_memory(textb[0]);
          }
          if (totalistic==2){
              /*rellocate v_codemix*/
             sprintf(textb[0],"cacode[%d]",zu);
             if ((v_code[zu]=
	     (char *)realloc(v_code[zu],(signed int)ceil((double)(maxk+1)/8)*
			  sizeof(char)))==NULL) outof_memory(textb[0]);
          }
       }
       /*reallocate wiring*/
       sprintf(textb[0],"wiring[%d]",zu);
	if ((wiring[zu]=
	    (unsigned int*)realloc(wiring[zu],maxk*sizeof(unsigned int)))
					==NULL) outof_memory(textb[0]);  
   }	
   /*free other misc arrays*/
   if (tot_only==0){ 
          free_mem_rule0_extra();
          free_mem_all_0s_all_1s_rules();
   } 
   if (tot_only==1) free_mem_tcode0_extra();
   
   nhood=nhood_ub=maxk;
   /*alloc other misc arrays*/   
   if (tot_only==0){ 
          allocate_mem_rule0_extra(nhood);
          allocate_mem_all_0s_all_1s_rules(nhood);
   }     
   if (tot_only==1) allocate_mem_tcode0_extra(nhood);

   cell_out_freq();
}

/********** load last rule, tcode, kcode, Aug 2002 *****************/
char loadlast_rule_tcode_vcode(char *thisrule,char tnhood,
	       signed int thistablemax, unsigned int cposs){
  char ruleloaded=0, *temprule;
  signed int tempx2,tempy2,tablemax,rulebytes;

        tempx2=getx;
        tempy2=gety;
   
        if (totalistic==0){ 
              tablemax=(signed int)pow(value_range,
                        (double)nhood)-1;/*max index of ruletable*/
              rulebytes=(signed int)ceil(value_bits * (double)(tablemax+1)/8);
           }
	   else if (totalistic==1){   
              tablemax=nhood*(value_range-1); /*max index of tcode*/
              rulebytes=(signed int) ceil(value_bits * 
                      (double)(tablemax+1)/8);/*bytes for kcode, min=1*/
           }              
           else if (totalistic==2){ 
              tablemax=v_tablecodemax[nhood]; /*max index of kcode*/
              rulebytes=(signed int) /*bytes for k_code, min=1*/
                      ceil(value_bits * (double)(tablemax+1)/8);
        }
        if ((temprule=(char *)calloc(rulebytes,sizeof(char)))
				       ==NULL) outof_memory("temprule");
 
	/*new k must = old k*/
        ruleloaded=load_save_wrs('l',temprule,0);
        if (is[0]=='q'){
            ruleloaded=0;
            goto endfunc;
        }
        if (ruleloaded==tnhood) memmove(thisrule,temprule,rulebytes);
        else if (ruleloaded>0){
              get_prompt_box(5,1);
	      draw_prompt_box(1);
	      if (ruleloaded>0) sprintf(textb[0],
		"file-k(%d) != base-k(%d), can't load, cont-ret:",
						 ruleloaded,tnhood);
              else if (ruleloaded==-1) sprintf(textb[0],"file error, cont-ret:");
	      outtext(textb[0]);
	      input_string(1,0);
              sprintf(textb[9],"%s","boximage_prompt[5]"); 
	      putimage((signed int)
		     ((float)Maxx)/2,2,boximage_prompt[5],COPY_PUT,textb[9]);
	      ruleloaded=0;
        }

      endfunc:
       free(temprule);
       return(ruleloaded);
 }

/********************* specify k-code, Aug 2002 **********************/
signed int select_t_v_code(char inbox,char one_cell,char** thiscode,
      char** thisrule,signed int number_rules,unsigned int poss,char forcezero){
 char select,all_remaining=0,tnhood,ruleloaded=0,dont_convert=0,select_def;
 signed int tablecodemax,codebytes,z,
      startx,starty,tempxr,tempyr,
      tablemax,rulebytes,tempy3,xbox,tempx,tempy;
 unsigned int cellindex,cindex;
 unsigned long codedec,code_dec_max;
 char *k_seen, **k_rule;

#define revise_code {\
     tempxr=getx;\
     tempyr=gety;\
     if (number_rules==1) goto start;\
     else{\
	sprintf(textb[0],\
	  "change: index(%d)-i, start again-a, selection-s, cont-ret:",\
						cellindex);\
	draw_prompt_box(1);\
	outtext(textb[0]);\
	input_string(1,0);\
	if (is[0]=='q') goto start;\
	else if (is[0]=='s'){\
	   select=reselect_rule_prompts(cellindex,select,code_dec_max);\
	   if (select=='q') goto start;\
	   else{\
	      cellindex-=1;\
	      continue;\
	   }\
	}\
	else if (is[0]=='i'){\
	   cellindex=\
	   reselect_rule_index(cellindex,number_rules)-1;\
	   continue;\
	}\
	else if (is[0]=='a') goto start;\
	moveto(tempxr,tempyr);\
     }\
  }

/*first set bits/values - then (in main sequence only) show bits/values+hex*/
#define reconfirm_code {\
        tempx=getx;\
        tempy=gety;\
        if (number_rules==1){\
	   define_bits(nhoodm[cindex],totalistic+1,thiscode[cindex],tablecodemax,0);\
           if (is[0]=='q'){\
              select_def='b';\
              goto start;\
           }\
        }\
}

  setcolor(white);
  startx=getx;
  starty=gety;
  if (poss!=Maxu) tnhood=nhoodm[poss];
  else tnhood=nhood;

  /*scale of bits*/
  set_cellscale(tnhood,2); 
  if (inbox==0) select_def='r';
  else if (inbox==1) select_def='b';

 start:
  if (inbox==0){
     setfillstyle(SOLID_FILL,black);
     bar(xtext,starty+CHeight/2,Maxx,Maxy);
  }
  else if (inbox==1){
     sprintf(textb[9],"%s","boximage[5]");
     putimage(trboxw,vgay(343),boximage[5],COPY_PUT,textb[9]);
     draw_box(-1,trboxw,vgay(343),Maxx-2,Maxy,1,0);
     startx=trboxw+3;
  }
  setcolor(white);
  moveto(startx,starty);  
  tablemax=(signed int)pow(value_range,
           (double)tnhood)-1;/*max index of ruletable*/
  rulebytes=(signed int)ceil(value_bits * (double)(tablemax+1)/8);
  if (totalistic==1){ 
     tablecodemax=tnhood*(value_range-1); /*max index of tcode table*/
     sprintf(textb[4],"tcode");
  }
  else if (totalistic==2){
      tablecodemax=v_tablecodemax[tnhood]; /*max index of kcode table*/
      sprintf(textb[4],"kcode");
  }
  codebytes=(signed int) /*bytes for tcode, v_code, min=1*/
             ceil(value_bits * (double)(tablecodemax+1)/8);
  code_dec_max=max_dec_rule(tablecodemax,value_range);
  if (code_dec_max>0) sprintf(textb[3]," dec-d ");
  else sprintf(textb[3]," ");
  if (tot_only==0 && rulemix==0) sprintf(textb[5],"rcode-R ");
  else sprintf(textb[5],"");
  if (totalistic==2) sprintf(textb[6],"/u Alt-A ");
  else sprintf(textb[6]," ");
  
  if (totalistic==2 && tot_only==1) sprintf(textb[2]," k+-k prtx/swap-x ");
  else if (totalistic==2) sprintf(textb[2]," prtx/swap-x ");
  else sprintf(textb[2]," prtx-x ");

  sprintf(textb[0],
     "Select v%dk%d %s (S=%d): empty-e fill-f%s ascii-v rnd-r",
                 value_range,tnhood,textb[4],tablecodemax+1,textb[2]);
  if (totalistic==1)
     sprintf(textb[1],      
     "bits-b hex-h%smaj-m%s%srep-p load-l (def-%c):",
                              textb[3],textb[6],textb[5],select_def);
  else sprintf(textb[1], /*totalistic==2*/     
     "bits-b hex-h%smaj-m%s%srep-p load-l (def-%c):",
                                 textb[3],textb[6],textb[5],select_def);
  
  if (inbox==0) next_line(xtext,1);
  else moveto(startx,gety+CHeight);
  outtext(textb[0]);
  if (inbox==0) next_line(xtext,1);
  else moveto(startx,gety+CHeight);
  outtext(textb[1]);
  input_string(1,0);
  select=is[0];
  if (is[0]=='q') return(0);
  else if (accept_rule_method(select,code_dec_max,tnhood)==1);/*accept*/
  else  select=select_def;/*don't accept*/

  tempy3=gety;

  //to clear space for isotropic ruletable jan2020  
  if (inbox==0) iso_x=xtext* CWidth;
  else iso_x=Maxx/2 +vgax(1);
  iso_y=gety+CHeight +vgay(1);

   /*to record if particular k occured and record latest rule*/
  if (nhood_mixed && poss==Maxu){
     signed int k_bytes;
     if ((k_seen=(char *)calloc(nhood+1,sizeof(char)))
				  ==NULL) outof_memory("(k_seen");
     if ((k_rule=(char**)calloc(nhood+1,sizeof(char*)))
				  ==NULL) outof_memory("k_rule");
     
     for (z=1;z<=nhood;z++){
        /*max index of codetable*/
        if (totalistic==1) tablecodemax=
            z*(value_range-1); /*max index of tcode table*/
        else if (totalistic==2) tablecodemax=
            v_tablecodemax[z]; /*max index of kcode table*/
        k_bytes=(signed int)ceil(value_bits * (double)(tablecodemax+1)/8);
      
        sprintf(textb[0],"k_bytes[%d]",z);
        if ((k_rule[z]=(char*)calloc(k_bytes,sizeof(char*)))
				       ==NULL) outof_memory(textb[0]);
     }
  }
  all_remaining=0;

  for (cellindex=0;cellindex<=number_rules-1;cellindex++){
     dont_convert=0;
     if (one_cell==1){ /*to revise rule at one cell*/
        if (poss==Maxu) cindex=0;
        else cindex=poss;
     } 
     else if (rulemix && poss==Maxu){ 
        /*includes: && nhood_mixed, one_cell=2 for rule subset*/
        cindex=cellindex;
        if (nhood_mixed) tnhood=nhoodm[cindex];
     }
     if (nhood_mixed){
	tablemax=(signed int)pow(value_range,(double)nhoodm[cindex])-1;
        /*max index of codetable*/
        if (totalistic==1) tablecodemax=
            nhoodm[cindex]*(value_range-1); /*max index of tcode table*/
        else if (totalistic==2) tablecodemax=
            v_tablecodemax[nhoodm[cindex]]; /*max index of kcode table*/
        codebytes=(signed int)ceil(value_bits * (double)(tablecodemax+1)/8);
        code_dec_max=(unsigned long)
                pow(value_range,(double)tablecodemax)-1;/*max code dec*/
     }
     if (inbox==0 && rulemix){
      char k_was_seen=0;
       xbox=draw_prompt_box(2);
       if (totalistic==4){
	  if (outer_tot==1) sprintf(textb[1],"OuterTcode");
          else sprintf(textb[1],"tcodemix");
       }
       else{
          if (outer_tot==1) sprintf(textb[1],"OuterKcode");
          else sprintf(textb[4],"kcodemix");
       }
       if (nhood_mixed==0) sprintf(textb[0],"index=%d (v%dk%d %s)",
                         cellindex,value_range,nhoodm[cindex],textb[4]);
       else sprintf(textb[0],"index=%d k(%d-%d) (v%dk%d %s) ",
               cellindex,nhood_lb,nhood_ub,value_range,nhoodm[cindex],textb[4]);
       outtext(textb[0]);
       
       if (nhood_mixed && poss==Maxu && cindex>0){    
	 if (k_seen[(signed int)nhoodm[cindex]]==1){
	     k_was_seen=1; 
             sprintf(textb[0],", same as last-s, all remaining-a:"); 
             outtext(textb[0]);
             input_string(1,0);
             if (is[0]=='s' || is[0]=='a' ){
                 memmove(thiscode[cindex],
                      k_rule[(signed int)nhoodm[cindex]],codebytes);
                 if (tot_only==0){ /*convert code to rule*/
                    if (totalistic==1) 
                       code2rule(thisrule[cindex],thiscode[cindex],nhoodm[cindex]);
                    else if (totalistic==2) 
                       v_code2rule(thisrule[cindex],thiscode[cindex],nhoodm[cindex],1);
                 }                 
                 if (is[0]=='a') k_seen[(signed int)nhoodm[cindex]]='a';
                 moveto(xtext,tempy3);
                 continue;
             }
         }
         else if (k_seen[(signed int)nhoodm[cindex]]=='a'){
            memmove(thiscode[cindex],
                k_rule[(signed int)nhoodm[cindex]],codebytes);
            if (tot_only==0){ /*convert code to rule*/
                    if (totalistic==1) 
                       code2rule(thisrule[cindex],thiscode[cindex],nhoodm[cindex]);
                    else if (totalistic==2) 
                       v_code2rule(thisrule[cindex],thiscode[cindex],nhoodm[cindex],1);
            }
            moveto(xtext,tempy3);
            continue;
	 }
       }
     
       if (all_remaining==0){
          char latest_select;
	    latest_select=select;
            moveto(xbox,gety+CHeight);	    
            sprintf(textb[0],
		    "hand=%c, change-(any valid entry) or index-q",select);
            outtext(textb[0]);
            if (nhood_mixed==0 &&
                 (select=='r' || select=='m' || select=='u'
                     || (select=='A' && totalistic==2))) outtext(", rnd all-a");
            outtext(":");          
            input_string(1,0);
            if (is[0]=='q'){
                 {revise_code}
                 is[0]=' ';
            }
            else{             
	       /*set all remaining automatically - only for this method*/
               if (nhood_mixed==0 && is[0]=='a' && 
                  (select=='r' || select=='m' || select=='u' ||
                             (select=='A' && totalistic==2))) all_remaining=1;
               /*or change selection by entering any of the following*/
               else{
                   select=is[0];
                   if (accept_rule_method(select,code_dec_max,tnhood)==1);/*accept*/
                    else select=latest_select;
               }
            }
       }
       moveto(xtext,tempy3);
       setfillstyle(SOLID_FILL,black); /*to blank out extra text after 'r'*/
       bar(getx,gety+CHeight,Maxx,Maxy);
     }
     if (select=='e'){ /*empty, all 0s*/
        for (z=tablecodemax;z>=0;z--) set_value(thiscode[cindex],z,0);
        {reconfirm_code}        
     }
     else if (select=='f'){ /*fill with chosen vyalue*/
       char temp;
        if (value_range>2){
           tempx=getx;
           tempy=gety;  
           draw_prompt_box(1);
           sprintf(textb[0],"fill with value 0-%d (def %d):",
                                      value_range-1,value_range-1);
           outtext(textb[0]);
           input_string(1,0);
           temp=atoi(is);
           if (is[0]!=13 && atoi(is)>=0 && atoi(is)<=value_range-1) temp=atoi(is);
           else temp=value_range-1;
           if (inbox==0) erase_prompt_box(1);
           moveto(tempx,tempy); 
        }
        else temp=1;
	for (z=0;z<=tablecodemax;z++) set_value(thiscode[cindex],z,temp);
        {reconfirm_code}
        
     }
     else if (select=='r'){  /*random code*/ 
        signed int temprand;     
        if (inbox==0 && rulemix && nhood_mixed==0 && all_remaining==1){
           /*set the remainder of rule-mix automatically*/    	   
           if (bias_density_rule==100*(((float)value_range-1)/value_range)){	     
	      for (z=tablecodemax;z>=0;z--)
	         set_value(thiscode[cindex],z,myrand()%value_range);
           }
	   else{
	      for (z=tablecodemax;z>=0;z--){
	         temprand=myrand()%10000; /*0 to 9999*/
                 if (temprand>bias_density_rule*100){
                       set_value(thiscode[cindex],z,0);
                 }   
                 else{
                    temprand=myrand()%(value_range-1);
                    set_value(thiscode[cindex],z,temprand+1);
                 }
	      }
	   }
           if (forcezero==1) set_value(thiscode[cindex],0,0);/*forcezero nhood -> 0*/
        }	     
        else{ 
	   random_bits(nhoodm[cindex],2,0,1,thiscode[cindex],tablecodemax);
           if (number_rules==1 && is[0]=='q'){
              select_def='b';
              goto start;
           }
        }        
     }

     /*approx transformation to k+ and save - to stretch kcode*/
     else if (select=='k' && tot_only==1 && totalistic==2){ 
       if (rulemix==0 && nhood<Maxnhood){
          /*approx  v_code -> v_code+k*/
          char *v_code_new,nhood_new;
          unsigned int v_tablesize,v_tablecodemax_new,v_codebytes_new; 
          signed int v_count,left_table,right_table;

          signed int fid;
          unsigned char *buf;

          draw_prompt_box(1);      
	  sprintf(textb[0],
	   "create similar to k%d kcode and save, enter greater k(%d-%d):",
                            nhood, nhood+1,Maxnhood);             

          outtext(textb[0]);
          input_string(2,0);
          if (atoi(is)>nhood && atoi(is)<=Maxnhood)
                                            nhood_new=atoi(is);
          else goto start;
          if (nhood_new<nhood) v_tablecodemax_new=v_tablecodemax[nhood_new];
          else{
#            if __UNIX__  /* long long doesnt work for DOS */        
                v_tablesize=/*v-codetable size*/
                (unsigned int) 
                 (longlong_fact(value_range+nhood_new-1,nhood_new+1)/ 
	         (longlong_fact(value_range-1,1)));
#            elif __WATCOM__
                v_tablesize=/*v-codetable size*/
                (unsigned int) 
                 (long_fact(value_range+nhood_new-1,nhood_new+1)/ 
	         (long_fact(value_range-1,1)));
#            endif
             v_tablecodemax_new=v_tablesize-1;
          }
	  v_codebytes_new=(signed int) /*bytes for vc_code*/
                 ceil(value_bits * (double)(v_tablecodemax_new+1)/8);
          if ((v_code_new=(char *)calloc(v_codebytes_new,
			  sizeof(char)))==NULL)outof_memory("v_code_new");
          /*set v_code_new at random*/
          for (z=0;z<v_tablecodemax_new;z++)
	        set_value(v_code_new,z,myrand()%value_range);

          /*now copy left and right ends of v_vode -> v_code_new k+*/
          if (nhood_new>nhood){   
             left_table=(v_tablecodemax[nhood])/2;
             right_table=(v_tablecodemax[nhood]+1)-left_table;
          }
          else{   
             left_table=(v_tablecodemax_new+1)/2;
             right_table=(v_tablecodemax_new+1)-left_table;
          }
          v_count=v_tablecodemax[nhood]; //copy left part
	  for (z=v_tablecodemax_new;
                        z>=v_tablecodemax_new-left_table;z--){
	      set_value(v_code_new,z,get_value(v_code[0],v_count));
              v_count--;
          }
          for (z=0;z<=right_table;z++)
	           set_value(v_code_new,z,get_value(v_code[0],z));

          fprintf(stderr,"\nv_tablecodemax[%d]=%d\n",
		                      nhood, v_tablecodemax[nhood]);
          for (z=v_tablecodemax[nhood];z>=0;z--)
                    fprintf(stderr,"%d",get_value(v_code[0],z));

          fprintf(stderr,"\nv_tablecodemax_new=%d nhood_new=%d\n",
		              v_tablecodemax_new,nhood_new);
          for (z=v_tablecodemax_new;z>=0;z--)
                      fprintf(stderr,"%d",get_value(v_code_new,z));
              
          /*save_last_rule(v_code_new,nhood_new);*/
          sprintf(filename,"%s%d%s%d%s","l_v",
                         value_range,"k",nhood_new,".vco\0");
          /*max buffer to store bytes*/
          if ((buf=(unsigned char *)calloc(
                       2+v_codebytes_new,sizeof(unsigned char)))
		           ==NULL) outof_memory("buf for saving last rule");
           fid=myopen(filename,1,0);
           buf[0]=value_range;
           buf[1]=nhood_new;
           memmove(buf+2,v_code_new,v_codebytes_new);
           vret=write(fid, buf, 2+v_codebytes_new);
           close(fid);
           free(buf);
           free(v_code_new);
	 }
         goto start;
     }
    
     else if (select=='v'){ /*load/save as value rule-table (ascii)*/
	/*unsigned int filebytes=0;*/
        tempx=getx;
        tempy=gety;
        draw_prompt_box(1);
        if (totalistic==1) sprintf(textb[0],
           "ASCII tcode-table (v=%d k=%d S=%d) load/save-l/s:",
		                        value_range,tnhood,tablecodemax+1);
        else if (totalistic==2) sprintf(textb[0],
           "ASCII kcode-table (v=%d k=%d S=%d) load/save-l/s:",
		                        value_range,tnhood,tablecodemax+1);
        /*in case kcode or tcode was changed to rcode with 'R'*/
        else if (totalistic==0) sprintf(textb[0],
           "ASCII rcode-table (v=%d k=%d S=%d) load/save-l/s:",
		                        value_range,tnhood,tablemax+1);
        outtext(textb[0]);
        input_string(1,0);
        if (is[0]=='l' || is[0]=='s'){
          load_save_ascii_rule_seed(
	    is[0],'r',thiscode[cindex],tablecodemax+1);
        }
        moveto(tempx,tempy);
        {reconfirm_code}
     } 
     
     else if (select=='l'){ /*load kcode or tcode*/
        tempx=getx;
        tempy=gety;
        ruleloaded=loadlast_rule_tcode_vcode(thiscode[cindex],
                             tnhood,tablecodemax,cindex);
        moveto(tempx,tempy);
        if (ruleloaded==nhoodm[cindex]) {reconfirm_code}
    }    
    else if (select=='p'){
      /*to copy the last valid rule in a rulemix/nhood_mix*/
       if (rulemix && poss==Maxu && cindex>0){
	  if (nhood_mixed){   
	     if (k_seen[(signed int)nhoodm[cindex]]==1){
                memmove(thiscode[cindex],
                      k_rule[(signed int)nhoodm[cindex]],codebytes);
             }	     
          }
          else if (rulemix) memmove(thiscode[cindex],thiscode[cindex-1],codebytes);
       }
       else if (cindex==0) load_last_rule(thiscode[cindex],nhoodm[cindex]);
       else memmove(thiscode[cindex],thiscode[cindex-1],codebytes);
       {reconfirm_code}
    }

    else if (select=='b'){  /*enter as bits/values*/
        tempx=getx;
        tempy=gety;
	define_bits(nhoodm[cindex],totalistic+1,thiscode[cindex],tablecodemax,0);
        if (number_rules==1 && is[0]=='q'){
           select_def='b';
           goto start;
        }
        if (number_rules==1) select_def='b';
    }
    
    /*convert single kcode or tcode to rule - 
      then modify the full rule-table if required*/
    else if (select=='R' && tot_only==0 && rulemix==0){ 
       char totalistic_temp;
       
        if (totalistic==1) 
          code2rule(thisrule[cindex],thiscode[cindex],nhoodm[cindex]);
        else if (totalistic==2)
          v_code2rule(thisrule[cindex],thiscode[cindex],nhoodm[cindex],1); 
        totalistic_temp=totalistic;
        totalistic=0;
        set_cellscale(tnhood,1); 
        tempx=getx;
        tempy=gety;
        if (number_rules==1){ /*the rule/full lookup table - not the code*/
           define_bits(nhoodm[cindex],1,thisrule[cindex],tablemax,0);
           if (is[0]=='q'){
              select_def='b';
              goto start;
           }           
        }   
        totalistic=totalistic_temp;
        set_cellscale(tnhood,2);
    }
 
    else if (select=='m' || select=='u'){/*majority rule*/
       if (totalistic==1){
	  majority_tcode(thiscode[cindex],nhoodm[cindex],tablecodemax);
       }  
       else if (totalistic==2){
	  majority_or_fprintf_vcode(1,thiscode[cindex],nhoodm[cindex]);
          if (select=='u') /*flip or shift outputs from unanimous (uniform) nhoods*/
	     shift_outputs_unanimous(thiscode[cindex],tablecodemax,
                                     nhoodm[cindex],cindex);
       }
       {reconfirm_code}
    }

    /*Lee Altenberg's random subset, set the output of each
      nhood in the rule table to a value, with prob of the frequency
      of that value in the nhood*/ 
    else if (select=='A' && totalistic==2){
        altenberg_kcode(thiscode[cindex], nhoodm[cindex], tablecodemax);
        {reconfirm_code}
        
    }
    else if (select=='d' && code_dec_max>0){ /*enter as dec*/
        tempx=getx;
        tempy=gety;
        sprintf(textb[0],"decimal equivalent: enter 0-%lu (def-rnd):",code_dec_max);
	next_line(xtext,1);
	outtext(textb[0]);
	sprintf(textb[0],"%lu",code_dec_max);
	input_string(strlen(textb[0]),1);

	if (is[0]=='q') {revise_code};
        if (is[0]==13) codedec=myrand()%(code_dec_max);
        else codedec=atolu(is);/*string->unsigned long*/	
        if (codedec<=code_dec_max){
           if (is[0]!=13) codedec=atolu(is);
           else{
	     sprintf(textb[0]," %lu",codedec);
	     outtext(textb[0]);
           }
           /*convert dec to valuestring*/
	   if (value_range==2)
                  dec_to_bit_line(thiscode[cindex],codedec,tablecodemax+1);
           else dec_to_value_line(thiscode[cindex],codedec,tablecodemax+1);
           {reconfirm_code}
	}
	else{
           setcolor(lightred);
	   outtext(" - too big! back-ret:");
           setcolor(white); 
           input_string(1,0);
           select_def='d';
           goto start;
	}
     }
     else if (select=='h'){  /*enter as hex*/
        tempx=getx;
        tempy=gety;
	define_hex(nhoodm[cindex],totalistic+1,thiscode[cindex],codebytes-1,0,xtext);
        moveto(tempx,tempy);
        setfillstyle(SOLID_FILL,black);
        if (inbox==0){
              moveto(xtext,tempy3);
              bar(getx,gety+CHeight,Maxx,Maxy);
        }
        else if (inbox==1)
              bar(trboxw+1,tempy3+CHeight*1.3,Maxx-2-1,Maxy-1);
        moveto(tempx,tempy);
        {reconfirm_code}
     }

     else if (select=='x'){
       char temp_pdata,temp_filedata;
       unsigned int vfreq[8],ttot=0;
        /*print hex, table, then the index/code/table to the terminal*/
        for (z=value_range-1;z>=0;z--) vfreq[z]=0;
        if (inside_wiring_graphic==0){
           if (rulemix){ /*show details for the previous rule, otherwise all 0's */
              if (cellindex==0) goto skip_x;
	      else{ 
                 cindex=cellindex-1;
                 //fprintf(stderr,"\ncindex=%d cellindex=%d\n",cindex,cellindex);
                 if (totalistic==1) 
                  tablecodemax=nhoodm[cindex]*(value_range-1); /*max index of tcode table*/
                 else if (totalistic==2) 
                  tablecodemax=v_tablecodemax[nhoodm[cindex]]; /*max index of kcode table*/
              }
           }
        }
        if (totalistic==1){
           if (rulemix) fprintf(stderr,"\nv%dk%d tcodeSize=%d cindex=%d\n",
                              value_range, nhoodm[cindex],tablecodemax+1,cindex);        
           else fprintf(stderr,"\nv%dk%d tcodeSize=%d\n",
                              value_range, nhood,tablecodemax+1);                
           fprintf(stderr,"(hex) ");
           temp_pdata=pdata;
           temp_filedata=filedata;
           pdata=1;
           filedata=0;
           print_current_bitstring_hexbytes(0,2,thiscode[cindex],nhoodm[cindex],Maxx,white,3);
           pdata=temp_pdata;
           filedata=temp_filedata;
              
           fprintf(stderr,"\n(tcode-table:%d-0)\n",value_range-1);
           for (z=tablecodemax;z>=0;z--){
	          fprintf(stderr,"%d",get_value(thiscode[cindex],z));
                  vfreq[get_value(thiscode[cindex],z)]+=1;
           }
           fprintf(stderr,"\nvfreq=");
           for (z=value_range-1;z>=0;z--){ 
               fprintf(stderr,"%d", vfreq[z]);
               if (z>0) fprintf(stderr,"+"); 
               ttot+=vfreq[z];
           }
           fprintf(stderr,"=%d", ttot);
           if (ttot!=tablecodemax+1)
                 fprintf(stderr," !=tablesize=%d: ERROR",tablecodemax+1);
           draw_prompt_box(1);      
	   sprintf(textb[0],"print tcode-table (S=%d) to xterm -v:",
		      tablecodemax+1);
           outtext(textb[0]);
           input_string(1,0);
           //if (is[0]=='x'){
           if (is[0]=='v'){
	      for (z=tablecodemax;z>=0;z--)
	         fprintf(stderr,"\n%4d -> %d",
                        z,get_value(thiscode[cindex],z));
           }
        }
        else if (totalistic==2){
	   start_t2:
            if (rulemix)
              fprintf(stderr,"\nv%dk%d kcodeSize=%d cindex=%d\n",
                              value_range, nhoodm[cindex],tablecodemax+1,cindex);
            else fprintf(stderr,"\nv%dk%d kcodeSize=%d\n",
                              value_range,nhood,tablecodemax+1);  
            fprintf(stderr,"(hex) ");
            temp_pdata=pdata;
            temp_filedata=filedata;
            pdata=1;
            filedata=0;
            print_current_bitstring_hexbytes(0,3,thiscode[cindex],nhoodm[cindex],Maxx,white,3);
            pdata=temp_pdata;
            filedata=temp_filedata;

            fprintf(stderr,"\n(kcode-table:%d-0)\n",value_range-1);
            for (z=value_range-1;z>=0;z--) vfreq[z]=0;
            for (z=tablecodemax;z>=0;z--){
	          fprintf(stderr,"%d",get_value(thiscode[cindex],z));
                  vfreq[get_value(thiscode[cindex],z)]+=1; 
            }
            fprintf(stderr,"\nvfreq=");
            for (z=value_range-1;z>=0;z--){ 
               fprintf(stderr,"%d", vfreq[z]);
               if (z>0) fprintf(stderr,"+"); 
               ttot+=vfreq[z];
            }
            fprintf(stderr,"=%d", ttot);
            if (ttot!=tablecodemax+1)
                 fprintf(stderr," !=tablesize=%d: ERROR",tablecodemax+1);

            draw_prompt_box(1);      
	    if (value_range==3) sprintf(textb[0],
       "swap values-s, print kcode (S=%d) to xterm (vert/horiz/matrix)-v/h/m:",
		      tablecodemax+1);
            else sprintf(textb[0],
       "swap values-s, print kcode (S=%d) to xterm (vert/horiz)-v/h:",
		      tablecodemax+1);
            outtext(textb[0]);
            input_string(1,0);
            /*if (is[0]=='x') majority_or_fprintf_vcode(
	                 0,thiscode[cindex],nhoodm[cindex]);*/
            if (is[0]=='s'){
                for (z=value_range-1;z>=0;z--) vfreq[z]=0;
                ttot=0;
                swap_values_vcode(thiscode[cindex],nhoodm[cindex]);
                goto start_t2;
            }
            else if (is[0]=='v') fprintf_vcode(0,
			     thiscode[cindex],nhoodm[cindex]);
            else if (is[0]=='h') fprintf_vcode(1,
			     thiscode[cindex],nhoodm[cindex]);
            else if (is[0]=='m' && value_range==3) fprintf_vcode(2,
			     thiscode[cindex],nhoodm[cindex]);
            erase_prompt_box(1);
        }
       skip_x:
        if (number_rules==1){
           select_def='b';
           goto start;
        }
        else if (rulemix){
           select_def=select='r';
           continue;
        }
     }
     /*----------------------------------------------------------*/
     /*convert code to rule*/
     if (tot_only==0 && dont_convert==0){ 
        if (totalistic==1){
	   if (rulemix==0) code2rule(carule[0],cacode[0],nhood);
           else code2rule(thisrule[cindex],thiscode[cindex],nhoodm[cindex]);
        }
        else if (totalistic==2){
           if (rulemix==0) v_code2rule(carule[0],v_code[0],nhood,1);
           else v_code2rule(thisrule[cindex],thiscode[cindex],nhoodm[cindex],1);
        }
     }
    /*-------------------------------------------------------------*/ 
     /*show details in bottom window for "by hand"
       but not if all_remaining set automatic*/
    
     if (rulemix && all_remaining==0){
        if (tot_only==0){
	   if (value_range==2) z_parameter_all(nhoodm[cindex],0,thisrule[cindex]);
           else z_parameter_all_mvalue(nhoodm[cindex],0,thisrule[cindex]);
           post_func(nhoodm[cindex],thisrule[cindex], 0,0,0,0);
	}
        if (!(direction=='f' && limitcheck==0) || secondpart==0){
               if (one_cell==2){ /*one_cell=2 is for rule subset*/		  
		  if (totalistic==1){
                        memmove(cacode[0],thiscode[cindex],codebytes);
                        if (tot_only==1) /*just cacode*/ 
                            show_rule_bottom(nhood,0,cacode[0],0);
                  }
		  else if (totalistic==2){
                        memmove(v_code[0],thiscode[cindex],codebytes);
                        if (tot_only==1) /*just v_code*/ 
                           show_rule_bottom(nhood,0,v_code[0],0);
                  }
                  if (tot_only==0){ /*just rule + code or v_code*/ 
                        memmove(carule[0],thisrule[cindex],rulebytes);
		        show_rule_bottom(nhood,0,carule[0],0);
                  }
	       }
               else if (tot_only==0){
                   if (inbox==0) show_rule_bottom(nhoodm[cindex],
					     0,thisrule[cindex],cindex);
               }
               else if (tot_only==1){ 
                    if (inbox==0) show_rule_bottom(nhoodm[cindex],
                                             0,thiscode[cindex],cindex);
               }            
        }
     }
      /*-------------compute/show Post functions------------------*/
     /*if (tot_only==0) post_func(nhoodm[cindex], thisrule[cindex], 
                                              -1,-1,1,0,0);*/
     if (rulemix==0) break;

     /*to record the last k rule*/
     if (nhood_mixed && poss==Maxu){
       if (k_seen[(signed int)nhoodm[cindex]]==0){ 
            k_seen[(signed int)nhoodm[cindex]]=1;
       }
        /*record last k_rule set, if not copying automatically*/
       if (k_seen[(signed int)nhoodm[cindex]]!='a'){ 
             memmove(k_rule[(signed int)nhoodm[cindex]],
                   thiscode[cindex],codebytes);
       }
       
     }
  }/*next cellindex*/

  /* to show rcode immediately after tcode or kcode, to modify or transform to iso-rule,
     but this is not necessary because 'q' then option 'R' does equivalent*/
  /*
  if (inbox==0 && rulemix==0 && tot_only==0){ 
    //transform rule -> then code; transform_rule() not applicable to tot_only
    char k_changed=0;      
      tablemax= (signed int)pow(value_range,(double)nhoodm[0])-1;
       
      //show full carule to allow convertion to iso-rule, but not for unfinished rnd
      if (select!='r') define_bits(nhood,1,carule[0],tablemax,0);
     
      show_rule_bottom(nhoodm[0],0,carule[0],0);

      k_changed=transform_rule(0); //also saved here
      show_rule_bottom(nhoodm[0],0,carule[0],0);
      tablemax= (signed int)pow(value_range,(double)nhoodm[0])-1;	
      if (is[0]=='q' && k_changed==0) goto start;
  }
  */

  if (rulemix==0){
      if (tot_only==0){
        char temptot;
         temptot=totalistic; 
         totalistic=0;
         save_last_rule(carule[0],nhoodm[0]);
         totalistic=temptot;
      }
      if (totalistic==1) save_last_rule(cacode[0],nhoodm[0]);
      else if (totalistic==2) save_last_rule(v_code[0],nhoodm[0]);
      if (is[0]=='q') is[0]=0;
  }
  if (nhood_mixed && poss==Maxu){
     free(k_seen);
     for (z=1;z<=nhood;z++) free(k_rule[z]);
     free(k_rule);   
  }
  erase_prompt_box(2); 
  return(gety);
}

/**************** majority tcode, June 2004 *******************/
void majority_tcode(char *thistcode, char thisnhood, 
		               signed int tablecodemax){
  
           signed int zv,z;
           double vbins[8],blockv,temp_lower;
	    /*fprintf(stderr,"\ntablesize=%d value_range=%d",
	         tablecodemax+1,value_range);*/
            /*create value_range bins*/ 
            for (zv=0;zv<=value_range-1;zv++) vbins[zv]=0;
            blockv=((double)(tablecodemax+1))/value_range;
            vbins[0]=blockv;
            for (zv=1;zv<=value_range-1;zv++)
                 vbins[zv]=vbins[zv-1]+blockv;
            
            /*fprintf(stderr,"\n");
            for (zv=0;zv<=value_range-1;zv++)
	        fprintf(stderr,"%d:%f\n",zv,vbins[zv]);
	    fprintf(stderr,"\n");*/
            
            for (z=tablecodemax;z>=0;z--){
	        /*fprintf(stderr,"\n%d ",z);*/
                for (zv=value_range-1;zv>=0;zv--){
		    /*fprintf(stderr,"%d,",zv);*/
                    if (zv==0) temp_lower=-1;
                    else temp_lower=vbins[zv-1];
                    if (z<vbins[zv] && z>=temp_lower){
		        set_value(thistcode,z,zv);
                        /*fprintf(stderr," -> %d:%f:%d ",z,vbins[zv],zv);*/
			break;
                    }
                    
                }
            }
}

/**************** Altenberg rule for kcode May 2004  **************/
/*Lee Altenberg's random subset, set the output of each
      nhood in the rule table to a value, with prob of the frequency
      of that value in the nhood*/ 
void altenberg_kcode(char *thiskcode, char thisnhood, 
                                    signed int tablecodemax){       
     signed int v_bits,zz,z;
     unsigned int probv,tempv,scalev[8],beforev;
     char vfreq[8];

       v_bits=check_value_bits(thisnhood+1);
       for (zz=0;zz<=tablecodemax;zz++){
	    /*fprintf(stderr,"\n");*/
             for (z=0;z<=value_range-1;z++){
                vfreq[z]=get_value_flex(v_index[thisnhood][zz],z,v_bits);
	        /*fprintf(stderr,"%d ",vfreq[z]);*/
             }
             
             tempv=0;
             /*fprintf(stderr,"\n");*/
             for (z=0;z<=value_range-1;z++){
		tempv+=(1000*vfreq[z])/thisnhood;
                scalev[z]=tempv;
                /*fprintf(stderr,"%d ",scalev[z]);*/
             }
             /* |-----|--|---|-| intervals for v=3 
                    ^              probv point to one of them*/
             probv=myrand()%1000;
             /*fprintf(stderr,"(%d) ",probv);*/
             for (z=0;z<=value_range-1;z++){
		if (z==0) beforev=0;
                else  beforev=scalev[z-1];
		if (probv<scalev[z] && probv>=beforev){ 
                   set_value(thiskcode,zz,z);
                   /*fprintf(stderr,"%d-%d ",zz,z);*/
                   break;
                }
             }
       }
}


/************* set threshold and reaction-diffusion kcode  *************/
void set_reaction_diffusion_outer(char ex_color, char *thiskcode, 
                          char thisnhood, signed int tablecodemax){
       
     signed int v_bits,zz,lower_t,upper_t,total_ex,tempx,tempy;

       tempx=getx;
       tempy=gety;

      start_r:       
       lower_t=0;
       upper_t=thisnhood-1;
       draw_prompt_box(1);
       sprintf(textb[0],
	  "thresholds: lower (0-%d):",thisnhood);
       outtext(textb[0]);
       input_string(2,0);
       if (is[0]=='q') return;   
       if (atoi(is)>=0 && atoi(is)<=thisnhood) lower_t=atoi(is);
       sprintf(textb[0],
	  " upper (%d-%d):",lower_t, thisnhood);
       outtext(textb[0]);  
       input_string(2,0);
       if (is[0]=='q') goto start_r;
       if (atoi(is)>=lower_t && atoi(is)<=thisnhood) upper_t=atoi(is);

       v_bits=check_value_bits(thisnhood+1);

       for (zz=0;zz<=tablecodemax;zz++){
	    /*fprintf(stderr,"\n");*/
            total_ex=get_value_flex(v_index[thisnhood][zz],ex_color,v_bits);
            if (total_ex>=lower_t && total_ex<=upper_t)
	              set_value(thiskcode,zz,ex_color);
            else set_value(thiskcode,zz,0);
       }
       moveto(tempx,tempy);  
}


/**************** convert k code-table to rule-table **************/
void code2rule(char *ruletable, char *codetable, char this_nhood){
 signed int tablemax,zz,z,sod;

   tablemax= (signed int)pow(value_range,(double)this_nhood)-1;
   if (totalistic==1){
      for (zz=tablemax;zz>=0;zz--){       
	 sod=0;
         if (value_range==2){
	    for (z=this_nhood-1;z>=0;z--) sod+=get_bit(nm[z],zz);
	    set_bit(ruletable,zz,get_bit(codetable,sod));
         }
         else{
            for (z=this_nhood-1;z>=0;z--){
               sod+=get_value(nm[z],zz);
            }
	    set_value(ruletable,zz,get_value(codetable,sod));
           /*fprintf(stderr,"\n %d-%d-%d",zz,sod,get_value(codetable,sod));*/
         }
      }
   }   
}

/********* set majority or print v code-table, Aug 2002  ***********/
void majority_or_fprintf_vcode(char majority,
                  char *codetable, char this_nhood){
  signed int z,v_range,nhood_range,v_bits,
               majtot,majvalue,no_of_maj,count,pick_rand;
  unsigned int index;
  char *maj_tie;

     v_range=value_range;           
     if ((maj_tie=(char *)calloc(v_range,sizeof(char)))
                            ==NULL) outof_memory("maj_tie");
     nhood_range=this_nhood;
     v_bits=check_value_bits(nhood_range+1);
     for (index=0;index<=v_tablecodemax[this_nhood];index++){
        if (majority==0) fprintf(stderr,"\n%d: ",index);
        majtot=0;
        for (z=v_range-1; z>=0; z--){
           if (majority==0) fprintf(stderr,"%d ",
	      get_value_flex(v_index[this_nhood][index],z,v_bits));
           else if (majority==1){
              maj_tie[z]=0;
	      if (get_value_flex(v_index[this_nhood][index],z,v_bits)>majtot){
		 majtot=get_value_flex(v_index[this_nhood][index],z,v_bits);
                 majvalue=z;
              } 
           }
        } 
        if (majority==1){
	    no_of_maj=0;
            for (z=v_range-1; z>=0; z--){
	      if (get_value_flex(v_index[this_nhood][index],z,v_bits)
                                                             ==majtot){
		   maj_tie[z]=1;
                   no_of_maj+=1;
              }
	    } 
        }
        if (majority==0) fprintf(stderr," -> %d", 
                         get_value(codetable,index));
        else if (majority==1){
	   if (no_of_maj==1) /*one majority*/
                 set_value(codetable,index,majvalue);
           else{ /*majority tie, pick one at random*/
              pick_rand=myrand()%(no_of_maj+1);
	      count=-1;
              for (z=v_range-1; z>=0; z--){
                 if (maj_tie[z]==1){ 
                    count+=1;
                    if (count==pick_rand){
                        set_value(codetable,index,z);
                        break;
                    }
                 }
              }
	   }
        }  
     }                
     free(maj_tie); 
}


/********* swap 2 colors in vcode dynamics, Dec 2003  ***********/
void swap_values_vcode(char *codetable, char this_nhood){
  signed int z,v_range,nhood_range,v_bits,xbox;
  unsigned int index,swap_index,bytes_req;
  char *tickoff_v,*swap_v_index,first_v, second_v,
       inp[8],out1,out2; /* for search tree */

  /* first swap the outputs of v_groups 
     where the frequencies of the two values are swapped*/
  /* then swap the two output values in the lookup table*/

     v_range=value_range;             
     nhood_range=this_nhood;
     v_bits=check_value_bits(nhood_range+1);

     xbox=draw_prompt_box(2);  
     sprintf(textb[0],
		 "swap 2 values: enter first (0-%d):",v_range-1);
     outtext(textb[0]);
     input_string(1,0);
     if (atoi(is)<=v_range-1) first_v=atoi(is);
     else first_v=myrand()%v_range;
     moveto(xbox,gety+CHeight);
     sprintf(textb[0],
		 "first=%d, enter second (0-%d):",0,v_range-1);
     outtext(textb[0]);
     input_string(1,0);
     if (atoi(is)<=v_range-1 && atoi(is)!=first_v) 
                                          second_v=atoi(is);
     else second_v=abs(first_v-1);
     /*fprintf(stderr,"\n %d - %d",first_v,second_v);*/

     if ((tickoff_v=(char *)calloc(v_tablecodemax[this_nhood]+1,sizeof(char)))
					==NULL) outof_memory("tickoff");
     bytes_req=(unsigned int)ceil(v_bits*(double)value_range/8);            
     if ((swap_v_index=(char*)calloc(
                      bytes_req,sizeof(char)))
			  ==NULL) outof_memory("swap_v_index");    

     for (index=0;index<=v_tablecodemax[this_nhood];index++){           
           if (get_bit(tickoff_v,index)==1) continue;
           /*copy the kcode freq group*/
           memmove(swap_v_index,v_index[this_nhood][index],bytes_req);
           /*swap totals of first and second values*/
           set_value_flex(swap_v_index,first_v,
		get_value_flex(v_index[this_nhood][index],second_v,v_bits),v_bits);
           set_value_flex(swap_v_index,second_v,
		get_value_flex(v_index[this_nhood][index],first_v,v_bits),v_bits);

           for (z=v_range-1; z>=0; z--)
                    inp[(value_range-1)-z]=
                          get_value_flex(swap_v_index,z,v_bits); 

           swap_index=(unsigned int)search_tree(inp,(signed int)value_range,
                                            v_tree[this_nhood],0); 
           
           out1=get_value(codetable,index); 
           out2=get_value(codetable,swap_index);
	   set_value(codetable,index,out2);
           set_value(codetable,swap_index,out1);
 
           set_bit(tickoff_v,swap_index,1);
              
     }
     for (index=0;index<=v_tablecodemax[this_nhood];index++){ 
       if (get_value(codetable,index)==first_v)
                        set_value(codetable,index,second_v);
       else if (get_value(codetable,index)==second_v)
                        set_value(codetable,index,first_v);
     }
     erase_prompt_box(2);
     free(tickoff);
     free(swap_v_index);
}

/********* print v code-table, July 2003  ***********/
void fprintf_vcode(char code_lay, char *codetable, char this_nhood){
  signed int z,v_range,nhood_range,v_bits;
  unsigned int index;

     v_range=value_range;             
     nhood_range=this_nhood;
     v_bits=check_value_bits(nhood_range+1);
     if (code_lay==0){
           //for (index=0;index<=v_tablecodemax[this_nhood];index++){
           //start with max index on top 
           for (index=v_tablecodemax[this_nhood];index!=Maxu;index--){
           fprintf(stderr,"\n%4d: ",index);
           for (z=v_range-1; z>=0; z--){
             fprintf(stderr,"%d ",
	      get_value_flex(v_index[this_nhood][index],z,v_bits));
           } 
           fprintf(stderr," -> %d", 
                         get_value(codetable,index));      
        }
     }
     if (code_lay==1){
        for (z=v_range-1; z>=0; z--){
           fprintf(stderr,"\n%d:",z);
           for (index=v_tablecodemax[this_nhood];index!=Maxu;index--){ 
              fprintf(stderr,"%d",
	         get_value_flex(v_index[this_nhood][index],z,v_bits));
           }
        }
        fprintf(stderr,"\n  ");
        for (index=v_tablecodemax[this_nhood];index!=Maxu;index--){ 
            fprintf(stderr,"|");
        }
        fprintf(stderr,"\n  ");
        for (index=v_tablecodemax[this_nhood];index!=Maxu;index--){ 
            fprintf(stderr,"%d", get_value(codetable,index));
        }
     }
     if (code_lay==2 && value_range==3){ /*matrix layout*/
	char matrix_ij=0, starti;
        fprintf(stderr,"\n");
        starti=this_nhood;
        for (index=0;index<=v_tablecodemax[this_nhood];index++){
	   
           fprintf(stderr,"%d ", 
                         get_value(codetable,index));
           matrix_ij++;
           if (matrix_ij>starti){ 
              fprintf(stderr,"\n");
	      matrix_ij=0;
              starti--;
           }      
        }
     }
}

/********* convert rule-table to v code-table, March  2003  ***********/
void v_code2rule(char *ruletable, char *codetable,char this_nhood, char c2r){
     signed int z,zz,this_value,tablemax;
     char *v_freq,*v_freq_null;
     unsigned int u;

      tablemax= (signed int)pow(value_range,(double)this_nhood)-1;
      
      if ((v_freq=(char*)calloc(value_range,sizeof(char)))
					==NULL) outof_memory("v_freq");
      if ((v_freq_null=(char*)calloc(value_range,sizeof(char)))
				   ==NULL) outof_memory("v_freq_null");
      /*fprintf(stderr,"\nv_code2rule(%d) v=%d k=%d tablemax=%d\n",
	                       c2r,value_range,this_nhood,tablemax);*/
      if (c2r==1){
         for (zz=tablemax;zz>=0;zz--){
	   /*fprintf(stderr,"\n%d:",zz); */
	    memmove(v_freq,v_freq_null,value_range); /*reset v_freq to null*/  
            for (z=this_nhood-1;z>=0;z--){
	       /*store the v_totals in each nhood*/
	       this_value=get_value(nm[z],zz);
               /*v_freq[this_value]+=1;*/ /*antonio's order*/
               v_freq[(value_range-1)-this_value]+=1;	    
             }
	     /*for (z=0;z<=value_range-1;z++) fprintf(stderr,"%d-",v_freq[z]);*/
             u=(unsigned int)search_tree(v_freq,(signed int)value_range,
                                            v_tree[this_nhood],0);
             /*fprintf(stderr,"=%d:->%d",u,get_value(ruletable,zz));*/             
             /*vcode to rule*/
             set_value(ruletable,zz,get_value(codetable,u));
         }
      }
      /*rule -> code*/
      /*NOTE: an equivalent k+ rule wont translate to an equivalent
              k+ code. To try to approximate, do left 1/2 ->, 
	      then right 1/2 <- , and dont overwrite
              This is improved in transform_rule() by copying the
              left and right ends of the original v_code*/

      if (c2r==0){
        unsigned long u_tickoffbytes;
        char *u_tickoff;
        signed int left_table,right_table;

         u_tickoffbytes=(unsigned long)ceil((double)(v_tablecodemax[nhood]+1)/8);
         if ((u_tickoff=(char *)calloc(u_tickoffbytes,sizeof(char)))
	                                       ==NULL) outof_memory("u_tickoff");
         /*fprintf(stderr,"\n");*/
         /*divide rule-table in two*/
         left_table=(tablemax+1)/2;
         right_table=(tablemax+1)-left_table;
         for (zz=tablemax;zz>=left_table;zz--){
	    /*fprintf(stderr,"\n%d:",zz);*/
            memmove(v_freq,v_freq_null,value_range); /*reset v_freq to null*/  
            for (z=this_nhood-1;z>=0;z--){
	       /*store the v_totals in each nhood*/
	       this_value=get_value(nm[z],zz);
               v_freq[(value_range-1)-this_value]+=1;	    
             }
	     /*for (z=0;z<=value_range-1;z++) fprintf(stderr,"%d-",v_freq[z]);*/
             u=(unsigned int)search_tree(v_freq,(signed int)value_range,
                                            v_tree[this_nhood],0);    
             /*if u was found before, dont overwrite*/
             if (get_bit(u_tickoff,u)==0){ 
	        /*fprintf(stderr,"=%d:->%d",u,get_value(ruletable,zz));*/
                /*rule to vcode*/
                set_value(codetable,u,get_value(ruletable,zz));
             }
             set_bit1(u_tickoff,u);
         }
	 free(u_tickoff);
         if ((u_tickoff=(char *)calloc(u_tickoffbytes,sizeof(char)))
	                                       ==NULL) outof_memory("u_tickoff");
         /*fprintf(stderr,"\n");*/
         for (zz=0;zz<=right_table-1;zz++){
	    /*fprintf(stderr,"\n\%d:",zz);*/
            memmove(v_freq,v_freq_null,value_range); /*reset v_freq to null*/  
            for (z=this_nhood-1;z>=0;z--){
	       /*store the v_totals in each nhood*/
	       this_value=get_value(nm[z],zz);
               v_freq[(value_range-1)-this_value]+=1;	    
             }
	     /*for (z=0;z<=value_range-1;z++) fprintf(stderr,"%d-",v_freq[z]);*/
             u=(unsigned int)search_tree(v_freq,(signed int)value_range,
                                            v_tree[this_nhood],0);
             /*if u was found before, dont overwrite*/
             if (get_bit(u_tickoff,u)==0){ 
	        /*fprintf(stderr,"=%d:->%d",u,get_value(ruletable,zz));*/
                /*rule to vcode*/
                set_value(codetable,u,get_value(ruletable,zz));
             }
             set_bit1(u_tickoff,u);
         }
         free(u_tickoff);
      }
      /*fprintf(stderr,"\n v_tablecodemax[%d]=%d\n",
	this_nhood,v_tablecodemax[this_nhood]);
      for (zz=v_tablecodemax[this_nhood];zz>=0;zz--)
	   fprintf(stderr,"%d",get_value(codetable,zz));
      fprintf(stderr,"\n");*/
      free(v_freq);
      free(v_freq_null);
}

/************************* revise one rule, 5 June 1994 **************/
void revise_rule_or_code(unsigned int thisposs){
 float oldxtext;
 char temp_totalistic;

   temp_totalistic=totalistic;
   if (tot_only==0){
      totalistic=0;
      /*allocate_mem_diffrules(nhoodm[thisposs],1);*/
   }
   /*else allocate_mem_diffcodes(nhoodm[thisposs],1);*/
   draw_box(5,trboxw,vgay(343),Maxx-2,Maxy,1,0);
   moveto(trboxw+3,vgay(345));
   if (tot_only==0){
      outtext("totalistic: tcode-t kcode-k (rule-def):");
      input_string(1,0);
      totalistic=0;
      if (is[0]=='t') totalistic=1; /*add up absolute total in nhood*/
      else if (is[0]=='k') totalistic=2; /*add up total of each value*/
   }
   moveto(trboxw+3,vgay(345)-CHeight);
   
   oldxtext=xtext;
   xtext=(float)(trboxw+3)/CWidth;

   /*fprintf(stderr,"\n tot=%d thisposs=%d",totalistic,thisposs);*/
   if (totalistic==0){
      if (rulemix) select_rule(1,1,carule,1,thisposs,0);
      else select_rule(1,1,carule,1,Maxu,0);
   }
   else{
      if (totalistic==1){
         if (rulemix || (outer_tot==1 && thisposs<value_range)) 
                    select_t_v_code(1,1,cacode,carule,1,thisposs,0);
         else select_t_v_code(1,1,cacode,carule,1,Maxu,0);
      }
      else if (totalistic==2){
         if (rulemix || (outer_tot==1 && thisposs<value_range)) 
                    select_t_v_code(1,1,v_code,carule,1,thisposs,0); 
         else select_t_v_code(1,1,v_code,carule,1,Maxu,0);
      }
   }
   xtext=oldxtext;
   sprintf(textb[9],"%s","boximage[5]"); 
   putimage(trboxw,vgay(343),boximage[5],COPY_PUT,textb[9]);
   freeimage(boximage[5]);
   if (tot_only==0){
      if (value_range==2) 
           z_parameter_all(nhoodm[thisposs],0,carule[thisposs]);
      else z_parameter_all_mvalue(nhoodm[thisposs],0,carule[thisposs]);
   }
   totalistic=temp_totalistic;
   is[0]=0;
}

/********* specify initial (seed) state, 13 May 1993 *****************/
signed int select_seed(char box_top_only, 
                   char *thisseed, char *text, char restore_box){

  char seedset,select,wasrandom=0,seed_box_changed=0,
       thisdim,bigdim,was_filled=0;
 float tempxtext;
 signed int temp,lineno, bigaxis,
     startx,starty,tempx2,tempy2,temp2,
     rightbox,mes_width,width_req,bottombox;
 unsigned int zu,startseg,endseg,maxseglen;
         /*blockx,blocky,blockzz,global variables, was seglen*/
 unsigned long seed,state_dec_max; /*=decimal eq. of CA seed*/
 float bias_density;
  
 #  define clearspace(possx,possy){\
      setfillstyle(SOLID_FILL,black);\
      bar(possx-1,possy+2,rightbox-1,bottombox-1);\
      moveto(possx,possy);\
    }

   erase_memory_box(2); //to erase memory_box while backtracking 
   startx=getx;

   /* learn -- remove this ??
   if (oned){ //to select 1d bit seed in 2d
      i2d=(signed int)ceil(pow((double)lineL,.5));
      j2d=(signed int)ceil((double)lineL/i2d);
   }
   if (memcmp(text,"targ",4)==0) showbits_1d_as_2d=1;
   */

   set_cellscale(nhood,0);

   width_req=Maxx*.52; /*to fit hex*/
   if (oned) mes_width=CWidth*6+cellscale*lineL/foldposs;
   else if (twod) mes_width=CWidth*6+cellscale*i2d;
   else if (threed) mes_width=CWidth*6+cellscale*i3d;
   if (mes_width>width_req) width_req=mes_width;

   /*default central block*/
   if (oned){
            thisdim=1;
            if (lineL<=5) blockx=lineL;
            else if (lineL<=20) blockx=lineL/2;
            else blockx=lineL/5;
            bigdim='i';
            bigaxis=lineL;
            seglen=blockx;
   }
   if (twod){
            thisdim=2;                
            if (i2d<=5) blockx=i2d;
            else if (i2d<=20) blockx=i2d/2;
            else blockx=i2d/5;
            bigdim='i';
            bigaxis=i2d;
            seglen=blockx;
            if (j2d<=5) blocky=j2d;
            else if (j2d<=20) blocky=j2d/2;
            else blocky=j2d/5;
            if (j2d>i2d){
               bigdim='j';
               bigaxis=j2d;
               seglen=blocky;
            }
   }
   else if (threed){ 
            thisdim=3;
            if (i3d<=5) blockx=i3d;
            else if (i3d<=20) blockx=i3d/2;
            else blockx=i3d/5;
            bigdim='i';
            bigaxis=i3d;
            seglen=blockx;
            if (j3d<=5) blocky=j3d;
            else if (j3d<=20) blocky=j3d/2;
            else blocky=j3d/5;
            if (j3d>i3d){
               bigdim='j';
               bigaxis=j3d;
               seglen=blocky;
            }
            if (h3d<=5) blockz=h3d;
            else if (h3d<=20) blockz=h3d/2;
            else blockz=h3d/5;
            if (h3d>j3d && h3d>i3d){
               bigdim='h';
               bigaxis=h3d;
               seglen=blockz;
            }
   }
   /*if (bigaxis>=3){
      if (bigaxis%2==0 && seglen%2==1) seglen-=1; //even
      else if (bigaxis%2==1 && seglen%2==0) seglen-=1; //odd
   }*/

startseed_box:
   /*bias_density=% density of non-zero values for random string, may be changed*/
   bias_density=bias_density_seed;
   rightbox=startx-3+width_req;
   
   tempxtext=xtext;
   if (restore_box) xtext=((float)startx/CWidth);
  
   bottombox=Maxy-vgay(33);
   starty=bottombox-height_req_seed_win;
   if (box_top_only==1){
      xtext=tempxtext;
      return(starty);
   }
   /*draw_box(12,startx-3,starty,rightbox,bottombox,1,0);*/
   draw_box(12,startx-3,starty,Maxx,bottombox,0,-1); /*just save the area up to Maxx*/
   setcolor(lightred);
   rectangle(startx-3,starty,rightbox,bottombox);

   setviewport(startx-3,starty,rightbox,bottombox-1,1);
   note_viewport;
   setviewport(0,0,Maxx,Maxy,0);

   setting_seed=1;
 
   /* learn -- remove this ??
   if (memcmp(text,"SEED",4)==0) showbits_1d_as_2d=0;*/

   state_dec_max=0;
   state_dec_max=max_dec_rule(lineL-1,value_range);
   /*check if a seed exists, if so setting bits is default*/
   
 start:
   setcolor(white); /*make prompt visible*/   
   clearspace(startx,starty);

   seedset=0;
   for (zu=0;zu<=bytesL-1;zu++){
      if (thisseed[zu]>=1){
         seedset=1;
         break;
      }
   }

   if (was_filled==1) seedset=1;  
   if (seedset) sprintf(textb[2],"(def-b)");
   else sprintf(textb[2],"(def-r)");
   if (memcmp(text,"targ",4)==0 || memcmp(text,"aspi",4)==0){
      /*from learning*/
     if (oned) sprintf(textb[2],"(def-B)");
     else sprintf(textb[2],"(def-b)");
   } 
   was_filled=0;
   /*skip for order seed*/
   if (memcmp(text,"order",5)==0) sprintf(textb[4]," ");
   else if (oned) sprintf(textb[4],"(v%d 1d n=%d)",value_range,lineL);
   else if (twod) sprintf(textb[4],"(v%d 2d ij=%d,%d)",
                                                 value_range,i2d,j2d);
   else if (threed) sprintf(textb[4],"(v%d 3d ijh=%d,%d,%d)",
                                              value_range,i3d,j3d,h3d);
   if (state_dec_max>0 /*&& state_dec_max!=Maxlu*/) sprintf(textb[5]," dec-d ");
   if (state_dec_max>0) sprintf(textb[5]," dec-d ");
   else sprintf(textb[5]," ");

   if (memcmp(text,"order",5)==0){ /*for order seed*/
      sprintf(textb[0], 
       "Select %s  prtx-x",text);
      sprintf(textb[1],
       "rnd-r bits1d-b bits2d-B hex-h%s(def-d):",textb[5]);
   }
   else if (twod){
      if (value_range==2) sprintf(textb[0],
           "Select %s %s win-w empty-e fill-f prtx-x ascii-v Golly-G",text,textb[4]);
      else sprintf(textb[0],
           "Select %s %s win-w empty-e fill-f prtx-x ascii-v",text,textb[4]);
      sprintf(textb[1],
         "rnd-r bits2d-b hex-h%srepeat-p load-l %s:",textb[5],textb[2]);
   } 
   else if (threed){
      sprintf(textb[0],
        "Select %s %s win-w empty-e fill-f prtx-x ascii-v",text,textb[4]);
      sprintf(textb[1],
        "rnd-r bits2d+3d-b hex-h%srepeat-p load-l %s:",textb[5],textb[2]);
   }
   else{
      sprintf(textb[0],
        "Select %s %s win-w empty-e fill-f prtx-x ascii-v",text,textb[4]);
      sprintf(textb[1],
	"rnd-r bits1d-b bits2d-B hex-h%srepeat-p load-l %s:",textb[5],textb[2]);
   }

   outtext(textb[0]);
   next_line(xtext,1);
   outtext(textb[1]);
   input_string(1,0);

   if (is[0]=='q') goto endFunc;

   if (is[0]=='x'){
     char temp_pdata,temp_filedata;
     unsigned int xcount;
      fprintf(stderr,"\n");
      temp_pdata=pdata;
      temp_filedata=filedata;
      pdata=1;
      filedata=0;
      print_current_bitstring_hexbytes(0,0,thisseed,nhood,Maxx,white,3);
      pdata=temp_pdata;
      filedata=temp_filedata;
      xcount=0;
      fprintf(stderr,"\n");
      for (zu=lineL-1;zu!=Maxu;zu--){
         fprintf(stderr,"%d",get_value(thisseed,zu));
	 xcount+=1;
         if (twod && xcount%i2d==0) fprintf(stderr,"\n");
         else if (threed){
	    if (xcount%i3d==0) fprintf(stderr,"\n");
            if (xcount%(i3d*j3d)==0) fprintf(stderr,"\n");
         }
	 
      }
      seed_box_changed=1;
      goto endFunc;
   }

   if (is[0]=='w'){  /*resize seed box*/
      seed_box_changed=0;      
      next_line(xtext,1);
      sprintf(textb[0],
               "change window size (max-m), width (now %d):",width_req);
      outtext(textb[0]);
      input_string(4,0);
      if (is[0]==13);
      else if (is[0]=='m' || atoi(is)>=Maxx-2-(startx-3)) 
                   width_req=Maxx-2-(startx-3);
      else if (atoi(is)>=50) width_req=atoi(is);


      sprintf(textb[0]," height (now %d):",height_req_seed_win);
      outtext(textb[0]);
      input_string(4,0);
      if (is[0]==13);
      else if (is[0]=='m' || atoi(is)>=bottombox) 
                   height_req_seed_win=bottombox-2;
      else if (atoi(is)>=50) height_req_seed_win=atoi(is);
      seed_box_changed=1;
      goto endFunc;
   }
   select=is[0];
   /* defaults */
   if (select!='e' && select!='f' && select!='v' && select!='G' && select!='b' && select!='B' &&
       !(select=='d' && state_dec_max>0 /*&& state_dec_max!=Maxlu*/) 
                            && select!='h' && select!='p' && 
                                 select!='r' && select!='l' && select!='t'){
         if (memcmp(text,"targ",4)==0 || memcmp(text,"aspi",4)==0){
            /*from learning*/
            if (oned) select='B';
            else select='b';
         } 
	 else if (seedset){
             if (twod || threed) select='B';
             else select='b';
         }
         else if (memcmp(text,"order",5)==0) select='d'; 
         else select='r';
   }

   if (select=='e'){
      memmove(thisseed,all_0s,bytesL);
      was_filled=1; /*filled with zeros*/
      goto start;
   }
   else if (select=='f'){ /*fill with chosen value*/
      if (value_range>2){
         draw_prompt_box(1);
         sprintf(textb[0],"fill with value 0-%d:",value_range-1);
         outtext(textb[0]);
         input_string(1,0);
         temp=atoi(textb[0]);
      }
      else temp=1;
      if (temp>=0 && temp<=value_range-1){
	for (zu=0;zu<=L;zu++) set_value(thisseed,zu,temp);
      }
      was_filled=1; /*filled with selected value*/              
      goto start;
   }
   else if (select=='r'){
     char hex;
      hex=0; /*was hex=1, but showing hex not necessary*/     
      next_line(xtext,1);
      tempx2=getx;
      tempy2=gety;

      if ((memcmp(text,"order",5)==0) || seglen<3){
	 random_bits(nhood,0,1,hex,thisseed,L);
	 if (is[0]=='q'){
	    clearspace(tempx2,tempy2);
	    goto start;
	 }
      }

      else{
	 if (oned==1) sprintf(textb[0],
	      "central %dd block (def diam %d) all-a (max %d):",
		                                  thisdim,seglen,bigaxis);
         else if (twod==2) sprintf(textb[0],
	      "central %dd block (def diam %d) rectangle-s all-a (max %d):",
		                                  thisdim,seglen,bigaxis);
         else if (threed==3) sprintf(textb[0],
	      "central %dd block (def diam %d) cuboid-s all-a (max %d):",
		                                  thisdim,seglen,bigaxis);
	 outtext(textb[0]);

	 sprintf(textb[0],"%d",lineL);
	 input_string(strlen(textb[0]),0);

         if (is[0]=='q'){
	    clearspace(tempx2,tempy2);
            goto start;
	 }

	 if (is[0]=='a'){
            blockx=blocky=blockz=0;
	    if (oned) blockx=lineL;
	    else if (twod){ 
                blockx=i2d;
                blocky=j2d;
            }
	    else if (threed){
                blockx=i3d;
                blocky=j3d;
                blockz=h3d;
            }
            random_bits(nhood,0,1,hex,thisseed,L);
         }

         else if (is[0]!='s' && is[0]!=13 && atoi(is)>=1 && atoi(is)<=bigaxis){
           char non_equal=0;
	    if (oned)  blockx=atoi(is);
            else if (twod){ 
               if (i2d==j2d) blockx=blocky=atoi(is);
               else non_equal=1;
            }
            else if (threed){
	       if (i3d==j3d && j3d==h3d) blockx=blocky=blockz=atoi(is);
               else if (i3d==j3d) blockx=blocky=atoi(is);
               else if (i3d==h3d) blockx=blockz=atoi(is);
               else if (j3d==h3d) blocky=blockz=atoi(is);
               else non_equal=1;
            }
            if (non_equal==1){
	       if (bigdim=='i') blockx=atoi(is);
               else if (bigdim=='j') blocky=atoi(is);
               else if (bigdim=='h') blockz=atoi(is);
            }       
            random_bits(nhood,0,0,hex,thisseed,L);
         }

         else if (is[0]=='s' && (twod==2 || threed==3)){
            if (twod || threed==3){
               next_line(xtext,1);
	       if (twod){
		  sprintf(textb[0],"rectangle: x(max %d, def %d):",i2d,blockx);
                  outtext(textb[0]);
                  sprintf(textb[1],"%d",i2d);          
                  input_string((signed int)strlen(textb[1]),0);
                  if (atoi(is)>0 && atoi(is)<=i2d) blockx=atoi(is);
                  sprintf(textb[0],"  y(max %d, def %d):",j2d,blocky);
                  outtext(textb[0]);
                  sprintf(textb[1],"%d",j2d);          
                  input_string((signed int)strlen(textb[1]),0);          
                  if (atoi(is)>0 && atoi(is)<=j2d) blocky=atoi(is);
               }
	       else if (threed){
		  sprintf(textb[0],"cuboid: x(max %d, def %d):",i3d,blockx);
                  outtext(textb[0]);
                  sprintf(textb[1],"%d",i3d);          
                  input_string((signed int)strlen(textb[1]),0);
                  if (atoi(is)>0 && atoi(is)<=i3d) blockx=atoi(is);
                  sprintf(textb[0],"  y(max %d, def %d):",j3d,blocky);
                  outtext(textb[0]);
                  sprintf(textb[1],"%d",j3d);          
                  input_string((signed int)strlen(textb[1]),0);          
                  if (atoi(is)>0 && atoi(is)<=j3d) blocky=atoi(is);
                  sprintf(textb[0],"  z(max %d, def %d):",h3d,blockz);
                  outtext(textb[0]);
                  sprintf(textb[1],"%d",h3d);          
                  input_string((signed int)strlen(textb[1]),0);          
                  if (atoi(is)>0 && atoi(is)<=h3d) blockz=atoi(is);
               }            
	    }      
            random_bits(nhood,0,0,hex,thisseed,L);
         }
         else random_bits(nhood,0,0,hex,thisseed,L);

	 if (is[0]=='q'){
            select='b';
            seedset=1;
	    clearspace(tempx2,tempy2);
	    goto start;
	 } 
      }
   }
  
   else if (select=='l' && memcmp(text,"order",5)!=0){      
      load_save_wrs('l',thisseed,'s');      
      if (is[0]=='q') goto start;
      next_line(xtext,1.5);
      if (state_dec_max>0 /*&& state_dec_max!=Maxlu*/){
	   seed=dec_equiv(thisseed,L);
	   sprintf(textb[0],"(dec) %lu, ",seed);
	   outtext(textb[0]);
      }
      if (L<16*16-1){
	   outtext("(hex)");
	   lineno=print_current_bitstring_hexbytes(0,0,thisseed,0,rightbox,white,0);
	   next_line(xtext,lineno+3);
      }
      define_bits(nhood,0,thisseed,L,0);     
      if (is[0]=='q') goto start;
      
   }
   else if (select=='b' || (select=='B' && (twod || threed))){
    signed int byte_size;
    unsigned int bit_seglen;

      maxseglen=lineL; /*define segment of ca as bitstring*/
      next_line(xtext,1);
      tempx2=getx;
      tempy2=gety;

     startb:
      if (oned){
	 startseg=lineL; /*bigger than L for def startseg*/
	 sprintf(textb[0],
	       "segment: enter length (max/def=%d):",
	 					  maxseglen);
	 outtext(textb[0]);
	 sprintf(textb[0],"%d",maxseglen);
	 input_string(strlen(textb[0]),1);

	 if (is[0]=='q') goto start;
	 bit_seglen=atol(is);

	 if (bit_seglen>=maxseglen || is[0]==13) bit_seglen=maxseglen;
	 if (bit_seglen<maxseglen){
            next_line(xtext,1);
	    sprintf(textb[0],
		"seglength %d: enter start position from left 0-%d, def centred: ",
                                              bit_seglen,L);	    
	    outtext(textb[0]);
	    sprintf(textb[0],"%d",L);
	    input_string(strlen(textb[0]),1);

	    if (is[0]=='q'){
	       clearspace(tempx2,tempy2);
	       goto startb;
	    }
            if (is[0]!=13) startseg=atol(is);
	 }
         if (startseg<=L) startseg=L-startseg;
         else if (startseg>L || is[0]==13) startseg=(L/2)+(bit_seglen/2);
         if (startseg>bit_seglen) endseg=startseg-bit_seglen+1;
         else endseg=0;
	 define_bits(nhood,0,thisseed,startseg,endseg);
	 if (is[0]=='q'){
	    clearspace(tempx2,tempy2);
            setcolor(white);
	    goto startb;
	 }
      }
      else{ /*2d or 3d*/
	 startseg=L;
	 endseg=0;
	 define_bits(nhood,0,thisseed,startseg,endseg);
	 if (is[0]=='q') goto start;
      }
      if (state_dec_max>0 /*&& state_dec_max!=Maxlu*/){
	 seed=dec_equiv(thisseed,L);
         next_line(xtext,1);
	 sprintf(textb[0]," (dec)%lu",seed);
	 outtext(textb[0]);
      }

      /*showing hex not necessary*/
      /*for small strings (byte_size<=64) show hex*/
      /*byte_size=(signed int)ceil( (double)(lineL*value_bits)/8);
      if (byte_size<=64){
         next_line(xtext,1);
         outtext("(hex)");
	 lineno=print_current_bitstring_hexbytes(0,0,thisseed,0,rightbox,white,0);
	 next_line(xtext,lineno+1);
      }*/
   }
   else if (select=='B' && oned){
     signed int byte_size;

      if (oned){
         showbits_1d_as_2d=1;
         set_i2dxj2d();
         if (i2d==0){
            i2d=lineL;
            j2d=1;
         }
      }
      sprintf(textb[0],"now %dx%d, reset i-axis:",i2d,j2d);
      next_line(xtext,1);
      outtext(textb[0]);
      input_string(4,0);
      if (is[0]=='q'){
         if (oned) showbits_1d_as_2d=0;
         goto start;
      }
      if (is[0]==13);
      else if (atoi(is)>0 && atoi(is)<=lineL){
	 i2d=atoi(is);
	 j2d=(signed int)ceil((double)lineL/i2d);
      }

      maxseglen=lineL; /*define segment of ca as bitstring*/
      next_line(xtext,1);
      tempx2=getx;
      tempy2=gety;

      startseg=L;
      endseg=0;
      
      define_bits(nhood,0,thisseed,startseg,endseg);      

      if (is[0]=='q'){
         if (oned) showbits_1d_as_2d=0;
	 goto start;
      }
      if (state_dec_max>0 /*&& state_dec_max!=Maxlu*/){
	 seed=dec_equiv(thisseed,L);
	 sprintf(textb[0]," (dec)%lu ",seed);
	 outtext(textb[0]);
      }

      /*showing hex not necessary*/
      /*for small strings (byte_size<=64) show hex*/
      /*byte_size=(signed int)ceil( (double)(lineL*value_bits)/8);
      if (byte_size<=64){
         next_line(xtext,1);
	 lineno=print_current_bitstring_hexbytes(0,0,thisseed,0,rightbox,white,0);
	 next_line(xtext,lineno+1);
      }*/

      /* learn -- remove this ??
      if (oned) showbits_1d_as_2d=0;*/
   }

   else if (select=='d' /*&& state_dec_max>0*/){ /*enter as dec*/    
      if (scale>2) sep=2;
      else sep=1; /*1..no division between cells, 2..1 pix black div*/

	 next_line(xtext,1);
	 tempx2=getx;
	 tempy2=gety;
         if (memcmp(text,"order",5)==0)
            sprintf(textb[0],"decimal seed, enter 0-%lu (def-rnd-dec):",
		                                            statespace);
	 else sprintf(textb[0],"decimal seed, enter 0-%lu (def-rnd-dec):",
		 (unsigned long) pow(value_range,(double)lineL)-1);
	 outtext(textb[0]);
         sprintf(textb[0],"%lu",state_dec_max);
         input_string(strlen(textb[0]),1);

	 if (is[0]=='q') goto start;
         if (memcmp(text,"order",5)==0 && is[0]==13) seed=myrand()%(statespace);
         else if (is[0]==13) seed=myrand()%(state_dec_max);
         else seed=atolu(is);/*string->unsigned long*/

         /*convert dec to valuestring*/
         if ( (memcmp(text,"order",5)==0 && seed<=statespace)
               || (memcmp(text,"order",5)!=0 && seed<=state_dec_max)){
            if (is[0]!=13)  seed=atolu(is);/*string->unsigned long*/
            else{
	       sprintf(textb[0]," %lu",seed);
	       outtext(textb[0]);
            }
            next_line(xtext,1);
	    if (value_range==2) dec_to_bit_line(thisseed,seed,lineL);
            else dec_to_value_line(thisseed,seed,lineL);
            define_bits(nhood,0,thisseed,L,0);            
         }
         else{
            setcolor(red); 
	    outtext(" - too big! back-ret:");
            setcolor(white); 
            input_string(1,0);
            select='d';
            goto start;
	 }
   }
   else if (select=='h'){  /*enter as hex*/
      tempx2=getx;
      tempy2=gety;

      /*bytes required from max--0*/
      temp2=(unsigned int)ceil((double)(lineL*value_bits)/8);
      /*draw boxes, input hex*/
      define_hex(nhood,0,thisseed,temp2-1,0,xtext);
      if (is[0]=='q') goto start;

      /*no of extra bits/values on left (if any) - set these zero*/
      temp= (temp2/value_bits)*8-lineL;
      /*fprintf(stderr,"\n extra values=%d\n",temp);*/
      if (temp>0){
	if (value_range==2){
	    for (zu=temp+lineL-1;zu>=lineL;zu--) set_bit0(thisseed,zu);
	}
        else{
            for (zu=temp+lineL-1;zu>=lineL;zu--) set_value(thisseed,zu,0);
        }
      }
      /*after define_hex -- define_bits -- keep hex visible though partly covered*/  
      moveto(tempx2,tempy2);
      next_line(xtext,1.3);
      /*setfillstyle(SOLID_FILL,black);
      bar(getx-1,gety,rightbox-1,bottombox-1);*/     
      define_bits(nhood,0,thisseed,L,0);
   }

   /*repeat last seed*/
   else if (select=='p' && memcmp(text,"order",5)!=0){
       next_line(xtext,1.5);
       define_bits(nhood,0,thisseed,L,0);
   }

   if ( (memcmp(text,"order",5)!=0) &&
        memcmp(text,"SEED",4)!=0 && (select=='r'|| wasrandom==1)){
      wasrandom=0;
      if (lineL<=(unsigned int)pow(2,(double)8)){
	 next_line(xtext,.5);
	 lineno=print_current_bitstring_hexbytes(0,0,thisseed,0,rightbox,white,0);
	 next_line(xtext,lineno+1);
      }
   }
   
   if (memcmp(text,"order",5)==0){
      seed=dec_equiv(thisseed,L);
      //if (seed>fact((char)templineL)-1){
      if (seed>statespace){
	 next_line(xtext,2);
	 sprintf(textb[2],
            "order index %lu > max (%lu) cont-ret:",
		 seed,statespace);
	 outtext(textb[2]);
	 input_string(1,0);
	 memmove(thisseed,all_0s,bytesL);
	 goto start;
      }   
   }
   else if (select=='v'){ /*load/save ascii value seed*/
     signed int tempx,tempy; 
        tempx=getx;
        tempy=gety;
        draw_prompt_box(1);      
	sprintf(textb[0],"ASCII seed (v=%d n=%d) load/save-l/s:",
		                            value_range,lineL);
        outtext(textb[0]);
        input_string(1,0);
        if (is[0]=='l' || is[0]=='s'){
           load_save_ascii_rule_seed(is[0],'s',thisseed,lineL);
        }
        erase_prompt_box(1);
        moveto(tempx,tempy);
        goto start;
    }
    else if (select=='G' /*load/save Golly ascii value seed*/
           && value_range==2 && twod){ 
     signed int tempx,tempy; 
        tempx=getx;
        tempy=gety;
        draw_prompt_box(1);      
	sprintf(textb[0],"Golly ascii seed (v=%d, base ij=%dx%d) load/save-l/s:",
		value_range,i2d,j2d);
        outtext(textb[0]);
        input_string(1,0);
        if (is[0]=='l' || is[0]=='s'){
	    load_Golly_seed(is[0],thisseed,lineL);
        }
        erase_prompt_box(1);
        moveto(tempx,tempy);
        goto start;
    }    

   /*save seed with selected filename or automatically*/
   if (select!='l' && dont_save==0){         
     unsigned int this_density=0,cellcount;
     signed int xbox;

      setcolor(white);
      /*show density etc*/
      for (cellcount=0;cellcount<=lineL-1;cellcount++){
	   if (get_value(thisseed,cellcount)>0) this_density++;
      }
        
      xbox=draw_prompt_box(2);
      if (value_range==2) sprintf(textb[1],"density 1s=");
      else sprintf(textb[1],"density %d-1s=",value_range-1); 
      sprintf(textb[0],"%s%d/%d=%.3f%%, bias=%.3f%%",
                textb[1], this_density,lineL,
                       100*(float)this_density/lineL,bias_density_seed);
      outtext(textb[0]);
      moveto(xbox,gety+CHeight);
           
      sprintf(textb[0],"SEED: revise-q save-s cont-ret:");
      outtext(textb[0]);
      input_string(1,0);
      erase_prompt_box(2);
      if (is[0]=='q') goto start;      
      if (is[0]=='s') load_save_wrs('s',thisseed,'s');      
      else{	
        /*save seed automatically with default filename myseed.eed*/
	unsigned char *seed_buf;
	signed int fid;
	unsigned long buffreq;
	
	buffreq=5+bytesL;
        /*buffer required to store bytes*/
        sprintf(textb[0],"seed_buf, buffreq=%lu, calloc failed",buffreq);
        if ((seed_buf=(unsigned char *)calloc(buffreq,sizeof(unsigned char)))
				 ==NULL) outof_memory(textb[0]);
	sprintf(textb[0],"mysee_v%d.eed",value_range);
        fid=myopen(textb[0],1,0);
        seed_buf[0]=value_range;
	seed_buf[1]=(unsigned char)(lineL & 0x00ff); /*low byte */
	seed_buf[2]=(unsigned char)(lineL >> 8);     /*high byte*/
	if (twod){
	       seed_buf[3]=(unsigned char)i2d;
	       seed_buf[4]=(unsigned char)j2d;
	}
        else if (threed){
	       seed_buf[3]=(unsigned char)i3d;
	       seed_buf[4]=(unsigned char)j3d;
	}
	memmove(seed_buf+5,thisseed,bytesL);
	vret=write(fid, seed_buf, 5+bytesL);
	free(seed_buf);
        erase_prompt_box(2);
      }
   }
   /*to test for bug - local wiring corrupted - now fixed Nov 2008*/
   /*fprintf(stderr,"\nend of select_seed");
     check_wiring_still_local();*/
   
  endFunc:
   if (restore_box){
       sprintf(textb[9],"%s","boximage[12]");
       putimage(startx-3,starty,boximage[12],COPY_PUT,textb[9]);
   }
   freeimage(boximage[12]);
   xtext=tempxtext;
   setviewport(0,0,Maxx,Maxy,0);
   note_viewport;
   setting_seed=0;
   if (seed_box_changed==1){
       seed_box_changed=0; 
       goto startseed_box;
   }

   /*if (1){   //print breakdown of the dec value for maxL_lu bits/values
     signed int z;
     unsigned long thisx=0,addx;   
     
      for (z=0;z<=lineL-1;z++){
         addx=(unsigned long) get_value(thisseed,z)*
				    pow(value_range,z);
         thisx+=addx;
         fprintf(stderr,"\n %d: thisx=%lu (+%lu)", z, thisx,addx);
         if (z>maxL_lu-1) break;
      }
      fprintf(stderr,"\n v=%d maxL_lu=%d thisx=%lu", value_range,maxL_lu,thisx);
     
      addx=(unsigned long) pow(value_range,(double)maxL_lu);
      fprintf(stderr,"\n v=%d maxL_lu=%d ss=%lu", value_range,maxL_lu,addx);
   }*/

   return(starty);       
}
/***************** check bug Nov 2008 -- that local wiring is still local *******/
void check_wiring_still_local(void){
    unsigned int poss,maxL;
    signed int wire;

      char bad_wire=0;
       maxL=lineL-1;
       for (poss=lineL-1;poss!=Maxu;poss--){
         for (wire=nhoodm[poss]-1;wire>=0;wire--){
	   if (wiring[poss][wire]!= (maxL+1+poss-(nhoodm[poss]/2)+wire)%(maxL+1)){
	      bad_wire=1;
              break; 
           }               
         }
	 if (bad_wire==1){
            fprintf(stderr,"\n****** bad-wire poss=%d wire=%d ******",poss,wire);/*test*/
            /*to test*/show_w_r_scheme();
            break;
         }
      }
      
} 

/***** set the scale, fold position of the rule/seed bit pattern ***/
void set_cellscale(char nhoodz, char isrule){
 signed int vlayers,ccount=0;
   
   if (isrule==0){ 
         if (oned && showbits_1d_as_2d==0){
            foldposs=64;
            vlayers=(signed int)ceil((float)lineL/foldposs);
         }
         else if (twod || showbits_1d_as_2d){
            foldposs=i2d;
            vlayers=j2d;
         }
         else if (threed){ 
            foldposs=i3d;
            vlayers=j3d*h3d;
            i2d=i3d;
            j2d=j3d*h3d;
         }
         cellscale=vgax(4);
         cellsep=vgax(2);
         height_req_seed_win=CHeight*10+cellscale*vlayers;

         while(cellscale>=1 && height_req_seed_win>Maxy*.83){
	    ccount++;
            cellscale-=1;
            height_req_seed_win=CHeight*10+cellscale*vlayers;
            if (ccount>20) break;
	 }

         if (cellscale<=2) cellsep=1;
         if (cellscale==0) cellscale=1;
         height_req_seed_win=CHeight*10+cellscale*vlayers;
	 
         if (height_req_seed_win>Maxy*.83){
            height_req_seed_win=Maxy*.8;
            cellscale=1;
            cellsep=1;
         }
         
   }
   else if (isrule){
     signed int tablemax;
           if (totalistic==0)
              tablemax=(signed int)pow(value_range,
                        (double)nhoodz)-1;/*max index of ruletable*/           
           else if (totalistic==1)
              tablemax=nhoodz*(value_range-1); /*max index of tcode*/             
           else if (totalistic==2)
              tablemax=v_tablecodemax[nhoodz]; /*max index of kcode*/

	   /*fprintf(stderr,"\n tablemax=%d",tablemax);*/
           if (tablemax>=((signed int)pow(2,16)-1)){ /*65536*/
               cellscale=1;
	       cellsep=0;
               foldposs=512;
	    }
           else if (tablemax>=((signed int)pow(2,12)-1)){ /*4095*/
               cellscale=2;
	       cellsep=1;
               foldposs=256;
	    }
	    else if (tablemax>=((signed int)pow(2,10)-1)){
               cellscale=3;
	       cellsep=1;
               foldposs=128;
	    }
	     else{
               cellscale=vgax(4);
               /*cellsep=vgax(2);*/
               cellsep=2;
               foldposs=64;
            }
   }
   //return foldposs;
}
/*-----------------------------------------------------*/
