package models.objectOrientedTransfer;
import java.util.ArrayList;
import java.util.List;
/**
* A dependency-composed closed delta
*
* @author Nitta
*
*/
public class DeltaComplex {
private Delta frontierDelta;
private DeltaComplex subComplex = null;
public DeltaComplex(Delta delta) {
this.frontierDelta = delta;
}
public DeltaComplex(Delta frontierDelta, DeltaComplex subComplex) {
this.frontierDelta = frontierDelta;
this.subComplex = subComplex;
}
/**
* dependency composition
* (this = delta | this)
*
* @param delta
*/
public void attach(Delta delta) {
this.subComplex = this.copy();
this.frontierDelta = delta;
}
/**
* if this = d1 | d2 | ... | dn
* and deltaComplex = c1 | c2 | ... | cm,
* this = c1 | c2 | ... | cm | d1 | d2 | ... | dn
*/
public void mergeFront(DeltaComplex deltaComplex) {
for (Delta delta: deltaComplex.split().reversed()) {
attach(delta);
}
}
/**
* if this = d1 | d2 | ... | dn
*
* @return [d1, d2, ..., dn]
*/
public List<Delta> split() {
if (subComplex == null) {
List<Delta> deltaSequence = new ArrayList<>();
deltaSequence.add(frontierDelta);
return deltaSequence;
}
List<Delta> deltaSequence = subComplex.split();
deltaSequence.add(0, frontierDelta);
return deltaSequence;
}
/**
* if this = (d11 * d12 * ... * d1m1) | (d21 * d22 * ... * d2m2) | ... | (dn1 * dn2 * ... * dnmn)
*
* @return d11 | d12 | ... | d1m1 | d21 | d22 | ... | d2m2 | ... | dn1 | dn2 | ... | dnmn
**/
public DeltaComplex flatten() {
DeltaComplex flattenComplex = subComplex;
if (flattenComplex != null) {
flattenComplex = flattenComplex.flatten();
}
for (PrimitiveDelta primDelta: frontierDelta.split().reversed()) {
flattenComplex = new DeltaComplex(new Delta(primDelta), flattenComplex);
}
return flattenComplex;
}
/**
* if this = d1 | d2 | ... | dn
*
* @return d1 * d2 * ... * dn
*/
public Delta collapse() {
Delta allDelta = null;
for (Delta delta: this.split()) {
if (allDelta == null) {
allDelta = delta;
} else {
allDelta = allDelta.combine(delta);
}
}
return allDelta;
}
public DeltaComplex copy() {
if (subComplex == null) {
return new DeltaComplex(frontierDelta.copy());
}
return new DeltaComplex(frontierDelta.copy(), subComplex.copy());
}
}