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

fr.lirmm.graphik.integraal.homomorphism.AtomicQueryHomomorphism Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (C) Inria Sophia Antipolis - Méditerranée / LIRMM
 * (Université de Montpellier & CNRS) (2014 - 2015)
 *
 * Contributors :
 *
 * Clément SIPIETER 
 * Mélanie KÖNIG
 * Swan ROCHER
 * Jean-François BAGET
 * Michel LECLÈRE
 * Marie-Laure MUGNIER 
 *
 *
 * This file is part of Graal .
 *
 * This software is governed by the CeCILL  license under French law and
 * abiding by the rules of distribution of free software.  You can  use,
 * modify and/ or redistribute the software under the terms of the CeCILL
 * license as circulated by CEA, CNRS and INRIA at the following URL
 * "http://www.cecill.info".
 *
 * As a counterpart to the access to the source code and  rights to copy,
 * modify and redistribute granted by the license, users are provided only
 * with a limited warranty  and the software's author,  the holder of the
 * economic rights,  and the successive licensors  have only  limited
 * liability.
 *
 * In this respect, the user's attention is drawn to the risks associated
 * with loading,  using,  modifying and/or developing or reproducing the
 * software by the user in light of its specific status of free software,
 * that may mean  that it is complicated to manipulate,  and  that  also
 * therefore means  that it is reserved for developers  and  experienced
 * professionals having in-depth computer knowledge. Users are therefore
 * encouraged to load and test the software's suitability as regards their
 * requirements in conditions enabling the security of their systems and/or
 * data to be ensured and,  more generally, to use and operate it in the
 * same conditions as regards security.
 *
 * The fact that you are presently reading this means that you have had
 * knowledge of the CeCILL license and that you accept its terms.
 */
package fr.lirmm.graphik.integraal.homomorphism;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

import org.apache.commons.lang3.tuple.Pair;

import fr.lirmm.graphik.integraal.api.core.Atom;
import fr.lirmm.graphik.integraal.api.core.AtomSet;
import fr.lirmm.graphik.integraal.api.core.AtomSetException;
import fr.lirmm.graphik.integraal.api.core.ConjunctiveQuery;
import fr.lirmm.graphik.integraal.api.core.RulesCompilation;
import fr.lirmm.graphik.integraal.api.core.Substitution;
import fr.lirmm.graphik.integraal.api.core.Term;
import fr.lirmm.graphik.integraal.api.core.Variable;
import fr.lirmm.graphik.integraal.api.homomorphism.HomomorphismException;
import fr.lirmm.graphik.integraal.core.factory.DefaultSubstitutionFactory;
import fr.lirmm.graphik.util.stream.CloseableIterator;
import fr.lirmm.graphik.util.stream.CloseableIteratorAdapter;
import fr.lirmm.graphik.util.stream.CloseableIteratorAggregator;
import fr.lirmm.graphik.util.stream.Iterators;
import fr.lirmm.graphik.util.stream.converter.ConverterCloseableIterator;

/**
 * Query evaluation for Atomic Conjunctive Queries without multiple occurrences of variables.
 * 
 * @author Clément Sipieter (INRIA) {@literal }
 *
 */
public class AtomicQueryHomomorphism extends AbstractHomomorphismWithCompilation {

	private static final AtomicQueryHomomorphism INSTANCE = new AtomicQueryHomomorphism();

	// /////////////////////////////////////////////////////////////////////////
	// SINGLETON
	// /////////////////////////////////////////////////////////////////////////

	public static AtomicQueryHomomorphism instance() {
		return INSTANCE;
	}

	private AtomicQueryHomomorphism() {}
	
	// /////////////////////////////////////////////////////////////////////////
	// HOMOMORPHISM METHODS
	// /////////////////////////////////////////////////////////////////////////

	/**
	 * The method enumerates all homomorphisms from a conjunctive query made of
	 * a single atom, that respect a given substitution. If no homomorphism is
	 * found then an empty iterator is returned.
	 * 
	 */
	@Override
	public CloseableIterator execute(ConjunctiveQuery q, AtomSet a, Substitution s)
			throws HomomorphismException {
		Atom atom = q.getAtomSet().iterator().next();
		try {

			// apply the substitution to the atom
			Atom queryAtom = s.createImageOf(atom);
			if (queryAtom.getVariables().isEmpty()) {
				
				if (a.contains(queryAtom)) {
					Substitution newSub = DefaultSubstitutionFactory.instance().createSubstitution();
					for (Term t : q.getAnswerVariables()) {
						if (t.isVariable()) {
							newSub.put((Variable) t, s.createImageOf(t));
						}
					}
					return new CloseableIteratorAdapter<>(Collections.singleton(newSub).iterator());
				} else {
					return Iterators.emptyIterator();
				}
			} else {
				return new ConverterCloseableIterator(a.match(atom, s),
						new Atom2SubstitutionConverter(atom, q.getAnswerVariables()));
			}
		} catch (AtomSetException e) {
			throw new HomomorphismException(e);
		}
	}

	/**
	 * The method enumerates all homomorphisms from a conjunctive query made of
	 * a single atom, respecting a given substitution, and also taking into
	 * account a compilation. If no homomorphism is found then an empty iterator
	 * is returned.
	 */
	@Override
	public CloseableIterator execute(ConjunctiveQuery q, AtomSet a, RulesCompilation rc, Substitution s)
			throws HomomorphismException {

		// if more than one atoms, only the first is considered

		Atom atom = q.getAtomSet().iterator().next();

		try {

			// apply the substitution to the atom
			Atom queryAtom = s.createImageOf(atom);

			if (queryAtom.getVariables().isEmpty()) {

				// the atom now has only constants (fully instantiated)

				boolean contains = false;

				// first rewrite it in all possible ways to account the compilation

				for (Pair im : rc.getRewritingOf(queryAtom)) {

					// now just check if a rewriting is contained in the atomset

					if (a.contains(im.getLeft())) {
						contains = true;
						break;
					}
				}
				if (contains) {

					// create the resulting substitution from the input one
					// hypothesis : no multiple occurrences of variables

					Substitution newSub = DefaultSubstitutionFactory.instance().createSubstitution();
					for (Term t : q.getAnswerVariables()) {
						if (t.isVariable()) {
							newSub.put((Variable) t, s.createImageOf(t));
						}
					}
					return new CloseableIteratorAdapter<>(Collections.singleton(newSub).iterator());
				} else {
					// no atom found
					return Iterators.emptyIterator();
				}
			} else {

				// the atom has at least one variable
				// so we have to enumerate all homomorphisms

				List> iteratorsList = new LinkedList>();

				// rewrite as before to account for the compilation
				for (Pair im : rc.getRewritingOf(atom)) {
					iteratorsList.add(new ConverterCloseableIterator(a.match(im.getLeft(), s),
							new Atom2SubstitutionConverter(im.getLeft(), q.getAnswerVariables(), im.getRight())));
				}

				// return the substitution
				// hypothesis : no multiple occurrences of variables
				return new CloseableIteratorAggregator((CloseableIterator>)
						new CloseableIteratorAdapter>(iteratorsList.iterator()));
			}
		} catch (AtomSetException e) {
			throw new HomomorphismException(e);
		}
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy