1:- module(dataframe, 2 [dataframe_header/2, 3 dataframe_header/3, 4 dataframe_row/2, 5 dataframe_row/3, 6 dataframe_row/4, 7 8 dataframe_to_csv/2, 9 dataframe_to_csv/3]). 10 11:- use_module(library(semweb/rdf11)).
person(ID,Name)
,
[street=Street,
city=City]-address(ID,Street,City)
,
...],
[description('person and location report')
,
entity(city)
]).
TODO
frame('person location report')
<<
foo(id=ID :: entity, name=Name) where person(ID,Name)
,
foo(street=Street, city=City :: entity) where address(ID,Street,City)
.
*/
35:- multifile dataframe/2. 36:- multifile dataframe/3. 37 38dataframe_specs_opts(Name,Specs,Opts) :- dataframe(Name,Specs,Opts). 39dataframe_specs_opts(Name,Specs,[]) :- dataframe(Name,Specs). 40 41:- module_transparent(dataframe_header/2). 42:- module_transparent(dataframe_header/3). 43dataframe_header(Name,Header) :- 44 dataframe_header(Name,Header,[]). 45dataframe_header(Name,Header,Opts) :- 46 dataframe_specs_opts(Name,Specs,SpecOpts), 47 findall(K, 48 ( member(Sub-_,Specs), 49 member(K=_,Sub)), 50 Header1), 51 inject_labels_to_header(Header1,Header,SpecOpts,Opts). 52 53inject_labels_to_header([],[],_,_). 54inject_labels_to_header([K|L],[K,KN|L2],SpecOpts,Opts) :- 55 member(entity(K),SpecOpts), 56 !, 57 atom_concat(K,' label',KN), 58 inject_labels_to_header(L,L2,SpecOpts,Opts). 59inject_labels_to_header([K|L],[K|L2],SpecOpts,Opts) :- 60 inject_labels_to_header(L,L2,SpecOpts,Opts). 61 62 63 64:- module_transparent(dataframe_row/2). 65:- module_transparent(dataframe_row/3). 66:- module_transparent(dataframe_row/4). 67dataframe_row(Name,Row) :- 68 dataframe_row(Name,Row,[]). 69dataframe_row(Name,Row,Opts) :- 70 dataframe_specs_opts(Name,_Specs,SpecOpts), 71 dataframe_row(Name,Row,Opts,SpecOpts). 72dataframe_row(Name,Row,Opts,SpecOpts) :- 73 dataframe_specs_opts(Name,[Spec|Specs],SpecOpts), 74 spec_bindings_goal(Spec,Bs,G), 75 dataframe_header(Name,Header,Opts), 76 call_wrap(G,SpecOpts), 77 maplist([_=V,V]>>true,Bs,Row1), 78 apply_specs(Specs,Row2), 79 append(Row1,Row2,Row3), 80 flatten_row(Row3,Row,Header,[Spec|Specs],SpecOpts,Opts). 81 82:- module_transparent(call_wrap/2). 83call_wrap(G,Opts) :- 84 member(endpoint(Endpoint),Opts), 85 !, 86 ??(Endpoint, G). 87call_wrap(G,_) :- 88 . 89 90:- module_transparent(apply_specs/2). 91apply_specs([],[]). 92apply_specs([Spec|Specs],Row) :- 93 spec_bindings_goal(Spec,Bs,G), 94 ( setof(Bs,G,BsSet) 95 -> true 96 ; BsSet=[]), 97 maplist({BsSet}/[Var=_,Vals] >> findall(X,(member(Bs1,BsSet),member(Var=X,Bs1)),Vals),Bs,Row1), 98 append(Row1,Row2,Row), 99 apply_specs(Specs,Row2). 100 101:- module_transparent(spec_bindings_goal/3). 102spec_bindings_goal(Bs-G,Bs,G). 103 104 105 106flatten_row([],[],_,_,_,_). 107flatten_row([V|Row],Row2,Keys,Specs,SpecOpts,Opts) :- 108 Keys=[K|_], 109 select(entity(K),SpecOpts,SpecOpts2), 110 !, 111 get_labels(V,Ns,Opts), 112 contract_uris(V,V2,Opts), 113 flatten_row([V2,Ns|Row],Row2,Keys,Specs,SpecOpts2,Opts). 114flatten_row([V|Row],[V2|Row2],Keys,Specs,SpecOpts,Opts) :- 115 Keys=[K|Keys2], 116 select(iri(K),SpecOpts,SpecOpts2), 117 !, 118 contract_uris(V,V1,Opts), 119 serialize_value(V1,V2,Opts), 120 flatten_row(Row,Row2,Keys2,Specs,SpecOpts2,Opts). 121flatten_row([V|Row],[V2|Row2],[_K|Keys],Specs,SpecOpts,Opts) :- 122 serialize_value(V,V2,Opts), 123 flatten_row(Row,Row2,Keys,Specs,SpecOpts,Opts). 124 125% todo: hook 126get_labels(L,Vs,Opts) :- 127 is_list(L), 128 !, 129 maplist({Opts}/[X,X2]>>get_labels(X,X2,Opts),L,L2), 130 flatten(L2,Vs). 131get_labels(X,V,_Opts) :- 132 rdf_is_iri(X), 133 rdf(X,rdfs:label,V), 134 !. 135get_labels(_,'',_). 136 137contract_uris(L,L2,Opts) :- is_list(L),!,maplist({Opts}/[A,B]>>contract_uri(A,B,Opts),L,L2). 138contract_uris(A,B,Opts) :- contract_uri(A,B,Opts). 139contract_uri(A,B,_) :- rdf_is_iri(A),rdf_global_id(Pre:Local,A),!,concat_atom([Pre,Local],':',B). 140contract_uri(A,A,_). 141 142 143serialize_value(V,'_',_) :- 144 var(V), 145 !. 146serialize_value(L,V,Opts) :- 147 is_list(L), 148 !, 149 maplist({Opts}/[X,X2]>>serialize_value(X,X2,Opts),L,L2), 150 option(internal_sep(Sep),Opts,'|'), 151 concat_atom(L2,Sep,V). 152serialize_value(S@_,V,_) :- 153 !, 154 atom_string(V,S). 155serialize_value(S^^_,V,_) :- 156 !, 157 atom_string(V,S). 158serialize_value(literal(type(_,V)),V,_) :- 159 !. 160serialize_value(literal(lang(_,V)),V,_) :- 161 !. 162serialize_value(literal(V),V,_) :- 163 !. 164serialize_value(S,V,_) :- 165 string(S), 166 !, 167 atom_string(V,S). 168serialize_value(X,V,_) :- 169 sformat(S,'~w',[X]), 170 string_to_atom(S,V). 171 172 173:- module_transparent(dataframe_to_csv/2). 174:- module_transparent(dataframe_to_csv/3). 175dataframe_to_csv(Name, Opts) :- 176 Stream = current_output, 177 dataframe_to_csv(Name, Stream, Opts). 178dataframe_to_csv(Name, Stream, Opts) :- 179 dataframe_header(Name, Header, Opts), 180 option(separator(Sep), Opts, 0'\t), 181 HTerm =.. [row|Header], 182 csv_write_stream(Stream, [HTerm], [separator(Sep)]), 183 dataframe_specs_opts(Name,_Specs,SpecOpts), 184 ( member(sort(_),SpecOpts) 185 -> findall(Row,dataframe_row(Name, Row, Opts, SpecOpts),Rows), 186 % TODO sort by key 187 sort(Rows,RowsSorted), 188 forall((member(Row,RowsSorted), RTerm =.. [row|Row]), 189 csv_write_stream(Stream, [RTerm], [separator(Sep)])) 190 ; forall((dataframe_row(Name, Row, Opts, SpecOpts), RTerm =.. [row|Row]), 191 csv_write_stream(Stream, [RTerm], [separator(Sep)]))), 192 !. 193dataframe_to_csv(Name, Stream, Opts) :- 194 throw(exception(no_dataframe(Name, Stream, Opts)))