=============================================
Substitutive structure of Jeandel-Rao tilings
=============================================

`arXiv:1808.07768`__, November 2019 (version 4), 48 p.

__ https://arxiv.org/abs/1808.07768

Running ``sage -t`` on this file takes 70 seconds with sage-9.0.beta6 and
slabbe-0.6.

Preparation
-----------

The optional Sage package ``slabbe`` can be installed by running the command::

    sage -pip install slabbe

Most of the computations use the dancing links solver available in Sage.
Few computations use Gurobi linear program solver, the SAT solver glucose
or the SAT solver cryptominisat. The latter two can be installed easily as they
are optional Sage packages.::

    sage -i glucose
    sage -i cryptominisat

SageMath code in the article
----------------------------

First we import the necessary libraries from slabbe::

    sage: from slabbe import WangTileSet

Part 1
======

We define the Jeandel-Rao set of Wang tiles $\T_0$

.. link

::

    sage: tiles = [(2,4,2,1), (2,2,2,0), (1,1,3,1), (1,2,3,2), (3,1,3,3), (0,1,3,1), 
    ....:          (0,0,0,1), (3,1,0,2), (0,2,1,2), (1,2,1,4), (3,3,1,2)]
    sage: tiles = [[str(a) for a in t] for t in tiles]
    sage: T0 = WangTileSet(tiles)

We use Knuth's dancing links algorithm because it is faster at this task than
MILP or SAT solvers.

We desubstitute $\T_0$:

.. link

::

    sage: T0.find_markers(i=2, radius=1, solver='dancing_links')
    [[0, 1]]
    sage: M0 = [0,1]
    sage: T1,omega0 = T0.find_substitution(M=M0, i=2, side='left', radius=1, solver='dancing_links')
    sage: T1
    Wang tile set of cardinality 13
    sage: omega0
    Substitution 2d: {0: [[2]], 1: [[3]], 2: [[4]], 3: [[5]], 4: [[6]], 5: [[7]], 6: [[8]], 7: [[10]], 8: [[0, 9]], 9: [[1, 3]], 10: [[1, 7]], 11: [[1, 8]], 12: [[1, 10]]}

We desubstitute $\T_1$:

.. link

::

    sage: T1.find_markers(i=2, radius=1, solver='dancing_links')
    [[8, 9, 10, 11, 12]]
    sage: M1 = [8, 9, 10, 11, 12]
    sage: T2,omega1 = T1.find_substitution(M=M1, i=2, side='left', radius=1, solver='dancing_links')
    sage: T2
    Wang tile set of cardinality 20
    sage: omega1
    Substitution 2d: {0: [[0]], 1: [[1]], 2: [[2]], 3: [[3]], 4: [[4]], 5: [[5]], 6: [[6]], 7: [[7]], 8: [[8, 1]], 9: [[8, 5]], 10: [[8, 6]], 11: [[8, 7]], 12: [[9, 1]], 13: [[9, 5]], 14: [[9, 6]], 15: [[10, 0]], 16: [[10, 3]], 17: [[11, 5]], 18: [[11, 7]], 19: [[12, 2]]}

We desubstitute $\T_2$:

.. link

::

    sage: T2.find_markers(i=2, radius=2, solver='dancing_links')             # takes 4s
    [[8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]]
    sage: M2 = [8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
    sage: T3,omega2 = T2.find_substitution(M=M2, i=2, side='left', radius=2, solver='dancing_links')
    sage: T3
    Wang tile set of cardinality 24
    sage: omega2
    Substitution 2d: {0: [[2]], 1: [[3]], 2: [[4]], 3: [[5]], 4: [[8, 1]], 5: [[8, 5]], 6: [[8, 6]], 7: [[9, 0]], 8: [[9, 3]], 9: [[10, 5]], 10: [[10, 7]], 11: [[11, 2]], 12: [[12, 5]], 13: [[12, 6]], 14: [[13, 4]], 15: [[14, 5]], 16: [[15, 3]], 17: [[16, 3]], 18: [[16, 4]], 19: [[17, 3]], 20: [[18, 2]], 21: [[19, 0]], 22: [[19, 3]], 23: [[19, 4]]}

We desubstitute $\T_3$:

.. link

::

    sage: T3.find_markers(i=2, radius=3, solver='dancing_links')              # takes 14s
    [[0, 1, 2, 3]]
    sage: M3 = [0, 1, 2, 3]
    sage: T4p,omega3p = T3.find_substitution(M=M3, i=2, side='right', radius=3, solver='dancing_links')
    sage: T4p
    Wang tile set of cardinality 30
    sage: omega3p
    Substitution 2d: {0: [[5]], 1: [[8]], 2: [[11]], 3: [[12]], 4: [[14]], 5: [[15]], 6: [[16]], 7: [[17]], 8: [[18]], 9: [[19]], 10: [[20]], 11: [[22]], 12: [[23]], 13: [[4, 3]], 14: [[5, 2]], 15: [[6, 3]], 16: [[7, 1]], 17: [[7, 2]], 18: [[8, 1]], 19: [[8, 2]], 20: [[9, 1]], 21: [[10, 0]], 22: [[11, 2]], 23: [[12, 2]], 24: [[13, 3]], 25: [[15, 2]], 26: [[16, 2]], 27: [[20, 2]], 28: [[21, 2]], 29: [[22, 2]]}

Below is the code to construct the problem. We construct the solver searching
for a tiling of the rectangle of size $71\times 9$ tiled with the tiles from
$\T_4'$ with the tile $(21103, 1, 23310, 0)$ in the center of that rectangle,
that is, at position $(35,4)$:

.. link

::

    sage: T4p[24]
    ('21103', '1', '23310', '0')
    sage: S = T4p.solver(width=71, height=9, preassigned_tiles={(35,4):24})

Using a reduction of that problem to SAT using 19170 variables and 1078659
clauses, the Glucose SAT solver says there is no solution in less than 4
seconds:

.. link

::

    sage: S.sat_solver('cryptominisat')            # optional cryptominisat pycryptosat # takes 3s
    CryptoMiniSat solver: 19170 variables, 1078659 clauses.
    sage: S.has_solution(solver='glucose')         # optional glucose # takes 4 s
    False

Using a reduction of the same problem to a MILP instance,
using 19170 variables and 1838 constraints,
the linear program is shown to have no solution using
\texttt{Gurobi} solver \cite{gurobi} 
in about 45 seconds on a normal 2018 desktop computer with 8 available
cpus:

.. link

::

    sage: S.has_solution(solver='Gurobi')         # not tested (takes 45s)
    False
    sage: p,x = S.milp()
    sage: p
    Boolean Program (maximization, 19170 variables, 1838 constraints)
    sage: x
    MIPVariable ...


