Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
* Added `KWay{State,Transition}CoverTestsIterator`s to `automata-util` as a new means for conformance testing.
* Added `CollectionUtil#allCombintationsIterator` and `CollectionUtil#allPermutationsIterator` for computing k-combinations and k-permutations.
* Added `NFAs#canonize` to canonize NFAs via [Brzozowski's algorithm](https://en.wikipedia.org/wiki/DFA_minimization#Brzozowski's_algorithm).
* Added a DOT parser for `ContextFreeModalProcessSystem`s.
* For nondeterministic model types, `DOTParsers` now contains methods that accept an initial node prefix, in case the number of initial nodes is not known beforehand.

### Changed

Expand Down
6 changes: 4 additions & 2 deletions api/src/main/java/net/automatalib/graph/CFMPSGraphView.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,13 @@
*/
public class CFMPSGraphView<N, L, E, AP> implements Graph<Pair<L, N>, Pair<L, E>> {

private final L mainProcedure;
private final Map<L, ProceduralModalProcessGraph<N, L, E, AP, ?>> pmpgs;

// cast is fine, because we make sure to only query nodes/edges belonging to the respective procedures
@SuppressWarnings("unchecked")
public CFMPSGraphView(Map<L, ? extends ProceduralModalProcessGraph<? extends N, L, ? extends E, AP, ?>> pmpgs) {
public CFMPSGraphView(L mainProcedure, Map<L, ? extends ProceduralModalProcessGraph<? extends N, L, ? extends E, AP, ?>> pmpgs) {
this.mainProcedure = mainProcedure;
this.pmpgs = (Map<L, ProceduralModalProcessGraph<N, L, E, AP, ?>>) pmpgs;
}

Expand Down Expand Up @@ -91,6 +93,6 @@ public Collection<Pair<L, N>> getNodes() {

@Override
public VisualizationHelper<Pair<L, N>, Pair<L, E>> getVisualizationHelper() {
return new CFMPSVisualizationHelper<>(this.pmpgs);
return new CFMPSVisualizationHelper<>(this.mainProcedure, this.pmpgs);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,6 @@ default int size() {

@Override
default Graph<?, ?> graphView() {
return new CFMPSGraphView<>(getPMPGs());
return new CFMPSGraphView<>(getMainProcess(), getPMPGs());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;

import net.automatalib.common.util.HashUtil;
import net.automatalib.common.util.Pair;
Expand All @@ -30,25 +31,26 @@

public class CFMPSVisualizationHelper<N, L, E> extends DefaultVisualizationHelper<Pair<L, N>, Pair<L, E>> {

private final Map<L, PMPGVisualizationHelper<N, E, ?>> visualizers;
private final Map<L, PMPGVisualizationHelper<N, L, E, ?>> visualizers;
private final List<Pair<L, N>> initialNodes;

// cast is fine, because we make sure to only query nodes/edges belonging to the respective procedures
@SuppressWarnings("unchecked")
public CFMPSVisualizationHelper(Map<L, ? extends ProceduralModalProcessGraph<? extends N, L, ? extends E, ?, ?>> pmpgs) {

public CFMPSVisualizationHelper(L mainProcedure,
Map<L, ? extends ProceduralModalProcessGraph<? extends N, L, ? extends E, ?, ?>> pmpgs) {
this.visualizers = new HashMap<>(HashUtil.capacity(pmpgs.size()));
this.initialNodes = new ArrayList<>(pmpgs.size());

for (Entry<L, ? extends ProceduralModalProcessGraph<? extends N, L, ? extends E, ?, ?>> e : pmpgs.entrySet()) {
final ProceduralModalProcessGraph<N, L, E, ?, ?> value =
(ProceduralModalProcessGraph<N, L, E, ?, ?>) e.getValue();
final L key = e.getKey();
final N initialNode = value.getInitialNode();

this.visualizers.put(e.getKey(), new PMPGVisualizationHelper<>(value));
this.visualizers.put(key, new PMPGVisualizationHelper<>(key, Objects.equals(key, mainProcedure), value));

if (initialNode != null) {
this.initialNodes.add(Pair.of(e.getKey(), initialNode));
this.initialNodes.add(Pair.of(key, initialNode));
}
}
}
Expand All @@ -63,7 +65,7 @@ public boolean getNodeProperties(Pair<L, N> node, Map<String, String> properties

final L process = node.getFirst();
@SuppressWarnings("assignment") // we only use identifier for which procedures exist
final @NonNull PMPGVisualizationHelper<N, E, ?> visualizer = this.visualizers.get(process);
final @NonNull PMPGVisualizationHelper<N, L, E, ?> visualizer = this.visualizers.get(process);

return visualizer.getNodeProperties(node.getSecond(), properties);
}
Expand All @@ -73,7 +75,7 @@ public boolean getEdgeProperties(Pair<L, N> src, Pair<L, E> edge, Pair<L, N> tgt

final L process = edge.getFirst();
@SuppressWarnings("assignment") // we only use identifier for which procedures exist
final @NonNull PMPGVisualizationHelper<N, E, ?> visualizer = this.visualizers.get(process);
final @NonNull PMPGVisualizationHelper<N, L, E, ?> visualizer = this.visualizers.get(process);

return visualizer.getEdgeProperties(src.getSecond(), edge.getSecond(), tgt.getSecond(), properties);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,21 @@
import net.automatalib.graph.ProceduralModalProcessGraph;
import net.automatalib.ts.modal.transition.ProceduralModalEdgeProperty;
import net.automatalib.visualization.DefaultVisualizationHelper;
import org.checkerframework.checker.nullness.qual.Nullable;

public class PMPGVisualizationHelper<N, E, AP> extends DefaultVisualizationHelper<N, E> {
public class PMPGVisualizationHelper<N, L, E, AP> extends DefaultVisualizationHelper<N, E> {

private final @Nullable L label;
private final boolean isMain;
private final ProceduralModalProcessGraph<N, ?, E, AP, ?> pmpg;

public PMPGVisualizationHelper(ProceduralModalProcessGraph<N, ?, E, AP, ?> pmpg) {
this(null, false, pmpg);
}

public PMPGVisualizationHelper(@Nullable L label, boolean isMain, ProceduralModalProcessGraph<N, ?, E, AP, ?> pmpg) {
this.label = label;
this.isMain = isMain;
this.pmpg = pmpg;
}

Expand All @@ -52,17 +61,26 @@ public boolean getNodeProperties(N node, Map<String, String> properties) {
final Set<AP> aps = pmpg.getNodeProperty(node);

if (aps.isEmpty()) {
properties.put(NodeAttrs.LABEL, "");
properties.put(PMPGNodeAttrs.LABEL, "");
} else {
properties.put(NodeAttrs.LABEL, aps.toString());
properties.put(PMPGNodeAttrs.LABEL, aps.toString());
}

if (label != null) {
properties.put(PMPGNodeAttrs.PROCESS, label.toString());
if (isMain) {
properties.put(PMPGNodeAttrs.MAIN, "true");
}
}

if (Objects.equals(pmpg.getInitialNode(), node)) {
properties.put(NodeAttrs.SHAPE, NodeShapes.OCTAGON);
properties.put(PMPGNodeAttrs.SHAPE, NodeShapes.OCTAGON);
properties.put(PMPGNodeAttrs.INITIAL, "true");
} else if (Objects.equals(pmpg.getFinalNode(), node)) {
properties.put(NodeAttrs.SHAPE, NodeShapes.BOX);
properties.put(PMPGNodeAttrs.SHAPE, NodeShapes.BOX);
properties.put(PMPGNodeAttrs.FINAL, "true");
} else {
properties.put(NodeAttrs.SHAPE, NodeShapes.CIRCLE);
properties.put(PMPGNodeAttrs.SHAPE, NodeShapes.CIRCLE);
}

return true;
Expand All @@ -83,8 +101,10 @@ public boolean getEdgeProperties(N src, E edge, N tgt, Map<String, String> prope
styleJoiner.add(EdgeStyles.BOLD);
}

properties.put(EdgeAttrs.LABEL, String.valueOf(pmpg.getEdgeLabel(edge)));
properties.put(EdgeAttrs.STYLE, styleJoiner.toString());
properties.put(PMPGEdgeAttrs.LABEL, String.valueOf(pmpg.getEdgeLabel(edge)));
properties.put(PMPGEdgeAttrs.MODALITY, prop.getModalType().toString());
properties.put(PMPGEdgeAttrs.PROCEDURALITY, prop.getProceduralType().toString());
properties.put(PMPGEdgeAttrs.STYLE, styleJoiner.toString());

return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ private CommonAttrs() {
}
}

sealed class NodeAttrs extends CommonAttrs permits MMLTNodeAttrs {
sealed class NodeAttrs extends CommonAttrs permits MMLTNodeAttrs, PMPGNodeAttrs {

public static final String SHAPE = "shape";
public static final String WIDTH = "width";
Expand All @@ -107,6 +107,17 @@ private MMLTNodeAttrs() {
}
}

final class PMPGNodeAttrs extends NodeAttrs {

public static final String PROCESS = "process";
public static final String MAIN = "main";
public static final String FINAL = "final";

private PMPGNodeAttrs() {
// prevent instantiation
}
}

sealed class EdgeAttrs extends CommonAttrs permits MTSEdgeAttrs, MMLTEdgeAttrs {

public static final String PENWIDTH = "penwidth";
Expand All @@ -117,7 +128,7 @@ private EdgeAttrs() {
}
}

final class MTSEdgeAttrs extends EdgeAttrs {
sealed class MTSEdgeAttrs extends EdgeAttrs permits PMPGEdgeAttrs {

public static final String MODALITY = "modality";

Expand All @@ -135,6 +146,15 @@ private MMLTEdgeAttrs() {
}
}

final class PMPGEdgeAttrs extends MTSEdgeAttrs {

public static final String PROCEDURALITY = "procedurality";

private PMPGEdgeAttrs() {
// prevent instantiation
}
}

final class NodeShapes {

public static final String NONE = "none";
Expand Down
Loading