• 検索結果がありません。

1.3 属性の宣言と属性値

1.3.4 変数宣言

Maximaで値を割当てた変数は基本的に大域変数になります.この変数は通常は型も属性も何も

ありません.この大域変数に特定の型を設定したり,初期値を割当てる事も出来ます.

先ず,変数に予め型を指定する函数としてmode declare函数とmodedeclare函数があります.但 し,mode declare函数とmodedeclare函数はMaxima内部では同じ函数です.この変数の宣言に加 えて,初期値を設定する函数にdefine variable函数があります.

変数宣言を行う函数

³

mode declare(変数1⟩,⟨1⟩,· · ·,変数n⟩,⟨n⟩,) modedeclare(函数1⟩,⟨1⟩,· · ·,函数n⟩,⟨n⟩,) mode identity(引数1⟩,⟨引数2)

define variable (変数名,初期値,)

µ ´

mode declare函数は変数i函数iiを設定します.この函数はtranslate函数で変 換する利用者定義の函数で用いる変数の宣言で利用されます.ここでmode declare函数で指定し た型は変数のmode属性に割当てられます.

大域変数のmode属性

³

型 mode declare函数で利用可能な表記 概要

float float,real,floatp,flonum,floatnum 浮動小数点

fixnum fixp,fixnum,integer 整数

rational rational,rat 有理数

number number,bignum,big 任意精度の数

complex complex 複素数

boolean boolean,bool Boolean

list list,listp リスト

any any,none,any check 任意の型

µ ´

以下に簡単な例を示します.

(%i28) mode_declare(x1,integer);

(%o28) [x1]

(%i29) :lisp (get ’$x1 ’mode)

$FIXNUM

(%i29) mode_declare(x2,rat);

(%o29) [x2]

(%i30) :lisp (get ’$x2 ’mode)

$RATIONAL

(%i30) mode_declare(x2,rational);

(%o30) [x2]

$RATIONAL

この例では変数x1を整数型,x2とx3を有理数型として宣言しています.これらの値は各変数 の mode属性に蓄えられています.この属性は LISPの get函数を用いて取出せます. この様 に,mode declare函数は基本的に型の指定を行う函数です. mode declare函数で指定した変数と型 はmode identity函数を用いて検証が出来ます.

(%i9) mode_identity(integer,x1);

(%o9) 128

(%i10) x1:256.988;

(%o10) 256.988

(%i11) mode_identity(integer,x1);

Warning: x1 was declared mode fixnum, has value: 256.988

(%o11) 256.988

(%i12) mode_identity(float,x1);

(%o12) 256.988

(%i13) :lisp (get ’$x1 ’mode);

$FIXNUM

この様に,mode declareで宣言した型以外の値を与える事は可能で, mode identityも変数に割当 てられた型と異なると文句を言うだけです. mode identityは変数のmode属性と指定された属性 が同じものかどうかを検証するのではなく,単純に変数に割当てられた型がmode identityの引数 で指定された型と同じものかどうかを検証する函数で,正しい場合には変数の値を返し,異なる場 合には警告するだけです.

型の検証に関連する大域変数

³

大域変数 初期値 概要

mode checkp true 定数変数の型を検証するかどうか制御

mode check errorp false 型エラー処理の制御

mode check warnp true 型エラーの表示の制御

µ ´

大域変数mode checkpがtrueの場合,mode declare函数で宣言する変数に割当てられた値の型 と,新たに宣言する型が矛盾しないか検証し,矛盾する場合はエラーを返します.

(%i17) x0:1.0$

(%i18) mode_declare(x0,integer);

Warning: x0 was declared mode fixnum, has value: 1.0

(%o18) [x0]

(%i19) mode_checkp:false$

(%i20) mode_declare(x0,integer);

(%o20) [x0]

大域変数mode check errorpがtrueであれば,mode declare函数で値が割当てられた変数に対し, 異なる型で変数の宣言を行う場合にエラーを出力します.

大域変数mode check warnpがtrueの場合,mode identity函数は変数に割当てられた値の型と 指定した型が異なる場合に警告を出します.

define variable函数は変数の宣言に加え,初期値と型の設定が行える函数です. 但し,この函数は

属性を上手く使う事で,変数に値を割当てる際に,その変数の利用者が設定した条件に適合するか どうかを検証する事も行える様に出来ます.

このdefine variable函数の処理手順を以下に示しておきます.

mode declare函数を用いて変数型を宣言します.

declare函数を用いて変数がspecial属性を持つと宣言します.

型がanyでなければ,属性assignに属性値assign-mode-checkを設定します. この属性値が 設定されていない変数に対して,Maximaは変数への値の割当の際に,値の検証を行いません.

値の検証を行う為には大域変数のvalue check属性に述語函数を割当てておく必要がありま す.この設定ではqput函数が有効です.

変数に値が割当てられていなければ,指定した初期値を設定します. もしも値が既に割当てら れていれば,define variable函数は与えられた初期値を割当てずに,そのままの値にしておき ます.

割当ての際に,変数値の検証を行う方法は,qput函数を用いて宣言した大域変数のvalue check属 性に変数値を検証する述語函数名を割当ておきます.以下に,動作例を示しておきましょう.

(%i1) ptest(y):=if not primep(y) then error(y,"is not prime!!")$

(%i2) define_variable(tama,5,integer)$

(%i3) qput(tama,ptest,value_check)$

(%i4) tama;

(%o4) 5

(%i5) tama:15;

15 is not prime!!

#0: ptest(y=15)

-- an error. Quitting. To debug this try debugmode(true);

(%i6) :lisp (get ’$tama ’assign) ASSIGN-MODE-CHECK

(%i6) define_variable(mike,5,any)$

(%i7) properties(mike);

(%o7) [value, special]

(%i9) properties(mike);

(%o9) [value, [user properties, value_check], special]

(%i10) mike:15;

(%o10) 15

(%i10) :lisp (get ’$mike ’assign) NIL

(%i10) :lisp (put ’$mike ’assign-mode-check ’assign) ASSIGN-MODE-CHECK

(%i10) mike:15;

15 is not prime!!

#0: ptest(y=15)

-- an error. Quitting. To debug this try debugmode(true);

この例では,最初に素数でなければエラーを返す述語函数ptestを定義し,それから, define variable 函数で大域変数tamaに初期値5を与えて整数変数として宣言します.それから,qput函数を用い てcheck value属性にptestを与えます.この時, 変数mikeに15を設定しようとすれば,15は素数 ではないのでエラーになっています.

ここまでの動作をもう少し詳しく解説しましょう.先ず,define variable函数による宣言で,変数 の型をintegerと宣言しています.define variable函数は, 変数の型をany以外に指定していれば, 宣言する大域変数のassign属性に内部函数のassign-mode-check函数を割当てます.この内部函数

は変数のvalue check属性に設定された函数を用いて変数の評価を実行する函数です.次に,この

value check属性の設定でqput函数を用いています.ここでの例では,大域変数tamaのvalue check

属性にptest函数を割当てていますね.すると,大域変数tama

に値を割当てる時に,assign-mode-check函数が,大域変数tamaのcheck value属性に割当てられた述語函数で割当てようとする値を

評価します.この例では,ptest函数に15が引渡されます.この例では15が素数でない為にfalseと なり,変数に15が割当てられません.

次の例では, 大域変数mikeの型を any とした場合です. この場合,変数 mikeの value check 属性に値を設定しても,先程の様にmike:15を実行した場合にエラーも何も出ません.この場合, 大域変数mikeのassign属性にassign-mode-checkが設定されていない為です.これはLISPで

(get ’$mike ’assign) を実行すれば, NILが返されるので判ります.

そこで, :lisp (put ’$mike ’assign-mode-check ’assign) として見ましょう.これによって,属性 as-signの値としてassign-mode-checkを設定されます.すると,割当の際に検証が実行される様になり ます.