~ubuntu-branches/ubuntu/intrepid/tcm/intrepid

« back to all changes in this revision

Viewing changes to src/dg/diagramchecks.c

  • Committer: Bazaar Package Importer
  • Author(s): Otavio Salvador
  • Date: 2003-07-03 20:08:21 UTC
  • Revision ID: james.westby@ubuntu.com-20030703200821-se4xtqx25e5miczi
Tags: upstream-2.20
ImportĀ upstreamĀ versionĀ 2.20

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
////////////////////////////////////////////////////////////////////////////////
 
2
//
 
3
// This file is part of Toolkit for Conceptual Modeling (TCM).
 
4
// (c) copyright 1997, Vrije Universiteit Amsterdam.
 
5
// Author: Frank Dehne (frank@cs.vu.nl).
 
6
//
 
7
// TCM is free software; you can redistribute it and/or modify
 
8
// it under the terms of the GNU General Public License as published by
 
9
// the Free Software Foundation; either version 2 of the License, or
 
10
// (at your option) any later version.
 
11
//
 
12
// TCM is distributed in the hope that it will be useful,
 
13
// but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
// GNU General Public License for more details.
 
16
//
 
17
// You should have received a copy of the GNU General Public License
 
18
// along with TCM; if not, write to the Free Software
 
19
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 
20
// 02111-1307, USA.
 
21
////////////////////////////////////////////////////////////////////////////////
 
22
#include "graph.h"
 
23
#include "diagram.h"
 
24
#include "node.h"
 
25
#include "edge.h"
 
26
#include "diagramchecks.h"
 
27
 
 
28
DiagramChecks::DiagramChecks(Diagram *d, Graph *g) {
 
29
        diagram = d;
 
30
        graph = g;
 
31
}
 
32
 
 
33
unsigned DiagramChecks::CheckCount(unsigned min, unsigned max,
 
34
                int type, string &chkbuf, bool node) {
 
35
        unsigned total;
 
36
        List<Subject *> s;
 
37
        if (node)
 
38
                total = graph->GetNodes(&s, type);
 
39
        else
 
40
                total = graph->GetEdges(&s, type);
 
41
        if (total < min || total > max) {
 
42
                chkbuf += "* Error: diagram has ";
 
43
                chkbuf += total;
 
44
                chkbuf += ' ';
 
45
                chkbuf += Code::GetName(type);
 
46
                if (total != 1)
 
47
                        chkbuf.addPlural();
 
48
                chkbuf += "\n";
 
49
                diagram->SelectSubjects(&s);
 
50
                return 1;
 
51
        }
 
52
        return 0;
 
53
}
 
54
 
 
55
unsigned DiagramChecks::CheckNodeCount(unsigned count, int nodeType, 
 
56
                        string &chkbuf) {
 
57
        return CheckNodeCount(count, count, nodeType, chkbuf);
 
58
}
 
59
 
 
60
unsigned DiagramChecks::CheckNodeCount(unsigned min, unsigned max, 
 
61
                int nodeType, string &chkbuf) {
 
62
        return CheckCount(min, max, nodeType, chkbuf, True);
 
63
}
 
64
 
 
65
unsigned DiagramChecks::CheckEdgeCount(unsigned count, int edgeType, 
 
66
                        string &chkbuf) {
 
67
        return CheckEdgeCount(count, count, edgeType, chkbuf);
 
68
}
 
69
 
 
70
unsigned DiagramChecks::CheckEdgeCount(unsigned min, unsigned max, 
 
71
                int edgeType, string &chkbuf) {
 
72
        return CheckCount(min, max, edgeType, chkbuf, False);
 
73
}
 
74
 
 
75
 
 
76
unsigned DiagramChecks::CheckNamelessNodes(int nodeType, string &chkbuf) {
 
77
        string empty("");
 
78
        return CheckIllegalNodeNames(nodeType, &empty, chkbuf);
 
79
}
 
80
 
 
81
unsigned DiagramChecks::CheckNamelessEdges(int nodeType, string &chkbuf) {
 
82
        string empty("");
 
83
        return CheckIllegalEdgeNames(nodeType, &empty, chkbuf);
 
84
}
 
85
 
 
86
unsigned DiagramChecks::CheckIllegalNodeNames(int nodeType, 
 
87
                        const string *name, string &chkbuf) {
 
88
        return CheckIllegalNames(nodeType, name, chkbuf, True);
 
89
}
 
90
 
 
91
unsigned DiagramChecks::CheckIllegalEdgeNames(int edgeType, 
 
92
                        const string *name, string &chkbuf) {
 
93
        return CheckIllegalNames(edgeType, name, chkbuf, False);
 
94
}
 
95
 
 
96
unsigned DiagramChecks::CheckIllegalNames(int type, const string *name, 
 
97
                string &chkbuf, bool node) {
 
98
        unsigned total;
 
99
        List<Subject *> s;
 
100
        if (node)
 
101
                total = graph->GetNodes(&s, name, type);
 
102
        else
 
103
                total = graph->GetEdges(&s, name, type);
 
104
        if (total != 0) {
 
105
                chkbuf += "* Error: there ";
 
106
                if (total == 1) chkbuf += "is "; else chkbuf += "are ";
 
107
                chkbuf += total;
 
108
                chkbuf += " ";
 
109
                chkbuf += Code::GetName(type);
 
110
                if (node)
 
111
                        chkbuf += " node";
 
112
                else
 
113
                        chkbuf += " edge";
 
114
                if (total != 1)
 
115
                        chkbuf.addPlural();
 
116
                if (*name == "")
 
117
                        chkbuf += " without name";
 
118
                else {
 
119
                        chkbuf += " named '";
 
120
                        chkbuf += *name;
 
121
                        chkbuf += "'";
 
122
                }
 
123
                chkbuf += "\n";
 
124
                diagram->SelectSubjects(&s);
 
125
        }
 
126
        return total;
 
127
}
 
128
 
 
129
 
 
130
unsigned DiagramChecks::CheckNamelessEdges(int edgeType, 
 
131
                        int subjectType1, int subjectType2, string &chkbuf) {
 
132
        List<Subject *> edges;
 
133
        unsigned total=0;
 
134
        string empty("");
 
135
        graph->GetEdges(&edges, &empty, edgeType);
 
136
        for (edges.first(); !edges.done(); edges.next()){
 
137
                Edge *edge = (Edge *)edges.cur();
 
138
                Subject *subject1 = edge->GetSubject1();
 
139
                Subject *subject2 = edge->GetSubject2();
 
140
                if (subject1->GetClassType() == subjectType1 &&
 
141
                    subject2->GetClassType() == subjectType2) {
 
142
                        chkbuf += "* Error: there is an unnamed ";
 
143
                        chkbuf +=  Code::GetName(edgeType);
 
144
                        chkbuf += " between ";
 
145
                        chkbuf +=  Code::GetName(subjectType1);
 
146
                        chkbuf += " '";
 
147
                        chkbuf += *subject1->GetName();
 
148
                        chkbuf += "'";
 
149
                        chkbuf += " and ";
 
150
                        chkbuf +=  Code::GetName(subjectType2);
 
151
                        chkbuf += " '";
 
152
                        chkbuf += *subject2->GetName();
 
153
                        chkbuf += "'\n";
 
154
                        total++;
 
155
                        diagram->SelectSubject(edge);
 
156
                }
 
157
        }
 
158
        return total;
 
159
}
 
160
 
 
161
unsigned DiagramChecks::CheckDoubleNamelessEdges(
 
162
                int edgeType, int subjType1, int subjType2, string &chkbuf) {
 
163
        string s("");
 
164
        unsigned total = 0;
 
165
        List<Subject *> subjs_from;
 
166
        List<Subject *> subjs_to;
 
167
        List<Subject *> edges;
 
168
        graph->GetNodes(&subjs_from, subjType1);
 
169
        if (subjs_from.count() == 0)
 
170
                graph->GetEdges(&subjs_from, subjType1);
 
171
        graph->GetNodes(&subjs_to, subjType2);
 
172
        if (subjs_to.count() == 0)
 
173
                graph->GetEdges(&subjs_to, subjType2);
 
174
        string empty("");
 
175
        for (subjs_from.first(); !subjs_from.done(); subjs_from.next()) {
 
176
                Subject *subj1 = subjs_from.cur();
 
177
                for (subjs_to.first(); !subjs_to.done(); subjs_to.next()) {
 
178
                        Subject *subj2 = subjs_to.cur();
 
179
                        graph->GetEdges(&edges, subj1, subj2, &empty, 
 
180
                                        edgeType);
 
181
                        unsigned count = edges.count();
 
182
                        if (count > 1) {
 
183
                                chkbuf += "* Error: there are ";
 
184
                                chkbuf += count;
 
185
                                chkbuf += " unnamed ";
 
186
                                chkbuf += Code::GetName(edgeType);
 
187
                                chkbuf.addPlural();
 
188
                                chkbuf += " between ";
 
189
                                chkbuf +=  Code::GetName(subjType1);
 
190
                                chkbuf += " '";
 
191
                                chkbuf += *subj1->GetName();
 
192
                                chkbuf += "'";
 
193
                                chkbuf += " and ";
 
194
                                chkbuf +=  Code::GetName(subjType2);
 
195
                                chkbuf += " '";
 
196
                                chkbuf += *subj2->GetName();
 
197
                                chkbuf += "'\n";
 
198
                                total++;
 
199
                                diagram->SelectSubjects(&edges);
 
200
                        }
 
201
                        edges.empty();
 
202
                }
 
203
        }
 
204
        return total;
 
205
}
 
206
 
 
207
unsigned DiagramChecks::CheckDoubleNodes(int nodeType, string &chkbuf) {
 
208
        unsigned total = 0;
 
209
        List<Subject *> nodes;
 
210
        List<string> strings_got;
 
211
        graph->GetNodes(&nodes, nodeType);
 
212
        for (nodes.first(); !nodes.done(); nodes.next()) {
 
213
                Subject *node = nodes.cur();
 
214
                string name = *node->GetName();
 
215
                if (name != "" && strings_got.find(name) == -1) {
 
216
                        List<Subject *> s;
 
217
                        unsigned card = graph->GetNodes(&s, &name, nodeType);
 
218
                        if (card != 1) {
 
219
                                chkbuf += "* Error: there are "; 
 
220
                                chkbuf += card;
 
221
                                chkbuf += ' ';
 
222
                                chkbuf += Code::GetName(nodeType);
 
223
                                chkbuf.addPlural();
 
224
                                chkbuf += " named '";
 
225
                                chkbuf += name;
 
226
                                chkbuf += "'\n";
 
227
                                total++;
 
228
                                diagram->SelectSubjects(&s);
 
229
                        }
 
230
                        strings_got.add(name);
 
231
                }
 
232
        }
 
233
        return total;
 
234
}
 
235
 
 
236
unsigned DiagramChecks::CheckConnected(int nodeType, bool index, string &chkbuf) {
 
237
        unsigned total = 0;
 
238
        List<Subject *> nodes;
 
239
        List<Subject *> edges;
 
240
        graph->GetNodes(&nodes, nodeType);
 
241
        for (nodes.first(); !nodes.done(); nodes.next()) {
 
242
                Subject *node = nodes.cur();
 
243
                graph->CompleteSubject(&edges, node);
 
244
                if (edges.count() < 1) {
 
245
                        chkbuf += "* Error: ";
 
246
                        chkbuf += Code::GetName(nodeType);
 
247
                        chkbuf += " ";
 
248
                        if (index && !node->IsEdge())
 
249
                                chkbuf += *((Node *)node)->GetIndex();
 
250
                        else {
 
251
                                chkbuf += "'";
 
252
                                chkbuf += *node->GetName();
 
253
                                chkbuf += "'";
 
254
                        }
 
255
                        chkbuf += " is not connected\n";
 
256
                        total++;
 
257
                        diagram->SelectSubject(node);
 
258
                }
 
259
                edges.empty();
 
260
        }
 
261
        return total;
 
262
}
 
263
 
 
264
unsigned DiagramChecks::CheckConnected(int fromType, int toType, int min, int max, 
 
265
                bool index, string &chkbuf) {
 
266
        unsigned total = 0;
 
267
        List<Subject *> subjects;
 
268
        List<Subject *> edges;
 
269
        List<Subject *> subjects2;
 
270
        graph->GetNodes(&subjects, fromType);
 
271
        for (subjects.first(); !subjects.done(); subjects.next()) {
 
272
                Subject *subject = subjects.cur();
 
273
                graph->CompleteSubject(&edges, subject);
 
274
                int n = 0;
 
275
                for (edges.first(); !edges.done(); edges.next()) {
 
276
                        Edge *edge = (Edge *)edges.cur();
 
277
                        Subject *s2;
 
278
                        if (edge->GetSubject1()==subject)
 
279
                                s2 = edge->GetSubject2();
 
280
                        else
 
281
                                s2 = edge->GetSubject1();
 
282
                        if (s2->GetClassType()==toType)
 
283
                                n++;
 
284
                        subjects2.add(s2);
 
285
                }
 
286
                if (n<min || n>max) {
 
287
                        chkbuf += "* Error: ";
 
288
                        chkbuf += Code::GetName(fromType);
 
289
                        chkbuf += " ";
 
290
                        if (index && !subject->IsEdge()) 
 
291
                                chkbuf += *((Node *)subject)->GetIndex();
 
292
                        else {
 
293
                                chkbuf += "'";
 
294
                                chkbuf += *subject->GetName();
 
295
                                chkbuf += "'";
 
296
                        }
 
297
                        chkbuf += " is ";
 
298
                        chkbuf += n;
 
299
                        chkbuf += " times connected to some ";
 
300
                        chkbuf += Code::GetName(toType);
 
301
                        if (n != 1)
 
302
                                chkbuf.addPlural();
 
303
                        chkbuf += " (it should be ";
 
304
                        if (n<min) {
 
305
                                chkbuf += "at least ";
 
306
                                chkbuf += min;
 
307
                        }
 
308
                        else {
 
309
                                chkbuf += "at most ";
 
310
                                chkbuf += max;
 
311
                        }
 
312
                        chkbuf += " times)\n";
 
313
                        diagram->SelectSubject(subject);
 
314
                        diagram->SelectSubjects(&subjects2);
 
315
                        total++;
 
316
                }
 
317
                edges.empty();
 
318
                subjects2.empty();
 
319
        }
 
320
        return total;
 
321
}
 
322
 
 
323
unsigned DiagramChecks::CheckJunctionCoherence(int nodeType, int parenttype, 
 
324
                        int childtype, unsigned minChildren, string &chkbuf) {
 
325
        unsigned total = 0;
 
326
        unsigned unconnected = 0;
 
327
        unsigned no_parent = 0;
 
328
        unsigned no_child = 0;
 
329
        unsigned few_child = 0;
 
330
        unsigned double_parent = 0;
 
331
        // Check for not properly connected junctions.
 
332
        List<Subject *> nodes;
 
333
        List<Subject *> edges;
 
334
        List<Subject *> errorNodes;
 
335
        graph->GetNodes(&nodes, nodeType);
 
336
        for (nodes.first(); !nodes.done(); nodes.next()) {
 
337
                Subject *node = nodes.cur();
 
338
                graph->CompleteSubject(&edges, node);
 
339
                // count nr. of parent and child edges.
 
340
                bool error = False;
 
341
                unsigned parent = 0;
 
342
                unsigned child = 0;
 
343
                for (edges.first(); !edges.done(); edges.next()) {
 
344
                        Edge *e = (Edge *)edges.cur();
 
345
                        if (parenttype != childtype) {
 
346
                                if (e->GetClassType() == parenttype)
 
347
                                        parent += 1;
 
348
                                else if (e->GetClassType() == childtype)
 
349
                                        child += 1;
 
350
                        }
 
351
                        else {
 
352
                                if (e->GetClassType() == parenttype) {
 
353
                                        if (e->GetSubject1()==node)
 
354
                                                parent++;
 
355
                                        else if (e->GetSubject2()==node)
 
356
                                                child++;
 
357
                                }
 
358
                        }
 
359
                }
 
360
                if (parent == 0 && child == 0) {
 
361
                        unconnected++;
 
362
                        error = True;
 
363
                }
 
364
                else if (parent == 0) {
 
365
                        no_parent++;
 
366
                        error = True;
 
367
                }
 
368
                else if (child == 0) {
 
369
                        no_child++;
 
370
                        error = True;
 
371
                }
 
372
                else if (child < minChildren) {
 
373
                        few_child++;
 
374
                        error = True;
 
375
                }
 
376
                else if (parent > 1) {
 
377
                        double_parent++;
 
378
                        error = True;
 
379
                }
 
380
                if (error) {
 
381
                        total++;
 
382
                        errorNodes.add(node);
 
383
                }
 
384
                edges.empty();
 
385
        }
 
386
        if (unconnected != 0) {
 
387
                chkbuf += "* Error: there ";
 
388
                if (unconnected == 1) chkbuf += "is "; else chkbuf += "are ";
 
389
                chkbuf += unconnected;
 
390
                chkbuf += " unconnected ";
 
391
                chkbuf += Code::GetName(nodeType);
 
392
                if (unconnected != 1)
 
393
                        chkbuf.addPlural();
 
394
                chkbuf += "\n";
 
395
        }
 
396
        if (no_child != 0) {
 
397
                chkbuf += "* Error: there ";
 
398
                if (no_child == 1) chkbuf += "is "; else chkbuf += "are ";
 
399
                chkbuf += no_child;
 
400
                chkbuf += ' ';
 
401
                chkbuf += Code::GetName(nodeType);
 
402
                if (no_child != 1)
 
403
                        chkbuf.addPlural();
 
404
                chkbuf += " not connected by some ";
 
405
                chkbuf += Code::GetName(childtype);
 
406
                chkbuf += "\n";
 
407
        }
 
408
        if (no_parent != 0) {
 
409
                chkbuf += "* Error: there ";
 
410
                if (no_parent == 1) chkbuf += "is "; else chkbuf += "are ";
 
411
                chkbuf += no_parent;
 
412
                chkbuf += ' ';
 
413
                chkbuf += Code::GetName(nodeType);
 
414
                if (no_parent != 1)
 
415
                        chkbuf.addPlural();
 
416
                chkbuf += " not connected by a single ";
 
417
                chkbuf += Code::GetName(parenttype);
 
418
                chkbuf += "\n";
 
419
        }
 
420
        if (few_child != 0) {
 
421
                chkbuf += "* Error: there ";
 
422
                if (few_child == 1) chkbuf += "is "; else chkbuf += "are ";
 
423
                chkbuf += few_child;
 
424
                chkbuf += ' ';
 
425
                chkbuf += Code::GetName(nodeType);
 
426
                if (few_child != 1)
 
427
                        chkbuf.addPlural();
 
428
                chkbuf += " connected by too few ";
 
429
                chkbuf += Code::GetName(childtype);
 
430
                chkbuf.addPlural();
 
431
                chkbuf += "\n";
 
432
        }
 
433
        if (double_parent != 0) {
 
434
                chkbuf += "* Error: there ";
 
435
                if (double_parent == 1) chkbuf += "is "; else chkbuf += "are ";
 
436
                chkbuf += double_parent;
 
437
                chkbuf += ' ';
 
438
                chkbuf += Code::GetName(nodeType);
 
439
                if (double_parent != 1)
 
440
                        chkbuf.addPlural();
 
441
                chkbuf += " connected by more than one ";
 
442
                chkbuf += Code::GetName(parenttype);
 
443
                chkbuf += "\n";
 
444
        }
 
445
        diagram->SelectSubjects(&errorNodes);
 
446
        return total;
 
447
}
 
448
 
 
449
unsigned DiagramChecks::CheckCountEdgesFrom(int nType, int eType, unsigned min, 
 
450
                unsigned max, bool zero_allowed, bool index, string &chkbuf) {
 
451
        unsigned total = 0;
 
452
        List<Subject *> nodes;
 
453
        List<Subject *> edges;
 
454
        graph->GetNodes(&nodes, nType);
 
455
        graph->GetEdges(&edges, eType);
 
456
        for (nodes.first(); !nodes.done(); nodes.next()) {
 
457
                unsigned n = 0;
 
458
                Subject *subject = (Subject *)(nodes.cur());
 
459
                for (edges.first(); !edges.done(); edges.next()) {
 
460
                        Edge *e = (Edge *)edges.cur();
 
461
                        if (e->GetSubject1() == subject)
 
462
                                n += 1;
 
463
                }
 
464
                if ((n > max || n < min) && (!zero_allowed || n > 0)) {
 
465
                        chkbuf += "* Error: ";
 
466
                        chkbuf += Code::GetName(nType);
 
467
                        chkbuf += " ";
 
468
                        if (index && !subject->IsEdge()) 
 
469
                                chkbuf += *((Node *)subject)->GetIndex();
 
470
                        else {
 
471
                                chkbuf += "'";
 
472
                                chkbuf += *subject->GetName();
 
473
                                chkbuf += "'";
 
474
                        }
 
475
                        chkbuf += " has ";
 
476
                        chkbuf += n;
 
477
                        chkbuf += " departing ";
 
478
                        chkbuf += Code::GetName(eType);
 
479
                        if (n != 1)
 
480
                                chkbuf.addPlural();
 
481
                        chkbuf += " (it should be ";
 
482
                        if (n<min) {
 
483
                                chkbuf += "at least ";
 
484
                                chkbuf += min;
 
485
                        }
 
486
                        else {
 
487
                                chkbuf += "at most ";
 
488
                                chkbuf += max;
 
489
                        }
 
490
                        chkbuf += ")\n";
 
491
                        diagram->SelectSubject(subject);
 
492
                        total++;
 
493
                }
 
494
        }
 
495
        return total;
 
496
}
 
497
 
 
498
unsigned DiagramChecks::CheckReachability(
 
499
                int rootType, int nodeType, bool index, string &chkbuf) {
 
500
        unsigned total = 0;
 
501
        unsigned unnamed = 0;
 
502
        List<Subject *> roots, nodes;
 
503
        graph->GetNodes(&roots, rootType);
 
504
        graph->GetNodes(&nodes, nodeType);
 
505
        // look for each node if there is a path from one of the
 
506
        // roots.
 
507
        for (nodes.first(); !nodes.done(); nodes.next()) {
 
508
                bool pathFound = False;
 
509
                Node *node = (Node *)nodes.cur();
 
510
                for (roots.first(); !roots.done(); roots.next()) {
 
511
                        Node *root = (Node *)roots.cur();
 
512
                        if (graph->PathExists(root, node))
 
513
                                pathFound = True; 
 
514
                }
 
515
                if (!pathFound) {
 
516
                        // do not report unnamed nodes individually.
 
517
                        diagram->SelectSubject(node);
 
518
                        if (!index && *node->GetName() == "") {
 
519
                                total++;
 
520
                                unnamed++; 
 
521
                                continue;
 
522
                        }
 
523
                        chkbuf += "* Error: ";
 
524
                        chkbuf += Code::GetName(nodeType);
 
525
                        chkbuf += " ";
 
526
                        if (index)
 
527
                                chkbuf += *node->GetIndex();
 
528
                        else {
 
529
                                chkbuf += "'";
 
530
                                chkbuf += *node->GetName();
 
531
                                chkbuf += "'";
 
532
                        }
 
533
                        chkbuf += " is not reachable from some ";
 
534
                        chkbuf += Code::GetName(rootType);
 
535
                        chkbuf += "\n";
 
536
                        total++;
 
537
                }
 
538
        }
 
539
        // report about the number of unnamed unreachable nodes found.
 
540
        if (unnamed != 0) {
 
541
                chkbuf += "* Error: there ";
 
542
                if (total == 1) chkbuf += "is "; else chkbuf += "are ";
 
543
                chkbuf += total;
 
544
                chkbuf += " unnamed ";
 
545
                chkbuf += Code::GetName(nodeType);
 
546
                if (total != 1)
 
547
                        chkbuf.addPlural();
 
548
                chkbuf += " unreachable from some ";
 
549
                chkbuf += Code::GetName(rootType);
 
550
                chkbuf += "\n";
 
551
        }
 
552
        return total;
 
553
}
 
554
 
 
555
unsigned DiagramChecks::CheckDoubleIndexes(string &chkbuf) {
 
556
        unsigned total = 0;
 
557
        List<Subject *> nodes;
 
558
        List<Subject *> nodes2;
 
559
        List<string> strings_got;
 
560
        graph->GetNodes(&nodes);
 
561
        for (nodes.first(); !nodes.done(); nodes.next()) {
 
562
                Node *node = (Node *)nodes.cur();
 
563
                const string *s = node->GetIndex();
 
564
                if (*s != "" && strings_got.find(*s) == -1) {
 
565
                        unsigned card = 0;
 
566
                        graph->GetNodes(&nodes2);
 
567
                        List<Subject *> errorNodes;
 
568
                        for (nodes2.first(); !nodes2.done(); nodes2.next()) {
 
569
                                Node *n = (Node *) nodes2.cur();
 
570
                                if (*n->GetIndex() == *s) {
 
571
                                        errorNodes.add(n);
 
572
                                        card++;
 
573
                                }
 
574
                        }
 
575
                        nodes2.empty();
 
576
                        if (card != 1) {
 
577
                                total++;
 
578
                                chkbuf += "* Error: there are ";
 
579
                                chkbuf += card;
 
580
                                chkbuf += " nodes having index ";
 
581
                                chkbuf += *s;
 
582
                                chkbuf += "\n";
 
583
                                diagram->SelectSubjects(&errorNodes);
 
584
                        }
 
585
                        strings_got.add(*s);
 
586
                        errorNodes.empty();
 
587
                }
 
588
        }
 
589
        return total;
 
590
}