Search code examples
prologclassification

Prolog classification by giving points to classes


I'm working on an knowledge system that can return a wine when a user enters a dish. My idea is to add points to every wine class depending on the input of the user and then displaying a top 3 of fitting wine classes. So for example if someone enters fish then all the red wines in the knowledge base get zero points and the white wines do get a point. If the user then enters a type of saus or vegetable ect. Wines that match this get an extra point. This will then result in a list that shows which wines (in my knowledgebase) fit best and which fits worst according to the points. Does anyone know how I could do this in prolog.


Solution

  • You can set up a database of wines and their characteristics something like this:

    wine_color_body(chardonnay, white, light).
    wine_color_body(gruener_veltliner, white, full).
    wine_color_body(cabernet_franc, red, light).
    wine_color_body(pinot_noir, red, medium).
    wine_color_body(merlot, red, full).
    

    (You will know more about wine than I do, and probably add a lot more criteria.)

    Then you can formulate your scoring rules based on individual characteristics like this:

    dish_wine_score(fish, Wine, 1) :-
        wine_color_body(Wine, white, _).
    dish_wine_score(fish, Wine, 0) :-
        wine_color_body(Wine, red, _).
    
    dish_wine_score(beef, Wine, 1) :-
        wine_color_body(Wine, red, _).
    dish_wine_score(beef, Wine, 0) :-
        wine_color_body(Wine, white, _).
    
    dish_wine_score(dessert, Wine, 2) :-
        wine_color_body(Wine, _, light).
    dish_wine_score(dessert, Wine, 1) :-
        wine_color_body(Wine, _, medium).
    dish_wine_score(dessert, Wine, 0) :-
        wine_color_body(Wine, _, full).
    

    For example, to see what goes with fish:

    ?- dish_wine_score(fish, Wine, Score).
    Wine = chardonnay,
    Score = 1 ;
    Wine = gruener_veltliner,
    Score = 1 ;
    Wine = cabernet_franc,
    Score = 0 ;
    Wine = pinot_noir,
    Score = 0 ;
    Wine = merlot,
    Score = 0.
    

    And then you can easily score based on a list of dishes or their properties:

    dishes_wine_score([], _Wine, 0).
    dishes_wine_score([Dish | Dishes], Wine, Score) :-
        dish_wine_score(Dish, Wine, DishScore),
        dishes_wine_score(Dishes, Wine, RestScore),
        Score is DishScore + RestScore.
    

    What wine would go best with both beef and the dessert afterwards?

    ?- dishes_wine_score([beef, dessert], Wine, Score).
    Wine = cabernet_franc,
    Score = 3 ;
    Wine = pinot_noir,
    Score = 2 ;
    Wine = merlot,
    Score = 1 ;
    Wine = chardonnay,
    Score = 2 ;
    Wine = gruener_veltliner,
    Score = 0.
    

    Once you are at this point, you just need to collect all of these answers, sort them, and find the ones with the highest score. You can do this with bagof/3 or findall/3 followed by sort/2.