├── test ├── file │ ├── 0 │ ├── writable │ ├── uncompressed.7z │ ├── uncompressed.bz2 │ ├── uncompressed.gz │ ├── uncompressed.lzma │ ├── uncompressed.xz │ ├── 1.bz2 │ ├── 2.gz │ ├── 4.7z │ ├── 5.xz │ └── 3.lzma ├── parse │ ├── onlycr │ ├── emptyfile │ ├── emptyline │ ├── nlafterp │ ├── nocnorp │ ├── nonafterc │ ├── eofinclauses │ ├── eofinheaderafterc │ ├── eofinmaxvar │ ├── nospaceafterp │ ├── signeof │ ├── nlaftervars │ ├── nospaceafterf │ ├── onlycraftervars │ ├── nonlaftercrinbody │ ├── oneclausemissing │ ├── twoclausesmissing │ ├── crnl │ ├── eofafterlit │ ├── eofafterzero │ ├── eofbodycomment │ ├── nlaftersign │ ├── nocafterpspace │ ├── nofaftern │ ├── nonlaftercrafterlit │ ├── nonlafterheaderline │ ├── notrailingzero │ ├── signedunit │ ├── toolargevars1 │ ├── toolargevars2 │ ├── zeroaftersign │ ├── eofafterlitcomment │ ├── eofbeforeheader │ ├── nodigitaftervarsnspace │ ├── nonlaftercrafterheaderline │ ├── nonlaftercrafterheadliner │ ├── othercharafterheaderline │ ├── toomanyclauses │ ├── varidxexceeded │ ├── embeddednegative │ ├── embeddedoptiocrnl │ ├── eofheadercomment │ ├── nodigitafterpcnfspace │ ├── nonlafterinvalidembeddedoption │ ├── tabs │ ├── embeddedcrmissingnl │ ├── embeddedoptioneqmissing │ ├── invalidembeddedoption │ ├── onlycomments │ ├── varidxtoolarge1 │ ├── varidxtoolarge2 │ ├── anainsteadoflit │ ├── nospaceaftervars │ ├── toolargeclauses1 │ ├── toolargeclauses2 │ ├── crnlfile │ ├── eofincommmentafterliteral │ ├── headerspaces │ ├── nodigitaftersign │ ├── nowsafterlit │ ├── emptyheadercrnl │ ├── embeddedoptionametoolong │ ├── emptyheaderline │ ├── embeddedcoverage │ └── comments ├── cnf │ ├── hard.cnf │ ├── true.cnf │ ├── false.cnf │ ├── bin1.cnf │ ├── bin2.cnf │ ├── eq1.cnf │ ├── eq3.cnf │ ├── unit1.cnf │ ├── unit2.cnf │ ├── unit3.cnf │ ├── bin3.cnf │ ├── unit5.cnf │ ├── twocores1.cnf │ ├── full2.cnf │ ├── eq2.cnf │ ├── unit4.cnf │ ├── tieshirt.cnf │ ├── probe1.cnf │ ├── twocores2.cnf │ ├── ph2.cnf │ ├── full3.cnf │ ├── unit6.cnf │ ├── and1.cnf │ ├── and2.cnf │ ├── diamond1.cnf │ ├── xor2.cnf │ ├── ite1.cnf │ ├── xor1.cnf │ ├── diamond2.cnf │ ├── twocores3.cnf │ ├── diamond3.cnf │ ├── full4.cnf │ ├── ph3.cnf │ ├── xor3.cnf │ ├── xor4.cnf │ ├── def1.cnf │ ├── ph4.cnf │ ├── prime4.cnf │ ├── ph5.cnf │ ├── ph6.cnf │ └── add4.cnf ├── configure ├── big │ ├── .gitignore │ └── makefile ├── cover │ ├── cover0000.cnf │ ├── cover0005.cnf │ ├── cover0031.cnf │ ├── cover0033.cnf │ ├── cover0037.cnf │ ├── cover0013.cnf │ ├── cover0034.cnf │ ├── cover0027.cnf │ ├── cover0001.cnf │ ├── cover0029.cnf │ ├── cover0003.cnf │ ├── cover0017.cnf │ ├── cover0019.cnf │ ├── cover0014.cnf │ ├── cover0004.cnf │ ├── cover0038.cnf │ ├── cover0006.cnf │ ├── cover0009.cnf │ ├── cover0007.cnf │ ├── cover0026.cnf │ ├── cover0044.cnf │ ├── cover0030.cnf │ ├── cover0032.cnf │ ├── cover0028.cnf │ ├── cover0021.cnf │ ├── cover0041.cnf │ ├── cover0010.cnf │ ├── cover0045.cnf │ ├── cover0024.cnf │ ├── cover0016.cnf │ ├── cover0040.cnf │ ├── cover0035.cnf │ ├── cover0011.cnf │ ├── cover0042.cnf │ ├── cover0036.cnf │ ├── cover0043.cnf │ ├── cover0023.cnf │ ├── cover0022.cnf │ ├── cover0025.cnf │ ├── cover0012.cnf │ ├── cover0039.cnf │ └── cover0020.cnf ├── makefile ├── testdivert.h ├── testapplication.h ├── testmessages.h ├── testscheduler.h ├── testsizes.c ├── testreap.c ├── testdump.c ├── testadd.c ├── testconfig.c ├── testutilities.c ├── testreluctant.c ├── testarray.c ├── testsolve.c ├── testbump.c ├── testendianness.c ├── testbits.c ├── testapplication.c ├── teststack.c ├── test.h ├── testsort.c ├── testcnfs.h ├── testdivert.c ├── testerror.c └── testcoverage.c ├── VERSION ├── src ├── makefile ├── configure ├── sweep.h ├── search.h ├── vivify.h ├── shrink.h ├── ternary.h ├── autarky.h ├── backbone.h ├── failed.h ├── restore.h ├── transitive.h ├── endianness.h ├── application.h ├── substitute.h ├── propsearch.h ├── bump.h ├── ands.h ├── definition.h ├── dominate.h ├── equivalences.h ├── witness.h ├── xors.h ├── probe.h ├── deduce.h ├── propdense.h ├── reduce.h ├── learn.h ├── prophyper.h ├── attribute.h ├── ifthenelse.h ├── import.h ├── resolve.h ├── backward.h ├── nonces.h ├── proprobe.h ├── walk.h ├── forward.h ├── add.h ├── compact.h ├── analyze.h ├── restart.h ├── resize.h ├── config.h ├── minimize.h ├── decide.h ├── weaken.h ├── value.h ├── dense.h ├── reference.h ├── report.h ├── backtrack.h ├── terminate.c ├── utilities.c ├── protect.h ├── parse.h ├── bits.c ├── error.h ├── strengthen.h ├── smooth.h ├── trail.h ├── assume.h ├── colors.c ├── resources.h ├── nonces.c ├── inlineframes.h ├── mode.h ├── frames.h ├── gates.h ├── averages.c ├── cover.h ├── reap.h ├── eliminate.h ├── rephase.h ├── averages.h ├── handle.h ├── reap.c ├── inlinescore.h ├── reluctant.h ├── clueue.h ├── allocate.h ├── queue.h ├── collect.h ├── promote.h ├── require.h ├── extend.h ├── arena.h ├── proprobe.c ├── cache.h ├── phases.h ├── literal.h ├── witness.c ├── fastassign.h ├── vector.h ├── flags.h ├── random.h ├── equivalences.c ├── array.h ├── format.h ├── main.c ├── assign.h ├── kitten.h ├── error.c ├── promote.c ├── print.h ├── kissat.h ├── file.h ├── colors.h ├── propsearch.c ├── reluctant.c ├── queue.c ├── stack.c ├── probe.c ├── assign.c ├── smooth.c ├── build.c ├── handle.c ├── protect.c ├── bits.h ├── heap.h ├── resources.c ├── phases.c ├── weaken.c ├── terminate.h ├── clause.h ├── config.c └── sort.c ├── UPSTREAM_VERSION ├── .gitignore ├── .clangd ├── scripts ├── determine-coverage.sh ├── filter-coverage-output.sh └── generate-build-header.sh ├── LICENSE ├── makefile.in └── README.md /test/file/writable: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/parse/onlycr: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /VERSION: -------------------------------------------------------------------------------- 1 | 0.1.0-dev 2 | -------------------------------------------------------------------------------- /src/makefile: -------------------------------------------------------------------------------- 1 | ../makefile -------------------------------------------------------------------------------- /test/parse/emptyfile: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /UPSTREAM_VERSION: -------------------------------------------------------------------------------- 1 | 2.0.1 2 | -------------------------------------------------------------------------------- /src/configure: -------------------------------------------------------------------------------- 1 | ../configure -------------------------------------------------------------------------------- /test/cnf/hard.cnf: -------------------------------------------------------------------------------- 1 | ph11.cnf -------------------------------------------------------------------------------- /test/configure: -------------------------------------------------------------------------------- 1 | ../configure -------------------------------------------------------------------------------- /test/file/0: -------------------------------------------------------------------------------- 1 | p cnf 0 0 2 | -------------------------------------------------------------------------------- /test/parse/emptyline: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /test/parse/nlafterp: -------------------------------------------------------------------------------- 1 | p 2 | -------------------------------------------------------------------------------- /test/parse/nocnorp: -------------------------------------------------------------------------------- 1 | a 2 | -------------------------------------------------------------------------------- /test/parse/nonafterc: -------------------------------------------------------------------------------- 1 | p c 2 | -------------------------------------------------------------------------------- /test/big/.gitignore: -------------------------------------------------------------------------------- 1 | genbigand 2 | -------------------------------------------------------------------------------- /test/cnf/true.cnf: -------------------------------------------------------------------------------- 1 | p cnf 0 0 2 | -------------------------------------------------------------------------------- /test/parse/eofinclauses: -------------------------------------------------------------------------------- 1 | p cnf 1 1 -------------------------------------------------------------------------------- /test/parse/eofinheaderafterc: -------------------------------------------------------------------------------- 1 | c -------------------------------------------------------------------------------- /test/parse/eofinmaxvar: -------------------------------------------------------------------------------- 1 | p cnf 1 -------------------------------------------------------------------------------- /test/parse/nospaceafterp: -------------------------------------------------------------------------------- 1 | pa 2 | -------------------------------------------------------------------------------- /test/parse/signeof: -------------------------------------------------------------------------------- 1 | p cnf 1 1 2 | - -------------------------------------------------------------------------------- /test/cnf/false.cnf: -------------------------------------------------------------------------------- 1 | p cnf 0 1 2 | 0 3 | -------------------------------------------------------------------------------- /test/parse/nlaftervars: -------------------------------------------------------------------------------- 1 | p cnf 1 2 | -------------------------------------------------------------------------------- /test/parse/nospaceafterf: -------------------------------------------------------------------------------- 1 | p cnf 2 | -------------------------------------------------------------------------------- /test/parse/onlycraftervars: -------------------------------------------------------------------------------- 1 | p cnf 1 -------------------------------------------------------------------------------- /test/cnf/bin1.cnf: -------------------------------------------------------------------------------- 1 | p cnf 2 1 2 | 1 2 0 3 | -------------------------------------------------------------------------------- /test/cnf/bin2.cnf: -------------------------------------------------------------------------------- 1 | p cnf 2 1 2 | -1 -2 0 3 | -------------------------------------------------------------------------------- /test/file/uncompressed.7z: -------------------------------------------------------------------------------- 1 | p cnf 0 0 2 | -------------------------------------------------------------------------------- /test/file/uncompressed.bz2: -------------------------------------------------------------------------------- 1 | p cnf 0 0 2 | -------------------------------------------------------------------------------- /test/file/uncompressed.gz: -------------------------------------------------------------------------------- 1 | p cnf 0 0 2 | -------------------------------------------------------------------------------- /test/file/uncompressed.lzma: -------------------------------------------------------------------------------- 1 | p cnf 0 0 2 | -------------------------------------------------------------------------------- /test/file/uncompressed.xz: -------------------------------------------------------------------------------- 1 | p cnf 0 0 2 | -------------------------------------------------------------------------------- /test/parse/nonlaftercrinbody: -------------------------------------------------------------------------------- 1 | p cnf 1 1 2 | -------------------------------------------------------------------------------- /test/parse/oneclausemissing: -------------------------------------------------------------------------------- 1 | p cnf 1 1 2 | -------------------------------------------------------------------------------- /test/parse/twoclausesmissing: -------------------------------------------------------------------------------- 1 | p cnf 1 2 2 | -------------------------------------------------------------------------------- /test/parse/crnl: -------------------------------------------------------------------------------- 1 | p cnf 1 1 2 | 3 | 1 0 4 | -------------------------------------------------------------------------------- /test/parse/eofafterlit: -------------------------------------------------------------------------------- 1 | p cnf 1 1 2 | 1 3 | 1 -------------------------------------------------------------------------------- /test/parse/eofafterzero: -------------------------------------------------------------------------------- 1 | p cnf 1 1 2 | 1 3 | 0 -------------------------------------------------------------------------------- /test/parse/eofbodycomment: -------------------------------------------------------------------------------- 1 | p cnf 1 1 2 | 1 0 3 | c -------------------------------------------------------------------------------- /test/parse/nlaftersign: -------------------------------------------------------------------------------- 1 | p cnf 1 1 2 | - 3 | 4 | -------------------------------------------------------------------------------- /test/parse/nocafterpspace: -------------------------------------------------------------------------------- 1 | comment 2 | p 3 | -------------------------------------------------------------------------------- /test/parse/nofaftern: -------------------------------------------------------------------------------- 1 | c 2 | c 3 | c 4 | p cnF 5 | -------------------------------------------------------------------------------- /test/parse/nonlaftercrafterlit: -------------------------------------------------------------------------------- 1 | p cnf 1 1 2 | 1 a -------------------------------------------------------------------------------- /test/parse/nonlafterheaderline: -------------------------------------------------------------------------------- 1 | p cnf 1 1 -------------------------------------------------------------------------------- /test/parse/notrailingzero: -------------------------------------------------------------------------------- 1 | p cnf 1 1 2 | 1 3 | -------------------------------------------------------------------------------- /test/parse/signedunit: -------------------------------------------------------------------------------- 1 | p cnf 1 1 2 | -1 0 3 | -------------------------------------------------------------------------------- /test/parse/toolargevars1: -------------------------------------------------------------------------------- 1 | p cnf 1000000000 0 2 | -------------------------------------------------------------------------------- /test/parse/toolargevars2: -------------------------------------------------------------------------------- 1 | p cnf 268435456 0 2 | -------------------------------------------------------------------------------- /test/parse/zeroaftersign: -------------------------------------------------------------------------------- 1 | p cnf 1 1 2 | -0 3 | -------------------------------------------------------------------------------- /test/cnf/eq1.cnf: -------------------------------------------------------------------------------- 1 | p cnf 2 2 2 | 1 2 0 3 | -1 -2 0 4 | -------------------------------------------------------------------------------- /test/cnf/eq3.cnf: -------------------------------------------------------------------------------- 1 | p cnf 2 2 2 | 1 2 0 3 | 1 -2 0 4 | -------------------------------------------------------------------------------- /test/cnf/unit1.cnf: -------------------------------------------------------------------------------- 1 | p cnf 1 2 2 | 1 0 3 | -1 0 4 | -------------------------------------------------------------------------------- /test/cnf/unit2.cnf: -------------------------------------------------------------------------------- 1 | p cnf 1 2 2 | -1 0 3 | 1 0 4 | -------------------------------------------------------------------------------- /test/cnf/unit3.cnf: -------------------------------------------------------------------------------- 1 | p cnf 2 2 2 | 2 0 3 | -2 0 4 | -------------------------------------------------------------------------------- /test/parse/eofafterlitcomment: -------------------------------------------------------------------------------- 1 | p cnf 1 1 2 | 1comment -------------------------------------------------------------------------------- /test/parse/eofbeforeheader: -------------------------------------------------------------------------------- 1 | c no header follows 2 | -------------------------------------------------------------------------------- /test/parse/nodigitaftervarsnspace: -------------------------------------------------------------------------------- 1 | p cnf 1 nodigit 2 | -------------------------------------------------------------------------------- /test/parse/nonlaftercrafterheaderline: -------------------------------------------------------------------------------- 1 | p cnf 1 1 -------------------------------------------------------------------------------- /test/parse/nonlaftercrafterheadliner: -------------------------------------------------------------------------------- 1 | c p cnf 0 0 2 | -------------------------------------------------------------------------------- /test/parse/othercharafterheaderline: -------------------------------------------------------------------------------- 1 | p cnf 1 1 nonl -------------------------------------------------------------------------------- /test/parse/toomanyclauses: -------------------------------------------------------------------------------- 1 | p cnf 1 0 2 | 1 3 | 0 4 | -------------------------------------------------------------------------------- /test/parse/varidxexceeded: -------------------------------------------------------------------------------- 1 | p cnf 13 1 2 | 14 0 3 | -------------------------------------------------------------------------------- /test/cnf/bin3.cnf: -------------------------------------------------------------------------------- 1 | p cnf 2 2 2 | 1 -2 0 3 | -1 -2 0 4 | -------------------------------------------------------------------------------- /test/cover/cover0000.cnf: -------------------------------------------------------------------------------- 1 | c status 10 2 | p cnf 0 0 3 | -------------------------------------------------------------------------------- /test/parse/embeddednegative: -------------------------------------------------------------------------------- 1 | c --oops=-1 2 | p cnf 0 0 3 | -------------------------------------------------------------------------------- /test/parse/embeddedoptiocrnl: -------------------------------------------------------------------------------- 1 | c --oops 2 | p cnf 0 0 3 | -------------------------------------------------------------------------------- /test/parse/eofheadercomment: -------------------------------------------------------------------------------- 1 | c end-of-file in header comment -------------------------------------------------------------------------------- /test/parse/nodigitafterpcnfspace: -------------------------------------------------------------------------------- 1 | c 2 | p cnf nodigit 3 | -------------------------------------------------------------------------------- /test/parse/nonlafterinvalidembeddedoption: -------------------------------------------------------------------------------- 1 | c- p cnf 0 0 2 | -------------------------------------------------------------------------------- /test/parse/tabs: -------------------------------------------------------------------------------- 1 | p cnf 1 1 2 | 3 | 1 0 4 | 5 | -------------------------------------------------------------------------------- /test/cnf/unit5.cnf: -------------------------------------------------------------------------------- 1 | p cnf 2 3 2 | -1 2 0 3 | 1 2 0 4 | -2 0 5 | -------------------------------------------------------------------------------- /test/parse/embeddedcrmissingnl: -------------------------------------------------------------------------------- 1 | c --verbose=1 p cnf 0 0 2 | -------------------------------------------------------------------------------- /test/parse/embeddedoptioneqmissing: -------------------------------------------------------------------------------- 1 | c --oops 2 | p cnf 0 0 3 | -------------------------------------------------------------------------------- /test/parse/invalidembeddedoption: -------------------------------------------------------------------------------- 1 | c --oops=1 2 | p cnf 0 0 3 | -------------------------------------------------------------------------------- /test/parse/onlycomments: -------------------------------------------------------------------------------- 1 | c one line 2 | c and another line 3 | -------------------------------------------------------------------------------- /test/parse/varidxtoolarge1: -------------------------------------------------------------------------------- 1 | p cnf 200000 1 2 | 2684354550 0 3 | -------------------------------------------------------------------------------- /test/parse/varidxtoolarge2: -------------------------------------------------------------------------------- 1 | p cnf 200000 1 2 | 268435456 0 3 | -------------------------------------------------------------------------------- /test/parse/anainsteadoflit: -------------------------------------------------------------------------------- 1 | p cnf 1 1 2 | 3 | a 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /test/parse/nospaceaftervars: -------------------------------------------------------------------------------- 1 | c 2 | c 3 | c 4 | p cnf 1nospace 5 | -------------------------------------------------------------------------------- /test/parse/toolargeclauses1: -------------------------------------------------------------------------------- 1 | p cnf 20000 20000000000000000000 2 | -------------------------------------------------------------------------------- /test/parse/toolargeclauses2: -------------------------------------------------------------------------------- 1 | p cnf 20000 18446744073709551616 2 | -------------------------------------------------------------------------------- /test/cnf/twocores1.cnf: -------------------------------------------------------------------------------- 1 | p cnf 2 4 2 | 1 0 3 | -1 0 4 | 2 0 5 | -2 0 6 | -------------------------------------------------------------------------------- /test/parse/crnlfile: -------------------------------------------------------------------------------- 1 | c 2 | c comment 3 | p cnf 1 1 4 | 1 0 5 | -------------------------------------------------------------------------------- /test/parse/eofincommmentafterliteral: -------------------------------------------------------------------------------- 1 | p cnf 1 1 2 | 1 0comment but no nl -------------------------------------------------------------------------------- /test/parse/headerspaces: -------------------------------------------------------------------------------- 1 | p cnf 1 2 2 | -1 0 3 | 1 0 4 | -------------------------------------------------------------------------------- /test/parse/nodigitaftersign: -------------------------------------------------------------------------------- 1 | p cnf 1 1 2 | 3 | 4 | -nodigit 5 | 6 | -------------------------------------------------------------------------------- /test/parse/nowsafterlit: -------------------------------------------------------------------------------- 1 | p cnf 1 1 2 | 3 | 4 | 1a 5 | 6 | 7 | -------------------------------------------------------------------------------- /test/cnf/full2.cnf: -------------------------------------------------------------------------------- 1 | p cnf 2 4 2 | 1 2 0 3 | 1 -2 0 4 | -1 2 0 5 | -1 -2 0 6 | -------------------------------------------------------------------------------- /test/file/1.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jix/kissat_extras/HEAD/test/file/1.bz2 -------------------------------------------------------------------------------- /test/file/2.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jix/kissat_extras/HEAD/test/file/2.gz -------------------------------------------------------------------------------- /test/file/4.7z: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jix/kissat_extras/HEAD/test/file/4.7z -------------------------------------------------------------------------------- /test/file/5.xz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jix/kissat_extras/HEAD/test/file/5.xz -------------------------------------------------------------------------------- /test/cnf/eq2.cnf: -------------------------------------------------------------------------------- 1 | p cnf 4 5 2 | 4 -2 0 3 | 1 -4 0 4 | 2 4 0 5 | -4 3 0 6 | -3 -1 0 7 | -------------------------------------------------------------------------------- /test/file/3.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jix/kissat_extras/HEAD/test/file/3.lzma -------------------------------------------------------------------------------- /test/big/makefile: -------------------------------------------------------------------------------- 1 | all: 2 | gcc -o genbigand genbigand.c 3 | clean: 4 | rm -f genbigand 5 | -------------------------------------------------------------------------------- /test/cnf/unit4.cnf: -------------------------------------------------------------------------------- 1 | p cnf 7 5 2 | 7 0 3 | -7 -1 0 4 | -7 1 3 0 5 | -7 1 5 0 6 | -7 -3 -5 0 7 | -------------------------------------------------------------------------------- /test/parse/emptyheadercrnl: -------------------------------------------------------------------------------- 1 | c a header comment 2 | 3 | c another one 4 | p cnf 0 0 5 | -------------------------------------------------------------------------------- /test/cnf/tieshirt.cnf: -------------------------------------------------------------------------------- 1 | c tie=1 2 | c shirt=2 3 | p cnf 2 3 4 | 1 2 0 5 | -1 2 0 6 | -1 -2 0 7 | -------------------------------------------------------------------------------- /test/cover/cover0005.cnf: -------------------------------------------------------------------------------- 1 | c status 10 2 | c --probeinit=0 3 | p cnf 2 3 4 | -2 -1 0 5 | -2 1 0 6 | 2 -1 0 7 | -------------------------------------------------------------------------------- /test/cnf/probe1.cnf: -------------------------------------------------------------------------------- 1 | p cnf 6 6 2 | -1 2 0 3 | -2 3 0 4 | -3 4 0 5 | -4 5 0 6 | -5 6 0 7 | -1 -2 -3 -4 -5 -6 0 8 | -------------------------------------------------------------------------------- /test/cover/cover0031.cnf: -------------------------------------------------------------------------------- 1 | c status 10 2 | c --eliminateinit=0 3 | p cnf 5 3 4 | -2 5 4 1 3 0 5 | -4 0 6 | -2 -3 0 7 | -------------------------------------------------------------------------------- /test/cover/cover0033.cnf: -------------------------------------------------------------------------------- 1 | c status 10 2 | c --eliminateinit=0 3 | p cnf 3 4 4 | -2 3 0 5 | 3 -1 0 6 | 3 2 0 7 | 1 3 0 8 | -------------------------------------------------------------------------------- /test/cover/cover0037.cnf: -------------------------------------------------------------------------------- 1 | c status 10 2 | c --probeinit=0 3 | c --vivifymineff=0 4 | p cnf 3 2 5 | 3 1 0 6 | 3 -1 2 0 7 | -------------------------------------------------------------------------------- /test/cover/cover0013.cnf: -------------------------------------------------------------------------------- 1 | c status 10 2 | c --focus=0 3 | c --phase=0 4 | c --reluctant=0 5 | p cnf 2 2 6 | 2 1 0 7 | 2 -1 0 8 | -------------------------------------------------------------------------------- /test/cover/cover0034.cnf: -------------------------------------------------------------------------------- 1 | c status 10 2 | c --eliminateinit=0 3 | c --walkinitially=1 4 | p cnf 5 3 5 | 4 5 1 0 6 | 4 0 7 | 2 3 0 8 | -------------------------------------------------------------------------------- /test/parse/embeddedoptionametoolong: -------------------------------------------------------------------------------- 1 | c --averyveryveryveryveryveryveryveryveryveryveryveryveryverylongoptionname=1 2 | p cnf 0 0 3 | -------------------------------------------------------------------------------- /test/cnf/twocores2.cnf: -------------------------------------------------------------------------------- 1 | p cnf 4 8 2 | 1 2 0 3 | 1 -2 0 4 | -1 2 0 5 | -1 -2 0 6 | 3 4 0 7 | 3 -4 0 8 | -3 4 0 9 | -3 -4 0 10 | -------------------------------------------------------------------------------- /test/cover/cover0027.cnf: -------------------------------------------------------------------------------- 1 | c status 10 2 | c --eliminateinit=0 3 | c --subsumeocclim=0 4 | p cnf 3 3 5 | -1 2 0 6 | 3 -2 0 7 | 1 -3 0 8 | -------------------------------------------------------------------------------- /test/cnf/ph2.cnf: -------------------------------------------------------------------------------- 1 | p cnf 6 9 2 | -1 -3 0 3 | -1 -5 0 4 | -3 -5 0 5 | -2 -4 0 6 | -2 -6 0 7 | -4 -6 0 8 | 2 1 0 9 | 4 3 0 10 | 6 5 0 11 | -------------------------------------------------------------------------------- /test/cover/cover0001.cnf: -------------------------------------------------------------------------------- 1 | c status 10 2 | c --probeinit=0 3 | c --really=0 4 | c --ternarymineff=0 5 | p cnf 4 2 6 | 2 -1 3 0 7 | -2 1 -4 0 8 | -------------------------------------------------------------------------------- /src/sweep.h: -------------------------------------------------------------------------------- 1 | #ifndef _sweep_h_INCLUDED 2 | #define _sweep_h_INCLUDED 3 | 4 | struct kissat; 5 | void kissat_sweep(struct kissat *); 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /test/cnf/full3.cnf: -------------------------------------------------------------------------------- 1 | p cnf 3 8 2 | 1 2 3 0 3 | 1 2 -3 0 4 | 1 -2 3 0 5 | 1 -2 -3 0 6 | -1 2 3 0 7 | -1 2 -3 0 8 | -1 -2 3 0 9 | -1 -2 -3 0 10 | -------------------------------------------------------------------------------- /test/cover/cover0029.cnf: -------------------------------------------------------------------------------- 1 | c status 10 2 | c --probeinit=0 3 | c --really=0 4 | c --ternarymineff=0 5 | p cnf 7 3 6 | 4 1 5 0 7 | -1 6 7 0 8 | 2 3 1 0 9 | -------------------------------------------------------------------------------- /test/cover/cover0003.cnf: -------------------------------------------------------------------------------- 1 | c status 10 2 | c --eliminateinit=0 3 | c --eliminatemineff=0 4 | c --phase=0 5 | p cnf 5 3 6 | 1 2 0 7 | 3 1 0 8 | 4 -1 5 3 0 9 | -------------------------------------------------------------------------------- /test/parse/emptyheaderline: -------------------------------------------------------------------------------- 1 | 2 | c another empty line follows 3 | 4 | c another header comment followed by two empty lines 5 | 6 | 7 | p cnf 0 0 8 | 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | *.o 3 | *.a 4 | makefile 5 | build.h 6 | kissat 7 | tissat 8 | *.gcno 9 | *.gcda 10 | *.gcov 11 | gmon.out 12 | *~ 13 | /.cache 14 | -------------------------------------------------------------------------------- /src/search.h: -------------------------------------------------------------------------------- 1 | #ifndef _search_h_INCLUDED 2 | #define _search_h_INCLUDED 3 | 4 | struct kissat; 5 | 6 | int kissat_search(struct kissat *); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /src/vivify.h: -------------------------------------------------------------------------------- 1 | #ifndef _vivify_h_INCLUDED 2 | #define _vivify_h_INCLUDED 3 | 4 | struct kissat; 5 | 6 | void kissat_vivify(struct kissat *); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /test/cnf/unit6.cnf: -------------------------------------------------------------------------------- 1 | p cnf 10 10 2 | 8 -4 0 3 | 4 5 0 4 | 4 -5 6 0 5 | -9 1 0 6 | -1 2 0 7 | -1 -2 -3 0 8 | -6 3 0 9 | 10 -8 0 10 | 10 9 0 11 | -10 0 12 | -------------------------------------------------------------------------------- /src/shrink.h: -------------------------------------------------------------------------------- 1 | #ifndef _shrink_h_INCLUDED 2 | #define _shrink_h_INCLUDED 3 | 4 | struct kissat; 5 | 6 | void kissat_shrink_clause(struct kissat *); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /src/ternary.h: -------------------------------------------------------------------------------- 1 | #ifndef _ternary_h_INCLUDED 2 | #define _ternary_h_INCLUDED 3 | 4 | struct kissat; 5 | 6 | void kissat_ternary(struct kissat *); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /test/cover/cover0017.cnf: -------------------------------------------------------------------------------- 1 | c status 20 2 | c --probeinit=0 3 | c --substitute=0 4 | p cnf 5 6 5 | -3 5 0 6 | -3 2 0 7 | -4 -1 0 8 | -2 -5 0 9 | 3 1 0 10 | 3 4 0 11 | -------------------------------------------------------------------------------- /test/cover/cover0019.cnf: -------------------------------------------------------------------------------- 1 | c status 20 2 | c --eliminateinit=0 3 | c --forward=0 4 | p cnf 4 6 5 | 1 -2 0 6 | -3 4 0 7 | -3 -2 0 8 | 3 -1 0 9 | 2 3 0 10 | 2 -4 0 11 | -------------------------------------------------------------------------------- /src/autarky.h: -------------------------------------------------------------------------------- 1 | #ifndef _autarky_h_INCLUDED 2 | #define _autarky_h_INCLUDED 3 | 4 | struct kissat; 5 | 6 | void kissat_autarky(struct kissat *, char type); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /src/backbone.h: -------------------------------------------------------------------------------- 1 | #ifndef _backbone_h_INCLUDED 2 | #define _backbone_h_INCLUDED 3 | 4 | struct kissat; 5 | void kissat_binary_clauses_backbone(struct kissat *); 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /test/cover/cover0014.cnf: -------------------------------------------------------------------------------- 1 | c status 10 2 | c --defraglim=0 3 | c --defragsize=0 4 | c --focus=0 5 | c --otfs=0 6 | c --phase=0 7 | p cnf 3 2 8 | 2 -3 1 0 9 | 2 1 3 0 10 | -------------------------------------------------------------------------------- /test/parse/embeddedcoverage: -------------------------------------------------------------------------------- 1 | c --option=nodigit 2 | c --option=21474836470 3 | c --option=2147483648 4 | c --option=0 then spaces and and some chars 5 | p cnf 0 0 6 | -------------------------------------------------------------------------------- /src/failed.h: -------------------------------------------------------------------------------- 1 | #ifndef _failed_h_INCLUDED 2 | #define _failed_h_INCLUDED 3 | 4 | struct kissat; 5 | 6 | void kissat_failed_literal_computation(struct kissat *); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /test/cover/cover0004.cnf: -------------------------------------------------------------------------------- 1 | c status 10 2 | c --focus=0 3 | c --phase=0 4 | c --reluctantint=0 5 | p cnf 7 5 6 | 2 -3 0 7 | 5 -4 0 8 | -7 -5 0 9 | 5 6 4 0 10 | 7 1 -5 0 11 | -------------------------------------------------------------------------------- /src/restore.h: -------------------------------------------------------------------------------- 1 | #ifndef _restore_h_INCLUDED 2 | #define _restore_h_INCLUDED 3 | 4 | typedef struct kissat kissat; 5 | 6 | void kissat_restore_clauses(kissat *solver); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /src/transitive.h: -------------------------------------------------------------------------------- 1 | #ifndef _transitive_h_INCLUDED 2 | #define _transitive_h_INCLUDED 3 | 4 | struct kissat; 5 | 6 | void kissat_transitive_reduction(struct kissat *); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /test/cnf/and1.cnf: -------------------------------------------------------------------------------- 1 | p cnf 5 11 2 | -1 2 0 3 | -1 3 0 4 | 1 -2 -3 0 5 | 2 4 -5 0 6 | 2 -4 5 0 7 | -2 -4 -5 0 8 | -2 4 5 0 9 | 3 4 -5 0 10 | 3 -4 5 0 11 | -3 -4 -5 0 12 | -3 4 5 0 13 | -------------------------------------------------------------------------------- /test/cover/cover0038.cnf: -------------------------------------------------------------------------------- 1 | c status 20 2 | c --eliminateinit=0 3 | c --subsumeclslim=0 4 | p cnf 6 7 5 | 5 -3 0 6 | -6 3 0 7 | -4 6 3 0 8 | 4 0 9 | 2 -1 0 10 | -2 -5 0 11 | 1 2 0 12 | -------------------------------------------------------------------------------- /test/parse/comments: -------------------------------------------------------------------------------- 1 | c this is a comment 2 | p cnf 2 2 3 | c comment here? 4 | 1 c first comment 5 | c another one 6 | 0c end of clause 7 | 2 comment 8 | 0 9 | comment 10 | -------------------------------------------------------------------------------- /src/endianness.h: -------------------------------------------------------------------------------- 1 | #ifndef _endianness_h_INCLUDED 2 | #define _endianness_h_INCLUDED 3 | 4 | #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 5 | #define KISSAT_IS_BIG_ENDIAN 6 | #endif 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /test/cnf/and2.cnf: -------------------------------------------------------------------------------- 1 | p cnf 5 11 2 | -1 2 0 3 | -1 3 0 4 | 1 -2 -3 0 5 | 2 4 -5 1 0 6 | 2 -4 5 0 7 | -2 -4 -5 0 8 | -2 4 5 0 9 | 3 4 -5 0 10 | 3 -4 5 -1 0 11 | -3 -4 -5 0 12 | -3 4 5 0 13 | -------------------------------------------------------------------------------- /test/cover/cover0006.cnf: -------------------------------------------------------------------------------- 1 | c status 10 2 | c --focus=0 3 | c --phase=0 4 | c --reduceinit=0 5 | p cnf 7 7 6 | 4 6 0 7 | 1 5 0 8 | 4 -1 -3 0 9 | -2 -5 0 10 | 1 2 0 11 | 5 -3 0 12 | 7 3 0 13 | -------------------------------------------------------------------------------- /src/application.h: -------------------------------------------------------------------------------- 1 | #ifndef _application_h_INCLUDED 2 | #define _application_h_INCLUDED 3 | 4 | struct kissat; 5 | 6 | int kissat_application(struct kissat *, int argc, char **argv); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /test/cover/cover0009.cnf: -------------------------------------------------------------------------------- 1 | c status 20 2 | c --probeinit=0 3 | p cnf 8 10 4 | 5 3 0 5 | 2 -1 4 0 6 | -2 0 7 | -5 6 -4 0 8 | 7 6 0 9 | 1 -7 0 10 | 3 8 0 11 | -6 -3 0 12 | -6 -8 0 13 | -3 -1 0 14 | -------------------------------------------------------------------------------- /test/cover/cover0007.cnf: -------------------------------------------------------------------------------- 1 | c status 20 2 | c --probeinit=0 3 | c --tumble=0 4 | p cnf 7 9 5 | 4 1 0 6 | -1 -2 0 7 | -5 3 0 8 | 6 2 -3 0 9 | 5 0 10 | -4 7 0 11 | -6 7 0 12 | -7 -4 0 13 | -7 2 0 14 | -------------------------------------------------------------------------------- /test/cover/cover0026.cnf: -------------------------------------------------------------------------------- 1 | c status 10 2 | c --eliminateclslim=3 3 | c --eliminateinit=0 4 | c --forward=0 5 | p cnf 6 6 6 | 5 -2 6 3 1 0 7 | -4 -1 0 8 | -3 -1 0 9 | -6 0 10 | -5 4 2 0 11 | 4 -2 0 12 | -------------------------------------------------------------------------------- /test/cover/cover0044.cnf: -------------------------------------------------------------------------------- 1 | c status 20 2 | c --probeinit=0 3 | c --vivify=0 4 | c --failed=0 5 | c --substitute=0 6 | c --backbone=0 7 | p cnf 2 4 8 | 1 2 0 9 | 1 -2 0 10 | -1 2 0 11 | -1 -2 0 12 | -------------------------------------------------------------------------------- /src/substitute.h: -------------------------------------------------------------------------------- 1 | #ifndef _substitute_h_INCLUDED 2 | #define _substitute_h_INCLUDED 3 | 4 | #include 5 | 6 | struct kissat; 7 | 8 | void kissat_substitute(struct kissat *); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /test/makefile: -------------------------------------------------------------------------------- 1 | test: 2 | +$(MAKE) -C .. test 3 | clean: 4 | $(MAKE) -C .. clean 5 | indent: 6 | $(MAKE) -C .. indent 7 | coverage: 8 | $(MAKE) -C .. coverage 9 | .PHONY: all clean coverage indent test 10 | -------------------------------------------------------------------------------- /src/propsearch.h: -------------------------------------------------------------------------------- 1 | #ifndef _propsearch_h_INCLUDED 2 | #define _propsearch_h_INCLUDED 3 | 4 | struct kissat; 5 | struct clause; 6 | 7 | struct clause *kissat_search_propagate(struct kissat *); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /test/cnf/diamond1.cnf: -------------------------------------------------------------------------------- 1 | p cnf 9 13 2 | -1 2 0 3 | -1 3 0 4 | -2 -3 4 0 5 | -4 5 0 6 | -4 6 0 7 | -5 -6 7 0 8 | -7 1 0 9 | 1 4 7 8 0 10 | -1 -4 -7 -8 0 11 | 1 4 7 9 0 12 | -1 -4 -7 -9 0 13 | 8 9 0 14 | -8 -9 0 15 | -------------------------------------------------------------------------------- /test/cnf/xor2.cnf: -------------------------------------------------------------------------------- 1 | c --eliminateinit=0 2 | c --eliminateinit = 0 3 | p cnf 4 8 4 | 1 2 3 4 0 5 | 1 2 -3 -4 0 6 | 1 -2 3 -4 0 7 | -1 2 3 -4 0 8 | 1 -2 -3 4 0 9 | -1 2 -3 4 0 10 | -1 -2 3 4 0 11 | -1 -2 -3 -4 0 12 | -------------------------------------------------------------------------------- /test/cover/cover0030.cnf: -------------------------------------------------------------------------------- 1 | c status 20 2 | c --eliminateinit=0 3 | p cnf 10 11 4 | 7 6 0 5 | -6 -10 -9 0 6 | -7 1 0 7 | 2 -3 0 8 | -2 9 0 9 | 4 5 0 10 | 10 0 11 | 3 -4 0 12 | -6 -5 0 13 | -8 -1 0 14 | -1 8 0 15 | -------------------------------------------------------------------------------- /test/cover/cover0032.cnf: -------------------------------------------------------------------------------- 1 | c status 10 2 | c --eliminateinit=0 3 | c --eliminateocclim=1 4 | p cnf 8 9 5 | 8 5 0 6 | 8 4 3 0 7 | 2 7 0 8 | 1 -4 0 9 | -6 -7 0 10 | 7 -8 0 11 | 3 4 6 0 12 | -3 -2 -5 0 13 | -1 5 0 14 | -------------------------------------------------------------------------------- /src/bump.h: -------------------------------------------------------------------------------- 1 | #ifndef _bump_h_INCLUDED 2 | #define _bump_h_INCLUDED 3 | 4 | #include 5 | 6 | struct kissat; 7 | 8 | void kissat_bump(struct kissat *); 9 | 10 | #define MAX_SCORE 1e150 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /test/cnf/ite1.cnf: -------------------------------------------------------------------------------- 1 | p cnf 6 12 2 | 1 -2 -3 0 3 | -1 -2 3 0 4 | 1 2 -4 0 5 | -1 2 4 0 6 | 3 5 -6 1 0 7 | 3 -5 6 2 0 8 | -3 -5 -6 2 0 9 | -3 5 6 2 0 10 | 4 5 -6 -1 0 11 | 4 -5 6 -2 0 12 | -4 -5 -6 -2 0 13 | -4 5 6 -2 0 14 | -------------------------------------------------------------------------------- /src/ands.h: -------------------------------------------------------------------------------- 1 | #ifndef _ands_h_INCLUDED 2 | #define _ands_h_INCLUDED 3 | 4 | #include 5 | 6 | struct kissat; 7 | 8 | bool kissat_find_and_gate(struct kissat *, unsigned lit, unsigned negative); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /src/definition.h: -------------------------------------------------------------------------------- 1 | #ifndef _definition_h_INCLUDED 2 | #define _definition_h_INCLUDED 3 | 4 | #include 5 | 6 | struct kissat; 7 | 8 | bool kissat_find_definition(struct kissat *, unsigned lit); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /src/dominate.h: -------------------------------------------------------------------------------- 1 | #ifndef _dominate_h_INCLUDED 2 | #define _dominate_h_INCLUDED 3 | 4 | struct kissat; 5 | struct clause; 6 | 7 | unsigned kissat_find_dominator(struct kissat *, unsigned, struct clause *); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/equivalences.h: -------------------------------------------------------------------------------- 1 | #ifndef _equivs_h_INCLUDED 2 | #define _equivs_h_INCLUDED 3 | 4 | #include 5 | 6 | struct kissat; 7 | 8 | bool kissat_find_equivalence_gate(struct kissat *, unsigned lit); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /src/witness.h: -------------------------------------------------------------------------------- 1 | #ifndef _witness_h_INCLUDED 2 | #define _witness_h_INCLUDED 3 | 4 | #include 5 | 6 | struct kissat; 7 | 8 | void kissat_print_witness(struct kissat *, int max_var, bool partial); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /src/xors.h: -------------------------------------------------------------------------------- 1 | #ifndef _xors_h_INCLUDED 2 | #define _xors_h_INCLUDED 3 | 4 | #include 5 | 6 | struct kissat; 7 | 8 | bool kissat_find_xor_gate(struct kissat *, unsigned lit, unsigned negative); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /test/cnf/xor1.cnf: -------------------------------------------------------------------------------- 1 | c --eliminateinit=0 2 | p cnf 5 12 3 | 1 2 3 0 4 | 1 -2 -3 0 5 | -1 -2 3 0 6 | -1 2 -3 0 7 | 2 4 -5 -1 0 8 | 2 -4 5 0 9 | -2 -4 -5 0 10 | -2 4 5 0 11 | 3 4 -5 0 12 | 3 -4 5 0 13 | -3 -4 -5 0 14 | -3 4 5 1 0 15 | -------------------------------------------------------------------------------- /src/probe.h: -------------------------------------------------------------------------------- 1 | #ifndef _probe_h_INCLUDED 2 | #define _probe_h_INCLUDED 3 | 4 | #include 5 | 6 | struct kissat; 7 | 8 | bool kissat_probing(struct kissat *); 9 | int kissat_probe(struct kissat *); 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /src/deduce.h: -------------------------------------------------------------------------------- 1 | #ifndef _deduce_h_INCLUDED 2 | #define _deduce_h_INCLUDED 3 | 4 | struct clause; 5 | struct kissat; 6 | 7 | struct clause *kissat_deduce_first_uip_clause(struct kissat *, 8 | struct clause *); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /src/propdense.h: -------------------------------------------------------------------------------- 1 | #ifndef _propdense_h_INCLUDED 2 | #define _propdense_h_INCLUDED 3 | 4 | #include 5 | #include 6 | 7 | struct kissat; 8 | 9 | bool kissat_dense_propagate(struct kissat *); 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /src/reduce.h: -------------------------------------------------------------------------------- 1 | #ifndef _reduce_h_INCLUDED 2 | #define _reduce_h_INCLUDED 3 | 4 | #include 5 | 6 | struct kissat; 7 | 8 | bool kissat_reducing(struct kissat *); 9 | int kissat_reduce(struct kissat *); 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /src/learn.h: -------------------------------------------------------------------------------- 1 | #ifndef _learn_h_INCLUDED 2 | #define _learn_h_INCLUDED 3 | 4 | struct kissat; 5 | 6 | void kissat_learn_clause(struct kissat *); 7 | void kissat_update_learned(struct kissat *, unsigned glue, unsigned size); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/prophyper.h: -------------------------------------------------------------------------------- 1 | #ifndef _prophyper_h_INCLUDED 2 | #define _prophyper_h_INCLUDED 3 | 4 | struct kissat; 5 | struct clause; 6 | 7 | struct clause *kissat_hyper_propagate(struct kissat *, 8 | const struct clause *); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /test/cnf/diamond2.cnf: -------------------------------------------------------------------------------- 1 | p cnf 11 15 2 | -1 10 0 3 | -1 11 0 4 | -10 2 0 5 | -11 3 0 6 | -2 -3 4 0 7 | -4 5 0 8 | -4 6 0 9 | -5 -6 7 0 10 | -7 1 0 11 | 1 4 7 8 0 12 | -1 -4 -7 -8 0 13 | 1 4 7 9 0 14 | -1 -4 -7 -9 0 15 | 8 9 0 16 | -8 -9 0 17 | -------------------------------------------------------------------------------- /test/cover/cover0028.cnf: -------------------------------------------------------------------------------- 1 | c status 10 2 | c --eliminateinit=0 3 | c --forward=0 4 | p cnf 10 12 5 | 1 8 0 6 | -1 5 0 7 | 5 3 -4 0 8 | 1 10 2 0 9 | 4 8 0 10 | -9 -7 0 11 | 4 3 0 12 | 1 6 0 13 | 9 -5 4 0 14 | 4 -3 0 15 | 7 -8 0 16 | -3 -7 0 17 | -------------------------------------------------------------------------------- /test/cover/cover0021.cnf: -------------------------------------------------------------------------------- 1 | c status 10 2 | c --eliminateinit=0 3 | c --subsumeclslim=0 4 | c --tumble=0 5 | p cnf 18 9 6 | -7 -3 0 7 | 7 6 -14 0 8 | -6 9 2 0 9 | -8 11 1 0 10 | 12 18 -3 0 11 | -15 -10 0 12 | -3 -16 0 13 | -13 -17 14 0 14 | 5 4 16 0 15 | -------------------------------------------------------------------------------- /test/cover/cover0041.cnf: -------------------------------------------------------------------------------- 1 | c status 10 2 | c --eliminateclslim=0 3 | c --eliminateinit=0 4 | c --subsumeclslim=0 5 | p cnf 11 10 6 | 2 8 5 0 7 | -2 10 0 8 | 5 10 0 9 | 7 1 -4 0 10 | 6 7 8 0 11 | -1 0 12 | 11 3 0 13 | 4 -11 0 14 | -3 -9 0 15 | -3 9 0 16 | -------------------------------------------------------------------------------- /src/attribute.h: -------------------------------------------------------------------------------- 1 | #ifndef _attribute_h_INCLUDED 2 | #define _attribute_h_INCLUDED 3 | 4 | #define ATTRIBUTE_FORMAT(FORMAT_POSITION,VARIADIC_ARGUMENT_POSITION) \ 5 | __attribute__ ((format (printf, FORMAT_POSITION, VARIADIC_ARGUMENT_POSITION))) 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /.clangd: -------------------------------------------------------------------------------- 1 | # No unused function warnings for header files 2 | If: 3 | PathMatch: .*\.h 4 | CompileFlags: 5 | Add: [-Wno-unused-function] 6 | --- 7 | # Not a stand-alone header file 8 | If: 9 | PathMatch: .*proplit\.h 10 | Diagnostics: 11 | Suppress: '*' 12 | -------------------------------------------------------------------------------- /src/ifthenelse.h: -------------------------------------------------------------------------------- 1 | #ifndef _ifthenelse_h_INCLUDED 2 | #define _ifthenelse_h_INCLUDED 3 | 4 | #include 5 | 6 | struct kissat; 7 | 8 | bool kissat_find_if_then_else_gate(struct kissat *, 9 | unsigned lit, unsigned negative); 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /test/cnf/twocores3.cnf: -------------------------------------------------------------------------------- 1 | p cnf 6 16 2 | 1 2 3 0 3 | 1 2 -3 0 4 | 1 -2 3 0 5 | 1 -2 -3 0 6 | -1 2 3 0 7 | -1 2 -3 0 8 | -1 -2 3 0 9 | -1 -2 -3 0 10 | 4 5 6 0 11 | 4 5 -6 0 12 | 4 -5 6 0 13 | 4 -5 -6 0 14 | -4 5 6 0 15 | -4 5 -6 0 16 | -4 -5 6 0 17 | -4 -5 -6 0 18 | -------------------------------------------------------------------------------- /src/import.h: -------------------------------------------------------------------------------- 1 | #ifndef _import_h_INLCUDED 2 | #define _import_h_INLCUDED 3 | 4 | struct kissat; 5 | 6 | unsigned kissat_import_literal(struct kissat *solver, int lit); 7 | 8 | int kissat_external_representative(struct kissat *solver, int elit); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /src/resolve.h: -------------------------------------------------------------------------------- 1 | #ifndef _resolve_h_INCLUDED 2 | #define _resolve_h_INCLUDED 3 | 4 | #include 5 | 6 | typedef struct kissat kissat; 7 | 8 | bool kissat_generate_resolvents(struct kissat *, 9 | unsigned idx, unsigned *lit_ptr); 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /test/cover/cover0010.cnf: -------------------------------------------------------------------------------- 1 | c status 20 2 | c --probeinit=0 3 | p cnf 14 15 4 | -7 -2 8 6 0 5 | -5 4 0 6 | 8 -10 0 7 | 13 7 0 8 | -11 9 0 9 | -8 -9 12 0 10 | -6 10 0 11 | -13 8 0 12 | 14 -1 0 13 | 5 1 0 14 | 5 -14 0 15 | -12 -3 0 16 | 2 -4 0 17 | -5 11 0 18 | 3 -4 0 19 | -------------------------------------------------------------------------------- /src/backward.h: -------------------------------------------------------------------------------- 1 | #ifndef _backward_h_INCLUDED 2 | #define _backward_h_INCLUDED 3 | 4 | #include "reference.h" 5 | 6 | #include 7 | 8 | struct kissat; 9 | 10 | bool kissat_backward_subsume_temporary(struct kissat *, reference ignore); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /src/nonces.h: -------------------------------------------------------------------------------- 1 | #ifndef _nonces_h_INCLUDED 2 | #define _nonces_h_INCLUDED 3 | 4 | #include "stack.h" 5 | 6 | #include 7 | 8 | typedef STACK(uint64_t) 9 | nonces; 10 | 11 | struct kissat; 12 | 13 | void kissat_init_nonces(struct kissat *); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /test/cover/cover0045.cnf: -------------------------------------------------------------------------------- 1 | c status 20 2 | c --probeinit=0 3 | c --vivify=0 4 | c --failed=0 5 | c --substitute=0 6 | c --backbone=0 7 | c --transitive=0 8 | p cnf 4 8 9 | -1 2 0 10 | -1 3 0 11 | -2 -3 1 0 12 | -4 2 0 13 | -4 3 0 14 | -2 -3 4 0 15 | 1 4 0 16 | -1 -4 0 17 | -------------------------------------------------------------------------------- /src/proprobe.h: -------------------------------------------------------------------------------- 1 | #ifndef _proprobe_h_INCLUDED 2 | #define _proprobe_h_INCLUDED 3 | 4 | #include 5 | 6 | struct kissat; 7 | struct clause; 8 | 9 | struct clause *kissat_probing_propagate(struct kissat *, 10 | struct clause *, bool flush); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /src/walk.h: -------------------------------------------------------------------------------- 1 | #ifndef _walk_h_INCLUDED 2 | #define _walk_h_INCLUDED 3 | 4 | #include 5 | 6 | struct kissat; 7 | 8 | bool kissat_walking(struct kissat *); 9 | void kissat_walk(struct kissat *); 10 | int kissat_walk_initially(struct kissat *); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /src/forward.h: -------------------------------------------------------------------------------- 1 | #ifndef _forward_h_INCLUDED 2 | #define _forward_h_INCLUDED 3 | 4 | #include 5 | 6 | struct kissat; 7 | 8 | bool kissat_forward_subsume_temporary(struct kissat *); 9 | bool kissat_forward_subsume_during_elimination(struct kissat *); 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /src/add.h: -------------------------------------------------------------------------------- 1 | #ifndef _add_h_INCLUDED 2 | #define _add_h_INCLUDED 3 | 4 | #include 5 | 6 | typedef struct kissat kissat; 7 | 8 | bool kissat_add_external_literal(kissat *solver, int elit); 9 | void kissat_finish_external_clause(kissat *solver, bool restored); 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /src/compact.h: -------------------------------------------------------------------------------- 1 | #ifndef _compact_h_INCLUDED 2 | #define _compact_h_INCLUDED 3 | 4 | struct kissat; 5 | 6 | unsigned kissat_compact_literals(struct kissat *, unsigned *mfixed_ptr); 7 | void kissat_finalize_compacting(struct kissat *, 8 | unsigned vars, unsigned mfixed); 9 | #endif 10 | -------------------------------------------------------------------------------- /test/cnf/diamond3.cnf: -------------------------------------------------------------------------------- 1 | p cnf 10 20 2 | -5 1 0 3 | -5 2 0 4 | -1 -2 5 0 5 | -6 3 0 6 | -6 4 0 7 | -3 -4 6 0 8 | -7 5 0 9 | -7 6 0 10 | -5 -6 7 0 11 | -8 1 0 12 | -8 2 0 13 | -1 -2 8 0 14 | -9 3 0 15 | -9 4 0 16 | -3 -4 9 0 17 | -10 8 0 18 | -10 9 0 19 | -8 -9 10 0 20 | 7 10 0 21 | -7 -10 0 22 | -------------------------------------------------------------------------------- /src/analyze.h: -------------------------------------------------------------------------------- 1 | #ifndef _analyze_h_INCLUDED 2 | #define _analyze_h_INCLUDED 3 | 4 | #include 5 | 6 | struct clause; 7 | struct kissat; 8 | 9 | int kissat_analyze(struct kissat *, struct clause *); 10 | void kissat_reset_only_analyzed_literals(struct kissat *); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /test/cnf/full4.cnf: -------------------------------------------------------------------------------- 1 | p cnf 4 16 2 | 1 2 3 4 0 3 | 1 2 3 -4 0 4 | 1 2 -3 4 0 5 | 1 2 -3 -4 0 6 | 1 -2 3 4 0 7 | 1 -2 3 -4 0 8 | 1 -2 -3 4 0 9 | 1 -2 -3 -4 0 10 | -1 2 3 4 0 11 | -1 2 3 -4 0 12 | -1 2 -3 4 0 13 | -1 2 -3 -4 0 14 | -1 -2 3 4 0 15 | -1 -2 3 -4 0 16 | -1 -2 -3 4 0 17 | -1 -2 -3 -4 0 18 | -------------------------------------------------------------------------------- /src/restart.h: -------------------------------------------------------------------------------- 1 | #ifndef _restart_h_INCLUDED 2 | #define _restart_h_INCLUDED 3 | 4 | #include 5 | 6 | struct kissat; 7 | 8 | bool kissat_restarting(struct kissat *); 9 | void kissat_restart(struct kissat *); 10 | void kissat_new_focused_restart_limit(struct kissat *); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /src/resize.h: -------------------------------------------------------------------------------- 1 | #ifndef _resize_h_INCLUDED 2 | #define _resize_h_INCLUDED 3 | 4 | struct kissat; 5 | 6 | void kissat_decrease_size(struct kissat *solver); 7 | void kissat_increase_size(struct kissat *, unsigned new_size); 8 | void kissat_enlarge_variables(struct kissat *, unsigned new_vars); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /test/testdivert.h: -------------------------------------------------------------------------------- 1 | #ifndef _testdivert_h_INCLUDED 2 | #define _testdivert_h_INCLUDED 3 | 4 | void tissat_divert_stdout_and_stderr_to_dev_null(void); 5 | void tissat_restore_stdout_and_stderr(void); 6 | 7 | void tissat_restore_stderr(void); 8 | void tissat_redirect_stderr_to_stdout(void); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /src/config.h: -------------------------------------------------------------------------------- 1 | #ifndef NOPTIONS 2 | #ifndef _config_h_INCLUDED 3 | #define _config_h_INCLUDED 4 | 5 | #define CONFIGURATIONS \ 6 | CONFIGURATION (default) \ 7 | CONFIGURATION (sat) \ 8 | CONFIGURATION (unsat) \ 9 | 10 | struct kissat; 11 | 12 | void kissat_configuration_usage(void); 13 | 14 | #endif 15 | #endif 16 | -------------------------------------------------------------------------------- /test/cnf/ph3.cnf: -------------------------------------------------------------------------------- 1 | p cnf 12 22 2 | -1 -4 0 3 | -1 -7 0 4 | -1 -10 0 5 | -4 -7 0 6 | -4 -10 0 7 | -7 -10 0 8 | -2 -5 0 9 | -2 -8 0 10 | -2 -11 0 11 | -5 -8 0 12 | -5 -11 0 13 | -8 -11 0 14 | -3 -6 0 15 | -3 -9 0 16 | -3 -12 0 17 | -6 -9 0 18 | -6 -12 0 19 | -9 -12 0 20 | 3 2 1 0 21 | 6 5 4 0 22 | 9 8 7 0 23 | 12 11 10 0 24 | -------------------------------------------------------------------------------- /src/minimize.h: -------------------------------------------------------------------------------- 1 | #ifndef _minimize_h_INCLUDED 2 | #define _minimize_h_INCLUDED 3 | 4 | #include 5 | 6 | struct kissat; 7 | 8 | void kissat_reset_poisoned(struct kissat *); 9 | 10 | void kissat_minimize_clause(struct kissat *); 11 | bool kissat_minimize_literal(struct kissat *, unsigned, bool lit_in_clause); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /scripts/determine-coverage.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | cd `dirname $0`/.. || exit 1 3 | if [ $# -gt 0 ] 4 | then 5 | options="$*" 6 | else 7 | options="-O0" 8 | fi 9 | if [ -f makefile ] 10 | then 11 | make clean 1>&2 || exit 1 12 | fi 13 | ./configure --coverage --test $options 1>&2 || exit 1 14 | make test 1>&2 || exit 1 15 | exec make -s coverage 16 | -------------------------------------------------------------------------------- /src/decide.h: -------------------------------------------------------------------------------- 1 | #ifndef _decide_h_INCLUDED 2 | #define _decide_h_INCLUDED 3 | 4 | struct kissat; 5 | 6 | void kissat_decide(struct kissat *); 7 | void kissat_internal_assume(struct kissat *, unsigned lit); 8 | unsigned kissat_next_decision_variable(struct kissat *); 9 | 10 | #define INITIAL_PHASE (GET_OPTION (phase) ? 1 : -1) 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /src/weaken.h: -------------------------------------------------------------------------------- 1 | #ifndef _weaken_h_INCLUDED 2 | #define _weaken_h_INCLUDED 3 | 4 | struct clause; 5 | struct kissat; 6 | 7 | void kissat_weaken_unit(struct kissat *, unsigned lit); 8 | void kissat_weaken_binary(struct kissat *, unsigned lit, unsigned other); 9 | void kissat_weaken_clause(struct kissat *, unsigned lit, struct clause *); 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /test/cover/cover0024.cnf: -------------------------------------------------------------------------------- 1 | c status 10 2 | c --incremental=1 3 | c --otfs=0 4 | c --rephaseinit=0 5 | p cnf 13 18 6 | 2 -3 7 0 7 | 6 4 8 0 8 | -8 6 -5 0 9 | -6 -4 7 0 10 | -5 -2 8 0 11 | 9 6 0 12 | 3 -4 0 13 | 4 8 -1 0 14 | -7 4 5 0 15 | 8 -7 0 16 | -6 -8 0 17 | 7 -8 5 0 18 | -4 5 -9 0 19 | 10 -13 0 20 | -10 7 0 21 | -4 -11 5 0 22 | 4 -13 0 23 | -12 1 0 24 | -------------------------------------------------------------------------------- /src/value.h: -------------------------------------------------------------------------------- 1 | #ifndef _value_h_INCLUDED 2 | #define _value_h_INCLUDED 3 | 4 | typedef signed char value; 5 | typedef signed char mark; 6 | 7 | #define VALUE(LIT) \ 8 | (solver->values[assert ((LIT) < LITS), (LIT)]) 9 | 10 | #define MARK(LIT) \ 11 | (solver->marks[assert ((LIT) < LITS), (LIT)]) 12 | 13 | #define BOOL_TO_VALUE(B) ((signed char)((B) ? -1 : 1)) 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /src/dense.h: -------------------------------------------------------------------------------- 1 | #ifndef _dense_h_INCLUDED 2 | #define _dense_h_INCLUDED 3 | 4 | #include "watch.h" 5 | 6 | void kissat_enter_dense_mode(struct kissat *, 7 | litpairs *saved_irredundant_binary_clauses, 8 | litwatches *saved_redundant_binary_clauses); 9 | 10 | void kissat_resume_sparse_mode(struct kissat *, bool flush_eliminated, 11 | litpairs *, litwatches *); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /src/reference.h: -------------------------------------------------------------------------------- 1 | #ifndef _reference_h_INCLUDED 2 | #define _reference_h_INCLUDED 3 | 4 | #include "stack.h" 5 | 6 | typedef unsigned reference; 7 | 8 | #define REFERENCE_FORMAT "u" 9 | 10 | #define LD_MAX_REF 31u 11 | #define MAX_REF ((1u << LD_MAX_REF)-1) 12 | 13 | #define INVALID_REF UINT_MAX 14 | 15 | // *INDENT-OFF* 16 | typedef STACK (reference) references; 17 | // *INDENT-ON* 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /src/report.h: -------------------------------------------------------------------------------- 1 | #ifndef _report_h_INCLUDED 2 | #define _report_h_INCLUDED 3 | 4 | #include 5 | 6 | #ifdef QUIET 7 | 8 | #define REPORT(...) do { } while (0) 9 | 10 | #else 11 | 12 | struct kissat; 13 | 14 | void kissat_report(struct kissat *, bool verbose, char type); 15 | 16 | #define REPORT(LEVEL,TYPE) \ 17 | kissat_report (solver, (LEVEL), (TYPE)) 18 | 19 | #endif 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /test/cover/cover0016.cnf: -------------------------------------------------------------------------------- 1 | c status 10 2 | c --probeinit=0 3 | p cnf 34 25 4 | 10 5 0 5 | 3 -1 9 0 6 | -6 7 0 7 | 3 10 1 0 8 | -1 3 4 0 9 | 1 -6 0 10 | -11 -2 0 11 | 8 10 0 12 | -9 4 3 0 13 | -4 9 0 14 | 4 -10 9 0 15 | -26 14 0 16 | -30 -31 0 17 | 16 -17 0 18 | 30 -16 0 19 | -29 13 0 20 | 27 23 0 21 | -21 -25 0 22 | 31 -18 0 23 | -24 -33 0 24 | 19 22 0 25 | 26 15 0 26 | -20 -16 0 27 | -28 34 0 28 | -12 32 0 29 | -------------------------------------------------------------------------------- /test/cnf/xor3.cnf: -------------------------------------------------------------------------------- 1 | c --eliminateinit=0 2 | c --forward=0 3 | 4 | p cnf 5 16 5 | 6 | -1 2 3 4 5 0 7 | 1 -2 3 4 5 0 8 | 1 2 -3 4 5 0 9 | 1 2 3 -4 5 0 10 | 1 2 3 4 -5 0 11 | 12 | -1 -2 -3 4 5 0 13 | -1 -2 3 -4 5 0 14 | -1 -2 3 4 -5 0 15 | -1 2 -3 -4 5 0 16 | -1 2 -3 4 -5 0 17 | -1 2 3 -4 -5 0 18 | 19 | 1 -2 -3 -4 5 0 20 | 1 -2 -3 4 -5 0 21 | 1 -2 3 -4 -5 0 22 | 23 | 1 2 -3 -4 -5 0 24 | 25 | -1 -2 -3 -4 -5 0 26 | -------------------------------------------------------------------------------- /src/backtrack.h: -------------------------------------------------------------------------------- 1 | #ifndef _backtrack_h_INCLUDED 2 | #define _backtrack_h_INCLUDED 3 | 4 | struct kissat; 5 | 6 | void kissat_backtrack_without_updating_phases(struct kissat *, unsigned); 7 | void kissat_backtrack_in_consistent_state(struct kissat *, unsigned); 8 | void kissat_backtrack_after_conflict(struct kissat *, unsigned); 9 | void kissat_backtrack_propagate_and_flush_trail(struct kissat *); 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /src/terminate.c: -------------------------------------------------------------------------------- 1 | #include "print.h" 2 | #include "terminate.h" 3 | 4 | #ifndef QUIET 5 | 6 | void kissat_report_termination(kissat *solver, const char *name, 7 | const char *file, long lineno, const char *fun) { 8 | kissat_very_verbose(solver, "%s:%ld: %s: 'TERMINATED (%s)' triggered", 9 | file, lineno, fun, name); 10 | } 11 | 12 | #else 13 | int kissat_terminate_dummy_to_avoid_warning; 14 | #endif 15 | -------------------------------------------------------------------------------- /src/utilities.c: -------------------------------------------------------------------------------- 1 | #include "utilities.h" 2 | 3 | #include 4 | 5 | bool kissat_has_suffix(const char *str, const char *suffix) { 6 | const char *p = str; 7 | while (*p) { 8 | p++; 9 | } 10 | const char *q = suffix; 11 | while (*q) { 12 | q++; 13 | } 14 | while (p > str && q > suffix) 15 | if (*--p != *--q) { 16 | return false; 17 | } 18 | return q == suffix; 19 | } 20 | -------------------------------------------------------------------------------- /src/protect.h: -------------------------------------------------------------------------------- 1 | #ifndef _protect_h_INCLUDED 2 | #define _protect_h_INCLUDED 3 | 4 | #define PROTECT(IDX) (solver->protect[assert((IDX) < VARS), IDX]) 5 | 6 | typedef struct kissat kissat; 7 | 8 | void kissat_protect_variable(kissat *solver, unsigned idx); 9 | void kissat_unprotect_variable(kissat *solver, unsigned idx); 10 | void kissat_move_protection(kissat *solver, unsigned from_idx, unsigned to_idx); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /src/parse.h: -------------------------------------------------------------------------------- 1 | #ifndef _parse_h_INCLUDED 2 | #define _parse_h_INCLUDED 3 | 4 | #include "file.h" 5 | 6 | enum strictness { 7 | RELAXED_PARSING = 0, 8 | NORMAL_PARSING = 1, 9 | PEDANTIC_PARSING = 2, 10 | }; 11 | 12 | typedef enum strictness strictness; 13 | 14 | struct kissat; 15 | 16 | const char *kissat_parse_dimacs(struct kissat *, strictness, file *, 17 | uint64_t *linenoptr, int *max_var_ptr); 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /test/cover/cover0040.cnf: -------------------------------------------------------------------------------- 1 | c status 20 2 | c --eliminateinit=1 3 | c --eliminateocclim=0 4 | c --phase=0 5 | p cnf 21 25 6 | 8 -9 0 7 | -7 -8 0 8 | 2 -1 0 9 | 7 -6 1 0 10 | -2 -3 0 11 | -4 6 0 12 | -12 5 0 13 | 6 -12 0 14 | 10 8 2 0 15 | 12 11 0 16 | 3 1 0 17 | 4 7 0 18 | 7 3 0 19 | 20 -14 0 20 | 15 16 0 21 | -18 -11 0 22 | -10 13 0 23 | -1 -5 9 0 24 | -1 -17 0 25 | 16 -15 0 26 | 19 3 0 27 | 18 -20 0 28 | -13 9 0 29 | -16 17 0 30 | 14 21 0 31 | -------------------------------------------------------------------------------- /src/bits.c: -------------------------------------------------------------------------------- 1 | #include "allocate.h" 2 | #include "bits.h" 3 | #include "internal.h" 4 | 5 | bits *kissat_new_bits(kissat *solver, size_t size) { 6 | const unsigned words = kissat_bits_size_in_words(size); 7 | bits *res; 8 | CALLOC(res, words); 9 | return res; 10 | } 11 | 12 | void kissat_delete_bits(kissat *solver, bits *bits, size_t size) { 13 | const unsigned words = kissat_bits_size_in_words(size); 14 | DEALLOC(bits, words); 15 | } 16 | -------------------------------------------------------------------------------- /src/error.h: -------------------------------------------------------------------------------- 1 | #ifndef _error_h_INCLUDED 2 | #define _error_h_INCLUDED 3 | 4 | #include "attribute.h" 5 | 6 | // *INDENT-OFF* 7 | 8 | void kissat_error (const char *fmt, ...) ATTRIBUTE_FORMAT (1, 2); 9 | void kissat_fatal (const char *fmt, ...) ATTRIBUTE_FORMAT (1, 2); 10 | 11 | void kissat_fatal_message_start (void); 12 | 13 | void kissat_call_function_instead_of_abort (void (*)(void)); 14 | void kissat_abort (); 15 | 16 | // *INDENT-ON* 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /src/strengthen.h: -------------------------------------------------------------------------------- 1 | #ifndef _strengthen_h_INCLUDED 2 | #define _strengthen_h_INCLUDED 3 | 4 | #include 5 | 6 | struct clause; 7 | struct kissat; 8 | 9 | struct clause *kissat_on_the_fly_strengthen(struct kissat *, struct clause *, 10 | unsigned lit); 11 | 12 | void kissat_on_the_fly_subsume(struct kissat *, struct clause *, 13 | struct clause *); 14 | 15 | bool issat_strengthen_clause(struct kissat *, struct clause *, unsigned); 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /src/smooth.h: -------------------------------------------------------------------------------- 1 | #ifndef _smooth_h_INCLUDED 2 | #define _smooth_h_INCLUDED 3 | 4 | #include 5 | 6 | typedef struct smooth smooth; 7 | 8 | struct smooth { 9 | double value, biased, alpha, beta, exp; 10 | #ifdef LOGGING 11 | const char *name; 12 | uint64_t updated; 13 | #endif 14 | }; 15 | 16 | struct kissat; 17 | 18 | void kissat_init_smooth(struct kissat *, smooth *, int window, const char *); 19 | void kissat_update_smooth(struct kissat *, smooth *, double); 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /test/cover/cover0035.cnf: -------------------------------------------------------------------------------- 1 | c status 10 2 | c --eliminateclslim=0 3 | c --eliminateinit=0 4 | c --subsumemineff=0 5 | p cnf 35 21 6 | -11 -32 25 0 7 | -27 -18 32 0 8 | 13 -20 3 4 -2 -17 7 0 9 | 16 2 -22 0 10 | 33 -6 0 11 | -15 -10 21 -24 -5 -4 -14 23 0 12 | -3 -16 0 13 | -9 -1 8 -33 0 14 | -25 1 28 15 0 15 | 18 12 10 -29 0 16 | 35 -30 11 14 0 17 | 24 -34 4 0 18 | 29 19 0 19 | 26 27 -13 0 20 | 5 -26 31 0 21 | -28 -21 0 22 | -35 34 -31 0 23 | 20 22 0 24 | 6 -8 -23 0 25 | -7 -19 30 -12 0 26 | 17 9 0 27 | -------------------------------------------------------------------------------- /src/trail.h: -------------------------------------------------------------------------------- 1 | #ifndef _trail_h_INLCUDED 2 | #define _trail_h_INLCUDED 3 | 4 | #include "reference.h" 5 | 6 | #include 7 | 8 | struct kissat; 9 | 10 | void kissat_flush_trail(struct kissat *); 11 | void kissat_restart_and_flush_trail(struct kissat *); 12 | bool kissat_flush_and_mark_reason_clauses(struct kissat *, reference start); 13 | void kissat_unmark_reason_clauses(struct kissat *, reference start); 14 | void kissat_mark_reason_clauses(struct kissat *, reference start); 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /src/assume.h: -------------------------------------------------------------------------------- 1 | #ifndef _assume_h_INCLUDED 2 | #define _assume_h_INCLUDED 3 | 4 | #include 5 | 6 | #include "internal.h" 7 | 8 | void kissat_reset_assumptions(kissat *solver); 9 | void kissat_assume_literal(kissat *solver, int elit, unsigned ilit); 10 | int kissat_assign_assumption(kissat *solver); 11 | int kissat_propagate_assumptions(kissat *solver); 12 | 13 | static inline bool kissat_assuming(kissat *solver) { 14 | return solver->level < SIZE_STACK(solver->assumptions); 15 | } 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /src/colors.c: -------------------------------------------------------------------------------- 1 | #include "colors.h" 2 | 3 | #include 4 | 5 | int kissat_is_terminal[3] = { 0, -1, -1 }; 6 | 7 | int kissat_initialize_terminal(int fd) { 8 | assert(fd == 1 || fd == 2); 9 | assert(kissat_is_terminal[fd] < 0); 10 | return kissat_is_terminal[fd] = isatty(fd); 11 | } 12 | 13 | void kissat_force_colors(void) { 14 | kissat_is_terminal[1] = kissat_is_terminal[2] = 1; 15 | } 16 | 17 | void kissat_force_no_colors(void) { 18 | kissat_is_terminal[1] = kissat_is_terminal[2] = 0; 19 | } 20 | -------------------------------------------------------------------------------- /test/cover/cover0011.cnf: -------------------------------------------------------------------------------- 1 | c status 10 2 | c --bumpreasons=0 3 | c --failedmineff=0 4 | c --probeinit=0 5 | c --probeint=0 6 | c --really=0 7 | c --reduceinit=0 8 | c --substitute=0 9 | c --transitivemineff=0 10 | c --vivifymineff=0 11 | p cnf 19 20 12 | -6 7 0 13 | -7 -2 0 14 | 8 -7 0 15 | -8 4 0 16 | -9 17 7 0 17 | 18 13 0 18 | 11 -4 0 19 | 10 -1 -16 0 20 | 6 -11 0 21 | 6 9 0 22 | 3 -5 0 23 | -17 -18 0 24 | -14 2 17 0 25 | -12 -8 0 26 | 12 5 0 27 | -17 -9 -15 0 28 | 9 -3 0 29 | -13 15 -17 0 30 | -6 14 -16 0 31 | 16 -19 0 32 | -------------------------------------------------------------------------------- /src/resources.h: -------------------------------------------------------------------------------- 1 | #ifndef _resources_h_INCLUDED 2 | #define _resources_h_INCLUDED 3 | 4 | double kissat_wall_clock_time(void); 5 | 6 | #ifndef QUIET 7 | 8 | #ifndef _resources_h_INLCUDED 9 | #define _resources_h_INLCUDED 10 | 11 | #include 12 | 13 | struct kissat; 14 | 15 | double kissat_process_time(void); 16 | uint64_t kissat_current_resident_set_size(void); 17 | uint64_t kissat_maximum_resident_set_size(void); 18 | void kissat_print_resources(struct kissat *); 19 | 20 | #endif 21 | 22 | #endif 23 | #endif 24 | -------------------------------------------------------------------------------- /src/nonces.c: -------------------------------------------------------------------------------- 1 | #include "internal.h" 2 | #include "logging.h" 3 | #include "nonces.h" 4 | 5 | static const size_t size_nonces = 32; 6 | 7 | void kissat_init_nonces(kissat *solver) { 8 | LOG("initializing %zu nonces", size_nonces); 9 | assert(EMPTY_STACK(solver->nonces)); 10 | generator random = solver->random; 11 | for (size_t i = 0; i < size_nonces; i++) { 12 | uint64_t nonce = 1 | kissat_next_random64(&random); 13 | LOG2("nonce[%zu] = 0x%016" PRIx64, i, nonce); 14 | PUSH_STACK(solver->nonces, nonce); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/cnf/xor4.cnf: -------------------------------------------------------------------------------- 1 | c --eliminateinit=0 2 | c --forward=0 3 | 4 | p cnf 5 24 5 | 6 | -1 2 3 4 5 0 7 | 1 -2 3 4 5 0 8 | 1 2 -3 5 0 9 | 1 -4 5 0 10 | 1 2 3 4 -5 0 11 | 12 | -1 -2 -3 4 5 0 13 | -1 -2 3 -4 5 0 14 | -1 3 0 15 | -1 2 -3 -4 5 0 16 | -1 2 -3 4 -5 0 17 | -1 2 -4 -5 0 18 | 19 | 1 -2 -3 -4 5 0 20 | 1 -2 -3 -5 0 21 | 1 -2 3 -4 -5 0 22 | 23 | 1 2 -3 -4 -5 0 24 | 25 | -1 -2 -3 -4 -5 0 26 | 27 | 2 3 4 5 0 28 | 2 -3 -4 5 0 29 | -2 3 4 -5 0 30 | -2 -3 -4 -5 0 31 | 32 | 2 3 4 -5 0 33 | 2 -3 -4 -5 0 34 | -2 3 4 5 0 35 | -2 -3 -4 5 0 36 | -------------------------------------------------------------------------------- /test/cover/cover0042.cnf: -------------------------------------------------------------------------------- 1 | c status 10 2 | c --incremental=1 3 | c --phase=0 4 | c --rephaseinit=0 5 | p cnf 29 33 6 | 7 3 0 7 | 2 -6 0 8 | -8 6 0 9 | -3 4 0 10 | -4 -9 0 11 | 16 -11 0 12 | 7 -8 0 13 | -8 11 0 14 | -10 14 0 15 | 1 10 -7 0 16 | 17 15 -16 0 17 | -13 -1 0 18 | 15 -17 0 19 | 20 23 0 20 | 9 19 0 21 | 5 -4 0 22 | -20 -6 -12 0 23 | 19 13 0 24 | -16 -19 0 25 | 6 -3 0 26 | 5 -7 0 27 | 18 -23 0 28 | 20 -18 0 29 | 22 8 0 30 | -2 -14 0 31 | -5 -24 0 32 | 21 24 0 33 | -21 -22 -29 0 34 | 25 28 0 35 | 29 12 0 36 | -1 27 0 37 | 26 28 3 0 38 | 28 23 0 39 | -------------------------------------------------------------------------------- /test/cover/cover0036.cnf: -------------------------------------------------------------------------------- 1 | c status 10 2 | c --bumpreasons=0 3 | c --focus=0 4 | c --reduceinit=0 5 | c --reduceint=0 6 | c --reluctantint=0 7 | c --tumble=0 8 | p cnf 34 30 9 | 8 7 0 10 | 3 9 0 11 | 1 -14 0 12 | -5 -9 0 13 | 4 11 0 14 | -13 -1 3 0 15 | -3 -7 0 16 | 2 -12 0 17 | 19 17 0 18 | 22 -24 0 19 | 15 23 0 20 | -9 -4 0 21 | 14 12 0 22 | 8 0 23 | -18 5 0 24 | 13 4 -9 0 25 | 20 7 0 26 | 1 -5 0 27 | 2 24 -3 0 28 | 2 10 0 29 | 9 6 0 30 | -24 6 0 31 | -3 4 -10 0 32 | 4 -16 0 33 | -2 18 0 34 | 26 16 0 35 | -20 9 -26 0 36 | -6 -27 0 37 | 28 25 31 34 21 30 0 38 | 33 32 0 39 | -------------------------------------------------------------------------------- /test/testapplication.h: -------------------------------------------------------------------------------- 1 | #ifndef _tissatapplication_h_INCLUDED 2 | #define _tissatapplication_h_INCLUDED 3 | 4 | struct tissat_job; 5 | 6 | extern const char *tissat_options[]; 7 | extern const char **tissat_end_of_options; 8 | 9 | void tissat_call_application(int expected, const char *cmd); 10 | 11 | const char *tissat_next_option(unsigned count); 12 | 13 | #define all_tissat_options(OPT) \ 14 | const char * OPT, ** PTR_ ## OPT = tissat_options; \ 15 | PTR_ ## OPT != tissat_end_of_options && (OPT = *PTR_ ##OPT, true); \ 16 | PTR_ ## OPT++ 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /src/inlineframes.h: -------------------------------------------------------------------------------- 1 | #ifndef _inlineframes_h_INCLUDEDd 2 | #define _inlineframes_h_INCLUDEDd 3 | 4 | #include "allocate.h" 5 | #include "internal.h" 6 | 7 | static inline void kissat_push_frame(kissat *solver, unsigned decision) { 8 | assert(!solver->level || decision != UINT_MAX); 9 | const size_t trail = SIZE_ARRAY(solver->trail); 10 | assert(trail <= MAX_TRAIL); 11 | frame frame; 12 | frame.decision = decision; 13 | frame.promote = false; 14 | frame.trail = trail; 15 | frame.used = 0; 16 | PUSH_STACK(solver->frames, frame); 17 | } 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /test/testmessages.h: -------------------------------------------------------------------------------- 1 | #ifndef _testmessages_h_INCLUDED 2 | #define _testmessages_h_INCLUDED 3 | 4 | extern int tissat_verbosity; 5 | extern int tissat_warnings; 6 | 7 | void tissat_bold_message(const char *, ...); 8 | void tissat_error(const char *, ...); 9 | void tissat_fatal(const char *, ...); 10 | void tissat_line(void); 11 | void tissat_message(const char *, ...); 12 | void tissat_section(const char *, ...); 13 | void tissat_signal(int sig, const char *, ...); 14 | void tissat_verbose(const char *, ...); 15 | void tissat_warning(const char *, ...); 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /src/mode.h: -------------------------------------------------------------------------------- 1 | #ifndef _mode_h_INCLUDED 2 | #define _mode_h_INCLUDED 3 | 4 | #include 5 | #include 6 | 7 | struct kissat; 8 | 9 | typedef struct mode mode; 10 | 11 | struct mode { 12 | uint64_t ticks; 13 | #ifndef QUIET 14 | double entered; 15 | uint64_t conflicts; 16 | #ifdef METRICS 17 | uint64_t propagations; 18 | uint64_t visits; 19 | #endif 20 | #endif 21 | }; 22 | 23 | bool kissat_switching_search_mode(struct kissat *); 24 | void kissat_switch_search_mode(struct kissat *); 25 | void kissat_update_scores(struct kissat *); 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /test/testscheduler.h: -------------------------------------------------------------------------------- 1 | #ifndef _testscheduler_h_INCLUDED 2 | #define _testscheduler_h_INCLUDED 3 | 4 | typedef struct tissat_job tissat_job; 5 | 6 | extern unsigned tissat_scheduled; 7 | 8 | void tissat_schedule_function(void (*function)(void), const char *name); 9 | tissat_job *tissat_schedule_command(int, const char *command, tissat_job *); 10 | tissat_job *tissat_schedule_application(int, const char *args); 11 | 12 | #define SCHEDULE_FUNCTION(FUNCTION) \ 13 | tissat_schedule_function (FUNCTION, #FUNCTION) 14 | 15 | void tissat_run_jobs(int parallel); 16 | void tissat_release_jobs(void); 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /src/frames.h: -------------------------------------------------------------------------------- 1 | #ifndef _frames_h_INCLUDED 2 | #define _frames_h_INCLUDED 3 | 4 | #include "literal.h" 5 | #include "stack.h" 6 | 7 | #include 8 | 9 | typedef struct frame frame; 10 | typedef struct slice slice; 11 | 12 | struct frame { 13 | bool promote; 14 | unsigned decision; 15 | unsigned trail; 16 | unsigned used; 17 | #ifndef NDEBUG 18 | unsigned saved; 19 | #endif 20 | }; 21 | 22 | // *INDENT-OFF* 23 | 24 | typedef STACK (frame) frames; 25 | 26 | // *INDENT-ON* 27 | 28 | struct kissat; 29 | 30 | #define FRAME(LEVEL) \ 31 | (PEEK_STACK (solver->frames, (LEVEL))) 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /src/gates.h: -------------------------------------------------------------------------------- 1 | #ifndef _gates_h_INCLUDED 2 | #define _gates_h_INCLUDED 3 | 4 | #include 5 | #include 6 | 7 | struct kissat; 8 | struct clause; 9 | 10 | bool kissat_find_gates(struct kissat *, unsigned lit, bool eq_only); 11 | void kissat_get_antecedents(struct kissat *, unsigned lit); 12 | 13 | size_t kissat_mark_binaries(struct kissat *, unsigned lit); 14 | void kissat_unmark_binaries(struct kissat *, unsigned lit); 15 | 16 | #ifndef METRICS 17 | #define GATE_ELIMINATED(...) true 18 | #else 19 | #define GATE_ELIMINATED(NAME) (&solver->statistics.NAME ## _eliminated) 20 | #endif 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /test/testsizes.c: -------------------------------------------------------------------------------- 1 | #include "test.h" 2 | 3 | bool test_sizes(void) { 4 | printf("sizeof (word) = %zu\n", sizeof(word)); 5 | assert(sizeof(void *) == sizeof(word)); 6 | assert(MAX_REF < INVALID_REF); 7 | assert(MAX_ARENA < INVALID_REF); 8 | printf("sizeof (clause) = %zu\n", sizeof(clause)); 9 | printf("SIZE_OF_CLAUSE_HEADER = %zu\n", SIZE_OF_CLAUSE_HEADER); 10 | assert(SIZE_OF_CLAUSE_HEADER == sizeof(unsigned)); 11 | printf("sizeof (flags) = %zu\n", sizeof(flags)); 12 | assert(sizeof(flags) == 1); 13 | printf("sizeof (value) = %zu\n", sizeof(value)); 14 | assert(sizeof(value) == 1); 15 | return false; 16 | } 17 | -------------------------------------------------------------------------------- /scripts/filter-coverage-output.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | sed \ 3 | -e '/^$/d' \ 4 | -e '/^File/d' \ 5 | -e s,\',,g \ 6 | -e 's,[:%], ,' | \ 7 | awk ' 8 | /^Lines/{coverage=$3;lines=$5} 9 | /^Creating/{ 10 | printf "%6.2f %% %-20s %12u lines\n", coverage, $2, lines 11 | } 12 | END{ 13 | printf "%6.2f %% %-20s %12u lines\n", coverage, "TOTAL COVERAGE", lines 14 | } 15 | ' | \ 16 | grep -v '^100.00 %' | \ 17 | sort -r -n | \ 18 | awk ' 19 | /TOTAL COVERAGE/ { 20 | print "-------------------------------------------------" 21 | print $0 22 | print "-------------------------------------------------" 23 | next 24 | } 25 | { print }' 26 | -------------------------------------------------------------------------------- /test/cnf/def1.cnf: -------------------------------------------------------------------------------- 1 | c --eliminateinit=0 2 | c --definitions=1 3 | c --definitionsalways=1 4 | c --really=0 5 | c --backward=0 6 | c --forward=0 7 | c --ands=0 8 | c --equivalences=0 9 | c --ifthenelse=0 10 | c --xors=0 11 | p cnf 6 24 12 | 1 2 3 0 13 | 1 2 -3 0 14 | 1 -2 3 0 15 | 1 -2 -3 0 16 | -1 4 5 0 17 | -1 4 -5 0 18 | -1 -4 5 0 19 | -1 -4 -5 0 20 | 6 2 3 4 5 0 21 | 6 2 3 4 -5 0 22 | 6 2 3 -4 5 0 23 | 6 2 3 -4 -5 0 24 | 6 2 -3 4 5 0 25 | 6 2 -3 4 -5 0 26 | 6 2 -3 -4 5 0 27 | 6 2 -3 -4 -5 0 28 | -6 -2 3 4 5 0 29 | -6 -2 3 4 -5 0 30 | -6 -2 3 -4 5 0 31 | -6 -2 3 -4 -5 0 32 | -6 -2 -3 4 5 0 33 | -6 -2 -3 4 -5 0 34 | -6 -2 -3 -4 5 0 35 | -6 -2 -3 -4 -5 0 36 | -------------------------------------------------------------------------------- /test/cover/cover0043.cnf: -------------------------------------------------------------------------------- 1 | c status 10 2 | c --incremental=1 3 | c --rephaseinit=0 4 | p cnf 35 40 5 | 10 -8 0 6 | 3 1 0 7 | 5 4 0 8 | 6 9 14 0 9 | 2 -17 0 10 | -2 -20 0 11 | -12 -7 -15 0 12 | 15 20 0 13 | 12 19 0 14 | 9 19 0 15 | -14 -18 11 0 16 | -5 11 0 17 | -18 11 3 0 18 | -20 9 0 19 | 7 -15 -10 0 20 | -20 -30 0 21 | 13 31 0 22 | -19 -22 0 23 | -8 -23 0 24 | 25 -14 0 25 | -9 6 0 26 | 20 -29 -32 0 27 | 23 -15 29 0 28 | -6 24 0 29 | -27 28 0 30 | -21 -16 8 0 31 | -9 -31 30 0 32 | 27 -13 0 33 | -28 -27 -22 0 34 | 4 17 0 35 | 26 32 0 36 | 21 -4 0 37 | -24 -11 0 38 | 18 16 0 39 | -25 -32 0 40 | 22 -26 0 41 | -33 3 -17 0 42 | -4 -35 0 43 | -34 33 0 44 | -3 14 0 45 | -------------------------------------------------------------------------------- /src/averages.c: -------------------------------------------------------------------------------- 1 | #include "internal.h" 2 | 3 | void kissat_init_averages(kissat *solver, averages *averages) { 4 | if (averages->initialized) { 5 | return; 6 | } 7 | #define INIT_EMA(EMA,WINDOW) \ 8 | kissat_init_smooth (solver, &averages->EMA, WINDOW, #EMA) 9 | #ifndef QUIET 10 | INIT_EMA(level, GET_OPTION(emaslow)); 11 | INIT_EMA(size, GET_OPTION(emaslow)); 12 | INIT_EMA(trail, GET_OPTION(emaslow)); 13 | #endif 14 | INIT_EMA(fast_glue, GET_OPTION(emafast)); 15 | INIT_EMA(slow_glue, GET_OPTION(emaslow)); 16 | INIT_EMA(decision_rate, GET_OPTION(emaslow)); 17 | averages->initialized = true; 18 | averages->saved_decisions = DECISIONS; 19 | } 20 | -------------------------------------------------------------------------------- /test/cnf/ph4.cnf: -------------------------------------------------------------------------------- 1 | p cnf 20 45 2 | -1 -5 0 3 | -1 -9 0 4 | -1 -13 0 5 | -1 -17 0 6 | -5 -9 0 7 | -5 -13 0 8 | -5 -17 0 9 | -9 -13 0 10 | -9 -17 0 11 | -13 -17 0 12 | -2 -6 0 13 | -2 -10 0 14 | -2 -14 0 15 | -2 -18 0 16 | -6 -10 0 17 | -6 -14 0 18 | -6 -18 0 19 | -10 -14 0 20 | -10 -18 0 21 | -14 -18 0 22 | -3 -7 0 23 | -3 -11 0 24 | -3 -15 0 25 | -3 -19 0 26 | -7 -11 0 27 | -7 -15 0 28 | -7 -19 0 29 | -11 -15 0 30 | -11 -19 0 31 | -15 -19 0 32 | -4 -8 0 33 | -4 -12 0 34 | -4 -16 0 35 | -4 -20 0 36 | -8 -12 0 37 | -8 -16 0 38 | -8 -20 0 39 | -12 -16 0 40 | -12 -20 0 41 | -16 -20 0 42 | 4 3 2 1 0 43 | 8 7 6 5 0 44 | 12 11 10 9 0 45 | 16 15 14 13 0 46 | 20 19 18 17 0 47 | -------------------------------------------------------------------------------- /test/cover/cover0023.cnf: -------------------------------------------------------------------------------- 1 | c status 10 2 | c --bumpreasons=0 3 | c --eliminateinit=1 4 | c --eliminateocclim=1 5 | c --forward=0 6 | c --rephaseinit=0 7 | p cnf 27 36 8 | 13 -10 0 9 | 2 -4 0 10 | 6 -7 -13 0 11 | 10 -1 -6 0 12 | 8 -3 12 0 13 | 5 8 0 14 | 1 11 0 15 | 9 8 -4 0 16 | 11 -10 -7 0 17 | 12 7 -10 0 18 | -8 13 0 19 | 7 4 0 20 | -10 -11 0 21 | -8 5 0 22 | -11 3 0 23 | -12 -5 0 24 | 4 -15 12 0 25 | 13 -18 -14 0 26 | -1 -16 0 27 | -18 -17 0 28 | -19 6 17 0 29 | 7 10 -14 0 30 | -20 -17 0 31 | 15 18 0 32 | 16 14 -2 0 33 | -9 4 0 34 | 14 9 19 0 35 | -4 8 21 0 36 | -3 -20 0 37 | 24 -22 0 38 | -19 -23 0 39 | 20 26 0 40 | 25 18 0 41 | 6 -25 -21 0 42 | -4 -22 0 43 | -27 -26 0 44 | -------------------------------------------------------------------------------- /src/cover.h: -------------------------------------------------------------------------------- 1 | #ifndef _cover_h_INCLUDED 2 | #define _cover_h_INCLUDED 3 | 4 | #include 5 | #include 6 | 7 | #define COVER(COND) \ 8 | ( \ 9 | (COND) \ 10 | ? \ 11 | \ 12 | ( \ 13 | fflush (stdout), \ 14 | fprintf (stderr, "%s:%ld: %s: Coverage goal `%s' reached.\n", \ 15 | __FILE__, (long) __LINE__, __func__, #COND), \ 16 | abort (), \ 17 | (void) 0 \ 18 | ) \ 19 | : \ 20 | (void) 0 \ 21 | ) 22 | 23 | #ifdef COVERAGE 24 | #define FLUSH_COVERAGE() \ 25 | do { \ 26 | void __gcov_flush (void); \ 27 | __gcov_flush (); \ 28 | } while (0) 29 | #else 30 | #define FLUSH_COVERAGE() do { } while (0) 31 | #endif 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /src/reap.h: -------------------------------------------------------------------------------- 1 | #ifndef _reap_h_INCLUDED 2 | #define _reap_h_INCLUDED 3 | 4 | #include 5 | 6 | #include "stack.h" 7 | 8 | typedef struct reap reap; 9 | 10 | struct reap { 11 | size_t num_elements; 12 | unsigned last_deleted; 13 | unsigned min_bucket; 14 | unsigned max_bucket; 15 | unsigneds buckets[33]; 16 | }; 17 | 18 | struct kissat; 19 | 20 | void kissat_init_reap(struct kissat *, reap *); 21 | void kissat_release_reap(struct kissat *solver, reap *); 22 | 23 | static inline bool kissat_empty_reap(reap *reap) { 24 | return !reap->num_elements; 25 | } 26 | 27 | static inline size_t kissat_size_reap(reap *reap) { 28 | return reap->num_elements; 29 | } 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /test/cnf/prime4.cnf: -------------------------------------------------------------------------------- 1 | p cnf 20 49 2 | -5 -1 0 3 | -5 2 0 4 | 1 -2 5 0 5 | -6 -3 0 6 | -6 4 0 7 | 3 -4 6 0 8 | -7 -5 0 9 | -7 -6 0 10 | 5 6 7 0 11 | -8 2 0 12 | -8 4 0 13 | -2 -4 8 0 14 | -9 2 0 15 | -9 3 0 16 | -2 -3 9 0 17 | -10 1 0 18 | -10 4 0 19 | -1 -4 10 0 20 | -11 9 0 21 | -11 10 0 22 | -9 -10 11 0 23 | -12 -9 0 24 | -12 -10 0 25 | 9 10 12 0 26 | -13 -11 0 27 | -13 -12 0 28 | 11 12 13 0 29 | -14 1 0 30 | -14 3 0 31 | -1 -3 14 0 32 | -15 14 0 33 | -15 11 0 34 | -14 -11 15 0 35 | -16 -14 0 36 | -16 -11 0 37 | 14 11 16 0 38 | -17 -15 0 39 | -17 -16 0 40 | 15 16 17 0 41 | -18 -13 0 42 | -18 17 0 43 | 13 -17 18 0 44 | -19 -8 0 45 | -19 18 0 46 | 8 -18 19 0 47 | -20 7 0 48 | -20 19 0 49 | -7 -19 20 0 50 | 20 0 51 | -------------------------------------------------------------------------------- /test/cover/cover0022.cnf: -------------------------------------------------------------------------------- 1 | c status 10 2 | c --otfs=0 3 | c --rephaseinit=0 4 | p cnf 34 43 5 | 3 8 -7 -2 0 6 | -7 -2 -10 0 7 | -1 9 0 8 | -1 -2 -12 0 9 | 3 5 -1 4 0 10 | 2 -11 0 11 | 11 8 -3 0 12 | 10 -1 0 13 | 7 -1 -3 0 14 | 9 5 -2 0 15 | 1 9 0 16 | 7 6 0 17 | 12 1 7 0 18 | -12 7 0 19 | 18 -17 -13 0 20 | 17 -13 -16 0 21 | -23 20 0 22 | 19 21 0 23 | 15 26 16 0 24 | -26 25 0 25 | -22 -25 0 26 | 21 3 0 27 | 16 5 0 28 | -3 21 2 0 29 | -6 -5 0 30 | -6 20 -11 0 31 | 26 -9 22 0 32 | 25 11 1 0 33 | 4 -21 -8 -7 0 34 | 1 -3 0 35 | -29 -30 0 36 | -33 -2 21 0 37 | -31 -27 -20 0 38 | 12 -8 0 39 | -28 33 -19 0 40 | 30 23 31 0 41 | -26 -16 0 42 | -30 8 0 43 | -14 -24 -15 0 44 | -32 10 -25 0 45 | 29 -18 -34 0 46 | 2 -5 0 47 | -22 -4 0 48 | -------------------------------------------------------------------------------- /src/eliminate.h: -------------------------------------------------------------------------------- 1 | #ifndef _eliminate_hpp_INCLUDED 2 | #define _eliminate_hpp_INCLUDED 3 | 4 | #include 5 | 6 | struct kissat; 7 | struct clause; 8 | 9 | void kissat_update_after_removing_variable(struct kissat *, unsigned); 10 | void kissat_update_after_removing_clause(struct kissat *, struct clause *, 11 | unsigned except); 12 | 13 | void kissat_flush_units_while_connected(struct kissat *); 14 | 15 | bool kissat_eliminating(struct kissat *); 16 | int kissat_eliminate(struct kissat *); 17 | 18 | void kissat_eliminate_binary( 19 | struct kissat *, bool weakened, unsigned, unsigned); 20 | void kissat_eliminate_clause( 21 | struct kissat *, bool weakened, struct clause *, unsigned); 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /src/rephase.h: -------------------------------------------------------------------------------- 1 | #ifndef _rephase_h_INCLUDED 2 | #define _rephase_h_INCLUDED 3 | 4 | #include 5 | #include 6 | 7 | typedef struct rephased rephased; 8 | 9 | struct rephased { 10 | uint64_t count; 11 | char last; 12 | }; 13 | 14 | struct kissat; 15 | 16 | bool kissat_rephasing(struct kissat *); 17 | void kissat_rephase(struct kissat *); 18 | char kissat_rephase_best(struct kissat *); 19 | 20 | void kissat_reset_rephased(struct kissat *); 21 | void kissat_reset_best_assigned(struct kissat *); 22 | void kissat_reset_target_assigned(struct kissat *); 23 | 24 | #define REPHASES \ 25 | REPHASE (best, 'B', 0) \ 26 | REPHASE (inverted, 'I', 1) \ 27 | REPHASE (original, 'O', 2) \ 28 | REPHASE (walking, 'W', 3) 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /test/cover/cover0025.cnf: -------------------------------------------------------------------------------- 1 | c status 10 2 | c --otfs=0 3 | c --rephaseinit=0 4 | p cnf 36 47 5 | -13 -3 0 6 | -8 15 0 7 | 2 -10 0 8 | 2 -14 0 9 | 17 6 0 10 | 10 -15 0 11 | -15 -12 0 12 | 6 -4 0 13 | -12 -9 17 0 14 | 18 -16 4 0 15 | -14 12 13 0 16 | -10 -1 -11 0 17 | -10 -3 0 18 | 11 5 0 19 | 24 -13 0 20 | 19 25 -18 0 21 | 20 22 -2 0 22 | -25 0 23 | 26 10 0 24 | 8 -9 -19 0 25 | -24 9 12 0 26 | -5 -8 0 27 | 12 17 0 28 | -1 19 14 0 29 | -12 10 -20 0 30 | 21 3 -20 0 31 | -30 24 0 32 | -21 15 0 33 | 20 -6 27 0 34 | 1 29 28 0 35 | 23 -29 0 36 | -24 -30 -27 0 37 | -29 -23 12 0 38 | 14 -26 0 39 | 30 -24 -10 0 40 | 33 31 0 41 | 30 -16 9 0 42 | -7 -33 0 43 | -32 27 0 44 | 16 -31 0 45 | -17 -22 0 46 | 15 -35 -29 0 47 | 31 29 0 48 | 36 35 0 49 | -28 0 50 | 32 34 0 51 | -34 -36 0 52 | -------------------------------------------------------------------------------- /src/averages.h: -------------------------------------------------------------------------------- 1 | #ifndef _averages_h_INCLUDED 2 | #define _averages_h_INCLUDED 3 | 4 | #include "smooth.h" 5 | 6 | #include 7 | 8 | typedef struct averages averages; 9 | 10 | struct averages { 11 | bool initialized; 12 | smooth fast_glue, slow_glue; 13 | #ifndef QUIET 14 | smooth level, size, trail; 15 | #endif 16 | smooth decision_rate; 17 | uint64_t saved_decisions; 18 | }; 19 | 20 | struct kissat; 21 | 22 | void kissat_init_averages(struct kissat *, averages *); 23 | 24 | #define AVERAGES (solver->averages[solver->stable]) 25 | 26 | #define EMA(NAME) (AVERAGES.NAME) 27 | 28 | #define AVERAGE(NAME) (EMA(NAME).value) 29 | 30 | #define UPDATE_AVERAGE(NAME,VALUE) \ 31 | kissat_update_smooth (solver, &EMA(NAME), VALUE) 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /src/handle.h: -------------------------------------------------------------------------------- 1 | #ifndef _handle_h_INCLUDED 2 | #define _handle_h_INCLUDED 3 | 4 | #include 5 | 6 | void kissat_init_signal_handler(void (*handler)(int)); 7 | void kissat_reset_signal_handler(void); 8 | 9 | void kissat_init_alarm(void (*handler)(void)); 10 | void kissat_reset_alarm(void); 11 | 12 | #define SIGNALS \ 13 | SIGNAL(SIGABRT) \ 14 | SIGNAL(SIGBUS) \ 15 | SIGNAL(SIGINT) \ 16 | SIGNAL(SIGSEGV) \ 17 | SIGNAL(SIGTERM) 18 | 19 | // *INDENT-OFF* 20 | 21 | static inline const char * 22 | kissat_signal_name (int sig) 23 | { 24 | #define SIGNAL(SIG) \ 25 | if (sig == SIG) return #SIG; 26 | SIGNALS 27 | #undef SIGNAL 28 | if (sig == SIGALRM) 29 | return "SIGALRM"; 30 | return "SIGUNKNOWN"; 31 | } 32 | 33 | // *INDENT-ON* 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /src/reap.c: -------------------------------------------------------------------------------- 1 | #include "allocate.h" 2 | #include "internal.h" 3 | #include "logging.h" 4 | #include "reap.h" 5 | 6 | #include 7 | 8 | void kissat_init_reap(kissat *solver, reap *reap) { 9 | LOG("initializing radix heap"); 10 | memset(reap, 0, sizeof * reap); 11 | assert(!reap->num_elements); 12 | assert(!reap->last_deleted); 13 | reap->min_bucket = 32; 14 | assert(!reap->max_bucket); 15 | #ifndef LOGGING 16 | (void) solver; 17 | #endif 18 | } 19 | 20 | void kissat_release_reap(kissat *solver, reap *reap) { 21 | LOG("releasing reap"); 22 | for (unsigned i = 0; i < 33; i++) { 23 | RELEASE_STACK(reap->buckets[i]); 24 | } 25 | reap->num_elements = 0; 26 | reap->last_deleted = 0; 27 | reap->min_bucket = 32; 28 | reap->max_bucket = 0; 29 | } 30 | -------------------------------------------------------------------------------- /src/inlinescore.h: -------------------------------------------------------------------------------- 1 | #ifndef _inlinescore_h_INCLUDED 2 | #define _inlinescore_h_INCLUDED 3 | 4 | #include "inlineheap.h" 5 | #include "inlinevector.h" 6 | 7 | static inline void kissat_update_variable_score(kissat *solver, heap *schedule, 8 | unsigned idx) { 9 | if (!GET_OPTION(eliminateheap)) { 10 | return; 11 | } 12 | assert(schedule->size); 13 | const unsigned lit = LIT(idx); 14 | const unsigned not_lit = NOT(lit); 15 | size_t pos = SIZE_WATCHES(WATCHES(lit)); 16 | size_t neg = SIZE_WATCHES(WATCHES(not_lit)); 17 | double new_score = ((double) pos) * neg + pos + neg; 18 | LOG("new elimination score %g for variable %u (pos %zu and neg %zu)", 19 | new_score, idx, pos, neg); 20 | kissat_update_heap(solver, schedule, idx, -new_score); 21 | } 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /src/reluctant.h: -------------------------------------------------------------------------------- 1 | #ifndef _reluctant_h_INCLUDED 2 | #define _reluctant_h_INCLUDED 3 | 4 | #include 5 | #include 6 | 7 | typedef struct reluctant reluctant; 8 | 9 | struct reluctant { 10 | bool limited; 11 | bool trigger; 12 | uint64_t period; 13 | uint64_t wait; 14 | uint64_t u, v; 15 | uint64_t limit; 16 | }; 17 | 18 | void kissat_enable_reluctant(reluctant *, uint64_t period, uint64_t limit); 19 | void kissat_disable_reluctant(reluctant *); 20 | void kissat_tick_reluctant(reluctant *); 21 | 22 | static inline bool kissat_reluctant_triggered(reluctant *reluctant) { 23 | if (!reluctant->trigger) { 24 | return false; 25 | } 26 | reluctant->trigger = false; 27 | return true; 28 | } 29 | 30 | struct kissat; 31 | 32 | void kissat_init_reluctant(struct kissat *); 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /src/clueue.h: -------------------------------------------------------------------------------- 1 | #ifndef _clueue_h_INCLUDED 2 | #define _clueue_h_INCLUDED 3 | 4 | #include "reference.h" 5 | 6 | #include 7 | 8 | typedef struct clueue clueue; 9 | 10 | struct clueue { 11 | unsigned size, next; 12 | reference *elements; 13 | }; 14 | 15 | struct kissat; 16 | 17 | void kissat_clear_clueue(struct kissat *, clueue *); 18 | void kissat_init_clueue(struct kissat *, clueue *, unsigned size); 19 | void kissat_release_clueue(struct kissat *, clueue *); 20 | 21 | static inline void kissat_push_clueue(clueue *clueue, reference element) { 22 | if (!clueue->size) { 23 | return; 24 | } 25 | assert(clueue->next < clueue->size); 26 | clueue->elements[clueue->next++] = element; 27 | if (clueue->next == clueue->size) { 28 | clueue->next = 0; 29 | } 30 | } 31 | 32 | void kissat_eager_subsume(struct kissat *); 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /src/allocate.h: -------------------------------------------------------------------------------- 1 | #ifndef _allocate_h_INCLUDED 2 | #define _allocate_h_INCLUDED 3 | 4 | #include 5 | 6 | struct kissat; 7 | 8 | void *kissat_malloc(struct kissat *, size_t bytes); 9 | void kissat_free(struct kissat *, void *, size_t bytes); 10 | 11 | void *kissat_calloc(struct kissat *, size_t n, size_t size); 12 | void *kissat_nalloc(struct kissat *, size_t n, size_t size); 13 | void kissat_dealloc(struct kissat *, void *ptr, size_t n, size_t size); 14 | 15 | void *kissat_realloc(struct kissat *, void *, size_t old, size_t bytes); 16 | void *kissat_nrealloc(struct kissat *, void *, size_t o, size_t n, size_t); 17 | 18 | #define CALLOC(P,N) \ 19 | do { \ 20 | (P) = kissat_calloc (solver, (N), sizeof *(P)); \ 21 | } while (0) 22 | 23 | #define DEALLOC(P,N) \ 24 | do { \ 25 | kissat_dealloc (solver, (P), (N), sizeof *(P)); \ 26 | } while (0) 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/queue.h: -------------------------------------------------------------------------------- 1 | #ifndef _queue_h_INCLUDED 2 | #define _queue_h_INCLUDED 3 | 4 | #define DISCONNECT UINT_MAX 5 | #define DISCONNECTED(IDX) ((int)(IDX) < 0) 6 | 7 | struct kissat; 8 | 9 | typedef struct links links; 10 | typedef struct queue queue; 11 | 12 | struct links { 13 | unsigned prev, next; 14 | unsigned stamp; 15 | }; 16 | 17 | struct queue { 18 | unsigned first, last, stamp; 19 | struct { 20 | unsigned idx, stamp; 21 | } search; 22 | }; 23 | 24 | void kissat_init_queue(struct kissat *); 25 | void kissat_reset_queue(struct kissat *); 26 | void kissat_reassign_queue_stamps(struct kissat *); 27 | 28 | #define LINK(IDX) \ 29 | (solver->links[assert ((IDX) < VARS), (IDX)]) 30 | 31 | #if defined(CHECK_QUEUE) && !defined(NDEBUG) 32 | void kissat_check_queue(struct kissat *); 33 | #else 34 | #define kissat_check_queue(...) do { } while (0) 35 | #endif 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /test/cover/cover0012.cnf: -------------------------------------------------------------------------------- 1 | c status 10 2 | c --failedmineff=0 3 | c --probeinit=0 4 | c --probeint=0 5 | c --reduceinit=0 6 | c --substitutelim=0 7 | c --ternarymineff=0 8 | c --vivifymineff=0 9 | p cnf 40 49 10 | -9 25 -5 0 11 | 24 12 0 12 | 25 10 -2 0 13 | 6 22 0 14 | -19 12 -16 0 15 | 4 -18 0 16 | 19 -1 0 17 | -24 -7 10 0 18 | -18 17 0 19 | -9 8 0 20 | -23 -25 0 21 | -21 8 0 22 | 2 24 0 23 | -15 -10 0 24 | 9 -14 0 25 | -22 -4 -10 0 26 | 2 16 0 27 | 15 4 -3 0 28 | -2 14 13 0 29 | 24 28 -11 0 30 | 27 -17 0 31 | 20 29 0 32 | 10 -27 0 33 | -29 13 0 34 | -12 14 0 35 | -35 -30 26 0 36 | 34 7 0 37 | -28 -30 -33 0 38 | 31 -26 0 39 | -8 -6 0 40 | 32 30 0 41 | 31 -20 0 42 | 35 23 0 43 | -13 -2 0 44 | 18 5 0 45 | -26 28 0 46 | -34 30 33 0 47 | -28 -32 -31 0 48 | 19 26 0 49 | 40 1 0 50 | 38 39 0 51 | -33 30 0 52 | 33 -40 -30 0 53 | 7 -36 0 54 | 11 33 0 55 | 35 -38 0 56 | -37 3 0 57 | 40 -37 0 58 | 34 21 0 59 | -------------------------------------------------------------------------------- /src/collect.h: -------------------------------------------------------------------------------- 1 | #ifndef _collect_h_INCLUDED 2 | #define _collect_h_INCLUDED 3 | 4 | #include "internal.h" 5 | 6 | void kissat_dense_collect(kissat *); 7 | void kissat_sparse_collect(kissat *, bool compact, reference start); 8 | 9 | static inline void kissat_defrag_watches(kissat *solver) { 10 | kissat_defrag_vectors(solver, LITS, solver->watches); 11 | } 12 | 13 | static inline void kissat_defrag_watches_if_needed(kissat *solver) { 14 | const size_t size = SIZE_STACK(solver->vectors.stack); 15 | const size_t size_limit = GET_OPTION(defragsize); 16 | if (size <= size_limit) { 17 | return; 18 | } 19 | 20 | const size_t usable = solver->vectors.usable; 21 | const size_t usable_limit = (size * GET_OPTION(defraglim)) / 100; 22 | if (usable <= usable_limit) { 23 | return; 24 | } 25 | 26 | INC(vectors_defrags_needed); 27 | kissat_defrag_watches(solver); 28 | } 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /src/promote.h: -------------------------------------------------------------------------------- 1 | #ifndef _promote_h_INCLUDED 2 | #define _promote_h_INCLUDED 3 | 4 | #include "internal.h" 5 | 6 | void kissat_promote_clause(struct kissat *, clause *, unsigned new_glue); 7 | 8 | static inline unsigned kissat_recompute_glue(kissat *solver, clause *c) { 9 | assert(EMPTY_STACK(solver->promote)); 10 | for (all_literals_in_clause(lit, c)) { 11 | assert(VALUE(lit)); 12 | const unsigned level = LEVEL(lit); 13 | frame *frame = &FRAME(level); 14 | if (frame->promote) { 15 | continue; 16 | } 17 | frame->promote = true; 18 | PUSH_STACK(solver->promote, level); 19 | } 20 | for (all_stack(unsigned, level, solver->promote)) { 21 | frame *frame = &FRAME(level); 22 | assert(frame->promote); 23 | frame->promote = false; 24 | } 25 | unsigned res = SIZE_STACK(solver->promote); 26 | CLEAR_STACK(solver->promote); 27 | return res; 28 | } 29 | 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /src/require.h: -------------------------------------------------------------------------------- 1 | #ifndef _require_h_INCLUDED 2 | #define _require_h_INCLUDED 3 | 4 | #define kissat_require(COND,...) \ 5 | do { \ 6 | if ((COND)) \ 7 | break; \ 8 | kissat_fatal_message_start (); \ 9 | fprintf (stderr, "calling '%s': ", __func__); \ 10 | fprintf (stderr, __VA_ARGS__); \ 11 | fputc ('\n', stderr); \ 12 | fflush (stderr); \ 13 | kissat_abort (); \ 14 | } while (0) 15 | 16 | #define kissat_require_initialized(SOLVER) \ 17 | kissat_require (SOLVER, "uninitialized") 18 | 19 | #define kissat_require_valid_external_internal(LIT) \ 20 | do { \ 21 | kissat_require ((LIT), "invalid zero literal"); \ 22 | kissat_require ((LIT) != INT_MIN, \ 23 | "invalid literal '%d' (INT_MIN)", (LIT)); \ 24 | const int TMP_IDX = ABS (LIT); \ 25 | kissat_require (TMP_IDX <= EXTERNAL_MAX_VAR, \ 26 | "invalid literal '%d' (variable larger than %d)", \ 27 | (LIT), EXTERNAL_MAX_VAR); \ 28 | assert (VALID_EXTERNAL_LITERAL (LIT)); \ 29 | } while (0) 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /test/testreap.c: -------------------------------------------------------------------------------- 1 | #include "../src/inlinereap.h" 2 | 3 | #include "test.h" 4 | 5 | static void test_reap_random(void) { 6 | srand(42); 7 | DECLARE_AND_INIT_SOLVER(solver); 8 | reap reap; 9 | kissat_init_reap(solver, &reap); 10 | #define N 3000 11 | #define M 1000 12 | for (unsigned i = 0; i < N; i++) { 13 | unsigned tmp = rand() % M; 14 | printf("push %u\n", tmp); 15 | kissat_push_reap(solver, &reap, tmp); 16 | } 17 | unsigned last = 0, count = 2; 18 | while (!kissat_empty_reap(&reap)) { 19 | unsigned popped = kissat_pop_reap(solver, &reap); 20 | printf("pop %u\n", popped); 21 | assert(last <= popped); 22 | last = popped; 23 | if (count--) { 24 | continue; 25 | } 26 | unsigned tmp = last + (rand() % M); 27 | printf("push %u\n", tmp); 28 | kissat_push_reap(solver, &reap, tmp); 29 | count = 1 + (rand() % 3); 30 | } 31 | kissat_release_reap(solver, &reap); 32 | } 33 | 34 | void tissat_schedule_reap(void) { 35 | SCHEDULE_FUNCTION(test_reap_random); 36 | } 37 | -------------------------------------------------------------------------------- /src/extend.h: -------------------------------------------------------------------------------- 1 | #ifndef _extend_h_INCLUDED 2 | #define _extend_h_INCLUDED 3 | 4 | #include 5 | 6 | #include "stack.h" 7 | #include "utilities.h" 8 | 9 | typedef struct extension extension; 10 | 11 | struct extension { 12 | signed int lit: 30; 13 | bool autarky: 1; 14 | bool blocking: 1; 15 | }; 16 | 17 | // *INDENT-OFF* 18 | typedef STACK (extension) extensions; 19 | // *INDENT-ON* 20 | 21 | static inline extension kissat_extension(bool blocking, int lit) { 22 | assert(ABS(lit) < (1 << 29)); 23 | extension res; 24 | res.autarky = false; 25 | res.blocking = blocking; 26 | res.lit = lit; 27 | return res; 28 | } 29 | 30 | static inline extension kissat_autarky_extension(bool blocking, int lit) { 31 | assert(ABS(lit) < (1 << 29)); 32 | extension res; 33 | res.autarky = true; 34 | res.blocking = blocking; 35 | res.lit = lit; 36 | return res; 37 | } 38 | 39 | struct kissat; 40 | 41 | void kissat_undo_eliminated_assignment(struct kissat *solver); 42 | void kissat_extend(struct kissat *solver); 43 | 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /src/arena.h: -------------------------------------------------------------------------------- 1 | #ifndef _arena_h_INCLUDED 2 | #define _arena_h_INCLUDED 3 | 4 | #include "reference.h" 5 | #include "stack.h" 6 | #include "utilities.h" 7 | 8 | #ifdef COMPACT 9 | typedef word ward; 10 | #else 11 | typedef w2rd ward; 12 | #endif 13 | 14 | #define LD_MAX_ARENA_32 (29 - (unsigned) sizeof (ward)/4) 15 | 16 | #define LD_MAX_ARENA \ 17 | ((sizeof (word) == 4) ? LD_MAX_ARENA_32 : LD_MAX_REF) 18 | 19 | #define MAX_ARENA ((size_t)1 << LD_MAX_ARENA) 20 | 21 | // *INDENT-OFF* 22 | 23 | typedef STACK (ward) arena; 24 | 25 | // *INDENT-ON* 26 | 27 | struct clause; 28 | struct kissat; 29 | 30 | reference kissat_allocate_clause(struct kissat *, size_t size); 31 | void kissat_shrink_arena(struct kissat *); 32 | 33 | #if !defined(NDEBUG) || defined(LOGGING) 34 | 35 | bool kissat_clause_in_arena(const struct kissat *, const struct clause *); 36 | 37 | #endif 38 | 39 | static inline word kissat_align_ward(word w) { 40 | #ifdef COMPACT 41 | return kissat_align_word(w); 42 | #else 43 | return kissat_align_w2rd(w); 44 | #endif 45 | } 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /src/proprobe.c: -------------------------------------------------------------------------------- 1 | #include "fastassign.h" 2 | #include "proprobe.h" 3 | #include "trail.h" 4 | 5 | #define PROPAGATE_LITERAL probing_propagate_literal 6 | #define PROPAGATION_TYPE "probing" 7 | #define PROBING_PROPAGATION 8 | 9 | #include "proplit.h" 10 | 11 | clause *kissat_probing_propagate(kissat *solver, clause *ignore, bool flush) { 12 | assert(solver->probing); 13 | assert(solver->watching); 14 | assert(!solver->inconsistent); 15 | 16 | START(propagate); 17 | 18 | clause *conflict = 0; 19 | unsigned *propagate = solver->propagate; 20 | solver->ticks = 0; 21 | while (!conflict && propagate != END_ARRAY(solver->trail)) { 22 | const unsigned lit = *propagate++; 23 | conflict = probing_propagate_literal(solver, ignore, lit); 24 | } 25 | 26 | const unsigned propagated = propagate - solver->propagate; 27 | solver->propagate = propagate; 28 | kissat_update_probing_propagation_statistics(solver, propagated); 29 | kissat_update_conflicts_and_trail(solver, conflict, flush); 30 | 31 | STOP(propagate); 32 | 33 | return conflict; 34 | } 35 | -------------------------------------------------------------------------------- /src/cache.h: -------------------------------------------------------------------------------- 1 | #ifndef _cache_h_INCLUDED 2 | #define _cache_h_INCLUDED 3 | 4 | #include "bits.h" 5 | #include "stack.h" 6 | #include "value.h" 7 | 8 | #include 9 | #include 10 | 11 | struct kissat; 12 | 13 | typedef struct cache cache; 14 | typedef struct line line; 15 | 16 | struct line { 17 | unsigned vars; 18 | unsigned unsatisfied; 19 | uint64_t signature; 20 | uint64_t inserted; 21 | bits *bits; 22 | }; 23 | 24 | // *INDENT-OFF* 25 | 26 | typedef STACK (line*) lineptrs; 27 | typedef STACK (line) lines; 28 | 29 | // *INDENT-ON* 30 | 31 | #define kissat_size_ 32 | 33 | struct cache { 34 | bool valid; 35 | bool looked; 36 | unsigned vars; 37 | uint64_t inserted; 38 | size_t last_looked_up_position; 39 | lines lines; 40 | }; 41 | 42 | void kissat_clear_cache(struct kissat *); 43 | void kissat_release_cache(struct kissat *); 44 | bool kissat_insert_cache(struct kissat *, unsigned unsatisfied); 45 | void kissat_update_cache(struct kissat *, unsigned unsatisfied); 46 | bits *kissat_lookup_cache(struct kissat *); 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /src/phases.h: -------------------------------------------------------------------------------- 1 | #ifndef _phases_h_INCLUDED 2 | #define _phases_h_INCLUDED 3 | 4 | #include "value.h" 5 | 6 | typedef struct phases phases; 7 | 8 | struct phases { 9 | value *best; 10 | value *saved; 11 | value *target; 12 | }; 13 | 14 | #define BEST(IDX) \ 15 | (solver->phases.best[assert (VALID_INTERNAL_INDEX (IDX)), (IDX)]) 16 | 17 | #define SAVED(IDX) \ 18 | (solver->phases.saved[assert (VALID_INTERNAL_INDEX (IDX)), (IDX)]) 19 | 20 | #define TARGET(IDX) \ 21 | (solver->phases.target[assert (VALID_INTERNAL_INDEX (IDX)), (IDX)]) 22 | 23 | struct kissat; 24 | 25 | void kissat_increase_phases(struct kissat *, unsigned); 26 | void kissat_decrease_phases(struct kissat *, unsigned); 27 | void kissat_release_phases(struct kissat *); 28 | 29 | void kissat_save_best_phases(struct kissat *); 30 | void kissat_save_saved_phases(struct kissat *); 31 | void kissat_save_target_phases(struct kissat *); 32 | 33 | #define all_phases(NAME,PTR) \ 34 | value * PTR = solver->phases.NAME, * const end_ ## PTR = PTR + VARS; \ 35 | PTR != end_ ## PTR; \ 36 | ++PTR 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /test/testdump.c: -------------------------------------------------------------------------------- 1 | #include "test.h" 2 | 3 | static void test_dump(void) { 4 | printf("First generating and solving simple CNF:\n\n"); 5 | kissat *solver = kissat_init(); 6 | kissat_add(solver, 1); 7 | kissat_add(solver, -2); 8 | kissat_add(solver, 0); 9 | kissat_add(solver, -1); 10 | kissat_add(solver, 2); 11 | kissat_add(solver, 0); 12 | kissat_add(solver, 1); 13 | kissat_add(solver, 2); 14 | kissat_add(solver, 3); 15 | kissat_add(solver, 0); 16 | kissat_add(solver, 1); 17 | kissat_add(solver, 2); 18 | kissat_add(solver, -3); 19 | kissat_add(solver, 0); 20 | int res = kissat_solve(solver); 21 | assert(res == 10); 22 | int a = kissat_value(solver, 1); 23 | int b = kissat_value(solver, 2); 24 | assert(a > 0); 25 | assert(b > 0); 26 | #ifndef NDEBUG 27 | void dump(kissat *); 28 | printf("\nCompletely dumping solver:\n\n"); 29 | dump(solver); 30 | printf("\nDumping also vectors:\n\n"); 31 | void dump_vectors(kissat *); 32 | dump_vectors(solver); 33 | #endif 34 | kissat_release(solver); 35 | } 36 | 37 | void tissat_schedule_dump(void) { 38 | SCHEDULE_FUNCTION(test_dump); 39 | } 40 | -------------------------------------------------------------------------------- /src/literal.h: -------------------------------------------------------------------------------- 1 | #ifndef _literal_h_INCLUDED 2 | #define _literal_h_INCLUDED 3 | 4 | #include 5 | 6 | #define LD_MAX_VAR 28u 7 | 8 | #define EXTERNAL_MAX_VAR ((1<> 1)) 29 | 30 | #define LIT(IDX) \ 31 | (assert (VALID_INTERNAL_INDEX (IDX)), ((IDX) << 1)) 32 | 33 | #define NOT(LIT) \ 34 | (assert (VALID_INTERNAL_LITERAL (LIT)), ((LIT) ^ 1u)) 35 | 36 | #define NEGATED(LIT) \ 37 | (assert (VALID_INTERNAL_LITERAL (LIT)), ((LIT) & 1u)) 38 | 39 | #define STRIP(LIT) \ 40 | (assert (VALID_INTERNAL_LITERAL (LIT)), ((LIT) & ~1u)) 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /test/testadd.c: -------------------------------------------------------------------------------- 1 | #include "test.h" 2 | 3 | static word full_clauses; 4 | 5 | static void add_full_clauses(kissat *solver, int *clause, int i, int n) { 6 | assert(0 < i); 7 | assert(i <= n); 8 | for (int sign = -1; sign <= 1; sign += 2) { 9 | clause[i] = sign * i; 10 | if (i == n) { 11 | for (int j = 1; j <= i; j++) { 12 | kissat_add(solver, clause[j]); 13 | } 14 | kissat_add(solver, 0); 15 | full_clauses++; 16 | } else { 17 | add_full_clauses(solver, clause, i + 1, n); 18 | } 19 | } 20 | } 21 | 22 | static void test_add(void) { 23 | const int m = tissat_big ? 16 : 10; 24 | 25 | for (int n = 1; n < m; n++) { 26 | int clause[n + 1]; 27 | full_clauses = 0; 28 | kissat *solver = kissat_init(); 29 | add_full_clauses(solver, clause, 1, n); 30 | size_t arena = CAPACITY_STACK(solver->arena) * sizeof(word); 31 | printf("%d: arena %s clauses %s\n", n, 32 | kissat_format_bytes(&solver->format, arena), 33 | kissat_format_count(&solver->format, full_clauses)); 34 | kissat_release(solver); 35 | } 36 | } 37 | 38 | void tissat_schedule_add(void) { 39 | SCHEDULE_FUNCTION(test_add); 40 | } 41 | -------------------------------------------------------------------------------- /test/testconfig.c: -------------------------------------------------------------------------------- 1 | #ifndef NOPTIONS 2 | 3 | #include "../src/config.h" 4 | 5 | #include "test.h" 6 | 7 | static void test_config_has(void) { 8 | #define CONFIGURATION(NAME) \ 9 | assert (kissat_has_configuration (#NAME)); \ 10 | printf ("checked 'kissat_has_configuration (\"%s\")'\n", #NAME); 11 | CONFIGURATIONS 12 | #undef CONFIGURATION 13 | assert(!kissat_has_configuration("invalid")); 14 | printf("checked '!kissat_has_configuration (\"invalid\")'\n"); 15 | } 16 | 17 | static void test_config_set(void) { 18 | #define CONFIGURATION(NAME) \ 19 | do { \ 20 | DECLARE_AND_INIT_SOLVER (solver); \ 21 | assert (kissat_set_configuration (solver, #NAME)); \ 22 | printf ("checked 'kissat_set_configuration (..., \"%s\")'\n", #NAME); \ 23 | } while (0); 24 | CONFIGURATIONS 25 | #undef CONFIGURATION 26 | { 27 | DECLARE_AND_INIT_SOLVER(solver); 28 | assert(!kissat_set_configuration(solver, "invalid")); 29 | printf("checked '!kissat_set_configuration (..., \"invalid\")'\n"); 30 | } 31 | } 32 | #endif 33 | 34 | void tissat_schedule_config(void) { 35 | #ifndef NOPTIONS 36 | SCHEDULE_FUNCTION(test_config_has); 37 | SCHEDULE_FUNCTION(test_config_set); 38 | #endif 39 | } 40 | -------------------------------------------------------------------------------- /test/cnf/ph5.cnf: -------------------------------------------------------------------------------- 1 | p cnf 30 81 2 | -1 -6 0 3 | -1 -11 0 4 | -1 -16 0 5 | -1 -21 0 6 | -1 -26 0 7 | -6 -11 0 8 | -6 -16 0 9 | -6 -21 0 10 | -6 -26 0 11 | -11 -16 0 12 | -11 -21 0 13 | -11 -26 0 14 | -16 -21 0 15 | -16 -26 0 16 | -21 -26 0 17 | -2 -7 0 18 | -2 -12 0 19 | -2 -17 0 20 | -2 -22 0 21 | -2 -27 0 22 | -7 -12 0 23 | -7 -17 0 24 | -7 -22 0 25 | -7 -27 0 26 | -12 -17 0 27 | -12 -22 0 28 | -12 -27 0 29 | -17 -22 0 30 | -17 -27 0 31 | -22 -27 0 32 | -3 -8 0 33 | -3 -13 0 34 | -3 -18 0 35 | -3 -23 0 36 | -3 -28 0 37 | -8 -13 0 38 | -8 -18 0 39 | -8 -23 0 40 | -8 -28 0 41 | -13 -18 0 42 | -13 -23 0 43 | -13 -28 0 44 | -18 -23 0 45 | -18 -28 0 46 | -23 -28 0 47 | -4 -9 0 48 | -4 -14 0 49 | -4 -19 0 50 | -4 -24 0 51 | -4 -29 0 52 | -9 -14 0 53 | -9 -19 0 54 | -9 -24 0 55 | -9 -29 0 56 | -14 -19 0 57 | -14 -24 0 58 | -14 -29 0 59 | -19 -24 0 60 | -19 -29 0 61 | -24 -29 0 62 | -5 -10 0 63 | -5 -15 0 64 | -5 -20 0 65 | -5 -25 0 66 | -5 -30 0 67 | -10 -15 0 68 | -10 -20 0 69 | -10 -25 0 70 | -10 -30 0 71 | -15 -20 0 72 | -15 -25 0 73 | -15 -30 0 74 | -20 -25 0 75 | -20 -30 0 76 | -25 -30 0 77 | 5 4 3 2 1 0 78 | 10 9 8 7 6 0 79 | 15 14 13 12 11 0 80 | 20 19 18 17 16 0 81 | 25 24 23 22 21 0 82 | 30 29 28 27 26 0 83 | -------------------------------------------------------------------------------- /test/testutilities.c: -------------------------------------------------------------------------------- 1 | #include "test.h" 2 | 3 | #include "../src/utilities.h" 4 | 5 | void test_utilities_suffix(void) { 6 | assert(kissat_has_suffix("", "")); 7 | assert(kissat_has_suffix("a", "")); 8 | assert(!kissat_has_suffix("", "a")); 9 | assert(!kissat_has_suffix("b", "a")); 10 | assert(kissat_has_suffix("ba", "a")); 11 | assert(!kissat_has_suffix("ba", "ca")); 12 | assert(!kissat_has_suffix("a", "ba")); 13 | assert(kissat_has_suffix("cba", "")); 14 | assert(kissat_has_suffix("cba", "a")); 15 | assert(kissat_has_suffix("cba", "ba")); 16 | assert(kissat_has_suffix("cba", "cba")); 17 | assert(kissat_has_suffix("cba", "cba")); 18 | assert(!kissat_has_suffix("001", "000")); 19 | assert(!kissat_has_suffix("010", "000")); 20 | assert(!kissat_has_suffix("100", "000")); 21 | assert(!kissat_has_suffix("00001", "000")); 22 | assert(!kissat_has_suffix("00010", "000")); 23 | assert(!kissat_has_suffix("00100", "000")); 24 | assert(!kissat_has_suffix("cba", "dcba")); 25 | assert(!kissat_has_suffix("cba", "edcba")); 26 | assert(!kissat_has_suffix("cba", "fedcba")); 27 | } 28 | 29 | void tissat_schedule_utilities(void) { 30 | SCHEDULE_FUNCTION(test_utilities_suffix); 31 | } 32 | -------------------------------------------------------------------------------- /test/testreluctant.c: -------------------------------------------------------------------------------- 1 | #include "../src/reluctant.h" 2 | 3 | #include "test.h" 4 | 5 | static void test_reluctant(void) { 6 | reluctant dummy_reluctant, *reluctant = &dummy_reluctant; 7 | memset(reluctant, 0, sizeof * reluctant); 8 | #define LD_PERIOD (tissat_big ? 10 : 7) 9 | #define LD_LIMIT (LD_PERIOD + 6) 10 | #define LD_TICKS (LD_LIMIT + 6) 11 | #define PERIOD (1u< 6 | #include 7 | 8 | static void flush_buffer(chars *buffer) { 9 | fputs("v", stdout); 10 | for (all_stack(char, ch, *buffer)) { 11 | fputc(ch, stdout); 12 | } 13 | fputc('\n', stdout); 14 | CLEAR_STACK(*buffer); 15 | } 16 | 17 | static void print_int(kissat *solver, chars *buffer, int i) { 18 | char tmp[16]; 19 | sprintf(tmp, " %d", i); 20 | size_t tmp_len = strlen(tmp); 21 | size_t buf_len = SIZE_STACK(*buffer); 22 | if (buf_len + tmp_len > 77) { 23 | flush_buffer(buffer); 24 | } 25 | for (const char *p = tmp; *p; p++) { 26 | PUSH_STACK(*buffer, *p); 27 | } 28 | } 29 | 30 | void kissat_print_witness(kissat *solver, int max_var, bool partial) { 31 | chars buffer; 32 | INIT_STACK(buffer); 33 | for (int eidx = 1; eidx <= max_var; eidx++) { 34 | int tmp = kissat_value(solver, eidx); 35 | if (!tmp && !partial) { 36 | tmp = eidx; 37 | } 38 | if (tmp) { 39 | print_int(solver, &buffer, tmp); 40 | } 41 | } 42 | print_int(solver, &buffer, 0); 43 | assert(!EMPTY_STACK(buffer)); 44 | flush_buffer(&buffer); 45 | RELEASE_STACK(buffer); 46 | } 47 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The Kissat SAT Solver: 2 | Copyright (c) 2019-2021 Armin Biere, Johannes Kepler University Linz, Austria 3 | 4 | Kissat Extras Patches: 5 | Copyright (c) 2022 Jannis Harder 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | -------------------------------------------------------------------------------- /src/fastassign.h: -------------------------------------------------------------------------------- 1 | #ifndef _fastassign_h_INCLUDED 2 | #define _fastassign_h_INCLUDED 3 | 4 | #define FAST_ASSIGN 5 | 6 | #include "inline.h" 7 | #include "inlineassign.h" 8 | 9 | static inline void kissat_fast_binary_assign(kissat *solver, 10 | const bool probing, const unsigned level, 11 | value *values, assigned *assigned, 12 | bool redundant, unsigned lit, unsigned other) { 13 | kissat_fast_assign(solver, probing, level, values, assigned, 14 | true, redundant, lit, other); 15 | LOGBINARY(lit, other, "assign %s %s reason", 16 | LOGLIT(lit), redundant ? "redundant" : "irredundant"); 17 | } 18 | 19 | static inline void kissat_fast_assign_reference(kissat *solver, 20 | value *values, assigned *assigned, 21 | unsigned lit, reference ref, clause *reason) { 22 | assert(reason == kissat_dereference_clause(solver, ref)); 23 | const unsigned level = 24 | kissat_assignment_level(solver, values, assigned, lit, reason); 25 | assert(level <= solver->level); 26 | assert(ref != DECISION_REASON); 27 | assert(ref != UNIT_REASON); 28 | kissat_fast_assign(solver, solver->probing, level, 29 | values, assigned, false, false, lit, ref); 30 | LOGREF(ref, "assign %s reason", LOGLIT(lit)); 31 | } 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /src/vector.h: -------------------------------------------------------------------------------- 1 | #ifndef _vector_h_INCLUDED 2 | #define _vector_h_INCLUDED 3 | 4 | #include "stack.h" 5 | #include "utilities.h" 6 | 7 | #include 8 | 9 | #ifdef COMPACT 10 | #define LD_MAX_VECTORS (sizeof (word) == 8 ? 32u : 28u) 11 | #else 12 | #define LD_MAX_VECTORS (sizeof (word) == 8 ? 48u : 28u) 13 | #endif 14 | 15 | #define MAX_VECTORS (((uint64_t) 1) << LD_MAX_VECTORS) 16 | 17 | #define INVALID_VECTOR_ELEMENT UINT_MAX 18 | 19 | #define MAX_SECTOR MAX_SIZE_T 20 | 21 | typedef struct vector vector; 22 | typedef struct vectors vectors; 23 | 24 | struct vectors { 25 | unsigneds stack; 26 | size_t usable; 27 | }; 28 | 29 | struct vector { 30 | #ifdef COMPACT 31 | unsigned offset; 32 | unsigned size; 33 | #else 34 | unsigned *begin; 35 | unsigned *end; 36 | #endif 37 | }; 38 | 39 | struct kissat; 40 | 41 | #ifdef CHECK_VECTORS 42 | void kissat_check_vectors(struct kissat *); 43 | #else 44 | #define kissat_check_vectors(...) do { } while (0) 45 | #endif 46 | 47 | unsigned *kissat_enlarge_vector(struct kissat *, vector *); 48 | void kissat_defrag_vectors(struct kissat *, size_t, vector *); 49 | void kissat_remove_from_vector(struct kissat *, vector *, unsigned); 50 | void kissat_resize_vector(struct kissat *, vector *, size_t); 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /src/flags.h: -------------------------------------------------------------------------------- 1 | #ifndef _flags_h_INCLUDED 2 | #define _flags_h_INCLUDED 3 | 4 | #include 5 | 6 | typedef struct flags flags; 7 | 8 | struct flags { 9 | bool active: 1; 10 | bool backbone0: 1; 11 | bool backbone1: 1; 12 | bool eliminate: 1; 13 | bool eliminated: 1; 14 | bool fixed: 1; 15 | bool probe: 1; 16 | bool subsume: 1; 17 | bool sweep: 1; 18 | bool transitive: 1; 19 | int assumed: 2; 20 | }; 21 | 22 | #define FLAGS(IDX) \ 23 | (assert ((IDX) < VARS), (solver->flags + (IDX))) 24 | 25 | #define ACTIVE(IDX) (FLAGS(IDX)->active) 26 | #define ELIMINATED(IDX) (FLAGS(IDX)->eliminated) 27 | 28 | struct kissat; 29 | 30 | void kissat_activate_literal(struct kissat *, unsigned); 31 | void kissat_activate_literals(struct kissat *, unsigned, unsigned *); 32 | 33 | void kissat_mark_eliminated_variable(struct kissat *, unsigned idx); 34 | void kissat_mark_substituted_variable(struct kissat *solver, 35 | unsigned idx, unsigned replacement_lit); 36 | void kissat_mark_fixed_literal(struct kissat *, unsigned lit); 37 | void kissat_mark_autarkic_literal(struct kissat *, unsigned lit); 38 | 39 | void kissat_mark_added_literals(struct kissat *, unsigned, unsigned *); 40 | void kissat_mark_removed_literals(struct kissat *, unsigned, unsigned *); 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /src/random.h: -------------------------------------------------------------------------------- 1 | #ifndef _random_h_INCLUDED 2 | #define _random_h_INCLUDED 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | typedef uint64_t generator; 9 | 10 | static inline uint64_t kissat_next_random64(generator *rng) { 11 | *rng *= 6364136223846793005ul; 12 | *rng += 1442695040888963407ul; 13 | return *rng; 14 | } 15 | 16 | static inline unsigned kissat_next_random32(generator *rng) { 17 | return kissat_next_random64(rng) >> 32; 18 | } 19 | 20 | static inline unsigned kissat_pick_random(generator *rng, unsigned l, 21 | unsigned r) { 22 | assert(l <= r); 23 | if (l == r) { 24 | return l; 25 | } 26 | const unsigned delta = r - l; 27 | const unsigned tmp = kissat_next_random32(rng); 28 | const double fraction = tmp / 4294967296.0; 29 | assert(0 <= fraction), assert(fraction < 1); 30 | const unsigned scaled = delta * fraction; 31 | assert(scaled < delta); 32 | const unsigned res = l + scaled; 33 | assert(l <= res), assert(res < r); 34 | return res; 35 | } 36 | 37 | static inline bool kissat_pick_bool(generator *rng) { 38 | return kissat_pick_random(rng, 0, 2); 39 | } 40 | 41 | static inline double kissat_pick_double(generator *rng) { 42 | return kissat_next_random32(rng) / 4294967296.0; 43 | } 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /scripts/generate-build-header.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | script=`basename $0` 3 | die () { 4 | echo "$script: error: $*" 1>&2 5 | exit 1 6 | } 7 | [ -f makefile ] || die "no 'makefile' (run './configure' first)" 8 | CC="`sed -e '/^CC/!d' -e 's,^CC=,,' makefile`" 9 | [ "$CC" = "" ] && die "could not get 'CC' from makefile" 10 | case "$CC" in 11 | gcc*|clang*) 12 | CFLAGS="`echo $CC|sed -e 's,^[^ ]* ,,'`" 13 | CC="`echo $CC|awk '{print \$1}'`" 14 | CC="`$CC --version 2>/dev/null|head -1`" 15 | ;; 16 | esac 17 | COMPILER="$CC $CFLAGS" 18 | VERSION="`cat ../VERSION 2>/dev/null`" 19 | [ "$VERSION" = "" ] && die "could not get 'VERSION'" 20 | cat <marks; 13 | unsigned not_lit = NOT(lit); 14 | watches *watches = &WATCHES(not_lit); 15 | unsigned replace = INVALID_LIT; 16 | for (all_binary_large_watches(watch, *watches)) { 17 | if (!watch.type.binary) { 18 | continue; 19 | } 20 | const unsigned other = watch.binary.lit; 21 | const unsigned not_other = NOT(other); 22 | if (!marks[not_other]) { 23 | continue; 24 | } 25 | replace = other; 26 | break; 27 | } 28 | kissat_unmark_binaries(solver, lit); 29 | if (replace == INVALID_LIT) { 30 | return false; 31 | } 32 | LOG("found equivalence gate %s = %s", LOGLIT(lit), LOGLIT(replace)); 33 | solver->found_equivalence = replace; 34 | 35 | const watch watch1 = kissat_binary_watch(replace, false, false); 36 | PUSH_STACK(solver->gates[1], watch1); 37 | 38 | const watch watch0 = kissat_binary_watch(NOT(replace), false, false); 39 | PUSH_STACK(solver->gates[0], watch0); 40 | solver->gate_eliminated = GATE_ELIMINATED(equivalences); 41 | INC(equivalences_extracted); 42 | return true; 43 | } 44 | -------------------------------------------------------------------------------- /src/array.h: -------------------------------------------------------------------------------- 1 | #ifndef _array_h_INCLUDED 2 | #define _array_h_INCLUDED 3 | 4 | #include "allocate.h" 5 | #include "stack.h" 6 | 7 | #define ARRAY(TYPE) \ 8 | struct { TYPE * begin; TYPE * end; } 9 | 10 | #define ALLOCATE_ARRAY(A,N) \ 11 | do { \ 12 | const size_t TMP_N = (N); \ 13 | (A).begin = (A).end = kissat_nalloc (solver, TMP_N, sizeof *(A).begin); \ 14 | } while (0) 15 | 16 | #define EMPTY_ARRAY EMPTY_STACK 17 | #define SIZE_ARRAY SIZE_STACK 18 | 19 | #define PUSH_ARRAY(A,E) \ 20 | do { \ 21 | *(A).end++ = (E); \ 22 | } while (0) 23 | 24 | #define REALLOCATE_ARRAY(A,O,N) \ 25 | do { \ 26 | const size_t SIZE = SIZE_ARRAY (A); \ 27 | (A).begin = kissat_nrealloc (solver, (A).begin, \ 28 | (O), (N), sizeof *(A).begin); \ 29 | (A).end = (A).begin + SIZE; \ 30 | } while (0) 31 | 32 | #define RELEASE_ARRAY(A,N) \ 33 | do { \ 34 | const size_t TMP_NIZE = (N); \ 35 | DEALLOC((A).begin, TMP_NIZE); \ 36 | } while (0) 37 | 38 | #define CLEAR_ARRAY CLEAR_STACK 39 | #define TOP_ARRAY TOP_STACK 40 | #define PEEK_ARRAY PEEK_STACK 41 | #define POKE_ARRAY POKE_STACK 42 | #define POP_ARRAY POP_STACK 43 | #define BEGIN_ARRAY BEGIN_STACK 44 | #define END_ARRAY END_STACK 45 | #define RESIZE_ARRAY RESIZE_STACK 46 | #define SET_END_OF_ARRAY SET_END_OF_STACK 47 | 48 | // *INDENT-OFF* 49 | 50 | typedef ARRAY (unsigned) unsigned_array; 51 | 52 | // *INDENT-ON* 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /src/format.h: -------------------------------------------------------------------------------- 1 | #ifndef _format_h_INCLUDED 2 | #define _format_h_INCLUDED 3 | 4 | #include "utilities.h" 5 | 6 | #include 7 | #include 8 | 9 | #define NUM_FORMAT_STRINGS 8 10 | #define FORMAT_STRING_SIZE 128 11 | 12 | typedef struct format format; 13 | 14 | struct format { 15 | unsigned pos; 16 | char str[NUM_FORMAT_STRINGS][FORMAT_STRING_SIZE]; 17 | }; 18 | 19 | char *kissat_next_format_string(format *); 20 | 21 | char const *kissat_format_bytes(format *, uint64_t bytes); 22 | char const *kissat_format_count(format *, uint64_t); 23 | char const *kissat_format_ordinal(format *, uint64_t); 24 | char const *kissat_format_signs(format *, unsigned size, word); 25 | char const *kissat_format_time(format *, double seconds); 26 | char const *kissat_format_value(format *, bool boolean, int value); 27 | 28 | #define FORMAT_BYTES(BYTES) \ 29 | kissat_format_bytes (&solver->format, BYTES) 30 | 31 | #define FORMAT_COUNT(WORD) \ 32 | kissat_format_count (&solver->format, WORD) 33 | 34 | #define FORMAT_ORDINAL(WORD) \ 35 | kissat_format_ordinal (&solver->format, WORD) 36 | 37 | #define FORMAT_SIGNS(SIZE, SIGNS) \ 38 | kissat_format_signs (&solver->format, SIZE, SIGNS) 39 | 40 | #define FORMAT_TIME(SECONDS) \ 41 | kissat_format_time (&solver->format, SECONDS) 42 | 43 | #define FORMAT_VALUE(BOOLEAN,VALUE) \ 44 | kissat_format_value (&solver->format, BOOLEAN, VALUE) 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /src/main.c: -------------------------------------------------------------------------------- 1 | #include "application.h" 2 | #include "cover.h" 3 | #include "handle.h" 4 | #include "kissat.h" 5 | #include "print.h" 6 | 7 | #include 8 | #include 9 | 10 | static kissat *volatile solver; 11 | 12 | // *INDENT-OFF* 13 | 14 | static void 15 | kissat_signal_handler (int sig) 16 | { 17 | kissat_signal (solver, "caught", sig); 18 | kissat_print_statistics (solver); 19 | kissat_signal (solver, "raising", sig); 20 | #ifdef QUIET 21 | (void) sig; 22 | #endif 23 | FLUSH_COVERAGE (); } // Keep this '}' in the same line! 24 | 25 | // *INDENT-ON* 26 | 27 | static volatile bool ignore_alarm = false; 28 | 29 | static void kissat_alarm_handler(void) { 30 | if (ignore_alarm) { 31 | return; 32 | } 33 | assert(solver); 34 | kissat_terminate(solver); 35 | } 36 | 37 | #ifndef NDEBUG 38 | extern int dump(kissat *); 39 | #endif 40 | 41 | #include "random.h" 42 | #include "error.h" 43 | #include 44 | 45 | int main(int argc, char **argv) { 46 | int res; 47 | solver = kissat_init(); 48 | kissat_set_option(solver, "incremental", 0); 49 | kissat_init_alarm(kissat_alarm_handler); 50 | kissat_init_signal_handler(kissat_signal_handler); 51 | res = kissat_application(solver, argc, argv); 52 | kissat_reset_signal_handler(); 53 | ignore_alarm = true; 54 | kissat_reset_alarm(); 55 | kissat_release(solver); 56 | #ifndef NDEBUG 57 | if (!res) { 58 | return dump(0); 59 | } 60 | #endif 61 | return res; 62 | } 63 | -------------------------------------------------------------------------------- /src/assign.h: -------------------------------------------------------------------------------- 1 | #ifndef _assign_h_INCLUDED 2 | #define _assign_h_INCLUDED 3 | 4 | #include 5 | 6 | #define DECISION_REASON UINT_MAX 7 | #define UNIT_REASON (DECISION_REASON - 1) 8 | 9 | #define INVALID_LEVEL UINT_MAX 10 | 11 | #define MAX_LEVEL ((1u<<28)-1) 12 | #define MAX_TRAIL ((1u<<30)-1) 13 | 14 | typedef struct assigned assigned; 15 | struct clause; 16 | 17 | struct assigned { 18 | unsigned level: 28; 19 | 20 | bool analyzed: 1; 21 | bool poisoned: 1; 22 | bool removable: 1; 23 | bool shrinkable: 1; 24 | 25 | unsigned trail: 30; 26 | 27 | bool binary: 1; 28 | bool redundant: 1; 29 | 30 | unsigned reason; 31 | }; 32 | 33 | #define ASSIGNED(LIT) \ 34 | (assert (VALID_INTERNAL_LITERAL (LIT)), \ 35 | solver->assigned + IDX (LIT)) 36 | 37 | #define LEVEL(LIT) \ 38 | (ASSIGNED(LIT)->level) 39 | 40 | #define REASON(LIT) \ 41 | (ASSIGNED(LIT)->reason) 42 | 43 | #ifndef FAST_ASSIGN 44 | 45 | #include "reference.h" 46 | 47 | struct kissat; 48 | struct clause; 49 | 50 | void kissat_assign_unit(struct kissat *, unsigned lit, const char *); 51 | void kissat_learned_unit(struct kissat *, unsigned lit); 52 | void kissat_original_unit(struct kissat *, unsigned lit); 53 | 54 | void kissat_assign_decision(struct kissat *, unsigned lit); 55 | 56 | void kissat_assign_binary(struct kissat *, bool, unsigned, unsigned); 57 | 58 | void kissat_assign_reference(struct kissat *, unsigned lit, 59 | reference, struct clause *); 60 | 61 | #endif 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /src/kitten.h: -------------------------------------------------------------------------------- 1 | #ifndef _kitten_h_INCLUDED 2 | #define _kitten_h_INCLUDED 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | typedef struct kitten kitten; 9 | 10 | kitten *kitten_init(void); 11 | void kitten_clear(kitten *); 12 | void kitten_release(kitten *); 13 | 14 | void kitten_track_antecedents(kitten *); 15 | void kitten_shuffle_clauses(kitten *); 16 | void kitten_randomize_phases(kitten *); 17 | void kitten_flip_phases(kitten *); 18 | 19 | void kitten_assume(kitten *, unsigned lit); 20 | 21 | void kitten_clause(kitten *, size_t size, unsigned *); 22 | void kitten_unit(kitten *, unsigned); 23 | void kitten_binary(kitten *, unsigned, unsigned); 24 | 25 | void kitten_clause_with_id_and_exception(kitten *, unsigned id, 26 | size_t size, const unsigned *, 27 | unsigned except); 28 | 29 | 30 | void kitten_set_ticks_limit(kitten *, uint64_t); 31 | 32 | int kitten_solve(kitten *); 33 | 34 | signed char kitten_value(kitten *, unsigned); 35 | bool kitten_failed(kitten *, unsigned); 36 | 37 | unsigned kitten_compute_clausal_core(kitten *, uint64_t *learned); 38 | void kitten_shrink_to_clausal_core(kitten *); 39 | 40 | void kitten_traverse_core_ids(kitten *, void *state, 41 | void (*traverse)(void *state, unsigned id)); 42 | 43 | void kitten_traverse_core_clauses(kitten *, void *state, 44 | void (*traverse)(void *state, 45 | bool learned, size_t, 46 | const unsigned *)); 47 | struct kissat; 48 | kitten *kitten_embedded(struct kissat *); 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /src/error.c: -------------------------------------------------------------------------------- 1 | #include "colors.h" 2 | #include "cover.h" 3 | #include "error.h" 4 | 5 | #include 6 | #include 7 | 8 | static void (*kissat_abort_function)(void); 9 | 10 | void kissat_call_function_instead_of_abort(void (*f)(void)) { 11 | kissat_abort_function = f; 12 | } 13 | 14 | // *INDENT-OFF* 15 | 16 | void 17 | kissat_abort (void) 18 | { 19 | if (kissat_abort_function) 20 | { FLUSH_COVERAGE (); kissat_abort_function (); } // Keep all in this line. 21 | else 22 | { FLUSH_COVERAGE (); abort (); } // Keep all in this line. 23 | } 24 | 25 | // *INDENT-ON* 26 | 27 | static void typed_error_message_start(const char *type) { 28 | fflush(stdout); 29 | TERMINAL(stderr, 2); 30 | COLOR(BOLD); 31 | fputs("kissat: ", stderr); 32 | COLOR(RED); 33 | fputs(type, stderr); 34 | fputs(": ", stderr); 35 | COLOR(NORMAL); 36 | } 37 | 38 | void kissat_fatal_message_start(void) { 39 | typed_error_message_start("fatal error"); 40 | } 41 | 42 | static void vprint_error(const char *type, const char *fmt, va_list *ap) { 43 | typed_error_message_start(type); 44 | vfprintf(stderr, fmt, *ap); 45 | fputc('\n', stderr); 46 | fflush(stderr); 47 | } 48 | 49 | void kissat_error(const char *fmt, ...) { 50 | va_list ap; 51 | va_start(ap, fmt); 52 | vprint_error("error", fmt, &ap); 53 | va_end(ap); 54 | } 55 | 56 | void kissat_fatal(const char *fmt, ...) { 57 | va_list ap; 58 | va_start(ap, fmt); 59 | vprint_error("fatal error", fmt, &ap); 60 | va_end(ap); 61 | kissat_abort(); 62 | } 63 | -------------------------------------------------------------------------------- /src/promote.c: -------------------------------------------------------------------------------- 1 | #include "internal.h" 2 | #include "logging.h" 3 | #include "promote.h" 4 | 5 | void kissat_promote_clause(kissat *solver, clause *c, unsigned new_glue) { 6 | if (!GET_OPTION(promote)) { 7 | return; 8 | } 9 | assert(!c->keep); 10 | assert(c->redundant); 11 | const unsigned old_glue = c->glue; 12 | assert(new_glue < old_glue); 13 | const unsigned tier1 = GET_OPTION(tier1); 14 | const unsigned tier2 = MAX(GET_OPTION(tier2), GET_OPTION(tier1)); 15 | if (c->hyper) { 16 | LOGCLS(c, "promoting to new glue %u", new_glue); 17 | } else if (new_glue <= tier1) { 18 | assert(tier1 < old_glue); 19 | assert(new_glue <= tier1); 20 | LOGCLS(c, "promoting to new glue %u to tier1", new_glue); 21 | INC(clauses_promoted1); 22 | c->keep = true; 23 | } else if (old_glue > tier2 && new_glue <= tier2) { 24 | assert(tier2 < old_glue); 25 | assert(tier1 < new_glue && new_glue <= tier2); 26 | LOGCLS(c, "promoting to new glue %u to tier2", new_glue); 27 | INC(clauses_promoted2); 28 | c->used = 2; 29 | } else if (old_glue <= tier2) { 30 | INC(clauses_kept2); 31 | assert(tier1 < old_glue && old_glue <= tier2); 32 | assert(tier1 < new_glue && new_glue <= tier2); 33 | LOGCLS(c, "keeping to new glue %u in tier2", new_glue); 34 | } else { 35 | INC(clauses_kept3); 36 | assert(tier2 < old_glue); 37 | assert(tier2 < new_glue); 38 | LOGCLS(c, "keeping to new glue %u in tier3", new_glue); 39 | } 40 | INC(clauses_improved); 41 | c->glue = new_glue; 42 | #ifndef LOGGING 43 | (void) solver; 44 | #endif 45 | } 46 | -------------------------------------------------------------------------------- /src/print.h: -------------------------------------------------------------------------------- 1 | #ifndef _print_h_INCLUDED 2 | #define _print_h_INCLUDED 3 | 4 | #ifndef QUIET 5 | 6 | #include 7 | 8 | #include "attribute.h" 9 | 10 | struct kissat; 11 | 12 | int kissat_verbosity(struct kissat *); 13 | 14 | void kissat_line(struct kissat *); 15 | void kissat_signal(struct kissat *, const char *type, int sig); 16 | void kissat_section(struct kissat *, const char *name); 17 | 18 | // *INDENT-OFF* 19 | 20 | void 21 | kissat_message (struct kissat *, const char *fmt, ...) 22 | ATTRIBUTE_FORMAT (2, 3); 23 | 24 | void kissat_verbose (struct kissat *, const char *fmt, ...) 25 | ATTRIBUTE_FORMAT (2, 3); 26 | 27 | void kissat_very_verbose (struct kissat *, const char *fmt, ...) 28 | ATTRIBUTE_FORMAT (2, 3); 29 | 30 | void kissat_extremely_verbose (struct kissat *, const char *fmt, ...) 31 | ATTRIBUTE_FORMAT (2, 3); 32 | 33 | void kissat_warning (struct kissat *, const char *fmt, ...) 34 | ATTRIBUTE_FORMAT (2, 3); 35 | 36 | void kissat_phase (struct kissat *, const char *name, uint64_t, 37 | const char * fmt, ...) 38 | ATTRIBUTE_FORMAT (4, 5); 39 | 40 | // *INDENT-ON* 41 | 42 | #else 43 | 44 | #define kissat_line(...) do { } while (0) 45 | #define kissat_message(...) do { } while (0) 46 | #define kissat_phase(...) do { } while (0) 47 | #define kissat_section(...) do { } while (0) 48 | #define kissat_signal(...) do { } while (0) 49 | #define kissat_verbose(...) do { } while (0) 50 | #define kissat_very_verbose(...) do { } while (0) 51 | #define kissat_extremely_verbose(...) do { } while (0) 52 | #define kissat_warning(...) do { } while (0) 53 | 54 | #endif 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /src/kissat.h: -------------------------------------------------------------------------------- 1 | #ifndef _kissat_h_INCLUDED 2 | #define _kissat_h_INCLUDED 3 | 4 | #define KISSAT_EXTRAS 5 | 6 | typedef struct kissat kissat; 7 | 8 | // Default (partial) IPASIR interface. 9 | 10 | const char *kissat_signature(void); 11 | kissat *kissat_init(void); 12 | void kissat_add(kissat *solver, int lit); 13 | void kissat_assume(kissat *solver, int lit); 14 | int kissat_solve(kissat *solver); 15 | int kissat_value(kissat *solver, int lit); 16 | int kissat_failed(kissat *solver, int lit); 17 | void kissat_release(kissat *solver); 18 | 19 | void kissat_set_terminate(kissat *solver, 20 | void *state, int (*terminate)(void *state)); 21 | 22 | // Additional API functions. 23 | 24 | void kissat_protect(kissat *solver, int var); 25 | void kissat_unprotect(kissat *solver, int var); 26 | 27 | void kissat_terminate(kissat *solver); 28 | void kissat_reserve(kissat *solver, int max_var); 29 | 30 | const char *kissat_id(void); 31 | const char *kissat_version(void); 32 | const char *kissat_compiler(void); 33 | 34 | const char *kissat_copyright(void); 35 | void kissat_build(const char *line_prefix); 36 | void kissat_banner(const char *line_prefix, const char *name_of_app); 37 | 38 | int kissat_get_option(kissat *solver, const char *name); 39 | int kissat_set_option(kissat *solver, const char *name, int new_value); 40 | 41 | int kissat_has_configuration(const char *name); 42 | int kissat_set_configuration(kissat *solver, const char *name); 43 | 44 | void kissat_set_conflict_limit(kissat *solver, unsigned); 45 | void kissat_set_decision_limit(kissat *solver, unsigned); 46 | 47 | void kissat_print_statistics(kissat *solver); 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /test/testarray.c: -------------------------------------------------------------------------------- 1 | #include "test.h" 2 | 3 | #include "../src/array.h" 4 | 5 | typedef struct pair pair; 6 | 7 | struct pair { 8 | unsigned first; 9 | unsigned second; 10 | }; 11 | 12 | static void test_array_basic(void) { 13 | DECLARE_AND_INIT_SOLVER(solver); 14 | ARRAY(pair) array; 15 | memset(&array, 0, sizeof array); 16 | assert(EMPTY_ARRAY(array)); 17 | size_t size = 0; 18 | unsigned sum = 0; 19 | for (unsigned l = 0; l <= 10; l++) { 20 | size_t new_size = 1u << l; 21 | REALLOCATE_ARRAY(array, size, new_size); 22 | for (unsigned i = 0; i < size; i++) { 23 | pair pair = PEEK_ARRAY(array, i); 24 | assert(pair.first == i); 25 | assert(pair.second == ~i); 26 | } 27 | for (unsigned i = size; i < new_size; i++) { 28 | pair pair; 29 | pair.first = i; 30 | pair.second = ~i; 31 | PUSH_ARRAY(array, pair); 32 | sum += i; 33 | } 34 | assert(!EMPTY_ARRAY(array)); 35 | assert(SIZE_ARRAY(array) == new_size); 36 | size = new_size; 37 | } 38 | pair *a = BEGIN_ARRAY(array); 39 | for (unsigned i = 0; i < size; i++) { 40 | pair *p = &a[i]; 41 | SWAP(unsigned, p->first, p->second); 42 | } 43 | for (all_stack(pair, pair, array)) { 44 | sum -= pair.second; 45 | } 46 | assert(!sum); 47 | for (unsigned expect = size - 1; !EMPTY_ARRAY(array); expect--) { 48 | pair pair = POP_ARRAY(array); 49 | assert(pair.first == ~expect); 50 | assert(pair.second == expect); 51 | } 52 | RELEASE_ARRAY(array, size); 53 | #ifdef METRICS 54 | assert(!solver->statistics.allocated_current); 55 | #endif 56 | } 57 | 58 | void tissat_schedule_array(void) { 59 | SCHEDULE_FUNCTION(test_array_basic); 60 | } 61 | -------------------------------------------------------------------------------- /test/testsolve.c: -------------------------------------------------------------------------------- 1 | #include "../src/file.h" 2 | 3 | #include "test.h" 4 | #include "testcnfs.h" 5 | 6 | static unsigned scheduled; 7 | 8 | static void schedule_solve_job_with_option(int expected, 9 | const char *opt, const char *path) { 10 | if (!kissat_file_readable(path)) { 11 | tissat_warning("Skipping unreadable '%s'", path); 12 | return; 13 | } 14 | char cmd[256]; 15 | assert(strlen(path) + strlen(opt) + 32 < sizeof cmd); 16 | sprintf(cmd, "%s%s", opt, path); 17 | assert(strlen(cmd) < sizeof cmd); 18 | tissat_schedule_application(expected, cmd); 19 | scheduled++; 20 | } 21 | 22 | static const char *simps[] = { 23 | "", 24 | #ifndef NOPTIONS 25 | "--eliminateinit=0 ", 26 | "--probeinit=0 ", 27 | "--reduceinit=10 --rephaseinit=10 --rephaseint=10 ", 28 | "--incremental ", 29 | "--walkinitially ", 30 | #endif 31 | }; 32 | 33 | static const char **end_of_simps = simps + sizeof(simps) / sizeof * simps; 34 | 35 | static void schedule_solve_job(int expected, const char *path) { 36 | for (const char **p = simps; p != end_of_simps; p++) { 37 | char combined[128]; 38 | if (tissat_big) { 39 | for (all_tissat_options(opt)) { 40 | sprintf(combined, *p, opt); 41 | schedule_solve_job_with_option(expected, combined, path); 42 | } 43 | } else { 44 | const char *opt = tissat_next_option(scheduled); 45 | sprintf(combined, *p, opt); 46 | schedule_solve_job_with_option(expected, combined, path); 47 | } 48 | } 49 | } 50 | 51 | void tissat_schedule_solve(void) { 52 | #define CNF(EXPECTED,NAME,BIG) \ 53 | if (!BIG || tissat_big) \ 54 | schedule_solve_job (EXPECTED, "../test/cnf/" #NAME ".cnf"); 55 | CNFS 56 | #undef CNF 57 | } 58 | -------------------------------------------------------------------------------- /test/cover/cover0039.cnf: -------------------------------------------------------------------------------- 1 | c status 10 2 | c --autarky=0 3 | c --eagersubsume=0 4 | c --failedmineff=0 5 | c --focus=0 6 | c --probeinit=2 7 | c --probeint=0 8 | c --reduceinit=0 9 | c --reduceint=0 10 | c --rephaseinit=13 11 | c --vivifymineff=0 12 | p cnf 91 102 13 | -10 1 9 0 14 | 6 4 0 15 | 8 -3 0 16 | -19 -16 0 17 | 16 -13 14 0 18 | 17 1 0 19 | 23 -12 5 0 20 | 18 1 0 21 | 12 19 0 22 | 21 3 0 23 | 7 35 0 24 | 20 33 0 25 | 30 24 0 26 | 36 4 0 27 | 26 1 0 28 | -23 37 31 0 29 | 45 8 0 30 | 13 -44 0 31 | 39 46 0 32 | -48 -9 47 0 33 | 25 2 0 34 | -37 50 0 35 | 48 12 0 36 | 28 5 0 37 | 43 40 42 0 38 | -35 52 0 39 | 51 49 0 40 | -6 -5 0 41 | 29 54 0 42 | -1 -6 34 0 43 | 27 15 0 44 | -52 44 0 45 | 41 55 0 46 | -47 -53 0 47 | 11 38 0 48 | 63 -57 0 49 | 64 58 0 50 | 7 22 0 51 | -63 5 -47 0 52 | -62 -50 0 53 | 61 -59 0 54 | 32 60 0 55 | 6 59 0 56 | 58 14 62 0 57 | -64 -52 0 58 | -7 -64 -62 0 59 | -6 73 0 60 | 57 -56 0 61 | -62 68 0 62 | -34 0 63 | -4 -72 0 64 | -14 -70 0 65 | 3 -55 0 66 | 51 3 0 67 | 53 68 0 68 | -31 0 69 | 68 61 0 70 | 72 -68 -51 0 71 | 4 -71 0 72 | -12 66 -69 0 73 | 62 -72 0 74 | 69 -70 67 -61 0 75 | 78 -80 0 76 | -65 -59 0 77 | -79 -84 0 78 | 3 75 0 79 | 85 36 0 80 | -67 79 0 81 | 77 -58 0 82 | 4 -81 0 83 | -78 -76 0 84 | 60 -85 0 85 | -83 -82 0 86 | 69 62 -4 0 87 | -74 56 0 88 | -66 -77 0 89 | 73 -60 0 90 | 83 -62 84 0 91 | -58 75 -1 0 92 | -71 72 0 93 | -68 -60 0 94 | -59 52 0 95 | -3 -80 0 96 | -73 80 61 0 97 | -61 74 0 98 | -8 82 0 99 | 71 -65 -74 0 100 | 84 -73 0 101 | 4 55 0 102 | -81 -58 0 103 | 87 3 0 104 | -81 85 0 105 | -89 -75 65 0 106 | 5 86 0 107 | 2 0 108 | 63 90 0 109 | 91 5 0 110 | 9 88 0 111 | -90 -87 0 112 | -24 0 113 | 70 78 0 114 | 86 0 115 | -------------------------------------------------------------------------------- /src/file.h: -------------------------------------------------------------------------------- 1 | #ifndef _file_h_INCLUDED 2 | #define _file_h_INCLUDED 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | bool kissat_file_exists(const char *path); 10 | bool kissat_file_readable(const char *path); 11 | bool kissat_file_writable(const char *path); 12 | size_t kissat_file_size(const char *path); 13 | bool kissat_find_executable(const char *name); 14 | 15 | typedef struct file file; 16 | 17 | struct file { 18 | FILE *file; 19 | bool close; 20 | bool reading; 21 | bool compressed; 22 | const char *path; 23 | uint64_t bytes; 24 | }; 25 | 26 | void kissat_read_already_open_file(file *, FILE *, const char *path); 27 | void kissat_write_already_open_file(file *, FILE *, const char *path); 28 | 29 | bool kissat_open_to_read_file(file *, const char *path); 30 | bool kissat_open_to_write_file(file *, const char *path); 31 | 32 | void kissat_close_file(file *); 33 | 34 | #ifndef _POSIX_C_SOURCE 35 | 36 | bool kissat_looks_like_a_compressed_file(const char *path); 37 | 38 | #endif 39 | 40 | static inline int kissat_getc(file *file) { 41 | assert(file); 42 | assert(file->file); 43 | assert(file->reading); 44 | #ifdef _POSIX_C_SOURCE 45 | int res = getc_unlocked(file->file); 46 | #else 47 | int res = getc(file->file); 48 | #endif 49 | if (res != EOF) { 50 | file->bytes++; 51 | } 52 | return res; 53 | } 54 | 55 | static inline int kissat_putc(file *file, int ch) { 56 | assert(file); 57 | assert(file->file); 58 | assert(!file->reading); 59 | #ifdef _POSIX_C_SOURCE 60 | int res = putc_unlocked(ch, file->file); 61 | #else 62 | int res = putc(ch, file->file); 63 | #endif 64 | if (res != EOF) { 65 | file->bytes++; 66 | } 67 | return ch; 68 | } 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /src/colors.h: -------------------------------------------------------------------------------- 1 | #ifndef _colors_h_INCLUDED 2 | #define _colors_h_INCLUDED 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #define BLUE "\033[34m" 9 | #define BOLD "\033[1m" 10 | #define CYAN "\033[36m" 11 | #define GREEN "\033[32m" 12 | #define MAGENTA "\033[35m" 13 | #define NORMAL "\033[0m" 14 | #define RED "\033[31m" 15 | #define WHITE "\037[34m" 16 | #define YELLOW "\033[33m" 17 | 18 | #define LIGHT_GRAY "\033[0;37m" 19 | #define DARK_GRAY "\033[1;30m" 20 | 21 | #ifdef _POSIX_C_SOURCE 22 | #define assert_if_posix assert 23 | #else 24 | #define assert_if_posix(...) do { } while (0) 25 | #endif 26 | 27 | #define TERMINAL(F,I) \ 28 | assert_if_posix (fileno (F) == I); /* 'fileno' only in POSIX not C99 */ \ 29 | assert ((I == 1 && F == stdout) || (I == 2 && F == stderr)); \ 30 | bool connected_to_terminal = kissat_connected_to_terminal (I); \ 31 | FILE * terminal_file = F 32 | 33 | #define COLOR(CODE) \ 34 | do { \ 35 | if (!connected_to_terminal) \ 36 | break; \ 37 | fputs (CODE, terminal_file); \ 38 | } while (0) 39 | 40 | extern int kissat_is_terminal[3]; 41 | 42 | int kissat_initialize_terminal(int fd); 43 | void kissat_force_colors(void); 44 | void kissat_force_no_colors(void); 45 | 46 | static inline bool kissat_connected_to_terminal(int fd) { 47 | assert(fd == 1 || fd == 2); 48 | int res = kissat_is_terminal[fd]; 49 | if (res < 0) { 50 | res = kissat_initialize_terminal(fd); 51 | } 52 | assert(res == 0 || res == 1); 53 | return res; 54 | } 55 | 56 | static inline const char *kissat_bold_green_color_code(int fd) { 57 | return kissat_connected_to_terminal(fd) ? BOLD GREEN : ""; 58 | } 59 | 60 | static inline const char *kissat_normal_color_code(int fd) { 61 | return kissat_connected_to_terminal(fd) ? NORMAL : ""; 62 | } 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /test/testbump.c: -------------------------------------------------------------------------------- 1 | #include "../src/bump.h" 2 | 3 | #include "test.h" 4 | 5 | void kissat_update_scores(kissat *); 6 | 7 | static void test_bump_rescale(void) { 8 | kissat *solver = kissat_init(); 9 | kissat_add(solver, 1); 10 | kissat_add(solver, 2); 11 | kissat_add(solver, 0); 12 | kissat_add(solver, -1); 13 | kissat_add(solver, -2); 14 | kissat_add(solver, 0); 15 | if (!solver->stable) { 16 | tissat_verbose("forced switching to stable mode"); 17 | solver->stable = true; 18 | } 19 | tissat_verbose("forced updating of scores"); 20 | kissat_update_scores(solver); 21 | assert(solver->scinc > 0); 22 | tissat_verbose("initial score increment %g", solver->scinc); 23 | ACTIVE(0) = ACTIVE(1) = true; 24 | heap *scores = &solver->scores; 25 | unsigned count = 0; 26 | for (unsigned i = 1; i <= 5; i++) { 27 | double prev = 0; 28 | assert(prev < solver->scinc); 29 | while (prev < solver->scinc) { 30 | prev = solver->scinc; 31 | if (i != 3) { 32 | PUSH_STACK(solver->analyzed, 0); 33 | if (count++ & 1) { 34 | PUSH_STACK(solver->analyzed, 1); 35 | } 36 | } 37 | kissat_bump(solver); 38 | CLEAR_STACK(solver->analyzed); 39 | if (prev >= solver->scinc || 40 | solver->scinc >= MAX_SCORE * 0.7 || 41 | kissat_get_heap_score(scores, 0) >= MAX_SCORE * 0.7 || 42 | kissat_get_heap_score(scores, 1) >= MAX_SCORE * 0.7) 43 | tissat_verbose("%u.%u: score[0]=%g score[1]=%g scinc=%g", 44 | i, count, 45 | kissat_get_heap_score(scores, 0), 46 | kissat_get_heap_score(scores, 1), solver->scinc); 47 | } 48 | } 49 | kissat_release(solver); 50 | } 51 | 52 | void tissat_schedule_bump(void) { 53 | SCHEDULE_FUNCTION(test_bump_rescale); 54 | } 55 | -------------------------------------------------------------------------------- /src/propsearch.c: -------------------------------------------------------------------------------- 1 | #include "fastassign.h" 2 | #include "propsearch.h" 3 | #include "trail.h" 4 | 5 | #define PROPAGATE_LITERAL search_propagate_literal 6 | #define PROPAGATION_TYPE "search" 7 | 8 | #include "proplit.h" 9 | 10 | static inline void update_search_propagation_statistics(kissat *solver, 11 | const unsigned *saved_propagate) { 12 | assert(saved_propagate <= solver->propagate); 13 | const unsigned propagated = solver->propagate - saved_propagate; 14 | 15 | LOG("propagated %u literals", propagated); 16 | LOG("propagation took %" PRIu64 " ticks", solver->ticks); 17 | 18 | ADD(propagations, propagated); 19 | ADD(ticks, solver->ticks); 20 | 21 | ADD(search_propagations, propagated); 22 | ADD(search_ticks, solver->ticks); 23 | 24 | if (solver->stable) { 25 | ADD(stable_propagations, propagated); 26 | ADD(stable_ticks, solver->ticks); 27 | } else { 28 | ADD(focused_propagations, propagated); 29 | ADD(focused_ticks, solver->ticks); 30 | } 31 | } 32 | 33 | static clause *search_propagate(kissat *solver) { 34 | clause *res = 0; 35 | unsigned *propagate = solver->propagate; 36 | while (!res && propagate != END_ARRAY(solver->trail)) { 37 | res = search_propagate_literal(solver, *propagate++); 38 | } 39 | solver->propagate = propagate; 40 | return res; 41 | } 42 | 43 | clause *kissat_search_propagate(kissat *solver) { 44 | assert(!solver->probing); 45 | assert(solver->watching); 46 | assert(!solver->inconsistent); 47 | 48 | START(propagate); 49 | 50 | solver->ticks = 0; 51 | const unsigned *saved_propagate = solver->propagate; 52 | clause *conflict = search_propagate(solver); 53 | update_search_propagation_statistics(solver, saved_propagate); 54 | kissat_update_conflicts_and_trail(solver, conflict, true); 55 | 56 | STOP(propagate); 57 | 58 | return conflict; 59 | } 60 | -------------------------------------------------------------------------------- /src/reluctant.c: -------------------------------------------------------------------------------- 1 | #include "internal.h" 2 | #include "logging.h" 3 | 4 | 5 | void kissat_enable_reluctant(reluctant *reluctant, 6 | uint64_t period, uint64_t limit) { 7 | if (limit && period > limit) { 8 | period = limit; 9 | } 10 | reluctant->limited = (limit > 0); 11 | reluctant->trigger = false; 12 | reluctant->period = period; 13 | reluctant->wait = period; 14 | reluctant->u = reluctant->v = 1; 15 | reluctant->limit = limit; 16 | } 17 | 18 | void kissat_disable_reluctant(reluctant *reluctant) { 19 | reluctant->period = 0; 20 | } 21 | 22 | void kissat_tick_reluctant(reluctant *reluctant) { 23 | if (!reluctant->period) { 24 | return; 25 | } 26 | 27 | if (reluctant->trigger) { 28 | return; 29 | } 30 | 31 | assert(reluctant->wait > 0); 32 | if (--reluctant->wait) { 33 | return; 34 | } 35 | 36 | uint64_t u = reluctant->u; 37 | uint64_t v = reluctant->v; 38 | 39 | if ((u & -u) == v) { 40 | u++; 41 | v = 1; 42 | } else { 43 | assert(UINT64_MAX / 2 >= v); 44 | v *= 2; 45 | } 46 | 47 | assert(v); 48 | assert(UINT64_MAX / v >= reluctant->period); 49 | uint64_t wait = v * reluctant->period; 50 | 51 | if (reluctant->limited && wait > reluctant->limit) { 52 | u = v = 1; 53 | wait = reluctant->period; 54 | } 55 | 56 | reluctant->trigger = true; 57 | reluctant->wait = wait; 58 | reluctant->u = u; 59 | reluctant->v = v; 60 | } 61 | 62 | void kissat_init_reluctant(kissat *solver) { 63 | if (GET_OPTION(reluctant)) { 64 | LOG("enable reluctant doubling with period %d limit %d", 65 | GET_OPTION(reluctantint), GET_OPTION(reluctantlim)); 66 | kissat_enable_reluctant(&solver->reluctant, 67 | GET_OPTION(reluctantint), 68 | GET_OPTION(reluctantlim)); 69 | } else { 70 | LOG("reluctant doubling disabled and thus no stable restarts"); 71 | kissat_disable_reluctant(&solver->reluctant); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/queue.c: -------------------------------------------------------------------------------- 1 | #include "inline.h" 2 | #include "inlinequeue.h" 3 | #include "print.h" 4 | 5 | void kissat_init_queue(kissat *solver) { 6 | queue *queue = &solver->queue; 7 | queue->first = queue->last = DISCONNECT; 8 | assert(!queue->stamp); 9 | 10 | queue->search.idx = DISCONNECT; 11 | assert(!queue->search.stamp); 12 | } 13 | 14 | void kissat_reset_queue(kissat *solver) { 15 | LOG("reset queue"); 16 | queue *queue = &solver->queue; 17 | links *links = solver->links; 18 | const unsigned last = queue->last; 19 | assert(!DISCONNECTED(last)); 20 | kissat_update_queue(solver, links, last); 21 | } 22 | 23 | void kissat_reassign_queue_stamps(kissat *solver) { 24 | kissat_very_verbose(solver, "need to reassign enqueue stamps on queue"); 25 | 26 | queue *queue = &solver->queue; 27 | links *links = solver->links; 28 | queue->stamp = 0; 29 | 30 | struct links *l; 31 | for (unsigned idx = queue->first; !DISCONNECTED(idx); idx = l->next) { 32 | (l = links + idx)->stamp = ++queue->stamp; 33 | } 34 | 35 | if (!DISCONNECTED(queue->search.idx)) { 36 | queue->search.stamp = links[queue->search.idx].stamp; 37 | } 38 | } 39 | 40 | #if defined(CHECK_QUEUE) && !defined(NDEBUG) 41 | void kissat_check_queue(kissat *solver) { 42 | links *links = solver->links; 43 | queue *queue = &solver->queue; 44 | bool passed_search_idx = false; 45 | const bool focused = !solver->stable; 46 | for (unsigned idx = queue->first, prev = DISCONNECT; 47 | !DISCONNECTED(idx); idx = links[idx].next) { 48 | if (!DISCONNECTED(prev)) { 49 | assert(links[prev].stamp < links[idx].stamp); 50 | } 51 | if (focused && passed_search_idx) { 52 | assert(VALUE(LIT(idx))); 53 | } 54 | if (idx == queue->search.idx) { 55 | passed_search_idx = true; 56 | } 57 | } 58 | if (!DISCONNECTED(queue->search.idx)) { 59 | assert(links[queue->search.idx].stamp == queue->search.stamp); 60 | } 61 | } 62 | #endif 63 | -------------------------------------------------------------------------------- /test/testendianness.c: -------------------------------------------------------------------------------- 1 | #include "../src/endianness.h" 2 | 3 | #include 4 | 5 | #include "test.h" 6 | 7 | struct first { 8 | bool bit: 1; 9 | unsigned rest: 31; 10 | }; 11 | 12 | struct last { 13 | unsigned rest: 31; 14 | bool bit: 1; 15 | }; 16 | 17 | union type { 18 | struct first first; 19 | struct last last; 20 | unsigned raw; 21 | }; 22 | 23 | #define PRINT(EXPR) \ 24 | do { \ 25 | const unsigned value = (unsigned)(EXPR); \ 26 | printf ("%s == %08x\n", #EXPR, value); \ 27 | } while (0) 28 | 29 | static void test_endianness(void) { 30 | assert(sizeof(struct first) == 4); 31 | assert(sizeof(struct last) == 4); 32 | assert(sizeof(union type) == 4); 33 | // *INDENT-OFF* 34 | PRINT (((union type) { .raw = 1u }).raw); 35 | PRINT (((union type) { .raw = (1u<<31)}).raw); 36 | printf ("\n"); 37 | PRINT (((union type) { .raw = 1u }).first.bit); 38 | PRINT (((union type) { .raw = 1u }).first.rest); 39 | PRINT (((union type) { .raw = (1u<<31)}).first.bit); 40 | PRINT (((union type) { .raw = (1u<<31)}).first.rest); 41 | printf ("\n"); 42 | PRINT (((union type) { .raw = 1u }).last.bit); 43 | PRINT (((union type) { .raw = 1u }).last.rest); 44 | PRINT (((union type) { .raw = (1u<<31)}).last.bit); 45 | PRINT (((union type) { .raw = (1u<<31)}).last.rest); 46 | printf ("\n"); 47 | #ifdef KISSAT_IS_BIG_ENDIAN 48 | if (((union type) { .raw = 1u}).last.bit) 49 | printf ("big endian as expected\n"); 50 | else if (((union type) { .raw = 1u}).first.bit) 51 | FATAL ("unexpected little endian"); 52 | #else 53 | if (((union type) { .raw = 1u}).first.bit) 54 | printf ("little endian as expected\n"); 55 | else if (((union type) { .raw = 1u}).last.bit) 56 | FATAL ("unexpected big endian"); 57 | #endif 58 | else 59 | FATAL ("could not determine endianness"); 60 | // *INDENT-ON* 61 | } 62 | 63 | void tissat_schedule_endianness(void) { 64 | SCHEDULE_FUNCTION(test_endianness); 65 | } 66 | -------------------------------------------------------------------------------- /test/testbits.c: -------------------------------------------------------------------------------- 1 | #include "../src/bits.h" 2 | 3 | #include "test.h" 4 | 5 | static void test_bits_manual(void) { 6 | DECLARE_AND_INIT_SOLVER(solver); 7 | 8 | 9 | { 10 | bits *bits = kissat_new_bits(solver, 0); 11 | kissat_delete_bits(solver, bits, 0); 12 | } 13 | 14 | { 15 | bits *bits = kissat_new_bits(solver, 1); 16 | assert(!kissat_get_bit(bits, 1, 0)); 17 | kissat_set_bit_to_true(bits, 1, 0); 18 | assert(kissat_get_bit(bits, 1, 0)); 19 | kissat_set_bit_to_false(bits, 1, 0); 20 | assert(!kissat_get_bit(bits, 1, 0)); 21 | kissat_delete_bits(solver, bits, 1); 22 | } 23 | 24 | for (unsigned size = 3; size < 100; size += 3) { 25 | bits *bits = kissat_new_bits(solver, size); 26 | for (unsigned bit = 0; bit < size; bit++) { 27 | assert(!kissat_get_bit(bits, size, bit)); 28 | } 29 | for (unsigned bit = 0; bit < size; bit += 5) { 30 | kissat_set_bit_to_true(bits, size, bit); 31 | } 32 | for (unsigned bit = 0; bit < size; bit += 2) { 33 | kissat_set_bit_to_true(bits, size, bit); 34 | } 35 | for (unsigned bit = 0; bit < size; bit += 10) { 36 | assert(kissat_get_bit(bits, size, bit)); 37 | kissat_set_bit_to_false(bits, size, bit); 38 | } 39 | for (unsigned bit = 0; bit < size; bit++) { 40 | bool set = kissat_get_bit(bits, size, bit); 41 | assert(set == (!(bit % 2) ^ !(bit % 5))); 42 | } 43 | for (unsigned bit = 0; bit < size; bit++) { 44 | bool value = !(bit % 7); 45 | kissat_set_bit_explicitly(bits, size, bit, value); 46 | } 47 | for (unsigned bit = 0; bit < size; bit += 7) { 48 | assert(kissat_get_bit(bits, size, bit + 0)); 49 | for (unsigned i = bit + 1; i < bit + 7 && i < size; i++) { 50 | assert(!kissat_get_bit(bits, size, i)); 51 | } 52 | } 53 | kissat_delete_bits(solver, bits, size); 54 | } 55 | } 56 | 57 | void tissat_schedule_bits(void) { 58 | SCHEDULE_FUNCTION(test_bits_manual); 59 | } 60 | -------------------------------------------------------------------------------- /test/testapplication.c: -------------------------------------------------------------------------------- 1 | #include "../src/application.h" 2 | #include "../src/file.h" 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "test.h" 10 | 11 | static char *copy_string(const char *begin, const char *end) { 12 | const size_t len = end - begin; 13 | char *res = malloc(len + 1); 14 | memcpy(res, begin, len); 15 | res[len] = 0; 16 | return res; 17 | } 18 | 19 | void tissat_call_application(int expected, const char *cmd) { 20 | #define MAX_ARGC 8 21 | char *argv[MAX_ARGC]; 22 | int argc = 0; 23 | argv[argc++] = "kissat"; 24 | for (const char *p = cmd, *start = cmd;; p++) 25 | if (!*p || *p == ' ') { 26 | if (argc == MAX_ARGC) { 27 | FATAL("MAX_ARGC exceeded"); 28 | } 29 | argv[argc++] = copy_string(start, p); 30 | if (!*p) { 31 | break; 32 | } 33 | start = ++p; 34 | } 35 | #undef MAX_ARGC 36 | kissat *solver = kissat_init(); 37 | tissat_init_solver(solver); 38 | tissat_redirect_stderr_to_stdout(); 39 | int res = kissat_application(solver, argc, argv); 40 | tissat_restore_stderr(); 41 | if (res != expected) { 42 | FATAL("'kissat %s' returns '%d' and not '%d'", cmd, res, expected); 43 | } 44 | kissat_release(solver); 45 | for (int i = 1; i < argc; i++) { 46 | free(argv[i]); 47 | } 48 | tissat_verbose("Application 'kissat %s' returned '%d' as expected.", 49 | cmd, res); 50 | } 51 | 52 | const char *tissat_options[] = { 53 | "", 54 | #if !defined(QUIET) && !defined(NOPTIONS) 55 | "-q ", 56 | "-s ", 57 | "-v ", 58 | "-s -v ", 59 | #endif 60 | }; 61 | 62 | #define SIZE_OPTIONS (sizeof (tissat_options) / sizeof (char*)) 63 | const unsigned tissat_size_options = SIZE_OPTIONS; 64 | const char **tissat_end_of_options = tissat_options + SIZE_OPTIONS; 65 | 66 | const char *tissat_next_option(unsigned count) { 67 | assert(tissat_size_options); 68 | return tissat_options[count % tissat_size_options]; 69 | } 70 | -------------------------------------------------------------------------------- /test/teststack.c: -------------------------------------------------------------------------------- 1 | #include "../src/allocate.h" 2 | 3 | #include "test.h" 4 | 5 | static void test_stack_basic(void) { 6 | DECLARE_AND_INIT_SOLVER(solver); 7 | STACK(unsigned) stack; 8 | assert(sizeof stack == 3 * sizeof(void *)); 9 | INIT_STACK(stack); 10 | assert(EMPTY_STACK(stack)); 11 | assert(FULL_STACK(stack)); 12 | const unsigned n = 100; 13 | for (unsigned i = 0; i < n; i++) { 14 | assert(SIZE_STACK(stack) == i); 15 | PUSH_STACK(stack, i); 16 | } 17 | #ifdef METRICS 18 | assert(solver->statistics.allocated_current == 128 * sizeof(unsigned)); 19 | #endif 20 | { 21 | unsigned i = 0; 22 | for (all_stack(unsigned, e, stack)) { 23 | assert(e == i++); 24 | } 25 | assert(i == n); 26 | } 27 | { 28 | unsigned i = n - 1; 29 | while (!EMPTY_STACK(stack)) { 30 | unsigned tmp = TOP_STACK(stack); 31 | assert(tmp == i); 32 | tmp = POP_STACK(stack); 33 | assert(tmp == i); 34 | i--; 35 | } 36 | assert(i == 0u - 1); 37 | } 38 | RELEASE_STACK(stack); 39 | #ifdef METRICS 40 | assert(!solver->statistics.allocated_current); 41 | #endif 42 | } 43 | 44 | typedef struct odd_sized odd_sized; 45 | 46 | struct odd_sized { 47 | unsigned a, b, c; 48 | }; 49 | 50 | // *INDENT-OFF* 51 | typedef STACK (odd_sized) odd_sized_stack; 52 | // *INDENT-ON* 53 | 54 | static void test_shrink_stack(void) { 55 | DECLARE_AND_INIT_SOLVER(solver); 56 | odd_sized element; 57 | memset(&element, 0, sizeof element); 58 | odd_sized_stack stack; 59 | INIT_STACK(stack); 60 | PUSH_STACK(stack, element); 61 | PUSH_STACK(stack, element); 62 | PUSH_STACK(stack, element); 63 | PUSH_STACK(stack, element); 64 | RESIZE_STACK(stack, 1); 65 | SHRINK_STACK(stack); 66 | RELEASE_STACK(stack); 67 | #ifdef METRICS 68 | assert(!solver->statistics.allocated_current); 69 | #endif 70 | } 71 | 72 | void tissat_schedule_stack(void) { 73 | SCHEDULE_FUNCTION(test_stack_basic); 74 | SCHEDULE_FUNCTION(test_shrink_stack); 75 | } 76 | -------------------------------------------------------------------------------- /src/stack.c: -------------------------------------------------------------------------------- 1 | #include "allocate.h" 2 | #include "stack.h" 3 | #include "utilities.h" 4 | 5 | #include 6 | 7 | void kissat_stack_enlarge(struct kissat *solver, chars *s, size_t bytes) { 8 | const size_t size = SIZE_STACK(*s); 9 | const size_t old_bytes = CAPACITY_STACK(*s); 10 | assert(MAX_SIZE_T / 2 >= old_bytes); 11 | size_t new_bytes; 12 | if (old_bytes) { 13 | new_bytes = 2 * old_bytes; 14 | } else { 15 | new_bytes = bytes; 16 | while (!kissat_aligned_word(new_bytes)) { 17 | new_bytes <<= 1; 18 | } 19 | } 20 | s->begin = kissat_realloc(solver, s->begin, old_bytes, new_bytes); 21 | s->allocated = s->begin + new_bytes; 22 | s->end = s->begin + size; 23 | } 24 | 25 | void kissat_shrink_stack(struct kissat *solver, chars *s, size_t bytes) { 26 | assert(bytes > 0); 27 | const size_t old_bytes_capacity = CAPACITY_STACK(*s); 28 | assert(kissat_aligned_word(old_bytes_capacity)); 29 | assert(!(old_bytes_capacity % bytes)); 30 | assert(kissat_is_zero_or_power_of_two(old_bytes_capacity / bytes)); 31 | const size_t old_bytes_size = SIZE_STACK(*s); 32 | assert(!(old_bytes_size % bytes)); 33 | const size_t old_size = old_bytes_size / bytes; 34 | size_t new_capacity; 35 | if (old_size) { 36 | const unsigned ld_old_size = kissat_log2_ceiling_of_word(old_size); 37 | new_capacity = ((size_t) 1) << ld_old_size; 38 | } else { 39 | new_capacity = 0; 40 | } 41 | assert(kissat_is_zero_or_power_of_two(new_capacity)); 42 | size_t new_bytes_capacity = new_capacity * bytes; 43 | while (!kissat_aligned_word(new_bytes_capacity)) { 44 | new_bytes_capacity <<= 1; 45 | } 46 | if (new_bytes_capacity == old_bytes_capacity) { 47 | return; 48 | } 49 | assert(new_bytes_capacity < old_bytes_capacity); 50 | s->begin = kissat_realloc(solver, s->begin, 51 | old_bytes_capacity, new_bytes_capacity); 52 | s->allocated = s->begin + new_bytes_capacity; 53 | s->end = s->begin + old_bytes_size; 54 | assert(s->end <= s->allocated); 55 | } 56 | -------------------------------------------------------------------------------- /src/probe.c: -------------------------------------------------------------------------------- 1 | #include "backbone.h" 2 | #include "backtrack.h" 3 | #include "failed.h" 4 | #include "internal.h" 5 | #include "print.h" 6 | #include "probe.h" 7 | #include "ternary.h" 8 | #include "transitive.h" 9 | #include "substitute.h" 10 | #include "sweep.h" 11 | #include "vivify.h" 12 | 13 | #include 14 | 15 | bool kissat_probing(kissat *solver) { 16 | if (!solver->enabled.probe) { 17 | return false; 18 | } 19 | if (solver->waiting.probe.reduce > solver->statistics.reductions) { 20 | return false; 21 | } 22 | return solver->limits.probe.conflicts <= CONFLICTS; 23 | } 24 | 25 | static void probe(kissat *solver) { 26 | RETURN_IF_DELAYED(probe); 27 | kissat_backtrack_propagate_and_flush_trail(solver); 28 | assert(!solver->inconsistent); 29 | STOP_SEARCH_AND_START_SIMPLIFIER(probe); 30 | kissat_phase(solver, "probe", GET(probings), 31 | "probing limit hit after %" PRIu64 " conflicts", 32 | solver->limits.probe.conflicts); 33 | const changes before = kissat_changes(solver); 34 | kissat_substitute(solver); 35 | kissat_binary_clauses_backbone(solver); 36 | kissat_ternary(solver); 37 | kissat_transitive_reduction(solver); 38 | kissat_failed_literal_computation(solver); 39 | kissat_vivify(solver); 40 | kissat_sweep(solver); 41 | kissat_substitute(solver); 42 | kissat_binary_clauses_backbone(solver); 43 | const changes after = kissat_changes(solver); 44 | const bool changed = kissat_changed(before, after); 45 | UPDATE_DELAY(changed, probe); 46 | STOP_SIMPLIFIER_AND_RESUME_SEARCH(probe); 47 | } 48 | 49 | int kissat_probe(kissat *solver) { 50 | assert(!solver->inconsistent); 51 | INC(probings); 52 | assert(!solver->probing); 53 | solver->probing = true; 54 | probe(solver); 55 | UPDATE_CONFLICT_LIMIT(probe, probings, NLOGN, true); 56 | solver->waiting.probe.reduce = solver->statistics.reductions + 1; 57 | solver->last.probe = solver->statistics.search_ticks; 58 | assert(solver->probing); 59 | solver->probing = false; 60 | return solver->inconsistent ? 20 : 0; 61 | } 62 | -------------------------------------------------------------------------------- /src/assign.c: -------------------------------------------------------------------------------- 1 | #include "assign.h" 2 | #include "inline.h" 3 | #include "inlineassign.h" 4 | #include "logging.h" 5 | 6 | #include 7 | 8 | void kissat_assign_unit(kissat *solver, unsigned lit, const char *reason) { 9 | kissat_assign(solver, solver->probing, 0, false, false, lit, UNIT_REASON); 10 | LOGUNARY(lit, "assign %s %s", LOGLIT(lit), reason); 11 | #ifndef LOGGING 12 | (void) reason; 13 | #endif 14 | } 15 | 16 | void kissat_learned_unit(kissat *solver, unsigned lit) { 17 | kissat_assign_unit(solver, lit, "learned reason"); 18 | CHECK_AND_ADD_UNIT(lit); 19 | ADD_UNIT_TO_PROOF(lit); 20 | } 21 | 22 | void kissat_original_unit(kissat *solver, unsigned lit) { 23 | kissat_assign_unit(solver, lit, "original reason"); 24 | } 25 | 26 | void kissat_assign_decision(kissat *solver, unsigned lit) { 27 | kissat_assign(solver, solver->probing, solver->level, false, false, 28 | lit, DECISION_REASON); 29 | LOG("assign %s decision", LOGLIT(lit)); 30 | } 31 | 32 | void kissat_assign_binary(kissat *solver, 33 | bool redundant, unsigned lit, unsigned other) { 34 | assert(VALUE(other) < 0); 35 | assigned *assigned = solver->assigned; 36 | const unsigned other_idx = IDX(other); 37 | struct assigned *a = assigned + other_idx; 38 | kissat_assign(solver, solver->probing, a->level, 39 | true, redundant, lit, other); 40 | LOGBINARY(lit, other, "assign %s %s reason", 41 | LOGLIT(lit), redundant ? "redundant" : "irredundant"); 42 | } 43 | 44 | void kissat_assign_reference(kissat *solver, 45 | unsigned lit, reference ref, clause *reason) { 46 | assert(reason == kissat_dereference_clause(solver, ref)); 47 | assigned *assigned = solver->assigned; 48 | value *values = solver->values; 49 | const unsigned level = 50 | kissat_assignment_level(solver, values, assigned, lit, reason); 51 | assert(level <= solver->level); 52 | assert(ref != DECISION_REASON); 53 | assert(ref != UNIT_REASON); 54 | kissat_assign(solver, solver->probing, level, false, false, lit, ref); 55 | LOGREF(ref, "assign %s reason", LOGLIT(lit)); 56 | } 57 | -------------------------------------------------------------------------------- /src/smooth.c: -------------------------------------------------------------------------------- 1 | #include "allocate.h" 2 | #include "internal.h" 3 | #include "logging.h" 4 | 5 | void kissat_init_smooth(kissat *solver, smooth *smooth, int window, 6 | const char *name) { 7 | assert(window > 0); 8 | const double alpha = 1.0 / window; 9 | LOG("initialized %s EMA alpha %g window %d", name, alpha, window); 10 | smooth->value = 0; 11 | smooth->biased = 0; 12 | smooth->alpha = alpha; 13 | smooth->beta = 1.0 - alpha; 14 | assert(smooth->beta > 0); 15 | smooth->exp = 1.0; 16 | #ifdef LOGGING 17 | smooth->name = name; 18 | smooth->updated = 0; 19 | #else 20 | (void) solver; 21 | (void) name; 22 | #endif 23 | } 24 | 25 | void kissat_update_smooth(kissat *solver, smooth *smooth, double y) { 26 | #ifdef LOGGING 27 | smooth->updated++; 28 | const double old_value = smooth->value; 29 | #endif 30 | const double old_biased = smooth->biased; 31 | const double alpha = smooth->alpha; 32 | const double beta = smooth->beta; 33 | const double delta = y - old_biased; 34 | const double scaled_delta = alpha * delta; 35 | const double new_biased = old_biased + scaled_delta; 36 | LOG("update %" PRIu64 " of biased %s EMA %g with %g (delta %g) " 37 | "yields %g (scaled delta %g)", 38 | smooth->updated, smooth->name, old_biased, y, delta, 39 | new_biased, scaled_delta); 40 | smooth->biased = new_biased; 41 | double old_exp = smooth->exp; 42 | double new_exp, div, new_value; 43 | if (old_exp) { 44 | new_exp = old_exp * beta; 45 | assert(new_exp < 1); 46 | smooth->exp = new_exp; 47 | div = 1 - new_exp; 48 | assert(div > 0); 49 | new_value = new_biased / div; 50 | } else { 51 | new_value = new_biased; 52 | #ifdef LOGGING 53 | new_exp = 0; 54 | div = 1; 55 | #endif 56 | } 57 | smooth->value = new_value; 58 | LOG("update %" PRIu64 " of corrected %s EMA %g " 59 | "with %g (delta %g) yields %g (exponent %g, div %g)", 60 | smooth->updated, smooth->name, old_value, y, delta, 61 | new_value, new_exp, div); 62 | #ifndef LOGGING 63 | (void) solver; 64 | #endif 65 | } 66 | -------------------------------------------------------------------------------- /src/build.c: -------------------------------------------------------------------------------- 1 | #include "build.h" 2 | #include "colors.h" 3 | #include "print.h" 4 | #include "kissat.h" 5 | 6 | #include 7 | #include 8 | 9 | const char *kissat_signature(void) { 10 | return "kissat-extras-" VERSION; 11 | } 12 | 13 | const char *kissat_id(void) { 14 | return ID; 15 | } 16 | 17 | const char *kissat_compiler(void) { 18 | return COMPILER; 19 | } 20 | 21 | const char *kissat_copyright(void) { 22 | return "Kissat SAT Solver: Copyright (c) 2019-2021 Armin Biere JKU Linz; " 23 | "Kissat Extras Patches: Copyright (c) 2022 Jannis Harder"; 24 | } 25 | 26 | const char *kissat_version(void) { 27 | return VERSION; 28 | } 29 | 30 | #define PREFIX(COLORS) \ 31 | do { \ 32 | if (prefix) \ 33 | fputs (prefix, stdout); \ 34 | COLOR (COLORS); \ 35 | } while (0) 36 | 37 | #define NL() \ 38 | do { \ 39 | COLOR (NORMAL); \ 40 | fputs ("\n", stdout); \ 41 | fflush(stdout); \ 42 | } while (0) 43 | 44 | void kissat_build(const char *prefix) { 45 | TERMINAL(stdout, 1); 46 | if (!prefix) { 47 | connected_to_terminal = false; 48 | } 49 | 50 | PREFIX(MAGENTA); 51 | if (ID) { 52 | printf("Version %s %s", VERSION, ID); 53 | } else { 54 | printf("Version %s", VERSION); 55 | } 56 | NL(); 57 | 58 | PREFIX(MAGENTA); 59 | printf("%s", COMPILER); 60 | NL(); 61 | 62 | PREFIX(MAGENTA); 63 | printf("%s", BUILD); 64 | NL(); 65 | } 66 | 67 | void kissat_banner(const char *prefix, const char *name) { 68 | TERMINAL(stdout, 1); 69 | if (!prefix) { 70 | connected_to_terminal = false; 71 | } 72 | 73 | PREFIX(BOLD MAGENTA); 74 | printf("%s", name); 75 | NL(); 76 | 77 | const char *copyright = kissat_copyright(); 78 | 79 | for (const char *end; end = strstr(copyright, "; "), end;) { 80 | PREFIX(BOLD MAGENTA); 81 | fwrite(copyright, end - copyright, 1, stdout); 82 | NL(); 83 | copyright = end + 2; 84 | } 85 | 86 | PREFIX(BOLD MAGENTA); 87 | fputs(copyright, stdout); 88 | NL(); 89 | 90 | if (prefix) { 91 | PREFIX(""); 92 | NL(); 93 | } 94 | 95 | kissat_build(prefix); 96 | } 97 | -------------------------------------------------------------------------------- /test/cnf/ph6.cnf: -------------------------------------------------------------------------------- 1 | p cnf 42 133 2 | -1 -7 0 3 | -1 -13 0 4 | -1 -19 0 5 | -1 -25 0 6 | -1 -31 0 7 | -1 -37 0 8 | -7 -13 0 9 | -7 -19 0 10 | -7 -25 0 11 | -7 -31 0 12 | -7 -37 0 13 | -13 -19 0 14 | -13 -25 0 15 | -13 -31 0 16 | -13 -37 0 17 | -19 -25 0 18 | -19 -31 0 19 | -19 -37 0 20 | -25 -31 0 21 | -25 -37 0 22 | -31 -37 0 23 | -2 -8 0 24 | -2 -14 0 25 | -2 -20 0 26 | -2 -26 0 27 | -2 -32 0 28 | -2 -38 0 29 | -8 -14 0 30 | -8 -20 0 31 | -8 -26 0 32 | -8 -32 0 33 | -8 -38 0 34 | -14 -20 0 35 | -14 -26 0 36 | -14 -32 0 37 | -14 -38 0 38 | -20 -26 0 39 | -20 -32 0 40 | -20 -38 0 41 | -26 -32 0 42 | -26 -38 0 43 | -32 -38 0 44 | -3 -9 0 45 | -3 -15 0 46 | -3 -21 0 47 | -3 -27 0 48 | -3 -33 0 49 | -3 -39 0 50 | -9 -15 0 51 | -9 -21 0 52 | -9 -27 0 53 | -9 -33 0 54 | -9 -39 0 55 | -15 -21 0 56 | -15 -27 0 57 | -15 -33 0 58 | -15 -39 0 59 | -21 -27 0 60 | -21 -33 0 61 | -21 -39 0 62 | -27 -33 0 63 | -27 -39 0 64 | -33 -39 0 65 | -4 -10 0 66 | -4 -16 0 67 | -4 -22 0 68 | -4 -28 0 69 | -4 -34 0 70 | -4 -40 0 71 | -10 -16 0 72 | -10 -22 0 73 | -10 -28 0 74 | -10 -34 0 75 | -10 -40 0 76 | -16 -22 0 77 | -16 -28 0 78 | -16 -34 0 79 | -16 -40 0 80 | -22 -28 0 81 | -22 -34 0 82 | -22 -40 0 83 | -28 -34 0 84 | -28 -40 0 85 | -34 -40 0 86 | -5 -11 0 87 | -5 -17 0 88 | -5 -23 0 89 | -5 -29 0 90 | -5 -35 0 91 | -5 -41 0 92 | -11 -17 0 93 | -11 -23 0 94 | -11 -29 0 95 | -11 -35 0 96 | -11 -41 0 97 | -17 -23 0 98 | -17 -29 0 99 | -17 -35 0 100 | -17 -41 0 101 | -23 -29 0 102 | -23 -35 0 103 | -23 -41 0 104 | -29 -35 0 105 | -29 -41 0 106 | -35 -41 0 107 | -6 -12 0 108 | -6 -18 0 109 | -6 -24 0 110 | -6 -30 0 111 | -6 -36 0 112 | -6 -42 0 113 | -12 -18 0 114 | -12 -24 0 115 | -12 -30 0 116 | -12 -36 0 117 | -12 -42 0 118 | -18 -24 0 119 | -18 -30 0 120 | -18 -36 0 121 | -18 -42 0 122 | -24 -30 0 123 | -24 -36 0 124 | -24 -42 0 125 | -30 -36 0 126 | -30 -42 0 127 | -36 -42 0 128 | 6 5 4 3 2 1 0 129 | 12 11 10 9 8 7 0 130 | 18 17 16 15 14 13 0 131 | 24 23 22 21 20 19 0 132 | 30 29 28 27 26 25 0 133 | 36 35 34 33 32 31 0 134 | 42 41 40 39 38 37 0 135 | -------------------------------------------------------------------------------- /src/handle.c: -------------------------------------------------------------------------------- 1 | #include "handle.h" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | static void (*handler)(int); 8 | static volatile int caught_signal; 9 | static volatile bool handler_set; 10 | 11 | // *INDENT-OFF* 12 | 13 | #define SIGNAL(SIG) \ 14 | static void (*SIG ## _handler)(int); 15 | SIGNALS 16 | #undef SIGNAL 17 | 18 | void 19 | kissat_reset_signal_handler (void) 20 | { 21 | if (!handler_set) 22 | return; 23 | #define SIGNAL(SIG) \ 24 | signal (SIG, SIG ## _handler); 25 | SIGNALS 26 | #undef SIGNAL 27 | handler_set = false; 28 | handler = 0; 29 | } 30 | 31 | // *INDENT-ON* 32 | 33 | static void catch_signal(int sig) { 34 | if (caught_signal) { 35 | return; 36 | } 37 | caught_signal = sig; 38 | assert(handler_set); 39 | assert(handler); 40 | handler(sig); 41 | kissat_reset_signal_handler(); 42 | raise(sig); 43 | } 44 | 45 | void kissat_init_signal_handler(void (*h)(int sig)) { 46 | assert(!handler); 47 | handler = h; 48 | handler_set = true; 49 | #define SIGNAL(SIG) \ 50 | SIG ##_handler = signal (SIG, catch_signal); 51 | SIGNALS 52 | #undef SIGNAL 53 | } 54 | 55 | static volatile bool caught_alarm; 56 | static volatile bool alarm_handler_set; 57 | static void (*volatile SIGALRM_handler)(int); 58 | static void (*volatile handle_alarm)(); 59 | 60 | static void catch_alarm(int sig) { 61 | assert(sig == SIGALRM); 62 | if (caught_alarm) { 63 | return; 64 | } 65 | caught_alarm = true; 66 | static void (*volatile handler)(); 67 | handler = handle_alarm; 68 | if (!alarm_handler_set) { 69 | raise(sig); 70 | } 71 | assert(handler); 72 | handler(); 73 | } 74 | 75 | void kissat_init_alarm(void (*handler)(void)) { 76 | assert(handler); 77 | assert(!caught_alarm); 78 | handle_alarm = handler; 79 | alarm_handler_set = true; 80 | assert(!SIGALRM_handler); 81 | SIGALRM_handler = signal(SIGALRM, catch_alarm); 82 | } 83 | 84 | void kissat_reset_alarm(void) { 85 | assert(alarm_handler_set); 86 | assert(handle_alarm); 87 | alarm_handler_set = false; 88 | handle_alarm = 0; 89 | (void) signal(SIGALRM, SIGALRM_handler); 90 | } 91 | -------------------------------------------------------------------------------- /src/protect.c: -------------------------------------------------------------------------------- 1 | #include "flags.h" 2 | #include "internal.h" 3 | #include "logging.h" 4 | #include "protect.h" 5 | 6 | #define PROTECT_MAX UINT_MAX 7 | 8 | void kissat_protect_variable(kissat *solver, unsigned idx) { 9 | assert(GET_OPTION(incremental) || !GET(searches) || PROTECT(idx) 10 | || FLAGS(idx)->fixed || !FLAGS(idx)->active); 11 | 12 | if (FLAGS(idx)->fixed) { 13 | LOG("internal %s is fixed, protect does nothing", LOGVAR(idx)); 14 | return; 15 | } 16 | 17 | kissat_activate_literal(solver, LIT(idx)); 18 | 19 | if (PROTECT(idx) < PROTECT_MAX) { 20 | PROTECT(idx)++; 21 | LOG("protecting internal %s (counter at %u)", LOGVAR(idx), PROTECT(idx)); 22 | } else { 23 | LOG("stuck counter, protecting internal %s forever", LOGVAR(idx)); 24 | } 25 | } 26 | 27 | void kissat_unprotect_variable(kissat *solver, unsigned idx) { 28 | assert(PROTECT(idx) || FLAGS(idx)->fixed); 29 | 30 | if (FLAGS(idx)->fixed) { 31 | LOG("internal %s is fixed, unprotect does nothing", LOGVAR(idx)); 32 | } else if (PROTECT(idx) < PROTECT_MAX) { 33 | PROTECT(idx)--; 34 | LOG("unprotecting internal %s (counter at %u)", LOGVAR(idx), PROTECT(idx)); 35 | } else { 36 | LOG("stuck counter for internal %s, unprotect does noething", LOGVAR(idx)); 37 | } 38 | } 39 | 40 | void kissat_move_protection(kissat *solver, 41 | unsigned from_idx, unsigned to_idx) { 42 | unsigned move = PROTECT(from_idx); 43 | if (!move) { 44 | LOG("no protection to move from %s to %s", LOGVAR(from_idx), 45 | LOGVAR(to_idx)); 46 | return; 47 | } 48 | PROTECT(from_idx) = 0; 49 | if (FLAGS(to_idx)->fixed) { 50 | LOG("no protection to move from %s to fixed %s", LOGVAR(from_idx), 51 | LOGVAR(to_idx)); 52 | return; 53 | } 54 | PROTECT(to_idx) += move; 55 | if (PROTECT(to_idx) < move || PROTECT(to_idx) > PROTECT_MAX) { 56 | LOG("stuck counter while moving %u protection from %s to %s", 57 | move, LOGVAR(from_idx), LOGVAR(to_idx)); 58 | PROTECT(to_idx) = PROTECT_MAX; 59 | } else { 60 | LOG("moved %u protection from %s to %s", 61 | move, LOGVAR(from_idx), LOGVAR(to_idx)); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/bits.h: -------------------------------------------------------------------------------- 1 | #ifndef _bits_h_INCLUDED 2 | #define _bits_h_INCLUDED 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | typedef unsigned bits; 9 | 10 | struct kissat; 11 | 12 | bits *kissat_new_bits(struct kissat *, size_t size); 13 | void kissat_delete_bits(struct kissat *, bits *, size_t size); 14 | 15 | static inline size_t kissat_bits_size_in_words(size_t size) { 16 | assert(sizeof(bits) == 4); 17 | return (size >> 5) + ! !(size & 31); 18 | } 19 | 20 | static inline bool kissat_get_bit(const bits *bits, size_t size, size_t bit) { 21 | assert(bit < size); 22 | const size_t x = (bit >> 5); 23 | assert(x < kissat_bits_size_in_words(size)); 24 | const unsigned word = bits[x]; 25 | const unsigned y = (bit & 31); 26 | const unsigned mask = (1u << y); 27 | const unsigned masked = word & mask; 28 | const bool res = ! !masked; 29 | (void) size; 30 | return res; 31 | } 32 | 33 | static inline void kissat_set_bit_to_true(bits *bits, size_t size, size_t bit) { 34 | assert(bit < size); 35 | const size_t x = (bit >> 5); 36 | assert(x < kissat_bits_size_in_words(size)); 37 | unsigned word = bits[x]; 38 | const unsigned y = (bit & 31); 39 | const unsigned mask = (1u << y); 40 | word |= mask; 41 | bits[x] = word; 42 | (void) size; 43 | } 44 | 45 | static inline void kissat_set_bit_to_false(bits *bits, size_t size, 46 | size_t bit) { 47 | assert(bit < size); 48 | const size_t x = (bit >> 5); 49 | assert(x < kissat_bits_size_in_words(size)); 50 | unsigned word = bits[x]; 51 | const unsigned y = (bit & 31); 52 | const unsigned mask = (1u << y); 53 | word &= ~mask; 54 | bits[x] = word; 55 | (void) size; 56 | } 57 | 58 | static inline void kissat_set_bit_explicitly(bits *bits, size_t size, 59 | size_t bit, bool value) { 60 | assert(bit < size); 61 | const size_t x = (bit >> 5); 62 | assert(x < kissat_bits_size_in_words(size)); 63 | unsigned word = bits[x]; 64 | const unsigned y = (bit & 31); 65 | const unsigned clear = (1 << y); 66 | const unsigned set = (value << y); 67 | word &= ~clear; 68 | word |= set; 69 | bits[x] = word; 70 | (void) size; 71 | } 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /test/cover/cover0020.cnf: -------------------------------------------------------------------------------- 1 | c status 10 2 | c --bumpreasons=0 3 | c --eliminatebound=0 4 | c --eliminateclslim=0 5 | c --eliminateinit=0 6 | c --eliminateint=0 7 | c --minimizedepth=0 8 | c --otfs=0 9 | c --phase=0 10 | c --reduceinit=10 11 | c --reduceint=0 12 | c --subsumeocclim=0 13 | p cnf 82 110 14 | -7 23 0 15 | -9 -21 0 16 | 13 -18 7 0 17 | 22 23 -17 0 18 | -2 9 0 19 | 19 23 12 3 0 20 | 10 -22 -3 0 21 | -4 6 -21 0 22 | 25 -24 6 0 23 | 10 -5 -17 0 24 | 20 8 -4 0 25 | -9 -10 -5 0 26 | -10 15 -5 0 27 | -5 21 13 -11 3 0 28 | -7 9 2 0 29 | 5 20 0 30 | 7 9 6 8 0 31 | 25 -8 0 32 | -12 -13 0 33 | -20 12 25 0 34 | 21 13 22 0 35 | 38 -26 -40 0 36 | 26 -45 0 37 | -43 -29 0 38 | 48 -32 0 39 | -27 -2 0 40 | 36 -16 0 41 | 18 6 14 0 42 | -1 11 0 43 | 37 22 -28 0 44 | 5 -30 0 45 | -28 16 -22 0 46 | -13 -20 2 0 47 | -44 29 0 48 | 8 -47 -22 0 49 | 21 -45 36 0 50 | -25 -36 -19 0 51 | -21 -15 0 52 | 20 34 0 53 | -32 27 0 54 | 25 7 24 0 55 | 42 2 0 56 | 3 46 28 0 57 | 17 -6 0 58 | -47 39 0 59 | -25 4 6 28 0 60 | -25 5 17 0 61 | 31 55 -59 0 62 | -4 30 14 0 63 | 58 59 0 64 | -47 -3 49 52 0 65 | -59 -34 56 0 66 | -56 -49 0 67 | -51 -24 0 68 | 54 53 -57 0 69 | -58 4 8 3 0 70 | 8 44 -54 12 0 71 | 5 4 52 0 72 | -16 -55 -20 0 73 | 43 10 0 74 | 17 47 0 75 | -13 -28 -59 0 76 | -38 32 -30 0 77 | -54 -38 0 78 | 54 49 -59 -3 -55 0 79 | 20 51 0 80 | -15 -49 0 81 | 59 -37 10 0 82 | -37 -53 57 0 83 | -48 -52 0 84 | -12 -43 0 85 | 59 -54 15 52 0 86 | 59 -8 -23 0 87 | -39 13 53 -59 35 0 88 | -58 55 0 89 | -3 9 -13 0 90 | 56 -53 0 91 | 58 17 -16 0 92 | 49 20 -56 0 93 | -56 -57 -53 0 94 | 55 28 53 -33 0 95 | 40 -4 10 59 0 96 | -54 -30 -42 0 97 | -45 -23 -59 53 0 98 | 56 54 -7 0 99 | -30 15 56 21 0 100 | 57 53 -46 28 23 0 101 | -31 -35 0 102 | -63 -68 0 103 | 60 45 0 104 | -4 -46 0 105 | -14 61 68 0 106 | -50 -52 -53 65 0 107 | -52 -22 0 108 | 81 67 50 0 109 | 76 41 -81 0 110 | 75 -73 71 -82 0 111 | -3 74 -17 82 0 112 | -64 79 0 113 | 66 33 0 114 | -61 78 80 -66 0 115 | 70 1 72 0 116 | -41 -77 0 117 | 64 -62 -67 -65 -80 0 118 | -56 -6 73 0 119 | -74 -76 63 69 -70 -75 62 0 120 | -69 -79 -71 0 121 | 77 -59 42 0 122 | -72 -78 0 123 | -60 29 0 124 | -------------------------------------------------------------------------------- /test/test.h: -------------------------------------------------------------------------------- 1 | #ifndef _tissat_h_INCLUDED 2 | #define _tissat_h_INCLUDED 3 | 4 | #include "../src/inline.h" 5 | #include "../src/print.h" 6 | 7 | #include "testapplication.h" 8 | #include "testdivert.h" 9 | #include "testmessages.h" 10 | #include "testscheduler.h" 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | extern bool tissat_big; 18 | extern bool tissat_found_test_directory; 19 | extern bool tissat_sequential; 20 | extern bool tissat_progress; 21 | 22 | #ifndef NPROOFS 23 | extern bool tissat_found_drabt; 24 | extern bool tissat_found_drat_trim; 25 | #endif 26 | 27 | #ifdef _POSIX_C_SOURCE 28 | extern bool tissat_found_bzip2; 29 | extern bool tissat_found_gzip; 30 | extern bool tissat_found_lzma; 31 | extern bool tissat_found_xz; 32 | extern bool tissat_found_7z; 33 | #endif 34 | 35 | extern const char *tissat_root; 36 | 37 | #define tissat_assert(COND) \ 38 | ( \ 39 | (COND) ? \ 40 | (void) 0 \ 41 | : \ 42 | \ 43 | ( \ 44 | tissat_restore_stdout_and_stderr (), \ 45 | printf ("tissat: %s:%ld: %s: Assertion `%s' failed.\n", \ 46 | __FILE__, (long) __LINE__, __func__, #COND), \ 47 | abort (), \ 48 | (void) 0 \ 49 | ) \ 50 | ) 51 | 52 | #define tissat_assume(COND) \ 53 | ( \ 54 | (COND) ? \ 55 | (void) 0 \ 56 | : \ 57 | \ 58 | ( \ 59 | tissat_restore_stdout_and_stderr (), \ 60 | tissat_warning ("tissat: %s:%ld: %s: Assumption `%s' failed.\n", \ 61 | __FILE__, (long) __LINE__, __func__, #COND), \ 62 | tissat_divert_stdout_and_stderr_to_dev_null (), \ 63 | tissat_warnings++, \ 64 | (void) 0 \ 65 | ) \ 66 | ) 67 | 68 | #ifdef assert 69 | #undef assert 70 | #endif 71 | 72 | #define assume tissat_assume 73 | #define assert tissat_assert 74 | 75 | #define FATAL(...) \ 76 | do { \ 77 | fflush (stdout); \ 78 | tissat_restore_stdout_and_stderr (); \ 79 | tissat_fatal (__VA_ARGS__); \ 80 | } while (0) 81 | 82 | void tissat_init_solver(struct kissat *); 83 | 84 | #define DECLARE_AND_INIT_SOLVER(SOLVER) \ 85 | kissat dummy_solver, *solver = &dummy_solver; \ 86 | memset (&dummy_solver, 0, sizeof dummy_solver); \ 87 | tissat_init_solver (solver) 88 | 89 | #endif 90 | -------------------------------------------------------------------------------- /src/heap.h: -------------------------------------------------------------------------------- 1 | #ifndef _heap_h_INCLUDED 2 | #define _heap_h_INCLUDED 3 | 4 | #include "stack.h" 5 | #include "utilities.h" 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #define DISCONTAIN UINT_MAX 12 | #define DISCONTAINED(IDX) ((int)(IDX) < 0) 13 | 14 | typedef struct heap heap; 15 | 16 | struct heap { 17 | bool tainted; 18 | unsigned vars; 19 | unsigned size; 20 | unsigneds stack; 21 | double *score; 22 | unsigned *pos; 23 | }; 24 | 25 | struct kissat; 26 | 27 | void kissat_resize_heap(struct kissat *, heap *, unsigned size); 28 | void kissat_release_heap(struct kissat *, heap *); 29 | 30 | static inline bool kissat_heap_contains(heap *heap, unsigned idx) { 31 | return idx < heap->vars && !DISCONTAINED(heap->pos[idx]); 32 | } 33 | 34 | static inline unsigned kissat_get_heap_pos(const heap *heap, unsigned idx) { 35 | return idx < heap->vars ? heap->pos[idx] : DISCONTAIN; 36 | } 37 | 38 | static inline double kissat_get_heap_score(const heap *heap, unsigned idx) { 39 | return idx < heap->vars ? heap->score[idx] : 0.0; 40 | } 41 | 42 | static inline bool kissat_empty_heap(heap *heap) { 43 | return EMPTY_STACK(heap->stack); 44 | } 45 | 46 | static inline size_t kissat_size_heap(heap *heap) { 47 | return SIZE_STACK(heap->stack); 48 | } 49 | 50 | static inline unsigned kissat_max_heap(heap *heap) { 51 | assert(!kissat_empty_heap(heap)); 52 | return PEEK_STACK(heap->stack, 0); 53 | } 54 | 55 | void kissat_rescale_heap(struct kissat *, heap *heap, double factor); 56 | 57 | void kissat_enlarge_heap(struct kissat *, heap *, unsigned new_vars); 58 | 59 | static inline double kissat_max_score_on_heap(heap *heap) { 60 | if (!heap->tainted) { 61 | return 0; 62 | } 63 | assert(heap->vars); 64 | const double *const score = heap->score; 65 | const double *const end = score + heap->vars; 66 | double res = score[0]; 67 | for (const double *p = score + 1; p != end; p++) { 68 | res = MAX(res, *p); 69 | } 70 | return res; 71 | } 72 | 73 | #ifndef NDEBUG 74 | void kissat_dump_heap(heap *); 75 | #endif 76 | 77 | #ifndef NDEBUG 78 | void kissat_check_heap(heap *); 79 | #else 80 | #define kissat_check_heap(...) do { } while (0) 81 | #endif 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /test/testsort.c: -------------------------------------------------------------------------------- 1 | #include "../src/allocate.h" 2 | #include "../src/sort.h" 3 | 4 | #include "test.h" 5 | 6 | static bool less_unsigned(unsigned a, unsigned b) { 7 | return a < b; 8 | } 9 | 10 | static void test_sort_unsigneds(void) { 11 | DECLARE_AND_INIT_SOLVER(solver); 12 | #define N 20 13 | unsigned found[N]; 14 | memset(found, 0, sizeof found); 15 | unsigneds stack; 16 | INIT_STACK(stack); 17 | SORT_STACK(unsigned, stack, less_unsigned); 18 | srand(42); 19 | for (unsigned i = 0; i < N; i++) { 20 | unsigned tmp = rand() % N / 2; 21 | PUSH_STACK(stack, tmp); 22 | found[tmp]++; 23 | } 24 | SORT_STACK(unsigned, stack, less_unsigned); 25 | for (all_stack(unsigned, i, stack)) { 26 | printf("%u\n", i); 27 | } 28 | for (all_stack(unsigned, i, stack)) { 29 | assert(found[i]); 30 | found[i]--; 31 | } 32 | for (unsigned i = 0; i < N; i++) { 33 | assert(!found[i]); 34 | } 35 | for (unsigned i = 1; i < N; i++) { 36 | assert(PEEK_STACK(stack, i - 1) <= PEEK_STACK(stack, i)); 37 | } 38 | RELEASE_STACK(stack); 39 | RELEASE_STACK(SORTER); 40 | #ifndef QUIET 41 | RELEASE_STACK(solver->profiles.stack); 42 | #endif 43 | #ifdef METRICS 44 | assert(!solver->statistics.allocated_current); 45 | #endif 46 | #undef N 47 | } 48 | 49 | static bool less_str(const char *a, const char *b) { 50 | return strcmp(a, b) < 0; 51 | } 52 | 53 | static void test_sort_strings(void) { 54 | struct kissat dummy, *solver = &dummy; 55 | memset(&dummy, 0, sizeof dummy); 56 | STACK(const char *) stack; 57 | INIT_STACK(stack); 58 | SORT_STACK(const char *, stack, less_str); 59 | PUSH_STACK(stack, "zzzzz"); 60 | SORT_STACK(const char *, stack, less_str); 61 | PUSH_STACK(stack, "ccccc"); 62 | PUSH_STACK(stack, "bbbbb"); 63 | PUSH_STACK(stack, "xxxxx"); 64 | PUSH_STACK(stack, "aaaaa"); 65 | SORT_STACK(const char *, stack, less_str); 66 | for (all_pointers(const char, s, stack)) { 67 | printf("%s\n", s); 68 | } 69 | RELEASE_STACK(stack); 70 | RELEASE_STACK(SORTER); 71 | #ifndef QUIET 72 | RELEASE_STACK(solver->profiles.stack); 73 | #endif 74 | #ifdef METRICS 75 | assert(!solver->statistics.allocated_current); 76 | #endif 77 | } 78 | 79 | void tissat_schedule_sort(void) { 80 | SCHEDULE_FUNCTION(test_sort_unsigneds); 81 | SCHEDULE_FUNCTION(test_sort_strings); 82 | } 83 | -------------------------------------------------------------------------------- /test/testcnfs.h: -------------------------------------------------------------------------------- 1 | #ifndef _testcnfs_h_INCLUDED 2 | #define _testcnfs_h_INCLUDED 3 | 4 | #define CNFS \ 5 | CNF (20, false, false) \ 6 | CNF (20, unit1, false) \ 7 | CNF (20, unit2, false) \ 8 | CNF (20, unit3, false) \ 9 | CNF (20, unit4, false) \ 10 | CNF (20, unit5, false) \ 11 | CNF (20, unit6, false) \ 12 | CNF (10, true, false) \ 13 | CNF (10, bin1, false) \ 14 | CNF (10, bin2, false) \ 15 | CNF (10, bin3, false) \ 16 | CNF (20, full2, false) \ 17 | CNF (20, full3, false) \ 18 | CNF (20, full4, false) \ 19 | CNF (10, and1, false) \ 20 | CNF (10, and2, false) \ 21 | CNF (10, ite1, false) \ 22 | CNF (10, xor1, false) \ 23 | CNF (10, xor2, false) \ 24 | CNF (10, xor3, false) \ 25 | CNF (10, xor4, false) \ 26 | CNF (20, ph2, false) \ 27 | CNF (20, ph3, false) \ 28 | CNF (20, ph4, false) \ 29 | CNF (20, ph5, false) \ 30 | CNF (20, ph6, false) \ 31 | CNF (10, sqrt3481, false) \ 32 | CNF (10, sqrt3721, false) \ 33 | CNF (10, sqrt2809, false) \ 34 | CNF (10, sqrt12769, false) \ 35 | CNF (10, sqrt5329, false) \ 36 | CNF (10, sqrt6889, false) \ 37 | CNF (10, sqrt4489, false) \ 38 | CNF (10, sqrt5041, false) \ 39 | CNF (10, sqrt6241, false) \ 40 | CNF (10, sqrt7921, false) \ 41 | CNF (10, sqrt16129, false) \ 42 | CNF (10, sqrt11449, false) \ 43 | CNF (10, sqrt10201, false) \ 44 | CNF (10, sqrt10609, false) \ 45 | CNF (10, sqrt9409, false) \ 46 | CNF (10, sqrt11881, false) \ 47 | CNF (10, sqrt63001, false) \ 48 | CNF (10, sqrt259081, false) \ 49 | CNF (10, sqrt1042441, false) \ 50 | CNF (10, prime4, false) \ 51 | CNF (10, prime9, false) \ 52 | CNF (10, prime25, false) \ 53 | CNF (10, prime49, false) \ 54 | CNF (10, prime121, false) \ 55 | CNF (10, prime169, false) \ 56 | CNF (10, prime289, false) \ 57 | CNF (10, prime361, false) \ 58 | CNF (10, prime529, false) \ 59 | CNF (10, prime841, false) \ 60 | CNF (10, prime961, false) \ 61 | CNF (10, prime1369, false) \ 62 | CNF (10, prime1681, false) \ 63 | CNF (10, prime1849, false) \ 64 | CNF (10, prime2209, false) \ 65 | CNF (20, prime65537, false) \ 66 | CNF (20, prime4294967297, true) \ 67 | CNF (20, add4, false) \ 68 | CNF (20, add8, false) \ 69 | CNF (20, add16, false) \ 70 | CNF (20, add32, false) \ 71 | CNF (20, add64, false) \ 72 | CNF (20, add128, false) \ 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /test/testdivert.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "test.h" 7 | 8 | static int dev_null = -1; 9 | static int saved[3] = { -1, -1, -1 }; 10 | 11 | void tissat_divert_stdout_and_stderr_to_dev_null(void) { 12 | if (tissat_verbosity) { 13 | return; 14 | } 15 | assert(saved[1] < 0); 16 | assert(saved[2] < 0); 17 | if (dev_null < 0) { 18 | dev_null = open("/dev/null", O_WRONLY); 19 | } 20 | assert(dev_null >= 3); 21 | saved[1] = dup(1); 22 | assert(saved[1] >= 4); 23 | saved[2] = dup(2); 24 | assert(saved[2] >= 5); 25 | int res; 26 | res = dup2(dev_null, 1); 27 | assert(res == 1); 28 | res = dup2(dev_null, 2); 29 | assert(res == 2); 30 | } 31 | 32 | #define ASSERT(COND) \ 33 | do { \ 34 | if (COND) \ 35 | break; \ 36 | abort (); \ 37 | } while (true) 38 | 39 | static void restore_stdout(void) { 40 | if (saved[1] < 0) { 41 | return; 42 | } 43 | fflush(stdout); 44 | ASSERT(saved[1] >= 4); 45 | int res; 46 | res = dup2(saved[1], 1); 47 | ASSERT(res == 1); 48 | res = close(saved[1]); 49 | ASSERT(!res); 50 | saved[1] = -1; 51 | } 52 | 53 | static void restore_stderr(void) { 54 | if (saved[2] < 0) { 55 | return; 56 | } 57 | fflush(stderr); 58 | ASSERT(saved[2] >= 5); 59 | int res; 60 | res = dup2(saved[2], 2); 61 | ASSERT(res == 2); 62 | res = close(saved[2]); 63 | ASSERT(!res); 64 | saved[2] = -1; 65 | } 66 | 67 | void tissat_restore_stdout_and_stderr(void) { 68 | if (tissat_verbosity) { 69 | return; 70 | } 71 | restore_stdout(); 72 | restore_stderr(); 73 | } 74 | 75 | void tissat_redirect_stderr_to_stdout(void) { 76 | if (dev_null >= 0) { 77 | return; 78 | } 79 | assert(saved[2] < 0); 80 | saved[2] = dup(2); 81 | assert(saved[2] >= 3); 82 | int res; 83 | res = dup2(1, 2); 84 | assert(res == 2); 85 | } 86 | 87 | void tissat_restore_stderr(void) { 88 | if (dev_null >= 0) { 89 | return; 90 | } 91 | if (saved[2] < 0) { 92 | return; 93 | } 94 | fflush(stderr); 95 | ASSERT(saved[2] >= 3); 96 | int res; 97 | res = dup2(saved[2], 2); 98 | ASSERT(res == 2); 99 | res = close(saved[2]); 100 | ASSERT(!res); 101 | saved[2] = -1; 102 | } 103 | -------------------------------------------------------------------------------- /src/resources.c: -------------------------------------------------------------------------------- 1 | #include "resources.h" 2 | 3 | #include 4 | 5 | double kissat_wall_clock_time(void) { 6 | struct timeval tv; 7 | if (gettimeofday(&tv, 0)) { 8 | return 0; 9 | } 10 | return 1e-6 * tv.tv_usec + tv.tv_sec; 11 | } 12 | 13 | #ifndef QUIET 14 | 15 | #include "internal.h" 16 | #include "statistics.h" 17 | #include "utilities.h" 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | double kissat_process_time(void) { 26 | struct rusage u; 27 | double res; 28 | if (getrusage(RUSAGE_SELF, &u)) { 29 | return 0; 30 | } 31 | res = u.ru_utime.tv_sec + 1e-6 * u.ru_utime.tv_usec; 32 | res += u.ru_stime.tv_sec + 1e-6 * u.ru_stime.tv_usec; 33 | return res; 34 | } 35 | 36 | uint64_t kissat_maximum_resident_set_size(void) { 37 | struct rusage u; 38 | if (getrusage(RUSAGE_SELF, &u)) { 39 | return 0; 40 | } 41 | return ((uint64_t) u.ru_maxrss) << 10; 42 | } 43 | 44 | uint64_t kissat_current_resident_set_size(void) { 45 | char path[48]; 46 | sprintf(path, "/proc/%" PRIu64 "/statm", (uint64_t) getpid()); 47 | FILE *file = fopen(path, "r"); 48 | if (!file) { 49 | return 0; 50 | } 51 | uint64_t dummy, rss; 52 | int scanned = fscanf(file, "%" PRIu64 " %" PRIu64 "", &dummy, &rss); 53 | fclose(file); 54 | return scanned == 2 ? rss * sysconf(_SC_PAGESIZE) : 0; 55 | } 56 | 57 | void kissat_print_resources(kissat *solver) { 58 | uint64_t rss = kissat_maximum_resident_set_size(); 59 | double t = kissat_time(solver); 60 | printf("c " 61 | "%-" SFW1 "s " 62 | "%" SFW2 PRIu64 " " 63 | "%-" SFW3 "s " 64 | "%" SFW4 ".0f " 65 | "MB\n", 66 | "maximum-resident-set-size:", 67 | rss, "bytes", rss / (double)(1 << 20)); 68 | #ifdef METRICS 69 | statistics *statistics = &solver->statistics; 70 | uint64_t max_allocated = statistics->allocated_max + sizeof(kissat); 71 | printf("c " 72 | "%-" SFW1 "s " 73 | "%" SFW2 PRIu64 " " 74 | "%-" SFW3 "s " 75 | "%" SFW4 ".0f " 76 | "%%\n", 77 | "max-allocated:", 78 | max_allocated, "bytes", kissat_percent(max_allocated, rss)); 79 | #endif 80 | printf("c process-time: %30s %18.2f seconds\n", FORMAT_TIME(t), t); 81 | fflush(stdout); 82 | } 83 | 84 | #endif 85 | -------------------------------------------------------------------------------- /src/phases.c: -------------------------------------------------------------------------------- 1 | #include "allocate.h" 2 | #include "internal.h" 3 | #include "logging.h" 4 | 5 | #include 6 | 7 | #define realloc_phases(NAME) \ 8 | do { \ 9 | solver->phases.NAME = \ 10 | kissat_realloc (solver, solver->phases.NAME, old_size, new_size); \ 11 | } while (0) 12 | 13 | #define increase_phases(NAME) \ 14 | do { \ 15 | assert (old_size < new_size); \ 16 | realloc_phases (NAME); \ 17 | memset (solver->phases.NAME + old_size, 0, new_size - old_size); \ 18 | } while (0) 19 | 20 | void kissat_increase_phases(kissat *solver, unsigned new_size) { 21 | const unsigned old_size = solver->size; 22 | assert(old_size < new_size); 23 | LOG("increasing phases from %u to %u", old_size, new_size); 24 | increase_phases(best); 25 | increase_phases(saved); 26 | increase_phases(target); 27 | } 28 | 29 | void kissat_decrease_phases(kissat *solver, unsigned new_size) { 30 | const unsigned old_size = solver->size; 31 | assert(old_size > new_size); 32 | LOG("decreasing phases from %u to %u", old_size, new_size); 33 | realloc_phases(best); 34 | realloc_phases(saved); 35 | realloc_phases(target); 36 | } 37 | 38 | #define release_phases(NAME, SIZE) \ 39 | kissat_free (solver, solver->phases.NAME, SIZE) 40 | 41 | void kissat_release_phases(kissat *solver) { 42 | const unsigned size = solver->size; 43 | release_phases(best, size); 44 | release_phases(saved, size); 45 | release_phases(target, size); 46 | } 47 | 48 | static void save_phases(kissat *solver, value *phases) { 49 | const value *const values = solver->values; 50 | const value *const end = phases + VARS; 51 | value const *v = values; 52 | for (value *p = phases, tmp; p != end; p++, v += 2) 53 | if ((tmp = *v)) { 54 | *p = tmp; 55 | } 56 | assert(v == values + LITS); 57 | } 58 | 59 | void kissat_save_best_phases(kissat *solver) { 60 | assert(sizeof(value) == 1); 61 | LOG("saving %u best values", VARS); 62 | save_phases(solver, solver->phases.best); 63 | } 64 | 65 | void kissat_save_saved_phases(kissat *solver) { 66 | assert(sizeof(value) == 1); 67 | LOG("saving %u saved values", VARS); 68 | save_phases(solver, solver->phases.saved); 69 | } 70 | 71 | void kissat_save_target_phases(kissat *solver) { 72 | assert(sizeof(value) == 1); 73 | LOG("saving %u target values", VARS); 74 | save_phases(solver, solver->phases.target); 75 | } 76 | -------------------------------------------------------------------------------- /src/weaken.c: -------------------------------------------------------------------------------- 1 | #include "inline.h" 2 | #include "weaken.h" 3 | 4 | static void push_witness_literal(kissat *solver, unsigned ilit) { 5 | assert(!VALUE(ilit)); 6 | int elit = kissat_export_literal(solver, ilit); 7 | assert(elit); 8 | LOG2("pushing external witness literal %d on extension stack", elit); 9 | const extension ext = kissat_extension(true, elit); 10 | PUSH_STACK(solver->extend, ext); 11 | } 12 | 13 | static void push_clause_literal(kissat *solver, unsigned ilit) { 14 | const value value = VALUE(ilit); 15 | assert(value <= 0); 16 | if (value < 0) { 17 | LOG("not pushing internal falsified clause literal %s " 18 | "on extension stack", LOGLIT(ilit)); 19 | } else { 20 | int elit = kissat_export_literal(solver, ilit); 21 | assert(elit); 22 | LOG2("pushing external clause literal %d on extension stack", elit); 23 | const extension ext = kissat_extension(false, elit); 24 | PUSH_STACK(solver->extend, ext); 25 | } 26 | } 27 | 28 | #define LOGPUSHED(SIZE) \ 29 | do { \ 30 | LOGEXT ((SIZE), END_STACK (solver->extend) - (SIZE), \ 31 | "pushed size %zu witness labelled clause at", (size_t) (SIZE)); \ 32 | } while (0) 33 | 34 | void kissat_weaken_clause(kissat *solver, unsigned lit, clause *c) { 35 | assert(!solver->level); 36 | INC(weakened); 37 | LOGCLS(c, "blocking on %s and weakening", LOGLIT(lit)); 38 | push_witness_literal(solver, lit); 39 | for (all_literals_in_clause(other, c)) { 40 | if (lit != other) { 41 | push_clause_literal(solver, other); 42 | } 43 | } 44 | 45 | if (GET_OPTION(incremental)) { 46 | SHRINK_CLAUSE_IN_PROOF(c, INVALID_LIT, INVALID_LIT); 47 | CHECK_SHRINK_CLAUSE(c, INVALID_LIT, INVALID_LIT); 48 | } 49 | LOGPUSHED(c->size); 50 | } 51 | 52 | void kissat_weaken_binary(kissat *solver, unsigned lit, unsigned other) { 53 | assert(!solver->level); 54 | INC(weakened); 55 | LOGBINARY(lit, other, "blocking on %s and weakening", LOGLIT(lit)); 56 | push_witness_literal(solver, lit); 57 | push_clause_literal(solver, other); 58 | LOGPUSHED(2); 59 | } 60 | 61 | void kissat_weaken_unit(kissat *solver, unsigned lit) { 62 | INC(weakened); 63 | LOG("blocking and weakening unit %s", LOGLIT(lit)); 64 | push_witness_literal(solver, lit); 65 | LOGEXT(1, END_STACK(solver->extend) - 1, 66 | "pushed witness labelled unit clause at"); 67 | } 68 | -------------------------------------------------------------------------------- /src/terminate.h: -------------------------------------------------------------------------------- 1 | #ifndef _terminate_h_INCLUDED 2 | #define _terminate_h_INCLUDED 3 | 4 | #include "internal.h" 5 | 6 | #ifndef QUIET 7 | void kissat_report_termination(kissat *, const char *name, 8 | const char *file, long lineno, 9 | const char *fun); 10 | #endif 11 | 12 | static inline bool kissat_terminated(kissat *solver, int bit, const char *name, 13 | const char *file, long lineno, const char *fun) { 14 | assert(0 <= bit), assert(bit < 64); 15 | #ifdef COVERAGE 16 | const uint64_t mask = (uint64_t) 1 << bit; 17 | if (!(solver->termination.flagged & mask)) { 18 | return false; 19 | } 20 | solver->termination.flagged = ~(uint64_t) 0; 21 | #else 22 | if (!solver->termination.flagged) { 23 | return false; 24 | } 25 | #endif 26 | #ifndef QUIET 27 | kissat_report_termination(solver, name, file, lineno, fun); 28 | #else 29 | (void) file; 30 | (void) fun; 31 | (void) lineno; 32 | (void) name; 33 | #endif 34 | #if !defined (COVERAGE) && defined(NDEBUG) 35 | (void) bit; 36 | #endif 37 | return true; 38 | } 39 | 40 | #define TERMINATED(BIT) \ 41 | kissat_terminated (solver, BIT, #BIT, __FILE__, __LINE__, __func__) 42 | 43 | #define autarky_terminated_1 0 44 | #define autarky_terminated_2 1 45 | #define autarky_terminated_3 2 46 | #define autarky_terminated_4 3 47 | #define backbone_terminated_1 4 48 | #define backbone_terminated_2 5 49 | #define backbone_terminated_3 6 50 | #define backward_terminated_1 7 51 | #define eliminate_terminated_1 8 52 | #define eliminate_terminated_2 9 53 | #define failed_terminated_1 10 54 | #define failed_terminated_2 11 55 | #define forward_terminated_1 12 56 | #define kitten_terminated_1 13 57 | #define rephase_terminated_1 14 58 | #define rephase_terminated_2 15 59 | #define search_terminated_1 16 60 | #define substitute_terminated_1 17 61 | #define sweep_terminated_1 18 62 | #define sweep_terminated_2 19 63 | #define sweep_terminated_3 20 64 | #define ternary_terminated_1 21 65 | #define ternary_terminated_2 22 66 | #define ternary_terminated_3 23 67 | #define transitive_terminated_1 24 68 | #define transitive_terminated_2 25 69 | #define transitive_terminated_3 26 70 | #define vivify_terminated_1 27 71 | #define vivify_terminated_2 28 72 | #define vivify_terminated_3 29 73 | #define vivify_terminated_4 30 74 | #define walk_terminated_1 31 75 | #define walk_terminated_2 32 76 | #define xors_terminated_1 33 77 | 78 | #endif 79 | -------------------------------------------------------------------------------- /test/cnf/add4.cnf: -------------------------------------------------------------------------------- 1 | p cnf 60 157 2 | -9 1 0 3 | -9 -2 0 4 | -1 2 9 0 5 | -10 -1 0 6 | -10 2 0 7 | 1 -2 10 0 8 | -11 -9 0 9 | -11 -10 0 10 | 9 10 11 0 11 | -12 3 0 12 | -12 4 0 13 | -3 -4 12 0 14 | -13 5 0 15 | -13 6 0 16 | -5 -6 13 0 17 | -14 -3 0 18 | -14 -4 0 19 | 3 4 14 0 20 | -15 13 0 21 | -15 -14 0 22 | -13 14 15 0 23 | -16 -12 0 24 | -16 -15 0 25 | 12 15 16 0 26 | -17 -11 0 27 | -17 -16 0 28 | 11 16 17 0 29 | -18 11 0 30 | -18 16 0 31 | -11 -16 18 0 32 | -19 -17 0 33 | -19 -18 0 34 | 17 18 19 0 35 | -20 3 0 36 | -20 -4 0 37 | -3 4 20 0 38 | -21 -3 0 39 | -21 4 0 40 | 3 -4 21 0 41 | -22 -20 0 42 | -22 -21 0 43 | 20 21 22 0 44 | -23 13 0 45 | -23 -22 0 46 | -13 22 23 0 47 | -24 -12 0 48 | -24 -23 0 49 | 12 23 24 0 50 | -25 -11 0 51 | -25 -24 0 52 | 11 24 25 0 53 | -26 11 0 54 | -26 24 0 55 | -11 -24 26 0 56 | -27 -25 0 57 | -27 -26 0 58 | 25 26 27 0 59 | -28 19 0 60 | -28 -27 0 61 | -19 27 28 0 62 | -29 -19 0 63 | -29 27 0 64 | 19 -27 29 0 65 | -30 -28 0 66 | -30 -29 0 67 | 28 29 30 0 68 | -31 7 0 69 | -31 -8 0 70 | -7 8 31 0 71 | -32 -7 0 72 | -32 8 0 73 | 7 -8 32 0 74 | -33 -31 0 75 | -33 -32 0 76 | 31 32 33 0 77 | -34 1 0 78 | -34 2 0 79 | -1 -2 34 0 80 | -35 -1 0 81 | -35 -2 0 82 | 1 2 35 0 83 | -36 -35 0 84 | -36 -16 0 85 | 35 16 36 0 86 | -37 -34 0 87 | -37 -36 0 88 | 34 36 37 0 89 | -38 -33 0 90 | -38 -37 0 91 | 33 37 38 0 92 | -39 33 0 93 | -39 37 0 94 | -33 -37 39 0 95 | -40 -38 0 96 | -40 -39 0 97 | 38 39 40 0 98 | -41 -34 0 99 | -41 -25 0 100 | 34 25 41 0 101 | -42 -33 0 102 | -42 -41 0 103 | 33 41 42 0 104 | -43 33 0 105 | -43 41 0 106 | -33 -41 43 0 107 | -44 -42 0 108 | -44 -43 0 109 | 42 43 44 0 110 | -45 40 0 111 | -45 -44 0 112 | -40 44 45 0 113 | -46 -40 0 114 | -46 44 0 115 | 40 -44 46 0 116 | -47 -45 0 117 | -47 -46 0 118 | 45 46 47 0 119 | -48 30 0 120 | -48 47 0 121 | -30 -47 48 0 122 | -49 7 0 123 | -49 8 0 124 | -7 -8 49 0 125 | -50 -7 0 126 | -50 -8 0 127 | 7 8 50 0 128 | -51 34 0 129 | -51 -50 0 130 | -34 50 51 0 131 | -52 -49 0 132 | -52 -51 0 133 | 49 51 52 0 134 | -53 -35 0 135 | -53 -50 0 136 | 35 50 53 0 137 | -54 -16 0 138 | -54 53 0 139 | 16 -53 54 0 140 | -55 52 0 141 | -55 -54 0 142 | -52 54 55 0 143 | -56 -49 0 144 | -56 -42 0 145 | 49 42 56 0 146 | -57 -55 0 147 | -57 56 0 148 | 55 -56 57 0 149 | -58 55 0 150 | -58 -56 0 151 | -55 56 58 0 152 | -59 -57 0 153 | -59 -58 0 154 | 57 58 59 0 155 | -60 48 0 156 | -60 59 0 157 | -48 -59 60 0 158 | -60 0 159 | -------------------------------------------------------------------------------- /test/testerror.c: -------------------------------------------------------------------------------- 1 | #include "../src/error.h" 2 | #include "../src/handle.h" 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "test.h" 10 | 11 | static void test_real_fatal_error(void) { 12 | int child = fork(); 13 | if (child < 0) { 14 | FATAL("failed to fork child process"); 15 | } else if (child) { 16 | int wstatus; 17 | pid_t pid = waitpid(child, &wstatus, 0); 18 | if (pid != child) { 19 | FATAL("failed to wait on child process"); 20 | } else if (WIFEXITED(wstatus)) { 21 | FATAL("child exited"); 22 | } else if (!WIFSIGNALED(wstatus)) { 23 | FATAL("child not signalled"); 24 | } else { 25 | int sig = WTERMSIG(wstatus); 26 | if (sig != SIGABRT) 27 | FATAL("child terminated by signal '%d' (%s) " 28 | "and not as expected by '%d' (SIGABRT)", 29 | sig, kissat_signal_name(sig), (int)(SIGABRT)); 30 | } 31 | } else { 32 | kissat_reset_signal_handler(); 33 | kissat_fatal("real fatal error message triggering 'abort'"); 34 | exit(0); 35 | } 36 | } 37 | 38 | #include 39 | 40 | static jmp_buf jump_buffer; 41 | 42 | static void abort_call_back(void) { 43 | longjmp(jump_buffer, 42); 44 | } 45 | 46 | static void test_fake_fatal_error(void) { 47 | kissat_call_function_instead_of_abort(abort_call_back); 48 | int val = setjmp(jump_buffer); 49 | if (val) { 50 | kissat_call_function_instead_of_abort(0); 51 | if (val != 42) { 52 | FATAL("expected '42' as result from 'setjmp'"); 53 | } 54 | } else { 55 | kissat_fatal("faked fatal error message triggering long jump"); 56 | kissat_call_function_instead_of_abort(0); 57 | FATAL("long jump not taken"); 58 | } 59 | } 60 | 61 | static void just_return_call_back(void) { 62 | } 63 | 64 | static void test_just_return_from_fatal_error(void) { 65 | kissat_call_function_instead_of_abort(just_return_call_back); 66 | kissat_fatal("faked just returning fatal error message"); 67 | } 68 | 69 | static void test_start_of_fatal_error_message(void) { 70 | kissat_fatal_message_start(); 71 | printf("after starting a fatal error message printing this message\n"); 72 | fflush(stdout); 73 | } 74 | 75 | void tissat_schedule_error(void) { 76 | SCHEDULE_FUNCTION(test_real_fatal_error); 77 | SCHEDULE_FUNCTION(test_fake_fatal_error); 78 | SCHEDULE_FUNCTION(test_just_return_from_fatal_error); 79 | SCHEDULE_FUNCTION(test_start_of_fatal_error_message); 80 | } 81 | -------------------------------------------------------------------------------- /makefile.in: -------------------------------------------------------------------------------- 1 | CC=@CC@ 2 | LD=@LD@ 3 | AR=@AR@ 4 | 5 | VPATH=../src:../test 6 | 7 | %.o: %.c ../[st]*/*.h makefile 8 | $(CC) -c $< 9 | 10 | %.h.check: %.h ../[st]*/*.h makefile 11 | $(CC) -c $< -o $@ 12 | 13 | APPSRC=application.c handle.c parse.c witness.c 14 | 15 | LIBSRT=$(sort $(wildcard ../src/*.c)) 16 | LIBSUB=$(subst ../src/,,$(LIBSRT)) 17 | LIBSRC=$(filter-out main.c $(APPSRC),$(LIBSUB)) 18 | 19 | TSTSRT=$(sort $(wildcard ../test/*.c)) 20 | TSTSUB=$(subst ../test/,,$(TSTSRT)) 21 | TSTSRC=$(filter-out test.c,$(TSTSUB)) 22 | 23 | HEADSRT=$(sort $(wildcard ../src/*.h)) 24 | HEADSUB=$(subst ../src/,,$(HEADSRT)) 25 | HEADSRC=$(filter-out proplit.h,$(HEADSUB)) 26 | HEADCHK=$(HEADSRC:.h=.h.check) 27 | 28 | APPOBJ=$(APPSRC:.c=.o) 29 | LIBOBJ=$(LIBSRC:.c=.o) 30 | TSTOBJ=$(APPOBJ) $(TSTSRC:.c=.o) 31 | 32 | INCLUDES=-I../$(shell pwd|sed -e 's,.*/,,') 33 | 34 | LIBS=libkissat.a 35 | 36 | all: @GOALS@ 37 | 38 | test: all tissat 39 | ./tissat 40 | 41 | headers: $(HEADCHK) 42 | 43 | REMOVE=*.gcda *.gcno *.gcov gmon.out *~ *.proof 44 | 45 | clean: 46 | rm -f kissat tissat kitten 47 | rm -f makefile build.h *.o *.a *.so 48 | rm -f $(REMOVE) 49 | cd ../src; rm -f $(REMOVE) 50 | cd ../test; rm -f $(REMOVE) 51 | 52 | coverage: 53 | @gcov -o . -s ../src/*.[ch] 2>&1 | \ 54 | ../scripts/filter-coverage-output.sh 55 | indent: 56 | printf '%s\n' ../*/*.[ch] | xargs -n 1 -P $(shell nproc) -- \ 57 | astyle -n -q --style=attach \ 58 | -j -xf -xh -xC80 -s2 -xU -xt3 -L -k3 -W3 -p -xg -U -H 59 | 60 | kissat: main.o $(APPOBJ) libkissat.a makefile 61 | $(LD) -o $@ main.o $(APPOBJ) $(LIBS) -lm 62 | 63 | tissat: test.o $(TSTOBJ) libkissat.a makefile 64 | $(LD) -o $@ test.o $(TSTOBJ) $(LIBS) -lm 65 | 66 | kitten: kitten.c random.h stack.h makefile 67 | $(CC) $(CFLAGS) -DSTAND_ALONE_KITTEN -o $@ ../src/kitten.c 68 | 69 | build.h: 70 | ../scripts/generate-build-header.sh > $@ 71 | 72 | collect.o: sort.c 73 | dense.o: sort.c 74 | propdense.o: assign.c 75 | prophyper.o: assign.c 76 | proprobe.o: assign.c 77 | propsearch.o: assign.c 78 | watch.o: sort.c 79 | 80 | build.o: build.c build.h ../[st]*/*.h makefile 81 | $(CC) $(INCLUDES) -c $< 82 | 83 | testkitten.o: testkitten.c ../[st]*/*.h makefile 84 | $(CC)@KITTEN@ -c $< 85 | 86 | test.o: test.c build.h ../[st]*/*.h makefile 87 | $(CC) $(INCLUDES) -c $< 88 | 89 | libkissat.a: $(LIBOBJ) makefile 90 | $(AR) rc $@ $(LIBOBJ) 91 | 92 | libkissat.so: $(LIBOBJ) makefile 93 | $(LD) -shared -o $@ $(LIBOBJ) 94 | 95 | .PHONY: all clean coverage headers indent test build.h 96 | -------------------------------------------------------------------------------- /test/testcoverage.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "test.h" 6 | 7 | static bool is_cover_file_name(const char *name) { 8 | #define CHAR(CH) (*p++ == CH) 9 | #define DIGIT() (isdigit ((int) *p++)) 10 | const char *p = name; 11 | // *INDENT-OFF* 12 | return 13 | CHAR ('c') && CHAR ('o') && CHAR ('v') && CHAR ('e') && CHAR ('r') && 14 | DIGIT () && DIGIT () && DIGIT () && DIGIT () && 15 | CHAR ('.') && CHAR ('c') && CHAR ('n') && CHAR ('f'); 16 | // *INDENT-ON* 17 | #undef CHAR 18 | #undef DIGIT 19 | } 20 | 21 | static void schedule_cover_file(const char *dir, const char *name) { 22 | char path[512]; 23 | assert(dir[0]); 24 | assert(dir[strlen(dir) - 1] == '/'); 25 | assert(strlen(dir) + strlen(name) + 1 < sizeof path); 26 | sprintf(path, "%s%s", dir, name); 27 | FILE *file = fopen(path, "r"); 28 | if (!file) { 29 | FATAL("could not read '%s'", path); 30 | } 31 | int status; 32 | if (fscanf(file, "c status %d\n", &status) != 1) 33 | FATAL("parse error at line 1 in '%s': expected 'c status '", 34 | path); 35 | fclose(file); 36 | tissat_schedule_application(status, path); 37 | } 38 | 39 | #define MAX_COVER_FILES (1<<16) 40 | 41 | static char *cover_files[MAX_COVER_FILES]; 42 | static size_t size_cover_files; 43 | 44 | static void push_cover_file(const char *name) { 45 | assert(size_cover_files < MAX_COVER_FILES); 46 | char *tmp = malloc(strlen(name) + 1); 47 | cover_files[size_cover_files++] = strcpy(tmp, name); 48 | } 49 | 50 | static int cmp(const void *p, const void *q) { 51 | return strcmp(*(char **) p, *(char **) q); 52 | } 53 | 54 | static void sort_cover_files(void) { 55 | qsort(cover_files, size_cover_files, sizeof(char *), cmp); 56 | } 57 | 58 | void tissat_schedule_coverage(void) { 59 | if (!tissat_found_test_directory) { 60 | return; 61 | } 62 | const char *path = "../test/cover/"; 63 | DIR *dir = opendir(path); 64 | if (!dir) 65 | FATAL("could not open directory '%s' " 66 | "(even though '../test/' claimed to exist)", path); 67 | struct dirent *entry; 68 | const char *name; 69 | while ((entry = readdir(dir))) 70 | if (is_cover_file_name((name = entry->d_name))) { 71 | push_cover_file(name); 72 | } 73 | closedir(dir); 74 | sort_cover_files(); 75 | for (size_t i = 0; i < size_cover_files; i++) { 76 | schedule_cover_file(path, cover_files[i]); 77 | } 78 | for (size_t i = 0; i < size_cover_files; i++) { 79 | free(cover_files[i]); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/clause.h: -------------------------------------------------------------------------------- 1 | #ifndef _clause_h_INCLUDED 2 | #define _clause_h_INCLUDED 3 | 4 | #include "arena.h" 5 | #include "literal.h" 6 | #include "reference.h" 7 | #include "utilities.h" 8 | 9 | #include 10 | 11 | typedef struct clause clause; 12 | 13 | #define LD_MAX_GLUE 21u 14 | #define MAX_GLUE ((1u<searched) 39 | 40 | #define BEGIN_LITS(C) ((C)->lits) 41 | #define END_LITS(C) (BEGIN_LITS (C) + (C)->size) 42 | 43 | #define all_literals_in_clause(LIT,C) \ 44 | unsigned LIT, * LIT ## _PTR = BEGIN_LITS (C), \ 45 | * const LIT ## _END = END_LITS (C); \ 46 | LIT ## _PTR != LIT ## _END && ((LIT = *LIT ## _PTR), true); \ 47 | ++LIT ## _PTR 48 | 49 | static inline size_t kissat_bytes_of_clause(unsigned size) { 50 | const size_t res = sizeof(clause) + (size - 3) * sizeof(unsigned); 51 | return kissat_align_ward(res); 52 | } 53 | 54 | static inline size_t kissat_actual_bytes_of_clause(clause *c) { 55 | unsigned const *p = END_LITS(c); 56 | if (c->shrunken) 57 | while (*p++ != INVALID_LIT) 58 | ; 59 | return kissat_align_ward((char *) p - (char *) c); 60 | } 61 | 62 | static inline clause *kissat_next_clause(clause *c) { 63 | word bytes = kissat_actual_bytes_of_clause(c); 64 | return (clause *)((char *) c + bytes); 65 | } 66 | 67 | struct kissat; 68 | 69 | void kissat_new_binary_clause(struct kissat *, 70 | bool redundant, unsigned, unsigned); 71 | 72 | reference kissat_new_original_clause(struct kissat *); 73 | reference kissat_new_irredundant_clause(struct kissat *); 74 | reference kissat_new_redundant_clause(struct kissat *, unsigned glue); 75 | 76 | #ifndef INLINE_SORT 77 | void kissat_sort_literals(struct kissat *, unsigned size, unsigned *lits); 78 | #endif 79 | 80 | void kissat_connect_clause(struct kissat *, clause *); 81 | 82 | clause *kissat_delete_clause(struct kissat *, clause *); 83 | void kissat_delete_binary(struct kissat *, 84 | bool redundant, bool hyper, bool weakened, unsigned, unsigned); 85 | 86 | void kissat_mark_clause_as_garbage(struct kissat *, bool weakened, clause *); 87 | 88 | #endif 89 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # The Kissat Extras SAT Solver 2 | 3 | This is a fork of Armin Biere's Kissat SAT Solver ([arminbiere/kissat]). Kassat 4 | Extras aims to provide additional functionality currently not available in the 5 | upstream version of Kissat. 6 | 7 | **Warning:** This is a work in progress and has not seen sufficient testing for 8 | production use. 9 | 10 | [arminbiere/kissat]:https://github.com/arminbiere/kissat 11 | 12 | ## New Functionality 13 | 14 | * Solving under assumptions 15 | * Requires use of the incremental solving modes mentioned below 16 | * Incremental solving via clause restoration 17 | * Enabled via the option `incremental` (on by default) 18 | * Transparent to the user 19 | * Incremental solving using `protect`/`unprotect` 20 | * Similar to `freeze`/`meld` but more flexible w.r.t. inprocessing 21 | * Allows protecting variables before the first search and fresh 22 | variables between searches. 23 | * Allows assuming and adding new clauses on protected variables even when 24 | `incremental` is off. 25 | * Still allows equivalent literal substitution of protected variables 26 | * _Planned:_ allow temporary elimination during inprocessing 27 | * _Planned:_ user provided constraint propagators on protected variables 28 | * `compile_commands.json` generation from `./configure` 29 | 30 | Software that wants to be compatible with both, upstream Kissat and Kissat 31 | Extras, can use the `KISSAT_EXTRAS` preprocessor macro that is defined by this 32 | fork. 33 | 34 | ## Why a Fork? 35 | 36 | Currently, the upstream project does not accept external contributions. This 37 | makes a fork the only option. 38 | 39 | ## Source Code Formatting 40 | 41 | Note that I reformatted all source files before I added any new functionality. 42 | While I usually try to follow existing conventions when working on an existing 43 | project, I make an exception for the GNU code style used by the upstream 44 | project. 45 | 46 | Besides reformatting, I also adjusted the `make indent` target to use `astyle` 47 | instead of GNU `indent`. If it becomes necessary, it should be possible to 48 | mostly automate conversion of individual patches from one style to another. 49 | 50 | ## Original Readme 51 | 52 | Kissat is a "keep it simple and clean bare metal SAT solver" written in C. 53 | It is a port of CaDiCaL back to C with improved data structures, better 54 | scheduling of inprocessing and optimized algorithms and implementation. 55 | 56 | Coincidentally "kissat" also means "cats" in Finnish. 57 | 58 | Run `./configure && make test` to configure, build and test in `build`. 59 | -------------------------------------------------------------------------------- /src/config.c: -------------------------------------------------------------------------------- 1 | #ifndef NOPTIONS 2 | 3 | #include "config.h" 4 | #include "kissat.h" 5 | #include "options.h" 6 | 7 | #include 8 | #include 9 | 10 | int kissat_has_configuration(const char *name) { 11 | if (!strcmp(name, "basic")) { 12 | return 1; 13 | } 14 | if (!strcmp(name, "default")) { 15 | return 1; 16 | } 17 | if (!strcmp(name, "plain")) { 18 | return 1; 19 | } 20 | if (!strcmp(name, "sat")) { 21 | return 1; 22 | } 23 | if (!strcmp(name, "unsat")) { 24 | return 1; 25 | } 26 | return 0; 27 | } 28 | 29 | void kissat_configuration_usage(void) { 30 | #define FMT " --%-8s %s" 31 | printf(FMT "\n", "basic", "basic CDCL solving " 32 | "('--plain' but no restarts, minimize, reduce)"); 33 | printf(FMT "\n", "default", "default configuration"); 34 | printf(FMT "\n", "plain", 35 | "plain CDCL solving without advanced techniques"); 36 | printf(FMT " ('--target=%d --restartint=%d')\n", "sat", 37 | "target satisfiable instances", (int) TARGET_SAT, 38 | (int) RESTARTINT_SAT); 39 | printf(FMT " ('--stable=%d')\n", "unsat", "target unsatisfiable instances", 40 | (int) STABLE_UNSAT); 41 | } 42 | 43 | static void set_plain_options(kissat *solver) { 44 | kissat_set_option(solver, "bumpreasons", 0); 45 | kissat_set_option(solver, "chrono", 0); 46 | kissat_set_option(solver, "compact", 0); 47 | kissat_set_option(solver, "eagersubsume", 0); 48 | kissat_set_option(solver, "otfs", 0); 49 | kissat_set_option(solver, "rephase", 0); 50 | kissat_set_option(solver, "restartreusetrail", 0); 51 | kissat_set_option(solver, "simplify", 0); 52 | kissat_set_option(solver, "stable", 0); 53 | kissat_set_option(solver, "tumble", 0); 54 | } 55 | 56 | int kissat_set_configuration(kissat *solver, const char *name) { 57 | if (!strcmp(name, "basic")) { 58 | set_plain_options(solver); 59 | kissat_set_option(solver, "restart", 0); 60 | kissat_set_option(solver, "reduce", 0); 61 | kissat_set_option(solver, "minimize", 0); 62 | return 1; 63 | } 64 | if (!strcmp(name, "default")) { 65 | return 1; 66 | } 67 | if (!strcmp(name, "plain")) { 68 | set_plain_options(solver); 69 | return 1; 70 | } 71 | if (!strcmp(name, "sat")) { 72 | kissat_set_option(solver, "target", TARGET_SAT); 73 | kissat_set_option(solver, "restartint", RESTARTINT_SAT); 74 | return 1; 75 | } 76 | if (!strcmp(name, "unsat")) { 77 | kissat_set_option(solver, "stable", STABLE_UNSAT); 78 | return 1; 79 | } 80 | return 0; 81 | } 82 | 83 | #else 84 | int kissat_config_dummy_to_avoid_warning; 85 | #endif 86 | -------------------------------------------------------------------------------- /src/sort.c: -------------------------------------------------------------------------------- 1 | #include "internal.h" 2 | #include "logging.h" 3 | 4 | static inline value move_smallest_literal_to_front(kissat *solver, 5 | const value *const values, 6 | const assigned *const assigned, 7 | bool satisfied_is_enough, 8 | unsigned start, unsigned size, unsigned *lits) { 9 | assert(1 < size); 10 | assert(start < size); 11 | 12 | unsigned a = lits[start]; 13 | 14 | value u = values[a]; 15 | if (!u || (u > 0 && satisfied_is_enough)) { 16 | return u; 17 | } 18 | 19 | unsigned pos = 0, best = a; 20 | 21 | { 22 | const unsigned i = IDX(a); 23 | unsigned k = (u ? assigned[i].level : UINT_MAX); 24 | 25 | assert(start < UINT_MAX); 26 | for (unsigned i = start + 1; i < size; i++) { 27 | const unsigned b = lits[i]; 28 | const value v = values[b]; 29 | 30 | if (!v || (v > 0 && satisfied_is_enough)) { 31 | best = b; 32 | pos = i; 33 | u = v; 34 | break; 35 | } 36 | 37 | const unsigned j = IDX(b); 38 | const unsigned l = (v ? assigned[j].level : UINT_MAX); 39 | 40 | bool better; 41 | 42 | if (u < 0 && v > 0) { 43 | better = true; 44 | } else if (u > 0 && v < 0) { 45 | better = false; 46 | } else if (u < 0) { 47 | assert(v < 0); 48 | better = (k < l); 49 | } else { 50 | assert(u > 0); 51 | assert(v > 0); 52 | assert(!satisfied_is_enough); 53 | better = (k > l); 54 | } 55 | 56 | if (!better) { 57 | continue; 58 | } 59 | 60 | best = b; 61 | pos = i; 62 | u = v; 63 | k = l; 64 | } 65 | } 66 | 67 | if (!pos) { 68 | return u; 69 | } 70 | 71 | lits[start] = best; 72 | lits[pos] = a; 73 | 74 | LOG("new smallest literal %s at %u swapped with %s at %u", 75 | LOGLIT(best), pos, LOGLIT(a), start); 76 | #ifndef LOGGING 77 | (void) solver; 78 | #endif 79 | return u; 80 | } 81 | 82 | #ifdef INLINE_SORT 83 | static inline 84 | #endif 85 | void 86 | kissat_sort_literals(kissat *solver, 87 | #ifdef INLINE_SORT 88 | const value *const values, const assigned *assigned, 89 | #endif 90 | unsigned size, unsigned *lits) { 91 | #ifndef INLINE_SORT 92 | const value *const values = solver->values; 93 | const assigned *const assigned = solver->assigned; 94 | #endif 95 | value u = move_smallest_literal_to_front(solver, values, assigned, 96 | false, 0, size, lits); 97 | if (size > 2) 98 | move_smallest_literal_to_front(solver, values, assigned, 99 | (u >= 0), 1, size, lits); 100 | } 101 | --------------------------------------------------------------------------------