diff --git a/.gitignore b/.gitignore index 8f93571d..1611edc7 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ docs/build +Manifest.toml diff --git a/.travis.yml b/.travis.yml index 169b3702..5d91e1b1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,23 +1,22 @@ language: julia +codecov: true os: - linux - osx julia: - 1.0 - - 1.4 -script: - - julia --project -e 'import Pkg; Pkg.build(); Pkg.instantiate()' - - julia --project -e 'import Pkg; Pkg.test(coverage=true);' -after_success: - - julia -e 'import Pkg; Pkg.add("Coverage"); using Coverage; Codecov.submit(process_folder())' + - 1 +before_script: + - julia -e 'using Pkg; Pkg.add(PackageSpec(name="Pavito", rev="master"))' # TODO remove when Pavito#master is released. jobs: allow_failures: - julia: nightly include: - stage: "Documentation" - julia: 1.4 + julia: 1 os: linux script: + - julia -e 'using Pkg; Pkg.rm("Pavito")' # TODO Pkg seems to get into troubles because of the `before_script`. Remove when Pavito#master is released. - julia --project=docs/ -e 'using Pkg; Pkg.instantiate(); Pkg.develop(PackageSpec(path=pwd()))' - julia --project=docs/ docs/make.jl after_success: skip diff --git a/Project.toml b/Project.toml index 96a620fd..b3b03f79 100644 --- a/Project.toml +++ b/Project.toml @@ -7,28 +7,27 @@ version = "0.1.16" Distributed = "8ba89e20-285c-5b6f-9357-94700520ee1b" JuMP = "4076af6c-e467-56ae-b986-b466b2749572" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" -MathProgBase = "fdba3010-5040-5b88-9595-932c9decdf73" +MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee" Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" [compat] -Cbc = "0.6.7" -GLPKMathProgInterface = ">=0.4.3" -Ipopt = ">= 0.4" -JuMP = "< 0.19" -MathProgBase = ">=0.6.4" -Pavito = "^0.1" +Cbc = "0.7" +Ipopt = "0.6" +JuMP = "0.21" +MathOptInterface = "0.9.14" julia = "^1" [extras] Cbc = "9961bab8-2fa3-5c5a-9d89-47fab24efd76" -GLPKMathProgInterface = "3c7084bd-78ad-589a-b5bb-dbd673274bea" +GLPK = "60bf3e95-4087-53dc-ae20-288a0d20c6a6" Ipopt = "b6b21f68-93f8-5de0-b562-5493be1d77c9" +Juniper = "2ddba703-00a4-53a7-87a5-e8b9971dde84" Pavito = "cd433a01-47d1-575d-afb7-6db927ee8d8f" Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [targets] -test = ["Cbc", "GLPKMathProgInterface", "Ipopt", "Pavito", "Pkg", "Test"] +test = ["Cbc", "GLPK", "Ipopt", "Juniper", "Pavito", "Pkg", "Test"] diff --git a/docs/Manifest.toml b/docs/Manifest.toml deleted file mode 100644 index eaf2ceac..00000000 --- a/docs/Manifest.toml +++ /dev/null @@ -1,216 +0,0 @@ -[[Alpine]] -deps = ["Distributed", "JuMP", "LinearAlgebra", "MathProgBase", "Printf", "Random", "SparseArrays", "Statistics"] -path = "/Users/harsha/.julia/dev/Alpine" -uuid = "07493b3f-dabb-5b16-a503-4139292d7dd4" -version = "0.1.15" - -[[Base64]] -uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" - -[[BinDeps]] -deps = ["Libdl", "Pkg", "SHA", "URIParser", "Unicode"] -git-tree-sha1 = "46cf2c1668ad07aba5a9d331bdeea994a1f13856" -uuid = "9e28174c-4ba2-5203-b857-d8d62c4213ee" -version = "1.0.1" - -[[BinaryProvider]] -deps = ["Libdl", "Logging", "SHA"] -git-tree-sha1 = "ecdec412a9abc8db54c0efc5548c64dfce072058" -uuid = "b99e7846-7c00-51b0-8f62-c81ae34c0232" -version = "0.5.10" - -[[Calculus]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "f641eb0a4f00c343bbc32346e1217b86f3ce9dad" -uuid = "49dc2e85-a5d0-5ad3-a950-438e2897f1b9" -version = "0.5.1" - -[[CommonSubexpressions]] -deps = ["Test"] -git-tree-sha1 = "efdaf19ab11c7889334ca247ff4c9f7c322817b0" -uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" -version = "0.2.0" - -[[Compat]] -deps = ["Base64", "Dates", "DelimitedFiles", "Distributed", "InteractiveUtils", "LibGit2", "Libdl", "LinearAlgebra", "Markdown", "Mmap", "Pkg", "Printf", "REPL", "Random", "Serialization", "SharedArrays", "Sockets", "SparseArrays", "Statistics", "Test", "UUIDs", "Unicode"] -git-tree-sha1 = "ed2c4abadf84c53d9e58510b5fc48912c2336fbb" -uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" -version = "2.2.0" - -[[DataStructures]] -deps = ["InteractiveUtils", "OrderedCollections"] -git-tree-sha1 = "be680f1ad03c0a03796aa3fda5a2180df7f83b46" -uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.17.18" - -[[Dates]] -deps = ["Printf"] -uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" - -[[DelimitedFiles]] -deps = ["Mmap"] -uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" - -[[DiffResults]] -deps = ["StaticArrays"] -git-tree-sha1 = "da24935df8e0c6cf28de340b958f6aac88eaa0cc" -uuid = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" -version = "1.0.2" - -[[DiffRules]] -deps = ["NaNMath", "Random", "SpecialFunctions"] -git-tree-sha1 = "eb0c34204c8410888844ada5359ac8b96292cfd1" -uuid = "b552c78f-8df3-52c6-915a-8e097449b14b" -version = "1.0.1" - -[[Distributed]] -deps = ["LinearAlgebra", "Random", "Serialization", "Sockets"] -uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" - -[[DocStringExtensions]] -deps = ["LibGit2", "Markdown", "Pkg", "Test"] -git-tree-sha1 = "c5714d9bcdba66389612dc4c47ed827c64112997" -uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" -version = "0.8.2" - -[[Documenter]] -deps = ["Base64", "Dates", "DocStringExtensions", "InteractiveUtils", "JSON", "LibGit2", "Logging", "Markdown", "REPL", "Test", "Unicode"] -git-tree-sha1 = "395fa1554c69735802bba37d9e7d9586fd44326c" -uuid = "e30172f5-a6a5-5a46-863b-614d45cd2de4" -version = "0.24.11" - -[[ForwardDiff]] -deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "NaNMath", "Random", "SpecialFunctions", "StaticArrays"] -git-tree-sha1 = "869540e4367122fbffaace383a5bdc34d6e5e5ac" -uuid = "f6369f11-7733-5829-9624-2563aa707210" -version = "0.10.10" - -[[InteractiveUtils]] -deps = ["LinearAlgebra", "Markdown"] -uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" - -[[JSON]] -deps = ["Dates", "Mmap", "Parsers", "Unicode"] -git-tree-sha1 = "b34d7cef7b337321e97d22242c3c2b91f476748e" -uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" -version = "0.21.0" - -[[JuMP]] -deps = ["Calculus", "Compat", "ForwardDiff", "MathProgBase", "ReverseDiffSparse"] -git-tree-sha1 = "8e1aea93f99e1141a8053e1d542d4534f62fe43f" -uuid = "4076af6c-e467-56ae-b986-b466b2749572" -version = "0.18.6" - -[[LibGit2]] -uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" - -[[Libdl]] -uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" - -[[LinearAlgebra]] -deps = ["Libdl"] -uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" - -[[Logging]] -uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" - -[[Markdown]] -deps = ["Base64"] -uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" - -[[MathProgBase]] -deps = ["LinearAlgebra", "SparseArrays"] -git-tree-sha1 = "9abbe463a1e9fc507f12a69e7f29346c2cdc472c" -uuid = "fdba3010-5040-5b88-9595-932c9decdf73" -version = "0.7.8" - -[[Mmap]] -uuid = "a63ad114-7e13-5084-954f-fe012c677804" - -[[NaNMath]] -git-tree-sha1 = "928b8ca9b2791081dc71a51c55347c27c618760f" -uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" -version = "0.3.3" - -[[OrderedCollections]] -git-tree-sha1 = "12ce190210d278e12644bcadf5b21cbdcf225cd3" -uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" -version = "1.2.0" - -[[Parsers]] -deps = ["Dates", "Test"] -git-tree-sha1 = "eb3e09940c0d7ae01b01d9291ebad7b081c844d3" -uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" -version = "1.0.5" - -[[Pkg]] -deps = ["Dates", "LibGit2", "Markdown", "Printf", "REPL", "Random", "SHA", "UUIDs"] -uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" - -[[Printf]] -deps = ["Unicode"] -uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" - -[[REPL]] -deps = ["InteractiveUtils", "Markdown", "Sockets"] -uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" - -[[Random]] -deps = ["Serialization"] -uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" - -[[ReverseDiffSparse]] -deps = ["Calculus", "Compat", "DataStructures", "ForwardDiff", "MathProgBase", "NaNMath"] -git-tree-sha1 = "cbbc2c710abea5cfe71459ce4711d80a212aac5a" -uuid = "89212889-6d3f-5f97-b412-7825138f6c9c" -version = "0.8.6" - -[[SHA]] -uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" - -[[Serialization]] -uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" - -[[SharedArrays]] -deps = ["Distributed", "Mmap", "Random", "Serialization"] -uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" - -[[Sockets]] -uuid = "6462fe0b-24de-5631-8697-dd941f90decc" - -[[SparseArrays]] -deps = ["LinearAlgebra", "Random"] -uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" - -[[SpecialFunctions]] -deps = ["BinDeps", "BinaryProvider", "Libdl"] -git-tree-sha1 = "3bdd374b6fd78faf0119b8c5d538788dbf910c6e" -uuid = "276daf66-3868-5448-9aa4-cd146d93841b" -version = "0.8.0" - -[[StaticArrays]] -deps = ["LinearAlgebra", "Random", "Statistics"] -git-tree-sha1 = "5c06c0aeb81bef54aed4b3f446847905eb6cbda0" -uuid = "90137ffa-7385-5640-81b9-e52037218182" -version = "0.12.3" - -[[Statistics]] -deps = ["LinearAlgebra", "SparseArrays"] -uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" - -[[Test]] -deps = ["Distributed", "InteractiveUtils", "Logging", "Random"] -uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" - -[[URIParser]] -deps = ["Unicode"] -git-tree-sha1 = "53a9f49546b8d2dd2e688d216421d050c9a31d0d" -uuid = "30578b45-9adc-5946-b283-645ec420af67" -version = "0.4.1" - -[[UUIDs]] -deps = ["Random"] -uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" - -[[Unicode]] -uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" diff --git a/docs/src/choosingsolver.md b/docs/src/choosingsolver.md index 1951af61..67619582 100644 --- a/docs/src/choosingsolver.md +++ b/docs/src/choosingsolver.md @@ -25,5 +25,5 @@ To use different sub-solvers, here is an example: using Gurobi, Ipopt m = Model() # Here goes the building of your model... - setsolver(m, AlpineSolver(nlp_solver=IpoptSolver(print_level=0), mip_solver=GurobiSolver(OutputFlag=0))) + setsolver(m, Alpine.Optimizer(nlp_solver=IpoptSolver(print_level=0), mip_solver=GurobiSolver(OutputFlag=0))) ``` diff --git a/src/Alpine.jl b/src/Alpine.jl index 46788fbb..59707f4e 100644 --- a/src/Alpine.jl +++ b/src/Alpine.jl @@ -5,8 +5,6 @@ module Alpine const ALPINE_DEBUG = false using JuMP -using MathProgBase - using LinearAlgebra using Random @@ -18,8 +16,9 @@ using SparseArrays include("const.jl") # Engine for High-level Algorithmic Control and User-interface +include("matrix_opt_interface.jl") +include("moi_function2expr.jl") include("solver.jl") -include("mpb2moi.jl") # Transition file # Engine for expression handling include("nlexpr.jl") diff --git a/src/algorithm.jl b/src/algorithm.jl index 2097dd69..acd77c54 100644 --- a/src/algorithm.jl +++ b/src/algorithm.jl @@ -1,21 +1,34 @@ +const STATUS_LIMIT = [ + MOI.ITERATION_LIMIT, MOI.TIME_LIMIT, MOI.NODE_LIMIT, + MOI.SOLUTION_LIMIT, MOI.MEMORY_LIMIT, MOI.OBJECTIVE_LIMIT, + MOI.NORM_LIMIT, MOI.OTHER_LIMIT +] +const STATUS_OPT = [ + MOI.OPTIMAL, MOI.LOCALLY_SOLVED, MOI.ALMOST_OPTIMAL +] +const STATUS_INF = [ + MOI.INFEASIBLE, MOI.LOCALLY_INFEASIBLE +] + """ High-level Function """ -function MathProgBase.optimize!(m::AlpineNonlinearModel) - if m.presolve_infeasible - summary_status(m) - return - end - presolve(m) - global_solve(m) - m.loglevel > 0 && logging_row_entry(m, finish_entry=true) - println("====================================================================================================") - summary_status(m) - return +function MOI.optimize!(m::Optimizer) + load!(m) + if getproperty(m, :presolve_infeasible) + summary_status(m) + return + end + presolve(m) + global_solve(m) + get_option(m, :loglevel) > 0 && logging_row_entry(m, finish_entry=true) + println("====================================================================================================") + summary_status(m) + return end """ -global_solve(m::AlpineNonlinearModel) +global_solve(m::Optimizer) Perform global optimization algorithm that is based on the adaptive piecewise convexification. This iterative algorithm loops over [`bounding_solve`](@ref) and [`local_solve`](@ref) until the optimality gap between the lower bound (relaxed problem with min. objective) and the upper bound (feasible problem) is within the user prescribed limits. @@ -23,10 +36,10 @@ Each [`bounding_solve`](@ref) provides a lower bound that serves as the partitio Each [`local_solve`](@ref) provides an incumbent feasible solution. The algorithm terminates when atleast one of these conditions are satisfied: time limit, optimality condition, or iteration limit. """ -function global_solve(m::AlpineNonlinearModel) +function global_solve(m::Optimizer) - m.loglevel > 0 && logging_head(m) - m.presolve_track_time || reset_timer(m) + get_option(m, :loglevel) > 0 && logging_head(m) + get_option(m, :presolve_track_time) || reset_timer(m) while !check_exit(m) m.logs[:n_iter] += 1 @@ -34,7 +47,7 @@ function global_solve(m::AlpineNonlinearModel) bounding_solve(m) # Solve the relaxation model update_opt_gap(m) # Update optimality gap check_exit(m) && break # Feasibility check - m.loglevel > 0 && logging_row_entry(m) # Logging + get_option(m, :loglevel) > 0 && logging_row_entry(m) # Logging local_solve(m) # Solve local model for feasible solution update_opt_gap(m) # Update optimality gap check_exit(m) && break # Detect optimality termination @@ -45,16 +58,16 @@ function global_solve(m::AlpineNonlinearModel) return end -function run_bounding_iteration(m::AlpineNonlinearModel) - m.loglevel > 0 && logging_head(m) - m.presolve_track_time || reset_timer(m) +function run_bounding_iteration(m::Optimizer) + get_option(m, :loglevel) > 0 && logging_head(m) + get_option(m, :presolve_track_time) || reset_timer(m) m.logs[:n_iter] += 1 create_bounding_mip(m) # Build the relaxation model bounding_solve(m) # Solve the relaxation model update_opt_gap(m) # Update optimality gap check_exit(m) && return # Feasibility check - m.loglevel > 0 && logging_row_entry(m) # Logging + get_option(m, :loglevel) > 0 && logging_row_entry(m) # Logging local_solve(m) # Solve local model for feasible solution update_opt_gap(m) # Update optimality gap check_exit(m) && return # Detect optimality termination @@ -63,37 +76,35 @@ function run_bounding_iteration(m::AlpineNonlinearModel) return -end +end """ -presolve(m::AlpineNonlinearModel) +presolve(m::Optimizer) """ -function presolve(m::AlpineNonlinearModel) +function presolve(m::Optimizer) start_presolve = time() - m.loglevel > 0 && printstyled("PRESOLVE \n", color=:cyan) - m.loglevel > 0 && println(" Doing local search") + get_option(m, :loglevel) > 0 && printstyled("PRESOLVE \n", color=:cyan) + get_option(m, :loglevel) > 0 && println(" Doing local search") local_solve(m, presolve = true) # Solver status - returns error when see different - status_pass = [:Optimal, :Suboptimal, :UserLimit, :LocalOptimal] - status_reroute = [:Infeasible, :Infeasibles] - if m.status[:local_solve] in status_pass - m.loglevel > 0 && println(" Local solver returns a feasible point") + if m.status[:local_solve] in STATUS_OPT || m.status[:local_solve] in STATUS_LIMIT + get_option(m, :loglevel) > 0 && println(" Local solver returns a feasible point") bound_tightening(m, use_bound = true) # performs bound-tightening with the local solve objective value - m.presolve_bt && init_disc(m) # Re-initialize discretization dictionary on tight bounds - m.disc_ratio_branch && (m.disc_ratio = update_disc_ratio(m, true)) + get_option(m, :presolve_bt) && init_disc(m) # Re-initialize discretization dictionary on tight bounds + get_option(m, :disc_ratio_branch) && (set_option(m, :disc_ratio, update_disc_ratio(m, true))) add_partition(m, use_solution=m.best_sol) # Setting up the initial discretization - # m.loglevel > 0 && println("Ending the presolve") - elseif m.status[:local_solve] in status_reroute - (m.loglevel > 0) && println(" Bound tightening without objective bounds (OBBT)") + # get_option(m, :loglevel) > 0 && println("Ending the presolve") + elseif m.status[:local_solve] in STATUS_INF + (get_option(m, :loglevel) > 0) && println(" Bound tightening without objective bounds (OBBT)") bound_tightening(m, use_bound = false) # do bound tightening without objective value - (m.disc_ratio_branch) && (m.disc_ratio = update_disc_ratio(m)) - m.presolve_bt && init_disc(m) - # m.loglevel > 0 && println("Ending the presolve") - elseif m.status[:local_solve] == :Not_Enough_Degrees_Of_Freedom - @warn " Warning: Presolve ends with local solver yielding $(m.status[:local_solve]). \n Consider more replace equality constraints with >= and <= to resolve this." + (get_option(m, :disc_ratio_branch)) && (set_option(m, :disc_ratio, update_disc_ratio(m, true))) + get_option(m, :presolve_bt) && init_disc(m) + # get_option(m, :loglevel) > 0 && println("Ending the presolve") + elseif m.status[:local_solve] == MOI.INVALID_MODEL + @warn " Warning: Presolve ends with local solver yielding $(m.status[:local_solve]). \n This may come from Ipopt's `:Not_Enough_Degrees_Of_Freedom`. \n Consider more replace equality constraints with >= and <= to resolve this." else @warn " Warning: Presolve ends with local solver yielding $(m.status[:local_solve])." end @@ -102,21 +113,21 @@ function presolve(m::AlpineNonlinearModel) m.logs[:presolve_time] += cputime_presolve m.logs[:total_time] = m.logs[:presolve_time] m.logs[:time_left] -= m.logs[:presolve_time] - # (m.loglevel > 0) && println("Presolve time = $(round.(m.logs[:total_time]; digits=2))s") - (m.loglevel > 0) && println(" Completed presolve in $(round.(m.logs[:total_time]; digits=2))s ($(m.logs[:bt_iter]) iterations).") + # (get_option(m, :loglevel) > 0) && println("Presolve time = $(round.(m.logs[:total_time]; digits=2))s") + (get_option(m, :loglevel) > 0) && println(" Completed presolve in $(round.(m.logs[:total_time]; digits=2))s ($(m.logs[:bt_iter]) iterations).") return end """ A wrapper function that collects some automated solver adjustments within the main while loop. """ -function algorithm_automation(m::AlpineNonlinearModel) +function algorithm_automation(m::Optimizer) - m.disc_var_pick == 3 && update_disc_cont_var(m) - m.int_cumulative_disc && update_disc_int_var(m) + get_option(m, :disc_var_pick) == 3 && update_disc_cont_var(m) + get_option(m, :int_cumulative_disc) && update_disc_int_var(m) - if m.disc_ratio_branch - m.disc_ratio = update_disc_ratio(m) # Only perform for a maximum three times + if get_option(m, :disc_ratio_branch) + set_option(m, :disc_ratio, update_disc_ratio(m, true)) # Only perform for a maximum three times end return @@ -125,61 +136,93 @@ end """ Summarized function to determine whether to interrupt the main while loop. """ -function check_exit(m::AlpineNonlinearModel) +function check_exit(m::Optimizer) # constant objective with feasible local solve check - if expr_isconst(m.obj_expr_orig) && (m.status[:local_solve] == :Optimal) + if expr_isconst(m.obj_expr_orig) && (m.status[:local_solve] == MOI.OPTIMAL || m.status == MOI.LOCALLY_SOLVED) m.best_bound = eval(m.obj_expr_orig) m.best_rel_gap = 0.0 m.best_abs_gap = 0.0 - m.status[:bounding_solve] = :Optimal + m.status[:bounding_solve] = MOI.OPTIMAL m.alpine_status = :Optimal - m.status[:bound] = :Detected + m.detected_bound = true return true - end + end # Infeasibility check - m.status[:bounding_solve] == :Infeasible && return true + m.status[:bounding_solve] == MOI.INFEASIBLE && return true # Unbounded check - m.status[:bounding_solve] == :Unbounded && return true + m.status[:bounding_solve] == MOI.DUAL_INFEASIBLE && return true # Optimality check - m.best_rel_gap <= m.relgap && return true - m.logs[:n_iter] >= m.maxiter && return true - m.best_abs_gap <= m.absgap && return true + m.best_rel_gap <= get_option(m, :relgap) && return true + m.logs[:n_iter] >= get_option(m, :maxiter) && return true + m.best_abs_gap <= get_option(m, :absgap) && return true # Userlimits check - m.logs[:time_left] < m.tol && return true + m.logs[:time_left] < get_option(m, :tol) && return true return false end +function load_nonlinear_model(m::Optimizer, model::MOI.ModelLike, l_var, u_var) + x = MOI.add_variables(model, m.num_var_orig) + for i in eachindex(x) + set = _bound_set(l_var[i], u_var[i]) + if set !== nothing + fx = MOI.SingleVariable(x[i]) + MOI.add_constraint(model, fx, set) + end + end + for (func, set) in m.lin_quad_constraints + MOI.add_constraint(model, func, set) + end + MOI.set(model, MOI.ObjectiveSense(), m.sense_orig) + if m.objective_function !== nothing + MOI.set(model, MOI.ObjectiveFunction{typeof(m.objective_function)}(), m.objective_function) + end + block = MOI.NLPBlockData(m.nonlinear_constraint_bounds_orig, m.d_orig, m.has_nlp_objective) + MOI.set(model, MOI.NLPBlock(), block) + return x +end +function set_variable_type(model::MOI.ModelLike, xs, variable_types) + for (x, variable_type) in zip(xs, variable_types) + fx = MOI.SingleVariable(x) + if variable_type == :Int + MOI.add_constraint(model, fx, MOI.Integer()) + elseif variable_type == :Bin + MOI.add_constraint(model, fx, MOI.ZeroOne()) + else + @assert variable_type == :Cont + end + end +end + """ -local_solve(m::AlpineNonlinearModel, presolve::Bool=false) +local_solve(m::Optimizer, presolve::Bool=false) Perform a local NLP or MINLP solve to obtain a feasible solution. The `presolve` option is set to `true` when the function is invoked in [`presolve`](@ref). Otherwise, the function is invoked from [`bounding_solve`](@ref). """ -function local_solve(m::AlpineNonlinearModel; presolve = false) +function local_solve(m::Optimizer; presolve = false) - convertor = Dict(:Max=>:>, :Min=>:<) + convertor = Dict(MOI.MAX_SENSE => :>, MOI.MIN_SENSE => :<) local_nlp_status = :Unknown - do_heuristic = false var_type_screener = [i for i in m.var_type_orig if i in [:Bin, :Int]] if presolve - if !isempty(var_type_screener) && m.minlp_solver != UnsetSolver() - local_solve_model = interface_init_nonlinear_model(m.minlp_solver) + if !isempty(var_type_screener) && get_option(m, :minlp_solver) !== nothing + local_solve_model = MOI.instantiate(get_option(m, :minlp_solver), with_bridge_type=Float64) elseif !isempty(var_type_screener) - local_solve_model = interface_init_nonlinear_model(m.nlp_solver) + local_solve_model = MOI.instantiate(get_option(m, :nlp_solver), with_bridge_type=Float64) else - local_solve_model = interface_init_nonlinear_model(m.nlp_solver) + local_solve_model = MOI.instantiate(get_option(m, :nlp_solver), with_bridge_type=Float64) end else - local_solve_model = interface_init_nonlinear_model(m.nlp_solver) + local_solve_model = MOI.instantiate(get_option(m, :nlp_solver), with_bridge_type=Float64) end if presolve == false @@ -189,72 +232,63 @@ function local_solve(m::AlpineNonlinearModel; presolve = false) end start_local_solve = time() - interface_load_nonlinear_model(m, local_solve_model, l_var, u_var) - (!m.d_orig.want_hess) && interface_init_nonlinear_data(m.d_orig) + x = load_nonlinear_model(m, local_solve_model, l_var, u_var) + (!m.d_orig.want_hess) && MOI.initialize(m.d_orig, [:Grad, :Jac, :Hess, :HessVec, :ExprGraph]) # Safety scheme for sub-solvers re-initializing the NLPEvaluator - if presolve == false - interface_set_warmstart(local_solve_model, m.best_sol[1:m.num_var_orig]) + if !presolve + warmval = m.best_sol[1:m.num_var_orig] else - initial_warmval = Float64[] - for i in 1:m.num_var_orig - isnan(m.d_orig.m.colVal[i]) ? push!(initial_warmval, 0.0) : push!(initial_warmval, m.d_orig.m.colVal[i]) - end - interface_set_warmstart(local_solve_model, initial_warmval) + warmval = m.initial_warmval[1:m.num_var_orig] end + MOI.set(local_solve_model, MOI.VariablePrimalStart(), x, warmval) + do_heuristic = false # The only case when MINLP solver is actually used if presolve && !isempty(var_type_screener) - m.minlp_solver == UnsetSolver() || interface_set_vartype(local_solve_model, m.var_type_orig) - interface_optimize(local_solve_model) - if m.minlp_solver == UnsetSolver() + if get_option(m, :minlp_solver) === nothing do_heuristic = true - local_nlp_status = :Heuristics else - local_nlp_status = interface_get_status(local_solve_model) - do_heuristic = false + set_variable_type(local_solve_model, x, m.var_type_orig) end - else - interface_optimize(local_solve_model) - local_nlp_status = interface_get_status(local_solve_model) + end + MOI.optimize!(local_solve_model) + if !do_heuristic + local_nlp_status = MOI.get(local_solve_model, MOI.TerminationStatus()) end cputime_local_solve = time() - start_local_solve m.logs[:total_time] += cputime_local_solve - m.logs[:time_left] = max(0.0, m.timeout - m.logs[:total_time]) + m.logs[:time_left] = max(0.0, get_option(m, :timeout) - m.logs[:total_time]) - status_pass = [:Optimal, :Suboptimal, :UserLimit, :LocalOptimal] - status_heuristic = [:Heuristics] - status_reroute = [:Infeasible, :Infeasibles] - - if local_nlp_status in status_pass - candidate_obj = interface_get_objval(local_solve_model) - candidate_sol = round.(interface_get_solution(local_solve_model); digits=5) + if do_heuristic + m.status[:local_solve] = heu_basic_rounding(m, MOI.get(local_solve_model, MOI.VariablePrimal(), x)) + return + elseif local_nlp_status in STATUS_OPT || local_nlp_status in STATUS_LIMIT + candidate_obj = MOI.get(local_solve_model, MOI.ObjectiveValue()) + candidate_sol = round.(MOI.get(local_solve_model, MOI.VariablePrimal(), x); digits=5) update_incumb_objective(m, candidate_obj, candidate_sol) m.status[:local_solve] = local_nlp_status return - elseif local_nlp_status in status_heuristic && do_heuristic - m.status[:local_solve] = heu_basic_rounding(m, local_solve_model) - return - elseif local_nlp_status == :Infeasible - heu_pool_multistart(m) == :LocalOptimal && return + elseif local_nlp_status in STATUS_INF + heu_pool_multistart(m) == MOI.LOCALLY_SOLVED && return push!(m.logs[:obj], "INF") - m.status[:local_solve] = :Infeasible + m.status[:local_solve] = MOI.LOCALLY_INFEASIBLE return - elseif local_nlp_status == :Unbounded + elseif local_nlp_status == MOI.DUAL_INFEASIBLE push!(m.logs[:obj], "U") - m.status[:local_solve] = :Unbounded - if presolve == true - @warn " Warning: NLP local solve is unbounded." - else - @warn " Warning: NLP local solve is unbounded." + m.status[:local_solve] = MOI.DUAL_INFEASIBLE + if presolve + @warn " Warning: NLP local solve is unbounded." + else + @warn " Warning: NLP local solve is unbounded." end return else push!(m.logs[:obj], "E") - m.status[:local_solve] = :Error - if presolve == true - @warn " Warning: NLP solve failure $(local_nlp_status)." - else + m.status[:local_solve] = MOI.OTHER_ERROR + if presolve + @warn " Warning: NLP solve failure $(local_nlp_status)." + else @warn " Warning: NLP local solve failure." end return @@ -266,7 +300,7 @@ end """ -bounding_solve(m::AlpineNonlinearModel; kwargs...) +bounding_solve(m::Optimizer; kwargs...) This process usually deals with a MILP or a MIQCP/MIQCQP problem for lower bounding the given problem. It solves the problem built upon a convexification base on a discretization Dictionary of some variables. @@ -274,49 +308,45 @@ The convexification utilized is Tighten McCormick scheme. See `create_bounding_mip` for more details of the problem solved here. """ -function bounding_solve(m::AlpineNonlinearModel) +function bounding_solve(m::Optimizer) - convertor = Dict(:Max=>:<, :Min=>:>) - boundlocator = Dict(:Max=>:+, :Min=>:-) - boundlocator_rev = Dict(:Max=>:-, :Max=>:+) + convertor = Dict(MOI.MAX_SENSE => :<, MOI.MIN_SENSE => :>) # Updates time metric and the termination bounds - update_mip_time_limit(m) + set_mip_time_limit(m) update_boundstop_options(m) # ================= Solve Start ================ # start_bounding_solve = time() - status = solve(m.model_mip, suppress_warnings=true) + optimize!(m.model_mip) + status = termination_status(m.model_mip) m.logs[:total_time] += time() - start_bounding_solve - m.logs[:time_left] = max(0.0, m.timeout - m.logs[:total_time]) + m.logs[:time_left] = max(0.0, get_option(m, :timeout) - m.logs[:total_time]) # ================= Solve End ================ # - status_solved = [:Optimal, :UserObjLimit, :UserLimit, :Suboptimal] - status_maynosolution = [:UserObjLimit, :UserLimit] # Watch out for these cases - status_infeasible = [:Infeasible, :InfeasibleOrUnbounded] - if status in status_solved - (status == :Optimal) ? candidate_bound = m.model_mip.objVal : candidate_bound = m.model_mip.objBound - candidate_bound_sol = [round.(getvalue(Variable(m.model_mip, i)); digits=6) for i in 1:(m.num_var_orig+m.num_var_linear_mip+m.num_var_nonlinear_mip)] + if status in STATUS_OPT || status in STATUS_LIMIT + candidate_bound = (status == MOI.OPTIMAL) ? objective_value(m.model_mip) : objective_bound(m.model_mip) + candidate_bound_sol = [round.(JuMP.value(_index_to_variable_ref(m.model_mip, i)); digits=6) for i in 1:(m.num_var_orig+m.num_var_linear_mip+m.num_var_nonlinear_mip)] # Experimental code measure_relaxed_deviation(m, sol=candidate_bound_sol) - if m.disc_consecutive_forbid > 0 - m.bound_sol_history[mod(m.logs[:n_iter]-1, m.disc_consecutive_forbid)+1] = copy(candidate_bound_sol) # Requires proper offseting + if get_option(m, :disc_consecutive_forbid) > 0 + m.bound_sol_history[mod(m.logs[:n_iter]-1, get_option(m, :disc_consecutive_forbid))+1] = copy(candidate_bound_sol) # Requires proper offseting end push!(m.logs[:bound], candidate_bound) if eval(convertor[m.sense_orig])(candidate_bound, m.best_bound) m.best_bound = candidate_bound m.best_bound_sol = copy(candidate_bound_sol) m.status[:bounding_solve] = status - m.status[:bound] = :Detected + m.detected_bound = true end collect_lb_pool(m) # Always collect details sub-optimal solution - elseif status in status_infeasible + elseif status in STATUS_INF || status == MOI.INFEASIBLE_OR_UNBOUNDED push!(m.logs[:bound], "-") - m.status[:bounding_solve] = :Infeasible + m.status[:bounding_solve] = MOI.INFEASIBLE ALPINE_DEBUG && print_iis_gurobi(m.model_mip) # Diagnostic code @warn " Warning: Infeasibility detected via convex relaxation Infeasibility" elseif status == :Unbounded - m.status[:bounding_solve] = :Unbounded + m.status[:bounding_solve] = MOI.DUAL_INFEASIBLE @warn " Warning: MIP solver return unbounded" else error(" Warning: MIP solver failure $(status)") @@ -326,31 +356,31 @@ function bounding_solve(m::AlpineNonlinearModel) end """ -pick_disc_vars(m::AlpineNonlinearModel) +pick_disc_vars(m::Optimizer) This function helps pick the variables for discretization. The method chosen depends on user-inputs. In case when `indices::Int` is provided, the method is chosen as built-in method. Currently, there are two built-in options for users as follows: -* `max-cover (m.disc_var_pick=0, default)`: pick all variables involved in the non-linear term for discretization -* `min-vertex-cover (m.disc_var_pick=1)`: pick a minimum vertex cover for variables involved in non-linear terms so that each non-linear term is at least convexified +* `max-cover (get_option(m, :disc_var_pick)=0, default)`: pick all variables involved in the non-linear term for discretization +* `min-vertex-cover (get_option(m, :disc_var_pick)=1)`: pick a minimum vertex cover for variables involved in non-linear terms so that each non-linear term is at least convexified -For advanced usage, `m.disc_var_pick` allows `::Function` inputs. User can provide his/her own function to choose the variables for discretization. +For advanced usage, `get_option(m, :disc_var_pick)` allows `::Function` inputs. User can provide his/her own function to choose the variables for discretization. """ -function pick_disc_vars(m::AlpineNonlinearModel) +function pick_disc_vars(m::Optimizer) - if isa(m.disc_var_pick, Function) - eval(m.disc_var_pick)(m) + if isa(get_option(m, :disc_var_pick), Function) + eval(get_option(m, :disc_var_pick))(m) length(m.disc_vars) == 0 && length(m.nonconvex_terms) > 0 && error("[USER FUNCTION] must select at least one variable to perform discretization for convexificiation purpose") - elseif isa(m.disc_var_pick, Int) - if m.disc_var_pick == 0 + elseif isa(get_option(m, :disc_var_pick), Int) + if get_option(m, :disc_var_pick) == 0 ncvar_collect_nodes(m) - elseif m.disc_var_pick == 1 + elseif get_option(m, :disc_var_pick) == 1 min_vertex_cover(m) - elseif m.disc_var_pick == 2 + elseif get_option(m, :disc_var_pick) == 2 (length(m.candidate_disc_vars) > 15) ? min_vertex_cover(m) : ncvar_collect_nodes(m) - elseif m.disc_var_pick == 3 # Initial + elseif get_option(m, :disc_var_pick) == 3 # Initial (length(m.candidate_disc_vars) > 15) ? min_vertex_cover(m) : ncvar_collect_nodes(m) else error("Unsupported default indicator for picking variables for discretization") diff --git a/src/amp.jl b/src/amp.jl index 09a73e84..935dc6db 100644 --- a/src/amp.jl +++ b/src/amp.jl @@ -1,6 +1,6 @@ """ - create_bounding_mip(m::AlpineNonlinearModel; use_disc::Dict) + create_bounding_mip(m::Optimizer; use_disc::Dict) Set up a JuMP MILP bounding model base on variable domain partitioning information stored in `use_disc`. By default, if `use_disc is` not provided, it will use `m.discretizations` store in the Alpine model. @@ -33,11 +33,11 @@ More specifically, the Tightening McCormick used here can be generalized in the ``` """ -function create_bounding_mip(m::AlpineNonlinearModel; use_disc=nothing) +function create_bounding_mip(m::Optimizer; use_disc=nothing) use_disc == nothing ? discretization = m.discretization : discretization = use_disc - m.model_mip = Model(solver=m.mip_solver) # Construct JuMP Model + m.model_mip = Model(get_option(m, :mip_solver)) # Construct JuMP Model start_build = time() # ------- Model Construction ------ # amp_post_vars(m) # Post original and lifted variables @@ -47,23 +47,23 @@ function create_bounding_mip(m::AlpineNonlinearModel; use_disc=nothing) # --------------------------------- # cputime_build = time() - start_build m.logs[:total_time] += cputime_build - m.logs[:time_left] = max(0.0, m.timeout - m.logs[:total_time]) + m.logs[:time_left] = max(0.0, get_option(m, :timeout) - m.logs[:total_time]) return end """ - amp_post_convexification(m::AlpineNonlinearModel; kwargs...) + amp_post_convexification(m::Optimizer; kwargs...) wrapper function to convexify the problem for a bounding model. This function talks to nonconvex_terms and convexification methods to finish the last step required during the construction of bounding model. """ -function amp_post_convexification(m::AlpineNonlinearModel; use_disc=nothing) +function amp_post_convexification(m::Optimizer; use_disc=nothing) use_disc == nothing ? discretization = m.discretization : discretization = use_disc - for i in 1:length(m.method_convexification) # Additional user-defined convexification method - eval(m.method_convexification[i])(m) + for i in 1:length(get_option(m, :method_convexification)) # Additional user-defined convexification method + eval(get_option(m, :method_convexification)[i])(m) end amp_post_mccormick(m, use_disc=discretization) # handles all bi-linear and monomial convexificaitons @@ -74,7 +74,7 @@ function amp_post_convexification(m::AlpineNonlinearModel; use_disc=nothing) return end -function amp_post_vars(m::AlpineNonlinearModel; kwargs...) +function amp_post_vars(m::Optimizer; kwargs...) options = Dict(kwargs) @@ -90,11 +90,17 @@ function amp_post_vars(m::AlpineNonlinearModel; kwargs...) for i in 1:(m.num_var_orig+m.num_var_linear_mip+m.num_var_nonlinear_mip) # This is a tricky step, not enforcing category of lifted variables is able to improve performance - (i <= m.num_var_orig) && setcategory(x[i], m.var_type_orig[i]) + if i <= m.num_var_orig + if m.var_type_orig[i] == :Bin + set_binary(x[i]) + elseif m.var_type_orig[i] == :Int + set_integer(x[i]) + end + end # Changed to tight bound, if no bound tightening is performed, will be just .l_var_orig - l_var[i] > -Inf && setlowerbound(x[i], l_var[i]) + l_var[i] > -Inf && JuMP.set_lower_bound(x[i], l_var[i]) # Changed to tight bound, if no bound tightening is performed, will be just .u_var_orig - u_var[i] < Inf && setupperbound(x[i], u_var[i]) + u_var[i] < Inf && JuMP.set_upper_bound(x[i], u_var[i]) m.var_type[i] == :Int && error("Support for general integer problem is current limited...") end @@ -103,7 +109,7 @@ function amp_post_vars(m::AlpineNonlinearModel; kwargs...) end -function amp_post_lifted_constraints(m::AlpineNonlinearModel) +function amp_post_lifted_constraints(m::Optimizer) for i in 1:m.num_constr_orig if m.constr_structure[i] == :affine @@ -126,13 +132,13 @@ function amp_post_affine_constraint(model_mip::JuMP.Model, affine::Dict) if affine[:sense] == :(>=) @constraint(model_mip, - sum(affine[:coefs][j]*Variable(model_mip, affine[:vars][j].args[2]) for j in 1:affine[:cnt]) >= affine[:rhs]) + sum(affine[:coefs][j]*_index_to_variable_ref(model_mip, affine[:vars][j].args[2]) for j in 1:affine[:cnt]) >= affine[:rhs]) elseif affine[:sense] == :(<=) @constraint(model_mip, - sum(affine[:coefs][j]*Variable(model_mip, affine[:vars][j].args[2]) for j in 1:affine[:cnt]) <= affine[:rhs]) + sum(affine[:coefs][j]*_index_to_variable_ref(model_mip, affine[:vars][j].args[2]) for j in 1:affine[:cnt]) <= affine[:rhs]) elseif affine[:sense] == :(==) @constraint(model_mip, - sum(affine[:coefs][j]*Variable(model_mip, affine[:vars][j].args[2]) for j in 1:affine[:cnt]) == affine[:rhs]) + sum(affine[:coefs][j]*_index_to_variable_ref(model_mip, affine[:vars][j].args[2]) for j in 1:affine[:cnt]) == affine[:rhs]) else error("Unkown sense.") end @@ -146,10 +152,10 @@ function amp_post_convex_constraint(model_mip::JuMP.Model, convex::Dict) if convex[:sense] == :(<=) @constraint(model_mip, - sum(convex[:coefs][j]*Variable(model_mip, convex[:vars][j].args[2])^2 for j in 1:convex[:cnt]) <= convex[:rhs]) + sum(convex[:coefs][j]*_index_to_variable_ref(model_mip, convex[:vars][j].args[2])^2 for j in 1:convex[:cnt]) <= convex[:rhs]) elseif convex[:sense] == :(>=) @constraint(model_mip, - sum(convex[:coefs][j]*Variable(model_mip, convex[:vars][j].args[2])^2 for j in 1:convex[:cnt]) >= convex[:rhs]) + sum(convex[:coefs][j]*_index_to_variable_ref(model_mip, convex[:vars][j].args[2])^2 for j in 1:convex[:cnt]) >= convex[:rhs]) else error("No equality constraints should be recognized as supported convex constriants") end @@ -160,21 +166,21 @@ end function amp_post_linear_lift_constraints(model_mip::JuMP.Model, l::Dict) @assert l[:ref][:sign] == :+ - @constraint(model_mip, Variable(model_mip, l[:y_idx]) == sum(i[1]*Variable(model_mip, i[2]) for i in l[:ref][:coef_var]) + l[:ref][:scalar]) + @constraint(model_mip, _index_to_variable_ref(model_mip, l[:y_idx]) == sum(i[1]*_index_to_variable_ref(model_mip, i[2]) for i in l[:ref][:coef_var]) + l[:ref][:scalar]) return end -function amp_post_lifted_objective(m::AlpineNonlinearModel) - +function amp_post_lifted_objective(m::Optimizer) + #if isa(m.obj_expr_orig, Number) if expr_isconst(m.obj_expr_orig) @objective(m.model_mip, m.sense_orig, eval(m.obj_expr_orig)) elseif m.obj_structure == :affine - @objective(m.model_mip, m.sense_orig, m.bounding_obj_mip[:rhs] + sum(m.bounding_obj_mip[:coefs][i]*Variable(m.model_mip, m.bounding_obj_mip[:vars][i].args[2]) for i in 1:m.bounding_obj_mip[:cnt])) + @objective(m.model_mip, m.sense_orig, m.bounding_obj_mip[:rhs] + sum(m.bounding_obj_mip[:coefs][i]*_index_to_variable_ref(m.model_mip, m.bounding_obj_mip[:vars][i].args[2]) for i in 1:m.bounding_obj_mip[:cnt])) elseif m.obj_structure == :convex - # This works only when the original objective is convex quadratic. + # This works only when the original objective is convex quadratic. # Higher-order convex monomials need implementation of outer-approximation (check resolve_convex_constr in operators.jl) - @objective(m.model_mip, m.sense_orig, m.bounding_obj_mip[:rhs] + sum(m.bounding_obj_mip[:coefs][i]*Variable(m.model_mip, m.bounding_obj_mip[:vars][i].args[2])^2 for i in 1:m.bounding_obj_mip[:cnt])) + @objective(m.model_mip, m.sense_orig, m.bounding_obj_mip[:rhs] + sum(m.bounding_obj_mip[:coefs][i]*_index_to_variable_ref(m.model_mip, m.bounding_obj_mip[:vars][i].args[2])^2 for i in 1:m.bounding_obj_mip[:cnt])) else @show m.obj_expr_orig error("Unknown structural obj type $(m.obj_structure)") @@ -182,17 +188,17 @@ if expr_isconst(m.obj_expr_orig) return end -function add_partition(m::AlpineNonlinearModel; kwargs...) +function add_partition(m::Optimizer; kwargs...) options = Dict(kwargs) haskey(options, :use_disc) ? discretization = options[:use_disc] : discretization = m.discretization haskey(options, :use_solution) ? point_vec = options[:use_solution] : point_vec = m.best_bound_sol - if isa(m.disc_add_partition_method, Function) - m.discretization = eval(m.disc_add_partition_method)(m, use_disc=discretization, use_solution=point_vec) - elseif m.disc_add_partition_method == "adaptive" + if isa(get_option(m, :disc_add_partition_method), Function) + m.discretization = eval(get_option(m, :disc_add_partition_method))(m, use_disc=discretization, use_solution=point_vec) + elseif get_option(m, :disc_add_partition_method) == "adaptive" m.discretization = add_adaptive_partition(m, use_disc=discretization, use_solution=point_vec) - elseif m.disc_add_partition_method == "uniform" + elseif get_option(m, :disc_add_partition_method) == "uniform" m.discretization = add_uniform_partition(m, use_disc=discretization) else error("Unknown input on how to add partitions.") @@ -202,7 +208,7 @@ function add_partition(m::AlpineNonlinearModel; kwargs...) end """ - add_discretization(m::AlpineNonlinearModel; use_disc::Dict, use_solution::Vector) + add_discretization(m::Optimizer; use_disc::Dict, use_solution::Vector) Basic built-in method used to add a new partition on feasible domains of discretizing variables. This method makes modification in discretization @@ -227,13 +233,13 @@ TODO: also need to document the special diverted cases when new partition touche This function can be accordingly modified by the user to change the behavior of the solver, and thus the convergence. """ -function add_adaptive_partition(m::AlpineNonlinearModel;kwargs...) +function add_adaptive_partition(m::Optimizer;kwargs...) options = Dict(kwargs) haskey(options, :use_disc) ? discretization = options[:use_disc] : discretization = m.discretization haskey(options, :use_solution) ? point_vec = copy(options[:use_solution]) : point_vec = copy(m.best_bound_sol) - haskey(options, :use_ratio) ? ratio = options[:use_ratio] : ratio = m.disc_ratio + haskey(options, :use_ratio) ? ratio = options[:use_ratio] : ratio = get_option(m, :disc_ratio) haskey(options, :branching) ? branching = options[:branching] : branching = false if length(point_vec) < m.num_var_orig + m.num_var_linear_mip + m.num_var_nonlinear_mip @@ -281,15 +287,15 @@ end """ This function targets to address unexpected numerical issues when adding partitions in tight regions. """ -function correct_point(m::AlpineNonlinearModel, partvec::Vector, point::Float64, var::Int) +function correct_point(m::Optimizer, partvec::Vector, point::Float64, var::Int) - if point < partvec[1] - m.tol || point > partvec[end] + m.tol + if point < partvec[1] - get_option(m, :tol) || point > partvec[end] + get_option(m, :tol) @warn " Warning: VAR$(var) SOL=$(point) out of discretization [$(partvec[1]),$(partvec[end])]. Taking middle point..." return 0.5*(partvec[1] + partvec[end]) # Should choose the longest range end - isapprox(point, partvec[1];atol=m.tol) && return partvec[1] - isapprox(point, partvec[end];atol=m.tol) && return partvec[end] + isapprox(point, partvec[1];atol=get_option(m, :tol)) && return partvec[1] + isapprox(point, partvec[end];atol=get_option(m, :tol)) && return partvec[end] return point end @@ -311,9 +317,9 @@ function calculate_radius(partvec::Vector, part::Int, ratio::Any) return radius end -function insert_partition(m::AlpineNonlinearModel, var::Int, partidx::Int, point::Number, radius::Float64, partvec::Vector) +function insert_partition(m::Optimizer, var::Int, partidx::Int, point::Number, radius::Float64, partvec::Vector) - abstol, reltol = m.disc_abs_width_tol, m.disc_rel_width_tol + abstol, reltol = get_option(m, :disc_abs_width_tol), get_option(m, :disc_rel_width_tol) lb_local, ub_local = partvec[partidx], partvec[partidx+1] ub_touch, lb_touch = true, true @@ -336,21 +342,21 @@ function insert_partition(m::AlpineNonlinearModel, var::Int, partidx::Int, point pos = distvec[end][1] lb_local = partvec[pos] ub_local = partvec[pos+1] - isapprox(lb_local, ub_local;atol=m.tol) && return - chunk = (ub_local - lb_local) / m.disc_divert_chunks - point = lb_local + (ub_local - lb_local) / m.disc_divert_chunks - for i in 2:m.disc_divert_chunks - insert!(partvec, pos+1, lb_local + chunk * (m.disc_divert_chunks-(i-1))) + isapprox(lb_local, ub_local;atol=get_option(m, :tol)) && return + chunk = (ub_local - lb_local) / get_option(m, :disc_divert_chunks) + point = lb_local + (ub_local - lb_local) / get_option(m, :disc_divert_chunks) + for i in 2:get_option(m, :disc_divert_chunks) + insert!(partvec, pos+1, lb_local + chunk * (get_option(m, :disc_divert_chunks)-(i-1))) end - (m.loglevel > 199) && println("[DEBUG] !D! VAR$(var): SOL=$(round(point_orig; digits=4))=>$(point) |$(round(lb_local; digits=4)) | $(m.disc_divert_chunks) SEGMENTS | $(round(ub_local; digits=4))|") + (get_option(m, :loglevel) > 199) && println("[DEBUG] !D! VAR$(var): SOL=$(round(point_orig; digits=4))=>$(point) |$(round(lb_local; digits=4)) | $(get_option(m, :disc_divert_chunks)) SEGMENTS | $(round(ub_local; digits=4))|") else - (m.loglevel > 199) && println("[DEBUG] VAR$(var): SOL=$(round(point; digits=4)) RADIUS=$(radius), PARTITIONS=$(length(partvec)-1) |$(round(lb_local; digits=4)) |$(round(lb_new; digits=6)) <- * -> $(round(ub_new; digits=6))| $(round(ub_local; digits=4))|") + (get_option(m, :loglevel) > 199) && println("[DEBUG] VAR$(var): SOL=$(round(point; digits=4)) RADIUS=$(radius), PARTITIONS=$(length(partvec)-1) |$(round(lb_local; digits=4)) |$(round(lb_new; digits=6)) <- * -> $(round(ub_new; digits=6))| $(round(ub_local; digits=4))|") end return end -function add_uniform_partition(m::AlpineNonlinearModel; kwargs...) +function add_uniform_partition(m::Optimizer; kwargs...) options = Dict(kwargs) haskey(options, :use_disc) ? discretization = options[:use_disc] : discretization = m.discretization @@ -359,25 +365,25 @@ function add_uniform_partition(m::AlpineNonlinearModel; kwargs...) lb_local = discretization[i][1] ub_local = discretization[i][end] distance = ub_local - lb_local - chunk = distance / ((m.logs[:n_iter]+1)*m.disc_uniform_rate) - discretization[i] = [lb_local+chunk*(j-1) for j in 1:(m.logs[:n_iter]+1)*m.disc_uniform_rate] + chunk = distance / ((m.logs[:n_iter]+1)*get_option(m, :disc_uniform_rate)) + discretization[i] = [lb_local+chunk*(j-1) for j in 1:(m.logs[:n_iter]+1)*get_option(m, :disc_uniform_rate)] push!(discretization[i], ub_local) # Safety Scheme - (m.loglevel > 199) && println("[DEBUG] VAR$(i): RATE=$(m.disc_uniform_rate), PARTITIONS=$(length(discretization[i])) |$(round(lb_local; digits=4)) | $(m.disc_uniform_rate*(1+m.logs[:n_iter])) SEGMENTS | $(round(ub_local; digits=4))|") + (get_option(m, :loglevel) > 199) && println("[DEBUG] VAR$(i): RATE=$(get_option(m, :disc_uniform_rate)), PARTITIONS=$(length(discretization[i])) |$(round(lb_local; digits=4)) | $(get_option(m, :disc_uniform_rate)*(1+m.logs[:n_iter])) SEGMENTS | $(round(ub_local; digits=4))|") end return discretization end -function update_disc_ratio(m::AlpineNonlinearModel, presolve=false) +function update_disc_ratio(m::Optimizer, presolve=false) - m.logs[:n_iter] > 2 && return m.disc_ratio # Stop branching after the second iterations + m.logs[:n_iter] > 2 && return get_option(m, :disc_ratio) # Stop branching after the second iterations ratio_pool = [8:2:20;] # Built-in try range - convertor = Dict(:Max=>:<, :Min=>:>) - revconvertor = Dict(:Max=>:>, :Min=>:<) + convertor = Dict(MOI.MAX_SENSE => :<, MOI.MIN_SENSE => :>) + revconvertor = Dict(MOI.MAX_SENSE => :>, MOI.MIN_SENSE => :<) incumb_ratio = ratio_pool[1] - m.sense_orig == :Min ? incumb_res = -Inf : incumb_res = Inf + is_min_sense(m) ? incumb_res = -Inf : incumb_res = Inf res_collector = Float64[] for r in ratio_pool @@ -399,12 +405,12 @@ function update_disc_ratio(m::AlpineNonlinearModel, presolve=false) println("Expensive disc branching pass... Fixed at 8") return 8 end - m.loglevel > 0 && println("BRANCH RATIO = $(r), METRIC = $(res) || TIME = $(time()-st)") + get_option(m, :loglevel) > 0 && println("BRANCH RATIO = $(r), METRIC = $(res) || TIME = $(time()-st)") end if std(res_collector) >= 1e-2 # Detect if all solution are similar to each other - m.loglevel > 0 && println("RATIO BRANCHING OFF due to solution variance test passed.") - m.disc_ratio_branch = false # If an incumbent ratio is selected, then stop the branching scheme + get_option(m, :loglevel) > 0 && println("RATIO BRANCHING OFF due to solution variance test passed.") + set_option(m, :disc_ratio_branch, false) # If an incumbent ratio is selected, then stop the branching scheme end if !isempty(m.best_sol) @@ -413,30 +419,31 @@ function update_disc_ratio(m::AlpineNonlinearModel, presolve=false) m.discretization = add_adaptive_partition(m, use_disc=m.discretization, branching=true, use_ratio=incumb_ratio) end - m.loglevel > 0 && println("INCUMB_RATIO = $(incumb_ratio)") + get_option(m, :loglevel) > 0 && println("INCUMB_RATIO = $(incumb_ratio)") return incumb_ratio end -function disc_branch_solve(m::AlpineNonlinearModel) +function disc_branch_solve(m::Optimizer) # ================= Solve Start ================ # - update_mip_time_limit(m) + set_mip_time_limit(m) start_bounding_solve = time() - status = solve(m.model_mip, suppress_warnings=true) + JuMP.optimize!(m.model_mip) + status = MOI.get(m.model_mip, MOI.TerminationStatus()) cputime_branch_bounding_solve = time() - start_bounding_solve m.logs[:total_time] += cputime_branch_bounding_solve - m.logs[:time_left] = max(0.0, m.timeout - m.logs[:total_time]) + m.logs[:time_left] = max(0.0, get_option(m, :timeout) - m.logs[:total_time]) # ================= Solve End ================ # - if status in [:Optimal, :Suboptimal, :UserLimit] - return m.model_mip.objBound + if status in STATUS_OPT || status in STATUS_LIMIT + return MOI.get(m.model_mip, MOI.ObjectiveBound()) else @warn " Warning: Unexpected solving condition $(status) during disc branching." end # Safety scheme - if m.sense_orig == :Min + if is_min_sense(m) return -Inf else return Inf diff --git a/src/bounds.jl b/src/bounds.jl index 95bf4ab6..5d97414d 100644 --- a/src/bounds.jl +++ b/src/bounds.jl @@ -1,10 +1,10 @@ """ - init_tight_bound(m::AlpineNonlinearModel) + init_tight_bound(m::Optimizer) Initialize internal bound vectors (placeholders) to be used in other places. In this case, we don't have to mess with the original bound information. """ -function init_tight_bound(m::AlpineNonlinearModel) +function init_tight_bound(m::Optimizer) m.l_var_tight = [m.l_var_orig; fill(-Inf, m.num_var_linear_mip+m.num_var_nonlinear_mip)] m.u_var_tight = [m.u_var_orig; fill(Inf, m.num_var_linear_mip+m.num_var_nonlinear_mip)] for i in 1:m.num_var_orig @@ -20,12 +20,12 @@ function init_tight_bound(m::AlpineNonlinearModel) end """ - init_disc(m::AlpineNonlinearModel) + init_disc(m::Optimizer) This function initialize the dynamic discretization used for any bounding models. By default, it takes (.l_var_orig, .u_var_orig) as the base information. User is allowed to use alternative bounds for initializing the discretization dictionary. -The output is a dictionary with MathProgBase variable indices keys attached to the :AlpineNonlinearModel.discretization. +The output is a dictionary with MathProgBase variable indices keys attached to the :Optimizer.discretization. """ -function init_disc(m::AlpineNonlinearModel) +function init_disc(m::Optimizer) for var in 1:(m.num_var_orig+m.num_var_linear_mip+m.num_var_nonlinear_mip) if m.var_type[var] in [:Bin, :Cont] @@ -33,8 +33,8 @@ function init_disc(m::AlpineNonlinearModel) ub = m.u_var_tight[var] m.discretization[var] = [lb, ub] elseif m.var_type[var] in [:Int] - m.int_enable ? lb = floor(m.l_var_tight[var]) - 0.5 : lb = floor(m.l_var_tight[var]) - m.int_enable ? ub = ceil(m.u_var_tight[var]) + 0.5 : ub = floor(m.u_var_tight[var]) + get_option(m, :int_enable) ? lb = floor(m.l_var_tight[var]) - 0.5 : lb = floor(m.l_var_tight[var]) + get_option(m, :int_enable) ? ub = ceil(m.u_var_tight[var]) + 0.5 : ub = floor(m.u_var_tight[var]) m.discretization[var] = [lb, ub] else error("[EXCEPTION] Unexpected variable type when initializing discretization dictionary.") @@ -46,13 +46,13 @@ end """ - to_discretization(m::AlpineNonlinearModel, lbs::Vector{Float64}, ubs::Vector{Float64}) + to_discretization(m::Optimizer, lbs::Vector{Float64}, ubs::Vector{Float64}) Utility functions to convert bounds vectors to Dictionary based structures that is more suitable for partition operations. """ -function to_discretization(m::AlpineNonlinearModel, lbs::Vector{Float64}, ubs::Vector{Float64}) +function to_discretization(m::Optimizer, lbs::Vector{Float64}, ubs::Vector{Float64}) @assert length(lbs) == length(ubs) var_discretization = Dict() @@ -100,13 +100,13 @@ end """ - detect_bound_from_aff(m::AlpineNonlinearModel) + detect_bound_from_aff(m::Optimizer) Detect bounds from parse affine constraint. This function examines the one variable constraints such as x >= 5, x <= 5 or x == 5 and fetch the information to m.l_var_tight and m.u_var_tight. This function can potential grow to be smarter. """ -function bound_propagation(m::AlpineNonlinearModel) +function bound_propagation(m::Optimizer) exhausted = false infeasible = false while !exhausted @@ -128,21 +128,21 @@ function bound_propagation(m::AlpineNonlinearModel) (eval_u_bound != Inf) && (eval_u_bound += abs(aff[:coefs][j]/var_coef)*m.u_var_tight[aff[:vars][j].args[2]]) end end - if eval_l_bound > m.l_var_tight[var_idx] + m.tol + if eval_l_bound > m.l_var_tight[var_idx] + get_option(m, :tol) exhausted = false m.l_var_tight[var_idx] = eval_l_bound - (m.loglevel > 199) && println("[VAR$(var_idx)] LB $(m.l_var_tight[var_idx]) evaluated from constraint") - elseif eval_l_bound > m.u_var_tight[var_idx] + m.tol - (m.loglevel > 199) && println("[VAR$(var_idx)] Infeasibility detection during bound propagation") + (get_option(m, :loglevel) > 199) && println("[VAR$(var_idx)] LB $(m.l_var_tight[var_idx]) evaluated from constraint") + elseif eval_l_bound > m.u_var_tight[var_idx] + get_option(m, :tol) + (get_option(m, :loglevel) > 199) && println("[VAR$(var_idx)] Infeasibility detection during bound propagation") infeasible = true break end - if eval_u_bound < m.u_var_tight[var_idx] - m.tol + if eval_u_bound < m.u_var_tight[var_idx] - get_option(m, :tol) exhausted = false m.u_var_tight[var_idx] = eval_u_bound - (m.loglevel > 199) && println("[VAR$(var_idx)] UB $(m.u_var_tight[var_idx]) evaluated from constraints") - elseif eval_u_bound < m.l_var_tight[var_idx] - m.tol - (m.loglevel > 199) && println("[VAR$(var_idx)] Infeasibility detection during bound propagation") + (get_option(m, :loglevel) > 199) && println("[VAR$(var_idx)] UB $(m.u_var_tight[var_idx]) evaluated from constraints") + elseif eval_u_bound < m.l_var_tight[var_idx] - get_option(m, :tol) + (get_option(m, :loglevel) > 199) && println("[VAR$(var_idx)] Infeasibility detection during bound propagation") infeasible = true break end @@ -156,12 +156,12 @@ function bound_propagation(m::AlpineNonlinearModel) end (eval_bound == -Inf) && break end - if eval_bound > m.l_var_tight[var_idx] + m.tol + if eval_bound > m.l_var_tight[var_idx] + get_option(m, :tol) exhausted = false m.l_var_tight[var_idx] = eval_bound - (m.loglevel > 199) && println("[VAR$(var_idx)] LB $(m.l_var_tight[var_idx]) evaluated from constraints") - elseif eval_bound > m.u_var_tight[var_idx] + m.tol - (m.loglevel > 199) && println("[VAR$(var_idx)] Infeasibility detection during bound propagation") + (get_option(m, :loglevel) > 199) && println("[VAR$(var_idx)] LB $(m.l_var_tight[var_idx]) evaluated from constraints") + elseif eval_bound > m.u_var_tight[var_idx] + get_option(m, :tol) + (get_option(m, :loglevel) > 199) && println("[VAR$(var_idx)] Infeasibility detection during bound propagation") infeasible = true break end @@ -175,12 +175,12 @@ function bound_propagation(m::AlpineNonlinearModel) end (eval_bound == Inf) && break end - if eval_bound < m.u_var_tight[var_idx] - m.tol + if eval_bound < m.u_var_tight[var_idx] - get_option(m, :tol) exhausted = false m.u_var_tight[var_idx] = eval_bound - (m.loglevel > 199) && println("[VAR$(var_idx)] UB $(m.u_var_tight[var_idx]) evaluated from constraints") - elseif eval_bound < m.l_var_tight[var_idx] - m.tol - (m.loglevel > 199) && println("[VAR$(var_idx)] Infeasibility detection during bound propagation") + (get_option(m, :loglevel) > 199) && println("[VAR$(var_idx)] UB $(m.u_var_tight[var_idx]) evaluated from constraints") + elseif eval_bound < m.l_var_tight[var_idx] - get_option(m, :tol) + (get_option(m, :loglevel) > 199) && println("[VAR$(var_idx)] Infeasibility detection during bound propagation") infeasible = true break end @@ -194,12 +194,12 @@ function bound_propagation(m::AlpineNonlinearModel) end (eval_bound == Inf) && break end - if eval_bound < m.u_var_tight[var_idx] - m.tol + if eval_bound < m.u_var_tight[var_idx] - get_option(m, :tol) exhausted = false m.u_var_tight[var_idx] = eval_bound - (m.loglevel > 199) && println("[VAR$(var_idx)] UB $(m.u_var_tight[var_idx]) evaluated from constraints") - elseif eval_bound < m.l_var_tight[var_idx] - m.tol - (m.loglevel > 199) && println("[VAR$(var_idx)] Infeasibility detection during bound propagation") + (get_option(m, :loglevel) > 199) && println("[VAR$(var_idx)] UB $(m.u_var_tight[var_idx]) evaluated from constraints") + elseif eval_bound < m.l_var_tight[var_idx] - get_option(m, :tol) + (get_option(m, :loglevel) > 199) && println("[VAR$(var_idx)] Infeasibility detection during bound propagation") infeasible = true break end @@ -213,23 +213,23 @@ function bound_propagation(m::AlpineNonlinearModel) end (eval_bound == -Inf) && break end - if eval_bound > m.l_var_tight[var_idx] + m.tol + if eval_bound > m.l_var_tight[var_idx] + get_option(m, :tol) exhausted = false m.l_var_tight[var_idx] = eval_bound - (m.loglevel > 199) && println("[VAR$(var_idx)] LB $(m.l_var_tight[var_idx]) evaluated from constraints") - elseif eval_bound > m.u_var_tight[var_idx] + m.tol - (m.loglevel > 199) && println("[VAR$(var_idx)] Infeasibility detection during bound propagation") + (get_option(m, :loglevel) > 199) && println("[VAR$(var_idx)] LB $(m.l_var_tight[var_idx]) evaluated from constraints") + elseif eval_bound > m.u_var_tight[var_idx] + get_option(m, :tol) + (get_option(m, :loglevel) > 199) && println("[VAR$(var_idx)] Infeasibility detection during bound propagation") infeasible = true break end end end end - (exhausted == true && m.loglevel > 99) && println("Initial constraint-based bound evaluation exhausted...") + (exhausted == true && get_option(m, :loglevel) > 99) && println("Initial constraint-based bound evaluation exhausted...") end if infeasible - m.status[:bounding_solve] = :Infeasible + m.status[:bounding_solve] = MOI.INFEASIBLE @warn "[INFEASIBLE] Infeasibility detected via bound propagation" end @@ -239,7 +239,7 @@ end """ Recategorize :Int variables to :Bin variables if variable bounds are [0,1] """ -function recategorize_var(m::AlpineNonlinearModel) +function recategorize_var(m::Optimizer) for i in 1:m.num_var_orig if m.var_type_orig[i] == :Int && m.l_var_orig[i] == 0.0 && m.u_var_orig[i] == 1.0 @@ -252,16 +252,16 @@ function recategorize_var(m::AlpineNonlinearModel) end """ - resolve_var_bounds(m::AlpineNonlinearModel) + resolve_var_bounds(m::Optimizer) Resolve the bounds of the lifted variable using the information in l_var_tight and u_var_tight. This method only takes in known or trivial bounds information to reason lifted variable bound to avoid the cases of infinity bounds. """ -function resolve_var_bounds(m::AlpineNonlinearModel) +function resolve_var_bounds(m::Optimizer) # Basic Bound propagation - if m.presolve_bp - m.presolve_infeasible = bound_propagation(m) # Fetch bounds from constraints + if get_option(m, :presolve_bp) + setproperty!(m, :presolve_infeasible, bound_propagation(m)) # Fetch bounds from constraints end # Resolve unbounded variables in the original formulation @@ -287,7 +287,7 @@ end """ Critically assumed since Alpine relies on finite bound to work """ -function resolve_inf_bounds(m::AlpineNonlinearModel) +function resolve_inf_bounds(m::Optimizer) warnuser = false infcount_l = 0 infcount_u = 0 @@ -296,20 +296,20 @@ function resolve_inf_bounds(m::AlpineNonlinearModel) for i = 1:length(m.l_var_orig) if m.l_var_tight[i] == -Inf warnuser = true - m.l_var_tight[i] = -m.largebound + m.l_var_tight[i] = -get_option(m, :largebound) infcount_l += 1 end if m.u_var_tight[i] == Inf warnuser = true - m.u_var_tight[i] = m.largebound + m.u_var_tight[i] = get_option(m, :largebound) infcount_u +=1 end end infcount = min(infcount_l, infcount_u) if infcount == 1 - warnuser && println("Warning: -/+Inf bounds detected on at least $infcount variable. Initializing with values -/+$(m.largebound). This may affect global optimality and run times.") + warnuser && println("Warning: -/+Inf bounds detected on at least $infcount variable. Initializing with values -/+$(get_option(m, :largebound)). This may affect global optimality and run times.") elseif infcount > 1 - warnuser && println("Warning: -/+Inf bounds detected on at least $infcount variables. Initializing with values -/+$(m.largebound). This may affect global optimality and run times.") + warnuser && println("Warning: -/+Inf bounds detected on at least $infcount variables. Initializing with values -/+$(get_option(m, :largebound)). This may affect global optimality and run times.") end return end @@ -323,7 +323,7 @@ end Only used in presolve bound tightening """ -function resolve_var_bounds(m::AlpineNonlinearModel, d::Dict; kwargs...) +function resolve_var_bounds(m::Optimizer, d::Dict; kwargs...) # Added sequential bound resolving process base on DFS process, which ensures all bounds are secured. # Increased complexity from linear to square but a reasonable amount # Potentially, additional mapping can be applied to reduce the complexity @@ -359,17 +359,17 @@ function resolve_var_bounds(m::AlpineNonlinearModel, d::Dict; kwargs...) end """ - resolve_closed_var_bounds(m::AlpineNonlinearModel) + resolve_closed_var_bounds(m::Optimizer) This function seeks variable with tight bounds (by presolve_bt_width_tol) by checking .l_var_tight and .u_var_tight. If a variable is found to be within a sufficiently small interval then no discretization will be performed on this variable and the .discretization will be cleared with the tight bounds for basic McCormick operation if necessary. """ -function resolve_closed_var_bounds(m::AlpineNonlinearModel; kwargs...) +function resolve_closed_var_bounds(m::Optimizer; kwargs...) for var in m.candidate_disc_vars - if abs(m.l_var_tight[var] - m.u_var_tight[var]) < m.presolve_bt_width_tol # Closed Bound Criteria + if abs(m.l_var_tight[var] - m.u_var_tight[var]) < get_option(m, :presolve_bt_width_tol) # Closed Bound Criteria deleteat!(m.disc_vars, findfirst(m.disc_vars, var)) # Clean nonconvex_terms by deleting the info m.discretization[var] = [m.l_var_tight[var], m.u_var_tight[var]] # Clean up the discretization for basic McCormick if necessary end @@ -379,7 +379,7 @@ function resolve_closed_var_bounds(m::AlpineNonlinearModel; kwargs...) end """ - update_var_bounds(m::AlpineNonlinearModel, discretization::Dict; len::Float64=length(keys(discretization))) + update_var_bounds(m::Optimizer, discretization::Dict; len::Float64=length(keys(discretization))) This function take in a dictionary-based discretization information and convert them into two bounds vectors (l_var, u_var) by picking the smallest and largest numbers. User can specify a certain length that may contains variables that is out of the scope of discretization. diff --git a/src/embedding.jl b/src/embedding.jl index 269d06f1..0c47fbf0 100644 --- a/src/embedding.jl +++ b/src/embedding.jl @@ -111,7 +111,7 @@ end This is the function that translate the bounding constraints (α¹b⁰+α²b¹ <= x <= α¹b¹+α²b²) with log # of binary variables, i.e., generate these constraints using log # of binary variables. """ -function ebd_link_xα(m::AlpineNonlinearModel, α::Vector, λCnt::Int, disc_vec::Vector, code_seq::Vector, var_idx::Int) +function ebd_link_xα(m::Optimizer, α::Vector, λCnt::Int, disc_vec::Vector, code_seq::Vector, var_idx::Int) lifters = Dict() exprs = Dict() @@ -125,7 +125,7 @@ function ebd_link_xα(m::AlpineNonlinearModel, α::Vector, λCnt::Int, disc_vec: end # Construct Variable Vector - α_A = @variable(m.model_mip, [1:length(keys(lifters))], lowerbound=0.0, upperbound=1.0, basename="αA$(var_idx)") + α_A = @variable(m.model_mip, [1:length(keys(lifters))], lower_bound=0.0, upper_bound=1.0, base_name="αA$(var_idx)") for i in keys(lifters) # Build first-level evaluation binprod_relax(m.model_mip, α_A[lifters[i]-L], [α[j] for j in i]) end @@ -137,8 +137,8 @@ function ebd_link_xα(m::AlpineNonlinearModel, α::Vector, λCnt::Int, disc_vec: end # Contructing final constraints - @constraint(m.model_mip, Variable(m.model_mip, var_idx) >= sum(exprs[j][:expr]*disc_vec[j] for j in 1:P)) - @constraint(m.model_mip, Variable(m.model_mip, var_idx) <= sum(exprs[j-1][:expr]*disc_vec[j] for j in 2:(P+1))) + @constraint(m.model_mip, _index_to_variable_ref(m.model_mip, var_idx) >= sum(exprs[j][:expr]*disc_vec[j] for j in 1:P)) + @constraint(m.model_mip, _index_to_variable_ref(m.model_mip, var_idx) <= sum(exprs[j-1][:expr]*disc_vec[j] for j in 2:(P+1))) return end diff --git a/src/heuristics.jl b/src/heuristics.jl index 5aae3764..3fae6196 100644 --- a/src/heuristics.jl +++ b/src/heuristics.jl @@ -1,14 +1,14 @@ """ - Ranking of variables involved in nonlinear terms for piecewise adaptive partitioning: - Ranked based on the absolute gap between each variable's solution from the lower-bounding MIP and the best feasible solution to the MINLP. + Ranking of variables involved in nonlinear terms for piecewise adaptive partitioning: + Ranked based on the absolute gap between each variable's solution from the lower-bounding MIP and the best feasible solution to the MINLP. Currently doesn't support recursive convexification """ -function update_disc_cont_var(m::AlpineNonlinearModel) +function update_disc_cont_var(m::Optimizer) length(m.candidate_disc_vars) <= 15 && return # Algorithm Separation Point # If no feasible solution is found, do NOT update - if m.status[:feasible_solution] != :Detected + if !m.detected_feasible_solution println("no feasible solution detected. No update disc var selection.") return end @@ -39,11 +39,11 @@ function update_disc_cont_var(m::AlpineNonlinearModel) distance = Dict(zip(var_idxs,var_diffs)) weighted_min_vertex_cover(m, distance) - (m.loglevel > 100) && println("updated partition var selection => $(m.disc_vars)") + (get_option(m, :loglevel) > 100) && println("updated partition var selection => $(m.disc_vars)") return end -function update_disc_int_var(m::AlpineNonlinearModel) +function update_disc_int_var(m::Optimizer) length(m.candidate_disc_vars) <= 15 && return # Algorithm Separation Point @@ -57,30 +57,30 @@ end One-time rounding heuristic to obtain a feasible solution For integer solutions """ -function heu_basic_rounding(m::AlpineNonlinearModel, local_model) +function heu_basic_rounding(m::Optimizer, relaxed_sol) println("Basic Rounding Heuristic Activated...") - convertor = Dict(:Max=>:>, :Min=>:<) + convertor = Dict(MOI.MAX_SENSE => :>, MOI.MIN_SENSE => :<) - rounded_sol = round_sol(m, nlp_model=local_model) + rounded_sol = round_sol(m, relaxed_sol) l_var, u_var = fix_domains(m, discrete_sol = rounded_sol) - heuristic_model = interface_init_nonlinear_model(m.nlp_solver) - interface_load_nonlinear_model(m, heuristic_model, l_var, u_var) - interface_optimize(heuristic_model) - heuristic_model_status = interface_get_status(heuristic_model) + heuristic_model = MOI.instantiate(get_option(m, :nlp_solver), with_bridge_type=Float64) + x = load_nonlinear_model(m, heuristic_model, l_var, u_var) + MOI.optimize!(heuristic_model) + heuristic_model_status = MOI.get(heuristic_model, MOI.TerminationStatus()) - if heuristic_model_status in [:Infeasible, :Error] - m.loglevel > 0 && println("Rounding obtained an Infeasible point.") + if heuristic_model_status == MOI.OTHER_ERROR || heuristic_model_status in STATUS_INF + get_option(m, :loglevel) > 0 && println("Rounding obtained an Infeasible point.") push!(m.logs[:obj], "INF") - return :Infeasibles - elseif heuristic_model_status in [:Optimal, :Suboptimal, :UserLimit, :LocalOptimal] - candidate_obj = interface_get_objval(heuristic_model) - candidate_sol = round.(interface_get_solution(heuristic_model), 5) + return MOI.LOCALLY_INFEASIBLE + elseif heuristic_model_status in STATUS_OPT || heuristic_model_status in STATUS_LIMIT + candidate_obj = MOI.get(heuristic_model, MOI.ObjectiveValue()) + candidate_sol = round.(MOI.get(heuristic_model, MOI.VariablePrimal(), x), 5) update_incumb_objective(m, candidate_obj, candidate_sol) - m.loglevel > 0 && println("Rounding obtained a feasible solution OBJ = $(m.best_obj)") - return :LocalOptimal + get_option(m, :loglevel) > 0 && println("Rounding obtained a feasible solution OBJ = $(m.best_obj)") + return MOI.LOCALLY_SOLVED else error("[EXCEPTION] Unknown NLP solver status.") end @@ -91,31 +91,31 @@ end """ Use solutions from the MIP solution pool as starting points """ -function heu_pool_multistart(m::AlpineNonlinearModel) +function heu_pool_multistart(m::Optimizer) - convertor = Dict(:Max=>:>, :Min=>:<) - m.sense_orig == :Min ? incumb_obj = Inf : incumb_obj = -Inf + convertor = Dict(MOI.MAX_SENSE => :>, MOI.MIN_SENSE => :<) + is_min_sense(m) ? incumb_obj = Inf : incumb_obj = -Inf incumb_sol = [] found_feasible = false for i in 1:m.bound_sol_pool[:cnt] if !m.bound_sol_pool[:ubstart][i] - rounded_sol = round_sol(m, nlp_sol=m.bound_sol_pool[:sol][i]) + rounded_sol = round_sol(m, m.bound_sol_pool[:sol][i]) l_var, u_var = fix_domains(m, discrete_sol=rounded_sol, use_orig=true) - heuristic_model = interface_init_nonlinear_model(m.nlp_solver) - interface_load_nonlinear_model(m, heuristic_model, l_var, u_var) - interface_optimize(heuristic_model) - heuristic_model_status = interface_get_status(heuristic_model) - if heuristic_model_status in [:Optimal, :Suboptimal, :UserLimit, :LocalOptimal] - candidate_obj = interface_get_objval(heuristic_model) + heuristic_model = MOI.instantiate(get_option(m, :nlp_solver), with_bridge_type=Float64) + x = load_nonlinear_model(m, heuristic_model, l_var, u_var) + MOI.optimize!(heuristic_model) + heuristic_model_status = MOI.get(heuristic_model, MOI.TerminationStatus()) + if heuristic_model_status in STATUS_OPT || heuristic_model_status in STATUS_LIMIT + candidate_obj = MOI.get(heuristic_model, MOI.ObjectiveValue()) if eval(convertor[m.sense_orig])(candidate_obj, incumb_obj) incumb_obj = candidate_obj - incumb_sol = round.(interface_get_solution(heuristic_model), 5) - m.loglevel > 0 && println("Feasible solution obtained using lower bound solution pool [SOL:$(i)] [OBJ=$(incumb_obj)]") + incumb_sol = round.(MOI.get(heuristic_model, MOI.VariablePrimal(), x), 5) + get_option(m, :loglevel) > 0 && println("Feasible solution obtained using lower bound solution pool [SOL:$(i)] [OBJ=$(incumb_obj)]") end found_feasible = true else - m.loglevel > 99 && println("Multi-start heuristic returns $(heuristic_model_status) [SOL:$(i)]") + get_option(m, :loglevel) > 99 && println("Multi-start heuristic returns $(heuristic_model_status) [SOL:$(i)]") end m.bound_sol_pool[:ubstart][i] = true end @@ -123,8 +123,8 @@ function heu_pool_multistart(m::AlpineNonlinearModel) if found_feasible update_incumb_objective(m, incumb_obj, incumb_sol) - return :LocalOptimal + return MOI.LOCALLY_SOLVED end - return :Infeasible + return MOI.LOCALLY_INFEASIBLE end diff --git a/src/log.jl b/src/log.jl index 0334e6bb..c007a81b 100644 --- a/src/log.jl +++ b/src/log.jl @@ -4,9 +4,9 @@ function create_logs!(m) logs = Dict{Symbol,Any}() # Timers - logs[:presolve_time] = 0. # Total presolve-time of the algorithm - logs[:total_time] = 0. # Total run-time of the algorithm - logs[:time_left] = m.timeout # Total remaining time of the algorithm if time-out is specified + logs[:presolve_time] = 0. # Total presolve-time of the algorithm + logs[:total_time] = 0. # Total run-time of the algorithm + logs[:time_left] = get_option(m, :timeout) # Total remaining time of the algorithm if time-out is specified # Values logs[:obj] = [] # Iteration-based objective @@ -22,15 +22,15 @@ function create_logs!(m) m.logs = logs end -function reset_timer(m::AlpineNonlinearModel) +function reset_timer(m::Optimizer) m.logs[:total_time] = 0. - m.logs[:time_left] = m.timeout + m.logs[:time_left] = get_option(m, :timeout) return m end -function logging_summary(m::AlpineNonlinearModel) +function logging_summary(m::Optimizer) - if m.loglevel > 0 + if get_option(m, :loglevel) > 0 # println("Problem sense $(m.sense_orig)") printstyled("\nPROBLEM STATISTICS\n", color=:cyan) println(" #Variables = ", length([i for i in 1:m.num_var_orig if m.var_type[i] == :Cont]) + length([i for i in 1:m.num_var_orig if m.var_type[i] == :Bin]) + length([i for i in 1:m.num_var_orig if m.var_type[i] == :Int])) @@ -39,7 +39,7 @@ function logging_summary(m::AlpineNonlinearModel) println(" #NL Constraints = ", m.num_nlconstr_orig) println(" #Linear Constraints = ", m.num_lconstr_orig) # println(" #Int variables = ", length([i for i in 1:m.num_var_orig if m.var_type[i] == :Int])) - m.recognize_convex && println(" #Detected convex constraints = $(length([i for i in m.constr_structure if i == :convex]))") + get_option(m, :recognize_convex) && println(" #Detected convex constraints = $(length([i for i in m.constr_structure if i == :convex]))") println(" #Detected nonlinear terms = ", length(m.nonconvex_terms)) # for i in ALPINE_C_NLTERMS # cnt = length([1 for j in keys(m.nonconvex_terms) if m.nonconvex_terms[j][:nonlinear_type] == i]) @@ -49,56 +49,56 @@ function logging_summary(m::AlpineNonlinearModel) println(" #Potential variables for partitioning = ", length(m.disc_vars)) printstyled("SUB-SOLVERS USED BY ALPINE\n", color=:cyan) - # m.minlp_solver != UnsetSolver() && println("MINLP local solver = ", split(string(m.minlp_solver),".")[1]) - if string(m.minlp_solver) == "Alpine.UnsetSolver()" - println(" NLP local solver = ", split(string(m.nlp_solver),"S")[1]) - else - println(" MINLP local solver = ", split(string(m.minlp_solver),".")[1]) + # get_option(m, :minlp_solver) !== nothing && println("MINLP local solver = ", split(string(get_option(m, :minlp_solver)),".")[1]) + if get_option(m, :minlp_solver) === nothing + println(" NLP local solver = ", split(string(get_option(m, :nlp_solver)),"S")[1]) + else + println(" MINLP local solver = ", split(string(get_option(m, :minlp_solver)),".")[1]) end - println(" MIP solver = ", split(string(m.mip_solver),"S")[1]) + println(" MIP solver = ", split(string(get_option(m, :mip_solver)),"S")[1]) printstyled("ALPINE CONFIGURATION\n", color=:cyan) - println(" Maximum solution time = ", m.timeout) - println(" Maximum iterations = ", m.maxiter) - # @printf " Relative optimality gap criteria = %.5f (%.4f %%)\n" m.relgap (m.relgap*100) - @printf " Relative optimality gap criteria = %.4f%%\n" m.relgap*100 - # m.recognize_convex && println(" actively recognize convex patterns") - # println(" Basic bound propagation = ", m.presolve_bp) - if m.disc_var_pick == 0 + println(" Maximum solution time = ", get_option(m, :timeout)) + println(" Maximum iterations = ", get_option(m, :maxiter)) + # @printf " Relative optimality gap criteria = %.5f (%.4f %%)\n" get_option(m, :relgap) (get_option(m, :relgap)*100) + @printf " Relative optimality gap criteria = %.4f%%\n" get_option(m, :relgap)*100 + # get_option(m, :recognize_convex) && println(" actively recognize convex patterns") + # println(" Basic bound propagation = ", get_option(m, :presolve_bp)) + if get_option(m, :disc_var_pick) == 0 println(" Potential variables chosen for partitioning = All") - elseif m.disc_var_pick == 1 + elseif get_option(m, :disc_var_pick) == 1 println(" Potential variables chosen for partitioning = Min. vertex cover") end - # println(" Conseuctive solution rejection = after ", m.disc_consecutive_forbid, " times") - if m.disc_ratio_branch + # println(" Conseuctive solution rejection = after ", get_option(m, :disc_consecutive_forbid), " times") + if get_option(m, :disc_ratio_branch) println(" Discretization ratio branch activated") else - println(" Discretization ratio = ", m.disc_ratio) + println(" Discretization ratio = ", get_option(m, :disc_ratio)) end - (m.convhull_ebd) && println(" Using convhull_ebd formulation") - (m.convhull_ebd) && println(" Encoding method = $(m.convhull_ebd_encode)") - (m.convhull_ebd) && println(" Independent branching scheme = $(m.convhull_ebd_ibs)") - println(" Bound-tightening presolve = ", m.presolve_bt) - m.presolve_bt && println(" Presolve maximum iterations = ", m.presolve_maxiter) - # m.presolve_bt && println("bound tightening presolve algorithm = ", m.presolve_bt_algo) - # m.presolve_bt && println("bound tightening presolve width tolerance = ", m.presolve_bt_width_tol) - # m.presolve_bt && println("bound tightening presolve output tolerance = ", m.presolve_bt_output_tol) - # m.presolve_bt && println("bound tightening presolve relaxation = ", m.presolve_bt_relax) - # m.presolve_bt && println("bound tightening presolve mip regulation time = ", m.presolve_bt_mip_timeout) + (get_option(m, :convhull_ebd)) && println(" Using convhull_ebd formulation") + (get_option(m, :convhull_ebd)) && println(" Encoding method = $(get_option(m, :convhull_ebd_encode))") + (get_option(m, :convhull_ebd)) && println(" Independent branching scheme = $(get_option(m, :convhull_ebd_ibs))") + println(" Bound-tightening presolve = ", get_option(m, :presolve_bt)) + get_option(m, :presolve_bt) && println(" Presolve maximum iterations = ", get_option(m, :presolve_maxiter)) + # get_option(m, :presolve_bt) && println("bound tightening presolve algorithm = ", get_option(m, :presolve_bt)_algo) + # get_option(m, :presolve_bt) && println("bound tightening presolve width tolerance = ", get_option(m, :presolve_bt)_width_tol) + # get_option(m, :presolve_bt) && println("bound tightening presolve output tolerance = ", get_option(m, :presolve_bt)_output_tol) + # get_option(m, :presolve_bt) && println("bound tightening presolve relaxation = ", get_option(m, :presolve_bt)_relax) + # get_option(m, :presolve_bt) && println("bound tightening presolve mip regulation time = ", get_option(m, :presolve_bt)_mip_timeout) # println("\n=======================================================================") end # Additional warnings - m.mip_solver_id == "Gurobi" && @warn "Alpine only supports Gurobi v7.0+ ..." + #get_option(m, :mip_solver_id) == "Gurobi" && @warn "Alpine only supports Gurobi v7.0+ ..." end -function logging_head(m::AlpineNonlinearModel) - if m.sense_orig == :Min +function logging_head(m::Optimizer) + if is_min_sense(m) printstyled("LOWER-BOUNDING ITERATIONS", color=:cyan) UB_iter = "Incumbent" UB = "Best Incumbent" LB = "Lower Bound" - elseif m.sense_orig == :Max + elseif is_max_sense(m) printstyled("UPPER-BOUNDING ITERATIONS", color=:cyan) UB_iter = "Incumbent" UB = "Best Incumbent" @@ -112,7 +112,7 @@ function logging_head(m::AlpineNonlinearModel) end end -function logging_row_entry(m::AlpineNonlinearModel; kwargs...) +function logging_row_entry(m::Optimizer; kwargs...) options = Dict(kwargs) @@ -172,13 +172,12 @@ end # Create dictionary of statuses for Alpine algorithm function create_status!(m) - status = Dict{Symbol,Symbol}() + status = Dict{Symbol,MOI.TerminationStatusCode}() - status[:presolve] = :none # Status of presolve - status[:local_solve] = :none # Status of local solve - status[:bounding_solve] = :none # Status of bounding solve - status[:feasible_solution] = :none # Status of whether a upper bound is detected or not - status[:bound] = :none # Status of whether a bound has been detected + status[:local_solve] = MOI.OPTIMIZE_NOT_CALLED # Status of local solve + status[:bounding_solve] = MOI.OPTIMIZE_NOT_CALLED # Status of bounding solve + m.detected_feasible_solution = false + m.detected_bound = false m.status = status end @@ -188,7 +187,7 @@ This function summarizes the eventual solver status based on all available infor recorded in the solver. The output status is self-defined which requires users to read our documentation to understand the details behind every status symbols. """ -function summary_status(m::AlpineNonlinearModel) +function summary_status(m::Optimizer) # Alpine Solver Status Definition # :Optimal : normal termination with optimality gap closed within time limits @@ -199,14 +198,14 @@ function summary_status(m::AlpineNonlinearModel) # happens when lower bound problem is extremely hard to solve # :Unknown : termination with no exception recorded - if m.status[:bound] == :Detected && m.status[:feasible_solution] == :Detected - m.best_rel_gap > m.relgap ? m.alpine_status = :UserLimits : m.alpine_status = :Optimal - elseif m.status[:bounding_solve] == :Infeasible - m.alpine_status = :Infeasible - elseif m.status[:bound] == :Detected && m.status[:feasible_solution] == :none - m.alpine_status = :UserLimits - elseif m.status[:bound] == :none && m.status[:feasible_solution] == :Detected - m.alpine_status = :Heuristic + if m.detected_bound && m.detected_feasible_solution + m.alpine_status = m.best_rel_gap > get_option(m, :relgap) ? MOI.OTHER_LIMIT : MOI.OPTIMAL + elseif m.status[:bounding_solve] == MOI.INFEASIBLE + m.alpine_status = MOI.INFEASIBLE + elseif m.detected_bound && !m.detected_feasible_solution + m.alpine_status = MOI.OTHER_LIMIT + elseif !m.detected_bound && m.detected_feasible_solution + m.alpine_status = MOI.LOCALLY_SOLVED else @warn " [EXCEPTION] Indefinite Alpine status. Please report your instance (& solver configuration) as an issue (https://github.com/lanl-ansi/Alpine.jl/issues) to help us make Alpine better." end diff --git a/src/matrix_opt_interface.jl b/src/matrix_opt_interface.jl new file mode 100644 index 00000000..67e89ad1 --- /dev/null +++ b/src/matrix_opt_interface.jl @@ -0,0 +1,48 @@ +# Taken from MatrixOptInterface.jl +@enum ConstraintSense EQUAL_TO GREATER_THAN LESS_THAN INTERVAL +_sense(::Type{<:MOI.EqualTo}) = EQUAL_TO +_sense(::Type{<:MOI.LessThan}) = LESS_THAN +_sense(::Type{<:MOI.GreaterThan}) = GREATER_THAN +_sense(::Type{<:MOI.Interval}) = INTERVAL + +_no_upper(bound) = bound != typemax(bound) +_no_lower(bound) = bound != typemin(bound) + +function _bound_sense(lb::T, ub::T) where T + if _no_upper(ub) + if _no_lower(lb) + if lb == ub + return EQUAL_TO + else + return INTERVAL + end + else + return LESS_THAN + end + else + if _no_lower(lb) + return GREATER_THAN + else + return + end + end +end +function _bound_set(lb::T, ub::T) where T + if _no_upper(ub) + if _no_lower(lb) + if ub == lb + return MOI.EqualTo(lb) + else + return MOI.Interval(lb, ub) + end + else + return MOI.LessThan(ub) + end + else + if _no_lower(lb) + return MOI.GreaterThan(lb) + else + return + end + end +end diff --git a/src/moi_function2expr.jl b/src/moi_function2expr.jl new file mode 100644 index 00000000..6bcab971 --- /dev/null +++ b/src/moi_function2expr.jl @@ -0,0 +1,62 @@ +function _constraint_expr(expr, set::MOI.Interval) + return Expr(:comparison, set.lower, :(<=), expr, :(<=), set.upper) +end + +_sense(::MOI.EqualTo) = :(==) +_sense(::MOI.LessThan) = :(<=) +_sense(::MOI.GreaterThan) = :(>=) +function _constraint_expr(expr, set) + return Expr(:call, _sense(set), expr, MOI.constant(set)) +end + +_variable_index_to_expr(v::MOI.VariableIndex) = Expr(:ref, :x, v.value) + +function _add_constant(expr::Expr, constant) + if !iszero(constant) + push!(expr.args, constant) + end +end + +function _term_to_expr(t::MOI.ScalarAffineTerm) + return Expr(:call, :*, t.coefficient, _variable_index_to_expr(t.variable_index)) +end + +function _term_to_expr(t::MOI.ScalarQuadraticTerm) + coef = t.coefficient + if t.variable_index_1 == t.variable_index_2 + coef /= 2 + end + return Expr(:call, :*, coef, _variable_index_to_expr(t.variable_index_1), _variable_index_to_expr(t.variable_index_2)) +end + +function _add_terms(expr::Expr, terms::Vector) + for term in terms + push!(expr.args, _term_to_expr(term)) + end +end + +function _moi_function_to_expr(f::MOI.ScalarAffineFunction) + iszero(f) && return 0 # Similar to `JuMP.affToExpr` in JuMP v0.18 and earlier + expr = Expr(:call, :+) + _add_terms(expr, f.terms) + _add_constant(expr, f.constant) + return expr +end + +function _moi_function_to_expr(t::MOI.ScalarQuadraticTerm) + return Expr( + :call, :*, + MOI.coefficient(t), + _variable_index_to_expr(t.variable_index_1), + _variable_index_to_expr(t.variable_index_2) + ) +end + +function _moi_function_to_expr(f::MOI.ScalarQuadraticFunction) + iszero(f) && return 0 # Similar to `JuMP.quadToExpr` in JuMP v0.18 and earlier + expr = Expr(:call, :+) + _add_terms(expr, f.quadratic_terms) + _add_terms(expr, f.affine_terms) + _add_constant(expr, f.constant) + return expr +end diff --git a/src/mpb2moi.jl b/src/mpb2moi.jl deleted file mode 100644 index bbe7a9f2..00000000 --- a/src/mpb2moi.jl +++ /dev/null @@ -1,83 +0,0 @@ -# This file carries the goal of getting ready to transit from MPB interface to MOI interface -# We wrap the functions -function interface_init_nonlinear_model(solver::Any) - return MathProgBase.NonlinearModel(solver) -end - -function interface_init_nonlinear_data(nonlinear_model::MathProgBase.AbstractNLPEvaluator) - MathProgBase.initialize(nonlinear_model, [:Grad, :Jac, :Hess, :HessVec, :ExprGraph]) # Safety scheme for sub-solvers re-initializing the NLPEvaluator - return -end - -function interface_load_nonlinear_model(m::AlpineNonlinearModel, nonlinear_model::Any, l_var::Vector, u_var::Vector) - MathProgBase.loadproblem!(nonlinear_model, m.num_var_orig, - m.num_constr_orig, - l_var, - u_var, - m.l_constr_orig, - m.u_constr_orig, - m.sense_orig, - m.d_orig) - - return -end - -function interface_set_warmstart(nonlinear_model::Any, startval::Vector{Float64}) - MathProgBase.setwarmstart!(nonlinear_model, startval) - return -end - -function interface_set_vartype(nonlinear_model::Any, vartype::Vector) - MathProgBase.setvartype!(nonlinear_model, vartype) - return -end - -function interface_optimize(nonlinear_model::Any) - MathProgBase.optimize!(nonlinear_model) - return -end - -function interface_get_status(nonlinear_model::Any) - return MathProgBase.status(nonlinear_model) -end - -function interface_get_solution(nonlinear_model::Any) - return MathProgBase.getsolution(nonlinear_model) -end - -function interface_get_objval(nonlinear_model::Any) - return MathProgBase.getobjval(nonlinear_model) -end - -function interface_get_obj_expr(nonlinear_model::MathProgBase.AbstractNLPEvaluator) - return MathProgBase.obj_expr(nonlinear_model) -end - -function interface_get_constr_expr(nonlinear_model::MathProgBase.AbstractNLPEvaluator, idx::Int) - return MathProgBase.constr_expr(nonlinear_model, idx) -end - -function interface_is_constr_linear(nonlinear_model::MathProgBase.AbstractNLPEvaluator, idx::Int) - return MathProgBase.isconstrlinear(nonlinear_model, idx) -end - -function interface_is_obj_linear(nonlinear_model::MathProgBase.AbstractNLPEvaluator) - return MathProgBase.isobjlinear(nonlinear_model) -end - -function interface_eval_g(nonlinear_model::MathProgBase.AbstractNLPEvaluator, rhs, sol) - MathProgBase.eval_g(nonlinear_model, rhs, sol) - return -end - -function interface_get_rawsolver(m::JuMP.Model) - return MathProgBase.getrawsolver(internalmodel(m)) -end - -MathProgBase.setwarmstart!(m::AlpineNonlinearModel, x) = (m.var_start_orig = x) -MathProgBase.setvartype!(m::AlpineNonlinearModel, v::Vector{Symbol}) = (m.var_type_orig = v) -MathProgBase.status(m::AlpineNonlinearModel) = m.alpine_status -MathProgBase.getobjval(m::AlpineNonlinearModel) = m.best_obj -MathProgBase.getobjbound(m::AlpineNonlinearModel) = m.best_bound -MathProgBase.getsolution(m::AlpineNonlinearModel) = m.best_sol -MathProgBase.getsolvetime(m::AlpineNonlinearModel) = m.logs[:total_time] diff --git a/src/multi.jl b/src/multi.jl index 57235fa0..110c8181 100644 --- a/src/multi.jl +++ b/src/multi.jl @@ -1,4 +1,4 @@ -function amp_post_convhull(m::AlpineNonlinearModel; kwargs...) +function amp_post_convhull(m::Optimizer; kwargs...) options = Dict(kwargs) haskey(options, :use_disc) ? d = options[:use_disc] : d = m.discretization @@ -31,12 +31,12 @@ function amp_post_convhull(m::AlpineNonlinearModel; kwargs...) end # Experimental code for Warm starting - m.convhull_warmstart && !isempty(m.best_bound_sol) && amp_warmstart_α(m, α) + get_option(m, :convhull_warmstart) && !isempty(m.best_bound_sol) && amp_warmstart_α(m, α) return end -function amp_convexify_multilinear(m::AlpineNonlinearModel, k::Any, λ::Dict, α::Dict, discretization::Dict) +function amp_convexify_multilinear(m::Optimizer, k::Any, λ::Dict, α::Dict, discretization::Dict) m.nonconvex_terms[k][:convexified] = true # Bookeeping the convexified terms @@ -49,7 +49,7 @@ function amp_convexify_multilinear(m::AlpineNonlinearModel, k::Any, λ::Dict, α return λ, α end -function amp_convexify_monomial(m::AlpineNonlinearModel, k::Any, λ::Dict, α::Dict, discretization::Dict) +function amp_convexify_monomial(m::Optimizer, k::Any, λ::Dict, α::Dict, discretization::Dict) m.nonconvex_terms[k][:convexified] = true # Bookeeping the convexified terms @@ -62,7 +62,7 @@ function amp_convexify_monomial(m::AlpineNonlinearModel, k::Any, λ::Dict, α::D return λ, α end -function amp_convexify_binlin(m::AlpineNonlinearModel, k::Any, β::Dict) +function amp_convexify_binlin(m::Optimizer, k::Any, β::Dict) m.nonconvex_terms[k][:convexified] = true # Bookeeping the convexified terms @@ -73,7 +73,7 @@ function amp_convexify_binlin(m::AlpineNonlinearModel, k::Any, β::Dict) if haskey(β, lift_idx) return β else - β[lift_idx] = Variable(m.model_mip, lift_idx) + β[lift_idx] = _index_to_variable_ref(m.model_mip, lift_idx) end bin_idx = [i for i in m.nonconvex_terms[k][:var_idxs] if m.var_type[i] == :Bin] @@ -84,16 +84,16 @@ function amp_convexify_binlin(m::AlpineNonlinearModel, k::Any, β::Dict) bin_idx = bin_idx[1] cont_idx = cont_idx[1] - mccormick_binlin(m.model_mip, Variable(m.model_mip, lift_idx), - Variable(m.model_mip, bin_idx), Variable(m.model_mip, cont_idx), + mccormick_binlin(m.model_mip, _index_to_variable_ref(m.model_mip, lift_idx), + _index_to_variable_ref(m.model_mip, bin_idx), _index_to_variable_ref(m.model_mip, cont_idx), m.l_var_tight[cont_idx], m.u_var_tight[cont_idx]) return β end -amp_convexify_binint(m::AlpineNonlinearModel, k::Any, β::Dict) = amp_convexify_binlin(m, k, β) +amp_convexify_binint(m::Optimizer, k::Any, β::Dict) = amp_convexify_binlin(m, k, β) -function amp_convexify_binprod(m::AlpineNonlinearModel, k::Any, β::Dict) +function amp_convexify_binprod(m::Optimizer, k::Any, β::Dict) m.nonconvex_terms[k][:convexified] = true # Bookeeping the convexified terms @@ -101,11 +101,11 @@ function amp_convexify_binprod(m::AlpineNonlinearModel, k::Any, β::Dict) if haskey(β, lift_idx) return β # Already constructed else - β[lift_idx] = Variable(m.model_mip, lift_idx) + β[lift_idx] = _index_to_variable_ref(m.model_mip, lift_idx) end - z = Variable(m.model_mip, m.nonconvex_terms[k][:y_idx]) - x = [Variable(m.model_mip, i) for i in m.nonconvex_terms[k][:var_idxs]] + z = _index_to_variable_ref(m.model_mip, m.nonconvex_terms[k][:y_idx]) + x = [_index_to_variable_ref(m.model_mip, i) for i in m.nonconvex_terms[k][:var_idxs]] for i in x @constraint(m.model_mip, z <= i) end @@ -117,7 +117,7 @@ end """ Method for general nonlinear terms """ -function amp_convhull_prepare(m::AlpineNonlinearModel, d::Dict, nonlinear_key::Any; monomial=false) +function amp_convhull_prepare(m::Optimizer, d::Dict, nonlinear_key::Any; monomial=false) counted_var = [] # Keep both vector and set for collection sake id = Set() # Coverting the nonlinear indices into a set @@ -152,14 +152,14 @@ end """ Method for integers """ -function amp_convhull_prepare(m::AlpineNonlinearModel, d::Dict, idx::Int) +function amp_convhull_prepare(m::Optimizer, d::Dict, idx::Int) return [idx], tuple(length(d[idx])), length(d[idx]) end """ Method for general nonlinear terms """ -function amp_convhull_λ(m::AlpineNonlinearModel, nonlinear_key::Any, indices::Any, λ::Dict, ext_cnt::Int, dim::Tuple) +function amp_convhull_λ(m::Optimizer, nonlinear_key::Any, indices::Any, λ::Dict, ext_cnt::Int, dim::Tuple) y_idx = m.nonconvex_terms[nonlinear_key][:y_idx] @@ -167,7 +167,7 @@ function amp_convhull_λ(m::AlpineNonlinearModel, nonlinear_key::Any, indices::A λ[indices] = Dict(:dim=>dim, :lifted_var_idx=>y_idx, :indices=>reshape([1:ext_cnt;], dim), - :vars=>@variable(m.model_mip, [1:ext_cnt], lowerbound=0, basename="L$(y_idx)"), + :vars=>@variable(m.model_mip, [1:ext_cnt], lower_bound=0, base_name="L$(y_idx)"), :vals=>ones(dim)) return λ @@ -176,7 +176,7 @@ end """ Method for power terms """ -function populate_convhull_extreme_values(m::AlpineNonlinearModel, d::Dict, mono_idx::Int, λ::Dict, p::Int) +function populate_convhull_extreme_values(m::Optimizer, d::Dict, mono_idx::Int, λ::Dict, p::Int) λ[mono_idx][:vals] = [d[mono_idx][i]^p for i in 1:length(d[mono_idx])] return λ end @@ -184,7 +184,7 @@ end """ Method for regular muiltilinear terms """ -function populate_convhull_extreme_values(m::AlpineNonlinearModel, discretization::Dict, indices::Any, λ::Dict, dim::Tuple, locator::Array, level::Int=1) +function populate_convhull_extreme_values(m::Optimizer, discretization::Dict, indices::Any, λ::Dict, dim::Tuple, locator::Array, level::Int=1) if level > length(dim) @assert length(indices) == length(dim) @@ -210,20 +210,20 @@ end """ General Method for all term """ -function amp_convhull_α(m::AlpineNonlinearModel, indices::Any, α::Dict, dim::Tuple, discretization::Dict) +function amp_convhull_α(m::Optimizer, indices::Any, α::Dict, dim::Tuple, discretization::Dict) for i in indices if !(i in keys(α)) lambda_cnt = length(discretization[i]) partition_cnt = length(discretization[i]) - 1 - if m.convhull_ebd && partition_cnt > 2 + if get_option(m, :convhull_ebd) && partition_cnt > 2 αCnt = Int(ceil(log(2,partition_cnt))) - α[i] = @variable(m.model_mip, [1:αCnt], Bin, basename=string("YL",i)) + α[i] = @variable(m.model_mip, [1:αCnt], Bin, base_name=string("YL",i)) else - α[i] = @variable(m.model_mip, [1:partition_cnt], Bin, basename="A$(i)") + α[i] = @variable(m.model_mip, [1:partition_cnt], Bin, base_name="A$(i)") @constraint(m.model_mip, sum(α[i]) == 1) - @constraint(m.model_mip, Variable(m.model_mip, i) >= sum(α[i][j]*discretization[i][j] for j in 1:lambda_cnt-1)) # Add x = f(α) for regulating the domains - @constraint(m.model_mip, Variable(m.model_mip, i) <= sum(α[i][j-1]*discretization[i][j] for j in 2:lambda_cnt)) + @constraint(m.model_mip, _index_to_variable_ref(m.model_mip, i) >= sum(α[i][j]*discretization[i][j] for j in 1:lambda_cnt-1)) # Add x = f(α) for regulating the domains + @constraint(m.model_mip, _index_to_variable_ref(m.model_mip, i) <= sum(α[i][j-1]*discretization[i][j] for j in 2:lambda_cnt)) end end end @@ -231,9 +231,9 @@ function amp_convhull_α(m::AlpineNonlinearModel, indices::Any, α::Dict, dim::T return α end -amp_convhull_α(m::AlpineNonlinearModel, idx::Int, α::Dict, dim, d::Dict) = amp_convhull_α(m, [idx], α, dim, d) +amp_convhull_α(m::Optimizer, idx::Int, α::Dict, dim, d::Dict) = amp_convhull_α(m, [idx], α, dim, d) -function amp_no_good_cut_α(m::AlpineNonlinearModel, α::Dict) +function amp_no_good_cut_α(m::Optimizer, α::Dict) println("Global Incumbent solution objective = $(m.best_obj)") @@ -243,7 +243,7 @@ function amp_no_good_cut_α(m::AlpineNonlinearModel, α::Dict) no_good_idxs = keys(m.bound_sol_pool[:disc][i]) no_good_size = length(no_good_idxs) - 1 @constraint(m.model_mip, sum(α[v][m.bound_sol_pool[:disc][i][v]] for v in no_good_idxs) <= no_good_size) - m.loglevel > 0 && println("!! GLOBAL cuts off POOL_SOL-$(i) POOL_OBJ=$(m.bound_sol_pool[:obj][i])!") + get_option(m, :loglevel) > 0 && println("!! GLOBAL cuts off POOL_SOL-$(i) POOL_OBJ=$(m.bound_sol_pool[:obj][i])!") m.bound_sol_pool[:stat][i] = :Cutoff end end @@ -251,14 +251,14 @@ function amp_no_good_cut_α(m::AlpineNonlinearModel, α::Dict) return end -function amp_warmstart_α(m::AlpineNonlinearModel, α::Dict) +function amp_warmstart_α(m::Optimizer, α::Dict) d = m.discretization if m.bound_sol_pool[:cnt] >= 2 # can only warm-start the problem when pool is large enough ws_idx = -1 - m.sense_orig == :Min ? ws_obj = Inf : ws_obj = -Inf - comp_opr = Dict(:Min=>:<, :Max=>:>) + is_min_sense(m) ? ws_obj = Inf : ws_obj = -Inf + comp_opr = Dict(MOI.MIN_SENSE => :<, MOI.MAX_SENSE => :>) # Search for the pool for incumbent warm starter for i in 1:m.bound_sol_pool[:cnt] @@ -278,7 +278,7 @@ function amp_warmstart_α(m::AlpineNonlinearModel, α::Dict) end end m.bound_sol_pool[:stat][ws_idx] = :Warmstarter - m.loglevel > 0 && println("!! WARM START bounding MIP using POOL SOL $(ws_idx) OBJ=$(m.bound_sol_pool[:obj][ws_idx])") + get_option(m, :loglevel) > 0 && println("!! WARM START bounding MIP using POOL SOL $(ws_idx) OBJ=$(m.bound_sol_pool[:obj][ws_idx])") end end @@ -288,11 +288,11 @@ end """ Method for general multilinear terms with/without integer variables """ -function amp_post_convhull_constrs(m::AlpineNonlinearModel, λ::Dict, α::Dict, indices::Any, dim::Tuple, ext_cnt::Int, d::Dict) +function amp_post_convhull_constrs(m::Optimizer, λ::Dict, α::Dict, indices::Any, dim::Tuple, ext_cnt::Int, d::Dict) # Adding λ constraints @constraint(m.model_mip, sum(λ[indices][:vars]) == 1) - @constraint(m.model_mip, Variable(m.model_mip, λ[indices][:lifted_var_idx]) == dot(λ[indices][:vars], reshape(λ[indices][:vals], ext_cnt))) + @constraint(m.model_mip, _index_to_variable_ref(m.model_mip, λ[indices][:lifted_var_idx]) == dot(λ[indices][:vars], reshape(λ[indices][:vals], ext_cnt))) # Add links on each dimension for (cnt, i) in enumerate(indices) @@ -303,7 +303,7 @@ function amp_post_convhull_constrs(m::AlpineNonlinearModel, λ::Dict, α::Dict, error("EXCEPTION: unexpected variable type during integer related realxation") end sliced_indices = [collect_indices(λ[indices][:indices], cnt, [k], dim) for k in 1:l_cnt] # Add x = f(λ) for convex representation of x value - @constraint(m.model_mip, Variable(m.model_mip, i) == sum(dot(repeat([d[i][k]],length(sliced_indices[k])), λ[indices][:vars][sliced_indices[k]]) for k in 1:l_cnt)) + @constraint(m.model_mip, _index_to_variable_ref(m.model_mip, i) == sum(dot(repeat([d[i][k]],length(sliced_indices[k])), λ[indices][:vars][sliced_indices[k]]) for k in 1:l_cnt)) end return @@ -312,19 +312,19 @@ end """ Method for power-2 term """ -function amp_post_convhull_constrs(m::AlpineNonlinearModel, λ::Dict, α::Dict, monomial_idx::Int, dim::Tuple, discretization::Dict) +function amp_post_convhull_constrs(m::Optimizer, λ::Dict, α::Dict, monomial_idx::Int, dim::Tuple, discretization::Dict) partition_cnt = length(discretization[monomial_idx])-1 lambda_cnt = length(discretization[monomial_idx]) # Adding λ constraints @constraint(m.model_mip, sum(λ[monomial_idx][:vars]) == 1) - @constraint(m.model_mip, Variable(m.model_mip, λ[monomial_idx][:lifted_var_idx]) <= dot(λ[monomial_idx][:vars], λ[monomial_idx][:vals])) - @constraint(m.model_mip, Variable(m.model_mip, λ[monomial_idx][:lifted_var_idx]) >= Variable(m.model_mip, monomial_idx)^2) + @constraint(m.model_mip, _index_to_variable_ref(m.model_mip, λ[monomial_idx][:lifted_var_idx]) <= dot(λ[monomial_idx][:vars], λ[monomial_idx][:vals])) + @constraint(m.model_mip, _index_to_variable_ref(m.model_mip, λ[monomial_idx][:lifted_var_idx]) >= _index_to_variable_ref(m.model_mip, monomial_idx)^2) # Add SOS-2 Constraints with basic encoding - if m.convhull_ebd && partition_cnt > 2 - ebd_map = embedding_map(lambda_cnt, m.convhull_ebd_encode, m.convhull_ebd_ibs) + if get_option(m, :convhull_ebd) && partition_cnt > 2 + ebd_map = embedding_map(lambda_cnt, get_option(m, :convhull_ebd_encode), get_option(m, :convhull_ebd_ibs)) YCnt = Int(ebd_map[:L]) @assert YCnt == length(α[monomial_idx]) for i in 1:YCnt @@ -342,12 +342,12 @@ function amp_post_convhull_constrs(m::AlpineNonlinearModel, λ::Dict, α::Dict, end end # Add x = f(α) for regulating the domains - @constraint(m.model_mip, Variable(m.model_mip, monomial_idx) >= sum(α[monomial_idx][j]*discretization[monomial_idx][j] for j in 1:lambda_cnt-1)) - @constraint(m.model_mip, Variable(m.model_mip, monomial_idx) <= sum(α[monomial_idx][j-1]*discretization[monomial_idx][j] for j in 2:lambda_cnt)) + @constraint(m.model_mip, _index_to_variable_ref(m.model_mip, monomial_idx) >= sum(α[monomial_idx][j]*discretization[monomial_idx][j] for j in 1:lambda_cnt-1)) + @constraint(m.model_mip, _index_to_variable_ref(m.model_mip, monomial_idx) <= sum(α[monomial_idx][j-1]*discretization[monomial_idx][j] for j in 2:lambda_cnt)) end # Add x = f(λ) for convex representation - @constraint(m.model_mip, Variable(m.model_mip, monomial_idx) == dot(λ[monomial_idx][:vars], discretization[monomial_idx])) + @constraint(m.model_mip, _index_to_variable_ref(m.model_mip, monomial_idx) == dot(λ[monomial_idx][:vars], discretization[monomial_idx])) return end @@ -355,14 +355,14 @@ end """ Method for regular multilinear terms (terms that only has continuous variables) """ -function amp_post_inequalities_cont(m::AlpineNonlinearModel, discretization::Dict, λ::Dict, α::Dict, ml_indices::Any, dim::Tuple, var_ind::Int, cnt::Int) +function amp_post_inequalities_cont(m::Optimizer, discretization::Dict, λ::Dict, α::Dict, ml_indices::Any, dim::Tuple, var_ind::Int, cnt::Int) lambda_cnt = length(discretization[var_ind]) partition_cnt = lambda_cnt - 1 # Embedding formulation - if m.convhull_formulation == "sos2" && m.convhull_ebd && partition_cnt > 2 - ebd_map = embedding_map(lambda_cnt, m.convhull_ebd_encode, m.convhull_ebd_ibs) + if get_option(m, :convhull_formulation) == "sos2" && get_option(m, :convhull_ebd) && partition_cnt > 2 + ebd_map = embedding_map(lambda_cnt, get_option(m, :convhull_ebd_encode), get_option(m, :convhull_ebd_ibs)) YCnt = Int(ebd_map[:L]) @assert YCnt == length(α[var_ind]) for i in 1:YCnt @@ -371,12 +371,12 @@ function amp_post_inequalities_cont(m::AlpineNonlinearModel, discretization::Dic @constraint(m.model_mip, sum(λ[ml_indices][:vars][p_sliced_indices]) <= α[var_ind][i]) @constraint(m.model_mip, sum(λ[ml_indices][:vars][n_sliced_indices]) <= 1-α[var_ind][i]) end - m.convhull_ebd_link && ebd_link_xα(m, α[var_ind], lambda_cnt, discretization[var_ind], ebd_map[:H_orig], var_ind) + get_option(m, :convhull_ebd_link) && ebd_link_xα(m, α[var_ind], lambda_cnt, discretization[var_ind], ebd_map[:H_orig], var_ind) return end # SOS-2 Formulation - if m.convhull_formulation == "sos2" + if get_option(m, :convhull_formulation) == "sos2" for j in 1:lambda_cnt sliced_indices = collect_indices(λ[ml_indices][:indices], cnt, [j], dim) if (j == 1) @@ -388,7 +388,7 @@ function amp_post_inequalities_cont(m::AlpineNonlinearModel, discretization::Dic end end return - elseif m.convhull_formulation == "facet" + elseif get_option(m, :convhull_formulation) == "facet" for j in 1:(partition_cnt-1) # Constraint cluster of α >= f(λ) sliced_indices = collect_indices(λ[ml_indices][:indices], cnt, [1:j;], dim) @constraint(m.model_mip, sum(α[var_ind][1:j]) >= sum(λ[ml_indices][:vars][sliced_indices])) @@ -409,16 +409,16 @@ end [Experimental Function] Method for multilinear terms with discrete variables """ -function amp_post_inequalities_int(m::AlpineNonlinearModel, d::Dict, λ::Dict, α::Dict, indices::Any, dim::Tuple, var_ind::Int, cnt::Int) +function amp_post_inequalities_int(m::Optimizer, d::Dict, λ::Dict, α::Dict, indices::Any, dim::Tuple, var_ind::Int, cnt::Int) l_cnt = length(d[var_ind]) p_cnt = l_cnt - 1 # Embedding formulation - m.convhull_ebd && @warn "Embedding is currently not supported for multilinear terms with discrete variables" + get_option(m, :convhull_ebd) && @warn "Embedding is currently not supported for multilinear terms with discrete variables" # SOS-2 Formulation - if m.convhull_formulation == "sos2" + if get_option(m, :convhull_formulation) == "sos2" for j in 1:l_cnt sliced_indices = collect_indices(λ[indices][:indices], cnt, [j], dim) if (j == 1) @@ -487,7 +487,7 @@ function amp_collect_tight_regions(partvec::Vector) return tight_regions end -function amp_post_λ_upperbound(m::AlpineNonlinearModel, λ::Dict, indices::Any, dim::Tuple, d::Dict, tregions::Vector, reg=[], level=0) +function amp_post_λ_upperbound(m::Optimizer, λ::Dict, indices::Any, dim::Tuple, d::Dict, tregions::Vector, reg=[], level=0) if level == length(indices) isempty(tregions[level]) && return @@ -496,7 +496,7 @@ function amp_post_λ_upperbound(m::AlpineNonlinearModel, λ::Dict, indices::Any, sliced_indices = intersect(sliced_indices, Set(collect_indices(λ[indices][:indices], i, [reg[i],reg[i]+1], dim))) end for i in sliced_indices - setupperbound(λ[indices][:vars][i], (1/2)^level) + JuMP.set_upper_bound(λ[indices][:vars][i], (1/2)^level) end return end @@ -511,9 +511,9 @@ function amp_post_λ_upperbound(m::AlpineNonlinearModel, λ::Dict, indices::Any, return end -function amp_post_λ_upperbound(m::AlpineNonlinearModel, λ::Dict, indices::Any, ub::Float64) +function amp_post_λ_upperbound(m::Optimizer, λ::Dict, indices::Any, ub::Float64) - for i in λ[indices][:vars] setupperbound(i, ub) end + for i in λ[indices][:vars] JuMP.set_upper_bound(i, ub) end return end diff --git a/src/nlexpr.jl b/src/nlexpr.jl index e0e670b6..3ed049e4 100644 --- a/src/nlexpr.jl +++ b/src/nlexpr.jl @@ -3,7 +3,7 @@ process_expr(expr; kwargs...) High-level wrapper for processing expression with sub-tree operators """ -function process_expr(m::AlpineNonlinearModel) +function process_expr(m::Optimizer) expr_initialization(m) # S0 : initialize the space for parsing and analyzing expr_preprocess(m) # S1 : pre-process the negative sign in expressions @@ -17,7 +17,7 @@ end """ STEP 1: initialize the expression/ space """ -function expr_initialization(m::AlpineNonlinearModel) +function expr_initialization(m::Optimizer) # 0 : deepcopy data into mip lifted expr place holders m.bounding_obj_expr_mip = deepcopy(m.obj_expr_orig) @@ -34,7 +34,7 @@ end """ STEP 2: preprocess expression for trivial sub-trees and nasty pieces for easier later process """ -function expr_preprocess(m::AlpineNonlinearModel) +function expr_preprocess(m::Optimizer) expr_resolve_const(m.bounding_obj_expr_mip) expr_resolve_sign(m.bounding_obj_expr_mip) @@ -51,7 +51,7 @@ end """ STEP 3: parse expression for patterns on either the generic level or term level """ -function expr_parsing(m::AlpineNonlinearModel) +function expr_parsing(m::Optimizer) # Throw an error if obj. expression has non-integer exponents expr_isfracexp(m.bounding_obj_expr_mip) @@ -61,7 +61,7 @@ function expr_parsing(m::AlpineNonlinearModel) m.bounding_obj_expr_mip = expr_term_parsing(m.bounding_obj_expr_mip, 0, m) m.obj_structure = :generic_linear end - (m.loglevel > 199) && println("[OBJ] $(m.obj_expr_orig)") + (get_option(m, :loglevel) > 199) && println("[OBJ] $(m.obj_expr_orig)") for i in 1:m.num_constr_orig is_strucural = expr_constr_parsing(m.bounding_constr_expr_mip[i], m, i) @@ -69,7 +69,7 @@ function expr_parsing(m::AlpineNonlinearModel) m.bounding_constr_expr_mip[i] = expr_term_parsing(m.bounding_constr_expr_mip[i], i, m) m.constr_structure[i] = :generic_linear end - (m.loglevel > 199) && println("[CONSTR] $(m.constr_expr_orig[i])") + (get_option(m, :loglevel) > 199) && println("[CONSTR] $(m.constr_expr_orig[i])") end return @@ -78,19 +78,19 @@ end """ STEP 4: convert the parsed expressions into affine-based function that can be used for adding JuMP constraints """ -function expr_conversion(m::AlpineNonlinearModel) +function expr_conversion(m::Optimizer) if m.obj_structure == :generic_linear m.bounding_obj_mip = expr_linear_to_affine(m.bounding_obj_expr_mip) m.obj_structure = :affine end - m.loglevel > 199 && println("type :: ", m.obj_structure) - m.loglevel > 199 && println("lifted ::", m.bounding_obj_expr_mip) - m.loglevel > 199 && println("coeffs ::", m.bounding_obj_mip[:coefs]) - m.loglevel > 199 && println("vars ::", m.bounding_obj_mip[:vars]) - m.loglevel > 199 && println("sense ::", m.bounding_obj_mip[:sense]) - m.loglevel > 199 && println("rhs ::", m.bounding_obj_mip[:rhs]) - m.loglevel > 199 && println("----------------") + get_option(m, :loglevel) > 199 && println("type :: ", m.obj_structure) + get_option(m, :loglevel) > 199 && println("lifted ::", m.bounding_obj_expr_mip) + get_option(m, :loglevel) > 199 && println("coeffs ::", m.bounding_obj_mip[:coefs]) + get_option(m, :loglevel) > 199 && println("vars ::", m.bounding_obj_mip[:vars]) + get_option(m, :loglevel) > 199 && println("sense ::", m.bounding_obj_mip[:sense]) + get_option(m, :loglevel) > 199 && println("rhs ::", m.bounding_obj_mip[:rhs]) + get_option(m, :loglevel) > 199 && println("----------------") for i in 1:m.num_constr_orig @@ -98,13 +98,13 @@ function expr_conversion(m::AlpineNonlinearModel) m.bounding_constr_mip[i] = expr_linear_to_affine(m.bounding_constr_expr_mip[i]) m.constr_structure[i] = :affine end - m.loglevel > 199 && println("type :: ", m.constr_structure[i]) - m.loglevel > 199 && println("lifted ::", m.bounding_constr_expr_mip[i]) - m.loglevel > 199 && println("coeffs ::", m.bounding_constr_mip[i][:coefs]) - m.loglevel > 199 && println("vars ::", m.bounding_constr_mip[i][:vars]) - m.loglevel > 199 && println("sense ::", m.bounding_constr_mip[i][:sense]) - m.loglevel > 199 && println("rhs ::", m.bounding_constr_mip[i][:rhs]) - m.loglevel > 199 && println("----------------") + get_option(m, :loglevel) > 199 && println("type :: ", m.constr_structure[i]) + get_option(m, :loglevel) > 199 && println("lifted ::", m.bounding_constr_expr_mip[i]) + get_option(m, :loglevel) > 199 && println("coeffs ::", m.bounding_constr_mip[i][:coefs]) + get_option(m, :loglevel) > 199 && println("vars ::", m.bounding_constr_mip[i][:vars]) + get_option(m, :loglevel) > 199 && println("sense ::", m.bounding_constr_mip[i][:sense]) + get_option(m, :loglevel) > 199 && println("rhs ::", m.bounding_constr_mip[i][:rhs]) + get_option(m, :loglevel) > 199 && println("----------------") end return @@ -114,7 +114,7 @@ end """ STEP 5: collect measurements and information as needed for handy operations in the algorithm section """ -function expr_finalized(m::AlpineNonlinearModel) +function expr_finalized(m::Optimizer) collect_nonconvex_vars(m) m.candidate_disc_vars = sort(m.candidate_disc_vars) @@ -125,7 +125,7 @@ function expr_finalized(m::AlpineNonlinearModel) return m end -function collect_nonconvex_vars(m::AlpineNonlinearModel) +function collect_nonconvex_vars(m::Optimizer) # Walk through all nonconvex terms for i in keys(m.nonconvex_terms) @@ -143,6 +143,9 @@ function collect_nonconvex_vars(m::AlpineNonlinearModel) return end +isa_variable_index(expr::Expr) = length(expr.args == 2) && expr.args[2] == :(MathOptInterface.VariableIndex) +get_index(expr::Expr) = expr.args[2] + function expr_strip_const(expr, subs=[], rhs=0.0) exhaust_const = [!(expr.args[1] in [:+, :-]) || !(isa(expr.args[i], Float64) || isa(expr.args[i], Int)) for i in 2:length(expr.args)] @@ -183,21 +186,21 @@ function build_constr_block(y_idx::Int, var_idxs::Vector, operator::Symbol) end """ -expr_constr_parsing(expr, m::AlpineNonlinearModel) +expr_constr_parsing(expr, m::Optimizer) Recognize structural constraints. """ -function expr_constr_parsing(expr, m::AlpineNonlinearModel, idx::Int=0) +function expr_constr_parsing(expr, m::Optimizer, idx::Int=0) # First process user-defined structures in-cases of over-ride - for i in 1:length(m.constr_patterns) - is_strucural = eval(m.constr_patterns[i])(expr, m, idx) + for i in 1:length(get_option(m, :constr_patterns)) + is_strucural = eval(get_option(m, :constr_patterns)[i])(expr, m, idx) return end isa(expr, Number) && return false # Recognize built-in special structural pattern - if m.recognize_convex + if get_option(m, :recognize_convex) is_convex = resolve_convex_constr(expr, m, idx) is_convex && return true end @@ -381,7 +384,7 @@ By separating the structure with some dummy treatments """ function expr_resolve_sign(expr, level=0; kwargs...) - isa(expr, Number) && return + isa(expr, Number) && return resolver = Dict(:- => -1, :+ => 1) for i in 2:length(expr.args) if !isa(expr.args[i], Float64) && !isa(expr.args[i], Int) # Skip the coefficients @@ -414,7 +417,7 @@ Most issues can be caused by this function. """ function expr_flatten(expr, level=0; kwargs...) - isa(expr, Number) && return + isa(expr, Number) && return if level > 0 # No trivial constraint is allowed "3>5" flat = expr_arrangeargs(expr.args) if isa(flat, Number) @@ -465,13 +468,13 @@ function expr_arrangeargs(args::Array; kwargs...) if args[1] in [:^] return args - elseif args[1] in [:/] + elseif args[1] in [:/] # error("Alpine does not currently support `$(args[1])` operator") if (typeof(args[3]) == Float64) || (typeof(args[3]) == Int64) args = expr_resolve_divdenominator(args) - else + else error("Alpine does not currently support `$(args[1])` operator with a variable in the denominator") - end + end elseif args[1] in [:*, :+, :-] # Such generic operators can be handled else @@ -537,7 +540,7 @@ Check if a sub-tree is a constant or not """ function expr_resolve_const(expr) - isa(expr, Number) && return + isa(expr, Number) && return for i in 1:length(expr.args) if isa(expr.args[i], Float64) || isa(expr.args[i], Int) || isa(expr.args[i], Symbol) continue @@ -624,20 +627,20 @@ function expr_isaffine(expr) is_affine = false if expr.head == :call k=0 - for i = 1:length(expr.args) - if isa(expr.args[i], Number) + for i = 1:length(expr.args) + if isa(expr.args[i], Number) k+=1 continue end - if isa(expr.args[i], Symbol) + if isa(expr.args[i], Symbol) (expr.args[i] in [:+,:-]) && (k+=1) continue end if expr.args[i].head == :ref - k+=1 + k+=1 elseif expr.args[i].head == :call status = expr_isaffine(expr.args[i]) - (status == true) && (k+=1) + status && (k += 1) end end (k == length(expr.args)) && (is_affine = true) @@ -647,17 +650,17 @@ end """ Converts ((a_1*x[1])^2 + (a_2*x[2])^2 + ... + (a_n*x[n])^2) to (a_1^2*x[1]^2 + a_2^2*x[2]^2 + ... + a_n^2*x[n]^2) -Signs in the summation can be +/- -Note: This function does not support terms of type (a*(x[1] + x[2]))^2 yet. +Signs in the summation can be +/- +Note: This function does not support terms of type (a*(x[1] + x[2]))^2 yet. """ function expr_isolate_const(expr) expr_isaffine(expr) && return expr # Check nonlinear expressions - if (expr.head == :call && expr.args[1] in [:+,:-]) + if (expr.head == :call && expr.args[1] in [:+,:-]) expr_array = Any[] for i=2:length(expr.args) - ind = 0 + ind = 0 # Handle negative sign in the first term if (!isa(expr.args[i], Number)) && (expr.args[i].args[1] == :-) && (length(expr.args[i].args) == 2) @@ -676,7 +679,7 @@ function expr_isolate_const(expr) end # Handle nonlinear terms with coefficients within the exponent - elseif (expr.args[i].head == :call && expr_i.args[1] == :^ && expr_i.args[2].head == :call && isa(expr_i.args[2].args[2], Number) && isa(expr_i.args[3], Number)) + elseif (expr.args[i].head == :call && expr_i.args[1] == :^ && expr_i.args[2].head == :call && isa(expr_i.args[2].args[2], Number) && isa(expr_i.args[3], Number)) expr_tmp = Expr(:call, :^, expr_i.args[2].args[3], expr_i.args[3]) if ((expr.args[1] == :-) && (i > 2)) || (ind == 1) push!(expr_array, Expr(:call, :*, -expr_i.args[2].args[2] ^ expr_i.args[3], expr_tmp)) @@ -684,15 +687,15 @@ function expr_isolate_const(expr) push!(expr_array, Expr(:call, :*, expr_i.args[2].args[2] ^ expr_i.args[3], expr_tmp)) end - # Handle no-coefficients case + # Handle no-coefficients case elseif expr_i.args[1] == :^ && expr_i.args[2].head == :ref - if (expr.args[1] == :- && (i > 2)) || (ind == 1) + if (expr.args[1] == :- && (i > 2)) || (ind == 1) push!(expr_array, Expr(:call, :*, -1, expr_i)) else push!(expr_array, expr_i) end - # Handle coefficients which are not part of the exponent + # Handle coefficients which are not part of the exponent elseif expr_i.args[1] == :* && isa(expr_i.args[2], Number) if ((expr.args[1] == :-) && (i > 2)) || (ind == 1) #push!(expr_array, Expr(:call, :*, -expr_i.args[2], expr_i.args[3])) @@ -707,14 +710,14 @@ function expr_isolate_const(expr) push!(expr_array, expr_rec) # For any other terms - else - if (expr.args[1] == :- && (i > 2)) || (ind == 1) + else + if (expr.args[1] == :- && (i > 2)) || (ind == 1) push!(expr_array, Expr(:call, :*, -1, expr_i)) else push!(expr_array, expr_i) end end - end + end # Construct the expression from the array if length(expr_array) == 1 @@ -729,7 +732,7 @@ function expr_isolate_const(expr) return(expr_n) end - elseif (expr.head == :call && expr.args[1] == :^ && expr.args[2].head == :call && isa(expr.args[2].args[2], Number) && isa(expr.args[3], Number)) + elseif (expr.head == :call && expr.args[1] == :^ && expr.args[2].head == :call && isa(expr.args[2].args[2], Number) && isa(expr.args[3], Number)) expr_tmp = Expr(:call, :^, expr.args[2].args[3], expr.args[3]) return(Expr(:call, :*, expr.args[2].args[2] ^ expr.args[3], expr_tmp)) else diff --git a/src/operators.jl b/src/operators.jl index 1aeffe85..973fdee9 100644 --- a/src/operators.jl +++ b/src/operators.jl @@ -1,9 +1,9 @@ """ - expr_term_parsing(expr, m::AlpineNonlinearModel, level=0) + expr_term_parsing(expr, m::Optimizer, level=0) Recognize and process nonlinear terms in an expression """ -function expr_term_parsing(expr::Any, constr_id::Int, m::AlpineNonlinearModel, level=0; options...) +function expr_term_parsing(expr::Any, constr_id::Int, m::Optimizer, level=0; options...) isa(expr, Number) && return expr @@ -25,20 +25,20 @@ function expr_term_parsing(expr::Any, constr_id::Int, m::AlpineNonlinearModel, l end """ - detect_nonconvex_terms(expr, m::AlpineNonlinearModel) + detect_nonconvex_terms(expr, m::Optimizer) This function recognizes, stores, and replaces a sub-tree `expr` with available -user-defined/built-in structures patterns. The procedure is creates the required number -of lifted variables based on the patterns that it it trying to recognize. -Then, go through all built-in structures and perform operatins to convexify the problem. +user-defined/built-in structures patterns. The procedure creates the required number +of lifted variables based on the patterns that it is trying to recognize. +Then, it goes through all built-in structures and performs operatins to convexify the problem. Specific structure pattern information will be described formally. """ -function detect_nonconvex_terms(expr::Any, constr_id::Int, m::AlpineNonlinearModel; kwargs...) +function detect_nonconvex_terms(expr::Any, constr_id::Int, m::Optimizer; kwargs...) # First process user-defined structures in-cases of over-ride - for i in 1:length(m.term_patterns) - skip, expr = eval(m.term_patterns[i])(expr, constr_id, m) + for i in 1:length(get_option(m, :term_patterns)) + skip, expr = eval(get_option(m, :term_patterns)[i])(expr, constr_id, m) skip && return expr end @@ -73,7 +73,7 @@ function detect_nonconvex_terms(expr::Any, constr_id::Int, m::AlpineNonlinearMod return expr # if no structure is detected, simply return the original tree end -function store_nonconvex_term(m::AlpineNonlinearModel, nl_key::Any, var_idxs::Any, term_type::Symbol, operator::Symbol, evaluator::Function, bd_resolver::Function, discvar_collector::Function) +function store_nonconvex_term(m::Optimizer, nl_key::Any, var_idxs::Any, term_type::Symbol, operator::Symbol, evaluator::Function, bd_resolver::Function, discvar_collector::Function) l_cnt = length(keys(m.linear_terms)) nl_cnt = length(keys(m.nonconvex_terms)) @@ -100,11 +100,11 @@ function store_nonconvex_term(m::AlpineNonlinearModel, nl_key::Any, var_idxs::An # push!(m.var_type, :Cont) # TODO check if this replacement is good since additional constraints should be able to sufficiently constraint the type push!(m.var_type, m.nonconvex_terms[nl_key][:y_type]) # Keep track of the lifted var type - m.loglevel > 199 && println("found lifted $(term_type) term $(lifted_constr_ref)") + get_option(m, :loglevel) > 199 && println("found lifted $(term_type) term $(lifted_constr_ref)") return y_idx end -function store_linear_term(m::AlpineNonlinearModel, term_key::Any, expr::Any)#, bound_resolver::Function) +function store_linear_term(m::Optimizer, term_key::Any, expr::Any)#, bound_resolver::Function) l_cnt = length(keys(m.linear_terms)) nl_cnt = length(keys(m.nonconvex_terms)) @@ -126,12 +126,12 @@ function store_linear_term(m::AlpineNonlinearModel, term_key::Any, expr::Any)#, m.term_seq[l_cnt+nl_cnt + 1] = term_key push!(m.var_type, m.linear_terms[term_key][:y_type]) # Keep track of the lifted var type - m.loglevel > 199 && println("found lifted linear term $(lifted_var_ref) = $expr") + get_option(m, :loglevel) > 199 && println("found lifted linear term $(lifted_var_ref) = $expr") return y_idx end -function lift_nonconvex_term(m::AlpineNonlinearModel, nl_key, constr_id::Int, scalar = 1.0) +function lift_nonconvex_term(m::Optimizer, nl_key, constr_id::Int, scalar = 1.0) push!(m.nonconvex_terms[nl_key][:constr_id], constr_id) if scalar == 1.0 @@ -141,7 +141,7 @@ function lift_nonconvex_term(m::AlpineNonlinearModel, nl_key, constr_id::Int, sc end end -function lift_linear_term(m::AlpineNonlinearModel, term_key, constr_id::Int) +function lift_linear_term(m::Optimizer, term_key, constr_id::Int) push!(m.linear_terms[term_key][:constr_id], constr_id) return m.linear_terms[term_key][:lifted_var_ref] @@ -149,7 +149,7 @@ function lift_linear_term(m::AlpineNonlinearModel, term_key, constr_id::Int) return end -function detect_linear_term(expr::Any, constr_id::Int, m::AlpineNonlinearModel) +function detect_linear_term(expr::Any, constr_id::Int, m::Optimizer) @assert (expr.head == :call || expr.head == :ref) coef_fetch = Dict(:+ => 1.0, :- => -1.0) @@ -218,7 +218,7 @@ function detect_linear_term(expr::Any, constr_id::Int, m::AlpineNonlinearModel) return false, expr end -function basic_linear_bounds(m::AlpineNonlinearModel, k::Any, linear_terms=nothing) +function basic_linear_bounds(m::Optimizer, k::Any, linear_terms=nothing) linear_terms == nothing ? linear_terms = m.linear_terms : linear_term = linear_terms @@ -231,17 +231,17 @@ function basic_linear_bounds(m::AlpineNonlinearModel, k::Any, linear_terms=nothi end lb += linear_terms[k][:ref][:scalar] ub += linear_terms[k][:ref][:scalar] - if lb > m.l_var_tight[lifted_idx] + m.tol + if lb > m.l_var_tight[lifted_idx] + get_option(m, :tol) m.l_var_tight[lifted_idx] = lb end - if ub < m.u_var_tight[lifted_idx] - m.tol + if ub < m.u_var_tight[lifted_idx] - get_option(m, :tol) m.u_var_tight[lifted_idx] = ub end return end -function basic_linear_bounds(m::AlpineNonlinearModel, k::Any, d::Dict) +function basic_linear_bounds(m::Optimizer, k::Any, d::Dict) lifted_idx = m.linear_terms[k][:y_idx] ub = 0.0 @@ -253,10 +253,10 @@ function basic_linear_bounds(m::AlpineNonlinearModel, k::Any, d::Dict) lb += m.linear_terms[k][:ref][:scalar] ub += m.linear_terms[k][:ref][:scalar] - if lb > d[lifted_idx][1] + m.tol + if lb > d[lifted_idx][1] + get_option(m, :tol) d[lifted_idx][1] = lb end - if ub < d[lifted_idx][end] - m.tol + if ub < d[lifted_idx][end] - get_option(m, :tol) d[lifted_idx][end] = ub end @@ -286,7 +286,7 @@ linear(k, vec) = k[:ref][:scalar] .+ sum([i[1]*vec[i[2]] for i in k[:ref][:coef_ Leads to BINLIN terms, with BINPROD, INTPROD, INTLIN if necessary """ -function detect_discretemulti_term(expr::Any, constr_id::Int, m::AlpineNonlinearModel) +function detect_discretemulti_term(expr::Any, constr_id::Int, m::Optimizer) # Alwasy construct the binlin term after lifting @assert (expr.head == :call || expr.head == :ref) @@ -393,7 +393,7 @@ function detect_discretemulti_term(expr::Any, constr_id::Int, m::AlpineNonlinear return false, expr end -function basic_binlin_bounds(m::AlpineNonlinearModel, k::Any) +function basic_binlin_bounds(m::Optimizer, k::Any) lifted_idx = m.nonconvex_terms[k][:y_idx] @@ -415,7 +415,7 @@ function basic_binlin_bounds(m::AlpineNonlinearModel, k::Any) return end -function basic_binlin_bounds(m::AlpineNonlinearModel, k::Any, d::Dict) +function basic_binlin_bounds(m::Optimizer, k::Any, d::Dict) lifted_idx = m.nonconvex_terms[k][:y_idx] @@ -437,7 +437,7 @@ function basic_binlin_bounds(m::AlpineNonlinearModel, k::Any, d::Dict) return d end -function basic_intlin_bounds(m::AlpineNonlinearModel, k::Any) +function basic_intlin_bounds(m::Optimizer, k::Any) lifted_idx = m.nonconvex_terms[k][:y_idx] @@ -459,7 +459,7 @@ function basic_intlin_bounds(m::AlpineNonlinearModel, k::Any) return end -function basic_intlin_bounds(m::AlpineNonlinearModel, k::Any, d::Dict) +function basic_intlin_bounds(m::Optimizer, k::Any, d::Dict) lifted_idx = m.nonconvex_terms[k][:y_idx] @@ -481,12 +481,12 @@ function basic_intlin_bounds(m::AlpineNonlinearModel, k::Any, d::Dict) return d end -function collect_binlin_discvar(m::AlpineNonlinearModel, k::Any; var_bowl=nothing) +function collect_binlin_discvar(m::Optimizer, k::Any; var_bowl=nothing) # Exact linearization exist return end -function collect_intlin_discvar(m::AlpineNonlinearModel, k::Any; var_bowl=nothing) +function collect_intlin_discvar(m::Optimizer, k::Any; var_bowl=nothing) for i in m.nonconvex_terms[k][:var_idxs] @assert isa(i, Int) @@ -509,7 +509,7 @@ end Leads to BININT terms, with BINPROD, INTPROD if necessary """ -function detect_binint_term(expr::Any, constr_id::Int, m::AlpineNonlinearModel) +function detect_binint_term(expr::Any, constr_id::Int, m::Optimizer) @assert (expr.head == :call || expr.head == :ref) @@ -577,7 +577,7 @@ function detect_binint_term(expr::Any, constr_id::Int, m::AlpineNonlinearModel) return false, expr end -function basic_binint_bound(m::AlpineNonlinearModel, k::Any) +function basic_binint_bound(m::Optimizer, k::Any) lifted_idx = m.nonconvex_terms[k][:y_idx] @@ -599,7 +599,7 @@ function basic_binint_bound(m::AlpineNonlinearModel, k::Any) return end -function basic_binint_bound(m::AlpineNonlinearModel, k::Any, d::Dict) +function basic_binint_bound(m::Optimizer, k::Any, d::Dict) lifted_idx = m.nonconvex_terms[k][:y_idx] @@ -621,7 +621,7 @@ function basic_binint_bound(m::AlpineNonlinearModel, k::Any, d::Dict) return d end -function collect_binint_discvar(m::AlpineNonlinearModel, k::Any; var_bowl=nothing) +function collect_binint_discvar(m::Optimizer, k::Any; var_bowl=nothing) # Exact linearization exist return end @@ -629,7 +629,7 @@ end """ Recognize products of binary variables : x1 * x2 * .. * xN """ -function detect_intprod_term(expr::Any, constr_id::Int, m::AlpineNonlinearModel) +function detect_intprod_term(expr::Any, constr_id::Int, m::Optimizer) @assert (expr.head == :call || expr.head == :ref) if (expr.args[1] == :*) @@ -691,7 +691,7 @@ function detect_intprod_term(expr::Any, constr_id::Int, m::AlpineNonlinearModel) return false, expr end -function basic_intprod_bounds(m::AlpineNonlinearModel, k::Any) +function basic_intprod_bounds(m::Optimizer, k::Any) lifted_idx = m.nonconvex_terms[k][:lifted_var_ref].args[2] @@ -708,17 +708,17 @@ function basic_intprod_bounds(m::AlpineNonlinearModel, k::Any) end end - if minimum(bound) > m.l_var_tight[lifted_idx] + m.tol + if minimum(bound) > m.l_var_tight[lifted_idx] + get_option(m, :tol) m.l_var_tight[lifted_idx] = minimum(bound) end - if maximum(bound) < m.u_var_tight[lifted_idx] - m.tol + if maximum(bound) < m.u_var_tight[lifted_idx] - get_option(m, :tol) m.u_var_tight[lifted_idx] = maximum(bound) end return end -function basic_intprod_bounds(m::AlpineNonlinearModel, k::Any, d::Dict) +function basic_intprod_bounds(m::Optimizer, k::Any, d::Dict) lifted_idx = m.nonconvex_terms[k][:lifted_var_ref].args[2] @@ -734,17 +734,17 @@ function basic_intprod_bounds(m::AlpineNonlinearModel, k::Any, d::Dict) bound = vec(bound) * var_bounds' end end - if minimum(bound) > d[lifted_idx][1] + m.tol + if minimum(bound) > d[lifted_idx][1] + get_option(m, :tol) d[lifted_idx][1] = minimum(bound) end - if maximum(bound) < d[lifted_idx][end] - m.tol + if maximum(bound) < d[lifted_idx][end] - get_option(m, :tol) d[lifted_idx][end] = maximum(bound) end return d end -function collect_intprod_discvar(m::AlpineNonlinearModel, k::Any; var_bowl=nothing) +function collect_intprod_discvar(m::Optimizer, k::Any; var_bowl=nothing) for var in m.nonconvex_terms[k][:var_idxs] @assert isa(var, Int) if var_bowl == nothing @@ -759,7 +759,7 @@ end """ Recognize products of binary variables : x1 * x2 * .. * xN """ -function detect_binprod_term(expr::Any, constr_id::Int, m::AlpineNonlinearModel) +function detect_binprod_term(expr::Any, constr_id::Int, m::Optimizer) @assert (expr.head == :call || expr.head == :ref) if (expr.args[1] == :*) @@ -818,7 +818,7 @@ function detect_binprod_term(expr::Any, constr_id::Int, m::AlpineNonlinearModel) return false, expr end -function basic_binprod_bounds(m::AlpineNonlinearModel, k::Any) +function basic_binprod_bounds(m::Optimizer, k::Any) lifted_idx = m.nonconvex_terms[k][:lifted_var_ref].args[2] m.l_var_tight[lifted_idx] = 0 @@ -827,7 +827,7 @@ function basic_binprod_bounds(m::AlpineNonlinearModel, k::Any) return end -function basic_binprod_bounds(m::AlpineNonlinearModel, k::Any, d::Dict) +function basic_binprod_bounds(m::Optimizer, k::Any, d::Dict) lifted_idx = m.nonconvex_terms[k][:lifted_var_ref].args[2] d[lifted_idx][1] = 0 @@ -836,7 +836,7 @@ function basic_binprod_bounds(m::AlpineNonlinearModel, k::Any, d::Dict) return d end -function collect_binprod_discvar(m::AlpineNonlinearModel, k::Any; var_bowl=nothing) +function collect_binprod_discvar(m::Optimizer, k::Any; var_bowl=nothing) # Exact linearization exists return end @@ -848,7 +848,7 @@ end Recognize multilinear terms: x1 * x2 * .. * xN, where all x_i ∀ i are continous variables Recognize monomial terms: x^2 or x * x, where x is continuous """ -function detect_bilinear_term(expr::Any, constr_id::Int, m::AlpineNonlinearModel) +function detect_bilinear_term(expr::Any, constr_id::Int, m::Optimizer) @assert (expr.head == :call || expr.head == :ref) if (expr.args[1] == :*) # confirm head (:*) @@ -889,7 +889,7 @@ function detect_bilinear_term(expr::Any, constr_id::Int, m::AlpineNonlinearModel return false, expr end -function detect_multilinear_term(expr::Any, constr_id::Int, m::AlpineNonlinearModel) +function detect_multilinear_term(expr::Any, constr_id::Int, m::Optimizer) @assert (expr.head == :call || expr.head == :ref) if (expr.args[1] == :*) # Pattern: coefficients * x * y * z ... @@ -946,7 +946,7 @@ function detect_multilinear_term(expr::Any, constr_id::Int, m::AlpineNonlinearMo return false, expr end -function detect_monomial_term(expr::Any, constr_id::Int, m::AlpineNonlinearModel) +function detect_monomial_term(expr::Any, constr_id::Int, m::Optimizer) if (expr.args[1] == :^) && length(expr.args) == 3 # Pattern: (x)^(2) @@ -1014,7 +1014,7 @@ function detect_monomial_term(expr::Any, constr_id::Int, m::AlpineNonlinearModel return false, expr end -function basic_monomial_bounds(m::AlpineNonlinearModel, k::Any) +function basic_monomial_bounds(m::Optimizer, k::Any) lifted_idx = m.nonconvex_terms[k][:lifted_var_ref].args[2] cnt = 0 @@ -1031,20 +1031,20 @@ function basic_monomial_bounds(m::AlpineNonlinearModel, k::Any) bound = vec(bound) * var_bounds' end end - if minimum(bound) > m.l_var_tight[lifted_idx] + m.tol + if minimum(bound) > m.l_var_tight[lifted_idx] + get_option(m, :tol) m.l_var_tight[lifted_idx] = minimum(bound) if m.nonconvex_terms[k][:nonlinear_type] == :MONOMIAL m.l_var_tight[lifted_idx] = 0.0 end end - if maximum(bound) < m.u_var_tight[lifted_idx] - m.tol + if maximum(bound) < m.u_var_tight[lifted_idx] - get_option(m, :tol) m.u_var_tight[lifted_idx] = maximum(bound) end return end -function basic_monomial_bounds(m::AlpineNonlinearModel, nlk::Any, d::Dict) +function basic_monomial_bounds(m::Optimizer, nlk::Any, d::Dict) lifted_idx = m.nonconvex_terms[nlk][:lifted_var_ref].args[2] cnt = 0 @@ -1062,18 +1062,18 @@ function basic_monomial_bounds(m::AlpineNonlinearModel, nlk::Any, d::Dict) end end - if minimum(bound) > d[lifted_idx][1] + m.tol + if minimum(bound) > d[lifted_idx][1] + get_option(m, :tol) d[lifted_idx][1] = minimum(bound) end - if maximum(bound) < d[lifted_idx][end] - m.tol + if maximum(bound) < d[lifted_idx][end] - get_option(m, :tol) d[lifted_idx][end] = maximum(bound) end return d end -function collect_monomial_discvar(m::AlpineNonlinearModel, k::Any; var_bowl=nothing) +function collect_monomial_discvar(m::Optimizer, k::Any; var_bowl=nothing) for var in k @assert isa(var.args[2], Int) if var_bowl == nothing @@ -1089,7 +1089,7 @@ end Recognize sin/cos terms: sin(x) / cos(x), where x "should" be continous variables # TODO future call detect_TRIGONOMETRIC_term """ -function detect_sincos_term(expr::Any, constr_id::Int, m::AlpineNonlinearModel) +function detect_sincos_term(expr::Any, constr_id::Int, m::Optimizer) @assert (expr.head == :call || expr.head == :ref) @@ -1122,7 +1122,7 @@ function detect_sincos_term(expr::Any, constr_id::Int, m::AlpineNonlinearModel) return false, expr end -function basic_sincos_bounds(m::AlpineNonlinearModel, k::Any) +function basic_sincos_bounds(m::Optimizer, k::Any) lifted_idx = m.nonconvex_terms[k][:lifted_var_ref].args[2] m.l_var_tight[lifted_idx] = -1 # TODO can be improved @@ -1131,7 +1131,7 @@ function basic_sincos_bounds(m::AlpineNonlinearModel, k::Any) return end -function basic_sincos_bounds(m::AlpineNonlinearModel, k::Any, d::Dict) +function basic_sincos_bounds(m::Optimizer, k::Any, d::Dict) lifted_idx = m.nonconvex_terms[k][:lifted_var_ref].args[2] d[lifted_idx][1] = -1 # TODO can be improved @@ -1141,7 +1141,7 @@ function basic_sincos_bounds(m::AlpineNonlinearModel, k::Any, d::Dict) end -function collect_sincos_discvar(m::AlpineNonlinearModel, k::Any; var_bowl=nothing) +function collect_sincos_discvar(m::Optimizer, k::Any; var_bowl=nothing) for var in m.nonconvex_terms[k][:var_idxs] @assert isa(var, Int) if var_bowl == nothing @@ -1157,7 +1157,7 @@ end Recognize convex constraints A catch for type-A convex constraint expression """ -function resolve_convex_constr(expr::Any, m::AlpineNonlinearModel=nothing, idx::Int=0, scalar_bin=[], idxs_bin=[], power_bin=[], rhs=0.0) +function resolve_convex_constr(expr::Any, m::Optimizer=nothing, idx::Int=0, scalar_bin=[], idxs_bin=[], power_bin=[], rhs=0.0) if expr.args[1] in [:(<=), :(>=)] && idx > 0 expr_orig = :constr @@ -1284,7 +1284,7 @@ function resolve_convex_constr(expr::Any, m::AlpineNonlinearModel=nothing, idx:: :cnt => length(idxs_bin), :powers => power_bin) - m.loglevel > 99 && println("CONVEX Constraint $(idx): $(expr)") + get_option(m, :loglevel) > 99 && println("CONVEX Constraint $(idx): $(expr)") return true elseif expr_orig == :obj @@ -1338,7 +1338,7 @@ function resolve_convex_constr(expr::Any, m::AlpineNonlinearModel=nothing, idx:: :cnt => length(idxs_bin), :powers => power_bin) - m.loglevel > 99 && println("CONVEX Objective: $(expr)") + get_option(m, :loglevel) > 99 && println("CONVEX Objective: $(expr)") return true end diff --git a/src/presolve.jl b/src/presolve.jl index 68b726e8..8cf110bb 100644 --- a/src/presolve.jl +++ b/src/presolve.jl @@ -1,34 +1,34 @@ """ - bound_tightening(m::AlpineNonlinearModel) + bound_tightening(m::Optimizer) Entry point for the optimization-based bound-tightening (OBBT) algorithm. The aim of the OBBT algorithm is to sequentially tighten the variable bounds until a fixed point is reached. Currently, two OBBT methods are implemented [`minmax_bound_tightening`](@ref). - * Bound-tightening with polyhedral relaxations (McCormick, Lambda for convex-hull) + * Bound-tightening with polyhedral relaxations (McCormick, Lambda for convex-hull) * Bound-tightening with piecewise polyhedral relaxations: (with three partitions around the local feasible solution) If no local feasible solution is obtained, the algorithm defaults to OBBT without partitions """ -function bound_tightening(m::AlpineNonlinearModel; use_bound = true, kwargs...) +function bound_tightening(m::Optimizer; use_bound = true, kwargs...) - m.presolve_bt || return + get_option(m, :presolve_bt) || return - if m.presolve_bt_algo == 1 + if get_option(m, :presolve_bt_algo) == 1 minmax_bound_tightening(m, use_bound=use_bound) - elseif m.presolve_bt_algo == 2 + elseif get_option(m, :presolve_bt_algo) == 2 minmax_bound_tightening(m, use_bound=use_bound, use_tmc=true) - elseif isa(m.presolve_bt_algo, Function) - eval(m.presolve_bt_algo)(m) + elseif isa(get_option(m, :presolve_bt_algo), Function) + eval(get_option(m, :presolve_bt_algo))(m) else error("Unrecognized optimization-based bound tightening algorithm") - end + end return end """ - minmax_bound_tightening(m:AlpineNonlinearModel; use_bound::Bool=true, use_tmc::Bool) + minmax_bound_tightening(m:Optimizer; use_bound::Bool=true, use_tmc::Bool) This function implements the OBBT algorithm to tighten the variable bounds. It utilizes either the basic polyhedral relaxations or the piecewise polyhedral relaxations (TMC) @@ -40,28 +40,26 @@ objective value of the local solve solution stored in `best_sol` for performing to `true` when the local solve is successful in obtaining a feasible solution, else this parameter is set to `false` -For details, refer to section 3.1.1 of -Nagarjan, Lu, Wang, Bent, Sundar, "An adaptive, multivariate partitioning algorithm for global optimization of nonconvex programs" +For details, refer to section 3.1.1 of +Nagarjan, Lu, Wang, Bent, Sundar, "An adaptive, multivariate partitioning algorithm for global optimization of nonconvex programs" URL: https://goo.gl/89zrDf Several other parameters are available for the OBBT algorithm tuning. For more details, see [Parameters](@ref). """ -function minmax_bound_tightening(m::AlpineNonlinearModel; use_bound = true, timelimit = Inf, kwargs...) +function minmax_bound_tightening(m::Optimizer; use_bound = true, timelimit = Inf, kwargs...) # Some functinal constants - both_senses = [:Min, :Max] # Senses during bound tightening procedures - tell_side = Dict(:Min=>1, :Max=>2) # Positional information - tell_round = Dict(:Min=>floor, :Max=>ceil) - status_pass = [:Optimal] - status_reroute = [:UserLimits] + both_senses = [MOI.MIN_SENSE, MOI.MAX_SENSE] # Senses during bound tightening procedures + tell_side = Dict(MOI.MIN_SENSE => 1, MOI.MAX_SENSE=>2) # Positional information + tell_round = Dict(MOI.MIN_SENSE => floor, MOI.MAX_SENSE => ceil) options = Dict(kwargs) st = time() # Track start time if timelimit == Inf - timelimit = m.presolve_timeout + timelimit = get_option(m, :presolve_timeout) end # Regulating Special Input Conditions: default use best feasible solution objective value @@ -71,89 +69,83 @@ function minmax_bound_tightening(m::AlpineNonlinearModel; use_bound = true, time discretization = to_discretization(m, m.l_var_tight, m.u_var_tight) if use_bound == false && haskey(options, :use_tmc) - (m.loglevel > 0) && @warn " Local solve infeasible; defaulting to doing bound-tightening without partitions." + (get_option(m, :loglevel) > 0) && @warn " Local solve infeasible; defaulting to doing bound-tightening without partitions." end if use_bound == true && haskey(options, :use_tmc) discretization = add_adaptive_partition(m, use_solution=m.best_sol, use_disc=discretization) end discretization = resolve_var_bounds(m, discretization) # recomputation of bounds for lifted_variables - (m.loglevel > 0) && println(" Starting bound-tightening") + (get_option(m, :loglevel) > 0) && println(" Starting bound-tightening") # start of the solve keeptightening = true avg_reduction = Inf total_reduction = 0.0 - while keeptightening && (m.logs[:time_left] > m.tol) && (m.logs[:bt_iter] < m.presolve_maxiter) # Stopping criteria + while keeptightening && (m.logs[:time_left] > get_option(m, :tol)) && (m.logs[:bt_iter] < get_option(m, :presolve_maxiter)) # Stopping criteria keeptightening = false m.logs[:bt_iter] += 1 - m.loglevel > 199 && println(" Iteration - $(m.logs[:bt_iter])") + get_option(m, :loglevel) > 199 && println(" Iteration - $(m.logs[:bt_iter])") temp_bounds = Dict() # Perform Bound Contraction for var_idx in 1:m.num_var_orig temp_bounds[var_idx] = [discretization[var_idx][1], discretization[var_idx][end]] - if (discretization[var_idx][end] - discretization[var_idx][1]) > m.presolve_bt_width_tol + if (discretization[var_idx][end] - discretization[var_idx][1]) > get_option(m, :presolve_bt_width_tol) create_bound_tightening_model(m, discretization, bound) for sense in both_senses - @objective(m.model_mip, sense, Variable(m.model_mip, var_idx)) + @objective(m.model_mip, sense, _index_to_variable_ref(m.model_mip, var_idx)) status = solve_bound_tightening_model(m) - if status in status_pass - temp_bounds[var_idx][tell_side[sense]] = eval(tell_round[sense])(getobjectivevalue(m.model_mip)/m.presolve_bt_output_tol)*m.presolve_bt_output_tol # Objective truncation for numerical issues - elseif status in status_reroute - temp_bounds[var_idx][tell_side[sense]] = eval(tell_round[sense])(getobjbound(m.model_mip)/m.presolve_bt_output_tol)*m.presolve_bt_output_tol + if status in STATUS_OPT + temp_bounds[var_idx][tell_side[sense]] = eval(tell_round[sense])(JuMP.objective_value(m.model_mip)/get_option(m, :presolve_bt_output_tol))*get_option(m, :presolve_bt_output_tol) # Objective truncation for numerical issues + elseif status in STATUS_LIMIT + temp_bounds[var_idx][tell_side[sense]] = eval(tell_round[sense])(JuMP.objective_bound(m.model_mip)/get_option(m, :presolve_bt_output_tol))*get_option(m, :presolve_bt_output_tol) else print("!") end end end - if (temp_bounds[var_idx][tell_side[:Min]] > temp_bounds[var_idx][tell_side[:Max]]) + if (temp_bounds[var_idx][tell_side[MOI.MIN_SENSE]] > temp_bounds[var_idx][tell_side[MOI.MAX_SENSE]]) temp_bounds[var_idx] = [discretization[var_idx][1], discretization[var_idx][end]] end - if (temp_bounds[var_idx][tell_side[:Min]] > discretization[var_idx][end]) - temp_bounds[var_idx][tell_side[:Min]] = discretization[var_idx][1] - end - if (temp_bounds[var_idx][tell_side[:Max]] < discretization[var_idx][1]) - temp_bounds[var_idx][tell_side[:Max]] = discretization[var_idx][end] + if (temp_bounds[var_idx][tell_side[MOI.MIN_SENSE]] > discretization[var_idx][end]) + temp_bounds[var_idx][tell_side[MOI.MIN_SENSE]] = discretization[var_idx][1] + end + if (temp_bounds[var_idx][tell_side[MOI.MAX_SENSE]] < discretization[var_idx][1]) + temp_bounds[var_idx][tell_side[MOI.MAX_SENSE]] = discretization[var_idx][end] end bound_reduction = 0.0 - if (temp_bounds[var_idx][tell_side[:Max]] - temp_bounds[var_idx][tell_side[:Min]]) > m.presolve_bt_width_tol - new_range = temp_bounds[var_idx][tell_side[:Max]] - temp_bounds[var_idx][tell_side[:Min]] - old_range = discretization[var_idx][end] - discretization[var_idx][1] - bound_reduction = old_range - new_range - discretization[var_idx][1] = temp_bounds[var_idx][1] - discretization[var_idx][end] = temp_bounds[var_idx][end] - else - midpoint = (temp_bounds[var_idx][1] + temp_bounds[var_idx][end])/2 - if (midpoint - discretization[var_idx][1] < m.presolve_bt_width_tol/2) - temp_bounds[var_idx][tell_side[:Min]] = discretization[var_idx][1] - temp_bounds[var_idx][tell_side[:Max]] = discretization[var_idx][1] + (m.presolve_bt_width_tol) - elseif (discretization[var_idx][end] - midpoint < m.presolve_bt_width_tol/2) - temp_bounds[var_idx][tell_side[:Min]] = discretization[var_idx][end] - (m.presolve_bt_width_tol) - temp_bounds[var_idx][tell_side[:Max]] = discretization[var_idx][end] - else - temp_bounds[var_idx][tell_side[:Min]] = midpoint - (m.presolve_bt_width_tol/2) - temp_bounds[var_idx][tell_side[:Max]] = midpoint + (m.presolve_bt_width_tol/2) - end - new_range = temp_bounds[var_idx][tell_side[:Max]] - temp_bounds[var_idx][tell_side[:Min]] - old_range = discretization[var_idx][end] - discretization[var_idx][1] - bound_reduction = old_range - new_range - discretization[var_idx][1] = temp_bounds[var_idx][1] - discretization[var_idx][end] = temp_bounds[var_idx][end] + if (temp_bounds[var_idx][tell_side[MOI.MAX_SENSE]] - temp_bounds[var_idx][tell_side[MOI.MIN_SENSE]]) <= get_option(m, :presolve_bt_width_tol) + midpoint = (temp_bounds[var_idx][1] + temp_bounds[var_idx][end]) / 2 + if (midpoint - discretization[var_idx][1] < get_option(m, :presolve_bt_width_tol)/2) + temp_bounds[var_idx][tell_side[MOI.MIN_SENSE]] = discretization[var_idx][1] + temp_bounds[var_idx][tell_side[MOI.MAX_SENSE]] = discretization[var_idx][1] + (get_option(m, :presolve_bt_width_tol)) + elseif (discretization[var_idx][end] - midpoint < get_option(m, :presolve_bt_width_tol)/2) + temp_bounds[var_idx][tell_side[MOI.MIN_SENSE]] = discretization[var_idx][end] - (get_option(m, :presolve_bt_width_tol)) + temp_bounds[var_idx][tell_side[MOI.MAX_SENSE]] = discretization[var_idx][end] + else + temp_bounds[var_idx][tell_side[MOI.MIN_SENSE]] = midpoint - (get_option(m, :presolve_bt_width_tol)/2) + temp_bounds[var_idx][tell_side[MOI.MAX_SENSE]] = midpoint + (get_option(m, :presolve_bt_width_tol)/2) + end end + new_range = temp_bounds[var_idx][tell_side[MOI.MAX_SENSE]] - temp_bounds[var_idx][tell_side[MOI.MIN_SENSE]] + old_range = discretization[var_idx][end] - discretization[var_idx][1] + bound_reduction = old_range - new_range total_reduction += bound_reduction - (m.loglevel > 99) && print("+") - (m.loglevel > 99) && println(" VAR $(var_idx) LB contracted $(discretization[var_idx][1])=>$(temp_bounds[var_idx][1])") - (m.loglevel > 99) && print("+") - (m.loglevel > 99) && println(" VAR $(var_idx) UB contracted $(discretization[var_idx][end])=>$(temp_bounds[var_idx][end])") + (get_option(m, :loglevel) > 99) && print("+") + (get_option(m, :loglevel) > 99) && println(" VAR $(var_idx) LB contracted $(discretization[var_idx][1])=>$(temp_bounds[var_idx][1])") + (get_option(m, :loglevel) > 99) && print("+") + (get_option(m, :loglevel) > 99) && println(" VAR $(var_idx) UB contracted $(discretization[var_idx][end])=>$(temp_bounds[var_idx][end])") + discretization[var_idx][1] = temp_bounds[var_idx][1] + discretization[var_idx][end] = temp_bounds[var_idx][end] end avg_reduction = total_reduction/length(keys(temp_bounds)) keeptightening = (avg_reduction > 1e-3) - + discretization = resolve_var_bounds(m, discretization) if haskey(options, :use_tmc) discretization = add_adaptive_partition(m, use_solution=m.best_sol, use_disc=flatten_discretization(discretization)) @@ -163,34 +155,34 @@ function minmax_bound_tightening(m::AlpineNonlinearModel; use_bound = true, time time() - st > timelimit && break end - # (m.loglevel > 0) && println("Completed bound-tightening in $(m.logs[:bt_iter]) iterations. Here are the tightened bounds:") - (m.loglevel > 0) && println(" Variables whose bounds were tightened:") + # (get_option(m, :loglevel) > 0) && println("Completed bound-tightening in $(m.logs[:bt_iter]) iterations. Here are the tightened bounds:") + (get_option(m, :loglevel) > 0) && println(" Variables whose bounds were tightened:") m.l_var_tight, m.u_var_tight = update_var_bounds(discretization) m.discretization = add_adaptive_partition(m, use_solution=m.best_sol) for i in m.disc_vars contract_ratio = round(1-abs(m.l_var_tight[i] - m.u_var_tight[i])/abs(l_var_orig[i] - u_var_orig[i]); digits=2)*100 - if m.loglevel > 0 && contract_ratio > 0.0001 + if get_option(m, :loglevel) > 0 && contract_ratio > 0.0001 println(" VAR $(i): $(contract_ratio)% contraction |$(round(l_var_orig[i]; digits=4)) --> | $(round(m.l_var_tight[i]; digits=4)) - $(round(m.u_var_tight[i]; digits=4)) | <-- $(round(u_var_orig[i]; digits=4)) |") end end - # (m.loglevel > 0) && print("\n") + # (get_option(m, :loglevel) > 0) && print("\n") return end """ - create_bound_tightening_model(m::AlpineNonlinearModel, discretization::Dict, bound::Float64) + create_bound_tightening_model(m::Optimizer, discretization::Dict, bound::Float64) This function takes in the initial discretization information and builds the OBBT model. It is an algorithm specific function called by [`minmax_bound_tightening`](@ref) """ -function create_bound_tightening_model(m::AlpineNonlinearModel, discretization, bound; kwargs...) +function create_bound_tightening_model(m::Optimizer, discretization, bound; kwargs...) options = Dict(kwargs) start_build = time() - m.model_mip = Model(solver=m.mip_solver) # Construct JuMP model + m.model_mip = Model(get_option(m, :mip_solver)) # Construct JuMP model amp_post_vars(m, use_disc=discretization) amp_post_lifted_constraints(m) amp_post_convexification(m, use_disc=discretization) # Convexify problem @@ -201,32 +193,40 @@ function create_bound_tightening_model(m::AlpineNonlinearModel, discretization, cputime_build = time() - start_build m.logs[:total_time] += cputime_build - m.logs[:time_left] = max(0.0, m.timeout - m.logs[:total_time]) + m.logs[:time_left] = max(0.0, get_option(m, :timeout) - m.logs[:total_time]) return end """ - solve_bound_tightening_model(m::AlpineNonlinearModel) + solve_bound_tightening_model(m::Optimizer) A function that solves the min and max OBBT model. """ -function solve_bound_tightening_model(m::AlpineNonlinearModel; kwargs...) +function solve_bound_tightening_model(m::Optimizer; kwargs...) # ========= MILP Solve ========= # - if m.presolve_bt_mip_timeout < Inf - update_mip_time_limit(m, timelimit = max(0.0, min(m.presolve_bt_mip_timeout, m.timeout - m.logs[:total_time]))) + time_limit = max(0.0, if get_option(m, :presolve_bt_mip_timeout) < Inf + min(get_option(m, :presolve_bt_mip_timeout), get_option(m, :timeout) - m.logs[:total_time]) else - update_mip_time_limit(m, timelimit = max(0.0, m.timeout - m.logs[:total_time])) - end + get_option(m, :timeout) - m.logs[:total_time] + end) + MOI.set(m.model_mip, MOI.TimeLimitSec(), time_limit) start_solve = time() - status = solve(m.model_mip, suppress_warnings=true, relaxation=m.presolve_bt_relax) #TODO Double check here + if get_option(m, :presolve_bt_relax) #TODO Double check here + unrelax = JuMP.relax_integrality(m.model_mip) + end + JuMP.optimize!(m.model_mip) + status = MOI.get(m.model_mip, MOI.TerminationStatus()) + if get_option(m, :presolve_bt_relax) + unrelax() # FIXME should this be called ? + end cputime_solve = time() - start_solve m.logs[:total_time] += cputime_solve - m.logs[:time_left] = max(0.0, m.timeout - m.logs[:total_time]) + m.logs[:time_left] = max(0.0, get_option(m, :timeout) - m.logs[:total_time]) # ========= MILP Solve ========= # return status @@ -235,13 +235,13 @@ end """ TODO: docstring """ -function post_obj_bounds(m::AlpineNonlinearModel, bound::Float64; kwargs...) - if m.sense_orig == :Max +function post_obj_bounds(m::Optimizer, bound::Float64; kwargs...) + if is_max_sense(m) @constraint(m.model_mip, - sum(m.bounding_obj_mip[:coefs][j]*Variable(m.model_mip, m.bounding_obj_mip[:vars][j].args[2]) for j in 1:m.bounding_obj_mip[:cnt]) >= bound) - elseif m.sense_orig == :Min + sum(m.bounding_obj_mip[:coefs][j]*_index_to_variable_ref(m.model_mip, m.bounding_obj_mip[:vars][j].args[2]) for j in 1:m.bounding_obj_mip[:cnt]) >= bound) + elseif is_min_sense(m) @constraint(m.model_mip, - sum(m.bounding_obj_mip[:coefs][j]*Variable(m.model_mip, m.bounding_obj_mip[:vars][j].args[2]) for j in 1:m.bounding_obj_mip[:cnt]) <= bound) + sum(m.bounding_obj_mip[:coefs][j]*_index_to_variable_ref(m.model_mip, m.bounding_obj_mip[:vars][j].args[2]) for j in 1:m.bounding_obj_mip[:cnt]) <= bound) end return diff --git a/src/solver.jl b/src/solver.jl index 632ebfdf..1d50fa23 100644 --- a/src/solver.jl +++ b/src/solver.jl @@ -1,7 +1,4 @@ -export AlpineSolver - -mutable struct AlpineNonlinearModel <: MathProgBase.AbstractNonlinearModel - +mutable struct OptimizerOptions # Parameters for tuning Alpine # basic solver parameters @@ -14,37 +11,42 @@ mutable struct AlpineNonlinearModel <: MathProgBase.AbstractNonlinearModel tol::Float64 # Numerical tol used in the algorithmic process largebound::Float64 # Large bounds for problems with unbounded variables + # add all the solver options + nlp_solver # Local continuous NLP solver for solving NLPs at each iteration + minlp_solver # Local MINLP solver for solving MINLPs at each iteration + mip_solver # MIP solver for successive lower bound solves + # convexification method tuning recognize_convex::Bool # Recognize convex expressions in parsing objective functions and constraints - bilinear_mccormick::Bool # Convexify bilinear terms using piecwise McCormick representation + bilinear_mccormick::Bool # [INACTIVE] Convexify bilinear terms using piecwise McCormick representation bilinear_convexhull::Bool # Convexify bilinear terms using lambda representation monomial_convexhull::Bool # Convexify monomial terms using convex-hull representation # expression-based user-inputs method_convexification::Array{Function} # Array of functions that user can choose to convexify specific non-linear terms : no over-ride privilege - method_partition_injection::Array{Function} # Array of functions for special methods to add partitions to variables under complex conditions + method_partition_injection::Array{Function} # [INACTIVE] Array of functions for special methods to add partitions to variables under complex conditions term_patterns::Array{Function} # Array of functions that user can choose to parse/recognize nonlinear terms in constraint expressions constr_patterns::Array{Function} # Array of functions that user can choose to parse/recognize structural constraint from expressions # parameters used in the partitioning algorithm + disc_var_pick::Any # Algorithm for choosing the variables to discretize: 1 for minimum vertex cover, 0 for all variables disc_ratio::Any # Discretization ratio parameter (use a fixed value for now, later switch to a function) disc_uniform_rate::Int # Discretization rate parameter when using uniform partitions - disc_var_pick::Any # Algorithm for choosing the variables to discretize: 1 for minimum vertex cover, 0 for all variables - disc_divert_chunks::Int # How many uniform partitions to construct disc_add_partition_method::Any # Additional methods to add discretization + disc_divert_chunks::Int # How many uniform partitions to construct disc_abs_width_tol::Float64 # Absolute tolerance used when setting up partition/discretization disc_rel_width_tol::Float64 # Relative width tolerance when setting up partition/discretization - disc_consecutive_forbid::Int # Prevent bounding model to add partitions consecutively in the same region when bounds do not improve + disc_consecutive_forbid::Int # Prevent bounding model to add partitions consecutively in the same region when bounds do not improve disc_ratio_branch::Bool # Branching tests for picking fixed the discretization ratio # MIP Formulation Parameters convhull_formulation::String # MIP Formulation for the relaxation - convhull_warmstart::Bool # Warm start the bounding MIP - convhull_no_good_cuts::Bool # Add no-good cuts to MIP based on the pool solutions convhull_ebd::Bool # Enable embedding formulation convhull_ebd_encode::Any # Encoding method used for convhull_ebd convhull_ebd_ibs::Bool # Enable independent branching scheme convhull_ebd_link::Bool # Linking constraints between x and α, type 1 uses hierarchical and type 2 uses big-m + convhull_warmstart::Bool # Warm start the bounding MIP + convhull_no_good_cuts::Bool # Add no-good cuts to MIP based on the pool solutions # Presolving Parameters presolve_track_time::Bool # Account presolve time for total time usage @@ -59,18 +61,88 @@ mutable struct AlpineNonlinearModel <: MathProgBase.AbstractNonlinearModel # Domain Reduction presolve_bp::Bool # Conduct basic bound propagation - presolve_infeasible::Bool # Presolve infeasibility detection flag - user_parameters::Dict # Additional parameters used for user-defined functional inputs + user_parameters::Dict # [INACTIVE] Additional parameters used for user-defined functional inputs # Features for Integer Problems (NOTE: no support for int-lin problems) - int_enable::Bool # Convert integer problem into binary problem - int_cumulative_disc::Bool # [INACTIVE] Cumulatively involve integer variables for discretization + int_enable::Bool # Convert integer problem into binary problem + int_cumulative_disc::Bool # Cumulatively involve integer variables for discretization int_fully_disc::Bool # [INACTIVE] Construct equivalent formulation for integer variables +end - # add all the solver options - nlp_solver::MathProgBase.AbstractMathProgSolver # Local continuous NLP solver for solving NLPs at each iteration - minlp_solver::MathProgBase.AbstractMathProgSolver # Local MINLP solver for solving MINLPs at each iteration - mip_solver::MathProgBase.AbstractMathProgSolver # MIP solver for successive lower bound solves +function default_options() + loglevel = 1 + timeout = Inf + maxiter = 99 + relgap = 1e-4 + gapref = :ub + absgap = 1e-6 + tol = 1e-6 + largebound = 1e4 + + nlp_solver = nothing + minlp_solver = nothing + mip_solver = nothing + + recognize_convex = true + bilinear_mccormick = false + bilinear_convexhull = true + monomial_convexhull = true + + method_convexification = Array{Function}(undef, 0) + method_partition_injection = Array{Function}(undef, 0) + term_patterns = Array{Function}(undef, 0) + constr_patterns = Array{Function}(undef, 0) + + disc_var_pick = 2 # By default use the 15-variable selective rule + disc_ratio = 4 + disc_uniform_rate = 2 + disc_add_partition_method = "adaptive" + disc_divert_chunks = 5 + disc_abs_width_tol = 1e-4 + disc_rel_width_tol = 1e-6 + disc_consecutive_forbid = 0 + disc_ratio_branch=false + + convhull_formulation = "sos2" + convhull_ebd = false + convhull_ebd_encode = "default" + convhull_ebd_ibs = false + convhull_ebd_link = false + convhull_warmstart = true + convhull_no_good_cuts = true + + presolve_track_time = true + presolve_bt = true + presolve_timeout = 900 + presolve_maxiter = 10 + presolve_bt_width_tol = 1e-3 + presolve_bt_output_tol = 1e-5 + presolve_bt_algo = 1 + presolve_bt_relax = false + presolve_bt_mip_timeout = Inf + presolve_bp = true + + user_parameters = Dict() + int_enable = false + int_cumulative_disc = true + int_fully_disc = false + + return OptimizerOptions(loglevel, timeout, maxiter, relgap, gapref, absgap, tol, largebound, + nlp_solver, minlp_solver, mip_solver, + recognize_convex, bilinear_mccormick, bilinear_convexhull, monomial_convexhull, + method_convexification, method_partition_injection, term_patterns, constr_patterns, + disc_var_pick, disc_ratio, disc_uniform_rate, disc_add_partition_method, disc_divert_chunks, + disc_abs_width_tol, disc_rel_width_tol, disc_consecutive_forbid, disc_ratio_branch, + convhull_formulation, convhull_ebd, convhull_ebd_encode, convhull_ebd_ibs, convhull_ebd_link, convhull_warmstart, convhull_no_good_cuts, + presolve_track_time, presolve_bt, presolve_timeout, presolve_maxiter, presolve_bt_width_tol, presolve_bt_output_tol, + presolve_bt_algo, presolve_bt_relax, presolve_bt_mip_timeout, presolve_bp, + user_parameters, int_enable, int_cumulative_disc, int_fully_disc) +end + + +mutable struct Optimizer <: MOI.AbstractOptimizer + + options::OptimizerOptions # Options set by user # Sub-solver identifier for customized solver option nlp_solver_id::AbstractString # NLP Solver identifier string @@ -87,16 +159,19 @@ mutable struct AlpineNonlinearModel <: MathProgBase.AbstractNonlinearModel var_type_orig::Vector{Symbol} # Variable type vector on original variables (only :Bin, :Cont, :Int) var_start_orig::Vector{Float64} # Variable warm start vector on original variables constr_type_orig::Vector{Symbol} # Constraint type vector on original variables (only :(==), :(>=), :(<=)) + lin_quad_constraints::Vector{Any} # Constraint `func`-in-`set` values constr_expr_orig::Vector{Expr} # Constraint expressions - obj_expr_orig::Union{Expr,Number} # Objective expression + obj_expr_orig::Union{Expr,Number} # Objective expression # additional user inputs useful for local solves l_var_orig::Vector{Float64} # Variable lower bounds u_var_orig::Vector{Float64} # Variable upper bounds - l_constr_orig::Vector{Float64} # Constraint lower bounds - u_constr_orig::Vector{Float64} # Constraint upper bounds - sense_orig::Symbol # Problem type (:Min, :Max) - d_orig::JuMP.NLPEvaluator # Instance of AbstractNLPEvaluator for evaluating gradient, Hessian-vector products, and Hessians of the Lagrangian + constraint_bounds_orig::Vector{MOI.NLPBoundsPair} # Constraint lower bounds + nonlinear_constraint_bounds_orig::Vector{MOI.NLPBoundsPair} # Constraint lower bounds + sense_orig::MOI.OptimizationSense # Problem type (:Min, :Max) + d_orig::Union{Nothing, JuMP.NLPEvaluator} # Instance of AbstractNLPEvaluator for evaluating gradient, Hessian-vector products, and Hessians of the Lagrangian + has_nlp_objective::Bool + objective_function::Union{Nothing, MOI.ScalarAffineFunction{Float64}, MOI.ScalarQuadraticFunction{Float64}} # additional initial data that may be useful later (not populated) A_orig::Any # Linear constraint matrix @@ -127,7 +202,7 @@ mutable struct AlpineNonlinearModel <: MathProgBase.AbstractNonlinearModel nonlinear_constrs::Dict{Any,Any} # Dictionary containing details of special constraints obj_structure::Symbol # A symbolic indicator of the expression type of objective function constr_structure::Vector{Symbol} # A vector indicating whether a constraint is with the special structure - bounding_obj_expr_mip::Union{Expr,Number} # Lifted objective expression; if linear, same as obj_expr_orig + bounding_obj_expr_mip::Union{Expr,Number} # Lifted objective expression; if linear, same as obj_expr_orig bounding_constr_expr_mip::Vector{Expr} # Lifted constraints; if linear, same as corresponding constr_expr_orig bounding_obj_mip::Dict{Any, Any} # Lifted objective expression in affine form bounding_constr_mip::Vector{Dict{Any, Any}} # Lifted constraint expressions in affine form @@ -145,8 +220,10 @@ mutable struct AlpineNonlinearModel <: MathProgBase.AbstractNonlinearModel var_type::Vector{Symbol} # Updated variable type for local solve # Solution information + presolve_infeasible::Bool # Presolve infeasibility detection flag best_bound::Float64 # Best bound from MIP best_obj::Float64 # Best feasible objective value + initial_warmval::Vector{Float64} # Warmstart values set to Alpine best_sol::Vector{Float64} # Best feasible solution best_bound_sol::Vector{Float64} # Best bound solution (arg-min) best_rel_gap::Float64 # Relative optimality gap = |best_obj - best_bound|/|best_obj|*100 @@ -156,536 +233,290 @@ mutable struct AlpineNonlinearModel <: MathProgBase.AbstractNonlinearModel # Logging information and status logs::Dict{Symbol,Any} # Logging information - status::Dict{Symbol,Symbol} # Detailed status of every iteration in the algorithm - alpine_status::Symbol # Current Alpine's status + detected_feasible_solution::Bool + detected_bound::Bool + status::Dict{Symbol, MOI.TerminationStatusCode} # Detailed status of every iteration in the algorithm + alpine_status::MOI.TerminationStatusCode # Current Alpine's status # constructor - function AlpineNonlinearModel(loglevel, - timeout, maxiter, relgap, gapref, absgap, tol, largebound, - nlp_solver, - minlp_solver, - mip_solver, - recognize_convex, - bilinear_mccormick, - bilinear_convexhull, - monomial_convexhull, - method_convexification, - method_partition_injection, - term_patterns, - constr_patterns, - disc_var_pick, - disc_ratio, - disc_uniform_rate, - disc_add_partition_method, - disc_divert_chunks, - disc_abs_width_tol, - disc_rel_width_tol, - disc_consecutive_forbid, - disc_ratio_branch, - convhull_formulation, - convhull_ebd, - convhull_ebd_encode, - convhull_ebd_ibs, - convhull_ebd_link, - convhull_warmstart, - convhull_no_good_cuts, - presolve_track_time, - presolve_bt, - presolve_timeout, - presolve_maxiter, - presolve_bt_width_tol, - presolve_bt_output_tol, - presolve_bt_algo, - presolve_bt_relax, - presolve_bt_mip_timeout, - presolve_bp, - user_parameters, - int_enable, - int_cumulative_disc, - int_fully_disc) + function Optimizer() m = new() - - m.loglevel = loglevel - m.timeout = timeout - m.maxiter = maxiter - m.relgap = relgap - m.gapref = gapref - m.absgap = absgap - m.tol = tol - m.largebound = largebound - - m.recognize_convex = recognize_convex - m.bilinear_mccormick = bilinear_mccormick - m.bilinear_convexhull = bilinear_convexhull - m.monomial_convexhull = monomial_convexhull - - m.method_convexification = method_convexification - m.method_partition_injection = method_partition_injection - m.term_patterns = term_patterns - m.constr_patterns = constr_patterns - - m.disc_var_pick = disc_var_pick - m.disc_ratio = disc_ratio - m.disc_uniform_rate = disc_uniform_rate - m.disc_add_partition_method = disc_add_partition_method - m.disc_divert_chunks = disc_divert_chunks - m.disc_abs_width_tol = disc_abs_width_tol - m.disc_rel_width_tol = disc_rel_width_tol - m.disc_consecutive_forbid = disc_consecutive_forbid - m.disc_ratio_branch = disc_ratio_branch - - m.convhull_formulation = convhull_formulation - m.convhull_ebd = convhull_ebd - m.convhull_ebd_encode = convhull_ebd_encode - m.convhull_ebd_ibs = convhull_ebd_ibs - m.convhull_ebd_link = convhull_ebd_link - m.convhull_warmstart = convhull_warmstart - m.convhull_no_good_cuts = convhull_no_good_cuts - - m.presolve_track_time = presolve_track_time - m.presolve_bt = presolve_bt - m.presolve_timeout = presolve_timeout - m.presolve_maxiter = presolve_maxiter - m.presolve_bt_width_tol = presolve_bt_width_tol - m.presolve_bt_output_tol = presolve_bt_output_tol - m.presolve_bt_algo = presolve_bt_algo - m.presolve_bt_relax = presolve_bt_relax - m.presolve_bt_mip_timeout = presolve_bt_mip_timeout - - m.presolve_bp = presolve_bp - - m.nlp_solver = nlp_solver - m.minlp_solver = minlp_solver - m.mip_solver = mip_solver - - m.user_parameters = user_parameters - m.int_enable = int_enable - m.int_cumulative_disc = int_cumulative_disc - m.int_fully_disc = int_fully_disc - - m.num_var_orig = 0 - m.num_cont_var_orig = 0 - m.num_int_var_orig = 0 - m.num_constr_orig = 0 - m.num_lconstr_orig = 0 - m.num_nlconstr_orig = 0 - m.var_type_orig = Symbol[] - m.var_start_orig = Float64[] - m.constr_type_orig = Symbol[] - m.constr_expr_orig = Expr[] - m.num_lconstr_updated = 0 - m.num_nlconstr_updated = 0 - m.indexes_lconstr_updated = Int[] - - m.linear_terms = Dict() - m.nonconvex_terms = Dict() - m.term_seq = Dict() - m.nonlinear_constrs = Dict() - m.candidate_disc_vars = Int[] - m.bounding_constr_expr_mip = [] - m.bounding_constr_mip = [] - m.disc_vars = [] - m.int_vars = [] - m.bin_vars = [] - m.discretization = Dict() - m.num_var_linear_mip = 0 - m.num_var_nonlinear_mip = 0 - m.num_var_disc_mip = 0 - m.num_constr_convex = 0 - m.constr_structure = [] - m.best_bound_sol = [] - m.bound_sol_history = [] - m.presolve_infeasible = false - m.bound_sol_history = Vector{Vector{Float64}}(undef, m.disc_consecutive_forbid) - - m.best_obj = Inf - m.best_bound = -Inf - m.best_rel_gap = Inf - m.best_abs_gap = Inf - m.alpine_status = :NotLoaded - - create_status!(m) - create_logs!(m) + m.options = default_options() + MOI.empty!(m) return m end end -struct UnsetSolver <: MathProgBase.AbstractMathProgSolver +struct NumberOfIterations <: MOI.AbstractModelAttribute end +MOI.is_set_by_optimize(::NumberOfIterations) = true +MOI.get(m::Optimizer, ::NumberOfIterations) = m.logs[:n_iter] + +struct NumberOfPresolveIterations <: MOI.AbstractModelAttribute end +MOI.is_set_by_optimize(::NumberOfPresolveIterations) = true +MOI.get(m::Optimizer, ::NumberOfPresolveIterations) = m.logs[:bt_iter] + +MOI.get(m::Optimizer, ::MOI.TerminationStatus) = m.alpine_status +MOI.get(m::Optimizer, ::MOI.ObjectiveValue) = m.best_obj +MOI.get(m::Optimizer, ::MOI.ObjectiveBound) = m.best_bound +MOI.get(m::Optimizer, ::MOI.SolveTime) = m.logs[:total_time] + +function get_option(m::Optimizer, s::Symbol) + getproperty(m.options, s) +end + +function set_option(m::Optimizer, s::Symbol, val) + setproperty!(m.options, s, val) +end + +function MOI.is_empty(model::Optimizer) + return iszero(model.num_var_orig) end -const empty_solver = UnsetSolver() - -mutable struct AlpineSolver <: MathProgBase.AbstractMathProgSolver - - loglevel::Int - timeout::Float64 - maxiter::Int - relgap::Float64 - gapref::Symbol - absgap::Float64 - tol::Float64 - largebound::Float64 - - nlp_solver::MathProgBase.AbstractMathProgSolver - minlp_solver::MathProgBase.AbstractMathProgSolver - mip_solver::MathProgBase.AbstractMathProgSolver - - recognize_convex::Bool - bilinear_mccormick::Bool - bilinear_convexhull::Bool - monomial_convexhull::Bool - - method_convexification::Array{Function} - method_partition_injection::Array{Function} - term_patterns::Array{Function} - constr_patterns::Array{Function} - - disc_var_pick::Any - disc_ratio::Any - disc_uniform_rate::Int - disc_add_partition_method::Any - disc_divert_chunks::Int - disc_abs_width_tol::Float64 - disc_rel_width_tol::Float64 - disc_consecutive_forbid::Int - disc_ratio_branch::Bool - - convhull_formulation::String - convhull_ebd::Bool - convhull_ebd_encode::Any - convhull_ebd_ibs::Bool - convhull_ebd_link::Bool - convhull_warmstart::Bool - convhull_no_good_cuts::Bool - - presolve_track_time::Bool - presolve_bt::Bool - presolve_timeout::Float64 - presolve_maxiter::Int - presolve_bt_width_tol::Float64 - presolve_bt_output_tol::Float64 - presolve_bt_algo::Any - presolve_bt_relax::Bool - presolve_bt_mip_timeout::Float64 - - presolve_bp::Bool - - user_parameters::Dict - int_enable::Bool - int_cumulative_disc::Bool - int_fully_disc::Bool - - # other options to be added later on +function MOI.empty!(m::Optimizer) + m.nlp_solver_id = "" + m.minlp_solver_id = "" + m.mip_solver_id = "" + + m.num_var_orig = 0 + m.num_cont_var_orig = 0 + m.num_int_var_orig = 0 + m.num_constr_orig = 0 + m.num_lconstr_orig = 0 + m.num_nlconstr_orig = 0 + m.var_type_orig = Symbol[] + m.var_start_orig = Float64[] + m.constr_type_orig = Symbol[] + m.lin_quad_constraints = Any[] + m.constr_expr_orig = Expr[] + m.num_lconstr_updated = 0 + m.num_nlconstr_updated = 0 + m.indexes_lconstr_updated = Int[] + + m.l_var_orig = Float64[] + m.u_var_orig = Float64[] + m.constraint_bounds_orig = MOI.NLPBoundsPair[] + m.nonlinear_constraint_bounds_orig = MOI.NLPBoundsPair[] + m.sense_orig = MOI.FEASIBILITY_SENSE + + m.d_orig = nothing + m.has_nlp_objective = false + m.objective_function = nothing + + m.linear_terms = Dict() + m.nonconvex_terms = Dict() + m.term_seq = Dict() + m.nonlinear_constrs = Dict() + m.candidate_disc_vars = Int[] + m.bounding_constr_expr_mip = [] + m.bounding_constr_mip = [] + m.disc_vars = [] + m.int_vars = [] + m.bin_vars = [] + m.discretization = Dict() + m.num_var_linear_mip = 0 + m.num_var_nonlinear_mip = 0 + m.num_var_disc_mip = 0 + m.num_constr_convex = 0 + m.constr_structure = Symbol[] + m.best_bound_sol = [] + m.bound_sol_history = [] + m.presolve_infeasible = false + m.bound_sol_history = Vector{Vector{Float64}}(undef, m.options.disc_consecutive_forbid) + + m.best_obj = Inf + m.initial_warmval = Float64[] + m.best_sol = Float64[] + m.best_bound = -Inf + m.best_rel_gap = Inf + m.best_abs_gap = Inf + m.alpine_status = MOI.OPTIMIZE_NOT_CALLED + + create_status!(m) + create_logs!(m) end -function AlpineSolver(; - - loglevel = 1, - timeout = Inf, - maxiter = 99, - relgap = 1e-4, - gapref = :ub, - absgap = 1e-6, - tol = 1e-6, - largebound = 1e4, - - nlp_solver = empty_solver, - minlp_solver = empty_solver, - mip_solver = empty_solver, - - recognize_convex = true, - bilinear_mccormick = false, - bilinear_convexhull = true, - monomial_convexhull = true, - - method_convexification = Array{Function}(undef, 0), - method_partition_injection = Array{Function}(undef, 0), - term_patterns = Array{Function}(undef, 0), - constr_patterns = Array{Function}(undef, 0), - - disc_var_pick = 2, # By default use the 15-variable selective rule - disc_ratio = 4, - disc_uniform_rate = 2, - disc_add_partition_method = "adaptive", - disc_divert_chunks = 5, - disc_abs_width_tol = 1e-4, - disc_rel_width_tol = 1e-6, - disc_consecutive_forbid = 0, - disc_ratio_branch=false, - - convhull_formulation = "sos2", - convhull_ebd = false, - convhull_ebd_encode = "default", - convhull_ebd_ibs = false, - convhull_ebd_link = false, - convhull_warmstart = true, - convhull_no_good_cuts = true, - - presolve_track_time = true, - presolve_maxiter = 10, - presolve_bt = true, - presolve_timeout = 900, - presolve_bt_width_tol = 1e-3, - presolve_bt_output_tol = 1e-5, - presolve_bt_algo = 1, - presolve_bt_relax = false, - presolve_bt_mip_timeout = Inf, - - presolve_bp = true, - - user_parameters = Dict(), - int_enable = false, - int_cumulative_disc = true, - int_fully_disc = false, - - kwargs... - ) - - # Keyword arguments screening - unsupported_kwargs = Dict(kwargs) - !isempty(keys(unsupported_kwargs)) && error("Detected unsupported keyword arguments: $(keys(unsupport_opts))") - - if nlp_solver == empty_solver && minlp_solver == empty_solver - error("No NLP and MINLP local solver specified; use nlp_solver or minlp_solver to set a local solver dependening on the problem type\n") - end - mip_solver == empty_solver && error("No MIP solver specififed; use mip_solver to set a mip solver\n") - - if nlp_solver != empty_solver && !applicable(MathProgBase.NonlinearModel, nlp_solver) - error("NLP local solver $(s.nlp_solver) is not supported by JuMP; use a JuMP-supoorted NLP local solver\n") - end - - if minlp_solver != empty_solver && !applicable(MathProgBase.NonlinearModel, minlp_solver) - error("MINLP local solver $(s.minlp_solver) is not supported by JuMP; use a JuMP-supoorted MINLP local solver\n") - end - - gapref in [:ub, :lb] || error("the option gapref can take a value only in [:ub, :lb]") - - # String Code Conversion (have to change this to consistently use Symbols and not give user many options) - if disc_var_pick in ["ncvar_collect_nodes", "all", "max"] - disc_var_pick = 0 - elseif disc_var_pick in ["min_vertex_cover","min"] - disc_var_pick = 1 - elseif disc_var_pick == "selective" - disc_var_pick = 2 - elseif disc_var_pick == "dynamic" - disc_var_pick = 3 +MOIU.supports_default_copy_to(model::Optimizer, copy_names::Bool) = !copy_names + +function MOI.copy_to(model::Optimizer, src::MOI.ModelLike; copy_names = false) + return MOIU.default_copy_to(model, src, copy_names) +end + +MOI.get(::Optimizer, ::MOI.SolverName) = "Alpine" + +function MOI.set(model::Optimizer, param::MOI.RawParameter, value) + set_option(model, Symbol(param.name), value) +end +function MOI.get(model::Optimizer, param::MOI.RawParameter) + get_option(model, Symbol(param.name)) +end + +function MOI.add_variables(model::Optimizer, n::Int) + return [MOI.add_variable(model) for i in 1:n] +end +function MOI.add_variable(model::Optimizer) + model.num_var_orig += 1 + push!(model.l_var_orig, -Inf) + push!(model.u_var_orig, Inf) + push!(model.var_type_orig, :Cont) + push!(model.initial_warmval, 0.0) + push!(model.best_sol, 0.0) + return MOI.VariableIndex(model.num_var_orig) +end + +function MOI.supports(::Optimizer, ::MOI.VariablePrimalStart, + ::Type{MOI.VariableIndex}) + return true +end +function MOI.set(model::Optimizer, ::MOI.VariablePrimalStart, + vi::MOI.VariableIndex, value::Union{Real, Nothing}) + model.best_sol[vi.value] = model.initial_warmval[vi.value] = something(value, 0.0) + return +end + +const SCALAR_SET = Union{MOI.EqualTo{Float64}, MOI.LessThan{Float64}, MOI.GreaterThan{Float64}, MOI.Interval{Float64}} + +MOI.supports_constraint(::Optimizer, ::Type{MOI.SingleVariable}, ::Type{<:SCALAR_SET}) = true + +_lower(set::MOI.EqualTo) = set.value +_upper(set::MOI.EqualTo) = set.value +_lower(set::MOI.LessThan) = nothing +_upper(set::MOI.LessThan) = set.upper +_lower(set::MOI.GreaterThan) = set.lower +_upper(set::MOI.GreaterThan) = nothing +_lower(set::MOI.Interval) = set.lower +_upper(set::MOI.Interval) = set.upper + +function MOI.add_constraint(model::Optimizer, f::MOI.SingleVariable, set::SCALAR_SET) + vi = f.variable + l = _lower(set) + if l !== nothing + model.l_var_orig[vi.value] = l + end + u = _upper(set) + if u !== nothing + model.u_var_orig[vi.value] = u end + return MOI.ConstraintIndex{typeof(f), typeof(set)}(vi.value) +end - # Deep-copy the solver options because Alpine may modify some options - AlpineSolver( - loglevel, timeout, maxiter, relgap, gapref, absgap, tol, largebound, - deepcopy(nlp_solver), - deepcopy(minlp_solver), - deepcopy(mip_solver), - recognize_convex, - bilinear_mccormick, - bilinear_convexhull, - monomial_convexhull, - method_convexification, - method_partition_injection, - term_patterns, - constr_patterns, - disc_var_pick, - disc_ratio, - disc_uniform_rate, - disc_add_partition_method, - disc_divert_chunks, - disc_abs_width_tol, - disc_rel_width_tol, - disc_consecutive_forbid, - disc_ratio_branch, - convhull_formulation, - convhull_ebd, - convhull_ebd_encode, - convhull_ebd_ibs, - convhull_ebd_link, - convhull_warmstart, - convhull_no_good_cuts, - presolve_track_time, - presolve_bt, - presolve_timeout, - presolve_maxiter, - presolve_bt_width_tol, - presolve_bt_output_tol, - presolve_bt_algo, - presolve_bt_relax, - presolve_bt_mip_timeout, - presolve_bp, - user_parameters, - int_enable, - int_cumulative_disc, - int_fully_disc) +MOI.supports_constraint(::Optimizer, ::Type{MOI.SingleVariable}, ::Type{MOI.Integer}) = true + +function MOI.add_constraint(model::Optimizer, f::MOI.SingleVariable, set::MOI.Integer) + model.var_type_orig[f.variable.value] = :Int + return MOI.ConstraintIndex{typeof(f), typeof(set)}(f.variable.value) +end +MOI.supports_constraint(::Optimizer, ::Type{MOI.SingleVariable}, ::Type{MOI.ZeroOne}) = true + +function MOI.add_constraint(model::Optimizer, f::MOI.SingleVariable, set::MOI.ZeroOne) + model.var_type_orig[f.variable.value] = :Bin + return MOI.ConstraintIndex{typeof(f), typeof(set)}(f.variable.value) +end + +MOI.supports_constraint(model::Optimizer, ::Type{<:Union{MOI.ScalarAffineFunction{Float64}, MOI.ScalarQuadraticFunction{Float64}}}, ::Type{<:SCALAR_SET}) = true + +function MOI.add_constraint(model::Optimizer, f::Union{MOI.ScalarAffineFunction{Float64}, MOI.ScalarQuadraticFunction{Float64}}, set::SCALAR_SET) + model.num_constr_orig += 1 + push!(model.constraint_bounds_orig, MOI.NLPBoundsPair(something(_lower(set), -Inf), something(_upper(set), Inf))) + iszero(f.constant) || throw(MOI.ScalarFunctionConstantNotZero{Float64, typeof(f), typeof(set)}(f.constant)) + push!(model.lin_quad_constraints, (copy(f), copy(set))) + push!(model.constr_expr_orig, _constraint_expr(_moi_function_to_expr(f), set)) + if f isa MOI.ScalarAffineFunction + model.num_lconstr_orig += 1 + push!(model.constr_structure, :generic_linear) + else + model.num_nlconstr_orig += 1 + push!(model.constr_structure, :generic_nonlinear) end -# Create Alpine's nonlinear model -- can solve with nonlinear algorithm only -function MathProgBase.NonlinearModel(s::AlpineSolver) - - # Translate options into old nonlinearmodel.jl fields - loglevel = s.loglevel - timeout = s.timeout - maxiter = s.maxiter - relgap = s.relgap - gapref = s.gapref - absgap = s.absgap - tol = s.tol - largebound = s.largebound - - recognize_convex = s.recognize_convex - bilinear_mccormick = s.bilinear_mccormick - bilinear_convexhull = s.bilinear_convexhull - monomial_convexhull = s.monomial_convexhull - - method_convexification = s.method_convexification - method_partition_injection = s.method_partition_injection - term_patterns = s.term_patterns - constr_patterns = s.constr_patterns - - nlp_solver = s.nlp_solver - minlp_solver = s.minlp_solver - mip_solver = s.mip_solver - - disc_var_pick = s.disc_var_pick - disc_ratio = s.disc_ratio - disc_uniform_rate = s.disc_uniform_rate - disc_add_partition_method = s.disc_add_partition_method - disc_divert_chunks = s.disc_divert_chunks - disc_abs_width_tol = s.disc_abs_width_tol - disc_rel_width_tol = s.disc_rel_width_tol - disc_consecutive_forbid = s.disc_consecutive_forbid - disc_ratio_branch = s.disc_ratio_branch - - convhull_formulation = s.convhull_formulation - convhull_ebd = s.convhull_ebd - convhull_ebd_encode = s.convhull_ebd_encode - convhull_ebd_ibs = s.convhull_ebd_ibs - convhull_ebd_link = s.convhull_ebd_link - convhull_warmstart = s.convhull_warmstart - convhull_no_good_cuts = s.convhull_no_good_cuts - - presolve_track_time = s.presolve_track_time - presolve_bt = s.presolve_bt - presolve_timeout = s.presolve_timeout - presolve_maxiter = s.presolve_maxiter - presolve_bt_width_tol = s.presolve_bt_width_tol - presolve_bt_output_tol = s.presolve_bt_output_tol - presolve_bt_algo = s.presolve_bt_algo - presolve_bt_relax = s.presolve_bt_relax - presolve_bt_mip_timeout = s.presolve_bt_mip_timeout - - presolve_bp = s.presolve_bp - - user_parameters = s.user_parameters - int_enable = s.int_enable - int_cumulative_disc = s.int_cumulative_disc - int_fully_disc = s.int_fully_disc - - return AlpineNonlinearModel(loglevel, - timeout, maxiter, relgap, gapref, absgap, tol, largebound, - nlp_solver, - minlp_solver, - mip_solver, - recognize_convex, - bilinear_mccormick, - bilinear_convexhull, - monomial_convexhull, - method_convexification, - method_partition_injection, - term_patterns, - constr_patterns, - disc_var_pick, - disc_ratio, - disc_uniform_rate, - disc_add_partition_method, - disc_divert_chunks, - disc_abs_width_tol, - disc_rel_width_tol, - disc_consecutive_forbid, - disc_ratio_branch, - convhull_formulation, - convhull_ebd, - convhull_ebd_encode, - convhull_ebd_ibs, - convhull_ebd_link, - convhull_warmstart, - convhull_no_good_cuts, - presolve_track_time, - presolve_bt, - presolve_timeout, - presolve_maxiter, - presolve_bt_width_tol, - presolve_bt_output_tol, - presolve_bt_algo, - presolve_bt_relax, - presolve_bt_mip_timeout, - presolve_bp, - user_parameters, - int_enable, - int_cumulative_disc, - int_fully_disc) + return MOI.ConstraintIndex{typeof(f), typeof(set)}(model.num_constr_orig) end -function MathProgBase.loadproblem!(m::AlpineNonlinearModel, - num_var::Int, - num_constr::Int, - l_var::Vector{Float64}, - u_var::Vector{Float64}, - l_constr::Vector{Float64}, - u_constr::Vector{Float64}, - sense::Symbol, - d::MathProgBase.AbstractNLPEvaluator) - - println("***********************************************************************") - println(" This package contains Alpine.jl, a global solver for nonconvex MINLPs") - println(" If you find it useful, please cite the following paper: ") - println(" Journal of Global Optimization, 2019, https://goo.gl/89zrDf") - println("***********************************************************************") - - # Populating AlpineNonlinearModel (invoked by JuMP.build(m)) - m.num_var_orig = num_var - m.num_constr_orig = num_constr - m.l_var_orig = l_var - m.u_var_orig = u_var - m.l_constr_orig = l_constr - m.u_constr_orig = u_constr - m.sense_orig = sense - if m.sense_orig == :Max - m.best_obj = -Inf - m.best_bound = Inf +function MOI.supports(model::Optimizer, ::Union{MOI.ObjectiveSense, MOI.ObjectiveFunction{F}}) where F<:Union{MOI.ScalarAffineFunction{Float64}, MOI.ScalarQuadraticFunction{Float64}} + return true +end + +is_min_sense(model::Optimizer) = model.sense_orig == MOI.MIN_SENSE +is_max_sense(model::Optimizer) = model.sense_orig == MOI.MAX_SENSE +function MOI.set(model::Optimizer, ::MOI.ObjectiveSense, sense) + model.sense_orig = sense + if is_max_sense(model) + model.best_obj = -Inf + model.best_bound = Inf + elseif is_min_sense(model) + model.best_obj = Inf + model.best_bound = -Inf else - m.best_obj = Inf - m.best_bound = -Inf + error("Feasibility sense not supported yet by Alpine.") + end +end + +function MOI.set(model::Optimizer, ::MOI.ObjectiveFunction{F}, func::F) where F + model.objective_function = func +end + +function MOI.set(m::Optimizer, ::MOI.NLPBlock, block) + m.d_orig = block.evaluator + m.has_nlp_objective = block.has_objective + # We cache it to add it in `load!` as we cannot call `MOI.constraint_expr` yet + # so we will add the nonlinear `constr_expr_orig` at the end so we need + # to add the bounds at the end too. + # So we can consider that the nonlinear constraints are the + # `length(m.nonlinear_constraint_bounds_orig)` last ones. + m.nonlinear_constraint_bounds_orig = block.constraint_bounds +end + +# In JuMP v0.18/MathProgBase, the 5th decision variable would be `:(x[5])`. +# In JuMP v0.19/MathOptInterface, it is now `:(x[MOI.VariableIndex(5)])`. +# To ease the transition, we simply transform it back to what it used to be. +_variable_index_to_index(expr::Union{Number, Symbol}) = expr +_variable_index_to_index(expr::MOI.VariableIndex) = expr.value +function _variable_index_to_index(expr::Expr) + for i in eachindex(expr.args) + expr.args[i] = _variable_index_to_index(expr.args[i]) end - m.d_orig = d + return expr +end +_index_to_variable_ref(m::JuMP.Model, idx::Int64) = JuMP.VariableRef(m, MOI.VariableIndex(idx)) +function load!(m::Optimizer) # Initialize NLP interface - interface_init_nonlinear_data(m.d_orig) + MOI.initialize(m.d_orig, [:Grad, :Jac, :Hess, :HessVec, :ExprGraph]) # Safety scheme for sub-solvers re-initializing the NLPEvaluator # Collect objective & constraint expressions - m.obj_expr_orig = expr_isolate_const(interface_get_obj_expr(m.d_orig)) # see in nlexpr.jl if this expr isolation has any issue - - for i in 1:m.num_constr_orig - push!(m.constr_expr_orig, interface_get_constr_expr(m.d_orig, i)) + if m.has_nlp_objective + m.obj_expr_orig = expr_isolate_const(_variable_index_to_index(MOI.objective_expr(m.d_orig))) # see in nlexpr.jl if this expr isolation has any issue + elseif m.objective_function isa Nothing + m.obj_expr_orig = Expr(:call, :+) + else + m.obj_expr_orig = _moi_function_to_expr(m.objective_function) end # Collect original variable type and build dynamic variable type space - m.var_type_orig = [getcategory(Variable(d.m, i)) for i in 1:m.num_var_orig] m.var_type = copy(m.var_type_orig) m.int_vars = [i for i in 1:m.num_var_orig if m.var_type[i] == :Int] m.bin_vars = [i for i in 1:m.num_var_orig if m.var_type[i] == :Bin] - if !isempty(m.int_vars) || !isempty(m.bin_vars) - (m.minlp_solver == empty_solver) && (error("No MINLP local solver specified; use minlp_solver to specify a MINLP local solver")) - end + if !isempty(m.int_vars) || !isempty(m.bin_vars) + (get_option(m, :minlp_solver) === nothing) && (error("No MINLP local solver specified; use minlp_solver to specify a MINLP local solver")) + end + + m.num_constr_orig += length(m.nonlinear_constraint_bounds_orig) + m.num_nlconstr_orig += length(m.nonlinear_constraint_bounds_orig) + append!(m.constraint_bounds_orig, m.nonlinear_constraint_bounds_orig) + for i in eachindex(m.nonlinear_constraint_bounds_orig) + push!(m.constr_expr_orig, _variable_index_to_index(MOI.constraint_expr(m.d_orig, i))) + push!(m.constr_structure, :generic_nonlinear) + end # Summarize constraints information in original model m.constr_type_orig = Array{Symbol}(undef, m.num_constr_orig) for i in 1:m.num_constr_orig - if l_constr[i] > -Inf && u_constr[i] < Inf + if m.constraint_bounds_orig[i].lower > -Inf && m.constraint_bounds_orig[i].upper < Inf m.constr_type_orig[i] = :(==) - elseif l_constr[i] > -Inf + elseif m.constraint_bounds_orig[i].lower > -Inf m.constr_type_orig[i] = :(>=) else m.constr_type_orig[i] = :(<=) @@ -694,37 +525,27 @@ function MathProgBase.loadproblem!(m::AlpineNonlinearModel, # Initialize recognizable structure properties with :none m.obj_structure = :none - m.constr_structure = [:none for i in 1:m.num_constr_orig] - for i = 1:m.num_constr_orig - if interface_is_constr_linear(m.d_orig, i) - m.num_lconstr_orig += 1 - m.constr_structure[i] = :generic_linear - else - m.num_nlconstr_orig += 1 - m.constr_structure[i] = :generic_nonlinear - end - end - + @assert m.num_constr_orig == m.num_nlconstr_orig + m.num_lconstr_orig - m.is_obj_linear_orig = interface_is_obj_linear(m.d_orig) + m.is_obj_linear_orig = !m.has_nlp_objective && m.objective_function isa MOI.ScalarAffineFunction{Float64} m.is_obj_linear_orig ? (m.obj_structure = :generic_linear) : (m.obj_structure = :generic_nonlinear) isa(m.obj_expr_orig, Number) && (m.obj_structure = :constant) - + # populate data to create the bounding model recategorize_var(m) # Initial round of variable re-categorization :Int in m.var_type_orig && @warn "Alpine's support for integer variables is experimental" - :Int in m.var_type_orig ? m.int_enable = true : m.int_enable = false # Separator for safer runs + :Int in m.var_type_orig ? set_option(m, :int_enable, true) : set_option(m, :int_enable, false) # Separator for safer runs # Conduct solver-dependent detection fetch_mip_solver_identifier(m) - (m.nlp_solver != empty_solver) && (fetch_nlp_solver_identifier(m)) - (m.minlp_solver != empty_solver) && (fetch_minlp_solver_identifier(m)) + (get_option(m, :nlp_solver) !== nothing) && (fetch_nlp_solver_identifier(m)) + (get_option(m, :minlp_solver) !== nothing) && (fetch_minlp_solver_identifier(m)) # Solver Dependent Options if m.mip_solver_id != :Gurobi - m.convhull_warmstart == false - m.convhull_no_good_cuts == false + get_option(m, :convhull_warmstart) == false + get_option(m, :convhull_no_good_cuts) == false end # Main Algorithmic Initialization @@ -735,24 +556,21 @@ function MathProgBase.loadproblem!(m::AlpineNonlinearModel, init_disc(m) # Initialize discretization dictionaries # Turn-on bt presolver if variables are not discrete - if isempty(m.int_vars) && length(m.bin_vars) <= 50 && m.num_var_orig <= 10000 && length(m.candidate_disc_vars)<=300 && m.presolve_bt == nothing - m.presolve_bt = true + if isempty(m.int_vars) && length(m.bin_vars) <= 50 && m.num_var_orig <= 10000 && length(m.candidate_disc_vars)<=300 && get_option(m, :presolve_bt) == nothing + set_option(m, :presolve_bt, true) println("Automatically turning on bound-tightening presolver...") - elseif m.presolve_bt == nothing # If no use indication - m.presolve_bt = false + elseif get_option(m, :presolve_bt) == nothing # If no use indication + set_option(m, :presolve_bt, false) end if length(m.bin_vars) > 200 || m.num_var_orig > 2000 println("Automatically turning OFF ratio branching due to the size of the problem") - m.disc_ratio_branch=false + set_option(m, :disc_ratio_branch, false) end # Initialize the solution pool m.bound_sol_pool = initialize_solution_pool(m, 0) # Initialize the solution pool - # Record the initial solution from the warm-starting value, if any - m.best_sol = m.d_orig.m.colVal - # Check if any illegal term exist in the warm-solution any(isnan, m.best_sol) && (m.best_sol = zeros(length(m.best_sol))) @@ -761,3 +579,9 @@ function MathProgBase.loadproblem!(m::AlpineNonlinearModel, return end + +function MOI.get(model::Optimizer, attr::MOI.VariablePrimal, vi::MOI.VariableIndex) + MOI.check_result_index_bounds(model, attr) + MOI.throw_if_not_valid(model, vi) + return model.best_sol[vi.value] +end diff --git a/src/tmc.jl b/src/tmc.jl index 57b0ec41..990642f3 100644 --- a/src/tmc.jl +++ b/src/tmc.jl @@ -1,7 +1,7 @@ """ TODO: docstring """ -function amp_post_mccormick(m::AlpineNonlinearModel; kwargs...) +function amp_post_mccormick(m::Optimizer; kwargs...) options = Dict(kwargs) @@ -16,7 +16,7 @@ function amp_post_mccormick(m::AlpineNonlinearModel; kwargs...) for bi in keys(m.nonconvex_terms) nl_type = m.nonconvex_terms[bi][:nonlinear_type] - if ((!m.monomial_convexhull)*(nl_type == :MONOMIAL) || (!m.bilinear_convexhull)*(nl_type == :BILINEAR)) && (m.nonconvex_terms[bi][:convexified] == false) + if ((!get_option(m, :monomial_convexhull))*(nl_type == :MONOMIAL) || (!get_option(m, :bilinear_convexhull))*(nl_type == :BILINEAR)) && (m.nonconvex_terms[bi][:convexified] == false) @assert length(bi) == 2 m.nonconvex_terms[bi][:convexified] = true # Bookeeping the examined terms idx_a = bi[1].args[2] @@ -38,9 +38,9 @@ function amp_post_mccormick(m::AlpineNonlinearModel; kwargs...) if (length(lb[idx_a]) == 1) && (length(lb[idx_b]) == 1) # Basic McCormick if m.nonconvex_terms[bi][:nonlinear_type] == :MONOMIAL - mccormick_monomial(m.model_mip, Variable(m.model_mip, idx_ab), Variable(m.model_mip,idx_a), lb[idx_a][1], ub[idx_a][1]) + mccormick_monomial(m.model_mip, _index_to_variable_ref(m.model_mip, idx_ab), _index_to_variable_ref(m.model_mip,idx_a), lb[idx_a][1], ub[idx_a][1]) elseif m.nonconvex_terms[bi][:nonlinear_type] == :BILINEAR - mccormick(m.model_mip, Variable(m.model_mip, idx_ab), Variable(m.model_mip, idx_a), Variable(m.model_mip, idx_b), + mccormick(m.model_mip, _index_to_variable_ref(m.model_mip, idx_ab), _index_to_variable_ref(m.model_mip, idx_a), _index_to_variable_ref(m.model_mip, idx_b), lb[idx_a][1], ub[idx_a][1], lb[idx_b][1], ub[idx_b][1]) end else # Tighten McCormick @@ -56,7 +56,7 @@ function amp_post_mccormick(m::AlpineNonlinearModel; kwargs...) if (idx_a in m.disc_vars) && !(idx_b in m.disc_vars) && (part_cnt_b == 1) λ = amp_post_tmc_λ(m.model_mip, λ, lb, ub, part_cnt_a, idx_a) λX = amp_post_tmc_λX(m.model_mip, λX, part_cnt_a, idx_a, idx_b) - λX[(idx_b,idx_a)] = [Variable(m.model_mip, idx_a)] + λX[(idx_b,idx_a)] = [_index_to_variable_ref(m.model_mip, idx_a)] λλ = amp_post_tmc_λλ(m.model_mip, λλ, λ, idx_a, idx_b) amp_post_tmc_λxX_mc(m.model_mip, λX, λ, lb, ub, idx_a, idx_b) amp_post_tmc_XX_mc(m.model_mip, idx_ab, λX, λλ, lb, ub, idx_a, idx_b) @@ -66,7 +66,7 @@ function amp_post_mccormick(m::AlpineNonlinearModel; kwargs...) if !(idx_a in m.disc_vars) && (idx_b in m.disc_vars) && (part_cnt_a == 1) λ = amp_post_tmc_λ(m.model_mip, λ, lb, ub, part_cnt_b, idx_b) λX = amp_post_tmc_λX(m.model_mip, λX, part_cnt_b, idx_b, idx_a) - λX[(idx_a,idx_b)] = [Variable(m.model_mip, idx_b)] + λX[(idx_a,idx_b)] = [_index_to_variable_ref(m.model_mip, idx_b)] λλ = amp_post_tmc_λλ(m.model_mip, λλ, λ, idx_b, idx_a) amp_post_tmc_λxX_mc(m.model_mip, λX, λ, lb, ub, idx_b, idx_a) amp_post_tmc_XX_mc(m.model_mip,idx_ab, λX, λλ, lb, ub, idx_b, idx_a) @@ -98,34 +98,34 @@ end function amp_post_tmc_λ(m::JuMP.Model, λ::Dict, lb::Dict, ub::Dict, dim::Int, idx::Int, relax=false) if !haskey(λ, idx) - λ[idx] = @variable(m, [1:dim], Bin, basename=string("L",idx)) + λ[idx] = @variable(m, [1:dim], Bin, base_name=string("L",idx)) @constraint(m, sum(λ[idx]) == 1) # The SOS-1 Constraints, not all MIP solver has SOS feature - @constraint(m, Variable(m, idx) >= dot(lb[idx], λ[idx])) - @constraint(m, Variable(m, idx) <= dot(ub[idx], λ[idx])) + @constraint(m, _index_to_variable_ref(m, idx) >= dot(lb[idx], λ[idx])) + @constraint(m, _index_to_variable_ref(m, idx) <= dot(ub[idx], λ[idx])) end return λ end function amp_post_tmc_monomial_mc(m::JuMP.Model, idx_aa::Int, λ::Dict, λX::Dict, LB::Dict, UB::Dict, dim::Int, idx_a::Int) - @constraint(m, Variable(m, idx_aa) >= Variable(m, idx_a)^(2)) - @constraint(m, Variable(m, idx_aa) <= dot(λX[(idx_a,idx_a)],LB[idx_a]) + dot(λX[(idx_a,idx_a)],UB[idx_a]) - dot(λ[idx_a], *(Matrix(Diagonal(LB[idx_a])), UB[idx_a]))) + @constraint(m, _index_to_variable_ref(m, idx_aa) >= _index_to_variable_ref(m, idx_a)^(2)) + @constraint(m, _index_to_variable_ref(m, idx_aa) <= dot(λX[(idx_a,idx_a)],LB[idx_a]) + dot(λX[(idx_a,idx_a)],UB[idx_a]) - dot(λ[idx_a], *(Matrix(Diagonal(LB[idx_a])), UB[idx_a]))) return end function amp_post_tmc_λX(m::JuMP.Model, λX::Dict, dim::Int, idx_a::Int, idx_b::Int) if !haskey(λX, (idx_a,idx_b)) - λX[(idx_a,idx_b)] = @variable(m, [1:dim], basename=string("L",idx_a,"X",idx_b)) + λX[(idx_a,idx_b)] = @variable(m, [1:dim], base_name=string("L",idx_a,"X",idx_b)) end return λX end function amp_post_tmc_λλ(m::JuMP.Model, λλ::Dict, dim_a::Int, dim_b::Int, idx_a::Int, idx_b::Int) if !haskey(λλ, (idx_a, idx_b)) - λλ[(idx_a,idx_b)] = @variable(m, [1:dim_a, 1:dim_b], basename=string("L",idx_a,"L",idx_b)) + λλ[(idx_a,idx_b)] = @variable(m, [1:dim_a, 1:dim_b], base_name=string("L",idx_a,"L",idx_b)) for i in 1:dim_a for j in 1:dim_b - setlowerbound(λλ[(idx_a, idx_b)][i,j], 0); - setupperbound(λλ[(idx_a, idx_b)][i,j], 1); + JuMP.set_lower_bound(λλ[(idx_a, idx_b)][i,j], 0); + JuMP.set_upper_bound(λλ[(idx_a, idx_b)][i,j], 1); end end λλ[(idx_b,idx_a)] = λλ[(idx_a,idx_b)]' @@ -147,13 +147,16 @@ function amp_post_tmc_XX_mc(m, ab, λX, λλ, LB, UB, a, b) @assert length(LB[b]) == length(UB[b]) dim_A = length(LB[a]) dim_B = length(LB[b]) - @constraint(m, Variable(m, ab) .>= dot(λX[(a,b)],LB[a]) + dot(λX[(b,a)],LB[b]) - reshape(LB[a], (1, dim_A))*λλ[(a,b)]*reshape(LB[b], (dim_B, 1))) - @constraint(m, Variable(m, ab) .>= dot(λX[(a,b)],UB[a]) + dot(λX[(b,a)],UB[b]) - reshape(UB[a], (1, dim_A))*λλ[(a,b)]*reshape(UB[b], (dim_B, 1))) - @constraint(m, Variable(m, ab) .<= dot(λX[(a,b)],LB[a]) + dot(λX[(b,a)],UB[b]) - reshape(LB[a], (1, dim_A))*λλ[(a,b)]*reshape(UB[b], (dim_B, 1))) - @constraint(m, Variable(m, ab) .<= dot(λX[(a,b)],UB[a]) + dot(λX[(b,a)],LB[b]) - reshape(UB[a], (1, dim_A))*λλ[(a,b)]*reshape(LB[b], (dim_B, 1))) + @constraint(m, _index_to_variable_ref(m, ab) .>= dot(λX[(a,b)],LB[a]) + dot(λX[(b,a)],LB[b]) - reshape(LB[a], (1, dim_A))*λλ[(a,b)]*reshape(LB[b], (dim_B, 1))) + @constraint(m, _index_to_variable_ref(m, ab) .>= dot(λX[(a,b)],UB[a]) + dot(λX[(b,a)],UB[b]) - reshape(UB[a], (1, dim_A))*λλ[(a,b)]*reshape(UB[b], (dim_B, 1))) + @constraint(m, _index_to_variable_ref(m, ab) .<= dot(λX[(a,b)],LB[a]) + dot(λX[(b,a)],UB[b]) - reshape(LB[a], (1, dim_A))*λλ[(a,b)]*reshape(UB[b], (dim_B, 1))) + @constraint(m, _index_to_variable_ref(m, ab) .<= dot(λX[(a,b)],UB[a]) + dot(λX[(b,a)],LB[b]) - reshape(UB[a], (1, dim_A))*λλ[(a,b)]*reshape(LB[b], (dim_B, 1))) return end +_lower_bound(x) = JuMP.is_binary(x) ? 0.0 : JuMP.lower_bound(x) +_upper_bound(x) = JuMP.is_binary(x) ? 1.0 : JuMP.upper_bound(x) + function amp_post_tmc_λxX_mc(m::JuMP.Model, λX::Dict, λ::Dict, lb::Dict, ub::Dict, ind_λ::Int, ind_X::Int) # X_u and λ here are vectors, and X is one variable, @@ -162,12 +165,13 @@ function amp_post_tmc_λxX_mc(m::JuMP.Model, λX::Dict, λ::Dict, lb::Dict, ub:: dim_λ = length(λ[ind_λ]) # This is how many new variables to be generated for i in 1:dim_λ - lb_X = getlowerbound(Variable(m, ind_X)) - ub_X = getupperbound(Variable(m, ind_X)) - lb_λ = getlowerbound(λ[ind_λ][i]) - ub_λ = getupperbound(λ[ind_λ][i]) + v = _index_to_variable_ref(m, ind_X) + lb_X = JuMP.lower_bound(v) + ub_X = JuMP.upper_bound(v) + lb_λ = _lower_bound(λ[ind_λ][i]) + ub_λ = _upper_bound(λ[ind_λ][i]) @assert (lb_λ == 0.0) && (ub_λ == 1.0) - mccormick(m, λX[(ind_λ,ind_X)][i], λ[ind_λ][i], Variable(m, ind_X), lb_λ, ub_λ, lb_X, ub_X) + mccormick(m, λX[(ind_λ,ind_X)][i], λ[ind_λ][i], v, lb_λ, ub_λ, lb_X, ub_X) end return end @@ -186,8 +190,8 @@ function amp_post_tmc_λxλ_mc(m::JuMP.Model, λλ::Dict, λ::Dict, ind_A::Int, dim_B = length(λ[ind_B]) for i in 1:dim_A for j in 1:dim_B - setlowerbound(λλ[(ind_A,ind_B)][i,j],0) - setupperbound(λλ[(ind_A,ind_B)][i,j],1) + JuMP.set_lower_bound(λλ[(ind_A,ind_B)][i,j],0) + JuMP.set_upper_bound(λλ[(ind_A,ind_B)][i,j],1) end end @@ -205,7 +209,7 @@ end Generic function to add a McCormick convex envelop, where `xy=x*y` and `x_l, x_u, y_l, y_u` are variable bounds. """ -function mccormick(m::JuMP.Model,xy::JuMP.Variable,x::JuMP.Variable,y::JuMP.Variable,xˡ,xᵘ,yˡ,yᵘ) +function mccormick(m::JuMP.Model,xy::JuMP.VariableRef,x::JuMP.VariableRef,y::JuMP.VariableRef,xˡ,xᵘ,yˡ,yᵘ) @constraint(m, xy >= xˡ*y + yˡ*x - xˡ*yˡ) @constraint(m, xy >= xᵘ*y + yᵘ*x - xᵘ*yᵘ) @@ -215,7 +219,7 @@ function mccormick(m::JuMP.Model,xy::JuMP.Variable,x::JuMP.Variable,y::JuMP.Vari return end -function mccormick_binlin(m::JuMP.Model,binlin::JuMP.Variable,bin::JuMP.Variable,lin::JuMP.Variable,lb,ub) +function mccormick_binlin(m::JuMP.Model,binlin::JuMP.VariableRef,bin::JuMP.VariableRef,lin::JuMP.VariableRef,lb,ub) # TODO think about how to address this issue warnuser = false @@ -248,7 +252,7 @@ function mccormick_binlin(m::JuMP.Model,binlin::JuMP.Variable,bin::JuMP.Variable return end -function mccormick_bin(m::JuMP.Model,xy::JuMP.Variable,x::JuMP.Variable,y::JuMP.Variable) +function mccormick_bin(m::JuMP.Model,xy::JuMP.VariableRef,x::JuMP.VariableRef,y::JuMP.VariableRef) @constraint(m, xy <= x) @constraint(m, xy <= y) @constraint(m, xy >= x+y-1) diff --git a/src/utility.jl b/src/utility.jl index 04638e22..fb483f94 100644 --- a/src/utility.jl +++ b/src/utility.jl @@ -1,5 +1,5 @@ """ -update_rel_gap(m::AlpineNonlinearModel) +update_rel_gap(m::Optimizer) Update Alpine model relative & absolute optimality gap. @@ -14,28 +14,28 @@ The absolute gap calculation is |UB-LB| ``` """ -function update_opt_gap(m::AlpineNonlinearModel) +function update_opt_gap(m::Optimizer) if m.best_obj in [Inf, -Inf] m.best_rel_gap = Inf return else - p = convert(Int, round(abs(log(10,m.relgap)))) + p = convert(Int, round(abs(log(10,get_option(m, :relgap))))) n = round(abs(m.best_obj-m.best_bound); digits=p) dn = round(abs(1e-12+abs(m.best_obj)); digits=p) - if isapprox(n, 0.0;atol=m.tol) && isapprox(m.best_obj,0.0;atol=m.tol) + if isapprox(n, 0.0;atol=get_option(m, :tol)) && isapprox(m.best_obj,0.0;atol=get_option(m, :tol)) m.best_rel_gap = 0.0 return end - if m.gapref == :ub - if isapprox(m.best_obj,0.0;atol=m.tol) # zero upper bound case + if get_option(m, :gapref) == :ub + if isapprox(m.best_obj,0.0;atol=get_option(m, :tol)) # zero upper bound case eps = 1 # shift factor - m.best_rel_gap = (m.best_obj + eps) - (m.best_bound + eps)/(m.tol+(m.best_obj + eps)) + m.best_rel_gap = (m.best_obj + eps) - (m.best_bound + eps)/(get_option(m, :tol)+(m.best_obj + eps)) else - m.best_rel_gap = abs(m.best_obj - m.best_bound)/(m.tol+abs(m.best_obj)) + m.best_rel_gap = abs(m.best_obj - m.best_bound)/(get_option(m, :tol)+abs(m.best_obj)) end else - m.best_rel_gap = abs(m.best_obj - m.best_bound)/(m.tol+abs(m.best_bound)) + m.best_rel_gap = abs(m.best_obj - m.best_bound)/(get_option(m, :tol)+abs(m.best_bound)) end end @@ -43,9 +43,9 @@ function update_opt_gap(m::AlpineNonlinearModel) return end -function measure_relaxed_deviation(m::AlpineNonlinearModel;sol=nothing) +function measure_relaxed_deviation(m::Optimizer;sol=nothing) - sol == nothing ? sol = m.best_bound_sol : sol = sol + sol = something(sol, m.best_bound_sol) isempty(sol) && return @@ -60,7 +60,7 @@ function measure_relaxed_deviation(m::AlpineNonlinearModel;sol=nothing) sort!(dev, by=x->x[1]) for i in dev - m.loglevel > 199 && println("Y-VAR$(i[1]): DIST=$(i[2]) || Y-hat = $(i[3]), Y-val = $(i[4]) || COMP $(i[5])") + get_option(m, :loglevel) > 199 && println("Y-VAR$(i[1]): DIST=$(i[2]) || Y-hat = $(i[3]), Y-val = $(i[4]) || COMP $(i[5])") end return @@ -76,14 +76,14 @@ discretization_to_bounds(d::Dict, l::Int) = update_var_bounds(d, len=l) """ Update the data structure with feasible solution and its associated objective (if better) """ -function update_incumb_objective(m::AlpineNonlinearModel, objval::Float64, sol::Vector) +function update_incumb_objective(m::Optimizer, objval::Float64, sol::Vector) - convertor = Dict(:Max=>:>, :Min=>:<) + convertor = Dict(MOI.MAX_SENSE => :>, MOI.MIN_SENSE => :<) push!(m.logs[:obj], objval) if eval(convertor[m.sense_orig])(objval, m.best_obj) #&& !eval(convertor[m.sense_orig])(objval, m.best_bound) m.best_obj = objval m.best_sol = sol - m.status[:feasible_solution] = :Detected + m.detected_feasible_solution = true end return @@ -93,8 +93,8 @@ end Utility function for debugging. """ function show_solution(m::JuMP.Model) - for i in 1:length(m.colNames) - println("$(m.colNames[i])=$(m.colVal[i])") + for var in all_variables(m) + println("$var=$(JuMP.value(var))") end return end @@ -158,25 +158,25 @@ function update_timeleft_symbol(options, keyword::Symbol, val::Float64; options_ end """ -fetch_boundstop_symbol(m::AlpineNonlinearModel) +fetch_boundstop_symbol(m::Optimizer) An utility function used to recognize different sub-solvers and return the bound stop option key words """ -function update_boundstop_options(m::AlpineNonlinearModel) +function update_boundstop_options(m::Optimizer) if m.mip_solver_id == "Gurobi" # Calculation of the bound - if m.sense_orig == :Min - m.gapref == :ub ? stopbound=(1-m.relgap+m.tol)*abs(m.best_obj) : stopbound=(1-m.relgap+m.tol)*abs(m.best_bound) - elseif m.sense_orig == :Max - m.gapref == :ub ? stopbound=(1+m.relgap-m.tol)*abs(m.best_obj) : stopbound=(1+m.relgap-m.tol)*abs(m.best_bound) + if is_min_sense(m) + get_option(m, :gapref) == :ub ? stopbound=(1-get_option(m, :relgap)+get_option(m, :tol))*abs(m.best_obj) : stopbound=(1-get_option(m, :relgap)+get_option(m, :tol))*abs(m.best_bound) + elseif is_max_sense(m) + get_option(m, :gapref) == :ub ? stopbound=(1+get_option(m, :relgap)-get_option(m, :tol))*abs(m.best_obj) : stopbound=(1+get_option(m, :relgap)-get_option(m, :tol))*abs(m.best_bound) end - for i in 1:length(m.mip_solver.options) - if m.mip_solver.options[i][1] == :BestBdStop - deleteat!(m.mip_solver.options, i) + for i in 1:length(get_option(m, :mip_solver).options) + if get_option(m, :mip_solver).options[i][1] == :BestBdStop + deleteat!(get_option(m, :mip_solver).options, i) if m.mip_solver_id == "Gurobi" - push!(m.mip_solver.options, (:BestBdStop, stopbound)) + push!(get_option(m, :mip_solver).options, (:BestBdStop, stopbound)) else return end @@ -189,46 +189,50 @@ end """ -check_solution_history(m::AlpineNonlinearModel, ind::Int) +check_solution_history(m::Optimizer, ind::Int) Check if the solution is alwasy the same within the last disc_consecutive_forbid iterations. Return true if suolution in invariant. """ -function check_solution_history(m::AlpineNonlinearModel, ind::Int) +function check_solution_history(m::Optimizer, ind::Int) - m.disc_consecutive_forbid == 0 && return false - (m.logs[:n_iter] < m.disc_consecutive_forbid) && return false + get_option(m, :disc_consecutive_forbid) == 0 && return false + (m.logs[:n_iter] < get_option(m, :disc_consecutive_forbid)) && return false - sol_val = m.bound_sol_history[mod(m.logs[:n_iter]-1, m.disc_consecutive_forbid)+1][ind] - for i in 1:(m.disc_consecutive_forbid-1) - search_pos = mod(m.logs[:n_iter]-1-i, m.disc_consecutive_forbid)+1 - !isapprox(sol_val, m.bound_sol_history[search_pos][ind]; atol=m.disc_rel_width_tol) && return false + sol_val = m.bound_sol_history[mod(m.logs[:n_iter]-1, get_option(m, :disc_consecutive_forbid))+1][ind] + for i in 1:(get_option(m, :disc_consecutive_forbid)-1) + search_pos = mod(m.logs[:n_iter]-1-i, get_option(m, :disc_consecutive_forbid))+1 + !isapprox(sol_val, m.bound_sol_history[search_pos][ind]; atol=get_option(m, :disc_rel_width_tol)) && return false end - m.loglevel > 99 && println("Consecutive bounding solution on VAR$(ind) obtained. Diverting...") + get_option(m, :loglevel) > 99 && println("Consecutive bounding solution on VAR$(ind) obtained. Diverting...") return true end """ -fix_domains(m::AlpineNonlinearModel) +fix_domains(m::Optimizer) This function is used to fix variables to certain domains during the local solve process in the [`global_solve`](@ref). More specifically, it is used in [`local_solve`](@ref) to fix binary and integer variables to lower bound solutions and discretizing variables to the active domain according to lower bound solution. """ -function fix_domains(m::AlpineNonlinearModel;discrete_sol=nothing, use_orig=false) +function fix_domains(m::Optimizer;discrete_sol=nothing, use_orig=false) - discrete_sol != nothing && @assert length(discrete_sol) >= m.num_var_orig + discrete_sol !== nothing && @assert length(discrete_sol) >= m.num_var_orig l_var = [m.l_var_tight[i] for i in 1:m.num_var_orig] u_var = [m.u_var_tight[i] for i in 1:m.num_var_orig] for i in 1:m.num_var_orig if i in m.disc_vars && m.var_type[i] == :Cont - discrete_sol == nothing ? point = m.best_bound_sol[i] : point = discrete_sol[i] + point = if discrete_sol === nothing + m.best_bound_sol[i] + else + discrete_sol[i] + end PCnt = length(m.discretization[i]) - 1 for j in 1:PCnt - if point >= (m.discretization[i][j] - m.tol) && (point <= m.discretization[i][j+1] + m.tol) + if point >= (m.discretization[i][j] - get_option(m, :tol)) && (point <= m.discretization[i][j+1] + get_option(m, :tol)) @assert j < length(m.discretization[i]) use_orig ? l_var[i] = m.discretization[i][1] : l_var[i] = m.discretization[i][j] use_orig ? u_var[i] = m.discretization[i][end] : u_var[i] = m.discretization[i][j+1] @@ -250,9 +254,9 @@ function fix_domains(m::AlpineNonlinearModel;discrete_sol=nothing, use_orig=fals end """ -is_fully_convexified(m::AlpineNonlinearModel) +is_fully_convexified(m::Optimizer) """ -function is_fully_convexified(m::AlpineNonlinearModel) +function is_fully_convexified(m::Optimizer) # Other more advanced convexification check goes here for term in keys(m.nonconvex_terms) @@ -271,7 +275,7 @@ end Collect LB solutions Don't test this function """ -function collect_lb_pool(m::AlpineNonlinearModel) +function collect_lb_pool(m::Optimizer) # Always stick to the structural .discretization for algorithm consideration info # If in need, the scheme need to be refreshed with customized discretization info @@ -305,7 +309,7 @@ end """ Merge collected solution pools """ -function merge_solution_pool(m::AlpineNonlinearModel, s::Dict) +function merge_solution_pool(m::Optimizer, s::Dict) # Always stick to the structural discretization for algorithm consideration info # If in need, the scheme needs to be refreshed with customized discretization info @@ -339,7 +343,7 @@ function merge_solution_pool(m::AlpineNonlinearModel, s::Dict) act || break end # Reject solutions that is around best bound to avoid traps - if isapprox(s[:obj][i], m.best_bound;atol=m.tol) + if isapprox(s[:obj][i], m.best_bound;atol=get_option(m, :tol)) s[:stat][i] = :Dead end push!(m.bound_sol_pool[:sol], s[:sol][i]) @@ -355,9 +359,9 @@ function merge_solution_pool(m::AlpineNonlinearModel, s::Dict) m.bound_sol_pool[:vars] = var_idxs # Show the summary - m.loglevel > 99 && println("POOL size = $(length([i for i in 1:m.bound_sol_pool[:cnt] if m.bound_sol_pool[:stat][i] != :Dead])) / $(m.bound_sol_pool[:cnt]) ") + get_option(m, :loglevel) > 99 && println("POOL size = $(length([i for i in 1:m.bound_sol_pool[:cnt] if m.bound_sol_pool[:stat][i] != :Dead])) / $(m.bound_sol_pool[:cnt]) ") for i in 1:m.bound_sol_pool[:cnt] - m.loglevel > 99 && m.bound_sol_pool[:stat][i] != :Dead && println("ITER $(m.bound_sol_pool[:iter][i]) | SOL $(i) | POOL solution obj = $(m.bound_sol_pool[:obj][i])") + get_option(m, :loglevel) > 99 && m.bound_sol_pool[:stat][i] != :Dead && println("ITER $(m.bound_sol_pool[:iter][i]) | SOL $(i) | POOL solution obj = $(m.bound_sol_pool[:obj][i])") end return @@ -410,12 +414,12 @@ end """ -ncvar_collect_nodes(m:AlpineNonlinearModel) +ncvar_collect_nodes(m:Optimizer) A built-in method for selecting variables for discretization. It selects all variables in the nonlinear terms. """ -function ncvar_collect_nodes(m::AlpineNonlinearModel;getoutput=false) +function ncvar_collect_nodes(m::Optimizer;getoutput=false) # Pick variables that is bound width more than tolerance length if getoutput @@ -428,10 +432,10 @@ function ncvar_collect_nodes(m::AlpineNonlinearModel;getoutput=false) return end -function eval_objective(m::AlpineNonlinearModel; svec::Vector=[]) +function eval_objective(m::Optimizer; svec::Vector=[]) isempty(svec) ? svec = m.best_bound_sol : svec = svec - m.sense_orig == :Min ? obj = Inf : obj=-Inf + is_min_sense(m) ? obj = Inf : obj = -Inf if m.obj_structure == :affine obj = m.bounding_obj_mip[:rhs] @@ -447,7 +451,7 @@ function eval_objective(m::AlpineNonlinearModel; svec::Vector=[]) return obj end -function initialize_solution_pool(m::AlpineNonlinearModel, cnt::Int) +function initialize_solution_pool(m::Optimizer, cnt::Int) s = Dict() @@ -472,7 +476,7 @@ end """ Reconsideration required """ -function ncvar_collect_arcs(m::AlpineNonlinearModel, nodes::Vector) +function ncvar_collect_arcs(m::Optimizer, nodes::Vector) arcs = Set() @@ -537,13 +541,13 @@ function print_iis_gurobi(m::JuMP.Model) info("Irreducible Inconsistent Subsystem (IIS)") info("Variable bounds:") for i in 1:numvar - v = Variable(m, i) + v = _index_to_variable_ref(m, i) if iislb[i] != 0 && iisub[i] != 0 - println(getlowerbound(v), " <= ", getname(v), " <= ", getupperbound(v)) + println(JuMP.lower_bound(v), " <= ", JuMP.name(v), " <= ", JuMP.upper_bound(v)) elseif iislb[i] != 0 - println(getname(v), " >= ", getlowerbound(v)) + println(JuMP.name(v), " >= ", JuMP.lower_bound(v)) elseif iisub[i] != 0 - println(getname(v), " <= ", getupperbound(v)) + println(JuMP.name(v), " <= ", JuMP.upper_bound(v)) end end @@ -560,7 +564,7 @@ end """ TODO can be improved """ -function build_discvar_graph(m::AlpineNonlinearModel) +function build_discvar_graph(m::Optimizer) # Collect the information of nonlinear terms in terms of arcs and nodes nodes = ncvar_collect_nodes(m, getoutput=true) @@ -580,28 +584,29 @@ function build_discvar_graph(m::AlpineNonlinearModel) return nodes, arcs end -function min_vertex_cover(m::AlpineNonlinearModel) +function min_vertex_cover(m::Optimizer) nodes, arcs = build_discvar_graph(m) # Set up minimum vertex cover problem - update_mip_time_limit(m, timelimit=60.0) # Set a timer to avoid waste of time in proving optimality - minvertex = Model(solver=m.mip_solver) + minvertex = Model(get_option(m, :mip_solver)) + MOI.set(minvertex, MOI.TimeLimitSec(), 60.0) # Set a timer to avoid waste of time in proving optimality @variable(minvertex, x[nodes], Bin) @constraint(minvertex, [a in arcs], x[a[1]] + x[a[2]] >= 1) @objective(minvertex, Min, sum(x)) - status = solve(minvertex, suppress_warnings=true) - xVal = getvalue(x) + optimize!(minvertex) + status = MOI.get(minvertex, MOI.TerminationStatus()) + xVal = JuMP.value.(x) # Collecting required information m.num_var_disc_mip = Int(sum(xVal)) - m.disc_vars = [i for i in nodes if xVal[i] > m.tol && abs(m.u_var_tight[i]-m.l_var_tight[i]) >= m.tol] + m.disc_vars = [i for i in nodes if xVal[i] > get_option(m, :tol) && abs(m.u_var_tight[i]-m.l_var_tight[i]) >= get_option(m, :tol)] return end -function weighted_min_vertex_cover(m::AlpineNonlinearModel, distance::Dict) +function weighted_min_vertex_cover(m::Optimizer, distance::Dict) # Collect the graph information nodes, arcs = build_discvar_graph(m) @@ -613,12 +618,12 @@ function weighted_min_vertex_cover(m::AlpineNonlinearModel, distance::Dict) weights = Dict() for i in m.candidate_disc_vars isapprox(distance[i], 0.0; atol=1e-6) ? weights[i] = heavy : (weights[i]=(1/distance[i])) - (m.loglevel > 100) && println("VAR$(i) WEIGHT -> $(weights[i]) ||| DISTANCE -> $(distance[i])") + (get_option(m, :loglevel) > 100) && println("VAR$(i) WEIGHT -> $(weights[i]) ||| DISTANCE -> $(distance[i])") end # Set up minimum vertex cover problem - update_mip_time_limit(m, timelimit=60.0) # Set a timer to avoid waste of time in proving optimality - minvertex = Model(solver=m.mip_solver) + minvertex = Model(get_option(m, :mip_solver)) + MOI.set(minvertex, MOI.TimeLimitSec(), 60.0) # Set a timer to avoid waste of time in proving optimality @variable(minvertex, x[nodes], Bin) for arc in arcs @constraint(minvertex, x[arc[1]] + x[arc[2]] >= 1) @@ -626,30 +631,17 @@ function weighted_min_vertex_cover(m::AlpineNonlinearModel, distance::Dict) @objective(minvertex, Min, sum(weights[i]*x[i] for i in nodes)) # Solve the minimum vertex cover - status = solve(minvertex, suppress_warnings=true) + JuMP.optimize!(minvertex) - xVal = getvalue(x) + xVal = JuMP.value.(x) m.num_var_disc_mip = Int(sum(xVal)) - m.disc_vars = [i for i in nodes if xVal[i] > 0 && abs(m.u_var_tight[i]-m.l_var_tight[i]) >= m.tol] - m.loglevel >= 99 && println("UPDATED DISC-VAR COUNT = $(length(m.disc_vars)) : $(m.disc_vars)") + m.disc_vars = [i for i in nodes if xVal[i] > 0 && abs(m.u_var_tight[i]-m.l_var_tight[i]) >= get_option(m, :tol)] + get_option(m, :loglevel) >= 99 && println("UPDATED DISC-VAR COUNT = $(length(m.disc_vars)) : $(m.disc_vars)") return end -function round_sol(m::AlpineNonlinearModel;nlp_model=nothing, nlp_sol=[]) - - if nlp_model != nothing - relaxed_sol = interface_get_solution(nlp_model) - end - - if !isempty(nlp_sol) - relaxed_sol = nlp_sol - end - - if nlp_model != nothing && !isempty(nlp_sol) - error("In function collision. Special usage") - end - +function round_sol(m::Optimizer, relaxed_sol) rounded_sol = copy(relaxed_sol) for i in 1:m.num_var_orig if m.var_type_orig[i] == :Bin @@ -667,7 +659,7 @@ end """ Evaluate a solution feasibility: Solution bust be in the feasible category and evaluated rhs must be feasible """ -function eval_feasibility(m::AlpineNonlinearModel, sol::Vector) +function eval_feasibility(m::Optimizer, sol::Vector) length(sol) == m.num_var_orig || error("Candidate solution length mismatch.") @@ -675,37 +667,43 @@ function eval_feasibility(m::AlpineNonlinearModel, sol::Vector) for i in 1:m.num_var_orig # Check solution category and bounds if m.var_type[i] == :Bin - isapprox(sol[i], 1.0;atol=m.tol) || isapprox(sol[i], 0.0;atol=m.tol) || return false + isapprox(sol[i], 1.0;atol=get_option(m, :tol)) || isapprox(sol[i], 0.0;atol=get_option(m, :tol)) || return false elseif m.var_type[i] == :Int - isapprox(mod(sol[i], 1.0), 0.0;atol=m.tol) || return false + isapprox(mod(sol[i], 1.0), 0.0;atol=get_option(m, :tol)) || return false end # Check solution bounds (with tight bounds) - sol[i] <= m.l_var_tight[i] - m.tol || return false - sol[i] >= m.u_var_tight[i] + m.tol || return false + sol[i] <= m.l_var_tight[i] - get_option(m, :tol) || return false + sol[i] >= m.u_var_tight[i] + get_option(m, :tol) || return false end # Check constraint violation eval_rhs = zeros(m.num_constr_orig) - interface_eval_g(m.d_orig, eval_rhs, rounded_sol) + for i in eachindex(m.lin_quad_constraints) + func = m.lin_quad_constraints[i][1] + eval_rhs[i] = MOI.Utilities.eval_variables(vi -> rounded_sol[vi.value], func) + end + start = m.num_constr_orig - length(m.nonlinear_constraint_bounds_orig) + 1 + @assert start == length(m.lin_quad_constraints) + 1 + interface_eval_g(m.d_orig, view(eval_rhs, start:m.num_constr_orig), rounded_sol) feasible = true for i in 1:m.num_constr_orig if m.constr_type_orig[i] == :(==) - if !isapprox(eval_rhs[i], m.l_constr_orig[i]; atol=m.tol) + if !isapprox(eval_rhs[i], m.constraint_bounds_orig[i].lower; atol=get_option(m, :tol)) feasible = false - m.loglevel >= 100 && println("[BETA] Violation on CONSTR $(i) :: EVAL $(eval_rhs[i]) != RHS $(m.l_constr_orig[i])") - m.loglevel >= 100 && println("[BETA] CONSTR $(i) :: $(m.bounding_constr_expr_mip[i])") + get_option(m, :loglevel) >= 100 && println("[BETA] Violation on CONSTR $(i) :: EVAL $(eval_rhs[i]) != RHS $(m.constraint_bounds_orig[i].lower)") + get_option(m, :loglevel) >= 100 && println("[BETA] CONSTR $(i) :: $(m.bounding_constr_expr_mip[i])") return false end elseif m.constr_type_orig[i] == :(>=) - if !(eval_rhs[i] >= m.l_constr_orig[i] - m.tol) - m.loglevel >= 100 && println("[BETA] Violation on CONSTR $(i) :: EVAL $(eval_rhs[i]) !>= RHS $(m.l_constr_orig[i])") - m.loglevel >= 100 && println("[BETA] CONSTR $(i) :: $(m.bounding_constr_expr_mip[i])") + if !(eval_rhs[i] >= m.constraint_bounds_orig[i].lower - get_option(m, :tol)) + get_option(m, :loglevel) >= 100 && println("[BETA] Violation on CONSTR $(i) :: EVAL $(eval_rhs[i]) !>= RHS $(m.constraint_bounds_orig[i].lower)") + get_option(m, :loglevel) >= 100 && println("[BETA] CONSTR $(i) :: $(m.bounding_constr_expr_mip[i])") return false end elseif m.constr_type_orig[i] == :(<=) - if !(eval_rhs[i] <= m.u_constr_orig[i] + m.tol) - m.loglevel >= 100 && println("[BETA] Violation on CONSTR $(i) :: EVAL $(eval_rhs[i]) !<= RHS $(m.u_constr_orig[i])") - m.loglevel >= 100 && println("[BETA] CONSTR $(i) :: $(m.bounding_constr_expr_mip[i])") + if !(eval_rhs[i] <= m.constraint_bounds_orig[i].upper + get_option(m, :tol)) + get_option(m, :loglevel) >= 100 && println("[BETA] Violation on CONSTR $(i) :: EVAL $(eval_rhs[i]) !<= RHS $(m.constraint_bounds_orig[i].upper)") + get_option(m, :loglevel) >= 100 && println("[BETA] CONSTR $(i) :: $(m.bounding_constr_expr_mip[i])") return false end end @@ -714,28 +712,31 @@ function eval_feasibility(m::AlpineNonlinearModel, sol::Vector) return feasible end -function fetch_mip_solver_identifier(m::AlpineNonlinearModel;override="") +function fetch_mip_solver_identifier(m::Optimizer;override="") - isempty(override) ? solverstring = string(m.mip_solver) : solverstring = override + isempty(override) ? solverstring = string(get_option(m, :mip_solver)) : solverstring = override # Higher-level solvers: that can use sub-solvers if occursin("Pajarito", solverstring) - m.mip_solver_id = "Pajarito" + m.mip_solver_id = "Pajarito" return elseif occursin("Pavito", solverstring) - m.mip_solver_id = "Pavito" + m.mip_solver_id = "Pavito" + return + elseif occursin("Juniper", solverstring) + m.mip_solver_id = "Juniper" return end # Lower level solvers if occursin("Gurobi", solverstring) - m.mip_solver_id = "Gurobi" - elseif occursin("Cplex", solverstring) - m.mip_solver_id = "Cplex" - elseif occursin("Cbc", solverstring) - m.mip_solver_id = "Cbc" + m.mip_solver_id = "Gurobi" + elseif occursin("CPLEX", solverstring) + m.mip_solver_id = "Cplex" + elseif occursin("Cbc", solverstring) # /!\ the `SolverName()` is "COIN Branch-and-Cut (Cbc)" + m.mip_solver_id = "Cbc" elseif occursin("GLPK", solverstring) - m.mip_solver_id = "GLPK" + m.mip_solver_id = "GLPK" else error("Unsupported MIP solver $solverstring; use a Alpine-supported MIP solver") end @@ -743,28 +744,28 @@ function fetch_mip_solver_identifier(m::AlpineNonlinearModel;override="") return end -function fetch_nlp_solver_identifier(m::AlpineNonlinearModel;override="") +function fetch_nlp_solver_identifier(m::Optimizer;override="") - isempty(override) ? solverstring = string(m.nlp_solver) : solverstring = override + isempty(override) ? solverstring = string(get_option(m, :nlp_solver)) : solverstring = override # Higher-level solver if occursin("Pajarito", solverstring) - m.nlp_solver_id = "Pajarito" + m.nlp_solver_id = "Pajarito" return elseif occursin("Pavito", solverstring) - m.nlp_solver_id = "Pavito" + m.nlp_solver_id = "Pavito" return end # Lower-level solver if occursin("Ipopt", solverstring) - m.nlp_solver_id = "Ipopt" + m.nlp_solver_id = "Ipopt" elseif occursin("AmplNL", solverstring) && occursin("bonmin", solverstring) - m.nlp_solver_id = "Bonmin" - elseif occursin("KNITRO", solverstring) - m.nlp_solver_id = "Knitro" + m.nlp_solver_id = "Bonmin" + elseif occursin("KNITRO", solverstring) # /!\ the `SolverName()` is "Knitro" + m.nlp_solver_id = "Knitro" elseif occursin("NLopt", solverstring) - m.nlp_solver_id = "NLopt" + m.nlp_solver_id = "NLopt" else error("Unsupported NLP local solver $solverstring; use a Alpine-supported NLP local solver") end @@ -772,34 +773,33 @@ function fetch_nlp_solver_identifier(m::AlpineNonlinearModel;override="") return end -function fetch_minlp_solver_identifier(m::AlpineNonlinearModel;override="") +function fetch_minlp_solver_identifier(m::Optimizer;override="") - (m.minlp_solver == empty_solver) && return + (get_option(m, :minlp_solver) === nothing) && return - isempty(override) ? solverstring = string(m.minlp_solver) : solverstring = override + isempty(override) ? solverstring = string(get_option(m, :minlp_solver)) : solverstring = override # Higher-level solver if occursin("Pajarito", solverstring) - m.minlp_solver_id = "Pajarito" + m.minlp_solver_id = "Pajarito" return elseif occursin("Pavito", solverstring) - m.minlp_solver_id = "Pavito" + m.minlp_solver_id = "Pavito" return end # Lower-level Solver if occursin("AmplNL", solverstring) && occursin("bonmin", solverstring) - m.minlp_solver_id = "Bonmin" + m.minlp_solver_id = "Bonmin" elseif occursin("KNITRO", solverstring) - m.minlp_solver_id = "Knitro" + m.minlp_solver_id = "Knitro" elseif occursin("NLopt", solverstring) - m.minlp_solver_id = "NLopt" + m.minlp_solver_id = "NLopt" elseif occursin("CoinOptServices.OsilSolver(\"bonmin\"", solverstring) - m.minlp_solver_id = "Bonmin" + m.minlp_solver_id = "Bonmin" elseif occursin("Juniper", solverstring) - m.minlp_solver_id = "Juniper" + m.minlp_solver_id = "Juniper" else - @show solverstring error("Unsupported MINLP local solver $solverstring; use a Alpine-supported MINLP local solver") end @@ -807,118 +807,19 @@ function fetch_minlp_solver_identifier(m::AlpineNonlinearModel;override="") end """ -update_mip_time_limit(m::AlpineNonlinearModel) -An utility function used to dynamically regulate MILP solver time limits to fit Alpine solver time limits. -""" -function update_mip_time_limit(m::AlpineNonlinearModel; kwargs...) - - options = Dict(kwargs) - timelimit = 0.0 - haskey(options, :timelimit) ? timelimit = options[:timelimit] : timelimit = max(0.0, m.timeout-m.logs[:total_time]) - - opts = Vector{Any}(undef, 0) - if m.mip_solver_id != "Pavito" && m.mip_solver_id != "Pajarito" - for i in collect(m.mip_solver.options) - push!(opts, i) - end - end - - if m.mip_solver_id == "Cplex" - opts = update_timeleft_symbol(opts, :CPX_PARAM_TILIM, timelimit) - m.mip_solver.options = opts - elseif m.mip_solver_id == "Pavito" - (timelimit < Inf) && (m.mip_solver.timeout = timelimit) - elseif m.mip_solver_id == "Gurobi" - opts = update_timeleft_symbol(opts, :TimeLimit, timelimit) - m.mip_solver.options = opts - elseif m.mip_solver_id == "Cbc" - opts = update_timeleft_symbol(opts, :seconds, timelimit) - m.mip_solver.options = opts - elseif m.mip_solver_id == "GLPK" - opts = update_timeleft_symbol(opts, :tm_lim, timelimit) - m.mip_solver.options = opts - elseif m.mip_solver_id == "Pajarito" - (timelimit < Inf) && (m.mip_solver.timeout = timelimit) - else - error("Needs support for this MIP solver") - end - - return -end + set_mip_time_limit(m::Optimizer) -""" -update_mip_time_limit(m::AlpineNonlinearModel) -An utility function used to dynamically regulate MILP solver time limits to fit Alpine solver time limits. -""" -function update_nlp_time_limit(m::AlpineNonlinearModel; kwargs...) - - options = Dict(kwargs) - timelimit = 0.0 - haskey(options, :timelimit) ? timelimit = options[:timelimit] : timelimit = max(0.0, m.timeout-m.logs[:total_time]) - - opts = Vector{Any}(undef, 0) - if m.nlp_solver_id != "Pavito" && m.nlp_solver_id != "Pajarito" - opts = collect(m.nlp_solver.options) - end - - - if m.nlp_solver_id == "Ipopt" - opts = update_timeleft_symbol(opts, :max_cpu_time, timelimit) - m.nlp_solver.options = opts - elseif m.nlp_solver_id == "Pajarito" - (timelimit < Inf) && (m.nlp_solver.timeout = timelimit) - elseif m.nlp_solver_id == "AmplNL" - opts = update_timeleft_symbol(opts, :seconds, timelimit, options_string_type=2) - m.nlp_solver.options = opts - elseif m.nlp_solver_id == "Knitro" - error("You never tell me anything about knitro. Probably because they have a very short trail length.") - elseif m.nlp_solver_id == "NLopt" - m.nlp_solver.maxtime = timelimit - else - error("Needs support for this MIP solver") - end - - return -end - -""" -update_mip_time_limit(m::AlpineNonlinearModel) An utility function used to dynamically regulate MILP solver time limits to fit Alpine solver time limits. """ -function update_minlp_time_limit(m::AlpineNonlinearModel; kwargs...) - - options = Dict(kwargs) - timelimit = 0.0 - haskey(options, :timelimit) ? timelimit = options[:timelimit] : timelimit = max(0.0, m.timeout-m.logs[:total_time]) - - opts = Vector{Any}(undef, 0) - if m.minlp_solver_id != "Pavito" && m.minlp_solver_id != "Pajarito" - opts = collect(m.minlp_solver.options) - end - - - if m.minlp_solver_id == "Pajarito" - (timelimit < Inf) && (m.minlp_solver.timeout = timelimit) - elseif m.minlp_solver_id == "Pavito" - (timelimit < Inf) && (m.minlp_solver.timeout = timelimit) - elseif m.minlp_solver_id == "AmplNL" - opts = update_timeleft_symbol(opts, :seconds, timelimit, options_string_type=2) - m.minlp_solver.options = opts - elseif m.minlp_solver_id == "Knitro" - error("You never tell me anything about knitro. Probably because they charge everything they own.") - elseif m.minlp_solver_id == "NLopt" - m.minlp_solver.maxtime = timelimit - else - error("Needs support for this MIP solver") - end - - return +function set_mip_time_limit(m::Optimizer) + time_limit = max(0.0, get_option(m, :timeout) - m.logs[:total_time]) + MOI.set(m.model_mip, MOI.TimeLimitSec(), time_limit) end """ Follow the definition of terms to calculate the value of lifted terms """ -function resolve_lifted_var_value(m::AlpineNonlinearModel, sol_vec::Array) +function resolve_lifted_var_value(m::Optimizer, sol_vec::Array) @assert length(sol_vec) == m.num_var_orig sol_vec = [sol_vec; fill(NaN, m.num_var_linear_mip+m.num_var_nonlinear_mip)] @@ -939,7 +840,7 @@ function resolve_lifted_var_value(m::AlpineNonlinearModel, sol_vec::Array) return sol_vec end -function adjust_branch_priority(m::AlpineNonlinearModel) +function adjust_branch_priority(m::Optimizer) if m.mip_solver_id == "Gurobi" !m.model_mip.internalModelLoaded && return diff --git a/test/algorithm.jl b/test/algorithm.jl index 340d6772..fde182a3 100644 --- a/test/algorithm.jl +++ b/test/algorithm.jl @@ -1,227 +1,232 @@ @testset " Validation Test || AMP-TMC || basic solve || examples/nlp1.jl" begin - test_solver = AlpineSolver(nlp_solver=IpoptSolver(print_level=0), - mip_solver=pavito_solver, - bilinear_convexhull=false, - monomial_convexhull=false, - presolve_bt=false, - presolve_bp=true, - presolve_bt_output_tol=1e-1, - loglevel=100) + test_solver = optimizer_with_attributes(Alpine.Optimizer, "nlp_solver" => IPOPT, + "mip_solver" => PAVITO, + "bilinear_convexhull" => false, + "monomial_convexhull" => false, + "presolve_bt" => false, + "presolve_bp" => true, + "presolve_bt_output_tol" => 1e-1, + "loglevel" =>100) m = nlp1(solver=test_solver) - status = solve(m) + JuMP.optimize!(m) - @test status == :Optimal - @test isapprox(m.objVal, 58.38367169858795; atol=1e-4) - @test m.internalModel.logs[:n_iter] == 7 + @test termination_status(m) == MOI.OPTIMAL + @test isapprox(objective_value(m), 58.38367169858795; atol=1e-4) + @test MOI.get(m, Alpine.NumberOfIterations()) == 7 end @testset " Validation Test || AMP-TMC || basic solve || examples/nlp3.jl (3 iterations)" begin - test_solver=AlpineSolver(nlp_solver=IpoptSolver(print_level=0), - mip_solver=CbcSolver(logLevel=0), - bilinear_convexhull=false, - monomial_convexhull=false, - presolve_bp=true, - loglevel=100, - maxiter=3, - presolve_bt_width_tol=1e-3, - presolve_bt=false, - disc_var_pick=0) + test_solver=optimizer_with_attributes(Alpine.Optimizer, "nlp_solver" => IPOPT, + "mip_solver" => CBC, + "bilinear_convexhull" => false, + "monomial_convexhull" => false, + "presolve_bp" => true, + "loglevel" =>100, + "maxiter" => 3, + "presolve_bt_width_tol" => 1e-3, + "presolve_bt" => false, + "disc_var_pick" => 0) m = nlp3(solver=test_solver) - status = solve(m) + JuMP.optimize!(m) - @test status == :UserLimits + @test termination_status(m) == MOI.OTHER_LIMIT - @test isapprox(m.objVal, 7049.247897696512; atol=1e-4) - @test m.internalModel.logs[:n_iter] == 3 + @test isapprox(objective_value(m), 7049.247897696512; atol=1e-4) + @test MOI.get(m, Alpine.NumberOfIterations()) == 3 end @testset " Validation Test || AMP-TMC || minimum-vertex solving || examples/nlp3.jl (3 iterations)" begin - test_solver=AlpineSolver(nlp_solver=IpoptSolver(print_level=0, max_iter=9999), - mip_solver=CbcSolver(logLevel=0), - bilinear_convexhull=false, - monomial_convexhull=false, - presolve_bp=true, - disc_var_pick=1, - loglevel=100, - maxiter=3, - presolve_bt_width_tol=1e-3, - presolve_bt=false) - m = nlp3(solver=test_solver) - status = solve(m) - - @test status == :UserLimits - @test isapprox(m.objVal, 7049.247897696512; atol=1e-4) - @test m.internalModel.logs[:n_iter] == 3 - @test isapprox(m.objBound, 3647.178; atol=1e-2) + test_solver=optimizer_with_attributes(Alpine.Optimizer, "nlp_solver" => IPOPT_9999, + "mip_solver" => CBC, + "bilinear_convexhull" => false, + "monomial_convexhull" => false, + "presolve_bp" => true, + "disc_var_pick" => 1, + "loglevel" =>100, + "maxiter" => 3, + "presolve_bt_width_tol" => 1e-3, + "presolve_bt" => false) + m = nlp3(solver = test_solver) + JuMP.optimize!(m) + + @test termination_status(m) == MOI.OTHER_LIMIT + @test isapprox(objective_value(m), 7049.247897696512; atol=1e-4) + @test MOI.get(m, Alpine.NumberOfIterations()) == 3 + @test isapprox(objective_bound(m), 3647.178; atol=1e-2) end @testset " Validation Test || BT-AMP-TMC || basic solve || examples/nlp3.jl" begin - test_solver = AlpineSolver(nlp_solver=IpoptSolver(print_level=0), - mip_solver=CbcSolver(logLevel=0), - bilinear_convexhull=false, - loglevel=100, - maxiter=3, - presolve_bt_width_tol=1e-3, - presolve_bt_output_tol=1e-1, - presolve_bt=true, - presolve_bt_algo=1, - presolve_bp=true, - presolve_maxiter=2, - presolve_track_time=true, - disc_var_pick=max_cover_var_picker) + test_solver = optimizer_with_attributes(Alpine.Optimizer, "nlp_solver" => IPOPT, + "mip_solver" => CBC, + "bilinear_convexhull" => false, + "loglevel" =>100, + "maxiter" => 3, + "presolve_bt_width_tol" => 1e-3, + "presolve_bt_output_tol" => 1e-1, + "presolve_bt" => true, + "presolve_bt_algo" => 1, + "presolve_bp" => true, + "presolve_maxiter" => 2, + "presolve_track_time" => true, + "disc_var_pick" => max_cover_var_picker) m = nlp3(solver=test_solver) - status = solve(m) - - @test status == :UserLimits - @test m.internalModel.logs[:n_iter] == 3 - @test m.internalModel.logs[:bt_iter] == 2 -end - -@testset " Validation Test || PBT-AMP-TMC || basic solve || examples/nlp3.jl" begin - - test_solver = AlpineSolver(nlp_solver=IpoptSolver(print_level=0), - mip_solver=pavito_solver, - bilinear_convexhull=false, - loglevel=100, - maxiter=2, - presolve_bt=true, - presolve_bt_width_tol=1e-3, - presolve_bt_output_tol=1e-1, - presolve_bt_algo=2, - presolve_bp=true, - presolve_maxiter=2, - disc_var_pick=max_cover_var_picker) - - m = nlp3(solver=test_solver) - status = solve(m) - @test status == :UserLimits - @test m.internalModel.logs[:n_iter] == 2 -end + JuMP.optimize!(m) + + @test termination_status(m) == MOI.OTHER_LIMIT + @test MOI.get(m, Alpine.NumberOfIterations()) == 3 + @test MOI.get(m, Alpine.NumberOfPresolveIterations()) == 2 +end + +# FIXME Pavito terminates with `NUMERICAL_ERROR` on Julia v1.0: +# https://travis-ci.org/github/lanl-ansi/Alpine.jl/jobs/717281623 +#@testset " Validation Test || PBT-AMP-TMC || basic solve || examples/nlp3.jl" begin +# +# test_solver = optimizer_with_attributes(Alpine.Optimizer, "nlp_solver" => IPOPT, +# "mip_solver" => PAVITO, +# "bilinear_convexhull" => false, +# "loglevel" =>100, +# "maxiter" => 2, +# "presolve_bt" => true, +# "presolve_bt_width_tol" => 1e-3, +# "presolve_bt_output_tol" => 1e-1, +# "presolve_bt_algo" => 2, +# "presolve_bp" => true, +# "presolve_maxiter" => 2, +# "disc_var_pick" => max_cover_var_picker) +# +# m = nlp3(solver=test_solver) +# JuMP.optimize!(m) +# @test termination_status(m) == MOI.OTHER_LIMIT +# @test MOI.get(m, Alpine.NumberOfIterations()) == 2 +#end @testset " Validation Test || AMP-CONV || basic solve || examples/nlp1.jl" begin - test_solver = AlpineSolver(nlp_solver=IpoptSolver(print_level=0), - mip_solver=pavito_solver, - bilinear_convexhull=true, - monomial_convexhull=true, - presolve_bt=false, - presolve_bp=true, - loglevel=100) + test_solver = optimizer_with_attributes(Alpine.Optimizer, "nlp_solver" => IPOPT, + "mip_solver" => PAVITO, + "bilinear_convexhull" => true, + "monomial_convexhull" => true, + "presolve_bt" => false, + "presolve_bp" => true, + "loglevel" => 100) m = nlp1(solver=test_solver) - status = solve(m) + JuMP.optimize!(m) - @test status == :Optimal - @test isapprox(m.objVal, 58.38367169858795; atol=1e-4) - @test m.internalModel.logs[:n_iter] == 7 + @test termination_status(m) == MOI.OPTIMAL + @test isapprox(objective_value(m), 58.38367169858795; atol=1e-4) + @test MOI.get(m, Alpine.NumberOfIterations()) == 7 end # @testset " Validation Test || AMP-CONV || basic solve || examples/nlp3.jl" begin -# test_solver = AlpineSolver(nlp_solver=IpoptSolver(print_level=0), -# mip_solver=CbcSolver(logLevel=0), -# bilinear_convexhull=true, -# monomial_convexhull=true, -# presolve_bt=false, -# presolve_bp=false, -# loglevel=100) +# test_solver = optimizer_with_attributes(Alpine.Optimizer, "nlp_solver" => IPOPT, +# "mip_solver" => CBC, +# "bilinear_convexhull" => true, +# "monomial_convexhull" => true, +# "presolve_bt" => false, +# "presolve_bp" => false, +# "loglevel" =>100) # m = nlp3(solver=test_solver) -# status = solve(m) +# JuMP.optimize!(m) -# @test status == :Optimal -# @test isapprox(m.objVal, 7049.247897696188; atol=1e-4) -# @test m.internalModel.logs[:n_iter] == 9 +# @test termination_status(m) == MOI.OPTIMAL +# @test isapprox(objective_value(m), 7049.247897696188; atol=1e-4) +# @test MOI.get(m, Alpine.NumberOfIterations()) == 9 # end @testset " Validation Test || AMP || basic solve || examples/circle.jl" begin - test_solver=AlpineSolver(nlp_solver=IpoptSolver(print_level=0), - mip_solver=pavito_solver, - disc_abs_width_tol=1e-2, - disc_ratio=8, - maxiter=6, - presolve_bt = false, - presolve_bt_algo = 1, - presolve_bt_output_tol = 1e-1, - loglevel=100) + test_solver=optimizer_with_attributes(Alpine.Optimizer, + "nlp_solver" => IPOPT, + "mip_solver" => PAVITO, + "disc_abs_width_tol" => 1e-2, + "disc_ratio" => 8, + "maxiter" => 6, + "presolve_bt" => false, + "presolve_bt_algo" => 1, + "presolve_bt_output_tol" => 1e-1, + "loglevel" => 100) m = circle(solver=test_solver) - solve(m) + optimize!(m) - @test isapprox(m.objVal, 1.4142135534556992; atol=1e-3) + @test isapprox(objective_value(m), 1.4142135534556992; atol=1e-3) end @testset " Validation Test || AMP || basic solve || examples/circleN.jl" begin - test_solver=AlpineSolver(nlp_solver=IpoptSolver(print_level=0), - mip_solver=pavito_solver, - disc_abs_width_tol=1e-2, - disc_ratio=8, - presolve_bt = false, - presolve_bt_algo = 1, - presolve_bt_output_tol = 1e-1, - loglevel=100) + test_solver=optimizer_with_attributes(Alpine.Optimizer, "nlp_solver" => IPOPT, + "mip_solver" => PAVITO, + "disc_abs_width_tol" => 1e-2, + "disc_ratio" => 8, + "presolve_bt" => false, + "presolve_bt_algo" => 1, + "presolve_bt_output_tol" => 1e-1, + "loglevel" => 100) m = circleN(solver=test_solver, N=4) - solve(m) - @test isapprox(m.objVal, 2.0; atol=1e-3) -end - -@testset " Validation Test || AMP-CONV-FACET || basic solve || examples/nlp1.jl" begin - test_solver = AlpineSolver(nlp_solver=IpoptSolver(print_level=0), - mip_solver=pavito_solver, - bilinear_convexhull=true, - monomial_convexhull=true, - presolve_bt=false, - presolve_bp=true, - convhull_formulation="facet", - loglevel=100) - m = nlp1(solver=test_solver) - status = solve(m) - - @test status == :Optimal - @test isapprox(m.objVal, 58.38367169858795; atol=1e-4) - @test m.internalModel.logs[:n_iter] == 7 -end + optimize!(m) + @test isapprox(objective_value(m), 2.0; atol=1e-3) +end + +# FIXME Pavito terminates with `OTHER_ERROR` +# https://travis-ci.org/github/lanl-ansi/Alpine.jl/jobs/717281624 +#@testset " Validation Test || AMP-CONV-FACET || basic solve || examples/nlp1.jl" begin +# test_solver = optimizer_with_attributes(Alpine.Optimizer, "nlp_solver" => IPOPT, +# "mip_solver" => PAVITO, +# "bilinear_convexhull" => true, +# "monomial_convexhull" => true, +# "presolve_bt" => false, +# "presolve_bp" => true, +# "convhull_formulation" => "facet", +# "loglevel" =>100) +# m = nlp1(solver=test_solver) +# JuMP.optimize!(m) +# +# @test termination_status(m) == MOI.OPTIMAL +# @test isapprox(objective_value(m), 58.38367169858795; atol=1e-4) +# @test MOI.get(m, Alpine.NumberOfIterations()) == 7 +#end @testset " Validation Test || AMP || multi4N || N = 2 || exprmode=1:11" begin objBoundVec = Any[4.68059, 12.0917, 8.94604, 10.0278, 8.100, 6.6384, 12.5674, 7.3975, 6.0292, 7.9146, 7.8830] objValVec = Any[2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0] for i in 1:11 - test_solver=AlpineSolver(nlp_solver=IpoptSolver(print_level=0), - mip_solver=CbcSolver(logLevel=0), - disc_abs_width_tol=1e-2, - maxiter=4, - presolve_bp=false, - presolve_bt=false, - loglevel=1) + test_solver=optimizer_with_attributes(Alpine.Optimizer, "nlp_solver" => IPOPT, + "mip_solver" => CBC, + "disc_abs_width_tol" => 1e-2, + "maxiter" => 4, + "presolve_bp" => false, + "presolve_bt" => false, + "loglevel" => 1) m = multi4N(solver=test_solver, N=2, exprmode=i) - status = solve(m) + JuMP.optimize!(m) - @test status == :UserLimits - @test isapprox(getobjectivevalue(m), objValVec[i];atol=1e-3) -# @test isapprox(getobjectivebound(m), objBoundVec[i];atol=1e-3) + @test termination_status(m) == MOI.OTHER_LIMIT + @test isapprox(objective_value(m), objValVec[i];atol=1e-3) +# @test isapprox(objective_bound(m), objBoundVec[i];atol=1e-3) end end @testset " Validation Test || AMP || multi2 || exprmode=1:11" begin - test_solver=AlpineSolver(nlp_solver=IpoptSolver(print_level=0), - mip_solver=CbcSolver(logLevel=0), - disc_abs_width_tol=1e-2, - maxiter=4, - presolve_bp=false, - presolve_bt=false, - loglevel=1) + test_solver=optimizer_with_attributes(Alpine.Optimizer, "nlp_solver" => IPOPT, + "mip_solver" => CBC, + "disc_abs_width_tol" => 1e-2, + "maxiter" => 4, + "presolve_bp" => false, + "presolve_bt" => false, + "loglevel" => 1) m = multi2(solver=test_solver) - status = solve(m) + JuMP.optimize!(m) - @test status == :UserLimits - @test isapprox(getobjectivevalue(m), 1.00000;atol=1e-3) - @test isapprox(getobjectivebound(m), 1.0074;atol=1e-3) + @test termination_status(m) == MOI.OTHER_LIMIT + @test isapprox(objective_value(m), 1.00000;atol=1e-3) + @test isapprox(objective_bound(m), 1.0074;atol=1e-3) end @testset " Validation Test || AMP || multi3N || N = 2 || exprmode=1:11" begin @@ -229,595 +234,598 @@ end objBoundVec = Any[2.97186, 3.85492, 4.23375] objValVec = Any[2.0, 2.0, 2.0] for i in 1:3 - test_solver=AlpineSolver(nlp_solver=IpoptSolver(print_level=0), - mip_solver=CbcSolver(logLevel=0), - disc_abs_width_tol=1e-2, - maxiter=4, - presolve_bp=false, - presolve_bt=false, - loglevel=1) + test_solver=optimizer_with_attributes(Alpine.Optimizer, "nlp_solver" => IPOPT, + "mip_solver" => CBC, + "disc_abs_width_tol" => 1e-2, + "maxiter" => 4, + "presolve_bp" => false, + "presolve_bt" => false, + "loglevel" => 1) m = multi3N(solver=test_solver, N=2, exprmode=i) - status = solve(m) + JuMP.optimize!(m) - @test status == :UserLimits - @test isapprox(getobjectivevalue(m), objValVec[i];atol=1e-3) - @test isapprox(getobjectivebound(m), objBoundVec[i];atol=1e-3) + @test termination_status(m) == MOI.OTHER_LIMIT + @test isapprox(objective_value(m), objValVec[i];atol=1e-3) + @test isapprox(objective_bound(m), objBoundVec[i];atol=1e-3) end end @testset " Validation Test || AMP || multiKND || K = 3, N = 3, D = 0 " begin - test_solver=AlpineSolver(nlp_solver=IpoptSolver(print_level=0), - mip_solver=CbcSolver(logLevel=0), - disc_abs_width_tol=1e-2, - maxiter=3, - presolve_bp=false, - presolve_bt=false, - loglevel=1) + test_solver=optimizer_with_attributes(Alpine.Optimizer, "nlp_solver" => IPOPT, + "mip_solver" => CBC, + "disc_abs_width_tol" => 1e-2, + "maxiter" => 3, + "presolve_bp" => false, + "presolve_bt" => false, + "loglevel" =>1) m = multiKND(solver=test_solver, randomub=50, K=3, N=3, D=0) - status = solve(m) + JuMP.optimize!(m) - @test status == :UserLimits - @test isapprox(getobjectivevalue(m),3.0000000824779454;atol=1e-3) - @test isapprox(getobjectivebound(m),12.054604248046875;atol=1e-3) + @test termination_status(m) == MOI.OTHER_LIMIT + @test isapprox(objective_value(m),3.0000000824779454;atol=1e-3) + @test isapprox(objective_bound(m),12.054604248046875;atol=1e-3) end @testset " Validation Test || AMP-CONV-FACET || basic solve || examples/nlp3.jl" begin - test_solver = AlpineSolver(nlp_solver=IpoptSolver(print_level=0), - mip_solver=CbcSolver(logLevel=0), - bilinear_convexhull=true, - monomial_convexhull=true, - presolve_bt=false, - presolve_bp=false, - maxiter=4, - convhull_formulation="facet", - loglevel=100) + test_solver = optimizer_with_attributes(Alpine.Optimizer, "nlp_solver" => IPOPT, + "mip_solver" => CBC, + "bilinear_convexhull" => true, + "monomial_convexhull" => true, + "presolve_bt" => false, + "presolve_bp" => false, + "maxiter" => 4, + "convhull_formulation" => "facet", + "loglevel" =>100) m = nlp3(solver=test_solver) - status = solve(m) + JuMP.optimize!(m) - @test status == :UserLimits - @test isapprox(m.objVal, 7049.247897696188; atol=1e-4) - @test m.objBound >= 6717.00 - @test m.objBound <= 6718.00 - @test m.internalModel.logs[:n_iter] == 4 + @test termination_status(m) == MOI.OTHER_LIMIT + @test isapprox(objective_value(m), 7049.247897696188; atol=1e-4) + @test objective_bound(m) >= 6717.00 + @test objective_bound(m) <= 6718.00 + @test MOI.get(m, Alpine.NumberOfIterations()) == 4 end @testset " Validation Test || AMP || DISC-RATIO || examples/nlp3.jl " begin - test_solver=AlpineSolver(nlp_solver=IpoptSolver(print_level=0), - mip_solver=CbcSolver(logLevel=0), - disc_abs_width_tol=1e-2, - disc_ratio_branch=false, - disc_ratio=18, - maxiter=1, - presolve_bp=true, - presolve_bt=false, - loglevel=100) + test_solver=optimizer_with_attributes(Alpine.Optimizer, "nlp_solver" => IPOPT, + "mip_solver" => CBC, + "disc_abs_width_tol" => 1e-2, + "disc_ratio_branch" => false, + "disc_ratio" => 18, + "maxiter" => 1, + "presolve_bp" => true, + "presolve_bt" => false, + "loglevel" => 100) m = nlp3(solver=test_solver) - solve(m) + optimize!(m) - @test m.internalModel.logs[:n_iter] == 1 - @test m.internalModel.disc_ratio == 18 + @test MOI.get(m, Alpine.NumberOfIterations()) == 1 + @test MOI.get(m, MOI.RawParameter("disc_ratio")) == 18 end @testset " Validation Test || AMP || DISC-RATIO-BRANCH || examples/nlp3.jl " begin - test_solver=AlpineSolver(nlp_solver=IpoptSolver(print_level=0), - mip_solver=CbcSolver(logLevel=0), - disc_abs_width_tol=1e-2, - disc_ratio_branch=true, - maxiter=1, - presolve_bp=true, - presolve_bt=false, - loglevel=100) + test_solver=optimizer_with_attributes(Alpine.Optimizer, "nlp_solver" => IPOPT, + "mip_solver" => CBC, + "disc_abs_width_tol" => 1e-2, + "disc_ratio_branch" => true, + "maxiter" => 1, + "presolve_bp" => true, + "presolve_bt" => false, + "loglevel" => 100) m = nlp3(solver=test_solver) - solve(m) + optimize!(m) - @test m.internalModel.logs[:n_iter] == 1 - @test m.internalModel.disc_ratio == 14 + @test MOI.get(m, Alpine.NumberOfIterations()) == 1 + @test MOI.get(m, MOI.RawParameter("disc_ratio")) == 14 end @testset " Validation Test || AMP || DISC-RATIO-BRANCH || examples/castro2m2.jl " begin - test_solver=AlpineSolver(nlp_solver=IpoptSolver(print_level=0), - mip_solver=CbcSolver(logLevel=0), - disc_abs_width_tol=1e-2, - disc_ratio_branch=true, - maxiter=1, - presolve_bp=true, - presolve_bt=false, - loglevel=100) + test_solver=optimizer_with_attributes(Alpine.Optimizer, "nlp_solver" => IPOPT, + "mip_solver" => CBC, + "disc_abs_width_tol" => 1e-2, + "disc_ratio_branch" => true, + "maxiter" => 1, + "presolve_bp" => true, + "presolve_bt" => false, + "loglevel" => 100) m = castro2m2(solver=test_solver) - solve(m) + optimize!(m) - @test m.internalModel.logs[:n_iter] == 1 - @test m.internalModel.disc_ratio == 8 + @test MOI.get(m, Alpine.NumberOfIterations()) == 1 + @test MOI.get(m, MOI.RawParameter("disc_ratio")) == 8 end @testset " Validation Test || AMP || DISC-RATIO-BRANCH || examples/multi3N.jl exprmode=2" begin - test_solver=AlpineSolver(nlp_solver=IpoptSolver(print_level=0), - mip_solver=CbcSolver(logLevel=0), - disc_abs_width_tol=1e-2, - disc_ratio_branch=true, - maxiter=1, - presolve_bp=true, - presolve_bt=false, - loglevel=100) + test_solver=optimizer_with_attributes(Alpine.Optimizer, "nlp_solver" => IPOPT, + "mip_solver" => CBC, + "disc_abs_width_tol" => 1e-2, + "disc_ratio_branch" => true, + "maxiter" => 1, + "presolve_bp" => true, + "presolve_bt" => false, + "loglevel" => 100) m = multi3N(solver=test_solver, N=3, exprmode=1) - solve(m) + optimize!(m) - @test m.internalModel.logs[:n_iter] == 1 - @test m.internalModel.disc_ratio == 16 + @test MOI.get(m, Alpine.NumberOfIterations()) == 1 + @test MOI.get(m, MOI.RawParameter("disc_ratio")) == 16 end @testset " Validation Test || AMP || DISC-RATIO-BRANCH || examples/multi3N.jl exprmode=2" begin - test_solver=AlpineSolver(nlp_solver=IpoptSolver(print_level=0), - mip_solver=CbcSolver(logLevel=0), - disc_abs_width_tol=1e-2, - disc_ratio_branch=true, - maxiter=1, - presolve_bp=false, - presolve_bt=false, - loglevel=100) + test_solver=optimizer_with_attributes(Alpine.Optimizer, "nlp_solver" => IPOPT, + "mip_solver" => CBC, + "disc_abs_width_tol" => 1e-2, + "disc_ratio_branch" => true, + "maxiter" => 1, + "presolve_bp" => false, + "presolve_bt" => false, + "loglevel" => 100) m = multi3N(solver=test_solver, N=3, exprmode=1) - solve(m) + optimize!(m) - @test m.internalModel.logs[:n_iter] == 1 - @test m.internalModel.disc_ratio == 20 + @test MOI.get(m, Alpine.NumberOfIterations()) == 1 + @test MOI.get(m, MOI.RawParameter("disc_ratio")) == 20 end @testset " Validation Test || AMP || DISC-RATIO-BRANCH || examples/multi4N.jl exprmode=1" begin - test_solver=AlpineSolver(nlp_solver=IpoptSolver(print_level=0), - mip_solver=CbcSolver(logLevel=0), - disc_abs_width_tol=1e-2, - disc_ratio_branch=true, - maxiter=1, - presolve_bp=true, - presolve_bt=false, - loglevel=100) + test_solver=optimizer_with_attributes(Alpine.Optimizer, "nlp_solver" => IPOPT, + "mip_solver" => CBC, + "disc_abs_width_tol" => 1e-2, + "disc_ratio_branch" => true, + "maxiter" => 1, + "presolve_bp" => true, + "presolve_bt" => false, + "loglevel" => 100) m = multi4N(solver=test_solver, N=2, exprmode=1) - solve(m) + optimize!(m) - @test m.internalModel.logs[:n_iter] == 1 - @test m.internalModel.disc_ratio == 12 + @test MOI.get(m, Alpine.NumberOfIterations()) == 1 + @test MOI.get(m, MOI.RawParameter("disc_ratio")) == 12 end @testset " Validation Test || AMP || DISC-RATIO-BRANCH || examples/multi4N.jl exprmode=2" begin - test_solver=AlpineSolver(nlp_solver=IpoptSolver(print_level=0), - mip_solver=CbcSolver(logLevel=0), - disc_abs_width_tol=1e-2, - disc_ratio_branch=true, - maxiter=1, - presolve_bp=false, - presolve_bt=false, - loglevel=100) + test_solver=optimizer_with_attributes(Alpine.Optimizer, "nlp_solver" => IPOPT, + "mip_solver" => CBC, + "disc_abs_width_tol" => 1e-2, + "disc_ratio_branch" => true, + "maxiter" => 1, + "presolve_bp" => false, + "presolve_bt" => false, + "loglevel" => 100) m = multi4N(solver=test_solver, N=2, exprmode=1) - solve(m) + optimize!(m) - @test m.internalModel.logs[:n_iter] == 1 - @test m.internalModel.disc_ratio == 20 + @test MOI.get(m, Alpine.NumberOfIterations()) == 1 + @test MOI.get(m, MOI.RawParameter("disc_ratio")) == 20 end @testset " Validation Test || AMP || DISC-RATIO-BRANCH || examples/multi4N.jl exprmode=2" begin - test_solver=AlpineSolver(nlp_solver=IpoptSolver(print_level=0), - mip_solver=CbcSolver(logLevel=0), - disc_abs_width_tol=1e-2, - disc_ratio_branch=true, - maxiter=1, - presolve_bp=true, - presolve_bt=false, - loglevel=100) + test_solver=optimizer_with_attributes(Alpine.Optimizer, "nlp_solver" => IPOPT, + "mip_solver" => CBC, + "disc_abs_width_tol" => 1e-2, + "disc_ratio_branch" => true, + "maxiter" => 1, + "presolve_bp" => true, + "presolve_bt" => false, + "loglevel" => 100) m = multi4N(solver=test_solver, N=2, exprmode=2) - solve(m) + optimize!(m) - @test m.internalModel.logs[:n_iter] == 1 - @test m.internalModel.disc_ratio == 20 + @test MOI.get(m, Alpine.NumberOfIterations()) == 1 + @test MOI.get(m, MOI.RawParameter("disc_ratio")) == 20 end @testset "Operator :: bmpl && binlin && binprod solve test I" begin - test_solver=AlpineSolver(minlp_solver=pavito_solver, - nlp_solver=IpoptSolver(print_level=0), - mip_solver=CbcSolver(logLevel=0), - presolve_bt=false, - loglevel=100) + test_solver=optimizer_with_attributes(Alpine.Optimizer, "minlp_solver" => PAVITO, + "nlp_solver" => IPOPT, + "mip_solver" => CBC, + "presolve_bt" => false, + "loglevel" => 100) m = bpml_lnl(test_solver) - solve(m) - @test isapprox(m.objVal, 0.3; atol=1e-6) - @test haskey(m.internalModel.nonconvex_terms, Expr[:(x[1]), :(x[6])]) - @test haskey(m.internalModel.nonconvex_terms, Expr[:(x[2]), :(x[7])]) - @test haskey(m.internalModel.nonconvex_terms, Expr[:(x[3]), :(x[8])]) - @test haskey(m.internalModel.nonconvex_terms, Expr[:(x[4]), :(x[9])]) - @test haskey(m.internalModel.nonconvex_terms, Expr[:(x[5]), :(x[10])]) - - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[6])]][:nonlinear_type] == :BINLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[7])]][:nonlinear_type] == :BINLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[8])]][:nonlinear_type] == :BINLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[9])]][:nonlinear_type] == :BINLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[10])]][:nonlinear_type] == :BINLIN + optimize!(m) + @test isapprox(objective_value(m), 0.3; atol=1e-6) + alpine = JuMP.backend(m).optimizer.model + @test haskey(alpine.nonconvex_terms, Expr[:(x[1]), :(x[6])]) + @test haskey(alpine.nonconvex_terms, Expr[:(x[2]), :(x[7])]) + @test haskey(alpine.nonconvex_terms, Expr[:(x[3]), :(x[8])]) + @test haskey(alpine.nonconvex_terms, Expr[:(x[4]), :(x[9])]) + @test haskey(alpine.nonconvex_terms, Expr[:(x[5]), :(x[10])]) + + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[6])]][:nonlinear_type] == :BINLIN + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[7])]][:nonlinear_type] == :BINLIN + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[8])]][:nonlinear_type] == :BINLIN + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[9])]][:nonlinear_type] == :BINLIN + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[10])]][:nonlinear_type] == :BINLIN end @testset "Operator :: bmpl && binlin && binprod solve test II" begin - test_solver=AlpineSolver(minlp_solver=pavito_solver, - nlp_solver=IpoptSolver(print_level=0), - mip_solver=CbcSolver(logLevel=0), - presolve_bt=false, - loglevel=100) + test_solver=optimizer_with_attributes(Alpine.Optimizer, "minlp_solver" => PAVITO, + "nlp_solver" => IPOPT, + "mip_solver" => CBC, + "presolve_bt" => false, + "loglevel" => 100) m = bpml_binl(test_solver) - solve(m) - @test isapprox(m.objVal, 15422.058099086951; atol=1e-1) - - @test haskey(m.internalModel.nonconvex_terms, Expr[:(x[6]), :(x[7])]) - @test haskey(m.internalModel.nonconvex_terms, Expr[:(x[7]), :(x[8])]) - @test haskey(m.internalModel.nonconvex_terms, Expr[:(x[8]), :(x[9])]) - @test haskey(m.internalModel.nonconvex_terms, Expr[:(x[9]), :(x[10])]) - @test haskey(m.internalModel.nonconvex_terms, Expr[:(x[10]), :(x[6])]) - @test haskey(m.internalModel.nonconvex_terms, Expr[:(x[1]), :(x[11])]) - @test haskey(m.internalModel.nonconvex_terms, Expr[:(x[2]), :(x[13])]) - @test haskey(m.internalModel.nonconvex_terms, Expr[:(x[3]), :(x[15])]) - @test haskey(m.internalModel.nonconvex_terms, Expr[:(x[4]), :(x[17])]) - @test haskey(m.internalModel.nonconvex_terms, Expr[:(x[5]), :(x[19])]) - - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[7])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[7]), :(x[8])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[8]), :(x[9])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[9]), :(x[10])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[10]), :(x[6])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[11])]][:nonlinear_type] == :BINLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[13])]][:nonlinear_type] == :BINLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[15])]][:nonlinear_type] == :BINLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[17])]][:nonlinear_type] == :BINLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[19])]][:nonlinear_type] == :BINLIN + optimize!(m) + @test isapprox(objective_value(m), 15422.058099086951; atol=1e-1) + + alpine = JuMP.backend(m).optimizer.model + @test haskey(alpine.nonconvex_terms, Expr[:(x[6]), :(x[7])]) + @test haskey(alpine.nonconvex_terms, Expr[:(x[7]), :(x[8])]) + @test haskey(alpine.nonconvex_terms, Expr[:(x[8]), :(x[9])]) + @test haskey(alpine.nonconvex_terms, Expr[:(x[9]), :(x[10])]) + @test haskey(alpine.nonconvex_terms, Expr[:(x[10]), :(x[6])]) + @test haskey(alpine.nonconvex_terms, Expr[:(x[1]), :(x[11])]) + @test haskey(alpine.nonconvex_terms, Expr[:(x[2]), :(x[13])]) + @test haskey(alpine.nonconvex_terms, Expr[:(x[3]), :(x[15])]) + @test haskey(alpine.nonconvex_terms, Expr[:(x[4]), :(x[17])]) + @test haskey(alpine.nonconvex_terms, Expr[:(x[5]), :(x[19])]) + + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[7])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[7]), :(x[8])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[8]), :(x[9])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[9]), :(x[10])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[10]), :(x[6])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[11])]][:nonlinear_type] == :BINLIN + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[13])]][:nonlinear_type] == :BINLIN + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[15])]][:nonlinear_type] == :BINLIN + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[17])]][:nonlinear_type] == :BINLIN + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[19])]][:nonlinear_type] == :BINLIN end @testset "Embedding Test || AMP-CONV || basic solve || examples/nlp1.jl" begin - test_solver = AlpineSolver(nlp_solver=IpoptSolver(print_level=0), - mip_solver=pavito_solver, - bilinear_convexhull=true, - monomial_convexhull=true, - presolve_bt=false, - presolve_bp=true, - convhull_ebd=true, - loglevel=100) + test_solver = optimizer_with_attributes(Alpine.Optimizer, "nlp_solver" => IPOPT, + "mip_solver" => PAVITO, + "bilinear_convexhull" => true, + "monomial_convexhull" => true, + "presolve_bt" => false, + "presolve_bp" => true, + "convhull_ebd" => true, + "loglevel" => 100) m = nlp1(solver=test_solver) - status = solve(m) + JuMP.optimize!(m) - @test status == :Optimal - @test isapprox(m.objVal, 58.38367169858795; atol=1e-4) - @test m.internalModel.logs[:n_iter] == 7 + @test termination_status(m) == MOI.OPTIMAL + @test isapprox(objective_value(m), 58.38367169858795; atol=1e-4) + @test MOI.get(m, Alpine.NumberOfIterations()) == 7 end @testset "Embedding Test || AMP || special problem || ... " begin - test_solver=AlpineSolver(nlp_solver=IpoptSolver(print_level=0), - mip_solver=pavito_solver, - disc_abs_width_tol=1e-2, - disc_ratio=8, - maxiter=6, - presolve_bt=false, - presolve_bp=true, - presolve_bt_algo=1, - presolve_bt_output_tol=1e-1, - convhull_ebd=true, - loglevel=100) + test_solver=optimizer_with_attributes(Alpine.Optimizer, "nlp_solver" => IPOPT, + "mip_solver" => PAVITO, + "disc_abs_width_tol" => 1e-2, + "disc_ratio" => 8, + "maxiter" => 6, + "presolve_bt" => false, + "presolve_bp" => true, + "presolve_bt_algo" => 1, + "presolve_bt_output_tol" => 1e-1, + "convhull_ebd" => true, + "loglevel" => 100) m = circle(solver=test_solver) - solve(m) - @test isapprox(m.objVal, 1.4142135534556992; atol=1e-3) + optimize!(m) + @test isapprox(objective_value(m), 1.4142135534556992; atol=1e-3) end @testset "Embedding IBS Test || AMP-CONV || basic solve || examples/nlp1.jl" begin - test_solver = AlpineSolver(nlp_solver=IpoptSolver(print_level=0), - mip_solver=pavito_solver, - bilinear_convexhull=true, - monomial_convexhull=true, - presolve_bt=false, - presolve_bp=true, - convhull_ebd=true, - convhull_ebd_ibs=true, - loglevel=100) + test_solver = optimizer_with_attributes(Alpine.Optimizer, "nlp_solver" => IPOPT, + "mip_solver" => PAVITO, + "bilinear_convexhull" => true, + "monomial_convexhull" => true, + "presolve_bt" => false, + "presolve_bp" => true, + "convhull_ebd" => true, + "convhull_ebd_ibs" => true, + "loglevel" => 100) m = nlp1(solver=test_solver) - status = solve(m) + JuMP.optimize!(m) - @test status == :Optimal - @test isapprox(m.objVal, 58.38367169858795; atol=1e-4) - @test m.internalModel.logs[:n_iter] == 7 + @test termination_status(m) == MOI.OPTIMAL + @test isapprox(objective_value(m), 58.38367169858795; atol=1e-4) + @test MOI.get(m, Alpine.NumberOfIterations()) == 7 end @testset "Embedding IBS Test || AMP-CONV || basic solve || examples/nlp3.jl" begin - test_solver = AlpineSolver(nlp_solver=IpoptSolver(print_level=0), - mip_solver=CbcSolver(logLevel=0), - bilinear_convexhull=true, - monomial_convexhull=true, - presolve_bt=false, - presolve_bp=false, - convhull_ebd=true, - convhull_ebd_ibs=true, - loglevel=100) + test_solver = optimizer_with_attributes(Alpine.Optimizer, "nlp_solver" => IPOPT, + "mip_solver" => CBC, + "bilinear_convexhull" => true, + "monomial_convexhull" => true, + "presolve_bt" => false, + "presolve_bp" => false, + "convhull_ebd" => true, + "convhull_ebd_ibs" => true, + "loglevel" => 100) m = nlp3(solver=test_solver) - status = solve(m) + JuMP.optimize!(m) - @test status == :Optimal - @test isapprox(m.objVal, 7049.247897696188; atol=1e-4) - @test m.internalModel.logs[:n_iter] == 9 + @test termination_status(m) == MOI.OPTIMAL + @test isapprox(objective_value(m), 7049.247897696188; atol=1e-4) + @test MOI.get(m, Alpine.NumberOfIterations()) == 9 end @testset "Embedding IBS Test || AMP || special problem || ... " begin - test_solver=AlpineSolver(nlp_solver=IpoptSolver(print_level=0), - mip_solver=pavito_solver, - disc_abs_width_tol=1e-2, - disc_ratio=8, - maxiter=6, - presolve_bt=false, - presolve_bp=true, - presolve_bt_algo=1, - presolve_bt_output_tol=1e-1, - convhull_ebd=true, - convhull_ebd_ibs=true, - loglevel=100) + test_solver=optimizer_with_attributes(Alpine.Optimizer, "nlp_solver" => IPOPT, + "mip_solver" => PAVITO, + "disc_abs_width_tol" => 1e-2, + "disc_ratio" => 8, + "maxiter" => 6, + "presolve_bt" => false, + "presolve_bp" => true, + "presolve_bt_algo" => 1, + "presolve_bt_output_tol" => 1e-1, + "convhull_ebd" => true, + "convhull_ebd_ibs" => true, + "loglevel" => 100) m = circle(solver=test_solver) - solve(m) - @test isapprox(m.objVal, 1.4142135534556992; atol=1e-3) + optimize!(m) + @test isapprox(objective_value(m), 1.4142135534556992; atol=1e-3) end @testset "Embedding LINK Test || AMP-CONV || basic solve || examples/nlp1.jl" begin - test_solver = AlpineSolver(nlp_solver=IpoptSolver(print_level=0), - mip_solver=pavito_solver, - bilinear_convexhull=true, - monomial_convexhull=true, - presolve_bt=false, - presolve_bp=true, - convhull_ebd=true, - convhull_ebd_link=true, - loglevel=100) + test_solver = optimizer_with_attributes(Alpine.Optimizer, "nlp_solver" => IPOPT, + "mip_solver" => PAVITO, + "bilinear_convexhull" => true, + "monomial_convexhull" => true, + "presolve_bt" => false, + "presolve_bp" => true, + "convhull_ebd" => true, + "convhull_ebd_link" => true, + "loglevel" => 100) m = nlp1(solver=test_solver) - status = solve(m) + JuMP.optimize!(m) - @test status == :Optimal - @test isapprox(m.objVal, 58.38367169858795; atol=1e-4) - @test m.internalModel.logs[:n_iter] == 7 + @test termination_status(m) == MOI.OPTIMAL + @test isapprox(objective_value(m), 58.38367169858795; atol=1e-4) + @test MOI.get(m, Alpine.NumberOfIterations()) == 7 end @testset "Embedding LINK Test || AMP-CONV || basic solve || examples/nlp3.jl" begin - test_solver = AlpineSolver(nlp_solver=IpoptSolver(print_level=0), - mip_solver=CbcSolver(logLevel=0), - bilinear_convexhull=true, - monomial_convexhull=true, - presolve_bt=false, - presolve_bp=false, - convhull_ebd=true, - convhull_ebd_link=true, - loglevel=100) + test_solver = optimizer_with_attributes(Alpine.Optimizer, "nlp_solver" => IPOPT, + "mip_solver" => CBC, + "bilinear_convexhull" => true, + "monomial_convexhull" => true, + "presolve_bt" => false, + "presolve_bp" => false, + "convhull_ebd" => true, + "convhull_ebd_link" => true, + "loglevel" => 100) m = nlp3(solver=test_solver) - status = solve(m) + JuMP.optimize!(m) - @test status == :Optimal - @test isapprox(m.objVal, 7049.247897696188; atol=1e-4) - @test m.internalModel.logs[:n_iter] == 9 + @test termination_status(m) == MOI.OPTIMAL + @test isapprox(objective_value(m), 7049.247897696188; atol=1e-4) + @test MOI.get(m, Alpine.NumberOfIterations()) == 9 end @testset "Embedding LINK Test || AMP || special problem || ... " begin - test_solver=AlpineSolver(nlp_solver=IpoptSolver(print_level=0), - mip_solver=pavito_solver, - disc_abs_width_tol=1e-2, - disc_ratio=8, - maxiter=6, - presolve_bt=false, - presolve_bp=true, - presolve_bt_algo=1, - presolve_bt_output_tol=1e-1, - convhull_ebd=true, - convhull_ebd_link=true, - loglevel=100) + test_solver=optimizer_with_attributes(Alpine.Optimizer, "nlp_solver" => IPOPT, + "mip_solver" => PAVITO, + "disc_abs_width_tol" => 1e-2, + "disc_ratio" => 8, + "maxiter" => 6, + "presolve_bt" => false, + "presolve_bp" => true, + "presolve_bt_algo" => 1, + "presolve_bt_output_tol" => 1e-1, + "convhull_ebd" => true, + "convhull_ebd_link" => true, + "loglevel" => 100) m = circle(solver=test_solver) - solve(m) - @test isapprox(m.objVal, 1.4142135534556992; atol=1e-3) + optimize!(m) + @test isapprox(objective_value(m), 1.4142135534556992; atol=1e-3) end @testset "Algorithm Logic Test || castro4m2 || 1 iteration || Error case" begin - test_solver=AlpineSolver(nlp_solver=IpoptSolver(print_level=0), - mip_solver=CbcSolver(logLevel=0), - maxiter=1, - presolve_bt=false, - loglevel=100) + test_solver=optimizer_with_attributes(Alpine.Optimizer, "nlp_solver" => IPOPT, + "mip_solver" => CBC, + "maxiter" => 1, + "presolve_bt" => false, + "loglevel" => 100) m = castro4m2(solver=test_solver) - status = solve(m) - @test status == :UserLimits + JuMP.optimize!(m) + @test termination_status(m) == MOI.OTHER_LIMIT end @testset " Algorithm Logic Test || blend029_gl || 3 iterations || Infeasible Case" begin - test_solver=AlpineSolver(minlp_solver=pavito_solver, - nlp_solver=IpoptSolver(print_level=0), - mip_solver=CbcSolver(logLevel=0), - presolve_bp=true, - disc_var_pick=1, - loglevel=100, - maxiter=3, - presolve_bt_width_tol=1e-3, - presolve_bt=false) + test_solver=optimizer_with_attributes(Alpine.Optimizer, "minlp_solver" => PAVITO, + "nlp_solver" => IPOPT, + "mip_solver" => CBC, + "presolve_bp" => true, + "disc_var_pick" => 1, + "loglevel" => 100, + "maxiter" => 3, + "presolve_bt_width_tol" => 1e-3, + "presolve_bt" => false) m = blend029_gl(solver=test_solver) - status = solve(m) + JuMP.optimize!(m) - @test status == :UserLimits - @test m.internalModel.logs[:n_iter] == 3 - @test getobjbound(m) <= 14.0074 + @test termination_status(m) == MOI.OTHER_LIMIT + @test MOI.get(m, Alpine.NumberOfIterations()) == 3 + @test objective_bound(m) <= 14.0074 end @testset "Convex Model Solve" begin - test_solver=AlpineSolver(nlp_solver=IpoptSolver(print_level=0), - mip_solver=pavito_solver, - maxiter=1, - presolve_bt=false, - loglevel=100) + test_solver=optimizer_with_attributes(Alpine.Optimizer, "nlp_solver" => IPOPT, + "mip_solver" => PAVITO, + "maxiter" => 1, + "presolve_bt" => false, + "loglevel" => 100) m = convex_solve(solver=test_solver) - status = solve(m) - @test status == :Optimal + JuMP.optimize!(m) + @test termination_status(m) == MOI.OPTIMAL end @testset "Uniform partitioning" begin - test_solver=AlpineSolver(nlp_solver=IpoptSolver(print_level=0), - mip_solver=CbcSolver(logLevel=0), - disc_add_partition_method = "uniform", - disc_uniform_rate = 10, - maxiter=1, - presolve_bt=false, - timeout=100000, - loglevel=100) + test_solver=optimizer_with_attributes(Alpine.Optimizer, "nlp_solver" => IPOPT, + "mip_solver" => CBC, + "disc_add_partition_method" => "uniform", + "disc_uniform_rate" => 10, + "maxiter" => 1, + "presolve_bt" => false, + "timeout" => 100000, + "loglevel" => 100) m = nlp3(solver=test_solver) - solve(m) - @test isapprox(m.objBound, 6561.7156;atol=1e-3) + optimize!(m) + @test isapprox(objective_bound(m), 6561.7156;atol=1e-3) end @testset "Algorithm Test with binprod terms" begin - test_solver = AlpineSolver(minlp_solver=pavito_solver, - nlp_solver=IpoptSolver(print_level=0), - mip_solver=CbcSolver(logLevel=0), - bilinear_convexhull=true, - monomial_convexhull=true, - presolve_bp=true, - presolve_bt=false, - loglevel=100) + test_solver = optimizer_with_attributes(Alpine.Optimizer, "minlp_solver" => PAVITO, + "nlp_solver" => IPOPT, + "mip_solver" => CBC, + "bilinear_convexhull" => true, + "monomial_convexhull" => true, + "presolve_bp" => true, + "presolve_bt" => false, + "loglevel" => 100) m = binprod_nlp3(solver=test_solver) - status = solve(m) - - @test status == :Optimal - @test isapprox(m.objVal, 3651.020370626844;atol=1e-3) - @test isapprox(m.objBound, 3650.791316892635;atol=1e-3) - - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[4])]][:y_idx] == 19 - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[4])]][:id] == 6 - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[4])]][:lifted_constr_ref] == :(x[19] == x[2] * x[4]) - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[4])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[8])]][:y_idx] == 25 - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[8])]][:id] == 12 - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[8])]][:lifted_constr_ref] == :(x[25] == x[3] * x[8]) - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[8])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[5])]][:y_idx] == 22 - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[5])]][:id] == 9 - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[5])]][:lifted_constr_ref] == :(x[22] == x[3] * x[5]) - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[5])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[12]), :(x[19])]][:y_idx] == 20 - @test m.internalModel.nonconvex_terms[Expr[:(x[12]), :(x[19])]][:id] == 7 - @test m.internalModel.nonconvex_terms[Expr[:(x[12]), :(x[19])]][:lifted_constr_ref] == :(x[20] == x[12] * x[19]) - @test m.internalModel.nonconvex_terms[Expr[:(x[12]), :(x[19])]][:nonlinear_type] == :BINLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[9]), :(x[4])]][:y_idx] == 14 - @test m.internalModel.nonconvex_terms[Expr[:(x[9]), :(x[4])]][:id] == 1 - @test m.internalModel.nonconvex_terms[Expr[:(x[9]), :(x[4])]][:lifted_constr_ref] == :(x[14] == x[9] * x[4]) - @test m.internalModel.nonconvex_terms[Expr[:(x[9]), :(x[4])]][:nonlinear_type] == :BINLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[6])]][:y_idx] == 17 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[6])]][:id] == 4 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[6])]][:lifted_constr_ref] == :(x[17] == x[1] * x[6]) - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[6])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[11]), :(x[5])]][:y_idx] == 16 - @test m.internalModel.nonconvex_terms[Expr[:(x[11]), :(x[5])]][:id] == 3 - @test m.internalModel.nonconvex_terms[Expr[:(x[11]), :(x[5])]][:lifted_constr_ref] == :(x[16] == x[11] * x[5]) - @test m.internalModel.nonconvex_terms[Expr[:(x[11]), :(x[5])]][:nonlinear_type] == :BINLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[10]), :(x[11])]][:y_idx] == 30 - @test m.internalModel.nonconvex_terms[Expr[:(x[10]), :(x[11])]][:id] == 17 - @test m.internalModel.nonconvex_terms[Expr[:(x[10]), :(x[11])]][:lifted_constr_ref] == :(x[30] == x[10] * x[11]) - @test m.internalModel.nonconvex_terms[Expr[:(x[10]), :(x[11])]][:nonlinear_type] == :BINPROD - @test m.internalModel.nonconvex_terms[Expr[:(x[9]), :(x[10]), :(x[11])]][:y_idx] == 29 - @test m.internalModel.nonconvex_terms[Expr[:(x[9]), :(x[10]), :(x[11])]][:id] == 16 - @test m.internalModel.nonconvex_terms[Expr[:(x[9]), :(x[10]), :(x[11])]][:lifted_constr_ref] == :(x[29] == x[9] * x[10] * x[11]) - @test m.internalModel.nonconvex_terms[Expr[:(x[9]), :(x[10]), :(x[11])]][:nonlinear_type] == :BINPROD - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[7])]][:y_idx] == 21 - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[7])]][:id] == 8 - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[7])]][:lifted_constr_ref] == :(x[21] == x[2] * x[7]) - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[7])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[9]), :(x[13])]][:y_idx] == 32 - @test m.internalModel.nonconvex_terms[Expr[:(x[9]), :(x[13])]][:id] == 19 - @test m.internalModel.nonconvex_terms[Expr[:(x[9]), :(x[13])]][:lifted_constr_ref] == :(x[32] == x[9] * x[13]) - @test m.internalModel.nonconvex_terms[Expr[:(x[9]), :(x[13])]][:nonlinear_type] == :BINPROD - @test m.internalModel.nonconvex_terms[Expr[:(x[10]), :(x[6])]][:y_idx] == 15 - @test m.internalModel.nonconvex_terms[Expr[:(x[10]), :(x[6])]][:id] == 2 - @test m.internalModel.nonconvex_terms[Expr[:(x[10]), :(x[6])]][:lifted_constr_ref] == :(x[15] == x[10] * x[6]) - @test m.internalModel.nonconvex_terms[Expr[:(x[10]), :(x[6])]][:nonlinear_type] == :BINLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[10]), :(x[12])]][:y_idx] == 33 - @test m.internalModel.nonconvex_terms[Expr[:(x[10]), :(x[12])]][:id] == 20 - @test m.internalModel.nonconvex_terms[Expr[:(x[10]), :(x[12])]][:lifted_constr_ref] == :(x[33] == x[10] * x[12]) - @test m.internalModel.nonconvex_terms[Expr[:(x[10]), :(x[12])]][:nonlinear_type] == :BINPROD - @test m.internalModel.nonconvex_terms[Expr[:(x[27]), :(x[5])]][:y_idx] == 28 - @test m.internalModel.nonconvex_terms[Expr[:(x[27]), :(x[5])]][:id] == 15 - @test m.internalModel.nonconvex_terms[Expr[:(x[27]), :(x[5])]][:lifted_constr_ref] == :(x[28] == x[27] * x[5]) - @test m.internalModel.nonconvex_terms[Expr[:(x[27]), :(x[5])]][:nonlinear_type] == :BINLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[13]), :(x[25])]][:y_idx] == 26 - @test m.internalModel.nonconvex_terms[Expr[:(x[13]), :(x[25])]][:id] == 13 - @test m.internalModel.nonconvex_terms[Expr[:(x[13]), :(x[25])]][:lifted_constr_ref] == :(x[26] == x[13] * x[25]) - @test m.internalModel.nonconvex_terms[Expr[:(x[13]), :(x[25])]][:nonlinear_type] == :BINLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[9]), :(x[12])]][:y_idx] == 27 - @test m.internalModel.nonconvex_terms[Expr[:(x[9]), :(x[12])]][:id] == 14 - @test m.internalModel.nonconvex_terms[Expr[:(x[9]), :(x[12])]][:lifted_constr_ref] == :(x[27] == x[9] * x[12]) - @test m.internalModel.nonconvex_terms[Expr[:(x[9]), :(x[12])]][:nonlinear_type] == :BINPROD - @test m.internalModel.nonconvex_terms[Expr[:(x[10]), :(x[13])]][:y_idx] == 23 - @test m.internalModel.nonconvex_terms[Expr[:(x[10]), :(x[13])]][:id] == 10 - @test m.internalModel.nonconvex_terms[Expr[:(x[10]), :(x[13])]][:lifted_constr_ref] == :(x[23] == x[10] * x[13]) - @test m.internalModel.nonconvex_terms[Expr[:(x[10]), :(x[13])]][:nonlinear_type] == :BINPROD - @test m.internalModel.nonconvex_terms[Expr[:(x[23]), :(x[22])]][:y_idx] == 24 - @test m.internalModel.nonconvex_terms[Expr[:(x[23]), :(x[22])]][:id] == 11 - @test m.internalModel.nonconvex_terms[Expr[:(x[23]), :(x[22])]][:lifted_constr_ref] == :(x[24] == x[23] * x[22]) - @test m.internalModel.nonconvex_terms[Expr[:(x[23]), :(x[22])]][:nonlinear_type] == :BINLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[12]), :(x[13])]][:y_idx] == 31 - @test m.internalModel.nonconvex_terms[Expr[:(x[12]), :(x[13])]][:id] == 18 - @test m.internalModel.nonconvex_terms[Expr[:(x[12]), :(x[13])]][:lifted_constr_ref] == :(x[31] == x[12] * x[13]) - @test m.internalModel.nonconvex_terms[Expr[:(x[12]), :(x[13])]][:nonlinear_type] == :BINPROD - @test m.internalModel.nonconvex_terms[Expr[:(x[9]), :(x[17])]][:y_idx] == 18 - @test m.internalModel.nonconvex_terms[Expr[:(x[9]), :(x[17])]][:id] == 5 - @test m.internalModel.nonconvex_terms[Expr[:(x[9]), :(x[17])]][:lifted_constr_ref] == :(x[18] == x[9] * x[17]) - @test m.internalModel.nonconvex_terms[Expr[:(x[9]), :(x[17])]][:nonlinear_type] == :BINLIN - @test m.internalModel.bounding_constr_mip[1][:rhs] == 1.0 - @test m.internalModel.bounding_constr_mip[1][:vars] == Any[:(x[14]), :(x[15])] - @test m.internalModel.bounding_constr_mip[1][:coefs] == Any[0.0025, 0.0025] - @test m.internalModel.bounding_constr_mip[1][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[1][:cnt] == 2 - @test m.internalModel.bounding_constr_mip[2][:rhs] == 1.0 - @test m.internalModel.bounding_constr_mip[2][:vars] == Any[:(x[14]), :(x[5]), :(x[7])] - @test m.internalModel.bounding_constr_mip[2][:coefs] == Any[-0.0025, 0.0025, 0.0025] - @test m.internalModel.bounding_constr_mip[2][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[2][:cnt] == 3 - @test m.internalModel.bounding_constr_mip[3][:rhs] == 1.0 - @test m.internalModel.bounding_constr_mip[3][:vars] == Any[:(x[16]), :(x[8])] - @test m.internalModel.bounding_constr_mip[3][:coefs] == Any[-0.01, 0.01] - @test m.internalModel.bounding_constr_mip[3][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[3][:cnt] == 2 - @test m.internalModel.bounding_constr_mip[4][:rhs] == 83333.333 - @test m.internalModel.bounding_constr_mip[4][:vars] == Any[:(x[1]), :(x[18]), :(x[14])] - @test m.internalModel.bounding_constr_mip[4][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[4][:cnt] == 3 - @test m.internalModel.bounding_constr_mip[5][:rhs] == 0.0 - @test m.internalModel.bounding_constr_mip[5][:vars] == Any[:(x[20]), :(x[21]), :(x[4]), :(x[5])] - @test m.internalModel.bounding_constr_mip[5][:coefs] == Any[1.0, -1.0, -1250.0, 1250.0] - @test m.internalModel.bounding_constr_mip[5][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[5][:cnt] == 4 - @test m.internalModel.bounding_constr_mip[6][:rhs] == -1.25e6 - @test m.internalModel.bounding_constr_mip[6][:vars] == Any[:(x[24]), :(x[26]), :(x[28])] - @test m.internalModel.bounding_constr_mip[6][:coefs] == Any[1.0, -1.0, -2500.0] - @test m.internalModel.bounding_constr_mip[6][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[6][:cnt] == 3 - @test m.internalModel.bounding_constr_mip[7][:rhs] == 0.0 - @test m.internalModel.bounding_constr_mip[7][:vars] == Any[:(x[29])] - @test m.internalModel.bounding_constr_mip[7][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[7][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[7][:cnt] == 1 - @test m.internalModel.bounding_constr_mip[8][:rhs] == 0.0 - @test m.internalModel.bounding_constr_mip[8][:vars] == Any[:(x[30]), :(x[31])] - @test m.internalModel.bounding_constr_mip[8][:coefs] == Any[1.0, -1.0] - @test m.internalModel.bounding_constr_mip[8][:sense] == :(>=) - @test m.internalModel.bounding_constr_mip[8][:cnt] == 2 - @test m.internalModel.bounding_constr_mip[9][:rhs] == 0.0 - @test m.internalModel.bounding_constr_mip[9][:vars] == Any[:(x[32]), :(x[33])] - @test m.internalModel.bounding_constr_mip[9][:coefs] == Any[1.0, -1.0] - @test m.internalModel.bounding_constr_mip[9][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[9][:cnt] == 2 + JuMP.optimize!(m) + + @test termination_status(m) == MOI.OPTIMAL + @test isapprox(objective_value(m), 3651.020370626844;atol=1e-3) + @test isapprox(objective_bound(m), 3650.791316892635;atol=1e-3) + + alpine = JuMP.backend(m).optimizer.model + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[4])]][:y_idx] == 19 + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[4])]][:id] == 6 + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[4])]][:lifted_constr_ref] == :(x[19] == x[2] * x[4]) + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[4])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[8])]][:y_idx] == 25 + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[8])]][:id] == 12 + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[8])]][:lifted_constr_ref] == :(x[25] == x[3] * x[8]) + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[8])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[5])]][:y_idx] == 22 + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[5])]][:id] == 9 + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[5])]][:lifted_constr_ref] == :(x[22] == x[3] * x[5]) + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[5])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[12]), :(x[19])]][:y_idx] == 20 + @test alpine.nonconvex_terms[Expr[:(x[12]), :(x[19])]][:id] == 7 + @test alpine.nonconvex_terms[Expr[:(x[12]), :(x[19])]][:lifted_constr_ref] == :(x[20] == x[12] * x[19]) + @test alpine.nonconvex_terms[Expr[:(x[12]), :(x[19])]][:nonlinear_type] == :BINLIN + @test alpine.nonconvex_terms[Expr[:(x[9]), :(x[4])]][:y_idx] == 14 + @test alpine.nonconvex_terms[Expr[:(x[9]), :(x[4])]][:id] == 1 + @test alpine.nonconvex_terms[Expr[:(x[9]), :(x[4])]][:lifted_constr_ref] == :(x[14] == x[9] * x[4]) + @test alpine.nonconvex_terms[Expr[:(x[9]), :(x[4])]][:nonlinear_type] == :BINLIN + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[6])]][:y_idx] == 17 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[6])]][:id] == 4 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[6])]][:lifted_constr_ref] == :(x[17] == x[1] * x[6]) + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[6])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[11]), :(x[5])]][:y_idx] == 16 + @test alpine.nonconvex_terms[Expr[:(x[11]), :(x[5])]][:id] == 3 + @test alpine.nonconvex_terms[Expr[:(x[11]), :(x[5])]][:lifted_constr_ref] == :(x[16] == x[11] * x[5]) + @test alpine.nonconvex_terms[Expr[:(x[11]), :(x[5])]][:nonlinear_type] == :BINLIN + @test alpine.nonconvex_terms[Expr[:(x[10]), :(x[11])]][:y_idx] == 30 + @test alpine.nonconvex_terms[Expr[:(x[10]), :(x[11])]][:id] == 17 + @test alpine.nonconvex_terms[Expr[:(x[10]), :(x[11])]][:lifted_constr_ref] == :(x[30] == x[10] * x[11]) + @test alpine.nonconvex_terms[Expr[:(x[10]), :(x[11])]][:nonlinear_type] == :BINPROD + @test alpine.nonconvex_terms[Expr[:(x[9]), :(x[10]), :(x[11])]][:y_idx] == 29 + @test alpine.nonconvex_terms[Expr[:(x[9]), :(x[10]), :(x[11])]][:id] == 16 + @test alpine.nonconvex_terms[Expr[:(x[9]), :(x[10]), :(x[11])]][:lifted_constr_ref] == :(x[29] == x[9] * x[10] * x[11]) + @test alpine.nonconvex_terms[Expr[:(x[9]), :(x[10]), :(x[11])]][:nonlinear_type] == :BINPROD + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[7])]][:y_idx] == 21 + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[7])]][:id] == 8 + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[7])]][:lifted_constr_ref] == :(x[21] == x[2] * x[7]) + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[7])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[9]), :(x[13])]][:y_idx] == 32 + @test alpine.nonconvex_terms[Expr[:(x[9]), :(x[13])]][:id] == 19 + @test alpine.nonconvex_terms[Expr[:(x[9]), :(x[13])]][:lifted_constr_ref] == :(x[32] == x[9] * x[13]) + @test alpine.nonconvex_terms[Expr[:(x[9]), :(x[13])]][:nonlinear_type] == :BINPROD + @test alpine.nonconvex_terms[Expr[:(x[10]), :(x[6])]][:y_idx] == 15 + @test alpine.nonconvex_terms[Expr[:(x[10]), :(x[6])]][:id] == 2 + @test alpine.nonconvex_terms[Expr[:(x[10]), :(x[6])]][:lifted_constr_ref] == :(x[15] == x[10] * x[6]) + @test alpine.nonconvex_terms[Expr[:(x[10]), :(x[6])]][:nonlinear_type] == :BINLIN + @test alpine.nonconvex_terms[Expr[:(x[10]), :(x[12])]][:y_idx] == 33 + @test alpine.nonconvex_terms[Expr[:(x[10]), :(x[12])]][:id] == 20 + @test alpine.nonconvex_terms[Expr[:(x[10]), :(x[12])]][:lifted_constr_ref] == :(x[33] == x[10] * x[12]) + @test alpine.nonconvex_terms[Expr[:(x[10]), :(x[12])]][:nonlinear_type] == :BINPROD + @test alpine.nonconvex_terms[Expr[:(x[27]), :(x[5])]][:y_idx] == 28 + @test alpine.nonconvex_terms[Expr[:(x[27]), :(x[5])]][:id] == 15 + @test alpine.nonconvex_terms[Expr[:(x[27]), :(x[5])]][:lifted_constr_ref] == :(x[28] == x[27] * x[5]) + @test alpine.nonconvex_terms[Expr[:(x[27]), :(x[5])]][:nonlinear_type] == :BINLIN + @test alpine.nonconvex_terms[Expr[:(x[13]), :(x[25])]][:y_idx] == 26 + @test alpine.nonconvex_terms[Expr[:(x[13]), :(x[25])]][:id] == 13 + @test alpine.nonconvex_terms[Expr[:(x[13]), :(x[25])]][:lifted_constr_ref] == :(x[26] == x[13] * x[25]) + @test alpine.nonconvex_terms[Expr[:(x[13]), :(x[25])]][:nonlinear_type] == :BINLIN + @test alpine.nonconvex_terms[Expr[:(x[9]), :(x[12])]][:y_idx] == 27 + @test alpine.nonconvex_terms[Expr[:(x[9]), :(x[12])]][:id] == 14 + @test alpine.nonconvex_terms[Expr[:(x[9]), :(x[12])]][:lifted_constr_ref] == :(x[27] == x[9] * x[12]) + @test alpine.nonconvex_terms[Expr[:(x[9]), :(x[12])]][:nonlinear_type] == :BINPROD + @test alpine.nonconvex_terms[Expr[:(x[10]), :(x[13])]][:y_idx] == 23 + @test alpine.nonconvex_terms[Expr[:(x[10]), :(x[13])]][:id] == 10 + @test alpine.nonconvex_terms[Expr[:(x[10]), :(x[13])]][:lifted_constr_ref] == :(x[23] == x[10] * x[13]) + @test alpine.nonconvex_terms[Expr[:(x[10]), :(x[13])]][:nonlinear_type] == :BINPROD + @test alpine.nonconvex_terms[Expr[:(x[23]), :(x[22])]][:y_idx] == 24 + @test alpine.nonconvex_terms[Expr[:(x[23]), :(x[22])]][:id] == 11 + @test alpine.nonconvex_terms[Expr[:(x[23]), :(x[22])]][:lifted_constr_ref] == :(x[24] == x[23] * x[22]) + @test alpine.nonconvex_terms[Expr[:(x[23]), :(x[22])]][:nonlinear_type] == :BINLIN + @test alpine.nonconvex_terms[Expr[:(x[12]), :(x[13])]][:y_idx] == 31 + @test alpine.nonconvex_terms[Expr[:(x[12]), :(x[13])]][:id] == 18 + @test alpine.nonconvex_terms[Expr[:(x[12]), :(x[13])]][:lifted_constr_ref] == :(x[31] == x[12] * x[13]) + @test alpine.nonconvex_terms[Expr[:(x[12]), :(x[13])]][:nonlinear_type] == :BINPROD + @test alpine.nonconvex_terms[Expr[:(x[9]), :(x[17])]][:y_idx] == 18 + @test alpine.nonconvex_terms[Expr[:(x[9]), :(x[17])]][:id] == 5 + @test alpine.nonconvex_terms[Expr[:(x[9]), :(x[17])]][:lifted_constr_ref] == :(x[18] == x[9] * x[17]) + @test alpine.nonconvex_terms[Expr[:(x[9]), :(x[17])]][:nonlinear_type] == :BINLIN + @test alpine.bounding_constr_mip[1][:rhs] == 1.0 + @test alpine.bounding_constr_mip[1][:vars] == Any[:(x[14]), :(x[15])] + @test alpine.bounding_constr_mip[1][:coefs] == Any[0.0025, 0.0025] + @test alpine.bounding_constr_mip[1][:sense] == :(<=) + @test alpine.bounding_constr_mip[1][:cnt] == 2 + @test alpine.bounding_constr_mip[2][:rhs] == 1.0 + @test alpine.bounding_constr_mip[2][:vars] == Any[:(x[14]), :(x[5]), :(x[7])] + @test alpine.bounding_constr_mip[2][:coefs] == Any[-0.0025, 0.0025, 0.0025] + @test alpine.bounding_constr_mip[2][:sense] == :(<=) + @test alpine.bounding_constr_mip[2][:cnt] == 3 + @test alpine.bounding_constr_mip[3][:rhs] == 1.0 + @test alpine.bounding_constr_mip[3][:vars] == Any[:(x[16]), :(x[8])] + @test alpine.bounding_constr_mip[3][:coefs] == Any[-0.01, 0.01] + @test alpine.bounding_constr_mip[3][:sense] == :(<=) + @test alpine.bounding_constr_mip[3][:cnt] == 2 + @test alpine.bounding_constr_mip[4][:rhs] == 83333.333 + @test alpine.bounding_constr_mip[4][:vars] == Any[:(x[1]), :(x[18]), :(x[14])] + @test alpine.bounding_constr_mip[4][:sense] == :(<=) + @test alpine.bounding_constr_mip[4][:cnt] == 3 + @test alpine.bounding_constr_mip[5][:rhs] == 0.0 + @test alpine.bounding_constr_mip[5][:vars] == Any[:(x[20]), :(x[21]), :(x[4]), :(x[5])] + @test alpine.bounding_constr_mip[5][:coefs] == Any[1.0, -1.0, -1250.0, 1250.0] + @test alpine.bounding_constr_mip[5][:sense] == :(<=) + @test alpine.bounding_constr_mip[5][:cnt] == 4 + @test alpine.bounding_constr_mip[6][:rhs] == -1.25e6 + @test alpine.bounding_constr_mip[6][:vars] == Any[:(x[24]), :(x[26]), :(x[28])] + @test alpine.bounding_constr_mip[6][:coefs] == Any[1.0, -1.0, -2500.0] + @test alpine.bounding_constr_mip[6][:sense] == :(<=) + @test alpine.bounding_constr_mip[6][:cnt] == 3 + @test alpine.bounding_constr_mip[7][:rhs] == 0.0 + @test alpine.bounding_constr_mip[7][:vars] == Any[:(x[29])] + @test alpine.bounding_constr_mip[7][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[7][:sense] == :(<=) + @test alpine.bounding_constr_mip[7][:cnt] == 1 + @test alpine.bounding_constr_mip[8][:rhs] == 0.0 + @test alpine.bounding_constr_mip[8][:vars] == Any[:(x[30]), :(x[31])] + @test alpine.bounding_constr_mip[8][:coefs] == Any[1.0, -1.0] + @test alpine.bounding_constr_mip[8][:sense] == :(>=) + @test alpine.bounding_constr_mip[8][:cnt] == 2 + @test alpine.bounding_constr_mip[9][:rhs] == 0.0 + @test alpine.bounding_constr_mip[9][:vars] == Any[:(x[32]), :(x[33])] + @test alpine.bounding_constr_mip[9][:coefs] == Any[1.0, -1.0] + @test alpine.bounding_constr_mip[9][:sense] == :(<=) + @test alpine.bounding_constr_mip[9][:cnt] == 2 end diff --git a/test/examples/blend.jl b/test/examples/blend.jl index 53f08cf4..c225fd0f 100644 --- a/test/examples/blend.jl +++ b/test/examples/blend.jl @@ -1,19 +1,19 @@ function blend029(;solver=nothing) - m = Model(solver=solver) + m = Model(solver) @variable(m, x[1:102]) for i=67:102 - setcategory(x[i], :Bin) + set_binary(x[i]) end for i=1:48 - setlowerbound(x[i], 0) - setupperbound(x[i], 1) + set_lower_bound(x[i], 0) + set_upper_bound(x[i], 1) end for i=49:66 - setlowerbound(x[i], 0) - setupperbound(x[i], 2) + set_lower_bound(x[i], 0) + set_upper_bound(x[i], 2) end @objective(m, Max, - 1.74*x[1] - 1.74*x[2] - 1.74*x[3] - 1.45*x[4] - 1.45*x[5] - 1.45*x[6] + 7.38*x[7] + 7.38*x[8] + 7.38*x[9] + 5.6*x[10] + 5.6*x[11] + 5.6*x[12] - 1.7*x[13] - 1.7*x[14] - 1.7*x[15] - 1.18*x[16] - 1.18*x[17] - 1.18*x[18] + 7.21*x[19] + 7.21*x[20] + 7.21*x[21] + 5.45*x[22] + 5.45*x[23] + 5.45*x[24] - 0.3*x[25] - 0.3*x[26] - 0.3*x[27] + 7.71*x[28] + 7.71*x[29] + 7.71*x[30] + 6.28*x[31] + 6.28*x[32] + 6.28*x[33] + 7.74*x[34] + 7.74*x[35] + 7.74*x[36] - 0.84*x[67] - 0.84*x[68] - 0.84*x[69] - 0.05*x[70] - 0.05*x[71] - 0.05*x[72] - 0.94*x[73] - 0.94*x[74] - 0.94*x[75] - 0.81*x[76] - 0.81*x[77] - 0.81*x[78] - 0.79*x[79] - 0.79*x[80] - 0.79*x[81] - 0.05*x[82] - 0.05*x[83] - 0.05*x[84] - 0.65*x[85] - 0.65*x[86] - 0.65*x[87] - 0.97*x[88] - 0.97*x[89] - 0.97*x[90] - 0.57*x[91] - 0.57*x[92] - 0.57*x[93] - 0.26*x[94] - 0.26*x[95] - 0.26*x[96] - 0.45*x[97] - 0.45*x[98] - 0.45*x[99] - 0.1*x[100] - 0.1*x[101] - 0.1*x[102]) @@ -238,20 +238,20 @@ end function blend029_gl(;solver=nothing) - m = Model(solver=solver) + m = Model(solver) @variable(m, x[1:102]) for i=67:102 - setcategory(x[i], :Bin) + JuMP.set_binary(x[i]) end for i=1:48 - setlowerbound(x[i], 0) - setupperbound(x[i], 1) + set_lower_bound(x[i], 0) + set_upper_bound(x[i], 1) end for i=49:66 - setlowerbound(x[i], 0) - setupperbound(x[i], 2) + set_lower_bound(x[i], 0) + set_upper_bound(x[i], 2) end @objective(m, Max, - 1.74*x[1] - 1.74*x[2] - 1.74*x[3] - 1.45*x[4] - 1.45*x[5] - 1.45*x[6] + 7.38*x[7] + 7.38*x[8] + 7.38*x[9] + 5.6*x[10] + 5.6*x[11] + 5.6*x[12] - 1.7*x[13] - 1.7*x[14] - 1.7*x[15] - 1.18*x[16] - 1.18*x[17] - 1.18*x[18] + 7.21*x[19] + 7.21*x[20] + 7.21*x[21] + 5.45*x[22] + 5.45*x[23] + 5.45*x[24] - 0.3*x[25] - 0.3*x[26] - 0.3*x[27] + 7.71*x[28] + 7.71*x[29] + 7.71*x[30] + 6.28*x[31] + 6.28*x[32] + 6.28*x[33] + 7.74*x[34] + 7.74*x[35] + 7.74*x[36] - 0.84*x[67] - 0.84*x[68] - 0.84*x[69] - 0.05*x[70] - 0.05*x[71] - 0.05*x[72] - 0.94*x[73] - 0.94*x[74] - 0.94*x[75] - 0.81*x[76] - 0.81*x[77] - 0.81*x[78] - 0.79*x[79] - 0.79*x[80] - 0.79*x[81] - 0.05*x[82] - 0.05*x[83] - 0.05*x[84] - 0.65*x[85] - 0.65*x[86] - 0.65*x[87] - 0.97*x[88] - 0.97*x[89] - 0.97*x[90] - 0.57*x[91] - 0.57*x[92] - 0.57*x[93] - 0.26*x[94] - 0.26*x[95] - 0.26*x[96] - 0.45*x[97] - 0.45*x[98] - 0.45*x[99] - 0.1*x[100] - 0.1*x[101] - 0.1*x[102]) diff --git a/test/examples/brainpc3.jl b/test/examples/brainpc3.jl index ab1d6270..657d92cb 100644 --- a/test/examples/brainpc3.jl +++ b/test/examples/brainpc3.jl @@ -1,6 +1,6 @@ function brainpc3(;solver=nothing) - m = Model(solver=solver) + m = Model(solver) # ----- Variables ----- # @variable(m, x[1:6907]) diff --git a/test/examples/castro.jl b/test/examples/castro.jl index 80d39f93..aa002f09 100644 --- a/test/examples/castro.jl +++ b/test/examples/castro.jl @@ -1,6 +1,6 @@ function castro2m2(;solver=nothing) - m = Model(solver=solver) + m = Model(solver) @variable(m, 0 <= x[1:41] <= 1E6) @variable(m, obj) @@ -58,7 +58,7 @@ end function castro6m2(;solver=nothing) - m = Model(solver=solver) + m = Model(solver) @variable(m, 0 <= x[1:133] <= 1E6) @variable(m, obj) @@ -225,7 +225,7 @@ end function castro4m2(;solver=nothing) - m = Model(solver=solver) + m = Model(solver) # ----- Variables ----- # @variable(m, 0 <= x[1:55] <= 1E6) diff --git a/test/examples/circle.jl b/test/examples/circle.jl index 02d962c8..86633ded 100644 --- a/test/examples/circle.jl +++ b/test/examples/circle.jl @@ -1,6 +1,6 @@ function circle(;solver=nothing) - m = Model(solver=solver) + m = Model(solver) @variable(m, 0<=x[1:2]<=2) @NLconstraint(m, x[1]^2 + x[2]^2 >= 2) @@ -11,7 +11,7 @@ end function circleN(;solver=nothing, N=2) - m = Model(solver=solver) + m = Model(solver) @variable(m, 0<=x[1:N]<=N) @NLconstraint(m, sum(x[i]^2 for i in 1:N) >= N) diff --git a/test/examples/convex.jl b/test/examples/convex.jl index 0da73212..3228e23b 100644 --- a/test/examples/convex.jl +++ b/test/examples/convex.jl @@ -1,6 +1,6 @@ function convex_test(solver=nothing) - m = Model(solver=solver) + m = Model(solver) @variable(m, 0<=x[1:5]<=2) @@ -47,7 +47,7 @@ end function convex_solve(;solver=nothing) - m = Model(solver=solver) + m = Model(solver) @variable(m, 0<=x[1:5]<=100) diff --git a/test/examples/discretemulti.jl b/test/examples/discretemulti.jl index 40465f02..a88019b0 100644 --- a/test/examples/discretemulti.jl +++ b/test/examples/discretemulti.jl @@ -1,27 +1,27 @@ function binprod_nlp3(;solver=nothing) - m = Model(solver=solver) + m = Model(solver) @variable(m, x[1:8]) @variable(m, y[1:5], Bin) - setlowerbound(x[1], 100) - setlowerbound(x[2], 1000) - setlowerbound(x[3], 1000) - setlowerbound(x[4], 10) - setlowerbound(x[5], 10) - setlowerbound(x[6], 10) - setlowerbound(x[7], 10) - setlowerbound(x[8], 10) - - setupperbound(x[1], 10000) - setupperbound(x[2], 10000) - setupperbound(x[3], 10000) - setupperbound(x[4], 1000) - setupperbound(x[5], 1000) - setupperbound(x[6], 1000) - setupperbound(x[7], 1000) - setupperbound(x[8], 1000) + JuMP.set_lower_bound(x[1], 100) + JuMP.set_lower_bound(x[2], 1000) + JuMP.set_lower_bound(x[3], 1000) + JuMP.set_lower_bound(x[4], 10) + JuMP.set_lower_bound(x[5], 10) + JuMP.set_lower_bound(x[6], 10) + JuMP.set_lower_bound(x[7], 10) + JuMP.set_lower_bound(x[8], 10) + + JuMP.set_upper_bound(x[1], 10000) + JuMP.set_upper_bound(x[2], 10000) + JuMP.set_upper_bound(x[3], 10000) + JuMP.set_upper_bound(x[4], 1000) + JuMP.set_upper_bound(x[5], 1000) + JuMP.set_upper_bound(x[6], 1000) + JuMP.set_upper_bound(x[7], 1000) + JuMP.set_upper_bound(x[8], 1000) @constraint(m, 0.0025*(x[4]*y[1] + x[6]*y[2]) <= 1) @constraint(m, 0.0025*(x[5] - x[4]*y[1] + x[7]) <= 1) @@ -41,7 +41,7 @@ end function circlebin(;verbose=false, solver=nothing) - m = Model(solver=solver) + m = Model(solver) @variable(m, x[1:5], Bin) @NLconstraint(m, x[1]^2 + x[2]^2 >= 2) @@ -52,7 +52,7 @@ end function bpml(;verbose=false, solver=nothing) - m = Model(solver=solver) + m = Model(solver) @variable(m, x[1:5], Bin) @variable(m, y[1:5]>=0) @@ -73,7 +73,7 @@ end function bmpl_linearlifting(;solver=nothing) - m = Model(solver=solver) + m = Model(solver) @variable(m, x[1:5], Bin) @variable(m, y[1:5]>=0) @@ -89,7 +89,7 @@ end function bpml_lnl(solver=nothing) - m = Model(solver=solver) + m = Model(solver) Random.seed!(10) @variable(m, X[1:5], Bin) @@ -102,7 +102,7 @@ end function bpml_binl(solver=nothing) - m = Model(solver=solver) + m = Model(solver) Random.seed!(10) @variable(m, X[1:5], Bin) @@ -115,7 +115,7 @@ end function bpml_monl(solver=nothing) - m = Model(solver=solver) + m = Model(solver) Random.seed!(10) @variable(m, X[1:5], Bin) @@ -128,16 +128,16 @@ end function bpml_negative(solver=nothing) - m = Model(solver=solver) + m = Model(solver) Random.seed!(10) @variable(m, X[1:5], Bin) @variable(m, 50<=Y[1:5]<=50+100*rand()*rand()) - setlowerbound(Y[1], -10) - setupperbound(Y[1], -1) - setlowerbound(Y[2], -40) - setlowerbound(Y[3], -30) - setlowerbound(Y[4], -50) + JuMP.set_lower_bound(Y[1], -10) + JuMP.set_upper_bound(Y[1], -1) + JuMP.set_lower_bound(Y[2], -40) + JuMP.set_lower_bound(Y[3], -30) + JuMP.set_lower_bound(Y[4], -50) @constraint(m, sum(X) >= 3) @NLobjective(m, Max, sum(X[i]*Y[i]*Y[i+1] for i in 1:4) - X[5]*Y[5]*Y[1]) @@ -145,7 +145,7 @@ function bpml_negative(solver=nothing) end function intprod_basic(;solver=nothing) - m = Model(solver=solver) + m = Model(solver) @variable(m, 1 <= Z[1:10] <= 10, Int) @NLconstraint(m, (Z[1]+Z[2])*(Z[3]+Z[4]) >= 25) @@ -159,7 +159,7 @@ end function discretemulti_basic(;solver=nothing) - m = Model(solver=solver) + m = Model(solver) Random.seed!(10) @variable(m, X[1:5], Bin) diff --git a/test/examples/div.jl b/test/examples/div.jl index 2ddc8b30..926d8e4c 100644 --- a/test/examples/div.jl +++ b/test/examples/div.jl @@ -1,6 +1,6 @@ function div(;verbose=false,solver=nothing) - m = Model(solver=solver) + m = Model(solver) @variable(m, 1<=x[1:2]<=10) diff --git a/test/examples/exprstest.jl b/test/examples/exprstest.jl index d4ea2c3f..d28b1aad 100644 --- a/test/examples/exprstest.jl +++ b/test/examples/exprstest.jl @@ -1,6 +1,6 @@ function exprstest(;solver=nothing) - m = Model(solver=solver) + m = Model(solver) @variable(m, px[i=1:6]>=1) # At some point if an initial value is given, keep them @@ -21,7 +21,7 @@ end function operator_b(;solver=nothing) - m = Model(solver=solver) + m = Model(solver) @variable(m, x[1:4]>=0) @variable(m, y[1:3]<=0) @@ -66,7 +66,7 @@ end function operator_basic(;solver=nothing) - m = Model(solver=solver) + m = Model(solver) @variable(m, x[1:4]>=0) @@ -169,7 +169,7 @@ end function operator_c(;solver=nothing) - m = Model(solver=solver) + m = Model(solver) @variable(m, px[i=1:6]>=1) # At some point if an initial value is given, keep them diff --git a/test/examples/integer.jl b/test/examples/integer.jl index ed28bf27..57888bf1 100644 --- a/test/examples/integer.jl +++ b/test/examples/integer.jl @@ -1,6 +1,6 @@ function ex1225a(;solver=nothing) - m = Model(solver=solver) + m = Model(solver) # ----- Variables ----- # @variable(m, objvar) @@ -10,63 +10,63 @@ function ex1225a(;solver=nothing) @variable(m, b[b_Idx]) i_Idx = Any[16, 17, 18, 19, 20, 21] @variable(m, i[i_Idx]) - setcategory(i[21], :Int) - setlowerbound(i[21], 0.0) - setupperbound(i[21], 100.0) - setlowerbound(x[4], 0.0) - setlowerbound(x[6], 0.0) - setlowerbound(x[14], 0.0) - setlowerbound(x[3], 0.0) - setcategory(i[19], :Int) - setlowerbound(i[19], 0.0) - setupperbound(i[19], 100.0) - setlowerbound(x[11], 0.0) - setlowerbound(x[12], 0.0) - setlowerbound(x[5], 0.0) - setlowerbound(x[2], 0.0) - setcategory(b[24], :Bin) - setcategory(i[16], :Int) - setlowerbound(i[16], 0.0) - setupperbound(i[16], 100.0) - setcategory(b[23], :Bin) - setcategory(i[17], :Int) - setlowerbound(i[17], 0.0) - setupperbound(i[17], 100.0) - setlowerbound(x[9], 0.0) - setlowerbound(x[15], 0.0) - setlowerbound(x[1], 0.0) - setlowerbound(x[7], 0.0) - setlowerbound(x[8], 0.0) - setlowerbound(x[13], 0.0) - setcategory(i[20], :Int) - setlowerbound(i[20], 0.0) - setupperbound(i[20], 100.0) - setlowerbound(x[10], 0.0) - setcategory(i[18], :Int) - setlowerbound(i[18], 0.0) - setupperbound(i[18], 100.0) - setcategory(b[22], :Bin) - setupperbound(x[1], 80.0) - setupperbound(x[2], 25.0) - setupperbound(x[3], 45.0) - setupperbound(x[4], 2950.0) - setupperbound(x[5], 2950.0) - setupperbound(x[6], 2950.0) - setupperbound(x[7], 400.0) - setupperbound(x[8], 400.0) - setupperbound(x[9], 400.0) - setupperbound(x[10], 350.0) - setupperbound(x[11], 350.0) - setupperbound(x[12], 350.0) - setupperbound(x[13], 1.0) - setupperbound(x[14], 1.0) - setupperbound(x[15], 1.0) - setupperbound(i[16], 3.0) - setupperbound(i[17], 3.0) - setupperbound(i[18], 3.0) - setupperbound(i[19], 3.0) - setupperbound(i[20], 3.0) - setupperbound(i[21], 3.0) + JuMP.set_integer(i[21]) + JuMP.set_lower_bound(i[21], 0.0) + JuMP.set_upper_bound(i[21], 100.0) + JuMP.set_lower_bound(x[4], 0.0) + JuMP.set_lower_bound(x[6], 0.0) + JuMP.set_lower_bound(x[14], 0.0) + JuMP.set_lower_bound(x[3], 0.0) + JuMP.set_integer(i[19]) + JuMP.set_lower_bound(i[19], 0.0) + JuMP.set_upper_bound(i[19], 100.0) + JuMP.set_lower_bound(x[11], 0.0) + JuMP.set_lower_bound(x[12], 0.0) + JuMP.set_lower_bound(x[5], 0.0) + JuMP.set_lower_bound(x[2], 0.0) + JuMP.set_binary(b[24]) + JuMP.set_integer(i[16]) + JuMP.set_lower_bound(i[16], 0.0) + JuMP.set_upper_bound(i[16], 100.0) + JuMP.set_binary(b[23]) + JuMP.set_integer(i[17]) + JuMP.set_lower_bound(i[17], 0.0) + JuMP.set_upper_bound(i[17], 100.0) + JuMP.set_lower_bound(x[9], 0.0) + JuMP.set_lower_bound(x[15], 0.0) + JuMP.set_lower_bound(x[1], 0.0) + JuMP.set_lower_bound(x[7], 0.0) + JuMP.set_lower_bound(x[8], 0.0) + JuMP.set_lower_bound(x[13], 0.0) + JuMP.set_integer(i[20]) + JuMP.set_lower_bound(i[20], 0.0) + JuMP.set_upper_bound(i[20], 100.0) + JuMP.set_lower_bound(x[10], 0.0) + JuMP.set_integer(i[18]) + JuMP.set_lower_bound(i[18], 0.0) + JuMP.set_upper_bound(i[18], 100.0) + JuMP.set_binary(b[22]) + JuMP.set_upper_bound(x[1], 80.0) + JuMP.set_upper_bound(x[2], 25.0) + JuMP.set_upper_bound(x[3], 45.0) + JuMP.set_upper_bound(x[4], 2950.0) + JuMP.set_upper_bound(x[5], 2950.0) + JuMP.set_upper_bound(x[6], 2950.0) + JuMP.set_upper_bound(x[7], 400.0) + JuMP.set_upper_bound(x[8], 400.0) + JuMP.set_upper_bound(x[9], 400.0) + JuMP.set_upper_bound(x[10], 350.0) + JuMP.set_upper_bound(x[11], 350.0) + JuMP.set_upper_bound(x[12], 350.0) + JuMP.set_upper_bound(x[13], 1.0) + JuMP.set_upper_bound(x[14], 1.0) + JuMP.set_upper_bound(x[15], 1.0) + JuMP.set_upper_bound(i[16], 3.0) + JuMP.set_upper_bound(i[17], 3.0) + JuMP.set_upper_bound(i[18], 3.0) + JuMP.set_upper_bound(i[19], 3.0) + JuMP.set_upper_bound(i[20], 3.0) + JuMP.set_upper_bound(i[21], 3.0) # ----- Constraints ----- # @@ -116,7 +116,7 @@ end function ex1264a(;solver=nothing) # 8.6 - m = Model(solver=solver) + m = Model(solver) # ----- Variables ----- # @variable(m, objvar) @@ -124,90 +124,90 @@ function ex1264a(;solver=nothing) @variable(m, b[b_Idx]) i_Idx = Any[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 21, 22, 23, 24] @variable(m, i[i_Idx]) - setcategory(i[8], :Int) - setlowerbound(i[8], 0.0) - setupperbound(i[8], 100.0) - setcategory(i[23], :Int) - setlowerbound(i[23], 0.0) - setupperbound(i[23], 100.0) - setcategory(i[21], :Int) - setlowerbound(i[21], 0.0) - setupperbound(i[21], 100.0) - setcategory(i[12], :Int) - setlowerbound(i[12], 0.0) - setupperbound(i[12], 100.0) - setcategory(b[18], :Bin) - setcategory(i[24], :Int) - setlowerbound(i[24], 0.0) - setupperbound(i[24], 100.0) - setcategory(i[5], :Int) - setlowerbound(i[5], 0.0) - setupperbound(i[5], 100.0) - setcategory(b[20], :Bin) - setcategory(i[3], :Int) - setlowerbound(i[3], 0.0) - setupperbound(i[3], 100.0) - setcategory(b[19], :Bin) - setcategory(i[2], :Int) - setlowerbound(i[2], 0.0) - setupperbound(i[2], 100.0) - setcategory(i[13], :Int) - setlowerbound(i[13], 0.0) - setupperbound(i[13], 100.0) - setcategory(i[6], :Int) - setlowerbound(i[6], 0.0) - setupperbound(i[6], 100.0) - setcategory(i[4], :Int) - setlowerbound(i[4], 0.0) - setupperbound(i[4], 100.0) - setcategory(i[9], :Int) - setlowerbound(i[9], 0.0) - setupperbound(i[9], 100.0) - setcategory(i[22], :Int) - setlowerbound(i[22], 0.0) - setupperbound(i[22], 100.0) - setcategory(i[14], :Int) - setlowerbound(i[14], 0.0) - setupperbound(i[14], 100.0) - setcategory(i[16], :Int) - setlowerbound(i[16], 0.0) - setupperbound(i[16], 100.0) - setcategory(i[10], :Int) - setlowerbound(i[10], 0.0) - setupperbound(i[10], 100.0) - setcategory(i[15], :Int) - setlowerbound(i[15], 0.0) - setupperbound(i[15], 100.0) - setcategory(b[17], :Bin) - setcategory(i[7], :Int) - setlowerbound(i[7], 0.0) - setupperbound(i[7], 100.0) - setcategory(i[11], :Int) - setlowerbound(i[11], 0.0) - setupperbound(i[11], 100.0) - setcategory(i[1], :Int) - setlowerbound(i[1], 0.0) - setupperbound(i[1], 100.0) - setupperbound(i[1], 5.0) - setupperbound(i[2], 5.0) - setupperbound(i[3], 5.0) - setupperbound(i[4], 5.0) - setupperbound(i[5], 5.0) - setupperbound(i[6], 5.0) - setupperbound(i[7], 5.0) - setupperbound(i[8], 5.0) - setupperbound(i[9], 5.0) - setupperbound(i[10], 5.0) - setupperbound(i[11], 5.0) - setupperbound(i[12], 5.0) - setupperbound(i[13], 5.0) - setupperbound(i[14], 5.0) - setupperbound(i[15], 5.0) - setupperbound(i[16], 5.0) - setupperbound(i[21], 15.0) - setupperbound(i[22], 12.0) - setupperbound(i[23], 9.0) - setupperbound(i[24], 6.0) + JuMP.set_integer(i[8]) + JuMP.set_lower_bound(i[8], 0.0) + JuMP.set_upper_bound(i[8], 100.0) + JuMP.set_integer(i[23]) + JuMP.set_lower_bound(i[23], 0.0) + JuMP.set_upper_bound(i[23], 100.0) + JuMP.set_integer(i[21]) + JuMP.set_lower_bound(i[21], 0.0) + JuMP.set_upper_bound(i[21], 100.0) + JuMP.set_integer(i[12]) + JuMP.set_lower_bound(i[12], 0.0) + JuMP.set_upper_bound(i[12], 100.0) + JuMP.set_binary(b[18]) + JuMP.set_integer(i[24]) + JuMP.set_lower_bound(i[24], 0.0) + JuMP.set_upper_bound(i[24], 100.0) + JuMP.set_integer(i[5]) + JuMP.set_lower_bound(i[5], 0.0) + JuMP.set_upper_bound(i[5], 100.0) + JuMP.set_binary(b[20]) + JuMP.set_integer(i[3]) + JuMP.set_lower_bound(i[3], 0.0) + JuMP.set_upper_bound(i[3], 100.0) + JuMP.set_binary(b[19]) + JuMP.set_integer(i[2]) + JuMP.set_lower_bound(i[2], 0.0) + JuMP.set_upper_bound(i[2], 100.0) + JuMP.set_integer(i[13]) + JuMP.set_lower_bound(i[13], 0.0) + JuMP.set_upper_bound(i[13], 100.0) + JuMP.set_integer(i[6]) + JuMP.set_lower_bound(i[6], 0.0) + JuMP.set_upper_bound(i[6], 100.0) + JuMP.set_integer(i[4]) + JuMP.set_lower_bound(i[4], 0.0) + JuMP.set_upper_bound(i[4], 100.0) + JuMP.set_integer(i[9]) + JuMP.set_lower_bound(i[9], 0.0) + JuMP.set_upper_bound(i[9], 100.0) + JuMP.set_integer(i[22]) + JuMP.set_lower_bound(i[22], 0.0) + JuMP.set_upper_bound(i[22], 100.0) + JuMP.set_integer(i[14]) + JuMP.set_lower_bound(i[14], 0.0) + JuMP.set_upper_bound(i[14], 100.0) + JuMP.set_integer(i[16]) + JuMP.set_lower_bound(i[16], 0.0) + JuMP.set_upper_bound(i[16], 100.0) + JuMP.set_integer(i[10]) + JuMP.set_lower_bound(i[10], 0.0) + JuMP.set_upper_bound(i[10], 100.0) + JuMP.set_integer(i[15]) + JuMP.set_lower_bound(i[15], 0.0) + JuMP.set_upper_bound(i[15], 100.0) + JuMP.set_binary(b[17]) + JuMP.set_integer(i[7]) + JuMP.set_lower_bound(i[7], 0.0) + JuMP.set_upper_bound(i[7], 100.0) + JuMP.set_integer(i[11]) + JuMP.set_lower_bound(i[11], 0.0) + JuMP.set_upper_bound(i[11], 100.0) + JuMP.set_integer(i[1]) + JuMP.set_lower_bound(i[1], 0.0) + JuMP.set_upper_bound(i[1], 100.0) + JuMP.set_upper_bound(i[1], 5.0) + JuMP.set_upper_bound(i[2], 5.0) + JuMP.set_upper_bound(i[3], 5.0) + JuMP.set_upper_bound(i[4], 5.0) + JuMP.set_upper_bound(i[5], 5.0) + JuMP.set_upper_bound(i[6], 5.0) + JuMP.set_upper_bound(i[7], 5.0) + JuMP.set_upper_bound(i[8], 5.0) + JuMP.set_upper_bound(i[9], 5.0) + JuMP.set_upper_bound(i[10], 5.0) + JuMP.set_upper_bound(i[11], 5.0) + JuMP.set_upper_bound(i[12], 5.0) + JuMP.set_upper_bound(i[13], 5.0) + JuMP.set_upper_bound(i[14], 5.0) + JuMP.set_upper_bound(i[15], 5.0) + JuMP.set_upper_bound(i[16], 5.0) + JuMP.set_upper_bound(i[21], 15.0) + JuMP.set_upper_bound(i[22], 12.0) + JuMP.set_upper_bound(i[23], 9.0) + JuMP.set_upper_bound(i[24], 6.0) # ----- Constraints ----- # @@ -257,22 +257,22 @@ end function prob03(;solver=nothing) - m = Model(solver=solver) + m = Model(solver) # ----- Variables ----- # @variable(m, objvar) i_Idx = Any[1, 2] @variable(m, i[i_Idx]) - setcategory(i[1], :Int) - setlowerbound(i[1], 0.0) - setupperbound(i[1], 100.0) - setcategory(i[2], :Int) - setlowerbound(i[2], 0.0) - setupperbound(i[2], 100.0) - setlowerbound(i[1], 1.0) - setupperbound(i[1], 5.0) - setlowerbound(i[2], 1.0) - setupperbound(i[2], 5.0) + JuMP.set_integer(i[1]) + JuMP.set_lower_bound(i[1], 0.0) + JuMP.set_upper_bound(i[1], 100.0) + JuMP.set_integer(i[2]) + JuMP.set_lower_bound(i[2], 0.0) + JuMP.set_upper_bound(i[2], 100.0) + JuMP.set_lower_bound(i[1], 1.0) + JuMP.set_upper_bound(i[1], 5.0) + JuMP.set_lower_bound(i[2], 1.0) + JuMP.set_upper_bound(i[2], 5.0) # ----- Constraints ----- # @@ -288,7 +288,7 @@ end function prob10(;solver=nothing) - m = Model(solver=solver) + m = Model(solver) # ----- Variables ----- # @variable(m, objvar) @@ -296,12 +296,12 @@ function prob10(;solver=nothing) @variable(m, x[x_Idx]) i_Idx = Any[3] @variable(m, i[i_Idx]) - setcategory(i[3], :Int) - setlowerbound(i[3], 0.0) - setupperbound(i[3], 100.0) - setlowerbound(x[2], 0.0) - setupperbound(x[2], 10.0) - setupperbound(i[3], 10.0) + JuMP.set_integer(i[3]) + JuMP.set_lower_bound(i[3], 0.0) + JuMP.set_upper_bound(i[3], 100.0) + JuMP.set_lower_bound(x[2], 0.0) + JuMP.set_upper_bound(x[2], 10.0) + JuMP.set_upper_bound(i[3], 10.0) # ----- Constraints ----- # @@ -319,32 +319,32 @@ end function st_miqp1(;solver=nothing) # 281.0000 - m = Model(solver=solver) + m = Model(solver) # ----- Variables ----- # @variable(m, objvar) i_Idx = Any[1, 2, 3, 4, 5] @variable(m, i[i_Idx]) - setcategory(i[5], :Int) - setlowerbound(i[5], 0.0) - setupperbound(i[5], 100.0) - setcategory(i[4], :Int) - setlowerbound(i[4], 0.0) - setupperbound(i[4], 100.0) - setcategory(i[3], :Int) - setlowerbound(i[3], 0.0) - setupperbound(i[3], 100.0) - setcategory(i[1], :Int) - setlowerbound(i[1], 0.0) - setupperbound(i[1], 100.0) - setcategory(i[2], :Int) - setlowerbound(i[2], 0.0) - setupperbound(i[2], 100.0) - setupperbound(i[1], 1.0) - setupperbound(i[2], 1.0) - setupperbound(i[3], 1.0) - setupperbound(i[4], 1.0) - setupperbound(i[5], 1.0) + JuMP.set_integer(i[5]) + JuMP.set_lower_bound(i[5], 0.0) + JuMP.set_upper_bound(i[5], 100.0) + JuMP.set_integer(i[4]) + JuMP.set_lower_bound(i[4], 0.0) + JuMP.set_upper_bound(i[4], 100.0) + JuMP.set_integer(i[3]) + JuMP.set_lower_bound(i[3], 0.0) + JuMP.set_upper_bound(i[3], 100.0) + JuMP.set_integer(i[1]) + JuMP.set_lower_bound(i[1], 0.0) + JuMP.set_upper_bound(i[1], 100.0) + JuMP.set_integer(i[2]) + JuMP.set_lower_bound(i[2], 0.0) + JuMP.set_upper_bound(i[2], 100.0) + JuMP.set_upper_bound(i[1], 1.0) + JuMP.set_upper_bound(i[2], 1.0) + JuMP.set_upper_bound(i[3], 1.0) + JuMP.set_upper_bound(i[4], 1.0) + JuMP.set_upper_bound(i[5], 1.0) # ----- Constraints ----- # @@ -361,28 +361,28 @@ end function st_miqp2(;solver=nothing) # 2.0000 - m = Model(solver=solver) + m = Model(solver) # ----- Variables ----- # @variable(m, objvar) i_Idx = Any[1, 2, 3, 4] @variable(m, i[i_Idx]) - setcategory(i[4], :Int) - setlowerbound(i[4], 0.0) - setupperbound(i[4], 100.0) - setcategory(i[3], :Int) - setlowerbound(i[3], 0.0) - setupperbound(i[3], 100.0) - setcategory(i[1], :Int) - setlowerbound(i[1], 0.0) - setupperbound(i[1], 100.0) - setcategory(i[2], :Int) - setlowerbound(i[2], 0.0) - setupperbound(i[2], 100.0) - setupperbound(i[1], 1.0) - setupperbound(i[2], 1.0) - setupperbound(i[3], 1.0e10) - setupperbound(i[4], 1.0e10) + JuMP.set_integer(i[4]) + JuMP.set_lower_bound(i[4], 0.0) + JuMP.set_upper_bound(i[4], 100.0) + JuMP.set_integer(i[3]) + JuMP.set_lower_bound(i[3], 0.0) + JuMP.set_upper_bound(i[3], 100.0) + JuMP.set_integer(i[1]) + JuMP.set_lower_bound(i[1], 0.0) + JuMP.set_upper_bound(i[1], 100.0) + JuMP.set_integer(i[2]) + JuMP.set_lower_bound(i[2], 0.0) + JuMP.set_upper_bound(i[2], 100.0) + JuMP.set_upper_bound(i[1], 1.0) + JuMP.set_upper_bound(i[2], 1.0) + JuMP.set_upper_bound(i[3], 1.0e10) + JuMP.set_upper_bound(i[4], 1.0e10) # ----- Constraints ----- # @@ -401,20 +401,20 @@ end function st_miqp3(;solver=nothing) # -6.0000 - m = Model(solver=solver) + m = Model(solver) # ----- Variables ----- # @variable(m, objvar) i_Idx = Any[1, 2] @variable(m, i[i_Idx]) - setcategory(i[1], :Int) - setlowerbound(i[1], 0.0) - setupperbound(i[1], 100.0) - setcategory(i[2], :Int) - setlowerbound(i[2], 0.0) - setupperbound(i[2], 100.0) - setupperbound(i[1], 3.0) - setupperbound(i[2], 1.0e15) + JuMP.set_integer(i[1]) + JuMP.set_lower_bound(i[1], 0.0) + JuMP.set_upper_bound(i[1], 100.0) + JuMP.set_integer(i[2]) + JuMP.set_lower_bound(i[2], 0.0) + JuMP.set_upper_bound(i[2], 100.0) + JuMP.set_upper_bound(i[1], 3.0) + JuMP.set_upper_bound(i[2], 1.0e15) # ----- Constraints ----- # @@ -431,7 +431,7 @@ end function st_miqp4(;solver=nothing) # -4574.0000 - m = Model(solver=solver) + m = Model(solver) # ----- Variables ----- # @variable(m, objvar) @@ -439,24 +439,24 @@ function st_miqp4(;solver=nothing) @variable(m, x[x_Idx]) i_Idx = Any[1, 2, 3] @variable(m, i[i_Idx]) - setlowerbound(x[5], 0.0) - setcategory(i[3], :Int) - setlowerbound(i[3], 0.0) - setupperbound(i[3], 100.0) - setlowerbound(x[4], 0.0) - setlowerbound(x[6], 0.0) - setcategory(i[1], :Int) - setlowerbound(i[1], 0.0) - setupperbound(i[1], 100.0) - setcategory(i[2], :Int) - setlowerbound(i[2], 0.0) - setupperbound(i[2], 100.0) - setupperbound(i[1], 1.0) - setupperbound(i[2], 1.0) - setupperbound(i[3], 1.0) - setupperbound(x[4], 1.0e15) - setupperbound(x[5], 1.0e15) - setupperbound(x[6], 1.0e15) + JuMP.set_lower_bound(x[5], 0.0) + JuMP.set_integer(i[3]) + JuMP.set_lower_bound(i[3], 0.0) + JuMP.set_upper_bound(i[3], 100.0) + JuMP.set_lower_bound(x[4], 0.0) + JuMP.set_lower_bound(x[6], 0.0) + JuMP.set_integer(i[1]) + JuMP.set_lower_bound(i[1], 0.0) + JuMP.set_upper_bound(i[1], 100.0) + JuMP.set_integer(i[2]) + JuMP.set_lower_bound(i[2], 0.0) + JuMP.set_upper_bound(i[2], 100.0) + JuMP.set_upper_bound(i[1], 1.0) + JuMP.set_upper_bound(i[2], 1.0) + JuMP.set_upper_bound(i[3], 1.0) + JuMP.set_upper_bound(x[4], 1.0e15) + JuMP.set_upper_bound(x[5], 1.0e15) + JuMP.set_upper_bound(x[6], 1.0e15) # ----- Constraints ----- # @@ -476,7 +476,7 @@ end function st_miqp5(;solver=nothing) # -333.88888890 - m = Model(solver=solver) + m = Model(solver) # ----- Variables ----- # @variable(m, objvar) @@ -484,24 +484,24 @@ function st_miqp5(;solver=nothing) @variable(m, x[x_Idx]) i_Idx = Any[1, 2] @variable(m, i[i_Idx]) - setcategory(i[1], :Int) - setlowerbound(i[1], 0.0) - setupperbound(i[1], 100.0) - setcategory(i[2], :Int) - setlowerbound(i[2], 0.0) - setupperbound(i[2], 100.0) - setupperbound(i[1], 1.0) - setupperbound(i[2], 1.0) - setlowerbound(x[3], -7.24380468458) - setupperbound(x[3], 22.6826188429) - setlowerbound(x[4], -6.0023781122) - setupperbound(x[4], 3.80464419615) - setlowerbound(x[5], -0.797166188733) - setupperbound(x[5], 11.5189336042) - setlowerbound(x[6], -8.75189948987) - setupperbound(x[6], 14.5864991498) - setlowerbound(x[7], 8.98296319621e-17) - setupperbound(x[7], 19.4187214575) + JuMP.set_integer(i[1]) + JuMP.set_lower_bound(i[1], 0.0) + JuMP.set_upper_bound(i[1], 100.0) + JuMP.set_integer(i[2]) + JuMP.set_lower_bound(i[2], 0.0) + JuMP.set_upper_bound(i[2], 100.0) + JuMP.set_upper_bound(i[1], 1.0) + JuMP.set_upper_bound(i[2], 1.0) + JuMP.set_lower_bound(x[3], -7.24380468458) + JuMP.set_upper_bound(x[3], 22.6826188429) + JuMP.set_lower_bound(x[4], -6.0023781122) + JuMP.set_upper_bound(x[4], 3.80464419615) + JuMP.set_lower_bound(x[5], -0.797166188733) + JuMP.set_upper_bound(x[5], 11.5189336042) + JuMP.set_lower_bound(x[6], -8.75189948987) + JuMP.set_upper_bound(x[6], 14.5864991498) + JuMP.set_lower_bound(x[7], 8.98296319621e-17) + JuMP.set_upper_bound(x[7], 19.4187214575) # ----- Constraints ----- # diff --git a/test/examples/linearlift.jl b/test/examples/linearlift.jl index 606e9954..00393fe6 100644 --- a/test/examples/linearlift.jl +++ b/test/examples/linearlift.jl @@ -1,11 +1,11 @@ function basic_linear_lift(;verbose=false, solver=nothing) if solver == nothing - m = Model(solver=AlpineSolver(nlp_solver=IpoptSolver(), + m = Model(Alpine.Optimizer(nlp_solver=IpoptSolver(), mip_solver=CbcSolver(logLevel=0), loglevel=10000)) else - m = Model(solver=solver) + m = Model(solver) end @variable(m, x[i=1:3]>=1) # At some point if an initial value is given, keep them diff --git a/test/examples/multi.jl b/test/examples/multi.jl index b186cc84..4ee8b04c 100644 --- a/test/examples/multi.jl +++ b/test/examples/multi.jl @@ -21,7 +21,7 @@ function multi4(;verbose=false,solver=nothing, exprmode=1) - m = Model(solver=solver) + m = Model(solver) Random.seed!(1) @variable(m, 0.1<=x[1:4]<=rand()*100) @@ -61,7 +61,7 @@ end function multi3(;verbose=false, solver=nothing, exprmode=1) - m = Model(solver=solver) + m = Model(solver) Random.seed!(1) ub = rand() @@ -87,7 +87,7 @@ end function multi2(;verbose=false,solver=nothing) - m = Model(solver=solver) + m = Model(solver) Random.seed!(1) @variable(m, 0.1<=x[1:2]<=rand()*10) @@ -103,7 +103,7 @@ end function multi4N(;verbose=false, exprmode=1, solver=nothing, N=1, randomub=true) - m = Model(solver=solver) + m = Model(solver) M = 1+3*N Random.seed!(100) @@ -146,7 +146,7 @@ end function multi3N(;verbose=false, randomub=nothing, solver=nothing, exprmode=1, N=1, delta=4) - m = Model(solver=solver) + m = Model(solver) M = 1+2*N Random.seed!(100) @@ -172,7 +172,7 @@ end function multiKND(;verbose=false, solver=nothing, exprmode=1, randomub=true, N=1, K=2, D=1) - m = Model(solver=solver) + m = Model(solver) M = K+(K-D)*(N-1) Random.seed!(100) diff --git a/test/examples/nlp.jl b/test/examples/nlp.jl index e3a020b2..569fc29c 100644 --- a/test/examples/nlp.jl +++ b/test/examples/nlp.jl @@ -1,7 +1,7 @@ function nlp1(;verbose=false,solver=nothing, convhull=false, presolve=0) if solver == nothing - m = Model(solver=AlpineSolver(nlp_solver=IpoptSolver(print_level=0), + m = Model(Alpine.Optimizer(nlp_solver=IpoptSolver(print_level=0), mip_solver=GurobiSolver(OutputFlag=0), bilinear_convexhull=convhull, monomial_convexhull=convhull, @@ -10,7 +10,7 @@ function nlp1(;verbose=false,solver=nothing, convhull=false, presolve=0) presolve_bt_output_tol=1e-1, loglevel=10000)) else - m = Model(solver=solver) + m = Model(solver) end @variable(m, 1<=x[1:2]<=10) @@ -24,7 +24,7 @@ end function nlp2(;verbose=false,solver=nothing, convhull=false, presolve=0) if solver == nothing - m = Model(solver=AlpineSolver(nlp_solver=IpoptSolver(print_level=0), + m = Model(Alpine.Optimizer(nlp_solver=IpoptSolver(print_level=0), mip_solver=GurobiSolver(OutputFlag=0), bilinear_convexhull=convhull, monomial_convexhull=convhull, @@ -33,7 +33,7 @@ function nlp2(;verbose=false,solver=nothing, convhull=false, presolve=0) presolve_bt_output_tol=1e-1, loglevel=10000)) else - m = Model(solver=solver) + m = Model(solver) end @variable(m, -500<=x[1:2]<=500) @@ -43,7 +43,7 @@ function nlp2(;verbose=false,solver=nothing, convhull=false, presolve=0) return m end -function max_cover_var_picker(m::Alpine.AlpineNonlinearModel) +function max_cover_var_picker(m::Alpine.Optimizer) nodes = Set() for pair in keys(m.nonconvex_terms) for i in pair @@ -60,27 +60,27 @@ end function nlp3(;solver=nothing) - m = Model(solver=solver) + m = Model(solver) @variable(m, x[1:8]) - setlowerbound(x[1], 100) - setlowerbound(x[2], 1000) - setlowerbound(x[3], 1000) - setlowerbound(x[4], 10) - setlowerbound(x[5], 10) - setlowerbound(x[6], 10) - setlowerbound(x[7], 10) - setlowerbound(x[8], 10) - - setupperbound(x[1], 10000) - setupperbound(x[2], 10000) - setupperbound(x[3], 10000) - setupperbound(x[4], 1000) - setupperbound(x[5], 1000) - setupperbound(x[6], 1000) - setupperbound(x[7], 1000) - setupperbound(x[8], 1000) + set_lower_bound(x[1], 100) + set_lower_bound(x[2], 1000) + set_lower_bound(x[3], 1000) + set_lower_bound(x[4], 10) + set_lower_bound(x[5], 10) + set_lower_bound(x[6], 10) + set_lower_bound(x[7], 10) + set_lower_bound(x[8], 10) + + set_upper_bound(x[1], 10000) + set_upper_bound(x[2], 10000) + set_upper_bound(x[3], 10000) + set_upper_bound(x[4], 1000) + set_upper_bound(x[5], 1000) + set_upper_bound(x[6], 1000) + set_upper_bound(x[7], 1000) + set_upper_bound(x[8], 1000) @constraint(m, 0.0025*(x[4] + x[6]) <= 1) @constraint(m, 0.0025*(x[5] - x[4] + x[7]) <= 1) diff --git a/test/examples/sincos.jl b/test/examples/sincos.jl index 58cba238..5b7873cb 100644 --- a/test/examples/sincos.jl +++ b/test/examples/sincos.jl @@ -1,6 +1,6 @@ function sincos_p1(;solver=nothing) - m = Model(solver=solver) + m = Model(solver) @variable(m, 0.1<=x[1:10]<=10) @NLconstraint(m, [i in 1:9], x[i]*x[i+1]*sin(x[i])>=0.32) @@ -12,14 +12,14 @@ end function trig(;solver=nothing) - m = Model(solver=solver) + m = Model(solver) # ----- Variables ----- # @variable(m, objvar) x_Idx = Any[1] @variable(m, x[x_Idx]) - setlowerbound(x[1], -2.0) - setupperbound(x[1], 5.0) + JuMP.set_lower_bound(x[1], -2.0) + JuMP.set_upper_bound(x[1], 5.0) # ----- Constraints ----- # @NLconstraint(m, e1, -(sin(11*x[1])+cos(13*x[1])-sin(17*x[1])-cos(19*x[1]))+objvar == 0.0) @@ -33,7 +33,7 @@ end function specialopts(;verbose=false, solver=nothing) - m = Model(solver=solver) + m = Model(solver) @variable(m, x[i=1:6]) # At some point if an initial value is given, keep them diff --git a/test/expression.jl b/test/expression.jl index f573a7d9..a66e20b6 100644 --- a/test/expression.jl +++ b/test/expression.jl @@ -1,675 +1,679 @@ @testset "Expression Parsing || bilinear || Affine || exprs.jl" begin - test_solver = AlpineSolver(nlp_solver=IpoptSolver(print_level=0, sb="yes"),mip_solver=CbcSolver(logLevel=0),loglevel=100) + test_solver = optimizer_with_attributes(Alpine.Optimizer,"nlp_solver" => IPOPT_SB,"mip_solver" => CBC,"loglevel" => 100) m=exprstest(solver=test_solver) - JuMP.build(m) + alpine = _build(m) - ex = m.internalModel.bounding_constr_expr_mip[1] + ex = alpine.bounding_constr_expr_mip[1] affdict = Alpine.expr_linear_to_affine(ex) @test affdict[:coefs] == [-1.0] - @test affdict[:coefs] == m.internalModel.bounding_constr_mip[1][:coefs] + @test affdict[:coefs] == alpine.bounding_constr_mip[1][:coefs] @test affdict[:vars] == [:(x[1])] - @test affdict[:vars] == m.internalModel.bounding_constr_mip[1][:vars] + @test affdict[:vars] == alpine.bounding_constr_mip[1][:vars] @test isapprox(affdict[:rhs], 109.0; atol = 1e-3) - @test affdict[:rhs] == m.internalModel.bounding_constr_mip[1][:rhs] + @test affdict[:rhs] == alpine.bounding_constr_mip[1][:rhs] @test affdict[:sense] == :(<=) - @test affdict[:sense] == m.internalModel.bounding_constr_mip[1][:sense] + @test affdict[:sense] == alpine.bounding_constr_mip[1][:sense] - ex = m.internalModel.bounding_constr_expr_mip[2] + ex = alpine.bounding_constr_expr_mip[2] affdict = Alpine.expr_linear_to_affine(ex) @test affdict[:coefs] == [3.0,3.0,3.0,3.0] - @test affdict[:coefs] == m.internalModel.bounding_constr_mip[2][:coefs] + @test affdict[:coefs] == alpine.bounding_constr_mip[2][:coefs] @test affdict[:vars] == [:(x[8]),:(x[9]),:(x[10]),:(x[11])] - @test affdict[:vars] == m.internalModel.bounding_constr_mip[2][:vars] + @test affdict[:vars] == alpine.bounding_constr_mip[2][:vars] @test isapprox(affdict[:rhs], 111.0; atol = 1e-3) - @test affdict[:rhs] == m.internalModel.bounding_constr_mip[2][:rhs] + @test affdict[:rhs] == alpine.bounding_constr_mip[2][:rhs] @test affdict[:sense] == :(>=) - @test affdict[:sense] == m.internalModel.bounding_constr_mip[2][:sense] + @test affdict[:sense] == alpine.bounding_constr_mip[2][:sense] - ex = m.internalModel.bounding_constr_expr_mip[3] + ex = alpine.bounding_constr_expr_mip[3] affdict = Alpine.expr_linear_to_affine(ex) @test affdict[:coefs] == [-1.0,20.0] - @test affdict[:coefs] == m.internalModel.bounding_constr_mip[3][:coefs] + @test affdict[:coefs] == alpine.bounding_constr_mip[3][:coefs] @test affdict[:vars] == [:(x[12]),:(x[13])] - @test affdict[:vars] == m.internalModel.bounding_constr_mip[3][:vars] + @test affdict[:vars] == alpine.bounding_constr_mip[3][:vars] @test isapprox(affdict[:rhs], 222.0; atol = 1e-3) - @test affdict[:rhs] == m.internalModel.bounding_constr_mip[3][:rhs] + @test affdict[:rhs] == alpine.bounding_constr_mip[3][:rhs] @test affdict[:sense] == :(>=) - @test affdict[:sense] == m.internalModel.bounding_constr_mip[3][:sense] + @test affdict[:sense] == alpine.bounding_constr_mip[3][:sense] # 1.0 * x[12] - 115.0 >= 0.0 - ex = m.internalModel.bounding_constr_expr_mip[4] + ex = alpine.bounding_constr_expr_mip[4] affdict = Alpine.expr_linear_to_affine(ex) @test affdict[:coefs] == [-1.0] - @test affdict[:coefs] == m.internalModel.bounding_constr_mip[4][:coefs] + @test affdict[:coefs] == alpine.bounding_constr_mip[4][:coefs] @test affdict[:vars] == [:(x[12])] - @test affdict[:vars] == m.internalModel.bounding_constr_mip[4][:vars] + @test affdict[:vars] == alpine.bounding_constr_mip[4][:vars] @test isapprox(affdict[:rhs], 115.0; atol = 1e-3) - @test affdict[:rhs] == m.internalModel.bounding_constr_mip[4][:rhs] + @test affdict[:rhs] == alpine.bounding_constr_mip[4][:rhs] @test affdict[:sense] == :(<=) - @test affdict[:sense] == m.internalModel.bounding_constr_mip[4][:sense] + @test affdict[:sense] == alpine.bounding_constr_mip[4][:sense] # 1.0 * x[12] - 115.0 <= 0.0 - ex = m.internalModel.bounding_constr_expr_mip[5] + ex = alpine.bounding_constr_expr_mip[5] affdict = Alpine.expr_linear_to_affine(ex) @test affdict[:coefs] == [1.0] - @test affdict[:coefs] == m.internalModel.bounding_constr_mip[5][:coefs] + @test affdict[:coefs] == alpine.bounding_constr_mip[5][:coefs] @test affdict[:vars] == [:(x[12])] - @test affdict[:vars] == m.internalModel.bounding_constr_mip[5][:vars] + @test affdict[:vars] == alpine.bounding_constr_mip[5][:vars] @test isapprox(affdict[:rhs], 115.0; atol = 1e-3) - @test affdict[:rhs] == m.internalModel.bounding_constr_mip[5][:rhs] + @test affdict[:rhs] == alpine.bounding_constr_mip[5][:rhs] @test affdict[:sense] == :(>=) - @test affdict[:sense] == m.internalModel.bounding_constr_mip[5][:sense] + @test affdict[:sense] == alpine.bounding_constr_mip[5][:sense] # -1.0 * x[12] - 115.0 >= 0.0 - ex = m.internalModel.bounding_constr_expr_mip[6] + ex = alpine.bounding_constr_expr_mip[6] affdict = Alpine.expr_linear_to_affine(ex) @test affdict[:coefs] == [-1.0] - @test affdict[:coefs] == m.internalModel.bounding_constr_mip[6][:coefs] + @test affdict[:coefs] == alpine.bounding_constr_mip[6][:coefs] @test affdict[:vars] == [:(x[12])] - @test affdict[:vars] == m.internalModel.bounding_constr_mip[6][:vars] + @test affdict[:vars] == alpine.bounding_constr_mip[6][:vars] @test isapprox(affdict[:rhs], 115.0; atol = 1e-3) - @test affdict[:rhs] == m.internalModel.bounding_constr_mip[6][:rhs] + @test affdict[:rhs] == alpine.bounding_constr_mip[6][:rhs] @test affdict[:sense] == :(<=) - @test affdict[:sense] == m.internalModel.bounding_constr_mip[6][:sense] + @test affdict[:sense] == alpine.bounding_constr_mip[6][:sense] # (x[1] + 1.0 * x[14]) - 555.0 >= 0.0 - ex = m.internalModel.bounding_constr_expr_mip[7] + ex = alpine.bounding_constr_expr_mip[7] affdict = Alpine.expr_linear_to_affine(ex) @test affdict[:coefs] == [1.0, 1.0] - @test affdict[:coefs] == m.internalModel.bounding_constr_mip[7][:coefs] + @test affdict[:coefs] == alpine.bounding_constr_mip[7][:coefs] @test affdict[:vars] == [:(x[1]),:(x[14])] - @test affdict[:vars] == m.internalModel.bounding_constr_mip[7][:vars] + @test affdict[:vars] == alpine.bounding_constr_mip[7][:vars] @test isapprox(affdict[:rhs], 555.0; atol = 1e-3) - @test affdict[:rhs] == m.internalModel.bounding_constr_mip[7][:rhs] + @test affdict[:rhs] == alpine.bounding_constr_mip[7][:rhs] @test affdict[:sense] == :(>=) - @test affdict[:sense] == m.internalModel.bounding_constr_mip[7][:sense] + @test affdict[:sense] == alpine.bounding_constr_mip[7][:sense] # ((x[8] - 7.0 * x[9]) + x[10] + x[4]) - 6666.0 <= 0.0 - ex = m.internalModel.bounding_constr_expr_mip[8] + ex = alpine.bounding_constr_expr_mip[8] affdict = Alpine.expr_linear_to_affine(ex) @test affdict[:coefs] == [1.0,-7.0,1.0,1.0] - @test affdict[:coefs] == m.internalModel.bounding_constr_mip[8][:coefs] + @test affdict[:coefs] == alpine.bounding_constr_mip[8][:coefs] @test affdict[:vars] == [:(x[8]),:(x[9]),:(x[10]),:(x[4])] - @test affdict[:vars] == m.internalModel.bounding_constr_mip[8][:vars] + @test affdict[:vars] == alpine.bounding_constr_mip[8][:vars] @test isapprox(affdict[:rhs], 6666.0; atol = 1e-3) - @test affdict[:rhs] == m.internalModel.bounding_constr_mip[8][:rhs] + @test affdict[:rhs] == alpine.bounding_constr_mip[8][:rhs] @test affdict[:sense] == :(<=) - @test affdict[:sense] == m.internalModel.bounding_constr_mip[8][:sense] + @test affdict[:sense] == alpine.bounding_constr_mip[8][:sense] # ((13.0 * x[1] - x[2]) + 30.0 * x[3] + x[4]) - 77.0 >= 0.0 - ex = m.internalModel.bounding_constr_expr_mip[9] + ex = alpine.bounding_constr_expr_mip[9] affdict = Alpine.expr_linear_to_affine(ex) @test affdict[:coefs] == [13.0,-1.0,30.0,1.0] - @test affdict[:coefs] == m.internalModel.bounding_constr_mip[9][:coefs] + @test affdict[:coefs] == alpine.bounding_constr_mip[9][:coefs] @test affdict[:vars] == [:(x[1]),:(x[2]),:(x[3]),:(x[4])] - @test affdict[:vars] == m.internalModel.bounding_constr_mip[9][:vars] + @test affdict[:vars] == alpine.bounding_constr_mip[9][:vars] @test isapprox(affdict[:rhs], 77.0; atol = 1e-3) - @test affdict[:rhs] == m.internalModel.bounding_constr_mip[9][:rhs] + @test affdict[:rhs] == alpine.bounding_constr_mip[9][:rhs] @test affdict[:sense] == :(>=) - @test affdict[:sense] == m.internalModel.bounding_constr_mip[9][:sense] + @test affdict[:sense] == alpine.bounding_constr_mip[9][:sense] end @testset "Expression Parsing || bilinear || Affine || nlp1.jl" begin - test_solver = AlpineSolver(nlp_solver=IpoptSolver(print_level=0, sb="yes"), - mip_solver=CbcSolver(logLevel=0), - loglevel=100) + test_solver = optimizer_with_attributes(Alpine.Optimizer,"nlp_solver" => IPOPT_SB, + "mip_solver" => CBC, + "loglevel" => 100) m=nlp1(solver=test_solver) - JuMP.build(m) + alpine = _build(m) - ex = m.internalModel.bounding_constr_expr_mip[1] + ex = alpine.bounding_constr_expr_mip[1] affdict = Alpine.expr_linear_to_affine(ex) @test affdict[:coefs] == [1.0] - @test affdict[:coefs] == m.internalModel.bounding_constr_mip[1][:coefs] + @test affdict[:coefs] == alpine.bounding_constr_mip[1][:coefs] @test affdict[:vars] == [:(x[5])] - @test affdict[:vars] == m.internalModel.bounding_constr_mip[1][:vars] + @test affdict[:vars] == alpine.bounding_constr_mip[1][:vars] @test isapprox(affdict[:rhs], 8.0; atol = 1e-3) - @test affdict[:rhs] == m.internalModel.bounding_constr_mip[1][:rhs] + @test affdict[:rhs] == alpine.bounding_constr_mip[1][:rhs] @test affdict[:sense] == :(>=) - @test affdict[:sense] == m.internalModel.bounding_constr_mip[1][:sense] + @test affdict[:sense] == alpine.bounding_constr_mip[1][:sense] end @testset "Expression Parsing || bilinear || Affine || nlp3.jl" begin - test_solver = AlpineSolver(nlp_solver=IpoptSolver(print_level=0, sb="yes"),mip_solver=CbcSolver(logLevel=0),loglevel=100) + test_solver = optimizer_with_attributes(Alpine.Optimizer,"nlp_solver" => IPOPT_SB,"mip_solver" => CBC,"loglevel" => 100) m=nlp3(solver=test_solver) - JuMP.build(m) + alpine = _build(m) - ex = m.internalModel.bounding_constr_expr_mip[1] + ex = alpine.bounding_constr_expr_mip[1] affdict = Alpine.expr_linear_to_affine(ex) @test affdict[:coefs] == [0.0025,0.0025] - @test affdict[:coefs] == m.internalModel.bounding_constr_mip[1][:coefs] + @test affdict[:coefs] == alpine.bounding_constr_mip[1][:coefs] @test affdict[:vars] == [:(x[4]),:(x[6])] - @test affdict[:vars] == m.internalModel.bounding_constr_mip[1][:vars] + @test affdict[:vars] == alpine.bounding_constr_mip[1][:vars] @test isapprox(affdict[:rhs], 1.0; atol = 1e-3) - @test affdict[:rhs] == m.internalModel.bounding_constr_mip[1][:rhs] + @test affdict[:rhs] == alpine.bounding_constr_mip[1][:rhs] @test affdict[:sense] == :(<=) - @test affdict[:sense] == m.internalModel.bounding_constr_mip[1][:sense] + @test affdict[:sense] == alpine.bounding_constr_mip[1][:sense] - ex = m.internalModel.bounding_constr_expr_mip[2] + ex = alpine.bounding_constr_expr_mip[2] affdict = Alpine.expr_linear_to_affine(ex) @test affdict[:coefs] == [0.0025,-0.0025,0.0025] - @test affdict[:coefs] == m.internalModel.bounding_constr_mip[2][:coefs] + @test affdict[:coefs] == alpine.bounding_constr_mip[2][:coefs] @test affdict[:vars] == [:(x[5]),:(x[4]),:(x[7])] - @test affdict[:vars] == m.internalModel.bounding_constr_mip[2][:vars] + @test affdict[:vars] == alpine.bounding_constr_mip[2][:vars] @test isapprox(affdict[:rhs], 1.0; atol = 1e-3) - @test affdict[:rhs] == m.internalModel.bounding_constr_mip[2][:rhs] + @test affdict[:rhs] == alpine.bounding_constr_mip[2][:rhs] @test affdict[:sense] == :(<=) - @test affdict[:sense] == m.internalModel.bounding_constr_mip[2][:sense] + @test affdict[:sense] == alpine.bounding_constr_mip[2][:sense] - ex = m.internalModel.bounding_constr_expr_mip[3] + ex = alpine.bounding_constr_expr_mip[3] affdict = Alpine.expr_linear_to_affine(ex) @test affdict[:coefs] == [0.01, -0.01] - @test affdict[:coefs] == m.internalModel.bounding_constr_mip[3][:coefs] + @test affdict[:coefs] == alpine.bounding_constr_mip[3][:coefs] @test affdict[:vars] == [:(x[8]),:(x[5])] - @test affdict[:vars] == m.internalModel.bounding_constr_mip[3][:vars] + @test affdict[:vars] == alpine.bounding_constr_mip[3][:vars] @test isapprox(affdict[:rhs], 1.0; atol = 1e-3) - @test affdict[:rhs] == m.internalModel.bounding_constr_mip[3][:rhs] + @test affdict[:rhs] == alpine.bounding_constr_mip[3][:rhs] @test affdict[:sense] == :(<=) - @test affdict[:sense] == m.internalModel.bounding_constr_mip[3][:sense] + @test affdict[:sense] == alpine.bounding_constr_mip[3][:sense] - ex = m.internalModel.bounding_constr_expr_mip[4] + ex = alpine.bounding_constr_expr_mip[4] affdict = Alpine.expr_linear_to_affine(ex) @test (affdict[:coefs] .== [100.0, -1.0, 833.33252]) == [true, true, true] - @test affdict[:coefs] == m.internalModel.bounding_constr_mip[4][:coefs] + @test affdict[:coefs] == alpine.bounding_constr_mip[4][:coefs] @test affdict[:vars] == [:(x[1]),:(x[9]),:(x[4])] - @test affdict[:vars] == m.internalModel.bounding_constr_mip[4][:vars] + @test affdict[:vars] == alpine.bounding_constr_mip[4][:vars] @test isapprox(affdict[:rhs], 83333.333; atol = 1e-3) - @test affdict[:rhs] == m.internalModel.bounding_constr_mip[4][:rhs] + @test affdict[:rhs] == alpine.bounding_constr_mip[4][:rhs] @test affdict[:sense] == :(<=) - @test affdict[:sense] == m.internalModel.bounding_constr_mip[4][:sense] + @test affdict[:sense] == alpine.bounding_constr_mip[4][:sense] - ex = m.internalModel.bounding_constr_expr_mip[5] + ex = alpine.bounding_constr_expr_mip[5] affdict = Alpine.expr_linear_to_affine(ex) @test affdict[:coefs] == [1.0,-1.0,-1250.0,1250.0] - @test affdict[:coefs] == m.internalModel.bounding_constr_mip[5][:coefs] + @test affdict[:coefs] == alpine.bounding_constr_mip[5][:coefs] @test affdict[:vars] == [:(x[10]),:(x[11]),:(x[4]),:(x[5])] - @test affdict[:vars] == m.internalModel.bounding_constr_mip[5][:vars] + @test affdict[:vars] == alpine.bounding_constr_mip[5][:vars] @test isapprox(affdict[:rhs], 0.0; atol = 1e-3) - @test affdict[:rhs] == m.internalModel.bounding_constr_mip[5][:rhs] + @test affdict[:rhs] == alpine.bounding_constr_mip[5][:rhs] @test affdict[:sense] == :(<=) - @test affdict[:sense] == m.internalModel.bounding_constr_mip[5][:sense] + @test affdict[:sense] == alpine.bounding_constr_mip[5][:sense] - ex = m.internalModel.bounding_constr_expr_mip[6] + ex = alpine.bounding_constr_expr_mip[6] affdict = Alpine.expr_linear_to_affine(ex) @test affdict[:coefs] == [1.0,-1.0,-2500.0] - @test affdict[:coefs] == m.internalModel.bounding_constr_mip[6][:coefs] + @test affdict[:coefs] == alpine.bounding_constr_mip[6][:coefs] @test affdict[:vars] == [:(x[12]),:(x[13]),:(x[5])] - @test affdict[:vars] == m.internalModel.bounding_constr_mip[6][:vars] + @test affdict[:vars] == alpine.bounding_constr_mip[6][:vars] @test isapprox(affdict[:rhs], -1.25e6; atol = 1e-3) - @test affdict[:rhs] == m.internalModel.bounding_constr_mip[6][:rhs] + @test affdict[:rhs] == alpine.bounding_constr_mip[6][:rhs] @test affdict[:sense] == :(<=) - @test affdict[:sense] == m.internalModel.bounding_constr_mip[6][:sense] + @test affdict[:sense] == alpine.bounding_constr_mip[6][:sense] end @testset "Expression Parsing || bilinear || Simple || bi1.jl " begin - test_solver = AlpineSolver(nlp_solver=IpoptSolver(print_level=0, sb="yes"), - mip_solver=CbcSolver(logLevel=0), - loglevel=100) + test_solver = optimizer_with_attributes(Alpine.Optimizer,"nlp_solver" => IPOPT_SB, + "mip_solver" => CBC, + "loglevel" => 100) m = operator_c(solver=test_solver) - JuMP.build(m) # Setup internal model + alpine = _build(m) # Setup internal model - @test length(keys(m.internalModel.nonconvex_terms)) == 8 - @test haskey(m.internalModel.nonconvex_terms, [Expr(:ref, :x, 1), Expr(:ref, :x, 1)]) - @test haskey(m.internalModel.nonconvex_terms, [Expr(:ref, :x, 2), Expr(:ref, :x, 2)]) - @test haskey(m.internalModel.nonconvex_terms, [Expr(:ref, :x, 3), Expr(:ref, :x, 3)]) - @test haskey(m.internalModel.nonconvex_terms, [Expr(:ref, :x, 4), Expr(:ref, :x, 4)]) - @test haskey(m.internalModel.nonconvex_terms, [Expr(:ref, :x, 2), Expr(:ref, :x, 3)]) - @test haskey(m.internalModel.nonconvex_terms, [Expr(:ref, :x, 3), Expr(:ref, :x, 4)]) + @test length(keys(alpine.nonconvex_terms)) == 8 + @test haskey(alpine.nonconvex_terms, [Expr(:ref, :x, 1), Expr(:ref, :x, 1)]) + @test haskey(alpine.nonconvex_terms, [Expr(:ref, :x, 2), Expr(:ref, :x, 2)]) + @test haskey(alpine.nonconvex_terms, [Expr(:ref, :x, 3), Expr(:ref, :x, 3)]) + @test haskey(alpine.nonconvex_terms, [Expr(:ref, :x, 4), Expr(:ref, :x, 4)]) + @test haskey(alpine.nonconvex_terms, [Expr(:ref, :x, 2), Expr(:ref, :x, 3)]) + @test haskey(alpine.nonconvex_terms, [Expr(:ref, :x, 3), Expr(:ref, :x, 4)]) # TODO setup detailed check on this problem end - @testset "Expression Parsing || bilinear || Complex || blend029.jl " begin - test_solver = AlpineSolver(minlp_solver=pavito_solver,mip_solver=CbcSolver(logLevel=0),loglevel=100) + test_solver = optimizer_with_attributes( + Alpine.Optimizer, + "minlp_solver" => JUNIPER, + "mip_solver" => CBC, + "loglevel" => 100) m = blend029(solver=test_solver) - JuMP.build(m) # Setup internal model - @test length(keys(m.internalModel.nonconvex_terms)) == 28 - @test haskey(m.internalModel.nonconvex_terms, [Expr(:ref, :x, 37), Expr(:ref, :x, 55)]) - @test haskey(m.internalModel.nonconvex_terms, [Expr(:ref, :x, 38), Expr(:ref, :x, 56)]) - @test haskey(m.internalModel.nonconvex_terms, [Expr(:ref, :x, 37), Expr(:ref, :x, 26)]) - @test haskey(m.internalModel.nonconvex_terms, [Expr(:ref, :x, 43), Expr(:ref, :x, 26)]) - @test haskey(m.internalModel.nonconvex_terms, [Expr(:ref, :x, 47), Expr(:ref, :x, 59)]) - @test haskey(m.internalModel.nonconvex_terms, [Expr(:ref, :x, 48), Expr(:ref, :x, 60)]) - @test haskey(m.internalModel.nonconvex_terms, [Expr(:ref, :x, 47), Expr(:ref, :x, 36)]) - - @test m.internalModel.bounding_constr_mip[1][:rhs] == 1.0 - @test m.internalModel.bounding_constr_mip[1][:vars] == Any[:(x[1]), :(x[4]), :(x[7]), :(x[10]), :(x[49])] - @test m.internalModel.bounding_constr_mip[1][:sense] == :(==) - @test m.internalModel.bounding_constr_mip[1][:coefs] == Any[1.0, 1.0, 1.0, 1.0, 1.0] - @test m.internalModel.bounding_constr_mip[1][:cnt] == 5 - - @test m.internalModel.bounding_constr_mip[4][:rhs] == 0.1 - @test m.internalModel.bounding_constr_mip[4][:vars] == Any[:(x[4]), :(x[16]), :(x[25]), :(x[34]), :(x[58])] - @test m.internalModel.bounding_constr_mip[4][:sense] == :(==) - @test m.internalModel.bounding_constr_mip[4][:coefs] == Any[-1.0, -1.0, -1.0, 1.0, 1.0] - @test m.internalModel.bounding_constr_mip[4][:cnt] == 5 - - @test m.internalModel.bounding_constr_mip[17][:rhs] == -0.14 - @test m.internalModel.bounding_constr_mip[17][:vars] == Any[:(x[11]), :(x[23]), :(x[32]), :(x[64]), :(x[65])] - @test m.internalModel.bounding_constr_mip[17][:sense] == :(==) - @test m.internalModel.bounding_constr_mip[17][:coefs] == Any[-1.0, -1.0, -1.0, -1.0, 1.0] - @test m.internalModel.bounding_constr_mip[17][:cnt] == 5 - - @test m.internalModel.bounding_constr_mip[67][:rhs] == 0.0 - @test m.internalModel.bounding_constr_mip[67][:vars] == Any[:(x[13])] - @test m.internalModel.bounding_constr_mip[67][:sense] == :(>=) - @test m.internalModel.bounding_constr_mip[67][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[67][:cnt] == 1 - - @test m.internalModel.bounding_constr_mip[103][:rhs] == 1.0 - @test m.internalModel.bounding_constr_mip[103][:vars] == Any[:(x[73])] - @test m.internalModel.bounding_constr_mip[103][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[103][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[103][:cnt] == 1 - - @test m.internalModel.bounding_constr_mip[127][:rhs] == -1.0 - @test m.internalModel.bounding_constr_mip[127][:vars] == Any[:(x[73])] - @test m.internalModel.bounding_constr_mip[127][:sense] == :(>=) - @test m.internalModel.bounding_constr_mip[127][:coefs] == Any[-1.0] - @test m.internalModel.bounding_constr_mip[127][:cnt] == 1 - - @test m.internalModel.bounding_constr_mip[187][:rhs] == 1.0 - @test m.internalModel.bounding_constr_mip[187][:vars] == Any[:(x[79]), :(x[94])] - @test m.internalModel.bounding_constr_mip[187][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[187][:coefs] == Any[1.0, 1.0] - @test m.internalModel.bounding_constr_mip[187][:cnt] == 2 - - @test m.internalModel.bounding_constr_mip[202][:rhs] == 0.04 - @test m.internalModel.bounding_constr_mip[202][:vars] == Any[:(x[103]), :(x[1]), :(x[13]), :(x[25]), :(x[28]), :(x[31])] - @test m.internalModel.bounding_constr_mip[202][:sense] == :(==) - @test m.internalModel.bounding_constr_mip[202][:coefs] == Any[1.0, -0.6, -0.2, 0.2, 0.2, 0.2] - @test m.internalModel.bounding_constr_mip[202][:cnt] == 6 - - @test m.internalModel.nonconvex_terms[[:(x[37]), :(x[55])]][:id] == 1 - @test m.internalModel.nonconvex_terms[[:(x[37]), :(x[55])]][:lifted_var_ref] == :(x[103]) - @test m.internalModel.nonconvex_terms[[:(x[37]), :(x[55])]][:convexified] == false - @test m.internalModel.nonconvex_terms[[:(x[37]), :(x[55])]][:nonlinear_type] == :BILINEAR - - @test m.internalModel.bounding_constr_mip[206][:rhs] == 0.0 - @test m.internalModel.bounding_constr_mip[206][:vars] == Any[:(x[107]), :(x[103]), :(x[108]), :(x[109]), :(x[110]), :(x[2]), :(x[14])] - @test m.internalModel.bounding_constr_mip[206][:sense] == :(==) - @test m.internalModel.bounding_constr_mip[206][:coefs] == Any[1.0, -1.0, 1.0, 1.0, 1.0, -0.6, -0.2] - @test m.internalModel.bounding_constr_mip[206][:cnt] == 7 - - @test m.internalModel.nonconvex_terms[[:(x[38]), :(x[56])]][:id] == 5 - @test m.internalModel.nonconvex_terms[[:(x[38]), :(x[56])]][:lifted_var_ref] == :(x[107]) - @test m.internalModel.nonconvex_terms[[:(x[38]), :(x[56])]][:convexified] == false - @test m.internalModel.nonconvex_terms[[:(x[38]), :(x[56])]][:nonlinear_type] == :BILINEAR - - @test m.internalModel.nonconvex_terms[[:(x[37]), :(x[26])]][:id] == 6 - @test m.internalModel.nonconvex_terms[[:(x[37]), :(x[26])]][:lifted_var_ref] == :(x[108]) - @test m.internalModel.nonconvex_terms[[:(x[37]), :(x[26])]][:convexified] == false - @test m.internalModel.nonconvex_terms[[:(x[37]), :(x[26])]][:nonlinear_type] == :BILINEAR - - @test m.internalModel.nonconvex_terms[[:(x[37]), :(x[32])]][:id] == 8 - @test m.internalModel.nonconvex_terms[[:(x[37]), :(x[32])]][:lifted_var_ref] == :(x[110]) - @test m.internalModel.nonconvex_terms[[:(x[37]), :(x[32])]][:convexified] == false - @test m.internalModel.nonconvex_terms[[:(x[37]), :(x[32])]][:nonlinear_type] == :BILINEAR - - @test m.internalModel.bounding_constr_mip[213][:rhs] == 0.0 - @test m.internalModel.bounding_constr_mip[213][:vars] == Any[:(x[129]), :(x[127]), :(x[124]), :(x[130]), :(x[6]), :(x[18])] - @test m.internalModel.bounding_constr_mip[213][:sense] == :(==) - @test m.internalModel.bounding_constr_mip[213][:coefs] == Any[1.0, -1.0, -1.0, 1.0, -0.4, -0.4] - @test m.internalModel.bounding_constr_mip[213][:cnt] == 6 - - @test m.internalModel.nonconvex_terms[[:(x[48]), :(x[60])]][:id] == 27 - @test m.internalModel.nonconvex_terms[[:(x[48]), :(x[60])]][:lifted_var_ref] == :(x[129]) - @test m.internalModel.nonconvex_terms[[:(x[48]), :(x[60])]][:convexified] == false - @test m.internalModel.nonconvex_terms[[:(x[48]), :(x[60])]][:nonlinear_type] == :BILINEAR - - @test m.internalModel.nonconvex_terms[[:(x[47]), :(x[59])]][:id] == 25 - @test m.internalModel.nonconvex_terms[[:(x[47]), :(x[59])]][:lifted_var_ref] == :(x[127]) - @test m.internalModel.nonconvex_terms[[:(x[47]), :(x[59])]][:convexified] == false - @test m.internalModel.nonconvex_terms[[:(x[47]), :(x[59])]][:nonlinear_type] == :BILINEAR - - @test m.internalModel.nonconvex_terms[[:(x[47]), :(x[36])]][:id] == 28 - @test m.internalModel.nonconvex_terms[[:(x[47]), :(x[36])]][:lifted_var_ref] == :(x[130]) - @test m.internalModel.nonconvex_terms[[:(x[47]), :(x[36])]][:convexified] == false - @test m.internalModel.nonconvex_terms[[:(x[47]), :(x[36])]][:nonlinear_type] == :BILINEAR + alpine = _build(m) # Setup internal model + + @test length(keys(alpine.nonconvex_terms)) == 28 + @test haskey(alpine.nonconvex_terms, [Expr(:ref, :x, 37), Expr(:ref, :x, 55)]) + @test haskey(alpine.nonconvex_terms, [Expr(:ref, :x, 38), Expr(:ref, :x, 56)]) + @test haskey(alpine.nonconvex_terms, [Expr(:ref, :x, 37), Expr(:ref, :x, 26)]) + @test haskey(alpine.nonconvex_terms, [Expr(:ref, :x, 43), Expr(:ref, :x, 26)]) + @test haskey(alpine.nonconvex_terms, [Expr(:ref, :x, 47), Expr(:ref, :x, 59)]) + @test haskey(alpine.nonconvex_terms, [Expr(:ref, :x, 48), Expr(:ref, :x, 60)]) + @test haskey(alpine.nonconvex_terms, [Expr(:ref, :x, 47), Expr(:ref, :x, 36)]) + + @test alpine.bounding_constr_mip[1][:rhs] == 1.0 + @test alpine.bounding_constr_mip[1][:vars] == Any[:(x[1]), :(x[4]), :(x[7]), :(x[10]), :(x[49])] + @test alpine.bounding_constr_mip[1][:sense] == :(==) + @test alpine.bounding_constr_mip[1][:coefs] == Any[1.0, 1.0, 1.0, 1.0, 1.0] + @test alpine.bounding_constr_mip[1][:cnt] == 5 + + @test alpine.bounding_constr_mip[4][:rhs] == 0.1 + @test alpine.bounding_constr_mip[4][:vars] == Any[:(x[4]), :(x[16]), :(x[25]), :(x[34]), :(x[58])] + @test alpine.bounding_constr_mip[4][:sense] == :(==) + @test alpine.bounding_constr_mip[4][:coefs] == Any[-1.0, -1.0, -1.0, 1.0, 1.0] + @test alpine.bounding_constr_mip[4][:cnt] == 5 + + @test alpine.bounding_constr_mip[17][:rhs] == -0.14 + @test alpine.bounding_constr_mip[17][:vars] == Any[:(x[11]), :(x[23]), :(x[32]), :(x[64]), :(x[65])] + @test alpine.bounding_constr_mip[17][:sense] == :(==) + @test alpine.bounding_constr_mip[17][:coefs] == Any[-1.0, -1.0, -1.0, -1.0, 1.0] + @test alpine.bounding_constr_mip[17][:cnt] == 5 + + @test alpine.bounding_constr_mip[31][:rhs] == 0.0 + @test alpine.bounding_constr_mip[31][:vars] == Any[:(x[13])] + @test alpine.bounding_constr_mip[31][:sense] == :(>=) + @test alpine.bounding_constr_mip[31][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[31][:cnt] == 1 + + @test alpine.bounding_constr_mip[145][:rhs] == 1.0 + @test alpine.bounding_constr_mip[145][:vars] == Any[:(x[73])] + @test alpine.bounding_constr_mip[145][:sense] == :(<=) + @test alpine.bounding_constr_mip[145][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[145][:cnt] == 1 + + @test alpine.bounding_constr_mip[67][:rhs] == -1.0 + @test alpine.bounding_constr_mip[67][:vars] == Any[:(x[73])] + @test alpine.bounding_constr_mip[67][:sense] == :(>=) + @test alpine.bounding_constr_mip[67][:coefs] == Any[-1.0] + @test alpine.bounding_constr_mip[67][:cnt] == 1 + + @test alpine.bounding_constr_mip[187][:rhs] == 1.0 + @test alpine.bounding_constr_mip[187][:vars] == Any[:(x[79]), :(x[94])] + @test alpine.bounding_constr_mip[187][:sense] == :(<=) + @test alpine.bounding_constr_mip[187][:coefs] == Any[1.0, 1.0] + @test alpine.bounding_constr_mip[187][:cnt] == 2 + + @test alpine.bounding_constr_mip[202][:rhs] == 0.04 + @test alpine.bounding_constr_mip[202][:vars] == Any[:(x[103]), :(x[1]), :(x[13]), :(x[25]), :(x[28]), :(x[31])] + @test alpine.bounding_constr_mip[202][:sense] == :(==) + @test alpine.bounding_constr_mip[202][:coefs] == Any[1.0, -0.6, -0.2, 0.2, 0.2, 0.2] + @test alpine.bounding_constr_mip[202][:cnt] == 6 + + @test alpine.nonconvex_terms[[:(x[37]), :(x[55])]][:id] == 1 + @test alpine.nonconvex_terms[[:(x[37]), :(x[55])]][:lifted_var_ref] == :(x[103]) + @test alpine.nonconvex_terms[[:(x[37]), :(x[55])]][:convexified] == false + @test alpine.nonconvex_terms[[:(x[37]), :(x[55])]][:nonlinear_type] == :BILINEAR + + @test alpine.bounding_constr_mip[206][:rhs] == 0.0 + @test alpine.bounding_constr_mip[206][:vars] == Any[:(x[107]), :(x[103]), :(x[108]), :(x[109]), :(x[110]), :(x[2]), :(x[14])] + @test alpine.bounding_constr_mip[206][:sense] == :(==) + @test alpine.bounding_constr_mip[206][:coefs] == Any[1.0, -1.0, 1.0, 1.0, 1.0, -0.6, -0.2] + @test alpine.bounding_constr_mip[206][:cnt] == 7 + + @test alpine.nonconvex_terms[[:(x[38]), :(x[56])]][:id] == 5 + @test alpine.nonconvex_terms[[:(x[38]), :(x[56])]][:lifted_var_ref] == :(x[107]) + @test alpine.nonconvex_terms[[:(x[38]), :(x[56])]][:convexified] == false + @test alpine.nonconvex_terms[[:(x[38]), :(x[56])]][:nonlinear_type] == :BILINEAR + + @test alpine.nonconvex_terms[[:(x[37]), :(x[26])]][:id] == 6 + @test alpine.nonconvex_terms[[:(x[37]), :(x[26])]][:lifted_var_ref] == :(x[108]) + @test alpine.nonconvex_terms[[:(x[37]), :(x[26])]][:convexified] == false + @test alpine.nonconvex_terms[[:(x[37]), :(x[26])]][:nonlinear_type] == :BILINEAR + + @test alpine.nonconvex_terms[[:(x[37]), :(x[32])]][:id] == 8 + @test alpine.nonconvex_terms[[:(x[37]), :(x[32])]][:lifted_var_ref] == :(x[110]) + @test alpine.nonconvex_terms[[:(x[37]), :(x[32])]][:convexified] == false + @test alpine.nonconvex_terms[[:(x[37]), :(x[32])]][:nonlinear_type] == :BILINEAR + + @test alpine.bounding_constr_mip[213][:rhs] == 0.0 + @test alpine.bounding_constr_mip[213][:vars] == Any[:(x[129]), :(x[127]), :(x[124]), :(x[130]), :(x[6]), :(x[18])] + @test alpine.bounding_constr_mip[213][:sense] == :(==) + @test alpine.bounding_constr_mip[213][:coefs] == Any[1.0, -1.0, -1.0, 1.0, -0.4, -0.4] + @test alpine.bounding_constr_mip[213][:cnt] == 6 + + @test alpine.nonconvex_terms[[:(x[48]), :(x[60])]][:id] == 27 + @test alpine.nonconvex_terms[[:(x[48]), :(x[60])]][:lifted_var_ref] == :(x[129]) + @test alpine.nonconvex_terms[[:(x[48]), :(x[60])]][:convexified] == false + @test alpine.nonconvex_terms[[:(x[48]), :(x[60])]][:nonlinear_type] == :BILINEAR + + @test alpine.nonconvex_terms[[:(x[47]), :(x[59])]][:id] == 25 + @test alpine.nonconvex_terms[[:(x[47]), :(x[59])]][:lifted_var_ref] == :(x[127]) + @test alpine.nonconvex_terms[[:(x[47]), :(x[59])]][:convexified] == false + @test alpine.nonconvex_terms[[:(x[47]), :(x[59])]][:nonlinear_type] == :BILINEAR + + @test alpine.nonconvex_terms[[:(x[47]), :(x[36])]][:id] == 28 + @test alpine.nonconvex_terms[[:(x[47]), :(x[36])]][:lifted_var_ref] == :(x[130]) + @test alpine.nonconvex_terms[[:(x[47]), :(x[36])]][:convexified] == false + @test alpine.nonconvex_terms[[:(x[47]), :(x[36])]][:nonlinear_type] == :BILINEAR end @testset "Expression Parsing || multilinear || Simple || multi.jl " begin - test_solver = AlpineSolver(nlp_solver=IpoptSolver(print_level=0, sb="yes"),mip_solver=CbcSolver(logLevel=0),loglevel=100) + test_solver = optimizer_with_attributes(Alpine.Optimizer,"nlp_solver" => IPOPT_SB,"mip_solver" => CBC,"loglevel" => 100) m = multi3(solver=test_solver, exprmode=1) - JuMP.build(m) # Setup internal model + alpine = _build(m) # Setup internal model - @test length(keys(m.internalModel.nonconvex_terms)) == 1 - @test m.internalModel.nonconvex_terms[[:(x[1]), :(x[2]), :(x[3])]][:id] == 1 - @test m.internalModel.nonconvex_terms[[:(x[1]), :(x[2]), :(x[3])]][:lifted_var_ref] == :(x[4]) - @test m.internalModel.nonconvex_terms[[:(x[1]), :(x[2]), :(x[3])]][:nonlinear_type] == :MULTILINEAR + @test length(keys(alpine.nonconvex_terms)) == 1 + @test alpine.nonconvex_terms[[:(x[1]), :(x[2]), :(x[3])]][:id] == 1 + @test alpine.nonconvex_terms[[:(x[1]), :(x[2]), :(x[3])]][:lifted_var_ref] == :(x[4]) + @test alpine.nonconvex_terms[[:(x[1]), :(x[2]), :(x[3])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.bounding_obj_mip[:rhs] == 0 - @test m.internalModel.bounding_obj_mip[:vars] == Expr[:(x[4])] - @test m.internalModel.bounding_obj_mip[:coefs] == [1.0] - @test m.internalModel.bounding_obj_mip[:cnt] == 1 - @test m.internalModel.bounding_obj_mip[:sense] == nothing + @test alpine.bounding_obj_mip[:rhs] == 0 + @test alpine.bounding_obj_mip[:vars] == Expr[:(x[4])] + @test alpine.bounding_obj_mip[:coefs] == [1.0] + @test alpine.bounding_obj_mip[:cnt] == 1 + @test alpine.bounding_obj_mip[:sense] == nothing - @test m.internalModel.bounding_constr_mip[1][:rhs] == 3.0 - @test m.internalModel.bounding_constr_mip[1][:vars] == Any[:(x[1]), :(x[2]), :(x[3])] - @test m.internalModel.bounding_constr_mip[1][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[1][:coefs] == Any[1.0, 1.0, 1.0] - @test m.internalModel.bounding_constr_mip[1][:cnt] == 3 + @test alpine.bounding_constr_mip[1][:rhs] == 3.0 + @test alpine.bounding_constr_mip[1][:vars] == Any[:(x[1]), :(x[2]), :(x[3])] + @test alpine.bounding_constr_mip[1][:sense] == :(<=) + @test alpine.bounding_constr_mip[1][:coefs] == Any[1.0, 1.0, 1.0] + @test alpine.bounding_constr_mip[1][:cnt] == 3 m = multi3(solver=test_solver, exprmode=2) - JuMP.build(m) + alpine = _build(m) - @test length(keys(m.internalModel.nonconvex_terms)) == 2 - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 2)]][:id] == 1 - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 2)]][:lifted_var_ref] == :(x[4]) - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 2)]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 4), Expr(:ref, :x, 3)]][:id] == 2 - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 4), Expr(:ref, :x, 3)]][:lifted_var_ref] == :(x[5]) - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 4), Expr(:ref, :x, 3)]][:nonlinear_type] == :BILINEAR + @test length(keys(alpine.nonconvex_terms)) == 2 + @test alpine.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 2)]][:id] == 1 + @test alpine.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 2)]][:lifted_var_ref] == :(x[4]) + @test alpine.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 2)]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[[Expr(:ref, :x, 4), Expr(:ref, :x, 3)]][:id] == 2 + @test alpine.nonconvex_terms[[Expr(:ref, :x, 4), Expr(:ref, :x, 3)]][:lifted_var_ref] == :(x[5]) + @test alpine.nonconvex_terms[[Expr(:ref, :x, 4), Expr(:ref, :x, 3)]][:nonlinear_type] == :BILINEAR - @test m.internalModel.bounding_obj_mip[:rhs] == 0 - @test m.internalModel.bounding_obj_mip[:vars] == Expr[:(x[5])] - @test m.internalModel.bounding_obj_mip[:coefs] == [1.0] - @test m.internalModel.bounding_obj_mip[:cnt] == 1 - @test m.internalModel.bounding_obj_mip[:sense] == nothing + @test alpine.bounding_obj_mip[:rhs] == 0 + @test alpine.bounding_obj_mip[:vars] == Expr[:(x[5])] + @test alpine.bounding_obj_mip[:coefs] == [1.0] + @test alpine.bounding_obj_mip[:cnt] == 1 + @test alpine.bounding_obj_mip[:sense] == nothing m = multi3(solver=test_solver, exprmode=3) - JuMP.build(m) + alpine = _build(m) - @test length(keys(m.internalModel.nonconvex_terms)) == 2 - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 2), Expr(:ref, :x, 3)]][:id] == 1 - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 2), Expr(:ref, :x, 3)]][:lifted_var_ref] == :(x[4]) - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 2), Expr(:ref, :x, 3)]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 4)]][:id] == 2 - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 4)]][:lifted_var_ref] == :(x[5]) - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 4)]][:nonlinear_type] == :BILINEAR + @test length(keys(alpine.nonconvex_terms)) == 2 + @test alpine.nonconvex_terms[[Expr(:ref, :x, 2), Expr(:ref, :x, 3)]][:id] == 1 + @test alpine.nonconvex_terms[[Expr(:ref, :x, 2), Expr(:ref, :x, 3)]][:lifted_var_ref] == :(x[4]) + @test alpine.nonconvex_terms[[Expr(:ref, :x, 2), Expr(:ref, :x, 3)]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 4)]][:id] == 2 + @test alpine.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 4)]][:lifted_var_ref] == :(x[5]) + @test alpine.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 4)]][:nonlinear_type] == :BILINEAR - @test m.internalModel.bounding_obj_mip[:rhs] == 0 - @test m.internalModel.bounding_obj_mip[:vars] == Expr[:(x[5])] - @test m.internalModel.bounding_obj_mip[:coefs] == [1.0] - @test m.internalModel.bounding_obj_mip[:cnt] == 1 - @test m.internalModel.bounding_obj_mip[:sense] == nothing + @test alpine.bounding_obj_mip[:rhs] == 0 + @test alpine.bounding_obj_mip[:vars] == Expr[:(x[5])] + @test alpine.bounding_obj_mip[:coefs] == [1.0] + @test alpine.bounding_obj_mip[:cnt] == 1 + @test alpine.bounding_obj_mip[:sense] == nothing m = multi4(solver=test_solver, exprmode=1) - JuMP.build(m) + alpine = _build(m) - @test length(keys(m.internalModel.nonconvex_terms)) == 1 + @test length(keys(alpine.nonconvex_terms)) == 1 - @test m.internalModel.bounding_obj_mip[:rhs] == 0 - @test m.internalModel.bounding_obj_mip[:vars] == Expr[:(x[5])] - @test m.internalModel.bounding_obj_mip[:coefs] == [1.0] - @test m.internalModel.bounding_obj_mip[:cnt] == 1 - @test m.internalModel.bounding_obj_mip[:sense] == nothing + @test alpine.bounding_obj_mip[:rhs] == 0 + @test alpine.bounding_obj_mip[:vars] == Expr[:(x[5])] + @test alpine.bounding_obj_mip[:coefs] == [1.0] + @test alpine.bounding_obj_mip[:cnt] == 1 + @test alpine.bounding_obj_mip[:sense] == nothing - @test m.internalModel.nonconvex_terms[[:(x[1]), :(x[2]), :(x[3]), :(x[4])]][:id] == 1 - @test m.internalModel.nonconvex_terms[[:(x[1]), :(x[2]), :(x[3]), :(x[4])]][:lifted_var_ref] == :(x[5]) - @test m.internalModel.nonconvex_terms[[:(x[1]), :(x[2]), :(x[3]), :(x[4])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[[:(x[1]), :(x[2]), :(x[3]), :(x[4])]][:id] == 1 + @test alpine.nonconvex_terms[[:(x[1]), :(x[2]), :(x[3]), :(x[4])]][:lifted_var_ref] == :(x[5]) + @test alpine.nonconvex_terms[[:(x[1]), :(x[2]), :(x[3]), :(x[4])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.bounding_constr_mip[1][:rhs] == 4.0 - @test m.internalModel.bounding_constr_mip[1][:vars] == Any[:(x[1]), :(x[2]), :(x[3]), :(x[4])] - @test m.internalModel.bounding_constr_mip[1][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[1][:coefs] == Any[1.0, 1.0, 1.0, 1.0] - @test m.internalModel.bounding_constr_mip[1][:cnt] == 4 + @test alpine.bounding_constr_mip[1][:rhs] == 4.0 + @test alpine.bounding_constr_mip[1][:vars] == Any[:(x[1]), :(x[2]), :(x[3]), :(x[4])] + @test alpine.bounding_constr_mip[1][:sense] == :(<=) + @test alpine.bounding_constr_mip[1][:coefs] == Any[1.0, 1.0, 1.0, 1.0] + @test alpine.bounding_constr_mip[1][:cnt] == 4 m = multi4(solver=test_solver, exprmode=2) - JuMP.build(m) + alpine = _build(m) - @test length(keys(m.internalModel.nonconvex_terms)) == 3 + @test length(keys(alpine.nonconvex_terms)) == 3 - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 2)]][:id] == 1 - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 2)]][:lifted_var_ref] == :(x[5]) - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 2)]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 3), Expr(:ref, :x, 4)]][:id] == 2 - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 3), Expr(:ref, :x, 4)]][:lifted_var_ref] == :(x[6]) - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 3), Expr(:ref, :x, 4)]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 5), Expr(:ref, :x, 6)]][:id] == 3 - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 5), Expr(:ref, :x, 6)]][:lifted_var_ref] == :(x[7]) - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 5), Expr(:ref, :x, 6)]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 2)]][:id] == 1 + @test alpine.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 2)]][:lifted_var_ref] == :(x[5]) + @test alpine.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 2)]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[[Expr(:ref, :x, 3), Expr(:ref, :x, 4)]][:id] == 2 + @test alpine.nonconvex_terms[[Expr(:ref, :x, 3), Expr(:ref, :x, 4)]][:lifted_var_ref] == :(x[6]) + @test alpine.nonconvex_terms[[Expr(:ref, :x, 3), Expr(:ref, :x, 4)]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[[Expr(:ref, :x, 5), Expr(:ref, :x, 6)]][:id] == 3 + @test alpine.nonconvex_terms[[Expr(:ref, :x, 5), Expr(:ref, :x, 6)]][:lifted_var_ref] == :(x[7]) + @test alpine.nonconvex_terms[[Expr(:ref, :x, 5), Expr(:ref, :x, 6)]][:nonlinear_type] == :BILINEAR - @test m.internalModel.bounding_obj_mip[:rhs] == 0 - @test m.internalModel.bounding_obj_mip[:vars] == Expr[:(x[7])] - @test m.internalModel.bounding_obj_mip[:coefs] == [1.0] - @test m.internalModel.bounding_obj_mip[:cnt] == 1 - @test m.internalModel.bounding_obj_mip[:sense] == nothing + @test alpine.bounding_obj_mip[:rhs] == 0 + @test alpine.bounding_obj_mip[:vars] == Expr[:(x[7])] + @test alpine.bounding_obj_mip[:coefs] == [1.0] + @test alpine.bounding_obj_mip[:cnt] == 1 + @test alpine.bounding_obj_mip[:sense] == nothing m = multi4(solver=test_solver, exprmode=3) - JuMP.build(m) + alpine = _build(m) - @test length(keys(m.internalModel.nonconvex_terms)) == 2 + @test length(keys(alpine.nonconvex_terms)) == 2 - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 2)]][:id] == 1 - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 2)]][:lifted_var_ref] == :(x[5]) - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 2)]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[[:(x[5]), :(x[3]), :(x[4])]][:id] == 2 - @test m.internalModel.nonconvex_terms[[:(x[5]), :(x[3]), :(x[4])]][:lifted_var_ref] == :(x[6]) - @test m.internalModel.nonconvex_terms[[:(x[5]), :(x[3]), :(x[4])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 2)]][:id] == 1 + @test alpine.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 2)]][:lifted_var_ref] == :(x[5]) + @test alpine.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 2)]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[[:(x[5]), :(x[3]), :(x[4])]][:id] == 2 + @test alpine.nonconvex_terms[[:(x[5]), :(x[3]), :(x[4])]][:lifted_var_ref] == :(x[6]) + @test alpine.nonconvex_terms[[:(x[5]), :(x[3]), :(x[4])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.bounding_obj_mip[:rhs] == 0 - @test m.internalModel.bounding_obj_mip[:vars] == Expr[:(x[6])] - @test m.internalModel.bounding_obj_mip[:coefs] == [1.0] - @test m.internalModel.bounding_obj_mip[:cnt] == 1 - @test m.internalModel.bounding_obj_mip[:sense] == nothing + @test alpine.bounding_obj_mip[:rhs] == 0 + @test alpine.bounding_obj_mip[:vars] == Expr[:(x[6])] + @test alpine.bounding_obj_mip[:coefs] == [1.0] + @test alpine.bounding_obj_mip[:cnt] == 1 + @test alpine.bounding_obj_mip[:sense] == nothing m = multi4(solver=test_solver, exprmode=4) - JuMP.build(m) + alpine = _build(m) - @test length(keys(m.internalModel.nonconvex_terms)) == 2 + @test length(keys(alpine.nonconvex_terms)) == 2 - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 3), Expr(:ref, :x, 4)]][:id] == 1 - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 3), Expr(:ref, :x, 4)]][:lifted_var_ref] == :(x[5]) - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 3), Expr(:ref, :x, 4)]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[[:(x[1]), :(x[2]), :(x[5])]][:id] == 2 - @test m.internalModel.nonconvex_terms[[:(x[1]), :(x[2]), :(x[5])]][:lifted_var_ref] == :(x[6]) - @test m.internalModel.nonconvex_terms[[:(x[1]), :(x[2]), :(x[5])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[[Expr(:ref, :x, 3), Expr(:ref, :x, 4)]][:id] == 1 + @test alpine.nonconvex_terms[[Expr(:ref, :x, 3), Expr(:ref, :x, 4)]][:lifted_var_ref] == :(x[5]) + @test alpine.nonconvex_terms[[Expr(:ref, :x, 3), Expr(:ref, :x, 4)]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[[:(x[1]), :(x[2]), :(x[5])]][:id] == 2 + @test alpine.nonconvex_terms[[:(x[1]), :(x[2]), :(x[5])]][:lifted_var_ref] == :(x[6]) + @test alpine.nonconvex_terms[[:(x[1]), :(x[2]), :(x[5])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.bounding_obj_mip[:rhs] == 0 - @test m.internalModel.bounding_obj_mip[:vars] == Expr[:(x[6])] - @test m.internalModel.bounding_obj_mip[:coefs] == [1.0] - @test m.internalModel.bounding_obj_mip[:cnt] == 1 - @test m.internalModel.bounding_obj_mip[:sense] == nothing + @test alpine.bounding_obj_mip[:rhs] == 0 + @test alpine.bounding_obj_mip[:vars] == Expr[:(x[6])] + @test alpine.bounding_obj_mip[:coefs] == [1.0] + @test alpine.bounding_obj_mip[:cnt] == 1 + @test alpine.bounding_obj_mip[:sense] == nothing - @test m.internalModel.bounding_obj_mip[:rhs] == 0 - @test m.internalModel.bounding_obj_mip[:vars] == Expr[:(x[6])] - @test m.internalModel.bounding_obj_mip[:coefs] == [1.0] - @test m.internalModel.bounding_obj_mip[:cnt] == 1 - @test m.internalModel.bounding_obj_mip[:sense] == nothing + @test alpine.bounding_obj_mip[:rhs] == 0 + @test alpine.bounding_obj_mip[:vars] == Expr[:(x[6])] + @test alpine.bounding_obj_mip[:coefs] == [1.0] + @test alpine.bounding_obj_mip[:cnt] == 1 + @test alpine.bounding_obj_mip[:sense] == nothing m = multi4(solver=test_solver, exprmode=5) - JuMP.build(m) + alpine = _build(m) - @test length(keys(m.internalModel.nonconvex_terms)) == 3 + @test length(keys(alpine.nonconvex_terms)) == 3 - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 2)]][:id] == 1 - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 2)]][:lifted_var_ref] == :(x[5]) - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 2)]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 3), Expr(:ref, :x, 5)]][:id] == 2 - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 3), Expr(:ref, :x, 5)]][:lifted_var_ref] == :(x[6]) - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 3), Expr(:ref, :x, 5)]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 6), Expr(:ref, :x, 4)]][:id] == 3 - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 6), Expr(:ref, :x, 4)]][:lifted_var_ref] == :(x[7]) - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 6), Expr(:ref, :x, 4)]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 2)]][:id] == 1 + @test alpine.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 2)]][:lifted_var_ref] == :(x[5]) + @test alpine.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 2)]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[[Expr(:ref, :x, 3), Expr(:ref, :x, 5)]][:id] == 2 + @test alpine.nonconvex_terms[[Expr(:ref, :x, 3), Expr(:ref, :x, 5)]][:lifted_var_ref] == :(x[6]) + @test alpine.nonconvex_terms[[Expr(:ref, :x, 3), Expr(:ref, :x, 5)]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[[Expr(:ref, :x, 6), Expr(:ref, :x, 4)]][:id] == 3 + @test alpine.nonconvex_terms[[Expr(:ref, :x, 6), Expr(:ref, :x, 4)]][:lifted_var_ref] == :(x[7]) + @test alpine.nonconvex_terms[[Expr(:ref, :x, 6), Expr(:ref, :x, 4)]][:nonlinear_type] == :BILINEAR - @test m.internalModel.bounding_obj_mip[:rhs] == 0 - @test m.internalModel.bounding_obj_mip[:vars] == Expr[:(x[7])] - @test m.internalModel.bounding_obj_mip[:coefs] == [1.0] - @test m.internalModel.bounding_obj_mip[:cnt] == 1 - @test m.internalModel.bounding_obj_mip[:sense] == nothing + @test alpine.bounding_obj_mip[:rhs] == 0 + @test alpine.bounding_obj_mip[:vars] == Expr[:(x[7])] + @test alpine.bounding_obj_mip[:coefs] == [1.0] + @test alpine.bounding_obj_mip[:cnt] == 1 + @test alpine.bounding_obj_mip[:sense] == nothing - @test m.internalModel.bounding_obj_mip[:rhs] == 0 - @test m.internalModel.bounding_obj_mip[:vars] == Expr[:(x[7])] - @test m.internalModel.bounding_obj_mip[:coefs] == [1.0] - @test m.internalModel.bounding_obj_mip[:cnt] == 1 - @test m.internalModel.bounding_obj_mip[:sense] == nothing + @test alpine.bounding_obj_mip[:rhs] == 0 + @test alpine.bounding_obj_mip[:vars] == Expr[:(x[7])] + @test alpine.bounding_obj_mip[:coefs] == [1.0] + @test alpine.bounding_obj_mip[:cnt] == 1 + @test alpine.bounding_obj_mip[:sense] == nothing m = multi4(solver=test_solver, exprmode=6) - JuMP.build(m) + alpine = _build(m) - @test length(keys(m.internalModel.nonconvex_terms)) == 2 + @test length(keys(alpine.nonconvex_terms)) == 2 - @test m.internalModel.nonconvex_terms[[:(x[1]), :(x[2]), :(x[3])]][:id] == 1 - @test m.internalModel.nonconvex_terms[[:(x[1]), :(x[2]), :(x[3])]][:lifted_var_ref] == :(x[5]) - @test m.internalModel.nonconvex_terms[[:(x[1]), :(x[2]), :(x[3])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 5), Expr(:ref, :x, 4)]][:id] == 2 - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 5), Expr(:ref, :x, 4)]][:lifted_var_ref] == :(x[6]) - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 5), Expr(:ref, :x, 4)]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[[:(x[1]), :(x[2]), :(x[3])]][:id] == 1 + @test alpine.nonconvex_terms[[:(x[1]), :(x[2]), :(x[3])]][:lifted_var_ref] == :(x[5]) + @test alpine.nonconvex_terms[[:(x[1]), :(x[2]), :(x[3])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[[Expr(:ref, :x, 5), Expr(:ref, :x, 4)]][:id] == 2 + @test alpine.nonconvex_terms[[Expr(:ref, :x, 5), Expr(:ref, :x, 4)]][:lifted_var_ref] == :(x[6]) + @test alpine.nonconvex_terms[[Expr(:ref, :x, 5), Expr(:ref, :x, 4)]][:nonlinear_type] == :BILINEAR - @test m.internalModel.bounding_obj_mip[:rhs] == 0 - @test m.internalModel.bounding_obj_mip[:vars] == Expr[:(x[6])] - @test m.internalModel.bounding_obj_mip[:coefs] == [1.0] - @test m.internalModel.bounding_obj_mip[:cnt] == 1 - @test m.internalModel.bounding_obj_mip[:sense] == nothing + @test alpine.bounding_obj_mip[:rhs] == 0 + @test alpine.bounding_obj_mip[:vars] == Expr[:(x[6])] + @test alpine.bounding_obj_mip[:coefs] == [1.0] + @test alpine.bounding_obj_mip[:cnt] == 1 + @test alpine.bounding_obj_mip[:sense] == nothing m = multi4(solver=test_solver, exprmode=7) - JuMP.build(m) + alpine = _build(m) - @test length(keys(m.internalModel.nonconvex_terms)) == 3 + @test length(keys(alpine.nonconvex_terms)) == 3 - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 3), Expr(:ref, :x, 4)]][:id] == 1 - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 3), Expr(:ref, :x, 4)]][:lifted_var_ref] == :(x[5]) - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 3), Expr(:ref, :x, 4)]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 2), Expr(:ref, :x, 5)]][:id] == 2 - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 2), Expr(:ref, :x, 5)]][:lifted_var_ref] == :(x[6]) - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 2), Expr(:ref, :x, 5)]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 6)]][:id] == 3 - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 6)]][:lifted_var_ref] == :(x[7]) - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 6)]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[[Expr(:ref, :x, 3), Expr(:ref, :x, 4)]][:id] == 1 + @test alpine.nonconvex_terms[[Expr(:ref, :x, 3), Expr(:ref, :x, 4)]][:lifted_var_ref] == :(x[5]) + @test alpine.nonconvex_terms[[Expr(:ref, :x, 3), Expr(:ref, :x, 4)]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[[Expr(:ref, :x, 2), Expr(:ref, :x, 5)]][:id] == 2 + @test alpine.nonconvex_terms[[Expr(:ref, :x, 2), Expr(:ref, :x, 5)]][:lifted_var_ref] == :(x[6]) + @test alpine.nonconvex_terms[[Expr(:ref, :x, 2), Expr(:ref, :x, 5)]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 6)]][:id] == 3 + @test alpine.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 6)]][:lifted_var_ref] == :(x[7]) + @test alpine.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 6)]][:nonlinear_type] == :BILINEAR - @test m.internalModel.bounding_obj_mip[:rhs] == 0 - @test m.internalModel.bounding_obj_mip[:vars] == Expr[:(x[7])] - @test m.internalModel.bounding_obj_mip[:coefs] == [1.0] - @test m.internalModel.bounding_obj_mip[:cnt] == 1 - @test m.internalModel.bounding_obj_mip[:sense] == nothing + @test alpine.bounding_obj_mip[:rhs] == 0 + @test alpine.bounding_obj_mip[:vars] == Expr[:(x[7])] + @test alpine.bounding_obj_mip[:coefs] == [1.0] + @test alpine.bounding_obj_mip[:cnt] == 1 + @test alpine.bounding_obj_mip[:sense] == nothing m = multi4(solver=test_solver, exprmode=8) - JuMP.build(m) + alpine = _build(m) - @test length(keys(m.internalModel.nonconvex_terms)) == 2 + @test length(keys(alpine.nonconvex_terms)) == 2 - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 2), Expr(:ref, :x, 3)]][:id] == 1 - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 2), Expr(:ref, :x, 3)]][:lifted_var_ref] == :(x[5]) - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 2), Expr(:ref, :x, 3)]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[[:(x[1]), :(x[5]), :(x[4])]][:id] == 2 - @test m.internalModel.nonconvex_terms[[:(x[1]), :(x[5]), :(x[4])]][:lifted_var_ref] == :(x[6]) - @test m.internalModel.nonconvex_terms[[:(x[1]), :(x[5]), :(x[4])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[[Expr(:ref, :x, 2), Expr(:ref, :x, 3)]][:id] == 1 + @test alpine.nonconvex_terms[[Expr(:ref, :x, 2), Expr(:ref, :x, 3)]][:lifted_var_ref] == :(x[5]) + @test alpine.nonconvex_terms[[Expr(:ref, :x, 2), Expr(:ref, :x, 3)]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[[:(x[1]), :(x[5]), :(x[4])]][:id] == 2 + @test alpine.nonconvex_terms[[:(x[1]), :(x[5]), :(x[4])]][:lifted_var_ref] == :(x[6]) + @test alpine.nonconvex_terms[[:(x[1]), :(x[5]), :(x[4])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.bounding_obj_mip[:rhs] == 0 - @test m.internalModel.bounding_obj_mip[:vars] == Expr[:(x[6])] - @test m.internalModel.bounding_obj_mip[:coefs] == [1.0] - @test m.internalModel.bounding_obj_mip[:cnt] == 1 - @test m.internalModel.bounding_obj_mip[:sense] == nothing + @test alpine.bounding_obj_mip[:rhs] == 0 + @test alpine.bounding_obj_mip[:vars] == Expr[:(x[6])] + @test alpine.bounding_obj_mip[:coefs] == [1.0] + @test alpine.bounding_obj_mip[:cnt] == 1 + @test alpine.bounding_obj_mip[:sense] == nothing m = multi4(solver=test_solver, exprmode=9) - JuMP.build(m) + alpine = _build(m) - @test length(keys(m.internalModel.nonconvex_terms)) == 2 + @test length(keys(alpine.nonconvex_terms)) == 2 - @test m.internalModel.nonconvex_terms[[:(x[2]), :(x[3]), :(x[4])]][:id] == 1 - @test m.internalModel.nonconvex_terms[[:(x[2]), :(x[3]), :(x[4])]][:lifted_var_ref] == :(x[5]) - @test m.internalModel.nonconvex_terms[[:(x[2]), :(x[3]), :(x[4])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 5)]][:id] == 2 - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 5)]][:lifted_var_ref] == :(x[6]) - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 5)]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[[:(x[2]), :(x[3]), :(x[4])]][:id] == 1 + @test alpine.nonconvex_terms[[:(x[2]), :(x[3]), :(x[4])]][:lifted_var_ref] == :(x[5]) + @test alpine.nonconvex_terms[[:(x[2]), :(x[3]), :(x[4])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 5)]][:id] == 2 + @test alpine.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 5)]][:lifted_var_ref] == :(x[6]) + @test alpine.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 5)]][:nonlinear_type] == :BILINEAR - @test m.internalModel.bounding_obj_mip[:rhs] == 0 - @test m.internalModel.bounding_obj_mip[:vars] == Expr[:(x[6])] - @test m.internalModel.bounding_obj_mip[:coefs] == [1.0] - @test m.internalModel.bounding_obj_mip[:cnt] == 1 - @test m.internalModel.bounding_obj_mip[:sense] == nothing + @test alpine.bounding_obj_mip[:rhs] == 0 + @test alpine.bounding_obj_mip[:vars] == Expr[:(x[6])] + @test alpine.bounding_obj_mip[:coefs] == [1.0] + @test alpine.bounding_obj_mip[:cnt] == 1 + @test alpine.bounding_obj_mip[:sense] == nothing m = multi4(solver=test_solver, exprmode=10) - JuMP.build(m) - @test length(keys(m.internalModel.nonconvex_terms)) == 3 + alpine = _build(m) + @test length(keys(alpine.nonconvex_terms)) == 3 - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 2), Expr(:ref, :x, 3)]][:id] == 1 - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 2), Expr(:ref, :x, 3)]][:lifted_var_ref] == :(x[5]) - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 2), Expr(:ref, :x, 3)]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 4), Expr(:ref, :x, 5)]][:id] == 2 - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 4), Expr(:ref, :x, 5)]][:lifted_var_ref] == :(x[6]) - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 4), Expr(:ref, :x, 5)]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 6)]][:id] == 3 - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 6)]][:lifted_var_ref] == :(x[7]) - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 6)]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[[Expr(:ref, :x, 2), Expr(:ref, :x, 3)]][:id] == 1 + @test alpine.nonconvex_terms[[Expr(:ref, :x, 2), Expr(:ref, :x, 3)]][:lifted_var_ref] == :(x[5]) + @test alpine.nonconvex_terms[[Expr(:ref, :x, 2), Expr(:ref, :x, 3)]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[[Expr(:ref, :x, 4), Expr(:ref, :x, 5)]][:id] == 2 + @test alpine.nonconvex_terms[[Expr(:ref, :x, 4), Expr(:ref, :x, 5)]][:lifted_var_ref] == :(x[6]) + @test alpine.nonconvex_terms[[Expr(:ref, :x, 4), Expr(:ref, :x, 5)]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 6)]][:id] == 3 + @test alpine.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 6)]][:lifted_var_ref] == :(x[7]) + @test alpine.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 6)]][:nonlinear_type] == :BILINEAR - @test m.internalModel.bounding_obj_mip[:rhs] == 0 - @test m.internalModel.bounding_obj_mip[:vars] == Expr[:(x[7])] - @test m.internalModel.bounding_obj_mip[:coefs] == [1.0] - @test m.internalModel.bounding_obj_mip[:cnt] == 1 - @test m.internalModel.bounding_obj_mip[:sense] == nothing + @test alpine.bounding_obj_mip[:rhs] == 0 + @test alpine.bounding_obj_mip[:vars] == Expr[:(x[7])] + @test alpine.bounding_obj_mip[:coefs] == [1.0] + @test alpine.bounding_obj_mip[:cnt] == 1 + @test alpine.bounding_obj_mip[:sense] == nothing m = multi4(solver=test_solver, exprmode=11) - JuMP.build(m) + alpine = _build(m) - @test length(keys(m.internalModel.nonconvex_terms)) == 3 + @test length(keys(alpine.nonconvex_terms)) == 3 - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 2), Expr(:ref, :x, 3)]][:id] == 1 - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 2), Expr(:ref, :x, 3)]][:lifted_var_ref] == :(x[5]) - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 2), Expr(:ref, :x, 3)]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 5)]][:id] == 2 - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 5)]][:lifted_var_ref] == :(x[6]) - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 5)]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 6), Expr(:ref, :x, 4)]][:id] == 3 - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 6), Expr(:ref, :x, 4)]][:lifted_var_ref] == :(x[7]) - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 6), Expr(:ref, :x, 4)]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[[Expr(:ref, :x, 2), Expr(:ref, :x, 3)]][:id] == 1 + @test alpine.nonconvex_terms[[Expr(:ref, :x, 2), Expr(:ref, :x, 3)]][:lifted_var_ref] == :(x[5]) + @test alpine.nonconvex_terms[[Expr(:ref, :x, 2), Expr(:ref, :x, 3)]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 5)]][:id] == 2 + @test alpine.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 5)]][:lifted_var_ref] == :(x[6]) + @test alpine.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 5)]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[[Expr(:ref, :x, 6), Expr(:ref, :x, 4)]][:id] == 3 + @test alpine.nonconvex_terms[[Expr(:ref, :x, 6), Expr(:ref, :x, 4)]][:lifted_var_ref] == :(x[7]) + @test alpine.nonconvex_terms[[Expr(:ref, :x, 6), Expr(:ref, :x, 4)]][:nonlinear_type] == :BILINEAR - @test m.internalModel.bounding_obj_mip[:rhs] == 0 - @test m.internalModel.bounding_obj_mip[:vars] == Expr[:(x[7])] - @test m.internalModel.bounding_obj_mip[:coefs] == [1.0] - @test m.internalModel.bounding_obj_mip[:cnt] == 1 - @test m.internalModel.bounding_obj_mip[:sense] == nothing + @test alpine.bounding_obj_mip[:rhs] == 0 + @test alpine.bounding_obj_mip[:vars] == Expr[:(x[7])] + @test alpine.bounding_obj_mip[:coefs] == [1.0] + @test alpine.bounding_obj_mip[:cnt] == 1 + @test alpine.bounding_obj_mip[:sense] == nothing end @testset "Expression Parsing || bilinear || Complex-div || div.jl" begin - test_solver = AlpineSolver(nlp_solver=IpoptSolver(print_level=0, sb="yes"),mip_solver=CbcSolver(logLevel=0),loglevel=100) + test_solver = optimizer_with_attributes(Alpine.Optimizer,"nlp_solver" => IPOPT_SB,"mip_solver" => CBC,"loglevel" => 100) m = div(solver=test_solver) - JuMP.build(m) # Setup internal model + alpine = _build(m) # Setup internal model - @test length(keys(m.internalModel.nonconvex_terms)) == 3 - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 1)]][:id] == 1 - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 1)]][:lifted_var_ref] == :(x[3]) - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 1)]][:nonlinear_type] == :MONOMIAL + @test length(keys(alpine.nonconvex_terms)) == 3 + @test alpine.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 1)]][:id] == 1 + @test alpine.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 1)]][:lifted_var_ref] == :(x[3]) + @test alpine.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 1)]][:nonlinear_type] == :MONOMIAL - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 2), Expr(:ref, :x, 2)]][:id] == 2 - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 2), Expr(:ref, :x, 2)]][:lifted_var_ref] == :(x[4]) - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 2), Expr(:ref, :x, 2)]][:nonlinear_type] == :MONOMIAL + @test alpine.nonconvex_terms[[Expr(:ref, :x, 2), Expr(:ref, :x, 2)]][:id] == 2 + @test alpine.nonconvex_terms[[Expr(:ref, :x, 2), Expr(:ref, :x, 2)]][:lifted_var_ref] == :(x[4]) + @test alpine.nonconvex_terms[[Expr(:ref, :x, 2), Expr(:ref, :x, 2)]][:nonlinear_type] == :MONOMIAL - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 2)]][:id] == 3 - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 2)]][:lifted_var_ref] == :(x[5]) - @test m.internalModel.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 2)]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 2)]][:id] == 3 + @test alpine.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 2)]][:lifted_var_ref] == :(x[5]) + @test alpine.nonconvex_terms[[Expr(:ref, :x, 1), Expr(:ref, :x, 2)]][:nonlinear_type] == :BILINEAR - aff_mip = m.internalModel.bounding_constr_mip + aff_mip = alpine.bounding_constr_mip @test aff_mip[1][:rhs] == 0.0 @test aff_mip[1][:vars] == Any[:(x[1])] @@ -739,7 +743,7 @@ end end @testset "Expression Parsing || part1 " begin - m = Model(solver=AlpineSolver(nlp_solver=IpoptSolver(print_level=0, sb="yes"),mip_solver=CbcSolver(logLevel=0),loglevel=100)) + m = Model(optimizer_with_attributes(Alpine.Optimizer,"nlp_solver" => IPOPT_SB,"mip_solver" => CBC,"loglevel" => 100)) @variable(m, x[1:4]>=0) @NLconstraint(m, x[1]^2 >= 1) # Basic monomial x[5]=x[1]^2 @NLconstraint(m, x[1]*x[2] <= 1) # x[6] <= 1 : x[6] = x[1]*x[2] @@ -747,36 +751,36 @@ end @NLconstraint(m, x[1]*(x[2]*x[3]) >= 1) # x[9] >= 1 : x[8] = x[2] * x[3] && x[9] = x[1]*x[8] @NLconstraint(m, x[1]^2*(x[2]^2 * x[3]^2) <= 1) # x[12] <= 1 : x[10] = x[3] ^ 2 && x[11] = x[7] * x[10] && x[12] = x[11]*[5] - JuMP.build(m) - - @test m.internalModel.bounding_constr_expr_mip[1] == :(x[5]-1.0>=0.0) - @test m.internalModel.bounding_constr_expr_mip[2] == :(x[6]-1.0<=0.0) - @test m.internalModel.bounding_constr_expr_mip[3] == :(x[8]-1.0<=0.0) - @test m.internalModel.bounding_constr_expr_mip[4] == :(x[10]-1.0>=0.0) - @test m.internalModel.bounding_constr_expr_mip[5] == :(x[13]-1.0<=0.0) - @test haskey(m.internalModel.nonconvex_terms, [:(x[1]), :(x[1])]) - @test haskey(m.internalModel.nonconvex_terms, [:(x[1]), :(x[2])]) - @test haskey(m.internalModel.nonconvex_terms, [:(x[2]), :(x[2])]) - @test haskey(m.internalModel.nonconvex_terms, [:(x[2]), :(x[3])]) - @test haskey(m.internalModel.nonconvex_terms, [:(x[5]), :(x[7])]) - @test haskey(m.internalModel.nonconvex_terms, [:(x[1]), :(x[9])]) - @test haskey(m.internalModel.nonconvex_terms, [:(x[3]), :(x[3])]) - @test haskey(m.internalModel.nonconvex_terms, [:(x[1]), :(x[2])]) - @test haskey(m.internalModel.nonconvex_terms, [:(x[5]), :(x[12])]) - - @test m.internalModel.nonconvex_terms[[:(x[1]), :(x[1])]][:id] == 1 - @test m.internalModel.nonconvex_terms[[:(x[1]), :(x[2])]][:id] == 2 - @test m.internalModel.nonconvex_terms[[:(x[2]), :(x[2])]][:id] == 3 - @test m.internalModel.nonconvex_terms[[:(x[5]), :(x[7])]][:id] == 4 - @test m.internalModel.nonconvex_terms[[:(x[2]), :(x[3])]][:id] == 5 - @test m.internalModel.nonconvex_terms[[:(x[1]), :(x[9])]][:id] == 6 - @test m.internalModel.nonconvex_terms[[:(x[3]), :(x[3])]][:id] == 7 - @test m.internalModel.nonconvex_terms[[:(x[7]), :(x[11])]][:id] == 8 - @test m.internalModel.nonconvex_terms[[:(x[5]), :(x[12])]][:id] == 9 + alpine = _build(m) + + @test alpine.bounding_constr_expr_mip[1] == :(x[5]-1.0>=0.0) + @test alpine.bounding_constr_expr_mip[2] == :(x[6]-1.0<=0.0) + @test alpine.bounding_constr_expr_mip[3] == :(x[8]-1.0<=0.0) + @test alpine.bounding_constr_expr_mip[4] == :(x[10]-1.0>=0.0) + @test alpine.bounding_constr_expr_mip[5] == :(x[13]-1.0<=0.0) + @test haskey(alpine.nonconvex_terms, [:(x[1]), :(x[1])]) + @test haskey(alpine.nonconvex_terms, [:(x[1]), :(x[2])]) + @test haskey(alpine.nonconvex_terms, [:(x[2]), :(x[2])]) + @test haskey(alpine.nonconvex_terms, [:(x[2]), :(x[3])]) + @test haskey(alpine.nonconvex_terms, [:(x[5]), :(x[7])]) + @test haskey(alpine.nonconvex_terms, [:(x[1]), :(x[9])]) + @test haskey(alpine.nonconvex_terms, [:(x[3]), :(x[3])]) + @test haskey(alpine.nonconvex_terms, [:(x[1]), :(x[2])]) + @test haskey(alpine.nonconvex_terms, [:(x[5]), :(x[12])]) + + @test alpine.nonconvex_terms[[:(x[1]), :(x[1])]][:id] == 1 + @test alpine.nonconvex_terms[[:(x[1]), :(x[2])]][:id] == 2 + @test alpine.nonconvex_terms[[:(x[2]), :(x[2])]][:id] == 3 + @test alpine.nonconvex_terms[[:(x[5]), :(x[7])]][:id] == 4 + @test alpine.nonconvex_terms[[:(x[2]), :(x[3])]][:id] == 5 + @test alpine.nonconvex_terms[[:(x[1]), :(x[9])]][:id] == 6 + @test alpine.nonconvex_terms[[:(x[3]), :(x[3])]][:id] == 7 + @test alpine.nonconvex_terms[[:(x[7]), :(x[11])]][:id] == 8 + @test alpine.nonconvex_terms[[:(x[5]), :(x[12])]][:id] == 9 end @testset "Expression Parsing || part2" begin - m = Model(solver=AlpineSolver(nlp_solver=IpoptSolver(print_level=0, sb="yes"),mip_solver=CbcSolver(logLevel=0),loglevel=100)) + m = Model(optimizer_with_attributes(Alpine.Optimizer,"nlp_solver" => IPOPT_SB,"mip_solver" => CBC,"loglevel" => 100)) @variable(m, x[1:4]>=0) @NLconstraint(m, (x[1]*x[2]) * x[3] >= 1) @@ -787,50 +791,50 @@ end @NLconstraint(m, x[1]^2 * (x[2] * x[3]) >= 1) @NLconstraint(m, (x[1] * x[2]^2) * x[3] <= 1) - JuMP.build(m) - - @test m.internalModel.bounding_constr_expr_mip[1] == :(x[6]-1.0>=0.0) - @test m.internalModel.bounding_constr_expr_mip[2] == :(x[11]-1.0<=0.0) - @test m.internalModel.bounding_constr_expr_mip[3] == :(x[13]-1.0>=0.0) - @test m.internalModel.bounding_constr_expr_mip[4] == :(x[15]-1.0<=0.0) - @test m.internalModel.bounding_constr_expr_mip[5] == :(x[17]-1.0>=0.0) - @test m.internalModel.bounding_constr_expr_mip[6] == :(x[19]-1.0<=0.0) - - @test haskey(m.internalModel.nonconvex_terms, [:(x[1]), :(x[2])]) #5 - @test haskey(m.internalModel.nonconvex_terms, [:(x[3]), :(x[5])]) #6 - @test haskey(m.internalModel.nonconvex_terms, [:(x[1]), :(x[1])]) #7 - @test haskey(m.internalModel.nonconvex_terms, [:(x[2]), :(x[2])]) #8 - @test haskey(m.internalModel.nonconvex_terms, [:(x[7]), :(x[8])]) #9 - @test haskey(m.internalModel.nonconvex_terms, [:(x[3]), :(x[3])]) #10 - @test haskey(m.internalModel.nonconvex_terms, [:(x[9]), :(x[10])]) #11 - @test haskey(m.internalModel.nonconvex_terms, [:(x[8]), :(x[10])]) #12 - @test haskey(m.internalModel.nonconvex_terms, [:(x[1]), :(x[12])]) #13 - @test haskey(m.internalModel.nonconvex_terms, [:(x[2]), :(x[7])]) #14 - @test haskey(m.internalModel.nonconvex_terms, [:(x[14]), :(x[10])]) #15 - @test haskey(m.internalModel.nonconvex_terms, [:(x[2]), :(x[3])]) #16 - @test haskey(m.internalModel.nonconvex_terms, [:(x[7]), :(x[16])]) #17 - @test haskey(m.internalModel.nonconvex_terms, [:(x[1]), :(x[8])]) #18 - @test haskey(m.internalModel.nonconvex_terms, [:(x[3]), :(x[18])]) #19 - - @test m.internalModel.nonconvex_terms[[:(x[1]), :(x[2])]][:id] == 1 - @test m.internalModel.nonconvex_terms[[:(x[3]), :(x[5])]][:id] == 2 - @test m.internalModel.nonconvex_terms[[:(x[1]), :(x[1])]][:id] == 3 - @test m.internalModel.nonconvex_terms[[:(x[2]), :(x[2])]][:id] == 4 - @test m.internalModel.nonconvex_terms[[:(x[7]), :(x[8])]][:id] == 5 - @test m.internalModel.nonconvex_terms[[:(x[3]), :(x[3])]][:id] == 6 - @test m.internalModel.nonconvex_terms[[:(x[9]), :(x[10])]][:id] == 7 - @test m.internalModel.nonconvex_terms[[:(x[8]), :(x[10])]][:id] == 8 - @test m.internalModel.nonconvex_terms[[:(x[1]), :(x[12])]][:id] == 9 - @test m.internalModel.nonconvex_terms[[:(x[2]), :(x[7])]][:id] == 10 - @test m.internalModel.nonconvex_terms[[:(x[14]), :(x[10])]][:id] == 11 - @test m.internalModel.nonconvex_terms[[:(x[2]), :(x[3])]][:id] == 12 - @test m.internalModel.nonconvex_terms[[:(x[7]), :(x[16])]][:id] == 13 - @test m.internalModel.nonconvex_terms[[:(x[1]), :(x[8])]][:id] == 14 - @test m.internalModel.nonconvex_terms[[:(x[3]), :(x[18])]][:id] == 15 + alpine = _build(m) + + @test alpine.bounding_constr_expr_mip[1] == :(x[6]-1.0>=0.0) + @test alpine.bounding_constr_expr_mip[2] == :(x[11]-1.0<=0.0) + @test alpine.bounding_constr_expr_mip[3] == :(x[13]-1.0>=0.0) + @test alpine.bounding_constr_expr_mip[4] == :(x[15]-1.0<=0.0) + @test alpine.bounding_constr_expr_mip[5] == :(x[17]-1.0>=0.0) + @test alpine.bounding_constr_expr_mip[6] == :(x[19]-1.0<=0.0) + + @test haskey(alpine.nonconvex_terms, [:(x[1]), :(x[2])]) #5 + @test haskey(alpine.nonconvex_terms, [:(x[3]), :(x[5])]) #6 + @test haskey(alpine.nonconvex_terms, [:(x[1]), :(x[1])]) #7 + @test haskey(alpine.nonconvex_terms, [:(x[2]), :(x[2])]) #8 + @test haskey(alpine.nonconvex_terms, [:(x[7]), :(x[8])]) #9 + @test haskey(alpine.nonconvex_terms, [:(x[3]), :(x[3])]) #10 + @test haskey(alpine.nonconvex_terms, [:(x[9]), :(x[10])]) #11 + @test haskey(alpine.nonconvex_terms, [:(x[8]), :(x[10])]) #12 + @test haskey(alpine.nonconvex_terms, [:(x[1]), :(x[12])]) #13 + @test haskey(alpine.nonconvex_terms, [:(x[2]), :(x[7])]) #14 + @test haskey(alpine.nonconvex_terms, [:(x[14]), :(x[10])]) #15 + @test haskey(alpine.nonconvex_terms, [:(x[2]), :(x[3])]) #16 + @test haskey(alpine.nonconvex_terms, [:(x[7]), :(x[16])]) #17 + @test haskey(alpine.nonconvex_terms, [:(x[1]), :(x[8])]) #18 + @test haskey(alpine.nonconvex_terms, [:(x[3]), :(x[18])]) #19 + + @test alpine.nonconvex_terms[[:(x[1]), :(x[2])]][:id] == 1 + @test alpine.nonconvex_terms[[:(x[3]), :(x[5])]][:id] == 2 + @test alpine.nonconvex_terms[[:(x[1]), :(x[1])]][:id] == 3 + @test alpine.nonconvex_terms[[:(x[2]), :(x[2])]][:id] == 4 + @test alpine.nonconvex_terms[[:(x[7]), :(x[8])]][:id] == 5 + @test alpine.nonconvex_terms[[:(x[3]), :(x[3])]][:id] == 6 + @test alpine.nonconvex_terms[[:(x[9]), :(x[10])]][:id] == 7 + @test alpine.nonconvex_terms[[:(x[8]), :(x[10])]][:id] == 8 + @test alpine.nonconvex_terms[[:(x[1]), :(x[12])]][:id] == 9 + @test alpine.nonconvex_terms[[:(x[2]), :(x[7])]][:id] == 10 + @test alpine.nonconvex_terms[[:(x[14]), :(x[10])]][:id] == 11 + @test alpine.nonconvex_terms[[:(x[2]), :(x[3])]][:id] == 12 + @test alpine.nonconvex_terms[[:(x[7]), :(x[16])]][:id] == 13 + @test alpine.nonconvex_terms[[:(x[1]), :(x[8])]][:id] == 14 + @test alpine.nonconvex_terms[[:(x[3]), :(x[18])]][:id] == 15 end @testset "Expression Parsing || part3" begin - m = Model(solver=AlpineSolver(nlp_solver=IpoptSolver(print_level=0, sb="yes"),mip_solver=CbcSolver(logLevel=0),loglevel=100)) + m = Model(optimizer_with_attributes(Alpine.Optimizer,"nlp_solver" => IPOPT_SB,"mip_solver" => CBC,"loglevel" => 100)) @variable(m, x[1:4]>=0) @NLconstraint(m, ((x[1]*x[2])*x[3])*x[4] >= 1) @@ -840,58 +844,58 @@ end @NLconstraint(m, ((x[1]*x[2])*x[3])*x[4]^2 >= 1) @NLconstraint(m, ((x[1]^2*x[2]^2)*x[3]^2)*x[4]^2 <= 1) - JuMP.build(m) - - @test m.internalModel.bounding_constr_expr_mip[1] == :(x[7]-1.0 >= 0.0) - @test m.internalModel.bounding_constr_expr_mip[2] == :(x[11]-1.0 <= 0.0) - @test m.internalModel.bounding_constr_expr_mip[3] == :(x[15]-1.0 >= 0.0) - @test m.internalModel.bounding_constr_expr_mip[4] == :(x[18]-1.0 <= 0.0) - @test m.internalModel.bounding_constr_expr_mip[5] == :(x[20]-1.0 >= 0.0) - @test m.internalModel.bounding_constr_expr_mip[6] == :(x[23]-1.0 <= 0.0) - - @test haskey(m.internalModel.nonconvex_terms, [:(x[1]), :(x[2])]) #5 - @test haskey(m.internalModel.nonconvex_terms, [:(x[3]), :(x[5])]) #6 - @test haskey(m.internalModel.nonconvex_terms, [:(x[4]), :(x[6])]) #7 - @test haskey(m.internalModel.nonconvex_terms, [:(x[1]), :(x[1])]) #8 - @test haskey(m.internalModel.nonconvex_terms, [:(x[2]), :(x[8])]) #9 - @test haskey(m.internalModel.nonconvex_terms, [:(x[3]), :(x[9])]) #10 - @test haskey(m.internalModel.nonconvex_terms, [:(x[4]), :(x[10])]) #11 - @test haskey(m.internalModel.nonconvex_terms, [:(x[2]), :(x[2])]) #12 - @test haskey(m.internalModel.nonconvex_terms, [:(x[1]), :(x[12])]) #13 - @test haskey(m.internalModel.nonconvex_terms, [:(x[3]), :(x[13])]) #14 - @test haskey(m.internalModel.nonconvex_terms, [:(x[4]), :(x[14])]) #15 - @test haskey(m.internalModel.nonconvex_terms, [:(x[3]), :(x[3])]) #16 - @test haskey(m.internalModel.nonconvex_terms, [:(x[5]), :(x[16])]) #17 - @test haskey(m.internalModel.nonconvex_terms, [:(x[4]), :(x[17])]) #18 - @test haskey(m.internalModel.nonconvex_terms, [:(x[4]), :(x[4])]) #19 - @test haskey(m.internalModel.nonconvex_terms, [:(x[6]), :(x[19])]) #20 - @test haskey(m.internalModel.nonconvex_terms, [:(x[8]), :(x[12])]) #21 - @test haskey(m.internalModel.nonconvex_terms, [:(x[21]), :(x[16])]) #22 - @test haskey(m.internalModel.nonconvex_terms, [:(x[22]), :(x[19])]) #23 - - @test m.internalModel.nonconvex_terms[[:(x[1]), :(x[2])]][:id] == 1 - @test m.internalModel.nonconvex_terms[[:(x[3]), :(x[5])]][:id] == 2 - @test m.internalModel.nonconvex_terms[[:(x[4]), :(x[6])]][:id] == 3 - @test m.internalModel.nonconvex_terms[[:(x[1]), :(x[1])]][:id] == 4 - @test m.internalModel.nonconvex_terms[[:(x[2]), :(x[8])]][:id] == 5 - @test m.internalModel.nonconvex_terms[[:(x[3]), :(x[9])]][:id] == 6 - @test m.internalModel.nonconvex_terms[[:(x[4]), :(x[10])]][:id] == 7 - @test m.internalModel.nonconvex_terms[[:(x[2]), :(x[2])]][:id] == 8 - @test m.internalModel.nonconvex_terms[[:(x[1]), :(x[12])]][:id] == 9 - @test m.internalModel.nonconvex_terms[[:(x[3]), :(x[13])]][:id] == 10 - @test m.internalModel.nonconvex_terms[[:(x[4]), :(x[14])]][:id] == 11 - @test m.internalModel.nonconvex_terms[[:(x[3]), :(x[3])]][:id] == 12 - @test m.internalModel.nonconvex_terms[[:(x[5]), :(x[16])]][:id] == 13 - @test m.internalModel.nonconvex_terms[[:(x[4]), :(x[17])]][:id] == 14 - @test m.internalModel.nonconvex_terms[[:(x[4]), :(x[4])]][:id] == 15 - @test m.internalModel.nonconvex_terms[[:(x[6]), :(x[19])]][:id] == 16 - @test m.internalModel.nonconvex_terms[[:(x[8]), :(x[12])]][:id] == 17 - @test m.internalModel.nonconvex_terms[[:(x[21]), :(x[16])]][:id] == 18 - @test m.internalModel.nonconvex_terms[[:(x[22]), :(x[19])]][:id] == 19 + alpine = _build(m) + + @test alpine.bounding_constr_expr_mip[1] == :(x[7]-1.0 >= 0.0) + @test alpine.bounding_constr_expr_mip[2] == :(x[11]-1.0 <= 0.0) + @test alpine.bounding_constr_expr_mip[3] == :(x[15]-1.0 >= 0.0) + @test alpine.bounding_constr_expr_mip[4] == :(x[18]-1.0 <= 0.0) + @test alpine.bounding_constr_expr_mip[5] == :(x[20]-1.0 >= 0.0) + @test alpine.bounding_constr_expr_mip[6] == :(x[23]-1.0 <= 0.0) + + @test haskey(alpine.nonconvex_terms, [:(x[1]), :(x[2])]) #5 + @test haskey(alpine.nonconvex_terms, [:(x[3]), :(x[5])]) #6 + @test haskey(alpine.nonconvex_terms, [:(x[4]), :(x[6])]) #7 + @test haskey(alpine.nonconvex_terms, [:(x[1]), :(x[1])]) #8 + @test haskey(alpine.nonconvex_terms, [:(x[2]), :(x[8])]) #9 + @test haskey(alpine.nonconvex_terms, [:(x[3]), :(x[9])]) #10 + @test haskey(alpine.nonconvex_terms, [:(x[4]), :(x[10])]) #11 + @test haskey(alpine.nonconvex_terms, [:(x[2]), :(x[2])]) #12 + @test haskey(alpine.nonconvex_terms, [:(x[1]), :(x[12])]) #13 + @test haskey(alpine.nonconvex_terms, [:(x[3]), :(x[13])]) #14 + @test haskey(alpine.nonconvex_terms, [:(x[4]), :(x[14])]) #15 + @test haskey(alpine.nonconvex_terms, [:(x[3]), :(x[3])]) #16 + @test haskey(alpine.nonconvex_terms, [:(x[5]), :(x[16])]) #17 + @test haskey(alpine.nonconvex_terms, [:(x[4]), :(x[17])]) #18 + @test haskey(alpine.nonconvex_terms, [:(x[4]), :(x[4])]) #19 + @test haskey(alpine.nonconvex_terms, [:(x[6]), :(x[19])]) #20 + @test haskey(alpine.nonconvex_terms, [:(x[8]), :(x[12])]) #21 + @test haskey(alpine.nonconvex_terms, [:(x[21]), :(x[16])]) #22 + @test haskey(alpine.nonconvex_terms, [:(x[22]), :(x[19])]) #23 + + @test alpine.nonconvex_terms[[:(x[1]), :(x[2])]][:id] == 1 + @test alpine.nonconvex_terms[[:(x[3]), :(x[5])]][:id] == 2 + @test alpine.nonconvex_terms[[:(x[4]), :(x[6])]][:id] == 3 + @test alpine.nonconvex_terms[[:(x[1]), :(x[1])]][:id] == 4 + @test alpine.nonconvex_terms[[:(x[2]), :(x[8])]][:id] == 5 + @test alpine.nonconvex_terms[[:(x[3]), :(x[9])]][:id] == 6 + @test alpine.nonconvex_terms[[:(x[4]), :(x[10])]][:id] == 7 + @test alpine.nonconvex_terms[[:(x[2]), :(x[2])]][:id] == 8 + @test alpine.nonconvex_terms[[:(x[1]), :(x[12])]][:id] == 9 + @test alpine.nonconvex_terms[[:(x[3]), :(x[13])]][:id] == 10 + @test alpine.nonconvex_terms[[:(x[4]), :(x[14])]][:id] == 11 + @test alpine.nonconvex_terms[[:(x[3]), :(x[3])]][:id] == 12 + @test alpine.nonconvex_terms[[:(x[5]), :(x[16])]][:id] == 13 + @test alpine.nonconvex_terms[[:(x[4]), :(x[17])]][:id] == 14 + @test alpine.nonconvex_terms[[:(x[4]), :(x[4])]][:id] == 15 + @test alpine.nonconvex_terms[[:(x[6]), :(x[19])]][:id] == 16 + @test alpine.nonconvex_terms[[:(x[8]), :(x[12])]][:id] == 17 + @test alpine.nonconvex_terms[[:(x[21]), :(x[16])]][:id] == 18 + @test alpine.nonconvex_terms[[:(x[22]), :(x[19])]][:id] == 19 end @testset "Expression Parsing || part7" begin - m = Model(solver=AlpineSolver(nlp_solver=IpoptSolver(print_level=0, sb="yes"),mip_solver=CbcSolver(logLevel=0),loglevel=100)) + m = Model(optimizer_with_attributes(Alpine.Optimizer,"nlp_solver" => IPOPT_SB,"mip_solver" => CBC,"loglevel" => 100)) @variable(m, x[1:4]>=0) @NLconstraint(m, x[1]*x[2]*x[3]*x[4] >= 1) @@ -902,45 +906,45 @@ end @NLconstraint(m, x[1]^2*x[2]*x[3]*x[4]^2 >= 1) @NLconstraint(m, x[1]^2*x[2]^2*x[3]^2*x[4]^2 >= 1) - JuMP.build(m) - - @test m.internalModel.bounding_constr_expr_mip[1] == :(x[5]-1.0 >= 0.0) - @test m.internalModel.bounding_constr_expr_mip[2] == :(x[7]-1.0 >= 0.0) - @test m.internalModel.bounding_constr_expr_mip[3] == :(x[9]-1.0 >= 0.0) - @test m.internalModel.bounding_constr_expr_mip[4] == :(x[12]-1.0 >= 0.0) - @test m.internalModel.bounding_constr_expr_mip[5] == :(x[13]-1.0 >= 0.0) - @test m.internalModel.bounding_constr_expr_mip[6] == :(x[14]-1.0 >= 0.0) - @test m.internalModel.bounding_constr_expr_mip[7] == :(x[15]-1.0 >= 0.0) - - @test haskey(m.internalModel.nonconvex_terms, [:(x[1]),:(x[2]),:(x[3]),:(x[4])]) #5 - @test haskey(m.internalModel.nonconvex_terms, [:(x[1]),:(x[1])]) #6 - @test haskey(m.internalModel.nonconvex_terms, [:(x[2]),:(x[3]),:(x[4]),:(x[6])]) #7 - @test haskey(m.internalModel.nonconvex_terms, [:(x[2]),:(x[2])]) #8 - @test haskey(m.internalModel.nonconvex_terms, [:(x[1]),:(x[3]),:(x[4]),:(x[8])]) #9 - @test haskey(m.internalModel.nonconvex_terms, [:(x[3]),:(x[3])]) #10 - @test haskey(m.internalModel.nonconvex_terms, [:(x[4]),:(x[4])]) #11 - @test haskey(m.internalModel.nonconvex_terms, [:(x[1]),:(x[2]),:(x[10]),:(x[11])]) #12 - @test haskey(m.internalModel.nonconvex_terms, [:(x[1]),:(x[4]),:(x[8]),:(x[10])]) #13 - @test haskey(m.internalModel.nonconvex_terms, [:(x[2]),:(x[3]),:(x[6]),:(x[11])]) #14 - @test haskey(m.internalModel.nonconvex_terms, [:(x[6]),:(x[8]),:(x[10]),:(x[11])]) #15 - - @test m.internalModel.nonconvex_terms[[:(x[1]),:(x[2]),:(x[3]),:(x[4])]][:id] == 1 #5 - @test m.internalModel.nonconvex_terms[[:(x[1]),:(x[1])]][:id] == 2 #6 - @test m.internalModel.nonconvex_terms[[:(x[2]),:(x[3]),:(x[4]),:(x[6])]][:id] == 3 #7 - @test m.internalModel.nonconvex_terms[[:(x[2]),:(x[2])]][:id] == 4 #8 - @test m.internalModel.nonconvex_terms[[:(x[1]),:(x[3]),:(x[4]),:(x[8])]][:id] == 5 #9 - @test m.internalModel.nonconvex_terms[[:(x[3]),:(x[3])]][:id] == 6 #10 - @test m.internalModel.nonconvex_terms[[:(x[4]),:(x[4])]][:id] == 7 #11 - @test m.internalModel.nonconvex_terms[[:(x[1]),:(x[2]),:(x[10]),:(x[11])]][:id] == 8 #12 - @test m.internalModel.nonconvex_terms[[:(x[1]),:(x[4]),:(x[8]),:(x[10])]][:id] == 9 #13 - @test m.internalModel.nonconvex_terms[[:(x[2]),:(x[3]),:(x[6]),:(x[11])]][:id] == 10 #14 - @test m.internalModel.nonconvex_terms[[:(x[6]),:(x[8]),:(x[10]),:(x[11])]][:id] == 11 #15 + alpine = _build(m) + + @test alpine.bounding_constr_expr_mip[1] == :(x[5]-1.0 >= 0.0) + @test alpine.bounding_constr_expr_mip[2] == :(x[7]-1.0 >= 0.0) + @test alpine.bounding_constr_expr_mip[3] == :(x[9]-1.0 >= 0.0) + @test alpine.bounding_constr_expr_mip[4] == :(x[12]-1.0 >= 0.0) + @test alpine.bounding_constr_expr_mip[5] == :(x[13]-1.0 >= 0.0) + @test alpine.bounding_constr_expr_mip[6] == :(x[14]-1.0 >= 0.0) + @test alpine.bounding_constr_expr_mip[7] == :(x[15]-1.0 >= 0.0) + + @test haskey(alpine.nonconvex_terms, [:(x[1]),:(x[2]),:(x[3]),:(x[4])]) #5 + @test haskey(alpine.nonconvex_terms, [:(x[1]),:(x[1])]) #6 + @test haskey(alpine.nonconvex_terms, [:(x[2]),:(x[3]),:(x[4]),:(x[6])]) #7 + @test haskey(alpine.nonconvex_terms, [:(x[2]),:(x[2])]) #8 + @test haskey(alpine.nonconvex_terms, [:(x[1]),:(x[3]),:(x[4]),:(x[8])]) #9 + @test haskey(alpine.nonconvex_terms, [:(x[3]),:(x[3])]) #10 + @test haskey(alpine.nonconvex_terms, [:(x[4]),:(x[4])]) #11 + @test haskey(alpine.nonconvex_terms, [:(x[1]),:(x[2]),:(x[10]),:(x[11])]) #12 + @test haskey(alpine.nonconvex_terms, [:(x[1]),:(x[4]),:(x[8]),:(x[10])]) #13 + @test haskey(alpine.nonconvex_terms, [:(x[2]),:(x[3]),:(x[6]),:(x[11])]) #14 + @test haskey(alpine.nonconvex_terms, [:(x[6]),:(x[8]),:(x[10]),:(x[11])]) #15 + + @test alpine.nonconvex_terms[[:(x[1]),:(x[2]),:(x[3]),:(x[4])]][:id] == 1 #5 + @test alpine.nonconvex_terms[[:(x[1]),:(x[1])]][:id] == 2 #6 + @test alpine.nonconvex_terms[[:(x[2]),:(x[3]),:(x[4]),:(x[6])]][:id] == 3 #7 + @test alpine.nonconvex_terms[[:(x[2]),:(x[2])]][:id] == 4 #8 + @test alpine.nonconvex_terms[[:(x[1]),:(x[3]),:(x[4]),:(x[8])]][:id] == 5 #9 + @test alpine.nonconvex_terms[[:(x[3]),:(x[3])]][:id] == 6 #10 + @test alpine.nonconvex_terms[[:(x[4]),:(x[4])]][:id] == 7 #11 + @test alpine.nonconvex_terms[[:(x[1]),:(x[2]),:(x[10]),:(x[11])]][:id] == 8 #12 + @test alpine.nonconvex_terms[[:(x[1]),:(x[4]),:(x[8]),:(x[10])]][:id] == 9 #13 + @test alpine.nonconvex_terms[[:(x[2]),:(x[3]),:(x[6]),:(x[11])]][:id] == 10 #14 + @test alpine.nonconvex_terms[[:(x[6]),:(x[8]),:(x[10]),:(x[11])]][:id] == 11 #15 end @testset "Expression Parsing || part8" begin - m = Model(solver=AlpineSolver(nlp_solver=IpoptSolver(print_level=0, sb="yes"), - mip_solver=CbcSolver(logLevel=0), - loglevel=100)) + m = Model(optimizer_with_attributes(Alpine.Optimizer,"nlp_solver" => IPOPT_SB, + "mip_solver" => CBC, + "loglevel" => 100)) @variable(m, x[1:4]>=0) @NLconstraint(m, (x[1]*x[2]*x[3])*x[4] >= 1) @@ -953,304 +957,305 @@ end @NLconstraint(m, (x[1]*x[2])*x[3]^2*x[4]^2 >= 1) @NLconstraint(m, (x[1]^2*x[2]^2*x[3]^2)*x[4]^2 >= 1) - JuMP.build(m) - - @test m.internalModel.bounding_constr_expr_mip[1] == :(x[6]-1.0 >= 0.0) - @test m.internalModel.bounding_constr_expr_mip[2] == :(x[9]-1.0 >= 0.0) - @test m.internalModel.bounding_constr_expr_mip[3] == :(x[12]-1.0 >= 0.0) - @test m.internalModel.bounding_constr_expr_mip[4] == :(x[15]-1.0 >= 0.0) - @test m.internalModel.bounding_constr_expr_mip[5] == :(x[17]-1.0 >= 0.0) - @test m.internalModel.bounding_constr_expr_mip[6] == :(x[19]-1.0 >= 0.0) - @test m.internalModel.bounding_constr_expr_mip[7] == :(x[21]-1.0 >= 0.0) - @test m.internalModel.bounding_constr_expr_mip[8] == :(x[22]-1.0 >= 0.0) - @test m.internalModel.bounding_constr_expr_mip[9] == :(x[24]-1.0 >= 0.0) - - @test haskey(m.internalModel.nonconvex_terms, [:(x[1]),:(x[2]),:(x[3])]) #5 - @test haskey(m.internalModel.nonconvex_terms, [:(x[4]),:(x[5])]) #6 - @test haskey(m.internalModel.nonconvex_terms, [:(x[1]),:(x[1])]) #7 - @test haskey(m.internalModel.nonconvex_terms, [:(x[2]),:(x[3]),:(x[7])]) #8 - @test haskey(m.internalModel.nonconvex_terms, [:(x[4]),:(x[8])]) #9 - @test haskey(m.internalModel.nonconvex_terms, [:(x[2]),:(x[2])]) #10 - @test haskey(m.internalModel.nonconvex_terms, [:(x[3]),:(x[10])]) #11 - @test haskey(m.internalModel.nonconvex_terms, [:(x[1]),:(x[4]),:(x[11])]) #12 - @test haskey(m.internalModel.nonconvex_terms, [:(x[3]),:(x[3])]) #13 - @test haskey(m.internalModel.nonconvex_terms, [:(x[2]),:(x[13])]) #14 - @test haskey(m.internalModel.nonconvex_terms, [:(x[1]),:(x[4]),:(x[14])]) #15 - @test haskey(m.internalModel.nonconvex_terms, [:(x[1]),:(x[10])]) #16 - @test haskey(m.internalModel.nonconvex_terms, [:(x[3]),:(x[4]),:(x[16])]) #17 - @test haskey(m.internalModel.nonconvex_terms, [:(x[1]),:(x[2])]) #18 - @test haskey(m.internalModel.nonconvex_terms, [:(x[4]),:(x[18]),:(x[13])]) #19 - @test haskey(m.internalModel.nonconvex_terms, [:(x[4]),:(x[4])]) #20 - @test haskey(m.internalModel.nonconvex_terms, [:(x[3]),:(x[18]),:(x[20])]) #21 - @test haskey(m.internalModel.nonconvex_terms, [:(x[18]),:(x[13]),:(x[20])]) #22 - @test haskey(m.internalModel.nonconvex_terms, [:(x[7]),:(x[10]),:(x[13])]) #23 - @test haskey(m.internalModel.nonconvex_terms, [:(x[23]),:(x[20])]) #24 + alpine = _build(m) + + @test alpine.bounding_constr_expr_mip[1] == :(x[6]-1.0 >= 0.0) + @test alpine.bounding_constr_expr_mip[2] == :(x[9]-1.0 >= 0.0) + @test alpine.bounding_constr_expr_mip[3] == :(x[12]-1.0 >= 0.0) + @test alpine.bounding_constr_expr_mip[4] == :(x[15]-1.0 >= 0.0) + @test alpine.bounding_constr_expr_mip[5] == :(x[17]-1.0 >= 0.0) + @test alpine.bounding_constr_expr_mip[6] == :(x[19]-1.0 >= 0.0) + @test alpine.bounding_constr_expr_mip[7] == :(x[21]-1.0 >= 0.0) + @test alpine.bounding_constr_expr_mip[8] == :(x[22]-1.0 >= 0.0) + @test alpine.bounding_constr_expr_mip[9] == :(x[24]-1.0 >= 0.0) + + @test haskey(alpine.nonconvex_terms, [:(x[1]),:(x[2]),:(x[3])]) #5 + @test haskey(alpine.nonconvex_terms, [:(x[4]),:(x[5])]) #6 + @test haskey(alpine.nonconvex_terms, [:(x[1]),:(x[1])]) #7 + @test haskey(alpine.nonconvex_terms, [:(x[2]),:(x[3]),:(x[7])]) #8 + @test haskey(alpine.nonconvex_terms, [:(x[4]),:(x[8])]) #9 + @test haskey(alpine.nonconvex_terms, [:(x[2]),:(x[2])]) #10 + @test haskey(alpine.nonconvex_terms, [:(x[3]),:(x[10])]) #11 + @test haskey(alpine.nonconvex_terms, [:(x[1]),:(x[4]),:(x[11])]) #12 + @test haskey(alpine.nonconvex_terms, [:(x[3]),:(x[3])]) #13 + @test haskey(alpine.nonconvex_terms, [:(x[2]),:(x[13])]) #14 + @test haskey(alpine.nonconvex_terms, [:(x[1]),:(x[4]),:(x[14])]) #15 + @test haskey(alpine.nonconvex_terms, [:(x[1]),:(x[10])]) #16 + @test haskey(alpine.nonconvex_terms, [:(x[3]),:(x[4]),:(x[16])]) #17 + @test haskey(alpine.nonconvex_terms, [:(x[1]),:(x[2])]) #18 + @test haskey(alpine.nonconvex_terms, [:(x[4]),:(x[18]),:(x[13])]) #19 + @test haskey(alpine.nonconvex_terms, [:(x[4]),:(x[4])]) #20 + @test haskey(alpine.nonconvex_terms, [:(x[3]),:(x[18]),:(x[20])]) #21 + @test haskey(alpine.nonconvex_terms, [:(x[18]),:(x[13]),:(x[20])]) #22 + @test haskey(alpine.nonconvex_terms, [:(x[7]),:(x[10]),:(x[13])]) #23 + @test haskey(alpine.nonconvex_terms, [:(x[23]),:(x[20])]) #24 end @testset "Expression Parsing || Convex" begin @testset "Convex Parsing :: PART I" begin - test_solver = AlpineSolver(nlp_solver=IpoptSolver(print_level=0, sb="yes"),mip_solver=CbcSolver(logLevel=0),loglevel=100) + test_solver = optimizer_with_attributes(Alpine.Optimizer,"nlp_solver" => IPOPT_SB,"mip_solver" => CBC,"loglevel" => 100) m = convex_test(test_solver) - JuMP.build(m) + alpine = _build(m) - @test m.internalModel.num_constr_convex == 21 + @test alpine.num_constr_convex == 21 # 0 : OBJ - @test m.internalModel.obj_structure == :convex - @test m.internalModel.nonlinear_constrs[0][:expr_orig] == :objective - @test m.internalModel.nonlinear_constrs[0][:convex_type] == :convexA - @test m.internalModel.nonlinear_constrs[0][:convexified] == false - - @test m.internalModel.bounding_obj_mip[:sense] == nothing - @test m.internalModel.bounding_obj_mip[:coefs] == [1.0, 1.0] - @test m.internalModel.bounding_obj_mip[:vars] == [:(x[1]), :(x[3])] - @test m.internalModel.bounding_obj_mip[:rhs] == 0.0 - @test m.internalModel.bounding_obj_mip[:powers] == [2, 2] - @test m.internalModel.bounding_obj_mip[:cnt] == 2 + @test alpine.obj_structure == :convex + @test alpine.nonlinear_constrs[0][:expr_orig] == :objective + @test alpine.nonlinear_constrs[0][:convex_type] == :convexA + @test alpine.nonlinear_constrs[0][:convexified] == false + + @test alpine.bounding_obj_mip[:sense] == nothing + @test alpine.bounding_obj_mip[:coefs] == [1.0, 1.0] + @test alpine.bounding_obj_mip[:vars] == [:(x[1]), :(x[3])] + @test alpine.bounding_obj_mip[:rhs] == 0.0 + @test alpine.bounding_obj_mip[:powers] == [2, 2] + @test alpine.bounding_obj_mip[:cnt] == 2 # 1 - @test m.internalModel.constr_structure[1] == :convex - @test m.internalModel.nonlinear_constrs[1][:expr_orig] == :constraints - @test m.internalModel.nonlinear_constrs[1][:convex_type] == :convexA - @test m.internalModel.nonlinear_constrs[1][:convexified] == false - @test m.internalModel.bounding_constr_mip[1][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[1][:coefs] == [3.0, 4.0] - @test m.internalModel.bounding_constr_mip[1][:vars] == [:(x[1]), :(x[2])] - @test m.internalModel.bounding_constr_mip[1][:rhs] == 25.0 - @test m.internalModel.bounding_constr_mip[1][:powers] == [2, 2] - @test m.internalModel.bounding_constr_mip[1][:cnt] == 2 + @test alpine.constr_structure[1] == :convex + @test alpine.nonlinear_constrs[1][:expr_orig] == :constraints + @test alpine.nonlinear_constrs[1][:convex_type] == :convexA + @test alpine.nonlinear_constrs[1][:convexified] == false + @test alpine.bounding_constr_mip[1][:sense] == :(<=) + @test alpine.bounding_constr_mip[1][:coefs] == [3.0, 4.0] + @test alpine.bounding_constr_mip[1][:vars] == [:(x[1]), :(x[2])] + @test alpine.bounding_constr_mip[1][:rhs] == 25.0 + @test alpine.bounding_constr_mip[1][:powers] == [2, 2] + @test alpine.bounding_constr_mip[1][:cnt] == 2 # 2 - @test m.internalModel.constr_structure[2] == :convex - @test m.internalModel.nonlinear_constrs[2][:expr_orig] == :constraints - @test m.internalModel.nonlinear_constrs[2][:convex_type] == :convexA - @test m.internalModel.nonlinear_constrs[2][:convexified] == false - @test m.internalModel.bounding_constr_mip[2][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[2][:coefs] == [3.0, 4.0] - @test m.internalModel.bounding_constr_mip[2][:vars] == [:(x[1]), :(x[2])] - @test m.internalModel.bounding_constr_mip[2][:rhs] == 25.0 - @test m.internalModel.bounding_constr_mip[2][:powers] == [2, 2] - @test m.internalModel.bounding_constr_mip[2][:cnt] == 2 + @test alpine.constr_structure[2] == :convex + @test alpine.nonlinear_constrs[2][:expr_orig] == :constraints + @test alpine.nonlinear_constrs[2][:convex_type] == :convexA + @test alpine.nonlinear_constrs[2][:convexified] == false + @test alpine.bounding_constr_mip[2][:sense] == :(<=) + @test alpine.bounding_constr_mip[2][:coefs] == [3.0, 4.0] + @test alpine.bounding_constr_mip[2][:vars] == [:(x[1]), :(x[2])] + @test alpine.bounding_constr_mip[2][:rhs] == 25.0 + @test alpine.bounding_constr_mip[2][:powers] == [2, 2] + @test alpine.bounding_constr_mip[2][:cnt] == 2 # 4 - @test m.internalModel.constr_structure[4] == :convex - @test m.internalModel.nonlinear_constrs[4][:expr_orig] == :constraints - @test m.internalModel.nonlinear_constrs[4][:convex_type] == :convexA - @test m.internalModel.nonlinear_constrs[4][:convexified] == false - @test m.internalModel.bounding_constr_mip[4][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[4][:coefs] == [3.0, 4.0] - @test m.internalModel.bounding_constr_mip[4][:vars] == [:(x[1]), :(x[2])] - @test m.internalModel.bounding_constr_mip[4][:rhs] == 10.0 - @test m.internalModel.bounding_constr_mip[4][:powers] == [2, 2] - @test m.internalModel.bounding_constr_mip[4][:cnt] == 2 + @test alpine.constr_structure[4] == :convex + @test alpine.nonlinear_constrs[4][:expr_orig] == :constraints + @test alpine.nonlinear_constrs[4][:convex_type] == :convexA + @test alpine.nonlinear_constrs[4][:convexified] == false + @test alpine.bounding_constr_mip[4][:sense] == :(<=) + @test alpine.bounding_constr_mip[4][:coefs] == [3.0, 4.0] + @test alpine.bounding_constr_mip[4][:vars] == [:(x[1]), :(x[2])] + @test alpine.bounding_constr_mip[4][:rhs] == 10.0 + @test alpine.bounding_constr_mip[4][:powers] == [2, 2] + @test alpine.bounding_constr_mip[4][:cnt] == 2 # 5 - @test m.internalModel.constr_structure[5] == :convex - @test m.internalModel.nonlinear_constrs[5][:expr_orig] == :constraints - @test m.internalModel.nonlinear_constrs[5][:convex_type] == :convexA - @test m.internalModel.nonlinear_constrs[5][:convexified] == :false - @test m.internalModel.bounding_constr_mip[5][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[5][:coefs] == [3.0, 4.0, 6.0] - @test m.internalModel.bounding_constr_mip[5][:vars] == [:(x[1]), :(x[2]), :(x[3])] - @test m.internalModel.bounding_constr_mip[5][:rhs] == 10.0 - @test m.internalModel.bounding_constr_mip[5][:powers] == [2, 2, 2] - @test m.internalModel.bounding_constr_mip[5][:cnt] == 3 + @test alpine.constr_structure[5] == :convex + @test alpine.nonlinear_constrs[5][:expr_orig] == :constraints + @test alpine.nonlinear_constrs[5][:convex_type] == :convexA + @test alpine.nonlinear_constrs[5][:convexified] == :false + @test alpine.bounding_constr_mip[5][:sense] == :(<=) + @test alpine.bounding_constr_mip[5][:coefs] == [3.0, 4.0, 6.0] + @test alpine.bounding_constr_mip[5][:vars] == [:(x[1]), :(x[2]), :(x[3])] + @test alpine.bounding_constr_mip[5][:rhs] == 10.0 + @test alpine.bounding_constr_mip[5][:powers] == [2, 2, 2] + @test alpine.bounding_constr_mip[5][:cnt] == 3 # 6 - @test m.internalModel.constr_structure[6] == :convex - @test m.internalModel.nonlinear_constrs[6][:expr_orig] == :constraints - @test m.internalModel.nonlinear_constrs[6][:convex_type] == :convexC - @test m.internalModel.nonlinear_constrs[6][:convexified] == :false - @test m.internalModel.bounding_constr_mip[6][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[6][:coefs] == [3.0, 4.0, 5.0] - @test m.internalModel.bounding_constr_mip[6][:vars] == [:(x[1]), :(x[2]), :(x[5])] - @test m.internalModel.bounding_constr_mip[6][:rhs] == 100.0 - @test m.internalModel.bounding_constr_mip[6][:powers] == [0.5, 0.5, 0.5] - @test m.internalModel.bounding_constr_mip[6][:cnt] == 3 + @test alpine.constr_structure[6] == :convex + @test alpine.nonlinear_constrs[6][:expr_orig] == :constraints + @test alpine.nonlinear_constrs[6][:convex_type] == :convexC + @test alpine.nonlinear_constrs[6][:convexified] == :false + @test alpine.bounding_constr_mip[6][:sense] == :(<=) + @test alpine.bounding_constr_mip[6][:coefs] == [3.0, 4.0, 5.0] + @test alpine.bounding_constr_mip[6][:vars] == [:(x[1]), :(x[2]), :(x[5])] + @test alpine.bounding_constr_mip[6][:rhs] == 100.0 + @test alpine.bounding_constr_mip[6][:powers] == [0.5, 0.5, 0.5] + @test alpine.bounding_constr_mip[6][:cnt] == 3 # 7 - @test m.internalModel.constr_structure[7] == :convex - @test m.internalModel.nonlinear_constrs[7][:expr_orig] == :constraints - @test m.internalModel.nonlinear_constrs[7][:convex_type] == :convexC - @test m.internalModel.nonlinear_constrs[7][:convexified] == :false - @test m.internalModel.bounding_constr_mip[7][:sense] == :(>=) - @test m.internalModel.bounding_constr_mip[7][:coefs] == [-3.0, -4.0] - @test m.internalModel.bounding_constr_mip[7][:vars] == [:(x[1]), :(x[2])] - @test m.internalModel.bounding_constr_mip[7][:rhs] == -100.0 - @test m.internalModel.bounding_constr_mip[7][:powers] == [0.5, 0.5] - @test m.internalModel.bounding_constr_mip[7][:cnt] == 2 + @test alpine.constr_structure[7] == :convex + @test alpine.nonlinear_constrs[7][:expr_orig] == :constraints + @test alpine.nonlinear_constrs[7][:convex_type] == :convexC + @test alpine.nonlinear_constrs[7][:convexified] == :false + @test alpine.bounding_constr_mip[7][:sense] == :(>=) + @test alpine.bounding_constr_mip[7][:coefs] == [-3.0, -4.0] + @test alpine.bounding_constr_mip[7][:vars] == [:(x[1]), :(x[2])] + @test alpine.bounding_constr_mip[7][:rhs] == -100.0 + @test alpine.bounding_constr_mip[7][:powers] == [0.5, 0.5] + @test alpine.bounding_constr_mip[7][:cnt] == 2 # 8 - @test m.internalModel.constr_structure[8] == :convex - @test m.internalModel.nonlinear_constrs[8][:expr_orig] == :constraints - @test m.internalModel.nonlinear_constrs[8][:convex_type] == :convexB - @test m.internalModel.nonlinear_constrs[8][:convexified] == :false - @test m.internalModel.bounding_constr_mip[8][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[8][:coefs] == [3.0, 1.0, 5.0] - @test m.internalModel.bounding_constr_mip[8][:vars] == [:(x[1]), :(x[2]), :(x[3])] - @test m.internalModel.bounding_constr_mip[8][:rhs] == 200.0 - @test m.internalModel.bounding_constr_mip[8][:powers] == [3.0, 3.0, 3.0] - @test m.internalModel.bounding_constr_mip[8][:cnt] == 3 + @test alpine.constr_structure[8] == :convex + @test alpine.nonlinear_constrs[8][:expr_orig] == :constraints + @test alpine.nonlinear_constrs[8][:convex_type] == :convexB + @test alpine.nonlinear_constrs[8][:convexified] == :false + @test alpine.bounding_constr_mip[8][:sense] == :(<=) + @test alpine.bounding_constr_mip[8][:coefs] == [3.0, 1.0, 5.0] + @test alpine.bounding_constr_mip[8][:vars] == [:(x[1]), :(x[2]), :(x[3])] + @test alpine.bounding_constr_mip[8][:rhs] == 200.0 + @test alpine.bounding_constr_mip[8][:powers] == [3.0, 3.0, 3.0] + @test alpine.bounding_constr_mip[8][:cnt] == 3 # 9 - @test m.internalModel.constr_structure[9] == :convex - @test m.internalModel.nonlinear_constrs[9][:expr_orig] == :constraints - @test m.internalModel.nonlinear_constrs[9][:convex_type] == :convexB - @test m.internalModel.nonlinear_constrs[9][:convexified] == :false - @test m.internalModel.bounding_constr_mip[9][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[9][:coefs] == [1.0, 1.0, 1.0, 100.0] - @test m.internalModel.bounding_constr_mip[9][:vars] == [:(x[1]), :(x[2]), :(x[3]), :(x[4])] - @test m.internalModel.bounding_constr_mip[9][:rhs] == 200.0 - @test m.internalModel.bounding_constr_mip[9][:powers] == [3, 3, 3, 3] - @test m.internalModel.bounding_constr_mip[9][:cnt] == 4 + @test alpine.constr_structure[9] == :convex + @test alpine.nonlinear_constrs[9][:expr_orig] == :constraints + @test alpine.nonlinear_constrs[9][:convex_type] == :convexB + @test alpine.nonlinear_constrs[9][:convexified] == :false + @test alpine.bounding_constr_mip[9][:sense] == :(<=) + @test alpine.bounding_constr_mip[9][:coefs] == [1.0, 1.0, 1.0, 100.0] + @test alpine.bounding_constr_mip[9][:vars] == [:(x[1]), :(x[2]), :(x[3]), :(x[4])] + @test alpine.bounding_constr_mip[9][:rhs] == 200.0 + @test alpine.bounding_constr_mip[9][:powers] == [3, 3, 3, 3] + @test alpine.bounding_constr_mip[9][:cnt] == 4 # 11 - @test m.internalModel.constr_structure[11] == :convex - @test m.internalModel.nonlinear_constrs[11][:expr_orig] == :constraints - @test m.internalModel.nonlinear_constrs[11][:convex_type] == :convexA - @test m.internalModel.nonlinear_constrs[11][:convexified] == :false - @test m.internalModel.bounding_constr_mip[11][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[11][:coefs] == [3.0, 4.0] - @test m.internalModel.bounding_constr_mip[11][:vars] == [:(x[1]), :(x[2])] - @test m.internalModel.bounding_constr_mip[11][:rhs] == 25.0 - @test m.internalModel.bounding_constr_mip[11][:powers] == [2, 2] - @test m.internalModel.bounding_constr_mip[11][:cnt] == 2 + @test alpine.constr_structure[11] == :convex + @test alpine.nonlinear_constrs[11][:expr_orig] == :constraints + @test alpine.nonlinear_constrs[11][:convex_type] == :convexA + @test alpine.nonlinear_constrs[11][:convexified] == :false + @test alpine.bounding_constr_mip[11][:sense] == :(<=) + @test alpine.bounding_constr_mip[11][:coefs] == [3.0, 4.0] + @test alpine.bounding_constr_mip[11][:vars] == [:(x[1]), :(x[2])] + @test alpine.bounding_constr_mip[11][:rhs] == 25.0 + @test alpine.bounding_constr_mip[11][:powers] == [2, 2] + @test alpine.bounding_constr_mip[11][:cnt] == 2 # 14 - @test m.internalModel.constr_structure[14] == :convex - @test m.internalModel.nonlinear_constrs[14][:expr_orig] == :constraints - @test m.internalModel.nonlinear_constrs[14][:convex_type] == :convexA - @test m.internalModel.nonlinear_constrs[14][:convexified] == :false - @test m.internalModel.bounding_constr_mip[14][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[14][:coefs] == [3.0, 5.0] - @test m.internalModel.bounding_constr_mip[14][:vars] == [:(x[1]), :(x[2])] - @test m.internalModel.bounding_constr_mip[14][:rhs] == 25.0 - @test m.internalModel.bounding_constr_mip[14][:powers] == [2, 2] - @test m.internalModel.bounding_constr_mip[14][:cnt] == 2 + @test alpine.constr_structure[14] == :convex + @test alpine.nonlinear_constrs[14][:expr_orig] == :constraints + @test alpine.nonlinear_constrs[14][:convex_type] == :convexA + @test alpine.nonlinear_constrs[14][:convexified] == :false + @test alpine.bounding_constr_mip[14][:sense] == :(<=) + @test alpine.bounding_constr_mip[14][:coefs] == [3.0, 5.0] + @test alpine.bounding_constr_mip[14][:vars] == [:(x[1]), :(x[2])] + @test alpine.bounding_constr_mip[14][:rhs] == 25.0 + @test alpine.bounding_constr_mip[14][:powers] == [2, 2] + @test alpine.bounding_constr_mip[14][:cnt] == 2 # 15 - @test m.internalModel.constr_structure[15] == :convex - @test m.internalModel.nonlinear_constrs[15][:expr_orig] == :constraints - @test m.internalModel.nonlinear_constrs[15][:convex_type] == :convexA - @test m.internalModel.nonlinear_constrs[15][:convexified] == :false - @test m.internalModel.bounding_constr_mip[15][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[15][:coefs] == [3.0, 5.0, 1.0] - @test m.internalModel.bounding_constr_mip[15][:vars] == [:(x[1]), :(x[2]), :(x[4])] - @test m.internalModel.bounding_constr_mip[15][:rhs] == 25.0 - @test m.internalModel.bounding_constr_mip[15][:powers] == [2, 2, 2] - @test m.internalModel.bounding_constr_mip[15][:cnt] == 3 + @test alpine.constr_structure[15] == :convex + @test alpine.nonlinear_constrs[15][:expr_orig] == :constraints + @test alpine.nonlinear_constrs[15][:convex_type] == :convexA + @test alpine.nonlinear_constrs[15][:convexified] == :false + @test alpine.bounding_constr_mip[15][:sense] == :(<=) + @test alpine.bounding_constr_mip[15][:coefs] == [3.0, 5.0, 1.0] + @test alpine.bounding_constr_mip[15][:vars] == [:(x[1]), :(x[2]), :(x[4])] + @test alpine.bounding_constr_mip[15][:rhs] == 25.0 + @test alpine.bounding_constr_mip[15][:powers] == [2, 2, 2] + @test alpine.bounding_constr_mip[15][:cnt] == 3 # 19 - @test m.internalModel.constr_structure[19] == :convex - @test m.internalModel.nonlinear_constrs[19][:expr_orig] == :constraints - @test m.internalModel.nonlinear_constrs[19][:convex_type] == :convexA - @test m.internalModel.nonlinear_constrs[19][:convexified] == :false - @test m.internalModel.bounding_constr_mip[19][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[19][:coefs] == [3.0, 16.0] - @test m.internalModel.bounding_constr_mip[19][:vars] == [:(x[1]), :(x[2])] - @test m.internalModel.bounding_constr_mip[19][:rhs] == 40.0 - @test m.internalModel.bounding_constr_mip[19][:powers] == [2, 2] - @test m.internalModel.bounding_constr_mip[19][:cnt] == 2 + @test alpine.constr_structure[19] == :convex + @test alpine.nonlinear_constrs[19][:expr_orig] == :constraints + @test alpine.nonlinear_constrs[19][:convex_type] == :convexA + @test alpine.nonlinear_constrs[19][:convexified] == :false + @test alpine.bounding_constr_mip[19][:sense] == :(<=) + @test alpine.bounding_constr_mip[19][:coefs] == [3.0, 16.0] + @test alpine.bounding_constr_mip[19][:vars] == [:(x[1]), :(x[2])] + @test alpine.bounding_constr_mip[19][:rhs] == 40.0 + @test alpine.bounding_constr_mip[19][:powers] == [2, 2] + @test alpine.bounding_constr_mip[19][:cnt] == 2 # 22 - @test m.internalModel.constr_structure[22] == :convex - @test m.internalModel.nonlinear_constrs[22][:expr_orig] == :constraints - @test m.internalModel.nonlinear_constrs[22][:convex_type] == :convexA - @test m.internalModel.nonlinear_constrs[22][:convexified] == :false - @test m.internalModel.bounding_constr_mip[22][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[22][:coefs] == [3.0, 4.0, 5.0, 6.0] - @test m.internalModel.bounding_constr_mip[22][:vars] == [:(x[1]), :(x[2]), :(x[3]), :(x[4])] - @test m.internalModel.bounding_constr_mip[22][:rhs] == 15.0 - @test m.internalModel.bounding_constr_mip[22][:powers] == [2, 2, 2, 2] - @test m.internalModel.bounding_constr_mip[22][:cnt] == 4 + @test alpine.constr_structure[22] == :convex + @test alpine.nonlinear_constrs[22][:expr_orig] == :constraints + @test alpine.nonlinear_constrs[22][:convex_type] == :convexA + @test alpine.nonlinear_constrs[22][:convexified] == :false + @test alpine.bounding_constr_mip[22][:sense] == :(<=) + @test alpine.bounding_constr_mip[22][:coefs] == [3.0, 4.0, 5.0, 6.0] + @test alpine.bounding_constr_mip[22][:vars] == [:(x[1]), :(x[2]), :(x[3]), :(x[4])] + @test alpine.bounding_constr_mip[22][:rhs] == 15.0 + @test alpine.bounding_constr_mip[22][:powers] == [2, 2, 2, 2] + @test alpine.bounding_constr_mip[22][:cnt] == 4 # 25 - @test m.internalModel.constr_structure[25] == :convex - @test m.internalModel.nonlinear_constrs[25][:expr_orig] == :constraints - @test m.internalModel.nonlinear_constrs[25][:convex_type] == :convexA - @test m.internalModel.nonlinear_constrs[25][:convexified] == :false - @test m.internalModel.bounding_constr_mip[25][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[25][:coefs] == [1.0, 1.0, 1.0, 1.0, 1.0] - @test m.internalModel.bounding_constr_mip[25][:vars] == [:(x[1]), :(x[2]), :(x[3]), :(x[4]), :(x[5])] - @test m.internalModel.bounding_constr_mip[25][:rhs] == 99999.0 - @test m.internalModel.bounding_constr_mip[25][:powers] == [2, 2, 2, 2, 2] - @test m.internalModel.bounding_constr_mip[25][:cnt] == 5 + @test alpine.constr_structure[25] == :convex + @test alpine.nonlinear_constrs[25][:expr_orig] == :constraints + @test alpine.nonlinear_constrs[25][:convex_type] == :convexA + @test alpine.nonlinear_constrs[25][:convexified] == :false + @test alpine.bounding_constr_mip[25][:sense] == :(<=) + @test alpine.bounding_constr_mip[25][:coefs] == [1.0, 1.0, 1.0, 1.0, 1.0] + @test alpine.bounding_constr_mip[25][:vars] == [:(x[1]), :(x[2]), :(x[3]), :(x[4]), :(x[5])] + @test alpine.bounding_constr_mip[25][:rhs] == 99999.0 + @test alpine.bounding_constr_mip[25][:powers] == [2, 2, 2, 2, 2] + @test alpine.bounding_constr_mip[25][:cnt] == 5 # 26 - @test m.internalModel.constr_structure[26] == :convex - @test m.internalModel.nonlinear_constrs[26][:expr_orig] == :constraints - @test m.internalModel.nonlinear_constrs[26][:convex_type] == :convexA - @test m.internalModel.nonlinear_constrs[26][:convexified] == :false - @test m.internalModel.bounding_constr_mip[26][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[26][:coefs] == [3.0, 4.0] - @test m.internalModel.bounding_constr_mip[26][:vars] == [:(x[1]), :(x[2])] - @test m.internalModel.bounding_constr_mip[26][:rhs] == 200.0 - @test m.internalModel.bounding_constr_mip[26][:powers] == [4, 4] - @test m.internalModel.bounding_constr_mip[26][:cnt] == 2 + @test alpine.constr_structure[26] == :convex + @test alpine.nonlinear_constrs[26][:expr_orig] == :constraints + @test alpine.nonlinear_constrs[26][:convex_type] == :convexA + @test alpine.nonlinear_constrs[26][:convexified] == :false + @test alpine.bounding_constr_mip[26][:sense] == :(<=) + @test alpine.bounding_constr_mip[26][:coefs] == [3.0, 4.0] + @test alpine.bounding_constr_mip[26][:vars] == [:(x[1]), :(x[2])] + @test alpine.bounding_constr_mip[26][:rhs] == 200.0 + @test alpine.bounding_constr_mip[26][:powers] == [4, 4] + @test alpine.bounding_constr_mip[26][:cnt] == 2 end end @testset "Expression Prasing || Linear Lifting" begin + @testset "Expression Parsing || Linear Lifting || nlp2" begin - test_solver = AlpineSolver(nlp_solver=IpoptSolver(print_level=0, sb="yes"), - mip_solver=CbcSolver(), - disc_ratio=8, - loglevel=100) + test_solver = optimizer_with_attributes(Alpine.Optimizer,"nlp_solver" => IPOPT_SB, + "mip_solver" => CBC, + "disc_ratio" => 8, + "loglevel" => 100) m = nlp2(solver=test_solver) - JuMP.build(m) + alpine = _build(m) - @test length(m.internalModel.linear_terms) == 2 - @test length(m.internalModel.nonconvex_terms) == 4 + @test length(alpine.linear_terms) == 2 + @test length(alpine.nonconvex_terms) == 4 lk = Vector{Any}(undef, 2) lk[1] = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, -1.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 3)]))) lk[2] = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, -2.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 6)]))) - @test length(keys(m.internalModel.linear_terms)) == 2 + @test length(keys(alpine.linear_terms)) == 2 yids = [4,7] - for i in 1:length(keys(m.internalModel.linear_terms)) - for j in keys(m.internalModel.linear_terms) - if m.internalModel.linear_terms[j][:id] == i + for i in 1:length(keys(alpine.linear_terms)) + for j in keys(alpine.linear_terms) + if alpine.linear_terms[j][:id] == i @test j == lk[i] @test j[:sign] == :+ @test j[:scalar] == lk[i][:scalar] @test j[:coef_var] == lk[i][:coef_var] - @test m.internalModel.linear_terms[j][:y_idx] == yids[i] + @test alpine.linear_terms[j][:y_idx] == yids[i] end end end - @test haskey(m.internalModel.linear_terms, lk[1]) - @test haskey(m.internalModel.linear_terms, lk[2]) - - - @test haskey(m.internalModel.nonconvex_terms, [:(x[2]), :(x[2])]) - @test haskey(m.internalModel.nonconvex_terms, [:(x[4]), :(x[4])]) - @test haskey(m.internalModel.nonconvex_terms, [:(x[7]), :(x[7])]) - @test haskey(m.internalModel.nonconvex_terms, [:(x[1]), :(x[1])]) - @test m.internalModel.nonconvex_terms[[:(x[1]), :(x[1])]][:id] == 1 - @test m.internalModel.nonconvex_terms[[:(x[2]), :(x[2])]][:id] == 3 - @test m.internalModel.nonconvex_terms[[:(x[4]), :(x[4])]][:id] == 2 - @test m.internalModel.nonconvex_terms[[:(x[7]), :(x[7])]][:id] == 4 - @test m.internalModel.nonconvex_terms[[:(x[1]), :(x[1])]][:lifted_var_ref].args[2] == 3 - @test m.internalModel.nonconvex_terms[[:(x[2]), :(x[2])]][:lifted_var_ref].args[2] == 6 - @test m.internalModel.nonconvex_terms[[:(x[4]), :(x[4])]][:lifted_var_ref].args[2] == 5 - @test m.internalModel.nonconvex_terms[[:(x[7]), :(x[7])]][:lifted_var_ref].args[2] == 8 + @test haskey(alpine.linear_terms, lk[1]) + @test haskey(alpine.linear_terms, lk[2]) + + + @test haskey(alpine.nonconvex_terms, [:(x[2]), :(x[2])]) + @test haskey(alpine.nonconvex_terms, [:(x[4]), :(x[4])]) + @test haskey(alpine.nonconvex_terms, [:(x[7]), :(x[7])]) + @test haskey(alpine.nonconvex_terms, [:(x[1]), :(x[1])]) + @test alpine.nonconvex_terms[[:(x[1]), :(x[1])]][:id] == 1 + @test alpine.nonconvex_terms[[:(x[2]), :(x[2])]][:id] == 3 + @test alpine.nonconvex_terms[[:(x[4]), :(x[4])]][:id] == 2 + @test alpine.nonconvex_terms[[:(x[7]), :(x[7])]][:id] == 4 + @test alpine.nonconvex_terms[[:(x[1]), :(x[1])]][:lifted_var_ref].args[2] == 3 + @test alpine.nonconvex_terms[[:(x[2]), :(x[2])]][:lifted_var_ref].args[2] == 6 + @test alpine.nonconvex_terms[[:(x[4]), :(x[4])]][:lifted_var_ref].args[2] == 5 + @test alpine.nonconvex_terms[[:(x[7]), :(x[7])]][:lifted_var_ref].args[2] == 8 end @testset "Expression Parsing || Linear Lifting || general" begin - test_solver = AlpineSolver(nlp_solver=IpoptSolver(print_level=0, sb="yes"), - mip_solver=CbcSolver(logLevel=0), - loglevel=100) + test_solver = optimizer_with_attributes(Alpine.Optimizer,"nlp_solver" => IPOPT_SB, + "mip_solver" => CBC, + "loglevel" => 100) m = basic_linear_lift(solver=test_solver) - JuMP.build(m) # Setup internal model + alpine = _build(m) # Setup internal model lk = Vector{Any}(undef, 5) lk[1] = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 1), (-1.0, 2)]))) @@ -1259,16 +1264,16 @@ end lk[4] = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 2), (1.0, 1)]))) lk[5] = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 3.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 2), (1.0, 1), (1.0, 3)]))) - @test length(keys(m.internalModel.linear_terms)) == 5 + @test length(keys(alpine.linear_terms)) == 5 yids = [8,9,12,14,16] - for i in 1:length(keys(m.internalModel.linear_terms)) - for j in keys(m.internalModel.linear_terms) - if m.internalModel.linear_terms[j][:id] == i + for i in 1:length(keys(alpine.linear_terms)) + for j in keys(alpine.linear_terms) + if alpine.linear_terms[j][:id] == i @test j == lk[i] @test j[:sign] == :+ @test j[:scalar] == lk[i][:scalar] @test j[:coef_var] == lk[i][:coef_var] - @test m.internalModel.linear_terms[j][:y_idx] == yids[i] + @test alpine.linear_terms[j][:y_idx] == yids[i] end end end @@ -1283,56 +1288,57 @@ end nlk8 = [:(x[16]), :(x[15])] nlk9 = [:(x[14]), :(x[14])] - @test m.internalModel.nonconvex_terms[nlk1][:id] == 7 - @test m.internalModel.nonconvex_terms[nlk2][:id] == 3 - @test m.internalModel.nonconvex_terms[nlk3][:id] == 4 - @test m.internalModel.nonconvex_terms[nlk4][:id] == 6 - @test m.internalModel.nonconvex_terms[nlk5][:id] == 2 - @test m.internalModel.nonconvex_terms[nlk6][:id] == 5 - @test m.internalModel.nonconvex_terms[nlk7][:id] == 1 - @test m.internalModel.nonconvex_terms[nlk8][:id] == 9 - @test m.internalModel.nonconvex_terms[nlk9][:id] == 8 - - @test m.internalModel.nonconvex_terms[nlk1][:lifted_var_ref].args[2] == 13 - @test m.internalModel.nonconvex_terms[nlk2][:lifted_var_ref].args[2] == 6 - @test m.internalModel.nonconvex_terms[nlk3][:lifted_var_ref].args[2] == 7 - @test m.internalModel.nonconvex_terms[nlk4][:lifted_var_ref].args[2] == 11 - @test m.internalModel.nonconvex_terms[nlk5][:lifted_var_ref].args[2] == 5 - @test m.internalModel.nonconvex_terms[nlk6][:lifted_var_ref].args[2] == 10 - @test m.internalModel.nonconvex_terms[nlk7][:lifted_var_ref].args[2] == 4 - @test m.internalModel.nonconvex_terms[nlk8][:lifted_var_ref].args[2] == 17 - @test m.internalModel.nonconvex_terms[nlk9][:lifted_var_ref].args[2] == 15 - - @test m.internalModel.nonconvex_terms[nlk1][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[nlk2][:nonlinear_type] == :MONOMIAL - @test m.internalModel.nonconvex_terms[nlk3][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[nlk4][:nonlinear_type] == :MONOMIAL - @test m.internalModel.nonconvex_terms[nlk5][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[nlk6][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[nlk7][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[nlk8][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[nlk9][:nonlinear_type] == :MONOMIAL - - @test m.internalModel.nonconvex_terms[nlk1][:var_idxs] == [8,9,12] - @test m.internalModel.nonconvex_terms[nlk2][:var_idxs] == [2,2] - @test m.internalModel.nonconvex_terms[nlk3][:var_idxs] == [2,3] - @test m.internalModel.nonconvex_terms[nlk4][:var_idxs] == [8] - @test m.internalModel.nonconvex_terms[nlk5][:var_idxs] == [1,3] - @test m.internalModel.nonconvex_terms[nlk6][:var_idxs] == [8,9] - @test m.internalModel.nonconvex_terms[nlk7][:var_idxs] == [1,2] - @test m.internalModel.nonconvex_terms[nlk8][:var_idxs] == [16, 15] - @test m.internalModel.nonconvex_terms[nlk9][:var_idxs] == [14] + @test alpine.nonconvex_terms[nlk1][:id] == 7 + @test alpine.nonconvex_terms[nlk2][:id] == 3 + @test alpine.nonconvex_terms[nlk3][:id] == 4 + @test alpine.nonconvex_terms[nlk4][:id] == 6 + @test alpine.nonconvex_terms[nlk5][:id] == 2 + @test alpine.nonconvex_terms[nlk6][:id] == 5 + @test alpine.nonconvex_terms[nlk7][:id] == 1 + @test alpine.nonconvex_terms[nlk8][:id] == 9 + @test alpine.nonconvex_terms[nlk9][:id] == 8 + + @test alpine.nonconvex_terms[nlk1][:lifted_var_ref].args[2] == 13 + @test alpine.nonconvex_terms[nlk2][:lifted_var_ref].args[2] == 6 + @test alpine.nonconvex_terms[nlk3][:lifted_var_ref].args[2] == 7 + @test alpine.nonconvex_terms[nlk4][:lifted_var_ref].args[2] == 11 + @test alpine.nonconvex_terms[nlk5][:lifted_var_ref].args[2] == 5 + @test alpine.nonconvex_terms[nlk6][:lifted_var_ref].args[2] == 10 + @test alpine.nonconvex_terms[nlk7][:lifted_var_ref].args[2] == 4 + @test alpine.nonconvex_terms[nlk8][:lifted_var_ref].args[2] == 17 + @test alpine.nonconvex_terms[nlk9][:lifted_var_ref].args[2] == 15 + + @test alpine.nonconvex_terms[nlk1][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[nlk2][:nonlinear_type] == :MONOMIAL + @test alpine.nonconvex_terms[nlk3][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[nlk4][:nonlinear_type] == :MONOMIAL + @test alpine.nonconvex_terms[nlk5][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[nlk6][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[nlk7][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[nlk8][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[nlk9][:nonlinear_type] == :MONOMIAL + + @test alpine.nonconvex_terms[nlk1][:var_idxs] == [8,9,12] + @test alpine.nonconvex_terms[nlk2][:var_idxs] == [2,2] + @test alpine.nonconvex_terms[nlk3][:var_idxs] == [2,3] + @test alpine.nonconvex_terms[nlk4][:var_idxs] == [8] + @test alpine.nonconvex_terms[nlk5][:var_idxs] == [1,3] + @test alpine.nonconvex_terms[nlk6][:var_idxs] == [8,9] + @test alpine.nonconvex_terms[nlk7][:var_idxs] == [1,2] + @test alpine.nonconvex_terms[nlk8][:var_idxs] == [16, 15] + @test alpine.nonconvex_terms[nlk9][:var_idxs] == [14] end + #= @testset "Expression Parsing || complex || Affine || operator_b" begin - test_solver = AlpineSolver(nlp_solver=IpoptSolver(print_level=0), - mip_solver=CbcSolver(logLevel=0), - loglevel=100) + test_solver = optimizer_with_attributes(Alpine.Optimizer,"nlp_solver" => IPOPT, + "mip_solver" => CBC, + "loglevel" => 100) m=operator_b(solver=test_solver) - JuMP.build(m) + alpine = _build(m) nlk = Vector{Any}(undef, 31) nlk[1] = [:(x[1]), :(x[2])] @@ -1367,7 +1373,7 @@ end nlk[30] = Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[48]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos)) nlk[31] = Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[21]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin)) - @test length(keys(m.internalModel.nonconvex_terms)) == 31 + @test length(keys(alpine.nonconvex_terms)) == 31 ids = [1:31;] yids = [8,9,11,13,14,15,16,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,37,38,39,41,43,45,47,49,50] nltypes = [:BILINEAR, :BILINEAR, :BILINEAR, :BILINEAR, :MONOMIAL, @@ -1377,10 +1383,10 @@ end :MULTILINEAR, :MULTILINEAR, :MULTILINEAR, :sin, :cos, :sin, :cos, :sin, :sin, :cos, :sin] for i in 1:31 - @test m.internalModel.nonconvex_terms[nlk[i]][:id] == i - @test m.internalModel.nonconvex_terms[nlk[i]][:y_idx] == yids[i] - @test m.internalModel.nonconvex_terms[nlk[i]][:nonlinear_type] == nltypes[i] - @test m.internalModel.nonconvex_terms[nlk[i]][:y_type] == :Cont + @test alpine.nonconvex_terms[nlk[i]][:id] == i + @test alpine.nonconvex_terms[nlk[i]][:y_idx] == yids[i] + @test alpine.nonconvex_terms[nlk[i]][:nonlinear_type] == nltypes[i] + @test alpine.nonconvex_terms[nlk[i]][:y_type] == :Cont end lk = Vector{Any}(undef, 12) @@ -1397,1238 +1403,1245 @@ end lk[11] = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(4.0, 8)]))) lk[12] = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(-1.0, 9)]))) - @test length(keys(m.internalModel.linear_terms)) == 12 + @test length(keys(alpine.linear_terms)) == 12 yids = [10,12,17,33,34,35,36,40,42,44,46,48] scas = [5.0,1.0,6.0,2.0,3.0,4.0,5.0,1.0,1.0,1.0,0.0,0.0] - for i in 1:length(keys(m.internalModel.linear_terms)) - for j in keys(m.internalModel.linear_terms) - if m.internalModel.linear_terms[j][:id] == i + for i in 1:length(keys(alpine.linear_terms)) + for j in keys(alpine.linear_terms) + if alpine.linear_terms[j][:id] == i @test j == lk[i] @test j[:sign] == :+ @test j[:scalar] == lk[i][:scalar] @test j[:coef_var] == lk[i][:coef_var] - @test m.internalModel.linear_terms[j][:y_idx] == yids[i] + @test alpine.linear_terms[j][:y_idx] == yids[i] end end end end =# - + @testset "Expression Parsing || Linear Lifting || brainpc3" begin - test_solver = AlpineSolver(nlp_solver=IpoptSolver(print_level=0, sb="yes"), - mip_solver=CbcSolver(logLevel=0), - disc_ratio=8, - loglevel=100) + test_solver = optimizer_with_attributes( + Alpine.Optimizer, + "nlp_solver" => IPOPT_SB, + "mip_solver" => CBC, + "disc_ratio" => 8, + "loglevel" => 100) m = brainpc3(solver=test_solver) - JuMP.build(m) - - @test m.internalModel.nonconvex_terms[Expr[:(x[6912]), :(x[6912])]][:y_idx] == 6913 - @test m.internalModel.nonconvex_terms[Expr[:(x[6912]), :(x[6912])]][:id] == 2 - @test m.internalModel.nonconvex_terms[Expr[:(x[6912]), :(x[6912])]][:lifted_constr_ref] == :(x[6913] == (*)(x[6912])) - @test m.internalModel.nonconvex_terms[Expr[:(x[6912]), :(x[6912])]][:nonlinear_type] == :MONOMIAL - @test m.internalModel.nonconvex_terms[Expr[:(x[6912]), :(x[6912])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[6912]), :(x[6912])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6969])]][:y_idx] == 6970 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6969])]][:id] == 25 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6969])]][:lifted_constr_ref] == :(x[6970] == x[6903] * x[6969]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6969])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6969])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6969])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6914])]][:y_idx] == 6915 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6914])]][:id] == 3 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6914])]][:lifted_constr_ref] == :(x[6915] == x[6903] * x[6914]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6914])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6914])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6914])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6919])]][:y_idx] == 6920 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6919])]][:id] == 5 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6919])]][:lifted_constr_ref] == :(x[6920] == x[6903] * x[6919]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6919])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6919])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6919])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6927]), :(x[6927])]][:y_idx] == 6928 - @test m.internalModel.nonconvex_terms[Expr[:(x[6927]), :(x[6927])]][:id] == 8 - @test m.internalModel.nonconvex_terms[Expr[:(x[6927]), :(x[6927])]][:lifted_constr_ref] == :(x[6928] == (*)(x[6927])) - @test m.internalModel.nonconvex_terms[Expr[:(x[6927]), :(x[6927])]][:nonlinear_type] == :MONOMIAL - @test m.internalModel.nonconvex_terms[Expr[:(x[6927]), :(x[6927])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[6927]), :(x[6927])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6952]), :(x[6952])]][:y_idx] == 6953 - @test m.internalModel.nonconvex_terms[Expr[:(x[6952]), :(x[6952])]][:id] == 18 - @test m.internalModel.nonconvex_terms[Expr[:(x[6952]), :(x[6952])]][:lifted_constr_ref] == :(x[6953] == (*)(x[6952])) - @test m.internalModel.nonconvex_terms[Expr[:(x[6952]), :(x[6952])]][:nonlinear_type] == :MONOMIAL - @test m.internalModel.nonconvex_terms[Expr[:(x[6952]), :(x[6952])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[6952]), :(x[6952])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6962]), :(x[6962])]][:y_idx] == 6963 - @test m.internalModel.nonconvex_terms[Expr[:(x[6962]), :(x[6962])]][:id] == 22 - @test m.internalModel.nonconvex_terms[Expr[:(x[6962]), :(x[6962])]][:lifted_constr_ref] == :(x[6963] == (*)(x[6962])) - @test m.internalModel.nonconvex_terms[Expr[:(x[6962]), :(x[6962])]][:nonlinear_type] == :MONOMIAL - @test m.internalModel.nonconvex_terms[Expr[:(x[6962]), :(x[6962])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[6962]), :(x[6962])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6974])]][:y_idx] == 6975 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6974])]][:id] == 27 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6974])]][:lifted_constr_ref] == :(x[6975] == x[6903] * x[6974]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6974])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6974])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6974])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6934])]][:y_idx] == 6935 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6934])]][:id] == 11 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6934])]][:lifted_constr_ref] == :(x[6935] == x[6903] * x[6934]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6934])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6934])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6934])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6959])]][:y_idx] == 6960 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6959])]][:id] == 21 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6959])]][:lifted_constr_ref] == :(x[6960] == x[6903] * x[6959]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6959])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6959])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6959])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[7014])]][:y_idx] == 7015 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[7014])]][:id] == 43 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[7014])]][:lifted_constr_ref] == :(x[7015] == x[6903] * x[7014]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[7014])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[7014])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[7014])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6939])]][:y_idx] == 6940 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6939])]][:id] == 13 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6939])]][:lifted_constr_ref] == :(x[6940] == x[6903] * x[6939]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6939])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6939])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6939])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[7017]), :(x[7017])]][:y_idx] == 7018 - @test m.internalModel.nonconvex_terms[Expr[:(x[7017]), :(x[7017])]][:id] == 44 - @test m.internalModel.nonconvex_terms[Expr[:(x[7017]), :(x[7017])]][:lifted_constr_ref] == :(x[7018] == (*)(x[7017])) - @test m.internalModel.nonconvex_terms[Expr[:(x[7017]), :(x[7017])]][:nonlinear_type] == :MONOMIAL - @test m.internalModel.nonconvex_terms[Expr[:(x[7017]), :(x[7017])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[7017]), :(x[7017])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6929])]][:y_idx] == 6930 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6929])]][:id] == 9 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6929])]][:lifted_constr_ref] == :(x[6930] == x[6903] * x[6929]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6929])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6929])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6929])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[7012]), :(x[7012])]][:y_idx] == 7013 - @test m.internalModel.nonconvex_terms[Expr[:(x[7012]), :(x[7012])]][:id] == 42 - @test m.internalModel.nonconvex_terms[Expr[:(x[7012]), :(x[7012])]][:lifted_constr_ref] == :(x[7013] == (*)(x[7012])) - @test m.internalModel.nonconvex_terms[Expr[:(x[7012]), :(x[7012])]][:nonlinear_type] == :MONOMIAL - @test m.internalModel.nonconvex_terms[Expr[:(x[7012]), :(x[7012])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[7012]), :(x[7012])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6947]), :(x[6947])]][:y_idx] == 6948 - @test m.internalModel.nonconvex_terms[Expr[:(x[6947]), :(x[6947])]][:id] == 16 - @test m.internalModel.nonconvex_terms[Expr[:(x[6947]), :(x[6947])]][:lifted_constr_ref] == :(x[6948] == (*)(x[6947])) - @test m.internalModel.nonconvex_terms[Expr[:(x[6947]), :(x[6947])]][:nonlinear_type] == :MONOMIAL - @test m.internalModel.nonconvex_terms[Expr[:(x[6947]), :(x[6947])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[6947]), :(x[6947])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[7032]), :(x[7032])]][:y_idx] == 7033 - @test m.internalModel.nonconvex_terms[Expr[:(x[7032]), :(x[7032])]][:id] == 50 - @test m.internalModel.nonconvex_terms[Expr[:(x[7032]), :(x[7032])]][:lifted_constr_ref] == :(x[7033] == (*)(x[7032])) - @test m.internalModel.nonconvex_terms[Expr[:(x[7032]), :(x[7032])]][:nonlinear_type] == :MONOMIAL - @test m.internalModel.nonconvex_terms[Expr[:(x[7032]), :(x[7032])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[7032]), :(x[7032])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6997]), :(x[6997])]][:y_idx] == 6998 - @test m.internalModel.nonconvex_terms[Expr[:(x[6997]), :(x[6997])]][:id] == 36 - @test m.internalModel.nonconvex_terms[Expr[:(x[6997]), :(x[6997])]][:lifted_constr_ref] == :(x[6998] == (*)(x[6997])) - @test m.internalModel.nonconvex_terms[Expr[:(x[6997]), :(x[6997])]][:nonlinear_type] == :MONOMIAL - @test m.internalModel.nonconvex_terms[Expr[:(x[6997]), :(x[6997])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[6997]), :(x[6997])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[7027]), :(x[7027])]][:y_idx] == 7028 - @test m.internalModel.nonconvex_terms[Expr[:(x[7027]), :(x[7027])]][:id] == 48 - @test m.internalModel.nonconvex_terms[Expr[:(x[7027]), :(x[7027])]][:lifted_constr_ref] == :(x[7028] == (*)(x[7027])) - @test m.internalModel.nonconvex_terms[Expr[:(x[7027]), :(x[7027])]][:nonlinear_type] == :MONOMIAL - @test m.internalModel.nonconvex_terms[Expr[:(x[7027]), :(x[7027])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[7027]), :(x[7027])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[7037]), :(x[7037])]][:y_idx] == 7038 - @test m.internalModel.nonconvex_terms[Expr[:(x[7037]), :(x[7037])]][:id] == 52 - @test m.internalModel.nonconvex_terms[Expr[:(x[7037]), :(x[7037])]][:lifted_constr_ref] == :(x[7038] == (*)(x[7037])) - @test m.internalModel.nonconvex_terms[Expr[:(x[7037]), :(x[7037])]][:nonlinear_type] == :MONOMIAL - @test m.internalModel.nonconvex_terms[Expr[:(x[7037]), :(x[7037])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[7037]), :(x[7037])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[7007]), :(x[7007])]][:y_idx] == 7008 - @test m.internalModel.nonconvex_terms[Expr[:(x[7007]), :(x[7007])]][:id] == 40 - @test m.internalModel.nonconvex_terms[Expr[:(x[7007]), :(x[7007])]][:lifted_constr_ref] == :(x[7008] == (*)(x[7007])) - @test m.internalModel.nonconvex_terms[Expr[:(x[7007]), :(x[7007])]][:nonlinear_type] == :MONOMIAL - @test m.internalModel.nonconvex_terms[Expr[:(x[7007]), :(x[7007])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[7007]), :(x[7007])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6964])]][:y_idx] == 6965 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6964])]][:id] == 23 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6964])]][:lifted_constr_ref] == :(x[6965] == x[6903] * x[6964]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6964])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6964])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6964])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6924])]][:y_idx] == 6925 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6924])]][:id] == 7 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6924])]][:lifted_constr_ref] == :(x[6925] == x[6903] * x[6924]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6924])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6924])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6924])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6979])]][:y_idx] == 6980 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6979])]][:id] == 29 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6979])]][:lifted_constr_ref] == :(x[6980] == x[6903] * x[6979]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6979])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6979])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6979])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6994])]][:y_idx] == 6995 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6994])]][:id] == 35 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6994])]][:lifted_constr_ref] == :(x[6995] == x[6903] * x[6994]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6994])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6994])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6994])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6972]), :(x[6972])]][:y_idx] == 6973 - @test m.internalModel.nonconvex_terms[Expr[:(x[6972]), :(x[6972])]][:id] == 26 - @test m.internalModel.nonconvex_terms[Expr[:(x[6972]), :(x[6972])]][:lifted_constr_ref] == :(x[6973] == (*)(x[6972])) - @test m.internalModel.nonconvex_terms[Expr[:(x[6972]), :(x[6972])]][:nonlinear_type] == :MONOMIAL - @test m.internalModel.nonconvex_terms[Expr[:(x[6972]), :(x[6972])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[6972]), :(x[6972])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[7019])]][:y_idx] == 7020 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[7019])]][:id] == 45 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[7019])]][:lifted_constr_ref] == :(x[7020] == x[6903] * x[7019]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[7019])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[7019])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[7019])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6992]), :(x[6992])]][:y_idx] == 6993 - @test m.internalModel.nonconvex_terms[Expr[:(x[6992]), :(x[6992])]][:id] == 34 - @test m.internalModel.nonconvex_terms[Expr[:(x[6992]), :(x[6992])]][:lifted_constr_ref] == :(x[6993] == (*)(x[6992])) - @test m.internalModel.nonconvex_terms[Expr[:(x[6992]), :(x[6992])]][:nonlinear_type] == :MONOMIAL - @test m.internalModel.nonconvex_terms[Expr[:(x[6992]), :(x[6992])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[6992]), :(x[6992])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[7002]), :(x[7002])]][:y_idx] == 7003 - @test m.internalModel.nonconvex_terms[Expr[:(x[7002]), :(x[7002])]][:id] == 38 - @test m.internalModel.nonconvex_terms[Expr[:(x[7002]), :(x[7002])]][:lifted_constr_ref] == :(x[7003] == (*)(x[7002])) - @test m.internalModel.nonconvex_terms[Expr[:(x[7002]), :(x[7002])]][:nonlinear_type] == :MONOMIAL - @test m.internalModel.nonconvex_terms[Expr[:(x[7002]), :(x[7002])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[7002]), :(x[7002])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[7022]), :(x[7022])]][:y_idx] == 7023 - @test m.internalModel.nonconvex_terms[Expr[:(x[7022]), :(x[7022])]][:id] == 46 - @test m.internalModel.nonconvex_terms[Expr[:(x[7022]), :(x[7022])]][:lifted_constr_ref] == :(x[7023] == (*)(x[7022])) - @test m.internalModel.nonconvex_terms[Expr[:(x[7022]), :(x[7022])]][:nonlinear_type] == :MONOMIAL - @test m.internalModel.nonconvex_terms[Expr[:(x[7022]), :(x[7022])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[7022]), :(x[7022])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6908])]][:y_idx] == 6909 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6908])]][:id] == 1 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6908])]][:lifted_constr_ref] == :(x[6909] == x[6903] * x[6908]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6908])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6908])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6908])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6949])]][:y_idx] == 6950 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6949])]][:id] == 17 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6949])]][:lifted_constr_ref] == :(x[6950] == x[6903] * x[6949]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6949])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6949])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6949])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[7004])]][:y_idx] == 7005 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[7004])]][:id] == 39 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[7004])]][:lifted_constr_ref] == :(x[7005] == x[6903] * x[7004]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[7004])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[7004])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[7004])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6917]), :(x[6917])]][:y_idx] == 6918 - @test m.internalModel.nonconvex_terms[Expr[:(x[6917]), :(x[6917])]][:id] == 4 - @test m.internalModel.nonconvex_terms[Expr[:(x[6917]), :(x[6917])]][:lifted_constr_ref] == :(x[6918] == (*)(x[6917])) - @test m.internalModel.nonconvex_terms[Expr[:(x[6917]), :(x[6917])]][:nonlinear_type] == :MONOMIAL - @test m.internalModel.nonconvex_terms[Expr[:(x[6917]), :(x[6917])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[6917]), :(x[6917])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6937]), :(x[6937])]][:y_idx] == 6938 - @test m.internalModel.nonconvex_terms[Expr[:(x[6937]), :(x[6937])]][:id] == 12 - @test m.internalModel.nonconvex_terms[Expr[:(x[6937]), :(x[6937])]][:lifted_constr_ref] == :(x[6938] == (*)(x[6937])) - @test m.internalModel.nonconvex_terms[Expr[:(x[6937]), :(x[6937])]][:nonlinear_type] == :MONOMIAL - @test m.internalModel.nonconvex_terms[Expr[:(x[6937]), :(x[6937])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[6937]), :(x[6937])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6932]), :(x[6932])]][:y_idx] == 6933 - @test m.internalModel.nonconvex_terms[Expr[:(x[6932]), :(x[6932])]][:id] == 10 - @test m.internalModel.nonconvex_terms[Expr[:(x[6932]), :(x[6932])]][:lifted_constr_ref] == :(x[6933] == (*)(x[6932])) - @test m.internalModel.nonconvex_terms[Expr[:(x[6932]), :(x[6932])]][:nonlinear_type] == :MONOMIAL - @test m.internalModel.nonconvex_terms[Expr[:(x[6932]), :(x[6932])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[6932]), :(x[6932])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6989])]][:y_idx] == 6990 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6989])]][:id] == 33 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6989])]][:lifted_constr_ref] == :(x[6990] == x[6903] * x[6989]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6989])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6989])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6989])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6977]), :(x[6977])]][:y_idx] == 6978 - @test m.internalModel.nonconvex_terms[Expr[:(x[6977]), :(x[6977])]][:id] == 28 - @test m.internalModel.nonconvex_terms[Expr[:(x[6977]), :(x[6977])]][:lifted_constr_ref] == :(x[6978] == (*)(x[6977])) - @test m.internalModel.nonconvex_terms[Expr[:(x[6977]), :(x[6977])]][:nonlinear_type] == :MONOMIAL - @test m.internalModel.nonconvex_terms[Expr[:(x[6977]), :(x[6977])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[6977]), :(x[6977])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6987]), :(x[6987])]][:y_idx] == 6988 - @test m.internalModel.nonconvex_terms[Expr[:(x[6987]), :(x[6987])]][:id] == 32 - @test m.internalModel.nonconvex_terms[Expr[:(x[6987]), :(x[6987])]][:lifted_constr_ref] == :(x[6988] == (*)(x[6987])) - @test m.internalModel.nonconvex_terms[Expr[:(x[6987]), :(x[6987])]][:nonlinear_type] == :MONOMIAL - @test m.internalModel.nonconvex_terms[Expr[:(x[6987]), :(x[6987])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[6987]), :(x[6987])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[7034])]][:y_idx] == 7035 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[7034])]][:id] == 51 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[7034])]][:lifted_constr_ref] == :(x[7035] == x[6903] * x[7034]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[7034])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[7034])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[7034])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6967]), :(x[6967])]][:y_idx] == 6968 - @test m.internalModel.nonconvex_terms[Expr[:(x[6967]), :(x[6967])]][:id] == 24 - @test m.internalModel.nonconvex_terms[Expr[:(x[6967]), :(x[6967])]][:lifted_constr_ref] == :(x[6968] == (*)(x[6967])) - @test m.internalModel.nonconvex_terms[Expr[:(x[6967]), :(x[6967])]][:nonlinear_type] == :MONOMIAL - @test m.internalModel.nonconvex_terms[Expr[:(x[6967]), :(x[6967])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[6967]), :(x[6967])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6957]), :(x[6957])]][:y_idx] == 6958 - @test m.internalModel.nonconvex_terms[Expr[:(x[6957]), :(x[6957])]][:id] == 20 - @test m.internalModel.nonconvex_terms[Expr[:(x[6957]), :(x[6957])]][:lifted_constr_ref] == :(x[6958] == (*)(x[6957])) - @test m.internalModel.nonconvex_terms[Expr[:(x[6957]), :(x[6957])]][:nonlinear_type] == :MONOMIAL - @test m.internalModel.nonconvex_terms[Expr[:(x[6957]), :(x[6957])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[6957]), :(x[6957])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[7009])]][:y_idx] == 7010 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[7009])]][:id] == 41 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[7009])]][:lifted_constr_ref] == :(x[7010] == x[6903] * x[7009]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[7009])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[7009])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[7009])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6942]), :(x[6942])]][:y_idx] == 6943 - @test m.internalModel.nonconvex_terms[Expr[:(x[6942]), :(x[6942])]][:id] == 14 - @test m.internalModel.nonconvex_terms[Expr[:(x[6942]), :(x[6942])]][:lifted_constr_ref] == :(x[6943] == (*)(x[6942])) - @test m.internalModel.nonconvex_terms[Expr[:(x[6942]), :(x[6942])]][:nonlinear_type] == :MONOMIAL - @test m.internalModel.nonconvex_terms[Expr[:(x[6942]), :(x[6942])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[6942]), :(x[6942])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6982]), :(x[6982])]][:y_idx] == 6983 - @test m.internalModel.nonconvex_terms[Expr[:(x[6982]), :(x[6982])]][:id] == 30 - @test m.internalModel.nonconvex_terms[Expr[:(x[6982]), :(x[6982])]][:lifted_constr_ref] == :(x[6983] == (*)(x[6982])) - @test m.internalModel.nonconvex_terms[Expr[:(x[6982]), :(x[6982])]][:nonlinear_type] == :MONOMIAL - @test m.internalModel.nonconvex_terms[Expr[:(x[6982]), :(x[6982])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[6982]), :(x[6982])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6999])]][:y_idx] == 7000 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6999])]][:id] == 37 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6999])]][:lifted_constr_ref] == :(x[7000] == x[6903] * x[6999]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6999])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6999])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6999])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6944])]][:y_idx] == 6945 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6944])]][:id] == 15 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6944])]][:lifted_constr_ref] == :(x[6945] == x[6903] * x[6944]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6944])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6944])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6944])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[7024])]][:y_idx] == 7025 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[7024])]][:id] == 47 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[7024])]][:lifted_constr_ref] == :(x[7025] == x[6903] * x[7024]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[7024])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[7024])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[7024])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6954])]][:y_idx] == 6955 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6954])]][:id] == 19 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6954])]][:lifted_constr_ref] == :(x[6955] == x[6903] * x[6954]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6954])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6954])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6954])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6922]), :(x[6922])]][:y_idx] == 6923 - @test m.internalModel.nonconvex_terms[Expr[:(x[6922]), :(x[6922])]][:id] == 6 - @test m.internalModel.nonconvex_terms[Expr[:(x[6922]), :(x[6922])]][:lifted_constr_ref] == :(x[6923] == (*)(x[6922])) - @test m.internalModel.nonconvex_terms[Expr[:(x[6922]), :(x[6922])]][:nonlinear_type] == :MONOMIAL - @test m.internalModel.nonconvex_terms[Expr[:(x[6922]), :(x[6922])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[6922]), :(x[6922])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6984])]][:y_idx] == 6985 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6984])]][:id] == 31 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6984])]][:lifted_constr_ref] == :(x[6985] == x[6903] * x[6984]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6984])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6984])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[6984])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[7029])]][:y_idx] == 7030 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[7029])]][:id] == 49 - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[7029])]][:lifted_constr_ref] == :(x[7030] == x[6903] * x[7029]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[7029])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[7029])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[6903]), :(x[7029])]][:constr_id] == Set(Any[0]) + alpine = _build(m) + + @test alpine.nonconvex_terms[Expr[:(x[6912]), :(x[6912])]][:y_idx] == 6913 + @test alpine.nonconvex_terms[Expr[:(x[6912]), :(x[6912])]][:id] == 2 + @test alpine.nonconvex_terms[Expr[:(x[6912]), :(x[6912])]][:lifted_constr_ref] == :(x[6913] == (*)(x[6912])) + @test alpine.nonconvex_terms[Expr[:(x[6912]), :(x[6912])]][:nonlinear_type] == :MONOMIAL + @test alpine.nonconvex_terms[Expr[:(x[6912]), :(x[6912])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[6912]), :(x[6912])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6969])]][:y_idx] == 6970 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6969])]][:id] == 25 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6969])]][:lifted_constr_ref] == :(x[6970] == x[6903] * x[6969]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6969])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6969])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6969])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6914])]][:y_idx] == 6915 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6914])]][:id] == 3 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6914])]][:lifted_constr_ref] == :(x[6915] == x[6903] * x[6914]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6914])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6914])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6914])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6919])]][:y_idx] == 6920 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6919])]][:id] == 5 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6919])]][:lifted_constr_ref] == :(x[6920] == x[6903] * x[6919]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6919])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6919])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6919])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[6927]), :(x[6927])]][:y_idx] == 6928 + @test alpine.nonconvex_terms[Expr[:(x[6927]), :(x[6927])]][:id] == 8 + @test alpine.nonconvex_terms[Expr[:(x[6927]), :(x[6927])]][:lifted_constr_ref] == :(x[6928] == (*)(x[6927])) + @test alpine.nonconvex_terms[Expr[:(x[6927]), :(x[6927])]][:nonlinear_type] == :MONOMIAL + @test alpine.nonconvex_terms[Expr[:(x[6927]), :(x[6927])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[6927]), :(x[6927])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[6952]), :(x[6952])]][:y_idx] == 6953 + @test alpine.nonconvex_terms[Expr[:(x[6952]), :(x[6952])]][:id] == 18 + @test alpine.nonconvex_terms[Expr[:(x[6952]), :(x[6952])]][:lifted_constr_ref] == :(x[6953] == (*)(x[6952])) + @test alpine.nonconvex_terms[Expr[:(x[6952]), :(x[6952])]][:nonlinear_type] == :MONOMIAL + @test alpine.nonconvex_terms[Expr[:(x[6952]), :(x[6952])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[6952]), :(x[6952])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[6962]), :(x[6962])]][:y_idx] == 6963 + @test alpine.nonconvex_terms[Expr[:(x[6962]), :(x[6962])]][:id] == 22 + @test alpine.nonconvex_terms[Expr[:(x[6962]), :(x[6962])]][:lifted_constr_ref] == :(x[6963] == (*)(x[6962])) + @test alpine.nonconvex_terms[Expr[:(x[6962]), :(x[6962])]][:nonlinear_type] == :MONOMIAL + @test alpine.nonconvex_terms[Expr[:(x[6962]), :(x[6962])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[6962]), :(x[6962])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6974])]][:y_idx] == 6975 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6974])]][:id] == 27 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6974])]][:lifted_constr_ref] == :(x[6975] == x[6903] * x[6974]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6974])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6974])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6974])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6934])]][:y_idx] == 6935 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6934])]][:id] == 11 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6934])]][:lifted_constr_ref] == :(x[6935] == x[6903] * x[6934]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6934])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6934])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6934])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6959])]][:y_idx] == 6960 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6959])]][:id] == 21 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6959])]][:lifted_constr_ref] == :(x[6960] == x[6903] * x[6959]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6959])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6959])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6959])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[7014])]][:y_idx] == 7015 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[7014])]][:id] == 43 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[7014])]][:lifted_constr_ref] == :(x[7015] == x[6903] * x[7014]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[7014])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[7014])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[7014])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6939])]][:y_idx] == 6940 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6939])]][:id] == 13 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6939])]][:lifted_constr_ref] == :(x[6940] == x[6903] * x[6939]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6939])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6939])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6939])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[7017]), :(x[7017])]][:y_idx] == 7018 + @test alpine.nonconvex_terms[Expr[:(x[7017]), :(x[7017])]][:id] == 44 + @test alpine.nonconvex_terms[Expr[:(x[7017]), :(x[7017])]][:lifted_constr_ref] == :(x[7018] == (*)(x[7017])) + @test alpine.nonconvex_terms[Expr[:(x[7017]), :(x[7017])]][:nonlinear_type] == :MONOMIAL + @test alpine.nonconvex_terms[Expr[:(x[7017]), :(x[7017])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[7017]), :(x[7017])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6929])]][:y_idx] == 6930 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6929])]][:id] == 9 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6929])]][:lifted_constr_ref] == :(x[6930] == x[6903] * x[6929]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6929])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6929])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6929])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[7012]), :(x[7012])]][:y_idx] == 7013 + @test alpine.nonconvex_terms[Expr[:(x[7012]), :(x[7012])]][:id] == 42 + @test alpine.nonconvex_terms[Expr[:(x[7012]), :(x[7012])]][:lifted_constr_ref] == :(x[7013] == (*)(x[7012])) + @test alpine.nonconvex_terms[Expr[:(x[7012]), :(x[7012])]][:nonlinear_type] == :MONOMIAL + @test alpine.nonconvex_terms[Expr[:(x[7012]), :(x[7012])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[7012]), :(x[7012])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[6947]), :(x[6947])]][:y_idx] == 6948 + @test alpine.nonconvex_terms[Expr[:(x[6947]), :(x[6947])]][:id] == 16 + @test alpine.nonconvex_terms[Expr[:(x[6947]), :(x[6947])]][:lifted_constr_ref] == :(x[6948] == (*)(x[6947])) + @test alpine.nonconvex_terms[Expr[:(x[6947]), :(x[6947])]][:nonlinear_type] == :MONOMIAL + @test alpine.nonconvex_terms[Expr[:(x[6947]), :(x[6947])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[6947]), :(x[6947])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[7032]), :(x[7032])]][:y_idx] == 7033 + @test alpine.nonconvex_terms[Expr[:(x[7032]), :(x[7032])]][:id] == 50 + @test alpine.nonconvex_terms[Expr[:(x[7032]), :(x[7032])]][:lifted_constr_ref] == :(x[7033] == (*)(x[7032])) + @test alpine.nonconvex_terms[Expr[:(x[7032]), :(x[7032])]][:nonlinear_type] == :MONOMIAL + @test alpine.nonconvex_terms[Expr[:(x[7032]), :(x[7032])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[7032]), :(x[7032])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[6997]), :(x[6997])]][:y_idx] == 6998 + @test alpine.nonconvex_terms[Expr[:(x[6997]), :(x[6997])]][:id] == 36 + @test alpine.nonconvex_terms[Expr[:(x[6997]), :(x[6997])]][:lifted_constr_ref] == :(x[6998] == (*)(x[6997])) + @test alpine.nonconvex_terms[Expr[:(x[6997]), :(x[6997])]][:nonlinear_type] == :MONOMIAL + @test alpine.nonconvex_terms[Expr[:(x[6997]), :(x[6997])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[6997]), :(x[6997])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[7027]), :(x[7027])]][:y_idx] == 7028 + @test alpine.nonconvex_terms[Expr[:(x[7027]), :(x[7027])]][:id] == 48 + @test alpine.nonconvex_terms[Expr[:(x[7027]), :(x[7027])]][:lifted_constr_ref] == :(x[7028] == (*)(x[7027])) + @test alpine.nonconvex_terms[Expr[:(x[7027]), :(x[7027])]][:nonlinear_type] == :MONOMIAL + @test alpine.nonconvex_terms[Expr[:(x[7027]), :(x[7027])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[7027]), :(x[7027])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[7037]), :(x[7037])]][:y_idx] == 7038 + @test alpine.nonconvex_terms[Expr[:(x[7037]), :(x[7037])]][:id] == 52 + @test alpine.nonconvex_terms[Expr[:(x[7037]), :(x[7037])]][:lifted_constr_ref] == :(x[7038] == (*)(x[7037])) + @test alpine.nonconvex_terms[Expr[:(x[7037]), :(x[7037])]][:nonlinear_type] == :MONOMIAL + @test alpine.nonconvex_terms[Expr[:(x[7037]), :(x[7037])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[7037]), :(x[7037])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[7007]), :(x[7007])]][:y_idx] == 7008 + @test alpine.nonconvex_terms[Expr[:(x[7007]), :(x[7007])]][:id] == 40 + @test alpine.nonconvex_terms[Expr[:(x[7007]), :(x[7007])]][:lifted_constr_ref] == :(x[7008] == (*)(x[7007])) + @test alpine.nonconvex_terms[Expr[:(x[7007]), :(x[7007])]][:nonlinear_type] == :MONOMIAL + @test alpine.nonconvex_terms[Expr[:(x[7007]), :(x[7007])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[7007]), :(x[7007])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6964])]][:y_idx] == 6965 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6964])]][:id] == 23 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6964])]][:lifted_constr_ref] == :(x[6965] == x[6903] * x[6964]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6964])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6964])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6964])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6924])]][:y_idx] == 6925 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6924])]][:id] == 7 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6924])]][:lifted_constr_ref] == :(x[6925] == x[6903] * x[6924]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6924])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6924])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6924])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6979])]][:y_idx] == 6980 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6979])]][:id] == 29 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6979])]][:lifted_constr_ref] == :(x[6980] == x[6903] * x[6979]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6979])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6979])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6979])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6994])]][:y_idx] == 6995 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6994])]][:id] == 35 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6994])]][:lifted_constr_ref] == :(x[6995] == x[6903] * x[6994]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6994])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6994])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6994])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[6972]), :(x[6972])]][:y_idx] == 6973 + @test alpine.nonconvex_terms[Expr[:(x[6972]), :(x[6972])]][:id] == 26 + @test alpine.nonconvex_terms[Expr[:(x[6972]), :(x[6972])]][:lifted_constr_ref] == :(x[6973] == (*)(x[6972])) + @test alpine.nonconvex_terms[Expr[:(x[6972]), :(x[6972])]][:nonlinear_type] == :MONOMIAL + @test alpine.nonconvex_terms[Expr[:(x[6972]), :(x[6972])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[6972]), :(x[6972])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[7019])]][:y_idx] == 7020 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[7019])]][:id] == 45 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[7019])]][:lifted_constr_ref] == :(x[7020] == x[6903] * x[7019]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[7019])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[7019])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[7019])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[6992]), :(x[6992])]][:y_idx] == 6993 + @test alpine.nonconvex_terms[Expr[:(x[6992]), :(x[6992])]][:id] == 34 + @test alpine.nonconvex_terms[Expr[:(x[6992]), :(x[6992])]][:lifted_constr_ref] == :(x[6993] == (*)(x[6992])) + @test alpine.nonconvex_terms[Expr[:(x[6992]), :(x[6992])]][:nonlinear_type] == :MONOMIAL + @test alpine.nonconvex_terms[Expr[:(x[6992]), :(x[6992])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[6992]), :(x[6992])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[7002]), :(x[7002])]][:y_idx] == 7003 + @test alpine.nonconvex_terms[Expr[:(x[7002]), :(x[7002])]][:id] == 38 + @test alpine.nonconvex_terms[Expr[:(x[7002]), :(x[7002])]][:lifted_constr_ref] == :(x[7003] == (*)(x[7002])) + @test alpine.nonconvex_terms[Expr[:(x[7002]), :(x[7002])]][:nonlinear_type] == :MONOMIAL + @test alpine.nonconvex_terms[Expr[:(x[7002]), :(x[7002])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[7002]), :(x[7002])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[7022]), :(x[7022])]][:y_idx] == 7023 + @test alpine.nonconvex_terms[Expr[:(x[7022]), :(x[7022])]][:id] == 46 + @test alpine.nonconvex_terms[Expr[:(x[7022]), :(x[7022])]][:lifted_constr_ref] == :(x[7023] == (*)(x[7022])) + @test alpine.nonconvex_terms[Expr[:(x[7022]), :(x[7022])]][:nonlinear_type] == :MONOMIAL + @test alpine.nonconvex_terms[Expr[:(x[7022]), :(x[7022])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[7022]), :(x[7022])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6908])]][:y_idx] == 6909 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6908])]][:id] == 1 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6908])]][:lifted_constr_ref] == :(x[6909] == x[6903] * x[6908]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6908])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6908])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6908])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6949])]][:y_idx] == 6950 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6949])]][:id] == 17 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6949])]][:lifted_constr_ref] == :(x[6950] == x[6903] * x[6949]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6949])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6949])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6949])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[7004])]][:y_idx] == 7005 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[7004])]][:id] == 39 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[7004])]][:lifted_constr_ref] == :(x[7005] == x[6903] * x[7004]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[7004])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[7004])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[7004])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[6917]), :(x[6917])]][:y_idx] == 6918 + @test alpine.nonconvex_terms[Expr[:(x[6917]), :(x[6917])]][:id] == 4 + @test alpine.nonconvex_terms[Expr[:(x[6917]), :(x[6917])]][:lifted_constr_ref] == :(x[6918] == (*)(x[6917])) + @test alpine.nonconvex_terms[Expr[:(x[6917]), :(x[6917])]][:nonlinear_type] == :MONOMIAL + @test alpine.nonconvex_terms[Expr[:(x[6917]), :(x[6917])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[6917]), :(x[6917])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[6937]), :(x[6937])]][:y_idx] == 6938 + @test alpine.nonconvex_terms[Expr[:(x[6937]), :(x[6937])]][:id] == 12 + @test alpine.nonconvex_terms[Expr[:(x[6937]), :(x[6937])]][:lifted_constr_ref] == :(x[6938] == (*)(x[6937])) + @test alpine.nonconvex_terms[Expr[:(x[6937]), :(x[6937])]][:nonlinear_type] == :MONOMIAL + @test alpine.nonconvex_terms[Expr[:(x[6937]), :(x[6937])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[6937]), :(x[6937])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[6932]), :(x[6932])]][:y_idx] == 6933 + @test alpine.nonconvex_terms[Expr[:(x[6932]), :(x[6932])]][:id] == 10 + @test alpine.nonconvex_terms[Expr[:(x[6932]), :(x[6932])]][:lifted_constr_ref] == :(x[6933] == (*)(x[6932])) + @test alpine.nonconvex_terms[Expr[:(x[6932]), :(x[6932])]][:nonlinear_type] == :MONOMIAL + @test alpine.nonconvex_terms[Expr[:(x[6932]), :(x[6932])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[6932]), :(x[6932])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6989])]][:y_idx] == 6990 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6989])]][:id] == 33 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6989])]][:lifted_constr_ref] == :(x[6990] == x[6903] * x[6989]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6989])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6989])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6989])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[6977]), :(x[6977])]][:y_idx] == 6978 + @test alpine.nonconvex_terms[Expr[:(x[6977]), :(x[6977])]][:id] == 28 + @test alpine.nonconvex_terms[Expr[:(x[6977]), :(x[6977])]][:lifted_constr_ref] == :(x[6978] == (*)(x[6977])) + @test alpine.nonconvex_terms[Expr[:(x[6977]), :(x[6977])]][:nonlinear_type] == :MONOMIAL + @test alpine.nonconvex_terms[Expr[:(x[6977]), :(x[6977])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[6977]), :(x[6977])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[6987]), :(x[6987])]][:y_idx] == 6988 + @test alpine.nonconvex_terms[Expr[:(x[6987]), :(x[6987])]][:id] == 32 + @test alpine.nonconvex_terms[Expr[:(x[6987]), :(x[6987])]][:lifted_constr_ref] == :(x[6988] == (*)(x[6987])) + @test alpine.nonconvex_terms[Expr[:(x[6987]), :(x[6987])]][:nonlinear_type] == :MONOMIAL + @test alpine.nonconvex_terms[Expr[:(x[6987]), :(x[6987])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[6987]), :(x[6987])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[7034])]][:y_idx] == 7035 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[7034])]][:id] == 51 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[7034])]][:lifted_constr_ref] == :(x[7035] == x[6903] * x[7034]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[7034])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[7034])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[7034])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[6967]), :(x[6967])]][:y_idx] == 6968 + @test alpine.nonconvex_terms[Expr[:(x[6967]), :(x[6967])]][:id] == 24 + @test alpine.nonconvex_terms[Expr[:(x[6967]), :(x[6967])]][:lifted_constr_ref] == :(x[6968] == (*)(x[6967])) + @test alpine.nonconvex_terms[Expr[:(x[6967]), :(x[6967])]][:nonlinear_type] == :MONOMIAL + @test alpine.nonconvex_terms[Expr[:(x[6967]), :(x[6967])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[6967]), :(x[6967])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[6957]), :(x[6957])]][:y_idx] == 6958 + @test alpine.nonconvex_terms[Expr[:(x[6957]), :(x[6957])]][:id] == 20 + @test alpine.nonconvex_terms[Expr[:(x[6957]), :(x[6957])]][:lifted_constr_ref] == :(x[6958] == (*)(x[6957])) + @test alpine.nonconvex_terms[Expr[:(x[6957]), :(x[6957])]][:nonlinear_type] == :MONOMIAL + @test alpine.nonconvex_terms[Expr[:(x[6957]), :(x[6957])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[6957]), :(x[6957])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[7009])]][:y_idx] == 7010 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[7009])]][:id] == 41 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[7009])]][:lifted_constr_ref] == :(x[7010] == x[6903] * x[7009]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[7009])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[7009])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[7009])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[6942]), :(x[6942])]][:y_idx] == 6943 + @test alpine.nonconvex_terms[Expr[:(x[6942]), :(x[6942])]][:id] == 14 + @test alpine.nonconvex_terms[Expr[:(x[6942]), :(x[6942])]][:lifted_constr_ref] == :(x[6943] == (*)(x[6942])) + @test alpine.nonconvex_terms[Expr[:(x[6942]), :(x[6942])]][:nonlinear_type] == :MONOMIAL + @test alpine.nonconvex_terms[Expr[:(x[6942]), :(x[6942])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[6942]), :(x[6942])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[6982]), :(x[6982])]][:y_idx] == 6983 + @test alpine.nonconvex_terms[Expr[:(x[6982]), :(x[6982])]][:id] == 30 + @test alpine.nonconvex_terms[Expr[:(x[6982]), :(x[6982])]][:lifted_constr_ref] == :(x[6983] == (*)(x[6982])) + @test alpine.nonconvex_terms[Expr[:(x[6982]), :(x[6982])]][:nonlinear_type] == :MONOMIAL + @test alpine.nonconvex_terms[Expr[:(x[6982]), :(x[6982])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[6982]), :(x[6982])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6999])]][:y_idx] == 7000 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6999])]][:id] == 37 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6999])]][:lifted_constr_ref] == :(x[7000] == x[6903] * x[6999]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6999])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6999])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6999])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6944])]][:y_idx] == 6945 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6944])]][:id] == 15 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6944])]][:lifted_constr_ref] == :(x[6945] == x[6903] * x[6944]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6944])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6944])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6944])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[7024])]][:y_idx] == 7025 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[7024])]][:id] == 47 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[7024])]][:lifted_constr_ref] == :(x[7025] == x[6903] * x[7024]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[7024])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[7024])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[7024])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6954])]][:y_idx] == 6955 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6954])]][:id] == 19 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6954])]][:lifted_constr_ref] == :(x[6955] == x[6903] * x[6954]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6954])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6954])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6954])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[6922]), :(x[6922])]][:y_idx] == 6923 + @test alpine.nonconvex_terms[Expr[:(x[6922]), :(x[6922])]][:id] == 6 + @test alpine.nonconvex_terms[Expr[:(x[6922]), :(x[6922])]][:lifted_constr_ref] == :(x[6923] == (*)(x[6922])) + @test alpine.nonconvex_terms[Expr[:(x[6922]), :(x[6922])]][:nonlinear_type] == :MONOMIAL + @test alpine.nonconvex_terms[Expr[:(x[6922]), :(x[6922])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[6922]), :(x[6922])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6984])]][:y_idx] == 6985 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6984])]][:id] == 31 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6984])]][:lifted_constr_ref] == :(x[6985] == x[6903] * x[6984]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6984])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6984])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[6984])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[7029])]][:y_idx] == 7030 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[7029])]][:id] == 49 + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[7029])]][:lifted_constr_ref] == :(x[7030] == x[6903] * x[7029]) + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[7029])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[7029])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[6903]), :(x[7029])]][:constr_id] == Set(Any[0]) lk1 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 6910), (-1.0, 6909)]))) - @test m.internalModel.linear_terms[lk1][:y_idx] == 6911 - @test m.internalModel.linear_terms[lk1][:id] == 3 - @test m.internalModel.linear_terms[lk1][:y_type] == :(Cont) + @test alpine.linear_terms[lk1][:y_idx] == 6911 + @test alpine.linear_terms[lk1][:id] == 3 + @test alpine.linear_terms[lk1][:y_type] == :(Cont) lk2 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 3467), (1.0, 16)]))) - @test m.internalModel.linear_terms[lk2][:y_idx] == 6908 - @test m.internalModel.linear_terms[lk2][:id] == 1 - @test m.internalModel.linear_terms[lk2][:y_type] == :(Cont) + @test alpine.linear_terms[lk2][:y_idx] == 6908 + @test alpine.linear_terms[lk2][:id] == 1 + @test alpine.linear_terms[lk2][:y_type] == :(Cont) lk3 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(0.001548, 6903), (1.0, 7016), (1.0, 5702)]))) - @test m.internalModel.linear_terms[lk3][:y_idx] == 7017 - @test m.internalModel.linear_terms[lk3][:id] == 67 - @test m.internalModel.linear_terms[lk3][:y_type] == :(Cont) + @test alpine.linear_terms[lk3][:y_idx] == 7017 + @test alpine.linear_terms[lk3][:id] == 67 + @test alpine.linear_terms[lk3][:y_type] == :(Cont) lk4 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 5162), (1.0, 1711)]))) - @test m.internalModel.linear_terms[lk4][:y_idx] == 7004 - @test m.internalModel.linear_terms[lk4][:id] == 59 - @test m.internalModel.linear_terms[lk4][:y_type] == :(Cont) + @test alpine.linear_terms[lk4][:y_idx] == 7004 + @test alpine.linear_terms[lk4][:id] == 59 + @test alpine.linear_terms[lk4][:y_type] == :(Cont) lk5 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 7021), (0.001435, 6903), (1.0, 6002)]))) - @test m.internalModel.linear_terms[lk5][:y_idx] == 7022 - @test m.internalModel.linear_terms[lk5][:id] == 70 - @test m.internalModel.linear_terms[lk5][:y_type] == :(Cont) + @test alpine.linear_terms[lk5][:y_idx] == 7022 + @test alpine.linear_terms[lk5][:id] == 70 + @test alpine.linear_terms[lk5][:y_type] == :(Cont) lk6 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(-1.0, 6935), (1.0, 166)]))) - @test m.internalModel.linear_terms[lk6][:y_idx] == 6936 - @test m.internalModel.linear_terms[lk6][:id] == 18 - @test m.internalModel.linear_terms[lk6][:y_type] == :(Cont) + @test alpine.linear_terms[lk6][:y_idx] == 6936 + @test alpine.linear_terms[lk6][:id] == 18 + @test alpine.linear_terms[lk6][:y_type] == :(Cont) lk7 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 4262), (0.00247, 6903), (1.0, 6981)]))) - @test m.internalModel.linear_terms[lk7][:y_idx] == 6982 - @test m.internalModel.linear_terms[lk7][:id] == 46 - @test m.internalModel.linear_terms[lk7][:y_type] == :(Cont) + @test alpine.linear_terms[lk7][:y_idx] == 6982 + @test alpine.linear_terms[lk7][:id] == 46 + @test alpine.linear_terms[lk7][:y_type] == :(Cont) lk8 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(-1.0, 7005), (1.0, 1711)]))) - @test m.internalModel.linear_terms[lk8][:y_idx] == 7006 - @test m.internalModel.linear_terms[lk8][:id] == 60 - @test m.internalModel.linear_terms[lk8][:y_type] == :(Cont) + @test alpine.linear_terms[lk8][:y_idx] == 7006 + @test alpine.linear_terms[lk8][:id] == 60 + @test alpine.linear_terms[lk8][:y_type] == :(Cont) lk9 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 1951), (1.0, 5402)]))) - @test m.internalModel.linear_terms[lk9][:y_idx] == 7009 - @test m.internalModel.linear_terms[lk9][:id] == 62 - @test m.internalModel.linear_terms[lk9][:y_type] == :(Cont) + @test alpine.linear_terms[lk9][:y_idx] == 7009 + @test alpine.linear_terms[lk9][:id] == 62 + @test alpine.linear_terms[lk9][:y_type] == :(Cont) lk10 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 226), (-1.0, 6945)]))) - @test m.internalModel.linear_terms[lk10][:y_idx] == 6946 - @test m.internalModel.linear_terms[lk10][:id] == 24 - @test m.internalModel.linear_terms[lk10][:y_type] == :(Cont) + @test alpine.linear_terms[lk10][:y_idx] == 6946 + @test alpine.linear_terms[lk10][:id] == 24 + @test alpine.linear_terms[lk10][:y_type] == :(Cont) lk11 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(-1.0, 7030), (1.0, 3151)]))) - @test m.internalModel.linear_terms[lk11][:y_idx] == 7031 - @test m.internalModel.linear_terms[lk11][:id] == 75 - @test m.internalModel.linear_terms[lk11][:y_type] == :(Cont) + @test alpine.linear_terms[lk11][:y_idx] == 7031 + @test alpine.linear_terms[lk11][:id] == 75 + @test alpine.linear_terms[lk11][:y_type] == :(Cont) lk12 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 6991), (1.0, 4622), (0.002066, 6903)]))) - @test m.internalModel.linear_terms[lk12][:y_idx] == 6992 - @test m.internalModel.linear_terms[lk12][:id] == 52 - @test m.internalModel.linear_terms[lk12][:y_type] == :(Cont) + @test alpine.linear_terms[lk12][:y_idx] == 6992 + @test alpine.linear_terms[lk12][:id] == 52 + @test alpine.linear_terms[lk12][:y_type] == :(Cont) lk13 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 7026), (1.0, 6302), (0.001323, 6903)]))) - @test m.internalModel.linear_terms[lk13][:y_idx] == 7027 - @test m.internalModel.linear_terms[lk13][:id] == 73 - @test m.internalModel.linear_terms[lk13][:y_type] == :(Cont) + @test alpine.linear_terms[lk13][:y_idx] == 7027 + @test alpine.linear_terms[lk13][:id] == 73 + @test alpine.linear_terms[lk13][:y_type] == :(Cont) lk14 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 46), (1.0, 3497)]))) - @test m.internalModel.linear_terms[lk14][:y_idx] == 6914 - @test m.internalModel.linear_terms[lk14][:id] == 5 - @test m.internalModel.linear_terms[lk14][:y_type] == :(Cont) + @test alpine.linear_terms[lk14][:y_idx] == 6914 + @test alpine.linear_terms[lk14][:id] == 5 + @test alpine.linear_terms[lk14][:y_type] == :(Cont) lk15 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(-1.0, 6960), (1.0, 391)]))) - @test m.internalModel.linear_terms[lk15][:y_idx] == 6961 - @test m.internalModel.linear_terms[lk15][:id] == 33 - @test m.internalModel.linear_terms[lk15][:y_type] == :(Cont) + @test alpine.linear_terms[lk15][:y_idx] == 6961 + @test alpine.linear_terms[lk15][:id] == 33 + @test alpine.linear_terms[lk15][:y_type] == :(Cont) lk16 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 631), (-1.0, 6975)]))) - @test m.internalModel.linear_terms[lk16][:y_idx] == 6976 - @test m.internalModel.linear_terms[lk16][:id] == 42 - @test m.internalModel.linear_terms[lk16][:y_type] == :(Cont) + @test alpine.linear_terms[lk16][:y_idx] == 6976 + @test alpine.linear_terms[lk16][:id] == 42 + @test alpine.linear_terms[lk16][:y_type] == :(Cont) lk17 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 1351), (-1.0, 6995)]))) - @test m.internalModel.linear_terms[lk17][:y_idx] == 6996 - @test m.internalModel.linear_terms[lk17][:id] == 54 - @test m.internalModel.linear_terms[lk17][:y_type] == :(Cont) + @test alpine.linear_terms[lk17][:y_idx] == 6996 + @test alpine.linear_terms[lk17][:id] == 54 + @test alpine.linear_terms[lk17][:y_type] == :(Cont) lk18 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 3557), (1.0, 106)]))) - @test m.internalModel.linear_terms[lk18][:y_idx] == 6924 - @test m.internalModel.linear_terms[lk18][:id] == 11 - @test m.internalModel.linear_terms[lk18][:y_type] == :(Cont) + @test alpine.linear_terms[lk18][:y_idx] == 6924 + @test alpine.linear_terms[lk18][:id] == 11 + @test alpine.linear_terms[lk18][:y_type] == :(Cont) lk19 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 3647), (1.0, 6941), (0.004795, 6903)]))) - @test m.internalModel.linear_terms[lk19][:y_idx] == 6942 - @test m.internalModel.linear_terms[lk19][:id] == 22 - @test m.internalModel.linear_terms[lk19][:y_type] == :(Cont) + @test alpine.linear_terms[lk19][:y_idx] == 6942 + @test alpine.linear_terms[lk19][:id] == 22 + @test alpine.linear_terms[lk19][:y_type] == :(Cont) lk20 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 3722), (1.0, 271)]))) - @test m.internalModel.linear_terms[lk20][:y_idx] == 6949 - @test m.internalModel.linear_terms[lk20][:id] == 26 - @test m.internalModel.linear_terms[lk20][:y_type] == :(Cont) + @test alpine.linear_terms[lk20][:y_idx] == 6949 + @test alpine.linear_terms[lk20][:id] == 26 + @test alpine.linear_terms[lk20][:y_type] == :(Cont) lk21 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 3647), (1.0, 196)]))) - @test m.internalModel.linear_terms[lk21][:y_idx] == 6939 - @test m.internalModel.linear_terms[lk21][:id] == 20 - @test m.internalModel.linear_terms[lk21][:y_type] == :(Cont) + @test alpine.linear_terms[lk21][:y_idx] == 6939 + @test alpine.linear_terms[lk21][:id] == 20 + @test alpine.linear_terms[lk21][:y_type] == :(Cont) lk22 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 3467), (1.0, 6911), (6.34e-6, 6903)]))) - @test m.internalModel.linear_terms[lk22][:y_idx] == 6912 - @test m.internalModel.linear_terms[lk22][:id] == 4 - @test m.internalModel.linear_terms[lk22][:y_type] == :(Cont) + @test alpine.linear_terms[lk22][:y_idx] == 6912 + @test alpine.linear_terms[lk22][:id] == 4 + @test alpine.linear_terms[lk22][:y_type] == :(Cont) lk23 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 1531), (1.0, 4982)]))) - @test m.internalModel.linear_terms[lk23][:y_idx] == 6999 - @test m.internalModel.linear_terms[lk23][:id] == 56 - @test m.internalModel.linear_terms[lk23][:y_type] == :(Cont) + @test alpine.linear_terms[lk23][:y_idx] == 6999 + @test alpine.linear_terms[lk23][:id] == 56 + @test alpine.linear_terms[lk23][:y_type] == :(Cont) lk24 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 106), (-1.0, 6925)]))) - @test m.internalModel.linear_terms[lk24][:y_idx] == 6926 - @test m.internalModel.linear_terms[lk24][:id] == 12 - @test m.internalModel.linear_terms[lk24][:y_type] == :(Cont) + @test alpine.linear_terms[lk24][:y_idx] == 6926 + @test alpine.linear_terms[lk24][:id] == 12 + @test alpine.linear_terms[lk24][:y_type] == :(Cont) lk25 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 2251), (-1.0, 7015)]))) - @test m.internalModel.linear_terms[lk25][:y_idx] == 7016 - @test m.internalModel.linear_terms[lk25][:id] == 66 - @test m.internalModel.linear_terms[lk25][:y_type] == :(Cont) + @test alpine.linear_terms[lk25][:y_idx] == 7016 + @test alpine.linear_terms[lk25][:id] == 66 + @test alpine.linear_terms[lk25][:y_type] == :(Cont) lk26 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 6936), (0.004985, 6903), (1.0, 3617)]))) - @test m.internalModel.linear_terms[lk26][:y_idx] == 6937 - @test m.internalModel.linear_terms[lk26][:id] == 19 - @test m.internalModel.linear_terms[lk26][:y_type] == :(Cont) + @test alpine.linear_terms[lk26][:y_idx] == 6937 + @test alpine.linear_terms[lk26][:id] == 19 + @test alpine.linear_terms[lk26][:y_type] == :(Cont) lk27 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(-1.0, 6915), (1.0, 46)]))) - @test m.internalModel.linear_terms[lk27][:y_idx] == 6916 - @test m.internalModel.linear_terms[lk27][:id] == 6 - @test m.internalModel.linear_terms[lk27][:y_type] == :(Cont) + @test alpine.linear_terms[lk27][:y_idx] == 6916 + @test alpine.linear_terms[lk27][:id] == 6 + @test alpine.linear_terms[lk27][:y_type] == :(Cont) lk28 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 3557), (0.005968, 6903), (1.0, 6926)]))) - @test m.internalModel.linear_terms[lk28][:y_idx] == 6927 - @test m.internalModel.linear_terms[lk28][:id] == 13 - @test m.internalModel.linear_terms[lk28][:y_type] == :(Cont) + @test alpine.linear_terms[lk28][:y_idx] == 6927 + @test alpine.linear_terms[lk28][:id] == 13 + @test alpine.linear_terms[lk28][:y_type] == :(Cont) lk29 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 271), (-1.0, 6950)]))) - @test m.internalModel.linear_terms[lk29][:y_idx] == 6951 - @test m.internalModel.linear_terms[lk29][:id] == 27 - @test m.internalModel.linear_terms[lk29][:y_type] == :(Cont) + @test alpine.linear_terms[lk29][:y_idx] == 6951 + @test alpine.linear_terms[lk29][:id] == 27 + @test alpine.linear_terms[lk29][:y_type] == :(Cont) lk30 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(0.002971, 6903), (1.0, 6971), (1.0, 3962)]))) - @test m.internalModel.linear_terms[lk30][:y_idx] == 6972 - @test m.internalModel.linear_terms[lk30][:id] == 40 - @test m.internalModel.linear_terms[lk30][:y_type] == :(Cont) + @test alpine.linear_terms[lk30][:y_idx] == 6972 + @test alpine.linear_terms[lk30][:id] == 40 + @test alpine.linear_terms[lk30][:y_type] == :(Cont) lk31 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 511), (-1.0, 6970)]))) - @test m.internalModel.linear_terms[lk31][:y_idx] == 6971 - @test m.internalModel.linear_terms[lk31][:id] == 39 - @test m.internalModel.linear_terms[lk31][:y_type] == :(Cont) + @test alpine.linear_terms[lk31][:y_idx] == 6971 + @test alpine.linear_terms[lk31][:id] == 39 + @test alpine.linear_terms[lk31][:y_type] == :(Cont) lk32 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 7031), (1.0, 6602), (0.00121, 6903)]))) - @test m.internalModel.linear_terms[lk32][:y_idx] == 7032 - @test m.internalModel.linear_terms[lk32][:id] == 76 - @test m.internalModel.linear_terms[lk32][:y_type] == :(Cont) + @test alpine.linear_terms[lk32][:y_idx] == 7032 + @test alpine.linear_terms[lk32][:id] == 76 + @test alpine.linear_terms[lk32][:y_type] == :(Cont) lk33 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(0.00166, 6903), (1.0, 7011), (1.0, 5402)]))) - @test m.internalModel.linear_terms[lk33][:y_idx] == 7012 - @test m.internalModel.linear_terms[lk33][:id] == 64 - @test m.internalModel.linear_terms[lk33][:y_type] == :(Cont) + @test alpine.linear_terms[lk33][:y_idx] == 7012 + @test alpine.linear_terms[lk33][:id] == 64 + @test alpine.linear_terms[lk33][:y_type] == :(Cont) lk34 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, -0.003214),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 16)]))) - @test m.internalModel.linear_terms[lk34][:y_idx] == 6910 - @test m.internalModel.linear_terms[lk34][:id] == 2 - @test m.internalModel.linear_terms[lk34][:y_type] == :(Cont) + @test alpine.linear_terms[lk34][:y_idx] == 6910 + @test alpine.linear_terms[lk34][:id] == 2 + @test alpine.linear_terms[lk34][:y_type] == :(Cont) lk35 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(-1.0, 7035), (1.0, 3451)]))) - @test m.internalModel.linear_terms[lk35][:y_idx] == 7036 - @test m.internalModel.linear_terms[lk35][:id] == 78 - @test m.internalModel.linear_terms[lk35][:y_type] == :(Cont) + @test alpine.linear_terms[lk35][:y_idx] == 7036 + @test alpine.linear_terms[lk35][:id] == 78 + @test alpine.linear_terms[lk35][:y_type] == :(Cont) lk36 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 2551), (1.0, 6002)]))) - @test m.internalModel.linear_terms[lk36][:y_idx] == 7019 - @test m.internalModel.linear_terms[lk36][:id] == 68 - @test m.internalModel.linear_terms[lk36][:y_type] == :(Cont) + @test alpine.linear_terms[lk36][:y_idx] == 7019 + @test alpine.linear_terms[lk36][:id] == 68 + @test alpine.linear_terms[lk36][:y_type] == :(Cont) lk37 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 3842), (1.0, 391)]))) - @test m.internalModel.linear_terms[lk37][:y_idx] == 6959 - @test m.internalModel.linear_terms[lk37][:id] == 32 - @test m.internalModel.linear_terms[lk37][:y_type] == :(Cont) + @test alpine.linear_terms[lk37][:y_idx] == 6959 + @test alpine.linear_terms[lk37][:id] == 32 + @test alpine.linear_terms[lk37][:y_type] == :(Cont) lk38 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 6966), (0.00307, 6903), (1.0, 3902)]))) - @test m.internalModel.linear_terms[lk38][:y_idx] == 6967 - @test m.internalModel.linear_terms[lk38][:id] == 37 - @test m.internalModel.linear_terms[lk38][:y_type] == :(Cont) + @test alpine.linear_terms[lk38][:y_idx] == 6967 + @test alpine.linear_terms[lk38][:id] == 37 + @test alpine.linear_terms[lk38][:y_type] == :(Cont) lk39 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 3722), (0.003829, 6903), (1.0, 6951)]))) - @test m.internalModel.linear_terms[lk39][:y_idx] == 6952 - @test m.internalModel.linear_terms[lk39][:id] == 28 - @test m.internalModel.linear_terms[lk39][:y_type] == :(Cont) + @test alpine.linear_terms[lk39][:y_idx] == 6952 + @test alpine.linear_terms[lk39][:id] == 28 + @test alpine.linear_terms[lk39][:y_type] == :(Cont) lk40 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 451), (1.0, 3902)]))) - @test m.internalModel.linear_terms[lk40][:y_idx] == 6964 - @test m.internalModel.linear_terms[lk40][:id] == 35 - @test m.internalModel.linear_terms[lk40][:y_type] == :(Cont) + @test alpine.linear_terms[lk40][:y_idx] == 6964 + @test alpine.linear_terms[lk40][:id] == 35 + @test alpine.linear_terms[lk40][:y_type] == :(Cont) lk41 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 7006), (1.0, 5162), (0.001713, 6903)]))) - @test m.internalModel.linear_terms[lk41][:y_idx] == 7007 - @test m.internalModel.linear_terms[lk41][:id] == 61 - @test m.internalModel.linear_terms[lk41][:y_type] == :(Cont) + @test alpine.linear_terms[lk41][:y_idx] == 7007 + @test alpine.linear_terms[lk41][:id] == 61 + @test alpine.linear_terms[lk41][:y_type] == :(Cont) lk42 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 811), (-1.0, 6980)]))) - @test m.internalModel.linear_terms[lk42][:y_idx] == 6981 - @test m.internalModel.linear_terms[lk42][:id] == 45 - @test m.internalModel.linear_terms[lk42][:y_type] == :(Cont) + @test alpine.linear_terms[lk42][:y_idx] == 6981 + @test alpine.linear_terms[lk42][:id] == 45 + @test alpine.linear_terms[lk42][:y_type] == :(Cont) lk43 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 7001), (1.0, 4982), (0.00173, 6903)]))) - @test m.internalModel.linear_terms[lk43][:y_idx] == 7002 - @test m.internalModel.linear_terms[lk43][:id] == 58 - @test m.internalModel.linear_terms[lk43][:y_type] == :(Cont) + @test alpine.linear_terms[lk43][:y_idx] == 7002 + @test alpine.linear_terms[lk43][:id] == 58 + @test alpine.linear_terms[lk43][:y_type] == :(Cont) lk44 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(-1.0, 6920), (1.0, 76)]))) - @test m.internalModel.linear_terms[lk44][:y_idx] == 6921 - @test m.internalModel.linear_terms[lk44][:id] == 9 - @test m.internalModel.linear_terms[lk44][:y_type] == :(Cont) + @test alpine.linear_terms[lk44][:y_idx] == 6921 + @test alpine.linear_terms[lk44][:id] == 9 + @test alpine.linear_terms[lk44][:y_type] == :(Cont) lk45 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 4622), (1.0, 1171)]))) - @test m.internalModel.linear_terms[lk45][:y_idx] == 6989 - @test m.internalModel.linear_terms[lk45][:id] == 50 - @test m.internalModel.linear_terms[lk45][:y_type] == :(Cont) + @test alpine.linear_terms[lk45][:y_idx] == 6989 + @test alpine.linear_terms[lk45][:id] == 50 + @test alpine.linear_terms[lk45][:y_type] == :(Cont) lk46 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 991), (1.0, 4442)]))) - @test m.internalModel.linear_terms[lk46][:y_idx] == 6984 - @test m.internalModel.linear_terms[lk46][:id] == 47 - @test m.internalModel.linear_terms[lk46][:y_type] == :(Cont) + @test alpine.linear_terms[lk46][:y_idx] == 6984 + @test alpine.linear_terms[lk46][:id] == 47 + @test alpine.linear_terms[lk46][:y_type] == :(Cont) lk47 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(-1.0, 6930), (1.0, 136)]))) - @test m.internalModel.linear_terms[lk47][:y_idx] == 6931 - @test m.internalModel.linear_terms[lk47][:id] == 15 - @test m.internalModel.linear_terms[lk47][:y_type] == :(Cont) + @test alpine.linear_terms[lk47][:y_idx] == 6931 + @test alpine.linear_terms[lk47][:id] == 15 + @test alpine.linear_terms[lk47][:y_type] == :(Cont) lk48 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 4802), (0.001891, 6903), (1.0, 6996)]))) - @test m.internalModel.linear_terms[lk48][:y_idx] == 6997 - @test m.internalModel.linear_terms[lk48][:id] == 55 - @test m.internalModel.linear_terms[lk48][:y_type] == :(Cont) + @test alpine.linear_terms[lk48][:y_idx] == 6997 + @test alpine.linear_terms[lk48][:id] == 55 + @test alpine.linear_terms[lk48][:y_type] == :(Cont) lk49 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 511), (1.0, 3962)]))) - @test m.internalModel.linear_terms[lk49][:y_idx] == 6969 - @test m.internalModel.linear_terms[lk49][:id] == 38 - @test m.internalModel.linear_terms[lk49][:y_type] == :(Cont) + @test alpine.linear_terms[lk49][:y_idx] == 6969 + @test alpine.linear_terms[lk49][:id] == 38 + @test alpine.linear_terms[lk49][:y_type] == :(Cont) lk50 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 811), (1.0, 4262)]))) - @test m.internalModel.linear_terms[lk50][:y_idx] == 6979 - @test m.internalModel.linear_terms[lk50][:id] == 44 - @test m.internalModel.linear_terms[lk50][:y_type] == :(Cont) + @test alpine.linear_terms[lk50][:y_idx] == 6979 + @test alpine.linear_terms[lk50][:id] == 44 + @test alpine.linear_terms[lk50][:y_type] == :(Cont) lk51 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(0.01551, 6903), (1.0, 6916), (1.0, 3497)]))) - @test m.internalModel.linear_terms[lk51][:y_idx] == 6917 - @test m.internalModel.linear_terms[lk51][:id] == 7 - @test m.internalModel.linear_terms[lk51][:y_type] == :(Cont) + @test alpine.linear_terms[lk51][:y_idx] == 6917 + @test alpine.linear_terms[lk51][:id] == 7 + @test alpine.linear_terms[lk51][:y_type] == :(Cont) lk52 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 451), (-1.0, 6965)]))) - @test m.internalModel.linear_terms[lk52][:y_idx] == 6966 - @test m.internalModel.linear_terms[lk52][:id] == 36 - @test m.internalModel.linear_terms[lk52][:y_type] == :(Cont) + @test alpine.linear_terms[lk52][:y_idx] == 6966 + @test alpine.linear_terms[lk52][:id] == 36 + @test alpine.linear_terms[lk52][:y_type] == :(Cont) lk53 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(0.005773, 6903), (1.0, 3587), (1.0, 6931)]))) - @test m.internalModel.linear_terms[lk53][:y_idx] == 6932 - @test m.internalModel.linear_terms[lk53][:id] == 16 - @test m.internalModel.linear_terms[lk53][:y_type] == :(Cont) + @test alpine.linear_terms[lk53][:y_idx] == 6932 + @test alpine.linear_terms[lk53][:id] == 16 + @test alpine.linear_terms[lk53][:y_type] == :(Cont) lk54 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 631), (1.0, 4082)]))) - @test m.internalModel.linear_terms[lk54][:y_idx] == 6974 - @test m.internalModel.linear_terms[lk54][:id] == 41 - @test m.internalModel.linear_terms[lk54][:y_type] == :(Cont) + @test alpine.linear_terms[lk54][:y_idx] == 6974 + @test alpine.linear_terms[lk54][:id] == 41 + @test alpine.linear_terms[lk54][:y_type] == :(Cont) lk55 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 991), (-1.0, 6985)]))) - @test m.internalModel.linear_terms[lk55][:y_idx] == 6986 - @test m.internalModel.linear_terms[lk55][:id] == 48 - @test m.internalModel.linear_terms[lk55][:y_type] == :(Cont) + @test alpine.linear_terms[lk55][:y_idx] == 6986 + @test alpine.linear_terms[lk55][:id] == 48 + @test alpine.linear_terms[lk55][:y_type] == :(Cont) lk56 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 4802), (1.0, 1351)]))) - @test m.internalModel.linear_terms[lk56][:y_idx] == 6994 - @test m.internalModel.linear_terms[lk56][:id] == 53 - @test m.internalModel.linear_terms[lk56][:y_type] == :(Cont) + @test alpine.linear_terms[lk56][:y_idx] == 6994 + @test alpine.linear_terms[lk56][:id] == 53 + @test alpine.linear_terms[lk56][:y_type] == :(Cont) lk57 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 6946), (0.004409, 6903), (1.0, 3677)]))) - @test m.internalModel.linear_terms[lk57][:y_idx] == 6947 - @test m.internalModel.linear_terms[lk57][:id] == 25 - @test m.internalModel.linear_terms[lk57][:y_type] == :(Cont) + @test alpine.linear_terms[lk57][:y_idx] == 6947 + @test alpine.linear_terms[lk57][:id] == 25 + @test alpine.linear_terms[lk57][:y_type] == :(Cont) lk58 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 2251), (1.0, 5702)]))) - @test m.internalModel.linear_terms[lk58][:y_idx] == 7014 - @test m.internalModel.linear_terms[lk58][:id] == 65 - @test m.internalModel.linear_terms[lk58][:y_type] == :(Cont) + @test alpine.linear_terms[lk58][:y_idx] == 7014 + @test alpine.linear_terms[lk58][:id] == 65 + @test alpine.linear_terms[lk58][:y_type] == :(Cont) lk59 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(-1.0, 7020), (1.0, 2551)]))) - @test m.internalModel.linear_terms[lk59][:y_idx] == 7021 - @test m.internalModel.linear_terms[lk59][:id] == 69 - @test m.internalModel.linear_terms[lk59][:y_type] == :(Cont) + @test alpine.linear_terms[lk59][:y_idx] == 7021 + @test alpine.linear_terms[lk59][:id] == 69 + @test alpine.linear_terms[lk59][:y_type] == :(Cont) lk60 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(-1.0, 6940), (1.0, 196)]))) - @test m.internalModel.linear_terms[lk60][:y_idx] == 6941 - @test m.internalModel.linear_terms[lk60][:id] == 21 - @test m.internalModel.linear_terms[lk60][:y_type] == :(Cont) + @test alpine.linear_terms[lk60][:y_idx] == 6941 + @test alpine.linear_terms[lk60][:id] == 21 + @test alpine.linear_terms[lk60][:y_type] == :(Cont) lk61 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 3527), (1.0, 6921), (0.008919, 6903)]))) - @test m.internalModel.linear_terms[lk61][:y_idx] == 6922 - @test m.internalModel.linear_terms[lk61][:id] == 10 - @test m.internalModel.linear_terms[lk61][:y_type] == :(Cont) + @test alpine.linear_terms[lk61][:y_idx] == 6922 + @test alpine.linear_terms[lk61][:id] == 10 + @test alpine.linear_terms[lk61][:y_type] == :(Cont) lk62 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(-1.0, 7025), (1.0, 2851)]))) - @test m.internalModel.linear_terms[lk62][:y_idx] == 7026 - @test m.internalModel.linear_terms[lk62][:id] == 72 - @test m.internalModel.linear_terms[lk62][:y_type] == :(Cont) + @test alpine.linear_terms[lk62][:y_idx] == 7026 + @test alpine.linear_terms[lk62][:id] == 72 + @test alpine.linear_terms[lk62][:y_type] == :(Cont) lk63 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 6986), (1.0, 4442), (0.002252, 6903)]))) - @test m.internalModel.linear_terms[lk63][:y_idx] == 6987 - @test m.internalModel.linear_terms[lk63][:id] == 49 - @test m.internalModel.linear_terms[lk63][:y_type] == :(Cont) + @test alpine.linear_terms[lk63][:y_idx] == 6987 + @test alpine.linear_terms[lk63][:id] == 49 + @test alpine.linear_terms[lk63][:y_type] == :(Cont) lk64 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(0.002765, 6903), (1.0, 6976), (1.0, 4082)]))) - @test m.internalModel.linear_terms[lk64][:y_idx] == 6977 - @test m.internalModel.linear_terms[lk64][:id] == 43 - @test m.internalModel.linear_terms[lk64][:y_type] == :(Cont) + @test alpine.linear_terms[lk64][:y_idx] == 6977 + @test alpine.linear_terms[lk64][:id] == 43 + @test alpine.linear_terms[lk64][:y_type] == :(Cont) lk65 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 6956), (0.003269, 6903), (1.0, 3782)]))) - @test m.internalModel.linear_terms[lk65][:y_idx] == 6957 - @test m.internalModel.linear_terms[lk65][:id] == 31 - @test m.internalModel.linear_terms[lk65][:y_type] == :(Cont) + @test alpine.linear_terms[lk65][:y_idx] == 6957 + @test alpine.linear_terms[lk65][:id] == 31 + @test alpine.linear_terms[lk65][:y_type] == :(Cont) lk66 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 3587), (1.0, 136)]))) - @test m.internalModel.linear_terms[lk66][:y_idx] == 6929 - @test m.internalModel.linear_terms[lk66][:id] == 14 - @test m.internalModel.linear_terms[lk66][:y_type] == :(Cont) + @test alpine.linear_terms[lk66][:y_idx] == 6929 + @test alpine.linear_terms[lk66][:id] == 14 + @test alpine.linear_terms[lk66][:y_type] == :(Cont) lk67 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 166), (1.0, 3617)]))) - @test m.internalModel.linear_terms[lk67][:y_idx] == 6934 - @test m.internalModel.linear_terms[lk67][:id] == 17 - @test m.internalModel.linear_terms[lk67][:y_type] == :(Cont) + @test alpine.linear_terms[lk67][:y_idx] == 6934 + @test alpine.linear_terms[lk67][:id] == 17 + @test alpine.linear_terms[lk67][:y_type] == :(Cont) lk68 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(-1.0, 7010), (1.0, 1951)]))) - @test m.internalModel.linear_terms[lk68][:y_idx] == 7011 - @test m.internalModel.linear_terms[lk68][:id] == 63 - @test m.internalModel.linear_terms[lk68][:y_type] == :(Cont) + @test alpine.linear_terms[lk68][:y_idx] == 7011 + @test alpine.linear_terms[lk68][:id] == 63 + @test alpine.linear_terms[lk68][:y_type] == :(Cont) lk69 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 7036), (0.001098, 6903), (1.0, 6902)]))) - @test m.internalModel.linear_terms[lk69][:y_idx] == 7037 - @test m.internalModel.linear_terms[lk69][:id] == 79 - @test m.internalModel.linear_terms[lk69][:y_type] == :(Cont) + @test alpine.linear_terms[lk69][:y_idx] == 7037 + @test alpine.linear_terms[lk69][:id] == 79 + @test alpine.linear_terms[lk69][:y_type] == :(Cont) lk70 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 3527), (1.0, 76)]))) - @test m.internalModel.linear_terms[lk70][:y_idx] == 6919 - @test m.internalModel.linear_terms[lk70][:id] == 8 - @test m.internalModel.linear_terms[lk70][:y_type] == :(Cont) + @test alpine.linear_terms[lk70][:y_idx] == 6919 + @test alpine.linear_terms[lk70][:id] == 8 + @test alpine.linear_terms[lk70][:y_type] == :(Cont) lk71 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 6961), (1.0, 3842), (0.00317, 6903)]))) - @test m.internalModel.linear_terms[lk71][:y_idx] == 6962 - @test m.internalModel.linear_terms[lk71][:id] == 34 - @test m.internalModel.linear_terms[lk71][:y_type] == :(Cont) + @test alpine.linear_terms[lk71][:y_idx] == 6962 + @test alpine.linear_terms[lk71][:id] == 34 + @test alpine.linear_terms[lk71][:y_type] == :(Cont) lk72 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(-1.0, 6990), (1.0, 1171)]))) - @test m.internalModel.linear_terms[lk72][:y_idx] == 6991 - @test m.internalModel.linear_terms[lk72][:id] == 51 - @test m.internalModel.linear_terms[lk72][:y_type] == :(Cont) + @test alpine.linear_terms[lk72][:y_idx] == 6991 + @test alpine.linear_terms[lk72][:id] == 51 + @test alpine.linear_terms[lk72][:y_type] == :(Cont) lk73 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 3451), (1.0, 6902)]))) - @test m.internalModel.linear_terms[lk73][:y_idx] == 7034 - @test m.internalModel.linear_terms[lk73][:id] == 77 - @test m.internalModel.linear_terms[lk73][:y_type] == :(Cont) + @test alpine.linear_terms[lk73][:y_idx] == 7034 + @test alpine.linear_terms[lk73][:id] == 77 + @test alpine.linear_terms[lk73][:y_type] == :(Cont) lk74 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 6302), (1.0, 2851)]))) - @test m.internalModel.linear_terms[lk74][:y_idx] == 7024 - @test m.internalModel.linear_terms[lk74][:id] == 71 - @test m.internalModel.linear_terms[lk74][:y_type] == :(Cont) + @test alpine.linear_terms[lk74][:y_idx] == 7024 + @test alpine.linear_terms[lk74][:id] == 71 + @test alpine.linear_terms[lk74][:y_type] == :(Cont) lk75 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 1531), (-1.0, 7000)]))) - @test m.internalModel.linear_terms[lk75][:y_idx] == 7001 - @test m.internalModel.linear_terms[lk75][:id] == 57 - @test m.internalModel.linear_terms[lk75][:y_type] == :(Cont) + @test alpine.linear_terms[lk75][:y_idx] == 7001 + @test alpine.linear_terms[lk75][:id] == 57 + @test alpine.linear_terms[lk75][:y_type] == :(Cont) lk76 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 3151), (1.0, 6602)]))) - @test m.internalModel.linear_terms[lk76][:y_idx] == 7029 - @test m.internalModel.linear_terms[lk76][:id] == 74 - @test m.internalModel.linear_terms[lk76][:y_type] == :(Cont) + @test alpine.linear_terms[lk76][:y_idx] == 7029 + @test alpine.linear_terms[lk76][:id] == 74 + @test alpine.linear_terms[lk76][:y_type] == :(Cont) lk77 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 3782), (1.0, 331)]))) - @test m.internalModel.linear_terms[lk77][:y_idx] == 6954 - @test m.internalModel.linear_terms[lk77][:id] == 29 - @test m.internalModel.linear_terms[lk77][:y_type] == :(Cont) + @test alpine.linear_terms[lk77][:y_idx] == 6954 + @test alpine.linear_terms[lk77][:id] == 29 + @test alpine.linear_terms[lk77][:y_type] == :(Cont) lk78 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(-1.0, 6955), (1.0, 331)]))) - @test m.internalModel.linear_terms[lk78][:y_idx] == 6956 - @test m.internalModel.linear_terms[lk78][:id] == 30 - @test m.internalModel.linear_terms[lk78][:y_type] == :(Cont) + @test alpine.linear_terms[lk78][:y_idx] == 6956 + @test alpine.linear_terms[lk78][:id] == 30 + @test alpine.linear_terms[lk78][:y_type] == :(Cont) lk79 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 226), (1.0, 3677)]))) - @test m.internalModel.linear_terms[lk79][:y_idx] == 6944 - @test m.internalModel.linear_terms[lk79][:id] == 23 - @test m.internalModel.linear_terms[lk79][:y_type] == :(Cont) + @test alpine.linear_terms[lk79][:y_idx] == 6944 + @test alpine.linear_terms[lk79][:id] == 23 + @test alpine.linear_terms[lk79][:y_type] == :(Cont) end end + @testset "Expression Parsing || Basic Multiplication Operators (Machine Generated for diffs)" begin - test_solver=AlpineSolver(nlp_solver=IpoptSolver(print_level=0, sb="yes"), - mip_solver=CbcSolver(logLevel=0), - loglevel=100) + test_solver=optimizer_with_attributes(Alpine.Optimizer,"minlp_solver" => JUNIPER, + "mip_solver" => CBC, + "loglevel" => 100) m = operator_basic(solver=test_solver) - JuMP.build(m) - - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[4])]][:y_idx] == 31 - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[4])]][:id] == 27 - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[4])]][:lifted_constr_ref] == :(x[31] == x[3] * x[4]) - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[4])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[5]), :(x[76])]][:y_idx] == 83 - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[5]), :(x[76])]][:id] == 79 - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[5]), :(x[76])]][:lifted_constr_ref] == :(x[83] == x[4] * x[5] * x[76]) - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[5]), :(x[76])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[2])]][:y_idx] == 9 - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[2])]][:id] == 5 - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[2])]][:lifted_constr_ref] == :(x[9] == (*)(x[2])) - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[2])]][:nonlinear_type] == :MONOMIAL - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[7])]][:y_idx] == 19 - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[7])]][:id] == 15 - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[7])]][:lifted_constr_ref] == :(x[19] == x[5] * x[7]) - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[7])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[31])]][:y_idx] == 32 - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[31])]][:id] == 28 - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[31])]][:lifted_constr_ref] == :(x[32] == x[2] * x[31]) - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[31])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[10])]][:y_idx] == 49 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[10])]][:id] == 45 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[10])]][:lifted_constr_ref] == :(x[49] == x[1] * x[2] * x[10]) - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[10])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[5]), :(x[9])]][:y_idx] == 50 - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[5]), :(x[9])]][:id] == 46 - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[5]), :(x[9])]][:lifted_constr_ref] == :(x[50] == x[3] * x[5] * x[9]) - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[5]), :(x[9])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[47])]][:y_idx] == 69 - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[47])]][:id] == 65 - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[47])]][:lifted_constr_ref] == :(x[69] == x[4] * x[47]) - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[47])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[4])]][:y_idx] == 28 - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[4])]][:id] == 24 - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[4])]][:lifted_constr_ref] == :(x[28] == (*)(x[4])) - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[4])]][:nonlinear_type] == :MONOMIAL - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[10])]][:y_idx] == 37 - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[10])]][:id] == 33 - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[10])]][:lifted_constr_ref] == :(x[37] == x[4] * x[10]) - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[10])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[1])]][:y_idx] == 5 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[1])]][:id] == 1 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[1])]][:lifted_constr_ref] == :(x[5] == (*)(x[1])) - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[1])]][:nonlinear_type] == :MONOMIAL - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[95])]][:y_idx] == 96 - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[95])]][:id] == 92 - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[95])]][:lifted_constr_ref] == :(x[96] == x[5] * x[95]) - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[95])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[40])]][:y_idx] == 41 - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[40])]][:id] == 37 - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[40])]][:lifted_constr_ref] == :(x[41] == x[2] * x[40]) - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[40])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[10])]][:y_idx] == 26 - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[10])]][:id] == 22 - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[10])]][:lifted_constr_ref] == :(x[26] == x[6] * x[10]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[10])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[78]), :(x[28])]][:y_idx] == 84 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[78]), :(x[28])]][:id] == 80 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[78]), :(x[28])]][:lifted_constr_ref] == :(x[84] == x[1] * x[78] * x[28]) - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[78]), :(x[28])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[43])]][:y_idx] == 58 - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[43])]][:id] == 54 - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[43])]][:lifted_constr_ref] == :(x[58] == x[6] * x[43]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[43])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[6]), :(x[10])]][:y_idx] == 106 - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[6]), :(x[10])]][:id] == 102 - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[6]), :(x[10])]][:lifted_constr_ref] == :(x[106] == x[4] * x[6] * x[10]) - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[6]), :(x[10])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[4]), :(x[10])]][:y_idx] == 90 - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[4]), :(x[10])]][:id] == 86 - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[4]), :(x[10])]][:lifted_constr_ref] == :(x[90] == x[2] * x[4] * x[10]) - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[4]), :(x[10])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[41])]][:y_idx] == 42 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[41])]][:id] == 38 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[41])]][:lifted_constr_ref] == :(x[42] == x[1] * x[41]) - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[41])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[37])]][:y_idx] == 38 - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[37])]][:id] == 34 - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[37])]][:lifted_constr_ref] == :(x[38] == x[2] * x[37]) - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[37])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[85])]][:y_idx] == 87 - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[85])]][:id] == 83 - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[85])]][:lifted_constr_ref] == :(x[87] == x[5] * x[85]) - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[85])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[5]), :(x[28])]][:y_idx] == 66 - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[5]), :(x[28])]][:id] == 62 - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[5]), :(x[28])]][:lifted_constr_ref] == :(x[66] == x[2] * x[3] * x[5] * x[28]) - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[5]), :(x[28])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[9]), :(x[10])]][:y_idx] == 53 - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[9]), :(x[10])]][:id] == 49 - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[9]), :(x[10])]][:lifted_constr_ref] == :(x[53] == x[5] * x[9] * x[10]) - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[9]), :(x[10])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[6]), :(x[28])]][:y_idx] == 107 - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[6]), :(x[28])]][:id] == 103 - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[6]), :(x[28])]][:lifted_constr_ref] == :(x[107] == x[3] * x[6] * x[28]) - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[6]), :(x[28])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[5])]][:y_idx] == 17 - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[5])]][:id] == 13 - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[5])]][:lifted_constr_ref] == :(x[17] == x[2] * x[5]) - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[5])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[37])]][:y_idx] == 57 - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[37])]][:id] == 53 - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[37])]][:lifted_constr_ref] == :(x[57] == x[6] * x[37]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[37])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[7]), :(x[28])]][:y_idx] == 81 - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[7]), :(x[28])]][:id] == 77 - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[7]), :(x[28])]][:lifted_constr_ref] == :(x[81] == x[5] * x[7] * x[28]) - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[7]), :(x[28])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[38])]][:y_idx] == 39 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[38])]][:id] == 35 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[38])]][:lifted_constr_ref] == :(x[39] == x[1] * x[38]) - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[38])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[3]), :(x[9])]][:y_idx] == 48 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[3]), :(x[9])]][:id] == 44 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[3]), :(x[9])]][:lifted_constr_ref] == :(x[48] == x[1] * x[3] * x[9]) - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[3]), :(x[9])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[23])]][:y_idx] == 24 - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[23])]][:id] == 20 - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[23])]][:lifted_constr_ref] == :(x[24] == x[4] * x[23]) - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[23])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[17])]][:y_idx] == 23 - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[17])]][:id] == 19 - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[17])]][:lifted_constr_ref] == :(x[23] == x[3] * x[17]) - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[17])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[9]), :(x[10])]][:y_idx] == 51 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[9]), :(x[10])]][:id] == 47 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[9]), :(x[10])]][:lifted_constr_ref] == :(x[51] == x[1] * x[9] * x[10]) - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[9]), :(x[10])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[5]), :(x[7])]][:y_idx] == 75 - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[5]), :(x[7])]][:id] == 71 - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[5]), :(x[7])]][:lifted_constr_ref] == :(x[75] == x[4] * x[5] * x[7]) - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[5]), :(x[7])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[9]), :(x[10]), :(x[28])]][:y_idx] == 95 - @test m.internalModel.nonconvex_terms[Expr[:(x[9]), :(x[10]), :(x[28])]][:id] == 91 - @test m.internalModel.nonconvex_terms[Expr[:(x[9]), :(x[10]), :(x[28])]][:lifted_constr_ref] == :(x[95] == x[9] * x[10] * x[28]) - @test m.internalModel.nonconvex_terms[Expr[:(x[9]), :(x[10]), :(x[28])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[9]), :(x[10])]][:y_idx] == 11 - @test m.internalModel.nonconvex_terms[Expr[:(x[9]), :(x[10])]][:id] == 7 - @test m.internalModel.nonconvex_terms[Expr[:(x[9]), :(x[10])]][:lifted_constr_ref] == :(x[11] == x[9] * x[10]) - @test m.internalModel.nonconvex_terms[Expr[:(x[9]), :(x[10])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[37])]][:y_idx] == 100 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[37])]][:id] == 96 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[37])]][:lifted_constr_ref] == :(x[100] == x[1] * x[2] * x[37]) - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[37])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[4]), :(x[5])]][:y_idx] == 62 - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[4]), :(x[5])]][:id] == 58 - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[4]), :(x[5])]][:lifted_constr_ref] == :(x[62] == x[2] * x[3] * x[4] * x[5]) - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[4]), :(x[5])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[9]), :(x[10])]][:y_idx] == 65 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[9]), :(x[10])]][:id] == 61 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[9]), :(x[10])]][:lifted_constr_ref] == :(x[65] == x[1] * x[4] * x[9] * x[10]) - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[9]), :(x[10])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[7]), :(x[28])]][:y_idx] == 80 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[7]), :(x[28])]][:id] == 76 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[7]), :(x[28])]][:lifted_constr_ref] == :(x[80] == x[1] * x[7] * x[28]) - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[7]), :(x[28])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[3])]][:y_idx] == 46 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[3])]][:id] == 42 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[3])]][:lifted_constr_ref] == :(x[46] == x[1] * x[2] * x[3]) - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[3])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[17]), :(x[40])]][:y_idx] == 59 - @test m.internalModel.nonconvex_terms[Expr[:(x[17]), :(x[40])]][:id] == 55 - @test m.internalModel.nonconvex_terms[Expr[:(x[17]), :(x[40])]][:lifted_constr_ref] == :(x[59] == x[17] * x[40]) - @test m.internalModel.nonconvex_terms[Expr[:(x[17]), :(x[40])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[85])]][:y_idx] == 86 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[85])]][:id] == 82 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[85])]][:lifted_constr_ref] == :(x[86] == x[1] * x[85]) - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[85])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[31])]][:y_idx] == 97 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[31])]][:id] == 93 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[31])]][:lifted_constr_ref] == :(x[97] == x[1] * x[2] * x[31]) - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[31])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[13]), :(x[28])]][:y_idx] == 29 - @test m.internalModel.nonconvex_terms[Expr[:(x[13]), :(x[28])]][:id] == 25 - @test m.internalModel.nonconvex_terms[Expr[:(x[13]), :(x[28])]][:lifted_constr_ref] == :(x[29] == x[13] * x[28]) - @test m.internalModel.nonconvex_terms[Expr[:(x[13]), :(x[28])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[28])]][:y_idx] == 92 - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[28])]][:id] == 88 - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[28])]][:lifted_constr_ref] == :(x[92] == x[2] * x[3] * x[28]) - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[28])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[9])]][:y_idx] == 20 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[9])]][:id] == 16 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[9])]][:lifted_constr_ref] == :(x[20] == x[1] * x[9]) - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[9])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[14]), :(x[10]), :(x[28])]][:y_idx] == 109 - @test m.internalModel.nonconvex_terms[Expr[:(x[14]), :(x[10]), :(x[28])]][:id] == 105 - @test m.internalModel.nonconvex_terms[Expr[:(x[14]), :(x[10]), :(x[28])]][:lifted_constr_ref] == :(x[109] == x[14] * x[10] * x[28]) - @test m.internalModel.nonconvex_terms[Expr[:(x[14]), :(x[10]), :(x[28])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[92])]][:y_idx] == 93 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[92])]][:id] == 89 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[92])]][:lifted_constr_ref] == :(x[93] == x[1] * x[92]) - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[92])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[4])]][:y_idx] == 85 - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[4])]][:id] == 81 - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[4])]][:lifted_constr_ref] == :(x[85] == x[2] * x[3] * x[4]) - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[4])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[11])]][:y_idx] == 16 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[11])]][:id] == 12 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[11])]][:lifted_constr_ref] == :(x[16] == x[1] * x[11]) - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[11])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[21])]][:y_idx] == 25 - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[21])]][:id] == 21 - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[21])]][:lifted_constr_ref] == :(x[25] == x[4] * x[21]) - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[21])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[53]), :(x[28])]][:y_idx] == 73 - @test m.internalModel.nonconvex_terms[Expr[:(x[53]), :(x[28])]][:id] == 69 - @test m.internalModel.nonconvex_terms[Expr[:(x[53]), :(x[28])]][:lifted_constr_ref] == :(x[73] == x[53] * x[28]) - @test m.internalModel.nonconvex_terms[Expr[:(x[53]), :(x[28])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[32])]][:y_idx] == 34 - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[32])]][:id] == 30 - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[32])]][:lifted_constr_ref] == :(x[34] == x[5] * x[32]) - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[32])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[28])]][:y_idx] == 40 - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[28])]][:id] == 36 - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[28])]][:lifted_constr_ref] == :(x[40] == x[3] * x[28]) - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[28])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[9]), :(x[10]), :(x[28])]][:y_idx] == 67 - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[9]), :(x[10]), :(x[28])]][:id] == 63 - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[9]), :(x[10]), :(x[28])]][:lifted_constr_ref] == :(x[67] == x[5] * x[9] * x[10] * x[28]) - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[9]), :(x[10]), :(x[28])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[9]), :(x[43])]][:y_idx] == 102 - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[9]), :(x[43])]][:id] == 98 - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[9]), :(x[43])]][:lifted_constr_ref] == :(x[102] == x[5] * x[9] * x[43]) - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[9]), :(x[43])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[26])]][:y_idx] == 27 - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[26])]][:id] == 23 - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[26])]][:lifted_constr_ref] == :(x[27] == x[4] * x[26]) - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[26])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[20]), :(x[31])]][:y_idx] == 56 - @test m.internalModel.nonconvex_terms[Expr[:(x[20]), :(x[31])]][:id] == 52 - @test m.internalModel.nonconvex_terms[Expr[:(x[20]), :(x[31])]][:lifted_constr_ref] == :(x[56] == x[20] * x[31]) - @test m.internalModel.nonconvex_terms[Expr[:(x[20]), :(x[31])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[3]), :(x[4]), :(x[9])]][:y_idx] == 63 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[3]), :(x[4]), :(x[9])]][:id] == 59 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[3]), :(x[4]), :(x[9])]][:lifted_constr_ref] == :(x[63] == x[1] * x[3] * x[4] * x[9]) - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[3]), :(x[4]), :(x[9])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[14]), :(x[10])]][:y_idx] == 15 - @test m.internalModel.nonconvex_terms[Expr[:(x[14]), :(x[10])]][:id] == 11 - @test m.internalModel.nonconvex_terms[Expr[:(x[14]), :(x[10])]][:lifted_constr_ref] == :(x[15] == x[14] * x[10]) - @test m.internalModel.nonconvex_terms[Expr[:(x[14]), :(x[10])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[76])]][:y_idx] == 77 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[76])]][:id] == 73 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[76])]][:lifted_constr_ref] == :(x[77] == x[1] * x[4] * x[76]) - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[76])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[88])]][:y_idx] == 89 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[88])]][:id] == 85 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[88])]][:lifted_constr_ref] == :(x[89] == x[1] * x[88]) - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[88])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[90])]][:y_idx] == 94 - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[90])]][:id] == 90 - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[90])]][:lifted_constr_ref] == :(x[94] == x[5] * x[90]) - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[90])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[10]), :(x[28])]][:y_idx] == 108 - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[10]), :(x[28])]][:id] == 104 - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[10]), :(x[28])]][:lifted_constr_ref] == :(x[108] == x[6] * x[10] * x[28]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[10]), :(x[28])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[48])]][:y_idx] == 70 - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[48])]][:id] == 66 - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[48])]][:lifted_constr_ref] == :(x[70] == x[4] * x[48]) - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[48])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[31])]][:y_idx] == 54 - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[31])]][:id] == 50 - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[31])]][:lifted_constr_ref] == :(x[54] == x[6] * x[31]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[31])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[9]), :(x[31])]][:y_idx] == 99 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[9]), :(x[31])]][:id] == 95 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[9]), :(x[31])]][:lifted_constr_ref] == :(x[99] == x[1] * x[9] * x[31]) - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[9]), :(x[31])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[35])]][:y_idx] == 36 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[35])]][:id] == 32 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[35])]][:lifted_constr_ref] == :(x[36] == x[1] * x[35]) - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[35])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[9])]][:y_idx] == 14 - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[9])]][:id] == 10 - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[9])]][:lifted_constr_ref] == :(x[14] == x[5] * x[9]) - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[9])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[13])]][:y_idx] == 22 - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[13])]][:id] == 18 - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[13])]][:lifted_constr_ref] == :(x[22] == x[4] * x[13]) - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[13])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[10]), :(x[28])]][:y_idx] == 64 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[10]), :(x[28])]][:id] == 60 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[10]), :(x[28])]][:lifted_constr_ref] == :(x[64] == x[1] * x[2] * x[10] * x[28]) - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[10]), :(x[28])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[46]), :(x[28])]][:y_idx] == 72 - @test m.internalModel.nonconvex_terms[Expr[:(x[46]), :(x[28])]][:id] == 68 - @test m.internalModel.nonconvex_terms[Expr[:(x[46]), :(x[28])]][:lifted_constr_ref] == :(x[72] == x[46] * x[28]) - @test m.internalModel.nonconvex_terms[Expr[:(x[46]), :(x[28])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[17]), :(x[31])]][:y_idx] == 55 - @test m.internalModel.nonconvex_terms[Expr[:(x[17]), :(x[31])]][:id] == 51 - @test m.internalModel.nonconvex_terms[Expr[:(x[17]), :(x[31])]][:lifted_constr_ref] == :(x[55] == x[17] * x[31]) - @test m.internalModel.nonconvex_terms[Expr[:(x[17]), :(x[31])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[5]), :(x[31])]][:y_idx] == 98 - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[5]), :(x[31])]][:id] == 94 - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[5]), :(x[31])]][:lifted_constr_ref] == :(x[98] == x[2] * x[5] * x[31]) - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[5]), :(x[31])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[10]), :(x[28])]][:y_idx] == 43 - @test m.internalModel.nonconvex_terms[Expr[:(x[10]), :(x[28])]][:id] == 39 - @test m.internalModel.nonconvex_terms[Expr[:(x[10]), :(x[28])]][:lifted_constr_ref] == :(x[43] == x[10] * x[28]) - @test m.internalModel.nonconvex_terms[Expr[:(x[10]), :(x[28])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[10])]][:y_idx] == 78 - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[10])]][:id] == 74 - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[10])]][:lifted_constr_ref] == :(x[78] == x[2] * x[10]) - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[10])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[5]), :(x[10])]][:y_idx] == 52 - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[5]), :(x[10])]][:id] == 48 - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[5]), :(x[10])]][:lifted_constr_ref] == :(x[52] == x[2] * x[5] * x[10]) - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[5]), :(x[10])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[90])]][:y_idx] == 91 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[90])]][:id] == 87 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[90])]][:lifted_constr_ref] == :(x[91] == x[1] * x[90]) - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[90])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[4]), :(x[17])]][:y_idx] == 104 - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[4]), :(x[17])]][:id] == 100 - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[4]), :(x[17])]][:lifted_constr_ref] == :(x[104] == x[3] * x[4] * x[17]) - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[4]), :(x[17])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[9])]][:y_idx] == 76 - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[9])]][:id] == 72 - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[9])]][:lifted_constr_ref] == :(x[76] == x[3] * x[9]) - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[9])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[78])]][:y_idx] == 79 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[78])]][:id] == 75 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[78])]][:lifted_constr_ref] == :(x[79] == x[1] * x[4] * x[78]) - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[78])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[3])]][:y_idx] == 10 - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[3])]][:id] == 6 - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[3])]][:lifted_constr_ref] == :(x[10] == (*)(x[3])) - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[3])]][:nonlinear_type] == :MONOMIAL - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[49])]][:y_idx] == 71 - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[49])]][:id] == 67 - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[49])]][:lifted_constr_ref] == :(x[71] == x[4] * x[49]) - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[49])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[4]), :(x[9])]][:y_idx] == 88 - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[4]), :(x[9])]][:id] == 84 - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[4]), :(x[9])]][:lifted_constr_ref] == :(x[88] == x[3] * x[4] * x[9]) - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[4]), :(x[9])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[15]), :(x[28])]][:y_idx] == 30 - @test m.internalModel.nonconvex_terms[Expr[:(x[15]), :(x[28])]][:id] == 26 - @test m.internalModel.nonconvex_terms[Expr[:(x[15]), :(x[28])]][:lifted_constr_ref] == :(x[30] == x[15] * x[28]) - @test m.internalModel.nonconvex_terms[Expr[:(x[15]), :(x[28])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[46])]][:y_idx] == 68 - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[46])]][:id] == 64 - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[46])]][:lifted_constr_ref] == :(x[68] == x[4] * x[46]) - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[46])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[11])]][:y_idx] == 12 - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[11])]][:id] == 8 - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[11])]][:lifted_constr_ref] == :(x[12] == x[5] * x[11]) - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[11])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[7])]][:y_idx] == 74 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[7])]][:id] == 70 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[7])]][:lifted_constr_ref] == :(x[74] == x[1] * x[4] * x[7]) - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[7])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[4]), :(x[20])]][:y_idx] == 105 - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[4]), :(x[20])]][:id] == 101 - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[4]), :(x[20])]][:lifted_constr_ref] == :(x[105] == x[3] * x[4] * x[20]) - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[4]), :(x[20])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[11])]][:y_idx] == 82 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[11])]][:id] == 78 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[11])]][:lifted_constr_ref] == :(x[82] == x[1] * x[4] * x[11]) - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[11])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[9]), :(x[43])]][:y_idx] == 44 - @test m.internalModel.nonconvex_terms[Expr[:(x[9]), :(x[43])]][:id] == 40 - @test m.internalModel.nonconvex_terms[Expr[:(x[9]), :(x[43])]][:lifted_constr_ref] == :(x[44] == x[9] * x[43]) - @test m.internalModel.nonconvex_terms[Expr[:(x[9]), :(x[43])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[3]), :(x[4])]][:y_idx] == 61 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[3]), :(x[4])]][:id] == 57 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[3]), :(x[4])]][:lifted_constr_ref] == :(x[61] == x[1] * x[2] * x[3] * x[4]) - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[3]), :(x[4])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[17]), :(x[10])]][:y_idx] == 18 - @test m.internalModel.nonconvex_terms[Expr[:(x[17]), :(x[10])]][:id] == 14 - @test m.internalModel.nonconvex_terms[Expr[:(x[17]), :(x[10])]][:lifted_constr_ref] == :(x[18] == x[17] * x[10]) - @test m.internalModel.nonconvex_terms[Expr[:(x[17]), :(x[10])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[7])]][:y_idx] == 8 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[7])]][:id] == 4 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[7])]][:lifted_constr_ref] == :(x[8] == x[1] * x[7]) - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[7])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[2])]][:y_idx] == 6 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[2])]][:id] == 2 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[2])]][:lifted_constr_ref] == :(x[6] == x[1] * x[2]) - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[2])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[40])]][:y_idx] == 101 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[40])]][:id] == 97 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[40])]][:lifted_constr_ref] == :(x[101] == x[1] * x[2] * x[40]) - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[40])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[17]), :(x[37])]][:y_idx] == 60 - @test m.internalModel.nonconvex_terms[Expr[:(x[17]), :(x[37])]][:id] == 56 - @test m.internalModel.nonconvex_terms[Expr[:(x[17]), :(x[37])]][:lifted_constr_ref] == :(x[60] == x[17] * x[37]) - @test m.internalModel.nonconvex_terms[Expr[:(x[17]), :(x[37])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[4]), :(x[6])]][:y_idx] == 103 - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[4]), :(x[6])]][:id] == 99 - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[4]), :(x[6])]][:lifted_constr_ref] == :(x[103] == x[3] * x[4] * x[6]) - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[4]), :(x[6])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[3])]][:y_idx] == 7 - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[3])]][:id] == 3 - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[3])]][:lifted_constr_ref] == :(x[7] == x[2] * x[3]) - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[3])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[5])]][:y_idx] == 47 - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[5])]][:id] == 43 - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[5])]][:lifted_constr_ref] == :(x[47] == x[2] * x[3] * x[5]) - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[5])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[6])]][:y_idx] == 13 - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[6])]][:id] == 9 - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[6])]][:lifted_constr_ref] == :(x[13] == x[3] * x[6]) - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[6])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[9]), :(x[31])]][:y_idx] == 35 - @test m.internalModel.nonconvex_terms[Expr[:(x[9]), :(x[31])]][:id] == 31 - @test m.internalModel.nonconvex_terms[Expr[:(x[9]), :(x[31])]][:lifted_constr_ref] == :(x[35] == x[9] * x[31]) - @test m.internalModel.nonconvex_terms[Expr[:(x[9]), :(x[31])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[32])]][:y_idx] == 33 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[32])]][:id] == 29 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[32])]][:lifted_constr_ref] == :(x[33] == x[1] * x[32]) - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[32])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[20])]][:y_idx] == 21 - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[20])]][:id] == 17 - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[20])]][:lifted_constr_ref] == :(x[21] == x[3] * x[20]) - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[20])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[44])]][:y_idx] == 45 - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[44])]][:id] == 41 - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[44])]][:lifted_constr_ref] == :(x[45] == x[5] * x[44]) - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[44])]][:nonlinear_type] == :BILINEAR - - @test m.internalModel.bounding_constr_mip[1][:rhs] == 1.0 - @test m.internalModel.bounding_constr_mip[1][:vars] == Any[:(x[5])] - @test m.internalModel.bounding_constr_mip[1][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[1][:sense] == :(>=) - @test m.internalModel.bounding_constr_mip[1][:cnt] == 1 - @test m.internalModel.bounding_constr_mip[2][:rhs] == 1.0 - @test m.internalModel.bounding_constr_mip[2][:vars] == Any[:(x[6])] - @test m.internalModel.bounding_constr_mip[2][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[2][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[2][:cnt] == 1 - @test m.internalModel.bounding_constr_mip[3][:rhs] == 1.0 - @test m.internalModel.bounding_constr_mip[3][:vars] == Any[:(x[5]), :(x[7])] - @test m.internalModel.bounding_constr_mip[3][:coefs] == Any[1.0, 1.0] - @test m.internalModel.bounding_constr_mip[3][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[3][:cnt] == 2 - @test m.internalModel.bounding_constr_mip[4][:rhs] == 1.0 - @test m.internalModel.bounding_constr_mip[4][:vars] == Any[:(x[8])] - @test m.internalModel.bounding_constr_mip[4][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[4][:sense] == :(>=) - @test m.internalModel.bounding_constr_mip[4][:cnt] == 1 - @test m.internalModel.bounding_constr_mip[5][:rhs] == 1.0 - @test m.internalModel.bounding_constr_mip[5][:vars] == Any[:(x[12])] - @test m.internalModel.bounding_constr_mip[5][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[5][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[5][:cnt] == 1 - @test m.internalModel.bounding_constr_mip[6][:rhs] == 1.0 - @test m.internalModel.bounding_constr_mip[6][:vars] == Any[:(x[13])] - @test m.internalModel.bounding_constr_mip[6][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[6][:sense] == :(>=) - @test m.internalModel.bounding_constr_mip[6][:cnt] == 1 - @test m.internalModel.bounding_constr_mip[7][:rhs] == 1.0 - @test m.internalModel.bounding_constr_mip[7][:vars] == Any[:(x[15])] - @test m.internalModel.bounding_constr_mip[7][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[7][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[7][:cnt] == 1 - @test m.internalModel.bounding_constr_mip[8][:rhs] == 1.0 - @test m.internalModel.bounding_constr_mip[8][:vars] == Any[:(x[16])] - @test m.internalModel.bounding_constr_mip[8][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[8][:sense] == :(>=) - @test m.internalModel.bounding_constr_mip[8][:cnt] == 1 - @test m.internalModel.bounding_constr_mip[9][:rhs] == 1.0 - @test m.internalModel.bounding_constr_mip[9][:vars] == Any[:(x[18])] - @test m.internalModel.bounding_constr_mip[9][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[9][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[9][:cnt] == 1 - @test m.internalModel.bounding_constr_mip[10][:rhs] == 1.0 - @test m.internalModel.bounding_constr_mip[10][:vars] == Any[:(x[19])] - @test m.internalModel.bounding_constr_mip[10][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[10][:sense] == :(>=) - @test m.internalModel.bounding_constr_mip[10][:cnt] == 1 - @test m.internalModel.bounding_constr_mip[11][:rhs] == 1.0 - @test m.internalModel.bounding_constr_mip[11][:vars] == Any[:(x[21])] - @test m.internalModel.bounding_constr_mip[11][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[11][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[11][:cnt] == 1 - @test m.internalModel.bounding_constr_mip[12][:rhs] == 1.0 - @test m.internalModel.bounding_constr_mip[12][:vars] == Any[:(x[22])] - @test m.internalModel.bounding_constr_mip[12][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[12][:sense] == :(>=) - @test m.internalModel.bounding_constr_mip[12][:cnt] == 1 - @test m.internalModel.bounding_constr_mip[13][:rhs] == 1.0 - @test m.internalModel.bounding_constr_mip[13][:vars] == Any[:(x[24])] - @test m.internalModel.bounding_constr_mip[13][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[13][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[13][:cnt] == 1 - @test m.internalModel.bounding_constr_mip[14][:rhs] == 1.0 - @test m.internalModel.bounding_constr_mip[14][:vars] == Any[:(x[25])] - @test m.internalModel.bounding_constr_mip[14][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[14][:sense] == :(>=) - @test m.internalModel.bounding_constr_mip[14][:cnt] == 1 - @test m.internalModel.bounding_constr_mip[15][:rhs] == 1.0 - @test m.internalModel.bounding_constr_mip[15][:vars] == Any[:(x[27])] - @test m.internalModel.bounding_constr_mip[15][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[15][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[15][:cnt] == 1 + MOI.Utilities.attach_optimizer(m) + MOI.set(m, MOI.NLPBlock(), JuMP._create_nlp_block_data(m)) + + alpine = JuMP.backend(m).optimizer.model + Alpine.load!(alpine) + + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[4])]][:y_idx] == 31 + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[4])]][:id] == 27 + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[4])]][:lifted_constr_ref] == :(x[31] == x[3] * x[4]) + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[4])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[5]), :(x[76])]][:y_idx] == 83 + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[5]), :(x[76])]][:id] == 79 + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[5]), :(x[76])]][:lifted_constr_ref] == :(x[83] == x[4] * x[5] * x[76]) + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[5]), :(x[76])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[2])]][:y_idx] == 9 + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[2])]][:id] == 5 + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[2])]][:lifted_constr_ref] == :(x[9] == (*)(x[2])) + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[2])]][:nonlinear_type] == :MONOMIAL + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[7])]][:y_idx] == 19 + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[7])]][:id] == 15 + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[7])]][:lifted_constr_ref] == :(x[19] == x[5] * x[7]) + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[7])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[31])]][:y_idx] == 32 + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[31])]][:id] == 28 + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[31])]][:lifted_constr_ref] == :(x[32] == x[2] * x[31]) + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[31])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[10])]][:y_idx] == 49 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[10])]][:id] == 45 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[10])]][:lifted_constr_ref] == :(x[49] == x[1] * x[2] * x[10]) + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[10])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[5]), :(x[9])]][:y_idx] == 50 + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[5]), :(x[9])]][:id] == 46 + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[5]), :(x[9])]][:lifted_constr_ref] == :(x[50] == x[3] * x[5] * x[9]) + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[5]), :(x[9])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[47])]][:y_idx] == 69 + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[47])]][:id] == 65 + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[47])]][:lifted_constr_ref] == :(x[69] == x[4] * x[47]) + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[47])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[4])]][:y_idx] == 28 + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[4])]][:id] == 24 + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[4])]][:lifted_constr_ref] == :(x[28] == (*)(x[4])) + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[4])]][:nonlinear_type] == :MONOMIAL + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[10])]][:y_idx] == 37 + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[10])]][:id] == 33 + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[10])]][:lifted_constr_ref] == :(x[37] == x[4] * x[10]) + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[10])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[1])]][:y_idx] == 5 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[1])]][:id] == 1 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[1])]][:lifted_constr_ref] == :(x[5] == (*)(x[1])) + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[1])]][:nonlinear_type] == :MONOMIAL + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[95])]][:y_idx] == 96 + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[95])]][:id] == 92 + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[95])]][:lifted_constr_ref] == :(x[96] == x[5] * x[95]) + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[95])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[40])]][:y_idx] == 41 + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[40])]][:id] == 37 + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[40])]][:lifted_constr_ref] == :(x[41] == x[2] * x[40]) + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[40])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[10])]][:y_idx] == 26 + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[10])]][:id] == 22 + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[10])]][:lifted_constr_ref] == :(x[26] == x[6] * x[10]) + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[10])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[78]), :(x[28])]][:y_idx] == 84 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[78]), :(x[28])]][:id] == 80 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[78]), :(x[28])]][:lifted_constr_ref] == :(x[84] == x[1] * x[78] * x[28]) + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[78]), :(x[28])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[43])]][:y_idx] == 58 + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[43])]][:id] == 54 + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[43])]][:lifted_constr_ref] == :(x[58] == x[6] * x[43]) + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[43])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[6]), :(x[10])]][:y_idx] == 106 + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[6]), :(x[10])]][:id] == 102 + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[6]), :(x[10])]][:lifted_constr_ref] == :(x[106] == x[4] * x[6] * x[10]) + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[6]), :(x[10])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[4]), :(x[10])]][:y_idx] == 90 + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[4]), :(x[10])]][:id] == 86 + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[4]), :(x[10])]][:lifted_constr_ref] == :(x[90] == x[2] * x[4] * x[10]) + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[4]), :(x[10])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[41])]][:y_idx] == 42 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[41])]][:id] == 38 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[41])]][:lifted_constr_ref] == :(x[42] == x[1] * x[41]) + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[41])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[37])]][:y_idx] == 38 + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[37])]][:id] == 34 + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[37])]][:lifted_constr_ref] == :(x[38] == x[2] * x[37]) + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[37])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[85])]][:y_idx] == 87 + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[85])]][:id] == 83 + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[85])]][:lifted_constr_ref] == :(x[87] == x[5] * x[85]) + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[85])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[5]), :(x[28])]][:y_idx] == 66 + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[5]), :(x[28])]][:id] == 62 + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[5]), :(x[28])]][:lifted_constr_ref] == :(x[66] == x[2] * x[3] * x[5] * x[28]) + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[5]), :(x[28])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[9]), :(x[10])]][:y_idx] == 53 + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[9]), :(x[10])]][:id] == 49 + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[9]), :(x[10])]][:lifted_constr_ref] == :(x[53] == x[5] * x[9] * x[10]) + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[9]), :(x[10])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[6]), :(x[28])]][:y_idx] == 107 + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[6]), :(x[28])]][:id] == 103 + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[6]), :(x[28])]][:lifted_constr_ref] == :(x[107] == x[3] * x[6] * x[28]) + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[6]), :(x[28])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[5])]][:y_idx] == 17 + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[5])]][:id] == 13 + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[5])]][:lifted_constr_ref] == :(x[17] == x[2] * x[5]) + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[5])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[37])]][:y_idx] == 57 + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[37])]][:id] == 53 + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[37])]][:lifted_constr_ref] == :(x[57] == x[6] * x[37]) + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[37])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[7]), :(x[28])]][:y_idx] == 81 + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[7]), :(x[28])]][:id] == 77 + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[7]), :(x[28])]][:lifted_constr_ref] == :(x[81] == x[5] * x[7] * x[28]) + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[7]), :(x[28])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[38])]][:y_idx] == 39 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[38])]][:id] == 35 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[38])]][:lifted_constr_ref] == :(x[39] == x[1] * x[38]) + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[38])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[3]), :(x[9])]][:y_idx] == 48 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[3]), :(x[9])]][:id] == 44 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[3]), :(x[9])]][:lifted_constr_ref] == :(x[48] == x[1] * x[3] * x[9]) + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[3]), :(x[9])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[23])]][:y_idx] == 24 + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[23])]][:id] == 20 + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[23])]][:lifted_constr_ref] == :(x[24] == x[4] * x[23]) + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[23])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[17])]][:y_idx] == 23 + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[17])]][:id] == 19 + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[17])]][:lifted_constr_ref] == :(x[23] == x[3] * x[17]) + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[17])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[9]), :(x[10])]][:y_idx] == 51 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[9]), :(x[10])]][:id] == 47 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[9]), :(x[10])]][:lifted_constr_ref] == :(x[51] == x[1] * x[9] * x[10]) + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[9]), :(x[10])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[5]), :(x[7])]][:y_idx] == 75 + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[5]), :(x[7])]][:id] == 71 + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[5]), :(x[7])]][:lifted_constr_ref] == :(x[75] == x[4] * x[5] * x[7]) + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[5]), :(x[7])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[9]), :(x[10]), :(x[28])]][:y_idx] == 95 + @test alpine.nonconvex_terms[Expr[:(x[9]), :(x[10]), :(x[28])]][:id] == 91 + @test alpine.nonconvex_terms[Expr[:(x[9]), :(x[10]), :(x[28])]][:lifted_constr_ref] == :(x[95] == x[9] * x[10] * x[28]) + @test alpine.nonconvex_terms[Expr[:(x[9]), :(x[10]), :(x[28])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[9]), :(x[10])]][:y_idx] == 11 + @test alpine.nonconvex_terms[Expr[:(x[9]), :(x[10])]][:id] == 7 + @test alpine.nonconvex_terms[Expr[:(x[9]), :(x[10])]][:lifted_constr_ref] == :(x[11] == x[9] * x[10]) + @test alpine.nonconvex_terms[Expr[:(x[9]), :(x[10])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[37])]][:y_idx] == 100 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[37])]][:id] == 96 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[37])]][:lifted_constr_ref] == :(x[100] == x[1] * x[2] * x[37]) + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[37])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[4]), :(x[5])]][:y_idx] == 62 + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[4]), :(x[5])]][:id] == 58 + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[4]), :(x[5])]][:lifted_constr_ref] == :(x[62] == x[2] * x[3] * x[4] * x[5]) + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[4]), :(x[5])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[9]), :(x[10])]][:y_idx] == 65 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[9]), :(x[10])]][:id] == 61 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[9]), :(x[10])]][:lifted_constr_ref] == :(x[65] == x[1] * x[4] * x[9] * x[10]) + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[9]), :(x[10])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[7]), :(x[28])]][:y_idx] == 80 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[7]), :(x[28])]][:id] == 76 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[7]), :(x[28])]][:lifted_constr_ref] == :(x[80] == x[1] * x[7] * x[28]) + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[7]), :(x[28])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[3])]][:y_idx] == 46 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[3])]][:id] == 42 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[3])]][:lifted_constr_ref] == :(x[46] == x[1] * x[2] * x[3]) + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[3])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[17]), :(x[40])]][:y_idx] == 59 + @test alpine.nonconvex_terms[Expr[:(x[17]), :(x[40])]][:id] == 55 + @test alpine.nonconvex_terms[Expr[:(x[17]), :(x[40])]][:lifted_constr_ref] == :(x[59] == x[17] * x[40]) + @test alpine.nonconvex_terms[Expr[:(x[17]), :(x[40])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[85])]][:y_idx] == 86 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[85])]][:id] == 82 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[85])]][:lifted_constr_ref] == :(x[86] == x[1] * x[85]) + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[85])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[31])]][:y_idx] == 97 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[31])]][:id] == 93 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[31])]][:lifted_constr_ref] == :(x[97] == x[1] * x[2] * x[31]) + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[31])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[13]), :(x[28])]][:y_idx] == 29 + @test alpine.nonconvex_terms[Expr[:(x[13]), :(x[28])]][:id] == 25 + @test alpine.nonconvex_terms[Expr[:(x[13]), :(x[28])]][:lifted_constr_ref] == :(x[29] == x[13] * x[28]) + @test alpine.nonconvex_terms[Expr[:(x[13]), :(x[28])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[28])]][:y_idx] == 92 + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[28])]][:id] == 88 + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[28])]][:lifted_constr_ref] == :(x[92] == x[2] * x[3] * x[28]) + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[28])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[9])]][:y_idx] == 20 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[9])]][:id] == 16 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[9])]][:lifted_constr_ref] == :(x[20] == x[1] * x[9]) + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[9])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[14]), :(x[10]), :(x[28])]][:y_idx] == 109 + @test alpine.nonconvex_terms[Expr[:(x[14]), :(x[10]), :(x[28])]][:id] == 105 + @test alpine.nonconvex_terms[Expr[:(x[14]), :(x[10]), :(x[28])]][:lifted_constr_ref] == :(x[109] == x[14] * x[10] * x[28]) + @test alpine.nonconvex_terms[Expr[:(x[14]), :(x[10]), :(x[28])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[92])]][:y_idx] == 93 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[92])]][:id] == 89 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[92])]][:lifted_constr_ref] == :(x[93] == x[1] * x[92]) + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[92])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[4])]][:y_idx] == 85 + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[4])]][:id] == 81 + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[4])]][:lifted_constr_ref] == :(x[85] == x[2] * x[3] * x[4]) + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[4])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[11])]][:y_idx] == 16 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[11])]][:id] == 12 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[11])]][:lifted_constr_ref] == :(x[16] == x[1] * x[11]) + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[11])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[21])]][:y_idx] == 25 + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[21])]][:id] == 21 + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[21])]][:lifted_constr_ref] == :(x[25] == x[4] * x[21]) + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[21])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[53]), :(x[28])]][:y_idx] == 73 + @test alpine.nonconvex_terms[Expr[:(x[53]), :(x[28])]][:id] == 69 + @test alpine.nonconvex_terms[Expr[:(x[53]), :(x[28])]][:lifted_constr_ref] == :(x[73] == x[53] * x[28]) + @test alpine.nonconvex_terms[Expr[:(x[53]), :(x[28])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[32])]][:y_idx] == 34 + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[32])]][:id] == 30 + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[32])]][:lifted_constr_ref] == :(x[34] == x[5] * x[32]) + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[32])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[28])]][:y_idx] == 40 + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[28])]][:id] == 36 + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[28])]][:lifted_constr_ref] == :(x[40] == x[3] * x[28]) + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[28])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[9]), :(x[10]), :(x[28])]][:y_idx] == 67 + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[9]), :(x[10]), :(x[28])]][:id] == 63 + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[9]), :(x[10]), :(x[28])]][:lifted_constr_ref] == :(x[67] == x[5] * x[9] * x[10] * x[28]) + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[9]), :(x[10]), :(x[28])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[9]), :(x[43])]][:y_idx] == 102 + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[9]), :(x[43])]][:id] == 98 + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[9]), :(x[43])]][:lifted_constr_ref] == :(x[102] == x[5] * x[9] * x[43]) + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[9]), :(x[43])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[26])]][:y_idx] == 27 + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[26])]][:id] == 23 + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[26])]][:lifted_constr_ref] == :(x[27] == x[4] * x[26]) + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[26])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[20]), :(x[31])]][:y_idx] == 56 + @test alpine.nonconvex_terms[Expr[:(x[20]), :(x[31])]][:id] == 52 + @test alpine.nonconvex_terms[Expr[:(x[20]), :(x[31])]][:lifted_constr_ref] == :(x[56] == x[20] * x[31]) + @test alpine.nonconvex_terms[Expr[:(x[20]), :(x[31])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[3]), :(x[4]), :(x[9])]][:y_idx] == 63 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[3]), :(x[4]), :(x[9])]][:id] == 59 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[3]), :(x[4]), :(x[9])]][:lifted_constr_ref] == :(x[63] == x[1] * x[3] * x[4] * x[9]) + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[3]), :(x[4]), :(x[9])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[14]), :(x[10])]][:y_idx] == 15 + @test alpine.nonconvex_terms[Expr[:(x[14]), :(x[10])]][:id] == 11 + @test alpine.nonconvex_terms[Expr[:(x[14]), :(x[10])]][:lifted_constr_ref] == :(x[15] == x[14] * x[10]) + @test alpine.nonconvex_terms[Expr[:(x[14]), :(x[10])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[76])]][:y_idx] == 77 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[76])]][:id] == 73 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[76])]][:lifted_constr_ref] == :(x[77] == x[1] * x[4] * x[76]) + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[76])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[88])]][:y_idx] == 89 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[88])]][:id] == 85 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[88])]][:lifted_constr_ref] == :(x[89] == x[1] * x[88]) + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[88])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[90])]][:y_idx] == 94 + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[90])]][:id] == 90 + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[90])]][:lifted_constr_ref] == :(x[94] == x[5] * x[90]) + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[90])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[10]), :(x[28])]][:y_idx] == 108 + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[10]), :(x[28])]][:id] == 104 + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[10]), :(x[28])]][:lifted_constr_ref] == :(x[108] == x[6] * x[10] * x[28]) + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[10]), :(x[28])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[48])]][:y_idx] == 70 + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[48])]][:id] == 66 + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[48])]][:lifted_constr_ref] == :(x[70] == x[4] * x[48]) + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[48])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[31])]][:y_idx] == 54 + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[31])]][:id] == 50 + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[31])]][:lifted_constr_ref] == :(x[54] == x[6] * x[31]) + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[31])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[9]), :(x[31])]][:y_idx] == 99 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[9]), :(x[31])]][:id] == 95 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[9]), :(x[31])]][:lifted_constr_ref] == :(x[99] == x[1] * x[9] * x[31]) + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[9]), :(x[31])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[35])]][:y_idx] == 36 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[35])]][:id] == 32 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[35])]][:lifted_constr_ref] == :(x[36] == x[1] * x[35]) + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[35])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[9])]][:y_idx] == 14 + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[9])]][:id] == 10 + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[9])]][:lifted_constr_ref] == :(x[14] == x[5] * x[9]) + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[9])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[13])]][:y_idx] == 22 + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[13])]][:id] == 18 + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[13])]][:lifted_constr_ref] == :(x[22] == x[4] * x[13]) + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[13])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[10]), :(x[28])]][:y_idx] == 64 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[10]), :(x[28])]][:id] == 60 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[10]), :(x[28])]][:lifted_constr_ref] == :(x[64] == x[1] * x[2] * x[10] * x[28]) + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[10]), :(x[28])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[46]), :(x[28])]][:y_idx] == 72 + @test alpine.nonconvex_terms[Expr[:(x[46]), :(x[28])]][:id] == 68 + @test alpine.nonconvex_terms[Expr[:(x[46]), :(x[28])]][:lifted_constr_ref] == :(x[72] == x[46] * x[28]) + @test alpine.nonconvex_terms[Expr[:(x[46]), :(x[28])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[17]), :(x[31])]][:y_idx] == 55 + @test alpine.nonconvex_terms[Expr[:(x[17]), :(x[31])]][:id] == 51 + @test alpine.nonconvex_terms[Expr[:(x[17]), :(x[31])]][:lifted_constr_ref] == :(x[55] == x[17] * x[31]) + @test alpine.nonconvex_terms[Expr[:(x[17]), :(x[31])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[5]), :(x[31])]][:y_idx] == 98 + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[5]), :(x[31])]][:id] == 94 + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[5]), :(x[31])]][:lifted_constr_ref] == :(x[98] == x[2] * x[5] * x[31]) + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[5]), :(x[31])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[10]), :(x[28])]][:y_idx] == 43 + @test alpine.nonconvex_terms[Expr[:(x[10]), :(x[28])]][:id] == 39 + @test alpine.nonconvex_terms[Expr[:(x[10]), :(x[28])]][:lifted_constr_ref] == :(x[43] == x[10] * x[28]) + @test alpine.nonconvex_terms[Expr[:(x[10]), :(x[28])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[10])]][:y_idx] == 78 + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[10])]][:id] == 74 + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[10])]][:lifted_constr_ref] == :(x[78] == x[2] * x[10]) + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[10])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[5]), :(x[10])]][:y_idx] == 52 + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[5]), :(x[10])]][:id] == 48 + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[5]), :(x[10])]][:lifted_constr_ref] == :(x[52] == x[2] * x[5] * x[10]) + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[5]), :(x[10])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[90])]][:y_idx] == 91 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[90])]][:id] == 87 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[90])]][:lifted_constr_ref] == :(x[91] == x[1] * x[90]) + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[90])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[4]), :(x[17])]][:y_idx] == 104 + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[4]), :(x[17])]][:id] == 100 + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[4]), :(x[17])]][:lifted_constr_ref] == :(x[104] == x[3] * x[4] * x[17]) + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[4]), :(x[17])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[9])]][:y_idx] == 76 + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[9])]][:id] == 72 + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[9])]][:lifted_constr_ref] == :(x[76] == x[3] * x[9]) + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[9])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[78])]][:y_idx] == 79 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[78])]][:id] == 75 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[78])]][:lifted_constr_ref] == :(x[79] == x[1] * x[4] * x[78]) + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[78])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[3])]][:y_idx] == 10 + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[3])]][:id] == 6 + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[3])]][:lifted_constr_ref] == :(x[10] == (*)(x[3])) + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[3])]][:nonlinear_type] == :MONOMIAL + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[49])]][:y_idx] == 71 + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[49])]][:id] == 67 + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[49])]][:lifted_constr_ref] == :(x[71] == x[4] * x[49]) + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[49])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[4]), :(x[9])]][:y_idx] == 88 + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[4]), :(x[9])]][:id] == 84 + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[4]), :(x[9])]][:lifted_constr_ref] == :(x[88] == x[3] * x[4] * x[9]) + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[4]), :(x[9])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[15]), :(x[28])]][:y_idx] == 30 + @test alpine.nonconvex_terms[Expr[:(x[15]), :(x[28])]][:id] == 26 + @test alpine.nonconvex_terms[Expr[:(x[15]), :(x[28])]][:lifted_constr_ref] == :(x[30] == x[15] * x[28]) + @test alpine.nonconvex_terms[Expr[:(x[15]), :(x[28])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[46])]][:y_idx] == 68 + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[46])]][:id] == 64 + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[46])]][:lifted_constr_ref] == :(x[68] == x[4] * x[46]) + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[46])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[11])]][:y_idx] == 12 + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[11])]][:id] == 8 + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[11])]][:lifted_constr_ref] == :(x[12] == x[5] * x[11]) + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[11])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[7])]][:y_idx] == 74 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[7])]][:id] == 70 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[7])]][:lifted_constr_ref] == :(x[74] == x[1] * x[4] * x[7]) + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[7])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[4]), :(x[20])]][:y_idx] == 105 + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[4]), :(x[20])]][:id] == 101 + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[4]), :(x[20])]][:lifted_constr_ref] == :(x[105] == x[3] * x[4] * x[20]) + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[4]), :(x[20])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[11])]][:y_idx] == 82 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[11])]][:id] == 78 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[11])]][:lifted_constr_ref] == :(x[82] == x[1] * x[4] * x[11]) + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[11])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[9]), :(x[43])]][:y_idx] == 44 + @test alpine.nonconvex_terms[Expr[:(x[9]), :(x[43])]][:id] == 40 + @test alpine.nonconvex_terms[Expr[:(x[9]), :(x[43])]][:lifted_constr_ref] == :(x[44] == x[9] * x[43]) + @test alpine.nonconvex_terms[Expr[:(x[9]), :(x[43])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[3]), :(x[4])]][:y_idx] == 61 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[3]), :(x[4])]][:id] == 57 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[3]), :(x[4])]][:lifted_constr_ref] == :(x[61] == x[1] * x[2] * x[3] * x[4]) + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[3]), :(x[4])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[17]), :(x[10])]][:y_idx] == 18 + @test alpine.nonconvex_terms[Expr[:(x[17]), :(x[10])]][:id] == 14 + @test alpine.nonconvex_terms[Expr[:(x[17]), :(x[10])]][:lifted_constr_ref] == :(x[18] == x[17] * x[10]) + @test alpine.nonconvex_terms[Expr[:(x[17]), :(x[10])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[7])]][:y_idx] == 8 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[7])]][:id] == 4 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[7])]][:lifted_constr_ref] == :(x[8] == x[1] * x[7]) + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[7])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[2])]][:y_idx] == 6 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[2])]][:id] == 2 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[2])]][:lifted_constr_ref] == :(x[6] == x[1] * x[2]) + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[2])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[40])]][:y_idx] == 101 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[40])]][:id] == 97 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[40])]][:lifted_constr_ref] == :(x[101] == x[1] * x[2] * x[40]) + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[40])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[17]), :(x[37])]][:y_idx] == 60 + @test alpine.nonconvex_terms[Expr[:(x[17]), :(x[37])]][:id] == 56 + @test alpine.nonconvex_terms[Expr[:(x[17]), :(x[37])]][:lifted_constr_ref] == :(x[60] == x[17] * x[37]) + @test alpine.nonconvex_terms[Expr[:(x[17]), :(x[37])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[4]), :(x[6])]][:y_idx] == 103 + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[4]), :(x[6])]][:id] == 99 + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[4]), :(x[6])]][:lifted_constr_ref] == :(x[103] == x[3] * x[4] * x[6]) + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[4]), :(x[6])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[3])]][:y_idx] == 7 + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[3])]][:id] == 3 + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[3])]][:lifted_constr_ref] == :(x[7] == x[2] * x[3]) + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[3])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[5])]][:y_idx] == 47 + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[5])]][:id] == 43 + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[5])]][:lifted_constr_ref] == :(x[47] == x[2] * x[3] * x[5]) + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[5])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[6])]][:y_idx] == 13 + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[6])]][:id] == 9 + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[6])]][:lifted_constr_ref] == :(x[13] == x[3] * x[6]) + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[6])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[9]), :(x[31])]][:y_idx] == 35 + @test alpine.nonconvex_terms[Expr[:(x[9]), :(x[31])]][:id] == 31 + @test alpine.nonconvex_terms[Expr[:(x[9]), :(x[31])]][:lifted_constr_ref] == :(x[35] == x[9] * x[31]) + @test alpine.nonconvex_terms[Expr[:(x[9]), :(x[31])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[32])]][:y_idx] == 33 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[32])]][:id] == 29 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[32])]][:lifted_constr_ref] == :(x[33] == x[1] * x[32]) + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[32])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[20])]][:y_idx] == 21 + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[20])]][:id] == 17 + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[20])]][:lifted_constr_ref] == :(x[21] == x[3] * x[20]) + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[20])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[44])]][:y_idx] == 45 + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[44])]][:id] == 41 + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[44])]][:lifted_constr_ref] == :(x[45] == x[5] * x[44]) + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[44])]][:nonlinear_type] == :BILINEAR + + @test alpine.bounding_constr_mip[1][:rhs] == 1.0 + @test alpine.bounding_constr_mip[1][:vars] == Any[:(x[5])] + @test alpine.bounding_constr_mip[1][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[1][:sense] == :(>=) + @test alpine.bounding_constr_mip[1][:cnt] == 1 + @test alpine.bounding_constr_mip[2][:rhs] == 1.0 + @test alpine.bounding_constr_mip[2][:vars] == Any[:(x[6])] + @test alpine.bounding_constr_mip[2][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[2][:sense] == :(<=) + @test alpine.bounding_constr_mip[2][:cnt] == 1 + @test alpine.bounding_constr_mip[3][:rhs] == 1.0 + @test alpine.bounding_constr_mip[3][:vars] == Any[:(x[5]), :(x[7])] + @test alpine.bounding_constr_mip[3][:coefs] == Any[1.0, 1.0] + @test alpine.bounding_constr_mip[3][:sense] == :(<=) + @test alpine.bounding_constr_mip[3][:cnt] == 2 + @test alpine.bounding_constr_mip[4][:rhs] == 1.0 + @test alpine.bounding_constr_mip[4][:vars] == Any[:(x[8])] + @test alpine.bounding_constr_mip[4][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[4][:sense] == :(>=) + @test alpine.bounding_constr_mip[4][:cnt] == 1 + @test alpine.bounding_constr_mip[5][:rhs] == 1.0 + @test alpine.bounding_constr_mip[5][:vars] == Any[:(x[12])] + @test alpine.bounding_constr_mip[5][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[5][:sense] == :(<=) + @test alpine.bounding_constr_mip[5][:cnt] == 1 + @test alpine.bounding_constr_mip[6][:rhs] == 1.0 + @test alpine.bounding_constr_mip[6][:vars] == Any[:(x[13])] + @test alpine.bounding_constr_mip[6][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[6][:sense] == :(>=) + @test alpine.bounding_constr_mip[6][:cnt] == 1 + @test alpine.bounding_constr_mip[7][:rhs] == 1.0 + @test alpine.bounding_constr_mip[7][:vars] == Any[:(x[15])] + @test alpine.bounding_constr_mip[7][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[7][:sense] == :(<=) + @test alpine.bounding_constr_mip[7][:cnt] == 1 + @test alpine.bounding_constr_mip[8][:rhs] == 1.0 + @test alpine.bounding_constr_mip[8][:vars] == Any[:(x[16])] + @test alpine.bounding_constr_mip[8][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[8][:sense] == :(>=) + @test alpine.bounding_constr_mip[8][:cnt] == 1 + @test alpine.bounding_constr_mip[9][:rhs] == 1.0 + @test alpine.bounding_constr_mip[9][:vars] == Any[:(x[18])] + @test alpine.bounding_constr_mip[9][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[9][:sense] == :(<=) + @test alpine.bounding_constr_mip[9][:cnt] == 1 + @test alpine.bounding_constr_mip[10][:rhs] == 1.0 + @test alpine.bounding_constr_mip[10][:vars] == Any[:(x[19])] + @test alpine.bounding_constr_mip[10][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[10][:sense] == :(>=) + @test alpine.bounding_constr_mip[10][:cnt] == 1 + @test alpine.bounding_constr_mip[11][:rhs] == 1.0 + @test alpine.bounding_constr_mip[11][:vars] == Any[:(x[21])] + @test alpine.bounding_constr_mip[11][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[11][:sense] == :(<=) + @test alpine.bounding_constr_mip[11][:cnt] == 1 + @test alpine.bounding_constr_mip[12][:rhs] == 1.0 + @test alpine.bounding_constr_mip[12][:vars] == Any[:(x[22])] + @test alpine.bounding_constr_mip[12][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[12][:sense] == :(>=) + @test alpine.bounding_constr_mip[12][:cnt] == 1 + @test alpine.bounding_constr_mip[13][:rhs] == 1.0 + @test alpine.bounding_constr_mip[13][:vars] == Any[:(x[24])] + @test alpine.bounding_constr_mip[13][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[13][:sense] == :(<=) + @test alpine.bounding_constr_mip[13][:cnt] == 1 + @test alpine.bounding_constr_mip[14][:rhs] == 1.0 + @test alpine.bounding_constr_mip[14][:vars] == Any[:(x[25])] + @test alpine.bounding_constr_mip[14][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[14][:sense] == :(>=) + @test alpine.bounding_constr_mip[14][:cnt] == 1 + @test alpine.bounding_constr_mip[15][:rhs] == 1.0 + @test alpine.bounding_constr_mip[15][:vars] == Any[:(x[27])] + @test alpine.bounding_constr_mip[15][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[15][:sense] == :(<=) + @test alpine.bounding_constr_mip[15][:cnt] == 1 end @testset "Expression Parsing || corner cases" begin @testset "Corner Cases - 1 : sign convertor special case" begin - test_solver = AlpineSolver(nlp_solver=IpoptSolver(print_level=0, sb="yes"), - mip_solver=CbcSolver(logLevel=0), - minlp_solver=pavito_solver, - loglevel=100) + test_solver = optimizer_with_attributes(Alpine.Optimizer,"nlp_solver" => IPOPT_SB, + "mip_solver" => CBC, + "minlp_solver" => JUNIPER, + "loglevel" => 100) - m = Model(solver=test_solver) + m = Model(test_solver) @variable(m, x[1:5], Bin) @NLconstraint(m, x[1] + -x[2] >= 2) @objective(m, Min, x[1]+x[2]) - JuMP.build(m) + alpine = _build(m) - @test m.internalModel.bounding_constr_mip[1][:rhs] == 2.0 - @test m.internalModel.bounding_constr_mip[1][:vars] == Any[:(x[1]), :(x[2])] - @test m.internalModel.bounding_constr_mip[1][:coefs] == Any[1.0, -1.0] - @test m.internalModel.bounding_constr_mip[1][:sense] == :(>=) - @test m.internalModel.bounding_constr_mip[1][:cnt] == 2 + @test alpine.bounding_constr_mip[1][:rhs] == 2.0 + @test alpine.bounding_constr_mip[1][:vars] == Any[:(x[1]), :(x[2])] + @test alpine.bounding_constr_mip[1][:coefs] == Any[1.0, -1.0] + @test alpine.bounding_constr_mip[1][:sense] == :(>=) + @test alpine.bounding_constr_mip[1][:cnt] == 2 end @testset "Corner Cases - 2 : full sub-expression" begin - test_solver = AlpineSolver(nlp_solver=IpoptSolver(print_level=0), - mip_solver=CbcSolver(logLevel=0), - loglevel=100) + test_solver = optimizer_with_attributes(Alpine.Optimizer,"nlp_solver" => IPOPT, + "mip_solver" => CBC, + "loglevel" => 100) - m = Model(solver=test_solver) + m = Model(test_solver) @variable(m, x[1:5]>=0) @NLconstraint(m, (x[1] + 10 + 4 * x[2] + 200) * 5 >= 2 * 5) @constraint(m, x[1] + x[2] + 200 >= 2) @objective(m, Min, x[1]+x[2]) - JuMP.build(m) - - @test m.internalModel.bounding_constr_mip[1][:rhs] == -198.0 - @test m.internalModel.bounding_constr_mip[1][:vars] == Any[:(x[1]), :(x[2])] - @test m.internalModel.bounding_constr_mip[1][:coefs] == Any[1.0, 1.0] - @test m.internalModel.bounding_constr_mip[1][:sense] == :(>=) - @test m.internalModel.bounding_constr_mip[1][:cnt] == 2 - @test m.internalModel.bounding_constr_mip[2][:rhs] == -1040.0 - @test m.internalModel.bounding_constr_mip[2][:vars] == Any[:(x[1]), :(x[2])] - @test m.internalModel.bounding_constr_mip[2][:coefs] == Any[5.0, 20.0] - @test m.internalModel.bounding_constr_mip[2][:sense] == :(>=) - @test m.internalModel.bounding_constr_mip[2][:cnt] == 2 + alpine = _build(m) + + @test alpine.bounding_constr_mip[1][:rhs] == -198.0 + @test alpine.bounding_constr_mip[1][:vars] == Any[:(x[1]), :(x[2])] + @test alpine.bounding_constr_mip[1][:coefs] == Any[1.0, 1.0] + @test alpine.bounding_constr_mip[1][:sense] == :(>=) + @test alpine.bounding_constr_mip[1][:cnt] == 2 + @test alpine.bounding_constr_mip[2][:rhs] == -1040.0 + @test alpine.bounding_constr_mip[2][:vars] == Any[:(x[1]), :(x[2])] + @test alpine.bounding_constr_mip[2][:coefs] == Any[5.0, 20.0] + @test alpine.bounding_constr_mip[2][:sense] == :(>=) + @test alpine.bounding_constr_mip[2][:cnt] == 2 end @testset "Corner Cases - 2 : full sub-expression" begin - test_solver = AlpineSolver(nlp_solver=IpoptSolver(print_level=0, sb="yes"), - mip_solver=CbcSolver(logLevel=0), - loglevel=100) + test_solver = optimizer_with_attributes(Alpine.Optimizer,"nlp_solver" => IPOPT_SB, + "mip_solver" => CBC, + "loglevel" => 100) - m = Model(solver=test_solver) + m = Model(test_solver) @variable(m, x[1:5]>=0) @NLconstraint(m, (x[1] + 10 + 4 * x[2] + 200) * 5 >= 2 * 5) @constraint(m, x[1] + x[2] + 200 >= 2) @objective(m, Min, x[1]+x[2]) - JuMP.build(m) - - @test m.internalModel.bounding_constr_mip[1][:rhs] == -198.0 - @test m.internalModel.bounding_constr_mip[1][:vars] == Any[:(x[1]), :(x[2])] - @test m.internalModel.bounding_constr_mip[1][:coefs] == Any[1.0, 1.0] - @test m.internalModel.bounding_constr_mip[1][:sense] == :(>=) - @test m.internalModel.bounding_constr_mip[1][:cnt] == 2 - @test m.internalModel.bounding_constr_mip[2][:rhs] == -1040.0 - @test m.internalModel.bounding_constr_mip[2][:vars] == Any[:(x[1]), :(x[2])] - @test m.internalModel.bounding_constr_mip[2][:coefs] == Any[5.0, 20.0] - @test m.internalModel.bounding_constr_mip[2][:sense] == :(>=) - @test m.internalModel.bounding_constr_mip[2][:cnt] == 2 + alpine = _build(m) + + @test alpine.bounding_constr_mip[1][:rhs] == -198.0 + @test alpine.bounding_constr_mip[1][:vars] == Any[:(x[1]), :(x[2])] + @test alpine.bounding_constr_mip[1][:coefs] == Any[1.0, 1.0] + @test alpine.bounding_constr_mip[1][:sense] == :(>=) + @test alpine.bounding_constr_mip[1][:cnt] == 2 + @test alpine.bounding_constr_mip[2][:rhs] == -1040.0 + @test alpine.bounding_constr_mip[2][:vars] == Any[:(x[1]), :(x[2])] + @test alpine.bounding_constr_mip[2][:coefs] == Any[5.0, 20.0] + @test alpine.bounding_constr_mip[2][:sense] == :(>=) + @test alpine.bounding_constr_mip[2][:cnt] == 2 end end @@ -2636,62 +2649,62 @@ end @testset "Expression Parsing || bmpl && binlin && binprod" begin - test_solver=AlpineSolver(minlp_solver=pavito_solver,nlp_solver=IpoptSolver(print_level=0, sb="yes"),mip_solver=CbcSolver(logLevel=0),loglevel=100) + test_solver=optimizer_with_attributes(Alpine.Optimizer,"minlp_solver" => JUNIPER,"nlp_solver" => IPOPT_SB,"mip_solver" => CBC,"loglevel" => 100) m = bpml(solver=test_solver) - JuMP.build(m) # Setup internal model - - @test length(keys(m.internalModel.nonconvex_terms)) == 12 - - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[6])]][:y_idx] == 11 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[2])]][:y_idx] == 12 - @test m.internalModel.nonconvex_terms[Expr[:(x[12]), :(x[6])]][:y_idx] == 13 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[3])]][:y_idx] == 14 - @test m.internalModel.nonconvex_terms[Expr[:(x[14]), :(x[6])]][:y_idx] == 15 - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[7])]][:y_idx] == 16 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[16])]][:y_idx] == 17 - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[7]), :(x[8])]][:y_idx] == 18 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[18])]][:y_idx] == 19 - @test m.internalModel.nonconvex_terms[Expr[:(x[14]), :(x[18])]][:y_idx] == 20 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[3]), :(x[4]), :(x[5])]][:y_idx] == 21 - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[7]), :(x[9]), :(x[10]), :(x[6])]][:y_idx] == 22 - - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[6])]][:nonlinear_type] == :BINLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[2])]][:nonlinear_type] == :BINPROD - @test m.internalModel.nonconvex_terms[Expr[:(x[12]), :(x[6])]][:nonlinear_type] == :BINLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[3])]][:nonlinear_type] == :BINPROD - @test m.internalModel.nonconvex_terms[Expr[:(x[14]), :(x[6])]][:nonlinear_type] == :BINLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[7])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[16])]][:nonlinear_type] == :BINLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[7]), :(x[8])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[18])]][:nonlinear_type] == :BINLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[14]), :(x[18])]][:nonlinear_type] == :BINLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[3]), :(x[4]), :(x[5])]][:nonlinear_type] == :BINPROD - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[7]), :(x[9]), :(x[10]), :(x[6])]][:nonlinear_type] == :MULTILINEAR - - @test length(m.internalModel.var_type) == 22 - @test m.internalModel.var_type[11] == :Cont - @test m.internalModel.var_type[12] == :Bin - @test m.internalModel.var_type[13] == :Cont - @test m.internalModel.var_type[14] == :Bin - @test m.internalModel.var_type[15] == :Cont - @test m.internalModel.var_type[16] == :Cont - @test m.internalModel.var_type[17] == :Cont - @test m.internalModel.var_type[18] == :Cont - @test m.internalModel.var_type[19] == :Cont - @test m.internalModel.var_type[20] == :Cont - @test m.internalModel.var_type[21] == :Bin - @test m.internalModel.var_type[22] == :Cont + alpine = _build(m) # Setup internal model + + @test length(keys(alpine.nonconvex_terms)) == 12 + + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[6])]][:y_idx] == 11 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[2])]][:y_idx] == 12 + @test alpine.nonconvex_terms[Expr[:(x[12]), :(x[6])]][:y_idx] == 13 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[3])]][:y_idx] == 14 + @test alpine.nonconvex_terms[Expr[:(x[14]), :(x[6])]][:y_idx] == 15 + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[7])]][:y_idx] == 16 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[16])]][:y_idx] == 17 + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[7]), :(x[8])]][:y_idx] == 18 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[18])]][:y_idx] == 19 + @test alpine.nonconvex_terms[Expr[:(x[14]), :(x[18])]][:y_idx] == 20 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[3]), :(x[4]), :(x[5])]][:y_idx] == 21 + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[7]), :(x[9]), :(x[10]), :(x[6])]][:y_idx] == 22 + + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[6])]][:nonlinear_type] == :BINLIN + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[2])]][:nonlinear_type] == :BINPROD + @test alpine.nonconvex_terms[Expr[:(x[12]), :(x[6])]][:nonlinear_type] == :BINLIN + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[3])]][:nonlinear_type] == :BINPROD + @test alpine.nonconvex_terms[Expr[:(x[14]), :(x[6])]][:nonlinear_type] == :BINLIN + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[7])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[16])]][:nonlinear_type] == :BINLIN + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[7]), :(x[8])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[18])]][:nonlinear_type] == :BINLIN + @test alpine.nonconvex_terms[Expr[:(x[14]), :(x[18])]][:nonlinear_type] == :BINLIN + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[3]), :(x[4]), :(x[5])]][:nonlinear_type] == :BINPROD + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[7]), :(x[9]), :(x[10]), :(x[6])]][:nonlinear_type] == :MULTILINEAR + + @test length(alpine.var_type) == 22 + @test alpine.var_type[11] == :Cont + @test alpine.var_type[12] == :Bin + @test alpine.var_type[13] == :Cont + @test alpine.var_type[14] == :Bin + @test alpine.var_type[15] == :Cont + @test alpine.var_type[16] == :Cont + @test alpine.var_type[17] == :Cont + @test alpine.var_type[18] == :Cont + @test alpine.var_type[19] == :Cont + @test alpine.var_type[20] == :Cont + @test alpine.var_type[21] == :Bin + @test alpine.var_type[22] == :Cont end @testset "Expression Parsing || bmpl && binlin && binprod with linear lifting and coefficients" begin - test_solver=AlpineSolver(minlp_solver=pavito_solver,nlp_solver=IpoptSolver(print_level=0, sb="yes"),mip_solver=CbcSolver(logLevel=0),loglevel=100) + test_solver=optimizer_with_attributes(Alpine.Optimizer,"minlp_solver" => JUNIPER,"nlp_solver" => IPOPT_SB,"mip_solver" => CBC,"loglevel" => 100) m = bmpl_linearlifting(solver=test_solver) - JuMP.build(m) + alpine = _build(m) lk1 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+), Pair{Symbol,Any}(:scalar, 0.0), @@ -2709,29 +2722,29 @@ end Pair{Symbol,Any}(:scalar, 0.0), Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 6), (1.0, 25)]))) - @test haskey(m.internalModel.linear_terms, lk1) - @test haskey(m.internalModel.linear_terms, lk2) - @test haskey(m.internalModel.linear_terms, lk3) - @test haskey(m.internalModel.linear_terms, lk4) - @test haskey(m.internalModel.linear_terms, lk5) - - @test m.internalModel.linear_terms[lk1][:lifted_constr_ref] == :(x[20] == x[1] + x[17]) - @test m.internalModel.linear_terms[lk2][:lifted_constr_ref] == :(x[13] == x[11] + x[12]) - @test m.internalModel.linear_terms[lk3][:lifted_constr_ref] == :(x[15] == 2*x[6] + x[7]) - @test m.internalModel.linear_terms[lk4][:lifted_constr_ref] == :(x[21] == x[6] + x[19]) - @test m.internalModel.linear_terms[lk5][:lifted_constr_ref] == :(x[26] == x[6] + x[25]) - - @test m.internalModel.linear_terms[lk1][:y_idx] == 20 - @test m.internalModel.linear_terms[lk2][:y_idx] == 13 - @test m.internalModel.linear_terms[lk3][:y_idx] == 15 - @test m.internalModel.linear_terms[lk4][:y_idx] == 21 - @test m.internalModel.linear_terms[lk5][:y_idx] == 26 - - @test m.internalModel.linear_terms[lk1][:y_type] == :Cont - @test m.internalModel.linear_terms[lk2][:y_type] == :Cont - @test m.internalModel.linear_terms[lk3][:y_type] == :Cont - @test m.internalModel.linear_terms[lk4][:y_type] == :Cont - @test m.internalModel.linear_terms[lk5][:y_type] == :Cont + @test haskey(alpine.linear_terms, lk1) + @test haskey(alpine.linear_terms, lk2) + @test haskey(alpine.linear_terms, lk3) + @test haskey(alpine.linear_terms, lk4) + @test haskey(alpine.linear_terms, lk5) + + @test alpine.linear_terms[lk1][:lifted_constr_ref] == :(x[20] == x[1] + x[17]) + @test alpine.linear_terms[lk2][:lifted_constr_ref] == :(x[13] == x[11] + x[12]) + @test alpine.linear_terms[lk3][:lifted_constr_ref] == :(x[15] == 2*x[6] + x[7]) + @test alpine.linear_terms[lk4][:lifted_constr_ref] == :(x[21] == x[6] + x[19]) + @test alpine.linear_terms[lk5][:lifted_constr_ref] == :(x[26] == x[6] + x[25]) + + @test alpine.linear_terms[lk1][:y_idx] == 20 + @test alpine.linear_terms[lk2][:y_idx] == 13 + @test alpine.linear_terms[lk3][:y_idx] == 15 + @test alpine.linear_terms[lk4][:y_idx] == 21 + @test alpine.linear_terms[lk5][:y_idx] == 26 + + @test alpine.linear_terms[lk1][:y_type] == :Cont + @test alpine.linear_terms[lk2][:y_type] == :Cont + @test alpine.linear_terms[lk3][:y_type] == :Cont + @test alpine.linear_terms[lk4][:y_type] == :Cont + @test alpine.linear_terms[lk5][:y_type] == :Cont nlk1 = Expr[:(x[18]), :(x[7])] nlk2 = Expr[:(x[6]), :(x[7]), :(x[8])] @@ -2746,997 +2759,997 @@ end nlk11 = Expr[:(x[20]), :(x[21])] nlk12 = Expr[:(x[3]), :(x[4])] - @test haskey(m.internalModel.nonconvex_terms, nlk1) - @test haskey(m.internalModel.nonconvex_terms, nlk2) - @test haskey(m.internalModel.nonconvex_terms, nlk3) - @test haskey(m.internalModel.nonconvex_terms, nlk4) - @test haskey(m.internalModel.nonconvex_terms, nlk5) - @test haskey(m.internalModel.nonconvex_terms, nlk6) - @test haskey(m.internalModel.nonconvex_terms, nlk7) - @test haskey(m.internalModel.nonconvex_terms, nlk8) - @test haskey(m.internalModel.nonconvex_terms, nlk9) - @test haskey(m.internalModel.nonconvex_terms, nlk10) - @test haskey(m.internalModel.nonconvex_terms, nlk11) - @test haskey(m.internalModel.nonconvex_terms, nlk12) - - @test m.internalModel.nonconvex_terms[nlk1][:id] == 7 - @test m.internalModel.nonconvex_terms[nlk2][:id] == 1 - @test m.internalModel.nonconvex_terms[nlk3][:id] == 9 - @test m.internalModel.nonconvex_terms[nlk4][:id] == 12 - @test m.internalModel.nonconvex_terms[nlk5][:id] == 3 - @test m.internalModel.nonconvex_terms[nlk6][:id] == 4 - @test m.internalModel.nonconvex_terms[nlk7][:id] == 5 - @test m.internalModel.nonconvex_terms[nlk8][:id] == 11 - @test m.internalModel.nonconvex_terms[nlk9][:id] == 6 - @test m.internalModel.nonconvex_terms[nlk10][:id] == 2 - @test m.internalModel.nonconvex_terms[nlk11][:id] == 8 - @test m.internalModel.nonconvex_terms[nlk12][:id] == 10 - - @test m.internalModel.nonconvex_terms[nlk1][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[nlk2][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[nlk3][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[nlk4][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[nlk5][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[nlk6][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[nlk7][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[nlk8][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[nlk9][:y_type] == :Bin - @test m.internalModel.nonconvex_terms[nlk10][:y_type] == :Bin - @test m.internalModel.nonconvex_terms[nlk11][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[nlk12][:y_type] == :Bin - - @test m.internalModel.nonconvex_terms[nlk1][:y_idx] == 19 - @test m.internalModel.nonconvex_terms[nlk2][:y_idx] == 11 - @test m.internalModel.nonconvex_terms[nlk3][:y_idx] == 23 - @test m.internalModel.nonconvex_terms[nlk4][:y_idx] == 27 - @test m.internalModel.nonconvex_terms[nlk5][:y_idx] == 14 - @test m.internalModel.nonconvex_terms[nlk6][:y_idx] == 16 - @test m.internalModel.nonconvex_terms[nlk7][:y_idx] == 17 - @test m.internalModel.nonconvex_terms[nlk8][:y_idx] == 25 - @test m.internalModel.nonconvex_terms[nlk9][:y_idx] == 18 - @test m.internalModel.nonconvex_terms[nlk10][:y_idx] == 12 - @test m.internalModel.nonconvex_terms[nlk11][:y_idx] == 22 - @test m.internalModel.nonconvex_terms[nlk12][:y_idx] == 24 - - @test m.internalModel.nonconvex_terms[nlk1][:nonlinear_type] == :BINLIN - @test m.internalModel.nonconvex_terms[nlk2][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[nlk3][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[nlk4][:nonlinear_type] == :BINLIN - @test m.internalModel.nonconvex_terms[nlk5][:nonlinear_type] == :BINLIN - @test m.internalModel.nonconvex_terms[nlk6][:nonlinear_type] == :BINLIN - @test m.internalModel.nonconvex_terms[nlk7][:nonlinear_type] == :BINLIN - @test m.internalModel.nonconvex_terms[nlk8][:nonlinear_type] == :BINLIN - @test m.internalModel.nonconvex_terms[nlk9][:nonlinear_type] == :BINPROD - @test m.internalModel.nonconvex_terms[nlk10][:nonlinear_type] == :BINPROD - @test m.internalModel.nonconvex_terms[nlk11][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[nlk12][:nonlinear_type] == :BINPROD + @test haskey(alpine.nonconvex_terms, nlk1) + @test haskey(alpine.nonconvex_terms, nlk2) + @test haskey(alpine.nonconvex_terms, nlk3) + @test haskey(alpine.nonconvex_terms, nlk4) + @test haskey(alpine.nonconvex_terms, nlk5) + @test haskey(alpine.nonconvex_terms, nlk6) + @test haskey(alpine.nonconvex_terms, nlk7) + @test haskey(alpine.nonconvex_terms, nlk8) + @test haskey(alpine.nonconvex_terms, nlk9) + @test haskey(alpine.nonconvex_terms, nlk10) + @test haskey(alpine.nonconvex_terms, nlk11) + @test haskey(alpine.nonconvex_terms, nlk12) + + @test alpine.nonconvex_terms[nlk1][:id] == 7 + @test alpine.nonconvex_terms[nlk2][:id] == 1 + @test alpine.nonconvex_terms[nlk3][:id] == 9 + @test alpine.nonconvex_terms[nlk4][:id] == 12 + @test alpine.nonconvex_terms[nlk5][:id] == 3 + @test alpine.nonconvex_terms[nlk6][:id] == 4 + @test alpine.nonconvex_terms[nlk7][:id] == 5 + @test alpine.nonconvex_terms[nlk8][:id] == 11 + @test alpine.nonconvex_terms[nlk9][:id] == 6 + @test alpine.nonconvex_terms[nlk10][:id] == 2 + @test alpine.nonconvex_terms[nlk11][:id] == 8 + @test alpine.nonconvex_terms[nlk12][:id] == 10 + + @test alpine.nonconvex_terms[nlk1][:y_type] == :Cont + @test alpine.nonconvex_terms[nlk2][:y_type] == :Cont + @test alpine.nonconvex_terms[nlk3][:y_type] == :Cont + @test alpine.nonconvex_terms[nlk4][:y_type] == :Cont + @test alpine.nonconvex_terms[nlk5][:y_type] == :Cont + @test alpine.nonconvex_terms[nlk6][:y_type] == :Cont + @test alpine.nonconvex_terms[nlk7][:y_type] == :Cont + @test alpine.nonconvex_terms[nlk8][:y_type] == :Cont + @test alpine.nonconvex_terms[nlk9][:y_type] == :Bin + @test alpine.nonconvex_terms[nlk10][:y_type] == :Bin + @test alpine.nonconvex_terms[nlk11][:y_type] == :Cont + @test alpine.nonconvex_terms[nlk12][:y_type] == :Bin + + @test alpine.nonconvex_terms[nlk1][:y_idx] == 19 + @test alpine.nonconvex_terms[nlk2][:y_idx] == 11 + @test alpine.nonconvex_terms[nlk3][:y_idx] == 23 + @test alpine.nonconvex_terms[nlk4][:y_idx] == 27 + @test alpine.nonconvex_terms[nlk5][:y_idx] == 14 + @test alpine.nonconvex_terms[nlk6][:y_idx] == 16 + @test alpine.nonconvex_terms[nlk7][:y_idx] == 17 + @test alpine.nonconvex_terms[nlk8][:y_idx] == 25 + @test alpine.nonconvex_terms[nlk9][:y_idx] == 18 + @test alpine.nonconvex_terms[nlk10][:y_idx] == 12 + @test alpine.nonconvex_terms[nlk11][:y_idx] == 22 + @test alpine.nonconvex_terms[nlk12][:y_idx] == 24 + + @test alpine.nonconvex_terms[nlk1][:nonlinear_type] == :BINLIN + @test alpine.nonconvex_terms[nlk2][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[nlk3][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[nlk4][:nonlinear_type] == :BINLIN + @test alpine.nonconvex_terms[nlk5][:nonlinear_type] == :BINLIN + @test alpine.nonconvex_terms[nlk6][:nonlinear_type] == :BINLIN + @test alpine.nonconvex_terms[nlk7][:nonlinear_type] == :BINLIN + @test alpine.nonconvex_terms[nlk8][:nonlinear_type] == :BINLIN + @test alpine.nonconvex_terms[nlk9][:nonlinear_type] == :BINPROD + @test alpine.nonconvex_terms[nlk10][:nonlinear_type] == :BINPROD + @test alpine.nonconvex_terms[nlk11][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[nlk12][:nonlinear_type] == :BINPROD end @testset "Expression Parsing || INTPROD Operators" begin - test_solver=AlpineSolver(minlp_solver=pavito_solver,nlp_solver=IpoptSolver(print_level=0, sb="yes"),mip_solver=CbcSolver(logLevel=0),loglevel=100) + test_solver=optimizer_with_attributes(Alpine.Optimizer,"minlp_solver" => JUNIPER,"nlp_solver" => IPOPT_SB,"mip_solver" => CBC,"loglevel" => 100) m = intprod_basic(solver=test_solver) - JuMP.build(m) # Setup internal model - - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[4])]][:y_idx] == 18 - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[4])]][:id] == 4 - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[4])]][:lifted_constr_ref] == :(x[18] == x[2] * x[3] * x[4]) - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[4])]][:nonlinear_type] == :INTPROD - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[4])]][:y_type] == :Int - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[4])]][:constr_id] == Set(Any[3]) - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[16])]][:y_idx] == 17 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[16])]][:id] == 3 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[16])]][:lifted_constr_ref] == :(x[17] == x[1] * x[4] * x[16]) - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[16])]][:nonlinear_type] == :INTPROD - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[16])]][:y_type] == :Int - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[16])]][:constr_id] == Set(Any[2]) - @test m.internalModel.nonconvex_terms[Expr[:(x[11]), :(x[2])]][:y_idx] == 12 - @test m.internalModel.nonconvex_terms[Expr[:(x[11]), :(x[2])]][:id] == 1 - @test m.internalModel.nonconvex_terms[Expr[:(x[11]), :(x[2])]][:lifted_constr_ref] == :(x[12] == x[11] * x[2]) - @test m.internalModel.nonconvex_terms[Expr[:(x[11]), :(x[2])]][:nonlinear_type] == :INTPROD - @test m.internalModel.nonconvex_terms[Expr[:(x[11]), :(x[2])]][:y_type] == :Int - @test m.internalModel.nonconvex_terms[Expr[:(x[11]), :(x[2])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[5])]][:y_idx] == 19 - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[5])]][:id] == 5 - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[5])]][:lifted_constr_ref] == :(x[19] == (*)(x[5])) - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[5])]][:nonlinear_type] == :INTPROD - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[5])]][:y_type] == :Int - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[5])]][:constr_id] == Set(Any[4]) - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[20]), :(x[19])]][:y_idx] == 21 - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[20]), :(x[19])]][:id] == 6 - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[20]), :(x[19])]][:lifted_constr_ref] == :(x[21] == x[5] * x[20] * x[19]) - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[20]), :(x[19])]][:nonlinear_type] == :INTPROD - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[20]), :(x[19])]][:y_type] == :Int - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[20]), :(x[19])]][:constr_id] == Set(Any[4]) - @test m.internalModel.nonconvex_terms[Expr[:(x[13]), :(x[14])]][:y_idx] == 15 - @test m.internalModel.nonconvex_terms[Expr[:(x[13]), :(x[14])]][:id] == 2 - @test m.internalModel.nonconvex_terms[Expr[:(x[13]), :(x[14])]][:lifted_constr_ref] == :(x[15] == x[13] * x[14]) - @test m.internalModel.nonconvex_terms[Expr[:(x[13]), :(x[14])]][:nonlinear_type] == :INTPROD - @test m.internalModel.nonconvex_terms[Expr[:(x[13]), :(x[14])]][:y_type] == :Int - @test m.internalModel.nonconvex_terms[Expr[:(x[13]), :(x[14])]][:constr_id] == Set(Any[1]) + alpine = _build(m) # Setup internal model + + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[4])]][:y_idx] == 18 + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[4])]][:id] == 4 + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[4])]][:lifted_constr_ref] == :(x[18] == x[2] * x[3] * x[4]) + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[4])]][:nonlinear_type] == :INTPROD + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[4])]][:y_type] == :Int + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[4])]][:constr_id] == Set(Any[3]) + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[16])]][:y_idx] == 17 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[16])]][:id] == 3 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[16])]][:lifted_constr_ref] == :(x[17] == x[1] * x[4] * x[16]) + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[16])]][:nonlinear_type] == :INTPROD + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[16])]][:y_type] == :Int + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[4]), :(x[16])]][:constr_id] == Set(Any[2]) + @test alpine.nonconvex_terms[Expr[:(x[11]), :(x[2])]][:y_idx] == 12 + @test alpine.nonconvex_terms[Expr[:(x[11]), :(x[2])]][:id] == 1 + @test alpine.nonconvex_terms[Expr[:(x[11]), :(x[2])]][:lifted_constr_ref] == :(x[12] == x[11] * x[2]) + @test alpine.nonconvex_terms[Expr[:(x[11]), :(x[2])]][:nonlinear_type] == :INTPROD + @test alpine.nonconvex_terms[Expr[:(x[11]), :(x[2])]][:y_type] == :Int + @test alpine.nonconvex_terms[Expr[:(x[11]), :(x[2])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[5])]][:y_idx] == 19 + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[5])]][:id] == 5 + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[5])]][:lifted_constr_ref] == :(x[19] == (*)(x[5])) + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[5])]][:nonlinear_type] == :INTPROD + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[5])]][:y_type] == :Int + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[5])]][:constr_id] == Set(Any[4]) + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[20]), :(x[19])]][:y_idx] == 21 + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[20]), :(x[19])]][:id] == 6 + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[20]), :(x[19])]][:lifted_constr_ref] == :(x[21] == x[5] * x[20] * x[19]) + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[20]), :(x[19])]][:nonlinear_type] == :INTPROD + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[20]), :(x[19])]][:y_type] == :Int + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[20]), :(x[19])]][:constr_id] == Set(Any[4]) + @test alpine.nonconvex_terms[Expr[:(x[13]), :(x[14])]][:y_idx] == 15 + @test alpine.nonconvex_terms[Expr[:(x[13]), :(x[14])]][:id] == 2 + @test alpine.nonconvex_terms[Expr[:(x[13]), :(x[14])]][:lifted_constr_ref] == :(x[15] == x[13] * x[14]) + @test alpine.nonconvex_terms[Expr[:(x[13]), :(x[14])]][:nonlinear_type] == :INTPROD + @test alpine.nonconvex_terms[Expr[:(x[13]), :(x[14])]][:y_type] == :Int + @test alpine.nonconvex_terms[Expr[:(x[13]), :(x[14])]][:constr_id] == Set(Any[1]) lk1 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 2), (1.0, 4), (1.0, 1), (1.0, 5), (1.0, 3)]))) - @test m.internalModel.linear_terms[lk1][:y_idx] == 11 - @test m.internalModel.linear_terms[lk1][:id] == 1 - @test m.internalModel.linear_terms[lk1][:y_type] == :(Int) + @test alpine.linear_terms[lk1][:y_idx] == 11 + @test alpine.linear_terms[lk1][:id] == 1 + @test alpine.linear_terms[lk1][:y_type] == :(Int) lk2 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 2), (-1.0, 3)]))) - @test m.internalModel.linear_terms[lk2][:y_idx] == 20 - @test m.internalModel.linear_terms[lk2][:id] == 5 - @test m.internalModel.linear_terms[lk2][:y_type] == :(Int) + @test alpine.linear_terms[lk2][:y_idx] == 20 + @test alpine.linear_terms[lk2][:id] == 5 + @test alpine.linear_terms[lk2][:y_type] == :(Int) lk3 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 2), (1.0, 3)]))) - @test m.internalModel.linear_terms[lk3][:y_idx] == 16 - @test m.internalModel.linear_terms[lk3][:id] == 4 - @test m.internalModel.linear_terms[lk3][:y_type] == :(Int) + @test alpine.linear_terms[lk3][:y_idx] == 16 + @test alpine.linear_terms[lk3][:id] == 4 + @test alpine.linear_terms[lk3][:y_type] == :(Int) lk4 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 4), (1.0, 3)]))) - @test m.internalModel.linear_terms[lk4][:y_idx] == 14 - @test m.internalModel.linear_terms[lk4][:id] == 3 - @test m.internalModel.linear_terms[lk4][:y_type] == :(Int) + @test alpine.linear_terms[lk4][:y_idx] == 14 + @test alpine.linear_terms[lk4][:id] == 3 + @test alpine.linear_terms[lk4][:y_type] == :(Int) lk5 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 2), (1.0, 1)]))) - @test m.internalModel.linear_terms[lk5][:y_idx] == 13 - @test m.internalModel.linear_terms[lk5][:id] == 2 - @test m.internalModel.linear_terms[lk5][:y_type] == :(Int) - @test m.internalModel.bounding_constr_mip[1][:rhs] == 25.0 - @test m.internalModel.bounding_constr_mip[1][:vars] == Any[:(x[15])] - @test m.internalModel.bounding_constr_mip[1][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[1][:sense] == :(>=) - @test m.internalModel.bounding_constr_mip[1][:cnt] == 1 - @test m.internalModel.bounding_constr_mip[2][:rhs] == 25.0 - @test m.internalModel.bounding_constr_mip[2][:vars] == Any[:(x[17])] - @test m.internalModel.bounding_constr_mip[2][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[2][:sense] == :(>=) - @test m.internalModel.bounding_constr_mip[2][:cnt] == 1 - @test m.internalModel.bounding_constr_mip[3][:rhs] == 10.0 - @test m.internalModel.bounding_constr_mip[3][:vars] == Any[:(x[1]), :(x[18])] - @test m.internalModel.bounding_constr_mip[3][:coefs] == Any[1.0, -1.0] - @test m.internalModel.bounding_constr_mip[3][:sense] == :(>=) - @test m.internalModel.bounding_constr_mip[3][:cnt] == 2 - @test m.internalModel.bounding_constr_mip[4][:rhs] == 40.0 - @test m.internalModel.bounding_constr_mip[4][:vars] == Any[:(x[21])] - @test m.internalModel.bounding_constr_mip[4][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[4][:sense] == :(>=) - @test m.internalModel.bounding_constr_mip[4][:cnt] == 1 + @test alpine.linear_terms[lk5][:y_idx] == 13 + @test alpine.linear_terms[lk5][:id] == 2 + @test alpine.linear_terms[lk5][:y_type] == :(Int) + @test alpine.bounding_constr_mip[1][:rhs] == 25.0 + @test alpine.bounding_constr_mip[1][:vars] == Any[:(x[15])] + @test alpine.bounding_constr_mip[1][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[1][:sense] == :(>=) + @test alpine.bounding_constr_mip[1][:cnt] == 1 + @test alpine.bounding_constr_mip[2][:rhs] == 25.0 + @test alpine.bounding_constr_mip[2][:vars] == Any[:(x[17])] + @test alpine.bounding_constr_mip[2][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[2][:sense] == :(>=) + @test alpine.bounding_constr_mip[2][:cnt] == 1 + @test alpine.bounding_constr_mip[3][:rhs] == 10.0 + @test alpine.bounding_constr_mip[3][:vars] == Any[:(x[1]), :(x[18])] + @test alpine.bounding_constr_mip[3][:coefs] == Any[1.0, -1.0] + @test alpine.bounding_constr_mip[3][:sense] == :(>=) + @test alpine.bounding_constr_mip[3][:cnt] == 2 + @test alpine.bounding_constr_mip[4][:rhs] == 40.0 + @test alpine.bounding_constr_mip[4][:vars] == Any[:(x[21])] + @test alpine.bounding_constr_mip[4][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[4][:sense] == :(>=) + @test alpine.bounding_constr_mip[4][:cnt] == 1 end @testset "Expression Parsing || ex1225a" begin - test_solver = AlpineSolver(minlp_solver=pavito_solver, nlp_solver=IpoptSolver(print_level=0, sb="yes"), mip_solver=CbcSolver(logLevel=0),loglevel=100) + test_solver = optimizer_with_attributes(Alpine.Optimizer,"minlp_solver" => JUNIPER, "nlp_solver" => IPOPT_SB, "mip_solver" => CBC,"loglevel" => 100) m = ex1225a(solver=test_solver) - JuMP.build(m) - - @test m.internalModel.nonconvex_terms[Expr[:(x[44]), :(x[44])]][:y_idx] == 46 - @test m.internalModel.nonconvex_terms[Expr[:(x[44]), :(x[44])]][:id] == 16 - @test m.internalModel.nonconvex_terms[Expr[:(x[44]), :(x[44])]][:lifted_constr_ref] == :(x[46] == (*)(x[44])) - @test m.internalModel.nonconvex_terms[Expr[:(x[44]), :(x[44])]][:nonlinear_type] == :MONOMIAL - @test m.internalModel.nonconvex_terms[Expr[:(x[44]), :(x[44])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[44]), :(x[44])]][:constr_id] == Set(Any[25, 28]) - @test m.internalModel.nonconvex_terms[Expr[:(x[13]), :(x[52])]][:y_idx] == 53 - @test m.internalModel.nonconvex_terms[Expr[:(x[13]), :(x[52])]][:id] == 22 - @test m.internalModel.nonconvex_terms[Expr[:(x[13]), :(x[52])]][:lifted_constr_ref] == :(x[53] == x[13] * x[52]) - @test m.internalModel.nonconvex_terms[Expr[:(x[13]), :(x[52])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[13]), :(x[52])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[13]), :(x[52])]][:constr_id] == Set(Any[26]) - @test m.internalModel.nonconvex_terms[Expr[:(x[25]), :(x[10])]][:y_idx] == 64 - @test m.internalModel.nonconvex_terms[Expr[:(x[25]), :(x[10])]][:id] == 33 - @test m.internalModel.nonconvex_terms[Expr[:(x[25]), :(x[10])]][:lifted_constr_ref] == :(x[64] == x[25] * x[10]) - @test m.internalModel.nonconvex_terms[Expr[:(x[25]), :(x[10])]][:nonlinear_type] == :INTLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[25]), :(x[10])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[25]), :(x[10])]][:constr_id] == Set(Any[35]) - @test m.internalModel.nonconvex_terms[Expr[:(x[19]), :(x[36])]][:y_idx] == 37 - @test m.internalModel.nonconvex_terms[Expr[:(x[19]), :(x[36])]][:id] == 9 - @test m.internalModel.nonconvex_terms[Expr[:(x[19]), :(x[36])]][:lifted_constr_ref] == :(x[37] == x[19] * x[36]) - @test m.internalModel.nonconvex_terms[Expr[:(x[19]), :(x[36])]][:nonlinear_type] == :BINLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[19]), :(x[36])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[19]), :(x[36])]][:constr_id] == Set(Any[23]) - @test m.internalModel.nonconvex_terms[Expr[:(x[38]), :(x[38])]][:y_idx] == 40 - @test m.internalModel.nonconvex_terms[Expr[:(x[38]), :(x[38])]][:id] == 11 - @test m.internalModel.nonconvex_terms[Expr[:(x[38]), :(x[38])]][:lifted_constr_ref] == :(x[40] == (*)(x[38])) - @test m.internalModel.nonconvex_terms[Expr[:(x[38]), :(x[38])]][:nonlinear_type] == :MONOMIAL - @test m.internalModel.nonconvex_terms[Expr[:(x[38]), :(x[38])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[38]), :(x[38])]][:constr_id] == Set(Any[27, 24]) - @test m.internalModel.nonconvex_terms[Expr[:(x[35]), :(x[34])]][:y_idx] == 36 - @test m.internalModel.nonconvex_terms[Expr[:(x[35]), :(x[34])]][:id] == 8 - @test m.internalModel.nonconvex_terms[Expr[:(x[35]), :(x[34])]][:lifted_constr_ref] == :(x[36] == x[35] * x[34]) - @test m.internalModel.nonconvex_terms[Expr[:(x[35]), :(x[34])]][:nonlinear_type] == :INTLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[35]), :(x[34])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[35]), :(x[34])]][:constr_id] == Set(Any[23]) - @test m.internalModel.nonconvex_terms[Expr[:(x[20]), :(x[23])]][:y_idx] == 27 - @test m.internalModel.nonconvex_terms[Expr[:(x[20]), :(x[23])]][:id] == 1 - @test m.internalModel.nonconvex_terms[Expr[:(x[20]), :(x[23])]][:lifted_constr_ref] == :(x[27] == x[20] * x[23]) - @test m.internalModel.nonconvex_terms[Expr[:(x[20]), :(x[23])]][:nonlinear_type] == :INTPROD - @test m.internalModel.nonconvex_terms[Expr[:(x[20]), :(x[23])]][:y_type] == :Int - @test m.internalModel.nonconvex_terms[Expr[:(x[20]), :(x[23])]][:constr_id] == Set(Any[23]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[48])]][:y_idx] == 49 - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[48])]][:id] == 19 - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[48])]][:lifted_constr_ref] == :(x[49] == x[6] * x[48]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[48])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[48])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[48])]][:constr_id] == Set(Any[25]) - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[11])]][:y_idx] == 56 - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[11])]][:id] == 25 - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[11])]][:lifted_constr_ref] == :(x[56] == x[5] * x[11]) - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[11])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[11])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[11])]][:constr_id] == Set(Any[27]) - @test m.internalModel.nonconvex_terms[Expr[:(x[11]), :(x[11])]][:y_idx] == 42 - @test m.internalModel.nonconvex_terms[Expr[:(x[11]), :(x[11])]][:id] == 13 - @test m.internalModel.nonconvex_terms[Expr[:(x[11]), :(x[11])]][:lifted_constr_ref] == :(x[42] == (*)(x[11])) - @test m.internalModel.nonconvex_terms[Expr[:(x[11]), :(x[11])]][:nonlinear_type] == :MONOMIAL - @test m.internalModel.nonconvex_terms[Expr[:(x[11]), :(x[11])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[11]), :(x[11])]][:constr_id] == Set(Any[27, 24]) - @test m.internalModel.nonconvex_terms[Expr[:(x[38]), :(x[38]), :(x[38])]][:y_idx] == 39 - @test m.internalModel.nonconvex_terms[Expr[:(x[38]), :(x[38]), :(x[38])]][:id] == 10 - @test m.internalModel.nonconvex_terms[Expr[:(x[38]), :(x[38]), :(x[38])]][:lifted_constr_ref] == :(x[39] == (*)(x[38])) - @test m.internalModel.nonconvex_terms[Expr[:(x[38]), :(x[38]), :(x[38])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[38]), :(x[38]), :(x[38])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[38]), :(x[38]), :(x[38])]][:constr_id] == Set(Any[24]) - @test m.internalModel.nonconvex_terms[Expr[:(x[7]), :(x[13])]][:y_idx] == 58 - @test m.internalModel.nonconvex_terms[Expr[:(x[7]), :(x[13])]][:id] == 27 - @test m.internalModel.nonconvex_terms[Expr[:(x[7]), :(x[13])]][:lifted_constr_ref] == :(x[58] == x[7] * x[13]) - @test m.internalModel.nonconvex_terms[Expr[:(x[7]), :(x[13])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[7]), :(x[13])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[7]), :(x[13])]][:constr_id] == Set(Any[29]) - @test m.internalModel.nonconvex_terms[Expr[:(x[12]), :(x[12])]][:y_idx] == 48 - @test m.internalModel.nonconvex_terms[Expr[:(x[12]), :(x[12])]][:id] == 18 - @test m.internalModel.nonconvex_terms[Expr[:(x[12]), :(x[12])]][:lifted_constr_ref] == :(x[48] == (*)(x[12])) - @test m.internalModel.nonconvex_terms[Expr[:(x[12]), :(x[12])]][:nonlinear_type] == :MONOMIAL - @test m.internalModel.nonconvex_terms[Expr[:(x[12]), :(x[12])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[12]), :(x[12])]][:constr_id] == Set(Any[25, 28]) - @test m.internalModel.nonconvex_terms[Expr[:(x[20]), :(x[11])]][:y_idx] == 59 - @test m.internalModel.nonconvex_terms[Expr[:(x[20]), :(x[11])]][:id] == 28 - @test m.internalModel.nonconvex_terms[Expr[:(x[20]), :(x[11])]][:lifted_constr_ref] == :(x[59] == x[20] * x[11]) - @test m.internalModel.nonconvex_terms[Expr[:(x[20]), :(x[11])]][:nonlinear_type] == :INTLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[20]), :(x[11])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[20]), :(x[11])]][:constr_id] == Set(Any[30]) - @test m.internalModel.nonconvex_terms[Expr[:(x[11]), :(x[40])]][:y_idx] == 41 - @test m.internalModel.nonconvex_terms[Expr[:(x[11]), :(x[40])]][:id] == 12 - @test m.internalModel.nonconvex_terms[Expr[:(x[11]), :(x[40])]][:lifted_constr_ref] == :(x[41] == x[11] * x[40]) - @test m.internalModel.nonconvex_terms[Expr[:(x[11]), :(x[40])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[11]), :(x[40])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[11]), :(x[40])]][:constr_id] == Set(Any[24]) - @test m.internalModel.nonconvex_terms[Expr[:(x[22]), :(x[25])]][:y_idx] == 35 - @test m.internalModel.nonconvex_terms[Expr[:(x[22]), :(x[25])]][:id] == 7 - @test m.internalModel.nonconvex_terms[Expr[:(x[22]), :(x[25])]][:lifted_constr_ref] == :(x[35] == x[22] * x[25]) - @test m.internalModel.nonconvex_terms[Expr[:(x[22]), :(x[25])]][:nonlinear_type] == :INTPROD - @test m.internalModel.nonconvex_terms[Expr[:(x[22]), :(x[25])]][:y_type] == :Int - @test m.internalModel.nonconvex_terms[Expr[:(x[22]), :(x[25])]][:constr_id] == Set(Any[23]) - @test m.internalModel.nonconvex_terms[Expr[:(x[17]), :(x[28])]][:y_idx] == 29 - @test m.internalModel.nonconvex_terms[Expr[:(x[17]), :(x[28])]][:id] == 3 - @test m.internalModel.nonconvex_terms[Expr[:(x[17]), :(x[28])]][:lifted_constr_ref] == :(x[29] == x[17] * x[28]) - @test m.internalModel.nonconvex_terms[Expr[:(x[17]), :(x[28])]][:nonlinear_type] == :BINLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[17]), :(x[28])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[17]), :(x[28])]][:constr_id] == Set(Any[23]) - @test m.internalModel.nonconvex_terms[Expr[:(x[18]), :(x[32])]][:y_idx] == 33 - @test m.internalModel.nonconvex_terms[Expr[:(x[18]), :(x[32])]][:id] == 6 - @test m.internalModel.nonconvex_terms[Expr[:(x[18]), :(x[32])]][:lifted_constr_ref] == :(x[33] == x[18] * x[32]) - @test m.internalModel.nonconvex_terms[Expr[:(x[18]), :(x[32])]][:nonlinear_type] == :BINLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[18]), :(x[32])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[18]), :(x[32])]][:constr_id] == Set(Any[23]) - @test m.internalModel.nonconvex_terms[Expr[:(x[50]), :(x[50])]][:y_idx] == 52 - @test m.internalModel.nonconvex_terms[Expr[:(x[50]), :(x[50])]][:id] == 21 - @test m.internalModel.nonconvex_terms[Expr[:(x[50]), :(x[50])]][:lifted_constr_ref] == :(x[52] == (*)(x[50])) - @test m.internalModel.nonconvex_terms[Expr[:(x[50]), :(x[50])]][:nonlinear_type] == :MONOMIAL - @test m.internalModel.nonconvex_terms[Expr[:(x[50]), :(x[50])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[50]), :(x[50])]][:constr_id] == Set(Any[26, 29]) - @test m.internalModel.nonconvex_terms[Expr[:(x[22]), :(x[13])]][:y_idx] == 61 - @test m.internalModel.nonconvex_terms[Expr[:(x[22]), :(x[13])]][:id] == 30 - @test m.internalModel.nonconvex_terms[Expr[:(x[22]), :(x[13])]][:lifted_constr_ref] == :(x[61] == x[22] * x[13]) - @test m.internalModel.nonconvex_terms[Expr[:(x[22]), :(x[13])]][:nonlinear_type] == :INTLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[22]), :(x[13])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[22]), :(x[13])]][:constr_id] == Set(Any[32]) - @test m.internalModel.nonconvex_terms[Expr[:(x[27]), :(x[26])]][:y_idx] == 28 - @test m.internalModel.nonconvex_terms[Expr[:(x[27]), :(x[26])]][:id] == 2 - @test m.internalModel.nonconvex_terms[Expr[:(x[27]), :(x[26])]][:lifted_constr_ref] == :(x[28] == x[27] * x[26]) - @test m.internalModel.nonconvex_terms[Expr[:(x[27]), :(x[26])]][:nonlinear_type] == :INTLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[27]), :(x[26])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[27]), :(x[26])]][:constr_id] == Set(Any[23]) - @test m.internalModel.nonconvex_terms[Expr[:(x[7]), :(x[54])]][:y_idx] == 55 - @test m.internalModel.nonconvex_terms[Expr[:(x[7]), :(x[54])]][:id] == 24 - @test m.internalModel.nonconvex_terms[Expr[:(x[7]), :(x[54])]][:lifted_constr_ref] == :(x[55] == x[7] * x[54]) - @test m.internalModel.nonconvex_terms[Expr[:(x[7]), :(x[54])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[7]), :(x[54])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[7]), :(x[54])]][:constr_id] == Set(Any[26]) - @test m.internalModel.nonconvex_terms[Expr[:(x[44]), :(x[44]), :(x[44])]][:y_idx] == 45 - @test m.internalModel.nonconvex_terms[Expr[:(x[44]), :(x[44]), :(x[44])]][:id] == 15 - @test m.internalModel.nonconvex_terms[Expr[:(x[44]), :(x[44]), :(x[44])]][:lifted_constr_ref] == :(x[45] == (*)(x[44])) - @test m.internalModel.nonconvex_terms[Expr[:(x[44]), :(x[44]), :(x[44])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[44]), :(x[44]), :(x[44])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[44]), :(x[44]), :(x[44])]][:constr_id] == Set(Any[25]) - @test m.internalModel.nonconvex_terms[Expr[:(x[21]), :(x[24])]][:y_idx] == 31 - @test m.internalModel.nonconvex_terms[Expr[:(x[21]), :(x[24])]][:id] == 4 - @test m.internalModel.nonconvex_terms[Expr[:(x[21]), :(x[24])]][:lifted_constr_ref] == :(x[31] == x[21] * x[24]) - @test m.internalModel.nonconvex_terms[Expr[:(x[21]), :(x[24])]][:nonlinear_type] == :INTPROD - @test m.internalModel.nonconvex_terms[Expr[:(x[21]), :(x[24])]][:y_type] == :Int - @test m.internalModel.nonconvex_terms[Expr[:(x[21]), :(x[24])]][:constr_id] == Set(Any[23]) - @test m.internalModel.nonconvex_terms[Expr[:(x[23]), :(x[8])]][:y_idx] == 62 - @test m.internalModel.nonconvex_terms[Expr[:(x[23]), :(x[8])]][:id] == 31 - @test m.internalModel.nonconvex_terms[Expr[:(x[23]), :(x[8])]][:lifted_constr_ref] == :(x[62] == x[23] * x[8]) - @test m.internalModel.nonconvex_terms[Expr[:(x[23]), :(x[8])]][:nonlinear_type] == :INTLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[23]), :(x[8])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[23]), :(x[8])]][:constr_id] == Set(Any[33]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[12])]][:y_idx] == 57 - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[12])]][:id] == 26 - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[12])]][:lifted_constr_ref] == :(x[57] == x[6] * x[12]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[12])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[12])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[12])]][:constr_id] == Set(Any[28]) - @test m.internalModel.nonconvex_terms[Expr[:(x[12]), :(x[46])]][:y_idx] == 47 - @test m.internalModel.nonconvex_terms[Expr[:(x[12]), :(x[46])]][:id] == 17 - @test m.internalModel.nonconvex_terms[Expr[:(x[12]), :(x[46])]][:lifted_constr_ref] == :(x[47] == x[12] * x[46]) - @test m.internalModel.nonconvex_terms[Expr[:(x[12]), :(x[46])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[12]), :(x[46])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[12]), :(x[46])]][:constr_id] == Set(Any[25]) - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[42])]][:y_idx] == 43 - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[42])]][:id] == 14 - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[42])]][:lifted_constr_ref] == :(x[43] == x[5] * x[42]) - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[42])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[42])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[42])]][:constr_id] == Set(Any[24]) - @test m.internalModel.nonconvex_terms[Expr[:(x[13]), :(x[13])]][:y_idx] == 54 - @test m.internalModel.nonconvex_terms[Expr[:(x[13]), :(x[13])]][:id] == 23 - @test m.internalModel.nonconvex_terms[Expr[:(x[13]), :(x[13])]][:lifted_constr_ref] == :(x[54] == (*)(x[13])) - @test m.internalModel.nonconvex_terms[Expr[:(x[13]), :(x[13])]][:nonlinear_type] == :MONOMIAL - @test m.internalModel.nonconvex_terms[Expr[:(x[13]), :(x[13])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[13]), :(x[13])]][:constr_id] == Set(Any[26, 29]) - @test m.internalModel.nonconvex_terms[Expr[:(x[21]), :(x[12])]][:y_idx] == 60 - @test m.internalModel.nonconvex_terms[Expr[:(x[21]), :(x[12])]][:id] == 29 - @test m.internalModel.nonconvex_terms[Expr[:(x[21]), :(x[12])]][:lifted_constr_ref] == :(x[60] == x[21] * x[12]) - @test m.internalModel.nonconvex_terms[Expr[:(x[21]), :(x[12])]][:nonlinear_type] == :INTLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[21]), :(x[12])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[21]), :(x[12])]][:constr_id] == Set(Any[31]) - @test m.internalModel.nonconvex_terms[Expr[:(x[24]), :(x[9])]][:y_idx] == 63 - @test m.internalModel.nonconvex_terms[Expr[:(x[24]), :(x[9])]][:id] == 32 - @test m.internalModel.nonconvex_terms[Expr[:(x[24]), :(x[9])]][:lifted_constr_ref] == :(x[63] == x[24] * x[9]) - @test m.internalModel.nonconvex_terms[Expr[:(x[24]), :(x[9])]][:nonlinear_type] == :INTLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[24]), :(x[9])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[24]), :(x[9])]][:constr_id] == Set(Any[34]) - @test m.internalModel.nonconvex_terms[Expr[:(x[31]), :(x[30])]][:y_idx] == 32 - @test m.internalModel.nonconvex_terms[Expr[:(x[31]), :(x[30])]][:id] == 5 - @test m.internalModel.nonconvex_terms[Expr[:(x[31]), :(x[30])]][:lifted_constr_ref] == :(x[32] == x[31] * x[30]) - @test m.internalModel.nonconvex_terms[Expr[:(x[31]), :(x[30])]][:nonlinear_type] == :INTLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[31]), :(x[30])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[31]), :(x[30])]][:constr_id] == Set(Any[23]) - @test m.internalModel.nonconvex_terms[Expr[:(x[50]), :(x[50]), :(x[50])]][:y_idx] == 51 - @test m.internalModel.nonconvex_terms[Expr[:(x[50]), :(x[50]), :(x[50])]][:id] == 20 - @test m.internalModel.nonconvex_terms[Expr[:(x[50]), :(x[50]), :(x[50])]][:lifted_constr_ref] == :(x[51] == (*)(x[50])) - @test m.internalModel.nonconvex_terms[Expr[:(x[50]), :(x[50]), :(x[50])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[50]), :(x[50]), :(x[50])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[50]), :(x[50]), :(x[50])]][:constr_id] == Set(Any[26]) - @test m.internalModel.bounding_constr_mip[1][:rhs] == 1.0 - @test m.internalModel.bounding_constr_mip[1][:vars] == Any[:(x[14]), :(x[15]), :(x[16])] - @test isapprox(m.internalModel.bounding_constr_mip[1][:coefs],Any[1.0, 1.0, 1.0];atol=1e-3) - @test m.internalModel.bounding_constr_mip[1][:sense] == :(==) - @test m.internalModel.bounding_constr_mip[1][:cnt] == 3 - @test m.internalModel.bounding_constr_mip[2][:rhs] == -0.0 - @test m.internalModel.bounding_constr_mip[2][:vars] == Any[:(x[5]), :(x[17])] - @test isapprox(m.internalModel.bounding_constr_mip[2][:coefs],Any[0.000338983, -1.0];atol=1e-3) - @test m.internalModel.bounding_constr_mip[2][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[2][:cnt] == 2 - @test m.internalModel.bounding_constr_mip[3][:rhs] == -0.0 - @test m.internalModel.bounding_constr_mip[3][:vars] == Any[:(x[6]), :(x[18])] - @test isapprox(m.internalModel.bounding_constr_mip[3][:coefs],Any[0.000338983, -1.0];atol=1e-3) - @test m.internalModel.bounding_constr_mip[3][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[3][:cnt] == 2 - @test m.internalModel.bounding_constr_mip[4][:rhs] == -0.0 - @test m.internalModel.bounding_constr_mip[4][:vars] == Any[:(x[7]), :(x[19])] - @test isapprox(m.internalModel.bounding_constr_mip[4][:coefs],Any[0.000338983, -1.0];atol=1e-3) - @test m.internalModel.bounding_constr_mip[4][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[4][:cnt] == 2 - @test m.internalModel.bounding_constr_mip[5][:rhs] == -0.0 - @test m.internalModel.bounding_constr_mip[5][:vars] == Any[:(x[2]), :(x[17])] - @test isapprox(m.internalModel.bounding_constr_mip[5][:coefs],Any[0.0125, -1.0];atol=1e-3) - @test m.internalModel.bounding_constr_mip[5][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[5][:cnt] == 2 - @test m.internalModel.bounding_constr_mip[6][:rhs] == -0.0 - @test m.internalModel.bounding_constr_mip[6][:vars] == Any[:(x[3]), :(x[18])] - @test isapprox(m.internalModel.bounding_constr_mip[6][:coefs],Any[0.04, -1.0];atol=1e-3) - @test m.internalModel.bounding_constr_mip[6][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[6][:cnt] == 2 - @test m.internalModel.bounding_constr_mip[7][:rhs] == -0.0 - @test m.internalModel.bounding_constr_mip[7][:vars] == Any[:(x[4]), :(x[19])] - @test isapprox(m.internalModel.bounding_constr_mip[7][:coefs],Any[0.0222222, -1.0];atol=1e-3) - @test m.internalModel.bounding_constr_mip[7][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[7][:cnt] == 2 - @test m.internalModel.bounding_constr_mip[8][:rhs] == -0.0 - @test m.internalModel.bounding_constr_mip[8][:vars] == Any[:(x[8]), :(x[17])] - @test isapprox(m.internalModel.bounding_constr_mip[8][:coefs],Any[0.0025, -1.0];atol=1e-3) - @test m.internalModel.bounding_constr_mip[8][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[8][:cnt] == 2 - @test m.internalModel.bounding_constr_mip[9][:rhs] == -0.0 - @test m.internalModel.bounding_constr_mip[9][:vars] == Any[:(x[9]), :(x[18])] - @test isapprox(m.internalModel.bounding_constr_mip[9][:coefs],Any[0.0025, -1.0];atol=1e-3) - @test m.internalModel.bounding_constr_mip[9][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[9][:cnt] == 2 - @test m.internalModel.bounding_constr_mip[10][:rhs] == -0.0 - @test m.internalModel.bounding_constr_mip[10][:vars] == Any[:(x[10]), :(x[19])] - @test isapprox(m.internalModel.bounding_constr_mip[10][:coefs],Any[0.0025, -1.0];atol=1e-3) - @test m.internalModel.bounding_constr_mip[10][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[10][:cnt] == 2 - @test m.internalModel.bounding_constr_mip[11][:rhs] == -0.0 - @test m.internalModel.bounding_constr_mip[11][:vars] == Any[:(x[11]), :(x[17])] - @test isapprox(m.internalModel.bounding_constr_mip[11][:coefs],Any[0.00285714, -1.0];atol=1e-3) - @test m.internalModel.bounding_constr_mip[11][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[11][:cnt] == 2 - @test m.internalModel.bounding_constr_mip[12][:rhs] == -0.0 - @test m.internalModel.bounding_constr_mip[12][:vars] == Any[:(x[12]), :(x[18])] - @test isapprox(m.internalModel.bounding_constr_mip[12][:coefs],Any[0.00285714, -1.0];atol=1e-3) - @test m.internalModel.bounding_constr_mip[12][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[12][:cnt] == 2 - @test m.internalModel.bounding_constr_mip[13][:rhs] == -0.0 - @test m.internalModel.bounding_constr_mip[13][:vars] == Any[:(x[13]), :(x[19])] - @test isapprox(m.internalModel.bounding_constr_mip[13][:coefs],Any[0.00285714, -1.0];atol=1e-3) - @test m.internalModel.bounding_constr_mip[13][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[13][:cnt] == 2 - @test m.internalModel.bounding_constr_mip[14][:rhs] == -0.0 - @test m.internalModel.bounding_constr_mip[14][:vars] == Any[:(x[14]), :(x[17])] - @test isapprox(m.internalModel.bounding_constr_mip[14][:coefs],Any[1.0, -1.0];atol=1e-3) - @test m.internalModel.bounding_constr_mip[14][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[14][:cnt] == 2 - @test m.internalModel.bounding_constr_mip[15][:rhs] == -0.0 - @test m.internalModel.bounding_constr_mip[15][:vars] == Any[:(x[15]), :(x[18])] - @test isapprox(m.internalModel.bounding_constr_mip[15][:coefs],Any[1.0, -1.0];atol=1e-3) - @test m.internalModel.bounding_constr_mip[15][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[15][:cnt] == 2 - @test m.internalModel.bounding_constr_mip[16][:rhs] == -0.0 - @test m.internalModel.bounding_constr_mip[16][:vars] == Any[:(x[16]), :(x[19])] - @test isapprox(m.internalModel.bounding_constr_mip[16][:coefs],Any[1.0, -1.0];atol=1e-3) - @test m.internalModel.bounding_constr_mip[16][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[16][:cnt] == 2 - @test m.internalModel.bounding_constr_mip[17][:rhs] == -0.0 - @test m.internalModel.bounding_constr_mip[17][:vars] == Any[:(x[20]), :(x[17])] - @test isapprox(m.internalModel.bounding_constr_mip[17][:coefs],Any[1.0, -3.0];atol=1e-3) - @test m.internalModel.bounding_constr_mip[17][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[17][:cnt] == 2 - @test m.internalModel.bounding_constr_mip[18][:rhs] == -0.0 - @test m.internalModel.bounding_constr_mip[18][:vars] == Any[:(x[21]), :(x[18])] - @test isapprox(m.internalModel.bounding_constr_mip[18][:coefs],Any[1.0, -3.0];atol=1e-3) - @test m.internalModel.bounding_constr_mip[18][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[18][:cnt] == 2 - @test m.internalModel.bounding_constr_mip[19][:rhs] == -0.0 - @test m.internalModel.bounding_constr_mip[19][:vars] == Any[:(x[22]), :(x[19])] - @test isapprox(m.internalModel.bounding_constr_mip[19][:coefs],Any[1.0, -3.0];atol=1e-3) - @test m.internalModel.bounding_constr_mip[19][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[19][:cnt] == 2 - @test m.internalModel.bounding_constr_mip[20][:rhs] == -0.0 - @test m.internalModel.bounding_constr_mip[20][:vars] == Any[:(x[23]), :(x[17])] - @test isapprox(m.internalModel.bounding_constr_mip[20][:coefs],Any[1.0, -3.0];atol=1e-3) - @test m.internalModel.bounding_constr_mip[20][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[20][:cnt] == 2 - @test m.internalModel.bounding_constr_mip[21][:rhs] == -0.0 - @test m.internalModel.bounding_constr_mip[21][:vars] == Any[:(x[24]), :(x[18])] - @test isapprox(m.internalModel.bounding_constr_mip[21][:coefs],Any[1.0, -3.0];atol=1e-3) - @test m.internalModel.bounding_constr_mip[21][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[21][:cnt] == 2 - @test m.internalModel.bounding_constr_mip[22][:rhs] == -0.0 - @test m.internalModel.bounding_constr_mip[22][:vars] == Any[:(x[25]), :(x[19])] - @test isapprox(m.internalModel.bounding_constr_mip[22][:coefs],Any[1.0, -3.0];atol=1e-3) - @test m.internalModel.bounding_constr_mip[22][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[22][:cnt] == 2 - @test m.internalModel.bounding_constr_mip[23][:rhs] == 0.0 - @test m.internalModel.bounding_constr_mip[23][:vars] == Any[:(x[29]), :(x[33]), :(x[37]), :(x[1])] - @test isapprox(m.internalModel.bounding_constr_mip[23][:coefs],Any[-1.0, -1.0, -1.0, 1.0];atol=1e-3) - @test m.internalModel.bounding_constr_mip[23][:sense] == :(==) - @test m.internalModel.bounding_constr_mip[23][:cnt] == 4 - @test m.internalModel.bounding_constr_mip[24][:rhs] == 0.0 - @test m.internalModel.bounding_constr_mip[24][:vars] == Any[:(x[39]), :(x[41]), :(x[43]), :(x[2])] - @test isapprox(m.internalModel.bounding_constr_mip[24][:coefs],Any[-19.9, -0.161, 1.90169e-7, 1.0];atol=1e-3) - @test m.internalModel.bounding_constr_mip[24][:sense] == :(==) - @test m.internalModel.bounding_constr_mip[24][:cnt] == 4 - @test m.internalModel.bounding_constr_mip[25][:rhs] == 0.0 - @test m.internalModel.bounding_constr_mip[25][:vars] == Any[:(x[45]), :(x[47]), :(x[49]), :(x[3])] - @test isapprox(m.internalModel.bounding_constr_mip[25][:coefs],Any[-1.21, -0.0644, 1.91186e-7, 1.0];atol=1e-3) - @test m.internalModel.bounding_constr_mip[25][:sense] == :(==) - @test m.internalModel.bounding_constr_mip[25][:cnt] == 4 - @test m.internalModel.bounding_constr_mip[26][:rhs] == 0.0 - @test m.internalModel.bounding_constr_mip[26][:vars] == Any[:(x[51]), :(x[53]), :(x[55]), :(x[4])] - @test isapprox(m.internalModel.bounding_constr_mip[26][:coefs],Any[-6.52, -0.102, 7.86441e-8, 1.0];atol=1e-3) - @test m.internalModel.bounding_constr_mip[26][:sense] == :(==) - @test m.internalModel.bounding_constr_mip[26][:cnt] == 4 - @test m.internalModel.bounding_constr_mip[27][:rhs] == 0.0 - @test m.internalModel.bounding_constr_mip[27][:vars] == Any[:(x[56]), :(x[40]), :(x[42]), :(x[8])] - @test isapprox(m.internalModel.bounding_constr_mip[27][:coefs],Any[-0.000235932, -629.0, 0.0116, 1.0];atol=1e-3) - @test m.internalModel.bounding_constr_mip[27][:sense] == :(==) - @test m.internalModel.bounding_constr_mip[27][:cnt] == 4 - @test m.internalModel.bounding_constr_mip[28][:rhs] == 0.0 - @test m.internalModel.bounding_constr_mip[28][:vars] == Any[:(x[57]), :(x[46]), :(x[48]), :(x[9])] - @test isapprox(m.internalModel.bounding_constr_mip[28][:coefs],Any[-0.001, -215.0, 0.115, 1.0];atol=1e-3) - @test m.internalModel.bounding_constr_mip[28][:sense] == :(==) - @test m.internalModel.bounding_constr_mip[28][:cnt] == 4 - @test m.internalModel.bounding_constr_mip[29][:rhs] == 0.0 - @test m.internalModel.bounding_constr_mip[29][:vars] == Any[:(x[58]), :(x[52]), :(x[54]), :(x[10])] - @test isapprox(m.internalModel.bounding_constr_mip[29][:coefs],Any[-0.000179661, -361.0, 0.00946, 1.0];atol=1e-3) - @test m.internalModel.bounding_constr_mip[29][:sense] == :(==) - @test m.internalModel.bounding_constr_mip[29][:cnt] == 4 - @test m.internalModel.bounding_constr_mip[30][:rhs] == 0.0 - @test m.internalModel.bounding_constr_mip[30][:vars] == Any[:(x[59]), :(x[14])] - @test isapprox(m.internalModel.bounding_constr_mip[30][:coefs],Any[0.00285714, -1.0];atol=1e-3) - @test m.internalModel.bounding_constr_mip[30][:sense] == :(==) - @test m.internalModel.bounding_constr_mip[30][:cnt] == 2 - @test m.internalModel.bounding_constr_mip[31][:rhs] == 0.0 - @test m.internalModel.bounding_constr_mip[31][:vars] == Any[:(x[60]), :(x[15])] - @test isapprox(m.internalModel.bounding_constr_mip[31][:coefs],Any[0.00285714, -1.0];atol=1e-3) - @test m.internalModel.bounding_constr_mip[31][:sense] == :(==) - @test m.internalModel.bounding_constr_mip[31][:cnt] == 2 - @test m.internalModel.bounding_constr_mip[32][:rhs] == 0.0 - @test m.internalModel.bounding_constr_mip[32][:vars] == Any[:(x[61]), :(x[16])] - @test isapprox(m.internalModel.bounding_constr_mip[32][:coefs],Any[0.00285714, -1.0];atol=1e-3) - @test m.internalModel.bounding_constr_mip[32][:sense] == :(==) - @test m.internalModel.bounding_constr_mip[32][:cnt] == 2 - @test m.internalModel.bounding_constr_mip[33][:rhs] == 0.0 - @test m.internalModel.bounding_constr_mip[33][:vars] == Any[:(x[62]), :(x[17])] - @test isapprox(m.internalModel.bounding_constr_mip[33][:coefs],Any[0.0025, -1.0];atol=1e-3) - @test m.internalModel.bounding_constr_mip[33][:sense] == :(==) - @test m.internalModel.bounding_constr_mip[33][:cnt] == 2 - @test m.internalModel.bounding_constr_mip[34][:rhs] == 0.0 - @test m.internalModel.bounding_constr_mip[34][:vars] == Any[:(x[63]), :(x[18])] - @test isapprox(m.internalModel.bounding_constr_mip[34][:coefs],Any[0.0025, -1.0];atol=1e-3) - @test m.internalModel.bounding_constr_mip[34][:sense] == :(==) - @test m.internalModel.bounding_constr_mip[34][:cnt] == 2 - @test m.internalModel.bounding_constr_mip[35][:rhs] == 0.0 - @test m.internalModel.bounding_constr_mip[35][:vars] == Any[:(x[64]), :(x[19])] - @test isapprox(m.internalModel.bounding_constr_mip[35][:coefs],Any[0.0025, -1.0];atol=1e-3) - @test m.internalModel.bounding_constr_mip[35][:sense] == :(==) - @test m.internalModel.bounding_constr_mip[35][:cnt] == 2 + alpine = _build(m) + + @test alpine.nonconvex_terms[Expr[:(x[44]), :(x[44])]][:y_idx] == 46 + @test alpine.nonconvex_terms[Expr[:(x[44]), :(x[44])]][:id] == 16 + @test alpine.nonconvex_terms[Expr[:(x[44]), :(x[44])]][:lifted_constr_ref] == :(x[46] == (*)(x[44])) + @test alpine.nonconvex_terms[Expr[:(x[44]), :(x[44])]][:nonlinear_type] == :MONOMIAL + @test alpine.nonconvex_terms[Expr[:(x[44]), :(x[44])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[44]), :(x[44])]][:constr_id] == Set(Any[25, 28]) + @test alpine.nonconvex_terms[Expr[:(x[13]), :(x[52])]][:y_idx] == 53 + @test alpine.nonconvex_terms[Expr[:(x[13]), :(x[52])]][:id] == 22 + @test alpine.nonconvex_terms[Expr[:(x[13]), :(x[52])]][:lifted_constr_ref] == :(x[53] == x[13] * x[52]) + @test alpine.nonconvex_terms[Expr[:(x[13]), :(x[52])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[13]), :(x[52])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[13]), :(x[52])]][:constr_id] == Set(Any[26]) + @test alpine.nonconvex_terms[Expr[:(x[25]), :(x[10])]][:y_idx] == 64 + @test alpine.nonconvex_terms[Expr[:(x[25]), :(x[10])]][:id] == 33 + @test alpine.nonconvex_terms[Expr[:(x[25]), :(x[10])]][:lifted_constr_ref] == :(x[64] == x[25] * x[10]) + @test alpine.nonconvex_terms[Expr[:(x[25]), :(x[10])]][:nonlinear_type] == :INTLIN + @test alpine.nonconvex_terms[Expr[:(x[25]), :(x[10])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[25]), :(x[10])]][:constr_id] == Set(Any[35]) + @test alpine.nonconvex_terms[Expr[:(x[19]), :(x[36])]][:y_idx] == 37 + @test alpine.nonconvex_terms[Expr[:(x[19]), :(x[36])]][:id] == 9 + @test alpine.nonconvex_terms[Expr[:(x[19]), :(x[36])]][:lifted_constr_ref] == :(x[37] == x[19] * x[36]) + @test alpine.nonconvex_terms[Expr[:(x[19]), :(x[36])]][:nonlinear_type] == :BINLIN + @test alpine.nonconvex_terms[Expr[:(x[19]), :(x[36])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[19]), :(x[36])]][:constr_id] == Set(Any[23]) + @test alpine.nonconvex_terms[Expr[:(x[38]), :(x[38])]][:y_idx] == 40 + @test alpine.nonconvex_terms[Expr[:(x[38]), :(x[38])]][:id] == 11 + @test alpine.nonconvex_terms[Expr[:(x[38]), :(x[38])]][:lifted_constr_ref] == :(x[40] == (*)(x[38])) + @test alpine.nonconvex_terms[Expr[:(x[38]), :(x[38])]][:nonlinear_type] == :MONOMIAL + @test alpine.nonconvex_terms[Expr[:(x[38]), :(x[38])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[38]), :(x[38])]][:constr_id] == Set(Any[27, 24]) + @test alpine.nonconvex_terms[Expr[:(x[35]), :(x[34])]][:y_idx] == 36 + @test alpine.nonconvex_terms[Expr[:(x[35]), :(x[34])]][:id] == 8 + @test alpine.nonconvex_terms[Expr[:(x[35]), :(x[34])]][:lifted_constr_ref] == :(x[36] == x[35] * x[34]) + @test alpine.nonconvex_terms[Expr[:(x[35]), :(x[34])]][:nonlinear_type] == :INTLIN + @test alpine.nonconvex_terms[Expr[:(x[35]), :(x[34])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[35]), :(x[34])]][:constr_id] == Set(Any[23]) + @test alpine.nonconvex_terms[Expr[:(x[20]), :(x[23])]][:y_idx] == 27 + @test alpine.nonconvex_terms[Expr[:(x[20]), :(x[23])]][:id] == 1 + @test alpine.nonconvex_terms[Expr[:(x[20]), :(x[23])]][:lifted_constr_ref] == :(x[27] == x[20] * x[23]) + @test alpine.nonconvex_terms[Expr[:(x[20]), :(x[23])]][:nonlinear_type] == :INTPROD + @test alpine.nonconvex_terms[Expr[:(x[20]), :(x[23])]][:y_type] == :Int + @test alpine.nonconvex_terms[Expr[:(x[20]), :(x[23])]][:constr_id] == Set(Any[23]) + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[48])]][:y_idx] == 49 + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[48])]][:id] == 19 + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[48])]][:lifted_constr_ref] == :(x[49] == x[6] * x[48]) + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[48])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[48])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[48])]][:constr_id] == Set(Any[25]) + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[11])]][:y_idx] == 56 + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[11])]][:id] == 25 + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[11])]][:lifted_constr_ref] == :(x[56] == x[5] * x[11]) + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[11])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[11])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[11])]][:constr_id] == Set(Any[27]) + @test alpine.nonconvex_terms[Expr[:(x[11]), :(x[11])]][:y_idx] == 42 + @test alpine.nonconvex_terms[Expr[:(x[11]), :(x[11])]][:id] == 13 + @test alpine.nonconvex_terms[Expr[:(x[11]), :(x[11])]][:lifted_constr_ref] == :(x[42] == (*)(x[11])) + @test alpine.nonconvex_terms[Expr[:(x[11]), :(x[11])]][:nonlinear_type] == :MONOMIAL + @test alpine.nonconvex_terms[Expr[:(x[11]), :(x[11])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[11]), :(x[11])]][:constr_id] == Set(Any[27, 24]) + @test alpine.nonconvex_terms[Expr[:(x[38]), :(x[38]), :(x[38])]][:y_idx] == 39 + @test alpine.nonconvex_terms[Expr[:(x[38]), :(x[38]), :(x[38])]][:id] == 10 + @test alpine.nonconvex_terms[Expr[:(x[38]), :(x[38]), :(x[38])]][:lifted_constr_ref] == :(x[39] == (*)(x[38])) + @test alpine.nonconvex_terms[Expr[:(x[38]), :(x[38]), :(x[38])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[38]), :(x[38]), :(x[38])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[38]), :(x[38]), :(x[38])]][:constr_id] == Set(Any[24]) + @test alpine.nonconvex_terms[Expr[:(x[7]), :(x[13])]][:y_idx] == 58 + @test alpine.nonconvex_terms[Expr[:(x[7]), :(x[13])]][:id] == 27 + @test alpine.nonconvex_terms[Expr[:(x[7]), :(x[13])]][:lifted_constr_ref] == :(x[58] == x[7] * x[13]) + @test alpine.nonconvex_terms[Expr[:(x[7]), :(x[13])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[7]), :(x[13])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[7]), :(x[13])]][:constr_id] == Set(Any[29]) + @test alpine.nonconvex_terms[Expr[:(x[12]), :(x[12])]][:y_idx] == 48 + @test alpine.nonconvex_terms[Expr[:(x[12]), :(x[12])]][:id] == 18 + @test alpine.nonconvex_terms[Expr[:(x[12]), :(x[12])]][:lifted_constr_ref] == :(x[48] == (*)(x[12])) + @test alpine.nonconvex_terms[Expr[:(x[12]), :(x[12])]][:nonlinear_type] == :MONOMIAL + @test alpine.nonconvex_terms[Expr[:(x[12]), :(x[12])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[12]), :(x[12])]][:constr_id] == Set(Any[25, 28]) + @test alpine.nonconvex_terms[Expr[:(x[20]), :(x[11])]][:y_idx] == 59 + @test alpine.nonconvex_terms[Expr[:(x[20]), :(x[11])]][:id] == 28 + @test alpine.nonconvex_terms[Expr[:(x[20]), :(x[11])]][:lifted_constr_ref] == :(x[59] == x[20] * x[11]) + @test alpine.nonconvex_terms[Expr[:(x[20]), :(x[11])]][:nonlinear_type] == :INTLIN + @test alpine.nonconvex_terms[Expr[:(x[20]), :(x[11])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[20]), :(x[11])]][:constr_id] == Set(Any[30]) + @test alpine.nonconvex_terms[Expr[:(x[11]), :(x[40])]][:y_idx] == 41 + @test alpine.nonconvex_terms[Expr[:(x[11]), :(x[40])]][:id] == 12 + @test alpine.nonconvex_terms[Expr[:(x[11]), :(x[40])]][:lifted_constr_ref] == :(x[41] == x[11] * x[40]) + @test alpine.nonconvex_terms[Expr[:(x[11]), :(x[40])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[11]), :(x[40])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[11]), :(x[40])]][:constr_id] == Set(Any[24]) + @test alpine.nonconvex_terms[Expr[:(x[22]), :(x[25])]][:y_idx] == 35 + @test alpine.nonconvex_terms[Expr[:(x[22]), :(x[25])]][:id] == 7 + @test alpine.nonconvex_terms[Expr[:(x[22]), :(x[25])]][:lifted_constr_ref] == :(x[35] == x[22] * x[25]) + @test alpine.nonconvex_terms[Expr[:(x[22]), :(x[25])]][:nonlinear_type] == :INTPROD + @test alpine.nonconvex_terms[Expr[:(x[22]), :(x[25])]][:y_type] == :Int + @test alpine.nonconvex_terms[Expr[:(x[22]), :(x[25])]][:constr_id] == Set(Any[23]) + @test alpine.nonconvex_terms[Expr[:(x[17]), :(x[28])]][:y_idx] == 29 + @test alpine.nonconvex_terms[Expr[:(x[17]), :(x[28])]][:id] == 3 + @test alpine.nonconvex_terms[Expr[:(x[17]), :(x[28])]][:lifted_constr_ref] == :(x[29] == x[17] * x[28]) + @test alpine.nonconvex_terms[Expr[:(x[17]), :(x[28])]][:nonlinear_type] == :BINLIN + @test alpine.nonconvex_terms[Expr[:(x[17]), :(x[28])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[17]), :(x[28])]][:constr_id] == Set(Any[23]) + @test alpine.nonconvex_terms[Expr[:(x[18]), :(x[32])]][:y_idx] == 33 + @test alpine.nonconvex_terms[Expr[:(x[18]), :(x[32])]][:id] == 6 + @test alpine.nonconvex_terms[Expr[:(x[18]), :(x[32])]][:lifted_constr_ref] == :(x[33] == x[18] * x[32]) + @test alpine.nonconvex_terms[Expr[:(x[18]), :(x[32])]][:nonlinear_type] == :BINLIN + @test alpine.nonconvex_terms[Expr[:(x[18]), :(x[32])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[18]), :(x[32])]][:constr_id] == Set(Any[23]) + @test alpine.nonconvex_terms[Expr[:(x[50]), :(x[50])]][:y_idx] == 52 + @test alpine.nonconvex_terms[Expr[:(x[50]), :(x[50])]][:id] == 21 + @test alpine.nonconvex_terms[Expr[:(x[50]), :(x[50])]][:lifted_constr_ref] == :(x[52] == (*)(x[50])) + @test alpine.nonconvex_terms[Expr[:(x[50]), :(x[50])]][:nonlinear_type] == :MONOMIAL + @test alpine.nonconvex_terms[Expr[:(x[50]), :(x[50])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[50]), :(x[50])]][:constr_id] == Set(Any[26, 29]) + @test alpine.nonconvex_terms[Expr[:(x[22]), :(x[13])]][:y_idx] == 61 + @test alpine.nonconvex_terms[Expr[:(x[22]), :(x[13])]][:id] == 30 + @test alpine.nonconvex_terms[Expr[:(x[22]), :(x[13])]][:lifted_constr_ref] == :(x[61] == x[22] * x[13]) + @test alpine.nonconvex_terms[Expr[:(x[22]), :(x[13])]][:nonlinear_type] == :INTLIN + @test alpine.nonconvex_terms[Expr[:(x[22]), :(x[13])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[22]), :(x[13])]][:constr_id] == Set(Any[32]) + @test alpine.nonconvex_terms[Expr[:(x[27]), :(x[26])]][:y_idx] == 28 + @test alpine.nonconvex_terms[Expr[:(x[27]), :(x[26])]][:id] == 2 + @test alpine.nonconvex_terms[Expr[:(x[27]), :(x[26])]][:lifted_constr_ref] == :(x[28] == x[27] * x[26]) + @test alpine.nonconvex_terms[Expr[:(x[27]), :(x[26])]][:nonlinear_type] == :INTLIN + @test alpine.nonconvex_terms[Expr[:(x[27]), :(x[26])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[27]), :(x[26])]][:constr_id] == Set(Any[23]) + @test alpine.nonconvex_terms[Expr[:(x[7]), :(x[54])]][:y_idx] == 55 + @test alpine.nonconvex_terms[Expr[:(x[7]), :(x[54])]][:id] == 24 + @test alpine.nonconvex_terms[Expr[:(x[7]), :(x[54])]][:lifted_constr_ref] == :(x[55] == x[7] * x[54]) + @test alpine.nonconvex_terms[Expr[:(x[7]), :(x[54])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[7]), :(x[54])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[7]), :(x[54])]][:constr_id] == Set(Any[26]) + @test alpine.nonconvex_terms[Expr[:(x[44]), :(x[44]), :(x[44])]][:y_idx] == 45 + @test alpine.nonconvex_terms[Expr[:(x[44]), :(x[44]), :(x[44])]][:id] == 15 + @test alpine.nonconvex_terms[Expr[:(x[44]), :(x[44]), :(x[44])]][:lifted_constr_ref] == :(x[45] == (*)(x[44])) + @test alpine.nonconvex_terms[Expr[:(x[44]), :(x[44]), :(x[44])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[44]), :(x[44]), :(x[44])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[44]), :(x[44]), :(x[44])]][:constr_id] == Set(Any[25]) + @test alpine.nonconvex_terms[Expr[:(x[21]), :(x[24])]][:y_idx] == 31 + @test alpine.nonconvex_terms[Expr[:(x[21]), :(x[24])]][:id] == 4 + @test alpine.nonconvex_terms[Expr[:(x[21]), :(x[24])]][:lifted_constr_ref] == :(x[31] == x[21] * x[24]) + @test alpine.nonconvex_terms[Expr[:(x[21]), :(x[24])]][:nonlinear_type] == :INTPROD + @test alpine.nonconvex_terms[Expr[:(x[21]), :(x[24])]][:y_type] == :Int + @test alpine.nonconvex_terms[Expr[:(x[21]), :(x[24])]][:constr_id] == Set(Any[23]) + @test alpine.nonconvex_terms[Expr[:(x[23]), :(x[8])]][:y_idx] == 62 + @test alpine.nonconvex_terms[Expr[:(x[23]), :(x[8])]][:id] == 31 + @test alpine.nonconvex_terms[Expr[:(x[23]), :(x[8])]][:lifted_constr_ref] == :(x[62] == x[23] * x[8]) + @test alpine.nonconvex_terms[Expr[:(x[23]), :(x[8])]][:nonlinear_type] == :INTLIN + @test alpine.nonconvex_terms[Expr[:(x[23]), :(x[8])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[23]), :(x[8])]][:constr_id] == Set(Any[33]) + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[12])]][:y_idx] == 57 + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[12])]][:id] == 26 + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[12])]][:lifted_constr_ref] == :(x[57] == x[6] * x[12]) + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[12])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[12])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[12])]][:constr_id] == Set(Any[28]) + @test alpine.nonconvex_terms[Expr[:(x[12]), :(x[46])]][:y_idx] == 47 + @test alpine.nonconvex_terms[Expr[:(x[12]), :(x[46])]][:id] == 17 + @test alpine.nonconvex_terms[Expr[:(x[12]), :(x[46])]][:lifted_constr_ref] == :(x[47] == x[12] * x[46]) + @test alpine.nonconvex_terms[Expr[:(x[12]), :(x[46])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[12]), :(x[46])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[12]), :(x[46])]][:constr_id] == Set(Any[25]) + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[42])]][:y_idx] == 43 + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[42])]][:id] == 14 + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[42])]][:lifted_constr_ref] == :(x[43] == x[5] * x[42]) + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[42])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[42])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[42])]][:constr_id] == Set(Any[24]) + @test alpine.nonconvex_terms[Expr[:(x[13]), :(x[13])]][:y_idx] == 54 + @test alpine.nonconvex_terms[Expr[:(x[13]), :(x[13])]][:id] == 23 + @test alpine.nonconvex_terms[Expr[:(x[13]), :(x[13])]][:lifted_constr_ref] == :(x[54] == (*)(x[13])) + @test alpine.nonconvex_terms[Expr[:(x[13]), :(x[13])]][:nonlinear_type] == :MONOMIAL + @test alpine.nonconvex_terms[Expr[:(x[13]), :(x[13])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[13]), :(x[13])]][:constr_id] == Set(Any[26, 29]) + @test alpine.nonconvex_terms[Expr[:(x[21]), :(x[12])]][:y_idx] == 60 + @test alpine.nonconvex_terms[Expr[:(x[21]), :(x[12])]][:id] == 29 + @test alpine.nonconvex_terms[Expr[:(x[21]), :(x[12])]][:lifted_constr_ref] == :(x[60] == x[21] * x[12]) + @test alpine.nonconvex_terms[Expr[:(x[21]), :(x[12])]][:nonlinear_type] == :INTLIN + @test alpine.nonconvex_terms[Expr[:(x[21]), :(x[12])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[21]), :(x[12])]][:constr_id] == Set(Any[31]) + @test alpine.nonconvex_terms[Expr[:(x[24]), :(x[9])]][:y_idx] == 63 + @test alpine.nonconvex_terms[Expr[:(x[24]), :(x[9])]][:id] == 32 + @test alpine.nonconvex_terms[Expr[:(x[24]), :(x[9])]][:lifted_constr_ref] == :(x[63] == x[24] * x[9]) + @test alpine.nonconvex_terms[Expr[:(x[24]), :(x[9])]][:nonlinear_type] == :INTLIN + @test alpine.nonconvex_terms[Expr[:(x[24]), :(x[9])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[24]), :(x[9])]][:constr_id] == Set(Any[34]) + @test alpine.nonconvex_terms[Expr[:(x[31]), :(x[30])]][:y_idx] == 32 + @test alpine.nonconvex_terms[Expr[:(x[31]), :(x[30])]][:id] == 5 + @test alpine.nonconvex_terms[Expr[:(x[31]), :(x[30])]][:lifted_constr_ref] == :(x[32] == x[31] * x[30]) + @test alpine.nonconvex_terms[Expr[:(x[31]), :(x[30])]][:nonlinear_type] == :INTLIN + @test alpine.nonconvex_terms[Expr[:(x[31]), :(x[30])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[31]), :(x[30])]][:constr_id] == Set(Any[23]) + @test alpine.nonconvex_terms[Expr[:(x[50]), :(x[50]), :(x[50])]][:y_idx] == 51 + @test alpine.nonconvex_terms[Expr[:(x[50]), :(x[50]), :(x[50])]][:id] == 20 + @test alpine.nonconvex_terms[Expr[:(x[50]), :(x[50]), :(x[50])]][:lifted_constr_ref] == :(x[51] == (*)(x[50])) + @test alpine.nonconvex_terms[Expr[:(x[50]), :(x[50]), :(x[50])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[50]), :(x[50]), :(x[50])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[50]), :(x[50]), :(x[50])]][:constr_id] == Set(Any[26]) + @test alpine.bounding_constr_mip[1][:rhs] == 1.0 + @test alpine.bounding_constr_mip[1][:vars] == Any[:(x[14]), :(x[15]), :(x[16])] + @test isapprox(alpine.bounding_constr_mip[1][:coefs],Any[1.0, 1.0, 1.0];atol=1e-3) + @test alpine.bounding_constr_mip[1][:sense] == :(==) + @test alpine.bounding_constr_mip[1][:cnt] == 3 + @test alpine.bounding_constr_mip[2][:rhs] == -0.0 + @test alpine.bounding_constr_mip[2][:vars] == Any[:(x[5]), :(x[17])] + @test isapprox(alpine.bounding_constr_mip[2][:coefs],Any[0.000338983, -1.0];atol=1e-3) + @test alpine.bounding_constr_mip[2][:sense] == :(<=) + @test alpine.bounding_constr_mip[2][:cnt] == 2 + @test alpine.bounding_constr_mip[3][:rhs] == -0.0 + @test alpine.bounding_constr_mip[3][:vars] == Any[:(x[6]), :(x[18])] + @test isapprox(alpine.bounding_constr_mip[3][:coefs],Any[0.000338983, -1.0];atol=1e-3) + @test alpine.bounding_constr_mip[3][:sense] == :(<=) + @test alpine.bounding_constr_mip[3][:cnt] == 2 + @test alpine.bounding_constr_mip[4][:rhs] == -0.0 + @test alpine.bounding_constr_mip[4][:vars] == Any[:(x[7]), :(x[19])] + @test isapprox(alpine.bounding_constr_mip[4][:coefs],Any[0.000338983, -1.0];atol=1e-3) + @test alpine.bounding_constr_mip[4][:sense] == :(<=) + @test alpine.bounding_constr_mip[4][:cnt] == 2 + @test alpine.bounding_constr_mip[5][:rhs] == -0.0 + @test alpine.bounding_constr_mip[5][:vars] == Any[:(x[2]), :(x[17])] + @test isapprox(alpine.bounding_constr_mip[5][:coefs],Any[0.0125, -1.0];atol=1e-3) + @test alpine.bounding_constr_mip[5][:sense] == :(<=) + @test alpine.bounding_constr_mip[5][:cnt] == 2 + @test alpine.bounding_constr_mip[6][:rhs] == -0.0 + @test alpine.bounding_constr_mip[6][:vars] == Any[:(x[3]), :(x[18])] + @test isapprox(alpine.bounding_constr_mip[6][:coefs],Any[0.04, -1.0];atol=1e-3) + @test alpine.bounding_constr_mip[6][:sense] == :(<=) + @test alpine.bounding_constr_mip[6][:cnt] == 2 + @test alpine.bounding_constr_mip[7][:rhs] == -0.0 + @test alpine.bounding_constr_mip[7][:vars] == Any[:(x[4]), :(x[19])] + @test isapprox(alpine.bounding_constr_mip[7][:coefs],Any[0.0222222, -1.0];atol=1e-3) + @test alpine.bounding_constr_mip[7][:sense] == :(<=) + @test alpine.bounding_constr_mip[7][:cnt] == 2 + @test alpine.bounding_constr_mip[8][:rhs] == -0.0 + @test alpine.bounding_constr_mip[8][:vars] == Any[:(x[8]), :(x[17])] + @test isapprox(alpine.bounding_constr_mip[8][:coefs],Any[0.0025, -1.0];atol=1e-3) + @test alpine.bounding_constr_mip[8][:sense] == :(<=) + @test alpine.bounding_constr_mip[8][:cnt] == 2 + @test alpine.bounding_constr_mip[9][:rhs] == -0.0 + @test alpine.bounding_constr_mip[9][:vars] == Any[:(x[9]), :(x[18])] + @test isapprox(alpine.bounding_constr_mip[9][:coefs],Any[0.0025, -1.0];atol=1e-3) + @test alpine.bounding_constr_mip[9][:sense] == :(<=) + @test alpine.bounding_constr_mip[9][:cnt] == 2 + @test alpine.bounding_constr_mip[10][:rhs] == -0.0 + @test alpine.bounding_constr_mip[10][:vars] == Any[:(x[10]), :(x[19])] + @test isapprox(alpine.bounding_constr_mip[10][:coefs],Any[0.0025, -1.0];atol=1e-3) + @test alpine.bounding_constr_mip[10][:sense] == :(<=) + @test alpine.bounding_constr_mip[10][:cnt] == 2 + @test alpine.bounding_constr_mip[11][:rhs] == -0.0 + @test alpine.bounding_constr_mip[11][:vars] == Any[:(x[11]), :(x[17])] + @test isapprox(alpine.bounding_constr_mip[11][:coefs],Any[0.00285714, -1.0];atol=1e-3) + @test alpine.bounding_constr_mip[11][:sense] == :(<=) + @test alpine.bounding_constr_mip[11][:cnt] == 2 + @test alpine.bounding_constr_mip[12][:rhs] == -0.0 + @test alpine.bounding_constr_mip[12][:vars] == Any[:(x[12]), :(x[18])] + @test isapprox(alpine.bounding_constr_mip[12][:coefs],Any[0.00285714, -1.0];atol=1e-3) + @test alpine.bounding_constr_mip[12][:sense] == :(<=) + @test alpine.bounding_constr_mip[12][:cnt] == 2 + @test alpine.bounding_constr_mip[13][:rhs] == -0.0 + @test alpine.bounding_constr_mip[13][:vars] == Any[:(x[13]), :(x[19])] + @test isapprox(alpine.bounding_constr_mip[13][:coefs],Any[0.00285714, -1.0];atol=1e-3) + @test alpine.bounding_constr_mip[13][:sense] == :(<=) + @test alpine.bounding_constr_mip[13][:cnt] == 2 + @test alpine.bounding_constr_mip[14][:rhs] == -0.0 + @test alpine.bounding_constr_mip[14][:vars] == Any[:(x[14]), :(x[17])] + @test isapprox(alpine.bounding_constr_mip[14][:coefs],Any[1.0, -1.0];atol=1e-3) + @test alpine.bounding_constr_mip[14][:sense] == :(<=) + @test alpine.bounding_constr_mip[14][:cnt] == 2 + @test alpine.bounding_constr_mip[15][:rhs] == -0.0 + @test alpine.bounding_constr_mip[15][:vars] == Any[:(x[15]), :(x[18])] + @test isapprox(alpine.bounding_constr_mip[15][:coefs],Any[1.0, -1.0];atol=1e-3) + @test alpine.bounding_constr_mip[15][:sense] == :(<=) + @test alpine.bounding_constr_mip[15][:cnt] == 2 + @test alpine.bounding_constr_mip[16][:rhs] == -0.0 + @test alpine.bounding_constr_mip[16][:vars] == Any[:(x[16]), :(x[19])] + @test isapprox(alpine.bounding_constr_mip[16][:coefs],Any[1.0, -1.0];atol=1e-3) + @test alpine.bounding_constr_mip[16][:sense] == :(<=) + @test alpine.bounding_constr_mip[16][:cnt] == 2 + @test alpine.bounding_constr_mip[17][:rhs] == -0.0 + @test alpine.bounding_constr_mip[17][:vars] == Any[:(x[20]), :(x[17])] + @test isapprox(alpine.bounding_constr_mip[17][:coefs],Any[1.0, -3.0];atol=1e-3) + @test alpine.bounding_constr_mip[17][:sense] == :(<=) + @test alpine.bounding_constr_mip[17][:cnt] == 2 + @test alpine.bounding_constr_mip[18][:rhs] == -0.0 + @test alpine.bounding_constr_mip[18][:vars] == Any[:(x[21]), :(x[18])] + @test isapprox(alpine.bounding_constr_mip[18][:coefs],Any[1.0, -3.0];atol=1e-3) + @test alpine.bounding_constr_mip[18][:sense] == :(<=) + @test alpine.bounding_constr_mip[18][:cnt] == 2 + @test alpine.bounding_constr_mip[19][:rhs] == -0.0 + @test alpine.bounding_constr_mip[19][:vars] == Any[:(x[22]), :(x[19])] + @test isapprox(alpine.bounding_constr_mip[19][:coefs],Any[1.0, -3.0];atol=1e-3) + @test alpine.bounding_constr_mip[19][:sense] == :(<=) + @test alpine.bounding_constr_mip[19][:cnt] == 2 + @test alpine.bounding_constr_mip[20][:rhs] == -0.0 + @test alpine.bounding_constr_mip[20][:vars] == Any[:(x[23]), :(x[17])] + @test isapprox(alpine.bounding_constr_mip[20][:coefs],Any[1.0, -3.0];atol=1e-3) + @test alpine.bounding_constr_mip[20][:sense] == :(<=) + @test alpine.bounding_constr_mip[20][:cnt] == 2 + @test alpine.bounding_constr_mip[21][:rhs] == -0.0 + @test alpine.bounding_constr_mip[21][:vars] == Any[:(x[24]), :(x[18])] + @test isapprox(alpine.bounding_constr_mip[21][:coefs],Any[1.0, -3.0];atol=1e-3) + @test alpine.bounding_constr_mip[21][:sense] == :(<=) + @test alpine.bounding_constr_mip[21][:cnt] == 2 + @test alpine.bounding_constr_mip[22][:rhs] == -0.0 + @test alpine.bounding_constr_mip[22][:vars] == Any[:(x[25]), :(x[19])] + @test isapprox(alpine.bounding_constr_mip[22][:coefs],Any[1.0, -3.0];atol=1e-3) + @test alpine.bounding_constr_mip[22][:sense] == :(<=) + @test alpine.bounding_constr_mip[22][:cnt] == 2 + @test alpine.bounding_constr_mip[23][:rhs] == 0.0 + @test alpine.bounding_constr_mip[23][:vars] == Any[:(x[29]), :(x[33]), :(x[37]), :(x[1])] + @test isapprox(alpine.bounding_constr_mip[23][:coefs],Any[-1.0, -1.0, -1.0, 1.0];atol=1e-3) + @test alpine.bounding_constr_mip[23][:sense] == :(==) + @test alpine.bounding_constr_mip[23][:cnt] == 4 + @test alpine.bounding_constr_mip[24][:rhs] == 0.0 + @test alpine.bounding_constr_mip[24][:vars] == Any[:(x[39]), :(x[41]), :(x[43]), :(x[2])] + @test isapprox(alpine.bounding_constr_mip[24][:coefs],Any[-19.9, -0.161, 1.90169e-7, 1.0];atol=1e-3) + @test alpine.bounding_constr_mip[24][:sense] == :(==) + @test alpine.bounding_constr_mip[24][:cnt] == 4 + @test alpine.bounding_constr_mip[25][:rhs] == 0.0 + @test alpine.bounding_constr_mip[25][:vars] == Any[:(x[45]), :(x[47]), :(x[49]), :(x[3])] + @test isapprox(alpine.bounding_constr_mip[25][:coefs],Any[-1.21, -0.0644, 1.91186e-7, 1.0];atol=1e-3) + @test alpine.bounding_constr_mip[25][:sense] == :(==) + @test alpine.bounding_constr_mip[25][:cnt] == 4 + @test alpine.bounding_constr_mip[26][:rhs] == 0.0 + @test alpine.bounding_constr_mip[26][:vars] == Any[:(x[51]), :(x[53]), :(x[55]), :(x[4])] + @test isapprox(alpine.bounding_constr_mip[26][:coefs],Any[-6.52, -0.102, 7.86441e-8, 1.0];atol=1e-3) + @test alpine.bounding_constr_mip[26][:sense] == :(==) + @test alpine.bounding_constr_mip[26][:cnt] == 4 + @test alpine.bounding_constr_mip[27][:rhs] == 0.0 + @test alpine.bounding_constr_mip[27][:vars] == Any[:(x[56]), :(x[40]), :(x[42]), :(x[8])] + @test isapprox(alpine.bounding_constr_mip[27][:coefs],Any[-0.000235932, -629.0, 0.0116, 1.0];atol=1e-3) + @test alpine.bounding_constr_mip[27][:sense] == :(==) + @test alpine.bounding_constr_mip[27][:cnt] == 4 + @test alpine.bounding_constr_mip[28][:rhs] == 0.0 + @test alpine.bounding_constr_mip[28][:vars] == Any[:(x[57]), :(x[46]), :(x[48]), :(x[9])] + @test isapprox(alpine.bounding_constr_mip[28][:coefs],Any[-0.001, -215.0, 0.115, 1.0];atol=1e-3) + @test alpine.bounding_constr_mip[28][:sense] == :(==) + @test alpine.bounding_constr_mip[28][:cnt] == 4 + @test alpine.bounding_constr_mip[29][:rhs] == 0.0 + @test alpine.bounding_constr_mip[29][:vars] == Any[:(x[58]), :(x[52]), :(x[54]), :(x[10])] + @test isapprox(alpine.bounding_constr_mip[29][:coefs],Any[-0.000179661, -361.0, 0.00946, 1.0];atol=1e-3) + @test alpine.bounding_constr_mip[29][:sense] == :(==) + @test alpine.bounding_constr_mip[29][:cnt] == 4 + @test alpine.bounding_constr_mip[30][:rhs] == 0.0 + @test alpine.bounding_constr_mip[30][:vars] == Any[:(x[59]), :(x[14])] + @test isapprox(alpine.bounding_constr_mip[30][:coefs],Any[0.00285714, -1.0];atol=1e-3) + @test alpine.bounding_constr_mip[30][:sense] == :(==) + @test alpine.bounding_constr_mip[30][:cnt] == 2 + @test alpine.bounding_constr_mip[31][:rhs] == 0.0 + @test alpine.bounding_constr_mip[31][:vars] == Any[:(x[60]), :(x[15])] + @test isapprox(alpine.bounding_constr_mip[31][:coefs],Any[0.00285714, -1.0];atol=1e-3) + @test alpine.bounding_constr_mip[31][:sense] == :(==) + @test alpine.bounding_constr_mip[31][:cnt] == 2 + @test alpine.bounding_constr_mip[32][:rhs] == 0.0 + @test alpine.bounding_constr_mip[32][:vars] == Any[:(x[61]), :(x[16])] + @test isapprox(alpine.bounding_constr_mip[32][:coefs],Any[0.00285714, -1.0];atol=1e-3) + @test alpine.bounding_constr_mip[32][:sense] == :(==) + @test alpine.bounding_constr_mip[32][:cnt] == 2 + @test alpine.bounding_constr_mip[33][:rhs] == 0.0 + @test alpine.bounding_constr_mip[33][:vars] == Any[:(x[62]), :(x[17])] + @test isapprox(alpine.bounding_constr_mip[33][:coefs],Any[0.0025, -1.0];atol=1e-3) + @test alpine.bounding_constr_mip[33][:sense] == :(==) + @test alpine.bounding_constr_mip[33][:cnt] == 2 + @test alpine.bounding_constr_mip[34][:rhs] == 0.0 + @test alpine.bounding_constr_mip[34][:vars] == Any[:(x[63]), :(x[18])] + @test isapprox(alpine.bounding_constr_mip[34][:coefs],Any[0.0025, -1.0];atol=1e-3) + @test alpine.bounding_constr_mip[34][:sense] == :(==) + @test alpine.bounding_constr_mip[34][:cnt] == 2 + @test alpine.bounding_constr_mip[35][:rhs] == 0.0 + @test alpine.bounding_constr_mip[35][:vars] == Any[:(x[64]), :(x[19])] + @test isapprox(alpine.bounding_constr_mip[35][:coefs],Any[0.0025, -1.0];atol=1e-3) + @test alpine.bounding_constr_mip[35][:sense] == :(==) + @test alpine.bounding_constr_mip[35][:cnt] == 2 end @testset "Expression Parsing || prob03" begin - test_solver = AlpineSolver(minlp_solver=pavito_solver,nlp_solver=IpoptSolver(print_level=0, sb="yes"), mip_solver=CbcSolver(logLevel=0),loglevel=100) + test_solver = optimizer_with_attributes(Alpine.Optimizer,"minlp_solver" => JUNIPER,"nlp_solver" => IPOPT_SB, "mip_solver" => CBC,"loglevel" => 100) m = prob03(solver=test_solver) - JuMP.build(m) - - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[3])]][:y_idx] == 4 - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[3])]][:id] == 1 - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[3])]][:lifted_constr_ref] == :(x[4] == x[2] * x[3]) - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[3])]][:nonlinear_type] == :INTPROD - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[3])]][:y_type] == :Int - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[3])]][:constr_id] == Set(Any[2]) - @test m.internalModel.bounding_constr_mip[1][:rhs] == -0.0 - @test m.internalModel.bounding_constr_mip[1][:vars] == Any[:(x[2]), :(x[3]), :(x[1])] - @test m.internalModel.bounding_constr_mip[1][:coefs] == Any[-3.0, -2.0, 1.0] - @test m.internalModel.bounding_constr_mip[1][:sense] == :(==) - @test m.internalModel.bounding_constr_mip[1][:cnt] == 3 - @test m.internalModel.bounding_constr_mip[2][:rhs] == -3.5 - @test m.internalModel.bounding_constr_mip[2][:vars] == Any[:(x[4])] - @test m.internalModel.bounding_constr_mip[2][:coefs] == Any[-1.0] - @test m.internalModel.bounding_constr_mip[2][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[2][:cnt] == 1 + alpine = _build(m) + + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[3])]][:y_idx] == 4 + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[3])]][:id] == 1 + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[3])]][:lifted_constr_ref] == :(x[4] == x[2] * x[3]) + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[3])]][:nonlinear_type] == :INTPROD + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[3])]][:y_type] == :Int + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[3])]][:constr_id] == Set(Any[2]) + @test alpine.bounding_constr_mip[1][:rhs] == -0.0 + @test alpine.bounding_constr_mip[1][:vars] == Any[:(x[2]), :(x[3]), :(x[1])] + @test alpine.bounding_constr_mip[1][:coefs] == Any[-3.0, -2.0, 1.0] + @test alpine.bounding_constr_mip[1][:sense] == :(==) + @test alpine.bounding_constr_mip[1][:cnt] == 3 + @test alpine.bounding_constr_mip[2][:rhs] == -3.5 + @test alpine.bounding_constr_mip[2][:vars] == Any[:(x[4])] + @test alpine.bounding_constr_mip[2][:coefs] == Any[-1.0] + @test alpine.bounding_constr_mip[2][:sense] == :(<=) + @test alpine.bounding_constr_mip[2][:cnt] == 1 end @testset "Expression Parsing || st_miqp5" begin - test_solver = AlpineSolver(minlp_solver=pavito_solver,nlp_solver=IpoptSolver(print_level=0, sb="yes"), mip_solver=CbcSolver(logLevel=0),loglevel=100) + test_solver = optimizer_with_attributes(Alpine.Optimizer,"minlp_solver" => JUNIPER,"nlp_solver" => IPOPT_SB, "mip_solver" => CBC,"loglevel" => 100) m = st_miqp5(solver=test_solver) - JuMP.build(m) - - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[6])]][:y_idx] == 10 - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[6])]][:id] == 2 - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[6])]][:lifted_constr_ref] == :(x[10] == x[6] * x[6]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[6])]][:nonlinear_type] == :MONOMIAL - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[6])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[6])]][:constr_id] == Set(Any[14]) - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[5])]][:y_idx] == 9 - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[5])]][:id] == 1 - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[5])]][:lifted_constr_ref] == :(x[9] == x[5] * x[5]) - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[5])]][:nonlinear_type] == :MONOMIAL - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[5])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[5])]][:constr_id] == Set(Any[14]) - @test m.internalModel.bounding_constr_mip[1][:rhs] == 60.0 - @test m.internalModel.bounding_constr_mip[1][:vars] == Any[:(x[2]), :(x[3]), :(x[4]), :(x[5]), :(x[6])] - @test isapprox(m.internalModel.bounding_constr_mip[1][:coefs],Any[-1.93415, 1.80315, 2.89696, 0.729325, 3.88374];atol=1e-3) - @test m.internalModel.bounding_constr_mip[1][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[1][:cnt] == 5 - @test m.internalModel.bounding_constr_mip[2][:rhs] == 60.0 - @test m.internalModel.bounding_constr_mip[2][:vars] == Any[:(x[2]), :(x[3]), :(x[4]), :(x[5]), :(x[6])] - @test isapprox(m.internalModel.bounding_constr_mip[2][:coefs],Any[-1.13151, 1.10501, -1.01839, 2.62557, 4.85468];atol=1e-3) - @test m.internalModel.bounding_constr_mip[2][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[2][:cnt] == 5 - @test m.internalModel.bounding_constr_mip[3][:rhs] == -0.0 - @test m.internalModel.bounding_constr_mip[3][:vars] == Any[:(x[2]), :(x[3]), :(x[4]), :(x[5]), :(x[6])] - @test isapprox(m.internalModel.bounding_constr_mip[3][:coefs],Any[-0.05248, -0.904838, 0.209521, -0.29173, -0.222506];atol=1e-3) - @test m.internalModel.bounding_constr_mip[3][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[3][:cnt] == 5 - @test m.internalModel.bounding_constr_mip[4][:rhs] == 1.0 - @test m.internalModel.bounding_constr_mip[4][:vars] == Any[:(x[2]), :(x[3]), :(x[4]), :(x[5]), :(x[6])] - @test isapprox(m.internalModel.bounding_constr_mip[4][:coefs],Any[0.05248, 0.904838, -0.209521, 0.29173, 0.222506];atol=1e-3) - @test m.internalModel.bounding_constr_mip[4][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[4][:cnt] == 5 - @test m.internalModel.bounding_constr_mip[5][:rhs] == -0.0 - @test m.internalModel.bounding_constr_mip[5][:vars] == Any[:(x[2]), :(x[3]), :(x[4]), :(x[5]), :(x[6])] - @test isapprox(m.internalModel.bounding_constr_mip[5][:coefs],Any[0.445392, 0.30152, 0.587645, -0.145865, -0.586607];atol=1e-3) - @test m.internalModel.bounding_constr_mip[5][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[5][:cnt] == 5 - @test m.internalModel.bounding_constr_mip[6][:rhs] == 1.0 - @test m.internalModel.bounding_constr_mip[6][:vars] == Any[:(x[2]), :(x[3]), :(x[4]), :(x[5]), :(x[6])] - @test isapprox(m.internalModel.bounding_constr_mip[6][:coefs],Any[-0.445392, -0.30152, -0.587645, 0.145865, 0.586607];atol=1e-3) - @test m.internalModel.bounding_constr_mip[6][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[6][:cnt] == 5 - @test m.internalModel.bounding_constr_mip[7][:rhs] == -0.0 - @test m.internalModel.bounding_constr_mip[7][:vars] == Any[:(x[2]), :(x[3]), :(x[4]), :(x[5]), :(x[6])] - @test isapprox(m.internalModel.bounding_constr_mip[7][:coefs],Any[-0.328189, 0.199987, 0.506106, -0.58346, 0.505696];atol=1e-3) - @test m.internalModel.bounding_constr_mip[7][:sense] == :(>=) - @test m.internalModel.bounding_constr_mip[7][:cnt] == 5 - @test m.internalModel.bounding_constr_mip[8][:rhs] == -0.0 - @test m.internalModel.bounding_constr_mip[8][:vars] == Any[:(x[2]), :(x[3]), :(x[4]), :(x[5]), :(x[6])] - @test isapprox(m.internalModel.bounding_constr_mip[8][:coefs],Any[-0.345682, -0.101626, 0.575947, 0.729325, 0.0809113];atol=1e-3) - @test m.internalModel.bounding_constr_mip[8][:sense] == :(>=) - @test m.internalModel.bounding_constr_mip[8][:cnt] == 5 - @test m.internalModel.bounding_constr_mip[9][:rhs] == -0.0 - @test m.internalModel.bounding_constr_mip[9][:vars] == Any[:(x[2]), :(x[3]), :(x[4]), :(x[5]), :(x[6])] - @test isapprox(m.internalModel.bounding_constr_mip[9][:coefs],Any[0.756087, -0.200079, 0.151379, 0.145865, 0.586607];atol=1e-3) - @test m.internalModel.bounding_constr_mip[9][:sense] == :(>=) - @test m.internalModel.bounding_constr_mip[9][:cnt] == 5 - @test m.internalModel.bounding_constr_mip[10][:rhs] == -0.0 - @test m.internalModel.bounding_constr_mip[10][:vars] == Any[:(x[7]), :(x[2]), :(x[3]), :(x[4]), :(x[5]), :(x[6])] - @test isapprox(m.internalModel.bounding_constr_mip[10][:coefs],Any[-1.0, 0.05248, 0.904838, -0.209521, 0.29173, 0.222506];atol=1e-3) - @test m.internalModel.bounding_constr_mip[10][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[10][:cnt] == 6 - @test m.internalModel.bounding_constr_mip[11][:rhs] == -0.0 - @test m.internalModel.bounding_constr_mip[11][:vars] == Any[:(x[7]), :(x[2]), :(x[3]), :(x[4]), :(x[5]), :(x[6])] - @test isapprox(m.internalModel.bounding_constr_mip[11][:coefs],Any[1.0, -0.05248, -0.904838, 0.209521, -0.29173, -0.222506];atol=1e-3) - @test m.internalModel.bounding_constr_mip[11][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[11][:cnt] == 6 - @test m.internalModel.bounding_constr_mip[12][:rhs] == -0.0 - @test m.internalModel.bounding_constr_mip[12][:vars] == Any[:(x[8]), :(x[2]), :(x[3]), :(x[4]), :(x[5]), :(x[6])] - @test isapprox(m.internalModel.bounding_constr_mip[12][:coefs],Any[-1.0, -0.445392, -0.30152, -0.587645, 0.145865, 0.586607];atol=1e-3) - @test m.internalModel.bounding_constr_mip[12][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[12][:cnt] == 6 - @test m.internalModel.bounding_constr_mip[13][:rhs] == -0.0 - @test m.internalModel.bounding_constr_mip[13][:vars] == Any[:(x[8]), :(x[2]), :(x[3]), :(x[4]), :(x[5]), :(x[6])] - @test isapprox(m.internalModel.bounding_constr_mip[13][:coefs],Any[1.0, 0.445392, 0.30152, 0.587645, -0.145865, -0.586607];atol=1e-3) - @test m.internalModel.bounding_constr_mip[13][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[13][:cnt] == 6 - @test m.internalModel.bounding_constr_mip[14][:rhs] == 0.0 - @test m.internalModel.bounding_constr_mip[14][:vars] == Any[:(x[9]), :(x[5]), :(x[10]), :(x[6]), :(x[2]), :(x[3]), :(x[4]), :(x[1])] - @test isapprox(m.internalModel.bounding_constr_mip[14][:coefs],Any[-5.0, 0.87519, -52.0, 192.711, 54.0616, 45.2691, 33.0896, 1.0];atol=1e-3) - @test m.internalModel.bounding_constr_mip[14][:sense] == :(==) - @test m.internalModel.bounding_constr_mip[14][:cnt] == 8 + alpine = _build(m) + + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[6])]][:y_idx] == 10 + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[6])]][:id] == 2 + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[6])]][:lifted_constr_ref] == :(x[10] == x[6] * x[6]) + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[6])]][:nonlinear_type] == :MONOMIAL + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[6])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[6])]][:constr_id] == Set(Any[14]) + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[5])]][:y_idx] == 9 + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[5])]][:id] == 1 + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[5])]][:lifted_constr_ref] == :(x[9] == x[5] * x[5]) + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[5])]][:nonlinear_type] == :MONOMIAL + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[5])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[5])]][:constr_id] == Set(Any[14]) + @test alpine.bounding_constr_mip[4][:rhs] == 60.0 + @test alpine.bounding_constr_mip[4][:vars] == Any[:(x[2]), :(x[3]), :(x[4]), :(x[5]), :(x[6])] + @test isapprox(alpine.bounding_constr_mip[4][:coefs],Any[-1.93415, 1.80315, 2.89696, 0.729325, 3.88374];atol=1e-3) + @test alpine.bounding_constr_mip[4][:sense] == :(<=) + @test alpine.bounding_constr_mip[4][:cnt] == 5 + @test alpine.bounding_constr_mip[5][:rhs] == 60.0 + @test alpine.bounding_constr_mip[5][:vars] == Any[:(x[2]), :(x[3]), :(x[4]), :(x[5]), :(x[6])] + @test isapprox(alpine.bounding_constr_mip[5][:coefs],Any[-1.13151, 1.10501, -1.01839, 2.62557, 4.85468];atol=1e-3) + @test alpine.bounding_constr_mip[5][:sense] == :(<=) + @test alpine.bounding_constr_mip[5][:cnt] == 5 + @test alpine.bounding_constr_mip[6][:rhs] == -0.0 + @test alpine.bounding_constr_mip[6][:vars] == Any[:(x[2]), :(x[3]), :(x[4]), :(x[5]), :(x[6])] + @test isapprox(alpine.bounding_constr_mip[6][:coefs],Any[-0.05248, -0.904838, 0.209521, -0.29173, -0.222506];atol=1e-3) + @test alpine.bounding_constr_mip[6][:sense] == :(<=) + @test alpine.bounding_constr_mip[6][:cnt] == 5 + @test alpine.bounding_constr_mip[7][:rhs] == 1.0 + @test alpine.bounding_constr_mip[7][:vars] == Any[:(x[2]), :(x[3]), :(x[4]), :(x[5]), :(x[6])] + @test isapprox(alpine.bounding_constr_mip[7][:coefs],Any[0.05248, 0.904838, -0.209521, 0.29173, 0.222506];atol=1e-3) + @test alpine.bounding_constr_mip[7][:sense] == :(<=) + @test alpine.bounding_constr_mip[7][:cnt] == 5 + @test alpine.bounding_constr_mip[8][:rhs] == -0.0 + @test alpine.bounding_constr_mip[8][:vars] == Any[:(x[2]), :(x[3]), :(x[4]), :(x[5]), :(x[6])] + @test isapprox(alpine.bounding_constr_mip[8][:coefs],Any[0.445392, 0.30152, 0.587645, -0.145865, -0.586607];atol=1e-3) + @test alpine.bounding_constr_mip[8][:sense] == :(<=) + @test alpine.bounding_constr_mip[8][:cnt] == 5 + @test alpine.bounding_constr_mip[9][:rhs] == 1.0 + @test alpine.bounding_constr_mip[9][:vars] == Any[:(x[2]), :(x[3]), :(x[4]), :(x[5]), :(x[6])] + @test isapprox(alpine.bounding_constr_mip[9][:coefs],Any[-0.445392, -0.30152, -0.587645, 0.145865, 0.586607];atol=1e-3) + @test alpine.bounding_constr_mip[9][:sense] == :(<=) + @test alpine.bounding_constr_mip[9][:cnt] == 5 + @test alpine.bounding_constr_mip[1][:rhs] == -0.0 + @test alpine.bounding_constr_mip[1][:vars] == Any[:(x[2]), :(x[3]), :(x[4]), :(x[5]), :(x[6])] + @test isapprox(alpine.bounding_constr_mip[1][:coefs],Any[-0.328189, 0.199987, 0.506106, -0.58346, 0.505696];atol=1e-3) + @test alpine.bounding_constr_mip[1][:sense] == :(>=) + @test alpine.bounding_constr_mip[1][:cnt] == 5 + @test alpine.bounding_constr_mip[2][:rhs] == -0.0 + @test alpine.bounding_constr_mip[2][:vars] == Any[:(x[2]), :(x[3]), :(x[4]), :(x[5]), :(x[6])] + @test isapprox(alpine.bounding_constr_mip[2][:coefs],Any[-0.345682, -0.101626, 0.575947, 0.729325, 0.0809113];atol=1e-3) + @test alpine.bounding_constr_mip[2][:sense] == :(>=) + @test alpine.bounding_constr_mip[2][:cnt] == 5 + @test alpine.bounding_constr_mip[3][:rhs] == -0.0 + @test alpine.bounding_constr_mip[3][:vars] == Any[:(x[2]), :(x[3]), :(x[4]), :(x[5]), :(x[6])] + @test isapprox(alpine.bounding_constr_mip[3][:coefs],Any[0.756087, -0.200079, 0.151379, 0.145865, 0.586607];atol=1e-3) + @test alpine.bounding_constr_mip[3][:sense] == :(>=) + @test alpine.bounding_constr_mip[3][:cnt] == 5 + @test alpine.bounding_constr_mip[10][:rhs] == -0.0 + @test alpine.bounding_constr_mip[10][:vars] == Any[:(x[7]), :(x[2]), :(x[3]), :(x[4]), :(x[5]), :(x[6])] + @test isapprox(alpine.bounding_constr_mip[10][:coefs],Any[-1.0, 0.05248, 0.904838, -0.209521, 0.29173, 0.222506];atol=1e-3) + @test alpine.bounding_constr_mip[10][:sense] == :(<=) + @test alpine.bounding_constr_mip[10][:cnt] == 6 + @test alpine.bounding_constr_mip[11][:rhs] == -0.0 + @test alpine.bounding_constr_mip[11][:vars] == Any[:(x[7]), :(x[2]), :(x[3]), :(x[4]), :(x[5]), :(x[6])] + @test isapprox(alpine.bounding_constr_mip[11][:coefs],Any[1.0, -0.05248, -0.904838, 0.209521, -0.29173, -0.222506];atol=1e-3) + @test alpine.bounding_constr_mip[11][:sense] == :(<=) + @test alpine.bounding_constr_mip[11][:cnt] == 6 + @test alpine.bounding_constr_mip[12][:rhs] == -0.0 + @test alpine.bounding_constr_mip[12][:vars] == Any[:(x[8]), :(x[2]), :(x[3]), :(x[4]), :(x[5]), :(x[6])] + @test isapprox(alpine.bounding_constr_mip[12][:coefs],Any[-1.0, -0.445392, -0.30152, -0.587645, 0.145865, 0.586607];atol=1e-3) + @test alpine.bounding_constr_mip[12][:sense] == :(<=) + @test alpine.bounding_constr_mip[12][:cnt] == 6 + @test alpine.bounding_constr_mip[13][:rhs] == -0.0 + @test alpine.bounding_constr_mip[13][:vars] == Any[:(x[8]), :(x[2]), :(x[3]), :(x[4]), :(x[5]), :(x[6])] + @test isapprox(alpine.bounding_constr_mip[13][:coefs],Any[1.0, 0.445392, 0.30152, 0.587645, -0.145865, -0.586607];atol=1e-3) + @test alpine.bounding_constr_mip[13][:sense] == :(<=) + @test alpine.bounding_constr_mip[13][:cnt] == 6 + @test alpine.bounding_constr_mip[14][:rhs] == 0.0 + @test alpine.bounding_constr_mip[14][:vars] == Any[:(x[9]), :(x[5]), :(x[10]), :(x[6]), :(x[2]), :(x[3]), :(x[4]), :(x[1])] + @test isapprox(alpine.bounding_constr_mip[14][:coefs],Any[-5.0, 0.87519, -52.0, 192.711, 54.0616, 45.2691, 33.0896, 1.0];atol=1e-3) + @test alpine.bounding_constr_mip[14][:sense] == :(==) + @test alpine.bounding_constr_mip[14][:cnt] == 8 end @testset "Expression Parsing || discretemulti_basic" begin - test_solver = AlpineSolver(minlp_solver=pavito_solver,nlp_solver=IpoptSolver(print_level=0, sb="yes"), mip_solver=CbcSolver(logLevel=0),loglevel=100) + test_solver = optimizer_with_attributes(Alpine.Optimizer,"minlp_solver" => JUNIPER,"nlp_solver" => IPOPT_SB, "mip_solver" => CBC,"loglevel" => 100) m = discretemulti_basic(solver=test_solver) - JuMP.build(m) - - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[8])]][:y_idx] == 18 - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[8])]][:id] == 3 - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[8])]][:lifted_constr_ref] == :(x[18] == x[3] * x[8]) - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[8])]][:nonlinear_type] == :BINLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[8])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[8])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[32]), :(x[9])]][:y_idx] == 33 - @test m.internalModel.nonconvex_terms[Expr[:(x[32]), :(x[9])]][:id] == 18 - @test m.internalModel.nonconvex_terms[Expr[:(x[32]), :(x[9])]][:lifted_constr_ref] == :(x[33] == x[32] * x[9]) - @test m.internalModel.nonconvex_terms[Expr[:(x[32]), :(x[9])]][:nonlinear_type] == :INTLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[32]), :(x[9])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[32]), :(x[9])]][:constr_id] == Set(Any[12]) - @test m.internalModel.nonconvex_terms[Expr[:(x[40]), :(x[41])]][:y_idx] == 42 - @test m.internalModel.nonconvex_terms[Expr[:(x[40]), :(x[41])]][:id] == 27 - @test m.internalModel.nonconvex_terms[Expr[:(x[40]), :(x[41])]][:lifted_constr_ref] == :(x[42] == x[40] * x[41]) - @test m.internalModel.nonconvex_terms[Expr[:(x[40]), :(x[41])]][:nonlinear_type] == :BINLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[40]), :(x[41])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[40]), :(x[41])]][:constr_id] == Set(Any[18]) - @test m.internalModel.nonconvex_terms[Expr[:(x[13]), :(x[8])]][:y_idx] == 23 - @test m.internalModel.nonconvex_terms[Expr[:(x[13]), :(x[8])]][:id] == 8 - @test m.internalModel.nonconvex_terms[Expr[:(x[13]), :(x[8])]][:lifted_constr_ref] == :(x[23] == x[13] * x[8]) - @test m.internalModel.nonconvex_terms[Expr[:(x[13]), :(x[8])]][:nonlinear_type] == :INTLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[13]), :(x[8])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[13]), :(x[8])]][:constr_id] == Set(Any[15, 6]) - @test m.internalModel.nonconvex_terms[Expr[:(x[44]), :(x[45])]][:y_idx] == 46 - @test m.internalModel.nonconvex_terms[Expr[:(x[44]), :(x[45])]][:id] == 31 - @test m.internalModel.nonconvex_terms[Expr[:(x[44]), :(x[45])]][:lifted_constr_ref] == :(x[46] == x[44] * x[45]) - @test m.internalModel.nonconvex_terms[Expr[:(x[44]), :(x[45])]][:nonlinear_type] == :BINLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[44]), :(x[45])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[44]), :(x[45])]][:constr_id] == Set(Any[19]) - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[4])]][:y_idx] == 48 - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[4])]][:id] == 33 - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[4])]][:lifted_constr_ref] == :(x[48] == x[3] * x[4]) - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[4])]][:nonlinear_type] == :BINPROD - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[4])]][:y_type] == :Bin - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[4])]][:constr_id] == Set(Any[20]) - @test m.internalModel.nonconvex_terms[Expr[:(x[14]), :(x[9])]][:y_idx] == 24 - @test m.internalModel.nonconvex_terms[Expr[:(x[14]), :(x[9])]][:id] == 9 - @test m.internalModel.nonconvex_terms[Expr[:(x[14]), :(x[9])]][:lifted_constr_ref] == :(x[24] == x[14] * x[9]) - @test m.internalModel.nonconvex_terms[Expr[:(x[14]), :(x[9])]][:nonlinear_type] == :INTLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[14]), :(x[9])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[14]), :(x[9])]][:constr_id] == Set(Any[7, 16]) - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[9])]][:y_idx] == 19 - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[9])]][:id] == 4 - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[9])]][:lifted_constr_ref] == :(x[19] == x[4] * x[9]) - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[9])]][:nonlinear_type] == :BINLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[9])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[9])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[24])]][:y_idx] == 37 - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[24])]][:id] == 22 - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[24])]][:lifted_constr_ref] == :(x[37] == x[4] * x[24]) - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[24])]][:nonlinear_type] == :BINLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[24])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[24])]][:constr_id] == Set(Any[16]) - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[6])]][:y_idx] == 16 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[6])]][:id] == 1 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[6])]][:lifted_constr_ref] == :(x[16] == x[1] * x[6]) - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[6])]][:nonlinear_type] == :BINLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[6])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[6])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[22])]][:y_idx] == 35 - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[22])]][:id] == 20 - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[22])]][:lifted_constr_ref] == :(x[35] == x[2] * x[22]) - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[22])]][:nonlinear_type] == :BINLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[22])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[22])]][:constr_id] == Set(Any[14]) - @test m.internalModel.nonconvex_terms[Expr[:(x[15]), :(x[10])]][:y_idx] == 25 - @test m.internalModel.nonconvex_terms[Expr[:(x[15]), :(x[10])]][:id] == 10 - @test m.internalModel.nonconvex_terms[Expr[:(x[15]), :(x[10])]][:lifted_constr_ref] == :(x[25] == x[15] * x[10]) - @test m.internalModel.nonconvex_terms[Expr[:(x[15]), :(x[10])]][:nonlinear_type] == :INTLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[15]), :(x[10])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[15]), :(x[10])]][:constr_id] == Set(Any[17, 8]) - @test m.internalModel.nonconvex_terms[Expr[:(x[9]), :(x[10])]][:y_idx] == 51 - @test m.internalModel.nonconvex_terms[Expr[:(x[9]), :(x[10])]][:id] == 36 - @test m.internalModel.nonconvex_terms[Expr[:(x[9]), :(x[10])]][:lifted_constr_ref] == :(x[51] == x[9] * x[10]) - @test m.internalModel.nonconvex_terms[Expr[:(x[9]), :(x[10])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[9]), :(x[10])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[9]), :(x[10])]][:constr_id] == Set(Any[21]) - @test m.internalModel.nonconvex_terms[Expr[:(x[28]), :(x[7])]][:y_idx] == 29 - @test m.internalModel.nonconvex_terms[Expr[:(x[28]), :(x[7])]][:id] == 14 - @test m.internalModel.nonconvex_terms[Expr[:(x[28]), :(x[7])]][:lifted_constr_ref] == :(x[29] == x[28] * x[7]) - @test m.internalModel.nonconvex_terms[Expr[:(x[28]), :(x[7])]][:nonlinear_type] == :INTLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[28]), :(x[7])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[28]), :(x[7])]][:constr_id] == Set(Any[10]) - @test m.internalModel.nonconvex_terms[Expr[:(x[30]), :(x[8])]][:y_idx] == 31 - @test m.internalModel.nonconvex_terms[Expr[:(x[30]), :(x[8])]][:id] == 16 - @test m.internalModel.nonconvex_terms[Expr[:(x[30]), :(x[8])]][:lifted_constr_ref] == :(x[31] == x[30] * x[8]) - @test m.internalModel.nonconvex_terms[Expr[:(x[30]), :(x[8])]][:nonlinear_type] == :INTLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[30]), :(x[8])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[30]), :(x[8])]][:constr_id] == Set(Any[11]) - @test m.internalModel.nonconvex_terms[Expr[:(x[8]), :(x[9])]][:y_idx] == 47 - @test m.internalModel.nonconvex_terms[Expr[:(x[8]), :(x[9])]][:id] == 32 - @test m.internalModel.nonconvex_terms[Expr[:(x[8]), :(x[9])]][:lifted_constr_ref] == :(x[47] == x[8] * x[9]) - @test m.internalModel.nonconvex_terms[Expr[:(x[8]), :(x[9])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[8]), :(x[9])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[8]), :(x[9])]][:constr_id] == Set(Any[20]) - @test m.internalModel.nonconvex_terms[Expr[:(x[14]), :(x[15])]][:y_idx] == 32 - @test m.internalModel.nonconvex_terms[Expr[:(x[14]), :(x[15])]][:id] == 17 - @test m.internalModel.nonconvex_terms[Expr[:(x[14]), :(x[15])]][:lifted_constr_ref] == :(x[32] == x[14] * x[15]) - @test m.internalModel.nonconvex_terms[Expr[:(x[14]), :(x[15])]][:nonlinear_type] == :INTPROD - @test m.internalModel.nonconvex_terms[Expr[:(x[14]), :(x[15])]][:y_type] == :Int - @test m.internalModel.nonconvex_terms[Expr[:(x[14]), :(x[15])]][:constr_id] == Set(Any[21, 12]) - @test m.internalModel.nonconvex_terms[Expr[:(x[7]), :(x[8])]][:y_idx] == 43 - @test m.internalModel.nonconvex_terms[Expr[:(x[7]), :(x[8])]][:id] == 28 - @test m.internalModel.nonconvex_terms[Expr[:(x[7]), :(x[8])]][:lifted_constr_ref] == :(x[43] == x[7] * x[8]) - @test m.internalModel.nonconvex_terms[Expr[:(x[7]), :(x[8])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[7]), :(x[8])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[7]), :(x[8])]][:constr_id] == Set(Any[19]) - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[23])]][:y_idx] == 36 - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[23])]][:id] == 21 - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[23])]][:lifted_constr_ref] == :(x[36] == x[3] * x[23]) - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[23])]][:nonlinear_type] == :BINLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[23])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[23])]][:constr_id] == Set(Any[15]) - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[7])]][:y_idx] == 17 - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[7])]][:id] == 2 - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[7])]][:lifted_constr_ref] == :(x[17] == x[2] * x[7]) - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[7])]][:nonlinear_type] == :BINLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[7])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[7])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[12]), :(x[7])]][:y_idx] == 22 - @test m.internalModel.nonconvex_terms[Expr[:(x[12]), :(x[7])]][:id] == 7 - @test m.internalModel.nonconvex_terms[Expr[:(x[12]), :(x[7])]][:lifted_constr_ref] == :(x[22] == x[12] * x[7]) - @test m.internalModel.nonconvex_terms[Expr[:(x[12]), :(x[7])]][:nonlinear_type] == :INTLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[12]), :(x[7])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[12]), :(x[7])]][:constr_id] == Set(Any[14, 5]) - @test m.internalModel.nonconvex_terms[Expr[:(x[11]), :(x[12])]][:y_idx] == 26 - @test m.internalModel.nonconvex_terms[Expr[:(x[11]), :(x[12])]][:id] == 11 - @test m.internalModel.nonconvex_terms[Expr[:(x[11]), :(x[12])]][:lifted_constr_ref] == :(x[26] == x[11] * x[12]) - @test m.internalModel.nonconvex_terms[Expr[:(x[11]), :(x[12])]][:nonlinear_type] == :INTPROD - @test m.internalModel.nonconvex_terms[Expr[:(x[11]), :(x[12])]][:y_type] == :Int - @test m.internalModel.nonconvex_terms[Expr[:(x[11]), :(x[12])]][:constr_id] == Set(Any[9, 18]) - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[5])]][:y_idx] == 52 - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[5])]][:id] == 37 - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[5])]][:lifted_constr_ref] == :(x[52] == x[4] * x[5]) - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[5])]][:nonlinear_type] == :BINPROD - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[5])]][:y_type] == :Bin - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[5])]][:constr_id] == Set(Any[21]) - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[21])]][:y_idx] == 34 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[21])]][:id] == 19 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[21])]][:lifted_constr_ref] == :(x[34] == x[1] * x[21]) - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[21])]][:nonlinear_type] == :BINLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[21])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[21])]][:constr_id] == Set(Any[13]) - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[2])]][:y_idx] == 40 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[2])]][:id] == 25 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[2])]][:lifted_constr_ref] == :(x[40] == x[1] * x[2]) - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[2])]][:nonlinear_type] == :BINPROD - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[2])]][:y_type] == :Bin - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[2])]][:constr_id] == Set(Any[18]) - @test m.internalModel.nonconvex_terms[Expr[:(x[13]), :(x[14])]][:y_idx] == 30 - @test m.internalModel.nonconvex_terms[Expr[:(x[13]), :(x[14])]][:id] == 15 - @test m.internalModel.nonconvex_terms[Expr[:(x[13]), :(x[14])]][:lifted_constr_ref] == :(x[30] == x[13] * x[14]) - @test m.internalModel.nonconvex_terms[Expr[:(x[13]), :(x[14])]][:nonlinear_type] == :INTPROD - @test m.internalModel.nonconvex_terms[Expr[:(x[13]), :(x[14])]][:y_type] == :Int - @test m.internalModel.nonconvex_terms[Expr[:(x[13]), :(x[14])]][:constr_id] == Set(Any[11, 20]) - @test m.internalModel.nonconvex_terms[Expr[:(x[28]), :(x[43])]][:y_idx] == 45 - @test m.internalModel.nonconvex_terms[Expr[:(x[28]), :(x[43])]][:id] == 30 - @test m.internalModel.nonconvex_terms[Expr[:(x[28]), :(x[43])]][:lifted_constr_ref] == :(x[45] == x[28] * x[43]) - @test m.internalModel.nonconvex_terms[Expr[:(x[28]), :(x[43])]][:nonlinear_type] == :INTLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[28]), :(x[43])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[28]), :(x[43])]][:constr_id] == Set(Any[19]) - @test m.internalModel.nonconvex_terms[Expr[:(x[52]), :(x[53])]][:y_idx] == 54 - @test m.internalModel.nonconvex_terms[Expr[:(x[52]), :(x[53])]][:id] == 39 - @test m.internalModel.nonconvex_terms[Expr[:(x[52]), :(x[53])]][:lifted_constr_ref] == :(x[54] == x[52] * x[53]) - @test m.internalModel.nonconvex_terms[Expr[:(x[52]), :(x[53])]][:nonlinear_type] == :BINLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[52]), :(x[53])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[52]), :(x[53])]][:constr_id] == Set(Any[21]) - @test m.internalModel.nonconvex_terms[Expr[:(x[48]), :(x[49])]][:y_idx] == 50 - @test m.internalModel.nonconvex_terms[Expr[:(x[48]), :(x[49])]][:id] == 35 - @test m.internalModel.nonconvex_terms[Expr[:(x[48]), :(x[49])]][:lifted_constr_ref] == :(x[50] == x[48] * x[49]) - @test m.internalModel.nonconvex_terms[Expr[:(x[48]), :(x[49])]][:nonlinear_type] == :BINLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[48]), :(x[49])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[48]), :(x[49])]][:constr_id] == Set(Any[20]) - @test m.internalModel.nonconvex_terms[Expr[:(x[32]), :(x[51])]][:y_idx] == 53 - @test m.internalModel.nonconvex_terms[Expr[:(x[32]), :(x[51])]][:id] == 38 - @test m.internalModel.nonconvex_terms[Expr[:(x[32]), :(x[51])]][:lifted_constr_ref] == :(x[53] == x[32] * x[51]) - @test m.internalModel.nonconvex_terms[Expr[:(x[32]), :(x[51])]][:nonlinear_type] == :INTLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[32]), :(x[51])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[32]), :(x[51])]][:constr_id] == Set(Any[21]) - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[3])]][:y_idx] == 44 - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[3])]][:id] == 29 - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[3])]][:lifted_constr_ref] == :(x[44] == x[2] * x[3]) - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[3])]][:nonlinear_type] == :BINPROD - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[3])]][:y_type] == :Bin - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[3])]][:constr_id] == Set(Any[19]) - @test m.internalModel.nonconvex_terms[Expr[:(x[26]), :(x[39])]][:y_idx] == 41 - @test m.internalModel.nonconvex_terms[Expr[:(x[26]), :(x[39])]][:id] == 26 - @test m.internalModel.nonconvex_terms[Expr[:(x[26]), :(x[39])]][:lifted_constr_ref] == :(x[41] == x[26] * x[39]) - @test m.internalModel.nonconvex_terms[Expr[:(x[26]), :(x[39])]][:nonlinear_type] == :INTLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[26]), :(x[39])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[26]), :(x[39])]][:constr_id] == Set(Any[18]) - @test m.internalModel.nonconvex_terms[Expr[:(x[26]), :(x[6])]][:y_idx] == 27 - @test m.internalModel.nonconvex_terms[Expr[:(x[26]), :(x[6])]][:id] == 12 - @test m.internalModel.nonconvex_terms[Expr[:(x[26]), :(x[6])]][:lifted_constr_ref] == :(x[27] == x[26] * x[6]) - @test m.internalModel.nonconvex_terms[Expr[:(x[26]), :(x[6])]][:nonlinear_type] == :INTLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[26]), :(x[6])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[26]), :(x[6])]][:constr_id] == Set(Any[9]) - @test m.internalModel.nonconvex_terms[Expr[:(x[12]), :(x[13])]][:y_idx] == 28 - @test m.internalModel.nonconvex_terms[Expr[:(x[12]), :(x[13])]][:id] == 13 - @test m.internalModel.nonconvex_terms[Expr[:(x[12]), :(x[13])]][:lifted_constr_ref] == :(x[28] == x[12] * x[13]) - @test m.internalModel.nonconvex_terms[Expr[:(x[12]), :(x[13])]][:nonlinear_type] == :INTPROD - @test m.internalModel.nonconvex_terms[Expr[:(x[12]), :(x[13])]][:y_type] == :Int - @test m.internalModel.nonconvex_terms[Expr[:(x[12]), :(x[13])]][:constr_id] == Set(Any[10, 19]) - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[25])]][:y_idx] == 38 - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[25])]][:id] == 23 - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[25])]][:lifted_constr_ref] == :(x[38] == x[5] * x[25]) - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[25])]][:nonlinear_type] == :BINLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[25])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[25])]][:constr_id] == Set(Any[17]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[7])]][:y_idx] == 39 - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[7])]][:id] == 24 - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[7])]][:lifted_constr_ref] == :(x[39] == x[6] * x[7]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[7])]][:nonlinear_type] == :BILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[7])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[7])]][:constr_id] == Set(Any[18]) - @test m.internalModel.nonconvex_terms[Expr[:(x[30]), :(x[47])]][:y_idx] == 49 - @test m.internalModel.nonconvex_terms[Expr[:(x[30]), :(x[47])]][:id] == 34 - @test m.internalModel.nonconvex_terms[Expr[:(x[30]), :(x[47])]][:lifted_constr_ref] == :(x[49] == x[30] * x[47]) - @test m.internalModel.nonconvex_terms[Expr[:(x[30]), :(x[47])]][:nonlinear_type] == :INTLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[30]), :(x[47])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[30]), :(x[47])]][:constr_id] == Set(Any[20]) - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[10])]][:y_idx] == 20 - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[10])]][:id] == 5 - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[10])]][:lifted_constr_ref] == :(x[20] == x[5] * x[10]) - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[10])]][:nonlinear_type] == :BINLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[10])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[10])]][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[11]), :(x[6])]][:y_idx] == 21 - @test m.internalModel.nonconvex_terms[Expr[:(x[11]), :(x[6])]][:id] == 6 - @test m.internalModel.nonconvex_terms[Expr[:(x[11]), :(x[6])]][:lifted_constr_ref] == :(x[21] == x[11] * x[6]) - @test m.internalModel.nonconvex_terms[Expr[:(x[11]), :(x[6])]][:nonlinear_type] == :INTLIN - @test m.internalModel.nonconvex_terms[Expr[:(x[11]), :(x[6])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[11]), :(x[6])]][:constr_id] == Set(Any[4, 13]) - @test m.internalModel.bounding_constr_mip[1][:rhs] == 3.0 - @test m.internalModel.bounding_constr_mip[1][:vars] == Any[:(x[1]), :(x[2]), :(x[3]), :(x[4]), :(x[5])] - @test m.internalModel.bounding_constr_mip[1][:coefs] == Any[1.0, 1.0, 1.0, 1.0, 1.0] - @test m.internalModel.bounding_constr_mip[1][:sense] == :(>=) - @test m.internalModel.bounding_constr_mip[1][:cnt] == 5 - @test m.internalModel.bounding_constr_mip[2][:rhs] == 10.0 - @test m.internalModel.bounding_constr_mip[2][:vars] == Any[:(x[11]), :(x[12]), :(x[13]), :(x[14]), :(x[15])] - @test m.internalModel.bounding_constr_mip[2][:coefs] == Any[1.0, 1.0, 1.0, 1.0, 1.0] - @test m.internalModel.bounding_constr_mip[2][:sense] == :(>=) - @test m.internalModel.bounding_constr_mip[2][:cnt] == 5 - @test m.internalModel.bounding_constr_mip[3][:rhs] == 8.0 - @test m.internalModel.bounding_constr_mip[3][:vars] == Any[:(x[11]), :(x[12]), :(x[13]), :(x[14]), :(x[15])] - @test m.internalModel.bounding_constr_mip[3][:coefs] == Any[1.0, 1.0, 1.0, 1.0, 1.0] - @test m.internalModel.bounding_constr_mip[3][:sense] == :(>=) - @test m.internalModel.bounding_constr_mip[3][:cnt] == 5 - @test m.internalModel.bounding_constr_mip[4][:rhs] == 17.1 - @test m.internalModel.bounding_constr_mip[4][:vars] == Any[:(x[21])] - @test m.internalModel.bounding_constr_mip[4][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[4][:sense] == :(>=) - @test m.internalModel.bounding_constr_mip[4][:cnt] == 1 - @test m.internalModel.bounding_constr_mip[5][:rhs] == 17.1 - @test m.internalModel.bounding_constr_mip[5][:vars] == Any[:(x[22])] - @test m.internalModel.bounding_constr_mip[5][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[5][:sense] == :(>=) - @test m.internalModel.bounding_constr_mip[5][:cnt] == 1 - @test m.internalModel.bounding_constr_mip[6][:rhs] == 17.1 - @test m.internalModel.bounding_constr_mip[6][:vars] == Any[:(x[23])] - @test m.internalModel.bounding_constr_mip[6][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[6][:sense] == :(>=) - @test m.internalModel.bounding_constr_mip[6][:cnt] == 1 - @test m.internalModel.bounding_constr_mip[7][:rhs] == 17.1 - @test m.internalModel.bounding_constr_mip[7][:vars] == Any[:(x[24])] - @test m.internalModel.bounding_constr_mip[7][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[7][:sense] == :(>=) - @test m.internalModel.bounding_constr_mip[7][:cnt] == 1 - @test m.internalModel.bounding_constr_mip[8][:rhs] == 17.1 - @test m.internalModel.bounding_constr_mip[8][:vars] == Any[:(x[25])] - @test m.internalModel.bounding_constr_mip[8][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[8][:sense] == :(>=) - @test m.internalModel.bounding_constr_mip[8][:cnt] == 1 - @test m.internalModel.bounding_constr_mip[9][:rhs] == 18.6 - @test m.internalModel.bounding_constr_mip[9][:vars] == Any[:(x[27])] - @test m.internalModel.bounding_constr_mip[9][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[9][:sense] == :(>=) - @test m.internalModel.bounding_constr_mip[9][:cnt] == 1 - @test m.internalModel.bounding_constr_mip[10][:rhs] == 18.6 - @test m.internalModel.bounding_constr_mip[10][:vars] == Any[:(x[29])] - @test m.internalModel.bounding_constr_mip[10][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[10][:sense] == :(>=) - @test m.internalModel.bounding_constr_mip[10][:cnt] == 1 - @test m.internalModel.bounding_constr_mip[11][:rhs] == 18.6 - @test m.internalModel.bounding_constr_mip[11][:vars] == Any[:(x[31])] - @test m.internalModel.bounding_constr_mip[11][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[11][:sense] == :(>=) - @test m.internalModel.bounding_constr_mip[11][:cnt] == 1 - @test m.internalModel.bounding_constr_mip[12][:rhs] == 18.6 - @test m.internalModel.bounding_constr_mip[12][:vars] == Any[:(x[33])] - @test m.internalModel.bounding_constr_mip[12][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[12][:sense] == :(>=) - @test m.internalModel.bounding_constr_mip[12][:cnt] == 1 - @test m.internalModel.bounding_constr_mip[13][:rhs] == 28.1 - @test m.internalModel.bounding_constr_mip[13][:vars] == Any[:(x[34])] - @test m.internalModel.bounding_constr_mip[13][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[13][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[13][:cnt] == 1 - @test m.internalModel.bounding_constr_mip[14][:rhs] == 28.1 - @test m.internalModel.bounding_constr_mip[14][:vars] == Any[:(x[35])] - @test m.internalModel.bounding_constr_mip[14][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[14][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[14][:cnt] == 1 - @test m.internalModel.bounding_constr_mip[15][:rhs] == 28.1 - @test m.internalModel.bounding_constr_mip[15][:vars] == Any[:(x[36])] - @test m.internalModel.bounding_constr_mip[15][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[15][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[15][:cnt] == 1 - @test m.internalModel.bounding_constr_mip[16][:rhs] == 28.1 - @test m.internalModel.bounding_constr_mip[16][:vars] == Any[:(x[37])] - @test m.internalModel.bounding_constr_mip[16][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[16][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[16][:cnt] == 1 - @test m.internalModel.bounding_constr_mip[17][:rhs] == 28.1 - @test m.internalModel.bounding_constr_mip[17][:vars] == Any[:(x[38])] - @test m.internalModel.bounding_constr_mip[17][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[17][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[17][:cnt] == 1 - @test m.internalModel.bounding_constr_mip[18][:rhs] == 33.2 - @test m.internalModel.bounding_constr_mip[18][:vars] == Any[:(x[42])] - @test m.internalModel.bounding_constr_mip[18][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[18][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[18][:cnt] == 1 - @test m.internalModel.bounding_constr_mip[19][:rhs] == 33.2 - @test m.internalModel.bounding_constr_mip[19][:vars] == Any[:(x[46])] - @test m.internalModel.bounding_constr_mip[19][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[19][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[19][:cnt] == 1 - @test m.internalModel.bounding_constr_mip[20][:rhs] == 33.2 - @test m.internalModel.bounding_constr_mip[20][:vars] == Any[:(x[50])] - @test m.internalModel.bounding_constr_mip[20][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[20][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[20][:cnt] == 1 - @test m.internalModel.bounding_constr_mip[21][:rhs] == 33.2 - @test m.internalModel.bounding_constr_mip[21][:vars] == Any[:(x[54])] - @test m.internalModel.bounding_constr_mip[21][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[21][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[21][:cnt] == 1 + alpine = _build(m) + + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[8])]][:y_idx] == 18 + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[8])]][:id] == 3 + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[8])]][:lifted_constr_ref] == :(x[18] == x[3] * x[8]) + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[8])]][:nonlinear_type] == :BINLIN + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[8])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[8])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[32]), :(x[9])]][:y_idx] == 33 + @test alpine.nonconvex_terms[Expr[:(x[32]), :(x[9])]][:id] == 18 + @test alpine.nonconvex_terms[Expr[:(x[32]), :(x[9])]][:lifted_constr_ref] == :(x[33] == x[32] * x[9]) + @test alpine.nonconvex_terms[Expr[:(x[32]), :(x[9])]][:nonlinear_type] == :INTLIN + @test alpine.nonconvex_terms[Expr[:(x[32]), :(x[9])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[32]), :(x[9])]][:constr_id] == Set(Any[12]) + @test alpine.nonconvex_terms[Expr[:(x[40]), :(x[41])]][:y_idx] == 42 + @test alpine.nonconvex_terms[Expr[:(x[40]), :(x[41])]][:id] == 27 + @test alpine.nonconvex_terms[Expr[:(x[40]), :(x[41])]][:lifted_constr_ref] == :(x[42] == x[40] * x[41]) + @test alpine.nonconvex_terms[Expr[:(x[40]), :(x[41])]][:nonlinear_type] == :BINLIN + @test alpine.nonconvex_terms[Expr[:(x[40]), :(x[41])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[40]), :(x[41])]][:constr_id] == Set(Any[18]) + @test alpine.nonconvex_terms[Expr[:(x[13]), :(x[8])]][:y_idx] == 23 + @test alpine.nonconvex_terms[Expr[:(x[13]), :(x[8])]][:id] == 8 + @test alpine.nonconvex_terms[Expr[:(x[13]), :(x[8])]][:lifted_constr_ref] == :(x[23] == x[13] * x[8]) + @test alpine.nonconvex_terms[Expr[:(x[13]), :(x[8])]][:nonlinear_type] == :INTLIN + @test alpine.nonconvex_terms[Expr[:(x[13]), :(x[8])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[13]), :(x[8])]][:constr_id] == Set(Any[15, 6]) + @test alpine.nonconvex_terms[Expr[:(x[44]), :(x[45])]][:y_idx] == 46 + @test alpine.nonconvex_terms[Expr[:(x[44]), :(x[45])]][:id] == 31 + @test alpine.nonconvex_terms[Expr[:(x[44]), :(x[45])]][:lifted_constr_ref] == :(x[46] == x[44] * x[45]) + @test alpine.nonconvex_terms[Expr[:(x[44]), :(x[45])]][:nonlinear_type] == :BINLIN + @test alpine.nonconvex_terms[Expr[:(x[44]), :(x[45])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[44]), :(x[45])]][:constr_id] == Set(Any[19]) + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[4])]][:y_idx] == 48 + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[4])]][:id] == 33 + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[4])]][:lifted_constr_ref] == :(x[48] == x[3] * x[4]) + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[4])]][:nonlinear_type] == :BINPROD + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[4])]][:y_type] == :Bin + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[4])]][:constr_id] == Set(Any[20]) + @test alpine.nonconvex_terms[Expr[:(x[14]), :(x[9])]][:y_idx] == 24 + @test alpine.nonconvex_terms[Expr[:(x[14]), :(x[9])]][:id] == 9 + @test alpine.nonconvex_terms[Expr[:(x[14]), :(x[9])]][:lifted_constr_ref] == :(x[24] == x[14] * x[9]) + @test alpine.nonconvex_terms[Expr[:(x[14]), :(x[9])]][:nonlinear_type] == :INTLIN + @test alpine.nonconvex_terms[Expr[:(x[14]), :(x[9])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[14]), :(x[9])]][:constr_id] == Set(Any[7, 16]) + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[9])]][:y_idx] == 19 + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[9])]][:id] == 4 + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[9])]][:lifted_constr_ref] == :(x[19] == x[4] * x[9]) + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[9])]][:nonlinear_type] == :BINLIN + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[9])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[9])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[24])]][:y_idx] == 37 + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[24])]][:id] == 22 + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[24])]][:lifted_constr_ref] == :(x[37] == x[4] * x[24]) + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[24])]][:nonlinear_type] == :BINLIN + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[24])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[24])]][:constr_id] == Set(Any[16]) + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[6])]][:y_idx] == 16 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[6])]][:id] == 1 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[6])]][:lifted_constr_ref] == :(x[16] == x[1] * x[6]) + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[6])]][:nonlinear_type] == :BINLIN + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[6])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[6])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[22])]][:y_idx] == 35 + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[22])]][:id] == 20 + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[22])]][:lifted_constr_ref] == :(x[35] == x[2] * x[22]) + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[22])]][:nonlinear_type] == :BINLIN + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[22])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[22])]][:constr_id] == Set(Any[14]) + @test alpine.nonconvex_terms[Expr[:(x[15]), :(x[10])]][:y_idx] == 25 + @test alpine.nonconvex_terms[Expr[:(x[15]), :(x[10])]][:id] == 10 + @test alpine.nonconvex_terms[Expr[:(x[15]), :(x[10])]][:lifted_constr_ref] == :(x[25] == x[15] * x[10]) + @test alpine.nonconvex_terms[Expr[:(x[15]), :(x[10])]][:nonlinear_type] == :INTLIN + @test alpine.nonconvex_terms[Expr[:(x[15]), :(x[10])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[15]), :(x[10])]][:constr_id] == Set(Any[17, 8]) + @test alpine.nonconvex_terms[Expr[:(x[9]), :(x[10])]][:y_idx] == 51 + @test alpine.nonconvex_terms[Expr[:(x[9]), :(x[10])]][:id] == 36 + @test alpine.nonconvex_terms[Expr[:(x[9]), :(x[10])]][:lifted_constr_ref] == :(x[51] == x[9] * x[10]) + @test alpine.nonconvex_terms[Expr[:(x[9]), :(x[10])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[9]), :(x[10])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[9]), :(x[10])]][:constr_id] == Set(Any[21]) + @test alpine.nonconvex_terms[Expr[:(x[28]), :(x[7])]][:y_idx] == 29 + @test alpine.nonconvex_terms[Expr[:(x[28]), :(x[7])]][:id] == 14 + @test alpine.nonconvex_terms[Expr[:(x[28]), :(x[7])]][:lifted_constr_ref] == :(x[29] == x[28] * x[7]) + @test alpine.nonconvex_terms[Expr[:(x[28]), :(x[7])]][:nonlinear_type] == :INTLIN + @test alpine.nonconvex_terms[Expr[:(x[28]), :(x[7])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[28]), :(x[7])]][:constr_id] == Set(Any[10]) + @test alpine.nonconvex_terms[Expr[:(x[30]), :(x[8])]][:y_idx] == 31 + @test alpine.nonconvex_terms[Expr[:(x[30]), :(x[8])]][:id] == 16 + @test alpine.nonconvex_terms[Expr[:(x[30]), :(x[8])]][:lifted_constr_ref] == :(x[31] == x[30] * x[8]) + @test alpine.nonconvex_terms[Expr[:(x[30]), :(x[8])]][:nonlinear_type] == :INTLIN + @test alpine.nonconvex_terms[Expr[:(x[30]), :(x[8])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[30]), :(x[8])]][:constr_id] == Set(Any[11]) + @test alpine.nonconvex_terms[Expr[:(x[8]), :(x[9])]][:y_idx] == 47 + @test alpine.nonconvex_terms[Expr[:(x[8]), :(x[9])]][:id] == 32 + @test alpine.nonconvex_terms[Expr[:(x[8]), :(x[9])]][:lifted_constr_ref] == :(x[47] == x[8] * x[9]) + @test alpine.nonconvex_terms[Expr[:(x[8]), :(x[9])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[8]), :(x[9])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[8]), :(x[9])]][:constr_id] == Set(Any[20]) + @test alpine.nonconvex_terms[Expr[:(x[14]), :(x[15])]][:y_idx] == 32 + @test alpine.nonconvex_terms[Expr[:(x[14]), :(x[15])]][:id] == 17 + @test alpine.nonconvex_terms[Expr[:(x[14]), :(x[15])]][:lifted_constr_ref] == :(x[32] == x[14] * x[15]) + @test alpine.nonconvex_terms[Expr[:(x[14]), :(x[15])]][:nonlinear_type] == :INTPROD + @test alpine.nonconvex_terms[Expr[:(x[14]), :(x[15])]][:y_type] == :Int + @test alpine.nonconvex_terms[Expr[:(x[14]), :(x[15])]][:constr_id] == Set(Any[21, 12]) + @test alpine.nonconvex_terms[Expr[:(x[7]), :(x[8])]][:y_idx] == 43 + @test alpine.nonconvex_terms[Expr[:(x[7]), :(x[8])]][:id] == 28 + @test alpine.nonconvex_terms[Expr[:(x[7]), :(x[8])]][:lifted_constr_ref] == :(x[43] == x[7] * x[8]) + @test alpine.nonconvex_terms[Expr[:(x[7]), :(x[8])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[7]), :(x[8])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[7]), :(x[8])]][:constr_id] == Set(Any[19]) + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[23])]][:y_idx] == 36 + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[23])]][:id] == 21 + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[23])]][:lifted_constr_ref] == :(x[36] == x[3] * x[23]) + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[23])]][:nonlinear_type] == :BINLIN + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[23])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[23])]][:constr_id] == Set(Any[15]) + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[7])]][:y_idx] == 17 + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[7])]][:id] == 2 + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[7])]][:lifted_constr_ref] == :(x[17] == x[2] * x[7]) + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[7])]][:nonlinear_type] == :BINLIN + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[7])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[7])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[12]), :(x[7])]][:y_idx] == 22 + @test alpine.nonconvex_terms[Expr[:(x[12]), :(x[7])]][:id] == 7 + @test alpine.nonconvex_terms[Expr[:(x[12]), :(x[7])]][:lifted_constr_ref] == :(x[22] == x[12] * x[7]) + @test alpine.nonconvex_terms[Expr[:(x[12]), :(x[7])]][:nonlinear_type] == :INTLIN + @test alpine.nonconvex_terms[Expr[:(x[12]), :(x[7])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[12]), :(x[7])]][:constr_id] == Set(Any[14, 5]) + @test alpine.nonconvex_terms[Expr[:(x[11]), :(x[12])]][:y_idx] == 26 + @test alpine.nonconvex_terms[Expr[:(x[11]), :(x[12])]][:id] == 11 + @test alpine.nonconvex_terms[Expr[:(x[11]), :(x[12])]][:lifted_constr_ref] == :(x[26] == x[11] * x[12]) + @test alpine.nonconvex_terms[Expr[:(x[11]), :(x[12])]][:nonlinear_type] == :INTPROD + @test alpine.nonconvex_terms[Expr[:(x[11]), :(x[12])]][:y_type] == :Int + @test alpine.nonconvex_terms[Expr[:(x[11]), :(x[12])]][:constr_id] == Set(Any[9, 18]) + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[5])]][:y_idx] == 52 + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[5])]][:id] == 37 + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[5])]][:lifted_constr_ref] == :(x[52] == x[4] * x[5]) + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[5])]][:nonlinear_type] == :BINPROD + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[5])]][:y_type] == :Bin + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[5])]][:constr_id] == Set(Any[21]) + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[21])]][:y_idx] == 34 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[21])]][:id] == 19 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[21])]][:lifted_constr_ref] == :(x[34] == x[1] * x[21]) + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[21])]][:nonlinear_type] == :BINLIN + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[21])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[21])]][:constr_id] == Set(Any[13]) + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[2])]][:y_idx] == 40 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[2])]][:id] == 25 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[2])]][:lifted_constr_ref] == :(x[40] == x[1] * x[2]) + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[2])]][:nonlinear_type] == :BINPROD + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[2])]][:y_type] == :Bin + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[2])]][:constr_id] == Set(Any[18]) + @test alpine.nonconvex_terms[Expr[:(x[13]), :(x[14])]][:y_idx] == 30 + @test alpine.nonconvex_terms[Expr[:(x[13]), :(x[14])]][:id] == 15 + @test alpine.nonconvex_terms[Expr[:(x[13]), :(x[14])]][:lifted_constr_ref] == :(x[30] == x[13] * x[14]) + @test alpine.nonconvex_terms[Expr[:(x[13]), :(x[14])]][:nonlinear_type] == :INTPROD + @test alpine.nonconvex_terms[Expr[:(x[13]), :(x[14])]][:y_type] == :Int + @test alpine.nonconvex_terms[Expr[:(x[13]), :(x[14])]][:constr_id] == Set(Any[11, 20]) + @test alpine.nonconvex_terms[Expr[:(x[28]), :(x[43])]][:y_idx] == 45 + @test alpine.nonconvex_terms[Expr[:(x[28]), :(x[43])]][:id] == 30 + @test alpine.nonconvex_terms[Expr[:(x[28]), :(x[43])]][:lifted_constr_ref] == :(x[45] == x[28] * x[43]) + @test alpine.nonconvex_terms[Expr[:(x[28]), :(x[43])]][:nonlinear_type] == :INTLIN + @test alpine.nonconvex_terms[Expr[:(x[28]), :(x[43])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[28]), :(x[43])]][:constr_id] == Set(Any[19]) + @test alpine.nonconvex_terms[Expr[:(x[52]), :(x[53])]][:y_idx] == 54 + @test alpine.nonconvex_terms[Expr[:(x[52]), :(x[53])]][:id] == 39 + @test alpine.nonconvex_terms[Expr[:(x[52]), :(x[53])]][:lifted_constr_ref] == :(x[54] == x[52] * x[53]) + @test alpine.nonconvex_terms[Expr[:(x[52]), :(x[53])]][:nonlinear_type] == :BINLIN + @test alpine.nonconvex_terms[Expr[:(x[52]), :(x[53])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[52]), :(x[53])]][:constr_id] == Set(Any[21]) + @test alpine.nonconvex_terms[Expr[:(x[48]), :(x[49])]][:y_idx] == 50 + @test alpine.nonconvex_terms[Expr[:(x[48]), :(x[49])]][:id] == 35 + @test alpine.nonconvex_terms[Expr[:(x[48]), :(x[49])]][:lifted_constr_ref] == :(x[50] == x[48] * x[49]) + @test alpine.nonconvex_terms[Expr[:(x[48]), :(x[49])]][:nonlinear_type] == :BINLIN + @test alpine.nonconvex_terms[Expr[:(x[48]), :(x[49])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[48]), :(x[49])]][:constr_id] == Set(Any[20]) + @test alpine.nonconvex_terms[Expr[:(x[32]), :(x[51])]][:y_idx] == 53 + @test alpine.nonconvex_terms[Expr[:(x[32]), :(x[51])]][:id] == 38 + @test alpine.nonconvex_terms[Expr[:(x[32]), :(x[51])]][:lifted_constr_ref] == :(x[53] == x[32] * x[51]) + @test alpine.nonconvex_terms[Expr[:(x[32]), :(x[51])]][:nonlinear_type] == :INTLIN + @test alpine.nonconvex_terms[Expr[:(x[32]), :(x[51])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[32]), :(x[51])]][:constr_id] == Set(Any[21]) + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[3])]][:y_idx] == 44 + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[3])]][:id] == 29 + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[3])]][:lifted_constr_ref] == :(x[44] == x[2] * x[3]) + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[3])]][:nonlinear_type] == :BINPROD + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[3])]][:y_type] == :Bin + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[3])]][:constr_id] == Set(Any[19]) + @test alpine.nonconvex_terms[Expr[:(x[26]), :(x[39])]][:y_idx] == 41 + @test alpine.nonconvex_terms[Expr[:(x[26]), :(x[39])]][:id] == 26 + @test alpine.nonconvex_terms[Expr[:(x[26]), :(x[39])]][:lifted_constr_ref] == :(x[41] == x[26] * x[39]) + @test alpine.nonconvex_terms[Expr[:(x[26]), :(x[39])]][:nonlinear_type] == :INTLIN + @test alpine.nonconvex_terms[Expr[:(x[26]), :(x[39])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[26]), :(x[39])]][:constr_id] == Set(Any[18]) + @test alpine.nonconvex_terms[Expr[:(x[26]), :(x[6])]][:y_idx] == 27 + @test alpine.nonconvex_terms[Expr[:(x[26]), :(x[6])]][:id] == 12 + @test alpine.nonconvex_terms[Expr[:(x[26]), :(x[6])]][:lifted_constr_ref] == :(x[27] == x[26] * x[6]) + @test alpine.nonconvex_terms[Expr[:(x[26]), :(x[6])]][:nonlinear_type] == :INTLIN + @test alpine.nonconvex_terms[Expr[:(x[26]), :(x[6])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[26]), :(x[6])]][:constr_id] == Set(Any[9]) + @test alpine.nonconvex_terms[Expr[:(x[12]), :(x[13])]][:y_idx] == 28 + @test alpine.nonconvex_terms[Expr[:(x[12]), :(x[13])]][:id] == 13 + @test alpine.nonconvex_terms[Expr[:(x[12]), :(x[13])]][:lifted_constr_ref] == :(x[28] == x[12] * x[13]) + @test alpine.nonconvex_terms[Expr[:(x[12]), :(x[13])]][:nonlinear_type] == :INTPROD + @test alpine.nonconvex_terms[Expr[:(x[12]), :(x[13])]][:y_type] == :Int + @test alpine.nonconvex_terms[Expr[:(x[12]), :(x[13])]][:constr_id] == Set(Any[10, 19]) + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[25])]][:y_idx] == 38 + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[25])]][:id] == 23 + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[25])]][:lifted_constr_ref] == :(x[38] == x[5] * x[25]) + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[25])]][:nonlinear_type] == :BINLIN + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[25])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[25])]][:constr_id] == Set(Any[17]) + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[7])]][:y_idx] == 39 + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[7])]][:id] == 24 + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[7])]][:lifted_constr_ref] == :(x[39] == x[6] * x[7]) + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[7])]][:nonlinear_type] == :BILINEAR + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[7])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[7])]][:constr_id] == Set(Any[18]) + @test alpine.nonconvex_terms[Expr[:(x[30]), :(x[47])]][:y_idx] == 49 + @test alpine.nonconvex_terms[Expr[:(x[30]), :(x[47])]][:id] == 34 + @test alpine.nonconvex_terms[Expr[:(x[30]), :(x[47])]][:lifted_constr_ref] == :(x[49] == x[30] * x[47]) + @test alpine.nonconvex_terms[Expr[:(x[30]), :(x[47])]][:nonlinear_type] == :INTLIN + @test alpine.nonconvex_terms[Expr[:(x[30]), :(x[47])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[30]), :(x[47])]][:constr_id] == Set(Any[20]) + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[10])]][:y_idx] == 20 + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[10])]][:id] == 5 + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[10])]][:lifted_constr_ref] == :(x[20] == x[5] * x[10]) + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[10])]][:nonlinear_type] == :BINLIN + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[10])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[10])]][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[11]), :(x[6])]][:y_idx] == 21 + @test alpine.nonconvex_terms[Expr[:(x[11]), :(x[6])]][:id] == 6 + @test alpine.nonconvex_terms[Expr[:(x[11]), :(x[6])]][:lifted_constr_ref] == :(x[21] == x[11] * x[6]) + @test alpine.nonconvex_terms[Expr[:(x[11]), :(x[6])]][:nonlinear_type] == :INTLIN + @test alpine.nonconvex_terms[Expr[:(x[11]), :(x[6])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[11]), :(x[6])]][:constr_id] == Set(Any[4, 13]) + @test alpine.bounding_constr_mip[1][:rhs] == 3.0 + @test alpine.bounding_constr_mip[1][:vars] == Any[:(x[1]), :(x[2]), :(x[3]), :(x[4]), :(x[5])] + @test alpine.bounding_constr_mip[1][:coefs] == Any[1.0, 1.0, 1.0, 1.0, 1.0] + @test alpine.bounding_constr_mip[1][:sense] == :(>=) + @test alpine.bounding_constr_mip[1][:cnt] == 5 + @test alpine.bounding_constr_mip[2][:rhs] == 10.0 + @test alpine.bounding_constr_mip[2][:vars] == Any[:(x[11]), :(x[12]), :(x[13]), :(x[14]), :(x[15])] + @test alpine.bounding_constr_mip[2][:coefs] == Any[1.0, 1.0, 1.0, 1.0, 1.0] + @test alpine.bounding_constr_mip[2][:sense] == :(>=) + @test alpine.bounding_constr_mip[2][:cnt] == 5 + @test alpine.bounding_constr_mip[3][:rhs] == 8.0 + @test alpine.bounding_constr_mip[3][:vars] == Any[:(x[11]), :(x[12]), :(x[13]), :(x[14]), :(x[15])] + @test alpine.bounding_constr_mip[3][:coefs] == Any[1.0, 1.0, 1.0, 1.0, 1.0] + @test alpine.bounding_constr_mip[3][:sense] == :(>=) + @test alpine.bounding_constr_mip[3][:cnt] == 5 + @test alpine.bounding_constr_mip[4][:rhs] == 17.1 + @test alpine.bounding_constr_mip[4][:vars] == Any[:(x[21])] + @test alpine.bounding_constr_mip[4][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[4][:sense] == :(>=) + @test alpine.bounding_constr_mip[4][:cnt] == 1 + @test alpine.bounding_constr_mip[5][:rhs] == 17.1 + @test alpine.bounding_constr_mip[5][:vars] == Any[:(x[22])] + @test alpine.bounding_constr_mip[5][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[5][:sense] == :(>=) + @test alpine.bounding_constr_mip[5][:cnt] == 1 + @test alpine.bounding_constr_mip[6][:rhs] == 17.1 + @test alpine.bounding_constr_mip[6][:vars] == Any[:(x[23])] + @test alpine.bounding_constr_mip[6][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[6][:sense] == :(>=) + @test alpine.bounding_constr_mip[6][:cnt] == 1 + @test alpine.bounding_constr_mip[7][:rhs] == 17.1 + @test alpine.bounding_constr_mip[7][:vars] == Any[:(x[24])] + @test alpine.bounding_constr_mip[7][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[7][:sense] == :(>=) + @test alpine.bounding_constr_mip[7][:cnt] == 1 + @test alpine.bounding_constr_mip[8][:rhs] == 17.1 + @test alpine.bounding_constr_mip[8][:vars] == Any[:(x[25])] + @test alpine.bounding_constr_mip[8][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[8][:sense] == :(>=) + @test alpine.bounding_constr_mip[8][:cnt] == 1 + @test alpine.bounding_constr_mip[9][:rhs] == 18.6 + @test alpine.bounding_constr_mip[9][:vars] == Any[:(x[27])] + @test alpine.bounding_constr_mip[9][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[9][:sense] == :(>=) + @test alpine.bounding_constr_mip[9][:cnt] == 1 + @test alpine.bounding_constr_mip[10][:rhs] == 18.6 + @test alpine.bounding_constr_mip[10][:vars] == Any[:(x[29])] + @test alpine.bounding_constr_mip[10][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[10][:sense] == :(>=) + @test alpine.bounding_constr_mip[10][:cnt] == 1 + @test alpine.bounding_constr_mip[11][:rhs] == 18.6 + @test alpine.bounding_constr_mip[11][:vars] == Any[:(x[31])] + @test alpine.bounding_constr_mip[11][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[11][:sense] == :(>=) + @test alpine.bounding_constr_mip[11][:cnt] == 1 + @test alpine.bounding_constr_mip[12][:rhs] == 18.6 + @test alpine.bounding_constr_mip[12][:vars] == Any[:(x[33])] + @test alpine.bounding_constr_mip[12][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[12][:sense] == :(>=) + @test alpine.bounding_constr_mip[12][:cnt] == 1 + @test alpine.bounding_constr_mip[13][:rhs] == 28.1 + @test alpine.bounding_constr_mip[13][:vars] == Any[:(x[34])] + @test alpine.bounding_constr_mip[13][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[13][:sense] == :(<=) + @test alpine.bounding_constr_mip[13][:cnt] == 1 + @test alpine.bounding_constr_mip[14][:rhs] == 28.1 + @test alpine.bounding_constr_mip[14][:vars] == Any[:(x[35])] + @test alpine.bounding_constr_mip[14][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[14][:sense] == :(<=) + @test alpine.bounding_constr_mip[14][:cnt] == 1 + @test alpine.bounding_constr_mip[15][:rhs] == 28.1 + @test alpine.bounding_constr_mip[15][:vars] == Any[:(x[36])] + @test alpine.bounding_constr_mip[15][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[15][:sense] == :(<=) + @test alpine.bounding_constr_mip[15][:cnt] == 1 + @test alpine.bounding_constr_mip[16][:rhs] == 28.1 + @test alpine.bounding_constr_mip[16][:vars] == Any[:(x[37])] + @test alpine.bounding_constr_mip[16][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[16][:sense] == :(<=) + @test alpine.bounding_constr_mip[16][:cnt] == 1 + @test alpine.bounding_constr_mip[17][:rhs] == 28.1 + @test alpine.bounding_constr_mip[17][:vars] == Any[:(x[38])] + @test alpine.bounding_constr_mip[17][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[17][:sense] == :(<=) + @test alpine.bounding_constr_mip[17][:cnt] == 1 + @test alpine.bounding_constr_mip[18][:rhs] == 33.2 + @test alpine.bounding_constr_mip[18][:vars] == Any[:(x[42])] + @test alpine.bounding_constr_mip[18][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[18][:sense] == :(<=) + @test alpine.bounding_constr_mip[18][:cnt] == 1 + @test alpine.bounding_constr_mip[19][:rhs] == 33.2 + @test alpine.bounding_constr_mip[19][:vars] == Any[:(x[46])] + @test alpine.bounding_constr_mip[19][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[19][:sense] == :(<=) + @test alpine.bounding_constr_mip[19][:cnt] == 1 + @test alpine.bounding_constr_mip[20][:rhs] == 33.2 + @test alpine.bounding_constr_mip[20][:vars] == Any[:(x[50])] + @test alpine.bounding_constr_mip[20][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[20][:sense] == :(<=) + @test alpine.bounding_constr_mip[20][:cnt] == 1 + @test alpine.bounding_constr_mip[21][:rhs] == 33.2 + @test alpine.bounding_constr_mip[21][:vars] == Any[:(x[54])] + @test alpine.bounding_constr_mip[21][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[21][:sense] == :(<=) + @test alpine.bounding_constr_mip[21][:cnt] == 1 end end @@ -3744,10 +3757,10 @@ end @testset "Expression Parsing || sin/cos" begin @testset "Expression Parsing || sin/cos || specialopts " begin - test_solver=AlpineSolver(minlp_solver=pavito_solver,nlp_solver=IpoptSolver(print_level=0), mip_solver=CbcSolver(logLevel=0),loglevel=100) + test_solver=optimizer_with_attributes(Alpine.Optimizer,"minlp_solver" => JUNIPER,"nlp_solver" => IPOPT, "mip_solver" => CBC,"loglevel" => 100) m = specialopts(solver=test_solver) - JuMP.build(m) + alpine = _build(m) nlk = Vector{Any}(undef, 10) nlk[1] = Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[1]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin)) @@ -3762,8 +3775,8 @@ end nlk[10] = Expr[:(x[1]), :(x[2])] for k in nlk - @test haskey(m.internalModel.nonconvex_terms, k) - isa(k, Dict) && @test k[:operator] == m.internalModel.nonconvex_terms[k][:nonlinear_type] + @test haskey(alpine.nonconvex_terms, k) + isa(k, Dict) && @test k[:operator] == alpine.nonconvex_terms[k][:nonlinear_type] end lk = Vector{Any}(undef, 4) @@ -3773,347 +3786,347 @@ end lk[4] = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(1.0, 2), (1.0, 1)]))) for k in lk - @test haskey(m.internalModel.linear_terms, k) + @test haskey(alpine.linear_terms, k) end - @test m.internalModel.linear_terms[lk[1]][:lifted_constr_ref] == :(x[19] == 0.2 * x[1] + 0.2 * x[2]) - @test m.internalModel.linear_terms[lk[2]][:lifted_constr_ref] == :(x[15] == 0.5 * x[1]) - @test m.internalModel.linear_terms[lk[3]][:lifted_constr_ref] == :(x[17] == 0.2 * x[11]) - @test m.internalModel.linear_terms[lk[4]][:lifted_constr_ref] == :(x[13] == x[1] + x[2]) + @test alpine.linear_terms[lk[1]][:lifted_constr_ref] == :(x[19] == 0.2 * x[1] + 0.2 * x[2]) + @test alpine.linear_terms[lk[2]][:lifted_constr_ref] == :(x[15] == 0.5 * x[1]) + @test alpine.linear_terms[lk[3]][:lifted_constr_ref] == :(x[17] == 0.2 * x[11]) + @test alpine.linear_terms[lk[4]][:lifted_constr_ref] == :(x[13] == x[1] + x[2]) end @testset "Expression Parsing || sin/cos || sincos_p1" begin - test_solver=AlpineSolver(minlp_solver=pavito_solver,nlp_solver=IpoptSolver(print_level=0), mip_solver=CbcSolver(logLevel=0),loglevel=100) + test_solver=optimizer_with_attributes(Alpine.Optimizer,"minlp_solver" => JUNIPER,"nlp_solver" => IPOPT, "mip_solver" => CBC,"loglevel" => 100) m = sincos_p1(solver=test_solver) - JuMP.build(m) - - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[1]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_idx] == 12 - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[1]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:id] == 2 - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[1]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:lifted_constr_ref] == :(x[12] == sin(x[1])) - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[1]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:nonlinear_type] == :sin - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[1]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[1]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:constr_id] == Set(Any[0, 10, 1]) - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[4]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_idx] == 18 - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[4]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:id] == 8 - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[4]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:lifted_constr_ref] == :(x[18] == sin(x[4])) - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[4]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:nonlinear_type] == :sin - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[4]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[4]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:constr_id] == Set(Any[0, 4, 13]) - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[2]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:y_idx] == 13 - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[2]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:id] == 3 - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[2]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:lifted_constr_ref] == :(x[13] == cos(x[2])) - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[2]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:nonlinear_type] == :cos - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[2]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[2]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[7]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_idx] == 24 - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[7]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:id] == 14 - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[7]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:lifted_constr_ref] == :(x[24] == sin(x[7])) - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[7]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:nonlinear_type] == :sin - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[7]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[7]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:constr_id] == Set(Any[0, 7, 16]) - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[7]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:y_idx] == 23 - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[7]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:id] == 13 - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[7]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:lifted_constr_ref] == :(x[23] == cos(x[7])) - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[7]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:nonlinear_type] == :cos - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[7]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[7]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[4]), :(x[16])]][:y_idx] == 33 - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[4]), :(x[16])]][:id] == 23 - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[4]), :(x[16])]][:lifted_constr_ref] == :(x[33] == x[3] * x[4] * x[16]) - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[4]), :(x[16])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[4]), :(x[16])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[3]), :(x[4]), :(x[16])]][:constr_id] == Set(Any[3, 12]) - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[2]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_idx] == 14 - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[2]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:id] == 4 - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[2]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:lifted_constr_ref] == :(x[14] == sin(x[2])) - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[2]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:nonlinear_type] == :sin - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[2]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[2]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:constr_id] == Set(Any[0, 2, 11]) - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[5]), :(x[18])]][:y_idx] == 34 - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[5]), :(x[18])]][:id] == 24 - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[5]), :(x[18])]][:lifted_constr_ref] == :(x[34] == x[4] * x[5] * x[18]) - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[5]), :(x[18])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[5]), :(x[18])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[4]), :(x[5]), :(x[18])]][:constr_id] == Set(Any[4, 13]) - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[5]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:y_idx] == 19 - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[5]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:id] == 9 - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[5]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:lifted_constr_ref] == :(x[19] == cos(x[5])) - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[5]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:nonlinear_type] == :cos - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[5]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[5]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[1]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:y_idx] == 11 - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[1]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:id] == 1 - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[1]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:lifted_constr_ref] == :(x[11] == cos(x[1])) - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[1]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:nonlinear_type] == :cos - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[1]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[1]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[10]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:y_idx] == 29 - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[10]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:id] == 19 - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[10]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:lifted_constr_ref] == :(x[29] == cos(x[10])) - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[10]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:nonlinear_type] == :cos - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[10]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[10]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[9]), :(x[10]), :(x[28])]][:y_idx] == 39 - @test m.internalModel.nonconvex_terms[Expr[:(x[9]), :(x[10]), :(x[28])]][:id] == 29 - @test m.internalModel.nonconvex_terms[Expr[:(x[9]), :(x[10]), :(x[28])]][:lifted_constr_ref] == :(x[39] == x[9] * x[10] * x[28]) - @test m.internalModel.nonconvex_terms[Expr[:(x[9]), :(x[10]), :(x[28])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[9]), :(x[10]), :(x[28])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[9]), :(x[10]), :(x[28])]][:constr_id] == Set(Any[9, 18]) - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[14])]][:y_idx] == 32 - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[14])]][:id] == 22 - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[14])]][:lifted_constr_ref] == :(x[32] == x[2] * x[3] * x[14]) - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[14])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[14])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[14])]][:constr_id] == Set(Any[2, 11]) - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[12])]][:y_idx] == 31 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[12])]][:id] == 21 - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[12])]][:lifted_constr_ref] == :(x[31] == x[1] * x[2] * x[12]) - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[12])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[12])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[12])]][:constr_id] == Set(Any[10, 1]) - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[10]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_idx] == 30 - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[10]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:id] == 20 - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[10]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:lifted_constr_ref] == :(x[30] == sin(x[10])) - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[10]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:nonlinear_type] == :sin - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[10]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[10]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[8]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_idx] == 26 - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[8]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:id] == 16 - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[8]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:lifted_constr_ref] == :(x[26] == sin(x[8])) - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[8]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:nonlinear_type] == :sin - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[8]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[8]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:constr_id] == Set(Any[0, 17, 8]) - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[6]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_idx] == 22 - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[6]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:id] == 12 - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[6]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:lifted_constr_ref] == :(x[22] == sin(x[6])) - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[6]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:nonlinear_type] == :sin - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[6]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[6]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:constr_id] == Set(Any[0, 15, 6]) - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[9]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_idx] == 28 - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[9]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:id] == 18 - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[9]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:lifted_constr_ref] == :(x[28] == sin(x[9])) - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[9]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:nonlinear_type] == :sin - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[9]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[9]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:constr_id] == Set(Any[0, 9, 18]) - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[5]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_idx] == 20 - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[5]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:id] == 10 - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[5]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:lifted_constr_ref] == :(x[20] == sin(x[5])) - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[5]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:nonlinear_type] == :sin - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[5]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[5]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:constr_id] == Set(Any[0, 14, 5]) - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[4]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:y_idx] == 17 - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[4]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:id] == 7 - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[4]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:lifted_constr_ref] == :(x[17] == cos(x[4])) - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[4]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:nonlinear_type] == :cos - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[4]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[4]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[3]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_idx] == 16 - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[3]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:id] == 6 - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[3]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:lifted_constr_ref] == :(x[16] == sin(x[3])) - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[3]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:nonlinear_type] == :sin - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[3]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[3]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:constr_id] == Set(Any[0, 3, 12]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[7]), :(x[22])]][:y_idx] == 36 - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[7]), :(x[22])]][:id] == 26 - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[7]), :(x[22])]][:lifted_constr_ref] == :(x[36] == x[6] * x[7] * x[22]) - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[7]), :(x[22])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[7]), :(x[22])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[6]), :(x[7]), :(x[22])]][:constr_id] == Set(Any[15, 6]) - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[6]), :(x[20])]][:y_idx] == 35 - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[6]), :(x[20])]][:id] == 25 - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[6]), :(x[20])]][:lifted_constr_ref] == :(x[35] == x[5] * x[6] * x[20]) - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[6]), :(x[20])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[6]), :(x[20])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[5]), :(x[6]), :(x[20])]][:constr_id] == Set(Any[14, 5]) - @test m.internalModel.nonconvex_terms[Expr[:(x[8]), :(x[9]), :(x[26])]][:y_idx] == 38 - @test m.internalModel.nonconvex_terms[Expr[:(x[8]), :(x[9]), :(x[26])]][:id] == 28 - @test m.internalModel.nonconvex_terms[Expr[:(x[8]), :(x[9]), :(x[26])]][:lifted_constr_ref] == :(x[38] == x[8] * x[9] * x[26]) - @test m.internalModel.nonconvex_terms[Expr[:(x[8]), :(x[9]), :(x[26])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[8]), :(x[9]), :(x[26])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[8]), :(x[9]), :(x[26])]][:constr_id] == Set(Any[17, 8]) - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[8]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:y_idx] == 25 - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[8]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:id] == 15 - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[8]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:lifted_constr_ref] == :(x[25] == cos(x[8])) - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[8]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:nonlinear_type] == :cos - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[8]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[8]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[3]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:y_idx] == 15 - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[3]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:id] == 5 - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[3]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:lifted_constr_ref] == :(x[15] == cos(x[3])) - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[3]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:nonlinear_type] == :cos - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[3]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[3]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[9]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:y_idx] == 27 - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[9]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:id] == 17 - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[9]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:lifted_constr_ref] == :(x[27] == cos(x[9])) - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[9]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:nonlinear_type] == :cos - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[9]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[9]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[6]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:y_idx] == 21 - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[6]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:id] == 11 - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[6]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:lifted_constr_ref] == :(x[21] == cos(x[6])) - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[6]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:nonlinear_type] == :cos - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[6]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[6]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:constr_id] == Set(Any[0]) - @test m.internalModel.nonconvex_terms[Expr[:(x[7]), :(x[8]), :(x[24])]][:y_idx] == 37 - @test m.internalModel.nonconvex_terms[Expr[:(x[7]), :(x[8]), :(x[24])]][:id] == 27 - @test m.internalModel.nonconvex_terms[Expr[:(x[7]), :(x[8]), :(x[24])]][:lifted_constr_ref] == :(x[37] == x[7] * x[8] * x[24]) - @test m.internalModel.nonconvex_terms[Expr[:(x[7]), :(x[8]), :(x[24])]][:nonlinear_type] == :MULTILINEAR - @test m.internalModel.nonconvex_terms[Expr[:(x[7]), :(x[8]), :(x[24])]][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Expr[:(x[7]), :(x[8]), :(x[24])]][:constr_id] == Set(Any[7, 16]) - @test m.internalModel.bounding_constr_mip[1][:rhs] == 0.32 - @test m.internalModel.bounding_constr_mip[1][:vars] == Any[:(x[31])] - @test m.internalModel.bounding_constr_mip[1][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[1][:sense] == :(>=) - @test m.internalModel.bounding_constr_mip[1][:cnt] == 1 - @test m.internalModel.bounding_constr_mip[2][:rhs] == 0.32 - @test m.internalModel.bounding_constr_mip[2][:vars] == Any[:(x[32])] - @test m.internalModel.bounding_constr_mip[2][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[2][:sense] == :(>=) - @test m.internalModel.bounding_constr_mip[2][:cnt] == 1 - @test m.internalModel.bounding_constr_mip[3][:rhs] == 0.32 - @test m.internalModel.bounding_constr_mip[3][:vars] == Any[:(x[33])] - @test m.internalModel.bounding_constr_mip[3][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[3][:sense] == :(>=) - @test m.internalModel.bounding_constr_mip[3][:cnt] == 1 - @test m.internalModel.bounding_constr_mip[4][:rhs] == 0.32 - @test m.internalModel.bounding_constr_mip[4][:vars] == Any[:(x[34])] - @test m.internalModel.bounding_constr_mip[4][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[4][:sense] == :(>=) - @test m.internalModel.bounding_constr_mip[4][:cnt] == 1 - @test m.internalModel.bounding_constr_mip[5][:rhs] == 0.32 - @test m.internalModel.bounding_constr_mip[5][:vars] == Any[:(x[35])] - @test m.internalModel.bounding_constr_mip[5][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[5][:sense] == :(>=) - @test m.internalModel.bounding_constr_mip[5][:cnt] == 1 - @test m.internalModel.bounding_constr_mip[6][:rhs] == 0.32 - @test m.internalModel.bounding_constr_mip[6][:vars] == Any[:(x[36])] - @test m.internalModel.bounding_constr_mip[6][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[6][:sense] == :(>=) - @test m.internalModel.bounding_constr_mip[6][:cnt] == 1 - @test m.internalModel.bounding_constr_mip[7][:rhs] == 0.32 - @test m.internalModel.bounding_constr_mip[7][:vars] == Any[:(x[37])] - @test m.internalModel.bounding_constr_mip[7][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[7][:sense] == :(>=) - @test m.internalModel.bounding_constr_mip[7][:cnt] == 1 - @test m.internalModel.bounding_constr_mip[8][:rhs] == 0.32 - @test m.internalModel.bounding_constr_mip[8][:vars] == Any[:(x[38])] - @test m.internalModel.bounding_constr_mip[8][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[8][:sense] == :(>=) - @test m.internalModel.bounding_constr_mip[8][:cnt] == 1 - @test m.internalModel.bounding_constr_mip[9][:rhs] == 0.32 - @test m.internalModel.bounding_constr_mip[9][:vars] == Any[:(x[39])] - @test m.internalModel.bounding_constr_mip[9][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[9][:sense] == :(>=) - @test m.internalModel.bounding_constr_mip[9][:cnt] == 1 - @test m.internalModel.bounding_constr_mip[10][:rhs] == 0.42 - @test m.internalModel.bounding_constr_mip[10][:vars] == Any[:(x[31])] - @test m.internalModel.bounding_constr_mip[10][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[10][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[10][:cnt] == 1 - @test m.internalModel.bounding_constr_mip[11][:rhs] == 0.42 - @test m.internalModel.bounding_constr_mip[11][:vars] == Any[:(x[32])] - @test m.internalModel.bounding_constr_mip[11][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[11][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[11][:cnt] == 1 - @test m.internalModel.bounding_constr_mip[12][:rhs] == 0.42 - @test m.internalModel.bounding_constr_mip[12][:vars] == Any[:(x[33])] - @test m.internalModel.bounding_constr_mip[12][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[12][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[12][:cnt] == 1 - @test m.internalModel.bounding_constr_mip[13][:rhs] == 0.42 - @test m.internalModel.bounding_constr_mip[13][:vars] == Any[:(x[34])] - @test m.internalModel.bounding_constr_mip[13][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[13][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[13][:cnt] == 1 - @test m.internalModel.bounding_constr_mip[14][:rhs] == 0.42 - @test m.internalModel.bounding_constr_mip[14][:vars] == Any[:(x[35])] - @test m.internalModel.bounding_constr_mip[14][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[14][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[14][:cnt] == 1 - @test m.internalModel.bounding_constr_mip[15][:rhs] == 0.42 - @test m.internalModel.bounding_constr_mip[15][:vars] == Any[:(x[36])] - @test m.internalModel.bounding_constr_mip[15][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[15][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[15][:cnt] == 1 - @test m.internalModel.bounding_constr_mip[16][:rhs] == 0.42 - @test m.internalModel.bounding_constr_mip[16][:vars] == Any[:(x[37])] - @test m.internalModel.bounding_constr_mip[16][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[16][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[16][:cnt] == 1 - @test m.internalModel.bounding_constr_mip[17][:rhs] == 0.42 - @test m.internalModel.bounding_constr_mip[17][:vars] == Any[:(x[38])] - @test m.internalModel.bounding_constr_mip[17][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[17][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[17][:cnt] == 1 - @test m.internalModel.bounding_constr_mip[18][:rhs] == 0.42 - @test m.internalModel.bounding_constr_mip[18][:vars] == Any[:(x[39])] - @test m.internalModel.bounding_constr_mip[18][:coefs] == Any[1.0] - @test m.internalModel.bounding_constr_mip[18][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[18][:cnt] == 1 + alpine = _build(m) + + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[1]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_idx] == 12 + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[1]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:id] == 2 + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[1]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:lifted_constr_ref] == :(x[12] == sin(x[1])) + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[1]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:nonlinear_type] == :sin + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[1]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_type] == :Cont + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[1]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:constr_id] == Set(Any[0, 10, 1]) + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[4]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_idx] == 18 + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[4]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:id] == 8 + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[4]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:lifted_constr_ref] == :(x[18] == sin(x[4])) + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[4]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:nonlinear_type] == :sin + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[4]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_type] == :Cont + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[4]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:constr_id] == Set(Any[0, 4, 13]) + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[2]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:y_idx] == 13 + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[2]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:id] == 3 + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[2]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:lifted_constr_ref] == :(x[13] == cos(x[2])) + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[2]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:nonlinear_type] == :cos + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[2]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:y_type] == :Cont + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[2]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[7]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_idx] == 24 + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[7]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:id] == 14 + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[7]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:lifted_constr_ref] == :(x[24] == sin(x[7])) + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[7]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:nonlinear_type] == :sin + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[7]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_type] == :Cont + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[7]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:constr_id] == Set(Any[0, 7, 16]) + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[7]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:y_idx] == 23 + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[7]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:id] == 13 + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[7]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:lifted_constr_ref] == :(x[23] == cos(x[7])) + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[7]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:nonlinear_type] == :cos + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[7]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:y_type] == :Cont + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[7]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[4]), :(x[16])]][:y_idx] == 33 + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[4]), :(x[16])]][:id] == 23 + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[4]), :(x[16])]][:lifted_constr_ref] == :(x[33] == x[3] * x[4] * x[16]) + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[4]), :(x[16])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[4]), :(x[16])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[3]), :(x[4]), :(x[16])]][:constr_id] == Set(Any[3, 12]) + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[2]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_idx] == 14 + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[2]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:id] == 4 + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[2]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:lifted_constr_ref] == :(x[14] == sin(x[2])) + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[2]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:nonlinear_type] == :sin + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[2]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_type] == :Cont + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[2]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:constr_id] == Set(Any[0, 2, 11]) + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[5]), :(x[18])]][:y_idx] == 34 + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[5]), :(x[18])]][:id] == 24 + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[5]), :(x[18])]][:lifted_constr_ref] == :(x[34] == x[4] * x[5] * x[18]) + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[5]), :(x[18])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[5]), :(x[18])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[4]), :(x[5]), :(x[18])]][:constr_id] == Set(Any[4, 13]) + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[5]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:y_idx] == 19 + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[5]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:id] == 9 + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[5]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:lifted_constr_ref] == :(x[19] == cos(x[5])) + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[5]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:nonlinear_type] == :cos + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[5]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:y_type] == :Cont + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[5]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[1]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:y_idx] == 11 + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[1]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:id] == 1 + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[1]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:lifted_constr_ref] == :(x[11] == cos(x[1])) + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[1]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:nonlinear_type] == :cos + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[1]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:y_type] == :Cont + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[1]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[10]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:y_idx] == 29 + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[10]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:id] == 19 + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[10]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:lifted_constr_ref] == :(x[29] == cos(x[10])) + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[10]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:nonlinear_type] == :cos + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[10]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:y_type] == :Cont + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[10]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[9]), :(x[10]), :(x[28])]][:y_idx] == 39 + @test alpine.nonconvex_terms[Expr[:(x[9]), :(x[10]), :(x[28])]][:id] == 29 + @test alpine.nonconvex_terms[Expr[:(x[9]), :(x[10]), :(x[28])]][:lifted_constr_ref] == :(x[39] == x[9] * x[10] * x[28]) + @test alpine.nonconvex_terms[Expr[:(x[9]), :(x[10]), :(x[28])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[9]), :(x[10]), :(x[28])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[9]), :(x[10]), :(x[28])]][:constr_id] == Set(Any[9, 18]) + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[14])]][:y_idx] == 32 + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[14])]][:id] == 22 + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[14])]][:lifted_constr_ref] == :(x[32] == x[2] * x[3] * x[14]) + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[14])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[14])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[2]), :(x[3]), :(x[14])]][:constr_id] == Set(Any[2, 11]) + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[12])]][:y_idx] == 31 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[12])]][:id] == 21 + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[12])]][:lifted_constr_ref] == :(x[31] == x[1] * x[2] * x[12]) + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[12])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[12])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[1]), :(x[2]), :(x[12])]][:constr_id] == Set(Any[10, 1]) + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[10]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_idx] == 30 + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[10]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:id] == 20 + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[10]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:lifted_constr_ref] == :(x[30] == sin(x[10])) + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[10]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:nonlinear_type] == :sin + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[10]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_type] == :Cont + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[10]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[8]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_idx] == 26 + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[8]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:id] == 16 + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[8]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:lifted_constr_ref] == :(x[26] == sin(x[8])) + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[8]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:nonlinear_type] == :sin + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[8]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_type] == :Cont + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[8]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:constr_id] == Set(Any[0, 17, 8]) + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[6]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_idx] == 22 + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[6]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:id] == 12 + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[6]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:lifted_constr_ref] == :(x[22] == sin(x[6])) + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[6]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:nonlinear_type] == :sin + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[6]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_type] == :Cont + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[6]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:constr_id] == Set(Any[0, 15, 6]) + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[9]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_idx] == 28 + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[9]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:id] == 18 + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[9]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:lifted_constr_ref] == :(x[28] == sin(x[9])) + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[9]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:nonlinear_type] == :sin + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[9]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_type] == :Cont + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[9]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:constr_id] == Set(Any[0, 9, 18]) + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[5]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_idx] == 20 + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[5]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:id] == 10 + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[5]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:lifted_constr_ref] == :(x[20] == sin(x[5])) + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[5]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:nonlinear_type] == :sin + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[5]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_type] == :Cont + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[5]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:constr_id] == Set(Any[0, 14, 5]) + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[4]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:y_idx] == 17 + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[4]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:id] == 7 + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[4]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:lifted_constr_ref] == :(x[17] == cos(x[4])) + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[4]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:nonlinear_type] == :cos + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[4]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:y_type] == :Cont + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[4]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[3]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_idx] == 16 + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[3]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:id] == 6 + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[3]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:lifted_constr_ref] == :(x[16] == sin(x[3])) + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[3]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:nonlinear_type] == :sin + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[3]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_type] == :Cont + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[3]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:constr_id] == Set(Any[0, 3, 12]) + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[7]), :(x[22])]][:y_idx] == 36 + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[7]), :(x[22])]][:id] == 26 + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[7]), :(x[22])]][:lifted_constr_ref] == :(x[36] == x[6] * x[7] * x[22]) + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[7]), :(x[22])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[7]), :(x[22])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[6]), :(x[7]), :(x[22])]][:constr_id] == Set(Any[15, 6]) + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[6]), :(x[20])]][:y_idx] == 35 + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[6]), :(x[20])]][:id] == 25 + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[6]), :(x[20])]][:lifted_constr_ref] == :(x[35] == x[5] * x[6] * x[20]) + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[6]), :(x[20])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[6]), :(x[20])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[5]), :(x[6]), :(x[20])]][:constr_id] == Set(Any[14, 5]) + @test alpine.nonconvex_terms[Expr[:(x[8]), :(x[9]), :(x[26])]][:y_idx] == 38 + @test alpine.nonconvex_terms[Expr[:(x[8]), :(x[9]), :(x[26])]][:id] == 28 + @test alpine.nonconvex_terms[Expr[:(x[8]), :(x[9]), :(x[26])]][:lifted_constr_ref] == :(x[38] == x[8] * x[9] * x[26]) + @test alpine.nonconvex_terms[Expr[:(x[8]), :(x[9]), :(x[26])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[8]), :(x[9]), :(x[26])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[8]), :(x[9]), :(x[26])]][:constr_id] == Set(Any[17, 8]) + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[8]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:y_idx] == 25 + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[8]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:id] == 15 + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[8]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:lifted_constr_ref] == :(x[25] == cos(x[8])) + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[8]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:nonlinear_type] == :cos + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[8]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:y_type] == :Cont + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[8]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[3]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:y_idx] == 15 + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[3]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:id] == 5 + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[3]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:lifted_constr_ref] == :(x[15] == cos(x[3])) + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[3]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:nonlinear_type] == :cos + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[3]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:y_type] == :Cont + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[3]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[9]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:y_idx] == 27 + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[9]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:id] == 17 + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[9]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:lifted_constr_ref] == :(x[27] == cos(x[9])) + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[9]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:nonlinear_type] == :cos + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[9]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:y_type] == :Cont + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[9]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[6]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:y_idx] == 21 + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[6]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:id] == 11 + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[6]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:lifted_constr_ref] == :(x[21] == cos(x[6])) + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[6]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:nonlinear_type] == :cos + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[6]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:y_type] == :Cont + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[6]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:constr_id] == Set(Any[0]) + @test alpine.nonconvex_terms[Expr[:(x[7]), :(x[8]), :(x[24])]][:y_idx] == 37 + @test alpine.nonconvex_terms[Expr[:(x[7]), :(x[8]), :(x[24])]][:id] == 27 + @test alpine.nonconvex_terms[Expr[:(x[7]), :(x[8]), :(x[24])]][:lifted_constr_ref] == :(x[37] == x[7] * x[8] * x[24]) + @test alpine.nonconvex_terms[Expr[:(x[7]), :(x[8]), :(x[24])]][:nonlinear_type] == :MULTILINEAR + @test alpine.nonconvex_terms[Expr[:(x[7]), :(x[8]), :(x[24])]][:y_type] == :Cont + @test alpine.nonconvex_terms[Expr[:(x[7]), :(x[8]), :(x[24])]][:constr_id] == Set(Any[7, 16]) + @test alpine.bounding_constr_mip[1][:rhs] == 0.32 + @test alpine.bounding_constr_mip[1][:vars] == Any[:(x[31])] + @test alpine.bounding_constr_mip[1][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[1][:sense] == :(>=) + @test alpine.bounding_constr_mip[1][:cnt] == 1 + @test alpine.bounding_constr_mip[2][:rhs] == 0.32 + @test alpine.bounding_constr_mip[2][:vars] == Any[:(x[32])] + @test alpine.bounding_constr_mip[2][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[2][:sense] == :(>=) + @test alpine.bounding_constr_mip[2][:cnt] == 1 + @test alpine.bounding_constr_mip[3][:rhs] == 0.32 + @test alpine.bounding_constr_mip[3][:vars] == Any[:(x[33])] + @test alpine.bounding_constr_mip[3][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[3][:sense] == :(>=) + @test alpine.bounding_constr_mip[3][:cnt] == 1 + @test alpine.bounding_constr_mip[4][:rhs] == 0.32 + @test alpine.bounding_constr_mip[4][:vars] == Any[:(x[34])] + @test alpine.bounding_constr_mip[4][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[4][:sense] == :(>=) + @test alpine.bounding_constr_mip[4][:cnt] == 1 + @test alpine.bounding_constr_mip[5][:rhs] == 0.32 + @test alpine.bounding_constr_mip[5][:vars] == Any[:(x[35])] + @test alpine.bounding_constr_mip[5][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[5][:sense] == :(>=) + @test alpine.bounding_constr_mip[5][:cnt] == 1 + @test alpine.bounding_constr_mip[6][:rhs] == 0.32 + @test alpine.bounding_constr_mip[6][:vars] == Any[:(x[36])] + @test alpine.bounding_constr_mip[6][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[6][:sense] == :(>=) + @test alpine.bounding_constr_mip[6][:cnt] == 1 + @test alpine.bounding_constr_mip[7][:rhs] == 0.32 + @test alpine.bounding_constr_mip[7][:vars] == Any[:(x[37])] + @test alpine.bounding_constr_mip[7][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[7][:sense] == :(>=) + @test alpine.bounding_constr_mip[7][:cnt] == 1 + @test alpine.bounding_constr_mip[8][:rhs] == 0.32 + @test alpine.bounding_constr_mip[8][:vars] == Any[:(x[38])] + @test alpine.bounding_constr_mip[8][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[8][:sense] == :(>=) + @test alpine.bounding_constr_mip[8][:cnt] == 1 + @test alpine.bounding_constr_mip[9][:rhs] == 0.32 + @test alpine.bounding_constr_mip[9][:vars] == Any[:(x[39])] + @test alpine.bounding_constr_mip[9][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[9][:sense] == :(>=) + @test alpine.bounding_constr_mip[9][:cnt] == 1 + @test alpine.bounding_constr_mip[10][:rhs] == 0.42 + @test alpine.bounding_constr_mip[10][:vars] == Any[:(x[31])] + @test alpine.bounding_constr_mip[10][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[10][:sense] == :(<=) + @test alpine.bounding_constr_mip[10][:cnt] == 1 + @test alpine.bounding_constr_mip[11][:rhs] == 0.42 + @test alpine.bounding_constr_mip[11][:vars] == Any[:(x[32])] + @test alpine.bounding_constr_mip[11][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[11][:sense] == :(<=) + @test alpine.bounding_constr_mip[11][:cnt] == 1 + @test alpine.bounding_constr_mip[12][:rhs] == 0.42 + @test alpine.bounding_constr_mip[12][:vars] == Any[:(x[33])] + @test alpine.bounding_constr_mip[12][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[12][:sense] == :(<=) + @test alpine.bounding_constr_mip[12][:cnt] == 1 + @test alpine.bounding_constr_mip[13][:rhs] == 0.42 + @test alpine.bounding_constr_mip[13][:vars] == Any[:(x[34])] + @test alpine.bounding_constr_mip[13][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[13][:sense] == :(<=) + @test alpine.bounding_constr_mip[13][:cnt] == 1 + @test alpine.bounding_constr_mip[14][:rhs] == 0.42 + @test alpine.bounding_constr_mip[14][:vars] == Any[:(x[35])] + @test alpine.bounding_constr_mip[14][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[14][:sense] == :(<=) + @test alpine.bounding_constr_mip[14][:cnt] == 1 + @test alpine.bounding_constr_mip[15][:rhs] == 0.42 + @test alpine.bounding_constr_mip[15][:vars] == Any[:(x[36])] + @test alpine.bounding_constr_mip[15][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[15][:sense] == :(<=) + @test alpine.bounding_constr_mip[15][:cnt] == 1 + @test alpine.bounding_constr_mip[16][:rhs] == 0.42 + @test alpine.bounding_constr_mip[16][:vars] == Any[:(x[37])] + @test alpine.bounding_constr_mip[16][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[16][:sense] == :(<=) + @test alpine.bounding_constr_mip[16][:cnt] == 1 + @test alpine.bounding_constr_mip[17][:rhs] == 0.42 + @test alpine.bounding_constr_mip[17][:vars] == Any[:(x[38])] + @test alpine.bounding_constr_mip[17][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[17][:sense] == :(<=) + @test alpine.bounding_constr_mip[17][:cnt] == 1 + @test alpine.bounding_constr_mip[18][:rhs] == 0.42 + @test alpine.bounding_constr_mip[18][:vars] == Any[:(x[39])] + @test alpine.bounding_constr_mip[18][:coefs] == Any[1.0] + @test alpine.bounding_constr_mip[18][:sense] == :(<=) + @test alpine.bounding_constr_mip[18][:cnt] == 1 end @testset "Expression Parsing || sin/cos || trig" begin - test_solver=AlpineSolver(minlp_solver=pavito_solver,nlp_solver=IpoptSolver(print_level=0), mip_solver=CbcSolver(logLevel=0),loglevel=100) + test_solver=optimizer_with_attributes(Alpine.Optimizer,"minlp_solver" => JUNIPER,"nlp_solver" => IPOPT, "mip_solver" => CBC,"loglevel" => 100) m = trig(solver=test_solver) - JuMP.build(m) - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[7]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_idx] == 8 - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[7]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:id] == 3 - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[7]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:lifted_constr_ref] == :(x[8] == sin(x[7])) - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[7]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:nonlinear_type] == :sin - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[7]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[7]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:constr_id] == Set(Any[1]) - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[9]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:y_idx] == 10 - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[9]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:id] == 4 - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[9]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:lifted_constr_ref] == :(x[10] == cos(x[9])) - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[9]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:nonlinear_type] == :cos - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[9]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[9]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:constr_id] == Set(Any[1]) - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[3]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_idx] == 4 - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[3]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:id] == 1 - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[3]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:lifted_constr_ref] == :(x[4] == sin(x[3])) - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[3]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:nonlinear_type] == :sin - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[3]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[3]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:constr_id] == Set(Any[1]) - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[2]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_idx] == 11 - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[2]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:id] == 5 - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[2]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:lifted_constr_ref] == :(x[11] == sin(x[2])) - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[2]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:nonlinear_type] == :sin - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[2]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[2]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:constr_id] == Set(Any[2]) - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[5]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:y_idx] == 6 - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[5]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:id] == 2 - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[5]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:lifted_constr_ref] == :(x[6] == cos(x[5])) - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[5]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:nonlinear_type] == :cos - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[5]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:y_type] == :Cont - @test m.internalModel.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[5]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:constr_id] == Set(Any[1]) + alpine = _build(m) + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[7]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_idx] == 8 + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[7]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:id] == 3 + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[7]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:lifted_constr_ref] == :(x[8] == sin(x[7])) + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[7]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:nonlinear_type] == :sin + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[7]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_type] == :Cont + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[7]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:constr_id] == Set(Any[1]) + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[9]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:y_idx] == 10 + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[9]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:id] == 4 + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[9]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:lifted_constr_ref] == :(x[10] == cos(x[9])) + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[9]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:nonlinear_type] == :cos + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[9]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:y_type] == :Cont + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[9]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:constr_id] == Set(Any[1]) + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[3]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_idx] == 4 + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[3]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:id] == 1 + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[3]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:lifted_constr_ref] == :(x[4] == sin(x[3])) + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[3]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:nonlinear_type] == :sin + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[3]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_type] == :Cont + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[3]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:constr_id] == Set(Any[1]) + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[2]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_idx] == 11 + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[2]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:id] == 5 + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[2]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:lifted_constr_ref] == :(x[11] == sin(x[2])) + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[2]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:nonlinear_type] == :sin + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[2]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:y_type] == :Cont + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[2]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :sin))][:constr_id] == Set(Any[2]) + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[5]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:y_idx] == 6 + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[5]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:id] == 2 + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[5]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:lifted_constr_ref] == :(x[6] == cos(x[5])) + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[5]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:nonlinear_type] == :cos + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[5]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:y_type] == :Cont + @test alpine.nonconvex_terms[Dict{Symbol,Any}(Pair{Symbol,Any}(:vars, Any[5]),Pair{Symbol,Any}(:scalar, 1.0),Pair{Symbol,Any}(:operator, :cos))][:constr_id] == Set(Any[1]) lk1 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(13.0, 2)]))) - @test m.internalModel.linear_terms[lk1][:y_idx] == 5 - @test m.internalModel.linear_terms[lk1][:id] == 2 - @test m.internalModel.linear_terms[lk1][:y_type] == :(Cont) + @test alpine.linear_terms[lk1][:y_idx] == 5 + @test alpine.linear_terms[lk1][:id] == 2 + @test alpine.linear_terms[lk1][:y_type] == :(Cont) lk2 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(11.0, 2)]))) - @test m.internalModel.linear_terms[lk2][:y_idx] == 3 - @test m.internalModel.linear_terms[lk2][:id] == 1 - @test m.internalModel.linear_terms[lk2][:y_type] == :(Cont) + @test alpine.linear_terms[lk2][:y_idx] == 3 + @test alpine.linear_terms[lk2][:id] == 1 + @test alpine.linear_terms[lk2][:y_type] == :(Cont) lk3 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(19.0, 2)]))) - @test m.internalModel.linear_terms[lk3][:y_idx] == 9 - @test m.internalModel.linear_terms[lk3][:id] == 4 - @test m.internalModel.linear_terms[lk3][:y_type] == :(Cont) + @test alpine.linear_terms[lk3][:y_idx] == 9 + @test alpine.linear_terms[lk3][:id] == 4 + @test alpine.linear_terms[lk3][:y_type] == :(Cont) lk4 = Dict{Symbol,Any}(Pair{Symbol,Any}(:sign, :+),Pair{Symbol,Any}(:scalar, 0.0),Pair{Symbol,Any}(:coef_var, Set(Any[(17.0, 2)]))) - @test m.internalModel.linear_terms[lk4][:y_idx] == 7 - @test m.internalModel.linear_terms[lk4][:id] == 3 - @test m.internalModel.linear_terms[lk4][:y_type] == :(Cont) - @test m.internalModel.bounding_constr_mip[1][:rhs] == 0.0 - @test m.internalModel.bounding_constr_mip[1][:vars] == Any[:(x[4]), :(x[6]), :(x[8]), :(x[10]), :(x[1])] - @test m.internalModel.bounding_constr_mip[1][:coefs] == Any[-1.0, -1.0, 1.0, 1.0, 1.0] - @test m.internalModel.bounding_constr_mip[1][:sense] == :(==) - @test m.internalModel.bounding_constr_mip[1][:cnt] == 5 - @test m.internalModel.bounding_constr_mip[2][:rhs] == 0.0 - @test m.internalModel.bounding_constr_mip[2][:vars] == Any[:(x[11]), :(x[2])] - @test m.internalModel.bounding_constr_mip[2][:coefs] == Any[5.0, -1.0] - @test m.internalModel.bounding_constr_mip[2][:sense] == :(<=) - @test m.internalModel.bounding_constr_mip[2][:cnt] == 2 + @test alpine.linear_terms[lk4][:y_idx] == 7 + @test alpine.linear_terms[lk4][:id] == 3 + @test alpine.linear_terms[lk4][:y_type] == :(Cont) + @test alpine.bounding_constr_mip[1][:rhs] == 0.0 + @test alpine.bounding_constr_mip[1][:vars] == Any[:(x[4]), :(x[6]), :(x[8]), :(x[10]), :(x[1])] + @test alpine.bounding_constr_mip[1][:coefs] == Any[-1.0, -1.0, 1.0, 1.0, 1.0] + @test alpine.bounding_constr_mip[1][:sense] == :(==) + @test alpine.bounding_constr_mip[1][:cnt] == 5 + @test alpine.bounding_constr_mip[2][:rhs] == 0.0 + @test alpine.bounding_constr_mip[2][:vars] == Any[:(x[11]), :(x[2])] + @test alpine.bounding_constr_mip[2][:coefs] == Any[5.0, -1.0] + @test alpine.bounding_constr_mip[2][:sense] == :(<=) + @test alpine.bounding_constr_mip[2][:cnt] == 2 end end =# diff --git a/test/runtests.jl b/test/runtests.jl index ce45e7aa..754e7d5f 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,6 +1,9 @@ -using JuMP, MathProgBase -using Ipopt, Cbc, Pavito -using GLPKMathProgInterface +using JuMP, MathOptInterface +const MOI = MathOptInterface +using Ipopt, Cbc #, Pavito +using Juniper +import Pavito +using GLPK using Alpine using Test @@ -16,10 +19,23 @@ for i in examples include(joinpath(alpine_dir, "test", "examples", i)) end -pavito_solver=PavitoSolver(mip_solver=CbcSolver(logLevel=0), cont_solver=IpoptSolver(print_level=0, sb="yes"), mip_solver_drives=false, log_level=0) +const IPOPT = optimizer_with_attributes(Ipopt.Optimizer, MOI.Silent() => true) +const IPOPT_SB = optimizer_with_attributes(Ipopt.Optimizer, MOI.Silent() => true, "sb" => "yes") +const IPOPT_9999 = optimizer_with_attributes(Ipopt.Optimizer, MOI.Silent() => true, "max_iter" => 9999) +const CBC = optimizer_with_attributes(Cbc.Optimizer, MOI.Silent() => true) +const JUNIPER = optimizer_with_attributes(Juniper.Optimizer, MOI.Silent() => true, "mip_solver" => CBC, "nl_solver" => IPOPT_SB) +const PAVITO = optimizer_with_attributes(Pavito.Optimizer, "mip_solver" => CBC, "cont_solver" => IPOPT_SB, "mip_solver_drives" => false) + +function _build(model::JuMP.Model) + MOI.set(model, MOI.NLPBlock(), JuMP._create_nlp_block_data(model)) + MOI.Utilities.attach_optimizer(model) + alpine = JuMP.backend(model).optimizer.model + Alpine.load!(alpine) + return alpine +end # Perform Tests include("$(alpine_dir)/test/solver.jl") include("$(alpine_dir)/test/expression.jl") include("$(alpine_dir)/test/algorithm.jl") -include("$(alpine_dir)/test/utility.jl") \ No newline at end of file +include("$(alpine_dir)/test/utility.jl") diff --git a/test/solver.jl b/test/solver.jl index c7e94ccf..fbbb496d 100644 --- a/test/solver.jl +++ b/test/solver.jl @@ -1,272 +1,280 @@ -#= -@testset "AlpineNonlinearModel loading tests" begin +@testset "Optimizer loading tests" begin # Random Model 1 - test_solver = AlpineSolver(nlp_solver=IpoptSolver(),mip_solver=CbcSolver(logLevel=0),loglevel=100) - m = operator_c(solver=test_solver) + test_solver = optimizer_with_attributes(Alpine.Optimizer, "nlp_solver" => IPOPT, + "mip_solver" => CBC, + "loglevel" => 100) + m = operator_c(solver = test_solver) - status = JuMP.build(m) - @test isa(m.internalModel, Alpine.AlpineNonlinearModel) + alpine = _build(m) + @test isa(alpine, Alpine.Optimizer) # Expression Model 1 - test_solver = AlpineSolver(nlp_solver=IpoptSolver(),mip_solver=CbcSolver(logLevel=0),loglevel=100) m = exprstest(solver=test_solver) - status = JuMP.build(m) - @test isa(m.internalModel, Alpine.AlpineNonlinearModel) + alpine = _build(m) + @test isa(alpine, Alpine.Optimizer) end -=# @testset "Partitioning variable selection tests :: nlp3" begin - # Select all NL variable - test_solver = AlpineSolver(nlp_solver=IpoptSolver(print_level=0), - mip_solver=CbcSolver(logLevel=0), - disc_var_pick=0, - disc_uniform_rate=10, - presolve_bp = false, - presolve_bt = false, - maxiter=1, - loglevel=100) + test_solver = optimizer_with_attributes(Alpine.Optimizer, + "nlp_solver" => IPOPT, + "mip_solver" => CBC, + "disc_var_pick" => 0, + "disc_uniform_rate" => 10, + "presolve_bp" => false, + "presolve_bt" => false, + "maxiter" => 1, + "loglevel" => 100) m = nlp3(solver=test_solver) - status = solve(m) + JuMP.optimize!(m) + alpine = JuMP.backend(m).optimizer.model - @test status == :UserLimits - @test isapprox(m.objVal, 7049.2478976; atol=1e-3) - @test length(m.internalModel.candidate_disc_vars) == 8 - @test length(m.internalModel.disc_vars) == 8 - @test m.internalModel.disc_var_pick == 0 + @test JuMP.termination_status(m) == MOI.OTHER_LIMIT + @test isapprox(JuMP.objective_value(m), 7049.2478976; atol=1e-3) + @test length(alpine.candidate_disc_vars) == 8 + @test length(alpine.disc_vars) == 8 + @test MOI.get(m, MOI.RawParameter("disc_var_pick")) == 0 # Select all NL variable - test_solver = AlpineSolver(nlp_solver=IpoptSolver(print_level=0), - mip_solver=CbcSolver(logLevel=0), - disc_var_pick=2, - disc_uniform_rate=10, - presolve_bp = false, - presolve_bt = false, - maxiter=1, - loglevel=100) + test_solver = optimizer_with_attributes(Alpine.Optimizer, "nlp_solver" => IPOPT, + "mip_solver" => CBC, + "disc_var_pick" => 2, + "disc_uniform_rate" => 10, + "presolve_bp" => false, + "presolve_bt" => false, + "maxiter" => 1, + "loglevel" => 100) m = nlp3(solver=test_solver) - status = solve(m) + JuMP.optimize!(m) + alpine = JuMP.backend(m).optimizer.model - @test status == :UserLimits - @test isapprox(m.objVal, 7049.2478976; atol=1e-3) - @test length(m.internalModel.candidate_disc_vars) == 8 - @test length(m.internalModel.disc_vars) == 8 - @test m.internalModel.disc_var_pick == 2 + @test JuMP.termination_status(m) == MOI.OTHER_LIMIT + @test isapprox(JuMP.objective_value(m), 7049.2478976; atol=1e-3) + @test length(alpine.candidate_disc_vars) == 8 + @test length(alpine.disc_vars) == 8 + @test MOI.get(m, MOI.RawParameter("disc_var_pick")) == 2 # Minimum vertex cover algorithm - test_solver = AlpineSolver(nlp_solver=IpoptSolver(print_level=0), - mip_solver=CbcSolver(logLevel=0), - disc_var_pick=1, - disc_uniform_rate=10, - presolve_bp = false, - presolve_bt = false, - maxiter=1, - loglevel=100) + test_solver = optimizer_with_attributes(Alpine.Optimizer, "nlp_solver" => IPOPT, + "mip_solver" => CBC, + "disc_var_pick" => 1, + "disc_uniform_rate" => 10, + "presolve_bp" => false, + "presolve_bt" => false, + "maxiter" => 1, + "loglevel" => 100) m = nlp3(solver=test_solver) - status = solve(m) + JuMP.optimize!(m) + alpine = JuMP.backend(m).optimizer.model - @test status == :UserLimits - @test isapprox(m.objVal, 7049.2478976; atol=1e-3) - @test length(m.internalModel.candidate_disc_vars) == 8 - @test length(m.internalModel.disc_vars) == 3 - @test m.internalModel.disc_var_pick == 1 + @test JuMP.termination_status(m) == MOI.OTHER_LIMIT + @test isapprox(JuMP.objective_value(m), 7049.2478976; atol=1e-3) + @test length(alpine.candidate_disc_vars) == 8 + @test length(alpine.disc_vars) == 3 + @test MOI.get(m, MOI.RawParameter("disc_var_pick")) == 1 # Adaptive variable selection scheme :: disc_var_pick = 3 - test_solver = AlpineSolver(nlp_solver=IpoptSolver(print_level=0), - mip_solver=CbcSolver(logLevel=0), - disc_var_pick=3, - presolve_bp = false, - presolve_bt = false, - maxiter=2, - loglevel=100) + test_solver = optimizer_with_attributes(Alpine.Optimizer, "nlp_solver" => IPOPT, + "mip_solver" => CBC, + "disc_var_pick" => 3, + "presolve_bp" => false, + "presolve_bt" => false, + "maxiter" => 2, + "loglevel" => 100) m = nlp3(solver=test_solver) - status = solve(m) - - @test status == :UserLimits - @test isapprox(m.objVal, 7049.2478976; atol=1e-3) - @test length(m.internalModel.candidate_disc_vars) == 8 - @test length(m.internalModel.disc_vars) == 8 - @test m.internalModel.disc_var_pick == 3 + JuMP.optimize!(m) + alpine = JuMP.backend(m).optimizer.model + + @test JuMP.termination_status(m) == MOI.OTHER_LIMIT + @test isapprox(JuMP.objective_value(m), 7049.2478976; atol=1e-3) + @test length(alpine.candidate_disc_vars) == 8 + @test length(alpine.disc_vars) == 8 + @test MOI.get(m, MOI.RawParameter("disc_var_pick")) == 3 end @testset "Partitioning variable selection tests :: castro2m2" begin # Select all NL variable - test_solver = AlpineSolver(nlp_solver=IpoptSolver(print_level=0), - mip_solver=CbcSolver(logLevel=0), - disc_var_pick=0, - disc_uniform_rate=10, - presolve_bp=false, - presolve_bt=false, - maxiter=1, - loglevel=100) + test_solver = optimizer_with_attributes(Alpine.Optimizer, "nlp_solver" => IPOPT, + "mip_solver" => CBC, + "disc_var_pick" => 0, + "disc_uniform_rate" => 10, + "presolve_bp" => false, + "presolve_bt" => false, + "maxiter" => 1, + "loglevel" => 100) m = castro2m2(solver=test_solver) - status = solve(m) + JuMP.optimize!(m) + alpine = JuMP.backend(m).optimizer.model - @test status == :UserLimits - @test m.objVal <= 470.3176 + @test JuMP.termination_status(m) == MOI.OTHER_LIMIT + @test JuMP.objective_value(m) <= 470.3176 - @test length(m.internalModel.candidate_disc_vars) == 10 - @test length(m.internalModel.disc_vars) == 10 - @test m.internalModel.disc_var_pick == 0 + @test length(alpine.candidate_disc_vars) == 10 + @test length(alpine.disc_vars) == 10 + @test MOI.get(m, MOI.RawParameter("disc_var_pick")) == 0 # Select minimum vertex cover - test_solver = AlpineSolver(nlp_solver=IpoptSolver(print_level=0), - mip_solver=CbcSolver(logLevel=0), - disc_var_pick=1, - disc_uniform_rate=10, - presolve_bp=false, - presolve_bt=false, - maxiter=1, - loglevel=100) + test_solver = optimizer_with_attributes(Alpine.Optimizer, "nlp_solver" => IPOPT, + "mip_solver" => CBC, + "disc_var_pick" => 1, + "disc_uniform_rate" => 10, + "presolve_bp" => false, + "presolve_bt" => false, + "maxiter" => 1, + "loglevel" => 100) m = castro2m2(solver=test_solver) - status = solve(m) + JuMP.optimize!(m) + alpine = JuMP.backend(m).optimizer.model - @test status == :UserLimits - @test m.objVal <= 470.3176 - @test length(m.internalModel.candidate_disc_vars) == 10 - @test length(m.internalModel.disc_vars) == 4 - @test m.internalModel.disc_var_pick == 1 + @test JuMP.termination_status(m) == MOI.OTHER_LIMIT + @test JuMP.objective_value(m) <= 470.3176 + @test length(alpine.candidate_disc_vars) == 10 + @test length(alpine.disc_vars) == 4 + @test MOI.get(m, MOI.RawParameter("disc_var_pick")) == 1 # Criteria 15 static selection - test_solver = AlpineSolver(nlp_solver=IpoptSolver(print_level=0), - mip_solver=CbcSolver(logLevel=0), - disc_var_pick=2, - disc_uniform_rate=15, - presolve_bp=false, - presolve_bt=false, - maxiter=1, - loglevel=100) + test_solver = optimizer_with_attributes(Alpine.Optimizer, "nlp_solver" => IPOPT, + "mip_solver" => CBC, + "disc_var_pick" => 2, + "disc_uniform_rate" => 15, + "presolve_bp" => false, + "presolve_bt" => false, + "maxiter" => 1, + "loglevel" => 100) m = castro2m2(solver=test_solver) - status = solve(m) + JuMP.optimize!(m) + alpine = JuMP.backend(m).optimizer.model - @test status == :UserLimits - @test m.objVal <= 470.3176 + @test JuMP.termination_status(m) == MOI.OTHER_LIMIT + @test JuMP.objective_value(m) <= 470.3176 - @test length(m.internalModel.candidate_disc_vars) == 10 - @test length(m.internalModel.disc_vars) == 10 - @test m.internalModel.disc_var_pick == 2 + @test length(alpine.candidate_disc_vars) == 10 + @test length(alpine.disc_vars) == 10 + @test MOI.get(m, MOI.RawParameter("disc_var_pick")) == 2 end @testset "Partitioning variable selection tests :: blend029" begin # Select all NL variable - test_solver = AlpineSolver(minlp_solver=pavito_solver, - nlp_solver=IpoptSolver(print_level=0), - mip_solver=CbcSolver(logLevel=0), - disc_var_pick=0, - disc_uniform_rate=10, - presolve_bt=false, - maxiter=1, - loglevel=100) + test_solver = optimizer_with_attributes(Alpine.Optimizer, "minlp_solver" => PAVITO, + "nlp_solver" => IPOPT, + "mip_solver" => CBC, + "disc_var_pick" => 0, + "disc_uniform_rate" => 10, + "presolve_bt" => false, + "maxiter" => 1, + "loglevel" => 100) m = blend029_gl(solver=test_solver) - JuMP.build(m) + alpine = _build(m) - @test length(m.internalModel.candidate_disc_vars) == 26 - @test Set(m.internalModel.candidate_disc_vars) == Set([26, 27, 29, 30, 32, 33, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 55, 56, 57, 58, 59, 60]) - @test length(m.internalModel.disc_vars) == 26 - @test m.internalModel.disc_var_pick == 0 + @test length(alpine.candidate_disc_vars) == 26 + @test Set(alpine.candidate_disc_vars) == Set([26, 27, 29, 30, 32, 33, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 55, 56, 57, 58, 59, 60]) + @test length(alpine.disc_vars) == 26 + @test MOI.get(m, MOI.RawParameter("disc_var_pick")) == 0 # Minimum vertex cover - test_solver = AlpineSolver(minlp_solver=pavito_solver, - nlp_solver=IpoptSolver(print_level=0), - mip_solver=CbcSolver(logLevel=0), - disc_var_pick=1, - disc_uniform_rate=10, - presolve_bp=false, - presolve_bt=false, - maxiter=1, - loglevel=100) + test_solver = optimizer_with_attributes(Alpine.Optimizer, "minlp_solver" => PAVITO, + "nlp_solver" => IPOPT, + "mip_solver" => CBC, + "disc_var_pick" => 1, + "disc_uniform_rate" => 10, + "presolve_bp" => false, + "presolve_bt" => false, + "maxiter" => 1, + "loglevel" => 100) m = blend029_gl(solver=test_solver) - JuMP.build(m) + alpine = _build(m) - @test length(m.internalModel.candidate_disc_vars) == 26 - @test Set(m.internalModel.candidate_disc_vars) == Set([26, 27, 29, 30, 32, 33, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 55, 56, 57, 58, 59, 60]) - @test length(m.internalModel.disc_vars) == 10 - @test m.internalModel.disc_var_pick == 1 + @test length(alpine.candidate_disc_vars) == 26 + @test Set(alpine.candidate_disc_vars) == Set([26, 27, 29, 30, 32, 33, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 55, 56, 57, 58, 59, 60]) + @test length(alpine.disc_vars) == 10 + @test MOI.get(m, MOI.RawParameter("disc_var_pick")) == 1 # Adaptive Scheme vertex cover - test_solver = AlpineSolver(minlp_solver=pavito_solver, - nlp_solver=IpoptSolver(print_level=0), - mip_solver=CbcSolver(logLevel=0), - disc_var_pick=2, - disc_uniform_rate=10, - presolve_bp=false, - presolve_bt=false, - maxiter=1, - loglevel=100) + test_solver = optimizer_with_attributes(Alpine.Optimizer, "minlp_solver" => PAVITO, + "nlp_solver" => IPOPT, + "mip_solver" => CBC, + "disc_var_pick" => 2, + "disc_uniform_rate" => 10, + "presolve_bp" => false, + "presolve_bt" => false, + "maxiter" => 1, + "loglevel" => 100) m = blend029_gl(solver=test_solver) - JuMP.build(m) + alpine = _build(m) - @test length(m.internalModel.candidate_disc_vars) == 26 - @test length(Set(m.internalModel.candidate_disc_vars)) == 26 + @test length(alpine.candidate_disc_vars) == 26 + @test length(Set(alpine.candidate_disc_vars)) == 26 # TODO provide a check to see if candidate_disc_vars are all covered - @test length(m.internalModel.disc_vars) == 10 - @test m.internalModel.disc_var_pick == 2 + @test length(alpine.disc_vars) == 10 + @test MOI.get(m, MOI.RawParameter("disc_var_pick")) == 2 end @testset "Partitioning variable selection tests :: castro6m2" begin # Dynamic Scheme step 2 - test_solver = AlpineSolver(nlp_solver=IpoptSolver(print_level=0), - mip_solver=CbcSolver(logLevel=0), - disc_var_pick=3, - presolve_bp=true, - presolve_bt=false, - maxiter=1, - loglevel=100) + test_solver = optimizer_with_attributes(Alpine.Optimizer, "nlp_solver" => IPOPT, + "mip_solver" => CBC, + "disc_var_pick" => 3, + "presolve_bp" => true, + "presolve_bt" => false, + "maxiter" => 1, + "loglevel" => 100) m = castro6m2(solver=test_solver) - status = solve(m) + JuMP.optimize!(m) + alpine = JuMP.backend(m).optimizer.model - @test status == :UserLimits - @test m.objVal <= 228.87 + @test JuMP.termination_status(m) == MOI.OTHER_LIMIT + @test JuMP.objective_value(m) <= 228.87 - @test length(m.internalModel.candidate_disc_vars) == 24 - @test length(Set(m.internalModel.candidate_disc_vars)) == 24 - @test length(m.internalModel.disc_vars) == 12 - @test length(Set(m.internalModel.disc_vars)) == 12 - @test m.internalModel.disc_var_pick == 3 + @test length(alpine.candidate_disc_vars) == 24 + @test length(Set(alpine.candidate_disc_vars)) == 24 + @test length(alpine.disc_vars) == 12 + @test length(Set(alpine.disc_vars)) == 12 + @test MOI.get(m, MOI.RawParameter("disc_var_pick")) == 3 # Dynamic Scheme step 2 - test_solver = AlpineSolver(nlp_solver=IpoptSolver(print_level=0), - mip_solver=CbcSolver(logLevel=0), - disc_var_pick=3, - presolve_bp=true, - presolve_bt=false, - maxiter=2, - loglevel=100) + test_solver = optimizer_with_attributes(Alpine.Optimizer, "nlp_solver" => IPOPT, + "mip_solver" => CBC, + "disc_var_pick" => 3, + "presolve_bp" => true, + "presolve_bt" => false, + "maxiter" => 2, + "loglevel" => 100) m = castro6m2(solver=test_solver) - status = solve(m) + JuMP.optimize!(m) + alpine = JuMP.backend(m).optimizer.model - @test status == :UserLimits - @test m.objVal <= 228.7810 + @test JuMP.termination_status(m) == MOI.OTHER_LIMIT + @test JuMP.objective_value(m) <= 228.7810 - @test length(m.internalModel.candidate_disc_vars) == 24 - @test length(Set(m.internalModel.candidate_disc_vars)) == 24 - @test length(m.internalModel.disc_vars) == 12 - @test length(Set(m.internalModel.disc_vars)) == 12 - @test m.internalModel.disc_var_pick == 3 + @test length(alpine.candidate_disc_vars) == 24 + @test length(Set(alpine.candidate_disc_vars)) == 24 + @test length(alpine.disc_vars) == 12 + @test length(Set(alpine.disc_vars)) == 12 + @test MOI.get(m, MOI.RawParameter("disc_var_pick")) == 3 end @testset "Test getsolvetime for time tracking" begin - test_solver = AlpineSolver(nlp_solver=IpoptSolver(print_level=0), - mip_solver=CbcSolver(logLevel=0), - disc_var_pick=0, - disc_uniform_rate=10, - presolve_bp=false, - presolve_bt=false, - maxiter=1, - loglevel=100) + test_solver = optimizer_with_attributes(Alpine.Optimizer, "nlp_solver" => IPOPT, + "mip_solver" => CBC, + "disc_var_pick" => 0, + "disc_uniform_rate" => 10, + "presolve_bp" => false, + "presolve_bt" => false, + "maxiter" => 1, + "loglevel" => 100) m = castro2m2(solver=test_solver) - status = solve(m) - @test getsolvetime(m) > 0. + JuMP.optimize!(m) + @test solve_time(m) > 0.0 end diff --git a/test/utility.jl b/test/utility.jl index 3563ce1b..ed5aeb9f 100644 --- a/test/utility.jl +++ b/test/utility.jl @@ -1,47 +1,48 @@ @testset "Utility Function Tests: Solver identifier fetch" begin - test_solver=AlpineSolver(minlp_solver=pavito_solver, - nlp_solver=IpoptSolver(print_level=0), - mip_solver=CbcSolver(logLevel=0), - presolve_bp=true, - disc_var_pick=1, - loglevel=100, - maxiter=2, - presolve_bt_width_tol=1e-3, - presolve_bt=false) + test_solver=optimizer_with_attributes(Alpine.Optimizer, "minlp_solver" => PAVITO, + "nlp_solver" => IPOPT, + "mip_solver" => CBC, + "presolve_bp" => true, + "disc_var_pick" => 1, + "loglevel" => 100, + "maxiter" => 2, + "presolve_bt_width_tol" => 1e-3, + "presolve_bt" => false) m = blend029_gl(solver=test_solver) - status = solve(m) + JuMP.optimize!(m) + alpine = JuMP.backend(m).optimizer.model - @test status == :UserLimits - @test m.internalModel.logs[:n_iter] == 2 + @test termination_status(m) == MOI.OTHER_LIMIT + @test alpine.logs[:n_iter] == 2 - Alpine.fetch_mip_solver_identifier(m.internalModel;override="Pajarito.PajaritoSolver(0, Inf, 1.0e-5, false, Cbc.CbcMathProgSolverInterface.CbcSolver(Any[(:logLevel, 0)]), Pajarito.UnsetSolver(), 0, false, true, Ipopt.IpoptSolver(Any[(:print_level, 0)]), true, true, false, false, true, false, false, true, false, true, true, true, true, false, true, 2.0, false, false, false, true, 1.0e-12, 1.0e-6, false, \"\")") - @test m.internalModel.mip_solver_id == "Pajarito" - Alpine.fetch_mip_solver_identifier(m.internalModel;override="Gurobi.GurobiSolver(nothing, Any[])") - @test m.internalModel.mip_solver_id == "Gurobi" - Alpine.fetch_mip_solver_identifier(m.internalModel;override="CPLEX.CplexSolver(Any[])") - @test m.internalModel.mip_solver_id == "Cplex" - Alpine.fetch_mip_solver_identifier(m.internalModel;override="Cbc.CbcMathProgSolverInterface.CbcSolver(Any[])") - @test m.internalModel.mip_solver_id == "Cbc" - Alpine.fetch_mip_solver_identifier(m.internalModel;override="GLPKMathProgInterface.GLPKInterfaceMIP.GLPKSolverMIP(false, Any[])") - @test m.internalModel.mip_solver_id == "GLPK" + Alpine.fetch_mip_solver_identifier(alpine;override="Pajarito.PajaritoSolver(0, Inf, 1.0e-5, false, Cbc.CbcMathProgSolverInterface.CbcSolver(Any[(:logLevel, 0)]), Pajarito.UnsetSolver(), 0, false, true, Ipopt.IpoptSolver(Any[(:print_level, 0)]), true, true, false, false, true, false, false, true, false, true, true, true, true, false, true, 2.0, false, false, false, true, 1.0e-12, 1.0e-6, false, \"\")") + @test alpine.mip_solver_id == "Pajarito" + Alpine.fetch_mip_solver_identifier(alpine;override="Gurobi.GurobiSolver(nothing, Any[])") + @test alpine.mip_solver_id == "Gurobi" + Alpine.fetch_mip_solver_identifier(alpine;override="CPLEX.CplexSolver(Any[])") + @test alpine.mip_solver_id == "Cplex" + Alpine.fetch_mip_solver_identifier(alpine;override="Cbc.CbcMathProgSolverInterface.CbcSolver(Any[])") + @test alpine.mip_solver_id == "Cbc" + Alpine.fetch_mip_solver_identifier(alpine;override="GLPKMathProgInterface.GLPKInterfaceMIP.GLPKSolverMIP(false, Any[])") + @test alpine.mip_solver_id == "GLPK" - Alpine.fetch_nlp_solver_identifier(m.internalModel;override="Pajarito.PajaritoSolver(0, Inf, 1.0e-5, false, Cbc.CbcMathProgSolverInterface.CbcSolver(Any[(:logLevel, 0)]), Pajarito.UnsetSolver(), 0, false, true, Ipopt.IpoptSolver(Any[(:print_level, 0)]), true, true, false, false, true, false, false, true, false, true, true, true, true, false, true, 2.0, false, false, false, true, 1.0e-12, 1.0e-6, false, \"\")") - @test m.internalModel.nlp_solver_id == "Pajarito" - Alpine.fetch_nlp_solver_identifier(m.internalModel;override="Ipopt.IpoptSolver(Any[])") - @test m.internalModel.nlp_solver_id == "Ipopt" - Alpine.fetch_nlp_solver_identifier(m.internalModel;override="AmplNLWriter.AmplNLSolver(\"bonmin\", String[], \"\")") - @test m.internalModel.nlp_solver_id == "Bonmin" + Alpine.fetch_nlp_solver_identifier(alpine;override="Pajarito.PajaritoSolver(0, Inf, 1.0e-5, false, Cbc.CbcMathProgSolverInterface.CbcSolver(Any[(:logLevel, 0)]), Pajarito.UnsetSolver(), 0, false, true, Ipopt.IpoptSolver(Any[(:print_level, 0)]), true, true, false, false, true, false, false, true, false, true, true, true, true, false, true, 2.0, false, false, false, true, 1.0e-12, 1.0e-6, false, \"\")") + @test alpine.nlp_solver_id == "Pajarito" + Alpine.fetch_nlp_solver_identifier(alpine;override="Ipopt.IpoptSolver(Any[])") + @test alpine.nlp_solver_id == "Ipopt" + Alpine.fetch_nlp_solver_identifier(alpine;override="AmplNLWriter.AmplNLSolver(\"bonmin\", String[], \"\")") + @test alpine.nlp_solver_id == "Bonmin" @test "NLopt" == "NLopt" - Alpine.fetch_nlp_solver_identifier(m.internalModel;override="KNITRO.KnitroSolver(Any[])") - @test m.internalModel.nlp_solver_id == "Knitro" + Alpine.fetch_nlp_solver_identifier(alpine;override="KNITRO.KnitroSolver(Any[])") + @test alpine.nlp_solver_id == "Knitro" - Alpine.fetch_minlp_solver_identifier(m.internalModel;override="Pajarito.PajaritoSolver(0, Inf, 1.0e-5, false, Cbc.CbcMathProgSolverInterface.CbcSolver(Any[(:logLevel, 0)]), Pajarito.UnsetSolver(), 0, false, true, Ipopt.IpoptSolver(Any[(:print_level, 0)]), true, true, false, false, true, false, false, true, false, true, true, true, true, false, true, 2.0, false, false, false, true, 1.0e-12, 1.0e-6, false, \"\")") - @test m.internalModel.minlp_solver_id == "Pajarito" - Alpine.fetch_minlp_solver_identifier(m.internalModel;override="AmplNLWriter.AmplNLSolver(\"bonmin\", String[], \"\")") - @test m.internalModel.minlp_solver_id == "Bonmin" - Alpine.fetch_minlp_solver_identifier(m.internalModel;override="KNITRO.KnitroSolver(Any[])") - @test m.internalModel.minlp_solver_id == "Knitro" + Alpine.fetch_minlp_solver_identifier(alpine;override="Pajarito.PajaritoSolver(0, Inf, 1.0e-5, false, Cbc.CbcMathProgSolverInterface.CbcSolver(Any[(:logLevel, 0)]), Pajarito.UnsetSolver(), 0, false, true, Ipopt.IpoptSolver(Any[(:print_level, 0)]), true, true, false, false, true, false, false, true, false, true, true, true, true, false, true, 2.0, false, false, false, true, 1.0e-12, 1.0e-6, false, \"\")") + @test alpine.minlp_solver_id == "Pajarito" + Alpine.fetch_minlp_solver_identifier(alpine;override="AmplNLWriter.AmplNLSolver(\"bonmin\", String[], \"\")") + @test alpine.minlp_solver_id == "Bonmin" + Alpine.fetch_minlp_solver_identifier(alpine;override="KNITRO.KnitroSolver(Any[])") + @test alpine.minlp_solver_id == "Knitro" @test "NLopt" == "NLopt" end