This repository has been archived by the owner on Jun 2, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
kb.go
100 lines (88 loc) · 2.13 KB
/
kb.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
package main
import (
"regexp"
"time"
)
var (
clauses []string
volatileMemory map[string]string
rgx = regexp.MustCompile(`^Run\((.*?)\)`)
)
func InitializeKB() {
volatileMemory = make(map[string]string)
}
func AddClause(clause string) bool {
clauses = append(clauses, clause)
return true
}
func RemoveClause(targetClause string) bool {
for i, clause := range clauses {
if clause == targetClause {
clauses = append(clauses[:i], clauses[i+1:]...)
return true
}
}
return false
}
func PrintClauses() []string {
return clauses
}
func PrintMemory() map[string]string {
return volatileMemory
}
func ClearMemory(subject string) {
delete(volatileMemory, subject)
}
func Ask() (plugins []string) {
for i := 0; i < len(clauses); i++ {
rs := rgx.FindStringSubmatch(clauses[i])
if len(rs) >= 1 {
plugins = append(plugins, rs[1])
}
}
return
}
// RunKnowledgebase handles KB related requests via channels
func RunKnowledgebase(fromMeasure chan RMQMessage, toScheduler chan string) {
for {
select {
case message := <-fromMeasure:
addMeasure(message)
// Let scheduler know if there is any
// interesting measure occurred
if reasoning(message.Topic, memory[message.Topic]) {
toScheduler <- "knowledgebase"
}
}
}
}
func addMeasure(message RMQMessage) {
measure := Measure{
Timestamp: time.Unix(0, message.Timestamp),
Value: message.Value,
}
if _, ok := memory[message.Topic]; !ok {
memory[message.Topic] = CreateTimeseriesMeasure(&measure)
} else {
timeSeriesMeasures := memory[message.Topic]
timeSeriesMeasures.Add(&measure)
}
}
// reasoning reasons about the received measure using rules
// to see if it logically entails a clause that matches
// any registered conditions
func reasoning(topic string, measures *TimeseriesMeasures) bool {
// TODO: this will be removed as we bring KB here
if topic == "env.rain_gauge" {
_, value := measures.Get()
if value > 3. {
AddClause("Rain(Now)")
AddClause("Run(Cloud)")
} else {
RemoveClause("Rain(Now)")
RemoveClause("Run(Cloud)")
}
}
// TODO: return true only when there is an interesting change occurred
return true
}