View source with formatted comments or as raw
    1/*  Part of SWI-Prolog
    2
    3    Author:        Jan Wielemaker and Wouter Beek
    4    E-mail:        J.Wielemaker@vu.nl
    5    WWW:           http://www.swi-prolog.org
    6    Copyright (c)  2015-2016, VU University 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
   36:- module(rdf11,
   37          [ rdf/3,                      % ?S, ?P, ?O
   38            rdf/4,                      % ?S, ?P, ?O, ?G
   39            rdf_has/3,                  % ?S, ?P, ?O
   40            rdf_has/4,                  % ?S, ?P, ?O, -RealP
   41            rdf_update/4,               % +S, +P, +O, +Action
   42            rdf_update/5,               % +S, +P, +O, +G, +Action
   43            rdf_reachable/3,            % ?S, ?P, ?O
   44            rdf_reachable/5,            % ?S, ?P, ?O, +MaxD, -D
   45
   46            rdf_assert/3,               % +S, +P, +O
   47            rdf_assert/4,               % +S, +P, +O, ?G
   48            rdf_retractall/3,           % ?S, ?P, ?O
   49            rdf_retractall/4,           % ?S, ?P, ?O, ?G
   50
   51            {}/1,                       % +Where
   52            rdf_where/1,                % +Where
   53            rdf_compare/3,              % -Diff, +Left, +Right
   54
   55            rdf_term/1,                 % ?Term
   56            rdf_literal/1,              % ?Term
   57            rdf_bnode/1,                % ?Term
   58            rdf_iri/1,                  % ?Term
   59            rdf_name/1,                 % ?Term
   60
   61            rdf_is_iri/1,               % @Term
   62            rdf_is_bnode/1,             % @Term
   63            rdf_is_literal/1,           % @Term
   64            rdf_is_name/1,              % @Term
   65            rdf_is_object/1,            % @Term
   66            rdf_is_predicate/1,         % @Term
   67            rdf_is_subject/1,           % @Term
   68            rdf_is_term/1,              % @Term
   69
   70            rdf_subject/1,              % ?Term
   71            rdf_predicate/1,            % ?Term
   72            rdf_object/1,               % ?Term
   73            rdf_node/1,                 % ?Term
   74
   75            rdf_create_bnode/1,         % ?Term
   76
   77            rdf_canonical_literal/2,    % +In, -Canonical
   78            rdf_lexical_form/2,         % +Literal, -Lexical
   79
   80            rdf_default_graph/1,        % -Graph
   81            rdf_default_graph/2,        % -Old, +New
   82
   83            rdf_estimate_complexity/4,  % ?S, ?P, ?O, -Estimate
   84            rdf_assert_list/2,          % +PrologList, ?RDFList
   85            rdf_assert_list/3,          % +PrologList, ?RDFList, +G
   86            rdf_last/2,                 % +RDFList, ?Last
   87            rdf_list/1,                 % ?RDFList
   88            rdf_list/2,                 % +RDFList, -PrologList
   89            rdf_length/2,               % ?RDFList, ?Length
   90            rdf_member/2,               % ?Member, +RDFList
   91            rdf_nextto/2,               % ?X, ?Y
   92            rdf_nextto/3,               % ?X, ?Y, ?RdfList
   93            rdf_nth0/3,                 % ?Index, +RDFList, ?X
   94            rdf_nth1/3,                 % ?Index, +RDFList, ?X
   95            rdf_retract_list/1,         % +RDFList
   96
   97            op(110, xfx, @),            % must be above .
   98            op(650, xfx, ^^),           % must be above :
   99            op(1150, fx, rdf_meta)
  100          ]).  101:- use_module(library(c14n2)).  102:- use_module(library(debug)).  103:- use_module(library(error)).  104:- use_module(library(lists)).  105:- use_module(library(memfile)).  106:- reexport(library(semweb/rdf_db),
  107            except([ rdf/3,
  108                     rdf/4,
  109                     rdf_assert/3,
  110                     rdf_assert/4,
  111                     rdf_current_literal/1,
  112                     rdf_current_predicate/1,
  113                     rdf_has/3,
  114                     rdf_has/4,
  115                     rdf_update/4,
  116                     rdf_update/5,
  117                     rdf_reachable/3,
  118                     rdf_reachable/5,
  119                     rdf_retractall/3,
  120                     rdf_retractall/4,
  121                     rdf_node/1,
  122                     rdf_bnode/1,
  123                     rdf_is_literal/1,
  124                     rdf_is_resource/1,
  125                     rdf_literal_value/2,
  126                     rdf_compare/3,
  127                     rdf_estimate_complexity/4
  128                   ])
  129           ).  130:- use_module(library(sgml)).  131:- use_module(library(solution_sequences)).  132
  133/** <module> RDF 1.1 API
  134
  135This library provides a new API   on  top of library(semweb/rdf_db). The
  136new API follows the  RDF  1.1  terminology   and  notation  as  much  as
  137possible. It runs on top of the old API, which implies that applications
  138can use the new API in one file and   the other in another one. Once the
  139new API is considered stable and robust the old API will be deprecated.
  140
  141In a nutshell, the following issues are addressed:
  142
  143  - Literals are now represented by Value^^Type or Text@Lang.  Plain
  144    literals no longer exist. Value is a Prolog representation of
  145    the value for known types.  In particular:
  146      - xsd:double, xsd:float and xsd:decimal are represented by a Prolog
  147        float
  148      - Integer types are represented by a Prolog integer
  149      - The date/time types are presented by Prolog terms
  150  - Literal matching and comparison operations are represented as
  151    Prolog _constraints_.  This replaces the literal(+Search,-Value)
  152    construct used by library(semweb/rdf_db). For example, the following
  153    query returns literals with prefix "ams", exploiting the RDF literal
  154    index.
  155
  156      ==
  157      { prefix(Name, "ams") },
  158      rdf(S,P,Name).
  159      ==
  160  - Graphs are always identified by the graph name only, i.e., the
  161    notation Graph:Line is no longer supported.  If a graph name is an IRI
  162    then RDF prefix notation can now be used.
  163  - The enumeration and type-testing predicates are now more closely based
  164    on the RDF 1.1 specification and use consistent naming.
  165
  166@author Jan Wielemaker
  167@author Wouter Beek
  168@see https://github.com/SWI-Prolog/packages-semweb/wiki/Proposal-for-Semweb-library-redesign
  169@version 2016
  170*/
  171
  172:- multifile
  173    in_ground_type_hook/3,                  % +Type, +Input, -Lexical:atom
  174    out_type_hook/3.                        % +Type, -Output, +Lexical:atom
  175
  176:- meta_predicate
  177    parse_partial_xml(3,+,-).  178
  179:- rdf_meta
  180    rdf(r,r,o),
  181    rdf(r,r,o,r),
  182    rdf_assert(r,r,o),
  183    rdf_assert(r,r,o,r),
  184    rdf_has(r,r,o),
  185    rdf_has(r,r,o,-),
  186    rdf_update(r,r,o,t),
  187    rdf_update(r,r,o,r,t),
  188    rdf_reachable(r,r,o),
  189    rdf_reachable(r,r,o,+,-),
  190    rdf_retractall(r,r,o),
  191    rdf_retractall(r,r,o,r),
  192    {}(t),
  193    rdf_where(t),
  194    rdf_canonical_literal(o,-),
  195    rdf_lexical_form(o,-),
  196    rdf_compare(-,o,o),
  197    rdf_iri(r),
  198    rdf_is_iri(r),
  199    rdf_is_literal(o),
  200    rdf_is_name(o),
  201    rdf_is_object(o),
  202    rdf_is_predicate(r),
  203    rdf_is_subject(r),
  204    rdf_is_term(o),
  205    rdf_term(o),
  206    rdf_literal(o),
  207    rdf_name(o),
  208    rdf_object(o),
  209    rdf_estimate_complexity(r,r,o,-),
  210    rdf_assert_list(t,r),
  211    rdf_assert_list(t,r,r),
  212    rdf_last(r,o),
  213    rdf_list(r),
  214    rdf_list(r,-),
  215    rdf_length(r,-),
  216    rdf_member(o,r),
  217    rdf_nextto(o,o),
  218    rdf_nth0(?,r,o),
  219    rdf_nth1(?,r,o),
  220    rdf_retract_list(r).  221
  222
  223%!  rdf(?S, ?P, ?O) is nondet.
  224%!  rdf(?S, ?P, ?O, ?G) is nondet.
  225%
  226%   True if an RDF triple <S,P,O> exists, optionally in the graph G.
  227%   The object O is either a resource  (atom)   or  one of the terms
  228%   listed below. The described types apply for  the case where O is
  229%   unbound. If O is instantiated it   is converted according to the
  230%   rules described with rdf_assert/3.
  231%
  232%   Triples consist of the following three terms:
  233%
  234%     - Blank nodes are encoded by atoms that start with `_:`.
  235%     - IRIs appear in two notations:
  236%       - Full IRIs are encoded by atoms that do not start with
  237%         `_:`.  Specifically, an IRI term is not required to follow
  238%         the IRI standard grammar.
  239%       - Abbreviated IRI notation that allows IRI prefix aliases
  240%         that are registered by rdf_register_prefix/[2,3] to be
  241%         used.  Their notation is `Alias:Local`, where Alias and
  242%         Local are atoms.  Each abbreviated IRI is expanded by the
  243%         system to a full IRI.
  244%     - Literals appear in two notations:
  245%       - String@Lang
  246%       A language-tagged string, where String is a Prolog string
  247%       and Lang is an atom.
  248%       - Value^^Type
  249%       A type qualified literal.  For unknown types, Value is a
  250%       Prolog string. If type is known, the Prolog representations
  251%       from the table below are used.
  252%
  253%       | **Datatype IRI**      | **Prolog term**                 |
  254%       |:----------------------|:--------------------------------|
  255%       | xsd:float             | float                           |
  256%       | xsd:double            | float                           |
  257%       | xsd:decimal           | float                     (1)   |
  258%       | xsd:integer           | integer                         |
  259%       | XSD integer sub-types | integer                         |
  260%       | xsd:boolean           | `true` or `false`               |
  261%       | xsd:date              | date(Y,M,D)                     |
  262%       | xsd:dateTime          | date_time(Y,M,D,HH,MM,SS) (2,3) |
  263%       | xsd:gDay              | integer                         |
  264%       | xsd:gMonth            | integer                         |
  265%       | xsd:gMonthDay         | month_day(M,D)                  |
  266%       | xsd:gYear             | integer                         |
  267%       | xsd:gYearMonth        | year_month(Y,M)                 |
  268%       | xsd:time              | time(HH,MM,SS)            (2)   |
  269%
  270%   Notes:
  271%
  272%     (1) The current implementation of `xsd:decimal` values
  273%         as floats is formally incorrect.  Future versions
  274%         of SWI-Prolog may introduce decimal as a subtype
  275%         of rational.
  276%
  277%     (2) `SS` fields denote the number of seconds.  This can
  278%         either be an integer or a float.
  279%
  280%     (3) The `date_time` structure can have a 7th field that
  281%         denotes the timezone offset *in seconds* as an
  282%         integer.
  283%
  284%   In addition, a _ground_  object  value   is  translated  into  a
  285%   properly typed RDF literal using rdf_canonical_literal/2.
  286%
  287%   There is a fine distinction  in   how  duplicate  statements are
  288%   handled in rdf/[3,4]: backtracking over  rdf/3 will never return
  289%   duplicate triples that appear  in   multiple  graphs. rdf/4 will
  290%   return such duplicate triples, because their graph term differs.
  291%
  292%   @arg S is the subject term.  It is either a blank node or IRI.
  293%   @arg P is the predicate term.  It is always an IRI.
  294%   @arg O is the object term.  It is either a literal, a blank
  295%        node or IRI (except for `true` and `false` that denote the
  296%        values of datatype XSD boolean).
  297%   @arg G is the graph term.  It is always an IRI.
  298%
  299%   @see [Triple pattern querying](http://www.w3.org/TR/sparql11-query/#sparqlTriplePatterns)
  300%   @see xsd_number_string/2 and xsd_time_string/3 are used to
  301%        convert between lexical representations and Prolog terms.
  302
  303rdf(S,P,O) :-
  304    pre_object(O,O0),
  305    rdf_db:rdf(S,P,O0),
  306    post_object(O,O0).
  307
  308rdf(S,P,O,G) :-
  309    pre_object(O,O0),
  310    pre_graph(G,G0),
  311    rdf_db:rdf(S,P,O0,G0),
  312    post_graph(G, G0),
  313    post_object(O,O0).
  314
  315%!  rdf_has(?S, ?P, ?O) is nondet.
  316%!  rdf_has(?S, ?P, ?O, -RealP) is nondet.
  317%
  318%   Similar to rdf/3 and rdf/4, but   P  matches all predicates that
  319%   are defined as an rdfs:subPropertyOf of   P. This predicate also
  320%   recognises   the   predicate   properties     `inverse_of`   and
  321%   `symmetric`. See rdf_set_predicate/2.
  322
  323rdf_has(S,P,O) :-
  324    pre_object(O,O0),
  325    rdf_db:rdf_has(S,P,O0),
  326    post_object(O,O0).
  327
  328rdf_has(S,P,O,RealP) :-
  329    pre_object(O,O0),
  330    rdf_db:rdf_has(S,P,O0,RealP),
  331    post_object(O,O0).
  332
  333
  334%!  rdf_update(+S, +P, +O, ++Action) is det.
  335%!  rdf_update(+S, +P, +O, +G, ++Action) is det.
  336%
  337%   Replaces one of  the  three  fields   on  the  matching  triples
  338%   depending on Action:
  339%
  340%     * subject(Resource)
  341%     Changes the first field of the triple.
  342%     * predicate(Resource)
  343%     Changes the second field of the triple.
  344%     * object(Object)
  345%     Changes the last field of the triple to the given resource or
  346%     literal(Value).
  347%     * graph(Graph)
  348%     Moves the triple from its current named graph to Graph.
  349%     This only works with rdf_update/4 and will throw an error when
  350%     used with rdf_update/3.
  351%
  352%   The argument matching  the  action  must   be  ground.  If  this
  353%   argument is equivalent to  the  current   value,  no  action  is
  354%   performed. Otherwise, the requested action   is performed on all
  355%   matching triples.  For example, all resources typed `rdfs:Class`
  356%   can be changed to `owl:Class` using
  357%
  358%     ```
  359%     ?- rdf_update(_, rdf:type, rdfs:'Class',
  360%                   object(owl:'Class')).
  361%     ```
  362%
  363%   @error instantiation_error if Action or the matching argument is
  364%          not ground.
  365%   @error domain_error(rdf_update_action, Action) if Action is not
  366%          one of the above terms.
  367
  368rdf_update(S, P, O, Action) :-
  369    rdf_update(S, P, O, _, Action).
  370rdf_update(S, P, O, G, Action) :-
  371    must_be(ground, Action),
  372    (   update_column(Action, S,P,O,G, On)
  373    ->  must_be(ground, On),
  374        arg(1, Action, Old),
  375        (   On == Old
  376        ->  true
  377        ;   rdf_transaction(rdf_update_(S, P, O, G, Action), update)
  378        )
  379    ;   domain_error(rdf_update_action, Action)
  380    ).
  381
  382update_column(subject(_),   S,_,_,_, S).
  383update_column(predicate(_), _,P,_,_, P).
  384update_column(object(_),    _,_,O,_, O).
  385update_column(graph(_),     _,_,_,G, G).
  386
  387rdf_update_(S1, P, O, G, subject(S2)) :-
  388    !,
  389    forall(rdf(S1, P, O, G),
  390           ( rdf_retractall(S1, P, O, G),
  391             rdf_assert(S2, P, O, G)
  392           )).
  393rdf_update_(S, P1, O, G, predicate(P2)) :-
  394    !,
  395    forall(rdf(S, P1, O, G),
  396           ( rdf_retractall(S, P1, O, G),
  397             rdf_assert(S, P2, O, G)
  398           )).
  399rdf_update_(S, P, O1, G, object(O2)) :-
  400    !,
  401    forall(rdf(S, P, O1, G),
  402           ( rdf_retractall(S, P, O1, G),
  403             rdf_assert(S, P, O2, G)
  404           )).
  405rdf_update_(S, P, O, G1, graph(G2)) :-
  406    !,
  407    forall(rdf(S, P, O, G1),
  408           ( rdf_retractall(S, P, O, G1),
  409             rdf_assert(S, P, O, G2)
  410           )).
  411
  412
  413%!  rdf_reachable(?S, +P, ?O) is nondet.
  414%!  rdf_reachable(?S, +P, ?O, +MaxD, -D) is nondet.
  415%
  416%   True when O can be reached from S using the transitive closure
  417%   of P. The predicate uses (the internals of) rdf_has/3 and thus
  418%   matches both rdfs:subPropertyOf and the `inverse_of` and
  419%   `symmetric` predicate properties. The version rdf_reachable/5
  420%   maximizes the steps considered and returns the number of steps
  421%   taken.
  422%
  423%   If both S and O are given,   these predicates are `semidet`. The
  424%   number of steps D is  minimal   because  the implementation uses
  425%   _breath first_ search.
  426
  427rdf_reachable(S,P,O) :-
  428    pre_object(O,O0),
  429    rdf_db:rdf_reachable(S,P,O0),
  430    post_object(O,O0).
  431
  432rdf_reachable(S,P,O,MaxD,D) :-
  433    pre_object(O,O0),
  434    rdf_db:rdf_reachable(S,P,O0,MaxD,D),
  435    post_object(O,O0).
  436
  437
  438%!  rdf_assert(+S, +P, +O) is det.
  439%!  rdf_assert(+S, +P, +O, +G) is det.
  440%
  441%   Assert a new triple. If O is a literal, certain Prolog terms are
  442%   translated  to  typed  RDF  literals.    These  conversions  are
  443%   described with rdf_canonical_literal/2.
  444%
  445%   If a type  is  provided   using  Value^^Type  syntax, additional
  446%   conversions are performed. All types accept   either  an atom or
  447%   Prolog string holding a valid RDF lexical value for the type and
  448%   xsd:float and xsd:double accept a Prolog integer.
  449
  450rdf_assert(S,P,O) :-
  451    rdf_default_graph(G),
  452    rdf_assert(S,P,O,G).
  453
  454rdf_assert(S,P,O,G) :-
  455    must_be(ground, O),
  456    pre_ground_object(O,O0),
  457    rdf_db:rdf_assert(S,P,O0,G).
  458
  459%!  rdf_retractall(?S, ?P, ?O) is nondet.
  460%!  rdf_retractall(?S, ?P, ?O, ?G) is nondet.
  461%
  462%   Remove all matching  triples  from   the  database.  Matching is
  463%   performed using the same  rules  as   rdf/3.  The  call does not
  464%   instantiate any of its arguments.
  465
  466rdf_retractall(S,P,O) :-
  467    pre_object(O,O0),
  468    rdf_db:rdf_retractall(S,P,O0).
  469
  470rdf_retractall(S,P,O,G) :-
  471    pre_object(O,O0),
  472    pre_graph(G,G0),
  473    rdf_db:rdf_retractall(S,P,O0,G0).
  474
  475
  476%!  rdf_compare(-Diff, +Left, +Right) is det.
  477%
  478%   True if the RDF terms Left and   Right  are ordered according to
  479%   the comparison operator Diff.  The ordering is defines as:
  480%
  481%     - Literal < BNode < IRI
  482%     - For literals
  483%       - Numeric < non-numeric
  484%       - Numeric literals are ordered by value.  If both are
  485%         equal, floats are ordered before integers.
  486%       - Other data types are ordered lexicographically.
  487%     - BNodes and IRIs are ordered lexicographically.
  488%
  489%   Note that this ordering is a complete ordering of RDF terms that
  490%   is consistent with the partial ordering defined by SPARQL.
  491%
  492%   @arg Diff is one of `<`, `=` or `>`
  493
  494rdf_compare(Diff, Left, Right) :-
  495    pre_ground_object(Left, Left0),
  496    pre_ground_object(Right, Right0),
  497    rdf_db:rdf_compare(Diff, Left0, Right0).
  498
  499
  500%!  {}(+Where) is semidet.
  501%!  rdf_where(+Where) is semidet.
  502%
  503%   Formulate constraints on RDF terms,  notably literals. These are
  504%   intended to be used as illustrated   below.  RDF constraints are
  505%   pure: they may be placed before, after or inside a graph pattern
  506%   and, provided the code contains no  _commit_ operations (!, ->),
  507%   the  semantics  of  the  goal   remains  the  same.  Preferably,
  508%   constraints are placed _before_ the graph  pattern as they often
  509%   help the RDF database to  exploit   its  literal indexes. In the
  510%   example below, the database can choose between using the subject
  511%   and/or predicate hash or the ordered literal table.
  512%
  513%     ==
  514%         { Date >= "2000-01-01"^^xsd:dateTime },
  515%         rdf(S, P, Date)
  516%     ==
  517%
  518%   The following constraints are currently defined:
  519%
  520%     - >, >=, ==, =<, <
  521%       The comparison operators are defined between numbers (of any
  522%       recognised type), typed literals of the same type and
  523%       langStrings of the same language.
  524%     - prefix(String, Pattern)
  525%     - substring(String, Pattern)
  526%     - word(String, Pattern)
  527%     - like(String, Pattern)
  528%     - icase(String, Pattern)
  529%       Text matching operators that act on both typed literals
  530%       and langStrings.
  531%     - lang_matches(Term, Pattern)
  532%       Demands a full RDF term (Text@Lang) or a plain `Lang` term
  533%       to match the language pattern Pattern.
  534%
  535%   The  predicates  rdf_where/1  and  {}/1    are   identical.  The
  536%   rdf_where/1  variant  is  provided   to    avoid   ambiguity  in
  537%   applications where {}/1 is used for other purposes. Note that it
  538%   is also possible to write `rdf11:{...}`.
  539
  540{}(Where) :-
  541    rdf_where(Where).
  542
  543rdf_where(Var) :-
  544    var(Var),
  545    !,
  546    instantiation_error(Var).
  547rdf_where((A,B)) :-
  548    !,
  549    rdf_where(A),
  550    rdf_where(B).
  551rdf_where(Constraint) :-
  552    rdf_constraint(Constraint, Goal),
  553    !,
  554    call(Goal).
  555rdf_where(Constraint) :-
  556    existence_error(rdf_constraint, Constraint).
  557
  558% Comparison operators
  559rdf_constraint(Term >= Value,
  560               add_value_constraint(Term, >=, Value)).
  561rdf_constraint(Term >  Value,
  562               add_value_constraint(Term, >,  Value)).
  563rdf_constraint(Term == Value,
  564               add_value_constraint(Term, ==,  Value)).
  565rdf_constraint(Term <  Value,
  566               add_value_constraint(Term, <,  Value)).
  567rdf_constraint(Term =< Value,
  568               add_value_constraint(Term, =<, Value)).
  569% String selection
  570rdf_constraint(prefix(Term, Pattern),
  571               add_text_constraint(Term, prefix(PatternA))) :-
  572    atom_string(PatternA, Pattern).
  573rdf_constraint(substring(Term, Pattern),
  574               add_text_constraint(Term, substring(PatternA))) :-
  575    atom_string(PatternA, Pattern).
  576rdf_constraint(word(Term, Pattern),
  577               add_text_constraint(Term, word(PatternA))) :-
  578    atom_string(PatternA, Pattern).
  579rdf_constraint(like(Term, Pattern),
  580               add_text_constraint(Term, like(PatternA))) :-
  581    atom_string(PatternA, Pattern).
  582rdf_constraint(icase(Term, Pattern),
  583               add_text_constraint(Term, icase(PatternA))) :-
  584    atom_string(PatternA, Pattern).
  585% Lang selection
  586rdf_constraint(lang_matches(Term, Pattern),
  587               add_lang_constraint(Term, lang_matches(Pattern))).
  588
  589add_text_constraint(Var, Cond) :-
  590    var(Var),
  591    !,
  592    (   get_attr(Var, rdf11, Cond0)
  593    ->  put_attr(Var, rdf11, [Cond|Cond0])
  594    ;   put_attr(Var, rdf11, [Cond])
  595    ).
  596add_text_constraint(Text^^_Type, Cond) :-
  597    !,
  598    add_text_constraint(Text, Cond).
  599add_text_constraint(Text@_Lang, Cond) :-
  600    !,
  601    add_text_constraint(Text, Cond).
  602add_text_constraint(Var, Cond) :-
  603    eval_condition(Cond, Var).
  604
  605%!  add_lang_constraint(?Term, +Constraint)
  606%
  607%   Add a constraint on the language of a literal
  608
  609add_lang_constraint(Var, Constraint) :-
  610    var(Var),
  611    !,
  612    (   get_attr(Var, rdf11, Cond0)
  613    ->  put_attr(Var, rdf11, [Constraint|Cond0])
  614    ;   put_attr(Var, rdf11, [Constraint])
  615    ).
  616add_lang_constraint(_Text@Lang, Constraint) :-
  617    !,
  618    add_lang_constraint(Lang, Constraint).
  619add_lang_constraint(_Text^^_Type, _Constraint) :-
  620    !,
  621    fail.
  622add_lang_constraint(Term, Constraint) :-
  623    eval_condition(Constraint, Term).
  624
  625%!  add_value_constraint(?Term, +Constraint, +Value)
  626%
  627%   Apply a value constraint to the RDF Term.
  628
  629add_value_constraint(Term, Constraint, ValueIn) :-
  630    constraint_literal_value(ValueIn, Value),
  631    add_value_constraint_cann(Value, Constraint, Term).
  632
  633constraint_literal_value(Value, Value^^_Type) :-
  634    number(Value),
  635    !.
  636constraint_literal_value(Value, Literal) :-
  637    rdf_canonical_literal(Value, Literal).
  638
  639add_value_constraint_cann(RefVal^^Type, Constraint, Term) :-
  640    var(Term), var(Type),
  641    !,
  642    add_text_constraint(Term, value(Constraint, RefVal, Type)).
  643add_value_constraint_cann(RefVal^^Type, Constraint, Val^^Type2) :-
  644    !,
  645    Type = Type2,
  646    add_text_constraint(Val, value(Constraint, RefVal, Type)).
  647add_value_constraint_cann(RefVal@Lang, Constraint, Val@Lang) :-
  648    !,
  649    add_text_constraint(Val, value(Constraint, RefVal, lang(Lang))).
  650add_value_constraint_cann(RefVal^^Type, Constraint, Val) :-
  651    !,
  652    ground(Val),
  653    Val \= _@_,
  654    eval_condition(value(Constraint, RefVal, Type), Val).
  655
  656put_cond(Var, []) :-
  657    !,
  658    del_attr(Var, rdf11).
  659put_cond(Var, List) :-
  660    put_attr(Var, rdf11, List).
  661
  662eval_condition(Cond, Literal) :-
  663    text_condition(Cond),
  664    !,
  665    text_of(Literal, Text),
  666    text_condition(Cond, Text).
  667eval_condition(Cond, Literal) :-
  668    lang_condition(Cond),
  669    !,
  670    lang_of(Literal, Lang),
  671    lang_condition(Cond, Lang).
  672eval_condition(value(Comp, Ref, _Type), Value) :-
  673    (   number(Ref)
  674    ->  number(Value),
  675        compare_numeric(Comp, Ref, Value)
  676    ;   compare_std(Comp, Ref, Value)
  677    ).
  678
  679compare_numeric(<,  Ref, Value) :- Value  < Ref.
  680compare_numeric(=<, Ref, Value) :- Value =< Ref.
  681compare_numeric(==, Ref, Value) :- Value =:= Ref.
  682compare_numeric(>=, Ref, Value) :- Value >= Ref.
  683compare_numeric( >, Ref, Value) :- Value >  Ref.
  684
  685compare_std(<,  Ref, Value) :- Value  @< Ref.
  686compare_std(=<, Ref, Value) :- Value @=< Ref.
  687compare_std(==, Ref, Value) :- Value ==  Ref.
  688compare_std(>=, Ref, Value) :- Value @>= Ref.
  689compare_std( >, Ref, Value) :- Value @>  Ref.
  690
  691text_condition(prefix(_)).
  692text_condition(substring(_)).
  693text_condition(word(_)).
  694text_condition(like(_)).
  695text_condition(icase(_)).
  696
  697text_of(Literal, Text) :-
  698    atomic(Literal),
  699    !,
  700    Text = Literal.
  701text_of(Text@_Lang, Text).
  702text_of(Text^^_Type, Text).
  703
  704text_condition(prefix(Pattern), Text) :-
  705    rdf_match_label(prefix, Pattern, Text).
  706text_condition(substring(Pattern), Text) :-
  707    rdf_match_label(substring, Pattern, Text).
  708text_condition(word(Pattern), Text) :-
  709    rdf_match_label(word, Pattern, Text).
  710text_condition(like(Pattern), Text) :-
  711    rdf_match_label(like, Pattern, Text).
  712text_condition(icase(Pattern), Text) :-
  713    rdf_match_label(icase, Pattern, Text).
  714
  715lang_condition(lang_matches(_)).
  716
  717lang_of(_Text@Lang0, Lang) :-
  718    !,
  719    Lang = Lang0.
  720lang_of(Lang, Lang) :-
  721    atom(Lang).
  722
  723lang_condition(lang_matches(Pattern), Lang) :-
  724    rdf_db:lang_matches(Lang, Pattern).
  725
  726%!  literal_condition(+Object, -Cond) is semidet.
  727%
  728%   True when some of the constraints   on  Object can be translated
  729%   into an equivalent query  of   the  form  literal(Cond, _Value).
  730%   Translated constraints are removed from object.
  731
  732literal_condition(Object, Cond) :-
  733    var(Object),
  734    !,
  735    get_attr(Object, rdf11, Cond0),
  736    best_literal_cond(Cond0, Cond, Rest),
  737    put_cond(Object, Rest).
  738literal_condition(Text@_Lang, Cond) :-
  739    get_attr(Text, rdf11, Cond0),
  740    !,
  741    best_literal_cond(Cond0, Cond, Rest),
  742    put_cond(Text, Rest).
  743literal_condition(Text^^_Type, Cond) :-
  744    get_attr(Text, rdf11, Cond0),
  745    best_literal_cond(Cond0, Cond, Rest),
  746    put_cond(Text, Rest).
  747
  748%!  best_literal_cond(+Conditions, -Best, -Rest) is semidet.
  749%
  750%   Extract the constraints that can be translated into the _Search_
  751%   of literal(Search, Value).
  752%
  753%   @tbd    Select the best rather than the first.
  754
  755best_literal_cond(Conditions, Best, Rest) :-
  756    sort(Conditions, Unique),
  757    best_literal_cond2(Unique, Best, Rest).
  758
  759best_literal_cond2(Conds, Best, Rest) :-
  760    select(Cond, Conds, Rest0),
  761    rdf10_cond(Cond, Best, Rest0, Rest),
  762    !.
  763
  764rdf10_cond(value(=<, URef, UType), Cond, Rest0, Rest) :-
  765    (   select(value(>=, LRef, LType), Rest0, Rest)
  766    ->  true
  767    ;   memberchk(value(>, LRef, LType), Rest0)
  768    ->  Rest = Rest0
  769    ),
  770    !,
  771    in_constaint_type(LType, SLType, LRef, LRef0),
  772    in_constaint_type(UType, SUType, URef, URef0),
  773    Cond = between(type(SLType, LRef0), type(SUType, URef0)).
  774rdf10_cond(value(<, URef, UType), Cond, Rest0, Rest) :-
  775    (   select(value(>=, LRef, LType), Rest0, Rest1)
  776    ->  true
  777    ;   memberchk(value(>, LRef, LType), Rest0)
  778    ->  Rest1 = Rest0
  779    ),
  780    !,
  781    Rest = [value(<, URef, UType)|Rest1],
  782    in_constaint_type(LType, SLType, LRef, LRef0),
  783    in_constaint_type(UType, SUType, URef, URef0),
  784    Cond = between(type(SLType, LRef0), type(SUType, URef0)).
  785rdf10_cond(value(Cmp, Ref, Type), Pattern, Rest, Rest) :-
  786    !,
  787    rdf10_compare(Cmp, Ref, Type, Pattern).
  788rdf10_cond(lang_matches(_), _, _, _) :- !, fail.
  789rdf10_cond(Cond, Cond, Rest, Rest).
  790
  791rdf10_compare(Cmp, Ref, Type, Pattern) :-
  792    nonvar(Type), Type = lang(Lang),
  793    !,
  794    atom_string(Ref0, Ref),
  795    rdf10_lang_cond(Cmp, Ref0, Lang, Pattern).
  796rdf10_compare(Cmp, Ref, Type, Pattern) :-
  797    in_constaint_type(Type, SType, Ref, Ref0),
  798    rdf10_type_cond(Cmp, Ref0, SType, Pattern).
  799
  800rdf10_lang_cond( <, Ref, Lang, lt(lang(Lang,Ref))).
  801rdf10_lang_cond(=<, Ref, Lang, le(lang(Lang,Ref))).
  802rdf10_lang_cond(==, Ref, Lang, eq(lang(Lang,Ref))).
  803rdf10_lang_cond(>=, Ref, Lang, ge(lang(Lang,Ref))).
  804rdf10_lang_cond(>,  Ref, Lang, gt(lang(Lang,Ref))).
  805
  806rdf10_type_cond( <, Ref, Type, lt(type(Type,Ref))).
  807rdf10_type_cond(=<, Ref, Type, le(type(Type,Ref))).
  808rdf10_type_cond(==, Ref, Type, eq(type(Type,Ref))).
  809rdf10_type_cond(>=, Ref, Type, ge(type(Type,Ref))).
  810rdf10_type_cond( >, Ref, Type, gt(type(Type,Ref))).
  811
  812
  813%!  in_constaint_type(?Type, -SType, ++Val, -Val0)
  814
  815in_constaint_type(Type, SType, Val, Val0) :-
  816    nonvar(Type), ground(Val),
  817    !,
  818    SType = Type,
  819    in_ground_type(Type, Val, Val0).
  820in_constaint_type(Type, SType, Val, Val0) :-
  821    var(Type), number(Val),
  822    !,
  823    (   integer(Val)
  824    ->  rdf_equal(SType, xsd:integer),
  825        in_ground_type(xsd:integer, Val, Val0)
  826    ;   float(Val)
  827    ->  rdf_equal(SType, xsd:double),
  828        in_ground_type(xsd:double, Val, Val0)
  829    ;   assertion(fail)
  830    ).
  831
  832
  833%!  literal_class(+Term, -Class)
  834%
  835%   Classify Term as literal  and  if   possible  as  lang  or typed
  836%   literal on the basis of the constraints that apply to it.
  837
  838literal_class(Term, Class) :-
  839    get_attr(Term, rdf11, Conds),
  840    select(Cond, Conds, Rest),
  841    lang_condition(Cond),
  842    !,
  843    Term = Text@Lang,
  844    put_attr(Lang, rdf11, [Cond]),
  845    put_cond(Text, Rest),
  846    (   var(Text)
  847    ->  true
  848    ;   atom_string(Text2, Text)
  849    ),
  850    Class = lang(Lang, Text2).
  851
  852%!  attr_unify_hook(+AttributeValue, +Value)
  853
  854attr_unify_hook(Cond, Value) :-
  855    get_attr(Value, rdf11, Cond2),
  856    !,
  857    append(Cond, Cond2, CondJ),
  858    sort(CondJ, Unique),
  859    put_cond(Value, Unique).
  860attr_unify_hook(Cond, Text^^_Type) :-
  861    var(Text),
  862    !,
  863    put_cond(Text, Cond).
  864attr_unify_hook(Cond, Text@Lang) :-
  865    var(Text), var(Lang),
  866    !,
  867    partition(lang_condition, Cond, LangCond, TextCond),
  868    put_cond(Text, TextCond),
  869    put_cond(Lang, LangCond).
  870attr_unify_hook(Cond, Value) :-
  871    sort(Cond, Unique),
  872    propagate_conditions(Unique, Value).
  873
  874propagate_conditions([], _).
  875propagate_conditions([H|T], Val) :-
  876    propagate_condition(H, Val),
  877    propagate_conditions(T, Val).
  878
  879propagate_condition(value(Comp, Ref, Type), Value) :-
  880    !,
  881    (   Value = Plain^^VType
  882    ->  VType = Type
  883    ;   Plain = Value
  884    ),
  885    cond_compare(Comp, Ref, Plain).
  886propagate_condition(lang_matches(Pattern), Value) :-
  887    !,
  888    (   Value = _@Lang
  889    ->  true
  890    ;   Lang = Value
  891    ),
  892    rdf_db:lang_matches(Lang, Pattern).
  893propagate_condition(Cond, Value) :-
  894    Cond =.. [Name|Args],
  895    Constraint =.. [Name,Value|Args],
  896    rdf_constraint(Constraint, Continuation),
  897    call(Continuation).
  898
  899cond_compare(>,  Ref, Value) :- Value @>  Ref.
  900cond_compare(>=, Ref, Value) :- Value @>= Ref.
  901cond_compare(==, Ref, Value) :- Value ==  Ref.
  902cond_compare(=<, Ref, Value) :- Value @=< Ref.
  903cond_compare( <, Ref, Value) :- Value  @< Ref.
  904
  905
  906%!  rdf_default_graph(-Graph) is det.
  907%!  rdf_default_graph(-Old, +New) is det.
  908%
  909%   Query/set the notion of the  default   graph.  The notion of the
  910%   default graph is local to a  thread. Threads created inherit the
  911%   default graph from their creator. See set_prolog_flag/2.
  912
  913:- create_prolog_flag(rdf_default_graph, default,
  914                      [ type(atom),
  915                        keep(true)
  916                      ]).  917
  918rdf_default_graph(Graph) :-
  919    current_prolog_flag(rdf_default_graph, Graph).
  920rdf_default_graph(Old, New) :-
  921    current_prolog_flag(rdf_default_graph, Old),
  922    (   New == Old
  923    ->  true
  924    ;   set_prolog_flag(rdf_default_graph, New)
  925    ).
  926
  927
  928pre_graph(G, _G0) :-
  929    var(G),
  930    !.
  931pre_graph(G, G) :-
  932    atom(G),
  933    !.
  934pre_graph(G, _) :-
  935    type_error(rdf_graph, G).
  936
  937post_graph(G, G0:_) :-
  938    !,
  939    G = G0.
  940post_graph(G, G).
  941
  942
  943pre_object(Literal, literal(Cond, Value)) :-
  944    literal_condition(Literal, Cond),
  945    !,
  946    debug(literal_index, 'Search literal using ~p', [literal(Cond, Value)]),
  947    literal_value0(Literal, Value).
  948pre_object(Literal, literal(Value)) :-
  949    literal_class(Literal, Value),
  950    !,
  951    debug(literal_index, 'Search literal using ~p', [literal(Value)]).
  952pre_object(Var, _Var) :-
  953    var(Var),
  954    !.
  955pre_object(Atom, URI) :-
  956    atom(Atom),
  957    \+ boolean(Atom),
  958    !,
  959    URI = Atom.
  960pre_object(Val@Lang, literal(lang(Lang, Val0))) :-
  961    !,
  962    in_lang_string(Val, Val0).
  963pre_object(Val^^Type, literal(Literal)) :-
  964    !,
  965    in_type(Type, Val, Type0, Val0),
  966    (   var(Type0), var(Val0)
  967    ->  true
  968    ;   Literal = type(Type0, Val0)
  969    ).
  970pre_object(Obj, Val0) :-
  971    ground(Obj),
  972    !,
  973    pre_ground_object(Obj, Val0).
  974pre_object(Obj, _) :-
  975    type_error(rdf_object, Obj).
  976
  977literal_value0(Var, _) :-
  978    var(Var),
  979    !.
  980literal_value0(_ @Lang, lang(Lang, _)).
  981literal_value0(_^^Type, type(Type, _)).
  982
  983
  984%!  pre_ground_object(+Object, -RDF) is det.
  985%
  986%   Convert between a Prolog value and an RDF value for rdf_assert/3
  987%   and friends.  Auto-conversion:
  988%
  989%     - Integer
  990%     Converted to Integer^^xsd:integer
  991%     - Float
  992%     Converted to Float^^xsd:double
  993%     - String
  994%     Converted to String^^xsd:string
  995%     - true
  996%     Converted to true^^xsd:boolean
  997%     - false
  998%     Converted to false^^xsd:boolean
  999%     - Text@Lang
 1000%     Converted to Text@Lang.  Uses canonical (lowercase) lang.
 1001%     Text is converted into an atom.
 1002%     - Value^^Type
 1003%     Typed conversion.  The translation of Value depends on
 1004%     Type:
 1005%       - Numeric types
 1006%       - Boolean
 1007%       - Date types
 1008%     - Atom
 1009%     All atoms except for `true` and `false` are considered
 1010%     URIs.
 1011
 1012:- rdf_meta
 1013    pre_ground_object(+, o). 1014
 1015pre_ground_object(Int, Object) :-
 1016    integer(Int),
 1017    !,
 1018    rdf_equal(Object, literal(type(xsd:integer, Atom))),
 1019    atom_number(Atom, Int).
 1020pre_ground_object(Float, Object) :-
 1021    float(Float),
 1022    !,
 1023    rdf_equal(Object, literal(type(xsd:double, Atom))),
 1024    xsd_number_string(Float, String),
 1025    atom_string(Atom, String).
 1026pre_ground_object(String, Object) :-
 1027    string(String),
 1028    !,
 1029    rdf_equal(Object, literal(type(xsd:string, Atom))),
 1030    atom_string(Atom, String).
 1031pre_ground_object(false, literal(type(xsd:boolean, false))) :- !.
 1032pre_ground_object(true, literal(type(xsd:boolean, true))) :- !.
 1033pre_ground_object(Val@Lang,  literal(lang(Lang0, Val0))) :-
 1034    !,
 1035    downcase_atom(Lang, Lang0),
 1036    in_lang_string(Val, Val0).
 1037pre_ground_object(Val^^Type, literal(type(Type0, Val0))) :-
 1038    !,
 1039    in_type(Type, Val, Type0, Val0).
 1040pre_ground_object(Atom, URI) :-
 1041    atom(Atom),
 1042    !,
 1043    URI = Atom.
 1044%pre_ground_object(NS:Local, URI) :-            % still leaves S and P.
 1045%       atom(NS), atom(Local), !,
 1046%       rdf_global_id(NS:Local, URI).
 1047pre_ground_object(literal(Lit0), literal(Lit)) :-
 1048    old_literal(Lit0, Lit),
 1049    !.
 1050pre_ground_object(Value, _) :-
 1051    type_error(rdf_object, Value).
 1052
 1053old_literal(Lit0, Lit) :-
 1054    old_literal(Lit0),
 1055    !,
 1056    Lit = Lit0.
 1057old_literal(Atom, Lit) :-
 1058    atom(Atom),
 1059    rdf_equal(xsd:string, XSDString),
 1060    Lit = type(XSDString, Atom).
 1061
 1062old_literal(type(Type, Value)) :-
 1063    atom(Type), atom(Value).
 1064old_literal(lang(Lang, Value)) :-
 1065    atom(Lang), atom(Value).
 1066
 1067in_lang_string(Val, Val0) :-
 1068    atomic(Val),
 1069    !,
 1070    atom_string(Val0, Val).
 1071in_lang_string(_, _).
 1072
 1073in_type(Type, Val, Type, Val0) :-
 1074    nonvar(Type), ground(Val),
 1075    !,
 1076    in_ground_type(Type, Val, Val0).
 1077in_type(VarType, Val, VarType, Val0) :-
 1078    ground(Val),
 1079    \+ catch(xsd_number_string(_, Val), _, fail),
 1080    !,
 1081    atom_string(Val0, Val).
 1082in_type(_, _, _, _).
 1083
 1084:- rdf_meta
 1085    in_ground_type(r,?,?),
 1086    in_date_component(r, +, +, -). 1087
 1088%!  in_ground_type(+Type, +Input, -Lexical:atom) is det.
 1089%
 1090%   Translate the Prolog date Input according   to Type into its RDF
 1091%   lexical form. The lecical form  is   represented  as an atom. In
 1092%   future versions this is likely to become a string.
 1093
 1094in_ground_type(Type, Input, Lex) :-
 1095    \+ string(Input),
 1096    in_ground_type_hook(Type, Input, Lex),
 1097    !.
 1098in_ground_type(IntType, Val, Val0) :-
 1099    xsd_numerical(IntType, Domain, PrologType),
 1100    !,
 1101    in_number(PrologType, Domain, IntType, Val, Val0).
 1102in_ground_type(xsd:boolean, Val, Val0) :-
 1103    !,
 1104    (   in_boolean(Val, Val0)
 1105    ->  true
 1106    ;   type_error(rdf_boolean, Val)
 1107    ).
 1108in_ground_type(rdf:langString, _Val0, _) :-
 1109    !,
 1110    domain_error(rdf_data_type, rdf:langString).
 1111in_ground_type(DateTimeType, Val, Val0) :-
 1112    xsd_date_time_type(DateTimeType),
 1113    !,
 1114    in_date_time(DateTimeType, Val, Val0).
 1115in_ground_type(rdf:'XMLLiteral', Val, Val0) :-
 1116    !,
 1117    in_xml_literal(xml, Val, Val0).
 1118in_ground_type(rdf:'HTML', Val, Val0) :-
 1119    !,
 1120    in_xml_literal(html, Val, Val0).
 1121in_ground_type(_Unknown, Val, Val0) :-
 1122    atom_string(Val0, Val).
 1123
 1124%!  in_date_time(+Type, +Input, -Lexical) is det.
 1125%
 1126%   Accepts either a term as  accepted   by  xsd_time_string/3  or a
 1127%   valid string for the corresponding XSD type.
 1128
 1129:- rdf_meta
 1130    in_date_time(r,+,-). 1131
 1132in_date_time(Type, Text, Text0) :-
 1133    atom(Text),
 1134    !,
 1135    xsd_time_string(_, Type, Text),
 1136    Text0 = Text.
 1137in_date_time(Type, Text, Text0) :-
 1138    string(Text),
 1139    !,
 1140    xsd_time_string(_, Type, Text),
 1141    atom_string(Text0, Text).
 1142in_date_time(xsd:dateTime, Stamp, Text0) :-
 1143    number(Stamp),
 1144    !,
 1145    format_time(atom(Text0), '%FT%T%:z', Stamp).
 1146in_date_time(Type, Term, Text0) :-
 1147    !,
 1148    xsd_time_string(Term, Type, String),
 1149    atom_string(Text0, String).
 1150
 1151
 1152%!  in_boolean(?NonCanonical, ?Canonical)
 1153%
 1154%   True when Canonical is the canonical boolean for NonCanonical.
 1155
 1156in_boolean(true,    true).
 1157in_boolean(false,   false).
 1158in_boolean("true",  true).
 1159in_boolean("false", false).
 1160in_boolean(1,       true).
 1161in_boolean(0,       false).
 1162
 1163boolean(false).
 1164boolean(true).
 1165
 1166%!  in_number(+PrologType, +Domain, +XSDType, +Value, -Lexical)
 1167%
 1168%   Lexical is the lexical representation for Value.
 1169%
 1170%   @error  type_error(PrologType, Value)
 1171%   @error  domain_error(XSDType, Value)
 1172
 1173in_number(integer, Domain, XSDType, Val, Val0) :-
 1174    integer(Val),
 1175    !,
 1176    check_integer_domain(Domain, XSDType, Val),
 1177    atom_number(Val0, Val).
 1178in_number(integer, Domain, XSDType, Val, Val0) :-
 1179    atomic(Val),
 1180    atom_number(Val, Num),
 1181    integer(Num),
 1182    !,
 1183    check_integer_domain(Domain, XSDType, Num),
 1184    atom_number(Val0, Num).
 1185in_number(double, _Domain, _, Val, Val0) :-
 1186    number(Val),
 1187    !,
 1188    ValF is float(Val),
 1189    xsd_number_string(ValF, ValS),
 1190    atom_string(Val0, ValS).
 1191in_number(double, _Domain, _, Val, Val0) :-
 1192    atomic(Val),
 1193    xsd_number_string(Num, Val),
 1194    ValF is float(Num),
 1195    !,
 1196    xsd_number_string(ValF, ValS),
 1197    atom_string(Val0, ValS).
 1198in_number(PrologType, _, _, Val, _) :-
 1199    type_error(PrologType, Val).
 1200
 1201check_integer_domain(PLType, _, Val) :-
 1202    is_of_type(PLType, Val),
 1203    !.
 1204check_integer_domain(_, XSDType, Val) :-
 1205    domain_error(XSDType, Val).
 1206
 1207error:has_type(nonpos, T):-
 1208    integer(T),
 1209    T =< 0.
 1210
 1211%check_integer_domain(between(Low, High), XSDType, Val) :-
 1212%       (   between(Low, High, Val)
 1213%       ->  true
 1214%       ;   domain_error(XSDType, Val)
 1215%       ).
 1216%check_integer_domain(integer, _, _).
 1217
 1218%!  xsd_numerical(?URI, ?TypeCheck, ?PrologType)
 1219
 1220:- rdf_meta
 1221    xsd_numerical(r, ?, ?). 1222
 1223xsd_numerical(xsd:byte,               between(-128,127),               integer).
 1224xsd_numerical(xsd:double,             float,                           double).
 1225xsd_numerical(xsd:decimal,            float,                           double).
 1226xsd_numerical(xsd:float,              float,                           double).
 1227xsd_numerical(xsd:int,                between(-2147483648,2147483647), integer).
 1228xsd_numerical(xsd:integer,            integer,                         integer).
 1229xsd_numerical(xsd:long,               between(-9223372036854775808,
 1230                                               9223372036854775807),   integer).
 1231xsd_numerical(xsd:negativeInteger,    negative_integer,                integer).
 1232xsd_numerical(xsd:nonNegativeInteger, nonneg,                          integer).
 1233xsd_numerical(xsd:nonPositiveInteger, nonpos,                          integer).
 1234xsd_numerical(xsd:positiveInteger,    positive_integer,                integer).
 1235xsd_numerical(xsd:short,              between(-32768,32767),           integer).
 1236xsd_numerical(xsd:unsignedByte,       between(0,255),                  integer).
 1237xsd_numerical(xsd:unsignedInt,        between(0,4294967295),           integer).
 1238xsd_numerical(xsd:unsignedLong,       between(0,18446744073709551615), integer).
 1239xsd_numerical(xsd:unsignedShort,      between(0,65535),                integer).
 1240
 1241%!  xsd_date_time_type(?URI)
 1242%
 1243%   True when URI is an XSD date or time type.
 1244
 1245:- rdf_meta
 1246    xsd_date_time_type(r). 1247
 1248xsd_date_time_type(xsd:date).
 1249xsd_date_time_type(xsd:dateTime).
 1250xsd_date_time_type(xsd:gDay).
 1251xsd_date_time_type(xsd:gMonth).
 1252xsd_date_time_type(xsd:gMonthDay).
 1253xsd_date_time_type(xsd:gYear).
 1254xsd_date_time_type(xsd:gYearMonth).
 1255xsd_date_time_type(xsd:time).
 1256
 1257
 1258%!  in_xml_literal(+Type, +Val, -Val0) is det.
 1259%
 1260%   Translate an XMLLiteral or HTML literal to its canonical textual
 1261%   representation. Input is either text or a Prolog XML DOM.
 1262%
 1263%   @tbd    Deal with partial content?
 1264
 1265in_xml_literal(Type, Val, Val0) :-
 1266    xml_is_dom(Val),
 1267    !,
 1268    write_xml_literal(Type, Val, Val0).
 1269in_xml_literal(xml, Val, Val0) :-
 1270    parse_partial_xml(load_xml, Val, DOM),
 1271    write_xml_literal(xml, DOM, Val0).
 1272in_xml_literal(html, Val, Val0) :-
 1273    parse_partial_xml(load_html, Val, DOM),
 1274    write_xml_literal(html, DOM, Val0).
 1275
 1276parse_partial_xml(Parser, Val, DOM) :-
 1277    setup_call_cleanup(
 1278        new_memory_file(MF),
 1279        (   setup_call_cleanup(
 1280                open_memory_file(MF, write, Out),
 1281                format(Out, "<xml>~w</xml>", [Val]),
 1282                close(Out)),
 1283            setup_call_cleanup(
 1284                open_memory_file(MF, read, In),
 1285                call(Parser, stream(In), [element(xml, _, DOM)], []),
 1286                close(In))
 1287        ),
 1288        free_memory_file(MF)).
 1289
 1290
 1291write_xml_literal(xml, DOM, Text) :-
 1292    with_output_to(atom(Text),
 1293                   xml_write_canonical(current_output, DOM, [])).
 1294write_xml_literal(html, DOM, Text) :-
 1295    with_output_to(atom(Text),
 1296                   html_write(current_output, DOM,
 1297                              [ header(false),
 1298                                layout(false)
 1299                              ])).
 1300
 1301%!  rdf_canonical_literal(++In, -Literal) is det.
 1302%
 1303%   Transform  a  relaxed  literal  specification   as  allowed  for
 1304%   rdf_assert/3 into its canonical form. The following Prolog terms
 1305%   are translated:
 1306%
 1307%   | **Prolog Term**               | **Datatype IRI** |
 1308%   |:------------------------------|:-----------------|
 1309%   | float                         | xsd:double       |
 1310%   | integer                       | xsd:integer      |
 1311%   | string                        | xsd:string       |
 1312%   | `true` or `false`             | xsd:boolean      |
 1313%   | date(Y,M,D)                   | xsd:date         |
 1314%   | date_time(Y,M,D,HH,MM,SS)     | xsd:dateTime     |
 1315%   | date_time(Y,M,D,HH,MM,SS,TZ)  | xsd:dateTime     |
 1316%   | month_day(M,D)                | xsd:gMonthDay    |
 1317%   | year_month(Y,M)               | xsd:gYearMonth   |
 1318%   | time(HH,MM,SS)                | xsd:time         |
 1319%
 1320%   For example:
 1321%
 1322%     ```
 1323%     ?- rdf_canonical_literal(42, X).
 1324%     X = 42^^'http://www.w3.org/2001/XMLSchema#integer'.
 1325%     ```
 1326
 1327rdf_canonical_literal(In, Literal) :-
 1328    ground(In),
 1329    !,
 1330    pre_ground_object(In, DBTerm),
 1331    post_object(Literal, DBTerm).
 1332rdf_canonical_literal(In, _) :-
 1333    must_be(ground, In).
 1334
 1335%!  rdf_lexical_form(++Literal, -Lexical:compound) is det.
 1336%
 1337%   True when Lexical is the lexical   form for the literal Literal.
 1338%   Lexical is of one of the forms below. The ntriples serialization
 1339%   is obtained by transforming String into a proper ntriples string
 1340%   using double quotes and escaping where   needed and turning Type
 1341%   into a proper IRI reference.
 1342%
 1343%     - String^^Type
 1344%     - String@Lang
 1345
 1346%       For example,
 1347%
 1348%       ==
 1349%       ?- rdf_lexical_form(2.3^^xsd:double, L).
 1350%       L = "2.3E0"^^'http://www.w3.org/2001/XMLSchema#double'.
 1351%       ==
 1352
 1353rdf_lexical_form(Literal, Lexical) :-
 1354    pre_ground_object(Literal, literal(Lit0)),
 1355    !,
 1356    text_of0(Lit0, Lexical).
 1357rdf_lexical_form(Literal, _) :-
 1358    type_error(rdf_literal, Literal).
 1359
 1360text_of0(type(TypeA, LexicalA), LexicalS^^TypeA) :-
 1361    atom_string(LexicalA, LexicalS).
 1362text_of0(lang(LangA, LexicalA), LexicalS@LangA) :-
 1363    atom_string(LexicalA, LexicalS).
 1364
 1365
 1366                 /*******************************
 1367                 *       POST PROCESSING        *
 1368                 *******************************/
 1369
 1370:- rdf_meta
 1371    post_object(o,o),
 1372    out_type(r,-,+). 1373
 1374post_object(Val, _) :-
 1375    ground(Val),
 1376    !.                 % already specified and matched
 1377post_object(URI, URI0) :-
 1378    atom(URI0),
 1379    !,
 1380    URI = URI0.
 1381post_object(Val@Lang, literal(lang(Lang, Val0))) :-
 1382    nonvar(Lang),          % lang(Lang,Text) returns var(Lang) if no lang
 1383    !,
 1384    atom_string(Val0, Val).
 1385post_object(Val^^Type, literal(type(Type, Val0))) :-
 1386    !,
 1387    out_type(Type, Val, Val0).
 1388post_object(Val^^xsd:string, literal(Plain)) :-
 1389    !,
 1390    atomic(Plain),
 1391    atom_string(Plain, Val).
 1392post_object(Val@Lang, literal(_, lang(Lang, Val0))) :-
 1393    nonvar(Lang),
 1394    !,
 1395    atom_string(Val0, Val).
 1396post_object(Val^^Type, literal(_, type(Type, Val0))) :-
 1397    !,
 1398    out_type(Type, Val, Val0).
 1399post_object(Val^^xsd:string, literal(_, Plain)) :-
 1400    atomic(Plain),
 1401    atom_string(Plain, Val).
 1402
 1403out_type(xsd:string, Val, Val0) :-     % catches unbound type too
 1404    !,
 1405    atom_string(Val0, Val).
 1406out_type(Type, Val, Val0) :-
 1407    out_type_hook(Type, Val, Val0),
 1408    !.
 1409out_type(IntType, Val, Val0) :-
 1410    xsd_numerical(IntType, _Domain, _BasicType),
 1411    !,
 1412    xsd_number_string(Val, Val0).
 1413out_type(DateTimeType, Val, Val0) :-
 1414    xsd_date_time_type(DateTimeType),
 1415    !,
 1416    out_date_time(DateTimeType, Val, Val0).
 1417out_type(xsd:boolean, Val, Val0) :-
 1418    !,
 1419    Val = Val0.
 1420out_type(rdf:'XMLLiteral', XML, DOM) :-
 1421    xml_is_dom(DOM),
 1422    !,
 1423    with_output_to(string(XML),
 1424                   xml_write(DOM, [header(false)])).
 1425out_type(_Unknown, Val, Val0) :-
 1426    atom_string(Val0, Val).
 1427
 1428
 1429%!  out_date_time(+DateTimeType, -Val, +Val0) is det.
 1430%
 1431%   Translate an XSD lexical form for   a date/time related datatype
 1432%   into the cannical form as defined by xsd_time_string/3.
 1433
 1434out_date_time(Type, Prolog, Lexical) :-
 1435    xsd_time_string(Prolog, Type, Lexical).
 1436
 1437
 1438                 /*******************************
 1439                 *          ENUMERATION         *
 1440                 *******************************/
 1441
 1442%!  rdf_term(?Term) is nondet.
 1443%
 1444%   True if Term appears in the RDF database. Term is either an iri,
 1445%   literal or blank node and may  appear   in  any  position of any
 1446%   triple. If Term is ground,  it   is  pre-processed as the object
 1447%   argument of rdf_assert/3 and the predicate is _semidet_.
 1448
 1449rdf_term(N) :-
 1450    ground(N),
 1451    !,
 1452    pre_object(N, N0),
 1453    visible_term(N0).
 1454rdf_term(N) :-
 1455    gen_term(N).
 1456
 1457gen_term(N) :-
 1458    resource(N),
 1459    visible_term(N).
 1460gen_term(O) :-                          % performs double conversion!
 1461    rdf_literal(O),
 1462    (rdf(_,_,O) -> true).
 1463
 1464%!  rdf_literal(?Term) is nondet.
 1465%
 1466%   True if Term is a  known  literal.   If  Term  is  ground, it is
 1467%   pre-processed as the object  argument   of  rdf_assert/3 and the
 1468%   predicate is _semidet_.
 1469
 1470rdf_literal(Term) :-
 1471    ground(Term),
 1472    !,
 1473    pre_ground_object(Term, Object),
 1474    (rdf_db:rdf(_,_,Object)->true).
 1475rdf_literal(Term) :-
 1476    pre_object(Term,literal(Lit0)),
 1477    rdf_db:rdf_current_literal(Lit0),
 1478    (rdf_db:rdf(_,_,literal(Lit0))->true),
 1479    post_object(Term, literal(Lit0)).
 1480
 1481%!  rdf_bnode(?BNode) is nondet.
 1482%
 1483%   True if BNode is a currently known  blank node. The predicate is
 1484%   _semidet_ if BNode is ground.
 1485
 1486rdf_bnode(BNode) :-
 1487    atom(BNode),
 1488    !,
 1489    current_bnode(BNode).
 1490rdf_bnode(BNode) :-
 1491    rdf_db:rdf_resource(BNode),
 1492    current_bnode(BNode).
 1493
 1494current_bnode(BNode) :-
 1495    rdf_is_bnode(BNode),
 1496    visible_node(BNode).            % Assumes BNodes cannot be predicates
 1497
 1498%!  rdf_iri(?IRI) is nondet.
 1499%
 1500%   True if IRI is a current IRI.  The predicate is _semidet_ if IRI
 1501%   is ground.
 1502
 1503rdf_iri(IRI) :-
 1504    atom(IRI),
 1505    !,
 1506    \+ rdf_is_bnode(IRI),
 1507    visible_term(IRI).
 1508rdf_iri(IRI) :-
 1509    resource(IRI),
 1510    \+ rdf_is_bnode(IRI),
 1511    visible_term(IRI).
 1512
 1513%!  rdf_name(?Name) is nondet.
 1514%
 1515%   True if Name is a  current  IRI   or  literal.  The predicate is
 1516%   _semidet_ if Name is ground.
 1517
 1518rdf_name(Name) :-
 1519    atom(Name), \+ boolean(Name),
 1520    !,
 1521    \+ rdf_is_bnode(Name),
 1522    visible_term(Name).
 1523rdf_name(Name) :-
 1524    ground(Name),
 1525    !,
 1526    pre_ground_object(Name, Name0),
 1527    (rdf_db:rdf(_,_,Name0)->true).
 1528rdf_name(Name) :-
 1529    rdf_iri(Name).
 1530rdf_name(Name) :-
 1531    rdf_literal(Name).
 1532
 1533%!  rdf_subject(?S) is nondet.
 1534%
 1535%   True when S is a currently known   _subject_, i.e. it appears in
 1536%   the subject position of some visible   triple.  The predicate is
 1537%   _semidet_ if S is ground.
 1538
 1539
 1540%!  rdf_predicate(?P) is nondet.
 1541%
 1542%   True when P is a currently known   predicate, i.e. it appears in
 1543%   the predicate position of some visible  triple. The predicate is
 1544%   _semidet_ if P is ground.
 1545
 1546rdf_predicate(P) :-
 1547    atom(P),
 1548    !,
 1549    (rdf(_,P,_) -> true).
 1550rdf_predicate(P) :-
 1551    rdf_db:rdf_current_predicate(P),
 1552    (rdf(_,P,_) -> true).
 1553
 1554%!  rdf_object(?O) is nondet.
 1555%
 1556%   True when O is a currently known  object, i.e. it appeasr in the
 1557%   object position of some visible triple. If Term is ground, it is
 1558%   pre-processed as the object  argument   of  rdf_assert/3 and the
 1559%   predicate is _semidet_.
 1560
 1561rdf_object(O) :-
 1562    ground(O),
 1563    !,
 1564    (   atom(O), \+ boolean(O)
 1565    ->  (rdf_db:rdf(_,_,O) -> true)
 1566    ;   rdf_literal(O)
 1567    ).
 1568rdf_object(O) :-
 1569    rdf_db:rdf_resource(O),
 1570    (rdf_db:rdf(_,_,O) -> true).
 1571rdf_object(O) :-
 1572    rdf_literal(O).
 1573
 1574%!  rdf_node(?T) is nondet.
 1575%
 1576%   True when T appears in the subject or object position of a known
 1577%   triple, i.e., is a node in the RDF graph.
 1578
 1579rdf_node(N) :-
 1580    var(N),
 1581    !,
 1582    gen_node(N).
 1583rdf_node(N) :-
 1584    pre_ground_object(N, N0),
 1585    visible_node(N0).
 1586
 1587gen_node(N) :-
 1588    rdf_db:rdf_resource(N),
 1589    visible_node(N).
 1590gen_node(O) :-                          % performs double conversion!
 1591    rdf_literal(O),
 1592    (rdf(_,_,O) -> true).
 1593
 1594%!  resource(?R)
 1595%
 1596%   True if R is a node that is not a literal. Note that RDF-DB does
 1597%   not necessarily include predicates in the set of resources. Also
 1598%   note that the resource may not really exist or be visible.
 1599
 1600resource(R) :-
 1601    var(R),
 1602    !,
 1603    gen_resource(R).
 1604resource(R) :-
 1605    rdf_db:rdf_resource(R),
 1606    !.
 1607resource(R) :-
 1608    rdf_db:rdf_current_predicate(R),
 1609    !.
 1610
 1611gen_resource(R) :-
 1612    rdf_db:rdf_resource(R).
 1613gen_resource(R) :-
 1614    rdf_db:rdf_current_predicate(R),
 1615    \+ rdf_db:rdf_resource(R).
 1616
 1617visible_node(Term) :-
 1618    atom(Term),
 1619    !,
 1620    (   rdf_db:rdf(Term,_,_)
 1621    ;   rdf_db:rdf(_,_,Term)
 1622    ),
 1623    !.
 1624visible_node(Term) :-
 1625    rdf_db:rdf(_,_,Term).
 1626
 1627visible_term(Term) :-
 1628    atom(Term),
 1629    !,
 1630    (   rdf_db:rdf(Term,_,_)
 1631    ;   rdf_db:rdf(_,Term,_)
 1632    ;   rdf_db:rdf(_,_,Term)
 1633    ),
 1634    !.
 1635visible_term(Term) :-
 1636    rdf_db:rdf(_,_,Term).
 1637
 1638%!  rdf_create_bnode(--BNode)
 1639%
 1640%   Create a new BNode. A  blank  node   is  an  atom  starting with
 1641%   =|_:|=. Blank nodes generated by this  predicate are of the form
 1642%   =|_:genid|= followed by a unique integer.
 1643
 1644rdf_create_bnode(BNode) :-
 1645    var(BNode),
 1646    !,
 1647    rdf_db:rdf_bnode(BNode).
 1648rdf_create_bnode(BNode) :-
 1649    uninstantiation_error(BNode).
 1650
 1651
 1652                 /*******************************
 1653                 *         TYPE CHECKING        *
 1654                 *******************************/
 1655
 1656%!  rdf_is_iri(@IRI) is semidet.
 1657%
 1658%   True if IRI is an RDF IRI term.
 1659%
 1660%   For performance reasons, this does not check for compliance to
 1661%   the syntax defined in [[RFC
 1662%   3987][http://www.ietf.org/rfc/rfc3987.txt]].  This checks
 1663%   whether the term is (1) an atom and (2) not a blank node
 1664%   identifier.
 1665%
 1666%   Success of this goal does not imply that the IRI is present in
 1667%   the database (see rdf_iri/1 for that).
 1668
 1669rdf_is_iri(IRI) :-
 1670    atom(IRI),
 1671    \+ rdf_is_bnode(IRI).
 1672
 1673%!  rdf_is_bnode(@Term) is semidet.
 1674%
 1675%   True if Term is an RDF blank node identifier.
 1676%
 1677%   A blank node is represented by an atom that starts with
 1678%   =|_:|=.
 1679%
 1680%   Success of this goal does not imply that the blank node is
 1681%   present in the database (see rdf_bnode/1 for that).
 1682%
 1683%   For backwards compatibility, atoms that are represented with
 1684%   an atom that starts with =|__|= are also considered to be a
 1685%   blank node.
 1686
 1687
 1688%!  rdf_is_literal(@Term) is semidet.
 1689%
 1690%   True if Term is an RDF literal term.
 1691%
 1692%   An RDF literal term is of the form `String@LanguageTag` or
 1693%   `Value^^Datatype`.
 1694%
 1695%   Success of this goal does not imply that the literal is
 1696%   well-formed or that it is present in the database (see
 1697%   rdf_literal/1 for that).
 1698
 1699rdf_is_literal(Literal) :-
 1700    literal_form(Literal),
 1701    !,
 1702    ground(Literal).
 1703
 1704literal_form(_@_).
 1705literal_form(_^^_).
 1706
 1707
 1708%!  rdf_is_name(@Term) is semidet.
 1709%
 1710%   True if Term is an RDF Name, i.e., an IRI or literal.
 1711%
 1712%   Success of this goal does not imply that the name is
 1713%   well-formed or that it is present in the database (see
 1714%   rdf_name/1) for that).
 1715
 1716rdf_is_name(T) :- rdf_is_iri(T), !.
 1717rdf_is_name(T) :- rdf_is_literal(T).
 1718
 1719
 1720%!  rdf_is_object(@Term) is semidet.
 1721%
 1722%   True if Term can appear in the object position of a triple.
 1723%
 1724%   Success of this goal does not imply that the object term in
 1725%   well-formed or that it is present in the database (see
 1726%   rdf_object/1) for that).
 1727%
 1728%   Since any RDF term can appear in the object position, this is
 1729%   equaivalent to rdf_is_term/1.
 1730
 1731rdf_is_object(T) :- rdf_is_subject(T), !.
 1732rdf_is_object(T) :- rdf_is_literal(T).
 1733
 1734
 1735%!  rdf_is_predicate(@Term) is semidet.
 1736%
 1737%   True if Term can appear in the   predicate position of a triple.
 1738%
 1739%   Success of this goal does not imply that the predicate term is
 1740%   present in the database (see rdf_predicate/1) for that).
 1741%
 1742%   Since only IRIs can appear in the predicate position, this is
 1743%   equivalent to rdf_is_iri/1.
 1744
 1745rdf_is_predicate(T) :- rdf_is_iri(T).
 1746
 1747
 1748%!  rdf_is_subject(@Term) is semidet.
 1749%
 1750%   True if Term can appear in  the   subject  position of a triple.
 1751%
 1752%   Only blank nodes and IRIs can appear in the subject position.
 1753%
 1754%   Success of this goal does not imply that the subject term is
 1755%   present in the database (see rdf_subject/1) for that).
 1756%
 1757%   Since blank nodes are represented by atoms that start with
 1758%   `_:` and an IRIs are atoms as well, this is equivalent to
 1759%   atom(Term).
 1760
 1761rdf_is_subject(T) :- atom(T).
 1762
 1763%!  rdf_is_term(@Term) is semidet.
 1764%
 1765%   True if Term can be used as an RDF term, i.e., if Term is
 1766%   either an IRI, a blank node or an RDF literal.
 1767%
 1768%   Success of this goal does not imply that the RDF term is
 1769%   present in the database (see rdf_term/1) for that).
 1770
 1771rdf_is_term(N) :- rdf_is_subject(N), !.
 1772rdf_is_term(N) :- rdf_is_literal(N).
 1773
 1774
 1775                 /*******************************
 1776                 *          COLLECTIONS         *
 1777                 *******************************/
 1778
 1779%!  rdf_list(?RDFTerm) is semidet.
 1780%
 1781%   True if RDFTerm is a proper RDF   list.  This implies that every
 1782%   node in the list has an  `rdf:first` and `rdf:rest` property and
 1783%   the list ends in `rdf:nil`.
 1784%
 1785%   If RDFTerm is unbound, RDFTerm is   bound  to each _maximal_ RDF
 1786%   list. An RDF list is _maximal_  if   there  is  no triple rdf(_,
 1787%   rdf:rest, RDFList).
 1788
 1789rdf_list(L) :-
 1790    var(L),
 1791    !,
 1792    rdf_has(L, rdf:first, _),
 1793    \+ rdf_has(_, rdf:rest, L),
 1794    rdf_list_g(L).
 1795rdf_list(L) :-
 1796    rdf_list_g(L),
 1797    !.
 1798
 1799rdf_list_g(rdf:nil) :- !.
 1800rdf_list_g(L) :-
 1801    once(rdf_has(L, rdf:first, _)),
 1802    rdf_has(L, rdf:rest, Rest),
 1803    (   rdf_equal(rdf:nil, Rest)
 1804    ->  true
 1805    ;   rdf_list_g(Rest)
 1806    ).
 1807
 1808
 1809%!  rdf_list(+RDFList, -PrologList) is det.
 1810%
 1811%   True when PrologList represents the   rdf:first  objects for all
 1812%   cells in RDFList. Note that  this   can  be non-deterministic if
 1813%   cells have multiple rdf:first or rdf:rest triples.
 1814
 1815rdf_list(RDFList, Prolog) :-
 1816    rdf_is_subject(RDFList),
 1817    !,
 1818    rdf_list_to_prolog(RDFList, Prolog).
 1819rdf_list(RDFList, _Prolog) :-
 1820    type_error(rdf_subject, RDFList).
 1821
 1822:- rdf_meta
 1823    rdf_list_to_prolog(r,-). 1824
 1825rdf_list_to_prolog(rdf:nil, Prolog) :-
 1826    !,
 1827    Prolog = [].
 1828rdf_list_to_prolog(RDF, [H|T2]) :-
 1829    (   rdf_has(RDF, rdf:first, H0),
 1830        rdf_has(RDF, rdf:rest, T1)
 1831    *-> H = H0,
 1832        rdf_list_to_prolog(T1, T2)
 1833    ;   type_error(rdf_list, RDF)
 1834    ).
 1835
 1836
 1837%!  rdf_length(+RDFList, -Length:nonneg) is nondet.
 1838%
 1839%   True when Length is the number of  cells in RDFList. Note that a
 1840%   list cell may have multiple rdf:rest   triples, which makes this
 1841%   predicate  non-deterministic.  This  predicate  does  not  check
 1842%   whether the list cells have   associated values (rdf:first). The
 1843%   list must end in rdf:nil.
 1844
 1845rdf_length(RDFList, Len) :-
 1846    rdf_is_subject(RDFList),
 1847    !,
 1848    rdf_length(RDFList, 0, Len).
 1849
 1850:- rdf_meta
 1851    rdf_length(r,+,-). 1852
 1853rdf_length(rdf:nil, Len, Len) :- !.
 1854rdf_length(RDF, Len0, Len) :-
 1855    (   rdf_has(RDF, rdf:rest, T)
 1856    *-> Len1 is Len0+1,
 1857        rdf_length(T, Len1, Len)
 1858    ;   type_error(rdf_list, RDF)
 1859    ).
 1860
 1861
 1862%!  rdf_member(?Member, +RDFList) is nondet.
 1863%
 1864%   True when Member is a member of RDFList
 1865
 1866rdf_member(M, L) :-
 1867    ground(M),
 1868    !,
 1869    (   rdf_member2(M, L)
 1870    ->  true
 1871    ).
 1872rdf_member(M, L) :-
 1873    rdf_member2(M, L).
 1874
 1875rdf_member2(M, L) :-
 1876    rdf_has(L, rdf:first, M).
 1877rdf_member2(M, L) :-
 1878    rdf_has(L, rdf:rest, L1),
 1879    rdf_member2(M, L1).
 1880
 1881
 1882%! rdf_nextto(?X, ?Y) is nondet.
 1883%! rdf_nextto(?X, ?Y, ?RdfList) is nondet.
 1884%
 1885%       True if Y directly follows X in RdfList.
 1886
 1887rdf_nextto(X, Y) :-
 1888    distinct(X-Y, rdf_nextto(X, Y, _)).
 1889
 1890
 1891rdf_nextto(X, Y, L) :-
 1892    var(X), ground(Y),
 1893    !,
 1894    rdf_nextto(Y, X, L).
 1895rdf_nextto(X, Y, L) :-
 1896    rdf_has(L, rdf:first, X),
 1897    rdf_has(L, rdf:rest, T),
 1898    rdf_has(T, rdf:first, Y).
 1899
 1900
 1901%!  rdf_nth0(?Index, +RDFList, ?X) is nondet.
 1902%!  rdf_nth1(?Index, +RDFList, ?X) is nondet.
 1903%
 1904%   True when X is the Index-th element (0-based or 1-based) of
 1905%   RDFList.  This predicate is deterministic if Index is given and
 1906%   the list has no multiple rdf:first or rdf:rest values.
 1907
 1908rdf_nth0(I, L, X) :-
 1909    rdf_nth(0, I, L, X).
 1910
 1911rdf_nth1(I, L, X) :-
 1912    rdf_nth(1, I, L, X).
 1913
 1914rdf_nth(Offset, I, L, X) :-
 1915    rdf_is_subject(L),
 1916    !,
 1917    (   var(I)
 1918    ->  true
 1919    ;   must_be(nonneg, I)
 1920    ),
 1921    rdf_nth_(I, Offset, L, X).
 1922rdf_nth(_, L, _) :-
 1923    type_error(rdf_subject, L).
 1924
 1925rdf_nth_(I, I0, L, X) :-
 1926    (   I0 == I
 1927    ->  !
 1928    ;   I0 = I
 1929    ),
 1930    rdf_has(L, rdf:first, X).
 1931rdf_nth_(I, I0, L, X) :-
 1932    rdf_has(L, rdf:rest, T),
 1933    I1 is I0+1,
 1934rdf_nth_(I, I1, T, X).
 1935
 1936
 1937%!  rdf_last(+RDFList, -Last) is det.
 1938%
 1939%   True when Last is the last element  of RDFList. Note that if the
 1940%   last cell has multiple rdf:first triples, this predicate becomes
 1941%   nondet.
 1942
 1943rdf_last(L, Last) :-
 1944    rdf_is_subject(L),
 1945    !,
 1946    rdf_has(L, rdf:rest, T),
 1947    (   rdf_equal(T, rdf:nil)
 1948    ->  rdf_has(L, rdf:first, Last)
 1949    ;   rdf_last(T, Last)
 1950    ).
 1951rdf_last(L, _) :-
 1952    type_error(rdf_subject, L).
 1953
 1954
 1955%!  rdf_estimate_complexity(?S, ?P, ?O, -Estimate) is det.
 1956
 1957rdf_estimate_complexity(S, P, O, Estimate) :-
 1958    pre_object(O,O0),
 1959    rdf_db:rdf_estimate_complexity(S,P,O0,Estimate).
 1960
 1961
 1962%!  rdf_assert_list(+PrologList, ?RDFList) is det.
 1963%!  rdf_assert_list(+PrologList, ?RDFList, +Graph) is det.
 1964%
 1965%   Create an RDF list from the   given Prolog List. PrologList must
 1966%   be a proper Prolog list and  all   members  of  the list must be
 1967%   acceptable as object for rdf_assert/3. If RDFList is unbound and
 1968%   PrologList is not empty, rdf_create_bnode/1   is  used to create
 1969%   RDFList.
 1970
 1971rdf_assert_list(Prolog, RDF) :-
 1972    rdf_default_graph(G),
 1973    rdf_assert_list(Prolog, RDF, G).
 1974
 1975rdf_assert_list(Prolog, RDF, G) :-
 1976    must_be(list, Prolog),
 1977    rdf_transaction(rdf_assert_list_(Prolog, RDF, G)).
 1978
 1979rdf_assert_list_([], Nil, _) :-
 1980    rdf_equal(rdf:nil, Nil).
 1981rdf_assert_list_([H|T], L2, G) :-
 1982    (var(L2) -> rdf_create_bnode(L2) ; true),
 1983    rdf_assert(L2, rdf:type, rdf:'List', G),
 1984    rdf_assert(L2, rdf:first, H, G),
 1985    (   T == []
 1986    ->  rdf_assert(L2, rdf:rest, rdf:nil, G)
 1987    ;   rdf_create_bnode(T2),
 1988        rdf_assert(L2, rdf:rest, T2, G),
 1989        rdf_assert_list_(T, T2, G)
 1990    ).
 1991
 1992
 1993%!  rdf_retract_list(+RDFList) is det.
 1994%
 1995%   Retract the rdf:first, rdf:rest  and rdf:type=rdf:'List' triples
 1996%   from all nodes  reachable  through   rdf:rest.  Note  that other
 1997%   triples that exist on the nodes are left untouched.
 1998
 1999rdf_retract_list(L) :-
 2000    rdf_is_subject(L),
 2001    !,
 2002    rdf_transaction(rdf_retract_list_(L)).
 2003rdf_retract_list(L) :-
 2004    type_error(rdf_subject, L).
 2005
 2006:- rdf_meta
 2007    rdf_retract_list_(r). 2008
 2009rdf_retract_list_(rdf:nil) :- !.
 2010rdf_retract_list_(L) :-
 2011    rdf_retractall(L, rdf:first, _),
 2012    forall(rdf_has(L, rdf:rest, L1),
 2013           rdf_retract_list_(L1)),
 2014    rdf_retractall(L, rdf:rest, _),
 2015    rdf_retractall(L, rdf:type, rdf:'List')