Respuestas Lisp.

Anuncio
Considere un sistema basado en reglas que realiza inferencia mediante encadenamiento hacia atrÁs. Los hechos
ciertos se almacenan en una lista asignada a la variable *hechos*:
(defvar *hechos* ‘(A H J M) )
y las reglas en otra lista asignada a la variable *reglas*:
(defvar *reglas* ‘( ( (A H) (C) )
( (C D R) (L) )
( (B J) (C) )
( (J M) (D) )
( (D A) (R) ) ) )
donde cada regla consta de dos sublistas. La primera sublista almacena el antecedente: conjunto de condiciones que
se deben cumplir conjuntamente para que la regla pueda ser aplicada. La segunda sublista contiene el consecuente:
hecho que pasa a ser cierto cuando la regla sea ejecutada.
En un proceso de encadenamiento hacia atrÁs, aquel hecho cuya veracidad pretendamos verificar da lugar a un
Árbol Y-O en funciÓn del contenido de *reglas*. Por ejemplo,
> (arbol-YO ‘R)
(enlaceY (enlaceY J M) A)
> (arbol-YO ‘L)
(enlaceY (enlaceO (enlaceY A H) (enlaceY B J)) (enlaceY J M) (enlaceY (enlaceY J M) A))
> (arbol-YO ‘A)
A
Por tanto, cualquier Árbol Y-O generado en un proceso de encadenamiento hacia atrÁs no contendrÁ ningÚn hecho que
pertenezca al consecuente de una regla perteneciente a *reglas*. Se pide, en primer lugar, escribir el procedimiento
LISP, denominado “arbol-YO”, que calcule el Árbol Y-O asociado a cierto hecho, teniendo en cuenta el contenido de
*reglas*.
En segundo lugar, dado un Árbol Y-O cualquiera, no generado necesariamente a partir de *reglas*, construir un
procedimiento LISP, denominado “evaluar-arbol-YO”, que determine si el hecho asociado a ese Árbol puede o no ser
considerado como cierto en funciÓn del contenido de *hechos*. Por ejemplo,
> (evaluar-arbol-YO ‘(enlaceY A H))
T
> (evaluar-arbol-YO ‘(enlaceO A B))
T
> (evaluar-arbol-YO ‘K)
NIL
> (evaluar-arbol-YO ‘(enlaceY (enlaceO A K) A M))
T
SOLUCI³N (por Severino FernÁndez GalÁn):
(defvar *hechos* '(A H J M))
(defvar *reglas* '(((A
((C
((B
((J
((D
H) (C))
D R) (L))
J) (C))
M) (D))
A) (R))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Procedimiento pedido en la primera parte del enunciado
(defun arbol-YO (hecho)
(case (numero-de-reglas-con-consecuente hecho)
(0 hecho)
(1 (arbol-YO-de-antecedente (antecedente-1 hecho)))
(otherwise (arbol-YO-de-antecedentes (antecedentes hecho)))))
;;; Determina el número de reglas en *reglas* cuyo consecuente es "h"
;;; Ejemplo: > (numero-de-reglas-con-consecuente 'C)
;;;
2
(defun numero-de-reglas-con-consecuente (h)
(let ((resultado 0))
(dolist (regla *reglas* resultado)
(when (eq (caadr regla) h)
(setf resultado (1+ resultado))))))
;;; Devuelve el antecedente de la primera regla en *reglas* cuyo consecuente es "h"
;;; Ejemplo: > (antecedente-1 'C)
;;;
(A H)
(defun antecedente-1 (h)
(dolist (regla *reglas*)
(when (eq (caadr regla) h)
(return (first regla)))))
;;; Halla el árbol Y-O determinado en *reglas* por los hechos de un único antecedente
;;; Ejemplo: > (arbol-YO-de-antecedente '(D A))
;;;
(enlaceY (enlaceY J M) A)
(defun arbol-YO-de-antecedente (antecedente)
(if (= (length antecedente) 1)
(arbol-YO (first antecedente))
(let ((resultado '(enlaceY)))
(dolist (hecho antecedente (reverse resultado))
(setf resultado (cons (arbol-YO hecho) resultado))))))
;;; Devuelve una lista con los antecedentes en *reglas* cuyo consecuente es "h"
;;; Ejemplo: > (antecedentes 'C)
;;;
((A H) (B J))
(defun antecedentes (h)
(let ((resultado))
(dolist (regla *reglas* resultado)
(when (eq (caadr regla) h)
(setf resultado (cons (first regla) resultado))))))
;;; Halla el árbol Y-O determinado en *reglas* por la disyunción de varios antecedentes
;;; Ejemplo: > (arbol-YO-de-antecedentes '((D A) (A H)))
;;;
(enlaceO (enlaceY (enlaceY J M) A) (enlaceY A H))
(defun arbol-YO-de-antecedentes (lista-de-antecedentes)
(let ((resultado '(enlaceO)))
(dolist (antecedente lista-de-antecedentes (reverse resultado))
(setf resultado (cons (arbol-YO-de-antecedente antecedente) resultado)))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Procedimiento pedido en la segunda parte del enunciado
(defun evaluar-arbol-YO (arbol)
(cond ((null arbol) nil)
((atom arbol) (member arbol *hechos*))
((eq (first arbol) 'enlaceY) (dolist (condicion (rest arbol) t)
(unless (evaluar-arbol-YO condicion)
(return nil))))
((eq (first arbol) 'enlaceO) (dolist (condicion (rest arbol) nil)
(when (evaluar-arbol-YO condicion)
(return t))))))
Escriba un procedimiento LISP que solicite al usuario dos matrices numÉricas, las multiplique y muestre el resultado
en pantalla de manera que cada fila de la matriz resultante aparezca en un renglÓn y se reserven 7 espacios para
escribir cada nÚmero.
SOLUCI³N (por Severino FernÁndez GalÁn):
(defun multiplica2matrices (&aux matriz1 filas1 columnas1 matriz2 columnas2 matriz3)
;; Definición de las dimensiones de las matrices
(format t "~%Introduzca el número de filas de la primera matriz: ")
(setf filas1 (read))
(format t "~%Introduzca el número de columnas de la primera matriz: ")
(setf columnas1 (read))
(format t "~%Introduzca el número de columnas de la segunda matriz: ")
(setf columnas2 (read))
;; Definición de las matrices
(setf matriz1 (make-array (list filas1 columnas1)))
(setf matriz2 (make-array (list columnas1 columnas2)))
(dotimes (f1 filas1)
(dotimes (c1 columnas1)
(format t "~%Escriba elemento (~a,~a) de la primera matriz: " (1+ f1) (1+ c1))
(setf (aref matriz1 f1 c1) (read))))
(dotimes (f2 columnas1)
(dotimes (c2 columnas2)
(format t "~%Escriba elemento (~a,~a) de la segunda matriz: " (1+ f2) (1+ c2))
(setf (aref matriz2 f2 c2) (read))))
;; Calcular la matriz resultante
(setf matriz3 (make-array (list filas1 columnas2)))
(dotimes (f3 filas1)
(dotimes (c3 columnas2)
(let ((parcial 0))
(dotimes (n columnas1)
(setf parcial (+ parcial (* (aref matriz1 f3 n) (aref matriz2 n c3)))))
(setf (aref matriz3 f3 c3) parcial))))
;; Mostrar resultado poniendo cada fila en un renglón
(format t "~%Matriz resultante de la multiplicación de las dos anteriores: ")
(dotimes (f3 filas1)
(format t "~%")
(dotimes (c3 columnas2)
(format t "~7a" (aref matriz3 f3 c3))))
)
Descargar