#' @title
#' Computing join (least upper bound).
#'
#' @description
#' The function computes the join (if existing) of a set of elements, in 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()], ...).
#'
#' @param elements A list of character strings (the names of some poset elements).
#'
#' @return
#' A character string (the name of the join).
#'
#' @examples
#' elems <- c("a", "b", "c", "d")
#'
#' doms <- matrix(c(
#'   "a", "b",
#'   "c", "b",
#'   "a", "d",
#'   "a", "a",
#'   "b", "b",
#'   "c", "c",
#'   "d", "d"
#' ), ncol = 2, byrow = TRUE)
#'
#' pos <- POSet(elements = elems, dom = doms)
#'
#' lub<-POSetJoin(pos, c("a", "c"))
#'
#'
#' @name POSetJoin
#' @export POSetJoin
POSetJoin <- function(poset, elements) {
  if (!methods::is(poset, "POSet")) {
    stop("poset must be of class POSet")
  }
  if (!is.character(elements)) {
    stop("elements must be character array")
  }
  if (length(unique(elements)) != length(elements)) {
    stop("elements contains duplicated values")
  }
  tryCatch({
    result <- .Call("_Join", poset@ptr, elements)
    return (result)
  }, error = function(err) {
    err_split <- strsplit(err[[1]], split = ":")
    stop(err_split[[1]][length(err_split[[1]])])
  }) # END tryCatch
}
