Google
 

domingo, 27 de abril de 2008

Programacion Logica : swi-prolog , Interfaces

Este articulo va destinado para las personas que tienen nociones básicas en programacion lógica o han manejado otro entorno programacion logica diferente al swi-prolog ejemplo visual prolog etc, Pero creo que no es tan dificil de entender lo que se les mencionara a continuacion. Lo ideal es que dado unas pequeñas nociones y funciones puedan utilizar la ayuda o demás herramientas para lograr un mejor entendimiento de todo lo que se mencionara a continuación Primeros pasos en swi-prolog en el blog de Jorge Valverde Revaza.



  1. Manejar Entorno de trabajo:
    Para esto abrir swi-Prolog aparecerá algo así , para tener un editor de programación lo único que debemos hacer es seleccionar de los botones de arriba Settings - User init file.. y nos aparecerá una nueva ventana cerramos la ventana y ahora si procedemos a file - New para crear un nuevo proyecto (la operación anterior algunos utilizan emacs.) de igual manera si se desea abrir un .pl doble clic sobre el .pl después Settings - User init file.. y la cerramos file - edit nombre.pl y aparecerá tu proyecto.

  2. Sintaxis de swi-Prolog:
    Bueno la sintaxis de swi-prolog es igual que cualquier otro entorno de programcion logica .
    Cualquier programa en Prolog tiene que estar escrito en un fichero de texto plano (sin formato). Lamanera mas sencilla es usar el Bloc de Notas. Dicho archivo debe poseer la extensin ”.pl” para indicar que contiene codigo fuente de Prolog.
    Un programa Prolog esta formado con un conjunto de hechos y de reglas junto con un objetivo. El archivo del codigo fuente de Prolog contendra el conjunto de hechos y de reglas y el objetivo sera lanzado desde el shell de SWI-Prolog.
    Existen ciertas consideraciones sobre la sintaxis de Prolog:
    1. Variables:
    El identificador de una variable tendra que tener su primera letra en mayusculas.
    Ej: X, Atapuerca, Cobaltina, RADgtfCdf
    2. Constantes:
    La primera letra de una constante deber´a estar escrita en min´usculas.
    Ej: a, incienso, roberto, rADgtfCdf
    Tambi´en se consideran constantes a los n´umeros,
    Ej: 1, 5.02, 0.7
    las palabras entre comillas simples
    Ej: ’a’, ’A’, ’a a’
    y la lista vacıa [ ].
    3. Funciones:
    Al igual que las constantes, su primera letra debe ser una minuscula. Debera estar seguido de un conjunto de terminos (otras funciones, variables o constantes) encerrados entre parentesis.
    Ej: f(c,X), conc arbol(Hijo Izq, Raiz, Hijo Der), rADgtfCdf(RADgtfCdf, rADgtfCdf)
    4. Predicados:
    Su sintaxis es la misma que la de las funciones aunque, por su localizacion dentro de la clausula (es decir, dentro del programa Prolog), el compilador los identificara como tal, y no como funciones.
    Ej: f(c,X), conc arbol(Hijo Izq, Raiz, Hijo Der), rADgtfCdf(RADgtfCdf, rADgtfCdf)
    Tambien existe la posibilidad de tener predicados 0-arios.
    5. Hechos:
    Son clausulas de Horn que poseen un unico predicado en la cabeza y ninguno en el cuerpo. Tienen la siguiente forma en sintaxis de logica de primer orden: P
    En Prolog no se escribe la flecha sino que se pone un punto al final: p.
    donde p es un predicado y tiene que seguir su sintaxis. Ej:
    padre(aaron, maria).
    compositor(shostakovich).
    shostakovich(compositor).
    6. Reglas:
    Son clausulas de Horn que poseen un ´unico predicado en la cabeza y uno o m´as en el cuerpo.
    Tienen la siguiente pinta:
    P← Q1,Q2,Q3 escritos en sintaxis clausular o
    P←Q1 ^ Q2 ^ Q3 escritos en sintaxis de logica de primer orden.
    En Prolog la flecha se sustituye por ”:-”, las conectivas conjuntivas se escriben como comas ”,” y la regla termina en punto:
    p :- q1, q2, q3.
    donde, al igual que los hechos, p y q1, q2 y q3 son predicados. Ej:
    cuadrado(X) :- poligono(X), numero_lados(X,4).
    7. Objetivos:
    Son clausulas de Horn que no poseen ningun predicado en su cabeza:
    &← Q1,Q2,Q3
    Los predicados se escriben separados por comas y terminados en punto. Solo pueden sen lanzados desde el shell de SWI-Prolog.
    ?- padre(X, Y),padre(Y, Z).
  3. Compilacion y ejecucion en swi-prolog:
    La codificacion en swi- prolog es la misma que todos los editores de prolog solo que aquí no declaras la variables que vas a utilizar, las funciones básicas serian:
    write, fail, nl, is ,!,:- dynamic, retract, assert, etc ;

    Algunos códigos como disktra , autómata, gramaticas, pequeño sistema experto, operaciones con listas , ordenación por mezcla selección inserción, vectores , matrices, problemas con recursion, torre de hanoi, búsquedas , etc, son los que se puedieron desarrollar en el laboratorio del curso de programacion logica dictado por Ivan sipiran.
    Para complilar un proyecto Compile-Compile buffer y para ejecutarlo en la consola de swi-prolog (figura anterior) escribir nombreReglaoHecho. y enter.



  4. Todas las soluciones a un objetivo:
    Existen predicados que no se paran cada vez que llegan a una hoja exito en el arbol de vuelta atras sino que realizan todo el arbol que esta por debajo de un objetivo dado y guardan las soluciones (unificaciones) en una lista.
    findall(+Template, +Goal, -Bag): realiza todo el arbol de backtracking del objetivo Goal. Cada vez que llega a un exito unifica las variables con la plantilla Template e introduce el resultado en la lista Bag.
    5 ?- listing.
    dios_egipcio(amon).
    dios_egipcio(anubis).
    dios_egipcio(apis).
    dios_egipcio(ra).
    Yes
    6 ?- findall(X,dios_egipcio(X), L).
    X = _G362
    L = [amon, anubis, apis, ra]
    yes
    bagof(+Template, +Goal, -Bag): identico a findall/3 excepto que si el objetivo posee variables libres entonces primero probara la unificacion con esas variables libres y despues realizara el arbol de vuelta atras para cada una de esas unificaciones, parando cada vez.
    ?- listing.
    vida(carlos_III, 1716, 1788).
    vida(carlos_IV, 1748, 1819).
    vida(fernando_VII, 1784, 1833).
    yes
    ?- bagof([A,B], vida(A, B, C),L).
    A = _G371
    B = _G374
    C = 1788
    L = [[carlos_III, 1716]] ;
    A = _G371
    B = _G374
    C = 1819
    L = [[carlos_IV, 1748]] ;
    A = _G371
    B = _G374
    C = 1833
    L = [[fernando_VII, 1784]] ;
    No
    Si no queremos que se pare cada vez que encuentre una unificacion debemos usar el sımbolo ˆ como
    en el ejemplo:
    ?- bagof([A,B], C^vida(A, B, C),L).
    A = _G383
    B = _G386
    C = _G391
    L = [[carlos_III, 1716], [carlos_IV, 1748], [fernando_VII, 1784]] ;
    No
    setof(+Template, +Goal, -Set): igual que bagof/3 pero la lista Bag es devuelta ordenada y sin duplicados.
  5. Interfaces en swi-prolog usando XPCE:
    La creacion de interfaces en swi-prolog no es tan complicada como podriamos imaginarnos por ejemplo tenemos lo siguiente :
    primerVentana:-new(D, dialog('Nombre de tu ventana')), send(D, open).

    Existen cuatro predicados basicos que te permiten interactuar con los objetos de swi-prolog :

    ?? new(?Reference, +NewTerm): Este predicado recoge dos parámetros, el primero recogería la referencia que se le asigna al nuevo objeto, ya que new se usa para crear objetos. El segundo parámetro le indicaría el objeto que se quiere crear.

    ?? send(?Receiver, +Selector(...Args...)): El primer parámetro del predicado es una referencia al objeto que deseemos enviarle un mensaje. El segundo parámetro indicará el método al que queremos invocar, lo cual indicaremos junto a los argumentos que queremos enviarle al método.

    ?? get(?Receiver, +Selector(+Argument...), -Result): Los dos primeros parámetros tienen el mismo significado que para send, sin embargo el último parámetro sirve para recoger el valor que nos devuelva el método que hallamos invocado.

    ?? free(?Reference): libera la memoria asociada al objeto que se le indica en el primer parámetro.

    Los objetos que podemos manejara en swi-prolog son:
    button
    label
    menu
    menu_bar
    menu_item
    popup
    slider
    window
    int_item
    editor
    text
    text_item
    picture
    etc.

    Cada uno de estos objetos como vimos en el ejemplo primeraVentana se alamcenan en variable por intuicion podemos concluir que para agreagar un boton a una ventana primero crearemos ambos objetos y despues agregaremos la variable de un boton a la variable de la ventana.

    Todos estos objetos tienen atributos como:
    size
    display
    margin
    colour
    style
    background
    font
    etc.

    Explicare algunos Objetos con mayor detalle:

    DIALOG
    Esta es la clase básica para crear dialogos.
    Constructor:
    dialog(label=[name], size=[size], display=[display])
    name: indica el titulo a la ventana
    size: es de tipo size y sirve para indicar el tamaño de la ventana display: indica donde queremos que se visualize (mejor no tocar este parametro si no sabemos que estamos haciendo) Podemos observar que todos los parametros son opcionales, aunque siempre es bueno ponerle un titulo a la ventana Así, como ejemplo crearemos un dialogo con titulo ‘Titulo del dialogo’ y de tamaño 440 x 320.
    new(D, dialog(‘Titulo del Dialogo’, size(440, 320)) ),
    Métodos:
    Esta clase dispone de varios métodos que pueden resultar interesantes, entre ellos tenemos:
    append(Objeto): Insertaria el objeto Objeto dentro del dialogo, visualizandolo en
    el mismo, por ejemplo sirve para insertar un boton o cualquier otra cosa, como en el siguiente ejemplo:
    send(D, append(button(‘Boton 1’)))
    open(): abre la ventana de diálogo visualizandola en pantalla:
    send(D, open),
    destroy(): cierra la ventana de diá logo visualizada en pantalla:
    send(D, destroy),

    BUTTON
    Esta es la clase básica para crear botones
    Constructor:
    button(name=name, message=[code]*, label=[name] )
    name: indica el nombre del boton (si no se especifica la etiqueta que queramos que tenga el boton, entonces adoptará una etiqueta con el mismo texto que name)
    message: indica el mensaje o acción que queremos que sea ejecutado cuando pulsemos sobre el botón con el ratón.
    label: Indica la etiqueta que queremos que se muestre en el boton.
    new(Boton, button(‘Salir’, message(Dialogo, quit)))

    LABEL
    Esta es la clase básica para crear etiquetas de texto
    Constructor:
    label(name=[name], selection=[stringimage], font=[font])
    name: indica el nombre de la etiqueta
    selection: puede ser una cadena o una imagen que queremos que sea mostrada en el lugar donde aparece la etiqueta.
    font: permite indicar la fuente en la que queremos mostrar el texto
    new(L, label(nombre, ‘texto que queramos que sea mostrado’)),

    WINDOW
    Esta clase sirve para crear ventanas donde dibujar o poner otros objetos graficos
    Constructor:
    window(label=[name], size=[size], display=[display])
    name: indica el nombre de la ventana
    size: indica el tamaño que queremos tenga la ventana
    display: indica donde queremos que aparezca (recomendamos no usar este parametro)
    Por ejemplo para crear una nueva ventana (de gráficos) de tamaño 320x200 pixels new(W, window(‘nombre ventana’, size(320, 200)),
    Métodos:
    Para esta clase nos interesarán básicamente los métodos ‘display’ y ‘flush’: display(figure, point): sirve para mostrar una figura en un lugar determinado de la ventana una determinada figura (que por ejemplo puede ser una imagen) y point que indicará las coordenadas (x,y) de la ventana donde queremos que se muestre.
    El siguiente ejemplo mostraría la figura Figure en la posicion (22, 32) de la ventana W.
    send(W, display, Figure, point(22,32))
    flush(): sirve para redibujar la venana que invoca al método, es decir, si estamos realizando una serie de llamadas y no está en el bucle principal de la ventana, entonces podemos llamar a este método para redibujar la ventana y los elementos que hayamos creado o movido.
    send(W, flush)

    Otros predicados y funciones importantes serian:
    timer: new( timer(0.2,'Aqui lo que se ejecutaro cad cierto tiempo')

    declarar variables globales: :- pce_global(@'aquinombre varglobal', new('objeto que sera global')).

    ubicacion de objetos dentro de otro objetos: right ,below ,next_row

    para cambiar forma de cursor: new(cursor('nombre del nuevo cursor')

    para retornar y esperar confirmacion de un objeto: return confirm

    para ejecutar predicados con parametros : message,?selection ejemplo-> message(@prolog, nombrepredicado, TI?selection)

    retrazar una ejecucion: sleep(10)

    etc.

    Manejo de eventos:
    Para manejar los eventos de mouse como los de teclado aqui les dejo su estructura .
    Para mouse:
    click_gesture

    Para teclado:
    key_binding

    Algunos eventos:
    handler
    handler_group
    key_binding
    click_gesture
    connect_gesture
    move_gesture
    move_outline_gesture
    resize_gesture
    resize_outline_gesture

    Manejo de imagenes :
    swi-prolog te permite manejar diferentes formatos de imagenes como por ejemplo JPEG, GIF, BMP y PNM.
    Para utilizar las imagenes primero tenemos que indicar el directorio en donde se encuentran

    :-pce_image_directory(‘direccion de la carpeta de imagenes ’)

    despues procedemos a seleccionar el nombre de la imagen:

    resource(fondo, image, image(‘nonbre de la imagen’)).

    Para poder mostrar la imagen fondo en un dialogo primero debemos primero debemos pasar la imagen a Bitmap para luego si mostrarla en el dialogo o ventana.
    Para mover imagenes tenemos los siguientes atributos:

    send(Figure, move, point(X, Y)).
    send(Figure, relative_move, point(X, Y)).

    Las imagenes se comportan igual que cualquier objeto visto anteriormente y se les puede agregar eventos de mouse como de teclado.

    Funciones para un entorno grafico:
    La principales funciones para dibujar con swiprolog serian:
    arrow
    bezier
    bitmap
    box
    circle
    ellipse
    arc
    line
    path
    text
    etc.

    Creacion de ejecutables swi-prolog:
    A continucaion un codigo para crear ejecutables :

    save(Exe):- pce_autoload_all, qsave_program(Exe,[ emulator(swi('bin/xpce-stub.exe')), stand_alone(true), goal(main) ]).

    Descargar ejecutables que desarrolle para el curso de programacion logica en swi-prolog:
    Tan solo debo hacerles recordar que los ejecutables de swi-prolog no son tan buenos como quisieramos pues su ejecucion se hase un poco pesada.
    Para ejecutar algun ejecutable primero descargar la carpeta Bin dentro de ella deberan de poner los ejecutables y posteriormente daran doble click sobre cada uno respectivamente.

    Descargar Carpeta Bin

    Descargar Tres raya swi-prolog
    Descargar Snake swi-prolog
    Descargar Sistema Experto swi-prolog
    Descargar Damas swi-prolog
    Descargar Automata-redPetri swi-prolog
    Descargar Tetris swi-prolog


  6. Archivos y Bases de datos en swi-prolog:
    Para archivos seria:
    Escritura: tell(achivo.txt'), write(primero.'), nl, write('segundo.'), nl, told.
    Lectura: see('archivo.txt'), read(P), read(S).

    Para base de datos mysql swi-prolog le dejo un pdf ojala les sea de utilidad:

    Tutorial mysql con swi-prolog

  7. Conectar Java con swi-prolog:
    Los pasos serian en si los siguientes:
    agregar alas variables de entorno del sistema operativo los siguientes direcciones talvez las direcciones no son las mismas buscar y poner la direccion indicada de cada uno si no conecta reiniciar la maquina o volver a intentar todo de nuevo.

    path=C:\Archivos de programa\Java\jdk1.5.0_09\bin;%path%
    path=C:\Archivos de programa\Java\jdk1.5.0_09\lib\tools.jar;%path%
    path=C:\Archivos de programa\Java\jdk1.5.0_09\jre\lib\rt.jar;%path% path=C:\Archivos de programa\pl\bin;%path%
    path=C:\Archivos de programa\pl\lib\jpl.jar;%path%

    Aqui les dejo un codigo de java-swiprolog que se encuentra en la ayuda de swi-prolog . Tambien lo pueden encontrar en C:\Archivos de programa \pl\doc\packages\ examples \jpl \java\Family
  8. Descagar codigo de Family

    Tambien unos ejemplos que encontre en internet para la coneccion java con swi-prolog
    ojala les sea de utilidad (son de calculadora y tictactoe).

    Descargar Ejemplos java con swi-prolog


  9. Sockets en swi-prolog:
    Para el manejo de sockets en swi-prolog ai les dejo un codigo que encontre y me sirvio , ojala les ayude a comprender un poco mas sobre este tema de sockes :

    %--------------Servidor.pl-----------------------
    server(Port):- tcp_socket(Socket), tcp_setopt(Socket, reuseaddr), tcp_bind(Socket, Port), tcp_listen(Socket, 0), tcp_open_socket(Socket, InStream, _OutStream), add_stream_to_pool(InStream,get_requests_from_clients(Socket)), stream_pool_main_loop.
    get_requests_from_clients(Socket):- trim_stacks, tcp_accept(Socket, ClientSocket, ClientIP), tcp_open_socket(ClientSocket, InStream, OutStream), add_stream_to_pool(InStream,get_request(InStream,OutStream,ClientIP)).
    get_request(InStream,OutStream,_ClientIP):- catch( read(InStream, Request), _, (writeln(error1), close(InStream), close(OutStream),delete_stream_from_pool(InStream), fail) ),
    close(InStream),
    ( Request==end_of_file -> ( writeln(error2),close(OutStream), delete_stream_from_pool(InStream),fail) ; true ),
    process(Request,Answer),
    catch( (write_canonical(OutStream, Answer), write(OutStream, '.\n')), _, (writeln(error3), close(OutStream), delete_stream_from_pool(InStream),fail) ),
    close(OutStream),
    delete_stream_from_pool(InStream).
    get_request(_InStream,_OutStream,_AgentIP).
    process(Message,test_ok(Message)).
    :-prolog_ide(thread_monitor), thread_create(server(4000),_, [alias(server),detached(true)]).


    %------ ------Clientes.pl ---------------
    create_clients:- between(1,8,N), term_to_atom(client(N),Client), thread_create(client(N), _, [alias(Client),detached(true)]), fail.create_clients.
    client(N):- Port is 4000+N, between(0,10000,F), sleep(0.0001), once( request(client(ip(127,0,0,1),Port), server(ip(127,0,0,1), 4000),hello_world(F)) ), fail.client(N):- writeln(client_finished(N)).
    request(client(_ClientIp,ClientPort), server(ServerIp,ServerPort),Message):- tcp_host_to_address(Host,ServerIp),
    repeat, tcp_socket(Socket), tcp_setopt(Socket, reuseaddr),
    catch( tcp_connect(Socket, Host:ServerPort), _, (writeln(error(ClientPort,' Client cannot tcp_connect.')),tcp_close_socket(Socket),fail) ),
    tcp_open_socket(Socket, ReadFd, WriteFd),
    catch( (write_canonical(WriteFd,Message), write(WriteFd, '.\n')), _, ( writeln(error(ClientPort,' Client cannot tcp_connect.')),tcp_close_socket(Socket),fail) ),
    close(WriteFd),
    wait_for_input([ReadFd], [ReadFd], 0),
    catch( read(ReadFd,Answer), _, ( writeln(error(ClientPort,' Client cannot tcp_connect.')), close(ReadFd),fail) ),
    close(ReadFd),
    writeln(answer(ClientPort,Answer)).
    :-create_clients.

38 comentarios:

Jorge Carlos dijo...

Saludos gran osciest (Y) congratulations por tu blog, y empiezas con un pequeño tutorial de Swi Prolog, del cual hay muy poca información (Y)...exitos brother

Luis Enrique Hilario Esteban dijo...

man te ubique por la pagina de la seccperu.org, te felicito man, io aprendí programacion logica via turbo prolog, parecida a DOS por un profe de La UPAO, se llama Walter SAgastegui... voy a poner a practikar man...

Maria dijo...

Some of the linsk to Prolog programs are invalid. Could you please post the correct linsk or mail me the sources?

Cheers,
Maria

Patri dijo...

Muy buena info, te escribo porque puede ser q me ayudes a salucionar mi problema. Uso el swi-prolog con el edito jprologeditor y me sale este error al consultar
ERROR: toplevel: Undefined procedure: street/1 (DWIM could not correct goal)
nose q es lo q pueda ser, ya implemente alguna de las soluciones q encontre, pero sigo igual. Agradecere tu ayuda.

Patri dijo...

Holas, gracias por responder en mi blog, me gustaria saber si podes instalar con los pasos que señalo en el post, y me comentas si surge el mismo error.

alicia dijo...

Hola me gustaria tener acceso a la aplicacion del sistema experto en swi prolog pero el link no carga.

Oscar Enrique Fernandez Asuncion dijo...

Hola Alicia mils disculpas creo que no lo subi o direccione mal el link acomodare ese problema en el transcurso delos dias cualquier cosa me escribes osciest@gmail.com

Anónimo dijo...

muy buena info es muy util saludos sigue asi amigo

Anónimo dijo...

Hola saludos...
espero me puedas ayudar mira estoy haciendo un detector de fallas automotrices en swi prolog lo que pasa que se muy poco y me gustaria saber si me puedes ayudar te dejo mi correo arias_v@hotmail.com, o donde mas te puedo contactar. me llamo felipe arias.

Beatriz dijo...

Al principio tuve problemas para entrar al blog, te felicito esta muy bueno tengo una pregunta con interfaces en XPCE para mostrar textos grandes pues el label y text solo permite mostrar cierto numero de line, me sugerieron adicionar varios label, pero si sabes de un objeto o algo donde no haya que partir el texto mi email es betmanujua@gmail.com

Gisela dijo...

Hola Mi nombre es Gisela y tengo que realizar un sistema experto, me podrias ayudar? ya que recien estoy empezando con este lenguaje y me esta costando entenderlo, espero tu respuesta y disculpa la molestia, mi mail es gisela_boca@hotmail.com, desde ya muchas gracias.

Saludos, Gisela

Bárbara dijo...

Hola, mi nombre es Bárbara,tengo 26 años,soy argentina.Muy buena la info, te cuento:tengo q hacer mi tesis(Sistema Experto) para UNNE, lo iva a hacer en Visual prolog, pero resulta q la version q se consigue de internet,es una version educativa y no permite generar el ejecutable, hasta donde se no permite su compilación. En la facu tengo q entregar el programa conpilado con su ejecutable. Por tal motivo tengo, desearia poder hacerlo en un lenguje libre, como los es swi-prolog, desearia poder charlar con vos on-line, tal ves te inerese lo q deseo proponerte, desde ya muchas gracias. Mi correo es:barbara_katherina@hotmail.com

Marcos dijo...

Tus ejecutables estan impresionantes muy buenos no sabia que se podia hacer eso en prolog .

juajo dijo...

hola felicidades por tu pagina esta muy completa soy juan jose de Nicaragua estoy diseñando un sistema experto de diagnostico de enfermedades si me puedes dar algun proyecto de algo parecido que tengas te lo agradeceria mucho

Valeria dijo...

Hola!, primero que nada quería felicitarte por tus trabajos y por toda la información que publicaste :)...aprovechando tu experiencia quería consultarte algo, que quizás sea pavo, necesitaría desde SWI-Prolog conectarme a un servidor a través de OAI PMH, donde las consultas se hacen a través de la url, entonces lo que quiero es poder acceder a esa dirección y como la información de esa página (la respuesta a la consulta) está en código XML utilizaría el parser y directamente trabajaría con esa información, pero el predicado para "parsear" load_xml_file(+File, -ListOfContent), trabaja con un archivo local (+File), y yo necesitaria acceder a una direccion web, una url. Resumo: necesitaría acceder a una url desde prolog. Y no se que predicado puede ser. Perdón si no fui muy clara en mi pregunta, desde ya muchas gracias por tu respuesta. Valeria.

Oscar Enrique Fernandez Asuncion dijo...

Valeria segun entiendo tu quieres leer la informacion de una pagina web .XML para cargarla a prolog y es verdad load_xml_file solo lee a un archivo local al igual que load_html_file PERO PARA RESPONDER TU PREGUNTA DEBES HACER LO SIGUIENTE DEBES LEER PRIMERO LA PAGINA Y DESPUES UTILIZAR load_xml_file . EJEMPLO:

http_open(Direccion, Stream, []),
load_html_file(Stream, Tokens),

espero solucione tu problema (y).

Valeria dijo...

Si, Oscar era eso mismo que me escribiste, ese dia que te escribí estuve buscando información y encontré una explicación sobre la libreria http, muchisimas gracias por tu tiempo, por responderme, gracias por todo!...Valeria.

Anónimo dijo...

Hola, tengo que hacer un trabajo de un sistema experto. En mi caso se trata de ir preguntando posibles características de los móviles para que recomiende uno. La estructura, por tanto es muy parecida al del sistema experto de enfermedades de conejos y tengo que hacer una interfaz gráfica, ¿sería posible que me mandaras el código? mi email es eli85_elle@hotmail.com
Un saludo!

Roberto dijo...

Oscar muy buen post, una pregunta hermano: como hago para ejecutar la regla que me genera el archivo ejecutable de mi archivo prolog?

Oscar Enrique Fernandez Asuncion dijo...

roberto segun entiendo quieres correr la regla que has creado verdad? bueno si es asi escribes el nombre de la regla en consola y despues "." despues enter y listo

Roberto dijo...

Oscar, use la misma regla que pusiste de ejemplo pero adaptada a mi codigo:

save(anemia):-
pce_autoload_all,
qsave_program(anemia,[ emulator(swi('bin/xpce-stub.exe')),
stand_alone(true), goal(main) ]).

% donde main es mi regla principal y anemia es como quiero que se llame mi exe... mi archivo es interfaz .pl
El problema es que al correrlo en la consola me genera un exe pero me da un error de que falta un dll

Oscar Enrique Fernandez Asuncion dijo...

Lo que pasa es que debes agregar la carpeta bin de la carpeta PL que esta en el c:\\ al path del sistema (inicio -Mi PC- click derecho -opciones avanzadas- variables de entono-busca en variables del sistema el path ) si no quieres asi solo copia tu .exe en la carpeta bin y doble click (por eso en mis ejecutables sugiore que bajen la carpeta bin).
Espero solucione tu problema

Anónimo dijo...

Hola Oscar soy Laura no se si me podrias ayudar con un sistema de diagnostico de enfermedades del naranjo ya tengo mi red semantica y red bayesiana pero me falta realizarlo en prolog , podrias darme tu correo para que pueda enviarte la red semantica, he visto que manejas muy bien pantallas en prolog si fuera posible este sistema de diagnostico seria con pnatallas en Prolog. Si no tienes tiempo podrias enviarme el codigo de tu sistema de conejos para que me guie por favor. desde ya muchas gracias..aahh mi correo es laura_rodrigues26@hotmail.com

Anónimo dijo...

hey que ondas tu blog me parecio muy interesante y me ayudaste mucho a entender programacion logica, soy margarita estudio en uruguay y estoy tratando de hacer el juego de cuatro en fila o cuatro en raya en prolog si me pudieras ayudar te agradeceria.Besos.

margarita_em2@hotmail.com

Rebeca dijo...

Estoy en 5º de Ingenieria Informàtica en la Universidad Jaume I de Castellón, España. Me he quedado muy sorprendida de tu blog y creo que voy a utilizarlo mucho a partir de ahora. Muchas gracias por tu aportación. Rebeca

Rainer dijo...

Oscar una ayudita soy nuevo con prolog necesito imprimir la salida de un predicado en un archivo este es elcaso.
involucrado(niño).
actividad(real).
delito(X,Y):-involucrado(X),actividad(Y).
%hago la consulta
delito(niño,real).
true

lo q necesito es imprimie la salida de este predicado en un archivo en disco, o sea el true deberia imprimir en un archivo en disco. Espero me puedas colaborar Salludos y gracias de antemano

Oscar Enrique Fernandez Asuncion dijo...

hola rainer para escribir en archivos seria:

involucrado(niño).
actividad(real).
delito(X,Y):- tell('guardado.txt'),% extension .txt o.doc etc
involucrado(X),
actividad(Y),
write(X),write(' -> '),
write(Y),write(' -> '),
write(yes),
told.

Anónimo dijo...

hola a todos...
agradezco mucho por la información me ha sido muy util para entender muchas cosas...
Quisiera ahcer una consulta soy nuevo en el uso de prolog usamos un programa llamado Visual Prolog el docente nos pidio hacer un jeugo llamado 4 en raya o conecta 4 pero nos dice que Visual Prolog no acepta graficos pero que debemos buscar la forma de hacerlo con este programa y además no nos da guia o explicación que realmente sirva para el desarrollo de esto... Agradezco me pudieran colaborar con alguna guia o ideas para ahcerlo o alguna documentacion Muchas gracias

Anónimo dijo...

Planteamiento problemático

Vas a ayudar a planear una comida de tres platos para un Seminario del Departamento de Informática. Los estudiantes y los profesores son de muy diversos países, y al chef le gustaría hacer la comida verdaderamente internacional: los tres platos/comidas (aperitivo, un plato principal y el postre) deberán proceder de países diferentes. Además, aplican las siguientes reglas:
1. La comida debe incluir ya sea un plato chino o egipcio.
2. Si se elige un aperitivo indio, se debe elegir un postre de Corea.
3. Si se elige un plato chileno, no se puede servir ningún plato mexicano.
4. Si se elige un plato vietnamita, el plato principal debe ser chino.
5. Un plato coreano no se puede servir antes de un plato egipcio.
6. El aperitivo no puede ser chino.
7. Los alimentos egipcios y vietnamitas no son seguros juntos.
8. De todos los platos chilenos sólo vale la pena comer postres.
9. La comida de la India es mejor con un aperitivo de Corea. Esto implica que, además, la comida india no puede ser un aperitivo.
10. Los postres mexicanos no son muy grandes.
11. Si los alimentos chinos y coreanos se sirven juntos, más vale que el plato principal sea coreano.
12. Un plato principal mexicano y comida egipcia son los mejores seguido por el postre de Corea. Esto significa que: Un plato principal de México, cuando se sirve con aperitivo egipcio, necesita un postre de Corea.
13. La comida china y chilena debe tener un aperitivo de la India. Esto significa que si los alimentos chinos y chilenos se sirven juntos, se necesita un aperitivo de la India.
14. Un aperitivo de México debe tener un postre de Corea.
15. La comida chilena debe ser servida con un plato principal chino. Esto significa que el alimento chileno se sirve si y sólo si se sirve un plato principal chino. (Aquí hay una doble implicación: el plato principal chino implica un poco de comida chilena, y la comida chilena implica plato principal chino.)
Por favor, asiste a la planificación del chef de esta comida, proporcionando una función/predicado de Prolog comida(A, E, D), que devuelva todas las soluciones posibles a este problema. (Hay tres soluciones.) Podría ser una buena idea descomponer este problema en un conjunto de cláusulas, y probar cada cláusula por separado. Esto es mucho más fácil que tratar de escribir una declaración gigantesca.

El predicado comida(A, E, D) producirá "Sí" si se le da un conjunto correcto de opciones de comida, y "No" para un conjunto que no es deducible o bien que no es correcto.

patrik dijo...

Planteamiento problemático

Vas a ayudar a planear una comida de tres platos para un Seminario del Departamento de Informática. Los estudiantes y los profesores son de muy diversos países, y al chef le gustaría hacer la comida verdaderamente internacional: los tres platos/comidas (aperitivo, un plato principal y el postre) deberán proceder de países diferentes. Además, aplican las siguientes reglas:
1. La comida debe incluir ya sea un plato chino o egipcio.
2. Si se elige un aperitivo indio, se debe elegir un postre de Corea.
3. Si se elige un plato chileno, no se puede servir ningún plato mexicano.
4. Si se elige un plato vietnamita, el plato principal debe ser chino.
5. Un plato coreano no se puede servir antes de un plato egipcio.
6. El aperitivo no puede ser chino.
7. Los alimentos egipcios y vietnamitas no son seguros juntos.
8. De todos los platos chilenos sólo vale la pena comer postres.
9. La comida de la India es mejor con un aperitivo de Corea. Esto implica que, además, la comida india no puede ser un aperitivo.
10. Los postres mexicanos no son muy grandes.
11. Si los alimentos chinos y coreanos se sirven juntos, más vale que el plato principal sea coreano.
12. Un plato principal mexicano y comida egipcia son los mejores seguido por el postre de Corea. Esto significa que: Un plato principal de México, cuando se sirve con aperitivo egipcio, necesita un postre de Corea.
13. La comida china y chilena debe tener un aperitivo de la India. Esto significa que si los alimentos chinos y chilenos se sirven juntos, se necesita un aperitivo de la India.
14. Un aperitivo de México debe tener un postre de Corea.
15. La comida chilena debe ser servida con un plato principal chino. Esto significa que el alimento chileno se sirve si y sólo si se sirve un plato principal chino. (Aquí hay una doble implicación: el plato principal chino implica un poco de comida chilena, y la comida chilena implica plato principal chino.)
Por favor, asiste a la planificación del chef de esta comida, proporcionando una función/predicado de Prolog comida(A, E, D), que devuelva todas las soluciones posibles a este problema. (Hay tres soluciones.) Podría ser una buena idea descomponer este problema en un conjunto de cláusulas, y probar cada cláusula por separado. Esto es mucho más fácil que tratar de escribir una declaración gigantesca.

El predicado comida(A, E, D) producirá "Sí" si se le da un conjunto correcto de opciones de comida, y "No" para un conjunto que no es deducible o bien que no es correcto.

Anónimo dijo...

hola me gustaria que alguien me ayudara a compilar un trabajo sobre SISTEMA EXPERTO TEST DE ORIENTACIÓN VOCACIONAL PARA LA COMPUTACIÓN hay archivos con extencion dia y no se como compilarlo por favor mi email es:
mirive121@hotmail.com

Anónimo dijo...

Hola:
Estoy haciendo un programa en Swi-prolog, pero al hacer qsave_program en el archivo se generan símbolos y me borra mi programación, no sé si me puedan ayudar a corregir mi problema, ya que realmente no sé cómo se utiliza un qsave_program...

Gracias...

Pd: me urge..., porfa!

Anónimo dijo...

hola
Oscar, me fue de gran ayuda la informacion que esta en tu blog. estoy empezando a utilizar swi prolog,me gustaria compartir ideas contigo,xfa me podrias proporcionar tu correo mucha gracias.

Anónimo dijo...

excelente! magistral! tanto que había buscado una información detallada acerca de prolog..
infinitas gracias.. =')

Anónimo dijo...

oscar a simple vista se ve que sabes basante de prolog y necesito saber como se puede enlazar un dialog con otro con un simple boton,gracias.

felipe dijo...

hola ingeniero oscar, te escribo por el algoritmo de triangulacion de delaunay, yo esty tratando de implementar dicho algoritmo en mi tesis pero me he encontrado con al dificultad sobre todo en encontrar las formulas matematicas que sustente el codigo, mi duda es saber el codigo, peus yo tengo mi nube de puntos en una matriz y quiero aplicar ese algoritmo pero hasta ahora sole he encontrado la formula del signo del determinante d euna laista de ptos p y quue si es positivo cumple con la condicion, ahora bien agradeceria si pudieses ayudarme con el codigo para adaptarlo al mio muchas gracias mi correo es felipes177@hotmail.com

Anónimo dijo...

hola que mas ingenierio oscar mi nombre es luis estoy haciendo una conexion de prolog con mysql o cualquier otra base de datos para que prolog consulte pero no he encontrado, usted coloco un link al respecto pero ese link no sirve favor le pido me colabore es de mucha importancia gracias.

Anónimo dijo...

hola que mas ingenierio oscar mi nombre es luis estoy haciendo una conexion de prolog con mysql o cualquier otra base de datos para que prolog consulte pero no he encontrado, usted coloco un link al respecto pero ese link no sirve favor le pido me colabore es de mucha importancia gracias.