@node 型,,, Top @chapter 型 @menu * Asir で使用可能な型:: * 数の型:: * 不定元の型:: @end menu @node Asir で使用可能な型,,, 型 @section @b{Asir} で使用可能な型 @noindent @b{Asir} においては, 可読な形式で入力されたさまざまな対象は, パーザにより 中間言語に変換され, インタプリタにより @b{Risa} の計算エンジンを呼び出し ながら内部形式に変換される. 変換された対象は, 次のいずれかの型を持つ. 各番号は, 組み込み函数 @code{type()} により返される値に対応している. 各例は, @b{Asir} のプロンプトに対する入力が可能な形式のいくつかを 示す. @table @code @item 0 @b{0} 実際には 0 を識別子にもつ対象は存在しない. 0 は, C における 0 ポインタに より表現されている. しかし, 便宜上 @b{Asir} の @code{type(0)} は 値 0 を返す. @item 1 @b{数} @example 1 2/3 14.5 3+2*@@i @end example 数は, さらにいくつかの型に分けられる. これについては下で述べる. @item 2 @b{多項式} (数でない) @example x afo (2.3*x+y)^10 @end example 多項式は, 全て展開され, その時点における変数順序に従って, 再帰的に 1 変数多項式として降冪の順に整理される (@xref{分散表現多項式}). この時, その多項式に現れる順序最大の変数を @b{主変数} と呼ぶ. @item 3 @b{有理式} (多項式でない) @example (x+1)/(y^2-y-x) x/x @end example 有理式は, 分母分子が約分可能でも, 明示的に @code{red()} が呼ばれない 限り約分は行われない. これは, 多項式の GCD 演算が極めて重い演算である ためで, 有理式の演算は注意が必要である. @item 4 @b{リスト} @example [] [1,2,[3,4],[x,y]] @end example リストは読み出し専用である. @code{[]} は空リストを意味する. リストに対する 操作としては, @code{car()}, @code{cdr()}, @code{cons()} などによる操作の他に, 読み出し専用の配列とみなして, @code{[@var{index}]} を必要なだけつけることにより 要素の取り出しを行うことができる. 例えば @example [0] L = [[1,2,3],[4,[5,6]],7]$ [1] L[1][1]; [5,6] @end example 注意すべきことは, リスト, 配列 (行列, ベクトル) 共に, インデックスは 0 から始まることと, リストの要素の取り出しをインデックスで行うことは, 結局は先頭からポインタをたどることに相当するため, 配列に対する操作に 比較して大きなリストでは時間がかかる場合があるということである. @item 5 @b{ベクトル} @example newvect(3) newvect(2,[a,1]) @end example ベクトルは, @code{newvect()} で明示的に生成する必要がある. 前者の例で は2 成分の 0 ベクトルが生成され, 後者では, 第 0 成分が @code{a}, 第 1 成分が @code{1} のベクトルが生成される. 初期化のための 第 2 引数は, 第 1 引数以下の長さのリストを受け付ける. リストの要素は左から用いられ, 足 りない分は 0 が補われる. 成分は @code{[@var{index}]} により取り出せる. 実際 には, 各成分に, ベクトル, 行列, リストを含む任意の型の対象を代入できる ので, 多次元配列をベクトルで表現することができる. @example [0] A3 = newvect(3); [ 0 0 0 ] [1] for (I=0;I<3;I++)A3[I] = newvect(3); [2] for (I=0;I<3;I++)for(J=0;J<3;J++)A3[I][J]=newvect(3); [3] A3; [ [ [ 0 0 0 ] [ 0 0 0 ] [ 0 0 0 ] ] [ [ 0 0 0 ] [ 0 0 0 ] [ 0 0 0 ] ] [ [ 0 0 0 ] [ 0 0 0 ] [ 0 0 0 ] ] ] [4] A3[0]; [ [ 0 0 0 ] [ 0 0 0 ] [ 0 0 0 ] ] [5] A3[0][0]; [ 0 0 0 ] @end example @item 6 @b{行列} @example newmat(2,2) newmat(2,3,[[x,y],[z]]) @end example 行列の生成も @code{newmat()} により明示的に行われる. 初期化も, 引数 がリストのリストとなることを除いてはベクトルと同様で, リストの各要素 (これはまたリストである) は, 各行の初期化に使われ, 足りない部分には 0 が埋められる. 行列も, 各要素には任意の対象を代入できる. 行列の各 行は, ベクトルとして取り出すことができる. @example [0] M=newmat(2,3); [ 0 0 0 ] [ 0 0 0 ] [1] M[1]; [ 0 0 0 ] [2] type(@@@@); 5 @end example @item 7 @b{文字列} @example "" "afo" @end example 文字列は, 主にファイル名などに用いられる. 文字列に対しては加算のみが 定義されていて, 結果は 2 つの文字列の結合である. @example [0] "afo"+"take"; afotake @end example @item 8 @b{構造体} @example newstruct(afo) @end example 構造体に関しては, 章を改めて解説する予定である. @item 9 @b{分散表現多項式} @example 2*<<0,1,2,3>>-3*<<1,2,3,4>> @end example これは, ほとんどグレブナ基底専用の型で, 通常の計算でこの型が必要と なることはまずないが, グレブナ基底計算パッケージ自体がユーザ言語 で書かれているため, ユーザが操作できるよう独立した型として @b{Asir} で使用できるようにしてある. これについては @xref{グレブナ基底の計算}. @item 10 @b{符号なしマシン 32bit 整数} @item 11 @b{エラーオブジェクト} 以上二つは, Open XM において用いられる特殊オブジェクトである. @item 12 @b{GF(2) 上の行列} 現在, 標数 2 の有限体における基底変換のためのオブジェクトとして用いられ る. @item 13 @b{MATHCAP オブジェクト} Open XM において, 実装されている機能を送受信するためのオブジェクトである. @item 14 @b{first order formula} quantifier elimination で用いられる一階述語論理式. @end table @node 数の型,,, 型 @section 数の型 @table @code @item 0 @b{有理数} 有理数は, 任意多倍長整数 (@b{bignum}) により実現されている. 有理数は常に 既約分数で表現される. @item 1 @b{倍精度浮動小数} マシンの提供する倍精度浮動小数である. @b{Asir} の起動時には, 通常の形式で入力された浮動小数はこの型に変換される. ただし, @code{ctrl()} により @b{bigfloat} が選択されている場合には @b{bigfloat} に変換される. @example [0] 1.2; 1.2 [1] 1.2e-1000; 0 [2] ctrl("bigfloat",1); 1 [3] 1.2e-1000; 1.20000000000000000513 E-1000 @end example 倍精度浮動小数と有理数の演算は, 有理数が浮動小数に変換されて, 浮動小数として演算される. @item 2 @b{代数的数} @xref{代数的数に関する演算}. @item 3 @b{bigfloat} @b{bigfloat} は, @b{Asir} では @b{PARI} ライブラリにより 実現されている. @b{PARI} においては, @b{bigfloat} は, 仮数部 のみ任意多倍長で, 指数部は 1 ワード以内の整数に限られている. @code{ctrl()} で @b{bigfloat} を選択することにより, 以後の浮動小数 の入力は @b{bigfloat} として扱われる. 精度はデフォルトでは 10 進 9 桁程度であるが, @code{setprec()} により指定可能である. @example [0] ctrl("bigfloat",1); 1 [1] eval(2^(1/2)); 1.414213562373095048763788073031 [2] setprec(100); 9 [3] eval(2^(1/2)); 1.41421356237309504880168872420969807856967187537694807317654396116148 @end example @code{eval()} は, 引数に含まれる函数値を可能な限り数値化する函数である. @code{setprec()} で指定された桁数は, 結果の精度を保証するものではなく, @b{PARI} 内部で用いられる表現のサイズを示すことに注意すべきである. (@ref{eval}, @xref{pari}) @item 4 @b{複素数} 複素数は, 有理数, 倍精度浮動小数, @b{bigfloat} を実部, 虚部として @code{a+b*@@i} (@@i は虚数単位) として与えられる数である. 実部, 虚部は それぞれ @code{real()}, @code{imag()} で取り出せる. @item 5 @b{小標数の有限素体の元} ここで言う小標数とは, 標数が 2^27 未満のもののことである. このような有限 体は, 現在のところグレブナ基底計算において内部的に用いられ, 有限体係数の 分散表現多項式の係数を取り出すことで得られる. それ自身は属する有限体に関 する情報は持たず, @code{setmod()} で設定されている素数 @var{p} を用いて GF(@var{p}) 上での演算が適用される. @item 6 @b{大標数の有限素体の元} 標数として任意の素数がとれる. この型の数は, 整数に対し@code{simp_ff} を適用することにより得られる. @item 7 @b{標数 2 の有限体の元} 標数 2 の任意の有限体の元を表現する. 標数 2 の有限体 F は, 拡大次数 [F:GF(2)] を n とすれば, GF(2) 上既約な n 次多項式 f(t) により F=GF(2)[t]/(f(t)) とあらわされる. さらに, GF(2)[t] の元 g は, f(t) も含めて自然な仕方でビット列とみなされるため, 形式上は, F の元は, g mod f は, g, f をあらわす 2 つのビット列で表現することができる. F の元を入力するいくつかの方法が用意されている. @itemize @bullet @item @code{@@} @code{@@} はその後ろに数字, 文字を伴って, ヒストリや特殊な数をあらわすが, 単独で現れた場合には, F=GF(2)[t]/(f(t)) における t mod f をあらわす. よって, @@ の多項式として F の元を入力できる. (@@^10+@@+1 など) @item @code{ptogf2n} 任意変数の 1 変数多項式を, @code{ptogf2n} により対応する F の元に変換する. @item @code{ntogf2n} 任意の自然数を, 自然な仕方で F の元とみなす. 自然数としては, 10 進, 16 進 (0x で始まる), 2 進 (0b で始まる) で入力が可能である. @item @code{その他} 多項式の係数を丸ごと F の元に変換するような場合, @code{simp_ff} により変換できる. @end itemize @end table 大標数素体の標数, 標数 2 の有限体の定義多項式は, @code{setmod_ff} で設定する. 有限体の元どうしの演算では, @code{setmod_ff} により設定されている modulus で, 属する体が分かり, その中で演算が行われる. 一方が有理数の場合には, その有理数は自動的に現在設定されている 有限体の元に変換され, 演算が行われる. @node 不定元の型,,, 型 @section 不定元の型 @noindent 多項式の変数となり得る対象を@b{不定元}とよぶ. @b{Asir} では, 英小文字で始まり, 任意個のアルファベット, 数字, @samp{_} からなる文字列 を不定元として扱うが, その他にもシステムにより不定元として扱われるもの がいくつかある. @b{Asir} の内部形式としては, これらは全て多項式としての 型を持つが, 数と同様, 不定元の型により区別される. @table @code @item 0 @b{一般不定元} 英小文字で始まる文字列. 多項式の変数として最も普通に用いられる. @example [0] [vtype(a),vtype(aA_12)]; [0,0] @end example @item 1 @b{未定係数} @code{uc()} は, @samp{_} で始まる文字列を名前とする不定元を生成する. これらは, ユーザが入力できないというだけで, 一般不定元と変わらないが, ユーザが入力した不定元と衝突しないという性質を利用して未定係数の 自動生成などに用いることができる. @example [1] U=uc(); _0 [2] vtype(U); 1 @end example @item 2 @b{函数形式} 組み込み函数, ユーザ函数の呼び出しは, 評価されて何らかの @b{Asir} の 内部形式に変換されるが, @code{sin(x)}, @code{cos(x+1)} などは, 評価後 もそのままの形で存在する. これは函数形式と呼ばれ, それ自身が 1 つの 不定元として扱われる. またやや特殊な例として, 円周率 @code{@@pi} や 自然対数の底 @code{@@e} も函数形式として扱われる. @example [3] V=sin(x); sin(x) [4] vtype(V); 2 [5] vars(V^2+V+1); [sin(x)] @end example @item 3 @b{函数子} 函数呼び出しは, @var{fname(args)} という形で行なわれるが, @var{fname} の 部分を函数子と呼ぶ. 函数子には, 函数の種類により組み込み函数子, ユーザ定義函数子, 初等函数子などがあるが, 函数子は単独で不定元として 機能する. @example [6] vtype(sin); 3 @end example @end table