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

swiprolog.errors.PrologError Maven / Gradle / Ivy

Go to download

An implementation of the KR Interface defined in the KR Tools project for SWI Prolog.

There is a newer version: 1.4.0
Show newest version
package swiprolog.errors;

import krTools.KRInterface;
import krTools.exceptions.KRException;
import krTools.exceptions.KRQueryFailedException;
import swiprolog.language.JPLUtils;

/**
 * A wrapper for {@link org.jpl7.PrologException}s.
 *
 * reasons for having this:
 * 
    *
  • a {@link KRInterface} can only throw {@link KRException}s *
  • We need to do pretty printing, {@link org.jpl7.PrologException} toString * is unreadable for most humans *
* *

* The error contents were determined with reverse engineering. We most likely * have not covered all possible cases. We try to give more general errors in * unknown cases. But including the original {@link org.jpl7.PrologException} * still is necessary. * */ public class PrologError extends KRQueryFailedException { /** * */ private static final long serialVersionUID = 1L; /** * Known {@link org.jpl7.PrologException}s */ enum ErrorType { /** * type_error(+Type, +Term) Tell the user that Term is not of the * expected Type */ TYPE_ERROR(2), /** * domain_error(+Type, +Term). The argument is of the proper type, but * has a value that is outside the supported values */ DOMAIN_ERROR(2), /** * existence_error(+Type, +Term). Term is of the correct type and * correct domain, but there is no existing (external) resource that is * represented by it. */ EXISTENCE_ERROR(2), /** * permission_error(+Action, +Type, +Term): It is not allowed to perform * Action on the object Term that is of the given Type. */ PERMISSION_ERROR(3), /** * instantiation_error(+Term). An argument is under-instantiated. I.e. * it is not acceptable as it is, but if some variables are bound to * appropriate values it would be acceptable. */ INSTANTIATION_ERROR(1), /** * uninstantiation_error(+Term): An argument is over-instantiated. */ UNINSTANTIATION_ERROR(1), /** * representation_error(+Reason). A representation error indicates a * limitation of the implementation. */ REPRESENTATION_ERROR(1), /** * syntax_error(+Culprit): A text has invalid syntax. */ SYNTAX_ERROR(1), /** * evaliation_error(Cause): some math evaluation failed. Not documented * by SWI so reverse engineered. */ EVALUATION_ERROR(1); private int arity; ErrorType(int arity) { this.arity = arity; } public int getArity() { return this.arity; } }; /** * Subtype, often passed as first argument of the error. This indicates to * which type of object the error is referring. This also influences the * format and type of the other arguments of the error. * */ enum ErrorSubType { /** * predicate/procedure type. */ PROCEDURE, /** * files type */ SOURCE_SINK }; /** * Creates prolog error from given error term. * * @param err * must be a {@link org.jpl7.PrologException} (not null) * containing a compound term which in turn containing the error * details term. The name of error details should be one of the * known {@link ErrorType}s. Unknown error types can not be * handled properly */ public PrologError(org.jpl7.PrologException exc) { // we can't know message before processing exc.. as workaround we // override #getMessage() super("", exc); } @Override public String getMessage() { String mess = "swi prolog says the query failed"; String detail = extractDetailMessage(); if (detail != null) { mess = mess + " because " + detail; } return mess; } /** * Try to extract a detailed message * * @return message, or null if we fail to create such a message. */ private String extractDetailMessage() { org.jpl7.PrologException cause = (org.jpl7.PrologException) getCause(); org.jpl7.Term term = cause.term(); // we are expecting error(specific error, context), so something // like this: // error(existence_error(procedure, // :('towerbuilder:main:on(a,b) , on(b,c) , on(c,table) , on(d,e) , // on(e,f) , on(f,table) , maintain', /(target, 2))), // context(:(system, /(',', 2)), _36)) // we will try to translate the contained specific error. if (term.name().equals("error") && term.arity() != 0) { return makeDetailMessage(term.arg(1)); } else { return null; } } /** * @param error * a Compound term like existence_error(..,..). * @return human readable error message, or null if unknown term. */ private String makeDetailMessage(org.jpl7.Term error) { ErrorType type; try { type = ErrorType.valueOf(error.name().toUpperCase()); } catch (IllegalArgumentException e) { return null; } String defaultmessage = "because of a general " + type.toString().toLowerCase(); if (error.arity() != type.getArity()) { // sometimes SWI gives wrong error objects to us with no details. // Still trying to be helpful somehow... return defaultmessage; } switch (type) { case EXISTENCE_ERROR: ErrorSubType subtype; try { subtype = ErrorSubType.valueOf(error.arg(1).name().toUpperCase()); } catch (IllegalArgumentException e) { return defaultmessage; } switch (subtype) { case PROCEDURE: org.jpl7.Term t = error.arg(2); if (t.arity() != 2) { return defaultmessage; } return "the term " + JPLUtils.toString(t.arg(2)) + " is undefined"; case SOURCE_SINK: return "the file " + JPLUtils.toString(error.arg(2)) + " is unaccesable"; default: return defaultmessage; } case INSTANTIATION_ERROR: return "the term " + JPLUtils.toString(error.arg(1)) + " is under-instantiated"; case DOMAIN_ERROR: return "The term " + JPLUtils.toString(error.arg(2)) + " has a value that is outside the supported values"; case UNINSTANTIATION_ERROR: return "the term " + JPLUtils.toString(error.arg(1)) + " is over-instantiated"; case PERMISSION_ERROR: return "it is not allowed to perform " + JPLUtils.toString(error.arg(1)) + " on the object " + JPLUtils.toString(error.arg(2)) + " that is of type " + error.arg(3); case TYPE_ERROR: return "the term " + JPLUtils.toString(error.arg(2)) + " is not of the expected " + error.arg(1) + " type"; case REPRESENTATION_ERROR: return "implementation limits exceeded:" + error.arg(1); case SYNTAX_ERROR: return "text has invalid syntax:" + error.arg(1); case EVALUATION_ERROR: return "computation failed:" + error.arg(1); default: return defaultmessage; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy