View source with formatted comments or as raw
    1/*  Part of SWI-Prolog
    2
    3    Author:        Jan Wielemaker
    4    E-mail:        J.Wielemaker@vu.nl
    5    WWW:           http://www.swi-prolog.org
    6    Copyright (c)  2010-2018, University of Amsterdam
    7    All rights reserved.
    8
    9    Redistribution and use in source and binary forms, with or without
   10    modification, are permitted provided that the following conditions
   11    are met:
   12
   13    1. Redistributions of source code must retain the above copyright
   14       notice, this list of conditions and the following disclaimer.
   15
   16    2. Redistributions in binary form must reproduce the above copyright
   17       notice, this list of conditions and the following disclaimer in
   18       the documentation and/or other materials provided with the
   19       distribution.
   20
   21    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   22    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   23    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
   24    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
   25    COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
   26    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
   27    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   28    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
   29    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   30    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
   31    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   32    POSSIBILITY OF SUCH DAMAGE.
   33*/
   34
   35:- module(serql_runtime,
   36          [ serql_compare/3,            % +Comparison, +Left, +Right
   37            serql_eval/2,               % +Term, -Evaluated
   38            serql_member_statement/2    % -Triple, +List
   39          ]).   40:- use_module(library(xsdp_types)).   41:- use_module(library(debug)).   42:- use_module(library('semweb/rdf_db')).   43
   44
   45/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   46This module provides runtime support for running compiled SeRQL queries.
   47I.e. it defines special constructs that  may   be  emitted  by the SeRQL
   48compiler and optimizer. Predicates common to   all  query languages have
   49been moved to rdfql_runtime.pl
   50- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
   51
   52
   53                 /*******************************
   54                 *         RUNTIME TESTS        *
   55                 *******************************/
   56
   57%!  serql_compare(+Op, +Left, +Right)
   58%
   59%   Handle numerical and textual comparison of literals.  Some work
   60%   must be done at compiletime.
   61
   62serql_compare(Op, L, R) :-
   63    serql_eval(L, VL),
   64    serql_eval(R, VR),
   65    !,
   66    do_compare(Op, VL, VR).
   67
   68do_compare(like, literal(Value), Pattern) :-
   69    !,
   70    to_string(Value, String),
   71    rdf_match_label(like, Pattern, String).
   72do_compare(like, Resource, Pattern) :-
   73    !,
   74    atom(Resource),
   75    rdf_match_label(like, Pattern, Resource).
   76do_compare(=, X, X) :- !.
   77do_compare(=, literal(X), query(X)) :- !.
   78do_compare(=, X, query(X)) :- !.
   79do_compare(\=, X, Y) :-
   80    !,
   81    \+ do_compare(=, X, Y).
   82do_compare(Op, literal(Data), query(Query)) :-
   83    catch(to_number(Query, Right, TypeQ), _, fail),
   84    !,
   85    (   nonvar(TypeQ), atom(Data)
   86    ->  catch(xsdp_convert(TypeQ, [Data], Left), _, fail)
   87    ;   catch(to_number(Data, Left, TypeD), _, fail),
   88        serql_subsumes(TypeQ, TypeD)
   89    ),
   90    cmp_nums(Op, Left, Right).
   91do_compare(Op, literal(Data), query(Query)) :-
   92    !,
   93    (   atom(Query)                 % plain text
   94    ->  atom(Data),                 % TBD: Lang and Type
   95        cmp_strings(Op, Data, Query)
   96    ).
   97do_compare(Op, query(Query), literal(Data)) :-
   98    !,
   99    inverse_op(Op, Inverse),
  100    do_compare(Inverse, literal(Data), query(Query)).
  101do_compare(Op, literal(Value), literal(Number)) :-
  102    catch(to_number(Value, Left, TypeL), _, fail),
  103    catch(to_number(Number, Right, TypeR), _, fail),
  104    TypeL == TypeR,
  105    cmp_nums(Op, Left, Right).
  106
  107serql_eval(Var, X) :-
  108    var(Var),
  109    !,
  110    X = '$null$'.
  111serql_eval(lang(X), Lang) :-
  112    !,
  113    lang(X, Lang).
  114serql_eval(datatype(X), Type) :-
  115    !,
  116    datatype(X, Type).
  117serql_eval(label(X), Lang) :-
  118    !,
  119    label(X, Lang).
  120serql_eval(X, X).
  121
  122%!  lang(+Literal, -Lang) is det.
  123%!  datatype(+Literal, -DataType) is det.
  124%!  label(+Literal, -Label) is det.
  125%
  126%   Defined functions on literals.  
  127
  128lang(literal(lang(Lang0, _)), Lang) :-
  129    nonvar(Lang0),
  130    !,
  131    Lang = literal(Lang0).
  132lang(_, '$null$').
  133
  134datatype(literal(type(Type0, _)), Type) :-
  135    nonvar(Type0),
  136    !,
  137    Type = Type0.
  138datatype(_, '$null$').
  139
  140label(literal(lang(_, Label0)), Label) :-
  141    nonvar(Label0),
  142    !,
  143    Label = literal(Label0).
  144label(literal(Label0), Label) :-
  145    nonvar(Label0),
  146    !,
  147    Label = literal(Label0).
  148label(_, '$null$').
  149
  150
  151cmp_nums(=, L, R)  :- L =:= R.
  152cmp_nums(=<, L, R) :- L =< R.
  153cmp_nums(<, L, R)  :- L < R.
  154cmp_nums(>, L, R)  :- L > R.
  155cmp_nums(>=, L, R) :- L >= R.
  156
  157cmp_strings(Op, S1, S2) :-
  158    atom(S1), atom(S2),
  159    compare(Op, S1, S2).
  160
  161inverse_op(=, =).
  162inverse_op(=<, >).
  163inverse_op(<, >=).
  164inverse_op(>, =<).
  165inverse_op(>=, <).
  166
  167to_number(type(Type, String), Num, Type) :-    % TBD: Check type
  168    !,
  169    atom_number(String, Num).
  170to_number(lang(_Lang, String), Num, _) :-
  171    !,
  172    atom_number(String, Num).
  173to_number(String, Num, _) :-
  174    assertion(atom(String)),
  175    atom_number(String, Num).
  176
  177%!  serql_subsumes(QueryType, DataType)
  178
  179serql_subsumes(Q, Var) :-               % odd rule!
  180    nonvar(Q),
  181    var(Var),
  182    !.
  183serql_subsumes(_, Var) :-               % odd rule!
  184    var(Var), !, fail.
  185serql_subsumes(Var, _) :-               % type is not specified in query
  186    var(Var),
  187    !.
  188serql_subsumes(Query, Data) :-
  189    xsdp_subtype_of(Data, Query).
  190
  191to_string(lang(_, String), String) :- !.
  192to_string(type(_, String), String) :- !.
  193to_string(String, String) :-
  194    atom(String).
  195
  196%!  serql_member_statement(-Triple, +List)
  197%
  198%   Get the individual triples from  the   original  reply. Used for
  199%   CONSTRUCT queries. As handling optional matches is different int
  200%   SeRQL compared to SPARQL, the selection  is in the SeRQL runtime
  201%   module.
  202
  203serql_member_statement(RDF, [H|_]) :-
  204    member_statement2(RDF, H).
  205serql_member_statement(RDF, [_|T]) :-
  206    serql_member_statement(RDF, T).
  207
  208member_statement2(RDF, optional(True, Statements)) :-
  209    !,
  210    True = true,
  211    serql_member_statement(RDF, Statements).
  212member_statement2(RDF, RDF)