# Path: jax_verify/extensions/sdp_verify/cvxpy_verify.py
# def solve_mip_mlp_elided(verif_instance):
# def solve_lp_primal_elided(verif_instance):
# def solve_sdp_mlp_elided(verif_instance, solver_name='SCS', verbose=False,
#                          check_feasibility=False, feasibility_margin=0.0):
#   def _slice(i):
#   def p_slice(i, j):
# def _violation(arr):
# def _violation_leq(arr1, arr2):
# def check_sdp_bounds_numpy(P, verif_instance, input_bounds=(0, 1)):
#   P = cp.Variable((1 + sum(layer_sizes), 1 + sum(layer_sizes)))
# 
# Path: jax_verify/extensions/sdp_verify/utils.py
# class SdpDualVerifInstance(_SdpDualVerifInstance):
# class VerifInstanceTypes(enum.Enum):
# class DualVarTypes(enum.Enum):
# def mlp_layer_sizes(params):
# def nn_layer_sizes(params):
# def layer_sizes_from_bounds(bounds):
# def predict_mlp(params, inputs):
# def fwd(inputs, layer_params):
# def predict_cnn(params, inputs, include_preactivations=False):
# def get_network_activs(params, x):
# def get_layer_params(fun_to_extract, example_input):
#   def _get_const_input_arg(eqn):
# def boundprop(params, bounds_in):
# def init_bound(x, epsilon, input_bounds=(0., 1.), add_batch_dim=True):
# def ibp_bound_elided(verif_instance):
# def ibp_bound_nonelided(verif_instance):
# def make_relu_robust_verif_instance(
#     params, bounds=None, target_label=1, label=2, input_bounds=None):
# def make_relu_robust_verif_instance_elided(
#     params, bounds=None, input_bounds=None):
# def output_size_and_verif_type(params, bounds):
# def elide_params(params, label, target_label, op_size):
# def preprocess_cifar(image, inception_preprocess=False, perturbation=False):
# def preprocessed_cifar_eps_and_input_bounds(
#     shape=(32, 32, 3), epsilon=2/255, inception_preprocess=False):
# def adv_objective(model_fn, x, label, target_label):
# def fgsm_single(model_fn, x, label, target_label, epsilon, num_steps,
#                 step_size, input_bounds=(0., 1.)):
# def untargeted_margin_loss(logits, labels):
# def pgd_default(model_fn, x, label, epsilon, num_steps, step_size,
#                 input_bounds=(0., 1.)):
# def pgd(adv_loss, x_init, epsilon, num_steps, step_size, input_bounds=(0., 1.)):
# def scale_by_variable_opt(multipliers):
#   def init_fn(params):
#   def update_fn(updates, _, params=None):
# def flatten(pytree, backend=np):
# def unflatten_like(a, pytree):
# def structure_like(tree1, tree2):
#   MLP_ELIDED = 'mlp_elided'
#   CNN_ELIDED = 'cnn_elided'
#   EQUALITY = 'equality'
#   INEQUALITY = 'inequality'
# 
# Path: jax_verify/tests/sdp_verify/test_utils.py
# def _init_fc_layer(key, n_in, n_out):
# def _init_conv_layer(key, n_h, n_w, n_cout, n_cin):
# def make_mlp_params(layer_sizes, key):
# def make_cnn_params(layer_sizes, key):
# def make_toy_verif_instance(seed=None, label=None, target_label=None, nn='mlp'):
# def make_mlp_layer_from_conv_layer(layer_params, input_bounds):
# def make_mlp_verif_instance_from_cnn(verif_instance):
#   W = random.normal(k1, (n_in, n_out))/ n_in
#   W = random.normal(k1, (n_h, n_w, n_cin, n_cout))


import unittest
import jax.numpy as jnp
from absl.testing import absltest
from absl.testing import parameterized
from cvxpy.reductions.solvers.defines import INSTALLED_MI_SOLVERS as MIP_SOLVERS
from jax_verify.extensions.sdp_verify import cvxpy_verify
from jax_verify.extensions.sdp_verify import utils
from jax_verify.tests.sdp_verify import test_utils
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Lint as: python3
"""Tests for cvxpy_verify.py."""


NO_MIP_SOLVERS_MESSAGE = 'No mixed-integer solver is installed.'


class CvxpyTest(parameterized.TestCase):

  @unittest.skipUnless(MIP_SOLVERS, NO_MIP_SOLVERS_MESSAGE)
  def test_mip_status(self):
    """Test toy MIP is solved optimally by cvxpy."""
    for seed in range(10):
      verif_instance = test_utils.make_toy_verif_instance(seed)
      val, info = cvxpy_verify.solve_mip_mlp_elided(verif_instance)
      status = info['problem'].status
      assert val is not None
      assert status in ('optimal', 'optimal_inaccurate'), f'Status is {status}.'

  def test_sdp_status(self):
    """Test toy SDP is solved optimally by cvxpy."""
    for seed in range(10):
      verif_instance = test_utils.make_toy_verif_instance(seed)

# Path: jax_verify/extensions/sdp_verify/cvxpy_verify.py
# def solve_mip_mlp_elided(verif_instance):
# def solve_lp_primal_elided(verif_instance):
# def solve_sdp_mlp_elided(verif_instance, solver_name='SCS', verbose=False,
#                          check_feasibility=False, feasibility_margin=0.0):
#   def _slice(i):
#   def p_slice(i, j):
# def _violation(arr):
# def _violation_leq(arr1, arr2):
# def check_sdp_bounds_numpy(P, verif_instance, input_bounds=(0, 1)):
#   P = cp.Variable((1 + sum(layer_sizes), 1 + sum(layer_sizes)))
# 
# Path: jax_verify/extensions/sdp_verify/utils.py
# class SdpDualVerifInstance(_SdpDualVerifInstance):
# class VerifInstanceTypes(enum.Enum):
# class DualVarTypes(enum.Enum):
# def mlp_layer_sizes(params):
# def nn_layer_sizes(params):
# def layer_sizes_from_bounds(bounds):
# def predict_mlp(params, inputs):
# def fwd(inputs, layer_params):
# def predict_cnn(params, inputs, include_preactivations=False):
# def get_network_activs(params, x):
# def get_layer_params(fun_to_extract, example_input):
#   def _get_const_input_arg(eqn):
# def boundprop(params, bounds_in):
# def init_bound(x, epsilon, input_bounds=(0., 1.), add_batch_dim=True):
# def ibp_bound_elided(verif_instance):
# def ibp_bound_nonelided(verif_instance):
# def make_relu_robust_verif_instance(
#     params, bounds=None, target_label=1, label=2, input_bounds=None):
# def make_relu_robust_verif_instance_elided(
#     params, bounds=None, input_bounds=None):
# def output_size_and_verif_type(params, bounds):
# def elide_params(params, label, target_label, op_size):
# def preprocess_cifar(image, inception_preprocess=False, perturbation=False):
# def preprocessed_cifar_eps_and_input_bounds(
#     shape=(32, 32, 3), epsilon=2/255, inception_preprocess=False):
# def adv_objective(model_fn, x, label, target_label):
# def fgsm_single(model_fn, x, label, target_label, epsilon, num_steps,
#                 step_size, input_bounds=(0., 1.)):
# def untargeted_margin_loss(logits, labels):
# def pgd_default(model_fn, x, label, epsilon, num_steps, step_size,
#                 input_bounds=(0., 1.)):
# def pgd(adv_loss, x_init, epsilon, num_steps, step_size, input_bounds=(0., 1.)):
# def scale_by_variable_opt(multipliers):
#   def init_fn(params):
#   def update_fn(updates, _, params=None):
# def flatten(pytree, backend=np):
# def unflatten_like(a, pytree):
# def structure_like(tree1, tree2):
#   MLP_ELIDED = 'mlp_elided'
#   CNN_ELIDED = 'cnn_elided'
#   EQUALITY = 'equality'
#   INEQUALITY = 'inequality'
# 
# Path: jax_verify/tests/sdp_verify/test_utils.py
# def _init_fc_layer(key, n_in, n_out):
# def _init_conv_layer(key, n_h, n_w, n_cout, n_cin):
# def make_mlp_params(layer_sizes, key):
# def make_cnn_params(layer_sizes, key):
# def make_toy_verif_instance(seed=None, label=None, target_label=None, nn='mlp'):
# def make_mlp_layer_from_conv_layer(layer_params, input_bounds):
# def make_mlp_verif_instance_from_cnn(verif_instance):
#   W = random.normal(k1, (n_in, n_out))/ n_in
#   W = random.normal(k1, (n_h, n_w, n_cin, n_cout))


# Path: jax_verify/tests/sdp_verify/cvxpy_verify_test.py
import unittest
import jax.numpy as jnp
from absl.testing import absltest
from absl.testing import parameterized
from cvxpy.reductions.solvers.defines import INSTALLED_MI_SOLVERS as MIP_SOLVERS
from jax_verify.extensions.sdp_verify import cvxpy_verify
from jax_verify.extensions.sdp_verify import utils
from jax_verify.tests.sdp_verify import test_utils

#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Lint as: python3
"""Tests for cvxpy_verify.py."""


NO_MIP_SOLVERS_MESSAGE = 'No mixed-integer solver is installed.'


class CvxpyTest(parameterized.TestCase):

  @unittest.skipUnless(MIP_SOLVERS, NO_MIP_SOLVERS_MESSAGE)
  def test_mip_status(self):
    """Test toy MIP is solved optimally by cvxpy."""
    for seed in range(10):
      verif_instance = test_utils.make_toy_verif_instance(seed)
      val, info = cvxpy_verify.solve_mip_mlp_elided(verif_instance)
      status = info['problem'].status
      assert val is not None
      assert status in ('optimal', 'optimal_inaccurate'), f'Status is {status}.'

  def test_sdp_status(self):
    """Test toy SDP is solved optimally by cvxpy."""
    for seed in range(10):
      verif_instance = test_utils.make_toy_verif_instance(seed)

      val, info = cvxpy_verify.solve_sdp_mlp_elided(verif_instance)