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

TheOne

Interligar C e Prolog

3 mensagens neste tópico

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 :)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

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....  :biggrin: 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:

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora