diff --git a/R/cycles.R b/R/cycles.R index c3d65b5cae0..25356203038 100644 --- a/R/cycles.R +++ b/R/cycles.R @@ -31,6 +31,7 @@ #' a specific cycle. #' #' @param graph The input graph. +#' @inheritParams rlang::args_dots_empty #' @param mode Character constant specifying how to handle directed graphs. #' `out` follows edge directions, `in` follows edges in the reverse direction, #' and `all` ignores edge directions. Ignored in undirected graphs. diff --git a/R/topology.R b/R/topology.R index b0de7a8f321..23860150f1d 100644 --- a/R/topology.R +++ b/R/topology.R @@ -183,16 +183,52 @@ graph.isoclass.subgraph <- function(graph, vids) { res } +#' @inheritParams rlang::args_dots_empty #' @export graph.subisomorphic.lad <- function( pattern, target, + ..., domains = NULL, induced = FALSE, map = TRUE, all.maps = FALSE, time.limit = Inf ) { + # BEGIN GENERATED ARG_HANDLE: graph.subisomorphic.lad, do not edit, see tools/generate-migrations.R + if (...length() > 0L) { + .arg_handle <- migrate_recover_args( + list(...), + current = list( + domains = domains, + induced = induced, + map = map, + all.maps = all.maps, + time.limit = time.limit + ), + recover_new = c("domains", "induced", "map", "all.maps", "time.limit"), + recover_old = c("domains", "induced", "map", "all.maps", "time.limit"), + match_names = c("domains", "induced", "map", "all.maps", "time.limit"), + match_to = c("domains", "induced", "map", "all.maps", "time.limit"), + defaults = list( + domains = NULL, + induced = FALSE, + map = TRUE, + all.maps = FALSE, + time.limit = Inf + ), + head_args = c("pattern", "target"), + fn_name = "graph.subisomorphic.lad" + ) + list2env(.arg_handle$values, environment()) + lifecycle::deprecate_soft( + "3.0.0", + what = I(.arg_handle$what), + details = .arg_handle$details + ) + } + # END GENERATED ARG_HANDLE + # Argument checks ensure_igraph(pattern) ensure_igraph(target) @@ -382,14 +418,42 @@ isomorphic <- function( } } +#' @inheritParams rlang::args_dots_empty #' @export graph.isomorphic.bliss <- function( graph1, graph2, + ..., colors1 = NULL, colors2 = NULL, sh = c("fm", "f", "fs", "fl", "flm", "fsm") ) { + # BEGIN GENERATED ARG_HANDLE: graph.isomorphic.bliss, do not edit, see tools/generate-migrations.R + if (...length() > 0L) { + .arg_handle <- migrate_recover_args( + list(...), + current = list(colors1 = colors1, colors2 = colors2, sh = sh), + recover_new = c("colors1", "colors2", "sh"), + recover_old = c("colors1", "colors2", "sh"), + match_names = c("colors1", "colors2", "sh"), + match_to = c("colors1", "colors2", "sh"), + defaults = list( + colors1 = NULL, + colors2 = NULL, + sh = c("fm", "f", "fs", "fl", "flm", "fsm") + ), + head_args = c("graph1", "graph2"), + fn_name = "graph.isomorphic.bliss" + ) + list2env(.arg_handle$values, environment()) + lifecycle::deprecate_soft( + "3.0.0", + what = I(.arg_handle$what), + details = .arg_handle$details + ) + } + # END GENERATED ARG_HANDLE + isomorphic_bliss_impl( graph1 = graph1, graph2 = graph2, @@ -398,15 +462,69 @@ graph.isomorphic.bliss <- function( sh = sh ) } +#' @inheritParams rlang::args_dots_empty #' @export graph.isomorphic.vf2 <- function( graph1, graph2, + ..., vertex.color1 = NULL, vertex.color2 = NULL, edge.color1 = NULL, edge.color2 = NULL ) { + # BEGIN GENERATED ARG_HANDLE: graph.isomorphic.vf2, do not edit, see tools/generate-migrations.R + if (...length() > 0L) { + .arg_handle <- migrate_recover_args( + list(...), + current = list( + vertex.color1 = vertex.color1, + vertex.color2 = vertex.color2, + edge.color1 = edge.color1, + edge.color2 = edge.color2 + ), + recover_new = c( + "vertex.color1", + "vertex.color2", + "edge.color1", + "edge.color2" + ), + recover_old = c( + "vertex.color1", + "vertex.color2", + "edge.color1", + "edge.color2" + ), + match_names = c( + "vertex.color1", + "vertex.color2", + "edge.color1", + "edge.color2" + ), + match_to = c( + "vertex.color1", + "vertex.color2", + "edge.color1", + "edge.color2" + ), + defaults = list( + vertex.color1 = NULL, + vertex.color2 = NULL, + edge.color1 = NULL, + edge.color2 = NULL + ), + head_args = c("graph1", "graph2"), + fn_name = "graph.isomorphic.vf2" + ) + list2env(.arg_handle$values, environment()) + lifecycle::deprecate_soft( + "3.0.0", + what = I(.arg_handle$what), + details = .arg_handle$details + ) + } + # END GENERATED ARG_HANDLE + isomorphic_vf2_impl( graph1 = graph1, graph2 = graph2, @@ -424,15 +542,69 @@ graph.isomorphic.vf2 <- function( edge_color2 = if (missing(edge.color2)) missing_arg() else edge.color2 ) } +#' @inheritParams rlang::args_dots_empty #' @export graph.subisomorphic.vf2 <- function( graph1, graph2, + ..., vertex.color1 = NULL, vertex.color2 = NULL, edge.color1 = NULL, edge.color2 = NULL ) { + # BEGIN GENERATED ARG_HANDLE: graph.subisomorphic.vf2, do not edit, see tools/generate-migrations.R + if (...length() > 0L) { + .arg_handle <- migrate_recover_args( + list(...), + current = list( + vertex.color1 = vertex.color1, + vertex.color2 = vertex.color2, + edge.color1 = edge.color1, + edge.color2 = edge.color2 + ), + recover_new = c( + "vertex.color1", + "vertex.color2", + "edge.color1", + "edge.color2" + ), + recover_old = c( + "vertex.color1", + "vertex.color2", + "edge.color1", + "edge.color2" + ), + match_names = c( + "vertex.color1", + "vertex.color2", + "edge.color1", + "edge.color2" + ), + match_to = c( + "vertex.color1", + "vertex.color2", + "edge.color1", + "edge.color2" + ), + defaults = list( + vertex.color1 = NULL, + vertex.color2 = NULL, + edge.color1 = NULL, + edge.color2 = NULL + ), + head_args = c("graph1", "graph2"), + fn_name = "graph.subisomorphic.vf2" + ) + list2env(.arg_handle$values, environment()) + lifecycle::deprecate_soft( + "3.0.0", + what = I(.arg_handle$what), + details = .arg_handle$details + ) + } + # END GENERATED ARG_HANDLE + subisomorphic_vf2_impl( graph1 = graph1, graph2 = graph2, @@ -621,15 +793,69 @@ count_isomorphisms <- function(graph1, graph2, method = "vf2", ...) { } } +#' @inheritParams rlang::args_dots_empty #' @export graph.count.isomorphisms.vf2 <- function( graph1, graph2, + ..., vertex.color1 = NULL, vertex.color2 = NULL, edge.color1 = NULL, edge.color2 = NULL ) { + # BEGIN GENERATED ARG_HANDLE: graph.count.isomorphisms.vf2, do not edit, see tools/generate-migrations.R + if (...length() > 0L) { + .arg_handle <- migrate_recover_args( + list(...), + current = list( + vertex.color1 = vertex.color1, + vertex.color2 = vertex.color2, + edge.color1 = edge.color1, + edge.color2 = edge.color2 + ), + recover_new = c( + "vertex.color1", + "vertex.color2", + "edge.color1", + "edge.color2" + ), + recover_old = c( + "vertex.color1", + "vertex.color2", + "edge.color1", + "edge.color2" + ), + match_names = c( + "vertex.color1", + "vertex.color2", + "edge.color1", + "edge.color2" + ), + match_to = c( + "vertex.color1", + "vertex.color2", + "edge.color1", + "edge.color2" + ), + defaults = list( + vertex.color1 = NULL, + vertex.color2 = NULL, + edge.color1 = NULL, + edge.color2 = NULL + ), + head_args = c("graph1", "graph2"), + fn_name = "graph.count.isomorphisms.vf2" + ) + list2env(.arg_handle$values, environment()) + lifecycle::deprecate_soft( + "3.0.0", + what = I(.arg_handle$what), + details = .arg_handle$details + ) + } + # END GENERATED ARG_HANDLE + count_isomorphisms_vf2_impl( graph1 = graph1, graph2 = graph2, @@ -727,15 +953,69 @@ count_subgraph_isomorphisms <- function( } } +#' @inheritParams rlang::args_dots_empty #' @export graph.count.subisomorphisms.vf2 <- function( graph1, graph2, + ..., vertex.color1 = NULL, vertex.color2 = NULL, edge.color1 = NULL, edge.color2 = NULL ) { + # BEGIN GENERATED ARG_HANDLE: graph.count.subisomorphisms.vf2, do not edit, see tools/generate-migrations.R + if (...length() > 0L) { + .arg_handle <- migrate_recover_args( + list(...), + current = list( + vertex.color1 = vertex.color1, + vertex.color2 = vertex.color2, + edge.color1 = edge.color1, + edge.color2 = edge.color2 + ), + recover_new = c( + "vertex.color1", + "vertex.color2", + "edge.color1", + "edge.color2" + ), + recover_old = c( + "vertex.color1", + "vertex.color2", + "edge.color1", + "edge.color2" + ), + match_names = c( + "vertex.color1", + "vertex.color2", + "edge.color1", + "edge.color2" + ), + match_to = c( + "vertex.color1", + "vertex.color2", + "edge.color1", + "edge.color2" + ), + defaults = list( + vertex.color1 = NULL, + vertex.color2 = NULL, + edge.color1 = NULL, + edge.color2 = NULL + ), + head_args = c("graph1", "graph2"), + fn_name = "graph.count.subisomorphisms.vf2" + ) + list2env(.arg_handle$values, environment()) + lifecycle::deprecate_soft( + "3.0.0", + what = I(.arg_handle$what), + details = .arg_handle$details + ) + } + # END GENERATED ARG_HANDLE + count_subisomorphisms_vf2_impl( graph1 = graph1, graph2 = graph2, @@ -1021,13 +1301,41 @@ graph.isoclass <- function(graph) { #' #' @param size The number of vertices in the graph. #' @param number The isomorphism class. +#' @inheritParams rlang::args_dots_empty #' @param directed Whether to create a directed graph (the default). #' @return An igraph object, the graph of the given size, directedness #' and isomorphism class. #' #' @family graph isomorphism #' @export -graph_from_isomorphism_class <- function(size, number, directed = TRUE) { +graph_from_isomorphism_class <- function( + size, + number, + ..., + directed = TRUE +) { + # BEGIN GENERATED ARG_HANDLE: graph_from_isomorphism_class, do not edit, see tools/generate-migrations.R + if (...length() > 0L) { + .arg_handle <- migrate_recover_args( + list(...), + current = list(directed = directed), + recover_new = c("directed"), + recover_old = c("directed"), + match_names = c("directed"), + match_to = c("directed"), + defaults = list(directed = TRUE), + head_args = c("size", "number"), + fn_name = "graph_from_isomorphism_class" + ) + list2env(.arg_handle$values, environment()) + lifecycle::deprecate_soft( + "3.0.0", + what = I(.arg_handle$what), + details = .arg_handle$details + ) + } + # END GENERATED ARG_HANDLE + isoclass_create_impl( size = size, number = number, @@ -1079,6 +1387,7 @@ graph_from_isomorphism_class <- function(size, number, directed = TRUE) { #' vertices, or, if there is no such vertex attribute, it simply assumes that #' all vertices have the same color. Pass NULL explicitly if the graph has a #' `color` vertex attribute but you do not want to use it. +#' @inheritParams rlang::args_dots_empty #' @param sh Type of the heuristics to use for the BLISS algorithm. See details #' for possible values. #' @return A list with the following members: @@ -1146,8 +1455,31 @@ graph_from_isomorphism_class <- function(size, number, directed = TRUE) { canonical_permutation <- function( graph, colors = NULL, + ..., sh = c("fm", "f", "fs", "fl", "flm", "fsm") ) { + # BEGIN GENERATED ARG_HANDLE: canonical_permutation, do not edit, see tools/generate-migrations.R + if (...length() > 0L) { + .arg_handle <- migrate_recover_args( + list(...), + current = list(sh = sh), + recover_new = c("sh"), + recover_old = c("sh"), + match_names = c("sh"), + match_to = c("sh"), + defaults = list(sh = c("fm", "f", "fs", "fl", "flm", "fsm")), + head_args = c("graph", "colors"), + fn_name = "canonical_permutation" + ) + list2env(.arg_handle$values, environment()) + lifecycle::deprecate_soft( + "3.0.0", + what = I(.arg_handle$what), + details = .arg_handle$details + ) + } + # END GENERATED ARG_HANDLE + canonical_permutation_impl( graph = graph, colors = if (missing(colors)) missing_arg() else colors, @@ -1230,6 +1562,7 @@ graph.isomorphic <- function(graph1, graph2) { #' vertices, or, if there is no such vertex attribute, it simply assumes that #' all vertices have the same color. Pass NULL explicitly if the graph has a #' `color` vertex attribute but you do not want to use it. +#' @inheritParams rlang::args_dots_empty #' @param sh The splitting heuristics for the BLISS algorithm. Possible values #' are: #' \sQuote{`f`}: @@ -1295,8 +1628,31 @@ graph.isomorphic <- function(graph1, graph2) { count_automorphisms <- function( graph, colors = NULL, + ..., sh = c("fm", "f", "fs", "fl", "flm", "fsm") ) { + # BEGIN GENERATED ARG_HANDLE: count_automorphisms, do not edit, see tools/generate-migrations.R + if (...length() > 0L) { + .arg_handle <- migrate_recover_args( + list(...), + current = list(sh = sh), + recover_new = c("sh"), + recover_old = c("sh"), + match_names = c("sh"), + match_to = c("sh"), + defaults = list(sh = c("fm", "f", "fs", "fl", "flm", "fsm")), + head_args = c("graph", "colors"), + fn_name = "count_automorphisms" + ) + list2env(.arg_handle$values, environment()) + lifecycle::deprecate_soft( + "3.0.0", + what = I(.arg_handle$what), + details = .arg_handle$details + ) + } + # END GENERATED ARG_HANDLE + count_automorphisms_impl( graph = graph, colors = if (missing(colors)) missing_arg() else colors, @@ -1328,6 +1684,7 @@ count_automorphisms <- function( #' vertices, or, if there is no such vertex attribute, it simply assumes that #' all vertices have the same color. Pass NULL explicitly if the graph has a #' `color` vertex attribute but you do not want to use it. +#' @inheritParams rlang::args_dots_empty #' @param sh The splitting heuristics for the BLISS algorithm. Possible values #' are: #' \sQuote{`f`}: @@ -1379,9 +1736,35 @@ count_automorphisms <- function( automorphism_group <- function( graph, colors = NULL, + ..., sh = c("fm", "f", "fs", "fl", "flm", "fsm"), details = FALSE ) { + # BEGIN GENERATED ARG_HANDLE: automorphism_group, do not edit, see tools/generate-migrations.R + if (...length() > 0L) { + .arg_handle <- migrate_recover_args( + list(...), + current = list(sh = sh, details = details), + recover_new = c("sh", "details"), + recover_old = c("sh", "details"), + match_names = c("sh", "details"), + match_to = c("sh", "details"), + defaults = list( + sh = c("fm", "f", "fs", "fl", "flm", "fsm"), + details = FALSE + ), + head_args = c("graph", "colors"), + fn_name = "automorphism_group" + ) + list2env(.arg_handle$values, environment()) + lifecycle::deprecate_soft( + "3.0.0", + what = I(.arg_handle$what), + details = .arg_handle$details + ) + } + # END GENERATED ARG_HANDLE + automorphism_group_impl( graph = graph, colors = if (missing(colors)) missing_arg() else colors, diff --git a/man/automorphism_group.Rd b/man/automorphism_group.Rd index f9e6dbcabc4..ad0087f2356 100644 --- a/man/automorphism_group.Rd +++ b/man/automorphism_group.Rd @@ -7,6 +7,7 @@ automorphism_group( graph, colors = NULL, + ..., sh = c("fm", "f", "fs", "fl", "flm", "fsm"), details = FALSE ) @@ -21,6 +22,8 @@ vertices, or, if there is no such vertex attribute, it simply assumes that all vertices have the same color. Pass NULL explicitly if the graph has a \code{color} vertex attribute but you do not want to use it.} +\item{...}{These dots are for future extensions and must be empty.} + \item{sh}{The splitting heuristics for the BLISS algorithm. Possible values are: \sQuote{\code{f}}: diff --git a/man/canonical_permutation.Rd b/man/canonical_permutation.Rd index bb0cc7a3cbb..9963a306968 100644 --- a/man/canonical_permutation.Rd +++ b/man/canonical_permutation.Rd @@ -7,6 +7,7 @@ canonical_permutation( graph, colors = NULL, + ..., sh = c("fm", "f", "fs", "fl", "flm", "fsm") ) } @@ -20,6 +21,8 @@ vertices, or, if there is no such vertex attribute, it simply assumes that all vertices have the same color. Pass NULL explicitly if the graph has a \code{color} vertex attribute but you do not want to use it.} +\item{...}{These dots are for future extensions and must be empty.} + \item{sh}{Type of the heuristics to use for the BLISS algorithm. See details for possible values.} } diff --git a/man/count_automorphisms.Rd b/man/count_automorphisms.Rd index 3f614f09a16..522ba3b2274 100644 --- a/man/count_automorphisms.Rd +++ b/man/count_automorphisms.Rd @@ -7,6 +7,7 @@ count_automorphisms( graph, colors = NULL, + ..., sh = c("fm", "f", "fs", "fl", "flm", "fsm") ) } @@ -20,6 +21,8 @@ vertices, or, if there is no such vertex attribute, it simply assumes that all vertices have the same color. Pass NULL explicitly if the graph has a \code{color} vertex attribute but you do not want to use it.} +\item{...}{These dots are for future extensions and must be empty.} + \item{sh}{The splitting heuristics for the BLISS algorithm. Possible values are: \sQuote{\code{f}}: diff --git a/man/graph_from_isomorphism_class.Rd b/man/graph_from_isomorphism_class.Rd index fa89079a16b..cd518d3c408 100644 --- a/man/graph_from_isomorphism_class.Rd +++ b/man/graph_from_isomorphism_class.Rd @@ -4,13 +4,15 @@ \alias{graph_from_isomorphism_class} \title{Create a graph from an isomorphism class} \usage{ -graph_from_isomorphism_class(size, number, directed = TRUE) +graph_from_isomorphism_class(size, number, ..., directed = TRUE) } \arguments{ \item{size}{The number of vertices in the graph.} \item{number}{The isomorphism class.} +\item{...}{These dots are for future extensions and must be empty.} + \item{directed}{Whether to create a directed graph (the default).} } \value{ diff --git a/tests/testthat/test-topology.R b/tests/testthat/test-topology.R index fc37fadde1e..b3e6f777e91 100644 --- a/tests/testthat/test-topology.R +++ b/tests/testthat/test-topology.R @@ -601,3 +601,265 @@ test_that("subisomorphisms works with callback handles errors in callback", { "Error in R callback function" ) }) + +# ---- ellipsis migration: argument coverage ---------------------------- + +test_that("graph.subisomorphic.lad() tail arguments and legacy positional recovery", { + path <- make_ring(3, circular = FALSE) + ring <- make_ring(4) + # Restrict the middle path vertex to ring vertex 2. + domains <- list(c(1, 3), 2, c(1, 3)) + + res <- graph.subisomorphic.lad( + path, + ring, + domains = domains, + induced = TRUE, + map = FALSE, + all.maps = TRUE, + time.limit = 60 + ) + expect_true(res$iso) + # Both maps must route the middle path vertex through ring vertex 2. + expect_length(res$maps, 2) + expect_true( + all(vapply(res$maps, function(m) as.vector(m)[[2]], numeric(1)) == 2) + ) + + lifecycle::expect_deprecated( + res2 <- graph.subisomorphic.lad(path, ring, domains) + ) + expect_identical(res2, graph.subisomorphic.lad(path, ring, domains = domains)) +}) + +test_that("graph.isomorphic.bliss() tail arguments and legacy positional recovery", { + ring <- make_ring(4) + + # The block coloring and the alternating coloring of a 4-ring are not + # isomorphic as colored graphs. + res <- graph.isomorphic.bliss( + ring, + ring, + colors1 = c(1, 1, 2, 2), + colors2 = c(1, 2, 1, 2), + sh = "fl" + ) + expect_false(res$iso) + + # With identical colorings the graphs remain isomorphic. + res_same <- graph.isomorphic.bliss( + ring, + ring, + colors1 = c(1, 2, 1, 2), + colors2 = c(1, 2, 1, 2), + sh = "fl" + ) + expect_true(res_same$iso) + + lifecycle::expect_deprecated( + res2 <- graph.isomorphic.bliss(ring, ring, c(1, 1, 2, 2), c(1, 2, 1, 2)) + ) + expect_identical( + res2, + graph.isomorphic.bliss( + ring, + ring, + colors1 = c(1, 1, 2, 2), + colors2 = c(1, 2, 1, 2) + ) + ) +}) + +test_that("graph.isomorphic.vf2() tail arguments and legacy positional recovery", { + tri <- make_ring(3) + + res <- graph.isomorphic.vf2( + tri, + tri, + vertex.color1 = c(1, 2, 3), + vertex.color2 = c(1, 2, 3), + edge.color1 = c(1, 1, 2), + edge.color2 = c(1, 1, 2) + ) + expect_true(res$iso) + expect_equal(res$map12, 1:3) + + # Different vertex color multiplicities break the colored isomorphism. + res_no <- graph.isomorphic.vf2( + tri, + tri, + vertex.color1 = c(1, 1, 2), + vertex.color2 = c(1, 2, 2) + ) + expect_false(res_no$iso) + + lifecycle::expect_deprecated( + res2 <- graph.isomorphic.vf2(tri, tri, c(1, 2, 3), c(1, 2, 3)) + ) + expect_identical( + res2, + graph.isomorphic.vf2( + tri, + tri, + vertex.color1 = c(1, 2, 3), + vertex.color2 = c(1, 2, 3) + ) + ) +}) + +test_that("graph.subisomorphic.vf2() tail arguments and legacy positional recovery", { + full <- make_full_graph(4) + tri <- make_ring(3) + + res <- graph.subisomorphic.vf2( + full, + tri, + vertex.color1 = c(1, 1, 1, 2), + vertex.color2 = c(1, 1, 1), + edge.color1 = rep(1, 6), + edge.color2 = rep(1, 3) + ) + expect_true(res$iso) + # The triangle can only map onto the three like-colored vertices. + expect_true(all(res$map21 <= 3)) + + lifecycle::expect_deprecated( + res2 <- graph.subisomorphic.vf2(full, tri, c(1, 1, 1, 2), c(1, 1, 1)) + ) + expect_identical( + res2, + graph.subisomorphic.vf2( + full, + tri, + vertex.color1 = c(1, 1, 1, 2), + vertex.color2 = c(1, 1, 1) + ) + ) +}) + +test_that("graph.count.isomorphisms.vf2() tail arguments and legacy positional recovery", { + tri <- make_ring(3) + + # Mutually distinct vertex colors leave only the identity mapping. + res <- graph.count.isomorphisms.vf2( + tri, + tri, + vertex.color1 = c(1, 2, 3), + vertex.color2 = c(1, 2, 3), + edge.color1 = c(2, 2, 2), + edge.color2 = c(2, 2, 2) + ) + expect_equal(res, 1) + + lifecycle::expect_deprecated( + res2 <- graph.count.isomorphisms.vf2(tri, tri, c(1, 2, 3), c(1, 2, 3)) + ) + expect_identical( + res2, + graph.count.isomorphisms.vf2( + tri, + tri, + vertex.color1 = c(1, 2, 3), + vertex.color2 = c(1, 2, 3) + ) + ) +}) + +test_that("graph.count.subisomorphisms.vf2() tail arguments and legacy positional recovery", { + full <- make_full_graph(4) + tri <- make_ring(3) + + # Uncolored, the triangle maps into the full graph in 24 ways. + # Coloring one vertex differently leaves the 6 mappings within the + # like-colored triangle. + res <- graph.count.subisomorphisms.vf2( + full, + tri, + vertex.color1 = c(1, 1, 1, 2), + vertex.color2 = c(1, 1, 1), + edge.color1 = rep(1, 6), + edge.color2 = rep(1, 3) + ) + expect_equal(res, 6) + expect_equal(graph.count.subisomorphisms.vf2(full, tri), 24) + + lifecycle::expect_deprecated( + res2 <- graph.count.subisomorphisms.vf2( + full, + tri, + c(1, 1, 1, 2), + c(1, 1, 1) + ) + ) + expect_identical( + res2, + graph.count.subisomorphisms.vf2( + full, + tri, + vertex.color1 = c(1, 1, 1, 2), + vertex.color2 = c(1, 1, 1) + ) + ) +}) + +test_that("graph_from_isomorphism_class() tail arguments and legacy positional recovery", { + # Undirected isomorphism class 3 on 3 vertices is the triangle. + g <- graph_from_isomorphism_class(3, 3, directed = FALSE) + expect_false(is_directed(g)) + expect_equal(vcount(g), 3) + expect_equal(ecount(g), 3) + expect_equal(isomorphism_class(g), 3) + + lifecycle::expect_deprecated( + res <- graph_from_isomorphism_class(3, 3, FALSE) + ) + expect_identical_graphs( + res, + graph_from_isomorphism_class(3, 3, directed = FALSE) + ) +}) + +test_that("canonical_permutation() tail arguments and legacy positional recovery", { + ring <- make_ring(4) + + # Alternating colors cut the automorphism group of the 4-ring from 8 to 4. + res <- canonical_permutation(ring, colors = c(1, 2, 1, 2), sh = "fs") + expect_setequal(res$labeling, 1:4) + expect_equal(res$info$group_size, "4") + + lifecycle::expect_deprecated( + res2 <- canonical_permutation(ring, NULL, "fs") + ) + expect_identical(res2, canonical_permutation(ring, NULL, sh = "fs")) +}) + +test_that("count_automorphisms() tail arguments and legacy positional recovery", { + ring <- make_ring(10) + + # The 10-ring has 20 automorphisms whatever the splitting heuristics. + res <- count_automorphisms(ring, colors = NULL, sh = "fl") + expect_equal(res$group_size, "20") + + lifecycle::expect_deprecated( + res2 <- count_automorphisms(ring, NULL, "fl") + ) + expect_identical(res2, count_automorphisms(ring, NULL, sh = "fl")) +}) + +test_that("automorphism_group() tail arguments and legacy positional recovery", { + ring <- make_ring(10) + + res <- automorphism_group(ring, colors = NULL, sh = "fl", details = TRUE) + expect_named(res, c("generators", "info")) + expect_equal(res$info$group_size, "20") + # Each generator is a permutation of the vertices. + for (gen in res$generators) { + expect_setequal(as.vector(gen), 1:10) + } + + lifecycle::expect_deprecated( + res2 <- automorphism_group(ring, NULL, "fl") + ) + ref <- automorphism_group(ring, NULL, sh = "fl") + expect_identical(lapply(res2, as.vector), lapply(ref, as.vector)) +}) diff --git a/tools/migrations/topology.R b/tools/migrations/topology.R new file mode 100644 index 00000000000..aa07e57e5a6 --- /dev/null +++ b/tools/migrations/topology.R @@ -0,0 +1,170 @@ +# Argument-signature migrations: topology +# Schema: see tools/migrations/README.md. Regenerate with: +# Rscript tools/generate-migrations.R + +migrations <- list( + automorphism_group = list( + old = function(graph, colors, sh, details) {}, + new = function( + graph, + colors = NULL, + ..., + sh = c("fm", "f", "fs", "fl", "flm", "fsm"), + details = FALSE + ) {}, + when = "3.0.0" + ), + + canonical_permutation = list( + old = function(graph, colors, sh) {}, + new = function( + graph, + colors = NULL, + ..., + sh = c("fm", "f", "fs", "fl", "flm", "fsm") + ) {}, + when = "3.0.0" + ), + + count_automorphisms = list( + old = function(graph, colors, sh) {}, + new = function( + graph, + colors = NULL, + ..., + sh = c("fm", "f", "fs", "fl", "flm", "fsm") + ) {}, + when = "3.0.0" + ), + + graph.count.isomorphisms.vf2 = list( + old = function( + graph1, + graph2, + vertex.color1, + vertex.color2, + edge.color1, + edge.color2 + ) {}, + new = function( + graph1, + graph2, + ..., + vertex.color1 = NULL, + vertex.color2 = NULL, + edge.color1 = NULL, + edge.color2 = NULL + ) {}, + when = "3.0.0" + ), + + graph.count.subisomorphisms.vf2 = list( + old = function( + graph1, + graph2, + vertex.color1, + vertex.color2, + edge.color1, + edge.color2 + ) {}, + new = function( + graph1, + graph2, + ..., + vertex.color1 = NULL, + vertex.color2 = NULL, + edge.color1 = NULL, + edge.color2 = NULL + ) {}, + when = "3.0.0" + ), + + graph.isomorphic.bliss = list( + old = function(graph1, graph2, colors1, colors2, sh) {}, + new = function( + graph1, + graph2, + ..., + colors1 = NULL, + colors2 = NULL, + sh = c("fm", "f", "fs", "fl", "flm", "fsm") + ) {}, + when = "3.0.0" + ), + + graph.isomorphic.vf2 = list( + old = function( + graph1, + graph2, + vertex.color1, + vertex.color2, + edge.color1, + edge.color2 + ) {}, + new = function( + graph1, + graph2, + ..., + vertex.color1 = NULL, + vertex.color2 = NULL, + edge.color1 = NULL, + edge.color2 = NULL + ) {}, + when = "3.0.0" + ), + + graph.subisomorphic.lad = list( + old = function( + pattern, + target, + domains, + induced, + map, + all.maps, + time.limit + ) {}, + new = function( + pattern, + target, + ..., + domains = NULL, + induced = FALSE, + map = TRUE, + all.maps = FALSE, + time.limit = Inf + ) {}, + when = "3.0.0" + ), + + graph.subisomorphic.vf2 = list( + old = function( + graph1, + graph2, + vertex.color1, + vertex.color2, + edge.color1, + edge.color2 + ) {}, + new = function( + graph1, + graph2, + ..., + vertex.color1 = NULL, + vertex.color2 = NULL, + edge.color1 = NULL, + edge.color2 = NULL + ) {}, + when = "3.0.0" + ), + + graph_from_isomorphism_class = list( + old = function(size, number, directed) {}, + new = function( + size, + number, + ..., + directed = TRUE + ) {}, + when = "3.0.0" + ) +)