All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ggp.base.util.assignments.LegacyAssignmentIterationPlanFactory Maven / Gradle / Ivy

There is a newer version: 0.0.15
Show newest version
package org.ggp.base.util.assignments;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Set;

import org.ggp.base.util.gdl.GdlUtils;
import org.ggp.base.util.gdl.grammar.GdlConstant;
import org.ggp.base.util.gdl.grammar.GdlLiteral;
import org.ggp.base.util.gdl.grammar.GdlRelation;
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.SimpleSentenceForm;
import org.ggp.base.util.gdl.model.assignments.FunctionInfo;
import org.ggp.base.util.gdl.model.assignments.IterationOrderCandidate;
import org.ggp.base.util.gdl.transforms.ConstantChecker;

import com.google.common.collect.Maps;

/**
 * This is probably the best iteration plan factory at the moment; a lot of
 * work went into it the first time around. This is "rewritten" for clarity
 * and to work with the new assignment iteration classes and MPNF.
 *
 * Adapted from code in the old AssignmentsImpl, mostly.
 */
public class LegacyAssignmentIterationPlanFactory {
    public static final boolean ANALYTIC_FUNCTION_ORDERING = false;
    //TODO: Test above with true vs. false

    public static NewAssignmentIterationPlan create(GdlRule rule, SentenceDomainModel domainModel,
            ConstantChecker constantChecker,
            Map functionInfoMap) {

        //		System.out.println("rule: " + rule);
        Map> varDomains =
                SentenceDomainModels.getVarDomains(rule, domainModel, VarDomainOpts.INCLUDE_HEAD);
        //		System.out.println("varDomains: " + varDomains);
        //TODO: This should probably just check the sizes in the ConstantChecker?
        //Or perhaps accept some smarter notion of ___...
        //TODO: Pass this in
        Map completedSentenceFormSizes =
                Maps.newHashMap();
        for (SentenceForm constantForm : constantChecker.getConstantSentenceForms()) {
            completedSentenceFormSizes.put(constantForm, constantChecker.getTrueSentences(constantForm).size());
        }
        IterationOrderCandidate bestIterationOrderCandidate = getBestIterationOrderCandidate(rule,
                varDomains,
                functionInfoMap,
                completedSentenceFormSizes,
                ANALYTIC_FUNCTION_ORDERING);

        return toPlan(bestIterationOrderCandidate, varDomains, constantChecker);
    }

    private static NewAssignmentIterationPlan toPlan(
            IterationOrderCandidate bestOrder,
            Map> varDomains, ConstantChecker constantChecker) {
        //		List assignmentOrder = bestOrder.getVariableOrdering();
        //		List strategies = Lists.newArrayList();
        //
        //		bestOrder.
        //
        //		return ComplexAssignmentIterationPlan.create(assignmentOrder, strategies);
        return bestOrder.toAssignmentIterationPlan(varDomains, constantChecker);
    }

    /**
     * Finds the iteration order (including variables, functions, and
     * source conjuncts) that is expected to result in the fastest iteration.
     *
     * The value that is compared for each ordering is the product of:
     * - For each source conjunct, the number of tuples offered by the conjunct;
     * - For each variable not defined by a function, the size of its domain.
     *
     * @param functionInfoMap
     * @param completedSentenceFormSizes For each sentence form, this may optionally
     * contain the number of possible sentences of this form. This is useful if the
     * number of sentences is much lower than the product of its variables' domain
     * sizes; however, if this contains sentence forms where the set of sentences
     * is unknown, then it may return an ordering that is unusable.
     */
    protected static IterationOrderCandidate getBestIterationOrderCandidate(GdlRule rule,
            /*SentenceModel model,*/
            Map> varDomains,
            Map functionInfoMap,
            Map completedSentenceFormSizes,
            //			Map preassignment,
            boolean analyticFunctionOrdering) {
        //Here are the things we need to pass into the first IOC constructor
        List sourceConjunctCandidates = new ArrayList();
        //What is a source conjunct candidate?
        //- It is a positive conjunct in the rule (i.e. a GdlSentence in the body).
        //- It has already been fully defined; i.e. it is not recursively defined in terms of the current form.
        //Furthermore, we know the number of potentially true tuples in it.
        List varsToAssign = GdlUtils.getVariables(rule);
        List newVarsToAssign = new ArrayList();
        for(GdlVariable var : varsToAssign)
            if(!newVarsToAssign.contains(var))
                newVarsToAssign.add(var);
        varsToAssign = newVarsToAssign;
        //		if(preassignment != null)
        //			varsToAssign.removeAll(preassignment.keySet());

        //Calculate var domain sizes
        Map varDomainSizes = getVarDomainSizes(varDomains/*rule, model*/);

        List sourceConjunctSizes = new ArrayList();
        for(GdlLiteral conjunct : rule.getBody()) {
            if(conjunct instanceof GdlRelation) {
                SentenceForm form = SimpleSentenceForm.create((GdlRelation)conjunct);
                if(completedSentenceFormSizes != null
                        && completedSentenceFormSizes.containsKey(form)) {
                    int size = completedSentenceFormSizes.get(form);
                    //New: Don't add if it will be useless as a source
                    //For now, we take a strict definition of that
                    //Compare its size with the product of the domains
                    //of the variables it defines
                    //In the future, we could require a certain ratio
                    //to decide that this is worthwhile
                    GdlRelation relation = (GdlRelation) conjunct;
                    int maxSize = 1;
                    Set vars = new HashSet(GdlUtils.getVariables(relation));
                    for(GdlVariable var : vars) {
                        int domainSize = varDomainSizes.get(var);
                        maxSize *= domainSize;
                    }
                    if(size >= maxSize)
                        continue;
                    sourceConjunctCandidates.add(relation);
                    sourceConjunctSizes.add(size);
                }
            }
        }

        List functionalSentences = new ArrayList();
        List functionalSentencesInfo = new ArrayList();
        for(GdlLiteral conjunct : rule.getBody()) {
            if(conjunct instanceof GdlSentence) {
                SentenceForm form = SimpleSentenceForm.create((GdlSentence) conjunct);
                if(functionInfoMap != null && functionInfoMap.containsKey(form)) {
                    functionalSentences.add((GdlSentence) conjunct);
                    functionalSentencesInfo.add(functionInfoMap.get(form));
                }
            }
        }

        //TODO: If we have a head assignment, treat everything as already replaced
        //Maybe just translate the rule? Or should we keep the pool clean?

        IterationOrderCandidate emptyCandidate = new IterationOrderCandidate(varsToAssign, sourceConjunctCandidates,
                sourceConjunctSizes, functionalSentences, functionalSentencesInfo, varDomainSizes);
        PriorityQueue searchQueue = new PriorityQueue();
        searchQueue.add(emptyCandidate);

        while(!searchQueue.isEmpty()) {
            IterationOrderCandidate curNode = searchQueue.remove();
            //			System.out.println("Node being checked out: " + curNode);
            if(curNode.isComplete()) {
                //This is the complete ordering with the lowest heuristic value
                return curNode;
            }
            searchQueue.addAll(curNode.getChildren(analyticFunctionOrdering));
        }
        throw new RuntimeException("Found no complete iteration orderings");
    }

    private static Map getVarDomainSizes(/*GdlRule rule,
			SentenceModel model*/Map> varDomains) {
        Map varDomainSizes = new HashMap();
        //Map> varDomains = model.getVarDomains(rule);
        for(GdlVariable var : varDomains.keySet()) {
            varDomainSizes.put(var, varDomains.get(var).size());
        }
        return varDomainSizes;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy