Manchester OWL Arithmetics Syntax:

Formulas in Manchester OWL Arithmetics are incorporated in OWL ontologies through annotations to the data type properties whose value they compute. Therefore, are obviously applicable only to data type properties. Every annotation containing a formula MUST have a valid URI whose namespace MUST be http://www.cs.manchester.ac.uk/owlcalculations/formula#

A formula is the value of such annotation and should abide by the following grammar rules:

Formula ::= ( ConflictStrategy )? ( AppliesTo )? ( StoreTo )? ( "{" Binding ( "," Binding )* "}->" )* ( Expression | Function ) ";"
ConflictStrategy ::= "$" <IDENTIFIER> "$"
StoreTo ::= "STORETO <" PropertyChain ">"
AppliesTo ::= "APPLIESTO <" manSyntaxClassExpression ">"
manSyntaxClassExpression ::= java code
Binding ::= <IDENTIFIER> "=" PropertyChain
PropertyChain ::= PropertyRendering ( "[" PropertyFacet "]" )? ( "o" ( PropertyChain ) )*
PropertyFacet ::= manSyntaxClassExpression
PropertyRendering ::= Corresponds to the current rendering of a property URI (depends on the one the system is crrently using, usually it is the property short name)
Expression ::= AdditiveExpression
AdditiveExpression ::= ( MultiplicativeExpression ( <SUM> AdditiveExpression )* )
MultiplicativeExpression ::= ( UnaryExpression ( <MULTIPLY> MultiplicativeExpression )* )
UnaryExpression ::= Power
| "(" Expression ")"
| groundTerm
Power ::= ( ( ( Integer ) | <IDENTIFIER> ) "^" Integer )
Integer ::= ( <NUMBER> | <INTEGER_LITERAL> )
Identifier ::= <IDENTIFIER>
groundTerm ::= ( Integer | Identifier )
Function ::= BigSum
BigSum ::= ( "SUM(" | "sum(" ) Expression ")"

As formally specified above, a formula is compound of three main parts:

Conflict Strategy:

This optional part instructs the evaluator on how to behave in case of conflict when assigning the value(s) resulting form the computation of the formula that is currently being specified. A conflict can occur when the evaluator computes a value of a functional data property containing a formula annotation for an individual that has already a value for the same property. We know that the semantics of the functional properties does not allow for more than one value to be assigned to such properties. We foresee the possibility of specifying three different strategies:

Application scope

This optional part restricts the set of individuals to which this formula may be applied. In OWL-DL, as opposite to the classical Object-Oriented frameworks, properties are not defined at class level, but they are first-class citizens. This means, for instance, that an hypothetical data property hasPerimeter in an ontology about geometric shapes should be defined globally. How to capture then the different ways to compute such value that depend on the particular polygon we are examining? Technically, a property can have as many annotations as we like in OWL therefore it seems straightforward to define as many perimeter computing formulas as many different ways we know. The application scope portion of each formula will tell the evaluator which variant to consider. The application scope contains a class expression so the evaluator, when computing the value for a given individual, will discard every variant in whose application scope the individual is not contained. To remain in our geometry example, suppose whe have three perimeter formula variants, one for triangles, one for squares, one for circles. Suppose that for each kind of polygon we have a separate class. Our formulas will look like the following ones:

Depending on the individual class one of them will be selected by the evaluator. Please notice that the third formula could have a wider application scope. In fact, it is the general formula for computing the perimeter of a generic polygon. If we widened the application scope to a superclass of Square, Circle, and Triangle (say Polygon) for every individual that is a polygon we could have the generic formula and possibly a more specific way of computing its perimeter. In such cases the evaluator picks the one with the narrower application scope. In other words we can say that class subsumption imposes a partial order on the formulas based on their application scopes. In the case in which there are two different formulas with an incomparable or equivalent application scope (w.r.t. subsumption) an exception is raised by the evaluator (i.e.: uk.ac.manchester.mae.MoreThanOneFormulaPerIndividualException)

Storage Instructions:

This block is optional and should be used for customising the storage of the computed values. If this block is omitted, the values will be stored as direct fillers of for the property whose annotation the formula is, for the individual for which the formula has been evaluated. Consider, for instance, a generic data property p which has been annotated with a formula. Now suppose that the formula application scope includes an individua i and the result of the computation si the value v. If no storage strategy is specified, the evaluator will add the data property axiom p(i,v) to the ontology. However, in order to support more complex patterns, we provide the flexibility of indicating a different storage strategy. By setting the storage instruction block the user can force the evaluator to follow a property chain before adding the actual axiom. Let us illustrate how it works through an example. Let us suppose to have an ontology with a single object property hasFeature whose range is a generic Feature class, which is then specialised into a value partition defining the various kinds of features. Now suppose that there are some sub-classes of features that might have a filler for a generic data type property hasValue. This is because we might want that, in our ontology, data property values for individuals are expressed as values for particular features, which is a quite widespread modelling practice. Therefore, our individuals will have a varying collections of features whose values might be the results of a computation. If we omitted the storage instructions in this case, the evaluator would then (wrongly from the modelling point of view) add fillers for the property hasValue directly to the individuals within our formulas application scope. What we need, on the contrary, is that our evaluator defines an appropriate feature instance as a filler of the hasFeature object property for the individual in the application scope and then, asserts the computed value as a filler for the feature instance just created for the hasValue property. The result of the evaluation will be, therefore, the addition of the following assertions to the ontology hasFeature(i,newFeatureInstance), SF(newFeatureInstance), and hasValue(newFeatureInstance,v); where SF is the appropriate sub-class of Feature and newFeatureInstance is the new feature whose value has been computed. Storage directives consist of a chain of properties (PropertyChain) whose elements in the case of storage MUST be all object properties. Please notice that the evaluator will chain the final element (the data type property) as it is the property containing the annotation for the formula and then MUST be omitted. Furthermore, for each element of the chain a filter for considering only a particular class of fillers can be specified (PropertyFacet). In case of more than one filler for a specific class filter the choice of the path is non deterministic.

Arithmetic Formula:

This block is further divided into bindings and the actual formula. Bindings instruct the evaluator on the values to be assigned to variables in the formula. Each binding follows a property chain and assigns its variable every possible value at the end of its property chain. Every property chain MUST end with a data property and every non ending element of the property chain MUST be an object property. Likewise storage instructions property chains, each element of the chain but the last can be filtered using a PropertyFacet. For example suppose to have the following formula:

$OVERRIDING$ APPLIESTO <Polygon>{sideLength=hasSide o hasLength}-> SUM(sideLength);

The evaluator, for each individual in the class Polygon will follow the hasSide object property and assign for each filler the value of its hasLength data property to the variable sideLength.

Let us now consider another example:

$OVERRIDING$ APPLIESTO <Polygon>{sideLength=hasFeature[SideLengthFeature] o hasLength}-> SUM(sideLength);

At the moment formulas can deal ONLY with values that can be cast as double primitive types in Java.