From UBC Wiki

Authors: Allison Earle, Burcu Gorgulicten

What is the problem?

Deciding what to cook can be difficult, so we will be implementing a recommender system to help. The program will suggest recipes based on user input. For example, the user can specify the ingredients they have, how much time they have, and what type of meal they want to make. We will use natural language processing to parse the user’s queries and find the perfect recipe.

What is the something extra?

We will retrieve recipes from an API using Prolog’s HTTP libraries and parse the JSON results. We will also be using WordNet to help classify types of words given by the user. Lastly we will write the returned recipes in a text file with a more readable format.

What did we learn from doing this?

We learned that logic programming is very suitable for recommender systems, especially those involving natural language processing tasks. Some of the features of Prolog that made it useful are its pattern matching and search capabilities. While logic programming was well-suited for many aspects of our project, we found its biggest downside to be its difficulty of debugging.

Making an HTTP request in Prolog was fairly simple once we figured out what the URL should look like. It was easily done with "http_get" which conveniently converted the returned JSON to a Prolog term. Moreover Prolog's very flexible pattern matching was very useful when parsing the Prolog term as long as we knew how the Prolog term was structured. For example, by iterating through the list with "[name=N|T] " it was able to find the rule where the value of "name" was N quickly. Additionally Prolog allowing us to build structures as we go without having to define them with specific types was very helpful. With that we were able to distinguish between the recipe's features such as its ingredients and its name without doing any additional checks. Moreover we were able to have different types of ingredients such as an array and a string without any problems. These allowed us to easily treat every recipe the same to write their values in the recipes.txt file. It was nice to not worry about types like we did in Haskell.

The first thing we struggled with before actually starting the project was finding the API that would do the searches we wanted while also being free of charge, and then getting familiar with that API to find out how to make the requests that would return us the information we would like. Another struggle was coming up with a design and the best way to represent the data so that rules were easy to write. Along with that as we were dealing with natural language processing, coming up with a variety of possible inputs was also difficult since we wanted to make sure we were being inclusive enough with the word choices like “apple” versus “apples”, or sentence structures like “What is a recipe with an apple” versus “A recipe that uses an apple”.

After determining valid sentence structures, the actual implementation was much easier. Prolog worked very well for the natural language processing component of our project. Its ability to match patterns and search through sentence structures to find a match made it much simpler to parse user input and accept a wide range of inputs. Using logic programming also made the grammar easily extensible. Broadening the acceptable inputs simply involved adding new rules to the existing ones. The only challenge with it was debugging. It was not as easy to tell why the expected sequence of rules was false instead of true or the value was different from the expected one as the program grew larger. Thus it was important to be able to test these rules individually, but even then when combined there were cases where they behaved unexpectedly.

Links to code etc