source: proiecte/Parallel-DT/R8/Src/rules.c @ 24

Last change on this file since 24 was 24, checked in by (none), 14 years ago

blabla

File size: 10.5 KB
Line 
1/*************************************************************************/
2/*                                                                       */
3/*      Miscellaneous routines for rule handling                         */
4/*      ----------------------------------------                         */
5/*                                                                       */
6/*************************************************************************/
7
8
9#include "defns.i"
10#include "types.i"
11#include "extern.i"
12#include "rulex.i"
13
14extern  FILE    *TRf;           /* rules file */
15
16
17Test    *TestVec;
18short   NTests = 0;
19
20FILE    *fopen();
21extern char     Fn[500];        /* file name */
22
23
24/*************************************************************************/
25/*                                                                       */
26/*  Save the current ruleset in rules file in order of the index         */
27/*                                                                       */
28/*************************************************************************/
29
30
31    SaveRules()
32/*  ----------  */
33{
34    short ri, d, v, Bytes;
35    RuleNo r;
36    Test Tst;
37
38    if ( TRf ) fclose(TRf);
39
40    strcpy(Fn, FileName);
41    strcat(Fn, ".rules");
42    if ( ! ( TRf = fopen(Fn, "w") ) ) Error(0, Fn, " for writing");
43   
44    StreamOut((char *) &NRules, sizeof(RuleNo));
45    StreamOut((char *) &DefaultClass, sizeof(ClassNo));
46
47    ForEach(ri, 1, NRules)
48    {
49        r = RuleIndex[ri];
50        StreamOut((char *) &Rule[r].Size, sizeof(short));
51        ForEach(d, 1, Rule[r].Size)
52        {
53            Tst = Rule[r].Lhs[d]->CondTest;
54
55            StreamOut((char *) &Tst->NodeType, sizeof(short));
56            StreamOut((char *) &Tst->Tested, sizeof(Attribute));
57            StreamOut((char *) &Tst->Forks, sizeof(short));
58            StreamOut((char *) &Tst->Cut, sizeof(float));
59            if ( Tst->NodeType == BrSubset )
60            {
61                Bytes = (MaxAttVal[Tst->Tested]>>3) + 1;
62                ForEach(v, 1, Tst->Forks)
63                {
64                    StreamOut((char *) Tst->Subset[v], Bytes);
65                }
66            }
67            StreamOut((char *) &Rule[r].Lhs[d]->TestValue, sizeof(short));
68        }
69        StreamOut((char *) &Rule[r].Rhs, sizeof(ClassNo));
70        StreamOut((char *) &Rule[r].Error, sizeof(float));
71    }
72
73    SaveDiscreteNames();
74}
75
76
77
78/*************************************************************************/
79/*                                                                       */
80/*      Get a new ruleset from rules file                                */
81/*                                                                       */
82/*************************************************************************/
83
84
85    GetRules()
86/*  ---------  */
87{
88    RuleNo nr, r;
89    short n, d, v, Bytes;
90    Condition *Cond;
91    Test Tst, FindTest();
92    ClassNo c;
93    float e;
94    Boolean NewRule();
95
96    if ( TRf ) fclose(TRf);
97
98    strcpy(Fn, FileName);
99    strcat(Fn, ".rules");
100    if ( ! ( TRf = fopen(Fn, "r") ) ) Error(0, Fn, "");
101   
102    StreamIn((char *) &nr, sizeof(RuleNo));
103    StreamIn((char *) &DefaultClass, sizeof(ClassNo));
104
105    ForEach(r, 1, nr)
106    {
107        StreamIn((char *) &n, sizeof(short));
108        Cond = (Condition *) calloc(n+1, sizeof(Condition));
109        ForEach(d, 1, n)
110        {
111            Tst = (Test) malloc(sizeof(struct TestRec));
112
113            StreamIn((char *) &Tst->NodeType, sizeof(short));
114            StreamIn((char *) &Tst->Tested, sizeof(Attribute));
115            StreamIn((char *) &Tst->Forks, sizeof(short));
116            StreamIn((char *) &Tst->Cut, sizeof(float));
117            if ( Tst->NodeType == BrSubset )
118            {
119                Tst->Subset = (Set *) calloc(Tst->Forks + 1, sizeof(Set));
120
121                Bytes = (MaxAttVal[Tst->Tested]>>3) + 1;
122                ForEach(v, 1, Tst->Forks)
123                {
124                    Tst->Subset[v] = (Set) malloc(Bytes);
125                    StreamIn((char *) Tst->Subset[v], Bytes);
126                }
127            }
128
129            Cond[d] = (Condition) malloc(sizeof(struct CondRec));
130            Cond[d]->CondTest = FindTest(Tst);
131            StreamIn((char *) &Cond[d]->TestValue, sizeof(short));
132        }
133        StreamIn((char *) &c, sizeof(ClassNo));
134        StreamIn((char *) &e, sizeof(float));
135        NewRule(Cond, n, c, e);
136        cfree(Cond);
137    }
138
139    RecoverDiscreteNames();
140}
141
142
143
144/*************************************************************************/
145/*                                                                       */
146/*  Find a test in the test vector; if it's not there already, add it    */
147/*                                                                       */
148/*************************************************************************/
149
150
151Test FindTest(Newtest)
152/*   ---------  */
153    Test Newtest;
154{
155    static short TestSpace=0;
156    short i;
157    Boolean SameTest();
158
159    ForEach(i, 1, NTests)
160    {
161        if ( SameTest(Newtest, TestVec[i]) )
162        {
163            cfree(Newtest);
164            return TestVec[i];
165        }
166    }
167
168    NTests++;
169    if ( NTests >= TestSpace )
170    {
171        TestSpace += 1000;
172        if ( TestSpace > 1000 )
173        {
174            TestVec = (Test *) realloc(TestVec, TestSpace * sizeof(Test));
175        }
176        else
177        {
178            TestVec = (Test *) malloc(TestSpace * sizeof(Test));
179        }
180    }
181
182    TestVec[NTests] = Newtest;
183
184    return TestVec[NTests];
185}
186
187
188
189/*************************************************************************/
190/*                                                                       */
191/*      See if test t1 is the same test as test t2                       */
192/*                                                                       */
193/*************************************************************************/
194
195
196Boolean SameTest(t1, t2)
197/*      ---------  */
198    Test t1, t2;
199{
200    short i;
201
202    if ( t1->NodeType != t2->NodeType ||
203        t1->Tested != t2->Tested )
204    {
205        return false;
206    }
207
208    switch ( t1->NodeType )
209    {
210        case BrDiscr:       return true;
211        case ThreshContin:  return  t1->Cut == t2->Cut;
212        case BrSubset:      ForEach(i, 1, t1->Forks)
213                            {
214                                if ( t1->Subset[i] != t2->Subset[i] )
215                                {
216                                    return false;
217                                }
218                            }
219    }
220    return true;
221}
222
223
224
225/*************************************************************************/
226/*                                                                       */
227/*              Clear for new set of rules                               */
228/*                                                                       */
229/*************************************************************************/
230
231
232    InitialiseRules()
233/*  ----------------  */
234{
235    NRules = 0;
236    Rule = 0;
237    RuleSpace = 0;
238}
239
240
241
242/*************************************************************************/
243/*                                                                       */
244/*  Add a new rule to the current ruleset, by updating Rule[],           */
245/*  NRules and, if necessary, RuleSpace                                  */
246/*                                                                       */
247/*************************************************************************/
248
249
250Boolean NewRule(Cond, NConds, TargetClass, Err)
251/*       -------  */
252    Condition Cond[];
253    short NConds;
254    ClassNo TargetClass;
255    float Err;
256{
257    short d, r;
258    Boolean SameRule();
259
260    /*  See if rule already exists  */
261
262    ForEach(r, 1, NRules)
263    {
264        if ( SameRule(r, Cond, NConds, TargetClass) )
265        {
266            Verbosity(1) printf("\tduplicates rule %d\n", r);
267
268            /*  Keep the most pessimistic error estimate  */
269
270            if ( Err > Rule[r].Error )
271            {
272                Rule[r].Error = Err;
273            }
274
275            return false;
276        }
277    }
278
279    /*  Make sure there is enough room for the new rule  */
280
281    NRules++;
282    if ( NRules >= RuleSpace )
283    {
284        RuleSpace += 100;
285        if ( RuleSpace > 100 )
286        {
287            Rule = (PR *) realloc(Rule, RuleSpace * sizeof(PR));
288        }
289        else
290        {
291            Rule = (PR *) malloc(RuleSpace * sizeof(PR));
292        }
293    }
294
295    /*  Form the new rule  */
296
297    Rule[NRules].Size = NConds;
298    Rule[NRules].Lhs = (Condition *) calloc(NConds+1, sizeof(Condition));
299    ForEach(d, 1, NConds)
300    {
301        Rule[NRules].Lhs[d] = (Condition) malloc(sizeof(struct CondRec));
302
303        Rule[NRules].Lhs[d]->CondTest = Cond[d]->CondTest;
304        Rule[NRules].Lhs[d]->TestValue = Cond[d]->TestValue;
305    }
306    Rule[NRules].Rhs = TargetClass;
307    Rule[NRules].Error = Err;
308
309    Verbosity(1) PrintRule(NRules);
310
311    return true;
312}
313
314
315
316/*************************************************************************/
317/*                                                                       */
318/*  Decide whether the given rule duplicates rule r                      */
319/*                                                                       */
320/*************************************************************************/
321
322
323Boolean SameRule(r, Cond, NConds, TargetClass)
324/*      --------  */
325    RuleNo r;
326    Condition Cond[];
327    short NConds;
328    ClassNo TargetClass;
329{
330    short d, i;
331    Test SubTest1, SubTest2;
332
333    if ( Rule[r].Size != NConds || Rule[r].Rhs != TargetClass )
334    {
335        return false;
336    }
337
338    ForEach(d, 1, NConds)
339    {
340        if ( Rule[r].Lhs[d]->CondTest->NodeType != Cond[d]->CondTest->NodeType ||
341             Rule[r].Lhs[d]->CondTest->Tested   != Cond[d]->CondTest->Tested )
342        {
343            return false;
344        }
345
346        switch ( Cond[d]->CondTest->NodeType )
347        {
348            case BrDiscr:
349                if ( Rule[r].Lhs[d]->TestValue != Cond[d]->TestValue )
350                {
351                    return false;
352                }
353                break;
354
355            case ThreshContin:
356                if ( Rule[r].Lhs[d]->CondTest->Cut != Cond[d]->CondTest->Cut )
357                {
358                    return false;
359                }
360                break;
361
362            case BrSubset:
363                SubTest1 = Rule[r].Lhs[d]->CondTest;
364                SubTest2 = Cond[d]->CondTest;
365                ForEach(i, 1, SubTest1->Forks)
366                {
367                    if ( SubTest1->Subset[i] != SubTest2->Subset[i] )
368                    {
369                        return false;
370                    }
371                }
372        }
373    }
374
375    return true;
376}
377
378
379
380/*************************************************************************/
381/*                                                                       */
382/*              Print the current indexed ruleset                        */
383/*                                                                       */
384/*************************************************************************/
385
386
387    PrintIndexedRules()
388/*  -----------------  */
389{
390    short ri;
391
392    ForEach(ri, 1, NRules )
393    {
394        PrintRule(RuleIndex[ri]);
395    }
396    printf("\nDefault class: %s\n", ClassName[DefaultClass]);
397}
398
399
400
401/*************************************************************************/
402/*                                                                       */
403/*              Print the rule r                                         */
404/*                                                                       */
405/*************************************************************************/
406
407
408    PrintRule(r)
409/*  ---------  */
410    RuleNo r;
411{
412    short d;
413
414    printf("\nRule %d:\n", r);
415    ForEach(d, 1, Rule[r].Size)
416    {
417        printf("    ");
418        PrintCondition(Rule[r].Lhs[d]);
419    }
420    printf("\t->  class %s  [%.1f%%]\n",
421            ClassName[Rule[r].Rhs], 100 * (1 - Rule[r].Error));
422}
423
424
425
426/*************************************************************************/
427/*                                                                       */
428/*      Print a condition c of a production rule                         */
429/*                                                                       */
430/*************************************************************************/
431
432
433    PrintCondition(c)
434/*  --------------  */
435    Condition c;
436{
437    Test tp;
438    DiscrValue v, pv, Last, Values=0;
439    Boolean First=true;
440    Attribute Att;
441
442    tp = c->CondTest;
443    v = c->TestValue;
444    Att = tp->Tested;
445
446    printf("\t%s", AttName[Att]);
447
448    if ( v < 0 )
449    {
450        printf(" is unknown\n");
451        return;
452    }
453
454    switch ( tp->NodeType )
455    {
456        case BrDiscr:
457            printf(" = %s\n", AttValName[Att][v]);
458            break;
459
460        case ThreshContin:
461            printf(" %s %g\n", ( v == 1 ? "<=" : ">" ), tp->Cut);
462            break;
463
464        case BrSubset:
465            /*  Count values at this branch  */
466
467            for ( pv=1 ; Values <= 1 && pv <= MaxAttVal[Att] ; pv++ )
468            {
469                if ( In(pv, tp->Subset[v]) )
470                {
471                    Last = pv;
472                    Values++;
473                }
474            }
475
476            if ( Values == 1 )
477            {
478                printf(" = %s\n", AttValName[Att][Last]);
479                break;
480            }
481
482            printf(" in ");
483            ForEach(pv, 1, MaxAttVal[Att])
484            {
485                if ( In(pv, tp->Subset[v]) )
486                {
487                    if ( First )
488                    {
489                        printf("{");
490                        First = false;
491                    }
492                    else
493                    {
494                        printf(", ");
495                    }
496                    printf("%s", AttValName[Att][pv]);
497                }
498            }
499            printf("}\n");
500    }
501}
Note: See TracBrowser for help on using the repository browser.