kDB: Knowledge DataBase
Loading...
Searching...
No Matches
CompareSPARQLResults.h
1#include <QDebug>
2
3#include <knowCore/IOFormat.h>
4#include <knowCore/Logging.h>
5#include <knowDBC/Result.h>
6#include <knowRDF/BlankNode.h>
7#include <knowRDF/Graph.h>
8#include <knowRDF/Literal.h>
9#include <knowRDF/Node.h>
10#include <knowCore/Uris/xsd.h>
11
12namespace
13{
14 namespace details
15 {
16 QDebug& print(QDebug& _debug, const knowCore::Value& _value)
17 {
18 _debug << "<" << _value.datatype() << ">(";
19 auto const& [s, v, m] = _value.printable();
20 if(s)
21 {
22 _debug << v;
23 } else {
24 _debug << "err: " << m;
25 }
26 _debug << ")";
27 return _debug;
28 }
29 bool comparable_special(const knowCore::Value& _v1, const knowCore::Value& _v2)
30 {
31 auto const& [s, v, m] = _v1.compare(_v2, knowCore::ComparisonOperator::AlmostEqual);
32 return s and v;
33 }
34 }
35 void printFields(const knowDBC::Result& r)
36 {
37 QDebug warn = qWarning().nospace();
38 warn << IOFormat::bold << "Fields: " << IOFormat::reset;
39 for(int j = 0; j < r.fields(); ++j)
40 {
41 warn << r.fieldName(j);
42 }
43 }
44 void printResults(const knowDBC::Result& r)
45 {
46 for(int j = 0; j < r.tuples(); ++j)
47 {
48 QDebug warn = qWarning().nospace();
49 warn << IOFormat::bold << j << "th: " << IOFormat::reset;
50 for(int k = 0; k < r.fields(); ++k)
51 {
52 details::print(warn, r.value(j, k)) << " ";
53 }
54 }
55 }
56 void printAll(const knowDBC::Result& r1, const knowDBC::Result& r2)
57 {
58 qWarning().nospace() << IOFormat::blue << "Possible reference values were" << IOFormat::reset;
59 printFields(r2);
60 printResults(r2);
61 qWarning().nospace() << IOFormat::red << "Tested values were" << IOFormat::reset;
62 printFields(r1);
63 printResults(r1);
64 }
65 inline bool compare_tuples(const knowDBC::Result& r1, const knowDBC::Result& r2)
66 {
67 QVector<bool> indexes(r2.tuples(), false);
68 for(int i = 0; i < r1.tuples(); ++i)
69 {
70 bool found_one = false;
71 for(int j = 0; j < r2.tuples(); ++j)
72 {
73 if(not indexes[j])
74 {
75 bool equal_tuple = true;
76 for(int k = 0; k < r1.fields(); ++k)
77 {
78 knowCore::Value val1 = r1.value(i, k);
79 knowCore::Value val2 = r2.value(j, r2.fieldIndex(r1.fieldName(k)));
80 if(val1 != val2 and (not knowCore::ValueIs<knowRDF::BlankNode>(val1) or not knowCore::ValueIs<knowRDF::BlankNode>(val2)) and not details::comparable_special(val1, val2))
81 {
82 equal_tuple = false;
83 break;
84 }
85 }
86 if(equal_tuple)
87 {
88 found_one = true;
89 indexes[j] = true;
90 break;
91 }
92 }
93 }
94 if(not found_one)
95 {
96 {
97 QDebug warn = qWarning().nospace();
98 warn << IOFormat::red << "Error: No match for " << i << "th tuple: " << IOFormat::reset;
99 for(int k = 0; k < r1.fields(); ++k)
100 {
101 details::print(warn, r1.value(i, k)) << " ";
102 }
103 }
104 printAll(r1, r2);
105 return false;
106 }
107 }
108 return true;
109 }
110 namespace details
111 {
112 inline void print_one(QDebug& warn, const knowRDF::Node* node)
113 {
114 switch(node->type())
115 {
116 case knowRDF::Node::Type::Undefined:
117 warn << "undefined";
118 break;
119 case knowRDF::Node::Type::Uri:
120 warn << node->uri();
121 break;
122 case knowRDF::Node::Type::BlankNode:
123 warn << node->blankNode();
124 break;
125 case knowRDF::Node::Type::Literal:
126 warn << node->literal();
127 break;
128 case knowRDF::Node::Type::Variable:
129 warn << node->variable();
130 break;
131 }
132 }
133 inline void print(QDebug& warn, const knowRDF::Node* node)
134 {
135 QMultiHash<knowCore::Uri, const knowRDF::Node*> children = node->children();
136 warn << "{";
137 print_one(warn, node);
138 warn << " -> ";
139 for(QMultiHash<knowCore::Uri, const knowRDF::Node*>::const_iterator it = children.begin(); it != children.end(); ++it)
140 {
141 warn << "(" << it.key() << ", ";
142 print_one(warn, it.value());
143 warn << ")";
144 }
145 warn << "}";
146 }
147 inline bool similar(const knowRDF::Node* node1, const knowRDF::Node* node2)
148 {
149 if(node1->type() == node2->type())
150 {
151 switch(node1->type())
152 {
153 case knowRDF::Node::Type::Undefined:
154 return true;
155 case knowRDF::Node::Type::Uri:
156 return node1->uri() == node2->uri();
157 case knowRDF::Node::Type::BlankNode:
158 return true;
159 case knowRDF::Node::Type::Literal:
160 return node1->literal() == node2->literal();
161 case knowRDF::Node::Type::Variable:
162 KNOWCORE_LOG_FATAL("Impossible");
163 }
164 }
165 return false;
166 }
167 QList<QPair<knowCore::Uri, const knowRDF::Node*>> toPairList(const QMultiHash<knowCore::Uri, const knowRDF::Node*>& _hash)
168 {
170 for(QMultiHash<knowCore::Uri, const knowRDF::Node*>::const_iterator it = _hash.begin(); it != _hash.end(); ++it)
171 {
172 r.append(QPair<knowCore::Uri, const knowRDF::Node*>(it.key(), it.value()));
173 }
174 return r;
175 }
176 }
177 inline bool compare_graphs(const knowRDF::Graph* _graph_1, const knowRDF::Graph* _graph_2)
178 {
179 QList<const knowRDF::Node*> nodes_1 = _graph_1->nodes();
180 QList<const knowRDF::Node*> nodes_2 = _graph_2->nodes();
181
182 QVector<bool> indexes(nodes_2.size(), false);
183
184 for(int i = 0; i < nodes_1.size(); ++i)
185 {
186 bool found_one = false;
187 const knowRDF::Node* node1 = nodes_1[i];
188 for(int j = 0; j < nodes_2.size(); ++j)
189 {
190 const knowRDF::Node* node2 = nodes_2[j];
191 if(not indexes[j])
192 {
193 if(details::similar(node1, node2) and node1->children().size() == node2->children().size())
194 {
195 QList<QPair<knowCore::Uri, const knowRDF::Node*>> children1 = details::toPairList(node1->children());
196 QList<QPair<knowCore::Uri, const knowRDF::Node*>> children2 = details::toPairList(node2->children());
197 QVector<bool> indexes_children(children2.size(), false);
198
199 bool all_children_found = true;
200
201 for(int k = 0; k < children1.size(); ++k)
202 {
203 bool found_one_child = false;
204 QPair<knowCore::Uri, const knowRDF::Node*> c1 = children1[k];
205 for(int l = 0; l < children2.size(); ++l)
206 {
207 if(not indexes_children[l])
208 {
209 QPair<knowCore::Uri, const knowRDF::Node*> c2 = children2[l];
210 if(c1.first == c2.first and details::similar(c1.second, c2.second))
211 {
212 found_one_child = true;
213 indexes_children[l] = true;
214 break;
215 }
216 }
217 }
218 if(not found_one_child)
219 {
220 all_children_found = false;
221 }
222 }
223
224 if(all_children_found)
225 {
226 found_one = true;
227 break;
228 }
229 }
230 }
231
232 }
233 if(not found_one)
234 {
235 {
236 QDebug warn = qWarning().nospace();
237 warn << IOFormat::red << "Error: No match for " << i << "th node: ";
238 details::print(warn, node1);
239 warn << IOFormat::reset;
240 }
241 qWarning().nospace() << IOFormat::blue << "Possible reference values were" << IOFormat::reset;
242 for(int j = 0; j < nodes_2.size(); ++j)
243 {
244 QDebug warn = qWarning().nospace();
245 warn << IOFormat::bold << j << "th: ";
246 details::print(warn, nodes_2[j]);
247 warn << IOFormat::reset;
248 }
249 qWarning().nospace() << IOFormat::red << "Tested values were" << IOFormat::reset;
250 for(int j = 0; j < nodes_1.size(); ++j)
251 {
252 QDebug warn = qWarning().nospace();
253 warn << IOFormat::bold << j << "th: ";
254 details::print(warn, nodes_1[j]);
255 warn << IOFormat::reset;
256 }
257 while(true) {}
258 return false;
259 }
260
261 }
262
263 if(nodes_1.size() != nodes_2.size())
264 {
265 qWarning().nospace() << IOFormat::red << "Different test results got: " << nodes_1.size() << " expecting: " << nodes_2.size() << IOFormat::reset;
266 return false;
267 }
268
269 return true;
270 }
271}
Definition Revision.h:9
Definition Value.h:445
Definition Value.h:21
Uri datatype() const
Definition Value.cpp:230
cres_qresult< bool > compare(const Value &_value, ComparisonOperators _operators) const
Definition Value.cpp:316
Definition Result.h:23
int fieldIndex(const QString &_name) const
Definition Result.cpp:77
QString fieldName(int _index) const
Definition Result.h:65
Definition Graph.h:10
Definition Node.h:17
knowCore::Uri uri() const
Definition Node.cpp:121
QString variable() const
Definition Node.cpp:119
Literal literal() const
Definition Node.cpp:123
QMultiHash< knowCore::Uri, const Node * > children() const
Definition Node.cpp:157
BlankNode blankNode() const
Definition Node.cpp:117
Type type() const
Definition Node.cpp:125