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

org.ggp.base.util.gdl.transforms.DeORer Maven / Gradle / Ivy

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

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

import org.ggp.base.util.gdl.grammar.Gdl;
import org.ggp.base.util.gdl.grammar.GdlConstant;
import org.ggp.base.util.gdl.grammar.GdlDistinct;
import org.ggp.base.util.gdl.grammar.GdlFunction;
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.GdlPool;
import org.ggp.base.util.gdl.grammar.GdlProposition;
import org.ggp.base.util.gdl.grammar.GdlRelation;
import org.ggp.base.util.gdl.grammar.GdlRule;
import org.ggp.base.util.gdl.grammar.GdlVariable;


/**
 * As a GDL transformer, this class takes in a GDL description of a game,
 * transforms it in some way, and outputs a new GDL descriptions of a game
 * which is functionally equivalent to the original game.
 *
 * DeORer removes OR rules from the GDL. Technically, these rules shouldn't
 * be in the GDL in the first place, but it's very straightforward to remove
 * them, so we do that so that we can handle GDL descriptions that use OR.
 *
 * @author Ethan Dreyfuss
 */
public class DeORer {
    public static List run(List description)
    {
        List newDesc = new ArrayList();
        for(Gdl gdl : description)
        {
            if(gdl instanceof GdlRule)
            {
                GdlRule rule = (GdlRule)gdl;
                List> newBodies = deOr(rule.getBody());
                for(List body : newBodies)
                {
                    newDesc.add(GdlPool.getRule(rule.getHead(), body));
                }
            }
            else
                newDesc.add(gdl);
        }
        return newDesc;
    }

    private static List> deOr(List rhs) {
        List> wrapped = new ArrayList>();
        wrapped.add(rhs);
        return deOr2(wrapped);
    }

    private static List> deOr2(List> rhsList) {
        List> rval = new ArrayList>();
        boolean expandedSomething = false;
        for(List rhs : rhsList)
        {
            int i=0;
            if(!expandedSomething)
            {
                for(GdlLiteral lit : rhs)
                {
                    if(!expandedSomething)
                    {
                        List expandedList = expandFirstOr(lit);

                        if(expandedList.size() > 1)
                        {
                            for(Gdl replacement : expandedList)
                            {
                                List newRhs = new ArrayList(rhs);
                                if(!(replacement instanceof GdlLiteral)) throw new RuntimeException("Top level return value is different type of gdl.");
                                GdlLiteral newLit = (GdlLiteral)replacement;
                                newRhs.set(i, newLit);
                                rval.add(newRhs);
                            }
                            expandedSomething = true;
                            break;
                        }
                    }

                    i++;
                }
                if(!expandedSomething) //If I didn't find anything to expand
                    rval.add(rhs);
            }
            else
                rval.add(rhs); //If I've already expanded this function call

        }

        if(!expandedSomething)
            return rhsList;
        else
            return deOr2(rval);
    }

    private static List expandFirstOr(Gdl gdl) {
        List rval;
        List expandedChild;
        if(gdl instanceof GdlDistinct)
        {
            //Can safely be ignored, won't contain 'or'
            rval = new ArrayList();
            rval.add(gdl);
            return rval;
        }
        else if(gdl instanceof GdlNot)
        {
            GdlNot not = (GdlNot)gdl;
            expandedChild = expandFirstOr(not.getBody());
            rval = new ArrayList();
            for(Gdl g : expandedChild)
            {
                if(!(g instanceof GdlLiteral)) throw new RuntimeException("Not must have literal child.");
                GdlLiteral lit = (GdlLiteral)g;
                rval.add(GdlPool.getNot(lit));
            }
            return rval;
        }
        else if(gdl instanceof GdlOr)
        {
            GdlOr or = (GdlOr)gdl;
            rval = new ArrayList();
            for(int i=0; i();
            rval.add(gdl);
            return rval;
        }
        else if(gdl instanceof GdlRelation)
        {
            //Can safely be ignored, won't contain 'or'
            rval = new ArrayList();
            rval.add(gdl);
            return rval;
        }
        else if(gdl instanceof GdlRule)
        {
            throw new RuntimeException("This should be used to remove 'or's from the body of a rule, and rules can't be nested");
        }
        else if(gdl instanceof GdlConstant)
        {
            //Can safely be ignored, won't contain 'or'
            rval = new ArrayList();
            rval.add(gdl);
            return rval;
        }
        else if(gdl instanceof GdlFunction)
        {
            //Can safely be ignored, won't contain 'or'
            rval = new ArrayList();
            rval.add(gdl);
            return rval;
        }
        else if(gdl instanceof GdlVariable)
        {
            //Can safely be ignored, won't contain 'or'
            rval = new ArrayList();
            rval.add(gdl);
            return rval;
        }
        else
        {
            throw new RuntimeException("Uh oh, gdl hierarchy must have been extended without updating this code.");
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy