Class: MiniKraken::Rela::Conj2

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

Overview

The conjunction is a relation that accepts only two goals as its arguments. It succeeds if and only if both 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

#initializeConj2

Default initialization



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

def initialize
  super('conj2', 2)
end

Instance Method Details

#conjunction(g1, g2, ctx) ⇒ Object

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

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
# File 'lib/mini_kraken/rela/conj2.rb', line 33

def conjunction(g1, g2, ctx)
  # require 'debug'
  if g1.relation.kind_of?(Core::Fail) || g2.relation.kind_of?(Core::Fail)
    Fiber.yield ctx.failed!
  else
    outcome1 = outcome2 = nil
    fiber1 = g1.achieve(ctx)

    loop do
      outcome1 = fiber1.resume(ctx)
      break if outcome1.nil?

      if outcome1.success?
        fiber2 = g2.achieve(ctx)
        loop do
          outcome2 = fiber2.resume(ctx)
          break if outcome2.nil?

          Fiber.yield outcome2
        end
      else
        Fiber.yield outcome1
      end
    end
  end

  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/conj2.rb', line 24

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