# Path: interval_bound_propagation/src/layers.py
# class BatchNorm(snt.BatchNorm):
# class ImageNorm(snt.AbstractModule):
#   def __init__(self, axis=None, offset=True, scale=False,
#                decay_rate=0.999, eps=1e-3, initializers=None,
#                partitioners=None, regularizers=None,
#                update_ops_collection=None, name='batch_norm'):
#   def _build_statistics(self, input_batch, axis, use_batch_stats, stat_dtype):
#   def _build(self, input_batch, is_training=True, test_local_stats=False,
#              reuse=False):
#   def scale(self):
#   def bias(self):
#   def mean(self):
#   def variance(self):
#   def epsilon(self):
#   def __init__(self, mean, std, name='image_norm'):
#   def _build(self, inputs):
#   def scale(self):
#   def offset(self):
#   def apply(self, inputs):
# 
# Path: interval_bound_propagation/src/verifiable_wrapper.py
# class VerifiableWrapper(object):
# class ModelInputWrapper(object):
# class ConstWrapper(VerifiableWrapper):
# class LinearFCWrapper(VerifiableWrapper):
# class LinearConvWrapper(VerifiableWrapper):
# class LinearConv1dWrapper(LinearConvWrapper):
# class LinearConv2dWrapper(LinearConvWrapper):
# class IncreasingMonotonicWrapper(VerifiableWrapper):
# class SoftmaxWrapper(VerifiableWrapper):
# class PiecewiseMonotonicWrapper(VerifiableWrapper):
# class ImageNormWrapper(IncreasingMonotonicWrapper):
# class BatchNormWrapper(VerifiableWrapper):
# class BatchReshapeWrapper(VerifiableWrapper):
# class BatchFlattenWrapper(BatchReshapeWrapper):
#   def __init__(self, module):
#   def input_bounds(self):
#   def output_bounds(self):
#   def module(self):
#   def __str__(self):
#   def propagate_bounds(self, *input_bounds):
#   def _propagate_through(self, module, *input_bounds):
#   def __init__(self, index):
#   def index(self):
#   def output_bounds(self):
#   def output_bounds(self, bounds):
#   def __str__(self):
#   def _propagate_through(self, module):
#   def __init__(self, module):
#   def _propagate_through(self, module, input_bounds):
#   def __init__(self, module):
#   def _propagate_through(self, module, input_bounds):
#   def __init__(self, module):
#   def _propagate_through(self, module, input_bounds):
#   def __init__(self, module, **parameters):
#   def parameters(self):
#   def _propagate_through(self, module, main_bounds, *other_input_bounds):
#   def __init__(self):
#   def _propagate_through(self, module, input_bounds):
#   def __init__(self, module, boundaries=()):
#   def boundaries(self):
#   def _propagate_through(self, module, main_bounds, *other_input_bounds):
#   def __init__(self, module):
#   def inner_module(self):
#   def __init__(self, module):
#   def _propagate_through(self, module, input_bounds):
#   def __init__(self, module, shape):
#   def shape(self):
#   def _propagate_through(self, module, input_bounds):
#   def __init__(self, module):


import collections
import numpy as np
import sonnet as snt
import tensorflow.compat.v1 as tf
from absl import logging
from interval_bound_propagation.src import layers
from interval_bound_propagation.src import verifiable_wrapper
      logging.warn('Unprocessed module "%s"', str(subgraph.module))
      return
    if subgraph.outputs in input_nodes:
      # The Sonnet module is just returning its input as its output.
      # This may happen with a reshape in which the shape does not change.
      return

    self._add_module(self._wrapper_for_observed_module(subgraph),
                     subgraph.outputs, *input_nodes)

  def _inputs_for_observed_module(self, subgraph):
    """Extracts input tensors from a connected Sonnet module.

    This default implementation supports common layer types, but should be
    overridden if custom layer types are to be supported.

    Args:
      subgraph: `snt.ConnectedSubGraph` specifying the Sonnet module being
        connected, and its inputs and outputs.

    Returns:
      List of input tensors, or None if not a supported Sonnet module.
    """
    m = subgraph.module
    # Only support a few operations for now.
    if not (isinstance(m, snt.BatchReshape) or
            isinstance(m, snt.Linear) or
            isinstance(m, snt.Conv1D) or
            isinstance(m, snt.Conv2D) or
            isinstance(m, snt.BatchNorm) or

# Path: interval_bound_propagation/src/layers.py
# class BatchNorm(snt.BatchNorm):
# class ImageNorm(snt.AbstractModule):
#   def __init__(self, axis=None, offset=True, scale=False,
#                decay_rate=0.999, eps=1e-3, initializers=None,
#                partitioners=None, regularizers=None,
#                update_ops_collection=None, name='batch_norm'):
#   def _build_statistics(self, input_batch, axis, use_batch_stats, stat_dtype):
#   def _build(self, input_batch, is_training=True, test_local_stats=False,
#              reuse=False):
#   def scale(self):
#   def bias(self):
#   def mean(self):
#   def variance(self):
#   def epsilon(self):
#   def __init__(self, mean, std, name='image_norm'):
#   def _build(self, inputs):
#   def scale(self):
#   def offset(self):
#   def apply(self, inputs):
# 
# Path: interval_bound_propagation/src/verifiable_wrapper.py
# class VerifiableWrapper(object):
# class ModelInputWrapper(object):
# class ConstWrapper(VerifiableWrapper):
# class LinearFCWrapper(VerifiableWrapper):
# class LinearConvWrapper(VerifiableWrapper):
# class LinearConv1dWrapper(LinearConvWrapper):
# class LinearConv2dWrapper(LinearConvWrapper):
# class IncreasingMonotonicWrapper(VerifiableWrapper):
# class SoftmaxWrapper(VerifiableWrapper):
# class PiecewiseMonotonicWrapper(VerifiableWrapper):
# class ImageNormWrapper(IncreasingMonotonicWrapper):
# class BatchNormWrapper(VerifiableWrapper):
# class BatchReshapeWrapper(VerifiableWrapper):
# class BatchFlattenWrapper(BatchReshapeWrapper):
#   def __init__(self, module):
#   def input_bounds(self):
#   def output_bounds(self):
#   def module(self):
#   def __str__(self):
#   def propagate_bounds(self, *input_bounds):
#   def _propagate_through(self, module, *input_bounds):
#   def __init__(self, index):
#   def index(self):
#   def output_bounds(self):
#   def output_bounds(self, bounds):
#   def __str__(self):
#   def _propagate_through(self, module):
#   def __init__(self, module):
#   def _propagate_through(self, module, input_bounds):
#   def __init__(self, module):
#   def _propagate_through(self, module, input_bounds):
#   def __init__(self, module):
#   def _propagate_through(self, module, input_bounds):
#   def __init__(self, module, **parameters):
#   def parameters(self):
#   def _propagate_through(self, module, main_bounds, *other_input_bounds):
#   def __init__(self):
#   def _propagate_through(self, module, input_bounds):
#   def __init__(self, module, boundaries=()):
#   def boundaries(self):
#   def _propagate_through(self, module, main_bounds, *other_input_bounds):
#   def __init__(self, module):
#   def inner_module(self):
#   def __init__(self, module):
#   def _propagate_through(self, module, input_bounds):
#   def __init__(self, module, shape):
#   def shape(self):
#   def _propagate_through(self, module, input_bounds):
#   def __init__(self, module):


# Path: interval_bound_propagation/src/model.py
import collections
import numpy as np
import sonnet as snt
import tensorflow.compat.v1 as tf
from absl import logging
from interval_bound_propagation.src import layers
from interval_bound_propagation.src import verifiable_wrapper

      logging.warn('Unprocessed module "%s"', str(subgraph.module))
      return
    if subgraph.outputs in input_nodes:
      # The Sonnet module is just returning its input as its output.
      # This may happen with a reshape in which the shape does not change.
      return

    self._add_module(self._wrapper_for_observed_module(subgraph),
                     subgraph.outputs, *input_nodes)

  def _inputs_for_observed_module(self, subgraph):
    """Extracts input tensors from a connected Sonnet module.

    This default implementation supports common layer types, but should be
    overridden if custom layer types are to be supported.

    Args:
      subgraph: `snt.ConnectedSubGraph` specifying the Sonnet module being
        connected, and its inputs and outputs.

    Returns:
      List of input tensors, or None if not a supported Sonnet module.
    """
    m = subgraph.module
    # Only support a few operations for now.
    if not (isinstance(m, snt.BatchReshape) or
            isinstance(m, snt.Linear) or
            isinstance(m, snt.Conv1D) or
            isinstance(m, snt.Conv2D) or
            isinstance(m, snt.BatchNorm) or

            isinstance(m, layers.ImageNorm)):