diff --git a/examples/Ising.jl b/examples/Ising.jl index 1f1cb8a5..5e622656 100644 --- a/examples/Ising.jl +++ b/examples/Ising.jl @@ -27,7 +27,7 @@ paths = reduction_paths(g,Factoring,SpinGlass) # The input of `reduction_paths` is the reduction graph and the types of source and target problems. And the output # is a nested vector, each element of the outer vector is a path from source to target problem. -# Then we could use [`implement_reduction_path`](@ref) to obtain the corresponding SpinGlass problem. +# Then we could use [`reduceto`](@ref) to obtain the corresponding SpinGlass problem. reduction_result = implement_reduction_path(paths[1], factoring) target = target_problem(reduction_result) diff --git a/src/ProblemReductions.jl b/src/ProblemReductions.jl index cb01f44f..17c95be8 100644 --- a/src/ProblemReductions.jl +++ b/src/ProblemReductions.jl @@ -44,7 +44,7 @@ export ReductionIndependentSetToSetPacking export ReductionSATToCircuit # reduction path -export ReductionGraph, reduction_graph, reduction_paths, implement_reduction_path, ConcatenatedReduction +export ReductionGraph, reduction_graph, reduction_paths, ConcatenatedReduction include("truth_table.jl") include("topology.jl") @@ -55,4 +55,6 @@ include("bruteforce.jl") include("reduction_path.jl") include("deprecated.jl") +@deprecate implement_reduction_path(path::ReductionPath, problem::AbstractProblem) reduceto(path, problem) + end diff --git a/src/reduction_path.jl b/src/reduction_path.jl index 438137d5..280c5a4c 100644 --- a/src/reduction_path.jl +++ b/src/reduction_path.jl @@ -74,16 +74,7 @@ function extract_solution(cr::ConcatenatedReduction, sol) return sol end -""" - implement_reduction_path(rg::ReductionGraph, path::ReductionPath, problem::AbstractProblem) - -Implement a reduction path on a problem. Returns a [`ConcatenatedReduction`](@ref) instance. - -### Arguments -- `path::ReductionPath`: A sequence of problem types, each element is an [`AbstractProblem`](@ref) instance. -- `problem::AbstractProblem`: The source problem, the type of which must be the same as the first node in the path. -""" -function implement_reduction_path(path::ReductionPath, problem::AbstractProblem) +function reduceto(path::ReductionPath, problem::AbstractProblem) @assert problem isa path.nodes[1] "The problem type must be the same as the first node: $(path.nodes[1]), got: $problem" sequence = [] for method in path.methods @@ -102,7 +93,7 @@ identity_reduction(::Type{<:AbstractProblem}, source) = IdentityReductionResult( Returns a [`ReductionGraph`](@ref) instance from the reduction rules defined with method `reduceto`. """ function reduction_graph() - ms = methods(reduceto) + ms = filter(m->m.sig.types[2] <: Type{<:AbstractProblem}, methods(reduceto)) rules = extract_types.(getfield.(ms, :sig)) nodes = unique!(vcat(concrete_subtypes(AbstractProblem), first.(rules), last.(rules))) graph = SimpleDiGraph(length(nodes)) diff --git a/src/rules/rules.jl b/src/rules/rules.jl index 27d1cf58..d899888f 100644 --- a/src/rules/rules.jl +++ b/src/rules/rules.jl @@ -19,14 +19,16 @@ function target_problem end target_problem(res::IdentityReductionResult) = res.problem """ - reduceto(::Type{TA}, x::AbstractProblem) + reduceto(problem_type::Type{<:AbstractProblem}, problem::AbstractProblem) -> AbstractReductionResult + reduceto(path::ReductionPath, problem::AbstractProblem) -> ConcatenatedReduction -Reduce the problem `x` to a target problem of type `TA`. -Returns an instance of `AbstractReductionResult`. +If the target problem is a single problem type, reduce the problem `problem` to a target problem of type. +Then the result is an instance of [`AbstractReductionResult`](@ref). +Otherwise, if the target problem is a reduction path, implement a reduction path on a problem. Then the result is a [`ConcatenatedReduction`](@ref) instance. ### Arguments -- `TA`: The target problem type. -- `x`: The original problem. +- `problem_type::Type{<:AbstractProblem}` or `path::ReductionPath`: The target problem type or a reduction path. +- `problem::AbstractProblem`: The original problem. """ function reduceto end diff --git a/src/rules/sat_independentset.jl b/src/rules/sat_independentset.jl index c55e7f60..e7b015f2 100644 --- a/src/rules/sat_independentset.jl +++ b/src/rules/sat_independentset.jl @@ -32,9 +32,9 @@ function reduceto(::Type{IndependentSet{<:SimpleGraph}}, s::AbstractSatisfiabili return ReductionSATToIndependentSet(IndependentSet(g), literals, variables(s), length(clauses(s))) end -function extract_solution(res::ReductionSATToIndependentSet, sol) +function extract_solution(res::ReductionSATToIndependentSet{ST}, sol) where ST assignment = falses(length(res.source_variables)) - covered_literals_name = Vector{Symbol}() + covered_literals_name = Vector{ST}() for (literal, value) in zip(res.literals, sol) iszero(value) && continue assignment[findfirst(==(literal.name), res.source_variables)] = !literal.neg diff --git a/test/reduction_path.jl b/test/reduction_path.jl index 3867b12c..02e2a3ba 100644 --- a/test/reduction_path.jl +++ b/test/reduction_path.jl @@ -5,13 +5,13 @@ using ProblemReductions, Test, Graphs @test g isa ReductionGraph paths = reduction_paths(MaxCut, SpinGlass) @test length(paths) >= 1 - res = implement_reduction_path(paths[1], MaxCut(smallgraph(:petersen))) + res = reduceto(paths[1], MaxCut(smallgraph(:petersen))) @test target_problem(res) isa SpinGlass paths = reduction_paths(MaxCut, QUBO) @test length(paths) >= 1 source = MaxCut(smallgraph(:petersen)) - res = implement_reduction_path(paths[1], source) + res = reduceto(paths[1], source) @test target_problem(res) isa QUBO best1 = findbest(source, BruteForce()) @@ -25,7 +25,7 @@ end # implement the reduction path factoring = Factoring(2, 1, 3) - res = implement_reduction_path(paths[1], factoring) + res = reduceto(paths[1], factoring) @test target_problem(res) isa SpinGlass @test configuration_space_size(target_problem(res)) ≈ 25 sol = findbest(target_problem(res), BruteForce())