Labeling with time_out difference between Sicstus 4.2.3 and 4.3.0 - clpfd

In Sicstus 4.2.3 it is possible to do like this:
| ?- X in 0..2, labeling( [minimize(X), time_out(1000, Lr)],[X] ).
X = 0,
Lr = success ? yes
| ?-
If you do the same in Sicstus 4.3.0 you get:
| ?- X in 0..2, labeling( [minimize(X), time_out(1000, Lr)],[X] ).
X = 0 ? yes
| ?-
What happened to Lr in 4.3.0?
And how do you know if the solution you get in 4.3.0 is the optimal solution or if the solution is a non-optimal solution?

It's a bug of course. Lr should be bound to 'success'. With Lr left unbound, there is no telling whether the solution is optimal.
Thanks for reporting this!

Related

Evaluating expressions with indexicals in SICStus Prolog

I'm trying to write a predicate in SICStus Prolog such that given an expression, I can evaluate it (possible several times). The following works as expected:
?- A is 1, H = A+2+2, C is H.
C = 5 ?
yes
And so does this more elaborate code:
testing(Variables, Updates, Values, Result):-
assert(temp(Variables, Updates)),
temp(Values, Result),
abolish(temp/2).
evaluate([],[]).
evaluate([Term|T1],[H|T2]):-
H is Term,
evaluate(T1,T2).
Now, if instead A is an indexical, say A in 1..3, it doesn't work anymore. Any ideas about how to fix it?
The longer code is supposed to be used as follows:
?- testing([A,B,C], [A+1,B+C,max(A,B)], [0,0,0], Result), evaluate(Result, R).
Result = [0+1,0+0,max(0,0)],
R = [1,0,0] ?
yes
But is suffers from the same problem as the small example: I can't provide ranges of values in this way:
?- Val1 in 1..2, Val2 in 3..10, testing([A,B], [A+1,B+A], [Val1,Val2], Result), evaluate(Result, R).
Any suggestions?
My current solution requires replacing is/2 with val_of/2. It works, but I still believe there should be a better/faster implementation.
testing(Variables, Updates, Values, Result):-
assert(temp(Variables, Updates)),
temp(Values, Result),
abolish(temp/2).
evaluate([],[]).
evaluate([Term|T1],[H|T2]):-
val_of(H,Term),
evaluate(T1,T2).
val_of(E,E):- number(E),!.
val_of(E,E):- var(E),!.
val_of(V,E1+E2):- !, val_of(V1,E1), val_of(V2,E2), V #= V1+V2.
val_of(V,E1-E2):- !, val_of(V1,E1), val_of(V2,E2), V #= V1-V2.
val_of(V,max(E1,E2)):- !, val_of(V1,E1), val_of(V2,E2), V #= max(V1,V2).
val_of(V,min(E1,E2)):- !, val_of(V1,E1), val_of(V2,E2), V #= min(V1,V2).
val_of(V,abs(E1,E2)):- !, val_of(V1,E1), val_of(V2,E2), V #= abs(V1,V2).
A test example:
| ?- X in 1..3, testing([A,B], [A+1,B], [X,0], R), evaluate(R,R1).
R = [X+1,0],
R1 = [_A,0],
X in 1..3,
_A in 2..4 ?
yes
I think that all you need is just
evaluate([],[]).
evaluate([Term|T1],[H|T2]):-
H #= Term,
evaluate(T1,T2).
but the temp/2 relation is unnecessary, so a real simplification could be:
testing(Variables, Updates, Values, Result):-
maplist(#=, Updates, Values), Result=Variables.
results in
?- testing([A,B,C], [A+1,B+C,max(A,B)], [0,0,0], Result).
A = -1,
B = C, C = 0,
Result = [-1, 0, 0].
(note: tested in SWI-Prolog, after ?- [library(clpfd)].)
My final solution is a modified version of my original code based on the useful answers and comments provided by #CapelliC and #false:
testing(Variables, Updates, Values, Result):-
copy_term(Variables-Updates, Values-Result).
evaluate([],[]).
evaluate([Term|T1],[H|T2]):-
call(H #= Term),
evaluate(T1,T2).
The main issue in my original code was the missing call/1 in evaluate/2.
A test example in SICStus Prolog looks like this:
?- A in 1..3, testing([C,D,R],[C+1,max(D,5),R],[A,0,0],Res), evaluate(Res,T).
Res = [A+1,max(0,5),0],
T = [_A,5,0],
A in 1..3,
_A in 2..4 ?
yes

swi-prolog abs operator not working in clpfd module

I am doing some toy tests with the CLPFD library in swi-prolog.
Does anybody know why the program below does not work?
start(X,Y):-
Vars = [X,Y],
Vars ins 1..3,
abs(X-Y) #>= 2,
X #>= Y,
nl,
write([X,Y]), nl.
The expected answer for start(X,Y) would be X=3 and Y=1. However, swi-prolog indicates me multiple answers. The program works properly if I replace
abs(X-Y) #>= 2
by
X-Y #>= 2
My question is whether I am using the abs operator in the right way.
First of all, constraints and side-effects do not flock together. Instead, simply stick to the pure part of your program:
start(X,Y):-
Vars = [X,Y],
Vars ins 1..3,
abs(X-Y) #>= 2,
X #>= Y.
And now, query your relation:
?- start(X,Y).
X in 1..3, X#>=Y, abs(X-Y)#>=2, Y in 1..3.
The answer is a conditional one:
Yes, there are solutions for X and Y provided all these conditions hold.
To get actual values, you have to eliminate all these conditions. You have several options:
In this case, you can use labeling/2:
?- start(X,Y), labeling([], [X,Y]).
X = 3, Y = 1.
So there is exactly one solution. The clpfd-solver alone was not powerful enough to come to this conclusion, it needed some extra help.
Even better would be to use contracting/1:
?- start(X,Y), clpfd:contracting([X,Y]).
X = 3, Y = 1.
In contrast to labeling, contracting tries to reduce the size of the domain without (visible) search. This makes the solver a bit stronger.
Reasons why the solver is not powerful enough
in the very general case solving such arithmetic problems is undecidable.
in more specific cases the algorithms would be extremely costly. In fact, there is more than one diophant in the room.
even simpler algorithms are very costly in terms of both implementation effort and runtime.
for many situations, the solver boils down to maintaining consistencies within one constraint1. So the only way to "communicate" between different constraints are the domains of variables.
In your case, the abs-constraint admits more solutions!
?- [X,Y]ins 1..3, abs(X-Y)#>=2, labeling([],[X,Y]).
X = 1, Y = 3
; X = 3, Y = 1.
?- [X,Y]ins 1..3, X-Y#>=2, labeling([],[X,Y]).
X = 3, Y = 1.
What you expect is that the extra constraint X #>= Y would help. Alas, the concrete consistency mechanisms are too weak. And not even X #> Y helps:
?- [X,Y]ins 1..3, abs(X-Y)#>=2, X#>Y.
X in 2..3, Y#=<X+ -1, abs(X-Y)#>=2, Y in 1..2.
However, if you switch from SWI to SICStus, things are a bit different:
| ?- assert(clpfd:full_answer).
| ?- X in 1..3, Y in 1..3, abs(X-Y)#>=2.
Y+_A#=X, X in 1..3, Y in 1..3, _A in{-2}\/{2}.
| ?- X in 1..3, Y in 1..3, abs(X-Y)#>=2, X#>Y.
X = 3, Y = 1.
Please note how abs is resolved!
And using SICStus with library(clpz) has the same strength:
| ?- X in 1..3, Y in 1..3, abs(X-Y)#>=2, X#>Y.
X = 3, Y = 1.
1 Note that I avoid to use the notion of local consistency as opposed to global consistency, since quite often also global consistency only refers to consistency within one "global" constraint.

Prolog: Is there a command to list all built in predicates?

Is there a command that can be used in Sicstus Prolog that prints a list of built in predicates to the console window? Or something with a similar behaviour?
The following link suggests that a predicate apropos can be used to suggest predcicates based on a keyword, but this is for SWI-Prolog, no Sicstus.
http://www.swi-prolog.org/pldoc/doc_for?object=section%282%2C%27F.1%27%2Cswi%28%27%2Fdoc%2FManual%2Fpredsummary.html%27%29%29
In SICStus Prolog, you can use the predicate_property/2 built-in predicate to list built-in predicates. For example:
| ?- predicate_property(P, built_in).
P = get_char(_A) ? ;
P = execution_state(_A) ? ;
...
If you want a list with all built-in predicates, try:
| ?- findall(P, predicate_property(P, built_in), L).
L = [get_char(_A),execution_state(_B),nospy _C,print_coverage(_D),print_profile(_E),debugging,disable_breakpoints(_F),current_breakpoint(_G,_H,_I,_J,_K),execution_state(_L,_M),spy(...)|...] ?
yes
current_predicate/1 is defined by ISO and seems to be available at least for SICSTUS, SWI-Prolog, and GNU-Prolog.
predicate_property/2 pointed out in the other answer is also available at least in these three Prolog implementations.
Note that for GNU-Prolog you would have to first turn off "strict_iso" if you want to enumerate built-ins with current_predicate/1:
| ?- current_predicate(P).
no
| ?- assertz(aaa).
yes
| ?- current_predicate(P).
P = aaa/0 ? ;
(1 ms) no
| ?- set_prolog_flag(strict_iso, off).
yes
| ?- current_predicate(P).
P = max_list/2 ? ;
P = at_end_of_stream/0 ? ;
P = at_end_of_stream/1 ? % and so on

SICStus Prolog 4.3.2: clpfd got no power?

Some of my Prolog programs could profit quite a bit if I could replace all (is)/2-based integer arithmetics by their clpfd counterpart.
So I want the power ... with clpfd ... so I can replace X is 10^3 with something clpfd-y :)
Consider the following five Prolog processors supporting clpfd:
GNU Prolog 1.4.4
?- X #= 10^3.
uncaught exception: error(type_error(fd_evaluable,(^)/2),(#=)/2)
?- X #= 10**3.
X = 1000.
SWI-Prolog 7.3.14
?- use_module(library(clpfd)). % autoload would be even more awesome
true.
?- X #= 10^3.
X = 1000.
?- X #= 10**3.
ERROR: Domain error: `clpfd_expression' expected, found `10**3'
B-Prolog 8.1
?- X #= 10^3.
X #= 10^3.
*** error(illegal_array_access,10^3)
?- X #= 10**3.
X = 1000.
SICStus Prolog 4.3.2
?- use_module(library(clpfd)).
true.
?- X #= 10^3.
! Existence error in (^)/2
! constraint user:wi(^)/2 does not exist
! goal: 10^3
?- X #= 10**3.
! Existence error in user:(**)/2
! constraint user:(**)/2 does not exist
! goal: 10**3
Ideas / hints / advice, please.
What can I do? Use some clpfd compatibility layer(s), perhaps?
Thank you in advance!
Quick hack to the rescue?
Warning: massive overkill ahead, but... does it even work? And is it portable?
Let's check it out!
SWI-Prolog 7.3.14
using clpq
?- use_module(library(clpq)).
true.
?- clpq:{X = 10^3}, integer(X).
X = 1000. % <== SUCCESS!
using clpr
?- use_module(library(clpr)).
true.
?- clpr:{X = 10^3}, integer(X).
false.
SICStus Prolog 4.3.2
using clpq
?- use_module(library(clpq)).
true.
?- clpq:{X = 10^3}, integer(X).
false.
using clpr
?- use_module(library(clpr)).
true.
?- clpr:{X = 10^3}, integer(X).
false.
1X success, 3X failure... Works, well, kind of... Then again, I guess it ain't it.
You can use for constant expressions:
?- X is 10^3.
X = 1000.
Which should work in a ISO compliant prolog thanks to corr2.
It will also propagate inside CLP(FD) as if it were X #= 10^3:
?- Y #= X+1, X is 10^3.
Y = 1001
X = 1000

Residual constraints with reification in clpfd

I defined reified variants of the
clpfd constraints (#<)/2, (#=<)/2, (#>=)/2 and (#>)/2:
:- use_module(library(clpfd)).
ltA(X,Y,Truth) :- X #< Y #<==> B, bool01_truth(B,Truth).
ltB(X,Y, true) :- X #< Y.
ltB(X,Y,false) :- X #>= Y.
lteA(X,Y,Truth) :- X #=< Y #<==> B, bool01_truth(B,Truth).
lteB(X,Y, true) :- X #=< Y.
lteB(X,Y,false) :- X #> Y.
gteA(X,Y,Truth) :- X #>= Y #<==> B, bool01_truth(B,Truth).
gteB(X,Y, true) :- X #>= Y.
gteB(X,Y,false) :- X #< Y.
gtA(X,Y,Truth) :- X #> Y #<==> B, bool01_truth(B,Truth).
gtB(X,Y, true) :- X #> Y.
gtB(X,Y,false) :- X #=< Y.
Of course, ltA/3 and ltB/3 are logically equivalent, as are
lteA/3 and lteB/3, gteA/3 and gteB/3, and gtA/3 and gtB/3.
The answers I get using these predicates, however, differ regarding size and readability. I ran the following queries with SWI-Prolog 7.1.37:
Good news, first!
?- lteA(X,Y,Truth).
Truth = false, Y#=<X+ -1 ;
Truth = true, Y#>=X.
?- lteB(X,Y,Truth).
Truth = true, Y#>=X ;
Truth = false, Y#=<X+ -1.
?- gteA(X,Y,Truth).
Truth = false, X#=<Y+ -1 ;
Truth = true, X#>=Y.
?- gteB(X,Y,Truth).
Truth = true, X#>=Y ;
Truth = false, X#=<Y+ -1.
Ok! But what about the other two?
?- ltA(X,Y,Truth).
Truth = false, X+1#=_G968, Y#=<_G968+ -1 ;
Truth = true, X+1#=_G912, Y#>=_G912.
?- ltB(X,Y,Truth).
Truth = true, X#=<Y+ -1 ;
Truth = false, X#>=Y.
?- gtA(X,Y,Truth).
Truth = false, X#=<_G1301+ -1, Y+1#=_G1301 ;
Truth = true, X#>=_G1243, Y+1#=_G1243.
?- gtB(X,Y,Truth).
Truth = true, Y#=<X+ -1 ;
Truth = false, Y#>=X.
Not quite!
How do I get compact answers with ltA/3 and gtA/3---just like with lteA/3 and gteA/3?
It runs counter the basic idea of CLP(FD) to have compact
answers. Since CLP(FD) usually doesn't do gauss elimination and
similar things. Its not like a Computer Algebra System (CAS).
In CLP(FD), you basically model your problem by entering
inequations, and the system is allowed to do nothing with this
inequations as long as you don't call labeling.
Some CLP(FD) realizations already check consistency to some
degree when entering inequations and/or already do simplifications
and propagations. But this isnt mandatory.
In your example you have E #= X where E is an expression and
X is a variable. There is no guarantee that occurences
of X are replaced by E when entering a model.
Usually this is not done in CLP(FD), since it would blow
up the entered model. You can directly test that this
is not simplified:
Welcome to SWI-Prolog (Multi-threaded, 64 bits, Version 7.3.4)
Copyright (c) 1990-2015 University of Amsterdam, VU Amsterdam
?- use_module(library(clpfd)).
true.
?- A#=X+1, Y#=<A+ -1.
Y#=<A+ -1,
X+1#=A.
The same also happens in Jekejeke Prolog. The CLP(FD) of
Jekejeke Prolog is open source here. Refification itself
is planned but not yet implemented:
Jekejeke Prolog, Runtime Library 1.0.7
(c) 1985-2015, XLOG Technologies GmbH, Switzerland
?- use_module(library(finite/clpfd)).
% 11 consults and 0 unloads in 513 ms.
Yes
?- A#=X+1, Y#=<A+ -1.
A #= 1+X,
-1+A #>= Y
Typicall an equation E #= X only leads to substitutions when
E is also a variable or constant. This might explain why your
examples look different from case to case.
Here you see SWI-Prolog simplifying A #= X. I just modified
the above example slightly so that E is a variable:
?- A#=X, Y#=<A+ -1.
A = X,
Y#=<X+ -1.
And here you see Jekejeke Prolog doing it (Todo bug fix: I
guess I need to reorder the rules a little bit, so that it
gives A = X and not X = A as here):
?- A#=X, Y#=<A+ -1.
X = A,
-1+A #>= Y
The case of E #= X where E is a constant and where this
value is propagated is called forward checking. This is the
minimum requirement a CLP(FD) must be able to do, otherwise
labeling would not work.
But already the case of E #= X where E is a variable a
propagation isn't mandatory. But the testing above shows
that many CLP(FD) do it. Propagating variables leads to
union find algorithms and the like.
Bye

Resources