class Pione::RuleEngine::DataFinder

DataFinder finds data tuples from tuple space server.

Public Class Methods

new(space, domain_id) click to toggle source

Creates a new finder.

# File lib/pione/rule-engine/data-finder.rb, line 8
def initialize(space, domain_id)
  set_tuple_space(space)
  @domain_id = domain_id
end

Public Instance Methods

find(type, conditions, env, &b) click to toggle source

Find data tuple combinations from tuple space server. This method calls the block when the combination found.

# File lib/pione/rule-engine/data-finder.rb, line 15
def find(type, conditions, env, &b)
  find_next(type, 1, conditions, env, [], &b)
end

Private Instance Methods

find_next(type, index, conditions, env, combination) { |env, combination| ... } click to toggle source

Find input tuple combinatioins recursively.

# File lib/pione/rule-engine/data-finder.rb, line 22
def find_next(type, index, conditions, env, combination, &b)
  # call block when we reach the recuirsion end
  return yield(env, combination) if conditions.empty?

  # expand variables and compile to regular expression
  head = conditions.first.eval(env)
  tail = conditions.drop(1)

  # find data tuples by head condition from tuple space server
  tuples = find_tuples_by_condition(head)

  # no tuples
  if tuples.empty?
    if head.accept_nonexistence?
      # accept noexistance data, find next tuples
      return find_next(type, index+1, tail, env.layer, combination + [[]], &b)
    else
      return # failed to find tuples
    end
  end

  # make combination results
  case head.distribution
  when :all
    _env = make_io_variables(type, index, :all, head, env, tuples)
    find_next(type, index+1, tail, _env, combination + [tuples], &b)
  when :each
    tuples.each do |tuple|
      _env = make_io_variables(type, index, :each, head, env, [tuple])
      find_next(type, index+1, tail, _env, combination + [[tuple]], &b)
    end
  end
end
find_tuples_by_condition(condition) click to toggle source

Find all matched data tuples by the rule expression condition from tuple space.

# File lib/pione/rule-engine/data-finder.rb, line 57
def find_tuples_by_condition(condition)
  return read_all(TupleSpace::DataTuple.new(name: condition, domain: @domain_id))
end
make_io_variables(type, index, distribution, condition, env, tuples) click to toggle source

Make input/output variables by data expression with all distribution.

# File lib/pione/rule-engine/data-finder.rb, line 62
def make_io_variables(type, index, distribution, condition, env, tuples)
  _env = env.layer
  asterisk = []

  # variable and value
  var = Lang::Variable.new(type == :input ? "I" : "O")
  val = env.variable_get!(var) || Lang::KeyedSequence.new

  # update value
  _val = tuples.inject(val) do |_val, tuple|
    # matched data
    md = condition.match(tuple.name).to_a
    asterisk << md[1]

    # make a date expression
    data = Lang::DataExpr.new(pattern: tuple.name, location: tuple.location, matched_data: md)

    # update value
    _val.put(Lang::IntegerSequence.of(index), Lang::DataExprSequence.of(data))
  end
  _env.variable_set!(var, _val)

  # set special variable if index equals 1
  if type == :input && index == 1
    strs = asterisk.map{|str| Lang::PioneString.new(str)}
    _env.variable_set(
      Lang::Variable.new("*"),
      Lang::StringSequence.new(strs).set(distribution: distribution)
    )
  end

  return _env
end