123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310(** This module provides a function to translate a signature to the XTC format
used in the termination competition.
@see <http://cl2-informatik.uibk.ac.at/mercurial.cgi/TPDB/file/tip/xml/xtc.xsd>
*)open!LplibopenLplib.BaseopenLplib.ExtraopenTimedopenCoreopenTermopenPrint(** [print_sym ppf s] outputs the fully qualified name of [s] to
[ppf]. Modules are separated with ["."]. *)letprint_sym:sympp=funppfs->outppf"%a.%a"pp_paths.sym_pathpp_uids.sym_nametypesymb_status=Object_level|Basic_type|Type_cstr(** [status s] returns [Type_cstr] if [s] has a type of the form
T1 -> ... -> Tn -> [TYPE] with n > 0, [Basic_type] if [s] has type [TYPE]
and [Object_level] otherwise. *)letstatus:sym->symb_status=funs->(* the argument [b] of [is_arrow_kind] is a boolean saying if we have
already gone under a product *)letrecis_arrow_kind:Term.term->bool->symb_status=funtb->matchtwith|Prod(_,b)->is_arrow_kind(snd(Bindlib.unbindb))true|Type->ifbthenType_cstrelseBasic_type|_->Object_levelinis_arrow_kind!(s.sym_type)false(** [print_term ppf p] outputs XTC format corresponding to the term [t], to
[ppf]. *)letrecprint_term:int->string->termpp=funisppft->matchunfoldtwith(* Forbidden cases. *)|Meta(_,_)->assertfalse|TRef(_)->assertfalse|TEnv(_,_)->assertfalse|Wild->assertfalse|Kind->assertfalse(* [TYPE] and products are necessarily at type level *)|Type->assertfalse|Prod(_,_)->assertfalse(* Printing of atoms. *)|Vari(x)->outppf"<var>v_%a</var>@."pp_varx|Symb(s)->outppf"<funapp>@.<name>%a</name>@.</funapp>@."print_syms|Patt(j,n,ts)->ifts=[||]thenoutppf"<var>%s_%i_%s</var>@."sinelseprint_termisppf(Array.fold_left(funtu->mk_Appl(t,u))(mk_Patt(j,n,[||]))ts)|Appl(t,u)->outppf"<application>@.%a%a</application>@."(print_termis)t(print_termis)u|Abst(a,t)->let(x,t)=Bindlib.unbindtinoutppf"<lambda>@.<var>v_%a</var>@.<type>%a<type>@.%a</lambda>@."pp_varx(print_typeis)a(print_termis)t|LLet(_,t,u)->print_termisppf(Bindlib.substut)andprint_type:int->string->termpp=funisppft->matchunfoldtwith(* Forbidden cases. *)|Meta(_,_)->assertfalse|TRef(_)->assertfalse|TEnv(_,_)->assertfalse|Wild->assertfalse|Kind->assertfalse(* Variables are necessarily at object level *)|Vari(_)->assertfalse|Patt(_,_,_)->assertfalse(* Printing of atoms. *)|Type->outppf"<TYPE/>@."|Symb(s)->outppf"<basic>%a</basic>@."print_syms|Appl(t,u)->outppf"<application>@.%a%a</application>@."(print_typeis)t(print_termis)u|Abst(a,t)->let(x,t)=Bindlib.unbindtinoutppf"<lambda>@.<var>v_%a</var>@.<type>%a<type>@.%a</lambda>@."pp_varx(print_typeis)a(print_typeis)t|Prod(a,b)->ifBindlib.binder_constantbthenoutppf"<arrow>@.<type>@.%a</type>@.<type>@.%a</type>@.</arrow>@."(print_typeis)a(print_typeis)(snd(Bindlib.unbindb))elselet(x,b)=Bindlib.unbindbinoutppf"<arrow>@.<var>v_%a</var>@."pp_varx;outppf"<type>@.%a</type>@.<type>@.%a</type>@.</arrow>"(print_typeis)a(print_typeis)b|LLet(_,t,u)->print_typeisppf(Bindlib.substut)(** [print_rule ppf s r] outputs the rule declaration corresponding [r] (on
the symbol [s]), to [ppf]. *)letprint_rule:Format.formatter->int->sym->rule->unit=funppfisr->(* Print the rewriting rule. *)letlhs=add_args(mk_Symbs)r.lhsinoutppf"<rule>@.<lhs>@.%a</lhs>@."(print_termis.sym_name)lhs;letrhs=LibTerm.term_of_rhsrinoutppf"<rhs>@.%a</rhs>@.</rule>@."(print_termis.sym_name)rhs(** [print_tl_rule] is identical to [print_rule] but for type-level rule *)letprint_tl_rule:Format.formatter->int->sym->rule->unit=funppfisr->(* Print the type level rewriting rule. *)letlhs=add_args(mk_Symbs)r.lhsinoutppf"<typeLevelRule>@.<TLlhs>@.%a</TLlhs>@."(print_typeis.sym_name)lhs;letrhs=LibTerm.term_of_rhsrinoutppf"<TLrhs>@.%a</TLrhs>@.</typeLevelRule>@."(print_typeis.sym_name)rhs(** [get_vars s r] returns the list of variables used in the rule [r],
in the form of a pair containing the name of the variable and its type,
inferred by the solver. *)letget_vars:sym->rule->(string*Term.term)list=funsr->letrule_ctx:tvaroptionarray=Array.make(Array.lengthr.vars)Noneinletvar_list:tvarlistref=ref[]inletrecsubst_pattvt=matchtwith|Type|Kind|TEnv(_,_)|Meta(_,_)|TRef_|Wild|Prod(_,_)|LLet(_)(* No let in LHS *)|Vari_->assertfalse|Symb(_)->t|Abst(t1,b)->let(x,t2)=Bindlib.unbindbinmk_Abst(subst_pattvt1,Bindlib.unbox(Bindlib.bind_varx(lift(subst_pattvt2))))|Appl(t1,t2)->mk_Appl(subst_pattvt1,subst_pattvt2)|Patt(None,x,a)->letv_i=new_tvarxinvar_list:=v_i::!var_list;Array.fold_left(funacct->mk_Appl(acc,t))(mk_Variv_i)a|Patt(Some(i),x,a)->ifv.(i)=Nonethen(letv_i=new_tvarxinvar_list:=v_i::!var_list;v.(i)<-Some(v_i));letv_i=matchv.(i)with|Some(vi)->vi|None->assertfalseinArray.fold_left(funacct->mk_Appl(acc,t))(mk_Variv_i)ainletlhs=List.fold_left(funth->mk_Appl(t,subst_pattrule_ctx(unfoldh)))(mk_Symbs)r.lhsinletctx=letp=new_problem()inletflx=(x,(mk_Meta(LibMeta.freshpmk_Type0,[||])),None)::linList.fold_leftf[]!var_listinletp=new_problem()inmatchInfer.infer_noexnpctxlhswith|None->assertfalse|Some_->letcs=List.rev_map(fun(_,t,u)->(t,u))!p.to_solveinletctx=List.map(fun(x,a,_)->(x,a))ctxinList.map(fun(v,ty)->Bindlib.name_ofv,List.assoctycs)ctx(** [to_XTC ppf sign] outputs a XTC representation of the rewriting system of
the signature [sign] to [ppf]. *)letto_XTC:Format.formatter->Sign.t->unit=funppfsign->(* Get all the dependencies (every needed symbols and rewriting rules). *)letdeps=Sign.dependenciessignin(* Function to iterate over every symbols. *)letiter_symbols:(sym->unit)->unit=funfn->(* Iterate on all symbols of a signature, excluding ghost symbols. *)letiter_symbolssign=letnot_on_ghosts_(s,_)=ifnot(Unif_rule.is_ghosts)thenfnsinStrMap.iternot_on_ghostsSign.(!(sign.sign_symbols))inList.iter(fun(_,sign)->iter_symbolssign)depsin(* Print the prelude and the postlude. *)letprelude=["<?xml version=\"1.0\" encoding=\"UTF-8\"?>";"<?xml-stylesheet href=\"xtc2tpdb.xsl\" type=\"text/xsl\"?>";"<problem xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"";"type=\"termination\"";"xsi:noNamespaceSchemaLocation=\"http://dev.aspsimon.org/xtc.xsd\">";"<trs>"]inletpostlude=["</trs>";"<strategy>FULL</strategy>";"<metainformation>";"<originalfilename>Produced from a Dedukti file</originalfilename>";"</metainformation>";"</problem>"]in(* Print the object level rewrite rules. *)letprint_object_rules:sym->unit=funs->ifstatuss=Object_levelthenmatch!(s.sym_def)with|Some(d)->outppf"<rule>@.<lhs>@.<funapp>@.<name>%a</name>@.</funapp>@.</lhs>@."print_syms;outppf"<rhs>@.%a</rhs>@.</rule>@."(print_term0s.sym_name)d|None->letc=ref0inList.iter(funx->incrc;print_ruleppf!csx)!(s.sym_rules)in(* Print the type level rewrite rules. *)letprint_type_rules:sym->unit=funs->ifstatuss!=Object_levelthenmatch!(s.sym_def)with|Some(d)->outppf"<rule>@.<lhs>@.<funapp>@.<name>%a</name>@.</funapp>@.</lhs>@."print_syms;outppf"<rhs>@.%a</rhs>@.</rule>@."(print_term0s.sym_name)d|None->letc=ref0inList.iter(incrc;print_tl_ruleppf!cs)!(s.sym_rules)in(* Print the variable declarations *)letprint_vars:sym->unit=funs->letc=ref0inList.iter(funr->incrc;List.iter(fun(x,ty)->outppf"<varDeclaration>@.<var>%s_%i_%s</var>@."s.sym_name!cx;outppf"<type>@.%a</type>@.</varDeclaration>@."(print_type!cs.sym_name)ty)(get_varssr))!(s.sym_rules)in(* Print the symbol declarations at object level. *)letprint_symbol:sym->unit=funs->ifstatuss=Object_levelthen(outppf"<funcDeclaration>@.<name>%a</name>@."print_syms;outppf"<typeDeclaration>@.<type>@.%a</type>@."(print_type0s.sym_name)!(s.sym_type);outppf"</typeDeclaration>@.</funcDeclaration>@.")in(* Print the type constructor declarations. *)letprint_type_cstr:sym->unit=funs->(* We don't declare type constant which do not take arguments for
compatibility issue with simply-typed higher order category of the
competition. *)ifstatuss=Type_cstrthen(outppf"<typeConstructorDeclaration>@.<name>%a</name>@."print_syms;outppf"<typeDeclaration>@.<type>@.%a</type>@."(print_type0s.sym_name)!(s.sym_type);outppf"</typeDeclaration>@.</typeConstructorDeclaration>@.")inList.iter(outppf"%s@.")prelude;outppf"<rules>@.";iter_symbolsprint_object_rules;outppf"</rules>@.";lettype_rule_presence=reffalseiniter_symbols(funs->ifstatuss!=Object_level&&!(s.sym_def)!=None&&!(s.sym_rules)!=[]thentype_rule_presence:=true);if!type_rule_presencethen(outppf"<typeLevelRules>@.";iter_symbolsprint_type_rules;outppf"</typeLevelRules>@.");outppf"<higherOrderSignature>@.";outppf"<variableTypeInfo>@.";iter_symbolsprint_vars;outppf"</variableTypeInfo>@.";outppf"<functionSymbolTypeInfo>@.";iter_symbolsprint_symbol;outppf"</functionSymbolTypeInfo>@.";lettype_cstr_presence=reffalseiniter_symbols(funs->ifstatuss=Type_cstrthentype_cstr_presence:=true);if!type_cstr_presencethen(outppf"<typeConstructorTypeInfo>@.";iter_symbolsprint_type_cstr;outppf"</typeConstructorTypeInfo>@.");outppf"</higherOrderSignature>@.";List.iter(outppf"%s@.")postlude