Skip to content

Commit 3da58ae

Browse files
authored
Merge pull request #26 from OptimalBranching/xw/hybrid
Update CDCL-hybrid solver
2 parents 93f39e7 + 64ff178 commit 3da58ae

46 files changed

Lines changed: 5144 additions & 1059 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/CI.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,15 @@ jobs:
3131
- x64
3232
steps:
3333
- uses: actions/checkout@v6
34+
with:
35+
submodules: recursive
3436
- uses: julia-actions/setup-julia@v2
3537
with:
3638
version: ${{ matrix.version }}
3739
arch: ${{ matrix.arch }}
3840
- uses: julia-actions/cache@v2
41+
- name: Build CaDiCaL dependency
42+
run: make
3943
- uses: julia-actions/julia-buildpkg@v1
4044
- uses: julia-actions/julia-runtest@v1
4145
- uses: julia-actions/julia-processcoverage@v1
@@ -53,10 +57,14 @@ jobs:
5357
statuses: write
5458
steps:
5559
- uses: actions/checkout@v6
60+
with:
61+
submodules: recursive
5662
- uses: julia-actions/setup-julia@v2
5763
with:
5864
version: '1'
5965
- uses: julia-actions/cache@v2
66+
- name: Build CaDiCaL dependency
67+
run: make
6068
- name: Configure doc environment
6169
shell: julia --project=docs --color=yes {0}
6270
run: |

.gitignore

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ Thumbs.db
2424
*.swo
2525

2626
statprof/
27-
OptimalBranching.jl/
2827
.julia/
2928
.claude/
29+
.history/
3030

3131
# === Build outputs ===
3232
/benchmarks/artifacts/
@@ -43,4 +43,8 @@ OptimalBranching.jl/
4343
/discs/
4444
/notes/
4545

46-
/benchmarks/results/
46+
/benchmarks/results/
47+
*.dylib
48+
*.o
49+
*.so
50+
*.dll

.gitmodules

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,7 @@
1818
path = benchmarks/third-party/cir_bench
1919
url = https://github.com/santoshsmalagi/Benchmarks.git
2020
ignore = all
21+
[submodule "deps/cadical"]
22+
path = deps/cadical
23+
url = https://github.com/arminbiere/cadical.git
24+
ignore = all

Makefile

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# BooleanInference Makefile
2+
# This Makefile handles building the CaDiCaL dependency and the custom library
3+
4+
.PHONY: all submodule cadical mylib clean clean-all help
5+
6+
# Default target
7+
all: mylib
8+
9+
# Help message
10+
help:
11+
@echo "Available targets:"
12+
@echo " all - Build everything (default)"
13+
@echo " submodule - Initialize and update git submodules"
14+
@echo " cadical - Build the CaDiCaL library"
15+
@echo " mylib - Build the custom CaDiCaL wrapper library"
16+
@echo " clean - Clean the custom library"
17+
@echo " clean-all - Clean everything including CaDiCaL build"
18+
19+
# Update git submodules
20+
submodule:
21+
git submodule update --init --recursive
22+
23+
# Build CaDiCaL
24+
cadical: submodule
25+
@echo "Building CaDiCaL..."
26+
cd deps/cadical && \
27+
make clean || true && \
28+
export CFLAGS="-fPIC" CXXFLAGS="-fPIC" && \
29+
./configure && \
30+
$(MAKE) -j4 CFLAGS="-fPIC" CXXFLAGS="-fPIC"
31+
32+
# Build the custom library (depends on CaDiCaL)
33+
mylib: cadical
34+
@echo "Building custom CaDiCaL wrapper..."
35+
$(MAKE) -C src/cdcl
36+
37+
# Clean custom library only
38+
clean:
39+
$(MAKE) -C src/cdcl clean
40+
41+
# Clean everything
42+
clean-all: clean
43+
@echo "Cleaning CaDiCaL build..."
44+
cd deps/cadical && make clean 2>/dev/null || true
45+
rm -rf deps/cadical/build

Project.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@ authors = ["nzy1997"]
77
BitBasis = "50ba71b6-fa0f-514d-ae9a-0916efc90dcf"
88
CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0"
99
Colors = "5ae59095-9a9b-59fe-a467-6f913c188581"
10+
Combinatorics = "861a8166-3701-5b0c-9a16-15d98fcdc6aa"
1011
Compose = "a81c6b42-2e10-5240-aca2-a61377ecd94b"
1112
DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
1213
GenericTensorNetworks = "3521c873-ad32-4bb4-b63d-f4f178f42b49"
1314
GraphMakie = "1ecd5474-83a3-4783-bb4f-06765db800d2"
1415
GraphPlot = "a2cc645c-3eea-5389-862e-a155d0052231"
1516
Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6"
1617
Gurobi = "2e9cd046-0924-5485-92f1-d5272153d98b"
18+
Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb"
1719
NetworkLayout = "46757867-2c16-5918-afeb-47bfcb05e46a"
1820
OptimalBranchingCore = "c76e7b22-e1d2-40e8-b0f1-f659837787b8"
1921
ProblemReductions = "899c297d-f7d2-4ebf-8815-a35996def416"
@@ -25,13 +27,15 @@ TropicalNumbers = "b3a74e9c-7526-4576-a4eb-79c0d4c32334"
2527
BitBasis = "0.9.10"
2628
CairoMakie = "0.15.6"
2729
Colors = "0.13.1"
30+
Combinatorics = "1.1.0"
2831
Compose = "0.9.6"
2932
DataStructures = "0.18.22"
3033
GenericTensorNetworks = "4"
3134
GraphMakie = "0.6.3"
3235
GraphPlot = "0.6.2"
3336
Graphs = "1.13.1"
3437
Gurobi = "1.8.0"
38+
Libdl = "1.11.0"
3539
NetworkLayout = "0.4.10"
3640
OptimalBranchingCore = "0.1"
3741
ProblemReductions = "0.3.5"

README.md

Lines changed: 107 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@ A high-performance Julia package for solving Boolean satisfiability problems usi
1212
- **Tensor Network Representation**: Efficiently represents Boolean satisfiability problems as tensor networks
1313
- **Optimal Branching**: Uses advanced branching strategies to minimize search space
1414
- **Multiple Problem Types**: Supports CNF, circuit, and factoring problems
15+
- **Circuit Simplification**: Automatic circuit simplification using constant propagation and gate optimization
16+
- **CDCL Integration**: Supports clause learning via CaDiCaL SAT solver integration
17+
- **2-SAT Solver**: Built-in efficient 2-SAT solver for special cases
1518
- **High Performance**: Optimized for speed with efficient propagation and contraction algorithms
19+
- **Visualization**: Problem structure visualization with graph-based representations
1620
- **Flexible Interface**: Easy-to-use API for various constraint satisfaction problems
1721

1822
## Installation
@@ -36,7 +40,7 @@ cnf = ∧(∨(a, b, ¬d, ¬e), ∨(¬a, d, e, ¬f), ∨(f, g), ∨(¬b, c), ∨(
3640

3741
# Solve and get assignments
3842
sat = Satisfiability(cnf; use_constraints=true)
39-
satisfiable, assignments, depth = solve_sat_with_assignments(sat)
43+
satisfiable, assignments, stats = solve_sat_with_assignments(sat)
4044

4145
println("Satisfiable: ", satisfiable)
4246
println("Assignments: ", assignments)
@@ -46,69 +50,144 @@ println("Assignments: ", assignments)
4650

4751
```julia
4852
# Factor a semiprime number
49-
a, b = solve_factoring(5, 5, 31*29)
53+
a, b, stats = solve_factoring(5, 5, 31*29)
5054
println("Factors: $a × $b = $(a*b)")
5155
```
5256

53-
### Circuit Problems
57+
### Circuit SAT Problems
5458

5559
```julia
60+
using ProblemReductions: Circuit, Assignment, BooleanExpr
61+
5662
# Solve circuit satisfiability
5763
circuit = @circuit begin
5864
c = x y
5965
end
6066
push!(circuit.exprs, Assignment([:c], BooleanExpr(true)))
6167

62-
tnproblem = setup_from_circuit(circuit)
63-
result, depth = solve(tnproblem, BranchingStrategy(), NoReducer())
68+
satisfiable, stats = solve_circuit_sat(circuit)
6469
```
6570

6671
## Core Components
6772

6873
### Problem Types
69-
- `TNProblem`: Main problem representation
70-
- `BipartiteGraph`: Static problem structure
71-
- `DomainMask`: Variable domain representation
72-
73-
### Solvers
74-
- `TNContractionSolver`: Tensor network contraction-based solver
75-
- `LeastOccurrenceSelector`: Variable selection strategy
76-
- `NumUnfixedVars`: Measurement strategy
74+
- `TNProblem`: Main tensor network problem representation
75+
- `BipartiteGraph`: Static problem structure (variables and tensors)
76+
- `DomainMask`: Variable domain representation using bitmasks
77+
- `ClauseTensor`: Clause representation as tensor factors
78+
79+
### Solvers & Strategies
80+
- `TNContractionSolver`: Tensor network contraction-based branching table solver
81+
- `MostOccurrenceSelector`: Variable selection based on occurrence frequency
82+
- `NumUnfixedVars`: Measurement strategy counting unfixed variables
83+
- `NumUnfixedTensors`: Measurement based on unfixed tensor count
84+
- `HardSetSize`: Measurement based on hard clause set size
7785

7886
### Key Functions
79-
- `solve()`: Main solving function
80-
- `setup_from_cnf()`: Setup from CNF formulas
81-
- `setup_from_circuit()`: Setup from circuit descriptions
82-
- `solve_factoring()`: Solve integer factoring problems
87+
88+
| Function | Description |
89+
|----------|-------------|
90+
| `solve()` | Main solving function with configurable strategy |
91+
| `solve_sat_problem()` | Solve SAT and return satisfiability result |
92+
| `solve_sat_with_assignments()` | Solve SAT and return variable assignments |
93+
| `solve_circuit_sat()` | Solve circuit satisfiability problems |
94+
| `solve_factoring()` | Solve integer factoring problems |
95+
| `setup_from_cnf()` | Setup problem from CNF formulas |
96+
| `setup_from_circuit()` | Setup problem from circuit descriptions |
97+
| `setup_from_sat()` | Setup problem from CSP representation |
8398

8499
## Advanced Usage
85100

86101
### Custom Branching Strategy
87102

88103
```julia
89-
using OptimalBranchingCore: BranchingStrategy
104+
using OptimalBranchingCore: BranchingStrategy, GreedyMerge
90105

91106
# Configure custom solver
92107
bsconfig = BranchingStrategy(
93108
table_solver=TNContractionSolver(),
94-
selector=LeastOccurrenceSelector(2, 10),
95-
measure=NumUnfixedVars()
109+
selector=MostOccurrenceSelector(3, 4),
110+
measure=NumUnfixedTensors(),
111+
set_cover_solver=GreedyMerge()
96112
)
97113

98114
# Solve with custom configuration
99-
result, depth = solve(problem, bsconfig, NoReducer())
115+
result = solve(problem, bsconfig, NoReducer())
100116
```
101117

102-
### Benchmarking
118+
### Circuit Simplification
119+
120+
```julia
121+
using ProblemReductions: CircuitSAT
122+
123+
# Simplify a circuit before solving
124+
simplified_circuit, var_mapping = simplify_circuit(circuit, fixed_vars)
125+
```
103126

104-
The package includes comprehensive benchmarking tools:
127+
### 2-SAT Solving
105128

106129
```julia
107-
using BooleanInferenceBenchmarks
130+
# Check if problem is 2-SAT reducible and solve
131+
if is_2sat_reducible(problem)
132+
result = solve_2sat(problem)
133+
end
134+
```
108135

109-
# Compare different solvers
110-
configs = [(10,10), (12,12), (14,14)]
111-
results = run_solver_comparison(FactoringProblem, configs)
112-
print_solver_comparison_summary(results)
136+
### CDCL with Clause Learning
137+
138+
```julia
139+
# Solve using CaDiCaL and mine learned clauses
140+
status, model, learned_clauses = solve_and_mine(cnf; conflict_limit=30000, max_len=5)
113141
```
114142

143+
### Visualization
144+
145+
```julia
146+
# Visualize the problem structure
147+
visualize_problem(problem, "output.png")
148+
149+
# Get and visualize highest degree variables
150+
high_degree_vars = get_highest_degree_variables(problem, k=10)
151+
visualize_highest_degree_vars(problem, k=10, "high_degree.png")
152+
```
153+
154+
## Project Structure
155+
156+
```
157+
src/
158+
├── BooleanInference.jl # Main module
159+
├── interface.jl # High-level API functions
160+
├── core/ # Core data structures
161+
│ ├── static.jl # BipartiteGraph structure
162+
│ ├── domain.jl # DomainMask operations
163+
│ ├── problem.jl # TNProblem definition
164+
│ └── stats.jl # BranchingStats tracking
165+
├── branching/ # Branching algorithms
166+
│ ├── branch.jl # Main branching logic (bbsat!)
167+
│ ├── propagate.jl # Constraint propagation
168+
│ └── measure.jl # Measure strategies
169+
├── branch_table/ # Branching table generation
170+
│ ├── contraction.jl # Tensor contraction
171+
│ ├── selector.jl # Variable selection
172+
│ └── branchtable.jl # Table generation
173+
├── utils/ # Utility functions
174+
│ ├── simplify_circuit.jl # Circuit simplification
175+
│ ├── circuit2cnf.jl # Circuit to CNF conversion
176+
│ ├── twosat.jl # 2-SAT solver
177+
│ └── visualization.jl # Problem visualization
178+
└── cdcl/ # CDCL integration
179+
└── CaDiCaLMiner.jl # CaDiCaL wrapper for clause learning
180+
```
181+
182+
## Dependencies
183+
184+
Key dependencies include:
185+
- [GenericTensorNetworks.jl](https://github.com/QuEraComputing/GenericTensorNetworks.jl) - Tensor network operations
186+
- [OptimalBranchingCore.jl](https://github.com/OptimalBranching/OptimalBranchingCore.jl) - Branching framework
187+
- [ProblemReductions.jl](https://github.com/GiggleLiu/ProblemReductions.jl) - Problem reduction utilities
188+
- [Graphs.jl](https://github.com/JuliaGraphs/Graphs.jl) - Graph data structures
189+
- [CairoMakie.jl](https://github.com/MakieOrg/Makie.jl) - Visualization
190+
191+
## License
192+
193+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

0 commit comments

Comments
 (0)