継続について勉強中。
非決定性計算に使われるambオペレータをBoost.Contextで実装してみました。
AMB_BLOCKの中で生成したamberのオブジェクトは、それらの組み合わせを扱うことができます。
#include <iostream> #include "amb.hpp" void amb1_f(amber& cont) { cont.suspend(1); cont.suspend(2); cont.suspend_break(3); } void amb2_f(amber& cont) { cont.suspend(4); cont.suspend_break(5); } void amb3_f(amber& cont) { cont.suspend(6); cont.suspend(7); cont.suspend_break(8); } int main() { AMB_BLOCK(ctx) { amber& x = amb(ctx, 0, amb1_f); amber& y = amb(ctx, 1, amb2_f); amber& z = amb(ctx, 2, amb3_f); std::cout << x.get() << ", " << y.get() << ", " << z.get() << std::endl; }; }
1, 4, 6 1, 4, 7 1, 4, 8 1, 5, 6 1, 5, 7 1, 5, 8 2, 4, 6 2, 4, 7 2, 4, 8 2, 5, 6 2, 5, 7 2, 5, 8 3, 4, 6 3, 4, 7 3, 4, 8 3, 5, 6 3, 5, 7 3, 5, 8
ambの実装は、私のGitHubに置いてあります:
amb.hpp - Keizoku
AMB_BLOCKは参照キャプチャのラムダ式なので、いちおう外部の変数に結果を返すことはできます。ただし、ラムダ式なのでbreakはできません。気持ち悪いかもしれませんが、breakしたい場合はreturnしてください。
それと、amb関数の第2引数が邪魔なのでそのうち消したいところです…。今のところ上から順番に連番を指定する必要があります。
参照:
天使のオペレータ amb
shfit/resetによるambのミニマム実装