/** * 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.outputter; import java.io.IOException; import java.io.OutputStream; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.Vector; import spindle.core.dom.Conclusion; import spindle.core.dom.ConclusionType; import spindle.core.dom.DomConst; import spindle.core.dom.LiteralVariable; import spindle.core.dom.Mode; import spindle.core.dom.Rule; import spindle.core.dom.RuleType; import spindle.core.dom.Superiority; import spindle.core.dom.Theory; import spindle.io.OutputterException; /** * Defeasible theory and conclusions outputter in DFL language. * * @author H.-P. Lam (oleklam@gmail.com), National ICT Australia - Queensland Research Laboratory * @since version 1.0.0 * @version Last modified 2012.05.30 */ public class DflTheoryOutputter extends AbstractTheoryOutputter { public static final String OUTPUTTER_TYPE = "dfl"; private static StringBuilder THEORY_COMMENT = null; private static StringBuilder CONCLUSION_COMMENT = null; static { String NEW_LINE_AND_COMMENT = LINE_SEPARATOR + DflTheoryConst.COMMENT_SYMBOL; THEORY_COMMENT = new StringBuilder(); THEORY_COMMENT.append("########################################").append(LINE_SEPARATOR); THEORY_COMMENT.append("# symbols used").append(LINE_SEPARATOR); THEORY_COMMENT.append("# ------------").append(LINE_SEPARATOR); for (RuleType ruleType : RuleType.values()) { THEORY_COMMENT.append(DflTheoryConst.COMMENT_SYMBOL).append(" ")// .append("[").append(ruleType.getSymbol()).append("] ")// .append(ruleType.getLabel()).append(LINE_SEPARATOR); } THEORY_COMMENT.append("#") // .append(NEW_LINE_AND_COMMENT).append(" [").append(DflTheoryConst.SYMBOL_NEGATION).append("] negation") // .append(NEW_LINE_AND_COMMENT).append(NEW_LINE_AND_COMMENT).append(" [").append(DflTheoryConst.SYMBOL_MODE_CONVERSION) .append("] mode conversion") // .append(NEW_LINE_AND_COMMENT).append(" [").append(DflTheoryConst.SYMBOL_MODE_CONFLICT).append("] mode conflict")// .append(LINE_SEPARATOR); THEORY_COMMENT.append("########################################").append(LINE_SEPARATOR).append(LINE_SEPARATOR); CONCLUSION_COMMENT = new StringBuilder(); CONCLUSION_COMMENT.append("########################################").append(LINE_SEPARATOR); CONCLUSION_COMMENT.append("# symbols used").append(LINE_SEPARATOR); CONCLUSION_COMMENT.append("# ------------").append(LINE_SEPARATOR); for (ConclusionType conclusionType : ConclusionType.values()) { switch (conclusionType) { case DEFINITE_PROVABLE: case DEFINITE_NOT_PROVABLE: case DEFEASIBLY_PROVABLE: case DEFEASIBLY_NOT_PROVABLE: CONCLUSION_COMMENT.append(DflTheoryConst.COMMENT_SYMBOL).append(" ")// .append(conclusionType.getSymbol())// .append(" - ")// .append(conclusionType.getLabel()).append(LINE_SEPARATOR); break; default: } } CONCLUSION_COMMENT.append("########################################").append(LINE_SEPARATOR).append(LINE_SEPARATOR); } public DflTheoryOutputter() { super(OUTPUTTER_TYPE); } protected void printHeader() throws IOException { writer.write("# " + getHeaderComment() + LINE_SEPARATOR); writer.write("# " + getGenerationTimeString() + LINE_SEPARATOR); writer.write(LINE_SEPARATOR); } @Override protected void saveToStream(OutputStream os, Theory theory) throws OutputterException { try { if (null == writer) throw new IOException("writer is null"); printHeader(); writer.write(THEORY_COMMENT.toString()); saveLiteralVariables(theory.getLiteralVariables(), "Literal variables"); saveLiteralVariables(theory.getLiteralBooleanFunctions(), "Literal boolean functions"); saveConversionRules(theory.getAllModeConversionRules(), theory.getAllModeConflictRules(), theory.getAllModeExclusionRules()); saveFactsAndAllRules(theory.getFactsAndAllRules().values()); saveSuperiority(theory.getAllSuperiority()); } catch (Exception e) { throw new OutputterException(e); } } private void saveLiteralVariables(Map<LiteralVariable, LiteralVariable> literalVariables, String label) throws IOException { if (literalVariables.size() > 0) { if (null != label && !"".equals(label)) { writer.write(DflTheoryConst.COMMENT_SYMBOL + " " + label.trim()); writer.write(LINE_SEPARATOR); } for (Entry<LiteralVariable, LiteralVariable> entry : literalVariables.entrySet()) { writer.write(RuleType.LITERAL_VARIABLE_SET.getSymbol()); writer.write(" "); writer.write(entry.getKey().getName() + DflTheoryConst.THEORY_EQUAL_SIGN + entry.getValue().getName()); writer.write(LINE_SEPARATOR); } writer.write(LINE_SEPARATOR); } } private void saveConversionRules(Map<String, Set<String>> conversionRules, // Map<String, Set<String>> conflictRules, Map<String, Set<String>> exclusionRules) throws IOException { List<String> modeUsed = new Vector<String>(); modeUsed.addAll(conversionRules.keySet()); for (String m : conflictRules.keySet()) { if (!modeUsed.contains(m)) modeUsed.add(m); } for (String m : exclusionRules.keySet()) { if (!modeUsed.contains(m)) modeUsed.add(m); } for (String mode : modeUsed) { if (null != conversionRules.get(mode)) { writer.write(generateConversionRuleStr(mode, conversionRules.get(mode), DflTheoryConst.SYMBOL_MODE_CONVERSION)); writer.write(LINE_SEPARATOR); } if (null != conflictRules.get(mode)) { writer.write(generateConversionRuleStr(mode, conflictRules.get(mode), DflTheoryConst.SYMBOL_MODE_CONFLICT)); writer.write(LINE_SEPARATOR); } if (null != exclusionRules.get(mode)) { writer.write(generateConversionRuleStr(mode, exclusionRules.get(mode), DflTheoryConst.SYMBOL_MODE_EXCLUSION)); writer.write(LINE_SEPARATOR); } writer.write(LINE_SEPARATOR); } } private String generateConversionRuleStr(String mode, Set<String> modeList, String typeStr) { StringBuilder sb = new StringBuilder(); for (String m : modeList) { if (sb.length() > 0) sb.append(","); sb.append(m); } return mode + " " + typeStr + " " + sb.toString(); } private void saveFactsAndAllRules(Collection<Rule> rules) throws IOException { if (null == rules || rules.size() == 0) return; for (Rule rule : rules) { StringBuilder sb = new StringBuilder(); if (!rule.getLabel().startsWith(DEFAULT_RULE_LABEL_PREFIX)) sb.append(rule.getLabel()); if (!"".equals(rule.getMode().getName())) { Mode mode = rule.getMode(); sb.append(DflTheoryConst.MODE_START); sb.append(mode.toString()); sb.append(DflTheoryConst.MODE_END); } if (sb.length() > 0) { sb.append(" " + DflTheoryConst.RULE_LABEL_SEPARATOR + " "); writer.write(sb.toString()); } String ruleStr = rule.getRuleAsString(); writer.write(ruleStr.replaceAll("" + DomConst.Literal.LITERAL_NEGATION_SIGN, DflTheoryConst.SYMBOL_NEGATION)); writer.write(LINE_SEPARATOR); } writer.write(LINE_SEPARATOR); } private void saveSuperiority(List<Superiority> sup) throws IOException { if (null == sup || sup.size() == 0) return; for (Superiority s : sup) { writer.write(s.toString()); writer.write(LINE_SEPARATOR); } writer.write(LINE_SEPARATOR); } @Override protected void saveToStream(OutputStream os, List<Conclusion> conclusionsAsList) throws OutputterException { try { if (null == writer) throw new IOException("writer is null"); printHeader(); writer.write(CONCLUSION_COMMENT.toString()); for (Conclusion conclusion : conclusionsAsList) { String conclusionStr = conclusion.getLiteral().toString(); conclusionStr = conclusionStr.replaceAll("" + DomConst.Literal.LITERAL_NEGATION_SIGN, DflTheoryConst.SYMBOL_NEGATION); ConclusionType conclusionType = conclusion.getConclusionType(); writer.write(conclusionType.getSymbol() + " " + conclusionStr + LINE_SEPARATOR); } } catch (Exception e) { throw new OutputterException(e); } } }