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

main.io.github.moonlightsuite.moonlight.online.algorithms.BooleanOp Maven / Gradle / Ivy

Go to download

MoonLight is a light-weight Java-tool for monitoring temporal, spatial and spatio-temporal properties of distributed complex systems, such as Cyber-Physical Systems and Collective Adaptive Systems.

The newest version!
package io.github.moonlightsuite.moonlight.online.algorithms;

import io.github.moonlightsuite.moonlight.core.signal.Sample;
import io.github.moonlightsuite.moonlight.online.signal.*;

import java.util.*;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.UnaryOperator;
import java.util.stream.Collectors;

/**
 *
 */
public class BooleanOp {
    private BooleanOp() {}     // hidden constructor

    /**
     *
     * @param u update of the input signal
     * @param op  operation to be performed
     * @param  Time domain, usually expressed as a {@link Number}
     * @param  Input signal domain
     * @param  Output robustness domain
     * @return an update of the robustness signal in input
     */
    public static
    , V, R>
    Update atom(Update u, Function op)
    {
        return new Update<>(u.getStart(), u.getEnd(),
                                           op.apply(u.getValue()));
    }

    /**
     *
     * @param us update of the input signal
     * @param op  operation to be performed
     * @param  Time domain, usually expressed as a {@link Number}
     * @param  Input signal domain
     * @param  Output robustness domain
     * @return an update of the robustness signal in input
     */
    public static
    ,
            V,
            R>
    TimeChain atomSequence(TimeChain us, Function op)
    {
        List> ls =
            us.stream()
              .map(s -> new TimeSegment<>(s.getStart(), op.apply(s.getValue())))
              .collect(Collectors.toList());

        return new TimeChain<>(ls, us.getEnd());
    }

    public static
    , V, R>
    TimeChain atomSequence(Update u, Function op)
    {
        List> ups = new ArrayList<>();
        ups.add(atom(u, op));
        return Update.asTimeChain(ups);
    }

    /**
     *
     * @param u update of the operand
     * @param op  operation to be performed
     * @param  Time domain, usually expressed as a {@link Number}
     * @param  Output robustness domain
     * @return an update of the robustness signal in input
     */
    public static
    , R>
    List> unary(Update u, UnaryOperator op)
    {
        Update result = new Update<>(u.getStart(), u.getEnd(),
                op.apply(u.getValue()));
        List> results = new ArrayList<>();
        results.add(result);

        return results;
    }

    /**
     *
     * @param us chain of updates of the operand
     * @param op  operation to be performed
     * @param  Time domain, usually expressed as a {@link Number}
     * @param  Output robustness domain
     * @return an update of the robustness signal in input
     */
    public static
    , R>
    TimeChain unarySequence(TimeChain us, UnaryOperator op)
    {
        List> ls =
            us.stream()
              .map(s -> new TimeSegment<>(s.getStart(), op.apply(s.getValue())))
              .collect(Collectors.toList());

        return new TimeChain<>(ls, us.getEnd());
    }

    /**
     * TODO: this should be different for left and right operands
     * @param c1 input signal of first argument
     * @param us updates of second argument
     * @param op operation to be performed (e.g. and/or)
     * @param  time domain of the signals
     * @param  evaluation domain of the semantics
     * @return a chain of sequential updates
     */
    public static
    , R>
    TimeChain binarySequence(TimeChain c1,
                                   TimeChain us,
                                   BinaryOperator op)
    {
        List> updates = new ArrayList<>(us.size());
        ChainsCombinator itr = new ChainsCombinator<>(c1, us);
        itr.forEach((segment, update) -> binaryOp(segment, update, updates, op));
        return new TimeChain<>(updates, us.getEnd());
    }


    public static
    , R>
    List> binary(TimeChain c1,
                              Update u,
                              BinaryOperator op)
    {
        List> updates;
        updates = rightApply(c1, op, u);  // TODO: this should be different for
                                           //       left and right operands
        return updates;
    }

    private static
    , R>
    List> rightApply(TimeChain s,
                    BinaryOperator op, Update u)
    {
        List> updates = new ArrayList<>();
        ChainIterator> itr = s.chainIterator();
        Sample curr;
        T nextTime;

        while(itr.hasNext()) {
            curr = itr.next();
            nextTime = tryPeekNextStart(itr, s.getEnd());
            exec(curr, u, nextTime, op, updates);
        }

        return updates;
    }

    private static , R>
    void exec(Sample curr, Update u, T nextTime,
              BinaryOperator op, List> updates)
    {
        if(curr.getStart().compareTo(u.getEnd()) < 0
                && nextTime.compareTo(u.getStart()) >= 0)
        {
            T end = min(nextTime, u.getEnd());
            T start = max(curr.getStart(), u.getStart());
            if(!start.equals(end)) {
                Update r = new Update<>(start, end,
                        op.apply(u.getValue(), curr.getValue()));
                updates.add(r);
            }
        }
    }

    private static , R>
    void binaryOp(Sample left,
                  Sample right,
                  List> output,
                  BinaryOperator op)
    {
        T start = max(left, right).getStart();
        R value = op.apply(right.getValue(), left.getValue());
        Sample r = new TimeSegment<>(start, value);
        int last = output.size() - 1;
        if(output.isEmpty() || !output.get(last).getValue().equals(value))
            output.add(r);
    }

    private static > R max(R a, R b) {
        return a.compareTo(b) >= 0 ? a : b;
    }

    private static > R min(R a, R b) {
        return a.compareTo(b) <= 0 ? a : b;
    }

    /**
     * Fail-safe method for fetching data from next element (if exists).
     *
     * @param itr iterator to use for looking forward
     * @param defaultValue value to return in case of failure
     * @param  time domain of interest, usually a Number
     * @param  domain of the returned value
     * @return the next time value if present, otherwise the default one.
     */
    static , V>
    T tryPeekNextStart(ChainIterator> itr, T defaultValue)
    {
        if(itr.hasNext())
            return itr.peekNext().getStart();
        else
            return defaultValue;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy