1

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

4

2 回答 2

0

我不确定需要为您的应用程序实现“循环缓冲区”的哪些功能。一般来说,“缓冲区”是可重用的存储,通常与处理异步通信的 I/O 进程相关联(因此需要一个允许一个进程领先于另一个进程的缓冲区)。“循环缓冲区”表示一种使用环绕(线性)连续区域的指针(指向有效/未处理数据的开头和结尾)管理可用存储的方法。这比为有效数据的开始维护一个具有固定位置的 FIFO 队列具有优势,因为不需要对未处理的项目进行“混洗”。

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

这里有一些想法:

  1. Turbo Prolog 支持的列表在某些方面比标准 Prolog 的正确列表更具限制性,并且可能在其他方面更复杂。其中一个限制是,在 Turbo Prolog 中,列表的所有项目都必须属于同一个“域”,这是一个与标准 Prolog 的弱类型字符不同的概念。在 Turbo Prolog 中,域也可以被指定为“参考”域,这是一种允许在子目标之间传递部分绑定的复合项的间接级别。无需过多详细介绍,“循环缓冲区”的一种含义可能是一个“列表”(由参考域形成),它环绕自身(循环参考)。这样的术语可以在许多其他 Prolog 中创建,区别在于它不是一个正确的列表。尽管这样的术语可能是圆形的,

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

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

希望这些建议能够阐明这里真正需要完成的工作。

于 2011-06-01T15:29:26.530 回答
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].

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

于 2011-06-10T14:59:47.380 回答