Turbo Prolog 2.0中的循环缓冲区

时间:2011-05-27 18:45:57

标签: prolog circular-buffer turbo-prolog

我需要在Turbo Prolog 2.0中编写类似循环缓冲区的内容来计算平均值。我不知道我需要写什么谓词,也不知道如何将它们联系在一起。

2 个答案:

答案 0 :(得分:0)

我不确定您的应用程序需要实现“循环缓冲区”的功能。通常,“缓冲区”是可重用的存储,通常与处理异步通信的I / O进程相关联(因此需要一个允许一个进程超前于另一个进程的缓冲区)。 “循环缓冲区”表示使用指针(有效/未处理数据的开头和结尾)管理可用存储的方式,该指针环绕(线性)连续区域。这有利于维护具有固定位置的FIFO队列以用于有效数据的开始,因为不需要“改组”未处理的项目。

在标准Prolog的一般上下文中,不直接支持重写内存位置,这种优势没有意义。即使在Turbo Prolog中,也必须准确询问您想要完成的任务,以便熟练使用扩展/非标准功能。

以下是一些想法:

  1. Turbo Prolog支持的列表在某些方面更具限制性,并且可能在其他方面比标准Prolog的正确列表更精细。其中一个限制是,在Turbo Prolog中,列表中的所有项目必须属于相同的“域”,这是对标准Prolog的弱类型字符的外来概念。在Turbo Prolog中,域也可以被指定为“参考”域,间接水平允许部分结合的化合物术语在子目标之间传递。没有太多细节,一个“循环缓冲区”的意义可能是一个“列表”(由参考域形成),它自身回绕(循环参考)。这样的术语可以在许多其他Prolog中创建,区别在于它不是一个正确的列表。虽然这个术语可能是循环的,但它不会是一个缓冲区(一旦创建),因为列表中的项目无法重写。

  2. Turbo Prolog支持事实的动态断言和撤销,使用 asserta / 1 assertz / 1 等元预测,允许在开始时对新事实进行连续定位或者同一谓词的那些现有事实的结束(以及如果需要,在指定的命名“模块”或事实库中使用Turbo Prolog术语)。如果FIFO队列中项目的简单管理是您的目标,那么这很可能是您想要的方法(至少对于初始实现而言),项目被封装为事实。

  3. Turbo Prolog还支持具有一些附加功能的“外部”事实基础,外部存储(在内存或磁盘上)的方式允许持久性和扩展空间超出为内部事实基础分配的内容。给定通常与循环缓冲区相关的适度固定大小(因为它们用于重用和溢出通常通过阻塞输入过程来处理,直到输出过程有机会赶上),外部事实基础似乎没有提供太多虽然可能持续“缓冲”的能力可能对长期运行的过程感兴趣。

  4. 希望这些建议能够引起一些关于这里真正需要完成的事情的澄清。

答案 1 :(得分:0)

经过深思熟虑,编写了以下程序

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

现在,为了演示任何计算,我们需要编写一个程序,它将运行“consumer”直到缓冲区为空。当缓冲区为空时,“consumer”将运行“producer”。当数据和缓冲区为空时停止进程。 希望对任何人都有用。