The Thermometers puzzle can be described as follows: we have a grid of
This assignment was developed as part of the course Reasoning and Planning (P4251103) at Universidade de Santiago de Compostela.
- Yago Estévez Figueiras
- Andrea Real Blanco
- Clingo: To run the
.lpprograms and solve the puzzles, you will need to have the Clingo ASP solver installed. - Python 3.x: This is required to execute all the utility scripts (for encoding, decoding, and, optionally, drawing the solution).
- (Optional visualizations) Install the Python package
pygameto visualize the solutions.pip install pygame
The initial thermometer configuration must be provided as an input file, either
in ASCII format (.txt) or in ASP fact format (.lp).
The ASCII file must contain a square grid of
- Thermometer bulbs are oriented using
U(up),D(down),R(right), andL(left). - Vertical body segments can point
^(up) orv(down). - Horizontal body segments can point
>(right) or<(left). - Turn segments are represented by digits
0(└),1(┏),2(┐), and3(┘).
Once the grid is complete, the final two lines contain the clue numbers: The first line lists the vertical (column) counts, and the second line lists the horizontal (row) counts separated by blank spaces.
For instance, this would be the ASCII representation for the puzzle above:
<LD^
^DvU
UvDD
<Lvv
1 2 1 3
2 1 3 1
The input puzzle domain can also be provided directly using ASP facts, where
rows and columns are indexed from
The encoding uses these predicates:
- Dimensions:
dim(n)defines the size of the grid. The row and column ranges are defined asr(0..n-1)andc(0..n-1). - Clues:
row_clue(row, count)andcol_clue(column, count)define the number of filled cells per row and column. - Layout:
bulb_at(row, column, orientation),body_at(row, column, orientation), andturn_at(row, column, type)define the thermometer structure.
For the
dim(4).
r(0..3). c(0..3).
% --- CLUES
row_clue(0,2). row_clue(1,1). row_clue(2,3). row_clue(3,1).
col_clue(0,1). col_clue(1,2). col_clue(2,1). col_clue(3,3).
% --- THERMOMETERS LAYOUT
body_at(0,0,left).
bulb_at(0,1,left).
bulb_at(0,2,down).
body_at(0,3,up).
body_at(1,0,up).
bulb_at(1,1,down).
body_at(1,2,down).
bulb_at(1,3,up).
bulb_at(2,0,up).
body_at(2,1,down).
bulb_at(2,2,down).
bulb_at(2,3,down).
body_at(3,0,left).
bulb_at(3,1,left).
body_at(3,2,down).
body_at(3,3,down).Note: An alternative implementation where the orientation logic is encoded
directly into the representation (instead of handled by the constraints) is
provided through its encoder utils/encode_alt.py and its solver
thermo_alt.py.
The main functionalities are the encoding of the input, finding the puzzle's solution, and the visualization of the solution.
- Encoding the ASCII input. First, convert the ASCII map
(
.txt) into the logical facts (.lp) that Clingo can read.python3 utils/encode.py domain_example.txt domain_example.lp
- Solving the puzzle (Clingo). Now that we have the puzzle in its
.lpformat, we can run Clingo. To do so, we combine the puzzle facts with the problem's core rules and constraints (thermo.lp).clingo 0 thermo.lp domain_example.lp
- Visualize the solution. To see the result as an image, we first need to
translate Clingo's output into an ASCII grid of filled/empty cells (
x/.) and then usepygameto draw the result.- Generate the ASCII solution output. This script outputs the solution
state to a text file (
-sol.txt).# This generates a file named domain_example-sol.txt python3 utils/decode-save-file.py thermo.lp domain_example.lp - Generate the solution picture. This script uses
pygameto draw the calculated solution and saves the result as a PNG image.# This generates a file named domain_example-pic.png python3 utils/drawthermo.py domain_example.txt domain_example-sol.txt
- Generate the ASCII solution output. This script outputs the solution
state to a text file (
