package Tree;
import DPJRuntime.*;
class RecursiveTreeBuild {
static class Body {
final double mass, pos;
Body(double m, double p) { this.mass = m; this.pos = p; }
}
static abstract class Node<region R> { Body centerOfMass in R; }
static class InnerNode<region R> extends Node<R> {
final double leftBound, rightBound;
region LeftRgn, RightRgn;
Node<R:LeftRgn> leftChild in R:LeftRgn;
Node<R:RightRgn> rightChild in R:RightRgn;
InnerNode(double lb, double rb) pure { leftBound = lb; rightBound = rb; }
}
static class LeafNode<region R> extends Node<R> {
LeafNode(Body b) pure { centerOfMass = b; }
}
private static <region R>
int computeSplitPoint(ArraySlice<Body,R> arr,
double midpoint)
reads R
{
int result = 0;
// Set result to the first index position in arr whose
// position is to the right of midpoint
return result;
}
public static <region RN,RA | RN:* # RA:*>
Node<RN>makeTree(ArraySlice<Body,RA:*> arr, double leftBound,
double rightBound)
reads RA:* writes RN:*
{
if (arr.length == 0) return null;
if (arr.length == 1) return new LeafNode<RN>(arr.get(0));
double midpoint = (leftBound + rightBound) / 2;
int splitPoint = computeSplitPoint(arr, midpoint);
Partition<Body,RA:*> segs = new Partition<Body,RA:*>(arr, splitPoint);
InnerNode<RN> node = new InnerNode<RN>(leftBound, rightBound);
cobegin {
node.leftChild = RecursiveTreeBuild.<region RN:InnerNode.LeftRgn,RA>
makeTree(segs.get(0), leftBound, midpoint);
node.rightChild = RecursiveTreeBuild.<region RN:InnerNode.RightRgn,RA>
makeTree(segs.get(1), midpoint, rightBound);
}
return node;
}
}