#!/bin/bash
##############################################################################
# Time-stamp: <Sun Dec 12 2004 01:37:18 Stardate: [-29]3170.12 hwloidl>
#
# Usage: check_it [options] <camelot-prg>
#
# Take Camelot program and check that it fulfills the infered heap consumption.
# NB: Currently the Certificate1 file, containing producer generated Isabelle file 
#     with info on heap consumption is mandatory. Ideally the compiler should
#     generate it automatically by setting the right option.
#
# Setup: you need to set MYPROGS as root of the mrg/progs dir, and set IMG to the
#        Isabelle image corresponding to the VCG logic.
#
# Options:
#  -p  ... specify the Certificate1 file, delivered by the producer
#  -G  ... name of gdf assembler
#  -g  ... options passed to gdf
#  -F  ... name of gf disassembler
#  -f  ... options passed to gf
#  -C  ... name of camelot compiler
#  -c  ... options passed to camelot
#  -v  ... be verbose
#  -h  ... help message
##############################################################################

progname="`basename $0`"
args="$*"

# NB: currently this needs camelot/gf/gdf from the hwl-y3 branch of the CVS rep
MYPROGS=/home/h/hwloidl/mrg-working/progs
# an isabelle heap of VCG logic
IMG=/home/h/hwloidl/isabelle/heaps/polyml-4.1.3_x86-linux/VCG_LRT

mygf=${MYPROGS}/Grail/gf/src/gf
mygdf=${MYPROGS}/Grail/gdf/src/gdf
myc=${MYPROGS}/Camelot/src/camelot

mygdf_opts="-t vcg -l -l -l -l"
mygf_opts="-t VCG -l -l -l -l"
myc_opts=""

verb=0
help=0
debug=0
proof_file=""

getopts "hvdo:p:G:g:F:f:C:c:" name
while [ "$name" != "?" ] ; do
  case $name in
   h) help=1;;
   v) verb=1;;
   o) apfile="$OPTARG";;
   p) proof_file="$OPTARG";;
   G) mygdf=$OPTARG;;
   g) mygdf_opts=$OPTARGS;;
   F) mygf=$OPTARG;;
   f) mygf_opts=$OPTARGS;;
   C) myc=$OPTARG;;
   f) myc_opts=$OPTARGS;;
  esac 
  getopts "hvdo:p:G:g:F:f:C:c:" name
done

if [ $verb -eq 1 ]
    then verb_opt="-v "
    else verb_opt=""
fi

shift $[ $OPTIND - 1 ]

if [ $help -eq 1 ]
 then no_of_lines=`cat $0 | awk 'BEGIN { n = 0; } \
                                 /^$/ { print n; \
                                        exit; } \
                                      { n++; }'`
      echo "`head -$no_of_lines $0`"
      exit 
fi

if [ -z "$1" ]
 then echo "Usage: $progname [options] file[.cmlt]"
      echo "Use -h option for details"
      exit 1;
fi

# 0. compile the Camelot file down to a JVM class file
f="`basename $1 .cmlt`"
if [ "$f" != "$1" ]
  then # it's a Camelot file
       if [ $verb -eq 1 ]
         then echo "Compiling Camelot file $1"
       fi
       $myc $1 
  else # assume it's a class file that we want to verify
       f="`basename $1 .class`"
fi        

prg_thy="${f}Prog.thy"
proof_thy="${f}Certificate1.thy"

if [ $verb -eq 1 ]
  then echo ".. Basename of input file: $f"
       if [ -f "$f.class" ]
         then echo ".. JVM class file: $f.class"
	 else echo "** Cannot find JVM class file $f.class"
       fi
       echo ".. camelot is $myc $myc_opts"
       echo ".. gdf/opts: $mygdf $mygdf_opts"
       echo ".. gf/opts: $mygf $mygf_opts"
       echo ".. Isabelle image file: $IMG"
fi


# 1. generate .thy file for prg out of a JVM class file
# cmlt2thy
if [ $debug -eq 1 ]
  then echo "Doing: |$mygf $mygf_opts $f.class > $f.gr|"
fi
$mygf $mygf_opts $f.class > $f.gr
if [ $debug -eq 1 ]
  then echo "Doing: |$mygf $mygf_opts $f.class > $f.gr|"
fi
$mygf $mygf_opts $f.class > $f.gr
if [ $debug -eq 1 ]
  then echo "Doing: |$mygdf $mygdf_opts $f.gr|"
fi
$mygdf $mygdf_opts $f.gr
if [ ! -z $outfile ]
  then prg_thy="${outfile}Prog.thy"
#  else prg_thy=$f.thy
fi
if [ -z $proof_file ]
  then echo "Need to specify proof file with option -p"
       exit
fi
if [ ! -f $proof_file ]
  then echo "$proof_file is not a regular file; specify a proof file with option -p"
       exit
fi
# make sure the Certificate1 file has the right name!
if [ "$proof_file" != "$proof_thy" ] 
  then echo "Copying $proof_file $proof_thy"
       cp $proof_file $proof_thy
fi

#mv $f.thy $prg_thy
# post-process prg.thy file
tmp_file="`basename ${prg_thy} .thy`.tmp"
if [ $verb -eq 1 ]
  then echo "Generated prog_thy file is ${f}.thy" #; tmp file is ${tmp_file}; prg file is $prg_thy"
fi

#cat "${f}.thy" | sed -e "s/= DAss_rulesU + NILList/= DAss_rulesU2/g;s/$f/${f}Prog/g" > $tmp_file
#lines=$[ `wc -l $tmp_file | awk '{print $1}'` - 6 ]
#echo "Lines: $lines"
#head -${lines} $tmp_file > $prg_thy
#echo "end" >> $prg_thy
# cp $tmp_file $prg_thy

# 2. generate ROOT.ML for the proof file
echo "use_thy \"${f}Certificate23\";" > ROOT.ML

if [ $debug -eq 1 ]
  then echo "ROOT.ML looks like this"
       cat ROOT.ML
fi

# 3. run isabelle to check the proof
if [ $debug -eq 1 ]
  then echo "Starting Isabelle; if successful this should finish with val it = () : unit and prompt"
fi

# first check whether we have an image
if [ ! -f "${IMG}" ]
  then echo "Freaking out: no isabelle image found at ${IMG}"
       exit
fi
isabelle -r ${IMG} DUMMY < ROOT.ML

