# Copyright 2019 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# 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.

"""Functions for proving mathematical properties of expressions."""

import math
import fractions
import operator

from compiler.util import ir_pb2
from compiler.util import ir_util
from compiler.util import traverse_ir


# Create a local alias for math.gcd with a fallback to fractions.gcd if it is
# not available. This can be dropped if pre-3.5 Python support is dropped.
if hasattr(math, 'gcd'):
  _math_gcd = math.gcd
else:
  _math_gcd = fractions.gcd


def compute_constraints_of_expression(expression, ir):
  """Adds appropriate bounding constraints to the given expression."""
  if ir_util.is_constant_type(expression.type):
    return
  expression_variety = expression.WhichOneof("expression")
  if expression_variety == "constant":
    _compute_constant_value_of_constant(expression)
  elif expression_variety == "constant_reference":
    _compute_constant_value_of_constant_reference(expression, ir)
  elif expression_variety == "function":
    _compute_constraints_of_function(expression, ir)
  elif expression_variety == "field_reference":
    _compute_constraints_of_field_reference(expression, ir)
  elif expression_variety == "builtin_reference":
    _compute_constraints_of_builtin_value(expression)
  elif expression_variety == "boolean_constant":
    _compute_constant_value_of_boolean_constant(expression)
  else:
    assert False, "Unknown expression variety {!r}".format(expression_variety)
  if expression.type.WhichOneof("type") == "integer":
    _assert_integer_constraints(expression)


def _compute_constant_value_of_constant(expression):
  value = expression.constant.value
  expression.type.integer.modular_value = value
  expression.type.integer.minimum_value = value
  expression.type.integer.maximum_value = value
  expression.type.integer.modulus = "infinity"


def _compute_constant_value_of_constant_reference(expression, ir):
  referred_object = ir_util.find_object(
      expression.constant_reference.canonical_name, ir)
  if isinstance(referred_object, ir_pb2.EnumValue):
    compute_constraints_of_expression(referred_object.value, ir)
    assert ir_util.is_constant(referred_object.value)
    new_value = str(ir_util.constant_value(referred_object.value))
    expression.type.enumeration.value = new_value
  elif isinstance(referred_object, ir_pb2.Field):
    assert ir_util.field_is_virtual(referred_object), (
        "Non-virtual non-enum-value constant reference should have been caught "
        "in type_check.py")
    compute_constraints_of_expression(referred_object.read_transform, ir)
    expression.type.CopyFrom(referred_object.read_transform.type)
  else:
    assert False, "Unexpected constant reference type."


def _compute_constraints_of_function(expression, ir):
  """Computes the known constraints of the result of a function."""
  for arg in expression.function.args:
    compute_constraints_of_expression(arg, ir)
  op = expression.function.function
  if op in (ir_pb2.Function.ADDITION, ir_pb2.Function.SUBTRACTION):
    _compute_constraints_of_additive_operator(expression)
  elif op == ir_pb2.Function.MULTIPLICATION:
    _compute_constraints_of_multiplicative_operator(expression)
  elif op in (ir_pb2.Function.EQUALITY, ir_pb2.Function.INEQUALITY,
              ir_pb2.Function.LESS, ir_pb2.Function.LESS_OR_EQUAL,
              ir_pb2.Function.GREATER, ir_pb2.Function.GREATER_OR_EQUAL,
              ir_pb2.Function.AND, ir_pb2.Function.OR):
    _compute_constant_value_of_comparison_operator(expression)
  elif op == ir_pb2.Function.CHOICE:
    _compute_constraints_of_choice_operator(expression)
  elif op == ir_pb2.Function.MAXIMUM:
    _compute_constraints_of_maximum_function(expression)
  elif op == ir_pb2.Function.PRESENCE:
    _compute_constraints_of_existence_function(expression, ir)
  elif op in (ir_pb2.Function.UPPER_BOUND, ir_pb2.Function.LOWER_BOUND):
    _compute_constraints_of_bound_function(expression)
  else:
    assert False, "Unknown operator {!r}".format(op)


def _compute_constraints_of_existence_function(expression, ir):
  """Computes the constraints of a $has(field) expression."""
  field_path = expression.function.args[0].field_reference.path[-1]
  field = ir_util.find_object(field_path, ir)
  compute_constraints_of_expression(field.existence_condition, ir)
  expression.type.CopyFrom(field.existence_condition.type)


def _compute_constraints_of_field_reference(expression, ir):
  """Computes the constraints of a reference to a structure's field."""
  field_path = expression.field_reference.path[-1]
  field = ir_util.find_object(field_path, ir)
  if isinstance(field, ir_pb2.Field) and ir_util.field_is_virtual(field):
    # References to virtual fields should have the virtual field's constraints
    # copied over.
    compute_constraints_of_expression(field.read_transform, ir)
    expression.type.CopyFrom(field.read_transform.type)
    return
  # Non-virtual non-integer fields do not (yet) have constraints.
  if expression.type.WhichOneof("type") == "integer":
    # TODO(bolms): These lines will need to change when support is added for
    # fixed-point types.
    expression.type.integer.modulus = "1"
    expression.type.integer.modular_value = "0"
    type_definition = ir_util.find_parent_object(field_path, ir)
    if isinstance(field, ir_pb2.Field):
      referrent_type = field.type
    else:
      referrent_type = field.physical_type_alias
    if referrent_type.HasField("size_in_bits"):
      type_size = ir_util.constant_value(referrent_type.size_in_bits)
    else:
      field_size = ir_util.constant_value(field.location.size)
      if field_size is None:
        type_size = None
      else:
        type_size = field_size * type_definition.addressable_unit
    assert referrent_type.HasField("atomic_type"), field
    assert not referrent_type.atomic_type.reference.canonical_name.module_file
    _set_integer_constraints_from_physical_type(
        expression, referrent_type, type_size)


def _set_integer_constraints_from_physical_type(
    expression, physical_type, type_size):
  """Copies the integer constraints of an expression from a physical type."""
  # SCAFFOLDING HACK: In order to keep changelists manageable, this hardcodes
  # the ranges for all of the Emboss Prelude integer types.   This would break
  # any user-defined `external` integer types, but that feature isn't fully
  # implemented in the C++ backend, so it doesn't matter for now.
  #
  # Adding the attribute(s) for integer bounds will require new operators:
  # integer/flooring division, remainder, and exponentiation (2**N, 10**N).
  #
  # (Technically, there are a few sets of operators that would work: for
  # example, just the choice operator `?:` is sufficient, but very ugly.
  # Bitwise AND, bitshift, and exponentiation would also work, but `10**($bits
  # >> 2) * 2**($bits & 0b11) - 1` isn't quite as clear as `10**($bits // 4) *
  # 2**($bits % 4) - 1`, in my (bolms@) opinion.)
  #
  # TODO(bolms): Add a scheme for defining integer bounds on user-defined
  # external types.
  if type_size is None:
    # If the type_size is unknown, then we can't actually say anything about the
    # minimum and maximum values of the type.  For UInt, Int, and Bcd, an error
    # will be thrown during the constraints check stage.
    expression.type.integer.minimum_value = "-infinity"
    expression.type.integer.maximum_value = "infinity"
    return
  name = tuple(physical_type.atomic_type.reference.canonical_name.object_path)
  if name == ("UInt",):
    expression.type.integer.minimum_value = "0"
    expression.type.integer.maximum_value = str(2**type_size - 1)
  elif name == ("Int",):
    expression.type.integer.minimum_value = str(-(2**(type_size - 1)))
    expression.type.integer.maximum_value = str(2**(type_size - 1) - 1)
  elif name == ("Bcd",):
    expression.type.integer.minimum_value = "0"
    expression.type.integer.maximum_value = str(
        10**(type_size // 4) * 2**(type_size % 4) - 1)
  else:
    assert False, "Unknown integral type " + ".".join(name)


def _compute_constraints_of_parameter(parameter):
  if parameter.type.WhichOneof("type") == "integer":
    type_size = ir_util.constant_value(
        parameter.physical_type_alias.size_in_bits)
    _set_integer_constraints_from_physical_type(
        parameter, parameter.physical_type_alias, type_size)


def _compute_constraints_of_builtin_value(expression):
  """Computes the constraints of a builtin (like $static_size_in_bits)."""
  name = expression.builtin_reference.canonical_name.object_path[0]
  if name == "$static_size_in_bits":
    expression.type.integer.modulus = "1"
    expression.type.integer.modular_value = "0"
    expression.type.integer.minimum_value = "0"
    # The maximum theoretically-supported size of something is 2**64 bytes,
    # which is 2**64 * 8 bits.
    #
    # Really, $static_size_in_bits is only valid in expressions that have to be
    # evaluated at compile time anyway, so it doesn't really matter if the
    # bounds are excessive.
    expression.type.integer.maximum_value = "infinity"
  elif name == "$is_statically_sized":
    # No bounds on a boolean variable.
    pass
  elif name == "$logical_value":
    # $logical_value is the placeholder used in inferred write-through
    # transformations.
    #
    # Only integers (currently) have "real" write-through transformations, but
    # fields that would otherwise be straight aliases, but which have a
    # [requires] attribute, are elevated to write-through fields, so that the
    # [requires] clause can be checked in Write, CouldWriteValue, TryToWrite,
    # Read, and Ok.
    if expression.type.WhichOneof("type") == "integer":
      assert expression.type.integer.modulus
      assert expression.type.integer.modular_value
      assert expression.type.integer.minimum_value
      assert expression.type.integer.maximum_value
    elif expression.type.WhichOneof("type") == "enumeration":
      assert expression.type.enumeration.name
    elif expression.type.WhichOneof("type") == "boolean":
      pass
    else:
      assert False, "Unexpected type for $logical_value"
  else:
    assert False, "Unknown builtin " + name


def _compute_constant_value_of_boolean_constant(expression):
  expression.type.boolean.value = expression.boolean_constant.value


def _add(a, b):
  """Adds a and b, where a and b are ints, "infinity", or "-infinity"."""
  if a in ("infinity", "-infinity"):
    a, b = b, a
  if b == "infinity":
    assert a != "-infinity"
    return "infinity"
  if b == "-infinity":
    assert a != "infinity"
    return "-infinity"
  return int(a) + int(b)


def _sub(a, b):
  """Subtracts b from a, where a and b are ints, "infinity", or "-infinity"."""
  if b == "infinity":
    return _add(a, "-infinity")
  if b == "-infinity":
    return _add(a, "infinity")
  return _add(a, -int(b))


def _sign(a):
  """Returns 1 if a > 0, 0 if a == 0, and -1 if a < 0."""
  if a == "infinity":
    return 1
  if a == "-infinity":
    return -1
  if int(a) > 0:
    return 1
  if int(a) < 0:
    return -1
  return 0


def _mul(a, b):
  """Multiplies a and b, where a and b are ints, "infinity", or "-infinity"."""
  if _is_infinite(a):
    a, b = b, a
  if _is_infinite(b):
    sign = _sign(a) * _sign(b)
    if sign > 0:
      return "infinity"
    if sign < 0:
      return "-infinity"
    return 0
  return int(a) * int(b)


def _is_infinite(a):
  return a in ("infinity", "-infinity")


def _max(a):
  """Returns max of a, where elements are ints, "infinity", or "-infinity"."""
  if any(n == "infinity" for n in a):
    return "infinity"
  if all(n == "-infinity" for n in a):
    return "-infinity"
  return max(int(n) for n in a if not _is_infinite(n))


def _min(a):
  """Returns min of a, where elements are ints, "infinity", or "-infinity"."""
  if any(n == "-infinity" for n in a):
    return "-infinity"
  if all(n == "infinity" for n in a):
    return "infinity"
  return min(int(n) for n in a if not _is_infinite(n))


def _compute_constraints_of_additive_operator(expression):
  """Computes the modular value of an additive expression."""
  funcs = {
      ir_pb2.Function.ADDITION: _add,
      ir_pb2.Function.SUBTRACTION: _sub,
  }
  func = funcs[expression.function.function]
  args = expression.function.args
  for arg in args:
    assert arg.type.integer.modular_value, str(expression)
  left, right = args
  unadjusted_modular_value = func(left.type.integer.modular_value,
                                  right.type.integer.modular_value)
  new_modulus = _greatest_common_divisor(left.type.integer.modulus,
                                         right.type.integer.modulus)
  expression.type.integer.modulus = str(new_modulus)
  if new_modulus == "infinity":
    expression.type.integer.modular_value = str(unadjusted_modular_value)
  else:
    expression.type.integer.modular_value = str(unadjusted_modular_value %
                                                new_modulus)
  lmax = left.type.integer.maximum_value
  lmin = left.type.integer.minimum_value
  if expression.function.function == ir_pb2.Function.SUBTRACTION:
    rmax = right.type.integer.minimum_value
    rmin = right.type.integer.maximum_value
  else:
    rmax = right.type.integer.maximum_value
    rmin = right.type.integer.minimum_value
  expression.type.integer.minimum_value = str(func(lmin, rmin))
  expression.type.integer.maximum_value = str(func(lmax, rmax))


def _compute_constraints_of_multiplicative_operator(expression):
  """Computes the modular value of a multiplicative expression."""
  bounds = [arg.type.integer for arg in expression.function.args]

  # The minimum and maximum values can come from any of the four pairings of
  # (left min, left max) with (right min, right max), depending on the signs and
  # magnitudes of the minima and maxima.  E.g.:
  #
  # max = left max * right max: [ 2,  3] * [ 2,  3]
  # max = left min * right min: [-3, -2] * [-3, -2]
  # max = left max * right min: [-3, -2] * [ 2,  3]
  # max = left min * right max: [ 2,  3] * [-3, -2]
  # max = left max * right max: [-2,  3] * [-2,  3]
  # max = left min * right min: [-3,  2] * [-3,  2]
  #
  # For uncorrelated multiplication, the minimum and maximum will always come
  # from multiplying one extreme by another: if x is nonzero, then
  #
  #     (y + e) * x > y * x  ||  (y - e) * x > y * x
  #
  # for arbitrary nonzero e, so the extrema can only occur when we either cannot
  # add or cannot subtract e.
  #
  # Correlated multiplication (e.g., `x * x`) can have tighter bounds, but
  # Emboss is not currently trying to be that smart.
  lmin, lmax = bounds[0].minimum_value, bounds[0].maximum_value
  rmin, rmax = bounds[1].minimum_value, bounds[1].maximum_value
  extrema = [_mul(lmax, rmax), _mul(lmin, rmax),  #
             _mul(lmax, rmin), _mul(lmin, rmin)]
  expression.type.integer.minimum_value = str(_min(extrema))
  expression.type.integer.maximum_value = str(_max(extrema))

  if all(bound.modulus == "infinity" for bound in bounds):
    # If both sides are constant, the result is constant.
    expression.type.integer.modulus = "infinity"
    expression.type.integer.modular_value = str(int(bounds[0].modular_value) *
                                                int(bounds[1].modular_value))
    return

  if any(bound.modulus == "infinity" for bound in bounds):
    # If one side is constant and the other is not, then the non-constant
    # modulus and modular_value can both be multiplied by the constant.  E.g.,
    # if `a` is congruent to 3 mod 5, then `4 * a` will be congruent to 12 mod
    # 20:
    #
    #   a = ...   |  4 * a = ...  |  4 * a mod 20 = ...
    #   3         |  12           |  12
    #   8         |  32           |  12
    #   13        |  52           |  12
    #   18        |  72           |  12
    #   23        |  92           |  12
    #   28        |  112          |  12
    #   33        |  132          |  12
    #
    # This is trivially shown by noting that the difference between consecutive
    # possible values for `4 * a` always differ by 20.
    if bounds[0].modulus == "infinity":
      constant, variable = bounds
    else:
      variable, constant = bounds
    if int(constant.modular_value) == 0:
      # If the constant is 0, the result is 0, no matter what the variable side
      # is.
      expression.type.integer.modulus = "infinity"
      expression.type.integer.modular_value = "0"
      return
    new_modulus = int(variable.modulus) * abs(int(constant.modular_value))
    expression.type.integer.modulus = str(new_modulus)
    # The `% new_modulus` will force the `modular_value` to be positive, even
    # when `constant.modular_value` is negative.
    expression.type.integer.modular_value = str(
        int(variable.modular_value) * int(constant.modular_value) % new_modulus)
    return

  # If neither side is constant, then the result is more complex.  Full proof is
  # available in g3doc/modular_congruence_multiplication_proof.md
  #
  # Essentially, if:
  #
  # l == _ * l_mod + l_mv
  # r == _ * r_mod + r_mv
  #
  # Then we find l_mod0 and r_mod0 in:
  #
  # l == (_ * l_mod_nz + l_mv_nz) * l_mod0
  # r == (_ * r_mod_nz + r_mv_nz) * r_mod0
  #
  # And finally conclude:
  #
  # l * r == _ * GCD(l_mod_nz, r_mod_nz) * l_mod0 * r_mod0 + l_mv * r_mv
  product_of_zero_congruence_moduli = 1
  product_of_modular_values = 1
  nonzero_congruence_moduli = []
  for bound in bounds:
    zero_congruence_modulus = _greatest_common_divisor(bound.modulus,
                                                       bound.modular_value)
    assert int(bound.modulus) % zero_congruence_modulus == 0
    product_of_zero_congruence_moduli *= zero_congruence_modulus
    product_of_modular_values *= int(bound.modular_value)
    nonzero_congruence_moduli.append(int(bound.modulus) //
                                     zero_congruence_modulus)
  shared_nonzero_congruence_modulus = _greatest_common_divisor(
      nonzero_congruence_moduli[0], nonzero_congruence_moduli[1])
  final_modulus = (shared_nonzero_congruence_modulus *
                   product_of_zero_congruence_moduli)
  expression.type.integer.modulus = str(final_modulus)
  expression.type.integer.modular_value = str(product_of_modular_values %
                                              final_modulus)


def _assert_integer_constraints(expression):
  """Asserts that the integer bounds of expression are self-consistent.

  Asserts that `minimum_value` and `maximum_value` are congruent to
  `modular_value` modulo `modulus`.

  If `modulus` is "infinity", asserts that `minimum_value`, `maximum_value`, and
  `modular_value` are all equal.

  If `minimum_value` is equal to `maximum_value`, asserts that `modular_value`
  is equal to both, and that `modulus` is "infinity".

  Arguments:
      expression: an expression with type.integer

  Returns:
      None
  """
  bounds = expression.type.integer
  if bounds.modulus == "infinity":
    assert bounds.minimum_value == bounds.modular_value
    assert bounds.maximum_value == bounds.modular_value
    return
  modulus = int(bounds.modulus)
  assert modulus > 0
  if bounds.minimum_value != "-infinity":
    assert int(bounds.minimum_value) % modulus == int(bounds.modular_value)
  if bounds.maximum_value != "infinity":
    assert int(bounds.maximum_value) % modulus == int(bounds.modular_value)
  if bounds.minimum_value == bounds.maximum_value:
    # TODO(bolms): I believe there are situations using the not-yet-implemented
    # integer division operator that would trigger these asserts, so they should
    # be turned into assignments (with corresponding tests) when implementing
    # division.
    assert bounds.modular_value == bounds.minimum_value
    assert bounds.modulus == "infinity"
  if bounds.minimum_value != "-infinity" and bounds.maximum_value != "infinity":
    assert int(bounds.minimum_value) <= int(bounds.maximum_value)


def _compute_constant_value_of_comparison_operator(expression):
  """Computes the constant value, if any, of a comparison operator."""
  args = expression.function.args
  if all(ir_util.is_constant(arg) for arg in args):
    functions = {
        ir_pb2.Function.EQUALITY: operator.eq,
        ir_pb2.Function.INEQUALITY: operator.ne,
        ir_pb2.Function.LESS: operator.lt,
        ir_pb2.Function.LESS_OR_EQUAL: operator.le,
        ir_pb2.Function.GREATER: operator.gt,
        ir_pb2.Function.GREATER_OR_EQUAL: operator.ge,
        ir_pb2.Function.AND: operator.and_,
        ir_pb2.Function.OR: operator.or_,
    }
    func = functions[expression.function.function]
    expression.type.boolean.value = func(
        *[ir_util.constant_value(arg) for arg in args])


def _compute_constraints_of_bound_function(expression):
  """Computes the constraints of $upper_bound or $lower_bound."""
  if expression.function.function == ir_pb2.Function.UPPER_BOUND:
    value = expression.function.args[0].type.integer.maximum_value
  elif expression.function.function == ir_pb2.Function.LOWER_BOUND:
    value = expression.function.args[0].type.integer.minimum_value
  else:
    assert False, "Non-bound function"
  expression.type.integer.minimum_value = value
  expression.type.integer.maximum_value = value
  expression.type.integer.modular_value = value
  expression.type.integer.modulus = "infinity"


def _compute_constraints_of_maximum_function(expression):
  """Computes the constraints of the $max function."""
  assert expression.type.WhichOneof("type") == "integer"
  args = expression.function.args
  assert args[0].type.WhichOneof("type") == "integer"
  # The minimum value of the result occurs when every argument takes its minimum
  # value, which means that the minimum result is the maximum-of-minimums.
  expression.type.integer.minimum_value = str(_max(
      [arg.type.integer.minimum_value for arg in args]))
  # The maximum result is the maximum-of-maximums.
  expression.type.integer.maximum_value = str(_max(
      [arg.type.integer.maximum_value for arg in args]))
  # If the expression is dominated by a constant factor, then the result is
  # constant.  I (bolms@) believe this is the only case where
  # _compute_constraints_of_maximum_function might violate the assertions in
  # _assert_integer_constraints.
  if (expression.type.integer.minimum_value ==
      expression.type.integer.maximum_value):
    expression.type.integer.modular_value = (
        expression.type.integer.minimum_value)
    expression.type.integer.modulus = "infinity"
    return
  result_modulus = args[0].type.integer.modulus
  result_modular_value = args[0].type.integer.modular_value
  # The result of $max(a, b) could be either a or b, which means that the result
  # of $max(a, b) uses the _shared_modular_value() of a and b, just like the
  # choice operator '?:'.
  #
  # This also takes advantage of the fact that $max(a, b, c, d, ...) is
  # equivalent to $max(a, $max(b, $max(c, $max(d, ...)))), so it is valid to
  # call _shared_modular_value() in a loop.
  for arg in args[1:]:
    # TODO(bolms): I think the bounds could be tigher in some cases where
    # arg.maximum_value is less than the new expression.minimum_value, and
    # in some very specific cases where arg.maximum_value is greater than the
    # new expression.minimum_value, but arg.maximum_value - arg.modulus is less
    # than expression.minimum_value.
    result_modulus, result_modular_value = _shared_modular_value(
        (result_modulus, result_modular_value),
        (arg.type.integer.modulus, arg.type.integer.modular_value))
  expression.type.integer.modulus = str(result_modulus)
  expression.type.integer.modular_value = str(result_modular_value)


def _shared_modular_value(left, right):
  """Returns the shared modulus and modular value of left and right.

  Arguments:
    left: A tuple of (modulus, modular value)
    right: A tuple of (modulus, modular value)

  Returns:
    A tuple of (modulus, modular_value) such that:

    left.modulus % result.modulus == 0
    right.modulus % result.modulus == 0
    left.modular_value % result.modulus = result.modular_value
    right.modular_value % result.modulus = result.modular_value

    That is, the result.modulus and result.modular_value will be compatible
    with, but (possibly) less restrictive than both left.(modulus,
    modular_value) and right.(modulus, modular_value).
  """
  left_modulus, left_modular_value = left
  right_modulus, right_modular_value = right
  # The combined modulus is gcd(gcd(left_modulus, right_modulus),
  # left_modular_value - right_modular_value).
  #
  # The inner gcd normalizes the left_modulus and right_modulus, but can leave
  # incompatible modular_values.  The outer gcd finds a modulus to which both
  # modular_values are congruent.  Some examples:
  #
  #     left          |  right         |  res
  #     --------------+----------------+--------------------
  #     l % 12 == 7   |  r % 20 == 15  |  res % 4 == 3
  #     l == 35       |  r % 20 == 15  |  res % 20 == 15
  #     l % 24 == 15  |  r % 12 == 7   |  res % 4 == 3
  #     l % 20 == 15  |  r % 20 == 10  |  res % 5 == 0
  #     l % 20 == 16  |  r % 20 == 11  |  res % 5 == 1
  #     l == 10       |  r == 7        |  res % 3 == 1
  #     l == 4        |  r == 4        |  res == 4
  #
  # The cases where one side or the other are constant are handled
  # automatically by the fact that _greatest_common_divisor("infinity", x)
  # is x.
  common_modulus = _greatest_common_divisor(left_modulus, right_modulus)
  new_modulus = _greatest_common_divisor(
      common_modulus, abs(int(left_modular_value) - int(right_modular_value)))
  if new_modulus == "infinity":
    # The only way for the new_modulus to come out as "infinity" *should* be
    # if both if_true and if_false have the same constant value.
    assert left_modular_value == right_modular_value
    assert left_modulus == right_modulus == "infinity"
    return new_modulus, left_modular_value
  else:
    assert (int(left_modular_value) % new_modulus ==
            int(right_modular_value) % new_modulus)
    return new_modulus, int(left_modular_value) % new_modulus


def _compute_constraints_of_choice_operator(expression):
  """Computes the constraints of a choice operation '?:'."""
  condition, if_true, if_false = expression.function.args
  if condition.type.boolean.HasField("value"):
    # The generated expressions for $size_in_bits and $size_in_bytes look like
    #
    #     $max((field1_existence_condition ? field1_start + field1_size : 0),
    #          (field2_existence_condition ? field2_start + field2_size : 0),
    #          (field3_existence_condition ? field3_start + field3_size : 0),
    #          ...)
    #
    # Since most existence_conditions are just "true", it is important to select
    # the tighter bounds in those cases -- otherwise, only zero-length
    # structures could have a constant $size_in_bits or $size_in_bytes.
    side = if_true if condition.type.boolean.value else if_false
    expression.type.CopyFrom(side.type)
    return
  # The type.integer minimum_value/maximum_value bounding code is needed since
  # constraints.check_constraints() will complain if minimum and maximum are not
  # set correctly.  I'm (bolms@) not sure if the modulus/modular_value pulls its
  # weight, but for completeness I've left it in.
  if if_true.type.WhichOneof("type") == "integer":
    # The minimum value of the choice is the minimum value of either side, and
    # the maximum is the maximum value of either side.
    expression.type.integer.minimum_value = str(_min([
        if_true.type.integer.minimum_value,
        if_false.type.integer.minimum_value]))
    expression.type.integer.maximum_value = str(_max([
        if_true.type.integer.maximum_value,
        if_false.type.integer.maximum_value]))
    new_modulus, new_modular_value = _shared_modular_value(
        (if_true.type.integer.modulus, if_true.type.integer.modular_value),
        (if_false.type.integer.modulus, if_false.type.integer.modular_value))
    expression.type.integer.modulus = str(new_modulus)
    expression.type.integer.modular_value = str(new_modular_value)
  else:
    assert if_true.type.WhichOneof("type") in ("boolean", "enumeration"), (
        "Unknown type {} for expression".format(
            if_true.type.WhichOneof("type")))


def _greatest_common_divisor(a, b):
  """Returns the greatest common divisor of a and b.

  Arguments:
    a: an integer, a stringified integer, or the string "infinity"
    b: an integer, a stringified integer, or the string "infinity"

  Returns:
    Conceptually, "infinity" is treated as the product of all integers.

    If both a and b are 0, returns "infinity".

    Otherwise, if either a or b are "infinity", and the other is 0, returns
    "infinity".

    Otherwise, if either a or b are "infinity", returns the other.

    Otherwise, returns the greatest common divisor of a and b.
  """
  if a != "infinity": a = int(a)
  if b != "infinity": b = int(b)
  assert a == "infinity" or a >= 0
  assert b == "infinity" or b >= 0
  if a == b == 0: return "infinity"
  # GCD(0, x) is always x, so it's safe to shortcut when a == 0 or b == 0.
  if a == 0: return b
  if b == 0: return a
  if a == "infinity": return b
  if b == "infinity": return a
  return _math_gcd(a, b)


def compute_constants(ir):
  """Computes constant values for all expressions in ir.

  compute_constants calculates all constant values and adds them to the type
  information for each expression and subexpression.

  Arguments:
      ir: an IR on which to compute constants

  Returns:
      A (possibly empty) list of errors.
  """
  traverse_ir.fast_traverse_ir_top_down(
      ir, [ir_pb2.Expression], compute_constraints_of_expression,
      skip_descendants_of={ir_pb2.Expression})
  traverse_ir.fast_traverse_ir_top_down(
      ir, [ir_pb2.RuntimeParameter], _compute_constraints_of_parameter,
      skip_descendants_of={ir_pb2.Expression})
  return []
