Operadores Relacionais Aritmética em Prolog • Operadores aritméticos são considerados funtores – 2+5 é representado internamente como +(2,5) – Para ativar as operações é necessário usar o predicado IS: – Sintaxe: X is <expressão> onde X (variável) <expressão> (expressão aritmética) – calcula a expressão e instancia o resultado com a variável X ?- X is 1+2. X=3 ?- Y is 1+5*(4-2). Y=11 • Alguns operadores aritméticos que podem ser usados com is: X +Y X -Y X *Y X /Y X //Y (d iv is ã o in te ir a ) X ^ Y ( e x p o n e n c ia ç ã o ) -X X m od Y a b s(X ) e x p (X ) ln (X ) lo g ( X ) s in ( X ) c o s(X ) s q r t( X ) • E1 e E2 são expressões aritméticas, que são calculadas antes da aplicação do operador E1 > E2 E1 < E2 E1 >= E2 E1 =< E2 X is E1 calcula E1 e unifica o resultado com X E1 =:= E2 calcula E1 e E2 e testa igualdade E1 =\= E2 calcula E1 e E2 e testa desigualdade | ?- 2+1 < 6-2. yes | ?- 1+2 =:= 2+1. yes | ?- 1+2 =:= X. ! ---------------------------------------! Error 22 : Instantiation Error ! Goal : _13568 is _5986 Comparação entre termos • Predicado = (unifica termos) • Sintaxe: Termo1 = Termo2 onde ?Termo1 ?Termo2 • Retorna sucesso se os termos Termo1 e Termo2 unificam. ?- 5 = 5. yes ?- fred = fred. yes ?- X = Y X=Y ?- pai_de(joao,paulo) = pai_de(X,Y). X = joao Y = paulo ?- X = 2+5. X = 2+5 ?- X is 2+5. X=7 ?- 1+2 = 2+1. no ?- 1+2 =:= 2+1. yes • Predicado = = (verifica se dois termos são idênticos) • Sintaxe: Termo1 == Termo2 onde ?Termo1 ?Termo2 • Retorna sucesso se Termo 1 e Termo2 são idênticos. As variáveis NÃO são instanciadas. | ?- nome == nome. yes | ?- X == X. X=_ | ?- X == 5. No | ?- X = 5. X=5 | ?- X == Y. no | ?- pred(1) == pred(X). no | ?- pred(1) = pred(X). X=1 | ?- X = 2+1. X=2+1 | ?- X is 2+1. X=3 | ?- X == 2+1. no | ?- X =:= 2+1. ! --------------------------------------! Error 22 : Instantiation Error ! Goal : _36580 is _28994 • Predicado \= = (verifica se dois termos não são idênticos) • Sintaxe: Termo1 \= = Termo2 ?- X \= = Y. yes ?- X \= = 5. yes ?- X \= = X. no • Outras comparações: • Termo1 <op> Termo2 onde <op> = @>=, @>, @=<, @< • Comparam Termo1 e Termo2 sem calcular. | ?- 2+1 < 1+3. yes | ?- 2+1 @< 1+3. no | ?- 2 @< 1+3. yes | ?- aba @< c. yes | ?- 28 @< abc. yes Exemplos • Somar os elementos de uma lista numérica soma([ ],0). soma([Elem| Cauda], S) ;- soma (Cauda,S1), S is S1 + Elem. ?- soma([1,2,3,4,5,6], S). S = 21 • Contar o número de elementos de uma lista conta([ ],0). Conta([_| Cauda], N) :- conta(Cauda, N1), N is N1 + 1. ?- conta([1,2,3,4,5,6],C). C=6 • Eliminar todas as ocorrências de um elemento de uma lista del_todas(Elem,[ ],[ ]). del_todas(Elem, [Elem|Y], Z) :del_todas(Elem,Y,Z). del_todas(Elem,[Elem1|Y], [Elem1|Z]) :Elem \== Elem1, del_todas(Elem,Y,Z). ?- del_todas(a, [a,b,a,c],L). L=[b,c] • Retirar todas as repetições de uma lista retirar_rep([ ],[ ]). retirar_rep([Elem|Cauda],[Elem|Cauda1]) :del_todas(Elem,Cauda,Lista), retirar_rep(Lista,Cauda1). ?- retirar_rep([a,b,[a],c,b,x,p1,b,a,[a]],Resultado). Resultado=[a,b,[a],c,x,p1]. • Contar o número de ocorrências de um dado elemento no primeiro nível de uma lista conta_occor(Elem,[ ],0). conta_occor(Elem,[Elem|Y],N) :conta_ocorr(Elem,Y,N1), N is N1 + 1. conta_occor(Elem,[Elem1|Y], N) :Elem \== Elem1, conta_ocorr(Elem,Y,N). • Dada uma lista de números, separar em duas sendo uma com os positivos e o zero, e outra com os negativos separa([ ],[ ],[ ]). separa([X|Y],[X|Z],W) :-X >= 0, separa(Y,Z,W). separa([X|Y],Z,[X|W]) :- X < 0, separa(Y,Z,W). ?- separa([1,3,-5,0,-64,37,0,19,-53],P,N). P = [1,3,0,37,0,19] , N = [-5,-64,-53] ; No • Dada uma lista de números, separar em duas sendo uma com os positivos e outra com os negativos, descartando o zero separa_sz([ ],[ ],[ ]). separa_sz([X|Y],[X|Z],W) :-X > 0, separa_sz(Y,Z,W). separa_sz([X|Y],Z,[X|W]) :-X < 0, separa_sz(Y,Z,W). separa_sz([X|Y],Z,W) :- X = 0, separa_sz(Y,Z,W). ?- separa_sz([1,3,-5,0,-64,37,0,19,-53],P,N). P = [1,3,37,19] , N = [-5,-64,-53] ; no