Alloyで出力したXMLをいじりやすくする
Alloyにも一応Evaluatorっていう対話的に値を観察するコンソールが付いているけども、出力された値をコピペ出来ないとか色々めんどくさくて、個人的にはもういっそJythonコンソールを突っ込んでしまえよと言いたくなるけど「お前がやれ」って言われそうでめんどくさいので、とりあえずXMLでエクスポートしたのをいじるライブラリを作りました。
ipythonで対話的に使うことを想定しています。
In [29]: load("a.xml") In [30]: get("flag") Out[30]: [[u'Memory$0', u'0', u'0', u'Time$0'], [u'Memory$0', u'0', u'0', u'Time$1'], [u'Memory$0', u'0', u'0', u'Time$2'], [u'Memory$0', u'0', u'1', u'Time$3'], [u'Memory$0', u'0', u'1', u'Time$4'], [u'Memory$0', u'0', u'1', u'Time$5'], [u'Memory$0', u'0', u'1', u'Time$6'], [u'Memory$0', u'1', u'0', u'Time$0'], [u'Memory$0', u'1', u'1', u'Time$1'], [u'Memory$0', u'1', u'1', u'Time$2'], [u'Memory$0', u'1', u'1', u'Time$3'], [u'Memory$0', u'1', u'1', u'Time$4'], [u'Memory$0', u'1', u'1', u'Time$5'], [u'Memory$0', u'1', u'1', u'Time$6']] In [31]: get("flag").to_int(1, 2, 3) Out[31]: [[u'Memory$0', u'0', u'0', u'Time$0', 0, 0, 0], [u'Memory$0', u'0', u'0', u'Time$1', 0, 0, 1], [u'Memory$0', u'0', u'0', u'Time$2', 0, 0, 2], [u'Memory$0', u'0', u'1', u'Time$3', 0, 1, 3], [u'Memory$0', u'0', u'1', u'Time$4', 0, 1, 4], [u'Memory$0', u'0', u'1', u'Time$5', 0, 1, 5], [u'Memory$0', u'0', u'1', u'Time$6', 0, 1, 6], [u'Memory$0', u'1', u'0', u'Time$0', 1, 0, 0], [u'Memory$0', u'1', u'1', u'Time$1', 1, 1, 1], [u'Memory$0', u'1', u'1', u'Time$2', 1, 1, 2], [u'Memory$0', u'1', u'1', u'Time$3', 1, 1, 3], [u'Memory$0', u'1', u'1', u'Time$4', 1, 1, 4], [u'Memory$0', u'1', u'1', u'Time$5', 1, 1, 5], [u'Memory$0', u'1', u'1', u'Time$6', 1, 1, 6]] In [32]: get("flag").to_int(1, 2, 3).trans(6, 4, 5) Out[32]: [[0, 0, 0], [1, 0, 0], [2, 0, 0], [3, 0, 1], [4, 0, 1], [5, 0, 1], [6, 0, 1], [0, 1, 0], [1, 1, 1], [2, 1, 1], [3, 1, 1], [4, 1, 1], [5, 1, 1], [6, 1, 1]] In [33]: get("flag").to_int(1, 2, 3).trans(6, 4, 5).sort(0) Out[33]: [[0, 0, 0], [0, 1, 0], [1, 0, 0], [1, 1, 1], [2, 0, 0], [2, 1, 1], [3, 0, 1], [3, 1, 1], [4, 0, 1], [4, 1, 1], [5, 0, 1], [5, 1, 1], [6, 0, 1], [6, 1, 1]] In [34]: get("flag").to_int(1, 2, 3).trans(6, 4, 5).sort(0).map(lambda t, x, y: "%d: flag[%d] = %d" % (t, x, y)) Out[34]: ['0: flag[0] = 0', '0: flag[1] = 0', '1: flag[0] = 0', '1: flag[1] = 1', '2: flag[0] = 0', '2: flag[1] = 1', '3: flag[0] = 1', '3: flag[1] = 1', '4: flag[0] = 1', '4: flag[1] = 1', '5: flag[0] = 1', '5: flag[1] = 1', '6: flag[0] = 1', '6: flag[1] = 1']
あとgroup_byとか欲しいかなぁ。Alloy的な結合演算も入れてもいいかも。
https://github.com/nishio/learning_alloy/blob/master/show.py
joinつけた
結合演算入れたよ!
In [16]: get("flag").trans(3, 1, 2) Out[16]: [[u'Time$0', u'0', u'0'], [u'Time$1', u'0', u'0'], [u'Time$2', u'0', u'0'], [u'Time$3', u'0', u'1'], [u'Time$4', u'0', u'1'], [u'Time$5', u'0', u'1'], [u'Time$6', u'0', u'1'], [u'Time$0', u'1', u'0'], [u'Time$1', u'1', u'1'], [u'Time$2', u'1', u'1'], [u'Time$3', u'1', u'1'], [u'Time$4', u'1', u'1'], [u'Time$5', u'1', u'1'], [u'Time$6', u'1', u'1']] In [17]: get('Time$6').join(_) Out[17]: [[u'0', u'1'], [u'1', u'1']]
集計的な意味ではgroup_byだの複数の関係の張り合わせ(UNIXのpasteコマンドみたいな)とかやりたくなるけど、型的には微妙だなぁ。どうしようかなぁ。
っていうかそもそもmapの返り値がAlloyListなのがおかしいのか。AlloyListの範囲内でゴニョゴニョいじったあと、mapもしくはgroup_byで可視化のための関数に渡す、という使い方がよいのかな。
group_by入れた
In [21]: get("flag").trans(1, 2, 3).map(lambda x, y, t: [t, "flag[%s] = %s" % (x, y)]) Out[21]: [[u'Time$0', u'flag[0] = 0'], [u'Time$1', u'flag[0] = 0'], [u'Time$2', u'flag[0] = 0'], [u'Time$3', u'flag[0] = 1'], [u'Time$4', u'flag[0] = 1'], [u'Time$5', u'flag[0] = 1'], [u'Time$6', u'flag[0] = 1'], [u'Time$0', u'flag[1] = 0'], [u'Time$1', u'flag[1] = 1'], [u'Time$2', u'flag[1] = 1'], [u'Time$3', u'flag[1] = 1'], [u'Time$4', u'flag[1] = 1'], [u'Time$5', u'flag[1] = 1'], [u'Time$6', u'flag[1] = 1']] In [22]: get("flag").trans(1, 2, 3).map(lambda x, y, t: [t, "flag[%s] = %s" % (x, y)]).group_by(0) Out[22]: [(u'Time$0', [[u'Time$0', u'flag[0] = 0'], [u'Time$0', u'flag[1] = 0']]), (u'Time$1', [[u'Time$1', u'flag[0] = 0'], [u'Time$1', u'flag[1] = 1']]), (u'Time$2', [[u'Time$2', u'flag[0] = 0'], [u'Time$2', u'flag[1] = 1']]), (u'Time$3', [[u'Time$3', u'flag[0] = 1'], [u'Time$3', u'flag[1] = 1']]), (u'Time$4', [[u'Time$4', u'flag[0] = 1'], [u'Time$4', u'flag[1] = 1']]), (u'Time$5', [[u'Time$5', u'flag[0] = 1'], [u'Time$5', u'flag[1] = 1']]), (u'Time$6', [[u'Time$6', u'flag[0] = 1'], [u'Time$6', u'flag[1] = 1']])] In [24]: get("flag").trans(1, 2, 3).map(lambda x, y, t: [t, "flag[%s] = %s" % (x, y)]).group_by(0, lambda k, xs: (k, ", ".join(x[1] for x in xs))) Out[24]: [(u'Time$0', u'flag[0] = 0, flag[1] = 0'), (u'Time$1', u'flag[0] = 0, flag[1] = 1'), (u'Time$2', u'flag[0] = 0, flag[1] = 1'), (u'Time$3', u'flag[0] = 1, flag[1] = 1'), (u'Time$4', u'flag[0] = 1, flag[1] = 1'), (u'Time$5', u'flag[0] = 1, flag[1] = 1'), (u'Time$6', u'flag[0] = 1, flag[1] = 1')] In [33]: get("turn").trans(2, 1, 2).join(_) Out[33]: [[u'Time$0', u'0', u'flag[0] = 0, flag[1] = 0'], [u'Time$1', u'0', u'flag[0] = 0, flag[1] = 1'], [u'Time$2', u'0', u'flag[0] = 0, flag[1] = 1'], [u'Time$3', u'0', u'flag[0] = 1, flag[1] = 1'], [u'Time$4', u'1', u'flag[0] = 1, flag[1] = 1'], [u'Time$5', u'1', u'flag[0] = 1, flag[1] = 1'], [u'Time$6', u'1', u'flag[0] = 1, flag[1] = 1']] In [35]: _.map(lambda t, x, y: "%s: turn = %s, %s" % (t, x, y)) Out[35]: [u'Time$0: turn = 0, flag[0] = 0, flag[1] = 0', u'Time$1: turn = 0, flag[0] = 0, flag[1] = 1', u'Time$2: turn = 0, flag[0] = 0, flag[1] = 1', u'Time$3: turn = 0, flag[0] = 1, flag[1] = 1', u'Time$4: turn = 1, flag[0] = 1, flag[1] = 1', u'Time$5: turn = 1, flag[0] = 1, flag[1] = 1', u'Time$6: turn = 1, flag[0] = 1, flag[1] = 1'] In [37]: print "\n".join(_) Time$0: turn = 0, flag[0] = 0, flag[1] = 0 Time$1: turn = 0, flag[0] = 0, flag[1] = 1 Time$2: turn = 0, flag[0] = 0, flag[1] = 1 Time$3: turn = 0, flag[0] = 1, flag[1] = 1 Time$4: turn = 1, flag[0] = 1, flag[1] = 1 Time$5: turn = 1, flag[0] = 1, flag[1] = 1 Time$6: turn = 1, flag[0] = 1, flag[1] = 1
わーいわーい