% ALMACENA CONOCIMIENTO DE ANIMALES (Josue Espinosa Romero)
pide_atributos(Animal):-
write('Atributo? (atributo.): '), read(ATRIB),
ATRIB \= fin,
atributos(Animal, L_ATRIB),
append(L_ATRIB, [ATRIB], L2_ATRIB),
retract(atributos(Animal, L_ATRIB)),
assert(atributos(Animal, L2_ATRIB)),
pide_atributos(Animal).
pide_atributos(_):-!.
muestra_lista([]).
muestra_lista([Head|Tail]):- write(Head), nl, muestra_lista(Tail).
muestra_atributos(Animal):- atributos(Animal, ATRIB), muestra_lista(ATRIB).
existe(Animal):- animal(Animal).
verifica(Animal):- existe(Animal), muestra_atributos(Animal).
verifica(Animal):- assert(animal(Animal)), assert(atributos(Animal, [])), pide_atributos(Animal).
miembro(X,[X|_]).
miembro(X,[_|Y]) :- miembro(X,Y).
subconjunto([X|Y],Z) :- miembro(X,Z), subconjunto(Y,Z).
subconjunto([],_).
obtenA([X|_], Y):- Y = X.
filtra(_, [], LA, LA):-!.
filtra(LC, [H|T], Aux, LA):- subconjunto(LC, H), obtenA(H, A), filtra(LC, T, [A|Aux], LA).
filtra(LC, [_|T], Aux, LA):- filtra(LC, T, Aux, LA).
carctede(A, [A|LC]):- setof(A, atributos(A, LC), _).
creaL([], L, L):-!.
creaL([H|T], L, LC):- carctede(H, LH), creaL(T, [LH|L], LC).
estan(L):- setof(X, animal(X), ListA), creaL(ListA, [], L).
filtraAnimales(LC, LA):- estan(LAC), filtra(LC, LAC, [], LA).
obtenListaCaracteristicas(X, N, L):- N2 is N + 1, write(N2),write('? '),read(Y), ((Y \= fin, obtenListaCaracteristicas([Y|X], N2, L));fail).
obtenListaCaracteristicas(L, _, L):-!.
nuevoA(LC):-
write('No conosco ningun animal con esas caracteristicas. Me podrias indicar cual es? '), read(A),
assert(animal(A)), assert(atributos(A, LC)).
lee(animal):- write('Tipo de animal: '), read(Animal), Animal \= fin, verifica(Animal), lee(animal).
lee(caracteristicas):-
writeln('Ingresa una serie de caracteristicas del animal(fin. para terminar): '),
obtenListaCaracteristicas([], 0, LC),
filtraAnimales(LC, LA),
((LA \= [], write('Los animales que tienen esas caracteristicas son: '), writeln(LA)); nuevoA(LC)).
%muestra_lista(LA).
lee(_).
guarda:- animal(Animal), atributos(Animal, Atrib), write(Animal),write('.'), nl, write(Atrib), write('.'), nl, fail.
guarda:-!.
guarda(Archivo):- tell(Archivo), guarda, told.
carga(Animal, Atrib):- assert(animal(Animal)), assert(atributos(Animal, Atrib)), carga.
carga:- read(Animal), Animal \== end_of_file, read(Atrib), carga(Animal, Atrib).
carga:-!.
carga(Archivo):- see(Archivo), carga, seen.
ciclo:- write('Introduce tipo de informacion (animal., caracteristicas., fin.): '), read(Tipo), ((Tipo \= fin, lee(Tipo), ciclo) ; fail).
ciclo.
%limpiaDatos:- animal(X), retract(animal(X)), fail.
%limpiaDatos:- atributos(X,Y), retract(atributos(X,Y)), fail.
%limpiaDatos:-!.
limpiaDatos:- retractall(animal(X)), retractall(atributos(X,_)).
%inicio(Archivo):- assert(animal(p)), assert(atributos(p, [])), limpiaDatos, carga(Archivo), ciclo, guarda(Archivo), !.
inicio:- limpiaDatos, carga('zoo.txt'), ciclo, guarda('zoo.txt'), !.
:- dynamic animal/1, atributos/2.