Entries

スポンサーサイト
[EDIT]
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
論理プログラミング
[EDIT]
OCamlの記事の途中ですが、溜めに溜めたデータをすべて吹っ飛ばしてしまったので、気力が帰ってくるまでほかの記事を、ということで論理プログラミングについて書きながら待つことにします(^^;
最近記事も重くなってきてますし、ちょっと気分転換というか(笑)
論理プログラミングに関する知識はほとんどないので、間違いなどあったら指摘していただければと思います。

論理プログラミングは数理論理学をプログラミングに取り入れ、さらに人工知能と密接に関わっているため、関数型言語以上に異質な存在に映るでしょう。
ある仮説・問題(=命題)について、すでに証明された問題(=定理・前提)で証明できるかをプログラミングで行うということが論理プログラミングの背景にあります。

例えば、コンピュータによって証明された有名な問題として、
ある図形について「隣り合った図形同士は同じ色にならない」という条件の下、できる限り少ない色数で図形を塗り分けるには「4色あれば十分」
という「4色問題」があります。これは過去の経験則から導き出された「5色で塗り分けられる」という前提が活用されました。

論理プログラミングは命題と定理の関係を記述するのに利用されます。例えば「AとはBとCである」とか、「CはDかEの何れかである」といったことを記述するわけですね。
この二つの前提から、「AはDかEの何れかである。これはAがCと等しいからである」ということが導き出せます。命題を証明したり、新しい解を導き出したりするのは自動です。
もうちょっと具体的な例を、論理プログラミング言語の代表格であるPrologのソースコードとともに挙げてみます。

まずは先ほどの例をプログラミングしてみましょう。%のうしろはコメントになります。
%AとはBとCである
a :- b, c.
%CはDかEの何れかである
c :- d.
c :- e.
:- の左辺を頭部(命題)、右辺を本体(すでに証明された命題)と呼びます。
実際のところは関数型言語のように、それぞれの項に付随する情報を書き加えることが多いです。
cat(tama). %tamaはcatである
cat(tom). %tomもcatである
pet(X) :- cat(X) %catはpetである。Xは変数である
ここでPrologに対して、タマはペットかどうか質問してみます。
?- pet(tama).
Yes
Prologがpetはcatであり、catがtamaと結びつけられているかどうかを判断してYesと答えます。つまり逆説的に答えを導き出したことになります。論理プログラミングは「本体がすべて真であれば頭部は真である」という解釈をするため、この辿りかたが普通になります。
今度はペットに誰がいるかを答えさせてみます。
?- pet(X).
X=tama
pet(X)を満たすcat(X)を導き出し、さらにcat(X)を満たす項を見つけてタマを変数Xに代入しました。
一般的なプログラミング言語ではここで終わってしまうでしょう。でもトムもこの条件を満たします。この問題に対応できるよう、論理プログラミングは複数の答えを導き出すことができます。
X=tamaで止まっているところでセミコロンを入力すると、次の答えを導き出します。
X=tama;
X=tom
ほかの答を求める機能を「バックトラック」、複数の答を持ちえることを「非決定性」といいます。

バックトラックについては「やりなおし」という意味合いがあって、先ほどの例では
pet(X)はcat(X)であり、cat(X)を満たすのは最初に見つかるcat(tama)である
でバックトラックを行うとcat(tama)を答えから取り除いて、もういちどcat(X)を満たす項を探してcat(tom)に辿り着いた、という形になります。
Prologは木という表現でデータを保持し、答えを探しています。数学にある木と同じと考えても差し支えありません。
→ pet(X)
 |
cat(X)
/ \
cat(tama) cat(tom)
pet(X)という入力があると、pet(X) = cat(X)であることから矢印が左に移動します。
pet(X)
 |
 → cat(X)
/ \
cat(tama) cat(tom)
さらにcat(X) = cat(tama) or cat(tom)であり、木の辿り方は左に近い方からというルールから、さらに左に移動し、末端であることから答えとして出力します。
pet(X)
 |
  cat(X)
/ \
→ cat(tama) cat(tom)
ここでバックトラックを行うと選択肢からcat(tama)を取り除いて、矢印は一旦上に戻ります。
pet(X)
 |
 → cat(X)
/ \
  cat(tom)
再びcat(X)を満たすものを探し、cat(tom)に辿り着きます。
pet(X)
 |
  cat(X)
/ \
   → cat(tom)
この状態でさらにバックトラックを行うと答えがなくなります。答がなくなってもエラーとしてプログラムを止めることはなく、答が見つからないと表示してユーザの入力を待ちます。

論理プログラミングにおけるもうひとつの重要な機能がユニフィケーションと呼ばれるものです。ユニフィケーションは先ほどの木構造の探索や入力とソースコードの比較、変数への代入など、論理プログラミングを成り立たせるほとんどの処理を行います。ユニフィケーションは次のようなルールの下で処理を行っていきます。
1. 入力された項と定義された項において、項の片方が変数でもう一方が変数でない場合、変数はもう一方の項と同一と見なす(変数への代入)
2. 同様にそれぞれの項において項の両方が変数ならば、両方の変数は同一と見なす
3. それぞれの項がアトム(変数でないもの)の場合、それぞれが完全に一致した場合に成功する
4. それぞれの項が複合項(f(A)という形式)で、引数(括弧の中。アリティという)が同じ形式である場合、すべての要素で1~4のユニフィケーションが成功する場合に成功する

member(X, [X|_]). % Xがリストの先頭要素と同じ場合
member(X, [_|Y]) :- member(X, Y) % それ以外の場合
この定義に対して次のように質問してみます。
?- member(Z, [tama,tom]).
Z=tama
変数Zにtamaが代入されました。

まずひとつめの定義member(X, [X|_])において、入力member(Z, [tama, tom])との関係は
・ZはXと同じものである………ユニフィケーション2
・Xと[tama, tom]についてはXを[tama, tom]とみなす………ユニフィケーション1
・入力と定義は複合項でアリティは互いに変数とリストである………ユニフィケーション4
 - 変数Zと変数Xは同一………ユニフィケーション1
 - リスト[X|_]とリスト[tama, tom]は互いにリストというアトムである………ユニフィケーション3
 - リスト[X|_]とリスト[tama, tom]はX=tama, _=tom………ユニフィケーション2
・アリティの全要素が満されるから複合項もtrueである………ユニフィケーション4が成功
・変数 _ は捨てて、これまでのユニフィケーションの結果からZ=tamaである
という結論に至り出力します。この状態でバックトラックを行うと
・member([X|_])の項から探査木を一段戻る
・ユニフィケーションが成功する次の頭部を探す
 - member(X, [_|Y])とmember(Z, [tama, tom])でユニフィケーションに成功
 - [_|Y]と[tama, tom]は_=tama, Y=tomで、変数 _ は捨てる………ユニフィケーション1
 - 本体がmember(X, Y)であり、_ が捨てられたmember(Z, [tom])とユニフィケーションに成功
・この結果を引き継いでmember(X, [X|_])とmember(Z, [tom])をユニフィケーション
・X=Zで、[X|_]と[tom]はX=tom, _=nil………ユニフィケーション1
・_ を捨ててX=tom、X=ZよりZ=tomである

論理プログラミングに込み入った条件に見合った答えを導き出す機能を付け加えたのが制約論理プログラミングで、制約プログラミングの始祖です。
論理プログラミングの根本的な制約は「ユニフィケーションできるか」だけで、それ以外の制約を付け加えるために制約プログラミングが考案されたということができます。
スポンサーサイト
関数型言語
[EDIT]
それはFORTRANコンパイラが登場して3年後のこと。ジョン・マッカーシーが、配列を操作するためのプログラミング言語としてLISP(LISt Processing)が登場しました。歴史的に見れば3番目の高級言語です。

LISPのソースコードはそれ自身が配列であり、データでもあります。またプログラミングにおいてソースコードは、ただ実行するだけの「ステートメント=文」と、実行すると一意の値になる「式」が存在しますが、LISPではすべてが式で表されます。よって、サブルーチンを作るとき、値を返さないようなサブルーチンを作ることはできません。
例えばC言語において、以下のソースコード
int main(){
int i = 1;
int j = 0;
return (i > j) ? i : j;
}
の main関数と (i > j) ? i : j; は式であり、ほかは文です。mainは最終的に i か j の値を表すようになり、(i > j) ? i : j; も i か j の値を表します。今回の例であれば i > j は成立し、? の直後の i が式の結果になり、mainはreturn文に続く式 (i > j) ? i : j; の結果である i を表すようになります。
ちなみにreturn (i > j) ? i : j; は
if(i > j){
return i;
}else{
return j;
}
と等価です。

これとまったく同じものをLISPで書くとどうなるか。
(defun main ()
(setq i 1)
(setq j 0)
(if (> i j) i j))
defunは関数に名前を付ける特殊な式で、関数名・引数・関数の定義と続けます。defunはすべてを評価した後、関数名を式の結果とします。
引数は単純な変数のリストという形で書き、その変数に引数の値が渡されます。空の括弧は何もないことを表すnilと評価され、すなわち引数がないことを表します。
setqはいわゆる変数宣言と代入です。setqは第1引数を変数名として変数に第2引数を割り当て、第2引数をそのまま返します。
ifも特殊な式で、比較を行う式・その結果が真(t)だったときの式・偽(nil)だったときの式と並んでいて、比較した式の結果が真だったときの式か偽だったときの式の結果がifの結果となって表されます。
>は続く引数リスト(今回なら i と j)に対して大小比較を行い、第1引数が第2引数より大きければ t、そうでなければnilを式の結果とします。
このように、すべて何かしらの値を返しています。
LISPはこのままでは関数名を返すだけで、実際にその関数を呼び出すことはしてくれません。どこかで呼び出す必要があります。今回の例なら、defunのあとに次のように書きます。
(main)
これでようやく関数が実行され、結果として0が返ってきます。実行する際、まずsetqを順に評価し、i には 0、j は1が割り当てられます。次に (> i j) が評価されます。これは i > j と等価で、今回この式は正しいのでt(真)と評価されます。すると今度はifが評価され、真の場合の式である i の結果を返します。これがmainの結果となって0が返ってきたわけです。

このようにLISPで自作の関数を実行するには自分で呼び出さなければならないので、引数を与える形で関数を作成した方が良い場合が多々あります。今回の例なら以下のように作る方が便利でしょう。
(defun main (i j) (if (> i j) i j))
(main 0 1)
2行目はは引数として0と1を渡しています。引数はそれぞれdefunの第2引数のリスト、今回は i と j に格納されます。引数がsetqと同じような役割を果たすので、関数は前回とまったく同じように評価されます。

関数型言語の古参でかつ定番中の定番とも言えるLISPで説明してきましたが、ほかの関数型言語も大体通用します(当然、構文などは異なりますが)。LISPは数多ある関数型言語の中でも直感的で、学習が容易だと思います。
LISPはLISPだけをつかってLISPそのものを自在に改造できる(メタプログラミング)ので、様々な方言が存在します。ここでいう方言とは、これまでも何度か扱ってきたBASICのように、おなじ言語でも処理系によって拡張されたりしている言語がある、という意味です。
方言としてはEmacsに特化されたEmacs LISP(elisp)、教育向けとして使われているらしいscheme、相次いで現れる方言を統一し、ANSIで標準規格が策定されたCommon LISP、ゼロックスのAltoに採用され一世を風靡したInterLispなどが有名です。この記事では主にCommon LISPを前提としています。例えばschemeでは真と偽の値として#tと#fを用いていて、先ほどの解説をそのまま適用することはできないようです。

それではいよいよ階乗を求めるプログラムです。ほかの言語だと大抵は2桁を超える数値から階乗を求めようとすると桁あふれで求められなかったりしますが(電卓に桁数の上限があるのと一緒)、LISPは数学の問題を解くことを得意としているので、言語レベルで何十桁にも及ぶ数値が扱えます。
(defun fact (n)
(if (<= n 1)
1
(* n (fact (- n 1)))))
関数の定義はこれで終わりです。LISPはリストや関数をすべて括弧で括って表現するので、このように括弧だらけになることで有名です。
実際に階乗を求めるときは例えば次のようにします。
(fact 120)
乗算、減算、比較などすべての演算子が先頭に来るという以外は構造化プログラミングで説明したことが通用します。その際、(fact (- n 1))は再帰になっているのも自明でしょう。

演算子が先頭に来る(前置記法)のはLISP特有のもので、演算子も関数であり、関数名は必ずリストの先頭(LISPではCAR: Contents of Address part of Register と呼ぶのが一般的です)に存在している必要があるからです。
また、LISPではリストのすべての項目に対して関数を適用することができるものもあります。例えば1+2+3+4+5は
(+ 1 2 3 4 5)
とすることで求めることができます。

 すべて表示

構造化プログラミング
[EDIT]
前回は非構造化プログラミングについて実例を使ってみてみましたが、ほかのパラダイムのサンプルがないので比較のしようがありませんでした。今回は構造化プログラミングを、前回のBASICと比べながら見てみます。
言語は引き続きcbasです。というのも、cbasはMinimal BASICを前提としながら構造化とオブジェクト指向に対応しているからです。
いきなりで申し訳ないのですが、階乗を求めるプログラムは以下の通りです。

call main


sub main
num = getFactNumber
max = num


num = fac(num)
print str$(max) + "'s factorial is " + str$(num)
quit
end sub


sub getFactNumber
while
input "Please input factorial number >$", num$
wend num$ = ""
getFactNumber = val(num$)
end sub


sub fac(i)
if i <= 1 then
fac = 1
return
endif
i = i * fac(i - 1)
fac = i
end sub

こんな感じです。別ウィンドウで前回のコードと比較してみてください。やってることは同じなんですが、長くなったわりにはすっきりしたコードに見えるはずです。前回のコードの方が見やすいという人はFORTRANあたりでも苦労することはないでしょう。とはいえ、人気のあるプログラミング言語は進化を続けていて、命令型言語はどれも構造化・オブジェクト指向化の道をたどっているのが現状です。

それはさておいて、順を追って解説しましょう。今回は行番号がないので、コードの先頭を1行目とします。
1行目はサブルーチンコールです。サブルーチンとは、ソースコードを小分けにして再利用しやすくしたもの、サブルーチンコールはサブルーチンに飛んでいく、いわばGOTOです。
call mainとあるのでsub mainまで飛んでいきます。cbasの場合sub ~ end subまでがサブルーチンになります。sub xxx というのはサブルーチンコールしたときの目標です。前回のコードで言えば行番号と同じような役割をしているわけです。

mainサブルーチンの1行目は数値変数numにgetFactNumberを代入しています。が、コードの先を見ていくと、もう一つgetFactNumberが見つかります。subではじまっているので、サブルーチンです。
構造化プログラミングでは、=演算子で代入するときにサブルーチン名を見つけると、サブルーチンコールして処理した結果を直接代入することができます。

では途中にあるコードを飛ばして先にgetFactNumberサブルーチンを見てみましょう。
getFactNumber サブルーチンの1行目にはwhileとあります。これはwendまでに書かれたコードを繰り返し実行するためのキーワードで、while文やwhileループと呼びます。
その次の行に、前回のコードでも出てきたinputがありますね。ユーザーの入力を待つ命令です。

その次の行にwendがあります。ここまでがループの本体となります。後ろにあるnum$ <> ""は見覚えがあるでしょう。前回のプログラムではこんなふうになっていました。
20 IF NUM$ = "" THEN 105
構造化プログラミングでは、たいていこのように、IF(if文)だけに頼ることなく条件判定できるのも特徴のひとつです。
ということは、wend num$ <> ""は空文字であるかどうかの判定をしています。
wendはIFの一種とも言えますから条件判定を行います。ただし、IFとは逆の挙動を示します。IFでは条件が正しいときにTHENまでを実行しますが、wendはIFで言えば、指定した条件が正しくないときにwhileに戻っていきます。したがってnum$ <> ""が正しくない(num$が空でない)と判断するとwhileに戻っていきます。正しいと判断すると、ループを抜け出しwendの次の行に戻っていきます。
前回のコードは該当部分だけを抜粋するとこんな感じでした。

5 LET FLAG = 0 : LET FAC = 1 : LET I =1
10 INPUT "Please input factorial number >", NUM$
20 IF NUM$ = "" THEN 105
105 LET FLAG = 1
125 IF FLAG = 1 THEN 5

処理が一致する部分に同じ行番号を付けて今回のコードを見ると

while
5, 10 input "Please input factorial number >", num$
125, 20 wend num$ <> ""

前回のコードに当てはめると、実行する順番は10→20→125→(5)行目です。125行目は強制的にTHENの後ろまで飛ばされますが。

ではいよいよ次の行に進みましょう。
getFactNumber = val(num$)
はてさて何だこれは。サブルーチンに対して値を代入しているか、サブルーチンとnum$を整数に変換した値を代入しているかのように見えます。これはcbas特有の構文で、サブルーチンを関数のように値を返すものにしたい場合、このようにして戻り値を与えます。
サブルーチンを抜け出したとき、mainサブルーチンの1行目、
num = getFactNumber
においてgetFactNumberに与えておいた値がnumに代入されます。

end subはサブルーチンの終わりです。構造化プログラミングの大多数はこのようにend subなどでサブルーチンを抜け出すか、returnで抜け出します。returnはサブルーチンの途中で何らかの理由で抜け出したいとき、また大部分のプログラミング言語ではサブルーチンの戻り値をreturnに渡します。

getFactNumberサブルーチンを抜けるとmainルーチンの2行目に移ります。変数maxに入力された値が入っているnumを代入しています。前回の30行目のコード
30 LET MAX = VAL(NUM$)
にあたりますが、サブルーチンを抜け出すときにVALで数値に変換しているので、VALがなくなっています。

1行開けて、やっと階乗を求める部分です。
num = fac(num)
どうやら、facというサブルーチンに、3行前で入力された値を与えて(渡して)、それを同じ変数に代入しているようです。というわけでsub fac(i)まで飛んでみましょう。
sub fac(i)
sub xxxがサブルーチンの移動先というのは解説していましたが、括弧の中身までは説明していませんでしたね。
括弧の中身は、先ほどnum = fac(num)の括弧で与えられた値が入っています。つまり i にはnumの値が入っています。この i を引数といいます。
その次は前回も見た、1以下かどうかを判定するIF文ですね。しかしthenの後ろが改行になっていて複数行にまたがっています。構造化プログラミングでは、thenからendifまでを複数行にまたがらせることができます。この中では i が1以下だったときの処理をしていて、サブルーチンの戻り値を強制的に1にしています。returnはサブルーチンを途中で抜け出す命令でした。
i が2以上であればthenからendifまでを飛ばし、endifの次の行に移動します。
ここまでを前回のコードと比較してみましょう
前回:

40 IF MAX <= 1 THEN LET MAX = 1 ELSE GOTO 50
45 GOTO 210
50 LET FAC = FAC * I
55 LET I = I + 1
60 IF I > MAX THEN GOTO 210 ELSE GOTO 50
210

今回:

40 if i <= 1 then
40 fac = 1
45 return
50 endif
50..60 i = i * fac(i - 1)

コードの実行順序は、i が1以下のときは40→40→45で、2以上のときは最初の40→50..60です。
endifの次の行が階乗を求める本体です。i とfacサブルーチンの値とを乗算して、facサブルーチンを呼び出します。このときの引数は i から1を引いた値です。i が1になるまで繰り返されます。サブルーチンの中で自分のサブルーチンを呼出し、頭から実行し直すことを「再帰」といいます。
動作を、変数の中身を見ながら追ってみましょう。i は4とします。それと矢印は関数や変数が返す値を表しています。

3←fac(4 - 1) : REM すべての i = i * fac(i - 1)
2←fac(3 - 1) : REM が先に実行される
1←fac(2 - 1)
if i <= 1 then→true
1←fac = 1
end sub
sub fac(2(i) - 1)
2←i 2← i * 1←fac()
2←fac = 2← i
end sub
sub fac(3(i) - 1)
6←i = 3← i * 2←fac()
6←fac = 6← i
end sub
sub fac(4)
24←i = 4← i * 6←fac()
24←fac = i
end sub

分かりやすくなったでしょうか?かえってわかりにくい?
まずは再帰呼出しになっているfac()をひたすら繰り返し、引数が 1 になったところで(3行目)if i <= 1 thenがtrueになり(4行目)、戻り値として1を返して(5行目)end sub(6行目)で1つ上のsub fac()の再帰呼出し部分に戻ります(7行目=3行目)。ここで i = i * fac(i -1)の i * fac()を実行します(8行目)。fac()の戻り値が1で、このサブルーチンに入ったときに実行されるsub fac(i)の i に与えられた値が i = i * fac(i -1)のすべての i に入っています。サブルーチンの引数を受け取る変数(ここでは i)を用意すると、その名前の変数すべてに引数が割り当てられるからです。

ということで一番最初の再帰呼出しで4 - 1が与えられていますが、一番最後に呼び出された再帰を抜け出すと3行目の状態(i = 2)から継続されます。fac i = i * fac(i -1)は i(2) = i(2) * fac()になっています。facは1を戻り値として返しているのでつまりi = 2(i) * 1(fac())です(8行目)。これを戻り値としてサブルーチンを抜け出します(fac = 2)。
同じようにしてサブルーチンを抜け出しsub fac(3 - 1)(11行目=2行目)のサブルーチンを続行します。fac i = i * fac(i -1)は i = i(3) * fac()でfacの戻り値は2ですから i =3(i) * 2(fac())と等価です。そしてfac = 6として再帰を抜け出します。
最後に再帰の一番上に帰ってきます。一番最初のサブルーチンに与えた引数はsub fac(4)でした。したがってfac i = i * fac(i -1)は i = i(4) * fac()で、facの戻り値は6ですから i = 4(i) * 6(fac())です。これを実行してfac = 24、end subで抜け出してmainに戻り、num = fac(num)を実行します。左辺のnumには24が代入され、printではれて答えが表示され、quitでプログラムを抜け出します。

最後までおつきあいありがとうございました。いかがでしょう?あまり複雑なプログラムではないので実際のところどっちがいいかわからないかもしれませんね。
非構造化プログラミング
[EDIT]
非構造化プログラミング言語がどのようなものか、非構造化プログラミング言語の代表格、BASICで見てみましょう。
BASICは1964年に米ダートマス大学で産声を上げました。コンピュータの教育用としてジョン・ケメニーとトーマス・カーツが開発し、同大学のコンピュータに組み込まれました。このBASICはコンパイラを通して実行されるよう設計されていて、ダートマスBASICと呼ばれるようになります。
1970年代には自作の8ビットコンピュータ、1980年代には8~16ビットパソコンで爆発的に普及します。とくに当時のパソコンにはOSが存在せず、代わりに大幅に機能を削ったBASICを利用していた関係で広く使われ、インタープリタやコンパイラも多数販売されていました。その中の筆頭となるのがMicrosoftで、MS-BASIC、GW-BASIC、QuickBASICといった製品が同社の飛躍に繋がります。後者ふたつはやがてVisual Basicへの足がかりにもなっています。
BASICはFORTRANやCOBOLに次いで標準規格が策定されましたが、将来性をまったく考慮しない限定的なものでした。パソコンの成長は目覚ましく、標準規格はあっけなく陳腐化し、各社で独自の拡張を施すことが流行り、様々なバリエーションが存在します。
その中でも無料で、makeなどすることなくすぐに利用できる、マルチプラットフォームのChipmunk Basic(以下cbasと略)を使ってみます。Mac版は歴史的な経緯でGUIバージョンが存在しますが、コマンドラインバージョン前提で解説します。もちろん中身はほぼ同じどころかGUI用に機能が拡張されているくらいですので、GUIバージョンのコマンドラインウィンドウで実行しても構いません。ターミナル.appから利用する場合はCarbon_window_versionフォルダかcommand-line-versionフォルダにあるbasicというファイルをインストールします。
まずHello,world!の次くらいに定番であろう練習プログラム、階乗を求めます。

5 LET FLAG = 0 : LET FAC = 1 : LET I =1
10 INPUT Please input factorial number >", NUM$
20 IF NUM$ = "" THEN 105
30 LET MAX = VAL(NUM$)
40 IF MAX <= 1 THEN LET MAX = 1 ELSE GOTO 50
45 GOTO 210
50 LET FAC = FAC * I
55 LET I = I + 1
60 IF I > MAX THEN GOTO 210 ELSE GOTO 50
100 REM エラー処理
105 LET FLAG = 1
110 PRINT "ERROR: No input."
120 INPUT "Please input any key to retry >", K$
125 IF FLAG = 1 THEN 5
130 QUIT
200 REM 計算終了
210 PRINT NUM$ + " factorial is " + MAX
220 GOTO 120

テキストエディタで入力し終えたら、アルファベットのファイル名に拡張子.basを付けて保存します。今回はfactor.basとでもしましょう。実行はxtermやターミナル.appなどから
basic factor.bas
でreturnキー。すると10行目(1行目ですが10を指定したため)のPlease input factorial number.が表示され、入力を求めてきます。半角で階乗を求めたい値を適当に入力してください。ただしあまり大きな値は入力しないように。
returnキーを押すと結果が返ってきます。

その前にある5行目は変数の初期化(初めて変数に値を代入すること)です。
LETはLet's GO!などでもおなじみの「~しよう」、「~しなさい」という命令です。つまるところLET FLAG = 0は「変数FLAGと0を等しくしなさい」という意味で、プログラミングでは代入といいます。
実はこのLET、省略することが可能で、FLAG = 0だけでもかまいません。何で省略できるのにわざわざ付けたかというと、プログラミングに慣れていないとFLAG = 0だけでは「変数 FLAGと0は同じである」と勘違いして混乱してしまいます。「変数 FLAGと0は等しくないかもしれないのに同じなのか。等しくなかったらどうなるんだ?」といった感じですね。LET FLAG = 0なら「変数FLAGと0を同じにしなさい」と読むことができ、すんなり理解できるわけです。この辺は教育向けに設計されたゆえのおせっかいというわけです。
BASICは1行1命令といいましたが、コロン : を使うことで1行にまとめることができます。ただし、古いBASICだと1行何文字、と決まっていることが多いので、今回のような短い命令をまとめる程度にしましょう。
というわけで、ここでは変数FLAGは0、残りの変数FACとIは1を代入します。

20行目は入力が空だった(returnだけを押した)場合にエラーとして処理させます。そのときはTHENに続く行番号、ここでは105行目に飛びます。入力が空の場合、変数に格納された文字は空(空文字)になっています。空文字は""と、ダブルクオート2つ「だけ」で表現されます。入力が空かどうかの判定は、変数と空文字が同じであるという比較 IF NUM$ = "" THEN で行います。
NUM$ = "" は一見「変数NUM$を""にする」と思ってしまいますが、手前にあるIFが続く式を比較するという意味を持っているので「変数NUM$と""は等しい」と読むことができるわけです。IFは文字通り「もしも」、THENも「ならば」という意味ですから、「もしも変数NUM$と""が等しいならば」と読みます。すっかり英文になってしまいました。これがBASICのよいところです。
THENの後の数字は、移動する行を指定しています。つまり105行目(実際に105行なくても、頭に付けた数字が行番号です!)に移動する(ジャンプする、飛ぶ)ということになります。入力が空でなかった場合、THENの後の数字は無視して次の行を実行します。

30行目は数値を受け取る変数に、入力された文字を数値に変換してから代入します。入力された数字は文字であり、数値変換しないと数学的な演算が正しくできなくなることがあります。これはプログラムを実行するプログラムが、文字で受け取ったものは文字であり、数字でも計算に使うものではない、数値として受け取ったものは数値であり計算のために使う、というように区別しているからです(実際のところは全然違うんですが、そういうものだと思ってください。ややこしい話ですので)。
VAL(NUM$) というのが文字を数値に変換する関数です。()の中に与えた文字列変数(引数=ひきすうといいます)を数値に変換して、= の左側(左辺)の数値変数に代入します。

40行目に再びIFが出てきました。ここでは変数 MAXが1以下(未満ではない)かどうかを調べます(大小・等不等を比較することを比較演算といいます)。数学では以下を表す不等号として≦がありますが、これは古いコンピュータで使用することができなかったた、また他言語かが進んだ現在でも手軽に入力できるようにするため、<=で代用しています。
閑話休題。比較演算でMAXが1未満とわかったらTHENの後ろが実行されます。前回出てきたIF~THENでは行番号を指定していましたが、今回は LET MAX = 1 ELSE GOTO 50 と書かれています。古いBASICではこのように、行番号を指定して実行する行を移動したり、なんらかの処理を行わせることも可能になっています。
つまりMAXが1以下であれば LET MAX = 1 が実行されてMAXは1を保持し(0および1の階乗は1)、ELSE以降を無視して次の行に移ります。
ELSE以降はMAXが1以上のときに初めて効力を発揮します。THENとELSEの間を無視してELSEに続く1つの命令を実行します。GOTOはBASIC最大の汚点と言われた命令で、指定の行番号かラベルに飛びます。ここでは行番号をしていしているので50行目に飛ぶわけです。

45行目はあとから50行目の前に挿入したのでこうなっています。行番号を2桁以上、通常は10とか100単位で増えるようにして、挿入時は1や5単位で行番号を割り当てておくと、何処に修正を加えたかが分かりやすくなります。ここには40行目でMAXが1以下だったときに、ELSEで飛ばされてくる場所です。GOTO 210と書いてあるので210行目に飛んでいきます。

50行目はいよいよ階乗を求める部分です。階乗の数学的な式は、たとえば4の階乗を求めたいなら1×2×3×4=24です。乗算を繰り返し行うのでループを使います。
まず、階乗の途中計算を入れておくFACに、FACとIを乗じた値を代入します。5行目でFACとIを1に初期化しているので、LET FAC = 1 * 1をやっていることになります。たいていのプログラミング言語は、≦と同じ理由で、×のかわりにアスタリスク * を使います。
55行目でLET I = I + 1を行ってIは2になります。
60行目はIがMAXを超えたかを調べ、等しければ210行目へ抜け出し、そうでなければ50行目に戻ります。この場合LET FAC = FAC + 2なのでFACは1 * 2の結果が代入され、55行目でIが3になります。
MAXを4とすれば、Iはまだ3なので50行目に戻り、LET FAC = 2 * 3が実行されます。55行目でIがMAXと同じ4になりますが、このままではFACは6で、まだ1×2×3までしか計算していないことになります。60行目でIがMAXを超えたかを調べているのはこのためです。50行目と55行目を入れ替えればIとMAXが等しくなったかを調べるようにすることができます。
さて、IはまだまだMAXを超えていないので、再び50行目に飛ばされます。LET FAC = 6 * 4を実行して晴れてFACが24になりました。55行目でIもMAXを超えることになり、ループを抜け出します。

100行目はREMの後ろに「エラー処理」と書かれています。REMはreminderの略で、コメントとか注釈という意味です。Cをご存知なら/* エラー処理 */ですし、HTMLなら<!-- エラー処理 -->と書いたのと同じで、cbasはREMより後ろを無視して次の行に進みます。つまりcbasにとっては何が書いてあるかなど知ったことではないので、日本語を書いても問題ありません。その時はUTF-8Shift-JISで保存しましょう。

105行目はフラグを立てます。フラグというのは、簡単に言えばプログラムの状態を表すものです。例えばエラーが起きているか正常か、といった状態です。105行目には20行目で入力が空だったときに飛んでくる場所でした。つまりエラーが起きたということなので、フラグ変数FLAGに1を入れます。別に1じゃなきゃいけないわけではないのですが、フラグにはたいてい何もなかった(フラグが立っていない)ときは0、何かしらあった(フラグが立った)ときは1を入れます。
110行目はエラーが起きたことを画面に表示します。
120行目はメッセージを確認したかどうかを調べるため、キー入力を待つことでプログラムが勝手に進まないように防いでいます。
125行目はエラーが発生したかどうかを調べています。ここではとりあえず入力が空であることを再度調べています。何度も同じことを調べるのは変な話ですが、あとで理由がわかるでしょう。
エラーが発生していた場合は5行目まで戻ってもう一度計算するチャンスを与えています。

130行目を飛ばして200行目です。コメントとして「計算終了」とあります。つまり階乗の計算が終わったらここに来て色々行うわけです。
210行目では入力された値に対する階乗の結果を表示します。実は文字同士も一応足し算はできます。ただし足し算といっても、文字と文字とを繋ぎ合わせるだけですが。こうすることでいくつもの変数の内容を1つの命令だけで表示させることができます。
220行目はGOTOで120行目に飛ぶよう指定しています。120行目はメッセージを確認するまで待つ処理を入れていました。計算結果を表示したら、やはり一旦実行が止まってほしいですからね。
その次の125行目も存在意義が発揮されます。200番台の行に飛んできた場合、FLAG変数は5行目で0に初期化したままなので、THENの後ろは無視されて130行目に移動します。
130行目のQUITはアプリケーションを終了させる命令です。

いかがでしたか?プログラミングがどのようなものかを理解できる一助になれば幸いです。
非構造化と構造化の違いは次の記事で理解することができるはずです。お楽しみに。
バイトコードと仮想機械
[EDIT]
要望があったので、バイトコードについて解説します。
今後もツイッターやブログコメントで要望があれば、(可能であれば)記事にしていこうと思います。

プログラミングに少しでも興味があるなら、Javaが爆発的に普及していることはご存知でしょう。C言語に比肩するくらいにまで広く使われています。
Javaが普及した秘密はCよりも学習コストが低いこともさることながら、移植性に優れ、比較的新しい言語であるがゆえに近代的な機能を持っているところも大きな理由です。
Javaの高い移植性を実現しているのが、今回扱うバイトコードです。

Javaはもともと、JVM(Java Virtual Machine)と呼ばれる、Javaプログラムを実行するための仮想的なコンピュータ(仮想機械、バーチャルマシン)を用いることで高い移植性を現実のものにしました。
バーチャルマシンとは、端的に言ってしまえばソースコードを一行ずつ読み込んで実行していくインタープリタのことです。ですが、仮想的なコンピュータというだけに、インタープリタとは違ってよりコンピュータに近い仕組みになっています。
Javaはバーチャルマシンに合わせた機械語を実行していきます。本来の機械語はCPUが直接実行するのでCPU依存したものですが、バーチャルマシン用の機械語はCPUが直接実行することはないため、高い移植性を可能にしています。そしてバーチャルマシン用の機械語をバイトコードといいます。

なぜバーチャルマシンが必要なのか、普通のインタープリタでは駄目なのか、という疑問が湧いてくると思います。BASICはインタープリタで実行するプログラミング言語の代表格です(CPU専用の機械語にコンパイルできる方言もたくさんあります)。
BASICで書かれたプログラムは、ソースコードをインタープリタに読み込ませればすぐに実行できます。しかし、実行の手順を見ると、
  1. 字句解析 キーワードを分割して取り出し、構文木と呼ばれるものを作ること

  2. 意味解析 字句解析で得たキーワードが何を意味しているか――演算子なのか、変数名なのか、サブルーチン名なのかなど――を調べる

  3. 実行   構文木をたどり、意味解析の結果に合わせてインタープリタに組み込まれたサブルーチンを実行したり、OSの機能を呼び出したり、ソースコードの読み込み位置を変えたりといった処理を行う

というステップによってプログラムとして機能します。
インタープリタではソースコードを読み込むたびにこれらすべてを行うので、処理速度の遅いコンピュータでは動作が非常に遅いという欠点がありました(現在はコンピュータの性能向上によって、さして気にならない程度になりました)。

それに対して、JavaではJVMの機械語にコンパイルしてから実行させます。このコンパイルの過程で、
  1. 字句解析や意味解析を済ませる

  2. 構文木をたどる順番にソースコードを並べ替える(例えば括弧で括られた計算など、優先順位の高い処理を先に並べることで、実行する順番を気にする必要がなくなる)

  3. インタープリタで呼び出すサブルーチン(命令)を番号に置き換える

  4. コンピュータが高速に処理できるバイナリ(2進数表現、機械的表現)に変換する

といったことを行います。
バーチャルマシンは、インタープリタがプログラムを実行するのに必要な作業のほとんどがあらかじめ済んでいるので、通常のインタープリタより高速に処理できます。
こうしてでき上がったものを中間コードと呼びます。バイトコードは中間コードの一種で、命令番号が1バイト(8ビット、255種類まで)になっているためこのように呼ばれます。

中間コードを利用することは、Java以前からありました。Pascalも初期はP-code(Pseudo Code)と呼ばれる中間コードを利用していますし、BCPLと呼ばれる、C言語の遠い祖先もまた、O-codeと呼ばれる中間コードを利用していました。
最近ではPerl6やRuby、C/Objective-C(ごく一部)、C#やVisualBasic.NETなど、様々なところで用いられるようになってきています。
これらの近代的な言語では、Just In Timeコンパイルと呼ばれる、実行時にバイトコードからネイティブコード(CPU固有の機械語)にコンパイルしたり、バイトコードとして実行している間に頻繁に実行される部分だけをネイティブコードにコンパイルする動的コンパイル(JavaではHotSpotという)などを行って実行速度を大幅に改善する技術が利用されています。
ネイティブコンパイラ(CPU 機械語にコンパイルするコンパイラ)で実装されていたCやObjective-Cは、移植性の高さを持たせ、機械語にかなり近いバイトコードにコンパイルすることで、ネイティブコードにコンパイルしやすくすることが目的のひとつです。
プログラミングとその手法
[EDIT]
プログラミングとは
「プログラムナンバー1番、開会の言葉。校長先生、お願いします」
小学生時代、運動会で読み上げられたこのセリフ。懐かしいものですね。
ことさら運動会では、ことを進める手順が示された紙を手渡され、自分の出番はいつかとか、親御さんなんかも我が子の活躍を残そうとその紙と睨めっこしたりしたかと思います。
運動会を進行するための手順を示された紙を「プログラム」と呼びました。コンピュータにおけるプログラムも、やはり物事を進める手順を書いたものになります。そして、プログラムを作成することを「プログラミング」といいます。走ることを「ランニング」、料理することを「クッキング」というのと同じですね。

コンピュータとして最古のプログラミングは、スイッチや電気配線を手動で切り替えるものと、パンチカードや紙テープ(さん孔テープ)などを用いて、スイッチを自動的に切り替えさせるためのスイッチの状態を示して行っていました。例えば、ある値同士を加算したいときは、加算装置(加算器)に信号を送るように配線を切り替えて(あるいはコンピュータ内部で自動的に切り替えさせて)いたわけです。
後者に該当する全自動コンピュータでは、例えば1+2を計算するにはテープに開いた穴で0(穴なし)と1(穴)の2進数を用い、1と2、そして加算命令を表す番号を作ることでプログラミングしていました。これが一番最初のプログラミング言語、機械語です。
例えば24桁の枠があって、加算命令を最初の5桁で表して、次の3桁で計算結果をどうしたいか――メモリに置いておくとか、画面に表示させるとかプリンタに印刷させるとか――を示して、次の8桁に1、残った8桁に2の穴を開ける、という要領です。仮に「加算してメモリに置いておく」を加算命令を1、出力方法を4として、穴をx、それ以外を_とするとこんな感じでテープやカードにパンチします。
____x x__ _______x ______x_
直前に何が何を意味するかを解説しても、この羅列を見たとたんに頭が混乱するでしょう。また、どこかが間違えていたとき、テープを読み直して意味を把握しつつ間違えを直すには相当な労力が必要です。そこで、先ほどの例であれば加算命令に対してADDという略語(ニーモニック)を当ててやり、略語を用いながらいったん紙にすべてのプログラムを書いて、完成したらすべてのプログラムをニーモニックと2進数(穴の羅列)の対応表とを照らし合わせながらカードに穴を開けていくという方法が考え出されました。アセンブリ言語の誕生です。しかしアセンブリ言語ができても、カードそのものには相変わらず機械語としてパンチされていました。
しかし、対応表から機械語に変換する作業は単純なので、それをコンピュータに担わせるようになります。その作業を担うのがアセンブラと呼ばれるプログラムです。
入力するのは相変わらずパンチカードやさん孔テープですが、穴の組み合わせでソースコードを書き、あとはアセンブラと今の足し算のカードを読み込ませればアセンブラが機械語に直してくれる、ということです。
しかしながら、アセンブリ言語(以下、言語もアセンブラと略)は結局のところ機械の命令を英語による略語にしただけなので、複雑な処理を書くには不向きでした。例えば、(1+2)×(3+4)を計算するには
1をメモリから読み取ってアキュムレータ(累算器:計算の途中結果などを保存しておくメモリ)に入れる
2をメモリから読み取ってアキュムレータに保存された値に直接加算する
アキュムレータからメモリに移動する
3をメモリから読み取ってアキュムレータに入れる
4をメモリから読み取ってアキュムレータの値に加算
1+2の結果を保存した場所から読み取ってアキュムレータの値に乗じる
という、非常に面倒な手順になります。今はアキュムレータに相当するレジスタというものがたくさんあるのでもうちょいスマートなんですが、時代が時代なので。アキュムレータに相当するものすらなかったかもしれませんが...。

なにはともあれこれではさすがに面倒なので、数式を数学通りに書けるようにしたい人もいたわけです。
そこで1952年に、Autocodeなる高級言語が生まれました。
しかし、当時のコンピュータは今のパソコンにすら及ばない時代でしたから、アセンブラか機械語以外は受け入れられず、Autocodeはあまり普及せずに終わりました。とはいえ10年間は使われていたようです。
そのような中、可能な限り性能を引き出すよう機械語を出力する(最適化する)コンパイラとプログラミング言語が1957年に完成します。半世紀以上過ぎた今なお現役のFORTRANです。
当然のごとくその性能に疑いの目が向けられるわけですが、命令の数が大幅に削減できるようにも設計されていて、FORTRANを一気に普及させました。FORTRANは様々なマシンに移植され、より効率的な機械語を出力させようという要求からコンパイラの性能も開発技術も向上していき、コンパイラ型言語の火付け役にもなりました。これ以降、コンピュータとOSの進化、ユーザやプログラマーの要求に合わせて様々なプログラミング言語が開発されることになります。
ちなみにこれら2つの言語はいずれも、アセンブラに一般的な計算式が使えるようになった程度のものだったと言われています。そのうち大成功をおさめたFORTRANは、非常に大きな数値から非常に小さな数値までを扱える浮動小数点数という数値表現方式を持ち、科学計算を中心としたニーズに合わせて進化していきました。この分野は後にスーパーコンピュータへと発展し、FORTRANもスーパーコンピュータに合わせた機能が加わっています。

追記@2011.02.21
プログラミングの歴史を語るうえで欠かせないもう一つの言語に、COBOL(Common Business Oriented Language)があげられます。歴史的に見れば5番目に誕生した高級言語で、FORTRANに次いで2番目に世界標準として仕様が規格化されたこの言語は、もう一つのコンピュータの用途である事務処理のためのプログラミング言語です。
世界初のコンピューターが登場する前にタビュレーティングシステムと呼ばれる自動集計・作表支援機があったことからすれば、事務処理用途としてもコンピュータが使われることは自明でしょう。
こちらはファイルへの入出力を中心としたもので、メインフレーム(コンピュータが登場した当時はコンピュータといえばメインフレームを指しました。現在では様々な用途に合わせたコンピュータが存在するため、メインフレームや大型汎用機などと呼ばれるようになりました)と呼ばれる範疇のコンピュータの特徴であるレコードベースのファイルの扱いに長けています。このファイルは極端に言うと、テキストデータで構成されたデータベースと言うことができるかと思います。たとえば給与明細のような、任意の文字○文字で可変長、3桁ずつ , で区切る数字○桁固定、というような決まりきった形式のデータを表現するのに長けています。
また通貨などは小数点以下まで厳密に扱う必要があるため、プログラム内部でも計算誤差を出さない数値表現が可能になっています。後にJavaなどで多倍長数(任意桁数の整数や小数)演算を行うときに、COBOLでよく使われる数値表現BCD(Binary Coded Decimal、二進化十進数)の一種を利用しています。

一方で、このころ出回ったプログラミング言語はいずれも特定分野に特化されているか性能が悪く、OSを開発するにはアセンブラ一択という状況が続きます。もっとも、当時はほかのCPU向けに移植するという考え自体がなく、同じメーカーでも新しいCPUで従来のOSが動作しなくなった時点でそのCPU向けに作り直す、ということが一般的でした。性能を引き出す以外にも、移植性をほとんど考慮していなかったゆえの選択と言えるでしょう。しかし、FORTRAN以降の高級言語ブームで、手間をかけずに開発したいという思いも高まっていました。

1960年に世界標準として規格が制定されたALGOL(Algorithmic Language)が、まずElliot 503というコンピュータの開発用に拡張を加えて使われ、その拡張版をそのまま利用して1961年からBurroughs(後の汚名高きUNISYS)のコンピュータに用いられました。しかしALGOLにはアセンブラ相当の能力がないと思われることが多く、OSの開発用に使われることはほとんどありませんでした。もっとも、大幅に拡張を施したからこそこれら2つのマシンが生まれたのもまた事実です。
1963年頃に実装されたとされるCPL(Combined Programming Language)はC言語の遠い祖先とされていますが、巨大で複雑だったためコンパイラの開発に時間がかかり、コンパイラが完成した頃には自然消滅しつつあったようです。
1964年にPL/I(Programming Language One)がMulticsの開発に使用され、後に大型機の主力言語のひとつとして今日まで利用され続けています。これのマイクロプロセッサ向けであるPL/Mが開発され、CP/Mの開発にも用いられました。
1966年にはC言語の祖先のひとつとなるBCPL(Basic-CPL)がMultics上で開発されています。CPLを簡素化したもので、これはTRIPOS(1976年)、AmigaOS(1985年)、そしてGUIを使用したパソコンの第一歩であるAlto(1973年)などに使われています。完成間もない頃のBCPLはMulticsのみコンパイラ言語として実装されましたが、コンピュータの性能向上に伴ってほかのコンピュータ向けにもコンパイル可能な言語になりました。現在は開発したマーティン・リチャーズの元でオープンソースで配布されています。
Multicsに挫折したメンバーのうちUnics(現在のUNIX)の開発に携わったケン・トンプソンが、BCPLを基にB言語を作り上げます(1969年)。MulticsではPL/Iが使われていたものの、UNIXはミニコンで開発されていてスペック不足だったためアセンブラが使われていました。B言語はUNIXを高級言語で開発するために誕生しました。B言語はUNIXとともにトンプソンとデニス・リッチー、ブライアン・カーニハンの手によって改良が加えられ、C言語へと生まれ変わり、プログラミング言語・そしてOS開発言語のデファクトスタンダードの地位に居座ります。

パソコンにおいては、8ビットマシン時代にはOSの代わりにBASICが起動したため、BASICが主力でした。
16ビット時代にはようやくOSを搭載できるようになり、BASICとアセンブラ以外の選択肢が出てきました。その中でも特筆すべきなのは、Pascalを利用していたLisaでしょう。Appleが開発を手がけ、商業的には失敗した製品でしたが、Mac OSを開発するのに用いられた関係で、初期のMac OSはPascalで開発されていました。といってもこのPascalは、開発したNiklaus Wirth(ニコラス・ヴィルト)自身がオブジェクト指向の拡張を施したObject Pascalでした。
この拡張版はMS DOSのTurbo Pascal用としても採用されます。こちらは独自に進化を遂げてDelphi言語と名前を変え、C#へと繋がっていきます。
その後Mac OSはC/C++へと移行し、Mac OS XでObjective-Cに移行しています。
WindowsはC#が存在しますが、OSの開発は依然C/C++です。

パラダイム


プログラミング言語は、コンピュータの制御を抽象化する際の手法にも焦点を当てて様々なものが作られてきました。

 すべて表示

AVFチョッパとAFEチョッパ
[EDIT]
電車の制御方式の解説、第8回目を迎えていよいよ大詰めです。...多分。
今回は電機子チョッパ制御の発展系2種を解説します。

AVF(Auto Variable Field: 自動可変界磁)チョッパ方式

電機子チョッパを愛用していた営団は、有楽町線用の7000系開発と同時に、制御方式に改良を加えました。6000系の一時試作車にて、弱め界磁を抵抗器を使わずに行えるAVF(自動可変界磁)チョッパ制御の試験を実施しました。これによって抵抗器を完全に撤廃した速度制御が可能になったのです。

電機子チョッパ制御回路には、電動機に常時通電しておくための閉回路が存在します。チョッパがONの間、閉回路に組み込まれた主リアクトル(ML)は電圧の急上昇を抑制しつつ、自身に電流を蓄えます。チョッパがOFFになると、MLに蓄えられた電流が閉回路を経由して電動機に流れ込んでいくというものでしたね。
AVFチョッパでは、この閉回路に着目して弱め界磁制御を無段階で行おうとするものです。
電動機の界磁巻線の途中に分路、すなわち分かれ道をつくり、その片方は閉回路に直結。さらに閉回路に界磁巻線(分割界磁)を1つ追加します。すると、これがちょうど複巻電動機に似た作用を示します。
チョッパのON時間が短い低速時は閉回路への流入が多く、分割界磁に流れる電流も増加して強界磁状態になります。速度が上がると分割界磁に流れる電流は減少し、弱め界磁に移行していきます。
AFE(Auto Field Excite: 自動界磁励磁)チョッパは、早い話がAVFを素直に複巻電動機で実現したものです。
電気車の制御方式7- サイリスタ位相制御
[EDIT]
電気車の制御方式、7回目となる今回は交流電車の制御方式のひとつ、サイリスタ位相制御について。

第4回で、初期の交流電車の制御方式であるタップ制御を解説しました。
タップ制御は構造が単純な反面、物理的な回路構成でありタップ数を増やしにくく、電圧の無段階制御が不可能であること、そしてなによりも、機械式スイッチで大電流を制御するため、アーク放電が様々なところに悪影響を及ぼします。
そんな折、半導体技術躍進の波に乗って、サイリスタが誕生しました。直流電車でチョッパ制御が普及しはじめると、交流電車でもサイリスタを取り入れるようになると、無電弧タップ制御(タップ間連続電圧制御とも)を経てサイリスタ位相制御が誕生します。
無電弧タップ制御ではアーク放電の解消と電圧の位相制御だけで、タップスイッチは機械スイッチのままでしたが、サイリスタ位相制御は完全な無接点化を実現しています。

位相制御の原理は、タップ制御+電機子チョッパ制御の交流版と考えることができます。
変圧器の二次コイルを2~6段程度に分割し、サイリスタを2つ、逆並列に挿入します。ひとつが+ → - 用、残りが - → +用、ということです。そして各種平滑フィルタで高調波を低減した後、整流して直流モーターに流します。

2段の位相制御を考えてみます。まず1段目の回路をサイリスタでチョッピングします(交流波形の場合は位相制御という)。徐々にON時間を増やしていけば電機子チョッパ制御とほぼ同じ、無段階制御になります。1段だけでは二次回路にかかる電圧があまりにも高いので、もう1段同じ制御をするように回路を設計します。ただし、2段目が機能するのは1段目のOFF時間が0になってからです。通常は2段でも回路電圧が高いので、4段以上が多いようです。その場合も、1つの段のOFF時間が0になってから次の段がスタートします。

どうでしょう。やっていることは電機子チョッパとほとんど同じで、交流ではチョッパという言葉を使わず、位相という言葉を使う、くらいしか違いはありません。

 すべて表示

遮断器と無電流遮断
[EDIT]
今回はちょっとばかり無駄話。いや今までも無駄といえば(略)

今回は遮断器について触れます。
電気鉄道が惰行に入るとき、いったい何が起こっているのか。
惰行とは惰性走行のことですから、モーターの助けもかりずに勢いだけで走っていきます。
その時、電気はどうなっているのかというと、主回路についてはスイッチで遮断され、補助電源回路に流れていきます。補助電源回路というのは、クーラーや室内灯、ヒーターをはじめとしたサービス電源系統と、制御信号や前照灯、電動空気圧縮機、補助電源の根本である蓄電池などに供給する制御電源系統とがあります。

そっちの方はともかくとして、惰行時、あるいは電気制動失効時に主回路の電気を完全に断ち切るため、遮断器という高電圧大電流に対応した特殊なスイッチを用います。
スイッチで電流を遮断するとき、サージと呼ばれる突発的な電圧上昇が起こります。電気車の断流器には、直流電車なら1500Vもの電圧がかかっているので、サージをきっかけに電弧とかアーク放電という放電が起きます。コンセントからプラグをゆっくり引き抜くとバチッと火花が飛びますが、あれのもっと巨大なもの、と思ってもらえば分かりやすいかと思います。
これが起きた瞬間、パコン!とかスコッというような音を立てます。これは車両というか遮断器の構造によっては鳴らないものもありますが。

この放電が発生すると機器に悪影響を及ぼすので、電圧を下げるかそもそも発生しないようにします。初期は断流器と並列に抵抗器を接続するだけの単純な方法で放電を弱めていました。とはいってもノッチをオフにすると制御装置の抵抗器も接続されるため、サージ電圧はだいぶ低くなります。なぜなら、サージはリアクタンス、すなわちコイルから発生するものだからです。電気車のリアクタンスと言えばモーターがあります。つまりサージはモーターから発生し、回路を逆流していきます。しかし、ノッチオフすると再加速に備えて抵抗器がすべて接続されるので、抵抗器に阻まれながら通過していきます。

しかし、チョッパ制御やインバータ制御ともなると抵抗器はほとんど存在しません。そのため別の方法で電圧を下げてあげる必要があります。その解決策が無電流遮断と呼ばれる方法です。
仕組みは簡単で、主制御装置のスイッチング素子でモーターへの電流を弱めてから遮断します。一気にスイッチング素子をオフしてしまうと意味がないので、スイッチング素子をゆっくりと動作させて、電圧を下げてから遮断します。スイッチング素子がゆっくりと動作するため、ジワッという感じの音とともに遮断機からガチャッという音が鳴ります。

モーターのしくみ3- 交流電動機1
[EDIT]
モーターのしくみ、第3回目の今回は交流電動機について解説します。交流電動機は古くから使われているもので、1980年代から鉄道でも導入が進み、今や主力となっています。

交流電動機は直流電動機以上に種類があります。交流電動機を分類するとき、まず入力電源によって以下の2つに分けられます。
・三相交流電動機
・単相交流電動機
この2種類はそれぞれ以下のように細分できます。
・整流子電動機
・誘導電動機
・同期電動機
まず三相交流電動機と単相交流電動機の違いと基本的な動作原理を説明しましょう。

単相交流電動機は入力に単相交流と呼ばれる交流を使います。一番身近な単相交流電源には家庭用コンセントがあります。つまり、家電の多くが単相交流で動いていることになります(例外もたくさんありますが)。
単相交流をコイルに流すと定期的に磁界の向きが変わります。整流子電動機は磁界の向きが交互に変わるだけで回転します。誘導電動機や同期電動機は回転子が特定の速度に達することができれば磁界の向きが変わるだけでも回転を維持できますが、速度0から動かすこと(起動または始動といいます)はできません。そのための工夫が必要になります。

三相交流電動機は入力に三相交流と呼ばれる交流を使います。3本の電線が必要で、それぞれの電線には単相交流が流れています。そしてそれぞれの単相交流は120度の位相差を持たせてあります。単相交流のプラス方向の山が180度、マイナス方向の谷が180度で、山と谷を合わせて360度で現されます。そして電圧0から頂点までが90度です。120度は3本の単相交流のうち2本が電圧0付近で交差するころに1本だけ頂点になる位置です。この頂点のズレを位相差といいます。
電動機に3つ以上のコイルを用意して回転子を取り囲み、それぞれのコイルに三相交流を流すと、界磁電流が最大になったコイルに回転子が引っ張られて回転します。やがて回転方向にあるコイルの界磁電流が最大になると、そのコイルに向かってさらに回転します。これが繰り返されて回転力を得ます。誘導電動機の原理です。それぞれのコイルには電圧が最大になる位置が少しずつずれた交流が最低3系統あるのでこれが実現できます。
単相交流誘導電動機ではコイルをいくつ用意しても電圧は一斉に最大になるので、速度0からは回転できないのです。回転している状態ならコイル2つでも遠心力で電圧が最大になっているコイルに向かっていくことができます。ちなみに1コイルモーターというのはありません。

今回はここまでにします。次回は整流子電動機について解説します。
曲線区間の敷設方法2
[EDIT]
最早レイアウト製作に関係なく曲線区間の敷設方法を学びます。第1回はこちら

反向曲線(はんこうきょくせん)
反向曲線は、単刀直入に言うとS字カーブのことをいいます。反対方向の曲線、ですね。なんとも響きがいいですが、鉄道では厄介者です。突然進行方向が変わるわけですから脱線の危険性が非常に高く、速度も乗り心地も犠牲になります。が、日本は起伏の激しい土地の塊で、簡単に避けられるようなものでもありません。日本でなくても、分岐器を用いると反向曲線がたくさんできあがります。反向曲線では緩和曲線を挿入することはもちろん、10m以上の直線を挿入するよう旧鉄道省で定められました。国産Nスケール(1/150)では66.6mmになります。
車両の性能が上がり高速運転が求められるようになると、反向曲線ができやすい分岐器においては16番を超えるような長大な分岐器を用いるようになりました。

複心曲線(ふくしんきょくせん)
曲線区間を構成する方法のひとつで、中心半径が異なる曲線を複数(大体は2つ)用いたものです。線形は段階的に半径が変わるもので、道床付き線路で緩和曲線として2つの半径のカーブを用いるのも、複心曲線を作りだしているといえます。高速用の長大な分岐器のリード曲線などに用いられています。

全緩和曲線
一方、曲線区間でも全区間を緩和曲線で結ぶ場合があり、これを全緩和曲線といいます。
曲線区間の敷設方法
[EDIT]
モジュールレイアウト製作にあたって復習をかねてみます。

鉄道において曲線区間に線路を敷設するにはいくつものルールがあります。鉄道模型のレイアウト製作でもできるだけこのルールに則って敷設することでリアリティがぐんとアップします。

カント

一番基礎的なルールの1つです。通常、曲線区間にはカントというものを設定します。カントは競輪などでいえばバンクです。高速で曲線区間を通過しようとすると、曲線の外側に向かって力が発生します。例えば投げ縄を作って振り回してみてください。そしてそのまま手を放すと、投げようとしなくてもわずかに飛んでいきます。投げ縄の輪っかに重いものを括りつけていればもっと遠くに飛んでいくでしょう。この遠くに飛ばす力と、振り回している間中輪っかが宙に浮いていられるのが遠心力です。鉄道や自動車などが曲線区間を走行している間でも発生しています。バイクがカーブを走っているとき、車体を曲る方向に傾けますね?こうすることで遠心力と重力のバランスがとれ、カーブが曲りやすくなります。鉄道や自動車のような巨大で重たいものを人力で傾けるわけにはいかないので、地面の方を傾けようというのがカントやバンクです。カントを設けることで制限速度を上げることもできます。このとき、曲線部分でいきなりカントを設けようとすると段差になってかえって危険です。そこで逓減カントといって、カントがなだらかにつくようになっています。
これには例外があって、カントがつけられない内外方以外の分岐器と分岐後基準線か分岐線と並列に戻す部分や、低速で走行するのが前提の側線などでカントがついていないカーブを見ることができます。

模型では脱線するほどの速度で走行しない、むしろ車体が軽すぎてカーブの内側に倒れる危険性があること、横転を回避しようとするとカント量が小さすぎ視覚的効果が得られないといった理由で、長らくは見た目にこだわる人だけがフレキシブルレールを用いてカントを取り入れていましたが、首都圏に構える鉄道模型店「Models IMON」が日本の在来線向け規格「HOj」用に道床付きレールを開発した際、ほとんどのカーブレールにカントをつけて発売しました。道床付きレール普及の立役者、TOMIXがこれを知ってカントレールの開発を視野に入れたという噂がありますが真偽のほどは定かではありません。とはいえユーザからの声は多かったようで、KATOが先行してカントレールを発売、TOMIXは後れを取りながらも単線でも使える仕様で発売しています。IMONではレール自体の重みを利用することでレールを捩り、カントを逓減させるためだけのレールを省略しています。KATO、TOMIXはカントを逓減させるためだけの「アプローチレール」というカーブレールを用意しています。

直線区間との接続方法とカントとの関係

まず一番基礎的なルールです。直線区間から曲線区間に切り替えるに当たって、お互いの区間をなだらかに結ぶ緩和曲線と呼ばれる区間を挿入することになっています。これは、直線から曲線に突然変わると、その場にとどまろうとする慣性の法則と、直進してきた惰性と遠心力が突発的に加わり、直進するかのように脱線してしまうのを防ぐためです。「曲りきれなかった」とはこういうことです。緩和曲線に対して、目標となる半径の曲線は「単曲線」といいます。そして緩和曲線の始まりをBTC、単曲線の始まりをBBC、単曲線の終わりをEBC、緩和曲線の終わりをETCと言います。
緩和曲線についても例外があって、分岐器に含まれる曲線に対しては緩和曲線がありません。また、緩和曲線をどうしても設けられない場合に限り、速度制限を大幅に落したうえで緩和曲線を省略することが可能です。この場合、当然のことながらカントの逓減は直線区間から始めることになります。IMONのカント逓減方法は基本的にこれになります(R700mm台のレールであればポイント返し用のカーブレールで緩和曲線区間でのカント逓減が可能です)

鉄道模型ではカントレール同様、遠心力で脱線するということはまず無いので、やはり見た目にこだわる人だけが取り入れています。道床付きの場合、だいたいは段階的に半径を落していく、という形でしか緩和曲線を挿入することができません。そもそも今では狭い家の中で使うものですから、緩和曲線を入れているとスペースが勿体ないのです。

長くなってきたのでとりあえずここまで。いずれガードレールなどについて触れて締めくくりたいと思います。
UJT型オシレータ
[EDIT]
サイリスタのゲート回路について解説します。鉄道の場合ノッチ位置からどの程度の速度でゲート信号を生成すべきか、など論理的な処理も必要で、そのすべてを解説することはできませんが、ゲート信号をどのようにして生成するかくらいは比較的簡単です。
今回は最も単純なゲート回路を解説します。
サイリスタを駆動するゲート回路は発振回路(オシレータ)として設計されます。その中でも最も単純なのが、ユニジャンクショントランジスタ(UJT: UniJunction Transistor)による弛張(しちょう)型発振回路です。
UJTオシレータ
UJTはひとつのエミッタ端子Eと二つのベース端子B1、B2からなる単接合3端子トランジスタです。B1-B2間にはDC1より一定の電圧を加えます。ツェナーダイオード(電圧安定化素子)Z2はより確実に電圧を安定化させるために接続しています。
キャパシタ(充放電素子)VCを0Vとして、UJTのE-B1間にはDC2より電圧VEを加えます。キャパシタが充電しきっていないとき、DC2から出てきた電流は真っ先にキャパシタに向かって流れ込んで充電を始めます。
キャパシタが充電し終わるとDC2の電流はエミッタに流れ、E-B1間の導通を促進します。電流が流れなくなったキャパシタは放電を始め、UJTのE-B1間を導通させます。するとDC2とキャパシタの電流、そしてDC1の電流が重なってB1から大きな電流が流れ出ます。これをサイリスタのゲート端子に流せばサイリスタも導通します。
キャパシタが放電を続けて一定の電圧VPを下回ると再び充電を開始するため、エミッタに流れる電流が減少しUJTはターンオフします。これを繰り返すことでパルスを生成します。
これはししおどしに例えることができます。DC2を常に流れている水、キャパシタを竹筒、竹筒が倒れる水量をVPとして、竹筒が水を溜めていってVPを超えると竹筒が倒れて水がこぼれ、空になると再び元に戻って水を溜め始めます。

パルスの周波数はキャパシタの電圧容量VPとキャパシタに印可する電源の周波数と電圧に依存します。電源が脈流成分をほとんど除去した直流であればVPと電源電圧に依存することになります。キャパシタもDC2も固定であれば一定周期でパルスを生成し、キャパシタを可変のものとするかDC2を可変とすると、パルスの周波数も可変にすることができます。
ししおどしの竹筒が小さいか、水の勢いが激しければ竹筒は短時間で頻繁に動きますし、大きい竹筒にして水の勢いを絞れば竹筒が倒れるまでの時間が延びるのと同じです。
キャパシタの充電容量を可変としたものには可変容量コンデンサが存在します。DC2の調節は可変抵抗器で行えます。
いずれもマスコンのノッチに合わせてサーボモータの速度を調節して、サーボモータに直結したキャパシタや可変抵抗器を駆動すれば連続制御が可能になります。電機子チョッパ制御や界磁チョッパ制御ならこの要領で単純な力行回路を作ることは可能です。
インバータではさらに目標とする交流周波数とパルス生成の基準となる搬送波を比較したりといった論理回路が必要となってきます。

 すべて表示

モーターのしくみ2 - 直流整流子電動機2
[EDIT]
最初の「モーターのしくみ」で、直流電動機が回転する原理と簡単な回路を学びました。
前回学んだのは永久磁石界磁形電動機の概念図でした。今回は電磁石界磁巻線の回路について学んでいきます。

電磁石界磁巻線形電動機は、基本的に回転子巻線に繋がっていて電気を共有しています。そのため界磁巻線と回転子巻線の繋ぎ方次第で電動機の特性が変わってきます。その繋ぎ方は次のようなものがあります。
・直列  直巻電動機
・並列  分巻電動機
・直並列 複巻電動機
また、界磁巻線に供給する電気を回転子巻線とは別の電源とする他励界磁電動機というものもあります。

直巻電動機

直巻整流子電動機概念図
界磁巻線と回転子巻線が直列接続になっているものを直巻(ちょくまき)電動機と呼び、構造が単純でありながら電気車の制御に最適な特性(大きな始動トルク、回転数の上昇に伴ってトルクが減少、電流を流すだけで速度が上がる「特性領域」が広い)を持っています。交流電源でも使用できるため、ユニバーサルモーターとも呼ばれます。
直巻電動機で回生制動を実現するには、基本的に高価で装置も大きな電機子チョッパ制御か界磁添加励磁制御でなければなりません。
しかしながら実際のところはかなり古くから回生制動が使われています。制動時に電動機を分巻電動機として動作させることで回生効率を向上していました。
日本初の回生制動搭載車両は1928年に製造された高野山電気鉄道(南海電鉄の前身)のデ101形です。この電車は吊り掛け駆動の抵抗制御電車でした。
ほかにも小田急2600形などが抵抗制御で回生制動を実現していました。

制御方式

抵抗制御
 ・バーニア抵抗制御
 ・界磁添加励磁制御
  ・バーニア界磁添加励磁制御
電機子チョッパ制御
 ・自動可変界磁チョッパ制御(AVF: Auto Variable Field)
・界磁位相制御
・変圧器タップ制御
 ・高圧タップ制御
 ・低圧タップ制御
 ・無電弧タップ制御
・サイリスタ位相制御

下図左は上の図を真上から見た回路図、同図右は正面から見た回路図です。以下同様です。
直巻整流子電動機回路概念図

分巻電動機・他励界磁電動機

分巻整流子電動機概念図
界磁巻線と回転子巻線が並列接続になっているものは分巻(ぶんまき)電動機と呼びますが、営団が高周波分巻制御用に用いたほかに採用例はほとんどなかったようです。前述の通り力行ではなく制動時に分巻接続とする車両はいました。
回転数にかかわらずほぼ一定のトルクが得られるほか、負荷が変わっても回転数が変わらないという特性を持っています。

制御方式

・高周波分巻チョッパ制御
分巻整流子電動機回路概念図
一方、界磁電流を別電源から得る他励界磁(たれいかいじ)電動機は分巻電動機の一種ととられることが多いようです。新交通システムに多く使われています。

制御方式

・ワードレオナード制御
 ・静止レオナード(サイリスタレオナード)制御
  ・可逆運転サイリスタレオナード制御
他励界磁整流子電動機回路概念図

複巻電動機

界磁巻線を複数用い、直列と並列繋ぎになるようにした複巻(ふくまき)電動機は、構造が複雑で架線電圧の変動に弱いなど数々の欠点を持っていますが、安価に、そしてあらゆる制御方式で簡単に回生制動を実現することが可能なので私鉄を中心に普及しました。とくに、起動時からの抵抗制御域では直巻電動機が適し、弱め界磁を行うには分巻電動機が適しています。その両方を持ち合わせた複巻電動機はまさにうってつけというわけです。
基本的には直巻電動機と分巻電動機の中間的な特性を持っていますが、鉄道では直巻電動機に近い特性を確保しています。これは単純に分巻巻線と直巻巻線をどのように接続するかで調整できるからなんですね。つまり複巻電動機は何種類か存在します。全部挙げると
・内分巻形和動複巻電動機
・内分巻形差動複巻電動機
・外分巻形和動複巻電動機
・外分巻形差動複巻電動機
があります。難しい単語ばかりで何が何やらわからないかもしれませんが、わかりやすく解説していきます。
まず内分巻(うちぶんまき)ですが、これは分巻界磁電流と電機子電流が等しく、直巻界磁だけ電流が大きくなるように接続されたものです。つまり、先に直巻巻線があって、そこから分巻巻線と回転子が並列に分岐しているものです。
外分巻(そとぶんまき)はすべての巻線の電流が等しいものです。こちらはまず回転子と分巻巻線とに分岐しています。そして回転子を通った後で直巻巻線が回転子を取り囲んでいます。
和動複巻というのは、直巻界磁と分巻界磁の磁束が足し合わさるようになっていて、直巻電動機と分巻電動機の中間的な特性になります。
差動複巻はその逆で、直巻界磁と分巻界磁の磁束が打ち消し合うようになっています。始動トルク(回転した瞬間のトルク)が小さいためあまり用いられないようです。
とまあ色々ありますが、そういう分類のしかたがあるということで、あまり気にしなくても大丈夫です。
構造上回転子は並列となってしまうため、回転子にかかる電圧は電源電圧の半分になってしまいます。一方で界磁電圧も下がるのため、弱め界磁制御がやりやすいといったメリットもあります。

制御方式

・抵抗制御
 ・界磁チョッパ制御
  ・バーニア界磁チョッパ制御
・界磁位相制御
・自動界磁励磁チョッパ制御(AFE: Auto Field Excite)
複巻整流子電動機回路概念図

 すべて表示

電気車の速度制御方式6- 界磁チョッパ制御
[EDIT]
都合上弱め界磁制御と分離しました。

界磁チョッパ制御とは、主に弱め界磁制御をチョッパ装置によって行うものです。
この方式は東急が初代6000系で試験採用し、初代7000系で量産化した直流複巻電動機と界磁調整器による抵抗制御を発展させたもので、界磁調整器をチョッパ装置に置き換えたものになります。同社の8000系で世界初の界磁チョッパ制御電車が誕生します。世界初の電機子チョッパ車、営団6000系の量産が1971年から(試作車は1965年の2000形、6000系試作車は1968年登場)で、東急8000系の量産が1969年からですから、チョッパ制御の量産車として見ても世界初といえます。

チョッパ制御については電機子チョッパの項目を見ていただくとして、早速話を進めます。
複巻電動機は界磁コイルがたくさんあるもので、そのうちの一部の界磁磁束をチョッパ制御するものです。直巻電動機と比べると欠点が多いのですが、独立した界磁があるため界磁を制御しやすく、失効速度は高いものの抵抗制御でも特に工夫することなく回生制動できるようになりました。
また界磁チョッパ制御は、抵抗制御よりも効率良く回生が制動でき、大電流が流れてくる主回路電流を直接制御する電機子チョッパ制御と比べると分巻界磁巻線に流れる電流は小さいため、チョッパ装置も安価なものが使えます。そのためコストに敏感な私鉄を中心に導入が進みます。
界磁チョッパ回路図
複巻電動機は界磁が電機子に対して直列と並列で分かれています。2列の並列接続ということは界磁電流は半分になってしまうということです。分巻界磁の界磁磁束を強めないと分巻界磁側が弱め界磁と同じ状態になってしまい、主回路に流れる電流はさらに低下してしまいます。そのため低速においてはチョッパ装置をONのままにして分巻界磁の電流を上げ、界磁磁束を強めます(逆に1ノッチ目で意図的にチョッパ制御を行えば弱め界磁起動になります)。これで電機子側の界磁(直巻界磁)磁束も強くなり、電気車の速度制御に見合う性能を出します。
そしてそのまま直並列抵抗制御で加速していきます。

高速域では界磁磁束を弱めるため、電機子側の電流を一定にして、分巻界磁側の電流をチョッパ制御で下げます。電機子側にも界磁はありますが、分巻側を制御するだけで弱め界磁制御と同じ効果が得られます。

減速はチョッパ装置で分巻界磁が強くなるように制御し、電気ブレーキを行います。すると電動機の起電力は
E=K×φ×n
(E:起電力、K:電動機固有定数、φ:分巻界磁磁束、n:電機子回転数)
という式から電圧を高くすることができます。
すなわち高速時はスイッチング周波数を落し、速度が落ちるにつれてスイッチング周波数を上げていくことになります。加速時、逆起電力を抑えるために界磁磁束を減らしているわけですから、減速時は逆起電力(発電機になるので単なる起電力=発電力)を上げるために界磁磁束を増加させるというわけです。
電機子チョッパと異なり、電圧を大幅に上げることなく回生電力を確保しているため、回生失効速度が比較的高いのが欠点です。それでも界磁調整器による回生制動(従来の方式とします)とは違って界磁磁束を調節しやすいので、従来の方式よりは回生範囲が拡大しやすくなっています。

上図下段の右隅にぽつんと切り離されているチョッパ装置は、想像のものです。
回生のところで、チョッパ回生専用のチョッパ装置を使っているという想像で書いているんですが、よく考えてみると、ただのフリーホイルダイオードを使ったサイリスタにして、回生電力はチョッパされずにここを通り、力行用チョッパの電流を調整して回生電力を打ち消すような形で(逆起電力の要領で)調節しているのかもしれません。どっちが採用されているかはメーカーのみぞしる、ってところです(手元の解説書にはそこまで書いてない)。

先に説明したように、界磁チョッパ制御は抵抗制御から派生した方式なので、抵抗制御域で使用する抵抗器を更に増やして滑らかな発進を可能にするバーニア制御が可能です。逆に言うと、低速域ではどうしても段階的な速度制御になってしまうという欠点があります。

一方で分巻巻線は電源電圧の半分ほどしかかからないため、界磁チョッパ装置は電機子チョッパ装置ほどの耐電圧性能でなくても十分に動作します。また、界磁チョッパの場合電圧を減らしていく処理が基本になるため、スイッチング周波数が低くても構いません。また、電流が小さいためスイッチング制御を行ったときに生じる脈流も小さく、誘導性リアクタンス(電流の変化)の遅れも大きいので主平滑リアクトルが不要、分巻巻線の電流を遮断しても直巻巻線の電流が電動機に供給されるため閉回路や充放電リアクトルが不要などといったメリットもあります。

Appendix

プロフィール

さくらゆーな

Author:さくらゆーな
鉄道熱が再燃して、撮影に模型にいろいろやってます。
最近反核運動に偏ってるのを反省したいけど
知れば知るほど極悪非道な界隈で止まらない…

カレンダー

04 | 2017/05 | 06
- 1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31 - - -

+ アーカイブ
 

最近の記事

カテゴリー

検索フォーム


キーワード

カウンター

トータルカウンター
現在の閲覧者数:

ads3

Mac ソフトのことなら act2.com

Make a donate

もしこのブログを気に入っていただけたら上記アフィリエイトプログラムか下のPayPalでブログ・サイトの維持にご協力ください。

donationPrice

ブロとも申請フォーム

この人とブロともになる

ブログランク

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。