ふと思い立ってλ計算の簡約器を XSLT で実装してみている(たぶんできる)
pretty print ができたので、簡約用に de bruijn index にするか
lo48576/xslt10-lambda-calculus: [experimental] Lambda calculus by XSLT
https://github.com/lo48576/xslt10-lambda-calculus
XSLT は純粋関数型言語なので、簡単に de bruijn index 化が実装できた(???)
ワンステップ簡約ならできそうだけど、一気に簡約するなら exslt の拡張を使わないと厳しそうだ (簡約後の XML ツリーを再度テンプレートに投げて変換みたいなことをしないといけないので)
ワンステップ簡約でも、変数の shift とか代入にどうやら exsl:node-set が欲しいので、もうあきらめて使うことにする
XSLT プログラミング、デバッグがめっちゃ面倒なんだが……
やはり快適なデバッグのためには評価途中の処理系の状態や変数が覗き見できる必要がある、自分で XSLT 処理系を作るしかない……
ワンステップ評価できた
(λ λ (λ λ $2) $1 ($2 $1))
を簡約すると
(λ λ (λ $NaN) ($2 $1))
になった、うれしい(しろめ)
exsl:node-set() の挙動がアレすぎてドツボに嵌まっている
exsl:node-set($var) が新しいドキュメント扱いされてルートが変わるところまでは理解できるんだけど、その結果マッチされるのが var に突っ込んでいない xsl:template[@ match=/] で吐いたはずの要素だったりして、意味がわからん
デバッグ用コードを最初から綺麗に埋め込んで書き直したところ、やっとバグの特定に至ったっぽい (ただしまだ修正していないので当たりかは不明)
当たりだった
普通の評価器実装できた、もう少し整理したら push する
lo48576/xslt10-lambda-calculus: [experimental] Lambda calculus by XSLT
https://github.com/lo48576/xslt10-lambda-calculus
できた (いま README 書いてる)
ひととおり必要なものは整備できたので、 Y コンビネータあたりを使うクソデカテストケースを用意したい気持ちになった
SKI コンビネータからの変換も書くか……
どうせなら変数定義があった方がいい?
先にη変換を実装した方がよさそう (テストケースの作り方的に)
Merge branch 'feature/eta-reduction' into develop · lo48576/xslt10-lambda-calculus@82ab57d
https://github.com/lo48576/xslt10-lambda-calculus/commit/82ab57d2f996ac84815da3f21ed6ffb970ab9599
η変換を実装したのでテストが書きやすくなった、次は let 式の実装かな