main() { char a[4002],b[4002]; int pi[4002]={}; int i,j; int len1,len2,max=0,res; len1=strlen(gets(a+1)); len2=strlen(gets(b+1)); if(len1<len2) { for(i=0;i<len1;i++) { make_pi(pi,a+i); res=kmp(pi,b,a+i,len1-i); max=max<res?res:max; } } else { for(i=0;i<len2;i++) { make_pi(pi,b+i); res=kmp(pi,a,b+i,len2-i); max=max<res?res:max; } } printf("%d",max); }
term* normalize_fuel_pi(context *Sigma, typing_context* Delta, term* t, int fuel) { term* B = NULL; term* A = normalize_fuel(Sigma, Delta, t->left, fuel-1); if (!A) goto error; context* extend = context_add(variable_dup(t->var), NULL, Sigma); B = normalize_fuel(extend, Delta, t->right, fuel-1); context_pop(extend); if (!B) goto error; return make_pi(variable_dup(t->var), A, B); error: free_term(A); free_term(B); return NULL; }
/* invariant: no sharing between returned term and *any* arguments. the caller must free the result. */ term* substitute(variable* from, term* to, term* haystack) { if (haystack == NULL) return NULL; check(from != NULL && to != NULL, "substitute requires non-NULL arguments"); check(term_locally_well_formed(to), "substitute requires %W to be locally well-formed", to, print_term); check(term_locally_well_formed(haystack),"substitute requires %W to be locally well-formed", haystack, print_term); switch(haystack->tag) { case VAR: if (variable_equal(from, haystack->var)) { return term_dup(to); } else { return term_dup(haystack); } case HOLE: return term_dup(haystack); case LAM: if (variable_equal(from, haystack->var)) { return make_lambda(variable_dup(haystack->var), substitute(from, to, haystack->left), term_dup(haystack->right)); } else { if (is_free(haystack->var, to)) { variable *g = gensym(haystack->var->name); term *tg = make_var(g); term* new_haystack = make_lambda(variable_dup(g), term_dup(haystack->left), substitute(haystack->var, tg, haystack->right)); free_term(tg); term* ans = substitute(from, to, new_haystack); free_term(new_haystack); return ans; } return make_lambda(variable_dup(haystack->var), substitute(from, to, haystack->left), substitute(from, to, haystack->right)); } case PI: if (variable_equal(from, haystack->var)) { return make_pi(variable_dup(haystack->var), substitute(from, to, haystack->left), term_dup(haystack->right)); } else { if (is_free(haystack->var, to)) { variable *g = gensym(haystack->var->name); term *tg = make_var(g); term* new_haystack = make_pi(variable_dup(g), term_dup(haystack->left), substitute(haystack->var, tg, haystack->right)); free_term(tg); term* ans = substitute(from, to, new_haystack); free_term(new_haystack); return ans; } return make_pi(variable_dup(haystack->var), substitute(from, to, haystack->left), substitute(from, to, haystack->right)); } case APP: return make_app(substitute(from, to, haystack->left), substitute(from, to, haystack->right)); case TYPE: return term_dup(haystack); case DATATYPE: { term* ans = make_datatype_term(variable_dup(haystack->var), haystack->num_params, haystack->num_indices); #define SUB_VEC(dst, src, n) do { \ int __i; \ for (__i = 0; __i < n; __i++) { \ dst[__i] = substitute(from, to, src[__i]); \ } \ } while(0) SUB_VEC(ans->params, haystack->params, haystack->num_params); SUB_VEC(ans->indices, haystack->indices, haystack->num_indices); return ans; } case INTRO: { term* ans = make_intro(variable_dup(haystack->var), substitute(from, to, haystack->left), haystack->num_args, haystack->num_params, haystack->num_indices); SUB_VEC(ans->args, haystack->args, haystack->num_args); SUB_VEC(ans->params, haystack->params, haystack->num_params); SUB_VEC(ans->indices, haystack->indices, haystack->num_indices); return ans; } case ELIM: { term* ans = make_elim(variable_dup(haystack->var), haystack->num_args, haystack->num_params, haystack->num_indices); SUB_VEC(ans->args, haystack->args, haystack->num_args); SUB_VEC(ans->params, haystack->params, haystack->num_params); SUB_VEC(ans->indices, haystack->indices, haystack->num_indices); return ans; } case IMPLICIT: return term_dup(haystack); default: sentinel("malformed term with tag %d", haystack->tag); } error: return NULL; }
int syntactically_identical(term* a, term* b) { if (a == NULL || b == NULL) return a == b; check(term_locally_well_formed(a) && term_locally_well_formed(b), "alpha equiv requires well-formed arguments"); if (a->tag == HOLE) { log_info("Hole should unify with %W", b, print_term); return 1; } if (b->tag == HOLE) { log_info("Hole should unify with %W", a, print_term); return 1; } if (a->tag != b-> tag) return 0; switch (a->tag) { case VAR: return variable_equal(a->var, b->var); case LAM: { if (a->left != NULL && b->left != NULL && !syntactically_identical(a->left, b->left)) return 0; if (variable_equal(a->var, b->var)) return syntactically_identical(a->right, b->right); term* va = make_var(variable_dup(a->var)); term* bsubs = substitute(b->var, va, b->right); free_term(va); term* c = make_lambda(variable_dup(a->var), term_dup(b->left), bsubs); int ans = syntactically_identical(a, c); free_term(c); return ans; } case PI: { if (!syntactically_identical(a->left, b->left)) return 0; if (variable_equal(a->var, b->var)) return syntactically_identical(a->right, b->right); term* va = make_var(variable_dup(a->var)); term* bsubs = substitute(b->var, va, b->right); free_term(va); term* c = make_pi(variable_dup(a->var), term_dup(b->left), bsubs); int ans = syntactically_identical(a, c); free_term(c); return ans; } case APP: return syntactically_identical(a->left, b->left) && syntactically_identical(a->right, b->right); case DATATYPE: { if (!variable_equal(a->var, b->var)) { return 0; } #define EQ_VEC(a, an, b, bn) do { \ if (an != bn) return 0; \ int __i; \ for (__i = 0; __i < an; __i++) { \ if (!syntactically_identical(a[__i], b[__i])) return 0; \ } \ } while(0) EQ_VEC(a->params, a->num_params, b->params, b->num_params); EQ_VEC(a->indices, a->num_indices, b->indices, b->num_indices); return 1; } case INTRO: case ELIM: { if (!variable_equal(a->var, b->var)) { return 0; } EQ_VEC(a->args, a->num_args, b->args, b->num_args); EQ_VEC(a->params, a->num_params, b->params, b->num_params); EQ_VEC(a->indices, a->num_indices, b->indices, b->num_indices); return 1; } case TYPE: return 1; case IMPLICIT: return syntactically_identical(a->right, b->right); default: sentinel("malformed term"); } error: return 0; }