Picat Version 3.9#8 Released

50 views
Skip to first unread message

Neng-Fa Zhou

unread,
May 20, 2026, 7:21:10 PMMay 20
to Picat
Picat 3.9#8 is available from https://picat-lang.org and  https://github.com/picat-lang/Picat.

This release brings major improvements to the SAT compiler and delivers significant performance gains on Pseudo-Boolean (PB) optimization problems.

In our experiments, the new version solves nearly twice as many PB instances as the version submitted to last year’s PB competition. These improvements are the result of several new techniques and optimizations introduced in the SAT compiler.

Improved PB Constraint Decomposition: A new algorithm for decomposing PB constraints has been introduced that exploits the presence of at-most-one constraints. This optimization significantly reduces encoding size and improves propagation efficiency on many benchmark instances.

Advanced Hybrid Encodings: New hybridization strategies have been developed for combining BDD, binary-adder, and Espresso encodings of PB constraints. The compiler can now better adapt encodings to the features of individual constraints, resulting in smaller SAT instances and faster solving times.

Bit-Vector Objectives in solve/2: The objective to be minimized or maximized in the solve/2 predicate of the sat module can now be specified as a bit-vector. This enhancement makes it possible to model optimization problems that involve big objective values.

Improved Branch-and-Bound Implementation: The implementation of the branch-and-bound algorithm in the SAT compiler has been improved. The new implementation generally reduces the number of calls of the SAT solver required to find optimal solutions.

We thank the Picat community for their continued support and feedback.

Neng-Fa Zhou

unread,
May 20, 2026, 7:33:21 PMMay 20
to Picat
P.S. The Linux executable was built with an older version of gcc/g++ to avoid dependencies on newer system libraries. For the best performance, I recommend building Picat from the source code.

Cheers,
NF

--
You received this message because you are subscribed to the Google Groups "Picat" group.
To unsubscribe from this group and stop receiving emails from it, send an email to picat-lang+...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/picat-lang/4ce798d4-0d2d-4128-b7ae-3f48102e3973n%40googlegroups.com.

C. G.

unread,
May 21, 2026, 8:38:03 AMMay 21
to Picat
Hi Neng-Fa,

A related bug report:

With 3.9#7 and with the new 3.9#8 as well (both on Linux) there are differences between the solution sets for cp vs sat.
I have extracted from a program generated by ASPIC a reproducible small test:

import cp. %returns [[0,0],[1,-2]]

%import sat. %returns only [[1,-2]]
main=>
A::0..1,
B#=cond(A, -2 ,0), % "useless" constraint that leads to the cp vs sat difference
L=solve_all([A,B]),println(L).

SAT fails to find one of the solutions in this case. In other cases, as it constraints more than it should, it fails to find solutions at all to models that cp solves successfully ; in yet other cases, by missing some of the search space it fails to find with sat the optimum value when the problem is one of optimization (I have seen all that).

The behavior is triggered by the constraint involving cond. It might well be that I don't understand something there, as the cp vs sat difference disappears when the -2 in cond is replaced with a positive number, such as 2. 

best regards,
CG

Neng-Fa Zhou

unread,
May 21, 2026, 10:46:19 AMMay 21
to C. G., Picat
Thanks, Cristian, for spotting that. I have fixed the bug and released a patch 3.9#8.1.

Best regards,
NF

Oisín Mac Fhearaí

unread,
May 21, 2026, 1:14:54 PMMay 21
to Neng-Fa Zhou, C. G., Picat
Very cool! I tested it on a couple of Advent of Code SAT solutions and got speedups from 60s -> 34.6s and 5.1s -> 4.2s. Impressive.

C. G.

unread,
May 22, 2026, 2:07:47 AMMay 22
to Picat
I hoped for a similar improvement on the N-queens benchmark for large N where in the ASPIC paper we compare clingo and aspic/picat on the same source. 
With picat 3.9#4, 512 queens is solved in 26 s. 
With 3.9#8.1 the time on the same machine is 62.5 s. 
With Picat 3.9#7: 64.5 s.
Somewhere between 3.9#4 and 3.9#7  picat got twice slower on that problem.

CG

Neng-Fa Zhou

unread,
May 23, 2026, 9:21:21 AMMay 23
to Picat
While the new version with the new optimizations overall is faster, it may be slower on some instances. This is always the case as the SAT solver uses opportunistic strategies. I notice that 3.9#8 is much slower than 3.9#6 on the bqueens benchmark (https://picat-lang.org/sat/bqueens.pi). For n=500, 3.9#6 took 5.5s while 3.9#8 took 16.3s on my computer, despite that the encoding sizes are similar (nvars=370042,ncls=2420822 for 3.9#6 and nvars=370050,ncls=2420650 for 3.9#8).

Cheers,
NF

C. G.

unread,
Jun 10, 2026, 4:55:07 AM (8 days ago) Jun 10
to Picat
Hi Neng-Fa,
 
Even with the Picat version 3.9#8.2 there are differences between cp and sat.
I've tried to isolate and simplify the bug-reproducing program,  it is given below. CP solves it the way I expect it, finds a set of edges that define a tree on 4 nodes, and reports the set of edges and how many are selected.
SAT just fails.
Here is the program.

%import cp.
import sat.
main:-
N=4,
X=new_array(N,N),X::0..1,
V=[{I,1}:I in 1..N],E=[{I,J,X[I,J]}:I in 1..N,J in 1..N],tree(V,E),
S#=sum([1:I in 1..N, J in 1..N,X[I,J]#=1]),
solve([X,S]),
println(s=S),
println(x=X).


best regards,
CG

Neng-Fa Zhou

unread,
Jun 10, 2026, 5:12:08 AM (8 days ago) Jun 10
to C. G., Picat
Hi Cristian,

I am surprised to see that this program works with cp. You should not use constraints in an iterator because an iterator condition is checked eagerly. If you change

S#=sum([1:I in 1..N, J in 1..N,X[I,J]#=1]),

to 

S#=sum([X[I,J]:I in 1..N, J in 1..N]),

your program should work as expected.

Cheers,
NF

C. G.

unread,
Jun 16, 2026, 5:46:31 PM (yesterday) Jun 16
to Picat
Hi Neng-Fa,

My usage is more complex, this was a minimal reproducing example. These situations appear in ASPIC when it translates ASP aggregators, say
#sum{Y:gen(Y),test(Y)}>5.
When in the ASP program there are these as well
gen(1..2).
test(2..3).
the predicate involving the aggregator expression gets translated to Picat as the following constraint expression:

aspic_gt(aspic_sum([ASPIC_OPTCOND3:Y in 1..2,Y in 2..3,ASPIC_OPTCOND1=aspic_conj([gen(Y),test(Y)]),ASPIC_OPTCOND2#=ASPIC_OPTCOND1,ASPIC_AGVAL1= Y, ASPIC_AGVAL2#=ASPIC_AGVAL1,ASPIC_OPTCOND3 #= cond(ASPIC_OPTCOND2,ASPIC_AGVAL2,0)]) ,5)

where gen/1,test/1,aspic_conj/2,aspic_gt/2,aspic_sum/1 are functions returning either 0,1 or constraint variables.
This is the workaround I found to basically use functions into constraints: Var=function_call(Args), Var2#=Var,... then Var2 can be used in further constraints.

"cond" is used to apply the condition in a constraint way. I could replace cond with multiplication Condition*Value, but I doubt multiplication leads to more efficient modelling, and I still need functions in constraints, so I have to use the workaround explained above.

best regards,
CG
Reply all
Reply to author
Forward
0 new messages