turboprolog 2.0中的循环缓冲区

turboprolog 2.0中的循环缓冲区,prolog,circular-buffer,turbo-prolog,Prolog,Circular Buffer,Turbo Prolog,我需要在TurboProlog2.0中编写类似于循环缓冲区的东西来计算平均值。我不知道我需要写什么谓词,也不知道如何将它们连接在一起 我不确定您的应用程序需要实现“循环缓冲区”的哪些功能。通常,“缓冲区”是可重用的存储,通常与处理异步通信的I/O进程相关联(因此需要一个允许一个进程领先于另一个进程的缓冲区)。“循环缓冲区”表示一种使用指针(指向有效/未处理数据的开始和结束)管理可用存储的方法,指针通过(线性)连续区域进行环绕。这比为有效数据的开始维护具有固定位置的FIFO队列具有优势,因为不需要

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

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

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

以下是一些想法:

  • turboprolog支持的列表在某些方面比标准Prolog的适当列表更具限制性,在其他方面可能更为详细。其中一个限制是,在turboprolog中,列表的所有项都必须属于同一个“域”,这一概念与标准Prolog的弱类型特征无关。在Turbo Prolog中,域也可以指定为“参考”域,这是一种间接级别,允许在子目标之间传递部分绑定的复合项。如果不深入太多细节,“循环缓冲区”的一种含义可能是一个“列表”(由引用域形成),它本身就是一个循环引用。这种术语可以在许多其他序言中创建,区别在于它不是一个合适的列表。虽然这样一个术语可能是循环的,但它不会成为缓冲区(一旦创建),因为列表中的项目无法重写

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

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


  • 希望这些建议能引起一些澄清,说明这里真正需要完成的工作。

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

    % 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).
    
    返回

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

    返回

    BufferAfter = [2,3,4,5], Result = 1.
    
    DataAfrer = [2,3,4,5,6], BufferAfter = [7,8,9,1].
    
    现在,为了演示任何计算,我们需要编写一个程序,该程序将运行“consumer”,直到缓冲区为空。当缓冲区为空时,“消费者”将运行“生产者”。并在数据和缓冲区为空时停止该过程。
    希望对任何人都有用。

    我甚至不知道他们写了2.0。根据谷歌前五名(3个torrents,1个Amazon…还有这里)的数据,没有多少人能做到。我可以想出几种方法,但不清楚如果“计算平均值”是目标,为什么需要循环缓冲区。您能解释一下为什么简单的列表不合适吗?主要目标是在turbo prolog中实现循环缓冲区。计算平均数是他作品的一个例证。