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?
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.
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).
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?
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.