Consider a simple constraint example a == b + c;
Now if you constraint any of the 2 values of a,b,c the third value gets generated automatically due to the bi-directional nature of the constraint.
Now modify the constraint void (a) == b+ C;
Value of a gets generated first based on which b and c are generated. Generating a based on b and c is not possible. The same functionality can be achieved by using a solve before constraint as follows.
a== b+c;
solve a before b; solve a before c;
Functions can be used in constraints for reusability between constraints, but important point to note is the constraints will become uni-directional when used in a function.
function integer sum (integer b, integer c);
sum=b+c;
end function
Constraint sum_constraint { a==sum(b,c); }