Now, suppose that we want to encode the input constraint (which is marked with the tag 1) redundantly with two encoders. We have to create an instance of each of these encoders, and to assign these encoders to the tag 1. As a consequence, each constraint of the input model tagged with 1 will be translated using these two encoders.

Encoder2cnf direct = new **CNFdirectEncoder** ( ) ;
Encoder2cnf bdd = new **CNFbddEncoder** ( ) ;
out . **assignEncoder** ( 1 , **direct** ) ; out . **assignEncoder** ( 1 , bdd ) ;
The translation process will be achieved by reading the input model thanks to the method read **of the output**
problem.

out . **read** ( m ) ;
The resulting cnf **formula is given in** dimacs format by the method **getOutput**.

System . out . print ( out . **getOutput** ( ) ) ;
For example, if only the encoder CNFdirectEncoder **is used, the result is the following:**
p cnf 3 1
−1 2 −3 0 This encoder produces an exponential number of clauses in the general case, but can produce quite compact outputs from small input constraints. The currently available encoders will be described in section 3. To conclude this brief presentation, let us mention that BoolVar also provide a class PBproblem and an encoder PBbasicEncoder **allowing to produce the output problem as an instance of pseudo-Boolean**
satisfiability with the opb **format. This allows a same input problem to be solved either using a** sat **solver** and a pseudo-Boolean satisfiability solver, in order to compare the performances and the relevance of the two approaches.

## 2 Description

This section presents the main aspects and resources of BoolVar/pb **from the user side and as well as a**
short description of its internal structure.

## 2.1 Architecture

Figure 1 presents the architecture of the BoolVar/pb **library, which can be decomposed in three parts: the** input block, the output block, ans the internal block.

## 2.1.1 The Input Block

This part includes the classes allowing the user to create and specify an input problem.

## Inputmodel

The container for the input constraints. Its constructor must be used to create a new input problem where the input constraints will be added thank to the method **addConstraint**.

Constraint An interface requiring that any input constraint implements a method addTag**, which allows to assign** tags to constraints.

## Genericconstraint

An abstract class which implements the tag management system, which is the same for any input constraint.