From 6d3719e1619786f70aaaa1b8d3410c0c6368272d Mon Sep 17 00:00:00 2001 From: NoR8quoh1r <20768237+NoR8quoh1r@users.noreply.github.com> Date: Fri, 15 Nov 2024 11:28:58 +0100 Subject: [PATCH] make CachePicker work with solver --- src/faebryk/libs/picker/common.py | 30 +++++++++++++++++++----------- src/faebryk/libs/picker/picker.py | 8 ++------ 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/faebryk/libs/picker/common.py b/src/faebryk/libs/picker/common.py index bfd81dd4..0eee1829 100644 --- a/src/faebryk/libs/picker/common.py +++ b/src/faebryk/libs/picker/common.py @@ -9,7 +9,7 @@ import faebryk.library._F as F from faebryk.core.module import Module -from faebryk.core.parameter import Parameter +from faebryk.core.parameter import And, Is, Parameter, ParameterOperatable, Predicate from faebryk.core.solver import Solver from faebryk.libs.picker.jlcpcb.jlcpcb import Component from faebryk.libs.picker.lcsc import attach @@ -82,8 +82,9 @@ def pick(self, module: Module): ) from e -def _try_merge_params(target: Module, source: Module, solver: Solver) -> bool: - raise NotImplementedError +def _build_compatible_constraint( + target: Module, source: Module +) -> ParameterOperatable.BooleanLike: assert type(target) is type(source) # Override module parameters with picked component parameters @@ -92,14 +93,23 @@ def _try_merge_params(target: Module, source: Module, solver: Solver) -> bool: ) # sort by type to avoid merge conflicts + predicates: list[Predicate] = [] it = module_params.values() for p, value in it: - if not value.is_subset_of(p): - return False - for p, value in it: - p.alias_is(value) + predicates.append(Is(p, value)) + + return And(*predicates) - return True + +def _get_compatible_modules( + module: Module, cache: list[Module], solver: Solver +) -> Iterable[Module]: + compatible_constraints = [_build_compatible_constraint(module, m) for m in cache] + solve_result = solver.assert_any_predicate( + list(zip(compatible_constraints, cache)), lock=True + ) + for _, m in solve_result.true_predicates: + yield m class CachePicker(F.has_multi_picker.Picker): @@ -109,9 +119,7 @@ def __init__(self): def pick(self, module: Module, solver: Solver): mcache = [m for m in self.cache[type(module)] if m.has_trait(has_part_picked)] - for m in mcache: - if not _try_merge_params(module, m, solver): - continue + for m in _get_compatible_modules(module, mcache, solver): logger.debug(f"Found compatible part in cache: {module} with {m}") module.add( F.has_descriptive_properties_defined( diff --git a/src/faebryk/libs/picker/picker.py b/src/faebryk/libs/picker/picker.py index d187113d..45322bde 100644 --- a/src/faebryk/libs/picker/picker.py +++ b/src/faebryk/libs/picker/picker.py @@ -15,7 +15,7 @@ import faebryk.library._F as F from faebryk.core.module import Module from faebryk.core.moduleinterface import ModuleInterface -from faebryk.core.parameter import Is, Parameter, ParameterOperatable, Predicate +from faebryk.core.parameter import And, Is, Parameter, ParameterOperatable, Predicate from faebryk.core.solver import Solver from faebryk.libs.util import flatten, not_none @@ -183,11 +183,7 @@ def pick_module_by_params( predicates[o] = True continue - anded = predicate_list[0] - for p in predicate_list[1:]: - anded = anded.operation_and(p) - - predicates[o] = anded + predicates[o] = And(*predicate_list) if len(predicates) == 0: raise PickErrorParams(module, list(options))