Académique Documents
Professionnel Documents
Culture Documents
5
Julio Luis Tenorio Cabrera.
INDICE
INDICE ........................................................................................................................................................................ 1
MODO CONSOLA ...................................................................................................................................................... 2
MODO GUI ................................................................................................................................................................ 35
Pgina 1
MODO CONSOLA
Visual Prolog, es un entorno de desarrollo para Sistemas Expertos, basado en la programacin lgica
utilizando asimismo el mecanismo de razonamiento con encadenamiento hacia atrs para realizar el
proceso de razonamiento.
En Visual Prolog, no es necesario programar el proceso de razonamiento ya que, cmo se mencion
anteriormente, ya se encuentra implementado, por lo que slo se le debe de alimentar de la
experiencia, es decir del conocimiento del experto o especialista humano, para la construccin 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
continuacin:
Pgina 2
Pgina 3
Pgina 4
Pgina 5
#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 tambin al
archivo core.pro de la carpeta pfc y al archivo main.cl. Se debe hacer mencin que el archivo
core.pro, es fundamental ya que contiene todos los predicados para el funcionamiento de un
programa por ejemplo, la definicin de los tipos de datos. Esto se muestra a continuacin:
#requires @"main.pack"
% publicly used packages
#include @"pfc\core.ph"
% exported interfaces
% exported classes
#include @"main.cl"
El archivo main.cl, contiene la declaracin del predicado run, el que se va a definir en main.pro.
Esto se muestra a continuacin:
class main
open core
predicates
run : core::runnable.
end class main
El archivo main.manifest contiene el cdigo XML del proyecto tal como se muestra a
continuacin:
Pgina 6
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 cdigo
respectivo en el archivo main.pro, ya que es el archivo que contiene el cdigo fuente principal
de la aplicacin cuando se trabaja en modo consola. Entonces se hace doble click sobre el archivo
main.pro con lo que se muestra el siguiente cdigo:
Pgina 7
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 cdigo por defecto tal como se muestra a continuacin:
implement main
open core
clauses
run() :console::write("Hola Mundo..."),
_=console::readChar().
end implement main
goal
console::runUtf8(main::run).
Otra versin del programa Hola Mundo, que es la que usaremos de ahora en adelante en el
presente manual, es la que se muestra a continuacin:
implement main
open core,console
clauses
run() :write("Hola Mundo..."),
_=readChar().
end implement main
goal
console::runUtf8(main::run).
Pgina 8
existen inconvenientes, Visual Prolog enviar el mensaje: Project has been built y luego se
selecciona la subopcin Execute ubicada en la opcin del men principal: Build, con lo que
se mostrar el resultado de la ejecucin de la aplicacin Hola Mundo, tal como se muestra a
continuacin:
Figura 05: Pantalla visualizacin de resultado de la ejecucin del proyecto del ejercicio 01
Luego para terminar la ejecucin de la aplicacin se presiona la tecla Enter.
Ejercicio 02: Desarrollar una aplicacin que solicite un nombre y le enve un saludo incluido el
nombre ingresado.
Solucin:
Se muestra el cdigo de main.pro:
Pgina 9
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).
Solucin:
En la solucin del presente programa se utilizar la variable annima o blanca o no ligada, que
se representa con el guion bajo o underscore (_) el cul se utiliza para ignorar el valor que se capture
con el predicado readChar(), ya que para el caso presente no es de inters. Asimismo se utiliza el
predicado corte (!) el que evitar que el motor de inferencia de Visual Prolog ejecute la otra
implementacin del predicado run ya que ste se debera ejecutar cuando la primera
implementacin de run falle.
Se muestra el cdigo de main.pro:
Pgina 10
implement main
open core, console
class facts
capital : (string,string).
clauses
capital("La Libertad","Trujillo").
run() :write("A continuacin 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 aplicacin 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.
Solucin:
Se muestra el cdigo de main.pro:
Pgina 11
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 continuacin mostrar cul 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 aplicacin 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.
Solucin:
Se muestra el cdigo de main.pro:
Pgina 12
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 continuacin mostrar cul 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).
Pgina 13
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 continuacin se muestra un ejemplo en el
ejercicio 06.
Ejercicio 06: Desarrollar una aplicacin que muestre las capitales de un nmero determinado de
pases, mostrando un mensaje de culminacin cuando ya no encuentre ms pases en la Base de
Conocimiento.
Solucin:
Se muestra el cdigo en main.pro:
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 continuacin mostrar las capitales de los pases 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 determinstica que por defecto posee una regla
de conocimiento, es decir, cuando se declara una regla de conocimiento, siempre Visual Prolog,
Tenorio Cabrera Julio Luis
Pgina 14
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 implementacin de la regla. Entonces cuando no se desea
construir otra implementacin 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 aplicacin que muestre las capitales de un nmero determinado de
ciudades, mostrando un mensaje de culminacin cuando ya no encuentre ms ciudades en la Base
de Conocimiento.
Solucin:
Se muestra el cdigo en main.pro:
Pgina 15
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 aplicacin que muestre los lugares que le agrada visitar a un esposo
siempre y cuando estos lugares sean del agrado de su esposa.
Solucin:
Se muestra el cdigo en main.pro:
Pgina 16
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 podra mostrar en los resultados
alguna incoherencia como la mostrada en el ejercicio en mencin.
Uno de los tipos de datos que ofrece Visual Prolog, es string_list, el cual se caracteriza por
permitir el manejo de los clsicos arreglos, en este caso de caracteres. A continuacin el siguiente
Ejercicio 09 muestra la aplicacin de este tipo de dato.
Ejercicio 09:
Pgina 17
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 tambin 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 continuacin el Ejercicio
10 muestra la aplicacin 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).
Pgina 18
As tambin 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 nmeros enteros positivos incluyendo el cero.
Por otro lado Visual Prolog ofrece los otros tipos de datos clsicos que otros lenguajes ofrecen como
integer, real, char, etc., para cada uno de los cuales permite implementar tambin listas, es decir
por ejemplo: integer_list, real_list, char_list, etc.
Visual Prolog ofrece la conversin de tipos de datos entre s, por ejemplo para convertir el proceso
de convertir el string 20 a nmero se observa el Ejercicio 11 y para convertir de nmero a string
se observa el Ejercicio 12.
Ejercicio 11:
implement main
open core,console
clauses
run() :ValorString="20",
ValorNumero= toTerm(ValorString) + 0,
write("En nmero es:", ValorNumero),
fail.
run():_=readChar().
end implement main
goal
console::runUtf8(main::run).
Pgina 19
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 tambin 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 estrado 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 seccin: domains, esta
seccin permite declarar los tipos de argumentos que se utilizarn en un hecho o regla de
conocimiento. El Ejercicio 14 muestra el uso de domains.
Pgina 20
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 ms de un valor en momentos distintos. El
Ejercicio 15 muestra lo mencionado:
Pgina 21
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).
Pgina 22
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:
Pgina 23
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 haba referenciado en el Ejercicio 11, Visual Prolog ofrece la conversin de tipos de datos
entre s, por ejemplo para convertir el proceso de convertir el string 20 a nmero entero se observa
el Ejercicio 18. Debe hacerse mencin que en esta oportunidad se utilizar otro predicado llamado
hasDomain, el que permitir hacer la conversin mencionada anteriormente.
Pgina 24
Ejercicio 18:
implement main
open core,console
clauses
run() :ValorString="20",
hasDomain(integer,ValorNumero),
ValorNumero= toTerm(ValorString),
write("En nmero 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 nmero original ",ValorNumero," incrementado en 40.5 es: ", ValorNumero+40.5),
_=readChar(),
fail.
run():_=readChar().
end implement main
goal
console::runUtf8(main::run).
Pgina 25
Visual Prolog ofrece un predicado llamado readString, el que permite leer un nmero limitado y
obligatorio de caracteres por teclado, por ejemplo, si se quiere ingresar obligatoriamente una
cantidad de 8 caracteres, se escribira 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 aplicacin 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 tambin estn presentes, como el caso de if then end if, el
cul se comporta de la misma manera que en los dems lenguajes de programacin. Una aplicacin
de la condicional if then end if, se muestra en el Ejercicio 21.
Ejercicio 21:
Pgina 26
implement main
open core,console
class predicates
evalua : () nondeterm anyflow.
clauses
evalua():write("Ingrese un nmero 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 tambin presente en Visual Prolog es: if then else - end if, la que tambin se
comporta como en los otros lenguajes de programacin. Una aplicacin de esta condicional se
muestra en el Ejercicio 22.
Ejercicio 22:
Pgina 27
implement main
open core,console
class predicates
evalua : () nondeterm anyflow.
clauses
evalua():write("Ingrese un nmero 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 tambin presente en Visual Prolog es: if then elseif then - else - end if, la
que tambin se comporta como en los otros lenguajes de programacin. Una aplicacin de esta
condicional se muestra en el Ejercicio 23.
Ejercicio 23:
Pgina 28
implement main
open core,console
class predicates
evalua : () nondeterm anyflow.
clauses
evalua():write("Ingrese un nmero 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).
Pgina 29
En Visual Prolog se usa tambin el predicado repeat, el que permite repetir la ejecucin de una
determinada parte de una aplicacin mientras se cumpla una condicin, y para indicar el final de la
parte del cdigo que se repetir se utiliza el predicado corte (!). En el Ejercicio 24 se observa la
aplicacin de este predicado, pero debe incluirse la librera 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 repeticin 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 cdigo para la
regla de conocimiento, es decir se trata como si le regla de conocimiento fuese nondeterm. En el
Ejercicio 25 se observa la aplicacin del predicado procedure.
Ejercicio 25:
Pgina 30
implement main
open core,console
class predicates
procedimiento : (integer) procedure.
clauses
procedimiento(Numero):write("El nmero ingresado fu ",Numero),
nl.
run() :nl,
hasDomain(integer,Numero),
write("Ingrese un nmero:"),
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 determinstico, es decir el final de
cada implementacin de la regla de conocimiento de tipo multi no se necesita poner el predicado
corte (!) . El Ejercicio 26 muestra la aplicacin del predicado multi.
Pgina 31
Ejercicio 26:
implement main
open core,console
class predicates
procedimiento : (integer) multi.
clauses
procedimiento(Numero):Numero<0,
write("El nmero ingresado fu ",Numero," y es menor que cero..."),
nl.
procedimiento(Numero):Numero>0,
write("El nmero ingresado fu ",Numero," y es mayor que cero..."),
nl.
procedimiento(Numero):write("El nmero ingresado fu ",Numero),
nl.
run() :nl,
hasDomain(integer,Numero),
write("Ingrese un nmero:"),
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 automticamente el backtracking. Esto se observa en el Ejercicio 27.
Pgina 32
Ejercicio 27:
implement main
open core,console
class predicates
procedimiento : (integer) determ.
clauses
procedimiento(Numero):Numero<0,
write("El nmero ingresado fu ",Numero," y es menor que cero..."),
_=readChar(),
nl.
run() :nl,
hasDomain(integer,Numero),
write("Ingrese un nmero:"),
Numero=read(),
procedimiento(Numero),
_=readChar(),
fail.
run().
end implement main
goal
console::runUtf8(main::run).
Otro uso del predicado nondeterm es para cuando se define mas de una implementacn para una
regla de conocimiento y se puede presentar la situacn de no encontrar solucin 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 aplicacin del predicado nondeterm que no generar error
al momento del proceso de ejecucin si se ingresa el nmero cero (0) a pesar que no se ha
comtemplado una implementacin para tal situacin en la regla de conocimiento procedimiento,
esto gracias a que el predicado en mencin es del tipo nondeterm.
Pgina 33
Ejercicio 28:
implement main
open core,console
class predicates
procedimiento : (integer) nondeterm.
clauses
procedimiento(Numero):Numero<0,
write("El nmero ingresado fu ",Numero," y es menor que cero..."),
_=readChar(),
nl.
procedimiento(Numero):Numero>0,
write("El nmero ingresado fu ",Numero," y es mayor que cero..."),
_=readChar(),
nl.
run() :nl,
hasDomain(integer,Numero),
write("Ingrese un nmero:"),
Numero=read(),
procedimiento(Numero),
_=readChar(),
fail.
run():_=readLine().
end implement main
goal
console::runUtf8(main::run).
Pgina 34
MODO GUI
El otro modo para el desarrollo de aplicaciones en Visual Prolog, es el modo GUI, es decir
modalidad de interfaz grfica. 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 creacin 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 cul se llamar Hola Mundo GUI, Visual Prolog compilar
automticamente el proyecto, y luego de ejecutar el mismo, se mostrar una pantalla inicial tal
como se muestra a continuacin:
Figura 06: Pantalla inicial de ejecucin del Proyecto Hola Mundo GUI.
Luego, al abrir el archivo main.pro, se observa el cdigo que crea la interfaz mostrada en la Figura
05, tal como se muestra a continuacin:
Tenorio Cabrera Julio Luis
Pgina 35
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
aplicacin creada, hacemos doble click sobre el archive TaskMenu.mnu (tambin ubicado en la
carpeta TaskWindow), con lo que se mostrar la siguiente interfaz (Figura 07):
Pgina 36
Pgina 37
predicates
onFileNew : window::menuItemListener.
clauses
onFileNew(_Source, _MenuTag):write("Hola Mundo !!!").
Pgina 38
Pgina 39
Luego hacer click en el botn 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 opcin
MDI, quedando la interfaz tal como se muestra a continuacin:
Pgina 40
Luego se har click en el botn Finish con lo que Visual Prolog, ejecutar automticamente el
proceso de compilacin y linkeado para que finalmente se muestre la siguiente interfaz:
Pgina 41
Pgina 42
Luego, cerrando la interfaz mostrada, procederemos a hacer los primeros cambios para personalizar
nuestra aplicacin. En primer lugar dentro de la carpeta TaskWindow encontraremos el archivo
TaskWindow.win en el cul al hacer click con el botn derecho del mouse y elegir la opcin
Attributes, se mostrar una interfaz en la que haremos los cambios que se muestran a continuacin:
Pgina 43
Pgina 44
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 travs de
la interfaz mostrada a continuacin:
Pgina 45
Eliminamos a continuacin todas las opciones y subopciones del men mostrado quedando
solamente &File y &Edit las cules renombraremos con las opciones indicadas en el punto 7,
quedando nuestra interfaz as:
Pgina 46
Pgina 47
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 continuacin:
Pgina 48
Pgina 49
Es necesario indicar que si apareciesen alertas antes de mostrarse la interfaz anterior, se debe
eliminar el cdigo respectivo en el archivo TaskWindow.pro
Ahora programaremos la opcin Salir y el botn de opcin Salir, para esto hacemos doble en el
archivo TaskWindow.win con lo que aparecer la siguiente interfaz:
Pgina 50
Luego se escribir el cdigo mostrado en la siguiente imagen, tanto en id_edit (de TaskMenu) y
en id_edit_cut (de Project Toolbar), tal como se muestra a continuacin:
Pgina 51
Luego al cerrar la interfaz y ejecutar la aplicacin, la opcin y el botn Salir preguntarn primer si
estamos seguro de salir o no del programa.
Ahora procederemos a crear el formulario llamado frmconsultar, en donde se harn las consultas
a la aplicacin. Este formulario deber ser llamado por la opcin Consultar del men principal y
por el botn de opcin Consultar. Para esto hacemos click con el botn derecho del mouse sobre
la carpeta Turismo Nacional y elegimos la opcin New In New Package con lo que aparecer la
siguiente interfaz:
Pgina 52
Elegimos ahora el objeto Form y en la casilla Name escribimos: frmconsultar y luego hacemos
click en el botn Create con lo que aparecer la siguiente interfaz:
Pgina 53
Pgina 54
Ahora para poder llamar al formulario creado tanto mediante la opcin del men as como mediante
el botn respectivo, hacemos doble click en el archivo TaskWindow.win y tanto para la opcin
id_file (de TaskMenu) y en id_file_new (de Project Toolbar), se escribir el cdigo que se
muestra a continuacin:
Pgina 55
Pgina 56
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("Informacin de Ciudad Seleccionada",Informacion),
fail.
onLbrutasDoubleClick(_Source).
Tenorio Cabrera Julio Luis
Pgina 57
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 aplicacin, se deber mostrar los resultados
esperados, tal como se muestra a continuacin:
En el caso que no exista respuesta para los requerimientos seleccionados o no se haya hecho bien la
seleccin de requisitos, se mostrar un mensaje de error como se v en la siguiente interfaz:
Pgina 58
Pgina 59
Pgina 60
y luego
Pgina 61
podemos modificar los atributos de la ventana raz, es decir, TaskWindow, por ejemplo el nuevo
ttulo de la ventana ser SISTEMA EXPERTO MEDICO EN NEUMOLOGA y se activa la
opcin Maximized y luego seleccionar el botn Ok. Si se ejecuta nuevamente la aplicacin se vern
los cambios tal como se muestra a continuacin.
Es de inters 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 opcin se
eliminar todas las subopciones menos New y Exit. Luego el archivo TaskMenu.mnu debe quedar
as:
Pgina 62
Las opciones no eliminadas se renombrarn de la siguiente manera: File = Consulta, New = Nueva,
Exit = Salir. La opcin Nueva deben de habilitarse ya que por defecto est deshabilitada (quitar el
check en la opcin Disabled), entonces el archivo TaskMenu.mnu debe quedar as:
Pgina 63
En este punto se debe ejecutar nuevamente la aplicacin mediante la opcin Build y luego Build
con lo que se observa la advertencia que no es usado el predicado onHelpAbout. Esto significa
que hay un cdigo asociado a las opciones eliminadas que est dems en el archivo
TaskWindow.pro, de donde debemos eliminar
Pgina 64
Luego en el mismo archivo, se debe modificar en el siguiente cdigo, el valor true por false, para
as eliminar la opcin Window la que no se elimina en modo diseo. El cdigo a modificar es:
constants
mdiProperty : boolean = true.
de la siguiente manera:
predicates
onShow : window::showListener.
clauses
onShow(_, _CreationData).
%_MessageForm = messageForm::display(This).
Pgina 65
En este punto del desarrollo de la aplicacin, 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 cdigo que
deber quedar por el momento, se muestra a continuacin:
Pgina 66
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 intencin del cdigo anterior es que el usuario pueda accesar a una nueva consulta y salir de la
aplicacin tambin 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 aplicacin se debe observar la siguiente interfaz:
Pgina 67
Ahora, para terminar con el formateo del proyecto en funcin del botn opcin Salir del
ProjectToolbar, se va a escribir el cdigo que permitir que cuando se seleccione el botn opcin
en mencin, se pueda salir de la aplicacin. 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 cdigo del cual solo nos
interesa el que se muestra a continuacin, ya que luego se modificar:
predicates
onEditCut : window::menuItemListener.
clauses
onEditCut(_Source, _MenuTag).
Pgina 68
predicates
onEditCut : window::menuItemListener.
clauses
onEditCut(_Source, _MenuTag):close().
Al ejecutar la aplicacin, sea al seleccionar la opcin Salir tanto del men principal o el botn
opcin Salir del ProjectToolbar, se debe terminar la ejecucin de la aplicacin. Ahora para
finalizar, como ya se mencion anteriormente, el formateo del proyecto en funcin 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 botn derecho sobre el archivo
TaskWindow.win y luego seleccionamos la opcin Attributes con lo que en la interfaz que aparece
desactivamos las casillas: CloseBox, MaximizeBox y MinimizeBox respectivamente.
Al ejecutar la aplicacin, la interfaz mostrada ser la siguiente:
Pgina 69
El paso siguiente es enviar al usuario un mensaje que explique la finalidad de la aplicacin, pero
este mensaje debe aparecer automticamente luego que se muestra la interfaz del punto anterior.
Para esto haciendo click con el botn derecho sobre la carpeta SISTEMA EXPERTO MDICO
EN NEUROLOGA, seleccione la opcin New in New Package y luego elija el objeto Dialog
para luego escribir como nombre del Dialog: dlgmensaje y luego hacer click en el botn Create.
El proceso grficamente se muestra a continuacin:
Pgina 70
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 dilogo creado y lo graba.
Como se dijo anteriormente el mensaje creado en el punto anterior debe aparecer automticamente,
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 cdigo:
predicates
onShow : window::showListener.
clauses
onShow(_, _CreationData).
%_MessageForm = messageForm::display(This).
Pgina 71
predicates
onShow : window::showListener.
clauses
onShow(_, _CreationData):% _MessageForm = messageForm::display(This).
postAction({ :- _ = dlgmensaje::display(This) }).
Al ejecutar la aplicacin, de aparecer algn mensaje de agregar las libreras necesarias, se hace click
en el botn Add All para que finalmente aparezca automticamente el mensaje creado.
A continuacin se deber crear un dilogo 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 ningn botn de ventana que trae por defecto el dilogo dlgnombre. Luego
se debe colocar un botn 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 tambin un Edit Control para ingresar
el nombre del usuario, el Edit Control, se llamar ednombre_ctl.
Ahora se debe crear un dilogo llamado dlgbienvenida, mediante el mismo procedimiento que para
crear los dilogos anteriores (recordar haciendo click con el botn derecho sobre la carpeta
MEDICO, seleccione la opcin New in New Package). En este dilogo debe mostrarse un mensaje
de bienvenida al uso del sistema al usuario. Se debe tener en cuenta que en este dilogo debe
capturarse el nombre del usuario ingresado en el dilogo anterior dlgnombre.
Entonces ahora escribir el siguiente cdigo al programar el botn de comando: btncontinuar_ctl,
en el dlgnombre.pro:
Pgina 72
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 dilogo
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 cdigo que
aparece por defecto, con el siguiente:
predicates
onFileNew : window::menuItemListener.
clauses
onFileNew(_Source, _MenuTag):_ = dlgnombre::display(This).
Luego al ejecutar la aplicacin, de aparecer algn mensaje de agregar las libreras necesarias, se
hace click en el botn Add All con lo que debera ejecutarse sin ningn problema hasta el punto
desarrollado.
Pgina 73
/*************************************************************************
****
Copyright (c) 2014 My Company
**************************************************************************
****/
class dlgbienvenida : dlgbienvenida
open core
predicates
display : (window Parent, string Name) -> dlgbienvenida Dlgbienvenida.
constructors
new : (window Parent, string Name).
end class dlgbienvenida
En el dilogo 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 botn ok_ctl, el cual se renombrar con la propiedad text, con el nombre
Continuar.
Pgina 74
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 dilogo en el que se realizar las consultas al experto artificial. Este dilogo
se llama dlgconsulta al cul en la propiedad Text se deber escribir: Consultando al experto.
Finalmente a este punto, en el dilogo creado, se cambiar la apariencia del botn Ok por Salir.
En este dilogo dlgconsulta, se debern poner los siguientes controles con sus respectivas
propiedades:
o Un Push Button, el que se denominar btndiagnosticar_ctl.
o Un StaticText_ctl, para que recepcione el nombre del usuario ingresado anteriormente, el
que debe ser del tipo Fact Variable, con lo que ahora se llamar: staticText_ctl, quedando
la propiedad Text en blanco.
o Un StaticText1_ctl, el que se denominar (en la propiedad Text) Sintomas a seleccionar.
o Un StaticText2_ctl, el que se denominar (en la propiedad Text) Sintomas
seleccionados.
o Un List Box, el que se denominar lbdisponibles_ctl.
Pgina 75
Pgina 76
predicates
onShow : window::showListener.
clauses
onShow(_Source, _Data):lbdisponibles_ctl:add("Sntoma_01"),
lbdisponibles_ctl:add("Sntoma_02"),
lbdisponibles_ctl:add("Sntoma_03"),
lbdisponibles_ctl:add("Sntoma_04"),
lbdisponibles_ctl:add("Sntoma_05").
Ahora la idea es que cuando el usuario seleccione (con doble click), un sntoma de
lbdisponibles_ctl, este sea agregado a lbseleccionados_ctl, eliminndose automticamente del
primer List Box y viceversa, es decir si el usuario desea eliminar un sntoma seleccionado de
lbseleccionados_ctl, pues lo debe seleccionar con doble click y automticamente pasar
nuevamente a formar parte de lbdisponibles_ctl. Para esto en la pestaa Events de la caja de
propiedades de lbdisponibles_ctl, se hace doble click sobre el evento DoubleClickListener, con
lo que aparecer el siguiente cdigo:
predicates
onLbdisponiblesDoubleClick : listBox::doubleClickListener.
clauses
onLbdisponiblesDoubleClick(_Source).
Pgina 77
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).
Se debe ahora llamar desde el dilogo dlgbienvenida al dilogo dlgconsulta. Para esto, en el botn
Continuar (es el botn ok_ctl) de dlgbienvenida, poner el siguiente cdigo:
Tenorio Cabrera Julio Luis
Pgina 78
predicates
onOkClick : button::clickResponder.
clauses
onOkClick(_Source) = button::defaultAction:close(),
_ = dlgconsulta::display(getParent(), name),
!.
predicates
display : (window Parent, string Name) -> dlgconsulta Dlgconsulta.
constructors
new : (window Parent, string Name).
end class dlgconsulta
Pgina 79
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 cdigo para el botn btndiagnosticar_ctl, para esto se hace doble
click en el botn mencionado con lo que aparecer el siguiente cdigo:
predicates
onBtndiagnosticarClick : button::clickResponder.
clauses
onBtndiagnosticarClick(_Source) = button::defaultAction.
Pgina 80
domains
sintomas = string*.
facts
diagnostico:(sintomas,string,string).
clauses
diagnostico(["Sntoma_01","Sntoma_02","Sntoma_03"],"Enfermedad_01_02_03","Trata
miento_01_02_03").
diagnostico(["Sntoma_04","Sntoma_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 snto
mas seleccionados").
Pgina 81
Figura 01: Pantalla con mensaje explicativo al usuario de la finalidad de la aplicacin experta.
Pgina 82
Pgina 83
Pgina 84
Pgina 85
Pgina 86
Pgina 87
Pgina 88
SITIOS WEB
Prolog Development Center (PDC). [Fecha de consulta: 15 enero 2013]. Disponible en: http://www.visualprolog.com/
Pgina 89