it.cnr.istc.core.Core.java Source code

Java tutorial

Introduction

Here is the source code for it.cnr.istc.core.Core.java

Source

/*
 * Copyright (C) 2016 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.core;

import it.cnr.istc.ac.ArithExpr;
import it.cnr.istc.ac.BoolExpr;
import it.cnr.istc.ac.Network;
import it.cnr.istc.core.parser.oRatioLexer;
import it.cnr.istc.core.parser.oRatioParser;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.antlr.v4.runtime.ANTLRFileStream;
import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.ParseTreeWalker;

/**
 *
 * @author Riccardo De Benedictis <riccardo.debenedictis@istc.cnr.it>
 */
public abstract class Core extends Network implements IScope, IEnv {

    public static final String BOOL = "bool";
    public static final String REAL = "real";
    public static final String STRING = "string";
    final Map<ParseTree, IScope> scopes = new IdentityHashMap<>();
    oRatioParser parser;
    protected final Map<String, Field> fields = new LinkedHashMap<>();
    protected final Map<String, Collection<Method>> methods = new LinkedHashMap<>();
    protected final Map<String, Predicate> predicates = new LinkedHashMap<>();
    protected final Map<String, Type> types = new LinkedHashMap<>();
    protected final Map<String, IItem> items = new LinkedHashMap<>();
    protected BoolExpr ctr_var = newBool(true);

    public Core() {
        types.put(BOOL, new BoolType(this));
        types.put(REAL, new RealType(this));
        types.put(STRING, new StringType(this));
    }

    public boolean read(String script) {
        parser = new oRatioParser(new CommonTokenStream(new oRatioLexer(new ANTLRInputStream(script))));
        oRatioParser.Compilation_unitContext cu = parser.compilation_unit();
        ParseTreeWalker.DEFAULT.walk(new TypeDeclarationListener(this), cu);
        ParseTreeWalker.DEFAULT.walk(new TypeRefinementListener(this), cu);
        if (!new StatementVisitor(this, this).visit(cu)) {
            return false;
        }
        parser = null;
        return true;
    }

    public boolean read(File... files) throws IOException {
        List<File> fs = new ArrayList<>(files.length);
        for (File file : files) {
            fs.addAll(Files.walk(Paths.get(file.toURI())).filter(Files::isRegularFile).map(path -> path.toFile())
                    .collect(Collectors.toList()));
        }
        Collection<CodeSnippet> snippets = new ArrayList<>(fs.size());
        for (File f : fs) {
            oRatioParser c_parser = new oRatioParser(
                    new CommonTokenStream(new oRatioLexer(new ANTLRFileStream(f.getPath()))));
            oRatioParser.Compilation_unitContext context = c_parser.compilation_unit();
            snippets.add(new CodeSnippet(f, c_parser, context));
        }
        for (CodeSnippet snippet : snippets) {
            parser = snippet.parser;
            ParseTreeWalker.DEFAULT.walk(new TypeDeclarationListener(this), snippet.context);
            ParseTreeWalker.DEFAULT.walk(new TypeRefinementListener(this), snippet.context);
            if (!new StatementVisitor(this, this).visit(snippet.context)) {
                return false;
            }
            parser = null;
        }
        return true;
    }

    /**
     * Solves the current problem returning {@code true} if a solution has been
     * found and {@code false} if the problem is unsolvable.
     *
     * @return {@code true} if a solution has been found or {@code false} if the
     * problem is unsolvable.
     */
    public abstract boolean solve();

    public IBoolItem newBoolItem() {
        return new BoolItem(this, types.get(BOOL), newBool());
    }

    public IBoolItem newBoolItem(boolean val) {
        return new BoolItem(this, types.get(BOOL), newBool(val));
    }

    public IArithItem newRealItem() {
        return new ArithItem(this, types.get(REAL), newReal());
    }

    public IArithItem newRealItem(double val) {
        return new ArithItem(this, types.get(REAL), newReal(val));
    }

    public IEnumItem newEnumItem(IItem value) {
        return new EnumItem(this, value.getType(), newEnum(value));
    }

    public IEnumItem newEnumItem(Type type, IItem... values) {
        assert values.length > 1;
        assert Stream.of(values).allMatch(item -> type.isAssignableFrom(item.getType()));
        switch (type.name) {
        case BOOL:
            return new BoolEnum(this, types.get(BOOL), newBool(),
                    newEnum(Arrays.copyOf(values, values.length, IBoolItem[].class)));
        case REAL:
            return new ArithEnum(this, types.get(REAL), newReal(),
                    newEnum(Arrays.copyOf(values, values.length, IArithItem[].class)));
        default:
            return new EnumItem(this, type, newEnum(values));
        }
    }

    public IStringItem newStringItem() {
        return new StringItem(this, types.get(REAL), "");
    }

    public IStringItem newStringItem(String val) {
        return new StringItem(this, types.get(REAL), val);
    }

    protected boolean newFact(Atom atom) {
        if (atom.type.scope instanceof Type) {
            if (!((Type) atom.type.scope).factCreated(atom)) {
                return false;
            }
        }
        return true;
    }

    protected boolean activateFact(Atom atom) {
        if (atom.type.scope instanceof Type) {
            if (!((Type) atom.type.scope).factActivated(atom)) {
                return false;
            }
        }
        return true;
    }

    protected boolean unifyFact(Atom unifying, Atom with) {
        assert unifying.type == with.type;
        if (unifying.type.scope instanceof Type) {
            if (!((Type) unifying.type.scope).factUnified(unifying, with)) {
                return false;
            }
        }
        return true;
    }

    protected boolean newGoal(Atom atom) {
        if (atom.type.scope instanceof Type) {
            if (!((Type) atom.type.scope).goalCreated(atom)) {
                return false;
            }
        }
        return true;
    }

    protected boolean activateGoal(Atom atom) {
        if (atom.type.scope instanceof Type) {
            if (!((Type) atom.type.scope).goalActivated(atom)) {
                return false;
            }
        }
        return true;
    }

    protected boolean unifyGoal(Atom unifying, Atom with) {
        assert unifying.type == with.type;
        if (unifying.type.scope instanceof Type) {
            if (!((Type) unifying.type.scope).goalUnified(unifying, with)) {
                return false;
            }
        }
        return true;
    }

    public boolean newDisjunction(IEnv env, Disjunction d) {
        return true;
    }

    public IBoolItem not(IBoolItem var) {
        return new BoolItem(this, types.get(BOOL), not(var.getBoolVar()));
    }

    public IBoolItem and(IBoolItem... vars) {
        return new BoolItem(this, types.get(BOOL),
                and(Stream.of(vars).map(var -> var.getBoolVar()).toArray(BoolExpr[]::new)));
    }

    public IBoolItem or(IBoolItem... vars) {
        return new BoolItem(this, types.get(BOOL),
                or(Stream.of(vars).map(var -> var.getBoolVar()).toArray(BoolExpr[]::new)));
    }

    public IBoolItem exct_one(IBoolItem... vars) {
        return new BoolItem(this, types.get(BOOL),
                exct_one(Stream.of(vars).map(var -> var.getBoolVar()).toArray(BoolExpr[]::new)));
    }

    public IBoolItem imply(IBoolItem left, IBoolItem right) {
        return new BoolItem(this, types.get(BOOL), imply(left.getBoolVar(), right.getBoolVar()));
    }

    public IArithItem minus(IArithItem var) {
        return new ArithItem(this, types.get(REAL), minus(var.getArithVar()));
    }

    public IArithItem sum(IArithItem... vars) {
        return new ArithItem(this, types.get(REAL),
                sum(Stream.of(vars).map(var -> var.getArithVar()).toArray(ArithExpr[]::new)));
    }

    public IArithItem sub(IArithItem... vars) {
        return new ArithItem(this, types.get(REAL),
                sub(Stream.of(vars).map(var -> var.getArithVar()).toArray(ArithExpr[]::new)));
    }

    public IArithItem mult(IArithItem... vars) {
        return new ArithItem(this, types.get(REAL),
                mult(Stream.of(vars).map(var -> var.getArithVar()).toArray(ArithExpr[]::new)));
    }

    public IArithItem div(IArithItem left, IArithItem right) {
        return new ArithItem(this, types.get(REAL), div(left.getArithVar(), right.getArithVar()));
    }

    public IBoolItem leq(IArithItem left, IArithItem right) {
        return new BoolItem(this, types.get(BOOL), leq(left.getArithVar(), right.getArithVar()));
    }

    public IBoolItem geq(IArithItem left, IArithItem right) {
        return new BoolItem(this, types.get(BOOL), geq(left.getArithVar(), right.getArithVar()));
    }

    public IBoolItem eq(IItem left, IItem right) {
        return new BoolItem(this, types.get(BOOL), left.eq(right));
    }

    public boolean add(IBoolItem... vars) {
        BoolExpr[] exprs = Stream.of(vars).map(var -> imply(ctr_var, var.getBoolVar())).toArray(BoolExpr[]::new);
        if (exprs.length == 0) {
            // there is nothing to add..
            return true;
        } else {
            return add(exprs);
        }
    }

    @Override
    public Core getCore() {
        return this;
    }

    @Override
    public IScope getScope() {
        return null;
    }

    @Override
    public Field getField(String name) {
        return fields.get(name);
    }

    @Override
    public Collection<Field> getFields() {
        return Collections.unmodifiableCollection(fields.values());
    }

    @Override
    public Method getMethod(String name, Type... parameterTypes) {
        boolean isCorrect;
        if (methods.containsKey(name)) {
            for (Method m : methods.get(name)) {
                if (m.parameters.length == parameterTypes.length) {
                    isCorrect = true;
                    for (int i = 0; i < m.parameters.length; i++) {
                        if (!m.parameters[i].type.isAssignableFrom(parameterTypes[i])) {
                            isCorrect = false;
                            break;
                        }
                    }
                    if (isCorrect) {
                        return m;
                    }
                }
            }
        }

        // not found
        return null;
    }

    @Override
    public Collection<Method> getMethods() {
        Collection<Method> c_methods = new ArrayList<>();
        for (Collection<Method> ms : methods.values()) {
            c_methods.addAll(ms);
        }
        return Collections.unmodifiableCollection(c_methods);
    }

    @Override
    public Predicate getPredicate(String name) {
        return predicates.get(name);
    }

    @Override
    public Collection<Predicate> getPredicates() {
        return Collections.unmodifiableCollection(predicates.values());
    }

    @Override
    public Type getType(String name) {
        return types.get(name);
    }

    @Override
    public Collection<Type> getTypes() {
        return Collections.unmodifiableCollection(types.values());
    }

    @Override
    public IEnv getEnv() {
        return null;
    }

    @Override
    public <T extends IItem> T get(String name) {
        return (T) items.get(name);
    }

    private static class CodeSnippet {

        private final File file;
        private final oRatioParser parser;
        private final oRatioParser.Compilation_unitContext context;

        CodeSnippet(File file, oRatioParser parser, oRatioParser.Compilation_unitContext context) {
            this.file = file;
            this.parser = parser;
            this.context = context;
        }
    }

    private static class BoolType extends Type {

        BoolType(Core c) {
            super(c, c, BOOL, true);
        }

        @Override
        public IItem newInstance(IEnv env) {
            return core.newBoolItem();
        }
    }

    private static class RealType extends Type {

        RealType(Core c) {
            super(c, c, REAL, true);
        }

        @Override
        public IItem newInstance(IEnv env) {
            return core.newRealItem();
        }
    }

    private static class StringType extends Type {

        StringType(Core c) {
            super(c, c, STRING, true);
        }

        @Override
        public IItem newInstance(IEnv env) {
            return core.newStringItem();
        }
    }
}