class Porolog::Arguments

A Porolog::Arguments specifies arguments of a Predicate. A predicate is not like a subroutine, although there are many similarities. An Arguments represents an instance of a predicate with a specific set of arguments. This forms the basis for implementing a goal to solve the predicate with those specific arguments.

@author Luis Esteban

@!attribute [r] predicate

The Predicate for which these are the arguments.

@!attribute [r] arguments

The actual arguments.

Attributes

arguments[R]
block[R]
predicate[R]

Public Class Methods

arguments() click to toggle source

Convenience method for testing/debugging @return [Array<Porolog::Arguments>] all registered Arguments

# File lib/porolog/arguments.rb, line 46
def self.arguments
  @@arguments
end
new(predicate, arguments, &block) click to toggle source

Creates a new Arguments for a Predicate @param predicate [Porolog::Predicate] the Predicate for which these are the arguments @param arguments [Array<Object>] the actual arguments

# File lib/porolog/arguments.rb, line 37
def initialize(predicate, arguments, &block)
  @predicate = predicate
  @arguments = arguments
  @block     = block
  @@arguments << self
end
reset() click to toggle source

Unregisters all Arguments @return [true]

# File lib/porolog/arguments.rb, line 27
def self.reset
  @@arguments = []
  true
end

Public Instance Methods

<<(*definition) click to toggle source

Adds a Rule to the Predicate for these Arguments @param definition [Array<Object>, Object] the Rule definition for these Arguments @return [Porolog::Arguments] the Arguments

# File lib/porolog/arguments.rb, line 93
def <<(*definition)
  @predicate << Rule.new(self, *definition)
  self
end
==(other) click to toggle source

@param other [Porolog::Arguments] arguments for comparison @return [Boolean] whether the Arguments match

# File lib/porolog/arguments.rb, line 170
def ==(other)
  @predicate == other.predicate &&
  @arguments == other.arguments
end
cut_fact!() click to toggle source

Creates a fact rule that states that these arguments satisfy the Predicate and terminates solving the predicate. @return [Porolog::Arguments] the Arguments

# File lib/porolog/arguments.rb, line 78
def cut_fact!
  @predicate << Rule.new(self, [:CUT, true])
  self
end
cut_fallacy!() click to toggle source

Creates a fact rule that states that these arguments do not satisfy the Predicate and terminates solving the predicate. @return [Porolog::Arguments] the Arguments

# File lib/porolog/arguments.rb, line 85
def cut_fallacy!
  @predicate << Rule.new(self, [:CUT, false])
  self
end
dup(goal) click to toggle source

Duplicates the Arguments in the context of the given goal @param goal [Porolog::Goal] the destination goal @return [Porolog::Arguments] the duplicated Arguments

# File lib/porolog/arguments.rb, line 164
def dup(goal)
  self.class.new @predicate, goal.variablise(arguments), &@block
end
evaluates(&block) click to toggle source

Adds an evaluation Rule to the Predicate @param block the block to evaluate @return [Porolog::Arguments] the Arguments

# File lib/porolog/arguments.rb, line 101
def evaluates(&block)
  @predicate << Rule.new(self, block)
  self
end
fact!() click to toggle source

Creates a fact rule that states that these arguments satisfy the Predicate. @return [Porolog::Arguments] the Arguments

# File lib/porolog/arguments.rb, line 64
def fact!
  @predicate << Rule.new(self, true)
  self
end
fallacy!() click to toggle source

Creates a fact rule that states that these arguments do not satisfy the Predicate. @return [Porolog::Arguments] the Arguments

# File lib/porolog/arguments.rb, line 71
def fallacy!
  @predicate << Rule.new(self, false)
  self
end
goal(calling_goal = nil) click to toggle source

Creates a Goal for solving this Arguments for the Predicate @param calling_goal [Porolog::Goal] the parent Goal (if this is a subgoal) @return [Porolog::Goal] the Goal to solve

# File lib/porolog/arguments.rb, line 114
def goal(calling_goal = nil)
  Goal.new(self, calling_goal)
end
inspect() click to toggle source

@return [String] pretty representation

# File lib/porolog/arguments.rb, line 57
def inspect
  block_inspect = block.nil? ? '' : "{#{block.inspect}}"
  "#{@predicate&.name}(#{@arguments&.map(&:inspect).join(',')})#{block_inspect}"
end
myid() click to toggle source

Convenience method for testing/debugging @return [String] pretty identification

# File lib/porolog/arguments.rb, line 52
def myid
  "Arguments#{(@@arguments.index(self) || -1000) + 1}"
end
solutions(max_solutions = nil) click to toggle source

Returns memoized solutions @param max_solutions [Integer] the maximum number of solutions to find (nil means find all) @return [Array<Hash{Symbol => Object}>] the solutions found (memoized)

# File lib/porolog/arguments.rb, line 121
def solutions(max_solutions = nil)
  @solutions ||= solve(max_solutions)
  max_solutions && @solutions[0...max_solutions] || @solutions
end
solve(max_solutions = nil) click to toggle source

Solves the Arguments @param max_solutions [Integer] the maximum number of solutions to find (nil means find all) @return [Array<Hash{Symbol => Object}>] the solutions found

# File lib/porolog/arguments.rb, line 129
def solve(max_solutions = nil)
  @solutions = goal.solve(max_solutions)
end
solve_for(*variables, max_solutions: nil) click to toggle source

Extracts solution values. @param variables [Symbol, Array<Symbol>] variable or variables @param max_solutions [Integer] the maximum number of solutions to find (nil means find all) @return [Array<Object>] all the values for the variables given @example

predicate :treasure_at
treasure_at(:X,:Y) << [...]
arguments = treasure_at(:X,:Y)
xs = arguments.solve_for(:X)
ys = arguments.solve_for(:Y)
coords = xs.zip(ys)
# File lib/porolog/arguments.rb, line 144
def solve_for(*variables, max_solutions: nil)
  variables = [*variables]
  solutions(max_solutions).map{|solution|
    values = variables.map{|variable| solution[variable] }
    if values.size == 1
      values.first
    else
      values
    end
  }
end
valid?() click to toggle source

@return [Boolean] whether any solutions were found

# File lib/porolog/arguments.rb, line 157
def valid?
  !solutions(1).empty?
end
variables() click to toggle source

@return [Array<Symbol>] the variables contained in the arguments

# File lib/porolog/arguments.rb, line 107
def variables
  @arguments.map(&:variables).flatten.uniq
end