Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented an interface to BatSat #84

Closed
wants to merge 27 commits into from

Conversation

nfbruns
Copy link
Contributor

@nfbruns nfbruns commented Apr 10, 2024

Description of the Contribution

Implemented an interface to the BatSat solver (https://github.com/c-cube/batsat)

Questions / Considerations

The add_clause_reuse(&mut c) function in fn add_clause(&mut self, clause: Clause) returns false if the Solver is in an UNSAT state. Should we handle that with an error message or just return Ok(()) as it is now?
My suggestion is that since we have no way to remove clauses from this solver, there cannot be a way to get the solver out of the UNSAT state, therefor, the return of Ok(()) is fine, even if the clause was not added.

PR Checklist

  • I read and agree to CONTRIBUTING.md
  • I have formatted my code with rustfmt / cargo fmt --all
  • Commits are named following conventional commits
  • I have added documentation for new features
  • The test suite still passes on this PR
  • I have added tests for new features / tests that would have caught the bug this PR fixes (please explain if not)

@nfbruns nfbruns force-pushed the feat-batsat-solver branch from 7332e03 to 31d7e1c Compare April 10, 2024 15:12
@nfbruns nfbruns marked this pull request as ready for review April 10, 2024 15:14
@chrjabs
Copy link
Owner

chrjabs commented Apr 11, 2024

Without having time to look at this closely right now, for a solver that is purely written in rust, I wonder whether it makes more sense to implement the RustSAT traits either in the main RustSAT crate (behind a feature switch) or in the original solver crate. That would eliminate an additional crate in the dependency graph, enable more optimizations for the compiler and make the implementation a bit nicer by, e.g., allowing implementations of the From trait to convert between RustSAT and solver types. (Would for example be interesting here for the lbool <=> TernaryVal relationship.)
I mainly factored the C-based solvers out because of the required external C build.

@chrjabs
Copy link
Owner

chrjabs commented Apr 12, 2024

@nfbruns, do you have where this implementation would make the most sense? Are there any specific reasons why you implemented this as a separate crate other than that that's what I did so far for solvers?
My thoughts on the different options of implementing the Solve trait (and related) for a solver implemented in Rust right now are the following:

  • Implementation in rustsat-<solver> crate: seems a bit overkill for this little code "between" RustSAT and the actual solver
  • Implement with the original solver: very dependent on the solver developer, whether they're interested to support RustSAT / how quickly they would make updates if the RustSAT API changes
  • Implement in main rustsat crate behind feature with optional dependency on the solver crate: probably my favourite. As outlined above, this eliminates an unnecessary type, makes some of the implementation simpler and shouldn't really have any drawbacks for using RustSAT without the solver either (by not activating the feature). This also seems similar to what PyO3 seems to for example do to support anyhow / serde, even though arguably their usecase is more similar to implementing this in the solver crate behind a feature.

@nfbruns
Copy link
Contributor Author

nfbruns commented Apr 20, 2024

I went directly with implementing it using the rustsat-<solver> setup since I have understood that to be the preferred way. But I completely understand your thoughts. I will try to summarize my opinions for the different options:

  • Implementation in rustsat-<solver> crate:
    I agree that for this "little" interface for batsat this is a bit of an overkill. Still i think it makes sense to handle it in this way since now anyone can implement a new solver interface in a separate crate and share it with the Opern Source world - and if you see it as "important enough", you can add it to the rustsat git repository or else it can continue to live as a seperate crate.

  • Implement with the original solver
    Of cause it depends on the maintainers of the original solver crates and their willingness to cooperate. One further downside would be the handling of interface changes to rustsat. If a interface changes in rustsat, all the other creates would need to update too, which needs a lot of cumminication, the availaility of the maintainers and could lead to a mess of interface versions. (except if the current version is stable enough to be considered "unchanching")

  • Implement in main rustsat crate behind feature
    Also possible. In my Solver implementation (which extends yours), I have handled it so that in the core crate rustsat-<solvers> are dev-dependencies used for testing. In the other crates I import the core crate and an applicable solver. This has so far worked really well. I think that feature flags kind of defeats the principle of "separation of concern" since the core rustsat crate defines the traits and the solvers implement it. Having the solvers in the rustsat core as features and other solvers as crates from the community would make it a bit inconsistent, i think.

I hope that helps, let me know what your thoughts are.

@chrjabs
Copy link
Owner

chrjabs commented Apr 23, 2024

Thanks for laying out your thoughts. I agree that having all solvers structured in the same way has its advantages. Here are some more thoughts.

  • At the current early stage of this library, it is probably indeed better to maintain the trait implementations in this project rather than in potential solver crates to avoid work for the solver developers to adjust to changes in the trait definitions.
  • Regarding the wrapper type, I'm less thinking of performance (the type is transparent indeed, so that shouldn't be an issue, but of usability. Needing the wrapper type means that functionality of the core solver that is not available via RustSAT traits are not accessible any more. I guess as a workaround something along the lines Wrapper::core_mut(&mut self) -> &mut Core and the respective _ref can and should be available, but that is slightly less ergonomic.

Another open question about doing it this way that I still have is related to authorship and ownership on crates.io. In this PR you specified yourself as the author of the crate, which is definitely valid, since you wrote the code. If this makes it into the main repository, releases will be done through the CI and crates.io ownership will therefore have to be under my account. Are you find with that? I guess I might have to add something like that to the contribution guideline as well.

Related to your question about why you cannot extend foreign types with foreign traits: as explained here this might lead to conflicts if a crate depends on two traits that define a trait differently for the same type.

Let me know if you hear back from the BatSat devs, but as mentioned above, I guess we'll more likely end up with one of the different options.

@chrjabs chrjabs added enhancement New feature or request solvers Related to solver interfaces labels Apr 24, 2024
@chrjabs
Copy link
Owner

chrjabs commented Jun 11, 2024

It's been a while now. I think by now I'm settled on it being a pragmatic solution to go with the rustsat-<solver> crate indeed.
Are you still up for putting in the work to get this merged? Mainly, since this PR was opened, I introduced the solvertests crate to unify solver tests, this PR should be adapted to use that, and the workspace dependencies I introduced on the next-major branch.

@nfbruns
Copy link
Contributor Author

nfbruns commented Jun 14, 2024

Hi Christoph,
I am very sorry, i did not get notifications and the last weeks i have been on a trip around the world. But well I am happy with the pragmatic solution as well! I just fixed the merge conflicts from main. In terms of the authorship issue, i would write my name in the batsat toml but i am completely fine with publishing it under your name for the crates.io part.

And yes, I am up for putting in the work to get this merged! I will start to implement your new testing api and make it compatible for the next-major branch. Thanks a lot and i will rerequest review as soon as it is ready!

@nfbruns nfbruns requested a review from chrjabs June 21, 2024 16:57
@nfbruns
Copy link
Contributor Author

nfbruns commented Jun 21, 2024

I added the new Test interface -which is a lot simpler to use-!

In terms of the workshop dependencies, should I address this with this PR already or should this be merged to the current main and then upgraded to next-major in a separate PR?

@chrjabs
Copy link
Owner

chrjabs commented Jun 24, 2024

In terms of the workshop dependencies, should I address this with this PR already or should this be merged to the current main and then upgraded to next-major in a separate PR?

Even though I don't know yet when the next major release will happen, I think it would make sense to directly target next-major with this PR, rather than main and then have more work down the line. The other main change that I did on the next-major branch is to activate pedantic clippy linting, which will probably mean some adjustments in this code as well.
The downside is that releasing this interface will take a bit more time (only with the next major release of RustSAT). Are you fine with that?

@nfbruns nfbruns changed the base branch from main to next-major June 26, 2024 09:04
@nfbruns
Copy link
Contributor Author

nfbruns commented Jun 26, 2024

I am fine with that!
I updated the target to merge to next-major and fixed the workspace dependencies as well as the linting warnings. From my side, this should be ready to merge now!

Copy link
Owner

@chrjabs chrjabs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for continuing to work on this. There are some more things that I hadn't spelled out in detail before, most of them to do with the CI. In addition to the changes I marked here, please make the following changes in files that GitHub won't let me mark changes in:

  • In .github/workflows/docs.yml, change line 35 to
    for dir in tools cadical kissat minisat glucose batsat ipasir capi pyapi; do
    
  • In .github/workflows/semver-checks.yml add the following block at the bottom
          - name: BatSat
            uses: obi1kenobi/cargo-semver-checks-action@v2
            with:
              package: rustsat-batsat
    
  • In release-plz.toml add the following at the bottom so that the crate isn't immediately release when this hits main. I'll remove this when it should be released. (I unfortunately don't know a nicer way of dealing with this.)
    [[package]]
    name = "rustsat-batsat"
    release = false
    git_release_enable = false
    

@nfbruns
Copy link
Contributor Author

nfbruns commented Jul 1, 2024

Thank you for the comments and suggestions to get the CI to work! I tried to address all the CI changes and also the clippy warnings and hope that it will work now. If there is anything left to change or not documented well, please let me know!

@nfbruns nfbruns requested a review from chrjabs July 1, 2024 16:13
Copy link
Owner

@chrjabs chrjabs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One more small thing, I forgot to tell you to add "BatSat" in the list of ignored named in clippy.toml.

@chrjabs
Copy link
Owner

chrjabs commented Jul 2, 2024

Just so you know, the semver check failing is to be expected for the next-major branch. The failing doc test points out that the readme is not up-to-date with the crate documentation.

@nfbruns
Copy link
Contributor Author

nfbruns commented Jul 3, 2024

Just so you know, the semver check failing is to be expected for the next-major branch. The failing doc test points out that the readme is not up-to-date with the crate documentation.

Oh yes, i forgot to run cargo rdme after i added a comment! I pushed a now commit that shoud fix this issue.

@chrjabs
Copy link
Owner

chrjabs commented Jul 3, 2024

Great. If you address the requested changes above, I think we should be pretty much ready to merge.

@nfbruns
Copy link
Contributor Author

nfbruns commented Jul 4, 2024

I addressed the clippy and documentation issues. I hope that it is so far ready to ship now!

@chrjabs
Copy link
Owner

chrjabs commented Jul 5, 2024

Great. Thanks for sticking with this through all the details. I'll merge this soon, but I'll probably squash it down into fewer commits.

@nfbruns
Copy link
Contributor Author

nfbruns commented Jul 5, 2024

Thank you very much for taking the time to review and also for the interesting discussions along the way about how to approach the integration, how to deal with rust specifics and how to code certain parts!

chrjabs pushed a commit that referenced this pull request Jul 8, 2024
interface to the [BatSat](https://github.com/c-cube/batsat) solver

closes #84

Squashed commit of the following:

commit 25bea4d
Author: Noah Bruns <[email protected]>
Date:   Thu Jul 4 16:01:43 2024 +0200

    refactor: reorder clippy valid idents list

    Co-authored-by: Christoph Jabs <[email protected]>

commit adbe43e
Author: Noah Bruns <[email protected]>
Date:   Thu Jul 4 12:03:33 2024 +0200

    lint: Batsat added as valid ident

commit 80db5aa
Author: Noah Bruns <[email protected]>
Date:   Thu Jul 4 09:42:01 2024 +0200

    ci: run cargo rdme

commit 3a3bd46
Author: Noah Bruns <[email protected]>
Date:   Thu Jul 4 09:41:02 2024 +0200

    docu: remove code blocks for names

    Co-authored-by: Christoph Jabs <[email protected]>

commit e0a9cd2
Author: Noah Bruns <[email protected]>
Date:   Wed Jul 3 11:03:56 2024 +0200

    ci: run cargo rdme after comments changed

commit 0aeac45
Author: Noah Bruns <[email protected]>
Date:   Mon Jul 1 18:09:57 2024 +0200

    docu: more comments and restructuring

commit a549dda
Author: Noah Bruns <[email protected]>
Date:   Mon Jul 1 17:51:42 2024 +0200

    docu: cargo rdme run

commit a1e4498
Author: Noah Bruns <[email protected]>
Date:   Mon Jul 1 17:48:15 2024 +0200

    lint: clippy fixes and docu

commit fcfa9df
Author: Noah Bruns <[email protected]>
Date:   Mon Jul 1 17:32:42 2024 +0200

    PR: implemented suggestions and applied reviews

commit 1544980
Author: Noah Bruns <[email protected]>
Date:   Wed Jun 26 11:17:22 2024 +0200

    fix: clippy linting issues addressed

commit 727e42c
Author: Noah Bruns <[email protected]>
Date:   Fri Jun 21 19:19:21 2024 +0200

    fix: use workspace dependencies

commit 707e207
Merge: 4649148 1e6aa6b
Author: Noah Bruns <[email protected]>
Date:   Wed Jun 26 11:08:55 2024 +0200

    Merge branch 'feat-batsat-solver' of github.com:nfbruns/rustsat into feat-batsat-solver

commit 4649148
Author: Noah Bruns <[email protected]>
Date:   Wed Jun 26 11:08:40 2024 +0200

    compatability to 0.5.1 and solvertests implemented

commit ed21c4f
Author: Noah Bruns <[email protected]>
Date:   Wed Jun 26 11:08:40 2024 +0200

    test: cleanup and renaming

commit 8ecd6ad
Author: Noah Bruns <[email protected]>
Date:   Wed Jun 26 11:08:40 2024 +0200

    fix: return of ok if clause not added

commit a0e84a1
Author: Noah Bruns <[email protected]>
Date:   Wed Jun 26 11:08:40 2024 +0200

    docs: fixed comments

commit 4acddcd
Author: Noah Bruns <[email protected]>
Date:   Wed Jun 26 11:08:40 2024 +0200

    ci: running github workflows

commit 2ccc905
Author: Noah Bruns <[email protected]>
Date:   Wed Jun 26 11:08:40 2024 +0200

    docs: changelog and readme added

commit 9f59fdd
Author: Noah Bruns <[email protected]>
Date:   Wed Jun 26 11:08:40 2024 +0200

    feat:implemented batsat api

commit 1e6aa6b
Author: Noah Bruns <[email protected]>
Date:   Fri Jun 14 17:21:51 2024 +0200

    compatability to 0.5.1 and solvertests implemented

commit cf6dd71
Merge: 31d7e1c ff1a3d6
Author: Noah Bruns <[email protected]>
Date:   Fri Jun 14 16:48:35 2024 +0200

    Merge branch 'main' into feat-batsat-solver

commit 31d7e1c
Author: Noah Bruns <[email protected]>
Date:   Wed Apr 10 16:25:51 2024 +0200

    test: cleanup and renaming

commit 46b2c27
Author: Noah Bruns <[email protected]>
Date:   Wed Apr 10 17:10:03 2024 +0200

    fix: return of ok if clause not added

commit 4b58cc8
Author: Noah Bruns <[email protected]>
Date:   Wed Apr 10 17:08:58 2024 +0200

    docs: fixed comments

commit ae01e17
Author: Noah Bruns <[email protected]>
Date:   Wed Apr 10 15:56:36 2024 +0200

    ci: running github workflows

commit b8326be
Author: Noah Bruns <[email protected]>
Date:   Wed Apr 10 15:55:25 2024 +0200

    docs: changelog and readme added

commit 5b78bd2
Author: Noah Bruns <[email protected]>
Date:   Wed Apr 10 15:17:41 2024 +0200

    feat:implemented batsat api
@chrjabs
Copy link
Owner

chrjabs commented Jul 8, 2024

I now (manually) merged this in 4d15c0f. I also did a little bit more work (98af54b) to generalize the interface to generic BatSat callbacks and to implement SolveStats, which is required for a solver to implement the CollectClauses trait that RustSAT encodings rely on.
Thanks again for your work on this.

@chrjabs chrjabs closed this Jul 8, 2024
@chrjabs
Copy link
Owner

chrjabs commented Oct 16, 2024

For completeness, I now finally got to some housekeeping and this is now finally officially published. Thanks again for working on this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request solvers Related to solver interfaces
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants