bool table_base::fetch_fact(table_fact & f) const { if(get_signature().functional_columns()==0) { return contains_fact(f); } else { unsigned sig_sz = get_signature().size(); unsigned non_func_cnt = sig_sz-get_signature().functional_columns(); table_base::iterator it = begin(); table_base::iterator iend = end(); table_fact row; for(; it!=iend; ++it) { it->get_fact(row); bool differs = false; for(unsigned i=0; i<non_func_cnt; i++) { if(row[i]!=f[i]) { differs = true; } } if(differs) { continue; } for(unsigned i=non_func_cnt; i<sig_sz; i++) { f[i]=row[i]; } return true; } return false; } }
bool table_base::suggest_fact(table_fact & f) { if(get_signature().functional_columns()==0) { if(contains_fact(f)) { return false; } add_new_fact(f); return true; } else { if(fetch_fact(f)) { return false; } add_new_fact(f); return true; } }
/** \brief Default method for complementation. It assumes that the compiler creates only tables with at most one column (0 or 1 columns). Complementation of tables with more than one columns is transformed into a cross product of complements and/or difference. */ table_base * table_base::complement(func_decl* p, const table_element * func_columns) const { const table_signature & sig = get_signature(); SASSERT(sig.functional_columns()==0 || func_columns!=0); SASSERT(sig.first_functional() <= 1); table_base * res = get_plugin().mk_empty(sig); table_fact fact; fact.resize(sig.first_functional()); fact.append(sig.functional_columns(), func_columns); if (sig.first_functional() == 0) { if (empty()) { res->add_fact(fact); } return res; } VERIFY(sig.first_functional() == 1); uint64 upper_bound = get_signature()[0]; bool empty_table = empty(); if (upper_bound > (1 << 18)) { std::ostringstream buffer; buffer << "creating large table of size " << upper_bound; if (p) buffer << " for relation " << p->get_name(); warning_msg(buffer.str().c_str()); } for(table_element i = 0; i < upper_bound; i++) { fact[0] = i; if(empty_table || !contains_fact(fact)) { res->add_fact(fact); } } return res; }
table_base * table_base::complement(func_decl* p, const table_element * func_columns) const { const table_signature & sig = get_signature(); SASSERT(sig.functional_columns()==0 || func_columns!=0); table_base * res = get_plugin().mk_empty(sig); table_fact fact; fact.resize(sig.first_functional()); fact.append(sig.functional_columns(), func_columns); if(sig.first_functional()==0) { if(empty()) { res->add_fact(fact); } return res; } if(sig.first_functional()!=1) { //now we support only tables with one non-functional column NOT_IMPLEMENTED_YET(); } uint64 upper_bound = get_signature()[0]; bool empty_table = empty(); if (upper_bound > (1 << 18)) { std::ostringstream buffer; buffer << "creating large table of size " << upper_bound; if (p) buffer << " for relation " << p->get_name(); warning_msg(buffer.str().c_str()); } for(table_element i=0; i<upper_bound; i++) { fact[0]=i; if(empty_table || !contains_fact(fact)) { res->add_fact(fact); } } return res; #if 0 svector<unsigned> var_arg_indexes(arity); var_arg_indexes.fill(0); svector<unsigned> var_arg_domain_sizes = s; unsigned var_cnt=var_arg_indexes.size(); table_fact fact; fact.resize(arity); fact.fill(0); unsigned depth=arity; while(true) { if(depth==arity) { SASSERT(!res->contains_fact(fact)); if(empty_table || !contains_fact(fact)) { res->add_fact(fact); } depth--; } else if(fact[depth]==s[depth]-1) { val_indexes[depth]=0; if(depth==0) { break; } depth--; } else { SASSERT(val_indexes[depth]<var_arg_domain_sizes[depth]); unsigned arg_idx = var_arg_indexes[depth]; unsigned val_idx = val_indexes[depth]++; head_args[arg_idx]=ctx.get_arith().mk_numeral(rational(val_idx), true); depth++; } } return res; #endif }