Question

I have a program written in Sicstus Prolog using constraints. My goal is to use labeling/2 and some other method to obtain a random instantiation of my variables.

Example:

X #> 2, Y #= 2*X, Z #<10

If I use

List = [X,Y,Z],
labeling([], List)

The first result obtained will be X = Y = Z = 0. How do you think is the best way to return a random set of values for X, Y and Z?

Était-ce utile?

La solution

I do not know much about the labeling options in recent SICStus versions, but with library(clpfd) of SWI-Prolog, there are the options random_variable(Seed) and random_value(Seed), you can use them for example with labeling([random_variable(10),random_value(10)], List). Maybe you can get the authors of SICStus to integrate similar options?

Autres conseils

In sicstus, this is done with a custom selection of variables / values.

In your case, just do:

labeling([value(mySelValores)], List)

mySelValores(Var, _Rest, BB, BB1) :-
    fd_set(Var, Set),
    select_best_value(Set, Value),
    (   
        first_bound(BB, BB1), Var #= Value
        ;   
        later_bound(BB, BB1), Var #\= Value
    ).

select_best_value(Set, BestValue):-
    fdset_to_list(Set, Lista),
    length(Lista, Len),
    random(0, Len, RandomIndex),
    nth0(RandomIndex, Lista, BestValue).

See value(Enum) in https://sicstus.sics.se/sicstus/docs/4.0.4/html/sicstus/Enumeration-Predicates.html.

Hope it helps ;)

I have opted in Jekejeke Prolog, for a new predicate random_labeling/1 in connection with CLP(FD) that takes implicitly the random number generator from the knowledge base that can be accessed and modified via the sys_random Prolog flag.

Jekejeke Prolog 3, Runtime Library 1.3.4
(c) 1985-2019, XLOG Technologies GmbH, Switzerland

?- use_module(library(finite/clpfd)).
% 20 consults and 0 unloads in 944 ms.
Yes

?- use_module(library(basic/random)).
% 0 consults and 0 unloads in 0 ms.
Yes

?- random_new(111,R), set_prolog_flag(sys_random,R), 
   X in 0..5, Y #= X*X, random_label([X,Y]), 
   write(X-Y), nl, fail; true.
4-16
3-9
5-25
1-1
2-4
0-0
Yes

?- random_new(111,R), set_prolog_flag(sys_random,R), 
   X in 0..5, Y #= X*X, random_label([X,Y]), 
   write(X-Y), nl, fail; true.
4-16
3-9
5-25
1-1
2-4
0-0

I am planning a further predicate random_labeling/2. But it would not take a seed, but instead a Java java.util.Random instance. This is more versatile than a seed. But I guess changing the API to labeling/2 and some options would be the best way to go.

Edit 29.12.2018: I will now take notes, since I guess its a good idea to adopt indomain/2, currently I have implemented random_indomain/1, and from this implemented random_label/1. See also here:

indomain/2 from ECLiPSe Prolog random: Try the enumeration in a random order. On backtracking, the previously tested value is removed. This method uses random/1 to create random numbers, use seed/1 before to make results reproducible. http://eclipseclp.org/doc/bips/lib/gfd_search/indomain-2.html

you can use all_different([X,Y,Z]) in order to get different values however, working with random seed in Sicstus could be tricky and you may need to define a function to change the seed or start the random function again. check below www.sics.se/sicstus/docs/3.7.1/html/sicstus_23.html

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top