Strawman DAML+OIL Query Language Proposal

From: Richard Fikes (fikes@ksl.stanford.edu)
Date: 08/22/01


As I mentioned yesterday in the telecon, a student of mine, Yulin Li,
and I have designed a simple language for querying DAML+OIL knowledge
bases.  The language is specified as a DAML+OIL ontology so that both
queries and the results obtained from asking a query are represented in
DAML+OIL.  So, in order to query a DAML+OIL KB, one expresses a query in
DAML+OIL and the results are returned in DAML+OIL.

The proposal is as follows:

An instance of class Query represents a question posed to a reasoner.  A
query instance consists of two parts: a query premise and a query
pattern.  A query premise is a DAML+OIL KB that is effectively asserted
to the queried KB for the duration of the query.  It is to contain
assumptions particular to the current query.  The query premise can be
empty to indicate the absence of such assumptions.  A query pattern is
the question itself.  It is in effect a conjunction of one or more
triples.  Each triple corresponds to an RDF Statement except that its
predicate, subject, and/or object can be a variable.  Variables present
in a query pattern, if any, are implicitly quantified existentially at
the beginning of the pattern.  Syntactically, a query pattern is in xml
markup.

An answer to a query specifies an instance of the query pattern all of
those RDF statements are entailed by the KB being queried conjoined with
the query premise KB.  An instance of class QueryAnswer represents one
answer to a query.  A query answer instance consists of two principle
parts: the query posed and a set of bindings to the query variables
representing an instantiation of those query variables.


Attached is the ontology for queries and query answers, and the results
of a set of tests queries run through our JTP DAML+OIL reasoner on the
Wines KB.  These are the same test cases I reported on at the PI
meeting.  However, now we have a query-answering interface for JTP that
accepts queries in DAML+OIL and returns the results in DAML+OIL using
the attached ontology.


I am basically sending this out to initiate discussion of a query
language for DAML+OIL.  Here are some open issues of which I am aware:

1) As mentioned in yesterday's telecon, we need to look at the query
languages being designed for RDF and XML to see where we can be
compatible.

2) We probably want to add the ability to include triples in the query
pattern containing evaluable predicates such as "less than" and "greater
than".

3) We will need to add some facilities for stating how many answers are
desired, for the reasoner to state whether the answers it has found are
all there are or all it can find, and perhaps for asking the reasoner
for more answers.

All comments welcome.

Richard
<rdf:RDF
  xmlns:rdf ="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
  xmlns:daml="http://www.daml.org/2001/03/daml+oil#"
  xmlns     ="http://www.ksl.Stanford.EDU/projects/DAML/Proof/query-answer.daml#"
>

<daml:Ontology rdf:about="">
  <daml:versionInfo>$Id: query-answer.daml,v 1.5 2001/08/19 04:40:40 yulinli Exp $</daml:versionInfo>
  <rdfs:comment> An ontology of basic query answering terms </rdfs:comment>
  <daml:imports rdf:resource="http://www.w3.org/1999/02/22-rdf-syntax-ns"/>
  <daml:imports rdf:resource="http://www.w3.org/2000/01/rdf-schema"/>
  <daml:imports rdf:resource="http://www.daml.org/2001/03/daml+oil"/>
</daml:Ontology>



<!-- ======= Constructs about Queries ======= -->


<daml:Class rdf:ID="Query">
  <rdfs:comment> 
	A Query represents a question posed to the reasoner.

	It consists of two principle parts: query premise and query pattern.

	A query premise is an ordinary DAML KB that is effectively asserted
	to the queried KB for the duration of the query. It should contain
	assumptions particular to the current query. The query premise can be
	empty to indicate the absence of such assumptions.

	A query pattern is the question itself. It is in effect a conjunction 
   	of one or more triples. Each triple corresponds to a RDF Statement except 
	that its predicate, subject, or object can be variables. Variables present
	in a query pattern, if any, are implicitly quantified existentially at
	the beginning of the pattern. Syntactically, a query pattern is in xml
	markup.
  </rdfs:comment>

  <rdfs:subClassOf>
    <daml:intersectionOf rdf:parseType="daml:collection">
	<daml:Restriction>
		<daml:onProperty rdf:resource="#queryPremise"/>
		<daml:maxCardinality> 1 </daml:maxCardinality>
	</daml:Restriction>

	<daml:Restriction>
		<daml:onProperty rdf:resource="#queryPattern"/>
		<daml:cardinality> 1 </daml:cardinality>
	</daml:Restriction>
    </daml:intersectionOf>
  </rdfs:subClassOf>
</daml:Class>



<rdf:Property rdf:ID="queryPremise">
  <rdfs:comment>
	A value of queryPremise is a URI of the DamlKB as the premise part
	of the Query.
  </rdfs:comment>

  <rdfs:domain rdf:resource="#Query"/>
  <rdfs:range rdf:resource="#URI"/>
</rdf:Property>



<rdf:Property rdf:ID="queryPattern">
  <rdfs:domain rdf:resource="#Query"/>
  <rdfs:range rdf:resource="#Conjunction"/>
</rdf:Property>



<!-- ======== Constructs about Answers to Queries ======= -->


<daml:Class rdf:ID="QueryAnswer">
  <rdfs:comment>
	A QueryAnswer represents ONE answer to a query.

	It consists of two principle parts: the query posed and 
	a set of bindings to the query variables representing an 
	instantiation of those query variables.
  </rdfs:comment>

  <rdfs:subClassOf>
      	<daml:Restriction>
        	<daml:onProperty rdf:resource="#query"/>
        	<daml:cardinality> 1 </daml:cardinality>
      	</daml:Restriction>
  </rdfs:subClassOf>
</daml:Class>



<rdf:Property rdf:ID="query">
  <rdfs:comment>
	A value of query is a URI of the QueryKB as the Query posed.
  </rdfs:comment>

  <rdfs:domain rdf:resource="#QueryAnswer"/>
  <rdfs:range rdf:resource="#URI"/>
</rdf:Property>



<rdf:Property rdf:ID="variableBinding">
  <rdfs:domain rdf:resource="#QueryAnswer"/>
  <rdfs:range rdf:resource="#VariableBinding"/>
</rdf:Property>



<daml:Class rdf:ID="VariableBinding">
  <rdfs:subClassOf>
    <daml:intersectionOf rdf:parseType="daml:collection">
      	<daml:Restriction>
        	<daml:onProperty rdf:resource="#var"/>
        	<daml:toClass rdf:resource="#Variable"/>
      	</daml:Restriction>

      	<daml:Restriction>
        	<daml:onProperty rdf:resource="#var"/>
        	<daml:cardinality> 1 </daml:cardinality>
      	</daml:Restriction>

      	<daml:Restriction>
        	<daml:onProperty rdf:resource="#val"/>
        	<daml:toClass rdf:resource="#Term"/>
      	</daml:Restriction>

      	<daml:Restriction>
        	<daml:onProperty rdf:resource="#val"/>
        	<daml:cardinality> 1 </daml:cardinality>
      	</daml:Restriction>
    </daml:intersectionOf>
  </rdfs:subClassOf>
</daml:Class>



<!-- ======= Constructs about DAML+OIL Knowledge Bases ======= -->


<daml:Class rdf:ID="DamlKB">
  <rdfs:comment> 
	A DamlKB is a well-formed DAML+OIL knowledge base.
  </rdfs:comment>
</daml:Class>



<daml:Class rdf:ID="QueryKB">
  <rdfs:comment> 
	A QueryKB is a DamlKB that contains exactly one upmost Description, which is
	an instance of Query. 

	All Descriptions in a QueryKB should be explicitly named and indicate the most
	specific types to which the subjects of the Descriptions belong.
  </rdfs:comment>

  <rdfs:subClassOf rdf:resource="#DamlKB"/>
</daml:Class>



<daml:Class rdf:ID="QueryAnswerKB">
  <rdfs:comment> 
	A QueryAnswerKB is a DamlKB that contains zero or more upmost Descriptions, all
	of which are instances of QueryAnswer. 

	All Descriptions in a QueryAnswerKB should be explicitly named and indicate 
	the most specific types to which the subjects of the Descriptions belong.
  </rdfs:comment>

  <rdfs:subClassOf rdf:resource="#DamlKB"/>
</daml:Class>



<!-- ========= Constructs about Logical Expressions ========= -->


<daml:Class rdf:ID="Expression">
  <daml:disjointUnionOf rdf:parseType="daml:collection">
    <daml:Class rdf:about="#Conjunction"/>
    <daml:Class rdf:about="#Triple"/>
    <daml:Class rdf:about="#Term"/>
  </daml:disjointUnionOf>
</daml:Class>



<daml:Class rdf:ID="Conjunction">
  <rdfs:subClassOf>
      	<daml:Restriction>
        	<daml:onProperty rdf:resource="#conjunct"/>
        	<daml:minCardinality> 1 </daml:minCardinality>
      	</daml:Restriction>
  </rdfs:subClassOf>
</daml:Class>



<rdf:Property rdf:ID="conjunct">
  <rdfs:domain rdf:resource="#Conjunction"/>
  <rdfs:range rdf:resource="#Triple"/>
</rdf:Property>



<daml:Class rdf:ID="Triple">
  <rdfs:subClassOf>
    <daml:intersectionOf rdf:parseType="daml:collection">
	<daml:Restriction>
		<daml:onProperty rdf:resource="#predicate"/>
		<daml:cardinality> 1 </daml:cardinality>
	</daml:Restriction>

	<daml:Restriction>
		<daml:onProperty rdf:resource="#subject"/>
		<daml:cardinality> 1 </daml:cardinality>
	</daml:Restriction>

	<daml:Restriction>
		<daml:onProperty rdf:resource="#object"/>
		<daml:cardinality> 1 </daml:cardinality>
	</daml:Restriction>
    </daml:intersectionOf>
  </rdfs:subClassOf>
</daml:Class>



<rdf:Property rdf:ID="predicate">
  <rdfs:domain rdf:resource="#Triple"/>
  <rdfs:range rdf:resource="#PropertyTerm"/>
</rdf:Property>



<rdf:Property rdf:ID="subject">
  <rdfs:domain rdf:resource="#Triple"/>
  <rdfs:range rdf:resource="#Term"/>
</rdf:Property>



<rdf:Property rdf:ID="object">
  <rdfs:domain rdf:resource="#Triple"/>
  <rdfs:range rdf:resource="#Term"/>
</rdf:Property>



<daml:Class rdf:ID="Term">
  <daml:disjointUnionOf rdf:parseType="daml:collection">
    <daml:Class rdf:about="#Variable"/>
    <daml:Class rdf:about="#Constant"/>
  </daml:disjointUnionOf>
</daml:Class>



<daml:Class rdf:ID="Variable">
  <rdfs:subClassOf>
	<daml:Restriction>
		<daml:onProperty rdf:resource="#vName"/>
		<daml:cardinality> 1 </daml:cardinality>
	</daml:Restriction>
  </rdfs:subClassOf>
</daml:Class>



<rdf:Property rdf:ID="vName">
  <rdfs:domain rdf:resource="#Variable"/>
  <rdfs:range rdf:resource="#Identifier"/>
</rdf:Property>



<daml:Class rdf:ID="Constant">
  <daml:disjointUnionOf rdf:parseType="daml:collection">
    <daml:Class rdf:about="#ObjectConstant"/>
    <daml:Class rdf:about="#LiteralConstant"/>
  </daml:disjointUnionOf>
</daml:Class>



<daml:Class rdf:ID="ObjectConstant">
  <rdfs:comment> An ObjectConstant denotes a resource in the object domain </rdfs:comment>

  <rdfs:subClassOf>
	<daml:Restriction>
		<daml:onProperty rdf:resource="#qName"/>
		<daml:cardinality> 1 </daml:cardinality>
	</daml:Restriction>
  </rdfs:subClassOf>
</daml:Class>



<rdf:Property rdf:ID="qName">
  <rdfs:domain rdf:resource="#ObjectConstant"/>
  <rdfs:range rdf:resource="#QualifiedName"/>
</rdf:Property>



<daml:Class rdf:ID="LiteralConstant">
  <rdfs:comment> A LiteralConstant denotes a resource in the datatype domain </rdfs:comment>

  <rdfs:subClassOf>
	<daml:Restriction>
		<daml:onProperty rdf:resource="#literalValue"/>
		<daml:cardinality> 1 </daml:cardinality>
	</daml:Restriction>
  </rdfs:subClassOf>
</daml:Class>



<rdf:Property rdf:ID="literalValue">
  <rdfs:domain rdf:resource="#LiteralConstant"/>
  <rdfs:range rdf:resource="http://www.w3.org/2000/01/rdf-schema#Literal"/>
</rdf:Property>



<daml:Class rdf:ID="PropertyTerm">
  <daml:disjointUnionOf rdf:parseType="daml:collection">
    <daml:Class rdf:about="#Variable"/>
    <daml:Class rdf:about="#PropertyConstant"/>
  </daml:disjointUnionOf>
</daml:Class>



<daml:Class rdf:ID="PropertyConstant">
  <rdfs:subClassOf rdf:resource="#ObjectConstant"/>
</daml:Class>



<!-- ========= Constructs about Names and Web Addresses ========= -->


<daml:Class rdf:ID="QualifiedName">
  <rdfs:subClassOf>
    <daml:intersectionOf rdf:parseType="daml:collection">
	<daml:Restriction>
		<daml:onProperty rdf:resource="#nsName"/>
		<daml:cardinality> 1 </daml:cardinality>
	</daml:Restriction>

	<daml:Restriction>
		<daml:onProperty rdf:resource="#localName"/>
		<daml:cardinality> 1 </daml:cardinality>
	</daml:Restriction>
    </daml:intersectionOf>
  </rdfs:subClassOf>
</daml:Class>



<rdf:Property rdf:ID="nsName">
  <rdfs:domain rdf:resource="#QualifiedName"/>
  <rdfs:range rdf:resource="#URI"/>
</rdf:Property>



<rdf:Property rdf:ID="localName">
  <rdfs:domain rdf:resource="#QualifiedName"/>
  <rdfs:range rdf:resource="#Identifier"/>
</rdf:Property>



<daml:Class rdf:ID="Identifier">
  <rdfs:subClassOf rdf:resource="http://www.w3.org/2000/01/rdf-schema#Literal"/>
</daml:Class>



<daml:Class rdf:ID="URI">
  <rdfs:subClassOf rdf:resource="http://www.w3.org/2000/01/rdf-schema#Literal"/>
</daml:Class>

</rdf:RDF>

=======
Test 1:
=======

------
Query:
------
http://www.ksl.stanford.edu/DAML/query-answer/wines-query1.daml

-------
Result:
-------
<rdf:RDF
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:qa="http://www.ksl.Stanford.EDU/projects/DAML/Proof/query-answer.daml#"
  >
  
  <qa:QueryAnswer rdf:ID="genid1">
    <qa:query>
      http://www.ksl.stanford.edu/DAML/query-answer/wines-query1.daml
    </qa:query>
  </qa:QueryAnswer>
  
</rdf:RDF>


--------
Comment:
--------
This test checks the transitivity of subClassOf.


=======
Test 2:
=======

------
Query:
------
http://www.ksl.stanford.edu/DAML/query-answer/wines-query2.daml

-------
Result:
-------
<rdf:RDF
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:qa="http://www.ksl.Stanford.EDU/projects/DAML/Proof/query-answer.daml#"
  >
  
  <qa:QueryAnswer rdf:ID="genid1">
    <qa:query>
      http://www.ksl.stanford.edu/DAML/query-answer/wines-query2.daml
    </qa:query>
  </qa:QueryAnswer>
  
</rdf:RDF>


--------
Comment:
--------
This test checks the inference of type relationship along the class-subclass chain.


=======
Test 3:
=======

------
Query:
------
http://www.ksl.stanford.edu/DAML/query-answer/wines-query3.daml

-------
Result:
-------
<rdf:RDF
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:qa="http://www.ksl.Stanford.EDU/projects/DAML/Proof/query-answer.daml#"
  >
  
  <qa:QueryAnswer rdf:ID="genid1">
    <qa:query>
      http://www.ksl.stanford.edu/DAML/query-answer/wines-query3.daml
    </qa:query>
    <qa:variableBinding>
      <qa:VariableBinding rdf:ID="genid2">
        <qa:var>
          <qa:Variable rdf:ID="genid3">
            <qa:vName>
              y
            </qa:vName>
          </qa:Variable>
        </qa:var>
        <qa:val>
          <qa:ObjectConstant rdf:ID="genid4">
            <qa:qName>
              <qa:QualifiedName rdf:ID="genid5">
                <qa:nsName>
                  http://www.ksl.stanford.edu/DAML/query-answer/wines-short3.daml#
                </qa:nsName>
                <qa:localName>
                  MEAL
                </qa:localName>
              </qa:QualifiedName>
            </qa:qName>
          </qa:ObjectConstant>
        </qa:val>
      </qa:VariableBinding>
    </qa:variableBinding>
  </qa:QueryAnswer>
  
  <qa:QueryAnswer rdf:ID="genid11">
    <qa:query>
      http://www.ksl.stanford.edu/DAML/query-answer/wines-query3.daml
    </qa:query>
    <qa:variableBinding>
      <qa:VariableBinding rdf:ID="genid12">
        <qa:var>
          <qa:Variable rdf:ID="genid13">
            <qa:vName>
              y
            </qa:vName>
          </qa:Variable>
        </qa:var>
        <qa:val>
          <qa:ObjectConstant rdf:ID="genid14">
            <qa:qName>
              <qa:QualifiedName rdf:ID="genid15">
                <qa:nsName>
                  http://www.w3.org/2000/01/rdf-schema#
                </qa:nsName>
                <qa:localName>
                  Resource
                </qa:localName>
              </qa:QualifiedName>
            </qa:qName>
          </qa:ObjectConstant>
        </qa:val>
      </qa:VariableBinding>
    </qa:variableBinding>
  </qa:QueryAnswer>
  
</rdf:RDF>


--------
Comment:
--------
This test checks the domain constraint on COURSE.


=======
Test 4:
=======

------
Query:
------
http://www.ksl.stanford.edu/DAML/query-answer/wines-query4.daml

-------
Result:
-------
<rdf:RDF
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:qa="http://www.ksl.Stanford.EDU/projects/DAML/Proof/query-answer.daml#"
  >
  
  <qa:QueryAnswer rdf:ID="genid1">
    <qa:query>
      http://www.ksl.stanford.edu/DAML/query-answer/wines-query4.daml
    </qa:query>
    <qa:variableBinding>
      <qa:VariableBinding rdf:ID="genid2">
        <qa:var>
          <qa:Variable rdf:ID="genid3">
            <qa:vName>
              x
            </qa:vName>
          </qa:Variable>
        </qa:var>
        <qa:val>
          <qa:ObjectConstant rdf:ID="genid4">
            <qa:qName>
              <qa:QualifiedName rdf:ID="genid5">
                <qa:nsName>
                  http://www.ksl.stanford.edu/DAML/query-answer/wines-short4.daml#
                </qa:nsName>
                <qa:localName>
                  SEA-HORSE
                </qa:localName>
              </qa:QualifiedName>
            </qa:qName>
          </qa:ObjectConstant>
        </qa:val>
      </qa:VariableBinding>
    </qa:variableBinding>
  </qa:QueryAnswer>
  
</rdf:RDF>


--------
Comment:
--------
This test checks the toClass constraint on FOOD.


=======
Test 5:
=======

------
Query:
------
http://www.ksl.stanford.edu/DAML/query-answer/wines-query5.daml

-------
Result:
-------
Inconsistency detected.

--------
Comment:
--------
This test checks the UniqueProperty constraint on FOOD.


=======
Test 6:
=======

------
Query:
------
http://www.ksl.stanford.edu/DAML/query-answer/wines-query6.daml

-------
Result:
-------
<rdf:RDF
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:qa="http://www.ksl.Stanford.EDU/projects/DAML/Proof/query-answer.daml#"
  >
  
  <qa:QueryAnswer rdf:ID="genid1">
    <qa:query>
      http://www.ksl.stanford.edu/DAML/query-answer/wines-query6.daml
    </qa:query>
    <qa:variableBinding>
      <qa:VariableBinding rdf:ID="genid2">
        <qa:var>
          <qa:Variable rdf:ID="genid3">
            <qa:vName>
              p
            </qa:vName>
          </qa:Variable>
        </qa:var>
        <qa:val>
          <qa:ObjectConstant rdf:ID="genid4">
            <qa:qName>
              <qa:QualifiedName rdf:ID="genid5">
                <qa:nsName>
                  http://www.ksl.stanford.edu/DAML/query-answer/wines-short6.daml#
                </qa:nsName>
                <qa:localName>
                  COLOR
                </qa:localName>
              </qa:QualifiedName>
            </qa:qName>
          </qa:ObjectConstant>
        </qa:val>
      </qa:VariableBinding>
    </qa:variableBinding>
  </qa:QueryAnswer>
  
</rdf:RDF>


--------
Comment:
--------
This test checks the toClass contraint on DRINK.


=======
Test 7:
=======

------
Query:
------
http://www.ksl.stanford.edu/DAML/query-answer/wines-query7.daml

-------
Result:
-------
Inconsistency detected.

--------
Comment:
--------
In this test,
W2 gets SWEET for its SUGAR property because a restriction defined on OYSTER-SHELLFISH-COURSE; 
W2 gets DRY for its SUGAR property because a restriction defined on NON-OYSTER-SHELLFISH-COURSE; 
SWEET is not equivalent to DRY by the unique name assumption;
but SUGAR is a UniqueProperty. Thus an inconsistency results.


=======
Test 8:
=======

------
Query:
------
http://www.ksl.stanford.edu/DAML/query-answer/wines-query8.daml

-------
Result:
-------
Inconsistency detected.

--------
Comment:
--------
There are several inconsistencies of this type in the original wines.daml KB due to
the incorrect use of maxCardinality.


This archive was generated by hypermail 2.1.4 : 04/02/02 EST