Given that you problem requires representing taxonomic knowledge, Let's use a Logtalk solution that can naturally express it, providing a one-to-one relation between the knowledge and its code representation. This solution is portable and can thus run in most Prolog systems:
:- object(species).
:- public([
scales/1, body_temperature/1, reproduction/1,
color/1, habitat/1
]).
:- end_object.
:- object(reptile, extends(species)).
scales(present).
body_temperature(cold_blooded).
reproduction(lays_eggs).
:- end_object.
:- object(alligator, extends(reptile)).
species(reptile).
color(dark_green).
habitat(water).
:- end_object.
Save this code in a, say, kb.lgt file, start Logtalk with your preferred Prolog system and try some queries. For example:
$ swilgt
...
{kb}.
...
?- alligator::habitat(Habitat).
Habitat = water.
?- alligator::reproduction(Reproduction).
Reproduction = lays_eggs.
But you also want to enumerate e.g. animals. I.e. reasoning about the hierarchy. There's a library for that. First, we need to import the necessary predicates into the root object:
:- object(species, imports(proto_hierarchy)).
We can then try:
?- {hierarchies(loader)}.
...
?- reptile::descendant(Reptile).
Reptile = alligator ;
false.
This example should be, hopefully, clear enough so that you can extend it to be more realistic in a way that would avoid your old Biology teacher screaming and pulling hair. It's also easy to evolve this solution into an expert system that could be used to classify a being given its description. For an example, see:
https://github.com/LogtalkDotOrg/logtalk3/tree/master/examples/birds