Chimezie’s posterous

Clinical Data Acquisition, Storage and Management

(download)

Pre-publication copy of entry. Springer requires placing the following notice:

"Chimezie Ogbuji's entry on Clinical Data Acquisition, Storage and Management will soon be published in the Encyclopedia of Database Systems by Springer. The Encyclopedia, under the editorial guidance of Ling Liu and M. Tamer Özsu, will be a multiple volume, comprehensive, and authoritative reference on databases, data management, and database systems. Since it will be available in both print and online formats, researchers, students, and practitioners will benefit from advanced search functionality and convenient interlinking possibilities with related online content. The Encyclopedia’s online version will be accessible on the platform SpringerLink.

Click here for more information about the Encyclopedia of Database Systems. 

Chimezie Ogbuji, "Clinical Data Acquisition, Storage and Management"
Encyclopedia of Database Systems, Editors-in-chief:
Özsu, M. Tamer; Liu, Ling , Springer, 2009.
(print and online)

Comments [0]

We got the Jazz.. We got the Jazz

Words from a Hip-Hop classic as an illustration

Comments [0]

A complete translation from SPARQL into efficient SQL

Our paper on a complete translation from SPARQL to SQL has been published (it looks like it has been on the ACM portal for some time). This is the basis for our RDF warehouse at the Cleveland Clinic that was recently committed back to rdflib.

This paper presents a feature-complete translation from SPARQL, the proposed standard for RDF querying, into efficient SQL. We propose "SQL model"-based algorithms that implement each SPARQL algebra operator via SQL query augmentation, and generate a flat SQL statement for efficient processing by relational database query engines. SPARQL-to-SQL translation presented is feature-complete, since it applies to all SPARQL language features. Finally, we demonstrate the performance and scalability of our method by an extensive evaluation using recent SPARQL benchmark queries, and a benchmark dataset, as well as a real-world photo dataset.

Comments [0]

Encyclopedia of Database Systems 2009 Entry (Clinical Data Acquisition, Storage and Management)

The Springer Encyclopedia of Database Systems 2009 has finally been published. This includes an entry I contributed: "Clinical Data Acquisition, Storage and Management". I believe I was told I can publish an author's proof on my website. I'll need to verify this before I do so. In the entry, I talked a bit about the role of XForms, GRDDL, XML, and RDF as infrastructure for healthcare information systems (towards the end).  Hopefully, I can find some time to elaborate a bit on this here.

Comments [0]

Lazy test and consumption of generators

So, I do a lot of design of RDF querying middleware and one of the tools of the trade that I have come to rely on quite a bit is the lazy handling of results. Consider a query to a large RDF dataset (with millions of rows). Generally, the naive approach would be to fetch all the answers from the server and then iterate over them at the client.

The lazy approach would instead fetch answers one at a time. Python generators are excellent for this and I've found myself using them judiciously in Python SPARQL results processing as well as in RDF/RIF/OWL inference (FuXi).

However, the problem with generators is that unlike lists they can only be consumed once rather than multiple times (as is the case with a list since it is a first class data structure). So, if I want to see if there is anything to fetch from the generator at all, I can't do it without effecting the consumption, since any subsequent attempt to fetch additional items from the generator will begin with the second item (if there is any).

I searched high and low for a 'lazy' test to determine if a generator has length. It would be similar to rdflib's first function - which takes an iterable or generator and consumes/returns the first item if there is one or None if not - but basically tests if a generator has length as an O(1) operation rather than an O(n) operation via the niave approach.

So, I wrote one up and am sharing it for anyone who has been faced with the same problem. It uses itertools.chain method in order to return a (new) generator over the initial item consumed for the purpose of testing if the generator has any length and the original generator (after losing the first item):

def lazyGeneratorPeek(iterable):
    """
    Lazily peeks into a generator and returns None if it is empty
    or returns another generator over *all* content if it isn't
    
    >>> a=(i for i in [1,2,3])
    >>> first(a)
    1
    >>> list(a)
    [2, 3]
    >>> a=(i for i in [1,2,3])
    >>> result = lazyGeneratorPeek(a)
    >>> result  # doctest:+ELLIPSIS
    <generator object at ...>
    >>> list(result)
    [1, 2, 3]
    >>> lazyGeneratorPeek((i for i in []))
    """
    item = first(iterable)
    if item:
        return (i for i in itertools.chain([item],
                                           iterable))

Filed under  //   logic-programming   python   rdf   tip  

Comments [0]

FuXi 1.0-rc-I.dev

FuXi has been updated and (recently) moved to its own Project on
Google code w/ a mercurial repository.
 
I have updated pypi / easy_install (http://pypi.python.org/pypi/FuXi/
1.0-rc-I.dev) as well:
 
Submitting dist/FuXi-1.0-rc-I.dev.tar.gz to http://www.python.org/pypi
Server response (200): OK
Submitting dist/FuXi-1.0_rc_I.dev-py2.5.egg to http://www.python.org/pypi
Server response (200): OK
 
A few noteworthy changes in logs below. The user manual [1] and
overview [2] have been heavily worked on to improve reference, fixed
examples, and described architectural motivations and features.
 
Revision 635ccf444e:
- fixed handling of URI to QName
- wired top-down functions with debug flag
- fixed handling of multi-variable SELECT sub queries
- fixed recursive passing on of remaining body literals upon multiple
prior answers
- fixed handling of answers when invoking a rule with multiple prior
answers
- added support for top-down solving of builtins
- fixed matching of adornment when finding rule heads that match
subquery
Revision 0041d3a603:
- fixed handling of normalization of clauses with empty heads
- added explicit exception for unsupported negation
- core support for rule safety with 3 levels of conformance
- fixed handling of Existentials in heads and structure of rules WRT
safety
- added HornFromDL to FuXi.Horn.HornRules
- added methods to support rule safety criteria to all conditions,
etc..
- updated command-line: builtin to SPARQL templates, rule safety,
debug, base/predicate strictness,
evaluation method , namespace handling,
- fix for derived/base predicate introspection
- fix for rule adornment in the face of open query
- handling of Exists
- added DisjunctiveNormalForm helper function to FuXi.DLP
- implementation for builting / SPARQL templates
- top-down method (similar to Prolog w/ Memoing and last call
optimization) is a full generator
- top-down handles special cases: no sips in magic programs (IFP OWL
test)
 
[1] http://code.google.com/p/fuxi/wiki/FuXiUserManual
[2] http://code.google.com/p/fuxi/wiki/Overview

Comments [0]

Updates to FuXi (backward chaining SPARQL/RIF/OWL entailment, various fixes, etc.)

So, I've re-organized python-dlp and FuXi. Originally, I thought of
python-dlp as a library on top of the expert system capabilities of a
SW reasoner (syntax libraries, etc.). Now with a small ecosystem of
(next generation) RDFlib-based, open-source libraries emerging from
the SW informatics being done in our Heart and Vascular Institute:
 
- Telescope 
- SPARQL to SQL method (wiki and changes)
- "rdflib-stable" revisions 
 
I've decided to separate the expert system (FuXi) into its own Google
Code project and decide soon what to do with python-dlp (the idea,
anyways):
 
It has a mercurial repository and can be cloned via:
 
hg clone https://fuxi.googlecode.com/hg/ fuxi
 
So, effectively, FuXi development has switched from SVN to
Mercurial :)
 
Shortly, I'll update the literature (wikis, etc.) on the python-dlp
Google Code project to (for now) act as a detour to the new project
until I determine what features, usecases are still left from the
original idea of having FuXi be everything inference-related on top of
"rdflib-stable"
 
I still have to determine if the RIF-Core XML syntax support should be
done using 4suite-xml, amara, amara2, or Python's (native) XML
processing capabilities (which is what rdflib originally did). This
will have an impact on the ease of distribution, etc.
 
Until then the recent changes are probably the last before the feature-
frozen candidate release testing leading to 1.0:
 
Revision 81d9eec480:
- Fixed use of Set (some performance boost perhaps)
- +++ b/lib/Rete/Magic.py (added imports from proof theory, minor
fixes, empty sip collections,
variable utility function, immutable dictionaries, )
+++ b/lib/Rete/Proof.py (updated proof builder, PML / RDF/XML
serialization, for top-down, query
generating strategies)
+++ b/lib/Rete/SidewaysInformationPassing.py (fix construction of sip
collection)
- Native Prolog-like Python implementation for RIF-Core, OWL, and
SPARQL (can be used to convert
SPARQL in-light of RIF-Core/OWL/OWL2 into a series of top-down
evaluated and combined SPARQL queries
against an RDF dataset)
 
Revision dc70e7a115:
Takes another Uniterm and in every case where the corresponding term
+ for both literals are different variables, we map from the
variable
+ for *this* uniterm to the corresponding variable of the other
.
Revision ff2acf3e96:
- Added --why option to command-line. Adds to a list of SPARQL
queries used to trigger the sip-
strategy to solve them top-down from the ruleset.
- minor checks/fixes for top-down method
 
Revision a0c14690be
fix to handle use of pyparsing or Bison for SPARQL parsing
 
There is a new wiki showing usage of top-down (backward-chaining) RIF/
OWL/N3 solver:
 
Also, the testOWL.py script has been updated with options for running
the OWL test using top-down or bottom-up reasoners:
 
$ python testOWL.py --bottomUp --singleTest=OWL/TransitiveProperty/
premises001
.. snip ..
$ python testOWL.py --topDown=ground --singleTest=OWL/
TransitiveProperty/premises001
.. snip ..
$ python testOWL.py --topDown=ground
ok
.. snip ..
----------------------------------------------------------------------
Ran 1 test in 3.089s
 
OK
 
For example, the command-line can be used to solve a OWL test by
remotely fetching the OWL class descriptions, converting them to RIF-
like rules internally (using the DLP feature), reducing the ruleset
and creating a rule/goal graph using the GMS strategy, taking a SPARQL/ASK
query via the --why option, and solving the query against the original
OWL graph using the new top-down feature, printing out a PML RDF/XML
proof.

Notice the backward chaining method (SipStrategy) can be passed a 'live' database-
connected graph in order to solve the query in backward-chaining
fashion by dispatching SPARQL queries against the possibly large RDF
warehouse).
 
The example below demonstrates the ability to handle the tail-
recursive rulesets / programs that can result from extracting rules
from an OWL ontology that includes RBox axioms about role transitivity
(the path between countries, for example). The top-down algorithm is
similar to prolog with memoization and last call optimization. Both
are trivial to implement in Python using one of many memioze
decorators and native generators respectively.
 
Note, the bottom-up (forward chaining) method using the RETE-UL
decision network is much quicker and only fires one rule (due to
sideways information passing optimization - similar to the kind used
by databases to answer relational queries in the face of live,
immaterial, and possibly recursive views). I'm devising larger in-
memory tests to determine why the forward chain algorithms that much
faster, but I imagine it has something to do with:
 
Ullman, JD , "Bottom-up beats top-down for datalog". Proceedings of
the eighth ACM symposium on Principles of database systems. pp
140-149, 1989, ACM New York, NY, USA.
 
$ time FuXi --ruleFacts --why="ASK { test:Ghent test:path
test:Amsterdam }" --ns=test=http://www.w3.org/2002/03owlt/
TransitiveProperty/premises001# --dlp --output=conflict
http://www.w3.org/2002/03owlt/TransitiveProperty/premises001
 
Time to solve goal ASK { test:Ghent test:path test:Amsterdam } top-
down: 17.4751281738 milli seconds

.. snip PML serlializtion of proof ..

Time to calculate closure on working memory:  2.55084037781 milli seconds

<Network: 1 rules, 4 nodes, 9 tokens in working memory, 1 inferred tokens>

<TerminalNode : CommonVariables: [?thJpxqsn18] (3 in left, 3 in right memories)>

test:path(?X ?thJpxqsn19) :- And( test:path(?X ?thJpxqsn18) test:path(?thJpxqsn18 ?thJpxqsn19) )

1 instanciations 

real 0m2.532s
user 0m1.770s
sys 0m0.479s

Proof generated via renderProof method on ProofBuilder instance

 

Filed under  //   fuxi   logic   logic-programming   n3   owl   rdf   semantic-web  

Comments [0]

On Model Theory

So, I've started a part-time Ph.D program at the EECS department of
Case Western University. I'm hoping to write a thesis on higher
education information science as patient advocacy. I've taken a
course on Machine Learning, database systems, and now on model theory.
 Luckily Case has a class on model theory in the philosophy
department. But it also counts as credit from the graduate
mathematics department.
 
The class on model theory is about Kurt Godel's (I know I'm
misspelling it) theory on the incompleteness theory of peano's
arithmetic ( an axiomatization of number theory ). The book for the
class, It is supposed to be written by mathematical geniuses, our
professor proclaims. The book is ".."
 
Models are states of absolute (binary) logical certainty: things that
are or things that aren't. Statements in this language are 'sound'
(they follow from our understanding of logic). The consist of
domains: sets of 'things' denoted by terms in a written language (a
first-order language). The model also consists of 'interpretations'
of phrases (or formulas) in this language, some of which are 'closed'
(i.e., all variables refer to constants interpreted through this
model) or open. The axiomatic nature of basic science presumes
logical certainty in its canon. The language consists of constants
that can be interpreted 'against' the domain of a model, sets of
constants composed form constants interpreted against the domain of
the model, functions that map sets of members of the domain to members
of the domain, 'relations' over the domains, and a determination of
'equality' over members of the domain. Model theory is the basis of
first-order theory, logic-based knowledge representation, numeric
theory, etc..
 
Godel's theory says that any axiomatic system that is as expressive as
some computable representation of number theory is not complete (i.e.,
there is at least one question you can formulate in the language for
which you cannot say with certainty that it is so or it isn't so).
 
Models 'entail' sets of formulas when they entail all the members of
the set. Models satisfy sentences and 'terms' in languages. Some
formulas can be said to be valid in every model (i.e., they are
satisfied by every model of a language) or they specifically are
entailed by a particular model. Axiomatic machinations (finite state
automata, etc..) are systems about languages and a set of axioms that
can be used to 'derive' expressions in the language via a finite set
of valid theories, specifically given sentences in a theory, or
sentences that follow from modus ponens (common sense if / then
conditionals) and sentences in a theory (a scientific theory).
 
As our prof puts it, all of logic programming (and database theory) is
spawned by this known limitation to model theory and first-order
logic. They are restricted forms of it that are complete (unlike
number theoretic languages), and sound and thus 'decidable' by a
finite state automaton or turing machine.
 
Systems that describe their 'formal semantics' - the meaning of
statements made in their languages often describe them using model
theory (all of semantic web theory does this: RDF, RDFS, OWL-DL,
etc..). More on this later

Comments [0]

Using OWL and Default Negation to Reason about Patient Records

We've been using SPARQL, OWL, and N3 lately to prototype the reporting
of common research variables to the Society of Thoracic Surgeon's
(STS) National Database. The reports are being run against our large
RDF dataset of abstracted electronic patient records from the
Cleveland Clinic's Electronic Health Record system. Our dataset
consists of about 200,000 patients each represented as statements in
named RDF graphs. The STS variables we are responsible for deriving
are represented using a combination of OWL-DL and Notation 3. The
constraints that do not benefit from the restricted, tree-like nature of description logic are captured using secondary plain Horn clauses
(or rules) represented in Notation 3.
 
We use an open source logic reasoning system for the semantic web that
converts the constraints and a SPARQL query for an RDF dataset
governed by these OWL-DL constraints into provably optimal sets of
rules used to calculate an entailed RDF graph (the specifics of this
method is a subject of a paper I'm working on for the RuleML 2009
conference). Such an entailed RDF graph can then be targeted with
SPARQL queries to answer for the STS variables. A recent challenge
has been to try to capture the semantics of negation in order to
implement 'exclusion criteria'. This is typically of the form of a
class of procedures that do not involve combinations of one or more
kinds of other procedures. A recent update to FuXi includes the
ability to convert OWL-DL expressions that use owl:complementOf into
general, stratified, logic programs that can be evaluated using SPARQL
in order to implement the semantics of stable model negation (which is
quite different from the way owl:complementOf is meant to be
interpreted: according to the negation of first-order logic).
 
In particular, statements of classical (first-order) negation are
making assertions about the lack of existence of models that satisfy
the positive form of such a statement in a theory. I prefer this
explanation to the way the term 'open world' assumption is often
used to describe this interpretation of negated terms in a
description logic language. Database theory, ofcourse, does not interpret negated terms
in this way, but instead (intuitively) understands statements of negated terms to be
'true' if the (ground) positive form is not in the set of known facts (the
database).

Our use of negation, and the nature of knowledge
recorded in a computer-based patient record system seems (so far) to
lend itself more to the database interpretation where there is an
understanding that a curated medical information system would have its
data entered under the governance of policies that would allow
medically useful inferences to be made from the absence of certain
facts about patient care.
 
In particular, if a fact is known to not be true about a patient or
some activity involving a patient, it is not recorded. This common
understanding can be used to make inferences about whether facts in a
patient record satisfy an exclusion criteria. Below is an example of
this:
 
Consider the following OWL descriptions of a class of operations:
 

SubClassOf(
 IntersectionOf(
  Operation
  PostOpInHOspitalEvent
  ObjectAllValuesFrom(
  involves
  ComplementOf( UnionOf( CardiacProcedure ThoracicControlBleeding ) ) )
 )
 sts:ReopForOtherNonCardiac )

The syntax above is the OWL2 functional-style syntax. We can
paraphrase the general class inclusion (GCI) axiom above as saying:
".. all operations that followed another operation and do not involve any 
cardiac procedures or thoracic control bleeding procedures.

The original documentation for this variable in the STS adult cardiac
database manual says: 

Indicate whether the patient returned to the operating room for
other non-cardiac reasons

Now, if we assume that all operations of interest and the involved
procedures are explicitly recorded in our patient RDF dataset. This
general class inclusion axioms can be reduced into a set of rules that use negated
'literals' (as they are called); understood to capture the semantics of
default negation (or the 'closed world assumption').  It is worth noting that this is exemplary of a class of expressions that description logic, tableaux-based reasoning algorithms often have problems with.

Conjunctive query answering for stratified datalog is a well-studied class of
problems in database theory. It is through the insight of this canon of theory that FuXi is now able to reduce
OWL-DL expressions that use owl:complementOf into sets of rules (or
logic programs) that can be efficiently processed in order to
implement SPARQL entailment regimes for combinations of OWL and
rule-based representations for the semantic web such as
Notation 3 or RIF core.
 
The current FuXi implementation converts the GCI into the following
two RIF rules:


Forall ?X ?QrjeKHuq961 (
?X # sts:ReopForOtherNonCardiac

  :- And(

    ?X # PostOpInHospitalEvent
    ?X # Operation,
    Naf ?X[involves -> ?QrjeKHuq961] ) )


Forall ?X ?QrjeKHuq961 (
?X # sts:ReopForOtherNonCardiac
  :- And(

    ?X # PostOpInHospitalEvent ,
    ?X # Operation,
    ?X[involves -> ?QrjeKHuq961],
    Naf ?QrjeKHuq961 # CardiacProcedure,
    Naf ?QrjeKHuq961 # ThoracicControlBleeding ) )


 Note, Naf is in the (current) 30 July 2008 version of the "RIF
Framework for Logic Dialects

The first rule describes members of the clas of ReopForOtherNonCardiac as those post-operative operations (i.e., operations that follow another operation in the same patient hospital visit or episode) that do not involve other procedures.

The second rule applies to those post-operative operations that do involve other procedures where these other operations are not either cardiac procedures or thoracic control bleeding procedures.

These RIF rules can be exchanged with other RIF-compliant rule-based
systems that implement any of the well-accepted semantics for negated
formulas in horn clause logic (stable models, well-founded models,
stratified models, etc.). A recent modification to FuXi makes
use of a programmatic SPARQL interface for Python that a colleague of
mind has been working on called telescope. It works with
rdflib (same as FuXi) and is used as a control layer that converts
negated RIF rules into a series of SPARQL queries involving
OPTIONAL/FILTER/!BOUND that are used to calculate "stratified models"
(i.e., the finite set of facts that can be inferred from the set of
rules that include negated literals).
 
Renzo Angles et al. (2008) and Polleres, A. (2007) have since
demonstrated that the expressive power of SPARQL coincides with that
of datalog with negation, so it comes as no suprise that certain
datalog clauses (or rules) can be converted into SPARQL queries using
so-called copy-patterns and the introduction of a MINUS operator. For
the details of how this operator works and how its semantics are
equivalent with that of datalog, the reader is urged to read any of
the above mentioned papers.
 
telescope is used to programatically convert MINUS operators into a
SPARQL queries that answer for RIF rules with the corresponding
negated frame formulas below:
 

SELECT ?X
WHERE {
 ?X a PostOpInHospitalEvent .
 ?X a Operation
 #The post-operative operation does not invlolve any procedures
 OPTIONAL { ?X involves ?QrjeKHuq961 }
 FILTER (!bound(?QrjeKHuq961))
}


SELECT ?X
WHERE {
 ?X a PostOpInHospitalEvent .
 ?X a Operation .
 ?X involves ?QrjeKHuq961
 #In the case where the post-operative operation involves a procedure
it is *not* either a
 # cardiac procedure or a thoracic control bleeding
 OPTIONAL {
  ?QrjeKHuq961 a CardiacProcedure .
  ?QrjeKHuq961 a ThoracicControlBleeding .
  ?QrjeKHuq16542 a CardiacProcedure .
  ?QrjeKHuq16542 a ThoracicControlBleeding
  FILTER (?QrjeKHuq961 = ?QrjeKHuq16542)
 }
 FILTER (!bound(?QrjeKHuq16542))
}


I'll be adding a wiki shortly (on the python-dlp google code wiki)
describing the explicit APIs that can be used for this purpose, but I
wanted to give the feature some context in the recent work I've been
doing on applications of semantic web for medical informatics
 
-- Chimezie

Filed under  //   n3   owl   rdf   semantic-web  

Comments [0]

RDF / OWL Tool Developers Should Respect xml:base!

Okay. I think it needs to be said that RDF / OWL tool-makers do not
do a good job of respecting the mechanics of xml:base . It seems
almost a given that most of them mangle the URI base resolution
conventions they find in existing RDF/OWL files, overwriting them with
their own. Often, this happens in a very destructive way that can be
even more annoying for a person who has much experience using XML and
thus has a better appreciation (perhaps) of the value of a base URI of
an OWL document for more than just owl:Ontology/@rdf:about.
 
This is the typical scenario: I create an OWL document like so:
 
<rdf:RDF>
 <owl:Ontology rdf:about="">
   <owl:imports rdf:resource=".. relative path .."/>
 </owl:Ontology>
 <owl:Class rdf:about="tag:info@example.com#Stuff"/>
</rdf:RDF>

 
First, let me describe the intent here. I think it is perfectly
reasonable to modularize large ontologies into fragments (if you will)
that are bundled together and linked via relative imports. Since they
are bundled together, I often like to use the power of URI resolution
to make relative references to imported OWL documents (as you can see
above) in a way that is completely independent from where the bundle
is being deployed (file system or on the web).
 
The downside of not using xml:base explicitly is that the URIs of my
classes need to be fully qualified, but as far as I'm concerned this
is outweighed by the advantage of knowing that I can deploy my bundled
import network on a website or on a filesystem and have any
self-respecting tool know how to resolve the relative URIs.
 
One of the more involved technical points during the development of
GRDDL was regarding the use of empty URI references in GRDDL results.
The primary importance of empty, relative URI references (in RDF serializations) is the
ability to refer to the containing document without necessarily having
the URI on hand. It was this particular dialogue that made me better
appreciate the power and simplicity of the URI base resolution process
that sits at the bottom of many of the important W3C specifications.
 
From RFC 3986 (the process of determining the Base URI to use when
resolving relative URIs):
 
* The base URI is embedded in the document's content.
* The base URI is that of the encapsulating entity (message, document, or none).
* The base URI is the URI used to retrieve the entity.
* The base URI is defined by the context of the application.
 
Getting back to my example above (this was supposed to be a short
rant). Too often what happens is that when I load an OWL document
such as the oneabove into an OWL editor and save it (even after not
making any changes), it results in:
 
<rdf:RDF xml:base="tag:info@example.com#">
 <owl:Ontology rdf:about="">
   <owl:imports rdf:resource="file:///path/to/OWL/document"/>
 </owl:Ontology>
 <owl:Class rdf:ID="Stuff"/>
</rdf:RDF>

 
<insert appropriate expletive>
 
Now, it's not so much the 'forced' use of rdf:ID that bothers me as
the fact that the relative paths used for the imports are now replaced
with absolute URIs. This sabotages the advantage I once had of being
able to rely on the URI resolution chain to be sufficient for clients
that need to resolve my relative URIs. Essentially, the OWL tool has
monopolized the opportunity to resolve relative URI references.
 
Now, in fairness, it seems much of the motivation of doing this is to
associate an explicit base URI with the ontology itself and often
ontology tools will complain if they are unable to determine an
absolute URI to use for this purpose. I think a better mechanism for
doing this would be explicit attributes or elements rather than
bastardization of the ability to give an explicit URI base in content.
 
It seems to me that if the author wanted to associate an explicit URI
with the ontology he or she would use one in the place of an empty,
relative URI reference. In fact, I would go as far as saying that it
is bad practice to forcibly insert an @xml:base in a document that
doesn't have one *and* uses empty, relative reference!
 
So, for any developers of RDF / OWL tools, please take care in trying
not to enforce a base resolution scheme despite the document author
providing one of their own for reasons that are orthogonal to
associating a URI to an ontology (and more important as far I'm
concerned): deployability.

Filed under  //   owl   rdf   semantic-web   tools   uri  

Comments [0]