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

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

There is a newer version: 17.6.0
Show newest version
module protelis:coord:tree
import protelis:coord:accumulation
import protelis:coord:spreading
import protelis:lang:utils
/*
 * Building a spanning tree equals to find the parent of device. Using this
 * library, parent information is based on an information pair (treated as a
 * Tuple): [parent device, additional information]. Finding the parent device
 * is based on protelis:coord:accumulation.getParentExtended. The first element
 * of the tuple is then a number (in case of error) or the parent's execution
 * context. The second field has been added for the sake of generality. It is
 * intended as any information of interest related to the parent.
 * @see protelis:coord:accumulation.getParentExtended
 */

/**
 * Build a spanning tree.
 *
 * @param potential num,  potential to be followed
 * @return          [num|ExecutionContext, num|ExecutionContext], parent
 * @see             protelis:coord:accumulation.getParentExtended
 */
public def spanningTree(potential) {
    spanningTreeExtended(potential, identity, self)
}

/**
 * Build a spanning tree.
 *
 * @param potential num, potential to be followed
 * @param function  (T) -> T', function to be applied to the parent value
 * @param init      T', initial value of the device
 * @return          [num|ExecutionContext, T']
 * @see protelis:coord:accumulation.getParentExtended,
 *      protelis:coord:accumulation.imRoot,
 *      protelis:coord:accumulation.noParent
 */
public def spanningTreeExtended(potential, function, init) {
    rep (parent <- [imRoot(), init]) {
        getParentExtended(
            potential,
            identity,
            (value) -> { function.apply(value) },
            parent.get(1)
        )
    }
}

/**
 * Assuming to have a spanning tree, apply f where condition holds,
 * g otherwise.
 *
 * @param tree      () -> T, tree
 * @param condition bool, condition
 * @param f         (T) -> T', what to do if condition is true
 * @param g         (T) -> T', what to do if condition is false
 * @return          T', apply f where condition holds, g otherwise
 */
public def applyOnTree(tree, condition, f, g) {
    let parent = tree.apply();
    mux (condition) {
        f.apply(parent)
    } else {
        g.apply(parent)
    }
}

/**
 * Assuming to have a spanning tree, apply f to the children of the first
 * device where condition holds, g otherwise.
 *
 * @param potential num, potential
 * @param filter    (bool) -> bool, whether to execute f or g according to the parent condition
 * @param f         ([ExecutionContext, bool]) -> T', what to do if condition is true
 * @param g         ([ExecutionContext, bool]) -> T', what to do if condition is false
 * @return          T', apply f where condition holds, g otherwise
 */
public def descendBranch(potential, filter, f, g) {
    descendBranchWithNull(potential, 0, filter, f, g)
}

/**
 * Assuming to have a spanning tree, apply f to the children of the first
 * device where condition holds, g otherwise.
 *
 * @param potential num, potential
 * @param null      num, null potential value
 * @param filter    (bool) -> bool, whether to execute f or g according to the parent condition
 * @param f         ([ExecutionContext, bool]) -> T', what to do if condition is true
 * @param g         ([ExecutionContext, bool]) -> T', what to do if condition is false
 * @return          T', apply f where condition holds, g otherwise
 */
public def descendBranchWithNull(potential, null, filter, f, g) {
    let c = directProjectionWithMetric(
        potential == null,
        filter.apply(),
        () -> { potential }
    );
    mux (c) {
        f.apply([getParent(potential, identity), c])
    } else {
        g.apply([getParent(potential, identity), c])
    }
}

/**
 * Assuming to have a spanning tree, apply f to the father of any of the
 * devices where condition holds, g otherwise.
 *
 * @param potential num, potential
 * @param filter    (bool) -> bool, whether to execute f or g according to the parent condition
 * @param f         ([ExecutionContext, bool]) -> T', what to do if condition is true
 * @param g         ([ExecutionContext, bool]) -> T', what to do if condition is false
 * @return          T', apply f where condition holds, g otherwise
 */
public def ascendBranch(potential, filter, f, g) {
    if (C(potential, or, filter.apply(), filter.apply())) {
        f.apply(getChildren(potential, identity, filter, false))
    } else {
        g.apply()
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy