cirrocumulus 0.9.9 → 0.9.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -154,7 +154,7 @@ class ChannelFactory
|
|
|
154
154
|
jabber_client = JabberChannel.query_client(instance.to_s)
|
|
155
155
|
|
|
156
156
|
if jabber_client
|
|
157
|
-
return NetworkChannel.new(jabber_client, agent.to_s)
|
|
157
|
+
return NetworkChannel.new(jabber_client, agent.is_a?(WholeOntologyIdentifier) ? nil : agent.to_s)
|
|
158
158
|
else
|
|
159
159
|
Logger['channels::factory'].warn "No active Jabber clients."
|
|
160
160
|
end
|
|
@@ -142,7 +142,7 @@ class JabberChannel
|
|
|
142
142
|
Log4r::Logger['channels::jabber'].debug('Received Jabber::ClientAuthenticationFailure, registering new account')
|
|
143
143
|
client = Jabber::Client.new(@full_jid)
|
|
144
144
|
client.connect()
|
|
145
|
-
client.register(password)
|
|
145
|
+
client.register(@@password)
|
|
146
146
|
client.close()
|
|
147
147
|
@jabber = Jabber::Simple.new(@full_jid, @@password)
|
|
148
148
|
rescue Exception => ex
|
|
@@ -10,12 +10,8 @@ class Agent
|
|
|
10
10
|
JabberIdentifier.new(ontology_name)
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
-
def self.all
|
|
14
|
-
|
|
15
|
-
Broadcast.new
|
|
16
|
-
else
|
|
17
|
-
Autodiscover.new(ontology_name)
|
|
18
|
-
end
|
|
13
|
+
def self.all
|
|
14
|
+
WholeOntologyIdentifier.new
|
|
19
15
|
end
|
|
20
16
|
|
|
21
17
|
def self.remote(agent_identifier)
|
|
@@ -56,6 +52,16 @@ class RemoteIdentifier
|
|
|
56
52
|
end
|
|
57
53
|
end
|
|
58
54
|
|
|
55
|
+
class WholeOntologyIdentifier < RemoteIdentifier
|
|
56
|
+
def initialize(ontology_name = nil)
|
|
57
|
+
@ontology_name = ontology_name
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def to_s
|
|
61
|
+
@ontology_name || "(broadcast)"
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
59
65
|
#
|
|
60
66
|
# Agent identifier for local agents.
|
|
61
67
|
#
|
|
@@ -20,10 +20,26 @@ class RuleDescription
|
|
|
20
20
|
end
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
+
class TriggerDescription
|
|
24
|
+
attr_reader :name, :fact, :action, :code
|
|
25
|
+
|
|
26
|
+
def initialize(name, fact, action, code)
|
|
27
|
+
@name = name
|
|
28
|
+
@fact = fact
|
|
29
|
+
@action = action
|
|
30
|
+
@code = code
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def ==(other)
|
|
34
|
+
name == other.name
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
23
38
|
class Ontology
|
|
24
39
|
class << self
|
|
25
40
|
@@inproc_agents = {}
|
|
26
41
|
@@loaded_rules = {}
|
|
42
|
+
@@loaded_triggers = {}
|
|
27
43
|
@@ontology_names = {}
|
|
28
44
|
|
|
29
45
|
def register_ontology_instance(instance)
|
|
@@ -64,7 +80,11 @@ class Ontology
|
|
|
64
80
|
|
|
65
81
|
def current_ruleset()
|
|
66
82
|
return @@loaded_rules[name] ||= []
|
|
67
|
-
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def triggers
|
|
86
|
+
return @@loaded_triggers[name] ||= []
|
|
87
|
+
end
|
|
68
88
|
|
|
69
89
|
def enable_console
|
|
70
90
|
proxy = RemoteConsole.new
|
|
@@ -81,7 +101,20 @@ class Ontology
|
|
|
81
101
|
|
|
82
102
|
distilled_predicate = predicate.map {|cond| cond.is_a?(KnowledgeClass) ? cond.to_params : cond}
|
|
83
103
|
current_ruleset << RuleDescription.new(name, distilled_predicate, options, block)
|
|
84
|
-
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def trigger(name, options, &block)
|
|
107
|
+
return unless options.has_key?(:for)
|
|
108
|
+
return if triggers.find {|t| t.name == name}
|
|
109
|
+
|
|
110
|
+
trigger_for = options[:for]
|
|
111
|
+
trigger_action = options[:on] || :assert
|
|
112
|
+
|
|
113
|
+
t = TriggerDescription.new(name, trigger_for, trigger_action, block)
|
|
114
|
+
triggers << t
|
|
115
|
+
|
|
116
|
+
p t
|
|
117
|
+
end
|
|
85
118
|
end
|
|
86
119
|
|
|
87
120
|
attr_reader :identifier
|
|
@@ -206,7 +239,7 @@ class Ontology
|
|
|
206
239
|
|
|
207
240
|
def create_saga(saga_class)
|
|
208
241
|
@last_saga_id += 1
|
|
209
|
-
saga = saga_class.new(saga_class.
|
|
242
|
+
saga = saga_class.new(saga_class.name + '-' + @last_saga_id.to_s, self)
|
|
210
243
|
@sagas << saga
|
|
211
244
|
|
|
212
245
|
saga
|
|
@@ -294,6 +327,10 @@ class Ontology
|
|
|
294
327
|
# Send 'query-if' to another agent. Normally, it will reply if the expression is true or false.
|
|
295
328
|
#
|
|
296
329
|
def query_if(agent, fact, options = {})
|
|
330
|
+
info "%25s | query %s if %s %s" % [identifier, agent, Sexpistol.new.to_sexp(fact), print_message_options(options)]
|
|
331
|
+
|
|
332
|
+
channel = ChannelFactory.retrieve(identifier, agent)
|
|
333
|
+
channel.query_if(identifier, fact, options) if channel
|
|
297
334
|
end
|
|
298
335
|
|
|
299
336
|
def query_if_and_wait(agent, fact, options = {})
|
|
@@ -307,7 +344,13 @@ class Ontology
|
|
|
307
344
|
#
|
|
308
345
|
# Tick. Every second.
|
|
309
346
|
#
|
|
310
|
-
def tick
|
|
347
|
+
def tick
|
|
348
|
+
@sagas.each do |saga|
|
|
349
|
+
next if saga.is_finished?
|
|
350
|
+
|
|
351
|
+
saga.tick
|
|
352
|
+
end
|
|
353
|
+
end
|
|
311
354
|
|
|
312
355
|
#
|
|
313
356
|
# Handles incoming fact. By default, just adds this fact to KB or redirects its processing to corresponding saga
|
|
@@ -364,6 +407,13 @@ class Ontology
|
|
|
364
407
|
|
|
365
408
|
def handle_query(sender, expression, options = {})
|
|
366
409
|
info "%25s | %s queries %s %s" % [identifier, sender, Sexpistol.new.to_sexp(expression), print_message_options(options)] unless handle_saga_reply(sender, :query, expression, options)
|
|
410
|
+
|
|
411
|
+
matcher = PatternMatcher.new(@facts.enumerate)
|
|
412
|
+
matches = matcher.find_matches_for_condition(expression).map {|data| data.data}
|
|
413
|
+
info "%25s | (found #{matches.size} matching facts)" % [identifier]
|
|
414
|
+
matches.each do |fact|
|
|
415
|
+
inform(sender, fact, reply(options))
|
|
416
|
+
end
|
|
367
417
|
end
|
|
368
418
|
|
|
369
419
|
#
|
data/lib/cirrocumulus/saga.rb
CHANGED
|
@@ -22,12 +22,20 @@ class Saga
|
|
|
22
22
|
@ontology = ontology
|
|
23
23
|
@state = STATE_START
|
|
24
24
|
@started_at = Time.now
|
|
25
|
+
@timeout_at = nil
|
|
25
26
|
end
|
|
26
27
|
|
|
27
28
|
def is_finished?
|
|
28
29
|
@state == STATE_ERROR || @state == STATE_FINISHED
|
|
29
30
|
end
|
|
30
31
|
|
|
32
|
+
def tick
|
|
33
|
+
return if @timeout_at.nil? || @timeout_at > Time.now
|
|
34
|
+
|
|
35
|
+
@timeout_at = nil
|
|
36
|
+
handle_reply(nil, nil, nil)
|
|
37
|
+
end
|
|
38
|
+
|
|
31
39
|
def handle_reply(sender, contents, options = {}); end
|
|
32
40
|
|
|
33
41
|
def dump_parameters
|
|
@@ -44,32 +52,32 @@ class Saga
|
|
|
44
52
|
# Inter-agent communications with context of this saga.
|
|
45
53
|
#
|
|
46
54
|
|
|
47
|
-
def inform(agent, proposition)
|
|
48
|
-
@ontology.inform agent, proposition, :conversation_id => self.id
|
|
55
|
+
def inform(agent, proposition, options = {})
|
|
56
|
+
@ontology.inform agent, proposition, options.merge(:conversation_id => self.id)
|
|
49
57
|
end
|
|
50
58
|
|
|
51
|
-
def agree(agent, action)
|
|
52
|
-
@ontology.agree agent, action, :conversation_id => self.id
|
|
59
|
+
def agree(agent, action, options = {})
|
|
60
|
+
@ontology.agree agent, action, options.merge(:conversation_id => self.id)
|
|
53
61
|
end
|
|
54
62
|
|
|
55
|
-
def refuse(agent, action, reason)
|
|
56
|
-
@ontology.refuse agent, action, reason, :conversation_id => self.id
|
|
63
|
+
def refuse(agent, action, reason, options = {})
|
|
64
|
+
@ontology.refuse agent, action, reason, options.merge(:conversation_id => self.id)
|
|
57
65
|
end
|
|
58
66
|
|
|
59
67
|
def failure(agent, action, reason = true)
|
|
60
|
-
@ontology.failure agent, action, reason, :conversation_id => self.id
|
|
68
|
+
@ontology.failure agent, action, reason, options.merge(:conversation_id => self.id)
|
|
61
69
|
end
|
|
62
70
|
|
|
63
|
-
def request(agent, action)
|
|
64
|
-
@ontology.request agent, action, :conversation_id => self.id
|
|
71
|
+
def request(agent, action, options = {})
|
|
72
|
+
@ontology.request agent, action, options.merge(:conversation_id => self.id)
|
|
65
73
|
end
|
|
66
74
|
|
|
67
|
-
def query(agent, expression)
|
|
68
|
-
@ontology.query agent, expression, :reply_with => self.id
|
|
75
|
+
def query(agent, expression, options = {})
|
|
76
|
+
@ontology.query agent, expression, options.merge(:reply_with => self.id)
|
|
69
77
|
end
|
|
70
78
|
|
|
71
|
-
def query_if(agent, proposition)
|
|
72
|
-
@ontology.query_if agent, proposition, :reply_with => self.id
|
|
79
|
+
def query_if(agent, proposition, options = {})
|
|
80
|
+
@ontology.query_if agent, proposition, options.merge(:reply_with => self.id)
|
|
73
81
|
end
|
|
74
82
|
|
|
75
83
|
def finish()
|
|
@@ -84,4 +92,8 @@ class Saga
|
|
|
84
92
|
@state = new_state
|
|
85
93
|
end
|
|
86
94
|
|
|
95
|
+
def timeout(secs)
|
|
96
|
+
@timeout_at = Time.now + secs.seconds
|
|
97
|
+
end
|
|
98
|
+
|
|
87
99
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: cirrocumulus
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.9.
|
|
4
|
+
version: 0.9.11
|
|
5
5
|
prerelease:
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date:
|
|
12
|
+
date: 2013-02-19 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: log4r
|
|
@@ -82,7 +82,7 @@ dependencies:
|
|
|
82
82
|
requirements:
|
|
83
83
|
- - ! '>='
|
|
84
84
|
- !ruby/object:Gem::Version
|
|
85
|
-
version:
|
|
85
|
+
version: 0.0.9
|
|
86
86
|
type: :runtime
|
|
87
87
|
prerelease: false
|
|
88
88
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -90,7 +90,7 @@ dependencies:
|
|
|
90
90
|
requirements:
|
|
91
91
|
- - ! '>='
|
|
92
92
|
- !ruby/object:Gem::Version
|
|
93
|
-
version:
|
|
93
|
+
version: 0.0.9
|
|
94
94
|
- !ruby/object:Gem::Dependency
|
|
95
95
|
name: guid
|
|
96
96
|
requirement: !ruby/object:Gem::Requirement
|