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

org.semanticweb.vlog4j.examples.ExamplesUtils Maven / Gradle / Ivy

package org.semanticweb.vlog4j.examples;

/*-
 * #%L
 * VLog4j Examples
 * %%
 * Copyright (C) 2018 - 2019 VLog4j Developers
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
import org.semanticweb.vlog4j.core.exceptions.ReasonerStateException;
import org.semanticweb.vlog4j.core.model.api.PositiveLiteral;
import org.semanticweb.vlog4j.core.model.api.Term;
import org.semanticweb.vlog4j.core.model.implementation.Expressions;
import org.semanticweb.vlog4j.core.reasoner.Correctness;
import org.semanticweb.vlog4j.core.reasoner.QueryResultIterator;
import org.semanticweb.vlog4j.core.reasoner.Reasoner;
import org.semanticweb.vlog4j.parser.ParsingException;
import org.semanticweb.vlog4j.parser.RuleParser;

public final class ExamplesUtils {

	public static final String OUTPUT_FOLDER = "src/main/data/output/";
	public static final String INPUT_FOLDER = "src/main/data/input/";

	/*
	 * This is a utility class. Therefore, it is best practice to do the following:
	 * (1) Make the class final, (2) make its constructor private, (3) make all its
	 * fields and methods static. This prevents the classes instantiation and
	 * inheritance.
	 */
	private ExamplesUtils() {

	}

	/**
	 * Defines how messages should be logged. This method can be modified to
	 * restrict the logging messages that are shown on the console or to change
	 * their formatting. See the documentation of Log4J for details on how to do
	 * this.
	 * 
	 * Note: The VLog C++ backend performs its own logging. The log-level for this
	 * can be configured using
	 * {@link Reasoner#setLogLevel(org.semanticweb.vlog4j.core.reasoner.LogLevel)}.
	 * It is also possible to specify a separate log file for this part of the logs.
	 */
	public static void configureLogging() {
		// Create the appender that will write log messages to the console.
		final ConsoleAppender consoleAppender = new ConsoleAppender();
		// Define the pattern of log messages.
		// Insert the string "%c{1}:%L" to also show class name and line.
		final String pattern = "%d{yyyy-MM-dd HH:mm:ss} %-5p - %m%n";
		consoleAppender.setLayout(new PatternLayout(pattern));
		// Change to Level.ERROR for fewer messages:
		consoleAppender.setThreshold(Level.INFO);

		consoleAppender.activateOptions();
		Logger.getRootLogger().addAppender(consoleAppender);
	}

	/**
	 * Prints out the answers given by {@code reasoner} to the query
	 * ({@code queryAtom}).
	 *
	 * @param queryAtom query to be answered
	 * @param reasoner  reasoner to query on
	 */
	public static void printOutQueryAnswers(final PositiveLiteral queryAtom, final Reasoner reasoner) {
		System.out.println("Answers to query " + queryAtom + " :");
		try (final QueryResultIterator answers = reasoner.answerQuery(queryAtom, true)) {
			answers.forEachRemaining(answer -> System.out.println(" - " + answer));

			System.out.println("Query answers are: " + answers.getCorrectness());
		}
		System.out.println();
	}

	/**
	 * Prints out the answers given by {@code reasoner} to the query
	 * ({@code queryAtom}).
	 *
	 * @param queryAtom query to be answered
	 * @param reasoner  reasoner to query on
	 */
	public static void printOutQueryAnswers(final String queryString, final Reasoner reasoner) {
		try {
			final PositiveLiteral query = RuleParser.parsePositiveLiteral(queryString);
			printOutQueryAnswers(query, reasoner);
		} catch (final ParsingException e) {
			throw new RuntimeException(e.getMessage(), e);
		}
	}

	/**
	 * Returns the number of answers returned by {@code reasoner} to the query
	 * ({@code queryAtom}).
	 *
	 * @param queryAtom query to be answered
	 * @param reasoner  reasoner to query on
	 */
	public static int getQueryAnswerCount(final PositiveLiteral queryAtom, final Reasoner reasoner) {
		try (final QueryResultIterator answers = reasoner.answerQuery(queryAtom, true)) {
			return iteratorSize(answers);
		}
	}

	/**
	 * Returns the number of answers returned by {@code reasoner} to the query
	 * ({@code queryAtom}).
	 *
	 * @param queryAtom query to be answered
	 * @param reasoner  reasoner to query on
	 */
	public static int getQueryAnswerCount(final String queryString, final Reasoner reasoner) {
		try {
			final PositiveLiteral query = RuleParser.parsePositiveLiteral(queryString);
			return getQueryAnswerCount(query, reasoner);
		} catch (final ParsingException e) {
			throw new RuntimeException(e.getMessage(), e);
		}
	}

	/**
	 * Returns the size of an iterator.
	 *
	 * @FIXME This is an inefficient way of counting results. It should be done at a
	 *        lower level instead
	 * @param Iterator to iterate over
	 * @return number of elements in iterator
	 */
	private static  int iteratorSize(final Iterator iterator) {
		int size = 0;
		for (; iterator.hasNext(); ++size) {
			iterator.next();
		}
		return size;
	}

	/**
	 * Creates an Atom with @numberOfVariables distinct variables
	 *
	 * @param predicateName for the new predicate
	 * @param arity         number of variables
	 */
	private static PositiveLiteral makeQueryAtom(final String predicateName, final int arity) {
		final List vars = new ArrayList<>();
		for (int i = 0; i < arity; i++) {
			vars.add(Expressions.makeUniversalVariable("x" + i));
		}
		return Expressions.makePositiveLiteral(predicateName, vars);
	}

	/**
	 * Exports the extension of the Atom with name @predicateName
	 *
	 * @param reasoner reasoner to query on
	 * @param atomName atom's name
	 * @param arity    atom's arity
	 */
	public static void exportQueryAnswersToCSV(final Reasoner reasoner, final String atomName, final int arity)
			throws ReasonerStateException, IOException {
		final PositiveLiteral atom = makeQueryAtom(atomName, arity);
		final String path = ExamplesUtils.OUTPUT_FOLDER + atomName + ".csv";

		final Correctness correctness = reasoner.exportQueryAnswersToCsv(atom, path, true);

		System.out.println("Query answers are: " + correctness);
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy