From 6480d351cf4b437312e30a04b309afa14a27ea96 Mon Sep 17 00:00:00 2001 From: MEO265 <99362508+MEO265@users.noreply.github.com> Date: Sun, 28 Dec 2025 01:43:49 +0100 Subject: [PATCH 1/5] Use CuddManager constructor and methods:: calls --- DESCRIPTION | 2 ++ NAMESPACE | 1 + R/cudd_manager.R | 38 ++++++++++++++++++++++++++++++++++++++ man/CuddManager-class.Rd | 29 +++++++++++++++++++++++++++++ man/CuddManager.Rd | 14 ++++++++++++++ src/cudd_manager.cpp | 29 +++++++++++++++++++++++++++++ src/rcudd.h | 1 + src/register.cpp | 1 + 8 files changed, 115 insertions(+) create mode 100644 R/cudd_manager.R create mode 100644 man/CuddManager-class.Rd create mode 100644 man/CuddManager.Rd create mode 100644 src/cudd_manager.cpp diff --git a/DESCRIPTION b/DESCRIPTION index aaaa6be..0ec9ceb 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -13,6 +13,8 @@ RoxygenNote: 7.3.3 Encoding: UTF-8 Depends: R (>= 4.0) +Imports: + methods Suggests: testthat (>= 3.0.0) Config/testthat/edition: 3 diff --git a/NAMESPACE b/NAMESPACE index cd2bbc8..aadae59 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,5 +1,6 @@ # Generated by roxygen2: do not edit by hand +export(CuddManager) export(bdd_has_redundant_variables) export(bdd_literals) export(bdd_restrict_chain) diff --git a/R/cudd_manager.R b/R/cudd_manager.R new file mode 100644 index 0000000..c5af88a --- /dev/null +++ b/R/cudd_manager.R @@ -0,0 +1,38 @@ +#' S4 wrapper for a CUDD manager +#' +#' The CUDD manager encapsulates the underlying C++ `Cudd` instance and is +#' represented in R as an external pointer managed by a finalizer. +#' +#' @slot ptr External pointer to the underlying CUDD manager. +#' @keywords internal +methods::setClass( + "CuddManager", + slots = list( + ptr = "externalptr" + ), + validity = function(object) { + if (!methods::is(object@ptr, "externalptr")) { + return("`ptr` must be an external pointer.") + } + if (is.null(object@ptr)) { + return("`ptr` must not be NULL.") + } + TRUE + } +) + +#' Create a new CUDD manager +#' +#' @return A [`CuddManager`] instance. +#' @export +CuddManager <- function() { + ptr <- .Call("c_cudd_new") + methods::new("CuddManager", ptr = ptr) +} + +#' @describeIn CuddManager-class Show a brief summary of the manager. +#' @param object A `CuddManager` instance. +#' @keywords internal +methods::setMethod("show", "CuddManager", function(object) { + cat("\n") +}) diff --git a/man/CuddManager-class.Rd b/man/CuddManager-class.Rd new file mode 100644 index 0000000..225030e --- /dev/null +++ b/man/CuddManager-class.Rd @@ -0,0 +1,29 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cudd_manager.R +\docType{class} +\name{CuddManager-class} +\alias{CuddManager-class} +\alias{show,CuddManager-method} +\title{S4 wrapper for a CUDD manager} +\usage{ +\S4method{show}{CuddManager}(object) +} +\arguments{ +\item{object}{A `CuddManager` instance.} +} +\description{ +The CUDD manager encapsulates the underlying C++ `Cudd` instance and is +represented in R as an external pointer managed by a finalizer. +} +\section{Functions}{ +\itemize{ +\item \code{show(CuddManager)}: Show a brief summary of the manager. + +}} +\section{Slots}{ + +\describe{ +\item{\code{ptr}}{External pointer to the underlying CUDD manager.} +}} + +\keyword{internal} diff --git a/man/CuddManager.Rd b/man/CuddManager.Rd new file mode 100644 index 0000000..f4519cf --- /dev/null +++ b/man/CuddManager.Rd @@ -0,0 +1,14 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cudd_manager.R +\name{CuddManager} +\alias{CuddManager} +\title{Create a new CUDD manager} +\usage{ +CuddManager() +} +\value{ +A [`CuddManager`] instance. +} +\description{ +Create a new CUDD manager +} diff --git a/src/cudd_manager.cpp b/src/cudd_manager.cpp new file mode 100644 index 0000000..d558be0 --- /dev/null +++ b/src/cudd_manager.cpp @@ -0,0 +1,29 @@ +#include "rcudd.h" +#include +#include +#include "cuddObj.hh" + +static void cudd_manager_finalizer(SEXP ptr) { + if (TYPEOF(ptr) != EXTPTRSXP) { + return; + } + void *addr = R_ExternalPtrAddr(ptr); + if (addr != nullptr) { + delete static_cast(addr); + R_ClearExternalPtr(ptr); + } +} + +extern "C" SEXP c_cudd_new() { + try { + Cudd *mgr = new Cudd(); + SEXP ptr = PROTECT(R_MakeExternalPtr(mgr, R_NilValue, R_NilValue)); + R_RegisterCFinalizerEx(ptr, cudd_manager_finalizer, TRUE); + UNPROTECT(1); + return ptr; + } catch (const std::exception &ex) { + Rf_error("Failed to create CUDD manager: %s", ex.what()); + } + + return R_NilValue; +} diff --git a/src/rcudd.h b/src/rcudd.h index 7596b84..3c142b1 100644 --- a/src/rcudd.h +++ b/src/rcudd.h @@ -9,6 +9,7 @@ extern "C" SEXP bdd_remaining_literals(SEXP expr_in); extern "C" SEXP bdd_restrict_chain(SEXP exprs_in, SEXP additional_constraints_in); +extern "C" SEXP c_cudd_new(); #ifdef __cplusplus #include diff --git a/src/register.cpp b/src/register.cpp index 514c563..2cee8cf 100644 --- a/src/register.cpp +++ b/src/register.cpp @@ -6,6 +6,7 @@ extern "C" { static const R_CallMethodDef CallEntries[] = { + {"c_cudd_new", (DL_FUNC) &c_cudd_new, 0}, {"c_bdd_remaining_literals", (DL_FUNC) &bdd_remaining_literals, 1}, {"c_bdd_restrict_chain", (DL_FUNC) &bdd_restrict_chain, 2}, {NULL, NULL, 0} From aab3c7a88875f61a45acc5c3936a3a8b66112f9b Mon Sep 17 00:00:00 2001 From: MEO265 <99362508+MEO265@users.noreply.github.com> Date: Sun, 28 Dec 2025 02:09:58 +0100 Subject: [PATCH 2/5] Add Cudd manager statistic wrappers --- NAMESPACE | 10 +++ R/cudd_manager.R | 97 ++++++++++++++++++++++++++++++ man/cudd_read_cache_used_slots.Rd | 17 ++++++ man/cudd_read_loose_up_to.Rd | 17 ++++++ man/cudd_read_min_hit.Rd | 17 ++++++ man/cudd_read_reorderings.Rd | 17 ++++++ man/cudd_read_zdd_size.Rd | 17 ++++++ src/cudd_manager.cpp | 61 +++++++++++++++++++ src/rcudd.h | 10 +++ src/register.cpp | 10 +++ tests/testthat/test_cudd_manager.R | 18 ++++++ 11 files changed, 291 insertions(+) create mode 100644 man/cudd_read_cache_used_slots.Rd create mode 100644 man/cudd_read_loose_up_to.Rd create mode 100644 man/cudd_read_min_hit.Rd create mode 100644 man/cudd_read_reorderings.Rd create mode 100644 man/cudd_read_zdd_size.Rd create mode 100644 tests/testthat/test_cudd_manager.R diff --git a/NAMESPACE b/NAMESPACE index aadae59..d16ae4d 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -5,6 +5,16 @@ export(bdd_has_redundant_variables) export(bdd_literals) export(bdd_restrict_chain) export(bdd_restrict_from_expressions) +export(cudd_read_cache_hits) +export(cudd_read_cache_lookups) +export(cudd_read_cache_slots) +export(cudd_read_cache_used_slots) +export(cudd_read_loose_up_to) +export(cudd_read_min_hit) +export(cudd_read_node_count) +export(cudd_read_reorderings) +export(cudd_read_size) +export(cudd_read_zdd_size) export(expression_to_cpp_logic) export(expressions_to_cpp_logic) export(order_constraints) diff --git a/R/cudd_manager.R b/R/cudd_manager.R index c5af88a..4eb4f9d 100644 --- a/R/cudd_manager.R +++ b/R/cudd_manager.R @@ -36,3 +36,100 @@ CuddManager <- function() { methods::setMethod("show", "CuddManager", function(object) { cat("\n") }) + +.cudd_manager_ptr <- function(manager) { + if (!methods::is(manager, "CuddManager")) { + stop("`manager` must be a CuddManager object.", call. = FALSE) + } + manager@ptr +} + +#' Read the number of BDD variables in the manager +#' +#' @param manager A [`CuddManager`] instance. +#' @return Integer scalar with the number of BDD variables. +#' @export +cudd_read_size <- function(manager) { + .Call("c_cudd_read_size", .cudd_manager_ptr(manager)) +} + +#' Read the cache slot count +#' +#' @param manager A [`CuddManager`] instance. +#' @return Integer scalar with the cache slot count. +#' @export +cudd_read_cache_slots <- function(manager) { + .Call("c_cudd_read_cache_slots", .cudd_manager_ptr(manager)) +} + +#' Read the cache used slots +#' +#' @param manager A [`CuddManager`] instance. +#' @return Double scalar with the cache used slot count. +#' @export +cudd_read_cache_used_slots <- function(manager) { + .Call("c_cudd_read_cache_used_slots", .cudd_manager_ptr(manager)) +} + +#' Read the cache lookup count +#' +#' @param manager A [`CuddManager`] instance. +#' @return Double scalar with the cache lookup count. +#' @export +cudd_read_cache_lookups <- function(manager) { + .Call("c_cudd_read_cache_lookups", .cudd_manager_ptr(manager)) +} + +#' Read the cache hit count +#' +#' @param manager A [`CuddManager`] instance. +#' @return Double scalar with the cache hit count. +#' @export +cudd_read_cache_hits <- function(manager) { + .Call("c_cudd_read_cache_hits", .cudd_manager_ptr(manager)) +} + +#' Read the minimum cache hit ratio +#' +#' @param manager A [`CuddManager`] instance. +#' @return Integer scalar with the minimum cache hit ratio. +#' @export +cudd_read_min_hit <- function(manager) { + .Call("c_cudd_read_min_hit", .cudd_manager_ptr(manager)) +} + +#' Read the cache loose up-to threshold +#' +#' @param manager A [`CuddManager`] instance. +#' @return Integer scalar with the cache loose up-to threshold. +#' @export +cudd_read_loose_up_to <- function(manager) { + .Call("c_cudd_read_loose_up_to", .cudd_manager_ptr(manager)) +} + +#' Read the live node count +#' +#' @param manager A [`CuddManager`] instance. +#' @return Double scalar with the live node count. +#' @export +cudd_read_node_count <- function(manager) { + .Call("c_cudd_read_node_count", .cudd_manager_ptr(manager)) +} + +#' Read the number of ZDD variables in the manager +#' +#' @param manager A [`CuddManager`] instance. +#' @return Integer scalar with the number of ZDD variables. +#' @export +cudd_read_zdd_size <- function(manager) { + .Call("c_cudd_read_zdd_size", .cudd_manager_ptr(manager)) +} + +#' Read the number of reorderings performed +#' +#' @param manager A [`CuddManager`] instance. +#' @return Integer scalar with the number of reorderings. +#' @export +cudd_read_reorderings <- function(manager) { + .Call("c_cudd_read_reorderings", .cudd_manager_ptr(manager)) +} diff --git a/man/cudd_read_cache_used_slots.Rd b/man/cudd_read_cache_used_slots.Rd new file mode 100644 index 0000000..b59e56c --- /dev/null +++ b/man/cudd_read_cache_used_slots.Rd @@ -0,0 +1,17 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cudd_manager.R +\name{cudd_read_cache_used_slots} +\alias{cudd_read_cache_used_slots} +\title{Read the cache used slots} +\usage{ +cudd_read_cache_used_slots(manager) +} +\arguments{ +\item{manager}{A [`CuddManager`] instance.} +} +\value{ +Double scalar with the cache used slot count. +} +\description{ +Read the cache used slots +} diff --git a/man/cudd_read_loose_up_to.Rd b/man/cudd_read_loose_up_to.Rd new file mode 100644 index 0000000..fccb1a4 --- /dev/null +++ b/man/cudd_read_loose_up_to.Rd @@ -0,0 +1,17 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cudd_manager.R +\name{cudd_read_loose_up_to} +\alias{cudd_read_loose_up_to} +\title{Read the cache loose up-to threshold} +\usage{ +cudd_read_loose_up_to(manager) +} +\arguments{ +\item{manager}{A [`CuddManager`] instance.} +} +\value{ +Integer scalar with the cache loose up-to threshold. +} +\description{ +Read the cache loose up-to threshold +} diff --git a/man/cudd_read_min_hit.Rd b/man/cudd_read_min_hit.Rd new file mode 100644 index 0000000..2c1badd --- /dev/null +++ b/man/cudd_read_min_hit.Rd @@ -0,0 +1,17 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cudd_manager.R +\name{cudd_read_min_hit} +\alias{cudd_read_min_hit} +\title{Read the minimum cache hit ratio} +\usage{ +cudd_read_min_hit(manager) +} +\arguments{ +\item{manager}{A [`CuddManager`] instance.} +} +\value{ +Integer scalar with the minimum cache hit ratio. +} +\description{ +Read the minimum cache hit ratio +} diff --git a/man/cudd_read_reorderings.Rd b/man/cudd_read_reorderings.Rd new file mode 100644 index 0000000..cdbd548 --- /dev/null +++ b/man/cudd_read_reorderings.Rd @@ -0,0 +1,17 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cudd_manager.R +\name{cudd_read_reorderings} +\alias{cudd_read_reorderings} +\title{Read the number of reorderings performed} +\usage{ +cudd_read_reorderings(manager) +} +\arguments{ +\item{manager}{A [`CuddManager`] instance.} +} +\value{ +Integer scalar with the number of reorderings. +} +\description{ +Read the number of reorderings performed +} diff --git a/man/cudd_read_zdd_size.Rd b/man/cudd_read_zdd_size.Rd new file mode 100644 index 0000000..8447b7e --- /dev/null +++ b/man/cudd_read_zdd_size.Rd @@ -0,0 +1,17 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cudd_manager.R +\name{cudd_read_zdd_size} +\alias{cudd_read_zdd_size} +\title{Read the number of ZDD variables in the manager} +\usage{ +cudd_read_zdd_size(manager) +} +\arguments{ +\item{manager}{A [`CuddManager`] instance.} +} +\value{ +Integer scalar with the number of ZDD variables. +} +\description{ +Read the number of ZDD variables in the manager +} diff --git a/src/cudd_manager.cpp b/src/cudd_manager.cpp index d558be0..bdc1c93 100644 --- a/src/cudd_manager.cpp +++ b/src/cudd_manager.cpp @@ -14,6 +14,17 @@ static void cudd_manager_finalizer(SEXP ptr) { } } +static Cudd *cudd_manager_from_ptr(SEXP ptr) { + if (TYPEOF(ptr) != EXTPTRSXP) { + Rf_error("Expected an external pointer for a CUDD manager."); + } + void *addr = R_ExternalPtrAddr(ptr); + if (addr == nullptr) { + Rf_error("CUDD manager pointer is NULL."); + } + return static_cast(addr); +} + extern "C" SEXP c_cudd_new() { try { Cudd *mgr = new Cudd(); @@ -27,3 +38,53 @@ extern "C" SEXP c_cudd_new() { return R_NilValue; } + +extern "C" SEXP c_cudd_read_size(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return Rf_ScalarInteger(mgr->ReadSize()); +} + +extern "C" SEXP c_cudd_read_cache_slots(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return Rf_ScalarInteger(static_cast(mgr->ReadCacheSlots())); +} + +extern "C" SEXP c_cudd_read_cache_used_slots(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return Rf_ScalarReal(mgr->ReadCacheUsedSlots()); +} + +extern "C" SEXP c_cudd_read_cache_lookups(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return Rf_ScalarReal(mgr->ReadCacheLookUps()); +} + +extern "C" SEXP c_cudd_read_cache_hits(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return Rf_ScalarReal(mgr->ReadCacheHits()); +} + +extern "C" SEXP c_cudd_read_min_hit(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return Rf_ScalarInteger(static_cast(mgr->ReadMinHit())); +} + +extern "C" SEXP c_cudd_read_loose_up_to(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return Rf_ScalarInteger(static_cast(mgr->ReadLooseUpTo())); +} + +extern "C" SEXP c_cudd_read_node_count(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return Rf_ScalarReal(static_cast(mgr->ReadNodeCount())); +} + +extern "C" SEXP c_cudd_read_zdd_size(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return Rf_ScalarInteger(mgr->ReadZddSize()); +} + +extern "C" SEXP c_cudd_read_reorderings(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return Rf_ScalarInteger(static_cast(mgr->ReadReorderings())); +} diff --git a/src/rcudd.h b/src/rcudd.h index 3c142b1..7dcd106 100644 --- a/src/rcudd.h +++ b/src/rcudd.h @@ -10,6 +10,16 @@ extern "C" SEXP bdd_remaining_literals(SEXP expr_in); extern "C" SEXP bdd_restrict_chain(SEXP exprs_in, SEXP additional_constraints_in); extern "C" SEXP c_cudd_new(); +extern "C" SEXP c_cudd_read_size(SEXP mgr_ptr); +extern "C" SEXP c_cudd_read_cache_slots(SEXP mgr_ptr); +extern "C" SEXP c_cudd_read_cache_used_slots(SEXP mgr_ptr); +extern "C" SEXP c_cudd_read_cache_lookups(SEXP mgr_ptr); +extern "C" SEXP c_cudd_read_cache_hits(SEXP mgr_ptr); +extern "C" SEXP c_cudd_read_min_hit(SEXP mgr_ptr); +extern "C" SEXP c_cudd_read_loose_up_to(SEXP mgr_ptr); +extern "C" SEXP c_cudd_read_node_count(SEXP mgr_ptr); +extern "C" SEXP c_cudd_read_zdd_size(SEXP mgr_ptr); +extern "C" SEXP c_cudd_read_reorderings(SEXP mgr_ptr); #ifdef __cplusplus #include diff --git a/src/register.cpp b/src/register.cpp index 2cee8cf..f392fda 100644 --- a/src/register.cpp +++ b/src/register.cpp @@ -7,6 +7,16 @@ extern "C" { static const R_CallMethodDef CallEntries[] = { {"c_cudd_new", (DL_FUNC) &c_cudd_new, 0}, + {"c_cudd_read_size", (DL_FUNC) &c_cudd_read_size, 1}, + {"c_cudd_read_cache_slots", (DL_FUNC) &c_cudd_read_cache_slots, 1}, + {"c_cudd_read_cache_used_slots", (DL_FUNC) &c_cudd_read_cache_used_slots, 1}, + {"c_cudd_read_cache_lookups", (DL_FUNC) &c_cudd_read_cache_lookups, 1}, + {"c_cudd_read_cache_hits", (DL_FUNC) &c_cudd_read_cache_hits, 1}, + {"c_cudd_read_min_hit", (DL_FUNC) &c_cudd_read_min_hit, 1}, + {"c_cudd_read_loose_up_to", (DL_FUNC) &c_cudd_read_loose_up_to, 1}, + {"c_cudd_read_node_count", (DL_FUNC) &c_cudd_read_node_count, 1}, + {"c_cudd_read_zdd_size", (DL_FUNC) &c_cudd_read_zdd_size, 1}, + {"c_cudd_read_reorderings", (DL_FUNC) &c_cudd_read_reorderings, 1}, {"c_bdd_remaining_literals", (DL_FUNC) &bdd_remaining_literals, 1}, {"c_bdd_restrict_chain", (DL_FUNC) &bdd_restrict_chain, 2}, {NULL, NULL, 0} diff --git a/tests/testthat/test_cudd_manager.R b/tests/testthat/test_cudd_manager.R new file mode 100644 index 0000000..bc9e40c --- /dev/null +++ b/tests/testthat/test_cudd_manager.R @@ -0,0 +1,18 @@ +test_that("CuddManager exposes manager stats", { + manager <- CuddManager() + + expect_length(cudd_read_cache_used_slots(manager), 1L) + expect_true(is.numeric(cudd_read_cache_used_slots(manager))) + + expect_length(cudd_read_min_hit(manager), 1L) + expect_true(is.numeric(cudd_read_min_hit(manager))) + + expect_length(cudd_read_loose_up_to(manager), 1L) + expect_true(is.numeric(cudd_read_loose_up_to(manager))) + + expect_length(cudd_read_zdd_size(manager), 1L) + expect_true(is.numeric(cudd_read_zdd_size(manager))) + + expect_length(cudd_read_reorderings(manager), 1L) + expect_true(is.numeric(cudd_read_reorderings(manager))) +}) From 0003a3c1ec7c433f2c48398c9d168d9d20a85eb2 Mon Sep 17 00:00:00 2001 From: MEO265 <99362508+MEO265@users.noreply.github.com> Date: Tue, 30 Dec 2025 09:27:00 +0100 Subject: [PATCH 3/5] Expose Cudd ADD constructors to R (CuddADD S4 + native wrappers) (#4) * Expose Cudd ADD constructors to R * Add ZDD bindings and operators * Refine diagram APIs and tests * Expose EPD minterm output wrappers * Expose diagram print helpers * Add snapshot tests for diagram output * Add BDD debug output helper * Add BDD DOT dump helper * Add manager controls for cache and verbosity * Expand Cudd manager test coverage * Track manager ownership for CUDD objects * Silence lintr object length warnings * Resolve native symbols before calling * Use native symbols directly in .Call * Bind native symbols without onLoad * Force symbol usage in registration --- NAMESPACE | 115 +++ R/cudd_add.R | 154 ++++ R/cudd_bdd.R | 187 ++++ R/cudd_conversions.R | 39 + R/cudd_manager.R | 638 +++++++++++++- R/cudd_zdd.R | 140 +++ R/rcudd.R | 161 ++++ R/restrict_chain.R | 2 +- man/CuddADD-class.Rd | 66 ++ man/CuddBDD-class.Rd | 66 ++ man/CuddZDD-class.Rd | 66 ++ man/cudd_add_epd_print_minterm.Rd | 20 + man/cudd_add_one.Rd | 17 + man/cudd_add_to_bdd.Rd | 17 + man/cudd_add_var.Rd | 20 + man/cudd_add_zero.Rd | 17 + man/cudd_bdd_dump_dot.Rd | 18 + man/cudd_bdd_epd_print_minterm.Rd | 20 + man/cudd_bdd_one.Rd | 17 + man/cudd_bdd_print_debug.Rd | 23 + man/cudd_bdd_to_add.Rd | 17 + man/cudd_bdd_to_zdd.Rd | 17 + man/cudd_bdd_var.Rd | 20 + man/cudd_bdd_zero.Rd | 17 + man/cudd_manager_controls.Rd | 333 +++++++ man/cudd_read_cache_hits.Rd | 17 + man/cudd_read_cache_lookups.Rd | 17 + man/cudd_read_cache_slots.Rd | 17 + man/cudd_read_node_count.Rd | 17 + man/cudd_read_size.Rd | 17 + man/cudd_zdd_one.Rd | 19 + man/cudd_zdd_to_bdd.Rd | 17 + man/cudd_zdd_var.Rd | 19 + man/cudd_zdd_zero.Rd | 17 + man/print-CuddADD-method.Rd | 20 + man/print-CuddBDD-method.Rd | 20 + man/print-CuddZDD-method.Rd | 20 + src/cudd_manager.cpp | 1128 ++++++++++++++++++++++++ src/rcudd.h | 125 +++ src/register.cpp | 125 +++ tests/testthat/_snaps/cudd_diagrams.md | 50 ++ tests/testthat/test_cudd_diagrams.R | 83 ++ tests/testthat/test_cudd_manager.R | 237 ++++- 43 files changed, 4151 insertions(+), 21 deletions(-) create mode 100644 R/cudd_add.R create mode 100644 R/cudd_bdd.R create mode 100644 R/cudd_conversions.R create mode 100644 R/cudd_zdd.R create mode 100644 man/CuddADD-class.Rd create mode 100644 man/CuddBDD-class.Rd create mode 100644 man/CuddZDD-class.Rd create mode 100644 man/cudd_add_epd_print_minterm.Rd create mode 100644 man/cudd_add_one.Rd create mode 100644 man/cudd_add_to_bdd.Rd create mode 100644 man/cudd_add_var.Rd create mode 100644 man/cudd_add_zero.Rd create mode 100644 man/cudd_bdd_dump_dot.Rd create mode 100644 man/cudd_bdd_epd_print_minterm.Rd create mode 100644 man/cudd_bdd_one.Rd create mode 100644 man/cudd_bdd_print_debug.Rd create mode 100644 man/cudd_bdd_to_add.Rd create mode 100644 man/cudd_bdd_to_zdd.Rd create mode 100644 man/cudd_bdd_var.Rd create mode 100644 man/cudd_bdd_zero.Rd create mode 100644 man/cudd_manager_controls.Rd create mode 100644 man/cudd_read_cache_hits.Rd create mode 100644 man/cudd_read_cache_lookups.Rd create mode 100644 man/cudd_read_cache_slots.Rd create mode 100644 man/cudd_read_node_count.Rd create mode 100644 man/cudd_read_size.Rd create mode 100644 man/cudd_zdd_one.Rd create mode 100644 man/cudd_zdd_to_bdd.Rd create mode 100644 man/cudd_zdd_var.Rd create mode 100644 man/cudd_zdd_zero.Rd create mode 100644 man/print-CuddADD-method.Rd create mode 100644 man/print-CuddBDD-method.Rd create mode 100644 man/print-CuddZDD-method.Rd create mode 100644 tests/testthat/_snaps/cudd_diagrams.md create mode 100644 tests/testthat/test_cudd_diagrams.R diff --git a/NAMESPACE b/NAMESPACE index d16ae4d..bd883a5 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -5,17 +5,132 @@ export(bdd_has_redundant_variables) export(bdd_literals) export(bdd_restrict_chain) export(bdd_restrict_from_expressions) +export(cudd_add_epd_print_minterm) +export(cudd_add_one) +export(cudd_add_to_bdd) +export(cudd_add_var) +export(cudd_add_zero) +export(cudd_autodyn_disable) +export(cudd_autodyn_disable_zdd) +export(cudd_autodyn_enable) +export(cudd_autodyn_enable_zdd) +export(cudd_background) +export(cudd_bdd_bind_var) +export(cudd_bdd_dump_dot) +export(cudd_bdd_epd_print_minterm) +export(cudd_bdd_one) +export(cudd_bdd_print_debug) +export(cudd_bdd_realign_disable) +export(cudd_bdd_realign_enable) +export(cudd_bdd_realignment_enabled) +export(cudd_bdd_to_add) +export(cudd_bdd_to_zdd) +export(cudd_bdd_unbind_var) +export(cudd_bdd_var) +export(cudd_bdd_var_is_bound) +export(cudd_bdd_zero) +export(cudd_clear_error_code) +export(cudd_clear_variable_names) +export(cudd_dead_are_counted) +export(cudd_disable_garbage_collection) +export(cudd_disable_reordering_reporting) +export(cudd_enable_garbage_collection) +export(cudd_enable_reordering_reporting) +export(cudd_garbage_collection_enabled) +export(cudd_get_variable_name) +export(cudd_increase_time_limit) +export(cudd_info) +export(cudd_is_verbose) +export(cudd_make_terse) +export(cudd_make_verbose) +export(cudd_push_variable_name) +export(cudd_read_arcviolation) export(cudd_read_cache_hits) export(cudd_read_cache_lookups) export(cudd_read_cache_slots) export(cudd_read_cache_used_slots) +export(cudd_read_dead) +export(cudd_read_elapsed_time) +export(cudd_read_epsilon) +export(cudd_read_error_code) +export(cudd_read_garbage_collection_time) +export(cudd_read_garbage_collections) +export(cudd_read_groupcheck) +export(cudd_read_inv_perm) +export(cudd_read_inv_perm_zdd) +export(cudd_read_keys) export(cudd_read_loose_up_to) +export(cudd_read_max_cache) +export(cudd_read_max_cache_hard) +export(cudd_read_max_growth) +export(cudd_read_max_live) +export(cudd_read_max_memory) +export(cudd_read_max_reorderings) +export(cudd_read_memory_in_use) +export(cudd_read_min_dead) export(cudd_read_min_hit) +export(cudd_read_next_reordering) export(cudd_read_node_count) +export(cudd_read_node_count_current) +export(cudd_read_node_count_zdd) +export(cudd_read_number_xovers) +export(cudd_read_order_randomization) +export(cudd_read_peak_node_count) +export(cudd_read_perm) +export(cudd_read_perm_zdd) +export(cudd_read_population_size) +export(cudd_read_recomb) +export(cudd_read_reordering_time) export(cudd_read_reorderings) +export(cudd_read_sift_max_swap) +export(cudd_read_sift_max_var) export(cudd_read_size) +export(cudd_read_slots) +export(cudd_read_start_time) +export(cudd_read_swap_steps) +export(cudd_read_symmviolation) +export(cudd_read_time_limit) +export(cudd_read_vars) export(cudd_read_zdd_size) +export(cudd_reordering_reporting) +export(cudd_reordering_status) +export(cudd_reordering_status_zdd) +export(cudd_reset_start_time) +export(cudd_set_arcviolation) +export(cudd_set_background) +export(cudd_set_epsilon) +export(cudd_set_groupcheck) +export(cudd_set_loose_up_to) +export(cudd_set_max_cache_hard) +export(cudd_set_max_growth) +export(cudd_set_max_live) +export(cudd_set_max_memory) +export(cudd_set_max_reorderings) +export(cudd_set_min_hit) +export(cudd_set_next_reordering) +export(cudd_set_number_xovers) +export(cudd_set_order_randomization) +export(cudd_set_population_size) +export(cudd_set_recomb) +export(cudd_set_sift_max_swap) +export(cudd_set_sift_max_var) +export(cudd_set_start_time) +export(cudd_set_symmviolation) +export(cudd_set_time_limit) +export(cudd_time_limited) +export(cudd_turn_off_count_dead) +export(cudd_turn_on_count_dead) +export(cudd_unset_time_limit) +export(cudd_update_time_limit) +export(cudd_zdd_one) +export(cudd_zdd_realign_disable) +export(cudd_zdd_realign_enable) +export(cudd_zdd_realignment_enabled) +export(cudd_zdd_to_bdd) +export(cudd_zdd_var) +export(cudd_zdd_zero) export(expression_to_cpp_logic) export(expressions_to_cpp_logic) export(order_constraints) +exportMethods(print) useDynLib(Rcudd, .registration=TRUE) diff --git a/R/cudd_add.R b/R/cudd_add.R new file mode 100644 index 0000000..4ecb4d4 --- /dev/null +++ b/R/cudd_add.R @@ -0,0 +1,154 @@ +#' S4 wrapper for a CUDD ADD +#' +#' The ADD wrapper encapsulates the underlying C++ `ADD` instance and is +#' represented in R as an external pointer managed by a finalizer. +#' +#' @slot ptr External pointer to the underlying ADD object. +#' @slot manager_ptr External pointer to the owning CUDD manager. +#' @keywords internal +methods::setClass( + "CuddADD", + slots = list( + ptr = "externalptr", + manager_ptr = "externalptr" + ), + validity = function(object) { + if (!methods::is(object@ptr, "externalptr")) { + return("`ptr` must be an external pointer.") + } + if (is.null(object@ptr)) { + return("`ptr` must not be NULL.") + } + if (!methods::is(object@manager_ptr, "externalptr")) { + return("`manager_ptr` must be an external pointer.") + } + if (is.null(object@manager_ptr)) { + return("`manager_ptr` must not be NULL.") + } + return(TRUE) + } +) + +#' @describeIn CuddADD-class Show a brief summary of the ADD. +#' @param object A `CuddADD` instance. +#' @keywords internal +methods::setMethod("show", "CuddADD", function(object) { + cat("\n") + print(object) + return(invisible(object)) +}) + +.cudd_add_ptr <- function(add) { + if (!methods::is(add, "CuddADD")) { + stop("`add` must be a CuddADD object.", call. = FALSE) + } + return(add@ptr) +} + +.cudd_add_manager_ptr <- function(add) { + if (!methods::is(add, "CuddADD")) { + stop("`add` must be a CuddADD object.", call. = FALSE) + } + return(add@manager_ptr) +} + +#' Create an ADD node that represents logical TRUE +#' +#' @param manager A [`CuddManager`] instance. +#' @return A [`CuddADD`] instance representing a constant TRUE ADD. +#' @export +cudd_add_one <- function(manager) { + ptr <- .Call(c_cudd_add_one, .cudd_manager_ptr(manager)) + return(methods::new("CuddADD", ptr = ptr, manager_ptr = .cudd_manager_ptr(manager))) +} + +#' Create an ADD node that represents logical FALSE +#' +#' @param manager A [`CuddManager`] instance. +#' @return A [`CuddADD`] instance representing a constant FALSE ADD. +#' @export +cudd_add_zero <- function(manager) { + ptr <- .Call(c_cudd_add_zero, .cudd_manager_ptr(manager)) + return(methods::new("CuddADD", ptr = ptr, manager_ptr = .cudd_manager_ptr(manager))) +} + +#' Create or access an ADD variable +#' +#' When `index` is `NULL`, a new ADD variable is created in the manager and +#' returned. Otherwise, the ADD variable at the specified index is returned. +#' +#' @param manager A [`CuddManager`] instance. +#' @param index Optional non-negative integer index of the ADD variable. +#' @return A [`CuddADD`] instance representing the requested variable. +#' @export +cudd_add_var <- function(manager, index = NULL) { + ptr <- .Call(c_cudd_add_var, .cudd_manager_ptr(manager), index) + return(methods::new("CuddADD", ptr = ptr, manager_ptr = .cudd_manager_ptr(manager))) +} + +#' @describeIn CuddADD-class Combine ADDs with multiplication +#' @param e1 A `CuddADD` instance. +#' @param e2 A `CuddADD` instance. +#' @return A `CuddADD` instance. +setMethod("*", signature(e1 = "CuddADD", e2 = "CuddADD"), function(e1, e2) { + if (!.cudd_check_same_manager(e1, e2, "*")) { + stop("Cannot combine ADDs from different CuddManager instances.", call. = FALSE) + } + ptr <- .Call(c_cudd_add_times, .cudd_add_ptr(e1), .cudd_add_ptr(e2)) + return(methods::new("CuddADD", ptr = ptr, manager_ptr = .cudd_add_manager_ptr(e1))) +}) + +#' @describeIn CuddADD-class Combine ADDs with addition +#' @param e1 A `CuddADD` instance. +#' @param e2 A `CuddADD` instance. +#' @return A `CuddADD` instance. +setMethod("+", signature(e1 = "CuddADD", e2 = "CuddADD"), function(e1, e2) { + if (!.cudd_check_same_manager(e1, e2, "+")) { + stop("Cannot combine ADDs from different CuddManager instances.", call. = FALSE) + } + ptr <- .Call(c_cudd_add_plus, .cudd_add_ptr(e1), .cudd_add_ptr(e2)) + return(methods::new("CuddADD", ptr = ptr, manager_ptr = .cudd_add_manager_ptr(e1))) +}) + +#' @describeIn CuddADD-class XOR is not defined for ADDs +#' @param e1 A `CuddADD` instance. +#' @param e2 A `CuddADD` instance. +#' @return An error indicating the operator is unsupported. +setMethod("^", signature(e1 = "CuddADD", e2 = "CuddADD"), function(e1, e2) { + stop("XOR (^) is not defined for CuddADD.", call. = FALSE) +}) + +#' @describeIn CuddADD-class Negation is not defined for ADDs +#' @param x A `CuddADD` instance. +#' @return An error indicating the operator is unsupported. +setMethod("!", "CuddADD", function(x) { + stop("Negation (!) is not defined for CuddADD.", call. = FALSE) +}) + +#' Print an EPD minterm count for an ADD +#' +#' This uses the CUDD `EpdPrintMinterm` implementation, which writes to R's +#' output stream. +#' +#' @param add A [`CuddADD`] instance. +#' @param nvars Non-negative integer indicating how many variables to consider. +#' @return `NULL`, invisibly. +#' @export +cudd_add_epd_print_minterm <- function(add, nvars) { + .Call(c_cudd_add_epd_print_minterm, .cudd_add_ptr(add), nvars) + return(invisible(NULL)) +} + +#' Print the minterm representation for an ADD +#' +#' This uses the CUDD `PrintMinterm` implementation, which writes to R's +#' output stream. +#' +#' @param x A [`CuddADD`] instance. +#' @param ... Unused. +#' @return The input `x`, invisibly. +#' @export +setMethod("print", "CuddADD", function(x, ...) { + .Call(c_cudd_add_print_minterm, .cudd_add_ptr(x)) + return(invisible(x)) +}) diff --git a/R/cudd_bdd.R b/R/cudd_bdd.R new file mode 100644 index 0000000..3bc1de5 --- /dev/null +++ b/R/cudd_bdd.R @@ -0,0 +1,187 @@ +#' S4 wrapper for a CUDD BDD +#' +#' The BDD wrapper encapsulates the underlying C++ `BDD` instance and is +#' represented in R as an external pointer managed by a finalizer. +#' +#' @slot ptr External pointer to the underlying BDD object. +#' @slot manager_ptr External pointer to the owning CUDD manager. +#' @keywords internal +methods::setClass( + "CuddBDD", + slots = list( + ptr = "externalptr", + manager_ptr = "externalptr" + ), + validity = function(object) { + if (!methods::is(object@ptr, "externalptr")) { + return("`ptr` must be an external pointer.") + } + if (is.null(object@ptr)) { + return("`ptr` must not be NULL.") + } + if (!methods::is(object@manager_ptr, "externalptr")) { + return("`manager_ptr` must be an external pointer.") + } + if (is.null(object@manager_ptr)) { + return("`manager_ptr` must not be NULL.") + } + return(TRUE) + } +) + +#' @describeIn CuddBDD-class Show a brief summary of the BDD. +#' @param object A `CuddBDD` instance. +#' @keywords internal +methods::setMethod("show", "CuddBDD", function(object) { + cat("\n") + print(object) + return(invisible(object)) +}) + +.cudd_bdd_ptr <- function(bdd) { + if (!methods::is(bdd, "CuddBDD")) { + stop("`bdd` must be a CuddBDD object.", call. = FALSE) + } + return(bdd@ptr) +} + +.cudd_bdd_manager_ptr <- function(bdd) { + if (!methods::is(bdd, "CuddBDD")) { + stop("`bdd` must be a CuddBDD object.", call. = FALSE) + } + return(bdd@manager_ptr) +} + +#' Create a BDD node that represents logical TRUE +#' +#' @param manager A [`CuddManager`] instance. +#' @return A [`CuddBDD`] instance representing a constant TRUE BDD. +#' @export +cudd_bdd_one <- function(manager) { + ptr <- .Call(c_cudd_bdd_one, .cudd_manager_ptr(manager)) + return(methods::new("CuddBDD", ptr = ptr, manager_ptr = .cudd_manager_ptr(manager))) +} + +#' Create a BDD node that represents logical FALSE +#' +#' @param manager A [`CuddManager`] instance. +#' @return A [`CuddBDD`] instance representing a constant FALSE BDD. +#' @export +cudd_bdd_zero <- function(manager) { + ptr <- .Call(c_cudd_bdd_zero, .cudd_manager_ptr(manager)) + return(methods::new("CuddBDD", ptr = ptr, manager_ptr = .cudd_manager_ptr(manager))) +} + +#' Create or access a BDD variable +#' +#' When `index` is `NULL`, a new BDD variable is created in the manager and +#' returned. Otherwise, the BDD variable at the specified index is returned. +#' +#' @param manager A [`CuddManager`] instance. +#' @param index Optional non-negative integer index of the BDD variable. +#' @return A [`CuddBDD`] instance representing the requested variable. +#' @export +cudd_bdd_var <- function(manager, index = NULL) { + ptr <- .Call(c_cudd_bdd_var, .cudd_manager_ptr(manager), index) + return(methods::new("CuddBDD", ptr = ptr, manager_ptr = .cudd_manager_ptr(manager))) +} + +#' @describeIn CuddBDD-class Negate a BDD +#' @param x A `CuddBDD` instance. +#' @return A `CuddBDD` instance. +setMethod("!", "CuddBDD", function(x) { + ptr <- .Call(c_cudd_bdd_not, .cudd_bdd_ptr(x)) + return(methods::new("CuddBDD", ptr = ptr, manager_ptr = .cudd_bdd_manager_ptr(x))) +}) + +#' @describeIn CuddBDD-class Combine BDDs with addition (logical OR) +#' @param e1 A `CuddBDD` instance. +#' @param e2 A `CuddBDD` instance. +#' @return A `CuddBDD` instance. +setMethod("+", signature(e1 = "CuddBDD", e2 = "CuddBDD"), function(e1, e2) { + if (!.cudd_check_same_manager(e1, e2, "+")) { + stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) + } + ptr <- .Call(c_cudd_bdd_or, .cudd_bdd_ptr(e1), .cudd_bdd_ptr(e2)) + return(methods::new("CuddBDD", ptr = ptr, manager_ptr = .cudd_bdd_manager_ptr(e1))) +}) + +#' @describeIn CuddBDD-class Combine BDDs with multiplication (logical AND) +#' @param e1 A `CuddBDD` instance. +#' @param e2 A `CuddBDD` instance. +#' @return A `CuddBDD` instance. +setMethod("*", signature(e1 = "CuddBDD", e2 = "CuddBDD"), function(e1, e2) { + if (!.cudd_check_same_manager(e1, e2, "*")) { + stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) + } + ptr <- .Call(c_cudd_bdd_and, .cudd_bdd_ptr(e1), .cudd_bdd_ptr(e2)) + return(methods::new("CuddBDD", ptr = ptr, manager_ptr = .cudd_bdd_manager_ptr(e1))) +}) + +#' @describeIn CuddBDD-class Combine BDDs with XOR +#' @param e1 A `CuddBDD` instance. +#' @param e2 A `CuddBDD` instance. +#' @return A `CuddBDD` instance. +setMethod("^", signature(e1 = "CuddBDD", e2 = "CuddBDD"), function(e1, e2) { + if (!.cudd_check_same_manager(e1, e2, "^")) { + stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) + } + ptr <- .Call(c_cudd_bdd_xor, .cudd_bdd_ptr(e1), .cudd_bdd_ptr(e2)) + return(methods::new("CuddBDD", ptr = ptr, manager_ptr = .cudd_bdd_manager_ptr(e1))) +}) + +#' Print an EPD minterm count for a BDD +#' +#' This uses the CUDD `EpdPrintMinterm` implementation, which writes to R's +#' output stream. +#' +#' @param bdd A [`CuddBDD`] instance. +#' @param nvars Non-negative integer indicating how many variables to consider. +#' @return `NULL`, invisibly. +#' @export +cudd_bdd_epd_print_minterm <- function(bdd, nvars) { + .Call(c_cudd_bdd_epd_print_minterm, .cudd_bdd_ptr(bdd), nvars) + return(invisible(NULL)) +} + +#' Print the minterm representation for a BDD +#' +#' This uses the CUDD `PrintMinterm` implementation, which writes to R's +#' output stream. +#' +#' @param x A [`CuddBDD`] instance. +#' @param ... Unused. +#' @return The input `x`, invisibly. +#' @export +setMethod("print", "CuddBDD", function(x, ...) { + .Call(c_cudd_bdd_print_minterm, .cudd_bdd_ptr(x)) + return(invisible(x)) +}) + +#' Print a debug representation for a BDD +#' +#' This uses the CUDD `PrintDebug` implementation, which writes to R's output +#' stream. +#' +#' @param bdd A [`CuddBDD`] instance. +#' @param nvars Optional non-negative integer indicating how many variables to +#' include. Defaults to the manager size. +#' @param verbosity Optional non-negative integer debug verbosity. +#' @return `NULL`, invisibly. +#' @export +cudd_bdd_print_debug <- function(bdd, nvars = NULL, verbosity = NULL) { + .Call(c_cudd_bdd_print_debug, .cudd_bdd_ptr(bdd), nvars, verbosity) + return(invisible(NULL)) +} + +#' Dump a BDD as Graphviz DOT +#' +#' Produces a DOT representation that can be rendered by Graphviz to visualize +#' the full decision diagram structure. +#' +#' @param bdd A [`CuddBDD`] instance. +#' @return Character scalar containing DOT text. +#' @export +cudd_bdd_dump_dot <- function(bdd) { + return(.Call(c_cudd_bdd_dump_dot, .cudd_bdd_ptr(bdd))) +} diff --git a/R/cudd_conversions.R b/R/cudd_conversions.R new file mode 100644 index 0000000..dcdc432 --- /dev/null +++ b/R/cudd_conversions.R @@ -0,0 +1,39 @@ +#' Convert a BDD to an ADD +#' +#' @param bdd A [`CuddBDD`] instance. +#' @return A [`CuddADD`] instance. +#' @export +cudd_bdd_to_add <- function(bdd) { + ptr <- .Call(c_cudd_bdd_to_add, .cudd_bdd_ptr(bdd)) + return(methods::new("CuddADD", ptr = ptr, manager_ptr = .cudd_bdd_manager_ptr(bdd))) +} + +#' Convert an ADD to a BDD using the non-zero pattern +#' +#' @param add A [`CuddADD`] instance. +#' @return A [`CuddBDD`] instance. +#' @export +cudd_add_to_bdd <- function(add) { + ptr <- .Call(c_cudd_add_to_bdd, .cudd_add_ptr(add)) + return(methods::new("CuddBDD", ptr = ptr, manager_ptr = .cudd_add_manager_ptr(add))) +} + +#' Convert a BDD to a ZDD +#' +#' @param bdd A [`CuddBDD`] instance. +#' @return A [`CuddZDD`] instance. +#' @export +cudd_bdd_to_zdd <- function(bdd) { + ptr <- .Call(c_cudd_bdd_to_zdd, .cudd_bdd_ptr(bdd)) + return(methods::new("CuddZDD", ptr = ptr, manager_ptr = .cudd_bdd_manager_ptr(bdd))) +} + +#' Convert a ZDD to a BDD +#' +#' @param zdd A [`CuddZDD`] instance. +#' @return A [`CuddBDD`] instance. +#' @export +cudd_zdd_to_bdd <- function(zdd) { + ptr <- .Call(c_cudd_zdd_to_bdd, .cudd_zdd_ptr(zdd)) + return(methods::new("CuddBDD", ptr = ptr, manager_ptr = .cudd_zdd_manager_ptr(zdd))) +} diff --git a/R/cudd_manager.R b/R/cudd_manager.R index 4eb4f9d..9a14704 100644 --- a/R/cudd_manager.R +++ b/R/cudd_manager.R @@ -17,7 +17,7 @@ methods::setClass( if (is.null(object@ptr)) { return("`ptr` must not be NULL.") } - TRUE + return(TRUE) } ) @@ -25,9 +25,9 @@ methods::setClass( #' #' @return A [`CuddManager`] instance. #' @export -CuddManager <- function() { - ptr <- .Call("c_cudd_new") - methods::new("CuddManager", ptr = ptr) +CuddManager <- function() { # nolint: object_name_linter. + ptr <- .Call(c_cudd_new) + return(methods::new("CuddManager", ptr = ptr)) } #' @describeIn CuddManager-class Show a brief summary of the manager. @@ -35,13 +35,14 @@ CuddManager <- function() { #' @keywords internal methods::setMethod("show", "CuddManager", function(object) { cat("\n") + return(invisible(object)) }) .cudd_manager_ptr <- function(manager) { if (!methods::is(manager, "CuddManager")) { stop("`manager` must be a CuddManager object.", call. = FALSE) } - manager@ptr + return(manager@ptr) } #' Read the number of BDD variables in the manager @@ -50,7 +51,7 @@ methods::setMethod("show", "CuddManager", function(object) { #' @return Integer scalar with the number of BDD variables. #' @export cudd_read_size <- function(manager) { - .Call("c_cudd_read_size", .cudd_manager_ptr(manager)) + return(.Call(c_cudd_read_size, .cudd_manager_ptr(manager))) } #' Read the cache slot count @@ -59,7 +60,7 @@ cudd_read_size <- function(manager) { #' @return Integer scalar with the cache slot count. #' @export cudd_read_cache_slots <- function(manager) { - .Call("c_cudd_read_cache_slots", .cudd_manager_ptr(manager)) + return(.Call(c_cudd_read_cache_slots, .cudd_manager_ptr(manager))) } #' Read the cache used slots @@ -68,7 +69,7 @@ cudd_read_cache_slots <- function(manager) { #' @return Double scalar with the cache used slot count. #' @export cudd_read_cache_used_slots <- function(manager) { - .Call("c_cudd_read_cache_used_slots", .cudd_manager_ptr(manager)) + return(.Call(c_cudd_read_cache_used_slots, .cudd_manager_ptr(manager))) } #' Read the cache lookup count @@ -77,7 +78,7 @@ cudd_read_cache_used_slots <- function(manager) { #' @return Double scalar with the cache lookup count. #' @export cudd_read_cache_lookups <- function(manager) { - .Call("c_cudd_read_cache_lookups", .cudd_manager_ptr(manager)) + return(.Call(c_cudd_read_cache_lookups, .cudd_manager_ptr(manager))) } #' Read the cache hit count @@ -86,7 +87,7 @@ cudd_read_cache_lookups <- function(manager) { #' @return Double scalar with the cache hit count. #' @export cudd_read_cache_hits <- function(manager) { - .Call("c_cudd_read_cache_hits", .cudd_manager_ptr(manager)) + return(.Call(c_cudd_read_cache_hits, .cudd_manager_ptr(manager))) } #' Read the minimum cache hit ratio @@ -95,7 +96,13 @@ cudd_read_cache_hits <- function(manager) { #' @return Integer scalar with the minimum cache hit ratio. #' @export cudd_read_min_hit <- function(manager) { - .Call("c_cudd_read_min_hit", .cudd_manager_ptr(manager)) + return(.Call(c_cudd_read_min_hit, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_set_min_hit <- function(manager, hr) { + return(.Call(c_cudd_set_min_hit, .cudd_manager_ptr(manager), hr)) } #' Read the cache loose up-to threshold @@ -104,7 +111,55 @@ cudd_read_min_hit <- function(manager) { #' @return Integer scalar with the cache loose up-to threshold. #' @export cudd_read_loose_up_to <- function(manager) { - .Call("c_cudd_read_loose_up_to", .cudd_manager_ptr(manager)) + return(.Call(c_cudd_read_loose_up_to, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_set_loose_up_to <- function(manager, lut) { + return(.Call(c_cudd_set_loose_up_to, .cudd_manager_ptr(manager), lut)) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_make_verbose <- function(manager) { + return(.Call(c_cudd_make_verbose, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_make_terse <- function(manager) { + return(.Call(c_cudd_make_terse, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_is_verbose <- function(manager) { + return(.Call(c_cudd_is_verbose, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_info <- function(manager) { + return(.Call(c_cudd_info, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_push_variable_name <- function(manager, name) { + return(.Call(c_cudd_push_variable_name, .cudd_manager_ptr(manager), name)) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_clear_variable_names <- function(manager) { + return(.Call(c_cudd_clear_variable_names, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_get_variable_name <- function(manager, index) { + return(.Call(c_cudd_get_variable_name, .cudd_manager_ptr(manager), index)) } #' Read the live node count @@ -113,7 +168,7 @@ cudd_read_loose_up_to <- function(manager) { #' @return Double scalar with the live node count. #' @export cudd_read_node_count <- function(manager) { - .Call("c_cudd_read_node_count", .cudd_manager_ptr(manager)) + return(.Call(c_cudd_read_node_count, .cudd_manager_ptr(manager))) } #' Read the number of ZDD variables in the manager @@ -122,7 +177,7 @@ cudd_read_node_count <- function(manager) { #' @return Integer scalar with the number of ZDD variables. #' @export cudd_read_zdd_size <- function(manager) { - .Call("c_cudd_read_zdd_size", .cudd_manager_ptr(manager)) + return(.Call(c_cudd_read_zdd_size, .cudd_manager_ptr(manager))) } #' Read the number of reorderings performed @@ -131,5 +186,558 @@ cudd_read_zdd_size <- function(manager) { #' @return Integer scalar with the number of reorderings. #' @export cudd_read_reorderings <- function(manager) { - .Call("c_cudd_read_reorderings", .cudd_manager_ptr(manager)) + return(.Call(c_cudd_read_reorderings, .cudd_manager_ptr(manager))) +} + +#' CUDD manager controls +#' +#' Convenience wrappers around the CUDD manager API for tuning reordering, +#' time limits, memory limits, and reading manager statistics. +#' +#' @param manager A [`CuddManager`] instance. +#' @param st,tl,inc Numeric scalars used for time limit operations. +#' @param method Optional integer reordering method (CUDD enum value). +#' @param mc,mr,smv,sms,max_live Integers used for cache/reordering limits. +#' @param hr,lut Integers used for cache hit/loose-up-to thresholds. +#' @param mg,ep Numeric values for growth/epsilon settings. +#' @param i,index Integer indices for variable-related queries. +#' @param name Single string for variable names. +#' @param gc Integer CUDD aggregation type. +#' @param recomb,symm,arc,pop,xovers Integers for genetic algorithm settings. +#' @param factor Integer randomization factor. +#' @param nr Integer next reordering value. +#' @param max_mem Numeric memory limit. +#' @param add A [`CuddADD`] instance. +#' @return A scalar value or `NULL`, depending on the call. +#' @name cudd_manager_controls +NULL + +#' @rdname cudd_manager_controls +#' @export +cudd_read_start_time <- function(manager) { + return(.Call(c_cudd_read_start_time, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_read_elapsed_time <- function(manager) { + return(.Call(c_cudd_read_elapsed_time, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_set_start_time <- function(manager, st) { + return(.Call(c_cudd_set_start_time, .cudd_manager_ptr(manager), st)) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_reset_start_time <- function(manager) { + return(.Call(c_cudd_reset_start_time, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_read_time_limit <- function(manager) { + return(.Call(c_cudd_read_time_limit, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_set_time_limit <- function(manager, tl) { + return(.Call(c_cudd_set_time_limit, .cudd_manager_ptr(manager), tl)) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_update_time_limit <- function(manager) { + return(.Call(c_cudd_update_time_limit, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_increase_time_limit <- function(manager, inc) { + return(.Call(c_cudd_increase_time_limit, .cudd_manager_ptr(manager), inc)) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_unset_time_limit <- function(manager) { + return(.Call(c_cudd_unset_time_limit, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_time_limited <- function(manager) { + return(.Call(c_cudd_time_limited, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_autodyn_enable <- function(manager, method = NULL) { + return(.Call(c_cudd_autodyn_enable, .cudd_manager_ptr(manager), method)) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_autodyn_disable <- function(manager) { + return(.Call(c_cudd_autodyn_disable, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_reordering_status <- function(manager) { + return(.Call(c_cudd_reordering_status, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_autodyn_enable_zdd <- function(manager, method = NULL) { + return(.Call(c_cudd_autodyn_enable_zdd, .cudd_manager_ptr(manager), method)) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_autodyn_disable_zdd <- function(manager) { + return(.Call(c_cudd_autodyn_disable_zdd, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_reordering_status_zdd <- function(manager) { + return(.Call(c_cudd_reordering_status_zdd, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_zdd_realignment_enabled <- function(manager) { + return(.Call(c_cudd_zdd_realignment_enabled, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_zdd_realign_enable <- function(manager) { + return(.Call(c_cudd_zdd_realign_enable, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_zdd_realign_disable <- function(manager) { + return(.Call(c_cudd_zdd_realign_disable, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_bdd_realignment_enabled <- function(manager) { + return(.Call(c_cudd_bdd_realignment_enabled, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_bdd_realign_enable <- function(manager) { + return(.Call(c_cudd_bdd_realign_enable, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_bdd_realign_disable <- function(manager) { + return(.Call(c_cudd_bdd_realign_disable, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_background <- function(manager) { + ptr <- .Call(c_cudd_background, .cudd_manager_ptr(manager)) + return(methods::new("CuddADD", ptr = ptr, manager_ptr = .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_set_background <- function(manager, add) { + return(.Call(c_cudd_set_background, .cudd_manager_ptr(manager), .cudd_add_ptr(add))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_read_max_cache <- function(manager) { + return(.Call(c_cudd_read_max_cache, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_read_max_cache_hard <- function(manager) { + return(.Call(c_cudd_read_max_cache_hard, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_set_max_cache_hard <- function(manager, mc) { + return(.Call(c_cudd_set_max_cache_hard, .cudd_manager_ptr(manager), mc)) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_read_slots <- function(manager) { + return(.Call(c_cudd_read_slots, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_read_keys <- function(manager) { + return(.Call(c_cudd_read_keys, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_read_dead <- function(manager) { + return(.Call(c_cudd_read_dead, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_read_min_dead <- function(manager) { + return(.Call(c_cudd_read_min_dead, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_read_max_reorderings <- function(manager) { + return(.Call(c_cudd_read_max_reorderings, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_set_max_reorderings <- function(manager, mr) { + return(.Call(c_cudd_set_max_reorderings, .cudd_manager_ptr(manager), mr)) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_read_reordering_time <- function(manager) { + return(.Call(c_cudd_read_reordering_time, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_read_garbage_collections <- function(manager) { + return(.Call(c_cudd_read_garbage_collections, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_read_garbage_collection_time <- function(manager) { # nolint: object_length_linter. + return(.Call(c_cudd_read_garbage_collection_time, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_read_sift_max_var <- function(manager) { + return(.Call(c_cudd_read_sift_max_var, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_set_sift_max_var <- function(manager, smv) { + return(.Call(c_cudd_set_sift_max_var, .cudd_manager_ptr(manager), smv)) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_read_sift_max_swap <- function(manager) { + return(.Call(c_cudd_read_sift_max_swap, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_set_sift_max_swap <- function(manager, sms) { + return(.Call(c_cudd_set_sift_max_swap, .cudd_manager_ptr(manager), sms)) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_read_max_growth <- function(manager) { + return(.Call(c_cudd_read_max_growth, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_set_max_growth <- function(manager, mg) { + return(.Call(c_cudd_set_max_growth, .cudd_manager_ptr(manager), mg)) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_read_perm <- function(manager, i) { + return(.Call(c_cudd_read_perm, .cudd_manager_ptr(manager), i)) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_read_perm_zdd <- function(manager, i) { + return(.Call(c_cudd_read_perm_zdd, .cudd_manager_ptr(manager), i)) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_read_inv_perm <- function(manager, i) { + return(.Call(c_cudd_read_inv_perm, .cudd_manager_ptr(manager), i)) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_read_inv_perm_zdd <- function(manager, i) { + return(.Call(c_cudd_read_inv_perm_zdd, .cudd_manager_ptr(manager), i)) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_read_vars <- function(manager, i) { + ptr <- .Call(c_cudd_read_vars, .cudd_manager_ptr(manager), i) + return(methods::new("CuddBDD", ptr = ptr, manager_ptr = .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_read_epsilon <- function(manager) { + return(.Call(c_cudd_read_epsilon, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_set_epsilon <- function(manager, ep) { + return(.Call(c_cudd_set_epsilon, .cudd_manager_ptr(manager), ep)) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_read_groupcheck <- function(manager) { + return(.Call(c_cudd_read_groupcheck, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_set_groupcheck <- function(manager, gc) { + return(.Call(c_cudd_set_groupcheck, .cudd_manager_ptr(manager), gc)) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_garbage_collection_enabled <- function(manager) { # nolint: object_length_linter. + return(.Call(c_cudd_garbage_collection_enabled, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_enable_garbage_collection <- function(manager) { + return(.Call(c_cudd_enable_garbage_collection, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_disable_garbage_collection <- function(manager) { # nolint: object_length_linter. + return(.Call(c_cudd_disable_garbage_collection, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_dead_are_counted <- function(manager) { + return(.Call(c_cudd_dead_are_counted, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_turn_on_count_dead <- function(manager) { + return(.Call(c_cudd_turn_on_count_dead, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_turn_off_count_dead <- function(manager) { + return(.Call(c_cudd_turn_off_count_dead, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_read_recomb <- function(manager) { + return(.Call(c_cudd_read_recomb, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_set_recomb <- function(manager, recomb) { + return(.Call(c_cudd_set_recomb, .cudd_manager_ptr(manager), recomb)) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_read_symmviolation <- function(manager) { + return(.Call(c_cudd_read_symmviolation, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_set_symmviolation <- function(manager, symm) { + return(.Call(c_cudd_set_symmviolation, .cudd_manager_ptr(manager), symm)) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_read_arcviolation <- function(manager) { + return(.Call(c_cudd_read_arcviolation, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_set_arcviolation <- function(manager, arc) { + return(.Call(c_cudd_set_arcviolation, .cudd_manager_ptr(manager), arc)) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_read_population_size <- function(manager) { + return(.Call(c_cudd_read_population_size, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_set_population_size <- function(manager, pop) { + return(.Call(c_cudd_set_population_size, .cudd_manager_ptr(manager), pop)) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_read_number_xovers <- function(manager) { + return(.Call(c_cudd_read_number_xovers, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_set_number_xovers <- function(manager, xovers) { + return(.Call(c_cudd_set_number_xovers, .cudd_manager_ptr(manager), xovers)) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_read_order_randomization <- function(manager) { + return(.Call(c_cudd_read_order_randomization, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_set_order_randomization <- function(manager, factor) { + return(.Call(c_cudd_set_order_randomization, .cudd_manager_ptr(manager), factor)) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_read_memory_in_use <- function(manager) { + return(.Call(c_cudd_read_memory_in_use, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_read_peak_node_count <- function(manager) { + return(.Call(c_cudd_read_peak_node_count, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_read_node_count_current <- function(manager) { + return(.Call(c_cudd_read_node_count_current, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_read_node_count_zdd <- function(manager) { + return(.Call(c_cudd_read_node_count_zdd, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_enable_reordering_reporting <- function(manager) { # nolint: object_length_linter. + return(.Call(c_cudd_enable_reordering_reporting, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_disable_reordering_reporting <- function(manager) { # nolint: object_length_linter. + return(.Call(c_cudd_disable_reordering_reporting, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_reordering_reporting <- function(manager) { + return(.Call(c_cudd_reordering_reporting, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_read_error_code <- function(manager) { + return(.Call(c_cudd_read_error_code, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_clear_error_code <- function(manager) { + return(.Call(c_cudd_clear_error_code, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_read_next_reordering <- function(manager) { + return(.Call(c_cudd_read_next_reordering, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_set_next_reordering <- function(manager, nr) { + return(.Call(c_cudd_set_next_reordering, .cudd_manager_ptr(manager), nr)) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_read_swap_steps <- function(manager) { + return(.Call(c_cudd_read_swap_steps, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_read_max_live <- function(manager) { + return(.Call(c_cudd_read_max_live, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_set_max_live <- function(manager, max_live) { + return(.Call(c_cudd_set_max_live, .cudd_manager_ptr(manager), max_live)) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_read_max_memory <- function(manager) { + return(.Call(c_cudd_read_max_memory, .cudd_manager_ptr(manager))) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_set_max_memory <- function(manager, max_mem) { + return(.Call(c_cudd_set_max_memory, .cudd_manager_ptr(manager), max_mem)) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_bdd_bind_var <- function(manager, index) { + return(.Call(c_cudd_bdd_bind_var, .cudd_manager_ptr(manager), index)) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_bdd_unbind_var <- function(manager, index) { + return(.Call(c_cudd_bdd_unbind_var, .cudd_manager_ptr(manager), index)) +} + +#' @rdname cudd_manager_controls +#' @export +cudd_bdd_var_is_bound <- function(manager, index) { + return(.Call(c_cudd_bdd_var_is_bound, .cudd_manager_ptr(manager), index)) } diff --git a/R/cudd_zdd.R b/R/cudd_zdd.R new file mode 100644 index 0000000..0e62f7d --- /dev/null +++ b/R/cudd_zdd.R @@ -0,0 +1,140 @@ +#' S4 wrapper for a CUDD ZDD +#' +#' The ZDD wrapper encapsulates the underlying C++ `ZDD` instance and is +#' represented in R as an external pointer managed by a finalizer. +#' +#' @slot ptr External pointer to the underlying ZDD object. +#' @slot manager_ptr External pointer to the owning CUDD manager. +#' @keywords internal +methods::setClass( + "CuddZDD", + slots = list( + ptr = "externalptr", + manager_ptr = "externalptr" + ), + validity = function(object) { + if (!methods::is(object@ptr, "externalptr")) { + return("`ptr` must be an external pointer.") + } + if (is.null(object@ptr)) { + return("`ptr` must not be NULL.") + } + if (!methods::is(object@manager_ptr, "externalptr")) { + return("`manager_ptr` must be an external pointer.") + } + if (is.null(object@manager_ptr)) { + return("`manager_ptr` must not be NULL.") + } + return(TRUE) + } +) + +#' @describeIn CuddZDD-class Show a brief summary of the ZDD. +#' @param object A `CuddZDD` instance. +#' @keywords internal +methods::setMethod("show", "CuddZDD", function(object) { + cat("\n") + print(object) + return(invisible(object)) +}) + +.cudd_zdd_ptr <- function(zdd) { + if (!methods::is(zdd, "CuddZDD")) { + stop("`zdd` must be a CuddZDD object.", call. = FALSE) + } + return(zdd@ptr) +} + +.cudd_zdd_manager_ptr <- function(zdd) { + if (!methods::is(zdd, "CuddZDD")) { + stop("`zdd` must be a CuddZDD object.", call. = FALSE) + } + return(zdd@manager_ptr) +} + +#' Create a ZDD node that represents the constant one +#' +#' @param manager A [`CuddManager`] instance. +#' @param index Non-negative integer index for the ZDD one node. +#' @return A [`CuddZDD`] instance representing the ZDD one node. +#' @export +cudd_zdd_one <- function(manager, index = 0L) { + ptr <- .Call(c_cudd_zdd_one, .cudd_manager_ptr(manager), index) + return(methods::new("CuddZDD", ptr = ptr, manager_ptr = .cudd_manager_ptr(manager))) +} + +#' Create a ZDD node that represents the constant zero +#' +#' @param manager A [`CuddManager`] instance. +#' @return A [`CuddZDD`] instance representing the ZDD zero node. +#' @export +cudd_zdd_zero <- function(manager) { + ptr <- .Call(c_cudd_zdd_zero, .cudd_manager_ptr(manager)) + return(methods::new("CuddZDD", ptr = ptr, manager_ptr = .cudd_manager_ptr(manager))) +} + +#' Create or access a ZDD variable +#' +#' When `index` is `NULL`, the next available ZDD variable index is used. +#' +#' @param manager A [`CuddManager`] instance. +#' @param index Optional non-negative integer index of the ZDD variable. +#' @return A [`CuddZDD`] instance representing the requested variable. +#' @export +cudd_zdd_var <- function(manager, index = NULL) { + ptr <- .Call(c_cudd_zdd_var, .cudd_manager_ptr(manager), index) + return(methods::new("CuddZDD", ptr = ptr, manager_ptr = .cudd_manager_ptr(manager))) +} + +#' @describeIn CuddZDD-class Combine ZDDs with intersection +#' @param e1 A `CuddZDD` instance. +#' @param e2 A `CuddZDD` instance. +#' @return A `CuddZDD` instance. +setMethod("*", signature(e1 = "CuddZDD", e2 = "CuddZDD"), function(e1, e2) { + if (!.cudd_check_same_manager(e1, e2, "*")) { + stop("Cannot combine ZDDs from different CuddManager instances.", call. = FALSE) + } + ptr <- .Call(c_cudd_zdd_intersect, .cudd_zdd_ptr(e1), .cudd_zdd_ptr(e2)) + return(methods::new("CuddZDD", ptr = ptr, manager_ptr = .cudd_zdd_manager_ptr(e1))) +}) + +#' @describeIn CuddZDD-class Combine ZDDs with union +#' @param e1 A `CuddZDD` instance. +#' @param e2 A `CuddZDD` instance. +#' @return A `CuddZDD` instance. +setMethod("+", signature(e1 = "CuddZDD", e2 = "CuddZDD"), function(e1, e2) { + if (!.cudd_check_same_manager(e1, e2, "+")) { + stop("Cannot combine ZDDs from different CuddManager instances.", call. = FALSE) + } + ptr <- .Call(c_cudd_zdd_union, .cudd_zdd_ptr(e1), .cudd_zdd_ptr(e2)) + return(methods::new("CuddZDD", ptr = ptr, manager_ptr = .cudd_zdd_manager_ptr(e1))) +}) + +#' @describeIn CuddZDD-class XOR is not defined for ZDDs +#' @param e1 A `CuddZDD` instance. +#' @param e2 A `CuddZDD` instance. +#' @return An error indicating the operator is unsupported. +setMethod("^", signature(e1 = "CuddZDD", e2 = "CuddZDD"), function(e1, e2) { + stop("XOR (^) is not defined for CuddZDD.", call. = FALSE) +}) + +#' @describeIn CuddZDD-class Negation is not defined for ZDDs +#' @param x A `CuddZDD` instance. +#' @return An error indicating the operator is unsupported. +setMethod("!", "CuddZDD", function(x) { + stop("Negation (!) is not defined for CuddZDD.", call. = FALSE) +}) + +#' Print the minterm representation for a ZDD +#' +#' This uses the CUDD `PrintMinterm` implementation, which writes to R's +#' output stream. +#' +#' @param x A [`CuddZDD`] instance. +#' @param ... Unused. +#' @return The input `x`, invisibly. +#' @export +setMethod("print", "CuddZDD", function(x, ...) { + .Call(c_cudd_zdd_print_minterm, .cudd_zdd_ptr(x)) + return(invisible(x)) +}) diff --git a/R/rcudd.R b/R/rcudd.R index 6c10963..02c8c79 100644 --- a/R/rcudd.R +++ b/R/rcudd.R @@ -1,2 +1,163 @@ #' @useDynLib Rcudd, .registration=TRUE NULL + +local({ + symbols <- c( + "c_bdd_remaining_literals", + "c_bdd_restrict_chain", + "c_cudd_add_epd_print_minterm", + "c_cudd_add_one", + "c_cudd_add_plus", + "c_cudd_add_print_minterm", + "c_cudd_add_times", + "c_cudd_add_to_bdd", + "c_cudd_add_var", + "c_cudd_add_zero", + "c_cudd_autodyn_disable", + "c_cudd_autodyn_disable_zdd", + "c_cudd_autodyn_enable", + "c_cudd_autodyn_enable_zdd", + "c_cudd_background", + "c_cudd_bdd_and", + "c_cudd_bdd_bind_var", + "c_cudd_bdd_dump_dot", + "c_cudd_bdd_epd_print_minterm", + "c_cudd_bdd_not", + "c_cudd_bdd_one", + "c_cudd_bdd_or", + "c_cudd_bdd_print_debug", + "c_cudd_bdd_print_minterm", + "c_cudd_bdd_realign_disable", + "c_cudd_bdd_realign_enable", + "c_cudd_bdd_realignment_enabled", + "c_cudd_bdd_to_add", + "c_cudd_bdd_to_zdd", + "c_cudd_bdd_unbind_var", + "c_cudd_bdd_var", + "c_cudd_bdd_var_is_bound", + "c_cudd_bdd_xor", + "c_cudd_bdd_zero", + "c_cudd_clear_error_code", + "c_cudd_clear_variable_names", + "c_cudd_dead_are_counted", + "c_cudd_disable_garbage_collection", + "c_cudd_disable_reordering_reporting", + "c_cudd_enable_garbage_collection", + "c_cudd_enable_reordering_reporting", + "c_cudd_garbage_collection_enabled", + "c_cudd_get_variable_name", + "c_cudd_increase_time_limit", + "c_cudd_info", + "c_cudd_is_verbose", + "c_cudd_make_terse", + "c_cudd_make_verbose", + "c_cudd_new", + "c_cudd_push_variable_name", + "c_cudd_read_arcviolation", + "c_cudd_read_cache_hits", + "c_cudd_read_cache_lookups", + "c_cudd_read_cache_slots", + "c_cudd_read_cache_used_slots", + "c_cudd_read_dead", + "c_cudd_read_elapsed_time", + "c_cudd_read_epsilon", + "c_cudd_read_error_code", + "c_cudd_read_garbage_collection_time", + "c_cudd_read_garbage_collections", + "c_cudd_read_groupcheck", + "c_cudd_read_inv_perm", + "c_cudd_read_inv_perm_zdd", + "c_cudd_read_keys", + "c_cudd_read_loose_up_to", + "c_cudd_read_max_cache", + "c_cudd_read_max_cache_hard", + "c_cudd_read_max_growth", + "c_cudd_read_max_live", + "c_cudd_read_max_memory", + "c_cudd_read_max_reorderings", + "c_cudd_read_memory_in_use", + "c_cudd_read_min_dead", + "c_cudd_read_min_hit", + "c_cudd_read_next_reordering", + "c_cudd_read_node_count", + "c_cudd_read_node_count_current", + "c_cudd_read_node_count_zdd", + "c_cudd_read_number_xovers", + "c_cudd_read_order_randomization", + "c_cudd_read_peak_node_count", + "c_cudd_read_perm", + "c_cudd_read_perm_zdd", + "c_cudd_read_population_size", + "c_cudd_read_recomb", + "c_cudd_read_reordering_time", + "c_cudd_read_reorderings", + "c_cudd_read_sift_max_swap", + "c_cudd_read_sift_max_var", + "c_cudd_read_size", + "c_cudd_read_slots", + "c_cudd_read_start_time", + "c_cudd_read_swap_steps", + "c_cudd_read_symmviolation", + "c_cudd_read_time_limit", + "c_cudd_read_vars", + "c_cudd_read_zdd_size", + "c_cudd_reordering_reporting", + "c_cudd_reordering_status", + "c_cudd_reordering_status_zdd", + "c_cudd_reset_start_time", + "c_cudd_set_arcviolation", + "c_cudd_set_background", + "c_cudd_set_epsilon", + "c_cudd_set_groupcheck", + "c_cudd_set_loose_up_to", + "c_cudd_set_max_cache_hard", + "c_cudd_set_max_growth", + "c_cudd_set_max_live", + "c_cudd_set_max_memory", + "c_cudd_set_max_reorderings", + "c_cudd_set_min_hit", + "c_cudd_set_next_reordering", + "c_cudd_set_number_xovers", + "c_cudd_set_order_randomization", + "c_cudd_set_population_size", + "c_cudd_set_recomb", + "c_cudd_set_sift_max_swap", + "c_cudd_set_sift_max_var", + "c_cudd_set_start_time", + "c_cudd_set_symmviolation", + "c_cudd_set_time_limit", + "c_cudd_time_limited", + "c_cudd_turn_off_count_dead", + "c_cudd_turn_on_count_dead", + "c_cudd_unset_time_limit", + "c_cudd_update_time_limit", + "c_cudd_zdd_intersect", + "c_cudd_zdd_one", + "c_cudd_zdd_print_minterm", + "c_cudd_zdd_realign_disable", + "c_cudd_zdd_realign_enable", + "c_cudd_zdd_realignment_enabled", + "c_cudd_zdd_to_bdd", + "c_cudd_zdd_union", + "c_cudd_zdd_var", + "c_cudd_zdd_zero" + ) + for (name in symbols) { + delayedAssign( + name, + getNativeSymbolInfo(name, PACKAGE = "Rcudd"), + assign.env = environment() + ) + } +}) + +.cudd_check_same_manager <- function(lhs, rhs, op) { + same_manager <- identical(lhs@manager_ptr, rhs@manager_ptr) + if (!same_manager) { + warning( + sprintf("Objects for %s come from different CuddManager instances.", op), + call. = FALSE + ) + } + return(same_manager) +} diff --git a/R/restrict_chain.R b/R/restrict_chain.R index 2aab5a1..6f0c19b 100644 --- a/R/restrict_chain.R +++ b/R/restrict_chain.R @@ -23,5 +23,5 @@ #' #' @export bdd_restrict_chain <- function(exprs, additional_constraints = character()) { - .Call(c_bdd_restrict_chain, exprs, additional_constraints) + return(.Call(c_bdd_restrict_chain, exprs, additional_constraints)) } diff --git a/man/CuddADD-class.Rd b/man/CuddADD-class.Rd new file mode 100644 index 0000000..d5c8dce --- /dev/null +++ b/man/CuddADD-class.Rd @@ -0,0 +1,66 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cudd_add.R +\docType{class} +\name{CuddADD-class} +\alias{CuddADD-class} +\alias{show,CuddADD-method} +\alias{*,CuddADD,CuddADD-method} +\alias{+,CuddADD,CuddADD-method} +\alias{^,CuddADD,CuddADD-method} +\alias{!,CuddADD-method} +\title{S4 wrapper for a CUDD ADD} +\usage{ +\S4method{show}{CuddADD}(object) + +\S4method{*}{CuddADD,CuddADD}(e1, e2) + +\S4method{+}{CuddADD,CuddADD}(e1, e2) + +\S4method{^}{CuddADD,CuddADD}(e1, e2) + +\S4method{!}{CuddADD}(x) +} +\arguments{ +\item{object}{A `CuddADD` instance.} + +\item{e1}{A `CuddADD` instance.} + +\item{e2}{A `CuddADD` instance.} + +\item{x}{A `CuddADD` instance.} +} +\value{ +A `CuddADD` instance. + +A `CuddADD` instance. + +An error indicating the operator is unsupported. + +An error indicating the operator is unsupported. +} +\description{ +The ADD wrapper encapsulates the underlying C++ `ADD` instance and is +represented in R as an external pointer managed by a finalizer. +} +\section{Functions}{ +\itemize{ +\item \code{show(CuddADD)}: Show a brief summary of the ADD. + +\item \code{e1 * e2}: Combine ADDs with multiplication + +\item \code{e1 + e2}: Combine ADDs with addition + +\item \code{e1^e2}: XOR is not defined for ADDs + +\item \code{`!`(CuddADD)}: Negation is not defined for ADDs + +}} +\section{Slots}{ + +\describe{ +\item{\code{ptr}}{External pointer to the underlying ADD object.} + +\item{\code{manager_ptr}}{External pointer to the owning CUDD manager.} +}} + +\keyword{internal} diff --git a/man/CuddBDD-class.Rd b/man/CuddBDD-class.Rd new file mode 100644 index 0000000..c20cb66 --- /dev/null +++ b/man/CuddBDD-class.Rd @@ -0,0 +1,66 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cudd_bdd.R +\docType{class} +\name{CuddBDD-class} +\alias{CuddBDD-class} +\alias{show,CuddBDD-method} +\alias{!,CuddBDD-method} +\alias{+,CuddBDD,CuddBDD-method} +\alias{*,CuddBDD,CuddBDD-method} +\alias{^,CuddBDD,CuddBDD-method} +\title{S4 wrapper for a CUDD BDD} +\usage{ +\S4method{show}{CuddBDD}(object) + +\S4method{!}{CuddBDD}(x) + +\S4method{+}{CuddBDD,CuddBDD}(e1, e2) + +\S4method{*}{CuddBDD,CuddBDD}(e1, e2) + +\S4method{^}{CuddBDD,CuddBDD}(e1, e2) +} +\arguments{ +\item{object}{A `CuddBDD` instance.} + +\item{x}{A `CuddBDD` instance.} + +\item{e1}{A `CuddBDD` instance.} + +\item{e2}{A `CuddBDD` instance.} +} +\value{ +A `CuddBDD` instance. + +A `CuddBDD` instance. + +A `CuddBDD` instance. + +A `CuddBDD` instance. +} +\description{ +The BDD wrapper encapsulates the underlying C++ `BDD` instance and is +represented in R as an external pointer managed by a finalizer. +} +\section{Functions}{ +\itemize{ +\item \code{show(CuddBDD)}: Show a brief summary of the BDD. + +\item \code{`!`(CuddBDD)}: Negate a BDD + +\item \code{e1 + e2}: Combine BDDs with addition (logical OR) + +\item \code{e1 * e2}: Combine BDDs with multiplication (logical AND) + +\item \code{e1^e2}: Combine BDDs with XOR + +}} +\section{Slots}{ + +\describe{ +\item{\code{ptr}}{External pointer to the underlying BDD object.} + +\item{\code{manager_ptr}}{External pointer to the owning CUDD manager.} +}} + +\keyword{internal} diff --git a/man/CuddZDD-class.Rd b/man/CuddZDD-class.Rd new file mode 100644 index 0000000..ab96089 --- /dev/null +++ b/man/CuddZDD-class.Rd @@ -0,0 +1,66 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cudd_zdd.R +\docType{class} +\name{CuddZDD-class} +\alias{CuddZDD-class} +\alias{show,CuddZDD-method} +\alias{*,CuddZDD,CuddZDD-method} +\alias{+,CuddZDD,CuddZDD-method} +\alias{^,CuddZDD,CuddZDD-method} +\alias{!,CuddZDD-method} +\title{S4 wrapper for a CUDD ZDD} +\usage{ +\S4method{show}{CuddZDD}(object) + +\S4method{*}{CuddZDD,CuddZDD}(e1, e2) + +\S4method{+}{CuddZDD,CuddZDD}(e1, e2) + +\S4method{^}{CuddZDD,CuddZDD}(e1, e2) + +\S4method{!}{CuddZDD}(x) +} +\arguments{ +\item{object}{A `CuddZDD` instance.} + +\item{e1}{A `CuddZDD` instance.} + +\item{e2}{A `CuddZDD` instance.} + +\item{x}{A `CuddZDD` instance.} +} +\value{ +A `CuddZDD` instance. + +A `CuddZDD` instance. + +An error indicating the operator is unsupported. + +An error indicating the operator is unsupported. +} +\description{ +The ZDD wrapper encapsulates the underlying C++ `ZDD` instance and is +represented in R as an external pointer managed by a finalizer. +} +\section{Functions}{ +\itemize{ +\item \code{show(CuddZDD)}: Show a brief summary of the ZDD. + +\item \code{e1 * e2}: Combine ZDDs with intersection + +\item \code{e1 + e2}: Combine ZDDs with union + +\item \code{e1^e2}: XOR is not defined for ZDDs + +\item \code{`!`(CuddZDD)}: Negation is not defined for ZDDs + +}} +\section{Slots}{ + +\describe{ +\item{\code{ptr}}{External pointer to the underlying ZDD object.} + +\item{\code{manager_ptr}}{External pointer to the owning CUDD manager.} +}} + +\keyword{internal} diff --git a/man/cudd_add_epd_print_minterm.Rd b/man/cudd_add_epd_print_minterm.Rd new file mode 100644 index 0000000..bff8867 --- /dev/null +++ b/man/cudd_add_epd_print_minterm.Rd @@ -0,0 +1,20 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cudd_add.R +\name{cudd_add_epd_print_minterm} +\alias{cudd_add_epd_print_minterm} +\title{Print an EPD minterm count for an ADD} +\usage{ +cudd_add_epd_print_minterm(add, nvars) +} +\arguments{ +\item{add}{A [`CuddADD`] instance.} + +\item{nvars}{Non-negative integer indicating how many variables to consider.} +} +\value{ +`NULL`, invisibly. +} +\description{ +This uses the CUDD `EpdPrintMinterm` implementation, which writes to R's +output stream. +} diff --git a/man/cudd_add_one.Rd b/man/cudd_add_one.Rd new file mode 100644 index 0000000..03429d8 --- /dev/null +++ b/man/cudd_add_one.Rd @@ -0,0 +1,17 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cudd_add.R +\name{cudd_add_one} +\alias{cudd_add_one} +\title{Create an ADD node that represents logical TRUE} +\usage{ +cudd_add_one(manager) +} +\arguments{ +\item{manager}{A [`CuddManager`] instance.} +} +\value{ +A [`CuddADD`] instance representing a constant TRUE ADD. +} +\description{ +Create an ADD node that represents logical TRUE +} diff --git a/man/cudd_add_to_bdd.Rd b/man/cudd_add_to_bdd.Rd new file mode 100644 index 0000000..1cd14bf --- /dev/null +++ b/man/cudd_add_to_bdd.Rd @@ -0,0 +1,17 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cudd_conversions.R +\name{cudd_add_to_bdd} +\alias{cudd_add_to_bdd} +\title{Convert an ADD to a BDD using the non-zero pattern} +\usage{ +cudd_add_to_bdd(add) +} +\arguments{ +\item{add}{A [`CuddADD`] instance.} +} +\value{ +A [`CuddBDD`] instance. +} +\description{ +Convert an ADD to a BDD using the non-zero pattern +} diff --git a/man/cudd_add_var.Rd b/man/cudd_add_var.Rd new file mode 100644 index 0000000..6214745 --- /dev/null +++ b/man/cudd_add_var.Rd @@ -0,0 +1,20 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cudd_add.R +\name{cudd_add_var} +\alias{cudd_add_var} +\title{Create or access an ADD variable} +\usage{ +cudd_add_var(manager, index = NULL) +} +\arguments{ +\item{manager}{A [`CuddManager`] instance.} + +\item{index}{Optional non-negative integer index of the ADD variable.} +} +\value{ +A [`CuddADD`] instance representing the requested variable. +} +\description{ +When `index` is `NULL`, a new ADD variable is created in the manager and +returned. Otherwise, the ADD variable at the specified index is returned. +} diff --git a/man/cudd_add_zero.Rd b/man/cudd_add_zero.Rd new file mode 100644 index 0000000..614292b --- /dev/null +++ b/man/cudd_add_zero.Rd @@ -0,0 +1,17 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cudd_add.R +\name{cudd_add_zero} +\alias{cudd_add_zero} +\title{Create an ADD node that represents logical FALSE} +\usage{ +cudd_add_zero(manager) +} +\arguments{ +\item{manager}{A [`CuddManager`] instance.} +} +\value{ +A [`CuddADD`] instance representing a constant FALSE ADD. +} +\description{ +Create an ADD node that represents logical FALSE +} diff --git a/man/cudd_bdd_dump_dot.Rd b/man/cudd_bdd_dump_dot.Rd new file mode 100644 index 0000000..59e25f5 --- /dev/null +++ b/man/cudd_bdd_dump_dot.Rd @@ -0,0 +1,18 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cudd_bdd.R +\name{cudd_bdd_dump_dot} +\alias{cudd_bdd_dump_dot} +\title{Dump a BDD as Graphviz DOT} +\usage{ +cudd_bdd_dump_dot(bdd) +} +\arguments{ +\item{bdd}{A [`CuddBDD`] instance.} +} +\value{ +Character scalar containing DOT text. +} +\description{ +Produces a DOT representation that can be rendered by Graphviz to visualize +the full decision diagram structure. +} diff --git a/man/cudd_bdd_epd_print_minterm.Rd b/man/cudd_bdd_epd_print_minterm.Rd new file mode 100644 index 0000000..2c922e6 --- /dev/null +++ b/man/cudd_bdd_epd_print_minterm.Rd @@ -0,0 +1,20 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cudd_bdd.R +\name{cudd_bdd_epd_print_minterm} +\alias{cudd_bdd_epd_print_minterm} +\title{Print an EPD minterm count for a BDD} +\usage{ +cudd_bdd_epd_print_minterm(bdd, nvars) +} +\arguments{ +\item{bdd}{A [`CuddBDD`] instance.} + +\item{nvars}{Non-negative integer indicating how many variables to consider.} +} +\value{ +`NULL`, invisibly. +} +\description{ +This uses the CUDD `EpdPrintMinterm` implementation, which writes to R's +output stream. +} diff --git a/man/cudd_bdd_one.Rd b/man/cudd_bdd_one.Rd new file mode 100644 index 0000000..3444e75 --- /dev/null +++ b/man/cudd_bdd_one.Rd @@ -0,0 +1,17 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cudd_bdd.R +\name{cudd_bdd_one} +\alias{cudd_bdd_one} +\title{Create a BDD node that represents logical TRUE} +\usage{ +cudd_bdd_one(manager) +} +\arguments{ +\item{manager}{A [`CuddManager`] instance.} +} +\value{ +A [`CuddBDD`] instance representing a constant TRUE BDD. +} +\description{ +Create a BDD node that represents logical TRUE +} diff --git a/man/cudd_bdd_print_debug.Rd b/man/cudd_bdd_print_debug.Rd new file mode 100644 index 0000000..bce3af7 --- /dev/null +++ b/man/cudd_bdd_print_debug.Rd @@ -0,0 +1,23 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cudd_bdd.R +\name{cudd_bdd_print_debug} +\alias{cudd_bdd_print_debug} +\title{Print a debug representation for a BDD} +\usage{ +cudd_bdd_print_debug(bdd, nvars = NULL, verbosity = NULL) +} +\arguments{ +\item{bdd}{A [`CuddBDD`] instance.} + +\item{nvars}{Optional non-negative integer indicating how many variables to +include. Defaults to the manager size.} + +\item{verbosity}{Optional non-negative integer debug verbosity.} +} +\value{ +`NULL`, invisibly. +} +\description{ +This uses the CUDD `PrintDebug` implementation, which writes to R's output +stream. +} diff --git a/man/cudd_bdd_to_add.Rd b/man/cudd_bdd_to_add.Rd new file mode 100644 index 0000000..d4b7cee --- /dev/null +++ b/man/cudd_bdd_to_add.Rd @@ -0,0 +1,17 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cudd_conversions.R +\name{cudd_bdd_to_add} +\alias{cudd_bdd_to_add} +\title{Convert a BDD to an ADD} +\usage{ +cudd_bdd_to_add(bdd) +} +\arguments{ +\item{bdd}{A [`CuddBDD`] instance.} +} +\value{ +A [`CuddADD`] instance. +} +\description{ +Convert a BDD to an ADD +} diff --git a/man/cudd_bdd_to_zdd.Rd b/man/cudd_bdd_to_zdd.Rd new file mode 100644 index 0000000..cefa213 --- /dev/null +++ b/man/cudd_bdd_to_zdd.Rd @@ -0,0 +1,17 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cudd_conversions.R +\name{cudd_bdd_to_zdd} +\alias{cudd_bdd_to_zdd} +\title{Convert a BDD to a ZDD} +\usage{ +cudd_bdd_to_zdd(bdd) +} +\arguments{ +\item{bdd}{A [`CuddBDD`] instance.} +} +\value{ +A [`CuddZDD`] instance. +} +\description{ +Convert a BDD to a ZDD +} diff --git a/man/cudd_bdd_var.Rd b/man/cudd_bdd_var.Rd new file mode 100644 index 0000000..97593e2 --- /dev/null +++ b/man/cudd_bdd_var.Rd @@ -0,0 +1,20 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cudd_bdd.R +\name{cudd_bdd_var} +\alias{cudd_bdd_var} +\title{Create or access a BDD variable} +\usage{ +cudd_bdd_var(manager, index = NULL) +} +\arguments{ +\item{manager}{A [`CuddManager`] instance.} + +\item{index}{Optional non-negative integer index of the BDD variable.} +} +\value{ +A [`CuddBDD`] instance representing the requested variable. +} +\description{ +When `index` is `NULL`, a new BDD variable is created in the manager and +returned. Otherwise, the BDD variable at the specified index is returned. +} diff --git a/man/cudd_bdd_zero.Rd b/man/cudd_bdd_zero.Rd new file mode 100644 index 0000000..5e7ab21 --- /dev/null +++ b/man/cudd_bdd_zero.Rd @@ -0,0 +1,17 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cudd_bdd.R +\name{cudd_bdd_zero} +\alias{cudd_bdd_zero} +\title{Create a BDD node that represents logical FALSE} +\usage{ +cudd_bdd_zero(manager) +} +\arguments{ +\item{manager}{A [`CuddManager`] instance.} +} +\value{ +A [`CuddBDD`] instance representing a constant FALSE BDD. +} +\description{ +Create a BDD node that represents logical FALSE +} diff --git a/man/cudd_manager_controls.Rd b/man/cudd_manager_controls.Rd new file mode 100644 index 0000000..6c93b7e --- /dev/null +++ b/man/cudd_manager_controls.Rd @@ -0,0 +1,333 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cudd_manager.R +\name{cudd_set_min_hit} +\alias{cudd_set_min_hit} +\alias{cudd_set_loose_up_to} +\alias{cudd_make_verbose} +\alias{cudd_make_terse} +\alias{cudd_is_verbose} +\alias{cudd_info} +\alias{cudd_push_variable_name} +\alias{cudd_clear_variable_names} +\alias{cudd_get_variable_name} +\alias{cudd_manager_controls} +\alias{cudd_read_start_time} +\alias{cudd_read_elapsed_time} +\alias{cudd_set_start_time} +\alias{cudd_reset_start_time} +\alias{cudd_read_time_limit} +\alias{cudd_set_time_limit} +\alias{cudd_update_time_limit} +\alias{cudd_increase_time_limit} +\alias{cudd_unset_time_limit} +\alias{cudd_time_limited} +\alias{cudd_autodyn_enable} +\alias{cudd_autodyn_disable} +\alias{cudd_reordering_status} +\alias{cudd_autodyn_enable_zdd} +\alias{cudd_autodyn_disable_zdd} +\alias{cudd_reordering_status_zdd} +\alias{cudd_zdd_realignment_enabled} +\alias{cudd_zdd_realign_enable} +\alias{cudd_zdd_realign_disable} +\alias{cudd_bdd_realignment_enabled} +\alias{cudd_bdd_realign_enable} +\alias{cudd_bdd_realign_disable} +\alias{cudd_background} +\alias{cudd_set_background} +\alias{cudd_read_max_cache} +\alias{cudd_read_max_cache_hard} +\alias{cudd_set_max_cache_hard} +\alias{cudd_read_slots} +\alias{cudd_read_keys} +\alias{cudd_read_dead} +\alias{cudd_read_min_dead} +\alias{cudd_read_max_reorderings} +\alias{cudd_set_max_reorderings} +\alias{cudd_read_reordering_time} +\alias{cudd_read_garbage_collections} +\alias{cudd_read_garbage_collection_time} +\alias{cudd_read_sift_max_var} +\alias{cudd_set_sift_max_var} +\alias{cudd_read_sift_max_swap} +\alias{cudd_set_sift_max_swap} +\alias{cudd_read_max_growth} +\alias{cudd_set_max_growth} +\alias{cudd_read_perm} +\alias{cudd_read_perm_zdd} +\alias{cudd_read_inv_perm} +\alias{cudd_read_inv_perm_zdd} +\alias{cudd_read_vars} +\alias{cudd_read_epsilon} +\alias{cudd_set_epsilon} +\alias{cudd_read_groupcheck} +\alias{cudd_set_groupcheck} +\alias{cudd_garbage_collection_enabled} +\alias{cudd_enable_garbage_collection} +\alias{cudd_disable_garbage_collection} +\alias{cudd_dead_are_counted} +\alias{cudd_turn_on_count_dead} +\alias{cudd_turn_off_count_dead} +\alias{cudd_read_recomb} +\alias{cudd_set_recomb} +\alias{cudd_read_symmviolation} +\alias{cudd_set_symmviolation} +\alias{cudd_read_arcviolation} +\alias{cudd_set_arcviolation} +\alias{cudd_read_population_size} +\alias{cudd_set_population_size} +\alias{cudd_read_number_xovers} +\alias{cudd_set_number_xovers} +\alias{cudd_read_order_randomization} +\alias{cudd_set_order_randomization} +\alias{cudd_read_memory_in_use} +\alias{cudd_read_peak_node_count} +\alias{cudd_read_node_count_current} +\alias{cudd_read_node_count_zdd} +\alias{cudd_enable_reordering_reporting} +\alias{cudd_disable_reordering_reporting} +\alias{cudd_reordering_reporting} +\alias{cudd_read_error_code} +\alias{cudd_clear_error_code} +\alias{cudd_read_next_reordering} +\alias{cudd_set_next_reordering} +\alias{cudd_read_swap_steps} +\alias{cudd_read_max_live} +\alias{cudd_set_max_live} +\alias{cudd_read_max_memory} +\alias{cudd_set_max_memory} +\alias{cudd_bdd_bind_var} +\alias{cudd_bdd_unbind_var} +\alias{cudd_bdd_var_is_bound} +\title{CUDD manager controls} +\usage{ +cudd_set_min_hit(manager, hr) + +cudd_set_loose_up_to(manager, lut) + +cudd_make_verbose(manager) + +cudd_make_terse(manager) + +cudd_is_verbose(manager) + +cudd_info(manager) + +cudd_push_variable_name(manager, name) + +cudd_clear_variable_names(manager) + +cudd_get_variable_name(manager, index) + +cudd_read_start_time(manager) + +cudd_read_elapsed_time(manager) + +cudd_set_start_time(manager, st) + +cudd_reset_start_time(manager) + +cudd_read_time_limit(manager) + +cudd_set_time_limit(manager, tl) + +cudd_update_time_limit(manager) + +cudd_increase_time_limit(manager, inc) + +cudd_unset_time_limit(manager) + +cudd_time_limited(manager) + +cudd_autodyn_enable(manager, method = NULL) + +cudd_autodyn_disable(manager) + +cudd_reordering_status(manager) + +cudd_autodyn_enable_zdd(manager, method = NULL) + +cudd_autodyn_disable_zdd(manager) + +cudd_reordering_status_zdd(manager) + +cudd_zdd_realignment_enabled(manager) + +cudd_zdd_realign_enable(manager) + +cudd_zdd_realign_disable(manager) + +cudd_bdd_realignment_enabled(manager) + +cudd_bdd_realign_enable(manager) + +cudd_bdd_realign_disable(manager) + +cudd_background(manager) + +cudd_set_background(manager, add) + +cudd_read_max_cache(manager) + +cudd_read_max_cache_hard(manager) + +cudd_set_max_cache_hard(manager, mc) + +cudd_read_slots(manager) + +cudd_read_keys(manager) + +cudd_read_dead(manager) + +cudd_read_min_dead(manager) + +cudd_read_max_reorderings(manager) + +cudd_set_max_reorderings(manager, mr) + +cudd_read_reordering_time(manager) + +cudd_read_garbage_collections(manager) + +cudd_read_garbage_collection_time(manager) + +cudd_read_sift_max_var(manager) + +cudd_set_sift_max_var(manager, smv) + +cudd_read_sift_max_swap(manager) + +cudd_set_sift_max_swap(manager, sms) + +cudd_read_max_growth(manager) + +cudd_set_max_growth(manager, mg) + +cudd_read_perm(manager, i) + +cudd_read_perm_zdd(manager, i) + +cudd_read_inv_perm(manager, i) + +cudd_read_inv_perm_zdd(manager, i) + +cudd_read_vars(manager, i) + +cudd_read_epsilon(manager) + +cudd_set_epsilon(manager, ep) + +cudd_read_groupcheck(manager) + +cudd_set_groupcheck(manager, gc) + +cudd_garbage_collection_enabled(manager) + +cudd_enable_garbage_collection(manager) + +cudd_disable_garbage_collection(manager) + +cudd_dead_are_counted(manager) + +cudd_turn_on_count_dead(manager) + +cudd_turn_off_count_dead(manager) + +cudd_read_recomb(manager) + +cudd_set_recomb(manager, recomb) + +cudd_read_symmviolation(manager) + +cudd_set_symmviolation(manager, symm) + +cudd_read_arcviolation(manager) + +cudd_set_arcviolation(manager, arc) + +cudd_read_population_size(manager) + +cudd_set_population_size(manager, pop) + +cudd_read_number_xovers(manager) + +cudd_set_number_xovers(manager, xovers) + +cudd_read_order_randomization(manager) + +cudd_set_order_randomization(manager, factor) + +cudd_read_memory_in_use(manager) + +cudd_read_peak_node_count(manager) + +cudd_read_node_count_current(manager) + +cudd_read_node_count_zdd(manager) + +cudd_enable_reordering_reporting(manager) + +cudd_disable_reordering_reporting(manager) + +cudd_reordering_reporting(manager) + +cudd_read_error_code(manager) + +cudd_clear_error_code(manager) + +cudd_read_next_reordering(manager) + +cudd_set_next_reordering(manager, nr) + +cudd_read_swap_steps(manager) + +cudd_read_max_live(manager) + +cudd_set_max_live(manager, max_live) + +cudd_read_max_memory(manager) + +cudd_set_max_memory(manager, max_mem) + +cudd_bdd_bind_var(manager, index) + +cudd_bdd_unbind_var(manager, index) + +cudd_bdd_var_is_bound(manager, index) +} +\arguments{ +\item{manager}{A [`CuddManager`] instance.} + +\item{hr, lut}{Integers used for cache hit/loose-up-to thresholds.} + +\item{name}{Single string for variable names.} + +\item{st, tl, inc}{Numeric scalars used for time limit operations.} + +\item{method}{Optional integer reordering method (CUDD enum value).} + +\item{add}{A [`CuddADD`] instance.} + +\item{mc, mr, smv, sms, max_live}{Integers used for cache/reordering limits.} + +\item{mg, ep}{Numeric values for growth/epsilon settings.} + +\item{i, index}{Integer indices for variable-related queries.} + +\item{gc}{Integer CUDD aggregation type.} + +\item{recomb, symm, arc, pop, xovers}{Integers for genetic algorithm settings.} + +\item{factor}{Integer randomization factor.} + +\item{nr}{Integer next reordering value.} + +\item{max_mem}{Numeric memory limit.} +} +\value{ +A scalar value or `NULL`, depending on the call. +} +\description{ +Convenience wrappers around the CUDD manager API for tuning reordering, +time limits, memory limits, and reading manager statistics. +} diff --git a/man/cudd_read_cache_hits.Rd b/man/cudd_read_cache_hits.Rd new file mode 100644 index 0000000..ebd6c0f --- /dev/null +++ b/man/cudd_read_cache_hits.Rd @@ -0,0 +1,17 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cudd_manager.R +\name{cudd_read_cache_hits} +\alias{cudd_read_cache_hits} +\title{Read the cache hit count} +\usage{ +cudd_read_cache_hits(manager) +} +\arguments{ +\item{manager}{A [`CuddManager`] instance.} +} +\value{ +Double scalar with the cache hit count. +} +\description{ +Read the cache hit count +} diff --git a/man/cudd_read_cache_lookups.Rd b/man/cudd_read_cache_lookups.Rd new file mode 100644 index 0000000..1d06b38 --- /dev/null +++ b/man/cudd_read_cache_lookups.Rd @@ -0,0 +1,17 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cudd_manager.R +\name{cudd_read_cache_lookups} +\alias{cudd_read_cache_lookups} +\title{Read the cache lookup count} +\usage{ +cudd_read_cache_lookups(manager) +} +\arguments{ +\item{manager}{A [`CuddManager`] instance.} +} +\value{ +Double scalar with the cache lookup count. +} +\description{ +Read the cache lookup count +} diff --git a/man/cudd_read_cache_slots.Rd b/man/cudd_read_cache_slots.Rd new file mode 100644 index 0000000..7cd1b21 --- /dev/null +++ b/man/cudd_read_cache_slots.Rd @@ -0,0 +1,17 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cudd_manager.R +\name{cudd_read_cache_slots} +\alias{cudd_read_cache_slots} +\title{Read the cache slot count} +\usage{ +cudd_read_cache_slots(manager) +} +\arguments{ +\item{manager}{A [`CuddManager`] instance.} +} +\value{ +Integer scalar with the cache slot count. +} +\description{ +Read the cache slot count +} diff --git a/man/cudd_read_node_count.Rd b/man/cudd_read_node_count.Rd new file mode 100644 index 0000000..ef00907 --- /dev/null +++ b/man/cudd_read_node_count.Rd @@ -0,0 +1,17 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cudd_manager.R +\name{cudd_read_node_count} +\alias{cudd_read_node_count} +\title{Read the live node count} +\usage{ +cudd_read_node_count(manager) +} +\arguments{ +\item{manager}{A [`CuddManager`] instance.} +} +\value{ +Double scalar with the live node count. +} +\description{ +Read the live node count +} diff --git a/man/cudd_read_size.Rd b/man/cudd_read_size.Rd new file mode 100644 index 0000000..c507a6d --- /dev/null +++ b/man/cudd_read_size.Rd @@ -0,0 +1,17 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cudd_manager.R +\name{cudd_read_size} +\alias{cudd_read_size} +\title{Read the number of BDD variables in the manager} +\usage{ +cudd_read_size(manager) +} +\arguments{ +\item{manager}{A [`CuddManager`] instance.} +} +\value{ +Integer scalar with the number of BDD variables. +} +\description{ +Read the number of BDD variables in the manager +} diff --git a/man/cudd_zdd_one.Rd b/man/cudd_zdd_one.Rd new file mode 100644 index 0000000..61b71ab --- /dev/null +++ b/man/cudd_zdd_one.Rd @@ -0,0 +1,19 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cudd_zdd.R +\name{cudd_zdd_one} +\alias{cudd_zdd_one} +\title{Create a ZDD node that represents the constant one} +\usage{ +cudd_zdd_one(manager, index = 0L) +} +\arguments{ +\item{manager}{A [`CuddManager`] instance.} + +\item{index}{Non-negative integer index for the ZDD one node.} +} +\value{ +A [`CuddZDD`] instance representing the ZDD one node. +} +\description{ +Create a ZDD node that represents the constant one +} diff --git a/man/cudd_zdd_to_bdd.Rd b/man/cudd_zdd_to_bdd.Rd new file mode 100644 index 0000000..aa61802 --- /dev/null +++ b/man/cudd_zdd_to_bdd.Rd @@ -0,0 +1,17 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cudd_conversions.R +\name{cudd_zdd_to_bdd} +\alias{cudd_zdd_to_bdd} +\title{Convert a ZDD to a BDD} +\usage{ +cudd_zdd_to_bdd(zdd) +} +\arguments{ +\item{zdd}{A [`CuddZDD`] instance.} +} +\value{ +A [`CuddBDD`] instance. +} +\description{ +Convert a ZDD to a BDD +} diff --git a/man/cudd_zdd_var.Rd b/man/cudd_zdd_var.Rd new file mode 100644 index 0000000..bbb88bb --- /dev/null +++ b/man/cudd_zdd_var.Rd @@ -0,0 +1,19 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cudd_zdd.R +\name{cudd_zdd_var} +\alias{cudd_zdd_var} +\title{Create or access a ZDD variable} +\usage{ +cudd_zdd_var(manager, index = NULL) +} +\arguments{ +\item{manager}{A [`CuddManager`] instance.} + +\item{index}{Optional non-negative integer index of the ZDD variable.} +} +\value{ +A [`CuddZDD`] instance representing the requested variable. +} +\description{ +When `index` is `NULL`, the next available ZDD variable index is used. +} diff --git a/man/cudd_zdd_zero.Rd b/man/cudd_zdd_zero.Rd new file mode 100644 index 0000000..ef59dd9 --- /dev/null +++ b/man/cudd_zdd_zero.Rd @@ -0,0 +1,17 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cudd_zdd.R +\name{cudd_zdd_zero} +\alias{cudd_zdd_zero} +\title{Create a ZDD node that represents the constant zero} +\usage{ +cudd_zdd_zero(manager) +} +\arguments{ +\item{manager}{A [`CuddManager`] instance.} +} +\value{ +A [`CuddZDD`] instance representing the ZDD zero node. +} +\description{ +Create a ZDD node that represents the constant zero +} diff --git a/man/print-CuddADD-method.Rd b/man/print-CuddADD-method.Rd new file mode 100644 index 0000000..bc9011b --- /dev/null +++ b/man/print-CuddADD-method.Rd @@ -0,0 +1,20 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cudd_add.R +\name{print,CuddADD-method} +\alias{print,CuddADD-method} +\title{Print the minterm representation for an ADD} +\usage{ +\S4method{print}{CuddADD}(x, ...) +} +\arguments{ +\item{x}{A [`CuddADD`] instance.} + +\item{...}{Unused.} +} +\value{ +The input `x`, invisibly. +} +\description{ +This uses the CUDD `PrintMinterm` implementation, which writes to R's +output stream. +} diff --git a/man/print-CuddBDD-method.Rd b/man/print-CuddBDD-method.Rd new file mode 100644 index 0000000..e298492 --- /dev/null +++ b/man/print-CuddBDD-method.Rd @@ -0,0 +1,20 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cudd_bdd.R +\name{print,CuddBDD-method} +\alias{print,CuddBDD-method} +\title{Print the minterm representation for a BDD} +\usage{ +\S4method{print}{CuddBDD}(x, ...) +} +\arguments{ +\item{x}{A [`CuddBDD`] instance.} + +\item{...}{Unused.} +} +\value{ +The input `x`, invisibly. +} +\description{ +This uses the CUDD `PrintMinterm` implementation, which writes to R's +output stream. +} diff --git a/man/print-CuddZDD-method.Rd b/man/print-CuddZDD-method.Rd new file mode 100644 index 0000000..f2d68e6 --- /dev/null +++ b/man/print-CuddZDD-method.Rd @@ -0,0 +1,20 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cudd_zdd.R +\name{print,CuddZDD-method} +\alias{print,CuddZDD-method} +\title{Print the minterm representation for a ZDD} +\usage{ +\S4method{print}{CuddZDD}(x, ...) +} +\arguments{ +\item{x}{A [`CuddZDD`] instance.} + +\item{...}{Unused.} +} +\value{ +The input `x`, invisibly. +} +\description{ +This uses the CUDD `PrintMinterm` implementation, which writes to R's +output stream. +} diff --git a/src/cudd_manager.cpp b/src/cudd_manager.cpp index bdc1c93..c5e90bb 100644 --- a/src/cudd_manager.cpp +++ b/src/cudd_manager.cpp @@ -1,6 +1,9 @@ #include "rcudd.h" #include #include +#include +#include +#include #include "cuddObj.hh" static void cudd_manager_finalizer(SEXP ptr) { @@ -14,6 +17,39 @@ static void cudd_manager_finalizer(SEXP ptr) { } } +static void bdd_finalizer(SEXP ptr) { + if (TYPEOF(ptr) != EXTPTRSXP) { + return; + } + void *addr = R_ExternalPtrAddr(ptr); + if (addr != nullptr) { + delete static_cast(addr); + R_ClearExternalPtr(ptr); + } +} + +static void add_finalizer(SEXP ptr) { + if (TYPEOF(ptr) != EXTPTRSXP) { + return; + } + void *addr = R_ExternalPtrAddr(ptr); + if (addr != nullptr) { + delete static_cast(addr); + R_ClearExternalPtr(ptr); + } +} + +static void zdd_finalizer(SEXP ptr) { + if (TYPEOF(ptr) != EXTPTRSXP) { + return; + } + void *addr = R_ExternalPtrAddr(ptr); + if (addr != nullptr) { + delete static_cast(addr); + R_ClearExternalPtr(ptr); + } +} + static Cudd *cudd_manager_from_ptr(SEXP ptr) { if (TYPEOF(ptr) != EXTPTRSXP) { Rf_error("Expected an external pointer for a CUDD manager."); @@ -25,6 +61,39 @@ static Cudd *cudd_manager_from_ptr(SEXP ptr) { return static_cast(addr); } +static BDD *bdd_from_ptr(SEXP ptr) { + if (TYPEOF(ptr) != EXTPTRSXP) { + Rf_error("Expected an external pointer for a CUDD BDD."); + } + void *addr = R_ExternalPtrAddr(ptr); + if (addr == nullptr) { + Rf_error("CUDD BDD pointer is NULL."); + } + return static_cast(addr); +} + +static ADD *add_from_ptr(SEXP ptr) { + if (TYPEOF(ptr) != EXTPTRSXP) { + Rf_error("Expected an external pointer for a CUDD ADD."); + } + void *addr = R_ExternalPtrAddr(ptr); + if (addr == nullptr) { + Rf_error("CUDD ADD pointer is NULL."); + } + return static_cast(addr); +} + +static ZDD *zdd_from_ptr(SEXP ptr) { + if (TYPEOF(ptr) != EXTPTRSXP) { + Rf_error("Expected an external pointer for a CUDD ZDD."); + } + void *addr = R_ExternalPtrAddr(ptr); + if (addr == nullptr) { + Rf_error("CUDD ZDD pointer is NULL."); + } + return static_cast(addr); +} + extern "C" SEXP c_cudd_new() { try { Cudd *mgr = new Cudd(); @@ -69,11 +138,79 @@ extern "C" SEXP c_cudd_read_min_hit(SEXP mgr_ptr) { return Rf_ScalarInteger(static_cast(mgr->ReadMinHit())); } +extern "C" SEXP c_cudd_set_min_hit(SEXP mgr_ptr, SEXP hr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + int value = Rf_asInteger(hr); + if (value == NA_INTEGER || value < 0) { + Rf_error("'hr' must be a non-negative integer."); + } + mgr->SetMinHit(static_cast(value)); + return R_NilValue; +} + extern "C" SEXP c_cudd_read_loose_up_to(SEXP mgr_ptr) { Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); return Rf_ScalarInteger(static_cast(mgr->ReadLooseUpTo())); } +extern "C" SEXP c_cudd_set_loose_up_to(SEXP mgr_ptr, SEXP lut) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + int value = Rf_asInteger(lut); + if (value == NA_INTEGER || value < 0) { + Rf_error("'lut' must be a non-negative integer."); + } + mgr->SetLooseUpTo(static_cast(value)); + return R_NilValue; +} + +extern "C" SEXP c_cudd_make_verbose(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + mgr->makeVerbose(); + return R_NilValue; +} + +extern "C" SEXP c_cudd_make_terse(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + mgr->makeTerse(); + return R_NilValue; +} + +extern "C" SEXP c_cudd_is_verbose(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return Rf_ScalarLogical(mgr->isVerbose()); +} + +extern "C" SEXP c_cudd_info(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + mgr->info(); + return R_NilValue; +} + +extern "C" SEXP c_cudd_push_variable_name(SEXP mgr_ptr, SEXP name) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + if (!Rf_isString(name) || Rf_length(name) != 1) { + Rf_error("'name' must be a single string."); + } + mgr->pushVariableName(CHAR(STRING_ELT(name, 0))); + return R_NilValue; +} + +extern "C" SEXP c_cudd_clear_variable_names(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + mgr->clearVariableNames(); + return R_NilValue; +} + +extern "C" SEXP c_cudd_get_variable_name(SEXP mgr_ptr, SEXP index) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + int idx = Rf_asInteger(index); + if (idx == NA_INTEGER || idx < 0) { + Rf_error("'index' must be a non-negative integer."); + } + std::string name = mgr->getVariableName(static_cast(idx)); + return Rf_mkString(name.c_str()); +} + extern "C" SEXP c_cudd_read_node_count(SEXP mgr_ptr) { Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); return Rf_ScalarReal(static_cast(mgr->ReadNodeCount())); @@ -88,3 +225,994 @@ extern "C" SEXP c_cudd_read_reorderings(SEXP mgr_ptr) { Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); return Rf_ScalarInteger(static_cast(mgr->ReadReorderings())); } + +extern "C" SEXP c_cudd_read_start_time(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return Rf_ScalarReal(static_cast(mgr->ReadStartTime())); +} + +extern "C" SEXP c_cudd_read_elapsed_time(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return Rf_ScalarReal(static_cast(mgr->ReadElapsedTime())); +} + +extern "C" SEXP c_cudd_set_start_time(SEXP mgr_ptr, SEXP st) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + if (!Rf_isNumeric(st) || Rf_length(st) != 1) { + Rf_error("'st' must be a single numeric value."); + } + unsigned long value = static_cast(Rf_asReal(st)); + mgr->SetStartTime(value); + return R_NilValue; +} + +extern "C" SEXP c_cudd_reset_start_time(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + mgr->ResetStartTime(); + return R_NilValue; +} + +extern "C" SEXP c_cudd_read_time_limit(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return Rf_ScalarReal(static_cast(mgr->ReadTimeLimit())); +} + +extern "C" SEXP c_cudd_set_time_limit(SEXP mgr_ptr, SEXP tl) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + if (!Rf_isNumeric(tl) || Rf_length(tl) != 1) { + Rf_error("'tl' must be a single numeric value."); + } + unsigned long value = static_cast(Rf_asReal(tl)); + unsigned long result = mgr->SetTimeLimit(value); + return Rf_ScalarReal(static_cast(result)); +} + +extern "C" SEXP c_cudd_update_time_limit(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + mgr->UpdateTimeLimit(); + return R_NilValue; +} + +extern "C" SEXP c_cudd_increase_time_limit(SEXP mgr_ptr, SEXP inc) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + if (!Rf_isNumeric(inc) || Rf_length(inc) != 1) { + Rf_error("'inc' must be a single numeric value."); + } + unsigned long value = static_cast(Rf_asReal(inc)); + mgr->IncreaseTimeLimit(value); + return R_NilValue; +} + +extern "C" SEXP c_cudd_unset_time_limit(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + mgr->UnsetTimeLimit(); + return R_NilValue; +} + +extern "C" SEXP c_cudd_time_limited(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return Rf_ScalarLogical(mgr->TimeLimited()); +} + +extern "C" SEXP c_cudd_autodyn_enable(SEXP mgr_ptr, SEXP method) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + if (Rf_isNull(method)) { + mgr->AutodynEnable(); + } else { + int value = Rf_asInteger(method); + if (value == NA_INTEGER) { + Rf_error("'method' must be a valid integer."); + } + mgr->AutodynEnable(static_cast(value)); + } + return R_NilValue; +} + +extern "C" SEXP c_cudd_autodyn_disable(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + mgr->AutodynDisable(); + return R_NilValue; +} + +extern "C" SEXP c_cudd_reordering_status(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + Cudd_ReorderingType method; + bool enabled = mgr->ReorderingStatus(&method); + SEXP out = PROTECT(Rf_allocVector(VECSXP, 2)); + SEXP names = PROTECT(Rf_allocVector(STRSXP, 2)); + SET_STRING_ELT(names, 0, Rf_mkChar("enabled")); + SET_STRING_ELT(names, 1, Rf_mkChar("method")); + Rf_setAttrib(out, R_NamesSymbol, names); + SET_VECTOR_ELT(out, 0, Rf_ScalarLogical(enabled)); + SET_VECTOR_ELT(out, 1, Rf_ScalarInteger(static_cast(method))); + UNPROTECT(2); + return out; +} + +extern "C" SEXP c_cudd_autodyn_enable_zdd(SEXP mgr_ptr, SEXP method) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + if (Rf_isNull(method)) { + mgr->AutodynEnableZdd(); + } else { + int value = Rf_asInteger(method); + if (value == NA_INTEGER) { + Rf_error("'method' must be a valid integer."); + } + mgr->AutodynEnableZdd(static_cast(value)); + } + return R_NilValue; +} + +extern "C" SEXP c_cudd_autodyn_disable_zdd(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + mgr->AutodynDisableZdd(); + return R_NilValue; +} + +extern "C" SEXP c_cudd_reordering_status_zdd(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + Cudd_ReorderingType method; + bool enabled = mgr->ReorderingStatusZdd(&method); + SEXP out = PROTECT(Rf_allocVector(VECSXP, 2)); + SEXP names = PROTECT(Rf_allocVector(STRSXP, 2)); + SET_STRING_ELT(names, 0, Rf_mkChar("enabled")); + SET_STRING_ELT(names, 1, Rf_mkChar("method")); + Rf_setAttrib(out, R_NamesSymbol, names); + SET_VECTOR_ELT(out, 0, Rf_ScalarLogical(enabled)); + SET_VECTOR_ELT(out, 1, Rf_ScalarInteger(static_cast(method))); + UNPROTECT(2); + return out; +} + +extern "C" SEXP c_cudd_zdd_realignment_enabled(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return Rf_ScalarLogical(mgr->zddRealignmentEnabled()); +} + +extern "C" SEXP c_cudd_zdd_realign_enable(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + mgr->zddRealignEnable(); + return R_NilValue; +} + +extern "C" SEXP c_cudd_zdd_realign_disable(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + mgr->zddRealignDisable(); + return R_NilValue; +} + +extern "C" SEXP c_cudd_bdd_realignment_enabled(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return Rf_ScalarLogical(mgr->bddRealignmentEnabled()); +} + +extern "C" SEXP c_cudd_bdd_realign_enable(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + mgr->bddRealignEnable(); + return R_NilValue; +} + +extern "C" SEXP c_cudd_bdd_realign_disable(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + mgr->bddRealignDisable(); + return R_NilValue; +} + +extern "C" SEXP c_cudd_background(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + ADD *add = new ADD(mgr->background()); + SEXP ptr = PROTECT(R_MakeExternalPtr(add, R_NilValue, mgr_ptr)); + R_RegisterCFinalizerEx(ptr, add_finalizer, TRUE); + UNPROTECT(1); + return ptr; +} + +extern "C" SEXP c_cudd_set_background(SEXP mgr_ptr, SEXP add_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + ADD *add = add_from_ptr(add_ptr); + mgr->SetBackground(*add); + return R_NilValue; +} + +extern "C" SEXP c_cudd_read_max_cache(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return Rf_ScalarInteger(static_cast(mgr->ReadMaxCache())); +} + +extern "C" SEXP c_cudd_read_max_cache_hard(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return Rf_ScalarInteger(static_cast(mgr->ReadMaxCacheHard())); +} + +extern "C" SEXP c_cudd_set_max_cache_hard(SEXP mgr_ptr, SEXP mc) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + int value = Rf_asInteger(mc); + if (value == NA_INTEGER || value < 0) { + Rf_error("'mc' must be a non-negative integer."); + } + mgr->SetMaxCacheHard(static_cast(value)); + return R_NilValue; +} + +extern "C" SEXP c_cudd_read_slots(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return Rf_ScalarInteger(static_cast(mgr->ReadSlots())); +} + +extern "C" SEXP c_cudd_read_keys(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return Rf_ScalarInteger(static_cast(mgr->ReadKeys())); +} + +extern "C" SEXP c_cudd_read_dead(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return Rf_ScalarInteger(static_cast(mgr->ReadDead())); +} + +extern "C" SEXP c_cudd_read_min_dead(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return Rf_ScalarInteger(static_cast(mgr->ReadMinDead())); +} + +extern "C" SEXP c_cudd_read_max_reorderings(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return Rf_ScalarInteger(static_cast(mgr->ReadMaxReorderings())); +} + +extern "C" SEXP c_cudd_set_max_reorderings(SEXP mgr_ptr, SEXP mr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + int value = Rf_asInteger(mr); + if (value == NA_INTEGER || value < 0) { + Rf_error("'mr' must be a non-negative integer."); + } + mgr->SetMaxReorderings(static_cast(value)); + return R_NilValue; +} + +extern "C" SEXP c_cudd_read_reordering_time(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return Rf_ScalarReal(static_cast(mgr->ReadReorderingTime())); +} + +extern "C" SEXP c_cudd_read_garbage_collections(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return Rf_ScalarInteger(mgr->ReadGarbageCollections()); +} + +extern "C" SEXP c_cudd_read_garbage_collection_time(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return Rf_ScalarReal(static_cast(mgr->ReadGarbageCollectionTime())); +} + +extern "C" SEXP c_cudd_read_sift_max_var(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return Rf_ScalarInteger(mgr->ReadSiftMaxVar()); +} + +extern "C" SEXP c_cudd_set_sift_max_var(SEXP mgr_ptr, SEXP smv) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + int value = Rf_asInteger(smv); + if (value == NA_INTEGER) { + Rf_error("'smv' must be a valid integer."); + } + mgr->SetSiftMaxVar(value); + return R_NilValue; +} + +extern "C" SEXP c_cudd_read_sift_max_swap(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return Rf_ScalarInteger(mgr->ReadSiftMaxSwap()); +} + +extern "C" SEXP c_cudd_set_sift_max_swap(SEXP mgr_ptr, SEXP sms) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + int value = Rf_asInteger(sms); + if (value == NA_INTEGER) { + Rf_error("'sms' must be a valid integer."); + } + mgr->SetSiftMaxSwap(value); + return R_NilValue; +} + +extern "C" SEXP c_cudd_read_max_growth(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return Rf_ScalarReal(mgr->ReadMaxGrowth()); +} + +extern "C" SEXP c_cudd_set_max_growth(SEXP mgr_ptr, SEXP mg) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + if (!Rf_isNumeric(mg) || Rf_length(mg) != 1) { + Rf_error("'mg' must be a single numeric value."); + } + mgr->SetMaxGrowth(Rf_asReal(mg)); + return R_NilValue; +} + +extern "C" SEXP c_cudd_read_perm(SEXP mgr_ptr, SEXP i) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + int idx = Rf_asInteger(i); + if (idx == NA_INTEGER) { + Rf_error("'i' must be a valid integer."); + } + return Rf_ScalarInteger(mgr->ReadPerm(idx)); +} + +extern "C" SEXP c_cudd_read_perm_zdd(SEXP mgr_ptr, SEXP i) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + int idx = Rf_asInteger(i); + if (idx == NA_INTEGER) { + Rf_error("'i' must be a valid integer."); + } + return Rf_ScalarInteger(mgr->ReadPermZdd(idx)); +} + +extern "C" SEXP c_cudd_read_inv_perm(SEXP mgr_ptr, SEXP i) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + int idx = Rf_asInteger(i); + if (idx == NA_INTEGER) { + Rf_error("'i' must be a valid integer."); + } + return Rf_ScalarInteger(mgr->ReadInvPerm(idx)); +} + +extern "C" SEXP c_cudd_read_inv_perm_zdd(SEXP mgr_ptr, SEXP i) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + int idx = Rf_asInteger(i); + if (idx == NA_INTEGER) { + Rf_error("'i' must be a valid integer."); + } + return Rf_ScalarInteger(mgr->ReadInvPermZdd(idx)); +} + +extern "C" SEXP c_cudd_read_vars(SEXP mgr_ptr, SEXP i) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + int idx = Rf_asInteger(i); + if (idx == NA_INTEGER) { + Rf_error("'i' must be a valid integer."); + } + BDD *bdd = new BDD(mgr->ReadVars(idx)); + SEXP ptr = PROTECT(R_MakeExternalPtr(bdd, R_NilValue, mgr_ptr)); + R_RegisterCFinalizerEx(ptr, bdd_finalizer, TRUE); + UNPROTECT(1); + return ptr; +} + +extern "C" SEXP c_cudd_read_epsilon(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return Rf_ScalarReal(mgr->ReadEpsilon()); +} + +extern "C" SEXP c_cudd_set_epsilon(SEXP mgr_ptr, SEXP ep) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + if (!Rf_isNumeric(ep) || Rf_length(ep) != 1) { + Rf_error("'ep' must be a single numeric value."); + } + mgr->SetEpsilon(Rf_asReal(ep)); + return R_NilValue; +} + +extern "C" SEXP c_cudd_read_groupcheck(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return Rf_ScalarInteger(static_cast(mgr->ReadGroupcheck())); +} + +extern "C" SEXP c_cudd_set_groupcheck(SEXP mgr_ptr, SEXP gc) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + int value = Rf_asInteger(gc); + if (value == NA_INTEGER) { + Rf_error("'gc' must be a valid integer."); + } + mgr->SetGroupcheck(static_cast(value)); + return R_NilValue; +} + +extern "C" SEXP c_cudd_garbage_collection_enabled(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return Rf_ScalarLogical(mgr->GarbageCollectionEnabled()); +} + +extern "C" SEXP c_cudd_enable_garbage_collection(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + mgr->EnableGarbageCollection(); + return R_NilValue; +} + +extern "C" SEXP c_cudd_disable_garbage_collection(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + mgr->DisableGarbageCollection(); + return R_NilValue; +} + +extern "C" SEXP c_cudd_dead_are_counted(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return Rf_ScalarLogical(mgr->DeadAreCounted()); +} + +extern "C" SEXP c_cudd_turn_on_count_dead(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + mgr->TurnOnCountDead(); + return R_NilValue; +} + +extern "C" SEXP c_cudd_turn_off_count_dead(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + mgr->TurnOffCountDead(); + return R_NilValue; +} + +extern "C" SEXP c_cudd_read_recomb(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return Rf_ScalarInteger(mgr->ReadRecomb()); +} + +extern "C" SEXP c_cudd_set_recomb(SEXP mgr_ptr, SEXP recomb) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + int value = Rf_asInteger(recomb); + if (value == NA_INTEGER) { + Rf_error("'recomb' must be a valid integer."); + } + mgr->SetRecomb(value); + return R_NilValue; +} + +extern "C" SEXP c_cudd_read_symmviolation(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return Rf_ScalarInteger(mgr->ReadSymmviolation()); +} + +extern "C" SEXP c_cudd_set_symmviolation(SEXP mgr_ptr, SEXP symm) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + int value = Rf_asInteger(symm); + if (value == NA_INTEGER) { + Rf_error("'symm' must be a valid integer."); + } + mgr->SetSymmviolation(value); + return R_NilValue; +} + +extern "C" SEXP c_cudd_read_arcviolation(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return Rf_ScalarInteger(mgr->ReadArcviolation()); +} + +extern "C" SEXP c_cudd_set_arcviolation(SEXP mgr_ptr, SEXP arc) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + int value = Rf_asInteger(arc); + if (value == NA_INTEGER) { + Rf_error("'arc' must be a valid integer."); + } + mgr->SetArcviolation(value); + return R_NilValue; +} + +extern "C" SEXP c_cudd_read_population_size(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return Rf_ScalarInteger(mgr->ReadPopulationSize()); +} + +extern "C" SEXP c_cudd_set_population_size(SEXP mgr_ptr, SEXP pop) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + int value = Rf_asInteger(pop); + if (value == NA_INTEGER) { + Rf_error("'pop' must be a valid integer."); + } + mgr->SetPopulationSize(value); + return R_NilValue; +} + +extern "C" SEXP c_cudd_read_number_xovers(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return Rf_ScalarInteger(mgr->ReadNumberXovers()); +} + +extern "C" SEXP c_cudd_set_number_xovers(SEXP mgr_ptr, SEXP xovers) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + int value = Rf_asInteger(xovers); + if (value == NA_INTEGER) { + Rf_error("'xovers' must be a valid integer."); + } + mgr->SetNumberXovers(value); + return R_NilValue; +} + +extern "C" SEXP c_cudd_read_order_randomization(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return Rf_ScalarInteger(static_cast(mgr->ReadOrderRandomization())); +} + +extern "C" SEXP c_cudd_set_order_randomization(SEXP mgr_ptr, SEXP factor) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + int value = Rf_asInteger(factor); + if (value == NA_INTEGER) { + Rf_error("'factor' must be a valid integer."); + } + mgr->SetOrderRandomization(static_cast(value)); + return R_NilValue; +} + +extern "C" SEXP c_cudd_read_memory_in_use(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return Rf_ScalarReal(static_cast(mgr->ReadMemoryInUse())); +} + +extern "C" SEXP c_cudd_read_peak_node_count(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return Rf_ScalarReal(static_cast(mgr->ReadPeakNodeCount())); +} + +extern "C" SEXP c_cudd_read_node_count_current(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return Rf_ScalarReal(static_cast(mgr->ReadNodeCount())); +} + +extern "C" SEXP c_cudd_read_node_count_zdd(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return Rf_ScalarReal(static_cast(mgr->zddReadNodeCount())); +} + +extern "C" SEXP c_cudd_enable_reordering_reporting(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + mgr->EnableReorderingReporting(); + return R_NilValue; +} + +extern "C" SEXP c_cudd_disable_reordering_reporting(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + mgr->DisableReorderingReporting(); + return R_NilValue; +} + +extern "C" SEXP c_cudd_reordering_reporting(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return Rf_ScalarLogical(mgr->ReorderingReporting()); +} + +extern "C" SEXP c_cudd_read_error_code(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return Rf_ScalarInteger(mgr->ReadErrorCode()); +} + +extern "C" SEXP c_cudd_clear_error_code(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + mgr->ClearErrorCode(); + return R_NilValue; +} + +extern "C" SEXP c_cudd_read_next_reordering(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return Rf_ScalarInteger(static_cast(mgr->ReadNextReordering())); +} + +extern "C" SEXP c_cudd_set_next_reordering(SEXP mgr_ptr, SEXP nr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + int value = Rf_asInteger(nr); + if (value == NA_INTEGER) { + Rf_error("'nr' must be a valid integer."); + } + mgr->SetNextReordering(static_cast(value)); + return R_NilValue; +} + +extern "C" SEXP c_cudd_read_swap_steps(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return Rf_ScalarReal(mgr->ReadSwapSteps()); +} + +extern "C" SEXP c_cudd_read_max_live(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return Rf_ScalarInteger(static_cast(mgr->ReadMaxLive())); +} + +extern "C" SEXP c_cudd_set_max_live(SEXP mgr_ptr, SEXP max_live) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + int value = Rf_asInteger(max_live); + if (value == NA_INTEGER) { + Rf_error("'max_live' must be a valid integer."); + } + mgr->SetMaxLive(static_cast(value)); + return R_NilValue; +} + +extern "C" SEXP c_cudd_read_max_memory(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return Rf_ScalarReal(static_cast(mgr->ReadMaxMemory())); +} + +extern "C" SEXP c_cudd_set_max_memory(SEXP mgr_ptr, SEXP max_mem) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + if (!Rf_isNumeric(max_mem) || Rf_length(max_mem) != 1) { + Rf_error("'max_mem' must be a single numeric value."); + } + size_t value = static_cast(Rf_asReal(max_mem)); + size_t result = mgr->SetMaxMemory(value); + return Rf_ScalarReal(static_cast(result)); +} + +extern "C" SEXP c_cudd_bdd_bind_var(SEXP mgr_ptr, SEXP index) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + int idx = Rf_asInteger(index); + if (idx == NA_INTEGER) { + Rf_error("'index' must be a valid integer."); + } + int result = mgr->bddBindVar(idx); + return Rf_ScalarInteger(result); +} + +extern "C" SEXP c_cudd_bdd_unbind_var(SEXP mgr_ptr, SEXP index) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + int idx = Rf_asInteger(index); + if (idx == NA_INTEGER) { + Rf_error("'index' must be a valid integer."); + } + int result = mgr->bddUnbindVar(idx); + return Rf_ScalarInteger(result); +} + +extern "C" SEXP c_cudd_bdd_var_is_bound(SEXP mgr_ptr, SEXP index) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + int idx = Rf_asInteger(index); + if (idx == NA_INTEGER) { + Rf_error("'index' must be a valid integer."); + } + return Rf_ScalarLogical(mgr->bddVarIsBound(idx)); +} + +extern "C" SEXP c_cudd_bdd_one(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + BDD *bdd = new BDD(mgr->bddOne()); + SEXP ptr = PROTECT(R_MakeExternalPtr(bdd, R_NilValue, mgr_ptr)); + R_RegisterCFinalizerEx(ptr, bdd_finalizer, TRUE); + UNPROTECT(1); + return ptr; +} + +extern "C" SEXP c_cudd_bdd_zero(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + BDD *bdd = new BDD(mgr->bddZero()); + SEXP ptr = PROTECT(R_MakeExternalPtr(bdd, R_NilValue, mgr_ptr)); + R_RegisterCFinalizerEx(ptr, bdd_finalizer, TRUE); + UNPROTECT(1); + return ptr; +} + +extern "C" SEXP c_cudd_bdd_var(SEXP mgr_ptr, SEXP index) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + BDD *bdd = nullptr; + + if (Rf_isNull(index)) { + bdd = new BDD(mgr->bddVar()); + } else { + if (!Rf_isNumeric(index) || Rf_length(index) != 1) { + Rf_error("'index' must be a single numeric value."); + } + int idx = Rf_asInteger(index); + if (idx == NA_INTEGER || idx < 0) { + Rf_error("'index' must be a non-negative integer."); + } + bdd = new BDD(mgr->bddVar(idx)); + } + + SEXP ptr = PROTECT(R_MakeExternalPtr(bdd, R_NilValue, mgr_ptr)); + R_RegisterCFinalizerEx(ptr, bdd_finalizer, TRUE); + UNPROTECT(1); + return ptr; +} + +extern "C" SEXP c_cudd_add_one(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + ADD *add = new ADD(mgr->addOne()); + SEXP ptr = PROTECT(R_MakeExternalPtr(add, R_NilValue, mgr_ptr)); + R_RegisterCFinalizerEx(ptr, add_finalizer, TRUE); + UNPROTECT(1); + return ptr; +} + +extern "C" SEXP c_cudd_add_zero(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + ADD *add = new ADD(mgr->addZero()); + SEXP ptr = PROTECT(R_MakeExternalPtr(add, R_NilValue, mgr_ptr)); + R_RegisterCFinalizerEx(ptr, add_finalizer, TRUE); + UNPROTECT(1); + return ptr; +} + +extern "C" SEXP c_cudd_add_var(SEXP mgr_ptr, SEXP index) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + ADD *add = nullptr; + + if (Rf_isNull(index)) { + add = new ADD(mgr->addVar()); + } else { + if (!Rf_isNumeric(index) || Rf_length(index) != 1) { + Rf_error("'index' must be a single numeric value."); + } + int idx = Rf_asInteger(index); + if (idx == NA_INTEGER || idx < 0) { + Rf_error("'index' must be a non-negative integer."); + } + add = new ADD(mgr->addVar(idx)); + } + + SEXP ptr = PROTECT(R_MakeExternalPtr(add, R_NilValue, mgr_ptr)); + R_RegisterCFinalizerEx(ptr, add_finalizer, TRUE); + UNPROTECT(1); + return ptr; +} + +extern "C" SEXP c_cudd_zdd_one(SEXP mgr_ptr, SEXP index) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + if (!Rf_isNumeric(index) || Rf_length(index) != 1) { + Rf_error("'index' must be a single numeric value."); + } + int idx = Rf_asInteger(index); + if (idx == NA_INTEGER || idx < 0) { + Rf_error("'index' must be a non-negative integer."); + } + ZDD *zdd = new ZDD(mgr->zddOne(idx)); + SEXP ptr = PROTECT(R_MakeExternalPtr(zdd, R_NilValue, mgr_ptr)); + R_RegisterCFinalizerEx(ptr, zdd_finalizer, TRUE); + UNPROTECT(1); + return ptr; +} + +extern "C" SEXP c_cudd_zdd_zero(SEXP mgr_ptr) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + ZDD *zdd = new ZDD(mgr->zddZero()); + SEXP ptr = PROTECT(R_MakeExternalPtr(zdd, R_NilValue, mgr_ptr)); + R_RegisterCFinalizerEx(ptr, zdd_finalizer, TRUE); + UNPROTECT(1); + return ptr; +} + +extern "C" SEXP c_cudd_zdd_var(SEXP mgr_ptr, SEXP index) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + int idx; + if (Rf_isNull(index)) { + idx = mgr->ReadZddSize(); + } else { + if (!Rf_isNumeric(index) || Rf_length(index) != 1) { + Rf_error("'index' must be a single numeric value."); + } + idx = Rf_asInteger(index); + if (idx == NA_INTEGER || idx < 0) { + Rf_error("'index' must be a non-negative integer."); + } + } + + ZDD *zdd = new ZDD(mgr->zddVar(idx)); + SEXP ptr = PROTECT(R_MakeExternalPtr(zdd, R_NilValue, mgr_ptr)); + R_RegisterCFinalizerEx(ptr, zdd_finalizer, TRUE); + UNPROTECT(1); + return ptr; +} + +extern "C" SEXP c_cudd_bdd_not(SEXP bdd_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + BDD *result = new BDD(!(*bdd)); + SEXP ptr = PROTECT(R_MakeExternalPtr(result, R_NilValue, R_NilValue)); + R_RegisterCFinalizerEx(ptr, bdd_finalizer, TRUE); + UNPROTECT(1); + return ptr; +} + +extern "C" SEXP c_cudd_bdd_and(SEXP lhs_ptr, SEXP rhs_ptr) { + BDD *lhs = bdd_from_ptr(lhs_ptr); + BDD *rhs = bdd_from_ptr(rhs_ptr); + BDD *result = new BDD((*lhs) * (*rhs)); + SEXP ptr = PROTECT(R_MakeExternalPtr(result, R_NilValue, R_NilValue)); + R_RegisterCFinalizerEx(ptr, bdd_finalizer, TRUE); + UNPROTECT(1); + return ptr; +} + +extern "C" SEXP c_cudd_bdd_or(SEXP lhs_ptr, SEXP rhs_ptr) { + BDD *lhs = bdd_from_ptr(lhs_ptr); + BDD *rhs = bdd_from_ptr(rhs_ptr); + BDD *result = new BDD((*lhs) + (*rhs)); + SEXP ptr = PROTECT(R_MakeExternalPtr(result, R_NilValue, R_NilValue)); + R_RegisterCFinalizerEx(ptr, bdd_finalizer, TRUE); + UNPROTECT(1); + return ptr; +} + +extern "C" SEXP c_cudd_bdd_xor(SEXP lhs_ptr, SEXP rhs_ptr) { + BDD *lhs = bdd_from_ptr(lhs_ptr); + BDD *rhs = bdd_from_ptr(rhs_ptr); + BDD *result = new BDD((*lhs) ^ (*rhs)); + SEXP ptr = PROTECT(R_MakeExternalPtr(result, R_NilValue, R_NilValue)); + R_RegisterCFinalizerEx(ptr, bdd_finalizer, TRUE); + UNPROTECT(1); + return ptr; +} + +extern "C" SEXP c_cudd_add_times(SEXP lhs_ptr, SEXP rhs_ptr) { + ADD *lhs = add_from_ptr(lhs_ptr); + ADD *rhs = add_from_ptr(rhs_ptr); + ADD *result = new ADD((*lhs) * (*rhs)); + SEXP ptr = PROTECT(R_MakeExternalPtr(result, R_NilValue, R_NilValue)); + R_RegisterCFinalizerEx(ptr, add_finalizer, TRUE); + UNPROTECT(1); + return ptr; +} + +extern "C" SEXP c_cudd_add_plus(SEXP lhs_ptr, SEXP rhs_ptr) { + ADD *lhs = add_from_ptr(lhs_ptr); + ADD *rhs = add_from_ptr(rhs_ptr); + ADD *result = new ADD((*lhs) + (*rhs)); + SEXP ptr = PROTECT(R_MakeExternalPtr(result, R_NilValue, R_NilValue)); + R_RegisterCFinalizerEx(ptr, add_finalizer, TRUE); + UNPROTECT(1); + return ptr; +} + +extern "C" SEXP c_cudd_zdd_intersect(SEXP lhs_ptr, SEXP rhs_ptr) { + ZDD *lhs = zdd_from_ptr(lhs_ptr); + ZDD *rhs = zdd_from_ptr(rhs_ptr); + ZDD *result = new ZDD((*lhs) * (*rhs)); + SEXP ptr = PROTECT(R_MakeExternalPtr(result, R_NilValue, R_NilValue)); + R_RegisterCFinalizerEx(ptr, zdd_finalizer, TRUE); + UNPROTECT(1); + return ptr; +} + +extern "C" SEXP c_cudd_zdd_union(SEXP lhs_ptr, SEXP rhs_ptr) { + ZDD *lhs = zdd_from_ptr(lhs_ptr); + ZDD *rhs = zdd_from_ptr(rhs_ptr); + ZDD *result = new ZDD((*lhs) + (*rhs)); + SEXP ptr = PROTECT(R_MakeExternalPtr(result, R_NilValue, R_NilValue)); + R_RegisterCFinalizerEx(ptr, zdd_finalizer, TRUE); + UNPROTECT(1); + return ptr; +} + +extern "C" SEXP c_cudd_bdd_to_add(SEXP bdd_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + ADD *result = new ADD(bdd->Add()); + SEXP ptr = PROTECT(R_MakeExternalPtr(result, R_NilValue, R_NilValue)); + R_RegisterCFinalizerEx(ptr, add_finalizer, TRUE); + UNPROTECT(1); + return ptr; +} + +extern "C" SEXP c_cudd_add_to_bdd(SEXP add_ptr) { + ADD *add = add_from_ptr(add_ptr); + BDD *result = new BDD(add->BddPattern()); + SEXP ptr = PROTECT(R_MakeExternalPtr(result, R_NilValue, R_NilValue)); + R_RegisterCFinalizerEx(ptr, bdd_finalizer, TRUE); + UNPROTECT(1); + return ptr; +} + +extern "C" SEXP c_cudd_bdd_to_zdd(SEXP bdd_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + ZDD *result = new ZDD(bdd->PortToZdd()); + SEXP ptr = PROTECT(R_MakeExternalPtr(result, R_NilValue, R_NilValue)); + R_RegisterCFinalizerEx(ptr, zdd_finalizer, TRUE); + UNPROTECT(1); + return ptr; +} + +extern "C" SEXP c_cudd_zdd_to_bdd(SEXP zdd_ptr) { + ZDD *zdd = zdd_from_ptr(zdd_ptr); + BDD *result = new BDD(zdd->PortToBdd()); + SEXP ptr = PROTECT(R_MakeExternalPtr(result, R_NilValue, R_NilValue)); + R_RegisterCFinalizerEx(ptr, bdd_finalizer, TRUE); + UNPROTECT(1); + return ptr; +} + +extern "C" SEXP c_cudd_bdd_epd_print_minterm(SEXP bdd_ptr, SEXP nvars) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + if (!Rf_isNumeric(nvars) || Rf_length(nvars) != 1) { + Rf_error("'nvars' must be a single numeric value."); + } + int vars = Rf_asInteger(nvars); + if (vars == NA_INTEGER || vars < 0) { + Rf_error("'nvars' must be a non-negative integer."); + } + bdd->EpdPrintMinterm(vars, nullptr); + return R_NilValue; +} + +extern "C" SEXP c_cudd_add_epd_print_minterm(SEXP add_ptr, SEXP nvars) { + ADD *add = add_from_ptr(add_ptr); + if (!Rf_isNumeric(nvars) || Rf_length(nvars) != 1) { + Rf_error("'nvars' must be a single numeric value."); + } + int vars = Rf_asInteger(nvars); + if (vars == NA_INTEGER || vars < 0) { + Rf_error("'nvars' must be a non-negative integer."); + } + add->EpdPrintMinterm(vars, nullptr); + return R_NilValue; +} + +extern "C" SEXP c_cudd_bdd_print_minterm(SEXP bdd_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + bdd->PrintMinterm(); + return R_NilValue; +} + +extern "C" SEXP c_cudd_add_print_minterm(SEXP add_ptr) { + ADD *add = add_from_ptr(add_ptr); + add->PrintMinterm(); + return R_NilValue; +} + +extern "C" SEXP c_cudd_zdd_print_minterm(SEXP zdd_ptr) { + ZDD *zdd = zdd_from_ptr(zdd_ptr); + zdd->PrintMinterm(); + return R_NilValue; +} + +extern "C" SEXP c_cudd_bdd_print_debug(SEXP bdd_ptr, SEXP nvars, SEXP verbosity) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + int vars; + if (Rf_isNull(nvars)) { + vars = Cudd_ReadSize(bdd->manager()); + } else { + if (!Rf_isNumeric(nvars) || Rf_length(nvars) != 1) { + Rf_error("'nvars' must be a single numeric value."); + } + vars = Rf_asInteger(nvars); + if (vars == NA_INTEGER || vars < 0) { + Rf_error("'nvars' must be a non-negative integer."); + } + } + + int verb = 2; + if (!Rf_isNull(verbosity)) { + if (!Rf_isNumeric(verbosity) || Rf_length(verbosity) != 1) { + Rf_error("'verbosity' must be a single numeric value."); + } + verb = Rf_asInteger(verbosity); + if (verb == NA_INTEGER || verb < 0) { + Rf_error("'verbosity' must be a non-negative integer."); + } + } + + Cudd_PrintDebug(bdd->manager(), bdd->getNode(), vars, verb); + return R_NilValue; +} + +extern "C" SEXP c_cudd_bdd_dump_dot(SEXP bdd_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + FILE *fp = tmpfile(); + if (fp == nullptr) { + Rf_error("Failed to create temporary file for DOT output."); + } + + DdManager *mgr = bdd->manager(); + DdNode *node = bdd->getNode(); + DdNode *nodes[1] = { node }; + int result = Cudd_DumpDot(mgr, 1, nodes, nullptr, nullptr, fp); + if (result != 1) { + fclose(fp); + Rf_error("Failed to dump DOT representation."); + } + + if (fseek(fp, 0, SEEK_END) != 0) { + fclose(fp); + Rf_error("Failed to seek DOT output."); + } + long size = ftell(fp); + if (size < 0) { + fclose(fp); + Rf_error("Failed to read DOT output size."); + } + if (fseek(fp, 0, SEEK_SET) != 0) { + fclose(fp); + Rf_error("Failed to rewind DOT output."); + } + + std::string buffer(static_cast(size), '\0'); + size_t read_bytes = fread(buffer.data(), 1, buffer.size(), fp); + fclose(fp); + + buffer.resize(read_bytes); + + SEXP out = PROTECT(Rf_allocVector(STRSXP, 1)); + SET_STRING_ELT(out, 0, Rf_mkCharLen(buffer.data(), static_cast(buffer.size()))); + UNPROTECT(1); + return out; +} diff --git a/src/rcudd.h b/src/rcudd.h index 7dcd106..0c8f6a3 100644 --- a/src/rcudd.h +++ b/src/rcudd.h @@ -16,10 +16,135 @@ extern "C" SEXP c_cudd_read_cache_used_slots(SEXP mgr_ptr); extern "C" SEXP c_cudd_read_cache_lookups(SEXP mgr_ptr); extern "C" SEXP c_cudd_read_cache_hits(SEXP mgr_ptr); extern "C" SEXP c_cudd_read_min_hit(SEXP mgr_ptr); +extern "C" SEXP c_cudd_set_min_hit(SEXP mgr_ptr, SEXP hr); extern "C" SEXP c_cudd_read_loose_up_to(SEXP mgr_ptr); +extern "C" SEXP c_cudd_set_loose_up_to(SEXP mgr_ptr, SEXP lut); +extern "C" SEXP c_cudd_make_verbose(SEXP mgr_ptr); +extern "C" SEXP c_cudd_make_terse(SEXP mgr_ptr); +extern "C" SEXP c_cudd_is_verbose(SEXP mgr_ptr); +extern "C" SEXP c_cudd_info(SEXP mgr_ptr); +extern "C" SEXP c_cudd_push_variable_name(SEXP mgr_ptr, SEXP name); +extern "C" SEXP c_cudd_clear_variable_names(SEXP mgr_ptr); +extern "C" SEXP c_cudd_get_variable_name(SEXP mgr_ptr, SEXP index); extern "C" SEXP c_cudd_read_node_count(SEXP mgr_ptr); extern "C" SEXP c_cudd_read_zdd_size(SEXP mgr_ptr); extern "C" SEXP c_cudd_read_reorderings(SEXP mgr_ptr); +extern "C" SEXP c_cudd_bdd_one(SEXP mgr_ptr); +extern "C" SEXP c_cudd_bdd_zero(SEXP mgr_ptr); +extern "C" SEXP c_cudd_bdd_var(SEXP mgr_ptr, SEXP index); +extern "C" SEXP c_cudd_add_one(SEXP mgr_ptr); +extern "C" SEXP c_cudd_add_zero(SEXP mgr_ptr); +extern "C" SEXP c_cudd_add_var(SEXP mgr_ptr, SEXP index); +extern "C" SEXP c_cudd_zdd_one(SEXP mgr_ptr, SEXP index); +extern "C" SEXP c_cudd_zdd_zero(SEXP mgr_ptr); +extern "C" SEXP c_cudd_zdd_var(SEXP mgr_ptr, SEXP index); +extern "C" SEXP c_cudd_bdd_not(SEXP bdd_ptr); +extern "C" SEXP c_cudd_bdd_and(SEXP lhs_ptr, SEXP rhs_ptr); +extern "C" SEXP c_cudd_bdd_or(SEXP lhs_ptr, SEXP rhs_ptr); +extern "C" SEXP c_cudd_bdd_xor(SEXP lhs_ptr, SEXP rhs_ptr); +extern "C" SEXP c_cudd_add_times(SEXP lhs_ptr, SEXP rhs_ptr); +extern "C" SEXP c_cudd_add_plus(SEXP lhs_ptr, SEXP rhs_ptr); +extern "C" SEXP c_cudd_zdd_intersect(SEXP lhs_ptr, SEXP rhs_ptr); +extern "C" SEXP c_cudd_zdd_union(SEXP lhs_ptr, SEXP rhs_ptr); +extern "C" SEXP c_cudd_bdd_to_add(SEXP bdd_ptr); +extern "C" SEXP c_cudd_add_to_bdd(SEXP add_ptr); +extern "C" SEXP c_cudd_bdd_to_zdd(SEXP bdd_ptr); +extern "C" SEXP c_cudd_zdd_to_bdd(SEXP zdd_ptr); +extern "C" SEXP c_cudd_bdd_epd_print_minterm(SEXP bdd_ptr, SEXP nvars); +extern "C" SEXP c_cudd_add_epd_print_minterm(SEXP add_ptr, SEXP nvars); +extern "C" SEXP c_cudd_bdd_print_minterm(SEXP bdd_ptr); +extern "C" SEXP c_cudd_add_print_minterm(SEXP add_ptr); +extern "C" SEXP c_cudd_zdd_print_minterm(SEXP zdd_ptr); +extern "C" SEXP c_cudd_bdd_print_debug(SEXP bdd_ptr, SEXP nvars, SEXP verbosity); +extern "C" SEXP c_cudd_bdd_dump_dot(SEXP bdd_ptr); +extern "C" SEXP c_cudd_read_start_time(SEXP mgr_ptr); +extern "C" SEXP c_cudd_read_elapsed_time(SEXP mgr_ptr); +extern "C" SEXP c_cudd_set_start_time(SEXP mgr_ptr, SEXP st); +extern "C" SEXP c_cudd_reset_start_time(SEXP mgr_ptr); +extern "C" SEXP c_cudd_read_time_limit(SEXP mgr_ptr); +extern "C" SEXP c_cudd_set_time_limit(SEXP mgr_ptr, SEXP tl); +extern "C" SEXP c_cudd_update_time_limit(SEXP mgr_ptr); +extern "C" SEXP c_cudd_increase_time_limit(SEXP mgr_ptr, SEXP inc); +extern "C" SEXP c_cudd_unset_time_limit(SEXP mgr_ptr); +extern "C" SEXP c_cudd_time_limited(SEXP mgr_ptr); +extern "C" SEXP c_cudd_autodyn_enable(SEXP mgr_ptr, SEXP method); +extern "C" SEXP c_cudd_autodyn_disable(SEXP mgr_ptr); +extern "C" SEXP c_cudd_reordering_status(SEXP mgr_ptr); +extern "C" SEXP c_cudd_autodyn_enable_zdd(SEXP mgr_ptr, SEXP method); +extern "C" SEXP c_cudd_autodyn_disable_zdd(SEXP mgr_ptr); +extern "C" SEXP c_cudd_reordering_status_zdd(SEXP mgr_ptr); +extern "C" SEXP c_cudd_zdd_realignment_enabled(SEXP mgr_ptr); +extern "C" SEXP c_cudd_zdd_realign_enable(SEXP mgr_ptr); +extern "C" SEXP c_cudd_zdd_realign_disable(SEXP mgr_ptr); +extern "C" SEXP c_cudd_bdd_realignment_enabled(SEXP mgr_ptr); +extern "C" SEXP c_cudd_bdd_realign_enable(SEXP mgr_ptr); +extern "C" SEXP c_cudd_bdd_realign_disable(SEXP mgr_ptr); +extern "C" SEXP c_cudd_background(SEXP mgr_ptr); +extern "C" SEXP c_cudd_set_background(SEXP mgr_ptr, SEXP add_ptr); +extern "C" SEXP c_cudd_read_max_cache(SEXP mgr_ptr); +extern "C" SEXP c_cudd_read_max_cache_hard(SEXP mgr_ptr); +extern "C" SEXP c_cudd_set_max_cache_hard(SEXP mgr_ptr, SEXP mc); +extern "C" SEXP c_cudd_read_slots(SEXP mgr_ptr); +extern "C" SEXP c_cudd_read_keys(SEXP mgr_ptr); +extern "C" SEXP c_cudd_read_dead(SEXP mgr_ptr); +extern "C" SEXP c_cudd_read_min_dead(SEXP mgr_ptr); +extern "C" SEXP c_cudd_read_max_reorderings(SEXP mgr_ptr); +extern "C" SEXP c_cudd_set_max_reorderings(SEXP mgr_ptr, SEXP mr); +extern "C" SEXP c_cudd_read_reordering_time(SEXP mgr_ptr); +extern "C" SEXP c_cudd_read_garbage_collections(SEXP mgr_ptr); +extern "C" SEXP c_cudd_read_garbage_collection_time(SEXP mgr_ptr); +extern "C" SEXP c_cudd_read_sift_max_var(SEXP mgr_ptr); +extern "C" SEXP c_cudd_set_sift_max_var(SEXP mgr_ptr, SEXP smv); +extern "C" SEXP c_cudd_read_sift_max_swap(SEXP mgr_ptr); +extern "C" SEXP c_cudd_set_sift_max_swap(SEXP mgr_ptr, SEXP sms); +extern "C" SEXP c_cudd_read_max_growth(SEXP mgr_ptr); +extern "C" SEXP c_cudd_set_max_growth(SEXP mgr_ptr, SEXP mg); +extern "C" SEXP c_cudd_read_perm(SEXP mgr_ptr, SEXP i); +extern "C" SEXP c_cudd_read_perm_zdd(SEXP mgr_ptr, SEXP i); +extern "C" SEXP c_cudd_read_inv_perm(SEXP mgr_ptr, SEXP i); +extern "C" SEXP c_cudd_read_inv_perm_zdd(SEXP mgr_ptr, SEXP i); +extern "C" SEXP c_cudd_read_vars(SEXP mgr_ptr, SEXP i); +extern "C" SEXP c_cudd_read_epsilon(SEXP mgr_ptr); +extern "C" SEXP c_cudd_set_epsilon(SEXP mgr_ptr, SEXP ep); +extern "C" SEXP c_cudd_read_groupcheck(SEXP mgr_ptr); +extern "C" SEXP c_cudd_set_groupcheck(SEXP mgr_ptr, SEXP gc); +extern "C" SEXP c_cudd_garbage_collection_enabled(SEXP mgr_ptr); +extern "C" SEXP c_cudd_enable_garbage_collection(SEXP mgr_ptr); +extern "C" SEXP c_cudd_disable_garbage_collection(SEXP mgr_ptr); +extern "C" SEXP c_cudd_dead_are_counted(SEXP mgr_ptr); +extern "C" SEXP c_cudd_turn_on_count_dead(SEXP mgr_ptr); +extern "C" SEXP c_cudd_turn_off_count_dead(SEXP mgr_ptr); +extern "C" SEXP c_cudd_read_recomb(SEXP mgr_ptr); +extern "C" SEXP c_cudd_set_recomb(SEXP mgr_ptr, SEXP recomb); +extern "C" SEXP c_cudd_read_symmviolation(SEXP mgr_ptr); +extern "C" SEXP c_cudd_set_symmviolation(SEXP mgr_ptr, SEXP symm); +extern "C" SEXP c_cudd_read_arcviolation(SEXP mgr_ptr); +extern "C" SEXP c_cudd_set_arcviolation(SEXP mgr_ptr, SEXP arc); +extern "C" SEXP c_cudd_read_population_size(SEXP mgr_ptr); +extern "C" SEXP c_cudd_set_population_size(SEXP mgr_ptr, SEXP pop); +extern "C" SEXP c_cudd_read_number_xovers(SEXP mgr_ptr); +extern "C" SEXP c_cudd_set_number_xovers(SEXP mgr_ptr, SEXP xovers); +extern "C" SEXP c_cudd_read_order_randomization(SEXP mgr_ptr); +extern "C" SEXP c_cudd_set_order_randomization(SEXP mgr_ptr, SEXP factor); +extern "C" SEXP c_cudd_read_memory_in_use(SEXP mgr_ptr); +extern "C" SEXP c_cudd_read_peak_node_count(SEXP mgr_ptr); +extern "C" SEXP c_cudd_read_node_count_current(SEXP mgr_ptr); +extern "C" SEXP c_cudd_read_node_count_zdd(SEXP mgr_ptr); +extern "C" SEXP c_cudd_enable_reordering_reporting(SEXP mgr_ptr); +extern "C" SEXP c_cudd_disable_reordering_reporting(SEXP mgr_ptr); +extern "C" SEXP c_cudd_reordering_reporting(SEXP mgr_ptr); +extern "C" SEXP c_cudd_read_error_code(SEXP mgr_ptr); +extern "C" SEXP c_cudd_clear_error_code(SEXP mgr_ptr); +extern "C" SEXP c_cudd_read_next_reordering(SEXP mgr_ptr); +extern "C" SEXP c_cudd_set_next_reordering(SEXP mgr_ptr, SEXP nr); +extern "C" SEXP c_cudd_read_swap_steps(SEXP mgr_ptr); +extern "C" SEXP c_cudd_read_max_live(SEXP mgr_ptr); +extern "C" SEXP c_cudd_set_max_live(SEXP mgr_ptr, SEXP max_live); +extern "C" SEXP c_cudd_read_max_memory(SEXP mgr_ptr); +extern "C" SEXP c_cudd_set_max_memory(SEXP mgr_ptr, SEXP max_mem); +extern "C" SEXP c_cudd_bdd_bind_var(SEXP mgr_ptr, SEXP index); +extern "C" SEXP c_cudd_bdd_unbind_var(SEXP mgr_ptr, SEXP index); +extern "C" SEXP c_cudd_bdd_var_is_bound(SEXP mgr_ptr, SEXP index); #ifdef __cplusplus #include diff --git a/src/register.cpp b/src/register.cpp index f392fda..49a99ef 100644 --- a/src/register.cpp +++ b/src/register.cpp @@ -13,10 +13,135 @@ static const R_CallMethodDef CallEntries[] = { {"c_cudd_read_cache_lookups", (DL_FUNC) &c_cudd_read_cache_lookups, 1}, {"c_cudd_read_cache_hits", (DL_FUNC) &c_cudd_read_cache_hits, 1}, {"c_cudd_read_min_hit", (DL_FUNC) &c_cudd_read_min_hit, 1}, + {"c_cudd_set_min_hit", (DL_FUNC) &c_cudd_set_min_hit, 2}, {"c_cudd_read_loose_up_to", (DL_FUNC) &c_cudd_read_loose_up_to, 1}, + {"c_cudd_set_loose_up_to", (DL_FUNC) &c_cudd_set_loose_up_to, 2}, + {"c_cudd_make_verbose", (DL_FUNC) &c_cudd_make_verbose, 1}, + {"c_cudd_make_terse", (DL_FUNC) &c_cudd_make_terse, 1}, + {"c_cudd_is_verbose", (DL_FUNC) &c_cudd_is_verbose, 1}, + {"c_cudd_info", (DL_FUNC) &c_cudd_info, 1}, + {"c_cudd_push_variable_name", (DL_FUNC) &c_cudd_push_variable_name, 2}, + {"c_cudd_clear_variable_names", (DL_FUNC) &c_cudd_clear_variable_names, 1}, + {"c_cudd_get_variable_name", (DL_FUNC) &c_cudd_get_variable_name, 2}, {"c_cudd_read_node_count", (DL_FUNC) &c_cudd_read_node_count, 1}, {"c_cudd_read_zdd_size", (DL_FUNC) &c_cudd_read_zdd_size, 1}, {"c_cudd_read_reorderings", (DL_FUNC) &c_cudd_read_reorderings, 1}, + {"c_cudd_bdd_one", (DL_FUNC) &c_cudd_bdd_one, 1}, + {"c_cudd_bdd_zero", (DL_FUNC) &c_cudd_bdd_zero, 1}, + {"c_cudd_bdd_var", (DL_FUNC) &c_cudd_bdd_var, 2}, + {"c_cudd_add_one", (DL_FUNC) &c_cudd_add_one, 1}, + {"c_cudd_add_zero", (DL_FUNC) &c_cudd_add_zero, 1}, + {"c_cudd_add_var", (DL_FUNC) &c_cudd_add_var, 2}, + {"c_cudd_zdd_one", (DL_FUNC) &c_cudd_zdd_one, 2}, + {"c_cudd_zdd_zero", (DL_FUNC) &c_cudd_zdd_zero, 1}, + {"c_cudd_zdd_var", (DL_FUNC) &c_cudd_zdd_var, 2}, + {"c_cudd_bdd_not", (DL_FUNC) &c_cudd_bdd_not, 1}, + {"c_cudd_bdd_and", (DL_FUNC) &c_cudd_bdd_and, 2}, + {"c_cudd_bdd_or", (DL_FUNC) &c_cudd_bdd_or, 2}, + {"c_cudd_bdd_xor", (DL_FUNC) &c_cudd_bdd_xor, 2}, + {"c_cudd_add_times", (DL_FUNC) &c_cudd_add_times, 2}, + {"c_cudd_add_plus", (DL_FUNC) &c_cudd_add_plus, 2}, + {"c_cudd_zdd_intersect", (DL_FUNC) &c_cudd_zdd_intersect, 2}, + {"c_cudd_zdd_union", (DL_FUNC) &c_cudd_zdd_union, 2}, + {"c_cudd_bdd_to_add", (DL_FUNC) &c_cudd_bdd_to_add, 1}, + {"c_cudd_add_to_bdd", (DL_FUNC) &c_cudd_add_to_bdd, 1}, + {"c_cudd_bdd_to_zdd", (DL_FUNC) &c_cudd_bdd_to_zdd, 1}, + {"c_cudd_zdd_to_bdd", (DL_FUNC) &c_cudd_zdd_to_bdd, 1}, + {"c_cudd_bdd_epd_print_minterm", (DL_FUNC) &c_cudd_bdd_epd_print_minterm, 2}, + {"c_cudd_add_epd_print_minterm", (DL_FUNC) &c_cudd_add_epd_print_minterm, 2}, + {"c_cudd_bdd_print_minterm", (DL_FUNC) &c_cudd_bdd_print_minterm, 1}, + {"c_cudd_add_print_minterm", (DL_FUNC) &c_cudd_add_print_minterm, 1}, + {"c_cudd_zdd_print_minterm", (DL_FUNC) &c_cudd_zdd_print_minterm, 1}, + {"c_cudd_bdd_print_debug", (DL_FUNC) &c_cudd_bdd_print_debug, 3}, + {"c_cudd_bdd_dump_dot", (DL_FUNC) &c_cudd_bdd_dump_dot, 1}, + {"c_cudd_read_start_time", (DL_FUNC) &c_cudd_read_start_time, 1}, + {"c_cudd_read_elapsed_time", (DL_FUNC) &c_cudd_read_elapsed_time, 1}, + {"c_cudd_set_start_time", (DL_FUNC) &c_cudd_set_start_time, 2}, + {"c_cudd_reset_start_time", (DL_FUNC) &c_cudd_reset_start_time, 1}, + {"c_cudd_read_time_limit", (DL_FUNC) &c_cudd_read_time_limit, 1}, + {"c_cudd_set_time_limit", (DL_FUNC) &c_cudd_set_time_limit, 2}, + {"c_cudd_update_time_limit", (DL_FUNC) &c_cudd_update_time_limit, 1}, + {"c_cudd_increase_time_limit", (DL_FUNC) &c_cudd_increase_time_limit, 2}, + {"c_cudd_unset_time_limit", (DL_FUNC) &c_cudd_unset_time_limit, 1}, + {"c_cudd_time_limited", (DL_FUNC) &c_cudd_time_limited, 1}, + {"c_cudd_autodyn_enable", (DL_FUNC) &c_cudd_autodyn_enable, 2}, + {"c_cudd_autodyn_disable", (DL_FUNC) &c_cudd_autodyn_disable, 1}, + {"c_cudd_reordering_status", (DL_FUNC) &c_cudd_reordering_status, 1}, + {"c_cudd_autodyn_enable_zdd", (DL_FUNC) &c_cudd_autodyn_enable_zdd, 2}, + {"c_cudd_autodyn_disable_zdd", (DL_FUNC) &c_cudd_autodyn_disable_zdd, 1}, + {"c_cudd_reordering_status_zdd", (DL_FUNC) &c_cudd_reordering_status_zdd, 1}, + {"c_cudd_zdd_realignment_enabled", (DL_FUNC) &c_cudd_zdd_realignment_enabled, 1}, + {"c_cudd_zdd_realign_enable", (DL_FUNC) &c_cudd_zdd_realign_enable, 1}, + {"c_cudd_zdd_realign_disable", (DL_FUNC) &c_cudd_zdd_realign_disable, 1}, + {"c_cudd_bdd_realignment_enabled", (DL_FUNC) &c_cudd_bdd_realignment_enabled, 1}, + {"c_cudd_bdd_realign_enable", (DL_FUNC) &c_cudd_bdd_realign_enable, 1}, + {"c_cudd_bdd_realign_disable", (DL_FUNC) &c_cudd_bdd_realign_disable, 1}, + {"c_cudd_background", (DL_FUNC) &c_cudd_background, 1}, + {"c_cudd_set_background", (DL_FUNC) &c_cudd_set_background, 2}, + {"c_cudd_read_max_cache", (DL_FUNC) &c_cudd_read_max_cache, 1}, + {"c_cudd_read_max_cache_hard", (DL_FUNC) &c_cudd_read_max_cache_hard, 1}, + {"c_cudd_set_max_cache_hard", (DL_FUNC) &c_cudd_set_max_cache_hard, 2}, + {"c_cudd_read_slots", (DL_FUNC) &c_cudd_read_slots, 1}, + {"c_cudd_read_keys", (DL_FUNC) &c_cudd_read_keys, 1}, + {"c_cudd_read_dead", (DL_FUNC) &c_cudd_read_dead, 1}, + {"c_cudd_read_min_dead", (DL_FUNC) &c_cudd_read_min_dead, 1}, + {"c_cudd_read_max_reorderings", (DL_FUNC) &c_cudd_read_max_reorderings, 1}, + {"c_cudd_set_max_reorderings", (DL_FUNC) &c_cudd_set_max_reorderings, 2}, + {"c_cudd_read_reordering_time", (DL_FUNC) &c_cudd_read_reordering_time, 1}, + {"c_cudd_read_garbage_collections", (DL_FUNC) &c_cudd_read_garbage_collections, 1}, + {"c_cudd_read_garbage_collection_time", (DL_FUNC) &c_cudd_read_garbage_collection_time, 1}, + {"c_cudd_read_sift_max_var", (DL_FUNC) &c_cudd_read_sift_max_var, 1}, + {"c_cudd_set_sift_max_var", (DL_FUNC) &c_cudd_set_sift_max_var, 2}, + {"c_cudd_read_sift_max_swap", (DL_FUNC) &c_cudd_read_sift_max_swap, 1}, + {"c_cudd_set_sift_max_swap", (DL_FUNC) &c_cudd_set_sift_max_swap, 2}, + {"c_cudd_read_max_growth", (DL_FUNC) &c_cudd_read_max_growth, 1}, + {"c_cudd_set_max_growth", (DL_FUNC) &c_cudd_set_max_growth, 2}, + {"c_cudd_read_perm", (DL_FUNC) &c_cudd_read_perm, 2}, + {"c_cudd_read_perm_zdd", (DL_FUNC) &c_cudd_read_perm_zdd, 2}, + {"c_cudd_read_inv_perm", (DL_FUNC) &c_cudd_read_inv_perm, 2}, + {"c_cudd_read_inv_perm_zdd", (DL_FUNC) &c_cudd_read_inv_perm_zdd, 2}, + {"c_cudd_read_vars", (DL_FUNC) &c_cudd_read_vars, 2}, + {"c_cudd_read_epsilon", (DL_FUNC) &c_cudd_read_epsilon, 1}, + {"c_cudd_set_epsilon", (DL_FUNC) &c_cudd_set_epsilon, 2}, + {"c_cudd_read_groupcheck", (DL_FUNC) &c_cudd_read_groupcheck, 1}, + {"c_cudd_set_groupcheck", (DL_FUNC) &c_cudd_set_groupcheck, 2}, + {"c_cudd_garbage_collection_enabled", (DL_FUNC) &c_cudd_garbage_collection_enabled, 1}, + {"c_cudd_enable_garbage_collection", (DL_FUNC) &c_cudd_enable_garbage_collection, 1}, + {"c_cudd_disable_garbage_collection", (DL_FUNC) &c_cudd_disable_garbage_collection, 1}, + {"c_cudd_dead_are_counted", (DL_FUNC) &c_cudd_dead_are_counted, 1}, + {"c_cudd_turn_on_count_dead", (DL_FUNC) &c_cudd_turn_on_count_dead, 1}, + {"c_cudd_turn_off_count_dead", (DL_FUNC) &c_cudd_turn_off_count_dead, 1}, + {"c_cudd_read_recomb", (DL_FUNC) &c_cudd_read_recomb, 1}, + {"c_cudd_set_recomb", (DL_FUNC) &c_cudd_set_recomb, 2}, + {"c_cudd_read_symmviolation", (DL_FUNC) &c_cudd_read_symmviolation, 1}, + {"c_cudd_set_symmviolation", (DL_FUNC) &c_cudd_set_symmviolation, 2}, + {"c_cudd_read_arcviolation", (DL_FUNC) &c_cudd_read_arcviolation, 1}, + {"c_cudd_set_arcviolation", (DL_FUNC) &c_cudd_set_arcviolation, 2}, + {"c_cudd_read_population_size", (DL_FUNC) &c_cudd_read_population_size, 1}, + {"c_cudd_set_population_size", (DL_FUNC) &c_cudd_set_population_size, 2}, + {"c_cudd_read_number_xovers", (DL_FUNC) &c_cudd_read_number_xovers, 1}, + {"c_cudd_set_number_xovers", (DL_FUNC) &c_cudd_set_number_xovers, 2}, + {"c_cudd_read_order_randomization", (DL_FUNC) &c_cudd_read_order_randomization, 1}, + {"c_cudd_set_order_randomization", (DL_FUNC) &c_cudd_set_order_randomization, 2}, + {"c_cudd_read_memory_in_use", (DL_FUNC) &c_cudd_read_memory_in_use, 1}, + {"c_cudd_read_peak_node_count", (DL_FUNC) &c_cudd_read_peak_node_count, 1}, + {"c_cudd_read_node_count_current", (DL_FUNC) &c_cudd_read_node_count_current, 1}, + {"c_cudd_read_node_count_zdd", (DL_FUNC) &c_cudd_read_node_count_zdd, 1}, + {"c_cudd_enable_reordering_reporting", (DL_FUNC) &c_cudd_enable_reordering_reporting, 1}, + {"c_cudd_disable_reordering_reporting", (DL_FUNC) &c_cudd_disable_reordering_reporting, 1}, + {"c_cudd_reordering_reporting", (DL_FUNC) &c_cudd_reordering_reporting, 1}, + {"c_cudd_read_error_code", (DL_FUNC) &c_cudd_read_error_code, 1}, + {"c_cudd_clear_error_code", (DL_FUNC) &c_cudd_clear_error_code, 1}, + {"c_cudd_read_next_reordering", (DL_FUNC) &c_cudd_read_next_reordering, 1}, + {"c_cudd_set_next_reordering", (DL_FUNC) &c_cudd_set_next_reordering, 2}, + {"c_cudd_read_swap_steps", (DL_FUNC) &c_cudd_read_swap_steps, 1}, + {"c_cudd_read_max_live", (DL_FUNC) &c_cudd_read_max_live, 1}, + {"c_cudd_set_max_live", (DL_FUNC) &c_cudd_set_max_live, 2}, + {"c_cudd_read_max_memory", (DL_FUNC) &c_cudd_read_max_memory, 1}, + {"c_cudd_set_max_memory", (DL_FUNC) &c_cudd_set_max_memory, 2}, + {"c_cudd_bdd_bind_var", (DL_FUNC) &c_cudd_bdd_bind_var, 2}, + {"c_cudd_bdd_unbind_var", (DL_FUNC) &c_cudd_bdd_unbind_var, 2}, + {"c_cudd_bdd_var_is_bound", (DL_FUNC) &c_cudd_bdd_var_is_bound, 2}, {"c_bdd_remaining_literals", (DL_FUNC) &bdd_remaining_literals, 1}, {"c_bdd_restrict_chain", (DL_FUNC) &bdd_restrict_chain, 2}, {NULL, NULL, 0} diff --git a/tests/testthat/_snaps/cudd_diagrams.md b/tests/testthat/_snaps/cudd_diagrams.md new file mode 100644 index 0000000..2b8ba5a --- /dev/null +++ b/tests/testthat/_snaps/cudd_diagrams.md @@ -0,0 +1,50 @@ +# BDD operations and conversions return expected classes + + Code + output + Output + [1] "1.000000e+00" + +--- + + Code + print_output + Output + [1] "- 1" + +--- + + Code + debug_output + Output + [1] ": 1 nodes 1 leaves 2 minterms" "- 1" + [3] "" + +--- + + Code + dot_output + Output + [1] "" + +# ADD operations and conversions return expected classes + + Code + output + Output + [1] "1.000000e+00" + +--- + + Code + print_output + Output + [1] "- 1" + +# ZDD operations and conversions return expected classes + + Code + print_output + Output + [1] "0 1" + diff --git a/tests/testthat/test_cudd_diagrams.R b/tests/testthat/test_cudd_diagrams.R new file mode 100644 index 0000000..08eab1e --- /dev/null +++ b/tests/testthat/test_cudd_diagrams.R @@ -0,0 +1,83 @@ +test_that("BDD operations and conversions return expected classes", { + manager <- CuddManager() + + bdd_one <- cudd_bdd_one(manager) + bdd_zero <- cudd_bdd_zero(manager) + bdd_var <- cudd_bdd_var(manager) + + expect_s4_class(bdd_one, "CuddBDD") + expect_s4_class(bdd_zero, "CuddBDD") + expect_s4_class(bdd_var, "CuddBDD") + + expect_s4_class(!bdd_one, "CuddBDD") + expect_s4_class(bdd_one + bdd_zero, "CuddBDD") + expect_s4_class(bdd_one * bdd_zero, "CuddBDD") + expect_s4_class(bdd_one ^ bdd_zero, "CuddBDD") + + add_from_bdd <- cudd_bdd_to_add(bdd_one) + expect_s4_class(add_from_bdd, "CuddADD") + + zdd_from_bdd <- cudd_bdd_to_zdd(bdd_var) + expect_s4_class(zdd_from_bdd, "CuddZDD") + + output <- capture.output(cudd_bdd_epd_print_minterm(bdd_one, 0L)) + expect_snapshot(output) + + print_output <- capture.output(print(bdd_one)) + expect_snapshot(print_output) + + debug_output <- capture.output(cudd_bdd_print_debug(bdd_one, nvars = 1L, verbosity = 2L)) + expect_snapshot(debug_output) + + dot_output <- cudd_bdd_dump_dot(bdd_one) + expect_snapshot(dot_output) +}) + +test_that("ADD operations and conversions return expected classes", { + manager <- CuddManager() + + add_one <- cudd_add_one(manager) + add_zero <- cudd_add_zero(manager) + add_var <- cudd_add_var(manager) + + expect_s4_class(add_one, "CuddADD") + expect_s4_class(add_zero, "CuddADD") + expect_s4_class(add_var, "CuddADD") + + expect_s4_class(add_one + add_zero, "CuddADD") + expect_s4_class(add_one * add_zero, "CuddADD") + expect_error(add_one ^ add_zero, "XOR") + expect_error(!add_one, "Negation") + + bdd_from_add <- cudd_add_to_bdd(add_one) + expect_s4_class(bdd_from_add, "CuddBDD") + + output <- capture.output(cudd_add_epd_print_minterm(add_one, 0L)) + expect_snapshot(output) + + print_output <- capture.output(print(add_one)) + expect_snapshot(print_output) +}) + +test_that("ZDD operations and conversions return expected classes", { + manager <- CuddManager() + + zdd_one <- cudd_zdd_one(manager, 0L) + zdd_zero <- cudd_zdd_zero(manager) + zdd_var <- cudd_zdd_var(manager) + + expect_s4_class(zdd_one, "CuddZDD") + expect_s4_class(zdd_zero, "CuddZDD") + expect_s4_class(zdd_var, "CuddZDD") + + expect_s4_class(zdd_one + zdd_zero, "CuddZDD") + expect_s4_class(zdd_one * zdd_zero, "CuddZDD") + expect_error(zdd_one ^ zdd_zero, "XOR") + expect_error(!zdd_one, "Negation") + + bdd_from_zdd <- cudd_zdd_to_bdd(zdd_var) + expect_s4_class(bdd_from_zdd, "CuddBDD") + + print_output <- capture.output(print(zdd_one)) + expect_snapshot(print_output) +}) diff --git a/tests/testthat/test_cudd_manager.R b/tests/testthat/test_cudd_manager.R index bc9e40c..7ebe7ea 100644 --- a/tests/testthat/test_cudd_manager.R +++ b/tests/testthat/test_cudd_manager.R @@ -2,17 +2,244 @@ test_that("CuddManager exposes manager stats", { manager <- CuddManager() expect_length(cudd_read_cache_used_slots(manager), 1L) - expect_true(is.numeric(cudd_read_cache_used_slots(manager))) + expect_type(cudd_read_cache_used_slots(manager), "double") expect_length(cudd_read_min_hit(manager), 1L) - expect_true(is.numeric(cudd_read_min_hit(manager))) + expect_type(cudd_read_min_hit(manager), "integer") expect_length(cudd_read_loose_up_to(manager), 1L) - expect_true(is.numeric(cudd_read_loose_up_to(manager))) + expect_type(cudd_read_loose_up_to(manager), "integer") expect_length(cudd_read_zdd_size(manager), 1L) - expect_true(is.numeric(cudd_read_zdd_size(manager))) + expect_type(cudd_read_zdd_size(manager), "integer") expect_length(cudd_read_reorderings(manager), 1L) - expect_true(is.numeric(cudd_read_reorderings(manager))) + expect_type(cudd_read_reorderings(manager), "integer") +}) + +test_that("CuddManager exposes time limit and verbosity controls", { + manager <- CuddManager() + + expect_length(cudd_read_start_time(manager), 1L) + expect_type(cudd_read_start_time(manager), "double") + expect_length(cudd_read_elapsed_time(manager), 1L) + expect_type(cudd_read_elapsed_time(manager), "double") + + expect_null(cudd_set_start_time(manager, 1.0)) + expect_null(cudd_reset_start_time(manager)) + + expect_length(cudd_read_time_limit(manager), 1L) + expect_type(cudd_read_time_limit(manager), "double") + expect_length(cudd_set_time_limit(manager, 1.0), 1L) + expect_type(cudd_set_time_limit(manager, 1.0), "double") + expect_null(cudd_update_time_limit(manager)) + expect_null(cudd_increase_time_limit(manager, 1.0)) + expect_null(cudd_unset_time_limit(manager)) + expect_type(cudd_time_limited(manager), "logical") + + expect_null(cudd_make_verbose(manager)) + expect_type(cudd_is_verbose(manager), "logical") + expect_null(cudd_info(manager)) + expect_null(cudd_make_terse(manager)) +}) + +test_that("CuddManager exposes reordering and realignment controls", { + manager <- CuddManager() + + expect_null(cudd_autodyn_enable(manager)) + status <- cudd_reordering_status(manager) + expect_true(all(c("enabled", "method") %in% names(status))) + expect_type(status$enabled, "logical") + expect_type(status$method, "integer") + expect_null(cudd_autodyn_disable(manager)) + + expect_null(cudd_autodyn_enable_zdd(manager)) + status_zdd <- cudd_reordering_status_zdd(manager) + expect_true(all(c("enabled", "method") %in% names(status_zdd))) + expect_type(status_zdd$enabled, "logical") + expect_type(status_zdd$method, "integer") + expect_null(cudd_autodyn_disable_zdd(manager)) + + expect_type(cudd_bdd_realignment_enabled(manager), "logical") + expect_null(cudd_bdd_realign_enable(manager)) + expect_true(cudd_bdd_realignment_enabled(manager)) + expect_null(cudd_bdd_realign_disable(manager)) + + expect_type(cudd_zdd_realignment_enabled(manager), "logical") + expect_null(cudd_zdd_realign_enable(manager)) + expect_true(cudd_zdd_realignment_enabled(manager)) + expect_null(cudd_zdd_realign_disable(manager)) +}) + +test_that("CuddManager exposes cache and memory controls", { + manager <- CuddManager() + + expect_null(cudd_set_min_hit(manager, 1L)) + expect_length(cudd_read_min_hit(manager), 1L) + + expect_null(cudd_set_loose_up_to(manager, 1L)) + expect_length(cudd_read_loose_up_to(manager), 1L) + + expect_length(cudd_read_max_cache(manager), 1L) + expect_type(cudd_read_max_cache(manager), "integer") + expect_length(cudd_read_max_cache_hard(manager), 1L) + expect_type(cudd_read_max_cache_hard(manager), "integer") + expect_null(cudd_set_max_cache_hard(manager, 10L)) + + expect_length(cudd_read_slots(manager), 1L) + expect_type(cudd_read_slots(manager), "integer") + expect_length(cudd_read_keys(manager), 1L) + expect_type(cudd_read_keys(manager), "integer") + expect_length(cudd_read_dead(manager), 1L) + expect_type(cudd_read_dead(manager), "integer") + expect_length(cudd_read_min_dead(manager), 1L) + expect_type(cudd_read_min_dead(manager), "integer") + + expect_length(cudd_read_memory_in_use(manager), 1L) + expect_type(cudd_read_memory_in_use(manager), "double") + expect_length(cudd_read_peak_node_count(manager), 1L) + expect_type(cudd_read_peak_node_count(manager), "double") + expect_length(cudd_read_node_count_current(manager), 1L) + expect_type(cudd_read_node_count_current(manager), "double") + expect_length(cudd_read_node_count_zdd(manager), 1L) + expect_type(cudd_read_node_count_zdd(manager), "double") + + expect_length(cudd_read_max_memory(manager), 1L) + expect_type(cudd_read_max_memory(manager), "double") + expect_length(cudd_set_max_memory(manager, 1024.0), 1L) + expect_type(cudd_set_max_memory(manager, 1024.0), "double") +}) + +test_that("CuddManager exposes variable and reordering parameters", { + manager <- CuddManager() + + expect_null(cudd_set_max_reorderings(manager, 1L)) + expect_length(cudd_read_max_reorderings(manager), 1L) + expect_type(cudd_read_reordering_time(manager), "double") + + expect_null(cudd_set_sift_max_var(manager, 1L)) + expect_length(cudd_read_sift_max_var(manager), 1L) + expect_type(cudd_read_sift_max_var(manager), "integer") + expect_null(cudd_set_sift_max_swap(manager, 1L)) + expect_length(cudd_read_sift_max_swap(manager), 1L) + expect_type(cudd_read_sift_max_swap(manager), "integer") + + expect_null(cudd_set_max_growth(manager, 1.5)) + expect_length(cudd_read_max_growth(manager), 1L) + expect_type(cudd_read_max_growth(manager), "double") + + expect_null(cudd_set_groupcheck(manager, 0L)) + expect_length(cudd_read_groupcheck(manager), 1L) + expect_type(cudd_read_groupcheck(manager), "integer") + + expect_null(cudd_set_recomb(manager, 1L)) + expect_length(cudd_read_recomb(manager), 1L) + expect_type(cudd_read_recomb(manager), "integer") + expect_null(cudd_set_symmviolation(manager, 1L)) + expect_length(cudd_read_symmviolation(manager), 1L) + expect_type(cudd_read_symmviolation(manager), "integer") + expect_null(cudd_set_arcviolation(manager, 1L)) + expect_length(cudd_read_arcviolation(manager), 1L) + expect_type(cudd_read_arcviolation(manager), "integer") + + expect_null(cudd_set_population_size(manager, 2L)) + expect_length(cudd_read_population_size(manager), 1L) + expect_type(cudd_read_population_size(manager), "integer") + expect_null(cudd_set_number_xovers(manager, 2L)) + expect_length(cudd_read_number_xovers(manager), 1L) + expect_type(cudd_read_number_xovers(manager), "integer") + expect_null(cudd_set_order_randomization(manager, 1L)) + expect_length(cudd_read_order_randomization(manager), 1L) + expect_type(cudd_read_order_randomization(manager), "integer") + + expect_null(cudd_set_next_reordering(manager, 0L)) + expect_length(cudd_read_next_reordering(manager), 1L) + expect_type(cudd_read_next_reordering(manager), "integer") + expect_length(cudd_read_swap_steps(manager), 1L) + expect_type(cudd_read_swap_steps(manager), "double") +}) + +test_that("CuddManager exposes variable name, epsilon, and GC helpers", { + manager <- CuddManager() + + expect_null(cudd_push_variable_name(manager, "x0")) + expect_identical(cudd_get_variable_name(manager, 0L), "x0") + expect_null(cudd_clear_variable_names(manager)) + + expect_length(cudd_read_epsilon(manager), 1L) + expect_type(cudd_read_epsilon(manager), "double") + expect_null(cudd_set_epsilon(manager, 0.01)) + + expect_type(cudd_garbage_collection_enabled(manager), "logical") + expect_null(cudd_enable_garbage_collection(manager)) + expect_null(cudd_disable_garbage_collection(manager)) + + expect_type(cudd_dead_are_counted(manager), "logical") + expect_null(cudd_turn_on_count_dead(manager)) + expect_null(cudd_turn_off_count_dead(manager)) + + expect_null(cudd_enable_reordering_reporting(manager)) + expect_type(cudd_reordering_reporting(manager), "logical") + expect_null(cudd_disable_reordering_reporting(manager)) + + expect_length(cudd_read_error_code(manager), 1L) + expect_type(cudd_read_error_code(manager), "integer") + expect_null(cudd_clear_error_code(manager)) +}) + +test_that("CuddManager exposes BDD bindings and variable accessors", { + manager <- CuddManager() + + expect_s4_class(cudd_bdd_var(manager, 0L), "CuddBDD") + expect_type(cudd_bdd_var_is_bound(manager, 0L), "logical") + expect_type(cudd_bdd_bind_var(manager, 0L), "integer") + expect_type(cudd_bdd_var_is_bound(manager, 0L), "logical") + expect_type(cudd_bdd_unbind_var(manager, 0L), "integer") + + expect_s4_class(cudd_read_vars(manager, 0L), "CuddBDD") + expect_type(cudd_read_perm(manager, 0L), "integer") + expect_type(cudd_read_perm_zdd(manager, 0L), "integer") + expect_type(cudd_read_inv_perm(manager, 0L), "integer") + expect_type(cudd_read_inv_perm_zdd(manager, 0L), "integer") +}) + +test_that("CuddManager exposes background and live controls", { + manager <- CuddManager() + + add_zero <- cudd_add_zero(manager) + expect_s4_class(cudd_background(manager), "CuddADD") + expect_null(cudd_set_background(manager, add_zero)) + + expect_length(cudd_read_max_live(manager), 1L) + expect_type(cudd_read_max_live(manager), "integer") + expect_null(cudd_set_max_live(manager, 1L)) +}) + +test_that("Cudd operations warn on manager mismatches", { + manager_a <- CuddManager() + manager_b <- CuddManager() + + bdd_a <- cudd_bdd_one(manager_a) + bdd_b <- cudd_bdd_one(manager_b) + expect_no_warning(bdd_a + cudd_bdd_zero(manager_a)) + expect_warning( + expect_error(bdd_a + bdd_b, "different CuddManager"), + "different CuddManager" + ) + + add_a <- cudd_add_one(manager_a) + add_b <- cudd_add_one(manager_b) + expect_no_warning(add_a * cudd_add_zero(manager_a)) + expect_warning( + expect_error(add_a * add_b, "different CuddManager"), + "different CuddManager" + ) + + zdd_a <- cudd_zdd_zero(manager_a) + zdd_b <- cudd_zdd_zero(manager_b) + expect_no_warning(zdd_a + cudd_zdd_one(manager_a)) + expect_warning( + expect_error(zdd_a + zdd_b, "different CuddManager"), + "different CuddManager" + ) }) From 0c44e54383af7ab1d0524b0a01fca3fc2d67870a Mon Sep 17 00:00:00 2001 From: MEO265 <99362508+MEO265@users.noreply.github.com> Date: Wed, 31 Dec 2025 05:12:47 +0100 Subject: [PATCH 4/5] Add BDD truth table helper (#5) * Add BDD truth table helper * Remove native symbol delayed assignments --- NAMESPACE | 11 +- R/cudd_add.R | 20 ++- R/cudd_bdd.R | 37 ++++- R/cudd_manager.R | 1 + R/cudd_zdd.R | 20 ++- R/rcudd.R | 151 +----------------- ...DD-method.Rd => cudd_add_print_minterm.Rd} | 12 +- ...DD-method.Rd => cudd_bdd_print_minterm.Rd} | 12 +- man/cudd_bdd_truth_table.Rd | 21 +++ ...DD-method.Rd => cudd_zdd_print_minterm.Rd} | 12 +- src/cudd_manager.cpp | 39 +++++ src/rcudd.h | 1 + src/register.cpp | 1 + tests/testthat/_snaps/cudd_diagrams.md | 12 +- tests/testthat/test_cudd_diagrams.R | 18 ++- 15 files changed, 160 insertions(+), 208 deletions(-) rename man/{print-CuddADD-method.Rd => cudd_add_print_minterm.Rd} (61%) rename man/{print-CuddBDD-method.Rd => cudd_bdd_print_minterm.Rd} (61%) create mode 100644 man/cudd_bdd_truth_table.Rd rename man/{print-CuddZDD-method.Rd => cudd_zdd_print_minterm.Rd} (61%) diff --git a/NAMESPACE b/NAMESPACE index bd883a5..42a5697 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -7,6 +7,7 @@ export(bdd_restrict_chain) export(bdd_restrict_from_expressions) export(cudd_add_epd_print_minterm) export(cudd_add_one) +export(cudd_add_print_minterm) export(cudd_add_to_bdd) export(cudd_add_var) export(cudd_add_zero) @@ -20,11 +21,13 @@ export(cudd_bdd_dump_dot) export(cudd_bdd_epd_print_minterm) export(cudd_bdd_one) export(cudd_bdd_print_debug) +export(cudd_bdd_print_minterm) export(cudd_bdd_realign_disable) export(cudd_bdd_realign_enable) export(cudd_bdd_realignment_enabled) export(cudd_bdd_to_add) export(cudd_bdd_to_zdd) +export(cudd_bdd_truth_table) export(cudd_bdd_unbind_var) export(cudd_bdd_var) export(cudd_bdd_var_is_bound) @@ -123,6 +126,7 @@ export(cudd_turn_on_count_dead) export(cudd_unset_time_limit) export(cudd_update_time_limit) export(cudd_zdd_one) +export(cudd_zdd_print_minterm) export(cudd_zdd_realign_disable) export(cudd_zdd_realign_enable) export(cudd_zdd_realignment_enabled) @@ -132,5 +136,10 @@ export(cudd_zdd_zero) export(expression_to_cpp_logic) export(expressions_to_cpp_logic) export(order_constraints) -exportMethods(print) +exportMethods("!") +exportMethods("*") +exportMethods("+") +exportMethods("^") +exportMethods(show) +importFrom(methods,show) useDynLib(Rcudd, .registration=TRUE) diff --git a/R/cudd_add.R b/R/cudd_add.R index 4ecb4d4..d6925c4 100644 --- a/R/cudd_add.R +++ b/R/cudd_add.R @@ -32,9 +32,10 @@ methods::setClass( #' @describeIn CuddADD-class Show a brief summary of the ADD. #' @param object A `CuddADD` instance. #' @keywords internal +#' @export methods::setMethod("show", "CuddADD", function(object) { cat("\n") - print(object) + cudd_add_print_minterm(object) return(invisible(object)) }) @@ -90,6 +91,7 @@ cudd_add_var <- function(manager, index = NULL) { #' @param e1 A `CuddADD` instance. #' @param e2 A `CuddADD` instance. #' @return A `CuddADD` instance. +#' @export setMethod("*", signature(e1 = "CuddADD", e2 = "CuddADD"), function(e1, e2) { if (!.cudd_check_same_manager(e1, e2, "*")) { stop("Cannot combine ADDs from different CuddManager instances.", call. = FALSE) @@ -102,6 +104,7 @@ setMethod("*", signature(e1 = "CuddADD", e2 = "CuddADD"), function(e1, e2) { #' @param e1 A `CuddADD` instance. #' @param e2 A `CuddADD` instance. #' @return A `CuddADD` instance. +#' @export setMethod("+", signature(e1 = "CuddADD", e2 = "CuddADD"), function(e1, e2) { if (!.cudd_check_same_manager(e1, e2, "+")) { stop("Cannot combine ADDs from different CuddManager instances.", call. = FALSE) @@ -114,6 +117,7 @@ setMethod("+", signature(e1 = "CuddADD", e2 = "CuddADD"), function(e1, e2) { #' @param e1 A `CuddADD` instance. #' @param e2 A `CuddADD` instance. #' @return An error indicating the operator is unsupported. +#' @export setMethod("^", signature(e1 = "CuddADD", e2 = "CuddADD"), function(e1, e2) { stop("XOR (^) is not defined for CuddADD.", call. = FALSE) }) @@ -121,6 +125,7 @@ setMethod("^", signature(e1 = "CuddADD", e2 = "CuddADD"), function(e1, e2) { #' @describeIn CuddADD-class Negation is not defined for ADDs #' @param x A `CuddADD` instance. #' @return An error indicating the operator is unsupported. +#' @export setMethod("!", "CuddADD", function(x) { stop("Negation (!) is not defined for CuddADD.", call. = FALSE) }) @@ -144,11 +149,10 @@ cudd_add_epd_print_minterm <- function(add, nvars) { #' This uses the CUDD `PrintMinterm` implementation, which writes to R's #' output stream. #' -#' @param x A [`CuddADD`] instance. -#' @param ... Unused. -#' @return The input `x`, invisibly. +#' @param add A [`CuddADD`] instance. +#' @return `NULL`, invisibly. #' @export -setMethod("print", "CuddADD", function(x, ...) { - .Call(c_cudd_add_print_minterm, .cudd_add_ptr(x)) - return(invisible(x)) -}) +cudd_add_print_minterm <- function(add) { + .Call(c_cudd_add_print_minterm, .cudd_add_ptr(add)) + return(invisible(NULL)) +} diff --git a/R/cudd_bdd.R b/R/cudd_bdd.R index 3bc1de5..4044e8b 100644 --- a/R/cudd_bdd.R +++ b/R/cudd_bdd.R @@ -32,9 +32,10 @@ methods::setClass( #' @describeIn CuddBDD-class Show a brief summary of the BDD. #' @param object A `CuddBDD` instance. #' @keywords internal +#' @export methods::setMethod("show", "CuddBDD", function(object) { cat("\n") - print(object) + cudd_bdd_print_minterm(object) return(invisible(object)) }) @@ -89,6 +90,7 @@ cudd_bdd_var <- function(manager, index = NULL) { #' @describeIn CuddBDD-class Negate a BDD #' @param x A `CuddBDD` instance. #' @return A `CuddBDD` instance. +#' @export setMethod("!", "CuddBDD", function(x) { ptr <- .Call(c_cudd_bdd_not, .cudd_bdd_ptr(x)) return(methods::new("CuddBDD", ptr = ptr, manager_ptr = .cudd_bdd_manager_ptr(x))) @@ -98,6 +100,7 @@ setMethod("!", "CuddBDD", function(x) { #' @param e1 A `CuddBDD` instance. #' @param e2 A `CuddBDD` instance. #' @return A `CuddBDD` instance. +#' @export setMethod("+", signature(e1 = "CuddBDD", e2 = "CuddBDD"), function(e1, e2) { if (!.cudd_check_same_manager(e1, e2, "+")) { stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) @@ -110,6 +113,7 @@ setMethod("+", signature(e1 = "CuddBDD", e2 = "CuddBDD"), function(e1, e2) { #' @param e1 A `CuddBDD` instance. #' @param e2 A `CuddBDD` instance. #' @return A `CuddBDD` instance. +#' @export setMethod("*", signature(e1 = "CuddBDD", e2 = "CuddBDD"), function(e1, e2) { if (!.cudd_check_same_manager(e1, e2, "*")) { stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) @@ -122,6 +126,7 @@ setMethod("*", signature(e1 = "CuddBDD", e2 = "CuddBDD"), function(e1, e2) { #' @param e1 A `CuddBDD` instance. #' @param e2 A `CuddBDD` instance. #' @return A `CuddBDD` instance. +#' @export setMethod("^", signature(e1 = "CuddBDD", e2 = "CuddBDD"), function(e1, e2) { if (!.cudd_check_same_manager(e1, e2, "^")) { stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) @@ -149,14 +154,30 @@ cudd_bdd_epd_print_minterm <- function(bdd, nvars) { #' This uses the CUDD `PrintMinterm` implementation, which writes to R's #' output stream. #' -#' @param x A [`CuddBDD`] instance. -#' @param ... Unused. -#' @return The input `x`, invisibly. +#' @param bdd A [`CuddBDD`] instance. +#' @return `NULL`, invisibly. #' @export -setMethod("print", "CuddBDD", function(x, ...) { - .Call(c_cudd_bdd_print_minterm, .cudd_bdd_ptr(x)) - return(invisible(x)) -}) +cudd_bdd_print_minterm <- function(bdd) { + .Call(c_cudd_bdd_print_minterm, .cudd_bdd_ptr(bdd)) + return(invisible(NULL)) +} + +#' Generate a truth table for a BDD +#' +#' Produces a matrix with one column per variable and a final column named +#' `value` containing the BDD evaluation for each assignment. +#' +#' @param bdd A [`CuddBDD`] instance. +#' @param nvars Optional non-negative integer indicating how many variables to +#' include. Defaults to the manager size. +#' @return An integer matrix representing the truth table. +#' @export +cudd_bdd_truth_table <- function(bdd, nvars = NULL) { + truth_table <- .Call(c_cudd_bdd_truth_table, .cudd_bdd_ptr(bdd), nvars) + var_count <- ncol(truth_table) - 1L + colnames(truth_table) <- c(paste0("x", seq_len(var_count)), "value") + return(truth_table) +} #' Print a debug representation for a BDD #' diff --git a/R/cudd_manager.R b/R/cudd_manager.R index 9a14704..0aba608 100644 --- a/R/cudd_manager.R +++ b/R/cudd_manager.R @@ -33,6 +33,7 @@ CuddManager <- function() { # nolint: object_name_linter. #' @describeIn CuddManager-class Show a brief summary of the manager. #' @param object A `CuddManager` instance. #' @keywords internal +#' @export methods::setMethod("show", "CuddManager", function(object) { cat("\n") return(invisible(object)) diff --git a/R/cudd_zdd.R b/R/cudd_zdd.R index 0e62f7d..68d5701 100644 --- a/R/cudd_zdd.R +++ b/R/cudd_zdd.R @@ -32,9 +32,10 @@ methods::setClass( #' @describeIn CuddZDD-class Show a brief summary of the ZDD. #' @param object A `CuddZDD` instance. #' @keywords internal +#' @export methods::setMethod("show", "CuddZDD", function(object) { cat("\n") - print(object) + cudd_zdd_print_minterm(object) return(invisible(object)) }) @@ -90,6 +91,7 @@ cudd_zdd_var <- function(manager, index = NULL) { #' @param e1 A `CuddZDD` instance. #' @param e2 A `CuddZDD` instance. #' @return A `CuddZDD` instance. +#' @export setMethod("*", signature(e1 = "CuddZDD", e2 = "CuddZDD"), function(e1, e2) { if (!.cudd_check_same_manager(e1, e2, "*")) { stop("Cannot combine ZDDs from different CuddManager instances.", call. = FALSE) @@ -102,6 +104,7 @@ setMethod("*", signature(e1 = "CuddZDD", e2 = "CuddZDD"), function(e1, e2) { #' @param e1 A `CuddZDD` instance. #' @param e2 A `CuddZDD` instance. #' @return A `CuddZDD` instance. +#' @export setMethod("+", signature(e1 = "CuddZDD", e2 = "CuddZDD"), function(e1, e2) { if (!.cudd_check_same_manager(e1, e2, "+")) { stop("Cannot combine ZDDs from different CuddManager instances.", call. = FALSE) @@ -114,6 +117,7 @@ setMethod("+", signature(e1 = "CuddZDD", e2 = "CuddZDD"), function(e1, e2) { #' @param e1 A `CuddZDD` instance. #' @param e2 A `CuddZDD` instance. #' @return An error indicating the operator is unsupported. +#' @export setMethod("^", signature(e1 = "CuddZDD", e2 = "CuddZDD"), function(e1, e2) { stop("XOR (^) is not defined for CuddZDD.", call. = FALSE) }) @@ -121,6 +125,7 @@ setMethod("^", signature(e1 = "CuddZDD", e2 = "CuddZDD"), function(e1, e2) { #' @describeIn CuddZDD-class Negation is not defined for ZDDs #' @param x A `CuddZDD` instance. #' @return An error indicating the operator is unsupported. +#' @export setMethod("!", "CuddZDD", function(x) { stop("Negation (!) is not defined for CuddZDD.", call. = FALSE) }) @@ -130,11 +135,10 @@ setMethod("!", "CuddZDD", function(x) { #' This uses the CUDD `PrintMinterm` implementation, which writes to R's #' output stream. #' -#' @param x A [`CuddZDD`] instance. -#' @param ... Unused. -#' @return The input `x`, invisibly. +#' @param zdd A [`CuddZDD`] instance. +#' @return `NULL`, invisibly. #' @export -setMethod("print", "CuddZDD", function(x, ...) { - .Call(c_cudd_zdd_print_minterm, .cudd_zdd_ptr(x)) - return(invisible(x)) -}) +cudd_zdd_print_minterm <- function(zdd) { + .Call(c_cudd_zdd_print_minterm, .cudd_zdd_ptr(zdd)) + return(invisible(NULL)) +} diff --git a/R/rcudd.R b/R/rcudd.R index 02c8c79..1518ad4 100644 --- a/R/rcudd.R +++ b/R/rcudd.R @@ -1,156 +1,7 @@ #' @useDynLib Rcudd, .registration=TRUE +#' @importFrom methods show NULL -local({ - symbols <- c( - "c_bdd_remaining_literals", - "c_bdd_restrict_chain", - "c_cudd_add_epd_print_minterm", - "c_cudd_add_one", - "c_cudd_add_plus", - "c_cudd_add_print_minterm", - "c_cudd_add_times", - "c_cudd_add_to_bdd", - "c_cudd_add_var", - "c_cudd_add_zero", - "c_cudd_autodyn_disable", - "c_cudd_autodyn_disable_zdd", - "c_cudd_autodyn_enable", - "c_cudd_autodyn_enable_zdd", - "c_cudd_background", - "c_cudd_bdd_and", - "c_cudd_bdd_bind_var", - "c_cudd_bdd_dump_dot", - "c_cudd_bdd_epd_print_minterm", - "c_cudd_bdd_not", - "c_cudd_bdd_one", - "c_cudd_bdd_or", - "c_cudd_bdd_print_debug", - "c_cudd_bdd_print_minterm", - "c_cudd_bdd_realign_disable", - "c_cudd_bdd_realign_enable", - "c_cudd_bdd_realignment_enabled", - "c_cudd_bdd_to_add", - "c_cudd_bdd_to_zdd", - "c_cudd_bdd_unbind_var", - "c_cudd_bdd_var", - "c_cudd_bdd_var_is_bound", - "c_cudd_bdd_xor", - "c_cudd_bdd_zero", - "c_cudd_clear_error_code", - "c_cudd_clear_variable_names", - "c_cudd_dead_are_counted", - "c_cudd_disable_garbage_collection", - "c_cudd_disable_reordering_reporting", - "c_cudd_enable_garbage_collection", - "c_cudd_enable_reordering_reporting", - "c_cudd_garbage_collection_enabled", - "c_cudd_get_variable_name", - "c_cudd_increase_time_limit", - "c_cudd_info", - "c_cudd_is_verbose", - "c_cudd_make_terse", - "c_cudd_make_verbose", - "c_cudd_new", - "c_cudd_push_variable_name", - "c_cudd_read_arcviolation", - "c_cudd_read_cache_hits", - "c_cudd_read_cache_lookups", - "c_cudd_read_cache_slots", - "c_cudd_read_cache_used_slots", - "c_cudd_read_dead", - "c_cudd_read_elapsed_time", - "c_cudd_read_epsilon", - "c_cudd_read_error_code", - "c_cudd_read_garbage_collection_time", - "c_cudd_read_garbage_collections", - "c_cudd_read_groupcheck", - "c_cudd_read_inv_perm", - "c_cudd_read_inv_perm_zdd", - "c_cudd_read_keys", - "c_cudd_read_loose_up_to", - "c_cudd_read_max_cache", - "c_cudd_read_max_cache_hard", - "c_cudd_read_max_growth", - "c_cudd_read_max_live", - "c_cudd_read_max_memory", - "c_cudd_read_max_reorderings", - "c_cudd_read_memory_in_use", - "c_cudd_read_min_dead", - "c_cudd_read_min_hit", - "c_cudd_read_next_reordering", - "c_cudd_read_node_count", - "c_cudd_read_node_count_current", - "c_cudd_read_node_count_zdd", - "c_cudd_read_number_xovers", - "c_cudd_read_order_randomization", - "c_cudd_read_peak_node_count", - "c_cudd_read_perm", - "c_cudd_read_perm_zdd", - "c_cudd_read_population_size", - "c_cudd_read_recomb", - "c_cudd_read_reordering_time", - "c_cudd_read_reorderings", - "c_cudd_read_sift_max_swap", - "c_cudd_read_sift_max_var", - "c_cudd_read_size", - "c_cudd_read_slots", - "c_cudd_read_start_time", - "c_cudd_read_swap_steps", - "c_cudd_read_symmviolation", - "c_cudd_read_time_limit", - "c_cudd_read_vars", - "c_cudd_read_zdd_size", - "c_cudd_reordering_reporting", - "c_cudd_reordering_status", - "c_cudd_reordering_status_zdd", - "c_cudd_reset_start_time", - "c_cudd_set_arcviolation", - "c_cudd_set_background", - "c_cudd_set_epsilon", - "c_cudd_set_groupcheck", - "c_cudd_set_loose_up_to", - "c_cudd_set_max_cache_hard", - "c_cudd_set_max_growth", - "c_cudd_set_max_live", - "c_cudd_set_max_memory", - "c_cudd_set_max_reorderings", - "c_cudd_set_min_hit", - "c_cudd_set_next_reordering", - "c_cudd_set_number_xovers", - "c_cudd_set_order_randomization", - "c_cudd_set_population_size", - "c_cudd_set_recomb", - "c_cudd_set_sift_max_swap", - "c_cudd_set_sift_max_var", - "c_cudd_set_start_time", - "c_cudd_set_symmviolation", - "c_cudd_set_time_limit", - "c_cudd_time_limited", - "c_cudd_turn_off_count_dead", - "c_cudd_turn_on_count_dead", - "c_cudd_unset_time_limit", - "c_cudd_update_time_limit", - "c_cudd_zdd_intersect", - "c_cudd_zdd_one", - "c_cudd_zdd_print_minterm", - "c_cudd_zdd_realign_disable", - "c_cudd_zdd_realign_enable", - "c_cudd_zdd_realignment_enabled", - "c_cudd_zdd_to_bdd", - "c_cudd_zdd_union", - "c_cudd_zdd_var", - "c_cudd_zdd_zero" - ) - for (name in symbols) { - delayedAssign( - name, - getNativeSymbolInfo(name, PACKAGE = "Rcudd"), - assign.env = environment() - ) - } -}) - .cudd_check_same_manager <- function(lhs, rhs, op) { same_manager <- identical(lhs@manager_ptr, rhs@manager_ptr) if (!same_manager) { diff --git a/man/print-CuddADD-method.Rd b/man/cudd_add_print_minterm.Rd similarity index 61% rename from man/print-CuddADD-method.Rd rename to man/cudd_add_print_minterm.Rd index bc9011b..81d7bbc 100644 --- a/man/print-CuddADD-method.Rd +++ b/man/cudd_add_print_minterm.Rd @@ -1,18 +1,16 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/cudd_add.R -\name{print,CuddADD-method} -\alias{print,CuddADD-method} +\name{cudd_add_print_minterm} +\alias{cudd_add_print_minterm} \title{Print the minterm representation for an ADD} \usage{ -\S4method{print}{CuddADD}(x, ...) +cudd_add_print_minterm(add) } \arguments{ -\item{x}{A [`CuddADD`] instance.} - -\item{...}{Unused.} +\item{add}{A [`CuddADD`] instance.} } \value{ -The input `x`, invisibly. +`NULL`, invisibly. } \description{ This uses the CUDD `PrintMinterm` implementation, which writes to R's diff --git a/man/print-CuddBDD-method.Rd b/man/cudd_bdd_print_minterm.Rd similarity index 61% rename from man/print-CuddBDD-method.Rd rename to man/cudd_bdd_print_minterm.Rd index e298492..9f630a4 100644 --- a/man/print-CuddBDD-method.Rd +++ b/man/cudd_bdd_print_minterm.Rd @@ -1,18 +1,16 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/cudd_bdd.R -\name{print,CuddBDD-method} -\alias{print,CuddBDD-method} +\name{cudd_bdd_print_minterm} +\alias{cudd_bdd_print_minterm} \title{Print the minterm representation for a BDD} \usage{ -\S4method{print}{CuddBDD}(x, ...) +cudd_bdd_print_minterm(bdd) } \arguments{ -\item{x}{A [`CuddBDD`] instance.} - -\item{...}{Unused.} +\item{bdd}{A [`CuddBDD`] instance.} } \value{ -The input `x`, invisibly. +`NULL`, invisibly. } \description{ This uses the CUDD `PrintMinterm` implementation, which writes to R's diff --git a/man/cudd_bdd_truth_table.Rd b/man/cudd_bdd_truth_table.Rd new file mode 100644 index 0000000..da10810 --- /dev/null +++ b/man/cudd_bdd_truth_table.Rd @@ -0,0 +1,21 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cudd_bdd.R +\name{cudd_bdd_truth_table} +\alias{cudd_bdd_truth_table} +\title{Generate a truth table for a BDD} +\usage{ +cudd_bdd_truth_table(bdd, nvars = NULL) +} +\arguments{ +\item{bdd}{A [`CuddBDD`] instance.} + +\item{nvars}{Optional non-negative integer indicating how many variables to +include. Defaults to the manager size.} +} +\value{ +An integer matrix representing the truth table. +} +\description{ +Produces a matrix with one column per variable and a final column named +`value` containing the BDD evaluation for each assignment. +} diff --git a/man/print-CuddZDD-method.Rd b/man/cudd_zdd_print_minterm.Rd similarity index 61% rename from man/print-CuddZDD-method.Rd rename to man/cudd_zdd_print_minterm.Rd index f2d68e6..746754d 100644 --- a/man/print-CuddZDD-method.Rd +++ b/man/cudd_zdd_print_minterm.Rd @@ -1,18 +1,16 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/cudd_zdd.R -\name{print,CuddZDD-method} -\alias{print,CuddZDD-method} +\name{cudd_zdd_print_minterm} +\alias{cudd_zdd_print_minterm} \title{Print the minterm representation for a ZDD} \usage{ -\S4method{print}{CuddZDD}(x, ...) +cudd_zdd_print_minterm(zdd) } \arguments{ -\item{x}{A [`CuddZDD`] instance.} - -\item{...}{Unused.} +\item{zdd}{A [`CuddZDD`] instance.} } \value{ -The input `x`, invisibly. +`NULL`, invisibly. } \description{ This uses the CUDD `PrintMinterm` implementation, which writes to R's diff --git a/src/cudd_manager.cpp b/src/cudd_manager.cpp index c5e90bb..1916c14 100644 --- a/src/cudd_manager.cpp +++ b/src/cudd_manager.cpp @@ -1145,6 +1145,45 @@ extern "C" SEXP c_cudd_zdd_print_minterm(SEXP zdd_ptr) { return R_NilValue; } +extern "C" SEXP c_cudd_bdd_truth_table(SEXP bdd_ptr, SEXP nvars) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + int vars; + if (Rf_isNull(nvars)) { + vars = Cudd_ReadSize(bdd->manager()); + } else { + if (!Rf_isNumeric(nvars) || Rf_length(nvars) != 1) { + Rf_error("'nvars' must be a single numeric value."); + } + vars = Rf_asInteger(nvars); + if (vars == NA_INTEGER || vars < 0) { + Rf_error("'nvars' must be a non-negative integer."); + } + } + + if (vars > 30) { + Rf_error("'nvars' is too large to build a truth table."); + } + + R_xlen_t rows = static_cast(1ULL << vars); + int cols = vars + 1; + SEXP table = PROTECT(Rf_allocMatrix(INTSXP, rows, cols)); + int *data = INTEGER(table); + std::vector inputs(static_cast(vars), 0); + + for (R_xlen_t row = 0; row < rows; ++row) { + for (int var = 0; var < vars; ++var) { + int value = static_cast((row >> var) & 1ULL); + inputs[static_cast(var)] = value; + data[static_cast(var) * rows + row] = value; + } + BDD result = bdd->Eval(inputs.data()); + data[static_cast(vars) * rows + row] = result.IsOne() ? 1 : 0; + } + + UNPROTECT(1); + return table; +} + extern "C" SEXP c_cudd_bdd_print_debug(SEXP bdd_ptr, SEXP nvars, SEXP verbosity) { BDD *bdd = bdd_from_ptr(bdd_ptr); int vars; diff --git a/src/rcudd.h b/src/rcudd.h index 0c8f6a3..bf95791 100644 --- a/src/rcudd.h +++ b/src/rcudd.h @@ -55,6 +55,7 @@ extern "C" SEXP c_cudd_add_epd_print_minterm(SEXP add_ptr, SEXP nvars); extern "C" SEXP c_cudd_bdd_print_minterm(SEXP bdd_ptr); extern "C" SEXP c_cudd_add_print_minterm(SEXP add_ptr); extern "C" SEXP c_cudd_zdd_print_minterm(SEXP zdd_ptr); +extern "C" SEXP c_cudd_bdd_truth_table(SEXP bdd_ptr, SEXP nvars); extern "C" SEXP c_cudd_bdd_print_debug(SEXP bdd_ptr, SEXP nvars, SEXP verbosity); extern "C" SEXP c_cudd_bdd_dump_dot(SEXP bdd_ptr); extern "C" SEXP c_cudd_read_start_time(SEXP mgr_ptr); diff --git a/src/register.cpp b/src/register.cpp index 49a99ef..3581cd1 100644 --- a/src/register.cpp +++ b/src/register.cpp @@ -52,6 +52,7 @@ static const R_CallMethodDef CallEntries[] = { {"c_cudd_bdd_print_minterm", (DL_FUNC) &c_cudd_bdd_print_minterm, 1}, {"c_cudd_add_print_minterm", (DL_FUNC) &c_cudd_add_print_minterm, 1}, {"c_cudd_zdd_print_minterm", (DL_FUNC) &c_cudd_zdd_print_minterm, 1}, + {"c_cudd_bdd_truth_table", (DL_FUNC) &c_cudd_bdd_truth_table, 2}, {"c_cudd_bdd_print_debug", (DL_FUNC) &c_cudd_bdd_print_debug, 3}, {"c_cudd_bdd_dump_dot", (DL_FUNC) &c_cudd_bdd_dump_dot, 1}, {"c_cudd_read_start_time", (DL_FUNC) &c_cudd_read_start_time, 1}, diff --git a/tests/testthat/_snaps/cudd_diagrams.md b/tests/testthat/_snaps/cudd_diagrams.md index 2b8ba5a..990790f 100644 --- a/tests/testthat/_snaps/cudd_diagrams.md +++ b/tests/testthat/_snaps/cudd_diagrams.md @@ -8,9 +8,9 @@ --- Code - print_output + show_output Output - [1] "- 1" + [1] "" "- 1" --- @@ -37,14 +37,14 @@ --- Code - print_output + show_output Output - [1] "- 1" + [1] "" "- 1" # ZDD operations and conversions return expected classes Code - print_output + show_output Output - [1] "0 1" + [1] "" "0 1" diff --git a/tests/testthat/test_cudd_diagrams.R b/tests/testthat/test_cudd_diagrams.R index 08eab1e..a114e72 100644 --- a/tests/testthat/test_cudd_diagrams.R +++ b/tests/testthat/test_cudd_diagrams.R @@ -23,8 +23,12 @@ test_that("BDD operations and conversions return expected classes", { output <- capture.output(cudd_bdd_epd_print_minterm(bdd_one, 0L)) expect_snapshot(output) - print_output <- capture.output(print(bdd_one)) - expect_snapshot(print_output) + show_output <- capture.output(show(bdd_one)) + expect_snapshot(show_output) + + truth_table <- cudd_bdd_truth_table(bdd_var, nvars = 1L) + expect_identical(truth_table, matrix(c(0L, 1L, 0L, 1L), ncol = 2L, + dimnames = list(NULL, c("x1", "value")))) debug_output <- capture.output(cudd_bdd_print_debug(bdd_one, nvars = 1L, verbosity = 2L)) expect_snapshot(debug_output) @@ -55,8 +59,9 @@ test_that("ADD operations and conversions return expected classes", { output <- capture.output(cudd_add_epd_print_minterm(add_one, 0L)) expect_snapshot(output) - print_output <- capture.output(print(add_one)) - expect_snapshot(print_output) + show_output <- capture.output(show(add_one)) + expect_snapshot(show_output) + }) test_that("ZDD operations and conversions return expected classes", { @@ -78,6 +83,7 @@ test_that("ZDD operations and conversions return expected classes", { bdd_from_zdd <- cudd_zdd_to_bdd(zdd_var) expect_s4_class(bdd_from_zdd, "CuddBDD") - print_output <- capture.output(print(zdd_one)) - expect_snapshot(print_output) + show_output <- capture.output(show(zdd_one)) + expect_snapshot(show_output) + }) From 6bd2f472c9b0edaa81098b88bb342034072a326f Mon Sep 17 00:00:00 2001 From: MEO265 <99362508+MEO265@users.noreply.github.com> Date: Sat, 3 Jan 2026 21:54:24 +0100 Subject: [PATCH 5/5] Document reorder heuristic values (#7) --- NAMESPACE | 108 ++ R/cudd_bdd.R | 16 + R/cudd_bdd_methods.R | 1034 ++++++++++++++++++ R/cudd_manager.R | 21 + inst/examples/bdd_reduce_example.R | 27 + man/cudd_bdd_methods.Rd | 385 +++++++ man/cudd_bdd_restrict.Rd | 19 + man/cudd_manager_controls.Rd | 21 + src/cudd_manager.cpp | 1160 +++++++++++++++++++++ src/rcudd.h | 108 ++ src/register.cpp | 108 ++ tests/testthat/_snaps/cudd_bdd_methods.md | 4 + tests/testthat/test_cudd_bdd_methods.R | 55 + 13 files changed, 3066 insertions(+) create mode 100644 R/cudd_bdd_methods.R create mode 100644 inst/examples/bdd_reduce_example.R create mode 100644 man/cudd_bdd_methods.Rd create mode 100644 man/cudd_bdd_restrict.Rd create mode 100644 tests/testthat/_snaps/cudd_bdd_methods.md create mode 100644 tests/testthat/test_cudd_bdd_methods.R diff --git a/NAMESPACE b/NAMESPACE index 42a5697..bdddfec 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -16,21 +16,128 @@ export(cudd_autodyn_disable_zdd) export(cudd_autodyn_enable) export(cudd_autodyn_enable_zdd) export(cudd_background) +export(cudd_bdd_adj_permute_x) +export(cudd_bdd_and_abstract) +export(cudd_bdd_and_limit) +export(cudd_bdd_apa_print_minterm) +export(cudd_bdd_apa_print_minterm_exp) +export(cudd_bdd_approx_conj_decomp) +export(cudd_bdd_approx_disj_decomp) +export(cudd_bdd_biased_over_approx) +export(cudd_bdd_biased_under_approx) export(cudd_bdd_bind_var) +export(cudd_bdd_boolean_diff) +export(cudd_bdd_c_projection) +export(cudd_bdd_char_to_vect) +export(cudd_bdd_classify_support) +export(cudd_bdd_clipping_and) +export(cudd_bdd_clipping_and_abstract) +export(cudd_bdd_cof_minterm) +export(cudd_bdd_cofactor) +export(cudd_bdd_compose) +export(cudd_bdd_constrain) +export(cudd_bdd_constrain_decomp) +export(cudd_bdd_correlation) +export(cudd_bdd_correlation_weights) +export(cudd_bdd_count_leaves) +export(cudd_bdd_count_minterm) +export(cudd_bdd_count_path) +export(cudd_bdd_decreasing) +export(cudd_bdd_density) export(cudd_bdd_dump_dot) export(cudd_bdd_epd_print_minterm) +export(cudd_bdd_equiv_dc) +export(cudd_bdd_estimate_cofactor) +export(cudd_bdd_estimate_cofactor_simple) +export(cudd_bdd_eval) +export(cudd_bdd_exist_abstract) +export(cudd_bdd_factored_form_string) +export(cudd_bdd_find_essential) +export(cudd_bdd_gen_conj_decomp) +export(cudd_bdd_gen_disj_decomp) +export(cudd_bdd_increasing) +export(cudd_bdd_interpolate) +export(cudd_bdd_intersect) +export(cudd_bdd_is_cube) +export(cudd_bdd_is_one) +export(cudd_bdd_is_var) +export(cudd_bdd_is_var_essential) +export(cudd_bdd_is_zero) +export(cudd_bdd_isop) +export(cudd_bdd_ite) +export(cudd_bdd_ite_constant) +export(cudd_bdd_ite_formula) +export(cudd_bdd_iter_conj_decomp) +export(cudd_bdd_iter_disj_decomp) +export(cudd_bdd_largest_cube) +export(cudd_bdd_largest_prime_unate) +export(cudd_bdd_ldbl_count_minterm) +export(cudd_bdd_leq) +export(cudd_bdd_leq_unless) +export(cudd_bdd_li_compaction) +export(cudd_bdd_literal_set_intersection) +export(cudd_bdd_make_prime) +export(cudd_bdd_maximally_expand) +export(cudd_bdd_min_hamming_dist) +export(cudd_bdd_minimize) +export(cudd_bdd_nand) +export(cudd_bdd_nor) +export(cudd_bdd_np_and) export(cudd_bdd_one) +export(cudd_bdd_or_limit) +export(cudd_bdd_over_approx) +export(cudd_bdd_permute) +export(cudd_bdd_pick_one_cube) +export(cudd_bdd_pick_one_minterm) +export(cudd_bdd_port_to_zdd) +export(cudd_bdd_print) +export(cudd_bdd_print_cover) +export(cudd_bdd_print_cover_with_cube) export(cudd_bdd_print_debug) +export(cudd_bdd_print_factored_form) export(cudd_bdd_print_minterm) +export(cudd_bdd_print_two_literal_clauses) export(cudd_bdd_realign_disable) export(cudd_bdd_realign_enable) export(cudd_bdd_realignment_enabled) +export(cudd_bdd_remap_over_approx) +export(cudd_bdd_remap_under_approx) +export(cudd_bdd_restrict) +export(cudd_bdd_shortest_length) +export(cudd_bdd_shortest_path) +export(cudd_bdd_solve_eqn) +export(cudd_bdd_split_set) +export(cudd_bdd_squeeze) +export(cudd_bdd_subset_compress) +export(cudd_bdd_subset_heavy_branch) +export(cudd_bdd_subset_short_paths) +export(cudd_bdd_summary) +export(cudd_bdd_superset_compress) +export(cudd_bdd_superset_heavy_branch) +export(cudd_bdd_superset_short_paths) +export(cudd_bdd_support) +export(cudd_bdd_support_indices) +export(cudd_bdd_support_size) +export(cudd_bdd_swap_variables) export(cudd_bdd_to_add) export(cudd_bdd_to_zdd) +export(cudd_bdd_transfer) export(cudd_bdd_truth_table) export(cudd_bdd_unbind_var) +export(cudd_bdd_under_approx) +export(cudd_bdd_univ_abstract) export(cudd_bdd_var) +export(cudd_bdd_var_are_symmetric) +export(cudd_bdd_var_conj_decomp) +export(cudd_bdd_var_disj_decomp) export(cudd_bdd_var_is_bound) +export(cudd_bdd_var_is_dependent) +export(cudd_bdd_vector_compose) +export(cudd_bdd_verify_sol) +export(cudd_bdd_xnor) +export(cudd_bdd_xor_exist_abstract) +export(cudd_bdd_xor_method) +export(cudd_bdd_zdd_isop) export(cudd_bdd_zero) export(cudd_clear_error_code) export(cudd_clear_variable_names) @@ -95,6 +202,7 @@ export(cudd_read_symmviolation) export(cudd_read_time_limit) export(cudd_read_vars) export(cudd_read_zdd_size) +export(cudd_reduce_heap) export(cudd_reordering_reporting) export(cudd_reordering_status) export(cudd_reordering_status_zdd) diff --git a/R/cudd_bdd.R b/R/cudd_bdd.R index 4044e8b..d19e975 100644 --- a/R/cudd_bdd.R +++ b/R/cudd_bdd.R @@ -135,6 +135,22 @@ setMethod("^", signature(e1 = "CuddBDD", e2 = "CuddBDD"), function(e1, e2) { return(methods::new("CuddBDD", ptr = ptr, manager_ptr = .cudd_bdd_manager_ptr(e1))) }) +#' Restrict a BDD with a constraint +#' +#' Applies the CUDD `Restrict` operator to reduce a BDD given a constraint BDD. +#' +#' @param bdd A [`CuddBDD`] instance to restrict. +#' @param constraint A [`CuddBDD`] instance expressing the restriction. +#' @return A [`CuddBDD`] instance. +#' @export +cudd_bdd_restrict <- function(bdd, constraint) { + if (!.cudd_check_same_manager(bdd, constraint, "Restrict")) { + stop("Cannot restrict BDDs from different CuddManager instances.", call. = FALSE) + } + ptr <- .Call(c_cudd_bdd_restrict, .cudd_bdd_ptr(bdd), .cudd_bdd_ptr(constraint)) + return(methods::new("CuddBDD", ptr = ptr, manager_ptr = .cudd_bdd_manager_ptr(bdd))) +} + #' Print an EPD minterm count for a BDD #' #' This uses the CUDD `EpdPrintMinterm` implementation, which writes to R's diff --git a/R/cudd_bdd_methods.R b/R/cudd_bdd_methods.R new file mode 100644 index 0000000..f696ee6 --- /dev/null +++ b/R/cudd_bdd_methods.R @@ -0,0 +1,1034 @@ +.cudd_bdd_wrap <- function(ptr, bdd) { + return(methods::new("CuddBDD", ptr = ptr, manager_ptr = .cudd_bdd_manager_ptr(bdd))) +} + +.cudd_bdd_wrap_list <- function(ptrs, bdd) { + return(lapply(ptrs, .cudd_bdd_wrap, bdd = bdd)) +} + +.cudd_check_bdd_list_manager <- function(bdd, vars, op) { + for (var in vars) { + if (!.cudd_check_same_manager(bdd, var, op)) { + return(FALSE) + } + } + return(TRUE) +} + +.cudd_zdd_wrap <- function(ptr, bdd) { + return(methods::new("CuddZDD", ptr = ptr, manager_ptr = .cudd_bdd_manager_ptr(bdd))) +} + +#' Additional BDD methods +#' +#' Convenience wrappers for additional methods on CUDD BDD objects. +#' +#' @param bdd A [`CuddBDD`] instance. +#' @param other,cube,var,g,h,upper,bias,phases,ub,f,d,y_bdd Additional [`CuddBDD`] +#' instances used by the operation. +#' @param manager A [`CuddManager`] instance. +#' @param limit Optional non-negative integer limit passed to CUDD. +#' @param index,index1,index2,phase Integer index values used by the operation. +#' @param permut Integer vector describing a variable permutation. +#' @param x,y,vector,vars,x_vars,g_list Lists of [`CuddBDD`] instances. +#' @param nvars,num_vars,threshold Non-negative integer values used by the operation. +#' @param weight Optional integer vector used in shortest path calculations. +#' @param mode,verbosity,precision Integer values used for reporting. +#' @param max_depth,direction Integer values used by clipping operations. +#' @param safe Logical scalar controlling approximate operations. +#' @param quality,quality1,quality0 Numeric scalars controlling approximate operations. +#' @param minterm,inputs,y_index Integer vectors used by the operation. +#' @param prob Numeric vector of probabilities for correlation weights. +#' @param n Integer size for equation solving. +#' @param upper_bound Integer upper bound for min hamming distance. +#' @param hardlimit Logical scalar for short path routines. +#' @param m Numeric scalar used by split operations. +#' @return A [`CuddBDD`] instance, a logical scalar, numeric scalar, character +#' scalar, or list depending on the operation. +#' @name cudd_bdd_methods +NULL + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_is_zero <- function(bdd) { + return(.Call(c_cudd_bdd_is_zero, .cudd_bdd_ptr(bdd))) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_is_one <- function(bdd) { + return(.Call(c_cudd_bdd_is_one, .cudd_bdd_ptr(bdd))) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_is_cube <- function(bdd) { + return(.Call(c_cudd_bdd_is_cube, .cudd_bdd_ptr(bdd))) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_is_var <- function(bdd) { + return(.Call(c_cudd_bdd_is_var, .cudd_bdd_ptr(bdd))) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_ite_formula <- function(bdd) { + return(.Call(c_cudd_bdd_ite_formula, .cudd_bdd_ptr(bdd))) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_print <- function(bdd, nvars, verbosity = 1L) { + .Call(c_cudd_bdd_print, .cudd_bdd_ptr(bdd), nvars, verbosity) + return(invisible(NULL)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_summary <- function(bdd, nvars, mode = 0L) { + .Call(c_cudd_bdd_summary, .cudd_bdd_ptr(bdd), nvars, mode) + return(invisible(NULL)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_apa_print_minterm <- function(bdd, nvars) { + .Call(c_cudd_bdd_apa_print_minterm, .cudd_bdd_ptr(bdd), nvars) + return(invisible(NULL)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_apa_print_minterm_exp <- function(bdd, nvars, precision = 6L) { + .Call(c_cudd_bdd_apa_print_minterm_exp, .cudd_bdd_ptr(bdd), nvars, precision) + return(invisible(NULL)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_ldbl_count_minterm <- function(bdd, nvars) { + return(.Call(c_cudd_bdd_ldbl_count_minterm, .cudd_bdd_ptr(bdd), nvars)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_shortest_path <- function(bdd, weight = NULL) { + result <- .Call(c_cudd_bdd_shortest_path, .cudd_bdd_ptr(bdd), weight) + output <- list( + bdd = .cudd_bdd_wrap(result[[1L]], bdd), + support = result[[2L]], + length = result[[3L]] + ) + return(output) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_largest_cube <- function(bdd) { + result <- .Call(c_cudd_bdd_largest_cube, .cudd_bdd_ptr(bdd)) + output <- list( + bdd = .cudd_bdd_wrap(result[[1L]], bdd), + length = result[[2L]] + ) + return(output) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_shortest_length <- function(bdd, weight = NULL) { + return(.Call(c_cudd_bdd_shortest_length, .cudd_bdd_ptr(bdd), weight)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_equiv_dc <- function(bdd, g, d) { + if (!.cudd_check_same_manager(bdd, g, "EquivDC") || + !.cudd_check_same_manager(bdd, d, "EquivDC")) { + stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) + } + return(.Call(c_cudd_bdd_equiv_dc, .cudd_bdd_ptr(bdd), .cudd_bdd_ptr(g), .cudd_bdd_ptr(d))) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_cof_minterm <- function(bdd) { + return(.Call(c_cudd_bdd_cof_minterm, .cudd_bdd_ptr(bdd))) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_find_essential <- function(bdd) { + ptr <- .Call(c_cudd_bdd_find_essential, .cudd_bdd_ptr(bdd)) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_print_two_literal_clauses <- function(bdd) { # nolint: object_length_linter. + .Call(c_cudd_bdd_print_two_literal_clauses, .cudd_bdd_ptr(bdd)) + return(invisible(NULL)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_count_minterm <- function(bdd, nvars) { + return(.Call(c_cudd_bdd_count_minterm, .cudd_bdd_ptr(bdd), nvars)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_count_path <- function(bdd) { + return(.Call(c_cudd_bdd_count_path, .cudd_bdd_ptr(bdd))) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_support <- function(bdd) { + ptr <- .Call(c_cudd_bdd_support, .cudd_bdd_ptr(bdd)) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_support_size <- function(bdd) { + return(.Call(c_cudd_bdd_support_size, .cudd_bdd_ptr(bdd))) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_support_indices <- function(bdd) { + return(.Call(c_cudd_bdd_support_indices, .cudd_bdd_ptr(bdd))) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_classify_support <- function(bdd, other) { + if (!.cudd_check_same_manager(bdd, other, "ClassifySupport")) { + stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) + } + result <- .Call(c_cudd_bdd_classify_support, .cudd_bdd_ptr(bdd), .cudd_bdd_ptr(other)) + output <- .cudd_bdd_wrap_list(result, bdd) + names(output) <- c("common", "only_bdd", "only_other") + return(output) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_count_leaves <- function(bdd) { + return(.Call(c_cudd_bdd_count_leaves, .cudd_bdd_ptr(bdd))) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_density <- function(bdd, nvars) { + return(.Call(c_cudd_bdd_density, .cudd_bdd_ptr(bdd), nvars)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_under_approx <- function(bdd, num_vars, threshold = 0L, safe = FALSE, quality = 1.0) { + ptr <- .Call( + c_cudd_bdd_under_approx, + .cudd_bdd_ptr(bdd), + num_vars, + threshold, + safe, + quality + ) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_over_approx <- function(bdd, num_vars, threshold = 0L, safe = FALSE, quality = 1.0) { + ptr <- .Call( + c_cudd_bdd_over_approx, + .cudd_bdd_ptr(bdd), + num_vars, + threshold, + safe, + quality + ) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_remap_under_approx <- function(bdd, num_vars, threshold = 0L, quality = 1.0) { + ptr <- .Call( + c_cudd_bdd_remap_under_approx, + .cudd_bdd_ptr(bdd), + num_vars, + threshold, + quality + ) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_remap_over_approx <- function(bdd, num_vars, threshold = 0L, quality = 1.0) { + ptr <- .Call( + c_cudd_bdd_remap_over_approx, + .cudd_bdd_ptr(bdd), + num_vars, + threshold, + quality + ) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_biased_under_approx <- function(bdd, bias, num_vars, threshold = 0L, quality1 = 1.0, quality0 = 1.0) { + if (!.cudd_check_same_manager(bdd, bias, "BiasedUnderApprox")) { + stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) + } + ptr <- .Call( + c_cudd_bdd_biased_under_approx, + .cudd_bdd_ptr(bdd), + .cudd_bdd_ptr(bias), + num_vars, + threshold, + quality1, + quality0 + ) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_biased_over_approx <- function(bdd, bias, num_vars, threshold = 0L, quality1 = 1.0, quality0 = 1.0) { + if (!.cudd_check_same_manager(bdd, bias, "BiasedOverApprox")) { + stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) + } + ptr <- .Call( + c_cudd_bdd_biased_over_approx, + .cudd_bdd_ptr(bdd), + .cudd_bdd_ptr(bias), + num_vars, + threshold, + quality1, + quality0 + ) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_leq <- function(bdd, other) { + if (!.cudd_check_same_manager(bdd, other, "Leq")) { + stop("Cannot compare BDDs from different CuddManager instances.", call. = FALSE) + } + return(.Call(c_cudd_bdd_leq, .cudd_bdd_ptr(bdd), .cudd_bdd_ptr(other))) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_and_abstract <- function(bdd, other, cube, limit = 0L) { + if (!.cudd_check_same_manager(bdd, other, "AndAbstract") || + !.cudd_check_same_manager(bdd, cube, "AndAbstract")) { + stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) + } + ptr <- .Call( + c_cudd_bdd_and_abstract, + .cudd_bdd_ptr(bdd), + .cudd_bdd_ptr(other), + .cudd_bdd_ptr(cube), + limit + ) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_exist_abstract <- function(bdd, cube, limit = 0L) { + if (!.cudd_check_same_manager(bdd, cube, "ExistAbstract")) { + stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) + } + ptr <- .Call(c_cudd_bdd_exist_abstract, .cudd_bdd_ptr(bdd), .cudd_bdd_ptr(cube), limit) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_univ_abstract <- function(bdd, cube) { + if (!.cudd_check_same_manager(bdd, cube, "UnivAbstract")) { + stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) + } + ptr <- .Call(c_cudd_bdd_univ_abstract, .cudd_bdd_ptr(bdd), .cudd_bdd_ptr(cube)) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_xor_exist_abstract <- function(bdd, other, cube) { + if (!.cudd_check_same_manager(bdd, other, "XorExistAbstract") || + !.cudd_check_same_manager(bdd, cube, "XorExistAbstract")) { + stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) + } + ptr <- .Call( + c_cudd_bdd_xor_exist_abstract, + .cudd_bdd_ptr(bdd), + .cudd_bdd_ptr(other), + .cudd_bdd_ptr(cube) + ) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_boolean_diff <- function(bdd, index) { + ptr <- .Call(c_cudd_bdd_boolean_diff, .cudd_bdd_ptr(bdd), index) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_var_is_dependent <- function(bdd, var) { + if (!.cudd_check_same_manager(bdd, var, "VarIsDependent")) { + stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) + } + return(.Call(c_cudd_bdd_var_is_dependent, .cudd_bdd_ptr(bdd), .cudd_bdd_ptr(var))) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_correlation <- function(bdd, other) { + if (!.cudd_check_same_manager(bdd, other, "Correlation")) { + stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) + } + return(.Call(c_cudd_bdd_correlation, .cudd_bdd_ptr(bdd), .cudd_bdd_ptr(other))) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_correlation_weights <- function(bdd, other, prob) { + if (!.cudd_check_same_manager(bdd, other, "CorrelationWeights")) { + stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) + } + return(.Call(c_cudd_bdd_correlation_weights, .cudd_bdd_ptr(bdd), .cudd_bdd_ptr(other), prob)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_xor_method <- function(bdd, other) { + if (!.cudd_check_same_manager(bdd, other, "Xor")) { + stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) + } + ptr <- .Call(c_cudd_bdd_xor_method, .cudd_bdd_ptr(bdd), .cudd_bdd_ptr(other)) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_ite <- function(bdd, g, h, limit = 0L) { + if (!.cudd_check_same_manager(bdd, g, "Ite") || + !.cudd_check_same_manager(bdd, h, "Ite")) { + stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) + } + ptr <- .Call( + c_cudd_bdd_ite, + .cudd_bdd_ptr(bdd), + .cudd_bdd_ptr(g), + .cudd_bdd_ptr(h), + limit + ) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_ite_constant <- function(bdd, g, h) { + if (!.cudd_check_same_manager(bdd, g, "IteConstant") || + !.cudd_check_same_manager(bdd, h, "IteConstant")) { + stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) + } + ptr <- .Call(c_cudd_bdd_ite_constant, .cudd_bdd_ptr(bdd), .cudd_bdd_ptr(g), .cudd_bdd_ptr(h)) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_intersect <- function(bdd, other) { + if (!.cudd_check_same_manager(bdd, other, "Intersect")) { + stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) + } + ptr <- .Call(c_cudd_bdd_intersect, .cudd_bdd_ptr(bdd), .cudd_bdd_ptr(other)) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_and_limit <- function(bdd, other, limit = 0L) { + if (!.cudd_check_same_manager(bdd, other, "And")) { + stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) + } + ptr <- .Call(c_cudd_bdd_and_limit, .cudd_bdd_ptr(bdd), .cudd_bdd_ptr(other), limit) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_or_limit <- function(bdd, other, limit = 0L) { + if (!.cudd_check_same_manager(bdd, other, "Or")) { + stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) + } + ptr <- .Call(c_cudd_bdd_or_limit, .cudd_bdd_ptr(bdd), .cudd_bdd_ptr(other), limit) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_nand <- function(bdd, other) { + if (!.cudd_check_same_manager(bdd, other, "Nand")) { + stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) + } + ptr <- .Call(c_cudd_bdd_nand, .cudd_bdd_ptr(bdd), .cudd_bdd_ptr(other)) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_nor <- function(bdd, other) { + if (!.cudd_check_same_manager(bdd, other, "Nor")) { + stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) + } + ptr <- .Call(c_cudd_bdd_nor, .cudd_bdd_ptr(bdd), .cudd_bdd_ptr(other)) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_xnor <- function(bdd, other, limit = 0L) { + if (!.cudd_check_same_manager(bdd, other, "Xnor")) { + stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) + } + ptr <- .Call(c_cudd_bdd_xnor, .cudd_bdd_ptr(bdd), .cudd_bdd_ptr(other), limit) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_cofactor <- function(bdd, other) { + if (!.cudd_check_same_manager(bdd, other, "Cofactor")) { + stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) + } + ptr <- .Call(c_cudd_bdd_cofactor, .cudd_bdd_ptr(bdd), .cudd_bdd_ptr(other)) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_constrain <- function(bdd, other) { + if (!.cudd_check_same_manager(bdd, other, "Constrain")) { + stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) + } + ptr <- .Call(c_cudd_bdd_constrain, .cudd_bdd_ptr(bdd), .cudd_bdd_ptr(other)) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_compose <- function(bdd, other, index) { + if (!.cudd_check_same_manager(bdd, other, "Compose")) { + stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) + } + ptr <- .Call(c_cudd_bdd_compose, .cudd_bdd_ptr(bdd), .cudd_bdd_ptr(other), index) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_permute <- function(bdd, permut) { + ptr <- .Call(c_cudd_bdd_permute, .cudd_bdd_ptr(bdd), permut) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_swap_variables <- function(bdd, x, y) { + if (!.cudd_check_bdd_list_manager(bdd, x, "SwapVariables") || + !.cudd_check_bdd_list_manager(bdd, y, "SwapVariables")) { + stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) + } + ptr <- .Call(c_cudd_bdd_swap_variables, .cudd_bdd_ptr(bdd), lapply(x, .cudd_bdd_ptr), lapply(y, .cudd_bdd_ptr)) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_vector_compose <- function(bdd, vector) { + if (!.cudd_check_bdd_list_manager(bdd, vector, "VectorCompose")) { + stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) + } + ptr <- .Call(c_cudd_bdd_vector_compose, .cudd_bdd_ptr(bdd), lapply(vector, .cudd_bdd_ptr)) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_approx_conj_decomp <- function(bdd) { + result <- .Call(c_cudd_bdd_approx_conj_decomp, .cudd_bdd_ptr(bdd)) + output <- .cudd_bdd_wrap_list(result, bdd) + names(output) <- c("g", "h") + return(output) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_approx_disj_decomp <- function(bdd) { + result <- .Call(c_cudd_bdd_approx_disj_decomp, .cudd_bdd_ptr(bdd)) + output <- .cudd_bdd_wrap_list(result, bdd) + names(output) <- c("g", "h") + return(output) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_iter_conj_decomp <- function(bdd) { + result <- .Call(c_cudd_bdd_iter_conj_decomp, .cudd_bdd_ptr(bdd)) + output <- .cudd_bdd_wrap_list(result, bdd) + names(output) <- c("g", "h") + return(output) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_iter_disj_decomp <- function(bdd) { + result <- .Call(c_cudd_bdd_iter_disj_decomp, .cudd_bdd_ptr(bdd)) + output <- .cudd_bdd_wrap_list(result, bdd) + names(output) <- c("g", "h") + return(output) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_gen_conj_decomp <- function(bdd) { + result <- .Call(c_cudd_bdd_gen_conj_decomp, .cudd_bdd_ptr(bdd)) + output <- .cudd_bdd_wrap_list(result, bdd) + names(output) <- c("g", "h") + return(output) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_gen_disj_decomp <- function(bdd) { + result <- .Call(c_cudd_bdd_gen_disj_decomp, .cudd_bdd_ptr(bdd)) + output <- .cudd_bdd_wrap_list(result, bdd) + names(output) <- c("g", "h") + return(output) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_var_conj_decomp <- function(bdd) { + result <- .Call(c_cudd_bdd_var_conj_decomp, .cudd_bdd_ptr(bdd)) + output <- .cudd_bdd_wrap_list(result, bdd) + names(output) <- c("g", "h") + return(output) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_var_disj_decomp <- function(bdd) { + result <- .Call(c_cudd_bdd_var_disj_decomp, .cudd_bdd_ptr(bdd)) + output <- .cudd_bdd_wrap_list(result, bdd) + names(output) <- c("g", "h") + return(output) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_li_compaction <- function(bdd, other) { + if (!.cudd_check_same_manager(bdd, other, "LICompaction")) { + stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) + } + ptr <- .Call(c_cudd_bdd_li_compaction, .cudd_bdd_ptr(bdd), .cudd_bdd_ptr(other)) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_squeeze <- function(bdd, other) { + if (!.cudd_check_same_manager(bdd, other, "Squeeze")) { + stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) + } + ptr <- .Call(c_cudd_bdd_squeeze, .cudd_bdd_ptr(bdd), .cudd_bdd_ptr(other)) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_interpolate <- function(bdd, other) { + if (!.cudd_check_same_manager(bdd, other, "Interpolate")) { + stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) + } + ptr <- .Call(c_cudd_bdd_interpolate, .cudd_bdd_ptr(bdd), .cudd_bdd_ptr(other)) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_minimize <- function(bdd, other) { + if (!.cudd_check_same_manager(bdd, other, "Minimize")) { + stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) + } + ptr <- .Call(c_cudd_bdd_minimize, .cudd_bdd_ptr(bdd), .cudd_bdd_ptr(other)) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_subset_compress <- function(bdd, nvars, threshold) { + ptr <- .Call(c_cudd_bdd_subset_compress, .cudd_bdd_ptr(bdd), nvars, threshold) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_superset_compress <- function(bdd, nvars, threshold) { + ptr <- .Call(c_cudd_bdd_superset_compress, .cudd_bdd_ptr(bdd), nvars, threshold) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_literal_set_intersection <- function(bdd, other) { # nolint: object_length_linter. + if (!.cudd_check_same_manager(bdd, other, "LiteralSetIntersection")) { + stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) + } + ptr <- .Call(c_cudd_bdd_literal_set_intersection, .cudd_bdd_ptr(bdd), .cudd_bdd_ptr(other)) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_c_projection <- function(bdd, other) { + if (!.cudd_check_same_manager(bdd, other, "CProjection")) { + stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) + } + ptr <- .Call(c_cudd_bdd_c_projection, .cudd_bdd_ptr(bdd), .cudd_bdd_ptr(other)) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_min_hamming_dist <- function(bdd, minterm, upper_bound) { + result <- .Call(c_cudd_bdd_min_hamming_dist, .cudd_bdd_ptr(bdd), minterm, upper_bound) + names(result) <- c("distance", "minterm") + return(result) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_eval <- function(bdd, inputs) { + ptr <- .Call(c_cudd_bdd_eval, .cudd_bdd_ptr(bdd), inputs) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_decreasing <- function(bdd, index) { + ptr <- .Call(c_cudd_bdd_decreasing, .cudd_bdd_ptr(bdd), index) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_increasing <- function(bdd, index) { + ptr <- .Call(c_cudd_bdd_increasing, .cudd_bdd_ptr(bdd), index) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_make_prime <- function(bdd, other) { + if (!.cudd_check_same_manager(bdd, other, "MakePrime")) { + stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) + } + ptr <- .Call(c_cudd_bdd_make_prime, .cudd_bdd_ptr(bdd), .cudd_bdd_ptr(other)) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_subset_heavy_branch <- function(bdd, num_vars, threshold) { + ptr <- .Call(c_cudd_bdd_subset_heavy_branch, .cudd_bdd_ptr(bdd), num_vars, threshold) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_superset_heavy_branch <- function(bdd, num_vars, threshold) { + ptr <- .Call(c_cudd_bdd_superset_heavy_branch, .cudd_bdd_ptr(bdd), num_vars, threshold) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_subset_short_paths <- function(bdd, num_vars, threshold, hardlimit = FALSE) { + ptr <- .Call(c_cudd_bdd_subset_short_paths, .cudd_bdd_ptr(bdd), num_vars, threshold, hardlimit) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_superset_short_paths <- function(bdd, num_vars, threshold, hardlimit = FALSE) { + ptr <- .Call(c_cudd_bdd_superset_short_paths, .cudd_bdd_ptr(bdd), num_vars, threshold, hardlimit) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_print_cover <- function(bdd) { + .Call(c_cudd_bdd_print_cover, .cudd_bdd_ptr(bdd)) + return(invisible(NULL)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_print_cover_with_cube <- function(bdd, cube) { + if (!.cudd_check_same_manager(bdd, cube, "PrintCover")) { + stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) + } + .Call(c_cudd_bdd_print_cover_with_cube, .cudd_bdd_ptr(bdd), .cudd_bdd_ptr(cube)) + return(invisible(NULL)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_pick_one_cube <- function(bdd) { + return(.Call(c_cudd_bdd_pick_one_cube, .cudd_bdd_ptr(bdd))) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_pick_one_minterm <- function(bdd, vars) { + if (!.cudd_check_bdd_list_manager(bdd, vars, "PickOneMinterm")) { + stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) + } + ptr <- .Call(c_cudd_bdd_pick_one_minterm, .cudd_bdd_ptr(bdd), lapply(vars, .cudd_bdd_ptr)) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_isop <- function(bdd, upper) { + if (!.cudd_check_same_manager(bdd, upper, "Isop")) { + stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) + } + ptr <- .Call(c_cudd_bdd_isop, .cudd_bdd_ptr(bdd), .cudd_bdd_ptr(upper)) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_port_to_zdd <- function(bdd) { + ptr <- .Call(c_cudd_bdd_port_to_zdd, .cudd_bdd_ptr(bdd)) + return(.cudd_zdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_factored_form_string <- function(bdd) { + return(.Call(c_cudd_bdd_factored_form_string, .cudd_bdd_ptr(bdd))) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_print_factored_form <- function(bdd) { + .Call(c_cudd_bdd_print_factored_form, .cudd_bdd_ptr(bdd)) + return(invisible(NULL)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_clipping_and <- function(bdd, other, max_depth, direction = 0L) { + if (!.cudd_check_same_manager(bdd, other, "ClippingAnd")) { + stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) + } + ptr <- .Call( + c_cudd_bdd_clipping_and, + .cudd_bdd_ptr(bdd), + .cudd_bdd_ptr(other), + max_depth, + direction + ) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_clipping_and_abstract <- function(bdd, other, cube, max_depth, direction = 0L) { + if (!.cudd_check_same_manager(bdd, other, "ClippingAndAbstract") || + !.cudd_check_same_manager(bdd, cube, "ClippingAndAbstract")) { + stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) + } + ptr <- .Call( + c_cudd_bdd_clipping_and_abstract, + .cudd_bdd_ptr(bdd), + .cudd_bdd_ptr(other), + .cudd_bdd_ptr(cube), + max_depth, + direction + ) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_var_are_symmetric <- function(bdd, index1, index2) { + return(.Call(c_cudd_bdd_var_are_symmetric, .cudd_bdd_ptr(bdd), index1, index2)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_adj_permute_x <- function(bdd, x) { + if (!.cudd_check_bdd_list_manager(bdd, x, "AdjPermuteX")) { + stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) + } + ptr <- .Call(c_cudd_bdd_adj_permute_x, .cudd_bdd_ptr(bdd), lapply(x, .cudd_bdd_ptr)) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_is_var_essential <- function(bdd, index, phase) { + return(.Call(c_cudd_bdd_is_var_essential, .cudd_bdd_ptr(bdd), index, phase)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_np_and <- function(bdd, other) { + if (!.cudd_check_same_manager(bdd, other, "NPAnd")) { + stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) + } + ptr <- .Call(c_cudd_bdd_np_and, .cudd_bdd_ptr(bdd), .cudd_bdd_ptr(other)) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_constrain_decomp <- function(bdd) { + result <- .Call(c_cudd_bdd_constrain_decomp, .cudd_bdd_ptr(bdd)) + return(.cudd_bdd_wrap_list(result, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_char_to_vect <- function(bdd) { + result <- .Call(c_cudd_bdd_char_to_vect, .cudd_bdd_ptr(bdd)) + return(.cudd_bdd_wrap_list(result, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_leq_unless <- function(bdd, g, d) { + if (!.cudd_check_same_manager(bdd, g, "LeqUnless") || + !.cudd_check_same_manager(bdd, d, "LeqUnless")) { + stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) + } + return(.Call(c_cudd_bdd_leq_unless, .cudd_bdd_ptr(bdd), .cudd_bdd_ptr(g), .cudd_bdd_ptr(d))) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_maximally_expand <- function(bdd, ub, f) { + if (!.cudd_check_same_manager(bdd, ub, "MaximallyExpand") || + !.cudd_check_same_manager(bdd, f, "MaximallyExpand")) { + stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) + } + ptr <- .Call( + c_cudd_bdd_maximally_expand, + .cudd_bdd_ptr(bdd), + .cudd_bdd_ptr(ub), + .cudd_bdd_ptr(f) + ) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_largest_prime_unate <- function(bdd, phases) { + if (!.cudd_check_same_manager(bdd, phases, "LargestPrimeUnate")) { + stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) + } + ptr <- .Call(c_cudd_bdd_largest_prime_unate, .cudd_bdd_ptr(bdd), .cudd_bdd_ptr(phases)) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_solve_eqn <- function(bdd, y_bdd, n) { + if (!.cudd_check_same_manager(bdd, y_bdd, "SolveEqn")) { + stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) + } + result <- .Call(c_cudd_bdd_solve_eqn, .cudd_bdd_ptr(bdd), .cudd_bdd_ptr(y_bdd), n) + output <- list( + bdd = .cudd_bdd_wrap(result[[1L]], bdd), + g = .cudd_bdd_wrap_list(result[[2L]], bdd), + y_index = result[[3L]] + ) + return(output) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_verify_sol <- function(bdd, g_list, y_index) { + if (!.cudd_check_bdd_list_manager(bdd, g_list, "VerifySol")) { + stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) + } + ptr <- .Call( + c_cudd_bdd_verify_sol, + .cudd_bdd_ptr(bdd), + lapply(g_list, .cudd_bdd_ptr), + y_index + ) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_split_set <- function(bdd, x_vars, m) { + if (!.cudd_check_bdd_list_manager(bdd, x_vars, "SplitSet")) { + stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) + } + ptr <- .Call(c_cudd_bdd_split_set, .cudd_bdd_ptr(bdd), lapply(x_vars, .cudd_bdd_ptr), m) + return(.cudd_bdd_wrap(ptr, bdd)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_estimate_cofactor <- function(bdd, index, phase) { + return(.Call(c_cudd_bdd_estimate_cofactor, .cudd_bdd_ptr(bdd), index, phase)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_estimate_cofactor_simple <- function(bdd, index) { # nolint: object_length_linter. + return(.Call(c_cudd_bdd_estimate_cofactor_simple, .cudd_bdd_ptr(bdd), index)) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_zdd_isop <- function(bdd, upper) { + if (!.cudd_check_same_manager(bdd, upper, "zddIsop")) { + stop("Cannot combine BDDs from different CuddManager instances.", call. = FALSE) + } + result <- .Call(c_cudd_bdd_zdd_isop, .cudd_bdd_ptr(bdd), .cudd_bdd_ptr(upper)) + output <- list( + bdd = .cudd_bdd_wrap(result[[1L]], bdd), + zdd = .cudd_zdd_wrap(result[[2L]], bdd) + ) + return(output) +} + +#' @rdname cudd_bdd_methods +#' @export +cudd_bdd_transfer <- function(bdd, manager) { + ptr <- .Call(c_cudd_bdd_transfer, .cudd_bdd_ptr(bdd), .cudd_manager_ptr(manager)) + return(methods::new("CuddBDD", ptr = ptr, manager_ptr = .cudd_manager_ptr(manager))) +} diff --git a/R/cudd_manager.R b/R/cudd_manager.R index 0aba608..7511b65 100644 --- a/R/cudd_manager.R +++ b/R/cudd_manager.R @@ -195,6 +195,19 @@ cudd_read_reorderings <- function(manager) { #' Convenience wrappers around the CUDD manager API for tuning reordering, #' time limits, memory limits, and reading manager statistics. #' +#' Reordering heuristic integers follow the CUDD enum ordering: +#' `0` = `CUDD_REORDER_SAME`, `1` = `CUDD_REORDER_NONE`, `2` = `CUDD_REORDER_RANDOM`, +#' `3` = `CUDD_REORDER_RANDOM_PIVOT`, `4` = `CUDD_REORDER_SIFT`, +#' `5` = `CUDD_REORDER_SIFT_CONVERGE`, `6` = `CUDD_REORDER_SYMM_SIFT`, +#' `7` = `CUDD_REORDER_SYMM_SIFT_CONV`, `8` = `CUDD_REORDER_WINDOW2`, +#' `9` = `CUDD_REORDER_WINDOW3`, `10` = `CUDD_REORDER_WINDOW4`, +#' `11` = `CUDD_REORDER_WINDOW2_CONV`, `12` = `CUDD_REORDER_WINDOW3_CONV`, +#' `13` = `CUDD_REORDER_WINDOW4_CONV`, `14` = `CUDD_REORDER_GROUP_SIFT`, +#' `15` = `CUDD_REORDER_GROUP_SIFT_CONV`, `16` = `CUDD_REORDER_ANNEALING`, +#' `17` = `CUDD_REORDER_GENETIC`, `18` = `CUDD_REORDER_LINEAR`, +#' `19` = `CUDD_REORDER_LINEAR_CONVERGE`, `20` = `CUDD_REORDER_LAZY_SIFT`, +#' `21` = `CUDD_REORDER_EXACT`. +#' #' @param manager A [`CuddManager`] instance. #' @param st,tl,inc Numeric scalars used for time limit operations. #' @param method Optional integer reordering method (CUDD enum value). @@ -206,6 +219,8 @@ cudd_read_reorderings <- function(manager) { #' @param gc Integer CUDD aggregation type. #' @param recomb,symm,arc,pop,xovers Integers for genetic algorithm settings. #' @param factor Integer randomization factor. +#' @param heuristic Integer reordering heuristic (CUDD enum value). +#' @param minsize Integer minimum size for reordering. #' @param nr Integer next reordering value. #' @param max_mem Numeric memory limit. #' @param add A [`CuddADD`] instance. @@ -309,6 +324,12 @@ cudd_reordering_status_zdd <- function(manager) { return(.Call(c_cudd_reordering_status_zdd, .cudd_manager_ptr(manager))) } +#' @rdname cudd_manager_controls +#' @export +cudd_reduce_heap <- function(manager, heuristic = NULL, minsize = 0L) { + return(.Call(c_cudd_reduce_heap, .cudd_manager_ptr(manager), heuristic, minsize)) +} + #' @rdname cudd_manager_controls #' @export cudd_zdd_realignment_enabled <- function(manager) { diff --git a/inst/examples/bdd_reduce_example.R b/inst/examples/bdd_reduce_example.R new file mode 100644 index 0000000..d6519ef --- /dev/null +++ b/inst/examples/bdd_reduce_example.R @@ -0,0 +1,27 @@ +# Beispiel: großen BDD bauen, darstellen, mit Reduce reduzieren, erneut darstellen + +library(Rcudd) + +manager <- CuddManager() + +vars <- lapply(1:10, function(i) cudd_bdd_var(manager)) +names(vars) <- paste0("x", seq_along(vars)) + +clauses <- list( + vars$x1 * vars$x2, + vars$x3 + !vars$x4, + (vars$x5 * !vars$x6) + (vars$x7 * vars$x8), + vars$x9 ^ vars$x10, + (!vars$x1 * vars$x3) + (vars$x2 * !vars$x4) +) + +large_bdd <- Reduce(`+`, clauses) + +cat("Großer BDD (vor Reduce):\n") +cudd_bdd_print_debug(large_bdd, nvars = 10L, verbosity = 2L) + +restriction <- vars$x1 * !vars$x3 * vars$x5 +reduced_bdd <- cudd_bdd_restrict(large_bdd, restriction) + +cat("Reduzierter BDD (nach Reduce):\n") +cudd_bdd_print_debug(reduced_bdd, nvars = 10L, verbosity = 2L) diff --git a/man/cudd_bdd_methods.Rd b/man/cudd_bdd_methods.Rd new file mode 100644 index 0000000..06931bc --- /dev/null +++ b/man/cudd_bdd_methods.Rd @@ -0,0 +1,385 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cudd_bdd_methods.R +\name{cudd_bdd_methods} +\alias{cudd_bdd_methods} +\alias{cudd_bdd_is_zero} +\alias{cudd_bdd_is_one} +\alias{cudd_bdd_is_cube} +\alias{cudd_bdd_is_var} +\alias{cudd_bdd_ite_formula} +\alias{cudd_bdd_print} +\alias{cudd_bdd_summary} +\alias{cudd_bdd_apa_print_minterm} +\alias{cudd_bdd_apa_print_minterm_exp} +\alias{cudd_bdd_ldbl_count_minterm} +\alias{cudd_bdd_shortest_path} +\alias{cudd_bdd_largest_cube} +\alias{cudd_bdd_shortest_length} +\alias{cudd_bdd_equiv_dc} +\alias{cudd_bdd_cof_minterm} +\alias{cudd_bdd_find_essential} +\alias{cudd_bdd_print_two_literal_clauses} +\alias{cudd_bdd_count_minterm} +\alias{cudd_bdd_count_path} +\alias{cudd_bdd_support} +\alias{cudd_bdd_support_size} +\alias{cudd_bdd_support_indices} +\alias{cudd_bdd_classify_support} +\alias{cudd_bdd_count_leaves} +\alias{cudd_bdd_density} +\alias{cudd_bdd_under_approx} +\alias{cudd_bdd_over_approx} +\alias{cudd_bdd_remap_under_approx} +\alias{cudd_bdd_remap_over_approx} +\alias{cudd_bdd_biased_under_approx} +\alias{cudd_bdd_biased_over_approx} +\alias{cudd_bdd_leq} +\alias{cudd_bdd_and_abstract} +\alias{cudd_bdd_exist_abstract} +\alias{cudd_bdd_univ_abstract} +\alias{cudd_bdd_xor_exist_abstract} +\alias{cudd_bdd_boolean_diff} +\alias{cudd_bdd_var_is_dependent} +\alias{cudd_bdd_correlation} +\alias{cudd_bdd_correlation_weights} +\alias{cudd_bdd_xor_method} +\alias{cudd_bdd_ite} +\alias{cudd_bdd_ite_constant} +\alias{cudd_bdd_intersect} +\alias{cudd_bdd_and_limit} +\alias{cudd_bdd_or_limit} +\alias{cudd_bdd_nand} +\alias{cudd_bdd_nor} +\alias{cudd_bdd_xnor} +\alias{cudd_bdd_cofactor} +\alias{cudd_bdd_constrain} +\alias{cudd_bdd_compose} +\alias{cudd_bdd_permute} +\alias{cudd_bdd_swap_variables} +\alias{cudd_bdd_vector_compose} +\alias{cudd_bdd_approx_conj_decomp} +\alias{cudd_bdd_approx_disj_decomp} +\alias{cudd_bdd_iter_conj_decomp} +\alias{cudd_bdd_iter_disj_decomp} +\alias{cudd_bdd_gen_conj_decomp} +\alias{cudd_bdd_gen_disj_decomp} +\alias{cudd_bdd_var_conj_decomp} +\alias{cudd_bdd_var_disj_decomp} +\alias{cudd_bdd_li_compaction} +\alias{cudd_bdd_squeeze} +\alias{cudd_bdd_interpolate} +\alias{cudd_bdd_minimize} +\alias{cudd_bdd_subset_compress} +\alias{cudd_bdd_superset_compress} +\alias{cudd_bdd_literal_set_intersection} +\alias{cudd_bdd_c_projection} +\alias{cudd_bdd_min_hamming_dist} +\alias{cudd_bdd_eval} +\alias{cudd_bdd_decreasing} +\alias{cudd_bdd_increasing} +\alias{cudd_bdd_make_prime} +\alias{cudd_bdd_subset_heavy_branch} +\alias{cudd_bdd_superset_heavy_branch} +\alias{cudd_bdd_subset_short_paths} +\alias{cudd_bdd_superset_short_paths} +\alias{cudd_bdd_print_cover} +\alias{cudd_bdd_print_cover_with_cube} +\alias{cudd_bdd_pick_one_cube} +\alias{cudd_bdd_pick_one_minterm} +\alias{cudd_bdd_isop} +\alias{cudd_bdd_port_to_zdd} +\alias{cudd_bdd_factored_form_string} +\alias{cudd_bdd_print_factored_form} +\alias{cudd_bdd_clipping_and} +\alias{cudd_bdd_clipping_and_abstract} +\alias{cudd_bdd_var_are_symmetric} +\alias{cudd_bdd_adj_permute_x} +\alias{cudd_bdd_is_var_essential} +\alias{cudd_bdd_np_and} +\alias{cudd_bdd_constrain_decomp} +\alias{cudd_bdd_char_to_vect} +\alias{cudd_bdd_leq_unless} +\alias{cudd_bdd_maximally_expand} +\alias{cudd_bdd_largest_prime_unate} +\alias{cudd_bdd_solve_eqn} +\alias{cudd_bdd_verify_sol} +\alias{cudd_bdd_split_set} +\alias{cudd_bdd_estimate_cofactor} +\alias{cudd_bdd_estimate_cofactor_simple} +\alias{cudd_bdd_zdd_isop} +\alias{cudd_bdd_transfer} +\title{Additional BDD methods} +\usage{ +cudd_bdd_is_zero(bdd) + +cudd_bdd_is_one(bdd) + +cudd_bdd_is_cube(bdd) + +cudd_bdd_is_var(bdd) + +cudd_bdd_ite_formula(bdd) + +cudd_bdd_print(bdd, nvars, verbosity = 1L) + +cudd_bdd_summary(bdd, nvars, mode = 0L) + +cudd_bdd_apa_print_minterm(bdd, nvars) + +cudd_bdd_apa_print_minterm_exp(bdd, nvars, precision = 6L) + +cudd_bdd_ldbl_count_minterm(bdd, nvars) + +cudd_bdd_shortest_path(bdd, weight = NULL) + +cudd_bdd_largest_cube(bdd) + +cudd_bdd_shortest_length(bdd, weight = NULL) + +cudd_bdd_equiv_dc(bdd, g, d) + +cudd_bdd_cof_minterm(bdd) + +cudd_bdd_find_essential(bdd) + +cudd_bdd_print_two_literal_clauses(bdd) + +cudd_bdd_count_minterm(bdd, nvars) + +cudd_bdd_count_path(bdd) + +cudd_bdd_support(bdd) + +cudd_bdd_support_size(bdd) + +cudd_bdd_support_indices(bdd) + +cudd_bdd_classify_support(bdd, other) + +cudd_bdd_count_leaves(bdd) + +cudd_bdd_density(bdd, nvars) + +cudd_bdd_under_approx(bdd, num_vars, threshold = 0L, safe = FALSE, quality = 1) + +cudd_bdd_over_approx(bdd, num_vars, threshold = 0L, safe = FALSE, quality = 1) + +cudd_bdd_remap_under_approx(bdd, num_vars, threshold = 0L, quality = 1) + +cudd_bdd_remap_over_approx(bdd, num_vars, threshold = 0L, quality = 1) + +cudd_bdd_biased_under_approx( + bdd, + bias, + num_vars, + threshold = 0L, + quality1 = 1, + quality0 = 1 +) + +cudd_bdd_biased_over_approx( + bdd, + bias, + num_vars, + threshold = 0L, + quality1 = 1, + quality0 = 1 +) + +cudd_bdd_leq(bdd, other) + +cudd_bdd_and_abstract(bdd, other, cube, limit = 0L) + +cudd_bdd_exist_abstract(bdd, cube, limit = 0L) + +cudd_bdd_univ_abstract(bdd, cube) + +cudd_bdd_xor_exist_abstract(bdd, other, cube) + +cudd_bdd_boolean_diff(bdd, index) + +cudd_bdd_var_is_dependent(bdd, var) + +cudd_bdd_correlation(bdd, other) + +cudd_bdd_correlation_weights(bdd, other, prob) + +cudd_bdd_xor_method(bdd, other) + +cudd_bdd_ite(bdd, g, h, limit = 0L) + +cudd_bdd_ite_constant(bdd, g, h) + +cudd_bdd_intersect(bdd, other) + +cudd_bdd_and_limit(bdd, other, limit = 0L) + +cudd_bdd_or_limit(bdd, other, limit = 0L) + +cudd_bdd_nand(bdd, other) + +cudd_bdd_nor(bdd, other) + +cudd_bdd_xnor(bdd, other, limit = 0L) + +cudd_bdd_cofactor(bdd, other) + +cudd_bdd_constrain(bdd, other) + +cudd_bdd_compose(bdd, other, index) + +cudd_bdd_permute(bdd, permut) + +cudd_bdd_swap_variables(bdd, x, y) + +cudd_bdd_vector_compose(bdd, vector) + +cudd_bdd_approx_conj_decomp(bdd) + +cudd_bdd_approx_disj_decomp(bdd) + +cudd_bdd_iter_conj_decomp(bdd) + +cudd_bdd_iter_disj_decomp(bdd) + +cudd_bdd_gen_conj_decomp(bdd) + +cudd_bdd_gen_disj_decomp(bdd) + +cudd_bdd_var_conj_decomp(bdd) + +cudd_bdd_var_disj_decomp(bdd) + +cudd_bdd_li_compaction(bdd, other) + +cudd_bdd_squeeze(bdd, other) + +cudd_bdd_interpolate(bdd, other) + +cudd_bdd_minimize(bdd, other) + +cudd_bdd_subset_compress(bdd, nvars, threshold) + +cudd_bdd_superset_compress(bdd, nvars, threshold) + +cudd_bdd_literal_set_intersection(bdd, other) + +cudd_bdd_c_projection(bdd, other) + +cudd_bdd_min_hamming_dist(bdd, minterm, upper_bound) + +cudd_bdd_eval(bdd, inputs) + +cudd_bdd_decreasing(bdd, index) + +cudd_bdd_increasing(bdd, index) + +cudd_bdd_make_prime(bdd, other) + +cudd_bdd_subset_heavy_branch(bdd, num_vars, threshold) + +cudd_bdd_superset_heavy_branch(bdd, num_vars, threshold) + +cudd_bdd_subset_short_paths(bdd, num_vars, threshold, hardlimit = FALSE) + +cudd_bdd_superset_short_paths(bdd, num_vars, threshold, hardlimit = FALSE) + +cudd_bdd_print_cover(bdd) + +cudd_bdd_print_cover_with_cube(bdd, cube) + +cudd_bdd_pick_one_cube(bdd) + +cudd_bdd_pick_one_minterm(bdd, vars) + +cudd_bdd_isop(bdd, upper) + +cudd_bdd_port_to_zdd(bdd) + +cudd_bdd_factored_form_string(bdd) + +cudd_bdd_print_factored_form(bdd) + +cudd_bdd_clipping_and(bdd, other, max_depth, direction = 0L) + +cudd_bdd_clipping_and_abstract(bdd, other, cube, max_depth, direction = 0L) + +cudd_bdd_var_are_symmetric(bdd, index1, index2) + +cudd_bdd_adj_permute_x(bdd, x) + +cudd_bdd_is_var_essential(bdd, index, phase) + +cudd_bdd_np_and(bdd, other) + +cudd_bdd_constrain_decomp(bdd) + +cudd_bdd_char_to_vect(bdd) + +cudd_bdd_leq_unless(bdd, g, d) + +cudd_bdd_maximally_expand(bdd, ub, f) + +cudd_bdd_largest_prime_unate(bdd, phases) + +cudd_bdd_solve_eqn(bdd, y_bdd, n) + +cudd_bdd_verify_sol(bdd, g_list, y_index) + +cudd_bdd_split_set(bdd, x_vars, m) + +cudd_bdd_estimate_cofactor(bdd, index, phase) + +cudd_bdd_estimate_cofactor_simple(bdd, index) + +cudd_bdd_zdd_isop(bdd, upper) + +cudd_bdd_transfer(bdd, manager) +} +\arguments{ +\item{bdd}{A [`CuddBDD`] instance.} + +\item{nvars, num_vars, threshold}{Non-negative integer values used by the operation.} + +\item{mode, verbosity, precision}{Integer values used for reporting.} + +\item{weight}{Optional integer vector used in shortest path calculations.} + +\item{other, cube, var, g, h, upper, bias, phases, ub, f, d, y_bdd}{Additional [`CuddBDD`] +instances used by the operation.} + +\item{safe}{Logical scalar controlling approximate operations.} + +\item{quality, quality1, quality0}{Numeric scalars controlling approximate operations.} + +\item{limit}{Optional non-negative integer limit passed to CUDD.} + +\item{index, index1, index2, phase}{Integer index values used by the operation.} + +\item{prob}{Numeric vector of probabilities for correlation weights.} + +\item{permut}{Integer vector describing a variable permutation.} + +\item{x, y, vector, vars, x_vars, g_list}{Lists of [`CuddBDD`] instances.} + +\item{minterm, inputs, y_index}{Integer vectors used by the operation.} + +\item{upper_bound}{Integer upper bound for min hamming distance.} + +\item{hardlimit}{Logical scalar for short path routines.} + +\item{max_depth, direction}{Integer values used by clipping operations.} + +\item{n}{Integer size for equation solving.} + +\item{m}{Numeric scalar used by split operations.} + +\item{manager}{A [`CuddManager`] instance.} +} +\value{ +A [`CuddBDD`] instance, a logical scalar, numeric scalar, character + scalar, or list depending on the operation. +} +\description{ +Convenience wrappers for additional methods on CUDD BDD objects. +} diff --git a/man/cudd_bdd_restrict.Rd b/man/cudd_bdd_restrict.Rd new file mode 100644 index 0000000..4657efa --- /dev/null +++ b/man/cudd_bdd_restrict.Rd @@ -0,0 +1,19 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cudd_bdd.R +\name{cudd_bdd_restrict} +\alias{cudd_bdd_restrict} +\title{Restrict a BDD with a constraint} +\usage{ +cudd_bdd_restrict(bdd, constraint) +} +\arguments{ +\item{bdd}{A [`CuddBDD`] instance to restrict.} + +\item{constraint}{A [`CuddBDD`] instance expressing the restriction.} +} +\value{ +A [`CuddBDD`] instance. +} +\description{ +Applies the CUDD `Restrict` operator to reduce a BDD given a constraint BDD. +} diff --git a/man/cudd_manager_controls.Rd b/man/cudd_manager_controls.Rd index 6c93b7e..6625a7d 100644 --- a/man/cudd_manager_controls.Rd +++ b/man/cudd_manager_controls.Rd @@ -27,6 +27,7 @@ \alias{cudd_autodyn_enable_zdd} \alias{cudd_autodyn_disable_zdd} \alias{cudd_reordering_status_zdd} +\alias{cudd_reduce_heap} \alias{cudd_zdd_realignment_enabled} \alias{cudd_zdd_realign_enable} \alias{cudd_zdd_realign_disable} @@ -151,6 +152,8 @@ cudd_autodyn_disable_zdd(manager) cudd_reordering_status_zdd(manager) +cudd_reduce_heap(manager, heuristic = NULL, minsize = 0L) + cudd_zdd_realignment_enabled(manager) cudd_zdd_realign_enable(manager) @@ -306,6 +309,10 @@ cudd_bdd_var_is_bound(manager, index) \item{method}{Optional integer reordering method (CUDD enum value).} +\item{heuristic}{Integer reordering heuristic (CUDD enum value).} + +\item{minsize}{Integer minimum size for reordering.} + \item{add}{A [`CuddADD`] instance.} \item{mc, mr, smv, sms, max_live}{Integers used for cache/reordering limits.} @@ -331,3 +338,17 @@ A scalar value or `NULL`, depending on the call. Convenience wrappers around the CUDD manager API for tuning reordering, time limits, memory limits, and reading manager statistics. } +\details{ +Reordering heuristic integers follow the CUDD enum ordering: +`0` = `CUDD_REORDER_SAME`, `1` = `CUDD_REORDER_NONE`, `2` = `CUDD_REORDER_RANDOM`, +`3` = `CUDD_REORDER_RANDOM_PIVOT`, `4` = `CUDD_REORDER_SIFT`, +`5` = `CUDD_REORDER_SIFT_CONVERGE`, `6` = `CUDD_REORDER_SYMM_SIFT`, +`7` = `CUDD_REORDER_SYMM_SIFT_CONV`, `8` = `CUDD_REORDER_WINDOW2`, +`9` = `CUDD_REORDER_WINDOW3`, `10` = `CUDD_REORDER_WINDOW4`, +`11` = `CUDD_REORDER_WINDOW2_CONV`, `12` = `CUDD_REORDER_WINDOW3_CONV`, +`13` = `CUDD_REORDER_WINDOW4_CONV`, `14` = `CUDD_REORDER_GROUP_SIFT`, +`15` = `CUDD_REORDER_GROUP_SIFT_CONV`, `16` = `CUDD_REORDER_ANNEALING`, +`17` = `CUDD_REORDER_GENETIC`, `18` = `CUDD_REORDER_LINEAR`, +`19` = `CUDD_REORDER_LINEAR_CONVERGE`, `20` = `CUDD_REORDER_LAZY_SIFT`, +`21` = `CUDD_REORDER_EXACT`. +} diff --git a/src/cudd_manager.cpp b/src/cudd_manager.cpp index 1916c14..ce98f21 100644 --- a/src/cudd_manager.cpp +++ b/src/cudd_manager.cpp @@ -2,7 +2,9 @@ #include #include #include +#include #include +#include #include #include "cuddObj.hh" @@ -94,6 +96,210 @@ static ZDD *zdd_from_ptr(SEXP ptr) { return static_cast(addr); } +static SEXP bdd_to_xptr(const BDD &bdd) { + BDD *result = new BDD(bdd); + SEXP ptr = PROTECT(R_MakeExternalPtr(result, R_NilValue, R_NilValue)); + R_RegisterCFinalizerEx(ptr, bdd_finalizer, TRUE); + UNPROTECT(1); + return ptr; +} + +static SEXP zdd_to_xptr(const ZDD &zdd) { + ZDD *result = new ZDD(zdd); + SEXP ptr = PROTECT(R_MakeExternalPtr(result, R_NilValue, R_NilValue)); + R_RegisterCFinalizerEx(ptr, zdd_finalizer, TRUE); + UNPROTECT(1); + return ptr; +} + +static std::vector bdd_vector_from_list(SEXP list, const char *name) { + if (!Rf_isNewList(list)) { + Rf_error("'%s' must be a list of CuddBDD objects.", name); + } + R_xlen_t size = Rf_xlength(list); + std::vector result; + result.reserve(static_cast(size)); + for (R_xlen_t i = 0; i < size; ++i) { + SEXP item = VECTOR_ELT(list, i); + BDD *bdd = bdd_from_ptr(item); + result.push_back(*bdd); + } + return result; +} + +static SEXP bdd_list_from_vector(const std::vector &values) { + R_xlen_t size = static_cast(values.size()); + SEXP list = PROTECT(Rf_allocVector(VECSXP, size)); + for (R_xlen_t i = 0; i < size; ++i) { + SEXP ptr = bdd_to_xptr(values[static_cast(i)]); + SET_VECTOR_ELT(list, i, ptr); + } + UNPROTECT(1); + return list; +} + +static std::vector int_vector_from_sexp(SEXP vec, const char *name) { + if (!Rf_isInteger(vec)) { + Rf_error("'%s' must be an integer vector.", name); + } + R_xlen_t size = Rf_xlength(vec); + std::vector result; + result.reserve(static_cast(size)); + for (R_xlen_t i = 0; i < size; ++i) { + int value = INTEGER(vec)[i]; + if (value == NA_INTEGER) { + Rf_error("'%s' must not contain NA.", name); + } + result.push_back(value); + } + return result; +} + +static SEXP int_vector_to_sexp(const std::vector &values) { + R_xlen_t size = static_cast(values.size()); + SEXP vec = PROTECT(Rf_allocVector(INTSXP, size)); + for (R_xlen_t i = 0; i < size; ++i) { + INTEGER(vec)[i] = static_cast(values[static_cast(i)]); + } + UNPROTECT(1); + return vec; +} + +static std::vector double_vector_from_sexp(SEXP vec, const char *name) { + if (!Rf_isReal(vec)) { + Rf_error("'%s' must be a numeric vector.", name); + } + R_xlen_t size = Rf_xlength(vec); + std::vector result; + result.reserve(static_cast(size)); + for (R_xlen_t i = 0; i < size; ++i) { + double value = REAL(vec)[i]; + if (ISNA(value)) { + Rf_error("'%s' must not contain NA.", name); + } + result.push_back(value); + } + return result; +} + +struct BddFormula { + std::string text; + int precedence; +}; + +static std::string maybe_parenthesize(const BddFormula &formula, int min_precedence) { + if (formula.precedence < min_precedence) { + return "(" + formula.text + ")"; + } + return formula.text; +} + +static BddFormula bdd_ite_formula( + DdManager *mgr, + DdNode *node, + std::unordered_map &memo +) { + constexpr int prec_or = 1; + constexpr int prec_and = 2; + constexpr int prec_not = 3; + constexpr int prec_atom = 4; + auto make_not = [&](const BddFormula &expr) { + std::string inner = maybe_parenthesize(expr, prec_not); + return BddFormula{"!" + inner, prec_not}; + }; + auto make_and = [&](const BddFormula &lhs, const BddFormula &rhs) { + std::string left = maybe_parenthesize(lhs, prec_and); + std::string right = maybe_parenthesize(rhs, prec_and); + return BddFormula{left + " && " + right, prec_and}; + }; + auto make_or = [&](const BddFormula &lhs, const BddFormula &rhs) { + std::string left = maybe_parenthesize(lhs, prec_or); + std::string right = maybe_parenthesize(rhs, prec_or); + return BddFormula{left + " || " + right, prec_or}; + }; + auto make_xor = [&](const BddFormula &lhs, const BddFormula &rhs) { + return BddFormula{"xor(" + lhs.text + ", " + rhs.text + ")", prec_atom}; + }; + auto is_const = [mgr](DdNode *candidate, bool &value) { + DdNode *regular = Cudd_Regular(candidate); + if (!Cudd_IsConstant(regular)) { + return false; + } + bool is_one = regular == Cudd_ReadOne(mgr); + if (Cudd_IsComplement(candidate)) { + is_one = !is_one; + } + value = is_one; + return true; + }; + bool complemented = Cudd_IsComplement(node); + DdNode *regular = Cudd_Regular(node); + if (Cudd_IsConstant(regular)) { + bool is_one = regular == Cudd_ReadOne(mgr); + if (complemented) { + is_one = !is_one; + } + return BddFormula{is_one ? "TRUE" : "FALSE", prec_atom}; + } + if (complemented) { + return make_not(bdd_ite_formula(mgr, regular, memo)); + } + auto found = memo.find(regular); + if (found != memo.end()) { + return found->second; + } + int index = static_cast(Cudd_NodeReadIndex(regular)); + BddFormula var{"x" + std::to_string(index), prec_atom}; + DdNode *t = Cudd_T(regular); + DdNode *e = Cudd_E(regular); + bool t_comp = Cudd_IsComplement(t); + bool e_comp = Cudd_IsComplement(e); + DdNode *t_reg = Cudd_Regular(t); + DdNode *e_reg = Cudd_Regular(e); + bool t_const = false; + bool e_const = false; + bool t_value = false; + bool e_value = false; + t_const = is_const(t, t_value); + e_const = is_const(e, e_value); + BddFormula formula; + if (t_reg == e_reg && t_comp != e_comp) { + if (t_comp && !e_comp) { + BddFormula sub = bdd_ite_formula(mgr, e, memo); + formula = make_xor(var, sub); + } else { + BddFormula sub = bdd_ite_formula(mgr, t, memo); + formula = make_not(make_xor(var, sub)); + } + } else if (t_const && e_const) { + if (t_value == e_value) { + formula = BddFormula{t_value ? "TRUE" : "FALSE", prec_atom}; + } else if (t_value) { + formula = var; + } else { + formula = make_not(var); + } + } else if (t_const && t_value) { + BddFormula e_formula = bdd_ite_formula(mgr, e, memo); + formula = make_or(var, e_formula); + } else if (t_const && !t_value) { + BddFormula e_formula = bdd_ite_formula(mgr, e, memo); + formula = make_and(make_not(var), e_formula); + } else if (e_const && !e_value) { + BddFormula t_formula = bdd_ite_formula(mgr, t, memo); + formula = make_and(var, t_formula); + } else if (e_const && e_value) { + BddFormula t_formula = bdd_ite_formula(mgr, t, memo); + formula = make_or(make_not(var), t_formula); + } else { + BddFormula t_formula = bdd_ite_formula(mgr, t, memo); + BddFormula e_formula = bdd_ite_formula(mgr, e, memo); + formula = make_or(make_and(var, t_formula), make_and(make_not(var), e_formula)); + } + memo.emplace(regular, formula); + return formula; +} + extern "C" SEXP c_cudd_new() { try { Cudd *mgr = new Cudd(); @@ -364,6 +570,24 @@ extern "C" SEXP c_cudd_reordering_status_zdd(SEXP mgr_ptr) { return out; } +extern "C" SEXP c_cudd_reduce_heap(SEXP mgr_ptr, SEXP heuristic, SEXP minsize) { + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + int minsize_value = Rf_asInteger(minsize); + if (minsize_value == NA_INTEGER || minsize_value < 0) { + Rf_error("'minsize' must be a non-negative integer."); + } + if (Rf_isNull(heuristic)) { + mgr->ReduceHeap(CUDD_REORDER_SIFT, minsize_value); + } else { + int value = Rf_asInteger(heuristic); + if (value == NA_INTEGER) { + Rf_error("'heuristic' must be a valid integer."); + } + mgr->ReduceHeap(static_cast(value), minsize_value); + } + return R_NilValue; +} + extern "C" SEXP c_cudd_zdd_realignment_enabled(SEXP mgr_ptr) { Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); return Rf_ScalarLogical(mgr->zddRealignmentEnabled()); @@ -1025,6 +1249,942 @@ extern "C" SEXP c_cudd_bdd_xor(SEXP lhs_ptr, SEXP rhs_ptr) { return ptr; } +extern "C" SEXP c_cudd_bdd_restrict(SEXP bdd_ptr, SEXP constraint_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + BDD *constraint = bdd_from_ptr(constraint_ptr); + BDD *result = new BDD(bdd->Restrict(*constraint)); + SEXP ptr = PROTECT(R_MakeExternalPtr(result, R_NilValue, R_NilValue)); + R_RegisterCFinalizerEx(ptr, bdd_finalizer, TRUE); + UNPROTECT(1); + return ptr; +} + +extern "C" SEXP c_cudd_bdd_print(SEXP bdd_ptr, SEXP nvars, SEXP verbosity) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + int vars = Rf_asInteger(nvars); + int verb = Rf_asInteger(verbosity); + if (vars == NA_INTEGER || vars < 0 || verb == NA_INTEGER) { + Rf_error("'nvars' must be non-negative and 'verbosity' must be an integer."); + } + bdd->print(vars, verb); + return R_NilValue; +} + +extern "C" SEXP c_cudd_bdd_summary(SEXP bdd_ptr, SEXP nvars, SEXP mode) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + int vars = Rf_asInteger(nvars); + int summary_mode = Rf_asInteger(mode); + if (vars == NA_INTEGER || vars < 0 || summary_mode == NA_INTEGER) { + Rf_error("'nvars' must be non-negative and 'mode' must be an integer."); + } + bdd->summary(vars, summary_mode); + return R_NilValue; +} + +extern "C" SEXP c_cudd_bdd_ite_formula(SEXP bdd_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + std::unordered_map memo; + BddFormula formula = bdd_ite_formula(bdd->manager(), bdd->getNode(), memo); + return Rf_mkString(formula.text.c_str()); +} + +extern "C" SEXP c_cudd_bdd_apa_print_minterm(SEXP bdd_ptr, SEXP nvars) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + int vars = Rf_asInteger(nvars); + if (vars == NA_INTEGER || vars < 0) { + Rf_error("'nvars' must be a non-negative integer."); + } + bdd->ApaPrintMinterm(vars); + return R_NilValue; +} + +extern "C" SEXP c_cudd_bdd_apa_print_minterm_exp(SEXP bdd_ptr, SEXP nvars, SEXP precision) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + int vars = Rf_asInteger(nvars); + int prec = Rf_asInteger(precision); + if (vars == NA_INTEGER || vars < 0 || prec == NA_INTEGER) { + Rf_error("'nvars' must be non-negative and 'precision' must be an integer."); + } + bdd->ApaPrintMintermExp(vars, prec); + return R_NilValue; +} + +extern "C" SEXP c_cudd_bdd_ldbl_count_minterm(SEXP bdd_ptr, SEXP nvars) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + int vars = Rf_asInteger(nvars); + if (vars == NA_INTEGER || vars < 0) { + Rf_error("'nvars' must be a non-negative integer."); + } + long double count = bdd->LdblCountMinterm(vars); + return Rf_ScalarReal(static_cast(count)); +} + +extern "C" SEXP c_cudd_bdd_shortest_path(SEXP bdd_ptr, SEXP weight) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + int size = Cudd_ReadSize(bdd->manager()); + std::vector weight_vec; + int *weight_ptr = nullptr; + if (!Rf_isNull(weight)) { + weight_vec = int_vector_from_sexp(weight, "weight"); + if (static_cast(weight_vec.size()) != size) { + Rf_error("'weight' must have length %d.", size); + } + weight_ptr = weight_vec.data(); + } + std::vector support(static_cast(size), 0); + int length = 0; + BDD result = bdd->ShortestPath(weight_ptr, support.data(), &length); + SEXP output = PROTECT(Rf_allocVector(VECSXP, 3)); + SET_VECTOR_ELT(output, 0, bdd_to_xptr(result)); + SEXP support_vec = PROTECT(Rf_allocVector(INTSXP, size)); + for (int i = 0; i < size; ++i) { + INTEGER(support_vec)[i] = support[static_cast(i)]; + } + SET_VECTOR_ELT(output, 1, support_vec); + SET_VECTOR_ELT(output, 2, Rf_ScalarInteger(length)); + UNPROTECT(2); + return output; +} + +extern "C" SEXP c_cudd_bdd_largest_cube(SEXP bdd_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + int length = 0; + BDD result = bdd->LargestCube(&length); + SEXP output = PROTECT(Rf_allocVector(VECSXP, 2)); + SET_VECTOR_ELT(output, 0, bdd_to_xptr(result)); + SET_VECTOR_ELT(output, 1, Rf_ScalarInteger(length)); + UNPROTECT(1); + return output; +} + +extern "C" SEXP c_cudd_bdd_shortest_length(SEXP bdd_ptr, SEXP weight) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + int size = Cudd_ReadSize(bdd->manager()); + std::vector weight_vec; + int *weight_ptr = nullptr; + if (!Rf_isNull(weight)) { + weight_vec = int_vector_from_sexp(weight, "weight"); + if (static_cast(weight_vec.size()) != size) { + Rf_error("'weight' must have length %d.", size); + } + weight_ptr = weight_vec.data(); + } + int result = bdd->ShortestLength(weight_ptr); + return Rf_ScalarInteger(result); +} + +extern "C" SEXP c_cudd_bdd_equiv_dc(SEXP bdd_ptr, SEXP g_ptr, SEXP d_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + BDD *g = bdd_from_ptr(g_ptr); + BDD *d = bdd_from_ptr(d_ptr); + return Rf_ScalarLogical(bdd->EquivDC(*g, *d)); +} + +extern "C" SEXP c_cudd_bdd_cof_minterm(SEXP bdd_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + int size = Cudd_ReadSize(bdd->manager()); + double *values = bdd->CofMinterm(); + if (values == nullptr) { + Rf_error("Failed to compute cofactor minterms."); + } + SEXP output = PROTECT(Rf_allocVector(REALSXP, size + 1)); + for (int i = 0; i < size + 1; ++i) { + REAL(output)[i] = values[i]; + } + free(values); + UNPROTECT(1); + return output; +} + +extern "C" SEXP c_cudd_bdd_is_one(SEXP bdd_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + return Rf_ScalarLogical(bdd->IsOne()); +} + +extern "C" SEXP c_cudd_bdd_is_cube(SEXP bdd_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + return Rf_ScalarLogical(bdd->IsCube()); +} + +extern "C" SEXP c_cudd_bdd_find_essential(SEXP bdd_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + return bdd_to_xptr(bdd->FindEssential()); +} + +extern "C" SEXP c_cudd_bdd_print_two_literal_clauses(SEXP bdd_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + bdd->PrintTwoLiteralClauses(); + return R_NilValue; +} + +extern "C" SEXP c_cudd_bdd_count_minterm(SEXP bdd_ptr, SEXP nvars) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + int vars = Rf_asInteger(nvars); + if (vars == NA_INTEGER || vars < 0) { + Rf_error("'nvars' must be a non-negative integer."); + } + return Rf_ScalarReal(bdd->CountMinterm(vars)); +} + +extern "C" SEXP c_cudd_bdd_count_path(SEXP bdd_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + return Rf_ScalarReal(bdd->CountPath()); +} + +extern "C" SEXP c_cudd_bdd_support(SEXP bdd_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + return bdd_to_xptr(bdd->Support()); +} + +extern "C" SEXP c_cudd_bdd_support_size(SEXP bdd_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + return Rf_ScalarInteger(bdd->SupportSize()); +} + +extern "C" SEXP c_cudd_bdd_support_indices(SEXP bdd_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + std::vector indices = bdd->SupportIndices(); + return int_vector_to_sexp(indices); +} + +extern "C" SEXP c_cudd_bdd_classify_support(SEXP bdd_ptr, SEXP other_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + BDD *other = bdd_from_ptr(other_ptr); + BDD common; + BDD only_f; + BDD only_g; + bdd->ClassifySupport(*other, &common, &only_f, &only_g); + SEXP output = PROTECT(Rf_allocVector(VECSXP, 3)); + SET_VECTOR_ELT(output, 0, bdd_to_xptr(common)); + SET_VECTOR_ELT(output, 1, bdd_to_xptr(only_f)); + SET_VECTOR_ELT(output, 2, bdd_to_xptr(only_g)); + UNPROTECT(1); + return output; +} + +extern "C" SEXP c_cudd_bdd_count_leaves(SEXP bdd_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + return Rf_ScalarInteger(bdd->CountLeaves()); +} + +extern "C" SEXP c_cudd_bdd_density(SEXP bdd_ptr, SEXP nvars) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + int vars = Rf_asInteger(nvars); + if (vars == NA_INTEGER || vars < 0) { + Rf_error("'nvars' must be a non-negative integer."); + } + return Rf_ScalarReal(bdd->Density(vars)); +} + +extern "C" SEXP c_cudd_bdd_under_approx(SEXP bdd_ptr, SEXP num_vars, SEXP threshold, SEXP safe, SEXP quality) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + int vars = Rf_asInteger(num_vars); + int thresh = Rf_asInteger(threshold); + if (vars == NA_INTEGER || vars < 0 || thresh == NA_INTEGER) { + Rf_error("'num_vars' must be non-negative and 'threshold' must be an integer."); + } + bool safe_flag = Rf_asLogical(safe); + double qual = Rf_asReal(quality); + return bdd_to_xptr(bdd->UnderApprox(vars, thresh, safe_flag, qual)); +} + +extern "C" SEXP c_cudd_bdd_over_approx(SEXP bdd_ptr, SEXP num_vars, SEXP threshold, SEXP safe, SEXP quality) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + int vars = Rf_asInteger(num_vars); + int thresh = Rf_asInteger(threshold); + if (vars == NA_INTEGER || vars < 0 || thresh == NA_INTEGER) { + Rf_error("'num_vars' must be non-negative and 'threshold' must be an integer."); + } + bool safe_flag = Rf_asLogical(safe); + double qual = Rf_asReal(quality); + return bdd_to_xptr(bdd->OverApprox(vars, thresh, safe_flag, qual)); +} + +extern "C" SEXP c_cudd_bdd_remap_under_approx(SEXP bdd_ptr, SEXP num_vars, SEXP threshold, SEXP quality) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + int vars = Rf_asInteger(num_vars); + int thresh = Rf_asInteger(threshold); + if (vars == NA_INTEGER || vars < 0 || thresh == NA_INTEGER) { + Rf_error("'num_vars' must be non-negative and 'threshold' must be an integer."); + } + double qual = Rf_asReal(quality); + return bdd_to_xptr(bdd->RemapUnderApprox(vars, thresh, qual)); +} + +extern "C" SEXP c_cudd_bdd_remap_over_approx(SEXP bdd_ptr, SEXP num_vars, SEXP threshold, SEXP quality) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + int vars = Rf_asInteger(num_vars); + int thresh = Rf_asInteger(threshold); + if (vars == NA_INTEGER || vars < 0 || thresh == NA_INTEGER) { + Rf_error("'num_vars' must be non-negative and 'threshold' must be an integer."); + } + double qual = Rf_asReal(quality); + return bdd_to_xptr(bdd->RemapOverApprox(vars, thresh, qual)); +} + +extern "C" SEXP c_cudd_bdd_biased_under_approx(SEXP bdd_ptr, SEXP bias_ptr, SEXP num_vars, SEXP threshold, SEXP quality1, SEXP quality0) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + BDD *bias = bdd_from_ptr(bias_ptr); + int vars = Rf_asInteger(num_vars); + int thresh = Rf_asInteger(threshold); + if (vars == NA_INTEGER || vars < 0 || thresh == NA_INTEGER) { + Rf_error("'num_vars' must be non-negative and 'threshold' must be an integer."); + } + double qual1 = Rf_asReal(quality1); + double qual0 = Rf_asReal(quality0); + return bdd_to_xptr(bdd->BiasedUnderApprox(*bias, vars, thresh, qual1, qual0)); +} + +extern "C" SEXP c_cudd_bdd_biased_over_approx(SEXP bdd_ptr, SEXP bias_ptr, SEXP num_vars, SEXP threshold, SEXP quality1, SEXP quality0) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + BDD *bias = bdd_from_ptr(bias_ptr); + int vars = Rf_asInteger(num_vars); + int thresh = Rf_asInteger(threshold); + if (vars == NA_INTEGER || vars < 0 || thresh == NA_INTEGER) { + Rf_error("'num_vars' must be non-negative and 'threshold' must be an integer."); + } + double qual1 = Rf_asReal(quality1); + double qual0 = Rf_asReal(quality0); + return bdd_to_xptr(bdd->BiasedOverApprox(*bias, vars, thresh, qual1, qual0)); +} + +extern "C" SEXP c_cudd_bdd_clipping_and(SEXP bdd_ptr, SEXP other_ptr, SEXP max_depth, SEXP direction) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + BDD *other = bdd_from_ptr(other_ptr); + int depth = Rf_asInteger(max_depth); + int dir = Rf_asInteger(direction); + if (depth == NA_INTEGER || dir == NA_INTEGER) { + Rf_error("'max_depth' and 'direction' must be integers."); + } + return bdd_to_xptr(bdd->ClippingAnd(*other, depth, dir)); +} + +extern "C" SEXP c_cudd_bdd_clipping_and_abstract(SEXP bdd_ptr, SEXP other_ptr, SEXP cube_ptr, SEXP max_depth, SEXP direction) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + BDD *other = bdd_from_ptr(other_ptr); + BDD *cube = bdd_from_ptr(cube_ptr); + int depth = Rf_asInteger(max_depth); + int dir = Rf_asInteger(direction); + if (depth == NA_INTEGER || dir == NA_INTEGER) { + Rf_error("'max_depth' and 'direction' must be integers."); + } + return bdd_to_xptr(bdd->ClippingAndAbstract(*other, *cube, depth, dir)); +} + +extern "C" SEXP c_cudd_bdd_var_are_symmetric(SEXP bdd_ptr, SEXP index1, SEXP index2) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + int idx1 = Rf_asInteger(index1); + int idx2 = Rf_asInteger(index2); + if (idx1 == NA_INTEGER || idx1 < 0 || idx2 == NA_INTEGER || idx2 < 0) { + Rf_error("'index1' and 'index2' must be non-negative integers."); + } + return Rf_ScalarLogical(bdd->VarAreSymmetric(idx1, idx2)); +} + +extern "C" SEXP c_cudd_bdd_adj_permute_x(SEXP bdd_ptr, SEXP x_list) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + std::vector x = bdd_vector_from_list(x_list, "x"); + return bdd_to_xptr(bdd->AdjPermuteX(x)); +} + +extern "C" SEXP c_cudd_bdd_is_var_essential(SEXP bdd_ptr, SEXP index, SEXP phase) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + int idx = Rf_asInteger(index); + int phase_val = Rf_asInteger(phase); + if (idx == NA_INTEGER || idx < 0 || phase_val == NA_INTEGER) { + Rf_error("'index' must be non-negative and 'phase' must be an integer."); + } + return Rf_ScalarLogical(bdd->IsVarEssential(idx, phase_val)); +} + +extern "C" SEXP c_cudd_bdd_np_and(SEXP bdd_ptr, SEXP other_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + BDD *other = bdd_from_ptr(other_ptr); + return bdd_to_xptr(bdd->NPAnd(*other)); +} + +extern "C" SEXP c_cudd_bdd_constrain_decomp(SEXP bdd_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + std::vector parts = bdd->ConstrainDecomp(); + return bdd_list_from_vector(parts); +} + +extern "C" SEXP c_cudd_bdd_char_to_vect(SEXP bdd_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + std::vector parts = bdd->CharToVect(); + return bdd_list_from_vector(parts); +} + +extern "C" SEXP c_cudd_bdd_leq_unless(SEXP bdd_ptr, SEXP g_ptr, SEXP d_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + BDD *g = bdd_from_ptr(g_ptr); + BDD *d = bdd_from_ptr(d_ptr); + return Rf_ScalarLogical(bdd->LeqUnless(*g, *d)); +} + +extern "C" SEXP c_cudd_bdd_maximally_expand(SEXP bdd_ptr, SEXP ub_ptr, SEXP f_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + BDD *ub = bdd_from_ptr(ub_ptr); + BDD *f = bdd_from_ptr(f_ptr); + return bdd_to_xptr(bdd->MaximallyExpand(*ub, *f)); +} + +extern "C" SEXP c_cudd_bdd_largest_prime_unate(SEXP bdd_ptr, SEXP phases_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + BDD *phases = bdd_from_ptr(phases_ptr); + return bdd_to_xptr(bdd->LargestPrimeUnate(*phases)); +} + +extern "C" SEXP c_cudd_bdd_solve_eqn(SEXP bdd_ptr, SEXP y_ptr, SEXP n) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + BDD *y = bdd_from_ptr(y_ptr); + int count = Rf_asInteger(n); + if (count == NA_INTEGER || count < 0) { + Rf_error("'n' must be a non-negative integer."); + } + std::vector g; + int *y_index = nullptr; + BDD result = bdd->SolveEqn(*y, g, &y_index, count); + SEXP output = PROTECT(Rf_allocVector(VECSXP, 3)); + SET_VECTOR_ELT(output, 0, bdd_to_xptr(result)); + SET_VECTOR_ELT(output, 1, bdd_list_from_vector(g)); + SEXP y_index_vec = PROTECT(Rf_allocVector(INTSXP, count)); + for (int i = 0; i < count; ++i) { + INTEGER(y_index_vec)[i] = y_index[i]; + } + SET_VECTOR_ELT(output, 2, y_index_vec); + if (y_index != nullptr) { + free(y_index); + } + UNPROTECT(2); + return output; +} + +extern "C" SEXP c_cudd_bdd_verify_sol(SEXP bdd_ptr, SEXP g_list, SEXP y_index) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + std::vector g = bdd_vector_from_list(g_list, "g"); + std::vector y_index_vec = int_vector_from_sexp(y_index, "y_index"); + BDD result = bdd->VerifySol(g, y_index_vec.data()); + return bdd_to_xptr(result); +} + +extern "C" SEXP c_cudd_bdd_split_set(SEXP bdd_ptr, SEXP x_vars, SEXP m) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + std::vector vars = bdd_vector_from_list(x_vars, "x_vars"); + double value = Rf_asReal(m); + return bdd_to_xptr(bdd->SplitSet(vars, value)); +} + +extern "C" SEXP c_cudd_bdd_estimate_cofactor(SEXP bdd_ptr, SEXP index, SEXP phase) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + int idx = Rf_asInteger(index); + int phase_val = Rf_asInteger(phase); + if (idx == NA_INTEGER || idx < 0 || phase_val == NA_INTEGER) { + Rf_error("'index' must be non-negative and 'phase' must be an integer."); + } + return Rf_ScalarInteger(bdd->EstimateCofactor(idx, phase_val)); +} + +extern "C" SEXP c_cudd_bdd_estimate_cofactor_simple(SEXP bdd_ptr, SEXP index) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + int idx = Rf_asInteger(index); + if (idx == NA_INTEGER || idx < 0) { + Rf_error("'index' must be a non-negative integer."); + } + return Rf_ScalarInteger(bdd->EstimateCofactorSimple(idx)); +} + +extern "C" SEXP c_cudd_bdd_zdd_isop(SEXP bdd_ptr, SEXP upper_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + BDD *upper = bdd_from_ptr(upper_ptr); + ZDD *zdd = new ZDD(); + BDD result = bdd->zddIsop(*upper, zdd); + SEXP output = PROTECT(Rf_allocVector(VECSXP, 2)); + SET_VECTOR_ELT(output, 0, bdd_to_xptr(result)); + SEXP zdd_ptr = PROTECT(R_MakeExternalPtr(zdd, R_NilValue, R_NilValue)); + R_RegisterCFinalizerEx(zdd_ptr, zdd_finalizer, TRUE); + SET_VECTOR_ELT(output, 1, zdd_ptr); + UNPROTECT(2); + return output; +} + +extern "C" SEXP c_cudd_bdd_transfer(SEXP bdd_ptr, SEXP mgr_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + Cudd *mgr = cudd_manager_from_ptr(mgr_ptr); + return bdd_to_xptr(bdd->Transfer(*mgr)); +} + +extern "C" SEXP c_cudd_bdd_is_zero(SEXP bdd_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + return Rf_ScalarLogical(bdd->IsZero()); +} + +extern "C" SEXP c_cudd_bdd_is_var(SEXP bdd_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + return Rf_ScalarLogical(bdd->IsVar()); +} + +extern "C" SEXP c_cudd_bdd_leq(SEXP lhs_ptr, SEXP rhs_ptr) { + BDD *lhs = bdd_from_ptr(lhs_ptr); + BDD *rhs = bdd_from_ptr(rhs_ptr); + return Rf_ScalarLogical(lhs->Leq(*rhs)); +} + +extern "C" SEXP c_cudd_bdd_and_abstract(SEXP bdd_ptr, SEXP other_ptr, SEXP cube_ptr, SEXP limit) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + BDD *other = bdd_from_ptr(other_ptr); + BDD *cube = bdd_from_ptr(cube_ptr); + unsigned int lim = static_cast(Rf_asInteger(limit)); + return bdd_to_xptr(bdd->AndAbstract(*other, *cube, lim)); +} + +extern "C" SEXP c_cudd_bdd_exist_abstract(SEXP bdd_ptr, SEXP cube_ptr, SEXP limit) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + BDD *cube = bdd_from_ptr(cube_ptr); + unsigned int lim = static_cast(Rf_asInteger(limit)); + return bdd_to_xptr(bdd->ExistAbstract(*cube, lim)); +} + +extern "C" SEXP c_cudd_bdd_univ_abstract(SEXP bdd_ptr, SEXP cube_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + BDD *cube = bdd_from_ptr(cube_ptr); + return bdd_to_xptr(bdd->UnivAbstract(*cube)); +} + +extern "C" SEXP c_cudd_bdd_xor_exist_abstract(SEXP bdd_ptr, SEXP other_ptr, SEXP cube_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + BDD *other = bdd_from_ptr(other_ptr); + BDD *cube = bdd_from_ptr(cube_ptr); + return bdd_to_xptr(bdd->XorExistAbstract(*other, *cube)); +} + +extern "C" SEXP c_cudd_bdd_boolean_diff(SEXP bdd_ptr, SEXP index) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + int idx = Rf_asInteger(index); + if (idx == NA_INTEGER || idx < 0) { + Rf_error("'index' must be a non-negative integer."); + } + return bdd_to_xptr(bdd->BooleanDiff(idx)); +} + +extern "C" SEXP c_cudd_bdd_var_is_dependent(SEXP bdd_ptr, SEXP var_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + BDD *var = bdd_from_ptr(var_ptr); + return Rf_ScalarLogical(bdd->VarIsDependent(*var)); +} + +extern "C" SEXP c_cudd_bdd_correlation(SEXP bdd_ptr, SEXP other_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + BDD *other = bdd_from_ptr(other_ptr); + return Rf_ScalarReal(bdd->Correlation(*other)); +} + +extern "C" SEXP c_cudd_bdd_correlation_weights(SEXP bdd_ptr, SEXP other_ptr, SEXP prob) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + BDD *other = bdd_from_ptr(other_ptr); + std::vector prob_vec = double_vector_from_sexp(prob, "prob"); + int size = Cudd_ReadSize(bdd->manager()); + if (static_cast(prob_vec.size()) != size) { + Rf_error("'prob' must have length %d.", size); + } + double corr = bdd->CorrelationWeights(*other, prob_vec.data()); + return Rf_ScalarReal(corr); +} + +extern "C" SEXP c_cudd_bdd_xor_method(SEXP bdd_ptr, SEXP other_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + BDD *other = bdd_from_ptr(other_ptr); + return bdd_to_xptr(bdd->Xor(*other)); +} + +extern "C" SEXP c_cudd_bdd_ite(SEXP bdd_ptr, SEXP g_ptr, SEXP h_ptr, SEXP limit) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + BDD *g = bdd_from_ptr(g_ptr); + BDD *h = bdd_from_ptr(h_ptr); + unsigned int lim = static_cast(Rf_asInteger(limit)); + return bdd_to_xptr(bdd->Ite(*g, *h, lim)); +} + +extern "C" SEXP c_cudd_bdd_ite_constant(SEXP bdd_ptr, SEXP g_ptr, SEXP h_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + BDD *g = bdd_from_ptr(g_ptr); + BDD *h = bdd_from_ptr(h_ptr); + return bdd_to_xptr(bdd->IteConstant(*g, *h)); +} + +extern "C" SEXP c_cudd_bdd_intersect(SEXP bdd_ptr, SEXP other_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + BDD *other = bdd_from_ptr(other_ptr); + return bdd_to_xptr(bdd->Intersect(*other)); +} + +extern "C" SEXP c_cudd_bdd_and_limit(SEXP bdd_ptr, SEXP other_ptr, SEXP limit) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + BDD *other = bdd_from_ptr(other_ptr); + unsigned int lim = static_cast(Rf_asInteger(limit)); + return bdd_to_xptr(bdd->And(*other, lim)); +} + +extern "C" SEXP c_cudd_bdd_or_limit(SEXP bdd_ptr, SEXP other_ptr, SEXP limit) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + BDD *other = bdd_from_ptr(other_ptr); + unsigned int lim = static_cast(Rf_asInteger(limit)); + return bdd_to_xptr(bdd->Or(*other, lim)); +} + +extern "C" SEXP c_cudd_bdd_nand(SEXP bdd_ptr, SEXP other_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + BDD *other = bdd_from_ptr(other_ptr); + return bdd_to_xptr(bdd->Nand(*other)); +} + +extern "C" SEXP c_cudd_bdd_nor(SEXP bdd_ptr, SEXP other_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + BDD *other = bdd_from_ptr(other_ptr); + return bdd_to_xptr(bdd->Nor(*other)); +} + +extern "C" SEXP c_cudd_bdd_xnor(SEXP bdd_ptr, SEXP other_ptr, SEXP limit) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + BDD *other = bdd_from_ptr(other_ptr); + unsigned int lim = static_cast(Rf_asInteger(limit)); + return bdd_to_xptr(bdd->Xnor(*other, lim)); +} + +extern "C" SEXP c_cudd_bdd_cofactor(SEXP bdd_ptr, SEXP other_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + BDD *other = bdd_from_ptr(other_ptr); + return bdd_to_xptr(bdd->Cofactor(*other)); +} + +extern "C" SEXP c_cudd_bdd_constrain(SEXP bdd_ptr, SEXP other_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + BDD *other = bdd_from_ptr(other_ptr); + return bdd_to_xptr(bdd->Constrain(*other)); +} + +extern "C" SEXP c_cudd_bdd_compose(SEXP bdd_ptr, SEXP other_ptr, SEXP index) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + BDD *other = bdd_from_ptr(other_ptr); + int idx = Rf_asInteger(index); + if (idx == NA_INTEGER || idx < 0) { + Rf_error("'index' must be a non-negative integer."); + } + return bdd_to_xptr(bdd->Compose(*other, idx)); +} + +extern "C" SEXP c_cudd_bdd_permute(SEXP bdd_ptr, SEXP permut) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + std::vector perm = int_vector_from_sexp(permut, "permut"); + return bdd_to_xptr(bdd->Permute(perm.data())); +} + +extern "C" SEXP c_cudd_bdd_swap_variables(SEXP bdd_ptr, SEXP x_list, SEXP y_list) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + std::vector x = bdd_vector_from_list(x_list, "x"); + std::vector y = bdd_vector_from_list(y_list, "y"); + return bdd_to_xptr(bdd->SwapVariables(x, y)); +} + +extern "C" SEXP c_cudd_bdd_vector_compose(SEXP bdd_ptr, SEXP vector_list) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + std::vector vec = bdd_vector_from_list(vector_list, "vector"); + return bdd_to_xptr(bdd->VectorCompose(vec)); +} + +extern "C" SEXP c_cudd_bdd_approx_conj_decomp(SEXP bdd_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + BDD g; + BDD h; + bdd->ApproxConjDecomp(&g, &h); + SEXP output = PROTECT(Rf_allocVector(VECSXP, 2)); + SET_VECTOR_ELT(output, 0, bdd_to_xptr(g)); + SET_VECTOR_ELT(output, 1, bdd_to_xptr(h)); + UNPROTECT(1); + return output; +} + +extern "C" SEXP c_cudd_bdd_approx_disj_decomp(SEXP bdd_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + BDD g; + BDD h; + bdd->ApproxDisjDecomp(&g, &h); + SEXP output = PROTECT(Rf_allocVector(VECSXP, 2)); + SET_VECTOR_ELT(output, 0, bdd_to_xptr(g)); + SET_VECTOR_ELT(output, 1, bdd_to_xptr(h)); + UNPROTECT(1); + return output; +} + +extern "C" SEXP c_cudd_bdd_iter_conj_decomp(SEXP bdd_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + BDD g; + BDD h; + bdd->IterConjDecomp(&g, &h); + SEXP output = PROTECT(Rf_allocVector(VECSXP, 2)); + SET_VECTOR_ELT(output, 0, bdd_to_xptr(g)); + SET_VECTOR_ELT(output, 1, bdd_to_xptr(h)); + UNPROTECT(1); + return output; +} + +extern "C" SEXP c_cudd_bdd_iter_disj_decomp(SEXP bdd_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + BDD g; + BDD h; + bdd->IterDisjDecomp(&g, &h); + SEXP output = PROTECT(Rf_allocVector(VECSXP, 2)); + SET_VECTOR_ELT(output, 0, bdd_to_xptr(g)); + SET_VECTOR_ELT(output, 1, bdd_to_xptr(h)); + UNPROTECT(1); + return output; +} + +extern "C" SEXP c_cudd_bdd_gen_conj_decomp(SEXP bdd_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + BDD g; + BDD h; + bdd->GenConjDecomp(&g, &h); + SEXP output = PROTECT(Rf_allocVector(VECSXP, 2)); + SET_VECTOR_ELT(output, 0, bdd_to_xptr(g)); + SET_VECTOR_ELT(output, 1, bdd_to_xptr(h)); + UNPROTECT(1); + return output; +} + +extern "C" SEXP c_cudd_bdd_gen_disj_decomp(SEXP bdd_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + BDD g; + BDD h; + bdd->GenDisjDecomp(&g, &h); + SEXP output = PROTECT(Rf_allocVector(VECSXP, 2)); + SET_VECTOR_ELT(output, 0, bdd_to_xptr(g)); + SET_VECTOR_ELT(output, 1, bdd_to_xptr(h)); + UNPROTECT(1); + return output; +} + +extern "C" SEXP c_cudd_bdd_var_conj_decomp(SEXP bdd_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + BDD g; + BDD h; + bdd->VarConjDecomp(&g, &h); + SEXP output = PROTECT(Rf_allocVector(VECSXP, 2)); + SET_VECTOR_ELT(output, 0, bdd_to_xptr(g)); + SET_VECTOR_ELT(output, 1, bdd_to_xptr(h)); + UNPROTECT(1); + return output; +} + +extern "C" SEXP c_cudd_bdd_var_disj_decomp(SEXP bdd_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + BDD g; + BDD h; + bdd->VarDisjDecomp(&g, &h); + SEXP output = PROTECT(Rf_allocVector(VECSXP, 2)); + SET_VECTOR_ELT(output, 0, bdd_to_xptr(g)); + SET_VECTOR_ELT(output, 1, bdd_to_xptr(h)); + UNPROTECT(1); + return output; +} + +extern "C" SEXP c_cudd_bdd_li_compaction(SEXP bdd_ptr, SEXP other_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + BDD *other = bdd_from_ptr(other_ptr); + return bdd_to_xptr(bdd->LICompaction(*other)); +} + +extern "C" SEXP c_cudd_bdd_squeeze(SEXP bdd_ptr, SEXP other_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + BDD *other = bdd_from_ptr(other_ptr); + return bdd_to_xptr(bdd->Squeeze(*other)); +} + +extern "C" SEXP c_cudd_bdd_interpolate(SEXP bdd_ptr, SEXP other_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + BDD *other = bdd_from_ptr(other_ptr); + return bdd_to_xptr(bdd->Interpolate(*other)); +} + +extern "C" SEXP c_cudd_bdd_minimize(SEXP bdd_ptr, SEXP other_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + BDD *other = bdd_from_ptr(other_ptr); + return bdd_to_xptr(bdd->Minimize(*other)); +} + +extern "C" SEXP c_cudd_bdd_subset_compress(SEXP bdd_ptr, SEXP nvars, SEXP threshold) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + int vars = Rf_asInteger(nvars); + int thresh = Rf_asInteger(threshold); + if (vars == NA_INTEGER || vars < 0 || thresh == NA_INTEGER) { + Rf_error("'nvars' must be non-negative and 'threshold' must be an integer."); + } + return bdd_to_xptr(bdd->SubsetCompress(vars, thresh)); +} + +extern "C" SEXP c_cudd_bdd_superset_compress(SEXP bdd_ptr, SEXP nvars, SEXP threshold) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + int vars = Rf_asInteger(nvars); + int thresh = Rf_asInteger(threshold); + if (vars == NA_INTEGER || vars < 0 || thresh == NA_INTEGER) { + Rf_error("'nvars' must be non-negative and 'threshold' must be an integer."); + } + return bdd_to_xptr(bdd->SupersetCompress(vars, thresh)); +} + +extern "C" SEXP c_cudd_bdd_literal_set_intersection(SEXP bdd_ptr, SEXP other_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + BDD *other = bdd_from_ptr(other_ptr); + return bdd_to_xptr(bdd->LiteralSetIntersection(*other)); +} + +extern "C" SEXP c_cudd_bdd_c_projection(SEXP bdd_ptr, SEXP other_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + BDD *other = bdd_from_ptr(other_ptr); + return bdd_to_xptr(bdd->CProjection(*other)); +} + +extern "C" SEXP c_cudd_bdd_min_hamming_dist(SEXP bdd_ptr, SEXP minterm, SEXP upper_bound) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + std::vector minterm_vec = int_vector_from_sexp(minterm, "minterm"); + int bound = Rf_asInteger(upper_bound); + if (bound == NA_INTEGER) { + Rf_error("'upper_bound' must be an integer."); + } + int result = bdd->MinHammingDist(minterm_vec.data(), bound); + SEXP output = PROTECT(Rf_allocVector(VECSXP, 2)); + SET_VECTOR_ELT(output, 0, Rf_ScalarInteger(result)); + SEXP minterm_out = PROTECT(Rf_allocVector(INTSXP, minterm_vec.size())); + for (R_xlen_t i = 0; i < static_cast(minterm_vec.size()); ++i) { + INTEGER(minterm_out)[i] = minterm_vec[static_cast(i)]; + } + SET_VECTOR_ELT(output, 1, minterm_out); + UNPROTECT(2); + return output; +} + +extern "C" SEXP c_cudd_bdd_eval(SEXP bdd_ptr, SEXP inputs) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + std::vector values = int_vector_from_sexp(inputs, "inputs"); + return bdd_to_xptr(bdd->Eval(values.data())); +} + +extern "C" SEXP c_cudd_bdd_decreasing(SEXP bdd_ptr, SEXP index) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + int idx = Rf_asInteger(index); + if (idx == NA_INTEGER || idx < 0) { + Rf_error("'index' must be a non-negative integer."); + } + return bdd_to_xptr(bdd->Decreasing(idx)); +} + +extern "C" SEXP c_cudd_bdd_increasing(SEXP bdd_ptr, SEXP index) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + int idx = Rf_asInteger(index); + if (idx == NA_INTEGER || idx < 0) { + Rf_error("'index' must be a non-negative integer."); + } + return bdd_to_xptr(bdd->Increasing(idx)); +} + +extern "C" SEXP c_cudd_bdd_make_prime(SEXP bdd_ptr, SEXP other_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + BDD *other = bdd_from_ptr(other_ptr); + return bdd_to_xptr(bdd->MakePrime(*other)); +} + +extern "C" SEXP c_cudd_bdd_subset_heavy_branch(SEXP bdd_ptr, SEXP num_vars, SEXP threshold) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + int vars = Rf_asInteger(num_vars); + int thresh = Rf_asInteger(threshold); + if (vars == NA_INTEGER || vars < 0 || thresh == NA_INTEGER) { + Rf_error("'num_vars' must be non-negative and 'threshold' must be an integer."); + } + return bdd_to_xptr(bdd->SubsetHeavyBranch(vars, thresh)); +} + +extern "C" SEXP c_cudd_bdd_superset_heavy_branch(SEXP bdd_ptr, SEXP num_vars, SEXP threshold) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + int vars = Rf_asInteger(num_vars); + int thresh = Rf_asInteger(threshold); + if (vars == NA_INTEGER || vars < 0 || thresh == NA_INTEGER) { + Rf_error("'num_vars' must be non-negative and 'threshold' must be an integer."); + } + return bdd_to_xptr(bdd->SupersetHeavyBranch(vars, thresh)); +} + +extern "C" SEXP c_cudd_bdd_subset_short_paths(SEXP bdd_ptr, SEXP num_vars, SEXP threshold, SEXP hardlimit) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + int vars = Rf_asInteger(num_vars); + int thresh = Rf_asInteger(threshold); + if (vars == NA_INTEGER || vars < 0 || thresh == NA_INTEGER) { + Rf_error("'num_vars' must be non-negative and 'threshold' must be an integer."); + } + bool hard = Rf_asLogical(hardlimit); + return bdd_to_xptr(bdd->SubsetShortPaths(vars, thresh, hard)); +} + +extern "C" SEXP c_cudd_bdd_superset_short_paths(SEXP bdd_ptr, SEXP num_vars, SEXP threshold, SEXP hardlimit) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + int vars = Rf_asInteger(num_vars); + int thresh = Rf_asInteger(threshold); + if (vars == NA_INTEGER || vars < 0 || thresh == NA_INTEGER) { + Rf_error("'num_vars' must be non-negative and 'threshold' must be an integer."); + } + bool hard = Rf_asLogical(hardlimit); + return bdd_to_xptr(bdd->SupersetShortPaths(vars, thresh, hard)); +} + +extern "C" SEXP c_cudd_bdd_print_cover(SEXP bdd_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + bdd->PrintCover(); + return R_NilValue; +} + +extern "C" SEXP c_cudd_bdd_print_cover_with_cube(SEXP bdd_ptr, SEXP cube_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + BDD *cube = bdd_from_ptr(cube_ptr); + bdd->PrintCover(*cube); + return R_NilValue; +} + +extern "C" SEXP c_cudd_bdd_pick_one_cube(SEXP bdd_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + int size = Cudd_ReadSize(bdd->manager()); + std::vector buffer(static_cast(size) + 1, '\0'); + bdd->PickOneCube(buffer.data()); + return Rf_mkString(buffer.data()); +} + +extern "C" SEXP c_cudd_bdd_pick_one_minterm(SEXP bdd_ptr, SEXP vars_list) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + std::vector vars = bdd_vector_from_list(vars_list, "vars"); + return bdd_to_xptr(bdd->PickOneMinterm(vars)); +} + +extern "C" SEXP c_cudd_bdd_isop(SEXP bdd_ptr, SEXP upper_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + BDD *upper = bdd_from_ptr(upper_ptr); + return bdd_to_xptr(bdd->Isop(*upper)); +} + +extern "C" SEXP c_cudd_bdd_port_to_zdd(SEXP bdd_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + return zdd_to_xptr(bdd->PortToZdd()); +} + +extern "C" SEXP c_cudd_bdd_factored_form_string(SEXP bdd_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + std::string output = bdd->FactoredFormString(); + return Rf_mkString(output.c_str()); +} + +extern "C" SEXP c_cudd_bdd_print_factored_form(SEXP bdd_ptr) { + BDD *bdd = bdd_from_ptr(bdd_ptr); + bdd->PrintFactoredForm(); + return R_NilValue; +} + extern "C" SEXP c_cudd_add_times(SEXP lhs_ptr, SEXP rhs_ptr) { ADD *lhs = add_from_ptr(lhs_ptr); ADD *rhs = add_from_ptr(rhs_ptr); diff --git a/src/rcudd.h b/src/rcudd.h index bf95791..51737ce 100644 --- a/src/rcudd.h +++ b/src/rcudd.h @@ -42,6 +42,113 @@ extern "C" SEXP c_cudd_bdd_not(SEXP bdd_ptr); extern "C" SEXP c_cudd_bdd_and(SEXP lhs_ptr, SEXP rhs_ptr); extern "C" SEXP c_cudd_bdd_or(SEXP lhs_ptr, SEXP rhs_ptr); extern "C" SEXP c_cudd_bdd_xor(SEXP lhs_ptr, SEXP rhs_ptr); +extern "C" SEXP c_cudd_bdd_restrict(SEXP bdd_ptr, SEXP constraint_ptr); +extern "C" SEXP c_cudd_bdd_ite_formula(SEXP bdd_ptr); +extern "C" SEXP c_cudd_bdd_print(SEXP bdd_ptr, SEXP nvars, SEXP verbosity); +extern "C" SEXP c_cudd_bdd_summary(SEXP bdd_ptr, SEXP nvars, SEXP mode); +extern "C" SEXP c_cudd_bdd_apa_print_minterm(SEXP bdd_ptr, SEXP nvars); +extern "C" SEXP c_cudd_bdd_apa_print_minterm_exp(SEXP bdd_ptr, SEXP nvars, SEXP precision); +extern "C" SEXP c_cudd_bdd_ldbl_count_minterm(SEXP bdd_ptr, SEXP nvars); +extern "C" SEXP c_cudd_bdd_shortest_path(SEXP bdd_ptr, SEXP weight); +extern "C" SEXP c_cudd_bdd_largest_cube(SEXP bdd_ptr); +extern "C" SEXP c_cudd_bdd_shortest_length(SEXP bdd_ptr, SEXP weight); +extern "C" SEXP c_cudd_bdd_equiv_dc(SEXP bdd_ptr, SEXP g_ptr, SEXP d_ptr); +extern "C" SEXP c_cudd_bdd_cof_minterm(SEXP bdd_ptr); +extern "C" SEXP c_cudd_bdd_is_one(SEXP bdd_ptr); +extern "C" SEXP c_cudd_bdd_is_cube(SEXP bdd_ptr); +extern "C" SEXP c_cudd_bdd_find_essential(SEXP bdd_ptr); +extern "C" SEXP c_cudd_bdd_print_two_literal_clauses(SEXP bdd_ptr); +extern "C" SEXP c_cudd_bdd_count_minterm(SEXP bdd_ptr, SEXP nvars); +extern "C" SEXP c_cudd_bdd_count_path(SEXP bdd_ptr); +extern "C" SEXP c_cudd_bdd_support(SEXP bdd_ptr); +extern "C" SEXP c_cudd_bdd_support_size(SEXP bdd_ptr); +extern "C" SEXP c_cudd_bdd_support_indices(SEXP bdd_ptr); +extern "C" SEXP c_cudd_bdd_classify_support(SEXP bdd_ptr, SEXP other_ptr); +extern "C" SEXP c_cudd_bdd_count_leaves(SEXP bdd_ptr); +extern "C" SEXP c_cudd_bdd_density(SEXP bdd_ptr, SEXP nvars); +extern "C" SEXP c_cudd_bdd_under_approx(SEXP bdd_ptr, SEXP num_vars, SEXP threshold, SEXP safe, SEXP quality); +extern "C" SEXP c_cudd_bdd_over_approx(SEXP bdd_ptr, SEXP num_vars, SEXP threshold, SEXP safe, SEXP quality); +extern "C" SEXP c_cudd_bdd_remap_under_approx(SEXP bdd_ptr, SEXP num_vars, SEXP threshold, SEXP quality); +extern "C" SEXP c_cudd_bdd_remap_over_approx(SEXP bdd_ptr, SEXP num_vars, SEXP threshold, SEXP quality); +extern "C" SEXP c_cudd_bdd_biased_under_approx(SEXP bdd_ptr, SEXP bias_ptr, SEXP num_vars, SEXP threshold, SEXP quality1, SEXP quality0); +extern "C" SEXP c_cudd_bdd_biased_over_approx(SEXP bdd_ptr, SEXP bias_ptr, SEXP num_vars, SEXP threshold, SEXP quality1, SEXP quality0); +extern "C" SEXP c_cudd_bdd_clipping_and(SEXP bdd_ptr, SEXP other_ptr, SEXP max_depth, SEXP direction); +extern "C" SEXP c_cudd_bdd_clipping_and_abstract(SEXP bdd_ptr, SEXP other_ptr, SEXP cube_ptr, SEXP max_depth, SEXP direction); +extern "C" SEXP c_cudd_bdd_var_are_symmetric(SEXP bdd_ptr, SEXP index1, SEXP index2); +extern "C" SEXP c_cudd_bdd_adj_permute_x(SEXP bdd_ptr, SEXP x_list); +extern "C" SEXP c_cudd_bdd_is_var_essential(SEXP bdd_ptr, SEXP index, SEXP phase); +extern "C" SEXP c_cudd_bdd_np_and(SEXP bdd_ptr, SEXP other_ptr); +extern "C" SEXP c_cudd_bdd_constrain_decomp(SEXP bdd_ptr); +extern "C" SEXP c_cudd_bdd_char_to_vect(SEXP bdd_ptr); +extern "C" SEXP c_cudd_bdd_leq_unless(SEXP bdd_ptr, SEXP g_ptr, SEXP d_ptr); +extern "C" SEXP c_cudd_bdd_maximally_expand(SEXP bdd_ptr, SEXP ub_ptr, SEXP f_ptr); +extern "C" SEXP c_cudd_bdd_largest_prime_unate(SEXP bdd_ptr, SEXP phases_ptr); +extern "C" SEXP c_cudd_bdd_solve_eqn(SEXP bdd_ptr, SEXP y_ptr, SEXP n); +extern "C" SEXP c_cudd_bdd_verify_sol(SEXP bdd_ptr, SEXP g_list, SEXP y_index); +extern "C" SEXP c_cudd_bdd_split_set(SEXP bdd_ptr, SEXP x_vars, SEXP m); +extern "C" SEXP c_cudd_bdd_estimate_cofactor(SEXP bdd_ptr, SEXP index, SEXP phase); +extern "C" SEXP c_cudd_bdd_estimate_cofactor_simple(SEXP bdd_ptr, SEXP index); +extern "C" SEXP c_cudd_bdd_zdd_isop(SEXP bdd_ptr, SEXP upper_ptr); +extern "C" SEXP c_cudd_bdd_transfer(SEXP bdd_ptr, SEXP mgr_ptr); +extern "C" SEXP c_cudd_bdd_is_zero(SEXP bdd_ptr); +extern "C" SEXP c_cudd_bdd_is_var(SEXP bdd_ptr); +extern "C" SEXP c_cudd_bdd_leq(SEXP lhs_ptr, SEXP rhs_ptr); +extern "C" SEXP c_cudd_bdd_and_abstract(SEXP bdd_ptr, SEXP other_ptr, SEXP cube_ptr, SEXP limit); +extern "C" SEXP c_cudd_bdd_exist_abstract(SEXP bdd_ptr, SEXP cube_ptr, SEXP limit); +extern "C" SEXP c_cudd_bdd_univ_abstract(SEXP bdd_ptr, SEXP cube_ptr); +extern "C" SEXP c_cudd_bdd_xor_exist_abstract(SEXP bdd_ptr, SEXP other_ptr, SEXP cube_ptr); +extern "C" SEXP c_cudd_bdd_boolean_diff(SEXP bdd_ptr, SEXP index); +extern "C" SEXP c_cudd_bdd_var_is_dependent(SEXP bdd_ptr, SEXP var_ptr); +extern "C" SEXP c_cudd_bdd_correlation(SEXP bdd_ptr, SEXP other_ptr); +extern "C" SEXP c_cudd_bdd_correlation_weights(SEXP bdd_ptr, SEXP other_ptr, SEXP prob); +extern "C" SEXP c_cudd_bdd_xor_method(SEXP bdd_ptr, SEXP other_ptr); +extern "C" SEXP c_cudd_bdd_ite(SEXP bdd_ptr, SEXP g_ptr, SEXP h_ptr, SEXP limit); +extern "C" SEXP c_cudd_bdd_ite_constant(SEXP bdd_ptr, SEXP g_ptr, SEXP h_ptr); +extern "C" SEXP c_cudd_bdd_intersect(SEXP bdd_ptr, SEXP other_ptr); +extern "C" SEXP c_cudd_bdd_and_limit(SEXP bdd_ptr, SEXP other_ptr, SEXP limit); +extern "C" SEXP c_cudd_bdd_or_limit(SEXP bdd_ptr, SEXP other_ptr, SEXP limit); +extern "C" SEXP c_cudd_bdd_nand(SEXP bdd_ptr, SEXP other_ptr); +extern "C" SEXP c_cudd_bdd_nor(SEXP bdd_ptr, SEXP other_ptr); +extern "C" SEXP c_cudd_bdd_xnor(SEXP bdd_ptr, SEXP other_ptr, SEXP limit); +extern "C" SEXP c_cudd_bdd_cofactor(SEXP bdd_ptr, SEXP other_ptr); +extern "C" SEXP c_cudd_bdd_constrain(SEXP bdd_ptr, SEXP other_ptr); +extern "C" SEXP c_cudd_bdd_compose(SEXP bdd_ptr, SEXP other_ptr, SEXP index); +extern "C" SEXP c_cudd_bdd_permute(SEXP bdd_ptr, SEXP permut); +extern "C" SEXP c_cudd_bdd_swap_variables(SEXP bdd_ptr, SEXP x_list, SEXP y_list); +extern "C" SEXP c_cudd_bdd_vector_compose(SEXP bdd_ptr, SEXP vector_list); +extern "C" SEXP c_cudd_bdd_approx_conj_decomp(SEXP bdd_ptr); +extern "C" SEXP c_cudd_bdd_approx_disj_decomp(SEXP bdd_ptr); +extern "C" SEXP c_cudd_bdd_iter_conj_decomp(SEXP bdd_ptr); +extern "C" SEXP c_cudd_bdd_iter_disj_decomp(SEXP bdd_ptr); +extern "C" SEXP c_cudd_bdd_gen_conj_decomp(SEXP bdd_ptr); +extern "C" SEXP c_cudd_bdd_gen_disj_decomp(SEXP bdd_ptr); +extern "C" SEXP c_cudd_bdd_var_conj_decomp(SEXP bdd_ptr); +extern "C" SEXP c_cudd_bdd_var_disj_decomp(SEXP bdd_ptr); +extern "C" SEXP c_cudd_bdd_li_compaction(SEXP bdd_ptr, SEXP other_ptr); +extern "C" SEXP c_cudd_bdd_squeeze(SEXP bdd_ptr, SEXP other_ptr); +extern "C" SEXP c_cudd_bdd_interpolate(SEXP bdd_ptr, SEXP other_ptr); +extern "C" SEXP c_cudd_bdd_minimize(SEXP bdd_ptr, SEXP other_ptr); +extern "C" SEXP c_cudd_bdd_subset_compress(SEXP bdd_ptr, SEXP nvars, SEXP threshold); +extern "C" SEXP c_cudd_bdd_superset_compress(SEXP bdd_ptr, SEXP nvars, SEXP threshold); +extern "C" SEXP c_cudd_bdd_literal_set_intersection(SEXP bdd_ptr, SEXP other_ptr); +extern "C" SEXP c_cudd_bdd_c_projection(SEXP bdd_ptr, SEXP other_ptr); +extern "C" SEXP c_cudd_bdd_min_hamming_dist(SEXP bdd_ptr, SEXP minterm, SEXP upper_bound); +extern "C" SEXP c_cudd_bdd_eval(SEXP bdd_ptr, SEXP inputs); +extern "C" SEXP c_cudd_bdd_decreasing(SEXP bdd_ptr, SEXP index); +extern "C" SEXP c_cudd_bdd_increasing(SEXP bdd_ptr, SEXP index); +extern "C" SEXP c_cudd_bdd_make_prime(SEXP bdd_ptr, SEXP other_ptr); +extern "C" SEXP c_cudd_bdd_subset_heavy_branch(SEXP bdd_ptr, SEXP num_vars, SEXP threshold); +extern "C" SEXP c_cudd_bdd_superset_heavy_branch(SEXP bdd_ptr, SEXP num_vars, SEXP threshold); +extern "C" SEXP c_cudd_bdd_subset_short_paths(SEXP bdd_ptr, SEXP num_vars, SEXP threshold, SEXP hardlimit); +extern "C" SEXP c_cudd_bdd_superset_short_paths(SEXP bdd_ptr, SEXP num_vars, SEXP threshold, SEXP hardlimit); +extern "C" SEXP c_cudd_bdd_print_cover(SEXP bdd_ptr); +extern "C" SEXP c_cudd_bdd_print_cover_with_cube(SEXP bdd_ptr, SEXP cube_ptr); +extern "C" SEXP c_cudd_bdd_pick_one_cube(SEXP bdd_ptr); +extern "C" SEXP c_cudd_bdd_pick_one_minterm(SEXP bdd_ptr, SEXP vars_list); +extern "C" SEXP c_cudd_bdd_isop(SEXP bdd_ptr, SEXP upper_ptr); +extern "C" SEXP c_cudd_bdd_port_to_zdd(SEXP bdd_ptr); +extern "C" SEXP c_cudd_bdd_factored_form_string(SEXP bdd_ptr); +extern "C" SEXP c_cudd_bdd_print_factored_form(SEXP bdd_ptr); extern "C" SEXP c_cudd_add_times(SEXP lhs_ptr, SEXP rhs_ptr); extern "C" SEXP c_cudd_add_plus(SEXP lhs_ptr, SEXP rhs_ptr); extern "C" SEXP c_cudd_zdd_intersect(SEXP lhs_ptr, SEXP rhs_ptr); @@ -74,6 +181,7 @@ extern "C" SEXP c_cudd_reordering_status(SEXP mgr_ptr); extern "C" SEXP c_cudd_autodyn_enable_zdd(SEXP mgr_ptr, SEXP method); extern "C" SEXP c_cudd_autodyn_disable_zdd(SEXP mgr_ptr); extern "C" SEXP c_cudd_reordering_status_zdd(SEXP mgr_ptr); +extern "C" SEXP c_cudd_reduce_heap(SEXP mgr_ptr, SEXP heuristic, SEXP minsize); extern "C" SEXP c_cudd_zdd_realignment_enabled(SEXP mgr_ptr); extern "C" SEXP c_cudd_zdd_realign_enable(SEXP mgr_ptr); extern "C" SEXP c_cudd_zdd_realign_disable(SEXP mgr_ptr); diff --git a/src/register.cpp b/src/register.cpp index 3581cd1..6499fd0 100644 --- a/src/register.cpp +++ b/src/register.cpp @@ -39,6 +39,113 @@ static const R_CallMethodDef CallEntries[] = { {"c_cudd_bdd_and", (DL_FUNC) &c_cudd_bdd_and, 2}, {"c_cudd_bdd_or", (DL_FUNC) &c_cudd_bdd_or, 2}, {"c_cudd_bdd_xor", (DL_FUNC) &c_cudd_bdd_xor, 2}, + {"c_cudd_bdd_restrict", (DL_FUNC) &c_cudd_bdd_restrict, 2}, + {"c_cudd_bdd_ite_formula", (DL_FUNC) &c_cudd_bdd_ite_formula, 1}, + {"c_cudd_bdd_print", (DL_FUNC) &c_cudd_bdd_print, 3}, + {"c_cudd_bdd_summary", (DL_FUNC) &c_cudd_bdd_summary, 3}, + {"c_cudd_bdd_apa_print_minterm", (DL_FUNC) &c_cudd_bdd_apa_print_minterm, 2}, + {"c_cudd_bdd_apa_print_minterm_exp", (DL_FUNC) &c_cudd_bdd_apa_print_minterm_exp, 3}, + {"c_cudd_bdd_ldbl_count_minterm", (DL_FUNC) &c_cudd_bdd_ldbl_count_minterm, 2}, + {"c_cudd_bdd_shortest_path", (DL_FUNC) &c_cudd_bdd_shortest_path, 2}, + {"c_cudd_bdd_largest_cube", (DL_FUNC) &c_cudd_bdd_largest_cube, 1}, + {"c_cudd_bdd_shortest_length", (DL_FUNC) &c_cudd_bdd_shortest_length, 2}, + {"c_cudd_bdd_equiv_dc", (DL_FUNC) &c_cudd_bdd_equiv_dc, 3}, + {"c_cudd_bdd_cof_minterm", (DL_FUNC) &c_cudd_bdd_cof_minterm, 1}, + {"c_cudd_bdd_is_one", (DL_FUNC) &c_cudd_bdd_is_one, 1}, + {"c_cudd_bdd_is_cube", (DL_FUNC) &c_cudd_bdd_is_cube, 1}, + {"c_cudd_bdd_find_essential", (DL_FUNC) &c_cudd_bdd_find_essential, 1}, + {"c_cudd_bdd_print_two_literal_clauses", (DL_FUNC) &c_cudd_bdd_print_two_literal_clauses, 1}, + {"c_cudd_bdd_count_minterm", (DL_FUNC) &c_cudd_bdd_count_minterm, 2}, + {"c_cudd_bdd_count_path", (DL_FUNC) &c_cudd_bdd_count_path, 1}, + {"c_cudd_bdd_support", (DL_FUNC) &c_cudd_bdd_support, 1}, + {"c_cudd_bdd_support_size", (DL_FUNC) &c_cudd_bdd_support_size, 1}, + {"c_cudd_bdd_support_indices", (DL_FUNC) &c_cudd_bdd_support_indices, 1}, + {"c_cudd_bdd_classify_support", (DL_FUNC) &c_cudd_bdd_classify_support, 2}, + {"c_cudd_bdd_count_leaves", (DL_FUNC) &c_cudd_bdd_count_leaves, 1}, + {"c_cudd_bdd_density", (DL_FUNC) &c_cudd_bdd_density, 2}, + {"c_cudd_bdd_under_approx", (DL_FUNC) &c_cudd_bdd_under_approx, 5}, + {"c_cudd_bdd_over_approx", (DL_FUNC) &c_cudd_bdd_over_approx, 5}, + {"c_cudd_bdd_remap_under_approx", (DL_FUNC) &c_cudd_bdd_remap_under_approx, 4}, + {"c_cudd_bdd_remap_over_approx", (DL_FUNC) &c_cudd_bdd_remap_over_approx, 4}, + {"c_cudd_bdd_biased_under_approx", (DL_FUNC) &c_cudd_bdd_biased_under_approx, 6}, + {"c_cudd_bdd_biased_over_approx", (DL_FUNC) &c_cudd_bdd_biased_over_approx, 6}, + {"c_cudd_bdd_clipping_and", (DL_FUNC) &c_cudd_bdd_clipping_and, 4}, + {"c_cudd_bdd_clipping_and_abstract", (DL_FUNC) &c_cudd_bdd_clipping_and_abstract, 5}, + {"c_cudd_bdd_var_are_symmetric", (DL_FUNC) &c_cudd_bdd_var_are_symmetric, 3}, + {"c_cudd_bdd_adj_permute_x", (DL_FUNC) &c_cudd_bdd_adj_permute_x, 2}, + {"c_cudd_bdd_is_var_essential", (DL_FUNC) &c_cudd_bdd_is_var_essential, 3}, + {"c_cudd_bdd_np_and", (DL_FUNC) &c_cudd_bdd_np_and, 2}, + {"c_cudd_bdd_constrain_decomp", (DL_FUNC) &c_cudd_bdd_constrain_decomp, 1}, + {"c_cudd_bdd_char_to_vect", (DL_FUNC) &c_cudd_bdd_char_to_vect, 1}, + {"c_cudd_bdd_leq_unless", (DL_FUNC) &c_cudd_bdd_leq_unless, 3}, + {"c_cudd_bdd_maximally_expand", (DL_FUNC) &c_cudd_bdd_maximally_expand, 3}, + {"c_cudd_bdd_largest_prime_unate", (DL_FUNC) &c_cudd_bdd_largest_prime_unate, 2}, + {"c_cudd_bdd_solve_eqn", (DL_FUNC) &c_cudd_bdd_solve_eqn, 3}, + {"c_cudd_bdd_verify_sol", (DL_FUNC) &c_cudd_bdd_verify_sol, 3}, + {"c_cudd_bdd_split_set", (DL_FUNC) &c_cudd_bdd_split_set, 3}, + {"c_cudd_bdd_estimate_cofactor", (DL_FUNC) &c_cudd_bdd_estimate_cofactor, 3}, + {"c_cudd_bdd_estimate_cofactor_simple", (DL_FUNC) &c_cudd_bdd_estimate_cofactor_simple, 2}, + {"c_cudd_bdd_zdd_isop", (DL_FUNC) &c_cudd_bdd_zdd_isop, 2}, + {"c_cudd_bdd_transfer", (DL_FUNC) &c_cudd_bdd_transfer, 2}, + {"c_cudd_bdd_is_zero", (DL_FUNC) &c_cudd_bdd_is_zero, 1}, + {"c_cudd_bdd_is_var", (DL_FUNC) &c_cudd_bdd_is_var, 1}, + {"c_cudd_bdd_leq", (DL_FUNC) &c_cudd_bdd_leq, 2}, + {"c_cudd_bdd_and_abstract", (DL_FUNC) &c_cudd_bdd_and_abstract, 4}, + {"c_cudd_bdd_exist_abstract", (DL_FUNC) &c_cudd_bdd_exist_abstract, 3}, + {"c_cudd_bdd_univ_abstract", (DL_FUNC) &c_cudd_bdd_univ_abstract, 2}, + {"c_cudd_bdd_xor_exist_abstract", (DL_FUNC) &c_cudd_bdd_xor_exist_abstract, 3}, + {"c_cudd_bdd_boolean_diff", (DL_FUNC) &c_cudd_bdd_boolean_diff, 2}, + {"c_cudd_bdd_var_is_dependent", (DL_FUNC) &c_cudd_bdd_var_is_dependent, 2}, + {"c_cudd_bdd_correlation", (DL_FUNC) &c_cudd_bdd_correlation, 2}, + {"c_cudd_bdd_correlation_weights", (DL_FUNC) &c_cudd_bdd_correlation_weights, 3}, + {"c_cudd_bdd_xor_method", (DL_FUNC) &c_cudd_bdd_xor_method, 2}, + {"c_cudd_bdd_ite", (DL_FUNC) &c_cudd_bdd_ite, 4}, + {"c_cudd_bdd_ite_constant", (DL_FUNC) &c_cudd_bdd_ite_constant, 3}, + {"c_cudd_bdd_intersect", (DL_FUNC) &c_cudd_bdd_intersect, 2}, + {"c_cudd_bdd_and_limit", (DL_FUNC) &c_cudd_bdd_and_limit, 3}, + {"c_cudd_bdd_or_limit", (DL_FUNC) &c_cudd_bdd_or_limit, 3}, + {"c_cudd_bdd_nand", (DL_FUNC) &c_cudd_bdd_nand, 2}, + {"c_cudd_bdd_nor", (DL_FUNC) &c_cudd_bdd_nor, 2}, + {"c_cudd_bdd_xnor", (DL_FUNC) &c_cudd_bdd_xnor, 3}, + {"c_cudd_bdd_cofactor", (DL_FUNC) &c_cudd_bdd_cofactor, 2}, + {"c_cudd_bdd_constrain", (DL_FUNC) &c_cudd_bdd_constrain, 2}, + {"c_cudd_bdd_compose", (DL_FUNC) &c_cudd_bdd_compose, 3}, + {"c_cudd_bdd_permute", (DL_FUNC) &c_cudd_bdd_permute, 2}, + {"c_cudd_bdd_swap_variables", (DL_FUNC) &c_cudd_bdd_swap_variables, 3}, + {"c_cudd_bdd_vector_compose", (DL_FUNC) &c_cudd_bdd_vector_compose, 2}, + {"c_cudd_bdd_approx_conj_decomp", (DL_FUNC) &c_cudd_bdd_approx_conj_decomp, 1}, + {"c_cudd_bdd_approx_disj_decomp", (DL_FUNC) &c_cudd_bdd_approx_disj_decomp, 1}, + {"c_cudd_bdd_iter_conj_decomp", (DL_FUNC) &c_cudd_bdd_iter_conj_decomp, 1}, + {"c_cudd_bdd_iter_disj_decomp", (DL_FUNC) &c_cudd_bdd_iter_disj_decomp, 1}, + {"c_cudd_bdd_gen_conj_decomp", (DL_FUNC) &c_cudd_bdd_gen_conj_decomp, 1}, + {"c_cudd_bdd_gen_disj_decomp", (DL_FUNC) &c_cudd_bdd_gen_disj_decomp, 1}, + {"c_cudd_bdd_var_conj_decomp", (DL_FUNC) &c_cudd_bdd_var_conj_decomp, 1}, + {"c_cudd_bdd_var_disj_decomp", (DL_FUNC) &c_cudd_bdd_var_disj_decomp, 1}, + {"c_cudd_bdd_li_compaction", (DL_FUNC) &c_cudd_bdd_li_compaction, 2}, + {"c_cudd_bdd_squeeze", (DL_FUNC) &c_cudd_bdd_squeeze, 2}, + {"c_cudd_bdd_interpolate", (DL_FUNC) &c_cudd_bdd_interpolate, 2}, + {"c_cudd_bdd_minimize", (DL_FUNC) &c_cudd_bdd_minimize, 2}, + {"c_cudd_bdd_subset_compress", (DL_FUNC) &c_cudd_bdd_subset_compress, 3}, + {"c_cudd_bdd_superset_compress", (DL_FUNC) &c_cudd_bdd_superset_compress, 3}, + {"c_cudd_bdd_literal_set_intersection", (DL_FUNC) &c_cudd_bdd_literal_set_intersection, 2}, + {"c_cudd_bdd_c_projection", (DL_FUNC) &c_cudd_bdd_c_projection, 2}, + {"c_cudd_bdd_min_hamming_dist", (DL_FUNC) &c_cudd_bdd_min_hamming_dist, 3}, + {"c_cudd_bdd_eval", (DL_FUNC) &c_cudd_bdd_eval, 2}, + {"c_cudd_bdd_decreasing", (DL_FUNC) &c_cudd_bdd_decreasing, 2}, + {"c_cudd_bdd_increasing", (DL_FUNC) &c_cudd_bdd_increasing, 2}, + {"c_cudd_bdd_make_prime", (DL_FUNC) &c_cudd_bdd_make_prime, 2}, + {"c_cudd_bdd_subset_heavy_branch", (DL_FUNC) &c_cudd_bdd_subset_heavy_branch, 3}, + {"c_cudd_bdd_superset_heavy_branch", (DL_FUNC) &c_cudd_bdd_superset_heavy_branch, 3}, + {"c_cudd_bdd_subset_short_paths", (DL_FUNC) &c_cudd_bdd_subset_short_paths, 4}, + {"c_cudd_bdd_superset_short_paths", (DL_FUNC) &c_cudd_bdd_superset_short_paths, 4}, + {"c_cudd_bdd_print_cover", (DL_FUNC) &c_cudd_bdd_print_cover, 1}, + {"c_cudd_bdd_print_cover_with_cube", (DL_FUNC) &c_cudd_bdd_print_cover_with_cube, 2}, + {"c_cudd_bdd_pick_one_cube", (DL_FUNC) &c_cudd_bdd_pick_one_cube, 1}, + {"c_cudd_bdd_pick_one_minterm", (DL_FUNC) &c_cudd_bdd_pick_one_minterm, 2}, + {"c_cudd_bdd_isop", (DL_FUNC) &c_cudd_bdd_isop, 2}, + {"c_cudd_bdd_port_to_zdd", (DL_FUNC) &c_cudd_bdd_port_to_zdd, 1}, + {"c_cudd_bdd_factored_form_string", (DL_FUNC) &c_cudd_bdd_factored_form_string, 1}, + {"c_cudd_bdd_print_factored_form", (DL_FUNC) &c_cudd_bdd_print_factored_form, 1}, {"c_cudd_add_times", (DL_FUNC) &c_cudd_add_times, 2}, {"c_cudd_add_plus", (DL_FUNC) &c_cudd_add_plus, 2}, {"c_cudd_zdd_intersect", (DL_FUNC) &c_cudd_zdd_intersect, 2}, @@ -71,6 +178,7 @@ static const R_CallMethodDef CallEntries[] = { {"c_cudd_autodyn_enable_zdd", (DL_FUNC) &c_cudd_autodyn_enable_zdd, 2}, {"c_cudd_autodyn_disable_zdd", (DL_FUNC) &c_cudd_autodyn_disable_zdd, 1}, {"c_cudd_reordering_status_zdd", (DL_FUNC) &c_cudd_reordering_status_zdd, 1}, + {"c_cudd_reduce_heap", (DL_FUNC) &c_cudd_reduce_heap, 3}, {"c_cudd_zdd_realignment_enabled", (DL_FUNC) &c_cudd_zdd_realignment_enabled, 1}, {"c_cudd_zdd_realign_enable", (DL_FUNC) &c_cudd_zdd_realign_enable, 1}, {"c_cudd_zdd_realign_disable", (DL_FUNC) &c_cudd_zdd_realign_disable, 1}, diff --git a/tests/testthat/_snaps/cudd_bdd_methods.md b/tests/testthat/_snaps/cudd_bdd_methods.md new file mode 100644 index 0000000..4fee794 --- /dev/null +++ b/tests/testthat/_snaps/cudd_bdd_methods.md @@ -0,0 +1,4 @@ +# additional BDD methods are exposed + + + diff --git a/tests/testthat/test_cudd_bdd_methods.R b/tests/testthat/test_cudd_bdd_methods.R new file mode 100644 index 0000000..c6c4453 --- /dev/null +++ b/tests/testthat/test_cudd_bdd_methods.R @@ -0,0 +1,55 @@ +test_that("additional BDD methods are exposed", { + manager <- CuddManager() + vars <- lapply(1:3, function(i) cudd_bdd_var(manager)) + + bdd_one <- cudd_bdd_one(manager) + bdd_zero <- cudd_bdd_zero(manager) + bdd_or <- vars[[1L]] + vars[[2L]] + bdd_and <- vars[[1L]] * vars[[3L]] + + expect_true(cudd_bdd_is_one(bdd_one)) + expect_true(cudd_bdd_is_zero(bdd_zero)) + expect_true(cudd_bdd_is_var(vars[[1L]])) + expect_true(cudd_bdd_is_cube(vars[[1L]])) + expect_false(cudd_bdd_is_cube(bdd_or)) + + expect_equal(cudd_bdd_count_minterm(vars[[1L]], 3L), 4.0, tolerance = 1e-8) + expect_identical(cudd_bdd_support_size(bdd_and), 2L) + expect_identical(cudd_bdd_support_indices(bdd_and), c(0L, 2L)) + + classified <- cudd_bdd_classify_support(bdd_and, vars[[1L]]) + expect_named(classified, c("common", "only_bdd", "only_other")) + expect_true(methods::is(classified$common, "CuddBDD")) + + expect_snapshot_output(cudd_bdd_print(bdd_or, 3L)) + expect_silent(cudd_bdd_summary(bdd_or, 3L)) + + expect_equal(cudd_bdd_correlation(vars[[1L]], vars[[1L]]), 1.0) + expect_equal( + cudd_bdd_correlation_weights(vars[[1L]], vars[[1L]], rep(0.5, 3L)), + 1.0 + ) + expect_identical(cudd_bdd_ite_formula(vars[[1L]] + vars[[2L]]), "x0 || x1") + expect_identical(cudd_bdd_ite_formula(vars[[1L]] * vars[[2L]]), "x0 && x1") + expect_identical(cudd_bdd_ite_formula(!vars[[1L]]), "!x0") + expect_identical(cudd_bdd_ite_formula(vars[[1L]] ^ vars[[2L]]), "xor(x0, x1)") + expect_identical(cudd_bdd_ite_formula(!(vars[[1L]] ^ vars[[2L]])), "!xor(x0, x1)") + expect_identical( + cudd_bdd_ite_formula((!vars[[1L]]) * vars[[2L]]), + "!x0 && x1" + ) + complex_bdd <- (vars[[1L]] * vars[[2L]]) + (!vars[[1L]] * (vars[[2L]] ^ vars[[3L]])) + expect_identical( + cudd_bdd_ite_formula(complex_bdd), + "x0 && x1 || !x0 && xor(x1, x2)" + ) + + shortest_length <- cudd_bdd_shortest_length(vars[[1L]]) + expect_type(shortest_length, "integer") + expect_gte(shortest_length, 0L) + + manager2 <- CuddManager() + transferred <- cudd_bdd_transfer(vars[[1L]], manager2) + expect_true(methods::is(transferred, "CuddBDD")) + expect_silent(transferred + cudd_bdd_var(manager2)) +})