Using Prolog for Sudoku Variants
dstrohmaier.com
dstrohmaier.com
The key feature that makes Prolog so attractive for such tasks is the availability of constraint solvers that ship with many Prolog systems and which can be used to elegantly express these tasks in terms of relations between integers, Boolean variables, rational numbers and other domains. The sophistication and efficiency of constraint solvers depend heavily on the used Prolog system, and fast constraint solvers are often an important motivation for buying a commercial Prolog system such as SICStus Prolog.
Interestingly, constraint solvers can themselves be implemented elegantly and efficiently in Prolog too. See for example A Pearl on SAT Solving in Prolog by Howe and King, where the authors use Prolog and its delay declarations to implement a succinct SAT solver with watched literals and unit propagation:
There are plenty of examples of Sudoku models in MiniZinc, and models for many other combinatorial problems as well.
Compared to a Prolog program, a MiniZinc model is quite hard to parse and reason about programmatically: Every Prolog program is also a valid Prolog term, and can be reasoned about logically as long as we keep to the pure monotonic core of Prolog, which also includes constraints. Pure Prolog programs can be debugged declaratively by generalizing away goals, whereas for example removing a line of a MiniZinc model may render the model invalid.
In addition, Prolog provides logic variables and therefore allows interesting questions to be asked about the model, such as queries about partially known data. This, in combination with Prolog being a programming language, allows its application in a way that is not readily available, or may not be possible at all, with more special-purpose tools and modeling languages. For instance, David C. Norris is using Scryer Prolog and its integer constraints to model and analyse dose escalation trials as they arise in clinical oncology, exceeding the expressiveness of other modeling languages:
https://github.com/dcnorris/precautionary
Regarding sophistication, a good example are dedicated placement constraints of SICStus Prolog such as the geost/N family of constraints:
https://sicstus.sics.se/sicstus/docs/latest4/html/sicstus.ht...
The publication A Geometric Constraint over k-Dimensional Objects and Shapes Subject to Business Rules by Carlsson, Beldiceanu and Martin gives an overview of what is going on behind the scenes when these constraints are posted:
http://contraintes.inria.fr/~jmartin/CBM08cp.pdf
Implementing these constraints with the efficiency, generality and correctness that SICStus provides is a huge project.
Surely the same thing could be accomplished in Lisp as well?
That said, it's relatively easy to write a version of Prolog in Lisp and then just use that to solve the problem. Both pg and Peter Norvig show that in their Lisp books.
If you'd like to see how to do that yourself: https://github.com/norvig/paip-lisp
With that said, solvers such as OR-Tools (in their newer CP-SAT engine) and Chuffed are using something called Lazy Clause Generation, which can be very effective for many problems. This is partly a newer way to implements CP solvers that uses a built-in SAT solver as the domain store. I know of no Prolog system that uses this architecture.
$ gprolog
GNU Prolog 1.4.5 (64 bits)
Compiled Mar 24 2020, 20:46:07 with gcc
By Daniel Diaz
Copyright (C) 1999-2020 Daniel Diaz
| ?- X #> 3.
X = _#2(4..268435455)
yes
GNU Prolog 1.5.0 was recently released, and the source repository is now available at:https://github.com/didoudiaz/gprolog
GNU Prolog is a nice Prolog system for learning Prolog, also because it is currently the only free system that correctly handles all syntactic ISO conformity tests collected at:
https://www.complang.tuwien.ac.at/ulrich/iso-prolog/conformi...
This means that GNU Prolog can be reliably used to learn what is valid Prolog syntax and what is not.
If you want to get started, I recommend starting with CLP(FD) as that has a lot of tutorials and is highly compatible between Prolog implementations.
Yes you could implement OptaPlanner in Prolog but then you are no longer using the Prolog language facilities.
#const d=3.
#const n=d*d.
1 { s(X,Y,1..n) } 1 :- X=1..n, Y=1..n.
% Achieved: A value is chosen for each cell
X1=X2 :- s(X1,Y,N), s(X2,Y,N).
Y1=Y2 :- s(X,Y1,N), s(X,Y2,N).
% Achieved: No value is duplicated for any given row or column
r(X,Y,Z) :- X=1..n, Y=1..n, Z=((X-1)/d)*d+((Y-1)/d)+1.
(X1-X2)*(X1-X2)+(Y1-Y2)*(Y1-Y2)=0 :- s(X1,Y1,N), s(X2,Y2,N), r(X1,Y1,Z), r(X2,Y2,Z).
% Achieved: No value is duplicated within a d*d region
#show s/3.
The program above can be used to generate completed puzzles from scratch, or it can be combined with an input file containing an incomplete puzzle to generate any or all valid solutions. Due to the semantics of ASP, additional constraints can be appended to the program to support Sudoku variants without modifying the existing lines.Examples include Google OR-tools, Microsoft Z3, etc.
Just note that encoding terms of various shapes in SAT is very difficult. Encoding terms of unknown size doubly so.
Encoding problems in Prolog is very easy in that sense, as you can build arbitrarily shaped terms very easily and you can constrain variables within terms and not only on the top level.
The sudoku example, with the fixed shape and all variables at the top level is a prime example for SAT solving though.
In fact we were taught a number of logic programing languages and had a set of games, including Sudoku which we had to create solvers for in each of the languages.