evaluate the expression for a given feature selection (all features not provided are assumed deselected)
evaluate the expression for a given feature selection (all features not provided are assumed deselected)
features provided as a list of names (how they would be created with createDefinedExternal)
evaluates to true or false
map function that applies to all leafs in the feature expression (i.
map function that applies to all leafs in the feature expression (i.e. all DefinedExpr nodes)
helper function for statistics and such that determines which features are involved in this feature expression
helper function for statistics and such that determines which features are involved in this feature expression
counts the number of features in this expression for statistic purposes
uses a SAT solver to determine whether two expressions are equivalent.
uses a SAT solver to determine whether two expressions are equivalent.
for performance reasons, it checks pointer equivalence first, but won't use the recursive equals on aexpr (there should only be few cases when equals is more accurate than eq, which are not worth the performance overhead)
NOT implemented, this method will always return None.
NOT implemented, this method will always return None.
NOT implemented, this method will always return None.
NOT implemented, this method will always return None.
checks whether there is some unresolved macro (DefinedMacro) somewhere in the expression tree
x.
x.isSatisfiable(fm) is short for x.and(fm).isSatisfiable but is faster because FM is cached
heuristic to determine whether a feature expression is small (may be used to decide whether to inline it or not)
heuristic to determine whether a feature expression is small (may be used to decide whether to inline it or not)
use with care
FM -> X is tautology if FM.
FM -> X is tautology if FM.implies(X).isTautology or !FM.and.(x.not).isSatisfiable
not final for optimization purposes
Prints the textual representation of this formula on a Writer.
Prints the textual representation of this formula on a Writer. The result shall be equivalent to p.print(toTextExpr), but it should avoid consuming so much temporary space.
the output Writer
replaces all DefinedMacro tokens by their full expansion.
replaces all DefinedMacro tokens by their full expansion.
the resulting feature expression contains only DefinedExternal nodes as leafs and can be printed and read again
creates an equivalent feature expression in CNF
creates an equivalent feature expression in CNF
be aware of exponential explosion. consider using toCnfEquiSat instead if possible
creates an equisatisfiable feature expression in CNF
creates an equisatisfiable feature expression in CNF
the result is not equivalent but will yield the same result in satisifiability tests with SAT solvers
the algorithm introduces new variables and is faster than toCNF
Converts this formula to a textual expression.
Converts this formula to a textual expression.
unique existential quantification over feature "feature".
unique existential quantification over feature "feature".
This has the effect of substituting the feature by true and false respectively and returning the xor of both: this[feature->True] xor this[feature->False]
It can be seen as identifying under which condition the feature matters for the result of the formula
Propositional (or boolean) feature expressions.
Feature expressions are compared on object identity (comparing them for equivalence is an additional but expensive operation). Connectives such as "and", "or" and "not" memoize results, so that the operation yields identical results on identical parameters. Classes And, Or and Not are made package-private, and their constructors wrapped through companion objects, to prevent the construction of formulas in any other way.
However, this is not yet enough to guarantee the 'maximal sharing' property, because the and/or operators are also associative, but the memoization cannot be associative. Papers on hash-consing explain that one needs to perform a further normalization step.
More in general, one can almost prove a theorem called the weak-canonicalization guarantee:
If at a given time during program execution, two formula objects represent structurally equal formulas, i.e. which are deeply equal modulo the order of operands of "and" and "or", then they are represented by the same object.
XXX: HOWEVER, that the associative property does not hold with pointer equality: (a and b) and c ne a and (b and c). Hopefully this is fixable through different caching.
Note that this is not related to formula equivalence, rather to pointer equality. This does not hold for formulas existing at different moments, because caches are implemented using weak references, so if a formula disappears from the heap it is recreated. However, this is not observable for the code.
The weak canonicalization property, if true, should allows also ensuring the strong-canonicalization guarantee: If at a given time during program execution, two formula objects a and b represent equivalent formulas, then a.toCNF eq b.toCNF (where eq denotes pointer equality).
CNF canonicalization, by construction, ensures that a.toCNF and b.toCNF are structurally equal. The weak canonicalization property would also ensure that they are the same object.
It would be interesting to see what happens for toEquiCNF.