Компьютерный форум
Правила
Вернуться   Компьютерный форум > Форум программистов > Языки программирования > Prolog
Перезагрузить страницу Переполнение стека
Ответ
 
Опции темы Опции просмотра
  (#1 (permalink)) Старый
DSan DSan вне форума
Новичок
 
Сообщений: 6
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 05.05.2007
По умолчанию 18.11.2007, 03:21

Написана игра, основной предикат которой имеет следующий вид:

Код:
play(P):- cls, show_board,!,
              not(game_over(P)),   
              ds2state(7,6,[],St), dlev2list(7,[],Lev), 
              move(P,St,Lev,St2,Lev2), 
              state2ds(St2,1,1), list2dlev(Lev2,1),
              next_player(P,P2),
              play(P2).

%move - предикат для осуществления хода (игрока или компьютера)
%P - integer (номер игрока 1 или 2)
%St, Lev - списки, представляющие состояние игрового поля
%St2, Lev2 - списки, полученные в результате хода

%ds2state, dlev2list - преобразование из фактов динамической БД, представляющих
%то же самое состояние игрого поля (удобнее проверять окончание игры и т.п.), в списки St и Lev

%state2ds, list2dlev - обратное преобразование
Для реализации хода компьютера написан довольно массивный кусок кода, который содержит большое количество вычислений, преобразований данных, рекурсий, и при этом соответственно забивается стек. Т.е. после выполнения предиката move в том случае, когда ходил компьютер, стек содержит приличное количество мусора. Стек конечно можно увеличить (по крайней мере, чтобы не вылетала игра со stack overflow), но чем сильнее он забит, тем медленнее работает программа, что меня не совсем устраивает.

Можно ли каким либо образом принудительно освободить память (после получения нового состояния игрового поля)? И каким образом вообще происходит освобождение памяти в Прологе? Может я что-то недопонимаю и неправильно делаю.

Пролог - VIP 5.2
Ответить с цитированием
  (#2 (permalink)) Старый
Винитарх Винитарх вне форума
Специалист
 
Аватар для Винитарх
 
Сообщений: 7,958
Сказал(а) спасибо: 2
Поблагодарили 303 раз(а) в 303 сообщениях
Регистрация: 01.03.2003
Адрес: Краснодар
По умолчанию 20.11.2007, 00:37

Поставьте отсечение перед рекурсивным вызовом:
Код:
play(P):- cls, show_board,!,
              not(game_over(P)),   
              ds2state(7,6,[],St), dlev2list(7,[],Lev), 
              move(P,St,Lev,St2,Lev2), 
              state2ds(St2,1,1), list2dlev(Lev2,1),
              next_player(P,P2),!,
              play(P2).
и вообще, перед всеми рекурсивными вызовами, если только они не недерминированные.
Ответить с цитированием
  (#3 (permalink)) Старый
DSan DSan вне форума
Новичок
 
Сообщений: 6
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Регистрация: 05.05.2007
По умолчанию 24.11.2007, 19:53

Цитата:
Поставьте отсечение перед рекурсивным вызовом:
<div class='codetop'>Код Prolog
<div class='codemain'>play(P):- cls, show_board,!,
not(game_over(P)),
ds2state(7,6,[],St), dlev2list(7,[],Lev),
move(P,St,Lev,St2,Lev2),
state2ds(St2,1,1), list2dlev(Lev2,1),
next_player(P,P2),!,
play(P2).[/code]
и вообще, перед всеми рекурсивными вызовами, если только они не недерминированные.[/quote]
Добрались руки до игрушки.
Понял свою ошибку. Я вместо того, чтобы делать предикаты детерминированными при помощи отсечений, делал их недетерминированными ключевым словом nondeterm (боролся таким образом с ошибкой "nondeterministic predicate"). И пролог записывал весь ход программы в стек на случай бэктрекинга.
Исправил свою оплошность, теперь программа "летает".

Спасибо за подсказку.
Ответить с цитированием
Ads
Ответ

Опции темы
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Trackbacks are Вкл.
Pingbacks are Вкл.
Refbacks are Выкл.


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Статическое реализация стека. Vergiliy Pascal 9 17.10.2011 08:56
Формирование стека Наташок Pascal 0 30.11.2010 15:52
Борьба с исчерпанием стека raydac Prolog 45 27.01.2009 12:03
Ajax и переполнение памяти Алексеев Николай PHP 6 09.03.2008 17:26
Размер стека в GNU C just_vladimir С/С++ 16 08.03.2007 04:50
Возведение в степень - переполнение milanitka C++ Builder 1 21.12.2006 13:00
Переполнение стека FPU как очистить imported_Sfinks Assembler 3 19.03.2006 00:35
Переполнение стека сопроцессора St. Andrew Assembler 0 28.11.2005 23:25
Проверка функции int на переполнение tonnn C++ Builder 1 09.05.2005 03:51
Переполнение стека при перерисовке канвы Anonymous C++ Builder 1 02.02.2004 15:27
Переполнение при перемножении Anonymous С/С++ 26 26.12.2003 17:03



Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.
Нardforum.ru - компьютерный форум и программирование, форум программистов