diff options
author | 2001-02-27 15:28:29 +0000 | |
---|---|---|
committer | 2001-02-27 15:28:29 +0000 | |
commit | 4c525008cb728571266ba418b58b4512763159fa (patch) | |
tree | 91d68a9da06a99288f72f40d4ef87db25bdcd6b0 /contrib/extraction | |
parent | c0679738c971a0d1717751b099c74dc43ec0b21c (diff) |
debut extraction termes; pp lambda
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/coq/trunk@1409 85f007b7-540e-0410-9357-904b9bb8a0f7
Diffstat (limited to 'contrib/extraction')
-rw-r--r-- | contrib/extraction/extraction.ml | 260 | ||||
-rw-r--r-- | contrib/extraction/ocaml.ml | 31 |
2 files changed, 185 insertions, 106 deletions
diff --git a/contrib/extraction/extraction.ml b/contrib/extraction/extraction.ml index ddbe378bb..c1503a467 100644 --- a/contrib/extraction/extraction.ml +++ b/contrib/extraction/extraction.ml @@ -15,15 +15,42 @@ open Mlimport (*s Extraction results. *) +(* The [signature] type is used to know how many arguments a CIC + object expects, and what these arguments will become in the ML + object. *) + +(* the flag [type_var] gives us information about an identifier + coming from a Lambda or a Product: + \begin{itemize} + \item [Varity] denotes identifiers of type an arity of sort $Set$ + or $Type$, that is $(x_1:X_1)\ldots(x_n:X_n)s$ with $s = Set$ or $Type$ + \item [Vprop] denotes identifiers of type an arity of sort $Prop$, + or of type of type $Prop$ + \item [Vdefault] represents the other cases + \end{itemize} *) + type type_var = Varity | Vprop | Vdefault type signature = (type_var * identifier) 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 dummy fresh + type variables (called flexible variables) + \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 | Tarity | Tprop +(* The [extraction_result] is the result of the [extract_constr] + function that extracts an CIC object. It is either a ML type, a ML + object or something non-informative. *) + type extraction_result = | Emltype of ml_type * signature * identifier list | Emlterm of ml_ast @@ -81,6 +108,15 @@ let rec list_of_ml_arrows = function | Tarr (a, b) -> a :: list_of_ml_arrows b | t -> [] +let renum_db sign n = + let rec renum = function + | (1, (Vdefault,_)::_) -> 1 + | (n, (Vdefault,_)::s) -> succ (renum (pred n, s)) + | (n, _::s) -> renum (pred n, s) + | _ -> assert false + in + renum (n, sign) + (*s Tables to keep the extraction of inductive types and constructors. *) type inductive_extraction_result = signature * identifier list @@ -113,7 +149,7 @@ i*) (*s Extraction of a type. *) -let rec extract_type env c = +let rec extract_type env sign c = let genv = Global.env() in let rec extract_rec env sign fl c args = let ty = Typing.type_of env Evd.empty c in @@ -127,7 +163,7 @@ let rec extract_type env c = let env' = push_rel (n,None,t) env in (match extract_rec env sign fl t [] with | Tarity | Tprop as et -> - extract_rec env' ((v_of_t et,id) :: sign) fl d [] + extract_rec env' ((v_of_t et,id) :: sign) fl d [] | Tmltype (t', _, fl') -> (match extract_rec env' ((Vdefault,id)::sign) fl' d [] with | Tmltype (d', sign', fl'') -> @@ -139,7 +175,7 @@ let rec extract_type env c = let env' = push_rel (n,None,t) env in (match extract_rec env sign fl t [] with | Tarity | Tprop as et -> - extract_rec env' ((v_of_t et,id) :: sign) fl d [] + extract_rec env' ((v_of_t et,id) :: sign) fl d [] | Tmltype (t', _, fl') -> extract_rec env' ((Vdefault,id) :: sign) fl' d []) | IsSort (Prop Null) -> @@ -177,39 +213,63 @@ let rec extract_type env c = extract_rec env sign fl c args | _ -> assert false - and extract_type_app env sign fl (r,sc,flc) args = - let nargs = List.length args in - assert (List.length sc >= nargs); - let (mlargs,fl') = - List.fold_right - (fun (v,a) ((args,fl) as acc) -> match v with - | (Vdefault | Vprop), _ -> acc - | Varity,_ -> match extract_rec env sign fl a [] with - | Tarity -> assert false - | Tprop -> (Miniml.Tprop :: args, fl) - | Tmltype (mla,_,fl') -> (mla :: args, fl')) - (List.combine (list_firstn nargs (List.rev sc)) args) - ([],fl) - in - let flc = List.map (fun i -> Tvar i) flc in - Tmltype (Tapp ((Tglob r) :: mlargs @ flc), sign, fl') + and extract_type_app env sign fl (r,sc,flc) args = + let nargs = List.length args in + assert (List.length sc >= nargs); + let (mlargs,fl') = + List.fold_right + (fun (v,a) ((args,fl) as acc) -> match v with + | (Vdefault | Vprop), _ -> acc + | Varity,_ -> match extract_rec env sign fl a [] with + | Tarity -> assert false + | Tprop -> (Miniml.Tprop :: args, fl) + | Tmltype (mla,_,fl') -> (mla :: args, fl')) + (List.combine (list_firstn nargs (List.rev sc)) args) + ([],fl) + in + let flc = List.map (fun i -> Tvar i) flc in + Tmltype (Tapp ((Tglob r) :: mlargs @ flc), sign, fl') in - extract_rec env [] [] c [] + extract_rec env sign [] c [] (*s Extraction of a term. *) and extract_term c = + let rec extract_rec env sign c = (*i - let rec extract_rec env c = match kind_of_term (whd_beta c) with + let apply t = match args with + | [] -> t + | _ -> MLapp (t, args) + in + i*) + match kind_of_term c with + | IsLambda (n, t, d) -> + let env' = push_rel (n,None,t) env in + let id = id_of_name n in + (match extract_type env sign t with + | Tmltype _ -> + (match extract_rec env' ((Vdefault,id) :: sign) d with + | Emlterm a -> Emlterm (MLlam (id, a)) + | Eprop -> Eprop + | Emltype _ -> assert false) + | Tarity | Tprop as et -> + extract_rec env' ((v_of_t et, id) :: sign) d) + | IsRel n -> + (match List.nth sign (pred n) with + | Varity,_ -> assert false + | Vprop,_ -> Eprop + | Vdefault,_ -> Emlterm (MLrel (renum_db sign n))) + | IsMutConstruct (ind,j) -> + failwith "todo" + | IsCast (c, _) -> + extract_rec env sign c + | IsMutInd _ | IsProd _ | IsSort _ | IsXtra _ | IsVar _ | IsMeta _ -> + assert false | _ -> - failwith "todo" - | IsSort _ | IsXtra _ | IsVar _ | IsMeta _ -> - assert false - in - extract_rec (Global.env()) c - i*) - failwith "todo" + failwith "todo" + in + extract_rec (Global.env()) [] c (*s Extraction of a constr. *) @@ -219,82 +279,82 @@ and extract_constr_with_type c t = | Some (Prop Null) -> Eprop | Some _ -> - (match extract_type genv c with + (match extract_type genv [] c with | Tprop -> Eprop | Tarity -> error "not an ML type" | Tmltype (t, sign, fl) -> Emltype (t, sign, fl)) | None -> - let t = extract_term c in Emlterm t - -and extract_constr c = - extract_constr_with_type c (Typing.type_of (Global.env()) Evd.empty c) - -(*s Extraction of a constant. *) - -and extract_constant sp = - let cb = Global.lookup_constant sp in - let typ = cb.const_type in - let body = match cb.const_body with Some c -> c | None -> assert false in - extract_constr_with_type body typ - -(*s Extraction of an inductive. *) - -and extract_inductive ((sp,_) as i) = - extract_mib sp; - lookup_inductive_extraction i - -and extract_constructor (((sp,_),_) as c) = - extract_mib sp; - lookup_constructor_extraction c - -and extract_mib sp = - if not (Gmap.mem (sp,0) !inductive_extraction_table) then begin - let mib = Global.lookup_mind sp in - let genv = Global.env () in - (* first pass: we store inductive signatures together with empty flex. *) - Array.iteri - (fun i ib -> add_inductive_extraction (sp,i) - (signature_of_arity genv ib.mind_nf_arity, [])) - mib.mind_packets; - (* second pass: we extract constructors arities and we accumulate - all flexible variables. *) - let fl = - array_foldi - (fun i ib fl -> - let mis = build_mis ((sp,i),[||]) mib in - array_foldi - (fun j _ fl -> - let t = mis_constructor_type (succ j) mis in - match extract_type genv t with - | Tarity | Tprop -> assert false - | Tmltype (mlt, s, f) -> - let l = list_of_ml_arrows mlt in - add_constructor_extraction ((sp,i),succ j) (l,s); - f @ fl) - ib.mind_nf_lc fl) - mib.mind_packets [] - in - (* third pass: we update the inductive flexible variables. *) - for i = 0 to mib.mind_ntypes - 1 do - let (s,_) = lookup_inductive_extraction (sp,i) in - add_inductive_extraction (sp,i) (s,fl) - done - end - -(*s Extraction of a global reference i.e. a constant or an inductive. *) - -and extract_inductive_declaration sp = - extract_mib sp; - let mib = Global.lookup_mind sp in - let one_constructor ind j id = - let (t,_) = lookup_constructor_extraction (ind,succ j) in (id, t) - in - let one_inductive i ip = - let (s,fl) = lookup_inductive_extraction (sp,i) in - (params_of_sign s @ fl, ip.mind_typename, - Array.to_list (Array.mapi (one_constructor (sp,i)) ip.mind_consnames)) - in - Dtype (Array.to_list (Array.mapi one_inductive mib.mind_packets)) + extract_term c + + and extract_constr c = + extract_constr_with_type c (Typing.type_of (Global.env()) Evd.empty c) + + (*s Extraction of a constant. *) + + and extract_constant sp = + let cb = Global.lookup_constant sp in + let typ = cb.const_type in + let body = match cb.const_body with Some c -> c | None -> assert false in + extract_constr_with_type body typ + + (*s Extraction of an inductive. *) + + and extract_inductive ((sp,_) as i) = + extract_mib sp; + lookup_inductive_extraction i + + and extract_constructor (((sp,_),_) as c) = + extract_mib sp; + lookup_constructor_extraction c + + and extract_mib sp = + if not (Gmap.mem (sp,0) !inductive_extraction_table) then begin + let mib = Global.lookup_mind sp in + let genv = Global.env () in + (* first pass: we store inductive signatures together with empty flex. *) + Array.iteri + (fun i ib -> add_inductive_extraction (sp,i) + (signature_of_arity genv ib.mind_nf_arity, [])) + mib.mind_packets; + (* second pass: we extract constructors arities and we accumulate + all flexible variables. *) + let fl = + array_foldi + (fun i ib fl -> + let mis = build_mis ((sp,i),[||]) mib in + array_foldi + (fun j _ fl -> + let t = mis_constructor_type (succ j) mis in + match extract_type genv [] t with + | Tarity | Tprop -> assert false + | Tmltype (mlt, s, f) -> + let l = list_of_ml_arrows mlt in + add_constructor_extraction ((sp,i),succ j) (l,s); + f @ fl) + ib.mind_nf_lc fl) + mib.mind_packets [] + in + (* third pass: we update the inductive flexible variables. *) + for i = 0 to mib.mind_ntypes - 1 do + let (s,_) = lookup_inductive_extraction (sp,i) in + add_inductive_extraction (sp,i) (s,fl) + done + end + + (*s Extraction of a global reference i.e. a constant or an inductive. *) + + and extract_inductive_declaration sp = + extract_mib sp; + let mib = Global.lookup_mind sp in + let one_constructor ind j id = + let (t,_) = lookup_constructor_extraction (ind,succ j) in (id, t) + in + let one_inductive i ip = + let (s,fl) = lookup_inductive_extraction (sp,i) in + (params_of_sign s @ fl, ip.mind_typename, + Array.to_list (Array.mapi (one_constructor (sp,i)) ip.mind_consnames)) + in + Dtype (Array.to_list (Array.mapi one_inductive mib.mind_packets)) (*s ML declaration from a reference. *) diff --git a/contrib/extraction/ocaml.ml b/contrib/extraction/ocaml.ml index 772d5e649..2f0f751ff 100644 --- a/contrib/extraction/ocaml.ml +++ b/contrib/extraction/ocaml.ml @@ -30,6 +30,28 @@ let pp_tuple f = function let space_if = function true -> [< 'sPC >] | false -> [<>] +(* collect_lambda MLlam(id1,...MLlam(idn,t)...) = [id1;...;idn],t *) + +let collect_lambda = + let rec collect acc = function + | MLlam(id,t) -> collect (id::acc) t + | x -> acc,x + in + collect [] + +let rec rename_bvars avoid = function + | [] -> [] + | id :: idl -> + let v = next_ident_away id avoid in + v :: (rename_bvars (v::avoid) idl) + +let abst = function + | [] -> [< >] + | l -> [< 'sTR"fun " ; + prlist_with_sep (fun ()-> [< 'sTR" " >]) + (fun id -> [< 'sTR(string_of_id id) >]) l ; + 'sTR" ->" ; 'sPC >] + (*s The pretty-printing functor. *) module Make = functor(P : Mlpp_param) -> struct @@ -75,17 +97,14 @@ let rec pp_expr par env args = | MLapp (f,args') -> let stl = List.map (pp_expr true env []) args' in pp_expr par env (stl @ args) f - | MLlam (id,a) -> - failwith "todo" - (*i + | MLlam _ as a -> let fl,a' = collect_lambda a in let fl = rename_bvars env fl in - let st = [< abst (List.rev fl) ; pp_rec false (fl@env) [] a' >] in + let st = [< abst (List.rev fl); pp_expr false (fl@env) [] a' >] in if args = [] then [< open_par par; st; close_par par >] else apply [< 'sTR "("; st; 'sTR ")" >] - i*) | MLglob r -> apply (P.pp_global r) | MLcons (_,id,[]) -> @@ -120,7 +139,7 @@ and pp_pat env pv = failwith "todo" and pp_fix par env f args = failwith "todo" -let pp_ast = pp_expr false [] [] +let pp_ast a = hOV 0 (pp_expr false [] [] a) (*s Pretty-printing of inductive types declaration. *) |