void processGdl(Gdl gdl, GdlConstant parent) { if (gdl instanceof GdlRelation) { GdlRelation relation = (GdlRelation) gdl; String name = relation.getName().toString(); if (!name.equals("base")) { for (Gdl gdl2 : relation.getBody()) processGdl(gdl2, relation.getName()); } } else if (gdl instanceof GdlRule) { GdlRule rule = (GdlRule) gdl; for (Gdl gdl2 : rule.getBody()) processGdl(gdl2, null); } else if (gdl instanceof GdlConstant) { universe.add((GdlConstant) gdl); } else if (gdl instanceof GdlFunction) { GdlFunction func = (GdlFunction) gdl; for (Gdl gdl2 : func.getBody()) processGdl(gdl2, func.getName()); } else if (gdl instanceof GdlDistinct) { GdlDistinct distinct = (GdlDistinct) gdl; processGdl(distinct.getArg1(), null); processGdl(distinct.getArg2(), null); } else if (gdl instanceof GdlNot) { GdlNot not = (GdlNot) gdl; processGdl(not.getBody(), null); } else if (gdl instanceof GdlOr) { GdlOr or = (GdlOr) gdl; for (int i = 0; i < or.arity(); i++) processGdl(or.get(i), null); } else if (gdl instanceof GdlProposition) { // IGNORE } else if (gdl instanceof GdlVariable) { // IGNORE } }
private static GdlRule substituteRule(GdlRule rule, Substitution theta) { GdlSentence head = substitute(rule.getHead(), theta); List<GdlLiteral> body = new ArrayList<>(); for (GdlLiteral literal : rule.getBody()) { body.add(substituteLiteral(literal, theta)); } return GdlPool.getRule(head, body); }
void initializeDomains(Gdl gdl) { if (gdl instanceof GdlRelation) { GdlRelation relation = (GdlRelation) gdl; String name = relation.getName().toString(); if (!name.equals("base")) { GdlTerm term = relation.toTerm(); GdlTerm generified = findGenericForm(term); Assignment instantiation = getConstantList(term); if (!domains.containsKey(generified)) domains.put(generified, new Domain(generified, term)); Domain dom = domains.get(generified); dom.assignments.add(instantiation); } } else if (gdl instanceof GdlRule) { GdlRule rule = (GdlRule) gdl; GdlSentence head = rule.getHead(); if (head instanceof GdlRelation) { GdlRelation rel = (GdlRelation) head; GdlTerm term = rel.toTerm(); GdlTerm generified = findGenericForm(term); if (!domains.containsKey(generified)) domains.put(generified, new Domain(generified, term)); Domain dom = domains.get(generified); List<GdlTerm> productionTemplate = getConstantAndVariableList(term); List<List<GdlLiteral>> newRHSs = deOr(rule.getBody()); for (List<GdlLiteral> RHS : newRHSs) { RuleReference ruleRef = new RuleReference(GdlPool.getRule(head, RHS)); ruleRef.productionTemplate = productionTemplate; for (GdlLiteral lit : RHS) { if (lit instanceof GdlSentence) { GdlTerm t = ((GdlSentence) lit).toTerm(); Condition cond = new Condition(t); ruleRef.conditions.add(cond); } } dom.ruleRefs.add(ruleRef); } } else { List<List<GdlLiteral>> newRHSs = deOr(rule.getBody()); for (List<GdlLiteral> RHS : newRHSs) { RuleReference ruleRef = new RuleReference(GdlPool.getRule(head, RHS)); for (GdlLiteral lit : RHS) { if (lit instanceof GdlSentence) { GdlTerm t = ((GdlSentence) lit).toTerm(); Condition cond = new Condition(t); ruleRef.conditions.add(cond); } } extraRefs.add(ruleRef); } } } }
private Gdl getInstantiationAux(Gdl gdl, Map<GdlVariable, GdlConstant> varInstantiation) { if (gdl instanceof GdlRelation) { GdlRelation relation = (GdlRelation) gdl; List<GdlTerm> body = new ArrayList<>(); for (int i = 0; i < relation.arity(); i++) { body.add((GdlTerm) getInstantiationAux(relation.get(i), varInstantiation)); } return GdlPool.getRelation(relation.getName(), body); } else if (gdl instanceof GdlRule) { GdlRule rule = (GdlRule) gdl; GdlSentence head = (GdlSentence) getInstantiationAux(rule.getHead(), varInstantiation); List<GdlLiteral> body = new ArrayList<>(); for (int i = 0; i < rule.arity(); i++) { body.add((GdlLiteral) getInstantiationAux(rule.get(i), varInstantiation)); } return GdlPool.getRule(head, body); } else if (gdl instanceof GdlDistinct) { GdlDistinct distinct = (GdlDistinct) gdl; GdlTerm arg1 = (GdlTerm) getInstantiationAux(distinct.getArg1(), varInstantiation); GdlTerm arg2 = (GdlTerm) getInstantiationAux(distinct.getArg2(), varInstantiation); return GdlPool.getDistinct(arg1, arg2); } else if (gdl instanceof GdlNot) { GdlNot not = (GdlNot) gdl; GdlLiteral body = (GdlLiteral) getInstantiationAux(not.getBody(), varInstantiation); return GdlPool.getNot(body); } else if (gdl instanceof GdlOr) { GdlOr or = (GdlOr) gdl; List<GdlLiteral> body = new ArrayList<>(); for (int i = 0; i < or.arity(); i++) { body.add((GdlLiteral) getInstantiationAux(or.get(i), varInstantiation)); } return GdlPool.getOr(body); } else if (gdl instanceof GdlProposition) { return gdl; } else if (gdl instanceof GdlConstant) { return gdl; } else if (gdl instanceof GdlFunction) { GdlFunction func = (GdlFunction) gdl; List<GdlTerm> body = new ArrayList<>(); for (int i = 0; i < func.arity(); i++) { body.add((GdlTerm) getInstantiationAux(func.get(i), varInstantiation)); } return GdlPool.getFunction(func.getName(), body); } else if (gdl instanceof GdlVariable) { GdlVariable variable = (GdlVariable) gdl; return varInstantiation.get(variable); } else throw new RuntimeException( "Someone went and extended the GDL hierarchy without updating this code."); }
public static List<GdlSentence> getSentencesInRuleBody(GdlRule rule) { List<GdlSentence> result = new ArrayList<>(); for (GdlLiteral literal : rule.getBody()) { addSentencesInLiteral(literal, result); } return result; }
private void findAndInstantiateBaseProps(Gdl gdl) { if (gdl instanceof GdlRelation) { GdlRelation relation = (GdlRelation) gdl; String name = relation.getName().toString(); if (name.equals("init")) { if (relation.arity() != 1) throw new RuntimeException("Can't init more than one thing as far as I know."); GdlTerm template = relation.get(0); if (template instanceof GdlConstant) { List<GdlTerm> body = new ArrayList<GdlTerm>(); body.add(template); GdlRelation toAdd = GdlPool.getRelation(baseConstant, body); baseRelations.add(toAdd); System.err.println("Weird init of constant"); } else if (template instanceof GdlVariable) { System.err.println("Weird init of constant"); List<GdlTerm> body = new ArrayList<GdlTerm>(); body.add(universalDom); GdlRelation toAdd = GdlPool.getRelation(baseConstant, body); baseRelations.add(toAdd); System.err.println("Weird init of variable"); } else if (template instanceof GdlFunction) { GdlFunction func = (GdlFunction) template; instantiateBaseProps(func.toSentence()); } } } else if (gdl instanceof GdlRule) { GdlRule rule = (GdlRule) gdl; String name = rule.getHead().getName().toString(); if (name.equals("next")) { GdlSentence head = rule.getHead(); if (head.arity() != 1) throw new RuntimeException("Can't next more than one thing as far as I know."); if (head.get(0) instanceof GdlVariable) { // weird case where you have rule like (next ?q) Location l = new Location(); l.idx = 0; l.name = head.getName(); Domain dom = domains.get(l); for (GdlConstant c : dom.values) { List<GdlTerm> body = new ArrayList<GdlTerm>(); body.add(c); baseRelations.add(GdlPool.getRelation(baseConstant, body)); } } else instantiateBasePropsWithRHS(head.get(0).toSentence(), rule.getBody()); } } }
/** @param args */ public static void main(String[] args) { List<Gdl> description = GameRepository.getDefaultRepository().getGame("conn4").getRules(); // List<Gdl> description = new LocalGameRepository().getGame("Kalaha").getRules(); PropNetFlattener flattener = new PropNetFlattener(description); List<GdlRule> flattened = flattener.flatten(); System.out.println("Flattened description contains: " + flattened.size() + " rules."); List<String> strings = new ArrayList<>(); for (GdlRule rule : flattened) { strings.add(rule.toString()); } Collections.sort(strings); for (String s : strings) { System.out.println(s); } }
void processDomain(Gdl gdl) { if (gdl instanceof GdlRelation) { GdlRelation relation = (GdlRelation) gdl; String name = relation.getName().toString(); if (!name.equals("base")) { addDomain(relation); } } else if (gdl instanceof GdlRule) { GdlRule rule = (GdlRule) gdl; GdlSentence head = rule.getHead(); if (head instanceof GdlRelation) { GdlRelation rel = (GdlRelation) head; int i = 0; for (GdlTerm term : rel.getBody()) { addDomain2(term, rel.getName(), i, rule.getBody()); i++; } } else if (head instanceof GdlProposition) { // GdlProposition prop = (GdlProposition)head; // addDomain2(prop.toTerm(), prop.getName(), 0, rule.getBody()); } else throw new RuntimeException("Don't know how to deal with this."); } }
// Returns null if the rule is useless. private static GdlRule removeNotDistinctLiteral(GdlRule rule, GdlNot notDistinctLiteral) { // Figure out the substitution we want... // If we have two constants: Either remove one or // maybe get rid of the ___? // One is a variable: Replace the variable with the other thing // throughout the rule GdlDistinct distinct = (GdlDistinct) notDistinctLiteral.getBody(); GdlTerm arg1 = distinct.getArg1(); GdlTerm arg2 = distinct.getArg2(); if (arg1 == arg2) { // Just remove that literal List<GdlLiteral> newBody = new ArrayList<GdlLiteral>(); newBody.addAll(rule.getBody()); newBody.remove(notDistinctLiteral); return GdlPool.getRule(rule.getHead(), newBody); } if (arg1 instanceof GdlVariable) { // What we return will still have the not-distinct literal, // but it will get replaced in the next pass. // (Even if we have two variables, they will be equal next time through.) return CommonTransforms.replaceVariable(rule, (GdlVariable) arg1, arg2); } if (arg2 instanceof GdlVariable) { return CommonTransforms.replaceVariable(rule, (GdlVariable) arg2, arg1); } if (arg1 instanceof GdlConstant || arg2 instanceof GdlConstant) { // We have two non-equal constants, or a constant and a function. // The rule should have no effect. return null; } // We have two functions. Complicated! (Have to replace them with unified version.) // We pass on this case for now. // TODO: Implement correctly. throw new UnsupportedOperationException( "We can't currently handle (not (distinct <function> <function>))."); }
private static GdlNot getNotDistinctLiteral(GdlRule rule) { for (GdlLiteral literal : rule.getBody()) { if (literal instanceof GdlNot) { GdlNot not = (GdlNot) literal; if (not.getBody() instanceof GdlDistinct) { // For now, we can only deal with this if not both are functions. // That means we have to skip that case at this point. GdlDistinct distinct = (GdlDistinct) not.getBody(); if (!(distinct.getArg1() instanceof GdlFunction) || !(distinct.getArg2() instanceof GdlFunction)) return not; } } } return null; }
private static List<Gdl> runOnce(List<Gdl> description) { List<Gdl> newDescription = new ArrayList<Gdl>(); // First: Clean up all rules with zero-element bodies for (Gdl gdl : description) { if (gdl instanceof GdlRule) { GdlRule rule = (GdlRule) gdl; if (rule.getBody().size() == 0) { newDescription.add(rule.getHead()); } else { newDescription.add(gdl); } } else { newDescription.add(gdl); } } // TODO: Add (role ?player) where appropriate, i.e. in rules for // "legal" or "input" where the first argument is an undefined // variable // Get rid of "extra parentheses", i.e. zero-arity functions description = newDescription; newDescription = new ArrayList<Gdl>(); for (Gdl gdl : description) { if (gdl instanceof GdlRelation) { newDescription.add(cleanParentheses((GdlRelation) gdl)); } else if (gdl instanceof GdlRule) { newDescription.add(cleanParentheses((GdlRule) gdl)); } else { newDescription.add(gdl); } } // TODO: Get rid of GdlPropositions in the description // Get rid of (not (distinct _ _)) literals in rules // TODO: Expand to functions description = newDescription; newDescription = new ArrayList<Gdl>(); for (Gdl gdl : description) { if (gdl instanceof GdlRule) { GdlRule cleaned = removeNotDistinctLiterals((GdlRule) gdl); if (cleaned != null) newDescription.add(cleaned); } else { newDescription.add(gdl); } } // Get rid of the old style of "base" sentences (with arity more than 1, not in rules) // See e.g. current version of Qyshinsu on the Dresden server description = newDescription; newDescription = new ArrayList<Gdl>(); boolean removeBaseSentences = false; for (Gdl gdl : description) { if (gdl instanceof GdlRelation) { GdlRelation relation = (GdlRelation) gdl; if (relation.getName() == BASE && relation.arity() != 1) { removeBaseSentences = true; break; } } } // Note that in this case, we have to remove ALL of them or we might // misinterpret this as being the new kind of "base" relation for (Gdl gdl : description) { if (gdl instanceof GdlRelation) { GdlRelation relation = (GdlRelation) gdl; if (removeBaseSentences && relation.getName() == BASE) { // Leave out the relation } else { newDescription.add(gdl); } } else { newDescription.add(gdl); } } return newDescription; }
private static GdlRule cleanParentheses(GdlRule rule) { GdlSentence cleanedHead = cleanParentheses(rule.getHead()); List<GdlLiteral> cleanedBody = new ArrayList<GdlLiteral>(); for (GdlLiteral literal : rule.getBody()) cleanedBody.add(cleanParentheses(literal)); return GdlPool.getRule(cleanedHead, cleanedBody); }