fr.boreal.storage.natives.FactBaseDelAtomsWrapper Maven / Gradle / Ivy
Show all versions of integraal-storage Show documentation
package fr.boreal.storage.natives;
import com.github.jsonldjava.shaded.com.google.common.collect.Streams;
import fr.boreal.model.formula.api.FOFormula;
import fr.boreal.model.kb.api.ColumnType;
import fr.boreal.model.kb.api.FactBase;
import fr.boreal.model.kb.api.FactBaseType;
import fr.boreal.model.kb.impl.FactBaseDescription;
import fr.boreal.model.logicalElements.api.*;
import java.util.*;
import java.util.stream.Stream;
/**
* This class is a wrapper around a fact base that allows virtual deletions of atoms.
* Atoms are not physically removed from the wrapped fact base, but are virtually
* marked as removed.
* When querying the fact base through this wrapper, any atom
* marked as removed will be excluded from the results.
*
* This class is useful for scenarios where you want to simulate the removal of facts
* from a knowledge base without actually deleting the data, allowing flexible
* "undo" operations or temporary filters.
*
* Additionally, this class provides a method to permanently remove atoms from the
* underlying fact base after they have been marked for virtual deletion.
*
* @author Guillaume Pérution-Kihli
*/
public class FactBaseDelAtomsWrapper implements FactBase {
final FactBase factBase;
final Set removedAtoms;
/**
* Constructs a new FactBaseDelAtomsWrapper instance, wrapping the provided fact base
* and initializing the set of atoms to be virtually removed.
*
* @param factBase the underlying fact base to wrap
* @param removedAtoms the set of atoms to be virtually removed
*/
public FactBaseDelAtomsWrapper(FactBase factBase, Set removedAtoms) {
this.factBase = factBase;
this.removedAtoms = removedAtoms;
}
/**
* Concrete the virtual deletions by permanently removing all atoms
* currently marked as removed in the underlying fact base.
* After this method, the set of removed atoms will be cleared.
*/
public void concreteDeletions() {
removedAtoms.forEach(factBase::remove);
removedAtoms.clear();
}
@Override
public Stream getAtoms() {
return this.factBase.getAtoms().filter(a -> !removedAtoms.contains(a));
}
@Override
public Set getAtomsInMemory() {
return new AbstractSet<>() {
@Override
public Iterator iterator() {
return FactBaseDelAtomsWrapper.this.getAtoms().iterator();
}
@Override
public int size() {
return (int) FactBaseDelAtomsWrapper.this.size();
}
@Override
public boolean contains(Object o) {
if (!(o instanceof Atom atom)) return false;
return !removedAtoms.contains(atom) && factBase.getAtomsInMemory().contains(atom);
}
};
}
@Override
public Stream getVariables() {
return this.getAtoms().parallel().flatMap(atom -> atom.getVariables().stream())
.distinct();
}
@Override
public Stream getTerms() {
return this.getAtoms().parallel().flatMap(atom -> Arrays.stream(atom.getTerms()))
.distinct();
}
@Override
public Stream getConstants() {
return this.getAtoms().parallel().flatMap(atom -> atom.getConstants().stream())
.distinct();
}
@Override
public Stream> getLiterals() {
return this.getAtoms().parallel().flatMap(atom -> atom.getLiterals().stream())
.distinct();
}
@Override
public Iterator getAtomsByPredicate(Predicate predicate) {
return Streams.stream(this.factBase.getAtomsByPredicate(predicate))
.filter(a -> !removedAtoms.contains(a))
.iterator();
}
@Override
public Iterator getAtomsByTerm(Term term) {
return Streams.stream(this.factBase.getAtomsByTerm(term))
.filter(a -> !removedAtoms.contains(a))
.iterator();
}
@Override
public Iterator getPredicates() {
return this.getAtoms().map(Atom::getPredicate).distinct().iterator();
}
@Override
public Iterator getTermsByPredicatePosition(Predicate p, int position) {
return this.getAtoms()
.filter(a -> a.getPredicate().equals(p))
.map(a -> a.getTerm(position))
.distinct()
.iterator();
}
@Override
public Stream getAtoms(Term t) {
return this.factBase.getAtoms(t).filter(a -> !removedAtoms.contains(a));
}
@Override
public boolean contains(Atom a) {
return !removedAtoms.contains(a) && this.factBase.contains(a);
}
@Override
public long size() {
return this.factBase.size() - removedAtoms.size();
}
@Override
public FactBaseDescription getDescription(Predicate viewPredicate) {
return this.factBase.getDescription(viewPredicate);
}
@Override
public FactBaseType getType(Predicate viewPredicate) {
return this.factBase.getType(viewPredicate);
}
@Override
public List getColumnsType(Predicate viewPredicate) {
return this.factBase.getColumnsType(viewPredicate);
}
@Override
public Optional estimateMatchCount(Atom atom) {
return this.factBase.estimateMatchCount(atom);
}
@Override
public Optional estimateMatchCount(Atom atom, Substitution substitution) {
return this.factBase.estimateMatchCount(atom, substitution);
}
@Override
public boolean canPerformIndexedMatch(Atom atom) {
return this.factBase.canPerformIndexedMatch(atom);
}
@Override
public boolean canPerformIndexedMatch(Atom atom, Substitution substitution) {
return this.factBase.canPerformIndexedMatch(atom, substitution);
}
@Override
public Iterator match(Atom a) {
return Streams.stream(this.factBase.match(a))
.filter(atom -> !removedAtoms.contains(atom))
.iterator();
}
@Override
public Iterator match(Atom a, Substitution s) {
return Streams.stream(this.factBase.match(a, s))
.filter(atom -> !removedAtoms.contains(atom))
.iterator();
}
@Override
public boolean add(Atom atom) {
return this.factBase.add(atom) || removedAtoms.remove(atom);
}
@Override
public boolean add(FOFormula atoms) {
return this.addAll(atoms.asAtomSet());
}
@Override
public boolean addAll(Collection atoms) {
return atoms.stream().map(this::add).reduce(false, Boolean::logicalOr);
}
@Override
public boolean addAll(Stream atoms) {
return atoms.map(this::add).reduce(false, Boolean::logicalOr);
}
@Override
public boolean remove(Atom atom) {
return factBase.contains(atom) && removedAtoms.add(atom);
}
@Override
public boolean remove(FOFormula atoms) {
return removedAtoms.addAll(atoms.asAtomSet());
}
@Override
public boolean removeAll(Collection atoms) {
return atoms.stream().map(this::remove).reduce(false, Boolean::logicalOr);
}
@Override
public boolean removeAll(Stream atoms) {
return atoms.map(this::remove).reduce(false, Boolean::logicalOr);
}
}