;*********************************************************************
; Módulo: IERL
; Uso:    IAAA Experimental Representation Language
; Autor:  Roberto Sobreviela Ruiz
; email:  419245@cepsz.unizar.es
;         sobreviela@teleline.es
;*********************************************************************
; Fichero: IERL Forward.lsp Fecha Creación: 20 de diciembre de 1999
; Versión: 0.0.1          Fecha Modificación: 28 de diciembre de 1999
; Estado:  Desarrollo     Autor: Roberto Sobreviela Ruiz
;---------------------------------------------------------------------
; Uso: Extensión del lenguaje IERL.
; Comentarios:
;    Almacenamiento de afirmaciones y reglas según la propuesta de 
;   Patrick Henry Winston [Lisp, Winston & Horn 3th ed].
; Historia:
;   Versión 0.0.1:  Implementaciones de las funciones de manejo de
;       afirmaciones y reglas.
;*********************************************************************

;; Definción de variables del motor de inferencia
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defvar *afirmaciones* 'flujo-vacio "Afirmaciones del Sistema de producción")
(defvar *reglas* 'flujo-vacio "Reglas del Sistema de producción")
(defvar *frames* 'flujo-vacio "Frames del Sistema de producción")

;; Funciones de manejo de afirmaciones
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defun recuerda-afirmacion (afirmacion)
    (recuerda-flujo afirmacion *afirmaciones*))

;; Funciones de manejo de frames
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defun recuerda-frame (frame)
    (recuerda-flujo (list frame) *frames*))

;; Funciones de manejo de reglas
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defun nombre-de-la-regla (regla)
    (first regla))

(defun antecedentes-de-la-regla (regla)
    (butlast (rest regla)))

(defun consecuente-de-la-regla (regla)
    (first (last regla)))

(defun recuerda-regla (regla)
    (format t "~%Añadiendo la regla ~a." regla)
    (recuerda-flujo regla *reglas*))

;; Funciones de manejo de ligaduras para afirmaciones
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defun intenta-afirmacion (patron afirmacion ligaduras)
    (let ((resultado (corresponde patron afirmacion ligaduras)))
        (if (eq 'FALLA resultado)
            'FLUJO-VACIO
            (construye-flujo resultado 'FLUJO-VACIO))))

(defun corresponde-patron-con-afirmaciones (patron ligaduras)
    (concatena-flujo 
        (transforma-flujo 
            #'(lambda (afirmacion)
                    (intenta-afirmacion patron afirmacion ligaduras))
            *afirmaciones*)))

;; Funciones de manejo de ligaduras para frames
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defun intenta-frame (patron frame ligaduras)
    (let ((resultado (corresponde-frames patron frame ligaduras)))
        (if (eq 'FALLA resultado)
            'FLUJO-VACIO
            (construye-flujo resultado 'FLUJO-VACIO))))

(defun corresponde-patron-con-frames (patron ligaduras)
    (concatena-flujo 
        (transforma-flujo 
            #'(lambda (frame)
                    (intenta-frame patron frame ligaduras))
            *frames*)))
