Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file hrs.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179(** 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>.
- Lambdapi terms are translated to the following HRS term algebra with a
unique type t:
A : t -> t -> t // for application
L : t -> (t -> t) -> t // for λ
B : t -> t -> (t -> t) -> t // for let
P : t -> (t -> t) -> t // for Π
Function symbols and variables are translated as symbols of type t.
Pattern variables of arity n are translated as variables of type t -> ... -> t
with n times ->.
- In the hrs format, variable names must be distinct from function symbol
names. So bound variables are translated into positive integers and pattern
variables are prefixed by ["$"].
- There is no clash between function symbol names and A, B, L, P because
function symbol names are fully qualified.
- Function symbol names are fully qualified but ["."] is replaced by ["_"]
because ["."] cannot be used in identifiers (["."] is used in lambda
abstractions).
- Two occurrences of the same pattern variable name may have two different
arities (in two different rules). So pattern variable names are prefixed by
the rule number.
TO DO:
- HRS does not accept unicode characters.
- Optim: output only the symbols used in the rules. *)openLplibopenBaseopenExtraopenCoreopenTerm(** [syms] maps every symbol to a name. *)letsyms=refSymMap.empty(** [bvars] is the set of abstracted variables. *)letbvars=refIntSet.empty(** [nb_rules] is the number of rewrite rules. *)letnb_rules=ref0(** [pvars] map every pattern variable name to its arity. *)moduleV=structtypet=int*intletcompare=lexInt.compareInt.compareendmoduleVMap=Map.Make(V)letpvars=refVMap.empty(** [sym_name s] translates the symbol name of [s]. *)letsym_name:sympp=funppfs->outppf"%a_%s"(List.ppstring"_")s.sym_paths.sym_name(** [add_sym] declares a Lambdapi symbol. *)letadd_sym:sym->unit=funs->syms:=SymMap.adds(Format.asprintf"%a"sym_names)!syms(** [sym ppf s] translates the Lambdapi symbol [s]. *)letsym:sympp=funppfs->stringppf(SymMap.finds!syms)(** [add_bvar v] declares an abstracted Lambdapi variable. *)letadd_bvar:tvar->unit=funv->bvars:=IntSet.add(Bindlib.uid_ofv)!bvars(** [bvar v] translates the Lambdapi variable [v]. *)letbvar:tvarpp=funppfv->intppf(Bindlib.uid_ofv)(** [pvar i] translates the pattern variable index [i]. *)letpvar:intpp=funppfi->outppf"$%d_%d"!nb_rulesi(** [add_pvar i k] declares a pvar of index [i] and arity [k]. *)letadd_pvar:int->int->unit=funik->pvars:=VMap.add(!nb_rules,i)k!pvars(** [term ppf t] translates the term [t]. *)letrecterm:termpp=funppft->matchunfoldtwith|Meta_->assertfalse|Plac_->assertfalse|TRef_->assertfalse|TEnv_->assertfalse|Wild->assertfalse|Kind->assertfalse|Type->assertfalse|Variv->bvarppfv|Symbs->add_syms;symppfs|Patt(None,_,_)->assertfalse|Patt(Somei,_,[||])->add_pvari0;pvarppfi|Patt(Somei,_,ts)->letk=Array.lengthtsinadd_pvarik;letargsppfts=fori=1tok-1dooutppf",%a"termts.(i)doneinoutppf"%a(%a%a)"pvaritermts.(0)argsts|Appl(t,u)->outppf"A(%a,%a)"termttermu|Abst(a,b)->letx,b=Bindlib.unbindbinadd_bvarx;outppf"L(%a,\\%a.%a)"termabvarxtermb|Prod(a,b)->letx,b=Bindlib.unbindbinadd_bvarx;outppf"P(%a,\\%a.%a)"termabvarxtermb|LLet(a,t,b)->letx,b=Bindlib.unbindbinadd_bvarx;outppf"B(%a,%a,\\%a.%a)"termatermtbvarxtermb(** [rule ppf r] translates the pair of terms [r] as a rule. *)letrule:(term*term)pp=funppf(l,r)->outppf",\n%a -> %a"termltermr(** [sym_rule ppf s r] increases the number of rules and translates the
sym_rule [r]. *)letsym_rule:sym->rulepp=funsppfr->incrnb_rules;letsr=s,rinruleppf(lhssr,rhssr)(** Translate the rules of symbol [s]. *)letrules_of_sym:sympp=funppfs->matchTimed.(!(s.sym_def))with|Somed->ruleppf(mk_Symbs,d)|None->List.iter(sym_rulesppf)Timed.(!(s.sym_rules))(** Translate the rules of a dependency except if it is a ghost signature. *)letrules_of_sign:Sign.tpp=funppfsign->ifsign!=Ghost.signthenStrMap.iter(fun_->rules_of_symppf)Timed.(!(sign.sign_symbols))(** [sign ppf s] translates the Lambdapi signature [s]. *)letsign:Sign.tpp=funppfsign->(* First, generate the rules in a buffer, because it generates data
necessary for the other sections. *)letbuf_rules=Buffer.create1000inletppf_rules=Format.formatter_of_bufferbuf_rulesinSign.iterate(rules_of_signppf_rules)sign;Format.pp_print_flushppf_rules();(* Function for printing the types of function symbols. *)letpp_syms:stringSymMap.tpp=funppfsyms->letsym_decl:stringpp=funppfn->outppf"\n%s : t"ninletsym_decl_n=sym_declppfninSymMap.itersym_declsymsin(* Function for printing the types of pattern variables. *)letpp_pvars=funppfpvars->lettyp:intpp=funppfk->for_i=1tokdostringppf"t -> "done;outppf"t"inletpvar_decl(n,i)k=outppf"\n$%d_%d : %a"nitypkinVMap.iterpvar_declpvarsin(* Function for printing the types of abstracted variables. *)letpp_bvars:IntSet.tpp=funppfbvars->letbvar_decl:intpp=funppfn->outppf"\n%d : t"ninIntSet.iter(bvar_declppf)bvarsin(* Finally, generate the whole hrs file. Note that the variables $x, $y and
$z used in the rules for beta and let cannot clash with user-defined
pattern variables which are integers. *)outppf"\
(FUN
A : t -> t -> t
L : t -> (t -> t) -> t
P : t -> (t -> t) -> t
B : t -> t -> (t -> t) -> t%a
)
(VAR
$x : t
$y : t -> t
$z : t%a%a
)
(RULES
A(L($x,$y),$z) -> $y($z),
B($x,$z,$y) -> $y($z)%s
)\n"pp_syms!symspp_pvars!pvarspp_bvars!bvars(Buffer.contentsbuf_rules)