#include #include #include #include "efc_structs.h" #define The_Stars_Twinkle 1 int cur_len, /* length of current word in input stream */ wd_len, /* length of current target word */ tok_high = -1, /* most tokens used to date */ new_wd; /* flag used so that statistics are gathered only on first token follower to match */ struct stats wd_info[20]; /* structure to store EFC statistics */ float WDS = 0; /* total words sampled */ float wd_occ, /* relative occurrence of target word */ wd_cur_match = 0.0, /* number of matches against current target */ matching_tok[5*TOK_NO+1], /* stats on tok fol activation */ real_tok[TOK_NO+1]; /* statistics on physical token follower use */ /************************************************************************** Routine: main Purpose: Check for proper parameter passing to program and then call top-level EFC simulator routine. Inputs: data base containing words and their relative frequencies of occurrence. Outputs: none. Other Side Effects: none. **************************************************************************/ main(argc, argv) int argc; char *argv[]; { if (argc != 2) error("Usage: efc wordfile", NULL); efc(argv[1]); } /************************************************************************** Subroutine: efc Purpose: Simulate one string matcher of an Electronic Filing Cabinet (EFC) system using a data base of words. The data base is formatted in two columns where the first is made up of words and the second is made up their relative frequencies of occurrence (integers). The sum of these frequencies represents the total number of words sampled. For the simulation, every word is compared to every other word in the data base. Inputs: pointer to data base of words. Outputs: Statistics of the simulation. **************************************************************************/ efc(fname) char *fname; { struct str_matcher ss[SS_NO]; struct state *st_tbl, *make_state_table(), *get_next_state(); char wd[50]; int ss_result, i, j, ta, match, newest_tok; float occ; FILE *fptr, *fopen(); void rewind(), deactivate_toks(); for (i = 0; i < 20 ;i++) init_stats(&wd_info[i]); st_tbl = make_state_table(); if ((fptr= fopen(fname, "r")) == NULL) error("efc: can't open %s", fname); while (The_Stars_Twinkle) { init_ss_matcher(fname, &ss[0]); while (getwd(fptr, wd, &occ, 1) != EOF ) { newest_tok = match = 0; new_wd = 1; for (i = 0; !match && (i < cur_len); i++) { activate_tok(st_tbl, &(ss[0]), &newest_tok); for (j = 0; !match && (j < TOK_NO); j++) if (ss[0].tok[j].active) { ss_result = ss_match(&ss[0], wd[i], &(ss[0].tok[j])); ss[0].tok[j].current_st = get_next_state(ss[0].tok[j].current_st, ss_result); do_state_actions(&(ss[0].tok[j])); match = check_tok(&(ss[0].tok[j]), ss[0].str_len, occ, wd, j); } } if (match) wd_info[wd_len].mismatches += wd_occ * wd_cur_match; if (tok_high >= 0) { wd_info[wd_len].toks_used[tok_high] += occ * wd_occ; } deactivate_toks(&ss[0]); } rewind(fptr); } } /************************************************************************** Subroutine: getwd Purpose: Retrieve a word and its relative frequency of occurrence from the word data base used in the simulation. Inputs: fptr - pointer to word data base. buf - where to store newly read word. occ - frequency of occurrence of new word. chg_stats - update frequency of occurrence of either target word or input word. Outputs: none. Returns: EOF upon end of data base file. Other Side Effects: input words are truncated to 16 characters. **************************************************************************/ getwd(fptr, buf, occ, chg_stats) FILE *fptr; char *buf; int chg_stats; float *occ; { int res, len, i; res = fscanf(fptr, "%s %f\n", buf, occ); if (res != EOF) { len = strlen(buf); len = (len > 15) ? 15: len; buf[len] = '\0'; if (chg_stats) cur_len = (float)len; else wd_len = (float)len; } return(res); }