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

fr.boreal.model.kb.api.FactBase Maven / Gradle / Ivy

The newest version!
package fr.boreal.model.kb.api;

import fr.boreal.model.kb.impl.FactBaseDescription;
import fr.boreal.model.logicalElements.api.*;
import fr.boreal.model.logicalElements.impl.SubstitutionImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * A FactBase represents a set of Atom seen as a conjunction
 * 
 * @author Florent Tornil
 * @author Federico Ulliana
 * @author Guillaume Pérution-Kihli
 *
 */
public interface FactBase extends Readable, Writeable {

	/**
	 * @return a stream over all the atoms of the factbase
	 */
	Stream getAtoms();

	/**
	 * Returns a set of all the atoms in the fact base
	 * This method can be costly in memory if the fact base is not in memory
	 *
	 * @return a set containing all the atoms of the fact base
	 */
	default Set getAtomsInMemory() {
		return getAtoms().collect(Collectors.toSet());
	}

	/**
	 * @return a stream over all the variables of the fact base
	 */
	default Stream getVariables() {
		return getAtoms().flatMap(a -> a.getVariables().stream()).distinct();
	}

	/**
	 * @return a stream over all the terms of the fact base
	 */
	default Stream getTerms() {
		return getAtoms().flatMap(a -> Arrays.stream(a.getTerms())).distinct();
	}

	/**
	 * @return a stream over all the constants of the fact base
	 */
	default Stream getConstants() {
		return getAtoms().flatMap(a -> a.getConstants().stream()).distinct();
	}

	/**
	 * @return a stream over all the literals of the fact base
	 */
	default Stream> getLiterals() {
		return getAtoms().flatMap(a -> a.getLiterals().stream()).distinct();
	}

	/**
	 * Returns an iterator over all atoms with the specified predicate.
	 *
	 * @param predicate to search
	 * @return an iterator over all atoms with the specified predicate
	 */
	Iterator getAtomsByPredicate(Predicate predicate);

	/**
	 * Returns an iterator over all atoms with the specified term.
	 *
	 * @param term to search
	 * @return an iterator over all atoms with the specified term
	 */
	default Iterator getAtomsByTerm(Term term) {
		return getAtoms().filter(a -> Arrays.asList(a.getTerms()).contains(term)).iterator();
	}

	/**
	 * Returns an Iterator of all predicates in this factbase.
	 * 
	 * @return an Iterator of all predicates.
	 */
	Iterator getPredicates();

	/**
	 * Returns an iterator over terms which are in a specific position in at
	 * least one atom with the given predicate.
	 * 
	 * @param p predicate
	 * @param position the position of the term in atoms, positions starts from 0.
	 * @return an iterator over terms which appear in the specified position of the specified predicate.
	 */
	Iterator getTermsByPredicatePosition(Predicate p, int position);

	/**
	 * @param t the term that all atoms must contain
	 * @return a stream over all the atoms of the factbase that contains the given
	 *         term t
	 */
	default Stream getAtoms(Term t) {
		return this.getAtoms().filter(a -> a.contains(t));
	}

	/**
	 * @param a the atom to find
	 * @return true iff this storage contains the given atom
	 */
	default boolean contains(Atom a) {
		return this.getAtoms().anyMatch(atom -> atom.equals(a));
	}

	/**
	 * @return the number of atoms represented by this factbase
	 */
	default long size() {
		return this.getAtoms().count();
	}

	// Tatooine temporary methods

	/**
	 * @param viewPredicate a predicate
	 * @return the description of the storage
	 */
	FactBaseDescription getDescription(Predicate viewPredicate);

	/**
	 * @param viewPredicate a predicate
	 * @return the type of storage used for the given predicate
	 */
	FactBaseType getType(Predicate viewPredicate);

	/**
	 * @param viewPredicate a predicate
	 * @return the type of the columns for the given predicate
	 */
	default List getColumnsType(Predicate viewPredicate) {
		int arity = viewPredicate.arity();
		List types = new ArrayList<>(arity);
		for (int i = 0; i < arity; i++) {
			types.add(ColumnType.STRING);
		}
		return types;
	}

	/**
	 * Removes all atoms from the fact base.
	 */
	@Override
	default void clear() {
		List batch;
		do {
			// Collect a batch of atoms to avoid ConcurrentModificationException
			batch = this.getAtoms().limit(1000).toList();
			this.removeAll(batch);
		} while (!batch.isEmpty());
	}

	/**
	 * Estimates the upper bound of the number of atoms that match the given atom.
	 * The estimation is the upper bound, meaning the actual number of matching atoms will not exceed this number.
	 * Implementations may return an empty Optional if they cannot provide an estimation.
	 *
	 * @param atom the atom to match
	 * @return an Optional containing the estimated upper bound of matching atoms, or an empty Optional if estimation is not possible
	 */
	default Optional estimateMatchCount(Atom atom) {
		return estimateMatchCount(atom, new SubstitutionImpl());
	}

	/**
	 * Estimates the upper bound of the number of atoms that match the given atom with a substitution.
	 * The estimation is the upper bound, meaning the actual number of matching atoms will not exceed this number.
	 * Implementations may return an empty Optional if they cannot provide an estimation.
	 *
	 * @param atom the atom to match
	 * @param substitution the substitution to apply
	 * @return an Optional containing the estimated upper bound of matching atoms, or an empty Optional if estimation is not possible
	 */
	default Optional estimateMatchCount(Atom atom, Substitution substitution) {
		return Optional.empty();
	}

	/**
	 * Determines if the fact base can perform an indexed match for the given atom.
	 * This method checks if the fact base can avoid a full scan of all atoms or all atoms with the same predicate.
	 *
	 * @param atom the atom to match
	 * @return true if the fact base can perform an indexed match for the given atom; false otherwise
	 */
	default boolean canPerformIndexedMatch(Atom atom) {
		return estimateMatchCount(atom).isPresent();
	}

	/**
	 * Determines if the fact base can perform an indexed match for the given atom with a substitution.
	 * This method checks if the fact base can avoid a full scan of all atoms or all atoms with the same predicate.
	 *
	 * @param atom the atom to match
	 * @param substitution the substitution to apply
	 * @return true if the fact base can perform an indexed match for the given atom with the substitution; false otherwise
	 */
	default boolean canPerformIndexedMatch(Atom atom, Substitution substitution) {
		return estimateMatchCount(atom, substitution).isPresent();
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy