Welcome to AnimalPro, your expert guide in the world of zoology! AnimalPro is an application designed to assist users in identifying various species of animals quickly and accurately. Powered by Prolog's logical programming capabilities and PyQt's graphical interface.
AnimalPro uses a knowledge base of facts and rules in Prolog to facilitate the identification of animals. Users interact with the AnimalPro through PyQt GUI, where they can answer yes or no to questions about the characteristics of an animal, such as its habitat, physical features, sound, diet, and behavior. Behind the scenes, AnimalPro leverages Prolog's inference engine to deduce the most likely matches based on the provided criteria.
-
Categories and Characteristics Mapping:
AnimalPro maps animal characteristics to specific categories, helping in organizing data, which simplifies the rule-checking process.
-
Animal Definitions:
AnimalPro defines an extensive list of animals along with their characteristics. Each animal is represented as a term with two arguments: the name of the animal and a list of characteristics.
-
Rule-Based Inference:
- Characteristics of animals are represented as rules.
- Check each rule against the characteristics of animals in the knowledge base, by recursively traversing the list of animals and evaluating each rule against the characteristics of each animal.
-
Interactive Querying:
AnimalPro interacts with the user by asking questions about the characteristics of the animal they are interested in, then updates the known facts based on the user's answers.
-
Graphical User Interface:
AnimalPro boasts an intuitive graphical user interface (GUI) that enhances user interaction and experience. The GUI streamlines the querying process, allowing users to provide answers about an animal's characteristics with ease.
-
Mapping Characteristics to Categories:
mapToCategory("barks", sound). mapToCategory("says meow", sound). mapToCategory("grunts", sound). mapToCategory("screeches", sound). mapToCategory("is silent", sound). mapToCategory("chirps", sound). mapToCategory("clucks", sound). ..... mapToCategory("is omnivore (eats both plants and animals)", diet). mapToCategory("is carnivore (Meat-Eater)", diet). mapToCategory("is herbivore (Plant-Eater)", diet). ..... mapToCategory("has fur", coating). mapToCategory("has feathers", coating). mapToCategory("has scales", coating). mapToCategory("has skin", coating). .....
Each characteristic is mapped into a unique category.
-
Defining Animal Characteristics:
animal(dinosaur, [is_true("is omnivore (eats both plants and animals)"), is_true("is huge"), is_true("does it run"), is_true("has scales"), is_true("is wild"), is_true("roars")]), animal(ostrich, [is_true("is omnivore (eats both plants and animals)"), is_true("is large"), is_true("does it run"), is_true("has feathers"), is_true("is wild"), is_true("booms")]), animal(dog, [is_true("is omnivore (eats both plants and animals)"), is_true("is regular-sized"), is_true("does it run"), is_true("has fur"), is_true("is domestic"), is_true("barks")]), animal(monkey, [is_true("is omnivore (eats both plants and animals)"), is_true("is regular-sized"), is_true("does it climb"), is_true("has fur"), is_true("is wild"), is_true("chatters")]), animal('flying fish', [is_true("is omnivore (eats both plants and animals)"), is_true("is small"), is_true("does it fly & swim"), is_true("has scales"), is_true("is wild"), is_true("is silent")]), animal(penguin, [is_true("is omnivore (eats both plants and animals)"), is_true("is small"), is_true("does it swim & run"), is_true("has fur"), is_true("is domestic"), is_true("squawks")]), animal(chicken, [is_true("is omnivore (eats both plants and animals)"), is_true("is small"), is_true("does it run"), is_true("has feathers"), is_true("is domestic"), is_true("clucks")]), animal(bat, [is_true("is omnivore (eats both plants and animals)"), is_true("is small"), is_true("does it fly"), is_true("has fur"), is_true("is wild"), is_true("screeches")]), animal(turtle, [is_true("is omnivore (eats both plants and animals)"), is_true("is small"), is_true("does it swim"), is_true("has skin"), is_true("is wild"), is_true("clacks")]), animal(chameleon, [is_true("is omnivore (eats both plants and animals)"), is_true("is small"), is_true("does it crawl"), is_true("has scales"), is_true("is wild"), is_true("hisses")]), animal(lizard, [is_true("is omnivore (eats both plants and animals)"), is_true("is small"), is_true("does it crawl"), is_true("has scales"), is_true("is wild"), is_true("is silent")]), animal(hedgehog, [is_true("is omnivore (eats both plants and animals)"), is_true("is small"), is_true("does it crawl"), is_true("has spines"), is_true("is wild"), is_true("snuffles")]), animal(rat, [is_true("is omnivore (eats both plants and animals)"), is_true("is tiny"), is_true("does it run"), is_true("has fur"), is_true("is domestic"), is_true("screeches")]), .....
Each animal is associated with a list of characteristics, which are then used for matching. We will discuss below how we gathered this data.
-
Checking Animal Rules:
searchAnimals([Animal|Animals], A) --> checkAnimalRules(Animal, Animals, A).
Checking animal rules. It iterates through the list of animals, checking if each animal satisfies the given characteristics or not.
-
Updating Known Facts:
updateState(New, Old), [Old] --> [New].
Updating the state of known facts based on the answers provided during the querying process. It's used to maintain a record of what has been determined true or false.
-
Checking Rule Truth:
checkRule(is_true(Q), Answer, Known0, Known) :- if_(ruleIsKnown(Q,Answer,Known0), Known0 = Known, ( format("~s?\n", [Q]), read(Answer), (mapToCategory(Q, Category) -> updateCategory(Category, Q, Answer, Known0, Known) ; Known = [known(Q, Answer)|Known0]))).
Check whether a given rule is known to be true or false based on the state of knowledge. If it's known, it updates the known list. Otherwise, it asks the user to give an answer then updates the knowledge state based on that answer.
-
Updating Category Information:
updateCategory(Category, Q, yes, Known0, Known) :- findall(known(OtherQ, no), (mapToCategory(OtherQ, Category), OtherQ \= Q), OtherQs), append([known(Q, yes)|OtherQs], Known0, Known). updateCategory(_, Q, no, Known0, [known(Q, no)|Known0]).
If the answer is "yes", it implies that the current characteristic is true, so all other characteristics in the same category are marked as false. If the answer is "no", only the current characteristic is marked as false.
Here you can watch some interactive queries for our program:
AnimalPro-SampleRuns.mp4
Creating a robust knowledge base is essential for the effectiveness of our animal expert system. We gathered data from a comprehensive questionnaire and analyzed the results to identify unique animal properties. This information was crucial for defining the facts and rules in our Prolog knowledge base.
We used a Google Form to collect data from participants. The questionnaire was designed to gather specific attributes and characteristics of various animals. You can access the questionnaire in this link.
Samples of form responses which helped us build the program:
After collecting the data, we compiled the results into an a spreadsheet, which includes detailed statistics on the frequency and uniqueness of various animal properties. The analysis focused on identifying properties that are most useful for distinguishing between different animals. You can view the Google spreadsheet and its analysis in this link.
Here are some screenshots from it:
- After organizing the data, we built the Prolog knowledge base as discussed above.
- Install SWI-Prolog from the official site: https://www.swi-prolog.org/download/stable
- Clone AnimalPro repository.
- Jump into AnimalPro directory:
cd AnimalPro
- Open the SWI-Prolog terminal:
swipl
- Install the
reif
package:
pack_install(reif).
- Go back to the previous terminal.
- Install required Python packages:
pip install -r requirements.txt
- Run the GUI:
python GUI.py
If you find a weird animal in your backyard, don't worry! You can use AnimalPro to learn more about it. Just tell us what it looks like or any special things it does, and we'll try to tell you what it might be.
- AbdElRahman Osama
- AbdElRahman Bassam
- AbdElRahman Deif
- Ahmed Youssef
- Mourad Mahgoub