Documentos de Académico
Documentos de Profesional
Documentos de Cultura
5
Julio Luis Tenorio Cabrera.
Manual Visual Prolog 7.5
INDICE
INDICE ........................................................................................................................................................................ 1
MODO CONSOLA ...................................................................................................................................................... 2
MODO GUI ................................................................................................................................................................ 35
MODO CONSOLA
Visual Prolog, es un entorno de desarrollo para Sistemas Expertos, basado en la programación lógica
utilizando asimismo el mecanismo de razonamiento con encadenamiento hacia atrás para realizar el
proceso de razonamiento.
En Visual Prolog, no es necesario programar el proceso de razonamiento ya que, cómo se mencionó
anteriormente, ya se encuentra implementado, por lo que sólo se le debe de alimentar de la
experiencia, es decir del conocimiento del experto o especialista humano, para la construcción de la
Base de Conocimiento del Sistema Experto que se vaya a desarrollar.
Visual Prolog, permite el desarrollo de aplicaciones tanto a nivel consola como aplicaciones de tipo
GUI. Para el presente manual, empezaremos explicando el desarrollo de aplicaciones a nivel consola
y luego con las aplicaciones tipo GUI.
Para el ingreso a Visual Prolog, hacemos doble click sobre el ícono respectivo, el que se muestra a
continuación:
Luego observaremos la siguiente interfaz, en la que podemos crear un nuevo proyecto, abrir un
proyecto de la lista de proyectos que se muestren en dicha interfaz o buscar ayuda en la wiki de
Visual Prolog (http://wiki.visual-prolog.com/index.php?title=Getting%20Started). La interfaz que
se muestra es:
Para la creación de un nuevo proyecto (Ejercicio 01) llamado “Hola Mundo” (por el momento de
tipo consola), se hace click en el botón “New Project” y en la interfaz que aparece se escriben los
datos necesario para el proyecto, tal como se muestra a continuación: (no olvidar que el tipo de
proyecto “Project Kind” es “Console Application”)
Luego de haber registrado los datos respectivos, se hace click en el botón Finish con lo que
aparecerá la siguiente interfaz y a la vez Visual Prolog compilará por defecto la aplicación que se
está desarrollando, mostrándose en la ventana “Messages” el proceso de compilación y finalmente
mostrándose el mensaje “Project has been built” es decir que el “Proyecto ha sido construido”:
En este punto es importante explicar el contenido de la ventana del proyecto en donde se observan
dos carpetas, una que lleva el nombre del proyecto, en este caso “Hola Mundo” y la otra $(ProDir).
La carpeta “Hola Mundo” contiene los archivos del proyecto que se deben de trabajar por parte del
desarrollador del proyecto, como por ejemplo los archivos: “Hola Mundo.vipprj”, “main.cl”,
“main.manifest”, “main.pack”, “main.ph”, “main.pro”, etc., y la carpeta $(ProDir) contiene
dos carpetas: “lib” y “pfc” que contienen las librerías a ser utilizadas en el proyecto. Por ejemplo
el archivo main.pack, se relaciona con la carpeta “pfc” (que está dentro de la carpeta “$(ProDir”),
ya que incluye a algunos paquetes y archivos que la carpeta “pfc” contiene. Asimismo el archivo
“main.pack” también contiene al archivo “main.ph” y “main.pro”. Esto se muestra a
continuación:
#include @"main.ph"
% privately used packages
#include @"pfc\console\console.ph"
#include @"pfc\core.ph"
% private interfaces
% private classes
% implementations
#include @"main.pro"
Asimismo por ejemplo, el archivo main.ph, requiere al archivo main.pack e incluye también al
archivo “core.pro” de la carpeta “pfc” y al archivo main.cl. Se debe hacer mención que el archivo
“core.pro”, es fundamental ya que contiene todos los predicados para el funcionamiento de un
programa por ejemplo, la definición de los tipos de datos. Esto se muestra a continuación:
#requires @"main.pack"
% publicly used packages
#include @"pfc\core.ph"
% exported interfaces
% exported classes
#include @"main.cl"
El archivo main.cl, contiene la declaración del predicado run, el que se va a definir en main.pro.
Esto se muestra a continuación:
class main
open core
predicates
run : core::runnable.
end class main
El archivo main.manifest contiene el código XML del proyecto tal como se muestra a
continuación:
El archivo “console.pro”, que está ubicado en la carpeta “console” de la carpeta “pfc”, contiene
por ejemplo al predicado “write”. Esto se puede verificar visualizando el archivo “consola.pro”,
desde el Visual Prolog.
Ahora, continuando con el desarrollo del programa “Hola Mundo”, se procede a escribir el código
respectivo en el archivo “main.pro”, ya que es el archivo que contiene el código fuente principal
de la aplicación cuando se trabaja en modo consola. Entonces se hace doble click sobre el archivo
“main.pro” con lo que se muestra el siguiente código:
implement main
open core
clauses
run() :-
succeed. % place your own code here
end implement main
goal
console::runUtf8(main::run).
Ahora se procede a completar el código por defecto tal como se muestra a continuación:
implement main
open core
clauses
run() :-
console::write("Hola Mundo..."),
_=console::readChar().
end implement main
goal
console::runUtf8(main::run).
Otra versión del programa “Hola Mundo”, que es la que usaremos de ahora en adelante en el
presente manual, es la que se muestra a continuación:
implement main
open core,console
clauses
run() :-
write("Hola Mundo..."),
_=readChar().
end implement main
goal
console::runUtf8(main::run).
existen inconvenientes, Visual Prolog enviará el mensaje: “Project has been built” y luego se
selecciona la subopción “Execute” ubicada en la opción del menú principal: “Build”, con lo que
se mostrará el resultado de la ejecución de la aplicación “Hola Mundo”, tal como se muestra a
continuación:
Figura 05: Pantalla visualización de resultado de la ejecución del proyecto del ejercicio 01
Ejercicio 02: Desarrollar una aplicación que solicite un nombre y le envíe un saludo incluido el
nombre ingresado.
Solución:
Se muestra el código de “main.pro”:
implement main
open core, console
clauses
run() :-
write("Ingrese su nombre por favor:"),
User=readLine(),
write("Bienvenido ",User," presiona por favor una tecla para continuar..."),
_=readChar().
end implement main
goal
console::runUtf8(main::run).
Solución:
En la solución del presente programa se utilizará la variable anónima o blanca o no ligada, que
se representa con el guion bajo o underscore (_) el cuál se utiliza para ignorar el valor que se capture
con el predicado readChar(), ya que para el caso presente no es de interés. Asimismo se utiliza el
predicado corte (!) el que evitará que el motor de inferencia de Visual Prolog ejecute la otra
implementación del predicado “run” ya que éste se debería ejecutar cuando la primera
implementación de “run” falle.
Se muestra el código de “main.pro”:
implement main
open core, console
class facts
capital : (string,string).
clauses
capital("La Libertad","Trujillo").
run() :-
write("A continuación mostraré la capital de un Departamento, por favor presione una tecla para continuar..."),
_=readChar(),
capital(X,Y),
write("La capital de ",X," es: ",Y),
_=readChar(),
!.
run().
end implement main
goal
console::runUtf8(main::run).
Ejercicio 04: Desarrollar una aplicación que muestre la capital de un Departamento el que será
ingresada por teclado, y en el caso que no se conozca la capital, se debe enviar un mensaje al usuario.
Solución:
implement main
open core,console
class facts
capital : (string,string).
clauses
capital("La Libertad","Trujillo").
capital("Lambayeque","Chiclayo").
capital("Lima","Lima").
capital("Piura","Piura").
run() :-
write("A continuación mostraré cuál es la capital de un Departamento, ingrese el nombre del Departamento:"),
Dpto=readLine(),
capital(Dpto,Capi),
write("La capital de ",Dpto," es: ",Capi),
_=readChar(),
!.
run():-
write("Lo siento no conozco la capital para el Departamento ingresado..."),
_=readChar().
end implement main
goal
console::runUtf8(main::run).
Ejercicio 05: Desarrollar una aplicación que muestre la capital de un Departamento el que será
ingresada por teclado, y en el caso que no se conozca la capital, se debe enviar un mensaje al usuario
conteniendo el nombre del Departamento.
Solución:
implement main
open core,console
class predicates
busca_capital : (string).
class facts
capital : (string,string).
clauses
capital("La Libertad","Trujillo").
capital("Lambayeque","Chiclayo").
capital("Lima","Lima").
capital("Piura","Piura").
run() :-
write("A continuación mostraré cuál es la capital de un Departamento, ingrese el nombre del Departamento:"),
Dpto=readLine(),
busca_capital(Dpto).
busca_capital(Dpto):-
capital(Dpto,Capi),
write("La capital de ",Dpto," es: ",Capi),
_=readChar(),
!.
busca_capital(Dpto):-
write("Lo siento no conozco la capital para el Departamento ",Dpto),
_=readChar().
end implement main
goal
console::runUtf8(main::run).
El predicado “fail” conocido como el predicado opuesto al predicado corte “!”, fuerza a que Visual
Prolog ejecute el backtracking, es decir, hace que Visual Prolog ejecute todas las
implementaciones de una regla de conocimiento. A continuación se muestra un ejemplo en el
ejercicio 06.
Ejercicio 06: Desarrollar una aplicación que muestre las capitales de un número determinado de
países, mostrando un mensaje de culminación cuando ya no encuentre más países en la Base de
Conocimiento.
Solución:
implement main
open core,console
class facts
capital : (string,string).
clauses
capital("Perú","Lima").
capital("Chile","Santiago de Chile").
capital("Bolivia","La Paz").
capital("Ecuador","Quito").
run() :-
write("A continuación mostraré las capitales de los países registrados en la Base de Conocimiento"),
nl,
capital(P,C),
write("La capital de ",P," es ",C),
nl,
fail.
run():-
write("Es todo lo que tengo registrado en la Base de Conocimiento"),
_=readChar().
end implement main
goal
console::runUtf8(main::run).
El predicado “nondeterm” modifica la naturaleza determinística que por defecto posee una regla
de conocimiento, es decir, cuando se declara una regla de conocimiento, siempre Visual Prolog,
Tenorio Cabrera Julio Luis Página 14
Manual Visual Prolog 7.5
espera que se construya por lo menos dos implementaciones de la regla de conocimiento ya que si
una de ellas falla se ejecuta la siguiente implementación de la regla. Entonces cuando no se desea
construir otra implementación de una regla de conocimiento, se utiliza el predicado “nondeterm”
cuando se declara la regla. Esto se muestra en el siguiente ejemplo.
Ejercicio 07: Desarrollar una aplicación que muestre las capitales de un número determinado de
ciudades, mostrando un mensaje de culminación cuando ya no encuentre más ciudades en la Base
de Conocimiento.
Solución:
implement main
open core,console
class predicates
busca_capital : () nondeterm.
class facts
capital : (string,string).
clauses
capital("La Libertad","Trujillo").
capital("Lambayeque","Chiclayo").
capital("Lima","Lima").
capital("Piura","Piura").
busca_capital():-
capital(Dpto,Capi),
write("La capital de ",Dpto," es: ",Capi),
nl.
run() :-
busca_capital(),
fail.
run():-
write("Eso es todo lo que tengo en la Base de Conocimiento"),
_=readChar().
end implement main
goal
console::runUtf8(main::run).
Ejercicio 08: Desarrollar una aplicación que muestre los lugares que le agrada visitar a un esposo
siempre y cuando estos lugares sean del agrado de su esposa.
Solución:
implement main
open core,console
class predicates
le_gusta_al_esposo : (string,string) nondeterm anyflow.
class facts
le_gusta_a_la_esposa : (string,string).
clauses
le_gusta_a_la_esposa("Lucy","Cine").
le_gusta_a_la_esposa("Lucy","Discoteca").
le_gusta_a_la_esposa("Isabel","Playas").
le_gusta_al_esposo(Esposo,Lugar):-
le_gusta_a_la_esposa(Esposa,Lugar),
nl.
run() :-
le_gusta_al_esposo("Luis",Lugar),
write("A Luis le gusta ",Lugar),
fail.
run():-
nl,
write("Eso es todo lo que le gusta al esposo"),
_=readChar().
end implement main
goal
console::runUtf8(main::run).
Con respecto al ejercicio 08, debe aclararse que el predicado “anyflow” debe utilizarse con mucho
cuidado, claro esto depende de las condiciones del problema, ya que podría mostrar en los resultados
alguna “incoherencia” como la mostrada en el ejercicio en mención.
Uno de los tipos de datos que ofrece Visual Prolog, es “string_list”, el cual se caracteriza por
permitir el manejo de los clásicos arreglos, en este caso de caracteres. A continuación el siguiente
Ejercicio 09 muestra la aplicación de este tipo de dato.
Ejercicio 09:
implement main
open core,console
class facts
soyunstringlist : (string_list).
clauses
soyunstringlist(["algo01","algo02"]).
soyunstringlist(["algo03"]).
run() :-
soyunstringlist(TipoString),
write(TipoString),
nl,
fail.
run():-
_=readChar().
end implement main
goal
console::runUtf8(main::run).
Así también Visual Prolog, ofrece otro tipo de datos que es “unsigned”, el cual se caracteriza por
solamente permitir datos de tipo entero positivo (incluyendo el cero). A continuación el Ejercicio
10 muestra la aplicación de este tipo de dato.
Ejercicio 10:
implement main
open core,console
class facts
soyununsigned : (unsigned).
clauses
soyununsigned(1).
soyununsigned(0).
run() :-
soyununsigned(TipoUnsigned),
write(TipoUnsigned),
nl,
fail.
run():-
_=readChar().
end implement main
goal
console::runUtf8(main::run).
Así también se puede utilizar otro tipo de dato que ofrece Visual Prolog, como es “unsigned_list”,
el cual se usa igual que “string_list”, pero con números enteros positivos incluyendo el cero.
Por otro lado Visual Prolog ofrece los otros tipos de datos clásicos que otros lenguajes ofrecen como
integer, real, char, etc., para cada uno de los cuales permite implementar también listas, es decir
por ejemplo: integer_list, real_list, char_list, etc.
Visual Prolog ofrece la conversión de tipos de datos entre sí, por ejemplo para convertir el proceso
de convertir el string “20” a número se observa el Ejercicio 11 y para convertir de número a string
se observa el Ejercicio 12.
Ejercicio 11:
implement main
open core,console
clauses
run() :-
ValorString="20",
ValorNumero= toTerm(ValorString) + 0,
write("En número es:", ValorNumero),
fail.
run():-
_=readChar().
end implement main
goal
console::runUtf8(main::run).
Ejercicio 12:
implement main
open core,console
clauses
run() :-
ValorNumero=20,
ValorString= toString(ValorNumero),
write("En String es:", ValorString),
fail.
run():-
_=readChar().
end implement main
goal
console::runUtf8(main::run).
Visual Prolog, ofrece también predicados para el manejo de cadenas, tal como lo muestra el
Ejercicio 13.
Ejercicio 13:
implement main
open core,console
clauses
run() :-
Cadena="Luis Tenorio",
PartedeCadena= string::subChar(Cadena,5),
write("El caracter estraído es:", PartedeCadena),
fail.
run():-
_=readChar().
end implement main
goal
console::runUtf8(main::run).
Visual Prolog, dentro de la estructura de un programa permite el uso de la sección: domains, esta
sección permite declarar los tipos de argumentos que se utilizarán en un hecho o regla de
conocimiento. El Ejercicio 14 muestra el uso de domains.
Ejercicio 14:
implement main
open core,console
domains
nombre = string.
class facts
persona : (nombre).
clauses
persona("Luis").
persona("Isabel").
run() :-
persona(Nombre),
write("Personas registrada:", Nombre),
nl,
fail.
run():-
_=readChar().
end implement main
goal
console::runUtf8(main::run).
Un objeto dominio, puede ser declarado para que asuma más de un valor en momentos distintos. El
Ejercicio 15 muestra lo mencionado:
Ejercicio 15:
implement main
open core,console
domains
cargo = operativo;administrativo;gerencial.
class facts
labora : (string,cargo).
clauses
labora("Jorge",operativo).
labora("Manuel",administrativo).
labora("Carla",gerencial).
run() :-
labora(Colaborador,Cargo),
write(Colaborador," ocupa un cargo ",Cargo),
nl,
fail.
run():-
_=readChar().
end implement main
goal
console::runUtf8(main::run).
En Visual Prolog, es posible asignar varios tipos de dominios a un argumento de un predicado. Esto
se observa en el Ejercicio 16.
Ejercicio 16:
implement main
open core,console
domains
datos = nombre(string) ; apellidos(string) ; edad(integer).
class facts
persona : (datos).
clauses
persona(nombre("Luis")).
persona(apellidos("Tenorio")).
persona(edad(83)).
run() :-
persona(nombre(N)),
persona(apellidos(A)),
persona(edad(E)),
write("Los datos son:"),
nl,
write("Nombre: ",N),
nl,
write("Apelliidos: ",A),
nl,
write("Edad: ",E),
nl,
fail.
run():-
write("Es todo lo que puedo mostrar..."),
_=readChar().
end implement main
goal
console::runUtf8(main::run).
En Visual Prolog, es posible asignar a un predicado varios tipos de dominio asignado a un solo
objeto de tipo dominio. Esto se observa en el Ejercicio 17.
Ejercicio 17:
implement main
open core,console
domains
datos = nombre(string) ; apellidos(string) ; edad(integer).
class facts
persona : (datos,datos,datos).
clauses
persona(nombre("Luis"),nombre("Rafael"),nombre("Alfredo")).
persona(apellidos("Tenorio"),apellidos("Lozada"),apellidos("Cabrera")).
persona(edad(83),edad(90),edad(45)).
run() :-
persona(nombre(N),nombre(M),nombre(O)),
persona(apellidos(A),apellidos(B),apellidos(C)),
persona(edad(E),edad(F),edad(G)),
write("Los NOMBRES son:",N," ",M," ",O),nl,
write("Los APELIDOS son:",A," ",B," ",C),nl,
write("Las EDADES son:",E," ",F," ",G),nl,
fail.
run():-
write("Es todo lo que puedo mostrar..."),
_=readChar().
end implement main
goal
console::runUtf8(main::run).
Como se había referenciado en el Ejercicio 11, Visual Prolog ofrece la conversión de tipos de datos
entre sí, por ejemplo para convertir el proceso de convertir el string “20” a número entero se observa
el Ejercicio 18. Debe hacerse mención que en esta oportunidad se utilizará otro predicado llamado
“hasDomain”, el que permitirá hacer la conversión mencionada anteriormente.
Ejercicio 18:
implement main
open core,console
clauses
run() :-
ValorString="20",
hasDomain(integer,ValorNumero),
ValorNumero= toTerm(ValorString),
write("En número original ",ValorNumero," incrementado en 40 es: ", ValorNumero+40),
fail.
run():-
_=readChar().
end implement main
goal
console::runUtf8(main::run).
Otro uso del predicado “hasDomain” es cuando se desea leer un dato por teclado tal como lo
muestra el Ejercicio 19.
Ejercicio 19:
implement main
open core,console
clauses
run() :-
hasDomain(real,ValorNumero),
write("Ingrese un valor:"),
ValorNumero= read(),
write("En número original ",ValorNumero," incrementado en 40.5 es: ", ValorNumero+40.5),
_=readChar(),
fail.
run():-
_=readChar().
end implement main
goal
console::runUtf8(main::run).
Visual Prolog ofrece un predicado llamado readString, el que permite leer un número limitado y
obligatorio de caracteres por teclado, por ejemplo, si se quiere ingresar obligatoriamente una
cantidad de 8 caracteres, se escribiría readString(8), por lo que en el caso de ingresar una cantidad
menor que la dimension indicada por mas que se presione la tecla enter, la aplicación esperará a
que se complete la cantidad de caracteres indicados en readString, y en el caso de ingresar una
cantidad mayor de caracteres, el siguiente caracter que esté fuera de la dimension será tomado como
el haber presionado la tecla enter. Esto se muestra por ejemplo en el Ejercicio 20. Es necesario el
uso del predicado stdio.
Ejercicio 20:
implement main
open core,console
clauses
run() :-
write("Ingrese una cadena no mayor de 8 caracteres :"),
Cadena= stdio::readString(8),
write("La cadena finalmente quedó así ",Cadena),
_=readChar(),
fail.
run():-
_=readChar().
end implement main
goal
console::runUtf8(main::run).
En Visual Prolog, las condicionales también están presentes, como el caso de if – then – end if, el
cuál se comporta de la misma manera que en los demás lenguajes de programación. Una aplicación
de la condicional if – then – end if, se muestra en el Ejercicio 21.
Ejercicio 21:
implement main
open core,console
class predicates
evalua : () nondeterm anyflow.
clauses
evalua():-
write("Ingrese un número menor a 20:"),
hasDomain(integer,Numero),
Numero=read(),
if(Numero<20) then
write("Correcto")
end if.
run() :-
evalua(),
_=readChar(),
fail.
run():-
_=readChar().
end implement main
goal
console::runUtf8(main::run).
Otra condicional también presente en Visual Prolog es: if – then – else - end if, la que también se
comporta como en los otros lenguajes de programación. Una aplicación de esta condicional se
muestra en el Ejercicio 22.
Ejercicio 22:
implement main
open core,console
class predicates
evalua : () nondeterm anyflow.
clauses
evalua():-
write("Ingrese un número menor a 20:"),
hasDomain(integer,Numero),
Numero=read(),
if(Numero<20) then
write("Correcto")
else
write("Incorrecto")
end if.
run() :-
evalua(),
_=readChar(),
fail.
run():-
_=readChar().
end implement main
goal
console::runUtf8(main::run).
Otra condicional también presente en Visual Prolog es: if – then – elseif – then - else - end if, la
que también se comporta como en los otros lenguajes de programación. Una aplicación de esta
condicional se muestra en el Ejercicio 23.
Ejercicio 23:
implement main
open core,console
class predicates
evalua : () nondeterm anyflow.
clauses
evalua():-
write("Ingrese un número menor a 20:"),
hasDomain(integer,Numero),
Numero=read(),
if(Numero<20) then
write("Correcto")
elseif (Numero=20) then
write("Casi Correcto porque es igual a 20")
else
write("Incorrecto porque es mayor a 20")
end if.
run() :-
evalua(),
_=readChar(),
fail.
run():-
_=readChar().
end implement main
goal
console::runUtf8(main::run).
En Visual Prolog se usa también el predicado repeat, el que permite repetir la ejecución de una
determinada parte de una aplicación mientras se cumpla una condición, y para indicar el final de la
parte del código que se repetirá se utiliza el predicado corte (!). En el Ejercicio 24 se observa la
aplicación de este predicado, pero debe incluirse la librería std.
Ejercicio 24:
implement main
open core,console,std
class predicates
bucle: () nondeterm.
clauses
bucle():-
write("Esta parte está fuera de lo que se va a repetir..."),
nl,
repeat,
write("Esta parte ya está dentro de lo que se va a repetir..."),
nl,
write("Si desea detener la repetición escriba la letra s..."),
Para=readLine(),
Para="s",
!,
write("Esta parte ya está fuera de lo que se va a repetir...").
run() :-
bucle(),
fail.
run():-
_=readChar().
end implement main
goal
console::runUtf8(main::run).
El predicado procedure, se utiliza en Visual Prolog cuando una regla de conocimiento se quiere
tartar como un procedimiento por lo que no será necesario definer otra alternative de código para la
regla de conocimiento, es decir se trata como si le regla de conocimiento fuese nondeterm. En el
Ejercicio 25 se observa la aplicación del predicado procedure.
Ejercicio 25:
implement main
open core,console
class predicates
procedimiento : (integer) procedure.
clauses
procedimiento(Numero):-
write("El número ingresado fué ",Numero),
nl.
run() :-
nl,
hasDomain(integer,Numero),
write("Ingrese un número:"),
Numero=read(),
procedimiento(Numero),
_=readChar(),
fail.
run():-
_=readChar().
end implement main
goal
console::runUtf8(main::run).
El predicado multi, se utiliza cuando se quiere definer a una regla de conocimiento para que acepte
varias implementaciones de ella pero como si el predicado fuese determinístico, es decir el final de
cada implementación de la regla de conocimiento de tipo multi no se necesita poner el predicado
corte (!) . El Ejercicio 26 muestra la aplicación del predicado multi.
Ejercicio 26:
implement main
open core,console
class predicates
procedimiento : (integer) multi.
clauses
procedimiento(Numero):-
Numero<0,
write("El número ingresado fué ",Numero," y es menor que cero..."),
nl.
procedimiento(Numero):-
Numero>0,
write("El número ingresado fué ",Numero," y es mayor que cero..."),
nl.
procedimiento(Numero):-
write("El número ingresado fué ",Numero),
nl.
run() :-
nl,
hasDomain(integer,Numero),
write("Ingrese un número:"),
Numero=read(),
procedimiento(Numero),
_=readChar(),
fail.
run().
end implement main
goal
console::runUtf8(main::run).
El predicado determ, permite declarar una regla de conocimiento la que solo deberá implementarse
una sola vez, esto siempre y cuando la regla de conocimiento que la contiene (es decir a la regla del
tipo determ) contenga el predicado fail lo que, por ejemplo para la regla run() del Ejercicio 27
ejecute automáticamente el backtracking. Esto se observa en el Ejercicio 27.
Ejercicio 27:
implement main
open core,console
class predicates
procedimiento : (integer) determ.
clauses
procedimiento(Numero):-
Numero<0,
write("El número ingresado fué ",Numero," y es menor que cero..."),
_=readChar(),
nl.
run() :-
nl,
hasDomain(integer,Numero),
write("Ingrese un número:"),
Numero=read(),
procedimiento(Numero),
_=readChar(),
fail.
run().
Otro uso del predicado nondeterm es para cuando se define mas de una implementacón para una
regla de conocimiento y se puede presentar la situacíón de no encontrar solución en las
implementaciones de la regla cuando se llama a dicha regla de conocimiento, con lo que no se
generará error. El Ejercicio 28 muestra la aplicación del predicado nondeterm que no generará error
al momento del proceso de ejecución si se ingresa el número cero (0) a pesar que no se ha
comtemplado una implementación para tal situación en la regla de conocimiento procedimiento,
esto gracias a que el predicado en mención es del tipo nondeterm.
Ejercicio 28:
implement main
open core,console
class predicates
procedimiento : (integer) nondeterm.
clauses
procedimiento(Numero):-
Numero<0,
write("El número ingresado fué ",Numero," y es menor que cero..."),
_=readChar(),
nl.
procedimiento(Numero):-
Numero>0,
write("El número ingresado fué ",Numero," y es mayor que cero..."),
_=readChar(),
nl.
run() :-
nl,
hasDomain(integer,Numero),
write("Ingrese un número:"),
Numero=read(),
procedimiento(Numero),
_=readChar(),
fail.
run():-
_=readLine().
end implement main
goal
console::runUtf8(main::run).
MODO GUI
El otro modo para el desarrollo de aplicaciones en Visual Prolog, es el modo GUI, es decir
modalidad de interfaz gráfica. Para esto cuando se crea un nuevo proyecto ya no se elige Console
como el tipo de proyecto (Project Kind), ahora se elige MDI (Multi Document Interface), como
pimer paso para la creación de un proyecto tip GUI.
Luego de escribir los datos necesarios, como por ejemplo, el nombre del proyecto, en este caso el
Ejercicio 39 (Figura 05) el cuál se llamará “Hola Mundo GUI”, Visual Prolog compilará
automáticamente el proyecto, y luego de ejecutar el mismo, se mostrará una pantalla inicial tal
como se muestra a continuación:
Figura 06: Pantalla inicial de ejecución del Proyecto Hola Mundo GUI.
Luego, al abrir el archivo main.pro, se observa el código que crea la interfaz mostrada en la Figura
05, tal como se muestra a continuación:
implement main
open core
clauses
run() :-
TaskWindow = taskWindow::new(),
TaskWindow:show().
end implement main
goal
mainExe::run(main::run).
Para poder personalizar el menú de opciones que por defecto considera Visual Prolog en la
aplicación creada, hacemos doble click sobre el archive TaskMenu.mnu (también ubicado en la
carpeta TaskWindow), con lo que se mostrará la siguiente interfaz (Figura 07):
Luego, al abrir, en la interfaz mostrada en la Figura 07, la opción “&File” se observan un conjunto
de opciones, que por el momento nos centraremos en la subopción “&New\tF7” la cuál se habilitará
quitando el “check” de la opción “Disabled”, para finalmente grabar los cambios y cerrar la interfaz
de “TaskMenu.mnu”.
Ahora, se hace doble click, en el archivo “TaskMenu.win” para poder empezar a crear el código
asociado a la opción “&New\tF7”, tal como se muestra en la figura 08:
Luego, se hace doble click sobre “id_file_new”, con lo que se abrirá el archivo
“TaskWindow.pro” en donde se escribirá el código para mostrar el mensaje “Hola Mundo”, esto
se muestra a continuación (no olvidar incluir la librería stdio, al final de open core, vpiDomains, stdio):
predicates
onFileNew : window::menuItemListener.
clauses
onFileNew(_Source, _MenuTag):-
write("Hola Mundo !!!").
Luego hacer click en el botón New Project con lo que aparecerá una interfaz, en la que en la casilla
Project Name, se escribirá Turismo Nacional y en la casilla Project Kind se elegirá la opción
MDI, quedando la interfaz tal como se muestra a continuación:
Luego se hará click en el botón Finish con lo que Visual Prolog, ejecutará automáticamente el
proceso de compilación y linkeado para que finalmente se muestre la siguiente interfaz:
Luego, cerrando la interfaz mostrada, procederemos a hacer los primeros cambios para personalizar
nuestra aplicación. En primer lugar dentro de la carpeta TaskWindow encontraremos el archivo
TaskWindow.win en el cuál al hacer click con el botón derecho del mouse y elegir la opción
Attributes, se mostrará una interfaz en la que haremos los cambios que se muestran a continuación:
Ahora, hacemos doble click en el archivo TaskMenu.mnu para modificar las opciones de nuestro
menú principal en el que solo debe quedar las opciones: Consultar y Salir. Esto se hace a través de
la interfaz mostrada a continuación:
Eliminamos a continuación todas las opciones y subopciones del menú mostrado quedando
solamente &File y &Edit las cuáles renombraremos con las opciones indicadas en el punto 7,
quedando nuestra interfaz así:
Ahora una vez que cerramos la ventana mostrada anteriormente, abrimos la carpeta Toolbars
hacemos doble click en el archivo ProjectToolbar.pro en el que haremos los cambios que
mostramos a continuación:
Es necesario indicar que si apareciesen alertas antes de mostrarse la interfaz anterior, se debe
eliminar el código respectivo en el archivo TaskWindow.pro
Ahora programaremos la opción Salir y el botón de opción Salir, para esto hacemos doble en el
archivo TaskWindow.win con lo que aparecerá la siguiente interfaz:
Luego se escribirá el código mostrado en la siguiente imagen, tanto en id_edit (de TaskMenu) y
en id_edit_cut (de Project Toolbar), tal como se muestra a continuación:
Luego al cerrar la interfaz y ejecutar la aplicación, la opción y el botón Salir preguntarán primer si
estamos seguro de salir o no del programa.
Ahora procederemos a crear el formulario llamado frmconsultar, en donde se harán las consultas
a la aplicación. Este formulario deberá ser llamado por la opción Consultar del menú principal y
por el botón de opción Consultar. Para esto hacemos click con el botón derecho del mouse sobre
la carpeta Turismo Nacional y elegimos la opción New In New Package con lo que aparecerá la
siguiente interfaz:
Elegimos ahora el objeto Form y en la casilla Name escribimos: frmconsultar y luego hacemos
click en el botón Create con lo que aparecerá la siguiente interfaz:
Ahora para poder llamar al formulario creado tanto mediante la opción del menú así como mediante
el botón respectivo, hacemos doble click en el archivo TaskWindow.win y tanto para la opción
id_file (de TaskMenu) y en id_file_new (de Project Toolbar), se escribirá el código que se
muestra a continuación:
facts
requisitos : (string,string,string).
rutas : (string,string_list).
clauses
requisitos("CALIDO","PLAYAS","1").
requisitos("TEMPLADO","MUSEOS","2").
requisitos("FRIO","RUINAS","3").
rutas("1",["TRUJILLO","LIMA","AREQUIPA"]).
rutas("2",["TRUJILLO","LIMA","TACNA","PUNO"]).
rutas("3",["TRUJILLO","HUANUCO","CUZCO","HUANCAYO","AREQUIPA","TACNA"]).
predicates
onBtnconsultarClick : button::clickResponder.
clauses
onBtnconsultarClick(_Source) = button::defaultAction:-
lbrutas_ctl:clearAll(),
lbclimas_ctl:getAllSelected(Climas,_),
[Clima|_]=Climas,
lblugares_ctl:getAllSelected(Lugares,_),
[Lugar|_]=Lugares,
requisitos(Clima,Lugar,Codigo),
rutas(Codigo,Ruta),
imprime_ruta(Ruta),
!.
onBtnconsultarClick(_Source) = button::defaultAction:-
vpiCommonDialogs::error("Mensaje del Sistema","No hay resultados para su consulta...").
predicates
imprime_ruta : (string_list).
clauses
imprime_ruta([H|C]):-
lbrutas_ctl:add(H),
imprime_ruta(C).
imprime_ruta([]).
predicates
onShow : window::showListener.
clauses
onShow(_Source, _Data):-
lbclimas_ctl:add("CALIDO"),
lbclimas_ctl:add("TEMPLADO"),
lbclimas_ctl:add("FRIO"),
lblugares_ctl:add("PLAYAS"),
lblugares_ctl:add("MUSEOS"),
lblugares_ctl:add("RUINAS").
predicates
onLbrutasDoubleClick : listBox::doubleClickListener.
clauses
onLbrutasDoubleClick(_Source):-
lbrutas_ctl:getAllSelected(Ruta,_),
[Ciudad|_]=Ruta,
datos(Ciudad,Informacion),
vpiCommonDialogs::note("Información de Ciudad Seleccionada",Informacion),
fail.
onLbrutasDoubleClick(_Source).
facts
datos : (string,string).
clauses
datos("TRUJILLO","LLAMADA CIUDAD DE LA PRIMAVERA, UBICADA AL NORTE DEL PERÚ").
datos("LIMA","LLAMADA CIUDAD DE LOS REYES, UBICADA AL CENTRO DEL PERÚ Y ES LA CAPITAL DE NUESTRO PAÍ
S").
datos("AREQUIPA","LLAMADA CIUDAD BLANCA, UBICADA AL SUR DEL PERÚ").
datos("TACNA","LLAMADA CIUDAD HEROICA, UBICADA AL SUR DEL PERÚ").
datos("PUNO","LLAMADA CIUDAD FRIA, UBICADA AL OESTE DEL PERÚ").
datos("HUANUCO","LLAMADA CIUDAD DEL EXCELENTE CLIMA, UBICADA AL CENTRO DEL PERÚ").
datos("CUZCO","LLAMADA CIUDAD OMBLIGO DEL MUNDO, UBICADA AL CENTRO DEL PERÚ").
datos("HUANCAYO","LLAMADA CIUDAD FRIOLENTA, UBICADA AL CENTRO DEL PERÚ").
Finalmente al grabar los cambios y ejecutar la aplicación, se deberá mostrar los resultados
esperados, tal como se muestra a continuación:
En el caso que no exista respuesta para los requerimientos seleccionados o no se haya hecho bien la
selección de requisitos, se mostrará un mensaje de error como se vé en la siguiente interfaz:
podemos modificar los atributos de la ventana raíz, es decir, TaskWindow, por ejemplo el nuevo
título de la ventana será “SISTEMA EXPERTO MEDICO EN NEUMOLOGÍA” y se activa la
opción Maximized y luego seleccionar el botón Ok. Si se ejecuta nuevamente la aplicación se verán
los cambios tal como se muestra a continuación.
Es de interés ahora el archivo TaskMenu.mnu, mediante el cual se puede modificar las opciones
que por defecto implementa Visual Prolog. Entonces primero se hace doble click sobre el archivo
TaskMenu.mnu y luego se eliminará todas las opciones menos File y dentro de esta opción se
eliminará todas las subopciones menos New y Exit. Luego el archivo TaskMenu.mnu debe quedar
así:
Las opciones no eliminadas se renombrarán de la siguiente manera: File = Consulta, New = Nueva,
Exit = Salir. La opción Nueva deben de habilitarse ya que por defecto está deshabilitada (quitar el
check en la opción Disabled), entonces el archivo TaskMenu.mnu debe quedar así:
En este punto se debe ejecutar nuevamente la aplicación mediante la opción Build y luego Build
con lo que se observa la advertencia que no es usado el predicado onHelpAbout. Esto significa
que hay un código asociado a las opciones eliminadas que está demás en el archivo
TaskWindow.pro, de donde debemos eliminar a dicho código. Para ir al archivo
TaskWindow.pro, se hace doble click en el mensaje de advertencia.
class predicates
onHelpAbout : window::menuItemListener.
clauses
onHelpAbout(TaskWin, _MenuTag):-
_AboutDialog = aboutDialog::display(TaskWin).
Luego en el mismo archivo, se debe modificar en el siguiente código, el valor true por false, para
así eliminar la opción Window la que no se elimina en modo diseño. El código a modificar es:
constants
mdiProperty : boolean = true.
constants
mdiProperty : boolean = false.
predicates
onShow : window::showListener.
clauses
onShow(_, _CreationData):-
_MessageForm = messageForm::display(This).
de la siguiente manera:
predicates
onShow : window::showListener.
clauses
onShow(_, _CreationData).
%_MessageForm = messageForm::display(This).
En este punto del desarrollo de la aplicación, se trabajará formateando las opciones de la barra
(menú) de herramientas (Toolbar), para lo cual se abre haciendo doble click, el archivo
ProjectToolbar.pro (se encuentra ubicado en la carpeta Toolbars del proyecto), y el código que
deberá quedar por el momento, se muestra a continuación:
implement projectToolbar
open core, vpiDomains, vpiToolbar, resourceIdentifiers
clauses
create(Parent) :-
StatusBar = statusBar::newApplicationWindow(),
StatusCell = statusBarCell::new(StatusBar, 0),
StatusBar:cells := [StatusCell],
Toolbar = vpiToolbar::create(style, Parent, controlList),
setStatusHandler(Toolbar, {(Text) :- StatusCell:text := Text}).
% This code is maintained automatically, do not update it manually. 16:42:04-24.4.2013
constants
style : vpiToolbar::style = tb_top().
controlList : vpiToolbar::control_list =
[
tb_ctrl(id_file_new,pushb(),resId(idb_NewFileBitmap),"Nueva consulta;",1,1),
vpiToolbar::separator,
tb_ctrl(id_edit_cut,pushb(),resId(idb_CutBitmap),"Salir;",1,1)
].
% end of automatic code
end implement projectToolbar
La intención del código anterior es que el usuario pueda accesar a una nueva consulta y salir de la
aplicación también de los botones mostrados en la barra de herramientas del proyecto, es decir,
ProjectToolbar, por lo que luego de grabar los cambios y cerrar las ventanas necesarias, al ejecutar
la aplicación se debe observar la siguiente interfaz:
Ahora, para terminar con el formateo del proyecto en función del botón opción Salir del
ProjectToolbar, se va a escribir el código que permitirá que cuando se seleccione el botón opción
en mención, se pueda salir de la aplicación. Para esto nos hacemos doble click sobre el archivo
TaskWindow.win, luego abrimos la carpeta Menu, luego abrimos la carpeta ProjectToolbar y
finalmente hacemos doble click sobre id_edit_cut, con lo que aparecerá un código del cual solo nos
interesa el que se muestra a continuación, ya que luego se modificará:
predicates
onEditCut : window::menuItemListener.
clauses
onEditCut(_Source, _MenuTag).
predicates
onEditCut : window::menuItemListener.
clauses
onEditCut(_Source, _MenuTag):-
close().
Al ejecutar la aplicación, sea al seleccionar la opción Salir tanto del menú principal o el botón
opción Salir del ProjectToolbar, se debe terminar la ejecución de la aplicación. Ahora para
finalizar, como ya se mencionó anteriormente, el formateo del proyecto en función de las opciones
que presentará al usuario, debemos eliminar: la caja de cerrar, la caja de maximizar y la caja de
minimizar la interfaz, para lo cual, hacemos click con el botón derecho sobre el archivo
TaskWindow.win y luego seleccionamos la opción Attributes con lo que en la interfaz que aparece
desactivamos las casillas: CloseBox, MaximizeBox y MinimizeBox respectivamente.
El paso siguiente es enviar al usuario un mensaje que explique la finalidad de la aplicación, pero
este mensaje debe aparecer automáticamente luego que se muestra la interfaz del punto anterior.
Para esto haciendo click con el botón derecho sobre la carpeta SISTEMA EXPERTO MÉDICO
EN NEUROLOGÍA, seleccione la opción New in New Package y luego elija el objeto Dialog
para luego escribir como nombre del Dialog: dlgmensaje y luego hacer click en el botón Create.
El proceso gráficamente se muestra a continuación:
Debe eliminar todos los botones que aparecen menos Ok, el cual se renombrará con: Continuar y
luego elija el objeto Static Text y en la propiedad Text escriba un mensaje explicando al usuario la
finalidad del sistema experto. Finalmente cierra el diálogo creado y lo graba.
Como se dijo anteriormente el mensaje creado en el punto anterior debe aparecer automáticamente,
por lo que para esto hacemos doble click en TaskWindow.win, con lo que en la carpeta Window
hacemos doble click en el evento OnShow y modificamos el siguiente código:
predicates
onShow : window::showListener.
clauses
onShow(_, _CreationData).
%_MessageForm = messageForm::display(This).
predicates
onShow : window::showListener.
clauses
onShow(_, _CreationData):-
% _MessageForm = messageForm::display(This).
postAction({ :- _ = dlgmensaje::display(This) }).
Al ejecutar la aplicación, de aparecer algún mensaje de agregar las librerías necesarias, se hace click
en el botón Add All para que finalmente aparezca automáticamente el mensaje creado.
A continuación se deberá crear un diálogo dlgnombre (la propiedad Text de este objeto deberá
contener “Solicitud de nombre al usuario”), con el mismo procedimiento para crear dlgmensaje,
el cual deberá quedar sin ningún botón de ventana que trae por defecto el diálogo dlgnombre. Luego
se debe colocar un botón de comando denominado Continuar cuyo nombre será btncontinuar_ctl.
El objetivo de dlgnombre es que el usuario ingrese su nombre en una caja de texto y mientras no
lo haga no se podrá continuar. Entonces se debe considerar un objeto tipo Static Text para el
mensaje de: “Ingrese su nombre por favor”. Debe haber también un Edit Control para ingresar
el nombre del usuario, el Edit Control, se llamará ednombre_ctl.
Ahora se debe crear un diálogo llamado dlgbienvenida, mediante el mismo procedimiento que para
crear los diálogos anteriores (recordar haciendo click con el botón derecho sobre la carpeta
MEDICO, seleccione la opción New in New Package). En este diálogo debe mostrarse un mensaje
de bienvenida al uso del sistema al usuario. Se debe tener en cuenta que en este diálogo debe
capturarse el nombre del usuario ingresado en el diálogo anterior dlgnombre.
Entonces ahora escribir el siguiente código al programar el botón de comando: btncontinuar_ctl,
en el dlgnombre.pro:
predicates
onBtningresarClick : button::clickResponder.
clauses
onBtningresarClick(_Source) = button::defaultAction:-
Contenido=ednombre_ctl:getText(),
Contenido<>"",
close(),
_ = dlgbienvenida::display(getParent(), ednombre_ctl:getText()),
!.
onBtningresarClick(_Source) = button::defaultAction:-
vpiCommonDialogs::error("Mensaje del Sistema","Ingrese su nombre").
En este punto se deberá mediante las opciones Consulta y luego Nueva, llamar al diálogo
dlgnombre y para esto, se hace doble click en el archivo TaskWindow.win de la carpeta
TaskWindow, para luego de la interfaz que aparece seleccionar la carpeta Menu, TaskMenu,
id_file y luego hacer doble click sobre id_file_new con lo que se deberá completar el código que
aparece por defecto, con el siguiente:
predicates
onFileNew : window::menuItemListener.
clauses
onFileNew(_Source, _MenuTag):-
_ = dlgnombre::display(This).
Luego al ejecutar la aplicación, de aparecer algún mensaje de agregar las librerías necesarias, se
hace click en el botón Add All con lo que debería ejecutarse sin ningún problema hasta el punto
desarrollado.
Al ingresar el nombre de usuario, se debe displayar un diálogo llamado dlgbienvenida, en donde
aparezca un mensaje de bienvenida con el nombre de usuario ingresado. En el archivo
dlgbienvenida.cl, debe el código quedar así:
/*************************************************************************
****
**************************************************************************
****/
class dlgbienvenida : dlgbienvenida
open core
predicates
display : (window Parent, string Name) -> dlgbienvenida Dlgbienvenida.
constructors
new : (window Parent, string Name).
En el diálogo dlgbienvenida, se coloca un StaticText_ctl, el que debe ser del tipo Fact Variable,
con lo que ahora se llamará: staticText_ctl, quedando la propiedad Text en blanco. Finalmente
debe quedar solo el botón ok_ctl, el cual se renombrará con la propiedad text, con el nombre
Continuar.
clauses
display(Parent,Name) = Dialog :-
Dialog = new(Parent,Name),
Dialog:show().
facts
name : string.
clauses
new(Parent,Name) :-
name := Name,
dialog::new(Parent),
generatedInitialize(),
staticText_ctl:setText(string::format("%, te doy la bienvenida,
con gusto te ayudaré. Presiona en Continuar por favor.", name)).
Ahora se debe crear un diálogo en el que se realizará las consultas al experto artificial. Este diálogo
se llama dlgconsulta al cuál en la propiedad Text se deberá escribir: “Consultando al experto”.
Finalmente a este punto, en el diálogo creado, se cambiará la apariencia del botón Ok por Salir.
En este diálogo dlgconsulta, se deberán poner los siguientes controles con sus respectivas
propiedades:
o Un Push Button, el que se denominará btndiagnosticar_ctl.
Lo que ahora se debe hacer es que cuando se llame a dlgconsulta, automáticamente los síntomas
disponibles deben aparecer en lbdisponibles_ctl. Para esto en la pestaña Events de la caja de
propiedades de dlgconsulta, se debe hacer doble click sobre el evento ShowListener, con lo que
aparecerá el siguiente código:
predicates
onShow : window::showListener.
clauses
onShow(_Source, _Data).
predicates
onShow : window::showListener.
clauses
onShow(_Source, _Data):-
lbdisponibles_ctl:add("Síntoma_01"),
lbdisponibles_ctl:add("Síntoma_02"),
lbdisponibles_ctl:add("Síntoma_03"),
lbdisponibles_ctl:add("Síntoma_04"),
lbdisponibles_ctl:add("Síntoma_05").
Ahora la idea es que cuando el usuario seleccione (con doble click), un síntoma de
lbdisponibles_ctl, este sea agregado a lbseleccionados_ctl, eliminándose automáticamente del
primer List Box y viceversa, es decir si el usuario desea eliminar un síntoma seleccionado de
lbseleccionados_ctl, pues lo debe seleccionar con doble click y automáticamente pasará
nuevamente a formar parte de lbdisponibles_ctl. Para esto en la pestaña Events de la caja de
propiedades de lbdisponibles_ctl, se hace doble click sobre el evento DoubleClickListener, con
lo que aparecerá el siguiente código:
predicates
onLbdisponiblesDoubleClick : listBox::doubleClickListener.
clauses
onLbdisponiblesDoubleClick(_Source).
predicates
onLbdisponiblesDoubleClick : listBox::doubleClickListener.
clauses
onLbdisponiblesDoubleClick(_Source):-
lbdisponibles_ctl:getAllSelected(E,I),
E=[EE|_],
I=[II|_],
lbseleccionados_ctl:add(EE),
lbdisponibles_ctl:delete(II),
!.
onLbdisponiblesDoubleClick(_Source).
predicates
onLbseleccionadosDoubleClick : listBox::doubleClickListener.
clauses
onLbseleccionadosDoubleClick(_Source).
predicates
onLbseleccionadosDoubleClick : listBox::doubleClickListener.
clauses
onLbseleccionadosDoubleClick(_Source):-
lbseleccionados_ctl:getAllSelected(E,I),
E=[EE|_],
I=[II|_],
lbdisponibles_ctl:add(EE),
lbseleccionados_ctl:delete(II),
!.
onLbseleccionadosDoubleClick(_Source).
Se debe ahora llamar desde el diálogo dlgbienvenida al diálogo dlgconsulta. Para esto, en el botón
Continuar (es el botón ok_ctl) de dlgbienvenida, poner el siguiente código:
predicates
onOkClick : button::clickResponder.
clauses
onOkClick(_Source) = button::defaultAction:-
close(),
_ = dlgconsulta::display(getParent(), name),
!.
/*************************************************************************
****
**************************************************************************
****/
class dlgconsulta : dlgconsulta
open core
predicates
display : (window Parent, string Name) -> dlgconsulta Dlgconsulta.
constructors
new : (window Parent, string Name).
end class dlgconsulta
clauses
display(Parent,Name) = Dialog :-
Dialog = new(Parent,Name),
Dialog:show().
facts
nam : string.
clauses
new(Parent,Name) :-
nam:=Name,
dialog::new(Parent),
generatedInitialize(),
staticText_ctl:setText(string::format("%, selecciona los requerimientos requeridos.", n
am)).
Finalmente se debe escribir el código para el botón btndiagnosticar_ctl, para esto se hace doble
click en el botón mencionado con lo que aparecerá el siguiente código:
predicates
onBtndiagnosticarClick : button::clickResponder.
clauses
onBtndiagnosticarClick(_Source) = button::defaultAction.
domains
sintomas = string*.
facts
diagnostico:(sintomas,string,string).
clauses
diagnostico(["Síntoma_01","Síntoma_02","Síntoma_03"],"Enfermedad_01_02_03","Trata
miento_01_02_03").
diagnostico(["Síntoma_04","Síntoma_05"],"Enfermedad_04_05","Tratamiento_04_05").
predicates
onBtndiagnosticarClick : button::clickResponder.
clauses
onBtndiagnosticarClick(_Source) = button::defaultAction:-
edenfermedad_ctl:setText(""),
edtratamiento_ctl:setText(""),
S=lbseleccionados_ctl:getAll(),
diagnostico(S,E,T),
edenfermedad_ctl:setText(E),
edtratamiento_ctl:setText(T),
!.
onBtndiagnosticarClick(_Source) = button::defaultAction:-
edenfermedad_ctl:setText(""),
edtratamiento_ctl:setText(""),
vpiCommonDialogs::error("Mensaje del Sistema","No existen respuestas para los sínto
mas seleccionados").
Figura 01: Pantalla con mensaje explicativo al usuario de la finalidad de la aplicación experta.
SITIOS WEB
Prolog Development Center (PDC). [Fecha de consulta: 15 enero 2013]. Disponible en: http://www.visual-
prolog.com/