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

cdc.applic.projections.Shadow Maven / Gradle / Ivy

There is a newer version: 0.13.3
Show newest version
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(); } }