- Documentation
- Reference manual
- Packages
- SWI-Prolog Semantic Web Library 3.0
- Two RDF APIs
- library(semweb/rdf_db): The RDF database
- Query the RDF database
- Enumerating objects
- Modifying the RDF database
- Update view, transactions and snapshots
- Type checking predicates
- Loading and saving to file
- Graph manipulation
- Literal matching and indexing
- Predicate properties
- Prefix Handling
- Miscellaneous predicates
- Memory management considerations
- library(semweb/rdf_db): The RDF database
- Two RDF APIs
- SWI-Prolog Semantic Web Library 3.0
3.3.10 Prefix Handling
Prolog code often contains references to constant resources with a
known
prefix (also known as XML namespaces). For example,
http://www.w3.org/2000/01/rdf-schema#Class
refers to the
most general notion of an RDFS class. Readability and maintability
concerns require for abstraction here. The RDF database maintains a
table of known prefixes. This table can be queried using rdf_current_ns/2
and can be extended using rdf_register_ns/3.
The prefix database is used to expand prefix:local
terms
that appear as arguments to calls which are known to accept a resource.
This expansion is achieved by Prolog preprocessor using expand_goal/2.
- [nondet]rdf_current_prefix(:Alias, ?URI)
- Query predefined prefixes and prefixes defined with
rdf_register_prefix/2
and local prefixes defined with
rdf_prefix/2. If Alias is
unbound and one URI is the prefix of another, the longest is
returned first. This allows turning a resource into a prefix/local
couple using the simple enumeration below. See rdf_global_id/2.
rdf_current_prefix(Prefix, Expansion), atom_concat(Expansion, Local, URI),
- [det]rdf_register_prefix(+Prefix, +URI)
- [det]rdf_register_prefix(+Prefix, +URI, +Options)
- Register Prefix as an abbreviation for URI. Options:
- force(Boolean)
- If
true
, replace existing namespace alias. Please note that replacing a namespace is dangerous as namespaces affect preprocessing. Make sure all code that depends on a namespace is compiled after changing the registration. - keep(Boolean)
- If
true
and Alias is already defined, keep the original binding for Prefix and succeed silently.
Without options, an attempt to redefine an alias raises a permission error.
Predefined prefixes are:
Explicit expansion is achieved using the predicates below. The predicate rdf_equal/2 performs this expansion at compile time, while the other predicates do it at runtime.
- rdf_equal(?Resource1, ?Resource2)
- Simple equality test to exploit goal-expansion.
- [semidet]rdf_global_id(?IRISpec, :IRI)
- Convert between Prefix:Local and full IRI (an atom). If IRISpec
is an atom, it is simply unified with IRI. This predicate
fails silently if IRI is an RDF literal.
Note that this predicate is a meta-predicate on its output argument. This is necessary to get the module context while the first argument may be of the form (:)/2. The above mode description is correct, but should be interpreted as (?,?).
- Errors
existence_error(rdf_prefix, Prefix)
- See also
- - rdf_equal/2 provides a compile
time alternative
- The rdf_meta/1 directive asks for compile time expansion of arguments. - bug
- Error handling is incomplete. In its current implementation the same code is used for compile-time expansion and to facilitate runtime conversion and checking. These use cases have different requirements.
- [semidet]rdf_global_object(+Object, :GlobalObject)
- [semidet]rdf_global_object(-Object, :GlobalObject)
- Same as rdf_global_id/2, but
intended for dealing with the object part of a triple, in particular the
type for typed literals. Note that the predicate is a meta-predicate on
the output argument. This is necessary to get the module context while
the first argument may be of the form (:)/2.
- Errors
existence_error(rdf_prefix, Prefix)
- [det]rdf_global_term(+TermIn, :GlobalTerm)
- Performs rdf_global_id/2 on
predixed IRIs and rdf_global_object/2
on RDF literals, by recursively analysing the term. Note that the
predicate is a meta-predicate on the output argument. This is necessary
to get the module context while the first argument may be of the form
(:)/2.
Terms of the form
Prefix:Local
that appear in TermIn for which Prefix is not defined are not replaced. Unlike rdf_global_id/2 and rdf_global_object/2, no error is raised.
Namespace handling for custom predicates
If we implement a new predicate based on one of the predicates of the semweb libraries that expands namespaces, namespace expansion is not automatically available to it. Consider the following code computing the number of distinct objects for a certain property on a certain object.
cardinality(S, P, C) :- ( setof(O, rdf_has(S, P, O), Os) -> length(Os, C) ; C = 0 ).
Now assume we want to write labels/2 that returns the number of distict labels of a resource:
labels(S, C) :- cardinality(S, rdfs:label, C).
This code will not work because rdfs:label
is not
expanded at compile time. To make this work, we need to add an rdf_meta/1
declaration.
:- rdf_meta cardinality(r,r,-).
The example below defines the rule concept/1.
:- use_module(library(semweb/rdf_db)). % for rdf_meta :- use_module(library(semweb/rdfs)). % for rdfs_individual_of :- rdf_meta concept(r). %% concept(?C) is nondet. % % True if C is a concept. concept(C) :- rdfs_individual_of(C, skos:'Concept').
In addition to expanding calls, rdf_meta/1 also causes expansion of clause heads for predicates that match a declaration. This is typically used write Prolog statements about resources. The following example produces three clauses with expanded (single-atom) arguments:
:- use_module(library(semweb/rdf_db)). :- rdf_meta label_predicate(r). label_predicate(rdfs:label). label_predicate(skos:prefLabel). label_predicate(skos:altLabel).