summaryrefslogtreecommitdiff
path: root/interp/constrextern.ml
diff options
context:
space:
mode:
Diffstat (limited to 'interp/constrextern.ml')
-rw-r--r--interp/constrextern.ml858
1 files changed, 452 insertions, 406 deletions
diff --git a/interp/constrextern.ml b/interp/constrextern.ml
index 911d3741..58e1eb1d 100644
--- a/interp/constrextern.ml
+++ b/interp/constrextern.ml
@@ -1,6 +1,6 @@
(************************************************************************)
(* 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 *)
@@ -8,25 +8,27 @@
(*i*)
open Pp
+open Errors
open Util
-open Univ
open Names
open Nameops
open Term
open Termops
-open Namegen
-open Inductive
-open Sign
-open Environ
open Libnames
+open Globnames
open Impargs
+open Constrexpr
+open Constrexpr_ops
+open Notation_ops
open Topconstr
open Glob_term
+open Glob_ops
open Pattern
open Nametab
open Notation
-open Reserve
open Detyping
+open Misctypes
+open Decl_kinds
(*i*)
(* Translation from glob_constr to front constr *)
@@ -37,8 +39,8 @@ open Detyping
(* This governs printing of local context of references *)
let print_arguments = ref false
-(* If true, prints local context of evars, whatever print_arguments *)
-let print_evar_arguments = ref false
+(* If true, prints local context of evars *)
+let print_evar_arguments = Detyping.print_evar_arguments
(* This governs printing of implicit arguments. When
[print_implicits] is on then [print_implicits_explicit_args] tells
@@ -56,11 +58,14 @@ let print_implicits_defensive = ref true
let print_coercions = ref false
(* This forces printing universe names of Type{.} *)
-let print_universes = ref false
+let print_universes = Detyping.print_universes
-(* This suppresses printing of primitive tokens (e.g. numeral) and symbols *)
+(* This suppresses printing of primitive tokens (e.g. numeral) and notations *)
let print_no_symbol = ref false
+(* This tells which notations still not to used if print_no_symbol is true *)
+let print_non_active_notations = ref ([] : interp_rule list)
+
(* This governs printing of projections using the dot notation symbols *)
let print_projections = ref false
@@ -70,8 +75,10 @@ let with_arguments f = Flags.with_option print_arguments f
let with_implicits f = Flags.with_option print_implicits f
let with_coercions f = Flags.with_option print_coercions f
let with_universes f = Flags.with_option print_universes f
-let without_symbols f = Flags.with_option print_no_symbol f
let with_meta_as_hole f = Flags.with_option print_meta_as_hole f
+let without_symbols f = Flags.with_option print_no_symbol f
+let without_specific_symbols l f =
+ Flags.with_extra_values print_non_active_notations l f
(**********************************************************************)
(* Control printing of records *)
@@ -121,7 +128,7 @@ module PrintingConstructor = Goptions.MakeRefTable(PrintingRecordConstructor)
let insert_delimiters e = function
| None -> e
- | Some sc -> CDelimiters (dummy_loc,sc,e)
+ | Some sc -> CDelimiters (Loc.ghost,sc,e)
let insert_pat_delimiters loc p = function
| None -> p
@@ -134,8 +141,7 @@ let insert_pat_alias loc p = function
(**********************************************************************)
(* conversion of references *)
-let extern_evar loc n l =
- if !print_evar_arguments then CEvar (loc,n,l) else CEvar (loc,n,None)
+let extern_evar loc n l = CEvar (loc,n,l)
(** We allow customization of the global_reference printer.
For instance, in the debugger the tables of global references
@@ -151,124 +157,44 @@ let get_extern_reference () = !my_extern_reference
let extern_reference loc vars l = !my_extern_reference loc vars l
-let in_debugger = ref false
-
-
-(************************************************************************)
-(* Equality up to location (useful for translator v8) *)
-
-let rec check_same_pattern p1 p2 =
- match p1, p2 with
- | CPatAlias(_,a1,i1), CPatAlias(_,a2,i2) when i1=i2 ->
- check_same_pattern a1 a2
- | CPatCstr(_,c1,a1), CPatCstr(_,c2,a2) when c1=c2 ->
- List.iter2 check_same_pattern a1 a2
- | CPatCstrExpl(_,c1,a1), CPatCstrExpl(_,c2,a2) when c1=c2 ->
- List.iter2 check_same_pattern a1 a2
- | CPatAtom(_,r1), CPatAtom(_,r2) when r1=r2 -> ()
- | CPatPrim(_,i1), CPatPrim(_,i2) when i1=i2 -> ()
- | CPatDelimiters(_,s1,e1), CPatDelimiters(_,s2,e2) when s1=s2 ->
- check_same_pattern e1 e2
- | _ -> failwith "not same pattern"
-
-let check_same_ref r1 r2 =
- match r1,r2 with
- | Qualid(_,q1), Qualid(_,q2) when q1=q2 -> ()
- | Ident(_,i1), Ident(_,i2) when i1=i2 -> ()
- | _ -> failwith "not same ref"
-
-let rec check_same_type ty1 ty2 =
- match ty1, ty2 with
- | CRef r1, CRef r2 -> check_same_ref r1 r2
- | CFix(_,(_,id1),fl1), CFix(_,(_,id2),fl2) when id1=id2 ->
- List.iter2 (fun (id1,i1,bl1,a1,b1) (id2,i2,bl2,a2,b2) ->
- if id1<>id2 || i1<>i2 then failwith "not same fix";
- check_same_fix_binder bl1 bl2;
- check_same_type a1 a2;
- check_same_type b1 b2)
- fl1 fl2
- | CCoFix(_,(_,id1),fl1), CCoFix(_,(_,id2),fl2) when id1=id2 ->
- List.iter2 (fun (id1,bl1,a1,b1) (id2,bl2,a2,b2) ->
- if id1<>id2 then failwith "not same fix";
- check_same_fix_binder bl1 bl2;
- check_same_type a1 a2;
- check_same_type b1 b2)
- fl1 fl2
- | CArrow(_,a1,b1), CArrow(_,a2,b2) ->
- check_same_type a1 a2;
- check_same_type b1 b2
- | CProdN(_,bl1,a1), CProdN(_,bl2,a2) ->
- List.iter2 check_same_binder bl1 bl2;
- check_same_type a1 a2
- | CLambdaN(_,bl1,a1), CLambdaN(_,bl2,a2) ->
- List.iter2 check_same_binder bl1 bl2;
- check_same_type a1 a2
- | CLetIn(_,(_,na1),a1,b1), CLetIn(_,(_,na2),a2,b2) when na1=na2 ->
- check_same_type a1 a2;
- check_same_type b1 b2
- | CAppExpl(_,(proj1,r1),al1), CAppExpl(_,(proj2,r2),al2) when proj1=proj2 ->
- check_same_ref r1 r2;
- List.iter2 check_same_type al1 al2
- | CApp(_,(_,e1),al1), CApp(_,(_,e2),al2) ->
- check_same_type e1 e2;
- List.iter2 (fun (a1,e1) (a2,e2) ->
- if e1<>e2 then failwith "not same expl";
- check_same_type a1 a2) al1 al2
- | CCases(_,_,_,a1,brl1), CCases(_,_,_,a2,brl2) ->
- List.iter2 (fun (tm1,_) (tm2,_) -> check_same_type tm1 tm2) a1 a2;
- List.iter2 (fun (_,pl1,r1) (_,pl2,r2) ->
- List.iter2 (located_iter2 (List.iter2 check_same_pattern)) pl1 pl2;
- check_same_type r1 r2) brl1 brl2
- | CHole _, CHole _ -> ()
- | CPatVar(_,i1), CPatVar(_,i2) when i1=i2 -> ()
- | CSort(_,s1), CSort(_,s2) when s1=s2 -> ()
- | CCast(_,a1,CastConv (_,b1)), CCast(_,a2, CastConv(_,b2)) ->
- check_same_type a1 a2;
- check_same_type b1 b2
- | CCast(_,a1,CastCoerce), CCast(_,a2, CastCoerce) ->
- check_same_type a1 a2
- | CNotation(_,n1,(e1,el1,bl1)), CNotation(_,n2,(e2,el2,bl2)) when n1=n2 ->
- List.iter2 check_same_type e1 e2;
- List.iter2 (List.iter2 check_same_type) el1 el2;
- List.iter2 check_same_fix_binder bl1 bl2
- | CPrim(_,i1), CPrim(_,i2) when i1=i2 -> ()
- | CDelimiters(_,s1,e1), CDelimiters(_,s2,e2) when s1=s2 ->
- check_same_type e1 e2
- | _ when ty1=ty2 -> ()
- | _ -> failwith "not same type"
-
-and check_same_binder (nal1,_,e1) (nal2,_,e2) =
- List.iter2 (fun (_,na1) (_,na2) ->
- if na1<>na2 then failwith "not same name") nal1 nal2;
- check_same_type e1 e2
-
-and check_same_fix_binder bl1 bl2 =
- List.iter2 (fun b1 b2 ->
- match b1,b2 with
- LocalRawAssum(nal1,k,ty1), LocalRawAssum(nal2,k',ty2) ->
- check_same_binder (nal1,k,ty1) (nal2,k',ty2)
- | LocalRawDef(na1,def1), LocalRawDef(na2,def2) ->
- check_same_binder ([na1],default_binder_kind,def1) ([na2],default_binder_kind,def2)
- | _ -> failwith "not same binder") bl1 bl2
-
-let is_same_type c d =
- try let () = check_same_type c d in true
- with Failure _ | Invalid_argument _ -> false
-
(**********************************************************************)
(* mapping patterns to cases_pattern_expr *)
+let add_patt_for_params ind l =
+ if !Flags.in_debugger then l else
+ Util.List.addn (Inductiveops.inductive_nparamdecls ind) (CPatAtom (Loc.ghost,None)) l
+
+let drop_implicits_in_patt cst nb_expl args =
+ let impl_st = (implicits_of_global cst) in
+ let impl_data = extract_impargs_data impl_st in
+ let rec impls_fit l = function
+ |[],t -> Some (List.rev_append l t)
+ |_,[] -> None
+ |h::t,CPatAtom(_,None)::tt when is_status_implicit h -> impls_fit l (t,tt)
+ |h::_,_ when is_status_implicit h -> None
+ |_::t,hh::tt -> impls_fit (hh::l) (t,tt)
+ in let rec aux = function
+ |[] -> None
+ |(_,imps)::t -> match impls_fit [] (imps,args) with
+ |None -> aux t
+ |x -> x
+ in
+ if Int.equal nb_expl 0 then aux impl_data
+ else
+ let imps = List.skipn_at_least nb_expl (select_stronger_impargs impl_st) in
+ impls_fit [] (imps,args)
+
let has_curly_brackets ntn =
- String.length ntn >= 6 & (String.sub ntn 0 6 = "{ _ } " or
- String.sub ntn (String.length ntn - 6) 6 = " { _ }" or
- string_string_contains ~where:ntn ~what:" { _ } ")
+ String.length ntn >= 6 && (String.is_sub "{ _ } " ntn 0 ||
+ String.is_sub " { _ }" ntn (String.length ntn - 6) ||
+ String.string_contains ~where:ntn ~what:" { _ } ")
let rec wildcards ntn n =
- if n = String.length ntn then []
- else let l = spaces ntn (n+1) in if ntn.[n] = '_' then n::l else l
+ if Int.equal n (String.length ntn) then []
+ else let l = spaces ntn (n+1) in if ntn.[n] == '_' then n::l else l
and spaces ntn n =
- if n = String.length ntn then []
- else if ntn.[n] = ' ' then wildcards ntn (n+1) else spaces ntn (n+1)
+ if Int.equal n (String.length ntn) then []
+ else if ntn.[n] == ' ' then wildcards ntn (n+1) else spaces ntn (n+1)
let expand_curly_brackets loc mknot ntn l =
let ntn' = ref ntn in
@@ -278,7 +204,7 @@ let expand_curly_brackets loc mknot ntn l =
| a::l ->
let a' =
let p = List.nth (wildcards !ntn' 0) i - 2 in
- if p>=0 & p+5 <= String.length !ntn' & String.sub !ntn' p 5 = "{ _ }"
+ if p>=0 && p+5 <= String.length !ntn' && String.is_sub "{ _ }" !ntn' p
then begin
ntn' :=
String.sub !ntn' 0 p ^ "_" ^
@@ -304,128 +230,199 @@ let make_notation_gen loc ntn mknot mkprim destprim l =
match decompose_notation_key ntn, l with
| [Terminal "-"; Terminal x], [] ->
(try mkprim (loc, Numeral (Bigint.neg (Bigint.of_string x)))
- with e when Errors.noncritical e -> mknot (loc,ntn,[]))
+ with Failure _ -> mknot (loc,ntn,[]))
| [Terminal x], [] ->
(try mkprim (loc, Numeral (Bigint.of_string x))
- with e when Errors.noncritical e -> mknot (loc,ntn,[]))
+ with Failure _ -> mknot (loc,ntn,[]))
| _ ->
mknot (loc,ntn,l)
let make_notation loc ntn (terms,termlists,binders as subst) =
- if termlists <> [] or binders <> [] then CNotation (loc,ntn,subst) else
- make_notation_gen loc ntn
- (fun (loc,ntn,l) -> CNotation (loc,ntn,(l,[],[])))
- (fun (loc,p) -> CPrim (loc,p))
- destPrim terms
+ if not (List.is_empty termlists) || not (List.is_empty binders) then
+ CNotation (loc,ntn,subst)
+ else
+ make_notation_gen loc ntn
+ (fun (loc,ntn,l) -> CNotation (loc,ntn,(l,[],[])))
+ (fun (loc,p) -> CPrim (loc,p))
+ destPrim terms
-let make_pat_notation loc ntn (terms,termlists as subst) =
- if termlists <> [] then CPatNotation (loc,ntn,subst) else
+let make_pat_notation loc ntn (terms,termlists as subst) args =
+ if not (List.is_empty termlists) then CPatNotation (loc,ntn,subst,args) else
make_notation_gen loc ntn
- (fun (loc,ntn,l) -> CPatNotation (loc,ntn,(l,[])))
+ (fun (loc,ntn,l) -> CPatNotation (loc,ntn,(l,[]),args))
(fun (loc,p) -> CPatPrim (loc,p))
destPatPrim terms
let mkPat loc qid l =
(* Normally irrelevant test with v8 syntax, but let's do it anyway *)
- if l = [] then CPatAtom (loc,Some qid) else CPatCstr (loc,qid,l)
+ if List.is_empty l then CPatAtom (loc,Some qid) else CPatCstr (loc,qid,[],l)
+
+let pattern_printable_in_both_syntax (ind,_ as c) =
+ let impl_st = extract_impargs_data (implicits_of_global (ConstructRef c)) in
+ let nb_params = Inductiveops.inductive_nparams ind in
+ List.exists (fun (_,impls) ->
+ (List.length impls >= nb_params) &&
+ let params,args = Util.List.chop nb_params impls in
+ (List.for_all is_status_implicit params)&&(List.for_all (fun x -> not (is_status_implicit x)) args)
+ ) impl_st
(* Better to use extern_glob_constr composed with injection/retraction ?? *)
let rec extern_cases_pattern_in_scope (scopes:local_scopes) vars pat =
+ (* pboutill: There are letins in pat which is incompatible with notations and
+ not explicit application. *)
+ match pat with
+ | PatCstr(loc,cstrsp,args,na)
+ when !Flags.in_debugger||Inductiveops.constructor_has_local_defs cstrsp ->
+ let c = extern_reference loc Id.Set.empty (ConstructRef cstrsp) in
+ let args = List.map (extern_cases_pattern_in_scope scopes vars) args in
+ CPatCstr (loc, c, add_patt_for_params (fst cstrsp) args, [])
+ | _ ->
try
- if !Flags.raw_print or !print_no_symbol then raise No_match;
+ if !Flags.raw_print || !print_no_symbol then raise No_match;
let (na,sc,p) = uninterp_prim_token_cases_pattern pat in
match availability_of_prim_token p sc scopes with
- | None -> raise No_match
- | Some key ->
- let loc = cases_pattern_loc pat in
- insert_pat_alias loc (insert_pat_delimiters loc (CPatPrim(loc,p)) key) na
- with No_match ->
- try
- if !Flags.raw_print or !print_no_symbol then raise No_match;
- extern_symbol_pattern scopes vars pat
- (uninterp_cases_pattern_notations pat)
+ | None -> raise No_match
+ | Some key ->
+ let loc = cases_pattern_loc pat in
+ insert_pat_alias loc (insert_pat_delimiters loc (CPatPrim(loc,p)) key) na
with No_match ->
- match pat with
- | PatVar (loc,Name id) -> CPatAtom (loc,Some (Ident (loc,id)))
- | PatVar (loc,Anonymous) -> CPatAtom (loc, None)
- | PatCstr(loc,cstrsp,args,na) ->
- let args = List.map (extern_cases_pattern_in_scope scopes vars) args in
- let p =
- try
- if !in_debugger || !Flags.raw_print then raise Exit;
- let projs = Recordops.lookup_projections (fst cstrsp) in
- let rec ip projs args acc =
- match projs with
- | [] -> acc
- | None :: q -> ip q args acc
- | Some c :: q ->
- match args with
- | [] -> raise No_match
- | CPatAtom(_, None) :: tail -> ip q tail acc
- (* we don't want to have 'x = _' in our patterns *)
- | head :: tail -> ip q tail
- ((extern_reference loc Idset.empty (ConstRef c), head) :: acc)
+ try
+ if !Flags.raw_print || !print_no_symbol then raise No_match;
+ extern_symbol_pattern scopes vars pat
+ (uninterp_cases_pattern_notations pat)
+ with No_match ->
+ match pat with
+ | PatVar (loc,Name id) -> CPatAtom (loc,Some (Ident (loc,id)))
+ | PatVar (loc,Anonymous) -> CPatAtom (loc, None)
+ | PatCstr(loc,cstrsp,args,na) ->
+ let args = List.map (extern_cases_pattern_in_scope scopes vars) args in
+ let p =
+ try
+ if !Flags.raw_print then raise Exit;
+ let projs = Recordops.lookup_projections (fst cstrsp) in
+ let rec ip projs args acc =
+ match projs with
+ | [] -> acc
+ | None :: q -> ip q args acc
+ | Some c :: q ->
+ match args with
+ | [] -> raise No_match
+ | CPatAtom(_, None) :: tail -> ip q tail acc
+ (* we don't want to have 'x = _' in our patterns *)
+ | head :: tail -> ip q tail
+ ((extern_reference loc Id.Set.empty (ConstRef c), head) :: acc)
+ in
+ CPatRecord(loc, List.rev (ip projs args []))
+ with
+ Not_found | No_match | Exit ->
+ let c = extern_reference loc Id.Set.empty (ConstructRef cstrsp) in
+ if !Topconstr.oldfashion_patterns then
+ if pattern_printable_in_both_syntax cstrsp
+ then CPatCstr (loc, c, [], args)
+ else CPatCstr (loc, c, add_patt_for_params (fst cstrsp) args, [])
+ else
+ let full_args = add_patt_for_params (fst cstrsp) args in
+ match drop_implicits_in_patt (ConstructRef cstrsp) 0 full_args with
+ |Some true_args -> CPatCstr (loc, c, [], true_args)
+ |None -> CPatCstr (loc, c, full_args, [])
+ in insert_pat_alias loc p na
+and apply_notation_to_pattern loc gr ((subst,substlist),(nb_to_drop,more_args))
+ (tmp_scope, scopes as allscopes) vars =
+ function
+ | NotationRule (sc,ntn) ->
+ begin
+ match availability_of_notation (sc,ntn) allscopes with
+ (* Uninterpretation is not allowed in current context *)
+ | None -> raise No_match
+ (* Uninterpretation is allowed in current context *)
+ | Some (scopt,key) ->
+ let scopes' = Option.List.cons scopt scopes in
+ let l =
+ List.map (fun (c,(scopt,scl)) ->
+ extern_cases_pattern_in_scope (scopt,scl@scopes') vars c)
+ subst in
+ let ll =
+ List.map (fun (c,(scopt,scl)) ->
+ let subscope = (scopt,scl@scopes') in
+ List.map (extern_cases_pattern_in_scope subscope vars) c)
+ substlist in
+ let l2 = List.map (extern_cases_pattern_in_scope allscopes vars) more_args in
+ let l2' = if !Topconstr.oldfashion_patterns || not (List.is_empty ll) then l2
+ else
+ match drop_implicits_in_patt gr nb_to_drop l2 with
+ |Some true_args -> true_args
+ |None -> raise No_match
in
- CPatRecord(loc, List.rev (ip projs args []))
- with
- Not_found | No_match | Exit ->
- CPatCstr (loc, extern_reference loc vars (ConstructRef cstrsp), args) in
- insert_pat_alias loc p na
-
+ insert_pat_delimiters loc
+ (make_pat_notation loc ntn (l,ll) l2') key
+ end
+ | SynDefRule kn ->
+ let qid = Qualid (loc, shortest_qualid_of_syndef vars kn) in
+ let l1 =
+ List.rev_map (fun (c,(scopt,scl)) ->
+ extern_cases_pattern_in_scope (scopt,scl@scopes) vars c)
+ subst in
+ let l2 = List.map (extern_cases_pattern_in_scope allscopes vars) more_args in
+ let l2' = if !Topconstr.oldfashion_patterns then l2
+ else
+ match drop_implicits_in_patt gr (nb_to_drop + List.length l1) l2 with
+ |Some true_args -> true_args
+ |None -> raise No_match
+ in
+ assert (List.is_empty substlist);
+ mkPat loc qid (List.rev_append l1 l2')
and extern_symbol_pattern (tmp_scope,scopes as allscopes) vars t = function
| [] -> raise No_match
| (keyrule,pat,n as _rule)::rules ->
try
- match t,n with
- | PatCstr (loc,(ind,_),l,na), n when (n = Some 0 or n = None or
- n = Some(fst(Global.lookup_inductive ind)).Declarations.mind_nparams)
- && (match keyrule with SynDefRule _ -> true | _ -> false) ->
- (* Abbreviation for the constructor name only *)
- (match keyrule with
- | NotationRule _ -> assert false
- | SynDefRule kn ->
- let qid = Qualid (loc, shortest_qualid_of_syndef vars kn) in
- let l = List.map (extern_cases_pattern_in_scope allscopes vars) l in
- insert_pat_alias loc (mkPat loc qid l) na)
- | PatCstr (_,f,l,_), Some n when List.length l > n ->
- raise No_match
- | PatCstr (loc,_,_,na),_ ->
- (* Try matching ... *)
- let subst,substlist = match_aconstr_cases_pattern t pat in
- (* Try availability of interpretation ... *)
- let p = match keyrule with
- | NotationRule (sc,ntn) ->
- (match availability_of_notation (sc,ntn) allscopes with
- (* Uninterpretation is not allowed in current context *)
- | None -> raise No_match
- (* Uninterpretation is allowed in current context *)
- | Some (scopt,key) ->
- let scopes' = Option.List.cons scopt scopes in
- let l =
- List.map (fun (c,(scopt,scl)) ->
- extern_cases_pattern_in_scope (scopt,scl@scopes') vars c)
- subst in
- let ll =
- List.map (fun (c,(scopt,scl)) ->
- let subscope = (scopt,scl@scopes') in
- List.map (extern_cases_pattern_in_scope subscope vars) c)
- substlist in
- insert_pat_delimiters loc
- (make_pat_notation loc ntn (l,ll)) key)
- | SynDefRule kn ->
- let qid = Qualid (loc, shortest_qualid_of_syndef vars kn) in
- let l =
- List.map (fun (c,(scopt,scl)) ->
- extern_cases_pattern_in_scope (scopt,scl@scopes) vars c)
- subst in
- assert (substlist = []);
- mkPat loc qid l in
- insert_pat_alias loc p na
- | PatVar (loc,Anonymous),_ -> CPatAtom (loc, None)
- | PatVar (loc,Name id),_ -> CPatAtom (loc, Some (Ident (loc,id)))
+ if List.mem keyrule !print_non_active_notations then raise No_match;
+ match t with
+ | PatCstr (loc,cstr,_,na) ->
+ let p = apply_notation_to_pattern loc (ConstructRef cstr)
+ (match_notation_constr_cases_pattern t pat) allscopes vars keyrule in
+ insert_pat_alias loc p na
+ | PatVar (loc,Anonymous) -> CPatAtom (loc, None)
+ | PatVar (loc,Name id) -> CPatAtom (loc, Some (Ident (loc,id)))
with
No_match -> extern_symbol_pattern allscopes vars t rules
+let rec extern_symbol_ind_pattern allscopes vars ind args = function
+ | [] -> raise No_match
+ | (keyrule,pat,n as _rule)::rules ->
+ try
+ if List.mem keyrule !print_non_active_notations then raise No_match;
+ apply_notation_to_pattern Loc.ghost (IndRef ind)
+ (match_notation_constr_ind_pattern ind args pat) allscopes vars keyrule
+ with
+ No_match -> extern_symbol_ind_pattern allscopes vars ind args rules
+
+let extern_ind_pattern_in_scope (scopes:local_scopes) vars ind args =
+ (* pboutill: There are letins in pat which is incompatible with notations and
+ not explicit application. *)
+ if !Flags.in_debugger||Inductiveops.inductive_has_local_defs ind then
+ let c = extern_reference Loc.ghost vars (IndRef ind) in
+ let args = List.map (extern_cases_pattern_in_scope scopes vars) args in
+ CPatCstr (Loc.ghost, c, add_patt_for_params ind args, [])
+ else
+ try
+ if !Flags.raw_print || !print_no_symbol then raise No_match;
+ let (sc,p) = uninterp_prim_token_ind_pattern ind args in
+ match availability_of_prim_token p sc scopes with
+ | None -> raise No_match
+ | Some key ->
+ insert_pat_delimiters Loc.ghost (CPatPrim(Loc.ghost,p)) key
+ with No_match ->
+ try
+ if !Flags.raw_print || !print_no_symbol then raise No_match;
+ extern_symbol_ind_pattern scopes vars ind args
+ (uninterp_ind_pattern_notations ind)
+ with No_match ->
+ let c = extern_reference Loc.ghost vars (IndRef ind) in
+ let args = List.map (extern_cases_pattern_in_scope scopes vars) args in
+ match drop_implicits_in_patt (IndRef ind) 0 args with
+ |Some true_args -> CPatCstr (Loc.ghost, c, [], true_args)
+ |None -> CPatCstr (Loc.ghost, c, args, [])
+
let extern_cases_pattern vars p =
extern_cases_pattern_in_scope (None,[]) vars p
@@ -438,20 +435,32 @@ let occur_name na aty =
| Anonymous -> false
let is_projection nargs = function
- | Some r when not !Flags.raw_print & !print_projections ->
- (try
- let n = Recordops.find_projection_nparams r + 1 in
- if n <= nargs then Some n else None
- with Not_found -> None)
+ | Some r when not !Flags.in_debugger && not !Flags.raw_print && !print_projections ->
+ (try
+ let n = Recordops.find_projection_nparams r + 1 in
+ if n <= nargs then None
+ else Some n
+ with Not_found -> None)
| _ -> None
-
-let is_hole = function CHole _ -> true | _ -> false
+
+let is_hole = function CHole _ | CEvar _ -> true | _ -> false
let is_significant_implicit a =
not (is_hole a)
let is_needed_for_correct_partial_application tail imp =
- tail = [] & not (maximal_insertion_of imp)
+ List.is_empty tail && not (maximal_insertion_of imp)
+
+exception Expl
+
+let params_implicit n impl =
+ let rec aux n impl =
+ if n == 0 then true
+ else match impl with
+ | [] -> false
+ | imp :: impl when is_status_implicit imp -> aux (pred n) impl
+ | _ -> false
+ in aux n impl
(* Implicit args indexes are in ascending order *)
(* inctx is useful only if there is a last argument to be deduced from ctxt *)
@@ -462,55 +471,70 @@ let explicitize loc inctx impl (cf,f) args =
| a::args, imp::impl when is_status_implicit imp ->
let tail = exprec (q+1) (args,impl) in
let visible =
- !Flags.raw_print or
- (!print_implicits & !print_implicits_explicit_args) or
- (is_needed_for_correct_partial_application tail imp) or
- (!print_implicits_defensive &
- is_significant_implicit a &
+ !Flags.raw_print ||
+ (!print_implicits && !print_implicits_explicit_args) ||
+ (is_needed_for_correct_partial_application tail imp) ||
+ (!print_implicits_defensive &&
+ is_significant_implicit a &&
not (is_inferable_implicit inctx n imp))
in
if visible then
- (a,Some (dummy_loc, ExplByName (name_of_implicit imp))) :: tail
+ (a,Some (Loc.ghost, ExplByName (name_of_implicit imp))) :: tail
else
tail
| a::args, _::impl -> (a,None) :: exprec (q+1) (args,impl)
| args, [] -> List.map (fun a -> (a,None)) args (*In case of polymorphism*)
- | [], _ -> [] in
- match is_projection (List.length args) cf with
- | Some i as ip ->
- if impl <> [] & is_status_implicit (List.nth impl (i-1)) then
- let f' = match f with CRef f -> f | _ -> assert false in
- CAppExpl (loc,(ip,f'),args)
- else
- let (args1,args2) = list_chop i args in
- let (impl1,impl2) = if impl=[] then [],[] else list_chop i impl in
- let args1 = exprec 1 (args1,impl1) in
- let args2 = exprec (i+1) (args2,impl2) in
- CApp (loc,(Some (List.length args1),f),args1@args2)
+ | [], (imp :: _) when is_status_implicit imp && maximal_insertion_of imp ->
+ (* The non-explicit application cannot be parsed back with the same type *)
+ raise Expl
+ | [], _ -> []
+ in
+ let ip = is_projection (List.length args) cf in
+ let expl () =
+ match ip with
+ | Some i ->
+ if not (List.is_empty impl) && is_status_implicit (List.nth impl (i-1)) then
+ raise Expl
+ else
+ let (args1,args2) = List.chop i args in
+ let (impl1,impl2) = if List.is_empty impl then [],[] else List.chop i impl in
+ let args1 = exprec 1 (args1,impl1) in
+ let args2 = exprec (i+1) (args2,impl2) in
+ let ip = Some (List.length args1) in
+ CApp (loc,(ip,f),args1@args2)
| None ->
- let args = exprec 1 (args,impl) in
- if args = [] then f else CApp (loc, (None, f), args)
-
-let extern_global loc impl f =
- if not !Constrintern.parsing_explicit &&
- impl <> [] && List.for_all is_status_implicit impl
+ let args = exprec 1 (args,impl) in
+ if List.is_empty args then f else CApp (loc, (None, f), args)
+ in
+ try expl ()
+ with Expl ->
+ let f',us = match f with CRef (f,us) -> f,us | _ -> assert false in
+ let ip = if !print_projections then ip else None in
+ CAppExpl (loc, (ip, f', us), args)
+
+let is_start_implicit = function
+ | imp :: _ -> is_status_implicit imp && maximal_insertion_of imp
+ | [] -> false
+
+let extern_global loc impl f us =
+ if not !Constrintern.parsing_explicit && is_start_implicit impl
then
- CAppExpl (loc, (None, f), [])
- else
- CRef f
-
-let extern_app loc inctx impl (cf,f) args =
- if args = [] (* maybe caused by a hidden coercion *) then
- extern_global loc impl f
+ CAppExpl (loc, (None, f, us), [])
else
- if not !Constrintern.parsing_explicit &&
- ((!Flags.raw_print or
- (!print_implicits & not !print_implicits_explicit_args)) &
+ CRef (f,us)
+
+let extern_app loc inctx impl (cf,f) us args =
+ if List.is_empty args then
+ (* If coming from a notation "Notation a := @b" *)
+ CAppExpl (loc, (None, f, us), [])
+ else if not !Constrintern.parsing_explicit &&
+ ((!Flags.raw_print ||
+ (!print_implicits && not !print_implicits_explicit_args)) &&
List.exists is_status_implicit impl)
then
- CAppExpl (loc, (is_projection (List.length args) cf, f), args)
+ CAppExpl (loc, (is_projection (List.length args) cf,f,us), args)
else
- explicitize loc inctx impl (cf,CRef f) args
+ explicitize loc inctx impl (cf,CRef (f,us)) args
let rec extern_args extern scopes env args subscopes =
match args with
@@ -521,15 +545,19 @@ let rec extern_args extern scopes env args subscopes =
| scopt::subscopes -> (scopt,scopes), subscopes in
extern argscopes env a :: extern_args extern scopes env args subscopes
-let rec remove_coercions inctx = function
- | GApp (loc,GRef (_,r),args) as c
- when not (!Flags.raw_print or !print_coercions)
- ->
+
+let match_coercion_app = function
+ | GApp (loc,GRef (_,r,_),args) -> Some (loc, r, 0, args)
+ | _ -> None
+
+let rec remove_coercions inctx c =
+ match match_coercion_app c with
+ | Some (loc,r,pars,args) when not (!Flags.raw_print || !print_coercions) ->
let nargs = List.length args in
(try match Classops.hide_coercion r with
- | Some n when n < nargs && (inctx or n+1 < nargs) ->
+ | Some n when (n - pars) < nargs && (inctx || (n - pars)+1 < nargs) ->
(* We skip a coercion *)
- let l = list_skipn n args in
+ let l = List.skipn (n - pars) args in
let (a,l) = match l with a::l -> (a,l) | [] -> assert false in
(* Recursively remove the head coercions *)
let a' = remove_coercions true a in
@@ -541,10 +569,10 @@ let rec remove_coercions inctx = function
been confused with ordinary application or would have need
a surrounding context and the coercion to funclass would
have been made explicit to match *)
- if l = [] then a' else GApp (loc,a',l)
+ if List.is_empty l then a' else GApp (loc,a',l)
| _ -> c
with Not_found -> c)
- | c -> c
+ | _ -> c
let rec flatten_application = function
| GApp (loc,GApp(_,a,l'),l) -> flatten_application (GApp (loc,a,l'@l))
@@ -574,38 +602,44 @@ let extern_optimal_prim_token scopes r r' =
(* mapping glob_constr to constr_expr *)
let extern_glob_sort = function
- | GProp _ as s -> s
- | GType (Some _) as s when !print_universes -> s
- | GType _ -> GType None
+ | GProp -> GProp
+ | GSet -> GSet
+ | GType _ as s when !print_universes -> s
+ | GType _ -> GType []
+let extern_universes = function
+ | Some _ as l when !print_universes -> l
+ | _ -> None
+
let rec extern inctx scopes vars r =
let r' = remove_coercions inctx r in
try
- if !Flags.raw_print or !print_no_symbol then raise No_match;
+ if !Flags.raw_print || !print_no_symbol then raise No_match;
extern_optimal_prim_token scopes r r'
with No_match ->
try
let r'' = flatten_application r' in
- if !Flags.raw_print or !print_no_symbol then raise No_match;
+ if !Flags.raw_print || !print_no_symbol then raise No_match;
extern_symbol scopes vars r'' (uninterp_notations r'')
with No_match -> match r' with
- | GRef (loc,ref) ->
+ | GRef (loc,ref,us) ->
extern_global loc (select_stronger_impargs (implicits_of_global ref))
- (extern_reference loc vars ref)
+ (extern_reference loc vars ref) (extern_universes us)
- | GVar (loc,id) -> CRef (Ident (loc,id))
+ | GVar (loc,id) -> CRef (Ident (loc,id),None)
- | GEvar (loc,n,None) when !print_meta_as_hole -> CHole (loc, None)
+ | GEvar (loc,n,[]) when !print_meta_as_hole -> CHole (loc, None, Misctypes.IntroAnonymous, None)
| GEvar (loc,n,l) ->
- extern_evar loc n (Option.map (List.map (extern false scopes vars)) l)
+ extern_evar loc n (List.map (on_snd (extern false scopes vars)) l)
- | GPatVar (loc,n) ->
- if !print_meta_as_hole then CHole (loc, None) else CPatVar (loc,n)
+ | GPatVar (loc,(b,n)) ->
+ if !print_meta_as_hole then CHole (loc, None, Misctypes.IntroAnonymous, None) else
+ if b then CPatVar (loc,n) else CEvar (loc,n,[])
| GApp (loc,f,args) ->
(match f with
- | GRef (rloc,ref) ->
+ | GRef (rloc,ref,us) ->
let subscopes = find_arguments_scope ref in
let args =
extern_args (extern true) (snd scopes) vars args subscopes in
@@ -623,7 +657,7 @@ let rec extern inctx scopes vars r =
let projs = struc.Recordops.s_PROJ in
let locals = struc.Recordops.s_PROJKIND in
let rec cut args n =
- if n = 0 then args
+ if Int.equal n 0 then args
else
match args with
| [] -> raise No_match
@@ -635,7 +669,7 @@ let rec extern inctx scopes vars r =
| None :: q -> raise No_match
| Some c :: q ->
match locs with
- | [] -> anomaly "projections corruption [Constrextern.extern]"
+ | [] -> anomaly (Pp.str "projections corruption [Constrextern.extern]")
| (_, false) :: locs' ->
(* we don't want to print locals *)
ip q locs' args acc
@@ -644,92 +678,93 @@ let rec extern inctx scopes vars r =
| [] -> raise No_match
(* we give up since the constructor is not complete *)
| head :: tail -> ip q locs' tail
- ((extern_reference loc Idset.empty (ConstRef c), head) :: acc)
+ ((extern_reference loc Id.Set.empty (ConstRef c), head) :: acc)
in
CRecord (loc, None, List.rev (ip projs locals args []))
with
| Not_found | No_match | Exit ->
extern_app loc inctx
(select_stronger_impargs (implicits_of_global ref))
- (Some ref,extern_reference rloc vars ref) args
+ (Some ref,extern_reference rloc vars ref) (extern_universes us) args
end
+
| _ ->
- explicitize loc inctx [] (None,sub_extern false scopes vars f)
- (List.map (sub_extern true scopes vars) args))
-
- | GProd (loc,Anonymous,_,t,c) ->
- (* Anonymous product are never factorized *)
- CArrow (loc,extern_typ scopes vars t, extern_typ scopes vars c)
+ explicitize loc inctx [] (None,sub_extern false scopes vars f)
+ (List.map (sub_extern true scopes vars) args))
| GLetIn (loc,na,t,c) ->
CLetIn (loc,(loc,na),sub_extern false scopes vars t,
extern inctx scopes (add_vname vars na) c)
| GProd (loc,na,bk,t,c) ->
- let t = extern_typ scopes vars (anonymize_if_reserved na t) in
+ let t = extern_typ scopes vars t in
let (idl,c) = factorize_prod scopes (add_vname vars na) na bk t c in
- CProdN (loc,[(dummy_loc,na)::idl,Default bk,t],c)
+ CProdN (loc,[(Loc.ghost,na)::idl,Default bk,t],c)
| GLambda (loc,na,bk,t,c) ->
- let t = extern_typ scopes vars (anonymize_if_reserved na t) in
+ let t = extern_typ scopes vars t in
let (idl,c) = factorize_lambda inctx scopes (add_vname vars na) na bk t c in
- CLambdaN (loc,[(dummy_loc,na)::idl,Default bk,t],c)
+ CLambdaN (loc,[(Loc.ghost,na)::idl,Default bk,t],c)
| GCases (loc,sty,rtntypopt,tml,eqns) ->
- let vars' =
- List.fold_right (name_fold Idset.add)
- (cases_predicate_names tml) vars in
- let rtntypopt' = Option.map (extern_typ scopes vars') rtntypopt in
- let tml = List.map (fun (tm,(na,x)) ->
- let na' = match na,tm with
- Anonymous, GVar (_,id) when
- rtntypopt<>None & occur_glob_constr id (Option.get rtntypopt)
- -> Some (dummy_loc,Anonymous)
- | Anonymous, _ -> None
- | Name id, GVar (_,id') when id=id' -> None
- | Name _, _ -> Some (dummy_loc,na) in
- (sub_extern false scopes vars tm,
- (na',Option.map (fun (loc,ind,n,nal) ->
- let params = list_tabulate
- (fun _ -> GHole (dummy_loc,Evd.InternalHole)) n in
- let args = List.map (function
- | Anonymous -> GHole (dummy_loc,Evd.InternalHole)
- | Name id -> GVar (dummy_loc,id)) nal in
- let t = GApp (dummy_loc,GRef (dummy_loc,IndRef ind),params@args) in
- (extern_typ scopes vars t)) x))) tml in
- let eqns = List.map (extern_eqn inctx scopes vars) eqns in
- CCases (loc,sty,rtntypopt',tml,eqns)
+ let vars' =
+ List.fold_right (name_fold Id.Set.add)
+ (cases_predicate_names tml) vars in
+ let rtntypopt' = Option.map (extern_typ scopes vars') rtntypopt in
+ let tml = List.map (fun (tm,(na,x)) ->
+ let na' = match na,tm with
+ | Anonymous, GVar (_, id) ->
+ begin match rtntypopt with
+ | None -> None
+ | Some ntn ->
+ if occur_glob_constr id ntn then
+ Some (Loc.ghost, Anonymous)
+ else None
+ end
+ | Anonymous, _ -> None
+ | Name id, GVar (_,id') when Id.equal id id' -> None
+ | Name _, _ -> Some (Loc.ghost,na) in
+ (sub_extern false scopes vars tm,
+ (na',Option.map (fun (loc,ind,nal) ->
+ let args = List.map (fun x -> PatVar (Loc.ghost, x)) nal in
+ let fullargs =
+ if !Flags.in_debugger then args else
+ Notation_ops.add_patterns_for_params ind args in
+ extern_ind_pattern_in_scope scopes vars ind fullargs
+ ) x))) tml in
+ let eqns = List.map (extern_eqn inctx scopes vars) eqns in
+ CCases (loc,sty,rtntypopt',tml,eqns)
| GLetTuple (loc,nal,(na,typopt),tm,b) ->
- CLetTuple (loc,List.map (fun na -> (dummy_loc,na)) nal,
- (Option.map (fun _ -> (dummy_loc,na)) typopt,
+ CLetTuple (loc,List.map (fun na -> (Loc.ghost,na)) nal,
+ (Option.map (fun _ -> (Loc.ghost,na)) typopt,
Option.map (extern_typ scopes (add_vname vars na)) typopt),
sub_extern false scopes vars tm,
extern inctx scopes (List.fold_left add_vname vars nal) b)
| GIf (loc,c,(na,typopt),b1,b2) ->
CIf (loc,sub_extern false scopes vars c,
- (Option.map (fun _ -> (dummy_loc,na)) typopt,
+ (Option.map (fun _ -> (Loc.ghost,na)) typopt,
Option.map (extern_typ scopes (add_vname vars na)) typopt),
sub_extern inctx scopes vars b1, sub_extern inctx scopes vars b2)
| GRec (loc,fk,idv,blv,tyv,bv) ->
- let vars' = Array.fold_right Idset.add idv vars in
+ let vars' = Array.fold_right Id.Set.add idv vars in
(match fk with
| GFix (nv,n) ->
let listdecl =
Array.mapi (fun i fi ->
let (bl,ty,def) = blv.(i), tyv.(i), bv.(i) in
let (assums,ids,bl) = extern_local_binder scopes vars bl in
- let vars0 = List.fold_right (name_fold Idset.add) ids vars in
- let vars1 = List.fold_right (name_fold Idset.add) ids vars' in
+ let vars0 = List.fold_right (name_fold Id.Set.add) ids vars in
+ let vars1 = List.fold_right (name_fold Id.Set.add) ids vars' in
let n =
match fst nv.(i) with
| None -> None
- | Some x -> Some (dummy_loc, out_name (List.nth assums x))
+ | Some x -> Some (Loc.ghost, out_name (List.nth assums x))
in
let ro = extern_recursion_order scopes vars (snd nv.(i)) in
- ((dummy_loc, fi), (n, ro), bl, extern_typ scopes vars0 ty,
+ ((Loc.ghost, fi), (n, ro), bl, extern_typ scopes vars0 ty,
extern false scopes vars1 def)) idv
in
CFix (loc,(loc,idv.(n)),Array.to_list listdecl)
@@ -737,21 +772,20 @@ let rec extern inctx scopes vars r =
let listdecl =
Array.mapi (fun i fi ->
let (_,ids,bl) = extern_local_binder scopes vars blv.(i) in
- let vars0 = List.fold_right (name_fold Idset.add) ids vars in
- let vars1 = List.fold_right (name_fold Idset.add) ids vars' in
- ((dummy_loc, fi),bl,extern_typ scopes vars0 tyv.(i),
+ let vars0 = List.fold_right (name_fold Id.Set.add) ids vars in
+ let vars1 = List.fold_right (name_fold Id.Set.add) ids vars' in
+ ((Loc.ghost, fi),bl,extern_typ scopes vars0 tyv.(i),
sub_extern false scopes vars1 bv.(i))) idv
in
CCoFix (loc,(loc,idv.(n)),Array.to_list listdecl))
| GSort (loc,s) -> CSort (loc,extern_glob_sort s)
- | GHole (loc,e) -> CHole (loc, Some e)
+ | GHole (loc,e,naming,_) -> CHole (loc, Some e, naming, None) (** TODO: extern tactics. *)
- | GCast (loc,c, CastConv (k,t)) ->
- CCast (loc,sub_extern true scopes vars c, CastConv (k,extern_typ scopes vars t))
- | GCast (loc,c, CastCoerce) ->
- CCast (loc,sub_extern true scopes vars c, CastCoerce)
+ | GCast (loc,c, c') ->
+ CCast (loc,sub_extern true scopes vars c,
+ Miscops.map_cast_type (extern_typ scopes vars) c')
and extern_typ (_,scopes) =
extern true (Some Notation.type_scope,scopes)
@@ -762,8 +796,8 @@ and factorize_prod scopes vars na bk aty c =
let c = extern_typ scopes vars c in
match na, c with
| Name id, CProdN (loc,[nal,Default bk',ty],c)
- when bk = bk' && is_same_type aty ty
- & not (occur_var_constr_expr id ty) (* avoid na in ty escapes scope *) ->
+ when binding_kind_eq bk bk' && constr_expr_eq aty ty
+ && not (occur_var_constr_expr id ty) (* avoid na in ty escapes scope *) ->
nal,c
| _ ->
[],c
@@ -772,8 +806,8 @@ and factorize_lambda inctx scopes vars na bk aty c =
let c = sub_extern inctx scopes vars c in
match c with
| CLambdaN (loc,[nal,Default bk',ty],c)
- when bk = bk' && is_same_type aty ty
- & not (occur_name na ty) (* avoid na in ty escapes scope *) ->
+ when binding_kind_eq bk bk' && constr_expr_eq aty ty
+ && not (occur_name na ty) (* avoid na in ty escapes scope *) ->
nal,c
| _ ->
[],c
@@ -782,22 +816,22 @@ and extern_local_binder scopes vars = function
[] -> ([],[],[])
| (na,bk,Some bd,ty)::l ->
let (assums,ids,l) =
- extern_local_binder scopes (name_fold Idset.add na vars) l in
+ extern_local_binder scopes (name_fold Id.Set.add na vars) l in
(assums,na::ids,
- LocalRawDef((dummy_loc,na), extern false scopes vars bd) :: l)
+ LocalRawDef((Loc.ghost,na), extern false scopes vars bd) :: l)
| (na,bk,None,ty)::l ->
- let ty = extern_typ scopes vars (anonymize_if_reserved na ty) in
- (match extern_local_binder scopes (name_fold Idset.add na vars) l with
+ let ty = extern_typ scopes vars ty in
+ (match extern_local_binder scopes (name_fold Id.Set.add na vars) l with
(assums,ids,LocalRawAssum(nal,k,ty')::l)
- when is_same_type ty ty' &
+ when constr_expr_eq ty ty' &&
match na with Name id -> not (occur_var_constr_expr id ty')
| _ -> true ->
(na::assums,na::ids,
- LocalRawAssum((dummy_loc,na)::nal,k,ty')::l)
+ LocalRawAssum((Loc.ghost,na)::nal,k,ty')::l)
| (assums,ids,l) ->
(na::assums,na::ids,
- LocalRawAssum([(dummy_loc,na)],Default bk,ty) :: l))
+ LocalRawAssum([(Loc.ghost,na)],Default bk,ty) :: l))
and extern_eqn inctx scopes vars (loc,ids,pl,c) =
(loc,[loc,List.map (extern_cases_pattern_in_scope scopes vars) pl],
@@ -806,42 +840,42 @@ and extern_eqn inctx scopes vars (loc,ids,pl,c) =
and extern_symbol (tmp_scope,scopes as allscopes) vars t = function
| [] -> raise No_match
| (keyrule,pat,n as _rule)::rules ->
- let loc = Glob_term.loc_of_glob_constr t in
+ let loc = Glob_ops.loc_of_glob_constr t in
try
+ if List.mem keyrule !print_non_active_notations then raise No_match;
(* Adjusts to the number of arguments expected by the notation *)
let (t,args,argsscopes,argsimpls) = match t,n with
| GApp (_,f,args), Some n
when List.length args >= n ->
- let args1, args2 = list_chop n args in
+ let args1, args2 = List.chop n args in
let subscopes, impls =
match f with
- | GRef (_,ref) ->
+ | GRef (_,ref,us) ->
let subscopes =
- try list_skipn n (find_arguments_scope ref)
- with e when Errors.noncritical e -> [] in
+ try List.skipn n (find_arguments_scope ref)
+ with Failure _ -> [] in
let impls =
let impls =
select_impargs_size
(List.length args) (implicits_of_global ref) in
- try list_skipn n impls
- with e when Errors.noncritical e -> [] in
+ try List.skipn n impls with Failure _ -> [] in
subscopes,impls
| _ ->
[], [] in
- (if n = 0 then f else GApp (dummy_loc,f,args1)),
+ (if Int.equal n 0 then f else GApp (Loc.ghost,f,args1)),
args2, subscopes, impls
- | GApp (_,(GRef (_,ref) as f),args), None ->
+ | GApp (_,(GRef (_,ref,us) as f),args), None ->
let subscopes = find_arguments_scope ref in
let impls =
select_impargs_size
(List.length args) (implicits_of_global ref) in
f, args, subscopes, impls
- | GRef _, Some 0 -> GApp (dummy_loc,t,[]), [], [], []
+ | GRef (_,ref,us), Some 0 -> GApp (Loc.ghost,t,[]), [], [], []
| _, None -> t, [], [], []
| _ -> raise No_match in
(* Try matching ... *)
let terms,termlists,binders =
- match_aconstr !print_universes t pat in
+ match_notation_constr !print_universes t pat in
(* Try availability of interpretation ... *)
let e =
match keyrule with
@@ -871,9 +905,9 @@ and extern_symbol (tmp_scope,scopes as allscopes) vars t = function
List.map (fun (c,(scopt,scl)) ->
extern true (scopt,scl@scopes) vars c, None)
terms in
- let a = CRef (Qualid (loc, shortest_qualid_of_syndef vars kn)) in
- if l = [] then a else CApp (loc,(None,a),l) in
- if args = [] then e
+ let a = CRef (Qualid (loc, shortest_qualid_of_syndef vars kn),None) in
+ if List.is_empty l then a else CApp (loc,(None,a),l) in
+ if List.is_empty args then e
else
let args = extern_args (extern true) scopes vars args argsscopes in
explicitize loc false argsimpls (None,e) args
@@ -896,9 +930,9 @@ let extern_glob_type vars c =
(******************************************************************)
(* Main translation function from constr -> constr_expr *)
-let loc = dummy_loc (* for constr and pattern, locations are lost *)
+let loc = Loc.ghost (* for constr and pattern, locations are lost *)
-let extern_constr_gen goal_concl_style scopt env t =
+let extern_constr_gen lax goal_concl_style scopt env sigma t =
(* "goal_concl_style" means do alpha-conversion using the "goal" convention *)
(* i.e.: avoid using the names of goal/section/rel variables and the short *)
(* names of global definitions of current module when computing names for *)
@@ -907,87 +941,99 @@ let extern_constr_gen goal_concl_style scopt env t =
(* those goal/section/rel variables that occurs in the subterm under *)
(* consideration; see namegen.ml for further details *)
let avoid = if goal_concl_style then ids_of_context env else [] in
- let rel_env_names = names_of_rel_context env in
- let r = Detyping.detype goal_concl_style avoid rel_env_names t in
+ let r = Detyping.detype ~lax:lax goal_concl_style avoid env sigma t in
let vars = vars_of_env env in
extern false (scopt,[]) vars r
-let extern_constr_in_scope goal_concl_style scope env t =
- extern_constr_gen goal_concl_style (Some scope) env t
+let extern_constr_in_scope goal_concl_style scope env sigma t =
+ extern_constr_gen false goal_concl_style (Some scope) env sigma t
-let extern_constr goal_concl_style env t =
- extern_constr_gen goal_concl_style None env t
+let extern_constr ?(lax=false) goal_concl_style env sigma t =
+ extern_constr_gen lax goal_concl_style None env sigma t
-let extern_type goal_concl_style env t =
+let extern_type goal_concl_style env sigma t =
let avoid = if goal_concl_style then ids_of_context env else [] in
- let rel_env_names = names_of_rel_context env in
- let r = Detyping.detype goal_concl_style avoid rel_env_names t in
+ let r = Detyping.detype goal_concl_style avoid env sigma t in
extern_glob_type (vars_of_env env) r
-let extern_sort s = extern_glob_sort (detype_sort s)
+let extern_sort sigma s = extern_glob_sort (detype_sort sigma s)
+
+let extern_closed_glob ?lax goal_concl_style env sigma t =
+ let avoid = if goal_concl_style then ids_of_context env else [] in
+ let r =
+ Detyping.detype_closed_glob ?lax goal_concl_style avoid env sigma t
+ in
+ let vars = vars_of_env env in
+ extern false (None,[]) vars r
(******************************************************************)
(* Main translation function from pattern -> constr_expr *)
let any_any_branch =
(* | _ => _ *)
- (loc,[],[PatVar (loc,Anonymous)],GHole (loc,Evd.InternalHole))
+ (loc,[],[PatVar (loc,Anonymous)],GHole (loc,Evar_kinds.InternalHole,Misctypes.IntroAnonymous,None))
-let rec glob_of_pat env = function
- | PRef ref -> GRef (loc,ref)
+let rec glob_of_pat env sigma = function
+ | PRef ref -> GRef (loc,ref,None)
| PVar id -> GVar (loc,id)
- | PEvar (n,l) -> GEvar (loc,n,Some (array_map_to_list (glob_of_pat env) l))
+ | PEvar (evk,l) ->
+ let test id = function PVar id' -> Id.equal id id' | _ -> false in
+ let l = Evd.evar_instance_array test (Evd.find sigma evk) l in
+ let id = Evd.evar_ident evk sigma in
+ GEvar (loc,id,List.map (on_snd (glob_of_pat env sigma)) l)
| PRel n ->
let id = try match lookup_name_of_rel n env with
| Name id -> id
| Anonymous ->
- anomaly "glob_constr_of_pattern: index to an anonymous variable"
- with Not_found -> id_of_string ("_UNBOUND_REL_"^(string_of_int n)) in
+ anomaly ~label:"glob_constr_of_pattern" (Pp.str "index to an anonymous variable")
+ with Not_found -> Id.of_string ("_UNBOUND_REL_"^(string_of_int n)) in
GVar (loc,id)
- | PMeta None -> GHole (loc,Evd.InternalHole)
+ | PMeta None -> GHole (loc,Evar_kinds.InternalHole, Misctypes.IntroAnonymous,None)
| PMeta (Some n) -> GPatVar (loc,(false,n))
+ | PProj (p,c) -> GApp (loc,GRef (loc, ConstRef (Projection.constant p),None),
+ [glob_of_pat env sigma c])
| PApp (f,args) ->
- GApp (loc,glob_of_pat env f,array_map_to_list (glob_of_pat env) args)
+ GApp (loc,glob_of_pat env sigma f,Array.map_to_list (glob_of_pat env sigma) args)
| PSoApp (n,args) ->
GApp (loc,GPatVar (loc,(true,n)),
- List.map (glob_of_pat env) args)
+ List.map (glob_of_pat env sigma) args)
| PProd (na,t,c) ->
- GProd (loc,na,Explicit,glob_of_pat env t,glob_of_pat (na::env) c)
+ GProd (loc,na,Explicit,glob_of_pat env sigma t,glob_of_pat (na::env) sigma c)
| PLetIn (na,t,c) ->
- GLetIn (loc,na,glob_of_pat env t, glob_of_pat (na::env) c)
+ GLetIn (loc,na,glob_of_pat env sigma t, glob_of_pat (na::env) sigma c)
| PLambda (na,t,c) ->
- GLambda (loc,na,Explicit,glob_of_pat env t, glob_of_pat (na::env) c)
+ GLambda (loc,na,Explicit,glob_of_pat env sigma t, glob_of_pat (na::env) sigma c)
| PIf (c,b1,b2) ->
- GIf (loc, glob_of_pat env c, (Anonymous,None),
- glob_of_pat env b1, glob_of_pat env b2)
- | PCase ({cip_style=LetStyle; cip_ind_args=None},PMeta None,tm,[(0,n,b)]) ->
- let nal,b = it_destRLambda_or_LetIn_names n (glob_of_pat env b) in
- GLetTuple (loc,nal,(Anonymous,None),glob_of_pat env tm,b)
+ GIf (loc, glob_of_pat env sigma c, (Anonymous,None),
+ glob_of_pat env sigma b1, glob_of_pat env sigma b2)
+ | PCase ({cip_style=LetStyle; cip_ind_tags=None},PMeta None,tm,[(0,n,b)]) ->
+ let nal,b = it_destRLambda_or_LetIn_names n (glob_of_pat env sigma b) in
+ GLetTuple (loc,nal,(Anonymous,None),glob_of_pat env sigma tm,b)
| PCase (info,p,tm,bl) ->
let mat = match bl, info.cip_ind with
| [], _ -> []
| _, Some ind ->
- let bl' = List.map (fun (i,n,c) -> (i,n,glob_of_pat env c)) bl in
+ let bl' = List.map (fun (i,n,c) -> (i,n,glob_of_pat env sigma c)) bl in
simple_cases_matrix_of_branches ind bl'
- | _, None -> anomaly "PCase with some branches but unknown inductive"
+ | _, None -> anomaly (Pp.str "PCase with some branches but unknown inductive")
in
let mat = if info.cip_extensible then mat @ [any_any_branch] else mat
in
- let indnames,rtn = match p, info.cip_ind, info.cip_ind_args with
+ let indnames,rtn = match p, info.cip_ind, info.cip_ind_tags with
| PMeta None, _, _ -> (Anonymous,None),None
- | _, Some ind, Some (nparams,nargs) ->
- return_type_of_predicate ind nparams nargs (glob_of_pat env p)
- | _ -> anomaly "PCase with non-trivial predicate but unknown inductive"
+ | _, Some ind, Some nargs ->
+ return_type_of_predicate ind nargs (glob_of_pat env sigma p)
+ | _ -> anomaly (Pp.str "PCase with non-trivial predicate but unknown inductive")
in
- GCases (loc,RegularStyle,rtn,[glob_of_pat env tm,indnames],mat)
- | PFix f -> Detyping.detype false [] env (mkFix f)
- | PCoFix c -> Detyping.detype false [] env (mkCoFix c)
+ GCases (loc,RegularStyle,rtn,[glob_of_pat env sigma tm,indnames],mat)
+ | PFix f -> Detyping.detype_names false [] env (Global.env()) sigma (mkFix f) (** FIXME bad env *)
+ | PCoFix c -> Detyping.detype_names false [] env (Global.env()) sigma (mkCoFix c)
| PSort s -> GSort (loc,s)
-let extern_constr_pattern env pat =
- extern true (None,[]) Idset.empty (glob_of_pat env pat)
+let extern_constr_pattern env sigma pat =
+ extern true (None,[]) Id.Set.empty (glob_of_pat env sigma pat)
-let extern_rel_context where env sign =
- let a = detype_rel_context where [] (names_of_rel_context env) sign in
+let extern_rel_context where env sigma sign =
+ let a = detype_rel_context where [] (names_of_rel_context env,env) sigma sign in
let vars = vars_of_env env in
pi3 (extern_local_binder (None,[]) vars a)