summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJon French2018-05-15 17:50:05 +0100
committerJon French2018-05-15 17:50:05 +0100
commite2d8fe4d847b6e8f71eecd7aa6d15799bd2a2e11 (patch)
treeaf5ca7ac35244a706f9631ab8f1a4dada172f27d /src
parented3bb9702bd1f76041a3798f453714b0636a1b6b (diff)
parent77b393e4f53d14955d301cbd16e22d2e7b026ede (diff)
Merge branch 'sail2' into mappings
Diffstat (limited to 'src')
-rw-r--r--src/ast_util.ml7
-rw-r--r--src/gen_lib/sail_operators.lem30
-rw-r--r--src/gen_lib/sail_operators_bitlists.lem16
-rw-r--r--src/gen_lib/sail_operators_mwords.lem16
-rw-r--r--src/latex.ml11
-rw-r--r--src/monomorphise.ml167
-rw-r--r--src/pretty_print_lem.ml22
-rw-r--r--src/state.ml15
8 files changed, 152 insertions, 132 deletions
diff --git a/src/ast_util.ml b/src/ast_util.ml
index 7af1b006..82e39022 100644
--- a/src/ast_util.ml
+++ b/src/ast_util.ml
@@ -247,6 +247,13 @@ and nexp_simp_aux = function
when Big_int.equal c1 (Big_int.negate c2) -> n
| _, _ -> Nexp_minus (n1, n2)
end
+ | Nexp_neg n ->
+ begin
+ let (Nexp_aux (n_simp, _) as n) = nexp_simp n in
+ match n_simp with
+ | Nexp_constant c -> Nexp_constant (Big_int.negate c)
+ | _ -> Nexp_neg n
+ end
| Nexp_app (Id_aux (Id "div",_) as id,[n1;n2]) ->
begin
let (Nexp_aux (n1_simp, _) as n1) = nexp_simp n1 in
diff --git a/src/gen_lib/sail_operators.lem b/src/gen_lib/sail_operators.lem
index 78aab65e..0c5da675 100644
--- a/src/gen_lib/sail_operators.lem
+++ b/src/gen_lib/sail_operators.lem
@@ -194,36 +194,6 @@ let neq_bv l r = not (eq_bv l r)
let inline neq_mword l r = (l <> r)
-val ult_bv : forall 'a. Bitvector 'a => 'a -> 'a -> bool
-let ult_bv l r = lexicographicLess (List.reverse (bits_of l)) (List.reverse (bits_of r))
-let ulteq_bv l r = (eq_bv l r) || (ult_bv l r)
-let ugt_bv l r = not (ulteq_bv l r)
-let ugteq_bv l r = (eq_bv l r) || (ugt_bv l r)
-
-val slt_bv : forall 'a. Bitvector 'a => 'a -> 'a -> bool
-let slt_bv l r =
- match (most_significant l, most_significant r) with
- | (B0, B0) -> ult_bv l r
- | (B0, B1) -> false
- | (B1, B0) -> true
- | (B1, B1) ->
- let l' = add_one_bit_ignore_overflow (bits_of l) in
- let r' = add_one_bit_ignore_overflow (bits_of r) in
- ugt_bv l' r'
- | (BU, BU) -> ult_bv l r
- | (BU, _) -> true
- | (_, BU) -> false
- end
-let slteq_bv l r = (eq_bv l r) || (slt_bv l r)
-let sgt_bv l r = not (slteq_bv l r)
-let sgteq_bv l r = (eq_bv l r) || (sgt_bv l r)
-
-val ucmp_mword : forall 'a. Size 'a => (integer -> integer -> bool) -> mword 'a -> mword 'a -> bool
-let inline ucmp_mword cmp l r = cmp (unsignedIntegerFromWord l) (unsignedIntegerFromWord r)
-
-val scmp_mword : forall 'a. Size 'a => (integer -> integer -> bool) -> mword 'a -> mword 'a -> bool
-let inline scmp_mword cmp l r = cmp (signedIntegerFromWord l) (signedIntegerFromWord r)
-
val get_slice_int_bv : forall 'a. Bitvector 'a => integer -> integer -> integer -> 'a
let get_slice_int_bv len n lo =
let hi = lo + len - 1 in
diff --git a/src/gen_lib/sail_operators_bitlists.lem b/src/gen_lib/sail_operators_bitlists.lem
index fed293b4..19e9b519 100644
--- a/src/gen_lib/sail_operators_bitlists.lem
+++ b/src/gen_lib/sail_operators_bitlists.lem
@@ -308,21 +308,5 @@ let set_slice (out_len:ii) (slice_len:ii) out (n:ii) v =
val eq_vec : list bitU -> list bitU -> bool
val neq_vec : list bitU -> list bitU -> bool
-val ult_vec : list bitU -> list bitU -> bool
-val slt_vec : list bitU -> list bitU -> bool
-val ugt_vec : list bitU -> list bitU -> bool
-val sgt_vec : list bitU -> list bitU -> bool
-val ulteq_vec : list bitU -> list bitU -> bool
-val slteq_vec : list bitU -> list bitU -> bool
-val ugteq_vec : list bitU -> list bitU -> bool
-val sgteq_vec : list bitU -> list bitU -> bool
let eq_vec = eq_bv
let neq_vec = neq_bv
-let ult_vec = ult_bv
-let slt_vec = slt_bv
-let ugt_vec = ugt_bv
-let sgt_vec = sgt_bv
-let ulteq_vec = ulteq_bv
-let slteq_vec = slteq_bv
-let ugteq_vec = ugteq_bv
-let sgteq_vec = sgteq_bv
diff --git a/src/gen_lib/sail_operators_mwords.lem b/src/gen_lib/sail_operators_mwords.lem
index 077dfb02..22d5b246 100644
--- a/src/gen_lib/sail_operators_mwords.lem
+++ b/src/gen_lib/sail_operators_mwords.lem
@@ -329,21 +329,5 @@ let set_slice (out_len:ii) (slice_len:ii) out (n:ii) v =
val eq_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> bool
val neq_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> bool
-val ult_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> bool
-val slt_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> bool
-val ugt_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> bool
-val sgt_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> bool
-val ulteq_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> bool
-val slteq_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> bool
-val ugteq_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> bool
-val sgteq_vec : forall 'a. Size 'a => mword 'a -> mword 'a -> bool
let inline eq_vec = eq_mword
let inline neq_vec = neq_mword
-let inline ult_vec = ucmp_mword (<)
-let inline slt_vec = scmp_mword (<)
-let inline ugt_vec = ucmp_mword (>)
-let inline sgt_vec = scmp_mword (>)
-let inline ulteq_vec = ucmp_mword (<=)
-let inline slteq_vec = scmp_mword (<=)
-let inline ugteq_vec = ucmp_mword (>=)
-let inline sgteq_vec = scmp_mword (>=)
diff --git a/src/latex.ml b/src/latex.ml
index f16dddd8..0520d074 100644
--- a/src/latex.ml
+++ b/src/latex.ml
@@ -123,18 +123,19 @@ let commands = ref StringSet.empty
let rec latex_command ?prefix:(prefix="") ?label:(label=None) dir cmd no_loc ((l, _) as annot) =
let labelling = match label with
| None -> ""
- | Some l -> Printf.sprintf "\\label{%s%s}" prefix l
+ | Some l -> Printf.sprintf "\\label{%s}" l
in
let cmd = !opt_prefix_latex ^ prefix ^ cmd in
- if StringSet.mem cmd !commands then
+ let lcmd = String.lowercase cmd in (* lowercase to avoid file names differing only by case *)
+ if StringSet.mem lcmd !commands then
latex_command ~label:label dir (cmd ^ "v") no_loc annot
else
begin
- commands := StringSet.add cmd !commands;
- let oc = open_out (Filename.concat dir (cmd ^ "_sail.tex")) in
+ commands := StringSet.add lcmd !commands;
+ let oc = open_out (Filename.concat dir (cmd ^ ".tex")) in
output_string oc (Pretty_print_sail.to_string (latex_loc no_loc l));
close_out oc;
- string (Printf.sprintf "\\newcommand{\\%s}{%s " cmd labelling) ^^ (docstring l) ^^ string (Printf.sprintf "\\lstinputlisting[language=sail]{%s/%s_sail.tex}}" dir cmd)
+ string (Printf.sprintf "\\newcommand{\\%s}{%s " cmd labelling) ^^ (docstring l) ^^ string (Printf.sprintf "\\lstinputlisting[language=sail]{%s/%s.tex}}" dir cmd)
end
let latex_command_id ?prefix:(prefix="") dir id no_loc annot =
diff --git a/src/monomorphise.ml b/src/monomorphise.ml
index 0585d9fa..4f257712 100644
--- a/src/monomorphise.ml
+++ b/src/monomorphise.ml
@@ -856,7 +856,7 @@ let try_app (l,ann) (id,args) =
| [E_aux (E_lit L_aux (L_num i,_),_); E_aux (E_lit L_aux (L_num j,_),_)] ->
Some (E_aux (E_lit (L_aux (L_num (Big_int.shift_left i (Big_int.to_int j)),new_l)),(l,ann)))
| _ -> None
- else if is_id "mult_int" || is_id "mult_range" then
+ else if is_id "mult_atom" || is_id "mult_int" || is_id "mult_range" then
match args with
| [E_aux (E_lit L_aux (L_num i,_),_); E_aux (E_lit L_aux (L_num j,_),_)] ->
Some (E_aux (E_lit (L_aux (L_num (Big_int.mul i j),new_l)),(l,ann)))
@@ -866,7 +866,7 @@ let try_app (l,ann) (id,args) =
| [E_aux (E_lit L_aux (L_num i,_),_); E_aux (E_lit L_aux (L_num j,_),_)] ->
Some (E_aux (E_lit (L_aux (L_num (Big_int.div i j),new_l)),(l,ann)))
| _ -> None
- else if is_id "add_range" then
+ else if is_id "add_atom" || is_id "add_int" || is_id "add_range" then
match args with
| [E_aux (E_lit L_aux (L_num i,_),_); E_aux (E_lit L_aux (L_num j,_),_)] ->
Some (E_aux (E_lit (L_aux (L_num (Big_int.add i j),new_l)),(l,ann)))
@@ -2241,13 +2241,20 @@ let rewrite_size_parameters env (Defs defs) =
let open Rewriter in
let open Util in
- let sizes_funcl fsizes (FCL_aux (FCL_Funcl (id,pexp),(l,_))) =
+ let sizes_funcl fsizes (FCL_aux (FCL_Funcl (id,pexp),(l,ann))) =
let pat,guard,exp,pannot = destruct_pexp pexp in
- let parameters = match pat with
- | P_aux (P_tup ps,_) -> ps
- | _ -> [pat]
+ let env = env_of_annot (l,ann) in
+ let _, typ = Env.get_val_spec_orig id env in
+ let typ = match typ with
+ | Typ_aux (Typ_fn (arg_typ,_,_),_) -> arg_typ
+ | _ -> typ (* TODO: error *)
in
- let add_parameter (i,nmap) (P_aux (_,(_,Some (env,typ,_)))) =
+ let types =
+ match pat, Env.expand_synonyms env typ with
+ | P_aux (P_tup ps,_), Typ_aux (Typ_tup ts,_) -> ts
+ | _, _ -> [typ]
+ in
+ let add_parameter (i,nmap) typ =
let nmap =
match Env.base_typ_of env typ with
Typ_aux (Typ_app(Id_aux (Id "range",_),
@@ -2262,8 +2269,14 @@ let rewrite_size_parameters env (Defs defs) =
| _ -> nmap
in (i+1,nmap)
in
- let (_,nexp_map) = List.fold_left add_parameter (0,NexpMap.empty) parameters in
+ let (_,nexp_map) = List.fold_left add_parameter (0,NexpMap.empty) types in
let nexp_list = NexpMap.bindings nexp_map in
+(* let () =
+ print_endline ("Type of pattern for " ^ string_of_id id ^": " ^string_of_typ (pat_typ_of pat));
+ print_endline ("Types : " ^ String.concat ", " (List.map string_of_typ types));
+ print_endline ("Nexp map for " ^ string_of_id id);
+ List.iter (fun (nexp, i) -> print_endline (" " ^ string_of_nexp nexp ^ " -> " ^ string_of_int i)) nexp_list
+in *)
let parameters_for = function
| Some (env,typ,_) ->
begin match Env.base_typ_of env typ with
@@ -2696,12 +2709,10 @@ let kids_bound_by_pat pat =
| ((s,p),ann) -> s, P_aux (p,ann))
}) pat)
-(* Add bound variables from a pattern to the environment with the given dependency. *)
+(* Diff the type environment to find new type variables and record that they
+ depend on deps *)
-let update_env env deps pat typ_env_pre typ_env_post =
- let bound = bindings_from_pat pat in
- let var_deps = List.fold_left (fun ds v -> Bindings.add v deps ds) env.var_deps bound in
- (* Diff the type environment to find the new variables *)
+let update_env_new_kids env deps typ_env_pre typ_env_post =
let kbound =
KBindings.merge (fun k x y ->
match x,y with
@@ -2711,7 +2722,15 @@ let update_env env deps pat typ_env_pre typ_env_post =
(Env.get_typ_vars typ_env_pre)
in
let kid_deps = KBindings.fold (fun v _ ds -> KBindings.add v deps ds) kbound env.kid_deps in
- { env with var_deps = var_deps; kid_deps = kid_deps }
+ { env with kid_deps = kid_deps }
+
+(* Add bound variables from a pattern to the environment with the given dependency,
+ plus any new type variables. *)
+
+let update_env env deps pat typ_env_pre typ_env_post =
+ let bound = bindings_from_pat pat in
+ let var_deps = List.fold_left (fun ds v -> Bindings.add v deps ds) env.var_deps bound in
+ update_env_new_kids { env with var_deps = var_deps } deps typ_env_pre typ_env_post
let assigned_vars_exps es =
List.fold_left (fun vs exp -> IdSet.union vs (assigned_vars exp))
@@ -2886,6 +2905,30 @@ let rec analyse_exp fn_id env assigns (E_aux (e,(l,annot)) as exp) =
let deps, _, rs = split3 (List.map (analyse_exp fn_id env assigns) es) in
(deps, assigns, List.fold_left merge empty rs)
in
+ (* We allow for arguments to functions being executed non-deterministically, but
+ follow the type checker in processing them in-order to detect the automatic
+ unpacking of existentials. When we spot a new type variable (using
+ update_env_new_kids) we set them to depend on the previous argument. *)
+ let non_det_args es =
+ let assigns = remove_assigns es " assigned in non-deterministic expressions" in
+ let rec aux prev_typ_env prev_deps env = function
+ | [] -> [], empty
+ | h::t ->
+ let typ_env = env_of h in
+ let env = update_env_new_kids env prev_deps prev_typ_env typ_env in
+ let new_deps, _, new_r = analyse_exp fn_id env assigns h in
+ let t_deps, t_r = aux typ_env new_deps env t in
+ new_deps::t_deps, merge new_r t_r
+ in
+ let deps, r = match es with
+ | [] -> [], empty
+ | h::t ->
+ let new_deps, _, new_r = analyse_exp fn_id env assigns h in
+ let t_deps, t_r = aux (env_of h) new_deps env t in
+ new_deps::t_deps, merge new_r t_r
+ in
+ (deps, assigns, r)
+ in
let merge_deps deps = List.fold_left dmerge dempty deps in
let deps, assigns, r =
match e with
@@ -2922,7 +2965,7 @@ let rec analyse_exp fn_id env assigns (E_aux (e,(l,annot)) as exp) =
| E_lit _ -> (dempty,assigns,empty)
| E_cast (_,e) -> analyse_exp fn_id env assigns e
| E_app (id,args) ->
- let deps, assigns, r = non_det args in
+ let deps, assigns, r = non_det_args args in
let typ_env = env_of_annot (l,annot) in
let (_,fn_typ) = Env.get_val_spec id typ_env in
let fn_effect = match fn_typ with
@@ -3772,10 +3815,21 @@ end
module BitvectorSizeCasts =
struct
+let simplify_size_nexp env quant_kids (Nexp_aux (_,l) as nexp) =
+ match solve env nexp with
+ | Some n -> Some (nconstant n)
+ | None ->
+ let is_equal kid =
+ prove env (NC_aux (NC_equal (Nexp_aux (Nexp_var kid,Unknown), nexp),Unknown))
+ in
+ match List.find is_equal quant_kids with
+ | kid -> Some (Nexp_aux (Nexp_var kid,Generated l))
+ | exception Not_found -> None
+
(* These functions add cast functions across case splits, so that when a
bitvector size becomes known in sail, the generated Lem code contains a
function call to change mword 'n to (say) mword ty16, and vice versa. *)
-let make_bitvector_cast_fns env src_typ target_typ =
+let make_bitvector_cast_fns env quant_kids src_typ target_typ =
let genunk = Generated Unknown in
let fresh =
let counter = ref 0 in
@@ -3784,7 +3838,7 @@ let make_bitvector_cast_fns env src_typ target_typ =
let () = counter := n+1 in
mk_id ("cast#" ^ string_of_int n)
in
- let required = ref false in
+ let at_least_one = ref None in
let rec aux (Typ_aux (src_t,src_l) as src_typ) (Typ_aux (tar_t,tar_l) as tar_typ) =
let src_ann = Some (env,src_typ,no_effect) in
let tar_ann = Some (env,tar_typ,no_effect) in
@@ -3796,18 +3850,26 @@ let make_bitvector_cast_fns env src_typ target_typ =
| Typ_app (Id_aux (Id "vector",_),
[Typ_arg_aux (Typ_arg_nexp size,_); _;
Typ_arg_aux (Typ_arg_typ (Typ_aux (Typ_id (Id_aux (Id "bit",_)),_)),_)]),
- Typ_app (Id_aux (Id "vector",_),
- [Typ_arg_aux (Typ_arg_nexp size',_); _;
- Typ_arg_aux (Typ_arg_typ (Typ_aux (Typ_id (Id_aux (Id "bit",_)),_)),_)])
- when Nexp.compare size size' <> 0 ->
- let () = required := true in
- let var = fresh () in
- P_aux (P_id var,(Generated src_l,src_ann)),
- E_aux
- (E_cast (tar_typ,
- E_aux (E_app (Id_aux (Id "bitvector_cast", genunk),
- [E_aux (E_id var, (genunk, src_ann))]), (genunk, tar_ann))),
- (genunk, tar_ann))
+ Typ_app (Id_aux (Id "vector",_) as t_id,
+ [Typ_arg_aux (Typ_arg_nexp size',l_size'); t_ord;
+ Typ_arg_aux (Typ_arg_typ (Typ_aux (Typ_id (Id_aux (Id "bit",_)),_)),_) as t_bit]) -> begin
+ match simplify_size_nexp env quant_kids size, simplify_size_nexp env quant_kids size' with
+ | Some size, Some size' when Nexp.compare size size' <> 0 ->
+ let var = fresh () in
+ let tar_typ' = Typ_aux (Typ_app (t_id, [Typ_arg_aux (Typ_arg_nexp size',l_size');t_ord;t_bit]),
+ tar_l) in
+ let () = at_least_one := Some tar_typ' in
+ P_aux (P_id var,(Generated src_l,src_ann)),
+ E_aux
+ (E_cast (tar_typ',
+ E_aux (E_app (Id_aux (Id "bitvector_cast", genunk),
+ [E_aux (E_id var, (genunk, src_ann))]), (genunk, tar_ann))),
+ (genunk, tar_ann))
+ | _ ->
+ let var = fresh () in
+ P_aux (P_id var,(Generated src_l,src_ann)),
+ E_aux (E_id var,(Generated src_l,tar_ann))
+ end
| _ ->
let var = fresh () in
P_aux (P_id var,(Generated src_l,src_ann)),
@@ -3816,8 +3878,8 @@ let make_bitvector_cast_fns env src_typ target_typ =
let src_typ' = Env.base_typ_of env src_typ in
let target_typ' = Env.base_typ_of env target_typ in
let pat, e' = aux src_typ' target_typ' in
- if !required
- then
+ match !at_least_one with
+ | Some one_target_typ -> begin
let src_ann = Some (env,src_typ,no_effect) in
let tar_ann = Some (env,target_typ,no_effect) in
match src_typ' with
@@ -3825,12 +3887,12 @@ let make_bitvector_cast_fns env src_typ target_typ =
| Typ_aux (Typ_app _,_) ->
(fun var exp ->
let exp_ann = Some (env,typ_of exp,effect_of exp) in
- E_aux (E_let (LB_aux (LB_val (P_aux (P_typ (target_typ, P_aux (P_id var,(genunk,tar_ann))),(genunk,tar_ann)),
+ E_aux (E_let (LB_aux (LB_val (P_aux (P_typ (one_target_typ, P_aux (P_id var,(genunk,tar_ann))),(genunk,tar_ann)),
E_aux (E_app (Id_aux (Id "bitvector_cast",genunk),
[E_aux (E_id var,(genunk,src_ann))]),(genunk,tar_ann))),(genunk,tar_ann)),
exp),(genunk,exp_ann))),
(fun (E_aux (_,(exp_l,exp_ann)) as exp) ->
- E_aux (E_cast (target_typ,
+ E_aux (E_cast (one_target_typ,
E_aux (E_app (Id_aux (Id "bitvector_cast", genunk), [exp]), (Generated exp_l,tar_ann))),
(Generated exp_l,tar_ann)))
| _ ->
@@ -3841,16 +3903,17 @@ let make_bitvector_cast_fns env src_typ target_typ =
exp),(genunk,exp_ann))),(genunk,exp_ann))),
(fun (E_aux (_,(exp_l,exp_ann)) as exp) ->
E_aux (E_let (LB_aux (LB_val (pat, exp),(Generated exp_l,exp_ann)), e'),(Generated exp_l,tar_ann)))
- else (fun _ e -> e),(fun e -> e)
+ end
+ | None -> (fun _ e -> e),(fun e -> e)
(* TODO: bound vars *)
-let make_bitvector_env_casts env (kid,i) exp =
- let mk_cast var typ exp = (fst (make_bitvector_cast_fns env typ (subst_src_typ (KBindings.singleton kid (nconstant i)) typ))) var exp in
+let make_bitvector_env_casts env quant_kids (kid,i) exp =
+ let mk_cast var typ exp = (fst (make_bitvector_cast_fns env quant_kids typ (subst_src_typ (KBindings.singleton kid (nconstant i)) typ))) var exp in
let locals = Env.get_locals env in
Bindings.fold (fun var (mut,typ) exp ->
if mut = Immutable then mk_cast var typ exp else exp) locals exp
-let make_bitvector_cast_exp typ target_typ exp = (snd (make_bitvector_cast_fns (env_of exp) typ target_typ)) exp
+let make_bitvector_cast_exp env quant_kids typ target_typ exp = (snd (make_bitvector_cast_fns env quant_kids typ target_typ)) exp
let rec extract_value_from_guard var (E_aux (e,_)) =
match e with
@@ -3871,14 +3934,14 @@ let fill_in_type env typ =
| BK_type
| BK_order -> subst
| BK_int ->
- match solve env (nvar kid) with
+ (match solve env (nvar kid) with
| None -> subst
- | Some n -> KBindings.add kid (nconstant n) subst) tyvars KBindings.empty in
+ | Some n -> KBindings.add kid (nconstant n) subst)) tyvars KBindings.empty in
subst_src_typ subst typ
(* TODO: top-level patterns *)
let add_bitvector_casts (Defs defs) =
- let rewrite_body ret_typ exp =
+ let rewrite_body id quant_kids top_env ret_typ exp =
let rewrite_aux (e,ann) =
match e with
| E_case (E_aux (e',ann') as exp',cases) -> begin
@@ -3893,16 +3956,17 @@ let add_bitvector_casts (Defs defs) =
let body = match pat, guard with
| P_aux (P_lit (L_aux (L_num i,_)),_), _ ->
let src_typ = subst_src_typ (KBindings.singleton kid (nconstant i)) result_typ in
- make_bitvector_cast_exp src_typ result_typ
- (make_bitvector_env_casts env (kid,i) body)
+ make_bitvector_cast_exp env quant_kids src_typ result_typ
+ (make_bitvector_env_casts env quant_kids (kid,i) body)
| P_aux (P_id var,_), Some guard ->
(match extract_value_from_guard var guard with
| Some i ->
let src_typ = subst_src_typ (KBindings.singleton kid (nconstant i)) result_typ in
- make_bitvector_cast_exp src_typ result_typ
- (make_bitvector_env_casts env (kid,i) body)
+ make_bitvector_cast_exp env quant_kids src_typ result_typ
+ (make_bitvector_env_casts env quant_kids (kid,i) body)
| None -> body)
- | _ -> body
+ | _ ->
+ body
in
construct_pexp (pat, guard, body, ann)
in
@@ -3910,10 +3974,10 @@ let add_bitvector_casts (Defs defs) =
| _ -> E_aux (e,ann)
end
| E_return e' ->
- E_aux (E_return (make_bitvector_cast_exp (fill_in_type (env_of e') (typ_of e')) ret_typ e'),ann)
+ E_aux (E_return (make_bitvector_cast_exp top_env quant_kids (fill_in_type (env_of e') (typ_of e')) ret_typ e'),ann)
| E_assign (LEXP_aux (lexp,lexp_annot),e') ->
E_aux (E_assign (LEXP_aux (lexp,lexp_annot),
- make_bitvector_cast_exp (fill_in_type (env_of e') (typ_of e'))
+ make_bitvector_cast_exp (env_of_annot ann) quant_kids (fill_in_type (env_of e') (typ_of e'))
(typ_of_annot lexp_annot) e'),ann)
| _ -> E_aux (e,ann)
in
@@ -3923,8 +3987,10 @@ let add_bitvector_casts (Defs defs) =
e_aux = rewrite_aux } exp
in
let rewrite_funcl (FCL_aux (FCL_Funcl (id,pexp),fcl_ann)) =
+ let (tq,typ) = Env.get_val_spec_orig id (env_of_annot fcl_ann) in
+ let quant_kids = List.map kopt_kid (quant_kopts tq) in
let ret_typ =
- match typ_of_annot fcl_ann with
+ match typ with
| Typ_aux (Typ_fn (_,ret,_),_) -> ret
| Typ_aux (_,l) as typ ->
raise (Reporting_basic.err_unreachable l
@@ -3932,10 +3998,11 @@ let add_bitvector_casts (Defs defs) =
" is not a function type"))
in
let pat,guard,body,annot = destruct_pexp pexp in
- let body = rewrite_body ret_typ body in
+ let env = env_of body in
+ let body = rewrite_body id quant_kids env ret_typ body in
(* Also add a cast around the entire function clause body, if necessary *)
let body =
- make_bitvector_cast_exp (fill_in_type (env_of body) (typ_of body)) ret_typ body
+ make_bitvector_cast_exp env quant_kids (fill_in_type (env_of body) (typ_of body)) ret_typ body
in
let pexp = construct_pexp (pat,guard,body,annot) in
FCL_aux (FCL_Funcl (id,pexp),fcl_ann)
diff --git a/src/pretty_print_lem.ml b/src/pretty_print_lem.ml
index c181249d..58bbfc4b 100644
--- a/src/pretty_print_lem.ml
+++ b/src/pretty_print_lem.ml
@@ -111,10 +111,7 @@ let rec fix_id remove_tick name = match name with
let doc_id_lem (Id_aux(i,_)) =
match i with
| Id i -> string (fix_id false i)
- | DeIid x ->
- (* add an extra space through empty to avoid a closing-comment
- * token in case of x ending with star. *)
- parens (separate space [colon; string x; empty])
+ | DeIid x -> string (Util.zencode_string ("op " ^ x))
let doc_id_lem_type (Id_aux(i,_)) =
match i with
@@ -122,10 +119,7 @@ let doc_id_lem_type (Id_aux(i,_)) =
| Id("nat") -> string "ii"
| Id("option") -> string "maybe"
| Id i -> string (fix_id false i)
- | DeIid x ->
- (* add an extra space through empty to avoid a closing-comment
- * token in case of x ending with star. *)
- parens (separate space [colon; string x; empty])
+ | DeIid x -> string (Util.zencode_string ("op " ^ x))
let doc_id_lem_ctor (Id_aux(i,_)) =
match i with
@@ -135,10 +129,11 @@ let doc_id_lem_ctor (Id_aux(i,_)) =
| Id("Some") -> string "Just"
| Id("None") -> string "Nothing"
| Id i -> string (fix_id false (String.capitalize i))
- | DeIid x ->
- (* add an extra space through empty to avoid a closing-comment
- * token in case of x ending with star. *)
- separate space [colon; string (String.capitalize x); empty]
+ | DeIid x -> string (Util.zencode_string ("op " ^ x))
+
+let deinfix = function
+ | Id_aux (Id v, l) -> Id_aux (DeIid v, l)
+ | Id_aux (DeIid v, l) -> Id_aux (DeIid v, l)
let doc_var_lem kid = string (fix_id true (string_of_kid kid))
@@ -880,8 +875,7 @@ let doc_exp_lem, doc_let_lem =
| E_assert (e1,e2) ->
align (liftR (separate space [string "assert_exp"; expY e1; expY e2]))
| E_app_infix (e1,id,e2) ->
- raise (Reporting_basic.err_unreachable l
- "E_app_infix should have been rewritten before pretty-printing")
+ expV aexp_needed (E_aux (E_app (deinfix id, [e1; e2]), (l, annot)))
| E_var(lexp, eq_exp, in_exp) ->
raise (report l "E_vars should have been removed before pretty-printing")
| E_internal_plet (pat,e1,e2) ->
diff --git a/src/state.ml b/src/state.ml
index 5a360456..ab63747c 100644
--- a/src/state.ml
+++ b/src/state.ml
@@ -286,7 +286,7 @@ let register_refs_lem mwords registers =
"";
"val option_of_regval : forall 'a. (register_value -> maybe 'a) -> register_value -> maybe (maybe 'a)";
"let option_of_regval of_regval = function";
- " | Regval_option v -> Maybe.map of_regval v";
+ " | Regval_option v -> Just (Maybe.bind v of_regval)";
" | _ -> Nothing";
"end";
"";
@@ -388,6 +388,19 @@ let generate_isa_lemmas mwords (Defs defs : tannot defs) =
"proof -";
" from assms have \"of_rv \\<circ> rv_of = Some\" by auto";
" then show ?thesis by (auto simp: vector_of_regval_def regval_of_vector_def)";
+ "qed";
+ "";
+ "lemma option_of_rv_rv_of_option[simp]:";
+ " assumes \"\\<And>v. of_rv (rv_of v) = Some v\"";
+ " shows \"option_of_regval of_rv (regval_of_option rv_of v) = Some v\"";
+ " using assms by (cases v) (auto simp: option_of_regval_def regval_of_option_def)";
+ "";
+ "lemma list_of_rv_rv_of_list[simp]:";
+ " assumes \"\\<And>v. of_rv (rv_of v) = Some v\"";
+ " shows \"list_of_regval of_rv (regval_of_list rv_of v) = Some v\"";
+ "proof -";
+ " from assms have \"of_rv \\<circ> rv_of = Some\" by auto";
+ " with assms show ?thesis by (induction v) (auto simp: list_of_regval_def regval_of_list_def)";
"qed"] ^^
hardline ^^ hardline ^^
separate_map (hardline ^^ hardline) register_lemmas registers