ファイルの読み書きとファイル構造 (2008.02.26) 1 基本 temp.lib:=["a","b","c"] とすると, 1)ファイルの中では,"a"改行"b"改行"c"改行となってます. このファイルをテキストエディタで開くと, "a" "b" "c" と表示されます. 2)もちろん,A:=temp.lib とすると,A=["a","b","c"] に戻ります. 3)project(temp.lib,3)="c"になります. 4)教科書未記載ですが, 述語 xread("temp.lib", [A]) で,temp.libの内容が変数Aに代入されます. この場合は,A:=xread("temp.lib")と書けません. 2 ファイルを空にできない. temp.lib:=[ ]; とすると,ファイルtemp.libに"nil"が代入される. 今の所,これが仕様のようです.ファイルを空にするには, テキストエディタで手作業で内容を削除するか,または OSに戻って,ファイルを削除し,新規にファイルを作成する 方法しかないようです. 3 読んで書くか,書いて読むか. 1)教科書p.274の getOrderId() では, 「ファイルを読み込んで処理して書き込む」ことをしています. 書いて読むのでなく,読んで書いているだけなので成功します. 教科書は間違っていません. 2)一方,書いた直後の「読み」が無効です. temp.lib:=[1,2,3], N:=cardinality(temp.lib), のとき,N=3 のはずですが,なりません. 理由は,書き込み速度が遅いからかも知れませんが, 実際のところ分かりません. 上記の例では, P:=[1,2,3], N:=cardinality(P), temp.lib:=P, とすれば回避できます. [注1] 書いた直後にそれを読むことは,実際にはほとんどありえないレアケースです. それでも,無理やりそれをしたいときは, ワンテンポ遅らせて,状態遷移後に読めば正しくN=3になります. または,資料「Solverの関数化」のoutのように,別途関数を作れば成功します. func([out]); out("temp.lib")=N <-> N:=cardinality(temp.lib); と定義しておいて,モデルのなかで, temp.lib:=[1,2,3], N:=out("temp.lib"), とすれば成功します. 4 巨大なファイルは「教科書のやり方」では扱えない. 例えば,ファイル temp.lib の内容が1万行を超えると, B:=temp.lib や Bs.g:=temp.lib は無効です. N:=cardinality(temp.lib)は無効です. ファイルサイズが大きすぎると変数に代入できないからです. しかし,代入しないで直接的にファイルを触ることはできます. 次の5や6を参考にしてください. 5 1万行以上のファイル temp.lib でも,次の述語が有効です. xread("temp.lib", K, L, [X])ファイルのK行からL行までを変数Xに代入する. appendf("temp.lib","a", [Y]) ファイルの最終行にデータYを追加する. appendf("temp.lib","w", [Y]) ファイルの内容全部をデータYに置き換える. 変数に[ ]がついていることに注意すること. 6 1万行以上のファイル temp.lib に対しては,行数を数える述語 cardinalityf("temp.lib",N) を用意しました.この形でNにtemp.libの行数が代入されます. 10万行のとき,20秒以上かかります. 遅いですが,どうしても必要なら使ってください. simcast.zipの中のstdAutomatonEngine.pに直接追加していますので, コードを見ることは可能です.