#' @title
#' Dual of a poset.
#'
#' @description
#' Computes the dual of the input poset.
#'
#' @param poset An object of S4 class `POSet`.
#' Argument `poset` must be created by using any function contained in the package
#' aimed at building object of S4 class `POSet`
#' (e.g. [POSet()], [LinearPOSet()], [ProductPOSet()], ...).
#'
#' @return
#' The dual of the input poset, an object of S4 class `POSet`.
#'
#' @details
#' Let \eqn{P=(V,\leq)} be a poset. Then its dual \eqn{P_d=(V,\leq_d)} is defined
#' by \eqn{a\leq_d b} if and only if \eqn{b\leq a} in \eqn{P}.
#' In other words, the dual of \eqn{P} is obtained by reversing its dominances.
#'
#' @examples
#' elems <- c("a", "b", "c", "d")
#'
#' doms <- matrix(c(
#'   "a", "b",
#'   "c", "b",
#'   "b", "d"
#' ), ncol = 2, byrow = TRUE)
#'
#' pos1 <- POSet(elements = elems, dom = doms)
#'
#' dual <- DualPOSet(pos1)
#'
#' @name DualPOSet
#' @export DualPOSet
DualPOSet <- function(poset) {
  if (!methods::is(poset, "POSet")) {
    stop("poset must be of class POSet")
  }
  tryCatch({
    ptr <- .Call("_BuildDualPOSet", poset@ptr)
    result <- methods::new("POSet", ptr = ptr)
    return (result)
  }, error = function(err) {
    err_split <- strsplit(err[[1]], split = ":")
    stop(err_split[[1]][length(err_split[[1]])])
  }) # END tryCatch
}
