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

org.jamesii.ml3.parser.buildIns.setFunctions.ArgMinFunction Maven / Gradle / Ivy

Go to download

The Modeling Language for Linked Lives, a domain specific modeling language for agent-based computational demography.

The newest version!
/*
 * Copyright 2018 University of Rostock
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.jamesii.ml3.parser.buildIns.setFunctions;

import org.jamesii.core.util.misc.Pair;
import org.jamesii.ml3.model.types.BasicType;
import org.jamesii.ml3.model.types.IType;
import org.jamesii.ml3.model.types.SetType;
import org.jamesii.ml3.model.validation.type.Scope;
import org.jamesii.ml3.model.validation.type.Utils;
import org.jamesii.ml3.model.values.INumericalValue;
import org.jamesii.ml3.model.values.IValue;
import org.jamesii.ml3.model.values.SetValue;
import org.jamesii.ml3.parser.buildIns.BuildIns;
import org.jamesii.ml3.parser.nodes.expressions.IExpression;
import org.jamesii.ml3.parser.nodes.expressions.IExpressionVisitor;
import org.jamesii.ml3.simulator.context.IContext;
import org.jamesii.ml3.simulator.exceptions.SimulationException;

import java.util.*;

/**
 * Represents the "argmin : Set(a) x (a -> real) -> a" function,
 * returning the set value where the given expression takes its minimum.
 */
public class ArgMinFunction implements ISetFunction {
    @Override
    public IValue evaluate(IContext context, SetValue set, Collection parameters) {
        Set> evaledSet = new HashSet<>();
        for (IValue v : set.getValue()) {
            /* Push context with a value for "alter". */
            IValue alter = context.getAlter();
            context.setAlter(v);
            /* Evaluate the parameter and put it into the result. */
            IValue result = context.getExpressionEvaluator().evaluateInternally(parameters.iterator().next(),
                    context);
            context.setAlter(alter);
            try {
                evaledSet.add(new Pair<>(v, (INumericalValue) result));
            } catch (ClassCastException ex) {
                throw new SimulationException(
                        "Set function " + BuildIns.SETFUNC_ARGMIN + " called with nonnumerical " +
                                "parameters.");
            }
        }
        Optional> min = evaledSet.stream().min(
                Comparator.comparingDouble(v -> v.getSecondValue().getDouble()));
        if (min.isPresent())
            return min.get().getFirstValue();
        else
            throw new SimulationException("Set function " + BuildIns.SETFUNC_ARGMIN + " called on" +
                    " an empty set.");
    }

    @Override
    @SuppressWarnings("Duplicates")
    public IType getType(IExpressionVisitor visitor, Scope scope, IExpression
            baseSet, Collection parameters) {
        SetType setType = (SetType) SetUtils.evaluateSetExpression(visitor, scope, baseSet);
        if (!Utils.checkParameterSize(scope, parameters, 1, baseSet.getParent())) {
            return BasicType.UNKNOWN;
        }
        IType oldAlter = scope.getAlter();
        scope.setAlter(setType.getElementType());
        IType parameterType = parameters.iterator().next().accept(visitor, scope);
        if (!Utils.checkNumeric(scope, baseSet.getParent(), parameterType)){
            return BasicType.UNKNOWN;
        }
        scope.setAlter(oldAlter);
        return setType.getElementType();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy