1:- module(obo_util,
    2          [gen_obo/2,
    3           gen_stanza/3,
    4           gen_header/3,
    5           entity_def/3,
    6           entity_obotype/2,
    7           entity_xref_prefix/3]).    8
    9:- use_module(library(obo_metadata/oio)).   10
   11:- use_module(library(semweb/rdf11)).   12:- use_module(library(semweb/rdfs)).   13:- use_module(library(sparqlprog/owl_util)).   14:- use_module(library(sparqlprog/emulate_builtins)).   15
   16:- rdf_register_ns(oio,'http://www.geneontology.org/formats/oboInOwl#').   17:- rdf_register_ns(def,'http://purl.obolibrary.org/obo/IAO_0000115').   18
   19entity_obotype(E,T) :- entity_obotype(E,T,_).
   20entity_obotype(E,'Term',G) :- rdf(E,rdf:type,owl:'Class',G), rdf_is_iri(E).
   21entity_obotype(E,'Typedef',G) :- rdf(E,rdf:type,owl:'ObjectProperty',G).
   22
   23ensure_curie_wrap(U,X) :-
   24        ensure_curie(U,X1),
   25        (   atom_concat('http://purl.obolibrary.org/obo/',Frag,X1),
   26            concat_atom([Pre,Post],'_',Frag)
   27        ->  concat_atom([Pre,Post],':',X)
   28        ;   X=X1).
   29
   30
   31        
   32ensure_id(U,Id) :-
   33        ensure_curie_wrap(U,X),
   34        (   atom_concat(Id,':',X)
   35        ->  true
   36        ;   Id=X).
 entity_xref_prefix(?Cls:atm, ?X:str, ?Pre:str)
true if Cls has X as an xref, and X has prefix Pre
   41entity_xref_prefix(C,X,P) :-
   42        has_dbxref(C,X),
   43        curie_prefix(X,P).
 entity_xref_src(?Cls:atm, ?X:str, ?S:str)
true if Cls has X as an xref, and axiom annotated with S
   48entity_xref_src(C,X,S) :-
   49        entity_xref_src(C,X,_,S).
   50entity_xref_src(C,X,A,S) :-
   51        has_dbxref_axiom(C,X,A),
   52        rdf(A,oio:source,S).
   53
   54entity_xref_prefix_srcont(C,X,P,S) :-
   55        entity_xref_prefix(C,X,P),
   56        entity_xref_src(C,X,SC),
   57        curie_prefix(SC,S).
   58
   59entity_def(E,D,Xs) :-
   60        triple_property_axiom_annotations(E,def:'',D1,oio:hasDbXref,Xs1),
   61        ensure_atom(D1,D),
   62        ensure_atoms(Xs1,Xs).
   63
   64syn_scope('http://www.geneontology.org/formats/oboInOwl#hasRelatedSynonym','RELATED').
   65syn_scope('http://www.geneontology.org/formats/oboInOwl#hasNarrowSynonym','NARROW').
   66syn_scope('http://www.geneontology.org/formats/oboInOwl#hasBroadSynonym','BROAD').
   67syn_scope('http://www.geneontology.org/formats/oboInOwl#hasExactSynonym','EXACT').
   68
   69syntype_uri_to_id(V1,V) :-
   70        concat_atom([_,V],'#',V1),
   71        !.
   72syntype_uri_to_id(V,V).
   73
   74entity_synonym(E,V,Scope,Type,Xrefs) :-
   75        syn_scope(P,Scope),
   76        triple_axiom_annotations(E,P,V1,Anns),
   77        ensure_atom(V1,V),
   78        convlist(['http://www.geneontology.org/formats/oboInOwl#hasDbXref'-Y1,
   79                  Y]>>ensure_atom(Y1,Y),
   80                 Anns,Xrefs),
   81        (   member('http://www.geneontology.org/formats/oboInOwl#hasSynonymType'-Type1,Anns)
   82        ->  syntype_uri_to_id(Type1,Type)
   83        ;   Type='').
   84
   85subset_uri_to_id(V1,V) :-
   86        concat_atom([_,V],'#',V1),
   87        !.
   88subset_uri_to_id(V,V).
   89
   90
   91entity_subset(E,V) :-
   92        rdf(E,oio:inSubset,V1),
   93        subset_uri_to_id(V1,V).
 curie_prefix(Literal:str, Pre:str)
   98curie_prefix(Literal,Pre) :-
   99        str_before(Literal,":",Pre).
  100
  101is_a(A,B) :-
  102        rdf(A,rdfs:subClassOf,B),
  103        rdf_is_iri(B).
  104
  105entity_name(E,N) :-
  106        label(E,N1),
  107        ensure_atom(N1,N).
  108
  109is_dangling(E) :-
  110        \+ label(E,_).
  111
  112
  113gen_obo(S,Opts) :-
  114        gen_obo(S,_,Opts).
  115
  116gen_obo(S,G,Opts) :-
  117        forall(gen_header(S,G,Opts),true),
  118        format(S,'~n',[]),
  119        setof(E,T^entity_obotype(E,T,G),Es),
  120        forall((member(E,Es),\+is_dangling(E)),
  121               gen_stanza(S,E,G,Opts)).
  122
  123gen_header(S,G,_) :-
  124        rdf_graph(G),
  125        ensure_id(G,Id),
  126        format(S,'ontology: ~w~n',Id).
  127gen_header(S,_G,_) :-
  128        rdf(V1,rdfs:subPropertyOf,oio:'SubsetProperty'),
  129        subset_uri_to_id(V1,V),
  130        format(S,'subsetdef: ~w "~w"~n',[V,V]).
  131
  132gen_stanza(S,E,Opts) :-
  133        gen_stanza(S,E,_G,Opts).
  134
  135gen_stanza(S,E,G,Opts) :-
  136        entity_obotype(E,T),
  137        ensure_id(E,Id),
  138        format(S,'[~w]~n',[T]),
  139        format(S,'id: ~w~n',[Id]),
  140        forall(gen_tag(S,E,G,Opts),true),
  141        format(S,'~n',[]).
  142
  143
  144gen_tag(S,E,_,_) :-
  145        entity_name(E,N),
  146        format(S,'name: ~w~n',[N]).
  147gen_tag(S,E,_,_) :-
  148        entity_def(E,N,Xrefs),
  149        escq(N,N1),
  150        serialize_xrefs(Xrefs,X),
  151        format(S,'def: "~w" ~w~n',[N1,X]).
  152
  153gen_tag(S,E,_,_) :-
  154        entity_subset(E,X),
  155        format(S,'subset: ~w~n',[X]).
  156
  157gen_tag(S,E,_,_) :-
  158        entity_synonym(E,V1,Scope,Type,Xrefs),
  159        serialize_xrefs(Xrefs,X),
  160        escq(V1,V),
  161        format(S,'synonym: "~w" ~w ~w ~w~n',[V,Scope,Type,X]).
  162
  163gen_tag(S,E,_,_) :-
  164        is_a(E,X),
  165        tv(S,is_a,[X]).
  166
  167gen_tag(S,E,_,_) :-
  168        rdf(E,rdfs:subClassOf,R),
  169        owl_some(R,P,O),
  170        \+ rdf_is_bnode(O),
  171        tv(S,relationship,[P,O]).
  172
  173tv(S,T,Vs) :-
  174        format(S,'~w:',[T]),
  175        forall((member(V,Vs),ensure_id(V,Id)),
  176               format(S,' ~w',[Id])),
  177        findall(N,(member(V,Vs),entity_name(V,N)),
  178                Ns),
  179        (   Ns=[]
  180        ->  true
  181        ;   format(S,' !',[]),
  182            forall(member(N,Ns),
  183                   format(S,' ~w',[N]))),
  184        nl.
  185
  186
  187serialize_xrefs(Xs,A) :-
  188        concat_atom(Xs,', ',A1),
  189        concat_atom(['[',A1,']'],A).
  190
  191
  192
  193escq(A,B) :-
  194        concat_atom(Xs,'"',A),
  195        concat_atom(Xs,'\\"',B)