Class: MiniKraken::Rela::Disj2

Inherits:
GoalRelation show all
Includes:
Singleton
Defined in:
lib/mini_kraken/rela/disj2.rb

Overview

The disjunction is a relation that accepts only goal(s) as its two arguments. It succeeds if at least one of its goal arguments succeeds.

Instance Attribute Summary

Attributes inherited from Core::Specification

#arity, #name

Instance Method Summary collapse

Methods inherited from Core::Specification

#check_arity, #inspect, #variadic?

Constructor Details

#initializeDisj2

Default initialization



17
18
19
# File 'lib/mini_kraken/rela/disj2.rb', line 17

def initialize
  super('disj2', 2)
end

Instance Method Details

#disjunction(g1, g2, ctx) ⇒ Object

Yields [Core::Context, NilClass] result of the disjunction

Parameters:

  • g1 (Goal)

    First goal argument

  • g2 (Goal)

    Second goal argument

  • ctx (Core::Context)

    A ctxabulary object



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/mini_kraken/rela/disj2.rb', line 33

def disjunction(g1, g2, ctx)
  # require 'debug'
  if g1.relation.kind_of?(Core::Fail) && g2.relation.kind_of?(Core::Fail)
    Fiber.yield ctx.failed!
  else
    ctx.place_bt_point
    outcome1 = nil
    outcome2 = nil
    f1 = g1.achieve(ctx)
    loop do
      outcome1 = f1.resume(ctx)
      break if outcome1.nil?

      if outcome1.success?
        Fiber.yield outcome1
        ctx.next_alternative
      end
    end
    f2 = g2.achieve(ctx)
    loop do
      outcome2 = f2.resume(ctx)
      break if outcome2.nil?

      if outcome2.success?
        Fiber.yield outcome2
        ctx.next_alternative
      end
    end
  end

  ctx.retract_bt_point
  Fiber.yield nil
end

#solver_for(actuals, ctx) ⇒ Fiber<Core::Context>

Returns A Fiber that yields Context objects.

Parameters:

Returns:



24
25
26
27
# File 'lib/mini_kraken/rela/disj2.rb', line 24

def solver_for(actuals, ctx)
  g1, g2 = *validated_args(actuals)
  Fiber.new { disjunction(g1, g2, ctx) }
end