# Path: deep_verify/src/auto_verifier.py
# class NotVerifiableError(Exception):
# class VerifiableLayerBuilder(object):
#   def __init__(self, network):
#   def build_layers(self):
#   def _build_layers_rec(self, node, known_fanout=1, batchnorm_node=None):
#   def _fuse(self, verifiable_layers):
# 
# Path: deep_verify/src/layers/layers.py
# class VerifiableLayer(object):
# class CustomOp(object):
# class SingleVerifiableLayer(VerifiableLayer):
# class AffineLayer(SingleVerifiableLayer):
# class Conv(AffineLayer):
# class Linear(AffineLayer):
# class AvgPool(AffineLayer):
# class MaxPool(SingleVerifiableLayer):
# class Activation(SingleVerifiableLayer):
#   def __init__(self):
#   def branches(self):
#   def input_node(self):
#   def output_node(self):
#   def input_shape(self):
#   def output_shape(self):
#   def inputs(self):
#   def outputs(self):
#   def input_bounds(self):
#   def output_bounds(self):
#   def dual_shape(self):
#   def set_no_duals(self):
#   def reshape_duals_forwards(self, next_layer, dual_vars):
#   def project_duals_op(self, dual_vars):  # pylint:disable=unused-argument
#   def visit_linear(self, layer, w, b, *args, **kwargs):
#   def visit_conv(self, layer, w, b, padding, strides, *args, **kwargs):
#   def visit_avgpool(self, layer, *args, **kwargs):
#   def visit_maxpool(self, layer, *args, **kwargs):
#   def visit_activation(self, layer, *args, **kwargs):
#   def __init__(self, input_node, output_node, module,
#                batch_norm=None, reshape=False):
#   def input_node(self):
#   def output_node(self):
#   def is_activation(self):
#   def module(self):
#   def batch_norm(self):
#   def reshape(self):
#   def backward_prop_batchnorm(self, y):
#   def backward_prop_batchnorm_bias(self, y, bias):
#   def custom_op(self, op, *args, **kwargs):
#   def is_activation(self):
#   def forward_prop(self, x, apply_bias=False, w_fn=None):
#   def backward_prop(self, y, w_fn=None):
#   def backward_prop_bias(self, y):
#   def flatten(self):
#   def __init__(self, input_node, output_node, module, batch_norm=None,
#                reshape=False):
#   def forward_prop(self, x, apply_bias=False, w_fn=None):
#   def backward_prop(self, y, w_fn=None):
#   def backward_prop_bias(self, y):
#   def flatten(self):
#   def custom_op(self, op, *args, **kwargs):
#   def __init__(self, input_node, output_node, module, batch_norm=None,
#                reshape=False):
#   def forward_prop(self, x, apply_bias=False, w_fn=None):
#   def backward_prop(self, y, w_fn=None):
#   def backward_prop_bias(self, y):
#   def flatten(self):
#   def custom_op(self, op, *args, **kwargs):
#   def get_objective_weights(self, labels, target_strategy=None):
#   def __init__(self, input_node, output_node,
#                kernel_shape, strides, reshape=False):
#   def kernel_shape(self):
#   def strides(self):
#   def forward_prop(self, x, apply_bias=False, w_fn=None):
#   def backward_prop(self, y, w_fn=None):
#   def backward_prop_bias(self, y):
#   def flatten(self):
#   def custom_op(self, op, *args, **kwargs):
#   def __init__(self, input_node, output_node,
#                kernel_shape, strides, with_relu=False, reshape=False):
#   def kernel_shape(self):
#   def strides(self):
#   def with_relu(self):
#   def is_activation(self):
#   def custom_op(self, op, *args, **kwargs):
#   def __init__(self, input_node, output_node, module,
#                reshape=False, parameters=None):
#   def is_activation(self):
#   def activation(self):
#   def parameters(self):
#   def custom_op(self, op, *args, **kwargs):
# def create_verifiable_layer(input_node, output_node, module,
#                             batch_norm=None, reshape=False,
#                             parameters=None):


from absl.testing import parameterized
from deep_verify.src import auto_verifier
from deep_verify.src.layers import layers
import interval_bound_propagation as ibp
import sonnet as snt
import tensorflow as tf
    self.assertEqual('relu', v_layers[1].activation)

    self.assertIsInstance(v_layers[2], layers.Linear)
    self.assertIs(linear, v_layers[2].module)

  def test_leaky_relu(self):
    module = lambda x: tf.nn.leaky_relu(x, alpha=0.3)

    network = ibp.VerifiableModelWrapper(module)
    network(self._inputs)

    v_layers = auto_verifier.VerifiableLayerBuilder(network).build_layers()

    self.assertLen(v_layers, 1)
    self.assertIsInstance(v_layers[0], layers.Activation)
    self.assertEqual('leaky_relu', v_layers[0].activation)
    self.assertLen(v_layers[0].parameters, 1)
    self.assertAllClose(0.3, v_layers[0].parameters['alpha'])

  def test_avgpool(self):
    def module(inputs):
      return tf.nn.avg_pool(inputs, ksize=(3, 3),
                            padding='VALID', strides=(2, 2))

    network = ibp.VerifiableModelWrapper(module)
    network(self._inputs)

    v_layers = auto_verifier.VerifiableLayerBuilder(network).build_layers()

    self.assertLen(v_layers, 1)

# Path: deep_verify/src/auto_verifier.py
# class NotVerifiableError(Exception):
# class VerifiableLayerBuilder(object):
#   def __init__(self, network):
#   def build_layers(self):
#   def _build_layers_rec(self, node, known_fanout=1, batchnorm_node=None):
#   def _fuse(self, verifiable_layers):
# 
# Path: deep_verify/src/layers/layers.py
# class VerifiableLayer(object):
# class CustomOp(object):
# class SingleVerifiableLayer(VerifiableLayer):
# class AffineLayer(SingleVerifiableLayer):
# class Conv(AffineLayer):
# class Linear(AffineLayer):
# class AvgPool(AffineLayer):
# class MaxPool(SingleVerifiableLayer):
# class Activation(SingleVerifiableLayer):
#   def __init__(self):
#   def branches(self):
#   def input_node(self):
#   def output_node(self):
#   def input_shape(self):
#   def output_shape(self):
#   def inputs(self):
#   def outputs(self):
#   def input_bounds(self):
#   def output_bounds(self):
#   def dual_shape(self):
#   def set_no_duals(self):
#   def reshape_duals_forwards(self, next_layer, dual_vars):
#   def project_duals_op(self, dual_vars):  # pylint:disable=unused-argument
#   def visit_linear(self, layer, w, b, *args, **kwargs):
#   def visit_conv(self, layer, w, b, padding, strides, *args, **kwargs):
#   def visit_avgpool(self, layer, *args, **kwargs):
#   def visit_maxpool(self, layer, *args, **kwargs):
#   def visit_activation(self, layer, *args, **kwargs):
#   def __init__(self, input_node, output_node, module,
#                batch_norm=None, reshape=False):
#   def input_node(self):
#   def output_node(self):
#   def is_activation(self):
#   def module(self):
#   def batch_norm(self):
#   def reshape(self):
#   def backward_prop_batchnorm(self, y):
#   def backward_prop_batchnorm_bias(self, y, bias):
#   def custom_op(self, op, *args, **kwargs):
#   def is_activation(self):
#   def forward_prop(self, x, apply_bias=False, w_fn=None):
#   def backward_prop(self, y, w_fn=None):
#   def backward_prop_bias(self, y):
#   def flatten(self):
#   def __init__(self, input_node, output_node, module, batch_norm=None,
#                reshape=False):
#   def forward_prop(self, x, apply_bias=False, w_fn=None):
#   def backward_prop(self, y, w_fn=None):
#   def backward_prop_bias(self, y):
#   def flatten(self):
#   def custom_op(self, op, *args, **kwargs):
#   def __init__(self, input_node, output_node, module, batch_norm=None,
#                reshape=False):
#   def forward_prop(self, x, apply_bias=False, w_fn=None):
#   def backward_prop(self, y, w_fn=None):
#   def backward_prop_bias(self, y):
#   def flatten(self):
#   def custom_op(self, op, *args, **kwargs):
#   def get_objective_weights(self, labels, target_strategy=None):
#   def __init__(self, input_node, output_node,
#                kernel_shape, strides, reshape=False):
#   def kernel_shape(self):
#   def strides(self):
#   def forward_prop(self, x, apply_bias=False, w_fn=None):
#   def backward_prop(self, y, w_fn=None):
#   def backward_prop_bias(self, y):
#   def flatten(self):
#   def custom_op(self, op, *args, **kwargs):
#   def __init__(self, input_node, output_node,
#                kernel_shape, strides, with_relu=False, reshape=False):
#   def kernel_shape(self):
#   def strides(self):
#   def with_relu(self):
#   def is_activation(self):
#   def custom_op(self, op, *args, **kwargs):
#   def __init__(self, input_node, output_node, module,
#                reshape=False, parameters=None):
#   def is_activation(self):
#   def activation(self):
#   def parameters(self):
#   def custom_op(self, op, *args, **kwargs):
# def create_verifiable_layer(input_node, output_node, module,
#                             batch_norm=None, reshape=False,
#                             parameters=None):


# Path: deep_verify/tests/auto_verifier_test.py
from absl.testing import parameterized
from deep_verify.src import auto_verifier
from deep_verify.src.layers import layers
import interval_bound_propagation as ibp
import sonnet as snt
import tensorflow as tf

    self.assertEqual('relu', v_layers[1].activation)

    self.assertIsInstance(v_layers[2], layers.Linear)
    self.assertIs(linear, v_layers[2].module)

  def test_leaky_relu(self):
    module = lambda x: tf.nn.leaky_relu(x, alpha=0.3)

    network = ibp.VerifiableModelWrapper(module)
    network(self._inputs)

    v_layers = auto_verifier.VerifiableLayerBuilder(network).build_layers()

    self.assertLen(v_layers, 1)
    self.assertIsInstance(v_layers[0], layers.Activation)
    self.assertEqual('leaky_relu', v_layers[0].activation)
    self.assertLen(v_layers[0].parameters, 1)
    self.assertAllClose(0.3, v_layers[0].parameters['alpha'])

  def test_avgpool(self):
    def module(inputs):
      return tf.nn.avg_pool(inputs, ksize=(3, 3),
                            padding='VALID', strides=(2, 2))

    network = ibp.VerifiableModelWrapper(module)
    network(self._inputs)

    v_layers = auto_verifier.VerifiableLayerBuilder(network).build_layers()

    self.assertLen(v_layers, 1)

    self.assertIsInstance(v_layers[0], layers.AvgPool)