// Transductive node classification: only indices 0..3 supply training labels.
// Allowed edges and all node features remain visible; 4 and 5 are held out.
import aner.nn
import aner.parallel

let graph = nn.graph(nodes: 6,
    sources: List(0, 1, 1, 4, 2, 3, 3, 5),
    destinations: List(1, 0, 4, 1, 3, 2, 5, 3))
let features: Tensor = [
    [-1.0, -0.8], [-0.8, -0.6], [0.8, 0.6],
    [1.0, 0.8], [-0.9, -0.7], [0.9, 0.7]]
let labels: Tensor = [[0.0], [0.0], [1.0], [1.0], [0.0], [1.0]]
let model = nn.gnn(inputs: 2, hidden: 8, outputs: 2,
    architecture: "sage", layers: 2, seed: 17)
    .task("node_classification").on("cpu", "Float64")
let fitted = model.fit(graph, features, labels, epochs: 20,
    batch: 3, rate: 0.02, indices: List(0, 1, 2, 3),
    execution: parallel.local(workers: 2))
print(fitted.evaluate(graph, features, labels, indices: List(4, 5)).summary())
print(graph.nodes())
print(graph.edges())
print(fitted.predict(graph, features).rows())
print(fitted.diagram())
// Preserve a fresh checkpoint together with graph/preprocessing metadata:
// fitted.save("node-classifier.anergnn")
