Ontology contents can be modified in two ways; by adding and removing axioms. These activities are closely related to Requests (please remember that requests retrieve asserted facts, i.e. explicitly stated knowledge base elements). Removing axioms, for example, would typically be preceded by placing a request. There is an alternative approach to modifying ontology contents using so-called bulk operations as demonstrated below.
Simple Add or Remove
Individual or multiple axioms can be added or removed by calling the appropriate method of the Ontology class. In the code snippet below, an axiom is created using the KAON2Factory and subsequently added to an ontology:
Axiom axComp = factory.fclassMember(
NOTE: the use of the namespaces object that frees us from having to write out the fully qualified object names.
An equivalent axiom can be created directly from ObjectLogic code as the next code snippet illustrates:
Axiom axText = factory.axiom("Heidelberg:City.", namespaces, geographyOnto.getModule());
Adding or Removing Multiple Axioms
Multiple axioms can be added or removed equally easily:
String axiomText = "Offenburg:City[hasName->\"Offenburg\" hasPopulation->59171, partOfFederalState->BW].";
List<Axiom> axioms = factory.axioms(axiomText, namespaces, geographyOnto.getModule());
As mentioned in the introduction, it is also possible to add or remove multiple axioms at once without having to specify each one of them individually. The described functionality is available in the form of the two methods bulkAddFacts and bulkRemoveFacts of an Ontology object. They both work in a similar fashion; one parameter specifies a pattern against which existing axioms are to be matched. The matching works very much like evaluating a request, i.e. no reasoning is performed and available axioms are simply compared with the provided prescription; this prescription (or pattern) also introduces variables that are used in the second parameter to describe the changes to be carried out in a generic way.
The meaning of the second parameter is different for the two bulk operations. The second parameter of the bulkAdd operation specifies facts that should be asserted true after the execution of the operation. That is, if the facts from the second parameter do not already exist for a matching variable assignment, they will be added to the knowledge base. On the other hand, the bulkRemove operation asserts the facts from the second parameter false, i.e. if for a variable assignment (from the first parameter) facts of the form specified by the second parameter exist, they will be removed from the knowledge base.
To demonstrate this functionality assume that there is an ontology containing German cities along with the federal state they belong to. Cities are expressed as instances of a concept called City and related to the respective states by a property called partOfFederalState. For the sake of the example, assume that we introduce a new concept called BavarianCity as a subconcept of City and intend to make all of the existing cities located in Bavaria instances of this new concept, rather than of the generic city.
The condition or pattern for matching cities in Bavaria is composed of two axioms. The first axiom, formulaPartOfBayern, states that a variable C is assigned to an instance called Bayern by the means of a property called partOfFederalState:
Term var = factory.variable("C");
Term partOf = factory.constantIRI(ns, "partOfFederalState");
Term bayern = factory.constantIRI(ns, "Bayern");
FactFormula formulaPartOfBayern = factory.fpropertyMember(var, partOf, bayern);
The second axiom, formulaIsCity, states that the same variable is an instance of a concept called City;
Term city = factory.constantIRI(ns, "City");
FactFormula formulaIsCity = factory.fclassMember(var, city);
These two axiom form the complete condition, or pattern for matching existing facts:
List<FactFormula> queryList = new ArrayList<FactFormula>();
Now, we need to express the changes that need to be made. Let us first of all focus on assigning the matching instances to the new concept BavarianCity. Upon execution, the matching instances should be assigned to the new concept. This is done by using the same variable to describe the state after execution.
Term bavCity = factory.constantIRI(ns, "BavarianCity");
FactFormula formulaIsBavCity = factory.fclassMember(var, bavCity);
List<FactFormula> addList = new ArrayList<FactFormula>();
Having prepared both arguments, we can now perform the bulkAdd operation:
At this point the Bavarian cities are explicitly assigned to both concepts, City and BavarianCity. To remove this possible source of inconsistencies, we will use the bulkRemove operation to remove the Bavarian cities from the regular City concept. This is easily done as we already have a pattern to match against that we can reuse:
List<FactFormula> removeList = new ArrayList<FactFormula>();
The bulk operations offer a high-performance alternative, especially in the case of changes involving large numbers of axioms.