-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrule.cpp
165 lines (144 loc) · 5.2 KB
/
rule.cpp
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
// Author: Kristi Daigh
// Project: MLEM2 Rule Induction
// Date: 11/20/2019
/** Source file for the rule class.
@file rule.cpp */
#include "avNumeric.hpp"
#include "rule.hpp"
#include "utils.hpp"
using namespace std;
int Rule::idCount = 0;
Rule::Rule() :
id(idCount++){ }
void Rule::addCondition(int index){
m_conditions.insert(index);
}
void Rule::removeCondition(int index){
m_conditions.erase(index);
}
bool Rule::containsCondition(int index) const {
if(m_conditions.find(index) == m_conditions.end()){
return false;
}
return true;
}
void Rule::setConditions(set<int> conditions){
m_conditions = conditions;
}
set<int> Rule::getConditions() const {
return m_conditions;
}
set<int> Rule::getBlock(vector<AV *> avBlocks) const {
if(m_conditions.empty()){
return m_conditions;
}
vector<set<int>> blocks;
for(int i : m_conditions){
blocks.push_back(avBlocks[i]->getBlock());
}
return (setsIntersection(blocks));
}
set<int> Rule::getAttributeGroup(vector<AV *> avBlocks, int index) const {
set<int> result;
for( int i : m_conditions ){
if( (i != index) && (avBlocks[index]->getAttr() == avBlocks[i]->getAttr()) ){
result.insert(i);
}
}
return result;
}
void Rule::mergeIntervals(vector<AV *> avBlocks){
if(m_conditions.size() <= 1){
return;
}
for(auto first = m_conditions.begin(); first != m_conditions.end();){
cout << "first: " << (*first);
bool modified = false;
for(auto second = next(first); second != m_conditions.end();){
cout << " second: " << (*second) << endl;
// IF: Current block is numeric
if(avBlocks[(*first)]->isNumeric()){
// IF: Blocks share the same attribute
if(avBlocks[(*first)]->getAttr() == avBlocks[(*second)]->getAttr()){
int mergedMin = max(avBlocks[(*first)]->getMinValue(), avBlocks[(*second)]->getMinValue());
int mergedMax = min(avBlocks[(*first)]->getMaxValue(), avBlocks[(*second)]->getMaxValue());
// IF: Intervals of blocks overlap
if(mergedMax > mergedMin){
#if DEBUG==true
cout << "Merging interval " << mergedMin << ".." << mergedMax << endl;
#endif
modified = true;
// Find or create merged attribute-value block
int pos = -1;
for(int i = 0; i < avBlocks.size(); i++){
if(avBlocks[i]->getMinValue() == mergedMin && avBlocks[i]->getMaxValue() == mergedMax){
pos = i;
break;
}
}
if(pos == -1){
pos = avBlocks.size();
avBlocks.push_back(new AVNumeric(avBlocks[(*first)]->getAttr(), -1, mergedMin, mergedMax));
avBlocks[pos]->setBlock(setIntersection(avBlocks[(*first)]->getBlock(), avBlocks[(*second)]->getBlock()));
}
cout << "pos: " << pos << endl;
// Update set of conditions
// IF: Second immediately follows first
if(second == next(first)){
m_conditions.erase(second);
first = m_conditions.erase(first);
}
else {
first = m_conditions.erase(first);
m_conditions.erase(second);
}
second = next(first);
m_conditions.insert(pos);
break;
} // end if
} // end if
} // end if
printSet("m_conditions = ", m_conditions);
if(second != m_conditions.end()){ ++second; }
} // end for
if(!modified && first != m_conditions.end()){ ++first; }
} // end for
}
void Rule::dropConditions(vector<AV *> avBlocks, set<int> B){
// IF: Rule has one or less condition
if(m_conditions.size() <= 1){
return;
}
// Else: Rule has at least two conditions
set<int>::iterator iter;
for(iter = m_conditions.begin(); iter != m_conditions.end();){
Rule r = *this;
r.removeCondition(*iter);
if(subsetEq(r.getBlock(avBlocks), B)){
#if DEBUG==true
cout << "Dropping condition " << avBlocks[*iter]->labelString() << endl;
#endif
iter = m_conditions.erase(iter);
} else {
iter++;
}
}
}
string Rule::toString(vector<AV *> avBlocks) const {
stringstream stream;
unsigned index = 0;
for(int c : m_conditions){
stream << avBlocks[c]->labelString();
if(index + 1 != m_conditions.size()){
stream << " & ";
}
index++;
}
return stream.str();
}
size_t Rule::size() const {
return m_conditions.size();
}
bool Rule::empty() const {
return m_conditions.empty();
}