-
Notifications
You must be signed in to change notification settings - Fork 257
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
Add type hints and type loop variables #946
base: master
Are you sure you want to change the base?
Changes from all commits
459e8e1
f546bb5
e95be67
ee40ac9
68e8263
cc04b5a
1bfb401
ead3365
79c1eef
941b472
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,7 +29,7 @@ cdef class Conshdlr: | |
'''informs constraint handler that the branch and bound process is being started ''' | ||
pass | ||
|
||
def consexitsol(self, constraints, restart): | ||
def consexitsol(self, constraints, SCIP_Bool restart): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What about There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wasn't sure if they were allowed to be just one or not and was too lazy to check There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If this is the list of constraints, I would not allow it to be a single constraint, can we declare it an iterable? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can declare something as an iterable in Python type hints. We might need to then import the |
||
'''informs constraint handler that the branch and bound process data is being freed ''' | ||
pass | ||
|
||
|
@@ -45,74 +45,74 @@ cdef class Conshdlr: | |
'''calls LP initialization method of constraint handler to separate all initial active constraints ''' | ||
return {} | ||
|
||
def conssepalp(self, constraints, nusefulconss): | ||
def conssepalp(self, constraints, int nusefulconss): | ||
'''calls separator method of constraint handler to separate LP solution ''' | ||
return {} | ||
|
||
def conssepasol(self, constraints, nusefulconss, solution): | ||
def conssepasol(self, constraints, int nusefulconss, Solution solution): | ||
'''calls separator method of constraint handler to separate given primal solution ''' | ||
return {} | ||
|
||
def consenfolp(self, constraints, nusefulconss, solinfeasible): | ||
def consenfolp(self, constraints, int nusefulconss, SCIP_Bool solinfeasible): | ||
'''calls enforcing method of constraint handler for LP solution for all constraints added''' | ||
print("python error in consenfolp: this method needs to be implemented") | ||
return {} | ||
|
||
def consenforelax(self, solution, constraints, nusefulconss, solinfeasible): | ||
def consenforelax(self, Solution solution, constraints, int nusefulconss, solinfeasible): | ||
'''calls enforcing method of constraint handler for a relaxation solution for all constraints added''' | ||
print("python error in consenforelax: this method needs to be implemented") | ||
return {} | ||
|
||
def consenfops(self, constraints, nusefulconss, solinfeasible, objinfeasible): | ||
def consenfops(self, constraints, int nusefulconss, SCIP_Bool solinfeasible, SCIP_Bool objinfeasible): | ||
'''calls enforcing method of constraint handler for pseudo solution for all constraints added''' | ||
print("python error in consenfops: this method needs to be implemented") | ||
return {} | ||
|
||
def conscheck(self, constraints, solution, checkintegrality, checklprows, printreason, completely): | ||
def conscheck(self, constraints, Solution solution, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool printreason, SCIP_Bool completely): | ||
'''calls feasibility check method of constraint handler ''' | ||
print("python error in conscheck: this method needs to be implemented") | ||
return {} | ||
|
||
def consprop(self, constraints, nusefulconss, nmarkedconss, proptiming): | ||
def consprop(self, constraints, int nusefulconss, int nmarkedconss, SCIP_PROPTIMING proptiming): | ||
'''calls propagation method of constraint handler ''' | ||
return {} | ||
|
||
def conspresol(self, constraints, nrounds, presoltiming, | ||
nnewfixedvars, nnewaggrvars, nnewchgvartypes, nnewchgbds, nnewholes, | ||
nnewdelconss, nnewaddconss, nnewupgdconss, nnewchgcoefs, nnewchgsides, result_dict): | ||
def conspresol(self, constraints, int nrounds, SCIP_PRESOLTIMING presoltiming, | ||
int nnewfixedvars, int nnewaggrvars, int nnewchgvartypes, int nnewchgbds, int nnewholes, | ||
int nnewdelconss, int nnewaddconss, int nnewupgdconss, int nnewchgcoefs, int nnewchgsides, result_dict): | ||
'''calls presolving method of constraint handler ''' | ||
return result_dict | ||
|
||
def consresprop(self): | ||
'''sets propagation conflict resolving method of constraint handler ''' | ||
return {} | ||
|
||
def conslock(self, constraint, locktype, nlockspos, nlocksneg): | ||
def conslock(self, constraint: Union[Constraint, ExprCons], int locktype, int nlockspos, int nlocksneg): | ||
'''variable rounding lock method of constraint handler''' | ||
print("python error in conslock: this method needs to be implemented") | ||
return {} | ||
|
||
def consactive(self, constraint): | ||
def consactive(self, constraint: Union[Constraint, ExprCons]): | ||
'''sets activation notification method of constraint handler ''' | ||
pass | ||
|
||
def consdeactive(self, constraint): | ||
def consdeactive(self, constraint: Union[Constraint, ExprCons]): | ||
'''sets deactivation notification method of constraint handler ''' | ||
pass | ||
|
||
def consenable(self, constraint): | ||
def consenable(self, constraint: Union[Constraint, ExprCons]): | ||
'''sets enabling notification method of constraint handler ''' | ||
pass | ||
|
||
def consdisable(self, constraint): | ||
def consdisable(self, constraint: Union[Constraint, ExprCons]): | ||
'''sets disabling notification method of constraint handler ''' | ||
pass | ||
|
||
def consdelvars(self, constraints): | ||
def consdelvars(self, constraint: Union[Constraint, ExprCons]): | ||
'''calls variable deletion method of constraint handler''' | ||
pass | ||
|
||
def consprint(self, constraint): | ||
def consprint(self, constraint: Union[Constraint, ExprCons]): | ||
'''sets constraint display method of constraint handler ''' | ||
pass | ||
|
||
|
@@ -124,11 +124,11 @@ cdef class Conshdlr: | |
'''sets constraint parsing method of constraint handler ''' | ||
pass | ||
|
||
def consgetvars(self, constraint): | ||
def consgetvars(self, constraint: Union[Constraint, ExprCons]): | ||
'''sets constraint variable getter method of constraint handler''' | ||
pass | ||
|
||
def consgetnvars(self, constraint): | ||
def consgetnvars(self, constraint: Union[Constraint, ExprCons]): | ||
'''sets constraint variable number getter method of constraint handler ''' | ||
return {} | ||
|
||
|
@@ -170,6 +170,7 @@ cdef SCIP_RETCODE PyConsFree (SCIP* scip, SCIP_CONSHDLR* conshdlr) noexcept with | |
cdef SCIP_RETCODE PyConsInit (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss) noexcept with gil: | ||
PyConshdlr = getPyConshdlr(conshdlr) | ||
cdef constraints = [] | ||
cdef int i | ||
for i in range(nconss): | ||
constraints.append(getPyCons(conss[i])) | ||
PyConshdlr.consinit(constraints) | ||
|
@@ -178,6 +179,7 @@ cdef SCIP_RETCODE PyConsInit (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** c | |
cdef SCIP_RETCODE PyConsExit (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss) noexcept with gil: | ||
PyConshdlr = getPyConshdlr(conshdlr) | ||
cdef constraints = [] | ||
cdef int i | ||
for i in range(nconss): | ||
constraints.append(getPyCons(conss[i])) | ||
PyConshdlr.consexit(constraints) | ||
|
@@ -186,6 +188,7 @@ cdef SCIP_RETCODE PyConsExit (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** c | |
cdef SCIP_RETCODE PyConsInitpre (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss) noexcept with gil: | ||
PyConshdlr = getPyConshdlr(conshdlr) | ||
cdef constraints = [] | ||
cdef int i | ||
for i in range(nconss): | ||
constraints.append(getPyCons(conss[i])) | ||
PyConshdlr.consinitpre(constraints) | ||
|
@@ -194,6 +197,7 @@ cdef SCIP_RETCODE PyConsInitpre (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS* | |
cdef SCIP_RETCODE PyConsExitpre (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss) noexcept with gil: | ||
PyConshdlr = getPyConshdlr(conshdlr) | ||
cdef constraints = [] | ||
cdef int i | ||
for i in range(nconss): | ||
constraints.append(getPyCons(conss[i])) | ||
PyConshdlr.consexitpre(constraints) | ||
|
@@ -202,6 +206,7 @@ cdef SCIP_RETCODE PyConsExitpre (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS* | |
cdef SCIP_RETCODE PyConsInitsol (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss) noexcept with gil: | ||
PyConshdlr = getPyConshdlr(conshdlr) | ||
cdef constraints = [] | ||
cdef int i | ||
for i in range(nconss): | ||
constraints.append(getPyCons(conss[i])) | ||
PyConshdlr.consinitsol(constraints) | ||
|
@@ -210,6 +215,7 @@ cdef SCIP_RETCODE PyConsInitsol (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS* | |
cdef SCIP_RETCODE PyConsExitsol (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss, SCIP_Bool restart) noexcept with gil: | ||
PyConshdlr = getPyConshdlr(conshdlr) | ||
cdef constraints = [] | ||
cdef int i | ||
for i in range(nconss): | ||
constraints.append(getPyCons(conss[i])) | ||
PyConshdlr.consexitsol(constraints, restart) | ||
|
@@ -246,6 +252,7 @@ cdef SCIP_RETCODE PyConsTrans (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS* s | |
cdef SCIP_RETCODE PyConsInitlp (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss, SCIP_Bool* infeasible) noexcept with gil: | ||
PyConshdlr = getPyConshdlr(conshdlr) | ||
cdef constraints = [] | ||
cdef int i | ||
for i in range(nconss): | ||
constraints.append(getPyCons(conss[i])) | ||
result_dict = PyConshdlr.consinitlp(constraints) | ||
|
@@ -255,6 +262,7 @@ cdef SCIP_RETCODE PyConsInitlp (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** | |
cdef SCIP_RETCODE PyConsSepalp (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss, int nusefulconss, SCIP_RESULT* result) noexcept with gil: | ||
PyConshdlr = getPyConshdlr(conshdlr) | ||
cdef constraints = [] | ||
cdef int i | ||
for i in range(nconss): | ||
constraints.append(getPyCons(conss[i])) | ||
result_dict = PyConshdlr.conssepalp(constraints, nusefulconss) | ||
|
@@ -265,6 +273,7 @@ cdef SCIP_RETCODE PyConsSepasol (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS* | |
SCIP_SOL* sol, SCIP_RESULT* result) noexcept with gil: | ||
PyConshdlr = getPyConshdlr(conshdlr) | ||
cdef constraints = [] | ||
cdef int i | ||
for i in range(nconss): | ||
constraints.append(getPyCons(conss[i])) | ||
solution = Solution.create(scip, sol) | ||
|
@@ -276,6 +285,7 @@ cdef SCIP_RETCODE PyConsEnfolp (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** | |
SCIP_Bool solinfeasible, SCIP_RESULT* result) noexcept with gil: | ||
PyConshdlr = getPyConshdlr(conshdlr) | ||
cdef constraints = [] | ||
cdef int i | ||
for i in range(nconss): | ||
constraints.append(getPyCons(conss[i])) | ||
result_dict = PyConshdlr.consenfolp(constraints, nusefulconss, solinfeasible) | ||
|
@@ -285,6 +295,7 @@ cdef SCIP_RETCODE PyConsEnfolp (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** | |
cdef SCIP_RETCODE PyConsEnforelax (SCIP* scip, SCIP_SOL* sol, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss, int nusefulconss, SCIP_Bool solinfeasible, SCIP_RESULT* result) noexcept with gil: | ||
PyConshdlr = getPyConshdlr(conshdlr) | ||
cdef constraints = [] | ||
cdef int i | ||
for i in range(nconss): | ||
constraints.append(getPyCons(conss[i])) | ||
solution = Solution.create(scip, sol) | ||
|
@@ -296,6 +307,7 @@ cdef SCIP_RETCODE PyConsEnfops (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** | |
SCIP_Bool solinfeasible, SCIP_Bool objinfeasible, SCIP_RESULT* result) noexcept with gil: | ||
PyConshdlr = getPyConshdlr(conshdlr) | ||
cdef constraints = [] | ||
cdef int i | ||
for i in range(nconss): | ||
constraints.append(getPyCons(conss[i])) | ||
result_dict = PyConshdlr.consenfops(constraints, nusefulconss, solinfeasible, objinfeasible) | ||
|
@@ -306,6 +318,7 @@ cdef SCIP_RETCODE PyConsCheck (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** | |
SCIP_Bool checklprows, SCIP_Bool printreason, SCIP_Bool completely, SCIP_RESULT* result) noexcept with gil: | ||
PyConshdlr = getPyConshdlr(conshdlr) | ||
cdef constraints = [] | ||
cdef int i | ||
for i in range(nconss): | ||
constraints.append(getPyCons(conss[i])) | ||
solution = Solution.create(scip, sol) | ||
|
@@ -317,6 +330,7 @@ cdef SCIP_RETCODE PyConsProp (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** c | |
SCIP_PROPTIMING proptiming, SCIP_RESULT* result) noexcept with gil: | ||
PyConshdlr = getPyConshdlr(conshdlr) | ||
cdef constraints = [] | ||
cdef int i | ||
for i in range(nconss): | ||
constraints.append(getPyCons(conss[i])) | ||
result_dict = PyConshdlr.consprop(constraints, nusefulconss, nmarkedconss, proptiming) | ||
|
@@ -330,6 +344,7 @@ cdef SCIP_RETCODE PyConsPresol (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** | |
int* ndelconss, int* naddconss, int* nupgdconss, int* nchgcoefs, int* nchgsides, SCIP_RESULT* result) noexcept with gil: | ||
PyConshdlr = getPyConshdlr(conshdlr) | ||
cdef constraints = [] | ||
cdef int i | ||
for i in range(nconss): | ||
constraints.append(getPyCons(conss[i])) | ||
# dictionary for input/output parameters | ||
|
@@ -403,6 +418,7 @@ cdef SCIP_RETCODE PyConsDisable (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS* | |
cdef SCIP_RETCODE PyConsDelvars (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS** conss, int nconss) noexcept with gil: | ||
PyConshdlr = getPyConshdlr(conshdlr) | ||
cdef constraints = [] | ||
cdef int i | ||
for i in range(nconss): | ||
constraints.append(getPyCons(conss[i])) | ||
PyConshdlr.consdelvars(constraints) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,7 +23,7 @@ cdef class Cutsel: | |
'''executed before the branch-and-bound process is freed''' | ||
pass | ||
|
||
def cutselselect(self, cuts, forcedcuts, root, maxnselectedcuts): | ||
def cutselselect(self, list[SCIP_ROW] cuts, int forcedcuts, SCIP_Bool root, int maxnselectedcuts): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess if we have def then the int means the Python int whereas SCIP_Bool is the C unsigned int, or am I wrong? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not entirely sure how this works, because in things like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe I am not aware of the Cython rules, but I find these type declarations confusing because
and since this should be a Python-callback, I would prefer if it is consistently supplied with Python-objects. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm also not sure about Cython, but I think there must be a definitive difference between this callback and a normal Python function. That's because using this sort of syntax (e.g. Type hints in Python would use the following syntax (and not be enforced, making them somewhat useless):
Further, in these callbacks, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess we're mixing type hints and variable type declarations here. |
||
'''first method called in each iteration in the main solving loop. ''' | ||
# this method needs to be implemented by the user | ||
return {} | ||
|
@@ -74,9 +74,10 @@ cdef SCIP_RETCODE PyCutselSelect (SCIP* scip, SCIP_CUTSEL* cutsel, SCIP_ROW** cu | |
int* nselectedcuts, SCIP_RESULT* result) noexcept with gil: | ||
cdef SCIP_CUTSELDATA* cutseldata | ||
cdef SCIP_ROW* scip_row | ||
cdef int i | ||
cutseldata = SCIPcutselGetData(cutsel) | ||
PyCutsel = <Cutsel>cutseldata | ||
|
||
# translate cuts to python | ||
pycuts = [Row.create(cuts[i]) for i in range(ncuts)] | ||
pyforcedcuts = [Row.create(forcedcuts[i]) for i in range(nforcedcuts)] | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are these methods not defined with cdef? I would say in the python world we should use bool and in the c world
SCIP_Bool
. So where are we here?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I said in the bigger comment, these functions should be accessible from the Python side, so we need to use
def
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But I guess to avoid confusion we should also use
bool
instead ofSCIP_Bool
and convert when entering the C world again.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SCIP_Bool
does not make sense here. The user should never have access to such a type and the type hint should simply bebool
(like Dominik suggested).Cython will handle the conversion or use a local declaration of
SCIP_Bool
inside of the function.