package org.ggp.base.util.gdl.scrambler; import org.ggp.base.util.gdl.grammar.Gdl; import org.ggp.base.util.gdl.grammar.GdlConstant; import org.ggp.base.util.gdl.grammar.GdlDistinct; import org.ggp.base.util.gdl.grammar.GdlFunction; import org.ggp.base.util.gdl.grammar.GdlLiteral; import org.ggp.base.util.gdl.grammar.GdlNot; import org.ggp.base.util.gdl.grammar.GdlOr; import org.ggp.base.util.gdl.grammar.GdlProposition; import org.ggp.base.util.gdl.grammar.GdlRelation; import org.ggp.base.util.gdl.grammar.GdlRule; import org.ggp.base.util.gdl.grammar.GdlSentence; import org.ggp.base.util.gdl.grammar.GdlTerm; import org.ggp.base.util.gdl.grammar.GdlVariable; /** * A renderer for Gdl objects. On its own, this class renders a Gdl object * in the way you'd expect. It can be subclassed to override particular parts * of the rendering scheme; for example, to render GdlConstants scrambled via * a mapping. * * TODO(schreib): Would it ever make sense for this to replace the regular * toString methods in the Gdl objects? * * TODO(schreib): What is the relationship between this and the GdlVisitor * framework that Alex put together? Can they be combined? * * @author Sam Schreiber */ public class GdlRenderer { public String renderGdl(Gdl gdl) { if (gdl instanceof GdlTerm) { return renderTerm((GdlTerm) gdl); } else if (gdl instanceof GdlLiteral) { return renderLiteral((GdlLiteral) gdl); } else if (gdl instanceof GdlRule) { return renderRule((GdlRule) gdl); } else { throw new RuntimeException("Unexpected Gdl type " + gdl.getClass()); } } protected String renderTerm(GdlTerm term) { if (term instanceof GdlConstant) { return renderConstant((GdlConstant) term); } else if (term instanceof GdlVariable) { return renderVariable((GdlVariable) term); } else if (term instanceof GdlFunction) { return renderFunction((GdlFunction) term); } else { throw new RuntimeException("Unexpected GdlTerm type " + term.getClass()); } } protected String renderSentence(GdlSentence sentence) { if (sentence instanceof GdlProposition) { return renderProposition((GdlProposition) sentence); } else if (sentence instanceof GdlRelation) { return renderRelation((GdlRelation) sentence); } else { throw new RuntimeException("Unexpected GdlSentence type " + sentence.getClass()); } } protected String renderLiteral(GdlLiteral literal) { if (literal instanceof GdlSentence) { return renderSentence((GdlSentence) literal); } else if (literal instanceof GdlNot) { return renderNot((GdlNot) literal); } else if (literal instanceof GdlOr) { return renderOr((GdlOr) literal); } else if (literal instanceof GdlDistinct) { return renderDistinct((GdlDistinct) literal); } else { throw new RuntimeException("Unexpected GdlLiteral type " + literal.getClass()); } } protected String renderConstant(GdlConstant constant) { return constant.toString(); } protected String renderVariable(GdlVariable variable) { return variable.toString(); } protected String renderFunction(GdlFunction function) { StringBuilder sb = new StringBuilder(); sb.append("( " + renderConstant(function.getName()) + " "); for (GdlTerm term : function.getBody()) { sb.append(renderTerm(term) + " "); } sb.append(")"); return sb.toString(); } protected String renderRelation(GdlRelation relation) { StringBuilder sb = new StringBuilder(); sb.append("( " + renderConstant(relation.getName()) + " "); for (GdlTerm term : relation.getBody()) { sb.append(renderTerm(term) + " "); } sb.append(")"); return sb.toString(); } protected String renderProposition(GdlProposition proposition) { return renderConstant(proposition.getName()); } protected String renderNot(GdlNot not) { return "( not " + renderLiteral(not.getBody()) + " )"; } protected String renderDistinct(GdlDistinct distinct) { return "( distinct " + renderTerm(distinct.getArg1()) + " " + renderTerm(distinct.getArg2()) + " )"; } protected String renderOr(GdlOr or) { StringBuilder sb = new StringBuilder(); sb.append("( or "); for (int i = 0; i < or.arity(); i++) { sb.append(renderLiteral(or.get(i)) + " "); } sb.append(")"); return sb.toString(); } protected String renderRule(GdlRule rule) { StringBuilder sb = new StringBuilder(); sb.append("( <= " + renderSentence(rule.getHead()) + " "); for (GdlLiteral literal : rule.getBody()) { sb.append(renderLiteral(literal) + " "); } sb.append(")"); return sb.toString(); } }