« August 2007 | Main | October 2007 »

2007.09.30

親子

娘が家の中で水着を着ながら3色ボールペンを真剣に分解している。この前は、上半身パジャマ+エプロンだったし、新しい萌えを追求している気がする。インクが飛び散ったり、食べたりする可能性もあるので、こっちも真剣に眺めている。

僕「なんで家の中で水着着てるかわからないけど、ボールペン分解するのは楽しいよね」
嫁「家の中で水着着るのは楽しいよ。でもボールペンは理解できない」

どーみても二人の子供です。

| | Comments (0) | TrackBack (0)

2007.09.27

今日の日記

・アクセス制限
会社や取引先の人とか、リアルで知り合いな人だけアクセス制限したいときってある。逆Mixiみたい。会社の愚痴とか、そういうの書くところがたまには欲しい。でも増田は嫌。どれくらい有効か分からないけど、トップにロリな絵を貼り付けて、まっとうな組織では立ち上げられないようにするのも良いかと思った。

フィンローダ・メソッドと名付けてみた。

↓こんな発言とか

・オタリーマン
1,2とも身に覚えのある話ばかりで、読んでいてイタタタタとなる。
会社の女の人と目をみて離せなかったり、タクシーを一緒に乗るとめいっぱい距離を取ろうとしたり、良くある。

・続 初めてのPerlより。
Perlはインタプリタですよみたいな分類分けをすると、コンパイルしているぞ!と突っ込む人たちが必ずいるわけです。Perlはコンパイルするよ厨かと思っていたのですが、BEGIN {}とか、useとか、コンパイル抜きでは理解できない機能がPerlにはある事をしりました。なるほど。

・バイオインフォ
もうちょっと良い省略の仕方は無いんだろうか。バイインじゃちょっといやらしい、BIは略しすぎ、バイフォくらいでどうよ、と思うんだが超素人がこんな所で書いてもしょうがない。しかし、バイオインフォマティクスの本は遊びが無いな。UNIXの本とか、最初にGNU's Not Unix とか、次は中野さんがどうのとか、いろいろ書いてあったきがするんだが。まずはおやじギャグから入る。

バイオインフォマティクスのためのPerl入門がわかりやすそうなので、そちらでPDBと戯れることにする。
デジャブ感があると思ったら、Data Crunchingに出てきたフォーマットだ。
参考:Data Crunching
Pragmaticの本は、原書で頑張って最後まで読んだ本は内容がまあまあのできで翻訳されず、これはって思った本は読み切るより早く翻訳される法則がある。前者がData CrunchingとBehind Closed Doors、後者はship itとインド人に仕事を取られるやつ。得しているのか?

会社の机が、Perlの本だらけになって「僕だけ遊んでいます」感が漂ってきた。

| | Comments (0) | TrackBack (0)

Transaction-Level Modeling With SystemC その3

3.4 Examples of TLM-oriented Device Driversは面白い。じっくり読んだ。

ISS経由で動かすか、nativeで動かすかの違いだけど、簡単に行き来できるようになっていればいいんだ。関数名や変数名がぶつかるかもと書いてあるけど、C++でもそんなことがあるのか。DUTのモジュール名がたまたまtlmだったりすると悲惨なことが起きるな。この本にこのことが書いてあるの2回目だから、実際に痛い目にあったんだろうなと予測。

気がついたけど、書いている人ってソフトよりの人だ。ハードウェアの抽象化が漏れているところ(受信バッファのオーバーフローとか)の対応がpainって書いてある。ハードの人なら「いやいや、それの仕組みを理解して書くのがあなたの仕事でしょ」と思うはずだ。回路図読めとは言わないから、データシートくらい全部読めよというのうは普通の感覚。Linux/Windows/uITronのdriverがこういう仕組みで動いているから、こういう風にdriver書けば良いんじゃないかな、まで考慮してハードの資料作っている人って見たこと無い。僕も出来ない。driverを実際に書く立場の人が「あそこはドキュメント少ないから使いたくない」という意見が反映される可能性というのは限りなく0なので力関係なんだろうな。「まだメーカーも何にも決まってないんだけど、通信用の石が最低2つつくからそれのdriverと試験も見積もり入れといて」なら良く聞く。ちょww、最低個数よりも最大個数をちゃんと聞いてこい。

| | Comments (0) | TrackBack (0)

2007.09.26

Verilogをはじめよう! その4

レジスタ:エロゲのフラグ
クロック:エロゲのクリック
ステートマシーン:エロゲのシナリオ分岐

過去記事
Verilogをはじめよう! その3
Verilogをはじめよう! その2
Verilogをはじめよう!

| | Comments (0) | TrackBack (0)

今日の日記

・アサヒる。
http://blog.livedoor.jp/dqnplus/archives/1035038.html
最近の若い子は、アベるだと思うよ。安部さんには言いたいこともあるけど、今のタイミングだと「お疲れ様でした。」と言うのが日本の文化だと思っていたのだが・・・。もう、KYって誰って感じ。

・バイオインフォ
タンパク質の情報はここ http://www.pdbj.org/index_j.html
PDBはここ http://www.rcsb.org/pdb/home/home.do
PDBフォーマットはここ http://www.wwpdb.org/docs.html

PDBと言えばpalmだと思う。

・Amazonで見つけたSystemCの新商品
http://www.amazon.com/Hseplnt-Systemc-1%25-Gran-8Oz2/dp/B000BX1HKI/ref=sr_1_13/102-1117548-6484131?ie=UTF8&s=home-garden&qid=1190766619&sr=8-13

・自作高位合成ツール
Neon lightさんを見つけた。意外にココログって技術系のblogが眠っている気がする。
コーディングガイドとか、激しく共感。

・なんだかんだ言って大人気
http://b.hatena.ne.jp/entrylist?url=http%3A%2F%2Fd.hatena.ne.jp%2Fshi3z%2F

・マシン語
http://dochikushow.blog3.fc2.com/blog-entry-624.html この人の本持ってる。
> たかだか2~3日ですむんだから覚えとけば良いじゃん
この意見は新鮮。

・Perlの勉強
関数プロトタイプ宣言のやり方が、やっつけすぎでワロタ。

| | Comments (2) | TrackBack (0)

2007.09.25

情報整理

Perlの勉強用に、shinhさんが書いたMakeっぽいPerlスクリプトがあったはずと、お昼からずっとさまよう。どこかのtxtファイルにメモったはずなのだが、どのファイルか分からないし、そもそも検索のキーが分からない。で3時間近く、ここここをさまよって、ここで、やっとみつけた。

ネットワークのアクセスに制限のあるPCに、USBメモリでひたすらデータを移動させるという、タンポポレベルの仕事をやりながらだったがちょっと疲れた。今後面白い物を見つけたときは、ローカルに情報を保存しないでちゃんとblogに書こうと思った。

Makefile テンプレート作成ツール kati

| | Comments (0) | TrackBack (0)

Transaction-Level Modeling With SystemC その2

丁寧に書いてあって面白いが、密度が濃いので読むのが疲れる。

2.2 Our Journey to SystemCから
Esterelという、並列記述言語を発見。ここから、Verilog出力したりできるのか。Bluespec以外にもいろいろある。

2.3 Software Enironments of TLM Platform
ソフトウェアを、ISSを使わずにSystemCのフレームワークに入れてしまう時のの注意点
1.Endianness
2.Assembler
3.Self-modifying code → 俺様デバッガが作れない
4.Data alignment and size
5.Addressing features

なるほど。

| | Comments (0) | TrackBack (0)

Larryが決めた

とりあえず「初めてのPerl」を最後まで読んだ。いろんな所で「Larryがそう決めた」と出てきて面白い。

「続・初めてのPerl」に入ろう。

プログラミング言語Perlから。

> これまでに見た最もお気に入りのアニメは「少女革命ウテナ」で
> 今見ている最もお気に入りのアニメは「るろうに剣心」である。

Larry Wallが、るろうに剣心好きと書いてあって一生Perl使おうと思った。

| | Comments (0) | TrackBack (0)

2007.09.24

今日の日記

・子供
どうでもよいけど、子ども達なんだな。子供で良い。

・CPUの創りかた
 を娘を膝に乗せて読む。嫁には見せられないからこっそり。
 読み返すとデータパスの説明の所は初心者に難しい気がする。ここで説明してある事は、パタヘネと同じ事だから理解できればずいぶんとレベルが上がっているんだけどね。ALUにどのデータを入れて、どこに結果を入れるかを、命令セットで切り替える。ここだけ萌え絵や軽口が少ないのは、そうとう書くのに苦労したんだろうと思う。何回読んでも、CPUの動きをデータの移動と割り切るのは天才的な切れを感じる
 残念なことは、娘が全然興味を示さないことだ。
 
 
・TCLネタ
ときどきの雑記帖 リターンズさんから。
突っ込みありがとうございます。

> まあ「数値」は整数だけではないので、数値を表すメンバーとして 整数+(倍精度)浮動小数点数+文字列 と持つよりは、 数値は浮動小数点数だけにしておいた方が都合が良いことが多い ということがあるわけで。これはまあawkからの伝統ですね。
 
なるほど。

EDA業界では、Altera、Xilinx、シンプリシティ、シノプシス、Mentor、Cadence等そうそうたる会社がそれぞれTCL処理系をバンドルしていますね。guileに駆逐されてしまえばよいのに。

こんなのみつけた。TCL for EDA project

コンピュータアーキテクチャのエッセンス
 よい子はヘネパタを読んでから。
 物事の重要性とか、教える優先順位がgdgd。まじめに書いてあるだけに面白い。ここでSRAMの説明がくるか、とか。実際のハードの動きをちゃんと教えたいんだろうけど、教え切れていないもどかしさがある。性格的に、ここは重要じゃないって割り切れないんだろうな。驚くべき事にメモリの容量は2のべき乗ではなく10のべき乗になるって、今まで2の補数とかさんざん説明してきて、今更そこで驚く筆者に驚きだよ。

・TCLネタ その2
 C:\altera\71sp1\quartus\common\tcl\apps\qflow>quartus_sh -t qflow_script.tcl
 ディレクトリは各自置き換えるとして、このコマンドで嘘っぽいquartusが立ち上がる。
 
 
・曹参
曹参だけじゃ特定するのは難しい。項羽に攻められて半泣きで逃げたとき、劉邦の近くにいた人だっけ?子供を捨てた時に馬車止めた人。違った、それは夏侯嬰だった。
 季布、かっこいいよ、季布


・☆を間に入れるとエロゲになる
 らしい。某チャットから。
 
 すも~る☆と~く
 こもん☆りすぷ
 しぃ☆ぷらぷら
 ぱ☆ある
 
 なるほど。

| | Comments (0) | TrackBack (0)

Transaction-Level Modeling With SystemC その1

Transaction-Level Modeling With SystemCから。

.comの値段なんて、見なければ良かった。$77の本を、18000円で売るってどうよ。僕が買ったとき16,016円だったから、前向きに2000円得したと思おう。
本の説明はここ

メモ 5. Advantages of TLM

TLMを使うメリット
1. Early software development
2. Architeccture analysis
3. Functional Verification

| | Comments (2) | TrackBack (0)

Verilogをはじめよう! その3

前回はすべての論理回路はANDとORとNOTに還元できて、それがびっくりするくらい間違いだったという所まででした。

今回はHDLで回路を記述するメリットについて、いい加減に説明してみます。

独断と偏見でHDLで書く回路を分けると、制御系と演算系に分かれます。C言語でいうところの、業務系とか組み込み系とかそんな感じです。多分。

制御系というのは、DDRメモリにリード/ライトしたり、LEDをつけたり、ロジックを超えて何かを制御する人たちです。制御系の回路というのは、外部との嫌な部分を隠して演算系の回路とデータをやりとりするが仕事です。LSIの内部でも、クロックツリーを設計する人や、無茶早い乗算器を作っているような人は、ここに入ると思います。デジタル回路と呼んではいますが、他の部分がちゃんとデジタルで動くように何とかしている人たちです。Intel様は神様で絶対に逆らえません。JEDECとか下手に規格団体作って資料が分かれるより、全てIntel様で情報を管理して欲しいです。でも資料は探しやすくお願いします。制御系の回路は、完全に電子工作の延長上なので今回は特に話しません。

制御系と違うところに位置するのが演算系の回路です。ちなみにこの分け方は私しか使っていないので、特に学生の方は鵜呑みにしないようにお願いします。演算系というのは、入ってきたデータに何か演算をして、どこかに出すこと。CPUの創りかたによると、データの転送こそがCPUの動きなので、まさにCPUを設計しているようなそんな楽しい回路です。デジカメの中ではほにゃららフィルターで画像処理をしたり、電気の知識よりは数学的な知識が必要な所です。

HDLも他の言語と同じく、論理演算と算術演算があり、だいたい同じように動きます。他の言語との決定的な違いは、任意のビット幅で自由に並列演算ができる点です。重要なのでもう一度書きます。

・HDLを使うと、任意のビット幅で、自由に並列演算ができる。

これこそが、HDLをはじめる最大の理由です。

実際に並列に演算をしているHDLを見てみましょう。

reg [3:0] output_a, output_b;
reg [9:0] output_c;
reg [12:0] output_d;

always @ (posedge clk) begin
  output_a <= input_a + input_b;
  output_b <= input_a + input_c;
  output_c <= input_b + input_c;
  output_d <= input_d + input_c;
end

こういうVerilogは、こんな感じに合成されます。

予想通り、加算器が4つ作られています。
ここの説明はちゃんとしようとすると難しいのですが、上のように記述すると全ての加算機は同時に動きます。threadやfiberといった見かけ上同時に動くモデルではなく、本当に4つ同時に動きます。昨今のCPUは、命令の並列性を高めるために涙ぐましい努力をしているわけですが、HDLで並列に演算をするのはこんな簡単に実現できます。実際、プロセッサのパイプライン、スーパースカラー、アウトオブオーダー、レジスタリネーミング等の涙ぐましい努力は全てはHDLで記述できます。裏は取っていませんが、大半のCPUはこういった動作をHDLで記述して作られているはずです。私が知っているだけでも、身近にあるプロセッサのうち、最低4つは全てHDLで書かれています。

ちなみにRTL ViewerがXilinxからAlteraに変わりましたが、深い意味はありません。片方だけ押すと、EDSFで襲われるとかそんな物騒な業界ではないので安心してください。

並列性ともう一つの特徴である、任意のビット幅という点は上の絵をもう一度よく見てください。台形の形をしたものが加算機なのですが、上から12bit、10bit、10bit、4bitになっているのがわかるでしょうか。

reg [3:0] output_a, output_b;

の部分はC言語の配列の宣言に似ていますが、こう書くことで4bitのレジスタが作られます。一番下の加算機は、代入先output_aが4bitなので、4bitの加算器が作られています。当然、reg[99:0]とすれば100bitのレジスタが作られ、そこに+の演算子を書けば100bitの加算器が作られます。プロセッサを使った演算が、プロセッサが想定しているビット幅を超えると複数の命令が必要になることを考えると、HDLを使うメリットも良く分かるのではないでしょうか。

細かいところですが、HDLのレジスタは好きに順番の入れ替えや分解ができます。

{input_d[5:0], input_c[3:0]}

こう書けば、上位6bitがinput_d、下位4bitがinput_cな10bitなレジスタが作れます。

{input_a[0], input_b[0], input_a[1], input_b[1], input_a[2], input_b[2], input_a[3], input_b[3] }

こう書くと、input_aとinput_bのLSBとMSBを入れ替え、交互に配置しして一つの8bitレジスタを作ります。ハッカーのたのしみの中の人から見れば泣いて喜びそうですが、彼らはHDLの世界でもそれなりに無茶な演算を思いつく事でしょう。基本的にはMです。

この技術を駆使すれば、特定の演算に特化したすごいハードが作れるのはずなのですが、なかなか現実は難しいです。実際演算能力のみでハードウェア化している例は非常に少ないです。ハードウェア化する大半が、物理的な小型化や、バッテリ駆動のため、あるいはコントローラと一体化してリアルタイム性の確保/CPUの負荷を減らすとかそんなのです。あと、セキュリティとか。

並列化のみを見た場合、10個程度の中途半端な並列化ではGHzで動くIntel様プロセッサに歯が立ちません。10000個といったスケールで並列化できているなら、これもパソコンを並べた方が良いでしょう。前門のIntel様、後門のGoogleです。ただでさえニッチなところですが、今後もどんどんニッチになっていくと思います。
そんな状態でも、我こそは!と思われる方は、是非ハードウェアの業界に来てください。

まとめ:×Intel、○Intel様

過去記事
Verilogをはじめよう! その2
Verilogをはじめよう!

| | Comments (0) | TrackBack (1)

下に降りると言うこと

アルゴリズムを知らない子ども達と、あろはさんの論文を読んで、いまさらながら一つの事実に気がついた。

降り方って1つじゃない。

プログラミングって言うのはアルゴリズムをコンピュータが理解できるようにすることだから、そこだけみても物としてのコンピュータの降り方と、アルゴリズムとしての降り方がある。前者が命令セット、マシン語(笑)、・・・量子力学と降りるとしたら、後者はデータ構造やらを経てチューリングさんの機械に行く気がする。この2つが全然別の降り方をするわけではなくて、ブール代数はどちらの降り方でも重要な位置を占めている。

降り方は複数有るし、互いに交わっている。

プログラムから一つ上に上がって、絵を出すプログラムを考えてみる。出力デバイスの方に降りようと思ったら、ブラウン管にしろ、液晶にしろ、どこかで電磁気学にぶつかる。これは、今のコンピュータを動かしている半導体による回路と知識を共有する。画像を見るって所で降り出すと、そもそも「見る」って何よって話になるし、見えた物を○○として認識するってのもそれだけで一つの学問だ。

文字列一つとっても、文字って何?って考えただけで一大スペクタル。人類すげー。

話を戻すと、共有している部分が大きいところというのは、抽象化が上手く行っている所に見える。ブール代数で上手く説明できるのであれば、0と1が物理的なスイッチなのか、電圧の0V/5Vなのかというのは意識しなくて良い。同じように、電磁気学で説明できるなら量子力学まで降りて行かなくても良いと思う。半導体は量子力学の成果だと思うけど、部品としてトランジスタを見る分には量子力学はいらない。まして、フリップフロップまでいってしまえば、CLK毎に値を保持する装置で十分だ。でも、電圧とかノイズの知識がないと困ったことになるから電磁気学の知識必須。

半導体以外のデジタル回路ができたとしても、最初は0で0V、1で5VのようなI/Fがつくんじゃないかな。世の中にあるメモリとかいろんな物がそのまま使えるから。そうなると半導体は交換可能な部品になる。話の流れ的には、ここで半導体の動作原理である量子力学が不要になって欲しいけど、多分そうはならない。次は量子コンピュータだ。時代はファインマンに追いつけるだろうか。

アルゴリズムを知らない子ども達を読んで思っていたもやもやが少し晴れた。考えるって大事だ。

| | Comments (0) | TrackBack (0)

2007.09.21

等価変換プログラミングパラダイムにおける問題解決

○○をさぼって読んでみた。○○の中にはいるのは家事だよ。多分。

全体的に隠しきれない若さがあふれでる文章でした。うらやましい。いや僕も気持ちは若いよ。頑張ろう。

> 産学協同とか大げさに構えるんじゃなくて、学生と社会人が同じレベルで議論できる場があればそれだけで凄いことだと思った。頑張れWeb2.0。

昨日書いた事が見事に実現されていて驚いた。そうか、あろはさん今研究中なんだ。GCCを使いこなせたら、FSFはもとより組み込み業界は引き手あまただと思んだが、給料は安いですよ。そしてunsigned short [100] data;のように確保して、Excelの表でNバイト目はXXFlag、みたいに管理しているCプログラマを見て悶絶するだろう。「N君、なんかねshortだと時々数字がおかしくなるんだけど、unsignedって入れると上手くいくんだよ。」と笑顔で言う上司に絶望した!。しまった、N君は僕のことだ。機能毎にソールファイルはわける、ただし、#include "func1.c"でリンカいらず みたいなっ!


やはり、研究者が思うプログラミングと、職業プログラマが思うプログラミングのギャップを感じました。プログラミング言語は問題を解かないといけない、くらいまでは一緒なのですが、目の前にある問題が違うというか。職業プログラマはもっと即物的な問題を解いて欲しいんだろう。階乗とかセールスマンじゃなくて、もう一歩だけでも歩み寄ってもらえるとETの力がよく分かると思う。いくらLispで階乗とかハノイとかしてもLispの力が分からないように、ETなら簡単にすごいことできるよ、ってのがあるともっともっと真剣に読めると思いました。もちろん、読者に職業プログラマは想定してないので的はずれでしょうが。Paul GrahamはでてくるけどJoelが出てこないのもそこなんでしょう。

遠い将来、自分が本を書くことになったら引用しようと思った。カコイイ。

> すなわち,最も基本的な階層の上に,何らかの,より抽象的で大きな視点から定式化さ
> れた階層を積み上げ,概念をまとめ上げていくことは,より高次のレベルで問題を考える
> ことを可能とし,発想の幅を広げるため,それが表現できるか否かという数学的可能性と
> は無関係に重要なのである.

| | Comments (2) | TrackBack (0)

今日の日記

・コンピュータアーキテクチャのエッセンス
ときどきの雑記帖 リターンズさんから。
アマゾンカートに直行。

・バイオインフォ
バイオプログラミングで、バイオインフォの勉強を始めた。1時間読んでみたけど、3ページくらいで寝そうになる。

>ヌクレオチドが鎖状に連なり、糖(デオキシリポーズ)とリン酸から成る骨格を形成する。それぞれの鎖から突き出た塩基同士が水素結合を形成する。水素結合を形成するのは、アデニン(A)とチミン(B)、グアニン(G)とシトシン(C)という対である。この水素結合により、2本の鎖は逆向きに絡み合い、ラセン構造を形成する。


わからないこと
・ヌクレオチド
・鎖状に連なる
・糖(デオキシリポーズ)
・リン酸
・骨格を形成する。
・突き出た塩基
・塩基
・水素結合
・チミン、アデニン、シトシン、グアニン
・ラセンって物理的な話 or トポロジーの話?

とりあえず分かった事は、AとT、CとGでそれぞれ仲良し。こんなときosdev-jの中の人のように萌え絵が描けたら、もっとわかりやすいのと思った。最初はこんなもんか。学習の静止摩擦係数を乗り越えよう。


・Stallman
ユメのチカラから。
Stallmanかっこよすぎる!

・可愛い
檜山正幸のキマイラ飼育記から
近所の子が鬼ごっこしているみたいなんだけど、いろんな必殺技があって見ていて飽きない。○○って技は、鬼が技を出したときにジャンプしてたらセーフとか、階段とか地面より上に上がった状態でいられるのは10秒までとか、何か元ネタがあるんだろうな。

冷凍ビームって技は、かけられるとその場で停止しないといけない。冷凍だから。でも、技をかけた方も「冷凍ビーム」と叫んでポーズをとり続けないと駄目らしい。技をかけている間二人とも一歩も動けないから、ちょwww、鬼の冷凍ビーム、意味ねーよwwwって笑いながら見てたりした。

後のDIO様である。


・初めてのPerl
Perl内部では整数値は存在しない。全部整数と文字列でやっているのかと思ってた。たしかTclが全部文字列だ。Tclも勉強するリストに入っている。EDA業界の中途半端Tcl浸透率って異常だと思う。一つのTcl処理系で全部動けばよいのに。
0が最初だと8進になるのはCと同じ。0bでバイナリは便利。
ちゃんと読む→ http://d.hatena.ne.jp/naoya/20060521/1148179798
Effective Perlは名著なのか。実家に送らない事にする。Perlデータマンジングはアマゾンのカートへ。


2つめのプログラムで、普通に@linesを@lineとtypoしてはまる。自分のレベルに絶望した。perldocが動いていないと思っていたよ。
http://naoya.dyndns.org/~naoya/mt/archives/000892.html
strictとmyを使おう。

・というわけでTclネタ
Quartus II Handbook Volume 2: Design Implementation and Optimization
Chapter 3. Tcl Scripting (ver 7.1.0, May 2007, 390 KB) から。

End-to-End Design Flows

You can use Tcl scripts to control all aspects of the design flow, including
controlling other software if it includes a scripting interface.

(省略)

Because scripts for different tools must be executed with different Tcl interpreters,
it is difficult to pass information between the scripts unless one script
writes information into a file and another script reads it.

いろんなEDAツールがTclのインターフェイス持っているけど、それぞれ違う(ベンダー拡張された)インタプリタで実行されるから、一つのTclスクリプトで全部やるのは難しいよ、という話。Tclに合わせている意味ねーよ。

・マシン語で面白いところ
というのは、限られたバイト長にどうbitパターンを振り分けてるかだと思うんだ。32bitプロセッサの命令長が32bit固定ならば、その時点で32bit即値のLoad/Storeができなくなるとか。x86で、push、pop、inc、dec、nop 1バイトウマーとか。ARMのバレルシフタ考えた奴はKitty Guyとか。命令セットと言っちゃうとアセンブラのイメージがある。

| | Comments (5) | TrackBack (0)

2007.09.20

あろはさんの論文が凄い件

http://www.geocities.jp/kl1_interpreter/GradThesis/
軽く印刷しようとして驚いた。卒論が300ページ近くもある。修士かと思ったら学部で二度びっくり。
普通卒論って「卒業論文要旨」くらいじゃないの?僕が徹底的にさぼっていたというのを抜きしても、一緒に卒研やっていた人達ってその程度だった気がする。修士を狙っている/いないで気合いの入り方は違うと思うけど、こんなには書けない。大学4年生の時って、SFCでトルネコしたり、Takeruで買ったティルナローグ遊んでばっかりだった。ホロホロの皆さんごめんなさい。いやいや、僕の話はどうでもよい。

気になったのは、卒論って社会に役に立つことを意図されているの?って事。今まで、卒論というのは卒業証書みたいなもので、個人の思い出としてそっと取って置く物だと思っていた。大学の友達と話していても、「俺の卒論こんなの」って話をすることはあっても「じゃあ、読ませてよ」まで話が進むことはない。修士も同じで、大変だーとは聞いてもその人の論文を読もうって気にはならなかった。それこそ、大学生の数だけ卒論があるのに、大半は論文の存在自体知られなくて研究室の中で風化されているんじゃないだろうか。もったいねー。

僕は自分の研究室(の自分が卒業したとき)の論文しか見たことがないので、あろはさんが特異点なのかどうか判断できない。こんなレベルの論文がいっぱいあるんだったら、もっと見てみたい。FPGAを使ったリコンフィグとか、マルチプロセッサとかいろんな所でやってますよね。最終成果物としての論文だけじゃなくて、Wikiベースで途中経過が見られたりしたら、もっと面白いことが出来そうな気がする。産学協同とか大げさに構えるんじゃなくて、学生と社会人が同じレベルで議論できる場があればそれだけで凄いことだと思った。頑張れWeb2.0。

| | Comments (0) | TrackBack (0)

今日の日記

若い人にGerberって何ですか?って聞かれた。プロッターという単語がその場で出てこなかったので、PostScriptみたいな感じで線とか円とが書いてあるフォーマットって説明してみた。

若い人「PostScriptって何ですか?」

そう返されるとは思わなかった。orz

| | Comments (0) | TrackBack (0)

Perlの勉強

Perlの勉強を始める。

何回か読んだ入門Perlは内容が古いらしい。どうりで、他でみるコードは雰囲気が違うはずだ。

本棚を眺めて、とりあえず「初めてのPerl」とタイトルが付くオライリー本が4冊もある。
初めてのPerl続・初めてのPerl 改訂版の順で読んでいけばよさそう。

古い初めてのPerlとfor win32、Effective Perl、プログラミングPerlの第二版も必要ないか。2000年以前に書かれた本は実家に送ろう。

| | Comments (0) | TrackBack (0)

2007.09.19

Dewign Wave 2007 10月号

久しぶりに買った。
ソフトマクロでかかれたCPUの話。結構濃いな。

LatticeMicoプロセッサが面白い。Windows環境で簡単にGNUのtoolが使えるのがうれしい。

DWには書いていないけど、極小8ビットプロセッサという物もある。リンク先の画像を見てもらうと、PCの存在は大きいがSICPのRegister-Machineにかなり構成が似ている。

HDLabさん所のSystemC 動作合成スタイルガイド 300万円かぁ。

欲しいな。3万円くらいまで下がったら買おう。合成に関する部分を抜いて、個人向けに再編集してくれないかしら。ここに書いたら中の人に伝わるのを期待。たかだかコーディングガイドに300万という値段もあれだが、取れるうちに取るのは商売の基本。

| | Comments (2) | TrackBack (0)

じわっと増えるVerilog/VHDL blog

コーヒーでも飲みながら検証の話でもから
有限?態機的都會傳奇(コピペできない)

たーぼ のハードウェア設計記録
VHDL TIPS 「shared variableの使用法」

あああ、素晴らしすぎる。
こういうHDLの小技を情報共有するってのは、半年前には全く無かった気がします。「各自好きな回路を作る。その過程で思ったことを書いておく」が今までのFPGA/HDL blogだとしたら、この2つはみんなで情報を共有しようという意志がある。

少しずつ良い世の中になっている。

| | Comments (2) | TrackBack (0)

「計算機プログラムの構造と解釈(SICP)」を読み終えて by なつたん

ひげぽんさんの所パクってテンプレートにして書いてみました。

練習問題をスキップしつつ、私も約半年でで読み終えました。とても楽しい日々を過ごすことができました。

SICPを読む過程で得たもの
・遅延評価とstream
・制約プログラミング、ロジックプログラミング、amb
・Emacs(Meadow)+gauche+Quackの組み合わせ便利
・同じ事を表現するのに、抽象度を上げたり、下げたりできること。
・手加減してあればLispのソースも追えるようになった。手加減していないのは駄目。
・Lisp特有の、手続きを評価する→S式ができる→また評価する→S式ができる、という気持ち悪い再帰の存在。
・SICP読み仲間ではないけどいろんなblogつながり。組み込みとFPGAだけでない、いろんな世界がある事をあらためて感じた。

SICPを読みはじめたときの動機を振り返る
・関数型言語について
 Lispは関数型言語では無い事が分かった。C++と同じで、関数型言語として書くことも出来るし、ループと破壊操作の組み合わせでも書ける。ただ、特別変わった言語という意識は無くなった。
・悟りについて
例のあれ
> LISP is worth learning for a different reason - the profound enlightenment experience you will have when you finally get it.
> That experience will make you a better programmer for the rest of your days, even if you never actually use LISP itself a lot.
この経験が役に立つかは、これから僕がどうするかだ。新しい概念は勉強できたけど、悟りを開いたかどうか微妙。
・Lispについて その1
 とりあえず、S式の世界に引きこもっているならLispが最強だと思った。SICP一冊読んだらLispについて語れるようになるかと思っていたけど、ただの入り口にしかすぎなかった。むしろ、読み終わってからLispの開始。Welcome to the Lisp world。
・Lispについて その2
C言語のプロトタイプ宣言程度の型チェックが欲しい。変数や関数に適切に名前を付ける能力が無いとLispは使いこなせない。自動GCは便利。Typoに弱い。デバッグ中に自分の想像と違う部分のコードが走っていてはまった。それぞれ良い方法があるんだろうけど。
・Paul Grahamについて
 Paul Grahamの言うところのLispの力は少しだけ分かった。Lispの力の一つは「S式引きこもり」。マクロも勉強しよう。もう一度、普通のやつらの上を行けを今読むと、Paul Grahamが丁寧に言葉を選んでいるように見える。

駄目だ。全然パクリ切れてない。普通に書こう。

SICPを勉強するのは、ハイソなお嬢さんと一夏を一緒に過ごしたような感じ。(ハイソって死語か)

3章まではいままでとは違う世界を丁寧に順番に紹介してもらい、住んでいる世界が違うことを実感。4章で初めての共同作業、世間しらずのお嬢様と思っていたけど、芯は太くてしっかりしている事を確認。5章は最後に一緒に映画を見に行った甘い思い出。このまま、美しい思い出のままで終わっても良い気がする。

思い返しても4章はきつい。ここから日本語の情報が激減する。できる一部の人たちは別の言語で処理系を作り始めるからあまり参考にならず、それ以外の人たちはここで脱落しているのでは無いかと思う。もしくは、大学の授業がその手前で終わってしまうとか。4章のきつさは、説明読む→打ち込む→動かして確認 のループが大きすぎる事。練習問題を解いてもそこだけは動かないからあっているかどうか分からない、Streamとか、put/getとか、今までに学んだことが当たり前のようにでてきて、飛ばした人間を容赦なく絶望させていく。

The老害のアドバイスとしては
・20代で読め!
 10年前とは言わなくても5年前にSICPを読んでいたら、と何回も悔やんだ僕がいうんだから間違いない。他の言語での実務経験はあった方がより楽しめる。
・半年くらい勉強する時間を作ろう。
 本文だけ読むよりは実際に手を動かした方が楽しい。ある程度時間がかかるという覚悟は必要。
・4章で迷い始めたら。
(1)とりあえずそのセクションは写経する。
(2)手続き毎に、教科書本文の説明をソースに付け加える。この手続きは○○を引数に××を返す等。
(3)一部でも動きが理解できたら、そこだけの単体試験を行う。
(4)納得するまで(2)に戻る
で、なんとか動きました。必要に応じて3章以前に戻るのも大事です。4章は特別難しい。
4章を理解すると、5章はボーナスステージのように面白いから頑張ろう。


今、次の本を決める至福の一時を満喫中。EoPLも良いんだけど、HTDPも興味あり。
思いて学ばざれば則ち殆うしのコメント欄が気になっていて、SICPよりもわかりやすくて、同じように楽しめる書籍があるなら、そっちの方が良いと思うんですよ。CPUの設計で言えば、Computer ArchitectureパタヘネCPUの創りかた の関係が好きで、内容もボリュームもSICPはパタヘネに相当する。パタヘネが終わった後に、次はヘネパタだとか、Intelのデータシート読めとか、いやいや論文ですよ、みたいに言うのは簡単で、むしろパタヘネが難しいって人に何を薦められるかって事の方が難しい。とくに社内でLisp仲間を増やしたいなら、SICPでふるいをかけるよりはもうちょっと難易度の低い本が欲しい。The Little Schemerはちょっと違った。

そんなこんなで一夏の思い出を胸にしまい、FPGAの世界に戻ってこよう。 ♪終わらない、なつやすみ~

| | Comments (5) | TrackBack (1)

SICP 5章 Computing with Register Machines

こういう計算機の説明の仕方もあるんだと、普通に感心した。
bit幅やアドレッシングが出てこないCPUの教科書って想像できますか?

それでいて、ALU、スタック、関数呼び出し、スタックといった基本構造だけでなく、コンパイラの最適化とリンカーまで、抽象度を上げたまま説明している。もちろんGCも簡単に説明してある。ネタとしか思えないんだけど、綺麗にLispの世界で説明しきっている。5章全部でfetchという単語が2回しかでてこない。計算機にとって、命令は取ってくる(fetch)するものではなく、単に実行(execute)する対象でしかないんだなとあらためて気がついた。そういえば、チューリングマシンにも命令フェッチって概念は無い。

プロセッサ、コンパイラ、リンカ、実行ファイルを抽象度を上げて考えるということを、今までしたことがなかったので夢中になって読めた。4章でさんざん苦労してきた事が、最後に綺麗にまとまったという感じを受けた。Webでも読めるけど、5章だけ読んでも面白くないと思う。

興奮が伝えきれない自分の国語力にorz

| | Comments (1) | TrackBack (0)

下ネタでSICP 5章

5章ヤバイ。エロい例えしか出てこないくらいヤバイ。
初めて憧れの女の子の手握ったら、やわらかくて、あったかくてびっくりしたくらいヤバイ。

イケメンPaul Grahamが、嫌がるStroustrupを華麗なマクロで翻弄し、生(ポインター)でアッー。

錯乱中

| | Comments (0) | TrackBack (0)

2007.09.18

本好き

イネムリネズミ日記から。
> 蔵書が1000冊を超えてしまいました。

1000冊!すげー。冊数よりも数えている方が凄い。僕はどれくらい持っているだろう。400~500冊くらいだと思うんだけど。会社に100冊以上あって、この前100冊捨てた感覚からいくと、500超えていそうな気がする。

Bibliomania-ビブリオマニア(愛書狂)とは何か-によると、僕はどちらかというとリーディング型だけどビブリオマニアって程でもない。ちょっと本が好きくらい。でも鞄の中には常に三冊くらい本がないと落ち着かない。ちなみに今日は、SICPの印刷、SystemCの本、ラノベ2冊で、4冊分くらい。読めればいいので、blogとか読み出すと一度見たblogでも何時間でも読んでられる。危険。技術書はそれなりに丁寧に扱うけど、ミステリーは2度と読まないのが分かっているのでポテチ食べながらでも読む。コーヒーこぼしても気にしない。外出先で読んだら、駅のゴミ箱に普通に捨ててくる。重いしね。


いまさら「活字中毒者に50の質問」やってみよう。

1.あなたの活字中毒度を病気に例えると。(例:軽い風邪)
生活習慣病

2.病気を決定的に悪化させた具体的な原因(本)に心当たりは?
小さいときに家にあった手塚治虫の漫画。

3.活字中毒であることを改めて確認したエピソードがあれば教えてください。
本を読みながら駅の階段を下りたら、足を踏み外して死にかけた事。それ以来、階段で本を読むのは禁止。
あと、アマゾン月12万

4.月に何冊本を買いますか?(文庫・漫画・雑誌は分けてカウント)
技術書数冊、ラノベ数冊。

5.では、月に何冊本を読みますか?(文庫・漫画・雑誌は分けてカウント)
ラノベは10冊以下だけど、これはペースを押さえているから。技術書は、平均すると月1冊くらいかな。

6.1冊の本を入手するために、最大で何軒の本屋をハシゴしましたたか?
Amazonで入手できなかったらあきらめる。

7.同じく1日何軒まで、本屋のハシゴをしたことがありますか?
四軒くらいはいったと思う。

8.おおよその蔵書数を教えてください。ダンボール単位でもいいから、とにかく概算を。無理でも何でも出すように。
500冊くらい。

9.本棚から本はあふれてますか? その場合、なにか工夫をしていますか?
あふれたら無理矢理押し込む。今一番上は、LispとかAIの本が並んでいるので、地震が来たら死ぬ。

10.読む当てもないのに、つい本を買ってしまった経験は?
いっぱい。

11.辞書を頭から読んでしまう行為について述べよ。
意味があるとは思わない。百科事典なら有り。

12.積読状態の本は何冊ありますか?
200冊くらい

13.既に自分でも持っている本を忘れて、ついだぶって本を買ったりしませんか?
年に数冊

14.あなたの立ち読みっぷりを教えてください。
新書だと普通に読み切る。速読とかじゃなくて、ただの斜め読み。読んだ後、満足すれば買う。

15.本屋(図書館)に行かないと何日で禁断症状が発生し、精神の均衡を保てる限界が何日で来ますか?
3ヶ月くらいは大丈夫だと思う。本屋に行く=アマゾンへのアクセスなら、5日が限度。

16.本屋での平均滞在時間と最大滞在時間は?
平均滞在時間は1時間くらい。最大滞在時間は4時間くらい。

17.TVと本。二者択一でとるならどっち?
本。

18.同じ本を意識的に複数冊買うことは、ありますか? 何冊買いますか? その場合、用途は?(例:愛読用、愛蔵用、布教用)
あきらかにパソコンに向かわないと意味がない本(ハッカーのたのしみとか)は、自宅用、会社用に2冊買います。
昔はアルゴリズムの本も2冊確保していたのですが、最近はgooleのおかげでそれほど出番がない。

19.死ぬほど読みたい定価500円の本があったとします。プレミア価格になっていたとしたら、いくらまでなら出せますか?
2万くらい。

20.電車の中で読んでるとき、読み続けていたいが為に降りる駅で降りないことがありますか? 降りた場合、駅構内のベンチで読み切ったことがありますか?
時々あります。ベンチ読み切りは普通。

21.日々の生活費用と本代。優先すべきは……。
生活費用だとわかってはいるのですが、本代に消えていく。

22.本を読んでどこに萌えますか?(ストーリー重視、妄想全開、キャラクター萌え、台詞重視等)
ラノベならキャラ

23.風呂など、家の中の変わった場所で本を読んだりしますか? 具体的な場所も教えてください。
特にない。風呂でもトイレでも読みます。読みながら家に帰ってきたら、玄関で靴も脱がずに立ったまま読み続けたこともある。

24.旅行先や外出先、知らない土地で本屋を見かけたときの行動は?
最近はあまり入らなくなりました。

25.既に読んだタイトルの新装版が出ました。あとがきが増えた、ちょっと加筆、大幅加筆の3パターンに分けて、その後の行動を教えてください。
立ち読みして判断。

26.あなたは学校の図書館に、伝説を残しましたか?
特になし

27.「R.O.D」を知っていますか? 知っていたら一言感想を。
読子は俺の嫁。

28.あなたには、面白い本のオーラを感じる能力や、面白い本を見つけるための嗅覚があると思いますか?
特にないです。他人のblogの書評で買うことがほとんど。

29.貴方の大切な本が雨(水でも可)に濡れてしまった場合、貴方はどうしますか?
特に気にしない。

30.同じ本の最大読み返し回数と、そのタイトルを教えてください。
ロードオブザリングスが3回。新しい訳の方が読みやすいけど、粥村は譲れない。

31.気がつくと会話が妙に書き言葉になってませんか?
それはない。

32.あなたに対する罰で、踏絵ならぬ「踏本」を強要されたら、耐えられますか?
全然OK。

33.読む本が何もないときの、代替行動について述べよ。
Tungstenで2chのログを読む。それでも駄目なら、妄想の世界に入る。

34.読んで数ページで地雷な本の予感が漂ってますが……あなたはそれでも最後まで読み続けますか?
恐ろしいくらいの地雷ならネタになるので最後まで読む。

35.地雷な本を読了した後のあなたの一言と行動は?
2chへGO!

36.特異ジャンルの本を買うときに抵抗感はありますか?(例:男だけどコバルト文庫買う……etc)
何かあった気がするけど忘れた。

37.最長連続読書時間を教えてください(食事はOK)
食事OKなら6時間くらいはいけると思う。人狼城はそんな勢いで読んだ。

38.外へ出かける時、何冊の本を持って外に出ますか?
3~4冊。ラノベ、技術書、日本語、英語、バランス良く。

39.図書館で軟禁生活を一ヶ月間送るはめになりました。一ヵ月後のあなたの状態は?
中国史に詳しくなっていると思う。

40.本を買うかどうか、表紙絵で判断することがありますか?
ラノベは絵が命。

41.読書感想文に「まともでない」タイトルを選びましたね?
特になし。

42.分厚い本を目にしたときのあなたの心理状態と行動を述べよ。
買う。僕の経験から、分厚い本は良い本が多い。パタヘネ、ヘネパタ、MINIX、SICP、コードコンプリート。言語の本で迷ったら分厚い方を買った方がよい。

43.活字中毒者のあなたにとって、天敵とは何(もしくは誰)でしょう?
腰痛

44.書評を信じますか?
雑誌の書評コーナーは信じない。Blogの書評は信じる。Amazon.comは信じる。Amazon.co.jpは参考程度。

45.本を読み終えたあと襲ってくる妄想はどうやって処理しますか?
増幅させて、妄想の世界に入ります。

46.電車の中などで読むときページを片手めくりで読み(め)ますか?
できません。

47.「本屋で買って読む」「古本屋で買って読む」「図書館で借りて読む」「知り合いから借りて読む」「知り合いに無理やり買わせて読む」のうち、どれが最も多いですか?
Amazonで買って読む

48.街でみかけた、活字中毒者についてレポートして下さい。また、あなたは、どうして、その人が活字中毒者だと思いましたか?
特にない。

49.活字中毒になって得たものと失ったものは何ですか?
もともと活字中毒だからよく分からない。趣味としては、そこそこお金かかると思う。

50.あなたから本をとってもいいですか?
勘弁してください。

さっそく、驚異の百科事典男 世界一頭のいい人間になる! (文庫)をアマゾンのカートに入れた。

| | Comments (0) | TrackBack (1)

2007.09.17

SICP 4.4.4.2 The Evaluator Simple queries

一つでもわかると、そこが取っかかりになってなんとか追えるようになってきた。

データベースの初期化ができていそうなので、Simple queryに挑戦。
(job ?x (computer programmer)


入力されたqueryは、?が分解される。

(query-syntax-process '(job ?x (computer programmer)))
=> (job (? x) (computer programmer))

これを忘れていて、迷宮にさまよい込んでしまった。

streamも少し修正して、ここまで動いた。

;;; Query input:
(job ?x (computer wizard))
;;; Query results:
(job (Bitdiddle Ben) (computer wizard))

;;; Query input:
(salary (Bitdiddle Ben) ?x)
;;; Query results:
(salary (Bitdiddle Ben) 60000)


2つめ以降の問い合わせができていない。
;;; Query input:
(job ?x (computer programmer))
;;; Query results:

とりあえず、効率を犠牲にして、fetch-assertionsを全てのassertionを返す事で対応した。
(define (fetch-assertions pattern frame)
 (get-all-assertions))

;;; Query input:
(job ?x (computer wizard))
;;; Query results:
(job (Bitdiddle Ben) (computer wizard))

;;; Query input:
(salary (Bitdiddle Ben) ?x)
;;; Query results:
(salary (Bitdiddle Ben) 60000)

;;; Query input:
(job ?x (computer programmer))
;;; Query results:
(job (Fect Cy D) (computer programmer))
(job (Hacker Alyssa P) (computer programmer))

;;; Query input:

ktkr!


Exercise 4.55.
a. all people supervised by Ben Bitdiddle;
(supervisor ?x (Bitdiddle Ben))

;;; Query results:
(supervisor (Tweakit Lem E) (Bitdiddle Ben))
(supervisor (Fect Cy D) (Bitdiddle Ben))
(supervisor (Hacker Alyssa P) (Bitdiddle Ben))

b. the names and jobs of all people in the accounting division;
(job ?x (accounting . ?y))
;;; Query results:
(job (Cratchet Robert) (accounting scrivener))
(job (Scrooge Eben) (accounting chief accountant))

c. the names and addresses of all people who live in Slumerville.
(address ?x (Slumerville ?y ?z))
;;; Query results:
(address (Aull DeWitt) (Slumerville (Onion Square) 5))
(address (Reasoner Louis) (Slumerville (Pine Tree Road) 80))
(address (Bitdiddle Ben) (Slumerville (Ridge Road) 10))


ここまで動くソースはここ
put-get.scmは拾い物ですが、どこから入手したのかすっかり忘れてしまったので、as-isで配布します。

| | Comments (1) | TrackBack (0)

SICP 4.4.4.5 Maintaining the Data Base

一つ分かった。

assertionとruleはそれぞれ、グローバル変数のTHE-ASSERTIONSとTHE-RULESにstreamとして保存される。
両方ともdriver-loopから(assert! ・・・・)で追加できる。

データベースを初期化するには、こんな感じでassertionとruleのリストを作る。

(define microshaft-data-base
'((address (Bitdiddle Ben) (Slumerville (Ridge Road) 10))
 (job (Bitdiddle Ben) (computer wizard))
 (salary (Bitdiddle Ben) 60000)

 (address (Hacker Alyssa P) (Cambridge (Mass Ave) 78))

省略

 (can-do-job (computer wizard) (computer programmer))
 (can-do-job (computer wizard) (computer technician))

省略

 (rule (wheel ?person)
  (and (supervisor ?middle-manager ?person)
   (supervisor ?x ?middle-manager)))

 (rule (outranked-by ?staff-person ?boss)
  (or (supervisor ?staff-person ?boss)
   (and (supervisor ?staff-person ?middle-manager)
      (outranked-by ?middle-manager ?boss))))
))

このリストを、add-rule-or-assertionに順に渡せばOK。

(define (initial-database)
 (map add-rule-or-assertion! microshaft-data-base))

(initial-database)

上手くassertionが入っているかの確認は、THE-ASSERTIONSを順に評価すればよい。

gosh> THE-ASSERTIONS
((can-do-job (administration secretary) (administration big wheel)) . #)
gosh> ((cdr THE-ASSERTIONS))
((can-do-job (computer programmer) (computer programmer trainee)) . #)
gosh>

initial-databaseで登録したassertionが、おしりから順に取り出せる。ruleも同じ。

Exercise 4.70
add-assertion!で、streamをいったんletでold-assertionsに束縛するのはなぜか?

(add-assertion! '(can-do-job (computer wizard) (computer technician)))
(add-assertion! '(can-do-job (computer wizard) (computer technician)))

みたいに、同じassertionを2回追加すると、順にストリームから取り出せなくなる。

| | Comments (1) | TrackBack (0)

はてなメモ

・naoyaさんは僕より年下。メディアでの発言を見ていて絶対に年上だと思っていた。僕の精神年齢低すぎ。

・Monaを訴えてもはてなポイントしかもらえない。はてな住民で無い僕には使い道がない。

・はてなの入社時にはゲームをすると聞いたけど、ひげぽんさんはどんなゲームだったのだろうか。吸血麻雀?

・はてなは京都にない。(←これが一番衝撃の事実)

| | Comments (0) | TrackBack (0)

今日の日記

勉強に使える時間が確保できるのもあと少し。SICP4章までは終わらせたい。一応本文は全部読んだから、自分が終わりって言えば終わりだけど。がんばろう。

なんでVerilogをはじめよう!を書き始めたのか自分でも分からない。僕が何か書かないといけないと思った。「これはやばいって時に、VHDLやVerilogは何もしてくれませんでした。」この言い回しが、自分でも酷すぎると思った。Verilogも面白いよ。

仕事フラグが一つ立った。Verilogをはじめよう!は、優先度低め。

タバサと一緒にSICPを勉強する夢を見た。

絵本を出しっぱなしにして怒られたときに、「これは勉強しているの。遊んでるんちゃうで」と言い返す娘(2才)が可愛い。どこでそんな言い回しを覚えたんだか。

| | Comments (0) | TrackBack (0)

Logic Programmingが難しい

SICP4.4

3回目なので、書いてあることはなんとなく分かったんだが、写経だけじゃ動かない。ambに比べたら、特別難しい概念ではなさそうなんだけどな。

・SICPのソース:どうやって処理系にルールを与えるのかとか、動かし方が全然分からない。Streamが出てきて、そこも上手く動いていない。ずるして正解のコード見たけど、教科書に書いていない関数がいっぱい。
・Schelogのソース:マクロが使われていてさっぱり分からない
Common Lisp入門 シンボルの操作とか構造体が出てくるので、僕の知識ではしんどい。boxモデルを見ていると、こんな難しいことやっているのか!と思う。
ANSI Common Lispこれは、分かってから読む本だと思う。

もう一歩引かないといけないな。目先のコードを追おうとすると無駄に時間ばかり過ぎていく。SICPの回答を持ってくるか、Common Lispで写経するなりすれば動く処理系は簡単に手に入るんだけど、それで良いのかって事だ。全体的にもやっとした感じ。マシン語の話にも通じるけど、どこまでやって分かった事にするのかだと思う。上にソース付きの4つの実装があるんだけど、どれも必要以上に難しくしてある気がする。つまり、大きく見落としている概念が1つ以上あるんだ。それをつかむまでは、分かったとはいえない。

The Reasoned schemerで勉強し直しが、ちょうど良いかと思ったが内容がちょっと違った。もう少し自力でがんばろう。Logic Programmingが仕事で役に立つとも思えないんだが、今を逃すと一生勉強しない気がする。

| | Comments (0) | TrackBack (0)

2007.09.14

Marissa Mayer

Marissa Mayerに萌えな人が日本では意外に少ない気がする。
HPのフィオリーナですら、モバ板では時々話題になるのに不思議。
The Google Storyの写真は普通に可愛いよ。

これをリスニングの題材にしようかと思った。
http://jp.youtube.com/watch?v=dNRE5x-V-sQ&mode=related&search=

| | Comments (0) | TrackBack (0)

Verilogをはじめよう! その2

前回は演算子が、○○器を作るという話まででした。加算器について、どのような加算器が作られるのか、いけるところまで作ってみましょう。
今日も嘘が多めです。

まずは、加算器の片方を定数にしてみましょう。これで、(define plus5 (lambda (x) (+ x 5))みたいな、わかりやすい変換を期待しています。

always @(posedge clk) begin
 if(a == b) begin
  a <= b + 5;
 end else begin
  a <= a + 10;
 end
end

コンパイルすると、5を足す加算器と、10を足す加算器がそれぞれできるはずです。

ちくしょう
なんということでしょう。最適化されて、加算器が一つになってしまいました。

つまりこういう事です。

 if(a == b) begin
  a <= b + 5;
 end else begin
  a <= a + 10;
 end

がC言語っぽい疑似コードで書くとこう最適化されました。

cond = (a == b);
tmp_a = cond ? b : a;
tmp_b = cond ? 5 : 10;
a <= tmp_a + tmp_b;

<=はレジスタへの代入、=はただの配線です。?はif文のシンタックスシュガーなので、○○器を作る演算子ではありません。結果的に、もとのコードに比べると+の演算子が一つ減っていることになります。その結果、等価な回路でも少ない加算器で実現できました。

教科書的にはリソースシェアリングという最適化です。この場合、加算器を b + 5、a + 10という2つの式でシェアしています。不意打ちだったのでびっくりしましたが、次からネタに使えるので良しとしましょう。

今日の発見
・ISEはデフォでリソースシェアリングをする。

ちなみにSynplifyはデフォでOFFです。多分。
ISEのresource sharingのオプションをoffにして、あらためてコンパイルするとこうなりました。

もう満足です。よく見ると加算器の片方の入力が、101や1010になっているのがわかります。当然、ソースの中に現れる定数、5と10の事です。+を書けば、書く度に加算器が作られます。足せば足すほど加算器です。

話は変わりますが、ifの話。
前回は四角いのがifとあっさり説明しましたが、四角の中身はこうなっています。

理系の方であれば1回くらい見たことがある図だと思います。マルチプレクサとかセレクタとか呼ばれる論理回路です。真面目な説明は例によって、http://ja.wikipedia.org/wiki/マルチプレクサへ。京大の中のページにはちゃんと2入力のマルチプレクサがあります。不真面目に説明すると、魔法使い?という信号が1ならばタバサが、0ならば長門がでてくるような回路です。一気にきもくなりました。

よくみるとマルチプレクサの入力が上から、a_addsub0001(7)、a_cmp_eq0000、a_addsub0000(7)、出力がa_mux000(7)です。セレクタのSにあたる部分に比較器の出力(a_cmp_eq0000)が接続されていています。比較器の出力とは、ソース内の(a == b)の判定結果です。A、Bにあたる部分がa_addsub0001(7)と、a_addsub0000(7)です。2つある加算器の出力から一つを選んで、a_mux000(7)を作っています。末尾の(7)はおそらく7bit目という意味ですが、コンパイラが勝手につけた中間ノードなので断言はできません。ソースははしょってますが、実は変数aは8bitです。最適化がかかっている図でも、そうでない図でもどちらでも良いのですが、もう一度図をよく見てください。マルチプレクサ(四角)が8つあるのがわかります。最終のa(8bit)を作るのに、各bitそれぞれにマルチプレクサが入っているというわけです。

if文は、C言語では条件付きジャンプ命令になりますが、HDLではマルチプレクサを生成します。C言語でif文書いても条件付きジャンプにならないことがあるように、常にマルチプレクサになるかといわれると困りますが、やっぱり困るのでこの説明で勘弁してください。こんな風に教えてくれたら、論理回路の授業ももっと楽しめたに違いありませんが、僕はそもそも論理回路or電気回路は履修していない気がします。

マルチプレクサが、andとorとnotで出来ているのも面白いです。全ての論理回路はandとorとnotで表現できます。Schemeが5つの構文(define、quote、if、set!、lambda)に還元できるように、全ての論理回路はandとorとnotに還元できます。携帯も、PS3も、パソコンも中に入っている半導体をばらしていくと、大半はandとorとnotの集まりになります。ちょっとすごい。Shiroさんお勧めの思考する機械コンピュータの前半もそういうお話でした。

andとorとnotにコンパイルされたHDLが、どのようにFPGAの中で動くのかはとても面白いのですが、今日はここまで。

| | Comments (10) | TrackBack (1)

2007.09.13

今日の日記

・あまりも当たり前過ぎて21世紀に入ってから言葉にだしたことはあまりないのですが、当然のことながら、モバイルというのは、MorphyOneを予約して初めて「モバ」と言うのです。

http://d.hatena.ne.jp/odz/20070912/1189572747#cのShiroさんのコメントから
>「抽象化の漏れ」については、物理的な制約も含めて構築物の性質がどこまで分解したら説明可能か(それ以下の層からくる性質を単なるパラメータとして扱えるか)というのがひとつの指標になるんじゃないでしょうか。同期論理回路は、その下の実装により動作周波数が限定されますが、逆に言ってしまえば下層からの影響は動作周波数だけですよね (通信とかメモリのソフトエラーまで考えるとエラー率も入ってきますが)。

メタメタになりそうな所を具体例できっちり止めているのがすごい。ハードウェア設計の大事なポイントがありそうな気がする。設計したハードウェアのI/Fを、プログラマーにどうみせるのが理想的なのかという話につながる。ビジネス的にはややこしいのはソフトウェアで処理させるが一つの正解。抽象化が漏れても、開発コストを下げる事の方が大事。その結果、抽象度を上げるために○○のドライバを書く人という新たなレイヤーが必要になってくる。自分の中でもう少し消化しよう。

メモリは凄い。EDOとか言っていたDRAMと、SDRAMと、DDRと、DDR2とか、ボードから見たI/F全然違うのに、CPUから見ると全部同じだよね。それだけじゃなくて、ボードからみたI/F全然違うのに、中身は同じDRAMってのもなんか凄い。

・あろはさんのgcc のフロントエンド作る日記から、関係の無いところに突っ込み
> # ようやく 3 年遅れで,wo さんの技術力にちょっとは追い付けたのかと思うと,いろいろ感慨深い.
その感覚ってわかりますよ。目標としている人に、少し近づいたうれしさ。僕もがんばろう。

・子供達の言い分もあるよね
> 見た瞬間にオーバーヘッドになるコードというのは解るのです。それはC++のソースを上から見ながら脳内でコンパイルしているからです。
一方、マシン語を知らない若い人たちはプロファイラを使った。
最近特に思いこみが激しい自分自身への苦言。

・ラブ
勉強して欲しかったら、マシン語を勉強する事がどれだけ楽しいかを書いた方が良い。北風と太陽。

・SICP
ロジックプログラミングの部分を読んで、写経中。さすがに3回目だから大分理解が深まった。正規表現みたいのものをイメージしていたが、そこまではいかない。最初のwordでマッチング失敗したらそこでおしまい。


・ビジネスマナー
いい加減、何かはじめる。

| | Comments (0) | TrackBack (0)

Verilogをはじめよう!

今日は、嘘、おおげさ、紛らわしいがいつもより多めです。

世の中にはHDLと呼ばれる言語があります。
まじめな説明はwikipedia http://ja.wikipedia.org/wiki/ハードウェア記述言語 をみてください。

HDLはいくつか種類があったのですが、今はAdaの血を引くVHDLと、C-likeなVerilog HDLの2つが生き残りました。HDLの特徴として、言語規格で決まっているのに、コンパイルできないという不合理があります。規格を満足するC++のコンパイラが無いとか、そんなレベルではありません。まずfor文が使えません。HDLが登場したときの初期の入門書には、これ見よがしにfor文とかが書いてあるため、調子に乗ってfor文を使うとコンパイラに怒られて涙したものです。基本的な制御構造であるforですらそうですから、後は推して知るべしです。一応whileとかuntilとか一通りの制御構造はありますが、基本的にループは使えません。

VHDLはAdaの血を引いているため、いちいち無駄に厳しいです。バイナリの"0100"を整数の4として扱うには、わざわざCONV_INTEGER()を使わないといけません。VHDLを書くような人間は、"0100"と4は同じ物として考えているのに、いちいち変換しないといけないのはとても苦痛です。最近は随分とましになったようですが、ソースの先頭にいっぱいおまじないを書かないといけないのは残っているようです。

VerilogはVHDLにくらべると随分ルーズです。僕はVerilogが好きなので、Verilogの他の言語と違うところを書いてみます。

まずはソースをみてください。

always @(posedge clk) begin
 if(a == b) begin
  a <= b * c;
 end else begin
  a <= a + b;
 end
end

C言語のようなPascalのようなそんな感じですが、1行目を除けば経験のあるプログラマならだいたい意味が分かるのではないでしょうか。aとbが同じなら、b * cをaに代入、そうでないなら a + bをaに代入します。たいして意味のあるコードではありません。

さて、ここで質問です。
このソースに出てくる演算子+は何をする演算子でしょうか?

a と bの和を求める演算子?

いいえ違います。これは、aとbのリアルな加算器(adder)を作る演算子です。HDLは演算子によって対応する回路が作られます。
上のソースをもう少し詳しく書くとこうなります。

これをコンパイル(合成)するとこうなります。

それっぽく、加算器、乗算器、比較器が作られているのがわかります。真ん中の並んでいる四角はif文で、右上のFDと書かれているのが変数aを入れるためのレジスタです。Verilogにおける演算子は、和を求めるわけでもなく、マシン語のaddに変換されるわけでもなく、前置、中置の違いはありますがλ式のような○○器を作る役割を持ちます。Paul Graham ならきっとこう言うでしょう。「加算器を生成するプログラムだって? いつそんなものが必要なんだ? そんなこと滅多にないよ、とほげプログラマは言うだろう。 いつでもさ、とVerilogプログラマは言うだろう。」

ここまで読まれた方は既に理解できていると思いますが、Verilogを使うことで想像しうるどんな命令セットでも作ることができます。
整数aとbを与えたら、1命令で和差積を同時に求めて、それぞれ別々のレジスタに入れることが出来ます。割り算もできそうですが、おそらく/はサポートされていません。試しにb * cをb / cに変えてコンパイルしてみると、こんなエラーがでます。

ERROR:Xst:870 - "../test.v" line 15: Can not simplify operator DIV.

Fuckin
割り算は難しいんですよ。Z80だって割り算が無かったでしょ。ほら、マシン語の知識はここでも役に立つ。まじめに割り算を実装したい人は、ベテランエンジニアに聞くか、パタヘネ本を読みましょう。そして、四則演算が普通にできる処理系にあらためて感謝しましょう。

乗算の結果がオーバーフローしたら全ビットが反転するような、やけくそな命令も作れます。偶数番地はライトスルー、奇数番地はライトバックのような、変態的キャッシュも頑張れば作れます。32/64bitのレジスタから解放され、RGB 10bitずつそれぞれ乗算したり、マスクしたりするような処理はよく使われますが、役に立つ回路を紹介するのはこの記事の意図するところでは無いので省略します。

省略したら書くことが無くなったので、今日はここまで。

| | Comments (0) | TrackBack (0)

2007.09.12

4.3 Variations on a Scheme -- Nondeterministic Computing

とりえあず終了。

call/cc=継続だと思っていたがちょっと違った。call/ccは、call-with-current-continuationの名の通り、今の継続と一緒に関数呼ぶぜって事だ。継続を使って元の場所に戻るとき、自分のフレームより外側の変数を戻すんだ。これはすごい。

バグが一つあってgoogleをさまよっていたら、Complete Code from SICP Second editionを見つけて、かなりへこむ。

もともと4章からがんばってSICP日記をつけていたのは、4章のコードが断片的で動かすのが難しく、Webの情報が少なかったから。少なくともこの練習問題だけは解けるってコードがあれば、次の人が勉強するときに役に立つかと思っていました。まあ、最初から最短を突っ走れば理解度も相当低いまま次に行っていたので、勉強する分には知らないで良かったと思う。ただ、勉強終わるまで存在を知らずにいたかった。忘れよう。

忘れた。
練習問題が動くソースはここ

| | Comments (0) | TrackBack (0)

C言語ラブ

shinhさんの所からいろいろ回る。

http://blog.livedoor.jp/dankogai/archives/50910559.html

のコメントから
> shi3zさんはverilogやVHDLを出さずに「論理回路」なんて表現を使っている点からして知識が浅い。
> それで大言壮語してるんだから、反論されてもしかたない。

HDL厨キターー。もっと煽れ。2chにマシン語厨とHDL厨が煽り合うスレが立つまで煽れ。スレが立ったら僕はそのスレで毎日煽り、煽られするよ。

もとはここか。こことは違うらしい。
マシン語を知らない子ども達

> 最低でも、論理回路だけで桁上がりをサポートした加算機を作れる程度の理解はしておいて欲しいと思います。
これは、マシン語とかそういうレベルでなくても簡単に理解できるし、それで理解できれば十分じゃないかと。
sum = a ^ b ^ cin;
cout = (a & b) | (a & cin) | (b & cin);
これの&とか| を絵で描いただけ。たんなる論理演算です。

むしろフリップフロップを使って4bitでいいからカウンター作って欲しい。
教科書的に言うと順序回路の方。これを作れば、CPUの動作周波数の概念も分かるし、パイプラインが必要な理由も分かる。
CPUのオーバークロックで何が起こるかもよく分かると思う。それ以上は興味持ったらどうぞ、の世界。
教科書はいうまでもなくCPUの創りかたが最適。

> マシン語はプログラミングの深淵であり、母であり、基礎です。すぐに理解できなくても、それを理
> しているのとしていないのとでは大きな差があると思います。
マシン語をLispに置き換えても違和感がないのがいい。結局心のよりどころか。

僕はCとPerlがラブです。(いきなり告白!)
Cはアセンブラとの合わせ技で小さいマイコンなら俺様デバッガくらいまで作れますが、Perlはサブルーチンを作った事がありません。変数に$が必要なC言語の方言だと思っています。
ラブな理由は一つで、仕事をしていてこのままでやばいって時にCとPerlはいつも僕を助けてくれました。CとPerlが無ければ、「やばい」から「駄目だ」になっていたことは間違いありません。RTOSの仕事をしていて通信物のライブラリを2種類使うことがあり、どちらも「この処理をしているときは割り込みは禁止にしてください」という混ぜたら危険状態を上手く乗り越えたのはCのおかげです。1万行近いOrCADネットリストから必要な情報だけをきっちり抜き出して、並び替え、なんとか出図が間に合ったのはPerlのおかげです。これはやばいって時に、VHDLやVerilogは何もしてくれませんでした。

組み込みの仕事をしていたときは、CPUをブートさせ、ICEをつなぎ、割り込みを入れ、メモリのテストを行い、コンパイラ、リンカの設定を終え、環境を構築するまでが仕事だと思っていました。各初期化が終わり、いわゆるmainへ処理が飛んでデバッガが普通に動けば、そこから先はC言語の世界だからなんとでもなるという信頼感がありました。ShiroさんやPaul Grahamは、それがLispなんだろうな。ShiroさんのLispラブは、Lisp:よくある正解にいっぱい、Perlラブは、僕やはてながPerlを選ぶ理由とか、どっちの文章も好きで何回もよんでます。Shinhさんは、コードが短くなるからバイナリ好きなんだ。なんという偏愛。

結局shi3zさんは、マシン語ラブなわけですよ。困ったときに386マシン語の知識が助けてくれた。それだけだと思う。R3000とかSH4が出てくるから、もともと組み込みに近いところで活躍していたのではないかと。組み込みエンジニアならマシン語うんぬんは100%正しい。「××が分からないと駄目」というのは、リアルで言われたら引くかもしれないけど、Web上ではどんどん言って欲しい。ある人が、どんなに言語ラブか、その言語で熱くなれるかってのはいっぱい知りたい。煽り、煽られでいいじゃない。ハッカーと画家なんかLispラブ以外の何物でもないし、そのLispへのラブでSICP読み始めた人間がここにいる。Lisp面白いよ、Lisp。

神様なんて信じない僕らのために
> だから、
> 好きな事を好きなだけやれば良いんじゃない?
結局これかな。

最後にこんなの見つけた!
オシロスコープを知らない子供たち
マルツでふいた。

トラ技はともかく、もう一回くらいファインマン読みたいな。

| | Comments (1) | TrackBack (0)

良い翻訳本

神様なんて信じない僕らのためにと、ときどきの雑記帖 リターンズから。

原書と翻訳を両方最後まで読んだ本は確かに少ないです。Effective C++、達人プログラマー、熊とワルツくらいか。

Effective C++と達人プログラマーは、プログラマとしての自分が翻訳がどうこうってレベルじゃないから何とも言えない。

熊とワルツは正直難しい英語だった。比喩が多いし、Cプログラマーが考えるような話はほとんど無い。これは日本語で読んだほうが圧倒的にわかりやすかった。
参考http://natu.txt-nifty.com/natsutan/2004/06/post_1.html
全体的にデマルコとかワインバーグの本は丁寧な良い翻訳が多いと感じます。

SICPは翻訳駄目。訳者じゃなくて、西田さんのいうところの、日本語翻訳の限界がそのまま出ている。
参考http://natu.txt-nifty.com/natsutan/2007/09/sicp_41_the_met.html

原書は読んでいないけど、素晴らしい翻訳だと思うのはデマルコ系以外では、ハッカーと画家、Joel on Software、エキスパートCプログラミングくらいかな。どれも、ジョークとか皮肉が入っているから、その辺りを汲んで翻訳されているのがとても助かりました。

通読にこだわらなければ、私の一番のお勧めはパタヘネ本

コンピュータの構成と設計(上)
コンピュータの構成と設計(下)
Computer Organization and Design: The Hardware/Software Interface

章ごとに独立しているので、キャッシュの章だけ読むとか可能です。ただ、神様なんて信じない僕らのためにの中の人は既読の可能性が高い。

| | Comments (0) | TrackBack (0)

2007.09.11

4.3 Variations on a Scheme -- Nondeterministic Computing

(amb 1 2 3)がやっていること

driver-loop

ambeval

analyze exp

analyze-amb
 ↓
 amb-choices でambの引数が変わる
 ↓
 cprocsには、ambの引数を返す手続きが入る。1を返す手続き、2を返す手続き、3を返す手続き。
 ↓
 analyze-ambは、cprocの先頭を評価して、trueならsucceedを実行し、falseなら次の引数を評価する関数を返す。次が無い場合、(null? cproc)、failを実行する。failとsucceedは、引数として与えられる。

ambevalに戻って、analyzeで戻ってきた手続きを実行する。((analyze exp) env succeed fail))
driver-loopの場合、それぞれ成功した場合、失敗した場合のメッセージを表示している。

教科書読まずに想像だけど、この手続きが状態を保持しているのね。所々に、continuationという文字が出ている。継続のpureな姿がここにありそうだ。

(list (amb 1 2 3) (amb 'a 'b))の場合、analyzeされると、1 2 3を作る手続きと、'a 'bを作る手続きの両方が式全体のanalyzeの結果として保存され、順に呼び出される。なるほど。だから、新しくトップレベルでamb式を使うと、driver-loopが持っている手続きが新しい手続きで上書きされてしまう。結果的に次の問題に行くけど、前回の問題の結果は消えてしまう。

写経して、letのanalyze手続きを加えると、prime-sum-pair動いた。
(define (analyze-let exp)
(analyze (let->combination exp)))

分かったこと
・requireの無いambはただの総当たりジェネレータ。
・処理系を作るって事は、与えられた問題の一般解とユーザーインターフェイスを作るって事

| | Comments (0) | TrackBack (0)

2007.09.10

SICP 4.1.7 Separating Syntactic Analysis from Execution

先にanalyzeして効率を良くする話。トレードオフでデバッグのしやすさという大事なものを失った。

Exercise 4.22

letは手続きの生成、呼び出しのシンタックスシュガー。let->combinationでletを手続き呼び出しに変えた後は、教科書に載っている範囲で処理できるから、そのままanalyzeに渡せる。

(define (analyze exp)
 (cond ((self-evaluating? exp)
     (analyze-self-evaluating exp))
    ((quoted? exp) (analyze-quoted exp))
    ((variable? exp) (analyze-variable exp))
    ((assignment? exp) (analyze-vairable exp))
    ((definition? exp) (analyze-definition exp))
    ((if? exp) (analyze-if exp))
    ((let? exp) (analyze-let exp)) ; 追加
    ((lambda? exp) (analyze-lambda exp))
    ((begin? exp) (analyze-sequence (begin-actions exp)))
    ((cond? exp) (analyze (cond->if exp)))
    ((application? exp) (analyze-application exp))
    (else
     (error "Unkown expression type nyo ANALYZE" exp))))

(define (analyze-let exp)
 (let ((proc (analyze (let->combination exp))))
  (lambda (env)
   (proc env))))

でOK。condも同じでいけそうだ。
ambへ再挑戦。

ソースはここ

| | Comments (0) | TrackBack (0)

今日の日記

・Three Implementation Models for Scheme by R. Kent Dybvig
ひげぽんさんから。
まだまだそんなレベルじゃないけど、忘れないようにしよう。
yamanetoshiさんも発見。
本当に同じ所だ。参考になります。情報ありがとうございます。

・アマゾンからの贈り物
Object-Oriented Programming in Common Lisp
The Art of Prolog, Second Edition: Advanced Programming Techniques
Advanced FPGA Design: Architecture, Implementation, and Optimization

の三冊が届いた。Prologの本、注文した記憶ねー。品川って書いてなんの本かと
思ったよ。どこかで「買える時に買え!」と保護本能が働いたか、あろはさんの
スタンド(遠隔操作型)が注文したにちがいない。アマゾンに費やすお金が、12万
→6万→3万とさがり、今のところ3万円/月をキープしている。すばらしい。

・財布のひもを締める
今月の刀語、ROD 6巻、ゼロの使い魔10巻と読んで、ちょっとラノベにお金使い
すぎな気もしてきた。Prologの本一冊でラノベどれくらい買えるのかを考えたら、
やっぱり気のせいだったと再確認。技術書を押さえて、ラノベを買おう。そうし
よう。

| | Comments (0) | TrackBack (0)

子育てに思うこと

えっとここはSystemCと子育てを愛するパパの為のブロクです。

産婦人科のニュースをWebでちょこちょこと見て思ったこと。娘の出産の時は、それなりに安心して生める環境が残っていて欲しい。2chで、そもそも「たらい」が何かわからない人がいてちょっと驚く。こういう事件/事故の度に確認するのは ここ
http://d.hatena.ne.jp/Yosyan/

娘を育ててから虐待のニュースを見る目が変わった。4才とかそういう年齢の子が虐待されて死亡したときに、今までだったら「親も○ね!」とか普通に思っていたわけですよ。ところが自分が育てる立場になったら、少し考えが変わった。どういう育てられ方をしたのかは別にしても、それでも4年間育てたんだよな、と思うようになった。僕はたった2年しか子育てをしていない。虐待をした親に対しての怒りよりも、虐待が子供に向いてしまった状況をとても悲しく思うようになった。何ができるわけでもないけど。

| | Comments (0) | TrackBack (0)

娘はツンデレ☆

最近の娘はどうも意地悪を覚えたようで、僕がトイレに行こうとすると「お父さんダメ」と言って先に入ってしまう。
娘「か~わって、言うて」
父「か~わって」
娘「もっと大きな声で」
父「か~わって」
娘「いやや~」
最後の「いやや~」が満面の笑みで可愛くてしょうがないわけですよ。「お父さんは、お箸つこたらダメ」「お父さんは、一人でお留守番しとき」とお父さんに意地悪を言うのが楽しくてしょうがないみたい。

夜寝るときは、オバケが怖いらしく「お父さん、手握って」と小さい手で僕の手を握ってくる。あまりの可愛さに顔をのぞき込むと、「お父さん、嫌!あっちいって!べっ!」と言って、僕を蹴ったり、唾を吐きかけたり、泣き出したりする。そんなに怒っているのに手だけは離さない娘が大好きだったりする。立派なツンデレです。

| | Comments (0) | TrackBack (0)

2007.09.09

SICP 4.3の前に・・

写経して(amb 1 2 3)としたときに1、try-againで順に2, 3と動くところまで来た。
例題を解こうとすると、letが動かない。ていうか、analyze関連が何をしているのか分からない。4.1.7を飛ばしたのが悪かった。

4.1.7 Separating Syntactic Analysis from Executionに戻るよ。blogに書き続けないと絶対に挫折する。

| | Comments (0) | TrackBack (0)

SICP 4.2 Variations on Scheme --- Lazy Evaluation

SICP 4.2 Variations on Scheme --- Lazy Evaluation

結局、named-let以降の問題は飛ばしてしまった。必要なときに戻ろう。let周辺が動けば、4章最後までいけるはず。

lazyに評価される必要があるものは、thunksと呼ばれるobjectに入れる。thunkを評価する事はforcingと呼ばれる。

Exercise 4.27
呼び出される度にcountの値が1増える。
(define count 0)
(define (id x)
 (set! count (+ count 1))
 x)

gaucheだと(define w (id (id 10)))の時点で、idが2回評価されて、countが2になる。wを評価しても、countは2のまま。そして、俺様処理系だと、(define w (id (id 10)))の時点で0。wを評価すると無限ループでエラーになった。ちくしょう。

今気がついたこと。
EmacsでSICPのdriver-loopをgaucheを使って動かす。

;;; L-Eval input;

この状態で、俺様処理系で評価したい式をC-cC-eで、gaucheとかと同じように評価できる!もっと早く気がつけば良かった。ついでに、the-global-environmentの綴りがgrobalになっていた。死にたい。

普通にset!動いてない。set!なおしたら動くようになった。

遅延評価というか、この処理系だと評価を一回したらevaluated-thunkになっちゃうから何回呼ばれても1回しか評価されない。だから、wを評価した時点でcountが1になる。

exercise 4.29
とりあえず、この3行をコメントアウトでmemoizationをしない

(define (force-it obj)
 (cond ((thunk? obj)
     (let ((result (actual-value
            (thunk-exp obj)
            (thunk-env obj))))
;      (set-car! obj 'evaluated-thunk)
;      (set-car! (cdr obj) result)
;      (set-cdr! (cdr obj) '())
      result))
    ((evaluated-thunk? obj)
     (thunk-value obj))
    (else obj)))

exercise 4.30以降はパス。

ソースはここ

| | Comments (0) | TrackBack (0)

SICP 4.1.3 Evaluator Data Structure

だんだん、のんびりとSICP勉強できる雰囲気じゃ無くなってきた。全力で4章を終わらせよう。

このあたりは動いているから、じっくり読むだけ。手続き呼んだり、ローカル変数を束縛する度に、フレームが拡張されるのは富豪的な気がする。なんていうか、自分で作ったプロンプト使いにくいよね。

Minix本に、コンソールの処理は本質的じゃないけど面倒だぜ、みたいな事が書いてあったのを思い出す。タネンバウム先生は、こんな口調じゃ無いけど。

Exercise 4.11、4.12、4.13はパス。回答を求めてgoogleで来た人ごめんなさい。先読んでいって、unboundが必要になれば戻ってくる。

4.1.4 Running the Evaluator as a Program
Exercise 4.14 mapが必要になれば戻ってくる。

4.1.5 Data as Program
S式で書かれたプログラムをan abstract machineじゃなくて、FPGAで動くreal machineにしたいな。

Exercise 4.15 ぱっと考えると(try try)が意味のある何かを返すのは無理そうな気がする。測定器を測定したいなら、別の測定器が必要。なんだけど、わざわざ問題にしてあるのはMITの連中は普通にhaltedを返せるのかもしれない。

| | Comments (0) | TrackBack (0)

SICP 4.1.2 Representing Expressins その4 Let*とnamed let

効率を上げるために、開発環境をcygwinのEmacsからMeadowに変更。これで、日本語打ちながら動作確認できる。

Exercise 4.7 Let*の問題

まずは四則演算を処理系に追加しないと、動作確認できない。

(define primitive-procedures
 (list (list 'car car)
    (list 'cdr cdr)
    (list 'cons cons)
    (list 'null? null?)
    (list '+ +) ;追加
    (list '- -) ;追加
    (list '* *) ;追加
    (list '/ /) ;追加
    (list '= =) ;追加
    ))

(let*->nested-lets '(let* ((x 3) (y (+ x 2)) (z (+ x y 5))) (* x z)))の結果がこうなるはず。

(let ((x 3))
 (let ((y (+ x 2)))
  (let ((z (+ x y 5)))
   (* x z))))

たた単に、letをネストさせれば終わりなんだが、letのネスト作るの難しい。♪consをしても、listをしても、つくれーないよ。letのネスト 思った以上に強敵

いろいろやってできた。
(define (let*? exp) (tagged-list? exp 'let*))
(define (let*-make-lets vlist body)
 (if (null? vlist)
   (car body)
   (list 'let (cons (car vlist) '())(let*-make-lets (cdr vlist) body))))
(define (let*->nested-lets exp)
 (let ((vlist (let-vlist exp)) (body (let-body exp)))
  (let*-make-lets vlist body)))

だんだんきもくなってきたので、let-oをletに戻す。+の引数が3個で変数が入ったとき計算結果がおかしいがスルー。

(let* ((x 3) (y (+ x 2)) (z (+ x y 5))) (* x z))
(eval-o '(let* ((x 3) (y (+ x 2)) (z (+ x (+ y 5)))) (* x z)) the-grobal-environment)
gosh> 39
OK!

exercise 4.8 named letの問題

(define (fib n)
 (let fib-iter ((a 1) (b 0) (count n))
  (if (= count 0)
    b
    (fib-iter (+ a b) a (- count 1)))))

をこれに変えれば良い。
(define (fib n)
 (let ((a 1) (b 0) (count n))
  (define (fib-iter a b count)
   (if (= count 0)
     b
     (fib-iter (+ a b) a (- count 1))))
  (fib-iter a b count)))

追加、変更はここ
(define (let->combination exp)
 (if (named-let? exp)
   ;; named let
   (let ((vlist (named-let-vlist exp))
      (proc-name (named-let-procname exp))
      (body (named-let-body exp)))
    (list 'let
       vlist
       (named-let-make-lambda proc-name vlist body)
       (named-let-make-call proc-name vlist)))
   ;;normal let
   (let ((vlist (let-vlist exp)))
    (let-make-combination
     (make-lambda (let-make-arg vlist) (let-body exp))
     (let-make-parameter vlist)))))
(define (named-let-make-call proc-name vlist)
 (cons proc-name (map car vlist)))
(define (named-let-make-lambda proc-name vlist body)
 (list 'define (cons proc-name (map car vlist)) body))
(define (named-let? exp)
 (symbol? (car (cdr exp))))
(define (named-let-procname exp)
 (car (cdr exp)))
(define (named-let-vlist exp)
 (car (cdr (cdr exp))))
(define (named-let-body exp)
 (car (cdr (cdr (cdr exp)))))


(eval-o '(define (fib n)
 (let fib-iter ((a 1) (b 0) (count n))
  (if (= count 0)
    b
    (fib-iter (+ a b) a (- count 1))))) the-grobal-environment)

(eval-o '(fib 10) the-grobal-environment)
で55返って来た。ワショーイ

Exercise 4.9とExercise 4.10はパス。

ひげぽんさんの所から
関数型言語の勉強にSICPを読もう - (65) 4章 - 超言語的抽象(222ページ) C++でSchemeインタプリタを作ろう14も意味が分かるようになっている。

shiro >その答えは、Schemerにとってローカル変数は関数呼出しのシンタックスシュガーにすぎないからです。

納得。

ここまで動くソースはここ


| | Comments (0) | TrackBack (0)

2007.09.07

SICP 4.1.2 Representing Expressins その3 condとlet

exercise 4.5
またassocとか俺様処理系で動かない手続きを使っている。もう少し教育的配慮が欲しかったりする。そのままif文で置き換えるとよさげ。(test => recipient)を(if test (recipient test))とするとtestが2回評価される。letで一回代入しないと。letの実装は次の問題だからそちらから先に解く。

exercise 4.6.

こんな変換が必要
(let-o ((a 5) (b 10))
 (cons a b))
((lambda (a b) (cons a b)) 5 10)

letは例によって俺様letのlet-oに置き換え
(let->combination '(let-o ((a 5) (b 10)) (cons a b)))

gosh> ((lambda (a b) (cons a b)) 5 10)
を返すことを確認。

(define the-grobal-environment (setup-environment))
(eval-o '(define consr
      (lambda (x y)
       (let-o ((a x) (b y))
        (cons b a)))) the-grobal-environment)
(eval-o '(consr 1 2) the-grobal-environment)
引数が逆になるconsrを、let-oを使って定義
gosh> (2 . 1)
ちゃんと、(2 . 1)返したぜ。そろそろcar, cdr, cons, null?以外にもprimitiveが欲しい。

(define (let? exp) (tagged-list? exp 'let-o))
(define (let-vlist exp) (car (cdr exp)))
(define (let-body exp) (cdr (cdr exp)))
(define (let-make-arg vlist)
 (map car vlist))
(define (let-make-parameter vlist)
 (map cadr vlist))
(define (let-make-combination lambda-expression parameters)
 (cons lambda-expression parameters))

(define (let->combination exp)
 (let ((vlist (let-vlist exp)))
  (let-make-combination
   (make-lambda (let-make-arg vlist) (let-body exp))
   (let-make-parameter vlist))))
あんまり綺麗にかけないけど、これで動いた。

~~~~~~~~~~~~~~~~~~~~~~~~~~

続いて、exercise 4.5に戻ろう
(test => recipient)

(let ((result test)) (if result (recipient result))

に変換すればよい。if文が上手くネストして、letの重複問題をクリアーできてる。


(define (cond-extend? first)
 (eq? (car (cdr first)) '=>))
(define (cond-extend-test first)
 (car first))
(define (cond-extend-reci first)
 (car (cdr (cdr first))))
(define (cond-extend-make-let test)
 (cons (list 'result test) '()))
(define (cond-extend-make-reci recipient)
 (list recipient 'result))

(define (cond-make-extend first rest)
 (let ((test (cond-extend-test first))
    (recipient (cond-extend-reci first)))
  (list 'let-o
     (cond-extend-make-let test)
     (make-if 'result
          (cond-extend-make-reci recipient)
          (expand-clauses rest)))))
(define (expand-clauses clauses)
 (if (null? clauses)
   'false
   (let ((first (car clauses))
      (rest (cdr clauses)))
    (if (cond-else-clause? first)
      (if (null? rest)
        (sequence->exp (cond-actions first))
        (error "Else caluse isn't last nyo - COND-IF" clauses))
      (if (cond-extend? first)
        (cond-make-extend first rest)
        (make-if (cond-predicate first)
             (sequence->exp (cond-actions first))
             (expand-clauses rest)))))))


試行錯誤してgdgdだけど、これで動いた。

 
(cond->if '(cond ((assoc 'b '((a 1) (b 2))) => cadr)
   (else false)))

gosh> (let-o ((result (assoc 'b '((a 1) (b 2))))) (if result (cadr result) false))
おお、良い感じ


goshで(cond ((null? 'a) => car) ((cdr '((a b) (c d))) => car) (else 'false))を評価して、(c d)が返るのを確認した後、

(eval-o '(cond ((null? 'a) => car) ((cdr '((a b) (c d))) => car) (else 'false)) the-grobal-environment)
とやって、(c d)が返ることを確認。

ソースはここ

| | Comments (2) | TrackBack (1)

SICP 4.1.2 Representing Expressins その2

SICP 4.1.2 Representing Expressins その3 condとlet

exercise 4.5
またassocとか、俺様処理系で動かない手続きを使っている。もう少し教育的配慮が欲しかったりする。そのままif文で置き換えるとよさげ。(test => recipient)を(if test (recipient test))とするとtestが2回評価される。letで一回代入しないと。letの実装は次の問題だからそちらから先に解く。

exercise 4.6.

こんな変換が必要
(let-o ((a 5) (b 10))
 (cons a b))
((lambda (a b) (cons a b)) 5 10)

letは例によって俺様letのlet-oに置き換え
(let->combination '(let-o ((a 5) (b 10)) (cons a b)))

gosh> ((lambda (a b) (cons a b)) 5 10)
を返すことを確認。

(define the-grobal-environment (setup-environment))
(eval-o '(define consr
      (lambda (x y)
       (let-o ((a x) (b y))
        (cons b a)))) the-grobal-environment)
(eval-o '(consr 1 2) the-grobal-environment)
引数が逆になるconsrを、let-oを使って定義
gosh> (2 . 1)
ちゃんと、(2 . 1)返したぜ。そろそろcar, cdr, cons, null?以外にもprimitiveが欲しい。

(define (let? exp) (tagged-list? exp 'let-o))
(define (let-vlist exp) (car (cdr exp)))
(define (let-body exp) (cdr (cdr exp)))
(define (let-make-arg vlist)
 (map car vlist))
(define (let-make-parameter vlist)
 (map cadr vlist))
(define (let-make-combination lambda-expression parameters)
 (cons lambda-expression parameters))

(define (let->combination exp)
 (let ((vlist (let-vlist exp)))
  (let-make-combination
   (make-lambda (let-make-arg vlist) (let-body exp))
   (let-make-parameter vlist))))
あんまり綺麗にかけないけど、これで動いた。

~~~~~~~~~~~~~~~~~~~~~~~~~~

続いて、exercise 4.5に戻ろう
(test => recipient)

(let ((result test)) (if result (recipient result))

に変換すればよい。if文が上手くネストして、letの重複問題をクリアーできてる。


(define (cond-extend? first)
 (eq? (car (cdr first)) '=>))
(define (cond-extend-test first)
 (car first))
(define (cond-extend-reci first)
 (car (cdr (cdr first))))
(define (cond-extend-make-let test)
 (cons (list 'result test) '()))
(define (cond-extend-make-reci recipient)
 (list recipient 'result))

(define (cond-make-extend first rest)
 (let ((test (cond-extend-test first))
    (recipient (cond-extend-reci first)))
  (list 'let-o
     (cond-extend-make-let test)
     (make-if 'result
          (cond-extend-make-reci recipient)
          (expand-clauses rest)))))
(define (expand-clauses clauses)
 (if (null? clauses)
   'false
   (let ((first (car clauses))
      (rest (cdr clauses)))
    (if (cond-else-clause? first)
      (if (null? rest)
        (sequence->exp (cond-actions first))
        (error "Else caluse isn't last nyo - COND-IF" clauses))
      (if (cond-extend? first)
        (cond-make-extend first rest)
        (make-if (cond-predicate first)
             (sequence->exp (cond-actions first))
             (expand-clauses rest)))))))


試行錯誤してgdgdだけど、これで動いた。

 
(cond->if '(cond ((assoc 'b '((a 1) (b 2))) => cadr)
   (else false)))

gosh> (let-o ((result (assoc 'b '((a 1) (b 2))))) (if result (cadr result) false))
おお、良い感じ


goshで(cond ((null? 'a) => car) ((cdr '((a b) (c d))) => car) (else 'false))を評価して、(c d)が返るのを確認した後、

(eval-o '(cond ((null? 'a) => car) ((cdr '((a b) (c d))) => car) (else 'false)) the-grobal-environment)
とやって、(c d)が返ることを確認。

ソースはここ

| | Comments (0) | TrackBack (0)

2007.09.06

SICP 4.1.2 Representing Expressins その2

俺様処理系にはデバッグ機能が無い事に気がついた。

それはさておき、僕なりに考えたデバッグ方法。traceを使うと、引数が省略されて困るときがある。特に素人はかなり困る。表示もそうだけど、同じ引数でその手続きだけ実行したいときがある。
CALL cond-clauses (cond ((...) ...) (x 10) (else -3))

トップレベルで、(define bp0 '())みたいに変数を定義しておき、ソースの該当箇所で(set! bp0 exp)のように値を設定しておくと、その関数を抜けた後もそのときの値が見れる。これで、ローカルに作った手続きのデバッグもできそう。頑張れば、bp1→bp2って順繰りに自動で設定することもできそうだ。もっと良い方法は絶対にあるんだけど、当面はこれで十分だ。bpはBreakPointの略。昔作ったROMデバッガの仕組みを思い出したから。

今回はcondからifへの変換の話。俺様処理系には、>とかeq?とかしゃれた演算子はないので、とりあえずこんな感じの手続きを考える。
(cond ((null? x) 5) (x 10) (else -3))

cond-ifによって、cond文が、if文に変換される。ここは俺様処理系とは関係ないので、写経で動くはず。

(cond->if '(cond ((null? x) 5) (x 10) (else -3)))
とすると、こんな式が返る。
(if (null? x)
  5
  (if x
    10
    -3))

良い感じ。

Exercise 4.3 飛ばす

Exercise 4.4 その1 and と orをスペシャルフォームとして実装しなさい。

まずは、普通にeval-oに手続きを追加したバージョン。andとorだと、gaucheのand、orと混乱するので、and-o、or-oにする。

(define (eval-o exp env)
 (cond ((self-evaluating? exp) exp)
    ((variable? exp) (lookup-variable-value exp env))
    ((quoted? exp) (text-of-quotation exp))
    ((call? exp) (apply-o (eval-o (call-operator exp) env)
               (list-of-values (call-operand exp) env)))
    ((assignment? exp) (eval-assignment exp env))
    ((definition? exp) (eval-definition exp env))
    ((if? exp) (eval-if exp env))
    ((and-o? exp) (eval-and (cond-tests exp) env)) ;追加
    ((or-o? exp) (eval-or (cond-tests exp) env))  ;追加
    ((and-d? exp) (eval-o (and->if exp) env))    ;追加
    ((or-d? exp) (eval-o (or->if exp) env))     ;追加
    ((lambda? exp)
     (make-procedure (lambda-parameters exp)
             (lambda-body exp)
             env))
    ((begin? exp)
     (eval-sequence (begin-actions exp) env))
    ((cond? exp) (eval-o (cond->if exp) env))
    ((application? exp)
     (apply-o (eval-o (operator exp) env)
         (list-of-values (operands exp) env)))
    (else
     (error "Unknown expression type nyo -- EVAL" exp))))

;;;and-oとor-oの実装
;;;and-o
(define (and-o? exp) (tagged-list? exp 'and-o))
(define (eval-and exp env)
 (if (null? exp)
   true
   (if (eval-o (first-operand exp) env)
     (eval-and (rest-operands exp) env)
     false)))
(define (cond-tests exp) (cdr exp))

;;;or-o
(define (or-o? exp) (tagged-list? exp 'or-o))
(define (eval-or exp env)
 (if (null? exp)
   false
   (if (eval-o (first-operand exp) env)
     true
     (eval-or (rest-operands exp) env))))
   

次が、if文への変換。derivedだから、and-d、or-dで実装。

;;;and-d
(define (and-d? exp) (tagged-list? exp 'and-d))
(define (and->if exp) (expand-and (cdr exp)))
(define (expand-and exp)
 (if (null? exp)
   'true
   (let ((first (car exp)) (rest (cdr exp)))
    (make-if first
         (expand-and rest)
         'false))))

;;;or-d
(define (or-d? exp) (tagged-list? exp 'or-d))
(define (or->if exp) (expand-or (cdr exp)))
(define (expand-or exp)
 (if (null? exp)
   'false
   (let ((first (car exp)) (rest (cdr exp)))
    (make-if first
         'true
         (expand-or rest)))))


and-ifの結果
(and->if '(and-d (cond1 'aaa) (cond2 'bbb) (cond3 'ccc)))
gosh> (if (cond1 'aaa) (if (cond2 'bbb) (if (cond3 'ccc) true false) false) false)

'falseの変わりにfalseや#fと書くと、and->ifの戻りに#fが入ってしまい俺様evalで評価できずエラーになった。evalや、true/falseの作りでどうにでもなるけどね。

動くソースはここ


と書いてから、Gaucheクックブックにデバッグのヒントを発見。

| | Comments (0) | TrackBack (0)

2007.09.05

SICP 4.1.2 Representing Expressins

Exercise 4.2

a.スペシャルフォームかどうかを先に評価しないと駄目。SICPの最初の方でifはなんでスペシャルフォームなのかと同じ理由。(define x 3)の場合、defineがapplicationだと見なされ、引数を先に評価しようとして、xがlookupできずエラーになる。

b.とりあえず動いた。evalはeval-oに、apllyもapply-oに変更してあります。-oは俺様のo。エラーメッセージも、写経だと処理系のエラーメッセージと区別がつきにくいので、最後にnyoの署名を入れてあります。nyoはニョガーンのnyo。

教科書のevalはこう変更。

(define (eval-o exp env)
 (cond ((self-evaluating? exp) exp)
  ((variable? exp) (lookup-variable-value exp env))
  ((quoted? exp) (text-of-quotation exp))
  ((call? exp) (apply-o (eval-o (call-operator exp) env)  ;追加
             (list-of-values (call-operand exp) env)))
  ((assignment? exp) (eval-assignment exp env))
  ((definition? exp) (eval-definition exp env))
  ((if? exp) (eval-if exp env))
  ((lambda? exp)
   (make-procedure (lambda-parameters exp)
            (lambda-body exp)
            env))
  ((begin? exp)
   (eval-sequence (begin-actions exp) env))
  ((cond? exp) (eval (cond->if exp) env))
  ((application? exp)
   (apply-o (eval-o (operator exp) env)
        (list-of-values (operands exp) env)))
  (else
   (error "Unknown expression type nyo -- EVAL" exp))))

callが呼ばれたら、一個ずらしてそのままapply-oへ。エラーチェック無し。
((call? exp) (apply-o (eval-o (call-operator exp) env)  ;追加
           (list-of-values (call-operand exp) env)))

call周りで作った手続きはこれ。
(define (call? exp) (tagged-list? exp 'call))
(define (remove-call exp) (cdr exp))
(define (call-operator exp)
 (operator (remove-call exp)))
(define (call-operand exp)
 (operands (remove-call exp)))

driver-loopが使いにくいので、直接俺様evalを呼び出してテスト

(define the-grobal-environment (setup-environment))
(eval-o '(define echo (lambda (x) x)) the-grobal-environment)

(trace application?)
(trace apply-o)
(trace call?)

普通の呼び出しだとこう。
(eval-o '(echo 'abc) the-grobal-environment)

gosh> CALL call? (echo (quote abc))
RETN call? #f
CALL application? (echo (quote abc))
RETN application? #t
CALL apply-o (pr...re (...) (...) ((...))) (abc)
RETN apply-o abc
abc

call?が#fを返し、application?が#tなので、apply-oに展開されたechoが渡される。

次にcallを使った呼び出しはこう。
(eval-o '(call echo 'abc) the-grobal-environment)

gosh> CALL call? (call echo (quote abc))
RETN call? #t
CALL apply-o (pr...re (...) (...) ((...))) (abc)
RETN apply-o abc
abc

call?が#tを返すので、追加した部分が評価され、apply-oに上のapplication?が#tを返したときと同じパラメータを渡している。

((call? exp) (apply-o (eval-o (call-operator exp) env)  ;追加
           (list-of-values (call-operand exp) env)))

結果は同じ。
問題は解けたけど、効率的になったかどうかは不明。

ここまでは動くファイルはここ

| | Comments (0) | TrackBack (0)

Xilinx ISE、EDIF、そしてLisp!

今日はニッチな所でblog書く。

素人がSICPの4章で驚くのは、なんといっても入力された文字列がいつの間にかListになっていること。最初の一歩の面倒なところを(read)一発で変換できているのが凄い。もしかして、(read)でEDIF読み込めない?と思ってやってみた履歴。

まず、準備としてISE環境でのedifの作り方。ngc2edifコマンドを使う。昔作ったshallotで試してみる。こういうとき、一つでも自分で作った回路があると便利だ。ISEで合成しngcまで作る。その後にこのコマンド。
> ngc2edif shallot.ngc
で、shallot.ndfが作られる。拡張子はndfだけど中身は立派なedif。テキストエディタで見てみよう。

やっていく過程で、びっくりするような低レベルなバグ発見。Verilogの中で普通に<=と=が混在している。クオータスの合成ツールって、ブロッキングとノンブロッキング代入の混在を見逃すのか?→後で書く or 誰か書いて(web 2.0的他力本願)

どきどきしながら、今できたファイルを読み込む。
(define input-port
 (open-input-file "d:/home/study/SICP/edif/shallot.ndf"))
(define shallot-edf (read input-port))

で、変数 shallot-edfに作ったままのedifが入っている!Wikipediaによると、「これは見かけはプログラム言語LISPに似ている。」との事だが、似ているんじゃない、S式そのものだ。

後は、適当にアクセスの手続きを用意する。

;;edifのバージョンを取得
(define edif-version
 (lambda (edif)
  (edif-scan 'edifVersion (edif-inner-list edif))))

::edfiのStatusを取得
(define edif-Status
 (lambda (edif)
  (edif-scan 'status (edif-inner-list edif))))

;;edifのレベルを取得
(define edif-Level
 (lambda (edif)
  (edif-scan 'edifLevel (edif-inner-list edif))))

;;検索失敗の試験
(define edif-fail
 (lambda (edif)
  (edif-scan 'edifFail (edif-inner-list edif))))

(define edif-inner-list
 (lambda (edif)
  (cdr (cdr shallot-edf))))

(define edif-tag
 (lambda (parameter)
  (car parameter)))

(define edif-scan
 (lambda (keyword edif-list)
  (if (null? edif-list)
    'fail
    (let ((parameter (car edif-list)))
     (if (eq? keyword (edif-tag parameter))
       parameter
       (edif-scan keyword (cdr edif-list)))))))


gaucheで実行

(edif-version shallot-edf)
gosh> (edifVersion 2 0 0)

(edif-Level shallot-edf)
gosh> (edifLevel 0)

(edif-Status shallot-edf)
gosh> (status (written (timestamp 2007 9 5 11 29 49) (program "Xilinx ngc2edif" (version "J.33")) (author "Xilinx. Inc ") (comment "This EDIF netlist is to be used within supported synthesis tools") (comment "for determining resource/timing estimates of the design component") (comment "represented by this netlist.") (comment "Command line: shallot.ngc ")))

キタコレ!
5分くらいでここまで出来たぜ。

普通に読めるということは、頑張れば修正もできるし、新しく書けるって事だ。1からedif作ってHDLを経由しない俺様合成ツールを作るもよし、内部ノード引き出しツールを作ってもよし、FPGAシミュレータ作ってもよし。広がれ妄想!

| | Comments (0) | TrackBack (0)

今日の日記

ときどきの雑記帖 リターンズ から

> shiro 『好きと仕事の関係っていうのは、まあ、 なんか泥沼みたいな登り坂を荷物を引きずりながら俺なんでこんなことやってんだろうなあ、 まあ、好きだからしゃあねえなぁ、とつぶやくようなものでしょうなあ。』
結婚も同じ気がした。

> ansible:
> Agreed. Start at the top level, and work your way down. Or else, start at the very bottom. Quantum mechanics,basic physics, electronics, semiconductor materials, transistors, logic circuits, low-level computer architecture (registers, ALUs, RAM), and high-level computer architecture (pipelines, crossbar switches, bus arbitration).
> Then we start on machine language, assembly language (not the same thing), and then C along with compiler design.
これを真顔で言えたらかっこいいぜ。

fpga-labさんから
http://www.fpga-lab.org/diary/days0709.html#2007/09/05
人のソース見ると本当に参考になりますね。昔、ISEでverilogのdefparamが効かなくでそれ以来defparamはずっと避けていたのですが、同僚のソースを見ると普通に使っていて驚いたりします。VHDL→Verilogと移ったりするとVHDLの癖とかがそのまま残っていたりして、最初から真っ当な合成ツール+Verilogから来る人とは違うソースになっていたりします。そして、老害ソースに。

あろはさんのところから
> いつものことながら gcc のことを書き出すと目に見えてアクセス数が落ちる当ブログですが,
にワラタ。読んでいる側から見るとgcc キタ━━━━━━(゚∀゚)━━━━━━!!!! って感じなのですが、少数派かもしれません。

| | Comments (2) | TrackBack (0)

2007.09.04

SICP 4.1 The Metacircular Evaluator

さわりだけ勉強して通り抜けようとしたけど、あきらめた。ちゃんと4章がんばる。処理系かけて一人前Lisperなら逃げない。

大事そうなのここ

1. To evaluate a combination (a compound expression other than a special form), evaluate the subexpressions and then apply the value of the operator subexpression to the values of the operand subexpressions.


2. To apply a compound procedure to a set of arguments, evaluate the body of the procedure in a new environment. To construct this environment, extend the environment part of the procedure object by a frame in which the formal parameters of the procedure are bound to the arguments to which the procedure is applied.

わかったような、わからないような。環境の中でlook up可能なシンボルと直接applyできるprimitiveな手続きになるまで、reduceしまくる必要があるのは分かった。日本語版SICP買ったのに、イラネって思って実家に送ってしまった。失敗。

Exercise 4.1 引数の評価順序の問題

最初の式がこれ

(define (list-of-values exps env)
 (if (no-operands? exps)
  '()
  (cons (eval-print (first-operand exps) env)
   (list-of-values (rest-operands exps) env))))


ますはgaucheで評価される順番を調べる。引数を表示して、引数を返すだけの関数を用意。2つめの引数yはlist-of-valuesのenv相当分。引数の数を合わせているだけ。

;;gaucheの実験
(define (eval-print x y)
 (debug-print x)
  x)

consを実行してみると
(cons (eval-print 'aa '()) (eval-print 'bb '()))


;#?=x
;#?- aa
;#?=x
;#?- bb
;(aa . bb)
こうなるので、左から右に評価されている。

次にlist-of-valuesで評価するために、この後で出てくる以下の手続きが必要。

(define (rest-operands ops) (cdr ops))
(define (first-operand ops) (car ops))
(define (no-operands? ops) (null? ops))

右から左に評価するには、いったんletで代入すればよい。

(define (list-of-values-inv exps env)
 (if (no-operands? exps)
  '()
  (let ((rhs (list-of-values (rest-operands exps) env)))
   (cons (eval-print (first-operand exps) env)
      rhs))))

これで違いを確認できる。
(list-of-values '(a b) '())
(list-of-values-inv '(a b) '())

| | Comments (2) | TrackBack (0)

8月の魔物

8月は魔物がいる。まあ、例年通りだ。

| | Comments (0) | TrackBack (0)

“文学少女”と慟哭の巡礼者

“文学少女”と慟哭の巡礼者読みました。

アマゾンのレビュー通り、文句なしの5星。★★★★★

レビューは若干ネタバレがあるから、読まない方が良いと思う。軽くクトゥルフから入って、今までひっぱてきた伏線が怒濤の展開を見せる。登場人物の悲しみ、怒り、やるせなさが僕にも伝わってきた。いろいろ書きたいけど、ネタバレになる。娘を持つ父親としてある場所で寒気が走った。こんな気持ちになるのは本当に久しぶりだ。ネタバレ防止の為、褒めるしかできませんが最高でした。

興味を持った人は一巻から順に、大事に大事に読んで欲しいです。

アマゾンリンク

| | Comments (0) | TrackBack (0)

資格の勉強

日記を書く[・ _ゝ・]はやみずさんから
blogの中の人のレベルであれば、全然資格なんて必要ないです。

僕は一種、二種はストレートで受かってますが、その次、エンベデッドとネットワークは合計4連敗くらいしています。以前は組み込みプログラマーしていましたが、今は高速基板とか、FPGAとかしています。資格作っている所が想定している情報処理技術者の枠組みからは少し離れます。その辺りを差し引いて読んでみてください。

僕なりに感じた情報処理検定を勉強して得た物はこんな感じです。

・情報処理に、基本的なアルゴリズム、概念が押さえられる。クイックソートと、バブルソートの違いは何?とか、2の補数表現って何?みたいな範囲。大学4年生(5年目だけど)から、情報処理の勉強を始めた僕には綺麗にまとまっていてとても助かりました。

・浅く広く勉強できる。
TCP/IPとかデータベースの正規化とか、概念だけはさらっと勉強できます。情報処理検定で勉強しなければ、ずっと勉強しなかったと思います。役に立ったかどうかは微妙ですが。

・一緒に勉強できる仲間が見つかる
僕の時はniftyのFLICが勉強の場でした。Tea Partyの人や、魔皇子さんとか。他業種の方と一緒に勉強できるのはとてもすばらしいことですが、今はblogで十分補完できると思います。

プログラミングがわからない人が、とっかかりとして勉強するにはお勧めしますが、ここまでできるひとが、あらためて勉強する必要はないです。もっと他の事を勉強した方がよいです。できたらblogにネタを書いてくれるともっとうれしいです。

もし僕が採用担当だったら、資格の有無よりも赤黒木の可視化の方を評価します。就職が心配であれば、資格で一律に評価する所より、資格以外のなにかを評価してくれる会社を探すという選択肢もあります。あと、資格の勉強は会社入ってからでもできますよ。

| | Comments (0) | TrackBack (1)

今日の日記

くだらない。主張するのは自由だと思うが、受け入れる方は頭にしょうが(ry
http://blog.livedoor.jp/dqnplus/archives/1025181.html

mainの話
http://d.hatena.ne.jp/RiSK/20070826
なるほど。mainだけ呼び出し規約が違う可能性って十分あると思う。

学生に戻りたい
http://ao.dip.jp/~okazaki/diary/?date=20070828

Javaプロセッサ すげー。でもVHDLなのか。
http://www.jopdesign.com/

それぞれの立場があるんだな。
 愛しの彼が振り向かない~みくるver~
 http://www.youtube.com/watch?v=7HKCKk-v2Ho&mode=related&search=
 【MAD】長門有希×エアーマンが倒せない : 愛しの彼が振り向かない
 http://www.youtube.com/watch?v=WsLkchAAo2I&mode=related&search=
 愛しの彼が振り向かない~デレデレハルヒver~ 歌ありver
 http://www.youtube.com/watch?v=QOpI6k4jPe8&mode=related&search=
 愛しの彼が振り向かない ~ダークサイド古泉ver~
 http://www.youtube.com/watch?v=s2Rda1pECiE&mode=related&search=
 キョンですが部室の空気が最悪です
 http://www.youtube.com/watch?v=LLPRHcp8p18&mode=related&search=

パラケルススの娘1巻:まあまあ面白かった。雰囲気は良いんだけど、人の名前が覚えられない。2巻どうしようっかなぁ。
ゼロの使い魔 9巻:読みました。なんていうか冒険のなかでのろけて欲しいんだが。のろけの間に冒険している。
タバサの冒険:こっちは面白かった。タバサ 長門だと結構ヒットするのに、読子が入ると激減するのが不思議。
R.O.D. 3~5巻:読みました。 面白い。どんどん読むよ。

文学少女で感動したのでラノベはおなかいっぱい。とらドラ5巻も読むのがもったいないので、本棚に大事に置いておこう。

| | Comments (0) | TrackBack (0)

2007.09.02

schelog その3

Schemeで動くロジックプログラミングの勉強続き

こういうルールに対して、
(define %knows-simple
  (%rel ()
     [('Odysseus 'Tex)]))
        

(%which () (%knows-simple 'Odysseus 'Tex))が()trueを返し、(%which () (%knows-simple 'Odysseus 'Scheme))が#fを返す所を追おう。

まずはマクロを展開する。
(%macroexpand (%which () (%knows-simple 'Odysseus 'Tex)))

展開するとこんな感じ。


(let ()
  (call-with-current-continuation
   (lambda (__qk)
     (set! schelog:*more-k* __qk)
     (set! schelog:*more-fk*
           ((schelog:deref* (%knows-simple 'Odysseus 'Tex))
            (lambda (d)
              (set! schelog:*more-fk* #f)
              (schelog:*more-k* #f))))
     (schelog:*more-k*
      (map
       (lambda (nam val)
         (list nam (schelog:deref* val)))
       '()
       (list))))))

(%which () (%knows-simple 'Odysseus 'Tex))の一つめの引数が()なので、letは意味が無くて、これと等価。

(call-with-current-continuation (lambda (__qk)
   (set! schelog:*more-k* __qk)   ; ここで、継続をschelog:*more-k*に代入
   (set! schelog:*more-fk*      ;  なんか処理した結果をschelog:*more-fk*に代入
     ((schelog:deref* (%knows-simple 'Odysseus 'Tex))
       (lambda (d)
         (set! schelog:*more-fk* #f)
         (schelog:*more-k* #f))))
   ; 下のmapで処理した結果を、schelog:*more-k*に渡す。  
   ; schelog:*more-k* が継続 __qk なので、mapの結果がそのまま%whichの戻り値になる。
   (schelog:*more-k*      
    (map (lambda (nam val) (list nam (schelog:deref* val))) '() (list)) ;;ここまでmap処理
     )))

どうも、したのmap処理を実行した形跡が()っぽい。mapの引数の評価順序は決まっていないが、gaucheとこの関数の場合、2つの目の引数が空リストなのでmapの中のlambda式は評価されずに'()を返している。

ちょっと話が楽になって
(call-with-current-continuation (lambda (__qk)
   (set! schelog:*more-k* __qk)   ; ここで、継続をschelog:*more-k*に代入
   (set! schelog:*more-fk*      ;  なんか処理した結果をschelog:*more-fk*に代入
      ((schelog:deref* (%knows-simple 'Odysseus 'Tex))
        (lambda (d)
         (set! schelog:*more-fk* #f)
         (schelog:*more-k* #f))))
   (schelog:*more-k* '()    ; ここに処理が移ると()trueを返す。
     )))

2つめのset!で、マッチングに成功したらそのまま抜けて、失敗したら一番奥のlambdaを評価する。その結果、schelog:*more-fk*に#fをset!し、(schelog:*more-k* #f)を評価して脱出している。schelog:*more-k*が最初に渡された継続だから、これで一気に#fを返す。

(set! schelog:*more-fk*        
   ((schelog:deref* (%knows-simple 'Odysseus 'Tex))
     (lambda (d)
      (set! schelog:*more-fk* #f)
      (schelog:*more-k* #f))))


schelog:deref*は、(%knows-simple 'Odysseus 'Tex)の戻り値をそのまま使っている。ようやく真偽の判定が、%=にある所まで追い込む。今の段階では、リストが同じかどうかを判断しているだけみたい。

(%=  '(Odysseus Tex) (list 'Odysseus 'Tex))

とりあえずここ。試しに、元のサンプルを展開したらこんな感じに。


(%macroexpand 
  (%rel ()
        [('Odysseus 'Tex)]
        [('Odysseus 'Prolog)]
        [('Odysseus 'Scheme)]
        [('Odysseus 'Panelope)]
        [('Panelope 'Tex)]
        [('Panelope 'Prolog)]
        [('Panelope 'Odysseus)]
        [('Telemachus 'Tex)]
        [('Telemachus 'calculus)]
        ))
 


(lambda __fmls
  (lambda (__fk)
    (call-with-current-continuation
     (lambda (__sk)
       (let ((! (lambda (fk1) __fk)))
         (%let
          ()
          (call-with-current-continuation
           (lambda #0=(__fk)
            (let* ((__fk ((%= __fmls (list 'Odysseus 'Tex)) . #1=(__fk)))) . #2=((__sk __fk)))))
          (call-with-current-continuation
           (lambda #0#
             (let* ((__fk ((%= __fmls (list 'Odysseus 'Prolog)) . #1#))) . #2#)))
          (call-with-current-continuation
           (lambda #0# (let* ((__fk ((%= __fmls (list 'Odysseus 'Scheme)) . #1#))) . #2#)))
          (call-with-current-continuation
           (lambda #0# (let* ((__fk ((%= __fmls (list 'Odysseus 'Panelope)) . #1#))) . #2#)))
          (call-with-current-continuation
           (lambda #0# (let* ((__fk ((%= __fmls (list 'Panelope 'Tex)) . #1#))) . #2#)))
          (call-with-current-continuation
           (lambda #0# (let* ((__fk ((%= __fmls (list 'Panelope 'Prolog)) . #1#))) . #2#)))
          (call-with-current-continuation
           (lambda #0# (let* ((__fk ((%= __fmls (list 'Panelope 'Odysseus)) . #1#))) . #2#)))
          (call-with-current-continuation
           (lambda #0# (let* ((__fk ((%= __fmls (list 'Telemachus 'Tex)) . #1#))) . #2#)))
          (call-with-current-continuation
           (lambda #0# (let* ((__fk ((%= __fmls (list 'Telemachus 'calculus)) . #1#))) . #2#)))
          (__fk 'fail)))))))

(call/cc (labmda ・・・))が全て、let%の引数になっている。
とりあえず、ルールが一個しか無いような場合は、同じリストが存在するかだけで判断できる。って、ものすごい遠回りして気がついた。自分がアホすぎて泣けてくる。ここまで整理してみてルールの連鎖に入ろう。

| | Comments (0) | TrackBack (0)

schelogと%macroexpand

なんとなくマクロの構文が分かったので、%relを解析してみよう。

(define %knows
(%rel ()
[('Odysseus 'TeX)]
[('Odysseus 'Scheme)]
[('Odysseus 'Prolog)]
[('Odysseus 'Penelope)]
[('Penelope 'TeX)]
[('Penelope 'Prolog)]
[('Penelope 'Odysseus)]
[('Telemachus 'TeX)]
[('Telemachus 'calculus)]))

まずはここから。


(define-macro %rel
(lambda (vv . cc)
`(lambda __fmls
(lambda (__fk)
(call-with-current-continuation
(lambda (__sk)
(let ((! (lambda (fk1) __fk)))
(%let ,vv
,@(map (lambda (c)
`(call-with-current-continuation
(lambda (__fk)
(let* ((__fk ((%= __fmls (list ,@(car c)))
__fk))
,@(map (lambda (sg)
`(__fk ((schelog:deref* ,sg)
__fk)))
(cdr c)))
(__sk __fk)))))
cc)
(__fk 'fail)))))))))

ぱっと見ただけで、2重のcall/ccか。

gcc -E みたいなものを求めてさまよう。
http://www.lingr.com/room/gauche/archives/2007/01/07に発見。

(%macroexpand (%rel () [('Odysseus 'Tex)]))

で展開型が返される。ひげぽんさんに感謝。


(lambda __fmls
(lambda (__fk)
(call-with-current-continuation
(lambda (__sk)
(let ((! (lambda (fk1) __fk)))
(%let ()
(call-with-current-continuation
(lambda (__fk)
(let* ((__fk ((%= __fmls (list 'Odysseus 'Tex)) __fk)))
(__sk __fk))))
(__fk 'fail)))))))

だいぶ見やすくなった。一番外側のlambdaで、引数リストが__fmlsになっている。()でくくられてないけど、良いのかな。再びここで発見。http://karetta.jp/book-node/gauche-hacks/000332 早く、(ry

> ここで、任意の数の引数を渡したい場合はどうすればいいでしょうか? この場合はリストではなく名前(正確にはシンボルと言うべきでしょう。シンボルについては「シンボルとquote」で説明します)を渡します

なるほど。%whichの実装と両側から追っていくか。

| | Comments (0) | TrackBack (0)

2007.09.01

schelogとdefine-macro

ロジックプログラミングの勉強にschelogを使ってみる。

入手先は、Programming in Schelogから。付属のinstall方法は情報が古いのか、schelog.scmを読み込むだけでgaucheでも普通に使えている。

(define %knows
(%rel ()
[('Odysseus 'TeX)]
[('Odysseus 'Scheme)]
[('Odysseus 'Prolog)]
[('Odysseus 'Penelope)]
[('Penelope 'TeX)]
[('Penelope 'Prolog)]
[('Penelope 'Odysseus)]
[('Telemachus 'TeX)]
[('Telemachus 'calculus)]))

%relを使って、で%knowsというpredicateを定義。%whichで問い合わせ。

(%which ()
(%knows 'Odysseus 'TeX))
=> ()true

(%which ()
(%knows 'Telemachus 'Scheme))

=> #f

動きを追いたいけど、define-macroの動きが分からない。schemeに関する本が一冊くらい欲しいな。

一番簡単そうなこれから。

;%let introduces new logic variables

;(define-syntax %let
; (syntax-rules ()
; ((%let (x ...) . e)
; (let ((x (schelog:make-ref)) ...)
; . e))))

(define-macro %let
(lambda (xx . ee)
`(let ,(map (lambda (x) `(,x (schelog:make-ref))) xx)
,@ee)))

まずは、(lambda (xx . ee) の.で躓く。ここに回答を見つけた。早くgauche本でないかな。
http://karetta.jp/book-node/gauche-hacks/000332
> 手続き引数の記述のなかで.(ドット)記号に続いて引数名を書くと、任意の個数以上の引数をとる手続きが書
> けます。

次、バッククオート`
http://karetta.jp/article/book/016206/016217/
> quasiquoteも式を評価せずそのまま返します。 quoteとの違いは、式の中でunquoteが使える点です。
なるほど。gauche本出たら、2冊くらい欲しい。

> unquoteは,(カンマ)記号で代用できます
`と,がペアか。

@も分からない。とりあえずlambdaを見やすくして、define-macroの本体を抜き出すと、

`(let ,(map (lambdaでくくった関数) xx)
,@ee)
僕の知っているletの構文と違う。ちょっと考えて分かった。,(mapの部分でunquoteされて、mapが評価されて間に入り、いつもの構文になるのか。

独習 Scheme 三週間から、,@も見つけた。,@は,と@の組み合わせではなく、,@で一つの意味がある。展開したときに、外側の括弧を取り除く。上の例だと、eeに手続きのリストを渡すと、マクロ展開時に順番に実行されるようだ。もう少しがんばろう。

今日分かったこと。

こんな感じでリストを作る。
(define lv (list (list 'x 1) (list 'y 2)))
gosh> lv
((x 1) (y 2))

こうやって、xとyを足す手続きが定義できる。
(define-macro foo (lambda () `(let ,lv (+ x y))))
gosh> (foo)
3

(define lv (list (list 'x 10) (list 'y 10)))でlvを再定義すると、define-macroを再評価しなくても、変更が有効になる。この例だと、fooが評価されるときに始めてマクロの展開をしているから。
gosh> (foo)
20

なんだか、何でもありだな。

ついでに、SICP読んでようやくここの意味が分かった。手続きを作るときに、frameをコピーして手続きにくっつけるから。
http://karetta.jp/book-node/gauche-hacks/007232

| | Comments (0) | TrackBack (0)

« August 2007 | Main | October 2007 »