Package org.ggp.base.util.reasoner.gdl

Source Code of org.ggp.base.util.reasoner.gdl.GdlChainingReasoner

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

import java.util.Collection;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.ggp.base.util.concurrency.ConcurrencyUtils;
import org.ggp.base.util.gdl.GdlUtils;
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.GdlRule;
import org.ggp.base.util.gdl.grammar.GdlSentence;
import org.ggp.base.util.gdl.grammar.GdlVariable;
import org.ggp.base.util.gdl.model.SentenceDomainModel;
import org.ggp.base.util.gdl.model.SentenceDomainModels;
import org.ggp.base.util.gdl.model.SentenceDomainModels.VarDomainOpts;
import org.ggp.base.util.gdl.model.SentenceForm;
import org.ggp.base.util.gdl.model.SentenceFormModel;
import org.ggp.base.util.gdl.model.assignments.AddibleFunctionInfo;
import org.ggp.base.util.gdl.model.assignments.AssignmentIterator;
import org.ggp.base.util.gdl.model.assignments.Assignments;
import org.ggp.base.util.gdl.model.assignments.AssignmentsImpl;
import org.ggp.base.util.gdl.model.assignments.FunctionInfo;
import org.ggp.base.util.gdl.transforms.CommonTransforms;
import org.ggp.base.util.reasoner.DifferentialForwardChainingReasoner;

import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.SetMultimap;

/**
* An implementation of a ForwardChainingReasoner that uses Gdl objects
* directly and allows for differential processing of rules.
*/
public class GdlChainingReasoner implements
    DifferentialForwardChainingReasoner<GdlRule, GdlSentenceSet> {
  private final SentenceFormModel model;
  private final ImmutableMultimap<SentenceForm, GdlSentence> constants;

  private GdlChainingReasoner(SentenceFormModel model, ImmutableMultimap<SentenceForm, GdlSentence> constants) {
    this.model = model;
    this.constants = constants;
  }

  public static GdlChainingReasoner create(SentenceFormModel model) {
    ImmutableMultimap.Builder<SentenceForm, GdlSentence> constantsBuilder = ImmutableMultimap.builder();
    for (SentenceForm form : model.getSentenceForms()) {
      constantsBuilder.putAll(form, model.getSentencesListedAsTrue(form));
    }
    return new GdlChainingReasoner(model, constantsBuilder.build());
  }

  @Override
  public GdlSentenceSet getConstantSentences() {
    return GdlSentenceSet.create(constants);
  }

  @Override
  public GdlSentenceSet getRuleResults(GdlRule rule,
      SentenceDomainModel domainModel,
      GdlSentenceSet sentencesSoFar) throws InterruptedException {
    ConcurrencyUtils.checkForInterruption();
    SentenceForm headForm = model.getSentenceForm(rule.getHead());
    Map<GdlVariable, Set<GdlConstant>> varDomains = SentenceDomainModels.getVarDomains(rule, domainModel, VarDomainOpts.INCLUDE_HEAD);
    Map<SentenceForm, ? extends FunctionInfo> functionInfoMap = sentencesSoFar.getFunctionInfo();
    Map<SentenceForm, ? extends Collection<GdlSentence>> completedSentenceFormValues = sentencesSoFar.getSentences().asMap();

    AssignmentsImpl assignments = new AssignmentsImpl(rule, varDomains, functionInfoMap, completedSentenceFormValues);
    AssignmentIterator asnItr = assignments.getIterator();
    GdlSentenceSet sentencesToAdd = GdlSentenceSet.create();
    while (asnItr.hasNext()) {
      Map<GdlVariable, GdlConstant> assignment = asnItr.next();
      boolean allSatisfied = true;
      for (GdlLiteral literal : rule.getBody()) {
        ConcurrencyUtils.checkForInterruption();
        if (!satisfies(assignment, literal, sentencesSoFar.getSentences())) {
          asnItr.changeOneInNext(GdlUtils.getVariables(literal), assignment);
          allSatisfied = false;
          break;
        }
      }
      if (allSatisfied) {
        GdlSentence head = rule.getHead();
        sentencesToAdd.put(headForm, CommonTransforms.replaceVariables(head, assignment));
        asnItr.changeOneInNext(GdlUtils.getVariables(head), assignment);
      }
    }
    return sentencesToAdd;
  }

  private boolean satisfies(Map<GdlVariable, GdlConstant> assignment,
      GdlLiteral literal, SetMultimap<SentenceForm, GdlSentence> sentencesSoFar) {
    if (literal instanceof GdlSentence) {
      return satisfiesSentence(assignment, (GdlSentence) literal, sentencesSoFar);
    } else if (literal instanceof GdlNot) {
      GdlLiteral body = ((GdlNot) literal).getBody();
      if (!(body instanceof GdlSentence)) {
        throw new IllegalStateException("Negated literal should be a sentence but isn't: " + body);
      }
      return !satisfiesSentence(assignment, (GdlSentence) body, sentencesSoFar);
    } else if (literal instanceof GdlDistinct) {
      return satisfiesDistinct(assignment, (GdlDistinct) literal);
    } else if (literal instanceof GdlOr) {
      GdlOr or = (GdlOr) literal;
      for (int i = 0; i < or.arity(); i++) {
        GdlLiteral innerLiteral = or.get(i);
        if (satisfies(assignment, innerLiteral, sentencesSoFar)) {
          return true;
        }
      }
      return false;
    } else {
      throw new IllegalArgumentException("Unrecognized type of literal " + literal.getClass() + " for literal " + literal);
    }
  }

  private boolean satisfiesSentence(Map<GdlVariable, GdlConstant> assignment,
      GdlSentence sentence,
      SetMultimap<SentenceForm, GdlSentence> sentencesSoFar) {
    sentence = CommonTransforms.replaceVariables(sentence, assignment);
    SentenceForm form = model.getSentenceForm(sentence);
    return sentencesSoFar.get(form).contains(sentence);
  }

  private boolean satisfiesDistinct(Map<GdlVariable, GdlConstant> assignment,
      GdlDistinct distinct) {
    distinct = CommonTransforms.replaceVariables(distinct, assignment);
    return distinct.getArg1() != distinct.getArg2();
  }

  @Override
  public GdlSentenceSet getUnion(
      GdlSentenceSet oldSentences,
      GdlSentenceSet newSentences) {
    oldSentences.putAll(newSentences.getSentences());
    return oldSentences;
  }

  @Override
  public boolean isSubsetOf(
      GdlSentenceSet oldSentences,
      GdlSentenceSet newSentences) {
    for (Entry<SentenceForm, GdlSentence> entry : newSentences.getSentences().entries()) {
      if (!oldSentences.containsSentence(entry.getKey(), entry.getValue())) {
        return false;
      }
    }
    return true;
  }

  @Override
  public GdlSentenceSet getRuleResultsForNewSentences(
      GdlRule rule, SentenceDomainModel domainModel,
      GdlSentenceSet allSentences,
      GdlSentenceSet newSentences) throws InterruptedException {
    GdlSentenceSet results = GdlSentenceSet.create();
    for (GdlLiteral literal : rule.getBody()) {
      ConcurrencyUtils.checkForInterruption();
      if (literal instanceof GdlSentence) {
        SentenceForm literalForm = domainModel.getSentenceForm((GdlSentence) literal);
        addRuleResultsForChosenLiteral(
            rule,
            (GdlSentence) literal,
            newSentences.getSentences().get(literalForm),
            domainModel,
            allSentences,
            results);
      } else if (literal instanceof GdlOr) {
        throw new IllegalArgumentException("Need more implementation work for this to work with ORs here");
      }
    }
    return results;
  }

  private void addRuleResultsForChosenLiteral(GdlRule rule,
      GdlSentence chosenLiteral, Set<GdlSentence> chosenNewSentences,
      SentenceDomainModel domainModel,
      GdlSentenceSet allSentences,
      GdlSentenceSet sentencesToAdd) {
    SentenceForm headForm = model.getSentenceForm(rule.getHead());
    Map<GdlVariable, Set<GdlConstant>> varDomains = SentenceDomainModels.getVarDomains(rule, domainModel, VarDomainOpts.INCLUDE_HEAD);
    Map<SentenceForm, AddibleFunctionInfo> functionInfoMap = allSentences.getFunctionInfo();
    Map<SentenceForm, ? extends Collection<GdlSentence>> completedSentenceFormValues = allSentences.getSentences().asMap();

    for (GdlSentence chosenNewSentence : chosenNewSentences) {
      Map<GdlVariable, GdlConstant> preassignments = GdlUtils.getAssignmentMakingLeftIntoRight(chosenLiteral, chosenNewSentence);
      if (preassignments != null) {
        Assignments assignments = new AssignmentsImpl(preassignments, rule, varDomains, functionInfoMap, completedSentenceFormValues);
        AssignmentIterator asnItr = assignments.getIterator();
        while (asnItr.hasNext()) {
          Map<GdlVariable, GdlConstant> assignment = asnItr.next();

          boolean allSatisfied = true;
          for (GdlLiteral literal : rule.getBody()) {
            if (literal == chosenLiteral) {
              //Already satisfied
              continue;
            }
            if (!satisfies(assignment, literal, allSentences.getSentences())) {
              asnItr.changeOneInNext(GdlUtils.getVariables(literal), assignment);
              allSatisfied = false;
              break;
            }
          }
          if (allSatisfied) {
            GdlSentence head = rule.getHead();
            GdlSentence newHead = CommonTransforms.replaceVariables(head, assignment);
            if (!allSentences.containsSentence(headForm, newHead)) {
              sentencesToAdd.put(headForm, newHead);
            }
            asnItr.changeOneInNext(GdlUtils.getVariables(head), assignment);
          }
        }
      }
    }
  }
}
TOP

Related Classes of org.ggp.base.util.reasoner.gdl.GdlChainingReasoner

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.