123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495(**************************************************************************)(* *)(* ACG development toolkit *)(* *)(* Copyright 2008-2021 INRIA *)(* *)(* More information on "http://acg.gforge.inria.fr/" *)(* License: CeCILL, see the LICENSE file or "http://www.cecill.info" *)(* Authors: see the AUTHORS file *)(* *)(* *)(* *)(* *)(* $Rev:: $: Revision of last commit *)(* $Author:: $: Author of last commit *)(* $Date:: $: Date of last commit *)(* *)(**************************************************************************)openUtilsLibopenTableopenLogic.LambdaopenLogic.Abstract_syntaxtypesig_entry=|Type_declarationofstring*int*Lambda.kind|Type_definitionofstring*int*Lambda.kind*Lambda.stype|Term_declarationofstring*int*Abstract_syntax.syntactic_behavior*Lambda.stype|Term_definitionofstring*int*Abstract_syntax.syntactic_behavior*Lambda.stype*Lambda.termmoduleLog=(valLogs.src_log(Logs.Src.create"ACGtkLib.signature"~doc:"logs ACGtkLib signature events"):Logs.LOG)moduleMake(Symbols:TABLEwithtypekey=String.t)(Id:TABLEwithtypekey=int)=structexceptionDuplicate_type_definitionexceptionDuplicate_term_definitionexceptionNot_foundexceptionNot_functional_type(* exception Not_yet_implemented *)typeentry=sig_entrytypet={name:string*Abstract_syntax.location;size:int;terms:entrySymbols.t;types:entrySymbols.t;precedence:(float*stringoption)Symbols.t;(* indicates the precedence and a link to the previous one *)max_pred:float*stringoption;(* indicates the greatest precedence and a link to the previous one *)ids:entryId.t;is_2nd_order:bool;extension_timestamp:float;definition_timestamp:float}typeterm=Lambda.termtypestype=Lambda.stypetypedata=|Typeofstype|Termof(term*stype)letfind_termsym{terms=syms;_}=(* TODO : Replace by an assert within IFDEFDEBUG *)matchSymbols.findsymsymswith|Term_declaration(x,id,_,const_type)whensym=x->Lambda.Constid,const_type|Term_declaration_->failwith"Bug in find_term"(* x should match the symbol *)|Term_definition(x,id,_,const_type,_)whensym=x->Lambda.DConstid,const_type|Term_definition_->failwith"Bug in find_term"(* x should match the symbol *)|_->failwith"Bug in find_term"(* x should return a Term, not a type *)|exceptionSymbols.Not_found->raiseNot_foundletid_to_string{ids=ids;_}i=matchId.findiidswith|Type_declaration(s,_,_)->Abstract_syntax.Default,s|Type_definition(s,_,_,_)->Abstract_syntax.Default,s|Term_declaration(s,_,behavior,_)->behavior,s|Term_definition(s,_,behavior,_,_)->behavior,slettype_to_stringtysg=Lambda.type_to_stringty(id_to_stringsg)letterm_to_stringtsg=Lambda.term_to_stringt(id_to_stringsg)lettype_to_formatted_stringfmttysg=Lambda.type_to_formatted_stringfmtty(id_to_stringsg)letterm_to_formatted_stringfmttsg=Lambda.term_to_formatted_stringfmtt(id_to_stringsg)letemptyn=lettimestamp=Unix.time()in{name=n;size=0;terms=Symbols.empty;types=Symbols.empty;ids=Id.empty;is_2nd_order=true;precedence=Symbols.empty;max_pred=0.,None;definition_timestamp=timestamp;extension_timestamp=timestamp}letname{name=n;_}=nletfind_atomic_types{types=syms;_}=(* TODO : Replace by an assert within IFDEFDEBUG *)matchSymbols.findssymswith|Type_declaration(x,id,_)whenx=s->Lambda.Atomid|Type_declaration_->failwith"Bug in find_atomic_type"(* x and s should match if something is returned *)|Type_definition(x,id,_,_)whenx=s->Lambda.DAtomid|Type_definition_->failwith"Bug in find_atomic_type"(* x and s should match if something is returned *)|_->failwith"Bug in find_atomic_type"(* A type, not a term should be returned *)|exceptionSymbols.Not_found->failwith"Bug in find_atomic_type"letfind_typessg=(* TODO : Replace by an assert within IFDEFDEBUG *)matchSymbols.findssg.typeswith|Type_declaration(x,id,_)whenx=s->Lambda.Atomid|Type_definition(x,id,_,_)whenx=s->Lambda.DAtomid|_->failwith"Bug in find_type"(* A type, not a term should be returned and x and s should match *)|exceptionSymbols.Not_found->raiseNot_found[@@warning"-32"]letrecconvert_typetysg=matchtywith|Abstract_syntax.Type_atom(s,_,_)->find_atomic_typessg|Abstract_syntax.Linear_arrow(ty1,ty2,_)->Lambda.LFun(convert_typety1sg,convert_typety2sg)|Abstract_syntax.Arrow(ty1,ty2,_)->Lambda.Fun(convert_typety1sg,convert_typety2sg)letabstract_on_dependent_typeslstsg=List.fold_right(funxacc->Lambda.Depend(convert_typexsg,acc))lstLambda.Typeletadd_sig_typete({size=s;types=syms;ids=ids;_}assg)=try(* First perform addition on the functional data structure *)letnew_symbols=Symbols.addtesymsin(* timestamps modified at add_entry function *){sgwithsize=s+1;types=new_symbols;ids=Id.addseids;}with|Symbols.Conflict->raiseDuplicate_type_definition|Id.Conflict->raiseDuplicate_type_definitionletadd_sig_termte({size=s;terms=syms;ids=ids;_}assg)=try(* First perform addition on the functional data structure *)letnew_symbols=Symbols.addtesymsin(* timestamps modified at add_entry function *){sgwithsize=s+1;terms=new_symbols;ids=Id.addseids}with|Symbols.Conflict->raiseDuplicate_term_definition|Id.Conflict->raiseDuplicate_term_definitionletrecexpand_typety({ids=ids;_}assg)=matchtywith|Lambda.Atom_->ty|Lambda.DAtomi->(matchId.findiidswith|Type_definition(_,_,_,ty1)->expand_typety1sg|_->failwith"Bug in expand type")|Lambda.LFun(ty1,ty2)->Lambda.LFun(expand_typety1sg,expand_typety2sg)|Lambda.Fun(ty1,ty2)->Lambda.Fun(expand_typety1sg,expand_typety2sg)|_->failwith"Not yet implemented"letrecexpand_termt({ids=ids;_}assg)=matchtwith|(Lambda.Var_|Lambda.LVar_|Lambda.Const_)->t|Lambda.DConsti->(matchId.findiidswith|Term_definition(_,_,_,_,u)->expand_termusg|_->failwith"Bug in expand term")|Lambda.Abs(x,u)->Lambda.Abs(x,expand_termusg)|Lambda.LAbs(x,u)->Lambda.LAbs(x,expand_termusg)|Lambda.App(u,v)->Lambda.App(expand_termusg,expand_termvsg)|_->failwith"Not yet implemented"letunfold_type_definitioni({ids=ids;_}assg)=matchId.findiidswith|Type_definition(_,_,_,ty1)->expand_typety1sg|_->failwith"Bug in unfold_type_definition"letunfold_term_definitioni({ids=ids;_}assg)=matchId.findiidswith|Term_definition(_,_,_,_,t)->expand_termtsg|_->failwith"Bug in unfold_term_definition"letget_type_of_const_idi({ids=ids;_}assg)=matchId.findiidswith|Term_declaration(_,_,_,ty)->expand_typetysg|Term_definition(_,_,_,ty,_)->expand_typetysg|_->failwith"Should be applied only on constants"|exceptionId.Not_found->failwith"Bug in get_type_of_const_id"letrecdecompose_functional_typety({ids=ids;_}assg)=matchtywith|Lambda.LFun(ty1,ty2)->ty1,ty2,Abstract_syntax.Linear|Lambda.Fun(ty1,ty2)->ty1,ty2,Abstract_syntax.Non_linear|Lambda.DAtomi->(matchId.findiidswith|Type_definition(_,_,_,ty1)->decompose_functional_typety1sg|_->failwith"Bug in decompose_functional_type")|_->raiseNot_functional_typeletget_binder_argument_functional_typex({terms=terms;_}assg)=letty=matchSymbols.findxtermswith|Term_declaration(_,_,_,ty)->ty|Term_definition(_,_,_,ty,_)->ty|_->failwith(Printf.sprintf"Bug: Request of the type of the non constant \"%s\""x)intryletty1,_,_=decompose_functional_typetysginlet_,_,lin=decompose_functional_typety1sginSomelinwith|Not_functional_type->None(* We assume here that [term] is well typed and in beta-normal form
and that types and terms definitions have been unfolded*)leteta_long_formtermstypesg=letexpanded_type=expand_typestypesginletexpanded_term=expand_termtermsginletres=Lambda.eta_long_formexpanded_termexpanded_type(funid->get_type_of_const_ididsg)inLog.debug(funm->m"term: %s:%s"(term_to_stringtermsg)(type_to_stringstypesg));Log.debug(funm->m"eta_long_form: %s:%s"(term_to_stringressg)(type_to_stringexpanded_typesg));resletunfoldtsg=Lambda.normalize(expand_termtsg)typetemp_t=t(* type temp_entry=entry *)moduleType_System=Type_system.Type_System.Make(structexceptionNot_foundtypet=temp_t(* type entry=temp_entry *)(* type stype=Lambda.stype *)letexpand_type=expand_typeletfind_term=find_termlettype_to_string=type_to_stringletterm_to_string=term_to_stringend)lettypecheck=Type_System.typecheckletstamp_declarationsg={sgwithextension_timestamp=Unix.time()}letstamp_definitionsg={sgwithdefinition_timestamp=Unix.time()}letadd_entrye({size=s;_}assg)=matchewith|Abstract_syntax.Type_decl(t,_,Abstract_syntax.Kk)->stamp_declaration(add_sig_typet(Type_declaration(t,s,abstract_on_dependent_typesksg))sg)|Abstract_syntax.Type_def(t,_,ty,Abstract_syntax.Kk)->stamp_definition(add_sig_typet(Type_definition(t,s,abstract_on_dependent_typesksg,convert_typetysg))sg)|Abstract_syntax.Term_decl(t,behavior,_,ty)->lett_type=convert_typetysginletsg_is_2nd_order=sg.is_2nd_order&&(Lambda.is_2nd_ordert_type(funi->unfold_type_definitionisg))instamp_declaration(add_sig_termt(Term_declaration(t,s,behavior,convert_typetysg)){sgwithis_2nd_order=sg_is_2nd_order})|Abstract_syntax.Term_def(t,behavior,_,term,ty)->lett_type=convert_typetysginlett_term=typechecktermt_typesginstamp_definition(add_sig_termt(Term_definition(t,s,behavior,t_type,t_term))sg)letis_types{types=syms;_}=matchSymbols.findssymswith|Type_declaration_->true|Type_definition_->true|_->false|exceptionSymbols.Not_found->falseletis_constants{terms=syms;_}=matchSymbols.findssymswith|Term_declaration(_,_,behavior,_)->true,Somebehavior|Term_definition(_,_,behavior,_,_)->true,Somebehavior|_->false,None|exceptionSymbols.Not_found->false,None(*
let precedence s {precedence;_} =
match Symbols.find s precedence with
| f,_ -> Some f
| exception Symbols.Not_found -> None
*)letnew_precedence?beforeidsg=matchbefore,sg.max_predwith|None,(f,None)->letp=f+.1.inp,{sgwithmax_pred=p,Someid;precedence=Symbols.addid(p,None)sg.precedence}|None,(f,(Some_asmax))->letp=f+.1.inp,{sgwithmax_pred=p,Someid;precedence=Symbols.addid(p,max)sg.precedence}|Some_,(f,None)->(* Strange to give an upper bound when there is no max. Behaves
like introducing the first element *)letp=f+.1.inp,{sgwithmax_pred=p,Someid;precedence=Symbols.addid(p,None)sg.precedence}|Someupper_bound,_->(matchSymbols.findupper_boundsg.precedencewith|f_up,None->letf_down=0.inletp=(f_up+.f_down)/.2.inletnew_pred=Symbols.add~overwrite:trueupper_bound(f_up,Someid)(Symbols.addid(p,None)sg.precedence)inp,{sgwithprecedence=new_pred}|f_up,Somelower_bound->letf_down,_=Symbols.findlower_boundsg.precedenceinletp=(f_up+.f_down)/.2.inletnew_pred=Symbols.addupper_bound(f_up,Someid)(Symbols.addid(p,Somelower_bound)sg.precedence)inp,{sgwithprecedence=new_pred}|exceptionNot_found->failwith"Bug: Shouldn't happen")letadd_warnings_sg=sgletget_warnings_=[][@@warning"-32"]letraw_to_stringt=Lambda.raw_to_stringt[@@warning"-32"]letbehavior_to_string=function|Abstract_syntax.Default->""|Abstract_syntax.Prefix->"prefix "|Abstract_syntax.Infix_->"infix "|Abstract_syntax.Binder->"binder "letentry_to_stringfdecl=letbuff=Buffer.create10inlettemp_str_formatter=Format.formatter_of_bufferbuffinlet()=Utils.fterm_set_sizetemp_str_formatterinlet()=matchdeclwith|Type_declaration(s,_,k)->let()=Utils.fformattemp_str_formatter"@[<hov 4>%s :@ @[%s"s(Lambda.kind_to_stringkf)inUtils.fformattemp_str_formatter"@];@]"|Type_definition(s,_,k,ty)->let()=Utils.fformattemp_str_formatter"@[<hov 4>%s =@ @["sinlet()=Lambda.type_to_formatted_stringtemp_str_formattertyfinlet()=Utils.fformattemp_str_formatter" :@ @["inlet()=Lambda.kind_to_formatted_stringtemp_str_formatterkfinUtils.fformattemp_str_formatter"@];@]@]"|Term_declaration(s,_,behavior,ty)->let()=Utils.fformattemp_str_formatter"@[<hov 4>%s%s :@ @["(behavior_to_stringbehavior)sinlet()=Lambda.type_to_formatted_stringtemp_str_formattertyfinUtils.fformattemp_str_formatter"@];@]"|Term_definition(s,_,behavior,ty,t)->let()=Utils.fformattemp_str_formatter"@[<hov 4>%s%s =@ @["(behavior_to_stringbehavior)sinlet()=Lambda.term_to_formatted_stringtemp_str_formattertfinlet()=Utils.fformattemp_str_formatter" :@ @["inlet()=Lambda.type_to_formatted_stringtemp_str_formattertyfinUtils.fformattemp_str_formatter"@];@]@]"inlet()=Format.pp_print_flushtemp_str_formatter()inBuffer.contentsbuffletentry_to_formatted_stringfdecl=let()=matchdeclwith|Type_declaration(s,_,k)->let()=Utils.sformat"@[<hov 4>%s :@ @["sinlet()=Lambda.kind_to_formatted_stringFormat.str_formatterkfinUtils.sformat"@];@]"|Type_definition(s,_,k,ty)->let()=Utils.sformat"@[<hov 4>%s =@ @["sinlet()=Lambda.type_to_formatted_stringFormat.str_formattertyfinlet()=Utils.sformat" :@ @["inlet()=Lambda.kind_to_formatted_stringFormat.str_formatterkfinUtils.sformat"@];@]@]"|Term_declaration(s,_,behavior,ty)->let()=Utils.sformat"@[<hov 4>%s%s :@ @["(behavior_to_stringbehavior)sinlet()=Lambda.type_to_formatted_stringFormat.str_formattertyfinUtils.sformat"@];@]"|Term_definition(s,_,behavior,ty,t)->let()=Utils.sformat"@[<hov 4>%s%s =@ @["(behavior_to_stringbehavior)sinlet()=Lambda.term_to_formatted_stringFormat.str_formattertfinlet()=Utils.sformat" :@ @["inlet()=Lambda.type_to_formatted_stringFormat.str_formattertyfinUtils.sformat"@];@]@]"in()[@@warning"-32"]letto_string({name=n;ids=ids;_}assg)=Printf.sprintf"signature %s = \n%send\n"(fstn)(fst(Id.fold(fun_e(acc,b)->matchbwith|true->Printf.sprintf"%s%s\n"acc(entry_to_string(id_to_stringsg)e),true|false->Printf.sprintf"%s\n"(entry_to_string(id_to_stringsg)e),true)("",false)ids))letconvert_termttysg=lett_type=convert_typetysginlett=typechecktt_typesgint,t_typelettype_of_constantx{terms=syms;_}=matchSymbols.findxsymswith|Term_declaration(s,_,_,ty)whenx=s->ty|Term_definition(s,_,_,ty,_)whenx=s->ty|_->failwith"Bug in type_of_constant"|exceptionSymbols.Not_found->failwith"Bug in type_of_constant"letfoldfa{ids=ids;_}=Id.fold(fun_attacc->fattacc)aidsletis_declarede_=matchewith|Type_declaration(s,_,_)->Somes|Term_declaration(s,_,_,_)->Somes|_->Noneletis_2nd_order{is_2nd_order;_}=is_2nd_orderletentry_to_datae=matchewith|Type_declaration(_,id,_)->Type(Lambda.Atomid)|Type_definition(_,_,_,stype)->Typestype|Term_declaration(_,id,_,stype)->Term(Lambda.Constid,stype)|Term_definition(_,_,_,stype,term)->Term(term,stype)endmoduleTable=Table.Make_table(structletb=10end)(*module Table =
struct
module IntMap = Map.Make(struct type t=int let compare i j = i-j end)
type 'a t = 'a IntMap.t
type key = int
exception Conflict
let empty = IntMap.empty
let add ?(overwrite=false) k v t =
try
let _ = IntMap.find k t in
if overwrite then IntMap.add k v t else raise Conflict
with
| Not_found -> IntMap.add k v t
exception Not_found
let find k t =
try
IntMap.find k t
with
| Not_found -> raise Not_found
let fold f acc t = IntMap.fold f t acc
end
*)moduleData_Signature=Make(Tries.Tries)(Table)