#!/usr/bin/env swipl -G12g :- initialization main. :- use_module(library(neoplasmer)). :- use_module(library(rdf_matcher)). :- use_module(library(sparqlprog/io_utils)). :- use_module(library(csv)). :- use_module(library(main)). :- use_module(library(optparse)). :- use_module(library(option)). :- use_module(library(index_util)). :- use_module(library(semweb/rdf_library)). :- use_module(library(semweb/rdf_http_plugin)). :- use_module(library(semweb/rdf_cache)). :- use_module(library(semweb/rdf_zlib_plugin)). :- use_module(library(semweb/rdf11)). :- use_module(library(semweb/rdfs)). :- use_module(library(pengines)). :- use_module(pengine_sandbox:library(neoplasmer)). :- use_module(pengine_sandbox:library(sparqlprog/labelutils)). :- use_module(pengine_sandbox:library(semweb/rdf11)). :- use_module(library(http/thread_httpd)). :- use_module(library(http/http_dispatch)). % TODO: make configurable :- rdf_set_cache_options([ global_directory('RDF-Cache'), create_global_directory(true) ]). main(Argv) :- Spec = [ [opt(output), type(atom), longflags(['output']), shortflags([o]), help('Outfile') ], [opt(format), type(atom), longflags(['format']), shortflags([f]), help('Output format: csv') ], [opt(input), type(atom), longflags(['input']), shortflags([i]), help('Input RDF file (use in combo with -x)') ], [opt(indexdir), type(atom), longflags(['indexdir']), shortflags(['X']), help('path to directory to be used for materializing index') ], [opt(prefix), type(atom), longflags(['prefix']), shortflags([p]), help('Prefix to perform matching against') ], [opt(ontology), type(atom), longflags(['ontology']), help('Prefix of ontology to be compared against; note if using indexes this will be filtered prior') ], [opt(port), type(integer), longflags([port]), help('Port to start pengines service on') ], [opt(goal), type(term), longflags([goal]), shortflags([g]), help('Prolog goal to call') ], [opt(consult), type(atom), longflags([consult]), shortflags([c]), help('Prolog program to load/consult') ], [opt(use), type(atom), longflags([use]), shortflags([u]), help('Prolog module to use') ], [opt(use_no_import), type(atom), longflags([use_no_import]), shortflags(['U']), help('Prolog module to use, do not import all') ], [opt(debug), type(term), longflags([debug]), shortflags([d]), help('term passed to debug/1') ], [opt(attach), type(atom), longflags([attach]), shortflags(['A']), help('rdf_attach_library - path to void.ttl') ], [opt(service), type(atom), longflags([service]), shortflags([s]), help('name of remote service to query') ], [opt(inject_labels), type(boolean), default(false), longflags([label]), shortflags([l]), help('Inject query for rdfs labels into query') ], [opt(obsoletes), type(boolean), default(false), longflags([obsoletes]), help('If set, include obsoletes in results') ], [opt(show), type(boolean), default(false), longflags([show]), shortflags(['S']), help('Show SPARQL query') ], [opt(prolog), type(boolean), default(false), longflags([prolog]), shortflags(['P']), help('Interactive prolog') ], [opt(interactive), type(boolean), default(false), longflags([interactive]), shortflags(['I']), help('Interactive prolog') ], [opt(compile), type(boolean), default(false), longflags([compile]), shortflags(['C']), help('Compile Prolog to SPARQL (no execution)') ], [opt(verbose), type(boolean), default(false), longflags([verbose]), shortflags([v]), help('Same as --debug sparqlprog') ], [opt(stacktrace), type(boolean), default(false), longflags([stacktrace]), shortflags(['T']), help('Shows stack trace on error') ], [opt(execute), type(boolean), default(false), longflags([execute]), shortflags([e]), help('Executes query directly in prolog') ], [opt(query), type(term), longflags([query]), shortflags([q]), help('Prolog query') ] ], opt_parse(Spec, Argv, Opts, Files, [duplicated_flags(keepall)]), handle_opts(Opts), option(indexdir(IndexDir),Opts), ( var(IndexDir) -> true ; ( exists_directory(IndexDir) -> debug(neoplasmer,'Using existing cache: ~w',[IndexDir]) ; make_directory(IndexDir)), debug(neoplasmer,'Indexing into: ~w',[IndexDir]), index_pairs(IndexDir)), opt_forall(port(X),server(X),Opts), opt_if_call(interactive,sparqlprog_shell(Opts),Opts), opt_if_call(prolog,prolog_shell(Opts),Opts), forall(member(File,Files), parse_and_match(File)), halt. parse_and_match(File) :- csv_read_file(File,Rows,[]), maplist(parse_row,Rows). parse_row(Row) :- Row =.. [_Pred,Term|_], G = term_best_match(Term,_,_,_), forall(G, write_result_wrap(G,[format(tsv)])). write_result_wrap(G,Opts) :- select(inject_labels(Inject),Opts,Opts2), nonvar(Inject), Inject, !, G =.. [P,A,B,C|Rest], obj_label(A,NameA), obj_label(B,NameB), obj_label(C,NameC), G2 =.. [P,A,NameA,B,NameB,C,NameC|Rest], write_result_wrap(G2,Opts2). write_result_wrap(G,Opts) :- write_result(G,Opts). obj_label(X,N) :- rdf(X,rdfs:label,N), !. obj_label(_,'') :- !. % Unify G with a goal that succeeds % if X passes criteria specified in Opts. % % these are intended to be executed prior to % matching opt_query_constraint_pre(X,G,Opts) :- option(prefix(Prefix),Opts), nonvar(Prefix), !, G=obj_has_prefix(X,Prefix). opt_query_constraint_pre(_,true,_). % as above, but executed after the fact opt_query_constraint_post(_,G,PostG,Opts) :- option(obsoletes(Obs),Opts), Obs=false, G =.. [_,A,B|_], !, PostG = (is_not_obsolete(A),is_not_obsolete(B)). opt_query_constraint_post(_,_,true,_). is_not_obsolete(X) :- \+ rdf(X,owl:deprecated,_). show_rules(Rs) :- use_module(library(rule_eval)), eval_rules(Rs,Pairs), forall(member(P,Pairs), show_rule(P)). :- op(1200, xfy, ::). show_rule(R-Scores) :- memberchk(precision(Pr),Scores), wrule( Pr::R ), format('%% Scores: ~q.~n',[Scores]), nl. wrule(R) :- copy_term(R,R2), numbervars(R2,0,_,[]), format('~q.~n',[R2]). handle_opts(Opts) :- opt_if_call(verbose,debug(neoplasmer),Opts), opt_if_call(verbose,debug(index),Opts), opt_if_call(verbose,debug(rule_eval),Opts), opt_if_call(stacktrace,use_module(library(sparqlprog/stacktrace)),Opts), opt_forall(attach(X),rdf_attach_library(X),Opts), opt_forall(debug(X),debug(X),Opts), opt_forall(use(X),use_module(library(X)),Opts), opt_forall(use_no_import(X),use_module(library(X),[]),Opts), opt_forall(ontology(Prefix),set_ontology(Prefix),Opts), opt_forall(consult(X),consult(X),Opts), opt_forall(input(X),rdf_load_wrap(X),Opts), opt_forall(goal(X),X,Opts). % execute a goal for every ground instance of Template opt_forall(Template,Goal,Opts) :- debug(sparqlprog,'Running ~q for all ground ~q in ~q',[Goal,Template,Opts]), forall((member(Template,Opts),ground(Template)), Goal). opt_if_call(Opt,Goal,Opts) :- T =.. [Opt,Var], member(T,Opts), ground(Var), Var=true, !, Goal. opt_if_call(_,_,_). opt_if(T,Opts) :- member(T,Opts), ground(T), !. opt_if(T,Opts,Opts2) :- select(T,Opts,Opts2), ground(T), !. rdf_load_wrap(X) :- catch(rdf_load(X), _E, rdf_load_library(X)). % TODO: get from elsewhere sparqlprog_shell(Opts):- format('% Starting pl2sparql shell~n'), current_input(IO), HFile='.sparqlprog_history', ( exists_file(HFile) -> rl_read_history(HFile) ; true), repeat, read_line_to_codes(IO,Codes), ( Codes=end_of_file -> ! ; atom_codes(A,Codes), rl_add_history(A), format('Cmd: ~w~n',[A]), concat_atom(L,' ',A), catch(run(L,Opts), E, ( format('ERROR:~n~w~n',[E]),fail)), format('SUCCESS!~n'), rl_write_history(HFile), fail). prolog_shell(_Opts):- format('% Starting prolog shell~n'), HFile='.plhistory', ( exists_file(HFile) -> rl_read_history(HFile) ; true), prolog, format('% Bye!~n'), rl_write_history(HFile), halt. server :- getenv('PORT',PortAtom), atom_number(PortAtom,Port), server(Port). server(Port) :- http_server(http_dispatch, [port(Port)]), T is 10 ** 10, sleep(T).