// SPDX-FileCopyrightText: 2020 Roberto Posenato // // SPDX-License-Identifier: LGPL-3.0-or-later package it.univr.di.cstnu.graph; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import it.unimi.dsi.fastutil.objects.*; import it.unimi.dsi.fastutil.objects.Object2ObjectMap.Entry; import it.univr.di.Debug; import it.univr.di.labeledvalue.*; import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.io.Serial; import java.util.logging.Level; import java.util.logging.Logger; /** * An implementation of CSTNPSUEdge. *
* This edge differs from the CSTNU edge because it also admits that lower-case values are propagated and that it is possible to have lower-case values with * conjoined lower-case labels. * * @author posenato * @version $Rev$ */ @SuppressFBWarnings(value = "SE_BAD_FIELD", justification = "I know what I'm doing") public class CSTNPSUEdgePluggable extends BasicCSTNUEdgePluggable implements CSTNPSUEdge { @Serial private static final long serialVersionUID = 1L; /* * class initializer */ static { /* * logger */ LOG = Logger.getLogger(CSTNPSUEdgePluggable.class.getName()); } /** * The CSTNU controllability check algorithm needs to know if a labeled value has been already considered in the past in order to avoid to add it a second * time. */ Object2IntMap> consideredLowerCaseValue; /** * Morris Lower case value augmented by a propositional label.
The name of node has to be equal to the original name. No case modifications are * necessary! */ LabeledALabelIntTreeMap lowerCaseValues; /** * Default constructor. Empty edge. */ CSTNPSUEdgePluggable() { this((String) null); } /** * @param n name of edge */ CSTNPSUEdgePluggable(String n) { super(n); lowerCaseValues = new LabeledALabelIntTreeMap(this.getLabeledIntMapImplClass()); consideredLowerCaseValue = new Object2IntArrayMap<>(); consideredLowerCaseValue.defaultReturnValue(Constants.INT_NULL); } /** * Constructor to clone the component. * * @param e the edge to clone. */ CSTNPSUEdgePluggable(Edge e) { super(e); lowerCaseValues = new LabeledALabelIntTreeMap(this.getLabeledIntMapImplClass()); if (e != null && CSTNPSUEdge.class.isAssignableFrom(e.getClass())) { final CSTNPSUEdge e1 = (CSTNPSUEdge) e; for (final Object2ObjectMap.Entry> entry : e1.getLowerCaseValues()) { lowerCaseValues.mergeTriple(entry.getValue().getKey(), entry.getKey(), entry.getValue().getIntValue()); } } else { if (e != null && CSTNUEdge.class.isAssignableFrom(e.getClass())) { final CSTNUEdge e1 = (CSTNUEdge) e; final LabeledLowerCaseValue lcv = e1.getLowerCaseValue(); if (!lcv.isEmpty()) { lowerCaseValues.mergeTriple(lcv.getLabel(), lcv.getNodeName(), lcv.getValue()); } } } consideredLowerCaseValue = new Object2IntArrayMap<>(); consideredLowerCaseValue.defaultReturnValue(Constants.INT_NULL); } @Override public void clear() { super.clear(); lowerCaseValues.clear(); consideredLowerCaseValue.clear(); } @Override public final boolean hasSameValues(Edge e) { if (!(e instanceof CSTNPSUEdge e1)) { return false; } if (e == this) { return true; } if (!super.hasSameValues(e)) { return false; } return (lowerCaseValues.entrySet().equals(e1.getLowerCaseValues())); } @Override public boolean isEmpty() { return super.isEmpty() && lowerCaseValues.isEmpty(); } @Override public boolean mergeLabeledValue(Label l, int i) { final boolean added = super.mergeLabeledValue(l, i); // If a value is positive, and there are more lower-case values, some of them may be simplified. if (added && i >= 0 && !lowerCaseValues.isEmpty()) { for (final ALabel LCALabel : lowerCaseValues.aLabelSet()) { final ObjectSet