Class: Musa::Rules::Rules

Inherits:
Object show all
Includes:
Extension::With
Defined in:
lib/musa-dsl/generative/rules.rb

Overview

Rule-based generator with growth and pruning.

Applies grow/cut rules to generate tree of valid possibilities.

Instance Method Summary collapse

Constructor Details

#initialize { ... } ⇒ void

Creates rule system with defined rules.

Examples:

rules = Rules.new do
  grow 'generate' { |obj| branch new_obj }
  cut 'validate' { |obj| prune if invalid?(obj) }
  ended_when { |obj| complete?(obj) }
end

Yields:

  • rule definition DSL block

Yield Returns:

  • (void)


154
155
156
# File 'lib/musa-dsl/generative/rules.rb', line 154

def initialize(&block)
  @dsl = RulesEvalContext.new(&block)
end

Instance Method Details

#apply(object_or_list, node = nil, **parameters) ⇒ Node

Applies rules to seed objects sequentially.

Processes list of seed objects in sequence, generating possibilities from each confirmed endpoint of previous seed. Returns tree of all valid combination paths.

Examples:

Single seed

tree = rules.apply(:I)
tree.combinations  # => [[:I, :ii, :V, :I], ...]

Multiple seeds

tree = rules.apply([:I, :ii, :V])
tree.combinations  # => combinations starting from each seed

Parameters:

  • object_or_list (Object, Array)

    seed object(s) to process

  • node (Node, nil) (defaults to: nil)

    root node (creates if nil)

  • parameters (Hash)

    additional parameters for rules

Returns:

  • (Node)

    root node with all combination paths



228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
# File 'lib/musa-dsl/generative/rules.rb', line 228

def apply(object_or_list, node = nil, **parameters)
  list = object_or_list.arrayfy.clone

  node ||= Node.new

  seed = list.shift

  if seed
    result = generate_possibilities seed, node, **parameters

    fished = result.fish

    node.reject! 'All children are rejected' if fished.empty?

    fished.each do |object|
      subnode = node.add(object).mark_as_ended!
      apply list, subnode, **parameters
    end
  end

  node
end

#generate_possibilities(object, confirmed_node = nil, node = nil, grow_rules = nil, **parameters) ⇒ Node

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Generates possibility tree from object.

Recursively applies grow rules to create branches, cut rules to prune invalid paths, and end conditions to mark complete branches.

Parameters:

  • object (Object)

    object to expand

  • confirmed_node (Node, nil) (defaults to: nil)

    confirmed parent node (for history)

  • node (Node, nil) (defaults to: nil)

    current node being built

  • grow_rules (Array<GrowRule>, nil) (defaults to: nil)

    rules to apply

  • parameters (Hash)

    additional parameters for rules

Returns:

  • (Node)

    root node of possibility tree



172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
# File 'lib/musa-dsl/generative/rules.rb', line 172

def generate_possibilities(object, confirmed_node = nil, node = nil, grow_rules = nil, **parameters)
  node ||= Node.new
  grow_rules ||= @dsl._grow_rules

  history = confirmed_node.history if confirmed_node
  history ||= []

  grow_rules = grow_rules.clone
  grow_rule = grow_rules.shift

  if grow_rule
    grow_rule.generate_possibilities(object, history, **parameters).each do |new_object|
      new_node = Node.new new_object, node
      if @dsl._has_ending? && @dsl._ended?(new_object, history, **parameters) ||
        !@dsl._has_ending? && grow_rules.empty?

        new_node.mark_as_ended!
      end

      rejection = @dsl._cut_rules.find { |cut_rule| cut_rule.rejects?(new_object, history, **parameters) }
      # TODO: include rejection secondary reasons in rejection message

      new_node.reject! rejection if rejection

      node.children << new_node
    end
  end

  unless grow_rules.empty?
    node.children.each do |node|
      generate_possibilities node.object, confirmed_node, node, grow_rules, **parameters unless node.rejected || node.ended?
    end
  end

  node
end

#with(*value_parameters, keep_block_context: nil, **key_parameters, &block) ⇒ Object Originally defined in module Extension::With

Note:

The _ parameter is special: when present, it signals "keep caller's context" and receives self (the object) as its value.

Note:

Uses SmartProcBinder internally to handle parameter matching.

Executes a block with flexible context and parameter handling.

Parameters:

  • value_parameters (Array)

    positional parameters to pass to block.

  • keep_block_context (Boolean, nil) (defaults to: nil)

    explicit control of context switching:

    • true: always keep caller's context
    • false: always use object's context
    • nil: auto-detect based on _ parameter
  • key_parameters (Hash)

    keyword parameters to pass to block.

  • block (Proc)

    block to execute.

Returns:

  • (Object)

    result of block execution.