{"id":20686918,"url":"https://github.com/gbury/msat","last_synced_at":"2025-04-22T14:07:21.686Z","repository":{"id":22578628,"uuid":"25920171","full_name":"Gbury/mSAT","owner":"Gbury","description":"A modular sat/smt solver with proof output.","archived":false,"fork":false,"pushed_at":"2024-01-08T16:44:31.000Z","size":5160,"stargazers_count":99,"open_issues_count":7,"forks_count":8,"subscribers_count":13,"default_branch":"master","last_synced_at":"2025-04-22T14:07:08.702Z","etag":null,"topics":["clause","formal-methods","formula","modular","ocaml","sat-solver","smt-solver","solver"],"latest_commit_sha":null,"homepage":"https://gbury.github.io/mSAT/","language":"OCaml","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Gbury.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2014-10-29T12:37:48.000Z","updated_at":"2025-02-13T18:34:37.000Z","dependencies_parsed_at":"2024-11-16T22:48:20.546Z","dependency_job_id":null,"html_url":"https://github.com/Gbury/mSAT","commit_stats":null,"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Gbury%2FmSAT","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Gbury%2FmSAT/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Gbury%2FmSAT/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Gbury%2FmSAT/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Gbury","download_url":"https://codeload.github.com/Gbury/mSAT/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250255710,"owners_count":21400410,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clause","formal-methods","formula","modular","ocaml","sat-solver","smt-solver","solver"],"created_at":"2024-11-16T22:37:21.078Z","updated_at":"2025-04-22T14:07:21.661Z","avatar_url":"https://github.com/Gbury.png","language":"OCaml","funding_links":[],"categories":[],"sub_categories":[],"readme":"# MSAT  [![Build Status](https://travis-ci.org/Gbury/mSAT.svg?branch=master)](https://travis-ci.org/Gbury/mSAT)\n\nMSAT is an OCaml library that features a modular SAT-solver and some\nextensions (including SMT), derived from [Alt-Ergo Zero](http://cubicle.lri.fr/alt-ergo-zero).\n\nIt was presented at [ICFP 2017](https://icfp17.sigplan.org/event/ocaml-2017-papers-msat-an-ocaml-sat-solver),\nusing a [poster](https://github.com/Gbury/mSAT/blob/master/articles/icfp_2017.pdf)\n\n\n## COPYRIGHT\n\nThis program is distributed under the Apache Software License version\n2.0. See the enclosed file `LICENSE`.\n\n## Documentation\n\nSee https://gbury.github.io/mSAT/\n\n## INSTALLATION\n\n### Via opam\n\nOnce the package is on [opam](http://opam.ocaml.org), just `opam install msat`.\nFor the development version, use:\n\n```\nopam pin add msat https://github.com/Gbury/mSAT.git\n```\n\n### Manual installation\n\nYou will need `dune` and `iter`. The command is:\n\n```\n$ make install\n```\n\n## USAGE\n\n### Generic SAT/SMT Solver\n\nA modular implementation of the SMT algorithm can be found in the `Msat.Solver` module,\nas a functor which takes two modules :\n\n  - A representation of formulas (which implements the `Formula_intf.S` signature)\n\n  - A theory (which implements the `Theory_intf.S` signature) to check consistence of assertions.\n\n  - A dummy empty module to ensure generativity of the solver (solver modules heavily relies on\n  side effects to their internal state)\n\n### Sat Solver\n\nA ready-to-use SAT solver is available in the `Msat_sat` module\nusing the `msat.sat` library. It can be loaded\nas shown in the following code :\n\n```ocaml\n# #require \"msat\";;\n# #require \"msat.sat\";;\n# #print_depth 0;; (* do not print details *)\n```\n\nThen we can create a solver and create some boolean variables:\n\n```ocaml\nmodule Sat = Msat_sat\nmodule E = Sat.Int_lit (* expressions *)\n\nlet solver = Sat.create()\n\n(* We create here two distinct atoms *)\nlet a = E.fresh ()    (* A 'new_atom' is always distinct from any other atom *)\nlet b = E.make 1      (* Atoms can be created from integers *)\n```\n\nWe can try and check the satisfiability of some clauses — here, the clause `a or b`.\n`Sat.assume` adds a list of clauses to the solver. Calling `Sat.solve`\nwill check the satisfiability of the current set of clauses, here \"Sat\".\n\n```ocaml\n# a \u003c\u003e b;;\n- : bool = true\n# Sat.assume solver [[a; b]] ();;\n- : unit = ()\n# let res = Sat.solve solver;;\nval res : Sat.res = Sat.Sat ...\n```\n\nThe Sat solver has an incremental mutable state, so we still have\nthe clause `a or b` in our assumptions.\nWe add `not a` and `not b` to the state, and get \"Unsat\".\n\n```ocaml\n# Sat.assume solver [[E.neg a]; [E.neg b]] () ;;\n- : unit = ()\n# let res = Sat.solve solver ;;\nval res : Sat.res = Sat.Unsat ...\n```\n\n#### Formulas API\n\nWriting clauses by hand can be tedious and error-prone.\nThe functor `Msat_tseitin.Make` in the library `msat.tseitin`\nproposes a formula AST (parametrized by\natoms) and a function to convert these formulas into clauses:\n\n```ocaml\n# #require \"msat.tseitin\";;\n```\n\n```ocaml\n(* Module initialization *)\nmodule F = Msat_tseitin.Make(E)\n\nlet solver = Sat.create ()\n\n(* We create here two distinct atoms *)\nlet a = E.fresh ()    (* A fresh atom is always distinct from any other atom *)\nlet b = E.make 1      (* Atoms can be created from integers *)\n\n(* Let's create some formulas *)\nlet p = F.make_atom a\nlet q = F.make_atom b\nlet r = F.make_and [p; q]\nlet s = F.make_or [F.make_not p; F.make_not q]\n```\n\nWe can try and check the satisfiability of the given formulas, by turning\nit into clauses using `make_cnf`:\n\n```ocaml\n# Sat.assume solver (F.make_cnf r) ();;\n- : unit = ()\n# Sat.solve solver;;\n- : Sat.res = Sat.Sat ...\n```\n\n```ocaml\n# Sat.assume solver (F.make_cnf s) ();;\n- : unit = ()\n# Sat.solve solver ;;\n- : Sat.res = Sat.Unsat ...\n```\n\n### CDCL(T): a Sudoku solver as an example\n\nThe directory `src/sudoku/` contains a simple Sudoku solver that\nuses the interface `Msat.Make_cdcl_t`.\nIn essence, it implements the logical theory `CDCL(Sudoku)`.\nThe script `sudoku_solve.sh` compiles and runs the solver,\nas does `dune exec src/sudoku/sudoku_solve.exe`.\n\nIt's able to parse sudoku grids denoted as 81 integers\n(see `tests/sudoku/sudoku.txt` for example).\n\nHere is a sample grid and the output from the solver (in roughly .5s):\n\n```sh non-deterministic=command\n$ echo '..............3.85..1.2.......5.7.....4...1...9.......5......73..2.1........4...9' \u003e sudoku.txt\n$ dune exec src/sudoku/sudoku_solve.exe -- sudoku.txt\n...\n#########################\nsolve grid:\n  .........\n  .....3.85\n  ..1.2....\n  ...5.7...\n  ..4...1..\n  .9.......\n  5......73\n  ..2.1....\n  ....4...9\n  \n...\n  987654321\n  246173985\n  351928746\n  128537694\n  634892157\n  795461832\n  519286473\n  472319568\n  863745219\n  \n###################\n...\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgbury%2Fmsat","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgbury%2Fmsat","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgbury%2Fmsat/lists"}