cbrkit 0.26.3__tar.gz → 0.26.4__tar.gz
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.
- {cbrkit-0.26.3 → cbrkit-0.26.4}/PKG-INFO +1 -1
- {cbrkit-0.26.3 → cbrkit-0.26.4}/pyproject.toml +1 -1
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/sim/graphs/astar.py +74 -46
- {cbrkit-0.26.3 → cbrkit-0.26.4}/README.md +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/__init__.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/__main__.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/adapt/__init__.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/adapt/attribute_value.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/adapt/generic.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/adapt/numbers.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/adapt/strings.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/api.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/cli.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/constants.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/cycle.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/dumpers.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/eval/__init__.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/eval/common.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/eval/retrieval.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/helpers.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/loaders.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/model/__init__.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/model/graph.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/model/result.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/py.typed +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/retrieval/__init__.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/retrieval/apply.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/retrieval/build.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/retrieval/rerank.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/reuse/__init__.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/reuse/apply.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/reuse/build.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/sim/__init__.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/sim/aggregator.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/sim/attribute_value.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/sim/collections.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/sim/embed.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/sim/generic.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/sim/graphs/__init__.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/sim/graphs/alignment.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/sim/graphs/brute_force.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/sim/graphs/common.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/sim/graphs/dfs.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/sim/graphs/greedy.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/sim/graphs/lap.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/sim/graphs/precompute.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/sim/graphs/qap.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/sim/graphs/vf2.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/sim/numbers.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/sim/strings.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/sim/taxonomy.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/sim/wrappers.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/synthesis/__init__.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/synthesis/apply.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/synthesis/build.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/synthesis/model.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/synthesis/prompts.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/synthesis/providers/__init__.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/synthesis/providers/anthropic.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/synthesis/providers/cohere.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/synthesis/providers/google.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/synthesis/providers/instructor.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/synthesis/providers/model.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/synthesis/providers/ollama.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/synthesis/providers/openai.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/synthesis/providers/wrappers.py +0 -0
- {cbrkit-0.26.3 → cbrkit-0.26.4}/src/cbrkit/typing.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: cbrkit
|
|
3
|
-
Version: 0.26.
|
|
3
|
+
Version: 0.26.4
|
|
4
4
|
Summary: Customizable Case-Based Reasoning (CBR) toolkit for Python with a built-in API and CLI
|
|
5
5
|
Keywords: cbr,case-based reasoning,api,similarity,nlp,retrieval,cli,tool,library
|
|
6
6
|
Author: Mirko Lenz
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import heapq
|
|
2
|
-
from collections.abc import Mapping
|
|
2
|
+
from collections.abc import Collection, Mapping
|
|
3
3
|
from dataclasses import dataclass, field
|
|
4
|
-
from typing import Protocol
|
|
4
|
+
from typing import Any, Protocol, cast
|
|
5
5
|
|
|
6
6
|
from ...helpers import (
|
|
7
7
|
get_logger,
|
|
@@ -34,6 +34,33 @@ __all__ = [
|
|
|
34
34
|
logger = get_logger(__name__)
|
|
35
35
|
|
|
36
36
|
|
|
37
|
+
def next_elem[K](elements: Collection[K]) -> K:
|
|
38
|
+
"""Select the next element from a set deterministically.
|
|
39
|
+
|
|
40
|
+
If elements are sortable, returns the smallest one.
|
|
41
|
+
Otherwise, returns the first element from iteration.
|
|
42
|
+
|
|
43
|
+
Args:
|
|
44
|
+
elements: Set of elements to choose from
|
|
45
|
+
|
|
46
|
+
Returns:
|
|
47
|
+
A single element from the set
|
|
48
|
+
|
|
49
|
+
Raises:
|
|
50
|
+
ValueError: If the set is empty
|
|
51
|
+
"""
|
|
52
|
+
if not elements:
|
|
53
|
+
raise ValueError("Cannot select from empty set")
|
|
54
|
+
|
|
55
|
+
if len(elements) == 1:
|
|
56
|
+
return next(iter(elements))
|
|
57
|
+
|
|
58
|
+
try:
|
|
59
|
+
return min(cast(Collection[Any], elements))
|
|
60
|
+
except TypeError:
|
|
61
|
+
return next(iter(elements))
|
|
62
|
+
|
|
63
|
+
|
|
37
64
|
@dataclass(slots=True, frozen=True, order=True)
|
|
38
65
|
class PriorityState[K]:
|
|
39
66
|
priority: float
|
|
@@ -157,15 +184,11 @@ class select1[K, N, E, G](SelectionFunc[K, N, E, G]):
|
|
|
157
184
|
) -> None | tuple[K, GraphElementType]:
|
|
158
185
|
"""Select the next node or edge to be mapped"""
|
|
159
186
|
|
|
160
|
-
|
|
161
|
-
return
|
|
162
|
-
except StopIteration:
|
|
163
|
-
pass
|
|
187
|
+
if s.open_y_nodes:
|
|
188
|
+
return next_elem(s.open_y_nodes), "node"
|
|
164
189
|
|
|
165
|
-
|
|
166
|
-
return
|
|
167
|
-
except StopIteration:
|
|
168
|
-
pass
|
|
190
|
+
if s.open_y_edges:
|
|
191
|
+
return next_elem(s.open_y_edges), "edge"
|
|
169
192
|
|
|
170
193
|
return None
|
|
171
194
|
|
|
@@ -182,20 +205,18 @@ class select2[K, N, E, G](SelectionFunc[K, N, E, G]):
|
|
|
182
205
|
) -> None | tuple[K, GraphElementType]:
|
|
183
206
|
"""Select the next node or edge to be mapped"""
|
|
184
207
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
), "edge"
|
|
192
|
-
except StopIteration:
|
|
193
|
-
pass
|
|
208
|
+
edge_candidates = {
|
|
209
|
+
key
|
|
210
|
+
for key in s.open_y_edges
|
|
211
|
+
if y.edges[key].source.key not in s.open_y_nodes
|
|
212
|
+
and y.edges[key].target.key not in s.open_y_nodes
|
|
213
|
+
}
|
|
194
214
|
|
|
195
|
-
|
|
196
|
-
return
|
|
197
|
-
|
|
198
|
-
|
|
215
|
+
if edge_candidates:
|
|
216
|
+
return next_elem(edge_candidates), "edge"
|
|
217
|
+
|
|
218
|
+
if s.open_y_nodes:
|
|
219
|
+
return next_elem(s.open_y_nodes), "node"
|
|
199
220
|
|
|
200
221
|
return None
|
|
201
222
|
|
|
@@ -246,19 +267,36 @@ class select3[K, N, E, G](SelectionFunc[K, N, E, G]):
|
|
|
246
267
|
|
|
247
268
|
if not heuristic_scores:
|
|
248
269
|
# Fallback: select any remaining node or edge for null mapping
|
|
270
|
+
# Use sorted to ensure deterministic selection
|
|
249
271
|
if s.open_y_nodes:
|
|
250
|
-
return
|
|
272
|
+
return next_elem(s.open_y_nodes), "node"
|
|
251
273
|
elif s.open_y_edges:
|
|
252
|
-
return
|
|
274
|
+
return next_elem(s.open_y_edges), "edge"
|
|
253
275
|
return None
|
|
254
276
|
|
|
277
|
+
# Find the maximum heuristic score
|
|
255
278
|
max_score = max(heuristic_scores.values())
|
|
256
|
-
best_selections =
|
|
279
|
+
best_selections = {
|
|
257
280
|
key for key, value in heuristic_scores.items() if value == max_score
|
|
258
|
-
|
|
281
|
+
}
|
|
259
282
|
|
|
260
283
|
# if multiple selections have the same score, select the one with the lowest number of possible mappings
|
|
261
|
-
|
|
284
|
+
if len(best_selections) > 1:
|
|
285
|
+
min_mapping_options = min(mapping_options[key] for key in best_selections)
|
|
286
|
+
best_selections = {
|
|
287
|
+
key
|
|
288
|
+
for key in best_selections
|
|
289
|
+
if mapping_options[key] == min_mapping_options
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
# select the one with the lowest key
|
|
293
|
+
try:
|
|
294
|
+
best_selection = min(
|
|
295
|
+
best_selections,
|
|
296
|
+
key=lambda item: cast(Any, item[0]),
|
|
297
|
+
)
|
|
298
|
+
except TypeError:
|
|
299
|
+
best_selection = next(iter(best_selections))
|
|
262
300
|
|
|
263
301
|
selection_key, selection_type = best_selection
|
|
264
302
|
|
|
@@ -290,7 +328,7 @@ class build[K, N, E, G](
|
|
|
290
328
|
beam_width: Limits the queue size which prunes the search space.
|
|
291
329
|
This leads to a faster search and less memory usage but also introduces a similarity error.
|
|
292
330
|
Disabled by default. Based on [Neuhaus et al. (2006)](https://doi.org/10.1007/11815921_17).
|
|
293
|
-
pathlength_weight:
|
|
331
|
+
pathlength_weight: Favor long partial edit paths over shorter ones.
|
|
294
332
|
Disabled by default. Based on [Neuhaus et al. (2006)](https://doi.org/10.1007/11815921_17).
|
|
295
333
|
|
|
296
334
|
Returns:
|
|
@@ -356,22 +394,11 @@ class build[K, N, E, G](
|
|
|
356
394
|
prio = 1 - (past_sim + future_sim)
|
|
357
395
|
|
|
358
396
|
if self.pathlength_weight > 0:
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
edge_null_mapping = (
|
|
365
|
-
set(y.edges.keys())
|
|
366
|
-
- set(state.edge_mapping.keys())
|
|
367
|
-
- set(state.open_y_edges)
|
|
368
|
-
)
|
|
369
|
-
num_paths = (
|
|
370
|
-
len(state.node_mapping)
|
|
371
|
-
+ len(state.edge_mapping)
|
|
372
|
-
+ len(node_null_mapping)
|
|
373
|
-
+ len(edge_null_mapping)
|
|
374
|
-
)
|
|
397
|
+
# Calculate the number of mapping decisions made so far (partial edit path length)
|
|
398
|
+
# This includes actual mappings plus null mappings (elements processed but not mapped)
|
|
399
|
+
total_y_elements = len(y.nodes) + len(y.edges)
|
|
400
|
+
open_y_elements = len(state.open_y_nodes) + len(state.open_y_edges)
|
|
401
|
+
num_paths = total_y_elements - open_y_elements
|
|
375
402
|
return prio / (self.pathlength_weight**num_paths)
|
|
376
403
|
|
|
377
404
|
return prio
|
|
@@ -432,7 +459,8 @@ class build[K, N, E, G](
|
|
|
432
459
|
heapq.heappush(open_set, PriorityState(next_prio, next_state))
|
|
433
460
|
|
|
434
461
|
if self.beam_width > 0 and len(open_set) > self.beam_width:
|
|
435
|
-
open_set =
|
|
462
|
+
open_set = heapq.nsmallest(self.beam_width, open_set)
|
|
463
|
+
heapq.heapify(open_set)
|
|
436
464
|
|
|
437
465
|
return self.similarity(
|
|
438
466
|
x,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|