Búscalo aquí:

Cómo programar en SWI Prolog?

SWI Prolog es una herramienta que permite la programación lógica y es de distribución libre. Sin embargo, su uso no es muy común...aun, pues he podido observar que muchas personas prefieren utilizar herramientas como Visual Prolog, la cual muy a parte de ser software privativo trae consigo algunas "complicaciones" al momento de trabajar en ella, como por ejemplo, el mantener cierto orden al ingresar código.



Sin embargo SWI PRolog es una heramienta de sencillo uso, en una entrada anterior presente los primeros pasos para trabajar en SWI Prolog y esta vez compartiré un ejemplo de código explícito.

Se mostrará como programar un Sistema Experto sencillo. Como sabemos, los Sistemas Expertos son herramioentas que poseen una base de conocimiento, la cual utilizan para brindar "ayuda" en alguna problemática específica haciendo el papel de un experto humano.

El ejemplo que mostraré es acerca de un Sistema Expeto que clasifica los espárragos (hortalizas) en 4 diferentes categorias, dependiendo de las características que la hortaliza que esta siendo examinada posea.

  1. :-dynamic cuerpo/2, turion/2.
  2. esPreg(cuerpoblanco,' tiene el cuerpo blanco?').
  3. esPreg(cuerpototalmenteblanco,' tiene el cuerpo totalmente blanco?').
  4. esPreg(cuerpoconmanchitas,' tiene el cuerpo pequeñas manchitas?').
  5. esPreg(cuerpoverde, ' tiene el cuerpo verde?').
  6. esPreg(cuerpototalmenteverde,' tiene el cuerpo totalmente verde?').
  7. esPreg(puntasrosaviole, ' tiene las puntas entre rosado y violeta?').
  8. esPreg(puntaspurpura, ' tiene las puntas purpura?').
  9. esPreg(puntasverde, ' tiene las puntas de color verde?').
  10. esPreg(puntaligverd, ' las puntas tienen una coloración ligeramente verde?').
  11. esPreg(puntastinteverde, ' las puntas tienen un tinte ligeramente verde?').
  12. esPreg(puntasblancas, ' tiene las puntas de color blancas?').
  13. esPreg(puntacompacta,' tiene la punta compacta? ').
  14. esPreg(puntaligabier,' tiene la punta ligeramente abierta? ').
  15. esPreg(puntaligrosa,' tiene las puntas ligeramente de color rosado?').
  16. esPreg(turionparteblanca, ' tiene una parte del turion de color blanco?').
  17. esPreg(turionblanco, ' tiene el turion de color blanco?').
  18. esPreg(turmayverd, ' tiene la mayor parte del turion de color verde?').
  19. esPreg(turionbienformado, ' tiene los turiones bien formados?').
  20. esPreg(matizligrosa, ' tiene un matiz ligeramente rosado en los turiones?').
  21. esPreg(puntaligverd, 'puntas poseen coloración ligeramente verde?').
  22. esPreg(leveherrumbre,'turiones con manchas leves de color herrumbre?').
  23. esPreg(fibrosidad, ' el turion tiene indicios de fibrosidad? ').
  24. esPreg(fibrosinf, ' el turion tiene leve fibrosidad en la parte inferior?').
  25. esPreg(curvo, ' los turiones son curvos? ').
  26. esPreg(diametro3, ' tiene un diametro mayor o igual a 3mm? ').
  27. esPreg(diametro8, 'tiene un diametro mayor o igual a 8mm? ').
  28. esPreg(verde98, ' el color verde predomina en más del 98%? ').
  29. esPreg(verde80, ' el color verde es de al menos el 80%? ').
  30. esPreg(verde60, ' el color verde es de al menos el 60%? ').
  31. esRespuesta(si).
  32. esRespuesta(no).
  33. preguntar(Caract,Resp):- esPreg(Caract,Preg),
  34. write('El esparrago '),
  35. write(Preg),
  36. read(Resp),
  37. esRespuesta(Resp),!.
  38. preguntar(Caract,Resp):- write('No entiendo tu respuesta,escribe si/no\n'),
  39. preguntar(Caract,Resp),!.
  40. evaluarCaractCuerpo(Caract,Resp):- cuerpo(Caract,Resp),!.
  41. evaluarCaractCuerpo(Caract,Resp):- preguntar(Caract,Resp),
  42. assert(cuerpo(Caract,Resp)),!.
  43. evaluarCaractTurion(Caract,Resp):- turion(Caract,Resp),!.
  44. evaluarCaractTurion(Caract,Resp):- preguntar(Caract,Resp),
  45. assert(turion(Caract,Resp)),!.
  46. esEsparragoBlanco:- evaluarCaractCuerpo(cuerpoblanco,R0),
  47. R0=si,
  48. evaluarCaractCuerpo(cuerpototalmenteblanco,R1),
  49. R1=si,!.
  50. esEsparragoBlanco:- evaluarCaractCuerpo(cuerpoblanco,R0),
  51. R0=si,
  52. evaluarCaractCuerpo(cuerpoconmanchitas,R1),
  53. R1=si,!.
  54. esEsparragoVerde:- evaluarCaractCuerpo(cuerpototalmenteverde,R0),
  55. R0=si,!.
  56. esEsparragoVerde:- evaluarCaractCuerpo(cuerpoverde,R0),
  57. R0=si,
  58. evaluarCaractCuerpo(cuerpoconmanchitas,R1),
  59. R1=si,!.
  60. esEsparragoVioleta:- evaluarCaractCuerpo(puntasrosaviole,R0),
  61. R0=si,
  62. evaluarCaractTurion(turionparteblanca,R1),
  63. R1=si,!.
  64. esEsparragoVioleta:- evaluarCaractCuerpo(puntaspurpura,R0),
  65. R0=si,
  66. evaluarCaractTurion(turionparteblanca,R1),
  67. R1=si,!.
  68. esEsparragoVioletaVerduzco:- evaluarCaractCuerpo(puntasverde,R0),
  69. R0=si,
  70. evaluarCaractTurion(turmayverd,R1),
  71. R1=si,!.
  72. esEsparragoBlancoSuperior:- esEsparragoBlanco,
  73. evaluarCaractCuerpo(diametro8,R0),
  74. R0=si,!.
  75. esEsparragoVerdeSuperior:- esEsparragoVerde,
  76. evaluarCaractCuerpo(diametro3,R0),
  77. R0=si,!.
  78. esEsparragoVioletaSuperior:- esEsparragoVioleta,
  79. evaluarCaractCuerpo(diametro8,R0),
  80. R0=si,!.
  81. esExtra:- evaluarCaractTurion(turionbienformado,R0),
  82. R0=si,
  83. evaluarCaractTurion(fibrosidad,R1),
  84. R1=no,
  85. evaluarCaractTurion(curvo,R2),
  86. R2=no,!.
  87. esCategoriaI:- evaluarCaractTurion(turionbienformado,R0),
  88. R0=si,
  89. evaluarCaractTurion(curvo,R1),
  90. R1=no,!.
  91. esCategoriaII:- evaluarCaractTurion(leveherrumbre,R0),
  92. R0=si,
  93. evaluarCaractTurion(turionbienformado,R1),
  94. R1=no,
  95. evaluarCaractTurion(curvo,R2),
  96. R2=no,!.
  97. esCategoriaII:- evaluarCaractTurion(leveherrumbre,R0),
  98. R0=si,
  99. evaluarCaractTurion(turionbienformado,R1),
  100. R1=si,
  101. evaluarCaractTurion(curvo,R2),
  102. R2=si,!.
  103. esCategoria('Blanco Extra'):- esEsparragoBlancoSuperior,
  104. evaluarCaractCuerpo(puntasblancas,R0),
  105. R0=si,
  106. evaluarCaractTurion(turionblanco,R1),
  107. R1=si,
  108. esExtra,!.
  109. esCategoria('Blanco Extra'):- esEsparragoBlancoSuperior,
  110. evaluarCaractTurion(matizligrosa,R0),
  111. R0=si,
  112. esExtra,!.
  113. esCategoria('Verde Extra'):- esEsparragoVerdeSuperior,
  114. evaluarCaractCuerpo(puntacompacta,R0), R0=si,
  115. evaluarCaractCuerpo(verde98,R1), R1=si,
  116. evaluarCaractTurion(leveherrumbre,R2), R2=si,
  117. esExtra,!.
  118. esCategoria('Verde Categoria I'):- esEsparragoVerdeSuperior,
  119. evaluarCaractCuerpo(verde80,R0),
  120. R0=si,
  121. evaluarCaractCuerpo(puntaligabier,R1),
  122. R1=si,
  123. evaluarCaractTurion(leveherrumbre,R2),
  124. R2=si,
  125. evaluarCaractTurion(fibrosinf,R3),
  126. R3=si,
  127. esCategoriaI,!.
  128. esCategoria('Verde Categoria I'):- esEsparragoVerdeSuperior,
  129. evaluarCaractCuerpo(verde80,R0),
  130. R0=si,
  131. evaluarCaractCuerpo(puntaligabier,R1),
  132. R1=si,
  133. evaluarCaractTurion(leveherrumbre,R2),
  134. R2=si,
  135. evaluarCaractTurion(fibrosinf,R3),
  136. R3=no,
  137. esCategoriaI,!.
  138. esCategoria('Blanco Categoria I'):- esEsparragoBlancoSuperior,
  139. evaluarCaractTurion(matizligrosa,R0),
  140. R0=si,
  141. evaluarCaractCuerpo(puntaligrosa,R1),
  142. R1=si,
  143. evaluarCaractTurion(fibrosidad,R2),
  144. R2=no,
  145. esCategoriaI,!.
  146. esCategoria('Verde Categoria II'):- esEsparragoVerdeSuperior,
  147. evaluarCaractCuerpo(verde60,R0),
  148. R0=si,
  149. esCategoriaII,!.
  150. esCategoria('Blanco Categoria II'):- esEsparragoBlancoSuperior,
  151. evaluarCaractCuerpo(puntaligverd,R1),
  152. R1=si,
  153. esCategoriaII,!.
  154. esCategoria('Violeta Categoria II'):-
  155. esEsparragoVioletaSuperior,
  156. evaluarCaractCuerpo(puntastinteverde,R1),
  157. R1=si,
  158. esCategoriaII,!.
  159. esCategoria('No determinado'):- !.
  160. inicio:- write('SE Esparragos \n'),
  161. esCategoria(Clase),
  162. write('El SE concluye que el esparrago es de categoría: '),
  163. write(Clase),!.

Como se puede observar se hace uso de la estructura "dynamic", la cual permite reservar espacio de memoria para cierta cantidad de variables referenciadas por otra variable, por ejemplo: "dynamic cuerpo/2" indica que la se guardará espacio de memoria para dos variables las cuales serán referenciadas mediante la variable "cuerpo". Luego para realizar la asignación en memoria de dichas variables se usa "assert()".


Para correr el programa tan solo debemos de compilar el código y llamar en el shell a la función principal, en este caso, a la función "inicio". Saludos, espero les sea de utilidad :D


Quieres leer más post como éste???...suscribete aquí!!!




18 comentarios:

  1. hola Jorge saludos desde Nicaragua este es un muy buen aporte de parte tuya Jorge te felicito por tu desempeño en la programacion logica
    hasta proto soyer112004@yahoo.es

    ResponderEliminar
  2. hola jorge como estas he estado observando tu blog y felicidades se nota que programas mucho

    yo estoy realizando un sistema experto para diagnostico de enfermedades del ganado en Nicaragua, ya tengo la base de conocimiento en prolog y ahora estoy realizando la interfaz con netbeans de java bueno.

    el problema que tengo es que ya he conectado ambos programas y en la interfaz de java ya puedo llamar a la primer pregunta de prolog pero sucede que no se como programar los botones de "si" y "no" para contestar las preguntas tengo entendido que es algo como

    pregunta.setText("Tienen fiebre ? :");
    if(boton1.isSelected()==true)respt="si";
    if(boton2.isSelected()==true)respt="no";

    si me puedes ayudar te lo agradeceria mucho

    ResponderEliminar
  3. Hola Juan, gracias por leer mi blog y tomar en cuenta algunas sugerencias que coloco en él. Bueno con respecto a tu pregunta, lo que estas haciendo depende de la interfaz de recepción de eventos, por lo que entiendo estas usando botones, en ese caso tienes que usar el actionListener para el JButton y capturar la respuesta del boton.

    Si usarás simpelemnte capturas de Si's o No's te recomendaria que uses el JOptionPane para la confirmacion de una respuesta Si o No, de la sgte manera:

    int opt = javax.swing.JOptionPane.showConfirmDialog(
    this, "Tiene Fiebre?",
    "Sist. Exp. de Ganado",javax.swing.JOptionPane.YES_NO_OPTION);

    if (opt == javax.swing.JOptionPane.YES_OPTION)
    hacer lo que tengas que hacer con la respuesta si
    else
    hacer lo que tengas que hacer con la respuesta no


    Espero te sirva, saludos

    ResponderEliminar
  4. hola jorge como estas espero que bien te saluda juan desde nicaragua
    he comenzado a realizar una interfaz sencilla para swiprolog en netbeans pero tengo una duda quiero que las preguntas de prolog me aparescan en java pero no se como, ademas no se como hacer para que las preguntas cambien y contestarlas con un boton de si y otro de no
    bueno este es el pequeño codigo en swiprolog llamado family.pl

    :-dynamic sintoma/2.

    esPreg(cansancio,' el bovino esta cansado?').
    esPreg(fiebre,' el bovino tiene fiebre?').
    esRespuesta(si).
    esRespuesta(no).

    preguntar(Caract,Resp):- esPreg(Caract,Preg),
    write(Preg),
    read(Resp),
    esRespuesta(Resp),!.

    preguntar(Caract,Resp):- write('respuesta erronea\n'),
    preguntar(Caract,Resp),!.

    evaluarBovino(Caract,Resp):- sintoma(Caract,Resp),!.
    evaluarBovino(Caract,Resp):- preguntar(Caract,Resp),
    assert(sintoma(Caract,Resp)),!.

    esAntrax:- evaluarBovino(cansancio,R0),
    R0=si,
    evaluarBovino(fiebre,R1),
    R1=si,!.
    esEnfermedad('Antrax'):- esAntrax,
    R0=si,!.
    esEnfermedad('Mucha Salud'):- !.


    inicio:- write(' diagnostico enfermedades bovinas \n'),
    esEnfermedad(Tipo),
    write('El bovino tiene: '),
    write(Tipo),!.

    y este es el de java

    package jpl;
    import java.util.Hashtable;
    import jpl.*;
    import java.util.Hashtable;
    import jpl.*;
    import jpl.Query;
    import java.awt.*;
    import java.lang.*;
    import javax.swing.*;
    import java.awt.event.*;
    class Interface1 extends JFrame
    {

    String t1 = "consult('family.pl')"; Query q1 = new Query(t1);
    String t2= "esEnfermedad(Tipo)"; Query q2 = new Query(t2);
    String [] Respuesta= {( (q1.hasSolution() ? "conectado con swi prolog" : "coneccion fallida") )};
    String [] Respuesta2={( " " + q2.oneSolution().get("Tipo"))};
    JLabel Provincial=new JLabel("Respuesta",JLabel.CENTER);
    JComboBox Resp=new JComboBox(Respuesta);
    JComboBox Resp2=new JComboBox(Respuesta2);
    JButton Cancelar=new JButton("Cancelar");
    JButton Diagnosticar=new JButton("Diagnosticar");
    JRadioButton Si=new JRadioButton("si");
    JRadioButton No=new JRadioButton("no");
    ButtonGroup Eleccion=new ButtonGroup();

    Interface1()
    {
    JPanel Botones=new JPanel();
    Botones.add(Diagnosticar);
    Botones.add(Cancelar);
    add(Botones,"South");
    JPanel Pprincipal=new JPanel();
    add(Pprincipal,"Center");
    Pprincipal.setLayout(new GridLayout(3,1));
    JPanel Datos=new JPanel();
    Datos.setLayout(new GridLayout(6,2));
    Datos.add(Resp);
    Datos.add(Resp2);
    JPanel JPanelEleccion=new JPanel(new GridLayout(1,2));
    Eleccion.add(Si);
    Eleccion.add(No);
    JPanelEleccion.add(Si);
    JPanelEleccion.add(No);
    Datos.add(JPanelEleccion);
    Pprincipal.add(Datos);
    addWindowListener(new WindowAdapter()
    {
    public void windowClosing(WindowEvent we)
    {
    System.exit(0);
    }
    });
    setResizable(false);
    setTitle("Sistema expero");
    setSize(700,500);
    setVisible(true);
    }
    }
    public class interfaze
    {
    public static void main( String argv[] )
    {

    Interface1 inter=new Interface1();

    }
    }
    bueno jorge espero que puedas ayudarme ya que para mi tus conocimientos son los de un maestro en cuanto a swiprolog. que tengas un buen dia nos vemos att soyer112004@yahoo.es

    ResponderEliminar
  5. Hola Juan, saludos a la distancia, bueno primero que nada, según mi poca experiencia en esto, cuando realizas la combinación de un lenguaje con otro para obtener un único producto es por que deseas aprovechar las ventajas que tienen cada uno con respecto al otro. En este caso, el objetivo de usar Java con Swi prolog, es realizar el trabajo de programación lógica de manera pura en swi prolog, y dejar a Java el trato de interfaz de usuario (por ser más vistosa y de alguna manera más común y sencilla de manejar).

    En tu caso, si deseas colocar las preguntas, estas deberían estar en Java, pues si las colocas en SWI prolog, desde acá las tendrías que enviar a la interfaz Java para que que las muestres (doble trabajo). Deja para swi prolog el trabajo de realizar la inferencia para tu sistema experto.

    Con respecto a cómo mostrar las preguntas en Java con los botones de SI o NO, puedes usar el JOptionPane de la sgte manera:

    int opt = javax.swing.JOptionPane.showConfirmDialog(
    this, "Tiene Fiebre?",
    "Sist. Exp. de Ganado",javax.swing.JOptionPane.YES_NO_OPTION);

    if (opt == javax.swing.JOptionPane.YES_OPTION)
    hacer lo que tengas que hacer con la respuesta si
    else
    hacer lo que tengas que hacer con la respuesta no


    Espero te sirva, saludos.

    ResponderEliminar
  6. amigaso hice lo que dice para correr tu SE, pero no me funca que estara pasando no creo que sea problema del code. ESTE ERROR SALE : ERROR: toplevel: Undefined procedure: esCategoria/0 (DWIM could not correct goal)

    ResponderEliminar
  7. ERROR: toplevel: Undefined procedure: inicio/0 (DWIM could not correct goal), este es el error al poner en el shell INICIO. .. claro que en minusculas.. AYUDAMEEEEEEEEEEE.!!! QUE VIVA EL PERÚ

    ResponderEliminar
  8. El error que muestra el shell indica que no se ha creado correctamente el procedimiento inicio..tal vez se te olvido copiarlo o lo estas llamando de manera inadeacuada. Saludos.

    ResponderEliminar
  9. hola jorge te saludan de chile (puntastinteverde,R1), R1=si,
    esto se puede reemplazar por
    (puntastinteverde,si),
    y otras partes de tu codigo que repites o te enseñaron asi y tu lo vuelves a repetir a programar de forma optima.

    ResponderEliminar
  10. Lo que mencionas en tu comentario es cierto, las variables que van como parametros en las funciones pueden ser reemplazados directamente por sus valores directos, esto no es novedad y s epuede realizar en cualquier lenguaje de programación y no tiene nada que ver con hacer más o menos eficiente un programa...a lo mucho puede ocupar unas cuantas lineas de código de más, pero a mi consideración vale la pena para dejar las cosas claras.

    Saludos a Chile!!!y gracias por leerme :D

    ResponderEliminar
  11. Excelente aportación debido a que no se encuentran tan facilmente ejemplos como el tuyo, cuando buscaba programación lógica mas bien todo lo que encontraba era conceptual. Felicidades por tan buen blog

    ResponderEliminar
  12. hola buenas noches
    disculpas sabes como hago para que las respuestas de preguntas de una evaluacion no este seleccionada desde inicio sino que el usuario elija una y pueda enviarla para su verificacion t agradeceria mucho si puedes ayudarme

    ResponderEliminar
  13. hola buenos dias disculpe sabes como hacerle para q los botones sean decolor ooo si se puede poner imaen a un botn

    ResponderEliminar
    Respuestas
    1. Hola, para los detalles de los botones, colores, etc, en prolog puedes revisar este post para trabajar GUI en Prolog

      saludos

      Eliminar
  14. HOla men estoy iniciando en esto de programacion con prolo desearia que me digas como puedo a traves de java ingresar un assert para prolog a traves de la interfaz de java gracias espero tu respuesta!!!!

    ResponderEliminar
  15. Buen Post me sirvió para mi Trabajo de Sistema Experto (MySQL+Java+Prolog)!!!

    ResponderEliminar
  16. Excelente post, una pregunta el motor de inferencia que usaste en el ejemplo cual es o tal vez no pregunte bien, estoy entrando en lo que se refiere a IA me gustaría tu respuesta gracias por adelantado.

    ResponderEliminar
  17. Hola Bro! Buen post! Conoces alguna forma de reproducir imágenes .gif en SWI-PROLOG? te agradecería mucho esa información!

    ResponderEliminar

Bienvenido a jcGeorge's Blog!!!

Por favor deja tu comentario, consulta o sugerencia, procura mantener habilitado tu perfil de Blogger o deja un enlace a tu blog o web.

Gracias por leer este blog!!!

Related Posts Plugin for WordPress, Blogger...