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

protelis.coord.meta.pt Maven / Gradle / Ivy

There is a newer version: 17.6.0
Show newest version
module protelis:coord:meta
import protelis:coord:accumulation
import protelis:coord:meta:timereplication
import protelis:coord:sparsechoice
import protelis:coord:spreading
import protelis:lang:utils
import java.lang.Double.POSITIVE_INFINITY

/**
 * Constrain the spreading of f only across a region.
 *
 * @param region bool, whether the function is spreaded or not
 * @param f      () -> T,  function to be spreaded
 * @param null   T, default value where f is not spreaded
 * @return       T, apply f inside the region, null outside
 */
public def boundSpreading(region, f, null) {
    if (region) {
        f.apply()
    } else {
        null
    }
}

/*
 * Gossip active sources.
 * 
 * @param source bool, whether the device is a source
 * @return       [deviceUID], list of sources' ids
 */
public def findSources(source) {
    let k = 5;
    findSourcesWithId(source, getUID(), roundTripTime(diameter(S(POSITIVE_INFINITY, nbrRange))) / (k - 1), k)
}

/*
 * Gossip active sources.
 * 
 * @param source bool, whether the device is a source
 * @param id     T, source identifier
 * @param d      num, network diameter
 * @param k      num, time replicated replicas
 * @return       [T], list of sources' ids
 */
public def findSourcesWithId(source, id, d, k) {
    timeReplicatedWithK(
        () -> {
            share(v, nbrV <- []) {
                v.union(unionHood(nbrV))
                    .union(if (source) { [id] } else { [] })
            }
        }, [id], d, k)
}

/**
 * Run an instance of a function for every source id.
 * 
 * @param sources [T], sources in the system
 * @param f       (T) -> T', function to be applied for every source
 * @param null    T', default value
 * @return        [T'], list of results coming from the executed instances
 */
public def multiInstance(sources, f, null) {
    alignedMap(
        nbr(sources.map(self, id -> {[id, null]})),
        (key, field) -> { sources.contains(key) },
        (key, field) -> { f.apply(key) },
        null
    )
}

/**
 * Splice devices into regions according to the discriminant and apply f.
 *
 * @param discriminant T, split regions according to this value
 * @param filter       (T) -> bool, how to handle the discriminant value
 * @param function     () -> T', what to apply in each region
 * @param default      T', default value
 * @return             T', apply f or default
 */
public def multiRegion(discriminant, filter, function, default) {
    if (filter.apply(discriminant)) {
        let res = alignedMap(
            nbr([[discriminant, default]]),
            (key, field) -> { filter.apply(key) },
            (key, field) -> { function.apply() },
            default
        );
        if (res == []) { default } else { res.get(0).get(1) }
    } else { default }
}

/**
 * Feed f with pre-processed data.
 *
 * @param input G, input
 * @param pre  (G) -> H, how to pre-process
 * @param f    (H) -> I, what to do
 * @return      I, f(pre(input))
 */
public def preProcessAndApply(input, pre, f) {
    f.apply(pre.apply(input))
}

/**
 * Feed f with pre-processed data, and then post-process the output.
 *
 * @param input G, input
 * @param pre  (G) -> H, how to pre-process
 * @param f    (H) -> I, what to do
 * @param post (I) -> T, how to post process
 * @return      T, post(f(pre(input)))
 */
public def processAndApply(input, pre, f, post) {
    post.apply(f.apply(pre.apply(input)))
}

/**
 * Apply f, and then post-process the output.
 *
 * @param input G, input
 * @param f    (H) -> I, what to do
 * @param post (I) -> T, how to post process
 * @return      T, post(f(input))
 */
public def postProcessAndApply(input, f, post) {
    post.apply(f.apply(input))
}

/**
 * Publish/Subscribe pattern.
 * 
 * @param publisher   bool, who publishes
 * @param subscriber  bool, who is subscribing
 * @param information T, what to share
 * @param null        T, what to share if you are neither a subscriber nor a
 *                    publisher
 * @return            T, information if the device is a publisher, a
 *                    subscriber or is in the shortest path between them.
 *                    null otherwise
 */
public def publishSubscribe(publisher, subscriber, information, null) {
    publishSubscribeWithPotential(distanceTo(publisher), subscriber, information, null)
}

/**
 * Publish/Subscribe pattern.
 * 
 * @param potential   num, aggregation direction (publisher are devices whose
 *                    potential is 0)
 * @param subscriber  bool, who is subscribing
 * @param information T, what to share
 * @param null        T, what to share if you are neither a subscriber nor a
 *                    publisher
 * @return            T, information if the device is a publisher, a
 *                    subscriber or is in the shortest path between them.
 *                    null otherwise
 */
public def publishSubscribeWithPotential(potential, subscriber, information, null) {
    if (C(potential, or, subscriber, false)) {
        gradcast(potential == 0, information, potential, identity)
    } else {
        null
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy