00001 #include "def.h"
00002 #include <string.h>
00003
00004 #define MAXP 32
00005 NODE *param_val[MAXP];
00006 int learn;
00007 int bondage;
00008 static SNODE *stack;
00009
00010 #define WR 1
00011 #define POP 2
00012 #define HAS_ARG (UNARY | BINARY)
00013
00014 typedef struct sub_stack {
00015 struct sub_stack *next;
00016 NODE *exp;
00017 } SUB_STACK;
00018 static SUB_STACK *sub_top = NULL;
00019
00020
00021
00022
00023
00024
00025 void
00026 subject_push(old)
00027 NODE *old;
00028 {
00029 char *malloc();
00030 register SUB_STACK *node;
00031
00032 node = (SUB_STACK *) malloc(sizeof(SUB_STACK));
00033 node->next = sub_top;
00034 node->exp = old;
00035 }
00036
00037
00038
00039
00040
00041
00042 NODE *
00043 subject_pop()
00044 {
00045 void free();
00046 register SUB_STACK *node;
00047 register NODE *exp;
00048
00049 if (!sub_top) return NULL;
00050 node = sub_top;
00051 sub_top = node->next;
00052 exp = node->exp;
00053 free(node);
00054 return exp;
00055 }
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 static RULE *
00069 match(exp)
00070 NODE *exp;
00071 {
00072 int match_sub();
00073 register RULE *rtt;
00074
00075
00076 if (!(exp->op->arity & OP_TERM)) return (RULE *) NULL;
00077
00078 for(rtt = exp->op->hash; rtt; rtt = rtt->next) {
00079 if (match_sub(rtt->head, exp)) return rtt;
00080 }
00081 return (RULE *) NULL;
00082 }
00083
00084
00085
00086
00087
00088
00089
00090 static int
00091 match_types(guard, exp)
00092 OP *guard;
00093 NODE *exp;
00094 {
00095 register OP *mt = exp->op;
00096 for (; mt; mt = mt->super) if (guard == mt) return TRUE;
00097 return FALSE;
00098 }
00099
00100
00101
00102
00103
00104
00105
00106 static int
00107 match_sub(head, exp)
00108 register NODE *head;
00109 register NODE *exp;
00110 {
00111 char *arity_name();
00112 extern OP *untyped_prim;
00113
00114 if (head->op->arity == OP_STR) {
00115 return (exp->op->arity == OP_STR && 0 == strcmp(
00116 ((STR_NODE *) head)->value, ((STR_NODE *) exp)->value));
00117 }
00118 if (head->op->arity == OP_NUM) {
00119 return (exp->op->arity == OP_NUM &&
00120 ((NUM_NODE *) head)->value == ((NUM_NODE *) exp)->value);
00121 }
00122 if (head->op->arity == OP_NAME) {
00123 if (head->op == untyped_prim || match_types(head->op, exp)) {
00124
00125 ((NAME_NODE *) head)->value = exp;
00126 return TRUE;
00127 }
00128 else return FALSE;
00129 }
00130 if (head->op->arity == NULLARY) {
00131 return ((exp->op->arity == NULLARY) && (head->op == exp->op));
00132 }
00133 if (head->op->arity & UNARY) {
00134 if ((head->op->arity != exp->op->arity) || (head->op != exp->op))
00135 return FALSE;
00136 if (head->op->arity == POSTFIX) return match_sub(
00137 ((TERM_NODE *) head)->left, ((TERM_NODE *) exp)->left);
00138 else return
00139 match_sub(((TERM_NODE *) head)->right,((TERM_NODE *) exp)->right);
00140 }
00141 if (head->op->arity & BINARY) {
00142
00143
00144
00145
00146 if ((!(exp->op->arity & BINARY)) || (head->op != exp->op)) return FALSE;
00147 if (!match_sub(((TERM_NODE *) head)->left, ((TERM_NODE *) exp)->left))
00148 return FALSE;
00149 if (!match_sub(((TERM_NODE *) head)->right,((TERM_NODE *) exp)->right))
00150 return FALSE;
00151 return TRUE;
00152 }
00153 fprintf(stderr, "arity: %s\n", arity_name(exp->op->arity));
00154 error("Unknown arity during pattern match!");
00155 return FALSE;
00156 }
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 NODE *
00167 walk(subject)
00168 NODE *subject;
00169 {
00170 SNODE *st_get();
00171 NODE *instantiate();
00172 NODE *primitive_execute();
00173 void expr_free();
00174 NAME_NODE *name_space_insert();
00175 void name_free();
00176 NODE *expr_copy();
00177 NODE *expr_update();
00178 extern OP *untyped_prim;
00179
00180 register NODE *cn = subject;
00181 register SNODE *stn;
00182 NAME_NODE *ts;
00183 RULE *mrule;
00184 NODE *ib;
00185
00186 learn = FALSE;
00187 stack = (SNODE *) NULL;
00188
00189 for (;;) {
00190 if (cn->op->arity == OP_NAME && ((NAME_NODE *)cn)->value) {
00191 fprintf(stderr, "variable: ");
00192 name_print((NAME_NODE *)cn);
00193 fprintf(stderr, "\n");
00194 error("Found loose bound variable in subject expression!");
00195 }
00196 else if (mrule = match(cn)) {
00197 learn = TRUE;
00198 if ((mrule->verbose + verbose)>1) {
00199 fprintf(stderr, "MATCH: ");
00200 rule_print(mrule);
00201 expr_print(subject);
00202 fprintf(stderr, " ==> ");
00203 }
00204
00205 if ((cn->op->arity & OP_TERM) && (((TERM_NODE *) cn)->label)) {
00206 ((TERM_NODE *) cn)->label->op = (mrule->tag) ?
00207 (mrule->tag) : untyped_prim;
00208 ts = name_space_insert(mrule->space, ((TERM_NODE *) cn)->label);
00209 }
00210 else {
00211 ts = name_space_insert(mrule->space, (NAME_NODE *) NULL);
00212 name_free(ts);
00213 }
00214 if (mrule->body->op->eval > 0) {
00215 ib = primitive_execute(mrule->body->op->eval, cn);
00216 }
00217 else ib = instantiate(mrule->body);
00218 expr_free(cn);
00219 ib = expr_update(ib);
00220 if (stack) {
00221 if ((stack->info == WR) || (stack->node->op->arity == POSTFIX))
00222 ((TERM_NODE *) stack->node)->left = ib;
00223 else ((TERM_NODE *) stack->node)->right = ib;
00224 }
00225 else subject = ib;
00226 if (bondage) {
00227 subject = expr_update(subject);
00228 bondage = FALSE;
00229 }
00230 if ((mrule->verbose + verbose)>1) {
00231 expr_print(subject);
00232 fprintf(stderr, "\n");
00233 }
00234 return subject;
00235 }
00236 else {
00237
00238 if (cn->op->arity & HAS_ARG && cn->op->eval != -4) {
00239 stn = st_get();
00240 stn->next = stack;
00241 stack = stn;
00242 stn->node = cn;
00243 if (cn->op->arity & BINARY) {
00244 stn->info = WR;
00245 cn = ((TERM_NODE *) cn)->left;
00246 }
00247 else {
00248 stn->info = POP;
00249 if (cn->op->arity == POSTFIX) cn = ((TERM_NODE *) cn)->left;
00250 else cn = ((TERM_NODE *) cn)->right;
00251 }
00252 }
00253 else {
00254 stn = NULL;
00255 do {
00256 if (stn) st_free(stn);
00257 stn = stack;
00258 if (!stn) return subject;
00259 cn = stn->node;
00260 stack = stn->next;
00261 } while (stn->info == POP);
00262 stack = stn;
00263 cn = ((TERM_NODE *) cn)->right;
00264 stn->info = POP;
00265 }
00266 }
00267 }
00268 }
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279 NODE *
00280 instantiate(body)
00281 NODE *body;
00282 {
00283 NAME_NODE *name_copy();
00284 NODE *expr_copy();
00285 NODE *node_new();
00286 char *arity_name();
00287
00288 if (!body) error("cannot instantiate null rule body");
00289 if (!body->op) error("missing operator in instantiate");
00290
00291 if (body->op->arity & OP_TERM) {
00292 TERM_NODE *te = (TERM_NODE *) node_new();
00293 te->op = body->op;
00294 if (((TERM_NODE *) body)->label)
00295 te->label = name_copy(((TERM_NODE *) body)->label->value);
00296 else te->label = (NAME_NODE *) NULL;
00297 if (((TERM_NODE *) body)->right)
00298 te->right = instantiate(((TERM_NODE *) body)->right);
00299 else te->right = (NODE *) NULL;
00300 if (((TERM_NODE *) body)->left)
00301 te->left = instantiate(((TERM_NODE *) body)->left);
00302 else te->left = (NODE *) NULL;
00303 return (NODE *) te;
00304 }
00305 if (body->op->arity == OP_NUM) {
00306 NUM_NODE *ne = (NUM_NODE *) node_new();
00307 ne->op = body->op;
00308 ne->value = ((NUM_NODE *) body)->value;
00309 return (NODE *) ne;
00310 }
00311 if (body->op->arity == OP_STR) {
00312 STR_NODE *se = (STR_NODE *) node_new();
00313 se->op = body->op;
00314
00315 se->value = ((STR_NODE *) body)->value;
00316 return (NODE *) se;
00317 }
00318 if (body->op->arity == OP_NAME) {
00319 return expr_copy(((NAME_NODE *) body)->value);
00320 }
00321
00322 fprintf(stderr, "operator: %s, arity: %s\n",
00323 body->op->pname, arity_name(body->op->arity));
00324 error("invalid operator arity in instantiate");
00325 }