Skip to content

Commit 0653c7f

Browse files
committed
new sat doc
1 parent b5bed1d commit 0653c7f

File tree

8 files changed

+54
-17
lines changed

8 files changed

+54
-17
lines changed

docs/make.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ makedocs(;
3636
"Matching problem" => "tutorials/Matching.md",
3737
"Binary paint shop problem" => "tutorials/PaintShop.md",
3838
"Coloring problem" => "tutorials/Coloring.md",
39+
"Satisfiability problem" => "tutorials/Satisfiability.md",
3940
"Other problems" => "tutorials/Others.md",
4041
],
4142
"Performance Tips" => "performancetips.md",

examples/Coloring.jl

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ problem = Coloring{3}(graph);
4949

5050
# ## Solving properties
5151
# ##### counting all possible coloring
52-
num_of_coloring = solve(problem, CountingAll())[]
52+
num_of_coloring = solve(problem, CountingMax())[]
5353

5454
# ##### finding one best coloring
5555
single_solution = solve(problem, SingleConfigMax())[]
@@ -70,6 +70,7 @@ show_graph(linegraph; locs=[0.5 .* (locations[e.src] .+ locations[e.dst])
7070
# Let us construct the tensor network and see if there are solutions.
7171
lineproblem = Coloring{3}(linegraph);
7272

73-
num_of_coloring = solve(lineproblem, CountingAll())[]
73+
num_of_coloring = solve(lineproblem, CountingMax())[]
7474

75-
# You will see a zero printed, meaning no solution for the 3-coloring on edges of a Petersen graph.
75+
# You will see the maximum size 28 is smaller than the number of edges in the `linegraph`,
76+
# meaning no solution for the 3-coloring on edges of a Petersen graph.

examples/Satisfiability.jl

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,35 @@
99
# * how to compute weighted graphs and handle open vertices.
1010

1111
# ## Problem definition
12+
# One can specify a satisfiable problem in the [conjuctive normal form](https://en.wikipedia.org/wiki/Conjunctive_normal_form).
13+
# In boolean logic, a formula is in conjunctive normal form (CNF) if it is a conjunction (∧) of one or more clauses,
14+
# where a clause is a disjunction (∨) of literals.
15+
using GraphTensorNetworks
16+
17+
@bools a b c d e f g
18+
19+
cnf = ((a, b, ¬d, ¬e), (¬a, d, e, ¬f), (f, g), (¬b, c))
20+
21+
# To goal is to find an assignment to satisfy the above CNF.
22+
# For a satisfiability problem at this size, we can find the following assignment to satisfy this assignment manually.
23+
assignment = Dict([:a=>true, :b=>false, :c=>false, :d=>true, :e=>false, :f=>false, :g=>true])
24+
25+
satisfiable(cnf, assignment)
26+
27+
# We can contruct a [`Satisfiability`](@ref) problem to solve the above problem more cleverly.
28+
29+
problem = Satisfiability(cnf);
30+
31+
# ## Satisfiability and its counting
32+
# The size of a satisfiability problem is defined by the number of satisfiable clauses.
33+
num_satisfiable = solve(problem, SizeMax())[]
34+
35+
# The [`GraphPolynomial`](@ref) of a satisfiability problem counts the number of solutions that `k` clauses satisfied.
36+
num_satisfiable_count = solve(problem, GraphPolynomial())[]
37+
38+
# ## Find one of the solutions
39+
single_config = solve(problem, SingleConfigMax())[].c.data
40+
41+
# One will see a bit vector printed.
42+
# One can create an assignment and check the validity with the following statement:
43+
satisfiable(cnf, Dict(zip(labels(problem), single_config)))

src/arithematics.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@ Base.zero(::ConfigSampler{N,S,C}) where {N,S,C} = zero(ConfigSampler{N,S,C})
282282
Base.one(::ConfigSampler{N,S,C}) where {N,S,C} = one(ConfigSampler{N,S,C})
283283

284284
# tree config enumerator
285+
# it must be mutable, otherwise the `IdDict` trick for computing the length does not work.
285286
"""
286287
TreeConfigEnumerator{N,S,C} <: AbstractSetNumber
287288
@@ -339,7 +340,6 @@ julia> one(s)
339340
340341
```
341342
"""
342-
# it must be mutable, otherwise the `IdDict` trick for computing the length does not work.
343343
mutable struct TreeConfigEnumerator{N,S,C} <: AbstractSetNumber
344344
tag::TreeTag
345345
data::StaticElementVector{N,S,C}

src/interfaces.jl

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -286,18 +286,15 @@ post_invert_exponent(t::TropicalNumbers.TropicalTypes) = inv(t)
286286
Returns the maximum size of the graph problem.
287287
A shorthand of `solve(problem, SizeMax(); usecuda=false)`.
288288
"""
289-
function max_size end
289+
max_size(m::GraphProblem; usecuda=false) = Int(sum(solve(m, SizeMax(); usecuda=usecuda)).n) # floating point number is faster (BLAS)
290+
290291
"""
291292
max_size_count(problem; usecuda=false)
292293
293294
Returns the maximum size and the counting of the graph problem.
294295
It is a shorthand of `solve(problem, CountingMax(); usecuda=false)`.
295296
"""
296-
function max_size_count end
297-
for TP in [:MaximalIS, :IndependentSet, :Matching, :MaxCut, :PaintShop]
298-
@eval max_size(m::$TP; usecuda=false) = Int(sum(solve(m, SizeMax(); usecuda=usecuda)).n) # floating point number is faster (BLAS)
299-
@eval max_size_count(m::$TP; usecuda=false) = (r = sum(solve(m, CountingMax(); usecuda=usecuda)); (Int(r.n), Int(r.c)))
300-
end
297+
max_size_count(m::GraphProblem; usecuda=false) = (r = sum(solve(m, CountingMax(); usecuda=usecuda)); (Int(r.n), Int(r.c)))
301298

302299
using DelimitedFiles
303300

src/networks/Coloring.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,20 +26,20 @@ labels(gp::Coloring) = [1:gp.nv...]
2626
function generate_tensors(x::T, c::Coloring{K}) where {K,T}
2727
ixs = getixsv(c.code)
2828
return add_labels!(map(1:length(ixs)) do i
29-
i <= c.nv ? coloringv(x, K) .^ get_weights(c, i) : coloringb(T, K)
29+
i <= c.nv ? coloringv(T, K) .^ get_weights(c, i) : coloringb(x, K)
3030
end, ixs, labels(c))
3131
end
3232

3333
# coloring bond tensor
34-
function coloringb(::Type{T}, k::Int) where T
35-
x = ones(T, k, k)
34+
function coloringb(x::T, k::Int) where T
35+
x = fill(x, k, k)
3636
for i=1:k
37-
x[i,i] = zero(T)
37+
x[i,i] = one(T)
3838
end
3939
return x
4040
end
4141
# coloring vertex tensor
42-
coloringv(x::T, k::Int) where T = fill(x, k)
42+
coloringv(::Type{T}, k::Int) where T = fill(one(T), k)
4343

4444
# utilities
4545
"""

src/networks/Satisfiability.jl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
"""
2+
BoolVar{T}
3+
BoolVar(name, neg)
4+
5+
Boolean variable for constructing CNF clauses.
6+
"""
17
struct BoolVar{T}
28
name::T
39
neg::Bool

test/networks/Coloring.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ using Test, GraphTensorNetworks, Graphs
66
add_edge!(g, i, j)
77
end
88
code = Coloring{3}(g; optimizer=GreedyMethod())
9-
res = solutions(code, CountingTropical{Float64,Float64}; all=true)[]
9+
res = best_solutions(code; all=true)[]
1010
@test length(res.c.data) == 12
1111
g = smallgraph(:petersen)
1212
code = Coloring{3}(g; optimizer=GreedyMethod())
13-
res = solutions(code, CountingTropicalF64; all=true)[]
13+
res = best_solutions(code; all=true)[]
1414
@test length(res.c.data) == 120
1515

1616
c = solve(code, SingleConfigMax())[]

0 commit comments

Comments
 (0)