REDUCEは、もともと物理学分野への応用を目的として開発された汎用コンピュータ代数システムである。
REDUCE の開発は 1963 年にAnthony C. Hearnによって開始されました。それ以来、世界中の多くの科学者がその開発に貢献してきました。[ 2 ] REDUCE は2008 年 12 月にオープンソース化され、 SourceForgeで修正 BSD ライセンスの下で無料で入手できます。以前は 695 ドルでした。
REDUCEはStandard Lispと呼ばれる独自のLisp方言で完全に記述されており[ 3 ] 、RLISPと呼ばれるALGOLに似た構文で表現され、REDUCEのユーザーレベル言語の基盤としても使用されています。
REDUCEの実装は、基盤となるPortable Standard Lisp (PSL)またはCodemist Standard Lisp (CSL)の実装を使用することで、 Unix、Linux、Microsoft Windows、Apple Macintoshシステムのほとんどのバージョンで利用可能です。CSL REDUCEはグラフィカルユーザーインターフェースを提供します。REDUCEは、 Common Lispなどの他のLispでも構築できます。
REDUCE言語は、ALGOL 60をベースとした高水準構造化プログラミング言語ですが(ただし、標準Lispのセマンティクスを採用しています)、ALGOL 60のすべての構文をサポートしているわけではありません。ALGOL 60から発展したPascalや、同じくPascalから発展したModulaと類似しています。
REDUCE は自由形式の言語です。つまり、スペースや改行は意味を持ちませんが、入力ステートメントは互いに区切る必要があり、すべての入力はセミコロン ( ;) またはドル記号 ( $) で終了する必要があります。違いは、入力が有用な (非nil) 値になる場合、区切り文字がセミコロン ( ;) の場合は出力されますが、ドル記号 ( ) の場合は非表示になるということです$。代入演算子はコロン等号 ( :=) で、最も単純な使用法では、左側の変数に右側の式の値を代入します。ただし、REDUCE 変数は値を持たない場合があり、その場合は名前で表示されます。これは、不定元を含む数式を構築および操作できるようにするためです。REDUCE を使用する最も簡単な方法は対話的に行うことです。最後の入力プロンプトの後に入力を入力し、セミコロンで終了してReturnキーまたはEnterキーを押します。REDUCE は入力を処理し、結果を表示します。これはスクリーンショットに示されています。
プログラミング言語では、変数や関数などの構成要素に名前を付けるために識別子を使用し、テキストを格納するために文字列を使用します。 REDUCE 識別子は文字で始まり、文字、数字、アンダースコア文字 ( _) が後に続くことができます。また、REDUCE 識別子には、感嘆符 ( !) の後に入力された任意の文字をどこにでも含めることができます。 REDUCE 文字列は、入力時に二重引用符 ( ") で区切られた任意の文字シーケンスです。二重引用符は、二重引用符を 2 つ入力することで文字列に含めることができます。文字列内には、他のエスケープメカニズムは実装されていません。ファイル名を表すなど、REDUCE のほとんどの状況で、文字列の代わりに識別子を使用できます。
REDUCE のソースコードは、1960 年代のすべてのプログラミング言語と同様に、元々はすべて大文字で書かれていました。(そのため、REDUCE という名前は通常すべて大文字で書かれています。)しかし、現代の REDUCE は(デフォルトで)大文字小文字を区別しないため、通常は小文字で書かれています。(REDUCE のソースコードは小文字に変換されています。)この規則の例外は、文字列内では大文字小文字が保持され、識別子の文字の前に感嘆符 ( ) が付いている場合です。そのため、キャメルケース( 例 )ではなくスネークケース(例) を REDUCE の識別子に!使用するのが慣例となっています。キャメルケースは、感嘆符も使用しないと意味が失われてしまうためです。long_namelongName
以下はREDUCEの「Hello, World!」プログラムです。このようなプログラムとしては、ほぼ最短と言えるほど短いものです。
"こんにちは世界!" ;REDUCEは出力を表示します
こんにちは世界!
上記バージョンより少し長い別のREDUCE「Hello, World!」プログラムでは、次のような識別子を使用します。
!こんにちは世界!!;CSL REDUCE は上記と同じ出力を表示します。(他の REDUCE GUI では、この出力が文字列ではなく識別子であるという理由で斜体で表示される場合があります。)
REDUCEはLispのセマンティクスを継承しているため、すべてのプログラミング構造には値があります。したがって、文と式の唯一の違いは、式の値が使用されますが、文の値は使用されないという点です。文と式という用語は互換性がありますが、一部の構造は常にLispの値を返すnilため、常に文として使用されます。
複数の文や式を、構文上は単一の文や式と同等の単一の単位にまとめる方法は 2 つあります。これは、構造化プログラミングを容易にするために必要なことです。 1 つは、ALGOL 60 から継承されたbegin...構文で、ブロック文または複合end文と呼ばれます。その値は、(オプションの)キーワードに続く式の値です。 もう 1 つは、括弧構文...を使用する方法で、グループ文と呼ばれます。その値は、括弧内の最後の(終了していない)式の値です。どちらの方法も、以下の手続き型プログラミングの例で示されています。return<<>>
REDUCE は条件文と繰り返し文をサポートしており、その一部はブール式によって制御されます。ブール式とは、値が真または偽のいずれかになる任意の式のことです。(REDUCEのユーザーレベル言語は、真偽を表す定数を明示的にサポートしていませんが、 C言語や関連言語と同様に、0はブール値falseを持ち、1やその他の多くの非ゼロ値はブール値trueを持ちます。)
条件文は次の形式をとる。
ifブール式thenステートメント
これに続いて任意で
else声明
例えば、次の条件文は、(数値であると仮定)は正の値をとる。(これは実質的に絶対値関数を実装している。)
n < 0 の場合、n := - n以下の条件文を式として使用することで、0で割ることによって発生するエラーを回避できます。
recip_x := if x = 0 then infinity else 1 / xこのステートメントは、事前にわかっている回数だけステートメントforを繰り返し実行する柔軟なループ構造です。1つのバージョンは次の形式です。
for変数 :=初期step増分until最終doステートメント
ここで、変数はステートメント内で使用できる値を持つ変数の名前であり、initial、increment、finalは数値(できれば整数)です。変数の値はinitialに初期化され、ステートメントが実行されます。その後、変数の値はincrementによって繰り返し増加され、ステートメントが再度実行されます。ただし、変数の値がfinalを超えないことが条件です。一般的な特殊ケース「initial step 1 untilfinal 」は「 initial : final 」と省略できます。
次のforステートメントは、変数の値としてfac。
n := 5 ; fac := 1 $ for r := 2 : n do fac := fac * r ;ファック;このステートメントの別のバージョンでは、リストを反復処理します。forキーワードは、、、またはdoに置き換えることができます。この場合、ステートメントは式になり、制御ステートメントは式として扱われます。の場合、値は制御ステートメントの値の積になります。の場合、値は制御ステートメントの値の合計になります。の場合、値は制御ステートメントの値をリストにまとめたものです。の場合、値は制御ステートメントの値(リストである必要があります)を1つのリストに結合したものです。productsumcollectjoinforproductsumcollectjoin
次のforステートメントは、前の例よりもはるかに簡潔かつ優雅に表現されている。
n := 5 ; for r := 2 : n積r ;2つのループ文
whileブール式doステートメントステートメントrepeatブールuntil式
は条件文と密接に関連しており、事前に知る必要のない回数だけ繰り返し実行されます。違いは、繰り返しはブール式が偽になったときに停止するのに対し、はブール式が真になったときに停止する点です。whileまた、は常にrepeat少なくとも1回は実行され、ブール式の初期化に使用できますが、を使用する場合は、ループに入る前にブール式を初期化する必要があります。repeatwhile
次のwhileステートメントは、変数の値として使用facされます。このコードは代入を式として扱い、その値を使用することに注意してください。n := n - 1
n := 5 ; fac := n $ while n > 1 do fac := fac * ( n := n - 1 );ファック;REDUCEには3つのコメント規約があります。ALGOL 60からコメント文を継承しており、その形式は次のようになります。
コメント これは複数行のコメントです 次の区切り線で終了し、 そのため、区切り文字を含めることはできません。
コメント文は主に古いコードに見られます。
これは%、Standard Lisp から継承した ... コメントで、以下のような形式になっています。
% これは行末で終了する1行のコメントです。 % コードの後の行に表示されることがあります。 % には区切り文字 ";" と "$" を含めることができます。
%...コメントはC++の//...コメントに類似しており、最も一般的に使用されるコメント形式です。
REDUCE は、次のようなCスタイルの/*...コメントもサポートしています。*/
/* これは複数行のコメントです 空間がどこにでも現れ、 区切り文字「;」と「$」を含めることができます。 */
REDUCEのユーザーレベル言語は、以下の代数プログラミングの例に示すように、いくつかのプログラミングパラダイムをサポートしています。
REDUCEは関数型プログラミング言語であるLispをベースとしているため、関数型プログラミングをサポートし、すべてのステートメントに値があります(ただし、常に有用とは限りません)。また、ステートメントの値を無視することで手続き型プログラミングもサポートしています。代数計算は通常、数式を同等だが異なる形式に変換することによって行われます。これは簡略化と呼ばれますが、結果ははるかに長くなる可能性があります。(REDUCEという名前は、この中間式膨張の問題をもじったものです!)REDUCEでは、簡略化ルールとスイッチによって制御され、式が入力または計算されると自動的に簡略化が行われます。このようにして、REDUCEはルールベースプログラミングをサポートしており、これは古典的なREDUCEプログラミングパラダイムです。初期のバージョンのREDUCEでは、ルールとスイッチはグローバルに設定することしかできませんでしたが、最新のREDUCEでは、ルールとスイッチのローカル設定もサポートしており、1つの式の簡略化のみを制御できます。REDUCEプログラムには、多くの場合、複数のプログラミングパラダイムが混在しています。
このスクリーンショットは、シンプルなインタラクティブな使用例を示しています。
簡単なプログラミングの例として、次の問題を考えてみましょう。 関数の番目のテイラー多項式その点についてこれは次の式で与えられる。。 ここ、は の階微分その時点で評価そしての階乗を表す(ただし、REDUCEには高度なべき級数展開機能が含まれていることに注意してください。)
REDUCE における関数型プログラミングの例として、次の 5 番目のテイラー多項式を計算する簡単な方法を示します。約 0。次のコードでは、制御変数はr0 から 5 まで 1 刻みで値を取り、dfは REDUCE微分演算子であり、演算子はsub最初の引数を 2 番目の引数に代入します。このコードは上記の数式と非常によく似ていることに注意してください (そして)
for r := 0 : 5 sum sub ( x = 0 , df ( sin x , x , r )) * x ^ r / factorial r ;デフォルトでは出力[ 4 ]を生成します
これは正しいのですが、テイラー級数とはあまり似ていません。出力制御スイッチをいくつか変更し、作業スペースを表す特殊変数を評価して、最後のws空でない出力式を取得することで修正できます。
allfac をオフにする; revpri 、divをオンにする; ws ;REDUCEにおける手続き型プログラミングの例として、展開点において良好な振る舞いをする関数に対して機能する、一般テイラー多項式を計算する手続きを以下に示します。。
procedure my_taylor ( f , x , x0 , n ); % x0 の周りの x の関数としてf の n 番目のテイラー多項式を返します。 begin scalar result := sub ( x = x0 , f ), mul := 1 ; for r := 1 : n do << f := df ( f , x ); mul := mul * ( x - x0 ) / r ; result := result + sub ( x = x0 , f ) * mul >> ; return result end ;このプロシージャは、my_taylorREDUCE に既に という演算子が含まれているため、このように呼ばれます。記号に続く行末までtaylorのテキストはすべてコメントです。 キーワードは、2 つのローカル変数、およびを導入して初期化します。 キーワードおよび は、ローカル変数を含み、値を返す可能性のあるコードブロックを区切りますが、 および 記号は、ローカル変数を導入しないステートメントのグループを区切ります。%scalarresultmulbeginend<<>>
上記と同じテイラー多項式を計算するには、以下の手順を呼び出すことができます。
my_taylor ( sin x , x , 0 , 5 );REDUCEのGUIは、以下に説明するファイルおよびパッケージ処理の一部または全部についてメニューサポートを提供します。
複雑な計算を行うには、ソースコードをファイルに保存し、対話型入力ではなくREDUCEにそのファイルを読み込むのが便利です。REDUCEへの入力はプレーンテキスト(ワープロソフトなどで生成されるリッチテキストではない)である必要があります。REDUCEのファイル名は任意です。REDUCEのソースコードは、メインソースコードとテストファイルにファイル名拡張子を使用しているため、CSL REDUCEなどのREDUCE GUIでは通常、デフォルトでこれらの拡張子を持つ入力ファイルを受け付けますが、Microsoft Windowsなどのプラットフォームでは拡張子の方が便利な場合があります。REDUCE入力ファイルは、次の行で終了することをお勧めします。.red.tst.txt
;終わり;
ファイル終端マーカーとして。これは歴史的な慣習ではありますが、潜在的な警告メッセージを回避できます。それ以外では、入力ファイルには、REDUCEに対話的に入力される可能性のあるものすべてを含めることができます。コマンド
inファイル1,ファイル2,...
このコマンドは、指定された各ファイルを順番に REDUCE に入力します。これは、実質的に;ファイルの内容が対話的に入力されたかのように動作し、その後、REDUCE は次の対話的な入力を待ちます。このコマンドの終了に使用される区切り文字がセミコロン ( ) の場合、ファイルの内容が出力としてエコーされます。区切り文字がドル記号 ( ドル$) の場合、ファイルの内容はエコーされません。
REDUCE ファイル名は、絶対パスでも現在のディレクトリからの相対パスでも構いません。REDUCE GUI を使用する場合は、現在のディレクトリが何であるかが明確ではないため、絶対パスの方が安全です。ファイル名は、文字列または識別子として指定できます。通常、文字列 (二重引用符で囲む) の方が便利です。そうでない場合、ディレクトリ区切り文字やドットなどのファイル名要素は、感嘆符 ( !) でエスケープする必要があるためです。Microsoft Windows のディレクトリまたはフォルダ区切り文字であるバックスラッシュ( \) は、REDUCE ではエスケープ文字ではないため、REDUCE 文字列で二重にする必要はありませんが、Microsoft Windows 上の REDUCE は、ディレクトリ区切り文字としてスラッシュ( ) も受け入れます。/
REDUCEの出力は、以下のコマンドを実行することで対話型表示ではなくファイルに出力できます。
outファイル;
出力リダイレクトは、以下のコマンドを実行することで完全に終了できます。
shutファイル;
または一時的にコマンドを実行する
out t;REDUCEの入力のコンパイル済みバージョンをファイルに出力したり、コンパイル済みコードをロードしたりするための同様のメカニズムがあり、これはREDUCEを構築するための基礎であり、REDUCEを拡張するために使用できます。
REDUCEは複数のパッケージで構成されています。一部はプリロードされ、一部は必要に応じて自動的にロードされ、一部は使用する前に明示的にロードする必要があります。
load_packageパッケージ1,パッケージ2,...
このコマンドは、指定されたパッケージを順番に REDUCE にロードします。パッケージ名はファイル名ではなく、感嘆符を必要としない単純な識別子です。そのため、通常は識別子として入力しますが、文字列として入力することも可能です。パッケージは、コンパイル済みの Lisp コードの 1 つ以上のファイルで構成され、このload_packageコマンドは適切なファイルが適切な順序でロードされることを保証します。正確なファイル名と場所は、REDUCE が構築されている Lisp のバージョンによって異なりますが、パッケージ名は常に同じです。
REDUCEはLispから動的スコープを継承しており、これはデータには型がありますが変数自体には型がないことを意味します。つまり、変数の型は、その変数に割り当てられたデータの型です。最も単純なREDUCEデータ型は、識別子、マシン番号(つまり、コンピュータハードウェアが直接サポートする「小さな」整数と浮動小数点数)、文字列などの標準Lispアトミック型です。その他のほとんどのREDUCEデータ型は、内部的にはLispリストとして表現され、最初の要素(car)がデータ型を示します。たとえば、REDUCE入力
mat (( 1 , 2 ), ( 3 , 4 ));ディスプレイを生成する
そしてこの行列の内部表現はLispリストである
(mat (1 2) (3 4))
REDUCEで使用される主な代数オブジェクトは、2つの多変数多項式の商であり、その不定元(カーネルと呼ばれる)は、実際には1つ以上の変数(例えば入力)の関数である可能性がある。
z := ( x + y ^ 2 ) / f ( x , y );ディスプレイを生成する
REDUCE は、このような代数オブジェクトに対して 2 つの表現を使用します。1 つはプレフィックス形式と呼ばれ、これは式の標準 Lisp コードであり、入力や出力などの操作に便利です。たとえば、それは
(商 (プラス x (exp y 2)) (fxy))
もう1つは標準商形式と呼ばれ、加算などの代数演算を行うのに適しています。それは
(!*sq ((((x . 1) . 1) ((y . 2) . 1)) (((fxy) . 1) . 1)) t)
REDUCE は必要に応じてこれら 2 つの表現間で変換を行いますが、変換のオーバーヘッドを避けるために、可能な限り標準的な商の形式を維持しようとします。
REDUCEでは変数に型がないため、変数型の宣言はありませんが、変数のスコープ宣言はあります。変数のスコープとは、プログラム全体を通して変数が同じ意味を持つ範囲のことです。デフォルトでは、REDUCEの変数は自動的にグローバルスコープになります。つまり、変数はどこでも同じ意味を持ちます。つまり、変数に値が代入されると、どこでも同じ値に評価されます。変数のスコープを特定のコードブロックに限定するには、キーワードとでコードブロックを区切りbegin、ブロックの先頭で次の構文を使用してend変数を宣言します(上記の代数プログラミングの例で示されているように)。scalar
beginscalar変数1、変数2、...; ステートメントend
このように宣言された各変数には、オプションで代入演算子(:=)と初期値を指定できます。キーワードは「ローカル」scalarという意味で解釈してください。( 「スカラー」という名前の由来はREDUCEの歴史の中に埋もれていますが、おそらくREDUCEの元々のコアであった高エネルギー物理パッケージで定義された相対論的4元ベクトルやディラックガンマ行列とローカル変数を区別するために選ばれたのでしょう。[ 2 ])
キーワードはまたはscalarに置き換えることができます。違いは、変数はデフォルトで 0 に初期化されるのに対し、および変数はデフォルトで Lisp 値(代数的値は 0 です) に初期化される点です。この違いは、REDUCE 実装言語である RLISP (シンボリックモードまたはLisp モードとも呼ばれる) ではより顕著です。それ以外の場合は、ローカル変数の意図された使用方法のドキュメントとして役立ちます。integerrealintegerscalarrealnil
REDUCEの実装、つまりシンボリックモードでのみ使用される変数宣言が他に2つあります。上記のREDUCE begin...ブロックはREDUCEパーサーによって標準Lisp形式に変換され、すべての標準Lisp変数は形式にバインドされるか、宣言されるか、またはする必要があります。RLISPでは、これらの宣言は次のようになります。endprogprogglobalfluid
fluid '(変数1変数2 ...)global '(変数1変数2 ...)
変数はフォームglobal内で再バインドできませんprogが、fluid変数は再バインドできます。この違いは通常、Lispコンパイラにとってのみ重要であり、効率を最大化するために使用されます。インタプリタコードでは、これらの宣言はスキップでき、未宣言の変数は実質的に となりますfluid。
REDUCE は、独立したポータブルなオープンソースのグラフィック パッケージであるgnuplotを介したグラフィック表示をサポートしています。gnuplot は、すべての REDUCE バイナリ ディストリビューションに含まれています。REDUCE GNUPLOT パッケージは、コマンドplot(...を介して、数式やデータセットで定義された曲線や曲面の表示をサポートしています)。このコマンドは、gnuplot の機能の一部のみを公開します。REDUCE TURTLE パッケージと LOGOTURTLE パッケージは、REDUCE GNUPLOT パッケージをベースに構築されており、 2 次元のタートル グラフィックスをサポートしています。LOGOTURTLE パッケージは、色や線の太さの制御、塗りつぶし、テキスト注釈など、gnuplot の追加機能も公開しています。
REDUCE はSourceForgeから入手できます。バイナリ ディストリビューションは、 Subversionリポジトリのスナップショットとして、決まったスケジュールなしで年に数回リリースされます[ 1 ]。また、完全なソース コードの圧縮アーカイブ スナップショットも提供されます。SourceForge では、新しいリリースが利用可能になったときにユーザーに通知するように設定できます。2024 年に、macOS、Linux ( DebianおよびRed Hatベースのシステム)、およびMicrosoft Windowsの 64 ビット バージョン用のバイナリ ディストリビューションがリリースされました。インストーラーには、CSL-REDUCE と PSL-REDUCE の両方が含まれているか、両方で利用可能であり、REDUCE ソース コードが含まれている場合があります。REDUCE は、より広範囲のプラットフォームやCommon Lispなどの他の Lisp システムでソース コードからビルドできます。[ 5 ]
以下のプロジェクトはREDUCEを使用しています。