セクション

Coqのセクションという機能を使うとグローバル変数みたいなのを使えます。

Section Hoge.
  Variable x : nat.

  Definition foo := x + 1.
  Definition bar := foo + 2.
  (* Section の中では x はグローバル変数みたいに使える *)
End Hoge.

(* Section を閉じると、foo と bar は x を引数にとるようになる *)
Definition baz := bar 42.

この機能とポインタを一緒に使うと変更できるグローバル変数みたいに使えます。

Section Foo.
  (* 最後にスロット8に置いた、ヒーラー。まだ置いてなければ None *)
  Variable heal_4095_at_8 : ptr (option value).

  (* スロットnにヒーラーが設置されている? *)
  Definition check_healer n : aicmd bool :=
    v <- myfld n; (* 自分とこのスロットnを読む *)
    v' <- AiRead heal_4095_at_8; (* スロット8に置いたかどうか *)
    match v' with
    | Some v'' => ret (eqvalue v v'')
    | None => ret false
    end.

  Definition make_healer :=
    ifb check_healer 8
    then
      ret tt
    else
      arun 8 (...);; (* がんばってヒーラーを作る *)
      v <- myfld 8;; (* できあがった値を読み出す *)
      AiWrite heal_4095_at_8 (Some v). (* ポインタに覚えておく *)
End Foo.

みたいな感じ。これは未来のプログラム言語に違いない!

cmdexの中ではポインタの操作はできないので、ためしにcmdexを実行してうまくいくか試すなんてことができるはず。でも本当は複数のarunをグループ化してそれをしたいわけなので、ポインタ部分はaicmdから分離すべき。

今の実装は公理の中に

Axiom ptr : Type -> Type.
Axiom make_ptr  : forall {T}, T -> ptr T.
Axiom read_ptr  : forall {T}, ptr T -> T.
Axiom write_ptr : forall {T}, ptr T -> T -> unit.

が入っているので、実はどこからでも操作できたりする。これをちゃんとモナドの中に入れた公理にするのはTODO。