prolog - 我想使用 Prolog 来订购一些东西,但我不断收到堆栈溢出错误
问题描述
在我的物理课上,我们在赛道上进行各种滚动比赛,并试图找出是什么让最快的东西最快。
我想节省时间,而不是与一切竞争。例如,一罐鸡汤胜过一罐蛤蜊,一罐蛤蜊胜过一罐西红柿。所以,鸡汤一定要打败西红柿。
这是我到目前为止写的所有内容:
% Define everything we know
outspeeds(chicken_soup, clams). % This represents "chicken_soup outspeeds clams."
outspeeds(beef, clams).
outspeeds(chicken_soup, beef).
outspeeds(chicken_soup, tomatoes).
outspeeds(clams, tomatoes).
% Now define inter-relationships
% A outspeeds B if A outspeeds some 3rd party "X" and they outspeed B.
outspeeds(A, B) :- outspeeds(A, X), outspeeds(X, B).
问题是当我尝试询问有关它的问题时。如果我试图找到所有chicken_soup
超速的东西,会发生以下情况:
?- outspeeds(chicken_soup, X).
X = clams ;
X = beef ;
X = tomatoes ;
X = tomatoes ;
ERROR: Stack limit (1.0Gb) exceeded
ERROR: Stack sizes: local: 1.0Gb, global: 4Kb, trail: 0Kb
ERROR: Stack depth: 12,197,875, last-call: 0%, Choice points: 5
ERROR: Probable infinite recursion (cycle):
ERROR: [12,197,875] user:outspeeds(tomatoes, _1098)
ERROR: [12,197,874] user:outspeeds(tomatoes, _1118)
为什么要这样做?最后我需要什么附加条款outspeeds
来防止堆栈溢出?
我是 Prolog 的新手,所以如果整个项目有什么可怕的问题,请告诉我。
解决方案
“卡尔文,你确定这是给物理课的吗?”
但也许这会有所帮助:
Wirth 教授让我终身讨厌调试器,我喜欢打印输出语句:
outspeeds_s(chicken_soup, clams, Sd, Sd) :- format("Fact: outspeeds(~w, ~w)\n",[chicken_soup,clams]).
outspeeds_s(beef, clams, Sd, Sd) :- format("Fact: outspeeds(~w, ~w)\n",[beef,clams]).
outspeeds_s(chicken_soup, beef, Sd, Sd) :- format("Fact: outspeeds(~w, ~w)\n",[chicken_soup,beef]).
outspeeds_s(chicken_soup, tomatoes, Sd, Sd) :- format("Fact: outspeeds(~w, ~w)\n",[chicken_soup,tomatoes]).
outspeeds_s(clams, tomatoes, Sd, Sd) :- format("Fact: outspeeds(~w, ~w)\n",[clams,tomatoes]).
outspeeds_s(A, B, Sd_in, Sd_max) :-
format("Stack ~w: The question is outspeeds(~w, ~w)?\n",[Sd_in,A,B]),
format("Stack ~w: ~w is fresh variable, we will now try outspeeds(~w, ~w)?\n",[Sd_in,X,A,X]),
Sd_next is Sd_in+1,
% can't ask the user in SWISH, so we sleep 3 seconds instead
sleep(3),
outspeeds_s(A, X, Sd_next, Sd_max_1),
format("Stack ~w: We found that outspeeds(~w, ~w)!\n",[Sd_in,A,X]),
format("Stack ~w: But does outspeeds(~w, ~w)?\n",[Sd_in,X,B]),
% can't ask the user in SWISH, so we sleep 3 seconds instead
sleep(3),
outspeeds_s(X, B, Sd_next, Sd_max_2),
Sd_max is max(Sd_max_1, Sd_max_2),
format("Stack ~w: We also found that outspeeds(~w, ~w)!\n",[Sd_in,X,B]),
format("Stack ~w: So we can conclude that outspeeds(~w, ~w)!\n",[Sd_in,A,B]).
outspeeds(X,Y) :-
format("outspeeds(~w, ~w)?\n",[X,Y]),
outspeeds_s(X,Y,0,Ss_max),
format("Found that outspeeds(~w, ~w) with max stack depth ~w\n",[X,Y,Ss_max]).
您可以区分无限递归要求outspeeds(tomatoes,_)
在SWISH中尝试一下。
(遗憾的是,SWISH 不接受用户通过 输入get/1
,这需要添加。)
为了实际解决问题,您可以选择几种方法来使潜在的绊雷outspeeds(A, B) :- outspeeds(A, X), outspeeds(X, B).
无害。阅读这个最近的问题以获得一两个想法:
推荐阅读
- c# - 添加两个具有 0.5 或 0.75 的文本框值
- javascript - 动态更新值的数学公式
- python - 套接字发送旧数据
- wpf - 如何让 Prism 和 Unity 的包依赖项工作?
- javascript - 将图像分配给不同的按钮
- java - Spring Cloud Hoxton.SR5 与 Eureka 和 WebFlux 的问题:超过了缓冲区的最大字节数限制
- c# - .Net Core 3.1 API 路由未按预期工作
- vb.net - 如何在 VB.NET 代码格式中保留空格(或对齐)?
- sql - 从累积和中计算减法
- java - 我有办法避免重新创建大量 String 对象吗?