This is a little demo app to show a Phoenix LiveView web frontend communicating with a clingo backend. Currently there are just a couple of Sudoku composer/solver pages – the user sets the puzzle and clingo solves it.
The elixir-clingo bridge is via python via erlport, but see Next Steps.
read-my-gif shows the app in action.
As well as the dependencies that mix setup
will pull in, this project requires clingo, python 3.6+, and clyngor. I haven’t tried clyngor-with-clingo, but that might simplify things a little.
One caveat: for maybe_valid_grid
, clyngor needs to access clingo directly, not via clingo’s own python API. If clingo’s python module is squatting in the way, maybe_valid_grid
will fail. The python tests (see below) will catch this.
$ python3 -m venv _venv $ . _venv/bin/activate $ pip install -r requirements.txt $ mix setup
Or, using docker:
$ docker build --pull -t phxcp .
$ python -m unittest apps/composer_cli/priv/python/test.py $ mix test
The test grids are also available in the asp/
directory for direct testing of the clingo rule file, e.g.:
$ cd apps/composer_cli/priv/asp/ $ clingo -n 100 sudoku9.lp test_gridbad.lp clingo version 5.4.0 Reading from sudoku9.lp ... Solving... UNSATISFIABLE Models : 0 Calls : 1 Time : 0.011s (Solving: 0.00s 1st Model: 0.00s Unsat: 0.00s) CPU Time : 0.011s $ clingo -n 100 sudoku9.lp test_gridok1.lp ... SATISFIABLE Models : 100+ # There are at least 100 possible solutions. Calls : 1 Time : 0.025s (Solving: 0.01s 1st Model: 0.00s Unsat: 0.00s) CPU Time : 0.024s $ clingo -n 100 sudoku9.lp test_gridok2.lp clingo version 5.4.0 Reading from sudoku9.lp ... Solving... Answer: 1 cellHasDigit(1,4,7) cellHasDigit(1,8,1) cellHasDigit(1,9,6) cellHasDigit(2,2,9) cellHasDigit(2,3,5) cellHasDigit(2,4,3) cellHasDigit(2,7,7) cellHasDigit(2,8,8) cellHasDigit(3,7,3) cellHasDigit(4,1,5) cellHasDigit(4,3,2) cellHasDigit(4,5,3) cellHasDigit(5,4,5) cellHasDigit(5,5,7) cellHasDigit(6,1,1) cellHasDigit(6,3,6) cellHasDigit(6,5,9) cellHasDigit(7,7,5) cellHasDigit(8,2,3) cellHasDigit(8,3,7) cellHasDigit(8,4,2) cellHasDigit(8,7,8) cellHasDigit(8,8,6) cellHasDigit(9,4,4) cellHasDigit(9,8,3) cellHasDigit(9,9,1) cellHasDigit(1,1,3) cellHasDigit(2,1,6) cellHasDigit(3,1,7) cellHasDigit(5,1,9) cellHasDigit(7,1,2) cellHasDigit(8,1,4) cellHasDigit(9,1,8) cellHasDigit(1,2,2) cellHasDigit(3,2,1) cellHasDigit(4,2,8) cellHasDigit(5,2,4) cellHasDigit(6,2,7) cellHasDigit(7,2,6) cellHasDigit(9,2,5) cellHasDigit(1,3,4) cellHasDigit(3,3,8) cellHasDigit(5,3,3) cellHasDigit(7,3,1) cellHasDigit(9,3,9) cellHasDigit(3,4,6) cellHasDigit(4,4,1) cellHasDigit(6,4,8) cellHasDigit(7,4,9) cellHasDigit(1,5,5) cellHasDigit(2,5,4) cellHasDigit(3,5,2) cellHasDigit(7,5,8) cellHasDigit(8,5,1) cellHasDigit(9,5,6) cellHasDigit(1,6,8) cellHasDigit(2,6,1) cellHasDigit(3,6,9) cellHasDigit(4,6,4) cellHasDigit(5,6,6) cellHasDigit(6,6,2) cellHasDigit(7,6,3) cellHasDigit(8,6,5) cellHasDigit(9,6,7) cellHasDigit(1,7,9) cellHasDigit(4,7,6) cellHasDigit(5,7,1) cellHasDigit(6,7,4) cellHasDigit(9,7,2) cellHasDigit(3,8,4) cellHasDigit(4,8,9) cellHasDigit(5,8,2) cellHasDigit(6,8,5) cellHasDigit(7,8,7) cellHasDigit(2,9,2) cellHasDigit(3,9,5) cellHasDigit(4,9,7) cellHasDigit(5,9,8) cellHasDigit(6,9,3) cellHasDigit(7,9,4) cellHasDigit(8,9,9) SATISFIABLE Models : 1 # There is exactly one possible solution. Calls : 1 Time : 0.019s (Solving: 0.00s 1st Model: 0.00s Unsat: 0.00s) CPU Time : 0.019s
$ mix phx.server
Or, using docker:
$ docker run -p 127.0.0.1:4000:4000 phxcp
Navigating to: http://localhost:4000
- Include a Rust NIF bridge to clingo (using clingo-rs)
- Configurable agent properties for the solver (eg provided sets of solving techniques)
- Richer feedback for the composer
- More puzzles
- Demo applications for other clingo-related libraries
- Visualisation and UI for other ASP applications (scheduling, traffic control, music generation, protein design, etc.)