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..bdddfec 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,10 +1,253 @@ # Generated by roxygen2: do not edit by hand +export(CuddManager) 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_print_minterm) +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_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) +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_reduce_heap) +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_print_minterm) +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("!") +exportMethods("*") +exportMethods("+") +exportMethods("^") +exportMethods(show) +importFrom(methods,show) useDynLib(Rcudd, .registration=TRUE) diff --git a/R/cudd_add.R b/R/cudd_add.R new file mode 100644 index 0000000..d6925c4 --- /dev/null +++ b/R/cudd_add.R @@ -0,0 +1,158 @@ +#' 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 +#' @export +methods::setMethod("show", "CuddADD", function(object) { + cat("\n") + cudd_add_print_minterm(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. +#' @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) + } + 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. +#' @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) + } + 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. +#' @export +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. +#' @export +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 add A [`CuddADD`] instance. +#' @return `NULL`, invisibly. +#' @export +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 new file mode 100644 index 0000000..d19e975 --- /dev/null +++ b/R/cudd_bdd.R @@ -0,0 +1,224 @@ +#' 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 +#' @export +methods::setMethod("show", "CuddBDD", function(object) { + cat("\n") + cudd_bdd_print_minterm(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. +#' @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))) +}) + +#' @describeIn CuddBDD-class Combine BDDs with addition (logical OR) +#' @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) + } + 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. +#' @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) + } + 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. +#' @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) + } + 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))) +}) + +#' 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 +#' 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 bdd A [`CuddBDD`] instance. +#' @return `NULL`, invisibly. +#' @export +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 +#' +#' 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_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_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 new file mode 100644 index 0000000..7511b65 --- /dev/null +++ b/R/cudd_manager.R @@ -0,0 +1,765 @@ +#' 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.") + } + return(TRUE) + } +) + +#' Create a new CUDD manager +#' +#' @return A [`CuddManager`] instance. +#' @export +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. +#' @param object A `CuddManager` instance. +#' @keywords internal +#' @export +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) + } + return(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) { + return(.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) { + return(.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) { + return(.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) { + return(.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) { + return(.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) { + 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 +#' +#' @param manager A [`CuddManager`] instance. +#' @return Integer scalar with the cache loose up-to threshold. +#' @export +cudd_read_loose_up_to <- function(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 +#' +#' @param manager A [`CuddManager`] instance. +#' @return Double scalar with the live node count. +#' @export +cudd_read_node_count <- function(manager) { + return(.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) { + return(.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) { + 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. +#' +#' 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). +#' @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 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. +#' @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_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) { + 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..68d5701 --- /dev/null +++ b/R/cudd_zdd.R @@ -0,0 +1,144 @@ +#' 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 +#' @export +methods::setMethod("show", "CuddZDD", function(object) { + cat("\n") + cudd_zdd_print_minterm(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. +#' @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) + } + 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. +#' @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) + } + 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. +#' @export +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. +#' @export +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 zdd A [`CuddZDD`] instance. +#' @return `NULL`, invisibly. +#' @export +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 6c10963..1518ad4 100644 --- a/R/rcudd.R +++ b/R/rcudd.R @@ -1,2 +1,14 @@ #' @useDynLib Rcudd, .registration=TRUE +#' @importFrom methods show NULL + +.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/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/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/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/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_print_minterm.Rd b/man/cudd_add_print_minterm.Rd new file mode 100644 index 0000000..81d7bbc --- /dev/null +++ b/man/cudd_add_print_minterm.Rd @@ -0,0 +1,18 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cudd_add.R +\name{cudd_add_print_minterm} +\alias{cudd_add_print_minterm} +\title{Print the minterm representation for an ADD} +\usage{ +cudd_add_print_minterm(add) +} +\arguments{ +\item{add}{A [`CuddADD`] instance.} +} +\value{ +`NULL`, invisibly. +} +\description{ +This uses the CUDD `PrintMinterm` implementation, which writes to R's +output stream. +} 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_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_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_print_minterm.Rd b/man/cudd_bdd_print_minterm.Rd new file mode 100644 index 0000000..9f630a4 --- /dev/null +++ b/man/cudd_bdd_print_minterm.Rd @@ -0,0 +1,18 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cudd_bdd.R +\name{cudd_bdd_print_minterm} +\alias{cudd_bdd_print_minterm} +\title{Print the minterm representation for a BDD} +\usage{ +cudd_bdd_print_minterm(bdd) +} +\arguments{ +\item{bdd}{A [`CuddBDD`] instance.} +} +\value{ +`NULL`, invisibly. +} +\description{ +This uses the CUDD `PrintMinterm` implementation, which writes to R's +output stream. +} 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_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_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/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..6625a7d --- /dev/null +++ b/man/cudd_manager_controls.Rd @@ -0,0 +1,354 @@ +% 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_reduce_heap} +\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_reduce_heap(manager, heuristic = NULL, minsize = 0L) + +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{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.} + +\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. +} +\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/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_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_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_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_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_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/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_print_minterm.Rd b/man/cudd_zdd_print_minterm.Rd new file mode 100644 index 0000000..746754d --- /dev/null +++ b/man/cudd_zdd_print_minterm.Rd @@ -0,0 +1,18 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cudd_zdd.R +\name{cudd_zdd_print_minterm} +\alias{cudd_zdd_print_minterm} +\title{Print the minterm representation for a ZDD} +\usage{ +cudd_zdd_print_minterm(zdd) +} +\arguments{ +\item{zdd}{A [`CuddZDD`] instance.} +} +\value{ +`NULL`, invisibly. +} +\description{ +This uses the CUDD `PrintMinterm` implementation, which writes to R's +output stream. +} 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/src/cudd_manager.cpp b/src/cudd_manager.cpp new file mode 100644 index 0000000..ce98f21 --- /dev/null +++ b/src/cudd_manager.cpp @@ -0,0 +1,2417 @@ +#include "rcudd.h" +#include +#include +#include +#include +#include +#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); + } +} + +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."); + } + void *addr = R_ExternalPtrAddr(ptr); + if (addr == nullptr) { + Rf_error("CUDD manager pointer is NULL."); + } + 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); +} + +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(); + 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; +} + +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_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())); +} + +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())); +} + +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_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()); +} + +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_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); + 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_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; + 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 7596b84..51737ce 100644 --- a/src/rcudd.h +++ b/src/rcudd.h @@ -9,6 +9,251 @@ 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_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_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); +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_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); +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_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); +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 514c563..6499fd0 100644 --- a/src/register.cpp +++ b/src/register.cpp @@ -6,6 +6,251 @@ 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_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_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}, + {"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_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}, + {"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_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}, + {"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_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/_snaps/cudd_diagrams.md b/tests/testthat/_snaps/cudd_diagrams.md new file mode 100644 index 0000000..990790f --- /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 + show_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 + show_output + Output + [1] "" "- 1" + +# ZDD operations and conversions return expected classes + + Code + show_output + Output + [1] "" "0 1" + 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)) +}) diff --git a/tests/testthat/test_cudd_diagrams.R b/tests/testthat/test_cudd_diagrams.R new file mode 100644 index 0000000..a114e72 --- /dev/null +++ b/tests/testthat/test_cudd_diagrams.R @@ -0,0 +1,89 @@ +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) + + 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) + + 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) + + show_output <- capture.output(show(add_one)) + expect_snapshot(show_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") + + show_output <- capture.output(show(zdd_one)) + expect_snapshot(show_output) + +}) diff --git a/tests/testthat/test_cudd_manager.R b/tests/testthat/test_cudd_manager.R new file mode 100644 index 0000000..7ebe7ea --- /dev/null +++ b/tests/testthat/test_cudd_manager.R @@ -0,0 +1,245 @@ +test_that("CuddManager exposes manager stats", { + manager <- CuddManager() + + expect_length(cudd_read_cache_used_slots(manager), 1L) + expect_type(cudd_read_cache_used_slots(manager), "double") + + expect_length(cudd_read_min_hit(manager), 1L) + expect_type(cudd_read_min_hit(manager), "integer") + + expect_length(cudd_read_loose_up_to(manager), 1L) + expect_type(cudd_read_loose_up_to(manager), "integer") + + expect_length(cudd_read_zdd_size(manager), 1L) + expect_type(cudd_read_zdd_size(manager), "integer") + + expect_length(cudd_read_reorderings(manager), 1L) + 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" + ) +})