📄 rules.c
字号:
return -1; /* return 'rule is applicable' */} /* r_check() *//*--------------------------------------------------------------------*/#ifdef RS_PARSEstatic int _valset (ATT *att, SCAN *scan, RULE *rule){ /* --- read a set of values */ int t; /* buffer for a token value */ int id, op; /* identifier and comparison operator */ INST val; /* to represent the condition value */ int *set = NULL; /* set of values read */ assert(att && scan && rule); /* check the function arguments */ t = att_valcnt(att); /* get the number of values and */ if (t <= 32) { /* decide on the set representation */ op = R_BF; val.i = 0; } /* if to use bit flags, clear bits */ else { /* if to use a vector of values, */ op = R_IN; /* allocate an identifier vector */ set = (int*)malloc((t+1) *sizeof(int)); if (!set) ERROR(E_NOMEM); /* create a set of values */ set[0] = 0; val.p = set; /* initialize the number of values */ } /* (vector format: [cnt v1 v2 ... ]) */ GET_CHR('{'); /* consume '{' */ while (1) { /* value read loop */ t = sc_token(scan); /* check for an attribute value */ if ((t != T_ID) && (t != T_NUM)) ERROR(E_VALEXP); id = att_valid(att, sc_value(scan)); if (id < 0) ERROR(E_UNKVAL); GET_TOK(); /* get, check, and consume the value */ if (op == R_BF) /* if the set is rep. by bit flags, */ val.i |= 1 << id; /* set the bit corresp. to the value */ else { /* if the set is rep. by a vector, */ for (t = *set; --t >= 0;) /* check whether the value exists */ if (set[t+1] == id) break; if (t < 0) { t = *set++; set[t] = id; } } /* add only new values */ if (sc_token(scan) != ',') /* add a condition to the rule */ break; /* and check for another value */ GET_TOK(); /* consume ',' */ } GET_CHR('}'); /* consume '}' */ r_condadd(rule, att_id(att), op, &val); if (set) free(set); /* add the condition, delete the */ return 0; /* identifier vector, and return 'ok' */} /* _valset() *//*--------------------------------------------------------------------*/static int _rule (ATTSET *attset, SCAN *scan, RULE *rule){ /* --- parse a rule */ int id, op; /* identifier and comp. operator */ ATT *att; /* attribute of a condition */ INST val; /* attribute value */ int head = 1; /* flag for the rule head */ double supp, conf; /* support and confidence */ int t; /* buffer for a token value */ assert(attset && scan && rule); /* check the function arguments */ while (1) { /* condition read loop */ t = sc_token(scan); /* check for an attribute */ if ((t != T_ID) && (t != T_NUM)) ERROR(E_ATTEXP); id = as_attid(attset, sc_value(scan)); if (id < 0) ERROR(E_UNKATT);/* get the attribute id */ att = as_att(attset, id); /* and the corresponding attribute */ GET_TOK(); /* consume the attribute name */ t = sc_token(scan); /* check for a comparison operator */ if ((t != '=') && (t != '<') && (t != '>') && (t != T_CMP) && (t != T_ID)) ERR_CHR('='); for (op = R_IN +1; --op >= 0; ) if (_opsigns[op] && (strcmp(_opsigns[op], sc_value(scan)) == 0)) break; /* encode the comparison operator */ if ((op < 0) || (head && (op != R_EQ))) ERR_CHR('='); /* check for a valid comp. operator */ if (att_type(att) == AT_SYM) { /* if the attribute is symbolic */ if ((op != R_IN) && (op != R_EQ)) ERROR(E_ILLOP); GET_TOK(); /* consume the comparison operator */ if (op == R_IN) { /* if to read a set of values */ t = _valset(att, scan, rule); if (t) return t; } else { /* if to read a single value */ t = sc_token(scan); /* check for a symbolic value */ if ((t != T_ID) && (t != T_NUM)) ERROR(E_VALEXP); val.i = att_valid(att, sc_value(scan)); if (val.i < 0) ERROR(E_UNKVAL); GET_TOK(); /* get, check, and consume the value */ if (head) r_headset(rule, id, op, &val);/* set the rule head */ else r_condadd(rule, id, op, &val);/* or add a condition */ } } else { /* if the attribute is numeric */ if (op >= R_IN) ERROR(E_ILLOP); GET_TOK(); /* consume the comparison operator */ if (sc_token(scan) != T_NUM) ERROR(E_NUMEXP); val.f = (float)atof(sc_value(scan)); GET_TOK(); /* get, check, and consume the number */ if (head) r_headset(rule, id, op, &val); /* set the rule head */ else r_condadd(rule, id, op, &val); /* or add a condition */ } if ((sc_token(scan) == ';') || (sc_token(scan) == '[')) break; /* check for the end of the rule */ if (head) { if (sc_token(scan) != T_LFT) ERR_STR("<-"); } else { if (sc_token(scan) != '&') ERR_CHR('&'); } GET_TOK(); /* consume implication or conjunction */ head = 0; /* the first round reads the head, */ } /* all following only conditions */ if (sc_token(scan) == '[') { /* if support/confidence follows */ GET_TOK(); t = 0; /* consume '[' */ if (sc_token(scan) == '~') { GET_TOK(); t = 1; } if (sc_token(scan) != T_NUM) ERROR(E_NUMEXP); supp = atof(sc_value(scan));/* get the support/confidence */ conf = 0; /* (set default confidence first) */ GET_TOK(); /* consume the number */ if ((t == 0) && (sc_token(scan) == '%')) t = 2; if (t != 0) { /* if there is no support value, */ conf = supp; supp = 0; /* set and check the confidence */ if ((conf < 0) || (conf > 100)) { sc_back(scan); ERROR(E_ILLNUM); } if (t == 2) GET_TOK(); } /* consume '%' */ else if (sc_token(scan) == '/') { GET_TOK(); /* consume the supp./conf. separator */ if (sc_token(scan) == '~') { GET_TOK(); t = 1; } if (sc_token(scan) != T_NUM) ERROR(E_NUMEXP); conf = atof(sc_value(scan)); if ((conf < 0) || (conf > 100)) ERROR(E_ILLNUM); GET_TOK(); /* get, check and consume the conf. */ if ((t == 0) && (sc_token(scan) == '%')) { GET_TOK(); t = 2; } } /* consume '%' */ GET_CHR(']'); /* consume ']' */ rule->supp = (float)supp; /* set support and confidence */ rule->conf = (float)((t == 2) ? 0.01 *conf : conf); } GET_CHR(';'); /* consume ';' */ return 0; /* return 'ok' */} /* _rule() *//*--------------------------------------------------------------------*/RULE* r_parse (ATTSET *attset, SCAN *scan){ /* --- parse a rule */ RULE *rule; /* created rule */ assert(attset && scan); /* check the function arguments */ pa_init(scan); /* initialize parsing */ rule = r_create(attset, 2 *as_attcnt(attset)); if (!rule) return NULL; /* create a rule of maximum size */ if (_rule(attset, scan, rule) != 0) { r_delete(rule); return NULL; } /* parse a rule */ rule = (RULE*)realloc(rule, sizeof(RULE) +(rule->condcnt-1) *sizeof(COND)); rule->condvsz = rule->condcnt;/* try to shrink the rule */ return rule; /* return the created rule */} /* r_parse() */#endif/*---------------------------------------------------------------------- Rule Set Functions----------------------------------------------------------------------*/RULESET* rs_create (ATTSET *attset, RULE_DELFN delfn){ /* --- create a ruleset */ RULESET *set; /* created rule set */ assert(attset && delfn); /* check arguments */ set = (RULESET*)malloc(sizeof(RULESET)); if (!set) return NULL; /* allocate memory and */ set->attset = attset; /* initialize fields */ set->delfn = delfn; set->rulevsz = set->rulecnt = 0; set->rules = NULL; return set; /* return the created rule set */} /* rs_create() *//*--------------------------------------------------------------------*/void rs_delete (RULESET *set, int delas){ /* --- delete a ruleset */ int i; /* loop variable */ RULE **p; /* to traverse the rules */ assert(set); /* check the function argument */ p = set->rules +set->rulecnt; /* traverse rules */ for (i = set->rulecnt; --i >= 0; ) { (*--p)->set = NULL; (*p)->id = -1; set->delfn(*p); /* remove and delete all rules */ } /* and delete the rule vector */ if (set->rules) free(set->rules); if (delas) as_delete(set->attset); free(set); /* delete the rule set body */} /* rs_delete() *//*--------------------------------------------------------------------*/int rs_ruleadd (RULESET *set, RULE *rule){ /* --- add a rule to a ruleset */ int vsz; /* size of rule vector */ RULE **p; /* (new) rule vector */ assert(set && rule); /* check the function arguments */ if (set->rulecnt >= set->rulevsz) { vsz = set->rulevsz /* if the rule vector is full */ + ((set->rulevsz > BLKSIZE) ? (set->rulevsz >> 1) : BLKSIZE); p = (RULE**)realloc(set->rules, vsz *sizeof(RULE*)); if (!p) return -1; /* allocate a (new) rule vector */ set->rules = p; set->rulevsz = vsz; } /* set rule vector and its size */ rule->set = set; /* note rule set reference */ rule->id = set->rulecnt; /* and set rule identifier */ set->rules[set->rulecnt++] = rule; return 0; /* add the rule and return 'ok' */} /* rs_ruleadd() *//*--------------------------------------------------------------------*/RULE* rs_rulerem (RULESET *set, int ruleid){ /* --- remove a rule from a ruleset */ int i; /* loop variable */ RULE **p; /* to traverse the rule vector */ RULE *rule; /* buffer for removed rule */ assert(set && (ruleid < set->rulecnt)); /* check arguments */ /* --- delete all rules --- */ if (ruleid < 0) { /* if no rule identifier given */ for (p = set->rules +(i = set->rulecnt); --i >= 0; ) { (*--p)->set = NULL; (*p)->id = -1; set->delfn(*p); /* remove and delete all rules */ } if (set->rules) { free(set->rules); set->rules = NULL; } set->rulecnt = set->rulevsz = 0; return NULL; /* delete the rule vector */ } /* and abort the function */ /* --- delete one rule --- */ rule = set->rules[ruleid]; /* note the rule to remove */ p = set->rules +ruleid; /* traverse the successor rules */ for (i = --set->rulecnt -ruleid; --i >= 0; ) { *p = p[1]; (*p++)->id--; } /* shift rules and adapt identifiers */ rule->set = NULL; /* clear the rule set reference */ rule->id = -1; /* and the rule identifier */ return rule; /* and return the removed rule */} /* rs_rulerem() */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -