ファイルの読み書きとファイル構造 (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に直接追加していますので,
コードを見ることは可能です.