Problema de la consulta de un médico.
Tenemos varias entidades...
Paciente: formado por nombre, apellidos, dni y año de nacimiento.
Consulta: formada por dni del paciente, fecha de visita, los signos y los sintomas...
Existe una relacion paciente consulta que viene representada por la asignacion del dni, un paciente puede realizar varias consultas...
Intentando representar simplificando el problema mediante hechos ordenados:
(assert (paciente pepe 62457 1977))
He quitado los apellidos porque al ser compuestos puede dar problemas... asi tenemos una representacion simplificada. Vamos con la consulta...
(assert (consulta 62457 12-12-2001 enrojecimiento de los ojos posiblemente debido al uso continuado del ordenador se le receta colirio))
Usando variables quedaria asi...
(assert (consulta ?x ?y $?z))
Siendo z variable de campo multiple.
sacar un listado de todas las consultas de un paciente seria...
(defrule paciente-consultas
(paciente ?x ?y ?z)
(consulta ?y ?j $?k)
=>
(printout t "El paciente " ?x " con dni " ?y " nacido el año " ?z crlf)
(printout t "realizo una consulta el dia " ?j " presentando lo siguiente " ?k crlf)
Vamos a crear una regla para monstar el listado anterior ordenado por orden
alfabetico, para ello creo una lista...
(asert (listado ))
(defrule inserta-lista
(declare (salience 200))
?f1<-(listado $?antes ?y $?despues)
(paciente ?x&~?y ? ?)
=>
(retract ?f1)
(if (< ?y ?x) then
(assert (listado ?antes ?x ?y ?despues))
else
(assert (listado ?antes ?y ?x ?despues)))
)
Ahora la regla para mostrarlos...
(defrule paciente-consultas
(declare (saliente 100))
f2<-(listado ?x $?resto)
(paciente ?x ?y ?z)
(consulta ?y ?j $?k)
=>
(retract ?f2)
(asssert (listado ?resto))
(printout t "El paciente " ?x " con dni " ?y " nacido el año " ?z crlf)
(printout t "realizo una consulta el dia " ?j " presentando lo siguiente " ?k crlf)
Podemos utilizar plantillas que nos representen mejor el problema...
(deftemplate paciente "Los datos de un paciente"
(slot nombre
(type STRING))
(slot apellidos
(type STRING))
(slot dni
(type INTEGER)
(default ?NONE)) ;debe declararse el dni.
(slot nacimiento
(type SYMBOL))
)
(deftemplate consulta "Los datos de una consulta"
(slot dni
(type INTEGER)
(default ?NONE)) ;debe declararse el dni.
(slot visita
(type SYMBOL)) ; fecha de la visita
(slot signos
(type STRING))
(slot sintomas
(type STRING))
(slot diagnostico
(type STRING))
)
y para listar los pacientes que han ido a una consulta la regla seria...
(defrule consulta-paciente
(consulta (dni ?x)(visita ?y) (signos ?w)(sintomas ?z)(diagnostico ?t))
(paciente (nombre ?i)(apellidos ?j)(dni ?x)(nacimiento k))
=>
(printout t "El paciente " ?i " " ?j " con dni " ?x " nacido el año " ?k crlf)
(printout t "realizo una consulta el dia " ?y " presentando..." crlf)
(printout t "signos: " ?w crlf)
(printout t "sintomas: " ?z crlf)
(printout t "diagnostico: " ?t crlf)
)
(assert listado)
; Ojo el nombre debe ser entonces de tipo SYMBOL
(defrule inserta-lista-ordenadamente
(declare (salience 200))
?f1<-(listado $?antes ?y $?despues)
(paciente (nombre ?x&~?y))
=>
(retract ?f1)
(if (< ?y ?x) then
(assert (listado ?antes ?x ?y ?despues))
else
(assert (listado ?antes ?y ?x ?despues)))
)
(defrule paciente-consultas
(declare (saliente 100))
f2<-(listado ?i $?resto)
(paciente (nombre ?i)(apellidos ?j)(dni ?x)(nacimiento k))
(consulta (dni ?x)(visita ?y) (signos ?w)(sintomas ?z)(diagnostico ?t))
=>
(retract ?f2)
(asssert (listado ?resto))
(printout t "El paciente " ?i " " ?j " con dni " ?x " nacido el año " ?k crlf)
(printout t "realizo una consulta el dia " ?y " presentando..." crlf)
(printout t "signos: " ?w crlf)
(printout t "sintomas: " ?z crlf)
(printout t "diagnostico: " ?t crlf)
)