Le point d'entrée du module de types est TypeSystem. Une instance de la classe d'implémentation de l'interface TypeSystem est obtenue par l'intermédiaire de la classe AromSetUp :
TypeSystem ts_ = AromSetUp.getAromSystem().getTypeSystem();
Depuis la classe TypeSystem ainsi obtenue, il est alors possible d'accéder aux différentes données et opérations proposées par le module de types.
Les interfaces des C-types proposées dans AROM sont représentées dans le diagramme qui suit. Ce sont des instances de ces C-types qui représentent effectivement un C-type donné.
L'une des possibilités offertes est d'accéder aux différents C-types définis par le module de types. Ce sont ces C-types qui servent à typer un slot d'une base de connaissances AROM, comme illustré dans l'exemple qui suit. En effet, lors de la création d'une variable il est nécessaire de spécifier des FacetModifiers décrivant cette nouvelle variable. Le seul modifieur qui soit obligatoire est le CTypeModifier permettant de savoir quel CType type la variable en question. La classe TypeSystem offre des méthodes permettant de récupérer les CTypes simples. Mais elle offre également la possibilité de créer de nouveaux C-types construits, des ListCT ou des SetCT, qui seront référencés dans le module de types par le nom spécifié en paramètre lors de cette création.
Pour rechercher un C-type à partir de son nom, il existe deux possibilités. Soit on réclame le type à l'objet TypeSystem, soit on le réclame à la KnowledgeBase. La différence entre ces deux accès apparaît uniquement lorsque le nom spécifiée est celui d'une Structure AROM. Dans le premier cas il est nécessaire d'utiliser le fully-qualified name de la structure pour retrouver le C-type la représentant. Par contre, si l'on s'adresse à la KnowledgeBase le nom simple suffit puisque le fully-qualified name est facilement accessible. De plus, lorsque l'on s'adresse à la KnowledgeBase et que l'on ne précise que le nom simple, si aucun C-type n'avait été préalablement enregistré, celui-ci sera créé et retourné à l'utilisateur.
Exemple 5-2. Typer une variable.
import arom.AromSetUp; import arom.kr.factory.AromSystem; import arom.kr.factory.ModifierFactory; import arom.kr.model.AMClass; import arom.kr.model.KnowledgeBase; import arom.kr.model.Variable; import arom.kr.model.InvalidNameException; import arom.kr.model.EntityCreationException; import arom.kr.model.Structure; import arom.kr.model.type.TypeSystem; import arom.kr.model.type.CType; import arom.kr.model.modifiers.CTypeModifier; import arom.kr.model.modifiers.DomainModifier; import arom.kr.model.modifiers.FacetModifier; import java.util.Vector; import java.util.Iterator; /** * Cet exemple montre comment acceder aux differents C-Types definis * dans le module de types et comment les utiliser afin de typer une variable. * * @author Veronique DUPIERRIS */ public class CreateTypedVars { /** * Cette methode cree une nouvelle base de connaissances nommee "BaseTest" et * cree une classe dans cette base : la classe racine 'Personne'. * * @return l'object KnowledgeBase representant la nouvelle base de * connaissances. */ public static KnowledgeBase createKb(){ String kbName = "BaseTest"; AromSystem aromFactory = AromSetUp.getAromSystem(); KnowledgeBase kb = null; try{ kb = aromFactory.createKB(kbName, new Object[0]); AMClass personne = kb.createClass("Personne", null); } catch(EntityCreationException ece){ System.out.println("Une erreur est survenue lors de la creation de la base : "); System.out.println(ece.getMessage()); // Arrete le system AROM proprement AromSetUp.getAromSystem().cleanup(); System.exit(1); } return kb; } /** * Cette methode recupere une instance de la classe d'implementation de * TypeSystem, qui est le point d'entre du module de types. Les instances * des C-Types sont ensuite obtenues et sont utilisees pour typer de nouvelles * variables de la structure specifiee. * * @param structure La Structure AROM a laquelle sera ajoutees quatre variables * de type String, Integer, Float et Boolean. */ public static void createAllTypedVariables(Structure structure){ //Recupere le module de type. TypeSystem typeSystem = AromSetUp.getAromSystem().getTypeSystem(); // Recupere l'objet permettant de creer les modifieurs de facettes ModifierFactory modifierFactory = AromSetUp.getAromSystem().getModifierFactory(); //Recupere les differents CTypes definis et les utilise pour typer une variable : try { // Chaine de caracteres CType stringCType = typeSystem.getStringCType(); // Creer le CTypeModifier permettant de typer une variable CTypeModifier ctypeModifier = modifierFactory.createCTypeModifier(stringCType); // Creer une nouvelle variable (nom) a la structure de type String FacetModifier[] facettes = new FacetModifier[1]; // un seul modifiers: CType facettes[0] = ctypeModifier; structure.createVariable("nom", facettes); // Entier CType integerCType = typeSystem.getIntegerCType(); // Creer le CTypeModifier permettant de typer une variable ctypeModifier = modifierFactory.createCTypeModifier(integerCType); // Creer une nouvelle variable (age) a structure de type Integer facettes[0] = ctypeModifier; // sauvegarde le nouveau CType structure.createVariable("age", facettes); // Reel CType floatCType = typeSystem.getFloatCType(); // Creer le CTypeModifier permettant de typer une variable ctypeModifier = modifierFactory.createCTypeModifier(floatCType); // Creer une nouvelle variable (salaire) a structure de type Float facettes[0] = ctypeModifier; // sauvegarde le nouveau CType structure.createVariable("salaire", facettes); // Booleen CType booleanCT = typeSystem.getBooleanCType(); // Creer le CTypeModifier permettant de typer une variable ctypeModifier = modifierFactory.createCTypeModifier(booleanCT); // Creer une nouvelle variable (marie(e)) a structure de type Boolean facettes[0] = ctypeModifier; // sauvegarde le nouveau CType structure.createVariable("mariee", facettes); } catch(InvalidNameException ine) { System.out.println("Une erreur est survenue lors de la creation d'une variable: "); System.out.println(ine.getMessage()); // Arrete le system AROM proprement AromSetUp.getAromSystem().cleanup(); System.exit(1); } } public static void main(String[] args){ KnowledgeBase kb = createKb(); AMClass personne = kb.lookupClass("Personne"); createAllTypedVariables(personne); System.out.println("Nouvelle classes : "+ personne.getFQName()); System.out.println("Slots : "); Iterator personneVariables = personne.variables(); while(personneVariables.hasNext()){ Variable nextVariable = (Variable) personneVariables.next(); CType variableType = nextVariable.getDescriptionFor(personne).getType().getCType(); System.out.println(nextVariable.getFQName()+" ("+variableType+")"); } // Arrete le system AROM proprement AromSetUp.getAromSystem().cleanup(); } }// CreateTypedVars
A une variable est associé un ensemble de descriptions, voir la section Slots, qui contiennent la définition des facettes (documentation, inférence, δ-type) pour chacune des structures dans laquelle elle apparaît. Le δ-type d'une variable pour une structure donnée est donc défini dans cette description.
Si l'on considère l'exemple de la section Spécialisation d'une facette de type, redonné ci-après, le slot age est défini par la classe Personne. Un descripteur du slot age pour la classe Personne, descageP, est donc créé et, plus précisemment, un δ-type, δtxA, est défini. Ce δ-type a été créé en appliquant successivement le modificateur de CType Ctype = integer et le modificateur de domain interval=[0..130] au descripteur descageP. La classe Enfant est une sous classe de Personne, par conséquent elle hérite du slot age. Un descripteur de ce slot pour la classe Enfant est donc également créé, descageE et il hérite du δ-type δtageP. Un modificateur de domaine interval=[0..18] est ensuite appliqué à descageE définissant un nouveau δ-type, δtageE, dont le domaine est l'intervalle [0..18]
Toujours en considérant cet exemple, l'application du modificateur de domaine interval=[20..130] à descageP génère une erreur puisque l'ensemble qui serait dénoté par δtageP serait disjoint de celui dénoté par δtageE. Dit autrement les contraintes exprimées par δtageP (age >= 20 et age <=130) sont incompatibles avec les contraintes exprimées par δtageP (age >= 0 et age <=18). Une solution, pour l'utilisateur, consisterait à annuler le modificateur de domaine appliqué à descxB, δtageE serait de nouveau identique à δtageP, puis à modifier δtageP en appliquant le modificateur de domaine désiré à descageP.
Le code correspondant à cet exemple est donné ci-après.
Exemple 5-3. Modifier le domaine d'une variable.
/** * Cet exemple montre comment modifier le domaine, et donc le delta-type, associe a * une variable. Pour cela des modificateurs de domaine sont appliques et d'autre sont * annules. * * @author Veronique DUPIERRIS */ import arom.kr.model.KnowledgeBase; import arom.kr.factory.AromSystem; import arom.AromSetUp; import arom.kr.model.AMClass; import arom.kr.model.type.CType; import arom.kr.model.modifiers.CTypeModifier; import arom.kr.factory.ModifierFactory; import arom.kr.model.modifiers.FacetModifier; import arom.kr.model.EntityCreationException; import arom.kr.model.InvalidNameException; import arom.kr.model.modifiers.InvalidModifierException; import arom.kr.model.VariableDescriptor; import arom.kr.model.modifiers.DomainModifier; public class ChangeVarsDomain { /** * Cette methode cree une nouvelle base de connaissances nommee "BaseTest" et * cree les classes dans cette base : la classe racine 'Personne' et la classe * 'enfant' la specialisant. Une variable age ayant pout CType integer est * egalement creee pour la classe Personne. * * @return l'object KnowledgeBase representant la nouvelle base de * connaissances. */ public static KnowledgeBase createKb(){ String kbName = "BaseTest"; AromSystem aromFactory = AromSetUp.getAromSystem(); KnowledgeBase kb = null; try{ kb = aromFactory.createKB(kbName, new Object[0]); AMClass personne = kb.createClass("Personne", null); CType integerCType = aromFactory.getTypeSystem().getIntegerCType(); // Creer le CTypeModifier permettant de typer une variable ModifierFactory modifierFact = AromSetUp.getAromSystem().getModifierFactory(); CTypeModifier ctype = modifierFact.createCTypeModifier(integerCType); // Creer une nouvelle variable (age) de type Integer FacetModifier[] facettes = new FacetModifier[1]; facettes[0] = ctype; // sauvegarde le nouveau CType personne.createVariable("age", facettes); AMClass enfant = kb.createClass("Enfant", personne); } catch(EntityCreationException ece){ System.out.println("Une erreur est survenue lors de la creation de la base : "); System.out.println(ece.getMessage()); System.exit(1); } catch(InvalidNameException ine) { System.out.println("Une erreur est survenue lors de la creation de la base : "); System.out.println(ine.getMessage()); System.exit(1); } return kb; } /** * Cette methode applique un nouveau domaine au descripteur de variable specifie, * variable qui doit etre de type integer. * * @param descrVar Le descripteur de variable de type integer auquel il faut * ajouter un domaine dont les bornes sont specifiees. * @param min la borne min de l'intervalle * @param max la borne max de l'intervalle */ public static void applyDomain(VariableDescriptor descrVar, Long min, Long max) throws InvalidModifierException { // Crée le modificateur de domaine ModifierFactory modifierFact = AromSetUp.getAromSystem().getModifierFactory(); Object[] values= {min,max}; DomainModifier intervalModifier = modifierFact.createDomainModifier( ModifierFactory.INTERVAL_MODIFIER, values); // Applique le modificateur de domaine au descripteur descrVar.applyTypeModifier(intervalModifier); } /** * Cette methode annule le modificateur de domaine au descripteur de variable * specifie, variable qui doit etre de type integer. Le modificateur de domaine * doit avoir ete prealablement applique * * @param descrVar Le descripteur de variable de type integer auquel il faut * ajouter un domaine dont les bornes sont specifiees. * @param min la borne min de l'intervalle * @param max la borne max de l'intervalle */ public static void cancelDomain(VariableDescriptor descrVar, Long min, Long max) throws InvalidModifierException { // Crée le modificateur de domaine ModifierFactory modifierFact = AromSetUp.getAromSystem().getModifierFactory(); Object[] values= {min,max}; DomainModifier intervalModifier = modifierFact.createDomainModifier( ModifierFactory.INTERVAL_MODIFIER, values); // Applique le modificateur au descripteur descrVar.cancelTypeModifier(intervalModifier); } public static void main(String[] args){ KnowledgeBase kb = createKb(); //Recupere les entites AROM AMClass personne = kb.lookupClass("Personne"); AMClass enfant = kb.lookupClass("Enfant"); VariableDescriptor agePersonne = personne.lookupVariable("age").getVariableDescriptionFor(personne); VariableDescriptor ageEnfant = personne.lookupVariable("age").getVariableDescriptionFor(enfant); //Application de modificateurs de domaine à age pour Personne et Enfant try { applyDomain(agePersonne, new Long(0), new Long(130) ); applyDomain(ageEnfant, new Long(0), new Long(18) ); System.out.println(" *** Suite a l'application des domaines, le descripteur de age associe a la classe personne a pour delta-type : "+agePersonne.getType() ); System.out.println(" *** Suite a l'application des domaines, le descripteur de age associe a la classe enfant a pour delta-type : "+ageEnfant.getType() ); System.out.println(""); } catch(InvalidModifierException ime) { System.out.println("Une erreur est survenue lors de l'application du modificateur de domaine : "); System.out.println(ime.getMessage()); System.exit(1); } try { applyDomain(agePersonne, new Long(20), new Long(130) ); } catch(InvalidModifierException ime) { System.out.println(" *** Impossible d'appliquer le domain [20..130] au descripteur de age pour la classe Personne."); System.out.println(""); } try { cancelDomain(ageEnfant, new Long(0), new Long(18) ); applyDomain(agePersonne, new Long(20), new Long(130) ); System.out.println("Suite a la modification des domaines, le descripteur de age associe a la classe personne a pour delta-type : "+agePersonne.getType() ); System.out.println("Suite a la modification des domaines, le descripteur de age associe a la classe enfant a pour delta-type : "+ageEnfant.getType() ); } catch(InvalidModifierException ime) { ime.printStackTrace(); System.out.println("Une erreur est survenue lors de l'application du modificateur de domaine : "); System.out.println(ime.getMessage()); System.exit(1); } AromSetUp.getAromSystem().cleanup(); } }// ChangeVarsDomain