R/173_reductions_dcp2cone_canonicalizers_logic_canon.R

Defines functions xor_canon or_canon and_canon not_canon

#####
## DO NOT EDIT THIS FILE!! EDIT THE SOURCE INSTEAD: rsrc_tree/reductions/dcp2cone/canonicalizers/logic_canon.R
#####

## CVXPY SOURCE: reductions/dcp2cone/canonicalizers/logic_canon.py
## Canonicalizers for boolean logic atoms: Not, And, Or, Xor


# -- not_canon -----------------------------------------------------
# Not(x) -> 1 - x  (pure substitution, no new constraints)
not_canon <- function(expr, args, solver_context = NULL) {
  list(1 - args[[1L]], list())
}

# -- and_canon -----------------------------------------------------
# And(x1, ..., xn) -> y where y <= xi for all i, y >= sum(xi) - (n-1)
and_canon <- function(expr, args, solver_context = NULL) {
  y <- Variable(shape = expr@shape, boolean = TRUE)
  constraints <- lapply(args, function(xi) y <= xi)
  constraints <- c(constraints,
    list(y >= Reduce(`+`, args) - (length(args) - 1L))
  )
  list(y, constraints)
}

# -- or_canon ------------------------------------------------------
# Or(x1, ..., xn) -> y where y >= xi for all i, y <= sum(xi)
or_canon <- function(expr, args, solver_context = NULL) {
  y <- Variable(shape = expr@shape, boolean = TRUE)
  constraints <- lapply(args, function(xi) y >= xi)
  constraints <- c(constraints,
    list(y <= Reduce(`+`, args))
  )
  list(y, constraints)
}

# -- xor_canon -----------------------------------------------------
# Xor(x1, ..., xn) -> y (parity: 1 iff odd number of args are 1)
# 2-arg: y <= x1+x2, y >= x1-x2, y >= x2-x1, y <= 2-x1-x2
# n-arg: sum(xi) == y + 2*k, k >= 0, k <= n %/% 2
xor_canon <- function(expr, args, solver_context = NULL) {
  n <- length(args)
  y <- Variable(shape = expr@shape, boolean = TRUE)
  if (n == 2L) {
    x1 <- args[[1L]]
    x2 <- args[[2L]]
    constraints <- list(
      y <= x1 + x2,
      y >= x1 - x2,
      y >= x2 - x1,
      y <= 2 - x1 - x2
    )
  } else {
    k <- Variable(shape = expr@shape, integer = TRUE)
    constraints <- list(
      Reduce(`+`, args) == y + 2 * k,
      k >= 0,
      k <= n %/% 2L
    )
  }
  list(y, constraints)
}

# -- Register S7 method dispatch -------------------------------------
method(dcp_canonicalize, Not) <- not_canon
method(has_dcp_canon, Not) <- function(expr) TRUE
method(dcp_canonicalize, And) <- and_canon
method(has_dcp_canon, And) <- function(expr) TRUE
method(dcp_canonicalize, Or) <- or_canon
method(has_dcp_canon, Or) <- function(expr) TRUE
method(dcp_canonicalize, Xor) <- xor_canon
method(has_dcp_canon, Xor) <- function(expr) TRUE

Try the CVXR package in your browser

Any scripts or data that you put into this service are public.

CVXR documentation built on March 6, 2026, 9:10 a.m.