を使用してrecursive
、単純な AST を生成できます。
from hypothesis import *
from hypothesis.strategies import *
def trees():
base = integers(min_value=1, max_value=10).map(lambda n: 'x' + str(n))
@composite
def extend(draw, children):
op = draw(sampled_from(['+', '-', '*', '/']))
return (op, draw(children), draw(children))
return recursive(base, draw)
ここで、算術演算に加えてブール演算を生成できるように変更したいと思います。私の最初のアイデアは、にパラメータを追加することtrees
です:
def trees(tpe):
base = integers(min_value=1, max_value=10).map(lambda n: 'x' + str(n) + ': ' + tpe)
@composite
def extend(draw, children):
if tpe == 'bool':
op = draw(sampled_from(['&&', '||']))
return (op, draw(children), draw(children))
elif tpe == 'num':
op = draw(sampled_from(['+', '-', '*', '/']))
return (op, draw(children), draw(children))
return recursive(base, draw)
わかりました。しかし、どのようにそれらを混ぜるのですか? つまりchildren
、いわば「別のパラメーターで呼び出す」必要がある比較演算子と三項演算子も必要です。
ツリーは適切に型付けされている必要があります: 演算が'||'
orの場合'&&'
、両方の引数がブール値である必要があり、'+'
orの引数'<'
が数値である必要があるなどです。型が 2 つしかない場合は、次のように使用できますfilter
(関数が与えられたtype_of
場合):
if op in ('&&', '||'):
bool_trees = children.filter(lambda x: type_of(x) == 'bool')
return (op, draw(bool_trees), draw(bool_trees))
しかし、実際にはそれは受け入れられません。
recursive
これをサポートしていますか?それとも別の方法がありますか?trees
もちろん、再帰的に直接定義することもできますが、それは標準的な問題に突き当たります。