• Nenhum resultado encontrado

Programação em Lógica

N/A
N/A
Protected

Academic year: 2021

Share "Programação em Lógica"

Copied!
5
0
0

Texto

(1)

Faculdade de Engenharia da Universidade do Porto

Licenciatura em Engenharia Informática e Computação

Programação em Lógica

Época Normal – Com Consulta / Duração: 2h30m

2003/2004

3º Ano

LEIC

Nome:

Data:

19/01/2004

Tópicos de Resolução do Exame de PL de 19 de Janeiro de 2004.

Diversas sugestões de resoluções são apresentadas, contendo algumas, propositadamente, pequenos “Bugs” e sugestões de trabalho. Sugere-se a análise de todas as resoluções realizando rastreios apropriados de forma a compreende-las bem.

GRUPO I – Programação em Prolog (7 val.)

:-use_module(library(lists)).

país(alemanha, europa, 82, [frança, belgica, holanda, suica]). país(australia, oceania, 19, []).

país(belgica, europa, 10, [frança, holanda, alemanha]). país(espanha, europa, 40, [portugal, frança]).

país(frança, europa, 59, [espanha, suica, belgica, alemanha, italia]). país(holanda, europa, 15, [belgica, alemanha]).

país(indonesia, oceania, 210, []).

país(italia, europa, 57, [frança, suica]). país(madagascar, africa, 17, []).

país(portugal, europa, 10, [espanha]).

país(suica, europa, 7, [frança, alemanha, italia]). %1.1 a) pop_elevada(+Continente, -Lista).

pop_elevada(Continente, Lista):-

findall(Pop-Pais, (país(Pais, Continente, Pop, _), Pop>15), ListaIni), keysort(ListaIni, Lista).

% 1.1 b) isolados_grandes(Lista).

isolados_grandes(Lista):- findall(Cont,

(isolado_grande(Pais1, Cont), isolado_grande(Pais2, Cont) , Pais1\=Pais2), Lista1),

sort(Lista1, Lista). isolado_grande(Pais, Cont):-

país(Pais, Cont, Pop, Front), Pop>15, length(Front, L), L<3.

% Outra versão

isolados_grandes2(Lista):- findall(Cont,

(país(_,Cont,_,_),findall(Pais1, isolado_grande2(Pais1, Cont), L), length(L,N), N>=2),

Lista1), sort(Lista1, Lista). isolado_grande2(Pais, Cont):-

país(Pais, Cont, Pop, Front), Pop>15, length(Front, L), L<3. % 1.2 Função dos Cuts

% O Cut em Imaturo funciona como no predicado Not. Se X for adulto então (!, fail) não é % imaturo. Senão é imaturo. É’ um Cut Vermelho pois é essencial para o funcionamento do % programa.

% O Cut em adulto evita explorar espaço de pesquisa em que é impossível estar a solução. % Se X for uma pessoa, então só será adulto se tiver uma idade maior ou igual a 18. Só % se X não for uma pessoa é que se vai verificar se X é uma Tartaruga, ... É um Cut verde % pois não altera as soluções obtidas mas sim a eficiência do programa.

(2)

% 1.3 a) caminho(+NoInicio, +NoFim, -Lista), ligacao(1, 2). ligacao(1, 3). ligacao(2, 4). ligacao(3, 4). ligacao(3, 6). ligacao(4, 6). ligacao(5, 6). ligacao2(X,Y):- ligacao(X,Y). ligacao2(X,Y):- ligacao(Y,X).

caminho(NoInicio, NoFim, Lista):- caminho(NoInicio, NoFim, [NoInicio], Lista, 5). caminho(NoInicio, NoFim, Lista, ListaFim,_):-

ligacao2(NoInicio, NoFim),

append(Lista, [NoFim], ListaFim).

caminho(NoInicio, NoFim, Lista, ListaFim, N):- N>0,

ligacao2(NoInicio, NoInterm), NoInterm \= NoFim,

\+(member(NoInterm, Lista)), append(Lista, [NoInterm], Lista2), N2 is N-1,

caminho(NoInterm, NoFim, Lista2, ListaFim, N2).

% Outra versão. Sera' que funciona? Porque?

caminho2(NoIni, NoFim, Lista):- caminho2(NoIni, NoFim, Lista, 5). caminho2(_,_,_,0):- !,fail.

caminho2(NoIni, NoFim, [NoIni,NoFim], _):- ligacao2(NoIni,NoFim). caminho2(NoIni, NoFim, [NoIni|Rest], N):-

N2 is N-1,

ligacao2(NoIni, NoInt),

caminho2(NoInt, NoFim, Rest, N2). % Ainda outra Versão!

caminho3(NoIni, NoFim, Lista):- caminho3(NoIni, NoFim, Lista, 0). caminho3(NoIni, NoFim, [H|Rest], N):-

N < 4,

ligacao2(NoIni, NoInt),

(NoInt = NoFim, [H|Rest] = [NoIni, NoFim] ;

H = NoIni, N2 is N+1, caminho3(NoInt, NoFim, Rest, N2)).

% 1.3 b) ciclos(+No, +Comp, -Lista),

ciclos(No, Comp, Lista):-

findall(Ciclo, caminho(No, No, [], Ciclo, Comp), Lista).

% 2.1) divideN(+Lista, +N, -ListaN, -ListaR)

divideN(L, 0, [], L).

divideN([H|T], N, [H|T2], ListaR):-

N2 is N-1, divideN(T, N2, T2, ListaR).

% 2.2) opera_panquecas(+N, +Lista , -Lista_Res)

opera_panquecas(N, Lista, Lista_Res):-

divideN(Lista, N, ListaN, ListaResto), reverse(ListaN, ListaNInv),

append(ListaNInv, ListaResto, Lista_Res).

% 2.3) lista_ordenada(+N, -Lista)

lista_ordenada(N, Lista):- lista_ordenada(1, N, Lista). lista_ordenada(N, N, [N]) .

lista_ordenada(X, N, [X|T]) :- X1 is X+1,

(3)

% Outra Versão

lista_ordenada2(N, Lista):- lista_ordenada2(N, [], Lista). lista_ordenada2(0, Lista, Lista) .

lista_ordenada2(N, Resto, Lista) :- N2 is N-1,

lista_ordenada2(N2, [N|Resto], Lista). % Ainda outra Versão

lista_ordenada3(1, [1]) . lista_ordenada3(N, Lista) :-

N2 is N-1,

append(Lista2, [N], Lista), lista_ordenada3(N2, Lista2).

% 2.4) resolve_panquecas(+Lista, -Solucao, -Estados)

resolve_panquecas(Lista, Solucao, [Lista|Estados]):- length(Lista, N),

lista_ordenada(N, Final),

resolve_panquecas(Lista, Final, Solucao, Estados, []). resolve_panquecas(Final, Final, [], [], _).

resolve_panquecas(Lista, Final, [N|RestoOp], [Est|RestoEst], Est_Visit):- member(N, Lista),

opera_panquecas(N, Lista, Est), \+(member(Est, Est_Visit)),

resolve_panquecas(Est, Final, RestoOp, RestoEst, [Est|Est_Visit]).

% Versão 2

resolve_panquecas2(Lista, Solucao, Estados):- length(Lista, N),

lista_ordenada(N, Final),

resolve_panquecas2(Lista, Final, [], Solucao, [Lista], Estados). resolve_panquecas2(Final, Final, SolFinal, SolFinal, EstFinal, EstFinal). resolve_panquecas2(Lista, Final, Solucao, SolFinal, Estados, EstFinal):-

member(N, Lista),

opera_panquecas(N, Lista, Lista_Res), \+(member(Lista_Res, Estados)), append(Solucao, [N], NovaSol),

append(Estados, [Lista_Res], NovosEst),

resolve_panquecas2(Lista_Res, Final, NovaSol, SolFinal, NovosEst, EstFinal). % Versão 3 - Será que funciona? Porque?

resolve_panquecas3(Final, [], [Final]):- lista_ordenada(_, Final). resolve_panquecas3(Lista, [N|RestoOp], [Lista|RestoEst]):-

member(N, Lista),

opera_panquecas(N, Lista, Est),

resolve_panquecas3(Est, RestoOp, RestoEst), \+(member(Lista, RestoEst)).

% Versão 4 - Sem Backtracking (usando heuristica para resolver o problema) resolve_panquecas4(Final, [], [Final]):- lista_ordenada(_, Final).

resolve_panquecas4(Lista, [Op|RestoOp], [Lista|RestoEst]):- selectN(Lista, Op), !,

opera_panquecas(Op, Lista, Est), !,

resolve_panquecas4(Est, RestoOp, RestoEst). selectN(Lista, Pos):-

length(Lista, Size), reverse(Lista, Lista2),

get_pos(Lista2, Size, _, Pos).

get_pos([H|Resto], H, Elem, Pos):- H2 is H-1, get_pos(Resto, H2, Elem, Pos). get_pos(Lista, Elem, Elem, Pos):- search(Lista, Elem, Elem, Pos).

search([Elem], Elem, _, Elem). % Element is on top, put it on bottom search([Elem|_], Elem, PosF, PosF). % Element is not on top, get it to top

(4)

/*

% Predicados Auxiliares (library lists) append([], List, List).

append([H|Tail], List, [H|Rest]) :- append(Tail, List, Rest). member(Element, [Element|_]).

member(Element, [_|Rest]) :- member(Element, Rest). reverse(List, Reversed) :- reverse(List, [], Reversed). reverse([], Reversed, Reversed).

reverse([H|Tail], SoFar, Reversed) :- reverse(Tail, [H|SoFar], Reversed). */ % 3.1 :-use_module(library(clpfd)). puzzle([A,B,C]):- domain([A,B,C],1,50), domain([A1,B1],0,5), domain([A2,B2],0,9), A #= A1*10+A2, B #= B1*10+B2, B #= 2*A, C #= 10+B, A+B #> 10, A1 mod 2 #\= A2 mod 2, B1 mod 2 #= B2 mod 2, labeling([ff],[A,B,C]). % 3.2 a)

% NMP is NP*NM % Nove variáveis para o exemplo, representando a

% length(VarMaquina, NMP), % Quantidade produzida por cada máquina de cada produto

% domain(VarMaquina, 0, 50), % Dominio entre 0 e 50 (embora se pudesse reduzir…)

% length(VarProd, NP), % Podia-se adicionar a Quantidade produzida de cada produto

% domain(VarProd, 0, 150), % com Dominio entre 0 e 150 (podia-se reduzir…)

% Explicar isto mais detalhadamente % 3.2 b)

% Hard Constraints – Restrições Rígidas

% HC1: Não Produzir mais do que máximo de cada produto (explicar…)

% HC2: Horas de utilização das máquinas não ultrapassam o máximo (explicar)

% HC3: Quantidade Total de cada Produto igual à soma do produzido em cada maquina

% Esta restrição não é precisa (depende das variáveis utilizadas…)

% Soft Constraints – Restrições Flexíveis

% FC1: Lucro é igual à soma dos lucros das unidades de produtos produzidas. % Esta é a Função de avaliação a maximizar.

% Explicar isto mais detalhadamente % 3.2 c) :-use_module(library(clpfd)). produtos(3, [60,30,20]). maquinas(3, [500, 350, 150]). producao([[9,3,5], [5,4,20], [3,20,2]]). lucros([50, 20, 25]).

%Versão 1: Não totalmente genérica (80% Cotação…)

solve(VarProd, VarMaquina, Lucro):-

produtos(NP, MaxProd), % Leitura de Dados

maquinas(NM, Horas), producao(Producao), lucros(LucroProd), NMP is NM*NP,

length(VarProd, NP), % Variáveis e Domínios

VarProd = [P1, P2, P3], domain(VarProd, 0, 150), length(VarMaquina, NMP),

(5)

domain(VarMaquina, 0, 50),

maximo_produtos(VarProd, MaxProd), % HC1: Não Produzir mais do que

% máximo de cada produto

Horas = [HA, HB, HC],

Producao = [[PA1, PA2, PA3], [PB1, PB2, PB3], [PC1, PC2, PC3]],

A1*PA1+A2*PA2+A3*PA3 #=< HA, % HC2: Horas de utilização das máquinas

B1*PB1+B2*PB2+B3*PB3 #=< HB, % não ultrapassam o máximo

C1*PC1+C2*PC2+C3*PC3 #=< HC,

A1+B1+C1 #= P1, % HC3: Quantidade Total de cada Produto igual

A2+B2+C2 #= P2, % à soma do produzido em cada maquina

A3+B3+C3 #= P3,

scalar_product(LucroProd, VarProd, #=, Lucro),

% FC1: Lucro é igual 'a soma dos lucros dos produtos

maximize(labeling([ff], VarMaquina), Lucro). % Labeling. Pesquisa da solução. maximo_produtos([], []).

maximo_produtos([V|RProd], [Max|RMax]):- V #=< Max, maximo_produtos(RProd, RMax).

Referências

Documentos relacionados

O comando append pode ser usado para adicionar um valor específico ao final da lista, enquanto que o comando extend faz o mesmo para uma lista

Os dados serão adicionados no fim do arquivo (“append“) se ele já existir, ou um novo arquivo será criado, no caso de arquivo não existente anteriormente. • “rb“: Abre

A's nove e meia horas, presentes os juizes: ministros Eduardo Espinola e Carvalho Mourão, desembargadores José Linhares e Renato Tavares, doutores Affonso Penna Júnior, Prudente

Após o barramento, a vazão do açude regularizada mantém o efeito de molhe hidráulico do Rio Pacoti durante o ano todo, favorecendo a sedimentação na praia de

Em um estudo clínico aberto não comparativo requerendo baseline punções de sinosite transantral, os seguintes resultados foram as taxas de sucesso clínico as visitas no dia

Existem processos que podem apresentar estados que n˜ao acess´ıveis a partir de algum outro estado, isto ´e, a probabilidade de transic¸˜ao para tais estados ´e igual a zero..

Esse fator ainda carece de uma análise à parte, haja vista que a grande quantidade de dados para ele é também dados que constituem exemplos de genitivo (pois todo genitivo é

(4) A lista de produtos requerida pelo Regulamento (CEE) n.° 3924/91, denominada «lista Prodcom», comum a todos os Estados-Membros, é necessária para comparar os dados entre