class Porolog::Predicate

A Porolog::Predicate corresponds to a Prolog predicate. It contains rules (Porolog::Rule) and belongs to a Porolog::Scope. When provided with arguments, it produces a Porolog::Arguments.

@author Luis Esteban

@!attribute [r] name

Name of the Predicate.

@!attribute [r] rules

Rules of the Predicate.

Constants

UNIQUE_VALUE

A unique value used to verify instantiations.

Attributes

name[R]
rules[R]

Public Class Methods

[](name) click to toggle source

Looks up a Predicate in the current scope by its name. @param name [Object] the name (or otherwise object) used to register a scope. @return [Porolog::Predicate] the Predicate with the given name.

# File lib/porolog/predicate.rb, line 65
def self.[](name)
  @@current_scope[name]
end
call_builtin(predicate, *args, &arg_block) click to toggle source

Call a builtin predicate @param predicate [Symbol] the name of the predicate to call. @param args [Array<Object>] arguments for the predicate call. @param arg_block [Proc] the block provided in the Arguments of the Predicate. @return [Boolean] whether the predicate was satisfied.

# File lib/porolog/predicate.rb, line 175
def self.call_builtin(predicate, *args, &arg_block)
  Porolog::Predicate::Builtin.instance_method(predicate).bind(self).call(*args, &arg_block)
end
new(name, scope_name = Predicate.scope.name, builtin: false) click to toggle source

Initializes a Porolog::Predicate and registers it by its name. @param name [#to_sym] the input object to read from @param scope_name the name of the scope in which to register the Predicate; if omitted, defaults to the name of the current scope

# File lib/porolog/predicate.rb, line 74
def initialize(name, scope_name = Predicate.scope.name, builtin: false)
  @name    = name.to_sym
  @rules   = []
  @builtin = builtin
  
  raise NameError, "Cannot name a predicate 'predicate'" if @name == :predicate
  
  scope = Scope[scope_name] || Scope.new(scope_name)
  scope[@name] = self
end
new(*args, **) click to toggle source

Creates a new Predicate, or returns an existing Predicate if one already exists with the given name in the current scope. @param args the args to be passed to initialize, first of which is the name of the predicate. @return [Porolog::Predicate] a new or existing Predicate.

Calls superclass method
# File lib/porolog/predicate.rb, line 88
def self.new(*args, **)
  scope[args.first.to_sym] || super
end
reset() click to toggle source

Resets the current scope to default and deregisters builtin predicates. @return [Porolog::Scope] the current Scope.

# File lib/porolog/predicate.rb, line 57
def self.reset
  scope(:default)
  @builtin_predicate_ids = {}
end
scope(scope_name = nil) click to toggle source

Returns the current scope, or sets the current scope if a paramter is provided (creating the new scope if necessary). @param scope_name [Object] the name (or otherwise object) used to register a scope. @return [Porolog::Scope] the current Scope.

# File lib/porolog/predicate.rb, line 39
def self.scope(scope_name = nil)
  if scope_name
    @@current_scope = Scope[scope_name] || Scope.new(scope_name)
  else
    @@current_scope
  end
end
scope=(scope_name) click to toggle source

Sets the current scope (creating the new scope if necessary. @param scope_name [Object] the name (or otherwise object) used to register a scope. @return [Porolog::Scope] the current Scope.

# File lib/porolog/predicate.rb, line 50
def self.scope=(scope_name)
  @@current_scope = Scope[scope_name] || Scope.new(scope_name)  if scope_name
  @@current_scope
end

Public Instance Methods

<<(rule) click to toggle source

Add a Rule to the Predicate. @param rule [Object] a rule to add to the Predicate. @return [Porolog::Predicate] the Predicate.

# File lib/porolog/predicate.rb, line 113
def <<(rule)
  @rules << rule
  self
end
arguments(*args, &block) click to toggle source

Create Arguments for the Predicate. @param args the args of the Predicate. @param block [Proc,nil] the block to be called when satisfying the Predicate. @return [Porolog::Arguments] Arguments of the Predicate with the given arguments.

# File lib/porolog/predicate.rb, line 106
def arguments(*args, &block)
  Arguments.new(self, args, &block)
end
builtin?() click to toggle source

@return [Boolean] whether the Predicate is a builtin predicate.

# File lib/porolog/predicate.rb, line 152
def builtin?
  @builtin
end
call(*args, &block) click to toggle source

Create Arguments for the Predicate. Provides the syntax option:

p.(x,y,z)

for

p.arguments(x,y,z)

@return [Porolog::Arguments] Arguments of the Predicate with the given arguments.

# File lib/porolog/predicate.rb, line 98
def call(*args, &block)
  Arguments.new(self, args, &block)
end
inspect() click to toggle source

A pretty print String of the Predicate. @return [String] the Predicate as a String.

# File lib/porolog/predicate.rb, line 120
def inspect
  if @rules.size == 1
    "#{@name}:-#{@rules.first.inspect}"
  else
    @rules.each_with_object(["#{@name}:-"]) do |rule, lines|
      lines << rule.inspect
    end.join("\n")
  end
end
satisfy(goal, &block) click to toggle source

Satisfy the Predicate within the supplied Goal. Satisfy of each rule of the Predicate is called with the Goal and success block. @param goal [Porolog::Goal] the Goal within which to satisfy the Predicate. @param block [Proc] the block to be called each time a Rule of the Predicate is satisfied. @return [Boolean] whether any Rule was satisfied.

# File lib/porolog/predicate.rb, line 135
def satisfy(goal, &block)
  if builtin?
    satisfy_builtin(goal, &block)
  else
    satisfied = false
    @rules.each do |rule|
      rule.satisfy(goal) do |subgoal|
        satisfied = true
        block.call(subgoal)
      end
      break if goal.terminated?
    end
    satisfied
  end
end
satisfy_builtin(goal, &block) click to toggle source

Satisfy the builtin Predicate within the supplied Goal. Call the builtin Predicate method with the Goal and success block. The arguments and block are extracted from the Goal's Arguments. @param goal [Porolog::Goal] the Goal within which to satisfy the Predicate. @param block [Proc] the block to be called each time a Rule of the Predicate is satisfied. @return [Boolean] whether any Rule was satisfied.

# File lib/porolog/predicate.rb, line 162
def satisfy_builtin(goal, &block)
  predicate = goal.arguments.predicate.name
  arguments = goal.arguments.arguments
  arg_block = goal.arguments.block
  
  Predicate.call_builtin(predicate, goal, block, *arguments, &arg_block)
end