{"id":13748699,"url":"https://github.com/shnarazk/splr","last_synced_at":"2025-04-13T04:23:49.976Z","repository":{"id":34276642,"uuid":"145999949","full_name":"shnarazk/splr","owner":"shnarazk","description":"A modern CDCL SAT solver in Rust","archived":false,"fork":false,"pushed_at":"2024-04-14T06:45:12.000Z","size":5600,"stargazers_count":71,"open_issues_count":8,"forks_count":8,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-04-14T07:56:58.294Z","etag":null,"topics":["cdcl","nix-flake","rust","sat-solver","satisfiability"],"latest_commit_sha":null,"homepage":"https://crates.io/crates/splr","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/shnarazk.png","metadata":{"files":{"readme":"README.md","changelog":"ChangeLog.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2018-08-24T14:12:42.000Z","updated_at":"2024-04-15T12:49:33.328Z","dependencies_parsed_at":"2023-02-16T08:16:02.197Z","dependency_job_id":"698c2481-2e38-4fdc-8a06-759f23d37d3d","html_url":"https://github.com/shnarazk/splr","commit_stats":{"total_commits":70,"total_committers":2,"mean_commits":35.0,"dds":"0.014285714285714235","last_synced_commit":"bb53c435447edb218f2d3ce82e1c765505ab1aa6"},"previous_names":[],"tags_count":35,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shnarazk%2Fsplr","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shnarazk%2Fsplr/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shnarazk%2Fsplr/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shnarazk%2Fsplr/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/shnarazk","download_url":"https://codeload.github.com/shnarazk/splr/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248662348,"owners_count":21141562,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cdcl","nix-flake","rust","sat-solver","satisfiability"],"created_at":"2024-08-03T07:00:47.706Z","updated_at":"2025-04-13T04:23:49.946Z","avatar_url":"https://github.com/shnarazk.png","language":"Rust","funding_links":[],"categories":["Projects","Rust"],"sub_categories":["Provers and Solvers"],"readme":"## A modern SAT Solver for Propositional Logic in Rust\n\nSplr is a modern SAT solver in [Rust](https://www.rust-lang.org), based on [Glucose 4.1](https://www.labri.fr/perso/lsimon/glucose/).\nIt adopts, or adopted, various research results on modern SAT solvers:\n\n- _CDCL_, _watch literals_, _LBD_ and so on from Glucose, [Minisat](http://minisat.se) and the ancestors\n- Luby series based restart control\n- Glucose-like _dynamic blocking/forcing restarts_\n- pre/in-processor to simplify the given CNF\n- branching variable selection based on _Learning Rate Based Branching_ with _Reason Side Rewarding_ or EVSIDS\n- [CaDiCaL](https://github.com/arminbiere/cadical)-like extended phase saving\n- _restart stabilization_ inspired by CadiCaL\n- _clause vivification_\n- _trail saving_\n\n*Many thanks to SAT researchers.*\n\nPlease check [ChangeLog](ChangeLog.md) about recent updates.\n\n## Correctness\n\nThough Splr comes with **ABSOLUTELY NO WARRANTY**, I'd like to show some results.\n\n#### Version 0.17.0\n\n- [SAT Competition 2021](https://satcompetition.github.io/2021/), [Benchmarks main track](https://satcompetition.github.io/2021/benchmarks.html) -- splr-0.17.0 solved with a 300 sec timeout (this is one of the best of splr):\n  - 49 satisfiable problems: all the solutions were correct.\n  - 34 unsatisfiable problems: all certifications were verified with [Grat toolchain](https://www21.in.tum.de/~lammich/grat/) or [drat-trim](https://github.com/marijnheule/drat-trim).\n\n## Install\n\nJust run `cargo install splr` after installing the latest [cargo](https://www.rust-lang.org/tools/install).\nTwo executables will be installed:\n\n- `splr` -- the solver\n- `dmcr` -- a very simple model checker to verify a *satisfiable* assignment set generated by `splr`.\n\nAlternatively, Nix users can use `nix build`.\n\n### About `no_std` environment and feature `no_IO`\n\nIf you want to build a library for `no_std` environment,\nor if you want to compile with feature `no_IO`,\nyou have to run `cargo build --lib --features no_IO`.\nThey are incompatible with `cargo install`.\n\n- [2024-02-03] Feature `platform_wasm` was added.\n\n## Usage\n\nSplr is a standalone program, taking a CNF file. The result will be saved to a file, which format is\ndefined by [SAT competition 2011 rules](http://www.satcompetition.org/2011/rules.pdf).\n\n```plain\n$ splr cnfs/unif-k3-r4.25-v360-c1530-S1293537826-039.cnf\nunif-k3-r4.25-v360-c1530-S1293537826-039.cnf       360,1530 |time:   732.01\n #conflict:    9663289, #decision:     23326959, #propagate:      546184944\n  Assignment|#rem:      351, #fix:        0, #elm:        9, prg%:   2.5000\n      Clause|Remv:    69224, LBD2:     2857, BinC:        1, Perm:     1522\n    Conflict|entg:   7.0499, cLvl:  12.2451, bLvl:  11.1030, /cpr:    30.74\n    Learning|avrg:  10.4375, trnd:   1.0069, #RST:   566140, /dpc:     1.18\n        misc|vivC:     7370, subC:        0, core:      122, /ppc:    61.53\n      Result|file: ./ans_unif-k3-r4.25-v360-c1530-S1293537826-039.cnf\ns SATISFIABLE: cnfs/unif-k3-r4.25-v360-c1530-S1293537826-039.cnf\n```\n\n```plain\n$ cat ans_unif-k3-r4.25-v360-c1530-S1293537826-039.cnf\nc This file was generated by splr-0.15.0 for cnfs/unif-k3-r4.25-v360-c1530-S1293537826-039.cnf\nc\nc unif-k3-r4.25-v360-c1530-S1293537826-039.cnf, #var:      360, #cls:     1530\nc  #conflict:    9663289, #decision:     23326959, #propagate:      546184944,\nc   Assignment|#rem:      351, #fix:        0, #elm:        9, prg%:   2.5000,\nc       Clause|Remv:    69224, LBD2:     2857, BinC:        1, Perm:     1522,\nc     Conflict|entg:   7.0499, cLvl:  12.2451, bLvl:  11.1030, /cpr:    30.74,\nc      Learing|avrg:  10.4375, trnd:   1.0069, #RST:   566140, /dpc:     1.18,\nc         misc|vivC:     7370, subC:        0, core:      122, /ppc:    61.53,\nc     Strategy|mode:  generic, time:   732.03,\nc\nc   config::VarRewardDecayRate                       0.960\nc   assign::NumConflict                        9663289\nc   assign::NumDecision                       23326959\nc   assign::NumPropagation                   546184944\nc   assign::NumRephase                             734\nc   assign::NumRestart                          566141\nc   assign::NumVar                                 360\nc   assign::NumAssertedVar                           0\nc   assign::NumEliminatedVar                         9\nc   assign::NumReconflict                          653\nc   assign::NumRepropagation                  12460396\nc   assign::NumUnassertedVar                       351\nc   assign::NumUnassignedVar                       351\nc   assign::NumUnreachableVar                        0\nc   assign::RootLevel                                0\nc   assign::AssignRate                               0.000\nc   assign::DecisionPerConflict                      1.179\nc   assign::PropagationPerConflict                  61.527\nc   assign::ConflictPerRestart                     122.388\nc   assign::ConflictPerBaseRestart                 122.388\nc   assign::BestPhaseDivergenceRate                  0.000\nc   clause::NumBiClause                              1\nc   clause::NumBiClauseCompletion                    0\nc   clause::NumBiLearnt                              1\nc   clause::NumClause                            70746\nc   clause::NumLBD2                               2857\nc   clause::NumLearnt                            69224\nc   clause::NumReduction                          1461\nc   clause::NumReRegistration                        0\nc   clause::Timestamp                                0\nc   clause::LiteralBlockDistance                    10.438\nc   clause::LiteralBlockEntanglement                 7.050\nc   state::Vivification                            735\nc   state::VivifiedClause                         7370\nc   state::VivifiedVar                               0\nc   state::NumCycle                                734\nc   state::NumStage                               1461\nc   state::IntervalScale                             1\nc   state::IntervalScaleMax                       1024\nc   state::BackjumpLevel                            11.103\nc   state::ConflictLevel                            12.245\nc\ns SATISFIABLE\nv 1 -2 3 4 5 6 -7 -8 9 -10 -11 -12 13 -14 ...  -360 0\n```\n\n```plain\n$ dmcr cnfs/unif-k3-r4.25-v360-c1530-S1293537826-039.cnf\nA valid assignment set for cnfs/unif-k3-r4.25-v360-c1530-S1293537826-039.cnf is found in ans_unif-k3-r4.25-v360-c1530-S1293537826-039.cnf\n```\n\nIf you want to certificate unsatisfiability, use `--certify` or `-c` and use proof checker like [Grid](https://www21.in.tum.de/~lammich/grat/).\n\nFirstly run splr with the certificate option `-c`.\n\n```plain\n$ splr -c cnfs/unif-k3-r4.25-v360-c1530-S1028159446-096.cnf\nunif-k3-r4.25-v360-c1530-S1028159446-096.cnf       360,1530 |time:   204.09\n #conflict:    4018458, #decision:      9511129, #propagate:      221662222\n  Assignment|#rem:      345, #fix:        7, #elm:        8, prg%:   4.1667\n      Clause|Remv:    11290, LBD2:     2018, BinC:      137, Perm:     1517\n    Conflict|entg:   4.5352, cLvl:   8.0716, bLvl:   6.9145, /cpr:   112.08\n    Learning|avrg:   1.5625, trnd:   0.2219, #RST:   237295, /dpc:     1.07\n        misc|vivC:     4085, subC:        0, core:      345, /ppc:    52.55\n      Result|file: ./ans_unif-k3-r4.25-v360-c1530-S1028159446-096.cnf\n Certificate|file: proof.drat\ns UNSATISFIABLE: cnfs/unif-k3-r4.25-v360-c1530-S1028159446-096.cnf\n```\n\n#### A: Verify with [drat-trim](https://github.com/marijnheule/drat-trim)\n\n```plain\n$ drat-trim cnfs/unif-k3-r4.25-v360-c1530-S1028159446-096.cnf proof.drat\nc parsing input formula with 360 variables and 1530 clauses\nc finished parsing\nc detected empty clause; start verification via backward checking\nc 1530 of 1530 clauses in core\nc 2036187 of 4029964 lemmas in core using 68451907 resolution steps\nc 0 RAT lemmas in core; 908116 redundant literals in core lemmas\ns VERIFIED\nc verification time: 105.841 seconds\n```\n\n#### B: Verify with gratchk\n\nFirstly you have to convert the generated DRAT file to a GRAT file.\n\n```plain\n$ gratgen cnfs/unif-k3-r4.25-v360-c1530-S1028159446-096.cnf proof.drat -o proof.grat\nc sizeof(cdb_t) = 4\nc sizeof(cdb_t*) = 8\nc Using RAT run heuristics\nc Parsing formula ... 1ms\nc Parsing proof (ASCII format) ... 32251ms\nc Forward pass ... 2073ms\nc Starting Backward pass\nc Single threaded mode\n\n0%   10   20   30   40   50   60   70   80   90   100%\n|----|----|----|----|----|----|----|----|----|----|\n***************************************************\nc Waiting for aux-threads ...done\nc Lemmas processed by threads: 2032698 mdev: 0\nc Finished Backward pass: 65356ms\nc Writing combined proof ... 19088ms\ns VERIFIED\nc Timing statistics (ms)\nc Parsing:  32253\nc Checking: 67465\nc   * bwd:  65356\nc Writing:  19088\nc Overall:  118808\nc   * vrf:  99720\n\nc Lemma statistics\nc RUP lemmas:  2032698\nc RAT lemmas:  0\nc   RAT run heuristics:   0\nc Total lemmas:  2032698\n\nc Size statistics (bytes)\nc Number of clauses: 4031493\nc Clause DB size:  309680252\nc Item list:       128778112\nc Pivots store:    16777216\n```\n\nThen verify it with `gratchk`.\n\n```plain\n$ gratchk unsat cnfs/unif-k3-r4.25-v360-c1530-S1028159446-096.cnf proof.grat\nc Reading cnf\nc Reading proof\nc Done\nc Verifying unsat\ns VERIFIED UNSAT\n```\n\n### Calling Splr from Rust programs\n\nSince 0.4.0, you can use Splr in your programs. (Here I suppose that you uses Rust 2021.)\n\n```rust\nuse splr::*;\n\nfn main() {\n    let v: Vec\u003cVec\u003ci32\u003e\u003e = vec![vec![1, 2], vec![-1, 3], vec![1, -3], vec![-1, 2]];\n    match Certificate::try_from(v) {\n        Ok(Certificate::SAT(ans)) =\u003e println!(\"s SATISFIABLE: {:?}\", ans),\n        Ok(Certificate::UNSAT) =\u003e println!(\"s UNSATISFIABLE\"),\n        Err(e) =\u003e panic!(\"s UNKNOWN; {}\", e),\n    }\n}\n```\n\n### All solutions SAT solver as an application of 'incremental_solver' feature\n\nThe following example requires 'incremental_solver' feature. You need the following dependeny:\n\n```toml\nsplr = { version = \"^0.17\", features = [\"incremental_solver\"] }\n```\nUnder this configuration, module `splr` provides some more functions:\n\n- `splr::Solver::reset(\u0026mut self)`\n- `splr::Solver::add_var(\u0026mut self)` // increments the last variable number\n- `splr::Solver::add_clause(\u0026mut self, vec: AsRef\u003c[i32]\u003e) -\u003e Result\u003c\u0026mut Solver, SolverError\u003e`\n\nYou have to call `reset` before calling `add_var`, `add_clause`, and `solve` again.\nBy this, splr forgets everything about the previous formula, especially non-equivalent transformations by pre/inter-processors like clause subsumbtion.\nSo technically splr is not an incremental solver.\n\n'add_clause' will emit an error if `vec` is invalid.\n\n```rust\nuse splr::*;\nuse std::env::args;\n\nfn main() {\n    let cnf = args().nth(1).expect(\"takes an arg\");\n    let assigns: Vec\u003ci32\u003e = Vec::new();\n    println!(\"#solutions: {}\", run(\u0026cnf, \u0026assigns));\n}\n\n#[cfg(feature = \"incremental_solver\")]\nfn run(cnf: \u0026str, assigns: \u0026[i32]) -\u003e usize {\n    let mut solver = Solver::try_from(cnf).expect(\"panic at loading a CNF\");\n    for n in assigns.iter() {\n        solver.add_assignment(*n).expect(\"panic at assertion\");\n    }\n    let mut count = 0;\n    loop {\n        match solver.solve() {\n            Ok(Certificate::SAT(ans)) =\u003e {\n                count += 1;\n                println!(\"s SATISFIABLE({}): {:?}\", count, ans);\n                let ans = ans.iter().map(|i| -i).collect::\u003cVec\u003ci32\u003e\u003e();\n                match solver.add_clause(ans) {\n                    Err(SolverError::Inconsistent) =\u003e {\n                        println!(\"c no answer due to level zero conflict\");\n                        break;\n                    }\n                    Err(e) =\u003e {\n                        println!(\"s UNKNOWN; {:?}\", e);\n                        break;\n                    }\n                    Ok(_) =\u003e solver.reset(),\n                }\n            }\n            Ok(Certificate::UNSAT) =\u003e {\n                println!(\"s UNSATISFIABLE\");\n                break;\n            }\n            Err(e) =\u003e {\n                println!(\"s UNKNOWN; {}\", e);\n                break;\n            }\n        }\n    }\n    count\n}\n```\n\nSince 0.4.1, `Solver` has `iter()`. So you can iterate on satisfiable '`solution: Vec\u003ci32\u003e`'s as:\n\n```rust\n#[cfg(feature = \"incremental_solver\")]\nfor (i, v) in Solver::try_from(cnf).expect(\"panic\").iter().enumerate() {\n    println!(\"{}-th answer: {:?}\", i, v);\n}\n```\n\n#### sample code from my [sudoku solver](https://github.com/shnarazk/sudoku_sat/)\n\nhttps://github.com/shnarazk/sudoku_sat/blob/4490b4358e5f3b72803a566323a6c8c196627f92/src/bin/sudoku400.rs#L36-L60\n\n```rust\n    let mut solver = Solver::try_from((config, rules.as_ref())).expect(\"panic\");\n    for a in setting.iter() {\n        solver.add_assignment(*a).expect(\"panic\");\n    }\n    for ans in solver.iter().take(1) {\n        let mut picked = ans.iter().filter(|l| 0 \u003c **l).collect::\u003cVec\u003c\u0026i32\u003e\u003e();\n        for _i in 1..=range {\n            for _j in 1..=range {\n                let (_i, _j, d, _b) = Cell::decode(*picked.remove(0));\n                print!(\"{:\u003e2} \", d);\n            }\n            println!();\n        }\n        println!();\n    }\n}\n```\n\n### Mnemonics used in the progress message\n\n| mnemonic     | meaning                                                                                   |\n| ------------ | ----------------------------------------------------------------------------------------- |\n| `#var`       | the number of variables used in the given CNF file                                        |\n| `#cls`       | the number of clauses used in the given CNF file                                          |\n| `time`       | elapsed CPU time in seconds (or wall-clock time if CPU time is not available)             |\n| `#conflict`  | the number of conflicts                                                                   |\n| `#decision`  | the number of decisions                                                                   |\n| `#propagate` | the number of propagates (its unit is literal)                                            |\n| `#rem`       | the number of remaining variables                                                         |\n| `#fix`       | the number of asserted variables (which has been assigned a value at decision level zero) |\n| `#elm`       | the number of eliminated variables                                                        |\n| `prg%`       | the percentage of `remaining variables / total variables`                                 |\n| `Remv`       | the current number of learnt clauses that are not bi-clauses                              |\n| `LBD2`       | the accumulated number of learnt clauses which LBDs are 2                                 |\n| `BinC`       | the current number of binary learnt clauses                                               |\n| `Perm`       | the current number of given clauses and binary learnt clauses                             |\n| `entg`       | the current average of 'Literal Block entanglement'                                       |\n| `cLvl`       | the EMA of decision levels at which conflicts occur                                       |\n| `bLvl`       | the EMA of decision levels to which backjumps go                                          |\n| `/cpr`       | the EMA of conflicts per restart                                                          |\n| `avrg`       | the EMA, Exponential Moving Average, of LBD of learnt clauses                             |\n| `trnd`       | the current trend of the LBD's EMA                                                        |\n| `#RST`       | the number of restarts                                                                    |\n| `/dpc`       | the EMA of decisions per conflict                                                         |\n| `vivC`       | the number of the vivified clauses                                                        |\n| `subC`       | the number of the clauses subsumed by clause elimination processor                        |\n| `core`       | the number of unreachable vars                                                            |\n| `/ppc`       | the EMA of propagations per conflict                                                      |\n| `time`       | the elapsed CPU time in seconds                                                           |\n\n## Command line options\n\n```plain\nA modern CDCL SAT solver in Rust\nActivated features: best phase tracking, stage-based clause elimination, stage-based clause vivification, stage-based dynamic restart threshold, Learning-Rate Based rewarding, reason-side rewarding, stage-based re-phasing, two-mode reduction, trail saving, unsafe access\n\nUSAGE:\n  splr [FLAGS] [OPTIONS] \u003ccnf-file\u003e\nFLAGS:\n  -h, --help                Prints help information\n  -C, --no-color            Disable coloring\n  -q, --quiet               Disable any progress message\n  -c, --certify             Writes a DRAT UNSAT certification file\n  -j, --journal             Shows log about restart stages\n  -l, --log                 Uses Glucose-like progress report\n  -V, --version             Prints version information\nOPTIONS:\n      --cl \u003cc-cls-lim\u003e      Soft limit of #clauses (6MC/GB)         0\n      --crl \u003ccls-rdc-lbd\u003e   Clause reduction LBD threshold          5\n      --cr1 \u003ccls-rdc-rm1\u003e   Clause reduction ratio for mode1        0.20\n      --cr2 \u003ccls-rdc-rm2\u003e   Clause reduction ratio for mode2        0.05\n      --ecl \u003celm-cls-lim\u003e   Max #lit for clause subsume            64\n      --evl \u003celm-grw-lim\u003e   Grow limit of #cls in var elim.         0\n      --evo \u003celm-var-occ\u003e   Max #cls for var elimination        20000\n  -o, --dir \u003cio-outdir\u003e     Output directory                         .\n  -p, --proof \u003cio-pfile\u003e    DRAT Cert. filename                 proof.drat\n  -r, --result \u003cio-rfile\u003e   Result filename/stdout\n  -t, --timeout \u003ctimeout\u003e   CPU time limit in sec.               5000\n      --vdr \u003cvrw-dcy-rat\u003e   Var reward decay rate                   0.96\nARGS:\n  \u003ccnf-file\u003e    DIMACS CNF file\n```\n\n## Solver description\n\nSplr-0.17.0 adopts the following features by default:\n\n- Learning-rate based (LRB) var rewarding and clause rewarding[4]\n- Reason-side var rewarding[4]\n- ~~chronological backtrack[5]~~ disabled since 0.12 due to incorrect UNSAT certificates.\n- clause vivification[6]\n- Luby series based on the number of conflicts defines 'stages/cycles/segments', which are used as trigger of\n  - restart\n  - clause reduction\n  - in-processor (clause elimination, subsumption and vivification)\n  - re-configuration of var phases and var activities\n  - re-configuration of trail saving extended with reason refinement based on clause quality[3].\n\n(Splr-0.15.0 and upper try to discard various dynamic and heuristic-based control schemes used in the previous versions.)\n\nThe following figure explains the flow used in the latest Splr.\n\n![search algorithm in Splr 0.17](https://user-images.githubusercontent.com/997855/215309646-1bfe3ea5-dcc3-42ee-9d76-99e1b07610c4.png)\n\nI use the following terms here:\n- _a stage_ -- a span in which solver uses the same restart parameters\n- _a cycle_ -- a group of continuos spans of which the corresponding Luby values make a non-decreasing sequence\n- _a segment_ -- a group of continuos cycles which are separated by new maximum Luby values' occurrences\n\n#### Bibliography\n\n- [1] G. Audemard and L. Simon, \"Predicting learnt clauses quality in modern SAT solvers,\" in _International Joint Conference on Artificial Intelligence 2009_, pp. 399–404, 2009.\n\n- [2] G. Audemard and L. Simon, \"Refining restarts strategies for SAT and UNSAT,\" in _LNCS_, vol.7513, pp.118–126, 2012.\n\n- [3] R. Hickey and F. Bacchus, \"Trail Saving on Backtrack\", _SAT 2020_, _LNCS_, vol. 12178, pp.46-61, 2020.\n\n- [4] J. H. Liang, V. Ganesh, P. Poupart, and K. Czarnecki, \"Learning Rate Based Branching Heuristic for SAT Solvers,\" in _LNCS_, vol.9710, pp.123–140, 2016.\n\n- [5] A. Nadel and V. Ryvchin, \"Chronological Backtracking,\" in _Theory and Applications of Satisfiability Testing - SAT 2018_, June 2018, pp.111–121, 2018.\n\n- [6] C. Piette, Y. Hamadi, and L. Saïs, \"Vivifying propositional clausal formulae,\" _Front. Artif. Intell. Appl._, vol.178, pp.525–529, 2008.\n\n## License\n\nThis Source Code Form is subject to the terms of the Mozilla Public\nLicense, v. 2.0. If a copy of the MPL was not distributed with this\nfile, You can obtain one at http://mozilla.org/MPL/2.0/.\n\n---\n\n2020-2024, Narazaki Shuji\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshnarazk%2Fsplr","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshnarazk%2Fsplr","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshnarazk%2Fsplr/lists"}