示例#1
0
    def test_evaluate_cfg_mod_n(self):
        initial_value = 1  # v0 = 1
        initial_values = {'v0': initial_value}
        python_source = """
v0 += 5
v0 *= 6
v0 -= 3
    """.strip()
        cfg = python_programs.to_cfg(python_source)
        final_values = python_interpreter.evaluate_cfg(
            self.executor, cfg, mod=5, initial_values=initial_values)
        final_value = final_values['v0']
        self.assertEqual(3, final_value)
示例#2
0
    def test_evaluate_cfg_break(self):
        initial_value = 1  # v0 = 1
        initial_values = {'v0': initial_value}
        python_source = """
v1 = 2
while v1 > 0:
  v1 -= 1
  v0 += 2
  break
    """.strip()
        cfg = python_programs.to_cfg(python_source)
        values = python_interpreter.evaluate_cfg(self.executor,
                                                 cfg,
                                                 initial_values=initial_values)
        self.assertEqual(values['v0'], 3)
示例#3
0
    def test_evaluate_cfg_while(self):
        initial_value = 1  # v0 = 1
        initial_values = {'v0': initial_value}
        python_source = """
v0 += 5
v0 *= 6
v1 = 5
while v1 > 0:
  v1 -= 1
  v0 -= 3
    """.strip()
        cfg = python_programs.to_cfg(python_source)
        final_values = python_interpreter.evaluate_cfg(
            self.executor, cfg, initial_values=initial_values)
        final_value = final_values['v0']
        self.assertEqual(21, final_value)
示例#4
0
 def test_evaluate_cfg_on_random_program(self):
     initial_value = 1  # v0 = 1
     initial_values = {'v0': initial_value}
     config = arithmetic_repeats_config.ArithmeticRepeatsConfig(
         base=10,
         length=10,
         max_repeat_statements=10,
         max_repetitions=9,
         max_repeat_block_size=5,
         repeat_probability=0.2,
         permit_nested_repeats=True,
     )
     python_source = program_generators.generate_python_source(
         config.length, config)
     cfg = python_programs.to_cfg(python_source)
     values = python_interpreter.evaluate_cfg(self.executor,
                                              cfg,
                                              initial_values=initial_values)
     self.assertIn('v0', values)
示例#5
0
    def test_evaluate_cfg_nested_while_trace(self):
        initial_value = 1  # v0 = 1
        initial_values = {'v0': initial_value}
        python_source = """
v0 += 49
v1 = 2
while v1 > 0:
  v1 -= 1
  v2 = 2
  while v2 > 0:
    v2 -= 1
    v0 -= 3
    v0 += 1
    """.strip()
        cfg = python_programs.to_cfg(python_source)
        trace_fn = python_interpreter_trace.make_trace_fn(python_source, cfg)
        final_values = python_interpreter.evaluate_cfg(
            self.executor,
            cfg,
            initial_values=initial_values,
            trace_fn=trace_fn)
        final_value = final_values['v0']
        expected_trace_cfg_node_indexes = [
            0, 1, 2, 3, 4, 5, 6, 7, 8, 5, 6, 7, 8, 5, 2, 3, 4, 5, 6, 7, 8, 5,
            6, 7, 8, 5, 2
        ]
        expected_trace_values = [
            [{
                'v0': 50
            }],
            [{
                'v0': 50,
                'v1': 2
            }],
            [{
                'v0': 50,
                'v1': 2,
                'vBranch': True
            }],
            [{
                'v0': 50,
                'v1': 1,
                'vBranch': True
            }],
            [{
                'v0': 50,
                'v1': 1,
                'v2': 2,
                'vBranch': True
            }],
            [{
                'v0': 50,
                'v1': 1,
                'v2': 2,
                'vBranch': True
            }],
            [{
                'v0': 50,
                'v1': 1,
                'v2': 1,
                'vBranch': True
            }],
            [{
                'v0': 47,
                'v1': 1,
                'v2': 1,
                'vBranch': True
            }],
            [{
                'v0': 48,
                'v1': 1,
                'v2': 1,
                'vBranch': True
            }],
            [{
                'v0': 48,
                'v1': 1,
                'v2': 1,
                'vBranch': True
            }],
            [{
                'v0': 48,
                'v1': 1,
                'v2': 0,
                'vBranch': True
            }],
            [{
                'v0': 45,
                'v1': 1,
                'v2': 0,
                'vBranch': True
            }],
            [{
                'v0': 46,
                'v1': 1,
                'v2': 0,
                'vBranch': True
            }],
            [{
                'v0': 46,
                'v1': 1,
                'v2': 0,
                'vBranch': False
            }],
            [{
                'v0': 46,
                'v1': 1,
                'v2': 0,
                'vBranch': True
            }],
            [{
                'v0': 46,
                'v1': 0,
                'v2': 0,
                'vBranch': True
            }],
            [{
                'v0': 46,
                'v1': 0,
                'v2': 2,
                'vBranch': True
            }],
            [{
                'v0': 46,
                'v1': 0,
                'v2': 2,
                'vBranch': True
            }],
            [{
                'v0': 46,
                'v1': 0,
                'v2': 1,
                'vBranch': True
            }],
            [{
                'v0': 43,
                'v1': 0,
                'v2': 1,
                'vBranch': True
            }],
            [{
                'v0': 44,
                'v1': 0,
                'v2': 1,
                'vBranch': True
            }],
            [{
                'v0': 44,
                'v1': 0,
                'v2': 1,
                'vBranch': True
            }],
            [{
                'v0': 44,
                'v1': 0,
                'v2': 0,
                'vBranch': True
            }],
            [{
                'v0': 41,
                'v1': 0,
                'v2': 0,
                'vBranch': True
            }],
            [{
                'v0': 42,
                'v1': 0,
                'v2': 0,
                'vBranch': True
            }],
            [{
                'v0': 42,
                'v1': 0,
                'v2': 0,
                'vBranch': False
            }],
            [{
                'v0': 42,
                'v1': 0,
                'v2': 0,
                'vBranch': False
            }],
        ]
        expected_cfg_node_index_values = [
            [{
                'v0': 50
            }],  # v0 += 49
            [{
                'v0': 50,
                'v1': 2
            }],  # v1 = 2
            [
                {
                    'v0': 50,
                    'v1': 2,
                    'vBranch': True
                },  # vBranch = (v1 > 0)
                {
                    'v0': 46,
                    'v1': 1,
                    'v2': 0,
                    'vBranch': True
                },
                {
                    'v0': 42,
                    'v1': 0,
                    'v2': 0,
                    'vBranch': False
                }
            ],
            [{
                'v0': 50,
                'v1': 1,
                'vBranch': True
            }, {
                'v0': 46,
                'v1': 0,
                'v2': 0,
                'vBranch': True
            }],  # v1 -= 1
            [{
                'v0': 50,
                'v1': 1,
                'v2': 2,
                'vBranch': True
            }, {
                'v0': 46,
                'v1': 0,
                'v2': 2,
                'vBranch': True
            }],  # v2 = 2
            [{
                'v0': 50,
                'v1': 1,
                'v2': 2,
                'vBranch': True
            }, {
                'v0': 48,
                'v1': 1,
                'v2': 1,
                'vBranch': True
            }, {
                'v0': 46,
                'v1': 1,
                'v2': 0,
                'vBranch': False
            }, {
                'v0': 46,
                'v1': 0,
                'v2': 2,
                'vBranch': True
            }, {
                'v0': 44,
                'v1': 0,
                'v2': 1,
                'vBranch': True
            }, {
                'v0': 42,
                'v1': 0,
                'v2': 0,
                'vBranch': False
            }],  # vBranch = (v2 > 0)
            [{
                'v0': 50,
                'v1': 1,
                'v2': 1,
                'vBranch': True
            }, {
                'v0': 48,
                'v1': 1,
                'v2': 0,
                'vBranch': True
            }, {
                'v0': 46,
                'v1': 0,
                'v2': 1,
                'vBranch': True
            }, {
                'v0': 44,
                'v1': 0,
                'v2': 0,
                'vBranch': True
            }],  # v2 -= 1
            [{
                'v0': 47,
                'v1': 1,
                'v2': 1,
                'vBranch': True
            }, {
                'v0': 45,
                'v1': 1,
                'v2': 0,
                'vBranch': True
            }, {
                'v0': 43,
                'v1': 0,
                'v2': 1,
                'vBranch': True
            }, {
                'v0': 41,
                'v1': 0,
                'v2': 0,
                'vBranch': True
            }],  # v0 -= 3
            [{
                'v0': 48,
                'v1': 1,
                'v2': 1,
                'vBranch': True
            }, {
                'v0': 46,
                'v1': 1,
                'v2': 0,
                'vBranch': True
            }, {
                'v0': 44,
                'v1': 0,
                'v2': 1,
                'vBranch': True
            }, {
                'v0': 42,
                'v1': 0,
                'v2': 0,
                'vBranch': True
            }],  # v0 += 1
        ]
        self.assertEqual(trace_fn.trace.trace_cfg_node_indexes,
                         expected_trace_cfg_node_indexes)
        self.assertEqual(trace_fn.trace.trace_values, expected_trace_values)
        self.assertEqual(trace_fn.trace.cfg_node_index_values,
                         expected_cfg_node_index_values)
        self.assertEqual(final_value, 42)
示例#6
0
    def test_evaluate_cfg_trace(self):
        initial_value = 1  # v0 = 1
        initial_values = {'v0': initial_value}
        python_source = """
v0 += 5
v0 *= 6
v1 = 2
while v1 > 0:
  v1 -= 1
  v0 -= 3
  v0 += 1
    """.strip()
        cfg = python_programs.to_cfg(python_source)
        trace_fn = python_interpreter_trace.make_trace_fn(python_source, cfg)
        final_values = python_interpreter.evaluate_cfg(
            self.executor,
            cfg,
            initial_values=initial_values,
            trace_fn=trace_fn)
        final_value = final_values['v0']
        expected_trace_cfg_node_indexes = [0, 1, 2, 3, 4, 5, 6, 3, 4, 5, 6, 3]
        expected_trace_line_indexes = expected_trace_cfg_node_indexes.copy()
        expected_trace_values = [
            [{
                'v0': 6
            }],
            [{
                'v0': 36
            }],
            [{
                'v0': 36,
                'v1': 2
            }],
            [{
                'v0': 36,
                'v1': 2,
                'vBranch': True
            }],
            [{
                'v0': 36,
                'v1': 1,
                'vBranch': True
            }],
            [{
                'v0': 33,
                'v1': 1,
                'vBranch': True
            }],
            [{
                'v0': 34,
                'v1': 1,
                'vBranch': True
            }],
            [{
                'v0': 34,
                'v1': 1,
                'vBranch': True
            }],
            [{
                'v0': 34,
                'v1': 0,
                'vBranch': True
            }],
            [{
                'v0': 31,
                'v1': 0,
                'vBranch': True
            }],
            [{
                'v0': 32,
                'v1': 0,
                'vBranch': True
            }],
            [{
                'v0': 32,
                'v1': 0,
                'vBranch': False
            }],
        ]
        expected_cfg_node_index_values = [
            [{
                'v0': 6
            }],  # v0 += 5
            [{
                'v0': 36
            }],  # v0 *= 6
            [{
                'v0': 36,
                'v1': 2
            }],  # v1 = 2
            [
                {
                    'v0': 36,
                    'v1': 2,
                    'vBranch': True
                },  # vBranch = (v1 > 0)
                {
                    'v0': 34,
                    'v1': 1,
                    'vBranch': True
                },
                {
                    'v0': 32,
                    'v1': 0,
                    'vBranch': False
                }
            ],
            [
                {
                    'v0': 36,
                    'v1': 1,
                    'vBranch': True
                },  # v1 -= 1
                {
                    'v0': 34,
                    'v1': 0,
                    'vBranch': True
                }
            ],
            [
                {
                    'v0': 33,
                    'v1': 1,
                    'vBranch': True
                },  # v0 -= 3
                {
                    'v0': 31,
                    'v1': 0,
                    'vBranch': True
                }
            ],
            [
                {
                    'v0': 34,
                    'v1': 1,
                    'vBranch': True
                },  # v0 += 1
                {
                    'v0': 32,
                    'v1': 0,
                    'vBranch': True
                }
            ],
        ]
        expected_line_index_values = expected_cfg_node_index_values
        self.assertEqual(final_value, 32)
        self.assertEqual(trace_fn.trace.trace_values, expected_trace_values)
        self.assertEqual(trace_fn.trace.trace_cfg_node_indexes,
                         expected_trace_cfg_node_indexes)
        self.assertEqual(trace_fn.trace.trace_line_indexes,
                         expected_trace_line_indexes)
        self.assertEqual(trace_fn.trace.cfg_node_index_values,
                         expected_cfg_node_index_values)
        self.assertEqual(trace_fn.trace.line_index_values,
                         expected_line_index_values)
def _generate_example_from_python_source(executor, base, python_source,
                                         tokens_per_statement,
                                         target_output_length, mod,
                                         output_mod):
    """Generates an example dict from the given statements."""
    human_readable_code = python_source
    cfg = python_programs.to_cfg(python_source)
    python_source_lines = python_source.strip().split("\n")

    # TODO(dbieber): This should occur in exactly one location.
    # (also in environment.py)
    values = {"v0": 1}
    trace_fn = python_interpreter_trace.make_trace_fn(python_source, cfg)
    # TODO(dbieber): Evaluating may have already occurred in environment.
    try:
        values = python_interpreter.evaluate_cfg(executor,
                                                 cfg,
                                                 mod=mod,
                                                 initial_values=values,
                                                 trace_fn=trace_fn,
                                                 timeout=200)
        error_type = "NoError"
    except Exception as e:  # pylint: disable=broad-except
        error_type = type(e).__name__
    target_output = values["v0"]

    if output_mod is not None:
        try:
            target_output %= output_mod
        except TypeError:
            target_output = 1

    code_features = build_representation(
        python_source, trace_fn.trace.cfg_node_index_values,
        trace_fn.trace.cfg_node_index_branch_decisions, tokens_per_statement,
        base, target_output_length, output_mod)

    use_full_lines_in_trace = False
    if use_full_lines_in_trace:
        trace_lines = [
            python_source_lines[line_index]
            for line_index in trace_fn.trace.trace_line_indexes
        ]
        trace_python_source = "\n".join(trace_lines)
    else:
        trace_control_flow_nodes = [
            cfg.nodes[cfg_node_index]
            for cfg_node_index in trace_fn.trace.trace_cfg_node_indexes
        ]
        # TODO(dbieber): This also occurs in environment `state_as_example`.
        # Refactor.
        python_source_lines = []
        for control_flow_node in trace_control_flow_nodes:
            ast_node = control_flow_node.instruction.node
            python_source_line = astunparse.unparse(ast_node,
                                                    version_info=(3, 5))
            python_source_line = python_source_line.strip()
            python_source_lines.append(python_source_line)
        trace_python_source = "\n".join(python_source_lines)
    trace_features = build_representation(
        trace_python_source, trace_fn.trace.trace_values,
        trace_fn.trace.trace_branch_decisions, tokens_per_statement, base,
        target_output_length, output_mod)

    target_output_list = encoders.as_nary_list(target_output, base,
                                               target_output_length)

    lm_text = f"{human_readable_code} SEP {target_output}"

    example_dict = {
        # human_readable_features
        "human_readable_code": human_readable_code,
        # "original_human_readable_code": human_readable_code,
        "human_readable_target_output": str(target_output),

        # target_output
        "target_output": target_output_list,
        "target_output_length": target_output_length,
        "lm_text": lm_text,
        "error_type": error_type,

        # control flow graph
        "cfg": (cfg, python_source),
        "cfg_forward": (cfg, python_source),
    }
    example_dict.update(
        {"code_" + key: value
         for key, value in code_features.items()})
    example_dict.update(
        {"trace_" + key: value
         for key, value in trace_features.items()})
    return example_dict