%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%% PROBLEMA 1
%% Def\'{\i}nanse, usando el lenguaje PROLOG, las siguientes operaciones:

%%%%%%%%%%%% A)
% {\tt sumList(L, S)}, donde {\tt S} es la suma de los elementos
% que componen la lista {\tt L} de n\'umeros. {\bf Deben emplearse} 
% par\'ametros  de acumulaci\'on en la soluci\'on de este apartado.%%\\[1ex]
% (0.75 puntos)
%%%%%%%%%%%%%%%%%%%%

sumList(L, S) :- sumlist(L, 0, S)

% sumlist(L, A, S)
% A es un par\'ametro de acumulaci\'on.
% Recorre la lista L y va sumando los elementos con el par\'ametro
% de acumulaci\'on (inicialmente a cero). Cuando se termina de recorrer
% la lista (la lista es vac\'{\i}a), S se enlaza con el valor del
% par\'ametro de acumulaci\'on.
sumlist([], A, A).
sumlist([N|Resto], A, S) :- NewA is N + A, sumlist(Resto, NewA, S).


%%%%%%%%%%%% B)
% {\tt brand(N)}, que obtenga los n\'umeros, {\tt N}, de Brandreth cuyo
% cuadrado tiene cuatro cifras. Esto es, los n\'umeros como el $45$
% cuyo cuadrado es $2025$, que si lo partimos en dos obtenemos los n\'umeros
% $20$ y $25$ cuya suma es, precisamente, $45$. (AYUDA: los n\'umeros N cuyo
% cuadrado es de cuatro cifras pueden generarse mediante una llamada
% al predicado  {\tt between(32, 99, N)}). (0.75 puntos)
%%%%%%%%%%%%%%%%%%%%


brand(N) :- between(32, 99, N), C is N * N,
		N1 is C // 100, N2 is C mod 100,
		N is N1 + N2.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%% PROBLEMA 3
%% Un diccionario binario es un \'arbol binario ordenado. En un diccionario  
% binario se cumplen las siguientes condiciones: 
% i) todos los nodos en el sub\'arbol izquierdo, son menores que la ra\'{\i}z; 
% ii) todos los nodos en el sub\'arbol derecho son mayores que la ra\'{\i}z; 
% iii) los sub\'arboles izquierdo y derecho son a su vez diccionarios binarios

%%%%%%%%%%%% A)
%	Dese una representaci\'on para los diccionarios binarios. (0.5 puntos)
%%%%%%%%%%%%%%%%%%%%
%
%%%%%%%%%%% REPRESENTACION PARA LOS ARBOLES BINARIOS
/*
	Un \'arbol binario es:
	1) Un \'arbol binario vac\'{\i}o que representamos por
	   el \'atomo:
			    nilTree
	2) o una hoja que representamos por el t\'ermino:
			    hoja(Hoja)
	donde Hoja toma valores entre los elementos de un dominio
	de discurso.
	3) o una \'arbol binario gen\'erico que representamos 
	por el t\'ermino:
			    arbol(Arbol1, Nodo, Arbol2)

	donde Arbol1 y Arbol2 son \'arboles binarios y Nodo toma 
	valores entre los elementos de un dominio de discurso.
	
V\'ease el libro de I.Bratko para una representaci\'on alternativa.
I.Bratko.
PROLOG: Programming for Artificial Intelligence.
Addison-Wesley, 1990.
*****************************************************************/

esArbolBinario(nilTree).
esArbolBinario(hoja(Hoja)) :- tipoElemento(Hoja).
esArbolBinario(arbol(Arbol1, Nodo, Arbol2)) :- 
	esArbolBinario(Arbol1),
	elemento(Nodo),
	esArbolBinario(Arbol2).

%%%% Este predicado habr\'{\i}a que definirlo seg\'un
%%%% fuese el dominio con el que se trabaja. 
%%%% Por simplicidad suponemos que trabajamos con enteros:
tipoElemento(E) :- integer(E).

%% TEST
obj1:- esArbolBinario(arbol(hoja(1), 
				2, 
				arbol(hoja(3), 
					4, 
				      hoja(5)
				)
			  )
		).


%%%%%%%%%%%% B)
% Def\'{\i}nase el predicado {\tt esDiccionario(O)} que permite determinar
% si un objeto {\tt O} es o no un diccionario binario. (1 punto)
%%%%%%%%%%%%%%%%%%%%
esDiccionario(nilTree).
esDiccionario(hoja(Hoja)):- tipoElemento(Hoja).
esDiccionario(arbol(nilTree, Nodo, ArbolR)):- 
			esDiccionario(ArbolR),
			menor(Nodo, ArbolR).
esDiccionario(arbol(ArbolL, Nodo, nilTree)):- 
			esDiccionario(ArbolL), 
			mayor(Nodo, ArbolL).
esDiccionario(arbol(ArbolL, Nodo, ArbolR)) :- 
			esDiccionario(ArbolL), 
			esDiccionario(ArbolR),
			mayor(Nodo, ArbolL), 
			menor(Nodo, ArbolR).

% mayor(X, Diccionario), es verdadero cuando X es mayor  
% que todos los elementos en los nodos del Diccionario

mayor(X, Diccionario) :- maxele(Diccionario, Max), X > Max.

% el predicado maxele se define en el apartado (C).

% menor(X, Diccionario), es verdadero cuando X es 
% menor  que todos los elementos en los nodos del Diccionario

menor(X, Diccionario) :- minele(Diccionario, Min), X < Min.

% el predicado {\tt minEle(D, E)} calcula el menor elemento, {\tt E},
% almacenado en el diccionario binario {\tt D}. 

minEle(D, E) :- esDiccionario(D), minele(D, E).

minele(nilTree, 0):- !.
minele(hoja(Hoja), Hoja):- !.
minele(arbol(nilTree, E, _), E):- !.
minele(arbol(ArbolL, _, _), E) :- minele(ArbolL, E).

%%%% TEST
obj2:- A = arbol(hoja(0), 2, arbol(hoja(3), 4, hoja(5))), esDiccionario(A).
obj22:- A = arbol(nilTree, 2, arbol(hoja(3), 4, hoja(5))), esDiccionario(A).
obj23:- A = arbol(nilTree, 2, arbol(hoja(3), 4, nilTree)), esDiccionario(A).


%%%%%%%%%%%% C)
% Def\'{\i}nase un predicado {\tt maxEle(D, E)} que calcula el mayor 
% elemento, {\tt E}, almacenado en el diccionario binario {\tt D}. 
%(0.5 puntos)
%%%%%%%%%%%%%%%%%%%%


maxEle(D, E) :- esDiccionario(D), maxele(D, E).

maxele(nilTree, 0):- !.
maxele(hoja(Hoja), Hoja):- !.
maxele(arbol(_, E, nilTree), E):- !.
maxele(arbol(_, _, ArbolR), E) :- maxele(ArbolR, E).
	
%% TEST
obj3(E):- A = arbol(hoja(1), 2, arbol(hoja(3), 4, hoja(5))), maxEle(A, E).

obj4(E):- A = arbol(nilTree, 2, arbol(hoja(3), 4, nilTree)), maxEle(A, E).


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%% PROBLEMA 4
%% Escr\'{\i}base un (fragmento) de programa Prolog que exprese, 
% mediante relaciones binarias, el conocimiento (expl\'{\i}cito) 
% almacenado en la red sem\'antica de la  Figura~\ref{fig-redSem}. 
% (1.25 punto)

% red_sem2.p
% Representacion de conocimiento utilizando redes semánticas
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
/* Implementación en PROLOG de la red semántica (ligeramente 
ampliada) que aparece en [Nilsson 87, pag.332]. Distinguimos en 
este ejercicio entre la relación de inclusión en un conjunto, 
"es" (también llamada "es_un" o "SUBC"), de la relación de 
pertenencia "en" (también llamada "instancia" o "ELEM") */

% conocimiento explicito en la red semántica
es(ev_dir, evento).
es(ev_ocu, evento).
es(ev_don, evento).

%%%
en(di1, ev_dir).
lugar(di1, mayor_n37).
persona(di1, juan).

%%%
en(oc1, ev_ocu).
trabajador(oc1, juan).
profesion(oc1, programador).


%%%
en(oc2, ev_ocu).
trabajador(oc2, maria).
profesion(oc2, abogado).

%%%
en(do1, ev_don).
dador(do1, juan).
receptor(do1, maria).
objeto(do1, libro).

%%%
en(juan, personas).
en(maria, personas).
en(mayor_n37, direcciones).
en(libro, objetos).
en(programador, tareas).
en(abogado, tareas).

% conocimiento implicito
en(X, B) :- es(A, B), en(X, A).
% herencia
pos(Hecho) :- Hecho,!. /*Hechos deducibles directamente de la red*/
pos(Hecho) :-          /*Inferencia de hechos por herencia*/
  Hecho =.. [Rel,Arg1,Arg2],
  (es(Arg1,SuperArg); en(Arg1,SuperArg)),
  SuperHecho =.. [Rel,SuperArg,Arg2],
  pos(SuperHecho).
  



