exonware-xwnode 0.0.1.12__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. exonware/__init__.py +14 -0
  2. exonware/xwnode/__init__.py +127 -0
  3. exonware/xwnode/base.py +676 -0
  4. exonware/xwnode/config.py +178 -0
  5. exonware/xwnode/contracts.py +730 -0
  6. exonware/xwnode/errors.py +503 -0
  7. exonware/xwnode/facade.py +460 -0
  8. exonware/xwnode/strategies/__init__.py +158 -0
  9. exonware/xwnode/strategies/advisor.py +463 -0
  10. exonware/xwnode/strategies/edges/__init__.py +32 -0
  11. exonware/xwnode/strategies/edges/adj_list.py +227 -0
  12. exonware/xwnode/strategies/edges/adj_matrix.py +391 -0
  13. exonware/xwnode/strategies/edges/base.py +169 -0
  14. exonware/xwnode/strategies/flyweight.py +328 -0
  15. exonware/xwnode/strategies/impls/__init__.py +13 -0
  16. exonware/xwnode/strategies/impls/_base_edge.py +403 -0
  17. exonware/xwnode/strategies/impls/_base_node.py +307 -0
  18. exonware/xwnode/strategies/impls/edge_adj_list.py +353 -0
  19. exonware/xwnode/strategies/impls/edge_adj_matrix.py +445 -0
  20. exonware/xwnode/strategies/impls/edge_bidir_wrapper.py +455 -0
  21. exonware/xwnode/strategies/impls/edge_block_adj_matrix.py +539 -0
  22. exonware/xwnode/strategies/impls/edge_coo.py +533 -0
  23. exonware/xwnode/strategies/impls/edge_csc.py +447 -0
  24. exonware/xwnode/strategies/impls/edge_csr.py +492 -0
  25. exonware/xwnode/strategies/impls/edge_dynamic_adj_list.py +503 -0
  26. exonware/xwnode/strategies/impls/edge_flow_network.py +555 -0
  27. exonware/xwnode/strategies/impls/edge_hyperedge_set.py +516 -0
  28. exonware/xwnode/strategies/impls/edge_neural_graph.py +650 -0
  29. exonware/xwnode/strategies/impls/edge_octree.py +574 -0
  30. exonware/xwnode/strategies/impls/edge_property_store.py +655 -0
  31. exonware/xwnode/strategies/impls/edge_quadtree.py +519 -0
  32. exonware/xwnode/strategies/impls/edge_rtree.py +820 -0
  33. exonware/xwnode/strategies/impls/edge_temporal_edgeset.py +558 -0
  34. exonware/xwnode/strategies/impls/edge_tree_graph_basic.py +271 -0
  35. exonware/xwnode/strategies/impls/edge_weighted_graph.py +411 -0
  36. exonware/xwnode/strategies/manager.py +775 -0
  37. exonware/xwnode/strategies/metrics.py +538 -0
  38. exonware/xwnode/strategies/migration.py +432 -0
  39. exonware/xwnode/strategies/nodes/__init__.py +50 -0
  40. exonware/xwnode/strategies/nodes/_base_node.py +307 -0
  41. exonware/xwnode/strategies/nodes/adjacency_list.py +267 -0
  42. exonware/xwnode/strategies/nodes/aho_corasick.py +345 -0
  43. exonware/xwnode/strategies/nodes/array_list.py +209 -0
  44. exonware/xwnode/strategies/nodes/base.py +247 -0
  45. exonware/xwnode/strategies/nodes/deque.py +200 -0
  46. exonware/xwnode/strategies/nodes/hash_map.py +135 -0
  47. exonware/xwnode/strategies/nodes/heap.py +307 -0
  48. exonware/xwnode/strategies/nodes/linked_list.py +232 -0
  49. exonware/xwnode/strategies/nodes/node_aho_corasick.py +520 -0
  50. exonware/xwnode/strategies/nodes/node_array_list.py +175 -0
  51. exonware/xwnode/strategies/nodes/node_avl_tree.py +371 -0
  52. exonware/xwnode/strategies/nodes/node_b_plus_tree.py +542 -0
  53. exonware/xwnode/strategies/nodes/node_bitmap.py +420 -0
  54. exonware/xwnode/strategies/nodes/node_bitset_dynamic.py +513 -0
  55. exonware/xwnode/strategies/nodes/node_bloom_filter.py +347 -0
  56. exonware/xwnode/strategies/nodes/node_btree.py +357 -0
  57. exonware/xwnode/strategies/nodes/node_count_min_sketch.py +470 -0
  58. exonware/xwnode/strategies/nodes/node_cow_tree.py +473 -0
  59. exonware/xwnode/strategies/nodes/node_cuckoo_hash.py +392 -0
  60. exonware/xwnode/strategies/nodes/node_fenwick_tree.py +301 -0
  61. exonware/xwnode/strategies/nodes/node_hash_map.py +269 -0
  62. exonware/xwnode/strategies/nodes/node_heap.py +191 -0
  63. exonware/xwnode/strategies/nodes/node_hyperloglog.py +407 -0
  64. exonware/xwnode/strategies/nodes/node_linked_list.py +409 -0
  65. exonware/xwnode/strategies/nodes/node_lsm_tree.py +400 -0
  66. exonware/xwnode/strategies/nodes/node_ordered_map.py +390 -0
  67. exonware/xwnode/strategies/nodes/node_ordered_map_balanced.py +565 -0
  68. exonware/xwnode/strategies/nodes/node_patricia.py +512 -0
  69. exonware/xwnode/strategies/nodes/node_persistent_tree.py +378 -0
  70. exonware/xwnode/strategies/nodes/node_radix_trie.py +452 -0
  71. exonware/xwnode/strategies/nodes/node_red_black_tree.py +497 -0
  72. exonware/xwnode/strategies/nodes/node_roaring_bitmap.py +570 -0
  73. exonware/xwnode/strategies/nodes/node_segment_tree.py +289 -0
  74. exonware/xwnode/strategies/nodes/node_set_hash.py +354 -0
  75. exonware/xwnode/strategies/nodes/node_set_tree.py +480 -0
  76. exonware/xwnode/strategies/nodes/node_skip_list.py +316 -0
  77. exonware/xwnode/strategies/nodes/node_splay_tree.py +393 -0
  78. exonware/xwnode/strategies/nodes/node_suffix_array.py +487 -0
  79. exonware/xwnode/strategies/nodes/node_treap.py +387 -0
  80. exonware/xwnode/strategies/nodes/node_tree_graph_hybrid.py +1434 -0
  81. exonware/xwnode/strategies/nodes/node_trie.py +252 -0
  82. exonware/xwnode/strategies/nodes/node_union_find.py +187 -0
  83. exonware/xwnode/strategies/nodes/node_xdata_optimized.py +369 -0
  84. exonware/xwnode/strategies/nodes/priority_queue.py +209 -0
  85. exonware/xwnode/strategies/nodes/queue.py +161 -0
  86. exonware/xwnode/strategies/nodes/sparse_matrix.py +206 -0
  87. exonware/xwnode/strategies/nodes/stack.py +152 -0
  88. exonware/xwnode/strategies/nodes/trie.py +274 -0
  89. exonware/xwnode/strategies/nodes/union_find.py +283 -0
  90. exonware/xwnode/strategies/pattern_detector.py +603 -0
  91. exonware/xwnode/strategies/performance_monitor.py +487 -0
  92. exonware/xwnode/strategies/queries/__init__.py +24 -0
  93. exonware/xwnode/strategies/queries/base.py +236 -0
  94. exonware/xwnode/strategies/queries/cql.py +201 -0
  95. exonware/xwnode/strategies/queries/cypher.py +181 -0
  96. exonware/xwnode/strategies/queries/datalog.py +70 -0
  97. exonware/xwnode/strategies/queries/elastic_dsl.py +70 -0
  98. exonware/xwnode/strategies/queries/eql.py +70 -0
  99. exonware/xwnode/strategies/queries/flux.py +70 -0
  100. exonware/xwnode/strategies/queries/gql.py +70 -0
  101. exonware/xwnode/strategies/queries/graphql.py +240 -0
  102. exonware/xwnode/strategies/queries/gremlin.py +181 -0
  103. exonware/xwnode/strategies/queries/hiveql.py +214 -0
  104. exonware/xwnode/strategies/queries/hql.py +70 -0
  105. exonware/xwnode/strategies/queries/jmespath.py +219 -0
  106. exonware/xwnode/strategies/queries/jq.py +66 -0
  107. exonware/xwnode/strategies/queries/json_query.py +66 -0
  108. exonware/xwnode/strategies/queries/jsoniq.py +248 -0
  109. exonware/xwnode/strategies/queries/kql.py +70 -0
  110. exonware/xwnode/strategies/queries/linq.py +238 -0
  111. exonware/xwnode/strategies/queries/logql.py +70 -0
  112. exonware/xwnode/strategies/queries/mql.py +68 -0
  113. exonware/xwnode/strategies/queries/n1ql.py +210 -0
  114. exonware/xwnode/strategies/queries/partiql.py +70 -0
  115. exonware/xwnode/strategies/queries/pig.py +215 -0
  116. exonware/xwnode/strategies/queries/promql.py +70 -0
  117. exonware/xwnode/strategies/queries/sparql.py +220 -0
  118. exonware/xwnode/strategies/queries/sql.py +275 -0
  119. exonware/xwnode/strategies/queries/xml_query.py +66 -0
  120. exonware/xwnode/strategies/queries/xpath.py +223 -0
  121. exonware/xwnode/strategies/queries/xquery.py +258 -0
  122. exonware/xwnode/strategies/queries/xwnode_executor.py +332 -0
  123. exonware/xwnode/strategies/queries/xwquery_strategy.py +424 -0
  124. exonware/xwnode/strategies/registry.py +604 -0
  125. exonware/xwnode/strategies/simple.py +273 -0
  126. exonware/xwnode/strategies/utils.py +532 -0
  127. exonware/xwnode/types.py +912 -0
  128. exonware/xwnode/version.py +78 -0
  129. exonware_xwnode-0.0.1.12.dist-info/METADATA +169 -0
  130. exonware_xwnode-0.0.1.12.dist-info/RECORD +132 -0
  131. exonware_xwnode-0.0.1.12.dist-info/WHEEL +4 -0
  132. exonware_xwnode-0.0.1.12.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,274 @@
1
+ """
2
+ Trie Node Strategy Implementation
3
+
4
+ This module implements the TRIE strategy for efficient string prefix operations.
5
+ """
6
+
7
+ from typing import Any, Iterator, Dict, List, Optional
8
+ from .base import ANodeTreeStrategy
9
+ from ...types import NodeMode, NodeTrait
10
+
11
+
12
+ class TrieNode:
13
+ """Node in the trie structure."""
14
+
15
+ def __init__(self):
16
+ self.children: Dict[str, 'TrieNode'] = {}
17
+ self.is_end_of_word = False
18
+ self.value: Any = None
19
+
20
+
21
+ class xTrieStrategy(ANodeTreeStrategy):
22
+ """
23
+ Trie node strategy for efficient string prefix operations.
24
+
25
+ Optimized for prefix matching, autocomplete, and string searching.
26
+ """
27
+
28
+ def __init__(self, traits: NodeTrait = NodeTrait.NONE, **options):
29
+ """Initialize the trie strategy."""
30
+ super().__init__(data=None, **options)
31
+ self._mode = NodeMode.TRIE
32
+ self._traits = traits
33
+ self._root = TrieNode()
34
+ self._size = 0
35
+
36
+ def get_supported_traits(self) -> NodeTrait:
37
+ """Get the traits supported by the trie strategy."""
38
+ return (NodeTrait.ORDERED | NodeTrait.HIERARCHICAL | NodeTrait.INDEXED)
39
+
40
+ # ============================================================================
41
+ # CORE OPERATIONS
42
+ # ============================================================================
43
+
44
+ def insert(self, key: Any, value: Any) -> None:
45
+ """Store a key-value pair (key should be string-like)."""
46
+ word = str(key)
47
+ node = self._root
48
+
49
+ # Traverse/create path
50
+ for char in word:
51
+ if char not in node.children:
52
+ node.children[char] = TrieNode()
53
+ node = node.children[char]
54
+
55
+ # Mark end of word and store value
56
+ if not node.is_end_of_word:
57
+ self._size += 1
58
+ node.is_end_of_word = True
59
+ node.value = value
60
+
61
+ def find(self, key: Any) -> Any:
62
+ """Retrieve a value by key."""
63
+ word = str(key)
64
+ node = self._root
65
+
66
+ # Traverse path
67
+ for char in word:
68
+ if char not in node.children:
69
+ return None
70
+ node = node.children[char]
71
+
72
+ return node.value if node.is_end_of_word else None
73
+
74
+ def delete(self, key: Any) -> bool:
75
+ """Remove a key-value pair."""
76
+ word = str(key)
77
+ return self._delete_helper(self._root, word, 0)
78
+
79
+ def _delete_helper(self, node: TrieNode, word: str, index: int) -> bool:
80
+ """Helper method for deletion."""
81
+ if index == len(word):
82
+ if node.is_end_of_word:
83
+ node.is_end_of_word = False
84
+ node.value = None
85
+ self._size -= 1
86
+ return True
87
+ return False
88
+
89
+ char = word[index]
90
+ if char not in node.children:
91
+ return False
92
+
93
+ deleted = self._delete_helper(node.children[char], word, index + 1)
94
+
95
+ # Clean up empty nodes
96
+ if deleted and not node.children[char].children and not node.children[char].is_end_of_word:
97
+ del node.children[char]
98
+
99
+ return deleted
100
+
101
+ def size(self) -> int:
102
+ """Get the number of items."""
103
+ return self._size
104
+
105
+ def is_empty(self) -> bool:
106
+ """Check if the structure is empty."""
107
+ return self._size == 0
108
+
109
+ def to_native(self) -> Dict[str, Any]:
110
+ """Convert to native Python dictionary."""
111
+ result = {}
112
+ self._collect_words(self._root, "", result)
113
+ return result
114
+
115
+ def _collect_words(self, node: TrieNode, prefix: str, result: Dict[str, Any]) -> None:
116
+ """Collect all words from trie."""
117
+ if node.is_end_of_word:
118
+ result[prefix] = node.value
119
+
120
+ for char, child in node.children.items():
121
+ self._collect_words(child, prefix + char, result)
122
+
123
+ # ============================================================================
124
+ # TREE STRATEGY METHODS
125
+ # ============================================================================
126
+
127
+ def traverse(self, order: str = 'inorder') -> List[Any]:
128
+ """Traverse tree in specified order."""
129
+ result = []
130
+ self._collect_words(self._root, "", result)
131
+ return list(result.values())
132
+
133
+ def get_min(self) -> Any:
134
+ """Get minimum key."""
135
+ # Find leftmost word
136
+ node = self._root
137
+ word = ""
138
+ while node.children:
139
+ char = min(node.children.keys())
140
+ word += char
141
+ node = node.children[char]
142
+ return word if node.is_end_of_word else None
143
+
144
+ def get_max(self) -> Any:
145
+ """Get maximum key."""
146
+ # Find rightmost word
147
+ node = self._root
148
+ word = ""
149
+ while node.children:
150
+ char = max(node.children.keys())
151
+ word += char
152
+ node = node.children[char]
153
+ return word if node.is_end_of_word else None
154
+
155
+ # ============================================================================
156
+ # AUTO-3 Phase 2 methods
157
+ # ============================================================================
158
+
159
+ def as_trie(self):
160
+ """Provide Trie behavioral view."""
161
+ return self
162
+
163
+ def as_heap(self):
164
+ """Provide Heap behavioral view."""
165
+ # TODO: Implement Heap view
166
+ return self
167
+
168
+ def as_skip_list(self):
169
+ """Provide SkipList behavioral view."""
170
+ # TODO: Implement SkipList view
171
+ return self
172
+
173
+ # ============================================================================
174
+ # TRIE SPECIFIC OPERATIONS
175
+ # ============================================================================
176
+
177
+ def prefix_search(self, prefix: str) -> List[str]:
178
+ """Find all keys with given prefix."""
179
+ node = self._root
180
+
181
+ # Navigate to prefix
182
+ for char in prefix:
183
+ if char not in node.children:
184
+ return []
185
+ node = node.children[char]
186
+
187
+ # Collect all words with this prefix
188
+ result = []
189
+ self._collect_words(node, prefix, result)
190
+ return list(result.keys())
191
+
192
+ def longest_common_prefix(self) -> str:
193
+ """Find longest common prefix of all keys."""
194
+ if not self._root.children:
195
+ return ""
196
+
197
+ prefix = ""
198
+ node = self._root
199
+
200
+ while len(node.children) == 1 and not node.is_end_of_word:
201
+ char = list(node.children.keys())[0]
202
+ prefix += char
203
+ node = node.children[char]
204
+
205
+ return prefix
206
+
207
+ def keys_with_prefix(self, prefix: str) -> List[str]:
208
+ """Get all keys with given prefix."""
209
+ return self.prefix_search(prefix)
210
+
211
+ def keys_with_suffix(self, suffix: str) -> List[str]:
212
+ """Get all keys with given suffix."""
213
+ # TODO: Implement suffix search
214
+ return []
215
+
216
+ # ============================================================================
217
+ # ITERATION
218
+ # ============================================================================
219
+
220
+ def keys(self) -> Iterator[str]:
221
+ """Get all keys."""
222
+ result = {}
223
+ self._collect_words(self._root, "", result)
224
+ return iter(result.keys())
225
+
226
+ def values(self) -> Iterator[Any]:
227
+ """Get all values."""
228
+ result = {}
229
+ self._collect_words(self._root, "", result)
230
+ return iter(result.values())
231
+
232
+ def items(self) -> Iterator[tuple[str, Any]]:
233
+ """Get all key-value pairs."""
234
+ result = {}
235
+ self._collect_words(self._root, "", result)
236
+ return iter(result.items())
237
+
238
+ # ============================================================================
239
+ # PERFORMANCE CHARACTERISTICS
240
+ # ============================================================================
241
+
242
+ @property
243
+ def backend_info(self) -> Dict[str, Any]:
244
+ """Get backend implementation info."""
245
+ return {
246
+ 'strategy': 'TRIE',
247
+ 'backend': 'Trie tree',
248
+ 'complexity': {
249
+ 'insert': 'O(m)',
250
+ 'search': 'O(m)',
251
+ 'delete': 'O(m)',
252
+ 'prefix_search': 'O(m + k)',
253
+ 'space': 'O(ALPHABET_SIZE * N * M)'
254
+ }
255
+ }
256
+
257
+ @property
258
+ def metrics(self) -> Dict[str, Any]:
259
+ """Get performance metrics."""
260
+ return {
261
+ 'size': self._size,
262
+ 'memory_usage': f"{self._size * 32} bytes (estimated)",
263
+ 'height': self._get_height()
264
+ }
265
+
266
+ def _get_height(self) -> int:
267
+ """Get height of trie."""
268
+ return self._height_helper(self._root)
269
+
270
+ def _height_helper(self, node: TrieNode) -> int:
271
+ """Helper for height calculation."""
272
+ if not node.children:
273
+ return 0
274
+ return 1 + max(self._height_helper(child) for child in node.children.values())
@@ -0,0 +1,283 @@
1
+ """
2
+ Union-Find Node Strategy Implementation
3
+
4
+ This module implements the UNION_FIND strategy for efficient set operations.
5
+ """
6
+
7
+ from typing import Any, Iterator, Dict, List, Set
8
+ from .base import ANodeGraphStrategy
9
+ from ...types import NodeMode, NodeTrait
10
+
11
+
12
+ class UnionFind:
13
+ """Union-Find data structure."""
14
+
15
+ def __init__(self):
16
+ self.parent: Dict[str, str] = {}
17
+ self.rank: Dict[str, int] = {}
18
+ self.values: Dict[str, Any] = {}
19
+
20
+ def make_set(self, x: str, value: Any = None) -> None:
21
+ """Make a new set containing x."""
22
+ if x not in self.parent:
23
+ self.parent[x] = x
24
+ self.rank[x] = 0
25
+ self.values[x] = value
26
+
27
+ def find(self, x: str) -> str:
28
+ """Find the root of the set containing x."""
29
+ if x not in self.parent:
30
+ return x
31
+
32
+ if self.parent[x] != x:
33
+ self.parent[x] = self.find(self.parent[x]) # Path compression
34
+ return self.parent[x]
35
+
36
+ def union(self, x: str, y: str) -> bool:
37
+ """Union the sets containing x and y."""
38
+ root_x = self.find(x)
39
+ root_y = self.find(y)
40
+
41
+ if root_x == root_y:
42
+ return False # Already in same set
43
+
44
+ # Union by rank
45
+ if self.rank[root_x] < self.rank[root_y]:
46
+ self.parent[root_x] = root_y
47
+ elif self.rank[root_x] > self.rank[root_y]:
48
+ self.parent[root_y] = root_x
49
+ else:
50
+ self.parent[root_y] = root_x
51
+ self.rank[root_x] += 1
52
+
53
+ return True
54
+
55
+ def connected(self, x: str, y: str) -> bool:
56
+ """Check if x and y are in the same set."""
57
+ return self.find(x) == self.find(y)
58
+
59
+ def get_set_members(self, x: str) -> Set[str]:
60
+ """Get all members of the set containing x."""
61
+ root = self.find(x)
62
+ return {member for member in self.parent.keys() if self.find(member) == root}
63
+
64
+ def get_all_sets(self) -> List[Set[str]]:
65
+ """Get all disjoint sets."""
66
+ roots = set(self.find(x) for x in self.parent.keys())
67
+ return [self.get_set_members(root) for root in roots]
68
+
69
+ def get_set_count(self) -> int:
70
+ """Get the number of disjoint sets."""
71
+ roots = set(self.find(x) for x in self.parent.keys())
72
+ return len(roots)
73
+
74
+ def get_set_size(self, x: str) -> int:
75
+ """Get the size of the set containing x."""
76
+ return len(self.get_set_members(x))
77
+
78
+
79
+ class xUnionFindStrategy(ANodeGraphStrategy):
80
+ """
81
+ Union-Find node strategy for efficient set operations.
82
+
83
+ Optimized for union, find, and connected operations on disjoint sets.
84
+ """
85
+
86
+ def __init__(self, traits: NodeTrait = NodeTrait.NONE, **options):
87
+ """Initialize the union-find strategy."""
88
+ super().__init__(data=None, **options)
89
+ self._mode = NodeMode.UNION_FIND
90
+ self._traits = traits
91
+ self._union_find = UnionFind()
92
+ self._size = 0
93
+
94
+ def get_supported_traits(self) -> NodeTrait:
95
+ """Get the traits supported by the union-find strategy."""
96
+ return (NodeTrait.SET_OPERATIONS | NodeTrait.HIERARCHICAL)
97
+
98
+ # ============================================================================
99
+ # CORE OPERATIONS
100
+ # ============================================================================
101
+
102
+ def insert(self, key: Any, value: Any) -> None:
103
+ """Store a key-value pair (creates a new set)."""
104
+ str_key = str(key)
105
+ if str_key not in self._union_find.parent:
106
+ self._size += 1
107
+ self._union_find.make_set(str_key, value)
108
+
109
+ def find(self, key: Any) -> Any:
110
+ """Find the root of the set containing key."""
111
+ str_key = str(key)
112
+ root = self._union_find.find(str_key)
113
+ return self._union_find.values.get(root)
114
+
115
+ def delete(self, key: Any) -> bool:
116
+ """Delete a key (not supported in union-find)."""
117
+ # Union-Find doesn't support deletion efficiently
118
+ return False
119
+
120
+ def size(self) -> int:
121
+ """Get the number of elements."""
122
+ return self._size
123
+
124
+ def is_empty(self) -> bool:
125
+ """Check if the structure is empty."""
126
+ return self._size == 0
127
+
128
+ def to_native(self) -> Dict[str, Any]:
129
+ """Convert to native Python dictionary."""
130
+ return self._union_find.values.copy()
131
+
132
+ # ============================================================================
133
+ # GRAPH STRATEGY METHODS
134
+ # ============================================================================
135
+
136
+ def add_edge(self, from_node: Any, to_node: Any, weight: float = 1.0) -> None:
137
+ """Add edge between nodes (union operation)."""
138
+ str_from = str(from_node)
139
+ str_to = str(to_node)
140
+
141
+ # Make sure both nodes exist
142
+ if str_from not in self._union_find.parent:
143
+ self._union_find.make_set(str_from)
144
+ self._size += 1
145
+ if str_to not in self._union_find.parent:
146
+ self._union_find.make_set(str_to)
147
+ self._size += 1
148
+
149
+ # Union the sets
150
+ self._union_find.union(str_from, str_to)
151
+
152
+ def remove_edge(self, from_node: Any, to_node: Any) -> bool:
153
+ """Remove edge between nodes (not supported in union-find)."""
154
+ # Union-Find doesn't support edge removal efficiently
155
+ return False
156
+
157
+ def has_edge(self, from_node: Any, to_node: Any) -> bool:
158
+ """Check if edge exists (connected operation)."""
159
+ str_from = str(from_node)
160
+ str_to = str(to_node)
161
+
162
+ if str_from not in self._union_find.parent or str_to not in self._union_find.parent:
163
+ return False
164
+
165
+ return self._union_find.connected(str_from, str_to)
166
+
167
+ def find_path(self, start: Any, end: Any) -> List[Any]:
168
+ """Find path between nodes."""
169
+ if self.has_edge(start, end):
170
+ return [start, end]
171
+ return []
172
+
173
+ def get_neighbors(self, node: Any) -> List[Any]:
174
+ """Get neighboring nodes (all nodes in same set)."""
175
+ str_node = str(node)
176
+ if str_node not in self._union_find.parent:
177
+ return []
178
+
179
+ members = self._union_find.get_set_members(str_node)
180
+ return [member for member in members if member != str_node]
181
+
182
+ def get_edge_weight(self, from_node: Any, to_node: Any) -> float:
183
+ """Get edge weight (always 1.0 for union-find)."""
184
+ return 1.0 if self.has_edge(from_node, to_node) else 0.0
185
+
186
+ # ============================================================================
187
+ # AUTO-3 Phase 3&4 methods
188
+ # ============================================================================
189
+
190
+ def as_union_find(self):
191
+ """Provide Union-Find behavioral view."""
192
+ return self
193
+
194
+ def as_neural_graph(self):
195
+ """Provide Neural Graph behavioral view."""
196
+ # TODO: Implement Neural Graph view
197
+ return self
198
+
199
+ def as_flow_network(self):
200
+ """Provide Flow Network behavioral view."""
201
+ # TODO: Implement Flow Network view
202
+ return self
203
+
204
+ # ============================================================================
205
+ # UNION-FIND SPECIFIC OPERATIONS
206
+ # ============================================================================
207
+
208
+ def make_set(self, element: str, value: Any = None) -> None:
209
+ """Make a new set containing element."""
210
+ if element not in self._union_find.parent:
211
+ self._size += 1
212
+ self._union_find.make_set(element, value)
213
+
214
+ def find_root(self, element: str) -> str:
215
+ """Find the root of the set containing element."""
216
+ return self._union_find.find(element)
217
+
218
+ def union_sets(self, element1: str, element2: str) -> bool:
219
+ """Union the sets containing element1 and element2."""
220
+ return self._union_find.union(element1, element2)
221
+
222
+ def connected(self, element1: str, element2: str) -> bool:
223
+ """Check if element1 and element2 are in the same set."""
224
+ return self._union_find.connected(element1, element2)
225
+
226
+ def get_set_members(self, element: str) -> Set[str]:
227
+ """Get all members of the set containing element."""
228
+ return self._union_find.get_set_members(element)
229
+
230
+ def get_all_sets(self) -> List[Set[str]]:
231
+ """Get all disjoint sets."""
232
+ return self._union_find.get_all_sets()
233
+
234
+ def get_set_count(self) -> int:
235
+ """Get the number of disjoint sets."""
236
+ return self._union_find.get_set_count()
237
+
238
+ def get_set_size(self, element: str) -> int:
239
+ """Get the size of the set containing element."""
240
+ return self._union_find.get_set_size(element)
241
+
242
+ # ============================================================================
243
+ # ITERATION
244
+ # ============================================================================
245
+
246
+ def keys(self) -> Iterator[str]:
247
+ """Get all elements."""
248
+ return iter(self._union_find.parent.keys())
249
+
250
+ def values(self) -> Iterator[Any]:
251
+ """Get all values."""
252
+ return iter(self._union_find.values.values())
253
+
254
+ def items(self) -> Iterator[tuple[str, Any]]:
255
+ """Get all element-value pairs."""
256
+ return iter(self._union_find.values.items())
257
+
258
+ # ============================================================================
259
+ # PERFORMANCE CHARACTERISTICS
260
+ # ============================================================================
261
+
262
+ @property
263
+ def backend_info(self) -> Dict[str, Any]:
264
+ """Get backend implementation info."""
265
+ return {
266
+ 'strategy': 'UNION_FIND',
267
+ 'backend': 'Union-Find with path compression',
268
+ 'complexity': {
269
+ 'make_set': 'O(1)',
270
+ 'find': 'O(α(n))',
271
+ 'union': 'O(α(n))',
272
+ 'connected': 'O(α(n))'
273
+ }
274
+ }
275
+
276
+ @property
277
+ def metrics(self) -> Dict[str, Any]:
278
+ """Get performance metrics."""
279
+ return {
280
+ 'elements': self._size,
281
+ 'sets': self._union_find.get_set_count(),
282
+ 'memory_usage': f"{self._size * 32} bytes (estimated)"
283
+ }