-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathfunctions.pl
More file actions
93 lines (84 loc) · 4.49 KB
/
Copy pathfunctions.pl
File metadata and controls
93 lines (84 loc) · 4.49 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
% Função para normalizar as entradas e saídas pro formato do dataset
% (sem espaços desnecessários nem letras maiúsculas).
normalizar(Entrada, Saida) :-
string_lower(Entrada, Baixa),
normalize_space(string(Saida), Baixa).
% Comparar os atributos de duas músicas, fazendo uma mini-clusterização
% ao pegar a distância dos dois.
similaridade(Id1, Id2, Dif) :-
song(Id1, _, _, _, _, Dance1, Energy1, Loud1, _, Speech1, _, Val1, _, _),
song(Id2, _, _, _, _, Dance2, Energy2, Loud2, _, Speech2, _, Val2, _, _),
Dif is abs(Dance1 - Dance2) + abs(Energy1 - Energy2) + abs(Loud1 - Loud2) + abs(Speech1 - Speech2) + abs(Val1 - Val2).
% Funções para retirar os elementos de uma lista e colocá-los em outra
% sublista.
take(0, _, []) :- !.
take(_, [], []) :- !.
take(N, [H|T], [H|Rest]) :-
N1 is N - 1,
take(N1, T, Rest).
% Função principal de recomendação
recomendar(Musica, Artista, Recomendacoes, ArtistasRecomendacoes) :-
song(Id, Artista, _, Musica, _, _, _, _, Mode, _, _, _, _, Genero),
% Compara a música recbida como parâmetro com todas do dataset de maneira bruteforce
% e roda uma função similaridades para ver a distância de cada elemento no conjunto universo.
findall(Dif-M-Artista2,
( song(Id2, Artista2, _, M, _, _, _, _, Mode, _, _, _, _, Genero),
Id \= Id2,
Artista \= Artista2,
similaridade(Id, Id2, Dif)
),
Similaridades),
% Os resultados são armazenados num vetor que é ordenado para que seja possível reitrar
% apenas as 5 principais. Depois, armazena-as em dois vetores para serem printadas.
( Similaridades \= []
-> sort(Similaridades, SimilaridadesOrdenadas),
length(SimilaridadesOrdenadas, Len),
( Len >= 5
-> take(5, SimilaridadesOrdenadas, Top5)
; Top5 = SimilaridadesOrdenadas
),
findall(M, member(_-M-_, Top5), Recomendacoes),
findall(A, member(_-_-A, Top5), ArtistasRecomendacoes)
; Recomendacoes = [],
ArtistasRecomendacoes = []
).
% Comando principal, pede uma musica e artista do usuário e lança como parâmetro
% para a função de recomendação. Depois, printa os resultados.
recomendar_musica :-
ansi_term:ansi_format([fg(cyan)],'Digite o nome da música: ', []), nl,
read_line_to_string(user_input, MusicaInput),
normalizar(MusicaInput, MusicaNormalizada),
ansi_term:ansi_format([fg(cyan)],'Digite o nome do artista: ', []), nl,
read_line_to_string(user_input, ArtistaInput),
normalizar(ArtistaInput, ArtistaNormalizada),
% Printa a primeira arte ASCII
write(' ,-. _,---._ __ / \\'), nl,
write(' / ) .-\' `./ / \\'), nl,
write('( ( ,\' `/ /|'), nl,
write(' \\ `-" \\\'\\ / |'), nl,
write(' `. , \\ \\ / |'), nl,
write(' /`. ,\'-`----Y |'), nl,
write(' ( ; | |''), nl,
write(' | ,-. ,\'-\' | /'), nl,
write(' | | ( | | /'), nl,
write(' ) | \\ `.___________| /'), nl,
write(' `--\' `--\''), nl,
( song(_, ArtistaTemplate, _, MusicaTemplate, _, _, _, _, _, _, _, _, _, _),
normalizar(MusicaTemplate, MusicaTemplateNormalizada),
normalizar(ArtistaTemplate, ArtistaTemplateNormalizada),
MusicaTemplateNormalizada = MusicaNormalizada,
ArtistaTemplateNormalizada = ArtistaNormalizada
-> recomendar(MusicaTemplate, ArtistaTemplate, Recomendacoes, ArtistasRecomendacoes),
( Recomendacoes \= []
-> ansi_term:ansi_format([fg(cyan)],'Aqui estão algumas músicas recomendadas baseadas em (', []),
ansi_term:ansi_format([fg(cyan)],MusicaTemplate, []), ansi_term:ansi_format([fg(cyan)],' - ', []), ansi_term:ansi_format([fg(cyan)],ArtistaTemplate, []), ansi_term:ansi_format([fg(cyan)],'):', []), nl,
print_recomendacoes(Recomendacoes, ArtistasRecomendacoes)
; ansi_term:ansi_format([fg(cyan)],'Nenhuma recomendação encontrada.', []), nl
)
; ansi_term:ansi_format([fg(cyan)],'Música ou artista não encontrados.', []), nl
).
print_recomendacoes([], []) :-
true. % Caso não haja músicas, não faz nada.
print_recomendacoes([Musica|RestMusicas], [Artista|RestArtistas]) :-
write('• '), write(Musica), write(' - '), write(Artista), nl,
print_recomendacoes(RestMusicas, RestArtistas).