/* *** equality *** */ bool val_equal(value_t a, value_t b) { if (val_eq(a, b)) { return true; } if (IS_VAL(a) || IS_VAL(b)) { // if both are only plain values, // they should have been equal by <eq?> return false; } ptrvalue_t *pa = AS_PTR(a); ptrvalue_t *pb = AS_PTR(b); if (pa->type != pb->type) { return false; } if (pa->type == T_CONS) { cons_t *consa = (cons_t *) pa; cons_t *consb = (cons_t *) pb; return val_equal(consa->car, consb->car) && val_equal(consa->cdr, consb->cdr); } else if (pa->type == T_STRING) { string_t *stra = (string_t *) pa; string_t *strb = (string_t *) pb; return stra->len == strb->len && stra->hash == strb->hash && memcmp(stra->value, strb->value, stra->len * sizeof(char)) == 0; } else if (pa->type == T_SYMBOL) { symbol_t *syma = (symbol_t *) pa; symbol_t *symb = (symbol_t *) pb; if ((syma->len == symb->len) && (memcmp(syma->name, symb->name, syma->len * sizeof(char)) == 0)) { // we should never get here! - two symbols with same name are eq? fprintf(stderr, "Error: symbol not interned!"); } return false; } else if (pa->type == T_VECTOR) { vector_t *veca = (vector_t *) pa; vector_t *vecb = (vector_t *) pb; if (veca->count != vecb->count) { return false; } for (uint32_t i = 0; i < veca->count; i++) { if (!val_equal(veca->data[i], vecb->data[i])) { return false; } } return true; } return false; }
int val_member(const cst_val *v1,const cst_val *l) { const cst_val *i; for (i=l; i; i=val_cdr(i)) { if (val_equal(val_car(i),v1)) return TRUE; } return FALSE; }
int val_equal(const cst_val *v1, const cst_val *v2) { if (v1 == v2) return TRUE; /* its eq so its equal */ else if (v1 == 0) return FALSE; else if (CST_VAL_TYPE(v1) == CST_VAL_TYPE(v2)) { if (cst_val_consp(v1)) return ((val_equal(val_car(v1),val_car(v2))) && (val_equal(val_cdr(v1),val_cdr(v2)))); else if (CST_VAL_TYPE(v1) == CST_VAL_TYPE_INT) return (val_int(v1) == val_int(v2)); else if (CST_VAL_TYPE(v1) == CST_VAL_TYPE_FLOAT) return (val_float(v1) == val_float(v2)); else if (CST_VAL_TYPE(v1) == CST_VAL_TYPE_STRING) return (cst_streq(CST_VAL_STRING(v1),CST_VAL_STRING(v2))); else return CST_VAL_VOID(v1) == CST_VAL_VOID(v2); } else return FALSE; }
const cst_val *cart_interpret(cst_item *item, const cst_cart *tree) { /* Tree interpretation */ const cst_val *v=0; const cst_val *tree_val; const char *tree_feat = ""; cst_features *fcache; int r=0; int node=0; fcache = new_features_local(item_utt(item)->ctx); while (cst_cart_node_op(node,tree) != CST_CART_OP_LEAF) { #if CART_DEBUG cart_print_node(node,tree); #endif tree_feat = cst_cart_node_feat(node,tree); v = get_param_val(fcache,tree_feat,0); if (v == 0) { v = ffeature(item,tree_feat); feat_set(fcache,tree_feat,v); } #if CART_DEBUG val_print(stdout,v); printf("\n"); #endif tree_val = cst_cart_node_val(node,tree); if (cst_cart_node_op(node,tree) == CST_CART_OP_IS) r = val_equal(v,tree_val); else if (cst_cart_node_op(node,tree) == CST_CART_OP_LESS) r = val_less(v,tree_val); else if (cst_cart_node_op(node,tree) == CST_CART_OP_GREATER) r = val_greater(v,tree_val); else if (cst_cart_node_op(node,tree) == CST_CART_OP_IN) r = val_member(v,tree_val); else if (cst_cart_node_op(node,tree) == CST_CART_OP_MATCHES) r = cst_regex_match(cst_regex_table[val_int(tree_val)], val_string(v)); else { cst_errmsg("cart_interpret_question: unknown op type %d\n", cst_cart_node_op(node,tree)); cst_error(); } if (r) { /* Oh yes it is */ #if CART_DEBUG printf(" YES\n"); #endif node = cst_cart_node_yes(node,tree); } else { /* Oh no it isn't */ #if CART_DEBUG printf(" NO\n"); #endif node = cst_cart_node_no(node,tree); } } delete_features(fcache); return cst_cart_node_val(node,tree); }
int main() { atexit(count_check); { DP dp; assert(null(dp)); DP dp2(std::move(dp)); assert(null(dp2)); dp = std::move(dp2); assert(null(dp)); dp2.reset(nullptr); assert(null(dp2)); assert(equal(dp, dp2)); } { DP dp{new Derived}; assert(not_null(dp)); assert(val_equal(dp, 1, 1)); dp.reset(new Derived{2}); assert(not_null(dp)); assert(val_equal(dp, 2, 2)); dp.reset(nullptr); assert(null(dp)); dp = DP{new Derived{3}}; assert(not_null(dp)); assert(val_equal(dp, 3, 3)); dp = std::move(dp); dp = DP{new Derived}; assert(not_null(dp)); assert(val_equal(dp, 1, 1)); } { BP bp{new Base}, dp{new Derived}; assert(not_null(bp)); assert(not_null(dp)); assert(val_equal(bp)); assert(val_equal(dp, 1, 1)); assert(val_not_equal(bp, dp)); { BP mp{std::move(bp)}; assert(val_equal(mp)); mp = std::move(dp); assert(val_equal(mp, 1, 1)); } bp.reset(new Base); dp.reset(new Derived); DP dp2{new Derived}; assert(val_not_equal(bp, dp)); assert(val_not_equal(bp, dp2)); assert(not_equal(dp, dp2)); } { CP<0> cp0{new Chain<2>}; assert(val_equal(cp0, 2, 2)); cp0 = CP<3>{new Chain<5>}; assert(val_equal(cp0, 5, 5)); cp0 = CP<2>{CP<5>{CP<8>{new Chain<12>}}}; assert(val_equal(cp0, 12, 12)); } { CP<0> cp0; CP<2> cp2; CP<5> cp5; cp5.reset(new Chain<10>); assert(val_equal(cp5, 10, 10)); cp2 = std::move(cp5); assert(val_equal(cp2, 10, 10)); cp0 = std::move(cp2); assert(val_equal(cp0, 10, 10)); } { GP<0, 0> gp00{GP<0,3>{GP<4,3>{GP<4,4>{GP<4,5>{new Grid<5, 5>}}}}}; assert(val_equal(gp00, 5, 5)); } { GP<0, 0> gp00; GP<1, 0> gp10; GP<1, 1> gp11; GP<1, 2> gp12; GP<2, 2> gp22; gp22.reset(new Grid<2, 5>); gp12 = std::move(gp22); gp11 = std::move(gp12); gp10 = std::move(gp11); gp00 = std::move(gp10); assert(val_equal(gp00, 2, 5)); } }
inline bool val_not_equal(const UP<T> &t, const UP<U> &u) { return not_null(t) && not_null(u) && not_equal(t, u) && val_equal(t, t->n, t->m) && !val_equal(t, u->n, u->m) && !val_equal(u, t->n, t->m) && val_equal(u, u->n, u->m); }