Skip to content

Dispara las reglas SWRL de tu Ontología con Jess y la API de Protégé

11 febrero 2012

En esta entrada vamos a ver cómo podemos inferir nuevo conocimiento desconocido hasta ahora partiendo de una ontología OWL que contiene una taxonomía completa de elementos y una serie de reglas en lenguaje SWRL. El objetivo de esta entrada es mostrar un ejemplo práctico (poca teoría) para que sepamos cómo hacer uso de un motor de inferencia y cómo utilizarlo desde nuestra aplicación en Java.

Para ello, vamos a hacer uso del motor de inferencia Jess y la API de Protege para gestionar ontologías. Para este ejemplo voy a utilizar la versión 7.1p2 de Jess y la versión 3.4.8 de la API de Protege. Además, partiremos de la base de que tenemos la ontología ya creada y con las reglas ya definidas (Esta operación la podemos hacer previamente con la herramienta gráfica de Protege, por ejemplo).

Empecemos… Veréis que el código es realmente sencillo, aunque podremos complicarlo todo lo que nos interese

En primer lugar debemos tener bien instaladas y configuradas en nuestro proyecto todas las librerías necesarias para trabajar con la API de Protege y Jess. Además necesitaremos la librería Jena ya que Protege utiliza esta librería para realizar las operaciones de bajo nivel sobre la ontología. En concreto necesitaremos:

  • protege.jar y looks.jar (Protege Core)
  • protege-owl.jar (ProtegeOWL)
  • jess.jar (Motor de inferencia)
  • swrl-jess-bridge.jar (Puente de enlace entre el motor de inferencia y la ontología)
  • orphanNodesAlg.jar (Requerida por ProtegeOWL en determinadas versiones)
  • Jena (Todos los jars que componen la librería)

¿Cómo o dónde consigo cada uno de estos ficheros jar?

Los tres primeros: protege.jar, looks.jar y protege-owl.jar se obtienen tras compilar el código fuente de la API de Protege. Podéis echar un vistazo a esta entrada en la que explico cómo realizar este proceso.

El siguiente jar: jess.jar podéis descargarlo de su página oficial en la que os dan 30 días de prueba para utilizar la librería e incluso podéis solicitar un año de prueba gratuita para uso académico. Para uso comercial, requiere licencia.

swrl-jess-bridge.jar es una librería necesaria para encapsular las funciones de bajo nivel de los motores de inferencia. El código fuente de la librería está disponible en los repositorios SVN de Protege y por tanto podéis compilarlo a partir de ahi utilizando Ant (por ejemplo). Aunque si no queréis complicaros, si os descargáis e instaláis la aplicación binaria de Protege, la que os permite utilizar todo su interfaz gráfico para crear y gestionar ontologías, encontraréis una versión ya compilada de esta librería. Normalmente se encuentra en el directorio: <ruta-instalacion-protege>/plugins/edu.stanford.smi.protegex.owl/swlr-jess-bridge.jar

En este mismo directorio podéis encontrar la librería orphanNodesAlg.jar.

Y por último todos los jar que componen la librería Jena podéis encontrarlos en su web oficial. Yo personalmente utilizo la versión 2.6.4 de Jena.

Empecemos con el código

Lo primero que debemos hacer es cargar nuestro modelo ontológico en memoria para trabajar con él. Esta operación suele ser pesada y dependiendo del tamaño y complejidad de nuestra ontología llevará más o menos tiempo.

JenaOWLModel jModel = ProtegeOWL.createJenaOWLModelFromInputStream(new FileInputStream(new File("Resources/animal.owl")));

Con esta operación cargamos en memoria la ontología almacenada en el fichero animal.owl, que en este caso contendrá una taxonomía de animales. Una vez que ya está en memoria nuestra ontología podremos manipularla a través de la referencia jModel.

La siguiente operación será establecer el motor de inferencia que vamos a utilizar y enlazarlo con nuestra ontología. Para ello:

SWRLRuleEngine engine = SWRLRuleEngineFactory.create("SWRLJessBridge", jModel);

Como veis, lo que estamos haciendo es decirle a la API de Protege que utilice el motor de inferencia Jess mediante el bridge SWRLJessBridge, por esta razón es necesaria la librería swrl-jess-bridge.jar.

Lo último que nos queda ya es disparar el motor de inferencia y procesar los resultados que se hayan obtenido. Para ello:

//Traducimos nuestra información en lenguaje OWL al lenguaje del Motor de Inferencia
engine.importSWRLRulesAndOWLKnowledge();
//Ejecutamos el motor de inferencia
engine.run();

A partir de aquí el motor de inferencia ya habrá hecho su trabajo y habrá disparado aquellas reglas SWRL que considerara aptas. El último paso por tanto, es procesar los datos obtenidos tras esta inferencia. Aquí tenemos dos opciones: La primera es dejar que sea el propio motor de inferencia el que actualice nuestra ontología, o recorrer los datos obtenidos y actualizarla nosotros mismos según nos interese.

La opción fácil y rápida:

//Dejamos que sea el motor de inferencia quien actualice la ontología
engine.writeInferredKnowledge2OWL();

Hasta aquí, si os fijáis, lo que hemos hecho es emular el comportamiento que tienen los tres botones que aparecen en el interfaz gráfico de Protege, en la pestaña de Jess.

La otra opción es recorrer y procesar por nosotros mismos los datos que hemos obtenido. Cuando un motor de inferencia se dispara, lo habitual es que nos ofrezca sus resultados en formato de tripleta de valores del siguiente modo: “Property (Instance, Value)“. Donde:

  • Property: Es la propiedad que ha visto alterado su valor tras la nueva inferencia
  • Instance: Es la instancia afectada por la inferencia
  • Value: Es el nuevo valor que ha recibido la propiedad Property de la instancia Instance.

El motor de inferencia nos aportará estras tripletas, denominadas también Axiomas, en una estructura que debemos recorrer y procesar. Habrá tantas tripletas como propiedades hayan modificado su valor tras la ejecución del motor de inferencia. Cuantas más reglas SWRL tengamos en nuestra ontología, mas tripletas obtendremos cada vez (o no). Para recorrer esta estructura debemos hacer lo siguiente:

if (engine.getNumberOfInferredOWLAxioms() > 0){ //Si hemos obtenido datos tras la inferencia
   for (Iterator<OWLAxiomReference> i = engine.getInferredOWLAxioms().iterator(); i.hasNext();){
      OWLAxiomReference o = i.next(); //Procesamos cada axioma
      if (o instanceof OWLPropertyAssertionAxiomReference) {
         OWLPropertyAssertionAxiomReference oA = (OWLPropertyAssertionAxiomReference) o;
         //Obtenemos la propiedad que ha sido afectada
         System.out.println(engine.uri2PrefixedName(oA.getProperty().getURI()));
         //Obtenemos la instancia
         System.out.println(engine.uri2PrefixedName(oA.getSubject().getURI()));
         if (o instanceof OWLDataPropertyAssertionAxiomReference){ //Si la propiedad es de tipo DataType
            OWLDataPropertyAssertionAxiomReference oD = (OWLDataPropertyAssertionAxiomReference) o;
            OWLDataValue data = engine.getOWLDataValueFactory().getOWLDataValue(oD.getObject());
            System.out.println(data.toString());
         }
      }
   }
}

NOTA: La función uri2PrefixedName() del objeto engine, se encarga de limpiar la cadena que vamos a mostrar de forma que muestre sólo el nombre de la instancia o de la propiedad, sin incluir todo el prefijo de su URI. La hemos utilizado en esta ocasión por claridad y limpieza. Si tenéis descargado el código fuente de ProtegeOWL, en la clase: edu.stanford.smi.protegex.owl.swrl.ui.subtab.InferredAxiomsPanel.java, tenéis un ejemplo sobre cómo acceder a otras propiedades que no sean de tipo DataType como las del ejemplo

En este fragmento de código lo único que estamos haciendo es recorrer la estructura de axiomas obtenidos y mostrar sus valores por pantalla, si quisiéramos añadirlos a la ontología y actualizarla nosotros mismos manualmente, podríamos hacerlo a través de los métodos de la API de Protege de forma fácil. Tenéis un ejemplo en esta entrada.

Utilizo una versión anterior a la 3.4.8 de la API de Protege

En este caso hay métodos que han variado un poco su nomenclatura y clases que en versiones anteriores estaban y en estas nuevas versiones de la API han desaparecido. Realmente las diferencias son mínimas,  pero pueden darnos un buen quebradero de cabeza si no las conocemos. Por ejemplo si estamos utilizando la API 3.4.1 de Protege, la forma de acceder al motor de inferencia y realizar las operaciones anteriores es así:

Establecemos cuál será nuestro motor de inferencia. En este caso hacemos uso de las clases SWRLRuleEngineBridge y BridgeFactory, que en estas nuevas versiones de la API han desaparecido:

SWRLRuleEngineBridge bridge =BridgeFactory.createBridge("SWRLJessBridge", jModel);
//Traducimos nuestra información en lenguaje OWL al lenguaje del Motor de Inferencia
bridge.importSWRLRulesAndOWLKnowledge();
//Ejecutamos el motor de inferencia
bridge.run();
//Almacenamos el conocimiento en la ontologia directamente
bridge.writeInferredKnowledge2OWL();

//o ...
if (bridge.getNumberOfInferredAxioms() > 0){ //Si hemos obtenido datos tras la inferencia
      for (Iterator<OWLAxiom> i = bridge.getInferredAxioms().iterator(); i.hashNext();){
        ...
      }
}

Y ya sabéis, cualquier duda, sugerencia, mejora, … será siempre bien recibida 😉

Más Info:

En Rekkeb’s Blog | Conocer qué reglas se están disparando con Jess

En Rekkeb’s Blog | Crear una ontología OWL usando la API de Protege

En Rekkeb’s Blog | Compilar la API de Protege 3.x Partiendo de los fuentes

En Rekkeb’s Blog | Eclipse. Librerías del Usuario

Anuncios
3 comentarios leave one →
  1. 24 noviembre 2012 15:58

    Hola, quisiera saber como puedo obtener las reglas que estan activas en la ontologia estoy usando Protege 3.4.8 y Jess 7.1.

    Por ejemplo:

    “Person(?p) ^ hasAge(?p, ?age) ^ swrlb:greaterThan(?age, 17) -> Adult(?p)”

    ya que solamente con System.out.println(engine.getImportedSWRLRules()) obtengo el nombre de ellas.

    Gracias

  2. Manuel permalink
    16 septiembre 2014 20:34

    Me parece genial toda esta información que nos das. Pronto comenzaré a introducirme en la implementación de ontologías. De seguro estaré necesitando su ayuda.

    Saludos.

  3. frank permalink
    11 noviembre 2014 01:01

    Me he aventurado en este tema y estoy medio perdido…..

    estoy haciendo una ontología ….. vahaa… ya tengo la ontologia echa con protege.
    pero ahora no se cual es el paso a seguir.

    tengo que programar algo en java? y creo un ejecutable

    no se que sigue para hacer las consultas en un pagina web.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: