#!/usr/bin/env swipl -G12g :- initialization main. :- use_module(library(rdf_matcher)). :- use_module(library(rdf_matcher/rule_inference)). :- use_module(library(main)). :- use_module(library(optparse)). :- use_module(library(option)). :- use_module(library(sparqlprog/io_utils)). %:- use_module(library(rule_eval)). :- use_module(library(index_util)). :- use_module(library(sparqlprog/labelutils)). :- 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)). % note: when we switc to swipl 7.8 consider using new stack options %:- set_prolog_flag(stack_limit,'0G'). %:- set_prolog_stack(global, limit(1)). % TODO: make configurable :- rdf_set_cache_options([ global_directory('RDF-Cache'), create_global_directory(true) ]). main(Argv) :- catch(wmain(Argv), E, ( format(user_error,'~q~n',[E]), halt(1))), halt. wmain(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(ontA), type(atom), longflags(['ontA']), help('Prefix1 of ontology in match (for learning)') ], [opt(ontB), type(atom), longflags(['ontB']), help('Prefix2 of ontology in match (for learning)') ], [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, Rest, [duplicated_flags(keepall)]), handle_opts(Opts), debug(rdf_matcher,'Opts = ~q.',[Opts]), inject_prefixes, option(indexdir(IndexDir),Opts,none), index_pairs(IndexDir), opt_if_call(interactive,sparqlprog_shell(Opts),Opts), opt_if_call(prolog,prolog_shell(Opts),Opts), run(Rest, Opts). run([learn|_Args], Opts) :- materialize_index(eq_from_match(+,+,-,-,-,+,+)), optional(materialize_index(eq_from_shared_xref(+,+,-,+,+))), debug(rdf_matcher,'Grounding',[]), ground_rules(Rules, Opts), debug(rdf_matcher,'Eval rules',[]), eval_and_show_rules(Rules). run([classify, WeightFile | _Args], Opts) :- use_module(library(rule_eval)), consult(WeightFile), forall(infer_fact(equivalent(X,Y),_,W), write_result(eq(X,Y,W,foo),Opts)). % format('eq\t~w\t~w\t~w\tlearned~n',[X,Y,W])). run([match|_Args], Opts) :- G = inter_pair_match(X,_,_,_Info), write_all_results(X,G,Opts). run([exact|_Args], Opts) :- write_result_wrap(m(c1,c2,c1parents,c2parents,conf,match,info,alt_c1,alt_c2,ignored_c1,ignored_c2),Opts), G = exact_inter_pair_match(X,_,_,_,_,_,_,_,_,_,_), write_all_results(X,G,Opts). run([new_match|_Args], Opts) :- G = new_pair_match(X,_,_,_Info), write_all_results(X,G,Opts). run([tri_match|_Args], Opts) :- G = tri_match(C1,_C2,_C3,_Info), write_all_results(C1,G,Opts). run([triad_nc|_Args], Opts) :- G = new_unique_match_triad_nc(C1,_C2,_C3), write_all_results(C1,G,Opts). run([rightnew_match|_Args], Opts) :- G = rightnew_pair_match(X,_,_,_Info), write_all_results(X,G,Opts). run([unique_match|_Args], Opts) :- G = new_unique_pair_match(X,_,_,_Info), write_all_results(X,G,Opts). run([cluster|_Args], Opts) :- materialize_index(new_pair_match(+,+,-,-)), %materialize_index(transitive_new_match(+,+)), G = transitive_new_match_set_pair(X,_,_), write_all_results(X,G,Opts). run([ucluster|_Args], Opts) :- materialize_index(new_unique_pair_match(+,+,-,-)), %materialize_index(transitive_unique_match(+,+)), G = transitive_unique_match_set_member(X,_), write_all_results(X,G,Opts). run([trial|_Args], Opts) :- materialize_index(new_unique_pair_match(+,+,-,-)), G = new_unique_match_triad(X,_,_), write_all_results(X,G,Opts). run([unmatched,Pfx|_Args], Opts) :- G = (unmatched_in(X,Pfx),has_prefix(X,XPfx)), forall((G,obj_label(X,XN)), write_result(unmatched(X,XN,Pfx,XPfx),Opts)). %! write_all_results(?X, +Goal, +Opts:list) is det. % % writes value of X for every Goal % % also filters based on Opts write_all_results(X,G,Opts) :- debug(rdf_matcher,'Goal=~q',[G]), opt_query_constraint_pre(X,PreG,Opts), opt_query_constraint_post(X,G,PostG,Opts), forall((PreG,G,PostG), write_result_wrap(G,Opts)). write_result_wrap(G,Opts) :- select(inject_labels(Inject),Opts,Opts2), nonvar(Inject), Inject, !, row_labelify(G,G2), 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_is_iri(X),rdf(X,owl:deprecated,_))). eval_and_show_rules(Rs) :- use_module(library(rule_eval)), debug(rdf_matcher,'Eval rules: ~q',[Rs]), eval_rules(Rs,Pairs), debug(rdf_matcher,'Evaled all rules',[]), forall(member(P,Pairs), show_rule(P)). :- op(1200, xfy, ::). show_rule(R-Scores) :- memberchk(pr_true(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(rdf_matcher),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(rdf_matcher,'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), !. optional(G) :- G,!. optional(_). 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.