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

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

The newest version!
package org.ggp.base.util.assignments;

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

import javax.annotation.concurrent.Immutable;

import org.ggp.base.util.AlloyUtils;
import org.ggp.base.util.Immutables;
import org.ggp.base.util.Odometer;
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.GdlRule;
import org.ggp.base.util.gdl.grammar.GdlSentence;
import org.ggp.base.util.gdl.grammar.GdlTerm;
import org.ggp.base.util.gdl.grammar.GdlVariable;
import org.ggp.base.util.gdl.model.SentenceDomainModel;
import org.ggp.base.util.gdl.model.SentenceForm;
import org.ggp.base.util.gdl.model.SentenceFormDomain;

import com.google.common.base.Preconditions;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.SetMultimap;
import com.google.common.collect.Sets;

//Odometer-style iteration only
@Immutable
public class OdometerAssignmentIterationPlan implements NewAssignmentIterationPlan {
    //TODO: Better perf here if we use List> in valuesByVar?
    private final ImmutableList variables;
    private final ImmutableListMultimap valuesByVariable;

    private final ImmutableMap varIndexToUpdateByConjunct;

    private OdometerAssignmentIterationPlan(
            ImmutableList variables,
            ImmutableListMultimap valuesByVariable,
            ImmutableMap varIndexToUpdateByConjunct) {
        this.variables = variables;
        this.valuesByVariable = valuesByVariable;
        this.varIndexToUpdateByConjunct = varIndexToUpdateByConjunct;
    }

    public static OdometerAssignmentIterationPlan create(
            List variables,
            SetMultimap valuesByVariable,
            Map varIndexToUpdateByConjunct) {
        return new OdometerAssignmentIterationPlan(ImmutableList.copyOf(variables),
                ImmutableListMultimap.copyOf(valuesByVariable),
                ImmutableMap.copyOf(varIndexToUpdateByConjunct));
    }

    public static NewAssignmentIterationPlan create(GdlRule rule, SentenceDomainModel domainModel) {
        List variables = GdlUtils.getVariables(rule);
        if (variables.isEmpty()) {
            return SingletonAssignmentIterationPlan.create();
        }
        //		System.out.println("variables: " + variables);
        Map varsIndex = AlloyUtils.getListIndex(variables);
        Preconditions.checkState(variables.size() == Sets.newHashSet(variables).size());
        SetMultimap valuesByVariable = HashMultimap.create();
        Map varIndexToUpdateByConjunct = Maps.newHashMap();
        for (GdlLiteral literal : rule.getBody()) {
            //			System.out.println("literal: " + literal);
            if (literal instanceof GdlSentence) {
                //Collect the variables in the positive conjunct's domain
                GdlSentence sentence = (GdlSentence) literal;
                SentenceForm form = domainModel.getSentenceForm(sentence);
                SentenceFormDomain domain = domainModel.getDomain(form);
                List tuple = GdlUtils.getTupleFromSentence(sentence);

                for (int i = 0; i < tuple.size(); i++) {
                    GdlTerm term = tuple.get(i);
                    if (term instanceof GdlVariable) {
                        GdlVariable var = (GdlVariable) term;
                        Set possibleValues = domain.getDomainForSlot(i);
                        valuesByVariable.putAll(var, possibleValues);
                    }
                }
            }
            List varsInLiteral = GdlUtils.getVariables(literal);
            if (!varsInLiteral.isEmpty()) {
                ImmutableSortedSet varIndices = varsInLiteral.stream()
                        .map(varsIndex::get)
                        .collect(Immutables.collectSortedSet());
                //Choice of first is based on Odometer class's behavior
                varIndexToUpdateByConjunct.put(literal, varIndices.first());
            }
        }
        return create(variables, valuesByVariable, varIndexToUpdateByConjunct);
    }

    @Override
    public NewAssignmentIterator getIterator() {
        return new OdometerAssignmentIterator();
    }

    private class OdometerAssignmentIterator implements NewAssignmentIterator {
        private final Odometer odometer;

        public OdometerAssignmentIterator() {
            List> values = Lists.newArrayListWithCapacity(variables.size());
            for (GdlVariable var : variables) {
                values.add(valuesByVariable.get(var));
            }
            odometer = Odometer.create(values);
        }

        @Override
        public boolean hasNext() {
            return odometer.hasNext();
        }

        @Override
        public Map next() {
            List list = odometer.next();
            return toMap(list);
        }

        private Map toMap(List list) {
            Map map = Maps.newHashMapWithExpectedSize(list.size());
            for (int i = 0; i < variables.size(); i++) {
                map.put(variables.get(i), list.get(i));
            }
            return map;
        }

        @Override
        public void skipForward(Set unsatisfiableLiterals,
                Map assignment) {
            for (GdlLiteral literal : unsatisfiableLiterals) {
                int varIndexToUpdate = varIndexToUpdateByConjunct.get(literal);
                if (varIndexToUpdate > 0) {
                    GdlVariable var = variables.get(varIndexToUpdate);
                    GdlConstant value = assignment.get(var);
                    //					System.out.println("Variable ordering: " + variables);
                    //					System.out.println("Assignment was " + assignment);
                    //					System.out.println("Skipping forward in variable " + var + " because of conjunct " + literal);
                    odometer.skipPastValueInSlot(varIndexToUpdate, value);
                }
            }
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy