Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
152 commits
Select commit Hold shift + click to select a range
f28f3a3
Cleanup
msoos Apr 19, 2026
af0ad87
Emplace back
msoos Apr 19, 2026
93d9cdf
Cleanup
msoos Apr 19, 2026
0f7cdb5
BEtter clang-tidy
msoos Apr 19, 2026
8031302
Cleanup and speedup
msoos Apr 19, 2026
5ffd008
Fix about 5% of time
msoos Apr 19, 2026
ed623b6
Faster get_dependent_vars
msoos Apr 19, 2026
c9a9661
Emplace back
msoos Apr 19, 2026
70ef3ae
Small improvements using unordered_map
msoos Apr 19, 2026
16f1c4b
Replace unordered_set<AIG*> visited marker with epoch field
msoos Apr 19, 2026
4717bfe
Package Windows release, too
msoos Apr 19, 2026
8e913f7
Memoize dependency
msoos Apr 19, 2026
8437ae5
Faster get_dependent_vars
msoos Apr 19, 2026
e5aaaca
Gen-ok
msoos Apr 19, 2026
e2182f0
Fix fuzzer config
msoos Apr 19, 2026
b10b429
Faster bitset lookup
msoos Apr 19, 2026
4023fe3
Fix test-synth
msoos Apr 19, 2026
ae5c2e7
Use AIGToCNF in fill_var_to_formula_with
msoos Apr 19, 2026
e42db69
Rename CexClauseSink to FormulaClauseSink
msoos Apr 19, 2026
ef09884
Rebuild solver less often
msoos Apr 19, 2026
6e85695
These should be floating
msoos Apr 19, 2026
aae67d8
AIG->CNF: structural AIG-level reasoning and pure-chain regression test
msoos Apr 19, 2026
bb08c12
Add rationale for rebuild
msoos Apr 19, 2026
9667de9
AIG->CNF: fuse nested ITEs into MUX3, canonical CSE keys
msoos Apr 19, 2026
11dd1ca
AIG->CNF: Plaisted-Greenbaum half-biconditional encoding
msoos Apr 19, 2026
2877aa1
Better printing
msoos Apr 19, 2026
88f193e
Fixing build
msoos Apr 19, 2026
5bd850d
None of this.
msoos Apr 20, 2026
9e95e6b
Cleanup
msoos Apr 20, 2026
6aeb335
Loops repair is counted now between rebuilds
msoos Apr 20, 2026
b3ff488
AIG->CNF: remove Plaisted-Greenbaum encoding
msoos Apr 20, 2026
772cc35
manthan: strip cex_solver rebuild machinery
msoos Apr 20, 2026
12ee179
Update
msoos Apr 20, 2026
c96ca81
Let's use the standard system for aig->cnf
msoos Apr 20, 2026
c530ad2
Better AIG simplification
msoos Apr 20, 2026
e25aa62
Rewrite AIGs before go into manthan
msoos Apr 20, 2026
ef7a186
Better setup for using AIG to CNF
msoos Apr 20, 2026
9a3ff83
Using a single generator
msoos Apr 20, 2026
32bc7ab
Update graph
msoos Apr 20, 2026
8b56713
OK, don't rewrite AIGs if we don't have to, it takes too much mem
msoos Apr 21, 2026
542a69f
Better graphs
msoos Apr 21, 2026
9be050c
Update scripts
msoos Apr 21, 2026
9fd2484
Make AIG ordering deterministic via nid instead of pointer address
msoos Apr 21, 2026
10215eb
Update claude
msoos Apr 21, 2026
0699ac6
Detect XOR pattern in AIG-to-CNF encoder
msoos Apr 21, 2026
53d9d2a
Extract random AIG generators into aig_fuzz_gen.h
msoos Apr 21, 2026
9ebc585
Add fuzz_aig_rewrite fuzzer
msoos Apr 21, 2026
9e51a3c
Add cut-based CNF encoding for k≤4 input cones
msoos Apr 21, 2026
14e39d8
Add opt-in SAT sweeping (FRAIG-lite) to AIGRewriter
msoos Apr 21, 2026
eee410e
Wire ctest into the top-level CMakeLists
msoos Apr 21, 2026
6b6a3ed
Add --sat-sweep CLI flag to drive FRAIG-lite sweeping
msoos Apr 21, 2026
4a539f0
Randomize --sat-sweep in fuzz_synth.py
msoos Apr 21, 2026
f3a9adf
Report sat-sweep node delta alongside the groups/checks/merges stats
msoos Apr 21, 2026
70e0fa1
Hash-cons sat_sweep rebuild to eliminate node inflation
msoos Apr 21, 2026
0d62a7d
Iterate rewrite+sweep to fixpoint and bump default sim rounds
msoos Apr 21, 2026
223bd26
Also iters elsewhere for rewrite
msoos Apr 22, 2026
880c209
Switch AIG to input-edge negation (literature convention)
msoos Apr 22, 2026
4b3a3d4
Restore simplify_pass + rewrite infrastructure
msoos Apr 22, 2026
c6438f4
Restore hash_cons structural sharing pass
msoos Apr 22, 2026
006691b
Restore deep_absorb multi-level AND/OR rewrites
msoos Apr 22, 2026
33c2c50
Restore flatten_ite_chains depth-reduction pass
msoos Apr 22, 2026
baea4fc
Restore sat_sweep FRAIG-lite equivalence merging
msoos Apr 22, 2026
30f054e
Restore ITE pattern detection in aig_to_cnf
msoos Apr 22, 2026
c4aef99
Restore XOR pattern detection in aig_to_cnf
msoos Apr 22, 2026
496ae42
Restore MUX3 fusion for nested ITE patterns
msoos Apr 22, 2026
7e60204
Restore cut-CNF minimum-clause encoding
msoos Apr 22, 2026
87fb6d7
Restore group-CSE for AND and ITE groups
msoos Apr 22, 2026
16034d5
Add DeMorgan-flatten counter (pattern is implicit in new model)
msoos Apr 22, 2026
35d88c9
Restore AIG-level structural_simplify_and
msoos Apr 22, 2026
29ee482
Cache AIG::transform on node, not signed edge
msoos Apr 22, 2026
9a5ba43
Don't materialise the TRUE literal speculatively in normalize_inputs
msoos Apr 22, 2026
aeb76b0
Update test-aig-to-cnf to expect OR routed through AND
msoos Apr 22, 2026
b164234
Canonicalise cut-CNF table on output complement
msoos Apr 22, 2026
8b38c03
Detect ITE / XOR at both edge polarities
msoos Apr 22, 2026
309dcd8
Revert sat-sweep merges that re-embed lit(v) into defs[v]
msoos Apr 22, 2026
90006ef
Add --multi-def mode to fuzz_aig_rewrite for SAT-sweep self-ref coverage
msoos Apr 22, 2026
dca6acb
Allow multi-def fuzzer to reference defined vars cross-def
msoos Apr 22, 2026
f7e055f
Order AIG edges by nid, not raw pointer, in CNF encoder and aig_lit
msoos Apr 23, 2026
a94553a
Two determinism + correctness-detection fixes
msoos Apr 23, 2026
25b410c
Track Tseitin helper vars created by compose_and / compose_or
msoos Apr 23, 2026
100cb1c
Add semantic synth-defs check + per-stage SLOW_DEBUG guard
msoos Apr 23, 2026
32dd09e
Document bug_real: Manthan wrong AIG under --synthmore --minimize 0
msoos Apr 23, 2026
d018777
Add clause-level delta debugger + minimal repro for bug_real
msoos Apr 23, 2026
f72aac9
Always recompute y_hat after repair; formulas cross-reference other y…
msoos Apr 23, 2026
1c9ee02
Update bug_real.md with Fix 2 root-cause analysis
msoos Apr 23, 2026
6e062d7
Document remaining 74-clause bug + commit bug_real_big.cnf
msoos Apr 23, 2026
336ac57
Use fresh AIGToCNF per formula in bve_and_substitute
msoos Apr 23, 2026
9cb5d0e
Update bug_real.md: Fix 3 resolved; remove stale repro
msoos Apr 23, 2026
f0891cb
UPdate
msoos Apr 22, 2026
ac1d63e
Add claude
msoos Apr 23, 2026
db5c6ba
Document debugging workflow in CLAUDE.md
msoos Apr 23, 2026
a497048
sat_sweep: revert defs involved in indirect dep cycles
msoos Apr 23, 2026
86e3822
sat_sweep: memoise post-merge cycle-detection DFS
msoos Apr 24, 2026
1fe756f
sat_sweep: bound SAT work with conflict, streak, and wall-clock budgets
msoos Apr 24, 2026
4255678
sat_sweep: bump default sim rounds 4→16
msoos Apr 24, 2026
e481461
fuzz: add MUX3-chain and XOR-chain shapes
msoos Apr 25, 2026
da6dd13
manthan: move-aware compose_or/and to fix O(N²) repair clauses
msoos Apr 25, 2026
0d2fba8
manthan: skip already-inserted clause prefix in inject_formulas
msoos Apr 25, 2026
fd82974
unate_def: detect conditional defs t = L for input literals L
msoos Apr 26, 2026
d453615
More fuzzing by default
msoos Apr 26, 2026
fcab3ff
Fix printing "to define" -> "to-define"
msoos Apr 26, 2026
b6e6fdb
Use emplace_back
msoos Apr 26, 2026
9b1888d
docs: explain plain unate, unate-with-def, and conditional unate
msoos Apr 26, 2026
fb512fb
unate_def: add cond stats, project models to inputs, prefer related-c…
msoos Apr 26, 2026
1abb37d
One sat_sweep iter is enough
msoos Apr 26, 2026
d32a321
No more time usage
msoos Apr 26, 2026
d13135b
Silence warning
msoos Apr 26, 2026
ab1aa60
Stupid flag removal
msoos Apr 26, 2026
42b25a0
No slow counting of AIG nodes anymore
msoos Apr 26, 2026
03755b1
Allow random sat-sweep in AIG rewrite fuzzer
msoos Apr 26, 2026
9b60de0
Higher limit for dry streak disabling of conditional unate_def
msoos Apr 26, 2026
aef2628
Add manthan-style guess+repair pass after unate_def
msoos Apr 27, 2026
99746c0
Fix warning
msoos Apr 27, 2026
5663a46
Cleaner code around if/then/else
msoos Apr 27, 2026
7b1f607
Less warning noise
msoos Apr 27, 2026
b1c6ea0
Print running stats in unate_def_rep periodic log
msoos Apr 27, 2026
c39dc5b
Restructure algorithm unate_def
msoos Apr 27, 2026
217bcd2
Expose unate_def cond dry-streak as a config option
msoos Apr 27, 2026
f8c03b1
Cleanup of VERBOSE_DEBUG
msoos Apr 27, 2026
4f5a949
Stronger, more uniform unate
msoos Apr 27, 2026
08b7e47
Remove synthesis_unate, superseded by synthesis_unate_def
msoos Apr 27, 2026
6587496
Bump unate repair cutoffs
msoos Apr 27, 2026
035ce96
Undate def rep is not a flat like that
msoos Apr 27, 2026
bd28793
This flag no longer there
msoos Apr 27, 2026
446c4fa
Assert non-null AIG t_and children in deep_absorb
msoos Apr 27, 2026
a78e4f0
None of this indirection
msoos Apr 27, 2026
92150f6
Per-var verb=2 trace in unate_def_rep
msoos Apr 27, 2026
f216ae9
Doc: cost-zero in unate_def_rep is a 2QBF gap
msoos Apr 27, 2026
cd07730
Drop dead neg parameter from AIG::transform visitor
msoos Apr 28, 2026
c75ff34
Rolling back puura to 8c2fa95f7b2a3f67cbb11d9d4dabe7306d8332fd
msoos Apr 28, 2026
e2bbf60
Adding new results
msoos Apr 28, 2026
062d2b9
Add SimpConf::puura_strategy to select Puura iter1 strategy
msoos Apr 28, 2026
e2a65b8
Fix strategy to better
msoos Apr 29, 2026
a0e9941
Tune to out-synt-1455773-1 -- i.e. best that's not out-synth-1367674-2
msoos Apr 29, 2026
7423af4
Update graph
msoos Apr 29, 2026
50571f2
Add new strategy
msoos Apr 29, 2026
ce2eb75
Allow non-input leaves in unate_def_rep H
msoos Apr 29, 2026
5137212
Update unate_def_rep cutoffs, enable it
msoos Apr 29, 2026
ce995e6
Fix unate_def_rep soundness bug with aux to-define leaves
msoos Apr 29, 2026
2f40682
Fix fuzz_synth.py to detect test-synth crashes
msoos Apr 30, 2026
24d7de8
More fuzzing per check
msoos Apr 30, 2026
72688bf
Disable unate_def_rep aux>=1 (clamp to input-only)
msoos Apr 30, 2026
e231ad6
Revert "Disable unate_def_rep aux>=1 (clamp to input-only)"
msoos Apr 30, 2026
3850196
Fix unate_def_rep aux>=1 by enforcing uniqueness + Skolem flag
msoos Apr 30, 2026
b0083bb
Add asserts and SLOW_DEBUG checks in unate_def_rep, widen fuzz ranges
msoos Apr 30, 2026
39f27b1
Add Skolem-set invariant checks in defs_invariant and get_var_types
msoos Apr 30, 2026
4c58991
Mirror unate_def_rep commits into f_solver for cumulative uniqueness
msoos Apr 30, 2026
c5e1e06
Loosen unate_def_rep check to feasibility, materialize def into cnf
msoos Apr 30, 2026
df94f55
Less unate rep iters by default: 200->50
msoos Apr 30, 2026
d758531
Lower unate repair iters
msoos Apr 30, 2026
8b8f15a
Add per-section timing breakdown to unate_def_rep stats
msoos Apr 30, 2026
615a03e
Validate fc_int/fc_double argument parsing
msoos Apr 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions .clang-tidy
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Checks: >
performance-unnecessary-copy-initialization,
readability-const-return-type,
readability-container-size-empty,
readability-convert-member-functions-to-static,
-readability-convert-member-functions-to-static,
readability-else-after-return,
readability-identifier-naming,
readability-make-member-function-const,
Expand All @@ -40,7 +40,7 @@ Checks: >
readability-redundant-member-init,
readability-redundant-smartptr-get,
readability-redundant-string-cstr,
readability-simplify-boolean-expr
-readability-simplify-boolean-expr

CheckOptions:
- key: bugprone-assert-side-effect.AssertMacros
Expand Down Expand Up @@ -74,6 +74,10 @@ CheckOptions:
value: 'CamelCase'
- key: readability-identifier-naming.VariableCase
value: 'lower_case'
- key: readability-identifier-naming.ConstexprVariableCase
value: 'UPPER_CASE'
- key: readability-identifier-naming.GlobalConstantCase
value: 'UPPER_CASE'

HeaderFilterRegex: '^./src/.*'

Expand Down
75 changes: 71 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,33 @@ jobs:
fail-fast: true

matrix:
os: [ubuntu-latest, ubuntu-24.04-arm, macos-15, macos-15-intel]
os: [ubuntu-latest, ubuntu-24.04-arm, macos-15, macos-15-intel, windows-latest]
build_type: [Release]

steps:
- name: Set up MSYS2
if: contains(matrix.os, 'windows')
uses: msys2/setup-msys2@v2
with:
msystem: MINGW64
update: true
install: >-
mingw-w64-x86_64-gcc
mingw-w64-x86_64-cmake
mingw-w64-x86_64-ninja
mingw-w64-x86_64-gmp
mingw-w64-x86_64-mpfr
mingw-w64-x86_64-zlib
mingw-w64-x86_64-pkgconf
make

- uses: actions/setup-python@v5
if: "!contains(matrix.os, 'windows')"
with:
python-version: '3.10'

- name: Install python dependencies
if: "!contains(matrix.os, 'windows')"
run: |
pip install numpy lit

Expand Down Expand Up @@ -63,12 +81,14 @@ jobs:
run: sudo apt-get update && sudo apt-get install -yq help2man libgmp-dev libmpfr-dev perl

- name: Setup ccache
if: "!contains(matrix.os, 'windows')"
uses: hendrikmuhs/ccache-action@v1
with:
key: release-${{ matrix.os }}-${{ matrix.build_type }}
max-size: 500M

- name: Checkout & build cereal
if: "!contains(matrix.os, 'windows')"
run: |
wget https://github.com/USCiLab/cereal/archive/v1.3.2.tar.gz
tar xvf v1.3.2.tar.gz
Expand All @@ -86,6 +106,7 @@ jobs:
cd ..

- name: Checkout armadillo static
if: "!contains(matrix.os, 'windows')"
run: |
wget https://sourceforge.net/projects/arma/files/armadillo-14.0.2.tar.xz
tar xvf armadillo-14.0.2.tar.xz
Expand All @@ -97,6 +118,7 @@ jobs:
cd ../..

- name: Checkout & build ensmallen
if: "!contains(matrix.os, 'windows')"
run: |
wget https://github.com/mlpack/ensmallen/archive/refs/tags/2.22.2.tar.gz
tar xvf 2.22.2.tar.gz
Expand All @@ -109,12 +131,14 @@ jobs:
cd ../..

- name: Checkout mlpack
if: "!contains(matrix.os, 'windows')"
uses: actions/checkout@v4
with:
repository: mlpack/mlpack
ref: 4.6.2
path: mlpack
- name: Build mlpack
if: "!contains(matrix.os, 'windows')"
run: |
cd mlpack
mkdir build
Expand All @@ -128,7 +152,8 @@ jobs:
with:
path: project
submodules: 'true'
- name: Build project
- name: Build project (non-Windows)
if: "!contains(matrix.os, 'windows')"
run: |
cd project
mkdir -p build && cd build
Expand All @@ -141,10 +166,26 @@ jobs:
-S ..
cmake --build . --config ${{matrix.build_type}} -v

- name: Build project (Windows)
if: contains(matrix.os, 'windows')
shell: msys2 {0}
run: |
cd project
mkdir -p build && cd build
cmake \
-DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \
-DBUILD_SHARED_LIBS=OFF \
-DEXTRA_SYNTH=OFF \
-G Ninja \
-S ..
cmake --build . --config ${{matrix.build_type}} -v

- name: Test
if: "!contains(matrix.os, 'windows')"
run: ctest -C ${{matrix.build_type}} --verbose

- name: run it to check it executes
- name: run it to check it executes (non-Windows)
if: "!contains(matrix.os, 'windows')"
run: |
echo "Running version command"
./project/build/arjun --version
Expand All @@ -153,6 +194,18 @@ jobs:
./project/build/arjun --help
echo $?

- name: run it to check it executes (Windows)
if: contains(matrix.os, 'windows')
shell: msys2 {0}
run: |
EXE=./project/build/arjun.exe
echo "Running: $EXE --version"
$EXE --version
echo $?
echo "Running: $EXE --help"
$EXE --help
echo $?

- name: Determine artifact name
id: artifact
shell: bash
Expand All @@ -166,9 +219,12 @@ jobs:
echo "name=arjun-mac-arm64" >> "$GITHUB_OUTPUT"
elif [[ "$OS" == "macos-15-intel" ]]; then
echo "name=arjun-mac-x86_64" >> "$GITHUB_OUTPUT"
elif [[ "$OS" == "windows-latest" ]]; then
echo "name=arjun-windows-x86_64" >> "$GITHUB_OUTPUT"
fi

- name: Package artifact
- name: Package artifact (non-Windows)
if: "!contains(matrix.os, 'windows')"
run: |
mkdir -p dist
cp project/build/arjun dist/
Expand All @@ -177,6 +233,17 @@ jobs:
cp -r project/build/include dist/ 2>/dev/null || true
tar czf ${{ steps.artifact.outputs.name }}.tar.gz -C dist .

- name: Package artifact (Windows)
if: contains(matrix.os, 'windows')
shell: msys2 {0}
run: |
mkdir -p dist
cp project/build/arjun.exe dist/
cp project/build/test-synth.exe dist/ 2>/dev/null || true
cp -r project/build/lib dist/ 2>/dev/null || true
cp -r project/build/include dist/ 2>/dev/null || true
tar czf ${{ steps.artifact.outputs.name }}.tar.gz -C dist .

- name: Upload artifact for release job
uses: actions/upload-artifact@v4
with:
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ examples
neovide_backtraces.log
/result
/.ccls-cache
CLAUDE.md
.claude
perf*
output
Expand All @@ -17,3 +16,4 @@ html/*.css
html/*.wasm
html/*.ts

/scripts/data/__pycache__
144 changes: 144 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
# Arjun

Minimal-independent-set calculator and CNF minimizer. Preprocessor for
[GANAK](https://github.com/meelgroup/ganak) and
[ApproxMC](https://github.com/meelgroup/ApproxMC). Also performs
Boolean-function **synthesis** (Manthan-style counterexample-guided repair)
for defining relationships between variables.

## Building

ALWAYS build with `make -j12` from `build/` — otherwise it's slow.

```
cd build && ./build_norm.sh
```

Dependencies (cadical, cryptominisat, sbva, treedecomp) are typically sibling
checkouts under `../` and are pointed at via the cmake configuration already
present in `build/`. If cmake needs to be re-run, use `scripts/build_norm.sh`
or `scripts/build_release.sh`.

## Running

From `build/`:

```
./arjun --verb 2 --synth --synthbve 1 --extend 1 --minimize 1 --debugsynth --samples 1 out/fuzzTest_596.cnf
```

Useful top-level flags:
- `--synth` — enable synthesis (Manthan)
- `--debugsynth` — emit intermediate AIGs (`*-simplified_cnf.aig`,
`*-autarky.aig`, `*-manthan.aig`, `*-final.aig`) for debugging
- `--verb N` — verbosity (0–2)

## Quick A/B benchmarking: `scripts/run_elim_bench.sh`

One-line sanity bench for comparing simplification tweaks. Runs `arjun` on a
CNF and prints a single line with the headline counts (vars, indep, optind,
bin cls, long cls, lits, time).

Run from `build/` (where `arjun` and `count_literals.py` live):

```
../scripts/run_elim_bench.sh <cnf[.gz]> [extra arjun args...]
```

Extra args are forwarded to `arjun`. The simplified CNF is written to
`/tmp/arjun_elim_out` and the full log to `/tmp/arjun_elim.log`. Typical
workflow: run it on the same CNF before and after a change and diff the
output lines.

## After every build ALWAYS run the fuzzers

From `build/`:

```
./fuzz_synth.py --num 1500
./fuzz_aig_to_cnf --num 1000
./fuzz_aig_rewrite --num 1000
./fuzz_unate_def_rep.py 300
```

All must pass before reporting a change as complete. `fuzz_unate_def_rep.py`
forces `--unatedef 1 --unatedefrep 1` on every iteration and verifies the
`*-unsat_unate_def_rep.aig` output AIG via `test-synth`; the general
`fuzz_synth.py` only randomizes those flags so the rep-pass output is not
always exercised.

## Source layout (`src/`)

- `arjun.{h,cpp}` — public API, the `AIG` class, and the `SimplifiedCNF`
container. AIG nodes are `std::shared_ptr<AIG>` (`aig_ptr`). Every AIG
node carries a monotonic `uint64_t nid` assigned at construction; use
`nid` for ordering/hashing, never the raw pointer (ASLR makes pointers
non-deterministic across runs).
- `manthan.{h,cpp}`, `manthan_learn.{h,cpp}` — counterexample-guided
synthesis / repair loop. Hot path for large benchmarks.
- `aig_rewrite.{h,cpp}` — structural hashing, CSE, absorption, ITE
flattening. Runs before Manthan and between repair rounds.
- `aig_to_cnf.{h,cpp}` — Tseitin encoding with fanout-based helper
suppression, k-ary AND/OR fusion, ITE / MUX3 detection.
- `puura.{h,cpp}` — SharpSAT-td-derived simplification.
- `autarky.cpp`, `backward.cpp`, `extend.cpp`, `minimize.cpp`,
`unate_def.cpp` — independent-set extraction passes.
- `metasolver.h`, `metasolver2.h`, `cachedsolver.h` — SAT-solver wrappers
used by Manthan.
- `test_aig_rewrite.cpp`, `test_aig_to_cnf.cpp`, `test-synth.cpp` —
correctness checkers.
- `aig_fuzzer.cpp`, `aig_to_cnf_fuzzer.cpp` — fuzzers.

## Determinism

The same binary must produce bit-identical output across runs and machines.
Do not introduce pointer-address-dependent ordering (`operator<` on
`shared_ptr`, `std::hash<T*>`, `reinterpret_cast<uintptr_t>` of a pointer).
For AIG nodes, order/hash on `AIG::nid` via the `aig_nid_less` comparator
(in `aig_rewrite.cpp`) or `AigPtrHash` (in `aig_rewrite.h` / `aig_to_cnf.h`).

## Debug outputs

When `--debugsynth` is passed, intermediate AIGs are written next to the
input CNF with suffixes `-simplified_cnf.aig`, `-autarky.aig`,
`-minim_idep_synt.aig`, `-manthan.aig`, `-final.aig`. `test-synth` verifies
each stage's AIG against the original CNF and is invoked automatically by
`fuzz_synth.py`.

## Debugging issues

When debugging a bug (assertion, wrong answer, crash, non-determinism), use
the full toolbox — don't stop at the first technique that gives a hint.
Expected workflow:

1. **Fuzzing** — reproduce / narrow down with `fuzz_synth.py`,
`fuzz_aig_to_cnf`, `fuzz_aig_rewrite` (see "After every build"). Fuzzers
generate minimal failing inputs much faster than reasoning from a large
user-supplied CNF.
2. **`scripts/cnf_delta.py`** — clause-level delta debugger for DIMACS CNFs.
Given a failing CNF and an oracle script that exits 0 iff the bug still
reproduces, it does plain ddmin on the clause list, preserving headers,
comments, and the `c p show … 0` projection line. Typical use: write a
tiny bash oracle that runs `arjun` with the bug-triggering flags and
greps stderr for the assertion text, then run
`./cnf_delta.py bug.cnf bug_min.cnf /tmp/oracle.sh`. Always minimize
before filing a repro or committing a bug CNF to the repo.
3. **`SLOW_DEBUG`** (`src/constants.h:50`) — uncomment to enable expensive
internal invariant checks (`SLOW_DEBUG_DO(...)` blocks). Turn this on
whenever an assertion fires or an output looks wrong; it will often fail
earlier and closer to the real cause.
4. **`VERBOSE_DEBUG`** (`src/constants.h:51`) — uncomment to enable verbose
trace prints guarded by `VERBOSE_DEBUG_DO(...)` / `verbose_debug_enabled`.
Use together with a delta-debugged small CNF so the traces stay readable.
5. **valgrind** — run under `valgrind --error-exitcode=1` (and
`--track-origins=yes` for uninitialized reads) for any suspected memory
issue. Undefined behavior here often manifests as non-determinism on
larger inputs.
6. **gdb** — for assertion failures and crashes, run under `gdb --args
./arjun ...`, `run`, then `bt` / `frame N` / `p` to inspect state at the
failure point. Pair with `SLOW_DEBUG` so gdb stops at the invariant
break, not downstream at a confusing symptom.

Default loop for a tricky bug: fuzz → delta-debug the failing CNF with
`cnf_delta.py` → rebuild with `SLOW_DEBUG` (and `VERBOSE_DEBUG` if needed) →
valgrind / gdb on the minimized CNF.
23 changes: 12 additions & 11 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,18 @@ endif()
# -----------------------------------------------------------------------------
set(ARJUN_EXPORT_NAME "arjunTargets")

# enable_testing() must run in the top-level CMakeLists BEFORE any
# add_subdirectory() calls that register tests with add_test(), otherwise
# the nested add_test() invocations land in a scope that ctest never sees
# and `make test` reports "No tests were found".
if(ENABLE_TESTING)
enable_testing()
message(STATUS "Testing is enabled")
set(UNIT_TEST_EXE_SUFFIX "Tests" CACHE STRING "Suffix for Unit test executable")
else()
message(WARNING "Testing is disabled")
endif()

add_subdirectory(src)

# -----------------------------------------------------------------------------
Expand All @@ -545,17 +557,6 @@ add_custom_target(uninstall_arjun
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake
)

if(ENABLE_TESTING)
enable_testing()

message(STATUS "Testing is enabled")
set(UNIT_TEST_EXE_SUFFIX "Tests" CACHE STRING "Suffix for Unit test executable")
#add_subdirectory(tests)

else()
message(WARNING "Testing is disabled")
endif()

# -----------------------------------------------------------------------------
# Export our targets so that other CMake based projects can interface with
# the build of arjun in the build-tree
Expand Down
Loading
Loading