ビスケットのあれこれ

ビジュアル言語ビスケット(Viscuit)に関するあれこれを書いてゆきます.

ビスケットの角度のマッチング

2013-11-14 18:49:05 | 1
ビスケットでは,絵の角度によってもマッチするメガネを制御することができます.この方法を使うと,面白いアニメーションが作れます.

まず基本的な考え方を説明します.動画


このメガネは,人が大きく回転しながら移動して,その跡に矢印を置いて行くものです.設定で「滑らかなうごき」のチェックを外しています.


次に,矢印が上を向いたときは1に変わる.矢印が下を向いたときは2に変わる.というメガネを作ります.

これを走らせると,


のようになりますが,大体上を向いているときに1,下を向いているときに2になりますが,1と2が切り替わるところは丁度真横になっています.ここが少しわかりにくいところです.

もう一つメガネをつくって,矢印が左を向いているときには3に変わるというのにしますと,

のようになります.1と3が切り替わるのは左斜め上,3と2が切り替わるのは左斜め下ですね.

角度が2つのときは,それぞれが丁度180度ずつ担当しましたけど,角度が3つになると,それぞれのメガネが担当する領域は対等にはなりません.この場合は3の角度が少し狭いですね.

さらに,狭くすることもできて,

これは,上を向いているときは1,少し左を向いたら3,少し右を向いたら2としています.こうすると,1になる角度をすごく狭くできます.わかり易さのために,3と2で違う絵を使っていますが,両方とも同じ絵を使うと,大部分は2だけど,ほんの少しだけ1になる,ということもできます.

角度の判定を上手く使うと,非常に面白いアニメーションができます.


カエルがジャンプするアニメーションです.これは動画を見ていただくとわかりますが,簡単に作っているようで,結構難しいです.伸びているカエルが大きく回転するメガネをつくって,カエルが下を向いたときしゃがみます.しゃがんだカエルはジャンプします.ここで真ん中のメガネ,カエルが下を向いたときにしゃがむ,というものメガネの左側で伸びているカエルの角度,右側で伸びたカエルがしゃがむときの角度の二つを調整しないと,うまくジャンプしません.


落ち葉がひらひらと落ちるアニメーションです.葉っぱを表と裏の絵を描きます.表の葉っぱは半時計回りで大きく回転.裏の葉っぱは時計回りで大きく回転します.これらは葉っぱが横向きで作ります.葉っぱが縦になったときに,表から裏,裏から表にひっくりかえります.縦の置き方で,茎を下にするか上にするかを間違うとダメです.これも動画を見ていただくのがよいでしょう.

カエルも落ち葉も,手順通り,それぞれのステップでちゃんと動いているのを確認しながら作らないと,なかなか思ったような動きにはならないと思います.この角度のマッチングは,僕自身はあまり納得できていない,直感的ではない変な仕様なんですが,使いこなせるようになるとかなり表現力があがります.

ビスケットで算数の勉強

2013-11-14 10:59:41 | 1
ビスケットを算数の勉強に使ってみましょう.

最初に5つの絵を用意します.

10円,50円,100円のお金と,りんごとみかんです.

次に,両替のメガネを作ります.

見づらいですが,左側が,10円が5枚で50円になる,右側が50円2枚で100円になる,というメガネです.

次に,りんごとみかんの値段を決めます.

上のメガネは,りんごが130円になる.下のメガネはみかんは40円になる,というものです.

では,計算させてみましょう.ステージにりんごを3個みかんを2個置いてみます.

実行させると,

のようになります.重なっていて見にくいので,すこしずらしてみますが,このとき,ビスケットで実行モードというのがあって,のアイコンをクリックすると,

というダイアログが出るので,ここで「置いた位置をおぼえる」というチェックを外します.このチェックはゲームとか絵本といった作品を作るときに便利な機能で,ステージに直接置いた部品の位置を覚えておいて,ビスケットのプログラムの実行はかならずその置いた位置から何度もスタートする,というものです.今回は,毎回最初から戻されるのではなく,ステージの位置を覚えないで,書き換えた結果に対して,また次の書き換えを行うということになります.そのようにしておくと,上の絵のような計算された結果に対しても触ることができて,絵を並べ替えると

のように,470円という結果になります(りんご3個で390円,みかん2個で80円ですから).このモードの場合一時停止を使ってメガネを編集すると便利です.

これらの様子はこの動画でもみれます(声が小さくてすみません).

同じように,今度は引き算をさせたいのですが,これがなかなか難しい.いちおうこの動画でトライしてますが,けっこうばたばたしてます.

先ほどの,りんごとみかんの買い物のメガネを壊して,逆向きのメガネにします.

上のメガネは「りんごと130円があれば消える」,下のメガネは「みかんと40円があれば消える」というものです.

ところがこれでは100円が2枚あっても,りんごは買えません.買えるようにするには,100円が1枚と10円が3枚必要なので,ここにある100円を,50円と10円5枚に両替しなければなりません.ビスケットの両替のメガネは小さい金額を大きくする,という方法だけ用意してありますが,自動的に都合の良いように逆向きには動いてくれません.

もしここで,逆向きの両替のメガネを追加したら,両替の向きが双方向であるので,10円5枚と50円1枚を交互に繰り返すアニメーションになってしまいます.いつ,どっちむきに両替すべきかというのは実は非常に難しいのです.

ではどうしたらよいかというと,たとえば,次のようなメガネを追加します.

100円が2枚あったとき,りんごを買うと,70円のおつりになる.50円でみかんを買うと,10円のおつりがでる.
というものです.実は,これでも完璧ではなくて,100円でみかんを買ったとき,150円(100円玉と50円玉)でりんごを買ったとき,というのも追加しなければなりません.

お金の種類が100円までだから,これでもよいですが,500円とか1000円という高額なお金を使うと,一気に複雑になります.りんごやみかんの他に新しい商品を買うことにすると,それぞれに高額紙幣に対応しなければなりません.りんごやみかんの値段を変更した場合は,関係するメガネを全部直すひつようがあります.

もっとコンピュータらしいやりかたもあります.
 お金を全部10円に両替する.
 次に,りんごと130円のメガネで,130円の表現を100円をつかわずに,全部10円だけで(10円が13個)表現する.
 計算が終わってから,お金を大きな金額のコインに両替する.
という3つの手順に分ける方法です.この方法だと,どんな金額がきてもうまく計算できると思います.

アルゴリズムを考えるというのは,このようにコンピュータでも計算できるような手順に分解するということです.人間の場合は,両替の方向を都合良く切り替えてなんとかなってますが,それをコンピュータにわかるようにするには難しい.

人間にとって易しいことでも,コンピュータには難しい.
もうひとつ.実は,これを作ってて,引き算というのは意外と難しいのだから,子供にはもっと丁寧に教えて上げようという気持ちにもなりました.

ビジュアルプログラミングに興味をもった理由

2013-11-13 12:42:40 | 1
僕は,独特な研究を色々とやってきてるんですが.例えば僕がD論で書いたのは,インターネットのような絶対アドレスを使わないで,相対アドレスで世界中を繋ぐという方式の提案だったし.「未来の電話」で検索すると出てくると思いますが,テレビ電話のまったく新しいディスプレイの配置法を考えたし.「コンピュータ」という名前の特許を書いたこともあって,これはCPUの命令セットを人間が設計するんじゃなくて,圧縮アルゴリズムで決めればいいのに,というものです(この特許は書いただけで審査請求はしていませんが).とにかく,何かを考えるときに究極の姿を追い求める姿勢だったと思います.

今から20年くらい前の話ですが,研究の世界で流行っていたキーワードに「オープンシステム」と「マルチエージェント」というのがありました.インターネットはありましたけど,まだWebの爆発が起きる前です.このインターネットの上で動くシステム,日本語で言うと「非均質開放分散系」とか言ってたかな.オープンシステムというのは,簡単に言うとビーカーに液体が入っていてそこにフタをしないものです.いろんな分子が液体に入り込むし,液体も蒸発して中の分子が出て行ったりする.何が入って,何が出て行くかを監視できないような状態です.それをどうやって記述するかということに興味がありました.

プログラミング言語の記法(書き方)について考えてみます.文法というのがあって,それを守るように書くと,コンピュータが間違わずに解釈できて,人間が書いた意味を理解してくれる.そしてその文法は,木構造をしています.木構造をしていない文法はあるのかなぁ.木構造というのは,たとえば,こういう式があったとき,
3 * (4 + 5)
これをコンピュータが解釈すると

のような構造になります.一番上にかけ算が来て,それを3と何かとでかける.何かというのは,足し算で,それは4と5を足す.基本的にすべてのプログラミング言語はこんな感じで木構造をしています.

ところが,オープンシステムというのは,いろんなものが出入りするシステムなので,こういった木で表現することはできないんですね.いま,出来ているように見えているのはどっかをごまかしているからだけです.ではどういう書き方をしなければ行けないか.たとえばこんなことなんじゃないか,と考えたのが,次のような書き方です.
( a { b ) c }
これです.括弧の対応があっていませんがそれでいいんです.「()」で考えるとa b がグループですが,「{}」で考えるとb c がグループです.ほ乳類と泳ぐ生き物という集合を考えると
( 犬 { くじら ) マグロ }
みたいになります.

で,オープンシステムですが,こんな感じに書きます.
a { b ) c d
なんと,「()」の開き括弧がありません.それと「{}」の閉じ括弧もありません.こういったファイルがあったときに,a b や b c d はこのファイルの中で閉じていなくて,外側に何が来るかによって変わってしまう,という記述なのです.ファイルの隣というのはどう定義するのか,そのファイルが置いてあるディレクトリの辞書順で隣にあるものなのか.とにかく,オープンシステムで何かを記述するということは,こんな記法を発明して行くことなんですね..

この書き方は,テキストでオープンシステムを表現するというものでしたが,テキストは1次元にならんだ文字の並びですから,オープンシステムの広がり具合が1次元に限定された記述とも言えます.実際は2次元・3次元などでは表現できない大きな次元で広がって行きますから,こんな1次元での書き方なんて発明してもご利益はほとんどないのですが,それでも思考実験としては面白いです.

きっかけはオープンシステムをどう記述するかだったのですが,考えてみると,今のテキストによる言語は木構造の文法に支配されすぎていて,いろいろと不自由だということがわかりました.そこで,もう少し色々な記法を考えて,たとえば括弧の半閉じ,半開きという記法も発明しました.
(a { b |) c (| d ) e}
|) は半閉じ括弧で,完全には閉じません.(|が半開き括弧で,さっき半分だけ閉じた括弧をまた開きます.括弧のスコープを飛び飛びであけたり開いたりできます.何のために必要なのかはともかくね.

一般のプログラミング言語はほぼすべてテキストで表現されています.それらの言語は複雑な意味を扱うので,実はとても木構造では表しきれないくらい複雑な構造を取り扱っているのですが,しかし表現する文法が木構造に限定されているために,複雑な構造をどうやって木構造に組み込んで表現するか,という工夫が盛んに行われるようになりました.

たとえば,先ほどの式は関数型言語では,こうかきます.
*(3, +(4, 5))
先ほどの式の木構造にすごく似ている書き方をします.一方で,Prologという不思議な言語でこの式を書いてみると,
*(3, A, Root)
+(4, 5, A)
のようになります.これは,3とAを足した物をRootにする.4と5を足したものをAにする.と読みます.関数型言語では,計算の値の流れが重要なので,その流れと,テキストの文法の木の枝のつながり方を対応させます.Prologでは計算の値よりも,計算が成功したか失敗したかということを重用しするので,その成功失敗の流れを,テキストの文法の木の枝に対応させています.そうすると,計算の流れについては木の枝で表現できないので,Aという変数を介して行うようになります.

テキストの言語では,一番重要な流れをテキストの木構造の枝の付き方で表現して,それ以外の犠牲になる部分には,同じ名前をつけてそこで流れを表現しています.

機械語の頃は,メモリーの命令の並びがそのままテキストでの命令の並びでした.gotoというかジャンプ命令はメモリーのすきな番地に処理が移動することですが,人間は単純な数字にとくべつな意味を持たせて考えるのは非常に苦手なので,番地の数字の代わりにラベルをつけて,人間が考えやすいようにしています.ラベルというメモリー上の印と,そこへ移動する命令で,プログラムはぐちゃぐちゃになってしまいまして,それをなんとかしようということで,goto文が悪者になりました.色々なプログラムを見てみると,goto文とif文とで同じようなプログラムのパターンが見えてきます.そのパターンに名前をつけたのがwhile, do until といった制御文になったというわけです.

実は,プログラミング言語にはもっといろんな流れを表現しなければなりません.たとえばファイルをオープンしたらクローズしなければなりません.あるリソースに対して,特定のパターンでアクセスする必要があります.本来ならそのパターンの部分を取り出して,それをテキストの木構造にあてはめて記述するようにしなければなりません.そうすると,そのリソースへのアクセスのパターンのエラーが劇的に減るはずです.ところが,テキストは単一の木構造しか表現できないため,ファイルのために貴重な木構造を使ってしまうと,他のものを犠牲にしなければなりません.そんなわけで,値の流れと,制御の流れ,というのからなかなか離れることができずに,新しい書き方の発明がなかなか進んでいないのでしょう.エラー処理とかはそれでも頑張っているのかな.

プログラミング言語は進化して,色々と複雑な流れを一度に記述しなければならなくなってきているのにも関わらず,それを表現する形式がテキストに限定されているのは,プログラミング言語の研究の妨げになると考えました.そんな感じで,ビジュアルプログラミングに興味を持って行ったのでした.

僕は最初から子供向けを作ろうと思ってビジュアルプログラミングをやっていたのではなくて,ものすごく深い話を考えるためにビジュアルプログラミングに進んだわけです.まあでもこういうのは,難しいのでがんがん研究が進むわけでもなく,ちょっと煮詰まってきたところで,いろんな表記法や計算法を発明したので,ちょっと視点を変えてそれらのノウハウを集めて言語をつくってみようか,ってことで力を抜いて作ったのがビスケットなのです.

Viscuitによる数の定義

2013-11-12 20:47:42 | 1
今回は,情報系の学生向けの話です.

0を含める自然数を定義するときに,0とsuc関数を使う方法があります.

0は自然数である.
Nが自然数のとき,suc(N)も自然数である.

これによって,
0
suc(0)
suc(suc(0))
suc(suc(suc(0)))
...

が自然数になります.これらをアラビア数字で0, 1, 2, 3 ... のように表記すれば我々の良く知っている数になります.

これを使って足し算を定義することができて,

0+N は N
suc(N1)+N2 は N1 + suc(N2)

こうすることで,たとえば,
suc(suc(suc(0))) + suc(suc(0))

suc(suc(0)) + suc(suc(suc(0)))
suc(0) + suc(suc(suc(suc(0))))
0 + suc(suc(suc(suc(suc(0)))))
suc(suc(suc(suc(suc(0)))))
という計算ができます.最初の式をアラビア数字で表すと
3+2
で,最後の式は
5
なので,ちゃんと計算できています.
僕はPrologに感動した人間ですが,Prologではこんな計算をさせて遊ぶことができます(Prolog のもっとすごい面白さは,足し算を教えただけなのに,勝手に引き算をやってしまう,ところなんですが).


さてこれをビスケットで表現するにはどうしたら良いか,という話です.
実は,残念ながら今のビスケットでは動きませんが,こんな感じでやれば動くのではないかと思ってます.

まず,使う記号は

の4つです.
ビスケットには絵の継承を定義するための「ゆきだるま」という機能があります.それを使って自然数Nを定義します.

ゆきだるまの左側は,0はNを継承するという意味です.右側は,N+1はNを継承するとなってます.ここで継承に×が付いているので,実際にはこのように定義してもビスケットでは動作しません.継承で循環を禁止しているからです.循環というのはゆきだるまの上と下にNがありますが,継承をたどったときに同じ絵が出てくることを禁止しているということです.継承するというのは,ピンと来ないかもしれませんが,ビスケットでは同じ動きをする,と言い換えてもよいです.つまり,0はNと同じ動きをする.N+1はNと同じ動きをする,です.

で,もしこの継承の循環を許したとすると,この継承は

このような図の継承をやったことと等しくなります.
0はNと同じ動きをする
0+1はNと同じ動きをする
0+1+1はNと同じ動きをする
0+1+1+1はNと同じ動きをする
これがずっと続きます.
で,Nに対して何か動きをつくれば,それはすべての数が同じように動くということになります.

では早速,Nに対して足し算を定義してみます.

一つ目のメガネは 0+N は N になる.
二つ目のメガネは N +1 + N は N + N +1 になる
というものです.

ここまで用意しておいて,

を書き換えることができるでしょうか.

実は動きません.というのは,NをN+1で置き換えるときに,+1がNの隣の図形と重なってしまって,ぐちゃぐちゃになってしまうからです.図形が自動的に重ならないようにずれてくれることが必要なのですが,別の方法を考えます.

継承でスケールの違う絵を入れてみます.これも今のビスケットでは禁止されてますが,そういう拡張をしたとしたら,

のようになります.
これは
小さい N +1 は 大きいNと同じ動きをする
というものです.ここで大きなNの横幅に対して,小さいNが丁度半分,+1も同じように半分になっているのがミソです.なので,1を足すごとにスケールが1/2になっていきます.たとえば苦しいですがこんな感じ.

構造がN倍に複雑になる場合,スケールを1/Nにするとすることで,どんなに複雑な構造でも,同じ面積に収めることができるようになります.

画面の解像度が無限に細かいとすれば,どんな複雑な構造でも表現できるようになるので,ビスケットのデータ表現能力は一般的な言語の項と同じにまでなれます.

まだ,実装されていないものの話ですから,なんとでも言えるというか,「そういう能力を持つようにビスケットを拡張すれば,そういう能力を持つようになる」という当たり前の話をしているだけなんですけど.

ここでは,項と呼んでますけど,ポインタと言い換えてもよいかもしれません.普通の言語が複雑なデータ構造を簡単に扱える理由はポインタを使っているからです.ビスケットはポインタがない言語ですから,こんな大変なことをしなければならないわけです.

プログラミング言語はもっともっと自由なんだということを言いたくて思考実験をしてみました.

プログラミングはサイエンスか

2013-11-12 01:47:54 | 1
先週末に,お台場でサイエンスアゴラという科学コミュニケーションの祭典にビスケットを出展してきました.
「ビスケットによるプログラミング入門」
サイエンスアゴラは6年目だそうで,ビスケットは初出展です.

やってみた感想としては,子供たちに大人気.幼稚園児でも楽しんでできるので,二日間で何度も足を運んでくれた人もいて,僕らのブースだけちょっと違う雰囲気でした(お隣の黒ラブ教授も他所とは違う雰囲気でしたが).僕たちは,もっといろんな客層を相手にビスケットのイベントをやっていますから,こんな科学教育に理解のあるご家庭のお子さんたちには,ものすごくやり易かったです.みんな頭も良いし,素直だし.それと僕は,色々な科学館の方達ともお話できたし,熱心な親御さんともお話できたし,出展してよかったです.

サイエンスアゴラは前から知ってましたが,これまで出展するのに少し抵抗がありました.その理由は「プログラミングはサイエンスか」ということです.僕自身はサイエンスであると強く思っていますが,一般人はともかく,隣の分野の人たち(たとえば,物理とか化学とかがっちりサイエンスな人たち)からみて,まったくサイエンスであると思われていない,ということをうすうす感じているからです.

僕が学生の頃所属した研究室の教授はすごく理解がありましたが,そこの助教授がガチガチの理論物理でコンピュータを軽蔑していました.コンピュータは学問ではなく就職に有利だからやっているのだろう,と言われました.30年くらい前の話ですけどね.他の科学者たちも,その人ほど思ったことを口にはしないとは思いますが,でもそんなものだろうとは思っています.

いろんな科学館に行ったって,FAXの原理とか,0と1でなんとかとか,底の浅そうなあんまり面白くない展示が多いですから.

コンピュータは何かやりたいことを作るための道具としてはしっかりとした地位を確立したと思います.しかし,ものを作ることに重きを置き過ぎて,コンピュータとはいったいなんだろうか,といったことを考える対象としては見られなくなってしまった.僕が危惧するのは「コンピュータとはなにか」を深く考えずにすごい未来は作れないということです.

一つの例が,ビスケットによる感染のシミュレーションです.
動画
これを説明すると本当に皆さんに面白がってもらえました.この例は「情報とは何か」ということを非常にシンプルに説明しています.普通の物は二つに分けると,それぞれの分量は半分になります.物質は保存則が働くということですね.それに対して,情報はコピーしても減りません.コピーしたものは元のものと全く同じになります.言葉で言うと当たり前のようですが,この原理で動くので,感染は指数関数で広がって行きます.病気がうつった相手も自分と同じ感染源になるわけですから.よく「風邪は他人にうつしたら治る」という冗談を言ったりしますけれど,本当はうつしても治りませんね.病原菌がリソースであれば,相手に渡してしまえば自分は治りますけれど.つまりここでは病気は「情報」としての性質をもっているということなのです.

もう一つは,プログラミング言語の可能性ですね.どれくらいプログラミング言語は人間の発想を超えて自由になれるのか,ということです.ビスケットの入門で出てくる面白い例があります.

魚がボールをツンツンする,というプログラムです.

上のメガネは魚はまっすぐ進む.下のメガネは,魚がボールに当たったら,ボールは前に進んで,魚は後ろに下がる,です.
これを動かすと,魚はボールにツンツンする動きになります.ところが,このメガネのなかのボールと魚の配置を入れ替えると,まったく違った動きをします.

これは,魚とボールがぶつかると,魚とボールは後ろに下がります.その結果,魚はボールを加えて後ろに引っ張っているような動きをします.別の例では,魚がボールに乗っかって動いているように見えたり,ヘディングしたり.
動画

ビスケットの動作は,ステージ場の絵の配置に対して,メガネの中の絵の配置と近いものを探して,みつかったらそのメガネで定義している絵の配置の変化を適用する,というものです.コンピュータにとっては,絵の座標を書き換えているだけで,ツンツンとか,引っ張るといった動きの違いを考えてはいません.

一般的なプログラミング言語では,最初に言葉があります.つまり,ツンツンする動きには「ツンツン」という名前を付けて,引っ張る動きには「引っ張る」という名前をつけます.プログラミンだと,上に行く,下に行くといった動きの方向がすべて違う名前がつけられていますし,スクラッチだとまっすぐ進むことと回転することは違う名前で呼ばれています.動きだけじゃなく衝突判定はほとんど何もできてません.言葉で考えて,それをコンピュータに命令すると動く.それがごく普通のプログラミング言語です.

ところがビスケットの場合はどうでしょうか.動く方向や回転だけでなく,衝突についても色々なぶつかり方を区別できます.ボールが上に当たったとき,下に当たったとき.それらはすべて,絵の配置のバリエーションです.コンピュタにとっては絵の座標の計算だけをしています.人間とコンピュータとのやりとりに,人間用の言葉はでてきません.人間同士がわかり易いように,メガネの並べ方に対して「ツンツン」といった言葉を与える場合はあります.しかし人間がそれを何と言う名前で呼んでいようとコンピュータは関係なく動きます.

多くのビジュアルプログラミング言語が,単にシンタックスエラーを回避する目的にしかビジュアルの良さを使っていません.それに対して,ビスケットのビジュアルは,それが本質的な意味を持っています.そして,人間が使っている不自由な言葉を超えて,もっと多彩な表現力を失わずに残しています.これがビジュアル言語の可能性なわけです.

僕がスクラッチやプログラミンが嫌いなのは,情報とは何かとか,表現力の可能性を追求する,という深い話にならないからです.それで,プログラミングのごく浅い部分しか見せないから,ガチガチの科学者たちに馬鹿にされるわけです.


追記
スクラッチがサイエンスかどうかは,サイエンスをどう定義するかということですし.というより,ツールがサイエンスかどうかを決めるのではなく,どういう立場でツールを使うのかということで決まるのだと思います.スクラッチでもサイエンスにせまれると思います.だけど,僕が言っているプログラミング言語の奥深さには全然迫れていないですね.LOGOより退化してますよね.

ちなみに,サイエンスアゴラのサイトでは,

http://www.jst.go.jp/csc/scienceagora/about/
 ここでいう「サイエンス」は、生命科学、理学・工学のほか、人文・社会科学までも含む広い意味で用いています。

と書かれてあるので,かなり広くとらえてよいと思います.開催側はそう考えているとしても,実際に出展しているガチガチの科学者たちにどう見られているかは別です.