Source file hrs.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
(** This module provides a function to translate a signature to the HRS format
used in the confluence competition.
@see <http://project-coco.uibk.ac.at/problems/hrs.php>. *)
open! Lplib
open Lplib.Base
open Lplib.Extra
open Timed
open Core
open Term
open Print
(** [print_sym ppf s] outputs the fully qualified name of [s] to [ppf]. The
name is prefixed by ["c_"], and modules are separated with ["_"], not
["."]. *)
let print_sym : sym pp = fun ppf s ->
let print_path = List.pp Format.pp_print_string "_" in
out ppf "c_%a_%s" print_path s.sym_path s.sym_name
(** [print_patt ppf p] outputs TPDB format corresponding to the pattern [p],
to [ppf]. *)
let print_term : bool -> term pp = fun lhs ->
let rec pp ppf t =
match unfold t with
| Meta(_,_) -> assert false
| Plac _ -> assert false
| TRef(_) -> assert false
| TEnv(_,_) -> assert false
| Wild -> assert false
| Kind -> assert false
| Vari(x) -> out ppf "%a" pp_var x
| Type -> out ppf "TYPE"
| Symb(s) -> print_sym ppf s
| Patt(i,n,ts) ->
if ts = [||] then out ppf "$%s" n else
pp ppf (Array.fold_left (fun t u -> mk_Appl(t,u))
(mk_Patt(i,n,[||])) ts)
| Appl(t,u) -> out ppf "app(%a,%a)" pp t pp u
| Abst(a,t) ->
let (x, t) = Bindlib.unbind t in
if lhs then out ppf "lam(m_typ,\\%a.%a)" pp_var x pp t
else out ppf "lam(%a,\\%a.%a)" pp a pp_var x pp t
| Prod(a,b) ->
let (x, b) = Bindlib.unbind b in
out ppf "pi(%a,\\%a.%a)" pp a pp_var x pp b
| LLet(_,t,u) -> pp ppf (Bindlib.subst u t)
in pp
(** [print_rule ppf lhs rhs] outputs the rule declaration [lhs]->[rhs]
to [ppf] *)
let print_rule : Format.formatter -> term -> term -> unit =
fun ppf lhs rhs ->
let add_var_names : StrSet.t -> term -> StrSet.t = fun ns t ->
let names = Stdlib.ref ns in
let fn t =
match t with
| Patt(_,n,_) -> Stdlib.(names := StrSet.add ("$" ^ n) !names)
| Abst(_,b) ->
let (x, _) = Bindlib.unbind b in
Stdlib.(names := StrSet.add (Bindlib.name_of x) !names)
| _ -> ()
in
LibTerm.iter fn t;
Stdlib.(!names)
in
let names = add_var_names StrSet.empty lhs in
let names = add_var_names names rhs in
if not (StrSet.is_empty names) then
begin
let print_name ppf x = out ppf " %s : term\n" x in
let pp_strset ppf = StrSet.iter (print_name ppf) in
out ppf "(VAR\n%a)\n" pp_strset names
end;
out ppf "(RULES %a" (print_term true) lhs;
out ppf "\n -> %a)\n" (print_term false) rhs
(** [print_sym_rule ppf s r] outputs the rule declaration corresponding [r]
(on the symbol [s]), to [ppf]. *)
let print_sym_rule : Format.formatter -> sym -> rule -> unit = fun ppf s r ->
let lhs = add_args (mk_Symb s) r.lhs in
let rhs = LibTerm.term_of_rhs r in
print_rule ppf lhs rhs
(** [to_HRS ppf sign] outputs a TPDB representation of the rewriting system of
the signature [sign] to [ppf]. *)
let to_HRS : Format.formatter -> Sign.t -> unit = fun ppf sign ->
let deps = Sign.dependencies sign in
let iter_symbols : (sym -> unit) -> unit = fun fn ->
let not_on_ghosts _ s = if not (Unif_rule.is_ghost s) then fn s in
let iter_symbols sign =
StrMap.iter not_on_ghosts Sign.(!(sign.sign_symbols))
in
List.iter (fun (_, sign) -> iter_symbols sign) deps
in
let prelude =
[ "(FUN"
; " lam : term -> (term -> term) -> term"
; " app : term -> term -> term"
; " pi : term -> (term -> term) -> term"
; " type : term"
; ")"
; ""
; "(COMMENT beta-reduction)"
; "(VAR"
; " v_x : term"
; " m_typ : term"
; " m_B : term"
; " m_F : term -> term"
; ")"
; "(RULES app(lam(m_typ,\\v_x. m_F v_x), m_B) -> m_F(m_B))"
; ""
; "(COMMENT TYPE keyword)"
; "(FUN TYPE : term)" ]
in
List.iter (out ppf "%s\n") prelude;
out ppf "\n(COMMENT symbols)\n";
let print_symbol s = out ppf "(FUN %a : term)\n" print_sym s in
iter_symbols print_symbol;
out ppf "\n(COMMENT rewriting rules)\n";
let print_rules s =
match !(s.sym_def) with
| Some(d) -> print_rule ppf (mk_Symb s) d
| None -> List.iter (print_sym_rule ppf s) !(s.sym_rules)
in
iter_symbols print_rules