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

org.ggp.base.util.gdl.model.SentenceDomainModels Maven / Gradle / Ivy

The newest version!
package org.ggp.base.util.gdl.model;

import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
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.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 com.google.common.base.Function;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;

public class SentenceDomainModels {
    public static enum VarDomainOpts {
        INCLUDE_HEAD,
        BODY_ONLY
    }

    public static Map> getVarDomains(
            GdlRule rule,
            SentenceDomainModel domainModel,
            VarDomainOpts includeHead) {
        // For each positive definition of sentences in the rule, intersect their
        // domains everywhere the variables show up
        Multimap> varDomainsByVar = ArrayListMultimap.create();
        for (GdlLiteral literal : getSentences(rule, includeHead)) {
            if (literal instanceof GdlSentence) {
                GdlSentence sentence = (GdlSentence) literal;
                SentenceForm form = SimpleSentenceForm.create(sentence);
                SentenceFormDomain formWithDomain = 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 domain = formWithDomain.getDomainForSlot(i);
                        varDomainsByVar.put(var, domain);
                    }
                }
            }
        }

        Map> varDomainByVar = combineDomains(varDomainsByVar);
        return varDomainByVar;
    }

    public static Iterable getSentences(GdlRule rule, VarDomainOpts includeHead) {
        if (includeHead == VarDomainOpts.INCLUDE_HEAD) {
            return Iterables.concat(ImmutableList.of(rule.getHead()), rule.getBody());
        } else {
            return rule.getBody();
        }
    }

    private static Map> combineDomains(
            Multimap> varDomainsByVar) {
        return ImmutableMap.copyOf(Maps.transformValues(varDomainsByVar.asMap(),
                new Function>, Set>() {
            @Override
            public Set apply(Collection> input) {
                return intersectSets(input);
            }
        }));
    }

    private static  Set intersectSets(
            Collection> input) {
        if (input.isEmpty()) {
            throw new IllegalArgumentException("Can't take an intersection of no sets");
        }
        Set result = null;
        for (Set set : input) {
            if (result == null) {
                result = Sets.newHashSet(set);
            } else {
                result.retainAll(set);
            }
        }
        assert result != null;
        return result;
    }

    public static Set> getSubdomains(SentenceDomainModel model) {
        // Splits the constants used in tuples in the game's sentences into groups, based on where
        // they could show up with one another.
        Set> subdomains = Sets.newHashSet();
        for (SentenceForm form : model.getSentenceForms()) {
            SentenceFormDomain domain = model.getDomain(form);
            for (int i = 0; i < form.getTupleSize(); i++) {
                subdomains.add(Sets.newHashSet(domain.getDomainForSlot(i)));
            }
        }

        return mergeOverlappingSubdomains(subdomains);
    }

    private static Set> mergeOverlappingSubdomains(
            Set> subdomains) {
        Set> mergedSubdomains = Sets.newHashSet();
        while (!subdomains.isEmpty()) {
            Iterator> domainItr = subdomains.iterator();
            Set curDomain = Sets.newHashSet(domainItr.next());
            domainItr.remove();
            boolean somethingChanged = true;
            while (somethingChanged) {
                somethingChanged = false;

                //Merge in any remaining domains that overlap with the current domain
                domainItr = subdomains.iterator();
                while (domainItr.hasNext()) {
                    Set domainToCheck = domainItr.next();
                    if (overlap(domainToCheck, curDomain)) {
                        curDomain.addAll(domainToCheck);
                        domainItr.remove();
                        somethingChanged = true;
                    }
                }
            }
            mergedSubdomains.add(curDomain);
        }
        return mergedSubdomains;
    }

    private static  boolean overlap(Set set1,
            Set set2) {
        if (set1.size() < set2.size()) {
            return !Sets.intersection(set1, set2).isEmpty();
        } else {
            return !Sets.intersection(set2, set1).isEmpty();
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy