View source with raw 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)).

RDF 1.1 API

This library provides a new API on top of library(semweb/rdf_db). The new API follows the RDF 1.1 terminology and notation as much as possible. It runs on top of the old API, which implies that applications can use the new API in one file and the other in another one. Once the new API is considered stable and robust the old API will be deprecated.

In a nutshell, the following issues are addressed:

author
- Jan Wielemaker
- Wouter Beek
version
- 2016 */
See also
- https://github.com/SWI-Prolog/packages-semweb/wiki/Proposal-for-Semweb-library-redesign
  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).
 rdf(?S, ?P, ?O) is nondet
 rdf(?S, ?P, ?O, ?G) is nondet
True if an RDF triple <S,P,O> exists, optionally in the graph G. The object O is either a resource (atom) or one of the terms listed below. The described types apply for the case where O is unbound. If O is instantiated it is converted according to the rules described with rdf_assert/3.

Triples consist of the following three terms:

Notes:

(1) The current implementation of xsd:decimal values as floats is formally incorrect. Future versions of SWI-Prolog may introduce decimal as a subtype of rational.
(2) SS fields denote the number of seconds. This can either be an integer or a float.
(3) The date_time structure can have a 7th field that denotes the timezone offset in seconds as an integer.

In addition, a ground object value is translated into a properly typed RDF literal using rdf_canonical_literal/2.

There is a fine distinction in how duplicate statements are handled in rdf/[3,4]: backtracking over rdf/3 will never return duplicate triples that appear in multiple graphs. rdf/4 will return such duplicate triples, because their graph term differs.

Arguments:
S- is the subject term. It is either a blank node or IRI.
P- is the predicate term. It is always an IRI.
O- is the object term. It is either a literal, a blank node or IRI (except for true and false that denote the values of datatype XSD boolean).
G- is the graph term. It is always an IRI.
See also
- Triple pattern querying
- xsd_number_string/2 and xsd_time_string/3 are used to convert between lexical representations and Prolog terms.
  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).
 rdf_has(?S, ?P, ?O) is nondet
 rdf_has(?S, ?P, ?O, -RealP) is nondet
Similar to rdf/3 and rdf/4, but P matches all predicates that are defined as an rdfs:subPropertyOf of P. This predicate also recognises the predicate properties inverse_of and symmetric. See rdf_set_predicate/2.
  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).
 rdf_update(+S, +P, +O, ++Action) is det
 rdf_update(+S, +P, +O, +G, ++Action) is det
Replaces one of the three fields on the matching triples depending on Action:
subject(Resource)
Changes the first field of the triple.
predicate(Resource)
Changes the second field of the triple.
object(Object)
Changes the last field of the triple to the given resource or literal(Value).
graph(Graph)
Moves the triple from its current named graph to Graph. This only works with rdf_update/4 and will throw an error when used with rdf_update/3.

The argument matching the action must be ground. If this argument is equivalent to the current value, no action is performed. Otherwise, the requested action is performed on all matching triples. For example, all resources typed rdfs:Class can be changed to owl:Class using

?- rdf_update(_, rdf:type, rdfs:'Class',
              object(owl:'Class')).
Errors
- instantiation_error if Action or the matching argument is not ground.
- domain_error(rdf_update_action, Action) if Action is not one of the above terms.
  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           )).
 rdf_reachable(?S, +P, ?O) is nondet
 rdf_reachable(?S, +P, ?O, +MaxD, -D) is nondet
True when O can be reached from S using the transitive closure of P. The predicate uses (the internals of) rdf_has/3 and thus matches both rdfs:subPropertyOf and the inverse_of and symmetric predicate properties. The version rdf_reachable/5 maximizes the steps considered and returns the number of steps taken.

If both S and O are given, these predicates are semidet. The number of steps D is minimal because the implementation uses breath first search.

  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).
 rdf_assert(+S, +P, +O) is det
 rdf_assert(+S, +P, +O, +G) is det
Assert a new triple. If O is a literal, certain Prolog terms are translated to typed RDF literals. These conversions are described with rdf_canonical_literal/2.

If a type is provided using Value^^Type syntax, additional conversions are performed. All types accept either an atom or Prolog string holding a valid RDF lexical value for the type and xsd:float and xsd:double accept a Prolog integer.

  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).
 rdf_retractall(?S, ?P, ?O) is nondet
 rdf_retractall(?S, ?P, ?O, ?G) is nondet
Remove all matching triples from the database. Matching is performed using the same rules as rdf/3. The call does not instantiate any of its arguments.
  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).
 rdf_compare(-Diff, +Left, +Right) is det
True if the RDF terms Left and Right are ordered according to the comparison operator Diff. The ordering is defines as:

Note that this ordering is a complete ordering of RDF terms that is consistent with the partial ordering defined by SPARQL.

Arguments:
Diff- is one of <, = or >
  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).
 {}(+Where) is semidet
 rdf_where(+Where) is semidet
Formulate constraints on RDF terms, notably literals. These are intended to be used as illustrated below. RDF constraints are pure: they may be placed before, after or inside a graph pattern and, provided the code contains no commit operations (!, ->), the semantics of the goal remains the same. Preferably, constraints are placed before the graph pattern as they often help the RDF database to exploit its literal indexes. In the example below, the database can choose between using the subject and/or predicate hash or the ordered literal table.
    { Date >= "2000-01-01"^^xsd:dateTime },
    rdf(S, P, Date)

The following constraints are currently defined:

>,>=,==,=<,<
The comparison operators are defined between numbers (of any recognised type), typed literals of the same type and langStrings of the same language.
prefix(String, Pattern)
substring(String, Pattern)
word(String, Pattern)
like(String, Pattern)
icase(String, Pattern)
Text matching operators that act on both typed literals and langStrings.
lang_matches(Term, Pattern)
Demands a full RDF term (Text@Lang) or a plain Lang term to match the language pattern Pattern.

The predicates rdf_where/1 and {}/1 are identical. The rdf_where/1 variant is provided to avoid ambiguity in applications where {}/1 is used for other purposes. Note that it is also possible to write rdf11:{...}.

  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).
 add_lang_constraint(?Term, +Constraint)
Add a constraint on the language of a literal
  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).
 add_value_constraint(?Term, +Constraint, +Value)
Apply a value constraint to the RDF Term.
  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).
 literal_condition(+Object, -Cond) is semidet
True when some of the constraints on Object can be translated into an equivalent query of the form literal(Cond, _Value). Translated constraints are removed from object.
  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).
 best_literal_cond(+Conditions, -Best, -Rest) is semidet
Extract the constraints that can be translated into the Search of literal(Search, Value).
To be done
- Select the best rather than the first.
  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))).
 in_constaint_type(?Type, -SType, ++Val, -Val0)
  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    ).
 literal_class(+Term, -Class)
Classify Term as literal and if possible as lang or typed literal on the basis of the constraints that apply to it.
  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).
 attr_unify_hook(+AttributeValue, +Value)
  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.
 rdf_default_graph(-Graph) is det
 rdf_default_graph(-Old, +New) is det
Query/set the notion of the default graph. The notion of the default graph is local to a thread. Threads created inherit the default graph from their creator. See set_prolog_flag/2.
  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, _)).
 pre_ground_object(+Object, -RDF) is det
Convert between a Prolog value and an RDF value for rdf_assert/3 and friends. Auto-conversion:
Integer
Converted to Integer^^xsd:integer
Float
Converted to Float^^xsd:double
String
Converted to String^^xsd:string
true
Converted to true^^xsd:boolean
false
Converted to false^^xsd:boolean
@(Text, Lang)
Converted to Text@Lang. Uses canonical (lowercase) lang. Text is converted into an atom.
^^(Value, Type)
Typed conversion. The translation of Value depends on Type:
  • Numeric types
  • Boolean
  • Date types
Atom
All atoms except for true and false are considered URIs.
 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, +, +, -).
 in_ground_type(+Type, +Input, -Lexical:atom) is det
Translate the Prolog date Input according to Type into its RDF lexical form. The lecical form is represented as an atom. In future versions this is likely to become a string.
 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).
 in_date_time(+Type, +Input, -Lexical) is det
Accepts either a term as accepted by xsd_time_string/3 or a valid string for the corresponding XSD type.
 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).
 in_boolean(?NonCanonical, ?Canonical)
True when Canonical is the canonical boolean for NonCanonical.
 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).
 in_number(+PrologType, +Domain, +XSDType, +Value, -Lexical)
Lexical is the lexical representation for Value.
Errors
- type_error(PrologType, Value)
- domain_error(XSDType, Value)
 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, _, _).
 xsd_numerical(?URI, ?TypeCheck, ?PrologType)
 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).
 xsd_date_time_type(?URI)
True when URI is an XSD date or time type.
 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).
 in_xml_literal(+Type, +Val, -Val0) is det
Translate an XMLLiteral or HTML literal to its canonical textual representation. Input is either text or a Prolog XML DOM.
To be done
- Deal with partial content?
 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                              ])).
 rdf_canonical_literal(++In, -Literal) is det
Transform a relaxed literal specification as allowed for rdf_assert/3 into its canonical form. The following Prolog terms are translated:
Prolog TermDatatype IRI
floatxsd:double
integerxsd:integer
stringxsd:string
true or falsexsd:boolean
date(Y,M,D)xsd:date
date_time(Y,M,D,HH,MM,SS)xsd:dateTime
date_time(Y,M,D,HH,MM,SS,TZ)xsd:dateTime
month_day(M,D)xsd:gMonthDay
year_month(Y,M)xsd:gYearMonth
time(HH,MM,SS)xsd:time

For example:

?- rdf_canonical_literal(42, X).
X = 42^^'http://www.w3.org/2001/XMLSchema#integer'.
 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).
 rdf_lexical_form(++Literal, -Lexical:compound) is det
True when Lexical is the lexical form for the literal Literal. Lexical is of one of the forms below. The ntriples serialization is obtained by transforming String into a proper ntriples string using double quotes and escaping where needed and turning Type into a proper IRI reference.
 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).
 out_date_time(+DateTimeType, -Val, +Val0) is det
Translate an XSD lexical form for a date/time related datatype into the cannical form as defined by xsd_time_string/3.
 1434out_date_time(Type, Prolog, Lexical) :-
 1435    xsd_time_string(Prolog, Type, Lexical).
 1436
 1437
 1438                 /*******************************
 1439                 *          ENUMERATION         *
 1440                 *******************************/
 rdf_term(?Term) is nondet
True if Term appears in the RDF database. Term is either an iri, literal or blank node and may appear in any position of any triple. If Term is ground, it is pre-processed as the object argument of rdf_assert/3 and the predicate is semidet.
 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).
 rdf_literal(?Term) is nondet
True if Term is a known literal. If Term is ground, it is pre-processed as the object argument of rdf_assert/3 and the predicate is semidet.
 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)).
 rdf_bnode(?BNode) is nondet
True if BNode is a currently known blank node. The predicate is semidet if BNode is ground.
 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
 rdf_iri(?IRI) is nondet
True if IRI is a current IRI. The predicate is semidet if IRI is ground.
 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).
 rdf_name(?Name) is nondet
True if Name is a current IRI or literal. The predicate is semidet if Name is ground.
 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).
 rdf_subject(?S) is nondet
True when S is a currently known subject, i.e. it appears in the subject position of some visible triple. The predicate is semidet if S is ground.
 rdf_predicate(?P) is nondet
True when P is a currently known predicate, i.e. it appears in the predicate position of some visible triple. The predicate is semidet if P is ground.
 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).
 rdf_object(?O) is nondet
True when O is a currently known object, i.e. it appeasr in the object position of some visible triple. If Term is ground, it is pre-processed as the object argument of rdf_assert/3 and the predicate is semidet.
 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).
 rdf_node(?T) is nondet
True when T appears in the subject or object position of a known triple, i.e., is a node in the RDF graph.
 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).
 resource(?R)
True if R is a node that is not a literal. Note that RDF-DB does not necessarily include predicates in the set of resources. Also note that the resource may not really exist or be visible.
 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).
 rdf_create_bnode(--BNode)
Create a new BNode. A blank node is an atom starting with _:. Blank nodes generated by this predicate are of the form _:genid followed by a unique integer.
 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                 *******************************/
 rdf_is_iri(@IRI) is semidet
True if IRI is an RDF IRI term.

For performance reasons, this does not check for compliance to the syntax defined in RFC 3987. This checks whether the term is (1) an atom and (2) not a blank node identifier.

Success of this goal does not imply that the IRI is present in the database (see rdf_iri/1 for that).

 1669rdf_is_iri(IRI) :-
 1670    atom(IRI),
 1671    \+ rdf_is_bnode(IRI).
 rdf_is_bnode(@Term) is semidet
True if Term is an RDF blank node identifier.

A blank node is represented by an atom that starts with _:.

Success of this goal does not imply that the blank node is present in the database (see rdf_bnode/1 for that).

For backwards compatibility, atoms that are represented with an atom that starts with __ are also considered to be a blank node.

 rdf_is_literal(@Term) is semidet
True if Term is an RDF literal term.

An RDF literal term is of the form `String@LanguageTag or Value^^Datatype`.

Success of this goal does not imply that the literal is well-formed or that it is present in the database (see rdf_literal/1 for that).

 1699rdf_is_literal(Literal) :-
 1700    literal_form(Literal),
 1701    !,
 1702    ground(Literal).
 1703
 1704literal_form(_@_).
 1705literal_form(_^^_).
 rdf_is_name(@Term) is semidet
True if Term is an RDF Name, i.e., an IRI or literal.

Success of this goal does not imply that the name is well-formed or that it is present in the database (see rdf_name/1) for that).

 1716rdf_is_name(T) :- rdf_is_iri(T), !.
 1717rdf_is_name(T) :- rdf_is_literal(T).
 rdf_is_object(@Term) is semidet
True if Term can appear in the object position of a triple.

Success of this goal does not imply that the object term in well-formed or that it is present in the database (see rdf_object/1) for that).

Since any RDF term can appear in the object position, this is equaivalent to rdf_is_term/1.

 1731rdf_is_object(T) :- rdf_is_subject(T), !.
 1732rdf_is_object(T) :- rdf_is_literal(T).
 rdf_is_predicate(@Term) is semidet
True if Term can appear in the predicate position of a triple.

Success of this goal does not imply that the predicate term is present in the database (see rdf_predicate/1) for that).

Since only IRIs can appear in the predicate position, this is equivalent to rdf_is_iri/1.

 1745rdf_is_predicate(T) :- rdf_is_iri(T).
 rdf_is_subject(@Term) is semidet
True if Term can appear in the subject position of a triple.

Only blank nodes and IRIs can appear in the subject position.

Success of this goal does not imply that the subject term is present in the database (see rdf_subject/1) for that).

Since blank nodes are represented by atoms that start with `_:` and an IRIs are atoms as well, this is equivalent to atom(Term).

 1761rdf_is_subject(T) :- atom(T).
 rdf_is_term(@Term) is semidet
True if Term can be used as an RDF term, i.e., if Term is either an IRI, a blank node or an RDF literal.

Success of this goal does not imply that the RDF term is present in the database (see rdf_term/1) for that).

 1771rdf_is_term(N) :- rdf_is_subject(N), !.
 1772rdf_is_term(N) :- rdf_is_literal(N).
 1773
 1774
 1775                 /*******************************
 1776                 *          COLLECTIONS         *
 1777                 *******************************/
 rdf_list(?RDFTerm) is semidet
True if RDFTerm is a proper RDF list. This implies that every node in the list has an rdf:first and rdf:rest property and the list ends in rdf:nil.

If RDFTerm is unbound, RDFTerm is bound to each maximal RDF list. An RDF list is maximal if there is no triple rdf(_, rdf:rest, RDFList).

 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    ).
 rdf_list(+RDFList, -PrologList) is det
True when PrologList represents the rdf:first objects for all cells in RDFList. Note that this can be non-deterministic if cells have multiple rdf:first or rdf:rest triples.
 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    ).
 rdf_length(+RDFList, -Length:nonneg) is nondet
True when Length is the number of cells in RDFList. Note that a list cell may have multiple rdf:rest triples, which makes this predicate non-deterministic. This predicate does not check whether the list cells have associated values (rdf:first). The list must end in rdf:nil.
 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    ).
 rdf_member(?Member, +RDFList) is nondet
True when Member is a member of RDFList
 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).
 rdf_nextto(?X, ?Y) is nondet
 rdf_nextto(?X, ?Y, ?RdfList) is nondet
True if Y directly follows X in RdfList.
 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).
 rdf_nth0(?Index, +RDFList, ?X) is nondet
 rdf_nth1(?Index, +RDFList, ?X) is nondet
True when X is the Index-th element (0-based or 1-based) of RDFList. This predicate is deterministic if Index is given and the list has no multiple rdf:first or rdf:rest values.
 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).
 rdf_last(+RDFList, -Last) is det
True when Last is the last element of RDFList. Note that if the last cell has multiple rdf:first triples, this predicate becomes nondet.
 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).
 rdf_estimate_complexity(?S, ?P, ?O, -Estimate) is det
 1957rdf_estimate_complexity(S, P, O, Estimate) :-
 1958    pre_object(O,O0),
 1959    rdf_db:rdf_estimate_complexity(S,P,O0,Estimate).
 rdf_assert_list(+PrologList, ?RDFList) is det
 rdf_assert_list(+PrologList, ?RDFList, +Graph) is det
Create an RDF list from the given Prolog List. PrologList must be a proper Prolog list and all members of the list must be acceptable as object for rdf_assert/3. If RDFList is unbound and PrologList is not empty, rdf_create_bnode/1 is used to create RDFList.
 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    ).
 rdf_retract_list(+RDFList) is det
Retract the rdf:first, rdf:rest and rdf:type=rdf:'List' triples from all nodes reachable through rdf:rest. Note that other triples that exist on the nodes are left untouched.
 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')