aboutsummaryrefslogtreecommitdiffhomepage
path: root/contrib/extraction
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/extraction')
-rw-r--r--contrib/extraction/extract_env.ml13
-rw-r--r--contrib/extraction/extraction.ml192
-rw-r--r--contrib/extraction/extraction.mli8
-rw-r--r--contrib/extraction/haskell.ml11
-rw-r--r--contrib/extraction/miniml.mli1
-rw-r--r--contrib/extraction/mlutil.ml14
-rw-r--r--contrib/extraction/ocaml.ml15
7 files changed, 160 insertions, 94 deletions
diff --git a/contrib/extraction/extract_env.ml b/contrib/extraction/extract_env.ml
index e322cc0a6..a0ca727e0 100644
--- a/contrib/extraction/extract_env.ml
+++ b/contrib/extraction/extract_env.ml
@@ -84,7 +84,7 @@ and visit_type m eenv t =
| Tglob r -> visit_reference m eenv r
| Tapp l -> List.iter visit l
| Tarr (t1,t2) -> visit t1; visit t2
- | Tvar _ | Tprop | Tarity -> ()
+ | Tvar _ | Texn _ | Tprop | Tarity -> ()
in
visit t
@@ -154,11 +154,18 @@ let local_optimize refs =
let print_user_extract r =
mSGNL [< 'sTR "User defined extraction:"; 'sPC; 'sTR (find_ml_extraction r) ; 'fNL>]
+let decl_in_r r0 = function
+ | Dglob (r,_) -> r = r0
+ | Dabbrev (r,_,_) -> r = r0
+ | Dtype ((_,r,_)::_, _) -> r = r0
+ | Dtype ([],_) -> false
+ | Dcustom (r,_) -> r = r0
+
let extract_reference r =
if is_ml_extraction r then
print_user_extract r
else
- mSGNL (ToplevelPp.pp_decl (list_last (local_optimize [r])))
+ mSGNL (ToplevelPp.pp_decl (List.find (decl_in_r r) (local_optimize [r])))
let _ =
vinterp_add "Extraction"
@@ -173,7 +180,7 @@ let _ =
| Construct cs -> extract_reference (ConstructRef cs)
(* Otherwise, output the ML type or expression *)
| _ ->
- match extract_constr (Global.env()) [] c with
+ match extract_constr (Global.env()) c with
| Emltype (t,_,_) -> mSGNL (ToplevelPp.pp_type t)
| Emlterm a -> mSGNL (ToplevelPp.pp_ast (normalize a)))
| _ -> assert false)
diff --git a/contrib/extraction/extraction.ml b/contrib/extraction/extraction.ml
index 34f7a78dc..368b41e3c 100644
--- a/contrib/extraction/extraction.ml
+++ b/contrib/extraction/extraction.ml
@@ -73,14 +73,13 @@ type extraction_context = bool list
(* The [type_extraction_result] is the result of the [extract_type] function
that extracts a CIC object into an ML type. It is either:
\begin{itemize}
- \item a real ML type, followed by its signature and its list of type
- variables (['a],\ldots)
+ \item a real ML type, followed by its list of type variables (['a],\ldots)
\item a CIC arity, without counterpart in ML
\item a non-informative type, which will receive special treatment
\end{itemize} *)
type type_extraction_result =
- | Tmltype of ml_type * signature * identifier list
+ | Tmltype of ml_type * identifier list
| Tarity
| Tprop
@@ -121,14 +120,6 @@ let id_of_name = function
| Anonymous -> id_of_string "x"
| Name id -> id
-let s_of_tmltype = function
- | Tmltype (_,s,_) -> s
- | _ -> assert false
-
-let mlterm_of_constr = function
- | Emltype _ -> MLarity
- | Emlterm a -> a
-
(* [list_of_ml_arrows] applied to the ML type [a->b->]\dots[z->t]
returns the list [[a;b;...;z]]. It is used when making the ML types
of inductive definitions. We also suppress [Prop] parts. *)
@@ -305,6 +296,7 @@ let _ = declare_summary "Extraction tables"
init_function = (fun () -> ());
survive_section = true }
+
(*s Extraction of a type. *)
(* When calling [extract_type] we suppose that the type of [c] is an
@@ -361,12 +353,12 @@ and extract_type_rec_info env c vl args =
| (_,Some t,_) ->
extract_type_rec_info env (lift n t) vl args
| (id,_,_) ->
- Tmltype (Tvar (id_of_name id), [], vl))
+ Tmltype (Tvar (id_of_name id), vl))
| Const sp when args = [] && is_ml_extraction (ConstRef sp) ->
- Tmltype (Tglob (ConstRef sp), [], vl)
+ Tmltype (Tglob (ConstRef sp), vl)
| Const sp when is_axiom sp ->
let id = next_ident_away (basename sp) vl in
- Tmltype (Tvar id, [], id :: vl)
+ Tmltype (Tvar id, id :: vl)
| Const sp ->
let t = constant_type env sp in
if is_arity env none t then
@@ -378,7 +370,7 @@ and extract_type_rec_info env c vl args =
| Emlterm _ -> assert false)
else
(* We can't keep as ML type abbreviation a CIC constant *)
- (* which type is not an arity: we reduce this constant. *)
+ (* which type is not an arity: we reduce this constant. *)
let cvalue = constant_value env sp in
extract_type_rec_info env (applist (cvalue, args)) vl []
| Ind spi ->
@@ -388,7 +380,7 @@ and extract_type_rec_info env c vl args =
|Iprop -> assert false (* Cf. initial tests *))
| Case _ | Fix _ | CoFix _ ->
let id = next_ident_away flexible_name vl in
- Tmltype (Tvar id, [], id :: vl)
+ Tmltype (Tvar id, id :: vl)
(* Type without counterpart in ML: we generate a
new flexible type variable. *)
| Cast (c, _) ->
@@ -408,29 +400,22 @@ and extract_prod_lam env (n,t,d) vl flag =
(* [lookup_rel] will be correct. *)
let id' = next_ident_away (id_of_name n) vl in
let env' = push_rel_assum (Name id', t) env in
- (match extract_type_rec_info env' d (id'::vl) [] with
- | Tmltype (mld, sign, vl') -> Tmltype (mld, tag::sign, vl')
- | et -> et)
+ extract_type_rec_info env' d (id'::vl) []
| (Logic, Arity), _ | _, Lam ->
- (match extract_type_rec_info env' d vl [] with
- | Tmltype (mld, sign, vl') -> Tmltype (mld, tag::sign, vl')
- | et -> et)
+ extract_type_rec_info env' d vl []
| (Logic, NotArity), Product ->
(match extract_type_rec_info env' d vl [] with
- | Tmltype (mld, sign, vl') ->
- Tmltype (Tarr (Miniml.Tprop, mld), tag::sign, vl')
+ | Tmltype (mld, vl') -> Tmltype (Tarr (Miniml.Tprop, mld), vl')
| et -> et)
| (Info, NotArity), Product ->
(* It is important to treat [d] first and [t] in second. *)
(* This ensures that the end of [vl] correspond to external binders. *)
(match extract_type_rec_info env' d vl [] with
- | Tmltype (mld, sign, vl') ->
+ | Tmltype (mld, vl') ->
(match extract_type_rec_info env t vl' [] with
- | Tprop | Tarity ->
- assert false
+ | Tprop | Tarity -> assert false
(* Cf. relation between [extract_type] and [v_of_t] *)
- | Tmltype (mlt,_,vl'') ->
- Tmltype (Tarr(mlt,mld), tag::sign, vl''))
+ | Tmltype (mlt,vl'') -> Tmltype (Tarr(mlt,mld), vl''))
| et -> et)
(* Auxiliary function dealing with type application.
@@ -441,16 +426,15 @@ and extract_type_app env (r,sc,vlc) vl args =
let args = if diff > 0 then begin
(* This can (normally) only happen when r is a flexible type.
We discard the remaining arguments *)
- (* wARN (hOV 0 [< 'sTR ("Discarding " ^
- (string_of_int diff) ^ " type(s) argument(s).") >]); *)
+ (*i wARN (hOV 0 [< 'sTR ("Discarding " ^
+ (string_of_int diff) ^ " type(s) argument(s).") >]); i*)
list_firstn (List.length sc) args
end else args in
let nargs = List.length args in
(* [r] is of type an arity, so it can't be applied to more than n args,
where n is the number of products in this arity type. *)
(* But there are flexibles ... *)
-
- let (sign_args,sign_rem) = list_chop nargs sc in
+ let sign_args = list_firstn nargs sc in
let (mlargs,vl') =
List.fold_right
(fun (v,a) ((args,vl) as acc) -> match v with
@@ -460,7 +444,7 @@ and extract_type_app env (r,sc,vlc) vl args =
| Tarity -> (Miniml.Tarity :: args, vl)
(* we pass a dummy type [arity] as argument *)
| Tprop -> (Miniml.Tprop :: args, vl)
- | Tmltype (mla,_,vl') -> (mla :: args, vl'))
+ | Tmltype (mla,vl') -> (mla :: args, vl'))
(List.combine sign_args args)
([],vl)
in
@@ -476,31 +460,82 @@ and extract_type_app env (r,sc,vlc) vl args =
(* We complete the list of arguments of [c] by variables *)
let vlargs =
List.rev_map (fun i -> Tvar i) (list_firstn nvlargs vl'') in
- Tmltype (Tapp ((Tglob r) :: mlargs @ vlargs), sign_rem, vl'')
-
+ Tmltype (Tapp ((Tglob r) :: mlargs @ vlargs), vl'')
+
+
+(*s Signature of a type. *)
+
+(* Precondition: [c] is of type an arity.
+ This function is built on the [extract_type] model. *)
+
+and signature env c =
+ signature_rec env (whd_betaiotalet env none c) []
+
+and signature_rec env c args =
+ match kind_of_term c with
+ | Prod (n,t,d)
+ | Lambda (n,t,d) ->
+ let env' = push_rel_assum (n,t) env in
+ (v_of_t env t) :: (signature_rec env' d [])
+ | App (d, args') ->
+ signature_rec env d (Array.to_list args' @ args)
+ | Rel n ->
+ (match lookup_rel n env with
+ | (_,Some t,_) -> signature_rec env (lift n t) args
+ | _ -> [])
+ | Const sp when args = [] && is_ml_extraction (ConstRef sp) -> []
+ | Const sp when is_axiom sp -> []
+ | Const sp ->
+ let t = constant_type env sp in
+ if is_arity env none t then
+ (match extract_constant sp with
+ | Emltype (Miniml.Tarity,_,_) -> []
+ | Emltype (Miniml.Tprop,_,_) -> []
+ | Emltype (_,sc,_) ->
+ let d = List.length sc - List.length args in
+ if d <= 0 then [] else list_lastn d sc
+ | Emlterm _ -> assert false)
+ else
+ let cvalue = constant_value env sp in
+ signature env (applist (cvalue, args))
+ | Ind spi ->
+ (match extract_inductive spi with
+ |Iml (si,_) ->
+ let d = List.length si - List.length args in
+ if d <= 0 then [] else list_lastn d si
+ |Iprop -> [])
+ | Sort _ | Case _ | Fix _ | CoFix _ -> []
+ | Cast (c, _) -> signature_rec env c args
+ | Var _ -> section_message ()
+ | _ -> assert false
+
(*s Extraction of a term.
Precondition: [c] has a type which is not an arity.
This is normaly checked in [extract_constr]. *)
and extract_term env ctx c =
- extract_term_with_type env ctx c (type_of env c)
+ extract_term_wt env ctx c (type_of env c)
-and extract_term_with_type env ctx c t =
+(* Same, but With Type (wt). *)
+
+and extract_term_wt env ctx c t =
let s = sort_of env t in
(* The only non-informative case: [s] is [Prop] *)
if (s = InProp) then
Rprop
else
- Rmlterm (extract_term_info_with_type env ctx c t)
+ Rmlterm (extract_term_info_wt env ctx c t)
(* Variants with a stronger precondition: [c] is informative.
We directly return a [ml_ast], not a [term_extraction_result] *)
and extract_term_info env ctx c =
- extract_term_info_with_type env ctx c (type_of env c)
+ extract_term_info_wt env ctx c (type_of env c)
+
+(* Same, but With Type (wt). *)
-and extract_term_info_with_type env ctx c t =
+and extract_term_info_wt env ctx c t =
match kind_of_term c with
| Lambda (n, t, d) ->
let v = v_of_t env t in
@@ -517,7 +552,7 @@ and extract_term_info_with_type env ctx c t =
let env' = push_rel (n,Some c1,t1) env in
(match v with
| (Info, NotArity) ->
- let c1' = extract_term_info_with_type env ctx c1 t1 in
+ let c1' = extract_term_info_wt env ctx c1 t1 in
let c2' = extract_term_info env' (true :: ctx) c2 in
(* If [c2] was of type an arity, [c] too would be so *)
MLletin (id_of_name n,c1',c2')
@@ -538,7 +573,7 @@ and extract_term_info_with_type env ctx c t =
| CoFix (i,recd) ->
extract_fix env ctx i recd
| Cast (c, _) ->
- extract_term_info_with_type env ctx c t
+ extract_term_info_wt env ctx c t
| Ind _ | Prod _ | Sort _ | Meta _ | Evar _ ->
assert false
| Var _ -> section_message ()
@@ -593,7 +628,7 @@ and extract_case env ctx ip c br =
(* Some pathological cases need an [extract_constr] here rather *)
(* than an [extract_term]. See exemples in [test_extraction.v] *)
let env' = push_rel_context (List.map (fun (x,t) -> (x,None,t)) rb) env in
- let e' = mlterm_of_constr (extract_constr env' ctx' e) in
+ let e' = extract_constr_to_term env' ctx' e in
let ids =
List.fold_right
(fun (v,(n,_)) a -> if v = default then (id_of_name n :: a) else a)
@@ -613,7 +648,7 @@ and extract_case env ctx ip c br =
let env' = push_rels_assum rb env in
(* We know that all arguments are logic. *)
let ctx' = iterate (fun l -> false :: l) ni.(0) ctx in
- mlterm_of_constr (extract_constr env' ctx' e))
+ extract_constr_to_term env' ctx' e)
(* Extraction of a (co)-fixpoint *)
@@ -626,7 +661,7 @@ and extract_fix env ctx i (fi,ti,ci as recd) =
(List.rev_map (fun (_,a) -> a = NotArity) (sign_of_lbinders env lb)) @ ctx
in
let extract_fix_body c t =
- mlterm_of_constr (extract_constr_with_type env' ctx' c (lift n t)) in
+ extract_constr_to_term_wt env' ctx' c (lift n t) in
let ei = array_map2 extract_fix_body ci ti in
MLfix (i, Array.map id_of_name fi, ei)
@@ -647,12 +682,12 @@ and extract_app env ctx f args =
| (Logic,NotArity) -> MLprop :: args
| (Info,NotArity) ->
(* We can't trust tag [default], so we use [extract_constr]. *)
- (mlterm_of_constr (extract_constr env ctx a)) :: args)
+ (extract_constr_to_term env ctx a) :: args)
(List.combine (list_firstn nargs sf) args)
[]
in
(* [f : arity] implies [(f args):arity], that can't be *)
- let f' = extract_term_info_with_type env ctx f tyf in
+ let f' = extract_term_info_wt env ctx f tyf in
MLapp (f', mlargs)
(* [signature_of_application] is used to generate a long enough signature.
@@ -665,8 +700,7 @@ and signature_of_application env f t a =
(* It does not really ensure that [t] start by [n] products,
but it reduces as much as possible *)
let nbp = nb_prod t in
- let s = s_of_tmltype (extract_type env t) in
- (* Cf precondition: [t] gives a [Tmltype] *)
+ let s = signature env t in
if nbp >= nargs then
s
else
@@ -675,25 +709,40 @@ and signature_of_application env f t a =
let a' = Array.sub a nbp (nargs-nbp) in
let t' = type_of env f' in
s @ signature_of_application env f' t' a'
-
-(*s Extraction of a constr. *)
-
-and extract_constr_with_type env ctx c t =
- match v_of_t env t with
- | (Logic, Arity) -> Emltype (Miniml.Tarity, [], [])
- | (Logic, NotArity) -> Emlterm MLprop
- | (Info, Arity) ->
- (match extract_type env c with
- | Tprop -> Emltype (Miniml.Tprop, [], [])
- | Tarity -> Emltype (Miniml.Tarity, [], [])
- | Tmltype (t, sign, vl) -> Emltype (t, sign, vl))
- | (Info, NotArity) ->
- Emlterm (extract_term_info_with_type env ctx c t)
-
-and extract_constr env ctx c =
- extract_constr_with_type env ctx c (type_of env c)
+(*s Extraction of a constr seen as a term. *)
+
+and extract_constr_to_term env ctx c =
+ extract_constr_to_term_wt env ctx c (type_of env c)
+
+(* Same, but With Type (wt). *)
+
+and extract_constr_to_term_wt env ctx c t =
+ match v_of_t env t with
+ | (_, Arity) -> MLarity
+ | (Logic, NotArity) -> MLprop
+ | (Info, NotArity) -> extract_term_info_wt env ctx c t
+
+(* Extraction of a constr. *)
+
+and extract_constr env c =
+ extract_constr_wt env c (type_of env c)
+
+(* Same, but With Type (wt). *)
+
+and extract_constr_wt env c t =
+ match v_of_t env t with
+ | (Logic, Arity) -> Emltype (Miniml.Tarity, [], [])
+ | (Logic, NotArity) -> Emlterm MLprop
+ | (Info, Arity) ->
+ (match extract_type env c with
+ | Tprop -> Emltype (Miniml.Tprop, [], [])
+ | Tarity -> Emltype (Miniml.Tarity, [], [])
+ | Tmltype (t, vl) -> Emltype (t, (signature env c), vl))
+ | (Info, NotArity) ->
+ Emlterm (extract_term_info_wt env [] c t)
+
(*s Extraction of a constant. *)
and extract_constant sp =
@@ -710,7 +759,7 @@ and extract_constant sp =
| (Logic,NotArity) -> Emlterm MLprop (* Axiom? I don't mind! *)
| (Logic,Arity) -> Emltype (Miniml.Tarity,[],[])) (* Idem *)
| Some body ->
- let e = extract_constr_with_type env [] body typ in
+ let e = extract_constr_wt env body typ in
let e = eta_expanse e typ in
constant_table := Gmap.add sp e !constant_table;
e
@@ -723,7 +772,7 @@ and eta_expanse ec typ = match ec with
| Emlterm (MLlam _) -> ec
| Emlterm a ->
(match extract_type (Global.env()) typ with
- | Tmltype (Tarr _, _, _) ->
+ | Tmltype (Tarr _, _) ->
Emlterm (MLlam (anonymous, MLapp (a, [MLrel 1])))
| _ -> ec)
| _ -> ec
@@ -794,8 +843,9 @@ and extract_mib sp =
let t = snd (decompose_prod_n nb t) in
match extract_type_rec_info env t vl [] with
| Tarity | Tprop -> assert false
- | Tmltype (mlt, s, v) ->
- let l = list_of_ml_arrows mlt in
+ | Tmltype (mlt, v) ->
+ let l = list_of_ml_arrows mlt
+ and s = signature env t in
add_constructor_extraction (ip,j) (Cml (l,s,nbtokeep));
v)
vl)
diff --git a/contrib/extraction/extraction.mli b/contrib/extraction/extraction.mli
index afc6efd6f..3f71c1d89 100644
--- a/contrib/extraction/extraction.mli
+++ b/contrib/extraction/extraction.mli
@@ -26,18 +26,16 @@ type type_var = info * arity
type signature = type_var list
-type extraction_context = bool list
-
type extraction_result =
| Emltype of ml_type * signature * identifier list
| Emlterm of ml_ast
-(*s Extraction functions. *)
+(*s Extraction function. *)
-val extract_constr : env -> extraction_context -> constr -> extraction_result
+val extract_constr : env -> constr -> extraction_result
(*s ML declaration corresponding to a Coq reference. *)
val extract_declaration : global_reference -> ml_decl
-
+val signature : env -> constr -> signature
diff --git a/contrib/extraction/haskell.ml b/contrib/extraction/haskell.ml
index f59a282ca..8d5cf6ebe 100644
--- a/contrib/extraction/haskell.ml
+++ b/contrib/extraction/haskell.ml
@@ -74,6 +74,8 @@ let rec pp_type par t =
pp_rec false t2; close_par par >]
| Tglob r ->
pp_type_global r
+ | Texn s ->
+ [< string ("() -- " ^ s) ; 'fNL >]
| Tprop ->
string "Prop"
| Tarity ->
@@ -219,12 +221,9 @@ let pp_one_inductive (pl,name,cl) =
pp_type_global name; 'sTR " ";
prlist_with_sep (fun () -> [< 'sTR " " >]) pr_lower_id pl;
if pl = [] then [< >] else [< 'sTR " " >];
- if cl = [] then
- [< 'sTR "= () -- empty inductive" >]
- else
- [< v 0 [< 'sTR "= ";
- prlist_with_sep (fun () -> [< 'fNL; 'sTR " | " >])
- pp_constructor cl >] >] >]
+ [< v 0 [< 'sTR "= ";
+ prlist_with_sep (fun () -> [< 'fNL; 'sTR " | " >])
+ pp_constructor cl >] >] >]
let pp_inductive il =
[< prlist_with_sep (fun () -> [< 'fNL >]) pp_one_inductive il; 'fNL >]
diff --git a/contrib/extraction/miniml.mli b/contrib/extraction/miniml.mli
index a022d67d8..54a230881 100644
--- a/contrib/extraction/miniml.mli
+++ b/contrib/extraction/miniml.mli
@@ -22,6 +22,7 @@ type ml_type =
| Tapp of ml_type list
| Tarr of ml_type * ml_type
| Tglob of global_reference
+ | Texn of string
| Tprop
| Tarity
diff --git a/contrib/extraction/mlutil.ml b/contrib/extraction/mlutil.ml
index 48d8a6e7b..39dc37f07 100644
--- a/contrib/extraction/mlutil.ml
+++ b/contrib/extraction/mlutil.ml
@@ -586,6 +586,13 @@ let strict_language = function
| "haskell" -> false
| _ -> assert false
+let rec empty_ind = function
+ | [] -> [],[]
+ | t :: q -> let l,l' = empty_ind q in
+ (match t with
+ | ids,r,[] -> Dabbrev (r,ids,Texn "empty inductive") :: l,l'
+ | _ -> l,t::l')
+
let rec optimize prm = function
| [] ->
[]
@@ -614,6 +621,11 @@ let rec optimize prm = function
(* Detection of informative singleton. *)
add_singleton r0;
Dabbrev (r, ids, t0) :: (optimize prm l)
- | (Dtype _ | Dabbrev _ | Dcustom _) as d :: l ->
+ | Dtype(il,b) :: l ->
+ (* Detection of empty inductives. *)
+ let l1,l2 = empty_ind il in
+ if l2 = [] then l1 @ (optimize prm l)
+ else l1 @ (Dtype(l2,b) :: (optimize prm l))
+ | (Dabbrev _ | Dcustom _) as d :: l ->
d :: (optimize prm l)
diff --git a/contrib/extraction/ocaml.ml b/contrib/extraction/ocaml.ml
index 185bbe0a7..391bf7350 100644
--- a/contrib/extraction/ocaml.ml
+++ b/contrib/extraction/ocaml.ml
@@ -142,6 +142,8 @@ let rec pp_type par t =
pp_rec false t2; close_par par >]
| Tglob r ->
pp_type_global r
+ | Texn s ->
+ string ("unit (* " ^ s ^ " *)")
| Tprop ->
string "prop"
| Tarity ->
@@ -305,14 +307,11 @@ let pp_one_inductive (pl,name,cl) =
(fun () -> [< 'sPC ; 'sTR "* " >]) (pp_type true) l >] >]
in
[< pp_parameters pl; pp_type_global name; 'sTR " =";
- if cl = [] then
- [< 'sTR " unit (* empty inductive *)" >]
- else
- [< 'fNL;
- v 0 [< 'sTR " ";
- prlist_with_sep (fun () -> [< 'fNL; 'sTR " | " >])
- (fun c -> hOV 2 (pp_constructor c)) cl >] >] >]
-
+ [< 'fNL;
+ v 0 [< 'sTR " ";
+ prlist_with_sep (fun () -> [< 'fNL; 'sTR " | " >])
+ (fun c -> hOV 2 (pp_constructor c)) cl >] >] >]
+
let pp_inductive il =
[< 'sTR "type ";
prlist_with_sep (fun () -> [< 'fNL; 'sTR "and " >]) pp_one_inductive il;