2014-02-12 7 views
6

Этот вопрос является продолжением этого question.Ошибка утечки памяти Sicstus Prolog

Я бегу большое количество тестов в Sicstus прологе:

runtest:- 
t1, 
t2, 
t3, 
. 
. 
t100. 

Каждый тест является автономным и будет печатать свой результат на экран. Между тестами нет разрыва, поэтому никакие данные не должны храниться/сохраняться между каждым тестом.

Моя проблема заключается в том, что Sicstus накапливает память и, наконец, попадет исключение: «Ошибка ресурса: недостаточная память»

Я пытался организовать мой тест, как это:

runtest:- 
    once(t1), 
    once(t2), 
    . 
    . 
    once(t100). 

Но я все-таки попасть в проблема.

Есть ли другой способ рассказать Prolog о освобождении всей выделенной памяти между каждым вызовом теста?

ответ

3

Попробуйте использовать (современную) failure driven loop: должен вернуть себе память на любой Пролог

?- forall(member(T, [t1,t2,...,t100]), once(T)). 
+2

Это очень помогло бы терминологически отделить этот стиль от общих провальных контуров. 'findall/3',' setof/3' имеют встроенные с ошибкой контуры. – false

+3

Нет необходимости в 'once (T)', потому что 'T' хватает. – false

6

Нет, нет никакого способа узнать, Пролог, чтобы освободить всех выделенной памяти.

Если тестовые предикаты не принимают аргументов, а их обертывание один раз/1 не помогает, то цикл с ошибкой также не должен помогать.

Одна из возможностей заключается в том, что ваши тесты каким-то образом добавляют постоянные данные, например. утверждает предложения.

Попробуйте добавить

garbage_collect, statistics

между (некоторые) испытание. Это должно дать вам представление о том, какие области памяти растут.

От взгляда на ваш предыдущий вопрос может случиться так, что один из ваших тестов исчерпывает память сам по себе, то есть проблема не связана с запуском нескольких тестов.

+3

'undo' может быть еще одной причиной, по которой' once/1' не может вернуть место. – false

2

Предикат один раз/1 отбрасывает только точки выбора, но оставляет неизменным след. Трейл обычно расширяется либо с помощью переменных унификаций, либо с помощью даже с помощью ограничений решателей ограничений.

Итак, ваша цепочка тестов собирает много данных. Существует фольклор Prolog , который поможет вам. Использование двойного отрицания освобождает ресурсы, поэтому эту конструкцию поэтому часто называют сборщиком мусора.

Просто переписать код:

runtest:- 
    \+ \+ t1, 
    \+ \+ t2, 
    \+ \+ t3, 
    . 
    . 
    \+ \+ t100. 

Но обратите внимание, что ваш тест теперь также будет измерять время снести след, возможно, изменяя старые результаты, так как когда-то время, чтобы рушить след может быть измеримым.

И последнее, но не менее важное, конечно, сбор фольклорных мусора двойное отрицание работает только тогда, когда это нормально, чтобы вызвать цель один раз.

Bye