尝试获取组合时参数未充分实例化
Arguments are not sufficiently instantiated while trying to get combinations
我正在学习 Prolog,我想根据卡路里构建食谱推荐。因此,根据您输入的卡路里数量,我想 return 早餐、午餐和晚餐的组合。
早餐、晚餐和午餐的组成不同,所以在这种情况下,早餐由饮料和菜肴组成,菜肴本身由麦片、水果或蔬菜组成,并且一种动物源性食品。
现在,我正在尝试获取所有可能的早餐我有以下序言代码
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.
如果我执行 dish 函数,只需要 600 卡路里就可以了,它 return 是给定食物的组合,但是当我尝试实现相同的逻辑来组合 breakfast 函数时,它抛出了我以下错误
Arguments are not sufficiently instantiated
然后找了一会儿,发现是因为inst初始化了一个var,但是没找到问题的根源。
知识库声明的一个例子是
cereal(flakes, 386).
fruit(apple, 52).
vegetable(broccoli, 31).
animalOrigin(chicken_breast, 134).
drink(water, 0).
第一个是食物的名称,第二个是卡路里
问题是你打电话
dish(Dish, DishCalories)
来自 breakfast/2
,但是 DishCalories
在那个时候是一个未实例化的变量。
所以当 Prolog 处理器命中时
Calories >= CerealCalories + FruitOrVegetableCalories + AnimalOriginCalories.
与之前的DishCalories
相同的变量Calories
将被取消实例化。没有什么可比较的!
您可以:
- 计算
dish/2
中的热量并“传回”,这样一个完整的
可以计算 drink + disk 的总和 breakfast/2
,然后像在其他编程语言中一样与 Calories
进行比较;或
- 使用不需要“立即计算”并在内部构造对应于部分填充表达式的数据结构的约束逻辑编程,当知道更多时可以“稍后”评估(并且可能失败):
:- use_module(library(clpfd)).
dish([Cereal, FruitOrVegetable, AnimalOrigin], Calories) :-
cereal(Cereal, CerealCalories),
(
fruit(FruitOrVegetable, FruitOrVegetableCalories);
vegetable(FruitOrVegetable, FruitOrVegetableCalories)
),
animalOrigin(AnimalOrigin, AnimalOriginCalories),
%
% Compare if we know enough, otherwise delay the decision on >=
% and proceed optimistically
%
Calories #>=
CerealCalories +
FruitOrVegetableCalories +
AnimalOriginCalories.
breakfast([Drink, Dish], Calories) :-
drink(Drink, DrinkCalories),
dish(Dish, DishCalories),
format("Calories: ~q, DrinkCalories: ~q, DishCalories: ~q~n",
[Calories,DrinkCalories,DishCalories]),
Calories #>= DrinkCalories + DishCalories.
等等:
像往常一样:
?- dish(List,600).
List = [flakes, apple, chicken_breast] ;
List = [flakes, broccoli, chicken_breast].
但现在这也行得通:
?- breakfast(List,600).
Calories: 600, DrinkCalories: 0, DishCalories: _21370
List = [water, [flakes, apple, chicken_breast]] ;
Calories: 600, DrinkCalories: 0, DishCalories: _22506
List = [water, [flakes, broccoli, chicken_breast]].
如果您甚至不指定 Calories
:
Calories
是大于572的数:
?- breakfast(List,Calories).
Calories: _23482, DrinkCalories: 0, DishCalories: _23990
List = [water, [flakes, apple, chicken_breast]],
_25276 in 572..sup,
Calories#>=_25276,
Calories in 572..sup ;
或Calories
是大于551的数字:
Calories: _23482, DrinkCalories: 0, DishCalories: _26724
List = [water, [flakes, broccoli, chicken_breast]],
_28010 in 551..sup,
Calories#>=_28010,
Calories in 551..sup.
我正在学习 Prolog,我想根据卡路里构建食谱推荐。因此,根据您输入的卡路里数量,我想 return 早餐、午餐和晚餐的组合。
早餐、晚餐和午餐的组成不同,所以在这种情况下,早餐由饮料和菜肴组成,菜肴本身由麦片、水果或蔬菜组成,并且一种动物源性食品。
现在,我正在尝试获取所有可能的早餐我有以下序言代码
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.
如果我执行 dish 函数,只需要 600 卡路里就可以了,它 return 是给定食物的组合,但是当我尝试实现相同的逻辑来组合 breakfast 函数时,它抛出了我以下错误
Arguments are not sufficiently instantiated
然后找了一会儿,发现是因为inst初始化了一个var,但是没找到问题的根源。
知识库声明的一个例子是
cereal(flakes, 386).
fruit(apple, 52).
vegetable(broccoli, 31).
animalOrigin(chicken_breast, 134).
drink(water, 0).
第一个是食物的名称,第二个是卡路里
问题是你打电话
dish(Dish, DishCalories)
来自 breakfast/2
,但是 DishCalories
在那个时候是一个未实例化的变量。
所以当 Prolog 处理器命中时
Calories >= CerealCalories + FruitOrVegetableCalories + AnimalOriginCalories.
与之前的DishCalories
相同的变量Calories
将被取消实例化。没有什么可比较的!
您可以:
- 计算
dish/2
中的热量并“传回”,这样一个完整的 可以计算 drink + disk 的总和breakfast/2
,然后像在其他编程语言中一样与Calories
进行比较;或 - 使用不需要“立即计算”并在内部构造对应于部分填充表达式的数据结构的约束逻辑编程,当知道更多时可以“稍后”评估(并且可能失败):
:- use_module(library(clpfd)).
dish([Cereal, FruitOrVegetable, AnimalOrigin], Calories) :-
cereal(Cereal, CerealCalories),
(
fruit(FruitOrVegetable, FruitOrVegetableCalories);
vegetable(FruitOrVegetable, FruitOrVegetableCalories)
),
animalOrigin(AnimalOrigin, AnimalOriginCalories),
%
% Compare if we know enough, otherwise delay the decision on >=
% and proceed optimistically
%
Calories #>=
CerealCalories +
FruitOrVegetableCalories +
AnimalOriginCalories.
breakfast([Drink, Dish], Calories) :-
drink(Drink, DrinkCalories),
dish(Dish, DishCalories),
format("Calories: ~q, DrinkCalories: ~q, DishCalories: ~q~n",
[Calories,DrinkCalories,DishCalories]),
Calories #>= DrinkCalories + DishCalories.
等等:
像往常一样:
?- dish(List,600).
List = [flakes, apple, chicken_breast] ;
List = [flakes, broccoli, chicken_breast].
但现在这也行得通:
?- breakfast(List,600).
Calories: 600, DrinkCalories: 0, DishCalories: _21370
List = [water, [flakes, apple, chicken_breast]] ;
Calories: 600, DrinkCalories: 0, DishCalories: _22506
List = [water, [flakes, broccoli, chicken_breast]].
如果您甚至不指定 Calories
:
Calories
是大于572的数:
?- breakfast(List,Calories).
Calories: _23482, DrinkCalories: 0, DishCalories: _23990
List = [water, [flakes, apple, chicken_breast]],
_25276 in 572..sup,
Calories#>=_25276,
Calories in 572..sup ;
或Calories
是大于551的数字:
Calories: _23482, DrinkCalories: 0, DishCalories: _26724
List = [water, [flakes, broccoli, chicken_breast]],
_28010 in 551..sup,
Calories#>=_28010,
Calories in 551..sup.