class Porolog::Rule
A Porolog::Rule
is one clause of a Porolog::Predicate
.
@author Luis Esteban
@!attribute [r] arguments
The Arguments of the Predicate for which this Rule applies.
@!attribute [r] definition
The definition of the Rule.
Attributes
Public Class Methods
Initializes the Rule
. @param arguments [Porolog::Arguments] the Arguments
of the Predicate
for which this Rule
applies. @param definition [Object] the definition of the Rule
.
# File lib/porolog/rule.rb, line 40 def initialize(arguments, definition = nil) @arguments = arguments @definition = definition @@rules << self end
Clears all Rules. @return [Boolean] success
# File lib/porolog/rule.rb, line 30 def self.reset @@rules = [] true end
Public Instance Methods
@return [String] pretty representation.
# File lib/porolog/rule.rb, line 53 def inspect " #{@arguments.inspect}:- #{@definition.inspect}" end
Convenience method for testing/debugging @return [String] pretty identification
# File lib/porolog/rule.rb, line 48 def myid "Rule#{(@@rules.index(self) || -1000) + 1}" end
Try to satisfy the Rule
for the given Goal
. @param goal [Porolog::Goal] the Goal
in which to satisfy this Rule
. @param block [Proc] code to perform when the Rule
is satisfied. @return [Boolean] the success of deleting the subgoal.
# File lib/porolog/rule.rb, line 61 def satisfy(goal, &block) subgoal = Goal.new self.arguments, goal unified_goals = Porolog::unify_goals(goal, subgoal) if unified_goals satisfy_definition(goal, subgoal) do |solution_goal| block.call(solution_goal) end else subgoal.log << "Dead-end: Cannot unify with #{goal.inspect}" end subgoal.delete! end
Try to satisfy the conjunction of the definition of the Rule
for a given Goal
. A conjunction is a sequence of expressions where the sequence is true if all the expressions are true.
@param goal [Porolog::Goal] the given Goal
for the Rule
. @param subgoal [Porolog::Goal] the subgoal for the Rule's definition. @param conjunction [Array] the conjunction to satisfy. @param block [Proc] code to perform when the definition is satisfied. @return [Boolean] whether the definition was satisfied.
# File lib/porolog/rule.rb, line 109 def satisfy_conjunction(goal, subgoal, conjunction, &block) arguments = conjunction.first conjunction = conjunction[1..-1] # -- Handle non-Arguments -- case arguments when :CUT, true subgoal.log << "CUTTING #{goal.inspect}..." result = true if conjunction.empty? !goal.terminated? && block.call(subgoal) else result = satisfy_conjunction(goal, subgoal, conjunction, &block) end if arguments == :CUT goal.terminate! goal.log << "TERMINATED after #{subgoal.inspect}" end return result when false return false when nil !goal.terminated? && block.call(subgoal) return true end # -- Unify Subsubgoal -- subsubgoal = arguments.goal(subgoal) unified = subsubgoal.inherit_variables(subgoal) # -- Satisfy Subgoal -- result = false unified && subsubgoal.satisfy() do result = true if conjunction.empty? !goal.terminated? && block.call(goal) else result = !goal.terminated? && satisfy_conjunction(goal, subsubgoal, conjunction, &block) end end # -- Uninstantiate -- subsubgoal.delete! result && !goal.terminated? end
Try to satisfy the definition of the Rule
for a given Goal
. @param goal [Porolog::Goal] the given Goal
for the Rule
. @param subgoal [Porolog::Goal] the subgoal for the Rule's definition. @param block [Proc] code to perform when the definition is satisfied. @return [Boolean] whether the definition was satisfied.
# File lib/porolog/rule.rb, line 81 def satisfy_definition(goal, subgoal, &block) case @definition when TrueClass block.call(subgoal) true when FalseClass false when Array satisfy_conjunction(goal, subgoal, @definition) do |solution_goal| block.call(solution_goal) end else raise DefinitionError, "UNEXPECTED TYPE OF DEFINITION: #{@definition.inspect} (#{@definition.class})" end end