メモのような日記のような(3) 2019.11.16-

Akihiko Koga

圏論を勉強しよう へ
束論を勉強しよう へ
半群論を勉強しよう へ
集合,位相,論理など へ
AKI's HOME Page (Top Page) へ

目次 (上が最近のものです)
  1. 違いは,出っ張り具合? PAD と C言語風疑似コード 2019 年 12月 9 日 (月)
  2. 学習形態に関するメモ:プレゼン資料の提示形態 2019 年 12 月 4日 (水)
  3. 「物理学の応用について (寺田 寅彦)」を読んで 2019 年 11 月 23 日 (土)
  4. 仕様は実装より分かりやすいか? 2019 年 11 月 16 日 (木)

違いは,出っ張り具合? PAD と C言語風疑似コード

2019 年 12月 9 日 (月)

私は.とあるところで,C言語の基礎を終えた大学生の実習編を担当しています. そこに来ている学生さんたちを指導して思うのですが,彼らは殆どフローチャートを書きません.

実は,学生さんたちは他の図も殆ど書きません. 他の図とは,例えば,ポインタで繋がっているリストの図,データ構造の図, 問題を分析した結果の何らかの構成図,また,これは図ではないかもしれませんが, 日本語など自然語で解法を抽象的に書いた疑似コードなどです.また, 制御フローを表す図でも,好き勝手なフローが書ける伝統的なフローチャートのほかに, 構造化されたフローを書くことに特化した,構造化フローチャート,PAD図, NSチャート, HCP図などもあります.これらも書きません.

大部分の学生さんたちは,このような図を書かずに,エディタに向かって 直接プログラムを書いていきます.それでプログラムが 書ける学生は良いのですが,書けない学生はなかなか課題を進めることが出来ません. もしかしたら, 彼らはフローチャートや疑似コードの書き方を(全く or 十分には)習ってないのかもしれません. 従って,頭の中にあるもやもやっとした解法を表現する手段が,直接実行可能な 詳細度を持つプログラミング言語しかないので,なかなかそういう詳細のコードを 出力できずに苦労しているのではないかと感じます.私はその大学の教育全体に係わっている 訳ではなく,学生さんたちがどんな教育を受けてその実習の場に来ているか 知らないので,上に書いたことは想像がずいぶん混じっています.

で,これも想像なのですが,この状況は1つの大学だけの状況ではなく,全体的な 状況なのではないかと思っています.理由は二つあります.一つ目は,私があまり段階的詳細化と いう言葉を聞いたり,目にしたりしないことです.特に本屋で「段階的詳細化」という語を タイトルにつけた本に出会った記憶がありません.こういう構造化フローチャートの技術とか, 段階的詳細化の技術は殆どロストテクノロジーと化しているような気がします.

二つ目の理由は,自分自身の心の中を覗いて 思うのですが,私自身がフローチャートを書かねばならないというニーズが殆ど無いこと です(他の構造化フローチャートも同様).C言語は,ほぼ構造化された疑似コードと 変わらず,(私たちは)これを使って段階的詳細化が行えるので,特にフローチャートを起こす必要性を 感じないのです.これは一般の先生方も同じなのではないでしょうか.先生方も, 自分たちの成長のある時期までは, フローチャートや疑似コードなど,何らかの中間的な表現手法でプログラムを作成する技術を学んだと思うのですが,

  1. 彼ら自身,すでにそのような 中間的な表現形態が必要なくなっていること と,
  2. プログラミング言語が段々高級になって来て日常語に近くなっていること
とで,学生さんたちの苦労が分からなくなっているのではないのかと 勘ぐってしまいます.

で,今回のメモの内容は次の二つです.

  1. 段階的詳細化などの技術の「再」活用
    現在殆どロストテクノロジー化している段階的詳細化などの技法を教育に復活させた方が良いのではないか?

  2. PAD 図と C風疑似コードの違いはどれほどか?
    色々な構造化フローチャートがある中で私が使うとしたら PAD 図なのですが, これは構造的には C 言語を連接,条件分岐,繰り返しに限定したものと 殆ど変わりません.したがって,自然語を使ったC言語風疑似コードで同じ内容が 書ける訳ですが,PAD 図とC言語風疑似コードに違いはあるのかという疑問が湧きます. 「違いがあるのか?」は何にとってを明確にすべきでしょうから,ここでは,
    「プログラミング初心者がプログラムを作るときや教師からプログラミングの説明を 受けるときの補助資料としてPAD 図とC言語風疑似コードに違いはあるのか
    という疑問にしておきます.

段階的詳細化などの技術の「再」活用

「段階的詳細化法」とは,1960年代後半から1970年代,もしかしたら,1980年代の 初めくらいまで,提唱され,使用されていたプログラム作成の方法で,最初から詳細な コードを書くのではなく,ラフな手順の記述からはじめて,次第に詳細化していくものです. 技法の名前のままですね. 最初に提唱されたころの代表的な文献は

  1. Niklaus Wirth (1971), Program Development by Stepwise Refinement, 14, pp. 221-227
  2. E.W.ダイクストラ, C.A.R.ホーア, O. J. ダール『構造化プログラミング』野下浩平訳、サイエンス社、1975年。
といったものだと思うのですが,人によって,例えば,「入力・変換・出力」の形式の プログラムと合わせた技法になっていたりとか,分割・統治の技法と合わせた技法を強調する人とか, 種々の流儀があるように思います.こういう細かな流儀が色々出て分かりにくくなったことと, 必ずしもすべての場合でうまく行く訳でなく,巨大なプログラムでは往々にして,データ中心の 分析技法やオブジェクト指向に基づいた技法の方が良かったりすることから,段々,人々の口に 登らなくなってきたのかなと思います.

こういった短所はあるのですが,しかし,小規模なプログラムで限定的に使い, 「一度に詳細化せずに段階的に詳細化する」くらいの緩い原理として使う場合は結構有効で, 教育においても初期段階から使ったら良いのになと思います.実際,私は全然課題を 進められない学生には,

まず,日本語か,自分の得意な言語で,大まかに解法を箇条書きで書いてごらん

と勧めています.その学生が書いたものを見ながら,
  1. まずは,この位の詳細さで書いたら良いよ
  2. ここは1つにしないで2つのステップに分けて書くと分かりやすいでしょう
  3. ここに書いたこの情報を保持するための変数がいるから,ここにメモ書きして おくと後で役に立つかも
とかの指導をします.あまり分かってない学生さんはなかなかアウトプットが出てこないので, どこが分かってないか分かりにくいのですが,こうして無理やりにでも書かせると,
ああ,ここがまだ一塊のままで,中がどんな手順になるか見えてないんだな
とか,分かって来るのです(私も学生さんたち自身も).

段階的詳細化をこういった個人の工夫で使っている場合は結構あると思うのですが,我流なので, 何か標準的な方法/記法があると良いと思います.次のトピックスの PAD のように, それほど難しくない大らかな技法として.

でも,こういう技法の制定はすぐ詳細化・特殊化してきてしまうんですよね. 技法の開発者さんとか標準化屋さんは,何かを詳細に決めていくのが自分の価値だと思っているので.

それと,「今更,段階的詳細化か」ということで,研究者があまり飛びつきにくいトピックスで あることも,この標準的な手法が確立されない理由なんでしょうね.あまり,論文ネタに ならないとかで.

PAD 図と C風疑似コードの違いはどれほどか?

PAD (Problem Analysis Diagram ) は H 製作所が開発した 構造化フローチャートです.世の中に既知の事実なので, 別に社名を伏字にする必要は無いのですが,私の昔いた会社なので,なんとなく, 直接書くのが躊躇われました.最初に PAD に出会ったのは 1982年頃,私が 修士1年の学生だったときに,ある研究会で,当時,H 製作所のF村Y彦さんという方が紹介したときだったと思います(F村Y彦さんは,Wikipedia によると,後に早稲田大学の教授になられ,さらにその後ご自分で会社を 作られているようです).

なんか,見るからに怪しそうな風貌と言動のF村Y彦さんが

PAD の普及のためにあちこちで講習会の講師をやっているんですけど,時々,「その書き方は規格と違います」と逆に注意されるんです.

もともと,私たちが作ったのに,規格化されると,もう私たちの自由にはならないんですよ.

とか言われていたような気がします.当時の私は,「へー,真面目そうな企業の社員なのに面白い人だな」と 思った記憶があります.

PAD 自体はかなり簡単で,基本的には次の3つの規則を覚えておけば書けます.これらは構造化プログラミングの3つの要素ですね.

  1. 連接
    逐次的に実行する動作を縦に書いていく.

  2. 条件分岐
    条件が成立するときの動作としないときの動作を書く. C 言語のswitch 文のように多くの条件を書くことも可能.

  3. 繰り返し
    ある条件が成立する間,ある動作を繰り返すことを書く.

他にも規則は沢山ありますし,流儀も沢山あるように思いますが,私は, 上の3つを使い,箱の中に適当な自然語を入れて使っています.

皆さんもお分かりと思いますが,実は,PAD で書いた殆ど同じものが,C 言語で書けるのです. 要は PAD は C 言語の構文木をグラフィカルに書いているだけですから.

例えば,「エラトステネスのふるい」で N 以下の素数をすべて列挙する手順を C 言語風疑似コードと PAD で書いてみます(小さい数からはじめて,見つかった素数の倍数を消していって 残ったものが素数という方法).

まずは,C 言語風疑似コードです.


C言語風疑似コードによる「エラトステネスのふるい」の手順

続いて,PAD です.


PADによる「エラトステネスのふるい」の手順

多少,視認性が違うような気がします.私は,この二つの効果が,学習者や, これを参考にしながらプログラムする人にとって,本当に違うのかずっと 悩んでいました.もっというなら,現在進行形で悩んでいます. これら二つはロジカルには等価なものを書いているつもりだからです. 書いたり,修正したりは,C言語風疑似コードの方がはるかに簡単です. でも,初学者に見せたとき,どちらが分かりやすいかと言うと PAD 図の 方が分かりやすいのではないだろうかと思いますので,学生さんたちに説明するときは, PAD 図に落とすようにしています.もしかしたら,PAD 図はフローチャートほどは 一般的ではないので,学生さんによってはこの図を読めない かもしれないという心配はありますから,有難迷惑なのかもしれませんが.一応,凡例はつけているので, それを見て解読はできると思うのですが,そういうことを総合すると,C言語風疑似コードに 理解容易性において劣るかもしれません.

いろいろ,あーでもない,こーでもないという議論をしてしまいましたが,現在, 私の中では,

  1. これら二つの同値な図は,学習者の受け取り方は違うだろう
  2. PAD の読み方を覚えたものにとっては,一般にはPAD の方が 把握が容易だろう(人のタイプによるとは思うのですが,文章より 図による把握の方が得意な人の方が一般的には多い)
という重みづけをしています.そして,ロジカルには同じなのだが, 受け手の印象が違うということの納得のために,次のようにトポロジカルには 同じ絵なのだけど,受け手の印象の違うものは世の中に沢山あると 考えるようにしています.まあ,安心のための比喩だけですが.

さらに,色を加えるともっと印象が変わります.

また,PAD 図とC言語風疑似コードとは出っ張り具合が違うということに着目するなら, 横顔の対比の方がよいかもしれません.

つまり,疑似コードに比べての,PAD の極端な凸凹,四角の区切り,文章と if や while などの 構文要素の明確な分離は,人にその処理フローの特徴をかなり明確に印象付けるもの ではないかということです.

ということで,プログラミングや計算機科学,数学でも,ロジカルには一緒でも印象が 違い,学習効果が異なる教具が存在し得るという個人的な結論を出して,今回のメモは終わりに します.

けど,...

追加事項 -- goto のこと --

最後にもう一つ.最近の学生さんがフローチャートを書かないことに関して,もう一つ気が付いたことがあります. 最近の学生さんは,goto も殆ど使いません.もしかしたら goto を習って ないのかもしれません.学生が goto を使うのを見た数少ない例では,その学生はどちらかと いうと優秀な学生でしたから,自分で習得したのかもしれません.フローチャートから プログラムを起こす場合は,goto がある程度出てきますから,フローチャートを書かないことが これに寄与しているのかもしれません.goto は,エラー処理など,ある局面ではプログラムを 分かりやすく書く効果はありますが,一般的には処理の流れを分かりにくくするので, 殆どの学生が goto を使わないという状況は,今の教育は構造化プログラミングの普及に 成功しているのかもしれません.ただ,上にも書きましたように,これは図を排除することが 良いと言っているのではありません. フローチャート以外の図や何か詳細なものに落とし込む手前の表現形態を勉強させることは 初学者の躓きを無くすことにつながると思います.

おまけ

学生さんたちがあまり図を書かないのは,いったん図を起こして(b),そこからプログラムを 作る方(a)が,直接プログラムを作る(c)より手間がかかると思うからなんですよね.「三角形の 二辺の和は他の一辺より長い」ですね.でも,c が絶望的に出来ないときは,a + b の方が 短い訳で. 急がば回れなんですよね.

近くに見えても,思ったより遠い

学習形態に関するメモ:プレゼン資料の提示形態

2019 年 12月 4 日 (水)

学習というような大げさなものではないかもしれませんが,プレゼン資料を自分で読むか, 相手に説明してもらうかで,理解の程度に差があるように感じますので,今回はそれに ついて考えたことを書いておきます.あまり整理されていないのですが,追々,整理して いきたいので,忘れないうちに考えたことを書き下しておこうということです.「難しいことを 比較的容易に理解するためにはどうすればよいか」というのが私の重要な関心事だから, こういう思い付きは大切なのです.

私は,とある勉強会に時々出かけるのですが,発表資料が事前に PDF で その会の web-site に掲示されるので,それを読んでいきます. 自分で読むのは,自分のペースで進められるのでとても良いのですが,やはり 理解できないところもあります.そういうのを,実際に勉強会に行って,発表者の 説明でプレゼンを一枚一枚進めていくと,自分で読んでいて分からなかったことが とてもよく分かるのです.

いま述べた例はとてもまともな比較にはなってないとは思います.例えば, 上の例で発表者付きのプレゼンでは,

  1. 読むのが2回目であること
    一度目を通したプレゼン資料をもう一度聞くと理解が深まるのは当然
  2. 補足説明があること
    発表者はプレゼン資料に書いてないことを補いながら説明するんだろうから, より理解が深まるのは当然
  3. 質問が可能な事
    勉強会では質疑応答ができ,読んで分からないことも質問すれば 分かるので,理解が深まるのは当然
といったことから,発表者の説明を聞くほうが理解が深まるのは当然という 議論が成り立つでしょう.

でも,私の感覚的にはそれ以上に理解が深まっているような気がするのです.また,発表者によっては プレゼンに文章を書き,それをただ読むだけという人もいますが,それでも,発表形態の ほうが理解が深まっている気がするのです.

ということで,今日のメモの内容は,この「理解が深まる(と感じる)」理由はなんだろうか, 思いつくもののメモを残しておこうということなのです.上に述べたような第1因子を 置いておいて,第2の因子を考察するのですから,あまりまっとうな話ではありません. 趣味の一人ブレインストーミングです.

とりあえず,すぐ思いつくものを挙げてみます.

今回はこれらについて一言ずつ述べてみます.

  1. ペースメイキング
    自分で読むときは,かなり速い速度で読んでいます.早く有効な情報を得たいと いうあせりの気持ちがあり,結構,飛ばして読んでいるのかもしれません.それに対して, 人がプレゼンするときはゆっくりした速度で説明がなされます.この強制的な 速度抑制で,小部分ずつの理解がしっかり出来ているのかもしれません.

  2. 音韻ループの活用
    人の説明では音声がしっかり発音されます.それに対して,自分で黙読するときは, 音声がそれほど頭の中に木霊(こだま)することはありません.「音韻ループ」とは
    認知科学での用語で,ワーキングメモリモデルの中央実行系のサブシステムの一つで 言語・音韻情報を保持する記憶貯蔵庫

    だそうです.聴覚の短期記憶です.発表者がしっかりした音声で説明してくれると,自分で読んだときは あまり働かなかった音韻ループがしっかり働いて,記憶や理解を助けるのかも しれません.発表の場合は,音声の反復を含んでいる訳ではないので,正確には 当てはまらないかもしれませんが,何らかの効果はあるんじゃないかと勝手に 想像しています.一方,音声を頭の中で木霊するのはそれなりの時間がかかるので, 頭の中での音読は,読書を遅くする理由として挙げている人もいるようです. 「速読」を主張する人とか.技術的な基礎の学習とかは,しっかり定着させることが 必要なので,ある程度時間を掛けてもよいのではないかなと思います.

  3. 学習作業の一部肩代わり
    やはり,ものを読むのはそれなりに労力が必要なのですが,音声にするまでは 他人である説明者がやってくれるので,その分の頭の CPU パワーを理解に 回すことができているのかもしれません.でも,音声認識の分が増えているので これはウソかもしれません.あっ! テキストを読むのでも,実はテキストコードを 読んでいるのではなく,画像理解でテキストコードに落としているのでしょうから どっちもどっちかもしれませんね.

  4. 人間の温かみ,信頼感,ラポール
    発表者から「これは真実なので信じるように!」という一種の「霊波光線」が 出ているのかもしれません.あるいは,自分自身の中に,「発表者に申し訳ないので 理解してやらなければ」という気持ちが生じているのかもしれません. あるいは,この発表者-聴衆という環境設定が,知識の受け身の体制を整えて, 知識が入ってきやすくなっているのかもしれません.一方,発表者がいかにも うさん臭くて信じられないと思う時は,かなり批判的な気持ちが働いて,知識は すんなり入ってこないでしょう.

    私は,6年前,会社を辞めた頃,学習に,「説得術」が使えないかと考えたことがあります. 無批判に何かの陳述を受け入れるのは学習とは言えないかもしれませんが, 生き物である私たちが,ある種の知識を手に入れるためには,保持すべき知識を受容しないと いけません.したがって,取り込みを楽にするための方便として,このような 説得術に基づいた手法もあっても良いのかもしれないと思ったのです.もちろん, 無批判の取り込みは良くないので,しっかり有効性を確かめたあと,それを 受容し,活用する手段としてではありますが.説得術で すぐ思い浮かぶのは,

    1. まず小さな要求を受け入れさせて,次第に大きな要求にしていく とか

    2. 逆に,まず,受け入れられないような大きな要求を出しておいて,それを否定させておいて, 実際に受け入れさせようとしている要求を出す とか

    があります.「小手先だけのテクニックで要求を飲ませるのは良くない」と言った 注意書き付きですが,色々なテクニックがあるようです.こういうのもプレゼン, あるいは,学習で役に立つかもしれません.例えば,とても難しい大きな定理を理解するのに, まずは,その定理の系から導かれる小さな例題をいくつか理解してから,その 大きな定理の理解に取り掛かるとかです.この例は結構普通ですね.

以上,かなり胡散臭い考察のオンパレードでした.こういう頭の中に時々思い描くことは, 機会を見て言語化しておかないといつの間にかなくなってしまうので,今回,言語化して みました.

プレゼン資料からの学習形態として,他に,展示会でのパネル展示などがあります. これは置いてあるパネルを読んで,分からないことを説明者に聞くことができるので 結構充実した学習ができます.時々,読んでいる最中に,説明者が,「ご説明しましょうか?」と 割り込んでくることがあったり,もう読んでしまって声を掛けて欲しいのに誰も声を掛けて くれなかったりすることもあります.そこでの説明者のスキルは,お店で,タイミング良く お客さんに声を掛けることができる店員さんのスキルと共通のものがありますね.

会社を辞めてから6年間,久しくこういう展示会場に行ったことがなく, 世の中に取り残されている気がするので,何か無料の展示会などを探して 行ってみようかと思う今日この頃です.

「物理学の応用について (寺田 寅彦)」を読んで

2019 年 11月 23 日 (土)

このサイトの別ページで, 青空文庫に挿絵を付けて紹介する(寺田寅彦の作品は, こちらで紹介)というのをやっていますが,昨日,寺田寅彦の 次の随筆を紹介しました.寺田寅彦は, Wikipedia によると,戦前の日本の物理学者、随筆家、俳人(1878年(明治11年)11月28日 - 1935年(昭和10年)12月31日))です.

物理学の応用について (寺田 寅彦 著)

物理学は基礎科学の一つであり,その応用は,
純粋な科学の各種の方面,工業,医学,航空術,
各種殖産事業と幅広い.

そういう分野への応用を進めるにあたっての方法や
心構えについて述べた随筆.

この随筆は,文字数にして 3,300文字位(400字詰め原稿用紙9枚)の短い随筆ですが上の場面の文章がとても気に入りましたので こちらでも紹介したいと思います.

この随筆は上の絵でも説明しましたように,物理学を色々な分野に応用していくときの, 心構えや方法について述べているものですが,理論を実際の応用に持っていくときは, 色々な抵抗に会うということが,この随筆の中に次のように書かれています.

  1. 複雑な実際問題を研究して先ずその真相を明らかにしようという場合には、先ずその大体を明らかにして枝葉を後にするのが肝要である。
    ...
  2. 渾沌とした問題を処理する第一着手は先ず大きいところに眼を着けて要点を攫むにあるので、いわゆる第一次の近似である
  3. しかし学者が第一次の近似を求めて真理の曙光を認めた時に、世人はただちに枝葉の問題を並べ立てて抗議を申込む

    ...
  4. 第一次の近似だけでもそのつもりで利用すれば非常に有益なものである
    ...

この随筆は百年以上前に書かれたものなのに,今日でもこの状況は変わってないように 思います.つまり,その理論は第一次近似だと思って使えば,それなりの恩恵があるにも関わらず, 色々な枝葉末節の欠点をあげつらって,適用させないようにする人たちがいるということです.研究者の 中にはこういうめにあった人も多いのではないでしょうか.私もこの気持ちが分かるところを 見ると,若いとき,こういうめにあって大いに憤慨したことがあったに違いありません.

ところで,同じ人がこの世人と理論適用の提案者になっていることはないでしょうか? つまり, ある事柄については,理論適用の提案者になって,世人の態度に大いに憤慨しているのだけど, 別の事柄については,世人となって別の提案者を攻撃しているとか.

例えば,私は,一つ前の日記の 「仕様は実装より分かりやすいか?」 で形式手法に ついて,かなり否定的なことを書いたと思います.これは,今をさること約40年前,1982年ごろ, 大学の研究室で作っていたプログラムの検証システムの経験がトラウマになっていることが あります.私も少し作ったのですが,大部分は私より前の学生さんや先生が作って,私は 主に,このシステムを使ってその妥当性を調べる役割でした.

そのシステムでは,プログラムが満たすべき性質や補助的な情報 を一階述語論理で与えると,証明すべき一階述語論理の論理式を生成して,後は, そのシステムに備わっている証明システムでひたすらその論理式を証明するというものでした.

ほんの小さなプログラムでも証明すべき式はすさまじく大きくなります.そこの建物は 4階建てでしたが,ラインプリンタ用紙にその論理式を打ち出して,4階の窓から垂らすと, きっと下までついてしまうほどの論理式を相手にしないといけないのです(ラインプリンタ用紙は 一ページごとにミシン目がありますがずっと繋がっています).

論理式の一部分には x=x のような自明な論理式も含まれているので,そういうのを除去するとある程度までは小さく なるのですが,それでも量に圧倒されます.そのとき,証明の空間を直に感じとったのが トラウマになっていて,形式検証にちょっと否定的な気持ちが出てきてしまうのです. もちろん,計算機も当時から比べるとすさまじく良くなったのですが,やはり,証明の 空間は莫大です.ちなみに,これはAI(人工知能)にも絡んだ問題だと思います.人は証明空間に 均等に関心を持っている訳ではないので,何か人の活動に関連の深い部分空間に限定する 方法はあると思いますが,何となく私はこの広大さに恐れがある訳です.

形式検証にしてもAI(人工知能)にしても,その発展のどの段階でも,(人と言うお手本の) 第一次近似だと思って,欠点に目を瞑れば,色々役に立つことが多いと思います. 寺田寅彦の随筆では先の文章の前に次のようなことが書いてあります.

  1. 今一般に実際上の問題に物理学を応用しようとする時に、第一着手としてしなければならぬ事は問題自身の分析的研究である。
  2. 実際上に起る問題をちょっと見ると簡単なようでも通常非常に複雑なものである。
  3. 同時に範囲の判然せぬ問題が多い。

問題自身の分析的研究」,たぶん,問題自身をきちんと分析して どこまでを解決するのか/できるのかということに見通しを立てる必要があるということ なんだろうと思います.よくよく考えてみると,私もあまり良く考えずに,「こんなことが できる,あんなことができる」と言ったことがあったと思います.

そしてやっていくうちに 何とかなると思っていた問題が実はとても難しい問題で最初のセールストークから ずいぶん後退したり,あるいは結局,使い物にならなかったり.

予算を取るときは,あまり欠点を大きく言うことは得策ではないし,プレゼン相手を 混乱させてしまうので大っぴらには言えませんが,トーンの大小や言い方を工夫して,やはり,こういう, 出来ないことや欠点も一応分析して述べておかないといけませんね.

今回は理論を適用する提案者側とそれに反対する世人の両方に配慮したバランスの とれた,我ながら良いお話になったのではないかと思います.

でも,他人の提案に枝葉を並べたくなる心理は,人間の根源に係わる 何か(生存競争に係わる)かもしれないので,今度,枝葉を言いたくなった時には自分の心の中に 潜ってみたいと思います.自分たちが生き物だと言うことを忘れて,理想を語ることはできませんので.

仕様は実装より分かりやすいか?

2019 年 11月 16 日 (木)

ソフトウェアの分野で「形式手法」という研究テーマがあります.ソフトウェアの 信頼性を向上するために,仕様を述語論理や様相論理などで「形式的」に記述して, 実装がその仕様を満たすことを,証明やモデル検査などで確かめる(検証する)という研究テーマです. 検証まではやらなくても,とにかく「形式的」に仕様を書いてみるという ようなことも含むと思います.ここで「形式的に」というのは述語論理など形式的体系を 使って厳密に記述することを意味します.私の知り合いにも,形式手法に真剣に取り組んでいる 人がいます.

ここでは,証明やモデル検査などの難しい話ではなく,

ということを考えてみたいと思います.もっと言うなら,仕様と実装の間の理論的な線引きはとても難しいということを 言うつもりです.

一般には,仕様自身はソフトウェアが動くところまで書かなくて良いので,記述において動くための仕掛けを 省略して,そのソフトウェアが満たすべき性質,あるいは他のモノ(ソフトウェア,デバイス,etc.)との関係のみに着目できます.

その意味では,

    細々とした記述から離れて,ソフトウェアに課される条件に集中できます.つまり, 抽象的な記述が可能になる訳です.

    その具体的な効果として

  1. 記述が少なくて済むという効果も得られます
    これにより,人間が読みやすくなり,仕様の段階での誤りも 発見しやすくなるでしょう.また,実装が仕様通りかを調べるときも,テスターが 仕様を十分把握していることが必要です.これにも寄与します.

  2. 余計なことを決めすぎないで良いと言う効果も得られます
    実装では動作を可能にするために,本来,利用者側からは要求されないことまで 決めていることがあるのです.仕様ではそれを削除して実装に自由度を与えることができます.

今回の日記では,

  1. これらのことは本当なのか?
  2. もしかしたら,我々が心の中に抱いている幻想,あるいは,願望にすぎないのではないか?
  3. また,もし,本当なら,その線引きを可能にしているのはいったい 何なのか?
ということを考えてみたいと思います.

少し話の設定を設けておきます.それは仕様と実装を記述する言語を別のものに してしまうと,話が簡単になりすぎてしまうからです.例えば,C言語で 書くのが実装で,述語論理で書くのが仕様というような基準ができてしまいます. ここはどちらも述語論理にしてしまいましょう.述語論理でも Prolog のように ホーン節だけに限れば,インタープリタを用意して,実装が書けます.つまり, フルの述語論理を使うと性質の記述だけになってしまうが,その中のある部分集合に 限ると実行できるという記述体系の中で考えることにします.

この枠組みでも実行できないものを実装とは呼べないでしょうから, たまたまホーン節で書けて実行できるようになってしまったものを実装と呼ぶべきか仕様と呼ぶべきかが問題になります.

話を少し具体的にしていきましょう.配列のソートを考えてみます. 配列の要素は大小関係のあるキーを持っていて,入力の配列のキーは すべて異なっているとします.そうすると仕様は次のようなものになるで しょう(読みやすさのために厳密な文法は決めずに書いています).

b = sort(a) →
b は a の要素の並び替え and
(0 ≤ i < j ≤ size(b) → b[i] < b[j])

つまり,

配列 a をソートした結果の配列 b は a の並び替えであって,要素の小さいものから大きなものへの順序で並んでいる
ということです.

この記述は,ソートするとき,どのような手順で要素を並び替えるかという情報を 含んでおらず,ソートされた結果に要求される必要なことだけを含んでおり,大変分かりやすく 感じます.具体的にどうやって並び替えるかは実装者に任せられ,バブルソートでも クィックソートでもマージソートでも適切に選んで実装すればよいのです.

この例を見る限りは,仕様は非常に分かりやすくソフトウェアの記述や検証にも有用に思えます. しかし,ほんの少し条件を複雑にすると状況はがらりと変わります.

上のソートの例で次の二つの条件を付け加えてみましょう.

  1. キーがすべて異なっているとは限らない
    ここでは要素のデータ自体は異なっていると仮定します. これは,単にキーの選び方が不適切ということかもしれません.

  2. 以前のソフトウェアで出力されていた順番を守って欲しい
    キーが同じでデータは異なる場合はキーの部分がソートされた色々な 要素の並びが考えられます.クィックソートやバブルソートなど, ソートのアルゴリズムはキーが異なっていれば結果は一緒ですが, 同じキーがある場合は,一般には結果の並べ方は異なります. 例えば,ここで対象となるソフトウェアは以前のソフトウェアのバージョンアップで, 以前のソフトウェアはある種のクイックソートを使っていたとします.
実は,こういうことは現実にあり得ます.例えば,ある店舗の顧客の集合から色々な 観点で抽出したリストを作るようなソフトウェアでは,以前の並びと微妙に異なる 順序のリストを受け取った担当者は嫌がるかもしれません.セカンダリのキーを決めて いなかったということが悪いのかもしれませんが,既存のシステムの中にはこのような ものは結構あるのではないでしょうか.

これは,システムの刷新に伴ういくつかの一時的な不便は我慢すると言う,責任者の英断がないと 何時までも古いままになってしまうのですが,過渡期にはあり得る話です.

このような条件にすると,ソートの仕様としては,上のようなすっきりした仕様でなく,元のソフトウェアの ある種の クィックソートの並びを規定したソートの仕様を書かなければならなくなってしまいます. クィックソートは,適当に選んだ要素を基準にして,それより大きな要素のリストとそれ以下の 要素のリストに分けるということを繰り返していくソートですから,同じ順序(同じキー)のデータ同士の 相対位置は動的に変わってしまいます.これを最初の配列の性質から静的に論理式で記述するのは とても難しく,元のソートのアルゴリズムをそのまま論理式(ホーン節)で記述するしか 無いように思います.以上,例題がちょっと長かったですが,これは

仕様として,アルゴリズムを記述し,しかも動くレベルまで 記述しなければならない例で,仕様が実装より簡単にすっきりと書けるとは 限らないことを示す例
でした.

もう一つ,簡単な例として,例えば,信号機の色の変わる順番を規定する仕様を考えてみます. 信号機の色が,青 → 黄 → 赤 → 青 と変わるという仕様は,

next(青, 黄)
next(黄, 赤)
next(赤, 青)
となるでしょう.実はこれは動いてしまいます.したがって,前の例もそうですが, 動く動かないを実装と仕様の差にすることはできません.

以上をまとめると次のようになります.

  1. 仕様と実装の違いを,動かない,動くで規定することはできない
    ある記述が仕様か実装かの違いは,そのソフトウェアに対する人間の頭の中に ある要求を表したものかどうかであって,動かない,動くのような単純な基準で 定義することはできそうもありません.でも,こういう頭の中のモヤモヤと したものを理論的な違いとして規定していくという活動自体は大切なことだと思います.

  2. 記述の対象によっては手順を記述してしまった方が,楽でかつ理解しやすいこともある
    必ずしも,手順(アルゴリズム)から離れた記述が分かりやすいとは限りません

以上,仕様と実装の違いを改めて考え直してみると言うお話でした.仕様というのは ソフトウェアを作る人が,作るべきものを必要十分に記述したもので,実装はそれを満たす 実際に動くものということなのでしょう.そして,仕様が実装より分かりやすく書けることが多いというのは 仕様を作る人たちの努力と勇気によってそうなっている部分も大きく,仕様だから,実装だから だけの理由では無いと思います.

こういう,概念の区別に人間の判断基準や感性が絡むものは,理論的かつ厳密な定義が難しいのですが,やはり, 定義しようという努力はそれらに対する理解を深めることに繋がり,大切なことだと思います. こういった事例は沢山あると思います.例えば,

  1. 特許で,「発明」と「単なる既存の技術の組み合わせ」の違いは何か?
    * 青空文庫 海野十三の作品紹介ページ「特許多腕人間方式」を参照

  2. システムの理論で,「システムとはそれの部分の算術的総和以上のものである」という人が いるが,「単なる部品間のインタラクション」と「算術的総和以上のなにか」は違うのか?
    「感覚的なもの」は「内容」を変容させて,新しい創造的な価値を生むか? 製本,表現形態,創造,ついでに,システムにおける人間の寄与
    に関連事項

  3. 計算機科学で,何が「プログラム」 で何が「アルゴリズム」なのか?
    「アルゴリズム」とは何だろうか?
    に関連事項

話を元に戻して,ソフトウェアの分野で形式手法を活用していくためには

  1. どのような仕様の記述が好ましいのか?

  2. 仕様の記述が実装程度,あるいは実装を超えて複雑化してしまう場合の対処方法
と言ったことを考えていく必要があると思います. 今度,Krm 先生にあったとき,要望を出しておこうかと思います.

最後に,仕様が必ずしも実装より簡単にならない場合があるということは,圏論で つくるモデルが必ずしも理解容易なものにならないことと関係があるような気が 最近してきました.実際,

M. Barr and C. Wells : Category Theory for Computing Science の概要説明
では,著者は圏論での記述を specification と呼んでいることがあります. これについては,また,圏論の考察をするとき書いてみたいと思います.


圏論を勉強しよう
束論を勉強しよう
半群論を勉強しよう へ
集合,位相,論理など へ
Back to Welcome to AKI's HOME Page