Search code examples
prologconstraintsclpfd

Use reified constraints to make 3 numbers consecutive


Here's an outline of my SWI-Prolog program:

:- use_module(library(clpfd)).

consec1(L) :-
   L=[L1,L2,L3,L4,L5,L6,L7,L8,L9],
   L ins 1..9,
   ...,
   abs(L5-L4)#=1,
   all_different(L),
   labeling([],L)

abs(L5-L4)#=1 makes L5 and L4 next to each other. If I wanted to make three numbers next to each other e.g. L3, L4 and L5, how could I use reified constraints to do this?

E.g. L3=4,L5=5,L4=6 or L4=7,L5=8,L3=9


Solution

  • This implements consecutive in the sense you gave in the comments. For a list of N values, we need space enough to make all the values fit in between, and all values need to be different.

    consecutive([]).  % debatable case
    consecutive(Xs) :-
       Xs = [_|_],
       length(Xs, N),
       all_different(Xs),
       max_of(Max, Xs),
       min_of(Min, Xs),
       Max-Min #= N-1.
    
    max_of(Max, [Max]).
    max_of(Max0, [E|Es]) :-
       Max0 #= max(E,Max1),
       max_of(Max1, Es).
    
    min_of(Min, [Min]).
    min_of(Min0, [E|Es]) :-
       Min0 #= min(E, Min1),
       min_of(Min1, Es).