aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorherbelin2003-11-01 22:45:12 +0000
committerherbelin2003-11-01 22:45:12 +0000
commitb2dbc89b58adbb38d950f0c29b9c3046773675c4 (patch)
treef8527a147fe3f0452cd8d5a974952b584793a9f6
parent9a60571e2c7a7d42bb3abeeaba59465880b5ef48 (diff)
Extensibilite de la grammaires des patterns
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/coq/trunk@4765 85f007b7-540e-0410-9357-904b9bb8a0f7
-rw-r--r--interp/constrextern.ml151
-rw-r--r--interp/constrintern.ml45
2 files changed, 182 insertions, 14 deletions
diff --git a/interp/constrextern.ml b/interp/constrextern.ml
index 01ed0cf98a..461eabf592 100644
--- a/interp/constrextern.ml
+++ b/interp/constrextern.ml
@@ -196,7 +196,7 @@ let translate_v7_string dir = function
| "times_assoc" -> "Pmult_assoc"
| "times_convert" -> "IPN_mult_morphism"
| "true_sub" -> "Pminus"
- | "times_x_1" -> "Pmult_1_right"
+ | "times_x_1" -> "Pmult_1_r"
| "times_x_double" -> "Pmult_xO_permute_r"
| "times_x_double_plus_one" -> "Pmult_xI_permute_r"
| "true_sub_convert" -> "IPN_minus_morphism"
@@ -246,6 +246,7 @@ let translate_v7_string dir = function
| "Zminus_Zplus_compatible" -> "Zminus_plus_simpl_r"
| "Zle_plus_minus" -> "Zplus_minus"
| "Zopp_Zplus" -> "Zplus_opp_distr"
+ | "Zplus_inverse_r" -> "Zplus_opp_r"
| "Zmult_sym" -> "Zmult_comm"
| "Zero_mult_left" -> "Zmult_0_l"
| "Zero_mult_right" -> "Zmult_0_r"
@@ -341,6 +342,8 @@ let translate_v7_string dir = function
| "Zsimpl_le_plus_r" -> "Zplus_le_reg_r"
| "Zsimpl_lt_plus_l" -> "Zplus_lt_reg_l"
| "Zsimpl_lt_plus_r" -> "Zplus_lt_reg_r"
+ | "Zlt_Zmult_left" -> "Zmult_lt_compat_l"
+ | "Zlt_Zmult_right" -> "Zmult_lt_compat_r"
(* IntMap *)
| "convert_xH" -> "IPN_xH"
| "convert_xO" -> "IPN_xO"
@@ -370,6 +373,7 @@ let translate_v7_string dir = function
| "exists" -> "exists_between"
| "IHexists" -> "IHexists_between"
| "pred_Sn" -> "pred_S"
+ | "inj_minus_aux" -> "not_le_minus_0"
| "gt_reg_l" -> "plus_gt_compat_l"
| "le_reg_l" -> "plus_le_compat_l"
| "le_reg_r" -> "plus_le_compat_r"
@@ -418,8 +422,39 @@ let translate_v7_string dir = function
| "complet_weak" -> "completeness_weak"
| "Rle_sym1" -> "Rle_ge"
| "Rmin_sym" -> "Rmin_comm"
+ | "Rplus_sym" -> "Rplus_comm"
+ | "Rmult_sym" -> "Rmult_comm"
| "Rsqr_times" -> "Rsqr_mult"
| "sqrt_times" -> "sqrt_mult"
+ | "Rmult_1l" -> "Rmult_1_l"
+ | "Rplus_Ol" -> "Rplus_0_l"
+ | "Rplus_Ropp_r" -> "Rplus_opp_r"
+ | "Rmult_Rplus_distr_l" -> "Rmult_plus_distr_l"
+ | "Rlt_antisym" -> "Rlt_asym"
+ | "Rlt_compatibility" -> "Rplus_lt_compat_l"
+ | "Rgt_plus_plus_r" -> "Rplus_gt_compat_l"
+ | "Rgt_r_plus_plus" -> "Rplus_gt_reg_l"
+ | "Rge_plus_plus_r" -> "Rplus_ge_compat_l"
+ | "Rge_r_plus_plus" -> "Rplus_ge_reg_l"
+(* Si on en change un, il faut changer tous les autres R*_monotony *)
+ | "Rlt_monotony" -> "Rmult_lt_compat_l"
+ | "Rlt_monotony_r" -> "Rmult_lt_compat_r"
+ | "Rlt_monotony_contra" -> "Rmult_lt_reg_l"
+ | "Rlt_anti_monotony" -> "Rmult_lt_gt_compat_neg_l"
+ | "Rle_monotony" -> "Rmult_le_compat_l"
+ | "Rle_monotony_r" -> "Rmult_le_compat_r"
+ | "Rle_monotony_contra" -> "Rmult_le_reg_l"
+ | "Rle_anti_monotony1" -> "Rmult_le_compat_neg_l"
+ | "Rle_anti_monotony" -> "Rmult_le_ge_compat_neg_l"
+ | "Rle_Rmult_comp" -> "Rmult_le_compat"
+ (* Expliciter que la contrainte est r2>0 dans r1<r2 et non 0<r1 ce
+ qui est plus général mais différent de Rmult_le_compat *)
+ | "Rmult_lt" -> "Rmult_lt_compat"
+ | "Rlt_monotony_rev" -> "Rmult_lt_reg_l"
+ | "Rge_monotony" -> "Rmult_ge_compat_r"
+ | "Rmult_lt_0" -> "Rmult_lt_compat_ge" (* Un truc hybride *)
+
+ | "Rge_ge_eq" -> "Rge_antisym"
| s when String.length s >= 7 &
let s' = String.sub s 0 7 in
(s' = "unicite" or s' = "unicity") ->
@@ -543,21 +578,86 @@ and check_same_binder (nal1,e1) (nal2,e2) =
let same c d = try check_same_type c d; true with _ -> false
(**********************************************************************)
-(* conversion of terms and cases patterns *)
+(* mapping patterns to cases_pattern_expr *)
let make_current_scopes (scopt,scopes) =
option_fold_right push_scope scopt scopes
+(*
+let rec cases_pattern_expr_of_constr_expr = function
+ | CRef r -> CPatAtom (dummy_loc,Some r)
+ | CHole loc -> CPatAtom (loc,None)
+ | CApp (loc,(proj,CRef c),l) when proj = None ->
+ let l,e = List.split l in
+ if not (List.for_all ((=) None) e) then
+ anomaly "Unexpected explicitation in pattern";
+ CPatCstr (loc,c,List.map cases_pattern_expr_of_constr_expr l)
+ | CNotation (loc,ntn,l) ->
+ CPatNotation (loc,ntn,List.map cases_pattern_expr_of_constr_expr l)
+ | CNumeral (loc,n) -> CPatNumeral (loc,n)
+ | CDelimiters (loc,s,e) ->
+ CPatDelimiters (loc,s,cases_pattern_expr_of_constr_expr e)
+ | _ -> anomaly "Constrextern: not a pattern"
+
+let rec rawconstr_of_cases_pattern = function
+ | PatVar (loc,Name id) -> RVar (loc,id)
+ | PatVar (loc,Anonymous) -> RHole (loc,InternalHole)
+ | PatCstr (loc,(ind,_ as c),args,_) ->
+ let nparams = (snd (Global.lookup_inductive ind)).Declarations.mind_nparams in
+ let params = list_tabulate (fun _ -> RHole (loc,InternalHole)) nparams in
+ let args = params @ List.map rawconstr_of_cases_pattern args in
+ let f = RRef (loc,ConstructRef c) in
+ if args = [] then f else RApp (loc,f,args)
+*)
+
+let bind_env sigma var v =
+ try
+ let vvar = List.assoc var sigma in
+ if v=vvar then sigma else raise No_match
+ with Not_found ->
+ (* TODO: handle the case of multiple occs in different scopes *)
+ (var,v)::sigma
+
+let rec match_cases_pattern metas sigma a1 a2 = match (a1,a2) with
+ | r1, AVar id2 when List.mem id2 metas -> bind_env sigma id2 r1
+ | PatVar (_,Anonymous), AHole _ -> sigma
+ | a, AHole _ when not(Options.do_translate()) -> sigma
+ | PatCstr (loc,(ind,_ as r1),args1,Anonymous), _ ->
+ let nparams =
+ (snd (Global.lookup_inductive ind)).Declarations.mind_nparams in
+ let params1 = list_tabulate (fun _ -> PatVar (loc,Anonymous)) nparams in
+ (match params1@args1, a2 with
+ | [], ARef (ConstructRef r2) when r1 = r2 -> sigma
+ | l1, AApp (ARef (ConstructRef r2),l2)
+ when r1 = r2 & List.length l1 = List.length l2 ->
+ List.fold_left2 (match_cases_pattern metas) sigma l1 l2
+ | _ -> raise No_match)
+ | _ -> raise No_match
+
+let match_aconstr_cases_pattern c (metas_scl,pat) =
+ let subst = match_cases_pattern (List.map fst metas_scl) [] c pat in
+ (* Reorder canonically the substitution *)
+ let find x subst =
+ try List.assoc x subst
+ with Not_found -> anomaly "match_aconstr_cases_pattern" in
+ List.map (fun (x,scl) -> (find x subst,scl)) metas_scl
+
+ (* Better to use extern_rawconstr composed with injection/retraction ?? *)
let rec extern_cases_pattern_in_scope scopes vars pat =
try
if !print_no_symbol then raise No_match;
let (sc,n) = Symbols.uninterp_cases_numeral pat in
- match Symbols.availability_of_numeral sc scopes with
+ match Symbols.availability_of_numeral sc (make_current_scopes scopes) with
| None -> raise No_match
| Some key ->
let loc = pattern_loc pat in
insert_pat_delimiters (CPatNumeral (loc,n)) key
with No_match ->
+ try
+ if !print_no_symbol then raise No_match;
+ extern_symbol_pattern scopes vars pat
+ (Symbols.uninterp_cases_pattern_notations pat)
+ with No_match ->
match pat with
| PatVar (loc,Name id) -> CPatAtom (loc,Some (Ident (loc,v7_to_v8_id id)))
| PatVar (loc,Anonymous) -> CPatAtom (loc, None)
@@ -569,6 +669,42 @@ let rec extern_cases_pattern_in_scope scopes vars pat =
| Name id -> CPatAlias (loc,p,v7_to_v8_id id)
| Anonymous -> p)
+and extern_symbol_pattern (tmp_scope,scopes as allscopes) vars t = function
+ | [] -> raise No_match
+ | (keyrule,pat,n as rule)::rules ->
+ try
+ (* Check the number of arguments expected by the notation *)
+ let loc = match t,n with
+ | PatCstr (_,f,l,_), Some n when List.length l > n ->
+ raise No_match
+ | PatCstr (loc,_,_,_),_ -> loc
+ | PatVar (loc,_),_ -> loc in
+ (* Try matching ... *)
+ let subst = match_aconstr_cases_pattern t pat in
+ (* Try availability of interpretation ... *)
+ match keyrule with
+ | NotationRule (sc,ntn) ->
+ let scopes' = make_current_scopes (tmp_scope, scopes) in
+ (match Symbols.availability_of_notation (sc,ntn) scopes' with
+ (* Uninterpretation is not allowed in current context *)
+ | None -> raise No_match
+ (* Uninterpretation is allowed in current context *)
+ | Some (scopt,key) ->
+ let scopes = make_current_scopes (scopt, scopes) in
+ let l =
+ List.map (fun (c,(scopt,scl)) ->
+ extern_cases_pattern_in_scope
+ (scopt,List.fold_right push_scope scl scopes) vars c)
+ subst in
+ insert_pat_delimiters (CPatNotation (loc,ntn,l)) key)
+ | SynDefRule kn ->
+ CPatAtom (loc,Some (Qualid (loc, shortest_qualid_of_syndef kn)))
+ with
+ No_match -> extern_symbol_pattern allscopes vars t rules
+
+(**********************************************************************)
+(* Externalising applications *)
+
let occur_name na aty =
match na with
| Name id -> occur_var_constr_expr id aty
@@ -591,6 +727,8 @@ let stdlib_but_length args = function
let dir,id = repr_path (sp_of_global r) in
(is_coq_root (Lib.library_dp()) or is_coq_root dir)
&& not (List.mem (string_of_id id) ["Zlength";"length"] && is_nil args)
+ && not (List.mem (string_of_id id) ["In"] && List.length args >= 2
+ && is_nil (List.tl args))
| None -> false
let explicit_code imp q =
@@ -678,6 +816,9 @@ 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
+(**********************************************************************)
+(* mapping rawterms to constr_expr *)
+
let rec extern inctx scopes vars r =
try
if !print_no_symbol then raise No_match;
@@ -835,7 +976,7 @@ and factorize_lambda inctx scopes vars aty = function
| c -> ([],sub_extern inctx scopes vars c)
and extern_eqn inctx scopes vars (loc,ids,pl,c) =
- (loc,List.map (extern_cases_pattern_in_scope (snd scopes) vars) pl,
+ (loc,List.map (extern_cases_pattern_in_scope scopes vars) pl,
extern inctx scopes vars c)
and extern_numeral loc scopes (sc,n) =
@@ -890,7 +1031,7 @@ let extern_rawtype vars c =
extern_type (None,Symbols.current_scopes()) vars c
let extern_cases_pattern vars p =
- extern_cases_pattern_in_scope (Symbols.current_scopes()) vars p
+ extern_cases_pattern_in_scope (None,Symbols.current_scopes()) vars p
(******************************************************************)
(* Main translation function from constr -> constr_expr *)
diff --git a/interp/constrintern.ml b/interp/constrintern.ml
index 97790d3633..f27b7e4ca5 100644
--- a/interp/constrintern.ml
+++ b/interp/constrintern.ml
@@ -313,6 +313,36 @@ let message_redundant_alias (id1,id2) =
if_verbose warning
("Alias variable "^(string_of_id id1)^" is merged with "^(string_of_id id2))
+(* Expanding notations *)
+
+let subst_cases_pattern loc aliases intern subst scopes a =
+ let rec aux aliases = function
+ | AVar id ->
+ begin
+ (* subst remembers the delimiters stack in the interpretation *)
+ (* of the notations *)
+ try
+ let (a,(scopt,subscopes)) = List.assoc id subst in
+ intern (subscopes@scopes) ([],[]) scopt a
+ with Not_found ->
+ anomaly "Unbound pattern notation variable"
+ (*
+ (* Happens for local notation joint with inductive/fixpoint defs *)
+ if aliases <> ([],[]) then
+ anomaly "Pattern notation without constructors";
+ [[id],[]], PatVar (loc,Name id)
+ *)
+ end
+ | ARef (ConstructRef c) ->
+ [aliases], PatCstr (loc,c, [], alias_of aliases)
+ | AApp (ARef (ConstructRef (ind,_ as c)),args) ->
+ let nparams = (snd (Global.lookup_inductive ind)).Declarations.mind_nparams in
+ let _,args = list_chop nparams args in
+ let (idsl,pl) = List.split (List.map (aux ([],[])) args) in
+ aliases::List.flatten idsl, PatCstr (loc,c,pl,alias_of aliases)
+ | t -> user_err_loc (loc,"",str "Invalid notation for pattern")
+ in aux aliases a
+
(* Differentiating between constructors and matching variables *)
type pattern_qualid_kind =
| ConstrPat of constructor
@@ -365,6 +395,11 @@ let rec intern_cases_pattern scopes aliases tmp_scope = function
List.split (List.map2 (intern_cases_pattern scopes ([],[])) argscs pl)
in
(aliases::(List.flatten idsl), PatCstr (loc,c,pl',alias_of aliases))
+ | CPatNotation (loc, ntn, args) ->
+ let scopes = option_cons tmp_scope scopes in
+ let (ids,c) = Symbols.interp_notation ntn scopes in
+ let subst = List.map2 (fun (id,scl) a -> (id,(a,scl))) ids args in
+ subst_cases_pattern loc aliases intern_cases_pattern subst scopes c
| CPatNumeral (loc, n) ->
let scopes = option_cons tmp_scope scopes in
([aliases],
@@ -519,16 +554,8 @@ let rec subst_rawconstr loc interp subst (ids,_,scopes as env) = function
(* Happens for local notation joint with inductive/fixpoint defs *)
RVar (loc,id)
end
-(*
- | AApp (ARef ref,args) ->
- let argscopes = find_arguments_scope ref in
- let argsenv = adjust_scopes env argscopes args in
- RApp (loc,RRef (loc,ref),
- List.map2 (subst_rawconstr loc interp subst) argsenv args)
- (* TODO: adjust type_scope for lambda, annotations, etc *)
-*)
| t ->
- map_aconstr_with_binders_loc loc (traverse_binder subst)
+ rawconstr_of_aconstr_with_binders loc (traverse_binder subst)
(subst_rawconstr loc interp subst) (ids,None,scopes) t
let set_type_scope (ids,tmp_scope,scopes) =