/** * SPINdle (version 2.2.2) * Copyright (C) 2009-2012 NICTA Ltd. * * This file is part of SPINdle project. * * SPINdle is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * SPINdle is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with SPINdle. If not, see <http://www.gnu.org/licenses/>. * * @author H.-P. Lam (oleklam@gmail.com), National ICT Australia - Queensland Research Laboratory */ package spindle.io.parser; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.LineNumberReader; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.TreeMap; import com.app.utils.NameValuePair; //import com.app.utils.Entry; import spindle.core.dom.Conclusion; import spindle.core.dom.ConclusionType; import spindle.core.dom.DomUtilities; import spindle.core.dom.Literal; import spindle.core.dom.LiteralVariable; import spindle.core.dom.Mode; import spindle.core.dom.Rule; import spindle.core.dom.RuleException; import spindle.core.dom.RuleType; import spindle.core.dom.Superiority; import spindle.core.dom.Theory; import spindle.core.dom.TheoryException; import spindle.io.ComponentMismatchException; import spindle.io.ParserException; import spindle.io.outputter.DflTheoryConst; import spindle.io.outputter.DflTheoryOutputter; import spindle.sys.AppLogger; import spindle.sys.message.ErrorMessage; /** * Defeasible theory and conclusions parser for theory represented using DFL language. * * @author H.-P. Lam (oleklam@gmail.com), National ICT Australia - Queensland Research Laboratory * @version Last modified 2012.09.24 * @version 2011.07.27 * @since version 1.0.0 * @deprecated As of version 2.1.0, the DFL theory parser class {@link spindle.io.parser.DflTheoryParser} is replaced by {@link spindle.io.parser.DflTheoryParser2}. * @see spindle.io.parser.DflTheoryParser2 */ @Deprecated public class DflTheoryParser extends AbstractTheoryParser { public static final String PARSER_TYPE = DflTheoryOutputter.OUTPUTTER_TYPE; private static DflTheoryParser INSTANCE = null; private static int THEORY_VARIABLE_SYMBOL_LENGTH = RuleType.LITERAL_VARIABLE_SET.getSymbol().length(); public static Theory getTheory(String theoryString, AppLogger logger) throws ParserException { if (null == INSTANCE) INSTANCE = new DflTheoryParser(); try { InputStream ins = new ByteArrayInputStream(theoryString.replaceAll("[\t\r]", "").getBytes()); if (null != logger) INSTANCE.setAppLogger(logger); return INSTANCE.getTheory(ins); } catch (ParserException e) { throw e; } catch (Exception e) { throw new ParserException(e); } finally { INSTANCE.resetAppLogger(); } } public static Map<Literal, Map<ConclusionType, Conclusion>> getConclusions(String xmlString, AppLogger logger) throws ParserException { if (null == INSTANCE) INSTANCE = new DflTheoryParser(); try { InputStream ins = new ByteArrayInputStream(xmlString.replaceAll("[\t\r]", "").getBytes()); if (null != logger) INSTANCE.setAppLogger(logger); return INSTANCE.getConclusions(ins); } catch (ParserException e) { throw e; } catch (Exception e) { throw new ParserException(e); } finally { INSTANCE.resetAppLogger(); } } public static RuleType getRuleType(final String theoryString) throws ParserException { if (null == INSTANCE) INSTANCE = new DflTheoryParser(); return RuleType.getRuleType(theoryString); } public static Rule extractRuleStr(final String theoryString) throws ParserException { if (null == INSTANCE) INSTANCE = new DflTheoryParser(); try { Theory theory = getTheory(theoryString, null); if (theory.getFactsAndAllRules().size() > 0) { return theory.getFactsAndAllRules().values().iterator().next(); } else { return null; } } catch (ParserException e) { throw e; } catch (Exception e) { throw new ParserException(e); } } public static Superiority extractSuperiorityStr(final String theoryString) throws ParserException { if (null == INSTANCE) INSTANCE = new DflTheoryParser(); return INSTANCE.extractSuperiority(theoryString); } public static LiteralVariable extractLiteralVariableStr(final String literalVariableString) throws ParserException, ComponentMismatchException { if (null == INSTANCE) INSTANCE = new DflTheoryParser(); try { String valueStr = INSTANCE.getTheoryParserUtilities().formatLiteralVariableString(literalVariableString); Literal l = INSTANCE.extractLiteral(valueStr, true); if (l instanceof LiteralVariable) return (LiteralVariable) l; System.err.println("literalVariableString=" + literalVariableString + ", l=" + l); throw new ParserException(ErrorMessage.LITERAL_VARIABLE_INPUT_STRING_ERROR, new Object[] { literalVariableString }); } catch (ParserException e) { throw e; } catch (Exception e) { throw new ParserException(e); } } private static TheoryParserUtilities parserUtilities = null; protected TheoryParserUtilities getTheoryParserUtilities() { if (null == parserUtilities) parserUtilities = TheoryParserUtilities.getInstance(); return parserUtilities; } private LineNumberReader reader = null; private Map<Literal, Map<ConclusionType, Conclusion>> conclusions = null; private int ruleCounter = 0; public DflTheoryParser() { super(PARSER_TYPE); } @Override protected void generateTheory(InputStream ins) throws ParserException { reader = new LineNumberReader(new InputStreamReader(new BufferedInputStream(ins))); String str = null; try { while ((str = getNextLine()) != null) { int l = str.indexOf(DflTheoryConst.COMMENT_SYMBOL); if (l >= 0) str = str.substring(0, l); str = str.replace("\r", "").trim(); if (!"".equals(str)) extractTheoryString(str); } } catch (ParserException e) { throw e; } catch (Exception e) { int lineNo = reader.getLineNumber(); throw new ParserException("exception throw in line " + lineNo + ", " + str, e); } finally { try { reader.close(); } catch (IOException e1) { } reader = null; } } private String getNextLine() throws IOException { return reader.readLine(); } private void extractTheoryString(final String str) throws ParserException { try { RuleType ruleType = RuleType.getRuleType(str); switch (ruleType) { case LITERAL_VARIABLE_SET: extractLiteralVariable(str); break; case FACT: case STRICT: case DEFEASIBLE: case DEFEATER: String ruleLabel = ""; String ruleMode = ""; boolean ruleModeNegation = false; String ruleStr = str.replaceAll("\\r", ""); int loc = ruleStr.indexOf(DflTheoryConst.RULE_LABEL_SEPARATOR); if (loc >= 0) { ruleLabel = ruleStr.substring(0, loc).trim(); ruleStr = ruleStr.substring(loc + 1); } int ms, me; if ((ms = ruleLabel.indexOf(DflTheoryConst.MODE_START)) >= 0) { me = ruleLabel.indexOf(DflTheoryConst.MODE_END); if (me < 0) throw new ParserException("rule mode end not found"); ruleMode = ruleLabel.substring(ms + 1, me).trim(); ruleLabel = ruleLabel.substring(0, ms); if (ruleMode.startsWith(DflTheoryConst.SYMBOL_NEGATION)) { ruleMode = ruleMode.substring(1); ruleModeNegation = true; } } if ("".equals(ruleLabel)) ruleLabel = TEMP_RULE_LABEL + Theory.formatter.format(ruleCounter++); Rule rule = extractRule(ruleType, ruleLabel, ("".equals(ruleMode) ? null : new Mode(ruleMode, ruleModeNegation)), ruleStr); if (ruleLabel.startsWith(TEMP_RULE_LABEL)) addPendingRule(rule); else addRule(rule); break; case SUPERIORITY: case INFERIORITY: Superiority superiority = extractSuperiority(str); addSuperiority(superiority); break; case MODE_CONVERSION: case MODE_CONFLICT: extractModeConversionAndModeRuleConflict(str); break; default: } } catch (ParserException e) { throw e; } catch (Exception e) { throw new ParserException("exception throw while processing [" + str + "]", e); } } private void extractLiteralVariable(String str) throws ParserException { String code = str.substring(THEORY_VARIABLE_SYMBOL_LENGTH).replaceAll("\\s", ""); int l = code.indexOf(DflTheoryConst.THEORY_EQUAL_SIGN); if (l < 0) throw new ParserException(ErrorMessage.LITERAL_VARIABLE_DEFINITION_NOT_FOUND); try { String nameStr = code.substring(0, l).trim(); String valueStr = code.substring(l + 1); if (nameStr.length() == 0 || valueStr.length() == 0) throw new ParserException(ErrorMessage.LITERAL_VARIABLE_DEFINITION_NOT_FOUND, null, code); LiteralVariable lvName = (LiteralVariable) extractLiteral(nameStr, true); if (getAppConstants().isAppConstant(lvName)) throw new ParserException(ErrorMessage.LITERAL_VARIABLE_APP_CONSTANT_AS_NAME, new Object[] { str }); valueStr = getTheoryParserUtilities().formatLiteralVariableString(valueStr); LiteralVariable lvValue = (LiteralVariable) extractLiteral(valueStr, true); addLiteralVariable(lvName, lvValue); } catch (ParserException e) { throw e; } catch (Exception e) { throw new ParserException(e); } } private Rule extractRule(RuleType ruleType, String ruleLabel, Mode ruleMode, String str) throws ParserException, RuleException { int loc = str.indexOf(ruleType.getSymbol()); String bodyStr = str.substring(0, loc); String headStr = str.substring(loc + ruleType.getSymbol().length()); Rule rule = DomUtilities.getRule(ruleLabel, ruleType); if (null != ruleMode) rule.setMode(ruleMode); if (!"".equals(bodyStr.trim())) { for (Literal literal : extractLiteralList(bodyStr)) { rule.addBodyLiteral(literal); } } if (!"".equals(headStr.trim())) { for (Literal literal : extractLiteralList(headStr)) { rule.addHeadLiteral(literal); } } return rule; } private List<Literal> extractLiteralList(String str) throws ParserException { List<Literal> literals = new ArrayList<Literal>(); try { List<String> literalsString = getTheoryParserUtilities().parseLiteralString(str); for (String literalStr : literalsString) { literals.add(extractLiteral(literalStr, false)); } } catch (Exception e) { System.err.println("str=" + str); throw new ParserException(e); } return literals; } private Literal extractLiteral(final String str, boolean isVerifyString) throws ParserException, ComponentMismatchException { boolean containsAbstractLiteralInPredicate = getAppConstants().containsAbstractLiteralInPredicate(str); String literalName = ""; boolean isNegation = false; String modeName = ""; boolean isModeNegation = false; String predicates = ""; // TimeStamp timeStamp = null; String literalStr = null; if (isVerifyString) { List<String> literalList = getTheoryParserUtilities().parseLiteralString(str); if (literalList.size() == 0) throw new ParserException(ErrorMessage.LITERAL_STRING_INCORRECT_FORMAT); if (literalList.size() > 1) throw new ParserException(ErrorMessage.LITERAL_STRING_CONTAINS_MULTIPLE_LITERALS); literalStr = literalList.get(0); } else literalStr = str.trim(); NameValuePair<String, String> theoryBooleanFunctionEntry = extractLiteralStringComponent(literalStr, DflTheoryConst.LITERAL_BOOLEAN_FUNCTION_PREFIX, DflTheoryConst.LITERAL_BOOLEAN_FUNCTION_POSTFIX, // true); boolean isBooleanFunction = "".equals(theoryBooleanFunctionEntry.getValue()); if (isBooleanFunction) { return DomUtilities.getLiteralVariable(literalStr, false); } literalStr = theoryBooleanFunctionEntry.getValue(); NameValuePair<String, String> modeEntry = extractLiteralStringComponent(literalStr, // DflTheoryConst.MODE_START, DflTheoryConst.MODE_END, true); modeName = modeEntry.getKey(); NameValuePair<String, String> predicateEntry = extractLiteralStringComponent(modeEntry.getValue(), // DflTheoryConst.PREDICATE_START, DflTheoryConst.PREDICATE_END, !containsAbstractLiteralInPredicate); predicates = predicateEntry.getKey(); NameValuePair<String, String> temporalEntry = extractLiteralStringComponent(predicateEntry.getValue(), // DflTheoryConst.TIMESTAMP_START, DflTheoryConst.TIMESTAMP_END, true); @SuppressWarnings("unused") String temporal = temporalEntry.getKey(); literalStr = temporalEntry.getValue(); if (literalStr.startsWith(DflTheoryConst.SYMBOL_NEGATION)) { literalStr = literalStr.substring(DflTheoryConst.SYMBOL_NEGATION.length()).trim(); isNegation = true; } literalName = literalStr.trim(); Literal literal = DomUtilities.getLiteral(literalName, isNegation, // modeName, isModeNegation); if (containsAbstractLiteralInPredicate) { literal.setPredicates(null); LiteralVariable lv = (LiteralVariable) DomUtilities.getLiteralVariable(literal); if (!"".equals(predicates)) { List<Literal> li = extractLiteralList(predicates); Literal[] literalPredicates = new Literal[li.size()]; li.toArray(literalPredicates); lv.setLiteralPredicates(literalPredicates); } literal = lv; } else { literal.setPredicates(predicates.split("" + DflTheoryConst.LITERAL_SEPARATOR)); if (literalName.startsWith("" + DflTheoryConst.LITERAL_VARIABLE_PREFIX)) { literal = DomUtilities.getLiteralVariable(literal); } } return literal; } private NameValuePair<String, String> extractLiteralStringComponent(final String literalStr, final char prefix, final char postfix, boolean verifyContent) throws ParserException { if (null == literalStr || "".equals(literalStr.trim())) return new NameValuePair<String, String>("", ""); int locStart = literalStr.indexOf(prefix); int locEnd = literalStr.lastIndexOf(postfix); if (locStart < 0 && locEnd < 0) return new NameValuePair<String, String>("", literalStr); if (locStart < 0 || locEnd < 0) throw new ParserException(ErrorMessage.LITERAL_STRING_INCORRECT_FORMAT, literalStr); String residual = literalStr.substring(0, locStart) + literalStr.substring(locEnd + 1); String content = literalStr.substring(locStart + 1, locEnd); if (verifyContent && (content.indexOf(prefix) >= 0 || residual.indexOf(postfix) >= 0)) throw new ParserException( ErrorMessage.LITERAL_STRING_INCORRECT_FORMAT, new Object[] { literalStr }); NameValuePair<String, String> entry = new NameValuePair<String, String>(content, residual); return entry; } private Superiority extractSuperiority(String str) throws ParserException { try { int l = str.indexOf(RuleType.SUPERIORITY.getSymbol()); String superior = ""; String inferior = ""; if (l > 0) { superior = str.substring(0, l).trim(); inferior = str.substring(l + RuleType.SUPERIORITY.getSymbol().length()).trim(); } else { l = str.indexOf(RuleType.INFERIORITY.getSymbol()); inferior = str.substring(0, l).trim(); superior = str.substring(l + RuleType.SUPERIORITY.getSymbol().length()).trim(); } if ("".equals(superior)) throw new ParserException(ErrorMessage.SUPERIORITY_SUPERIOR_RULE_NOT_DEFINED, str); if ("".equals(inferior)) throw new ParserException(ErrorMessage.SUPERIORITY_INFERIOR_RULE_NOT_DEFINED, str); return new Superiority(superior, inferior); } catch (Exception e) { throw new ParserException(e); } } private void extractModeConversionAndModeRuleConflict(String str) throws ParserException, TheoryException { int l = -1; if ((l = str.indexOf(DflTheoryConst.SYMBOL_MODE_CONVERSION)) > 0) { String o = str.substring(0, l).trim(); String[] c = str.substring(l + DflTheoryConst.SYMBOL_MODE_CONVERSION.length()).split("" + DflTheoryConst.LITERAL_SEPARATOR); addModeConversionRule(o, c); } else if ((l = str.indexOf(DflTheoryConst.SYMBOL_MODE_CONFLICT)) > 0) { String o = str.substring(0, l).trim(); String[] c = str.substring(l + DflTheoryConst.SYMBOL_MODE_CONVERSION.length()).split("" + DflTheoryConst.LITERAL_SEPARATOR); addModeConflictRule(o, c); } else { throw new ParserException(ErrorMessage.RULE_UNRECOGNIZED_RULE_TYPE); } } // =========================================== // conclusions @Override protected Map<Literal, Map<ConclusionType, Conclusion>> generateConclusions(InputStream ins) throws ParserException { reader = new LineNumberReader(new InputStreamReader(new BufferedInputStream(ins))); String str = null; conclusions = new TreeMap<Literal, Map<ConclusionType, Conclusion>>(); try { while ((str = getNextLine()) != null) { int l = str.indexOf(DflTheoryConst.COMMENT_SYMBOL); if (l >= 0) str = str.substring(0, l); str = str.replace("\r", "").trim(); if (!"".equals(str)) extractConclusionString(str); } } catch (Exception e) { int lineNo = reader.getLineNumber(); conclusions = null; throw new ParserException(ErrorMessage.IO_FILE_READING_ERROR, new Object[] { lineNo }, str, e); } finally { try { reader.close(); } catch (IOException e1) { } reader = null; } return conclusions; } protected void extractConclusionString(String str) throws ParserException, ComponentMismatchException { ConclusionType conclusionType = ConclusionType.getConclusionType(str); String literalStr = str.substring(conclusionType.getSymbol().length()).trim(); Literal literal = extractLiteral(literalStr, true); Map<ConclusionType, Conclusion> conclusionList = null; if (conclusions.containsKey(literal)) { conclusionList = conclusions.get(literal); } else { conclusionList = new TreeMap<ConclusionType, Conclusion>(); conclusions.put(literal, conclusionList); } conclusionList.put(conclusionType, new Conclusion(conclusionType, literal)); } }