prolog - reificar - reificación estética
Usa restricciones reificadas para hacer 3 números consecutivos (2)
Esto implementa consecutivo en el sentido que dio en los comentarios. Para obtener una lista de N
valores, necesitamos espacio suficiente para que todos los valores quepan entre ellos, y todos los valores deben ser diferentes.
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).
Aquí hay un resumen de mi programa SWI-Prolog:
:- 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
hace L5
y L4
uno al lado del otro. Si quisiera hacer tres números uno al lado del otro, por ejemplo, L3
, L4
y L5
, ¿cómo podría usar restricciones reificadas para hacer esto?
Ej. L3=4
, L5=5
, L4=6
o L4=7
, L5=8
, L3=9
TL; DR: demasiado tiempo para un comentario: tiempo de reproducción con restricciones sicstus-prolog clpfd especializadas
Esta respuesta sigue esta respuesta previa ; las versiones recientes de SICStus Prolog ofrecen restricciones especializadas clpfd maximum/2
y minimum/2
como alternativas a min_of/2
y max_of/2
.
Usando el siguiente código para benchmarking 1,2 ...
:- use_module(library(clpfd)). :- use_module(library(between)). bench_(How, N, Ub) :- /+ /+ ( length(Xs, N), domain(Xs, 1, Ub), all_different(Xs), Max-Min #= N-1, ( How = 0 ; How = min_of , max_of( Max, Xs), min_of( Min, Xs) ; How = minimum, maximum(Max, Xs), minimum(Min, Xs) ), labeling([enum], Xs) ).
... ejecutamos las siguientes pruebas:
Para estimar la sobrecarga del peor de los casos de restricción mínima / máxima:
?- member(How, [0,v1,v2]), call_time(bench_(How,10,10), T_ms). How = 0 , T_ms = 5910 ; How = v1, T_ms = 19560 ; How = v2, T_ms = 7190.
Para medir los costos de tiempo de ejecución de la propagación de restricciones mínimas / máximas en casos más típicos:
?- between(6, 8, N), NN #= N+N, call_time(bench_(v1,N,NN),T_ms). N = 6, NN = 12, T_ms = 50 ; N = 7, NN = 14, T_ms = 300 ; N = 8, NN = 16, T_ms = 2790. ?- between(6, 8, N), NN #= N+N, call_time(bench_(v2,N,NN),T_ms). N = 6, NN = 12, T_ms = 20 ; N = 7, NN = 14, T_ms = 100 ; N = 8, NN = 16, T_ms = 830.
En ambos "casos de uso", las restricciones especializadas dan una aceleración impresionante.
Nota al pie 1: Usar SICStus Prolog versión 4.3.2 (64 bits).
Nota al pie 2: las secuencias de respuestas se procesaron posteriormente para mejorar la apariencia.