Skip to content

Commit 8d90e87

Browse files
author
gabrielhdt
committed
Allow to rewrite constants
1 parent 6b449a6 commit 8d90e87

File tree

5 files changed

+64
-23
lines changed

5 files changed

+64
-23
lines changed

src/handle/command.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ let handle_modifiers : p_modifier list -> prop * expo * match_strat =
136136
let handle_rule : sig_state -> p_rule -> sym = fun ss r ->
137137
Console.out 3 (Color.cya "%a") Pos.pp r.pos;
138138
Console.out 4 "%a" (Pretty.rule "rule") r;
139-
let pr = scope_rule false ss r in
139+
let pr = scope_rule ss r in
140140
let sym = pr.elt.pr_sym in
141141
if !(sym.sym_def) <> None then
142142
fatal pr.pos "No rewriting rule can be given on the defined symbol %a."
@@ -227,7 +227,7 @@ let get_proof_data : compiler -> sig_state -> p_command -> cmd_output =
227227
(add_notation ss sym n, None, None)
228228
| P_unif_rule(h) ->
229229
(* Approximately same processing as rules without SR checking. *)
230-
let pur = (scope_rule true ss h).elt in
230+
let pur = (scope_unif_rule ss h).elt in
231231
let urule = Scope.rule_of_pre_rule pur in
232232
Sign.add_rule ss.signature Unif_rule.equiv urule;
233233
Tree.update_dtree Unif_rule.equiv;

src/parsing/scope.ml

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -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). *)
732753
let scope_pattern : sig_state -> env -> p_term -> term = fun ss env t ->

src/parsing/scope.mli

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,17 @@ type pre_rule =
4848
(** [rule_of_pre_rule r] converts a pre-rewrite rule into a rewrite rule. *)
4949
val rule_of_pre_rule : pre_rule -> rule
5050

51-
(** [scope_rule ur ss r] turns a parser-level rewriting rule [r], or a
52-
unification rule if [ur] is true, into a pre-rewriting rule. *)
53-
val scope_rule : bool -> sig_state -> p_rule -> pre_rule loc
51+
(** [scope_rule ss r] turns a parser-level rewriting rule [r] into a
52+
pre-rewriting rule. *)
53+
val scope_rule : sig_state -> p_rule -> pre_rule loc
54+
55+
(** [scope_unif_rule ss r] turns a parser-level unification rule [r] into a
56+
pre-rewriting rule. *)
57+
val scope_unif_rule : sig_state -> p_rule -> pre_rule loc
58+
59+
(** [scope_meta_rule ss r] turns a parser-level meta rewriting rule [r]
60+
into a pre-rewriting rule. *)
61+
val scope_meta_rule : sig_state -> p_rule -> pre_rule loc
5462

5563
(** [scope_rw_patt ss env t] turns a parser-level rewrite tactic specification
5664
[s] into an actual rewrite specification (possibly containing variables of

tests/meta.ml

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,32 +36,44 @@ let or_true_true =
3636
(** Unit tests functions *)
3737

3838
let no_rewrite () =
39-
let no_rewrite =
40-
Tool.Meta.rewrite_with bool_sig [] or_true_true
41-
in
39+
let no_rewrite = Tool.Meta.rewrite_with bool_sig [] or_true_true in
4240
Alcotest.(check term) "same term" or_true_true no_rewrite
4341

4442
let simple_rewrite () =
4543
let lhs = Syntax.P.iden "bool_or" in
4644
let rhs = Syntax.P.iden "bool_and" in
4745
let Pos.{ elt = r; _ } =
48-
Scope.scope_rule true bool_sig_st (Pos.none (lhs, rhs))
46+
Scope.scope_meta_rule bool_sig_st (Pos.none (lhs, rhs))
4947
in
5048
let r = (r.pr_sym, Scope.rule_of_pre_rule r) in
51-
let rewritten =
52-
Tool.Meta.rewrite_with bool_sig [ r ] or_true_true
53-
in
49+
let rewritten = Tool.Meta.rewrite_with bool_sig [ r ] or_true_true in
5450
let and_true_true =
5551
Syntax.P.(appl_list (iden "bool_and") [ iden "true"; iden "true" ])
5652
|> scope_term bool_sig_st
5753
in
5854
Alcotest.(check term) "same term" and_true_true rewritten
5955

56+
(* Meta rewrite rules can rewrite symbols noted "constant". *)
57+
let rewrite_constant () =
58+
let lhs = Syntax.P.iden "true" in (* [true] is constant *)
59+
let rhs = Syntax.P.iden "false" in
60+
let Pos.{ elt = r; _ } =
61+
Scope.scope_meta_rule bool_sig_st (Pos.none (lhs, rhs))
62+
in
63+
let r = (r.pr_sym, Scope.rule_of_pre_rule r) in
64+
let or_false_false =
65+
Syntax.P.(appl_list (iden "bool_or") [ iden "false"; iden "false" ])
66+
|> scope_term bool_sig_st
67+
in
68+
let rewritten = Tool.Meta.rewrite_with bool_sig [ r ] or_true_true in
69+
Alcotest.check term "same term" or_false_false rewritten
70+
6071
let () =
6172
let open Alcotest in
6273
run "Meta"
6374
[ ( "standard"
6475
, [ ("no rewriting with signature's rules", `Quick, no_rewrite)
6576
; ("rewrite symbol", `Quick, simple_rewrite)
77+
; ("rewrite constant", `Quick, rewrite_constant)
6678
] )
6779
]

tests/rewriting.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ let sig_state, a = add_sym sig_state "A"
3232
let parse_rule s =
3333
let r = Parser.Lp.parse_string "rewrite_test rule" s |> Stream.next in
3434
let r = match r.elt with Syntax.P_rules [r] -> r | _ -> assert false in
35-
(Scope.scope_rule false sig_state r).elt |> Scope.rule_of_pre_rule
35+
(Scope.scope_rule sig_state r).elt |> Scope.rule_of_pre_rule
3636

3737
let arrow_matching () =
3838
(* Matching on a product. *)

0 commit comments

Comments
 (0)