@@ -628,9 +628,20 @@ let rule_of_pre_rule : pre_rule -> rule =
628628 ; vars = pr_vars
629629 ; xvars_nb = pr_xvars_nb }
630630
631- (* * [scope_rule ur ss r] turns a parser-level rewriting rule [r], or a
632- unification rule if [ur] is true, into a pre-rewriting rule. *)
633- let scope_rule : bool -> sig_state -> p_rule -> pre_rule loc = fun ur ss r ->
631+ (* * The status of rewrite rules. *)
632+ type rule_status =
633+ | Regular (* * Regular LPMT rewrite rule *)
634+ | Unif
635+ (* * Unification rule: rewrite a unification problem into another
636+ unification problem. *)
637+ | Meta
638+ (* * Meta rewrite rule: such rewrite rules are allowed to rewrite
639+ constant symbols *)
640+
641+ (* * [scope_rule rst ss r] turns a parser-level rewriting rule [r] into
642+ a pre-rewriting rule. Argument [rst] specifies the nature of the
643+ rewrite rulea unification rule if [rst] is [Unif], *)
644+ let scope_rule : rule_status -> sig_state -> p_rule -> pre_rule loc = fun rst ss r ->
634645 let (p_lhs, p_rhs) = r.elt in
635646 (* Compute the set of pattern variables on both sides. *)
636647 let (pvs_lhs, nl) = patt_vars p_lhs in
@@ -667,8 +678,10 @@ let scope_rule : bool -> sig_state -> p_rule -> pre_rule loc = fun ur ss r ->
667678 let (h, args) = get_args pr_lhs in
668679 match h with
669680 | Symb (s ) ->
670- if is_constant s then fatal p_lhs.pos " Constant LHS head symbol." ;
671- if s.sym_expo = Protec && ss.signature.sign_path <> s.sym_path then
681+ if rst <> Meta && is_constant s then
682+ fatal p_lhs.pos " Constant LHS head symbol." ;
683+ if rst <> Meta && s.sym_expo = Protec &&
684+ ss.signature.sign_path <> s.sym_path then
672685 fatal p_lhs.pos " Cannot define rules on foreign protected symbols." ;
673686 (s, args)
674687 | _ -> fatal p_lhs.pos " No head symbol in LHS."
@@ -685,10 +698,11 @@ let scope_rule : bool -> sig_state -> p_rule -> pre_rule loc = fun ur ss r ->
685698 let htbl_vars = Hashtbl. create (Hashtbl. length lhs_indices) in
686699 let fn k i = Hashtbl. add htbl_vars k pr_vars.(i) in
687700 Hashtbl. iter fn lhs_indices;
688- if ur then
689- M_URHS { m_urhs_data = htbl_vars ; m_urhs_vars_nb = Array. length pr_vars
701+ match rst with
702+ | Unif ->
703+ M_URHS { m_urhs_data = htbl_vars ; m_urhs_vars_nb = Array. length pr_vars
690704 ; m_urhs_xvars = [] }
691- else
705+ | Regular | Meta ->
692706 M_RHS { m_rhs_prv = is_private sym; m_rhs_data = htbl_vars;
693707 m_rhs_new_metas = new_problem() }
694708 in
@@ -702,7 +716,8 @@ let scope_rule : bool -> sig_state -> p_rule -> pre_rule loc = fun ur ss r ->
702716 in
703717 Array. init lhs_size fn
704718 in
705- if ur then (* Unification rule. *)
719+ match rst with
720+ | Unif ->
706721 (* We scope the RHS and retrieve variables not occurring in the LHS. *)
707722 let xvars =
708723 match mode with
@@ -721,12 +736,18 @@ let scope_rule : bool -> sig_state -> p_rule -> pre_rule loc = fun ur ss r ->
721736 (* We put everything together to build the pre-rule. *)
722737 { pr_sym = sym ; pr_lhs ; pr_vars ; pr_rhs ; pr_arities
723738 ; pr_names = lhs_names ; pr_xvars_nb }
724- else (* Rewrite rule. *)
739+ | Regular | Meta ->
725740 { pr_sym = sym ; pr_lhs ; pr_vars ; pr_rhs ; pr_arities
726741 ; pr_names = lhs_names ; pr_xvars_nb= 0 }
727742 in
728743 Pos. make r.pos prerule
729744
745+ let scope_unif_rule : sig_state -> p_rule -> pre_rule loc = scope_rule Unif
746+
747+ let scope_meta_rule : sig_state -> p_rule -> pre_rule loc = scope_rule Meta
748+
749+ let scope_rule : sig_state -> p_rule -> pre_rule loc = scope_rule Regular
750+
730751(* * [scope_pattern ss env t] turns a parser-level term [t] into an actual term
731752 that will correspond to selection pattern (rewrite tactic). *)
732753let scope_pattern : sig_state -> env -> p_term -> term = fun ss env t ->
0 commit comments