Rev.03 1997/05/08 風つかい Rev.01 1997/05/03 風つかい ■ Icon > Icon雑記帳 はじめに 風つかい Iconは AWKや Perlの仲間のテキスト処理言語です。 Iconは データ構造が豊富で、テキスト解析に 威力を発揮する 強力な制御構造 を持っています。 もっと^2 使われてよい言語と思います。 しかし、未だ 日本語の入門書が ありませんので、 AWKについて、ある程度の 知識を お持ちになっている方を 対象として、入門講座を書きました。 ・テキスト解析言語Icon入門講座 ---AWKerのための Icon入門--- ・Icon日記 ---テキスト解析言語Icon入門講座2--- この Icon雑記帳は その続編として、その後 作ったプログラムや 前の 講座で 書き落とした 部分の 解説を、まとめたものです。 前の 2編の講座と いっしょに ご覧になって Iconを使って頂けると うれしい です。 Iconのプログラムおよびライブラリーは、次のところから入手できます。 http://www.cs.arizona.edu/icon/index.html Iconは PDSですので、この入門講座も同じ扱いとします。(転載・編集自由) (This textbook is in the public domain.) 目次 はじめに (1) jsplit.icn(1) (2) jsplit.icn(2) (3) jsplit.icn(3) (4) generatorの使い方(1) (5) generatorの使い方(2) (6) generatorの作り方(1) (7) generatorの作り方(2) (8) generatorのまとめ (9) IYAX.ICN (10) 順列 (11) 組み合わせ (12) pipe風のプログラム (13) ビデオ問題は、道遠し (14) ビデオ問題/組み合わせ (15) ビデオ問題/簡易解法 (16) ビデオ問題/難しい (17) 構造体 tree表示(1) (18) jimage.icn (19) 構造体 tree表示(2) (20) dir2tree(1) (21) dir2tree(2) (22) dir2tree(3) むすび 風つかい (TRA11936@biglobe.ne.jp/PFF01531@niftyserve.or.jp) < IconのWWWは、http://www.cs.arizona.edu/icon/index.html> BGM: La Fiesta / Chick Corea (icon_224.txt 1997/05/03 PCVAN PIG) ■ Icon > Icon雑記帳(1) jsplit.icn(1) 風つかい Icon日記 に引き続き、Icon雑記帳 というタイトルで、Icon関連の お話しをし ていきたい と思います。 Iconの話題が多いか 雑記帳の方が多いかは、ちと心配 なところも ありますが。 ところで、HB彗星ですが3月下旬になると、夕方の6時〜7時頃に北西の空 に見えるということで、期待していたのですが、余り見えません。 6時頃は未だ太陽が沈みきっていないのと、7時頃は見易いはずなのですが、 結構 雲が出てたり、天気が良くなかったりして 見えないことが多いです。結局 下旬になって まだ1度しか見ていません。 さて今日はシフトJIS関連の procedureの続きで、split.icnのシフトJIS 対応をやってみたいと思います。 split.icnは文字列をある文字(セット)で、 区切って listに格納するものです。 space区切りや tab区切りのデータ処理に 使います。 で、まず、当初の split.icnの復習 を。 文字列から 単語を切り出して 書き出す プログラムです。 切り出した 単語を listにして 上位プログラムに渡す やり方と generatorで 上位に渡す やり方 の 2種類のやり方 が 入っていますが、結果は 同じです。 -----^ SPLIT4.ICN ( date:97-03-29 time:17:04 ) ------------- BGM: Europe/Carlos Santana (icon_201.txt 1997/03/30 PCVAN PIG) ■ Icon > Icon雑記帳(2) jsplit.icn(2) 風つかい 今日は、暖かい晴れの天気で、桜も見頃となっています。月に群雲 花に風 の 例えの通り、強風が 吹いて来ました。 春の嵐 ですね〜。 さて、今回は、jsplit.icnの続きです。 split.icnは、upto()と many()で 構成されています。 これを シフトJIS対応に した jupto()と jmany()に すればいいのですが、もう一つ問題があります。 ~cという 表現を 使って います。 しかし 前回 お話し しました ように 2バイト文字で 補集合(指定文字セット以外 の文字)を 使うと 膨大な 文 字数 の 照合 が 必要となります ので、jupto_not()と jmany_not() という 補集合を 使わない procedureを 作ろう と 思います。 という訳で、次に 補集合を 使わないため procedureです。 -----^ SJIS5.ICN ( date:97-03-30 time:18:11 ) -------------- BGM: トライアングル・ブルー/アン・ルイス (icon_202.txt 1997/03/30 PCVAN PIG) ■ Icon > Icon雑記帳(3) jsplit.icn(3) 風つかい 今回も jsplit.icnの続きです。 シフトJIS対応の split.icnプログラムです。 linkしている sjis5は 前回 の プログラムです。 -----^ SPLIT5.ICN ( date:97-03-30 time:18:38 ) ------------- split5.txtとした時の結果です。 -----^ SPLIT5.TXT ( date:97-03-30 time:18:38 ) ------------- BGM: Vivien/篠原美也子 (icon_203.txt 1997/03/30 PCVAN PIG) ■ Icon > Icon雑記帳(4) generatorの使い方(1) 風つかい アリゾナ大の Icon-Webに アクセスしましたら、Icon Newsletterの No.52 が、出ていました。 urlは、次の通りです。 http://www.cs.arizona.edu/icon/newsletter/inl52/inl52.html 目次の部分を引用しておきます。 >No. 52 -- April 1, 1997 > >Contents > > Mail-Order Program Material > Teaching Icon > Web Links > Native Interface Components in Windows Icon 9.3 > Programming Language Handbook > From Our Mail > Knowledge Explorer ご興味のある方は、ご覧になって下さい。 さて、今日は、Iconの特徴 の1つである generatorの使い方 について、 お話し します。 generatorと、その使い方を あげて みましょう。 実例を 示した方が 早いと思いますので、早速サンプルを。 every (generatorを含む式) または、 every (generatorを含む式) do ... の格好で 使います。 -----^ GEN01.ICN ( date:97-04-01 time:01:02 ) -------------- gen01.txt とした時の結果です。 -----^ GEN01.TXT ( date:97-04-01 time:01:03 ) -------------- BGM: Four On Six / Wes Montgomery (icon_204.txt 1997/04/01 PCVAN PIG) ■ Icon > Icon雑記帳(5) generatorの使い方(2) 風つかい 今回は、generatorの続きです。 データを 順次 発生するものには、前回あげたものの他にも あります。 ・read(), reads() のような ファイル読みだし関数 ・get(), pull() のような データ取り出し関数 ・upto(), find() のような スキャン関数 と ・while ... ・until ... ・repeat ... のような くり返し構文 の組み合わせでも、データを 順次 発生できます。 早速サンプルを。 -----^ GEN02.ICN ( date:97-04-02 time:23:04 ) --------------= n," :",s) # 最初の5行のみ書き出す } # while s := read(dir) do write( 5 >= (n +:= 1), " :",s) # これでも同じ。 # while write(5 >= (n +:= 1) ," :",read(dir)) # これでも同じ。 write() write("while ... get()のサンプル 先頭から取り出し") L := ["A","B","C"] n := 0 while s := get(L) do writes(" ",n +:= 1,":",s) ; write() write() write("while ... pull()のサンプル 末尾から取り出し") L := ["A","B","C"] n := 0 while writes(" ",n +:= 1,":",pull(L)) ; write() # get()もこう書けます。 write() write("until ... do ... pop() のサンプル") L := ["A","B","C","D","E","F","G"] n := 0 until n = 5 do writes(" ",n +:= 1,":",pop(L)) # pop()は get()と同じ。 write() write() write("repeat { if ... break } のサンプル") L := ["A","B","C","D","E","F","G"] n := 0 repeat { writes(" ",n +:= 1,":",get(L)) if n >= 5 then break } write() write() write("while ... upto() do {... many() ...} のサンプル") s := " The Icon Programming Language" n := 0 s ? { while tab(upto(~' ')) do writes(" ",n +:= 1,":",tab(many(~' '))) } write() end -----$ GEN02.ICN ( lines:55 words:209 ) -------------------- gen02.txtとした時の結果です。 -----^ GEN02.TXT ( date:97-04-02 time:23:04 ) -------------- BGM: 熱くなれ/大黒麻季 (icon_205.txt 1997/04/02 PCVAN PIG) ■ Icon > Icon雑記帳(6) generatorの作り方(1) 風つかい 今回は、generatorの使い方に 変わって、作り方です。 といっても、前々回、前回の generatorの使い方で、write()や writes()で データを書き出しているところを、 suspend データ という形に、変えれば そのまま generatorができあがります。 例えば、前々回の gen01.icnの every writes(" ",!"ABC") ; write() # string は、 procedure abc() suspend !"ABC" end と変形すれば、これは generatorとなります。 procedure main() every writes(" ",abc()) end とすると、最初の、every writes(" ",!"ABC") と同じ動作となります。 実際のプログラムでは、同じ動作では仕方が無いのですが、generator を使って、generatorを作る一番簡単なサンプルとしてあげました。 実際は、複雑な generatorを、比較的簡単な generatorを段階的に組み 合わせて作っていきます。 gen01.icnを generatorに変換しますと、次のように なります。 -----^ GEN01A.ICN ( date:97-04-04 time:21:46 ) ------------- BGM: MOSAIC/遊佐未森 (icon_206.txt 1997/04/04 PCVAN PIG) ■ Icon > Icon雑記帳(7) generatorの作り方(2) 風つかい 今回も generatorの作り方の続きです。gen02.icnの L := ["A","B","C"] n := 0 while s := get(L) do writes(" ",n +:= 1,":",s) ; write() の while ...の部分を while s := get(L) do suspend s とすると、これも generatorとなります。 これが、くり返し構文を使って generatorを作る 一番簡単なサンプルとなります。 この場合に、nも返したければ、 while s := get(L) do suspend [n +:= 1,s] とすると、リストを発生する generatorということになります。 generatorを 使って、generatorを 階層的に 作っていくやり方は、既に jsplit.icnで 使っています。 jsplit.icnの中の jgetword()は、次のような 階層構造に なっていました。 generator --- jgetword() --- | ... | | while ... jupto_not()...| <---- 文字列から単語を切り出す | ... | | generator -------------------------- | --------------- | generator --- jupto_not() -- | ... | 文字列を、1文字ずつ なめて | every ... jpos() do ... | <---- 文字セットとの照合をして、 | ... | | 単語の区切り位置を探す -------------------------- | generator --------------- | generator --- jpos()-------- 文字列を、1バイトずつ なめて | ... | シフトJISの文字の 先頭位置 | every ... i to j do ... | を探す generator | ... | ( i to j という generatorを -------------------------- を使った generatorです。) さて、gen02.icnを generatorに変換したものを、次に。 -----^ GEN02A.ICN ( date:97-04-04 time:21:50 ) ------------- BGM: MOSAIC/遊佐未森 (icon_207.txt 1997/04/04 PCVAN PIG) ■ Icon > Icon雑記帳(8) generatorのまとめ 風つかい このところ、雨の日が多いです。 でも、桜の花は 結構 しぶとく残って いますね。 さて、雨の日は、Iconでもやろうかな。 今日は、generatorの考え方のまとめを、やってみようと思います。 generatorを 使ったプログラム の構成は、 - generator--------- -consumer---------- | データ発生部 | データ | データ消費部 | | suspend data -----------------> every generator | | | | | -------------------- ------------------- データを順次生成 データ加工 データ選択 の ような 格好になります。 データを 順次生成する プログラムがあって、そのデータを 消費するプログ ラムが ある。 という構成になります。 ここで、generatorが生成したデータに対して、consumerが 条件に 合わない データを棄てて、次のデータを試してみる。 とした 場合が、Backtracking と いうことに なります。 前回、あげました jgetword()は、プログラム構成上は、 ----------- 上位 | jgetword | 単語 切り出し ↑ ----------- | | ------------ | 呼ぶ -->| jupto_not | 単語 区切り位置 検索 | call ------------ | | --------------- | 呼ぶ -->| jpos | シフトJIS文字 ↓ call | | | 区切り位置 検索 下位 |呼ぶ -> i to j | --------------- という階層に なっていますが、考え方としては、 drive ----------- 上位 駆動 -->| jgetword | 単語 切り出し ↑ | ----------- | drive ------------ | 駆動 -->| jupto_not | 単語 区切り位置 検索 | | ------------ | --------------- | |駆動 --> jpos | シフトJIS文字 ↓ | | | 区切り位置 検索 下位 | i to j | --------------- generatorが生成するデータで、順次 上位プログラムを 駆動していく構成と 考えた方が、分かりやすいと思います。 データ駆動型のプログラム構成 とで も言えるでしょう。 テキストデータで、 ・1行に データが スペース区切りで、格納されている形式で、 そのデータを使って、何らかの処理を やりたい場合 ですと、 AWKのように、行データを 自動的に カラム分割して $1,$2,...と変数にセット してくれた方が、プログラムは 組みやすく なります。 Iconでは、この場合は、カラム分割 procedureを 作らないと いけません。 一方、 ・テキストデータが、通常の文章 とか プログラムソースで、 文字や単語の出現順に、何かの処理を やりたい場合 ですと、 Iconのように、文字や単語を、先頭から 順次 切り出して いく機能が 必要に なります。 このような処理で generatorが 非常に 役立ちます。 generatorは、文章のような テキストデータを、文字の集まり 単語の集まり と みなした方が 自然なケース のプログラムに、向いています。 風つかい (TRA11936@biglobe.ne.jp/PFF01531@niftyserve.or.jp) < IconのWWWは、http://www.cs.arizona.edu/icon/index.html> BGM: そのままの君でいて/岡本真夜 (icon_208.txt 1997/04/05 PCVAN PIG) ■ Icon > Icon雑記帳(9) IYAX.ICN 風つかい Icon入門講座で、YAX形式のバインダー YAB.ICNを説明しましたが、実はテキ ストファイルから、ファイルを取り出す YAX.ICNも いっしょに説明する予定で した。 しかし、コメント付けがメンドイので はしょって しまいました。 次のシリーズでは、説明しようと 思っていた のですが、Icon日記を書いてる 頃には 、すっかり 忘れてしまって いました。 というのは、YABは使うのですが、YAXは余り使わないもので。 どなたかの 書き込みの中の スクリプトを、ログから抜き出して、ちょっと 動かしてみるのは、エディターで切り出しても、大差は無いですからね。 Icon入門講座や、Icon日記から、まとめて プログラムを 切り出す のなら あった方が、良いと思うのですが。 でも、YABと YAXはやはり ペアで揃えて 置きたい。ということで、だいぶ前 に作ったプログラムに、コメントを追加して、整えてみました。 -----^ IYAX.ICN ( date:97-04-05 time:22:22 ) --------------- BGM: 愛の言霊/サザン・オールスターズ (icon_209.txt 1997/04/05 PCVAN PIG) ■ Icon > Icon雑記帳(10) 順列 風つかい HB彗星に関するTV番組を、結構やっていますね。 で、彗星は 何処から来るかというので、太陽系から10兆kmあたりまでは、 観測できないが 氷や塵が漂っているそうです。 その辺から太陽系に近づいて来て、太陽の引力に捉えられたものが彗星になって 太陽の周りを回りだすのではないか? という説明をやっていました。 冥王星のあたりが、60億kmですので、そのまた遥か遠くからやって来るので すね。 今日も雨で、HB彗星は見えません。 でも、飛行機で旅行される方は、雲の上 を飛んでらっしゃいますので、ご覧になれる方もいますよね。 さて、以前、文字列の組み合わせを、やりました。 これは、確か高校の頃に やった 順列・組み合わせ と同じものですよね。 nPmとか nCmに、頭を悩ませたものです。 前のプログラムでは、nPnしかやって いませんので、一般化して、nPmの場合のプログラムを作ってみましょう。 stringの順列と listの順列のプログラムを作ってみました。 考え方は、Icon日記(16) Recursive generator と同じです。 生成文字数に 制限を つけないといけない のですが、そこは紙に実際に書き出 して ふむふむ、ここで制限をつければいいんだな...と、やってます。 3P2の場合ですと、 perm("DNA",2) |--> "D" || perm("NA",1) # ここで1文字目 |--> "N" || perm("A",0) # ここで2文字目(後は不要) |---> "" # 3文字目なので空文字で返す。 という風に動きます。 -----^ PERM11.ICN ( date:97-04-06 time:22:24 ) ------------- BGM: 哀愁のカサブランカ/郷ひろみ (icon_210.txt 1997/04/06 PCVAN PIG) ■ Icon > Icon雑記帳(11) 組み合わせ 風つかい 前回、順列をやりましたので、今回は、組み合わせです。 nCmに相当するプログラムです。順列のプログラムと、ほぼ同様のプログラム です。 順列と違って、文字の順番を考慮しませんので、 残りの部分に、同じ処理を加えるために、渡す処理が少し違っています。 3C2の場合ですと、 comb("CPU",2) |--> "C" || comb("PU",1) # ここで1文字目 |--> "P" || comb("U",0) # ここで2文字目(後は不要) |---> "" # 3文字目なので空文字で返す。 という風に動きます。 -----^ COMB11.ICN ( date:97-04-07 time:19:06 ) ------------- BGM: Waltz For Debby / Bill Evans (icon_211.txt 1997/04/07 PCVAN PIG) ■ Icon > Icon雑記帳(12) pipe風のプログラム 風つかい パイプというのは、Unixや MS-DOSでいうパイプのことです。プログラム の間のデータの渡し方で、 data data ------------ stream ------------ stream ------------ | program1 | =====> | program2 | =====> | program3 | ------------ pipe ------------ pipe ------------ 標準 標準 標準 標準 出力 入力 出力 入力 と、つないでいける ものです。 generatorの考え方の説明をしていて、こりゃ〜パイプだ〜と思いました。 generatorのことですから、procedureの間のデータの受け渡し方法のこと になるんですが。 よく似ていますよね。 パイプの場合は、上の図のように、program1と program2は対等な位置 関係になりますが、procedureの場合は、データを渡すところで、対等と いう訳にはいかず、どちらかのプログラムが 他方を呼ぶ/使うという関 係になりますので、 ------------ data ------------ data ------------ | procedure1 | =====> | procedure2 | =====> | procedure3 | ------------ ------------ ------------ は、 - proc1 ---- 呼ぶ/使う - proc2 ---- 呼ぶ/使う - proc3 ---- | | ---- procedure2 | ---- procedure3 | | | / | | / | | | proc2 <-- | <-- | | ------------ 下位 上位 ------------ 下位 上位 ------------ という構成になります。 サンプルとして、ちょっと強引な例ですが、データを発生して、それを フィルターにかけて、出力するものを。 -----^ PIPE01.ICN ( date:97-04-10 time:21:57 ) ------------- pipe.txt pipe03 の出力が標準出力ですので、pipe04 不要ですが、形を合わせるため に入れてあります。(汗) -----^ PIPE02.ICN ( date:97-04-10 time:22:21 ) ------------- BGM: Vivien/篠原美也子 (icon_212.txt 1997/04/10 PCVAN PIG) ■ Icon > Icon雑記帳(13) ビデオ問題は、道遠し 風つかい う〜ん。難しい。 先日から、組み合わせのプログラムを色々試していますが 目標があります。 以前の書きこみにあった、録画ビデオを効率よく、別のビデオテープへ詰め込 む問題が、なんとか解けないかとやっています。 しかし、道は遠いな〜 という状態です。 (PCVANの PIGの テキストデータ会議室に、録画ビデオを 別のテープに 効率良く 詰め込むアルゴリズムは無いか と質問された方が いらっしゃいまし た。 この辺は、それを講座のネタに 使わせて いただいています。) 本屋で、組み合わせ理論の本とか、アルゴリズムの本とかをパラパラめくって みたのですが、この問題は「ナップザック問題」というらしいですね。 ナップザック問題は、ナップザックと荷物があって、一番たくさん詰めるやり 方はどれかというような問題です。 具体的に、どうやって、組み合わせを洗いだすのか、よく分かりません。 この問題を解くプログラムには、ある程度は「しらみつぶし」「総当たり」的 な処理が必要だろうということで、Iconが向いているのは確かだと思うのですが なかなか、手強いです。 今回も、ビデオ問題の習作プログラムとなります。 generatorからデータを受け取り、そのデータを順に組み合わせていく プログ ラムをやってみます。 動作は、コメントを参照して下さい。 -----^ COMB12.ICN ( date:97-04-12 time:10:53 ) ------------- 1 then { # リストが2要素以上だったら every j := 1 to *L[i -1] do { # (i-1)文字リストの要素に put(L[i], comb := (L[i -1][j] || new) ) # 新たな文字を連結し # i文字リストに格納 suspend comb # 追加した文字列を渡す } } else { put(L[1],new) # 1文字リストに、新たな文字を追加 suspend new # 追加した文字を渡す } } } end # ↓データ(文字(列)) # 文字列設定/結果書き出し処理 procedure main(args) # コマンドラインパラメータが無ければ、"ABCD"をソースデータとする。 s := if *args = 0 then "ABCD" else args[1] # すべての組み合わせを書き出す。 every write(glcomb(s)) end -----$ COMB12.ICN ( lines:62 words:198 ) ------------------- BGM: あゝ無情/アン・ルイス (icon_213.txt 1997/04/12 PCVAN PIG) ■ Icon > Icon雑記帳(14) ビデオ問題/組み合わせ 風つかい ビデオ問題の習作プログラムの続きです。 前回の generatorから 受け取った 文字の組み合わせプログラムを、リスト形式データでも 受け取れるように 拡張 したものです。 -----^ COMB13.ICN ( date:97-04-12 time:10:31 ) ------------- 1 then { # 既に、要素があったら、新たな要素 every j := 1 to *L[i -1] do { # と組み合わせて、 put(L[i], comb := (L[i -1][j] ||| [new]) ) # 要素数毎リストに追加 # ↑i要素数リスト ↑(i-1)要素数リスト suspend comb # 組み合わせで生成した要素を返す } } else { put(L[1],[new]) # 1要素リストに、新たに来た要素を追加 suspend [new] # 新たに来た要素を返す } } } end # ↓データ # ソースデータ設定/結果書き出し処理 procedure main() # 文字列データ x := "ABCD" every show_sl(glcombf(gen_elem,x)) # ↑1重リスト書き出し write() # リストデータ x := [["A1","A2","A3"],["B1","B2","B3"],["C1","C2","C3"]] every show_wl(glcombf(gen_elem,x)) # ↑2重リスト書き出し end -----$ COMB13.ICN ( lines:56 words:161 ) ------------------- BGM: トライアングル・ブルー/アン・ルイス (icon_214.txt 1997/04/12 PCVAN PIG) ■ Icon > Icon雑記帳(15) ビデオ問題/簡易解法 風つかい ビデオテープへの録画詰め込み問題は、テープやMDに好きな音楽を詰め込ん だり、トラックに荷物を詰め込んだり、生活していて実際にいろんな場面で遭遇 します。 でも、実際的には、全ての組み合わせを試すのではなく、 ・大きいものから、順に詰めていく。 ・空きがあれば、なるべく大きいものを詰めてみる。 ・空きに、入るものが無くなるまで試す。 というようなやり方もよくやります。 これで、最適といえなくとも、実用的には、そこそこの結果が、得られている のでないかと、思います。このやり方ですと、比較的簡単にプログラムできます。 しかし、Iconでは 多重 listデータ構造がサポートされていますが、無い言語 では 結構 面倒なプログラムになるかも。 録画ビデオのデータ例を引用しておきます。題名と録画時間が行単位に書き込 まれているファイルです。 -----^ SOURCE.DAT ( date:97-03-23 time:19:38 ) -------------0 do { # 録画データが無くなる迄 (Rev.1.2) i +:= 1 # テープ番号を進める。(Rev.1.2) put(L_out,[[0,"分"]]) # i番目テープ詰め込み時間初期値を追加(Rev.1.3) every 1 to *L_data2 do { # 録画データ全部に対して LL := pull(L_data2) # 録画データ取り出し # list末尾から試す。 #(昇順なので末尾の方が録画時間が長い。) if (L_out[i][1][1] +LL[3]) <= t_max then { put(L_out[i],LL) L_out[i][1][1] +:= LL[3] # 録画時間更新 } else { push(L_data2,LL) # データを戻す } } # end of every } # end of while write("詰め込みデータ(先頭は詰め込み時間総和)") show_tl(L_out) end -----$ PACK01.ICN ( lines:65 words:204 ) ------------------- BGM: 美人薄命/アン・ルイス (icon_215.txt 1997/04/12 PCVAN PIG) ■ Icon > Icon雑記帳(16) ビデオ問題/難しい 風つかい ビデオテープへの録画詰め込み問題の習作です。今回は、録画テープのデータ の組み合わせのうち、1本のテープに入る組み合わせを、全て書き出すところ迄 をやってみました。 プログラムは、録画データ読み込み部 (pack02.icn)と、実際に組み合わせを生 成する部分 (pack04.icn)の2つに分けてあります。 まず、録画データ読み込み部分です。 main()はこちらにあります。 -----^ PACK02.ICN ( date:97-04-14 time:20:16 ) ------------- 1 then { # 2つ目以降のデータの場合 # 既に、要素があったら、新たな要素 every j := 2 to *L[i -1] do { # と その要素を組み合わせて、 if (t := (L[i -1][j][1][1] + new[3])) <= t_max then { LL := [[t,"分"]] ||| L[i -1][j][2:0] ||| [new] put(L[i],LL) # 要素数毎リストに追加 # ↑i要素数リスト ↑(i-1)要素数リスト suspend LL # 組み合わせで生成した要素を返す } # end of if } # end of every } # end of if else { # 最初のデータの場合。 LL := [[new[3],"分"]] ||| [new] # ↑録画時間 ↑新要素 put(L[1],LL) # 1要素リストに、新たに来た要素を追加 suspend LL # 新たに来た要素を返す } # end of else } # end of if } # end of every end # ↓データ # pack02.icn の main()で、この pack()を呼んでいる。 procedure pack(L_data,t_max) # L_data # 録画データ list # [j][1]:データNo, [j][2]:録画名称, [j][3]:録画時間 i := 0 # 詰め込みテープ番号 L_out := [] # 詰め込みデータ格納 list # i : テープ番号 # [i][1] : 詰め込み時間 (初期値 : [0,"分"]) # 時間をlistにするのは、show_tlで確認しやすくするため write("録画データ") # 録画データ書出し show_wl(L_data) # 2重 list内容表示 # 組み合わせデータ書出し every show_wl( # ↓every でこの generatorからデータを取り出し。 glcombf(gen_elem,L_data,t_max) ) return # このリターンは無くとも動きます。 #( main()に値を返す構成ではないため) end -----$ PACK04.ICN ( lines:70 words:249 ) -------------------|procedure pack() | | .... | / 呼ぶ | | | pack() ----------------- | | -------------------- --------------------- ↓ icont -c pack02.icn | pack02.u1 ----- link ----->| icont pack04.icn pack02.u2 ↓ pack04.exe と、いうものです。 すなわち、下位の procedureが、入っているファイルが、 上位の procedureが入っているファイルを linkしています。 先に、 icont -c pack02.icnとしておいて、次に icont pack04.icnとして linkし ます。実行ファイル名は、pack04.exeとなります。 逆の、上位プログラムが下位プログラムを linkするやり方は、今までも使ってい たのですが、こういう下位プログラムが上位プログラムを linkするやり方ができる とは、思っていませんでした。 データ読み込み部分は同じで、組み合わせ部分を、色々のやり方のプログラムに 変えられるといいな。 ということで、試してみましたら、できました。 風つかい (TRA11936@biglobe.ne.jp/PFF01531@niftyserve.or.jp) < IconのWWWは、http://www.cs.arizona.edu/icon/index.html> BGM: WOMAN/アン・ルイス (icon_216.txt 1997/04/17 PCVAN PIG) ■ Icon > Icon雑記帳(17) 構造体 tree表示 風つかい 桜は、横浜では、もうすっかり葉桜になっていますが、確か札幌あたりでは、 桜は5月でしたかね。 桜前線を追いかける旅なんてのも、やってみたいもんで すね〜。 さて、今日は、構造体 (list,set,table)の tree表示をやってみます。 Iconでは、listや setや tableの要素に、再び listや setや tableを 含む ことができて、いくらでも 深い階層の構造を作ることできます。 Iconの重要 な特徴の1つだと、思います。 しかし、私の頭では、2重 list位までは、頭に浮かべられますが、3重の listともなると、なかなかサットは思い浮かびません。 プログラムを書いたその時は、分かっているのですが、しばらく後になると、 もう自分の書いたプログラムの データ構造が、理解できなくなっています。 コメントで、シッカリとデータ構造を書いておけば良いのですが、そのために はプログラムの行より、コメントの行の方が、多すぎるくらいになります。 コメントの間にプログラムが、ぽつぽつと存在するような状態になって、これ また 読解性が、落ちることになります。 ということで、階層構造を持つ構造体を tree状に表示するプログラムを作っ てみました。 Recursive generatorを使って、再帰的に データ構造を書出して いきます。 treeの最初の列の書出しが、再帰構造に含め切れませんでしてので、少し 分か りにくくなってしまいました。 また stringの内容表示 のところにも、image()という 表示可能な文字 なら そのまま 表示し そうで無ければ 16進数表示 を行う 関数を、使いたかった のですが、シフトJIS対応では無いので、使っていません。 この関数をシフトJIS対応にした procedureを、作らないといけませんね。 -----^ X2TREE01.ICN ( date:97-04-23 time:21:05 ) -----------" # xのタイプを書出し suspend " " || x2tree(x) # tree化処理 # ↑tree書出し初期位置 end procedure x2tree(x) # generator # show the tree structure of x n := *x # xのサイズ(末尾要素検出用) every xx := !x do { # 構造体の要素を1つづつ取り出す n -:= 1 # 要素カウンタ−1 case t := type(xx) of { # 構造体のタイプにより、 "string" : suspend "+ " || left(t,7) || " " || xx # jimageを作らなきゃ。↑ "list" | "set" | "table" : { # この場合は、再度構成要素を解析 suspend "+ <" || t || ">" #↓最後の要素でないなら if n > 0 then suspend "| " || x2tree(xx) else suspend " " || x2tree(xx) } #↑list,set,tableなら、typeを書出して、その中身をまた解析する。 default : suspend "+ " || left(t,7) || " " || image(xx) # ↑その他なら、typeと値を書き出す。 } } end # test driver procedure main() L := ["A",[],"B",10.5,["C","D",set(["X","Y"]),["E","F",127],"G"],"H"] every write(x2t(L)) end -----$ X2TREE01.ICN ( lines:41 words:157 ) ----------------- x2tree01.txtとした時の結果です。 -----^ X2TREE01.TXT ( date:97-04-23 time:00:30 ) ----------- + string A + + string B + real 10.5 + | + string C | + string D | + | | + string X | | + string Y | + | | + string E | | + string F | | + integer 127 | + string G + string H -----$ X2TREE01.TXT ( lines:17 words:60 ) ------------------ BGM: The Other Side of Love / Ryuichi Sakamoto featuring Sister M (icon_217.txt 1997/04/27 PCVAN PIG) ■ Icon > Icon雑記帳(18) jimage.icn 風つかい 近ごろ書く プログラムには、殆ど generatorを 使っています。つい先頃まで は、この generatorを、どういう風に使ったら 良いのか 分かりませんでした。 今は、便利なんで、使えない所以外は、使ってしまう。 という状態です。 listは、Icon教典 (The Icon Programming Language)を読んだだけで、これは 便利だ と分かりました。 しかし、generatorの便利さは、使っているとジワジワと効いてくる。 なんつ うか、漢方薬の効能書きみたいな良さです。 使ってみないと、わかりませんでしたが、なかなかのスグレモノです。 こういう良さは、どう説明していけばいいんでしょうかね。やっぱり、実例を 沢山書いていくしかないんでしょうね〜。 というところで、今回は image()関数を SHIFT-JIS対応にした procedureを作 ってみます。 SHIFT-JISの文字列を解析する procedureは、Icon日記で 作って いますので、比較的簡単に、SHIFT-JIS対応にできます。 プログラムを次にあげます。 データタイプが string以外では、image()を、 そのまま使っています。 -----^ JIMAGE.ICN ( date:97-04-27 time:19:37 ) -------------" suspend " " || x2tree(x) end procedure x2tree(x) # generator # show the tree structure of x n := *x every xx := !x do { # 構造体の要素を1つづつ取り出す n -:= 1 case t := type(xx) of { # 構造体のタイプにより、 "string" : suspend "+ " || left(t,7) || " " || jimage(xx) "list" | "set" | "table" : { suspend "+ <" || t || ">" if n > 0 then suspend "| " || x2tree(xx) else suspend " " || x2tree(xx) } # 再帰↑ #↑list,set,tableなら、typeを書出して、その中身をまた解析する。 default : suspend "+ " || left(t,7) || " " || image(xx) # ↑その他なら、typeと値を書き出す。 } } end # test driver #procedure main() # L := ["A",[],"B",10.5,["C","D",set(["X","Y"]),["E","F",127],"G"],"H"] # every write(x2t(L)) #end -----$ X2TREE02.ICN ( lines:39 words:152 ) ----------------- + | + | | + integer 352 | | + string "分" | + | | + integer 4 | | + string "あなただけ今晩は" | | + integer 137 | + | | + integer 3 | | + string "セルピコ" | | + integer 130 | + | + integer 6 | + string "スタンドバイミー" | + integer 85 + | + | | + integer 357 | | + string "分" | + | | + integer 8 | | + string "スティング" | | + integer 129 | + | | + integer 2 | | + string "暴力脱獄" | | + integer 127 | + | + integer 5 | + string "天国からきたチャンピオン" | + integer 101 + + | + integer 357 | + string "分" + | + integer 9 | + string "グッドモーニングベトナム" | + integer 121 + | + integer 7 | + string "フランキー&ジョニー" | + integer 118 + + integer 1 + string "ジャスティス" + integer 118 -----$ PACK05.TXT ( lines:50 words:185 ) ------------------- BGM: Vivien/篠原美也子 (icon_218.txt 1997/04/27 PCVAN PIG) ■ Icon > Icon雑記帳(19) 構造体 tree表示(2) 風つかい Iconの構造体(list,set,table)は、その要素にまた list,set,tableを持てます が、自分自身をその要素に持つこともできます。 再帰的な構造 とでも いいまし ょうか。 どんな場合に使うかというと、例えば再帰構成のプログラムの構造を、 表わそうと すると、再帰的な構造体が必要になります。 前に作った tree表示のプログラム(x2tree01.icn, x2tree02.icn)は、そういう 構造体の場合でも、素直に表示していきますので、延々 treeを書き出します。 サンプルプログラムを次に示します。 延々書き出されても困るので、generatorの生成数限定指定で、20個迄として います。 -----^ RECUR01.ICN ( date:97-04-30 time:09:09 ) ------------recur01.txtとした時の結果です。 -----^ RECUR01.TXT ( date:97-04-30 time:09:18 ) ------------ + string "A" + string "B" + | + string "C" | + string "D" | + | + string "E" | + string "F" | + | + string "A" | + string "B" | + | | + string "C" | | + string "D" | | + | | + string "E" | | + string "F" | | + | | + string "A" -----$ RECUR01.TXT ( lines:20 words:75 ) -------------------" #↑listの serial No suspend " " || x2tree(x) end procedure x2tree(x) # generator # show the tree structure of x static S # serial No 登録用 initial { S := set([serial(x)]) # serial Noを Sに登録 } n := *x # 枝の末端検出用 every xx := !x do { # 構造体の要素を1つ づつ取り出す n -:= 1 case t := type(xx) of { # 構造体のタイプにより、 "string" : suspend "+ " || left(t,7) || " " || jimage(xx) #↓list,set,tableなら、typeを書出して、その中身をまた解析する。 "list" | "set" | "table" : { if not member(S,m := serial(xx)) then { # 再帰構造で なければ # Sに既に登録済みなら再帰構造 insert(S,m) # serial Noを Sへ登録 suspend "+ <" || t || " " || string(m) || ">" suspend (if n > 0 then "| " else " ") || # Rev.1.2 if...then #↑枝の途中 #↑枝の末端 # else...の冗長修正 x2tree(xx) do delete(S,m) # 再帰↑ #↑登録を削除 } else { # 再帰構造 ならば、書き出すとキリが無いので打止め return "+ <" || t || " " || string(m) || "> (Recursion)" } } #↓その他なら、typeと値を書き出す。 default : suspend "+ " || left(t,7) || " " || image(xx) } } end # test driver #procedure main() # L1 := ["A","B"] # L2 := ["C","D"] # L3 := ["E","F"] # put(L1,L2) # put(L2,L3) # put(L1,L3) # suspend doが働いているかのテスト # put(L3,L1) # Recursiveの stopperが働いているかのテスト # every write(x2t(L1) \20) # \20は、テストをドジッた時に、20個で止めるため。 #end -----$ X2TREE03.ICN ( lines:58 words:257 ) -----------------recur02.txtとした時の結果です。 -----^ RECUR02.TXT ( date:97-05-01 time:10:07 ) ------------ + string "A" + string "B" + | + string "C" | + string "D" | + | + string "E" | + string "F" | + (Recursion) + + string "E" + string "F" + (Recursion) -----$ RECUR02.TXT ( lines:14 words:49 ) ------------------- BGM: 河よりも長くゆるやかに/篠原美也子 (icon_219.txt 1997/04/30 PCVAN PIG) ■ Icon > Icon雑記帳(20) dir2tree(1) 風つかい せっかく、tree表示のプログラムを 書きましたので、以前から やりたかった directoryの tree表示もやってみましょう。 MS-DOSの、dir /s コマンドで、directory情報を 再帰的に 得ること が でき ます。 この情報を tree表示してみます。 MS-DOSの、dir /s で、次のようなデータが得られます。 sub-directory内の fileや sub-directoryの情報が、順次でてきます。 d:\icon\lec24が current directoryの時に dir /s test_a とした 時の 結果 です。 -----^ TEST_A_D.TXT ( date:97-05-03 time:00:33 ) ----------- 97-04-29 21:51 . .. 97-04-29 21:51 .. TEST_B 97-04-29 21:52 TEST_B BBB TXT 10 97-04-29 21:56 BBB.TXT TEST_CCC TXT 15 97-04-29 21:57 TEST_CCC.TXT TEST_C 97-04-29 21:55 TEST_C AAA 6 97-04-29 21:56 AAA 3 個 31 バイトのファイルがあります ディレクトリは D:\ICON\LEC24\TEST_A\TEST_B . 97-04-29 21:52 . .. 97-04-29 21:52 .. HHH TXT 10 97-04-29 21:59 HHH.TXT TEST_D 97-04-29 21:52 TEST_D TEST_III TXT 15 97-04-29 22:00 TEST_III.TXT GGG 6 97-04-29 21:59 GGG 3 個 31 バイトのファイルがあります ディレクトリは D:\ICON\LEC24\TEST_A\TEST_B\TEST_D . 97-04-29 21:52 . .. 97-04-29 21:52 .. KKK TXT 10 97-04-29 22:01 KKK.TXT TEST_LLL TXT 15 97-04-29 22:02 TEST_LLL.TXT JJJ 6 97-04-29 22:01 JJJ 3 個 31 バイトのファイルがあります ディレクトリは D:\ICON\LEC24\TEST_A\TEST_C . 97-04-29 21:55 . .. 97-04-29 21:55 .. EEE TXT 10 97-04-29 21:58 EEE.TXT TEST_FFF TXT 15 97-04-29 21:58 TEST_FFF.TXT DDD 6 97-04-29 21:58 DDD 3 個 31 バイトのファイルがあります 一覧のファイル総数: 12 個 124 バイトのファイルがあります 11 ディレクトリ 3,391,488 バイトの空きがあります -----$ TEST_A_D.TXT ( lines:46 words:161 ) ----------------- + + string "D0" + string "A0" + | + string "D1" | + | + string "D1" | + string "B0" | + | | + string "D2" | | + | | + string "D2" | | + string "C0" | | + string "C1" | + string "B1" + string "A1" T + | + string "D2" | + | + string "D2" | + string "C0" | + string "C1" + + string "D1" + + string "D1" + string "B0" + | + string "D2" | + | + string "D2" | + string "C0" | + string "C1" + string "B1" -----$ TEST220B ( lines:38 words:134 ) --------------------- BGM: La Fiesta / Chick Corea (icon_220.txt 1997/05/03 PCVAN PIG) ■ Icon > Icon雑記帳(21) dir2tree(2) 風つかい directoryの tree表示 programの続きです。 実験が、うまくいきましたので 次は、実際の programです。 ・dir /s のコマンド発行、結果の取り入れ ・結果の listへの変換、親子関係に従って link ・結果の表示(別の procedure) の構成になっています。 -----^ DIR2TREE.ICN ( date:97-05-03 time:13:22 ) ----------- 0 then args[1] else "" tmp := "$$$tmp.$$$" # テンポラリファイル名設定 # ↓環境変数に、テンポラリーディレクトリ名が、設定してあればファイル名 # の前に追加 if s := getenv("TMP") then tmp := s || "\\" || tmp # コマンドラインの ディレクトリー名指定 をもとに、"dir /s" コマンド を # 発行して tmpへ出力 system("dir /s " || dir_name || " >" || tmp) # directory data sample ↓こんなデータが tmpに格納されます。 #1 16 #ディレクトリは D:\ICON\LEC24\TEST_A # #. 97-04-29 21:51 . #.. 97-04-29 21:51 .. #TEST_B 97-04-29 21:52 TEST_B #BBB TXT 10 97-04-29 21:56 BBB.TXT #TEST_CCC TXT 15 97-04-29 21:57 TEST_CCC.TXT #TEST_C 97-04-29 21:55 TEST_C #AAA 6 97-04-29 21:56 AAA # 3 個 31 バイトのファイルがあります # #一覧のファイル総数: ###################### # dir /s (dir_name)結果から、directory毎の情報を listへ 登録 ###################### dir := open(tmp) | stop("cannot open " || tmp) # tmpファイルオープン L_dir := [] # directory情報登録用 list T_dir := table() # sub-directory list参照 table while line := read(dir) do { # directory情報を directory毎に、一旦 list(LL)にまとめて、登録する。 line ? { #↓listにまとめた directory情報を登録 if find("個") then put(\T_dir[c_dir] | L_dir,LL) #↑tableに c_dirが存在すれば if match(" ") then next # ごみ行を無視 if match("一") then break # "一覧の..."が来たら終わり L := p_split() # lineを " "で分割→[1]:開始位置 # [2]:要素 #↓lineの1番目の要素 case L[1][2] of { "ディレクトリは" : { LL := [] # directory data buffer # ↓lineの2番目の要素の開始位置 c_dir := line[L[2][1] : 0] put(LL,[c_dir]) #↑listにして LLに追加 } "." : next # 無視 ".." : put(LL[1],line) # その directory自身の情報。 # トップの directory以外では必要 # ないが、全てにつき格納 default : { if find("") # sub-directoryだったら then { put(LL,LLL := [line]) # 内容を bufferに追加 insert(T_dir,c_dir || "\\" || L[1][2] ,LLL) # ↑sub-directory名称を keyにして tableへ登録 } else put(LL,line) # 通常 fileならそのまま追加 } } # end of case } # end of line ? } # end of while close(dir) remove(tmp) # delete tmp ####################### # directory情報の表示 ####################### # every write(x2t(L_dir)) # list内容確認用表示 # stop() every write(d2t(L_dir)) end ######################## # directory tree表示 ######################## procedure d2t(L) # top directoryの名前/time_stamp処理 L1 := get(L) # Lには1個しか要素が無い。それを取り出す。 L2 := get(L1) # そのまた top (directory_name,time_stamp)を取り出す。 suspend L2[1] || L2[2][14:-3] # top directoryの名前と time stamp suspend " " || d2tree(L1) # tree化処理 # ↑tree書出し初期位置 end procedure d2tree(L) # directoryの処理 # show the tree structure of directory n := *L # Lのサイズ(末尾要素検出用) every LL := !L do { # listの要素を1つづつ取り出す n -:= 1 # 要素カウンタ−1 case t := type(LL) of { # 要素のタイプにより、 "string" : suspend "+ " || LL # file "list" : { # sub-directory suspend "+ " || get(LL) # sub-directory自体表示 LLL := get(LL) # sub-directoryの中身を取り出し get(LLL) # 先頭要素を読み飛ばし #↓最後の要素でないなら suspend (if n > 0 then "| " else " ") || d2tree(LLL) } default : stop("error") } } end ######################## # stringを cを区切りにして分割して、開始位置と要素を返す。 ######################## # 動作は、Icon入門講座(7) Iconの特徴(5)スキャンを参考にして下さい。 procedure p_split(line,c) /c := ' \t' # default /line := &subject # default list := [] # 戻り値用 list line ? { while tab(ps := upto(~c)) do put(list,[ps,tab(pe := many(~c))]) } return list end -----$ DIR2TREE.ICN ( lines:134 words:505 ) ---------------- BGM: La Fiesta / Chick Corea (icon_221.txt 1997/05/03 PCVAN PIG) ■ Icon > Icon雑記帳(22) dir2tree(3) 風つかい directoryの tree表示 programの続きです。 sub-directory毎の listを連結 しますと、次のような listができます。 前回の program中で、コメントアウトしてある list内容表示を 生かしたとき の結果です。 尚、test時に linkする x2tree04は、x2tree03で 階層毎の 列 の進みを 縮める修正をしたものです。 この listの中には 冗長な情報が ありますので 表示programで 削って 表示し ます。 -----^ TEST_A_L.TXT ( date:97-05-03 time:11:27 ) ----------- + + | +string "D:\ICON\LEC24\TEST_A" | +string ".. 97-04-29 21:51 .." + | +string "TEST_B 97-04-29 21:52 TEST_B" | + | + | | +string "D:\ICON\LEC24\TEST_A\TEST_B" | | +string ".. 97-04-29 21:52 .." | +string "HHH TXT 10 97-04-29 21:59 HHH.TXT" | + | | +string "TEST_D 97-04-29 21:52 TEST_D" | | + | | + | | | +string "D:\ICON\LEC24\TEST_A\TEST_B\TEST_D" | | | +string ".. 97-04-29 21:52 .." | | +string "KKK TXT 10 97-04-29 22:01 KKK.TXT" | | +string "TEST_LLL TXT 15 97-04-29 22:02 TEST_LLL.TXT" | | +string "JJJ 6 97-04-29 22:01 JJJ" | +string "TEST_III TXT 15 97-04-29 22:00 TEST_III.TXT" | +string "GGG 6 97-04-29 21:59 GGG" +string "BBB TXT 10 97-04-29 21:56 BBB.TXT" +string "TEST_CCC TXT 15 97-04-29 21:57 TEST_CCC.TXT" + | +string "TEST_C 97-04-29 21:55 TEST_C" | + | + | | +string "D:\ICON\LEC24\TEST_A\TEST_C" | | +string ".. 97-04-29 21:55 .." | +string "EEE TXT 10 97-04-29 21:58 EEE.TXT" | +string "TEST_FFF TXT 15 97-04-29 21:58 TEST_FFF.TXT" | +string "DDD 6 97-04-29 21:58 DDD" +string "AAA 6 97-04-29 21:56 AAA" -----$ TEST_A_L.TXT ( lines:35 words:195 ) ----------------- 97-04-29 21:51 + TEST_B 97-04-29 21:52 TEST_B | + HHH TXT 10 97-04-29 21:59 HHH.TXT | + TEST_D 97-04-29 21:52 TEST_D | | + KKK TXT 10 97-04-29 22:01 KKK.TXT | | + TEST_LLL TXT 15 97-04-29 22:02 TEST_LLL.TXT | | + JJJ 6 97-04-29 22:01 JJJ | + TEST_III TXT 15 97-04-29 22:00 TEST_III.TXT | + GGG 6 97-04-29 21:59 GGG + BBB TXT 10 97-04-29 21:56 BBB.TXT + TEST_CCC TXT 15 97-04-29 21:57 TEST_CCC.TXT + TEST_C 97-04-29 21:55 TEST_C | + EEE TXT 10 97-04-29 21:58 EEE.TXT | + TEST_FFF TXT 15 97-04-29 21:58 TEST_FFF.TXT | + DDD 6 97-04-29 21:58 DDD + AAA 6 97-04-29 21:56 AAA -----$ TEST_A_T.TXT ( lines:16 words:115 ) ----------------- BGM: La Fiesta / Chick Corea (icon_222.txt 1997/05/03 PCVAN PIG) ■ Icon > Icon雑記帳 むすび 風つかい 雑記帳では、テキスト解析をやろうと思っていたのですが、殆ど generatorの 解説になってしまいました。 4月も終わったことですので、雑記帳は おしまいとします。(全然、説明に なっていない。(汗)) 今シリーズでは、私は generatorサルになってしまいました。 前シリーズの Icon日記で generatorの使い心地の良さを 知ってしまってから、もう 離れられ ません。 【イケイケ評価】(Goal-directed evaluation)の威力は、generatorを 使って みないと分かりませんね。 会話に使う言葉にしても、その地方地方の 言葉(方言)でないと 表わせない ものって ありますよね。 私の母国語の博多弁では、他の方言にはみかけない「進行形」の表現がありま す。 「〜よる。」という表現です。 「行きよる。」= 行きつつある。行く途中である。 この表現が使いこなせると、あなたも、博多弁の達人です。(笑) Iconにも そういう独特の【Iconでなければ表わせない】表現が あると思いま す。これは、ある程度、そのプログラムに、はまってみないと、分からない感覚 だと思います。 さて、Icon山の周りの茂みを さまよって、なかなか テキスト解析への登り道 へ たどりつけませんが、次のシリーズでは、是非、テキスト解析を やってみま しょう。 次のシリーズのタイトルは、Icon散歩道 としようかと思います。 Icon迷い道 の方が合っていると思いますが、それじゃあんまりですので。(笑) では、また、お会いする日まで。 風つかい (TRA11936@biglobe.ne.jp/PFF01531@niftyserve.or.jp) < IconのWWWは、http://www.cs.arizona.edu/icon/index.html> BGM: いとおしいグレイ/篠原美也子 BGD: お〜い お茶 (icon_223.txt 1997/05/03 PCVAN PIG)