/** * This is the main method to be used to get Explanations from explainers by supplying a Query. It * should be extended by subclasses to support more types of question. * * @param query containing the question about a context regarding a certain time * @return the generated Explanation corresponding to the Query */ public Explanation getExplanation(Query query) { if (query == null) { return new Explanation(query, DNF.UNKNOWN); } String question = query.getQuestion(); String context = query.getContext(); // System.out.println("Explainer.getExplanation question = " + question); /* * Model-independent explanations */ if (question == null) { return new Explanation(query, DNF.UNKNOWN); } if (question.equals(Query.QUESTION_WHAT)) { // output value return new Explanation(query, new DNF(getWhatExplanation(context))); } else if (question.equals(Query.QUESTION_WHEN)) { return new Explanation(query, new DNF(getWhenExplanation())); } else if (question.equals(WhatIfQuery.QUESTION_WHAT_IF)) { return new Explanation( query, new DNF(getWhatIfExplanation(((WhatIfQuery) query).getInputs()))); } else if (question.equals( Query.QUESTION_INPUTS)) { // for convenience, return names and values of inputs return new Explanation(query, new DNF(getInputsExplanation())); } else if (question.equals(Query.QUESTION_OUTPUTS)) { return new Explanation(query, getOutputsExplanation()); } else if (question.equals(Query.QUESTION_CERTAINTY)) { return new Explanation(query, getCertaintyExplanation()); } /* * Descriptive explanations */ else if (question.equals(Query.QUESTION_DEFINITION)) { return new Explanation(query, new DNF(getDefinitionExplanation(context))); } else if (question.equals(Query.QUESTION_RATIONALE)) { return new Explanation(query, new DNF(descExplainer.getRationaleExplanation(context))); } else if (question.equals(Query.QUESTION_PRETTY_NAME)) { return new Explanation(query, new DNF(descExplainer.getPrettyNameExplanation(context))); } else if (question.equals(Query.QUESTION_UNIT)) { return new Explanation(query, new DNF(descExplainer.getUnitExplanation(context))); } /* * Model-dependent explanations */ if (question.equals(Query.QUESTION_WHY)) { return new Explanation(query, getWhyExplanation()); } else if (question.equals(AltQuery.QUESTION_WHY_NOT)) { String altOutcomeValue = ((AltQuery) query).getAltOutcomeValue(); return new Explanation(query, getWhyNotExplanation(altOutcomeValue)); } else if (question.equals(AltQuery.QUESTION_HOW_TO)) { String altOutcomeValue = ((AltQuery) query).getAltOutcomeValue(); return new Explanation(query, getHowToExplanation(altOutcomeValue)); } // else if (question.equals(Query.QUESTION_CONTROL)) { // // TODO maybe this should be implemented at the subclass level, which is application domain // dependent? // // or can just use the EnactorParameters framework // } /* * Explanation unknown */ return new Explanation(query, DNF.UNKNOWN); }
/** * Returns the descriptive definition of the context with name = attributeName. By default, this * uses a DescriptionExplainerDelegate, but may be overridden. * * @param attributeName of the context to get its definition * @return Parameter<String> where name is attributeName and value is the definition. */ public Parameter<String> getDefinitionExplanation(String attributeName) { return descExplainer.getDefinitionExplanation(attributeName); }