
# compare two network scores in an efficient way.
score.delta = function(arc, network, data, score, score.delta,
    reference.score, op, extra, decomposable = TRUE) {

  .Call(call_score_delta,
        arc = arc,
        network = network,
        data = data,
        score = score,
        score.delta = score.delta,
        reference.score = reference.score,
        op = op,
        extra = extra,
        decomposable = decomposable)

}#SCORE.DELTA

# create a data frame containing the arcs to be added.
arcs.to.be.added = function(arcs, nodes, blacklist = NULL, whitelist = NULL,
    nparents = NULL, maxp = Inf) {

  # the C code expects one maximum number of parents per node, in node order:
  # expand a single value, and reorder a named vector to match.
  if (length(maxp) == 1)
    maxp = rep(as.double(maxp), length(nodes))
  else if (!is.null(names(maxp)))
    maxp = maxp[nodes]

  .Call(call_hc_to_be_added,
        arcs = arcs,
        blacklist = blacklist,
        whitelist = whitelist,
        nparents = nparents,
        maxp = as.double(maxp),
        nodes = nodes)

}#ARCS.TO.BE.ADDED

# create a data frame containing the arcs to be dropped:
# arcs                   arcs already in the graph.
# !is.listed(whitelist)  exclude whitelisted arcs.
arcs.to.be.dropped = function(arcs, whitelist) {

  if (!is.null(whitelist))
    return(arcs[!which.listed(arcs, whitelist), , drop = FALSE])
  else
    return(arcs)

}#ARCS.TO.BE.DROPPED

# create a data frame containing the arcs to be reversed:
arcs.to.be.reversed = function(arcs, blacklist, nparents, maxp = Inf) {

  if (!is.null(blacklist))
    arcs = arcs[!which.listed(arcs[, c(2, 1), drop = FALSE], blacklist), , drop = FALSE]

  if (!missing(nparents)) {

    # maxp is either a single value or one maximum number of parents per node;
    # in the latter case, the limit applies to the tail of the arc being
    # reversed (the node that gains a parent).
    if (length(maxp) == 1)
      limit = maxp
    else
      limit = maxp[arcs[, 1]]
    arcs = arcs[nparents[arcs[, 1]] < limit, , drop = FALSE]

  }#THEN

  return(arcs)

}#ARCS.TO.BE.REVERSED

