trying to understand the interaction between functions, sum and constraints

23 views
Skip to first unread message

C. G.

unread,
May 17, 2026, 5:22:35 PM (8 days ago) May 17
to Picat
In the following mini-program, main2 works, whereas main1 doesn't - it is the same, just using the function call next(Z) instead of Z+1. 
Why does main1 produce such an error?
 *** error(invalid_constraint_exp,next(_270))

Shouldn't next(Z) and Z+1 be interchangeable, given the definition of the function "next"?

import sat.
next(X)=X+1.
%this doesn't work,
main1=>[X,Y]::0..1,sum([next(Z):Z in [X,Y]])#<20,solve([X,Y]).
%this works
main2=>[X,Y]::0..1,sum([  Z+1  :Z in [X,Y]])#<20,solve([X,Y]).

best regards,
CG

Claudio Cesar de Sa

unread,
May 17, 2026, 6:36:28 PM (8 days ago) May 17
to C. G., Picat
Hi

Trying to help you, normally I avoid  mixing the  functions and constraints ....due evaluations by the solvers.
The solvers follow some systematic order to process the constraints and deal with its domain reduction.
Here a version to play (naive version) on your doubt. Surely, Neng-Fa and others will be able to answer you precisely.

import sat.

my_next(X) = X+1.

main =>
    [X,Y] :: 0..1,%% any domain
%    Nexts = [NZ : Z in [X,Y], NZ #= Z + 1], %%% works also
     Nexts = [NZ : Z in [X,Y], (NZ #= X+1 ; NZ #= Y+1) ]  ,
     sum(Nexts) #< 20,
     solve_all([X,Y]) = All_Sol,
     println(All_Sol).

All: [[1,0],[1,1],[0,0],[0,1]]








--
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/6e04fe25-395e-4440-986a-c7d5ce864184n%40googlegroups.com.


--
claudio

**********************************************************************
Whatsapp: +55 47 992451825
Telegram: @ccs1664
***********************************************************************

C. G.

unread,
May 18, 2026, 4:54:15 AM (7 days ago) May 18
to Picat
The thing is, for ASPIC I need to combine functions (usually returning constraint variables or expressions over them) and constraints.
This is why I distilled the things not working to the smallest example possible and produced the example given in the first post.

best regards,
CG

Neng-Fa Zhou

unread,
May 18, 2026, 11:51:29 AM (7 days ago) May 18
to C. G., Picat
In Picat, expressions in arithmetic constraints are constructed as terms and passed to the constraint solver. The only functions that are eagerly evaluated are index operations, such as X[I,J], and comprehensions, such as [X[I] : I in 1..100]. Picat allows certain built-in functions, such as sum/1, min/1, and max/1, in constraint arithmetic expressions, but never allows user-defined functions. You can find the details in Section 12.3 in the User's Guide (https://picat-lang.org/download/picat_guide_html/picat_guide.html#x1-14100012).

Cheers,
NF

Oisín Mac Fhearaí

unread,
May 18, 2026, 12:33:51 PM (7 days ago) May 18
to Picat
There are some limitations yes, but you can call a predicate that uses constraint expressions like this:

import sat.

main => main_alt.

next(X)=X+1.
next_alt(X,Fx) => Fx #= X+1.


%this doesn't work,
main1=>[X,Y]::0..1,sum([next(Z):Z in [X,Y]])#<20,solve([X,Y]).
%this works
main_alt=>[X,Y]::0..1,sum([ Fx : Z in [X,Y], next_alt(Z,Fx)])#<20,solve([X,Y]).

Oisín

C. G.

unread,
May 21, 2026, 7:14:07 AM (4 days ago) May 21
to Picat
I've found out that this way with functions that return constraint variables and many indirections through variables works as well, so this is what we'll use in ASPIC, where we need to combine functions with constraints:
import sat.
next(X)=Y=>Y#=X+1.
main=>[X,Y]::0..1,sum([Z3:Z in [X,Y],Z2=next(Z),Z3#=Z2])#<20,solve([X,Y]).

CG
Reply all
Reply to author
Forward
0 new messages