# Time-stamp: <Sat Aug 06 2005 23:43:13 Stardate: [-29]4359.52 hwloidl>
#
# Targets:
#  cons-<name> ... do the consumer for <name>.cmlt
#  conx-<name> ... as above but don't launch isabelle
#  prod-<name> ... do the producer for <name>.cmlt
#  cert-<name> .., generate and check the certificate for <name> in batch mode
#
# The producer is kicked-off automatically if con[sx] is called and the
# consumer generated files don't exist yet.
# Targets for producing intermediate files are as expected
#  <name>.gr
#  <name>.class
#  <name>Certificate.thy
#
# To pass flags to camelot or gf on per-name basis set
#  <name>_CFLAGS
#  <name>_GFLAGS
# (see examples below)
#
# ---------------------------------------------------------------------------

# Setup ------------------------------------------------------------------


#MRGDIR ?= $(HOME)/mrg-working
#MRGDIR ?= ../../../..
#PROGDIR = $(MRGDIR)/progs
PROGDIR = ../../../..
TESTDIR = ..

CAMELOT=$(PROGDIR)/Camelot/src/camelot
CAMELOT_FLAGS=-n -C -thy -lfd -lfd-prg $(PROGDIR)/LFD_inference/lfd_infer -lfd-opts "-olhs 4" 

CERT=$(FILE)Certificate.thy

# demo: review-y3
# HEAP=SLACK
# HEAP=NULL_rules
HEAP=MRG
# only used for batch jobs
HEAP_DIR=/tmp
HEAP_WITH_PATH=$(HEAP_DIR)/$(HEAP)
# style for thy generation
# demo: review-y3
#THY_STYLE=vcg
THY_STYLE=mrg

# URL of dir for downloading HEAP image
URL=ftp://ftp.macs.hw.ac.uk/pub/gph/hwloidl

MRGISABELLE ?= emacs
ISABELLE=$(MRGISABELLE)
ISABELLE_BATCH=isabelle
#ISABELLE=Isabelle
#ISABELLE_FLAGS="-l $(HEAP)"

GF=$(PROGDIR)/Grail/gf/src/gf
GF_FLAGS=-t $(THY_STYLE) -C -q

CERT_NOTES=
PROGS_CERTIFIABLE=$(subst .cmlt,,$(shell ls *.cmlt))

# Prg specific settings -------------------------------------------------------

Twice_CFLAGS=-b

# rules ------------------------------------------------------------------

.PHONY: %.Certificate.thy prod-% cons-% 

%.class:	%.cmlt
	$(CAMELOT) $(CAMELOT_FLAGS) $($(subst .class,,$@)_CFLAGS) $<

%.gr:	%.cmlt
	$(CAMELOT) -g $(CAMELOT_FLAGS) $($(subst .class,,$@)_CFLAGS) $<

%Certificate.thy: %.class
	@echo "Built certificate: $@"

prod-%:  %Certificate.thy clean-%
	@echo "Finished with producer for: $@"

cons-%: CERT=$*Certificate.thy
#cons-%: LAYOUT="`$(TESTDIR)/grab_pragmas.sh 1 $(CERT)`"
cons-%: LAYOUT=$(shell $(TESTDIR)/grab_pragmas.sh L $(CERT))
cons-%: TAG=$(shell $(TESTDIR)/grab_pragmas.sh T $(CERT))
cons-%: WRAPPER=$(shell $(TESTDIR)/grab_pragmas.sh W $(CERT))
cons-%: FLAVOUR=$(shell $(TESTDIR)/grab_pragmas.sh F $(CERT))
cons-%: %Certificate.thy %.class
	echo "Doing: |$(GF) $(LAYOUT) $(TAG) $(FLAVOUR) $(WRAPPER) $(GF_FLAGS) $($(subst Certificate.thy,,$<)_GFLAGS) $*|"
	$(GF) $(LAYOUT) $(TAG) $(FLAVOUR) $(WRAPPER) $(GF_FLAGS) $($(subst Certificate.thy,,$<)_GFLAGS) $* 
	@echo "Name: $*; Certificate: $<; Layout: $(LAYOUT); TAG: $(TAG); FLAVOUR $(FLAVOUR); WRAPPER: $(WRAPPER)"
	@if [ "x$(DRY_RUN)"=="x" ] ; then $(ISABELLE) $(ISABELLE_FLAGS) $*_Consumer1.thy  ;  else echo "dry run" ; fi

#conx-%: DRY_RUN=1
#conx-%: cons-%
#	$(GF) -L $(LAYOUT) -T $(TAG) $(GF_FLAGS) $($(subst Certificate.thy,,$<)_GFLAGS) $*
#	@echo "Name: $*; Certificate: $<; Layout: $(LAYOUT); TAG: $(TAG)"
#	ifeq "$(DRY_RUN)" ""
#	$(ISABELLE) $(ISABELLE_FLAGS) $*_Consumer1.thy  
#	else 
#	@echo "dry run"
#	endif

$(HEAP_WITH_PATH):
	@echo "Downloading image from $(URL)"
	wget --output-document=$@ $(URL)/$(HEAP)

cert-all: $(HEAP_WITH_PATH)
	@echo "Certifying all programs: $(PROGS_CERTIFIABLE) $(CERT_NOTES)"
	@-for p in $(PROGS_CERTIFIABLE) ; do $(MAKE) DRY_RUN=1 -s cert-$$p ; done

cert-%: $(HEAP_WITH_PATH)
cert-%: CERT=$*Certificate.thy
cert-%: FLAVOUR=$(shell $(TESTDIR)/grab_pragmas.sh F $(CERT))
cert-%:	%.class
	@echo "Certifying the inferred heap consumption of $(subst .class,.cmlt,$<) ..."
	$(GF) -L $(LAYOUT) -T $(TAG) $(FLAVOUR) $(GF_FLAGS) $($(subst Certificate.thy,,$<)_GFLAGS) $* 
	@echo "Name: $*; Certificate: $<; Layout: $(LAYOUT); TAG: $(TAG)"
	@echo "use_thy \"$(subst .class,,$<)_Consumer2\";" > ROOT.ML
	$(ISABELLE_BATCH) -r $(HEAP_WITH_PATH) DUMMY < ROOT.ML
	@if [ -f ROOT.ML ] ; then rm ROOT.ML ; fi


#STR=@s=split; if ($$x=="") { $$x=$$s[0] } else { $$x .= "/".$$s[0]; print $$x."\n" }

sz-%: %Certificate.thy
	@echo "Measuring size of certificate relative to source code for $(subst Certificate.thy,.cmlt,$<)"
	@cat $< | sed 's/(\*.*\*)//' | gzip -9 -c  > q.thy.gz
	@ls -lU q.thy.gz $(subst Certificate.thy,.cmlt,$<)  | cut -c26-31  | perl -ne '@s=split; if ($$x=="") { $$x=$$s[0] } else { $$x .= "/".$$s[0]; print $$x."\n" }' | bc -l

sz-all: 
	@echo "Certifying all programs: $(PROGS_CERTIFIABLE) $(CERT_NOTES)"
	@-for p in $(PROGS_CERTIFIABLE) ; do $(MAKE) DRY_RUN=1 -s sz-$$p ; done

cleanup-%: %.constraints %.lfd
	rm -f $^

clean-%: cleanup-% %.class %Certificate.thy %.thy %_Consumer1.thy %_Consumer2.thy %_TACTIC.thy
	rm -f $^

# Edinburgh-style setup
producer:
	$(MRGDIR)/progs/Camelot/src/camelot -D -lfd -n -thy $(FILE).cmlt
	rm -f *.constraints *.lfd *~

consumer:
	$(MRGDIR)/progs/Grail/gf/src/gf -L $(L) -T $(T) -t vcg $(FILE).class
	$(ISABELLE) $(ISABELLE_FLAGS) $(FILE)_Consumer1.thy &
	@echo "Cert: $(Q) ; Layout: $(LAYOUT) ; TAG: $(TAG)"


clean:
	rm -f *.class *.thy *.constraints *.lfd *~
