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)
)