control_flow.py revision 6a822c373818948037baacfbae1c7355e0fc2c48
15b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
25b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower#
35b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower# Licensed under the Apache License, Version 2.0 (the "License");
45b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower# you may not use this file except in compliance with the License.
55b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower# You may obtain a copy of the License at
65b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower#
75b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower#     http://www.apache.org/licenses/LICENSE-2.0
85b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower#
95b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower# Unless required by applicable law or agreed to in writing, software
105b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower# distributed under the License is distributed on an "AS IS" BASIS,
115b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
125b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower# See the License for the specific language governing permissions and
135b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower# limitations under the License.
145b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower# ==============================================================================
15453f94412f908aadd21561c14feae80dfac1e933A. Unique TensorFlower"""Handles control flow statements: while, if."""
165b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower
175b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlowerfrom __future__ import absolute_import
185b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlowerfrom __future__ import division
195b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlowerfrom __future__ import print_function
205b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower
215b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlowerimport gast
225b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower
235b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlowerfrom tensorflow.contrib.py2tf.pyct import anno
245b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlowerfrom tensorflow.contrib.py2tf.pyct import templates
256a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlowerfrom tensorflow.contrib.py2tf.pyct import transformer
266a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlowerfrom tensorflow.contrib.py2tf.pyct.static_analysis.annos import NodeAnno
275b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower
285b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower
295b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlowerclass SymbolNamer(object):
305b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower  """Describes the interface for ControlFlowTransformer's namer."""
315b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower
325b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower  def new_symbol(self, name_root, reserved_locals):
335b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower    """Generate a new unique symbol.
345b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower
355b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower    Args:
365b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower      name_root: String, used as stem in the new name.
375b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower      reserved_locals: Set(string), additional local symbols that are reserved
385b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower          and which should not be used.
395b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower    Returns:
405b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower      String.
415b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower    """
425b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower    raise NotImplementedError()
435b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower
445b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower
456ee404d17929c613b217400406e7e665010ebf18A. Unique TensorFlowerclass SymbolRenamer(gast.NodeTransformer):
466a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower  """Transformer that can rename symbols to a simple names."""
476ee404d17929c613b217400406e7e665010ebf18A. Unique TensorFlower
486ee404d17929c613b217400406e7e665010ebf18A. Unique TensorFlower  def __init__(self, name_map):
496ee404d17929c613b217400406e7e665010ebf18A. Unique TensorFlower    self.name_map = name_map
506ee404d17929c613b217400406e7e665010ebf18A. Unique TensorFlower
516a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower  def _process(self, node):
526a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower    qn = anno.getanno(node, anno.Basic.QN)
536a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower    if qn in self.name_map:
546a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower      return gast.Name(self.name_map[qn], node.ctx, None)
556ee404d17929c613b217400406e7e665010ebf18A. Unique TensorFlower    return node
566ee404d17929c613b217400406e7e665010ebf18A. Unique TensorFlower
576a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower  def visit_Name(self, node):
586a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower    return self._process(node)
596a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower
606a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower  def visit_Attribute(self, node):
616a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower    return self._process(node)
626a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower
636ee404d17929c613b217400406e7e665010ebf18A. Unique TensorFlower
646a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlowerclass ControlFlowTransformer(transformer.Base):
655b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower  """Transforms control flow structures like loops an conditionals."""
665b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower
676a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower  def __init__(self, context):
686a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower    super(ControlFlowTransformer, self).__init__(context)
695b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower
705b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower  # pylint:disable=invalid-name
715b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower
72453f94412f908aadd21561c14feae80dfac1e933A. Unique TensorFlower  def visit_For(self, node):
73453f94412f908aadd21561c14feae80dfac1e933A. Unique TensorFlower    assert False, 'for statement should have been canonicalized at this point'
745b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower
755b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower  def visit_If(self, node):
766ee404d17929c613b217400406e7e665010ebf18A. Unique TensorFlower    self.generic_visit(node)
776ee404d17929c613b217400406e7e665010ebf18A. Unique TensorFlower
786a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower    body_scope = anno.getanno(node, NodeAnno.BODY_SCOPE)
796a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower    orelse_scope = anno.getanno(node, NodeAnno.ORELSE_SCOPE)
806ee404d17929c613b217400406e7e665010ebf18A. Unique TensorFlower
816ee404d17929c613b217400406e7e665010ebf18A. Unique TensorFlower    if body_scope.created - orelse_scope.created:
826ee404d17929c613b217400406e7e665010ebf18A. Unique TensorFlower      raise ValueError(
836ee404d17929c613b217400406e7e665010ebf18A. Unique TensorFlower          'The if branch creates new symbols that the else branch does not.')
846ee404d17929c613b217400406e7e665010ebf18A. Unique TensorFlower    if orelse_scope.created - body_scope.created:
856ee404d17929c613b217400406e7e665010ebf18A. Unique TensorFlower      raise ValueError(
866ee404d17929c613b217400406e7e665010ebf18A. Unique TensorFlower          'The else branch creates new symbols that the if branch does not.')
876ee404d17929c613b217400406e7e665010ebf18A. Unique TensorFlower
886ee404d17929c613b217400406e7e665010ebf18A. Unique TensorFlower    all_modified = tuple(body_scope.modified | orelse_scope.modified)
896ee404d17929c613b217400406e7e665010ebf18A. Unique TensorFlower    all_referenced = body_scope.referenced | orelse_scope.referenced
906ee404d17929c613b217400406e7e665010ebf18A. Unique TensorFlower
916ee404d17929c613b217400406e7e665010ebf18A. Unique TensorFlower    # Alias the closure variables inside the conditional functions
926ee404d17929c613b217400406e7e665010ebf18A. Unique TensorFlower    # to avoid errors caused by the local variables created in the branch
936ee404d17929c613b217400406e7e665010ebf18A. Unique TensorFlower    # functions.
946ee404d17929c613b217400406e7e665010ebf18A. Unique TensorFlower    need_alias = (
956ee404d17929c613b217400406e7e665010ebf18A. Unique TensorFlower        (body_scope.modified | orelse_scope.modified) -
966ee404d17929c613b217400406e7e665010ebf18A. Unique TensorFlower        (body_scope.created | orelse_scope.created))
97949dd29d3a8bdc21328c9e94721b344310686eabA. Unique TensorFlower    aliased_orig_names = tuple(need_alias)
98949dd29d3a8bdc21328c9e94721b344310686eabA. Unique TensorFlower    aliased_new_names = tuple(
996a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower        self.context.namer.new_symbol(s.ssf(), all_referenced)
1006a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower        for s in aliased_orig_names)
101949dd29d3a8bdc21328c9e94721b344310686eabA. Unique TensorFlower    alias_map = dict(zip(aliased_orig_names, aliased_new_names))
1026ee404d17929c613b217400406e7e665010ebf18A. Unique TensorFlower    node_body = node.body
1036ee404d17929c613b217400406e7e665010ebf18A. Unique TensorFlower    node_body = [SymbolRenamer(alias_map).visit(n) for n in node_body]
1046ee404d17929c613b217400406e7e665010ebf18A. Unique TensorFlower    node_orelse = node.orelse
1056ee404d17929c613b217400406e7e665010ebf18A. Unique TensorFlower    node_orelse = [SymbolRenamer(alias_map).visit(n) for n in node_orelse]
1066ee404d17929c613b217400406e7e665010ebf18A. Unique TensorFlower
1076ee404d17929c613b217400406e7e665010ebf18A. Unique TensorFlower    if len(all_modified) == 1:
1086a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower      results = all_modified[0]
1096ee404d17929c613b217400406e7e665010ebf18A. Unique TensorFlower    else:
1106a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower      results = gast.Tuple([s.ast() for s in all_modified], None)
1116a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower
1126a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower    if aliased_orig_names:
1136a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower      template = """
1146a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower        def body_name():
1156a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower          aliased_new_names, = aliased_orig_names,
1166a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower          body
1176a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower          return (all_results,)
1186a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower        def orelse_name():
1196a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower          aliased_new_names, = aliased_orig_names,
1206a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower          orelse
1216a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower          return (all_results,)
1226a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower        results = tf.cond(test, body_name, orelse_name)
1236a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower      """
1246a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower      body_name = self.context.namer.new_symbol('if_true', all_referenced)
1256a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower      return templates.replace(
1266a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower          template,
1276a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower          test=node.test,
1286a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower          body_name=body_name,
1296a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower          body=node_body,
1306a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower          orelse_name=self.context.namer.new_symbol('if_false', all_referenced),
1316a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower          orelse=node_orelse,
1326a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower          aliased_orig_names=tuple(aliased_orig_names),
1336a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower          aliased_new_names=tuple(aliased_new_names),
1346a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower          all_results=tuple(alias_map[s] if s in aliased_orig_names else s
1356a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower                            for s in all_modified),
1366a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower          results=results)
1376a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower    else:
1386a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower      template = """
1396a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower        def body_name():
1406a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower          body
1416a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower          return (all_results,)
1426a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower        def orelse_name():
1436a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower          orelse
1446a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower          return (all_results,)
1456a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower        results = tf.cond(test, body_name, orelse_name)
1466a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower      """
1476a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower      body_name = self.context.namer.new_symbol('if_true', all_referenced)
1486a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower      return templates.replace(
1496a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower          template,
1506a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower          test=node.test,
1516a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower          body_name=body_name,
1526a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower          body=node_body,
1536a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower          orelse_name=self.context.namer.new_symbol('if_false', all_referenced),
1546a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower          orelse=node_orelse,
1556a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower          all_results=tuple(s for s in all_modified),
1566a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower          results=results)
1575b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower
1585b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower  def visit_While(self, node):
1595b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower    self.generic_visit(node)
1606ee404d17929c613b217400406e7e665010ebf18A. Unique TensorFlower
1616a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower    body_scope = anno.getanno(node, NodeAnno.BODY_SCOPE)
1626a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower    body_closure = body_scope.modified - body_scope.created
1636a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower    all_referenced = body_scope.referenced
1646a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower
1656a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower    state = list(body_closure)
1666a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower    state_ssf = [
1676a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower        self.context.namer.new_symbol(s.ssf(), all_referenced) for s in state
1686a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower    ]
1696a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower    ssf_map = {
1706a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower        name: ssf
1716a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower        for name, ssf in zip(state, state_ssf)
1726a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower        if str(name) != ssf
1736a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower    }
1746a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower
1756a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower    if len(state) == 1:
1766a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower      state = state[0]
1776a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower      state_ssf = state_ssf[0]
178453f94412f908aadd21561c14feae80dfac1e933A. Unique TensorFlower      state_ast_tuple = state
179453f94412f908aadd21561c14feae80dfac1e933A. Unique TensorFlower    else:
1806a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower      state_ast_tuple = gast.Tuple([n.ast() for n in state], None)
1816a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower
1826a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower    node_body = node.body
1836a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower    node_body = [SymbolRenamer(ssf_map).visit(n) for n in node_body]
1846a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower
1856a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower    test = node.test
1866a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower    test = SymbolRenamer(ssf_map).visit(test)
1876a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower
188949dd29d3a8bdc21328c9e94721b344310686eabA. Unique TensorFlower    template = """
1896a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower      def test_name(state_ssf):
190949dd29d3a8bdc21328c9e94721b344310686eabA. Unique TensorFlower        return test
1916a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower      def body_name(state_ssf):
192949dd29d3a8bdc21328c9e94721b344310686eabA. Unique TensorFlower        body
1936a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower        return state_ssf,
194949dd29d3a8bdc21328c9e94721b344310686eabA. Unique TensorFlower      state_ast_tuple = tf.while_loop(test_name, body_name, [state])
195949dd29d3a8bdc21328c9e94721b344310686eabA. Unique TensorFlower    """
1965b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower    node = templates.replace(
1975b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower        template,
198453f94412f908aadd21561c14feae80dfac1e933A. Unique TensorFlower        state=state,
1996a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower        state_ssf=state_ssf,
200453f94412f908aadd21561c14feae80dfac1e933A. Unique TensorFlower        state_ast_tuple=state_ast_tuple,
2016a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower        test_name=self.context.namer.new_symbol('loop_test',
2026a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower                                                body_scope.referenced),
2036a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower        test=test,
2046a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower        body_name=self.context.namer.new_symbol('loop_body',
2056a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower                                                body_scope.referenced),
2066a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower        body=node_body)
2075b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower
2085b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower    return node
2095b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower
2105b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower  # pylint:enable=invalid-name
2115b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower
2125b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower
2136a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlowerdef transform(node, context):
2146a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower  t = ControlFlowTransformer(context)
2156a822c373818948037baacfbae1c7355e0fc2c48A. Unique TensorFlower  node = t.visit(node)
2165b2aae39b75f5a864e0ec0dd95c7f3a07e9d16e7A. Unique TensorFlower  return node
217