コンピュータ科学において、指示的意味論(当初は数学的意味論またはスコット・ストレイチー意味論として知られていた)は、プログラミング言語の式の意味を記述する数学的対象(指示と呼ばれる)を構築することによって、プログラミング言語の意味を形式化する手法である。プログラミング言語の形式的意味論を提供する他の手法には、公理的意味論や操作的意味論などがある。
大まかに言えば、指示的意味論は、プログラムが行うことを表すドメインと呼ばれる数学的対象を見つけることに関係しています。たとえば、プログラム(またはプログラム句)は、部分関数[ 1 ] [ 2 ]や、環境とシステム間のゲーム[ 3 ]によって表現される可能性があります。
指示的意味論の重要な原則は、意味論は構成的であるべきだということである。つまり、プログラム句の指示は、その部分句の指示から構築されるべきである。
表示的意味論は、1970年代初頭に発表されたクリストファー・ストラッチーとダナ・スコットの研究に端を発する。 [ 1 ] [ 2 ]ストラッチーとスコットによって最初に開発された表示的意味論は、コンピュータプログラムの意味を、入力を出力にマッピングする関数として提供するものであった。[ 2 ]再帰的に定義されたプログラムに意味を与えるために、スコットは、ドメイン間の連続関数、具体的には完全半順序を扱うことを提案した。以下に説明するように、逐次性、並行性、非決定性、ローカル状態などのプログラミング言語の側面に適した表示的意味論を調査する研究が続けられている。
表示的意味論は、並行処理や例外処理などの機能を使用する現代のプログラミング言語、例えばConcurrent ML [ 4 ] 、CSP [ 5 ]、Haskell [ 6 ]向けに開発されました。これらの言語の意味論は構成的であり、句の意味はその部分句の意味に依存します。例えば、適用式の意味は、その部分句 f、E1、E2 の意味論によって定義されます。現代のプログラミング言語では、E1 と E2 は並行して評価でき、一方の実行は共有オブジェクトを介して相互作用することで他方に影響を与え、その結果、両者の意味が互いによって定義される可能性があります。また、E1 または E2 が例外をスローして、他方の実行を終了させる可能性もあります。以下のセクションでは、これらの現代のプログラミング言語の意味論の特殊なケースについて説明します。f(E1,E2)
指示的意味論は、環境(自由変数の現在の値を保持する)からその指示への関数としてプログラム句に帰属されます。たとえば、この句は、n*m2 つの自由変数 と に束縛を持つ環境が与えられたときに指示を生成します。環境内での値が 3 で、の値が 5 の場合、指示は 15 になりますn。[ 2 ]mnm
関数は、引数とそれに対応する結果値の順序対の集合として表現できます。例えば、集合 {(0,1), (4,3)} は、引数 0 に対して結果 1、引数 4 に対して結果 3、それ以外の場合は未定義となる関数を表します。
例えば、階乗関数を考えてみましょう。これは再帰的に次のように定義できます。
int factorial ( int n ) { if ( n == 0 ) return 1 ; else return n * factorial ( n - 1 ); }この再帰的な定義に意味を与えるために、この表記は近似の極限として構築され、各近似は階乗の呼び出し回数を制限します。最初は呼び出しがないため、何も定義されていません。次の近似では、順序対 (0,1) を追加できます。これは、階乗を再度呼び出す必要がないためです。同様に、(1,1)、(2,2) などを追加でき、階乗(n)の計算にはn+1 回の呼び出しが必要なため、各近似ごとに 1 つのペアを追加していきます。極限では、次の全関数が得られます。にその領域内のあらゆる場所で定義されている。
形式的には、各近似を部分関数としてモデル化する。我々の近似は、「より明確な部分階乗関数を作成する」関数を繰り返し適用することである。空の関数(空集合)から始めます。Fはコードで次のように定義できますMap<int,int>( ):
int factorial_nonrecursive ( Map < int , int > factorial_less_defined , int n ) { if ( n == 0 ) then return 1 ; else if ( fprev = lookup ( factorial_less_defined , n -1 )) then return n * fprev ; else return NOT_DEFINED ; }Map < int , int > F ( Map < int , int > factorial_less_defined ) { Map < int , int > new_factorial = Map.empty ( ) ; for ( int n in all <int> ( ) ) { if ( f = factorial_nonrecursive ( factorial_less_defined , n ) ! = NOT_DEFINED ) new_factorial.put ( n , f ) ; } return new_factorial ; }そこで、 Fをn回適用したことを示すために、F nという表記を導入することができる。
この反復プロセスは、部分関数のシーケンスを構築します。に部分関数は、 ⊆ を順序として用いて、連鎖的に完全な部分順序を形成します。さらに、階乗関数のより良い近似のこの反復プロセスは、各⊆を順序付けとして使用します。したがって、不動点定理(具体的にはブルバキ・ウィットの定理)により、この反復プロセスには不動点が存在します。
この場合、不動点はこの連鎖の最小上界であり、それは完全な関数であり、和集合factorialとして表現できます。
今回見つけた不動点は、 Fの最小不動点です。なぜなら、反復計算は定義域内の最小要素(空集合)から開始したからです。これを証明するには、クナスター・タルスキーの定理のような、より複雑な不動点定理が必要です。
パワードメインの概念は、非決定的な逐次プログラムに表示的意味論を与えるために開発されました。パワードメインコンストラクタをPと表記すると、ドメインP ( D ) は、 Dで表されるタイプの非決定的な計算のドメインになります。
多くの研究者は、上記のドメイン理論モデルは、より一般的な並行計算の場合には不十分であると主張してきた。このため、さまざまな新しいモデルが導入されてきた。1980年代初頭、人々は並行言語のセマンティクスを与えるために、表示的意味論のスタイルを使用し始めた。例としては、Will Clinger のアクターモデルに関する研究、Glynn Winskel のイベント構造とペトリネットに関する研究[ 8 ]、および Francez、Hoare、Lehmann、de Roever (1979) による CSP のトレース意味論に関する研究[ 9 ]などがある。これらの研究の方向性はすべて、現在も調査中である (たとえば、CSP のさまざまな表示的モデル[ 5 ]を参照)。
状態(ヒープなど)や単純な命令機能は、上述の表示的意味論で簡単にモデル化できます。重要なアイデアは、コマンドを何らかの状態ドメイン上の部分関数とみなすことです。「 」の意味は、状態を に割り当てx:=3られた状態へ移行する関数です。シーケンス演算子「」は、関数の合成によって表されます。次に、固定小数点構造を使用して、「」などのループ構造に意味を与えます。3x;while
ローカル変数を持つプログラムのモデリングはより困難になります。 1 つのアプローチは、ドメインを扱うのではなく、型をある世界のカテゴリからドメインのカテゴリへのファンクターとして解釈することです。プログラムは、これらのファンクター間の自然な連続関数によって表されます。[ 12 ] [ 13 ]
多くのプログラミング言語では、ユーザーが再帰的なデータ型を定義できます。たとえば、数値のリストの型は次のように指定できます。
データ型リスト= nat * listのCons |空このセクションでは、変更不可能な関数型データ構造のみを扱います。従来の命令型プログラミング言語では、このような再帰リストの要素を変更することが一般的に認められています。
別の例として、型なしラムダ計算の指示の型は次のようになります。
データ型D = D of ( D → D )ドメイン方程式を解く問題は、これらのデータ型をモデル化するドメインを見つけることに関係しています。大まかに言えば、一つのアプローチは、すべてのドメインの集合をそれ自体をドメインとみなし、そこで再帰的な定義を解くことです。
多相データ型は、パラメータで定義されるデータ型です。たとえば、α lists の型は次のように定義されます。
データ型αリスト= Cons of α * αリスト|空したがって、自然数のリストは 型でありnat list、文字列のリストは 型であるstring list。
一部の研究者は、多相性の領域理論的モデルを開発してきた。また、他の研究者は、構成的集合論の枠組みの中でパラメトリック多相性をモデル化している。
最近の研究分野では、オブジェクトおよびクラスベースのプログラミング言語の表示的意味論が取り上げられている。[ 14 ]
線形論理に基づくプログラミング言語の開発に伴い、線形使用のための言語には表示的意味論(例えば、証明ネット、コヒーレンス空間を参照)と多項式時間計算量が与えられた。 [ 15 ]
逐次プログラミング言語PCFにおける完全な抽象化の問題は、長らく表示的意味論における大きな未解決問題であった。PCFの難しさは、それが非常に逐次的な言語であることにある。例えば、 PCFでは並列OR関数を定義する方法がない。そのため、上述したドメインを用いたアプローチでは、完全な抽象化ではない表示的意味論しか得られないのである。
この未解決の問題は、1990年代にゲーム意味論の発展と論理関係を含む技術によってほぼ解決されました。[ 16 ]詳細については、PCF のページを参照してください。
プログラミング言語を別の言語に変換することは、しばしば有用である。例えば、並行プログラミング言語はプロセス計算に変換でき、高水準プログラミング言語はバイトコードに変換できる。(実際、従来の表示的意味論は、プログラミング言語をドメインのカテゴリの内部言語に解釈するものと見なすことができる。)
指示的意味論と操作的意味論を結びつけることは、しばしば重要視される。これは、指示的意味論が数学的で抽象的である一方、操作的意味論がより具体的であったり、計算論的な直観に近い場合に特に重要となる。指示的意味論の以下の特性は、しばしば注目される。
伝統的な意味論においては、妥当性と完全抽象化は、「操作的等価性が指示的等価性と一致する」という要件として大まかに理解できる。アクターモデルやプロセス計算などの、より内包的なモデルにおける指示的意味論においては、各モデル内で等価性の概念が異なるため、妥当性と完全抽象化の概念は議論の的となり、明確に定義するのが難しくなる。また、操作的意味論と指示的意味論の数学的構造は非常に類似する可能性がある。
操作的意味論と表示的意味論の間に保持したいその他の望ましい特性は次のとおりです。
プログラミング言語の指示的意味論における重要な側面の一つは構成性であり、これはプログラムの意味が、その構成要素の意味から構成されることを意味します。例えば、「7 + 4」という式を考えてみましょう。この場合の構成性とは、「7」、「4」、「+」の意味を用いて「7 + 4」の意味を与えることです。
ドメイン理論における基本的な表示的意味論は、以下のように与えられるため構成的です。まず、プログラム断片、つまり自由変数を持つプログラムについて考えます。型付けコンテキストは、各自由変数に型を割り当てます。たとえば、式 ( x + y ) は、型付けコンテキスト ( x : nat, y : nat) で考えることができます。次に、以下のスキームを使用して、プログラム断片に表示的意味論を与えます。
nat自然数のドメインです。〚nat〛=⊥ .nat, y : nat〛=⊥ ×⊥。特殊なケースとして、変数のない空の型コンテキストの意味は、1 つの要素を持つドメインであり、1 で表されます。nat〛:1→⊥は常に「7」関数であり、〚x : nat、y : nat⊢ x + y : nat〛:⊥ ×⊥ →⊥は2つの数を加算する関数です。さて、複合式 (7+4) の意味は、3 つの関数 〚⊢7: nat〛:1→を合成することによって決定されます。⊥、〚⊢4: nat〛:1→⊥、および 〚x : nat、y : nat⊢ x + y : nat〛:⊥ ×⊥ →⊥ .
実際、これは構成的指示意味論の一般的な枠組みです。ここではドメインと連続関数について特別なことは何もありません。代わりに別のカテゴリで作業することもできます。たとえば、ゲーム意味論では、ゲームのカテゴリはゲームをオブジェクト、戦略を射として持ちます。型をゲーム、プログラムを戦略として解釈できます。一般的な再帰のない単純な言語の場合は、集合と関数のカテゴリで十分です。副作用のある言語の場合は、モナドのクライスリカテゴリで作業できます。状態のある言語の場合は、ファンクターカテゴリで作業できます。ミルナーは、インターフェースをオブジェクト、バイグラフを射として持つカテゴリで作業することにより、位置と相互作用をモデル化することを提唱しました。[ 20 ]
ダナ・スコット(1980)によると:[ 21 ]
クリンガー(1981)によると:[ 22 ]: 79
表示的意味論における研究の中には、型をドメイン理論の意味でドメインとして解釈するものがあり、これはモデル理論の一分野と見なすことができ、型理論や圏論との関連性につながる。コンピュータ科学の分野では、抽象解釈、プログラム検証、モデル検査との関連性が見られる。
{{cite book}}: CS1メンテナンス: 場所の発行元が見つかりません (リンク){{cite book}}:|work=無視されました (ヘルプ)