예제 #1
0
 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
   }
 }
예제 #2
0
  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);
  }
예제 #3
0
  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);
        }
      }
    }
  }
예제 #4
0
  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.");
  }
예제 #5
0
 public static List<GdlSentence> getSentencesInRuleBody(GdlRule rule) {
   List<GdlSentence> result = new ArrayList<>();
   for (GdlLiteral literal : rule.getBody()) {
     addSentencesInLiteral(literal, result);
   }
   return result;
 }
예제 #6
0
 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());
     }
   }
 }
예제 #7
0
  /** @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);
    }
  }
예제 #8
0
  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.");
    }
  }
예제 #9
0
 // 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>)).");
 }
예제 #10
0
 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;
 }
예제 #11
0
  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;
  }
예제 #12
0
 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);
 }