宣言論理プログラミングにおけるアキュムレータ


オリジナルポストからKodumaro .

Declarative Logic プログラミングは、他のパラダイムpogrammersのための全く外国のパラダイムです.
最も人気のあるパラダイムは命令型プログラミング(変更されました)です.そして、それは流れシステム変化を尊重して、コンピュータシステムが順番に実行しなければならないという声明を注文することから成ります.それはマイクロプログラムにできるだけ近いです.
しかし、作成と管理の視力、命令のプログラミングは、効率的な遠くに立って、ハードの達成コード、他のパラダイムよりもバグの多くの否定につながる.
地面を獲得しているライバルのパラダイムはFunction Programming , に基づいてλ-calculus , それは、完全性問題を解決するいくつかの制約を利用します.
これらのパラダイムを超えて、注目すべき二つがある.
  • 宣言型プログラミング:制御フローによってアルゴリズムを表現しませんが、事実ドメインを宣言するのではなく.
  • 論理プログラミング:主に形式論理に基づく.
  • 論理プログラミングは宣言的プログラミングから離れて存在し,宣言論理プログラミングという大きな交差点に存在する.
    命令型プログラミングでは、1命令文をマシンに対して宣言しているが、宣言論理プログラミングでは、事実ドメインと節間の論理関係を定義する.
    「順序」はシステムに与えません、代わりに質問は尋ねられます.答えを理解しようとするシステムの余波は期待されるプログラムの振る舞いです.
    行動はI/O副作用からドメイン変更自体に異なります.
    をしましょうProlog Prologは4種類の節を持っています:facts, rules, goals, and queries .
    事実は自己満足の真理であり、他の事実や規則に依存しない.たとえば、「アナはボブの友人です」、それは以下の通りに表されることができます:
    friend(anna, bob).
    
    ルールは事実かどうかを検証するための事実やその他のルールに依存します.例えば:
    sunny(Today) :- \+ raining(Today).
    
    今日は晴れなら晴れ\+ ) 雨
    目標はターゲット変数で、変数はありません.クエリは、変数を使用してシステムに尋ねた質問です.
    クエリは、true、false、または変数の値に応じて複数の回答を与えることがあります.目標はtrueでなければなりません.

    フィボナッチ


    今フィボナッチ数を定義しましょう.
    2つの最初の値(インデックス0と1)が1に等しいことが必要です.ひとつはprologでこれを表します:
    fibonacci(0, 1).
    fibonacci(1, 1).
    
    ステップは、その2人の前任者の合計として定義されます.現在の値を呼び出すのは有効ですN 前任者N1 and N2 :
    fibonacci(N, R) :- succ(N1, N),
                       succ(N2, N1),
                       fibonacci(N1, R1),
                       fibonacci(N2, R2),
                       plus(R1, R2, R).
    
    これは有効な実装ですが、深刻なスタックオーバーフロー問題です.TCO を解決するために必要です.
    つの規則を定義しましょう:主なものは補助的なものを呼んでいます.補助ルールは、結果を転送するためにアキュムレータを使用します.
    fibonacci(N, R) :- N >= 0,
                       fibonacci(N, 0, 1, R).
    
    fibonacci(0, _, R, R) :- !.
    fibonacci(N, A, B, R) :- succ(N1, N),
                             plus(A, B, AB),
                             fibonacci(N1, B, AB, R).
    
    The fibonacci/2 主な規則ですfibonacci/4 は補助的なものです.N ), つのアキュムレータA and B ), と結果R ).
    最後の呼び出しはfibonacci/4 , それはTCOを利用する.

    確定節文法


    Definite clause grammar (dcg)は,prologにおける自然文法と形式文法を表現する方法である.これは-->/2 文法クリアランスの構文砂糖としての節.
    恥ずかしいことに、最後の2つのパラメータを省略し、節の連鎖を作成します.
    The fibonacci//2 のようになります.
    fibonacci(0, _) --> '=', !.
    fibonacci(N, A) --> { succ(N1, N) },
                        call(\B^B^B^(true), B),
                        plus(A),
                        fibonacci(N1, B).
    
    巻き括弧はN1 ASN ’チェーンを変更せずに前任者.The call//2 ( call/4 ) 定義するラムダを使用するB 最初の暗黙のパラメータとして.
    その後、A 値は最初の暗黙のパラメータに加えられます.
    最後に、再帰は前置詞、元の最初のパラメータを通過すると呼ばれます.そして、現在の暗黙のパラメタが続きました.
    次のクエリを実行できます.
    forall(between(0, 10, X), (fibonacci(X, F), writeln({X, F}))).
    
    いくつかのDCGの魔法のためにAnne Ogborn tutorial .
    好奇心のため、上記のDCGは以下のように拡張されます:
    fibonacci(0, _, `_1`, `_R`) :- `_1` = `_R`, !.
    fibonacci(N, A, `_1`, `_R`) :- succ(N1, N),
                                   call(\B^B^B^(true), B, `_1`, `_2`),
                                   plus(A, `_2`, `_3`),
                                   fibonacci(N1, B, `_3`, `_R`).