Location: Welcome > Documentation > Upgrading FaMa

Upgrading FaMa


HowTo integrate your own Reasoner

In order to include your own reasoner into the SPL Reasoner architecture, you have to know well some aspects of it. Because of this, we are go to take a look at the classes diagram of this part of the design.

The three main elements we manage are:

  • Reasoner: the main module, which implements the reasoner state handler and the transformation routines from the feature model elements to the reasoner elements.
  • Result: at this element, we define the methods that returns the results of the reasoning process.
  • Question: we have to define one abstract class for the reasoner and one class extended from this for each type of question the reasoner is going to support.

And an auxiliar structure we define for configuration and maintenance issues, saved on a XML file we specify later.

This is an example of the config.xml configuration file the Jar file has to include al root directory. Inside we match each question interface or requirement with its implementation into the reasoner:

<reasoner>
<question interface="es.us.isa.FAMA.Reasoner.questions.ProductsQuestion" class="es.us.isa.JavaBDDReasoner.questions.JavaBDDProductsQuestion"/>
<question interface="es.us.isa.FAMA.Reasoner.questions.ValidQuestion" class="es.us.isa.JavaBDDReasoner.questions.JavaBDDValidQuestion"/>
<question interface="es.us.isa.FAMA.Reasoner.questions.SetQuestion" class="es.us.isa.JavaBDDReasoner.questions.JavaBDDSetQuestion"/>
<question interface="es.us.isa.FAMA.Reasoner.questions.NumberOfProductsQuestion" class="es.us.isa.JavaBDDReasoner.questions.JavaBDDNumberOfProductsQuestion"/>
<question interface="es.us.isa.FAMA.Reasoner.questions.FilterQuestion" class="es.us.isa.JavaBDDReasoner.questions.JavaBDDFilterQuestion"/>
<question interface="es.us.isa.FAMA.Reasoner.questions.CommonalityQuestion" class="es.us.isa.JavaBDDReasoner.questions.JavaBDDCommonalityQuestion"/>
</reasoner>

This is not the unique configuration file we have to modify, also at the main configuration file FAMAconfig.xml, we are going to add a new row with our reasoner specification. Here we�ve got an example:

<questionTrader>
<reasoner id="Sat4j" file="lib/Sat4jReasoner.jar" class="es.us.isa.Sat4jReasoner.Sat4jReasoner"/>
<criteriaSelector name="default" class="es.us.isa.FAMA.Reasoner.DefaultCriteriaSelector"/>
<question id="Products" interface="es.us.isa.FAMA.Reasoner.questions.ProductsQuestion" file="lib/FAMAquestions.jar"/>
<question id="#Products" interface="es.us.isa.FAMA.Reasoner.questions.NumberOfProductsQuestion" file="lib/FAMAquestions.jar"/>
<question id="Commonality" interface="es.us.isa.FAMA.Reasoner.questions.CommonalityQuestion" file="lib/FAMAquestions.jar"/>
<models>
<reader extensions="xml,fama" class="es.us.isa.FAMA.models.FAMAfeatureModel.fileformats.XMLReader" file="lib/FAMAmodel.jar"/>
<writer extensions="xml,fama" class="es.us.isa.FAMA.models.FAMAfeatureModel.fileformats.XMLWriter" file="lib/FAMAmodel.jar"/>
</models>
</questionTrader>

The row <reasoner id=�� file=�� class=�� /> has three elements we have to fill:

  • id: the name of the reasoner
  • file: the Jar file in which we con find the reasoner files
  • class: the main class of the reasoner that extends from reasoner abstract class.

HowTo integrate your own Criteria

There is a easy way to include a new criteria in the tool configuration. First, you have to create a new class that extends from CriteriaSelector. You can take the DefaultCriteriaSelector as example. This new class has to implement two methods, one of them is the most important: createQuestion, this method receive one VM and one QuestionClass. This method should contain an algoritm to select one of all available reasoners. Once it is selected, we call to its factory to create the Question instance providing the QuestionClass. Also, we return it.

After this we have to modify the configuration file with one more line corresponding to our new criteria. Something like this is valid:

<criteriaSelector name="newCriteria" class="es.us.isa.FAMA.Reasoner.NewCriteriaSelector" />

HowTo integrate your own Questions

To introduce new questions in the framework, the first thing you have to do is define their interfaces, and include them in all available questions. After this, you must provide the implementation of these new questions in the reasoner(s) implementation, as explained in the preceding section HowTo add your own Reasoner.

The interface of the question has to extend the generic interface Question. At the level of the interface we define those methods that we need to implement the question on the reasoner. These interfaces are included in a jar and this in a folder within the framework.

Finally, we have to tell the framework the new question(s) is available for use. We do this modifing the configuration file FAMAconfig.xml. We have to add a line defining the identification of the question, the package in which it is included and the jar file we provide. Here you can see an example with one of the questions already implemented:

<question id="Products" interface="es.us.isa.FAMA.Reasoner.questions.ProductsQuestion" file="lib/FAMAquestions.jar"/>

HowTo integrate your own Metamodel

If you want to add your own metamodel to SPLReasoner, you have to follow the following steps:

  1. Define the metamodel structure.
  2. Implement the transformations from the metamodel to the reasoner model.
  3. Implement the loaders and savers you�re going to use.

The second point is the most important and it is where we�re going to start.

Metamodel Transformations

Basically, we define model to model transformation using the methods provided by the tool. In SPLReasoner there is an interface specified for metamodel transformations. All you have to do is create a class that implements the interface ITransform. In this class, you have to run the metamodel and call the suitable method to convert each node to a constraint the reasoner has to solve.

One part of this interface is ITransform. Its specification looks as follow:

  public interface ITransform {
public void transform (VariabilityModel vmodel, Reasoner reasoner);
public void update ();
}

At the constructor, we get the metamodel and the reasoner. At the main method for this class, for each element on our metamodel we have to call to one method of the reasoner in order to construct the same structure in a semantic that the reasoner is able to understand.

These methods are public at the reasoner:

List of methods

addRoot(GenericFeature)
addFeature(GenericFeature, Collection<Cardinality>)
addMandatory(GenericRelation, GenericFeature, GenericFeature)
addOptional(GenericRelation, GenericFeature, GenericFeature)
addCardinality(GenericRelation, GenericFeature, GenericFeature, Iterator<Cardinality>)
addSet(GenericRelation, GenericFeature, Collection<GenericFeature>, Collection<Cardinality>)
addExcludes(GenericRelation, GenericFeature, GenericFeature)
addRequires(GenericRelation, GenericFeature, GenericFeature)
  • addRoot: This method must be the first call at the process. Like that, we transform the root of the model to the root of the reasoner model.
  • addFeature: With this method we could add a feature from our model to the reasoner model. To do this, we set as parameters the feature and a set of cardinalities linked to this feature.
  • addOptional: With this method we transform an optional relatioship.
  • addCardinality: With this method we transform a cardinality linked to a relatioship between features.
  • addSet:
  • addExcludes: With this method we transform a excludes constraint between features.
  • addRequires: With this method we transform a requires constraint between features.