ConstraintDomains.jl: Defining Variables and Exploring Domains
ConstraintDomains.jl is the standard way to define variables and explore domains in the Julia Constraints ecosystem. This package can be used to specify both discrete and continuous domains. Explorations features are primarily related to learning about constraints, aka constraint learning.
Most users should use it through JuMP/MOI interfaces.
Commons
AbstractDomain
An abstract super type for any domain type. A domain type D <: AbstractDomain
must implement the following methods to properly interface AbstractDomain
.
Base.∈(val, ::D)
Base.rand(::D)
Base.length(::D)
that is the number of elements in a discrete domain, and the distance between bounds or similar for a continuous domain
Additionally, if the domain is used in a dynamic context, it can extend
add!(::D, args)
delete!(::D, args)
where args
depends on D
's structure
EmptyDomain
A struct to handle yet to be defined domains.
domain()
Construct an EmptyDomain
.
domain(a::Tuple{T, Bool}, b::Tuple{T, Bool}) where {T <: Real}
domain(intervals::Vector{Tuple{Tuple{T, Bool},Tuple{T, Bool}}}) where {T <: Real}
Construct a domain of continuous interval(s).
domain(values)
domain(range::R) where {T <: Real, R <: AbstractRange{T}}
Construct either a SetDomain
or a RangeDomain
.
d1 = domain(1:5)
d2 = domain([53.69, 89.2, 0.12])
d3 = domain([2//3, 89//123])
d4 = domain(4.3)
d5 = domain(1,42,86.9)
domain_size(d <: AbstractDomain)
Fallback method for domain_size(d)
that return length(d)
.
domain_size(itv::Intervals)
Return the difference between the highest and lowest values in itv
.
domain_size(d::D) where D <: DiscreteDomain
Return the maximum distance between two points in d
.
get_domain(::AbstractDomain)
Access the internal structure of any domain type.
to_domains(args...)
Convert various arguments into valid domains format.
Extension to Base module
x::Variable ∈ constraint
value ∈ x::Variable
Check if a variable x
is restricted by a constraint::Int
, or if a value
belongs to the domain of x
.
var::Int ∈ c::Constraint
Base.in(value, d <: AbstractDomain)
Fallback method for value ∈ d
that returns false
.
Base.in(x, itv::Intervals)
Return true
if x ∈ I
for any 'I ∈ itv, false otherwise.
x ∈ I` is equivalent to
a < x < b
ifI = (a, b)
a < x ≤ b
ifI = (a, b]
a ≤ x < b
ifI = [a, b)
a ≤ x ≤ b
ifI = [a, b]
Base.in(value, d::D) where D <: DiscreteDomain
Return true
if value
is a point of d
.
Base.rand(d::Union{Vector{D},Set{D}, D}) where {D<:AbstractDomain}
Extends Base.rand
to (a collection of) domains.
Base.rand(itv::Intervals)
Base.rand(itv::Intervals, i)
Return a random value from itv
, specifically from the i
th interval if i
is specified.
Base.rand(d::D) where D <: DiscreteDomain
Draw randomly a point in d
.
Base.rand(fa::FakeAutomaton)
Extends Base.rand
. Currently simply returns fa
.
Base.isempty(d <: AbstractDomain)
Fallback method for isempty(d)
that return length(d) == 0
which default to 0
.
Base.rand(d::Union{Vector{D},Set{D}, D}) where {D<:AbstractDomain}
Extends Base.rand
to (a collection of) domains.
Base.rand(itv::Intervals)
Base.rand(itv::Intervals, i)
Return a random value from itv
, specifically from the i
th interval if i
is specified.
Base.rand(d::D) where D <: DiscreteDomain
Draw randomly a point in d
.
Base.rand(fa::FakeAutomaton)
Extends Base.rand
. Currently simply returns fa
.
Base.string(D::Vector{<:AbstractDomain})
Base.string(d<:AbstractDomain)
Extends the string
method to (a vector of) domains.
Performances
Continuous
ContinuousDomain{T <: Real} <: AbstractDomain
An abstract supertype for all continuous domains.
Intervals{T <: Real} <: ContinuousDomain{T}
An encapsuler to store a vector of PatternFolds.Interval
. Dynamic changes to Intervals
are not handled yet.
domain()
Construct an EmptyDomain
.
domain(a::Tuple{T, Bool}, b::Tuple{T, Bool}) where {T <: Real}
domain(intervals::Vector{Tuple{Tuple{T, Bool},Tuple{T, Bool}}}) where {T <: Real}
Construct a domain of continuous interval(s).
domain(values)
domain(range::R) where {T <: Real, R <: AbstractRange{T}}
Construct either a SetDomain
or a RangeDomain
.
d1 = domain(1:5)
d2 = domain([53.69, 89.2, 0.12])
d3 = domain([2//3, 89//123])
d4 = domain(4.3)
d5 = domain(1,42,86.9)
domain_size(d <: AbstractDomain)
Fallback method for domain_size(d)
that return length(d)
.
domain_size(itv::Intervals)
Return the difference between the highest and lowest values in itv
.
domain_size(d::D) where D <: DiscreteDomain
Return the maximum distance between two points in d
.
merge_domains(d₁::AbstractDomain, d₂::AbstractDomain)
Merge two domains of same nature (discrete/contiuous).
intersect_domains(d₁, d₂)
Compute the intersections of two domains.
intersect_domains!(is, i, new_itvls)
Compute the intersections of a domain with an interval and store the results in new_itvls
.
Arguments
is::IS
: a collection of intervals.i::I
: an interval.new_itvls::Vector{I}
: a vector to store the results.
Base.size(i::I) where {I <: Interval}
Defines the size of an interval as its span
.
Extension to Base module
length(layer)
Return the number of operations in a layer.
Base.length(icn)
Return the total number of operations of an ICN.
Base.rand(d <: AbstractDomain)
Fallback method for length(d)
that return 0
.
Base.length(itv::Intervals)
Return the sum of the length of each interval in itv
.
Base.length(d::D) where D <: DiscreteDomain
Return the number of points in d
.
Base.rand(d::Union{Vector{D},Set{D}, D}) where {D<:AbstractDomain}
Extends Base.rand
to (a collection of) domains.
Base.rand(itv::Intervals)
Base.rand(itv::Intervals, i)
Return a random value from itv
, specifically from the i
th interval if i
is specified.
Base.rand(d::D) where D <: DiscreteDomain
Draw randomly a point in d
.
Base.rand(fa::FakeAutomaton)
Extends Base.rand
. Currently simply returns fa
.
x::Variable ∈ constraint
value ∈ x::Variable
Check if a variable x
is restricted by a constraint::Int
, or if a value
belongs to the domain of x
.
var::Int ∈ c::Constraint
Base.in(value, d <: AbstractDomain)
Fallback method for value ∈ d
that returns false
.
Base.in(x, itv::Intervals)
Return true
if x ∈ I
for any 'I ∈ itv, false otherwise.
x ∈ I` is equivalent to
a < x < b
ifI = (a, b)
a < x ≤ b
ifI = (a, b]
a ≤ x < b
ifI = [a, b)
a ≤ x ≤ b
ifI = [a, b]
Base.in(value, d::D) where D <: DiscreteDomain
Return true
if value
is a point of d
.
Base.string(D::Vector{<:AbstractDomain})
Base.string(d<:AbstractDomain)
Extends the string
method to (a vector of) domains.
Performances
Discrete
DiscreteDomain{T <: Number} <: AbstractDomain
An abstract supertype for discrete domains (set, range).
SetDomain{T <: Number} <: DiscreteDomain{T}
Domain that stores discrete values as a set of (unordered) points.
RangeDomain
A discrete domain defined by a range <: AbstractRange{Real}
. As ranges are immutable in Julia, changes in RangeDomain
must use set_domain!
.
ArbitraryDomain{T} <: DiscreteDomain{T}
A domain type that stores arbitrary values, possibly non numeric, of type T
.
domain()
Construct an EmptyDomain
.
domain(a::Tuple{T, Bool}, b::Tuple{T, Bool}) where {T <: Real}
domain(intervals::Vector{Tuple{Tuple{T, Bool},Tuple{T, Bool}}}) where {T <: Real}
Construct a domain of continuous interval(s).
domain(values)
domain(range::R) where {T <: Real, R <: AbstractRange{T}}
Construct either a SetDomain
or a RangeDomain
.
d1 = domain(1:5)
d2 = domain([53.69, 89.2, 0.12])
d3 = domain([2//3, 89//123])
d4 = domain(4.3)
d5 = domain(1,42,86.9)
domain_size(d <: AbstractDomain)
Fallback method for domain_size(d)
that return length(d)
.
domain_size(itv::Intervals)
Return the difference between the highest and lowest values in itv
.
domain_size(d::D) where D <: DiscreteDomain
Return the maximum distance between two points in d
.
add!(d::SetDomain, value)
Add value
to the list of points in d
.
merge_domains(d₁::AbstractDomain, d₂::AbstractDomain)
Merge two domains of same nature (discrete/contiuous).
intersect_domains(d₁, d₂)
Compute the intersections of two domains.
Base.size(i::I) where {I <: Interval}
Defines the size of an interval as its span
.
Extension to Base module
Base.delete!(d::SetDomain, value)(d::SetDomain, value)
Delete value
from the list of points in d
.
length(layer)
Return the number of operations in a layer.
Base.length(icn)
Return the total number of operations of an ICN.
Base.rand(d <: AbstractDomain)
Fallback method for length(d)
that return 0
.
Base.length(itv::Intervals)
Return the sum of the length of each interval in itv
.
Base.length(d::D) where D <: DiscreteDomain
Return the number of points in d
.
Base.rand(d::Union{Vector{D},Set{D}, D}) where {D<:AbstractDomain}
Extends Base.rand
to (a collection of) domains.
Base.rand(itv::Intervals)
Base.rand(itv::Intervals, i)
Return a random value from itv
, specifically from the i
th interval if i
is specified.
Base.rand(d::D) where D <: DiscreteDomain
Draw randomly a point in d
.
Base.rand(fa::FakeAutomaton)
Extends Base.rand
. Currently simply returns fa
.
x::Variable ∈ constraint
value ∈ x::Variable
Check if a variable x
is restricted by a constraint::Int
, or if a value
belongs to the domain of x
.
var::Int ∈ c::Constraint
Base.in(value, d <: AbstractDomain)
Fallback method for value ∈ d
that returns false
.
Base.in(x, itv::Intervals)
Return true
if x ∈ I
for any 'I ∈ itv, false otherwise.
x ∈ I` is equivalent to
a < x < b
ifI = (a, b)
a < x ≤ b
ifI = (a, b]
a ≤ x < b
ifI = [a, b)
a ≤ x ≤ b
ifI = [a, b]
Base.in(value, d::D) where D <: DiscreteDomain
Return true
if value
is a point of d
.
Base.string(D::Vector{<:AbstractDomain})
Base.string(d<:AbstractDomain)
Extends the string
method to (a vector of) domains.
Performances
General
Base.convert(::Type{Union{Intervals, RangeDomain}}, d::Union{Intervals, RangeDomain})
Extends Base.convert
for domains.
Exploration
ExploreSettings(domains;
complete_search_limit = 10^6,
max_samplings = sum(domain_size, domains),
search = :flexible,
solutions_limit = floor(Int, sqrt(max_samplings)))
Create an ExploreSettings
object to configure the exploration of a search space composed of a collection of domains.
Arguments
domains
: A collection of domains to be explored.complete_search_limit
: An integer specifying the maximum limit for complete search iterations. Default is 10^6.max_samplings
: An integer specifying the maximum number of samplings. Default is the sum of domain sizes.search
: A symbol indicating the type of search to perform. Default is:flexible
.solutions_limit
: An integer specifying the limit on the number of solutions. Default is the floor of the square root ofmax_samplings
.
Returns
ExploreSettings
object with the specified settings.
_explore(args...)
Internals of the explore
function. Behavior is automatically adjusted on the kind of exploration: :flexible
, :complete
, :partial
.
explore(domains, concept; settings = ExploreSettings(domains), parameters...)
Search (a part of) a search space and return a pair of vectors of configurations: (solutions, non_solutions)
. The exploration behavior is determined based on the settings
.
Arguments
domains
: A collection of domains to be explored.concept
: The concept representing the constraint to be targeted.settings
: An optionalExploreSettings
object to configure the exploration. Default isExploreSettings(domains)
.parameters...
: Additional parameters for theconcept
.
Returns
- A tuple of sets:
(solutions, non_solutions)
.
Performances
Parameters
BoolParameterDomain <: AbstractDomain
A domain to store boolean values. It is used to generate random parameters.
DimParameterDomain <: AbstractDomain
A domain to store dimensions. It is used to generate random parameters.
IdParameterDomain <: AbstractDomain
A domain to store ids. It is used to generate random parameters.
FakeAutomaton{T} <: ConstraintCommons.AbstractAutomaton
A structure to generate pseudo automaton enough for parameter exploration.
accept(a::Union{Automaton, MDD}, w)
Return true
if a
accepts the word w
and false
otherwise.
ConstraintCommons.accept(fa::FakeAutomaton, word)
Implement the accept
methods for FakeAutomaton
.
LanguageParameterDomain <: AbstractDomain
A domain to store languages. It is used to generate random parameters.
OpParameterDomain{T} <: AbstractDomain
A domain to store operators. It is used to generate random parameters.
PairVarsParameterDomain{T} <: AbstractDomain
A domain to store values paired with variables. It is used to generate random parameters.
ValParameterDomain{T} <: AbstractDomain
A domain to store one value. It is used to generate random parameters.
ValsParameterDomain{T} <: AbstractDomain
A domain to store values. It is used to generate random parameters.
Base.rand(d::Union{Vector{D},Set{D}, D}) where {D<:AbstractDomain}
Extends Base.rand
to (a collection of) domains.
Base.rand(itv::Intervals)
Base.rand(itv::Intervals, i)
Return a random value from itv
, specifically from the i
th interval if i
is specified.
Base.rand(d::D) where D <: DiscreteDomain
Draw randomly a point in d
.
Base.rand(fa::FakeAutomaton)
Extends Base.rand
. Currently simply returns fa
.
generate_parameters(d<:AbstractDomain, param)
Generates random parameters based on the domain d
and the kind of parameters param
.