Package org.ggp.base.util.prover.aima

Source Code of org.ggp.base.util.prover.aima.AimaProver

package org.ggp.base.util.prover.aima;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

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.GdlLiteral;
import org.ggp.base.util.gdl.grammar.GdlNot;
import org.ggp.base.util.gdl.grammar.GdlOr;
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.DistinctAndNotMover;
import org.ggp.base.util.prover.Prover;
import org.ggp.base.util.prover.aima.cache.ProverCache;
import org.ggp.base.util.prover.aima.knowledge.KnowledgeBase;
import org.ggp.base.util.prover.aima.renamer.VariableRenamer;
import org.ggp.base.util.prover.aima.substituter.Substituter;
import org.ggp.base.util.prover.aima.substitution.Substitution;
import org.ggp.base.util.prover.aima.unifier.Unifier;

import com.google.common.collect.Sets;


public final class AimaProver implements Prover
{

  private final KnowledgeBase knowledgeBase;

  private final ProverCache fixedAnswerCache = ProverCache.createMultiThreadedCache();

  public AimaProver(List<Gdl> description)
  {
    description = DistinctAndNotMover.run(description);
    knowledgeBase = new KnowledgeBase(Sets.newHashSet(description));
  }

  private Set<GdlSentence> ask(GdlSentence query, Set<GdlSentence> context, boolean askOne)
  {
    LinkedList<GdlLiteral> goals = new LinkedList<GdlLiteral>();
    goals.add(query);

    Set<Substitution> answers = new HashSet<Substitution>();
    Set<GdlSentence> alreadyAsking = new HashSet<GdlSentence>();
    ask(goals, new KnowledgeBase(context), new Substitution(), ProverCache.createSingleThreadedCache(),
        new VariableRenamer(), askOne, answers, alreadyAsking);

    Set<GdlSentence> results = new HashSet<GdlSentence>();
    for (Substitution theta : answers)
    {
      results.add(Substituter.substitute(query, theta));
    }

    return results;
  }

  // Returns true iff the result is constant across all possible states of the game.
  private boolean ask(LinkedList<GdlLiteral> goals, KnowledgeBase context, Substitution theta, ProverCache cache, VariableRenamer renamer, boolean askOne, Set<Substitution> results, Set<GdlSentence> alreadyAsking)
  {
    if (goals.size() == 0)
    {
      results.add(theta);
      return true;
    }
    else
    {
      GdlLiteral literal = goals.removeFirst();
      GdlLiteral qPrime = Substituter.substitute(literal, theta);

      boolean isConstant;

      if (qPrime instanceof GdlDistinct)
      {
        GdlDistinct distinct = (GdlDistinct) qPrime;
        isConstant = askDistinct(distinct, goals, context, theta, cache, renamer, askOne, results, alreadyAsking);
      }
      else if (qPrime instanceof GdlNot)
      {
        GdlNot not = (GdlNot) qPrime;
        isConstant = askNot(not, goals, context, theta, cache, renamer, askOne, results, alreadyAsking);
      }
      else if (qPrime instanceof GdlOr)
      {
        GdlOr or = (GdlOr) qPrime;
        isConstant = askOr(or, goals, context, theta, cache, renamer, askOne, results, alreadyAsking);
      }
      else
      {
        GdlSentence sentence = (GdlSentence) qPrime;
        isConstant = askSentence(sentence, goals, context, theta, cache, renamer, askOne, results, alreadyAsking);
      }

      goals.addFirst(literal);
      return isConstant;
    }
  }

  @Override
  public Set<GdlSentence> askAll(GdlSentence query, Set<GdlSentence> context)
  {
    return ask(query, context, false);
  }

  // Returns true iff the result is constant across all possible states of the game.
  private boolean askDistinct(GdlDistinct distinct, LinkedList<GdlLiteral> goals, KnowledgeBase context, Substitution theta, ProverCache cache, VariableRenamer renamer, boolean askOne, Set<Substitution> results, Set<GdlSentence> alreadyAsking)
  {
    if (!distinct.getArg1().equals(distinct.getArg2()))
    {
      return ask(goals, context, theta, cache, renamer, askOne, results, alreadyAsking);
    }
    return true;
  }

  // Returns true iff the result is constant across all possible states of the game.
  private boolean askNot(GdlNot not, LinkedList<GdlLiteral> goals, KnowledgeBase context, Substitution theta, ProverCache cache, VariableRenamer renamer, boolean askOne, Set<Substitution> results, Set<GdlSentence> alreadyAsking)
  {
    LinkedList<GdlLiteral> notGoals = new LinkedList<GdlLiteral>();
    notGoals.add(not.getBody());

    Set<Substitution> notResults = new HashSet<Substitution>();
    boolean isConstant = true;
    isConstant &= ask(notGoals, context, theta, cache, renamer, true, notResults, alreadyAsking);

    if (notResults.size() == 0)
    {
      isConstant &= ask(goals, context, theta, cache, renamer, askOne, results, alreadyAsking);
    }
    return isConstant;
  }

  @Override
  public GdlSentence askOne(GdlSentence query, Set<GdlSentence> context)
  {
    Set<GdlSentence> results = ask(query, context, true);
    return (results.size() > 0) ? results.iterator().next() : null;
  }

  // Returns true iff the result is constant across all possible states of the game.
  private boolean askOr(GdlOr or, LinkedList<GdlLiteral> goals, KnowledgeBase context, Substitution theta, ProverCache cache, VariableRenamer renamer, boolean askOne, Set<Substitution> results, Set<GdlSentence> alreadyAsking)
  {
    boolean isConstant = true;
    for (int i = 0; i < or.arity(); i++)
    {
      goals.addFirst(or.get(i));
      isConstant &= ask(goals, context, theta, cache, renamer, askOne, results, alreadyAsking);
      goals.removeFirst();

      if (askOne && (results.size() > 0))
      {
        break;
      }
    }
    return isConstant;
  }

  // Returns true iff the result is constant across all possible states of the game.
  private boolean askSentence(GdlSentence sentence, LinkedList<GdlLiteral> goals, KnowledgeBase context, Substitution theta, ProverCache cache, VariableRenamer renamer, boolean askOne, Set<Substitution> results, Set<GdlSentence> alreadyAsking)
  {
    GdlSentence varRenamedSentence = new VariableRenamer().rename(sentence);
    if (!fixedAnswerCache.contains(varRenamedSentence) && !cache.contains(varRenamedSentence))
    {
      //Prevent infinite loops on certain recursive queries.
      if(alreadyAsking.contains(sentence)) {
        return false;
      }
      alreadyAsking.add(sentence);
      List<GdlRule> candidates = new ArrayList<GdlRule>();
      candidates.addAll(knowledgeBase.fetch(sentence));
      candidates.addAll(context.fetch(sentence));
      boolean isConstant = !isTrueOrDoesSentence(sentence);

      Set<Substitution> sentenceResults = new HashSet<Substitution>();
      for (GdlRule rule : candidates)
      {
        GdlRule r = renamer.rename(rule);
        Substitution thetaPrime = Unifier.unify(r.getHead(), sentence);

        if (thetaPrime != null)
        {
          LinkedList<GdlLiteral> sentenceGoals = new LinkedList<GdlLiteral>();
          for (int i = 0; i < r.arity(); i++)
          {
            sentenceGoals.add(r.get(i));
          }

          isConstant &= ask(sentenceGoals, context, theta.compose(thetaPrime), cache, renamer, false, sentenceResults, alreadyAsking);
        }
      }

      if (isConstant) {
        fixedAnswerCache.put(sentence, varRenamedSentence, sentenceResults);
      } else {
        cache.put(sentence, varRenamedSentence, sentenceResults);
      }

      alreadyAsking.remove(sentence);
    }

    List<Substitution> cachedResults = fixedAnswerCache.get(sentence, varRenamedSentence);
    boolean isConstant = (cachedResults != null);
    if (cachedResults == null) {
      cachedResults = cache.get(sentence, varRenamedSentence);
    }
    for (Substitution thetaPrime : cachedResults)
    {
      isConstant &= ask(goals, context, theta.compose(thetaPrime), cache, renamer, askOne, results, alreadyAsking);
      if (askOne && (results.size() > 0))
      {
        break;
      }
    }
    return isConstant;
  }

  private boolean isTrueOrDoesSentence(GdlSentence sentence) {
    GdlConstant name = sentence.getName();
    return name == GdlPool.TRUE || name == GdlPool.DOES;
  }

  @Override
  public boolean prove(GdlSentence query, Set<GdlSentence> context)
  {
    return askOne(query, context) != null;
  }

}
TOP

Related Classes of org.ggp.base.util.prover.aima.AimaProver

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.