Package org.ggp.base.util.gdl.transforms

Source Code of org.ggp.base.util.gdl.transforms.DistinctAndNotMover

package org.ggp.base.util.gdl.transforms;

import java.util.List;
import java.util.Set;

import org.ggp.base.util.gdl.GdlUtils;
import org.ggp.base.util.gdl.grammar.Gdl;
import org.ggp.base.util.gdl.grammar.GdlDistinct;
import org.ggp.base.util.gdl.grammar.GdlLiteral;
import org.ggp.base.util.gdl.grammar.GdlNot;
import org.ggp.base.util.gdl.grammar.GdlPool;
import org.ggp.base.util.gdl.grammar.GdlRule;
import org.ggp.base.util.gdl.grammar.GdlSentence;
import org.ggp.base.util.gdl.grammar.GdlVariable;

import com.google.common.collect.Lists;
import com.google.common.collect.Sets;

/**
* As a GDL transformer, this class takes in a GDL description of a game,
* transforms it in some way, and outputs a new GDL descriptions of a game
* which is functionally equivalent to the original game.
*
* The AimaProver does not correctly apply "distinct" literals in rules if
* they have not yet been bound. (See test_distinct_beginning_rule.kif for
* an example where this comes up.) The same is true for "not" literals.
* This transformation moves "distinct" and "not" literals later in the
* rule, so they always appear after sentence literals have defined those
* variables.
*
* This should be applied to the input to the ProverStateMachine until this
* bug is fixed some other way.
*/
public class DistinctAndNotMover {
  public static List<Gdl> run(List<Gdl> oldRules) {
    oldRules = DeORer.run(oldRules);

    List<Gdl> newRules = Lists.newArrayListWithCapacity(oldRules.size());
    for (Gdl gdl : oldRules) {
      if (gdl instanceof GdlRule) {
        GdlRule rule = (GdlRule) gdl;
        newRules.add(reorderRule(rule));
      } else {
        newRules.add(gdl);
      }
    }
    return newRules;
  }

  private static GdlRule reorderRule(GdlRule oldRule) {
    List<GdlLiteral> newBody = Lists.newArrayList(oldRule.getBody());
    rearrangeDistinctsAndNots(newBody);
    return GdlPool.getRule(oldRule.getHead(), newBody);
  }

  private static void rearrangeDistinctsAndNots(List<GdlLiteral> ruleBody) {
    Integer oldIndex = findDistinctOrNotToMoveIndex(ruleBody);
    while (oldIndex != null) {
      GdlLiteral literalToMove = ruleBody.get(oldIndex);
      ruleBody.remove((int) oldIndex);
      reinsertLiteralInRightPlace(ruleBody, literalToMove);

      oldIndex = findDistinctOrNotToMoveIndex(ruleBody);
    }
  }

  //Returns null if no distincts have to be moved.
  private static Integer findDistinctOrNotToMoveIndex(List<GdlLiteral> ruleBody) {
    Set<GdlVariable> setVars = Sets.newHashSet();
    for (int i = 0; i < ruleBody.size(); i++) {
      GdlLiteral literal = ruleBody.get(i);
      if (literal instanceof GdlSentence) {
        setVars.addAll(GdlUtils.getVariables(literal));
      } else if (literal instanceof GdlDistinct
          || literal instanceof GdlNot) {
        if (!allVarsInLiteralAlreadySet(literal, setVars)) {
          return i;
        }
      }
    }
    return null;
  }

  private static void reinsertLiteralInRightPlace(List<GdlLiteral> ruleBody,
      GdlLiteral literalToReinsert) {
    Set<GdlVariable> setVars = Sets.newHashSet();
    for (int i = 0; i < ruleBody.size(); i++) {
      GdlLiteral literal = ruleBody.get(i);
      if (literal instanceof GdlSentence) {
        setVars.addAll(GdlUtils.getVariables(literal));

        if (allVarsInLiteralAlreadySet(literalToReinsert, setVars)) {
          ruleBody.add(i + 1, literalToReinsert);
          return;
        }
      }
    }
  }

  private static boolean allVarsInLiteralAlreadySet(GdlLiteral literal,
      Set<GdlVariable> setVars) {
    List<GdlVariable> varsInLiteral = GdlUtils.getVariables(literal);
    for (GdlVariable varInLiteral : varsInLiteral) {
      if (!setVars.contains(varInLiteral)) {
        return false;
      }
    }
    return true;
  }
}
TOP

Related Classes of org.ggp.base.util.gdl.transforms.DistinctAndNotMover

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.