Jump to content
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

Sign in to follow this  
TheOne

Interligar C e Prolog

Recommended Posts

TheOne

Boas, desta vez é um trabalho para a universidade. Preciso de fazer uma parte de IA para um jogo e tem de ser feito em Prolog. Mas para começar tenho de dar ao Prolog uma string para que ele possa fazer a busca em espaços de dados (a string contém um mapa).

Como é que eu passo ao Prolog um argumento? E depois o contrário, do Prolog para o C?

Já tenho os .h, .def e tudo o que é necessário para efectuar a ligação, apenas preciso de saber em termos de código.

Obrigado :)

Share this post


Link to post
Share on other sites
merlin3000

Já experimentas-te com o LPA Win-Prolog? A experiência que tenho de ligação é com C# mas as instruções do manual também incluem ligação a C.

A ligação depois funciona por chamadas em C que executam comandos em prolog, uma maneira de passar argumentos pode ser fazeres o assert de factos. Ou obrigá-lo a fazer consults de fiheiros criados por ti.

Edit: Link do manual http://www.lpa.co.uk/ftp/4800/int_ref.pdf


Criar é Divertido

Share this post


Link to post
Share on other sites
zecapistolas

Eu neste semestre fiz um trabalho que englobava duas cadeiras, Programação em Lógica (ProloG) e Laboratórios de Aplicações de Software (C/C++ e OpenGL)....

E para isso tiver que fazer a tal interligação do ProloG com C++, que tu desejas....  :cheesygrin: Essa ligação é feita através de socket's, o C++ envia para o ProloG uma mensagem (em formato string) e o ProloG trata essa mensagem, e delvolve também uma mensagem ao C++....

O que tu precisas é o seguinte, criar um servidor no ProloG (utilizando para isso o SICStus Prolog) e criar o cliente em C++....

Então aqui vai.....  :)

Cliente.h

#pragma comment(lib, "ws2_32.lib")

#ifndef _WINDOWS_
#include <winsock2.h>
#endif

#include <stdio.h>
#include <string.h>	// for memcpy()...
#include <stdlib.h>	// for atoi()...
#include <ctype.h>	// for tolower()...

#define BUFS	1024
#define NAMS	64

// Helper macro for displaying errors
#define perror(s)	\
fprintf(stderr,"\n%s %d\n", s, WSAGetLastError())

class Cliente
{
WORD wVersionRequested;	// request Winsock 1.1
WSADATA wsaData;
SOCKET sock;
struct sockaddr_in server;
struct hostent *hp;
char buf[bUFS];

public:
Cliente(int porta, char* hostname);
~Cliente(void);
void send_data(char* dados);
char* receive_data();
};

Cliente.cpp

#define _CRT_SECURE_NO_WARNINGS

#include "Cliente.h"

Cliente::Cliente(int porta, char* hostname)
{
wVersionRequested = MAKEWORD(1,1);

// Initialize Winsockets
if (WSAStartup(wVersionRequested, &wsaData) == 0)	// allways needed
	printf("\nVersion allowed: %d.%d\n",
		LOBYTE(wsaData.wHighVersion),HIBYTE(wsaData.wHighVersion));
else
{
	fprintf(stderr,"\n Wrong version\n");
	WSACleanup();
	exit(1);
}

/* Create socket */
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == INVALID_SOCKET)
{
	perror("Opening stream socket");
	exit(1);
}
setbuf(stdout, NULL);	// do not buffer output - DEBUGING!!

/* Connect socket using server name indicated in the command line */
server.sin_family = AF_INET;
hp = gethostbyname(hostname);
if (hp == NULL)
{
	perror("Trying to get host by name");
	exit(2);
}
memcpy((char *)&server.sin_addr, (char *)hp->h_addr, hp->h_length);
server.sin_port = htons((short)porta);

if (connect(sock, (struct sockaddr *)&server, sizeof server) == SOCKET_ERROR)
{
	perror("Connecting stream socket");
	exit(1);
}
}

Cliente::~Cliente(void)
{
if (closesocket(sock) == SOCKET_ERROR)
	perror("Closing message socket");
}

void Cliente::send_data(char* dados)
{
if (send (sock, dados, strlen(dados)+1, 0) == SOCKET_ERROR)
	perror("Writing on stream socket");
}

char* Cliente::receive_data()
{
int nread;
memset((char*) buf, 0, sizeof(buf));
while ((nread = recv(sock, buf, BUFS, 0)) < 0);
return buf;
}

Coisas a colocar no ficheiro ProloG

:-use_module(library(sockets)).

port(60001).

force_close:-
        socket_bk(S), socket_close(S).

socket_bk(0).

server:-
        current_host(Host),
        port(Port),
        socket('AF_INET', Socket),
        socket_bind(Socket, 'AF_INET'(Host,Port)),
        socket_listen(Socket, 5),
        socket_accept(Socket, _Client, Stream),
        abolish(socket_bk/1),asserta(socket_bk(Socket)),
        server_loop(Stream),
        socket_close(Socket),
        write('Server Exit'),nl.

server_loop(Stream) :-
        repeat,
                read(Stream, ClientRequest),
                write('Received: '), write(ClientRequest), nl, 
                server_input(ClientRequest, ServerReply),
                format(Stream, '~q.~n', [serverReply]),
                write('Send: '), write(ServerReply), nl, 
                flush_output(Stream),
        (ClientRequest == bye; ClientRequest == end_of_file), !.

server_input(bye, ok):-!.
server_input(end_of_file, ok):-!.
server_input(_, invalid) :- !.

Agora no ficheiro ProloG só tens que criar predicados server_input que recebem uma mensagem e devolvem uma resposta, exemplo, server_input(+Mensagem, -Resposta). Dentro deste predicado vais chamar os predicados que já terás feito para o teu projecto...

Exemplo de um main.cpp

#include <iostream>
using std::cout;
using std::endl;

#include <string>
using std::string;

#include "Cliente.h"

// esta funcao recebe uma mensagem para enviar ao ProloG e devolve a resposta do ProloG já em string
string TrataSockets(string comando)
{
client->send_data(const_cast<char*>(comando.c_str()));
char * data = client->receive_data();

// Retira o ponto "." do buffer que veio dos socket's
string temp_string = data;
string sub = temp_string.substr(0, temp_string.size() - 2);

return sub;
}

int main(int argc, char* argv[])
{
// Cliente para fazer a comunicacao do C++ com os Sockets do ProloG
Cliente * client = new Cliente(60001, "127.0.0.1");

// supondo que foi criado o server_input("Ola_Mundo", Resposta).
string buffer = ""Ola_Mundo.";

string s = TrataSockets(buffer);

cout << s << endl;
return 0;
}

Agora, pá, experimenta e qualquer dúvida vou tentar ajudar....

cumps  :thumbsup:

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.