/*1.*/

p(X,Y) :- q(X),r(Y).
p(5,z).
q(1).
q(2).
r(a).
r(b).

/*(MRC) Deparas-te com o predicado insereOrd/3, tal que insereOrd(E, L1, L2)
(em que E é um inteiro e L1 e L2 são listas de inteiros ordenadas de forma ascen-
dente), significa que L2 é o resultado de inserir E em L1.*/

/*processo recursivo*/
insereOrd(N, [], [N]).
insereOrd(N, [H | T], [N, H | T]) :- N < H,!.
insereOrd(N, [H | T], [H | T1]) :-
            N >= H,
            insereOrd(N, T, T1),!.
/*The cut predicate ! is not requiered, if not present tries to search for another solution,
 it does not exist so you have to press enter*/

/*Example: ?- insereOrd(5, [1,2,3,6,9], L). */

/*Versao funcional*/
insereOrd1(N, L1, L2) :-
findall(E, (member(E, L1), E < N), Menores),
            append(Menores, Maiores, L1),
            append([Menores, [N], Maiores], L2).
/*?- insereOrd1(5, [1,2,3,6,9], L). */

/*Gerando um processo iterativo, implementa o predicado comp_maior_lista/2,
tal que comp_maior_lista(L, C), em que L é uma lista de listas, significa que o
maior comprimento das listas de L é C.*/
/*English: Determines the length of the longest list*/
/*The cut predicate ! is not requiered, if not present tries to search for another solution,
 it does not exist so you have to press enter*/

compMaiorLista([ H | T], C) :-
                    length(H, Comp),
                    compMaiorLista(T, Comp, C).
compMaiorLista([],C,C).
compMaiorLista([ H | T], CompAct, C) :-
                    length(H, Comp),
                    Comp > CompAct,
                    compMaiorLista(T, Comp, C),!.
compMaiorLista([H | R], CompAct, C) :-
                    length(H, Comp),
                    Comp =< CompAct,
                    compMaiorLista(R, CompAct, C),!.

/*?- compMaiorLista([[1,2,3,2], [1,3,1,3,4], []], C). 
  C=5.
  ?- compMaiorLista([[1], []], C). 
  C = 1.
?- compMaiorLista([[], []], C). 
  C = 0.
*/

/*numOcc(L, E, N)
significa que o elemento E ocorre N vezes na lista L.*/

numOcc(L, E, N) :- include(==(E), L, ListaEs), length(ListaEs, N).

/*substituiMaioresN(N, Subst, L1, L2), em que Lst1 é uma lista de inteiros e N é
um inteiro, significa que a lista L2 é o resultado de substituir todos os elementos
da lista L1 maiores do que N, por Subst. */
/*The cut predicate ! is not requiered, if not present tries to search for another solution,
 it does not exist so you have to press enter*/

substituiMaioresN(N, Subst, L1, L2) :-
                                    maplist(substituiMaioresNAux(N, Subst), L1, L2).
                                    substituiMaioresNAux(N, Subst, E, Subst) :- E > N,!.
substituiMaioresNAux(N, _, E, E) :- E =< N,!.    

