Package org.ggp.base.util.gdl.model

Source Code of org.ggp.base.util.gdl.model.SentenceFormModelFactory

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

import java.util.HashSet;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;

import org.ggp.base.util.gdl.GdlVisitor;
import org.ggp.base.util.gdl.GdlVisitors;
import org.ggp.base.util.gdl.grammar.Gdl;
import org.ggp.base.util.gdl.grammar.GdlLiteral;
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.transforms.GdlCleaner;
import org.ggp.base.util.gdl.transforms.VariableConstrainer;

import com.google.common.base.Predicates;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSetMultimap;
import com.google.common.collect.SetMultimap;
import com.google.common.collect.Sets;

public class SentenceFormModelFactory {
  /**
   * Creates a SentenceFormModel for the given game description.
   *
   * It is recommended to use the {@link GdlCleaner} on the game
   * description before constructing this model, to prevent some
   * common problems with slightly invalid game descriptions.
   *
   * It is also recommended to use the {@link VariableConstrainer}
   * on the description before using this. If the description allows
   * for function-valued variables, some aspects of the model,
   * including the dependency graph, may be incorrect.
   */
  public static ImmutableSentenceFormModel create(List<Gdl> description) throws InterruptedException {
    ImmutableList<Gdl> gameRules = ImmutableList.copyOf(description);
    ImmutableSet<SentenceForm> sentenceForms = getSentenceForms(gameRules);
    ImmutableSetMultimap<SentenceForm, GdlRule> rulesByForm = getRulesByForm(gameRules, sentenceForms);
    ImmutableSetMultimap<SentenceForm, GdlSentence> trueSentencesByForm = getTrueSentencesByForm(gameRules, sentenceForms);
    ImmutableSetMultimap<SentenceForm, SentenceForm> dependencyGraph = getDependencyGraph(sentenceForms, rulesByForm);
    ImmutableSet<SentenceForm> constantSentenceForms = getConstantSentenceForms(sentenceForms, dependencyGraph);
    ImmutableSet<SentenceForm> independentSentenceForms = getIndependentSentenceForms(sentenceForms, dependencyGraph);

    return new ImmutableSentenceFormModel(
        gameRules,
        sentenceForms,
        constantSentenceForms,
        independentSentenceForms,
        dependencyGraph,
        rulesByForm,
        trueSentencesByForm);
  }

  private static ImmutableSet<SentenceForm> getIndependentSentenceForms(
      ImmutableSet<SentenceForm> sentenceForms,
      ImmutableSetMultimap<SentenceForm, SentenceForm> dependencyGraph) {
    SetMultimap<SentenceForm, SentenceForm> augmentedGraph = augmentGraphWithLanguageRules(dependencyGraph, sentenceForms);
    ImmutableSet<SentenceForm> moveDependentSentenceForms =
        DependencyGraphs.getMatchingAndDownstream(sentenceForms, augmentedGraph,
            SentenceForms.DOES_PRED);
    return ImmutableSet.copyOf(Sets.difference(sentenceForms, moveDependentSentenceForms));
  }

  private static ImmutableSet<SentenceForm> getConstantSentenceForms(
      ImmutableSet<SentenceForm> sentenceForms,
      ImmutableSetMultimap<SentenceForm, SentenceForm> dependencyGraph) {
    SetMultimap<SentenceForm, SentenceForm> augmentedGraph = augmentGraphWithLanguageRules(dependencyGraph, sentenceForms);
    ImmutableSet<SentenceForm> changingSentenceForms =
        DependencyGraphs.getMatchingAndDownstream(sentenceForms, augmentedGraph,
            Predicates.or(SentenceForms.TRUE_PRED, SentenceForms.DOES_PRED));
    return ImmutableSet.copyOf(Sets.difference(sentenceForms, changingSentenceForms));
  }

  /**
   * Modifies the graph by adding dependencies corresponding to language rules
   * that apply in a looser sense: TRUE forms depend on NEXT forms and DOES
   * forms depend on LEGAL forms.
   */
  private static SetMultimap<SentenceForm, SentenceForm> augmentGraphWithLanguageRules(
      ImmutableSetMultimap<SentenceForm, SentenceForm> dependencyGraph, ImmutableSet<SentenceForm> sentenceForms) {
    SetMultimap<SentenceForm, SentenceForm> newGraph = HashMultimap.create();
    newGraph.putAll(dependencyGraph);
    for (SentenceForm form : sentenceForms) {
      if (form.getName() == GdlPool.TRUE) {
        SentenceForm nextForm = form.withName(GdlPool.NEXT);
        if (sentenceForms.contains(nextForm)) {
          newGraph.put(form, nextForm);
        }
      } else if (form.getName() == GdlPool.DOES) {
        SentenceForm legalForm = form.withName(GdlPool.LEGAL);
        if (sentenceForms.contains(legalForm)) {
          newGraph.put(form, legalForm);
        }
      }
    }
    return newGraph;
  }

  private static ImmutableSetMultimap<SentenceForm, SentenceForm> getDependencyGraph(
      ImmutableSet<SentenceForm> sentenceForms,
      ImmutableSetMultimap<SentenceForm, GdlRule> rulesByForm) {
    SetMultimap<SentenceForm, SentenceForm> dependencyGraph = HashMultimap.create();
    for(Entry<SentenceForm, GdlRule> entry : rulesByForm.entries()) {
      SentenceForm head = entry.getKey();
      GdlRule rule = entry.getValue();
      for(GdlLiteral bodyLiteral : rule.getBody()) {
        dependencyGraph.putAll(head, getSentenceFormsInBody(bodyLiteral, sentenceForms));
      }
    }
    return ImmutableSetMultimap.copyOf(dependencyGraph);
  }

  private static Set<SentenceForm> getSentenceFormsInBody(
      GdlLiteral bodyLiteral, final ImmutableSet<SentenceForm> sentenceForms) {
    final Set<SentenceForm> forms = new HashSet<SentenceForm>();
    GdlVisitors.visitAll(bodyLiteral, new GdlVisitor() {
      @Override
      public void visitSentence(GdlSentence sentence) {
        for (SentenceForm form : sentenceForms) {
          if (form.matches(sentence)) {
            forms.add(form);
          }
        }
      }
    });
    return forms;
  }

  private static ImmutableSetMultimap<SentenceForm, GdlSentence> getTrueSentencesByForm(
      ImmutableList<Gdl> gameRules,
      ImmutableSet<SentenceForm> sentenceForms) {
    ImmutableSetMultimap.Builder<SentenceForm, GdlSentence> builder =
        ImmutableSetMultimap.builder();

    for(Gdl gdl : gameRules) {
      if(gdl instanceof GdlSentence) {
        GdlSentence sentence = (GdlSentence) gdl;
        for (SentenceForm form : sentenceForms) {
          if(form.matches(sentence)) {
            builder.put(form, sentence);
            break;
          }
        }
      }
    }

    return builder.build();
  }

  private static ImmutableSetMultimap<SentenceForm, GdlRule> getRulesByForm(
      ImmutableList<Gdl> gameRules,
      ImmutableSet<SentenceForm> sentenceForms) {
    ImmutableSetMultimap.Builder<SentenceForm, GdlRule> builder =
        ImmutableSetMultimap.builder();

    for(Gdl gdl : gameRules) {
      if(gdl instanceof GdlRule) {
        GdlRule rule = (GdlRule) gdl;
        for (SentenceForm form : sentenceForms) {
          if(form.matches(rule.getHead())) {
            builder.put(form, rule);
            break;
          }
        }
      }
    }

    return builder.build();
  }

  private static ImmutableSet<SentenceForm> getSentenceForms(
      ImmutableList<Gdl> gameRules) throws InterruptedException {
    return new SentenceFormsFinder(gameRules).findSentenceForms();
  }
}
TOP

Related Classes of org.ggp.base.util.gdl.model.SentenceFormModelFactory

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.