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

fr.boreal.backward_chaining.unfolding.UCQUnfolder Maven / Gradle / Ivy

package fr.boreal.backward_chaining.unfolding;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;

import fr.boreal.model.formula.api.FOFormula;
import org.apache.commons.lang3.tuple.Pair;

import com.google.common.collect.Sets;

import fr.boreal.backward_chaining.core.QueryCoreProcessorImpl;
import fr.boreal.backward_chaining.core.QueryCoreProcessor;
import fr.boreal.backward_chaining.cover.CoverFunction;
import fr.boreal.backward_chaining.cover.QueryCover;
import fr.boreal.model.formula.factory.FOFormulaFactory;
import fr.boreal.model.logicalElements.api.Atom;
import fr.boreal.model.logicalElements.api.Substitution;
import fr.boreal.model.logicalElements.impl.SubstitutionImpl;
import fr.boreal.model.query.api.FOQuery;
import fr.boreal.model.query.factory.FOQueryFactory;
import fr.boreal.model.ruleCompilation.api.RuleCompilation;

/**
 * @author Florent Tornil
 *
 * Unfold an pivotal-UCQ into a classical UCQ
 */
public class UCQUnfolder {

	private final RuleCompilation compilation;

	private final CoverFunction coverFct;
	private final QueryCoreProcessor core;

	/**
	 * Creates a new UCQUnfolder using the given parameters
	 * @param compilation the rule compilation to use
	 */
	public UCQUnfolder(RuleCompilation compilation) {
		this(new QueryCover(), new QueryCoreProcessorImpl(), compilation);
	}

	/**
	 * Creates a new UCQUnfolder using the given parameters
	 * @param coverFct the cover function to use
	 * @param core the core function to use
	 * @param compilation the rule compilation to use
	 */
	public UCQUnfolder(CoverFunction coverFct,  QueryCoreProcessor core, RuleCompilation compilation) {
		this.coverFct = coverFct;
		this.core = core;
		this.compilation = compilation;
	}

	/**
	 * Each query of the UCQ will be a core
	 * Computes a cover of the unfolding before returning it
	 * @param pivotalQueries a pivotal query
	 * @return the unfolding of the pivotal query by the compilation
	 */
	public Set> unfold(Collection> pivotalQueries) {
		Set> unfoldedUCQ = new HashSet<>();

		for(FOQuery pivotalQuery : pivotalQueries) {
			List>> atomicUnfoldings = new ArrayList<>();
			for(Atom a : pivotalQuery.getFormula().asAtomSet()) {
				atomicUnfoldings.add(compilation.unfold(a));
			}
			Set>> unfolding = Sets.cartesianProduct(atomicUnfoldings);

			for(List> atoms : unfolding) {
				Set queryAtoms = new HashSet<>();
				Substitution initialSubstitution = new SubstitutionImpl();
				boolean valid = true;
				for(Pair pair : atoms) {
					if(valid) {
						queryAtoms.add(pair.getKey());
						Optional initialSubstitutionOpt = initialSubstitution.merged(pair.getValue());
						if(initialSubstitutionOpt.isPresent()) {
							initialSubstitution = initialSubstitutionOpt.get();
						} else {
							valid = false;
						}
					}
				}
				if(valid) {
					FOQuery q = FOQueryFactory.instance().createOrGetQuery(
							FOFormulaFactory.instance().createOrGetConjunction(queryAtoms.toArray(new Atom[0])),
							pivotalQuery.getAnswerVariables());
					q = this.core.computeCore(q);
					unfoldedUCQ.add(q);
				}
			}
		}
		unfoldedUCQ = this.coverFct.cover(unfoldedUCQ);
		return unfoldedUCQ;

	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy