The CtcInter contractor
Main author: Simon Rohou
-
template<typename ...X>
class CtcInter : public codac2::Ctc<CtcInter<X...>, X...> Sequential intersection of several contractors:
\[\mathcal{C}_{\mathrm{inter}} = \mathcal{C}_1 \cap \mathcal{C}_2 \cap \dots \cap \mathcal{C}_n. \]Each sub-contractor is applied successively to the current domain. If two contractors implement two constraints, then their intersection corresponds to the logical conjunction of these constraints. This corresponds to the classical intersection/composition pattern of contractor programming.
CtcInterstores a collection of contractors acting on the same contracted types and applies them one after the other. For instance, for contractors acting on a single box \([\mathbf{x}]\):\[\left(\mathcal{C}_1 \cap \mathcal{C}_2\right)([\mathbf{x}]) := \mathcal{C}_1([\mathbf{x}]) \cap \mathcal{C}_2([\mathbf{x}]). \]In practice, each stored contractor contracts the current domain in place; the next one then works on the already reduced result. It does not perform any fixpoint iteration. If the domain becomes empty at some step, the contraction stops immediately.
A
CtcInterobject can be built explicitly, extended incrementally with&=, or constructed implicitly with the binary&operator between two contractors.In C++, a variadic
.contract(..)function is available when the intersected contractors act on several domains rather than on a single box. Such contractors can be combined provided they are homogeneous, i.e. they act on the same sequence of input types.- Template Parameters:
X – Contracted domain type(s). For the common box-contractor case, this is typically
IntervalVector.
Basic usage
The most common way to create an intersection contractor is to combine two existing
contractors with &.
c1 = CtcWrapper([[-10,10],[-2,2]])
c2 = CtcWrapper([[-12,2],[0,4]])
c3 = c1 & c2
# c3 is a CtcInter gathering the two contractors.
CtcWrapper c1(IntervalVector({{-10,10},{-2,2}}));
CtcWrapper c2(IntervalVector({{-12,2},{0,4}}));
auto c3 = c1 & c2;
// c3 is a CtcInter<IntervalVector> gathering the two contractors.
Once built, the contractor can be applied as any other box contractor.
x = IntervalVector([[-oo,oo],[-oo,oo]])
x = c3.contract(x)
# x = [ [-10, 2] ; [0, 2] ]
IntervalVector x({{-oo,oo},{-oo,oo}});
c3.contract(x);
// x = [ [-10, 2] ; [0, 2] ]
In this example, c1 restricts the box to \([-10,10]\times[-2,2]\) and c2
restricts it to \([-12,2]\times[0,4]\). Their conjunction therefore contracts the
initial box to:
Building a conjunction incrementally
A CtcInter may also be created from a prescribed domain size and then populated later.
In that case, the object is initially neutral: as long as no sub-contractor is added, it
has no effect on the contracted box.
c4 = CtcInter(2) # initially neutral conjunction on 2d boxes
c4 &= c1
c4 &= c2
n = c4.nb()
# n = 2
CtcInter c4(2); // initially neutral conjunction on 2d boxes
c4 &= c1;
c4 &= c2;
auto n = c4.nb();
// n = 2
The method nb() returns the current number of sub-contractors stored in the
intersection.
Technical documentation
See the C++ API documentation of this class.