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
1 change: 1 addition & 0 deletions src/graphtea/extensions/AlgorithmUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ public static boolean isConnected(GraphModel g) {
for (int i = 0; i < g.getVerticesCount(); i++) {
parent[i] = -1;
}
parent[0] = 0; // mark root as visited so it is not re-entered during recursion
dfs(g, 0, vs, parent);
return vs.stream().distinct().count() == g.getVerticesCount();
}
Expand Down
100 changes: 100 additions & 0 deletions src/graphtea/extensions/reports/basicreports/PruferSequence.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// GraphTea Project: http://github.com/graphtheorysoftware/GraphTea
// Copyright (C) 2012 Graph Theory Software Foundation: http://GraphTheorySoftware.com
// Copyright (C) 2008 Mathematical Science Department of Sharif University of Technology
// Distributed under the terms of the GNU General Public License (GPL): http://www.gnu.org/licenses/

package graphtea.extensions.reports.basicreports;

import graphtea.graph.graph.GraphModel;
import graphtea.graph.graph.Vertex;
import graphtea.platform.lang.CommandAttitude;
import graphtea.plugins.reports.extension.GraphReportExtension;


Comment on lines +12 to +13

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

1. Extra blank line in prufersequence 📘 Rule violation ⛯ Reliability

PruferSequence.java contains multiple consecutive blank lines after the import block, which
violates the repository Checkstyle configuration and can cause ant checkstyle-strict to fail. This
breaks the requirement that newly added Java files comply with Checkstyle 10 rules.
Agent Prompt
## Issue description
`PruferSequence.java` has multiple consecutive empty lines after the import section, which violates Checkstyle (`EmptyLineSeparator` with `allowMultipleEmptyLines=false`) and may fail `ant checkstyle-strict`.

## Issue Context
This is a newly added Java source file and must comply with the repository Checkstyle configuration.

## Fix Focus Areas
- src/graphtea/extensions/reports/basicreports/PruferSequence.java[8-15]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

/**
* Computes the Prüfer sequence of a labeled tree.
*
* The Prüfer sequence is a unique sequence of n-2 vertex labels that encodes
* a labeled tree on n vertices. It is produced by repeatedly removing the leaf
* with the smallest label and appending its neighbor's label to the sequence.
*
* The graph must be an unrooted labeled tree (connected, undirected, n-1 edges).
*/
@CommandAttitude(name = "prufer_sequence", abbreviation = "_ps")
public class PruferSequence implements GraphReportExtension<String> {

public String calculate(GraphModel g) {
int n = g.getVerticesCount();
if (n < 2) {
return "Graph must have at least 2 vertices";
}
if (g.getEdgesCount() != n - 1) {
return "Graph is not a tree (edge count must equal n-1)";
}

// degree[i] mirrors the current degree of vertex with id=i
int[] degree = new int[n];
Vertex[] vertices = g.getVertexArray();
for (Vertex v : vertices) {
degree[v.getId()] = g.getDegree(v);
}
Comment on lines +21 to +40

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

3. Directed tree accepted 🐞 Bug ✓ Correctness

PruferSequence claims the input must be an undirected tree but never rejects directed graphs; on
directed graphs it mixes total degree (in+out) with neighbors derived from outgoing edges only,
producing incorrect sequences or misleading errors.
Agent Prompt
### Issue description
`PruferSequence.calculate` is documented for undirected trees but will run on directed graphs. In directed graphs, degree and neighbor iteration semantics do not align with the Prüfer algorithm, so results are wrong.

### Issue Context
- `BaseGraph.getDegree()` counts in+out for directed graphs.
- `getNeighbors()` depends on `lightEdgeIterator(vertex)` which, in `ListGraph`, yields outgoing edges only when `directed==true`.

### Fix Focus Areas
- src/graphtea/extensions/reports/basicreports/PruferSequence.java[26-40]
- src/graphtea/library/BaseGraph.java[433-456]
- src/graphtea/library/ListGraph.java[375-399]

### Suggested change
- Early in `calculate(GraphModel g)` add:
  - `if (g.isDirected()) return "Graph is not a tree (graph must be undirected)";`
  - (Optional but aligns with the docstring) `if (!AlgorithmUtils.isConnected(g)) return "Graph is not a tree (disconnected)";`

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


int[] sequence = new int[n - 2];
boolean[] removed = new boolean[n];

for (int step = 0; step < n - 2; step++) {
// find the leaf with the smallest id
int leaf = -1;
for (int i = 0; i < n; i++) {
if (!removed[i] && degree[i] == 1) {
leaf = i;
break;
}
}
if (leaf == -1) {
return "Graph is not a tree (cycle detected)";
}

// find the unique neighbor of this leaf
Vertex leafVertex = g.getVertex(leaf);
int neighbor = -1;
for (Vertex nb : g.getNeighbors(leafVertex)) {
if (!removed[nb.getId()]) {
neighbor = nb.getId();
break;
Comment on lines +35 to +64

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

2. Subgraph id crash 🐞 Bug ✓ Correctness

PruferSequence indexes arrays by Vertex.getId(), but in GraphModel subgraphs (subgraphIndex!=0) the
local vertex index is stored separately as a subgraphId, so getId() can be outside 0..n-1 and cause
ArrayIndexOutOfBoundsException or incorrect removals.
Agent Prompt
### Issue description
`PruferSequence.calculate` assumes `Vertex.getId()` is a 0..n-1 local index and uses it to index `degree[]`/`removed[]`. In GraphModel subgraphs, local indices are stored as `subgraphId` and `Vertex.getId()` may refer to the supergraph id, leading to `ArrayIndexOutOfBoundsException` and wrong behavior.

### Issue Context
Subgraphs are created via `registerSubgraph()` + `setSubGraphIndex()` and then inserting existing `Vertex` objects. In this mode, `ListGraph.setId` writes `v.setSubgraphId(...)` instead of mutating `v.id`.

### Fix Focus Areas
- src/graphtea/extensions/reports/basicreports/PruferSequence.java[35-75]
- src/graphtea/extensions/algorithms/subgraphs/InducedSubgraphs.java[20-29]
- src/graphtea/library/ListGraph.java[141-148]
- src/graphtea/library/BaseGraph.java[402-408]
- src/graphtea/graph/graph/GraphModel.java[529-536]

### Implementation sketch
- Use `Vertex[] verts = g.getVertexArray();`
- Build `IdentityHashMap<Vertex,Integer> idx` mapping each `verts[i]` to `i`.
- Maintain `degree[i] = g.getDegree(verts[i])` and `removed[i]`.
- When iterating neighbors, translate `nb` to `nbIdx = idx.get(nb)` and use `removed[nbIdx]`/`degree[nbIdx]--`.
- Store output label separately (e.g., `nb.getId()` or `verts[nbIdx].getId()`) rather than array index.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

}
}
if (neighbor == -1) {
return "Graph is not a tree (disconnected)";
}

sequence[step] = neighbor;
removed[leaf] = true;
degree[leaf] = 0;
degree[neighbor]--;
}

// format as comma-separated list of 1-based labels for readability
StringBuilder sb = new StringBuilder();
for (int i = 0; i < sequence.length; i++) {
sb.append(sequence[i]);
if (i < sequence.length - 1) {
sb.append(", ");
}
}
return sb.toString();
}

public String getName() {
return "Prufer Sequence";
}

public String getDescription() {
return "Prufer sequence of a labeled tree";
}

@Override
public String getCategory() {
return "General";
}
}
Loading