From c4cba7cede71c89651708a792efa6dd35762faa0 Mon Sep 17 00:00:00 2001 From: Chris Coey Date: Sat, 16 Dec 2023 12:08:40 +1000 Subject: [PATCH] remove `interval` and `NonNegative`, as these are better expressed with inequalities --- CHANGELOG.md | 2 +- src/json_to_moi.jl | 17 ++--------------- test/all_tests.jl | 3 --- test/inputs/abs_gap_out_of_range.json | 2 +- test/inputs/cons_false.json | 2 +- test/inputs/cons_true.json | 2 +- test/inputs/empty_arr_con.json | 2 +- test/inputs/incorrect_interval_num_params.json | 1 - test/inputs/min_constant.json | 2 +- test/inputs/min_interval.json | 1 - test/inputs/rel_gap_out_of_range.json | 2 +- test/inputs/simple_lp.json | 2 +- test/inputs/unsupported_con_sign.json | 2 +- test/inputs/unsupported_con_type.json | 2 +- test/inputs/unsupported_obj_type.json | 2 +- test/outputs/min_interval.json | 1 - 16 files changed, 13 insertions(+), 32 deletions(-) delete mode 100644 test/inputs/incorrect_interval_num_params.json delete mode 100644 test/inputs/min_interval.json delete mode 100644 test/outputs/min_interval.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ef6345..23fd2dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Make `options` field optional [#22](https://github.com/RelationalAI/SolverAPI.jl/pull/22) - Remove `names` field in results [#20](https://github.com/RelationalAI/SolverAPI.jl/pull/20) - Update format to use JSON vector for relational appl constraint - args [#21](https://github.com/RelationalAI/SolverAPI.jl/pull/21) + args [#21](https://github.com/RelationalAI/SolverAPI.jl/pull/21) ## [0.2.2] diff --git a/src/json_to_moi.jl b/src/json_to_moi.jl index 37644f4..e6bf8aa 100644 --- a/src/json_to_moi.jl +++ b/src/json_to_moi.jl @@ -51,10 +51,7 @@ function add_cons!( _check_v_type(v) MOI.add_constraint(model, v, MOI.ZeroOne()) elseif head == "Float" - elseif head == "Nonneg" - v = json_to_snf(a[2], vars_map) - _check_v_type(v) - MOI.add_constraint(model, v, MOI.GreaterThan(zero(T))) + # no-op elseif head == "PosNegOne" v = json_to_snf(a[2], vars_map) _check_v_type(v) @@ -62,16 +59,6 @@ function add_cons!( MOI.add_constraint(model, v, MOI.Integer()) f = MOI.ScalarNonlinearFunction(:abs, Any[v]) MOI.add_constraint(model, f, MOI.EqualTo(1)) - elseif head == "interval" - if length(a) != 4 - throw(Error(InvalidModel, "The `interval` constraint expects three arguments.")) - end - v = json_to_snf(a[4], vars_map) - _check_v_type(v) - if !(a[2] isa Number && a[3] isa Number) - throw(Error(InvalidModel, "The `interval` constraint expects number bounds.")) - end - MOI.add_constraint(model, v, MOI.Interval{T}(T(a[2]), T(a[3]))) elseif head == "range" if length(a) != 5 throw(Error(InvalidModel, "The `range` constraint expects four arguments.")) @@ -159,7 +146,7 @@ function add_cons!(::Type{<:Real}, ::MOI.ModelLike, a::A, ::Dict, ::Dict) where end _check_v_type(::MOI.VariableIndex) = nothing -_check_v_type(_) = +_check_v_type(v::Any) = throw(Error(InvalidModel, "$v must be a `MOI.VariableIndex`, not $(typeof(v)).")) ineq_to_moi = Dict(:<= => MOI.LessThan, :>= => MOI.GreaterThan, :(==) => MOI.EqualTo) diff --git a/test/all_tests.jl b/test/all_tests.jl index c92d83d..5ec2542 100644 --- a/test/all_tests.jl +++ b/test/all_tests.jl @@ -63,7 +63,6 @@ end # names of JSON files in inputs/ and outputs/ folders json_names = [ "feas_range", - "min_interval", "tiny_min", "tiny_feas", "tiny_infeas", @@ -132,8 +131,6 @@ end ("incorrect_range_num_params", "InvalidModel"), # range: step not one ("incorrect_range_step_not_1", "InvalidModel"), - # interval: wrong number of args - ("incorrect_interval_num_params", "InvalidModel"), # relational application constraint malformed ("in_con_malformed", "InvalidModel"), # unsupported objective function type diff --git a/test/inputs/abs_gap_out_of_range.json b/test/inputs/abs_gap_out_of_range.json index 3a2b7ba..3a1c9bc 100644 --- a/test/inputs/abs_gap_out_of_range.json +++ b/test/inputs/abs_gap_out_of_range.json @@ -1 +1 @@ -{"version":"0.1","sense":"min","variables":["x","y"],"constraints":[["and",["==",["+","x",["*",3,"y"]],1],[">=",["+","x","y"],1]],["and",["Int","x"],["Nonneg","x"]],["Int","y"]],"objectives":[["+",["*",2,"x"],"y"]],"options":{"solver":"HIGHS", "absolute_gap_tolerance":-0.1}} +{"version":"0.1","sense":"min","variables":["x","y"],"constraints":[["and",["==",["+","x",["*",3,"y"]],1],[">=",["+","x","y"],1]],["and",["Int","x"],[">=","x",0]],["Int","y"]],"objectives":[["+",["*",2,"x"],"y"]],"options":{"solver":"HIGHS", "absolute_gap_tolerance":-0.1}} diff --git a/test/inputs/cons_false.json b/test/inputs/cons_false.json index 30daea1..d341814 100644 --- a/test/inputs/cons_false.json +++ b/test/inputs/cons_false.json @@ -1 +1 @@ -{"version":"0.1","sense":"feas","variables":["x"],"constraints":[["==",1,0],["Nonneg","x"]],"objectives":[],"options":{"solver":"highs"}} +{"version":"0.1","sense":"feas","variables":["x"],"constraints":[["==",1,0],[">=","x",0]],"objectives":[],"options":{"solver":"highs"}} diff --git a/test/inputs/cons_true.json b/test/inputs/cons_true.json index ba8024a..c81a2e4 100644 --- a/test/inputs/cons_true.json +++ b/test/inputs/cons_true.json @@ -1 +1 @@ -{"version":"0.1","sense":"feas","variables":["x_1","x_2"],"constraints":[["==",0,0],["Nonneg","x_1"],["Nonneg","x_2"]],"objectives":[],"options":{"solver":"highs"}} +{"version":"0.1","sense":"feas","variables":["x_1","x_2"],"constraints":[["==",0,0],[">=","x_1",0],[">=","x_2",0]],"objectives":[],"options":{"solver":"highs"}} diff --git a/test/inputs/empty_arr_con.json b/test/inputs/empty_arr_con.json index 81c78ce..924734c 100644 --- a/test/inputs/empty_arr_con.json +++ b/test/inputs/empty_arr_con.json @@ -1 +1 @@ -{"version":"0.1","sense":"min","variables":["x","y"],"constraints":[[">=","x",1.5],[],["Nonneg","x"],["Nonneg","y"]],"objectives":[["+","x","y"]],"options":{"solver":"HiGHS"}} +{"version":"0.1","sense":"min","variables":["x","y"],"constraints":[[">=","x",1.5],[],[">=","x",0],[">=","y",0]],"objectives":[["+","x","y"]],"options":{"solver":"HiGHS"}} diff --git a/test/inputs/incorrect_interval_num_params.json b/test/inputs/incorrect_interval_num_params.json deleted file mode 100644 index d553b45..0000000 --- a/test/inputs/incorrect_interval_num_params.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"0.1","sense":"feas","variables":["x"],"constraints":[["interval",0,4,1,"x"],["Int","x"]],"objectives":[],"options":{"solver":"MiniZinc"}} diff --git a/test/inputs/min_constant.json b/test/inputs/min_constant.json index a132b5b..0798df3 100644 --- a/test/inputs/min_constant.json +++ b/test/inputs/min_constant.json @@ -1 +1 @@ -{"version":"0.1","sense":"min","variables":["x"],"constraints":[["==","x",1],["Int","x"]],"objectives":[1.5],"options":{"solver":"HiGHS"}} +{"version":"0.1","sense":"min","variables":["x"],"constraints":[["==","x",1],["Bin","x"]],"objectives":[1.5],"options":{"solver":"HiGHS"}} diff --git a/test/inputs/min_interval.json b/test/inputs/min_interval.json deleted file mode 100644 index f2238aa..0000000 --- a/test/inputs/min_interval.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"0.1","sense":"min","variables":["x"],"constraints":[["interval",1,3.5,"x"],["Float","x"]],"objectives":["x"],"options":{"time_limit_sec":60,"solver":"HiGHS","silent":0,"print_format":"MOI"}} diff --git a/test/inputs/rel_gap_out_of_range.json b/test/inputs/rel_gap_out_of_range.json index afad52b..d239c93 100644 --- a/test/inputs/rel_gap_out_of_range.json +++ b/test/inputs/rel_gap_out_of_range.json @@ -1 +1 @@ -{"version":"0.1","sense":"min","variables":["x","y"],"constraints":[["and",["==",["+","x",["*",3,"y"]],1],[">=",["+","x","y"],1]],["and",["Int","x"],["Nonneg","x"]],["Int","y"]],"objectives":[["+",["*",2,"x"],"y"]],"options":{"solver":"HIGHS", "relative_gap_tolerance":1.1}} +{"version":"0.1","sense":"min","variables":["x","y"],"constraints":[["and",["==",["+","x",["*",3,"y"]],1],[">=",["+","x","y"],1]],["and",["Int","x"],[">=","x",0]],["Int","y"]],"objectives":[["+",["*",2,"x"],"y"]],"options":{"solver":"HIGHS", "relative_gap_tolerance":1.1}} diff --git a/test/inputs/simple_lp.json b/test/inputs/simple_lp.json index 7ffd886..d3e3606 100644 --- a/test/inputs/simple_lp.json +++ b/test/inputs/simple_lp.json @@ -1 +1 @@ -{"version":"0.1","sense":"min","variables":["x","y"],"constraints":[["and",["==",["+","x",["*",3,"y"]],1],[">=",["+","x","y"],1]],["and",["Int","x"],["Nonneg","x"]],["Int","y"]],"objectives":[["+",["*",2,"x"],"y"]],"options":{"solver":"HiGHS"}} +{"version":"0.1","sense":"min","variables":["x","y"],"constraints":[["and",["==",["+","x",["*",3,"y"]],1],[">=",["+","x","y"],1]],["and",["Int","x"],[">=","x",0]],["Bin","y"]],"objectives":[["+",["*",2,"x"],"y"]],"options":{"solver":"HiGHS"}} diff --git a/test/inputs/unsupported_con_sign.json b/test/inputs/unsupported_con_sign.json index e079ddc..bc11cc0 100644 --- a/test/inputs/unsupported_con_sign.json +++ b/test/inputs/unsupported_con_sign.json @@ -1 +1 @@ -{"version":"0.1","sense":"min","variables":["x","y"],"constraints":[["and",["!=",["+","x",["*",3,"y"]],1],[">=",["+","x","y"],1]],["and",["Int","x"],["Nonneg","x"]],["Int","y"]],"objectives":[["+",["*",2,"x"],"y"]],"options":{"solver":"HiGHS"}} +{"version":"0.1","sense":"min","variables":["x","y"],"constraints":[["and",["!=",["+","x",["*",3,"y"]],1],[">=",["+","x","y"],1]],["and",["Int","x"],[">=","x",0]],["Int","y"]],"objectives":[["+",["*",2,"x"],"y"]],"options":{"solver":"HiGHS"}} diff --git a/test/inputs/unsupported_con_type.json b/test/inputs/unsupported_con_type.json index ea6dd3a..9a4fc70 100644 --- a/test/inputs/unsupported_con_type.json +++ b/test/inputs/unsupported_con_type.json @@ -1 +1 @@ -{"version":"0.1","sense":"min","variables":["x","y"],"constraints":[["and",["==",["*","x",["*","x","y"]],1],[">=",["+","x","y"],1]],["and",["Int","x"],["Nonneg","x"]],["Int","y"]],"objectives":[["+",["*",2,"x"],"y"]],"options":{"solver":"HiGHS"}} +{"version":"0.1","sense":"min","variables":["x","y"],"constraints":[["and",["==",["*","x",["*","x","y"]],1],[">=",["+","x","y"],1]],["and",["Int","x"],[">=","x",0]],["Int","y"]],"objectives":[["+",["*",2,"x"],"y"]],"options":{"solver":"HiGHS"}} diff --git a/test/inputs/unsupported_obj_type.json b/test/inputs/unsupported_obj_type.json index 8b07678..9ce2c57 100644 --- a/test/inputs/unsupported_obj_type.json +++ b/test/inputs/unsupported_obj_type.json @@ -1 +1 @@ -{"version":"0.1","sense":"min","variables":["x","y"],"constraints":[["and",["==",["+","x",["*",3,"y"]],1],[">=",["+","x","y"],1]],["and",["Int","x"],["Nonneg","x"]],["Int","y"]],"objectives":[["/",["*",2,"x"],"y"]],"options":{"solver":"HiGHS"}} +{"version":"0.1","sense":"min","variables":["x","y"],"constraints":[["and",["==",["+","x",["*",3,"y"]],1],[">=",["+","x","y"],1]],["and",["Int","x"],[">=","x",0]],["Int","y"]],"objectives":[["/",["*",2,"x"],"y"]],"options":{"solver":"HiGHS"}} diff --git a/test/outputs/min_interval.json b/test/outputs/min_interval.json deleted file mode 100644 index d384ad3..0000000 --- a/test/outputs/min_interval.json +++ /dev/null @@ -1 +0,0 @@ -{"model_string":"Minimize: x\n\nSubject to:\n x ∈ [1, 3.5]\n","termination_status":"OPTIMAL","names":["\"x\""],"results":[{"values":[1.0],"primal_status":"FEASIBLE_POINT","objective_value":1.0}],"version":"0.1"}