123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297(*********************************************************************************)(* OCaml-RDF *)(* *)(* Copyright (C) 2012-2021 Institut National de Recherche en Informatique *)(* et en Automatique. All rights reserved. *)(* *)(* This program is free software; you can redistribute it and/or modify *)(* it under the terms of the GNU Lesser General Public License version *)(* 3 as published by the Free Software Foundation. *)(* *)(* This program is distributed in the hope that it will be useful, *)(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *)(* GNU General Public License for more details. *)(* *)(* You should have received a copy of the GNU General Public License *)(* along with this program; if not, write to the Free Software *)(* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA *)(* 02111-1307 USA *)(* *)(* Contact: Maxence.Guesdon@inria.fr *)(* *)(*********************************************************************************)(** *)openTerm;;moduleSMap=Types.SMap;;moduleTriples=functor(Map1:Map.S)->functor(Map2:Map.S)->functor(Set:Set.S)->structmoduleSet=SetmoduleMap=Map1typet=Set.tMap2.tMap1.tletempty=Map1.emptyletaddtxyz=letm=tryMap1.findxtwithNot_found->Map2.emptyinletset=trySet.addz(Map2.findym)withNot_found->Set.singletonzinletm=Map2.addysetminMap1.addxmtletremtxyz=letm=tryMap1.findxtwithNot_found->Map2.emptyintryletset=Set.removez(Map2.findym)inletm=Map2.addysetminMap1.addxmtwithNot_found->tletfindtxy=tryMap2.findy(Map1.findxt)withNot_found->Set.emptyletfind_listtxy=Set.elements(findtxy)letfind2_listtxz=letfysetacc=ifSet.memzsettheny::accelseaccintryletm=Map1.findxtinMap2.foldfm[]withNot_found->[]lettriples_yxysetacc=letfzxyzacc=(x,y,z)::accinSet.fold(fzxy)setacclettriples_xtxacc=tryMap2.fold(triples_yx)(Map1.findxt)accwithNot_found->acclettriples=letfxeltmapacc=Map2.fold(triples_yelt)mapaccinfunt->Map1.foldfxt[]letx_list=letpred_set=not(Set.is_emptyset)inletfxeltmapacc=ifMap2.existspredmapthenelt::accelseaccinfunt->Map1.foldfxt[]letcardinal=letf_map2_setacc=acc+Set.cardinalsetinletf_map_mapacc=Map2.foldf_map2mapaccinfunt->Map1.foldf_mapt0end;;moduleTriples_s_p=Triples(Term.TMap)(Iri.Map)(Term.TSet);;moduleTriples_p_o=Triples(Iri.Map)(Term.TMap)(Term.TSet);;moduleTriples_o_s=Triples(Term.TMap)(Term.TMap)(Iri.Set);;typet={g_name:Iri.t;(* graph name *)mutableg_set_sub:Triples_s_p.t;(* sub -> (pred -> obj set) *)mutableg_set_pred:Triples_p_o.t;(* pred -> (obj -> sub set) *)mutableg_set_obj:Triples_o_s.t;(* obj -> (sub -> pred set) *)mutableg_in_transaction:toption;(* Some t: t is the state before starting the transaction *)mutableg_ns:Iri.tSMap.t;}typeerror=stringexceptionErroroferror;;letstring_of_errors=s;;letopen_graph?(options=[])name={g_name=name;g_set_sub=Triples_s_p.empty;g_set_pred=Triples_p_o.empty;g_set_obj=Triples_o_s.empty;g_in_transaction=None;g_ns=SMap.empty;};;letadd_tripleg~sub~pred~obj=g.g_set_sub<-Triples_s_p.addg.g_set_subsubpredobj;g.g_set_pred<-Triples_p_o.addg.g_set_predpredobjsub;g.g_set_obj<-Triples_o_s.addg.g_set_objobjsubpred;;;letrem_tripleg~sub~pred~obj=g.g_set_sub<-Triples_s_p.remg.g_set_subsubpredobj;g.g_set_pred<-Triples_p_o.remg.g_set_predpredobjsub;g.g_set_obj<-Triples_o_s.remg.g_set_objobjsubpred;;;letsubjects_ofg~pred~obj=Triples_p_o.find_listg.g_set_predpredobj;;letpredicates_ofg~sub~obj=Triples_o_s.find_listg.g_set_objobjsub;;letobjects_ofg~sub~pred=Triples_s_p.find_listg.g_set_subsubpred;;letfind?sub?pred?objg=matchsub,pred,objwithNone,None,None->Triples_s_p.triplesg.g_set_sub|Somesub,None,None->Triples_s_p.triples_xg.g_set_subsub[]|None,Somepred,None->List.rev_map(fun(p,o,s)->(s,p,o))(Triples_p_o.triples_xg.g_set_predpred[])|None,None,Someobj->List.rev_map(fun(o,s,p)->(s,p,o))(Triples_o_s.triples_xg.g_set_objobj[])|Somesub,Somepred,None->List.map(funo->(sub,pred,o))(objects_ofg~sub~pred)|Somesub,None,Someobj->List.map(funp->(sub,p,obj))(predicates_ofg~sub~obj)|None,Somepred,Someobj->List.map(funs->(s,pred,obj))(subjects_ofg~pred~obj)|Somesub,Somepred,Someobj->letset=Triples_p_o.findg.g_set_predpredobjinifTriples_p_o.Set.memsubsetthen[sub,pred,obj]else[];;letexists?sub?pred?objg=matchfind?sub?pred?objgwith[]->false|_->true;;letsubjectsg=Triples_s_p.x_listg.g_set_sub;;letpredicatesg=Triples_p_o.x_listg.g_set_pred;;letobjectsg=Triples_o_s.x_listg.g_set_obj;;letfolderg=Someg.g_set_sub;;lettransaction_startg=letold={g_name=g.g_name;g_set_sub=g.g_set_sub;g_set_pred=g.g_set_pred;g_set_obj=g.g_set_obj;g_in_transaction=g.g_in_transaction;g_ns=g.g_ns;}ing.g_in_transaction<-Someold;;lettransaction_commitg=matchg.g_in_transactionwithNone->raise(Error"Not in a transaction.")|Someold->g.g_in_transaction<-old.g_in_transaction;;lettransaction_rollbackg=matchg.g_in_transactionwithNone->raise(Error"Not in a transaction.")|Someold->g.g_set_sub<-old.g_set_sub;g.g_set_pred<-old.g_set_pred;g.g_set_obj<-old.g_set_obj;g.g_in_transaction<-old.g_in_transaction;;letnew_blank_idg=letmax_int=Int32.to_int(Int32.divInt32.max_int(Int32.of_int2))inlets="genid"^(string_of_int(Triples_s_p.Map.cardinalg.g_set_sub))^"-"^(string_of_int(Random.intmax_int))inTerm.blank_id_of_strings;;letgraph_sizeg=Triples_s_p.cardinalg.g_set_sub;;moduleMem_BGP=structletto_iri(sub,pred,obj)=(sub,Term.Iripred,obj)typeterm=Term.termtypeg=tletterm_t=tletrdfterm_t=tletcompare_=Term.compareletsubjects=subjectsletobjects=objectsletfind?sub?pred?objg=matchpredwithNone->List.mapto_iri(find?sub?objg)|Some(Term.Iriiri)->List.mapto_iri(find?sub~pred:iri?objg)|_->[]endmoduleMem=structletname="mem"typeg=ttypeerror=stringexceptionError=Errorletstring_of_error=string_of_errorlet()=Printexc.register_printer(function|Errore->Some(string_of_errore)|_->None)letgraph_nameg=g.g_nameletgraph_sizeg=graph_sizegletopen_graph=open_graphletadd_triple=add_tripleletrem_triple=rem_tripleletadd_triple_tg(sub,pred,obj)=add_tripleg~sub~pred~objletrem_triple_tg(sub,pred,obj)=rem_tripleg~sub~pred~objletsubjects_of=subjects_ofletpredicates_of=predicates_ofletobjects_of=objects_ofletfind=findletexists=existsletexists_t(sub,pred,obj)g=exists~sub~pred~objgletsubjects=subjectsletpredicates=predicatesletobjects=objectsletfolder=folderlettransaction_start=transaction_startlettransaction_commit=transaction_commitlettransaction_rollback=transaction_rollbackletnew_blank_id=new_blank_idletnamespacesg=SMap.fold(funnameiriacc->(iri,name)::acc)g.g_ns[]letadd_namespacegiriname=g.g_ns<-SMap.addnameirig.g_nsletrem_namespacegname=g.g_ns<-SMap.removenameg.g_nsletset_namespacesgl=g.g_ns<-List.fold_left(funmap(iri,name)->SMap.addnameirimap)SMap.emptylmoduleBGP=Mem_BGPend;;Graph.add_storage(moduleMem:Graph.Storage);;