1. Práctica:Representación Estructurada del Conocimiento
  2.  

     

    1. Objetivo de la práctica

Esta práctica tiene varios objetivos. En primer lugar continuar el aprendizaje de Common Lisp, en este caso con aplicaciones a la representación del conocimiento. En segundo lugar comprobar como es posible la creación de tu propio esquema de representación del conocimiento, simulando incluso una metodología orientada a objeto. Y como último objetivo utilizar un esquema de representación para modelar entidades de un dominio concreto.

Para poder enfrentarte con éxito a esta práctica debes cumplir algunos requisitos previos:

1. En programación orientada a objeto hay conceptos muy importantes como: especialización, herencia, mensajes, encapsulamiento, etc. Convendría que los repasaras.

  1. En un lenguaje de frames también hay cosas importantes como slots, demonds (if-needed, if-added), espectativas, razonamiento por defecto, razonamiento por herencia, etc.

 

    1. Descripción del sistema
    2. Los listados que se encuentran al final de la práctica corresponden a la implementación de un simple esquema de representación del conocimiento que hemos denominado IERL (iaaa experimental representation language.

       

      1. Una introducción al IERL

      La unidad básica de conocimiento en IERL se llama form y está implementada utilizando la lista de propiedades disponibles en los símbolos. Como en las prácticas anteriores, trataremos de ocultar los detalles de implementación de las estructuras de datos detrás de la sintaxis de nuestro nuevo lenguaje (IERL).

      Una de las particularidades más importantes de este lenguaje es su énfasis en la jerarquía is-a. Esto es, diseñamos nuestra representación para tomar ventaja del hecho de que muchos hechos sobre una entidad, tales como el número de patas de una vaca particular, pueden ser inferidos de la superclase a la que pertenece la entidad: vaca, mamífero, animal.

      Si lees cuidadosamente el listado adjunto encontrarás diversas funciones que permiten definir forms, acceder a sus contenidos y modificarlos.

      También podrás encontrar un ejemplo de una base de conocimiento muy simple especializada en la asistencia a una empresa inmobiliaria.

      - Haz pruebas creando y obteniendo valores de las forms.

       

    3. Tarea

La primera tarea concreta de esta práctica es familiarizar al alumno con la utilización de sistemas basados en frames con demons y mensajes. La jerarquía is-a ya está soportada por el esquema de representación del conocimiento proporcionado por IERL, mientras que tu deberás implementar demons que hacen uso de esta relación.

 

1. - Para la base de conocimiento de la inmobiliaria, crea un slot denominado cantidad con el demon if-needed adecuado de forma que devuelva la cantidad que en ese momento existan de instancias (forms que no tienen descendientes) de la clase (o instancia) a la que se pregunta. Por ejemplo, para la jerarquía dada de la inmobiliaria:

(get-value 'vivienda 'cantidad)

---> 2

(get-value 'apartamento 'cantidad)

---> 1

(get-value 'chalet 'cantidad)

---> 1

(get-value 'chalet-montesol-5 'cantidad)

---> 1

 

!!!Nota!!!: Modifica la función que crea forms para que se guarden los hijos directos que tiene una clase y así se pueda obtener el número de instancias mediante if-needed.

 

2. - Habrás observado en el ejemplo de la inmobiliaria el funcionamiento del aspecto if-needed (es un mecanismo que permite disparar una función siempre que se trate de obtener el valor de su slot). Otro aspecto que puede resultar útil es if-added (es un mecanismo que permite disparar una función siempre que se trate de modificar el valor de su slot).

( a ) Deberás incrementar la potencia de representación de IERL con el mecanismo if-added.

( b ) Se pide también incrementar la base de conocimiento anterior con slots que hagan uso de este mecanismo. Muestra su utilidad y resultados con un ejemplo.

3. - En programación orientada a objeto los métodos son el mecanismo utilizado para encapsular los detalles de implementación. Incrementa la potencia de representación de IERL con el mecanismo de envío de mensaje. Para ello define las funciones

 

(create-method form mensaje metodo) y

(<-- form mensaje &rest parámetros)

Se pide también incrementar la base de conocimiento anterior con slots que hagan uso de este mecanismo. Muestra su utilidad y resultados de ejecución con un ejemplo.

4. - Deberás utilizar IERL para crear una base de conocimiento (forms y funciones adicionales). Define un frame genérico que contenga la siguiente información referente a una persona: nombre, apellido, cónyuge, padres, hijos, si está vivo o no, etc. Definir instancias para representar la siguiente familia.

  1. Definir métodos para casar, dar a luz, y fallecimientos de personas.
  2. Cuando fallece una persona se reparten a partes iguales sus pertenencias entre el cónyuge y los hijos que le sobrevivan. Si no tiene hijos ni cónyuge se reparten a partes iguales entre los padres y los hermanos. De la misma manera se reparte el valor del atributo cuenta (ptas). Las pertenencias se suponen del mismo valor. Si el número de pertenencias no fueran divisibles, el resto pasa a pertenecer al cónyuge, y si este no le sobrevive el resto se pierde (pasan a pertenecer al estado). El orden de los hijos en la lista de hijos determina las pertenencias que les corresponden. Por ejemplo, si una persona viuda fallece con tres pertenencias deja la primera a su primer hijo, la segunda al segundo hijo, y la tercera se pierde.
  3. Definir demonios que devuelvan los hermanos políticos de una persona. Se calculan si se solicitan.
  4. Las pertenencias tienen un atributo propietario y las personas tienen el atributo pertenencias. Define un demonio que actualice el correspondiente propietario de la pertenencia cuando esta se añada a la lista de pertenencias de una persona.
  5. Los abuelos dan una asignación semanal a los nietos. El atributo asignacion_abuelos tiene un valor que se calcula si se solicita, y su valor viene dado por el número de abuelos vivos * 1000.

 

Listado de las funciones suministradas

Creación de las form

 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;; iaaa iaaa iaaa iaaa iaaa iaaa iaaa iaaa iaaa iaaa ;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;

;;; Pedro R. Muro & Jose L. Villarroel

;;;

;;; 20-2-1991

;;;

;;; IERL: iaaa experimental representation language

;;;

;;;

;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;; iaaa iaaa iaaa iaaa iaaa iaaa iaaa iaaa iaaa iaaa ;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;

;;; Una form tiene tres partes: un IS-A, slots y metodos

;;; esta implementada mediante la lista de propiedades del simbolo.

;;;

;;;

;;; FORM :: valor

;;; Modifica los valors de una form y la crea en caso de que no exista.

;;;

(defun form (&key name is-a slots)

(let* ((la-form (if (get name 'is-a)

name

(progn (setf (get name 'is-a) is-a) name)))

)

(dolist (slot-conten slots)

(funcall #'set-aspect la-form

(car slot-conten)

(cadr slot-conten)

(cadr(cdr slot-conten))))

la-form))

 

Funciones de modificación

 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;

;;;(SET-ASPECT form slot aspecto valor) :: valor

;;; Guarda el valor del aspecto del slot de la form.

;;;

;;; Cada slot corresponde con una propiedad del simbolo.

;;; El contenido del slot esta formado por listas de aspectos compuestas

;;; por un simpbolo identificador del aspecto y su contenido:

;;; = para el valor

;;; IF-NEEDED para el metodo de acceso

;;;

(defun set-aspect (form slot aspecto valor)

(let* ((contenido (get form slot)))

(cond (contenido

(if (assoc aspecto contenido)

(rplacd (assoc aspecto contenido) valor)

(setq contenido (cons (list aspecto valor) contenido))))

(t

(setq contenido (cons (list aspecto valor) contenido))))

(setf (get form slot) contenido)))

 

 

;;; SET-VALUE esta especializado en el aspecto =

;;; el parametro MENSAJE no es realmente necesario si no se utiliza el modo

;;; orientado a objeto

;;; (en POO normalmente todos los metodos reciben al menos dos parametros,

;;; el primero es el OBJETO y el segundo el MENSAJE.

;;;

(defun set-value (form slot valor)

(set-aspect form slot '= valor))

 

Funciones de acceso

 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;

;;; Aqui comienzan las definiciones del vocabulario de acceso y

;;; manipulacion de datos

;;;

;;;(GET-ASPECT form slot aspecto) :: valor

;;; Devuelve el valor del aspecto del slot de la form

;;;

 

;;;

;;; GET-SIMPLE-ASPECT toma un aspecto de un slot sin acceder por la

;;; jerarquia.

;;;

(defun get-simple-aspect (form slot aspecto)

(cadr (assoc aspecto (get form slot))))

 

;;;

;;; GET-ASPECT toma un aspecto de un slot accediendo por la

;;; jerarquia.

;;;

(defun get-aspect (form slot aspecto)

(let* ((value (assoc aspecto (get form slot))))

(if value

(cadr value)

(if (get form 'is-a)

(get-aspect (get form 'is-a) slot aspecto)

))))

 

;;;

;;; GET-VALUE toma el aspecto = de un slot accediendo por la

;;; jerarquia.

;;; Amplia el vocabulario para el aspecto = pues es muy utilizado.

;;;

(defun get-value (form slot)

(get-aspect form slot '=))

 

;;;

;;; GET-VALUE obtiene el valor del aspecto = de un slot con herencia

;;; y aplicando ademas el demond en el aspecto IF-NEEDED.

;;;

(defun get-value (form slot)

(let ((needed (get-aspect form slot 'if-needed)))

(if needed

(funcall needed form slot)

(get-aspect form slot '=))))

 

;;;

;;; FIND-SLOT-FROM-SUPERS toma el contenido entero de un slot accediendo por la

;;; jerarquia.

;;; Puede ser utilizado para heredar mensajes en el estilo orientado a objeto

;;;

(defun find-slot-from-supers (form slot)

(let* ((value (get form slot)))

(if value

value

(if (get form 'is-a)

(find-slot-from-supers (get form 'is-a) slot)

))))

Listado del ejemplo

 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;

;;; Creacion de la estructura de conocimiento para el problema de

;;; los apartamentos.

;;; El objetivo es disponer de una representacion del conocimiento

;;; que permita obtener informacion a una empresa inmoviliaria.

;;; Para ello se crea una base de datos de forms con algunos metodos.

;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;; Generacion de la jerarquia de forms

;;; La funcion GBD genera la base de datos de las forms

(defun gbd ()

(let ()

(create-form :is-a nil :name 'object)

(form :name 'cosa

:is-a 'object)

(form :name 'vivienda

:is-a 'cosa)

(form :name 'apartamento

:is-a 'vivienda

:slots (list (list 'ruido-calle 'if-needed #'calcula-ruido)))

(form :name 'chalet

:is-a 'vivienda

:slots (list (list 'ruido-calle 'if-needed #'calcula-ruido-en-casa)

))

(form :name 'apt-breton-22

:is-a 'apartamento

:slots '((calle-nombre = Breton)

(calle-numero = 22)

(color-pared = blanco)

(material-suelo = madera)))

(form :name 'apt-22-1

:is-a 'apt-breton-22

:slots '((numero-habitaciones = 3)

(piso = 2)))

(form :name 'chalet-montesol-5

:is-a 'chalet

:slots '((calle-nombre = urbanizacion-montesol)

(calle-numero = 5)

(numero-habitaciones = 5)

(pisos = 2)

(distancia-carretera = 200)))

))

 

(defun calcula-ruido (form slot)

(let* ((valor (get-aspect form 'ruido-calle '=))

piso)

(cond (valor valor)

(t (setq piso (get-value form 'piso))

(cond ((> piso 15) 'muy-bajo)

((> piso 8) 'bajo)

((> piso 4) 'medio)

((> piso 1) 'alto)

(t 'muy-alto))))))

 

(defun calcula-ruido-en-casa (form slot)

(let* ((valor (get-aspect form 'ruido-calle '=))

distancia)

(cond (valor valor)

(t (setq distancia (get-value form 'distancia-carretera))

(cond ((> distancia 1000) 'muy-bajo)

((> distancia 100) 'bajo)

((> distancia 30) 'medio)

((> distancia 10) 'alto)

(t 'muy-alto))))))

Ejemplo de utilización

 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;

;;; Puedes probar a obtener valores con la funcion GET-VALUE

;;;

;(get-value 'apt-22-1 'ruido-calle)

;--> ALTO

;(get-value 'chalet-montesol-5 'ruido-calle)

;--> BAJO

;;;

;(set-value 'apt-breton-22 'ruido-calle 'muy-alto)

;(set-value 'chalet 'ruido-calle 'muy-bajo)

;(get-value 'apt-22-1 'ruido-calle)

;--> MUY-ALTO