
fr.lirmm.boreal.util.PiecesSplitter Maven / Gradle / Ivy
Show all versions of integraal-util Show documentation
/**
*
*/
package fr.lirmm.boreal.util;
import fr.boreal.model.logicalElements.api.Atom;
import fr.boreal.model.logicalElements.api.Variable;
import java.util.*;
/**
* Split a set of atoms in pieces
* A piece of an atom set is a set of atoms such that the atoms containing a variable v
* are all in the same piece and the size of the pieces is minimal for this property
*
* You can choose if you want to include grounded atoms as their own piece or exclude them from the splitting
*
* @author Guillaume Pérution-Kihli
*
*/
public class PiecesSplitter {
private final boolean includeGroundedAtoms;
private Collection existentialVariables;
/**
* Default constructor
*
* By default, grounded atoms are included
*
*/
public PiecesSplitter() {
this(true);
}
/**
* @param includeGroundedAtoms to declare if grounded atoms should be included
*/
public PiecesSplitter(boolean includeGroundedAtoms) {
this(includeGroundedAtoms, null);
}
/**
* @param includeGroundedAtoms to declare if grounded atoms should be included
* @param existentialVariables pre-computed existential variables
*/
public PiecesSplitter(boolean includeGroundedAtoms, Collection existentialVariables) {
this.includeGroundedAtoms = includeGroundedAtoms;
this.existentialVariables = existentialVariables;
}
/**
* Splits the given atoms into single piece
*
* @param toSplit atoms to split into single pieces
* @return pieces of atoms
*/
public Collection> split(Collection toSplit) {
List> pieces = new ArrayList<>();
if(this.existentialVariables == null) {
this.existentialVariables = new HashSet<>();
toSplit.forEach(atom -> this.existentialVariables.addAll(atom.getVariables()));
}
Collection variables = this.existentialVariables;
Set varToTreat = new HashSet<>(variables);
while (!varToTreat.isEmpty()) {
Variable root = varToTreat.iterator().next();
Deque queue = new ArrayDeque<>();
queue.add(root);
Collection piece = new HashSet<>();
while (!queue.isEmpty()) {
Variable v = queue.pollFirst();
varToTreat.remove(v);
for (Atom a : toSplit) {
if (a.contains(v)) {
a.getVariables().stream()
.filter(vv -> variables.contains(vv) && varToTreat.contains(vv))
.distinct()
.forEach(vv -> {
queue.add(vv);
varToTreat.remove(vv);
});
piece.add(a);
}
}
}
pieces.add(piece);
}
if (this.includeGroundedAtoms) {
for (Atom a : toSplit) {
long nbVar = a.getVariables().stream()
.filter(variables::contains)
.distinct()
.count();
// If the atom is not totally grounded
if (nbVar == 0) {
Collection atomSet = new HashSet<>();
atomSet.add(a);
pieces.add(atomSet);
}
}
}
return pieces;
}
}