Я хочу использовать Prolog, чтобы заказать некоторые вещи, и я продолжаю получать ошибки переполнения стека - PullRequest
1 голос
/ 01 апреля 2020

Для моего класса физики мы гоняем разные вещи по трассе и пытаемся выяснить, что делает самые быстрые из них самыми быстрыми.

Я хочу сэкономить время, а не гонять все против всего. Например, банка с куриным супом бьет банку с моллюсками, а банка с моллюсками - с банкой с помидорами. Итак, куриный суп должен побить помидоры.

Вот все, что я написал до сих пор:

% 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, поэтому, если что-то ужасно не так с проектом в целом, пожалуйста, сообщите мне.

1 Ответ

2 голосов
/ 01 апреля 2020

" Кальвин , вы уверены, что это для настоящего класса физики?"

Но, возможно, это поможет:

tomatoes outspeed nothing

Профессор Вирт привил мне пожизненную ненависть отладчиков, и мне нравятся распечатки:

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]).

Вы можете различить guish бесконечную рекурсию, запрашивающую outspeeds(tomatoes,_)

Попробуйте в SWI SH.

(К сожалению, SWI SH, к сожалению, не принимает ввод пользователя через get/1, его необходимо добавить.)

Для фактического решения проблемы вам доступны несколько вариантов, чтобы потенциальный трипмин outspeeds(A, B) :- outspeeds(A, X), outspeeds(X, B). безвреден. Прочитайте этот недавний вопрос для идеи или двух:

Рекурсивный l oop необходим оператор выхода

...