-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathProjeto.pl
More file actions
112 lines (87 loc) · 3.83 KB
/
Copy pathProjeto.pl
File metadata and controls
112 lines (87 loc) · 3.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
maratonaFilmes(ListaFilmes, ListaRestricoes, Programacao):-
%Encontrar todas as sequencias que satisfazem as restrições
length(ListaFilmes, Tamanho),
Tamanho =< 7,
length(ListaEmpty, 7-Tamanho),
maplist(=('empty'), ListaEmpty),
append(ListaFilmes, ListaEmpty, ListaAtualizada),
% Predicado Auxiliar: Itera sobre a lista de restrições (Functores)
valida_restricoes([], _).
valida_restricoes([Restricao|Resto], Seq) :-
verifica(Restricao, Seq), % Intrepreta a restrição
valida_restricoes(Resto, Seq).
%terror(Filme):-
verifica(soPode(Filme, Sessao)):-
nth1(Sessao, Seq, FilmeNaSessao),
FilmeNaSessao \== Filme.
verifica(nunca(Filme,Sessao)):-
verifica(seguido(Filme1, Filme2), Seq):-
nth1()
% ==============================================================================
% 1. PREDICADO PRINCIPAL
% ==============================================================================
maratonaFilmes(ListaFilmes, ListaRestricoes, Programacao) :-
% setof recolhe todas as soluções (S), ordena-as e remove duplicados.
% Se não houver soluções, o setof falha, por isso usamos o (-> ; )
( setof(Seq, gera_e_testa(ListaFilmes, ListaRestricoes, Seq), Programacao)
-> true
; Programacao = [] % Se falhar, a lista de programação é vazia
).
% ==============================================================================
% 2. MOTOR DE GERAÇÃO E TESTE
% ==============================================================================
gera_e_testa(ListaFilmes, ListaRestricoes, Seq) :-
% A. PREPARAÇÃO: Garantir que a lista tem 7 elementos
length(ListaFilmes, Comp),
NumEmpties is 7 - Comp,
cria_lista_empty(NumEmpties, ListaEmpties),
append(ListaFilmes, ListaEmpties, FilmesComEspacos),
% B. GERAÇÃO: Criar uma permutação (uma tentativa de horário)
permutation(FilmesComEspacos, Seq),
% C. TESTE: Verificar se esta permutação cumpre TODAS as restrições
valida_restricoes(ListaRestricoes, Seq).
% Auxiliar: Cria uma lista com N átomos 'empty'
cria_lista_empty(0, []) :- !.
cria_lista_empty(N, [empty|T]) :-
N > 0,
N1 is N - 1,
cria_lista_empty(N1, T).
% Auxiliar: Itera sobre a lista de restrições (Functores)
valida_restricoes([], _).
valida_restricoes([Restricao|Resto], Seq) :-
verifica(Restricao, Seq), % Chama o predicado que "entende" o functor
valida_restricoes(Resto, Seq).
% ==============================================================================
% 3. REGRAS DE VERIFICAÇÃO (Functores)
% ==============================================================================
% TERROR: Só às 20h ou 23h.
% Sábado: sessões 3 (20h) e 4 (23h). Domingo: sessão 7 (20h).
verifica(terror(Filme), Seq) :-
nth1(Pos, Seq, Filme),
member(Pos, [3, 4, 7]).
% SOPODE: O filme tem de estar na posição exata 'Sessao'.
verifica(soPode(Filme, Sessao), Seq) :-
nth1(Sessao, Seq, Filme).
% NUNCA: O filme NÃO pode estar na posição 'Sessao'.
verifica(nunca(Filme, Sessao), Seq) :-
%Procura o filme da Sessao
nth1(Sessao, Seq, FilmeNaSessao),
FilmeNaSessao \== Filme. %O filme tem de ser diferente
% SEGUIDO: Filme2 logo após Filme1, NO MESMO DIA.
% Pares válidos: (1,2), (2,3), (3,4) [Sáb] e (5,6), (6,7) [Dom].
% O par (4,5) é inválido porque troca de dia.
verifica(seguido(Filme1, Filme2), Seq) :-
%Encontrar as sessões
nth1(P1, Seq, Filme1),
nth1(P2, Seq, Filme2),
P2 =:= P1 + 1, % Tem de ser matematicamente consecutivo
member(P1, [1, 2, 3, 5, 6]). % Exclui a sessão 4 (fim de Sábado) e 7 (fim)
% NAOSEGUIDO: Não podem ser vizinhos em lado nenhum.
verifica(naoSeguido(F1, F2), Seq) :-
\+ nextto(F1, F2, Seq),
\+ nextto(F2, F1, Seq).
% ANTES: F1 tem de aparecer antes de F2 (índice menor).
verifica(antes(F1, F2), Seq) :-
nth1(P1, Seq, F1),
nth1(P2, Seq, F2),
P1 < P2.