it.cnr.istc.iloc.translators.pddl.parser.Parser.java Source code

Java tutorial

Introduction

Here is the source code for it.cnr.istc.iloc.translators.pddl.parser.Parser.java

Source

/*
 * Copyright (C) 2015 Riccardo De Benedictis <riccardo.debenedictis@istc.cnr.it>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package it.cnr.istc.iloc.translators.pddl.parser;

import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.antlr.v4.runtime.BaseErrorListener;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTreeWalker;

/**
 *
 * @author Riccardo De Benedictis <riccardo.debenedictis@istc.cnr.it>
 */
public class Parser {

    private static final ParseTreeWalker WALKER = new ParseTreeWalker();

    public static PDDLInstance parse(File pddl_domain, File pddl_problem) throws IOException {
        // We get the requirements
        Set<String> domain_requirements = PDDLRequirements.getRequirements(pddl_domain);
        Set<String> problem_requirements = PDDLRequirements.getRequirements(pddl_problem);
        problem_requirements.addAll(domain_requirements);

        // we create the domain parser..
        PDDLLexer domain_lexer = new PDDLLexer(new CaseInsensitiveFileStream(pddl_domain.getPath()));
        domain_lexer.requirements.addAll(domain_requirements);
        PDDLParser domain_parser = new PDDLParser(new CommonTokenStream(domain_lexer));
        domain_parser.requirements.addAll(domain_requirements);
        domain_parser.addErrorListener(new BaseErrorListener());

        // we create the problem parser..
        PDDLLexer problem_lexer = new PDDLLexer(new CaseInsensitiveFileStream(pddl_problem.getPath()));
        problem_lexer.requirements.addAll(problem_requirements);
        PDDLParser problem_parser = new PDDLParser(new CommonTokenStream(problem_lexer));
        problem_parser.requirements.addAll(problem_requirements);
        problem_parser.addErrorListener(new BaseErrorListener());

        // We parse the domain..
        PDDLParser.DomainContext domain_context = domain_parser.domain();

        // We parse the problem..
        PDDLParser.ProblemContext problem_context = problem_parser.problem();

        Domain domain = new Domain(Utils.capitalize(domain_context.name().NAME().getSymbol().getText()));
        Problem problem = new Problem(domain,
                Utils.capitalize(problem_context.name(1).NAME().getSymbol().getText()));

        if (domain_context.types_def() != null) {
            /**
             * We define all the types of the domain..
             */
            WALKER.walk(new PDDLBaseListener() {
                @Override
                public void enterTyped_list_name(PDDLParser.Typed_list_nameContext ctx) {
                    ctx.name().stream().forEach(type_name -> {
                        Type type = new Type(Utils.capitalize(type_name.getText()));
                        domain.addType(type);
                    });
                }
            }, domain_context.types_def());

            /**
             * We set the superclasses (i.e., we manage type inheritance)..
             */
            WALKER.walk(new PDDLBaseListener() {
                @Override
                public void enterTyped_list_name(PDDLParser.Typed_list_nameContext ctx) {
                    Type c_superclass = null;
                    if (ctx.type() == null) {
                        c_superclass = Type.OBJECT;
                    } else if (ctx.type().primitive_type().size() == 1) {
                        c_superclass = ctx.type().primitive_type(0).name() == null ? Type.OBJECT
                                : domain.getType(Utils.capitalize(ctx.type().primitive_type(0).name().getText()));
                    } else {
                        throw new AssertionError("multiple inheritance..");
                    }
                    final Type superclass = c_superclass;
                    ctx.name().stream().forEach(type_name -> {
                        Type type = domain.getType(Utils.capitalize(type_name.getText()));
                        type.setSuperclass(superclass);
                        domain.addType(type);
                    });
                }
            }, domain_context.types_def());
        }

        if (domain_context.constants_def() != null) {
            /**
             * We define the constants.
             */
            WALKER.walk(new PDDLBaseListener() {
                @Override
                public void enterTyped_list_name(PDDLParser.Typed_list_nameContext ctx) {
                    Type type = null;
                    if (ctx.type() == null) {
                        type = Type.OBJECT;
                    } else if (ctx.type().primitive_type().size() == 1) {
                        type = ctx.type().primitive_type(0).name() == null ? Type.OBJECT
                                : domain.getType(Utils.capitalize(ctx.type().primitive_type(0).name().getText()));
                    } else {
                        type = new EitherType(ctx.type().primitive_type().stream()
                                .map(primitive_type -> primitive_type.name() == null ? Type.OBJECT
                                        : domain.getType(Utils.capitalize(primitive_type.name().getText())))
                                .collect(Collectors.toList()));
                        if (!domain.getTypes().containsKey(type.getName())) {
                            domain.addType(type);
                        }
                    }

                    assert type != null : "Cannot find type " + ctx.type().primitive_type(0).name().getText();
                    Type c_type = type;
                    ctx.name().stream().forEach(name -> {
                        domain.addConstant(c_type.newInstance(Utils.lowercase(name.getText())));
                    });
                }
            }, domain_context.constants_def());
        }

        if (domain_context.predicates_def() != null) {
            /**
             * We define the predicates.
             */
            WALKER.walk(new PDDLBaseListener() {
                @Override
                public void enterAtomic_formula_skeleton(PDDLParser.Atomic_formula_skeletonContext ctx) {
                    Variable[] variables = new Variable[0];
                    if (ctx.typed_list_variable() != null) {
                        // The predicate formula has parameters
                        TypedListVariableListener typedListVariable = new TypedListVariableListener(domain);
                        WALKER.walk(typedListVariable, ctx.typed_list_variable());
                        variables = typedListVariable.variables
                                .toArray(new Variable[typedListVariable.variables.size()]);
                    }
                    domain.addPredicate(
                            new Predicate(Utils.capitalize(ctx.predicate().name().getText()), variables));
                }
            }, domain_context.predicates_def());
        }

        if (domain_context.functions_def() != null) {
            /**
             * We define the functions.
             */
            WALKER.walk(new PDDLBaseListener() {
                private Type function_type = null;

                @Override
                public void enterFunction_typed_list_atomic_function_skeleton(
                        PDDLParser.Function_typed_list_atomic_function_skeletonContext ctx) {
                    if (ctx.function_type() == null) {
                        function_type = Type.OBJECT;
                    } else if (ctx.function_type().type() == null) {
                        function_type = Type.NUMBER;
                    } else if (ctx.function_type().type().primitive_type().size() == 1) {
                        function_type = ctx.function_type().type().primitive_type(0).name() == null ? Type.OBJECT
                                : domain.getType(Utils
                                        .capitalize(ctx.function_type().type().primitive_type(0).name().getText()));
                    } else {
                        function_type = new EitherType(ctx.function_type().type().primitive_type().stream()
                                .map(primitive_type -> primitive_type.name() == null ? Type.OBJECT
                                        : domain.getType(Utils.capitalize(primitive_type.name().getText())))
                                .collect(Collectors.toList()));
                        domain.addType(function_type);
                    }
                }

                @Override
                public void enterAtomic_function_skeleton(PDDLParser.Atomic_function_skeletonContext ctx) {
                    Variable[] variables = new Variable[0];
                    if (ctx.typed_list_variable() != null) {
                        // The predicate formula has parameters
                        TypedListVariableListener typedListVariable = new TypedListVariableListener(domain);
                        WALKER.walk(typedListVariable, ctx.typed_list_variable());
                        variables = typedListVariable.variables
                                .toArray(new Variable[typedListVariable.variables.size()]);
                    }
                    domain.addFunction(new Function(Utils.capitalize(ctx.function_symbol().name().getText()),
                            function_type, variables));
                }
            }, domain_context.functions_def());
        }

        /**
         * We define the structures.
         */
        domain_context.structure_def().stream().forEach(structure_def -> {
            if (structure_def.action_def() != null) {
                WALKER.walk(new PDDLBaseListener() {
                    @Override
                    public void enterAction_def(PDDLParser.Action_defContext ctx) {
                        Variable[] variables = new Variable[0];
                        if (ctx.typed_list_variable() != null) {
                            // The action has parameters
                            TypedListVariableListener typedListVariable = new TypedListVariableListener(domain);
                            WALKER.walk(typedListVariable, ctx.typed_list_variable());
                            variables = typedListVariable.variables
                                    .toArray(new Variable[typedListVariable.variables.size()]);
                        }
                        Action action = new Action(Utils.capitalize(ctx.action_symbol().name().getText()),
                                variables);

                        TermVisitor term_visitor = new TermVisitor(domain_parser, domain, problem, Stream
                                .of(variables).collect(Collectors.toMap(Variable::getName, variable -> variable)));
                        if (ctx.action_def_body().emptyOr_pre_GD() != null) {
                            action.setPrecondition(term_visitor.visit(ctx.action_def_body().emptyOr_pre_GD()));
                        }
                        if (ctx.action_def_body().emptyOr_effect() != null) {
                            action.setEffect(term_visitor.visit(ctx.action_def_body().emptyOr_effect()));
                        }
                        domain.addAction(action);
                    }
                }, structure_def.action_def());
            } else if (structure_def.durative_action_def() != null) {
                WALKER.walk(new PDDLBaseListener() {
                    @Override
                    public void enterDurative_action_def(PDDLParser.Durative_action_defContext ctx) {
                        Variable[] variables = new Variable[0];
                        if (ctx.typed_list_variable() != null) {
                            // The durative action has parameters
                            TypedListVariableListener typedListVariable = new TypedListVariableListener(domain);
                            WALKER.walk(typedListVariable, ctx.typed_list_variable());
                            variables = typedListVariable.variables
                                    .toArray(new Variable[typedListVariable.variables.size()]);
                        }
                        DurativeAction action = new DurativeAction(
                                Utils.capitalize(ctx.da_symbol().name().getText()), variables);
                        TermVisitor term_visitor = new TermVisitor(domain_parser, domain, problem, Stream
                                .of(variables).collect(Collectors.toMap(Variable::getName, variable -> variable)));
                        if (ctx.da_def_body().duration_constraint() != null) {
                            action.setDuration(term_visitor.visit(ctx.da_def_body().duration_constraint()));
                        }
                        if (ctx.da_def_body().emptyOr_da_GD() != null) {
                            action.setEffect(term_visitor.visit(ctx.da_def_body().emptyOr_da_GD()));
                        }
                        if (ctx.da_def_body().emptyOr_da_effect() != null) {
                            action.setEffect(term_visitor.visit(ctx.da_def_body().emptyOr_da_effect()));
                        }
                        domain.addDurativeAction(action);
                    }
                }, structure_def.durative_action_def());
            }
        });

        /**
         * We define the objects.
         */
        if (problem_context.object_declaration() != null) {
            WALKER.walk(new PDDLBaseListener() {
                @Override
                public void enterTyped_list_name(PDDLParser.Typed_list_nameContext ctx) {
                    Type type = null;
                    if (ctx.type() == null) {
                        type = Type.OBJECT;
                    } else if (ctx.type().primitive_type().size() == 1) {
                        type = ctx.type().primitive_type(0).name() == null ? Type.OBJECT
                                : domain.getType(Utils.capitalize(ctx.type().primitive_type(0).name().getText()));
                    }
                    final Type c_type = type;
                    ctx.name().stream().forEach(object -> {
                        problem.addObject(c_type.newInstance(Utils.lowercase(object.getText())));
                    });
                }
            }, problem_context.object_declaration());
        }

        TermVisitor term_visitor = new TermVisitor(domain_parser, domain, problem, Collections.emptyMap());
        /**
         * We define the initial state
         */
        problem_context.init().init_el().stream().forEach(init_el -> {
            problem.addInitEl(term_visitor.visit(init_el));
        });

        /**
         * We define the goal
         */
        problem.setGoal(term_visitor.visit(problem_context.goal().pre_GD()));

        return new PDDLInstance(domain, problem);
    }

    private Parser() {
    }
}