From d995ba60a96ff21bc52cf9ecb3e1856fbde8766f Mon Sep 17 00:00:00 2001 From: schillic Date: Mon, 11 Mar 2024 19:22:14 +0100 Subject: [PATCH 01/16] .gitignore --- .gitignore | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index d77b2b2..4c56458 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,12 @@ *.jl.cov *.jl.*.cov *.jl.mem -docs/build/ \ No newline at end of file +docs/build/ + +*.DS_Store + +coverage/ + +.vscode + +Manifest.toml From e764c7fd60ba08f77f6a2e515e40f01735060ae3 Mon Sep 17 00:00:00 2001 From: schillic Date: Mon, 11 Mar 2024 19:22:35 +0100 Subject: [PATCH 02/16] fix header spaces in NEWS --- NEWS.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/NEWS.md b/NEWS.md index c574313..b89c46e 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,14 +1,14 @@ # IntervalConstraintProgramming.jl -#v0.11 +# v0.11 ## Minimum Julia version - The minimum Julia version supported is now Julia 1.1 -##Functionality's are added +## Functionality's are added - Contractor can be make by just function name only - New type of Contractor named as `BasicContractor` can be construct which only contain fields of useful data. - + # v0.10 ## Minimum Julia version - The minimum Julia version supported is now Julia 1.0. @@ -17,6 +17,7 @@ - By the help of `ModelingToolkit.jl` we can construct contractors and separators without the use of macros. + # v0.9 ## Minimum Julia version - The minimum Julia version supported is now Julia 0.7. The package is fully compatible with Julia 1.0. @@ -29,12 +30,14 @@ ## Minimum Julia version - The minimum Julia version required has been bumped to 0.6; this will be the last release to support 0.6. + # v0.7 ## New dependency: `IntervalContractors.jl` The reverse functions used for constraint propagation have been factored out into the `IntervalContractors.jl` package. + # v0.6 ## Minimum Julia version - The minimum Julia version required has been bumped to 0.5 @@ -45,6 +48,7 @@ The reverse functions used for constraint propagation have been factored out int ## Dependency change - The dependency on `ValidatedNumerics.jl` has been replaced by `IntervalArithmetic.jl` and `IntervalRootFinding.jl` + # v0.5 - API change: Contractors now have their dimension as a type parameter - Refactoring for type stability @@ -53,6 +57,7 @@ The reverse functions used for constraint propagation have been factored out int - Generated code uses simpler symbols - Example notebooks have been split out into a separate repository: https://github.com/dpsanders/IntervalConstraintProgrammingNotebooks + # v0.4 - `@function f(x) = 4x` defines a function - Functions may be used inside constraints @@ -84,6 +89,7 @@ C = @constraint (x-$a)^2 + (y-$b)^2 The constraint will *not* change if the constants are changed, but may be updated (changed) by calling the same `@constraint` command again. + # v0.2 - `setinverse` now returns an object of type `Paving` [#17](https://github.com/dpsanders/IntervalConstraintProgramming.jl/pull/17) @@ -95,7 +101,7 @@ updated (changed) by calling the same `@constraint` command again. to eliminate collisions with user-defined variables [#20](https://github.com/dpsanders/IntervalConstraintProgramming.jl/pull/20) -## v0.1.1 +# v0.1.1 - Add `sqrtRev` reverse-mode function - Add solid torus example, including 3D visualization with GLVisualize From a6cb8be0e2a494653c325dea2e5f2395a19dd41d Mon Sep 17 00:00:00 2001 From: schillic Date: Mon, 11 Mar 2024 19:22:52 +0100 Subject: [PATCH 03/16] remove redundant version in Project.toml --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index ce013aa..14622cf 100644 --- a/Project.toml +++ b/Project.toml @@ -15,7 +15,7 @@ IntervalContractors = "0.4" IntervalRootFinding = "0.5" MacroTools = "0.4, 0.5" ModelingToolkit = "3" -julia = "1.3, 1.4" +julia = "1.3" [extras] ModelingToolkit = "961ee093-0014-501f-94e3-6117800e7a78" From 57818eec1917a8a9bfdf58bb4460fd1b6e8b7baa Mon Sep 17 00:00:00 2001 From: schillic Date: Mon, 11 Mar 2024 19:23:50 +0100 Subject: [PATCH 04/16] remove REQUIRE files --- REQUIRE | 6 ------ test/REQUIRE | 2 -- 2 files changed, 8 deletions(-) delete mode 100644 REQUIRE delete mode 100644 test/REQUIRE diff --git a/REQUIRE b/REQUIRE deleted file mode 100644 index f4b7bcc..0000000 --- a/REQUIRE +++ /dev/null @@ -1,6 +0,0 @@ -julia 1.0 -ModelingToolkit -IntervalArithmetic 0.15 -IntervalRootFinding 0.4 -IntervalContractors 0.3 -MacroTools 0.4 diff --git a/test/REQUIRE b/test/REQUIRE deleted file mode 100644 index d1e8555..0000000 --- a/test/REQUIRE +++ /dev/null @@ -1,2 +0,0 @@ -ModelingToolkit -DynamicPolynomials From 6cd16cf2b0b862c5f0325a24708ba18614bdec7d Mon Sep 17 00:00:00 2001 From: schillic Date: Mon, 11 Mar 2024 19:25:46 +0100 Subject: [PATCH 05/16] remove .DS_Store --- .DS_Store | Bin 6148 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 5172429f264de2441865cb4700216d4256da9242..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeH~J!%6%427R!7lt%jx}3%b$PET#pTHLgIFQEJ;E>dF^gR7ES*H$5cmnB-G%I%Z zD|S`@Z2$T80!#olbXV*=%*>dt@PRwdU#I)^a=X5>;#J@&VrHyNnC;iLL0pQvfVyTmjO&;ssLc!1UOG})p;=82 zR;?Ceh}WZ?+UmMqI#RP8R>OzYoz15hnq@nzF`-!xQ4j$Um=RcIKKc27r2jVm&svm< zfC&6E0=7P!4tu^-ovjbA=k?dB`g+i*aXG_}p8zI)6mRKa+;6_1_R^8c3Qa!(fk8n8 H{*=HsM+*^= From 8099f84fc23eec498e85a3c47e045cd91e2aac18 Mon Sep 17 00:00:00 2001 From: schillic Date: Mon, 11 Mar 2024 19:28:22 +0100 Subject: [PATCH 06/16] use isnothing --- src/ast.jl | 4 ++-- src/setinversion.jl | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ast.jl b/src/ast.jl index 6fda8a6..53f1fa8 100644 --- a/src/ast.jl +++ b/src/ast.jl @@ -335,7 +335,7 @@ function process_call!(flatAST::FlatAST, ex, var = [], new_var=nothing) #@show op if op ∈ keys(reverse_operations) # standard operator - if new_var == nothing + if isnothing(new_var) new_var = make_symbol() end @@ -408,7 +408,7 @@ function process_operation!(flatAST::FlatAST, ex, var, new_var=nothing) #@show op if Symbol(op) ∈ keys(reverse_operations) # standard operator - if new_var == nothing + if isnothing(new_var) new_var = make_symbol() end diff --git a/src/setinversion.jl b/src/setinversion.jl index 6392cec..654dfeb 100644 --- a/src/setinversion.jl +++ b/src/setinversion.jl @@ -33,7 +33,7 @@ function pave(S::Separator, working::Vector{IntervalBox{N,T}}, ϵ, bisection_poi push!(boundary_list, boundary) else - if bisection_point == nothing + if isnothing(bisection_point) push!(working, bisect(boundary)...) else push!(working, bisect(boundary, bisection_point)...) From 64c0fccc01858c7e55c3d23f8c90e98284045f06 Mon Sep 17 00:00:00 2001 From: schillic Date: Mon, 11 Mar 2024 19:32:42 +0100 Subject: [PATCH 07/16] minor formatting --- src/IntervalConstraintProgramming.jl | 6 +++--- src/contractor.jl | 1 - src/functions.jl | 2 -- src/setinversion.jl | 3 +-- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/IntervalConstraintProgramming.jl b/src/IntervalConstraintProgramming.jl index 9ca5b18..1e00cfd 100644 --- a/src/IntervalConstraintProgramming.jl +++ b/src/IntervalConstraintProgramming.jl @@ -2,9 +2,9 @@ __precompile__() module IntervalConstraintProgramming -using IntervalArithmetic, - IntervalRootFinding, - IntervalContractors +using IntervalArithmetic, + IntervalRootFinding, + IntervalContractors using ModelingToolkit using MacroTools diff --git a/src/contractor.jl b/src/contractor.jl index 5534606..fd26cf3 100644 --- a/src/contractor.jl +++ b/src/contractor.jl @@ -1,4 +1,3 @@ - """ `Contractor` represents a `Contractor` from ``\\mathbb{R}^N`` to ``\\mathbb{R}^N``. Nout is the output dimension of the forward part. diff --git a/src/functions.jl b/src/functions.jl index b7693f9..11def7a 100644 --- a/src/functions.jl +++ b/src/functions.jl @@ -1,5 +1,3 @@ - - """ A `ConstraintFunction` contains the created forward and backward code diff --git a/src/setinversion.jl b/src/setinversion.jl index 654dfeb..9a2362c 100644 --- a/src/setinversion.jl +++ b/src/setinversion.jl @@ -1,4 +1,3 @@ - """ `pave` takes the given working list of boxes and splits them into inner and boundary lists with the given separator @@ -62,7 +61,7 @@ function pave(S::Separator, X::IntervalBox{N,T}, ϵ = 1e-2, bisection_point=noth end -# + # """Refine a paving to tolerance ϵ""" # function refine!(P::Paving, ϵ = 1e-2) # if P.ϵ <= ϵ # already refined From c1dcb761bf93ab9f95c5a75923f41b3446a3fe83 Mon Sep 17 00:00:00 2001 From: schillic Date: Mon, 11 Mar 2024 19:57:41 +0100 Subject: [PATCH 08/16] remove IntervalRootFinding --- Project.toml | 2 -- src/IntervalConstraintProgramming.jl | 1 - 2 files changed, 3 deletions(-) diff --git a/Project.toml b/Project.toml index 14622cf..e754fd7 100644 --- a/Project.toml +++ b/Project.toml @@ -5,14 +5,12 @@ version = "0.12.4" [deps] IntervalArithmetic = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253" IntervalContractors = "15111844-de3b-5229-b4ba-526f2f385dc9" -IntervalRootFinding = "d2bf35a9-74e0-55ec-b149-d360ff49b807" MacroTools = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" ModelingToolkit = "961ee093-0014-501f-94e3-6117800e7a78" [compat] IntervalArithmetic = "0.16, 0.17, 0.18, 0.19, 0.20" IntervalContractors = "0.4" -IntervalRootFinding = "0.5" MacroTools = "0.4, 0.5" ModelingToolkit = "3" julia = "1.3" diff --git a/src/IntervalConstraintProgramming.jl b/src/IntervalConstraintProgramming.jl index 1e00cfd..ceee40a 100644 --- a/src/IntervalConstraintProgramming.jl +++ b/src/IntervalConstraintProgramming.jl @@ -3,7 +3,6 @@ __precompile__() module IntervalConstraintProgramming using IntervalArithmetic, - IntervalRootFinding, IntervalContractors using ModelingToolkit From 434506c5b7b0f873cb5d98de19719278d2a21f4b Mon Sep 17 00:00:00 2001 From: schillic Date: Mon, 11 Mar 2024 20:11:05 +0100 Subject: [PATCH 09/16] remove undefined exports --- src/IntervalConstraintProgramming.jl | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/IntervalConstraintProgramming.jl b/src/IntervalConstraintProgramming.jl index ceee40a..a888243 100644 --- a/src/IntervalConstraintProgramming.jl +++ b/src/IntervalConstraintProgramming.jl @@ -17,12 +17,11 @@ export BasicContractor, @contractor, Contractor, - Separator, separator, @separator, @constraint, + Separator, @constraint, @function, SubPaving, Paving, - pave, refine!, - Vol, - show_code + pave, + Vol const reverse_operations = IntervalContractors.reverse_operations From 9d6b30288c2521ecbee70fc9f7372578227b6cbc Mon Sep 17 00:00:00 2001 From: schillic Date: Mon, 11 Mar 2024 20:21:25 +0100 Subject: [PATCH 10/16] prepare for making ModelingToolkit an optional dependency --- Project.toml | 2 + src/IntervalConstraintProgramming.jl | 3 +- src/ast.jl | 48 ++++++------ src/contractor.jl | 83 ++++++++++---------- src/init.jl | 3 + src/init_ModelingToolkit.jl | 7 ++ src/separator.jl | 108 +++++++++++++++------------ 7 files changed, 144 insertions(+), 110 deletions(-) create mode 100644 src/init.jl create mode 100644 src/init_ModelingToolkit.jl diff --git a/Project.toml b/Project.toml index e754fd7..f815e6e 100644 --- a/Project.toml +++ b/Project.toml @@ -7,12 +7,14 @@ IntervalArithmetic = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253" IntervalContractors = "15111844-de3b-5229-b4ba-526f2f385dc9" MacroTools = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" ModelingToolkit = "961ee093-0014-501f-94e3-6117800e7a78" +Requires = "ae029012-a4dd-5104-9daa-d747884805df" [compat] IntervalArithmetic = "0.16, 0.17, 0.18, 0.19, 0.20" IntervalContractors = "0.4" MacroTools = "0.4, 0.5" ModelingToolkit = "3" +Requires = "0.5, 1" julia = "1.3" [extras] diff --git a/src/IntervalConstraintProgramming.jl b/src/IntervalConstraintProgramming.jl index a888243..ce0dd44 100644 --- a/src/IntervalConstraintProgramming.jl +++ b/src/IntervalConstraintProgramming.jl @@ -4,7 +4,7 @@ module IntervalConstraintProgramming using IntervalArithmetic, IntervalContractors - +using Requires using ModelingToolkit using MacroTools @@ -33,5 +33,6 @@ include("paving.jl") include("setinversion.jl") include("volume.jl") include("functions.jl") +include("init.jl") end # module diff --git a/src/ast.jl b/src/ast.jl index 53f1fa8..5127625 100644 --- a/src/ast.jl +++ b/src/ast.jl @@ -116,9 +116,32 @@ Returns the variable at the top of the current piece of the tree.""" # TODO: Parameters -# numbers: -function flatten!(flatAST::FlatAST, ex::ModelingToolkit.Constant, var) - return ex.value # nothing to do the AST; return the number +function _load_MT_flatten() + return quote + # numbers: + function flatten!(flatAST::FlatAST, ex::Constant, var) + return ex.value # nothing to do the AST; return the number + end + + function flatten!(flatAST::FlatAST, ex::Variable, var) # symbols are leaves + if isempty(var) + add_variable!(flatAST, Symbol(ex)) # add the discovered symbol as an input variable + end + return Symbol(ex) + end + + function flatten!(flatAST::FlatAST, ex::Operation, var) + # top = process_operation!(flatAST, ex, var) + # set_top!(flatAST, top) + + if ex.op isa Variable + return flatten!(flatAST, ex.op, var) + else + top = process_operation!(flatAST, ex, var) + set_top!(flatAST, top) + end + end + end end function flatten!(flatAST::FlatAST, ex, var) @@ -126,13 +149,6 @@ function flatten!(flatAST::FlatAST, ex, var) end # symbols: -function flatten!(flatAST::FlatAST, ex::Variable, var) # symbols are leaves - if isempty(var) - add_variable!(flatAST, Symbol(ex)) # add the discovered symbol as an input variable - end - return Symbol(ex) -end - function flatten!(flatAST::FlatAST, ex::Symbol, var) if isempty(var) add_variable!(flatAST, ex) # add the discovered symbol as an input variable @@ -169,18 +185,6 @@ function flatten!(flatAST::FlatAST, ex::Expr, var = []) set_top!(flatAST, top) end -function flatten!(flatAST::FlatAST, ex::Operation, var) - # top = process_operation!(flatAST, ex, var) - # set_top!(flatAST, top) - - if ex.op isa Variable - return flatten!(flatAST, ex.op, var) - else - top = process_operation!(flatAST, ex, var) - set_top!(flatAST, top) - end -end - function process_constant!(flatAST::FlatAST, ex) return esc(ex.args[1]) # interpolate the value of the external constant diff --git a/src/contractor.jl b/src/contractor.jl index fd26cf3..79c5871 100644 --- a/src/contractor.jl +++ b/src/contractor.jl @@ -4,7 +4,7 @@ Nout is the output dimension of the forward part. """ abstract type AbstractContractor end -struct Contractor{N, Nout, F1<:Function, F2<:Function, ex<:Union{Operation,Expr}} <:AbstractContractor +struct Contractor{N, Nout, F1<:Function, F2<:Function, ex} <:AbstractContractor variables::Vector{Symbol} # input variables forward::GeneratedFunction{F1} backward::GeneratedFunction{F2} @@ -87,68 +87,71 @@ end # allow 1D contractors to take Interval instead of IntervalBox for simplicty: (C::BasicContractor)(A::Interval{T}, X::IntervalBox{N,T}) where {N,Nout,T} = C(IntervalBox(A), X) -""" Contractor can also be construct without the use of macros - vars = @variables x y z - C = Contractor(x + y , vars) - C(-Inf..1, IntervalBox(0.5..1.5,3)) - """ -function Contractor(variables, expr::Operation) +function Base.show(io::IO, C::BasicContractor{F1,F2}) where {F1,F2} + println(io, " Basic version of Contractor") +end - var = [i.op.name for i in variables] - top, linear_AST = flatten(expr, var) +function _load_MT_contractor() + return quote + """ Contractor can also be construct without the use of macros + vars = @variables x y z + C = Contractor(x + y , vars) + C(-Inf..1, IntervalBox(0.5..1.5,3)) + """ + function Contractor(variables, expr::Operation) + var = [i.op.name for i in variables] + top, linear_AST = flatten(expr, var) - forward_code, backward_code = forward_backward(linear_AST) + forward_code, backward_code = forward_backward(linear_AST) - # @show top - if isa(top, Symbol) - top = [top] - end + # @show top - forward = eval(forward_code) - backward = eval(backward_code) + if isa(top, Symbol) + top = [top] + end - Contractor(linear_AST.variables, - top, - GeneratedFunction(forward, forward_code), - GeneratedFunction(backward, backward_code), - expr) + forward = eval(forward_code) + backward = eval(backward_code) -end + Contractor(linear_AST.variables, + top, + GeneratedFunction(forward, forward_code), + GeneratedFunction(backward, backward_code), + expr) + end -function BasicContractor(variables, expr::Operation) - var = [i.op.name for i in variables] - top, linear_AST = flatten(expr, var) + function BasicContractor(variables, expr::Operation) - forward_code, backward_code = forward_backward(linear_AST) + var = [i.op.name for i in variables] + top, linear_AST = flatten(expr, var) - forward = eval(forward_code) - backward = eval(backward_code) + forward_code, backward_code = forward_backward(linear_AST) - BasicContractor{typeof(forward), typeof(backward)}(forward, backward) -end + forward = eval(forward_code) + backward = eval(backward_code) -function Base.show(io::IO, C::BasicContractor{F1,F2}) where {F1,F2} - println(io, " Basic version of Contractor") -end - -BasicContractor(expr::Operation) = BasicContractor([], expr::Operation) + BasicContractor{typeof(forward), typeof(backward)}(forward, backward) + end -BasicContractor(vars::Union{Vector{Operation}, Tuple{Vararg{Operation,N}}}, g::Function) where N = BasicContractor(vars, g(vars...)) #Contractor can be constructed by function name only + BasicContractor(expr::Operation) = BasicContractor([], expr::Operation) -BasicContractor(vars, f::Function) = BasicContractor([Variable(Symbol(i))() for i in vars], f([Variable(Symbol(i))() for i in vars]...))#if vars is not vector of Operation + BasicContractor(vars::Union{Vector{Operation}, Tuple{Vararg{Operation,N}}}, g::Function) where N = BasicContractor(vars, g(vars...)) #Contractor can be constructed by function name only + BasicContractor(vars, f::Function) = BasicContractor([Variable(Symbol(i))() for i in vars], f([Variable(Symbol(i))() for i in vars]...))#if vars is not vector of Operation -Contractor(expr::Operation) = Contractor([], expr::Operation) + Contractor(expr::Operation) = Contractor([], expr::Operation) -Contractor(vars::Union{Vector{Operation}, Tuple{Vararg{Operation,N}}}, g::Function) where N = Contractor(vars, g(vars...)) #Contractor can be constructed by function name only + Contractor(vars::Union{Vector{Operation}, Tuple{Vararg{Operation,N}}}, g::Function) where N = Contractor(vars, g(vars...)) #Contractor can be constructed by function name only -Contractor(vars, f::Function) = Contractor([Variable(Symbol(i))() for i in vars], f([Variable(Symbol(i))() for i in vars]...))#if vars is not vector of Operation + Contractor(vars, f::Function) = Contractor([Variable(Symbol(i))() for i in vars], f([Variable(Symbol(i))() for i in vars]...))#if vars is not vector of Operation + end +end function make_contractor(expr::Expr, var = []) # println("Entering Contractor(ex) with ex=$ex") diff --git a/src/init.jl b/src/init.jl new file mode 100644 index 0000000..1d9af38 --- /dev/null +++ b/src/init.jl @@ -0,0 +1,3 @@ +function __init__() + @require ModelingToolkit = "961ee093-0014-501f-94e3-6117800e7a78" include("init_ModelingToolkit.jl") +end diff --git a/src/init_ModelingToolkit.jl b/src/init_ModelingToolkit.jl new file mode 100644 index 0000000..81df136 --- /dev/null +++ b/src/init_ModelingToolkit.jl @@ -0,0 +1,7 @@ +using .ModelingToolkit: Constant, Variable, Operation + +eval(_load_MT_flatten()) +eval(_load_MT_parse()) +eval(_load_MT_make_constraint()) +eval(_load_MT_separator()) +eval(_load_MT_contractor()) diff --git a/src/separator.jl b/src/separator.jl index f0b25cd..0aa4c93 100644 --- a/src/separator.jl +++ b/src/separator.jl @@ -5,7 +5,7 @@ abstract type Separator end ConstraintSeparator is a separator that represents a constraint defined directly using `@constraint`. """ -struct ConstraintSeparator{C, II, ex<:Union{Operation,Expr}} <: Separator +struct ConstraintSeparator{C, II, ex} <: Separator variables::Vector{Symbol} constraint::II # Interval or IntervalBox contractor::C @@ -17,7 +17,7 @@ ConstraintSeparator(constraint, contractor, expression) = ConstraintSeparator(co """CombinationSeparator is a separator that is a combination (union, intersection, or complement) of other separators. """ -struct CombinationSeparator{F, ex<:Union{Operation,Expr}} <: Separator +struct CombinationSeparator{F, ex} <: Separator variables::Vector{Symbol} separator::F expression::ex @@ -89,35 +89,38 @@ function parse_comparison(ex::Expr) end -function parse_comparison(ex::Operation) +function _load_MT_parse() + return quote + function parse_comparison(ex::Operation) + + if isa(ex.args[1], Constant) + if ex.op == < + a = ex.args[1].value + b = Inf + elseif ex.op == > + a = -Inf + b = ex.args[1].value + end + return (ex.args[2], a..b) + elseif isa(ex.args[2], Constant) + if ex.op == > + a = ex.args[2].value + b = Inf + elseif ex.op == < + a = -Inf + b = ex.args[2].value + else + a = ex.args[2].value + b = ex.args[2].value + end + return (ex.args[1], a..b) + end - if isa(ex.args[1], ModelingToolkit.Constant) - if ex.op == < - a = ex.args[1].value - b = Inf - elseif ex.op == > - a = -Inf - b = ex.args[1].value end - return (ex.args[2], a..b) - elseif isa(ex.args[2], ModelingToolkit.Constant) - if ex.op == > - a = ex.args[2].value - b = Inf - elseif ex.op == < - a = -Inf - b = ex.args[2].value - else - a = ex.args[2].value - b = ex.args[2].value - end - return (ex.args[1], a..b) end - end - function new_parse_comparison(ex) # @show ex if @capture ex begin @@ -158,13 +161,18 @@ function make_constraint(expr, constraint, var =[]) code end -make_constraint(expr::Variable, constraint) = make_constraint(Operation(expr), constraint) + +function _load_MT_make_constraint() + return quote + make_constraint(expr::Variable, constraint) = make_constraint(Operation(expr), constraint) -function make_constraint(expr::Operation, constraint, var=[]) - C = Contractor(var, expr) - ex = expr ∈ constraint - ConstraintSeparator(constraint, C, ex) + function make_constraint(expr::Operation, constraint, var=[]) + C = Contractor(var, expr) + ex = expr ∈ constraint + ConstraintSeparator(constraint, C, ex) + end + end end @@ -187,27 +195,33 @@ macro constraint(ex::Expr, variables = []) make_constraint(expr, constraint, var) end -""" -Create a separator without the use of macros using ModelingToolkit -e.g -``` -vars = @variables x y z -S = Separator(vars, x^2+y^2<1) -X= IntervalBox(-0.5..1.5, -0.5..1.5, -0.5..1.5) -S(X) -``` -""" -function Separator(variables, ex::Operation) - expr, constraint = parse_comparison(ex) - make_constraint(expr, constraint, variables) -end +function _load_MT_separator() + return quote + """ + Create a separator without the use of macros using ModelingToolkit + + e.g + ``` + vars = @variables x y z + S = Separator(vars, x^2+y^2<1) + X= IntervalBox(-0.5..1.5, -0.5..1.5, -0.5..1.5) + S(X) + ``` + """ + function Separator(variables, ex::Operation) + expr, constraint = parse_comparison(ex) + make_constraint(expr, constraint, variables) + end + + Separator(ex::Operation) = Separator([], ex) -Separator(ex::Operation) = Separator([], ex) + Separator(vars::Union{Vector{Operation}, Tuple{Vararg{Operation,N}}}, g::Function) where N = Separator(vars, g(vars...)) -Separator(vars::Union{Vector{Operation}, Tuple{Vararg{Operation,N}}}, g::Function) where N = Separator(vars, g(vars...)) + Separator(vars, f::Function) = Separator([Variable(Symbol(i))() for i in vars], f([Variable(Symbol(i))() for i in vars]...)) # if vars is not vector of variables + end +end -Separator(vars, f::Function) = Separator([Variable(Symbol(i))() for i in vars], f([Variable(Symbol(i))() for i in vars]...)) # if vars is not vector of variables function show(io::IO, S::Separator) println(io, "Separator:") From c91bf105ca8ac167afc54291e1f22488630d854a Mon Sep 17 00:00:00 2001 From: schillic Date: Mon, 11 Mar 2024 20:28:18 +0100 Subject: [PATCH 11/16] make ModelingToolkit an optional dependency --- Project.toml | 1 - src/IntervalConstraintProgramming.jl | 1 - 2 files changed, 2 deletions(-) diff --git a/Project.toml b/Project.toml index f815e6e..48d121a 100644 --- a/Project.toml +++ b/Project.toml @@ -6,7 +6,6 @@ version = "0.12.4" IntervalArithmetic = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253" IntervalContractors = "15111844-de3b-5229-b4ba-526f2f385dc9" MacroTools = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" -ModelingToolkit = "961ee093-0014-501f-94e3-6117800e7a78" Requires = "ae029012-a4dd-5104-9daa-d747884805df" [compat] diff --git a/src/IntervalConstraintProgramming.jl b/src/IntervalConstraintProgramming.jl index ce0dd44..bd9607d 100644 --- a/src/IntervalConstraintProgramming.jl +++ b/src/IntervalConstraintProgramming.jl @@ -5,7 +5,6 @@ module IntervalConstraintProgramming using IntervalArithmetic, IntervalContractors using Requires -using ModelingToolkit using MacroTools import Base: From 39e5fccbfc00770b5e643a8fd92fa447fcf771a5 Mon Sep 17 00:00:00 2001 From: schillic Date: Mon, 11 Mar 2024 20:40:52 +0100 Subject: [PATCH 12/16] use test/Project.toml --- Project.toml | 8 -------- test/Project.toml | 9 +++++++++ 2 files changed, 9 insertions(+), 8 deletions(-) create mode 100644 test/Project.toml diff --git a/Project.toml b/Project.toml index 48d121a..2348c54 100644 --- a/Project.toml +++ b/Project.toml @@ -12,13 +12,5 @@ Requires = "ae029012-a4dd-5104-9daa-d747884805df" IntervalArithmetic = "0.16, 0.17, 0.18, 0.19, 0.20" IntervalContractors = "0.4" MacroTools = "0.4, 0.5" -ModelingToolkit = "3" Requires = "0.5, 1" julia = "1.3" - -[extras] -ModelingToolkit = "961ee093-0014-501f-94e3-6117800e7a78" -Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" - -[targets] -test = ["Test", "ModelingToolkit"] diff --git a/test/Project.toml b/test/Project.toml new file mode 100644 index 0000000..cd1b0e9 --- /dev/null +++ b/test/Project.toml @@ -0,0 +1,9 @@ +[deps] +IntervalArithmetic = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253" +ModelingToolkit = "961ee093-0014-501f-94e3-6117800e7a78" +Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[compat] +IntervalArithmetic = "0.16, 0.17, 0.18, 0.19, 0.20" +ModelingToolkit = "3" +Test = "<0.0.1, 1.3" From c5338abe5e29207b5cccd18d9ffdb4b00708a889 Mon Sep 17 00:00:00 2001 From: schillic Date: Mon, 11 Mar 2024 20:50:34 +0100 Subject: [PATCH 13/16] remove unbound arg --- src/contractor.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/contractor.jl b/src/contractor.jl index 79c5871..ab8991a 100644 --- a/src/contractor.jl +++ b/src/contractor.jl @@ -85,7 +85,7 @@ function (C::BasicContractor)(A::IntervalBox{Nout,T}, X::IntervalBox{N,T})where end # allow 1D contractors to take Interval instead of IntervalBox for simplicty: -(C::BasicContractor)(A::Interval{T}, X::IntervalBox{N,T}) where {N,Nout,T} = C(IntervalBox(A), X) +(C::BasicContractor)(A::Interval{T}, X::IntervalBox{N,T}) where {N,T} = C(IntervalBox(A), X) function Base.show(io::IO, C::BasicContractor{F1,F2}) where {F1,F2} From eacda0f5c58ac16cf2439fcd72407b33261a2e39 Mon Sep 17 00:00:00 2001 From: schillic Date: Mon, 11 Mar 2024 21:18:09 +0100 Subject: [PATCH 14/16] add coverage badge --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 54b878a..fe45384 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ [![Build Status](https://github.com/JuliaIntervals/IntervalConstraintProgramming.jl/workflows/CI/badge.svg)](https://github.com/JuliaIntervals/IntervalConstraintProgramming.jl/actions/workflows/CI.yml) [![Docs](https://img.shields.io/badge/docs-stable-blue.svg)](https://juliaintervals.github.io/pages/packages/intervalconstraintprogramming/) +[![coverage](https://codecov.io/gh/JuliaIntervals/IntervalConstraintProgramming.jl/branch/master/graph/badge.svg)](https://codecov.io/gh/JuliaIntervals/IntervalConstraintProgramming.jl) This Julia package allows us to specify a set of constraints on real-valued variables, given by inequalities, and From c8fc0118c1f7d344a4cfe19392be4c276e33434b Mon Sep 17 00:00:00 2001 From: schillic Date: Tue, 12 Mar 2024 08:12:58 +0100 Subject: [PATCH 15/16] outsource ModelingToolkit tests --- test/ModelingToolkit.jl | 87 ++++++++++++++++++++++++++++++++++++++ test/runtests.jl | 94 +++-------------------------------------- 2 files changed, 93 insertions(+), 88 deletions(-) create mode 100644 test/ModelingToolkit.jl diff --git a/test/ModelingToolkit.jl b/test/ModelingToolkit.jl new file mode 100644 index 0000000..ffa7642 --- /dev/null +++ b/test/ModelingToolkit.jl @@ -0,0 +1,87 @@ +using ModelingToolkit + +@testset "BasicContractor" begin + @variables x y + C = BasicContractor(x^2 + y^2) + + @test C(-∞..1, IntervalBox(-∞..∞,2)) == IntervalBox(-1..1, -1..1) + + X =IntervalBox(-1..1,2) + @test C(X) == 0..2 + + @test C((1,2)) == 5 +end + +@testset "Contractor without using macro" begin + @variables x y + C = Contractor(x^2 + y^2) + @test C(-∞..1, IntervalBox(-∞..∞, 2)) == IntervalBox(-1..1, -1..1) + +end + +@testset "Contractor (with macros and without macros) specifying variables explicitly" begin + X =IntervalBox(0.5..1.5,3) + A=-Inf..1 + + C1 = @contractor(x+y, [x,y,z]) + @test C1(A,X) == IntervalBox(0.5..0.5, 0.5..0.5, 0.5..1.5) + + C2 = @contractor(y+z, [x,y,z]) + @test C2(A,X) == IntervalBox(0.5..1.5, 0.5..0.5, 0.5..0.5) + + vars = @variables x y z + + C1 = Contractor(vars, x+y) + @test C1(A,X) == IntervalBox(0.5..0.5, 0.5..0.5, 0.5..1.5) + + C2 = Contractor(vars, y+z) + @test C2(A,X) == IntervalBox(0.5..1.5, 0.5..0.5, 0.5..0.5) + + C1 = Contractor([x, y, z], x+y) + @test C1(A,X) == IntervalBox(0.5..0.5, 0.5..0.5, 0.5..1.5) + + C2 = Contractor([x, y, z], y+z) + @test C2(A,X) == IntervalBox(0.5..1.5, 0.5..0.5, 0.5..0.5) + + vars = @variables x1 x3 x2 + + C = Contractor(vars, x1+x2) + @test C(A, X) == IntervalBox(0.5..0.5, 0.5..1.5, 0.5..0.5) + +end + +@testset "Contractor is created by function name " begin + vars = @variables x y + g(x, y) = x + y + C = Contractor(vars, g) + + @test C(-Inf..1, IntervalBox(0.5..1.5, 2)) == IntervalBox(0.5..0.5, 2) + +end + +@testset "Separators without using macros" begin + II = -100..100 + X = IntervalBox(II, II) + vars = @variables x y + + S = Separator(vars, x^2 + y^2 < 1) + + inner, outer = S(X) + @test inner == IntervalBox(-1..1, -1..1) + @test outer == IntervalBox(II, II) + + X = IntervalBox(-∞..∞, -∞..∞) + inner, outer = S(X) + @test inner == IntervalBox(-1..1, -1..1) + @test outer == IntervalBox(-∞..∞, -∞..∞) + +end + +@testset "Separator is created by function name " begin + vars = @variables x y + g(x, y) = x + y < 1 + S = Separator(vars, g) + + @test S(IntervalBox(0.5..1.5, 2)) == (IntervalBox(0.5..0.5, 2), IntervalBox(0.5..1.5, 2)) + +end diff --git a/test/runtests.jl b/test/runtests.jl index b58a782..10959b5 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,23 +1,10 @@ +using IntervalConstraintProgramming, Test using IntervalArithmetic -using IntervalConstraintProgramming -using ModelingToolkit - -using Test @testset "Utilities" begin @test IntervalConstraintProgramming.unify_variables([:a, :c], [:c, :b]) == ([:a,:b,:c], [1,3], [3,2], [1,0,2], [0,2,1]) end -@testset "BasicContractor" begin - @variables x y - C = BasicContractor(x^2 + y^2) - - @test C(-∞..1, IntervalBox(-∞..∞,2)) == IntervalBox(-1..1, -1..1) - - X =IntervalBox(-1..1,2) - @test C(X) == 0..2 - @test C((1,2)) == 5 -end @testset "Contractor" begin x = y = -∞..∞ X = IntervalBox(x, y) @@ -33,53 +20,6 @@ end end -@testset "Contractor without using macro" begin - @variables x y - C = Contractor(x^2 + y^2) - @test C(-∞..1, IntervalBox(-∞..∞, 2)) == IntervalBox(-1..1, -1..1) - -end - -@testset "Contractor (with macros and without macros) specifying variables explicitly" begin - X =IntervalBox(0.5..1.5,3) - A=-Inf..1 - - C1 = @contractor(x+y, [x,y,z]) - @test C1(A,X) == IntervalBox(0.5..0.5, 0.5..0.5, 0.5..1.5) - - C2 = @contractor(y+z, [x,y,z]) - @test C2(A,X) == IntervalBox(0.5..1.5, 0.5..0.5, 0.5..0.5) - - vars = @variables x y z - - C1 = Contractor(vars, x+y) - @test C1(A,X) == IntervalBox(0.5..0.5, 0.5..0.5, 0.5..1.5) - - C2 = Contractor(vars, y+z) - @test C2(A,X) == IntervalBox(0.5..1.5, 0.5..0.5, 0.5..0.5) - - C1 = Contractor([x, y, z], x+y) - @test C1(A,X) == IntervalBox(0.5..0.5, 0.5..0.5, 0.5..1.5) - - C2 = Contractor([x, y, z], y+z) - @test C2(A,X) == IntervalBox(0.5..1.5, 0.5..0.5, 0.5..0.5) - - vars = @variables x1 x3 x2 - - C = Contractor(vars, x1+x2) - @test C(A, X) == IntervalBox(0.5..0.5, 0.5..1.5, 0.5..0.5) - -end - -@testset "Contractor is created by function name " begin - vars = @variables x y - g(x, y) = x + y - C = Contractor(vars, g) - - @test C(-Inf..1, IntervalBox(0.5..1.5, 2)) == IntervalBox(0.5..0.5, 2) - -end - @testset "Separators" begin II = -100..100 X = IntervalBox(II, II) @@ -98,33 +38,6 @@ end end -@testset "Separators without using macros" begin - II = -100..100 - X = IntervalBox(II, II) - vars = @variables x y - - S = Separator(vars, x^2 + y^2 < 1) - - inner, outer = S(X) - @test inner == IntervalBox(-1..1, -1..1) - @test outer == IntervalBox(II, II) - - X = IntervalBox(-∞..∞, -∞..∞) - inner, outer = S(X) - @test inner == IntervalBox(-1..1, -1..1) - @test outer == IntervalBox(-∞..∞, -∞..∞) - -end - -@testset "Separator is created by function name " begin - vars = @variables x y - g(x, y) = x + y < 1 - S = Separator(vars, g) - - @test S(IntervalBox(0.5..1.5, 2)) == (IntervalBox(0.5..0.5, 2), IntervalBox(0.5..1.5, 2)) - -end - @testset "pave" begin S1a = @constraint(x > 0 , [x, y]) S1b = @constraint(y > 0 , [x, y]) @@ -254,3 +167,8 @@ end @test C3(A, x) == IntervalBox(sqrt(A[1] / 16)) end + +@static if VERSION < v"1.9" + # ModelingToolkit causes compilation problems with new Julia versions starting v1.9 + include("ModelingToolkit.jl") +end From a8f979c7955f2abf59eaebed66e1b04400886e5a Mon Sep 17 00:00:00 2001 From: schillic Date: Tue, 12 Mar 2024 08:17:37 +0100 Subject: [PATCH 16/16] add CI runs in older Julia versions --- .github/workflows/CI.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 990e3f4..b6011cd 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -14,6 +14,8 @@ jobs: fail-fast: false matrix: version: + - '1.3' # oldest Julia version that works + - '1.8' # newest Julia version that works with ModelingToolkit - '1' - 'nightly' os: