int lessp(U *p1, U *p2) { if (cmp_expr(p1, p2) < 0) return 1; else return 0; }
int equal(U *p1, U *p2) { if (cmp_expr(p1, p2) == 0) return 1; else return 0; }
int cmp_expr(expr * ae, expr * be, int depth) { if (ae == be) { return 0; } //remove negations bool a_neg = m.is_not(ae, ae); bool b_neg = m.is_not(be, be); if (ae==be) { return cmp(a_neg, b_neg); } if (!is_app(ae) && !is_app(be)) { return cmp(ae->get_id(), be->get_id()); } if (!is_app(ae)) { return -1; } if (!is_app(be)) { return 1; } app * a = to_app(ae); app * b = to_app(be); if (a->get_decl()!=b->get_decl()) { return cmp(a->get_decl()->get_id(), b->get_decl()->get_id()); } if (a->get_num_args()!=b->get_num_args()) { return cmp(a->get_num_args(), b->get_num_args()); } if (depth==0) { return cmp(a->get_id(),b->get_id()); } unsigned arg_cnt = a->get_num_args(); unsigned neg_comparison = 0; for (unsigned i=0; i<arg_cnt; i++) { expr * arg_a = a->get_arg(i); expr * arg_b = b->get_arg(i); //we normalize away negations bool a_is_neg = m.is_not(arg_a, arg_a); bool b_is_neg = m.is_not(arg_b, arg_b); if (neg_comparison==0 && a_is_neg!=b_is_neg) { neg_comparison = a_is_neg ? -1 : 1; } int res = cmp_expr(arg_a, arg_b, depth-1); if (res!=0) { return res; } } if (neg_comparison!=0) { return neg_comparison; } //by normalizing away negation we may have put non-equal terms to be equal, so here we check return cmp(a->get_id(),b->get_id()); }
int cmp_terms(const void *q1, const void *q2) { int i, t; cmp_terms_count++; if (cmp_terms_count == 52) printf("stop here"); p1 = *((U **) q1); p2 = *((U **) q2); /* numbers can be combined */ if (isnum(p1) && isnum(p2)) { flag = 1; //printf("cmp_terms #%d returns 0\n", cmp_terms_count); return 0; } /* congruent tensors can be combined */ if (istensor(p1) && istensor(p2)) { if (p1->u.tensor->ndim < p2->u.tensor->ndim){ //printf("cmp_terms #%d returns -1\n", cmp_terms_count); return -1; } if (p1->u.tensor->ndim > p2->u.tensor->ndim){ //printf("cmp_terms #%d returns 1\n", cmp_terms_count); return 1; } for (i = 0; i < p1->u.tensor->ndim; i++) { if (p1->u.tensor->dim[i] < p2->u.tensor->dim[i]){ //printf("cmp_terms #%d returns -1\n", cmp_terms_count); return -1; } if (p1->u.tensor->dim[i] > p2->u.tensor->dim[i]){ //printf("cmp_terms #%d returns 1\n", cmp_terms_count); return 1; } } flag = 1; ////printf("cmp_terms #%d returns 0"); return 0; } if (car(p1) == symbol(MULTIPLY)) { p1 = cdr(p1); if (isnum(car(p1))) { p1 = cdr(p1); if (cdr(p1) == symbol(NIL)) p1 = car(p1); } } if (car(p2) == symbol(MULTIPLY)) { p2 = cdr(p2); if (isnum(car(p2))) { p2 = cdr(p2); if (cdr(p2) == symbol(NIL)) p2 = car(p2); } } t = cmp_expr(p1, p2); if (t == 0) flag = 1; //printf("cmp_terms #%d returns %d\n", cmp_terms_count, t); return t; }
bool operator()(expr * ae, expr * be) { return cmp_expr(ae, be, 4) == -1; }
int cmp_expr(U *p1, U *p2) { int n; if (p1 == p2) return 0; if (p1 == symbol(NIL)) return -1; if (p2 == symbol(NIL)) return 1; if (isnum(p1) && isnum(p2)) return sign(compare_numbers(p1, p2)); if (isnum(p1)) return -1; if (isnum(p2)) return 1; if (isstr(p1) && isstr(p2)) return sign(strcmp(p1->u.str, p2->u.str)); if (isstr(p1)) return -1; if (isstr(p2)) return 1; if (issymbol(p1) && issymbol(p2)) return sign(strcmp(get_printname(p1), get_printname(p2))); if (issymbol(p1)) return -1; if (issymbol(p2)) return 1; if (istensor(p1) && istensor(p2)) return compare_tensors(p1, p2); if (istensor(p1)) return -1; if (istensor(p2)) return 1; while (iscons(p1) && iscons(p2)) { n = cmp_expr(car(p1), car(p2)); if (n != 0) return n; p1 = cdr(p1); p2 = cdr(p2); } if (iscons(p2)) return -1; if (iscons(p1)) return 1; return 0; }
static int __cmp(const void *p1, const void *p2) { return cmp_expr(*((U **) p1), *((U **) p2)); }