我想用Prolog来订购一些东西,但我经常会遇到堆栈溢出错误

我想用Prolog来订购一些东西,但我经常会遇到堆栈溢出错误,prolog,stack-overflow,Prolog,Stack Overflow,在我的物理课上,我们在一条赛道上比赛各种各样的东西,试图找出最快的东西跑得最快的原因 我想节省时间,而不是与任何事物竞争。例如,鸡汤罐胜过蛤蜊罐,蛤蜊罐胜过西红柿罐。所以,鸡汤一定要打西红柿 以下是我到目前为止写的所有内容: % Define everything we know outspeeds(chicken_soup, clams). % This represents "chicken_soup outspeeds clams." outspeeds(beef, clams). out

在我的物理课上,我们在一条赛道上比赛各种各样的东西,试图找出最快的东西跑得最快的原因

我想节省时间,而不是与任何事物竞争。例如,鸡汤罐胜过蛤蜊罐,蛤蜊罐胜过西红柿罐。所以,鸡汤一定要打西红柿

以下是我到目前为止写的所有内容:

% 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).
问题是当我试着问关于它的问题时。下面是如果我试图找到所有比这快的
鸡汤
会发生什么:

?- 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)
为什么要这样做?在最后一个
outspeed
中,我需要什么额外的子句来防止堆栈溢出

我不熟悉Prolog,所以如果整个项目有什么严重问题,请告诉我。

“,你确定这是为实际的物理课准备的吗?”

但也许这会有所帮助:

沃思教授让我终生厌恶调试器,我喜欢打印输出语句:

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]).
您可以区分要求
超过速度的无限递归(西红柿,)

试试看

(SWISH不接受通过
get/1
进行的用户输入,这需要添加。)

为了实际解决这个问题,您可以选择几个选项,使潜在的tripmine
超过速度(A,B):-outspeed(A,X),outspeed(X,B)。
无害。阅读最近的问题,了解一两个想法:


您的
X=X+X
非常经典。将其改为
Y=X+Y
。同时查看“传递闭包”>卡尔文,你确定这是物理课的吗。。。。是的,这主要是为了好玩。但至少它是有用的乐趣,对吧?@gamma_delta是的。