I'm learning Prolog and I want to build a recipe recommendation based on calories. So base on how many calories you put as input, I want to return the combinations of a breakfast, a lunch, and a dinner.
The breakfast, the dinner, and the lunch are composed differently, so in this case, the breakfast is composed of a drink and a dish, and the dish itself is composed of cereal, a fruit or a vegetable, and an animal origin food.
Right now, I'm trying to get all the possible breakfast I have the following Prolog code
dish([Cereal, FruitOrVegetable, AnimalOrigin], Calories) :-
cereal(Cereal, CerealCalories),
(
fruit(FruitOrVegetable, FruitOrVegetableCalories);
vegetable(FruitOrVegetable, FruitOrVegetableCalories)
),
animalOrigin(AnimalOrigin, AnimalOriginCalories),
Calories >= CerealCalories + FruitOrVegetableCalories + AnimalOriginCalories.
breakfast([Drink, Dish], Calories) :-
drink(Drink, DrinkCalories),
dish(Dish, DishCalories),
Calories >= DrinkCalories + DishCalories.
If I execute the dish function, just with 600 calories it works, it returns the combination of the given food, but when I tried to implement the same logic to compose the breakfast function it throws me the following error
Arguments are not sufficiently instantiated
And I search for a while, and I found that it because of a var that is inst initialized but I didn't found the origin of the problem.
An example of the declaration of the knowledge data base is
cereal(flakes, 386).
fruit(apple, 52).
vegetable(broccoli, 31).
animalOrigin(chicken_breast, 134).
drink(water, 0).
where the first is the name of the food, and the second the calories
The problem is that you call
from
breakfast/2, butDishCaloriesis at that point an uninstantiated variable.So when the Prolog Processor hits
the variable
Calories, which is the same as the earlierDishCalories, will be uninstantiated. There is nothing to compare!You can either:
dish/2and "pass it back out" so that a complete sum of drink + disk can be computedbreakfast/2and then compare againstCaloriesas you would in other programming languages; orAnd so:
As usual:
But this works too, now:
If you don't even specify the
Calories:Caloriesis a number larger than 572:or
Caloriesis a number larger than 551: