All Downloads are FREE. Search and download functionalities are using the official Maven repository.

fr.lirmm.boreal.util.PiecesSplitter Maven / Gradle / Ivy

/**
 * 
 */
package fr.lirmm.boreal.util;

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Deque;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import fr.boreal.model.logicalElements.api.Atom;
import fr.boreal.model.logicalElements.api.Variable;

/**
 * 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 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();
		varToTreat.addAll(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);
				
				Iterator it = toSplit.iterator();
				while (it.hasNext()) {
					Atom a = it.next();
					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) {
			Iterator it = toSplit.iterator();
			while (it.hasNext()) {
				Atom a = it.next();
				long nbVar = a.getVariables().stream()
						.filter(v -> variables.contains(v))
						.distinct()
						.count();
				
				// If the atom is not totally grounded
				if (nbVar == 0) {
					Collection atomSet = new HashSet();
					atomSet.add(a);
					pieces.add(atomSet);
				}
			}
		}
		
		return pieces;
	}
	
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy