From 5c691c128544bdcd4f01db009a7f3bdb9d5ea882 Mon Sep 17 00:00:00 2001 From: "David P. Sanders" Date: Thu, 15 Apr 2021 15:11:19 -0400 Subject: [PATCH 1/6] Add source files for rewrite --- Project.toml | 25 ++++---- src/IntervalConstraintProgramming.jl | 59 +++++++++++------- src/new_contractor.jl | 55 +++++++++++++++++ src/new_pave.jl | 84 ++++++++++++++++++++++++++ src/separator.jl | 8 ++- src/set_operations.jl | 89 ++++++++++++++++++++++++++++ src/utils.jl | 37 ++++++++++++ 7 files changed, 321 insertions(+), 36 deletions(-) create mode 100644 src/new_contractor.jl create mode 100644 src/new_pave.jl create mode 100644 src/set_operations.jl create mode 100644 src/utils.jl diff --git a/Project.toml b/Project.toml index 0b633a7..6a8a06f 100644 --- a/Project.toml +++ b/Project.toml @@ -1,25 +1,24 @@ name = "IntervalConstraintProgramming" uuid = "138f1668-1576-5ad7-91b9-7425abbf3153" -version = "0.12.2" - -[compat] -IntervalArithmetic = "0.16, 0.17" -IntervalContractors = "0.4" -IntervalRootFinding = "0.5" -MacroTools = "0.4, 0.5" -ModelingToolkit = "3" -julia = "1.3, 1.4" +version = "0.13.0" [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" +ReversePropagation = "527681c1-8309-4d3f-8790-caf822a419ba" +Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7" + +[compat] +IntervalArithmetic = "0.16, 0.17" +IntervalContractors = "0.4" +MacroTools = "0.4, 0.5" +ReversePropagation = "0.1" +Symbolics = "0.1" +julia = "1.6" [extras] -ModelingToolkit = "961ee093-0014-501f-94e3-6117800e7a78" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [targets] -test = ["Test", "ModelingToolkit"] +test = ["Test", "Symbolics"] diff --git a/src/IntervalConstraintProgramming.jl b/src/IntervalConstraintProgramming.jl index 9ca5b18..494d295 100644 --- a/src/IntervalConstraintProgramming.jl +++ b/src/IntervalConstraintProgramming.jl @@ -3,37 +3,56 @@ __precompile__() module IntervalConstraintProgramming using IntervalArithmetic, - IntervalRootFinding, IntervalContractors -using ModelingToolkit -using MacroTools +using Symbolics +using Symbolics: operation, value, arguments, toexpr + +using Symbolics: @register + +using ReversePropagation + +# using MacroTools import Base: - show, ∩, ∪, !, ⊆, setdiff + show, ∩, ∪, !, ⊆, setdiff, symdiff, &, | import IntervalArithmetic: sqr, setindex + +@register ¬(x) +@register x & y +@register x | y + export - BasicContractor, - @contractor, + # BasicContractor, + # @contractor, Contractor, - Separator, separator, @separator, @constraint, - @function, - SubPaving, Paving, - pave, refine!, - Vol, - show_code + Separator, #, separator, @separator, @constraint, + #@function, + #SubPaving, Paving, + pave #, refine!, + # Vol, + # show_code + +export ¬ const reverse_operations = IntervalContractors.reverse_operations -include("ast.jl") -include("code_generation.jl") -include("contractor.jl") -include("separator.jl") -include("paving.jl") -include("setinversion.jl") -include("volume.jl") -include("functions.jl") +# include("ast.jl") +# include("code_generation.jl") +# include("contractor.jl") +# include("separator.jl") +# include("paving.jl") +# include("setinversion.jl") +# include("volume.jl") +# include("functions.jl") + + +include("utils.jl") +include("new_contractor.jl") +include("new_pave.jl") +include("set_operations.jl") + end # module diff --git a/src/new_contractor.jl b/src/new_contractor.jl new file mode 100644 index 0000000..df8f4ba --- /dev/null +++ b/src/new_contractor.jl @@ -0,0 +1,55 @@ +struct Contractor{V, E, CC} + vars::V + ex::E + contractor::CC +end + +Contractor(ex, vars) = Contractor(vars, ex, forward_backward_contractor(ex, vars)) + +(CC::Contractor)(X, constraint=interval(0.0)) = IntervalBox(CC.contractor(X, constraint)[1]) + + +abstract type AbstractSeparator end + +"A separator models the inside and outside of a constraint set using a forward--backward contractor" +struct Separator{V,E,C,F,R} <: AbstractSeparator + vars::V + ex::E + constraint::C + f::F + contractor::R +end + +Base.show(io::IO, S::AbstractSeparator) = print(io, "Separator($(S.ex))") + +function Separator(orig_expr, vars) + ex, constraint = analyse(orig_expr) + + return Separator(vars, ex, constraint, make_function(ex, vars), Contractor(ex, vars)) +end + +"Returns boundary, inner, outer" +function (SS::Separator)(X) + boundary = SS.contractor(X) # contract with respect to 0, which is always the boundary + + lb = IntervalBox(inf.(X)) + ub = IntervalBox(sup.(X)) + + inner = boundary + outer = boundary + + if SS.f(lb) ⊆ SS.constraint + inner = inner ∪ lb + else + outer = outer ∪ lb + end + + if SS.f(ub) ⊆ SS.constraint + inner = inner ∪ ub + else + outer = outer ∪ ub + end + + + return boundary, inner, outer +end diff --git a/src/new_pave.jl b/src/new_pave.jl new file mode 100644 index 0000000..ae86c59 --- /dev/null +++ b/src/new_pave.jl @@ -0,0 +1,84 @@ +function pave(X, C::Contractor, ϵ=0.1) + working = [X] + paving = typeof(X)[] + + while !isempty(working) + X = pop!(working) + + if isempty(X) + continue + end + + X = C(X, 0..0) + + if isempty(X) + continue + end + + if diam(X) < ϵ + push!(paving, X) + continue + end + + push!(working, bisect(X)...) + + end + + return paving +end + +""" +Find inner and outer approximations of the intersection of `X` with the +set ``S`` specified by the separator `S`. + +Returns the `inner` paving (a vector of those boxes that are guaranteed to be inside ``S``) and the `boundary` +paving (boxes which have unknown status: they have neither been excluded, nor proved to +lie inside `S`). +""" +function pave(X, S::AbstractSeparator, ϵ=0.1) + working = [X] + inner_paving = typeof(X)[] + boundary_paving = typeof(X)[] + + while !isempty(working) + + X = pop!(working) + + if isempty(X) + continue + end + + if any(any.(isnan, X)) # hack to check empty + continue + end + + # @show X + + + boundary, inner, outer = S(X) + + if outer != X + # index = findfirst(outer .!= X) + + diff = setdiff(X, outer) + # replace setdiff with finding the *unique* direction that shrank + + if !isempty(diff) + + append!(inner_paving, diff) + + end + end + + + if diam(boundary) < ϵ + push!(boundary_paving, boundary) + continue + end + + push!(working, bisect(boundary)...) + + end + + return inner_paving, boundary_paving +end diff --git a/src/separator.jl b/src/separator.jl index f0b25cd..cff24b2 100644 --- a/src/separator.jl +++ b/src/separator.jl @@ -257,7 +257,7 @@ Takes an iterator of intervals (`IntervalBox`, tuple, array, etc.), of length equal to the total number of variables in `S1` and `S2`; it returns inner and outer tuples of the same length """ -function ∩(S1::Separator, S2::Separator) +function ∩(S1::AbstractSeparator, S2::AbstractSeparator) #=variables, indices1, indices2, where1, where2 = unify_variables(S1.variables, S2.variables) numvars = length(variables)=# @@ -314,7 +314,7 @@ function ∩(S1::Separator, S2::Separator) end -function ∪(S1::Separator, S2::Separator) +function ∪(S1::AbstractSeparator, S2::AbstractSeparator) #=variables, indices1, indices2, where1, where2 = unify_variables(S1.variables, S2.variables) numvars = length(variables)=# @@ -369,7 +369,7 @@ function ∪(S1::Separator, S2::Separator) end -function !(S::Separator) +function ¬(S::AbstractSeparator) f = X -> begin inner, outer = S(X) return (outer, inner) @@ -379,3 +379,5 @@ function !(S::Separator) return CombinationSeparator(S.variables, f, expression) end + +Base.:!(S::AbstractSeparator) = ¬(S) \ No newline at end of file diff --git a/src/set_operations.jl b/src/set_operations.jl new file mode 100644 index 0000000..617659f --- /dev/null +++ b/src/set_operations.jl @@ -0,0 +1,89 @@ + +struct CombinationSeparator{V, E, F} <: AbstractSeparator + vars::V + ex::E + f::F +end + + +function ∩(S1::AbstractSeparator, S2::AbstractSeparator) + + vars = S1.vars # assume S1 and S2 have same variables + + f = X -> begin + + boundary1, inner1, outer1 = S1(X) + boundary2, inner2, outer2 = S2(X) + + inner = inner1 ∩ inner2 + outer = outer1 ∪ outer2 + + boundary = inner ∩ outer + + return (boundary, inner, outer) + + end + + ex = (S1.ex) ∩ (S2.ex) + + return CombinationSeparator(vars, ex, f) + +end + + + +function ∪(S1::AbstractSeparator, S2::AbstractSeparator) + + vars = S1.vars # assume S1 and S2 have same variables + + f = X -> begin + + boundary1, inner1, outer1 = S1(X) + boundary2, inner2, outer2 = S2(X) + + inner = inner1 ∪ inner2 + outer = outer1 ∩ outer2 + + boundary = inner ∩ outer + + return (boundary, inner, outer) + + end + + ex = (S1.ex) ∪ (S2.ex) + + return CombinationSeparator(vars, ex, f) + +end + + + +function ¬(S::AbstractSeparator) + + vars = S.vars # assume S1 and S2 have same variables + + f = X -> begin + + boundary, inner, outer = S(X) + + return (boundary, outer, inner) + + end + + ex = ¬(S.ex) + + return CombinationSeparator(vars, ex, f) + +end + +Base.:!(S::AbstractSeparator) = ¬(S) + + + +(S::CombinationSeparator)(X) = S.f(X) + + +Base.setdiff(S1::AbstractSeparator, S2::AbstractSeparator) = S1 ∩ ¬(S2) +Base.symdiff(S1::AbstractSeparator, S2::AbstractSeparator) = setdiff(S1, S2) ∪ setdiff(S2, S1) + +## TODO: Make separate type \ No newline at end of file diff --git a/src/utils.jl b/src/utils.jl new file mode 100644 index 0000000..50af932 --- /dev/null +++ b/src/utils.jl @@ -0,0 +1,37 @@ + + +make_function(ex, vars) = eval(build_function(ex, vars)) + + +""" +Convert inequalities in an expression to interval constraints + +Moves everything to one side, e.g. + +x^2 < y^2 becomes x^2 - y^2 ∈ [-∞, 0] + +Returns the new expression and constraint. +""" +function analyse(ex) + ex2 = value(ex) + + op = operation(ex2) + lhs, rhs = arguments(ex2) + + if op ∈ (≤, <) + constraint = interval(-∞, 0) + Num(lhs - rhs), constraint + + elseif op ∈ (≥, >) + constraint = interval(0, +∞) + Num(lhs - rhs), constraint + + elseif op == (==) + constraint = interval(0, 0) + Num(lhs - rhs), constraint + + else + return ex, interval(0, 0) # implicit 0 + end + +end \ No newline at end of file From 0a0714f29e0a9af2bba40f6ced509bf690f83ed1 Mon Sep 17 00:00:00 2001 From: "David P. Sanders" Date: Thu, 15 Apr 2021 15:11:38 -0400 Subject: [PATCH 2/6] Add basic examples --- examples/basic_examples.jl | 92 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 examples/basic_examples.jl diff --git a/examples/basic_examples.jl b/examples/basic_examples.jl new file mode 100644 index 0000000..88263ad --- /dev/null +++ b/examples/basic_examples.jl @@ -0,0 +1,92 @@ +using Revise +using IntervalConstraintProgramming +using Symbolics +using IntervalArithmetic + +IntervalArithmetic.configure!(directed_rounding=:fast, powers=:fast) + +vars = @variables x, y + +ex = x^2 + y^2 ≤ 1 +@time S1 = Separator(ex, vars); + +X = IntervalBox(-10..10, 2) +S1(X) + +using BenchmarkTools + +@btime $S1($X) + + + +const plot_options = Dict(:ratio=>1, :leg=>false, :alpha=>0.5, :size=>(500, 300), :lw=>0.3) + +function plot_paving!(p; kw...) + inner, boundary = p + + plot!(inner; plot_options..., kw...) + plot!(boundary; plot_options..., kw...) +end + + +using Plots + +ex2 = (x - 0.5)^2 + (y - 0.5)^2 <= 1 + +S2 = Separator(ex2, vars) + + +p1 = pave(X, S1, 0.1) +p2 = pave(X, S2, 0.1) + + +S = S1 ∩ S2 + +p3 = pave(X, S, 0.1) + +X + +S(X) + +S1(X) + + +S.ex + + +p = plot(; plot_options...) + +plot_paving!(p1, lw=0) +plot_paving!(p2, lw=0) +plot_paving!(p3) + +p4 = pave(IntervalBox(-3..3, 2), !(S), 0.1) + +plot_paving!(p4; plot_options...) + +typeof(S) + +# SS = S1 ∩ (!S2); + +SS = setdiff(S1, S2); + + +SS + +p5 = pave(IntervalBox(-3..3, 2), SS, 0.1) + +p = plot(; plot_options...) +plot_paving!(p5, lw=0) + + +SS = setdiff(S1, S2); + + +SS2 = symdiff(S1, S2) + +p6 = pave(IntervalBox(-3..3, 2), SS2, 0.01) + +p = plot(; plot_options...) +plot_paving!(p6, lw=0) + +SS2 \ No newline at end of file From db996d4c70b28477c094a476b21f457d84fcca8e Mon Sep 17 00:00:00 2001 From: "David P. Sanders" Date: Thu, 13 May 2021 11:23:28 -0400 Subject: [PATCH 3/6] Add ConstraintProblem --- Project.toml | 2 +- examples/basic_examples.jl | 69 ++++++++++++++++++++++------ src/IntervalConstraintProgramming.jl | 19 ++++++-- src/new_contractor.jl | 11 ++++- src/new_pave.jl | 3 ++ src/set_operations.jl | 45 ++++++++++++++---- src/utils.jl | 61 +++++++++++++++++++++++- 7 files changed, 180 insertions(+), 30 deletions(-) diff --git a/Project.toml b/Project.toml index 6a8a06f..20967ad 100644 --- a/Project.toml +++ b/Project.toml @@ -10,7 +10,7 @@ ReversePropagation = "527681c1-8309-4d3f-8790-caf822a419ba" Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7" [compat] -IntervalArithmetic = "0.16, 0.17" +IntervalArithmetic = "0.16, 0.17, 0.18" IntervalContractors = "0.4" MacroTools = "0.4, 0.5" ReversePropagation = "0.1" diff --git a/examples/basic_examples.jl b/examples/basic_examples.jl index 88263ad..96a38f8 100644 --- a/examples/basic_examples.jl +++ b/examples/basic_examples.jl @@ -1,13 +1,22 @@ using Revise +using IntervalArithmetic using IntervalConstraintProgramming using Symbolics -using IntervalArithmetic IntervalArithmetic.configure!(directed_rounding=:fast, powers=:fast) vars = @variables x, y -ex = x^2 + y^2 ≤ 1 + +f(x, y) = x^2 + y^2 + +f(x, y) + +ex = x^2 ≤ 1 - y^2 + +ex +typeof(ex) + @time S1 = Separator(ex, vars); X = IntervalBox(-10..10, 2) @@ -35,6 +44,7 @@ ex2 = (x - 0.5)^2 + (y - 0.5)^2 <= 1 S2 = Separator(ex2, vars) +@constraint 1 <= x^2 + y^2 <= 3 p1 = pave(X, S1, 0.1) p2 = pave(X, S2, 0.1) @@ -44,16 +54,6 @@ S = S1 ∩ S2 p3 = pave(X, S, 0.1) -X - -S(X) - -S1(X) - - -S.ex - - p = plot(; plot_options...) plot_paving!(p1, lw=0) @@ -89,4 +89,47 @@ p6 = pave(IntervalBox(-3..3, 2), SS2, 0.01) p = plot(; plot_options...) plot_paving!(p6, lw=0) -SS2 \ No newline at end of file +SS2 + + + + +using ReversePropagation + +vars = @variables x, y + +ex = x^2 + y^2 + +ReversePropagation.forward_backward_contractor(ex, vars) + +p7 = pave(X, Separator((y - 5) * cos(4 * sqrt( (x-4)^2 + y^2 )) > x * sin(2 * sqrt( x^2 +y^2 )), vars), 0.1) + +plot(; plot_options...) +plot_paving!(p7) + + +separator(1 ≤ x^2 + y^2, vars) + + +constraint(x^2 + y^2 ≤ 1) + + +m = Model() + +@constraint(m, x^2 + y^2 <= 1) + + +# models + +m = Model() + +vars = @variables x, y, z +add_variables!(m, vars) + +add_constraint!(m, x^2 + y^2 ≤ 1) + + +c = constraint(m.constraints[1], variables(m)) + +X = IntervalBox(-3..3, 3) +c(X) \ No newline at end of file diff --git a/src/IntervalConstraintProgramming.jl b/src/IntervalConstraintProgramming.jl index 494d295..bcc1ad5 100644 --- a/src/IntervalConstraintProgramming.jl +++ b/src/IntervalConstraintProgramming.jl @@ -6,7 +6,7 @@ using IntervalArithmetic, IntervalContractors using Symbolics -using Symbolics: operation, value, arguments, toexpr +using Symbolics: operation, value, arguments, toexpr, Sym using Symbolics: @register @@ -15,7 +15,7 @@ using ReversePropagation # using MacroTools import Base: - show, ∩, ∪, !, ⊆, setdiff, symdiff, &, | + show, ∩, ∪, !, ⊆, setdiff, symdiff, &, |, ∈ import IntervalArithmetic: sqr, setindex @@ -23,6 +23,9 @@ import IntervalArithmetic: sqr, setindex @register ¬(x) @register x & y @register x | y +@register x ∈ y::Interval +@register x ∨ y +@register x ∧ y export # BasicContractor, @@ -31,9 +34,16 @@ export Separator, #, separator, @separator, @constraint, #@function, #SubPaving, Paving, - pave #, refine!, + pave, #, refine!, # Vol, # show_code + separator, constraint, + Model, + @constraint, + add_constraint!, + variables, + add_variables!, + ConstraintProblem export ¬ @@ -51,8 +61,9 @@ const reverse_operations = IntervalContractors.reverse_operations include("utils.jl") include("new_contractor.jl") -include("new_pave.jl") include("set_operations.jl") +include("model.jl") +include("new_pave.jl") end # module diff --git a/src/new_contractor.jl b/src/new_contractor.jl index df8f4ba..458f5b6 100644 --- a/src/new_contractor.jl +++ b/src/new_contractor.jl @@ -20,14 +20,21 @@ struct Separator{V,E,C,F,R} <: AbstractSeparator contractor::R end -Base.show(io::IO, S::AbstractSeparator) = print(io, "Separator($(S.ex))") +# Base.show(io::IO, S::Separator) = print(io, "Separator($(S.ex) ∈ $(S.constraint), vars = $(join(S.vars, ", ")))") + +Base.show(io::IO, S::AbstractSeparator) = print(io, "Separator($(S.ex), vars=$(join(S.vars, ", ")))") function Separator(orig_expr, vars) ex, constraint = analyse(orig_expr) - return Separator(vars, ex, constraint, make_function(ex, vars), Contractor(ex, vars)) + return Separator(ex, vars, constraint) end +Separator(ex, vars, constraint::Interval) = Separator(vars, ex ∈ constraint, constraint, make_function(ex, vars), Contractor(ex, vars)) + + + + "Returns boundary, inner, outer" function (SS::Separator)(X) boundary = SS.contractor(X) # contract with respect to 0, which is always the boundary diff --git a/src/new_pave.jl b/src/new_pave.jl index ae86c59..cb67e22 100644 --- a/src/new_pave.jl +++ b/src/new_pave.jl @@ -82,3 +82,6 @@ function pave(X, S::AbstractSeparator, ϵ=0.1) return inner_paving, boundary_paving end + +pave(X, S::ConstraintProblem, ϵ=0.1) = pave(X, S.separator, ϵ) + diff --git a/src/set_operations.jl b/src/set_operations.jl index 617659f..9fa6119 100644 --- a/src/set_operations.jl +++ b/src/set_operations.jl @@ -5,6 +5,7 @@ struct CombinationSeparator{V, E, F} <: AbstractSeparator f::F end +# TODO: Replace intersection with composition function ∩(S1::AbstractSeparator, S2::AbstractSeparator) @@ -12,15 +13,39 @@ function ∩(S1::AbstractSeparator, S2::AbstractSeparator) f = X -> begin - boundary1, inner1, outer1 = S1(X) - boundary2, inner2, outer2 = S2(X) - - inner = inner1 ∩ inner2 - outer = outer1 ∪ outer2 + boundary1, inner1, outer1 = S1(X) + boundary2, inner2, outer2 = S2(X) + + inner = inner1 ∩ inner2 + outer = outer1 ∪ outer2 - boundary = inner ∩ outer - - return (boundary, inner, outer) + boundary = inner ∩ outer + + return (boundary, inner, outer) + + end + + ex = (S1.ex) ∩ (S2.ex) + + return CombinationSeparator(vars, ex, f) + +end + +function ∘(S1::AbstractSeparator, S2::AbstractSeparator) + + vars = S1.vars # assume S1 and S2 have same variables + + f = X -> begin + + boundary1, inner1, outer1 = S1(X) + boundary2, inner2, outer2 = S2(X) + + inner = inner1 ∩ inner2 + outer = outer1 ∪ outer2 + + boundary = inner ∩ outer + + return (boundary, inner, outer) end @@ -86,4 +111,6 @@ Base.:!(S::AbstractSeparator) = ¬(S) Base.setdiff(S1::AbstractSeparator, S2::AbstractSeparator) = S1 ∩ ¬(S2) Base.symdiff(S1::AbstractSeparator, S2::AbstractSeparator) = setdiff(S1, S2) ∪ setdiff(S2, S1) -## TODO: Make separate type \ No newline at end of file +## TODO: Make separate type + + diff --git a/src/utils.jl b/src/utils.jl index 50af932..0e339ba 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -17,6 +17,7 @@ function analyse(ex) op = operation(ex2) lhs, rhs = arguments(ex2) + if op ∈ (≤, <) constraint = interval(-∞, 0) @@ -34,4 +35,62 @@ function analyse(ex) return ex, interval(0, 0) # implicit 0 end -end \ No newline at end of file +end + + + + + +function separator(ex, vars) + ex2 = ex + + if ex isa Num + ex2 = value(ex) + end + + op = operation(ex2) + + + if op == ¬ + arg = arguments(ex2)[1] + return ¬(separator(arg, vars)) + end + + lhs, rhs = arguments(ex2) + + if op == & + return separator(lhs, vars) ∩ separator(rhs, vars) + + elseif op == | + return separator(lhs, vars) ∪ separator(rhs, vars) + + elseif op ∈ (≤, <) + constraint = interval(-∞, 0) + Separator(Num(lhs - rhs), vars, constraint) + + elseif op ∈ (≥, >) + constraint = interval(0, +∞) + Separator(Num(lhs - rhs), vars, constraint) + + elseif op == (==) + constraint = interval(0, 0) + Separator(Num(lhs - rhs), vars, constraint) + + else + return Separator(ex, vars, interval(0, 0)) # implicit "== 0" + end + +end + + +function separator(ex) + vars = Symbolics.get_variables(ex) + + + return separator(ex, vars) +end + + +const constraint = separator + + From 740972043847b9bb40f535ae52258785763ed50b Mon Sep 17 00:00:00 2001 From: "David P. Sanders" Date: Tue, 2 Nov 2021 17:23:50 -0400 Subject: [PATCH 4/6] Bump versions --- Project.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Project.toml b/Project.toml index 20967ad..4927a6e 100644 --- a/Project.toml +++ b/Project.toml @@ -10,12 +10,12 @@ ReversePropagation = "527681c1-8309-4d3f-8790-caf822a419ba" Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7" [compat] -IntervalArithmetic = "0.16, 0.17, 0.18" +IntervalArithmetic = "0.16, 0.17, 0.18, 0.19, 0.20" IntervalContractors = "0.4" MacroTools = "0.4, 0.5" ReversePropagation = "0.1" -Symbolics = "0.1" -julia = "1.6" +Symbolics = "1, 2, 3, 4" +julia = "1.6, 1.7" [extras] Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" From ffee1fde3eaa51a2b131ee9883262149f299a072 Mon Sep 17 00:00:00 2001 From: David Sanders Date: Tue, 2 Nov 2021 17:51:32 -0400 Subject: [PATCH 5/6] Add model.jl --- src/model.jl | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 src/model.jl diff --git a/src/model.jl b/src/model.jl new file mode 100644 index 0000000..92e246c --- /dev/null +++ b/src/model.jl @@ -0,0 +1,107 @@ + + +struct Model + vars::Set{Sym{Real, Nothing}} + params + constraints +end + +Model() = Model(Set([]), Set([]), []) + +add_variable!(m::Model, v::Num) = add_variable!(m, value(v)) +add_variable!(m::Model, v::Sym) = push!(m.vars, v) + +function add_variables!(m::Model, vars) + for var in vars + add_variable!(m, var) + end +end + +function add_constraint!(m::Model, s::Num) + # push!(m.vars, s.vars...) + push!(m.constraints, s) +end + + + + + +variables(m::Model) = sort(collect(m.vars), lt = (x, y) -> x.name < y.name) + + +extract_vars(ex) = Symbol[] +extract_vars(ex::Symbol) = [ex] + +function extract_vars(ex::Expr) + if ex.head == :call + reduce(vcat, extract_vars.(ex.args[2:end])) + + else + reduce(vcat, extract_vars.(ex.args)) + end +end + +function add_constraint!(m, ex::Expr) + # @show m, ex + + m2 = esc(m) + + vars = extract_vars(ex) + + @show vars + + # create variables in global scope: + code = [:($(esc(v)) = Sym{Real}($(Meta.quot(v)))) for v in vars] + + code2 = [:(push!($(m2).vars, $(esc(v)))) for v in vars] + + @show code + + quote + $(code...) + $(code2...) + + push!($(m2).constraints, $(esc(ex))) + end + +end + +macro constraint(m, ex) + # @show m, ex + + add_constraint!(m, ex) +end + + +# m = Model() +# @constraint(m, x^2 + y^2 <= 1) + +# separator(m.constraints[1], sort(collect(m.vars), lt = (x, y) -> x.name < y.name)) + +# @constraint(m, z < 3) + +# separator(m.constraints[1], sort(collect(m.vars), lt = (x, y) -> x.name < y.name)) + + +# rename to ConstraintSatisfactionProblem? +struct ConstraintProblem + vars + constraint_expressions + constraints +end + +function ConstraintProblem(vars, constraint_exprs) + constraints = constraint.(constraint_exprs, Ref(vars)) + + return ConstraintProblem(vars, constraint_exprs, constraints) +end + +function ConstraintProblem(constraint_exprs) + + vars = collect(reduce(∪, Symbolics.get_variables.(constraint_exprs))) + + return ConstraintProblem(vars, constraint_exprs) +end + + + From 15283dad5f0123c7aa7d7607313b66793708da4f Mon Sep 17 00:00:00 2001 From: lucaferranti Date: Wed, 3 Nov 2021 09:20:32 +0200 Subject: [PATCH 6/6] update Project.toml and workflow --- .github/workflows/CI.yml | 3 +-- .gitignore | 3 ++- Project.toml | 1 + test/runtests.jl | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index b8adf3d..47b929b 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -11,8 +11,7 @@ jobs: fail-fast: false matrix: version: - - '1.5' - - '^1.6.0-0' + - '1.6' - 'nightly' os: - ubuntu-latest diff --git a/.gitignore b/.gitignore index d77b2b2..44a110c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ *.jl.cov *.jl.*.cov *.jl.mem -docs/build/ \ No newline at end of file +docs/build/ +Manifest.toml \ No newline at end of file diff --git a/Project.toml b/Project.toml index 4927a6e..7dc5b6d 100644 --- a/Project.toml +++ b/Project.toml @@ -18,6 +18,7 @@ Symbolics = "1, 2, 3, 4" julia = "1.6, 1.7" [extras] +Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [targets] diff --git a/test/runtests.jl b/test/runtests.jl index ff4d304..1d482ac 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,6 +1,6 @@ using IntervalArithmetic using IntervalConstraintProgramming -using ModelingToolkit +using Symbolics using Test