たとえば、任意 Coq用語(AST s-expressions/sexpを使用した形式))があるとします。
n = n + n
そしてそれを自動的に次のように変換したい:
= n + n n
ASTツリー(これはsexpのためにリストのネストされたリストです)をトラバースします。Pythonこれを行う?
今私がアルゴリズム/ペソコードを書き留める場合、私はそうします(sexpを実際のツリーオブジェクトに変換できると仮定します):
def ToPolish():
'''
"postfix" tree traversal
'''
text = ''
for node in root.children:
if node is atoms:
text := text + node.text
else:
text := text + ToPolish(node,text)
return text
これは近いと思いますが、どこかに小さなバグがあると思います...
aSTの例:
(ObjList
((CoqGoal
((fg_goals
(((name 4)
(ty
(App
(Ind
(((Mutind (MPfile (DirPath ((Id Logic) (Id Init) (Id Coq))))
(DirPath ()) (Id eq))
0)
(Instance ())))
((Ind
(((Mutind (MPfile (DirPath ((Id Datatypes) (Id Init) (Id Coq))))
(DirPath ()) (Id nat))
0)
(Instance ())))
(App
(Const
((Constant (MPfile (DirPath ((Id Nat) (Id Init) (Id Coq))))
(DirPath ()) (Id add))
(Instance ())))
((Construct
((((Mutind
(MPfile (DirPath ((Id Datatypes) (Id Init) (Id Coq))))
(DirPath ()) (Id nat))
0)
1)
(Instance ())))
(Var (Id n))))
(Var (Id n)))))
(hyp
((((Id n)) ()
(Ind
(((Mutind (MPfile (DirPath ((Id Datatypes) (Id Init) (Id Coq))))
(DirPath ()) (Id nat))
0)
(Instance ())))))))))
(bg_goals ()) (shelved_goals ()) (given_up_goals ())))))
上記は単純です:
(ObjList
((CoqString "\
\n n : nat\
\n============================\
\n0 + n = n"))))
または
= n + n n
Sexpパーサーの使用:
[Symbol('Answer'), 2, [Symbol('ObjList'), [[Symbol('CoqGoal'), [[Symbol('fg_goals'), [[[Symbol('name'), 4], [Symbol('ty'), [Symbol('App'), [Symbol('Ind'), [[[Symbol('Mutind'), [Symbol('MPfile'), [Symbol('DirPath'), [[Symbol('Id'), Symbol('Logic')], [Symbol('Id'), Symbol('Init')], [Symbol('Id'), Symbol('Coq')]]]], [Symbol('DirPath'), []], [Symbol('Id'), Symbol('eq')]], 0], [Symbol('Instance'), []]]], [[Symbol('Ind'), [[[Symbol('Mutind'), [Symbol('MPfile'), [Symbol('DirPath'), [[Symbol('Id'), Symbol('Datatypes')], [Symbol('Id'), Symbol('Init')], [Symbol('Id'), Symbol('Coq')]]]], [Symbol('DirPath'), []], [Symbol('Id'), Symbol('nat')]], 0], [Symbol('Instance'), []]]], [Symbol('App'), [Symbol('Const'), [[Symbol('Constant'), [Symbol('MPfile'), [Symbol('DirPath'), [[Symbol('Id'), Symbol('Nat')], [Symbol('Id'), Symbol('Init')], [Symbol('Id'), Symbol('Coq')]]]], [Symbol('DirPath'), []], [Symbol('Id'), Symbol('add')]], [Symbol('Instance'), []]]], [[Symbol('Construct'), [[[[Symbol('Mutind'), [Symbol('MPfile'), [Symbol('DirPath'), [[Symbol('Id'), Symbol('Datatypes')], [Symbol('Id'), Symbol('Init')], [Symbol('Id'), Symbol('Coq')]]]], [Symbol('DirPath'), []], [Symbol('Id'), Symbol('nat')]], 0], 1], [Symbol('Instance'), []]]], [Symbol('Var'), [Symbol('Id'), Symbol('n')]]]], [Symbol('Var'), [Symbol('Id'), Symbol('n')]]]]], [Symbol('hyp'), [[[[Symbol('Id'), Symbol('n')]], [], [Symbol('Ind'), [[[Symbol('Mutind'), [Symbol('MPfile'), [Symbol('DirPath'), [[Symbol('Id'), Symbol('Datatypes')], [Symbol('Id'), Symbol('Init')], [Symbol('Id'), Symbol('Coq')]]]], [Symbol('DirPath'), []], [Symbol('Id'), Symbol('nat')]], 0], [Symbol('Instance'), []]]]]]]]]], [Symbol('bg_goals'), []], [Symbol('shelved_goals'), []], [Symbol('given_up_goals'), []]]]]]]
私が恐れていることを実行するモジュールは知りませんが、あなたが正しく実行したいことを理解していて、あなたが特定したように、ツリーをトラバースする必要があるだけです。再帰的な実装は少しずれています。これはどう?
class Node:
def __init__(self, text, children=None):
self.text = text
self.children = children or []
def is_atomic(self):
return not self.children
def to_polish(root):
''' postfix tree traversal '''
return root.text + ' ' + ''.join(to_polish(n) for n in root.children)
print(to_polish(
Node('=', [
Node('a', [
Node('+', [
Node('b'),
Node('c')
])
])
])
))