This repository has been archived on 2023-08-20. You can view files and clone it, but cannot push or open issues or pull requests.
yap-6.3/CLPQR/clpqr/examples/squares.pl

108 lines
2.7 KiB
Perl
Raw Normal View History

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% clp(q,r) version 1.3.2 %
% %
% (c) Copyright 1992,1993,1994,1995 %
% Austrian Research Institute for Artificial Intelligence (OFAI) %
% Schottengasse 3 %
% A-1010 Vienna, Austria %
% %
% File: squares.pl %
% Author: Christian Holzbaur christian@ai.univie.ac.at %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
/*
This beautiful example of disequations at work is due
to [Colmerauer 90]. It addresses the task of tiling a rectangle
with squares of all-different, a priori unknown sizes. Here is a
translation of the original Prolog-III program to clp(q,r)
[Colmerauer 90]
Colmerauer A.: An Introduction to Prolog III,
Communications of the ACM, 33(7), 69-90, 1990.
| ?- length(L,9),filled_rectangle(A,L).
A = 33/32,
L = [15/32,9/16,1/4,7/32,1/8,7/16,1/32,5/16,9/32] ? ;
A = 69/61,
L = [33/61,36/61,28/61,5/61,2/61,9/61,25/61,7/61,16/61] ?
*/
rectangle( A, Rs) :-
Rs = [X1,X2,X3,X4,X5,X6,X7,X8,X9],
filled_rectangle( A, Rs).
filled_rectangle( A, C) :-
{ A >= 1 },
distinct_squares( C), % also acts as generator [], [_], [_,_], ...
filled_zone( [-1,A,1], _, C, []).
distinct_squares( []).
distinct_squares( [B|C]) :-
{ B > 0 },
outof( C, B),
distinct_squares( C).
outof( [], _).
outof( [B1|C], B) :-
{ B =\= B1 },
outof( C, B).
filled_zone( [V|L], [V|L], C0, C0) :-
{ V >= 0 }.
filled_zone( [V|L], L3, [B|C], C2) :-
{ V < 0 },
placed_square( B, L, L1),
filled_zone( L1, L2, C, C1),
{ Vb=V+B },
filled_zone( [Vb,B|L2], L3, C1, C2).
placed_square( B, [H,H0,H1|L], L1) :-
{ B > H, H0=0, H2=H+H1 },
placed_square( B, [H2|L], L1).
placed_square( B, [B,V|L], [X|L]) :-
{ X=V-B }.
placed_square( B, [H|L], [X,Y|L]) :-
{ B < H, X= -B, Y=H-B }.
%
% first nontrivial solution has 21 squares ...
%
perfect( S) :-
{ A = 1 },
distinct_squares( S),
length( S, Len), Len > 1,
print( try(Len)), nl,
flush_output,
time( filled_zone( [-1,A,1], _, S, [])).
/*
try(2)
%%% Timing 00:00:00.030 0.030
try(3)
%%% Timing 00:00:00.070 0.070
try(4)
%%% Timing 00:00:00.270 0.270
try(5)
%%% Timing 00:00:01.060 1.060
try(6)
%%% Timing 00:00:04.470 4.470
try(7)
%%% Timing 00:00:19.960 19.960
try(8)
%%% Timing 00:01:33.380 93.380
try(9)
%%% Timing 00:07:27.380 447.380
try(10)
%%% Timing 00:37:03.770 2223.770
try(11)
%%% Timing 03:11:38.380 11498.380
try(12)
%%% Timing 16:18:43.110 58723.110
*/