cdc.applic.projections.Shadow Maven / Gradle / Ivy
Show all versions of cdc-applic-projections Show documentation
package cdc.applic.projections;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import cdc.applic.dictionaries.types.DomainedType;
import cdc.applic.dictionaries.types.PatternType;
import cdc.applic.expressions.content.SItem;
import cdc.applic.expressions.content.SItemSet;
import cdc.applic.expressions.content.SItemSetUtils;
import cdc.applic.proofs.ProverMatching;
import cdc.util.lang.CollectionUtils;
/**
* A Shadow is a set of {@link ShadowPiece}s. Each piece has one matching.
*
* @author Damien Carbonne
*/
public class Shadow {
@SuppressWarnings("unchecked")
private final Set[] array = new Set[3];
private final Map cuts = new HashMap<>();
/**
* Creates a Shadow from 3 set of {@link ShadowPiece}s.
*
* All pieces must be compliant: they must use the same set of axes.
*
* @param never The pieces with {@link ProverMatching#NEVER} matching.
* @param sometimes The pieces with {@link ProverMatching#SOMETIMES} matching.
* @param always The pieces with {@link ProverMatching#ALWAYS} matching.
*/
public Shadow(Set never,
Set sometimes,
Set always) {
array[ProverMatching.NEVER.ordinal()] = CollectionUtils.seal(never);
array[ProverMatching.SOMETIMES.ordinal()] = CollectionUtils.seal(sometimes);
array[ProverMatching.ALWAYS.ordinal()] = CollectionUtils.seal(always);
fillCuts(never);
fillCuts(sometimes);
fillCuts(always);
}
private void fillCuts(Set pieces) {
if (pieces != null) {
for (final ShadowPiece piece : pieces) {
for (final Axis axis : piece.getAxes()) {
if (cuts.containsKey(axis)) {
cuts.put(axis, cuts.get(axis).union(piece.getAxisSet(axis)));
} else {
cuts.put(axis, piece.getAxisSet(axis));
}
}
}
}
}
public Shadow(ShadowPiece never,
ShadowPiece sometimes,
ShadowPiece always) {
this(toSet(never),
toSet(sometimes),
toSet(always));
}
public Shadow(AxisPiece never,
AxisPiece sometimes,
AxisPiece always) {
this(toShadowPiece(never),
toShadowPiece(sometimes),
toShadowPiece(always));
}
public Shadow(Axis axis,
SItemSet never,
SItemSet sometimes,
SItemSet always) {
this(toAxisPiece(axis, never),
toAxisPiece(axis, sometimes),
toAxisPiece(axis, always));
}
private static ShadowPiece toShadowPiece(AxisPiece axisPiece) {
return axisPiece == null ? null : new ShadowPiece(axisPiece);
}
private static AxisPiece toAxisPiece(Axis axis,
SItemSet set) {
return set == null ? null : new AxisPiece(axis, set);
}
private static Set toSet(ShadowPiece slab) {
if (slab == null) {
return Collections.emptySet();
} else {
final Set set = new HashSet<>();
set.add(slab);
return CollectionUtils.seal(set);
}
}
/**
* Returns a set of ShadowPieces that correspond to a ProverMatching.
*
* @param matching The ProverMatching.
* @return A set of ShadowPieces that correspond to {@code matching}.
*/
public Set getShadowPieces(ProverMatching matching) {
return array[matching.ordinal()];
}
/**
* Returns a set of AxisPieces corresponding to an Axis and a ProverMatching.
*
* @param axis The Axis.
* @param matching The ProverMatching.
* @return A set of AxisPieces corresponding to {@code axis} and {@code matching}.
*/
public Set getAxisPieces(Axis axis,
ProverMatching matching) {
final Set set = new HashSet<>();
for (final ShadowPiece spiece : array[matching.ordinal()]) {
set.add(spiece.getAxisPiece(axis));
}
return set;
}
/**
* Returns the SItemSet corresponding to an Axis.
*
* For a {@link DomainedType}, it is the domain of the type.
* For a {@link PatternType}, it is the set of known values, in the projection context.
*
* @param axis The Axis.
* @return The SItemSet corresponding to {@code axis}.
*/
public SItemSet getAxisSet(Axis axis) {
return cuts.get(axis);
}
/**
* Returns the SItemSet corresponding to an Axis and a ProverMatching.
*
* @param axis The Axis.
* @param matching The ProverMatching.
* @return The SItemSet corresponding to {@code axis} and {@code matching}.
*/
public SItemSet getAxisSet(Axis axis,
ProverMatching matching) {
SItemSet set = SItemSetUtils.getEmptySet(axis.getCheckedSetClass());
for (final ShadowPiece spiece : array[matching.ordinal()]) {
final AxisPiece apiece = spiece.getAxisPiece(axis);
set = set.union(apiece.getSet());
}
return set;
}
/**
* Returns the SItemSet corresponding to an Axis and ProverMatchings.
*
* @param axis The Axis.
* @param matchings The ProverMatchings.
* @return The SItemSet corresponding to {@code axis} and {@code matchings}.
*/
public SItemSet getAxisSet(Axis axis,
ProverMatching... matchings) {
SItemSet set = SItemSetUtils.getEmptySet(axis.getCheckedSetClass());
for (final ProverMatching matching : matchings) {
for (final ShadowPiece spiece : array[matching.ordinal()]) {
final AxisPiece apiece = spiece.getAxisPiece(axis);
set = set.union(apiece.getSet());
}
}
return set;
}
/**
* Returns a set of SItems corresponding to an Axis and a ProverMatching.
*
* @param The SItem type.
* @param sitemClass The SItem class.
* @param axis The Axis.
* @param matching The ProverMatching.
* @return A set of SItems corresponding to {@code axis} and {@code matching}.
* @throws ClassCastException When SItems can not be converted to {@code sitemClass}.
*/
public Set getAxisItems(Class sitemClass,
Axis axis,
ProverMatching matching) {
final Set result = new HashSet<>();
for (final AxisPiece piece : getAxisPieces(axis, matching)) {
for (final SItem item : piece.getSet().getItems()) {
result.add(sitemClass.cast(item));
}
}
return result;
}
@Override
public int hashCode() {
return Arrays.hashCode(array);
}
@Override
public boolean equals(Object object) {
if (this == object) {
return true;
}
if (!(object instanceof Shadow)) {
return false;
}
final Shadow other = (Shadow) object;
return Arrays.equals(array, other.array);
}
@Override
public String toString() {
final StringBuilder builder = new StringBuilder();
boolean first = true;
builder.append('[');
for (final ProverMatching matching : ProverMatching.values()) {
if (first) {
first = false;
} else {
builder.append(' ');
}
builder.append(matching);
builder.append(':');
builder.append(getShadowPieces(matching)); // TODO sort
}
builder.append(']');
return builder.toString();
}
}