Class: CLIPS

Inherits:
Object
  • Object
show all
Defined in:
lib/clips.rb,
lib/clips/rule.rb

Defined Under Namespace

Classes: Rule

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeCLIPS

Returns a new instance of CLIPS.



21
22
23
24
25
26
27
# File 'lib/clips.rb', line 21

def initialize
  @activations = Set.new
  @agenda = Set.new
  @default_facts = Hash.new
  @facts = Set.new
  @rules = Hash.new
end

Instance Attribute Details

#activationsSet (readonly)

Returns The currently activated Facts awaiting processing.

Returns:

  • (Set)

    The currently activated Facts awaiting processing



7
8
9
# File 'lib/clips.rb', line 7

def activations
  @activations
end

#agendaSet (readonly)

Returns The Rules waiting to be processed.

Returns:

  • (Set)

    The Rules waiting to be processed



10
11
12
# File 'lib/clips.rb', line 10

def agenda
  @agenda
end

#default_factsHash (readonly)

Returns The set of facts that will be instantiated on each reset.

Returns:

  • (Hash)

    The set of facts that will be instantiated on each reset



13
14
15
# File 'lib/clips.rb', line 13

def default_facts
  @default_facts
end

#factsSet (readonly)

Returns Just the Facts.

Returns:

  • (Set)

    Just the Facts



16
17
18
# File 'lib/clips.rb', line 16

def facts
  @facts
end

#rulesHash (readonly)

Returns The set of Rules and their names.

Returns:

  • (Hash)

    The set of Rules and their names



19
20
21
# File 'lib/clips.rb', line 19

def rules
  @rules
end

Instance Method Details

#add(name, rule) ⇒ CLIPS #add(*fields) ⇒ CLIPS

Overloads:

  • #add(name, rule) ⇒ CLIPS

    Add the named Rule

    Parameters:

    • name (String)

      The name of the Rule

    • rule (Rule)

      The Rule to add

    Returns:

  • #add(*fields) ⇒ CLIPS

    Add a fact using the given field values

    Returns:



37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/clips.rb', line 37

def add(*fields)
  if (2==fields.length) and fields.last&.is_a?(Rule)
 self.rules[fields.first.to_sym] ||= fields.last
  else # Assume the item to be a Fact
 fields[0] = fields.first.to_sym
 # Add the new Fact to the activations list for processing during the next call to run()
 self.activations.add(fields)
 self.facts.add(fields)
 fields
  # else
  #     raise ArgumentError.new("Invalid fact")
  end
  self
end

#clearCLIPS

Remove all Facts and return self

Returns:



54
55
56
57
58
59
60
61
# File 'lib/clips.rb', line 54

def clear
  self.activations.clear
  self.agenda.clear
  self.default_facts.clear
  self.facts.clear
  self.rules.clear
  self
end

#delete(*fact) ⇒ CLIPS

Remove the given fact

Returns:



65
66
67
68
69
70
71
# File 'lib/clips.rb', line 65

def delete(*fact)
  fact[0] = fact.first.to_sym
  if self.facts.delete?(fact)
 self.activations.delete(fact)
  end
  self
end

#resetCLIPS

Delete everything but the rules, then add the default facts

Returns:



75
76
77
78
79
80
81
82
83
84
85
# File 'lib/clips.rb', line 75

def reset
  self.activations.clear
  self.agenda.clear
  self.facts.clear

  self.default_facts.each do |name, fact_set|
 fact_set.each {|fact| self.add(*fact)}
  end

  self
end

#run(limit = nil) ⇒ Integer

Returns The number of rules that were fired.

Parameters:

  • limit (Integer) (defaults to: nil)

    The maximum number of rules that will fire before the function returns. The limit is disabled if nil.

Returns:

  • (Integer)

    The number of rules that were fired



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/clips.rb', line 89

def run(limit=nil)
  self.rules.each do |name, rule|
 self.agenda.add(rule) if rule.patterns.empty?
  end

  rule_counter = 0
  begin
 # If all of a Rule's patterns match, and any of those patterns are on the activation list, then fire the Rule
 self.rules.each do |name, rule|
    activated = false
    _all = rule.patterns.all? do |pattern|
  activated = true if not activated and self.activations.include?(pattern)
  self.facts.include?(pattern)
    end
    self.agenda.add(rule) if activated and _all
 end

 self.activations.clear # All activations have been processed, so clear the Set

 # Fire all of the Rules on the agenda in salience-order
 sorted_agenda = self.agenda.sort {|a,b| b.salience <=> a.salience}
 self.agenda.clear
 sorted_agenda.each do |rule|
    rule.run!(self)
    rule_counter += 1

    break if rule_counter == limit
 end
  end until self.agenda.empty? and self.activations.empty?

  rule_counter
end