Prolog observa a Prolog: inspección de estructuras 1/6 Unificacion VS comparación de términos Conocemos la unificación: T1 = T2 tiene éxito si T1 y T2 son unificables y en ese caso además los unifica. La unificación también se hace implı́citamente (sin el sı́mbolo =) al utilizar las clásulas de programa en la resolución. Por ejemplo, append([],Xs,Xs). ≡ append([],Xs,Ys):- Xs=Ys. Además si utilizamos esta cláusula para resolver: ?- append(As,Bs,Cs). Se unificará As = [], Cs = Bs Conocemos además predicados de comparación de términos: T1 == T2 tiene éxito si los términos T1 y T2 son sintácticamente idénticos (no hace ninguna unificación). Por ejemplo, X == Y falla. T1 \ == T2 tiene éxito si los términos T1 y T2 no son sintácticamente idénticos. Por ejemplo, X \ == Y tiene éxito. 2/6 Predicados aritméticos de comparación E1 =:= E2 tiene éxito si las expresiones aritméticas E1 y E2 se evalúan al mismo entero. Por ejemplo, 2 + 4 =:= 3 ∗ 2 tiene éxito. E1 = \ = E2 negación del anterior 3/6 Estructura de los términos. Tipos Los términos en Prolog tienen la siguiente clasificación: variables átomos Simples enteros constantes Términos números reales Compuestos 4/6 Estructura de los términos. Tipos De acuerdo a esta clasificación tenemos los predicados: atom/1: comprueba si el argumento es un átomo integer/1: comprueba si el argumento es un entero float/1: comprueba si el argumento es un real number/1: comprueba si el argumento es un número var/1: comprueba si el argumento es una variable nonvar/1: comprueba si el argumento no es una variable compound/1: comprueba si el argumento es compuesto Hay otros predicados útiles: ground/1: comprueba si el argumento es un término cerrado (sin variables) term variables(+Term,-List): devuelve en List la lista de variables que contiene el término Term (en orden de aparición y sin repeticiones) 5/6 Analizando la estructura de los términos functor(?Term,?Nom,?Ar)::= Term es un término construido con (el functor principal o raı́z) Nom y de aridad Ar. Por ejemplo: ?- functor(progenitor(juan,sara),N,Ar). N = progenitor Ar = 2 ?- functor(6,N,Ar). N = 6 Ar = 0 ?- functor([4,5],N,Ar). N = ’.’ Ar = 2 ?- functor(F,progenitor,2). F = progenitor( G232, G233) 6/6 Analizando la estructura de los términos II arg(?N,+Term,?Val)::= N se instancia a un valor entre 1 y la aridad del término Term y Val se instancia al argumento N-ésimo de dicho término. ?- arg(2,progenitor(juan,sara),V). V = sara ?- arg(N,progenitor(juan,sara),V). N = 1 V = juan ; N = 2 V = sara ?- arg(N,[a,b,c(6)],V). N = 1 V = a; N = 2 V = [b, c(6)] 7/6 Analizando la estructura de los términos II Uno de los predicados más útiles: ?Term =.. ?List List es una lista cuya cabeza es el functor de Term y los restantes elementos son los argumentos del término. <functor> (arg1 , . . . , argn ) | {z } Term = .. [<functor>, arg1 , . . . , argn ] | {z } List Este predicado se usa de modo reversible con frecuencia. 8/6 Analizando la estructura de los términos III ?- progenitor(juan,sara) =.. L. L = [progenitor, juan, sara] ?- f(a,b(d)) =.. L. L = [f, a, b(d)] ?- T =.. [f, a, b(d)]. T = f(a, b(d)) ?- [1,2] =.. L. L = [’.’, 1, [2]] 9/6 Ejemplos Definir el predicado: subTerm(+Term,-ST)::= obtiene en ST un subtérmino de Term subTerm(T,T). subTerm(T,S):- nonvar(T), T=..[ |Args], subTermLst(Args,S). subTermLst([X|Xs],S):- subTerm(X,S); subTermLst(Xs,S). ?- subTerm(f(X,g(a,g),T). X X X X X = = = = = G186 G186 G186 G186 G186 T T T T T = = = = = f( G186, g(a, g)) ; G186 ; g(a, g) ; a ; g 10 / 6 Ejemplos II Definir: incrementa(+T1,-T2)::= T2 es el término resultante de incrementar en 1 todos los subtérminos numéricos de T1 incrementa(T,T1):- number(T), !, T1 is T+1. incrementa(T,T):- atom(T),!. incrementa(T,T1):compound(T),!, T=..[N|Args], incrementaLst(Args,Args1), T1=..[N|Args1]. incrementa(T,T). incrementaLst([],[]). incrementaLst([X|Xs],[X1|Xs1]):- incrementa(X,X1), incrementaLst(Xs,Xs1). 11 / 6