diff options
author | Enrico Tassi <gareuselesinge@debian.org> | 2015-01-25 14:42:51 +0100 |
---|---|---|
committer | Enrico Tassi <gareuselesinge@debian.org> | 2015-01-25 14:42:51 +0100 |
commit | 7cfc4e5146be5666419451bdd516f1f3f264d24a (patch) | |
tree | e4197645da03dc3c7cc84e434cc31d0a0cca7056 /plugins/extraction/mlutil.ml | |
parent | 420f78b2caeaaddc6fe484565b2d0e49c66888e5 (diff) |
Imported Upstream version 8.5~beta1+dfsg
Diffstat (limited to 'plugins/extraction/mlutil.ml')
-rw-r--r-- | plugins/extraction/mlutil.ml | 291 |
1 files changed, 174 insertions, 117 deletions
diff --git a/plugins/extraction/mlutil.ml b/plugins/extraction/mlutil.ml index 1462d3e7..9fdb0205 100644 --- a/plugins/extraction/mlutil.ml +++ b/plugins/extraction/mlutil.ml @@ -1,17 +1,16 @@ (************************************************************************) (* v * The Coq Proof Assistant / The Coq Development Team *) -(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2014 *) +(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2015 *) (* \VV/ **************************************************************) (* // * This file is distributed under the terms of the *) (* * GNU Lesser General Public License Version 2.1 *) (************************************************************************) (*i*) -open Pp open Util open Names open Libnames -open Nametab +open Globnames open Table open Miniml (*i*) @@ -23,14 +22,14 @@ exception Impossible (*S Names operations. *) -let anonymous_name = id_of_string "x" -let dummy_name = id_of_string "_" +let anonymous_name = Id.of_string "x" +let dummy_name = Id.of_string "_" let anonymous = Id anonymous_name let id_of_name = function | Anonymous -> anonymous_name - | Name id when id = dummy_name -> anonymous_name + | Name id when Id.equal id dummy_name -> anonymous_name | Name id -> id let id_of_mlid = function @@ -54,6 +53,22 @@ let new_meta _ = incr meta_count; Tmeta {id = !meta_count; contents = None} +let rec eq_ml_type t1 t2 = match t1, t2 with +| Tarr (tl1, tr1), Tarr (tl2, tr2) -> + eq_ml_type tl1 tl2 && eq_ml_type tr1 tr2 +| Tglob (gr1, t1), Tglob (gr2, t2) -> + eq_gr gr1 gr2 && List.equal eq_ml_type t1 t2 +| Tvar i1, Tvar i2 -> Int.equal i1 i2 +| Tvar' i1, Tvar' i2 -> Int.equal i1 i2 +| Tmeta m1, Tmeta m2 -> eq_ml_meta m1 m2 +| Tdummy k1, Tdummy k2 -> k1 == k2 +| Tunknown, Tunknown -> true +| Taxiom, Taxiom -> true +| _ -> false + +and eq_ml_meta m1 m2 = + Int.equal m1.id m2.id && Option.equal eq_ml_type m1.contents m2.contents + (* Simultaneous substitution of [[Tvar 1; ... ; Tvar n]] by [l] in a ML type. *) let type_subst_list l t = @@ -86,7 +101,7 @@ let instantiation (nb,t) = type_subst_vect (Array.init nb new_meta) t let rec type_occurs alpha t = match t with - | Tmeta {id=beta; contents=None} -> alpha = beta + | Tmeta {id=beta; contents=None} -> Int.equal alpha beta | Tmeta {contents=Some u} -> type_occurs alpha u | Tarr (t1, t2) -> type_occurs alpha t1 || type_occurs alpha t2 | Tglob (r,l) -> List.exists (type_occurs alpha) l @@ -95,7 +110,7 @@ let rec type_occurs alpha t = (*s Most General Unificator *) let rec mgu = function - | Tmeta m, Tmeta m' when m.id = m'.id -> () + | Tmeta m, Tmeta m' when Int.equal m.id m'.id -> () | Tmeta m, t | t, Tmeta m -> (match m.contents with | Some u -> mgu (u, t) @@ -103,21 +118,24 @@ let rec mgu = function | None -> m.contents <- Some t) | Tarr(a, b), Tarr(a', b') -> mgu (a, a'); mgu (b, b') - | Tglob (r,l), Tglob (r',l') when r = r' -> + | Tglob (r,l), Tglob (r',l') when Globnames.eq_gr r r' -> List.iter mgu (List.combine l l') - | (Tdummy _, _ | _, Tdummy _) when lang() = Haskell -> () + | (Tdummy _, _ | _, Tdummy _) when lang() == Haskell -> () | Tdummy _, Tdummy _ -> () - | t, u when t = u -> () (* for Tvar, Tvar', Tunknown, Taxiom *) + | Tvar i, Tvar j when Int.equal i j -> () + | Tvar' i, Tvar' j when Int.equal i j -> () + | Tunknown, Tunknown -> () + | Taxiom, Taxiom -> () | _ -> raise Impossible let needs_magic p = try mgu p; false with Impossible -> true -let put_magic_if b a = if b && lang () <> Scheme then MLmagic a else a +let put_magic_if b a = if b && lang () != Scheme then MLmagic a else a -let put_magic p a = if needs_magic p && lang () <> Scheme then MLmagic a else a +let put_magic p a = if needs_magic p && lang () != Scheme then MLmagic a else a let generalizable a = - lang () <> Ocaml || + lang () != Ocaml || match a with | MLapp _ -> false | _ -> true (* TODO, this is just an approximation for the moment *) @@ -148,7 +166,7 @@ module Mlenv = struct (* [find_free] finds the free meta in a type. *) let rec find_free set = function - | Tmeta m when m.contents = None -> Metaset.add m set + | Tmeta m when Option.is_empty m.contents -> Metaset.add m set | Tmeta {contents = Some t} -> find_free set t | Tarr (a,b) -> find_free (find_free set a) b | Tglob (_,l) -> List.fold_left find_free set l @@ -172,12 +190,12 @@ module Mlenv = struct let generalization mle t = let c = ref 0 in - let map = ref (Intmap.empty : int Intmap.t) in - let add_new i = incr c; map := Intmap.add i !c !map; !c in + let map = ref (Int.Map.empty : int Int.Map.t) in + let add_new i = incr c; map := Int.Map.add i !c !map; !c in let rec meta2var t = match t with | Tmeta {contents=Some u} -> meta2var u | Tmeta ({id=i} as m) -> - (try Tvar (Intmap.find i !map) + (try Tvar (Int.Map.find i !map) with Not_found -> if Metaset.mem m mle.free then t else Tvar (add_new i)) @@ -225,21 +243,6 @@ let type_maxvar t = | _ -> n in parse 0 t -(*s What are the type variables occurring in [t]. *) - -let intset_union_map_list f l = - List.fold_left (fun s t -> Intset.union s (f t)) Intset.empty l - -let intset_union_map_array f a = - Array.fold_left (fun s t -> Intset.union s (f t)) Intset.empty a - -let rec type_listvar = function - | Tmeta {contents = Some t} -> type_listvar t - | Tvar i | Tvar' i -> Intset.singleton i - | Tarr (a,b) -> Intset.union (type_listvar a) (type_listvar b) - | Tglob (_,l) -> intset_union_map_list type_listvar l - | _ -> Intset.empty - (*s From [a -> b -> c] to [[a;b],c]. *) let rec type_decomp = function @@ -283,13 +286,13 @@ let type_simpl = type_expand (fun _ -> None) (*s Generating a signature from a ML type. *) let type_to_sign env t = match type_expand env t with - | Tdummy d -> Kill d + | Tdummy d when not (conservative_types ()) -> Kill d | _ -> Keep let type_to_signature env t = let rec f = function | Tmeta {contents = Some t} -> f t - | Tarr (Tdummy d, b) -> Kill d :: f b + | Tarr (Tdummy d, b) when not (conservative_types ()) -> Kill d :: f b | Tarr (_, b) -> Keep :: f b | _ -> [] in f (type_expand env t) @@ -318,7 +321,7 @@ let rec sign_kind = function | NonLogicalSig -> NonLogicalSig | UnsafeLogicalSig -> UnsafeLogicalSig | SafeLogicalSig | EmptySig -> - if k = Kother then UnsafeLogicalSig else SafeLogicalSig + if k == Kother then UnsafeLogicalSig else SafeLogicalSig (* Removing the final [Keep] in a signature *) @@ -326,17 +329,17 @@ let rec sign_no_final_keeps = function | [] -> [] | k :: s -> let s' = k :: sign_no_final_keeps s in - if s' = [Keep] then [] else s' + match s' with [Keep] -> [] | _ -> s' (*s Removing [Tdummy] from the top level of a ML type. *) let type_expunge_from_sign env s t = let rec expunge s t = - if s = [] then t else match t with + if List.is_empty s then t else match t with | Tmeta {contents = Some t} -> expunge s t | Tarr (a,b) -> let t = expunge (List.tl s) b in - if List.hd s = Keep then Tarr (a, t) else t + if List.hd s == Keep then Tarr (a, t) else t | Tglob (r,l) -> (match env r with | Some mlt -> expunge s (type_subst_list l mlt) @@ -344,7 +347,7 @@ let type_expunge_from_sign env s t = | _ -> assert false in let t = expunge (sign_no_final_keeps s) t in - if lang () <> Haskell && sign_kind s = UnsafeLogicalSig then + if lang () != Haskell && sign_kind s == UnsafeLogicalSig then Tarr (Tdummy Kother, t) else t @@ -353,7 +356,55 @@ let type_expunge env t = (*S Generic functions over ML ast terms. *) -let mlapp f a = if a = [] then f else MLapp (f,a) +let mlapp f a = if List.is_empty a then f else MLapp (f,a) + +(** Equality *) + +let eq_ml_ident i1 i2 = match i1, i2 with +| Dummy, Dummy -> true +| Id id1, Id id2 -> Id.equal id1 id2 +| Tmp id1, Tmp id2 -> Id.equal id1 id2 +| _ -> false + +let rec eq_ml_ast t1 t2 = match t1, t2 with +| MLrel i1, MLrel i2 -> + Int.equal i1 i2 +| MLapp (f1, t1), MLapp (f2, t2) -> + eq_ml_ast f1 f2 && List.equal eq_ml_ast t1 t2 +| MLlam (na1, t1), MLlam (na2, t2) -> + eq_ml_ident na1 na2 && eq_ml_ast t1 t2 +| MLletin (na1, c1, t1), MLletin (na2, c2, t2) -> + eq_ml_ident na1 na2 && eq_ml_ast c1 c2 && eq_ml_ast t1 t2 +| MLglob gr1, MLglob gr2 -> eq_gr gr1 gr2 +| MLcons (t1, gr1, c1), MLcons (t2, gr2, c2) -> + eq_ml_type t1 t2 && eq_gr gr1 gr2 && List.equal eq_ml_ast c1 c2 +| MLtuple t1, MLtuple t2 -> + List.equal eq_ml_ast t1 t2 +| MLcase (t1, c1, p1), MLcase (t2, c2, p2) -> + eq_ml_type t1 t2 && eq_ml_ast c1 c2 && Array.equal eq_ml_branch p1 p2 +| MLfix (i1, id1, t1), MLfix (i2, id2, t2) -> + Int.equal i1 i2 && Array.equal Id.equal id1 id2 && Array.equal eq_ml_ast t1 t2 +| MLexn e1, MLexn e2 -> String.equal e1 e2 +| MLdummy, MLdummy -> true +| MLaxiom, MLaxiom -> true +| MLmagic t1, MLmagic t2 -> eq_ml_ast t1 t2 +| _ -> false + +and eq_ml_pattern p1 p2 = match p1, p2 with +| Pcons (gr1, p1), Pcons (gr2, p2) -> + eq_gr gr1 gr2 && List.equal eq_ml_pattern p1 p2 +| Ptuple p1, Ptuple p2 -> + List.equal eq_ml_pattern p1 p2 +| Prel i1, Prel i2 -> + Int.equal i1 i2 +| Pwild, Pwild -> true +| Pusual gr1, Pusual gr2 -> eq_gr gr1 gr2 +| _ -> false + +and eq_ml_branch (id1, p1, t1) (id2, p2, t2) = + List.equal eq_ml_ident id1 id2 && + eq_ml_pattern p1 p2 && + eq_ml_ast t1 t2 (*s [ast_iter_rel f t] applies [f] on every [MLrel] in t. It takes care of the number of bingings crossed before reaching the [MLrel]. *) @@ -428,7 +479,7 @@ let ast_iter f = function let ast_occurs k t = try - ast_iter_rel (fun i -> if i = k then raise Found) t; false + ast_iter_rel (fun i -> if Int.equal i k then raise Found) t; false with Found -> true (*s [occurs_itvl k k' t] returns [true] if there is a [(Rel i)] @@ -444,7 +495,7 @@ let ast_occurs_itvl k k' t = let nb_occur_match = let rec nb k = function - | MLrel i -> if i = k then 1 else 0 + | MLrel i -> if Int.equal i k then 1 else 0 | MLcase(_,a,v) -> (nb k a) + Array.fold_left @@ -466,7 +517,7 @@ let ast_lift k t = let rec liftrec n = function | MLrel i as a -> if i-n < 1 then a else MLrel (i+k) | a -> ast_map_lift liftrec n a - in if k = 0 then t else liftrec 0 t + in if Int.equal k 0 then t else liftrec 0 t let ast_pop t = ast_lift (-1) t @@ -490,7 +541,7 @@ let ast_subst e = let rec subst n = function | MLrel i as a -> let i' = i-n in - if i'=1 then ast_lift n e + if Int.equal i' 1 then ast_lift n e else if i'<1 then a else MLrel (i-1) | a -> ast_map_lift subst n a @@ -525,17 +576,18 @@ let has_deep_pattern br = | Pcons (_,l) | Ptuple l -> not (List.for_all is_basic_pattern l) | Pusual _ | Prel _ | Pwild -> false in - array_exists (function (_,pat,_) -> deep pat) br + Array.exists (function (_,pat,_) -> deep pat) br let is_regular_match br = - if Array.length br = 0 then false (* empty match becomes MLexn *) + if Array.is_empty br then false (* empty match becomes MLexn *) else try let get_r (ids,pat,c) = match pat with | Pusual r -> r | Pcons (r,l) -> - if not (list_for_all_i (fun i -> (=) (Prel i)) 1 (List.rev l)) + let is_rel i = function Prel j -> Int.equal i j | _ -> false in + if not (List.for_all_i is_rel 1 (List.rev l)) then raise Impossible; r | _ -> raise Impossible @@ -544,7 +596,11 @@ let is_regular_match br = | ConstructRef (ind,_) -> ind | _ -> raise Impossible in - array_for_all_i (fun i tr -> get_r tr = ConstructRef (ind,i+1)) 0 br + let is_ref i tr = match get_r tr with + | ConstructRef (ind', j) -> eq_ind ind ind' && Int.equal j (i + 1) + | _ -> false + in + Array.for_all_i is_ref 0 br with Impossible -> false (*S Operations concerning lambdas. *) @@ -562,7 +618,7 @@ let collect_lams = let collect_n_lams = let rec collect acc n t = - if n = 0 then acc,t + if Int.equal n 0 then acc,t else match t with | MLlam(id,t) -> collect (id::acc) (n-1) t | _ -> assert false @@ -571,7 +627,7 @@ let collect_n_lams = (*s [remove_n_lams] just removes some [MLlam]. *) let rec remove_n_lams n t = - if n = 0 then t + if Int.equal n 0 then t else match t with | MLlam(_,t) -> remove_n_lams (n-1) t | _ -> assert false @@ -609,7 +665,7 @@ let rec anonym_or_dummy_lams a = function (*s The following function creates [MLrel n;...;MLrel 1] *) let rec eta_args n = - if n = 0 then [] else (MLrel n)::(eta_args (pred n)) + if Int.equal n 0 then [] else (MLrel n)::(eta_args (pred n)) (*s Same, but filtered by a signature. *) @@ -621,25 +677,26 @@ let rec eta_args_sign n = function (*s This one tests [MLrel (n+k); ... ;MLrel (1+k)] *) let rec test_eta_args_lift k n = function - | [] -> n=0 - | a :: q -> (a = (MLrel (k+n))) && (test_eta_args_lift k (pred n) q) + | [] -> Int.equal n 0 + | MLrel m :: q -> Int.equal (k+n) m && (test_eta_args_lift k (pred n) q) + | _ -> false (*s Computes an eta-reduction. *) let eta_red e = let ids,t = collect_lams e in let n = List.length ids in - if n = 0 then e + if Int.equal n 0 then e else match t with | MLapp (f,a) -> let m = List.length a in let ids,body,args = - if m = n then + if Int.equal m n then [], f, a else if m < n then - list_skipn m ids, f, a + List.skipn m ids, f, a else (* m > n *) - let a1,a2 = list_chop (m-n) a in + let a1,a2 = List.chop (m-n) a in [], MLapp (f,a1), a2 in let p = List.length args in @@ -715,7 +772,7 @@ let branch_as_fun typ (l,p,c) = if i'<1 then c else if i'>nargs then MLrel (i-nargs+1) else raise Impossible - | MLcons _ as cons' when cons' = ast_lift n cons -> MLrel (n+1) + | MLcons _ as cons' when eq_ml_ast cons' (ast_lift n cons) -> MLrel (n+1) | a -> ast_map_lift genrec n a in genrec 0 c @@ -739,27 +796,33 @@ let branch_as_cst (l,_,c) = When searching for the best factorisation below, we'll try both. *) -(* The following structure allows to record which element occurred +(* The following structure allows recording which element occurred at what position, and then finally return the most frequent element and its positions. *) let census_add, census_max, census_clean = - let h = Hashtbl.create 13 in - let clear () = Hashtbl.clear h in - let add e i = - let s = try Hashtbl.find h e with Not_found -> Intset.empty in - Hashtbl.replace h e (Intset.add i s) + let h = ref [] in + let clearf () = h := [] in + let rec add k v = function + | [] -> raise Not_found + | (k', s) as p :: l -> + if eq_ml_ast k k' then (k', Int.Set.add v s) :: l + else p :: add k v l + in + let addf k i = + try h := add k i !h + with Not_found -> h := (k, Int.Set.singleton i) :: !h in - let max e0 = - let len = ref 0 and lst = ref Intset.empty and elm = ref e0 in - Hashtbl.iter - (fun e s -> - let n = Intset.cardinal s in + let maxf k = + let len = ref 0 and lst = ref Int.Set.empty and elm = ref k in + List.iter + (fun (e, s) -> + let n = Int.Set.cardinal s in if n > !len then begin len := n; lst := s; elm := e end) - h; + !h; (!elm,!lst) in - (add,max,clear) + (addf,maxf,clearf) (* [factor_branches] return the longest possible list of branches that have the same factorization, either as a function or as a @@ -771,7 +834,7 @@ let is_opt_pat (_,p,_) = match p with | _ -> false let factor_branches o typ br = - if array_exists is_opt_pat br then None (* already optimized *) + if Array.exists is_opt_pat br then None (* already optimized *) else begin census_clean (); for i = 0 to Array.length br - 1 do @@ -782,8 +845,8 @@ let factor_branches o typ br = done; let br_factor, br_set = census_max MLdummy in census_clean (); - let n = Intset.cardinal br_set in - if n = 0 then None + let n = Int.Set.cardinal br_set in + if Int.equal n 0 then None else if Array.length br >= 2 && n < 2 then None else Some (br_factor, br_set) end @@ -794,17 +857,17 @@ let rec merge_ids ids ids' = match ids,ids' with | [],l -> l | l,[] -> l | i::ids, i'::ids' -> - (if i = Dummy then i' else i) :: (merge_ids ids ids') + (if i == Dummy then i' else i) :: (merge_ids ids ids') let is_exn = function MLexn _ -> true | _ -> false -let rec permut_case_fun br acc = +let permut_case_fun br acc = let nb = ref max_int in Array.iter (fun (_,_,t) -> let ids, c = collect_lams t in let n = List.length ids in if (n < !nb) && (not (is_exn c)) then nb := n) br; - if !nb = max_int || !nb = 0 then ([],br) + if Int.equal !nb max_int || Int.equal !nb 0 then ([],br) else begin let br = Array.copy br in let ids = ref [] in @@ -837,16 +900,16 @@ let rec iota_red i lift br ((typ,r,a) as cons) = if i >= Array.length br then raise Impossible; let (ids,p,c) = br.(i) in match p with - | Pusual r' | Pcons (r',_) when r'<>r -> iota_red (i+1) lift br cons + | Pusual r' | Pcons (r',_) when not (Globnames.eq_gr r' r) -> iota_red (i+1) lift br cons | Pusual r' -> let c = named_lams (List.rev ids) c in let c = ast_lift lift c in MLapp (c,a) - | Prel 1 when List.length ids = 1 -> + | Prel 1 when Int.equal (List.length ids) 1 -> let c = MLlam (List.hd ids, c) in let c = ast_lift lift c in MLapp(c,[MLcons(typ,r,a)]) - | Pwild when ids = [] -> ast_lift lift c + | Pwild when List.is_empty ids -> ast_lift lift c | _ -> raise Impossible (* TODO: handle some more cases *) (* [iota_gen] is an extension of [iota_red] where we allow to @@ -872,15 +935,11 @@ let is_imm_apply = function MLapp (MLrel 1, _) -> true | _ -> false Unfolding them leads to more natural code (and more dummy removal) *) let is_program_branch = function - | Id id -> - let s = string_of_id id in - let br = "program_branch_" in - let n = String.length br in - (try - ignore (int_of_string (String.sub s n (String.length s - n))); - String.sub s 0 n = br - with e when Errors.noncritical e -> false) | Tmp _ | Dummy -> false + | Id id -> + let s = Id.to_string id in + try Scanf.sscanf s "program_branch_%d%!" (fun _ -> true) + with Scanf.Scan_failure _ | End_of_file -> false let expand_linear_let o id e = o.opt_lin_let || is_tmp id || is_program_branch id || is_imm_apply e @@ -901,7 +960,7 @@ let rec simpl o = function if (is_atomic c) || (is_atomic e) || (let n = nb_occur_match e in - (n = 0 || (n=1 && expand_linear_let o id e))) + (Int.equal n 0 || (Int.equal n 1 && expand_linear_let o id e))) then simpl o (ast_subst c e) else @@ -954,14 +1013,14 @@ and simpl_case o typ br e = (* Swap the case and the lam if possible *) let ids,br = if o.opt_case_fun then permut_case_fun br [] else [],br in let n = List.length ids in - if n <> 0 then + if not (Int.equal n 0) then simpl o (named_lams ids (MLcase (typ, ast_lift n e, br))) else (* Can we merge several branches as the same constant or function ? *) - if lang() = Scheme || is_custom_match br + if lang() == Scheme || is_custom_match br then MLcase (typ, e, br) else match factor_branches o typ br with - | Some (f,ints) when Intset.cardinal ints = Array.length br -> + | Some (f,ints) when Int.equal (Int.Set.cardinal ints) (Array.length br) -> (* If all branches have been factorized, we remove the match *) simpl o (MLletin (Tmp anonymous_name, e, f)) | Some (f,ints) -> @@ -970,7 +1029,7 @@ and simpl_case o typ br e = else ([], Pwild, ast_pop f) in let brl = Array.to_list br in - let brl_opt = list_filter_i (fun i _ -> not (Intset.mem i ints)) brl in + let brl_opt = List.filteri (fun i _ -> not (Int.Set.mem i ints)) brl in let brl_opt = brl_opt @ [last_br] in MLcase (typ, e, Array.of_list brl_opt) | None -> MLcase (typ, e, br) @@ -996,9 +1055,9 @@ let rec select_via_bl l args = match l,args with let kill_some_lams bl (ids,c) = let n = List.length bl in - let n' = List.fold_left (fun n b -> if b=Keep then (n+1) else n) 0 bl in - if n = n' then ids,c - else if n' = 0 then [],ast_lift (-n) c + let n' = List.fold_left (fun n b -> if b == Keep then (n+1) else n) 0 bl in + if Int.equal n n' then ids,c + else if Int.equal n' 0 then [],ast_lift (-n) c else begin let v = Array.make n None in let rec parse_ids i j = function @@ -1016,15 +1075,15 @@ let kill_some_lams bl (ids,c) = let kill_dummy_lams c = let ids,c = collect_lams c in let bl = List.map sign_of_id ids in - if not (List.mem Keep bl) then raise Impossible; + if not (List.memq Keep bl) then raise Impossible; let rec fst_kill n = function | [] -> raise Impossible | Kill _ :: bl -> n | Keep :: bl -> fst_kill (n+1) bl in let skip = max 0 ((fst_kill 0 bl) - 1) in - let ids_skip, ids = list_chop skip ids in - let _, bl = list_chop skip bl in + let ids_skip, ids = List.chop skip ids in + let _, bl = List.chop skip bl in let c = named_lams ids_skip c in let ids',c = kill_some_lams bl (ids,c) in ids, named_lams ids' c @@ -1052,7 +1111,7 @@ let case_expunge s e = let m = List.length s in let n = nb_lams e in let p = if m <= n then collect_n_lams m e - else eta_expansion_sign (list_skipn n s) (collect_lams e) in + else eta_expansion_sign (List.skipn n s) (collect_lams e) in kill_some_lams (List.rev s) p (*s [term_expunge] takes a function [fun idn ... id1 -> c] @@ -1061,10 +1120,10 @@ let case_expunge s e = if all lambdas are logical dummy and the target language is strict. *) let term_expunge s (ids,c) = - if s = [] then c + if List.is_empty s then c else let ids,c = kill_some_lams (List.rev s) (ids,c) in - if ids = [] && lang () <> Haskell && List.mem (Kill Kother) s then + if List.is_empty ids && lang () != Haskell && List.mem (Kill Kother) s then MLlam (Dummy, ast_lift 1 c) else named_lams ids c @@ -1076,7 +1135,7 @@ let kill_dummy_args ids r t = let m = List.length ids in let bl = List.rev_map sign_of_id ids in let rec found n = function - | MLrel r' when r' = r + n -> true + | MLrel r' when Int.equal r' (r + n) -> true | MLmagic e -> found n e | _ -> false in @@ -1086,7 +1145,7 @@ let kill_dummy_args ids r t = let a = List.map (killrec n) a in let a = List.map (ast_lift k) a in let a = select_via_bl bl (a @ (eta_args k)) in - named_lams (list_firstn k ids) (MLapp (ast_lift k e, a)) + named_lams (List.firstn k ids) (MLapp (ast_lift k e, a)) | e when found n e -> let a = select_via_bl bl (eta_args m) in named_lams ids (MLapp (ast_lift m e, a)) @@ -1153,7 +1212,7 @@ let normalize a = let o = optims () in let rec norm a = let a' = if o.opt_kill_dum then kill_dummy (simpl o a) else simpl o a in - if a = a' then a else norm a' + if eq_ml_ast a a' then a else norm a' in norm a (*S Special treatment of fixpoint for pretty-printing purpose. *) @@ -1165,7 +1224,7 @@ let general_optimize_fix f ids n args m c = | MLrel j when v.(j-1)>=0 -> if ast_occurs (j+1) c then raise Impossible else v.(j-1)<-(-i-1) | _ -> raise Impossible - in list_iter_i aux args; + in List.iteri aux args; let args_f = List.rev_map (fun i -> MLrel (i+m+1)) (Array.to_list v) in let new_f = anonym_tmp_lams (MLapp (MLrel (n+m+1),args_f)) m in let new_c = named_lams ids (normalize (MLapp ((ast_subst new_f c),args))) in @@ -1176,7 +1235,7 @@ let optimize_fix a = else let ids,a' = collect_lams a in let n = List.length ids in - if n = 0 then a + if Int.equal n 0 then a else match a' with | MLfix(_,[|f|],[|c|]) -> let new_f = MLapp (MLrel (n+1),eta_args n) in @@ -1244,7 +1303,7 @@ let rec non_stricts add cand = function let cand = if add then 1::cand else cand in pop 1 (non_stricts add cand t) | MLrel n -> - List.filter ((<>) n) cand + List.filter (fun m -> not (Int.equal m n)) cand | MLapp (t,l)-> let cand = non_stricts false cand t in List.fold_left (non_stricts false) cand l @@ -1268,7 +1327,7 @@ let rec non_stricts add cand = function let n = List.length i in let cand = lift n cand in let cand = pop n (non_stricts add cand t) in - Sort.merge (<=) cand c) [] v + List.merge Int.compare cand c) [] v (* [merge] may duplicates some indices, but I don't mind. *) | MLmagic t -> non_stricts add cand t @@ -1304,7 +1363,7 @@ let is_not_strict t = restriction for the moment. *) -open Declarations +open Declareops let inline_test r t = if not (auto_inline ()) then false @@ -1312,7 +1371,7 @@ let inline_test r t = let c = match r with ConstRef c -> c | _ -> assert false in let has_body = try constant_has_body (Global.lookup_constant c) - with e when Errors.noncritical e -> false + with Not_found -> false in has_body && (let t1 = eta_red t in @@ -1320,10 +1379,8 @@ let inline_test r t = not (is_fix t2) && ml_size t < 12 && is_not_strict t) let con_of_string s = - let null = empty_dirpath in - match repr_dirpath (dirpath_of_string s) with - | id :: d -> make_con (MPfile (make_dirpath d)) null (label_of_id id) - | [] -> assert false + let d, id = Libnames.split_dirpath (dirpath_of_string s) in + Constant.make2 (MPfile d) (Label.of_id id) let manual_inline_set = List.fold_right (fun x -> Cset_env.add (con_of_string x)) @@ -1355,6 +1412,6 @@ let inline r t = not (to_keep r) (* The user DOES want to keep it *) && not (is_inline_custom r) && (to_inline r (* The user DOES want to inline it *) - || (lang () <> Haskell && not (is_projection r) && + || (lang () != Haskell && not (is_projection r) && (is_recursor r || manual_inline r || inline_test r t))) |