10.2. Spécialisation des structures

Les structures sont des entités qui sont organisées en hiérarchie et plus particulièrement en hiérarchie simple. Cela signifie que toute structure peut admettre une, et une seule, structure comme super structure, voir la section Spécialisation d'entités.

L'API d'AROM permet d'accéder à cette hiérarchie soit en lecture, pour connaître les structures qui en spécialisent une autre, soit en écriture afin de modifier la hiérarchie courante.

Lors de la création d'une structure, voir la section précédente Création de structures., il est nécessaire de spécifier sa généralisation, ou super structure. Une valeur null signifiant que la structure en création est une structure racine. Mais il est également possible de modifier une hiérarchie existante en modifiant la généralisation d'une structure, comme illustré dans l'exemple qui suit.

Figure 10-1. Modification d'une hiérarchie de structures

L'objectif ici est d'insérer une structure dans une hiérarchie existante. Ce problème peut se décomposer en deux sous-problèmes. Tout d'abord, la structure Humain devient une spécialisation de la struture EtreVivant. Dans un second temps, il faudra changer la généralisation de la structure Homme de EtreVivant en Humain.

Exemple 10-2. Modification d'une hiérarchie de structures.


  /**
   * Creer un ensemble de classes AROM dans la base de connaissances 
   * passée en paramètre.
   *
   * @param kb La base de connaissances dans laquelle les classes
   * seront inserees.
   */
  public static void createClasses(KnowledgeBase kb){
	
    AMClass etreVivant = null;
    AMClass humain =  null;
    AMClass homme = null;
    AMClass vegetal = null;
    
    try {
      // cree les structures de departs (Humain et EtreVivant,  
      // specialise en Vegetal et Homme).
      etreVivant = kb.createClass("EtreVivant", null);
      humain = kb.createClass("Humain", null);
      homme = kb.createClass("Homme", etreVivant);
      vegetal = kb.createClass("Vegetal", etreVivant);
    } catch (EntityCreationException ece) {
      System.out.println("Une erreur est survenue lors de la creation des classes :");
      System.out.println(ece.getMessage());	    
      System.exit(1);
    }
  }

  /**
     * Modifie la hierarchie de structures d'une base. La modification
     * consiste a inserer la classe 'Humain' entre les classes  'EtreVivant'
     * et 'Homme'.
     *
     * @param kb la base de connaissances qui sera modifiee.  
     */
  public static void modifyHierarchy(KnowledgeBase kb) {  
    
	AMClass etreVivant = kb.lookupClass("EtreVivant");
	AMClass humain =  kb.lookupClass("Humain");
	AMClass homme = kb.lookupClass("Homme");
		
	// la classe 'EtreVivant' devient la super-classe de 
	// 'Humain'.
	AMClass[] superStructures = {etreVivant};
	try { 
	    humain.setGeneralization(superStructures); 
	} catch (UnsupportedOperationException uoe){
	    System.out.println("L'operation de modification de la super Structure est invalide: ");
	    System.out.println(uoe.getMessage());
	    System.exit(1);
	} catch (InvalidSpecializationException ise){
	  System.out.println("Le changement de super structure est invalide: ");
	  System.out.println(ise.getMessage());
	  System.exit(1);
	}

	// la classe 'Homme' devient sous classe de la classe 'Humain'.
	try{
	  humain.addSpecialization(homme);
	} catch (InvalidSpecializationException ise){
	  System.out.println("L'ajout d'une sous structure a echouer: ");
	  System.out.println(ise.getMessage());
	  System.exit(1);
	}
    }

  public static void main(String[] args){
    KnowledgeBase kb = newKb();
    createClasses(kb);
    modifyHierarchy(kb);
  }

    

Cet exemple montre qu'il est possible de modifier une hiérarchie en modifiant soit la partie supérieure, c'est à dire en changeant la super structure d'une structure, soit, au contraire, en modifiant la partie inférieure, c'est à dire l'ensemble des sous structures d'une structure donnée.

De la même façon, la lecture d'une hiérarchie à partir d'une structure donnée peut consister soit à lire la super structure soit à lire l'ensemble de ses sous structures, comme c'est le cas dans l'exemple qui suit. En effet, cet exemple permet de lire toute la hiérarchie de classes d'une base de connaissance AROM à partir des classes racines de cette base.

Exemple 10-3. Lecture d'une hiérarchie de classes.


    /**
     * Lit et affiche sur la sortie standard la hierarchie des classes de la
     * base de connaissances passee en parametres.
     *
     * @param kb La base de connaissance a afficher
     */   
    public static void printSpecialization(KnowledgeBase kb){

	// recupere un iterateur sur toutes les classes racines de 
	// la base.
	Iterator rootClasses = kb.rootClasses();
	while(rootClasses.hasNext()){
	    AMClass classe = (AMClass)rootClasses.next();
	    // affiche la hierarchie propre a une classe.
	    printClassLevel(classe, 1);	
	}
    }
    
    /**
     * Cette methode affiche sur la sortie standard la classe passee
     * en parametre puis affiche récursivement toute ses sous classes.
     *
     * @param classe la classe qui doit etre affichee
     * @param level le niveau de la classe dans la hierarchie globale de
     * la base de connaissances.
     */
    private static void printClassLevel(AMClass classe, int level){
	//Affiche la classe specifie, selon son niveau dans la hierarchie
	for(int i=0; i<level; i++)
	    System.out.print("  ");
	System.out.println("** Classe "+classe.getName());

	// Affiche les niveaux suivants
	int newLevel = ++level;
	Iterator specializedClasses = classe.specializations();
	while(specializedClasses.hasNext()){
	  AMClass nextSpecialization = (AMClass)specializedClasses.next();
	  printClassLevel(nextSpecialization, newLevel);
	}
    }
  
  public static void main(String[] args){
    KnowledgeBase kb = newKb();
    createClasses(kb);
    modifyHierarchy(kb);
    printSpecialization(newKb);
  }