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

Source Code of org.ggp.base.util.gdl.model.assignments.AssignmentFunction

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

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.ggp.base.util.gdl.grammar.GdlConstant;
import org.ggp.base.util.gdl.grammar.GdlFunction;
import org.ggp.base.util.gdl.grammar.GdlRelation;
import org.ggp.base.util.gdl.grammar.GdlTerm;
import org.ggp.base.util.gdl.grammar.GdlVariable;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;

public class AssignmentFunction {
    //How is the AssignmentFunction going to operate?
    //Well, some of the variables are going to be
    //specified as having one or more of these functions
    //apply to them. (If multiple apply, they all have
    //to agree.)
    //We pass in the current value of the tuple and
    //it gives us the value desired (or null).
    //This means it just has to know which indices in
    //the tuple (i.e. which variables) correspond to
    //which slots in its native tuple.

    //Used when multiple assignment functions are relevant
    //to the same variable. In this case we call these other
    //functions with the same arguments and return null if
    //any of the answers differ.
    private final ImmutableList<AssignmentFunction> internalFunctions;
    private final int querySize;
    private final ImmutableList<Boolean> isInputConstant;
    private final ImmutableMap<Integer, GdlConstant> queryConstants;
    private final ImmutableList<Integer> queryInputIndices;
    private final ImmutableMap<ImmutableList<GdlConstant>, GdlConstant> function;
    //Some sort of trie might work better here...

    private AssignmentFunction(ImmutableList<AssignmentFunction> internalFunctions,
        int querySize,
        ImmutableList<Boolean> isInputConstant,
        ImmutableMap<Integer, GdlConstant> queryConstants,
        ImmutableList<Integer> queryInputIndices,
        ImmutableMap<ImmutableList<GdlConstant>, GdlConstant> function) {
      this.internalFunctions = internalFunctions;
      this.querySize = querySize;
      this.isInputConstant = isInputConstant;
      this.queryConstants = queryConstants;
      this.queryInputIndices = queryInputIndices;
      this.function = function;
    }

    public static AssignmentFunction create(GdlRelation conjunct, FunctionInfo functionInfo,
        GdlVariable rightmostVar, List<GdlVariable> varOrder,
        Map<GdlVariable, GdlConstant> preassignment) {
      //We have to set up the things mentioned above...
      List<AssignmentFunction> internalFunctions = new ArrayList<AssignmentFunction>();

      //We can traverse the conjunct for the list of variables/constants...
      List<GdlTerm> terms = new ArrayList<GdlTerm>();
      gatherVars(conjunct.getBody(), terms);
      //Note that we assume here that the var of interest only
      //appears once in the relation...
      int varIndex = terms.indexOf(rightmostVar);
      if(varIndex == -1) {
        System.out.println("conjunct is: " + conjunct);
        System.out.println("terms are: " + terms);
        System.out.println("righmostVar is: " + rightmostVar);
      }
      terms.remove(rightmostVar);
      Map<ImmutableList<GdlConstant>, GdlConstant> function = functionInfo.getValueMap(varIndex);

      //Set up inputs and such, using terms
      int querySize = terms.size();
      List<Boolean> isInputConstant = new ArrayList<Boolean>(terms.size());
      Map<Integer, GdlConstant> queryConstants = Maps.newHashMap();
      List<Integer> queryInputIndices = new ArrayList<Integer>(terms.size());
      for(int i = 0; i < terms.size(); i++) {
        GdlTerm term = terms.get(i);
        if(term instanceof GdlConstant) {
          isInputConstant.add(true);
          queryConstants.put(i, (GdlConstant) term);
          queryInputIndices.add(-1);
        } else if(term instanceof GdlVariable) {
          //Is it in the head assignment?
          if(preassignment.containsKey(term)) {
            isInputConstant.add(true);
            queryConstants.put(i, preassignment.get(term));
            queryInputIndices.add(-1);
          } else {
            isInputConstant.add(false);
//            queryConstants.add(null);
            //What value do we put here?
            //We want to grab some value out of the
            //input tuple, which uses functional ordering
            //Index of the relevant variable, by the
            //assignment's ordering
            queryInputIndices.add(varOrder.indexOf(term));
          }
        }
      }
      return new AssignmentFunction(
          ImmutableList.copyOf(internalFunctions),
          querySize,
          ImmutableList.copyOf(isInputConstant),
          ImmutableMap.copyOf(queryConstants),
          ImmutableList.copyOf(queryInputIndices),
          ImmutableMap.copyOf(function));
    }

    public boolean functional() {
      return (function != null);
    }

    private static void gatherVars(List<GdlTerm> body, List<GdlTerm> terms) {
      for(GdlTerm term : body) {
        if(term instanceof GdlConstant || term instanceof GdlVariable)
          terms.add(term);
        else if(term instanceof GdlFunction)
          gatherVars(((GdlFunction)term).getBody(), terms);
      }
    }

    public GdlConstant getValue(List<GdlConstant> remainingTuple) {
      //We have a map from a tuple of GdlConstants
      //to the GdlConstant we need, provided by the FunctionInfo.
      //We need to make the tuple for this map.
      List<GdlConstant> queryTuple = new ArrayList<GdlConstant>(querySize);
      //Now we have to fill in the query
      for(int i = 0; i < querySize; i++) {
        if(isInputConstant.get(i)) {
          queryTuple.add(queryConstants.get(i));
        } else {
          queryTuple.add(remainingTuple.get(queryInputIndices.get(i)));
        }
      }
      //The query is filled; we ask the map
      GdlConstant answer = function.get(queryTuple);

      for (AssignmentFunction internalFunction : internalFunctions) {
        if (internalFunction.getValue(remainingTuple) != answer) {
          return null;
        }
      }
      return answer;
    }
  }
TOP

Related Classes of org.ggp.base.util.gdl.model.assignments.AssignmentFunction

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.