Possible bug in ic

From: Karen E Petrie <scomkep_at_zeus.hud.ac.uk>
Date: Wed 09 Oct 2002 04:49:02 PM GMT
Message-Id: <200210091649.RAA24322@dvorak.hud.ac.uk>
The ECLiPSe banner with the version number and configuration
(unless visible in the script):

ECLiPSe Constraint Logic Programming System [kernel]
Copyright Imperial College London and ICL
Certain libraries copyright Parc Technologies Ltd
GMP library copyright Free Software Foundation
Version 5.4 #41, Tue Jul 16 00:14 2002

Machine type:
Sun blade 100

Operating system name and version number:
Solaris 8, CDE 1.4

A script which causes the bug to appear, enhanced by comments where
necessary (start from the ECLiPSe banner unless the option -e is used):

I working on a problem called graceful graphs. A labelling f of the 
vertices of a graph with e edges is graceful if f assigns each vertex a 
unique label from {0,1,..e} and when each edge xy is labelled with 
|f(x) - f(y)|, the edge labels are all different. (Hence, the edge labels 
are a permutation of 1,2,..e).

The most obvious model, for this is to label the nodes, but another option 
should be to label the edges. The constraints should be the same in both 
cases. 

The ecplise code is: (I have also added this as an attachment for 
easiness)

:- lib(ic).
:- lib(ic_global).
:- lib(lists).

main_node_ff:-
	model(Node, Edge),
	constrain(Node, Edge),
	flatten_matrix(Node, NodeList),
	search(NodeList, 0, first_fail, indomain,complete,[backtrack(B)]),
	writeln("Node: "),
	writeln(Node),	
	writeln("Edge: "),
	writeln(Edge),
	writeln("Backtracks: "),
	writeln(B).
	
main_edge_ff:-
	model(Node, Edge),
	constrain(Node, Edge),
	flatten_matrix(Edge, EdgeList),
	search(EdgeList, 0, first_fail, indomain,complete,[backtrack(B)]),
	writeln("Edge: "),
	writeln(Edge),
	writeln("Node: "),
	writeln(Node),
	writeln("Backtracks: "),
	writeln(B).


model(Node, Edge):-
	dim(Node, [8]),
	Node[1..8] :: 0..16,
	dim(Edge, [16]),
	Edge[1..16] :: 1..16.
	
constrain(Node, Edge):-
	Edge[1] #= abs(Node[1]-Node[2]),
	Edge[2] #= abs(Node[2]-Node[4]),
	Edge[3] #= abs(Node[3]-Node[4]),
	Edge[4] #= abs(Node[1]-Node[3]),
	Edge[5] #= abs(Node[1]-Node[5]),
	Edge[6] #= abs(Node[2]-Node[6]),
	Edge[7] #= abs(Node[3]-Node[7]),
	Edge[8] #= abs(Node[4]-Node[8]),
	Edge[9] #= abs(Node[5]-Node[6]),
	Edge[10] #= abs(Node[6]-Node[8]),
	Edge[11] #= abs(Node[7]-Node[8]),
	Edge[12] #= abs(Node[5]-Node[7]),
	Edge[13] #= abs(Node[5]-Node[8]),
	Edge[14] #= abs(Node[6]-Node[7]),
	Edge[15] #= abs(Node[1]-Node[4]),
	Edge[16] #= abs(Node[2]-Node[3]),
	flatten_matrix(Edge, EdgeList),
	flatten_matrix(Node, NodeList),
	ic_global:alldifferent(EdgeList),
	ic_global:alldifferent(NodeList).
	
% Flatten a matrix into a list of its elements.
flatten_matrix(M, List) :-
	flatten_matrix(M, List, []).

flatten_matrix(M, List, Tail) :-
	compound(M),
	!,
	M =.. [_ | Elems],
	(
	    foreach(Elem, Elems),
	    fromto(List, List1, Tail1, Tail)
	do
	    flatten_matrix(Elem, List1, Tail1)
	).
flatten_matrix(X, [X | Tail], Tail).

The script for this follows:

dvorak{scomkep}4: eclipse
ECLiPSe Constraint Logic Programming System [kernel]
Copyright Imperial College London and ICL
Certain libraries copyright Parc Technologies Ltd
GMP library copyright Free Software Foundation
Version 5.4 #41, Tue Jul 16 00:14 2002
[eclipse 1]: [basictest].
ic_kernel.eco loaded traceable 0 bytes in 0.08 seconds
linearize.eco loaded traceable 0 bytes in 0.05 seconds
ic_constraints.eco loaded traceable 0 bytes in 0.21 seconds
ic.eco     loaded traceable 0 bytes in 0.03 seconds
ic_search.eco loaded traceable 0 bytes in 0.10 seconds
ic.eco     loaded traceable 0 bytes in 0.43 seconds
hash.eco   loaded traceable 0 bytes in 0.03 seconds
ordset.pl  compiled traceable 4764 bytes in 0.02 seconds
ic_global.eco loaded traceable 0 bytes in 0.14 seconds
lists.pl   compiled traceable 5188 bytes in 0.03 seconds
basictest.ecl compiled traceable 13000 bytes in 0.63 seconds

Yes (0.64s cpu)
% command to run search on nodes, works as expected
[eclipse 2]: main_node_ff.
Node: 
[](0, 1, 5, 16, 6, 15, 13, 3)
Edge: 
[](1, 15, 11, 5, 6, 14, 8, 13, 9, 12, 10, 7, 3, 2, 16, 4)
Backtracks: 
13

More (0.97s cpu) ? 
%command to run test on edges, gives a wrong answer and delayed goals 
%not as expected
[eclipse 3]: main_edge_ff.
Edge: 
[](1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)
Node: 
[](_289{0 .. 16}, _304{0 .. 16}, _319{0 .. 16}, _334{0 .. 16}, _349{0 .. 
16}, _364{0 .. 16}, _379{0 .. 16}, _394{0 .. 16})
Backtracks: 
0


There are 209 delayed goals. Do you want to see them? (y/n) 

Delayed goals:
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        finalise_on_ground(0 .. 16)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        finalise_on_ground(0 .. 16)
        ic : (_1408{-1 .. 1} + _304{0 .. 16} - _289{0 .. 16} =:= 0)
        ic : (1 =:= abs(_1408{-1 .. 1}))
        ic : (_1408{-1 .. 1} =:= +- 1)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        finalise_on_ground(0 .. 16)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        finalise_on_ground(0 .. 16)
        ic : (_2012{-2 .. 2} + _334{0 .. 16} - _304{0 .. 16} =:= 0)
        ic : (2 =:= abs(_2012{-2 .. 2}))
        ic : (_2012{-2 .. 2} =:= +- 2)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        finalise_on_ground(0 .. 16)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        finalise_on_ground(0 .. 16)
        ic : (_2616{-3 .. 3} + _334{0 .. 16} - _319{0 .. 16} =:= 0)
        ic : (3 =:= abs(_2616{-3 .. 3}))
        ic : (_2616{-3 .. 3} =:= +- 3)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        finalise_on_ground(0 .. 16)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        finalise_on_ground(0 .. 16)
        ic : (_3213{-4 .. 4} + _319{0 .. 16} - _289{0 .. 16} =:= 0)
        ic : (4 =:= abs(_3213{-4 .. 4}))
        ic : (_3213{-4 .. 4} =:= +- 4)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        finalise_on_ground(0 .. 16)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        finalise_on_ground(0 .. 16)
        ic : (_3817{-5 .. 5} + _349{0 .. 16} - _289{0 .. 16} =:= 0)
        ic : (5 =:= abs(_3817{-5 .. 5}))
        ic : (_3817{-5 .. 5} =:= +- 5)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        finalise_on_ground(0 .. 16)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        finalise_on_ground(0 .. 16)
        ic : (_4421{-6 .. 6} + _364{0 .. 16} - _304{0 .. 16} =:= 0)
        ic : (6 =:= abs(_4421{-6 .. 6}))
        ic : (_4421{-6 .. 6} =:= +- 6)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        finalise_on_ground(0 .. 16)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        finalise_on_ground(0 .. 16)
        ic : (_5025{-7 .. 7} + _379{0 .. 16} - _319{0 .. 16} =:= 0)
        ic : (7 =:= abs(_5025{-7 .. 7}))
        ic : (_5025{-7 .. 7} =:= +- 7)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        finalise_on_ground(0 .. 16)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        finalise_on_ground(0 .. 16)
        ic : (_5629{-8 .. 8} + _394{0 .. 16} - _334{0 .. 16} =:= 0)
        ic : (8 =:= abs(_5629{-8 .. 8}))
        ic : (_5629{-8 .. 8} =:= +- 8)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        finalise_on_ground(0 .. 16)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        finalise_on_ground(0 .. 16)
        ic : (_6226{-9 .. 9} + _364{0 .. 16} - _349{0 .. 16} =:= 0)
        ic : (9 =:= abs(_6226{-9 .. 9}))
        ic : (_6226{-9 .. 9} =:= +- 9)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        finalise_on_ground(0 .. 16)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        finalise_on_ground(0 .. 16)
        ic : (_6823{-10 .. 10} + _394{0 .. 16} - _364{0 .. 16} =:= 0)
        ic : (10 =:= abs(_6823{-10 .. 10}))
        ic : (_6823{-10 .. 10} =:= +- 10)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        finalise_on_ground(0 .. 16)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        finalise_on_ground(0 .. 16)
        ic : (_7420{-11 .. 11} + _394{0 .. 16} - _379{0 .. 16} =:= 0)
        ic : (11 =:= abs(_7420{-11 .. 11}))
        ic : (_7420{-11 .. 11} =:= +- 11)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        finalise_on_ground(0 .. 16)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        finalise_on_ground(0 .. 16)
        ic : (_8017{-12 .. 12} + _379{0 .. 16} - _349{0 .. 16} =:= 0)
        ic : (12 =:= abs(_8017{-12 .. 12}))
        ic : (_8017{-12 .. 12} =:= +- 12)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        finalise_on_ground(0 .. 16)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        finalise_on_ground(0 .. 16)
        ic : (_8614{-13 .. 13} + _394{0 .. 16} - _349{0 .. 16} =:= 0)
        ic : (13 =:= abs(_8614{-13 .. 13}))
        ic : (_8614{-13 .. 13} =:= +- 13)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        finalise_on_ground(0 .. 16)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        finalise_on_ground(0 .. 16)
        ic : (_9211{-14 .. 14} + _379{0 .. 16} - _364{0 .. 16} =:= 0)
        ic : (14 =:= abs(_9211{-14 .. 14}))
        ic : (_9211{-14 .. 14} =:= +- 14)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        finalise_on_ground(0 .. 16)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        finalise_on_ground(0 .. 16)
        ic : (_9808{-15 .. 15} + _334{0 .. 16} - _289{0 .. 16} =:= 0)
        ic : (15 =:= abs(_9808{-15 .. 15}))
        ic : (_9808{-15 .. 15} =:= +- 15)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        finalise_on_ground(0 .. 16)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_bounds(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        sync_ic_holes(0 .. 16, 0 .. 16)
        finalise_on_ground(0 .. 16)
        ic : (_10405{-16 .. 16} + _319{0 .. 16} - _304{0 .. 16} =:= 0)
        ic : (16 =:= abs(_10405{-16 .. 16}))
        ic : (_10405{-16 .. 16} =:= +- 16)
        alldifferent([_289{0 .. 16}, _304{0 .. 16}, _319{0 .. 16}, _334{0 
.. 16}, _349{0 .. 16}, _364{0 .. 16}, _379{0 .. 16}, _394{0 .. 16}], 1)
More (0.04s cpu) ? 


It may be that this is not a bug, and is infact expected behaviour, in 
which case I would be gratified if someone can explain to me why this is 
so.

:- lib(ic).
:- lib(ic_global).
:- lib(lists).

main_node_ff:-
	model(Node, Edge),
	constrain(Node, Edge),
	flatten_matrix(Node, NodeList),
	search(NodeList, 0, first_fail, indomain, complete,[backtrack(B)]),
	writeln("Node: "),
	writeln(Node),	
	writeln("Edge: "),
	writeln(Edge),
	writeln("Backtracks: "),
	writeln(B).
	
main_edge_ff:-
	model(Node, Edge),
	constrain(Node, Edge),
	flatten_matrix(Edge, EdgeList),
	search(EdgeList, 0, first_fail, indomain, complete,[backtrack(B)]),
	writeln("Edge: "),
	writeln(Edge),
	writeln("Node: "),
	writeln(Node),
	writeln("Backtracks: "),
	writeln(B).


model(Node, Edge):-
	dim(Node, [8]),
	Node[1..8] :: 0..16,
	dim(Edge, [16]),
	Edge[1..16] :: 1..16.
	
constrain(Node, Edge):-
	Edge[1] #= abs(Node[1]-Node[2]),
	Edge[2] #= abs(Node[2]-Node[4]),
	Edge[3] #= abs(Node[3]-Node[4]),
	Edge[4] #= abs(Node[1]-Node[3]),
	Edge[5] #= abs(Node[1]-Node[5]),
	Edge[6] #= abs(Node[2]-Node[6]),
	Edge[7] #= abs(Node[3]-Node[7]),
	Edge[8] #= abs(Node[4]-Node[8]),
	Edge[9] #= abs(Node[5]-Node[6]),
	Edge[10] #= abs(Node[6]-Node[8]),
	Edge[11] #= abs(Node[7]-Node[8]),
	Edge[12] #= abs(Node[5]-Node[7]),
	Edge[13] #= abs(Node[5]-Node[8]),
	Edge[14] #= abs(Node[6]-Node[7]),
	Edge[15] #= abs(Node[1]-Node[4]),
	Edge[16] #= abs(Node[2]-Node[3]),
	flatten_matrix(Edge, EdgeList),
	flatten_matrix(Node, NodeList),
	ic_global:alldifferent(EdgeList),
	ic_global:alldifferent(NodeList).
	
% Flatten a matrix into a list of its elements.
flatten_matrix(M, List) :-
	flatten_matrix(M, List, []).

flatten_matrix(M, List, Tail) :-
	compound(M),
	!,
	M =.. [_ | Elems],
	(
	    foreach(Elem, Elems),
	    fromto(List, List1, Tail1, Tail)
	do
	    flatten_matrix(Elem, List1, Tail1)
	).
flatten_matrix(X, [X | Tail], Tail).
Received on Wed Oct 09 17:54:28 2002

This archive was generated by hypermail 2.1.8 : Wed 16 Nov 2005 06:08:18 PM GMT GMT