99 std::optional<Portal::Graphics::ShaderSpec>
gpu_spec;
107 std::chrono::milliseconds max_execution_time { 0 };
110 std::type_index target_operation_type = std::type_index(
typeid(
void));
126 std::string rule_name = rule.
name;
129 auto insert_pos = std::ranges::upper_bound(m_rules, rule,
131 m_rules.insert(insert_pos, std::move(rule));
133 m_context_index[rule_context].push_back(rule_name);
151 for (
const auto& rule : m_rules) {
152 if (rule.matcher(
input, context)) {
174 const std::any&
input,
177 auto it = std::ranges::find_if(m_rules,
178 [&rule_name](
const Rule& rule) {
return rule.
name == rule_name; });
180 if (it != m_rules.end() && it->matcher(
input, context)) {
181 return it->executor(
input, context);
197 auto it = m_context_index.find(context);
198 return it != m_context_index.end() ? it->second : std::vector<std::string> {};
216 template <
typename OperationType>
219 std::vector<std::string> matching_rules;
222 for (
const auto& rule : m_rules) {
223 if (rule.target_operation_type == target_type) {
224 matching_rules.push_back(rule.name);
227 return matching_rules;
263 template <
typename ConcreteOpType,
typename... OpArgs>
267 const std::unordered_map<std::string, std::any>& op_parameters = {},
272 rule.name = rule_name;
273 rule.context = context;
274 rule.priority = priority;
275 rule.matcher = std::move(matcher);
276 rule.target_operation_type = std::type_index(
typeid(ConcreteOpType));
278 auto captured_args = std::make_tuple(std::forward<OpArgs>(op_args)...);
280 rule.executor = [op_parameters, captured_args = std::move(captured_args)](
const std::any&
input,
const ExecutionContext& ctx) -> std::any {
281 auto operation = std::apply([&op_parameters](
auto&&... args) {
282 return create_configured_operation<ConcreteOpType>(op_parameters, std::forward<
decltype(args)>(args)...);
286 apply_context_parameters(operation, ctx);
288 auto typed_input = safe_any_cast_or_throw<DataIO>(
input);
289 return operation->apply_operation(typed_input);
292 add_rule(std::move(rule));
333 m_rule.
name = std::move(name);
378 template <ComputeData DataType>
381 m_rule.
matcher = UniversalMatcher::create_type_matcher<DataType>();
396 m_rule.
matcher = std::move(matcher);
415 template <
typename Func>
420 m_rule.
executor = [func = std::forward<Func>(executor), spec = std::move(spec)](
425 if (cfg.shader_id != Portal::Graphics::INVALID_SHADER) {
426 auto gpu_exec = std::make_shared<ShaderExecutionContext<>>(cfg, bindings);
429 return func(
input, patched);
431 return func(
input, ctx);
434 m_rule.
executor = [func = std::forward<Func>(executor)](
436 return func(
input, ctx);
450 template <
typename OperationType>
468 m_rule.
tags = std::move(tags);
502 m_grammar->
add_rule(std::move(m_rule));
541 std::vector<std::string> names;
542 names.reserve(m_rules.size());
543 std::ranges::transform(m_rules, std::back_inserter(names),
544 [](
const Rule& rule) {
return rule.
name; });
553 [[nodiscard]]
bool has_rule(
const std::string& rule_name)
const
555 return std::ranges::any_of(m_rules,
556 [&rule_name](
const Rule& rule) {
return rule.
name == rule_name; });
569 auto it = std::ranges::find_if(m_rules,
570 [&rule_name](
const Rule& rule) {
return rule.
name == rule_name; });
572 if (it != m_rules.end()) {
576 auto& context_rules = m_context_index[context];
577 std::erase_if(context_rules,
578 [&](
const std::string& name) {
579 return name == rule_name;
596 m_context_index.clear();
Core::GlobalInputConfig input
void build()
Finalizes and adds the rule to the grammar.
RuleBuilder(ComputationGrammar *grammar, std::string name)
Constructs a RuleBuilder for the specified grammar.
RuleBuilder & with_context(ComputationContext context)
Sets the computation context for this rule.
RuleBuilder & matches_type()
Sets the matcher to check for a specific data type.
RuleBuilder & with_gpu_backend(Portal::Graphics::ShaderSpec spec)
Attach a ShaderSpec GPU backend to this rule.
ComputationGrammar * m_grammar
Reference to parent grammar.
RuleBuilder & executes(Func &&executor)
Sets the executor function for this rule.
Rule m_rule
Rule being constructed.
RuleBuilder & with_tags(std::vector< std::string > tags)
Sets arbitrary tags for this rule.
RuleBuilder & matches_custom(UniversalMatcher::MatcherFunc matcher)
Sets a custom matcher function.
RuleBuilder & with_priority(int priority)
Sets the execution priority for this rule.
RuleBuilder & with_description(std::string description)
Sets a human-readable description for this rule.
RuleBuilder & targets_operation()
Sets the target operation type for this rule.
Fluent interface for building rules with method chaining.
bool remove_rule(const std::string &rule_name)
Remove a rule by name.
RuleBuilder create_rule(const std::string &name)
Create a rule builder for fluent rule construction.
std::unordered_map< ComputationContext, std::vector< std::string > > m_context_index
Index of rule names by context for fast lookup.
std::optional< Rule > find_best_match(const std::any &input, const ExecutionContext &context) const
Find the best matching rule for the given input.
std::vector< std::string > get_rules_for_operation_type() const
Get rules that target a specific operation type.
size_t get_rule_count() const
Get the total number of rules in the grammar.
void clear_all_rules()
Clear all rules from the grammar.
std::vector< std::string > get_all_rule_names() const
Get all rule names in the grammar.
std::vector< std::string > get_rules_by_context(ComputationContext context) const
Get all rule names for a specific computation context.
bool has_rule(const std::string &rule_name) const
Check if a rule with the given name exists.
void add_operation_rule(const std::string &rule_name, ComputationContext context, UniversalMatcher::MatcherFunc matcher, const std::unordered_map< std::string, std::any > &op_parameters={}, int priority=50, OpArgs &&... op_args)
Helper to add concrete operation rules with automatic executor generation.
std::optional< std::any > execute_rule(const std::string &rule_name, const std::any &input, const ExecutionContext &context) const
Execute a specific rule by name.
void add_rule(Rule rule)
Add a rule to the grammar.
std::vector< Rule > m_rules
All rules sorted by priority (highest first)
Core grammar system for rule-based computation in Maya Flux.
std::function< bool(const std::any &, const ExecutionContext &)> MatcherFunc
ComputationContext
Defines the computational contexts in which rules can be applied.
OperationType
Operation categories for organization and discovery.
ExecutionMode
Execution paradigms for operations.
GpuComputeConfig config_from_spec(const Portal::Graphics::ShaderSpec &spec)
Derive a GpuComputeConfig from a ShaderSpec.
std::vector< GpuBufferBinding > bindings_from_spec(const Portal::Graphics::ShaderSpec &spec)
Derive a GpuBufferBinding list from a ShaderSpec.
Complete declarative description of a generated compute shader.
std::optional< Portal::Graphics::ShaderSpec > gpu_spec
When set, executor receives a GPU-backed operation.
ComputationContext context
Computational context this rule operates in.
std::type_index target_operation_type
Type of operation this rule creates (for type-based queries)
int priority
Execution priority (higher values evaluated first)
std::unordered_map< std::string, std::any > default_parameters
Default parameters for the rule's operation.
Executor executor
Function that performs the computation.
std::string description
Human-readable description of what the rule does.
std::string name
Unique identifier for this rule.
std::vector< std::string > tags
Arbitrary tags for categorization and search.
std::vector< std::string > dependencies
Names of rules that must execute before this one.
UniversalMatcher::MatcherFunc matcher
Function that determines if rule applies.
std::function< std::any(const std::any &, const ExecutionContext &)> Executor
Type alias for matcher functions used in computation rules.
Represents a computation rule with matching and execution logic.
std::unordered_map< std::string, std::any > execution_metadata
Arbitrary metadata parameters used by operations.
Context information controlling how a compute operation executes.