Циркулярный буфер в Turbo Prolog 2.0 - PullRequest
1 голос
/ 27 мая 2011

Мне нужно написать что-то вроде кольцевого буфера в TurboProlog 2.0 для расчета среднего.Я не знаю, какие предикаты мне нужно написать, и понятия не имею, как их связать.

Ответы [ 2 ]

0 голосов
/ 10 июня 2011

После долгих раздумий была написана следующая программа

% Consumer predicate. If buffer is empty, nothing to take, need to wait for producer predicate.

    consumer(BufferBefore, [], _) :- 
        length(BufferBefore, BuffSize), 
        BuffSize = 0, 
        write("Buffer is empty. Waiting for producer"), nl, !, fail.

    % If the buffer is not empty, returns first element and removes them from the buffer
    consumer(BufferBefore, BufferAfter, Result) :- 
        car(BufferBefore, Result),
        deletefirst(BufferBefore, BufferAfter).

    % Producer predicate. If data and buffer is empty, nothing taken from the data to put in buffer.
    producer([], [], [], [], _) :- write("End of data!."), !, fail.

    % Else if buffer is not empty, add first elem from data (and removes them from here) to last position in buffer.
    producer(DataBefore, BufferBefore, DataAfter, BufferAfter, Size) :- 
        length(BufferBefore, BuffSize), BuffSize < Size, !, 
        car(DataBefore, Elem), 
        addlast(Elem, BufferBefore, BufferAfter), 
        deletefirst(DataBefore, DataAfter).

Несколько примеров бега

consumer([1,2,3,4,5], BufferAfter, Result) 

возвращает

BufferAfter = [2,3,4,5], Result = 1.

И

producer([1,2,3,4,5,6],[7,8,9],DataAfter, BufferAfter, %">3 here"%) 

возвращает

DataAfrer = [2,3,4,5,6], BufferAfter = [7,8,9,1].

Теперь, чтобы продемонстрировать какой-либо расчет, нам нужно написать программу, которая будет запускать «потребитель», пока буфер не будет пустым. И «потребитель» будет запускать «производитель», когда буфер пуст. И остановите процесс, когда данные и буфер станут пустыми. Надежда будет полезна всем.

0 голосов
/ 01 июня 2011

Я не уверен, какую функциональность «кольцевого буфера» нужно реализовать для вашего приложения. В общем случае «буфер» - это хранилище многократного использования, часто связанное с процессами ввода-вывода, которые обрабатывают асинхронную связь (отсюда необходимость в буфере, который позволяет одному процессу опережать другой). «Круговой буфер» обозначает способ управления доступным хранилищем с помощью указателей (как на начало, так и на конец действительных / необработанных данных), которые охватывают (линейную) непрерывную область. Это имеет преимущество перед сохранением очереди FIFO с фиксированным местоположением для начала допустимых данных, поскольку не требуется «перемешивание» необработанных элементов.

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

Вот несколько идей:

  1. Turbo Prolog поддерживает списки, которые в некоторых отношениях являются более ограничительными и, возможно, другими способами более сложными, чем соответствующие списки стандартных Prolog. Одним из ограничений является то, что в Turbo Prolog все элементы списка должны принадлежать одному и тому же «домену», понятие, чуждое слабо типизированному символу стандартного Prolog. Также домены могут быть обозначены как «эталонные» домены в Turbo Prolog, уровне косвенности, который позволяет передавать частично связанные составные термины между подцелями. Не вдаваясь в подробности, одним смыслом «кругового буфера» может быть «список» (сформированный из ссылочной области), который оборачивается вокруг себя (циклическая ссылка). Такой термин может быть создан во многих других Прологах, с той разницей, что это не правильный список. Несмотря на то, что такой термин может быть круговым, он не будет представлять собой большую часть буфера (после его создания), поскольку элементы в списке не могут быть переписаны.

  2. Turbo Prolog поддерживает динамическое утверждение и ретракцию фактов с такими метапредикатами, как asserta / 1 и assertz / 1 , которые позволяют последовательно позиционировать новые факты в начале или конец этих существующих фактов для одного и того же предиката (а также, если необходимо, в указанном именованном «модуле» или базе фактов для использования терминологии Turbo Prolog). Если вашей целью является простое управление элементами в очереди FIFO, то это, скорее всего, тот подход, который вам нужен (по крайней мере для начальной реализации), с элементами, инкапсулированными как факты.

  3. Turbo Prolog также поддерживает «внешние» базы фактов с некоторыми дополнительными функциями, внешними в том смысле, что они сохраняются (либо в памяти, либо на диске) таким образом, чтобы обеспечить постоянство и расширенное пространство сверх того, что выделено для внутренних баз фактов. , Учитывая скромные фиксированные размеры, обычно связанные с циклическими буферами (поскольку они предназначены для повторного использования, а переполнение обычно решается путем блокирования процесса ввода до тех пор, пока процесс вывода не сможет наверстать упущенное), внешние базы фактов, по-видимому, не предлагают много представляет интерес, хотя, возможно, возможность сохранения «буферов» может представлять интерес для длительных процессов.

Надеемся, что эти предложения помогут прояснить, что действительно нужно сделать здесь.

...