summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore9
l---------[-rw-r--r--]aarch64/mono/mono_rewrites.sail158
-rw-r--r--cheri/.gitignore5
-rw-r--r--cheri/Holmakefile11
-rw-r--r--cheri/Makefile13
-rw-r--r--lib/hol/.gitignore9
-rw-r--r--lib/hol/Holmakefile32
-rw-r--r--lib/hol/Makefile31
-rw-r--r--lib/hol/prompt.lem18
-rw-r--r--lib/hol/prompt_monad.lem49
-rw-r--r--lib/hol/sail_valuesAuxiliaryScript.sml132
-rw-r--r--lib/isabelle/Makefile5
-rw-r--r--lib/isabelle/State_lemmas.thy10
-rw-r--r--lib/isabelle/manual/Manual.thy2
-rw-r--r--lib/mono_rewrites.sail157
-rw-r--r--mips/.gitignore5
-rw-r--r--mips/Holmakefile11
-rw-r--r--mips/Makefile15
-rw-r--r--mips/main.sail74
-rw-r--r--mips/prelude.sail9
-rw-r--r--riscv/.gitignore5
-rw-r--r--riscv/Holmakefile11
-rw-r--r--riscv/Makefile14
-rw-r--r--src/gen_lib/prompt_monad.lem7
-rw-r--r--src/gen_lib/sail_values.lem16
-rw-r--r--src/gen_lib/state.lem65
-rw-r--r--src/gen_lib/state_lifting.lem27
-rw-r--r--src/gen_lib/state_monad.lem14
-rw-r--r--src/pretty_print_lem.ml25
-rw-r--r--src/process_file.ml8
-rw-r--r--src/process_file.mli2
-rw-r--r--test/isabelle/run_cheri.ml2
32 files changed, 679 insertions, 272 deletions
diff --git a/.gitignore b/.gitignore
index 7c36889b..9d77bb0a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,3 +21,12 @@ language/*.aux
language/*.log
language/*.dvi
language/*.ps
+# HOL4
+.HOLMK
+.hollogs
+*Theory.dat
+*Theory.sig
+*Theory.sml
+*Theory.ui
+*Theory.uo
+lib/hol/sail-heap
diff --git a/aarch64/mono/mono_rewrites.sail b/aarch64/mono/mono_rewrites.sail
index c9164b6c..10f2d07b 100644..120000
--- a/aarch64/mono/mono_rewrites.sail
+++ b/aarch64/mono/mono_rewrites.sail
@@ -1,157 +1 @@
-/* Definitions for use with the -mono_rewrites option */
-
-/* External definitions not in the usual asl prelude */
-
-infix 6 <<
-
-val shiftleft = "shiftl" : forall 'n ('ord : Order).
- (vector('n, 'ord, bit), int) -> vector('n, 'ord, bit) effect pure
-
-overload operator << = {shiftleft}
-
-infix 6 >>
-
-val shiftright = "shiftr" : forall 'n ('ord : Order).
- (vector('n, 'ord, bit), int) -> vector('n, 'ord, bit) effect pure
-
-overload operator >> = {shiftright}
-
-val arith_shiftright = "arith_shiftr" : forall 'n ('ord : Order).
- (vector('n, 'ord, bit), int) -> vector('n, 'ord, bit) effect pure
-
-val "extz_vec" : forall 'n 'm. (atom('m),vector('n, dec, bit)) -> vector('m, dec, bit) effect pure
-val extzv : forall 'n 'm. vector('n, dec, bit) -> vector('m, dec, bit) effect pure
-function extzv(v) = extz_vec(sizeof('m),v)
-
-val "exts_vec" : forall 'n 'm. (atom('m),vector('n, dec, bit)) -> vector('m, dec, bit) effect pure
-val extsv : forall 'n 'm. vector('n, dec, bit) -> vector('m, dec, bit) effect pure
-function extsv(v) = exts_vec(sizeof('m),v)
-
-/* This is generated internally to deal with case splits which reveal the size
- of a bitvector */
-val bitvector_cast = "zeroExtend" : forall 'n. bits('n) -> bits('n) effect pure
-
-/* Definitions for the rewrites */
-
-val slice_mask : forall 'n, 'n >= 0. (int, int) -> bits('n) effect pure
-function slice_mask(i,l) =
- let one : bits('n) = extzv(0b1) in
- ((one << l) - one) << i
-
-val is_zero_subrange : forall 'n, 'n >= 0.
- (bits('n), int, int) -> bool effect pure
-
-function is_zero_subrange (xs, i, j) = {
- (xs & slice_mask(j, i-j)) == extzv(0b0)
-}
-
-val is_ones_subrange : forall 'n, 'n >= 0.
- (bits('n), int, int) -> bool effect pure
-
-function is_ones_subrange (xs, i, j) = {
- let m : bits('n) = slice_mask(j,j-i) in
- (xs & m) == m
-}
-
-val slice_slice_concat : forall 'n 'm 'r, 'n >= 0 & 'm >= 0 & 'r >= 0.
- (bits('n), int, int, bits('m), int, int) -> bits('r) effect pure
-
-function slice_slice_concat (xs, i, l, ys, i', l') = {
- let xs = (xs & slice_mask(i,l)) >> i in
- let ys = (ys & slice_mask(i',l')) >> i' in
- extzv(xs) << l' | extzv(ys)
-}
-
-val slice_zeros_concat : forall 'n 'p 'q 'r, 'r = 'p + 'q & 'n >= 0 & 'p >= 0 & 'q >= 0 & 'r >= 0.
- (bits('n), int, atom('p), atom('q)) -> bits('r) effect pure
-
-function slice_zeros_concat (xs, i, l, l') = {
- let xs = (xs & slice_mask(i,l)) >> i in
- extzv(xs) << l'
-}
-
-/* Assumes initial vectors are of equal size */
-
-val subrange_subrange_eq : forall 'n, 'n >= 0.
- (bits('n), int, int, bits('n), int, int) -> bool effect pure
-
-function subrange_subrange_eq (xs, i, j, ys, i', j') = {
- let xs = (xs & slice_mask(j,i-j)) >> j in
- let ys = (ys & slice_mask(j',i'-j')) >> j' in
- xs == ys
-}
-
-val subrange_subrange_concat : forall 'n 'o 'p 'm 'q 'r 's, 's = 'o - ('p - 1) + 'q - ('r - 1) & 'n >= 0 & 'm >= 0.
- (bits('n), atom('o), atom('p), bits('m), atom('q), atom('r)) -> bits('s) effect pure
-
-function subrange_subrange_concat (xs, i, j, ys, i', j') = {
- let xs = (xs & slice_mask(j,i-j)) >> j in
- let ys = (ys & slice_mask(j',i'-j')) >> j' in
- extzv(xs) << i' - (j' - 1) | extzv(ys)
-}
-
-val place_subrange : forall 'n 'm, 'n >= 0 & 'm >= 0.
- (bits('n), int, int, int) -> bits('m) effect pure
-
-function place_subrange(xs,i,j,shift) = {
- let xs = (xs & slice_mask(j,i-j)) >> j in
- extzv(xs) << shift
-}
-
-val place_slice : forall 'n 'm, 'n >= 0 & 'm >= 0.
- (bits('n), int, int, int) -> bits('m) effect pure
-
-function place_slice(xs,i,l,shift) = {
- let xs = (xs & slice_mask(i,l)) >> i in
- extzv(xs) << shift
-}
-
-val zext_slice : forall 'n 'm, 'n >= 0 & 'm >= 0.
- (bits('n), int, int) -> bits('m) effect pure
-
-function zext_slice(xs,i,l) = {
- let xs = (xs & slice_mask(i,l)) >> i in
- extzv(xs)
-}
-
-val sext_slice : forall 'n 'm, 'n >= 0 & 'm >= 0.
- (bits('n), int, int) -> bits('m) effect pure
-
-function sext_slice(xs,i,l) = {
- let xs = arith_shiftright(((xs & slice_mask(i,l)) << ('n - i - l)), 'n - l) in
- extsv(xs)
-}
-
-/* This has different names in the aarch64 prelude (UInt) and the other
- preludes (unsigned). To avoid variable name clashes, we redeclare it
- here with a suitably awkward name. */
-val _builtin_unsigned = {
- ocaml: "uint",
- lem: "uint",
- interpreter: "uint",
- c: "sail_uint"
-} : forall 'n. bits('n) -> range(0, 2 ^ 'n - 1)
-
-val unsigned_slice : forall 'n, 'n >= 0.
- (bits('n), int, int) -> int effect pure
-
-function unsigned_slice(xs,i,l) = {
- let xs = (xs & slice_mask(i,l)) >> i in
- _builtin_unsigned(xs)
-}
-
-val unsigned_subrange : forall 'n, 'n >= 0.
- (bits('n), int, int) -> int effect pure
-
-function unsigned_subrange(xs,i,j) = {
- let xs = (xs & slice_mask(j,i-j)) >> i in
- _builtin_unsigned(xs)
-}
-
-
-val zext_ones : forall 'n, 'n >= 0. int -> bits('n) effect pure
-
-function zext_ones(m) = {
- let v : bits('n) = extsv(0b1) in
- v >> ('n - m)
-}
+../../lib/mono_rewrites.sail \ No newline at end of file
diff --git a/cheri/.gitignore b/cheri/.gitignore
new file mode 100644
index 00000000..f7f98624
--- /dev/null
+++ b/cheri/.gitignore
@@ -0,0 +1,5 @@
+cheri.lem
+cheri_types.lem
+cheriScript.sml
+cheri_typesScript.sml
+mips_extrasScript.sml \ No newline at end of file
diff --git a/cheri/Holmakefile b/cheri/Holmakefile
new file mode 100644
index 00000000..d64fc3fd
--- /dev/null
+++ b/cheri/Holmakefile
@@ -0,0 +1,11 @@
+LEMDIR=../../lem/hol-lib
+
+INCLUDES = $(LEMDIR) ../lib/hol
+
+all: cheriTheory.uo
+.PHONY: all
+
+ifdef POLY
+BASE_HEAP = ../lib/hol/sail-heap
+
+endif
diff --git a/cheri/Makefile b/cheri/Makefile
index 5861dde4..42c7ef86 100644
--- a/cheri/Makefile
+++ b/cheri/Makefile
@@ -17,6 +17,7 @@ CHERI128_PRE:=$(CHERI_SAIL_DIR)/cheri_types.sail $(CHERI_SAIL_DIR)/cheri_prelude
CHERI_INSTS:=$(CHERI_SAIL_DIR)/cheri_insts.sail
CHERI_SAILS:=$(SAIL_LIB_HEADERS) $(MIPS_PRE) $(MIPS_TLB) $(CHERI_PRE) $(MIPS_INSTS) $(CHERI_INSTS) $(MIPS_EPILOGUE)
+CHERI_MONO_SAILS:=$(SAIL_LIB_HEADERS) $(MIPS_PRE) $(SAIL_LIB_DIR)/mono_rewrites.sail $(MIPS_TLB) $(CHERI_PRE) $(MIPS_INSTS) $(CHERI_INSTS) $(MIPS_EPILOGUE)
CHERI_NO_TLB_SAILS:=$(SAIL_LIB_HEADERS) $(MIPS_PRE) $(MIPS_TLB_STUB) $(CHERI_PRE) $(MIPS_INSTS) $(CHERI_INSTS) $(MIPS_EPILOGUE)
CHERI128_SAILS:=$(SAIL_LIB_HEADERS) $(MIPS_PRE) $(MIPS_TLB) $(CHERI128_PRE) $(MIPS_INSTS) $(CHERI_INSTS) $(MIPS_EPILOGUE)
CHERI128_NO_TLB_SAILS:=$(SAIL_LIB_HEADERS) $(MIPS_PRE) $(MIPS_TLB_STUB) $(CHERI128_PRE) $(MIPS_INSTS) $(CHERI_INSTS) $(MIPS_EPILOGUE)
@@ -59,8 +60,8 @@ cheri_no_tlb.lem: $(CHERI_NO_TLB_SAILS)
$(SAIL) -lem -o cheri_no_tlb -lem_lib Mips_extras -undefined_gen -memo_z3 $^
cheri_no_tlb_types.lem: cheri_no_tlb.lem
-cheri.lem: $(CHERI_SAILS) $(CHERI_MAIN)
- $(SAIL) -lem -o cheri -lem_lib Mips_extras -undefined_gen -memo_z3 $^
+cheri.lem: $(CHERI_MONO_SAILS) $(CHERI_MAIN)
+ $(SAIL) -lem -o cheri -auto_mono -mono_rewrites -lem_mwords -lem_lib Mips_extras -undefined_gen -memo_z3 $^
cheri_types.lem: cheri.lem
cheri128_no_tlb.lem: $(CHERI128_NO_TLB_SAILS)
@@ -75,5 +76,13 @@ C%.thy: c%.lem c%_types.lem $(MIPS_SAIL_DIR)/mips_extras.lem
lem -isa -outdir . -lib $(SAIL_DIR)/src/gen_lib -lib $(SAIL_DIR)/src/lem_interp $^
sed -i 's/datatype ast/datatype (plugins only: size) ast/' C$*_types.thy
+%Script.sml: %.lem %_types.lem $(MIPS_SAIL_DIR)/mips_extras.lem
+ lem -hol -outdir . -lib $(SAIL_DIR)/lib/hol -lib $(SAIL_DIR)/src/gen_lib -lib $(SAIL_DIR)/src/lem_interp $^
+
+%Theory.uo: %Script.sml
+ Holmake $@
+
clean:
rm -rf cheri cheri_trace cheri128 cheri128_trace _sbuild inst_*.sail cheri.c sail_latex sail_latexcc
+ rm -f cheriScript.sml cheri_typesScript.sml mips_extrasScript.sml
+ -Holmake cleanAll
diff --git a/lib/hol/.gitignore b/lib/hol/.gitignore
new file mode 100644
index 00000000..fe652801
--- /dev/null
+++ b/lib/hol/.gitignore
@@ -0,0 +1,9 @@
+prompt_monadScript.sml
+promptScript.sml
+sail_instr_kindsScript.sml
+sail_operators_bitlistsScript.sml
+sail_operators_mwordsScript.sml
+sail_operatorsScript.sml
+sail_valuesScript.sml
+state_monadScript.sml
+stateScript.sml
diff --git a/lib/hol/Holmakefile b/lib/hol/Holmakefile
new file mode 100644
index 00000000..6698e210
--- /dev/null
+++ b/lib/hol/Holmakefile
@@ -0,0 +1,32 @@
+LEM_SCRIPTS = sail_instr_kindsScript.sml sail_valuesScript.sml sail_operatorsScript.sml \
+ sail_operators_mwordsScript.sml sail_operators_bitlistsScript.sml \
+ state_monadScript.sml stateScript.sml promptScript.sml prompt_monadScript.sml
+
+LEM_CLEANS = $(LEM_SCRIPTS)
+
+SCRIPTS = $(LEM_SCRIPTS) \
+ sail_valuesAuxiliaryScript.sml
+
+THYS = $(patsubst %Script.sml,%Theory.uo,$(SCRIPTS))
+
+LEMDIR=../../../lem/hol-lib
+
+INCLUDES = $(LEMDIR)
+
+all: $(THYS)
+.PHONY: all
+
+EXTRA_CLEANS = $(LEM_CLEANS)
+
+ifdef POLY
+HOLHEAP = sail-heap
+EXTRA_CLEANS = $(LEM_CLEANS) $(HOLHEAP) $(HOLHEAP).o
+
+BASE_HEAP = $(LEMDIR)/lemheap
+
+$(HOLHEAP):
+ $(protect $(HOLDIR)/bin/buildheap) -o $(HOLHEAP) -b $(BASE_HEAP)
+
+all: $(HOLHEAP)
+
+endif
diff --git a/lib/hol/Makefile b/lib/hol/Makefile
new file mode 100644
index 00000000..065f887a
--- /dev/null
+++ b/lib/hol/Makefile
@@ -0,0 +1,31 @@
+LEMSRC = \
+ ../../src/lem_interp/sail_instr_kinds.lem \
+ ../../src/gen_lib/sail_values.lem \
+ ../../src/gen_lib/sail_operators.lem \
+ ../../src/gen_lib/sail_operators_mwords.lem \
+ ../../src/gen_lib/sail_operators_bitlists.lem \
+ ../../src/gen_lib/state_monad.lem \
+ ../../src/gen_lib/state.lem \
+ prompt_monad.lem \
+ prompt.lem
+
+SCRIPTS = sail_instr_kindsScript.sml sail_valuesScript.sml sail_operatorsScript.sml \
+ sail_operators_mwordsScript.sml sail_operators_bitlistsScript.sml \
+ state_monadScript.sml stateScript.sml \
+ prompt_monadScript.sml promptScript.sml
+
+THYS = $(patsubst %Script.sml,%Theory.uo,$(SCRIPTS))
+
+all: sail-heap $(THYS)
+
+$(SCRIPTS): $(LEMSRC)
+ lem -hol -outdir . -auxiliary_level none -lib ../../src/lem_interp -lib ../../src/gen_lib $(LEMSRC)
+
+$(THYS) sail-heap: $(SCRIPTS)
+ Holmake
+
+# Holmake will also clear out the generated $(SCRIPTS) files
+clean:
+ Holmake cleanAll
+
+.PHONY: all clean
diff --git a/lib/hol/prompt.lem b/lib/hol/prompt.lem
new file mode 100644
index 00000000..edbd3752
--- /dev/null
+++ b/lib/hol/prompt.lem
@@ -0,0 +1,18 @@
+open import Prompt_monad
+open import State_monad
+open import State
+
+let inline undefined_bool = undefined_boolS
+let inline bool_of_bitU_oracle = bool_of_bitU_oracleS
+let inline bool_of_bitU_fail = bool_of_bitU_fail
+let inline bools_of_bits_oracle = bools_of_bits_oracleS
+let inline of_bits_oracle = of_bits_oracleS
+let inline of_bits_fail = of_bits_failS
+let inline mword_oracle = mword_oracleS
+let inline reg_deref = read_regS
+
+let inline foreachM = foreachS
+let inline whileM = whileS
+let inline untilM = untilS
+let inline and_boolM = and_boolS
+let inline or_boolM = or_boolS
diff --git a/lib/hol/prompt_monad.lem b/lib/hol/prompt_monad.lem
new file mode 100644
index 00000000..8fcd645a
--- /dev/null
+++ b/lib/hol/prompt_monad.lem
@@ -0,0 +1,49 @@
+open import Pervasives_extra
+open import Sail_instr_kinds
+open import Sail_values
+open import State_monad
+
+(* Fake interface of the prompt monad by redirecting to the state monad, since
+ the former is not currently supported by HOL4 *)
+
+type monad 'rv 'a 'e = monadS 'rv 'a 'e
+type monadR 'rv 'a 'e 'r = monadRS 'rv 'a 'e 'r
+
+(* We need to use a target_rep for these because HOL doesn't handle unused
+ type parameters well. *)
+
+type base_monad 'regval 'regstate 'a 'e = monad 'regstate 'a 'e
+declare hol target_rep type base_monad 'regval 'regstate 'a 'e = `monad` 'regstate 'a 'e
+type base_monadR 'regval 'regstate 'a 'r 'e = monadR 'regstate 'a 'r 'e
+declare hol target_rep type base_monadR 'regval 'regstate 'a 'r 'e = `monadR` 'regstate 'a 'r 'e
+
+let inline return = returnS
+let inline bind = bindS
+let inline (>>=) = (>>$=)
+let inline (>>) = (>>$)
+
+let inline exit = exitS
+
+let inline throw = throwS
+let inline try_catch = try_catchS
+
+let inline catch_early_return = catch_early_returnS
+let inline early_return = early_returnS
+let inline liftR = liftRS
+let inline try_catchR = try_catchRS
+
+let inline maybe_fail = maybe_failS
+
+let inline read_mem_bytes = read_mem_bytesS
+let inline read_reg = read_regS
+let inline reg_deref = read_regS
+let inline read_mem = read_memS
+let inline read_tag = read_tagS
+let inline excl_result = excl_resultS
+let inline write_reg = write_regS
+let inline write_tag = write_tagS
+let inline write_mem_ea wk addr sz = write_mem_eaS wk addr (nat_of_int sz)
+let inline write_mem_val = write_mem_valS
+let barrier _ = return ()
+
+let inline assert_exp = assert_expS
diff --git a/lib/hol/sail_valuesAuxiliaryScript.sml b/lib/hol/sail_valuesAuxiliaryScript.sml
new file mode 100644
index 00000000..af3f56c5
--- /dev/null
+++ b/lib/hol/sail_valuesAuxiliaryScript.sml
@@ -0,0 +1,132 @@
+(*Generated by Lem from ../../src/gen_lib/sail_values.lem.*)
+open HolKernel Parse boolLib bossLib;
+open lem_pervasives_extraTheory lem_machine_wordTheory sail_valuesTheory;
+open intLib;
+
+val _ = numLib.prefer_num();
+
+
+
+open lemLib;
+(* val _ = lemLib.run_interactive := true; *)
+val _ = new_theory "sail_valuesAuxiliary"
+
+
+(****************************************************)
+(* *)
+(* Termination Proofs *)
+(* *)
+(****************************************************)
+
+(* val gst = Defn.tgoal_no_defn (shr_int_def, shr_int_ind) *)
+val (shr_int_rw, shr_int_ind_rw) =
+ Defn.tprove_no_defn ((shr_int_def, shr_int_ind),
+ WF_REL_TAC`measure (Num o SND)` \\ COOPER_TAC
+ )
+val shr_int_rw = save_thm ("shr_int_rw", shr_int_rw);
+val shr_int_ind_rw = save_thm ("shr_int_ind_rw", shr_int_ind_rw);
+
+
+(* val gst = Defn.tgoal_no_defn (shl_int_def, shl_int_ind) *)
+val (shl_int_rw, shl_int_ind_rw) =
+ Defn.tprove_no_defn ((shl_int_def, shl_int_ind),
+ WF_REL_TAC`measure (Num o SND)` \\ COOPER_TAC
+ )
+val shl_int_rw = save_thm ("shl_int_rw", shl_int_rw);
+val shl_int_ind_rw = save_thm ("shl_int_ind_rw", shl_int_ind_rw);
+
+
+(* val gst = Defn.tgoal_no_defn (repeat_def, repeat_ind) *)
+val (repeat_rw, repeat_ind_rw) =
+ Defn.tprove_no_defn ((repeat_def, repeat_ind),
+ WF_REL_TAC`measure (Num o SND)` \\ COOPER_TAC
+ )
+val repeat_rw = save_thm ("repeat_rw", repeat_rw);
+val repeat_ind_rw = save_thm ("repeat_ind_rw", repeat_ind_rw);
+
+
+(* val gst = Defn.tgoal_no_defn (bools_of_nat_aux_def, bools_of_nat_aux_ind) *)
+val (bools_of_nat_aux_rw, bools_of_nat_aux_ind_rw) =
+ Defn.tprove_no_defn ((bools_of_nat_aux_def, bools_of_nat_aux_ind),
+ WF_REL_TAC`measure (Num o FST)` \\ COOPER_TAC
+ )
+val bools_of_nat_aux_rw = save_thm ("bools_of_nat_aux_rw", bools_of_nat_aux_rw);
+val bools_of_nat_aux_ind_rw = save_thm ("bools_of_nat_aux_ind_rw", bools_of_nat_aux_ind_rw);
+
+
+(* val gst = Defn.tgoal_no_defn (pad_list_def, pad_list_ind) *)
+val (pad_list_rw, pad_list_ind_rw) =
+ Defn.tprove_no_defn ((pad_list_def, pad_list_ind),
+ WF_REL_TAC`measure (Num o SND o SND)` \\ COOPER_TAC
+ )
+val pad_list_rw = save_thm ("pad_list_rw", pad_list_rw);
+val pad_list_ind_rw = save_thm ("pad_list_ind_rw", pad_list_ind_rw);
+
+
+(* val gst = Defn.tgoal_no_defn (reverse_endianness_list_def, reverse_endianness_list_ind) *)
+val (reverse_endianness_list_rw, reverse_endianness_list_ind_rw) =
+ Defn.tprove_no_defn ((reverse_endianness_list_def, reverse_endianness_list_ind),
+ WF_REL_TAC`measure LENGTH` \\ rw[drop_list_def,nat_of_int_def]
+ )
+val reverse_endianness_list_rw = save_thm ("reverse_endianness_list_rw", reverse_endianness_list_rw);
+val reverse_endianness_list_ind_rw = save_thm ("reverse_endianness_list_ind_rw", reverse_endianness_list_ind_rw);
+
+
+(* val gst = Defn.tgoal_no_defn (index_list_def, index_list_ind) *)
+val (index_list_rw, index_list_ind_rw) =
+ Defn.tprove_no_defn ((index_list_def, index_list_ind),
+ WF_REL_TAC`measure (λ(x,y,z). Num(1+(if z > 0 then int_max (-1) (y - x) else int_max (-1) (x - y))))`
+ \\ rw[integerTheory.INT_MAX]
+ \\ intLib.COOPER_TAC
+ )
+val index_list_rw = save_thm ("index_list_rw", index_list_rw);
+val index_list_ind_rw = save_thm ("index_list_ind_rw", index_list_ind_rw);
+
+
+(*
+(* val gst = Defn.tgoal_no_defn (while_def, while_ind) *)
+val (while_rw, while_ind_rw) =
+ Defn.tprove_no_defn ((while_def, while_ind),
+ cheat (* the termination proof *)
+ )
+val while_rw = save_thm ("while_rw", while_rw);
+val while_ind_rw = save_thm ("while_ind_rw", while_ind_rw);
+*)
+
+
+(*
+(* val gst = Defn.tgoal_no_defn (until_def, until_ind) *)
+val (until_rw, until_ind_rw) =
+ Defn.tprove_no_defn ((until_def, until_ind),
+ cheat (* the termination proof *)
+ )
+val until_rw = save_thm ("until_rw", until_rw);
+val until_ind_rw = save_thm ("until_ind_rw", until_ind_rw);
+*)
+
+
+(****************************************************)
+(* *)
+(* Lemmata *)
+(* *)
+(****************************************************)
+
+val just_list_spec = store_thm("just_list_spec",
+``((! xs. (just_list xs = NONE) <=> MEM NONE xs) /\
+ (! xs es. (just_list xs = SOME es) <=> (xs = MAP SOME es)))``,
+ (* Theorem: just_list_spec*)
+ conj_tac
+ \\ ho_match_mp_tac just_list_ind
+ \\ Cases \\ rw[]
+ \\ rw[Once just_list_def]
+ >- ( CASE_TAC \\ fs[] \\ CASE_TAC )
+ >- PROVE_TAC[]
+ \\ Cases_on`es` \\ fs[]
+ \\ CASE_TAC \\ fs[]
+ \\ CASE_TAC \\ fs[]
+);
+
+
+
+val _ = export_theory()
+
diff --git a/lib/isabelle/Makefile b/lib/isabelle/Makefile
index f8786321..b10dde78 100644
--- a/lib/isabelle/Makefile
+++ b/lib/isabelle/Makefile
@@ -1,6 +1,6 @@
THYS = Sail_instr_kinds.thy Sail_values.thy Sail_operators.thy \
Sail_operators_mwords.thy Sail_operators_bitlists.thy \
- State_monad.thy State.thy Prompt_monad.thy Prompt.thy
+ State_monad.thy State.thy State_lifting.thy Prompt_monad.thy Prompt.thy
EXTRA_THYS = State_monad_lemmas.thy State_lemmas.thy Prompt_monad_lemmas.thy \
Sail_operators_mwords_lemmas.thy Hoare.thy
@@ -51,5 +51,8 @@ State_monad.thy: ../../src/gen_lib/state_monad.lem Sail_values.thy
State.thy: ../../src/gen_lib/state.lem Prompt.thy State_monad.thy State_monad_lemmas.thy
lem -isa -outdir . -auxiliary_level none -lib ../../src/lem_interp -lib ../../src/gen_lib $<
+State_lifting.thy: ../../src/gen_lib/state_lifting.lem Prompt.thy State.thy
+ lem -isa -outdir . -auxiliary_level none -lib ../../src/lem_interp -lib ../../src/gen_lib $<
+
clean:
-rm $(THYS)
diff --git a/lib/isabelle/State_lemmas.thy b/lib/isabelle/State_lemmas.thy
index 84b08e6c..253c21b9 100644
--- a/lib/isabelle/State_lemmas.thy
+++ b/lib/isabelle/State_lemmas.thy
@@ -1,5 +1,5 @@
theory State_lemmas
- imports State
+ imports State State_lifting
begin
lemma All_liftState_dom: "liftState_dom (r, m)"
@@ -44,12 +44,12 @@ lemma liftState_catch_early_return[simp]:
by (auto simp: catch_early_return_def catch_early_returnS_def sum.case_distrib cong: sum.case_cong)
lemma liftState_liftR[simp]:
- "liftState r (liftR m) = liftSR (liftState r m)"
- by (auto simp: liftR_def liftSR_def)
+ "liftState r (liftR m) = liftRS (liftState r m)"
+ by (auto simp: liftR_def liftRS_def)
lemma liftState_try_catchR[simp]:
- "liftState r (try_catchR m h) = try_catchSR (liftState r m) (liftState r \<circ> h)"
- by (auto simp: try_catchR_def try_catchSR_def sum.case_distrib cong: sum.case_cong)
+ "liftState r (try_catchR m h) = try_catchRS (liftState r m) (liftState r \<circ> h)"
+ by (auto simp: try_catchR_def try_catchRS_def sum.case_distrib cong: sum.case_cong)
lemma liftState_read_mem_BC:
assumes "unsigned_method BC_bitU_list (bits_of_method BCa a) = unsigned_method BCa a"
diff --git a/lib/isabelle/manual/Manual.thy b/lib/isabelle/manual/Manual.thy
index 6cdfbfa1..51591531 100644
--- a/lib/isabelle/manual/Manual.thy
+++ b/lib/isabelle/manual/Manual.thy
@@ -288,7 +288,7 @@ exception handler as arguments.
The exception mechanism is also used to implement early returns by throwing and catching return
values: A function body with one or more early returns of type @{typ 'a} (and exception type
@{typ 'e}) is lifted to a monadic expression with exception type @{typ "('a + 'e)"} using
-@{term liftSR}, such that an early return of the value @{term a} throws @{term "Inl a"}, and a
+@{term liftRS}, such that an early return of the value @{term a} throws @{term "Inl a"}, and a
regular exception @{term e} is thrown as @{term "Inr e"}. The function body is then wrapped in
@{term catch_early_returnS} to lower it back to the default monad and exception type. These
liftings and lowerings are automatically inserted by Sail for functions with early returns.\<^footnote>\<open>To be
diff --git a/lib/mono_rewrites.sail b/lib/mono_rewrites.sail
new file mode 100644
index 00000000..c9164b6c
--- /dev/null
+++ b/lib/mono_rewrites.sail
@@ -0,0 +1,157 @@
+/* Definitions for use with the -mono_rewrites option */
+
+/* External definitions not in the usual asl prelude */
+
+infix 6 <<
+
+val shiftleft = "shiftl" : forall 'n ('ord : Order).
+ (vector('n, 'ord, bit), int) -> vector('n, 'ord, bit) effect pure
+
+overload operator << = {shiftleft}
+
+infix 6 >>
+
+val shiftright = "shiftr" : forall 'n ('ord : Order).
+ (vector('n, 'ord, bit), int) -> vector('n, 'ord, bit) effect pure
+
+overload operator >> = {shiftright}
+
+val arith_shiftright = "arith_shiftr" : forall 'n ('ord : Order).
+ (vector('n, 'ord, bit), int) -> vector('n, 'ord, bit) effect pure
+
+val "extz_vec" : forall 'n 'm. (atom('m),vector('n, dec, bit)) -> vector('m, dec, bit) effect pure
+val extzv : forall 'n 'm. vector('n, dec, bit) -> vector('m, dec, bit) effect pure
+function extzv(v) = extz_vec(sizeof('m),v)
+
+val "exts_vec" : forall 'n 'm. (atom('m),vector('n, dec, bit)) -> vector('m, dec, bit) effect pure
+val extsv : forall 'n 'm. vector('n, dec, bit) -> vector('m, dec, bit) effect pure
+function extsv(v) = exts_vec(sizeof('m),v)
+
+/* This is generated internally to deal with case splits which reveal the size
+ of a bitvector */
+val bitvector_cast = "zeroExtend" : forall 'n. bits('n) -> bits('n) effect pure
+
+/* Definitions for the rewrites */
+
+val slice_mask : forall 'n, 'n >= 0. (int, int) -> bits('n) effect pure
+function slice_mask(i,l) =
+ let one : bits('n) = extzv(0b1) in
+ ((one << l) - one) << i
+
+val is_zero_subrange : forall 'n, 'n >= 0.
+ (bits('n), int, int) -> bool effect pure
+
+function is_zero_subrange (xs, i, j) = {
+ (xs & slice_mask(j, i-j)) == extzv(0b0)
+}
+
+val is_ones_subrange : forall 'n, 'n >= 0.
+ (bits('n), int, int) -> bool effect pure
+
+function is_ones_subrange (xs, i, j) = {
+ let m : bits('n) = slice_mask(j,j-i) in
+ (xs & m) == m
+}
+
+val slice_slice_concat : forall 'n 'm 'r, 'n >= 0 & 'm >= 0 & 'r >= 0.
+ (bits('n), int, int, bits('m), int, int) -> bits('r) effect pure
+
+function slice_slice_concat (xs, i, l, ys, i', l') = {
+ let xs = (xs & slice_mask(i,l)) >> i in
+ let ys = (ys & slice_mask(i',l')) >> i' in
+ extzv(xs) << l' | extzv(ys)
+}
+
+val slice_zeros_concat : forall 'n 'p 'q 'r, 'r = 'p + 'q & 'n >= 0 & 'p >= 0 & 'q >= 0 & 'r >= 0.
+ (bits('n), int, atom('p), atom('q)) -> bits('r) effect pure
+
+function slice_zeros_concat (xs, i, l, l') = {
+ let xs = (xs & slice_mask(i,l)) >> i in
+ extzv(xs) << l'
+}
+
+/* Assumes initial vectors are of equal size */
+
+val subrange_subrange_eq : forall 'n, 'n >= 0.
+ (bits('n), int, int, bits('n), int, int) -> bool effect pure
+
+function subrange_subrange_eq (xs, i, j, ys, i', j') = {
+ let xs = (xs & slice_mask(j,i-j)) >> j in
+ let ys = (ys & slice_mask(j',i'-j')) >> j' in
+ xs == ys
+}
+
+val subrange_subrange_concat : forall 'n 'o 'p 'm 'q 'r 's, 's = 'o - ('p - 1) + 'q - ('r - 1) & 'n >= 0 & 'm >= 0.
+ (bits('n), atom('o), atom('p), bits('m), atom('q), atom('r)) -> bits('s) effect pure
+
+function subrange_subrange_concat (xs, i, j, ys, i', j') = {
+ let xs = (xs & slice_mask(j,i-j)) >> j in
+ let ys = (ys & slice_mask(j',i'-j')) >> j' in
+ extzv(xs) << i' - (j' - 1) | extzv(ys)
+}
+
+val place_subrange : forall 'n 'm, 'n >= 0 & 'm >= 0.
+ (bits('n), int, int, int) -> bits('m) effect pure
+
+function place_subrange(xs,i,j,shift) = {
+ let xs = (xs & slice_mask(j,i-j)) >> j in
+ extzv(xs) << shift
+}
+
+val place_slice : forall 'n 'm, 'n >= 0 & 'm >= 0.
+ (bits('n), int, int, int) -> bits('m) effect pure
+
+function place_slice(xs,i,l,shift) = {
+ let xs = (xs & slice_mask(i,l)) >> i in
+ extzv(xs) << shift
+}
+
+val zext_slice : forall 'n 'm, 'n >= 0 & 'm >= 0.
+ (bits('n), int, int) -> bits('m) effect pure
+
+function zext_slice(xs,i,l) = {
+ let xs = (xs & slice_mask(i,l)) >> i in
+ extzv(xs)
+}
+
+val sext_slice : forall 'n 'm, 'n >= 0 & 'm >= 0.
+ (bits('n), int, int) -> bits('m) effect pure
+
+function sext_slice(xs,i,l) = {
+ let xs = arith_shiftright(((xs & slice_mask(i,l)) << ('n - i - l)), 'n - l) in
+ extsv(xs)
+}
+
+/* This has different names in the aarch64 prelude (UInt) and the other
+ preludes (unsigned). To avoid variable name clashes, we redeclare it
+ here with a suitably awkward name. */
+val _builtin_unsigned = {
+ ocaml: "uint",
+ lem: "uint",
+ interpreter: "uint",
+ c: "sail_uint"
+} : forall 'n. bits('n) -> range(0, 2 ^ 'n - 1)
+
+val unsigned_slice : forall 'n, 'n >= 0.
+ (bits('n), int, int) -> int effect pure
+
+function unsigned_slice(xs,i,l) = {
+ let xs = (xs & slice_mask(i,l)) >> i in
+ _builtin_unsigned(xs)
+}
+
+val unsigned_subrange : forall 'n, 'n >= 0.
+ (bits('n), int, int) -> int effect pure
+
+function unsigned_subrange(xs,i,j) = {
+ let xs = (xs & slice_mask(j,i-j)) >> i in
+ _builtin_unsigned(xs)
+}
+
+
+val zext_ones : forall 'n, 'n >= 0. int -> bits('n) effect pure
+
+function zext_ones(m) = {
+ let v : bits('n) = extsv(0b1) in
+ v >> ('n - m)
+}
diff --git a/mips/.gitignore b/mips/.gitignore
new file mode 100644
index 00000000..2ee9fde0
--- /dev/null
+++ b/mips/.gitignore
@@ -0,0 +1,5 @@
+mips.lem
+mips_types.lem
+mipsScript.sml
+mips_typesScript.sml
+mips_extrasScript.sml \ No newline at end of file
diff --git a/mips/Holmakefile b/mips/Holmakefile
new file mode 100644
index 00000000..a31bfd4f
--- /dev/null
+++ b/mips/Holmakefile
@@ -0,0 +1,11 @@
+LEMDIR=../../lem/hol-lib
+
+INCLUDES = $(LEMDIR) ../lib/hol
+
+all: mipsTheory.uo
+.PHONY: all
+
+ifdef POLY
+BASE_HEAP = ../lib/hol/sail-heap
+
+endif
diff --git a/mips/Makefile b/mips/Makefile
index 6d605d60..100687e8 100644
--- a/mips/Makefile
+++ b/mips/Makefile
@@ -19,17 +19,24 @@ mips_no_tlb.lem: $(MIPS_PRE) $(MIPS_TLB_STUB) $(MIPS_SAILS)
$(SAIL) -lem -o mips_no_tlb -lem_mwords -lem_lib Mips_extras -undefined_gen -memo_z3 $^
mips_no_tlb_types.lem: mips_no_tlb.lem
-# TODO: Use monomorphisation so that we can switch to machine words
-mips.lem: $(MIPS_PRE) $(MIPS_TLB) $(MIPS_SAILS)
- $(SAIL) -lem -o mips -lem_lib Mips_extras -undefined_gen -memo_z3 $^
+mips.lem: $(MIPS_PRE) $(SAIL_LIB_DIR)/mono_rewrites.sail $(MIPS_TLB) $(MIPS_SAILS)
+ $(SAIL) -lem -o mips -auto_mono -mono_rewrites -lem_mwords -lem_lib Mips_extras -undefined_gen -memo_z3 $^
mips_types.lem: mips.lem
M%.thy: m%.lem m%_types.lem mips_extras.lem
lem -isa -outdir . -lib $(SAIL_DIR)/src/gen_lib -lib $(SAIL_DIR)/src/lem_interp $^
sed -i 's/datatype ast/datatype (plugins only: size) ast/' M$*_types.thy
+%Script.sml: %.lem %_types.lem $(MIPS_SAIL_DIR)/mips_extras.lem
+ lem -hol -outdir . -lib $(SAIL_DIR)/lib/hol -lib $(SAIL_DIR)/src/gen_lib -lib $(SAIL_DIR)/src/lem_interp $^
+
+%Theory.uo: %Script.sml
+ Holmake $@
+
LOC_FILES:=$(MIPS_PRE) $(MIPS_TLB) $(MIPS_SAILS) $(MIPS_MAIN)
include ../etc/loc.mk
clean:
- rm -rf mips Mips.thy mips.lem _sbuild
+ rm -rf mips Mips.thy mips.lem mips_types.lem _sbuild
+ rm -f mipsScript.sml mips_typesScript.sml mips_extrasScript.sml
+ -Holmake cleanAll
diff --git a/mips/main.sail b/mips/main.sail
index 8ec91ba6..54fb34ee 100644
--- a/mips/main.sail
+++ b/mips/main.sail
@@ -1,39 +1,35 @@
register instCount : int
-val fetch_and_execute : unit -> unit effect {barr, eamem, escape, rmem, rreg, wmv, wreg, undef, wmvt, rmemt}
+val fetch_and_execute : unit -> bool effect {barr, eamem, escape, rmem, rreg, wmv, wreg, undef, wmvt, rmemt}
function fetch_and_execute () = {
- while true do {
- PC = nextPC;
- inBranchDelay = branchPending;
- branchPending = 0b0;
- nextPC = if inBranchDelay then delayedPC else PC + 4;
- cp2_next_pc();
- instCount = instCount + 1;
- print_bits("PC: ", PC);
- try {
- let pc_pa = TranslatePC(PC);
- /*print_bits("pa: ", pc_pa);*/
- let instr = MEMr_wrapper(pc_pa, 4);
- /*print_bits("hex: ", instr);*/
- let instr_ast = decode(instr);
- match instr_ast {
- Some(HCF()) => {
- print("simulation stopped due to halt instruction.");
- return ();
- },
- Some(ast) => execute(ast),
- None() => {print("Decode failed"); exit (())} /* Never expect this -- unknown instruction should actually result in reserved instruction ISA-level exception (see mips_ri.sail). */
- }
- } catch {
- ISAException() => print("EXCEPTION")
- /* ISA-level exception occurrred either during TranslatePC or execute --
- just continue from nextPC, which should have been set to the appropriate
- exception vector (along with clearing branchPending etc.) . */
- };
+ PC = nextPC;
+ inBranchDelay = branchPending;
+ branchPending = 0b0;
+ nextPC = if inBranchDelay then delayedPC else PC + 4;
+ cp2_next_pc();
+ instCount = instCount + 1;
+ print_bits("PC: ", PC);
+ try {
+ let pc_pa = TranslatePC(PC);
+ /*print_bits("pa: ", pc_pa);*/
+ let instr = MEMr_wrapper(pc_pa, 4);
+ /*print_bits("hex: ", instr);*/
+ let instr_ast = decode(instr);
+ match instr_ast {
+ Some(HCF()) => {
+ print("simulation stopped due to halt instruction.");
+ false
+ },
+ Some(ast) => { execute(ast); true },
+ None() => { print("Decode failed"); exit (()) } /* Never expect this -- unknown instruction should actually result in reserved instruction ISA-level exception (see mips_ri.sail). */
+ }
+ } catch {
+ ISAException() => { print("EXCEPTION"); true }
+ /* ISA-level exception occurrred either during TranslatePC or execute --
+ just continue from nextPC, which should have been set to the appropriate
+ exception vector (along with clearing branchPending etc.) . */
};
- skip_rmemt();
- skip_wmvt();
}
val elf_entry = {
@@ -42,7 +38,13 @@ val elf_entry = {
c: "elf_entry"
} : unit -> int
-val main : unit -> unit effect {barr, eamem, escape, rmem, rreg, undef, wmv, wreg, rmemt, wmvt}
+val init_registers : bits(64) -> unit effect {wreg}
+
+function init_registers (initialPC) = {
+ init_cp0_state();
+ init_cp2_state();
+ nextPC = initialPC;
+}
function dump_mips_state () : unit -> unit = {
print_bits("DEBUG MIPS PC ", PC);
@@ -51,12 +53,12 @@ function dump_mips_state () : unit -> unit = {
}
}
+val main : unit -> unit effect {barr, eamem, escape, rmem, rreg, undef, wmv, wreg, rmemt, wmvt}
+
function main () = {
- init_cp0_state();
- init_cp2_state();
- nextPC = to_bits(64, elf_entry());
+ init_registers(to_bits(64, elf_entry()));
startTime = get_time_ns();
- fetch_and_execute();
+ while (fetch_and_execute()) do ();
endTime = get_time_ns();
elapsed = endTime - startTime;
inst_1e9 = instCount * 1000000000;
diff --git a/mips/prelude.sail b/mips/prelude.sail
index e0bcd8cf..f805876a 100644
--- a/mips/prelude.sail
+++ b/mips/prelude.sail
@@ -1,8 +1,11 @@
+$include <smt.sail>
+
default Order dec
type bits ('n : Int) = vector('n, dec, bit)
union option ('a : Type) = {None : unit, Some : 'a}
+
val eq_bit = {ocaml: "(fun (x, y) -> x = y)", lem: "eq", interpreter: "eq_anything", c: "eq_bit"} : (bit, bit) -> bool
val eq_vec = {ocaml: "eq_list", lem: "eq_vec"} : forall 'n. (bits('n), bits('n)) -> bool
@@ -126,6 +129,9 @@ val int_power = {ocaml: "int_power", lem: "pow"} : (int, int) -> int
overload operator ^ = {xor_vec, int_power}
+val add_atom = {ocaml: "add_int", lem: "integerAdd"} : forall 'n 'm.
+ (atom('n), atom('m)) -> atom('n + 'm)
+
val add_range = {ocaml: "add_int", lem: "integerAdd"} : forall 'n 'm 'o 'p.
(range('n, 'm), range('o, 'p)) -> range('n + 'o, 'm + 'p)
@@ -137,6 +143,9 @@ val add_vec_int = "add_vec_int" : forall 'n. (bits('n), int) -> bits('n)
overload operator + = {add_range, add_int, add_vec, add_vec_int}
+val sub_atom = {ocaml: "sub_int", lem: "integerMinus", c: "sub_int"} : forall 'n 'm.
+ (atom('n), atom('m)) -> atom('n - 'm)
+
val sub_range = {ocaml: "sub_int", lem: "integerMinus"} : forall 'n 'm 'o 'p.
(range('n, 'm), range('o, 'p)) -> range('n - 'p, 'm - 'o)
diff --git a/riscv/.gitignore b/riscv/.gitignore
new file mode 100644
index 00000000..52f3767a
--- /dev/null
+++ b/riscv/.gitignore
@@ -0,0 +1,5 @@
+riscv.lem
+riscv_types.lem
+riscvScript.sml
+riscv_extrasScript.sml
+riscv_typesScript.sml
diff --git a/riscv/Holmakefile b/riscv/Holmakefile
new file mode 100644
index 00000000..8269bc36
--- /dev/null
+++ b/riscv/Holmakefile
@@ -0,0 +1,11 @@
+LEMDIR=../../lem/hol-lib
+
+INCLUDES = $(LEMDIR) ../lib/hol
+
+all: riscvTheory.uo
+.PHONY: all
+
+ifdef POLY
+BASE_HEAP = ../lib/hol/sail-heap
+
+endif
diff --git a/riscv/Makefile b/riscv/Makefile
index 11cc7731..0532bf09 100644
--- a/riscv/Makefile
+++ b/riscv/Makefile
@@ -34,6 +34,18 @@ Riscv.thy: riscv.lem riscv_extras.lem
riscv.lem: $(SAIL_SRCS) Makefile
$(SAIL_DIR)/sail -lem -o riscv -lem_mwords -lem_lib Riscv_extras $(SAIL_SRCS)
+riscv_sequential.lem: $(SAIL_SRCS) Makefile
+ $(SAIL_DIR)/sail -lem -lem_sequential -o riscv_sequential -lem_mwords -lem_lib Riscv_extras_sequential $(SAIL_SRCS)
+
+riscvScript.sml : riscv.lem riscv_extras.lem
+ lem -hol -outdir . -lib ../lib/hol -lib ../src/lem_interp -lib ../src/gen_lib \
+ riscv_extras.lem \
+ riscv_types.lem \
+ riscv.lem
+
+riscvTheory.uo riscvTheory.ui: riscvScript.sml
+ Holmake riscvTheory.uo
+
# we exclude prelude.sail here, most code there should move to sail lib
LOC_FILES:=$(SAIL_SRCS) main.sail
include ../etc/loc.mk
@@ -44,3 +56,5 @@ clean:
-rm -f Riscv.thy Riscv_types.thy \
Riscv_extras.thy
-rm -f Riscv_duopod.thy Riscv_duopod_types.thy riscv_duopod.lem riscv_duopod_types.lem
+ -rm -f riscvScript.sml riscv_typesScript.sml riscv_extrasScript.sml
+ -Holmake cleanAll
diff --git a/src/gen_lib/prompt_monad.lem b/src/gen_lib/prompt_monad.lem
index 9eb59319..87c9af39 100644
--- a/src/gen_lib/prompt_monad.lem
+++ b/src/gen_lib/prompt_monad.lem
@@ -212,3 +212,10 @@ let barrier bk = Barrier bk (Done ())
val footprint : forall 'rv 'e. unit -> monad 'rv unit 'e
let footprint _ = Footprint (Done ())
+
+(* Define a type synonym that also takes the register state as a type parameter,
+ in order to make switching to the state monad without changing generated
+ definitions easier, see also lib/hol/prompt_monad.lem. *)
+
+type base_monad 'regval 'regstate 'a 'e = monad 'regval 'a 'e
+type base_monadR 'regval 'regstate 'a 'r 'e = monadR 'regval 'a 'r 'e
diff --git a/src/gen_lib/sail_values.lem b/src/gen_lib/sail_values.lem
index 5c6dc593..a709a8c1 100644
--- a/src/gen_lib/sail_values.lem
+++ b/src/gen_lib/sail_values.lem
@@ -85,7 +85,7 @@ let rec replace bs (n : integer) b' = match bs with
if n = 0 then b' :: bs
else b :: replace bs (n - 1) b'
end
-declare {isabelle} termination_argument replace = automatic
+declare {isabelle; hol} termination_argument replace = automatic
let upper n = n
@@ -128,7 +128,7 @@ let rec just_list l = match l with
| (_, _) -> Nothing
end
end
-declare {isabelle} termination_argument just_list = automatic
+declare {isabelle; hol} termination_argument just_list = automatic
lemma just_list_spec:
((forall xs. (just_list xs = Nothing) <-> List.elem Nothing xs) &&
@@ -267,7 +267,7 @@ let rec nat_of_bools_aux acc bs = match bs with
| true :: bs -> nat_of_bools_aux ((2 * acc) + 1) bs
| false :: bs -> nat_of_bools_aux (2 * acc) bs
end
-declare {isabelle} termination_argument nat_of_bools_aux = automatic
+declare {isabelle; hol} termination_argument nat_of_bools_aux = automatic
let nat_of_bools bs = nat_of_bools_aux 0 bs
val unsigned_of_bools : list bool -> integer
@@ -306,7 +306,7 @@ let rec add_one_bool_ignore_overflow_aux bits = match bits with
| false :: bits -> true :: bits
| true :: bits -> false :: add_one_bool_ignore_overflow_aux bits
end
-declare {isabelle} termination_argument add_one_bool_ignore_overflow_aux = automatic
+declare {isabelle; hol} termination_argument add_one_bool_ignore_overflow_aux = automatic
let add_one_bool_ignore_overflow bits =
List.reverse (add_one_bool_ignore_overflow_aux (List.reverse bits))
@@ -369,7 +369,7 @@ let rec add_one_bit_ignore_overflow_aux bits = match bits with
| B1 :: bits -> B0 :: add_one_bit_ignore_overflow_aux bits
| BU :: bits -> BU :: List.map (fun _ -> BU) bits
end
-declare {isabelle} termination_argument add_one_bit_ignore_overflow_aux = automatic
+declare {isabelle; hol} termination_argument add_one_bit_ignore_overflow_aux = automatic
let add_one_bit_ignore_overflow bits =
List.reverse (add_one_bit_ignore_overflow_aux (List.reverse bits))
@@ -417,7 +417,7 @@ let rec hexstring_of_bits bs = match bs with
| [] -> Just []
| _ -> Nothing
end
-declare {isabelle} termination_argument hexstring_of_bits = automatic
+declare {isabelle; hol} termination_argument hexstring_of_bits = automatic
let show_bitlist bs =
match hexstring_of_bits bs with
@@ -630,7 +630,7 @@ let rec byte_chunks bs = match bs with
Maybe.bind (byte_chunks rest) (fun rest -> Just ([a;b;c;d;e;f;g;h] :: rest))
| _ -> Nothing
end
-declare {isabelle} termination_argument byte_chunks = automatic
+declare {isabelle; hol} termination_argument byte_chunks = automatic
val bytes_of_bits : forall 'a. Bitvector 'a => 'a -> maybe (list memory_byte)
let bytes_of_bits bs = byte_chunks (bits_of bs)
@@ -854,7 +854,7 @@ let rec foreach l vars body =
| (x :: xs) -> foreach xs (body x vars) body
end
-declare {isabelle} termination_argument foreach = automatic
+declare {isabelle; hol} termination_argument foreach = automatic
val index_list : integer -> integer -> integer -> list integer
let rec index_list from to step =
diff --git a/src/gen_lib/state.lem b/src/gen_lib/state.lem
index 61477258..f69f59c1 100644
--- a/src/gen_lib/state.lem
+++ b/src/gen_lib/state.lem
@@ -1,33 +1,8 @@
open import Pervasives_extra
-(*open import Sail_impl_base*)
open import Sail_values
-open import Prompt_monad
-open import Prompt
open import State_monad
open import {isabelle} `State_monad_lemmas`
-(* State monad wrapper around prompt monad *)
-
-val liftState : forall 'regval 'regs 'a 'e. register_accessors 'regs 'regval -> monad 'regval 'a 'e -> monadS 'regs 'a 'e
-let rec liftState ra s = match s with
- | (Done a) -> returnS a
- | (Read_mem rk a sz k) -> bindS (read_mem_bytesS rk a sz) (fun v -> liftState ra (k v))
- | (Read_tag t k) -> bindS (read_tagS t) (fun v -> liftState ra (k v))
- | (Write_memv a k) -> bindS (write_mem_bytesS a) (fun v -> liftState ra (k v))
- | (Write_tag a t k) -> bindS (write_tagS a t) (fun v -> liftState ra (k v))
- | (Read_reg r k) -> bindS (read_regvalS ra r) (fun v -> liftState ra (k v))
- | (Excl_res k) -> bindS (excl_resultS ()) (fun v -> liftState ra (k v))
- | (Undefined k) -> bindS (undefined_boolS ()) (fun v -> liftState ra (k v))
- | (Write_ea wk a sz k) -> seqS (write_mem_eaS wk a sz) (liftState ra k)
- | (Write_reg r v k) -> seqS (write_regvalS ra r v) (liftState ra k)
- | (Footprint k) -> liftState ra k
- | (Barrier _ k) -> liftState ra k
- | (Print _ k) -> liftState ra k (* TODO *)
- | (Fail descr) -> failS descr
- | (Exception e) -> throwS e
-end
-
-
val iterS_aux : forall 'rv 'a 'e. integer -> (integer -> 'a -> monadS 'rv unit 'e) -> list 'a -> monadS 'rv unit 'e
let rec iterS_aux i f xs = match xs with
| x :: xs -> f i x >>$ iterS_aux (i + 1) f xs
@@ -53,6 +28,46 @@ end
declare {isabelle} termination_argument foreachS = automatic
+val and_boolS : forall 'rv 'e. monadS 'rv bool 'e -> monadS 'rv bool 'e -> monadS 'rv bool 'e
+let and_boolS l r = l >>$= (fun l -> if l then r else returnS false)
+
+val or_boolS : forall 'rv 'e. monadS 'rv bool 'e -> monadS 'rv bool 'e -> monadS 'rv bool 'e
+let or_boolS l r = l >>$= (fun l -> if l then returnS true else r)
+
+val bool_of_bitU_fail : forall 'rv 'e. bitU -> monadS 'rv bool 'e
+let bool_of_bitU_fail = function
+ | B0 -> returnS false
+ | B1 -> returnS true
+ | BU -> failS "bool_of_bitU"
+end
+
+val bool_of_bitU_oracleS : forall 'rv 'e. bitU -> monadS 'rv bool 'e
+let bool_of_bitU_oracleS = function
+ | B0 -> returnS false
+ | B1 -> returnS true
+ | BU -> undefined_boolS ()
+end
+
+val bools_of_bits_oracleS : forall 'rv 'e. list bitU -> monadS 'rv (list bool) 'e
+let bools_of_bits_oracleS bits =
+ foreachS bits []
+ (fun b bools ->
+ bool_of_bitU_oracleS b >>$= (fun b ->
+ returnS (bools ++ [b])))
+
+val of_bits_oracleS : forall 'rv 'a 'e. Bitvector 'a => list bitU -> monadS 'rv 'a 'e
+let of_bits_oracleS bits =
+ bools_of_bits_oracleS bits >>$= (fun bs ->
+ returnS (of_bools bs))
+
+val of_bits_failS : forall 'rv 'a 'e. Bitvector 'a => list bitU -> monadS 'rv 'a 'e
+let of_bits_failS bits = maybe_failS "of_bits" (of_bits bits)
+
+val mword_oracleS : forall 'rv 'a 'e. Size 'a => unit -> monadS 'rv (mword 'a) 'e
+let mword_oracleS () =
+ bools_of_bits_oracleS (repeat [BU] (integerFromNat size)) >>$= (fun bs ->
+ returnS (wordFromBitlist bs))
+
val whileS : forall 'rv 'vars 'e. 'vars -> ('vars -> monadS 'rv bool 'e) ->
('vars -> monadS 'rv 'vars 'e) -> monadS 'rv 'vars 'e
diff --git a/src/gen_lib/state_lifting.lem b/src/gen_lib/state_lifting.lem
new file mode 100644
index 00000000..7e569a7e
--- /dev/null
+++ b/src/gen_lib/state_lifting.lem
@@ -0,0 +1,27 @@
+open import Pervasives_extra
+open import Sail_values
+open import Prompt_monad
+open import Prompt
+open import State_monad
+open import {isabelle} `State_monad_lemmas`
+
+(* State monad wrapper around prompt monad *)
+
+val liftState : forall 'regval 'regs 'a 'e. register_accessors 'regs 'regval -> monad 'regval 'a 'e -> monadS 'regs 'a 'e
+let rec liftState ra s = match s with
+ | (Done a) -> returnS a
+ | (Read_mem rk a sz k) -> bindS (read_mem_bytesS rk a sz) (fun v -> liftState ra (k v))
+ | (Read_tag t k) -> bindS (read_tagS t) (fun v -> liftState ra (k v))
+ | (Write_memv a k) -> bindS (write_mem_bytesS a) (fun v -> liftState ra (k v))
+ | (Write_tag a t k) -> bindS (write_tagS a t) (fun v -> liftState ra (k v))
+ | (Read_reg r k) -> bindS (read_regvalS ra r) (fun v -> liftState ra (k v))
+ | (Excl_res k) -> bindS (excl_resultS ()) (fun v -> liftState ra (k v))
+ | (Undefined k) -> bindS (undefined_boolS ()) (fun v -> liftState ra (k v))
+ | (Write_ea wk a sz k) -> seqS (write_mem_eaS wk a sz) (liftState ra k)
+ | (Write_reg r v k) -> seqS (write_regvalS ra r v) (liftState ra k)
+ | (Footprint k) -> liftState ra k
+ | (Barrier _ k) -> liftState ra k
+ | (Print _ k) -> liftState ra k (* TODO *)
+ | (Fail descr) -> failS descr
+ | (Exception e) -> throwS e
+end
diff --git a/src/gen_lib/state_monad.lem b/src/gen_lib/state_monad.lem
index a2919762..89021890 100644
--- a/src/gen_lib/state_monad.lem
+++ b/src/gen_lib/state_monad.lem
@@ -94,12 +94,12 @@ let assert_expS exp msg = if exp then returnS () else failS msg
(* For early return, we abuse exceptions by throwing and catching
the return value. The exception type is "either 'r 'e", where "Right e"
represents a proper exception and "Left r" an early return of value "r". *)
-type monadSR 'regs 'a 'r 'e = monadS 'regs 'a (either 'r 'e)
+type monadRS 'regs 'a 'r 'e = monadS 'regs 'a (either 'r 'e)
-val early_returnS : forall 'regs 'a 'r 'e. 'r -> monadSR 'regs 'a 'r 'e
+val early_returnS : forall 'regs 'a 'r 'e. 'r -> monadRS 'regs 'a 'r 'e
let early_returnS r = throwS (Left r)
-val catch_early_returnS : forall 'regs 'a 'e. monadSR 'regs 'a 'a 'e -> monadS 'regs 'a 'e
+val catch_early_returnS : forall 'regs 'a 'e. monadRS 'regs 'a 'a 'e -> monadS 'regs 'a 'e
let catch_early_returnS m =
try_catchS m
(function
@@ -108,12 +108,12 @@ let catch_early_returnS m =
end)
(* Lift to monad with early return by wrapping exceptions *)
-val liftSR : forall 'a 'r 'regs 'e. monadS 'regs 'a 'e -> monadSR 'regs 'a 'r 'e
-let liftSR m = try_catchS m (fun e -> throwS (Right e))
+val liftRS : forall 'a 'r 'regs 'e. monadS 'regs 'a 'e -> monadRS 'regs 'a 'r 'e
+let liftRS m = try_catchS m (fun e -> throwS (Right e))
(* Catch exceptions in the presence of early returns *)
-val try_catchSR : forall 'regs 'a 'r 'e1 'e2. monadSR 'regs 'a 'r 'e1 -> ('e1 -> monadSR 'regs 'a 'r 'e2) -> monadSR 'regs 'a 'r 'e2
-let try_catchSR m h =
+val try_catchRS : forall 'regs 'a 'r 'e1 'e2. monadRS 'regs 'a 'r 'e1 -> ('e1 -> monadRS 'regs 'a 'r 'e2) -> monadRS 'regs 'a 'r 'e2
+let try_catchRS m h =
try_catchS m
(function
| Left r -> throwS (Left r)
diff --git a/src/pretty_print_lem.ml b/src/pretty_print_lem.ml
index 58bbfc4b..c872d420 100644
--- a/src/pretty_print_lem.ml
+++ b/src/pretty_print_lem.ml
@@ -883,8 +883,7 @@ let doc_exp_lem, doc_let_lem =
let b = match e1 with E_aux (E_if _,_) -> true | _ -> false in
let middle =
match fst (untyp_pat pat) with
- | P_aux (P_wild,_) | P_aux (P_typ (_, P_aux (P_wild, _)), _) ->
- string ">>"
+ | P_aux (P_wild,_) | P_aux (P_typ (_, P_aux (P_wild, _)), _) -> string ">>"
| P_aux (P_tup _, _)
when not (IdSet.mem (mk_id "varstup") (find_e_ids e2)) ->
(* Work around indentation issues in Lem when translating
@@ -894,7 +893,8 @@ let doc_exp_lem, doc_let_lem =
doc_pat_lem ctxt true pat;
string "= varstup in"]
| _ ->
- separate space [string ">>= fun"; doc_pat_lem ctxt true pat; arrow]
+ separate space [string ">>= fun";
+ doc_pat_lem ctxt true pat; arrow]
in
infix 0 1 middle (expV b e1) (expN e2)
in
@@ -908,12 +908,11 @@ let doc_exp_lem, doc_let_lem =
raise (Reporting_basic.err_unreachable l
"pretty-printing non-constant sizeof expressions to Lem not supported"))
| E_return r ->
- let ret_monad = if !opt_sequential then " : MR regstate" else " : MR" in
let ta =
if contains_t_pp_var ctxt (typ_of full_exp) || contains_t_pp_var ctxt (typ_of r)
then empty
else separate space
- [string ret_monad;
+ [string ": MR";
parens (doc_typ_lem (typ_of full_exp));
parens (doc_typ_lem (typ_of r))] in
align (parens (string "early_return" ^//^ expV true r ^//^ ta))
@@ -1438,17 +1437,11 @@ let pp_defs_lem (types_file,types_modules) (defs_file,defs_modules) (Defs defs)
separate empty (List.map doc_def_lem statedefs); hardline;
hardline;
register_refs; hardline;
- (* if !opt_sequential then
- concat [
- string ("type MR 'a 'r = State_monad.MR regstate 'a 'r " ^ exc_typ); hardline;
- string ("type M 'a = State_monad.M regstate 'a " ^ exc_typ); hardline;
- ]
- else *)
- concat [
- string ("type MR 'a 'r = monadR register_value 'a 'r " ^ exc_typ); hardline;
- string ("type M 'a = monad register_value 'a " ^ exc_typ); hardline
- ]
- ]);
+ concat [
+ string ("type MR 'a 'r = base_monadR register_value regstate 'a 'r " ^ exc_typ); hardline;
+ string ("type M 'a = base_monad register_value regstate 'a " ^ exc_typ); hardline
+ ]
+ ]);
(print defs_file)
(concat
[string "(*" ^^ (string top_line) ^^ string "*)";hardline;
diff --git a/src/process_file.ml b/src/process_file.ml
index 4856c20a..34c1a255 100644
--- a/src/process_file.ml
+++ b/src/process_file.ml
@@ -51,9 +51,6 @@
open PPrint
open Pretty_print_common
-let opt_lem_sequential = ref false
-let opt_lem_mwords = ref false
-
type out_type =
| Lem_ast_out
| Lem_out of string list
@@ -246,10 +243,7 @@ let output_lem filename libs defs =
let generated_line = generated_line filename in
(* let seq_suffix = if !Pretty_print_lem.opt_sequential then "_sequential" else "" in *)
let types_module = (filename ^ "_types") in
- let monad_modules = ["Prompt_monad"; "Prompt"; "State"] in
- (* if !Pretty_print_lem.opt_sequential
- then ["State_monad"; "State"]
- else ["Prompt_monad"; "Prompt"] in *)
+ let monad_modules = ["Prompt_monad"; "Prompt"] in
let operators_module =
if !Pretty_print_lem.opt_mwords
then "Sail_operators_mwords"
diff --git a/src/process_file.mli b/src/process_file.mli
index b38b4259..cc94888e 100644
--- a/src/process_file.mli
+++ b/src/process_file.mli
@@ -65,8 +65,6 @@ val rewrite_ast_check : Type_check.tannot Ast.defs -> Type_check.tannot Ast.defs
val load_file_no_check : Ast.order -> string -> unit Ast.defs
val load_file : Ast.order -> Type_check.Env.t -> string -> Type_check.tannot Ast.defs * Type_check.Env.t
-val opt_lem_sequential : bool ref
-val opt_lem_mwords : bool ref
val opt_just_check : bool ref
val opt_ddump_tc_ast : bool ref
val opt_ddump_rewrite_ast : ((string * int) option) ref
diff --git a/test/isabelle/run_cheri.ml b/test/isabelle/run_cheri.ml
index e6d752b7..f51ef4dd 100644
--- a/test/isabelle/run_cheri.ml
+++ b/test/isabelle/run_cheri.ml
@@ -64,7 +64,7 @@ let () =
Arg.parse options (fun s -> opt_file_arguments := !opt_file_arguments @ [s]) usage_msg
let (>>) = State_monad.bindS
-let liftS = State.liftState (Cheri_types.get_regval, Cheri_types.set_regval)
+let liftS = State_lifting.liftState (Cheri_types.get_regval, Cheri_types.set_regval)
let load_elf_segment seg =
let open Elf_interpreted_segment in