summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/pretty_print_coq.ml19
-rw-r--r--src/rewrites.ml28
2 files changed, 27 insertions, 20 deletions
diff --git a/src/pretty_print_coq.ml b/src/pretty_print_coq.ml
index 90484598..72d7730e 100644
--- a/src/pretty_print_coq.ml
+++ b/src/pretty_print_coq.ml
@@ -2519,7 +2519,7 @@ let merge_var_patterns map pats =
type mutrec_pos = NotMutrec | FirstFn | LaterFn
-let doc_funcl mutrec rec_opt (FCL_aux(FCL_Funcl(id, pexp), annot)) =
+let doc_funcl mutrec rec_opt ?rec_set (FCL_aux(FCL_Funcl(id, pexp), annot)) =
let env = env_of_annot annot in
let (tq,typ) = Env.get_val_spec_orig id env in
let (arg_typs, ret_typ, eff) = match typ with
@@ -2542,9 +2542,8 @@ let doc_funcl mutrec rec_opt (FCL_aux(FCL_Funcl(id, pexp), annot)) =
let kid_to_arg_rename, pats = merge_var_patterns kid_to_arg_rename pats in
let kids_used = KidSet.diff bound_kids eliminated_kids in
let is_measured, recursive_ids = match rec_opt with
- (* No mutual recursion in this backend yet; only change recursive
- definitions where we have a measure *)
- | Rec_aux (Rec_measure _,_) -> true, IdSet.singleton id
+ | Rec_aux (Rec_measure _,_) ->
+ true, (match rec_set with None -> IdSet.singleton id | Some s -> s)
| _ -> false, IdSet.empty
in
let kir_rev =
@@ -2694,17 +2693,17 @@ let get_id = function
(* Coq doesn't support multiple clauses for a single function joined
by "and". However, all the funcls should have been merged by the
merge_funcls rewrite now. *)
-let doc_fundef_rhs ?(mutrec=NotMutrec) (FD_aux(FD_function(r, typa, efa, funcls),(l,_))) =
+let doc_fundef_rhs ?(mutrec=NotMutrec) rec_set (FD_aux(FD_function(r, typa, efa, funcls),(l,_))) =
match funcls with
| [] -> unreachable l __POS__ "function with no clauses"
- | [funcl] -> doc_funcl mutrec r funcl
+ | [funcl] -> doc_funcl mutrec r ~rec_set funcl
| (FCL_aux (FCL_Funcl (id,_),_))::_ -> unreachable l __POS__ ("function " ^ string_of_id id ^ " has multiple clauses in backend")
-let doc_mutrec = function
+let doc_mutrec rec_set = function
| [] -> failwith "DEF_internal_mutrec with empty function list"
| fundef::fundefs ->
- doc_fundef_rhs ~mutrec:FirstFn fundef ^^ hardline ^^
- separate_map hardline (doc_fundef_rhs ~mutrec:LaterFn) fundefs ^^ dot
+ doc_fundef_rhs ~mutrec:FirstFn rec_set fundef ^^ hardline ^^
+ separate_map hardline (doc_fundef_rhs ~mutrec:LaterFn rec_set) fundefs ^^ dot
let rec doc_fundef (FD_aux(FD_function(r, typa, efa, fcls),fannot)) =
match fcls with
@@ -2918,7 +2917,7 @@ let rec doc_def unimplemented generic_eq_types def =
| DEF_default df -> empty
| DEF_fundef fdef -> group (doc_fundef fdef) ^/^ hardline
- | DEF_internal_mutrec fundefs -> doc_mutrec fundefs ^/^ hardline
+ | DEF_internal_mutrec fundefs -> doc_mutrec (ids_of_def def) fundefs ^/^ hardline
| DEF_val (LB_aux (LB_val (pat, exp), _)) -> doc_val pat exp
| DEF_scattered sdef -> failwith "doc_def: shoulnd't have DEF_scattered at this point"
| DEF_mapdef (MD_aux (_, (l,_))) -> unreachable l __POS__ "Coq doesn't support mappings"
diff --git a/src/rewrites.ml b/src/rewrites.ml
index 2a5799d3..11b1d469 100644
--- a/src/rewrites.ml
+++ b/src/rewrites.ml
@@ -4476,8 +4476,9 @@ let rewrite_explicit_measure env (Defs defs) =
Bindings.add id (mpat,mexp) measures
| _ -> measures
in
- let scan_def measures = function
+ let rec scan_def measures = function
| DEF_fundef fd -> scan_function measures fd
+ | DEF_internal_mutrec fds -> List.fold_left scan_function measures fds
| _ -> measures
in
let measures = List.fold_left scan_def Bindings.empty defs in
@@ -4510,7 +4511,7 @@ let rewrite_explicit_measure env (Defs defs) =
| exception Not_found -> [vs]
in
(* Add extra argument and assertion to each funcl, and rewrite recursive calls *)
- let rewrite_funcl (FCL_aux (FCL_Funcl (id,pexp),fcl_ann) as fcl) =
+ let rewrite_funcl recset (FCL_aux (FCL_Funcl (id,pexp),fcl_ann) as fcl) =
let loc = Parse_ast.Generated (fst fcl_ann) in
let P_aux (pat,pann),guard,body,ann = destruct_pexp pexp in
let extra_pat = P_aux (P_id limit,(loc,empty_tannot)) in
@@ -4537,15 +4538,15 @@ let rewrite_explicit_measure env (Defs defs) =
let body =
fold_exp { id_exp_alg with
e_app = (fun (f,args) ->
- if Id.compare f id == 0
- then E_app (rec_id id, args@[tick])
+ if IdSet.mem f recset
+ then E_app (rec_id f, args@[tick])
else E_app (f, args))
} body
in
let body = E_aux (E_block [assert_exp; body],(loc,empty_tannot)) in
FCL_aux (FCL_Funcl (rec_id id, construct_pexp (P_aux (pat,pann),guard,body,ann)),fcl_ann)
in
- let rewrite_function (FD_aux (FD_function (r,t,e,fcls),ann) as fd) =
+ let rewrite_function recset (FD_aux (FD_function (r,t,e,fcls),ann) as fd) =
let loc = Parse_ast.Generated (fst ann) in
match fcls with
| FCL_aux (FCL_Funcl (id,_),fcl_ann)::_ -> begin
@@ -4593,15 +4594,22 @@ let rewrite_explicit_measure env (Defs defs) =
let new_rec =
Rec_aux (Rec_measure (P_aux (P_tup (List.map (fun _ -> P_aux (P_wild,(loc,empty_tannot))) measure_pats @ [P_aux (P_id limit,(loc,empty_tannot))]),(loc,empty_tannot)), E_aux (E_id limit, (loc,empty_tannot))), loc)
in
- [FD_aux (FD_function (new_rec,t,e,List.map rewrite_funcl fcls),ann);
- FD_aux (FD_function (Rec_aux (Rec_nonrec,loc),t,e,[wrapper]),ann)]
- | exception Not_found -> [fd]
+ FD_aux (FD_function (new_rec,t,e,List.map (rewrite_funcl recset) fcls),ann),
+ [FD_aux (FD_function (Rec_aux (Rec_nonrec,loc),t,e,[wrapper]),ann)]
+ | exception Not_found -> fd,[]
end
- | _ -> [fd]
+ | _ -> fd,[]
in
let rewrite_def = function
| DEF_spec vs -> List.map (fun vs -> DEF_spec vs) (rewrite_spec vs)
- | DEF_fundef fd -> List.map (fun f -> DEF_fundef f) (rewrite_function fd)
+ | DEF_fundef fd ->
+ let fd,extra = rewrite_function (IdSet.singleton (id_of_fundef fd)) fd in
+ List.map (fun f -> DEF_fundef f) (fd::extra)
+ | (DEF_internal_mutrec fds) as d ->
+ let recset = ids_of_def d in
+ let fds,extras = List.split (List.map (rewrite_function recset) fds) in
+ let extras = List.concat extras in
+ (DEF_internal_mutrec fds)::(List.map (fun f -> DEF_fundef f) extras)
| d -> [d]
in
Defs (List.flatten (List.map rewrite_def defs))