平均を計算するには、TurboProlog 2.0 で循環バッファーのようなものを記述する必要があります。どの述語を書く必要があるのか わかりません。また、それらをどのようにリンクするのかわかりません。
2 に答える
いろいろ考えた結果、以下のプログラムを書きました
% 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」を実行するプログラムを書く必要があります。そして、バッファが空の場合、「消費者」は「生産者」を実行します。データとバッファが空になると、プロセスを停止します。希望は誰にとっても役に立ちます。
アプリケーションで「循環バッファ」のどの機能を実現する必要があるのか わかりません。一般に、「バッファ」は再利用可能なストレージであり、多くの場合、非同期通信を処理する I/O プロセスに関連付けられます (したがって、1 つのプロセスが他のプロセスよりも先に進むことができるバッファが必要です)。「循環バッファ」は、(線形の) 連続領域を循環するポインタ (有効/未処理データの先頭と末尾の両方) を使用して、使用可能なストレージを管理する方法を示します。これには、未処理のアイテムの「シャッフル」が必要ないため、有効なデータの開始位置が固定された FIFO キューを維持するよりも利点があります。
メモリ位置の書き換えが直接サポートされていない標準の Prolog の一般的なコンテキストでは、その利点は意味がありません。Turbo Prolog でさえ、利用可能な拡張/非標準機能を巧みに使用できるように、達成したいことを正確に尋ねなければなりません。
ここにいくつかのアイデアがあります:
Turbo Prolog は、標準の Prolog の適切なリストよりも、いくつかの点で制限が厳しく、おそらく別の点でより精巧なリストをサポートしています。制限の 1 つは、Turbo Prolog では、リストのすべての項目が同じ「ドメイン」に属していなければならないということです。これは、標準の Prolog の弱く型付けされた文字とは異なる概念です。また、ドメインは、Turbo Prolog で「参照」ドメインとして指定することもできます。これは、サブゴール間で部分的にバインドされた複合語を渡すことを許可する間接レベルです。あまり詳しく説明しなくても、「循環バッファー」の 1 つの意味は、それ自体 (循環参照) をラップする (参照ドメインから形成された) 「リスト」である可能性があります。このような用語は、他の多くのプロローグで作成できますが、適切なリストではないという違いがあります。そのような用語は循環的ですが、
Turbo Prolog は、asserta/1やassertz/ 1 などのメタ述語を使用して、動的なアサーションとファクトの撤回をサポートします。これにより、同じ述語の既存のファクトの先頭または末尾に新しいファクトを連続的に配置できます (必要に応じて、指定された名前のTurbo Prolog 用語を使用する場合は「モジュール」またはファクトベース)。FIFO キュー内のアイテムを簡単に管理することが目的である場合は、(少なくとも最初の実装では) ファクトとしてカプセル化されたアイテムを使用する方法が最も適しています。
Turbo Prolog は、いくつかの追加機能を備えた「外部」ファクトベースもサポートします。これは、内部ファクトベースに割り当てられたものを超えて持続性と拡張スペースを可能にする方法で (メモリまたはディスク上に) 保存されるという意味での外部です。通常、循環バッファーに関連付けられている適度な固定サイズを考えると (それらは再利用を目的としており、オーバーフローは通常、出力プロセスが追いつく機会が得られるまで入力プロセスをブロックすることによって処理されるため)、外部のファクトベースはあまり提供していないようです。興味深いですが、「バッファ」を永続化する機能は、長時間実行されるプロセスにとって興味深いかもしれません。
これらの提案によって、ここで実際に何を達成する必要があるかが明確になることを願っています。