Skip to main content

ModelGraph

Struct ModelGraph 

Source
pub struct ModelGraph { /* private fields */ }
Expand description

Graph representation of a SAMM model

Nodes represent properties and characteristics, edges represent dependencies

Implementations§

Source§

impl ModelGraph

Source

pub fn to_dot(&self, style: VisualizationStyle) -> Result<String>

Generate DOT format representation of the graph

Creates a Graphviz DOT file that can be rendered using dot command or online tools like GraphvizOnline.

§Arguments
  • style - Visualization style to use
§Returns

DOT format string

§Example
use oxirs_samm::graph_analytics::{ModelGraph, VisualizationStyle};

let dot = graph.to_dot(VisualizationStyle::Detailed)?;
std::fs::write("model.dot", dot)?;
Source

pub fn to_dot_with_colors( &self, style: VisualizationStyle, colors: ColorScheme, ) -> Result<String>

Generate DOT format with custom color scheme

§Arguments
  • style - Visualization style to use
  • colors - Custom color scheme
§Returns

DOT format string

Source

pub fn render_svg( &self, output_path: &str, style: VisualizationStyle, ) -> Result<()>

Render graph to SVG file (requires graphviz feature)

This method directly renders the graph to an SVG file using the Graphviz library.

§Arguments
  • output_path - Path to output SVG file
  • style - Visualization style to use
§Example
use oxirs_samm::graph_analytics::{ModelGraph, VisualizationStyle};

graph.render_svg("model.svg", VisualizationStyle::Hierarchical)?;
Source

pub fn render_png( &self, output_path: &str, style: VisualizationStyle, ) -> Result<()>

Render graph to PNG file (requires graphviz feature)

This method directly renders the graph to a PNG file using the Graphviz library.

§Arguments
  • output_path - Path to output PNG file
  • style - Visualization style to use
§Example
use oxirs_samm::graph_analytics::{ModelGraph, VisualizationStyle};

graph.render_png("model.png", VisualizationStyle::Compact)?;
Source§

impl ModelGraph

Source

pub fn from_aspect(aspect: &Aspect) -> Result<Self>

Build a dependency graph from a SAMM aspect

§Arguments
  • aspect - The aspect model to analyze
§Returns

A graph representation of the model’s dependency structure

§Example
use oxirs_samm::graph_analytics::ModelGraph;
use oxirs_samm::metamodel::Aspect;

let graph = ModelGraph::from_aspect(aspect)?;
println!("Graph has {} nodes and {} edges",
         graph.num_nodes(), graph.num_edges());
Source

pub fn num_nodes(&self) -> usize

Get the number of nodes in the graph

Source

pub fn num_edges(&self) -> usize

Get the number of edges in the graph

Source

pub fn nodes(&self) -> &[String]

Get all nodes in the graph

Source

pub fn edges(&self) -> &[(String, String)]

Get all edges in the graph

Source

pub fn compute_centrality(&self) -> CentralityMetrics

Compute centrality metrics for all nodes

Uses PageRank, betweenness centrality, and closeness centrality to identify the most important nodes in the dependency graph.

§Example
use oxirs_samm::graph_analytics::ModelGraph;

let centrality = graph.compute_centrality();
println!("Top 5 most central nodes:");
for (name, score) in centrality.top_nodes(5) {
    println!("  {}: {:.4}", name, score);
}
Source

pub fn detect_communities(&self) -> Result<Vec<Community>>

Detect communities (clusters) of related elements

Uses the Louvain algorithm to identify modules or groups of tightly coupled properties.

§Example
use oxirs_samm::graph_analytics::ModelGraph;

let communities = graph.detect_communities()?;
println!("Model has {} distinct modules", communities.len());
for (i, community) in communities.iter().enumerate() {
    println!("Module {}: {} elements", i, community.members.len());
}
Source

pub fn has_cycles(&self) -> Result<bool>

Check if the graph has circular dependencies

Circular dependencies indicate potential design issues and should be avoided.

§Example
use oxirs_samm::graph_analytics::ModelGraph;

if graph.has_cycles()? {
    eprintln!("Warning: Circular dependencies detected!");
}
Source

pub fn shortest_path(&self, from: &str, to: &str) -> Result<Option<Vec<String>>>

Compute shortest path between two elements

§Arguments
  • from - Source element name
  • to - Target element name
§Returns

The path from source to target, or None if no path exists

§Example
use oxirs_samm::graph_analytics::ModelGraph;

if let Some(path) = graph.shortest_path("Property1", "Property2")? {
    println!("Path: {}", path.join(" -> "));
} else {
    println!("No dependency path found");
}
Source

pub fn compute_metrics(&self) -> Result<GraphMetrics>

Compute comprehensive graph metrics

Returns metrics like diameter, density, clustering coefficient, etc.

§Example
use oxirs_samm::graph_analytics::ModelGraph;

let metrics = graph.compute_metrics()?;
println!("Graph Metrics:");
println!("  Nodes: {}", metrics.num_nodes);
println!("  Edges: {}", metrics.num_edges);
println!("  Density: {:.4}", metrics.density);
Source

pub fn strongly_connected_components(&self) -> Result<Vec<Vec<String>>>

Get strongly connected components

Returns groups of nodes where each node is reachable from every other node in the group.

§Example
use oxirs_samm::graph_analytics::ModelGraph;

let sccs = graph.strongly_connected_components()?;
println!("Found {} strongly connected components", sccs.len());
Source

pub fn analyze_impact(&self, node_name: &str) -> Result<ImpactAnalysis>

Analyze the impact of changing or removing a node

This performs a dependency impact analysis to identify all nodes that would be affected if the given node is modified or removed. It computes both direct dependents and transitive dependents, along with a risk assessment.

§Arguments
  • node_name - The name of the node to analyze
§Returns

An ImpactAnalysis struct containing:

  • Direct dependents (nodes with edges from the source node)
  • All transitive dependents (reachable via dependency chains)
  • Impact score (percentage of graph affected)
  • Risk level classification
§Example
use oxirs_samm::graph_analytics::ModelGraph;
use oxirs_samm::metamodel::Aspect;

let graph = ModelGraph::from_aspect(aspect)?;
let impact = graph.analyze_impact("PropertyName")?;

println!("Changing {} would affect {} nodes",
         impact.source_node, impact.all_dependents.len());
println!("Risk level: {:?}", impact.risk_level);
Source

pub fn suggest_cycle_breaks(&self) -> Result<Vec<CycleBreakSuggestion>>

Suggest ways to break circular dependencies

Analyzes detected cycles and provides suggestions for breaking them, including which edges to remove and why.

§Returns

A vector of suggestions for breaking each cycle found in the graph

§Example
use oxirs_samm::graph_analytics::ModelGraph;
use oxirs_samm::metamodel::Aspect;

let graph = ModelGraph::from_aspect(aspect)?;

if graph.has_cycles()? {
    let suggestions = graph.suggest_cycle_breaks()?;
    for suggestion in suggestions {
        println!("Remove edge: {:?}", suggestion.edge_to_remove);
        println!("Reason: {}", suggestion.reason);
    }
}
Source

pub fn compare(&self, other: &ModelGraph) -> Result<GraphComparison>

Compare this graph with another graph

Performs structural comparison between two model graphs, identifying added/removed nodes and edges, and computing similarity metrics.

§Arguments
  • other - The graph to compare with
§Returns

A GraphComparison struct containing:

  • Lists of added/removed nodes and edges
  • Similarity score (0.0-1.0, where 1.0 means identical)
  • Change magnitude classification
§Example
use oxirs_samm::graph_analytics::ModelGraph;
use oxirs_samm::metamodel::Aspect;

let old_graph = ModelGraph::from_aspect(old_aspect)?;
let new_graph = ModelGraph::from_aspect(new_aspect)?;

let comparison = old_graph.compare(&new_graph)?;
println!("Similarity: {:.2}%", comparison.similarity_score * 100.0);
println!("Change magnitude: {:?}", comparison.change_magnitude);
println!("Added {} nodes, removed {} nodes",
         comparison.added_nodes.len(),
         comparison.removed_nodes.len());

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<SS, SP> SupersetOf<SS> for SP
where SS: SubsetOf<SP>,

Source§

fn to_subset(&self) -> Option<SS>

The inverse inclusion map: attempts to construct self from the equivalent element of its superset. Read more
Source§

fn is_in_subset(&self) -> bool

Checks if self is actually part of its subset T (and can be converted to it).
Source§

fn to_subset_unchecked(&self) -> SS

Use with care! Same as self.to_subset but without any property checks. Always succeeds.
Source§

fn from_subset(element: &SS) -> SP

The inclusion map: converts self to the equivalent element of its superset.
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> ErasedDestructor for T
where T: 'static,