Skip to content

Commit

Permalink
Refactor (#106)
Browse files Browse the repository at this point in the history
* update

* update

* update

* fix rules

* fix tests and documents

* new reduction path

* update

* update

* fix tests

* fix ci

* improve test coverage
  • Loading branch information
GiggleLiu authored Oct 9, 2024
1 parent 614c537 commit f5b26e1
Show file tree
Hide file tree
Showing 77 changed files with 877 additions and 602 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ jobs:
- uses: actions/checkout@v4
- uses: julia-actions/setup-julia@v2
with:
version: '1'
version: '1.10'
- uses: julia-actions/cache@v2
- name: Configure doc environment
shell: julia --project=docs --color=yes {0}
Expand Down
9 changes: 4 additions & 5 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,23 @@ version = "0.1.0"
[deps]
BitBasis = "50ba71b6-fa0f-514d-ae9a-0916efc90dcf"
DocStringExtensions = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae"
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6"
InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
MLStyle = "d8e11817-5142-5d16-987a-aa16d5891078"
PrettyTables = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d"
UnitDiskMapping = "1b61a8d9-79ed-4491-8266-ef37f39e1727"

[compat]
BitBasis = "0.9"
DocStringExtensions = "0.9"
Documenter = "1"
Graphs = "1"
InteractiveUtils = "1"
MLStyle = "0.4"
PrettyTables = "2"
UnitDiskMapping = "0.3, 0.4"
julia = "1.10"

[extras]
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["Test"]
test = ["Test", "Documenter"]
3 changes: 1 addition & 2 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ makedocs(;
doctest = ("doctest=true" in ARGS),
pages=[
"Home" => "index.md",
"Interfaces" => ["models.md", "topology.md", "rules.md"],
"Models" => [
"models/CircuitSAT.md",
"models/Coloring.md",
Expand All @@ -45,9 +44,9 @@ makedocs(;
"rules/independentset_setpacking.md"
],
"Examples" => [
"generated/material_compute.md",
"generated/Ising.md",
],
"Interfaces" => ["models.md", "topology.md", "rules.md"],
"Reference" => "ref.md",
],
)
Expand Down
8 changes: 4 additions & 4 deletions docs/src/models.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ Required functions include:
- [`flavors`](@ref): A vector of integers as the flavors (or domain) of a degree of freedom.
e.g. for the maximum independent set problems, the flavors are [0, 1], where 0 means the vertex is not in the set and 1 means the vertex is in the set.

- [`parameters`](@ref): Energies associated with terms.
- [`weights`](@ref): Energies associated with constraints.

- [`evaluate`](@ref): Evaluate the energy of a given configuration.
- [`energy`](@ref): Energy of a given configuration.

Optional functions include:
- [`num_variables`](@ref): The number of variables in the problem.
- [`num_flavors`](@ref): The number of flavors in the problem.
- [`set_parameters`](@ref): Change the parameters for the `problem` and return a new problem instance.
- [`parameter_type`](@ref): The data type of parameters.
- [`set_weights`](@ref): Change the weights for the `problem` and return a new problem instance.
- [`weight_type`](@ref): The data type of weights.
- [`findbest`](@ref): Find the best configurations in the computational problem.
6 changes: 3 additions & 3 deletions docs/src/models/CircuitSAT.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ variables(sat)
flavors(sat)
```

The circuit can be evaluated with the [`evaluate`](@ref) function:
The circuit can be evaluated with the [`energy`](@ref) function:
```@repl CircuitSAT
evaluate(sat, [true, false, true, true, false, false, true])
energy(sat, [true, false, true, true, false, false, true])
```
The return value is 0 if the assignment satisfies the circuit, otherwise, it is the number of unsatisfied clauses.
!!! note
[`evaluate`](@ref) funciton returns lower values for satisfiable assignments.
[`energy`](@ref) funciton returns lower values for satisfiable assignments.

To find all satisfying assignments, use the [`findbest`](@ref) function:
```@repl CircuitSAT
Expand Down
4 changes: 2 additions & 2 deletions docs/src/models/Coloring.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ coloring = Coloring{3}(g)
```
We create a petersen graph and take 3 colors here to initialize a Coloring Problem.

Functions [`variables`](@ref), [`flavors`](@ref), [`num_flavors`](@ref), [`parameters`](@ref) and [`set_parameters`](@ref) are implemented for `Coloring` model.
Functions [`variables`](@ref), [`flavors`](@ref), [`num_flavors`](@ref), [`weights`](@ref) and [`set_weights`](@ref) are implemented for `Coloring` model.
```@repl Coloring
variables(coloring)
flavors(coloring)
```

Also, [`evaluate`](@ref) and [`is_vertex_coloring`](@ref) is also implemented.
Also, [`energy`](@ref) and [`is_vertex_coloring`](@ref) is also implemented.
```@repl Coloring
is_vertex_coloring(coloring.graph,[1,2,3,1,3,2,1,2,3,1]) #random assignment
```
6 changes: 3 additions & 3 deletions docs/src/models/DominatingSet.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ add_edge!(graph, 4, 5)
DS = DominatingSet(graph)
```

Besides, the required functions, [`variables`](@ref), [`flavors`](@ref), and [`evaluate`](@ref), and optional functions, [`findbest`](@ref), are implemented for the Dominating Set problem.
Besides, the required functions, [`variables`](@ref), [`flavors`](@ref), and [`energy`](@ref), and optional functions, [`findbest`](@ref), are implemented for the Dominating Set problem.
```@repl DominatingSet
variables(DS) # degrees of freedom
flavors(DS) # flavors of the vertices
evaluate(DS, [0, 1, 0, 1, 0]) # Positive sample: (size) of a dominating set
evaluate(DS, [0, 1, 1, 0, 0]) # Negative sample: number of vertices
energy(DS, [0, 1, 0, 1, 0]) # Positive sample: (size) of a dominating set
energy(DS, [0, 1, 1, 0, 0]) # Negative sample: number of vertices
findbest(DS, BruteForce()) # solve the problem with brute force
```
6 changes: 3 additions & 3 deletions docs/src/models/Factoring.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ factoring = Factoring(2,2,6)
```
Here, the two `2` is the factors' bit size and `6` is the number to be factored. $6$ is $110$ in binary so its factors should be 2-bits number.

Functions [`variables`](@ref),[`flavors`](@ref) and [`evaluate`](@ref) are implemented for `Factoring` model.
Functions [`variables`](@ref),[`flavors`](@ref) and [`energy`](@ref) are implemented for `Factoring` model.

```@repl Factoring
variables(factoring) # return the sum of factors' bit size
flavors(factoring)
evaluate(factoring,[0,1,1,1]) # 01 -> 2, 11 -> 3
energy(factoring,[0,1,1,1]) # 01 -> 2, 11 -> 3
```

!!! note
`evaluate` function return `0` if the config is a correct factorization and `1` otherwise.
`energy` function return `0` if the config is a correct factorization and `1` otherwise.
6 changes: 3 additions & 3 deletions docs/src/models/IndependentSet.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ add_edge!(graph, 2, 3)
IS = IndependentSet(graph)
```

Besides, the required functions, [`variables`](@ref), [`flavors`](@ref), and [`evaluate`](@ref), and optional functions, [`findbest`](@ref), are implemented for the Independent Set problem.
Besides, the required functions, [`variables`](@ref), [`flavors`](@ref), and [`energy`](@ref), and optional functions, [`findbest`](@ref), are implemented for the Independent Set problem.
```@repl IndependentSet
variables(IS) # degrees of freedom
flavors(IS) # flavors of the vertices
evaluate(IS, [1, 0, 0, 1]) # Positive sample: -(size) of an independent set
evaluate(IS, [0, 1, 1, 0]) # Negative sample: 0
energy(IS, [1, 0, 0, 1]) # Positive sample: -(size) of an independent set
energy(IS, [0, 1, 1, 0]) # Negative sample: 0
findbest(IS, BruteForce()) # solve the problem with brute force
```
4 changes: 2 additions & 2 deletions docs/src/models/MaxCut.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ maxcut = MaxCut(g,[1,2,3]) # specify the weights of the edges

Here the graph is a simple graph with 3 vertices and 3 edges. The weights of the edges are `[1,2,3]`.

Required functions and optional functions: [`set_parameters`](@ref), [`num_variables`](@ref) are implemented for this model.
Required functions and optional functions: [`set_weights`](@ref), [`num_variables`](@ref) are implemented for this model.
```@repl MaxCut
mc = set_parameters(maxcut, [2,1,3]) # set the weights and get a new instance
mc = set_weights(maxcut, [2,1,3]) # set the weights and get a new instance
num_variables(maxcut) # return the number of vertices
```
6 changes: 3 additions & 3 deletions docs/src/models/QUBO.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ graph = SimpleGraph(3)
QUBO02 = QUBO(graph, Float64[], [1., 1., 1.])
```

Besides, the required functions, [`variables`](@ref), [`flavors`](@ref), and [`evaluate`](@ref), and optional functions, [`findbest`](@ref), are implemented for the [`QUBO`] problem.
Besides, the required functions, [`variables`](@ref), [`flavors`](@ref), and [`energy`](@ref), and optional functions, [`findbest`](@ref), are implemented for the [`QUBO`] problem.
```@repl QUBO
variables(QUBO01) # degrees of freedom
variables(QUBO02)
flavors(QUBO01) # flavors of the vertices
evaluate(QUBO01, [0, 1, 0])
evaluate(QUBO02, [0, 1, 0])
energy(QUBO01, [0, 1, 0])
energy(QUBO02, [0, 1, 0])
findbest(QUBO01, BruteForce()) # solve the problem with brute force
findbest(QUBO02, BruteForce())
```
6 changes: 3 additions & 3 deletions docs/src/models/Satisfiability.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ cnf_test = CNF([clause1, clause2])
sat_test = Satisfiability(cnf_test)
```

Besides, the required functions, [`variables`](@ref), [`flavors`](@ref), and [`evaluate`](@ref), and optional functions, [`findbest`](@ref), are implemented for the Satisfiability problem.
Besides, the required functions, [`variables`](@ref), [`flavors`](@ref), and [`energy`](@ref), and optional functions, [`findbest`](@ref), are implemented for the Satisfiability problem.
```@repl Satisfiability
variables(sat_test) # degrees of freedom
flavors(sat_test) # flavors of the literals
evaluate(sat_test, [1, 1, 1, 1]) # Positive sample
evaluate(sat_test, [0, 0, 1, 0]) # Negative sample
energy(sat_test, [1, 1, 1, 1]) # Positive sample
energy(sat_test, [0, 0, 1, 0]) # Negative sample
findbest(sat_test, BruteForce()) # solve the problem with brute force
```

Expand Down
10 changes: 5 additions & 5 deletions docs/src/models/SetCovering.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ setcovering = SetCovering(subsets, weights)
```
Use 2-dimensional vector to represent the subsets.

The required functions, `variables`, `evaluate`, and optional functions:`set_parameters` are implemented for the set covering problem.
The required functions, `variables`, `energy`, and optional functions:`set_weights` are implemented for the set covering problem.
```@repl SetCovering
variables(setcovering) # degrees of freedom
evaluate(setcovering, [1, 0, 1]) # cost of a configuration
evaluate(setcovering, [0, 1, 1])
sc = set_parameters(setcovering, [1, 2, 3]) # set the weights of the subsets
energy(setcovering, [1, 0, 1]) # cost of a configuration
energy(setcovering, [0, 1, 1])
sc = set_weights(setcovering, [1, 2, 3]) # set the weights of the subsets
```
!!! note
The `evaluate` function returns the cost of a configuration. If the configuration is not a set cover, it returns a large number.
The `energy` function returns the cost of a configuration. If the configuration is not a set cover, it returns a large number.


6 changes: 3 additions & 3 deletions docs/src/models/SetPacking.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ sets = [[1, 2, 5], [1, 3], [2, 4], [3, 6], [2, 3, 6]]
SP = SetPacking(sets)
```

Then, the required functions, [`variables`](@ref), [`flavors`](@ref), and [`evaluate`](@ref), and optional functions, [`findbest`](@ref), are implemented for the Set Packing problem.
Then, the required functions, [`variables`](@ref), [`flavors`](@ref), and [`energy`](@ref), and optional functions, [`findbest`](@ref), are implemented for the Set Packing problem.
```@repl SetPacking
variables(SP) # degrees of freedom
flavors(SP) # flavors of the subsets
evaluate(SP, [1, 0, 0, 1, 0]) # Positive sample: -(size) of a packing
evaluate(SP, [1, 0, 1, 1, 0]) # Negative sample: 0
energy(SP, [1, 0, 0, 1, 0]) # Positive sample: -(size) of a packing
energy(SP, [1, 0, 1, 1, 0]) # Negative sample: 0
findbest(SP, BruteForce()) # solve the problem with brute force
```
14 changes: 9 additions & 5 deletions docs/src/models/SpinGlass.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,15 @@
## Problem Definition
Spin Glass is a type of disordered magnetic system that exhibits a glassy behavior. The Hamiltonian of the system on a simple graph $G$ is given by
```math
H(G, \sigma) = \sum_{(i,j) \in E(G)} J_{ij} \sigma_i \sigma_j
H(G, \sigma) = \sum_{(i,j) \in E(G)} J_{ij} \sigma_i \sigma_j + \sum_{i \in V(G)} h_i \sigma_i
```
where $J_{ij}$ is the coupling strength between spins $i$ and $j$ and $\sigma_i$ is the spin variable that can take values in $\{-1, 1\}$.
where $J_{ij} \in \mathbb{R}$ is the coupling strength between spins $i$ and $j$, $h_i \in \mathbb{R}$ is the external field on spin $i$, and $\sigma_i$ is the spin variable that can take values in $\{-1, 1\}$ for spin up and spin down, respectively.

This definition naturally extends to the case of a [`HyperGraph`](@ref).
This definition naturally extends to the case of a [`HyperGraph`](@ref):
```math
H(G, \sigma) = \sum_{e \in E(G)} J_{e} \prod_k\sigma_k,
```
where $J_e$ is the coupling strength associated with hyperedge $e$, and the product is over all spins in the hyperedge.

## Interfaces

Expand All @@ -24,11 +28,11 @@ spinglass = SpinGlass(graph, J, h) # Define a spin glass problem
Here, we also define an external field $h_i$ for each spin $i$. The resulting spin glass problem is defined on a [`HyperGraph`](@ref), where external fields are associated with hyperedges connecting single spins.


The required functions, [`variables`](@ref), [`flavors`](@ref), and [`evaluate`](@ref), and optional functions, [`findbest`](@ref), are implemented for the spin glass problem.
The required functions, [`variables`](@ref), [`flavors`](@ref), and [`energy`](@ref), and optional functions, [`findbest`](@ref), are implemented for the spin glass problem.

```@repl spinglass
variables(spinglass) # degrees of freedom
flavors(spinglass) # flavors of the spins
evaluate(spinglass, [-1, 1, 1, -1, 1, 1, 1, -1, -1, 1]) # energy of a configuration
energy(spinglass, [-1, 1, 1, -1, 1, 1, 1, -1, -1, 1]) # energy of a configuration
findbest(spinglass, BruteForce()) # solve the problem with brute force
```
10 changes: 5 additions & 5 deletions docs/src/models/VertexCovering.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ weights = [1, 3, 1, 4]
VC= VertexCovering(graph, weights)
```

The required functions, `variables`, `evaluate`, and optional functions: `set_parameters` are implemented for the vertex covering problem.
The required functions, `variables`, `energy`, and optional functions: `set_weights` are implemented for the vertex covering problem.
```@repl VertexCovering
variables(VC) # degrees of freedom
evaluate(VC, [1, 0, 0, 1]) # Negative sample
evaluate(VC, [0, 1, 1, 0]) # Positive sample
energy(VC, [1, 0, 0, 1]) # Negative sample
energy(VC, [0, 1, 1, 0]) # Positive sample
findbest(VC, BruteForce()) # solve the problem with brute force
VC02 = set_parameters(VC, [1, 2, 3, 4]) # set the weights of the subsets
VC02 = set_weights(VC, [1, 2, 3, 4]) # set the weights of the subsets
```
!!! note
The `evaluate` function returns the cost of a configuration. If the configuration is not a vertex cover, it returns a large number.
The `energy` function returns the cost of a configuration. If the configuration is not a vertex cover, it returns a large number.
7 changes: 3 additions & 4 deletions docs/src/rules/independentset_setpacking.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,9 @@ We can firstly define a [`IndependentSet`] (@ref) problem over a simple graph wi
```@repl independentset_setpacking
using ProblemReductions, Graphs
graph = SimpleGraph(4)
add_edge!(graph, 1, 2)
add_edge!(graph, 1, 3)
add_edge!(graph, 3, 4)
add_edge!(graph, 2, 3)
for (i, j) in [(1, 2), (1, 3), (3, 4), (2, 3)]
add_edge!(graph, i, j)
end
IS = IndependentSet(graph)
```
Then the reduction [`ReductionIndependentSetToSetPacking`] (@ref) can be easily constructed by the [`reduceto`](@ref) function.
Expand Down
4 changes: 2 additions & 2 deletions docs/src/rules/spinglass_sat.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ The variables are mapped to integers that pointing to the symbols that stored in

The we can convert the circuit to a [`SpinGlass`](@ref) problem using the [`reduceto`](@ref) function.
```@repl spinglass_sat
result = reduceto(SpinGlass, circuitsat)
result = reduceto(SpinGlass{<:SimpleGraph}, circuitsat)
```
The resulting `result` is a `ReductionCircuitToSpinGlass` instance that contains the spin glass problem.

With the `result` instance, we can define a logic gadget that maps the spin glass variables to the circuit variables.
```@repl spinglass_sat
indexof(x) = findfirst(==(findfirst(==(x), circuitsat.symbols)), result.variables)
indexof(x) = findfirst(==(x), circuitsat.symbols[sortperm(result.variables)])
gadget = LogicGadget(result.spinglass, indexof.([:x, :y, :z]), [indexof(:d)])
tb = truth_table(gadget; variables=circuitsat.symbols[result.variables])
```
Expand Down
12 changes: 6 additions & 6 deletions examples/Ising.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

# Run the following code in Julia REPL:

using ProblemReductions
using ProblemReductions, Graphs
factoring = Factoring(2, 2, 6) # initialize the Factoring problem

# Using [`reduction_graph`](@ref) and [`reduction_paths`](@ref), we could obtain the way to reduce Factoring to SpinGlass.
Expand All @@ -35,11 +35,11 @@ target = target_problem(reduction_result)
# Note that the output of `implement_reduction_path` is a [`AbstractReductionResult`](@ref), which contains the target problem and reduction information. So we
# need to extract the target problem by [`target_problem`](@ref) function.

import GenericTensorNetworks # import Ising machine solver
import GenericTensorNetworks, Graphs # import Ising machine solver
gtn_problem = GenericTensorNetworks.SpinGlass(
target.graph.n,
target.graph.edges,
target.weights
ProblemReductions.nv(target.graph),
vcat(ProblemReductions._vec.(Graphs.edges(target.graph)), [[i] for i=1:Graphs.nv(target.graph)]),
ProblemReductions.weights(target)
)
result = GenericTensorNetworks.solve(
GenericTensorNetworks.GenericTensorNetwork(gtn_problem),
Expand All @@ -56,7 +56,7 @@ extract_solution(reduction_result, 1 .- 2 .* Int.(GenericTensorNetworks.read_con
# In this example, we show how to reduce Factoring problem to SpinGlass and solve it with Ising machine solver. This shows the power of `ProblemReductions.jl` in helping Problem Reduction.
#
# For your convenience, here is how to use `ProblemReductions.jl` to reduce source problem to target problem:
# - Initialize the source problem `source = SourceProblem(...) `, `...` is the parameters of the source problem.
# - Initialize the source problem `source = SourceProblem(...) `.
# - Obtain the reduction paths `paths = reduction_paths(reduction_graph(), SourceProblem, TargetProblem)`.
# - Implement the reduction path `reduction_result = implement_reduction_path(paths[1], source)`.
# - Extract the target problem `target = target_problem(reduction_result)`.
5 changes: 0 additions & 5 deletions examples/material_compute.jl

This file was deleted.

Loading

0 comments on commit f5b26e1

Please sign in to comment.