protelis.coord.tree.pt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of protelis-lang Show documentation
Show all versions of protelis-lang Show documentation
Essential libraries for the Protelis language
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()
}
}