コンピュータサイエンスにおいて、宣言型プログラミングは、制御フローを完全に記述することなく計算のロジックを表現するプログラミングパラダイムである。[ 1 ]
このパラダイムは、プログラムの実行順序を超えて抽象化することに重点を置いている。これは、高水準プログラミング言語の使用を意味する。
このスタイルを許容する言語では、開発者は問題領域の観点からプログラムが達成すべきことを記述することで副作用を最小限に抑えたり排除したりすることができ、プログラミング言語のプリミティブのシーケンスとしてそれを達成する方法を完全に記述する必要はありません(方法は言語の実装に委ねられます)。宣言型プログラミングは、明示的なステップでアルゴリズムを実装する命令型プログラミングとは対照的です。 [ 2 ] [ 3 ]
関数型プログラミングのパラダイムと同様に、変数の変更は宣言型パラダイムには適合しません。なぜなら、それは命令的な実行順序を意味するからです。
宣言型プログラミングでは、プログラムを形式論理の理論とみなし、計算をその論理理論における演繹とみなすことがある。宣言型プログラミングは、並列プログラムの記述を簡略化することがある。[ 4 ]
一般的な宣言型言語パラダイムには、論理プログラミング(例:Prolog、Datalog、解答集合プログラミング)や代数モデリングシステムなどがある。
Prologなどの論理プログラミング言語やSQLなどのデータベースクエリ言語は、原則として宣言型であるが、手続き型プログラミングもサポートしている。[ 5 ]
その他の定義:
宣言型プログラミングは、よりよく知られている多くのプログラミングパラダイムを含む包括的な用語です。
Haskellのような純粋関数型言語では、すべての関数は副作用を持たず、状態の変化は、プログラム内で第一級オブジェクトとして明示的に表現される状態を変換する関数としてのみ表現されます。純粋関数型言語は命令型ではありませんが、関数の効果を一連のステップとして記述する機能を提供することがよくあります。
制約プログラミングでは、変数間の関係を制約という形で表現し、目標とする解の特性を指定します。制約のセットは、各変数に値を割り当てることで解決され、解が制約の最大数と矛盾しないようにします。制約プログラミングは、関数型プログラミング、論理型プログラミング、あるいは命令型プログラミングといった他のプログラミングパラダイムを補完することがよくあります。
例えば、Makefile は宣言的な方法で依存関係を指定しますが、[ 7 ]実行するアクションの命令的なリストも含まれています。同様に、yacc は宣言的に文脈自由文法を指定しますが、通常は命令型 ( Cなど) であるホスト言語からのコード スニペットが含まれています。
論理プログラミング言語は、主に宣言型のプログラミングスタイルを特徴としています。論理プログラミングでは、プログラムは論理形式で表現された文で構成され、計算はそれらの文を用いて、同じく論理形式で表現された問題を解決します。
Prolog、Datalog、アンサーセットプログラミングなどの論理プログラミング言語は、目標がプログラムの論理的帰結であることを証明するか、プログラムによって定義されたモデルにおいて目標が真であることを示すことによって計算を行います。Prologは、後方推論を用いて目標をサブ目標に還元することで計算を行うのに対し、ほとんどのDatalogシステムは前方推論を用いてボトムアップで計算を行います。アンサーセットプログラムは通常、 SATソルバーを使用してプログラムのモデルを生成します。
物理システムのモデル、つまり数学的表現は、宣言型のコンピュータコードで実装できます。このコードには、動作関係を記述(「宣言」)する命令型の代入ではなく、多数の方程式が含まれています。モデルがこの形式で表現されると、コンピュータは代数操作を実行して、最適な解法アルゴリズムを定式化できます。数学的な因果関係は通常、物理システムの境界で課せられますが、システム自体の動作記述は宣言的または非因果的です。宣言型モデリング言語と環境には、Analytica、Modelica、Simileなどがあります。[ 8 ]
Prolog (1972) は「PROgramming in LOGic」の略です。自然言語の質問応答のために開発され、[ 9 ] SL 解決[ 10 ]を使用してクエリに対する回答を推論し、自然言語の文を解析および生成します。
Prologプログラムの構成要素は、事実と規則です。以下に簡単な例を示します。
猫(トム)。% トムは猫です。ネズミ(ジェリー)。% ジェリーはネズミです。animal ( X ) :- cat ( X ). % 各猫は動物ですanimal ( X ) :- mouse ( X ). % 各ネズミは動物ですbig ( X ) :- cat ( X ). % 各猫は大きいsmall ( X ) :- mouse ( X ). % 各ネズミは小さいeat ( X , Y ) :- mouse ( X ), cheese ( Y ). % 各ネズミが各チーズを食べるeat ( X , Y ) :- big ( X ), small ( Y ). % 各大きな生き物が各小さな生き物を食べるこのプログラムの場合、クエリは成功しますが、失敗します。さらに、クエリは、回答置換によって成功します。eat(tom,jerry)eat(jerry,tom)eat(X,jerry)X=tom
Prolog はプログラムをトップダウンで実行し、SLD 解決を使用して逆方向に推論し、目標をサブゴールに還元します。この例では、プログラムの最後のルールを使用して、クエリに答えるという目標を、まず が成り立つ X を見つけ、次に が成り立つことを示すというサブゴールに還元します。ルールを繰り返し使用してサブゴールをさらに他のサブゴールに還元し、最終的にすべてのサブゴールをプログラム内の事実と統合することに成功します。この逆方向推論、目標還元戦略により、論理プログラム内のルールは手続きとして扱われ、Prolog は宣言型プログラミング言語と手続き型プログラミング言語の両方になります。[ 11 ]eat(X,jerry)big(X)small(jerry)
Prologの幅広い応用範囲は、Prologの50周年を記念した書籍「Year of Prolog」 [ 12 ]で強調されています。
Datalogの起源は論理プログラミングの黎明期に遡りますが、独立した分野として認識されるようになったのは1977年頃です。構文的にも意味的にもPrologのサブセットと言えますが、複合項を持たないためチューリング完全ではありません。
ほとんどのDatalogシステムは、プログラムをボトムアップ方式で実行し、ルールを使用して推論を進め、既存の事実から新しい事実を導き出し、導き出せる新しい事実がなくなったとき、または導き出された事実がクエリと一致するときに終了します。
Datalogは、データ統合、情報抽出、ネットワーク、セキュリティ、クラウドコンピューティング、機械学習などの問題に適用されてきました。[ 13 ] [ 14 ]
解答集合プログラミング(ASP)は、論理プログラミングの安定モデル(解答集合)意味論に基づいて、1990年代後半に発展しました。Datalogと同様にPrologのサブセットであり、複合項を持たないためチューリング完全ではありません。
ASPのほとんどの実装では、まずプログラムをグラウンディングし、ルール内のすべての変数を考えられるすべての方法で定数に置き換え、次にDPLLアルゴリズムなどの命題SATソルバーを使用してプログラムの1つ以上のモデルを生成することによってプログラムを実行します。
その応用は、困難な探索問題や知識表現の解決に向けられている。[ 15 ] [ 16 ]
この文脈では、プログラミング言語を宣言的と呼ぶための基準は、言語と数理論理学との間に明確で数学的に確立された対応関係が存在し、その言語の宣言的意味論が論理のモデルまたは証明論(あるいはその両方)に基づいて構築できることである。