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.

CtcInter stores 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 CtcInter object 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.

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] ]

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:

\[[-10,10]\times[-2,2] \ \cap \ [-12,2]\times[0,4] \,=\, [-10,2]\times[0,2].\]

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

The method nb() returns the current number of sub-contractors stored in the intersection.

Technical documentation

See the C++ API documentation of this class.