OWL-S: Semantic Markup for Web Services

Authors:
David Martin, SRI International (editor)
Mark Burstein, BBN Technologies
Jerry Hobbs, USC Information Sciences Institute (*)
Ora Lassila, Nokia
Drew McDermott, Yale University
Sheila McIlraith, University of Toronto (**)
Srini Narayanan, International Institute of Computer Science (*)
Massimo Paolucci, DoCoMo Communications Laboratories Europe (***)
Bijan Parsia, The MIND Laboratory of the University of Maryland at College Park
Terry Payne, University of Southampton
Evren Sirin, The MIND Laboratory of the University of Maryland at College Park
Naveen Srinivasan, Web Methods (***)
Katia Sycara, Carnegie Mellon University
(*) Jerry Hobbs and Srini Narayanan were affiliated with SRI International when their work on OWL-S was done.
(**) Sheila McIlraith was affiliated with Stanford University (Knowledge Systems Laboratory) for a substantial part of the time that she has worked on OWL-S.
(***) Massimo Paolucci and Naveen Srinivasan were affiliated with Carnegie Mellon University for a large part of the time that they have worked on OWL-S.

Abstract

The Semantic Web should enable greater access not only to content but also to services on the Web. Users and software agents should be able to discover, invoke, compose, and monitor Web resources offering particular services and having particular properties, and should be able to do so with a high degree of automation if desired. Powerful tools should be enabled by service descriptions, across the Web service lifecycle. OWL-S (formerly DAML-S) is an ontology of services that makes these functionalities possible. In this document we describe the overall structure of the ontology and its three main parts: the service profile for advertising and discovering services; the process model, which gives a detailed description of a service's operation; and the grounding, which provides details on how to interoperate with a service, via messages.

Following the layered approach to markup language development, the current version of OWL-S builds on the Ontology Web Language (OWL) Recommendation produced by theWeb-Ontology Working Group at the World Wide Web Consortium (W3C).


Table of contents


1. Introduction: Services on the Semantic Web

Efforts toward the creation of the Semantic Web are gaining momentum [1]. Soon it will be possible to access Web resources by content rather than just by keywords. A significant force in this movement is the development of a new generation of Web markup languages such as OWL[16] and its predecessor DAML+OIL [7,9]. These languages enable the creation of ontologies for any domain and the instantiation of these ontologies in the description of specific Web sites. These languages are also amenable to efficient reasoning procedures and thus reasoning applications can be built to automatically determine the logical consequences of the ontological statements.

Among the most important Web resources are those that provide services. By ``service'' we mean Web sites that do not merely provide static information but allow one to effect some action or change in the world, such as the sale of a product or the control of a physical device. The Semantic Web should enable users to locate, select, employ, compose, and monitor Web-based services automatically.

To make use of a Web service, a software agent needs a computer-interpretable description of the service, and the means by which it is accessed. An important goal for Semantic Web markup languages, then, is to establish a framework within which these descriptions are made and shared. Web sites should be able to employ a standard ontology, consisting of a set of basic classes and properties, for declaring and describing services, and the ontology structuring mechanisms of OWL provide an appropriate, Web-compatible representation language framework within which to do this.

This paper describes a collaborative effort by researchers at several organizations to define just such an ontology. We call this ontology OWL-S1. In what follows, we will first motivate OWL-S in terms of some sample tasks that it is designed to support. In the central part of the paper we describe the upper ontology for services that we have developed, including its subontologies for profiles, processes, and groundings. The ontology is still evolving, and making connections to other development efforts, such as those building ontologies of time and resources. We will sometimes refer to the OWL-S ontology as a language for describing services, reflecting the fact that it provides a standard vocabulary that can be used together with the other aspects of the OWL description language to create service descriptions.

This document reflects the authors' design consensus as of OWL-S version 1.2, which is available at [3]. Please note that, in addition to the OWL ontology files, the release site includes examples and additional forms of documentation, including, in particular, a code walk-through illustrative of many points in this document, additional explanatory material (in HTML) regarding the grounding and the use of profile-based class hierarchies, and information about the status of this work, including unresolved issues and future directions.


2. Some Motivating Tasks

We will be considering both primitive, or ``atomic'' services, and complex or "composite" services. Atomic services are ones where a single Web-accessible computer program, sensor, or device is invoked by a request message, performs its task and perhaps produces a single response to the requester. With atomic services there is no ongoing interaction between the user and the service. For example, a service that returns a postal code or the longitude and latitude when given an address would be in this category. In contrast, complex or 'composite' services are composed of multiple more primitive services, and may require an extended interaction or conversation between the requester and the set of services that are being utilized. One's interaction with www.amazon.com to buy a book is like this; the user searches for books by various criteria, perhaps reads reviews, may or may not decide to buy, and gives credit card and mailing information. OWL-S is meant to support both categories of services, but complex services have motivated many of the ontology's elements. The following three task types will give the reader an idea of the kinds of tasks we expect OWL-S to enable [17,18].

  1. Automatic Web service discovery. Automatic Web service discovery is an automated process for location of Web services that can provide a particular class of service capabilities, while adhering to some client-specified constraints. For example, the user may want to find a service that sells airline tickets between two given cities and accepts a particular credit card. Currently, this task must be performed by a human who might use a search engine to find a service, read the Web page, and execute the service manually, to determine if it satisfies the constraints. With OWL-S markup of services, the information necessary for Web service discovery could be specified as computer-interpretable semantic markup at the service Web sites, and a service registry or ontology-enhanced search engine could be used to locate the services automatically. Alternatively, a server could proactively advertise itself in OWL-S with a service registry, also called middle agent [4,25,15], so that requesters can find it when they query the registry. Thus, OWL-S enables declarative advertisements of service properties and capabilities that can be used for automatic service discovery.
  2. Automatic Web service invocation. Automatic Web service invocation is the automatic invocation of an Web service by a computer program or agent, given only a declarative description of that service, as opposed to when the agent has been pre-programmed to be able to call that particular service. This is required, for example, so that a user can request the purchase, from a site found by searching and then selected by that user, of an airline ticket on a particular flight. Execution of a Web service can be thought of as a collection of remote procedure calls. OWL-S markup of Web services provides a declarative, computer-interpretable API that includes the semantics of the arguments to be specified when executing these calls, and the semantics of the messages that are returned when the services succeed or fail. A software agent should be able to interpret this markup to understand what input is necessary to invoke the service, and what information will be returned. OWL-S, in conjunction with domain ontologies specified in OWL, provides standard means of specifying declaratively APIs for Web services that enable this kind of automated Web service execution.
  3. Automatic Web service composition and interoperation. This task involves the automatic selection, composition, and interoperation of Web services to perform some complex task, given a high-level description of an objective. For example, the user may want to make all the travel arrangements for a trip to a conference. Currently, the user must select the Web services, specify the composition manually, and make sure that any software needed for the interoperation of services that must share information is custom-created. With OWL-S markup of Web services, the information necessary to select and compose services will be encoded at the service Web sites. Software can be written to manipulate these representations, together with a specification of the objectives of the task, to achieve the task automatically. To support this, OWL-S provides declarative specifications of the prerequisites and consequences of application of individual services, and a language for describing service compositions and data flow interactions.

Any Web-accessible program/sensor/device that is declared as a service will be regarded as a service. OWL-S does not preclude declaring simple, static Web pages as services. But our primary motivation in defining OWL-S has been to support more complex tasks of the kinds described above.


3. An Upper Ontology for Services

Our structuring of the ontology of services is motivated by the need to provide three essential types of knowledge about a service (shown in Figure 1), each characterized by the question it answers:

The class Service provides an organizational point of reference for a declared Web service; one instance of Service will exist for each distinct published service. The properties presents, describedBy, and supports are properties of Service. The classes ServiceProfile, ServiceModel, and ServiceGrounding are the respective ranges of those properties. Each instance of Service will present a ServiceProfile description, be describedBy a ServiceModel description, and support a ServiceGrounding description. The details of profiles, models, and groundings may vary widely from one type of service to another--that is, from one instance of Service to another. But each of these three service perspectives provides an essential type of information about the service, as we explain below.

Generally speaking, the ServiceProfile provides the information needed for an agent to discover a service, while the ServiceModel and ServiceGrounding, taken together, provide enough information for an agent to make use of a service, once found.

Figure 1: Top level of the service ontology
Service-Ontology1.1.gif

The service profile tells "what the service does", in a way that is suitable for a service-seeking agent (or matchmaking agent acting on behalf of a service-seeking agent) to determine whether the service meets its needs. This form of representation includes a description of what is accomplished by the service, limitations on service applicability and quality of service, and requirements that the service requester must satisfy to use the service successfully.

The service model tells a client how to use the service, by detailing the semantic content of requests, the conditions under which particular outcomes will occur, and, where necessary, the step by step processes leading to those outcomes. That is, it describes how to ask for the service and what happens when the service is carried out. For nontrivial services (those composed of multiple steps over time), this description may be used by a service-seeking agent in at least four different ways: (1) to perform a more in-depth analysis of whether the service meets its needs; (2) to compose service descriptions from multiple services to perform a specific task; (3) during the course of the service enactment, to coordinate the activities of the different participants; and (4) to monitor the execution of the service.

A service grounding ("grounding" for short) specifies the details of how an agent can access a service. Typically a grounding will specify a communication protocol, message formats, and other service-specific details such as port numbers used in contacting the service. In addition, the grounding must specify, for each semantic type of input or output specified in the ServiceModel, an unambiguous way of exchanging data elements of that type with the service (that is, the serialization techniques employed).

The upper ontology for services specifies only two cardinality constraints: a service can be described by at most one service model, and a grounding must be associated with exactly one service. The upper ontology deliberately does not specify any minimum cardinality for the properties presents or describedBy. (Although, in principle, a service needs all three properties to be fully characterized, it is easy to imagine situations in which a partial characterization could be useful.) Nor does the upper ontology specify any maximum cardinality for presents or supports. (It will be extremely useful for some services to offer multiple profiles and/or multiple groundings.)

Finally, it must be noted that while we define one particular upper ontology for profiles, one for service models, and one for groundings, nevertheless OWL-S allows for the construction of alternative approaches in each case. Our intent here is not to prescribe a single approach in each of the three areas, but rather to provide default approaches that will be useful for the majority of cases. In the following three sections we discuss the resulting service profile, service model, and service grounding in greater detail.


4. Service Profiles

A transaction in a web services marketplace involves three parties: the service requesters, the service provider, and infrastructure components [24,25]. The service requester, which may broadly identify with the buyer, seeks a service to complete its work; the service provider, which can be broadly identified with the seller, provides a service sought by the requester. In an open environment such as the Internet, the requester may not know ahead of time of the existence of the provider, so the requester relies on infrastructure components that act like registries to find the appropriate provider. For instance, a requester may need a news service that reports stock quotes with no delay with respect to the market. The role of the registries is to match the request with the offers of service providers to identify which of them is the best match. Within the OWL-S framework, the Service Profile provides a way to describe the services offered by the providers, and the services needed by the requesters.

The Service Profile does not mandate any representation of services; rather, using the OWL subclassing it is possible to create specialized representations of services that can be used as service profiles. OWL-S provides one possible representation through the class Profile. An OWL-S Profile describes a service as a function of three basic types of information: what organization provides the service, what function the service computes, and a host of features that specify characteristics of the service. The three pieces of information are reviewed in order below.

The provider information consists of contact information that refers to the entity that provides the service. For instance, contact information may refer to the maintenance operator that is responsible for running the service, or to a customer representative that may provide additional information about the service.

The functional description of the service is expressed in terms of the transformation produced by the service. Specifically, it specifies the inputs required by the service and the outputs generated; furthermore, since a service may require external conditions to be satisfied, and it has the effect of changing such conditions, the profile describes the preconditions required by the service and the expected effects that result from the execution of the service. For example, a selling service may require as a precondition a valid credit card and as input the credit card number and expiration date. As output it generates a receipt, and as effect the card is charged.

Finally, the profile allows the description of a host of properties that are used to describe features of the service. The first type of information specifies the category of a given service, for example, the category of the service within the UNSPSC classification system. The second type of information is quality rating of the service: some services may be very good, reliable, and quick to respond; others may be unreliable, sluggish, or even malevolent. Before using a service, a requester may want to check what kind of service it is dealing with; therefore, a service may want to publish its rating within a specified rating system, to showcase the quality of service it provides. It is up to the service requester to use this information, to verify that it is indeed correct, and to decide what to do with it. The last type of information is an unbounded list of service parameters that can contain any type of information. The OWL-S Profile provides a mechanism for representing such parameters; which might include parameters that provide an estimate of the max response time, to the geographic availability of a service.

4.1 Compiling a Profile: The Relation with Process Model

The Profile of a service provides a concise description of the service to a registry, but once the service has been selected the Profile is useless; rather, the client will use the Process Model to control the interaction with the service. Although the Profile and the Process Model play different roles during the transaction between Web services, they are two different representations of the same service, so it is natural to expect that the input, output, precondition, and results (hereafter IOPRs) of one are reflected in the IOPRs of the other. However, it is possible that the Profile would only describe some of the inputs, outputs, preconditions and results that the complete process model does, or describe them more generally than the process model does, especially when the service has the potential to produce a variety of results on request. Just as an rental car company advertisement or yellow pages entry might would not specify all of the information to be provided and all of the conditions to be agreed to when signing a contract to rent a car.

OWL-S does not dictate any constraint between Profiles and Process Models, so the two descriptions may be inconsistent without affecting the validity of the OWL expression. Still, if the Profile describes a service that is not consistent with the service represented in the Process Model, the interaction will break at some point. As an extreme example, imagine a service that advertises as a travel agent, but adopts the process model of a book selling agent; it will be selected to reserve travels, but it will fail to do that, asking instead for book titles and ISBN numbers. On the other side, it will never be selected by services that want to buy books, so it will never sell a book either.

Ideally, one might expect that all inputs, outputs, etc. of a process model would appear in the Profile. On the other hand, some of those IOPRs may be so general or so specific that they do not contribute to how one would describe the class of service one is seeking in a query to a registry or matchmaker. These aspects are thus of little value in a profile. Profile developers may also want to consider or be aware of the registry's algorithm for matching requests with providers, and the ontologies used for representing profiles and profile queries, so as to understand which kinds of inexact matches will work. The Profile of a service implicitly specifies the intended purpose of the service: it advertises those functionalities that the service wants to provide, while it may hide (not declare publicly) other functionalities. As an example, consider a book-selling service that includes two component functionalities: the first one allows other services to browse its site to find books of interest, and the second one allows users to buy the books they found. The book seller has the choice of advertising just the book-buying functionality or both the browsing functionality and the buying functionality independently. In the latter case, the service makes public the fact that it can provide browsing services, and it allows everybody to browse its registry without buying a book. In contrast, by advertising only the book-selling functionality, but not the browsing, the agent discourages browsing by requesters who do not intend to buy. The decision as to which functionalities to advertise determines how the service will be used: a requester who intends to browse but not to buy would select a service that advertises both buying and browsing capabilities, but not one that advertises buying only.

Thus far, we tacitly assumed a registry model in which service capabilities are advertised, and then matched against requests of service. This is the model adopted by registries like UDDI. While this is the most likely model to be adopted by Web services, other forms of registry are also possible. For example, when the demand for a service is higher than the supply, then advertising needs for service is more efficient then advertising offered services since a provider can select the next request as soon as it is free; furthermore, in a pure P2P architecture there would be no registry at all. Indeed the types of registry may vary widely and as many as 28 different types have been identified [25,4]. By using a declarative representation of Web services, the service profile is not committed to any form of registry, but it can be used in all of them. Since the service profile represents both offers of services and needs of services, then it can be used in a reverse registry that records needs and queries on offers. Indeed, the Service Profile can be used in all 28 types of registry.

4.2 Profile Properties

In the following we describe in detail the main parts of the profile model; we classify them into four sections: the first one (4.2.1) describes the properties that link the Service Profile class with the Service class and Process Model class; the second section (4.2.2) describes the form of contact information and the Description of the profile -- this is information usually intended for human consumption; in the third section (4.2.3), we discuss the functional representation in terms of IOPRs; finally, in the last section (4.2.4), we list Profile elements that have been recently deprecated.


4.2.1 Service Profile

The class ServiceProfile provides a superclass of every type of high-level description of the service. ServiceProfile does not mandate any representation of services, but it mandates the basic information to link any instance of profile with an instance of service.

There is a two-way relation between a service and a profile, so that a service can be related to a profile and a profile to a service. These relations are expressed by the properties presents and presentedBy.

presents
describes a relation between an instance of service and an instance of profile, it basically says that the service is described by the profile.
presentedBy
is the inverse of presents; it specifies that a given profile describes a service.


4.2.2 Service Name, Contacts and Description

Some properties of the profile provide human-readable information that is unlikely to be automatically processed. These properties include serviceName, textDescription and contactInformation. A profile may have at most one service name and text description, but as many items of contact information as the provider wants to offer.

serviceName
refers to the name of the service that is being offered. It can be used as an identifier of the service.
textDescription
provides a brief description of the service. It summarizes what the service offers, it describes what the service requires to work, and it indicates any additional information that the compiler of the profile wants to share with the receivers.
contactInformation
provides a mechanism of referring to humans or individuals responsible for the service (or some aspect of the service). The range of this property is unspecified within OWL-S, but can be restricted to some other ontology, such as FOAF, VCard, or the simple Actor class provided with OWL-S.


4.2.3 Functionality Description

An essential component of the profile is the specification of what functionality the service provides and the specification of the conditions that must be satisfied for a successful result. In addition, the profile specifies what conditions result from the service, including the expected and unexpected results of the service activity. The OWL-S Profile represents two aspects of the functionality of the service: the information transformation (represented by inputs and outputs) and the state change produced by the execution of the service (represented by preconditions and effects). For example, to complete the sale, a book-selling service requires as input a credit card number and expiration date, but also the precondition that the credit card actually exists and is not overdrawn. The result of the sale is the output of a receipt that confirms the proper execution of the transaction, and as effect the transfer of ownership and the physical transfer of the book from the warehouse of the seller to the address of the buyer.

The Profile ontology does not provide a schema to describe IOPR instances. However, such a schema exists in the Process ontology, as discussed in the next section. Ideally, we envision that the IOPR's published by the Profile are a subset of those published by the Process. Therefore, the Process part of a description will create all the IOPR instances and the Profile instance can simply point to these instances. In this case a single instance is created for any IOPR, unlike in previous versions of OWL-S when, for a certain IOPR, an instance was created both in the Profile and Process part of the OWL-S description. However, if the IOPR's of the Profile are different from those of the Process, the Profile can still create its own IOPR instances using the schema offered by the Process ontology.

The Profile ontology defines the following properties of the Profile class for pointing to IOPR's:

hasParameter
ranges over a Parameter instance of the Process ontology. Note that the Parameter class models our intuition that Inputs and Outputs (which are kinds of Parameters) are both involved in information transformation and therefore they are different from Preconditions and Effects. As a consequence, we do not expect this class to be instantiated. It's role is solely making domain knowledge explicit.
hasInput
ranges over instances of Inputs as defined in the Process Ontology.
hasOutput
ranges over instances of type Output, as defined in the Process ontology.
hasPrecondition
specifies one of the preconditions of the service and ranges over a Precondition instance defined according to the schema in the Process ontology.
hasResult
specifies one of the results of the service, as defined by the Result class in the Process ontology. It specifies under what conditions the outputs are generated. Furthermore, the Result specifies what domain changes are produced during the execution of the service.

See Figure  2, which shows selected properties of the Profile. Note that Figure 2 also portrays the simple Actor class, which is included as part of the OWL-S release, in the ontology file ActorDefault.owl.

Figure 2: Selected classes and properties of the Profile
Profile-Ontology-1.2.gif


4.2.4 Deprecated Profile Properties

As of release 1.2, the following properties of Profile have been deprecated: serviceParameter, serviceCategory, serviceClassification, and serviceProduct. OWL-S users who need "special purpose" properties such as these, or domain-specific properties, are encouraged to create a new ontology that contains a subclass of Profile (and imports Profile.owl), and declares the additional needed properties with the subclass as their domain.

For backwards compatibility, these properties and related ontology elements are still available and can still be used by importing selected ontology files, as follows:

For documentation of these deprecated properties and related elements, please consult the release 1.1 Technical Overview.


5. Modeling Services as Processes

To give a detailed perspective on how to interact with a service, it can be viewed as a process. Specifically, OWL-S 1.2 defines Process as a subclass of ServiceModel. The OWL-S notation of a process draws upon well-established work in a variety of fields, including work in AI on standardizations of planning languages [6], work on languages for business processes [26], work in programming languages and distributed systems [20,19], emerging standards in process modeling and workflow technology such as the NIST's Process Specification Language (PSL) [22] and the Workflow Management Coalition effort (http://www.aiim.org/wfmc), work on modeling verb semantics and event structure [21], previous work on action-inspired Web service markup [18], work in AI on modeling complex actions [13], and work in agent communication languages [15,5].

It is important to understand that a process is not a program to be executed. It is a specification of the ways a client may interact with a service or set of related services. An atomic process is a description of a service that expects one (possibly complex) message and returns one (possibly complex) message in response. A composite process is one that maintains some state; each message the client sends advances it through the process.

A web service process can have two sorts of purpose. First, it can generate and return some new information based on information it is given and the world state. Information production is described by the inputs and outputs of the process. Second, it can produce a change in the world. This transition is described by the preconditions and effects of the process.

A process can have any number of inputs (including zero). Inputs represent the information that must be specified for the service to produce a particular kind of result. Services can have any number of outputs, the information that the process provide back to the requester. There can also be any number of preconditions. All preconditions must hold in order for the process to be successfully invoked. Finally, the process can have any number of effects. Outputs and effects can depend on conditions that hold true of the world state at the time the process is performed. When a particular set of conditions hold, and a set of outputs and effects are produced, we cal this a result (We use the term perform instead of execute to de-emphasize the traditional picture of a single agent being responsible for the occurrence of the process.)

Before we can go into the details of how processes work, it's necessary to explain how inputs, outputs, preconditions, and results (colloquially known as IOPRs) work, because fitting them into the OWL framework requires bending the rules somewhat.

5.1 Parameters and Expressions

Inputs and outputs are subclasses of a general class called Parameter, itself a subclass of ProcessVar. It's convenient to identify process vars with what are called variables in SWRL, the language for expressing OWL Rules, so we declare ProcessVar a subclass of SWRL variables.

<owl:Class rdf:about="#ProcessVar">
  <rdfs:subClassOf rdf:resource="&swrl;#Variable"/>
</owl:Class>

Every process var has a type, specified using a URI. This is not the OWL class the variable belongs to, but a specification of the class (or datatype) its values belong to.

<owl:DatatypeProperty rdf:ID="parameterType">
  <rdfs:domain rdf:resource="#ProcessVar"/>
  <rdfs:range rdf:resource="&xsd;anyURI"/>
</owl:DatatypeProperty>

Parameters, Existential variables, Participants, ResultVars and Local variables are all distinct (that is, disjoint) subclasses of ProcessVar:

<owl:Class rdf:ID="ProcessVar">
 <rdfs:subClassOf>
   <owl:Restriction>
     <owl:onProperty rdf:resource="#parameterType" />
     <owl:cardinality rdf:datatype="&xsd;#nonNegativeInteger">1</owl:cardinality>
   </owl:Restriction>
 </rdfs:subClassOf>
 <owl:unionOf rdf:parseType="Collection">
   <owl:Class rdf:about="#Parameter"/>
   <owl:Class rdf:about="#Existential"/>
   <owl:Class rdf:about="#Participant"/>
   <owl:Class rdf:aobut="#ResultVar"/>
   <owl:Class rdf:about="#Local"/>
 </owl:unionOf>
</owl:Class>
We'll describe each of these (and provide the disjointness conditions) in the appropriate place. Note that we use the term parameterType to refer to the types of all ProcessVars, not just Parameters. We like the way it sounds, and the alternatives don't seem any clearer.

Parameters are the disjoint union of Inputs and Outputs.


<owl:Class rdf:ID="Parameter">
  <rdfs:comment>
      Parameter is the disjoint union of Input and Output
  </rdfs:comment>
  <owl:unionOf rdf:parseType="Collection">
    <owl:Class rdf:about="#Input"/>
    <owl:Class rdf:about="#Output"/>
  </owl:unionOf>
</owl:Class>

<owl:Class rdf:ID="Input">
  <rdfs:subClassOf rdf:resource="#Parameter"/>
  <owl:disjointWith rdf:resource="#Output"/>
</owl:Class>

Modeling variables as global, named individuals, as is done for Owl Rules, can be misleading. RDF has no notion of the ``scope'' of a variable, because an RDF document is nothing but a pile of triples. A variable is named with a URI, like any other resource, and so has global scope, or, more accurately, no notion of scope at all. In spite of this lack of structure, we often use RDF to encode hierarchical entites such as formulas and control structures. Wrapping variable references inside literals allows us to sneak in and impose our own scoping rules. We discuss the OWL-S rules in section 5.2.

A process will not execute properly unless its preconditions are true. If and when it does execute, it has various effects. For example, an agent can order 1000 bolts from a web service only if it can get the web service to accept its promise to pay. One effect of placing the order is the transfer of ownership of the bolts from the service to the agent (or the legal person for which it is a proxy).

Preconditions and effects are represented as logical formulas. Getting logical formulas into RDF has not been easy, but it is now reasonably clear how to proceed. There are actually several possible approaches, depending on how close to RDF/OWL one wants to remain. Usually having lots of choices for such a crucial job is a bad idea, but in this case most of the differences are superficial; it is fairly easy to translate between alternative notations.

The key idea underpinning our approach is to treat expressions as literals, either string literals or XML literals. The latter case is used for languages whose standard encoding is in XML, such as SWRL [8] or RDF [11]. The former case is for other languages such as KIF [10] and PDDL [6]. The ontology [http://www.daml.org/services/owl-s/1.2/generic/Expression.owl] defines Expressions and their properties.

<owl:Class rdf:ID="Expression">
  <rdfs:subClassOf>
    <owl:Restriction>
      <owl:onProperty rdf:resource="#expressionLanguage"/>
      <owl:cardinality rdf:datatype="&xsd;nonNegativeInteger">
                   1</owl:cardinality>
    </owl:Restriction>
  </rdfs:subClassOf>
  <rdfs:subClassOf>
    <owl:Restriction>
      <owl:onProperty rdf:resource="#expressionBody"/>
      <owl:cardinality rdf:datatype="&xsd;nonNegativeInteger">
                   1</owl:cardinality>
    </owl:Restriction>
  </rdfs:subClassOf>
</owl:Class>

We annotate expressions with the language they are expressed in:

<owl:ObjectProperty rdf:ID="&expr;#expressionLanguage">
  <rdfs:domain rdf:resource="&expr;#Expression"/>
  <rdfs:range rdf:resource="&expr;#LogicLanguage"/> 
</owl:ObjectProperty>

The expressionBody property gives the actual expression:

<owl:DatatypeProperty rdf:ID="expressionBody">
  <rdfs:domain rdf:resource="#Expression"/>
</owl:DatatypeProperty>

As an example, we might state that in order to send the number of a certain credit card to a web agent, one must know what its number is:

  <Description rdf:about="#process2">
     <hasPrecondition>
        <expr:KIF-Expression>
           <expr:expressionBody>
             (!agnt:know_val_is 
                    (!ecom:credit_card_num ?cc) 
                    ?num)
           </expr:expressionBody>
        </expr:KIF-Expression>
     </hasPrecondition>
  </Description>

(where the notation ``!ecom:'' for namespaces is taken from Lassila's WILBUR system [12]). (The declaration of the variable ?cc is not shown. We'll come back to that point shortly.)

In cases where an XML encoding is used, we would declare an expression to be an XML literal. Here's the same example using DRS as the expression language:

  <Description rdf:about="#process2">
     <hasPrecondition>
        <Expression expressionLanguage="&drs;#DRS">
           <process:expressionBody>
              <drs:Atomic_formula>
                 <rdf:predicate rdf:resource="&agnt;#Know_val_is"/>
                 <rdf:subject>
                    <drs:Functional_term>
                       <drs:function rdf:resource="&ecom;credit_card_num"/>
                       <drs:term_args rdf:parseType="Collection">
                          <swrl:Variable rdf:resource="#CC"/>
                       </drs:term_args>
                    </drs:Functional_term>
                 </rdf:subject>
                 <rdf:object rdf:resource="#Num"/>
              </drs:Atomic_formula>
           </process:expressionBody>
        </Expression>
     </hasPrecondition>
  </Description>

The references to #CC and #Num in the DRS example are to parameters, the same ones written as ?cc and ?num in the KIF example. We haven't yet provided a mechanism for declaring the scopes of variables (see section 5.2) and how they acquire values. Roughly speaking, parameters and other variables are scoped to the process where they are used. We will describe this in more detail later. In the example, #CC is an input parameter to the process, that is, supplied by the client, but #Num is supposed to be set in the process of reasoning about this very precondition. Verifying that the process is feasible requires retrieving the credit-card's 16-digit number, which is then associated with the variable #Num. We call this an existential variable.

<owl:Class rdf:ID="Existential">
   <rdfs:subClassOf rdf:resource="#ProcessVar"/>
   <owl:disjointwith rdf:resource="#Parameter"/>
</owl:Class>

Of course, flagging bits of RDF as ``Literals'' means that an RDF parser should ignore them. (If it did not, then it might turn the RDF into a set of triples with a simple declarative meaning, which is not appropriate.) The trick is to have the OWL-S parser extract the ignored stuff and interpret it appropriately for its context, treating it as ordinary RDF after transformations such as replacing occurrences of variables with their values. In the example above, the occurrences of #num and #cc are interpreted as the values of these variables, not the variables themselves. In the KIF example, the expressions ?num and ?cc must be similarly interpreted. It is usually not too difficult to do this sort of ``field engineering'' to interface an assertional language to RDF.

There are two special cases of Expression: Condition and Effect. Because they are implemented as literals, there is no way to declare what this difference is, but it's a useful distinction for a human reader of the ontology.

<owl:Class rdf:ID="Condition">
   <owl:subClassOf rdf:resource="&expr;#Expression"/>
</owl:Class>

<owl:Class rdf:ID="Effect">
   <owl:subClassOf rdf:resource="&expr;#Expression"/>
</owl:Class>


5.2 Process Parameters and Results

We connect processes to their "IOPRs" using the properties shown in this table:

Property Range Kind
hasParticipant Participant ProcessVar
hasInput Input Parameter
hasOutput Output Parameter
hasExistential Existential ProcessVar
hasPrecondition Condition Expression
hasResult Result (see below)

As promised above, the links from a process to its parameters implicitly gives them scope. Participant, input, output, and existential variables have as scope the entire process they occur in. We introduce result vars and local vars below, which have a narrower scope.

In the rest of this section, we will discuss the entries in this table.

5.3 Atomic and Simple Processes

We are now ready to formalize the classes of processes: atomic, composite, and, not mentioned before, ``simple.''

<owl:Class rdf:ID="Process">
  <rdfs:comment> The most general class of processes </rdfs:comment>
  <owl:unionOf rdf:parseType="Collection">
    <owl:Class rdf:about="#AtomicProcess"/>
    <owl:Class rdf:about="#SimpleProcess"/>
    <owl:Class rdf:about="#CompositeProcess"/>
  </owl:unionOf>
</owl:Class>

See Figure  3, which shows selected classes and properties of the process model.

Figure 3: Top level of the process ontology
Process-Model-1.2.gif

Atomic processes correspond to the actions a service can perform by engaging it in a single interaction; composite processes correspond to actions that require multi-step protocols and/or multiple server actions; finally, simple processes provide an abstraction mechanism to provide multiple views of the same process. We discuss atomics and simples here, reserving composites for the next subsection.

Atomic processes are directly invocable (by passing them the appropriate messages). Atomic processes have no subprocesses and execute in a single step, as far as the service requester is concerned. That is, they take an input message, do something, and then return their output message. For each atomic process, there must be provided a grounding that enables a service requester to construct messages to the process from its inputs and deconstruct replies, as explained in Section 6.

<owl:Class rdf:ID="AtomicProcess">
  <owl:subClassOf rdf:resource="#Process"/>
</owl:Class>

Simple processes are not invocable and are not associated with a grounding, but, like atomic processes, they are conceived of as having single-step executions. Simple processes are used as elements of abstraction; a simple process may be used either to provide a view of (a specialized way of using) some atomic process, or a simplified representation of some composite process (for purposes of planning and reasoning). In the former case, the simple process is realizedBy the atomic process; in the latter case, the simple process expandsTo the composite process (see below).

<owl:Class rdf:ID="SimpleProcess">
  <rdfs:subClassOf rdf:resource="#Process"/>
  <owl:disjointWith rdf:resource="#AtomicProcess"/>
</owl:Class>

<owl:ObjectProperty rdf:ID="realizedBy">
  <rdfs:domain rdf:resource="#SimpleProcess"/>
  <rdfs:range rdf:resource="#AtomicProcess"/>
  <owl:inverseOf rdf:resource="#realizes"/>
</owl:ObjectProperty>

<owl:ObjectProperty rdf:ID="realizes">
  <rdfs:domain rdf:resource="#AtomicProcess"/>
  <rdfs:range rdf:resource="#SimpleProcess"/>
  <owl:inverseOf rdf:resource="#realizedBy"/>
</owl:ObjectProperty>

Finally, for an atomic process, there are always only two participants, TheClient and TheServer:

<owl:Class rdf:about="#AtomicProcess">
    <rdfs:subClassOf>
      <owl:Restriction>
        <owl:onProperty rdf:resource="#hasClient"/>
        <owl:hasValue rdf:resource="#TheClient"/>
      </owl:Restriction>
    </rdfs:subClassOf>
    <rdfs:subClassOf>
      <owl:Restriction>
        <owl:onProperty rdf:resource="#performedBy"/>
        <owl:hasValue rdf:resource="#TheServer"/>
      </owl:Restriction>
    </rdfs:subClassOf>
</owl:Class>

5.4 Composite Processes

Composite processes are decomposable into other (non-composite or composite) processes; their decomposition can be specified by using control constructs such as Sequence and If-Then-Else, which are discussed below. Because many of the control constructs have names reminiscent of control structures in programming languages, it is easy to lose sight of a fundamental difference: a composite process is not a behavior a service will do, but a behavior (or set of behaviors) the client can perform by sending and receiving a series of messages. If the composite process has an overall effect, then the client must perform the entire process in order to achieve that effect. We have not yet given a precise specification of what it means to perform a process, but all we mean is that, e.g., if a composite is a Sequence, then the client sends a series of messages that invoke every step in order.

One crucial feature of a composite process is its specification of how its inputs are accepted by particular subprocesses, and how its various outputs are produced by particular subprocesses. We discuss this topic in section 5.5.

<owl:Class rdf:ID="CompositeProcess">
  <rdfs:subClassOf rdf:resource="#Process"/>
  <owl:disjointWith rdf:resource="#AtomicProcess"/>
  <owl:disjointWith rdf:resource="#SimpleProcess"/>
  <rdfs:comment>
    A CompositeProcess must have exactly 1 composedOf property.
  </rdfs:comment>
  <owl:intersectionOf rdf:parseType="Collection">
      <owl:Class rdf:about="#Process"/>
      <owl:Restriction>
         <owl:onProperty rdf:resource="#composedOf"/>
         <owl:cardinality rdf:datatype="&xsd;#nonNegativeInteger">
                  1</owl:cardinality>
      </owl:Restriction>
  </owl:intersectionOf>
</owl:Class>

A CompositeProcess must have a composedOf property by which is indicated the control structure of the composite, using a ControlConstruct.

<owl:ObjectProperty rdf:ID="composedOf">
  <rdfs:domain rdf:resource="#CompositeProcess"/>
  <rdfs:range rdf:resource="#ControlConstruct"/>
</owl:ObjectProperty>

<owl:Class rdf:ID="ControlConstruct">
</owl:Class>

Each control construct, in turn, is associated with an additional property called components to indicate the nested control constructs from which it is composed, and, in some cases, their ordering.

<owl:ObjectProperty rdf:ID="components">
 <rdfs:domain rdf:resource="#ControlConstruct"/>
</owl:ObjectProperty>

For instance, any instance of the control construct Sequence has a components property that ranges over a ControlConstructList (a list of control constructs). We give a complete table of composite control constructs below.

Any composite process can be considered a tree whose nonterminal nodes are labeled with control constructs, each of which has children specified using components. The leaves of the tree are invocations of other processes, indicated as instances of class Perform.

<owl:Class rdf:ID="Perform">
  <rdfs:subClassOf rdf:resource="#ControlConstruct"/>
  <rdfs:subClassOf> 
    <owl:Restriction>
      <owl:onProperty rdf:resource="#process"/>
      <owl:cardinality rdf:datatype="&xsd;#nonNegativeInteger">
                   1</owl:cardinality>
    </owl:Restriction>
  </rdfs:subClassOf>
</owl:Class>

The process property of a perform indicates the process to be performed:

<owl:ObjectProperty rdf:ID="process">
  <rdfs:domain rdf:resource="#Perform"/>
  <rdfs:range rdf:resource="#Process"/>
</owl:ObjectProperty>

When a process is performed as a step in a larger process, there must be a description of where the inputs to the performed process come from and where the outputs go. This issue we defer to section 5.5.

A process can often be viewed at different levels of granularity, either as a primitive, undecomposable process or as a composite process. These are sometimes referred to as ``black box'' and ``glass box'' views, respectively. Either perspective may be the more useful in some given context. When a composite process is viewed as a black box, a simple process can be used to represent this. In this case, the relationship between the simple and composite is represented using the expandsTo property, and its inverse, the collapsesTo property.

<owl:ObjectProperty rdf:ID="expandsTo">
  <rdfs:domain rdf:resource="#SimpleProcess"/>
  <rdfs:range rdf:resource="#CompositeProcess"/>
  <owl:inverseOf rdf:resource="#collapsesTo"/>
</owl:ObjectProperty>

<owl:ObjectProperty rdf:ID="collapsesTo">
  <rdfs:domain rdf:resource="#CompositeProcess"/>
  <rdfs:range rdf:resource="#SimpleProcess"/>
  <owl:inverseOf rdf:resource="#expandsTo"/>
</owl:ObjectProperty>

We conclude this section with an overview of the OWL-S control constructs: Sequence, Split, Split + Join, Choice, Any-Order, Condition, If-Then-Else, Iterate, Repeat-While, Repeat-Until, and AsProcess.

Sequence
A list of control constructs to be done in order.
<owl:Class rdf:ID="Sequence">
  <rdfs:subClassOf rdf:resource="#ControlConstruct"/>
  <rdfs:subClassOf>
    <owl:Restriction>
      <owl:onProperty rdf:resource="#components"/>
      <owl:allValuesFrom rdf:resource="#ControlConstructList"/>
    </owl:Restriction>
  </rdfs:subClassOf>
</owl:Class>

A ControlConstructList is just a List whose elements are control constructs.

Split
The components of a Split process are a bag of process components to be executed concurrently. Split completes as soon as all of its component processes have been scheduled for execution.
<owl:Class rdf:ID="Split">
  <rdfs:subClassOf rdf:resource="#ControlConstruct"/>
  <rdfs:subClassOf>
    <owl:Restriction>
      <owl:onProperty rdf:resource="#components"/>
      <owl:allValuesFrom rdf:resource="#ControlConstructBag"/>
    </owl:Restriction>
  </rdfs:subClassOf>
</owl:Class>

A ControlConstructBag is like a ControlConstructList, but unordered.

Split+Join

Here the process consists of concurrent execution of a bunch of process components with barrier synchronization. That is, Split+Join completes when all of its components processes have completed. With Split and Split+Join, we can define processes that have partial synchronization (e.g., split all and join some sub-bag).

<owl:Class rdf:ID="Split-Join">
  <rdfs:subClassOf rdf:resource="#ControlConstruct"/>
  <rdfs:subClassOf>
    <owl:Restriction>
      <owl:onProperty rdf:resource="#components"/>
      <owl:allValuesFrom rdf:resource="#ControlConstructBag"/>
    </owl:Restriction>
  </rdfs:subClassOf>
</owl:Class>
Any-Order
Allows the process components (specified as a bag) to be executed in some unspecified order but not concurrently. Execution and completion of all components is required. The execution of processes in an Any-Order construct cannot overlap, i.e. atomic processes cannot be executed concurrently and composite processes cannot be interleaved. All components must be executed. As with Split+Join, completion of all components is required.
<owl:Class rdf:ID="Any-Order">
  <rdfs:subClassOf rdf:resource="#ControlConstruct"/>
  <rdfs:subClassOf>
    <owl:Restriction>
      <owl:onProperty rdf:resource="#components"/>
      <owl:allValuesFrom rdf:resource="#ControlConstructBag"/>
    </owl:Restriction>
  </rdfs:subClassOf>
</owl:Class>
Choice
Choice calls for the execution of a single control construct from a given bag of control constructs (given by the components property). Any of the given control constructs may be chosen for execution.
<owl:Class rdf:ID="Choice">
  <rdfs:subClassOf rdf:resource="#ControlConstruct"/>
  <rdfs:subClassOf>
    <owl:Restriction>
      <owl:onProperty rdf:resource="#components"/>
      <owl:allValuesFrom rdf:resource="#ControlConstructBag"/>
    </owl:Restriction>
  </rdfs:subClassOf>
</owl:Class>
If-Then-Else
The If-Then-Else class is a control construct that has properties ifCondition, then and else holding different aspects of the If-Then-Else. Its semantics is intended to be ``Test If-condition; if True do Then, if False do Else.''
<owl:Class rdf:ID="If-Then-Else">
  <rdfs:comment>
    If-Then-Else Class is a ControlConstruct that consists of a Condition, a
    then and an optional else process.
  </rdfs:comment>
  <rdfs:subClassOf rdf:resource="#ControlConstruct"/>
  <rdfs:subClassOf>
    <owl:Restriction>
      <owl:onProperty rdf:resource="#ifCondition"/>
      <owl:cardinality rdf:datatype="&xsd;#nonNegativeInteger">1</owl:cardinality>
    </owl:Restriction>
  </rdfs:subClassOf>
  <rdfs:subClassOf>
    <owl:Restriction>
      <owl:onProperty rdf:resource="#then"/>
      <owl:cardinality rdf:datatype="&xsd;#nonNegativeInteger">1</owl:cardinality>
    </owl:Restriction>
  </rdfs:subClassOf>
  <rdfs:subClassOf>
    <owl:Restriction>
      <owl:onProperty rdf:resource="#else"/>
      <owl:maxCardinality rdf:datatype="&xsd;#nonNegativeInteger">1</owl:maxCardinality>
    </owl:Restriction>
  </rdfs:subClassOf>
</owl:Class>

<owl:ObjectProperty rdf:ID="ifCondition">
 <rdfs:comment> The if condition of an if-then-else</rdfs:comment> 
  <rdfs:domain rdf:resource="#If-Then-Else"/>
  <rdfs:range rdf:resource="&expr;#Condition"/>
</owl:ObjectProperty>

<owl:ObjectProperty rdf:ID="then">
  <rdfs:domain rdf:resource="#If-Then-Else"/>
  <rdfs:range rdf:resource="#ControlConstruct"/>
</owl:ObjectProperty>

<owl:ObjectProperty rdf:ID="else">
  <rdfs:domain rdf:resource="#If-Then-Else"/>
  <rdfs:range rdf:resource="#ControlConstruct"/> 
</owl:ObjectProperty>
Iterate
The Iterate construct makes no assumption about how many iterations are made or when to initiate, terminate, or resume. The initiation, termination or maintenance condition could be specified with a whileCondition or an untilCondition as below.3

Iterate is an "abstract" class, in the sense that it's not detailed enough to be instantiated in a process model. It's defined to serve as the common superclass of Repeat-While, Repeat-Until, and potentially other specific iteration constructs that might be needed in the future.

<owl:Class rdf:ID="Iterate">
  <rdfs:subClassOf rdf:resource="#ControlConstruct"/>
  <rdfs:subClassOf>
    <owl:Restriction>
      <owl:onProperty rdf:resource="#components"/>
      <owl:allValuesFrom rdf:resource="#ControlConstructBag"/>
    </owl:Restriction>
  </rdfs:subClassOf>
</owl:Class>
Repeat-While and Repeat-Until
Both of these iterate until a condition becomes false or true, following the familiar programming language conventions. Repeat-While tests for the condition, exits if it is false and does the operation if the condition is true, then loops. Repeat-Until does the operation, tests for the condition, exits if it is true, and otherwise loops. Thus, Repeat-While while may never act, whereas Repeat-Until always acts at least once.
<owl:ObjectProperty rdf:ID="whileCondition">
  <rdfs:domain rdf:resource="#Repeat-While"/>
  <rdfs:range rdf:resource="&expr;#Condition"/>
</owl:ObjectProperty>

<owl:ObjectProperty rdf:ID="whileProcess">
  <rdfs:domain rdf:resource="#Repeat-While"/>
  <rdfs:range rdf:resource="#ControlConstruct"/>
</owl:ObjectProperty>

<owl:Class rdf:ID="Repeat-While">
 <rdfs:comment> The repeat while construct</rdfs:comment> 
 <rdfs:subClassOf rdf:resource="#Iterate"/>
</owl:Class>
<owl:ObjectProperty rdf:ID="untilCondition">
  <rdfs:domain rdf:resource="#Repeat-Until"/>
  <rdfs:range rdf:resource="&expr;#Condition"/>
</owl:ObjectProperty>

<owl:ObjectProperty rdf:ID="untilProcess">
  <rdfs:domain rdf:resource="#Repeat-Until"/>
  <rdfs:range rdf:resource="#ControlConstruct"/>
</owl:ObjectProperty>

<owl:Class rdf:ID="Repeat-Until">
  <rdfs:comment> The repeat until process</rdfs:comment> 
  <rdfs:subClassOf rdf:resource="#Iterate"/>
</owl:Class>

AsProcess

The final control construct, AsProcess, is slightly different from the others.

<owl:Class rdf:ID="AsProcess">
   <rdfs:comment>
      AsProcess turns an arbitrary control construct into a "local
      process" that is called at the point it is defined.
   </rdfs:comment>
   <rdfs:subClassOf rdf:resource="#ControlConstruct"/>
   <rdfs:subClassOf rdf:resource="#Process"/>
   <owl:disjointWith rdf:resource="#SimpleProcess"/>
   <rdfs:comment>
      AsProcess's may be Atomic or Composite, but not Simple;
      they are used purely as syntactic devices.
   </rdfs:comment>
   <rdfs:subClassOf>
      <owl:Restriction>
         <owl:onProperty rdf:resource="#components"/>
         <owl:cardinality rdf:datatype="&xsd;#nonNegativeInteger">
            0</owl:cardinality>
       </owl:Restriction>
   </rdfs:subClassOf>
</owl:Class>
An AsProcess object is both a control construct and a process. Considered as a ControlConstruct, AsProcess has no components. However, if it is a CompositeProcess it may have a body (the value of its composedOf property). It allows you to associate outputs, local variables, effects, and even preconditions with an arbitrary subtree of a composite-process definition.

For example, a brokering process might be defined in such a way that after confirming with both Contractor and Contractee, a brokered relationship exists between them:

<process:AsProcess>
   <process:Result>
         <process:hasEffect>
             <Expression expressionLanguage="&drs;#DRS">
                <drs:AtomicFormula>
                   <rdf:predicate rdf:resource="&aux;brokered"/>
                   <rdf:subject rdf:resource="&aux;Contractor"/>
                   <rdf:object rdf:resource="&aux;Contractee"/>
                </drs:AtomicFormula>
             </Expression>
         </process:hasEffect>
   </process:Result>
   <process:composedOf>
      <process:Split+Join rdf:parseType="Collection">
         <process:Perform>
            <process:process rdf:resource="&aux;#Confirm-Contractor"/>
            ...
         </process:Perform>
         <process:Perform>
            <process:process rdf:resource="&aux;#Confirm-Contractee"/>
            ...
         </process:Perform>
      </process:Split+Join>
   </process:composedOf>
</process:AsProcess>
The elided pieces of the Performs specify how how data from this process are to be passed as parameters to the performed process. These will be filled in in the next section.

One could replace any use of AsProcess by a Perform of a process created ad hocwith roughly the same properties, but creating the extra process would be a distracting chore. (And the ad hoc process would have to be loaded with extra arguments if it had to make use of any variables from the enclosing context; in an AsProc they can be referred to as any other variables in scope would be; see next section.)


5.5 Specifying Data Flow and Variable Bindings

When defining processes using OWL-S, there are many places where the input to one process component is obtained as one of the outputs of a preceding step. This is one type of data flow from one step of a process to another. There are also other patterns; in particular, the outputs of a composite process may be derived from outputs of some of its components, and specifying which component's output becomes output X of the composite is also a data-flow specification.

There are two complementary ways to specify how data flow from step to step: consumer-pull and producer-push. One uses the "pull" approach when specifying the source of a datum at the point where it is used: if step 1 feeds step 3, we specify this fact in the description of step 3 rather than the description of step 1. We implement this convention by providing a notation for arbitrary terms as the values of input or output parameters of a process step, plus a notation for subterms denoting the output or input parameters of prior process steps.

Consumer-Pull

Consider the following tableau:

I1 input of: { Composite Process CP }: with output O1

composed of Step 1: Perform S1 ⇒ Step 2: Perform S2
where S1 has inputs I11 and I12, and output O11 and S2 has input I21 and output O21

The right-arrow here indicates that step 2 is meant to follow step 1, but not necessarily immediately.

Suppose that we want a straightforward data flow: Input I1 of the overall process CP is used as input I11 of S1, after adding 1. Input I12 of S1 is a constant, the string "Academic". Output O11 of S1 is used as input I21 of S2. The maximum of 0 and output O21 of S2, times π, is used as output O1 of CP. Using a consumer-pull convention, we simply declare the parameters I1, O11, and O21, but for parameters I11, I21, and O1 we provide, in addition to a declaration, bindings that specify that

I11(Step1) comes from incr(I1(CP))
I12(Step1) = "Academic"
I21(Step2) comes from O11(Step1)
O1(CP) comes from π × max 0, O21(Step2))

OWL-S uses hasDataFrom properties and InputBinding objects to represent each of these flows. A Binding represents a flow of data to a variable; it has two properties: toVar, the name of the variable (e.g., I21), and valueSpecifier, a description of the value it is to receive. A Perform has one hasDataFrom property per input variable; its value is a Binding of that variable, in particular, an InputBinding.

In an effort to provide value specifications in as concise a manner as possible in a variety of situations, we provide four different kinds of valueSpecifier for Bindings: valueSource, valueType, valueData, and valueFunction.

We declare the toVar property in the usual way:

<owl:Class rdf:ID="Binding">
  <rdfs:subClassOf>
    <owl:Restriction>
      <owl:onProperty rdf:resource="#toVar"/>
      <owl:cardinality rdf:datatype="&xsd;nonNegativeInteger">
                     1</owl:cardinality>
    </owl:Restriction>
  </rdfs:subClassOf>
</owl:Class>

<owl:ObjectProperty rdf:ID="toVar">
  <rdfs:domain rdf:resource="#Binding"/>
  <rdfs:range rdf:resource="#Parameter"/>
</owl:ObjectProperty>

The simplest sort of dataflow spec is valueSource:

<owl:ObjectProperty rdf:ID="valueSource">
  <rdfs:label>valueSource</rdfs:label>
  <rdfs:domain rdf:resource="#Binding"/>
  <rdfs:range rdf:resource="#ValueOf"/> 
  <rdfs:subPropertyOf rdf:resource="#valueSpecifier"/>
</owl:ObjectProperty>

The range of valueSource is an object of class ValueOf, specified entirely by its properties theVar and fromProcess. If a binding with toVar = p has valueSource  = s with properties theVar= v and fromProcess = R , that means that parameter  p of this process = parameter  v of  R.

<owl:Class rdf:ID="ValueOf">
  <rdfs:label>ValueOf</rdfs:label>
  <rdfs:subClassOf>
    <owl:Restriction>
      <owl:onProperty rdf:resource="#theVar"/>
      <owl:cardinality rdf:datatype="&xsd;#nonNegativeInteger">
                1</owl:cardinality>
    </owl:Restriction>
  </rdfs:subClassOf>
  <rdfs:subClassOf>
    <owl:Restriction>
      <owl:onProperty rdf:resource="#fromProcess"/>
      <owl:maxCardinality rdf:datatype="&xsd;#nonNegativeInteger">
                  1</owl:maxCardinality>
    </owl:Restriction>
  </rdfs:subClassOf>
</owl:Class>

<owl:ObjectProperty rdf:ID="theVar">
  <rdfs:domain rdf:resource="#ValueOf"/>
  <rdfs:range rdf:resource="#Parameter"/> 
</owl:ObjectProperty>

<owl:ObjectProperty rdf:ID="fromProcess">
  <rdfs:domain rdf:resource="#ValueOf"/>
  <rdfs:range rdf:resource="#Perform"/>
</owl:ObjectProperty>

For example, our simple tableau has one place where a ValueSource expression can be used. Here is how that part of the tableau would be expressed:

<process:Sequence rdf:ID="CP">
   <process:components rdf:parseType="Collection">
      <process:Perform rdf:ID="Step1">
         <process:process rdf:resource="&aux;#S1"/>
         ...
      </process:Perform>
      <process:Perform rdf:ID="Step2">
         <process:process rdf:resource="&aux;#S2"/>
         <process:hasDataFrom>
            <process:InputBinding>
               <process:toVar rdf:resource="&aux;#I21"/>
               <process:valueSource>
                  <process:ValueOf>
                      <process:theParam rdf:resource="#O11"/>
                      <process:fromProcess rdf:resource="#Step1"/>
                  </process:ValueOf>
               </process:valueSource>
            </process:InputBinding>
         </process:hasDataFrom>
      </process:Perform>
   </process:components>
</process:Sequence>

Note the use of the hasDataFrom property to connect Performs to input bindings:

<owl:ObjectProperty rdf:ID="hasDataFrom">
  <rdfs:domain rdf:resource="#Perform"/>
  <rdfs:range rdf:resource="#InputBinding"/>
</owl:ObjectProperty>
In the fragment above, Step2 has one input parameter, and hence one hasDataFrom that specifies that I21 is to get its input from the given valueSource.

Not surprisingly, an InputBinding is just a Binding that binds an input parameter:

<owl:Class rdf:ID="InputBinding">
  <owl:intersectionOf rdf:parseType="Collection">
     <owl:Class rdf:about="#Binding"/>
     <owl:Restriction>
       <owl:onProperty rdf:resource="#toVar"/>
       <owl:allValuesFrom rdf:resource="#Input"/>
     </owl:Restriction>
  </owl:intersectionOf> 
  <rdfs:subClassOf rdf:resource="#Binding"/>
</owl:Class>

The complete tableau appears below, after discussion of the remaining valueSpecifiers. Two of them, valueFunction and valueData, use the XML Literal trick to encode arbitrary expressions.

<owl:DatatypeProperty rdf:ID="valueFunction">
  <rdfs:label>valueFunction</rdfs:label>
  <rdfs:subPropertyOf rdf:resource="#valueSpecifier"/>
  <rdfs:domain rdf:resource="#Binding"/>
  <rdfs:range rdf:resource="&rdf;#XMLLiteral"/> 
</owl:DatatypeProperty>

<owl:DatatypeProperty rdf:ID="valueData">
  <rdfs:label>valueData</rdfs:label>
  <rdfs:domain rdf:resource="#Binding"/>
</owl:DatatypeProperty>

The valueFunction of a Binding is an XML literal to be read as a functional term. Some of its subterms may be ValueOfs specifying outputs of previous terms. As with conditions and effects, the denotation of the valueFunction expression cannot be known until variable values are plugged in. The valueData of a Binding is an XML literal to be interpreted as constant data.

The valueType of a Binding is a URI referring to an OWL class definition C. An instance of valueType asserts that the value of the given parameter will belong to C. C must be a subclass of the parameter's overall type, declared using parameterType.

<owl:DatatypeProperty rdf:ID="valueType">
  <rdfs:label>valueType</rdfs:label>
  <rdfs:subPropertyOf rdf:resource="#valueSpecifier"/>
  <rdfs:domain rdf:resource="#Binding"/>
  <rdfs:range rdf:resource="&xsd;#anyURI"/> 
</owl:DatatypeProperty>

In the discussion of Results, we gave a credit-card example, where we specified the outputs using OutputBindings. We won't bother to give the formal specification of these; they are exactly analogous to InputBindings. We'll see another example of them below.

There are a bunch of subtle issues that arise from the fact that our ontological categories refer to variables and not to the objects the variables denote when processes are performed. A person writing down a process is far more likely to be interested in the latter. In XML Literals such as KIF expressions, when we write a variable name we have assumed that software tools processing those expressions will treat occurrences of variables as denoting their enactment-time values. (See, for example, our treatment of Results in a process checking credit cards.) In other contexts we adopt similar conventions. For example, in a ValueOf, the fromProcess is nominally a step. But inference and enactment tools should treat it as denoting the enactment corresponding to that step during the current process performance.

Occasionally, it is necessary to refer to the enactment of the process currently being defined. For example, In our informal tableau above, we used expressions such as incr(I1(CP)) to mean the the input I1 of the overall process CP. But we cannot literally refer to a Binding with valueSource that is a ValueOf with fromProcess = CP, because CP is not a Perform, but a process. We want to say: During any Perform  P of CP, the value of the input I1 of step S1 is the value of the input I1 of  P .

Hence we introduce a standard variable to play the role of  P , and give it the name ThisPerform.

<swrl:Variable rdf:ID="ThisPerform">
  <rdfs:comment>
    A special-purpose variable, used to refer, at runtime, to the execution
    instance of the enclosing process definition.
  </rdfs:comment>
</swrl:Variable>

We will show how this device is used in our example tableau shortly.

We close the discussion of "consumer-pull" with some examples. First, we fill in the missing lines in the AsProcess example from the previous section. Recall that we wanted to call the Confirm-Contractor process in one branch of a Split+Join, the Confirm-Contractee process in the other. Here's how the first of these would look:

         <process:Perform>
            <process:process rdf:resource="&aux;#Confirm-Contractor"/>
            <process:hasDataFrom>
               <process:InputBinding>
                  <process:toVar rdf:resource=&aux;#Contractor"/>
                  <process:valueData xsd:datatpe=&rdfs;#XML-Literal"
                      >aux:Contractor</process:valueData>
               </process:InputBinding>
            </process:hasDataFrom>
            <process:hasDataFrom>
               <process:InputBinding>
                  <process:toVar rdf:resource="&aux;#Partner"/>
                  <process:valueData xsd:datatype="&rdfs;#XML-Literal"
                      >aux:Contractee </process:valueData>
               </process:InputBinding>
            </process:hasDataFrom>
         </process:Perform>
Filling in the call to Confirm-Contractee is left as an exercise for the reader.

Finally, here is the OWL-S RDF representation of the example tableau with which we began this section, with all data flows expressed using one of the three data-source specs.

<process:CompositeProcess rdf:ID="CP">
   <process:hasInput rdf:ID="I1"/>
   <process:hasOutput rdf:ID="O1"/>
   <process:composedOf>
      <process:Sequence rdf:ID="CP">
         <process:components rdf:parseType="Collection">
            <process:Perform rdf:ID="Step1">
               <process:process rdf:resource="&aux;#S1"/>
               <process:hasDataFrom>
                  <process:InputBinding>
                     <process:toVar rdf:resource="&aux;#I11"/>
                     <process:valueFunction expressionLanguage="&drs;#DRS" 
                                      rdf:parseType="Literal">
                        <drs:Functional_term>
                           <drs:term_function rdf:resource="&arith;#incr"/>
                           <drs:term_args rdf:parseType="Collection">
                              <process:ValueOf>
                                  <process:theParam rdf:resource="#I1"/>
                                  <process:fromProcess
                                      rdf:resource="#ThisPerform"/>
                              </process:valueOf>
                           </drs:term_args>
                        </drs:Functional_term>
                     </process:valueFunction>
                  </process:InputBinding>
                  <process:InputBinding>
                     <process:toVar rdf:resource="&aux;#I12"/>
                     <process:valueData
                        xsd:datatype="&xsd;#string"
                        >Academic</process:valueData>
                  </process:InputBinding>
               </process:hasDataFrom>
            </process:Perform>
            <process:Perform rdf:ID="Step2">
               <process:process rdf:resource="&aux;#S2"/>
               <process:hasDataFrom>
                  <process:InputBinding>
                     <process:toVar rdf:resource="&aux;#I21"/>
                     <process:valueSource>
                        <process:ValueOf>
                            <process:theParam rdf:resource="#O11"/>
                            <process:fromProcess rdf:resource="#Step1"/>
                        </process:ValueOf>
                     </process:valueSource>
                  </process:InputBinding>
               </process:hasDataFrom>
            </process:Perform>
         </process:components>
      </process:Sequence>
  </process:composedOf>

  <process:hasResult>
     <process:Result>
        <process:withOutput>
            <process:OutputBinding>
                <process:toVar rdf:resource="#O1"/>
                <process:valueFunction expressionLanguage="&drs;#DRS"
                                 rdf:parseType="Literal">
                   <drs:Functional_term>
                       <drs:term_function rdf:resource="&arith;#times"/>
                       <drs:term_args rdf:parseType="Collection">
                          <xsd:Integer rdf:datatype="&xsd;#Float"
                             >3.14159</xsd:Float>
                          <drs:Functional_term>
                             <drs:term_function
                                rdf:resource="&arith;#max"/>
                             <drs:term_args rdf:parseType="Collection">
                                <xsd:Integer rdf:datatype="&xsd;#Integer"
                                             >0</xsd:Integer>
                                <process:ValueOf>
                                   <process:theParam
                                       rdf:resource="#O21"/>
                                   <process:fromProcess
                                       rdf:resource="#S2"/>
                                </process:valueOf>
                             </drs:term_args>
                          </drs:Functional_term>
                       </drs:term_args>
                   </drs:Functional_term>
                </process:valueFunction>
            </process:OutputBinding>
        </process:withOutput>
     </process:Result>
</process:CompositeProcess>

Producer-Push

In all the examples so far, we were able to use withOutput to "pull" the outputs out of terms available when a Result is declared. In some cases specifying things this way becomes awkward. If a process is defined using IfThenElses the outputs may depend on which branches of the conditionals the agent takes. So at the point in a branch where the data required to compute the output are known, we insert a Produce pseudo-step to say what the output will be. Produce is a ControlConstruct that "pushes" to an Output a value available at run time. This brings us to the "producer-push" paradigm for expressing dataflow.

<owl:Class rdf:ID="Produce">
  <rdfs:subClassOf rdf:resource="#ControlConstruct"/>
</owl:Class>

A Produce specifies a value and where it is going. We can spell out the possible destinations of such values after we explain the varieties of local variables.:

<owl:Class rdf:ID="Local">
  <rdfs:comment>
     A Local is a distinct type of variable used for intermediate results
     in a CompositeProcess.
  </rdfs:comment>
  <rdfs:subClassOf rdf:resource="#ProcessVar"/>
  <owl:disjointWith rdf:resource="#Participant"/>
  <owl:disjointWith rdf:resource="#Existential"/>
  <owl:disjointWith rdf:resource="#ResultVar"/>
  <owl:disjointWith rdf:resource="#Participant"/>
  <owl:unionOf rdf:parseType="Collection">
    <owl:Class rdf:about="#Loc"/>
    <owl:Class rdf:about="#Link"/>
  </owl:unionOf>
</owl:Class>

<owl:ObjectProperty rdf:ID="hasLocal">
  <rdfs:subPropertyOf rdf:resource="#hasVar"/>
  <rdfs:domain rdf:resource="#CompositeProcess"/>
  <rdfs:range rdf:resource="#Local"/>
</owl:ObjectProperty>

Locals are divided into further classes of variable: Locs and Links.

<owl:Class rdf:ID="Loc">
   <rdfs:comment>
      A Loc is a variable that may be written and overwritten as
      often as one pleases.
   </rdfs:comment>
   <rdfs:subClassOf rdf:resource="#Local"/>
</owl:Class>

<owl:Class rdf:ID="Link">
   <rdfs:comment>
      A Link is a communication channel that may be written exactly once.
   </rdfs:comment>
   <rdfs:subclassOf rdf:resource="#Local"/>
   <owl:disjointWith rdf:resrouce="#Loc"/>
</owl:Class>

We can finally specify the precise target of a Produce: the target is its producedBinding property, which specifies either a Link or an Output:

<owl:ObjectProperty rdf:ID="producedBinding">
   <rdfs:domain rdf:resource="#Produce"/>
   <rdfs:range>
      <owl:unionOf rdf:parseType="Collection">
         <owl:Class rdf:about="#OutputBinding"/>
         <owl:Class rdf:about="#LinkBinding"/>
      </owl:unionOf>
   </rdfs:range>
</owl:ObjectProperty>

<owl:Class rdf:ID="LinkBinding">
  <owl:intersectionOf rdf:parseType="Collection">
     <owl:Class rdf:about="#Binding"/>
     <owl:Restriction>
       <owl:onProperty rdf:resource="#toVar"/>
       <owl:allValuesFrom rdf:resource="#Link"/>
     </owl:Restriction>
  </owl:intersectionOf> 
  <rdfs:subClassOf rdf:resource="#Binding"/>
</owl:Class>

Analogous to Produce, we have Set, which sends a value to a Loc.

<owl:Class rdf:ID="Set">
   <rdfs:subclassOf rdf:resource="#ControlConstruct"/>
</owl:Class>

<owl:ObjectProperty rdf:ID="setBinding">
   <rdfs:domain rdf:resource="#Set"/>
   <rdfs:range rdf:resource="#LocBinding"/>
</owl:ObjectProperty>

<owl:Class rdf:ID="LocBinding">
  <owl:intersectionOf rdf:parseType="Collection">
     <owl:Class rdf:about="#Binding"/>
     <owl:Restriction>
       <owl:onProperty rdf:resource="#toVar"/>
       <owl:allValuesFrom rdf:resource="#Loc"/>
     </owl:Restriction>
  </owl:intersectionOf> 
  <rdfs:subClassOf rdf:resource="#Binding"/>
</owl:Class>

Here is how one might use these push devices to express flow out of an If-Then-Else:

<process:If-Then-Else>
   <process:ifCondition>
      ...
   </process:ifCondition>
   <process:then>
      <process:Produce>
          <process:producedBinding>
             <process:LinkBinding>
                <process:toVar rdf:resource="#SomeLink"/>
                <process:valueData xsd:datatype="&xsd;integer"
                            >5</process:valueData>
             </process:LinkBinding>  
          </process:producedBinding>
      </process:Produce>
   </process:then>
   <process:else>
      <process:Produce>
          <process:producedBinding>
             <process:LinkBinding>
                <process:toVar rdf:resource="#SomeLink"/>
                <process:valueData xsd:datatype="&xsd;integer"
                            >-5</process:valueData>
             </process:LinkBinding>  
          </process:producedBinding>
      </process:Produce>
   </process:else>
</process:If-Then-Else>
After this construct is executed, the value 5 or -5 is written to the link SomeLink. The link can be referred to in later steps, like any other variable, by simply writing its name.

In this example, we could just as easily have used a Loc. In more realistic examples, Links, because they are written exactly once, give analysis tools a better chance of inferring the values of expressions by tracing through the different possible paths through a process. Currently there is no way to use Links to express algorithms that involve iteration, passing values from one iteration to the next. That is on the agenda for future development. One must currently Locs for that purpose.

6. Grounding a Service to a Concrete Realization

The grounding of a service specifies the details of how to access the service - details having mainly to do with protocol and message formats, serialization, transport, and addressing. A grounding can be thought of as a mapping from an abstract to a concrete specification of those service description elements that are required for interacting with the service - in particular, for our purposes, the inputs and outputs of atomic processes. Note that in OWL-S, both the ServiceProfile and the ServiceModel are thought of as abstract representations; only the ServiceGrounding deals with the concrete level of specification.

OWL-S does not include an abstract construct for explicitly describing messages. Rather, the abstract content of a message is specified, implicitly, by the input or output properties of some atomic process. Thus, atomic processes, in addition to specifying the basic actions from which larger processes are composed, can also be thought of as the communication primitives of an (abstract) process specification.

Concrete messages, however, are specified explicitly in a grounding. The central function of an OWL-S grounding is to show how the (abstract) inputs and outputs of an atomic process are to be realized concretely as messages, which carry those inputs and outputs in some specific transmittable format. Due to the existence of a significant body of work in the area of concrete message specification, which is already well along in terms of industry adoption, we have chosen to make use of the Web Services Description Language (WSDL) in crafting an initial grounding mechanism for OWL-S. As mentioned above, our intent here is not to prescribe the only possible grounding approach to be used with all services, but rather to provide a general, canonical and broadly applicable approach that will be useful for the great majority of cases.

Web Services Description Language (WSDL) ``is an XML format for describing network services as a set of endpoints operating on messages containing either document-oriented or procedure-oriented information. The operations and messages are described abstractly, and then bound to a concrete network protocol and message format to define an endpoint. Related concrete endpoints are combined into abstract endpoints (services). WSDL is extensible to allow description of endpoints and their messages regardless of what message formats or network protocols are used to communicate" [ 2 ] .

It may readily be observed that OWL-S' concept of grounding is generally consistent with WSDL's concept of binding. Indeed, by using the extensibility elements already provided by WSDL, along with one new extensibility element proposed here, it is an easy matter to ground an OWL-S atomic process. Here, we show how this may be done, relying on the WSDL 1.1 specification. (After WSDL 2.0 has been finalized, we expect to update the OWL-S Grounding, and this document, appropriately.)

6.1 Relationships between OWL-S and WSDL

The approach described here allows a service developer, who is going to provide service descriptions for use by potential clients, to take advantage of the complementary strengths of these two specification languages. On the one hand (the abstract side of a service specification), the developer benefits by making use of OWL-S' process model, and the expressiveness of OWL's class typing mechanisms, relative to what XML Schema Definition (XSD) provides. On the other hand (the concrete side), the developer benefits from the opportunity to reuse the extensive work done in WSDL (and related languages such as SOAP), and software support for message exchanges based on these declarations, as defined to date for various protocols and transport mechanisms.

Figure 4: Mapping between OWL-S and WSDL
Grounding-Overview-1.2.jpg

We emphasize that an OWL-S/WSDL grounding involves a complementary use of the two languages, in a way that is in accord with the intentions of the authors of WSDL. Both languages are required for the full specification of a grounding, because the two languages do not cover the same conceptual space. As indicated by Figure 4, the two languages do overlap in providing for the specification of what WSDL calls ``abstract types'', which in turn are used to characterize the inputs and outputs of services. WSDL, by default, specifies abstract types using XML Schema, whereas OWL-S allows for the definition of abstract types as (description logic-based) OWL classes 4. However, WSDL/XSD is unable to express the semantics of an OWL class. Similarly, OWL-S has no means, as currently defined, to express the binding information that WSDL captures. Thus, it is natural that a OWL-S/WSDL grounding uses OWL classes as the abstract types of message parts declared in WSDL, and then relies on WSDL binding constructs to specify the formatting of the messages.

AN OWL-S/WSDL grounding is based upon the following three correspondences between OWL-S and WSDL. Figure 4 shows the first two of these.

  1. AN OWL-S atomic process corresponds to a WSDL (1.1) operation. Different types of operations are related to OWL-S processes as follows:

    Note that OWL-S grounding doesn't mandate a one-to-one correspondence between an atomic process and a single WSDL operation (although that is the most normal case). To accommodate the WSDL-supported practice of providing multiple definitions (within different port types) of the same operation, OWL-S allows for a one-to-many correspondence between an atomic process and multiple WSDL operations. It is also possible, in these situations, to maintain a one-to-one correspondence, by using multiple (differently named) atomic processes.

  2. The set of inputs and the set of outputs of an OWL-S atomic process each correspond to WSDL's concept of message. More precisely, OWL-S inputs correspond to the parts of an input message of a WSDL operation, and OWL-S outputs correspond to the parts of an output message of a WSDL operation.
  3. The types (OWL classes) of the inputs and outputs of an OWL-S atomic process correspond to WSDL's extensible notion of abstract type (and, as such, may be used in WSDL specifications of message parts).

To construct an OWL-S/WSDL grounding one must first identify, in WSDL, the messages and operations by which an atomic process may be accessed, and then specify correspondences (1) - (3).

Prior to OWL-S version 0.9, correspondences (2) and (3) were required to be direct correspondences. That is, each OWL-S input or output had to directly match up with a particular WSDL message part; and each input/output type had to literally serve as the type specified in WSDL. Starting with version 0.9, this limitation no longer exists. Version 0.9 allows for the specification of XSLT transformations to show how each WSDL input is derived from (one or more) OWL-S input properties, and how each OWL-S output is derived from (one or more) WSDL output message parts.

Although it is not logically necessary to do so, we believe it will be useful to specify these correspondences both in WSDL and in OWL-S. Thus, as indicated in the following, we allow for constructs in both languages for this purpose.

6.2 Grounding OWL-S Services with WSDL and SOAP

Because OWL-S is an XML-based language, and its atomic process declarations and input and output types already fit nicely with WSDL, it is easy to extend existing WSDL bindings for use with OWL-S, such as the SOAP binding. Here, we indicate briefly how an arbitrary atomic process, specified in OWL-S, can be given a grounding using WSDL and SOAP, with the assumption of HTTP as the chosen transport mechanism.

6.2.1 The WSDL Specification

Grounding OWL-S with WSDL and SOAP involves the construction of a WSDL (1.1) service description with all the usual parts (types, message, operation, port type, binding, and service constructs).

With respect to the types of the WSDL message parts, it is useful to distinguish two cases: those in which the type is an OWL type (that is, the WSDL service is a ``native speaker'' of that OWL type); and all others. In the first case, the OWL class can either be defined within the WSDL types section, or defined in a separate document and referred to from within the WSDL description, using owl-s-parameter, as explained below -- in which case its definition can be omitted from the WSDL types section.

OWL-S extensions are introduced as follows:

  1. In a part of the WSDL message definition, the owl-s-parameter attribute may be used to indicate the fully qualified name of the OWL-S input or output object (instance of class Parameter), to which this part of the message corresponds. This attribute is especially useful for those cases in which the type of the message part is an OWL type (and has not been defined in the WSDL types section). In these cases, the OWL type definition can be obtained from the OWL-S process specification, by inspecting the parameterType property of the referenced input or output object.
  2. For those cases in which a message part uses an OWL type, the encodingStyle attribute, within the WSDL binding element, can be given a value such as
    ``http://www.w3.org/2002/07/owl'' (or whatever is appropriate for a later version or descendant language of OWL), to indicate that the message parts will be serialized in the normal way for class instances of the given types, for the specified version of OWL.
  3. In each WSDL operation element, the owl-s-process attribute may be used to indicate the name of the OWL-S atomic process, to which the operation corresponds.

Note that WSDL already allows for the use of arbitrary new attributes in message part elements, and for the use of arbitrary values for the encodingStyle attribute. Thus, extension (3) above is the only point on which a modification to the current WSDL 1.1 specification is called for.

6.2.2 OWL-S' Grounding Class

Thus far, we have only shown how WSDL definitions may refer to the corresponding OWL-S declarations. It remains to establish a mechanism by which the relevant WSDL constructs may be referenced in OWL-S. The OWL-S WsdlGrounding class, a subclass of Grounding, serves this purpose. Each WsdlGrounding instance, in turn, contains a list of WsdlAtomicProcessGrounding instances.

A WsdlAtomicProcessGrounding instance refers to specific elements within the WSDL specification, using the following properties:

6.2.3 Using XSLT with a WSDL Grounding

In the case where an XSLT script is used to generate an input message for a WSDL operation, values are passed into the WSDL script by means of variable / parameter bindings. Specifically, variables that appear in an atomic process precondition get bound to values when that precondition is evaluated, and those values also get bound to params that appear in an XSLT script. The XSLT script then can produce a WSDL input message that includes those values.

The precondition should be arranged so that all values required by the XSLT script are assigned either to input parameters or to local variables of the atomic process.

XSLT params should be defined using the URIs of the required input parameters and local variables, as illustrated in the example below.

We note that the binding of the XSLT params will not come "for free"; that is, XSLT software will not know where to get those values from. That binding will need to be done by the OWL-S execution environment (e.g., by preprocessing the XSLT script before it is evaluated).

OWL-S allows that preconditions can be expressed in a variety of logic languages, including e.g. SWRL, DRS, RDQL, SPARQL, and KIF. Here's an example that employes SWRL. The thing to notice about this example is simply that evaluation of this precondition binds local variables #Firstname, #Lastname, and #Title to values contained in the input #Book. These same values are then plugged in to the XSLT script (as xsl:params) when it gets processed. The precondition is the following query expressed in SWRL:

  (?Book :hasAuthor ?Author)
  (?Author :hasFirstname ?Firstname)
  (?Author :hasLastname ?Lastname)
  (?Book :hasTitle ?Title)

Also note that the grounding is based on WSDL 1.1 (hence the reference to wsdlMessagePart), but this will be updated to WSDL 2.0 when that version has been finalized.

<!-- For simplicity we omit the definitions of Book, Firstname,
     Lastname, and Title

     "congo" is the namespace prefix for the example
       ("http://www.example.org/congo")
     "congo_wsdl" is the namespace prefix for the WSDL spec
     "p" is the namespace prefix for owl-s/1.2/Process.owl
     "e" is the namespace prefix for owl-s/1.2/generic/Expression.owl
     "e" is the namespace prefix for owl-s/1.2/Grounding.owl
-->

<p:AtomicProcess rdf:ID="BookInfo">
    <p:hasInput rdf:resource="#Book">
    <p:hasLocal rdf:resource="#Firstname">
    <p:hasLocal rdf:resource="#Lastname">
    <p:hasLocal rdf:resource="#Title">

    <p:hasPrecondition>
       <e:Expression>
           <e:expressionObject parsetype="Collection">
              <swrl:IndividualPropertyAtom>
                <swrl:propertyPredicate rdf:resource="publ:hasAuthor"/>
                <swrl:argument1 rdf:resource="#Book"/>
                <swrl:argument2 rdf:resource="#Author"/>
              </swrl:IndividualPropertyAtom>
              <swrl:IndividualPropertyAtom>
                <swrl:propertyPredicate
                  rdf:resource="publ:hasFirstname"/>
                <swrl:argument1 rdf:resource="#Author"/>
                <swrl:argument2 rdf:resource="#Firstname"/>
              </swrl:IndividualPropertyAtom>
              <swrl:IndividualPropertyAtom>
                <swrl:propertyPredicate
                  rdf:resource="publ:hasFirstname"/>
                <swrl:argument1 rdf:resource="#Author"/>
                <swrl:argument2 rdf:resource="#Lastname"/>
              </swrl:IndividualPropertyAtom>
              <swrl:IndividualPropertyAtom>
                <swrl:propertyPredicate rdf:resource="publ:hasTitle"/>
                <swrl:argument1 rdf:resource="#Book"/>
                <swrl:argument2 rdf:resource="#Title"/>
              </swrl:IndividualPropertyAtom>
           </e:expressionObject>
       </e:Expression>
    </e:hasPrecondition>
</e:AtomicProcess>

<g:WsdlAtomicProcessGrounding>
 <g:owlsProcess rdf:resource="#BookInfo>
  <g:wsdlInput>
   <g:XSLTInputMessageMap>
    <grounding:wsdlMessagePart rdf:datatype="&xsd;#anyURI">
       congo_wsdl:BookInfoMessagepart
    </grounding:wsdlMessagePart>
    <g:xsltTransformationString>
     <![CDATA[
      <xsl:stylesheet version="1.0"
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
       xmlns:congo="http://www.example.org/congo">

       <xsl:param name="congo:Firstname"/>
       <xsl:param name="congo:Lastname"/>
       <xsl:param name="congo:Title"/>

       <xsl:template match="/">
            <Book>
               <author>
                  <xsl:value-of select="$congo:Firstname"/>
                  <xsl:value-of select="$congo:Lastname"/>
               </author>
               <title>
                  <xsl:value-of select="$congo:Title"/>
               </title>
            </Book>
       </xsl:template>
     </xsl:stylesheet>
    ]]>
   </g:xsltTransformationString>
  </g:XSLTInputMessageMap>
 </g:wsdlInput>
</g:WsdlAtomicProcessGrounding>

Additional explanation and examples of how to specify groundings are given in an online document [14], as part of the OWL-S release site on www.daml.org.


7. Summary and Current Status

OWL-S is an ontology, within the OWL-based framework of the Semantic Web, for describing Web services. It will enable users and software agents to automatically discover, invoke, compose, and monitor Web resources offering services, under specified constraints.

We hope to enhance OWL-S in the future in selected ways that we have indicated in this technical overview and elsewhere, and in response to users' experience with it.

We believe OWL-S will help make the Semantic Web a place where people can not only find information but also get things done.


Appendix A. Note on Input/Output Type Compatiblity

In general, two processes are type compatible if for each output of one that flows to the input of the other, the parameterType of the output is a subtype of the parameterType of the input. It is quite common, and often encouraged, to use OWL classes as the type of parameters in OWL-S descriptions. That is, the URI which is a value of the parameterType property, denotes an OWL class, that is, a set of individuals which answer to a description encoded in OWL. An OWL reasoner can determine type compatibility in such cases by testing that the relevant output type is subsumed by the input type (of course, equivalent classes subsume each other). In the case where the types are XML Schema types (or elements), the subtype relation is determined by the XML Schema specification (and can be tested by an XML schema validator).

XML Schema types and OWL classes are type incompatible. If the service uses XML Schema (or similar) types in WSDL declarations, and a service modeler wishes to use OWL at the process or profile level, the modeler should provide for translations from the XML Schema to OWL.


Appendix B. Note on a Convention for Notating Lists in OWL-S

In OWL DL, the RDF List vocabulary (rdf:List, rdf:first, rdf:rest, rdf:nil) can only be used in conjunction with built-in predicates such as owl:unionOf, owl:intersectionOf, etc. Using RDF lists to denote a list of individuals is only permitted in OWL Full. More precisely, the list vocabulary (and constructs that generate it, such as rdf:parseType="Collection") can only be used as syntax in OWL DL, and not for domain modeling.

To make OWL-S ontologies accessible to existing OWL DL reasoners the OWL-S Coalition has decided to obey this restriction. Unfortunately, the control constructs in the Process ontology heavily used the collection vocabulary. In OWL-S 1.0 such constructs were modeled as RDF lists and the rdf:parseType="Collection" attribute was used to write the list, for example:

<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns:process-1.0="http://www.daml.org/services/owl-s/1.0/  Process.owl#">
<process-1.0:CompositeProcess rdf:ID="BravoAir_Process">
 <process-1.0:composedOf>
     <process-1.0:Sequence>
       <process-1.0:components rdf:parseType="Collection">
           <process-1.0:AtomicProcess   rdf:about="#GetDesiredFlightDetails"/>
           <process-1.0:AtomicProcess   rdf:about="#SelectAvailableFlight"/>
           <process-1.0:CompositeProcess rdf:about="#BookFlight"/>
       </process-1.0:components>
     </process-1.0:Sequence>
 </process-1.0:composedOf>
</process-1.0:CompositeProcess>
</rdf:RDF>

This is exactly equivalent to the following verbose representation:

<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns:process-1.0="http://www.daml.org/services/owl-s/1.0/  Process.owl#">
<process-1.0:CompositeProcess rdf:ID="BravoAir_Process">
 <process-1.0:composedOf>
     <process-1.0:Sequence>
       <process-1.0:components>
           <rdf:Description>
             <rdf:first>
                 <process-1.0:AtomicProcess   rdf:about="#GetDesiredFlightDetails"/>
             </rdf:first>
             <rdf:rest>
                 <rdf:Description>
                   <rdf:first>
                       <process-1.0:AtomicProcess   rdf:about="#SelectAvailableFlight"/>
                   </rdf:first>
                   <rdf:rest>
                       <rdf:Description>
                         <rdf:first>
                             <process-1.0:CompositeProcess   rdf:about="#BookFlight"/>
                         </rdf:first>
                         <rdf:rest rdf:resource="&rdf;#nil"/>
                       </rdf:Description>
                   </rdf:rest>
                 </rdf:Description>
             </rdf:rest>
           </rdf:Description>
       </process-1.0:components>
     </process-1.0:Sequence>
 </process-1.0:composedOf>
</process-1.0:CompositeProcess>
</rdf:RDF>

In OWL-S 1.1 and beyond, the solution to stay in OWL DL is achieved by using a "shadow" vocabulary to redefine List, first, rest and nil concepts in a different namespace. The shadow list ontology is located at http://www.daml.org/services/owl-s/1.2/generic/ObjectList.owl. The use of this vocabulary in OWL-S 1.2 is very similar to the above example:

<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns:shadow-rdf="http://www.daml.org/services/owl-s/1.2/generic/  ObjectList.owl"
  xmlns:process-1.2="http://www.daml.org/services/owl-s/1.2/  Process.owl#">
<process-1.2:CompositeProcess shadow-rdf:ID="BravoAir_Process">
 <process-1.2:composedOf>
     <process-1.2:Sequence>
       <process-1.2:components>
           <rdf:Description>
             <shadow-rdf:first>
                 <process-1.2:AtomicProcess
                        rdf:about="#GetDesiredFlightDetails"/>
             </shadow-rdf:first>
             <shadow-rdf:rest>
                 <rdf:Description>
                   <shadow-rdf:first>
                       <process-1.2:AtomicProcess
                            rdf:about="#SelectAvailableFlight"/>
                   </shadow-rdf:first>
                   <shadow-rdf:rest>
                       <rdf:Description>
                         <shadow-rdf:first>
                             <process-1.2:CompositeProcess
                                  rdf:about="#BookFlight"/>
                         </shadow-rdf:first>
                         <shadow-rdf:rest
                            rdf:resource="&shadow-rdf;#nil"/>
                       </rdf:Description>
                   </shadow-rdf:rest>
                 </rdf:Description>
             </shadow-rdf:rest>
           </rdf:Description>
       </process-1.2:components>
     </process-1.2:Sequence>
 </process-1.2:composedOf>
</process-1.2:CompositeProcess>
</rdf:RDF>

Note that, in this case we cannot use the short-hand notation of rdf:parseType="Collection" since we are using a completely different set of properties to denote lists. The current shadow list vocabulary is a rather shallow representation of lists, but hardly more so than the original RDF vocabulary. In OWL Full, there is no restriction on the use of RDF list vocabulary and it is also possible to define equivalence relations between the built-in RDF list vocabulary and shadow list vocabulary. The following set of assertions is one way to establish this equivalence:

<rdf:Description rdf:ID="&rdf;#List">
 <owl:equivalentClass rdf:resource="&shadow-rdf;#List"/>
</rdf:Description>
<rdf:Property rdf:about="&rdf;#first">
  <owl:equivalentProperty rdf:resource="&shadow-rdf;#first"/>
</rdf:Property>
<rdf:Property rdf:about="&rdf;#rest">
  <owl:equivalentProperty rdf:resource="&shadow-rdf;#rest"/>
</rdf:Property>
<rdf:Description rdf:ID="&rdf;#nil">
 <owl:sameAs rdf:resource="&shadow-rdf;#nil"/>
</rdf:Description>

A service provider can simply import an ontology that contains these assertions and continue to use the built-in RDF vocabulary (and short-hand rdf:parseType="Collection" notation). Such service descriptions are still consistent with OWL-S ontologies but certainly fall into OWL Full. It is more difficult to go the other way, since one must maintain the distinction between syntax uses of the RDF vocabulary and domain modeling uses. It almost certainly requires an a priori pass of an OWL parser such as the OWL API to remove all the syntax triples first; then the remaining triples may be replaced with the shadow vocabulary.


Acknowledgments

This document was produced as part of the DARPA DAML Program, which provided funding to many of the authors. We very much appreciate the ongoing support, interest, and patience of DAML program managers Jim Hendler, Murray Burke, and Mark Greaves.

We thank the W3C for permitting and supporting the use of the public-sws-ig mailing list for discussion of OWL-S issues, and Carine Bournez at W3C for helping to make this possible.

We would like to give a special thanks to the following individuals who have made significant contributions to this work:

In addition, we would like to express our gratitude to the many interested researchers and users who have employed OWL-S in their projects and publications, and to those who have taken the trouble to share their suggestions and questions in the discussions of OWL-S on the public-sws-ig list.

This document has benefited from input from members of the Semantic Web Services Initiative (SWSI).


References

[OWL Guide]
OWL Web Ontology Language Guide. Michael K. Smith, Chris Welty, and Deborah L. McGuinness. W3C Recommendation 10 February 2004. Latest version is available at http://www.w3.org/TR/owl-guide/.
[OWL Reference]
OWL Web Ontology Language Reference. Mike Dean, Guus Schreiber, Sean Bechhofer, Frank van Harmelen, James Hendler, Ian Horrocks, Deborah L. McGuinness, Peter F. Patel-Schneider, and Lynn Andrea Stein. W3C Recommendation 10 February 2004. Latest version is available at http://www.w3.org/TR/owl-ref/.
[OWL XML]
OWL Web Ontology Language XML Presentation Syntax. Masahiro Hori, Jérôme Euzenat, Peter F. Patel-Schneider. W3C Note 11 June 2003
[RDF Concepts]
Resource Description Framework (RDF) Concepts and Abstract Syntax. Graham Klyne, Jeremy J. Carroll, and Brian McBride, eds. W3C Recommendation 10 February 2004. Latest version is available at http://www.w3.org/TR/rdf-concepts/.
[RuleML]
Rule Markup Language Initiative.
[XML]
Extensible Markup Language (XML) 1.0 (Second Edition). Tim Bray, Jean Paoli, C. M. Sperberg-McQueen, and Eve Maler, eds. W3C Recommendation 6 October 2000. Latest version is available at http://www.w3.org/TR/REC-xml/.
1
T. Berners-Lee, J. Hendler, and O. Lassila.
The Semantic Web.
Scientific American, 284(5):34-43, 2001.
2
E. Christensen, F. Curbera, G. Meredith, and S. Weerawarana.
Web Services Description Language (WSDL) 1.1.
http://www.w3.org/TR/2001/NOTE-wsdl-20010315, 2001.
3
OWL-S Home Page.
http://www.daml.org/services/owl-s/, 2003.
4
K. Decker, K. Sycara, and M.  Williamson.
Middle-agents for the Internet.
In IJCAI97, 1997.
5
T. Finin, Y. Labrou, and J. Mayfield.
KQML as an Agent Communication Language.
In J. Bradshaw, editor, Software Agents. MIT Press, Cambridge, 1997.
6
M. Ghallab et al.
PDDL-The Planning Domain Definition Language V. 2.
Technical Report, report CVC TR-98-003/DCS TR-1165, Yale Center for Computational Vision and Control, 1998.
7
J. Hendler and D. L. McGuinness.
DARPA Agent Markup Language.
IEEE Intelligent Systems, 15(6):72-73, 2001.
8
I. Horrocks, P. F. Patel-Schneider, H. Boley, S. Tabet, B. Grosof, and M. Dean.
Swrl: A semantic web rule language combining owl and ruleml, 2003.
Available at http://www.daml.org/2003/11/swrl/.
9
D. Connolly, F. van Harmelen, I. Horrocks, D. L. McGuinness, P. F. Patel-Schneider, and L. Stein.
DAML+OIL (March 2001) Reference Description. W3C Note 18, December 2001.
http://www.w3.org/TR/daml+oil-reference
10
KIF.
Knowledge Interchange Format: Draft proposed American National Standard (dpans).
Technical Report 2/98-004, ANS, 1998.
Also at http://logic.stanford.edu/kif/dpans.html.
11
G. Klyne and J. J. Carroll.
Resource description framework (rdf): concepts and abstract syntax, 2004.
W3C Recommendation. Available at http://www.w3.org/TR/2004/REC-rdf-concepts-20040210.
12
O. Lassila.
Enabling semantic web programming by integrating Rdf and Common Lisp.
In Proc. First Semantic Web Working Symposium, 2001.
Stanford University.
13
H. Levesque, R. Reiter, Y. Lesperance, F. Lin, and R. Scherl.
GOLOG: A Logic programming language for dynamic domains.
Journal of Logic Programming, 31(1-3):59-84, April-June 1997.
14
D. Martin, M. Burstein, O. Lassila, M. Paolucci, T. Payne, and S. McIlraith.
Describing Web Services using OWL-S and WSDL.
http://www.daml.org/services/owl-s/1.2/owl-s-wsdl.html, November 2004.
15
D. Martin, A. Cheyer, and D. Moran.
The Open Agent Architecture: A Framework for Building Distributed Software Systems.
Applied Artificial Intelligence, 13(1-2):92-128, 1999.
16
D. L. McGuinness and F. van Harmelen.
OWL Web Ontology Language Overview.
http://www.w3.org/TR/owl-features/, February 2004.
World Wide Web Consortium (W3C) Recommendation.
17
S. McIlraith, T. C. Son, and H. Zeng.
Mobilizing the Web with DAML-Enabled Web Service.
In Proc. Second Int'l Workshop Semantic Web (SemWeb'2001), 2001.
18
S. McIlraith, T. C. Son, and H. Zeng.
Semantic Web Service.
IEEE Intelligent Systems, 16(2):46-53, 2001.
19
J. Meseguer.
Conditional Rewriting Logic as a Unified Model of Concurrency.
Theoretical Computer Science, 96(1):73-155, 1992.
20
R. Milner.
Communicating with Mobile Agents: The pi-Calculus.
Cambridge University Press, Cambridge, 1999.
21
S. Narayanan.
Reasoning About Actions in Narrative Understanding.
In Proc. International Joint Conference on Artificial Intelligence (IJCAI'1999), pages 350-357. Morgan Kaufmann Press, San Francisco, 1999.
22
C. Schlenoff, M. Gruninger, F. Tissot, J. Valois, J. Lubell, and J. Lee .
The Process Specification Language (PSL): Overview and Version 1.0 Specification.
NISTIR 6459, National Institute of Standards and Technology, Gaithersburg, MD, 2000.
23
K. Sycara and M. Klusch.
Brokering and Matchmaking for Coordination of Agent Societies: A Survey.
In A. Omicini et al, editor, Coordination of Internet Agents. Springer, 2001.
24
K. Sycara, M. Klusch, S. Widoff, and J. Lu.
Dynamic Service Matchmaking Among Agents in Open Information Environments.
ACM SIGMOD Record (Special Issue on Semantic Interoperability in Global Information Systems), 28(1):47-53, 1999.
25
H.-C. Wong and K. Sycara.
A Taxonomy of Middle-agents for the Internet.
In ICMAS'2000, 2000.
26
Francisco Curbera, Yaron Goland, Johannes Klein, Frank Leymann, Dieter Roller, Satish Thatte, and Sanjiva Weerawarana
Business Process Execution Language for Web Services, Version 1.0.
http://www-106.ibm.com/developerworks/library/ws-bpel/
IBM Technical Report

Footnotes

... OWL-S1
Originally called DAML-S.
... ``profile2
Service profile has also been called ``service capability advertisement'' [23].
... below.3
Another possible extension is the ability to define counters and use their values as termination conditions. This could be part of an extended process control and execution monitoring ontology.
... classes4
The data types of XML Schema can also be used in defining OWL properties.
... operation. 5
Since a composite process has no grounding, this construct would be grounded indirectly by means of its relationship to a simple process (by the collapsesTo property), and hence to an atomic process (by the realizedBy property).