

# evolve: script to facilitate the creation of CA rule sets.
# evolve makes transitions from one CA to the next, so long as the rules
# provided are sufficient.

# echo the usage if no arguments are passed

case $# in
0) echo 'Usage: evolve [-m|v] [-o file] [-t n] [-r 'symbols'] [-s n] CAfile rulefile' 1>&2; exit 1
esac


# establish a temporary file

TEMP=/tmp/evolve_temp.$$


# parse the command line arguments

while test "$1" != ""
do
  case "$1" in
    -v) NBHD='-v';;	
    -m) NBHD='-m';;
    -s) SYM="-s $2"; shift;;
    -r) ROT="-r $2"; shift;;
    -t) TICK=$2    ; shift;;
    -o) OUT=$2     ; shift;;
    -*) echo "evolve: Unknown argument $1" 1>&2; exit 1;;
     *) if test -r $1		# if the file exists and is readable
        then CA_FILE=$1
        else echo "evolve: Unable to open $1"  1>&2; exit 1
        fi

        RULE_FILE=${2?'Expected rulefile argument'} # verify rulefile given

        if test ! -r $RULE_FILE	# if the file does not exist or is not readable
        then >$RULE_FILE	# create a RULE_FILE
        fi

	shift;;
  esac
  shift
done


# if TICK not defined by user, set default 
TICK=${TICK='1000'}		


# this is the guts of evolve.
# evolve makes transitions from one CA to the next CA so long as the rules
# provided are sufficient.  when trans fails it outputs the rules it needs
# in order to make the next transition.  evolve appends those skeleton
# rules onto the given RULE_FILE.


# this little awk program determines the current state from the RULE_FILE 
# and assigns it to T

T=`awk 'BEGIN		{ max = 0 }
  	$1 == "state"	{ if ($2 > max) max = $2 }
  	END		{ print  max }' $RULE_FILE`

# this while statement reads like: 
# while the CA state has not exceeded the tick count AND
#	transitions can still be made

while test $T -lt $TICK && 
      cat $CA_FILE | trans ${NBHD-'-v'} $SYM $ROT $RULE_FILE > $TEMP 
do

  # increment T; man is this stuff ugly!
  T=`echo "$T 1 + p" | dc`

  # append new state number to rulefile
  echo "state $T" >> $RULE_FILE 

  # since a successful transition was made, we "reload" so we can do it again
  cp $TEMP $CA_FILE

  # here we append the results to the output file, if that option was specified
  if test "$OUT" != ""
  then cat $TEMP >> $OUT
       echo "state $T" >> $OUT 
  fi

done


# now that we're out of the loop, we check to see exactly how we exited,
# so we know how to clean up

if test $T -lt $TICK 	# if trans failed before max ticks elapsed
then 
  # since the transition failed at this point, we append the needed rules to
  # the RULE_FILE

  cat $TEMP >> $RULE_FILE
else
  if test -r $TEMP 	# if trans executed at least once
  then cp $TEMP $CA_FILE
  fi
fi
