Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extending automatic teststuite #464

Merged
merged 56 commits into from
May 21, 2024
Merged

Extending automatic teststuite #464

merged 56 commits into from
May 21, 2024

Conversation

IgnaceBleukx
Copy link
Collaborator

Extended the automatic test_constraints testsuite which uncovers several bugs (some of which are fixed in this PR)

Main changes to test file:

  • Inspect "globalconstraints.py" and "globalfunctions.py" files to automatically generate all global constraints
  • All Boolean expressions, including global constraints are also tested as numerical expressions now
  • Option to do a solveAll which tests wheter all solutions to the constraint are valid. Untested for now as it takes a long time for some consrtaints, but potentially usefull before doing a release?
  • General cleanup

Bugs and fixes:

  • [fixed in Save all uservars #463] Some vars were unknown to the solver
  • [fixed] Simplify Boolean did not translate comparisons to 0/1 when in numerical context
  • [fixed] When partial functions are in a toplevel constraint, should be translated to False and not throw an error (I am unsure about this fix, it produced a lot of duplicate code, potential for cleanup here)
  • [open] incorrect decomposition of Inverse consrtraint when nested

The last is also why the automatic tests fail for now.

@IgnaceBleukx IgnaceBleukx added the blocked Pull request blocked by another pull request/issue. label May 2, 2024
# Conflicts:
#	tests/test_solvers.py
@Dimosts
Copy link
Collaborator

Dimosts commented May 2, 2024

Is this a draft?

@Dimosts
Copy link
Collaborator

Dimosts commented May 2, 2024

Quite some errors in Choco too, regarding GCC. Choco accepts only ints for values, and not variables

@Wout4
Copy link
Collaborator

Wout4 commented May 4, 2024

The inverse bug is just because it uses element probably?
Maybe disable inverse if we want to merge this, but indeed there should be a way to get rid of all that duplicate code..

@Wout4
Copy link
Collaborator

Wout4 commented May 4, 2024

We could have argval return an 'undefined' value in stead of raising an error

@Wout4
Copy link
Collaborator

Wout4 commented May 10, 2024

Fine to be merged by me, but some conflict to be resolved first

@Wout4
Copy link
Collaborator

Wout4 commented May 13, 2024

I could not resist giving this another try :)
The way I implemented it now argval() helper function handles all the incompletefunctionerror things, which is nice because we can just keep all our old .value() implementations.

Downside is that .value() is not safe anymore so you (and user) should always use argval() or .safe_value() in stead of .value()

@IgnaceBleukx
Copy link
Collaborator Author

IgnaceBleukx commented May 15, 2024

Hmm not sure if I like having two value functions... Using argval seems like a good solution tho!
Actually, if we assume reasonable use by the user. That is, a user does not set values to a constraint himself, we might not even need to wrap the .value() function at all!

Take the following (convoluted) example:

m = cp.Model()
arr = cp.intvar(0,10, shape=3, name="arr")
idx = cp.intvar(0,10, name="idx")
x = cp.boolvar(name="x")
y = cp.boolvar(name="y")

m += cp.AllEqual([cp.AllDifferent([arr[idx], 11, 12]),x,y]) 
m += idx == 7

Then, arr[idx] is undefined, hence will throw the exception.
As AllDifferent is the nearest Boolean context to the undefinedness, it should be set to False. But this is done by the argval call originating from AllEqual
E.g., the constraint becomes AllEqual(False, x,y) which is a perfectly valid constraint and can proceed as normal.

So basically what I'm saying is: the Boolean expression catching the undefinedness will never be at the top-level of the constraint model when the user is interested in the value of the decision variables. This is true as the model will be UNSAT when a constraint at toplevel is set to False because of the undefinedness so no values are assigned to the variables anyway.

So, as long as the value of the arguments of any expression are calculated using argval we do not need to put any logic about the exceptions into the individual expressions. This means we can revert the changes of the safe_value() and just put that logic into argval again like it used to be.

@Wout4
Copy link
Collaborator

Wout4 commented May 15, 2024

yeah exactly, .value() will only fail if it is called on a toplevel constraint with an undefined value directly underneath, because at all the other levels argval will take care of the undefinedness.
The extra safe_value function does feel quite useless, but we actually need it to be a class function because then it knows if it is being called on a boolean expression or not. argval can not know this..
I guess we could make it hidden _safe_value() and tell the user only about argval

@IgnaceBleukx
Copy link
Collaborator Author

IgnaceBleukx commented May 15, 2024

Yup indeed, but that can actually still happen...

m = cp.Model()
arr = cp.intvar(0,10, shape=3, name="arr")
idx = cp.intvar(0,10, name="idx")
x = cp.boolvar(name="x")
y = cp.boolvar(name="y")

aldiff_expr = cp.AllDifferent([arr[idx], 11, 12])
m += cp.AllEqual([alldiff_expr,x,y]) 
m += idx == 7
m.solve()

alldiff_expr.value()
>> exception

Ok, so lets indeed put in the exception one should use "argval" instead of value(), but still remove the safe_value().
A user can just do argval(alldiff_expr) which returns False as expected if we put the logic of is_bool into argval.

You can still call the argval() on the Element constraint here, i.e., argval(arr[idx]) will return an exception, but thats fine to me.

@IgnaceBleukx IgnaceBleukx mentioned this pull request May 17, 2024
@IgnaceBleukx
Copy link
Collaborator Author

@Wout4 A lot of PRs depoend on this one now. I think it is ready to merge?

@Wout4
Copy link
Collaborator

Wout4 commented May 17, 2024

Indeed, if it also looks good to you will merge it

@IgnaceBleukx
Copy link
Collaborator Author

Strictly increasing test was failing for Minizinc but excluded it now and reported on their github. Will merge it so all other PRs can use the new testsuite too

@IgnaceBleukx IgnaceBleukx merged commit ab9d558 into master May 21, 2024
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
blocked Pull request blocked by another pull request/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants