/*
   persona(P,N,S)
   
   Predicado que comprueba si P es una persona con N años y sexo S

   Argumentos:
   + P:
	- Significado: nombre de persona
	- Tipo: entrada y salida

   + N:
	- Significado: número natural
	- Tipo: entrada y salida

   + S:
	- Significado: sexo {femenino, masculino}
	- Tipo: entrada y salida
*/

persona(patricia,9,femenino).
persona(laura,9,femenino).
persona(juan,9,masculino).

persona(teresa,8,femenino).
persona(pedro,8,masculino).
persona(laura,8,femenino).



/*
   buscar_por_edad(E,L)
   
   Predicado que comprueba L es una lista compuesta por personas con la edad E

   Argumentos:
   + L:
	- Significado: lista de personas
	- Tipo: entrada y salida

   + E:
	- Significado: número natural
	- Tipo: entrada y salida

  Variables locales
  + P:
	- Significado: nombre de persona

   + S:
	- Significado: sexo {femenino, masculino}

   Predicados relacionados
    persona, bagof
*/
buscar_por_edad(E,L):-
		bagof(P,S^persona(P,E,S),L).
		


/*
   buscar_ordenado_por_edad(E,L)
   
   Predicado que comprueba L es una lista compuesta por personas con la edad E. 
             La lista está ordenada alfabéticamente y no hay repeticiones

   Argumentos:
   + L:
	- Significado: lista de personas
	- Tipo: entrada y salida

   + E:
	- Significado: número natural
	- Tipo: entrada y salida

  Variables locales
  + P:
	- Significado: nombre de persona

   + S:
	- Significado: sexo {femenino, masculino}

   Predicados relacionados
    persona, setof
*/


buscar_ordenado_por_edad(E,L):-
		setof(P,S^persona(P,E,S),L).
		

/*
   buscar_por_edad(E,L)
   
   Predicado que comprueba L es una lista compuesta por personas con la edad E. 
             La lista está no ordenada alfabéticamente

   Argumentos:
   + L:
	- Significado: lista de personas
	- Tipo: entrada y salida

   + E:
	- Significado: número natural
	- Tipo: entrada y salida

  Variable local
  + P:
	- Significado: nombre de persona

   Predicados relacionados
    persona, findall
*/

buscar_por_edad_2(E,L):-
		findall(P,persona(P,E,_),L).
		

/*
   buscar_por_sexo(S,L)
   
   Predicado que comprueba L es una lista compuesta por personas con el sexo S

   Argumentos:
   + L:
	- Significado: lista de personas
	- Tipo: entrada y salida

   + S:
	- Significado: sexo {femenino, masculino}
	- Tipo: entrada y salida

  Variable local
  + P:
	- Significado: nombre de persona
  + E:
	- Significado: número natural

   Predicados relacionados
    persona, bagof
*/
buscar_por_sexo(S,L):-
		bagof(P,E^persona(P,E,S),L).
		


/*
   buscar_ordenado_por_sexo(S,L)
   
   Predicado que comprueba L es una lista compuesta por personas con el sexo S
             La lista está ordenada alfabéticamente y no hay repeticiones

   Argumentos:
   + L:
	- Significado: lista de personas
	- Tipo: entrada y salida

   + S:
	- Significado: sexo {femenino, masculino}
	- Tipo: entrada y salida

  Variables locales
  + P:
	- Significado: nombre de persona
  + E:
	- Significado: número natural

   Predicados relacionados
    persona, setof
*/
buscar_ordenado_por_sexo(S,L):-
		setof(P,E^persona(P,E,S),L).
	

/*
   buscar_por_sexo_2(S,L)
   
   Predicado que comprueba L es una lista compuesta por personas con el sexo S
             La lista no está ordenada alfabéticamente 

   Argumentos:
   + L:
	- Significado: lista de personas
	- Tipo: entrada y salida

   + S:
	- Significado: sexo {femenino, masculino}
	- Tipo: entrada y salida

  Variable local
  + P:
	- Significado: nombre de persona

   Predicados relacionados
    persona, findall
*/	

buscar_por_sexo_2(S,L):-
		findall(P,persona(P,_,S),L).
		


/*
   buscar_personas_1(L)
   
   Predicado que comprueba L es una lista compuesta por personas 
             La lista no está ordenada alfabéticamente 

   Argumentos:
   + L:
	- Significado: lista de personas
	- Tipo: entrada y salida

  Variables locales
  + P:
	- Significado: nombre de persona
  + E:
	- Significado: número natural
  + S:
	- Significado: sexo {femenino, masculino}


   Predicados relacionados
    persona, bagof
*/

buscar_personas_1(L):-
		bagof(P,E^S^persona(P,E,S),L).

/*
   buscar_personas_2(L)
   
   Predicado que comprueba L es una lista compuesta por personas  

   Argumentos:
   + L:
	- Significado: lista de personas
	- Tipo: entrada y salida

 
  Variable local
  + P:
	- Significado: nombre de persona

   Predicados relacionados
    persona, findall
*/	


buscar_personas_2(L):-
		findall(P,persona(P,_,_),L).




/*
   numero_personas_por_edad(E,N)
   
   Predicado que comprueba hay N personas con la edad E

   Argumentos:
   + E:
	- Significado: número natural
	- Tipo: entrada 

   + N:
	- Significado: número natural
	- Tipo: entrada y salida 

  Variable local
  + P:
	- Significado: nombre de persona
  + L:
	- Significado: lista de personas

   Predicados relacionados
    persona, findall, contar
*/


numero_personas_por_edad(E,N):-
	 	findall(P,persona(P,E,_),L),
		contar(L,N).
  

/*
  contar(L,N).

  Predicado que comprueba N es la longitud de la lista L 

  Argumentos
  + L:
    - Significado: lista de elementos
    - Tipo: entrada

  + N:
    - Significado: número natural
    - Tipo: entrada y salida

  Variables locales
  + Cola:
    - Significado: lista de elementos
  + M:
    - Significado: número natural
*/

contar([],0).
contar([_|Cola],N):- 
 		contar(Cola,M),
 		N is M + 1.
