2D とは

  • ICFP プログラミングコンテストで使われたプログラミング言語

ICFP プログラミングコンテストの問題

メモ

いわゆる Hello, world! は書けません。文字出力ないから。

たぶん最小プログラムはこれ。

,...............,
:main           :
:*=============*:
:!send [((),E)]!-
:*=============*:
,...............,

単純な仕様

send []
  nothing happens.
  何も起こらない。

send [(val, outface)]
  val is sent along the specified outface.
  val は指定された outface に送られる。

send [(val1, outface1), (val2, outface2)]
  val1 is sent to outface1, and val2 is sent to outface2.
  val1 は outface1 に送られる。val2 は outface2 に送られる。
  The two outfaces may not be equal.
  2つの outface は異なっていなければならない。

split (val1, val2)
  val1 is sent south, and val2 is sent east.
  val1 は南(S)に送られる。val2 は東(E)に送られる。

case Inl val of outface1, outface2
  val is sent to outface1.
  val は outface1 に送られる。

case Inr val of outface1, outface2
  val is sent to outface2.
  val は outface2 に送られる。

use mod
  a new instance of the module mod is evaluated. The inputs to
  the module must match the inputs to this box, and are instantiated
  with the values along those wires. The output along the east
  face is the output of the module instance.
  mod モジュールの新しいインスタンスが評価される。
  モジュールへの入力はこのボックスの入力と一致していなければならない。
  モジュールはこのボックスの配線の値でインスタンス化される。
  東面(E)の出力がモジュールインスタンスの出力となる。

参考

  • 裸のコマンドは実行できない。
*=============*
!send [((),E)]!
*=============*
[2D] Parse Error:  Stray character * at (ln: 1, col: 0).
  • モジュールの S からの出力はできない。E のみ。
,...............,
:main           :
:*=============*:
:!send [((),S)]!:
:*=============*:
,........|......,
[2D] Parse Error: No outputs allowed along S side of module (ln: 6, col: 9).
  • 2つ出力はできない。
    • case などで複数出力されているように見える場合があるが、その場合は片方しか評価されていない。
,...................,
:main               :
:*=============*    :
:!send [((),E)]!-----
:*=============*    :
:*=================*:
:!send [(Inr (),E)]!-
:*=================*:
,...................,
[2D] Eval Error : A module had multiple outputs!
  • コマンドで同じ面から2つの入力は受け取れない。(A or B のような受け取り方は不可)
    • 片方が評価されなくてもダメ。
    • 分岐を合流させたければ、モジュール化するのがよい。
,...................................,
:main                               :
:*===============*                  :
:!send[(Inl(),S)]!                  :
:*===============*                  :
: |                                 :
: v                                 :
:*=============*   *===============*:
:!case N of S,E!-->!send[(Inr(),S)]!:
:*=============*   *===============*:
:           |       |               :
:           v       v               :
:          *===========*            :
:          !send[(N,E)]!-------------
:          *===========*            :
,...................................,
[2D] Parse Error: Box with upper left corner at (ln: 13, col: 11)
  has more than one north input
  • "()" はこれ以上分解も判定もできない。(split も case も使えない)
    • ということは正常処理としてのエラー判定は不可。実行時エラーで落ちるか、ある階層以下は怪しげな状態のままで処理される…
    • Inr () としてターミネートするのが逃げのようだ。Inl Inr Inl Inr () のようなものは Inl Inr () と等価とみなされてしまう。
  • split を使うべきか、case を使うべきかをデータを見て判定できない。
    • データ構造をあらかじめ知っていないと処理できない。

send コマンド

send コマンドの出力を単純に無視することはできない。

,.........................................,
:main                                     :
:*=================*  *=================* :
:!send [(Inl (),E)]!  !send [(Inr (),E)]!--
:*=================*  *=================* :
,.........................................,
[2D] Eval Error : box send [(Inl (),E)] used an output interface that doesn't exist

send コマンドの入力を無視するのはOK。不要なものはダミー入力が必要?

,.........................................,
:main                                     :
:*=================*  *=================* :
:!send [(Inl (),E)]!->!send [(Inr (),E)]!--
:*=================*  *=================* :
,.........................................,
Result:
Inr ()

case コマンド

case は、以下の構文になる。

case 入力 of 出力l,出力r

case は Inl exp か Inr exp を受け取り、先頭の Inl, Inr を取り除いて、 Inl なら出力l、Inr なら出力rに出力する。

Inl var の場合

,.........................................,
:main                                     :
:*=================*                      :
:!send [(Inl (),S)]!                      :
:*=================*                      :
:       |                                 :
:       v                                 :
:*=============*  *=====================* :
:!case N of S,E!->!send[((((),()),W),E)]!--
:*=============*  *=====================* :
:       |                                 :
:       |         *=====================* :
:       +-------->!send[((W,((),())),E)]!--
:                 *=====================* :
,.........................................,
Result:
((),((),()))

Inr var の場合

,.........................................,
:main                                     :
:*=================*                      :
:!send [(Inr (),S)]!                      :
:*=================*                      :
:       |                                 :
:       v                                 :
:*=============*  *=====================* :
:!case N of S,E!->!send[((((),()),W),E)]!--
:*=============*  *=====================* :
:       |                                 :
:       |         *=====================* :
:       +-------->!send[((W,((),())),E)]!--
:                 *=====================* :
,.........................................,
Result:
(((),()),())

Inr, Inl 以外を case に渡すとエラー。

,.........................................,
:main                                     :
:*=============*                          :
:!send [((),S)]!                          :
:*=============*                          :
:       |                                 :
:       v                                 :
:*=============*  *=====================* :
:!case N of S,E!->!send[((((),()),W),E)]!--
:*=============*  *=====================* :
:       |                                 :
:       |         *=====================* :
:       +-------->!send[((W,((),())),E)]!--
:                 *=====================* :
,.........................................,
[2D] Eval Error : Wrong Form - A case was passed ()!
,.........................................,
:main                                     :
:*==================*                     :
:!send [(((),()),S)]!                     :
:*==================*                     :
:       |                                 :
:       v                                 :
:*=============*  *=====================* :
:!case N of S,E!->!send[((((),()),W),E)]!--
:*=============*  *=====================* :
:       |                                 :
:       |         *=====================* :
:       +-------->!send[((W,((),())),E)]!--
:                 *=====================* :
,.........................................,
[2D] Eval Error : Wrong Form - A case was passed ((),())!

評価されないなら、case の先がなくてもよい。

,.........................................,
:main                                     :
:*=================*                      :
:!send [(Inr (),S)]!                      :
:*=================*                      :
:       |                                 :
:       v                                 :
:*=============*  *=====================* :
:!case N of S,E!->!send[((((),()),W),E)]!--
:*=============*  *=====================* :
,.........................................,
Result:
(((),()),())

split コマンド

split exp は (var1, var2) を受け取り、S に var1 を、E に var2 を出力する。

,......................................,
:main                                  :
:*=======================*             :
:!send [(Inr (),((),()))]!             :
:*=======================*             :
:       |                              :
:       v                              :
:   *=======*                          :
:   !split N!----+                     :
:   *=======*    v                     :
:       |   *========================* :
:       +-->!send[((Inl W, Inl N),E)]!--
:           *========================* :
,......................................,
Result:
(Inl Inr (),Inl ((),()))

split は (var1, var2) 以外は受け取らない。

,......................................,
:main                                  :
:*=============*                       :
:!send [((),S)]!                       :
:*=============*                       :
:       |                              :
:       v                              :
:   *=======*                          :
:   !split N!----+                     :
:   *=======*    v                     :
:       |   *========================* :
:       +-->!send[((Inl W, Inl N),E)]!--
:           *========================* :
,......................................,
[2D] Eval Error : Wrong Form - A split was passed ()!
,......................................,
:main                                  :
:*=================*                   :
:!send [(Inr (),S)]!                   :
:*=================*                   :
:       |                              :
:       v                              :
:   *=======*                          :
:   !split N!----+                     :
:   *=======*    v                     :
:       |   *========================* :
:       +-->!send[((Inl W, Inl N),E)]!--
:           *========================* :
,......................................,
[2D] Eval Error : Wrong Form - A split was passed Inr ()!

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2006-10-11 (水) 15:19:46 (1427d)