Thread creation in first_solution

Hello,

What’s the strategy of thread creation in first_solution/3? Is it like in concurrent_maplist (i.e. the number of threads is the minimum of the list length and the number of cores available)? If the length of :Goals is larger than the number of cores available, once one of the goals fails a new element of :Goals is launched in that now unused core?

Hope the questions are clear.

Thanks!

Maxi

Click the (:-) link to the source (thread.pl) and find

create_solvers([], _, _, _, [], _).
create_solvers([H|T], M, X, Done, [Id|IDs], Options) :-
    thread_create(solve(M:H, X, Done), Id, Options),
    create_solvers(T, M, X, Done, IDs, Options).

For short, it creates a thread per solver, regardless of the number of cores. Where concurrent_maplist/3 creates as many threads as cores (or less if the list is shorter).

first_solution/3 is primarily intended to solve problems for which you have alternative algorithms to solve them but there is no good way to predict which one is better. So, you want to try them concurrently, even if you have fewer cores than algorithms.

Thanks Jan!

Sorry for this but I’m not sure what I’m doing wrong here.

?- first_solution([X],[(X=a,1=2),(X=a,1=2),(X=b)],[]).
false.

?- first_solution([X],[(X=a,1=2),(X=a,1=2),(X=b)],[]).
X = b.

I’ve run the same query over and over again sometimes getting false and others X = b.

If (X=a,1=2) is repeated several times (32 in my case) leaving X=b as the last element of the list the answer is always false (or at least after executing the query over 10 times false is the only answer I get).

Thanks again!

What exactly do you expect to happen? The docs say,

Try alternative solvers concurrently, returning the first answer. In a typical scenario, solving any of the goals in Goals is satisfactory for the application to continue. As soon as one of the tried alternatives is successful, all the others are killed and first_solution/3 succeeds.

In the case of (X=a, 1=2): this is always false (right??) so as soon as it fails you get your false. This sounds correct to me?

So, what were you expecting to happen here?

Are you sure you didn’t mean:

first_solution([X],[(X=a,1=2),(X=a,1=2),(X=b)],[on_fail(continue)]).

This is what the docs say:

If stop (default), terminate all threads and stop with the failure. If continue, keep waiting.

Ahhh, OK, now I see. I was thinking in getting a positive answer so I thought that if a thread returned false first_solution will wait until another thread returned something different from false.

Thanks for the clarification!

Maxi