- Documentation
- Reference manual
- Packages
- SWI-Prolog Semantic Web Library 3.0
- Plugin modules for rdf_db
- Hooks into the RDF library
- library(semweb/rdf_zlib_plugin): Reading compressed RDF
- library(semweb/rdf_http_plugin): Reading RDF from a HTTP server
- library(semweb/rdf_cache): Cache RDF triples
- library(semweb/rdf_litindex): Indexing words in literals
- library(semweb/rdf_persistency): Providing persistent storage
- Plugin modules for rdf_db
- SWI-Prolog Semantic Web Library 3.0
4.5 library(semweb/rdf_litindex): Indexing words in literals
The library library(semweb/rdf_litindex.pl)
exploits the
primitives of section 4.5.1 and the
NLP package to provide indexing on words inside literal constants. It
also allows for fuzzy matching using stemming and‘sounds-like’based
on the double metaphone algorithm of the NLP package.
- rdf_find_literals(+Spec, -ListOfLiterals)
- Find literals (without type or language specification) that satisfy
Spec. The required indices are created as needed and kept
up-to-date using hooks registered with rdf_monitor/2.
Numerical indexing is currently limited to integers in the range ±2^30
(±2^62 on 64-bit platforms). Spec is defined
as:
- and(Spec1, Spec2)
- Intersection of both specifications.
- or(Spec1, Spec2)
- Union of both specifications.
- not(Spec)
- Negation of Spec. After translation of the full specification to Disjunctive Normal Form (DNF), negations are only allowed inside a conjunction with at least one positive literal.
- case(Word)
- Matches all literals containing the word Word, doing the match case insensitive and after removing diacritics.
- stem(Like)
- Matches all literals containing at least one word that has the same stem as Like using the Porter stem algorithm. See NLP package for details.
- sounds(Like)
- Matches all literals containing at least one word that‘sounds like’ Like using the double metaphone algorithm. See NLP package for details.
- prefix(Prefix)
- Matches all literals containing at least one word that starts with Prefix, discarding diacritics and case.
- between(Low, High)
- Matches all literals containing an integer token in the range Low..High, including the boundaries.
- ge(Low)
- Matches all literals containing an integer token with value Low or higher.
- le(High)
- Matches all literals containing an integer token with value High or lower.
- Token
- Matches all literals containing the given token. See tokenize_atom/2 of the NLP package for details.
- rdf_token_expansions(+Spec, -Expansions)
- Uses the same database as rdf_find_literals/2
to find possible expansions of Spec, i.e. which words‘sound
like’,‘have prefix’, etc. Spec is a
compound expression as in rdf_find_literals/2.
Expansions is unified to a list of terms
sounds(Like, Words)
,stem(Like, Words)
orprefix(Prefix, Words)
. On compound expressions, only combinations that provide literals are returned. Below is an example after loading the ULAN2Unified List of Artist Names from the Getty Foundation. database and showing all words that sounds like‘rembrandt’and appear together in a literal with the word‘Rijn’. Finding this result from the 228,710 literals contained in ULAN requires 0.54 milliseconds (AMD 1600+).?- rdf_token_expansions(and('Rijn', sounds(rembrandt)), L). L = [sounds(rembrandt, ['Rambrandt', 'Reimbrant', 'Rembradt', 'Rembrand', 'Rembrandt', 'Rembrandtsz', 'Rembrant', 'Rembrants', 'Rijmbrand'])]
Here is another example, illustrating handling of diacritics:
?- rdf_token_expansions(case(cafe), L). L = [case(cafe, [cafe, caf\'e])]
- rdf_tokenize_literal(+Literal, -Tokens)
- Tokenize a literal, returning a list of atoms and integers in the range
-1073741824 ... 1073741823. As tokenization is in general
domain and task-dependent this predicate first calls the hook
rdf_litindex:tokenization(Literal, -Tokens)
. On failure it calls tokenize_atom/2 from the NLP package and deletes the following: atoms of length 1, floats, integers that are out of range and the english wordsand
,an
,or
,of
,on
,in
,this
andthe
. Deletion first calls the hookrdf_litindex:exclude_from_index(token, X)
. This hook is called as follows:no_index_token(X) :- exclude_from_index(token, X), !. no_index_token(X) :- ...
4.5.1 Literal maps: Creating additional indices on literals
‘Literal maps’provide a relation between literal values, intended to create additional indexes on literals. The current implementation can only deal with integers and atoms (string literals). A literal map maintains an ordered set of keys. The ordering uses the same rules as described in section 4.5. Each key is associated with an ordered set of values. Literal map objects can be shared between threads, using a locking strategy that allows for multiple concurrent readers.
Typically, this module is used together with rdf_monitor/2
on the channals new_literal
and old_literal
to
maintain an index of words that appear in a literal. Further abstraction
using Porter stemming or Metaphone can be used to create additional
search indices. These can map either directly to the literal values, or
indirectly to the plain word-map. The SWI-Prolog NLP package provides
complimentary building blocks, such as a tokenizer, Porter stem and
Double Metaphone.
- rdf_new_literal_map(-Map)
- Create a new literal map, returning an opaque handle.
- rdf_destroy_literal_map(+Map)
- Destroy a literal map. After this call, further use of the Map handle is illegal. Additional synchronisation is needed if maps that are shared between threads are destroyed to guarantee the handle is no longer used. In some scenarios rdf_reset_literal_map/1 provides a safe alternative.
- rdf_reset_literal_map(+Map)
- Delete all content from the literal map.
- rdf_insert_literal_map(+Map, +Key, +Value)
- Add a relation between Key and Value to the map. If this relation already exists no action is performed.
- rdf_insert_literal_map(+Map, +Key, +Value, -KeyCount)
- As rdf_insert_literal_map/3.
In addition, if Key is a new key in
Map, unify KeyCount with the number of keys in Map.
This serves two purposes. Derived maps, such as the stem and metaphone
maps need to know about new keys and it avoids additional foreign calls
for doing the progress in
rdf_litindex.pl
. - rdf_delete_literal_map(+Map, +Key)
- Delete Key and all associated values from the map. Succeeds always.
- rdf_delete_literal_map(+Map, +Key, +Value)
- Delete the association between Key and Value from the map. Succeeds always.
- [det]rdf_find_literal_map(+Map, +KeyList, -ValueList)
- Unify ValueList with an ordered set of values associated to
all keys from KeyList. Each key in KeyList is
either an atom, an integer or a term
not(Key)
. If not-terms are provided, there must be at least one positive keywords. The negations are tested after establishing the positive matches. - rdf_keys_in_literal_map(+Map, +Spec, -Answer)
- Realises various queries on the key-set:
- all
- Unify Answer with an ordered list of all keys.
- key(+Key)
- Succeeds if Key is a key in the map and unify Answer with the number of values associated with the key. This provides a fast test of existence without fetching the possibly large associated value set as with rdf_find_literal_map/3.
- prefix(+Prefix)
- Unify Answer with an ordered set of all keys that have the given prefix. Prefix must be an atom. This call is intended for auto-completion in user interfaces.
- ge(+Min)
- Unify Answer with all keys that are larger or equal to the integer Min.
- le(+Max)
- Unify Answer with all keys that are smaller or equal to the integer Max.
- between(+Min, +Max)
- Unify Answer with all keys between Min and Max (including).
- rdf_statistics_literal_map(+Map, +Key(-Arg...))
- Query some statistics of the map. Provides keys are:
- size(-Keys, -Relations)
- Unify Keys with the total key-count of the index and Relation with the total Key-Value count.