We provide multiple notations for specifying feature models ( SPLOT,  GUIDSL/FeatureIDE, a subset of  TVL, etc.) It means you can:

  • load feature models in those notations (using FM constructor) ;
  • serialize the feature models in those notations (using save).

Loading Feature Models

Internal notation

fm1 = FM (A : B C [D]; D : (E|F|G); C : (H|I|J)+ ; (!C | I) ; )

  • A is the root
  • B, C and D are child-features of A: B and C are mandatory whereas D is optional
  • E, F and G form a Xor-group and are child-features of D
  • H, I, and J form an Or-group and are child-features of C
  • (!C | I) is equivalent to (C -> I) and is an internal constraint of the feature model

Here is a diagrammatic representation of fm1 with FeatureIDE editor:

fm1 in FeatureIDE

See the grammar below:

FeatureModel : 'FM' LEFT_PAREN  (features+=Production ';')+ ( expr+=Constraint ';')* ) RIGHT_PAREN ;
Production  : name=FML_IDENTIFIER ':' features+=Child ;

Child       : (Mandatory
                | Optional
                | Mutexgroup 
                | Xorgroup
                | Orgroup) ;

Mandatory   : name=ID ;
Optional    : '[' name=FML_IDENTIFIER ']' ;
Mutexgroup   : LEFT_PAREN features+=ID  ('|' features+=ID)+ RIGHT_PAREN '?' ;
Xorgroup   : LEFT_PAREN features+=ID  ('|' features+=ID)+ RIGHT_PAREN ;
Orgroup    : LEFT_PAREN features+=ID  ('|' features+=ID)+ RIGHT_PAREN '+' ;

ID : ('^')?('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'_'|'0'..'9')*; 

Constraint       : Constraint  ('|' | '&' | '->' | '<->') Constraint
            | '!' Constraint 
            | '(' Constraint ')'
            | ID

Importing feature models in other notation

You can also import feature models in other notation. This time, you need to specify a filename (using quotes).

FM ("filename")

At the moment, the filename extension is important (see below for the corresponding between extension and format)

FML interoperability

For example,

fm2 = FM ("internal1.m")

assigns to fm2 a feature model which has been created using FeatureIDE notation and file with name "internal1.m".

Formats currently supported

See https://nyx.unice.fr/projects/familiar/milestone/Interoperability%3A%20convert%20in%20different%20formats (you need a login)

Serializing Feature Models

You can serialize feature models in different formats.

First, the convert returns a string representation of the feature model in the specified format.

fml> convert fm1 in featureide
res0: (STRING) A : [D] B C+ :: _A ;

D : E
	| G
	| F ;

C : J
	| I
	| H ;


C implies I ;

save serializes the content of convert, e.g., (convert fm1 in featureide), in a file (by default, in the "output" folder of the Eclipse project in which the FAMILIAR script is executed or in the standalone version, in the "output" folder where the jar is located).

Other facilities to interoperate

  • Loading
    • You can implement a bridge between your formalism and one of the formalism supported by FAMILIAR
      • Hint: it can be a model-to-text transformation or a model-to-model transformation (using the Ecore metamodel generated by Xtext)
    • Note that FAMILIAR can load a feature model serialized in an XMI file conforms to the Ecore metamodel generated by Xtext.
    • You can use the class FMLFeatureModelReader.java
FeatureModel fm = new FMLFeatureModelReader().parseString("FM (A: B C [D];) ");
FeatureModel fm2 = new FMLFeatureModelReader().parseFile(new File("examples/testing/FMs/fm2.fml"));
XMIResource xmi = new FMLFeatureModelWriter(fm2).toXMI("examples/testing/FMs/fm2ecore");
FeatureModel fm3 = new FMLFeatureModelReader().parseXMIFile(xmi);

  • Serializing
    • Once a feature model is serialized in an XMI file conforms to the Ecore metamodel generated by Xtext, you can use state-of-the-art modeling tools to visit the model.
    • Or simply using the class FMLFeatureModelWriter.java
// serializing fm2 to XMI
XMIResource xmi = new FMLFeatureModelWriter(fm2).toXMI("examples/testing/FMs/fm2ecore");
// or to text (String representation)
new FMLFeatureModelWriter(fm2).toString() ; 
public abstract class FeatureModelVisitor {
	 *  the feature model to visit
	protected FeatureModel fm ;
	public FeatureModelVisitor(FeatureModel fm) {
		this.fm = fm ;
	 * Entry point
	public abstract String treatFeatureModel(FeatureModel fm) ; 
	 * Treat a production (like a grammar production in GUIDSL)
	public abstract String treatProd(Production prod) ;

	 * Treat a child feature (Xor, Or, And)
	public abstract String treatChild(Child c) ;

	 * Treat a constraint (e.g., A implies B)
	public abstract String treatConstraint(CNF constraint) ;